Original Post

I have had the basic idea for this for a long time but now that we are getting close(?) to having a mass-produced VB-PC cable, I have improved it and now it is much better than before.

Basically, the cartridge would be the same as a flash cartridge, but containing only SRAM memory. The advantage is that SRAM has (for all practical purposes) an unlimited lifetime, so the cartridge could be reprogrammed an infinite number of times without wearing out (and at a higher speed too?). The disadvantage would be having to change the battery periodically, but I think this is a small price to pay in exchange for those capabilities, and since this cartridge would be aimed at developers, it would be no problem simply to reprogram it again with a ROM image of the program in development if it loses data. Actually, it might not even have to be powered at all times, which brings me to my next point.

The big feature is that such a cartridge, if it exposed at least 2M of memory in the 0x06xxxxxx area, could be reprogrammed while being used in the Virtual Boy if there was a small loader program in the 0x07xxxxxx area that received the ROM image from a PC and wrote it to the 0x06xxxxxx area, then jumped to it. The ROM image would of course have to be compiled so it would use addresses in that area. While running, it could (perhaps by using an interrupt) call the loader to patch itself. Of course, the loader could also implement other features, for example dumping memory contents to the PC or taking screendumps (by dumping the frame buffers being displayed).

If the VB allows writing to the 0x07xxxxxx area (which it probably does not given that this area is intended for ROM, but my knowledge regarding this is insufficient), the ROM images would not have to be customized to use different addresses and they could use the 0x06xxxxxx area like commercial game cartridges for the 8K (or more) of SRAM intended for saving game data, but they would have to contain their own code to communicate with a PC and the cartridge would have to be programmable from a PC as well, otherwise you would run into a chicken and egg problem if you loaded a ROM image without any communication code. Or maybe the cartridge could contain code at 0x07FFFFF0 to jump to a loader at the end of the 0x06xxxxxx area, receive a ROM image from a PC and write it starting at 0x07000000 and ending before 0x07FFFFF0, jump to it, and still expose functions in the 0x06xxxxxx area for the program to access. The possibilities are limitless (well, at least theoretically).

So, VB hardware gurus, is this at least slightly possible to implement?

11 Replies

While I have no direct experience, I believe DogP has written to flashROMs located at 0x07xxxxxx while the cart was in a VB. I believe the “write enable” line used for the expansion area (0x04xxxxxx) is also active during writes to the ROM area.

When I was pondering the problem of an SRAM cart, here is what I came up with:
1) The SRAM would be mapped to ROM space, as usual.
2) A bootloader, stored in a small (mask/OTP/EP/EEP/flash)ROM, would also be mapped in the ROM area.
3) There would be no conflict, because the /CE lines of the two (sets of) chips would not be enabled at the same time.
4) Upon booting, the ROM’s /CE would be connected to the VB.
5) After optionally loading a ROM over the link, the VB would jump to the reset vector (0xFFFF_FFF0).
6) Logic in the cart would detect this jump and simultaneously disconnect the ROM’s /CE while connecting the SRAM’s /CE.
7) When power is removed from the cart and reapplied, the /CE switching circuit would be reset, ensuring that the ROM will boot next time the system is started.

It could be done with discrete logic, but a more compact (and likely cheaper) method would use some kind of programmable logic chip. If I were familiar enough with these to decide on the best one(s) to use, I would have already designed the circuit for this. (I have a lot of 5V SRAM chips salvaged from the cache of old PC motherboards). I would gladly help do some research on this, though.

I had also considered an SRAM cart in the past, but there were several things that kept me from pursuing it. One… large 5V SRAM isn’t easy to come by, and isn’t cheap (at least it wasn’t when I last looked… IIRC I have a lot of 512KB chips somewhere). Also, you’d need to make sure it was the low power SRAM if you planned to have it store the data across power cycles (otherwise you’d drain the battery fairly quickly).

My opinion was that flash can do pretty much everything that SRAM can do, though maybe just a little bit slower to write (though if you’re talking about using a VB<->PC cable as the programming cable… either one will be faster than the VB link port). I doubt any of us would ever hit the endurance cycles on one of the flash chips. You could put a bootloader in the upper half of a flash chip (and waste half the flash), or use a second flash chip. Two flash chips (like using a flash chip and SRAM) will make routing more tedious since you’ll need to route a bunch of duplicate address and data lines to multiple chips, plus the chip selector decoder logic. And I certainly haven’t looked hard, but I don’t remember seeing x16 SRAM chips, so that’s even more tedious routing to have 2x x8 SRAM chips, plus a bootloader flash chip, plus decoding logic.

And yeah, I don’t think there’s any reason to connect to the 0x06xxxxxx addresses (pin 5 is /WE, which works just fine for writing at 0x07xxxxxx).

Overall though, I think slapping an FPGA on a cart with some modern memory is the way to go. If I had time to finish projects, I’d just build a real cart like I prototyped up a few years back: http://www.planetvb.com/modules/newbb/viewtopic.php?topic_id=4060 . I’d love to have tons of extra RAM and an FPGA as a co-processor. Maybe I can pay off my house and stockpile a bunch of food so I can quit my job and finish these things. πŸ˜›

DogP

It could be done with discrete logic, but a more compact (and likely cheaper) method would use some kind of programmable logic chip.

Dude, a 4-bit register would suffice for this. Just

– configure it as a shift register,
– have asynchronous reset connected to the #RESET line,
– clock connected to #ROM_CE, and
– parallel load connected to #LWR.

Then either make the input A a static ‘1’ or D0 or something. The output Q_A goes to the boot ROM.
You should then use a little logic gate to invert this enable signal for the SRAM chip: tie the SRAM CE to deasserted state when #RESET is asserted to protect SRAM from spurious writes during powerup.

Overall though, I think slapping an FPGA on a cart with some modern memory is the way to go. If I had time to finish projects, I’d just build a real cart like I prototyped up a few years back

An FPGA would be an excellent expansion lol. However, I do think an FPGA/CPLD for this kind of project would be overkill 😐

cYa,

Tauwasser

There is a lot of stuff in your post I don’t get, Tauwasser.

Tauwasser wrote:
Dude, a 4-bit register would suffice for this. Just

Do you have an actual part number for this? It sounds like you’re talking about a quad D flip-flop.

– configure it as a shift register,

What is this configurable part that isn’t an FPGA/CPLD(/PAL/GAL)? Do you just mean strapping inputs to outputs in a chain? Why not just use a purpose-built, serial-in, parallel-out shift register?

– have asynchronous reset connected to the #RESET line,
– clock connected to #ROM_CE, and
– parallel load connected to #LWR.

What does #LWR mean? I assume you mean the ROM/EXP write strobe, pin 5. What is the purpose of doing this?

Then either make the input A a static ‘1’ or D0 or something. The output Q_A goes to the boot ROM.

Where on the boot ROM does Q_A connect? #CE?

You should then use a little logic gate to invert this enable signal for the SRAM chip: tie the SRAM CE to deasserted state when #RESET is asserted to protect SRAM from spurious writes during powerup.

This part I get, although the point of this whole excercise is to make a circuit that keeps the SRAM disabled until it’s time to switch.

Now, let me see if I get how your proposed circuit would work:
1) Upon boot, the “register” would be reset, thus containing four ‘0’ bits.
2) Output Q_A, being low, would enable the ROM (and disable the SRAM).
3) Every time the ROM chip-enable line is asserted, the contents of the register are shifted.
4) Since input “A” is tied high, ones would always be shifted into the register. (Unless it’s tied to D0, then I’m not even sure how to determine what gets shifted in…)
5) After one read from the ROM, a ‘1’ gets clocked in, switching from ROM to SRAM.
6) The VB appears to freeze as it starts executing the (still empty) SRAM. πŸ˜•

I don’t think you can fit a link port-based SRAM programming routine in one instruction… πŸ˜‰

I probably don’t fully understand what your circuit does. It’s pretty much moot, though since, IMO, switching between the ROM and the SRAM shouldn’t be based on a pre-determined number of read cycles. For maximum versatility, it should be totally under the control of the software running on the VB. Hence my proposal for triggering it based on a read from the reset vector. Would you care to apply your 1337 logic haxx0ring skillz to that problem? πŸ˜€

Overall though, I think slapping an FPGA on a cart with some modern memory is the way to go. If I had time to finish projects, I’d just build a real cart like I prototyped up a few years back

An FPGA would be an excellent expansion lol. However, I do think an FPGA/CPLD for this kind of project would be overkill 😐

I agree that an FPGA or other large programmable device would be overkill for the cart I described. I was thinking more along the lines of a PAL/GAL like the (once ubiquitous) PALCE16V8 (or whatever similar device can still be found/programmed in sufficient quantity).

RunnerPack wrote:

Tauwasser wrote:
Dude, a 4-bit register would suffice for this.

Do you have an actual part number for this? It sounds like you’re talking about a quad D flip-flop.

I am talking about a quad DFF, specifially one with clock and write enable. Four bit counters have this option and are cheap.

I picked up the line “in shift register configuration” somewhere and it stuck. Yes, it means connecting the outputs to the next input. However, I did not explain in too much detail what I actually meant, my bad.

The purpose of not using a dedicated part is to be able to adjust the bus access cycle delay.

So you can either have byte and half-word access to only half-word access, or only word-access to our register.

RunnerPack wrote:
What does #LWR mean? I assume you mean the ROM/EXP write strobe, pin 5. What is the purpose of doing this?

It’s the write strobe for the least-significant 8 bits on the data bus. The meaning is the same as for the WRAM chips. You could also use #UWR if you so wished (only half-word/word access then). Look at this Wiki page where I updated the signal names and corrected the pinout.

It’s /WE0 and /WE1 respectively. I doubt the table is correct, because the write strobes don’t really depend on memory ranges but on bus configuration and width of write/read access. Which is why I stick to #LWR and #UWR.

RunnerPack wrote:
Where on the boot ROM does Q_A connect? #CE?

Yes. And with some logic in-between to accommodate safe power-up the other output will go to SRAM.

RunnerPack wrote:
IMO, switching between the ROM and the SRAM shouldn’t be based on a pre-determined number of read cycles. For maximum versatility, it should be totally under the control of the software running on the VB.

It is totally under control of the software. You write to anywhere in the ROM region, either byte-wide or half-word-wide (so we have one bus access cycle). Then you jump to the reset vector of whatever you just wrote into SRAM.

You will have to bridge the delay
– from writing to our register,
– reading the JMP instruction — one bus accesses in instruction format I,
– executing the JMP instruction

Instruction cache will have to be off for that, but I image it will have to be off either way or you risk data from your bootstrap being used in place of program instructions?

An ugly eagle drawing will suffice:

(This is the first time I used Eagle – and I hope it’s the last time…)

Gating logic could be for instance 74LVC1G57 + Transistor + Pullup Resistor. Take 74HC161 for the 4-bit synchronous counter with asynchronous clear and we’re looking at part costs of about 1.50 USD with no special programming equipment and no concern for high-voltages needed for PALs/GALs that would kill our other parts.

cYa,

Tauwasser

  • This reply was modified 10 years, 6 months ago by Tauwasser.

RunnerPack wrote:
Would you care to apply your 1337 logic haxx0ring skillz to that problem? πŸ˜€

Don’t patronize me.

cYa,

Tauwasser

Oki…non-hardware/software/barely a good player talking.

What would this be used for ? increasing the memory size/saving games…? just curious.

-Eric

***Deleted by author***

  • This reply was modified 10 years, 6 months ago by RunnerPack.

bigmak wrote:
What would this be used for ? increasing the memory size/saving games…? just curious.

-Eric

The proposed cartridge would allow developers to test code on hardware more quickly, since there would be no need to remove the cart from the VB to program, and the SRAM can be written to much faster than flash.

The downside for general gaming use is the need to battery-back the SRAM for it to retain its contents with the VB off (hence the use of flash in the flashboy).

Tauwasser wrote:

RunnerPack wrote:
What does #LWR mean? I assume you mean the ROM/EXP write strobe, pin 5. What is the purpose of doing this?

It’s the write strobe for the least-significant 8 bits on the data bus. The meaning is the same as for the WRAM chips. You could also use #UWR if you so wished (only half-word/word access then). Look at this Wiki page where I updated the signal names and corrected the pinout.

It’s /WE0 and /WE1 respectively. I doubt the table is correct, because the write strobes don’t really depend on memory ranges but on bus configuration and width of write/read access. Which is why I stick to #LWR and #UWR.

Actually, while that may be true on a standard V810 bus, are you sure its applicable to the VB? The address masking alone shows how much Nintendo messed with the V810 when they made the NVC. I don’t think there is a way to access individual byte addresses on the cart, since there is no A0 line (which is why the upper bytes read from cart RAM have to be masked off). I do believe the pinout on the Wiki is correct, though, according to information gathered by David Tucker and DogP while testing the actual hardware (and, obviously, the Flashboy+ works ;-)).

RunnerPack wrote:
IMO, switching between the ROM and the SRAM shouldn’t be based on a pre-determined number of read cycles. For maximum versatility, it should be totally under the control of the software running on the VB.

It is totally under control of the software. You write to anywhere in the ROM region, either byte-wide or half-word-wide (so we have one bus access cycle). Then you jump to the reset vector of whatever you just wrote into SRAM.

You will have to bridge the delay
– from writing to our register,
– reading the JMP instruction — one bus accesses in instruction format I,
– executing the JMP instruction

Instruction cache will have to be off for that, but I image it will have to be off either way or you risk data from your bootstrap being used in place of program instructions?

Oh, I think I get it, now. I was assuming the SRAM and ROM would both be in the ROM address space, with writes going to the SRAM and reads coming from either the ROM or the SRAM under the control of your circuit. Now it seems like you want to use the cart SRAM (i.e. save-game RAM) space for the SRAM, which would require modifying the ROM or retargeting the compiler. Am I close?

An ugly eagle drawing will suffice:

(This is the first time I used Eagle – and I hope it’s the last time…)

As an aside, what do you normally use instead of Eagle, and why didn’t you use it this time? I use Eagle quite a bit. It was a little weird at first, but once you understand how it does things, it’s not that bad. The limitations of the “hobbyist” version are frustrating, sometimes, but not a deal-breaker.

Gating logic could be for instance 74LVC1G57 + Transistor + Pullup Resistor. Take 74HC161 for the 4-bit synchronous counter with asynchronous clear and we’re looking at part costs of about 1.50 USD with no special programming equipment and no concern for high-voltages needed for PALs/GALs that would kill our other parts.

I just did a quick check, and your parts list comes to quite a bit more than the cost of many of the ATtiny chips (only checked Mouser, though). Other than the cost of a programmer, that might be a better solution (and a parallel port could be used as a bootstrap, in a pinch). Just something to ponder, anyway. Of course, your actual circuit function looks good, even if it’s implemented in code instead of silicon.

RunnerPack wrote:
Actually, while that may be true on a standard V810 bus, are you sure its applicable to the VB? The address masking alone shows how much Nintendo messed with the V810 when they made the NVC. I don’t think there is a way to access individual byte addresses on the cart, since there is no A0 line (which is why the upper bytes read from cart RAM have to be masked off). I do believe the pinout on the Wiki is correct, though, according to information gathered by David Tucker and DogP while testing the actual hardware (and, obviously, the Flashboy+ works ;-)).

Since I checked the pinout and contributed to it while working on my dumper (which also works correctly), I, too, assume it to be correct.

Notice how I didn’t say the SRAM was byte-addressable — merely byte-accessible. You still have the byte aliasing.
However, I see no point in Nintendo screwing with the write strobes as they are used like the documented counterparts on the WRAM chips.

I didn’t find any substantial research into this. As a matter of fact, I found very little research into any of the hardware in the homebrew scene. Sure, code will work without knowing this specific piece of information.

However, I’d like to think that it operates just the same as 16-bit fixed mode, Table 5-2 in the official μPD70732 data sheet.
Until somebody comes up with better information using a test program and a logic analyzer/oscilloscope this is moot, however.

RunnerPack wrote:
Now it seems like you want to use the cart SRAM (i.e. save-game RAM) space for the SRAM, which would require modifying the ROM or retargeting the compiler. Am I close?

No. Merely have this register somewhere accessible and it will switch between enabling the ROM (for your bootstrap code) and SRAM in ROM space — or any space you want, really.
The register itself could be in either ROM, SRAM or EXPANSION space for that matter.

However, you could also simplify this circuit quite a bit by just being a register and executing the code from WRAM, so you don’t need a delay if that is what concerns you.

You’d read the appropriate code beforehand, write it to WRAM, then jump to it. You could then even build the register to selectably turn SRAM on/off at will, which might help with programming if you need to access data in your bootstrap ROM in-between.

This might even be better for programming anyway.

RunnerPack wrote:
As an aside, what do you normally use instead of Eagle

On other occasions, I have used the industry standard software package Altium. I thought doing this in Eagle might help me get started, but it was really painful :-/

RunnerPack wrote:
I just did a quick check, and your parts list comes to quite a bit more than the cost of many of the ATtiny chips (only checked Mouser, though).

I only checked Digikey, but made sure to look for prices at low quantities.
However, I caution you not to use a software solution for this. IIRC, the bus accesses are done at 20 MHz, so you will have to have quite efficient code and a really fast clock to do this in software.
Apart from that, there is also no need for a software solution for this problem.

cYa,

Tauwasser

  • This reply was modified 10 years, 6 months ago by Tauwasser.

 

Write a reply

You must be logged in to reply to this topic.