USB MegaDrive DevKit

For hardware talk only (please avoid ROM dumper stuff)
prophet36
Very interested
Posts: 234
Joined: Sat Dec 13, 2008 6:58 pm
Location: London, UK
Contact:

USB MegaDrive DevKit

Post by prophet36 » Sat Dec 13, 2008 8:17 pm



*** Click Here for Progress Updates on the USB Megadrive DevKit! ***


Hi,

I've been working on this project on and off for a few months now, mostly as a training exercise in circuit design, homebrew PCB fabrication and programming microcontrollers.

http://www.swaton.ukfsn.org/umdk/

Basically it's a custom MegaDrive cartridge with 1Mb of SRAM, an Atmel AVR microcontroller (AT90USB647), an SD-card slot with a 2Gb card and various bits of glue logic, and a couple of bits of veroboard (RS-232 transceiver and switches).

At the moment it's in its early stages. When the MegaDrive is powered on, the AVR holds the MegaDrive in RESET, then prints a CLI prompt on the (VT100-compatible) terminal on the other end of the blue-white striped RS-232 wire you see on the left of the pictures. It then accepts a few simple commands:

ls: list the root directory of the FAT32-formatted SD card.
load <fileName>: load the specified file into the onboard SRAM.
crc: calculate the CRC32 of the file loaded into memory.
boot: let go of the bus and release the MegaDrive from RESET.

As you can see in the pictures, when the MegaDrive is released from RESET it sees the onboard SRAM as if it were a 1Mb ROM, and starts executing (and yes, before anyone asks, I do own the original carts for the ROM images shown).

However, I wrote this CLI thing just to get me started. What I'd like to do is implement two modes of operation, standalone and USB.

Standalone Mode
In standalone mode, the AVR will scan the SD card for a ROM image called index.bin, which it will load into memory and start it executing. This image is a simple on-screen menu system, listing all the ROMs on the SD card. You select one using the control pad, and the MegaDrive notifies the AVR somehow which one was chosen. The AVR then loads the chosen ROM and starts it executing.

USB Mode
In USB mode, the cartridge enumerates as a custom USB device (using Dean Camera's excellent Lightweight USB Framework for AVRs) which will accept commands from a USB host via libusb, allowing MegaDrive code to be developed on the PC and uploaded over USB.

I'd also like to be able to give the MegaDrive access to on-cartridge peripherals (SD card, RS-232/MIDI, PS2 keyboard?), but since these are typically embedded in the AVR, direct bus access is not an option, so I'm thinking about some kind of interprocessor communication mechanism similar to Acorn's Tube. The result would be usable as a simple standalone computer.

My problem is that I work full-time so I can only afford to spend a few hours per week on this thing, so I'm thinking of releasing the whole lot (Eagle schematics & layout, PAL design, firmware source etc) with an open-source licence, in the hope that someone out there is interested in contributing.

So...any volunteers?

- Chris
Last edited by prophet36 on Sun Apr 03, 2011 3:55 pm, edited 2 times in total.

Graz
Very interested
Posts: 81
Joined: Thu Aug 23, 2007 12:36 am
Location: Orlando, FL

Post by Graz » Sat Dec 13, 2008 8:37 pm

Wow, that's excellent. I'm very interested in these kinds of projects. Unfortunately I don't have access to home-brew PCB making equipment right now and so can't attempt anything too ambitious.
As for making peripherals accessible to the 68K, I would suggest using an FPGA to build a bridge between the 68K bus and the AVR. Bus access to the appropriate region could trigger interrupts on the AVR. Alternatively, just build your RS232, SD interface, etc. into the FPGA and build a register programming interface right onto the bus rather than using the AVR's integrated blocks. There's plenty of examples of handing the 68K's bus protocol at opencores and other such sites.
I'd certainly volunteer to help, but I think my time may be as scarce as yours.

prophet36
Very interested
Posts: 234
Joined: Sat Dec 13, 2008 6:58 pm
Location: London, UK
Contact:

Post by prophet36 » Sat Dec 13, 2008 8:56 pm

Thanks Graz!

Hmmm...FPGAs...never played with them. The closest I got is simple PALs, although I did work for 3Dlabs a few years ago doing VHDL validation. But there's a big difference between doing stuff as part of a big (and very talented) team and doing it all on your own. Have you done any FPGA development? Any pointers on where to get started?

Leaving the interprocessor communication stuff aside for now, I would actually be happy with just the two modes of operation I described, and I think the only bit of hardware necessary to get those working is some mechanism for the 68000 to return the ID of the selected ROM. I could solve that easily enough by wiring up the 68000's data strobes, allowing it to write to the top word of the cartridge ROM. I could easily make that write operation cause an interrupt on the AVR, which would take back the bus, read the top word, and continue.

But on the software side, despite the fact that I used to write 68000 for the Amiga (I used to be RanX of Quartz in a past life), I have never written any MegaDrive code, so even a simple menu system is beyond me...that's where I could really use some help at the moment, and I'm sure such a thing could be implemented on an emulator easily enough.

- Chris

Graz
Very interested
Posts: 81
Joined: Thu Aug 23, 2007 12:36 am
Location: Orlando, FL

Post by Graz » Sat Dec 13, 2008 10:14 pm

One of the sites I read a lot when I was learning about FPGAs is fpga4fun.com. It's geared towards the beginner and hobbyist. I got one of their dragon boards. It's a bit expensive given the size of the FPGA, but it's got a PCI interface, which is nice for building register-driven designs that don't really stand alone. If you don't care about PCI, this board is less expensive and has a pretty large FPGA, loads of RAM and other IO. I've used it to build custom microcontroller/DSP cores before. It should be more than enough to learn about FPGAs. Once you're comfortable with FPGA design, take a look through opencores for a huge amount of example code. Xilinx's webpack is free and can build VHDL (and many other languages) for their FPGAs. I believe Altera now gives Quartus away for free too, but I haven't checked in ages.
If you do decide to put an FPGA into your design, there are a couple of things to watch for. First, if you find an FPGA with enough IO to decode the 68K address bus, interface to the 68K's data bus, drive the RAM and other IO and interface to the AVR, it may only be available in a ball-grid package. These are basically impossible to route on a home-built PCB. Try to get a QFP (TQFP or VQFP) packaging if you want to build the board yourself. Second, you'll need to make sure that the FPGA has 5V tolerant IO. Not all do. If you can't find an FPGA that has enough 5V tolerant IO, you'll need level shifters and such in your design.

vBLANK
Newbie
Posts: 2
Joined: Mon Dec 15, 2008 2:27 pm
Location: Philadelphia
Contact:

Post by vBLANK » Mon Dec 15, 2008 2:52 pm

Hey Chris,
This is great stuff! A friend who's aware of my recent interest in this system bumped your project to me. I think we're quite like minded!

I do AVR work, and some hobby system design, and was thinking of a very similar scheme for SD. My thought was less slick, in that the index.bin would simply be a label set that helped the user select via dipswitches on the cart.

I think your scheme implies writing the index.bin on the fly and then resetting the hardware on user/menu selection to load the selected program. Interesting!

I'm not familiar with Acorn's Tube, but it seems to me a simple set of handles for the 68k to have access to would work quite well for most slower peripheral devices. This is done all the time in the "Arduino" end of the AVR world for access to things like LCDs and GPS receivers (that have their own processors on board) via a trimmed down RS-232 or I2C.

I'll have to take a deeper look at all of this when I return from work, but I'll drop you a PM later in the week.

Thanks for the inspiration!
-Wil

abcminiuser
Newbie
Posts: 1
Joined: Tue Dec 16, 2008 2:56 am

Post by abcminiuser » Tue Dec 16, 2008 2:59 am

Wow - that's absolutely incredible! As a lover of Sonic on the Megadrive (but not the lack of a save functionality) I must say this is a great (if totally unexpected) use of my USB library.

Fantastic work, and I'm looking forward to seeing how this evolves.

- Dean Camera

prophet36
Very interested
Posts: 234
Joined: Sat Dec 13, 2008 6:58 pm
Location: London, UK
Contact:

Post by prophet36 » Thu Dec 18, 2008 9:46 pm

Update...I've got my menu system working. I used Stef's devkit, and I'm very impressed with how easy it is to use. From never having written any MegaDrive code, to having a working menu only took a couple of hours. Here's the menu image. It will run on an emulator OK, but the ROM select logic uses the scheme I referred to earlier. When you press the Start button on the controller, the menu system writes details of your choice to the cartridge address space. On an emulator, this write will just be ignored. But on my hardware, the write raises an interrupt in the AVR. It then puts the MegaDrive back in RESET, reads the data written by the MegaDrive, loads the appropriate ROM image from the SD card, and boots the MegaDrive once more. I have tried it with a selection of ROMs and it works fine in this standalone mode. The code is very messy and inefficient at the moment and is badly in need of a bit of refactoring but when it's done I'll post everything up for people to look at.

@Dean: thanks mate, but I would never have even attempted to put USB on it if it weren't for all the hard work you put into MyUSB/LUFA!

@Will: yeah I was hoping for something a bit more performant than an I2C connection. For example, 8MHz is the maximum rate I can clock the SPI bus to the SD card, and it is a severely limiting factor in performance. What I would like is a bidirectional FIFO between the AVR and 68K, but such a thing implies an FPGA or at least a CPLD, and there are a few problems there (those already mentioned by Graz, and the eye-straining 0.5mm lead pitch of PQFP FPGAs).

vBLANK
Newbie
Posts: 2
Joined: Mon Dec 15, 2008 2:27 pm
Location: Philadelphia
Contact:

Post by vBLANK » Fri Dec 19, 2008 12:48 am

I forgot how slow my project work goes during the holiday season!

You've done quite an amazing bit here!
Is the AVR handling the roms on a FAT16? or did you create a simple file system on the SD? Between that and the menu parsing, and the file moving on interrupt, you must be running out of space on the AVR to do more tricks with outboard devices!

Perhaps it's time to start looking at the MD's side port for wide bandwidth accessory services. What you have here is already a pretty serious DEV system.

I'll keep an eye out when you're ready to release. This looks like great stuff! I'll spend my while-time warming up on the 68k code.

-Wil

prophet36
Very interested
Posts: 234
Joined: Sat Dec 13, 2008 6:58 pm
Location: London, UK
Contact:

Post by prophet36 » Fri Dec 19, 2008 12:56 am

It's actually FAT32...I couldn't be bothered to implement FAT16 because it doesn't scale well to very large disks (for other projects). I don't have write support or long filenames working yet, which makes the menu a bit crap. But the AVR I use is quite nice...64k of flash, 4k onboard SRAM, loads of I/O, USB interface, external memory interface etc etc.

prophet36
Very interested
Posts: 234
Joined: Sat Dec 13, 2008 6:58 pm
Location: London, UK
Contact:

Update...

Post by prophet36 » Fri Jun 12, 2009 1:16 am

Hi guys,

Kaneda PM'd me to ask whether I'm still working on this project. The answer is yes, but following suggestions made by Graz I am redesigning it with an FPGA and an 8Mbyte SDRAM chip instead of the two 512kbyte SRAM chips.

This has been taking longer than I'd like; I've been busy with other stuff, but I hope to be able to get v2 working in the next few weeks.

Why redesign it? Well...
  1. v1 is pretty slow. It takes 10-15 seconds to load a 1Mb game.
  2. There is no possibility of bidirectional communication between the 68000 and the AVR.
  3. As a game is loading, the MegaDrive is held in RESET, so the screen is blank...I'd like a progress bar.
Why is v1 so slow? I believe v1 is slow because of a combination of factors. The SD card is clocked by the microcontroller's SPI port, which runs at 8MHz. Since SPI is serial, that means it has a theoretical maximum bandwidth of 1Mbyte/s. But then there's my implementation of FAT32 which I originally wrote optimised for space (for a microcontroller with only 512 bytes of RAM!), so it needs to be optimised for speed. Then there's all the bank-switching (the AVR accesses the cartridge SRAM in blocks of 32kbytes). Then there's my CRC routine to verify the data. All that is implemented in C and compiled for the 8-bit AVR. I doubt the compiler has generated particularly optimal AVR code.

Obviously I can optimise it a bit, but as Graz mentioned, it would make more sense to implement all the peripherals (e.g SPI) in an FPGA and have the 68000 do all the heavy lifting. That means I can clock the SD card at 24MHz instead of 8MHz, giving a theoretical throughput of 3Mbyte/s. And the loader code would be simpler and more easily optimised running on the 68000. Unfortunately I'm not too familiar with FPGAs so I'm still learning.

In the end I hope to be able to make a small and neat card with a throughput of about 2Mbyte/s loading from an SD card, and about 400kbyte/s loading from USB via Dean's LUFA library (I could get more throughput if I used a Hi-Speed USB device, but I have no experience there).

I guess so far I've been concentrating on getting games loaded from SD card (not exactly DevKit functionality!), but with the v2 architecture it should be possible to implement a USB-based debugger where you can stop a game as it's running, save its state, examine the memory and the registers, step through the code, set breakpoints, etc.

Anyway, in the meantime, I've gathered all the stuff for v1 together and published it here: http://www.makestuff.eu/umdkv1/umdk.tar.gz. Apologies about the state of the code and design. I don't see much point tidying it up because v2 is more or less a complete redesign. I consider v1 to be a dead-end, but if someone wants to build one I'm happy to help.

- Chris

prophet36
Very interested
Posts: 234
Joined: Sat Dec 13, 2008 6:58 pm
Location: London, UK
Contact:

Progress!

Post by prophet36 » Sun Apr 03, 2011 2:29 pm

I got fed up with not having enough time to work on my own projects, so I quit my job :D

Consequently, I've actually been making some good progress on this. If anyone's still interested in this, you can look here for details:

http://www.makestuff.eu/wordpress/?p=1431

I'd quite like some ideas about stuff people would like to see in a cartridge like this. Game saves to SD-card perhaps? Is there a standard way that games implement saves?

Also I'd like some guidance about choice of address-space regions. I chose to put I/O at 0xA13000 and the monitor code at 0x400000, where it will probably clash with something. My hardware currently does no /DTACK generation which might be a good idea, so I can put the monitor somewhere else.

Chilly Willy
Very interested
Posts: 2816
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Sun Apr 03, 2011 6:44 pm

Very interesting proto board...

At $400000, you'll clash with a SCD; with a cart in the slot, 0 - 4M is for the cart, 4 - 8 is for the CD, and 8 - A is for the 32X. With no cart in the slot, the first two flip with the SCD being 0 - 4, and the cart being 4 - 8 (which is what the CD BRAM cart uses).

Game saves are simply the sram data with the even bytes tossed (since sram only exists on the odd bytes).

prophet36
Very interested
Posts: 234
Joined: Sat Dec 13, 2008 6:58 pm
Location: London, UK
Contact:

Post by prophet36 » Sun Apr 03, 2011 7:21 pm

Assuming I add /DTACK generation, are there any "safe" areas I can use? What about the $C00000 - $FEFFFF range? In theory I could get away with a small area (the monitor/menu program will probably only be a few kilobytes, and I can address the rest of my spare 4Mbyte RAM indirectly with some sort of autoincrement pointers mapped into I/O).

So games with save features write stuff somewhere in the $000000 - $3fffff range? I can easily keep track of any writes to that range (e.g remember the lowest and highest addresses written to) and give the option to write a file to the SD card when reset is pressed.

What about dev tools? I'd like to try to get some sort of EclipseIDE debugger integration working. Doing it with handwritten assembler should be straightforward but making it work with the line-number back-annotations GCC spits out would probably be tricky.

Chilly Willy
Very interested
Posts: 2816
Joined: Fri Aug 17, 2007 9:33 pm

Post by Chilly Willy » Sun Apr 03, 2011 11:45 pm

prophet36 wrote:Assuming I add /DTACK generation, are there any "safe" areas I can use? What about the $C00000 - $FEFFFF range? In theory I could get away with a small area (the monitor/menu program will probably only be a few kilobytes, and I can address the rest of my spare 4Mbyte RAM indirectly with some sort of autoincrement pointers mapped into I/O).
$000000 - $3FFFFF is cart or cd
$400000 - $7FFFFF is cd or cart (the two swap based on if the /CART line is asserted)
$800000 - $9FFFFF is 32X
$A00000 - $BFFFFF is IO
$C00000 - $DFFFFF is VDP
$E00000 - $FFFFFF is WRAM

There's lots of room for things in those ranges, but you'd need to do your own decoding and /DTACK generation.

So games with save features write stuff somewhere in the $000000 - $3fffff range? I can easily keep track of any writes to that range (e.g remember the lowest and highest addresses written to) and give the option to write a file to the SD card when reset is pressed.
Save RAM is nearly always at $200000. It can be enabled/disabled by writing $A130F1 for carts with sram that are bigger than 2MBytes.

What about dev tools? I'd like to try to get some sort of EclipseIDE debugger integration working. Doing it with handwritten assembler should be straightforward but making it work with the line-number back-annotations GCC spits out would probably be tricky.
There's really nothing like that. I use logging to the screen for all my debugging. You could also log to the save ram for cases where you didn't wish to disturb the video. You would then dump the save ram and look at the data to see how far you got.

KRIKzz
Interested
Posts: 20
Joined: Wed Jul 22, 2009 11:25 am
Location: Ukraine
Contact:

Post by KRIKzz » Tue Jun 28, 2011 5:22 pm

prophet36 i wonder if your memory controller enough fast for 32x? while ago i used altera DE1 for build similar thing, genesis games works fine, but 32x unfortunately not. i tried to count write/read period for 32x and looks like 32x has twice more fast r/w timings than genesis dma. my first sdram controller was too slow even for genesis dma, so any attempts to use dma was failed (just glitches on the screen instead of graphics). currently my controller enough fast for genny dma, but just bit more fast than req by dma, so if so if few Mhz down, then i will back to glitches world :D

Post Reply