Simple/cheap EEPROM-style NES cartridge interface.

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Simple/cheap EEPROM-style NES cartridge interface.
by on (#79929)
I have been thinking about getting a NES ROM dumper, but I just find the public alternatives like CopyNES way overpriced.

I know that most solutions use huge arrays of I/O ports or a bunch of buffers and latches in combination with some micocontroller, but I don't have a microcontroller, and I don't want to learn another programming language just for this project. Because of this I set out to design my own interface, with the idea that it could easily be directly connected to a standard computer bus interface (like the old-fashioned ISA-bus).

I came up with a design using two Nand gates, one Or gate and a 74LS145 bus-transceiver. It still needs an address decoder to be put on an ISA card, but it should at this point be possible to plug it into any EEPROM-interface with support for 64K*8 chips.

The design should only theoretically work, unless the mapper chips are extremely timing-sensitive. However, it's not tested practically. It works like this: A read from the lower 32KB will read whatever the cartridge curently maps as CHR. A read from the upper 32KB will read whatever the cartrige curently maps as PRG. A write to the upper 32KB will result in a write to the mapper (just like on the actual NES), while a write to the lower 32KB will indicate a write to the cartridge, but no chip will be enabled to receive it.

At this point I have most of the parts, except for the 72-pin edge connector and a 64K*8 ROM interface. It's darn simple to make such an interface, so that's no problem.

Here is the schematics:
http://oldibmpc.sitesled.com/misc/NESadapter.GIF

If the ISA-card solution is chosen, then the ISA ALE signal can replace the Nand-gate generating the Ø2 signal. However, then the /CE line must be masked by the ISA AEN line (requiering an OR-gate). Still, the part-count doesn't really change at all.

Any thoughts or comments on this?

by on (#79953)
I won't judge you're DIY attitude. I am currently soldering together an EEPROM burner with an Arduino :D

Also, Arduino is a great choice for a general-purpose microcontroller platform. It's written in C, has great library support and is dead-simple to use. Home Page, Buy at SparkFun ($29.95 USD).

Back to your ISA bus project. I thought I had a hard enough time finding a computer with an LPT port on it. I haven't seen an ISA card since 98 :P

The upper / lower 32K stuff you are doing is going to be problematic. Many mappers (like MMC5) have mapper registers in the $5000 - $7FFF address range. Furthermore many carts also have save RAM at $6000 - $7FFF. It might be useful to be able to read and write to this as well.

Other than that it all sounds pretty straight-forward. Can I ask what you use for your prototypes? I am doing my first project on protoboard and I am hating it. Air wires are getting on my nerves :D

by on (#79964)
Have you seen this page :

IO-56 Reader/Writer for NES

by on (#79973)
Why do you need the LS245 transceiver?

I'm not familiar with ISA, but the cart certainly shouldn't require it, if you don't enable the chip the data line will be high-Z. And if you are writing the roms will accept whatever you put on the bus.

So from the cart's standpoint I don't see why controlling data flow direction will do anything for you. Unless you're just using it for a common output enable for some reason.

by on (#79976)
qbradq wrote:
Also, Arduino is a great choice for a general-purpose microcontroller platform. It's written in C, has great library support and is dead-simple to use. Home Page, Buy at SparkFun ($29.95 USD).

Yes, but that's one of the problems I have with microcontrollers. I don't know enough C to be familiar with it. I do know a lot of assembler languages, though, especially for the Intel-based chips.

qbradq wrote:
Back to your ISA bus project. I thought I had a hard enough time finding a computer with an LPT port on it. I haven't seen an ISA card since 98 :P

The system is not a problem. I'm a "vintage computer" enthusiast so I have the requiered machines available.

qbradq wrote:
The upper / lower 32K stuff you are doing is going to be problematic. Many mappers (like MMC5) have mapper registers in the $5000 - $7FFF address range. Furthermore many carts also have save RAM at $6000 - $7FFF. It might be useful to be able to read and write to this as well.

That can be fixed by adding more address lines to the /CHR-RD line decoder. However, I don't have any MMC5 cartridges.

As of I've understood, the CHR area is never more than the lower 16KB.

qbradq wrote:
Other than that it all sounds pretty straight-forward. Can I ask what you use for your prototypes? I am doing my first project on protoboard and I am hating it. Air wires are getting on my nerves :D

My previous project ended up like this: http://oldibmpc.sitesled.com/nestoxt/RIMG0457.JPG , where the PCB-part alone looks like this: http://oldibmpc.sitesled.com/nestoxt/RIMG0300.JPG . It's a complete spaghetti-soup, but it works. However, I had to do some questionable tricks to get it working, like soldering wires to other wires instead of to the PCB.

What I used there was proto-board with every 3 holes connected, somewhat like an big array of 3*1 connections. The wire I have available is regular blasting-cap-type wire (solid steel-core wire). I got towards a kilogram of it years ago after they did some construction work by the school I went to.

I know about the I/O 56, but I don't have any spare 8255's around.

And about the bus transceiver, that's to keep compability with bus-operation. If the adapter is only a part of a bigger bus, then it will need to be disabled from outputing data when it's not accessed (asuming the bus has more than 16 address lines)

by on (#79977)
I think the simplest (and cheapest?) dumper is building a cart with blargg's bootloader in it (of course it can also be run off of a PowerPak), building a rs232/usb->controller port cable and disabling the CIC in the NES. Then just hotswap the cart-to-be-dumped in after the bootloader has been loaded to RAM. Rest is just software (which remains to be written...)

by on (#79980)
Original schematics has been updated. Now it limits the CHR area to the lower 16KB instead of the lower 32KB, and the upper 48KB should work just like it does on a real NES when accessed.

I also added a XOR-OR based comparator for the addres decoder if the design is to be put on an ISA card. It would also be possible to use a 4-bit demultiplexer with a 16*2 pin-connector and a jumper, however 4-bit demultiplexers are not as common as theit 3-bit counterparts.

I do not have any kind of flashcartridge, and I don't want to sacrifice one of my games, so the bootloader solution is at the moment out of question.

by on (#79984)
I have now reworked the schematics to contain parts that I actually have (except the 72-pin edge connecror and an ISA prototype card, both which can be gotten relatively cheap): http://oldibmpc.sitesled.com/misc/NESadapter2.GIF

The entire design will have a total of 4 ICs (one 74LS04, one 74LS08, one 74LS32 and one 74LS154), and can be configured to anywhere in the base 1MB of the targer PC's memory.

The real question still is that if it is OK to "forge" the Ø2 signal by NAND-ing /RD and /WE.

by on (#79987)
The CHR address space is 8KB. Carts have contained up to 512 KB of CHR-ROM that I know of, with bank switching normally occurring by write cycles to the CPU address space above $401f. However, some games (like Punch Out! and I think a Dragon Quest game or two) bank swap CHR-ROM based on read cycles to the PPU address space.

If you like assembly you can also code the Arduino in AVR assembly. You just have to use a different makefile.

As for not wanting to learn another assembler, you're going to need to understand at least the basics of the 2A03 used in the NES and have a much better understanding of the various mapper hardware used for this project to work out for you.

Here is some recommended reading:
MOS 6502 (Wikipedia)
2A03 CPU
Mappers

Supplemental reading:
NES CPU Details
NES PPU Details

Reference material:
6502 Instruction Set

by on (#80089)
person wrote:
The real question still is that if it is OK to "forge" the Ø2 signal by NAND-ing /RD and /WE.

Not likely since without further decoding Phi2 and PPU /RD every write on the ISA bus will go to the cart as garbage (really not good with bus conflict carts). Also ISA accesses are/can be 4x faster than the CPU or PPU so that's a problem too.

I had the same idea as you, but I went with the parallel port. If you want REALLY cheap you only need two '393 counters. The control port can do all the decoding. Since there aren't enough outputs for counter reset the counter state can be determined by hooking A14 back to a status input. This method also gives you access to VRAM A10, VRAM /CE and /IRQ (though VRAM /CE isn't necessarily of use without an inverter for PPU /A13).

by on (#80140)
I know about the various mappers, so that shouldn't be a problem.

Also, I don't expect the mapper-chipsets to be extremely timing-sensitive (TTL chips can take anything from single-stepping to about 25MHz). ROM chips can also tackle any bus speed up to their maximum specification, which in most cases includes the ISA bus speed, so that's not a problem either.

As of the "forged" Ø2 signal, I see the problem, and I guess it will work if I mask it with the /CS signal then.

Code:
A15   A14   /WE   /RD   /CE   |   PRG R /W   Ø2   PRG ROM /CE   CHR /RD
 0     0     0     0     0    |      0       1         1           0      Invalid
 0     0     0     1     0    |      0       1         1           1      Dummy Write (No operation)
 0     0     1     0     0    |      1       1         1           0      Read CHR
 0     0     1     1     0    |      1       0         1           1      No operation
 X     1     0     0     0    |      0       1         1           1      Invalid
 X     1     0     1     0    |      0       1         1           1      Mapper Write
 X     1     0     1     1    |      0       0         1           1      No operation
 X     1     1     0     0    |      1       1         1           1      PRG read
 X     1     1     1     0    |      1       0         1           1      No operation

by on (#80174)
It looks like ISA holds the read strobe for 1.5 clock periods. Best case that's 188ns on an 8 MHz bus. Then you have to take into account your decoding which at 4 gates deep is 40-80ns, so subtract that and a few more ns (maybe 10) for ISA hold time. Even if you improved the decoding you still only have ~150 ns best case on an 8 MHz ISA.

NES carts will have up to 100 ns of decoding on top of 200 ns ROMs.

I'm not sure even 4.77 MHz will work. To be safe we could call your decoding and worst case cart propagation 400ns. 1 / (400 ns / 1.5) = a maximum clock speed of 3.75 MHz.

by on (#80175)
kyuusaku wrote:
Unless you're on a 4.77 MHz PC/XT I think it WILL be a problem for ROM reads.

It looks like ISA holds the read strobe for 1.5 (8-8.33 MHz) clock periods. Best case that's 188ns. Then you have to take into account your decoding which at 4 gates deep is 40-80ns, so subtract that and a few more ns (maybe 10) for ISA hold time.

Then realize that carts will have up to 100 ns of decoding on top of 200 ns ROMs.

Fortunately I do have a 4.77MHz XT available. Actually I have two, plus a clone (as I mentioned, I am a vintage computer enthusiast :wink: ).

by on (#80177)
Better underclock it to 3.58 MHz lol

by on (#80178)
kyuusaku wrote:
Better underclock it to 3.58 MHz lol

Remember that those old CPU's don't do 1-cycle-per-operation like todays CPUs. For an IBM XT with an 8088, a full bus-cycle takes 4 clocks, where two are provided for actual memory access. Even some of the BIOS chips supplied by IBM are 400ns!

Eventually, you allways have the "IO CH RDY" line which can add waitstates manually.

by on (#80179)
If the bus is strobed for two cycles (419 ns) it's still might not work since I forgot some things:

-the bus itself has decoding to make the strobes. They are probably implemented by a 74LS32 (~20 ns)

-the '245 and '154 adds 40+ ns to the "setup" requirements

by on (#80180)
kyuusaku wrote:
If the bus is strobed for two cycles (419 ns) it's still might not work since I forgot some things:

-the bus itself has decoding to make the strobes. They are probably implemented by a 74LS32 (~20 ns)

-the '245 and '154 adds 40+ ns to the "setup" requirements


In the XT, the controll-signals for the bus comes directly out of the Intel 8288 Bus-controller, where the address is latched by a set of 74LS373 latches. The 4-clock bus-cycle is controlled by the CPU itself, causing minimal intermission between the clocks.

The latching of the address is done during the first clock. Then the control signals are set and the bus is allowed half a clock of setting time (tristating), then any device has an additional one and a half clock + waitstates to provide data. Data is read by the CPU on the initial falling edge of the final clock. The rest of the final clock is used to reset the control signals for a new bus-cycle.

There is absolutely no custom logic between the 8288 bus controller and the bus.

All in all, if it still doesn't work in a worst-case scenario, then up to 10 waitstates may be added. That's more than 2uS. You'll have to go back to the 60's or early 70's to find that slow memory.

by on (#80185)
I know that under normal conditions there wouldn't be any issues due to ample address decoding time, but since the 2 cycle read strobe is being used for NES address decoding via /ROMSEL it counts.

The PC doesn't have a built-in programmable wait-state controller does it? I didn't say ISA wasn't possible, just that the design probably wouldn't work. Hell you could make a PCI-E x16 card with wait states :P

I'd argue that a ISA card to begin with isn't simple or cheap for most people due to materials and availability, but I think you'd have to agree that adding wait state logic pushes it from being practical for even a retro computer collector to a novelty design when instead you could just use a couple i8255 + address decoder and end up with a more capable device*. Something like this: http://enes.emunova.net/en/infos/dumper.htm

*with every I/O fully programmable you could reverse engineer carts, handle PPU /A13 and detect mirroring

by on (#80197)
kyuusaku wrote:
If the bus is strobed for two cycles (419 ns) it still might not work since I forgot some things:
That doesn't make sense... the NES itself supports no waitstates. From nROMSEL to data valid must be less than 279ns; from PPU nRD to data valid similarly must be less than 186ns.

The absolutely most paranoid interpretation of timing would require the cpu address bus to be stable for the entirety of φ1 and φ2 to load prgrom (558ns), and for the ppu address bus to be stable for the entire ALE and nRD cycles (372ns minus the latching time of 74x373). But I can say confidently that I've never seen anything so braindead that it requires a setup time as slow as its access time.

by on (#80224)
It makes sense because there is a lot more decoding in this design than on the NES (single '139). After the '139 there is ~250 ns before Phi2 ends. Carts can get away with even slower ROMs since A0-A14 may be decoded way before Phi2 even starts. Maybe there aren't NES carts out there with ROMs that slow, but there are FC carts that are.

Also the PPU has a lot longer than 186 ns to decode because it uses a transparent latch. It may have up to ((1/5.37 MHz) * 2) - 30 ns == ~340 ns.


419 ns could be an issue with

250 ns propagation (boards that /CE with /ROMSEL)
80 ns for 4x gate propagation (to make /ROMSEL in the design)
20 ns for '154
20 ns for '245
??? for the ISA bus state decoder
??? for 8086 hold times

--

The address bus *is* stable the entirety of Phi2, and most of Phi1. It's not an interpretation. The are carts with at least 250 ns ROMs so it's not far fetched.

by on (#80235)
kyuusaku wrote:
It makes sense because there is a lot more decoding in this design than on the NES (single '139). After the '139 there is ~250 ns before Phi2 ends. Carts can get away with even slower ROMs since A0-A14 may be decoded way before Phi2 even starts. Maybe there aren't NES carts out there with ROMs that slow, but there are FC carts that are.
BootGod's DB only knows of one.
Quote:
80 ns for 4x gate propagation (to make /ROMSEL in the design)
20 ns for '154 + 20 ns for '245
The latter happens in parallel with the former, irrelevant
Quote:
??? for the ISA bus state decoder
35ns. Except that it's stable a whole cycle before the read happens anyway. Looking at a pdf for the 82c88 it looks like the 8086 also has a substantial address stable time before nRD. (address valid starting at second half of T1, nRD asserted at start of T2, data valid by end of T3)
Quote:
??? for 8086 hold times
10ns. Which is the same as the 2MHz R6502
Quote:
The address bus *is* stable the entirety of Phi2, and most of Phi1. It's not an interpretation. The are carts with at least 250 ns ROMs so it's not far fetched.
The interpretation is only a question of how long of a setup time the ROM needs. But NES ROMs don't have latches, so they don't have a setup time. Looking at a 300ns (m27128a) rom datasheet it only has a nCE-or-address→data time of 300ns and a nOE→data time of 120ns

But all of this is irrelevant, because if it doesn't work because it's too fast, all he has to do is had a little more logic to add wait states.