So I noticed that microchip now has the PIC18F66J60 microcontroller that has a built-in 10base-t mac/phy. There is also a reference implementation for a full TCP/IP stack that runs on the chip that is available for free. I think this presents the best opportunity for getting the NES connected to ethernet via the expansion bus.
If pin 4 on the expansion but really is the R/W signal line from the 2A03, then it would be trivial to interface the 2A03 with the PIC. Since the only address line available on the expansion port is A15, that means the I/O register could be anywhere in the memory range $8000 - $FFFF. The entire data bus is on the expansion port so talking to the PIC microcontroller is as simple as reading and writing to whatever memory address you pick for the I/O register.
Since the mappers typically use memory mapped I/O in the upper memory ranges for controlling bank switching, I think it would be wise to come up with a scheme for turning on/off the ethernet adapter. That way, when power is turned on, the PIC would ignore any reads/writes to the any memory in $8000-$FFFF. To turn it on, the external device output pins (#37 and #38 on the CPU -> #44 and #45 on the expansion port) could be used to trigger an a wakeup IRQ in the PIC which would turn it on.
Since there is only one address line, there would only be one I/O register. That means a simple serial like command/response protocol needs to be used to talk to the PIC. The 2A03 would write a command and parameters to the register, the PIC would clock them in, decode it, then pull on the 2A03's /IRQ line when the response is ready. The 2A03 would then read from the register, clocking the response bytes back from the PIC. Once this whole thing is working, then pretty much any command/response could be implemented.
On top of the that protocol, a routine for detecting the ethernet device and a simple network library could be built. Commands for creating a socket, configuring it, connecting, disconnecting, writing data, reading data, etc.
The idea sounds good to me, and inexpensive. Nearly ideal use of the expansion port.
I hate to say it though, but the expansion port itself is the big hurdle. The main issue is that it's custom, I was never able to find a connector suitable for it (admittedly it's been years since I looked but I'm doubtful anything changed). The 2nd more minor issue is that it's only available on the original NES, not the NES2, Famicom, A/V Famicom, or multitude of clones.
It makes a lot of sense to have something like this as an expansion rather than a dedicated cart. So I still think the most viable options are a cart or controller port adapter. The obvious disadvantage to the controller port is the lack of an IRQ. I suppose a cart that needed it could have an IRQ pass-through connector on it (or use the exp connector), but any wiring or expensive custom parts seem to make it less useful for people besides developers and hackers.
Of course the circuit could be pretty easily adapted to fit on a cart too, if the cart has something cool enough.
I'd really like to see something like this work.
So far, my main idea for network access on NES is over USB/RS232 to PC. It helps that I already have that link, so anything else I can do with it is pretty much "free".
As for some practical reasons, it might be pretty cool to have PC clients and servers that share and init games when when opponents are ready the incumbent can start the game. You could probably even chat via a same computer on the LAN instead of messing around with adding extra hardware support to the NES.
Above all, being a sound engineer, would be cool to sync different NESes to play music together.
What about remotely controlling the NES and launching code via ethernet with a dummy receiver ROM?
What sort of other applications would you all be thinking about?
What sort of other applications would you all be thinking about?
8-bit MMORPG
a NES-based BBS system or web server would be baddass, as would a lynx type text based web browser
custom/expanding level data pulled from a server or networked games would be fun as well
Quote:
Above all, being a sound engineer, would be cool to sync different NESes to play music together.
i'd like to figure out a way to implement midi-in via a controller port without a special mapper.. the miracle keyboard game used a controller port as a midi port i believe. Then it would be eas(ier) to sync a couple neses to play together. i want to make a nes sampler so midi support would be major
bad news. pin 4 on the expansion port is connected to /NMI on the CPU, not R/W. That means, there is no way for an expansion port device to map to a specific hardware address.
If R/W were on the expansion port, then the combination of R/W, A15, and D0-D7 would make it trivial for a device to map to any address between $8000-$FFFF. A15 would be the chip select signal and the R/W would be the signal for a read or a write.
But, since there isn't the R/W signal, I've got to figure out something else.
There's always the expansion pins on cart, I can't see any major disadvantage to using one to pass the R/W signal to the exp port.
That is a possibility and probably what the Nintendo engineers intended to do. That would mean that they could control which carts can access expansion devices. Only carts with the R/W pass-through would work.
That is the path of least resistance. I'll just do that.
BTW, I was able to find card edge connectors with the right number of pins but the opening was too skinny. The fat card edge in the expansion port is too thick. My solution was to use a hacksaw blade to carefully slice the card edge socket into two pieces that fit snugly on each side of the expansion connector. It works for a one-off prototype, but won't work for anything production. I'm still looking around for a connector that will work as-is.
Awesome. I found a place that can make NES expansion port connectors:
http://www.sullinscorp.com/
Wookie wrote:
Awesome. I found a place that can make NES expansion port connectors:
http://www.sullinscorp.com/
Awesome, I want one!
When you can get an estimate how much those female connectors are let us know. That's set back a lot of development and innovation so far.
I know that I'm going off topic a little bit but if you would be able to get one of those connector, would it allow you do to the NES mod for famicom sound without the need to open your NES? I don't own a nes, I'm just curious since if I understand well, the pins for the sound are located there, aren't they?
yes, yes it would. I already have one NES modded for sound, but I DO NOT modify my original NES I've had since the 4th grade. I could use the connector to add sound to it without opening it.
I'm pretty sure Sullins part number EBC24DN will work. I just ordered a couple of samples so I'll be able to test it out in a few days.
To answer your questions, yes this would allow for you to easily create a plug in device that would route the audio in/out pins in the expansion port to some of the cart pins.
My ethernet adapter design includes the following details:
1. the audio in (exp. port pin 3) is routed to a cart pin for games to provide their own sound. (does anybody dare put a SID chip in a cart for some rockin' retro sound?)
2. any cart that uses the ethernet device needs to connect the R/W, and a couple additional address lines from the CPU bus to the expansion port pins to facilitate memory mapped I/O. I haven't decided which ones yet.
Well, consider this. There are 10 pins in the cart port that connect to the expansion bus. If the ethernet adapter routes the audio in pin to the cart, and the cart routes the R/W to the expansion port, that leaves 8 left over. With 8 pins, I think routing A12, A13, and A14 along with A0, A1, A2, A3, and A4 to the expansion port would make the most sense. That means the memory mapped I/O region could land at the following addresses: $8000, $9000, $A000, $B000, $C000, $D000, $E000, $F000. And with the 5 least significant address lines there would be 32 available registers. This would put the memory mapped I/O registers up in the program ROM area, which is fine.
Also, since the chip in the ethernet adapter is a regular PIC microcontroller, there is also the possibility of adding new features to the code on the PIC as long as the TCP/IP stack and NES bus interfacing code isn't changed. Floating point anybody?
I wasn't able to find a EBC24DN in a search.
The product number is generated based on features. Download and look at their product catalog pdf file. The part I ordered samples of is listed on page 38 and 39 of the catalog. On page 39, it shows you how to generate the product number for the part you want. The part number I used was EBC24DKSN which means the following:
E - PBT/Phosphor Bronze (Standard) Materials
B - 0.000010" gold plating (Standard)
C - contact centers are 0.100" apart (matches expansion port)
24 - the number of positions (48 contacts)
D - Dual Readout (pins for both sides)
KS - Cantilever bellows (this puts the contact point as close to the opening as it can be to make sure that it gets deep enough to make contact)
N - no mounting holes
More good news. I was looking over the datasheet for the PIC18F97J60 and it says the following:
Quote:
In addition, one of the general purpose I/O ports can be reconfigured as an 8-bit Parallel Slave Port for direct processor-to-processor communications.
This is exactly what I had in mind. I've got to look at the specs to see how many lines, in addition to the data lines, are needed to drive this interface. This will make it trivial to connect the 2A03 to the PIC for mmap I/O communication.
Only the 100-pin TQFP version of the PIC has the parallel slave port.
Here's a Schmartboard for prototyping with the 100-pin TQFP with 0.40" pitch:
http://www.schmartboard.com/index.asp?page=products_qfp&id=72
OK, so I worked out a pretty good design for the EtherNES:
Here's a quick description of how it is laid out:
1. Any cart that wishes to use the EtherNES must connect pin 14 (2A03 R/W) to pin 16 (Exp. 42) on the cart as well as pins 39-41 (2A03 A12, A13, A14) to pins 52-54 (Exp. 7-9). This routes the CPU's R/W signal and the remaining MSB address bits to the expansion port.
2. The EtherNES connects expansion port pin 3 (premix audio in) with expansion port pin 6 (cart pin 51) giving carts the ability to inject custom audio into the mixer. It could be fun to put a SID chip on a cart and create a SID player for the NES.
3. The connection between the expansion port and the PIC18F97J60 is done using exp. pins 5, 7-9, 14, 25-32, 42, 47, and 48.
4. Pins 25-32 are the data lines from the CPU bus. The logic coming from the CPU is 5V logic but the PIC can handle voltages up to 6V on it's I/O pins (in digital mode) even though it is a 3.3V part. The data lines are connected to the parallel slave port (PSP) data lines on the PIC.
5. Pin 5 and pins 7-9 from the expansion port is connected to the PSP /CS pin on the PIC through some logic that drives the /CS low when A15 is high and A12-A14 are low. The EtherNES will be memory mapped to $8000-$8FFF. Any read/write to that memory range will activate the PSP connection between the 2A03 and the PIC. I know this cuts a big hole in the cart ROM area but with a good mapper, you should be able to get around it.
6. Pin 14 is the 2A03 /IRQ signal. This is pulled low by the PIC whenever a packet is received. My design has it tied to the PIC's port B, pin 0 so all I have to do is write 0 to port B to interrupt the 2A03. The 2A03 will then handle the wakeup by sending the read packet command to the PIC and reading by the bytes to process them.
7. Pin 42 is the rerouted 2A03 R/W signal. It is connected to the PIC's PSP /RD and /WR lines. The connection to the /RD line is inverted. This means that when the 2A03 is doing a read operation, it drives the R/W line high which in turn drives the PIC's /RD line low and the /WR line high signaling a read. During a read, I think the PIC fires an internal interrupt to handle the read on the bus. The interrupt handler must write the next byte to the PSP bus. When the 2A03 is doing a write, the R/W is driven low which in turn drives the PIC's /RD high and /WR low. This causes the PIC to latch the data that is on the PSP data bus and then fire an interrupt for processing.
8. I'm going to use an LM3940 to step down the 5V from the NES to the 3.3V needed by the PIC.
9. The design calls for an RJ-45 MagJack ethernet port with integrated magnetics and LED's. The PIC's integrated ethernet MAC and PHY are connected to it.
10. The PIC only uses a 25MHz external clock connected to OSC1 and OSC2. The 25MHz reference clock is required for the ethernet to function. There's no need to provide a secondary clock because we're not really concerned with low-power modes.
11. There is also an ICSP for programming the PIC.
12. The logic that decodes the address lines to generate the chip select logic should probably also generate the reset trigger for the PIC. I'll have to look at this, but when the 2A03 is reset, it accesses a specific memory address to read the next address to jump to. If we detected the reset vector read and generated a reset to the PIC, punching the reset button on the NES would also reset the EtherNES. I'm not sure if this is necessary, but just something I thought of just now.
I talked to the Sullins connector people and it looks like they don't have a standard COTS part that will mate with the expansion port. I'm going to have to talk to them about having custom ones made.
Does anybody here have expertise in designing PCB's using Eagle or one of the other PCB cad tools? I could use some help. I'm 90% sure that my schematic will work. I just need some help getting the parts laid out in a PCB design that can be ordered from one of the PCB fabs.
[
Extra WIIIIIDE image]
(The graphic is wrong, now that I've written this all out. The SN74LVCC4245A buffers are not needed and I need to route three more address lines from the cart port to the expansion port to force the memory mapping to $8XXX.)
Wookie wrote:
12. The logic that decodes the address lines to generate the chip select logic should probably also generate the reset trigger for the PIC. I'll have to look at this, but when the 2A03 is reset, it accesses a specific memory address to read the next address to jump to. If we detected the reset vector read and generated a reset to the PIC, punching the reset button on the NES would also reset the EtherNES. I'm not sure if this is necessary, but just something I thought of just now.
Alternatively, the NES could issue a soft-reset command to the PIC (detect the reset on the NES side in software, easy to do by setting a pattern to unused RAM after testing for it - I like the upper $100 page since no one hardly uses that area).
Quote:
I talked to the Sullins connector people and it looks like they don't have a standard COTS part that will mate with the expansion port. I'm going to have to talk to them about having custom ones made.
Yeah I didn't think it'd be that easy, but it looks like this can be pulled off.
Quote:
Does anybody here have expertise in designing PCB's using Eagle or one of the other PCB cad tools? I could use some help. I'm 90% sure that my schematic will work. I just need some help getting the parts laid out in a PCB design that can be ordered from one of the PCB fabs.
I do, I've done several NES boards. Here's my best example,
Squeedo rev2. I would be interested in helping out and doing the board layout. Also notice the PIC on the Squeedo PCB, I'd like to play around with that too. I could probably pretty easily run my sound synth code on the PIC you'll use.
Wookie wrote:
OK, so I worked out a pretty good design for the EtherNES:
Here's a quick description of how it is laid out:
1. Any cart that wishes to use the EtherNES must connect pin 14 (2A03 R/W) to pin 16 (Exp. 42) on the cart as well as pins 39-41 (2A03 A12, A13, A14) to pins 52-54 (Exp. 7-9). This routes the CPU's R/W signal and the remaining MSB address bits to the expansion port.
2. The EtherNES connects expansion port pin 3 (premix audio in) with expansion port pin 6 (cart pin 51) giving carts the ability to inject custom audio into the mixer. It could be fun to put a SID chip on a cart and create a SID player for the NES.
This isn't very powerpak friendly since the powerpak already uses pin 54 (exp 9) for audio. Wouldn't it be possible to use pins 51-53 (exp six - eight) Instead, and bridge expansion pins 3 and 9 as the powerpak requires? I'm not sure if the powerpak has the ability to use expansion pins other than 54, but if it does you could use it for developing ethernet capable games.
BTW this is an exciting and ambitious project. I can't wait to see how it comes out.
I do firmware (and some hardware) for PIC micros for work, if I can help.
Super-Hamster is right about the PowerPak pins. I plan on developing my EtherNES compatible game using a PowerPak Lite that I plan on modifying to route the right signals to the expansion port.
I haven't looked at the PowerPak Lite schematic in any detail at the moment. I propose that we choose pins that don't conflict with the popular dev carts.
I appreciate the offers of help. It's going to take all of us to pull this off.
Memblers, what PCB CAD tool did you use for the Squeedo? I'm trying to learn PCB CAD tools and manufacturing. lidnariq, we'll probably need your help getting the parallel slave port (PSP) working. I'm not sure if my design is correct, I still need to read the datasheet a little more.
I think the next steps are this:
1. Talk to the Sullins connector people and get a quote for a custom connector that mates with the expansion port. I'm thinking I'll probably have to scavenge a port from a dead NES and mail it to them.
2. Draw up a proposed schematic and get as many eyes on it as possible to work out any potential hardware bugs. The questions I still have in my mind are:
- can we really get away with connecting the 5V TTL logic from the 2A03 to the PIC PSP?
- how will the two chips talk through the PSP?
3. Take a close look at the PowerPak and PowerPak Lite to see which pins we can use to route signals to the expansion port that don't conflict with the PowerPaks.
Anyway, stay tuned for more.
The only 2 (un)commonly used expansion pins, I don't know the numbers off-hand but one is to enable/disable mapper access (so CopyNES can write to memory that overlaps mapper regs) and the other of course is for audio-in.
Quote:
Memblers, what PCB CAD tool did you use for the Squeedo? I'm trying to learn PCB CAD tools and manufacturing.
I use Proteus by Labcenter. I've tried Eagle, ExpressPCB (proprietary - don't bother), gEDA, and KiCad. Unfortunately in the Proteus demo version you can't save, but that's what I learned on and found it to be Good. gEDA and KiCad are free, but seemed kind of harder to use (it's been a while so they probably were older versions at the time also).
If you're interested, here's the PIC setup in Squeedo:
http://memblers.com/NES/mapschem.png
Despite what it says on there, I eventually used a PIC18F4525 (same pinout).
Things to notice:
-PPU A12 is connected to a timer input that is able to be pre-scaled by 8. Automatic scanline-counting.
-M2 is also connected to a timer input, for an NES CPU cycle counter.
-74HC377 latches PRG A0-A7 when the NES writes to the PSP. With this, the PIC can distinguish accesses between $5000-$50FF (the PIC's interrupt code uses it for a jump table).
Communicating between the NES data bus and PSP is a little tricky, but I wouldn't say it's hard to do. Sounds like you're on the right track.
I would strongly encourage moving the address decoding to $5000, or anywhere else that doesn't overlap everyone's favorite memory. Squeedo has enables for $5xxx and $6000-$7FFF, that's done with a 74HC139 and one NAND gate. You could do the same by bringing in PRG/CE, or inverting A15. You will need to bring in the M2 (Phi2) signal also, I didn't see that in your schematic. M2 needs to be high when you use the PSP /CE.
Also another suggestion is to hook the PIC up to the controller port pins that are on the exp connector. This could perhaps pave the way for Famicom and NES2 compatibility, serial mode instead of parallel. Also maybe it could make for a hacky way to play-back gameplay recordings or do multiplayer.
Wookie wrote:
1. Talk to the Sullins connector people and get a quote for a custom connector that mates with the expansion port. I'm thinking I'll probably have to scavenge a port from a dead NES and mail it to them.
Would you like one?
I made the mistake of doing a basic sound mod a while back and hot plugging. I think I fried my 2a03.
WHOOPS. The system is as good as dead but I've been holding into it for parts. I'm busy moving during the next couple days, but by this weekend or early next week I'd gladly mail you that part or the entire board. Send me a PM if you're interested!
The possibilities of this project are overwhelming.
Thanks, but I think I have a dead NES around here somewhere. I'll go check and let you know.
Alright, technical detail #1: the parallel slave port (PSP).
I'm trying to figure out two things:
1. Can we interface the 5V 2A03 logic directly to the PIC? The data sheet says yes. The PIC is 6V tolerant on all I/O pins in digital mode, so we should be able to go from 5V to 3.3V. The logic threshold for the 2A03 is less than 3.3V so the PIC should be able to drive the pins the other way too. (from 3.3V to 5V).
2. How do we use the PSP in the PIC firmware? It is a "slave" port meaning that the PIC must respond to the read and writes coming from the 2A03. What happens inside the PIC when the 2A03 executes a read operation? How about a write? I'm reading PIC programming books now to figure it out.
Looking at this book:
http://books.google.com/books?id=CB9GaAU1dwsC&pg=PR23&lpg=PR23&dq=Microchip+PIC+parallel+slave+port+interfacing&source=bl&ots=Hfe6x_ruch&sig=k9OfP1ieu54iPCVqnM28x4TOsBk&hl=en&ei=tF_4SY3mBJTOtAOVj8ThDg&sa=X&oi=book_result&ct=result&resnum=4#PPA328,M2 on page 326-329, it looks like the PIC has a one byte PSP output buffer and a one byte PSP input buffer. The PIC has an internal parallel slave port interrupt bit (PSPIF) which I assume means we can set an interrupt condition on. (UPDATE: yes the PSPIF can trigger a PSP interrupt, which we will do.)
If that is true then we can use an ISR to check the parallel slave port output buffer full (OBF) and input buffer full (IBF) flags to see if the 2A03 did a write to the PIC or a read from the PIC and act accordingly.
If the 2A03 writes to the PIC, the IBF flag will be set. The ISR would then disable the PSP interrupt, read the byte from the input buffer, move it to an internal command buffer, adjust the internal command buffer write pointer for the next write, clear the IBF flag, set an "input" flag to signal the main loop, re-enable the PSP interrupt, and return.
The main loop would check the input flag and see that it is true. It will then scan the bytes it hasn't seen yet, looking for an "end of command" byte or checking to see if the expected number of bytes in the command have been received (see below about the packet protocol). If it sees a complete packet, then it know the 2A03 has written an entire command to the PIC. It then processes the command and writes the response to the output memory area.
Sending data back from the PIC to the 2A03 is similar, just in reverse. When the PIC has something to send back to the 2A03, it will prime the pump by putting the entire response into an output memory area in RAM, write the first byte into the PSP output buffer and then set the I/O line tied to the 2A03's interrupt pin low to let it know there is data ready. (This will have to be a little more complicated than this because there could be other packets still waiting to be read by the 2A03). The 2A03 will execute a read operation which will read the byte from the PSP output buffer. That will trigger an interrupt in the PIC which will disable the PSP interrupt, see that the output buffer flag (OBF) flag is false, copy the next byte from the output buffer memory block to the PSP output buffer, adjust the output buffer memory block read pointer, set the OBF, and re-enable the PSP interrupt. It is then ready for the next read by the 2A03.
We're going to have to check the timing on this to make sure that the PIC is fast enough to do all of that in an ISR before the 2A03 tries to read the next byte. If the PIC isn't fast enough, we'll have to change the protocol so that the 2A03 only reads one byte when its /IRQ line gets yanked on by the PIC. That will slow things down a bit, but I don't think it will matter much.
As for the protocol between the two chips, I was thinking of a "standard" command and response packet protocol. There are two approaches to packets. One approach is to use an "end of packet" byte or byte sequence. The other is to include the packet length in the packet header. Both have their pluses and minuses. The "end of packet" byte or byte sequence means that we have to take precautions to ensure that the "end of packet" value(s) never occur inside of the body of the packet. We'd have to come up with some kind of encoding scheme to get around that. The option of including a length value in the packet header is probably the best option. The length just tells both processors how many bytes to wait for before processing, no encoding of the payload is required.
Anyway, that's about it for the 2A03 <---> PIC interfacing through the PSP.
I just realized that yanking on the 2A03's /IRQ line won't be enough to signal that the PIC has data to read. We'll also have to assert one or more of the controller pins in the expansion bus. If I'm reading the docs right, controller input signals an interrupt in the 2A03 as well. If it does, then the 2A03 can read the controller port during the ISR and check the expansion port bits to figure out if the interrupt was triggered by controller input or by the EtherNES. If it was triggered by controller input, it can then do the little dance necessary to clock in the controller button status. If it was triggered by the EtherNES, it can set a flag that signals the main loop to read in a command response.
Does anybody know for sure if the controller input signals an interrupt? I guess it really doesn't matter. We can still use the scheme while polling the controllers for input.
Here are some extra credit points:
1. Figure out a good source for an 8x8 matrix keyboard.
2. Figure out if it is possible for us to hook up some 8-bit latches to the keyboard and then what it will take to hook it to the second controller port so that when the 2A03 reads the status of the controllers, the first 8-bit latch comes in as the button states for controller 2 and the second 8-bit latch comes in as the button states for controller 4.
I've seen several sources on the web for NES male connectors. Combine the ingredients and we'd have a simple keyboard for the NES that only takes up a single controller port. I'm thinking a keyboard is going to be something we'll want once the EtherNES is working. (IRC anyone?, In-game chat? Smack talking in a game lobby? You get the point.)
But watch out for DPCM double clocks. With a report that long (64 bits), the repeat-and-compare method might not work so well. So the keyboard's circuitry itself would have to smooth out double clocks. I seem to remember MMC3 doing the same thing for PPU A12, which cycles rapidly at the end of each scanline, before it hits the scanline counter.
An authentic controller reading loop, even an unrolled one, won't clock faster than more than once every 11 CPU cycles, or 163 kHz:
Code:
.repeat 8
lda $4017
lsr a
rol 0
.endrepeat
Anything faster than that is probably a double clock.
I know SLIP to work fairly well on Linux but have had no success making it work via Windows XP. Could that be an easier alternative than CAT5?
Regarding the keyboard, I'm thinking it would probably be cheaper and easier just to use a PIC 16F84 to power a PS/2 keyboard dongle. The PIC would interface with the PS/2 keyboard and then send the scan codes when the 2A03 clocks in the button states. Since there are 8 buttons, that would mean that the dongle could support up to 255 scan codes. The PIC wouldn't need to translate the PS/2 protocol at all, it would just read in the scan code from the PS/2 keyboard and pass that along as the button states to the 2A03.
The PIC would be responsible for sending commands to the keyboard to set the indicator lights and stuff so it would have to be smart enough to maintain the keyboard state.
The real trick would be to figure out a way to detect the presence of a the keyboard adapter from the 2A03. Maybe there is something we could do with pins 6 and 7 on the controller port to signal that the device plugged into a given controller port is a PS/2 keyboard adapter. Do any of the other NES peripherals like Rob, power pad, or light gun use those pins?
We'd need to be able to detect the presence of the keyboard adapter so that we can decide whether to use a controller based character entry scheme common to old NES games or to expect the user to type in the text using their keyboard. Or make it a selectable option where if they select the keyboard and we don't detect a keyboard plugged in, we can put up a message that says, "please plug in your keyboard."
Ok, so again, this is possible but the biggest hurdle will be finding the connectors. I've found a source for the male connectors:
http://www.parallax.com/Store/Components/Other/tabid/157/CategoryID/32/List/0/SortField/0/Level/a/ProductID/522/Default.aspx but that is not what we need. We actually need the female connector--the one on the end of the controller cord. I know that there are companies that make them because the same source for the male connectors also sells a retro game pad with the female connector on the end:
http://www.parallax.com/Store/Accessories/Other/tabid/167/CategoryID/32/List/0/SortField/0/Level/a/ProductID/528/Default.aspx They must be getting them from somewhere, the only question is where.
I'm working on the expansion port connector with the Sullins connector people, but I'm now shining the bat light and asking for help on finding a source for the female NES connector.
Whoa, I just realized that there may be an even easier solution for the EtherNES than the PIC. Check this chip out:
http://www.wiznet.co.kr/en/pro02.php?&page=1&num=25
The Wiznet 5100 has it's own internal TCP/IP stack, 16 kb of transmit memory, and integrated ethernet MAC/PHY. The best part is that it is designed to work with old 5V logic as well as 3.3V logic. If we run the Wiznet 5100 in "indirect addressing" mode, then we only need two address lines, /CS, /WR, /RD, /INT, and D0-D7 data lines which is exactly what we have worked out already. That means we'd only need to route one address line and the R/W from the CPU to the expansion port through the cart.
The Wiznet W5100 is a $5 part from here:
http://www.ewiznet.com/goods_detail.php?goodsIdx=104 and the external components are minimal. There just needs to be a 25 MHz crystal and some filtering capacitors and some resistors plus the RJ-45 MagJack, which we were already planning to use.
The biggest benefit of going with the Wiznet part instead of the PIC is that we don't have to write any code other than 2A03 code. With the PIC, we were going to have to write code that interfaced with the 2A03 and the TCP/IP stack implementation from Microchip.
Wookie wrote:
The real trick would be to figure out a way to detect the presence of a the keyboard adapter from the 2A03. Maybe there is something we could do with pins 6 and 7 on the controller port to signal that the device plugged into a given controller port is a PS/2 keyboard adapter. Do any of the other NES peripherals like Rob, power pad, or light gun use those pins?
Seven signals are present on the controller port: 0 V, 5 V, clock, strobe out, data in D0, data in D3, and data in D4. The Zapper uses D3 and D4 for the button state and the photodiode state. The Power Pad uses D3 and D4 much as the standard controller uses D0.
So I guess, the easiest way would be to make D3 or D4 just return a well know bit sequence over and over again. We could hook it up so that subsequent reads to D3 always return 11110000 or something. The code could read from the register a bunch of times and if it gets 11110000 on D3 for each set of 8 reads, then it can safely assume the keyboard adapter is plugged in.
B00daW wrote:
I know SLIP to work fairly well on Linux but have had no success making it work via Windows XP. Could that be an easier alternative than CAT5?
I couldn't get SLIP to work in XP either. I wanted to run
Contiki on Squeedo using SLIP.
If there's a reasonable way to get SLIP working on XP it would be much easier, mostly because the hardware I've had for years would already work.
Contiki works well with CC65 (but the NES libraries are faulty somewhere). This may be worth another look with any working network access.
Wookie wrote:
The Wiznet 5100 has it's own internal TCP/IP stack, 16 kb of transmit memory, and integrated ethernet MAC/PHY.
Nice, I remember looking at that chip before, but it never looked better than now. That's a huge buffer.
Quote:
The biggest benefit of going with the Wiznet part instead of the PIC is that we don't have to write any code other than 2A03 code. With the PIC, we were going to have to write code that interfaced with the 2A03 and the TCP/IP stack implementation from Microchip.
Is there any potential downside to it? It'd be really bad if the NES could somehow get slammed with a bunch of IRQs because of random connection attempts (internet background noise, or whatever it'd be called). I'm mostly a newb at this, so I don't know if that's a problem left up to the chip or the NES to handle (or if it even is a problem).
Memblers wrote:
Is there any potential downside to it? It'd be really bad if the NES could somehow get slammed with a bunch of IRQs because of random connection attempts (internet background noise, or whatever it'd be called). I'm mostly a newb at this, so I don't know if that's a problem left up to the chip or the NES to handle (or if it even is a problem).
Don't forward any ports from your NAT gateway to the NES, and none of the background noise will reach the NES.
The
Microchip ENC28J60 is a SPI-based Ethernet chip (no processor), if you don't mind serial-port like throughput to the NES by bit-banging SPI through an I/O pin then you could do all the TCP/IP stuff in 2A03-land instead of PIC-land. Or a 4-bit counter (reset on 8 to make it a 3-bit counter) could be attached to a clock and serial-parallel shift register to latch onto the SPI data through an I/O port instead. At that point that WIZnes WS5100 or the PIC would be less complicated than doing SPI to parallel conversion in hardware. It would also be pretty straight forward to attach a
CS8900A ethernet chip (Cirrus Crystal LAN) on there, that supports an 8-bit I/O mode and you would just do the TCP/IP in 6502-land (uIP from Contiki works)
But I would almost recommend using the cartridge slot instead of expansion port for all of this. Sure it's a semi-custom mapper, just modify an existing mapper to give you some space for Ethernet I/O. But it's not like the firmware to use the Ethernet isn't going to be custom anyways. Being able to play unmodified Contra/Zelda/etc and use Ethernet is not going to happen if you use the expansion port anyways.
I was reading through the wiznet data sheet and the interrupt thing won't be a problem unless it listening on an open port that is being flooded with connection requests, but that is a problem on regular PC's too.
The wiznet part only yanks on the interrupt pin when a packet is received on an already established and connected socket, so no worries. The 2A03 will only be interrupted when we want it to be interrupted.
I have a plane trip tomorrow and then again on Friday. I'll take along data sheet print outs and see if I can bang out an initial schematic for the EtherNES. Even if the connector takes more time and effort, I'll be able to at least build an initial batch of 4 EtherNES peripherals out of the parts I have. I have a handful of 48 pin female edge connectors that I can cut in two and glue in spacers to give them the correct opening size. I already have one built that correctly mates with the expansion port.
Oddly enough, it is looking like the EtherNES will be pretty "cheap". The wiznet chip is $5. The magjack is $2 and the rest of the components can't be more that $10 total. With $10 for each PCB in small quantities, we're looking at $30 in parts depending on the cost of the connector.
Alright, I just had time to desolder the expansion port connector from my spare NES and I'll be FedEx'ing it to the Sullins' engineering department to get a quote for custom connectors that mate with it. Cross your fingers that the quote will be reasonable.
I just emailed Sullins to get an address to mail the expansion port connector to. I sure hope this works out.
Jon wrote:
But I would almost recommend using the cartridge slot instead of expansion port for all of this. Sure it's a semi-custom mapper, just modify an existing mapper to give you some space for Ethernet I/O. But it's not like the firmware to use the Ethernet isn't going to be custom anyways. Being able to play unmodified Contra/Zelda/etc and use Ethernet is not going to happen if you use the expansion port anyways.
I'm not trying to make old games use ethernet. And using the cart slot is not an option. I want to build a legitimate expansion device for the NES that can be used by multiple games. The Wiznet part is by far the easiest way to go if we can get a part that mates with the expansion port. The Wiznet part has an "indirect addressing" mode that only needs two address lines and eight data lines in addition to the RD, /WR, /INT, power and ground. I've already got a schematic.
The firmware to use a Wiznet based ethernet adapter would be fairly simple and small. It could easily be implemented as a library that game developers could use. Any game that wants to use the ethernet device would have to route a couple address lines to the expansion port pins in the cart slot and that's it. Since the Wiznet handles all of the TCP/IP internally, there's only a bunch of registers the 6502 firmware would have to set up and interact with. The Wiznet chip is also 5V capable even though it is a 3.3V device so there is no 5V->3.3V stuff needed.
I just emailed Sullins about designing an expansion port adapter connector part. They have a few connectors that are extremely close to what is needed. I am ordering the parts needed to put together a prototype using my hacked connector and some proto boards. I just got a new job though so things will likely slow down but I'm going to try hard to keep things rolling.
Oh and the speed of using the Wiznet chip, even in indirect addressing mode would be much faster than the SPI Microchip part. The way the indirect addressing works is that there are four registers at the base of the MM I/O space in the Wiznet chip (thus only needed two address lines from the cart port in addition to A15 on the expansion port). When you want to read/write from/to a memory address in the Wiznet chip's memory space, you write the low byte of the address to the first base register, then you write the high byte of the address to the second base register, and then start reading/writing. If you set the "auto increment" flag in the third base register, the Wiznet chip has an internal address pointer that increments after each read/write.
So if you wanted to read 0x100 bytes from 0x0400 in the Wiznet memory, you set the auto increment flag in the third register and then write 0x00 to the first register, then write 0x04 to the second register, then do 256 reads from the Wiznet chip. The first read will return the byte at 0x0400 and cause the internal address pointer to increment. The second read will return the byte at 0x0401, and so on. Writing is the same way. You set up the address you want to write a block of data to and then you just write the data. I'd be interested to see if it would be possible to use the 2A03's DMA to move packets in and out of the Wiznet chip...that would be really cool.
Anyway, the coding wouldn't be hard at all. The Wiznet chip has tons of internal packet memory so the ISR for handling packet reception can just queue up a packet event in the global event loop and then return. Deferring the packet processing to the main game loop keeps the ISR small and allows for incremental processing to be done while the game keeps going.
Wookie wrote:
When you want to read/write from/to a memory address in the Wiznet chip's memory space, you write the low byte of the address to the first base register, then you write the high byte of the address to the second base register, and then start reading/writing. If you set the "auto increment" flag in the third base register, the Wiznet chip has an internal address pointer that increments after each read/write.
Where have I heard this before?
Wookie wrote:
I'd be interested to see if it would be possible to use the 2A03's DMA to move packets in and out of the Wiznet chip...that would be really cool.
Not possible. The DMA on the NES is for updating the PPU sprite ram quickly during the vblank. It is hard wired to write to $2004. It's not targetable.
Well, I'm getting farther with Sullins. They have an off-the-shelf part that is so close to what we need except that it is too thick to fit into expansion port. The expansion port opening only has room for a 0.375" thick card edge connector and their part is 0.470" thick. I'm working with them to see if they can adapt their existing part to be thinner. I'm also about to mail them an expansion port connector from my spare NES to get a quote from them.
They wanted quantity estimates and I asked them to give me a quote for quantities of 100, 500, and 1000. I have no idea what this will cost, but I won't be surprised if the 100 quantity order will be several thousand dollars or more, making the part a $20+/piece part. If that is the case, my plan is to contact retrousb.com and/or the sparkfun.com guys to see if they would do the initial buy and resell the parts through their site. I don't care how this thing gets made, I just want a legitimate part that I can use in my product.
I'm mailing the expansion port part and my handmade part that mates with it to the Sullins people this week. Their engineering is going take a look at it and see if they can make one.
So I got a quote back from Sullins. They want $5300 as a setup fee and then I assume there is a per-unit charge on top of that.
Unfortunately, I don't have that kind of cash laying around to throw at making a part for a NES expansion board.
If you guys have any ideas on how to pull together the funds, I'm all ears.
If we could put together an order for 1,000 units, then the startup fee is only $5.30 per unit and any per-unit cost on top of that gives us a total cost per unit. I'm guessing that the per-unit cost wouldn't be more than $10/unit with a 1,000 unit order, but still, that makes the total order $15K+. That makes things difficult.
I don't think the entire NESdev community as a whole has $5300, so I'd say go looking for another vendor, or ask Kevtris how he gets his PCBs made.
At this point I would work on getting a working prototype made with a hand made connector before I thought about investing so much in the final product.
an ISA (8 or 16bit) connector + a dremel should do the trick
I'm pretty sure a lot of people here are broke due to current economic conditions. If you can poll a realistic amount of resources from users here, get quotes from other manufacturers, you could probably haggle down the quote a little; but I'm not sure about significantly.
I don't think I can put more than $300 into it, and that barely puts a dent in it. Plus $10 - $15 per connector isn't too thrilling. I've always heard connectors were expensive, I never really looked into it though.
I while back I had an idea for a "backplane cart". Of course that absurd, but with some bus buffers and multiple edge connectors (standard ones), you could have multiple cartridges, software selectable. But anyways that's absurd, and hardware like that already exists (though rare).
daniela wrote:
How can i split one Ethernet cable off a router connected to a modem?
A switch.
Quote:
Can i attach another router to the cable off the previous router?
Yes, but a switch is probably more efficient.
Hello.
What about using
WIZnet W5300)?
Quote:
Supports hardwired TCP/IP protocols : TCP,UDP, ICMP, IPv4, ARP, IGMPv2, PPPoE, Ethernet
- Supports 8 independent SOCKETs simultaneously
- High network performance : Max 80Mbps
- Supports hybrid TCP/IP stack(software and hardware TCP/IP stack)
- IP Fragmentation is not supported
- Internal 128Kbytes memory for data communication(Internal TX/RX memory)
- More flexible allocation internal TX/RX memory according to application throughput
- Supports memory-to-memory DMA (only 16bit Data bus width & slave mode)
- Embedded 10BaseT/100BaseTX Ethernet PHY
- Supports auto negotiation (Full-duplex and half duplex)
- Supports auto MDI/MDIX(Crossover)
- Supports network Indicator LEDs (TX, RX, Full/Half duplex, Collision, Link, Speed)
- Supports a external PHY instead of the internal PHY
- Supports 16/8 bit data bus width
- Supports 2 host interface mode(Direct address mode & Indirect address mode)
- External 25MHz operation frequency (For internal PLL logic, period=40ns)
- Internal 150MHz core operation frequency (PLL_CLK, period=about 6.67ns)
- Network operation frequency (NIC_CLK : 25MHz(100BaseTX) or 2.5MHz(10BaseT))
- 3.3V operation with 5V I/O signal tolerance
- Embedded power regulator for 1.8V core operation
- 0.18 µm CMOS technology
- 100LQFP 14X14 Lead-Free Package
It's the bigger bro of
WIZnet W5100, featuring both 8 and 16bit bus, more speed, better TCP engine.
A project like this could be amazing with an usb interface for HID and mass storage and a flexible ram based cart emulator plus some fpga or tiny ARM for mapper emulation. It could be quite nice for gaming and developmentp
Projects using wiznet chips:
Ethernet cartridge for MSXSpectranet (ethernet for Sinclair ZX Spectrum)Stuff interesting to get from Spectranet, for example.
Quote:
A simple network file system (TNFS, Tiny Network Filesystem) designed for 8 bit systems.
Why not make a common network filesystem for all 8bit systems and some 16bit ones too? It could be amazing!
[/url]
Well the MSX is lucky, because from what I recall it has 2 cartridge ports. Plus that system and the Spectrum being computers, already have other ways to load programs.
I think most of the interest here is about it being a separate expansion, allowing for cheaper cartridges to be made later rather than having an expensive single cartridge to be permanently stuck with.
What is the difference between the free ethernet cable free with the xbox 360 and the wireless network adapter? I am just wondering what is the difference between the Wireless network adapter which is quite expensive and the free ethernet cable that comes free with the xbox 360..They do the same thing right, but why is one so expensive than the other? If I am wrong and they do not do the same thing please tell me!
______________
indian matrimonial
The Wi-Fi adapter is more expensive because it uses Wi-Fi. But it works even if your landlord won't let you pull CAT-5e through your walls.
Hate to reply to an old post, but though I'd share what I came up with tonight. I was able to establish bi-directional communication from a PC serial port to the NES using the second controller port on the NES. No expansion port, no wires hanging out of a cart. This may have been done before, but I haven't found any references to it. I've been reading up on all the ideas regarding embedded ethernet controllers, but I figured I'd start with one block at a time. Here's what I did...
Step 1 was to transmit data to an unmodified NES. Easy enough. I've used an Atmel ATTiny2313 to read data from a NES Advantage before. Instead of providing the clock and latch signals to pick up the data, reverse the process and listen for latch and clock signals. When latch and clock signals are received, shift the data out to the data pin.
Step 2 was to receive data from an unmodified NES without using the expansion port or a hacked cartridge with wires hanging out the front. This was quite a bit trickier. To get controller input, you normally send high/low signals to $4016, then read each bit from $4016. I modified the clouds.asm demo to include three additional high/low cycles to $4016 before fetching the data. In effect, you can use the latch signal as a serial output. While the latch signal gets sent to both controller ports, this did not affect the ability to then read data from controller 1. I hooked an oscilloscope up to the clock and latch lines to verify the multiple latch signals were good.
Step 3 was to interpret and re-transmit the data. The ATTiny2313 is attached to the serial port via a Max232 chip. The clock and latch pins from controller 2 are connected to additional I/O pins on the 2313. Figuring out the timing and order was a real pain. Also, the 2313 had to know whether it was going to send or receive data. Problem is that when the first latch is sent, you still don't know if the 2313 is expected to read or write. If the NES wants a read, you have to have the first data bit ready on the next cycle. If the NES is going to output data, it will sent two latch cycles in a row instead of sending a latch then a clock. If the latter occurs, the 2313 will then use wait cycles for timing to receive data on the latch line. If the NES sends clock signals, the 2313 will output from a buffer to the data pin.
The next step will be to write a simple app on the PC to receive the data over the serial connection and proxy it to a server. A daemon will be running on the server to interpret and reply to the data from the PC, which will then send it back to the NES. You could bypass the PC by using one of the ethernet enabled MCU's mentioned earlier. If you were to get something like this up and running on the PC, then it might be worthwhile to look at building a solution from an MCU.
Someone mentioned a MMORPG using the NES - definitely possible!
chykn wrote:
Someone mentioned a MMORPG using the NES - definitely possible!
Masive multiplayer as in not more than 8 characters at the same time due to sprite limitations?
Don't get me wrong, it would be awesome with some kind of internet multiplayer support and it would be possible too with the right hardware but I wouldn't go as far as saying a MMORPG would be "definitely possible" to create.
That and how would you find enough retro gamers to pay for your cartridge and adapter, let alone for running the server?
It's possible, even feasible, just not likely due to the lack of interest. Pretty much an academic debate anyway, but just for grins, we'll think about it. You'd definitely have to break away from the traditional style of gameplay. Let's say you have a Dragon Warrior style game and there are 100+ people in a town. You're absolutely right - you're limited on the number of concurrent sprites that can be displayed. One workaround would be to limit your view to players you want to see, maybe players that are in your party or guild. Another workaround would be to view only the first 20 or 30 players available in your viewing area. Not as pretty, but doable. Finally, no one says you can't use the background instead of sprites for displaying remote player avatars. I'd avoid this last one, though - wouldn't look very clean.
As long as you can effectively filter the information coming into the NES, it could be done.
tepples wrote:
That and how would you find enough retro gamers to pay for your cartridge and adapter, let alone for running the server?
Good questions...
Hardware Availability - it would be open source schematic and code, so people would have the option of building or buying. It you have an EEPROM programmer, you could mod your own cart then connect a controller cable into an Atmel or PIC MCU. The parts cost so far is less than $15 for the adapter. If you don't have the tools, I'm sure there's someone out there who would be happy to build and distribute the cart and cable for a small profit. You could also use the existing flash carts sold commercially.
Server - hosting is not an issue, but maintenance would be. Updating stories, maps, etc. It would definitely be a community effort.
Generating Interest - you got me there! That's why I'm posting here, maybe get the idea out there to see what folks might be interested in.
chykn wrote:
The parts cost so far is less than $15 for the adapter.
Think you didn't take something into calculations, $15 might be enough for creating a PCB + the cost of a uC and a ethernet socket, but you also need some kind of connector to interface it with the NES (if you don't put everything in the cartridge), casing, ethernet chip etc.(this if you just want to make one unit)
think the best way to do this would be to make a network module that you connect to the EXT-port like the unreleased
Batons TelePlay modem(as mentioned before in this thread). This way it's only one time cost for the player.
To be able to do such unit we would need to establish:
1) a protocol for communicating with EXT-port devices (to identify what kind of device that is plugged in)
2) a pin configuration so no shortage is made if more than one unit is constructed and used with the wrong type of cartridge
3) a way to program an onboard MCU in the device via the from the Game PAK to reduce what the NES has to do in order to communicate
I would guess such a unit would costs at least $70 for the end costumer (if produced in more than 50units), and games that would support it would probably cost 5-15$ more than what they costs today @ retrozone (if bunnyboy wants it in his store)
Remember, this is about establishing communication between the NES software and a game server. First I'd like to prove the concept, then we can go back and start adding more functionality such as updating a flash cart on the fly.
hyarion wrote:
Think you didn't take something into calculations, $15 might be enough...
For a DIY'er building the thing on a breadboard, $15 for the adapter would be about right. Buy the breadboard ($2), ATTiny2313 ($3), Max232 chip ($2), DB9 header ($2), caps ($2) and controller cable ($4). Obviously, this is for early adopters who have at least some experience working with components. Yes, a polished, commercial package would be a bit more.
hyarion wrote:
think the best way to do this would be to make a network module that you connect to the EXT-port...
Technically speaking, I would agree on using the EXT port. Would be much easier, but remember - this solution is geared towards an unmodified NES. Taking a cutter and removing the EXT port cover may be trivial to you or I, but not everyone would feel comfortable with that. Using the second controller port allows you to communicate with the NES without any hacks.
If you overcomplicate the idea, it will be doomed from the beginning. No one will touch a project like this if they have to plunk down $80 for custom hardware. But, if you give the developers and players a less expensive option to accomplish the same goal, you might have a shot at getting it off the ground. This way, the NES would not care whether it was talking to an ATTiny2313 connected to a PC or a MCU with embedded ethernet. It would use the same protocol to talk to both. Open the protocol and let people choose which way they want to go.
hyarion wrote:
1) a protocol for communicating
Yes, you're right about establishing a protocol. Most games cycle the latch bit, input the data for controller 1 then controller 2. For the raw signalling, I'm thinking of something along these lines...
A. Cycle latch (normal)
B. Get Controller A bits 1-8 (normal)
C. Get Controller B bits 1-8 (normal, but shift bits into an "incoming command" byte)
D. Get Controller B bits 9-16 (new, shift bits into an "incoming data" byte)
E. Cycle latch again (new)
F. Output an "outgoing command" byte, shift bits out to the latch (new)
G. Output an "outgoing data" byte, shift bits out to the latch (new)
Each controller read cycle will input 1 byte from controller 1, two bytes from controller two then output two bytes to the latch line. This could be the low level protocol for transmitting and receiving, then each game would then interpret the command/data byte pairs in their own way.
chykn wrote:
If you overcomplicate the idea, it will be doomed from the beginning. No one will touch a project like this if they have to plunk down $80 for custom hardware. But, if you give the developers and players a less expensive option to accomplish the same goal, you might have a shot at getting it off the ground. This way, the NES would not care whether it was talking to an ATTiny2313 connected to a PC or a MCU with embedded ethernet. It would use the same protocol to talk to both. Open the protocol and let people choose which way they want to go.
a power pak costs $135 and people still buys it, even though it's custom hardware
but I agree with you, wouldn't be that many who would buy a device that costs that much if nothing supports it, and it's hard to add support for it if you don't have one to test on. chykn or the egg dilemma so to speak...
chykn wrote:
Yes, you're right about establishing a protocol. Most games cycle the latch bit, input the data for controller 1 then controller 2. For the raw signalling, I'm thinking of something along these lines...
.
.
.
you should be able to use all three data lines which would tripple the data that can be transfered each read cycle AFAIK. But what would it talk to? would each game need it's own custom adapter or what should interpret the byte peers?
hyarion wrote:
But what would it talk to? would each game need it's own custom adapter or what should interpret the byte peers?
No, all games could use a common adapter. As long as the game and the adapter use the same method of transmitting and receiving, you're good. Each game would be free to interpret the command and data bytes as they please, but the data is still exchanged the same way. Right now that would be: Cycle the latch, receive 8-bits on controller 1, receive 16-bits on controller 2 (cmd & data in), cycle the latch then output 16 bits on the latch (cmd & data out). Let me know if you want the ASM I came up with to accomplish this.
When the transceiving method is standardized, I'd be happy to build a few modules and send them out to people who are seriously interested in working on games.
And again, if we use a modular approach like this, the serial->PC adapter could easily be swapped out with an ethernet MCU down the road without modifying the ROM code. I'm almost tempted to hook it up to the second serial port on the WRT54G, but it would be better to spend the time finishing the proxy app in VB and writing a server daemon.
Wow - it just dawned on me, I have an Arduino at home. I hate to jump on that bandwagon (it was a gift), but you could use that as the adapter to connect the NES to the USB port on the PC. The VB proxy app could then communicate with the Arduino's virtual serial port.
This way anyone who is interested could just pick one up online ($30 + shipping) and splice a NES controller cable into it.
http://www.liquidware.com/shop/show/ARD/Arduino+Duemilanove
You could also put an Ethernet shield on it and have it communicate with the server directly, bypassing the PC altogether. I can't vouch for this, though, since I've never used the Ethernet shield.
so if i understand you correctly it would be something like this:
NES <-> adapter <-> something using RS232
or if over internet
NES <-> adapter <-> internets (connected to a server)
so lets say I want to write an email client, then I should
1) somehow setup the adapter to use internet
2) tell it to use tcp
3) tell the adapter to open a connection to a server
4) create packages on the NES
5) send the packages to the adapter so it can redirect it
6) poll the adapter to see if any new packages has arrived
7) interpret the received data
8) pressent it to the user
9) goto 4
this would be pretty much to handel for the NES, and it would be even worse for games and p2p programs. they would have even more to do, synchronizing messages etc.
If most of this communication could be put on another processor on the adapter/device it would free a lot of NES CPU time. However to be able to do this offload one would need to program the adapter-uC so it can convert the data coming from the internet to something easily interpretable for the NES.
In this kind of setup the all the TCP stuff can and should be transparent to the NES. It should be as simple as telnet. The PC or adapter interface would be handling a lot of stuff behind the scenes. I've found a way to do this using a free version of some software, but it's limited to whatever server and port you enter in the interface. It works though. It definitely needs custom software, I've never written any useful PC apps before. The big missing feature is that the NES can't close the connection, open a new one, etc.
I've also done the bare interface of NES controller port > MAX202 > PC before, bad thing there is the NES not knowing when to receive. It works great for XMODEM transfers and user-initiated stuff like that, however. I also hacked an NSF player to stream sound register writes over that connection and that played good. blargg did that too, but did even better and had DPCM samples playing at the same time.
Because of the receiving thing it does need an MCU though, it's part of why I have a PIC on my Squeedo cartridge. It uses the NES's data bus as a parallel port, and also works as a FIFO buffer in the PIC software.
chykn: If there is any interest in Squeedo as a test platform for this, I do have some prototypes that I've been wanting to show around. I already have one tester who is getting one to test some networking experiments with me. So hopefully this could be compatible. But if you'll be making progress on this, you can just have one if you want it.
From here on out, I'll use the term "adapter" to identify the solution which brokers the communication between the NES controller port and the target game server. It could be an MCU->PC->Ethernet solution or a straight MCU->Ethernet solution. If you think another term is more suitable (broker, proxy, magicrainstick), LMK.
Memblers, you're dead on concerning the TCP handling. The only interaction the NES should have in setting up IP communication is possibly telling the adapter what host to connect to. After that, when the NES sends a byte to the adapter, the byte is simply re-transmitted to the game server. Same for the return path. If the TCP session is broken or unresponsive, the adapter will send a status message to the NES and you might see "Server Unresponsive" pop up.
If I'm able to make this work in the next few days and get the client/server functioning properly, I may have to take you up on the Squeedo. Could you send me some info on it? As you can tell from my number of posts, I'm still pretty new at this and am not too familiar with all the tools of the trade.
Tonight I'm going to try and program the Arduino to talk to the NES. I've written a basic server daemon as well as an app for the desktop to retransmit the data from the Arduino (both in Perl). What I'll REALLY need help with is writing a test game. Know of any Pong clones we can get the source to?
chykn wrote:
Know of any Pong clones we can get the source to?
perhaps
"pung - balls of steel", who knows jero32 might want to help out
Haha yeah, jero32 is also the tester I mentioned. So that would be good to use. I've wanted to hack some networking feature into Solar Wars also.
So much for the Arduino idea. Long story short, the compiled language does not execute fast enough. Wish I'd found this before wasting my evening...
http://hackaday.com/2010/01/06/arduino-io-speed-breakdown/
To give you an idea of how slow it runs, I did a simple on/off on a data pin. The high pulse lasted around 4us. The same pulse on the ATTiny2313 in assembly lasted around .25us, about 8 times faster. I didn't really believe it until I watched both inputs together on the oscilloscope.
Back to the drawing board. I'm going to go ahead and use the ATTiny2313 for now. Will post the results when it's done, hopefully tomorrow evening. If we find a suitable replacement later we can go with that.
what happens if you access the port directly?
(example for port b in c for avr)
Code:
DDRB = 0xFF; //set data direction register
unsigned byte out = 0x55; // 0b01010101
for(;;) {
out ~= out; // toggle between 0b01010101 and 0b10101010
PORTB = out; // output out
}
you can also use SPI if you need fast transfer speed on serial data
That's a good point. Can the MCU operate as a 5.0 V SPI slave? If so, you might not need much interfacing logic on the side between the NES and the MCU because the NES's controller protocol is already close enough to
SPI.
tepples wrote:
That's a good point. Can the MCU operate as a 5.0 V SPI slave? If so, you might not need much interfacing logic on the side between the NES and the MCU because the NES's controller protocol is already close enough to
SPI.
both atmega and attiny has 5V SPI and can both operate as both slave and master.
the ATTINY2313 you have should actually be very good for the project (exists both 10 and 20MHz versions), looks like it's the cheapest smallest AVR uC with both SPI and USART. it costs
$2.47 at digikey or $1.556 if you buy 25
hyarion wrote:
both atmega and attiny has 5V SPI and can both operate as both slave and master.
Excellent idea, hyarion. I've been bit-banging the data, but this would be much more efficient and eliminate timing issues. I didn't think about it before, but we can use a "LDA $4017" command to automatically generate the clock cycle necessary for SPI on the second controller port even when outputting data on the latch line.
The current NES ASM code requires bit-banging (and strict timing) on the part of the MCU receive data. The code to output a sprite X location to the MCU looks like this...
Code:
lda spritex
sta txbuffer
rol txbuffer
lda #1
sta $4016 ; //HIGH pulse to Latch
lda #0
sta $4016 ; //LOW pulse to Latch
rol txbuffer
lda txbuffer
and #1
sta $4016 ; Send bit 1
lda #0
sta $4016
(... send bits 2 - 8 )
Using SPI on the MCU, we might do this...
Code:
lda spritex
sta txbuffer
rol txbuffer
lda #1
sta $4016 ; //HIGH pulse to Latch
lda #0
sta $4016 ; //LOW pulse to Latch
rol txbuffer
lda txbuffer
and #1
sta $4016 ; Send bit 1
lda $4017 ; Generate clock cycle
(... send bits 2 - 8 )
Using SPI should also allow us to use the Arduino. I'll give that another shot tonight before going back to the 2313. It would be much easier to tell people "buy an Arduino for $30 and do this to program it" than to say "here's a schematic - good luck!"
Found this code for using SPI on the Arduino...
http://dorkbotpdx.org/blog/feurig/arduino_code_for_thought_spi_slave[/code]
I could use some help if anyone has some spare time today. I need a simple NES program written to talk to the MCU tonight. I can do it, but it would take me a bit longer than someone with more experience. Will need ASM code that I can compile and burn to the PRG that will do the following steps.
1. Start up, display a background that with the text "Waiting for MCU".
2. Send high/low signals to $4016
3. Poll controller 1 (do nothing with the data, just poll)
4. Poll controller 2 (shift the data into the variable rxByte)
Code:
// Do for each of the 8 bits...
asl rxByte
lda $4017
and #1
adc rxByte
sta rxByte
5. If rxByte does not equal 128, loop back to step 2.
6. If rxByte equals 128, update the background to display "MCU Found"
7. End
You should be able to test in an emulator by hitting B or Left on the second virtual controller. Can't remember which is the 7th bit. There are two reasons I'd like this. One, it's a test to make sure the MCU is responding. Two, it's the first step in establishing the protocol that the NES will use to communicate with the MCU to get connection status, etc.
I have two flash carts to work with. The one I've been using is an NROM with 32K EEPROMs in both CHR and PRG sockets. I also have an SNROM cart modified according to this page...
http://www.54.org/sage/condev/ff2cartproject/
I'm sure some wizard out there could make quick work of this. If so, I would greatly appreciate it!
This is polling without rereads for DPCM-induced double clocks, right?
I'd make it, but I have a haircut appointment after work tonight, and someone might beat me to it.
Sorry, you're over my head there. I understand the concept of DPCM, but I don't know it's effect on polling the controller. Are you saying that playing music may interrupt the controller polling process and cause an unexpected clock upon resuming the polling process? We're not playing any music yet, so I just need the code written so that if the software receives value 127 from controller 2, it will proceed to the next step. Although that's definitely something we'd need to keep in mind long term.
I'll be working on this after we get the kids to bed tonight, but that won't be until 9PM Central. Getting 4 girls under 8 years old to bed is like herding cats. Angry, vicious, cranky cats.
chykn wrote:
Sorry, you're over my head there. I understand the concept of DPCM, but I don't know it's effect on polling the controller.
DMA double clock bug: If the CPU is executing a read at the exact same time the sample playback unit wants to fetch one more byte of compressed samples, the same address is read again. There are two notable places in the NES where a read has side effects proportional to the number of reads: PPUDATA ($2007) and the controller ports. On the controller ports, a double clock results in sending two clock pulses instead of one, so the CPU misses a bit.
Thanks for the explanation. You've probably had to go over that a number of times, so I appreciate your patience. I try to RTFM when I can, but on occasion I will need some guidance. Will try to keep that to a minimum.
So there's a good chance that music would mess with the SPI communication. You could probably filter out double clocks if you were bit-banging the data. Say you used a counter in ASM to count the number of wait states expected between clock cycles. If two clock pulses are normally 8us apart but you came across two that were 2us apart, you could restart the timing from the second clock pulse. A pain, but doable with the ATTiny2313.
A typical NES controller read routine will look like this:
Code:
read_player_x:
lda #1
sta tmp0
sta $4016
lda #0
sta $4016
@loop:
lda $4016,x ; 4 c
lsr a ; 2 c
rol tmp0 ; 5 c if in zero page
bcc loop ; 3 c - after 8 left shifts, the 1 will be in carry
lda tmp0
rts
You guessed right that clock cycles will typically be 14 cycles (7.8 µs) apart with this loop.
Actual game controller reading code is slightly more complex because on the Famicom, the hardwired controllers for players 1 and 2 are on bit 0 of $4016/7, and the plug-in controllers for players 3 and 4 are on bit 1. Games are supposed to OR together controllers 1 and 3 and controllers 2 and 4 until a 3- or 4-player game starts, so that the player can use plug-in controllers instead of the hardwired controllers. But games never released in Japan often ignored bit 1.
Music need not interfere with SPI comms if the music just uses the tone generators (pulse 1, pulse 2, triangle, noise). Or perhaps you could run the clock signal through some sort of monostable circuit so that the double-clocks are smeared together.
chykn wrote:
A pain, but doable with the ATTiny2313.
you should be able to read out the time diff if you tie the clock pin on the control port to both the ICP (input capture) and to an interrupt pin (might be able to setup an interrupt on ICP instead so this pin isn't needed) on the attiny and then setup a timer on the avr.
more about timers and counters can be read in:
http://www.atmel.com/dyn/resources/prod ... oc2505.pdf
and:
http://www.atmel.com/dyn/resources/prod ... OC2543.PDF
Feel free to modify my pung source. (Memblers has a copy of it) Which reminds me...gotta get that squeedo deal trough.
Here is a little multi-test program. You have to press A to start the test, but you can add other ones into the test.asm file. An RTS instruction may return to the menu (the MCU test doesn't).
The MCU test changes the palette for every $80 it reads off of $4017. That was just quicker to do than text printing at the moment. BTW, that's the same as pressing the A button on the 2nd controller. Also it doesn't use the exact code you posted.
http://www.parodius.com/~memblers/nes/testmenu.zip
SUCCESS! Memblers, thanks for putting that together so fast. I was finally able to send a signal from HyperTerminal through the ATTiny2313 and have it toggle the menu on your test code. I also modified it to reply to the PC with an ACK code after the first signal was processed. In short, send a single character command to the NES, the NES processes and a response is returned.
I tried for some time to get SPI working on the Arduino. I was able to receive without issue, but the Arduino would not send the SPI data. Probably due to my inexperience with it, but I don't want to spend another day trying to figure it out. Someone else could always take a look, but for now I'm bit-banging on the ATTiny2313.
So, we've verified that we can send signals to the NES and have it respond. In order to make it useful, the transmissions will have to be variable length. If a single-byte data transaction occurs once every 16ms, it's gonna take a while to dynamically load up CHR-RAM.
So it's time to discuss a protocol. We have to hammer this out before proceeding, otherwise we'll be re-writing every piece of code (NES, MCU & server) we write before it's done.
Idea #1
We could set it up so that the first byte of a transmission contains the command signal as well as the number of bytes to follow. This would allow for 15 distinct command codes and 15 bytes to follow. At least three command codes would be reserved for MCU session setup and teardown. MCU available, Connected to Server and Server Disconnect. The remaining 12 could be interpreted by each game independently.
Idea #2
We could set it up so that the first byte is the command byte and the number of bytes to be expected is pre-determined based on command received. Not sure I like this since that may require more logic in the MCU.
Idea #3
A command byte and a data length byte would be mandatory for each transmission. This would allow for about 254 commands with 254 bytes to follow.
If we ever decided that this would be a cross-platform protocol, and it could, I'd probably go with option 3. Doesn't add much more overhead, but it would greatly expand the possibilities. Imagine playing Pong on the NES against someone playing the same re-written on the SNES. Or an RPG. Not saying it would happen anytime soon, just that we don't want to limit the possibilities because of one byte.
Last thing - we need a project page to keep track of things. I can install some wiki software on my web server (
http://www.chykn.com) if we need to and do it that way. Some place where the code and protocol info can be easily found and modified (only by admins at first). If we can do that on parodius.com, awesome. I just prefer the wiki method due to ease of use. Better ideas are more than welcome.
wouldn't it be better with just:
Code:
datastream length (in bytes)
command
optional data
example:
Code:
0000 0001
8bit application specific command
no data
0000 0002
8bit application specific command
8bit application specific data
0000 0003
8bit application specific command
16bit application specific data
but since it's a serial protocol we could change the lengths of each type of "byte"
for instance, if we have length 00000000 as a special case to setup the connection
Code:
0000 0000 length 0 = setup command
0000 0000 command to make the divice identify itself (type of device, revision, etc)
0000 0000 length 0 = internal setup command
0000 0001 command to setup how many bits each "datastream length" should use
aaaa aaaa how many bits to use in command (defaults to 8bits)
0000 0000 length 0 = internal setup command
0000 0002 command to setup how many bits each application specific command will use
aaaa aaaa how many bits to use in command (defaults to 8bits)
0000 0000 length 0 = internal setup command
0000 0003 command to setup how many bits it should be in each application specific
data chunk for a specified command
aaaa aaaa application specific command to setup
bbbb bbbb how many bits to use in data chunk (defaults to 8bits)
0000 0000 length 0 = internal setup command
0000 0004 command to setup number of data lines use for adapter -> NES communication
aa number of datalines (1-3)
.
.
.
then it could look something like this:
Code:
0000 0000
0000 0001
0000 0011 setup length size to 2bits (length between 1-3 chunks)
00
0000 0002
0000 0011 setup command size to 5 bits
00
0000 0003
0000 0001
0000 0101 setup data chunk size for application command 1 to 5 bits
00
0000 0003
0000 0002
0000 0101 setup data chunk size for application command 2 to 5 bits
00
0000 0003
0000 0003
0000 0001 setup data chunk size for application command 3 to 1 bit
00
0000 0003
0000 0004
0000 0001 setup data chunk size for application command 4 to 1 bit
... start program in this case pong (might not be the best application protocol) ...
10 1 command and 1 data chunk
001 command 1, my paddle position
0111 1 set it to somewhere in the middle
10 1 command and 1 data chunk
010 command 2, your paddle position
0111 1 set it to somewhere in the middle
01 1 command no data
100 command 4, syn, should be answered with an acc
... wait for acc...
... play game for a while, then...
10 1 command and 1 data chunk
011 game over
1 player 2 won
01 1 command no data
100 command 4, syn, should be answered with an acc
... wait for acc...
the pros with this type of configurable protocol would be that it creates less overhead for transmitting data that only uses 1 bit since you don't need to transmit in 8bit block. It is also just as easy to interface with (from the nes side) as your 3:rd protocol option, but more configurable for the advanced user.
cons however are that it is harder for beginners to program a compatible adapter and that it might be a bit confusing at first.
I'd go with your first idea. The second it good, but since the data is transmitted from the server in whole bytes, I'd just as soon spend the time it takes to transmit a full byte. Especially if it makes things easier on folks developing software.
What I really like about your first idea is that the length byte could take into account the command byte. That way if there is no command byte, the length would be zero. The NES would then proceed without receiving an unnecessary empty byte. Might also use this to track the last time you received a command to tell if the MCU has become unresponsive.
Code:
datastream length (in bytes)
optional command
optional data
To speed things along, I've created a wiki for this project. It will describe the hardware, software and protocols used. Source code and schematics will be posted where applicable.
http://nesdev.chykn.com
I've posted a VERY rough draft of the protocol, CGP. Click on the CGP link from the main page to get more info.
It may be smart to include CRC checking. There is a great XMODEM routine for 6502 by
Daryl Rictor. I've used with the Squeedo interface and also while bit-banging over the controller port. It was rare, but every now and then I would see a retransmitted block. XMODEM is just 128 bytes of data, with CRC-16.
Good idea, as long as it wouldn't chew up much CPU time. Only one problem...
Memblers wrote:
XMODEM is just 128 bytes of data, with CRC-16
The ATTiny2313 chip only has 128 bytes of SRAM. For now, this will effectively limit transactions to maybe 120 bytes each way. It will slow things down if you're trying to send bulk data (populating CHR-RAM), but other than that it shouldn't be an issue. When we move to a device with embedded ethernet, we'll have plenty of RAM to buffer larger transactions.
Are you thinking about doing the CRC check on the NES itself or on the adapter? I'm leery about putting it on the adapter since you still have one more serial hop until the data gets to the target. Besides, if you do the CRC check on the NES, you can always update the software. Let's implement as little as necessary in the hardware unless it's going to cause a serious performance hit on the NES.
chykn wrote:
To speed things along, I've created a wiki for this project. It will describe the hardware, software and protocols used. Source code and schematics will be posted where applicable.
http://nesdev.chykn.comI've posted a VERY rough draft of the protocol, CGP. Click on the CGP link from the main page to get more info.
Shouldn't you just put it on the nesDev wiki? It would make it easier to find. Totally up to you though.
chykn wrote:
Good idea, as long as it wouldn't chew up much CPU time. Only one problem...
Yeah it is fairly fast. There are a couple 256-byte lookup tables and a little code. The receiving end could ignore it if it wants to, if there's some reason to prefer newer data instead of making a retransmission request.
Quote:
Are you thinking about doing the CRC check on the NES itself or on the adapter?
I mean in the NES, and in the main client/server, since the adapter won't care what the data is. BUT I am kind of concerned about the adapter getting bogus commands, I don't know how likely that is or if it's worth having a checksum, CRC or something for that. I'm kind of curious what the NES or the adapter will be reading if something is being plugged in and swapped around the ports, or NES is being reset or powered on and off, someone plugs it in and tries to save a track in Excitebike and does a command to format their hard drive, heheh..
WhatULive4 wrote:
Shouldn't you just put it on the nesDev wiki? It would make it easier to find. Totally up to you though.
Huh - didn't realize there was one until you mentioned that. Asked yesterday morning and no one mentioned anything about it, so I went ahead and built the wiki on my site today.
I added the "NES Online" project to the Nesdev wiki under "NES Hardware Projects". If you search the wiki for "online" or "ethernet" it will show up and display the link to the project page on my site.
Memblers wrote:
I mean in the NES, and in the main client/server, since the adapter won't care what the data is.
Sounds wonderful. The less we put on the adapter, the sooner we can finalize the protocol and I can start sending out a few hardware samples.
Memblers wrote:
BUT I am kind of concerned about the adapter getting bogus commands
Wouldn't that be funny. Right after we get this thing online someone will come up with come up with the first NES virus to wipe out the saved games on your battery backed SRAM.
Good point. I can definitely see where there would be concern if the PC is being used to proxy the data. Before I finish the proxy app, I'll be sure to add a strict data validation function based on the command received. If the adapter were to get bogus commands, it would in turn re-transmit them to the NES. The majority of the signals will be status updates and what not, so the effects of a single bogus command would be temporary. Worst case, it locks up the NES and the player has to reset.
For the amount of work we'd put in trying to figure out all the possible attack vectors and the code we'd write to compensate, I'd just as soon take the chance and spend the time working on other things. Spend a month figuring out some sort of signature or encryption scheme and someone will break it in two. If the server and client do any type of validations, I'd leave it at doing the CRC.
I hope something comes out of this. Standardized way of NES<->PC communication would be very useful. Especially when coupled with PowerPak
thefox wrote:
I hope something comes out of this. Standardized way of NES<->PC communication would be very useful.
Yeah, hopefully what we're doing will extend beyond games communicating with the server. Downloading new games to a flash cart on the fly then playing then would be pretty sweet.
Buffering the data is an interesting problem. Because the MCU is a slave device to the NES, it requires very strict control in terms of clock cycle usage. Because timing is so critical, it just about forces you to use a discrete device as a buffer and separate it from the IP device. Otherwise an influx in IP traffic would spike the CPU and cause a temporary loss. I found that out trying to use GPIO pins on a WRT54G. Using a buffer device (in this case, the ATTiny2313) and the serial interface allows full commands to be sent or received with perfect timing even if the IP device is experiencing heavy load. The upside/downside depending on how you look at it is that a command string can only be sent to the NES if it has been loaded in the buffer in it's entirety. Will be working on the buffering mechanism tonight.
I'm thinking about limiting individual command strings to 34 bytes each. That's 1 LEN + 1 CMD + 32 DATA bytes. Since the NES normally polls the controller ports every 14ms, we could safely assume that at least one command string could be transmitted in this timeframe.
Also, the data receiving function needs to be reworked to receive multiple commands to expedite the loading of bulk data (CHR-RAM). Make it so that the NES continues to poll for new commands until it receives a 0x00 signal. Say the NES sends a signal to the game server for an 8KB chunk. The IP proxy receives the data and holds it in memory. The data is then transmitted to the NES in 32(+2) byte chunks. The buffer device can continue to receive data from the IP proxy even while transmitting to the NES. Unless the IP proxy becomes busy, this should let us avoid buffer starvation and get a nice continuous stream of data to the NES. I know 34 bytes doesn't sound like much, but the ATTiny2313 only has 128 bytes RAM. This would allow for 3 full command strings, hopefully enough buffer space to keep things going smoothly.
Will the ATTiny always have to bit-bang the NES port to use it? I'm wondering if this is full-duplex or not. If SPI or something could work in hardware, I would think the adapter could safely do nothing but pass-through data, and let the host software deal with the commands and interpreting string/block sizes.
At the other end of the cable for what I'd like to build, it would be a USB interface with a generic virtual COM port driver for the remote system. So by that point I figure it's probably cheap and easy to use a USB PIC, that's what I'll be looking into using in a Squeedo revision. Heheh if it was code-compatible you could theoretically have something like Squeedo's sound synth, controlled and played through the controller port.
Most of that is assuming there's not lots of bit-banging needed by the MCU, I don't know for sure but I wouldn't be surprised if there is.
I'm pretty sure SPI would work on the ATtiny's side of the NES controller cable; it's just clocked serial like in the Game Boy. The NES side of this cable would of course have to bit-bang MOSI to $4016.D0 and MISO from $4017.D0 as it does with controllers. There are three wrinkles:
- DPCM double clocking, as mentioned before.
- You might have to play with the CPOL and CPHA settings so that the lines are sampled on the correct side of the clock signal.
- A transmission starts after a falling edge of /SS, but the NES has one output for MOSI and /SS. Controllers use $4016.D0 solely as /SS, but if $4016 is also used for MOSI, something will have to recover a /SS signal: perhaps no clocks for a while might reset it.
tepples wrote:
I'm pretty sure SPI would work on the ATtiny's side of the NES controller cable
If you can get SPI to work, that would be awesome. After trying it with the Arduino as well as the ATTiny2313, I gave up on it. Couldn't get transmits to work on either one. Receives worked like a charm, though. Oh well.
I finally managed to do a buffered receive from the PC to the NES. The adapter queued up 8 bytes @ 57600 then passed them to the NES as soon as the command was complete. Now to implement an outgoing buffer to handle responses. Speaking of the adapter, how's this for a name; the "NES232". Simple and descriptive. Adapts the control ports signals and provides buffering for RS232 communications.
memblers wrote:
If SPI or something could work in hardware, I would think the adapter could safely do nothing but pass-through data, and let the host software deal with the commands and interpreting string/block sizes.
The problem here is speed mismatch and possible congestion on the host. The NES->RS232 speed mismatch alone would warrant a buffer since you'd run the risk of processing incomplete commands without one. If you connect the NES directly to GPIO pins on a host and the host is unable to respond, you have to have a way to either queue the transactions and/or provide notification to the NES that data cannot be transmitted at this time. Similar to congestion notication signalling in the routing world. That way the NES doesn't send data that ends up in the bit bucket.
Or look up "flow control": DSR/DTR, XON/XOFF, etc.
tepples wrote:
Or look up "flow control": DSR/DTR, XON/XOFF, etc.
Flow control alone still wouldn't give us the ability to queue up transactions for delivery while the NES is between the 14ms polling periods. As a consequence, it wouldn't guarantee a consistent stream of data. It would stutter and you'd use a good chunk of NES CPU time either waiting for delivery or holding off until the next polling period. Either way, you're wasting valuable time. A rough analogy would be using LLQ in the Cisco world to support VoIP. You COULD get by without it, but then your voice quality would suffer. Here's we're not only trying to get the data to the NES as fast as possible, but with the lowest latency we can get.
And before anyone starts in on the analogy, yes, I know LLQ prioritizes certain packets before other types of packets. But the goal is the same. Didn't say it was a perfect analogy.
While writing this, I just realized that you may have been referring to the congestion notifications. If that's the case, my bad - you're absolutely right. The only reason I'd avoid standard XON/XOFF signals is that they do not give enough info. Depending on the size of the next incoming command, the NES232 may or may not have enough buffer space. Instead of XON/XOFF, send status signals to the host with the amount of free buffer space. If the space available is not large enough, it will not transmit and will wait until more buffer space is available. But yes, in theory, I do agree with you. This does require flow control.
chykn wrote:
Similar to congestion notication signalling in the routing world. That way the NES doesn't send data that ends up in the bit bucket.
Oh yeah that makes sense, especially considering the host system would be running an operating system of some sort, it's sure to have a lot of other stuff going on.
If it's not a big hassle, it would be cool if it could support an NES bit-banged async mode. I'd be willing to try my hand at coding it in whatever memory might be left over in the MCU (heh). It'd be for back-compatibility with stuff I wrote before, and probably a couple other people who have bit-banged stuff over RS232. The only released thing that comes to mind is the Pitfall! port by never-obsolete:
http://nesdev.com/bbs/viewtopic.php?t=3744&highlight=pitfall. I sent him the code for bit-banged XMODEM that the level editor can use, but it hasn't been tested in-game AFAIK. It's just as well to leave async mode in the dust though, I don't think anyone would be mourning the loss.
Even the async NES-RS232 adapters I built (like 6 of them years ago), I later repurposed to use for Squeedo, with a real UART.
Memblers wrote:
The only released thing that comes to mind is the Pitfall! port by never-obsolete:
http://nesdev.com/bbs/viewtopic.php?t=3744&highlight=pitfall.
Off-topic: Yet another broken link, I wish we had a central place where we could collect and showcase stuff like this so it wouldn't be buried in the depths of the forum so quickly. The main page kinda serves the purpose but not at this rate of updates.
Wow - whoever mentioned standardizing serial communication was really on to something. I was looking at emulator support a few minutes ago and found something very interesting. The FCEUX guys replied back and said an existing controller module could be modified to emulate the function of the NES232. I looked over the source and it looks like it's doable. One caveat, you'd have to also install another package to support the necessary virtual serial ports if you're using a pure software solution. But here's how it would work...
Hardware: NES -> NES232(COM1) -> IP Proxy App(COM1)
Emulator: FCEUX -> VirtualNES232(VirtCOM3) -> IP Proxy App (VirtCOM4)
OR
Hardware: NES -> NES232(COM1) -> TestApp(COM1)
Emulator: FCEUX -> VirtualNES232(VirtCOM3) -> TestApp(VirtCOM4)
Using serial communications in both situations would allow us to make it more modular. Say you wrote a test app that would talk directly to the NES using CGP (Classic Gaming Protocol, made that up). You could have the physical NES connect to the test app or fire up the ROM in FCEUX and have it talk to the same app. Better yet, say you wanted to reprogram a WRT54G to proxy the IP traffic. You could test it with the emulator like this...
Emulator: FCEUX -> VirtualNES232(COM1) -> WRT54G(COM2)
As long as everything is using the same protocol, a setup like this would not be too hard to do. If anyone has a good amount of experience in C++, please let me know. We could have the hardware and the emulator support ready in the very near future if someone can give me a hand with the emulator portion.
For those who need the link, I'm posting all the project info here...
http://nesdev.chykn.com
I'm going to try and finish the outgoing buffer code on the MCU this evening. If we can agree on the functional responsibilities of the NES232, I might be able to send a few samples out to those who are interested in the next few days. To make it as flexible as possible, it should only serve three functions...
1. Serve as a NES->RS232 signal translator
2. Provide buffer space so full commands (up to 34 bytes each) can be delivered and accomodate for speed mismatch
3. Notify the NES and RS232 host of available buffer space prior to receiving transmissions
Item 3 is what Tepples was referring to, I believe. What if we did something like this...
1. NES starts by sending code 0x09 (or whatever) to request the available outgoing buffer space
2. The NES232 replies with code 0x0A followed by the total buffer space
3. The NES sends full commands up to the total buffer length
4. After the NES232 successfully sends out data upstream, it tells the NES the new amount of free buffer space
(Repeat steps 3 and 4 for all further transmissions)
The same process applies to the RS232 host. This way, the NES232 can be upgraded to a device with a larger buffer, up to 255 chars in each direction. That would allow for longer commands and faster loading of bulk data.
I reworked the transceiving method. It's now full duplex and executes in roughly half the time on the NES. I've update the wiki and posted all the details. Click on the "NES232 Adapter" link on the main page and scroll down. You'll see the functional description for the device as well as the ASM code for the NES side. Let me know what you think.
That's really cool and compact. It's funny how bufferbyte can contain the sent and received byte. Also, maybe that CLC could be optimized out by changing 'ADC bufferbyte' to 'ORA bufferbyte'.
Also there was the idea of mounting one of these inside an NES. The more I thought about it though, I realized it would prevent a toploader (and don't forget the SNES, with it's 100% compatible ports, even the SNES regs are at $004016/$004017). Having it inside would allow the extra data lines to be used though, if there was any point.
It might be useful to pass through a controller signal if it was external, you could put one of these on there maybe:
http://www.parallax.com/Store/Components/Other/tabid/157/CategoryID/32/List/0/SortField/0/Level/a/ProductID/522/Default.aspx
memblers wrote:
Also, maybe that CLC could be optimized out by changing 'ADC bufferbyte' to 'ORA bufferbyte'.
I'm all for cutting out any unnecessary steps. The initial ROL sets C which is added by ADC #0 and outputted to STA $4016. If C is high, it will affect the ADC bufferbyte in step 7, thus the CLC. If there's a better way to clear it, LMK and I'll update it.
memblers wrote:
and don't forget the SNES, with it's 100% compatible ports
Very true - this is one of the reasons I'm taking a modular approach with this whole thing. If you wired the NES232 up to the SNES port, you could poll it the exact same way. A custom SNES game using CPG could talk to the same Proxy App and game server as a NES game.
memblers wrote:
It might be useful to pass through a controller signal if it was external,
The NES232 would have to poll it then pass the data to the NES via the buffer. But yeah, definitely possible. Good idea.
chykn wrote:
memblers wrote:
Also, maybe that CLC could be optimized out by changing 'ADC bufferbyte' to 'ORA bufferbyte'.
I'm all for cutting out any unnecessary steps. The initial ROL sets C which is added by ADC #0 and outputted to STA $4016. If C is high, it will affect the ADC bufferbyte in step 7, thus the CLC. If there's a better way to clear it, LMK and I'll update it.
He told you the better way.
Take out step 4 (CLC) and change step 7 "ADC bufferbyte" to "ORA bufferbyte".
thefox wrote:
He told you the better way.
My bad - you're absolutely right. Thanks for the correction guys. I've updated the wiki. Down to 7 instructions from 8.
Just about wrapped up the initial hardware design tonight...
- Finally got the NES232 talking to the NES using the full duplex method.
- The incoming buffer is working, up to 112 bytes can be queued.
- The full duplex method added enough cycles that the NES transmits and receives a bit slower than the 115,200 bps serial link. This means we do not need an outgoing buffer. Each bit takes ~16us to transmit. If my math is correct, that's around 62,500 bps. If you're doing bulk reads, this CAN be increased to over 100,000 bps by eliminating the instructions necessary for transmitting.
- NULL bytes from NES - the MCU was receiving 0x00 bytes and transmitting them even if the NES had no outgoing data. Applied the same rules as the inbound, first byte must be the length descriptor. Done.
- Had to modify the method - replaced ROL with ASL due to unwanted bits coming back on the right and screwing up the following ORA statement. Also had to add another step to pull the outgoing bit from Carry instead of the LSB. Don't ask why I did that to begin with - seemed like a good idea at the time.
I got to thinking about the congestion management. Since the NES should be sending ackowledgements anyway, it can send "Received X bytes" upstream after it gets done receiving the commands for that data exchange session. Then the host will know the space is free and proceed to send.
So, I'm done with it for now. Here's a recap of where we are....
- NES232, based on an Atmel ATTiny2313 @ 11MHz
- Talks to the PC via RS232 @ 115,200 bps
- Talks to the NES via 2nd controller port @ ~62,500 bps
- Uses a buffer for incoming commands
- Sends outgoing data on the fly
- Congestion management will be handled via NES ACK to the upstream host.
Feedback would be greatly appreciated. Thanks!
how are you connecting it to your computer? IIRC a max232 is needed to put between the attiny and the serial port due to voltage diffs (or fl232rl for usb support)
Quote:
how are you connecting it to your computer?
The cans and a string didn't work - had high hopes for that, too. I play around with WRT54G's & OpenWRT, so I keep a MAX232 chip, DB9 connector and .1uf caps on my breadboard. Jumpered that to the ATTiny2313 and hooked it up to COM1 on the laptop. Good to go.
It will actually easier to get it up and running on the WRT54G because you won't have to use the MAX232 chip. You could go straight TTL from the ATTiny2313 to the second UART port on the WRT54G. Or Buffalo, whatever your preference. Then the WRT54G would be the IP proxy. That would be pretty sweet since it wouldn't require a PC for operation and you could use it as a wireless client. Cheaper than developing an embedded solution and much more readily available.
You're right about the USB support. That's the way most folks would want to go if they wanted to hook it to the PC. I've never played with the FL232RL chips; will have to try that out sometime.
ooops, i meant ft, not fl sorry for that :S
Okay, here's the schematic. The serial RX/TX lines would need to go to a TTL to RS232 converter or similar device unless you're hooking it up to another TTL device. Just search "TTL RS232" on Ebay. There are also TTL to USB devices available, but I haven't tested any out myself. I imagine they'd work just fine. For now, please contact me for the firmware. Not quite ready to post publicly. I want to make sure this behaves as expected before letting untested firmware go in the wild.
Code:
NES232 ASCII Schematic
Pete Brown, 3/6/2010
ATTINY2313
___________
| 1 20 |--- Vcc +5v
Serial RX-------->--| 2 19 |
Serial TX--------<--| 3 18 |
XTAL--+-------------| 4 17 |
XTAL--|-+-----------| 5 16 |
| | CLOCK-->--| 6 15 |
| | LATCH-->--| 7 14 |
| | DATA--<--| 8 13 |
| | | 9 12 |
| | GND--+---| 10 11 |
| | | -----------
| +---)|--+
+-----)|--+
* The two caps tying XTAL to GND are 22pf ceramic
* XTAL is 11MHz (11.0592 is perfect, but 11 will be fine)
If you want to start developing with one of these and you don't have the facilities to build your own, let me know. If there's enough interest I'll get enough to do 10 boards or so from DigiKey. Will probably cost around $20 to build and ship.
The MCU is $1 less at
Arrow, for a smaller quantity anyways. They don't stock a usable crystal though.
Looking at Digikey, the 11.0592 is a lot more common than 11mhz, might as well spec it.
I want to build a few, but don't have a programmer that will do this chip. Which brings up another question, is it possible and worthwhile to fit a bootloader into it?
Memblers wrote:
Looking at Digikey, the 11.0592 is a lot more common than 11mhz, might as well spec it.
Now that you mention it, I've been running at 11MHz because I'm using an ATTiny2313-10 instead of the -20 version. They only carry stock of the -20 surface mount version, but it costs the same. We could go up to 18.432MHz for the same price. I'm set up for surface mount rework, so it wouldn't be a problem.
Memblers wrote:
I want to build a few, but don't have a programmer that will do this chip. Which brings up another question, is it possible and worthwhile to fit a bootloader into it?
Good one. Yes, there are at least two boot loaders for the ATTiny2313. The NES232 firmware is only 693 bytes, so that leaves plenty of space for a bootloader. Looks like we can also bump the RS232 serial rate to 230,400. Both the 11.0592 and 18.432 crystals would support this. So, tonight I'll play around with upping the speed to 230,400 and using a bootloader.
Two more things we need to make a decision on. I'm going to come up with a PCB layout for an SMD version. It will include the ATTiny2313, crystal, (2) 22pf caps and connection points for the NES controller cable.
- Do we want to have a three post header for the RX/TX/GND and leave the TTL-RS232 conversion to the user or go ahead and include a MAX232 & caps in the circuit? I ask because of the earlier discussion about using an FT232 USB converter. Some like me won't even use a converter, some will need USB and some will want the good old RS232.
- What kind of header do we want to connect the controller cable? We could either have 5 empty pads for the user to solder the cable to or put a standard 10-pin header on it.
Of course, we could give the board one 10-pin header for all connections. Then people could just plug a standard 10-pin header cable to it and use any of the three options (TTL, USB, RS232) without modding the board. Just wire the header cable to whatever.
Code:
+5v CLK LAT DATA GND
+-------------------+
NES | 0 0 0 0 0 |
| |
Serial | 0 0 0 0 0 |
(TTL) +-------------------+
TX RX GND
I think it would be good to put a max202 clone on the board, and assume most of the interested users won't want to solder anything to it. You could drill some big holes for cable tiles to fit through, for strain-relief on both sides of the cables. max202 by itself doesn't cost much, and I guess one could use a seperate RS232-to-USB adapter if they really had to.
I actually have a box of new RS232 cables I never used (since I wanted to go to USB). It would be cool to have a use for them now maybe.
My Squeedo cart uses a right-angle polarized .1" header, it was 6 pins but I'll cut it down to 4 on the later revision (VCC,TX,RX,GND). It's just TTL-level at that point. The idea is that one could theoretically use it to control another serial device. I don't know if anything would be made for it, but if the adapter included that connector, it could make the controller port compatible with the same type of stuff.
Memblers wrote:
I think it would be good to put a max202 clone on the board
Yeah, you're right. Most folks will need to have a turnkey solution. I went ahead and ordered enough parts to do 5 SMD boards with TTL-RS232 converters and DB9 headers. The only thing the user will need to do is supply a controller cable and splice it in. Digikey didn't have those and I'm not giving up my Arkanoid controller.
I'll also have enough parts to do 2 or 3 thru-hole boards with no TTL-RS232 converter. Someone could use one of those if they wanted to do the USB thing.
Will work on the PCB layout over the next few days, hopefully be done by the time the components get here. Should be able to ship the first board to you Monday. Might be possibly to interface the Squeedo's UART directly with the NES232. That way the Squeedo would be able to load game code or whatever without having to go through the second controller port. Man, that would be cool. First NES cart to connect to an IP host and load a game on the fly.
I put a few of these 8-position terminals on the order...
http://search.digikey.com/scripts/DkSearch/dksus.dll?vendor=0&keywords=ED2606-ND
This way someone can just strip the controller wires and tighten the screws down. Like a car speaker amp. No taping or soldering; very clean and modular. This will also let us put the MAX232 and NES232 on the same board but still be separate. You'll be able to change from MAX232 to TTL by simply unscrewing the RX/TX leads and connecting another set of wires to the terminal.
I think there is a much faster way to load data if you're using an SNROM cart, maybe other MMC1 boards. Since the NES232 has 10 unused data pins, you could hook the 8 PortB pins to the PRG data bus and take the place of the WRAM chip. Remove/disable the WRAM chip and tie the CE & WE lines to the NES232. The beauty of this is that it could use the exact same hardware and the NES232 could use either method to communicate. Load bit-by-bit through the controller port or load a byte at a time on the PRG data bus. The cart would dictate which method to use. But instead of using 70 instructions to load a byte, you might cut it down to 1 or 2. The NES232 would detect the CE/WE signals and switch the direction of PortB based on that.
The only problem here is that I've never played around with WRAM before. Am I correct in assuming that you can read byte by using "LDA $6000" and write by using "STA $6000"? Or is there some other setup you have to do first? If it's a single statement each, then the NES would have to automatically toggle the WRAM CE in the background. The toggle would serve two purposes - tell the NES232 to activate as well as increment the buffer pointer if data is ready to be sent.
You would have to make two changes to the NES232. One, add a 12-pin header to the PCB design (8 data, 1 WE, 1CE, VCC & GND). No big deal, can by done in an hour. Two, update the firmware to accomodate communicating through PortB. Probably take an evening or so. In the end, you could either use controller port B or a jumper cable to the cart itself.
The parts came in Saturday, started building today. I've never actually designed a surface mount board before, so I got a bit of a crash course. The etching took a few tries, but in the end it worked. Made the mistake of not using the bottom copper, so the solder joints on this one are on top. Like I said, this is my first surface mount board.
I'm going to get this one up and running then rework the PCB on the next board. Move the DB9 connector so it's flush with the edge and use the bottom copper for the thru-hole solder joints.
I've mounted the ATTiny2313 as well as the MAX202 and its caps. The MAX202 circuit works perfectly; tested with a WRT54G. Still need to mount the headers, flash the ATTiny2313 then mount the crystal and 22pf caps. Here is the board as it is now...
it's alot easier to each a PCB if you use copper-fill/pour on the board, that way you don't need to etch away all copper between the tracks. And it's easier to solder the parts if you put the throuhole components on the other side of the PCB
do you have the schematics/pcb files available somewhere?
btw, good work
hyarion wrote:
it's alot easier to each a PCB if you use copper-fill/pour on the board, that way you don't need to etch away all copper between the tracks. And it's easier to solder the parts if you put the throuhole components on the other side of the PCB
Good idea. I went ahead and flipped the DB9 header so it can be mounted from the other side. All other headers and pins can be mounted from the other side without further modification. Also moved the DB9 connector out so that it is flush with the board.
hyarion wrote:
do you have the schematics/pcb files available somewhere?
Sure. If you'd like to add the copper-fill, that would be great. Here are the DSN and FPC versions of the layout. Currently unrouted since I just made the change to the DB9 header. Don't have a schematic made up of the MAX202 portion, but the schematic for the ATTiny2313 portion is on the project page. And earlier in this thread. There are a pair of 2-pin headers on the MAX202 portion. One is to jumper the MAX202 VCC pin to VCC and the other (on the right) goes to the TTL in/out pins. A header cable will attach these pins to the RX/TX holes on the 8-pin terminal. This was done so you can either disable the MAX202 or use the MAX202 for another TTL/RS232 circuit. Could have just traced them straight to the UC, but I prefer the flexibility.
http://www.chykn.com/NES232.dsn
http://www.chykn.com/NES232.fpc
The first board is complete and has been tested with the NES. Here are a few pics. Low res, had to use the Blackberry. Kids took my camera batteries for their Leapsters.
Top of the PCB
Bottom of the PCB
You'll notice a few traces on the PCB that had to be jumpered due to moving the thru-hole components to the other side. And the recessed DB-9 connector. These are corrected on the Rev 1.1 PCB. The 12-pin header can be used to reprogram the Attiny2313 via ISP. I was able to get the bootloader to talk to the PC, but haven't been able to load any code yet. So for now you can only update the firmware by using an ISP programmer. They are actually VERY easy to build. I used this one when I was starting off. It consists of (3) 220 ohm resistors, a 25-pin male connector and some wiring. Connects to an LPT port on the PC.
http://www.qsl.net/ba1fb/fbprg.gif
So, if you want one (NES232), let me know. I'll go ahead and start building a couple boards if there is some interest.
Wookie wrote:
I think you guys are missing a much easier solution to the EtherNES idea. Instead of trying to use one of the ethernet chips with address and data lines, why not use the Microchip ENC28J60. It is a 10baseT chip with an SPI interface.
I read this again and realized this could easily interface with the NES232. The SPI pins come out on the 12-pin header, so the NES232 could be reprogrammed and jumpered to the ENC28J60. This would provide the ethernet connectivity and allow the NES232 to communicate by either RS232 or SPI. The beauty of this is that this change would be transparent to the NES as well as the server. You wouldn't have to update the game or server code. If anyone has worked with this chip, please let me know. Could use some help integrating it into the design. Maybe swap an ENC28J60 based board for a NES232 if someone has a spare.
The first two Rev2 boards have been built and shipped. Here is a pic of the Rev1 board next to the two Rev2 boards in their housing. I separated the NES232 and MAX202 into two individual modules so they could be placed into the slots of a small Radio Shack project box. This also allows you to quickly swap the TTL-RS232 converter board for a TTL-USB serial cable. Having a sturdy container for shipping doesn't hurt, either.
If anyone else wants one, LMK. Will build and ship one in the project box for $25; need to raise a few shekels to build more. Can include an AVR910 serial programmer for $5 if you do not have an AVR ISP programmer. A jumper cable from the MAX202 allows you to switch the serial port to either the NES232 or AVR910. The first Rev2 board above has an external programmer. The second Rev2 board has the same programmer on an internal module. If we are able to get a bootloader working, we will not need the programmer.