Last night i had a long debug session with Max and we tried to track down the problem with the prototype board.The problem is that some homebrew roms are runinng fine, but most commerical games don’t even start. I can start up the game “Mr. Do”, but it hangs directly at the first intro screen.
So we investigated this. We went thru all logic step involving setting up our hardware. Double checked all IO Ports and Input/Output behaviour. Re-wrote all our setup routines and switching functions, like Lo/Hi rom switching and bus driver switching. Did memory pattern checking from the AVR and the SNES side. Added extra delays to critical area and double checked all IO line on the board. And guess what. Still the same problem. Nearly everything crashes.
So here are the news, we figured out as soon as a rom start music its crashes. So all homebrew stuff without SPC stuff works fine. But can’t get any homebrew or commerical stuff running thats uses sound. I don’t have any deep knowledge about the sound sub system of the SNES. I only know its co-processor called SPC, it gets his IPL from the SNES and it has to be setup with code/music via a dedicated 8bit data port. So i assume there is no direct rom access from the SPC to the cartridge. So why is his a problem on our prototype board. We never had this kind of problem with the proof of concept board.
Last options we are thinking are: We either have a problem with the SRAM timings, since we use faster SRAM on the prototype board. The proof of concept board used 70ns SRAMs, now we are running 50ns. Or the capacitors on the SRAMs are to small. I would appreciate if anybody reading this have experienced same problems or knows what causing this problem could leave me a comment or contact me on #snesdev.
The last 2 nights i spend some time debugging the firmware of the prototype board. I added CRC checks for the sram areas and each uploaded bank. Hence i can push roms to the sram and verify it at runtime on both sides. So i can see if there are any transfer errors. Iam not using any CRC checks on USB layer, because the VUSB lib only supports this for 18MHz driven mcpus and we use 20MHz. This why i have to do it by ‘hand’ later after a block/bank is upoaded.
Also i switched the SRAM addressing mode to the faster counter based version. This boosted the upload speed by a great magnitude. I guess there is more room for optimization, but right now its quite fast to upload a rom. Like 2 seconds for a 32kb LOROM bank. So just a few seconds for a 4mbit game.
I know that USB could do much faster, but there are limits to the USB lib we are using. The client side allows only transfer up to 254 for each call. Minus the protocol overhead. Also the host side runs in user mode and can’t be compared to a kernel module performance. USB Transfer is realized thru callback in the firmware. Right now an 128 Bytes data transfer is splitted into 16 times 8 bytes payload callbacks. So i got a huge accumulated function overhead with this. Either i have to optimize this callback behavior or do it in ASM to squeeze out some cycles.
There a little downside right now. I can’t get commerical roms working. Iam able to upload and run homebrew stuff, but games doesn’t seem to boot. Sometime i have weird crashes in homebrew stuff.
I can assume that our attached CRC chip is working, because i made it into the start screen of Mr.Do, but Super Mario World doesn’t even show up the Nintendo start logo. I guess there is something wrong with the our HI/LOROM or WR Enable switching logic. Have to investigate this….
Last night we spend atleast 3 hours to track down a little bug in the cpu fuse settings. After running first tests on the hardware we got debug uart and some basic sreg addressing working.
Then we started to implement a sram read/write round trip. We found out that we read for all sram cells the same value as the last value which was written. So we stepped through the schematics and traced all IO lines and logic involved in the sram addressing process. First we analysed the sreg setup and the address counters. Then we checked the busdriver and the sram multiplexer. But this looked all out. Finally we found the problm that the WR line from the AVR to the sram is not pulled high when set in software.
So we looked for shortcircuits but didn’t find anything. Last guess was the mcu is broken, but finally we found out that we had a false fuse setting. So our IO pin was configured to passthru the clock signal on that pin. Fixed that and so basic sram read/write is working.
Tonite we gonna test bulk transfer. Hopefully this time we don’t have so nasty bugs.
These two pictures show the different functional blocks of the prototype design. On the top side you have the MCU and next to it the connector for In-System-Programming and the MMC/SD daughter board. The yellow block marks the usb hardware for emulated software-usb on the mcu, the green block is the ram section. The orange block on top, right under the cart edge connector marks the bus transceivers to connect or disconnect the snes to the ram interface. The blue block overlays the transceiver for data access to the ram from the mcu side. The logic gates are for lo-/hiram switching and to disable write access to the ram section from the snes side.
On the bottom side you have a socket for the cic-lockout chip and the rest of the bus transceivers to connect or disconnect the snes. In the lower half you have shift registers to preset a certain adress to the adress counters. These counters are connected to the ram via bus transceivers, so you can access large memory with only a few io-pins on the mcu side. The red block is a demultiplexer to distribute the 22bit adresses to the 19 bit adresses of the ram ics.
Finally assembled and the pcb powers up. So iam posting a few more details photos. The boards powers up and the FTDI can be accessed via usb. So tomorrow i gonna meet with max and we will port the old firmware from the mega16 to the mega644. Tomorrow we might have simple usb based uploader working.
This monday morning the long awaited first prototype PCB arrived from pcb-pool. We had a little UPS problem on friday, so we had to wait till monday to get the PCB. Max just started to solder all the chips, looking forward to get a working usb uploader firmware running till the next weekend.
I think the PCB looks really good and iam looking forward to power it up soon…
Got an mail from pcb-pool.de, our PCB is nearly done and will arrive this week. So the first prototype will be assembled over the weekend. Keep fingers crossed that everything is working as planed.
Quick Featuers list
Things not happping with this version
Yesterday i learnt from Lint that there is a new Snes toolchain coming down. The Project can be found herehttp://code.google.com/p/snes-sdk/. Right now i have it running under linux. Just working on a patch for os x. Thumbs up to Ulrich Hecht for his work on this project.
Features:
Project layout
david@slap:[~/Devel/arch...h/snes/snes-sdk]$ ls -l total 40 drwxr-xr-x 2 david david 4096 2009-04-27 13:52 bin/ drwxr-xr-x 3 david david 4096 2009-04-27 14:04 libs/ -rw-r--r-- 1 david david 1387 2009-04-27 13:59 Makefile drwxr-xr-x 11 david david 4096 2009-04-27 14:01 snes9x/ drwxr-xr-x 3 david david 4096 2009-04-28 09:29 snesc/ drwxr-xr-x 7 david david 4096 2009-04-27 14:14 tcc-65816/ -rw-r--r-- 1 david david 11304 2009-04-27 13:24 TODO drwxr-xr-x 16 david david 4096 2009-04-27 13:59 wla_dx/
Libc
-rw-r--r-- 1 david david 7946 2009-04-27 13:23 crt0_snes.asm -rw-r--r-- 1 david david 6096 2009-04-27 13:59 crt0_snes.obj -rw-r--r-- 1 david david 1755 2009-04-27 14:04 hdr.asm -rw-r--r-- 1 david david 7108 2009-04-27 13:23 libc.asm -rw-r--r-- 1 david david 12160 2009-04-27 13:59 libc.obj -rw-r--r-- 1 david david 11087 2009-04-27 13:23 libm.asm -rw-r--r-- 1 david david 14670 2009-04-27 13:59 libm.obj -rw-r--r-- 1 david david 6051 2009-04-27 13:23 libtcc.asm -rw-r--r-- 1 david david 10101 2009-04-27 13:59 libtcc.obj -rw-r--r-- 1 david david 132 2009-04-27 13:46 Makefile drwxr-xr-x 6 david david 4096 2009-04-27 13:24 .svn/
Compile run of the demo game
rm -f snesc.smc snesc.sym data.obj graph_asm.obj str.obj snesc.obj input.obj init.obj graph.obj *.s /home/david/Devel/arch/snes/devkit/bin/wla-65816 -io data.asm data.obj /home/david/Devel/arch/snes/devkit/bin/wla-65816 -io graph_asm.asm graph_asm.obj /home/david/Devel/arch/snes/devkit/bin/wla-65816 -io str.asm str.obj /home/david/Devel/arch/snes/devkit/bin/816-tcc -I. -o snesc.s.pre -c snesc.c /home/david/Devel/arch/snes/devkit/bin/816-opt snesc.s.pre > snesc.s optimization pass 1: 411 optimizations performed optimization pass 2: 204 optimizations performed optimization pass 3: 1 optimizations performed optimization pass 4: 0 optimizations performed 616 optimizations performed in total rm snesc.s.pre /home/david/Devel/arch/snes/devkit/bin/wla-65816 -io snesc.s snesc.obj /home/david/Devel/arch/snes/devkit/bin/816-tcc -I. -o input.s.pre -c input.c /home/david/Devel/arch/snes/devkit/bin/816-opt input.s.pre > input.s optimization pass 1: 5 optimizations performed optimization pass 2: 2 optimizations performed optimization pass 3: 0 optimizations performed 7 optimizations performed in total rm input.s.pre /home/david/Devel/arch/snes/devkit/bin/wla-65816 -io input.s input.obj /home/david/Devel/arch/snes/devkit/bin/816-tcc -I. -o init.s.pre -c init.c /home/david/Devel/arch/snes/devkit/bin/816-opt init.s.pre > init.s optimization pass 1: 74 optimizations performed optimization pass 2: 29 optimizations performed optimization pass 3: 0 optimizations performed 103 optimizations performed in total rm init.s.pre /home/david/Devel/arch/snes/devkit/bin/wla-65816 -io init.s init.obj /home/david/Devel/arch/snes/devkit/bin/816-tcc -I. -o graph.s.pre -c graph.c /home/david/Devel/arch/snes/devkit/bin/816-opt graph.s.pre > graph.s optimization pass 1: 7 optimizations performed optimization pass 2: 4 optimizations performed optimization pass 3: 0 optimizations performed 11 optimizations performed in total rm graph.s.pre /home/david/Devel/arch/snes/devkit/bin/wla-65816 -io graph.s graph.obj /home/david/Devel/arch/snes/devkit/bin/wlalink -dvSo data.obj graph_asm.obj str.obj snesc.obj input.obj init.obj graph.obj snesc.smc DISCARD: /home/david/Devel/arch/snes/devkit/lib/libc.obj:libc.asm: Section ".libc_misc" was discarded. DISCARD: /home/david/Devel/arch/snes/devkit/lib/libc.obj:libc.asm: Section ".libc_cstd" was discarded. Free space at $6833-$7fb1. Free space at $7fb6-$7fbf. Free space at $7fe0-$7fe3. Free space at $7ff0-$7ff3. Free space at $8000-$3ffff. Bank 00 has 06033 bytes (18.41%) free. Bank 01 has 32768 bytes (100.0%) free. Bank 02 has 32768 bytes (100.0%) free. Bank 03 has 32768 bytes (100.0%) free. Bank 04 has 32768 bytes (100.0%) free. Bank 05 has 32768 bytes (100.0%) free. Bank 06 has 32768 bytes (100.0%) free. Bank 07 has 32768 bytes (100.0%) free. 235409 unused bytes of total 262144. ../../tool/bsnes/bsnes snesc.smc || xset r on
Had a big breakthrough yesterday with our Super Nintendo Snesram project. Got for the first time a commercial game running. This was quite a hard one.
Spend a great amount of time debugging the memory uploads routines. I had to add CRC checks to both sides of the hardware. An AVR hosted CRC memory check and SNES hosted CRC check, showed us that our addressing was done correctly. But we found out that no commercial game ran on our hardware. Why that ??? More testing showed that we got a lot of memory corruption while starting a game. First we thought that the bus driver switching ( which was quite lazy implemented) caused the memory corruptions. Fixing that help a little, we could boot Super Mario World. But that would crash right after the start. Finally we found out that we shouldn’t map the WR line of the cartridge to our sram. We always thought the snes uses an unique address space for the rom and save game ram mapping. This might be true for the cpu address space but not for the cartridge address space. So the games constantly wrote to save game ram and destroyed the actual rom content….Fixing that worked out perfectly.
Right now we support up to 4mbit games. But We don’t have any save gave support at all. Also HI ROM support isn’t tested yet. The good thing is, now that we have our poc working we can move on to build an actual pcb. Our main focus will be on homebrew stuff, so running all kinds of commercial game is not our first target. This implies some hardware design decision. We want to go for software usb for the bulk rom upload, and another ftdi based usb for the cpu debugging or even for an control and user interface. Like a little remote login shell to upload roms, peek and poke memory…name it. If we have the board running with usb i see a lot of features coming up. I am not sure if we go for an sd card slot, which in my views is only interesting for gamers.
Also i have to admit that our approach, using an cpu and a static memory
addressing mode is limited. The way how Scott is
doing this gives him a lot more options to handle the black magic snes rom
layouts. Also he will have the option to synthesize DSP and FX chips onto his
fpga. So we might see him playing super mario kart on his board
But i also see an advantage in our design i guess if we make pcb kits they will be
suitable to be build by an average hobbyist geek.
We have been working the last 4 Weekends on a cool side project – we built a DIY Super Nintendo development hardware. As a SNES Programmer or SNES Nerd you always want to run your code on the orignal hardware. But this is only possible using old backup stations from the 90ies like the Super Wild Card or Game Doctor. But all these tools lack cool features like SD Card support, USB connection or real time debugging. I own an old Super Wild Card and its a pain in the ass. I can’t get the parallel port connection working and so i have to use the builtin floppy drive
There are newer projects around, but either not working or not really cool.
So we decided to build our own hardware. Today we got our proof of concept working. Its based on a STK500 setup using a ATmega16 (Ja.. I fried the ATmega32 while setting the fuses..). Attached is a SD Card and a home cooked memory bus driver for one 512k SRAM Chip. Both the ATmega and the SNES memorybus are connected to this SRAM via busdrivers. The ATmega does the housekeeping and manages the access to the RAM. To save IOpins on the ATmega side, we use shiftregisters and counter to set the adress. On the SNES side its connected to a Snes Multi Cartridge Adapter. One slot holds an orginal game, so we can use the lockout chip from there and solder the data and address from the other slot to our memory interface.
Now we are able to upload a 2Mbit SNES rom. A mario sprite on flashing background. We load this rom image from the SD Card and write it to the attached SRAM. When this is done we switch the busdriver and connect it to the SNES memory bus. Today we got the demo working. See the video and pics.
We did like 3 other proof of conecpts before to get this working.
- Interface external SRAM with an ATmega8
- Access SD Card with an ATmega8
- Dump an orginal SNES Cartridge with an FTDI based solution
- Put all this together on the STK 500
Link: www.vimeo.com
Watch the Video on vimeo to get HD and see the console output
Right now we are planing the features for version 0.1. Its mainly to get a good hardware design the cool software features are planed for version 0.2
- ATmega 644
- 4mb SRAM
- Address Counter
- Address SREG
- Busdriver
- LO/HI Rom support
- Lockout Chip
- Save game SRAM
- SD Card Support
- Software USB
- USB Upload Client
- Software Mode Switch
- Remote Reset
The Project is hosted at Assembla.com
And the poc code is here and here
git://git.assembla.com/snesram.git