To allow programming, we're making cheap serial interface cables for the NES, with the NES implementing the UART in software. The basic design uses a MAX232 or equivalent to convert between the NES 5V and RS232 +/-12V signals. An alternate design uses an
FTDI TTL-232R cable which has a USB connector on one end, and bare wires on the other with 5V serial signals. While more expensive, the cable can be made by literally just splicing it to a NES controller cable. With some heat-shrink tubing, such a cable would look very elegant.
Can you (or somebody else) enlighten me a little how this would work in practice. Are the RTS# and CTS# signals of the TTL-232R used at all? (What are those signals used for?) Also is the NES controller "CLK" used?
I really would like to buy a NES<->USB cable like this or make one myself. So many cool applications when used together with PowerPak.
No, currently flow control isn't used (the NES has only one output, unfortunately... maybe that could be used as CTS and Tx). byuu is donating an FTDI cable to me in a few days, so I'll know for sure how well they work out. In theory, you just connect GNDs together, NES strobe out to Rx on the FTDI, and NES D0 to Tx on the FTDI. Three splices you could do with just a pair of scissors and some houshold tape, if you had to. That's why despite the cost of the FTDI cable, I believe it has many advantages for cheap construction by anyone. Props to byuu for discovering this cable in the first place.
blargg wrote:
No, currently flow control isn't used (the NES has only one output, unfortunately... maybe that could be used as CTS and Tx). byuu is donating an FTDI cable to me in a few days, so I'll know for sure how well they work out. In theory, you just connect GNDs together, NES strobe out to Rx on the FTDI, and NES D0 to Tx on the FTDI. Three splices you could do with just a pair of scissors and some houshold tape, if you had to. That's why despite the cost of the FTDI cable, I believe it has many advantages for cheap construction by anyone. Props to byuu for discovering this cable in the first place.
Ok thanks. Let me know how your tests go. I ordered the FTDI USB cable a second ago so I'll probably test some stuff myself also.
Here's a super-cheap interface I just built. Works so far at 57600 bps with one serial port I've tested it with. You can of course build both to get bidirectional data transfer. The serial port I tested with outputs about +/-5V signals. The NES-to-PC output only goes down to about -2.6V, which isn't quite to spec, but it works so far. The diodes and transistor are common-variety small-signal.
Mods: please split theFox's question and our exchange after that into a separate thread about PC to NES serial interfaces. Thanks.
I think for my serial cable I'll be using the MAX232 because I want to use it with some hardware that is certainly outside the correct voltage range and has a tendency to get a bit finicky if it doesn't get the expected voltages returned either.
The schematic Blargg posted will probably work fine with 90% of PC serial ports, but I'd personally be careful using it with other serial sources such as vintage computers etc. because of the differences in adherence to RS232 between hardware platforms then and now.
Cool, flow control is actually working. I just made a duplicate circuit like the NES-to-PC one above and hooked that to CTS, and am able to have the serial receive run with as much delay as I want between bytes without losing any. The host gets garbage bytes in return, but it can just discard those or wait for a header if receiving any data from the NES afterwards.
I also found a page saying that modern serial ports accept 0V and +5V as the two levels, rather than requiring a negative voltage, so the transistor driver above might not even be necessary.
The next step is to try this on a USB-to-RS232 adaptor, and the built-in serial on a different PC, see whether it's just this computer's serial that happens to like this arrangement.
What is the practical limit for receiving on a NES? Is 115200 possible at 15.5 cycles / bit? It might be time for me to lose the LPT solutions if everyone jumps on RS232 :P
Ahhh, the problem with the higher rate was the lack of time between receiving bytes to process them. This flow control addition might make that possible now! Dusting off the old 115200 routines again...
EDIT: Argh, running into problems with flow control even at 57600. Trying to make sense of the problem. So maybe flow control won't work.
I read that 3% tolerance is common with UART; at 115200 baud on the NES you're you are closer to 4% fast or slow transmitting.. I wonder if this is a significant problem. Timing can be modulated for correct baudrate but the skew would probably throw off the receiver more than the off frequency.
Here's an output routine for 115200 using 16 cycles / bit (111861 baud):
Code:
jsr here ;6
ldx #9 ;2
asl a ;2 - 10
loop:
sta $4016 ;4
lsr a ;2
sta zpg_garbage ;3
sec ;2
dex ;2
bne loop ;3 - 16*9+15
rts ;6 - 175 cc total
Well, I'm kinda clueless about how best to handle serial communications. The best I can do with serial is vintage computer stuff, and most of my gear actually tops out at 19200 baud.
Are there USB to
SPI-slave adapters? The clocked-serial protocol for NES controllers and Game Boy Game Link looks a lot like SPI. Connect SCLK to clock, MOSI to strobe, MISO to D0, and /SS to a
one-shot multivibrator from strobe.
A big benefit of using serial (even if just a USB-serial adaptor) is that the host-side drivers use a well-worn protocol. You don't have to mess with special drivers or communication models when using serial, so it's easy to port to different operating systems. That's not to say you couldn't have a microcontroller with a USB interface to the PC acting like a serial device, but giving the NES a clocked interface (maybe that was your point). If someone wants to release such a cable for the NES, please do!
If anyone wants to step back to LPT days, I have a clocked-serial solution (4-bit I/O w/ handshake) that will fit into a 20 pin GAL/PALCE/PEEL chip (or probably 4x 74 series chips). I believe it can achieve approximately 16KiB/s but haven't bothered to build it. Surely a USB MCU is more convenient, but neither the software nor firmware will exactly be a breeze.
OK, now that I'm using something more normal for RS-232 (was using my old Mac, with its RS-485 ports or whatever it has), flow control is working well. This USB adaptor (based on the PL2303) accepts 0 and +5V signals, so no driver transistors are even needed. Now, to try 115200 again.
EDIT: Sweet, 115200 with flow control is working great for the initial tests, and there's plenty of margin for timing error (I can add/subtract around 7 cycles between the start bit detection and the data bit reads before it gets errors).
EDIT: And passes the 4K random data receive test. 115200+flow control is where it's at!
EDIT: I found that on my old Mac, when you deassert CTS, it sends 13 more bytes before it stops! This would explain the problems I had with it. I'm thinking this can be worked around on the NES side, by being ready to buffer a few more bytes after deasserting CTS. Going to try implementing that without lots of overhead.
EDIT: Works. Even with the host sending an extra 13 bytes after deasserting CTS, this doesn't lose any bytes, and the processing code can take as long as it likes. This can handle the host sending up to 255 extra bytes, which is probably more than anything sends after you tell it to stop.
i might add in that i've designed a Console <->USB adapter (~5.5x2.5x3cm box + cables) which uses serial communication with the console and communicates with the computer with a ft232 chip (to make it as robust and cross-platform as possible).
IIRC it should be able to transceive a byte in ~185 cycles, so it should be possible to make it quite fast. it should also be capable of being interrupted by DPCM every now and then without it interfering with the communication.
would anyone be interested in such a device?
blargg wrote:
OK, now that I'm using something more normal for RS-232 (was using my old Mac, with its RS-485 ports or whatever it has), flow control is working well. This USB adaptor (based on the PL2303) accepts 0 and +5V signals, so no driver transistors are even needed. Now, to try 115200 again.
Just to be clear, you're using both controller ports for this stuff?
No, just one controller port (so the other is free for a controller or whatever). It can work with either one of course. It would actually work fine even with two controllers connected, if I used one of the other data input pins exposed on the connector. Basically you'd modify an extension cable to have taps into GND, +5V, Strobe, and D3 or D4 (rather than D0 as currently).
The ultra-cheap interface works on the built-in serial ports on my Dell Precision 360, and the USB-serial adaptor. The Dell's serial ports are like my Mac's: even when you deassert CTS, it sends around 16 more bytes. With the buffering scheme, 115200 is working excellently, and now flow control only sends 00 bytes to the PC, rather than junk values.
Ultra-cheap interface (I added an extra resistor for extra protection of the NES input):
For NES to PC, just connect Strobe output from NES to 220 ohm resistor to Rx and CTS on RS-232 port.
I also concluded that unless you're going the ultra-cheap way, you might as well use a MAX232. The transistors and resistors would be a mess to do without a board, and they draw current.
Next, to try having the NES read RTS, so that it can tell whether there's even any data from the PC.
I wonder how a NES to RS232 would compare to the Miracle cable?
blargg, flow control sounds really cool, how can all this work using one port? I never tried using more than tx/rx because there aren't any more wires in the usual controller cables (other than clock).
Another build option that I didn't consider when I first built these, was to connect it to the NES mainboard's controller connector. Then you could be free to use any of the data bits, as well as pass the controller harness wires through. With just 2 IDC connectors to hook up + the needed serial/usb line, this would be an easy-to-install system mod for people, I think. If there was a way to cut case's plastic cleanly, you could have some kind of panel-mount RS232 connector on the back of the system.. that would look hilarious.
dwedit: I have a Miracle cable, it's sealed shut pretty well so I don't know what's in it. I can only see a hint of some green PCB soldermask.
Memblers, the NES Strobe output connects to Rx and Clear To Send on RS-232. That's how it does flow control with only one output. When asserting CTS, I have it assert it for at least 10 bit periods, so that the host interprets it as a $00 byte (or break, since it has no proper stop bit). This is the main downside, but it wouldn't be hard to make the protocol such that it can skip these extraneous bytes on the host side. This also means that when the NES is sending to the host, it will be asserting CTS even though the NES isn't ready to receive, so the host mustn't send any data while the NES is sending since it would get lost.
I've gotten 115200 working very well now on all three hosts (including a SNES implementation), using the ultra-cheap or usual MAX232 approach. The code buffers input, and allows you to find out whether there's any incoming data. Sending 32KB of data to the NES without any further processing runs at about 9.1 KB/sec. The buffering unfortunately adds some overhead. For a run of code that can process data at full rate and doesn't need flow control, you could get the full 11.52 KB/sec maximum throughput, though you'd have very little time between bytes (around 20 cycles). I'll post plans and code hopefully later today, after I take advantage of this nice day to get outside some.
Quote:
If there was a way to cut case's plastic cleanly, you could have some kind of panel-mount RS232 connector on the back of the system.. that would look hilarious.
Awesome, I love this idea! If you put a USB adaptor in, you could even have a standard USB square jack on the back of the NES.
I happened to have a NES extension cable that connects all pins, so I can try using D3 or D4 for serial data, and have it pass eveything else through to allow two controllers and serial connected at the same time.
Can someone expand on what this is being/will be used for? I've read the thread in full and I just don't see the purpose. Edumakate me.
koitsu: The split notice in
the first post should clarify things. It's for a rewritable MMC1 flash cartridge.
blargg wrote:
Memblers, the NES Strobe output connects to Rx and Clear To Send on RS-232. That's how it does flow control with only one output.
Ah nice, double duty for the strobe line. If the PC will be getting 00's (I forget what will happen without the stop bit) then it seems similar to xon/xoff flow control, at least in that there will be essentially control bytes needing to be dropped out of the data stream. That would mess up compatibility, but that's not the case I hope?
I remember hearing that many UARTs will keep sending bytes after telling it to stop, like you noticed. I guess that would be flushing its FIFO buffer, so if it stays under 16 bytes that wouldn't be too bad.
The main reason I've been concerned about PICs and a "smart" adapter not being used is because I want it to be compatible with software written with for Squeedo, where an IRQ is used for the UART receiving. So if one wanted to play the same program on a cart without a UART or IRQ (all of them?), you can just poll (and really, that's just as good). As long as it's 100% safe and done synchronously, so NMIs, DPCM, SPR-DMA, is not a problem (though at least DPCM can be worked around, as mentioned).
Well maybe DPCM would cause a bunch of problems anyways, judging by the way controllers work with it (in a synchronous mode). That sucks.
Quote:
I happened to have a NES extension cable that connects all pins, so I can try using D3 or D4 for serial data, and have it pass eveything else through to allow two controllers and serial connected at the same time.
Actually one thing I've been wondering about, is that these signals also exist on the expansion port. What are the potential problems or benefits of this (when having any kind of device attached to both ports)? I guess if nothing else, an RS232/USB mod should be standardized to one of the ports (I'd say #2).
thefox wrote:
blargg wrote:
No, currently flow control isn't used (the NES has only one output, unfortunately... maybe that could be used as CTS and Tx). byuu is donating an FTDI cable to me in a few days, so I'll know for sure how well they work out. In theory, you just connect GNDs together, NES strobe out to Rx on the FTDI, and NES D0 to Tx on the FTDI. Three splices you could do with just a pair of scissors and some houshold tape, if you had to. That's why despite the cost of the FTDI cable, I believe it has many advantages for cheap construction by anyone. Props to byuu for discovering this cable in the first place.
Ok thanks. Let me know how your tests go. I ordered the FTDI USB cable a second ago so I'll probably test some stuff myself also.
Got my FTDI cable (really fast delivery!), now to run some tests.
If anybody has got any NES/PC (FTDI VCP/D2XX) transfer software to share please do so.
Ah, there was a Pitfall clone for the NES someone wrote, I gave him XMODEM code to use for saving/loading in the level editor, he put it in there but it was never tested (since I didn't have my system hooked up around that time). Try that one if you can find it.
Also here is the XMODEM routine if you want to try assembling it. I'm at work so I can't dig up any other stuff at the moment.
http://www.parodius.com/~memblers/nes/xmodem.asm (look for Get_Chr and Put_Chr for the main parts that might need adjusted).
Blargg has some test code coming. He has already given part of it to me, but he'll be releasing it here soon.
Well, I wore myself out yesterday in the heat, and got bogged down today. Trying to finish this code release. For now I've got a test ROM that checksums any files you send to it:
checksum_file.zip. This assumes a MAX232 or FTDI cable that inverts the signals connected to the second controller port, with Strobe driving Rx and CTS, and D0 connected to Tx; it won't work with the cheap versions posted here. You must use hardware handshaking as well. Send a binary file to it at 115200 bits per second, 8 data bits, 1 stop bit, no parity, and it updates the total bytes and CRC-32. Once you stop sending for 50 msec or more, it updates the final size and checksum, AND sends the checksum as ASCII back to the PC. You can then send another file as before. Also, this is NOT a demonstration of the transfer speed, as it uses a relatively slow CRC algorithm. I've measured buffered transfer at about 9.6 KB/sec, not that bad compared to the theoretical maximum of 11.52 KB/sec.
I'm running a 16 MB test file as I write this, should take about an hour. I'm hoping for zero errors.
EDIT: 16 MB test took an hour and passed the proper CRC-32. Since the test ROM regularly waits for VBL and updates the current time, and CRC updates take a variable number of clocks, this was a good test.
And, here is the source code, the demo source and NES ROMs, and some documentation:
serial_115200.zip
Hmm I guess I'd need to tweak the timing for PAL NES. Thanks anyways for great work once again blargg.
I wonder what the fastest theoretical speed for receiving would be with custom hardware. I.e. the code in NES side would be string of something like LDA $4017 and hardware (like a custom PowerPak mapper) would take care of shifting the data and so on (could also calculate checksums and stuff). Would it be something along the lines of 400kbit/s or am I forgetting something? Are there any instructions on 6502 that reads the same address twice that could be utilized to get faster speed? Just a thought.
If you want the absolute fastest method, put the USB-in port on the cartridge too. Then you can simulate a bidirectional parallel port instead of a serial port. This can be an order of magnitude faster than serial even at USB low speed.
tepples wrote:
If you want the absolute fastest method, put the USB-in port on the cartridge too. Then you can simulate a bidirectional parallel port instead of a serial port. This can be an order of magnitude faster than serial even at USB low speed.
Nah I'm thinking about something that I could do with just controller port cable + PowerPak here.
thefox wrote:
Hmm I guess I'd need to tweak the timing for PAL NES. Thanks anyways for great work once again blargg. :)
Oh, you need PAL? I haven't tried that with 115200 yet. I know 57600 works very well on PAL though, but I haven't implement flow control for that speed yet.
Quote:
I wonder what the fastest theoretical speed for receiving would be with custom hardware. I.e. the code in NES side would be string of something like LDA $4017 and hardware (like a custom PowerPak mapper) would take care of shifting the data and so on (could also calculate checksums and stuff). Would it be something along the lines of 400kbit/s or am I forgetting something?
Yes, the fact that a controller port has three data input bits. So you can get around 1.5 Mbps. But this is of course just for a bitbucket read. To actually save the data, you'd need at least 7 cycles per bit triplet (LDA $4017 : PHA), so about 770 kbps.
I interpreted thefox's suggestion as referring to something that
snoops D3 and D4 of every $4017 read and constructs a byte for a mapper register.
Code:
:
bit $4017
bit $4017
bit $4017
bit $4017
lda $5017
sta $0200,x
inx
dey
bne :-
tepples wrote:
I interpreted thefox's suggestion as referring to something that
snoops D3 and D4 of every $4017 read and constructs a byte for a mapper register.
Yes, although I was actually thinking about reading D0 only (rest of the pins aren't connected on my cable). When using the PowerPak it could even buffer the bytes in the FPGA Block RAM (3K I think on PowerPak). I'll probably look in to this later...
blargg wrote:
thefox wrote:
Hmm I guess I'd need to tweak the timing for PAL NES. Thanks anyways for great work once again blargg.
Oh, you need PAL? I haven't tried that with 115200 yet. I know 57600 works very well on PAL though, but I haven't implement flow control for that speed yet.
I forgot that I can set arbitrary baud rates in D2XX. I set the baud rate to 107265 (the actual rate that the 232R uses isn't exactly this but close enough) and it works on my PAL NES.
Here's a doc about baud rates on FT232R if anybody needs it:
http://www.ftdichip.com/Documents/AppNo ... dRates.pdf
EDIT: I'm not sure how I should be handling these "garbage" bytes on the PC side though. My code works like this:
- writes 0x1234 bytes with FT_Write()
- waits couple of seconds (the amount of bytes received stays same regardless of the delay)
- gets number of bytes in the buffer with FT_GetQueueStatus(): it's always 660
- reads those bytes in with FT_Read()
The 660 bytes that FT_Read reads are 138 bytes of zero (presumably from asserting CTS?) then comes 510 bytes of alternating 0xFF, 0x00, then checksum+cr+lf, then 2 more bytes of zero.
My question: what are those 0xFF, 0x00 in there and how should I properly skip the garbage? Is it required to skip all 0x00/0xFF (and escape them when needed) or is there a better way?
I feel like an idiot asking all these questions.
I know that on one of the chinese clone USB-TTL adapters I picked up (they are 3V and I haven't tried them on an NES port), by cross-wiring the TX/RX and testing in hyperterminal, it didn't care what the baud rate was, it worked with all of them.
I know for the PICs that do baud-rate autodetection in hardware it requires sending $55 or $AA I think, though. But all sorts of tricks could do it in software as well.
Hayes Smartmodem and its hundreds of clones did baud rate autodetection by timing the bit pattern for ASCII "A" and "T".
thefox wrote:
The 660 bytes that FT_Read reads are 138 bytes of zero (presumably from asserting CTS?) then comes 510 bytes of alternating 0xFF, 0x00, then checksum+cr+lf, then 2 more bytes of zero.
Hmmm, I'll have to investigate. I'll be getting an FTDI cable soon, and can see whether it behaves the same.
It
might be that it's interpreting the CTS/Rx assertions as break signals (basically where the line is held in a space state through the stop bit, so that it's not a valid stop bit), which is actually what I intended for them to be in the first place. I've noticed that serial drivers often have a way to insert a particular character in the case of an error. Perhaps yours is set to insert $FF in the case of a break signal, and you could change it to $00. I don't see any mention of this in the documentation, though.
You know, the timing of CTS/Rx isn't always a multiple of 10 bit periods, so it might be my code. If this is the case, the junk byte should be limited to $00, $01, $03, $07, $0F, $1F, $3F, $7F, or $FF. So your protocol could simply begin the valid data back to the PC with a byte like $55, something that could never occur due to flow control on the NES side.
Quote:
I feel like an idiot asking all these questions. :roll:
It's just collaborative problem-solving. It's too bad the code has to be so complex, but the way the PC can send data after the NES has deasserted CTS requires it.
If you don't need flow control or extreme speed, and can process each byte fairly quickly on the NES, the 57600 code I've been using for years is solid and very easy to follow.
blargg wrote:
If you don't need flow control or extreme speed, and can process each byte fairly quickly on the NES, the 57600 code I've been using for years is solid and very easy to follow.
Yeah I don't "need" anything per se currently, just playing around. Hoping to have a development system with PowerPak+FTDI cable that I could use without swapping the CF card all the time. It would also make PowerPak mapper development a lot easier.
So for now, the 57600 code would do just fine for me. Is it already available somewhere?
Yeah, here's the 57600 code, which I just tested on NTSC and PAL NES:
serial_57600.s
No flow control, so you don't get garbage to the PC when receiving. Source is well-documented.
Yesterday I got PC->PowerPak transfers working using blargg's 57600 code. So it works like this:
- boot up the PowerPak (all the normal menus are skipped)
- NES waits for transfer
- PC transfers PRG, CHR and FPGA config (mapper)
- game/demo automatically runs when transfer is done
When power is cycled it waits for a new transfer, although by modifying the mapper this can be done by pressing RESET also.
TODO:
- transfer game genie codes
- CRC checks
- faster transfer
- check for differences in files and only transfer what has changed
- transfer WRAM PC->NES
- modify the normal "save WRAM to CF" menu to transfer it back over the cable instead
EDIT: PRG/CHR size and mirroring settings no longer hardcoded, now the PC app can read iNES files directly
thefox wrote:
Yesterday I got PC->PowerPak transfers working using blargg's 57600 code.
Now this is something I'd actually be interested in!
tokumaru wrote:
thefox wrote:
Yesterday I got PC->PowerPak transfers working using blargg's 57600 code.
Now this is something I'd actually be interested in!
If you have a cable I can release the replacement PowerPak mapper file and the protocol for testing. The software I have only works with FTDI chips, I should probably make it use the the COM ports directly since the FTDI chips can show up as COM ports anyways.
I also added support for blargg's 115200 bps code. Still no CRC I but wouldn't worry about it too much.