Skip to content

Getting Started

Chris McClelland edited this page Mar 25, 2017 · 7 revisions

STEP 0: Preparation

Unless you know what you're doing, you should test your new UMDK cart using a recent x86 or x64 Linux installation, on "real" (as opposed to virtual, e.g on VMware or VirtualBox) x86 or x64 hardware. The software will build and function correctly on MacOSX or Windows, or even on a Raspberry Pi, but whilst we're getting everyone up and running it makes sense to minimize the number of configurations being used.

So, you will need:

  • A PC with a spare USB port and an Internet connection
  • A recent Linux installation, x86 or x64 (amd64)
  • A digital multimeter, for verifying voltage levels
  • Four jumpers, for selecting options on the boards
  • A good solid block of time to run through the test and install process
  • Patience!

Now we can split into two groups:

  • If you built your own UMDK cart, or bought it direct from a manufacturer, you're in group A
  • If you bought your UMDK from a member of the SpritesMind community, you're in group B

Got all that? Great! Let's go!

STEP 1: System Setup

First, make sure sudo works:

$ sudo ls
[sudo] password for <user>: *********
:
$

If it fails, you'll need to find out how to enable sudo on your particular Linux distro. Ubuntu normally has it pre-installed; on Debian you'll need to do apt-get install sudo as root and then add yourself to the sudo group; on Fedora you'll need to add yourself to the wheel group. Google is your friend.

Next, if you want to use the DDD debugger front-end, you'll have to install it. Again, this will depend on your OS, but it'll probably be something like sudo apt-get install ddd or sudo yum install ddd.

Next, entitlements. Since Linux is a multiuser OS, ordinary users are by default not allowed to access USB devices, so you must explicitly grant specific users or groups access to specific devices. This is achieved by means of a new udev rule. First, find out which groups you're in, and choose one to use in the udev rule:

$ groups
users cdrom floppy sudo audio dip video plugdev netdev lpadmin scanner vboxusers
$

I'm going to choose the users group for this example udev rule. As root, create a file /etc/udev/rules.d/10-umdkv2.rules, containing these two lines:

ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="04b4", ATTR{idProduct}=="8613", GROUP="users", MODE="0660"
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="1d50", ATTR{idProduct}=="602b", GROUP="users", MODE="0660"

That instructs the system to detect when a UMDK cart is added to the system, and allow access to members of the users group. Without this rule, you'd have to run all the UMDK software as root, which would be a bit rubbish.

Lastly, if you're in Group A, you'll need to blacklist the usbtest kernel module. As root, create a file /etc/modprobe.d/usbtest.conf, containing this line:

blacklist usbtest

Finally, reboot your computer to force your changes to take effect.

STEP 2: Software Installation

For x86:

cd ${HOME}
wget -qO- http://tiny.cc/umdk-lx86-20151220 | tar zxf -
wget -qO- http://tiny.cc/xtools-lx86-20151220 | tar zxf -

And for x64:

cd ${HOME}
wget -qO- http://tiny.cc/umdk-lx64-20151220 | tar zxf -
wget -qO- http://tiny.cc/xtools-lx64-20151220 | tar zxf -

This will create two directories:

  • The umdkv2-bin directory contains the UMDK tools
  • The x-tools directory contains the 68000 assembler, GCC compiler and GDB debugger

You can add these two directories to your system PATH like this:

export PATH=${HOME}/umdkv2-bin:${HOME}/x-tools/m68k-megadrive-elf/bin:${PATH}

You will probably want to add that line to your profile (e.g add it to ${HOME}/.bashrc), so you don't have to type it in every time you open a new terminal window.

STEP 3: Verify Voltages

If you're in Group B, you can skip forward to Step 7.

With no jumpers populated, connect the LX9 board to one of your computer's USB sockets, and using your multimeter, verify that the voltage on J4's top pin is close to 5.0V. You can use the row of GNDs at the bottom as a reference point:

Next, with J4 set to USB (i.e a jumper shorting the top two pins on J4), verify that the output of REG3.3 is not significantly less than 3.3V (sorry, crappy photo):

Next, with J2 populated, verify that the output of REG1.2 is not significantly less than 1.2V:

All correct? Great! Next we'll start loading the firmware and testing the LX9 board.

STEP 4: LX9 Hardware Tests

First, check that the USB cable is unplugged, the bridge board is disconnected and that the jumper settings are correct (J4 in USB mode, J2 populated):

Now, tail the system log:

$ sudo tail -f /var/log/messages
:

...and then connect the USB cable. You should see something similar to this:

$ sudo tail -f /var/log/messages
Nov 22 12:06:00 wotan kernel: [84365.200518] usb 2-1.2: new high-speed USB device number 20 using ehci-pci
Nov 22 12:06:00 wotan kernel: [84365.292631] usb 2-1.2: New USB device found, idVendor=04b4, idProduct=8613
Nov 22 12:06:00 wotan kernel: [84365.292644] usb 2-1.2: New USB device strings: Mfr=0, Product=0, SerialNumber=0
Nov 22 12:06:00 wotan mtp-probe: checking bus 2, device 20: "/sys/devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.2"
Nov 22 12:06:00 wotan mtp-probe: bus: 2, device: 20 was not an MTP device

Hit Ctrl-C and list the USB devices:

$ lsusb | grep 04b4
Bus 002 Device 020: ID 04b4:8613 Cypress Semiconductor Corp. CY7C68013 EZ-USB FX2 USB 2.0 Development Kit
$

This means that the FX2 microcontroller on the LX9 board is enumerating correctly, and is cause for a minor celebration.

Next, load the FPGALink firmware into the FX2 microcontroller's RAM, using the flcli utility:

$ flcli -i 04b4:8613 -v 1d50:602b
Attempting to open connection to FPGALink device 1d50:602b...
Loading firmware into 04b4:8613...
Awaiting renumeration.....
Attempting to open connection to FPGLink device 1d50:602b again...
Connected to FPGALink device 1d50:602b (firmwareID: 0xFFFF, firmwareVersion: 0x20140311)
$

Now, leaving the USB cable connected, add a jumper to J1:

Now load the FPGALink firmware into the FX2's EEPROM:

$ flcli -v 1d50:602b --eeprom=std
Attempting to open connection to FPGALink device 1d50:602b...
Connected to FPGALink device 1d50:602b (firmwareID: 0xFFFF, firmwareVersion: 0x20140311)
Writing the standard FPGALink firmware to the FX2's EEPROM...
$

Now disconnect and reconnect the USB cable, and verify that the FX2 boots correctly from EEPROM:

$ flcli -v 1d50:602b
Attempting to open connection to FPGALink device 1d50:602b...
Connected to FPGALink device 1d50:602b (firmwareID: 0xFFFF, firmwareVersion: 0x20140311)
$

Now scan the JTAG chain, to verify that the FPGA is present:

$ flcli -v 1d50:602b -q A7A0A3A1
Attempting to open connection to FPGALink device 1d50:602b...
Connected to FPGALink device 1d50:602b (firmwareID: 0xFFFF, firmwareVersion: 0x20140311)
The FPGALink device at 1d50:602b scanned its JTAG chain, yielding:
  0x24001093
$

Now program the FPGA with cksum.xsvf:

$ flcli -v 1d50:602b -p J:A7A0A3A1:${HOME}/umdkv2-bin/cksum.xsvf
Attempting to open connection to FPGALink device 1d50:602b...
Connected to FPGALink device 1d50:602b (firmwareID: 0xFFFF, firmwareVersion: 0x20140311)
Programming device...
$

Next, write 512KiB of random data to the FPGA, and compare the FPGA-calculated and CPU-calculated checksums:

$ cd ${HOME}
$ dd if=/dev/urandom of=random.bin bs=1024 count=512
512+0 records in
512+0 records out
524288 bytes (524 kB) copied, 0.0650854 s, 8.1 MB/s
$ flcli -v 1d50:602b -a 'w0 "random.bin";r1;r2' -b
Attempting to open connection to FPGALink device 1d50:602b...
Connected to FPGALink device 1d50:602b (firmwareID: 0xFFFF, firmwareVersion: 0x20140311)
Executing CommFPGA actions on FPGALink device 1d50:602b...
Wrote 524288 bytes (checksum 0xA8D2) to channel 0 at 41.722296 MiB/s
Read 1 bytes (checksum 0x00A8) from channel 1 at 0.019463 MiB/s
Read 1 bytes (checksum 0x00D2) from channel 2 at 0.008913 MiB/s
     00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
0000 A8 D2                                           ..

Note that in this case the CPU-calculated checksum is 0xA8D2 and the FPGA-calculated checksum is A8 D2. The actual checksum you get will almost certainly differ. The actual value you get doesn't matter; the important thing is that the CPU and FPGA both calculate the same checksum value.

Before we move on, make a note of your measured USB throughput figure. Mine is 41.722296 MiB/s. If you get something significantly less than that, try again with different USB ports and different USB cables, to see if that gets you closer to 40MiB/s. A slow USB link is an early-warning sign that UMDK's instruction-tracing capability may not work reliably for you.

Now, let's see if the FPGA's flash works OK. Program the FPGA with spi-talk.xsvf, then use the gordon tool (flash gordon, geddit?) to write our 512KiB of random data to the FPGA's flash, then read it back and compare:

$ flcli -v 1d50:602b -p J:A7A0A3A1:${HOME}/umdkv2-bin/spi-talk.xsvf
Attempting to open connection to FPGALink device 1d50:602b...
Connected to FPGALink device 1d50:602b (firmwareID: 0xFFFF, firmwareVersion: 0x20140311)
Programming device...
$ gordon -v 1d50:602b -t indirect:1 -w random.bin:0
Device: Micron/Numonyx/ST M25P40
Writing 0x00080000 bytes to address 0x00000000...
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................

$ gordon -v 1d50:602b -t indirect:1 -r out.bin:0:0x80000
Device: Micron/Numonyx/ST M25P40
Reading 0x00080000 bytes from address 0x00000000...
$ cmp random.bin out.bin
$

Now let's see if the FPGA will boot OK from its flash. First, write the cksum.bin file to the flash:

$ gordon -v 1d50:602b -t indirect:1 -w ${HOME}/umdkv2-bin/cksum.bin:0
Device: Micron/Numonyx/ST M25P40
Writing 0x0005327C bytes to address 0x00000000...
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
...................................................
$

Then disconnect and reconnect the USB cable, to force the FX2 and the FPGA to boot from their respective nonvolatile memories. We can verify by re-running the earlier flcli command:

$ flcli -v 1d50:602b -a 'w0 "random.bin";r1;r2' -b
Attempting to open connection to FPGALink device 1d50:602b...
Connected to FPGALink device 1d50:602b (firmwareID: 0xFFFF, firmwareVersion: 0x20140311)
Executing CommFPGA actions on FPGALink device 1d50:602b...
Wrote 524288 bytes (checksum 0xA8D2) to channel 0 at 41.618112 MiB/s
Read 1 bytes (checksum 0x00A8) from channel 1 at 0.004541 MiB/s
Read 1 bytes (checksum 0x00D2) from channel 2 at 0.016731 MiB/s
     00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
0000 A8 D2                                           ..
$

Now let's test the SDRAM. Program the FPGA with readback.xsvf, then write 16MiB of random data to the SDRAM, read it back and compare:

$ flcli -v 1d50:602b -p J:A7A0A3A1:${HOME}/umdkv2-bin/readback.xsvf
Attempting to open connection to FPGALink device 1d50:602b...
Connected to FPGALink device 1d50:602b (firmwareID: 0xFFFF, firmwareVersion: 0x20140311)
Programming device...
$ dd if=/dev/urandom of=random.bin bs=1M count=16
16+0 records in
16+0 records out
16777216 bytes (17 MB) copied, 1.07856 s, 15.6 MB/s
$ flcli -v 1d50:602b -a 'w0 0000000080800000;w0 "random.bin"'
Attempting to open connection to FPGALink device 1d50:602b...
Connected to FPGALink device 1d50:602b (firmwareID: 0xFFFF, firmwareVersion: 0x20140311)
Executing CommFPGA actions on FPGALink device 1d50:602b...
$ flcli -v 1d50:602b -a 'w0 0000000040800000;r0 1000000 "out.bin"'
Attempting to open connection to FPGALink device 1d50:602b...
Connected to FPGALink device 1d50:602b (firmwareID: 0xFFFF, firmwareVersion: 0x20140311)
Executing CommFPGA actions on FPGALink device 1d50:602b...
$ cmp random.bin out.bin
$

If you've got this far, congratulations. Your LX9 board has passed all the basic functional tests. The next step is to connect it to the UMDK bridge-board and plug it into your MegaDrive for the first time!

Step 5: Basic MegaDrive Tests

Start with the jumper configuration we ended up with in step 4:

Now use spi-talk.xsvf to write 512KiB of random data to the FPGA's flash again like we did in the middle of step 4 (we'll be reading it back and verifying later).

$ cd ${HOME}
$ dd if=/dev/urandom of=random.bin bs=1024 count=512
512+0 records in
512+0 records out
524288 bytes (524 kB) copied, 0.0650854 s, 8.1 MB/s
$ flcli -v 1d50:602b -p J:A7A0A3A1:${HOME}/umdkv2-bin/spi-talk.xsvf
Attempting to open connection to FPGALink device 1d50:602b...
Connected to FPGALink device 1d50:602b (firmwareID: 0xFFFF, firmwareVersion: 0x20140311)
Programming device...
$ gordon -v 1d50:602b -t indirect:1 -w random.bin:0
Device: Micron/Numonyx/ST M25P40
Writing 0x00080000 bytes to address 0x00000000...
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................

$ 

Now, disconnect the USB cable and carefully attach the bridge-board, ensuring you have the correct orientation. Then move the jumper at J4 to select EXT mode, and populate J3. Your boards should now look like this:

In this configuration, the LX9 is configured to get its 5V power from the MegaDrive, and to supply 3.3V power from REG3.3 to the bridge-board.

Now plug your UMDK cart into your MegaDrive, again making sure you have the correct orientation. It's safest to actually put the cart into a standard-sized game-cart enclosure - you'll need to use a file to cut a thin slot in the top of the plastic enclosure for this. If you don't care about the enclosure, just make sure you have the cartridge's orientation correct - from the front of the MegaDrive, you should see the FPGA, but the SD-Card slot should not be visible:

When you turn on your MegaDrive, it will be held in reset by the (uninitialised) FPGA, so you'll see a blank screen. We can now run some basic tests to verify that the MegaDrive can access the UMDK cart correctly.

First, a basic signal test:

$ flcli -v 1d50:602b -p J:A7A0A3A1:${HOME}/umdkv2-bin/fpga-test.xsvf
Attempting to open connection to FPGALink device 1d50:602b...
Connected to FPGALink device 1d50:602b (firmwareID: 0xFFFF, firmwareVersion: 0x20140311)
Programming device...
$ wget -qO- http://tiny.cc/umdk-sigtest | bunzip2 > sigtest.bin
$ loader -w sigtest.bin:0 -x 2 -t trace.bin:2048
UMDKv2 Loader Copyright (C) 2014 Chris McClelland

Putting MD in reset...
Writing SDRAM...
Releasing MD from reset...
Dumping execution trace to trace.bin:2048
................................................................
................................................................
................................................................
................................................................
Finished!
$ logread trace.bin | grep -v HEARTBEAT | head -8388250 | awk '{print $2$3$4$5}' > result.txt
$ md5sum result.txt
d5a670db486de8597e214c6849fdfacb  result.txt
$ 

The resulting MD5 should be d5a670db486de8597e214c6849fdfacb. If you get something else, then fetch the expected trace output and compare it with yours:

$ wget -qO- http://tiny.cc/umdk-expected | bunzip2 > expected.txt
$ diff expected.txt result.txt | less

This should help you determine what happened.

The sigtest.bin file is just a big 8MiB blob of 68000 machine-code, without branches:

$ dis68 sigtest.bin 8 8
0x000008  move.w #21845, d0
0x00000C  move.w #-21846, d1
0x000010  lea 0xFF0000, a0
0x000016  move.w d0, (a0)+
0x000018  move.w d0, (a0)+
0x00001A  move.w d0, (a0)+
0x00001C  move.w d0, (a0)+
0x00001E  move.w d0, (a0)+
$

It first loads D0 with 0x5555 and D1 with 0xAAAA, then points A0 at the bottom of WRAM, and then proceeds to save D0 to WRAM 32768 times using an A0 postincrement. Then it resets A0 back to the bottom of WRAM and repeats, this time saving D1:

$ dis68 sigtest.bin 0x010012 8
0x010012  move.w d0, (a0)+
0x010014  move.w d0, (a0)+
0x010016  lea 0xFF0000, a0
0x01001C  move.w d1, (a0)+
0x01001E  move.w d1, (a0)+
0x010020  move.w d1, (a0)+
0x010022  move.w d1, (a0)+
0x010024  move.w d1, (a0)+
$

It proceeds like this, alternating between writing 0x5555 and then 0xAAAA to WRAM, until it reaches the very top of the 8MiB cartridge address-space, where it ends up in an infinite loop:

$ dis68 sigtest.bin 0x7FFFEE 8
0x7FFFEE  move.w d1, (a0)+
0x7FFFF0  move.w d1, (a0)+
0x7FFFF2  move.w d1, (a0)+
0x7FFFF4  move.w d1, (a0)+
0x7FFFF6  move.w d1, (a0)+
0x7FFFF8  move.w d1, (a0)+
0x7FFFFA  move.w d1, (a0)+
0x7FFFFC  bra.s 0x7FFFFC
$ 

Armed with this information, the differences between your result.txt and the expected.txt should give you some hints as to what's wrong. It's likely to be a solder bridge between two pins, or a dry solder-joint somewhere. If you have trouble making deductions from the trace logs, run bzip2 result.txt to compress your file and upload it to DropBox or similar, and post a link to the forum asking for help.

Next, a flash readback test:

$ flcli -v 1d50:602b -p J:A7A0A3A1:${HOME}/umdkv2-bin/fpga-test.xsvf
Attempting to open connection to FPGALink device 1d50:602b...
Connected to FPGALink device 1d50:602b (firmwareID: 0xFFFF, firmwareVersion: 0x20140311)
Programming device...
$ wget -qO flashtest.bin http://tiny.cc/umdk-flashtest
$ loader -w flashtest.bin:0 -x 2
UMDKv2 Loader Copyright (C) 2014 Chris McClelland

Putting MD in reset...
Writing SDRAM...
Releasing MD from reset...
$ 

Wait a few seconds for the flash readback to complete, then:

$ loader -r readback.bin:0x400000:0x80000
UMDKv2 Loader Copyright (C) 2014 Chris McClelland

Reading SDRAM...
$ cmp readback.bin random.bin 
$ 

The purpose of this test is to ensure that the MegaDrive can read the contents of the UMDK's onboard flash chip. It does this by reading all 512KiB from flash, and copying it into SDRAM in the 0x400000-0x47FFFF range, where it can be later read back over USB.

If the cmp command returns an error like "readback.bin random.bin differ: byte 1234, line 123", then the test has failed. Try running the test again, this time returning a trace log:

loader -w flashtest.bin:0 -x 2 -t trace.log:512

You can then grep the resulting trace log to see what values are actually written to the 0x400000-0x47FFFF range:

logread trace.log | grep " WB 4" | less

Step 6: Install UMDK Production Firmware

Now use spi-talk.xsvf to write fpga-prod.bin to the bottom of the flash. This is the thing that actually implements the UMDKv2's digital electronics in the FPGA:

$ flcli -v 1d50:602b -p J:A7A0A3A1:${HOME}/umdkv2-bin/spi-talk.xsvf
Attempting to open connection to FPGALink device 1d50:602b...
Connected to FPGALink device 1d50:602b (firmwareID: 0xFFFF, firmwareVersion: 0x20140311)
Programming device...
$ gordon -v 1d50:602b -t indirect:1 -w ${HOME}/umdkv2-bin/fpga-prod.bin:0
Device: Micron/Numonyx/ST M25P40
Writing 0x0005327C bytes to address 0x00000000...
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
................................................................
...................................................
$

Next, write firmware.bin to address 0x60000 of the flash. This contains the 2nd-stage bootloader, the machine-code monitor and the menu program:

$ gordon -v 1d50:602b -t indirect:1 -w ${HOME}/umdkv2-bin/firmware.bin:0x60000
Device: Micron/Numonyx/ST M25P40
Writing 0x0000C454 bytes to address 0x00060000...
................................................................
................................................................
................................................................
.....
$

Step 7: Boot Menu Program

If you're in Group B and have skipped forward, you will probably need to connect the LX9 board to the UMDK bridge-board, and plug the pair into your MegaDrive for the first time. First, carefully attach the bridge-board, ensuring you have the correct orientation and jumper configuration as shown below:

Now plug your UMDK cart into your MegaDrive, again making sure you have the correct orientation. It's safest to actually put the cart into a standard-sized game-cart enclosure - you'll need to use a file to cut a thin slot in the top of the plastic enclosure for this. If you don't care about the enclosure, just make sure you have the cartridge's orientation correct - from the front of the MegaDrive, you should see the FPGA, but the SD-Card slot should not be visible:

When you power up the MegaDrive, you should see "MakeStuff USB MegaDrive Devkit v2" on the screen. Plug in a FAT32-formatted SD-Card (2GB or smaller) with a bunch of .bin game images, and you should be able to use controller 1 to select and play one of them.

You can also load a .bin game over USB using the loader utility:

loader -w sonic.bin:0 -x 2

When connected to your PC via USB, the debugger tools I demonstrated in the videos should also work. For example, you can build a debug version of the menu program like this:

cd ${HOME}
mkdir 20151220
cd 20151220
wget -qO- http://tiny.cc/msbil | tar zxf -
cd makestuff
scripts/msget.sh makestuff/hdlmake/20151220
cd hdlmake/apps
mkdir makestuff
cd makestuff
../../../scripts/msget.sh makestuff/umdkv2
cd umdkv2/scripts
./build-sgdk.sh
cd ../m68k/menu
./dbg.sh

Now in one terminal window, run gdb-bridge:

$ gdb-bridge -l 8000
UMDKv2 Bridge Tool Copyright (C) 2014 Chris McClelland

Waiting for GDB connection on :8000

...and in another terminal window, start DDD:

$ cd ${HOME}/20151220/makestuff/hdlmake/apps/makestuff/umdkv2/m68k/menu
$ ../../scripts/ddd.sh 8000 menu.elf

...whereupon DDD should startup, awaiting your instructions:

Happy hacking!

You can’t perform that action at this time.