FPGA SPC / SPC Test ROMs?

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
FPGA SPC / SPC Test ROMs?
by on (#88056)
Well I finally decided I should do this FPGA SPC for my possible FPGA SNES in the future. Figured doing the SPC part would be fun, and so far it has been.

I have fully written the CPU portion in verilog over the course of a day and have spent some time testing the instructions on it, but this is taking quit awhile, since I have to write code then trace its execution and manually verify that things are working how they should.

I kinda remember there being test ROMs for the SPC that blargg might've written, but my google-fu has been letting me down. I can't find much out there for testing the SPC, so my question is.. is there an SPC CPU test ROM floating around?

Ideally something that could load via .spc would be nice but I'd take anything. I don't mind having to hack around (i.e. an SNES based tester) to get something usable, since it'd save me a couple days of work testing and verifying.

by on (#88063)
Not a test ROM as such, but I have a VGM->SPC converter which includes the full source for the SPC playback code: http://jiggawatt.org/badc0de/vgm2spc-2.zip
It doesn't use every single SPC700 instruction, but maybe it can be helpful for verification in some way anyway.

by on (#88074)
Do you know this already?
http://tcrf.net/SNES_Test_Program

by on (#88075)
I imagine that the "test cartridges" like the one Hias mentions were designed to test the common ways that an authentic Super NES could malfunction in the field, not exhaustively test that the hardware is authentic. If the SPC700 is authentic, and it can run the 64-byte bootloader, it's probably working enough to rule out most known SPC-related failure modes.

by on (#88398)
thanks for the tips so far. I used that .vgm converter project to debug and that went pretty well. I have since finished the DSP (well "finished" as in, I got it to play some samples that I stuck in memory and the ADSR seems to be working.

All the instructions that are used in the .vgm player seem to be working good but I can't get any SPCs working other than it. I must have more buggy CPU instructions kicking around.

I got a few tunes from equinox to actually sorta work though. I think I might have some more DSP bugs but haven't really put a lot of effort into it yet to try and fix them since the CPU's so buggy. :-)

I think I will have to make up some kind of test ROM for it since no such ROMs exist that I could find. Specifically, some kind of instruction test ROM. I might make a CRC based one kinda like zexall.

To help development, is there an SPC player that lets you save the RAM after loading and playing it? Some of the SNES emulators might do this but it'd save time if someone could tell me of one that does it before I go through and check all of them for one that can do it.

by on (#88404)
BSNES's debugger let's you step/trace the S-SMP. There's also a memory viewer where you can look at various memory areas (select S-APU bus to look at the SPC RAM).

If you trace the execution and everything looks correct from a CPU point-of-view, you could compare what's written to the ENVX registers ($x8) in BSNES and in your DSP implementation. If they don't match then you might have a problem in your envelope handling.

by on (#88463)
mic_ wrote:
BSNES's debugger let's you step/trace the S-SMP. There's also a memory viewer where you can look at various memory areas (select S-APU bus to look at the SPC RAM).

If you trace the execution and everything looks correct from a CPU point-of-view, you could compare what's written to the ENVX registers ($x8) in BSNES and in your DSP implementation. If they don't match then you might have a problem in your envelope handling.


Unfortunately, bsnes seems to have had its debugger 100% removed. I don't know why, but the debugger is totally gone now. The webpage doesn't even hint that a debugger ever existed. I found links about it the forum here but it all just ends in 404's.

marshall did manage to find the source code to an old version and built it with the debugging on but it didn't work. I could load/run ROMs but the debugger wouldn't work. it'd just grey out the "step" buttons and do nothing.

I spent a lot of time trying to find a debugger that worked, so I finally did. The mess emulator's debugger has been working pretty good for me now and testing has been proceeding. It's buggy but I have gotten most of the bugs in it fixed (a buggy debugger. lol).

So far, I have come up with a basic opcode testing framework that works like this:

There's a 4096 entry linked list table that is loaded into memory, then the code follows the list and uses the addresses generated as input into the opcode testing part, which uses bits of the address to index 4 more random tables (0-255 sequence, no repeats) to generate the psw, a, x, and y values to test the opcodes with. My coverage is probably going to be pretty close to 100% this way. I did it this way to remove as much testing bias as possible (I had a nasty bug where X and Y were flipped on indexing for example.. this would've immediately detected that).

After running the opcode it builds into memory (using the old linked list address, so things like inc and dec actually modify the old pointers), it then crc32's the psw, a, x, and y registers and after the opcode performs all 4096 tests, it crc's the pointer table in case it was modified. This final 32 bit crc is then the "fingerprint" for a particular opcode. This is stuffed into a 2K table (256 opcodes, max of 2 tests per).

It sounds complicated but the code is actually fairly small, and a single test routine is about 200 bytes long and tests 36 opcodes with two sets of addresses which does not, and then does cross pages. That's 72 full tests. It takes about 50 seconds to run those so a full test ROM run will probably take 10-15 minutes. But that's the price of accuracy.

The only hard part I am going to have is how to test this on a real SNES. Some kind of snes ROM that loads the data into the SPC, runs it, then reads the results back and saves them into battery-backed RAM is probably the best. Then a SNES copier (yeah I have one) can be used to save the battery backed RAM to a file to recover the CRCs on the real system.

That won't be for a few days though, so any ideas on how to do that would be cool.

I finally got the tester debugged and working now, so adding the other opcodes shouldn't take TOO much time. Right now I have it testing all of the absolute instructions, and absolute indexed instructions. Today I will round that out hopefully with all of the ALU functions.

After this tester is done, it should be relatively easy to port it to the 6502 and have it run on the NES for a kind of "super 6502 tester".

by on (#88470)
Quote:
Unfortunately, bsnes seems to have had its debugger 100% removed. I don't know why, but the debugger is totally gone now. The webpage doesn't even hint that a debugger ever existed. I found links about it the forum here but it all just ends in 404's.


I've got a copy of the debugger version of BSNES v0.60 (for Windows) that I can put online, unless byuu has any objections.

EDIT: Here's the BSNES 0.60 archive with the debugger.

As for loading SPC files from the SNES side, I've got something for that here (source included) (more info on how it works).

by on (#88691)
mic_ wrote:
Quote:
Unfortunately, bsnes seems to have had its debugger 100% removed. I don't know why, but the debugger is totally gone now. The webpage doesn't even hint that a debugger ever existed. I found links about it the forum here but it all just ends in 404's.


I've got a copy of the debugger version of BSNES v0.60 (for Windows) that I can put online, unless byuu has any objections.

EDIT: Here's the BSNES 0.60 archive with the debugger.

As for loading SPC files from the SNES side, I've got something for that here (source included) (more info on how it works).


Cool thanks for the stuff.

update: The SPC test ROM is more or less done, and tests 254 of the 256 opcodes with around 8000 tests per opcode, followed by CRC32'ing of the results.

I have used it to debug my FPGA SPC CPU, and it worked great for this. I still have a few kinks to work out with the test code then I guess I can post the source to it. It's not runnable on a real SNES yet, since I don't really know anything about the SNES to get it to spit back data in some usable form.

I suspect it will basically run, then spit the crc's back to the SNES which can store it in SRAM, then the SRAM can be backed up by a copier and read out that way. I might need some help on writing code to do this... I dunno yet. After I post the source maybe someone can take a look at what I did and go from there.

The tests are done fairly simply: it just loads the registers with randomish values via some tables, runs the instruction, then CRC's all the registers afterwards (a, x, y, flags) and data bytes, if needed (i.e. instructions that modify memory). This is done with two sets of data, and sometimes two slightly different testing methods. i.e. page crosses and no page crosses.

I didn't go nuts with testing yet because I wasn't sure if the PC emulators could handle it. namely things like zeropage wrapping and pcall wrapping among other things.

(since someone will probably ask, the two opcodes I cannot test are sleep and stop).

by on (#88693)
Quote:
I suspect it will basically run, then spit the crc's back to the SNES which can store it in SRAM, then the SRAM can be backed up by a copier and read out that way. I might need some help on writing code to do this...


Or display it on the screen? Unless you really want to keep the data for later.

Sending data back to the SNES works the same way as for the other direction: you've got your four communication ports ($2140-$2143 on the S-CPU [SNES] side, and $F4-$F7 on the S-SMP [SPC] side).

Pseudo-code:

S-CPU
Code:
for (i=0; i < CRC_BYTES/2; i++)
{
   while (R_SPCCOM0 != i) ;  // Wait for indication of new data
   crc[i*2] = R_SPCCOM1;
   crc[i*2 + 1] = R_SPCCOM2;
   R_SPCCOM0 = i;  // echo the counter back to the S-SMP
}


S-SMP
Code:
for (i = 0; i < CRC_BYTES/2; i++)
{
   R_PORT0 = i;   
   R_PORT1 = crc[i*2];
   R_PORT2 = crc[i*2 + 1];
   while (R_PORT0 != i) ;  // wait for echo from the S-CPU
}


If you have more than 256 bytes of data to transfer you might want to use ports 0-1 as a 16-bit counter, and ports 2-3 for the actual data bytes.. Or some other combination.

by on (#88775)
> I didn't go nuts with testing yet because I wasn't sure if the PC emulators could handle it. namely things like zeropage wrapping and pcall wrapping among other things.

I would appreciate it if you ran the test on bsnes v085 to see if it fails anything. If so, I'll fix it.

> (since someone will probably ask, the two opcodes I cannot test are sleep and stop).

One of the pins on the S-SMP has to be /IRQ (but I can't find a complete pinout.) Wire it up to a switch to toggle +5V/GND (pull off the Vreg or something), and have fun with SLEEP =)

I'd actually really like to emulate IRQs on the chip, even if there's no way to use them, just to have a complete core.

Speaking of that ... you have any plans to attack the TEST register? Neither me, anomie nor blargg have been able to figure out every bit entirely.
We know: frequency adjust, RAM disable, RAM write disable, MMIO disable.
We are fuzzy on: two bits that each do weird things to the timers, one frequency setting that deadlocks every SMP we've tried it on to date.
No games use it at all, but again, fun to do it all the way.

> Unfortunately, bsnes seems to have had its debugger 100% removed. I don't know why, but the debugger is totally gone now.

Rewrote the GUI. Debugger takes a lot of time to remake. Plan in the future is to have the debugger be a separate GUI entirely. Trying to get it to work with ALL GUI features doesn't work very well.

You wouldn't like the current one anyway. I threw out the official SPC700 mnemonics and made my own 6502-alike to match the S-CPU, eg:
Code:
mov a,#$12 -> lda #$12
push x -> phx

It works amazingly well. The chip was clearly a 6502 with the mnemonics changed last-minute (probably) for legal reasons.

Anyway, v070 has probably the best debugger.

by on (#88816)
byuu wrote:
> I didn't go nuts with testing yet because I wasn't sure if the PC emulators could handle it. namely things like zeropage wrapping and pcall wrapping among other things.

I would appreciate it if you ran the test on bsnes v085 to see if it fails anything. If so, I'll fix it.



Yeah I may need a bit of help on the SNES side of things, since I have never written anything for it. Sure I can learn it and all that, but at this point I don't want to spend the time to learn it, hehe. (Since I've been concentrating on SPC and the FPGA implementation thereof).

Quote:

One of the pins on the S-SMP has to be /IRQ (but I can't find a complete pinout.) Wire it up to a switch to toggle +5V/GND (pull off the Vreg or something), and have fun with SLEEP =)

I'd actually really like to emulate IRQs on the chip, even if there's no way to use them, just to have a complete core.



Yeah I was wondering if the pin(s) existed for an interrupt or two. It seems silly to have the instruction if you cannot use it. But it miight make a little sense if they used a "stock" core as a base for it.

Quote:

Speaking of that ... you have any plans to attack the TEST register? Neither me, anomie nor blargg have been able to figure out every bit entirely.
We know: frequency adjust, RAM disable, RAM write disable, MMIO disable.
We are fuzzy on: two bits that each do weird things to the timers, one frequency setting that deadlocks every SMP we've tried it on to date.
No games use it at all, but again, fun to do it all the way.



Is is possible it controls something to do with the DSP's memory sharing or something? From what I can tell, the DSP hits what amounts to RDY on the CPU for 2 out of 3 cycles. This is how I implement it on my FPGA version anyways.

I guess the DSP could be running the show, too, when it comes to memory interleaving.

Quote:

> Unfortunately, bsnes seems to have had its debugger 100% removed. I don't know why, but the debugger is totally gone now.

Rewrote the GUI. Debugger takes a lot of time to remake. Plan in the future is to have the debugger be a separate GUI entirely. Trying to get it to work with ALL GUI features doesn't work very well.

You wouldn't like the current one anyway. I threw out the official SPC700 mnemonics and made my own 6502-alike to match the S-CPU, eg:
Code:
mov a,#$12 -> lda #$12
push x -> phx




Gotcha. that's a good reason as any :-) I wouldn't mind it TOO much, so long as it works. I ended up using the MESS debugger, however. It was good for dumping the SPC's RAM to disk so I could poke it later.

The output of my test program is a 2K block of CRC's corresponding to all 256 instructions (4 bytes per, and 2 tests per opcode, so 512*4 bytes). There is also a 512 byte field that indicates which tests passed and which failed (though that's not implemented yet, it just shows when a test is run).

Quote:

It works amazingly well. The chip was clearly a 6502 with the mnemonics changed last-minute (probably) for legal reasons.

Anyway, v070 has probably the best debugger.


Yeah I was wondering about this, if it was meant to be a super-enhanced 6502 or not. They sure added some weird instructions if so, like being able to OR/NOR/AND/NAND/XOR a single memory bit with the carry flag. Does anything even USE those instructions?

by on (#88817)
mic_ wrote:
Quote:
I suspect it will basically run, then spit the crc's back to the SNES which can store it in SRAM, then the SRAM can be backed up by a copier and read out that way. I might need some help on writing code to do this...


Or display it on the screen? Unless you really want to keep the data for later.



Yeah, I wanted to keep the 2K of CRC's so I could plug them back into the SPC so it can indicate pass/fail on the various tests. I figure that on a real SNES, most of the tests will pass, through, so indicating the failures might be a valid way to go.

My biggest issue is not getting them out of the SPC, but getting the SNES to do what I want it to do, hehe. I haven't touched the SNES before with regards to coding it. I was probably going to just take some kind of example code and convert it over to do my bidding or something.

Buut I've been busy with FPGA and running the SPC thereon, so I haven't had time nor inclination to do it yet.

Speaking of, I got a video of it playing some SPC's posted to youtube:

http://www.youtube.com/watch?v=_uDHCZGoHjM

I squashed a major echo bug after posting this, but I don't think it's terribly audible. I had some channel "Cross pollination" of the echo, because the right channel N audio is written during channel time N+1, which means the echo enable bit had changed, turning echo on wrongly for channel N. This was since fixed.

by on (#88818)
Quote:
My biggest issue is not getting them out of the SPC, but getting the SNES to do what I want it to do, hehe. I haven't touched the SNES before with regards to coding it.


Sounds like you've done all the hard parts and have the easy stuff left :P
Hell, you can program the SNES using C, except for the most timing-critical stuff, which simplifies the work a bit. And unless you need a fancy-schmancy GUI there's no need to learn all the details of the PPU and DMA controller (until you start implementing the full FPGASNES).

by on (#88819)
The SNES is close enough conceptually to the NES that it shouldn't be too hard to get some sort of terminal running, should it?

by on (#88820)
What determines whether the echo buffer is displayed in purple or blue?

by on (#88822)
lidnariq wrote:
What determines whether the echo buffer is displayed in purple or blue?


It depends on if it's read-only (purple) or read/write (blue).