thursday, 4 march 2010

posted at 09:51

Nothing big to report, just work plodding along, so here's an update in pictures.

Here's the fully assembled N64 RGB DAC board:

It's not currently working though, so some debugging is required. When I hook it up I get no picture, and occassionally it seems to short out the whole console. I haven't really had time to diagnose it properly yet. I'm mostly waiting to figure out a systematic approach, since its all a bit confusing right now.

My other project is the USB-to-N64 controller bridge. I've written a lot of AVR assembly for this so far but haven't done any actual hardware work. Its coming very soon though, so I very carefully removed the cable from one of my controllers (so I have the option of putting it back together later) and added some pins to the end so I can connect up a breadboard:

This is my first outing with shrinkwrap tube and it was a breeze. My wife has a hot air gun that she uses for her craft work, mostly with embossing inks, so I borrowed it and it worked brilliantly. I was surprised at how much physical strength it actually gives.

This is the insides of my N64:

The large ribbon is the digital signal tap for the RGB DAC, soldered to the inputs on the existing composite DAC chip (easier to solder to that chip than to the much narrower output pins on the video chip. The brown/black pair in the left is the 3.3v power feed for the RGB DAC. Over there on the right under everything is a DE9 D-sub connector with lines for the outputs from the RGB DAC (the narrower ribbon), audio from under the multi-out (the purple/gray/white ribbon) and a 5v line that's needed for some SCART signalling (the fat red wire). Right now its actually hooked to a 3.3v line under the board because I was testing something. Soon I'll hook it instead to the 5V regulator you see just to the right of the composite DAC.

Finally, some recent ebay loot:

Clockwise from top left: a pack of 78L33 3.3v voltage regulators; a sheet of 6 74HC374 8-bit latches and 4 74HC04 inverters; an anti-static pack containing two ATmega88 microcontrollers; a giant roll of 560-ohm 1% resistors (190 left on the roll); a tube of 74HC04 inverters; and a pack of 10n ceramic capacitors (which I use for IC bypass caps).

As I've mentioned before, ebay is an incredible source of cheap parts. There's less than $30 of parts in this picture, and that's not everything I've bought recently. I love getting home every second day and there's a little parcel waiting for me!

thursday, 4 february 2010

posted at 21:23

A couple of weeks ago I placed an order with BatchPCB for the N64 RGB DAC board. Today I received two of them!

I'm quite excited to see the design all professional looking. If I'm really lucky they might even work!

As I understand it sometimes the fabs will make extras of a board in case something goes wrong. If they all come out fine then there's not much to do with the extras, so they just chuck them in as a bonus. That's good; now I have a spare if something goes wrong and I don't feel like I got such a bad deal with the insane postage cost.

eBay is the best source of cheap components in bulk. There's hundreds of stores all selling manner of things in huge quantities for mere pennies and half of the time with free shipping. This time around I've picked these up:

All for the bargain basement price of $22.50. Sure, I have to wait a couple of weeks, but I'm not in any hurry here. If I'd been really smart I would've ordered the parts a couple of weeks ago. Oh well :)

friday, 29 january 2010

posted at 09:28

Ok, so what am I working on. Part two of my N64 modernisation project is to arrange it so that USB controllers can be used with the Nintendo 64.

The reasoning here is pretty simple. N64 controllers have a design flaw. I don't fully understand it, but the gist is that there's a magic powder inside the analog sticks that gives them their "springiness" and makes them return to centre. As the controllers wear, the powder escapes and it gets to the point where the sticks won't return to centre anymore as well as losing their sensitivity. Mine have held up pretty well, mostly because I've gone to great pains to take care of them, but they're fifteen years old now and they're starting to show it.

Obviously these controllers aren't manufactured anymore. Its not enough to buy used ones, for obvious reasons, and new ones are difficult to come by. Not impossible - I've seen them on eBay and in shops like Gametraders and Cash Converters, and I guess I wouldn't need to buy many of them, but still, they aren't exactly cheap or plentiful.

A better option is USB gamepads. As you'd expect from any PC peripheral, they're common as dirt and the good ones (eg Logitech or XBox) are comfortable, sturdy and responsive. So my thought has been to arrange it so that these sticks can be used with the N64.

First stop: Google. There's lots of projects where people have interfaced N64 controllers to something else (USB, parallel, Gamecube/Wii) or interfaced similar controllers (Gamecube) to the N64. As far as I've been able to tell though, nobody has ever got a USB stick going on a N64. Great, new territory - seems I can't avoid it.

I've spent the last couple of weeks researching and thinking and while I haven't yet done any testing with real hardware, I think I have a rough concept for how an interface might work. There's three aspects to it:

  • Acting as a USB host controller and HID class implementation.
  • Translating USB gamepad data into equivalent N64 button/position data
  • Speaking the proprietary N64 controller protocol.

The translation is fairly straight forward. The gamepads I'm interested in (I'll be using a Logitech Dual Action pad for my testing) have (at least) two sticks, a direction pad, four buttons and two shoulder buttons. There's enough here to map to the N64 layout, which is one stick, a direction pad, two buttons (A and B), a second directional pad (C) and two shoulder buttons. The left shoulder maps to the Z trigger or the real left shoulder, as they were never used together on the N64 due to the structure of the controller. The second stick on the Logitech pad will map to the C buttons, with some threshold to determine if the analog stick is considered "pushed" or not.

The USB side is interesting. Its pretty easy to build a AVR-based USB device. V-USB is a very good software stack to turn an AVR into a USB device controller, or you can use one of the numerous chips from FTDI. For a USB host however, the options are far less compelling. As far as I'm able to tell, V-USB does not implement a USB host controller at all. I had intended to use the FTDI Vinculum VDIP1, but as I mentioned previously, the cost of shipping is prohibitive. After some more searching yesterday I found SIAM32, a software USB host controller implemented by a student project team at Cornell. I think some combination of their code and the V-USB code should be enough to implement a minimal host controller and HID class, which is all I need.

On the other side is the N64 controller protocol. Although its proprietary, its long been studied and is pretty well understood. The most useful sources of information have been tzanger's n64dev page and Micah Dowty's Cube64 project.

Its a command based protocol. The N64 sends a command, and the controller sends the response. There's no provision for the controller to initiate a data send - the N64 regularly polls the controller by sending a "get status" command, to which the controller response by sending a data packet containing the current state of the buttons and stick. There's also commands in there ask the controller if its there and what peripherals it has attached (such as a rumble or memory pak), as well as reading and writing to the memory card. Its pretty simple really, which is good - I like simple.

The connection to the N64 has three lines - +3.3V, ground and data. Obviously the power lines play no part in the communication. All that happens on the data line.

The most difficult thing about the data protocol itself is its strict timing requirements, as it typical of a serial protocol without a seperate clock. The line begins in a high (logical 1) state, held there by a pull-up resistor in the controller itself (the line is never explicitly driven high by either end).

A single byte consists of eight data bits and one stop bit. A single bit is 4 microseconds wide. To start the bit, the sender pulls the line low for 1us. The next two microseconds are either high or low, depending on the value of the bit. The final microsecond is high, then it goes again. After all eight bits are sent, the final 4us are all high to signal the end of the byte. See tzanger's page - it has some diagrams that make it easier to follow.

What this means is that however I implement this I need to be able to sample or transition the data line every microsecond. At 16MHz, that means I need to do something every sixteen cycles. Most instructions on the AVR take a single cycle to execute, so there's plenty of time to do things in between, but because I need to be able to respond to the N64 sending data within 2us, its pretty much impossible to run the USB host out of the same AVR.

So my interface has two AVRs - one doing the N64 comms, the other managing USB. This complicates things as now some mechanism is required for the two AVRs to communicate with each other.

This is the bit I'm not quite sure about. I originally thought to have the AVR ports tied together such that the USB AVR could just chuck the current state on the port and the N64 AVR could read it whenever it wanted. This is no good though because the entire controller state is 32 bits wide - sixteen for the button state, eight for the analog stick X axis and eight more for the Y axis. I don't really have the bandwidth available to do it that way, not even with the larger AVRs, which would be overkill in every other way anyway.

I've been thinking about perhaps using eight lines and sending the data a byte at a time, but at that point I've now got the two AVRs needing to coordinate communication when they could both be interrupted at any moment, breaking the whole thing. It might work if I allowed the transfer to be interrupted and in that case the N64 AVR will just use the last button state, but then this means that the USB AVR would have to be constantly streaming the current state rather than just sending updates when transitions occur. If it didn't then a state transition could be lost if the transfer is interrupted.

There's always the option of putting four eight-bit latches in between the two AVRs and storing the state there, as they can effectively be thought of as memories with seperate read and write channels. This however means slower access (external memories access instructions take two cycles in most cases instead of one) which might present timing problems, as well as requiring more board space.

I need to study the AVR datasheets to figure out if any of the peripherals it comes with can help me out. I'm sure a simple solution will present itself, I just have to find it. Fortunately the need for it is quite a way off. The USB and N64 comms need to be developed first, and they need to be done in isolation to ensure they work correctly.

So that's where I'm at. So far I'm just getting my development environment setup. This week I've built myself an AVR programmer which is working nicely, so next I need to write a few basic programs and make sure my laptop is setup properly and I know what I'm doing. Then the real work can begin :)

sunday, 17 january 2010

posted at 22:20

Here it is, first post of the new year on the last day of my almost-four-week break from work. The time off has been awesome because I've gotten so much down. Apart from various parties and outings and other festivities, most of the first two weeks were spent organising the garage in a pretty serious way. I took almost all of my old computer gear to the local tip (who are participating in the Byteback program, making my culling reasonably environmentally-friendly). This is a pretty big thing for me, as I'm a hoarder and had kept all sorts of stuff (mostly for sentimental reasons) dating back to 1982. I've kept one working model of every computer and console I had for posterity and/or hacking, but have thrown all the extras and all the PC stuff I had that I'll likely never use. I've kept a few things that might have some actual monetary or other value as collectables, and I'll put those up on eBay when I get around to it.

As a result of all this, my garage has just about nothing in it, so I've set up a desk and sorted all my various electronics bits, tools and whatever so they're all nicely labeled and accessible. I even put in some halogen lights so the whole place is extremely well lit and I can see what I'm doing. And no computer in sight, though I am dragging the laptop out there with me.

All of this is to support this weeks' new hobby, which is getting back into hardware hacking in a pretty serious way. I'm not sure if its as a result of general burnout or because I'm now write code for my job rather than hacking to support my job as I was previously, but I found towards the end of last year that I just had no brain for code by the time I got home. I'm thinking that perhaps hardware is close enough to what I know to hold my interest and not be completely impossible, but different enough that there's room in my brain for it. Time shall tell.

Anyway, back in May I bought a RGB-to-HDMI converter and did some work to get my Amiga going on my LCD TV. As I mentioned then, my next project was to get RGB out of my Nintendo 64 so that I could play it without it looking horrible. I began work on what seemed like a fairly modest project: to build Tim Worthington's N64 RGB DAC using discrete logic rather than a CPLD (which at the time seemed way to complicated).

At the time I didn't really want to commit any money to this project as I didn't know if it was something that I was actually capable of doing. Since I had some stripboard, connectors and most of the other parts I'd need I opted to just build the thing on stripboard and buy the few chips and resistors that I'd need.

In hindsight this turned out to be the wrong decision. Routing data buses on stripboard means a lot of bits of wire flying around, and it doesn't help that the board has to be small to fit inside the case. Over the course of the next couple of months I got perhaps three-quarters of the way there, and after a big effort in the last two weeks I produced this monstrosity:

Yeah, I know. There's more pics on Flickr but it doesn't get any prettier.

There's not much to it. Its four data latches (one for each of red, green and blue and one for the control lines), a couple of support chips and three R2R ladders.

In spite of the mess I still had high hopes for it, so I hooked it up and to my great surprise it (sorta) worked. Here's what Super Mario 64 looks like on my TV with the standard composite cable:

The major thing I'm trying to fix here is the weird "hatching" effect on high-contrast edges (like the life/star counters). Its not bad in static screens, but once things start moving its a horror on the eyes; its pretty much impossible to play.

But, with the magic of wires, we get this:

As you can see, everything is nice and crispy, which is was the desired result. Some of the colours are off though, which obviously isn't right.

Another example, this time from Yoshi's Story:

Composite:

RGB:

I haven't had the chance to really think about it in depth but with the way that the colours are generally brighter and Mario's clothes are washed out, and the way the other colours appear, my gut feeling is that I've wired the inputs to the R2R ladders wrong in such a way that they're off by one bit. With the board being so insane though I figured I have pretty much no chance of debugging it and even if I do figure it out its going to kill my fingers to try and make any changes to the board.

Actually getting the damn thing to work though has given me a lot of confidence and so I've decided to build it again, but this time done right, which means a real PCB. So over the last week I've been teaching myself how to use Eagle, a circuit and PCB designer that seems to be pretty popular. The learning curve is pretty steep, but I've made some good progress with it.

The first thing you do is draw the circuit. I've pretty much just copied Tim's design, getting this:

Next comes the board layout. Its pretty straightforward: setup the board size, place the components, then add all the wire routes to the board. The last bit is made simple using Eagle's autorouter. Various forums and whatnot suggest that real board designers don't use the autorouter, but I don't care - it seems like it will work well enough and I'm just a noob here so I'll take all the help I can get.

I also found a wonderful little program called Eagle3D which produced 3D renders of Eagle boards, including components. I ran mine through it to see what it would look like and got this:

Top side:

Bottom side:

I'm feeling pretty good about this! I'll sit on this for a couple of days just to make sure I've got it right, then I'll send it off to BatchPCB, a PCB fabrication service that will do short runs (even one) for reasonable prices.

I've no doubt that I've missed something, and it won't work properly the first time, but at least this board can be debugged. I see some good looking games in my future :)