Welcome, Guest!

Here are some links you may find helpful

MD Hardware engineering advice on Mega Drive dev cart design

MrD

Member
Joined
Oct 24, 2019
Messages
14
Reaction score
5
Points
3
Hello, I'm designing a basic flash-style cart to read games and demos from an SD card and write them to flash memory, as an exercise. I'd like to get Titan's OVERDRIVE demo working as I've met some of the makers. :)

I'm somewhat new to hardware engineering so I'd like a critical eye over my hardware and software design before I try to make it for real. Any advice would be appreciated.

(You might like my Ocelot Arcade System, PSCD32 controller adapter, my little Master System game or my YM2612 FM instrument editor.)

My hardware stuff up until now has been pretty basic through-hole stuff. I was thinking of getting the PCB and SMT assembly done by JLCPCB so I'm constrained by the choice of parts they have. Luckily, the ones they have seem to lend themselves to a good layout.

My cart will have a 64Mbit Flash (8 MByte, 22-bit address space A0-A21) which I'll consider as two 4MByte halves. The lower 4MByte will be the BOOT half and will be selected when the FLASH A21 is low, this will contain the menu software and so on. The upper half will be a flat 4MByte address space to write a cartridge ROM image into.

Here's my organisation for the cart: click to enlarge



Not shown is the 5V->3.3V regulator, a tank cap for the board, or the caps for each IC or the !CART grounded detection pin.

It'll boot up into a menu, read a list of files from the SD card, ask the user to pick one, then write the image to the upper 4MByte, then jump to it.

A basic summary of the steps:

1) !VRES is asserted, then negated. The cart starts connected to the 68000 address and data buses. The MCU sets up a rising edge interrupt on DETECTREGISTERCLK, then idles. The default state of !BOOT/GAME is to bankswitch in the lower 4MByte of the Flash. This will contain my menu code, etc. (I'm also going to use a 32Kbyte block of it to store the list of game names read from the SD card later.)

2) The Mega Drive performs the normal boot/TMSS sequence reading from the lower 4MByte of the Flash, and then boots into the set-up sequence of my cart's firmware.

3) The intro graphic is displayed, and a small code stub is copied to the Mega Drive RAM.

4) The stub is jumped to - the stub writes $0000 to the !TIME address $A13000, then NOPs for 0.5s, then continually reads $000006.w and loops continually while the LSB is set.

5) The write to the !TIME address $A13000 is decoded by the cart and both populates the content of the 16-bit register and triggers the MCU interrupt. The MCU NOPs briefly before acting.

6) The MCU raises MCU!68000 high, which isolates the cartridge from the 68000 bus by tristating all the transceivers in both directions. Since D0 is pulled up by the cart, any word reads to cart space will have their LSB set (other bits indeterminate). Since I know that the lowest bit of $000007 will be zero (since this is the entry point vector in the header, it must be a multiple of two), the 68000 stub will continually read 1 in the LSB of $000006.w while isolated and 0 when the cart is non-isolated.

7) While isolated, the MCU reads game filenames, titles and sizes from the SD card (or whatever data it needs) and uses FLASH!WE, the cart address and data buses to write the retrieved data to a 32 Kbyte block within the lower 4MByte of the Flash. (While isolated from the 68000 bus, the Flash chip's !C_CE will be pulled low.)

8) When finished, the MCU sets up another rising edge interrupt on DETECTREGISTERCLK and lowers MCU!68000 to reconnect the cart to the 68000 buses.

9) The 68000 can now exit the busy loop.

10) The Mega Drive jumps back into the lower 4Mbyte of the cart Flash to run a menu program, with all the available games data available within that 32Kbyte block.

11) The user selects a game - this is encoded as a 16-bit value (the index of the game in the order retrieved from the directory listing, or some other numeric identifier).

12) A second stub is jumped to in RAM, and the selected game value is written to the !TIME address $A13000, then the Mega Drive NOPs for 0.5s, then continually reads $000006.w and loops continually while the LSB is set as before.

13) The write to the !TIME address $A13000 is decoded by the cart and both populates the content of the 16-bit register and triggers the MCU interrupt. The MCU NOPs briefly before acting.

14) The MCU raises MCU!68000 high again to isolate the cart.

15) The value written to the register is retrieved into the MCU using REGISTER!OE and the cart's data bus.

16) The MCU raises !BOOT/GAME to switch in the upper 4MByte of the Flash.

17) The MCU can now open the indicated game file from the SD card and write it to the upper 4MByte of Flash.

18) When done, the MCU can lower MCU!68000 to reconnect the cart to the 68000 buses. The MCU enters a low-power idle state and takes no further action. All of its pins are inputs except !BOOT/GAME which is high.

19) The 68000 is released from its busy loop when the cart buses are reconnected.

20) The Mega Drive cleans up any RAM/VRAM it needs to using its stub (in case certain software cares?), zeroes out itself as much as it can, then jumps to ($000004).l to boot the game present in the upper 4MByte of the Flash. From this point on, the cart is completely dumb ROM. Writes to !TIME will populate the register, but it will never be read.

Does that sound like a good approach?

--

I'd like a second opinion on my glue logic and transceiver usage since I've never done this before.

My signal names are (usually) prefixed by their source (68000 bus or MCU).

I'm using transceivers to split the 5V 68000 world from the 3.3V internal world. The two 16-bit transceivers on the left should be considered as one 32-bit transceiver for the 'address and signals bus'. I'm using the !C_CE, !AS, R/!W, !TIME and !VRES signals from the cartridge slot to detect chip enables, reads, writes, strobes and reset conditions.

I'm using the 16-bit register because the MCU is way too slow to react to the 68000 quickly writing a word to the !TIME address space. With the register, I can store the value and use the rising edge of CLK to awaken the MCU, then it can isolate the cart and read the written register value at its own pace.

Reset logic:

FLASH!RST = 68000!VRES
MCU!RESET = 68000!VRES
The PICkit is also connected to this pin when I'm programming the MCU, but you should never program the PIC while the cart is within the MD anyway. I'm going to have it so that you apply an external 5V source to the cart through header pins.

Address decoding logic:

FLASH!CE = 68000!C_CE (pulled low on isolate) The Flash should be selected on access to $000000-$3FFFFF, or always if the cart is isolated.
FLASH!OE_EXTERNAL = 68000!C_CE + 68000!AS + NOT(68000R/!W) This signal represents an !OE request from a 68000 request. This happens when !C_CE is low, !AS is low and R/!W is high. I shouldn't need !C_CE strictly, but I'm using this combination as an input below.
FLASH!OE = MCUFLASH!FORCEOE * FLASH!OE_EXTERNAL I want the Flash to output a value if the MCU is forcing it to, or if the 68000 signals ask it to.
REGISTER!WE = 68000!TIME + 68000!AS + 68000R/!W I'm going to have the register respond to any write in the $A130xx range, since that's simple. The register writes on the ascending edge of this signal, so it's also listed as REGISTERCLK.
MCUDETECTREGISTERCLK = REGISTERCLK On the rising edge of the register clock, the MCU awakes at the same time as the register is written.

Transceiver logic:

74ALVC164245 logic:
A bus = 3.3V
B bus = 5.0V
DIR L = 3.3V output <- 5V input (value into cart from 68000 - DATA: a write operation, ADDRESS: 68000 Ax enters cart address bus.)
DIR H = 3.3V input -> 5V output (value from cart into 68000 - DATA: a read operation, ADDRESS: cart address bus leaves onto 68000 Ax, do not allow this.)

ADDRESSTRANSCEIVERDIR = low Only valid direction is an address from the 5V port placed on 3.3V port if ADDRESSTRANSCEIVER!OE is low.
ADDRESSTRANSCEIVER!OE = MCU!68000 When MCU is in !RESET or if this pin has not been raised, the 68000 address appears on the 3.3V address bus.

DATATRANSCEIVERDIR = R/!W I'm surprised I don't have to invert this, the 68000's R/!W signals match the direction of the 74ALVC164245.
DATATRANSCEIVER!OE = MCU!68000 + (FLASH!OE_EXTERNAL * REGISTER!WE) I want to connect the data bus if isolation is not in effect and we're valid reading the Flash or valid writing the register. (Notice my FLASH!OE requires FLASH!CE instead of being independent of it to allow the combination to be used here.)

When the !OEs are low, the address or data buses will be floating, so I'm going to connect each pin to ground through 6k8 to prevent any unusual behaviour during isolation.

I'm also pulling up !AS, R/!W, !TIME and !VRES high whenever the cart is isolated, to disable the Flash and register ICs unless the MCU activates them itself.

MCU Outputs:

While the MCU is in the reset state, all its pins are tristated. My pull- resistors need to make this a good safe state for the cart to be in before the menu begin, and while the real game is running and the MCU is idle:
MCU!BOOT/GAME, low default, if low select the boot menu half of Flash, if high select the game half of Flash.
MCUFLASH!WE, high default, allows the MCU to program the Flash
MCU!68000, low default, if high the cartridge transceivers tristate the cart from the 68000 buses.
MCUFLASH!FORCEOE, high default, if low the MCU is reading the Flash (to verify a write)
MCUREGISTER!OE, high default, if low the MCU is reading the last value written to a !TIME address

MCU Inputs:
DETECTREGISTERCLK, a rising edge wakes the cart for either the 'ready to read games' state or the 'please play game REGISTER' state.
!RESET, standard reset.
The Flash indicates a busy state by toggling a Qx pin on consecutive reads during busy, so there's no busy pin to poll.

I haven't yet fully specified the SD card interface yet. I think I'm going to use the 4-wire SPI mode, with all the lines pulled to 3.3V through 3k3, and a 10R resistor on the +3.3V line to prevent high inrush current.

Please let me know what you think.

Datasheets:
Transceiver
Flash
Register
PIC MCU

Regards,
Matt C. :)
 
Last edited:

MrD

Member
Joined
Oct 24, 2019
Messages
14
Reaction score
5
Points
3
I've had another look and it seems that the 68000 R/!W signal isn't present on the cartridge port, and there's !UDW and !LDW upper and lower data write strobes instead. So is it the case that a read is taking place if neither !UDW and !LDW are asserted, and a write is taking place otherwise?

So in my design I could add
DERIVED R/!W = !UDW * !LDW
and the rest of the semantics would be the same? I'd have to transceiver these and pull them up, etc?
 
Last edited:

MrD

Member
Joined
Oct 24, 2019
Messages
14
Reaction score
5
Points
3
The CPU is used for writing the ROM images from the SD card to the Flash.

I'm going to implement the control logic I listed that controls the OEs of the Flash and register etc using gates.
 

megavolt85

DreamShell Developer
Registered
Joined
Jun 17, 2019
Messages
203
Reaction score
554
Points
93
Location
Russia
Website
www.dc-swat.ru
AG User Name
megavolt85
AG Join Date
01.09.2015
Why use a third-party processor if 68K is enough?
If the project is for yourself, why save on the flash memory, use SRAM
 

MrD

Member
Joined
Oct 24, 2019
Messages
14
Reaction score
5
Points
3
Why use a third-party processor if 68K is enough?
If the project is for yourself, why save on the flash memory, use SRAM
I already have an SD card library for the PIC microcontroller that supports FAT32, Long File Names, directories, etc.

I don't want to have to write a new SD card library for the 68000, and bit-bang the protocol to and from the SD card through some register mapped into the memory space. That is certainly doable, but a lot of effort. :)

I don't understand your second point - I'd rather save money on having a single cheap component that acts as nonvolatile boot menu rom, and a large rewritable game area rom, than buy a series of more expensive components which I then have to place, route and decode addresses for. On top of that, I'd still need a nonvolatile rom area for the cartridge to boot into in the first place to select what game I wanted from the SD card's storage anyway.

--

I had a look at your schematic, but I don't see how that applies to my project. I don't have a single large Flash rom that contains many games that I need to bankswitch between. And if I did, how would I get the games onto it in the first place?
 

megavolt85

DreamShell Developer
Registered
Joined
Jun 17, 2019
Messages
203
Reaction score
554
Points
93
Location
Russia
Website
www.dc-swat.ru
AG User Name
megavolt85
AG Join Date
01.09.2015
Look towards the CH376S by hanging this chip into the address space /TIME (A13000-A130FF) you 'll very simply get a USB or SD
FAT is integrated into this chip at the hardware level

In order to sew in the flash the rum you choose, it takes a lot of time if you use SRAM upload will be a lot faster
 

MrD

Member
Joined
Oct 24, 2019
Messages
14
Reaction score
5
Points
3
I hadn't heard of that chip, but I'm surprised to see that the manufacturer I was going to use stocks it, and its in their 'basic' parts category so there's no stocking fee for using it. That's very interesting! Thank you.
 

MrD

Member
Joined
Oct 24, 2019
Messages
14
Reaction score
5
Points
3
A cart using a SD interface chip would still need some non volatile storage on it for the boot rom, though. How would you program that? You'd have to build a freestanding programmer perhaps, with a cart slot on it? (Or do something really risky like boot off one cart, copy contents to ram, jump to ram, swap to second cart, write to new cart?)
 

megavolt85

DreamShell Developer
Registered
Joined
Jun 17, 2019
Messages
203
Reaction score
554
Points
93
Location
Russia
Website
www.dc-swat.ru
AG User Name
megavolt85
AG Join Date
01.09.2015
need small flash memory for store boot loader (menu)
The first firmware will in any case require a programmer
It can be TL866 or homemade on arduino
 

MrD

Member
Joined
Oct 24, 2019
Messages
14
Reaction score
5
Points
3
I've written a big ol' technical page about Game Raccoon Revision 0!

Everything worked exactly as I'd hoped, in terms of !TIME, the PIC, the Flash, the SD card, etc.

But as you can see my design uses !AS as a read strobe so VDP copies don't work sadly. :( Which means that Overdrive looks a little different :)


A more blog-like post with lots of sketches and wip images will come later.

Any hints for Revision 1 would be gratefully accepted. :)
 

MrD

Member
Joined
Oct 24, 2019
Messages
14
Reaction score
5
Points
3
My Raccoon page has been updated with a (long!) blog about the design process and reasoning.
 

supersega

Donator
Donator
Joined
Nov 25, 2019
Messages
54
Reaction score
18
Points
8
AG User Name
supersega
AG Join Date
Jul 25, 2014
WOW man!! That's still amazing how you were able to get that working. I may have to build this circuit myself to mess with! :)
 

MrD

Member
Joined
Oct 24, 2019
Messages
14
Reaction score
5
Points
3
Thanks :D You could wait until my Revision 1 prototypes arrive though - I've redesigned the logic section so it ought to work with DMA
 

MrD

Member
Joined
Oct 24, 2019
Messages
14
Reaction score
5
Points
3
gameraccoonlogo7_raccooncute_shadow_placedcaption400.png


I've now completed Revision 1 of my Game Raccoon SD Card flash cart and published the web site. :)

http://www.mrdictionary.net/gameraccoon/

IMG_6950_2000wide-295x220_1.jpg


Each revision has a Technical Report, which is a basic description of how the cart works, with the schematics and EAGLE files available under CERN OHL and the on-board PIC firmware and 68k Flash-resident menu available under AGPL3. *

The Misadventures are (very) lengthy blogs about the journey from a blank sheet of paper to Revision 0, and from there to the fully-functioning Revision 1. That's also where you'll find links to the latest software compatibility spreadsheets for demos and Sonic hacks etc.

* I'm not super attached to the licenses, I'm just sick of dithering about it. You can ask, but if you think you need another license, you're probably good enough to rewrite the code anyway. :)

Please ask me anything! If there's something I've seriously messed up, please let me know. I also need to find myself an artist to work on the cute mascot raccoon animations during the copy operations!

I'm not manufacturing or selling Game Raccoon carts, and don't have any plans to right now. The plans are there if you want to see how it works and mess about and make your own. :D
 
shape1
shape2
shape3
shape4
shape5
shape6
Top