SPC7110 Reverse Engineering Project

Discussion of hardware and software development for Super NES and Super Famicom.

Moderator: Moderators

Forum rules
  • For making cartridges of your Super NES games, see Reproduction.
Post Reply
User avatar
kyuusaku
Posts: 1665
Joined: Mon Sep 27, 2004 2:13 pm

Post by kyuusaku »

The test fails but correctly displays the game's name.
neviksti
Posts: 205
Joined: Thu Jun 22, 2006 11:39 pm

Post by neviksti »

Doh!
I thought I followed Caitsith's dumping code exactly.

Thanks for giving it a try.
Hopefully my FEoEZ cart will be arriving soon and I can play with the hardware to debug this thing.

EDIT: What hex values does it show for the start/end? And does it just lock up when waiting for decompression to finish? (If it completes the tests it should say "Done." and a frame counter will be running on the bottom of the screen.)
neviksti
Posts: 205
Joined: Thu Jun 22, 2006 11:39 pm

Post by neviksti »

My FEoEZ came in and I was able to debug my program (it had a bunch of stupid little errors).

I couldn't get FEoEZ to work right on my SF7. It would look like it was getting most of the decompressed bytes, but not entirely correctly... or shifted somehow. It works fine on passthrough with the SF3. So I assume it is just that the clock from my SNES is too noisy, and the NAND gate in the SF3 cleans it up nice enough while the transistor in the SF7 doesn't.


Anyway, both decompressions worked fine, so it is confirmed that the table address does not matter.

I was able to read from the start and end of the datarom, and pass both decompressions, regardless of whether I did that spc7110 initialization sequence. Caitsith, where did you get that from (was it in one of the register tests)?

I'll just leave it in since it doesn't really hurt anything.


DarkForce's document suggests bank $50 is no different than just accessing register $4800. Kammedo, is there something in particular that made you think this was internal RAM?

Basically, if you can't reach anything in bank $50 with random access, then it can't really be distinguished from register $4800... and why would they pay to put 64kB of RAM (that is a heck of a lot of RAM) in a cartridge when it doesn't seem to be needed or used?

If there is a test that clearly shows bank $50 is internal ram, I would definitely like to try it. Please let me know.


Tomorrow I'll start running tests to get all the possible first byte inputs -> decompressed outputs.
kammedo
Posts: 57
Joined: Wed May 28, 2008 5:43 am

Post by kammedo »

neviksti wrote:My FEoEZ came in and I was able to debug my program (it had a bunch of stupid little errors).

I couldn't get FEoEZ to work right on my SF7. It would look like it was getting most of the decompressed bytes, but not entirely correctly... or shifted somehow. It works fine on passthrough with the SF3. So I assume it is just that the clock from my SNES is too noisy, and the NAND gate in the SF3 cleans it up nice enough while the transistor in the SF7 doesn't.
Yeah, i have problems with it too. Probably I should just bridge the clock straight - through. But Im afrait to ruin the GDSF7 with it, with taking control about the clock from it..


neviksti wrote:Anyway, both decompressions worked fine, so it is confirmed that the table address does not matter.

I was able to read from the start and end of the datarom, and pass both decompressions, regardless of whether I did that spc7110 initialization sequence. Caitsith, where did you get that from (was it in one of the register tests)?

I'll just leave it in since it doesn't really hurt anything.


DarkForce's document suggests bank $50 is no different than just accessing register $4800. Kammedo, is there something in particular that made you think this was internal RAM?

Basically, if you can't reach anything in bank $50 with random access, then it can't really be distinguished from register $4800... and why would they pay to put 64kB of RAM (that is a heck of a lot of RAM) in a cartridge when it doesn't seem to be needed or used?

If there is a test that clearly shows bank $50 is internal ram, I would definitely like to try it. Please let me know.


Tomorrow I'll start running tests to get all the possible first byte inputs -> decompressed outputs.
Actually FEoEZ and MDH and I think even PL3 all DMA from bank $50 the decompressed data to WRAM.
As I stated, I think the only difference in the two ways to get the data from is that one is synchronous (reg 4800) to the reads (ie the SPC decomrpesses "on demand") while the other is a "block" mode, that is it decompresses the whole. That's the only reason i can come up with.
Charles Macdonald was unsure about this RAM to even exist, until he managed to test it directly.

Actually there is a nice way to find out :
a) write a pattern of known data to bank $50
b) init the offset for reg $4800 (regs $4804/05) to 0
c) read data from reg $4800
d) compare it with your pattern at the given offset.

This way we would be able to know if reading from that register is equivalent in reading from the bank directly or not.
neviksti
Posts: 205
Joined: Thu Jun 22, 2006 11:39 pm

Post by neviksti »

kammedo wrote:Actually FEoEZ and MDH and I think even PL3 all DMA from bank $50 the decompressed data to WRAM.
But that doesn't show anything. You could also do a DMA from reg $4800. In DarkForce's document he says reading from any location in bank $50 is as if you read from reg $4800. Just because they did a DMA from bank $50 doesn't mean the data was stored waiting to be read in RAM mapped to bank $50.
kammedo wrote:As I stated, I think the only difference in the two ways to get the data from is that one is synchronous (reg 4800) to the reads (ie the SPC decomrpesses "on demand") while the other is a "block" mode, that is it decompresses the whole. That's the only reason i can come up with.
But the sequence used to setup a decompression doesn't have any distinction between these two. The only possible difference would be if you could read anywhere in the "block" at $50 to get a random byte in the decompressed data ... you can't as far as I can tell, and according to DarkForce's document as well. So there is no distinction to be made here.

kammedo wrote:Charles Macdonald was unsure about this RAM to even exist, until he managed to test it directly.
I am very interested in learning what precisely it was that changed his mind, because I am very skeptical myself at the moment.
kammedo wrote:Actually there is a nice way to find out :
a) write a pattern of known data to bank $50
b) init the offset for reg $4800 (regs $4804/05) to 0
c) read data from reg $4800
d) compare it with your pattern at the given offset.

This way we would be able to know if reading from that register is equivalent in reading from the bank directly or not.
It is not even possible to write a value to some location at bank $50 and read it back (I've tried). It is not RAM as far as I can tell. If Chris did a test that convinced him there was internal RAM mapped to bank $50, it must have been something other than this.

Since you've seen the code that the cartridges use, can you show me an entire setup and decompress sequence. Maybe there is something that makes bank $50 act like RAM and I just haven't enabled it?


On a more pertinent note, if your SF7 doesn't have a working CLK buffer or a floppy drive, is there anything else you can use to play around with the SPC7110? I hope I can compare any findings with someone else as a double check.
kammedo
Posts: 57
Joined: Wed May 28, 2008 5:43 am

Post by kammedo »

neviksti wrote: But that doesn't show anything. You could also do a DMA from reg $4800. In DarkForce's document he says reading from any location in bank $50 is as if you read from reg $4800. Just because they did a DMA from bank $50 doesn't mean the data was stored waiting to be read in RAM mapped to bank $50.
But that's the point. Why would they DMA from bank $50, if they could do exactly the same via the $4800 register? Also, as far as we know, maybe the chip needs a lookup buffer with the last decompressed values (in a LZ fashion).
neviksti wrote: But the sequence used to setup a decompression doesn't have any distinction between these two. The only possible difference would be if you could read anywhere in the "block" at $50 to get a random byte in the decompressed data ... you can't as far as I can tell, and according to DarkForce's document as well. So there is no distinction to be made here.
Thats actually a good point. We know for sure that reading from $4800 decrements the compressed counter. Which makes me think : how much can we trust Darkforce's doc? As in, how feasible is it?
neviksti wrote: I am very interested in learning what precisely it was that changed his mind, because I am very skeptical myself at the moment.

It is not even possible to write a value to some location at bank $50 and read it back (I've tried). It is not RAM as far as I can tell. If Chris did a test that convinced him there was internal RAM mapped to bank $50, it must have been something other than this.

Since you've seen the code that the cartridges use, can you show me an entire setup and decompress sequence. Maybe there is something that makes bank $50 act like RAM and I just haven't enabled it?

On a more pertinent note, if your SF7 doesn't have a working CLK buffer or a floppy drive, is there anything else you can use to play around with the SPC7110? I hope I can compare any findings with someone else as a double check.
Isnt it possible in that the read returns a different value than what has been written? This could mean that either you cant write and read to the $50 bank from the SNES, or you can just read from it and not write to it which sounds more realistic since DMA works, so I dont see why reading from the bank shouldnt.

I cant recall which test Charles MacDonald did, but perhaps he got driven to that conclusion by the fact that the same data is not available anywhere else?

Here is the trace of the decompression routine. I had most of the code of the tests re-eng but i cant find the trace file..>_< I will look after it, but in case I think it shouldnt take too long to r-e it again.

Code: Select all

---------- Set up paramenters for the SPC decompression routine
$C0/139D 22 05 16 C0 JSL $C01605[$C0:1605]   A:0301 X:00FF Y:00FF P:envMXdizC

$C0/1605 8B          PHB                     A:0301 X:00FF Y:00FF P:envMXdizC
$C0/1606 5A          PHY                     A:0301 X:00FF Y:00FF P:envMXdizC
$C0/1607 DA          PHX                     A:0301 X:00FF Y:00FF P:envMXdizC
$C0/1608 8D E5 0F    STA $0FE5  [$80:0FE5]   A:0301 X:00FF Y:00FF P:envMXdizC
$C0/160B 3A          DEC A                   A:0301 X:00FF Y:00FF P:envMXdizC
$C0/160C A8          TAY                     A:0300 X:00FF Y:00FF P:envMXdiZC
$C0/160D AD ED 0F    LDA $0FED  [$80:0FED]   A:0300 X:00FF Y:0000 P:envMXdiZC
$C0/1610 0A          ASL A                   A:030A X:00FF Y:0000 P:envMXdizC
$C0/1611 6D ED 0F    ADC $0FED  [$80:0FED]   A:0314 X:00FF Y:0000 P:envMXdizc
$C0/1614 AA          TAX                     A:031E X:00FF Y:0000 P:envMXdizc
$C0/1615 9C 3A 02    STZ $023A  [$80:023A]   A:031E X:001E Y:0000 P:envMXdizc
$C0/1618 9C 0D 42    STZ $420D  [$80:420D]   A:031E X:001E Y:0000 P:envMXdizc
$C0/161B C2 20       REP #$20                A:031E X:001E Y:0000 P:envMXdizc
------------ Set up Data Table pointer
$C0/161D BF 3C 18 C0 LDA $C0183C,x[$C0:185A] A:031E X:001E Y:0000 P:envmXdizc
$C0/1621 85 06       STA $06    [$00:0006]   A:8800 X:001E Y:0000 P:eNvmXdizc
$C0/1623 BF 3D 18 C0 LDA $C0183D,x[$C0:185B] A:8800 X:001E Y:0000 P:eNvmXdizc
$C0/1627 85 07       STA $07    [$00:0007]   A:2A88 X:001E Y:0000 P:envmXdizc
------------ Set up corrispondent Offset table pointer
$C0/1629 BF CD 17 C0 LDA $C017CD,x[$C0:17EB] A:2A88 X:001E Y:0000 P:envmXdizc
$C0/162D 85 2A       STA $2A    [$00:002A]   A:2DB8 X:001E Y:0000 P:envmXdizc
$C0/162F BF CE 17 C0 LDA $C017CE,x[$C0:17EC] A:2DB8 X:001E Y:0000 P:envmXdizc
$C0/1633 85 2B       STA $2B    [$00:002B]   A:DF2D X:001E Y:0000 P:eNvmXdizc
$C0/1635 98          TYA                     A:DF2D X:001E Y:0000 P:eNvmXdizc
$C0/1636 C2 10       REP #$10                A:0000 X:001E Y:0000 P:envmXdiZc
$C0/1638 29 FF 00    AND #$00FF              A:0000 X:001E Y:0000 P:envmxdiZc
$C0/163B 0A          ASL A                   A:0000 X:001E Y:0000 P:envmxdiZc
$C0/163C 0A          ASL A                   A:0000 X:001E Y:0000 P:envmxdiZc
$C0/163D A8          TAY                     A:0000 X:001E Y:0000 P:envmxdiZc
--------- Get VRAM destination OFFSET
$C0/163E B7 2A       LDA [$2A],y[$DF:2DB8]   A:0000 X:001E Y:0000 P:envmxdiZc
$C0/1640 29 F8 FF    AND #$FFF8              A:3803 X:001E Y:0000 P:envmxdizc
$C0/1643 85 0F       STA $0F    [$00:000F]   A:3800 X:001E Y:0000 P:envmxdizc
$C0/1645 B7 2A       LDA [$2A],y[$DF:2DB8]   A:3800 X:001E Y:0000 P:envmxdizc
$C0/1647 29 07 00    AND #$0007              A:3803 X:001E Y:0000 P:envmxdizc
$C0/164A 85 09       STA $09    [$00:0009]   A:0003 X:001E Y:0000 P:envmxdizc
$C0/164C C8          INY                     A:0003 X:001E Y:0000 P:envmxdizc
$C0/164D C8          INY                     A:0003 X:001E Y:0001 P:envmxdizc
$C0/164E B7 2A       LDA [$2A],y[$DF:2DBA]   A:0003 X:001E Y:0002 P:envmxdizc
$C0/1650 85 0C       STA $0C    [$00:000C]   A:0DF0 X:001E Y:0002 P:envmxdizc
$C0/1652 C8          INY                     A:0DF0 X:001E Y:0002 P:envmxdizc
$C0/1653 C8          INY                     A:0DF0 X:001E Y:0003 P:envmxdizc
$C0/1654 E2 20       SEP #$20                A:0DF0 X:001E Y:0004 P:envmxdizc
$C0/1656 E2 10       SEP #$10                A:0DF0 X:001E Y:0004 P:envMxdizc
$C0/1658 A9 01       LDA #$01                A:0DF0 X:001E Y:0004 P:envMXdizc
$C0/165A 8D 3A 02    STA $023A  [$80:023A]   A:0D01 X:001E Y:0004 P:envMXdizc
$C0/165D 8D 0D 42    STA $420D  [$80:420D]   A:0D01 X:001E Y:0004 P:envMXdizc
$C0/1660 AD E5 0F    LDA $0FE5  [$80:0FE5]   A:0D01 X:001E Y:0004 P:envMXdizc
------------ Decompress GFX!
------- Parameters :
---- $00 pointer Index (32 bit pointer!)
---- $06 Data Table pointer Lo Byte
---- $07 Data Table pointer Mid byte
---- $08 Data Table pointer Hi Byte

$C0/1663 22 00 2D C0 JSL $C02D00[$C0:2D00]   A:0D01 X:001E Y:0004 P:envMXdizc

$C0/2D00 48          PHA                     A:0D01 X:001E Y:0004 P:envMXdizc
$C0/2D01 A9 00       LDA #$00                A:0D01 X:001E Y:0004 P:envMXdizc
$C0/2D03 8F C1 2E 7E STA $7E2EC1[$7E:2EC1]   A:0D00 X:001E Y:0004 P:envMXdiZc
$C0/2D07 8F C2 2E 7E STA $7E2EC2[$7E:2EC2]   A:0D00 X:001E Y:0004 P:envMXdiZc
$C0/2D0B 68          PLA                     A:0D00 X:001E Y:0004 P:envMXdiZc
$C0/2D0C 3A          DEC A                   A:0D01 X:001E Y:0004 P:envMXdizc
$C0/2D0D C9 FF       CMP #$FF                A:0D00 X:001E Y:0004 P:envMXdiZc
$C0/2D0F D0 04       BNE $04    [$2D15]      A:0D00 X:001E Y:0004 P:envMXdizc
$C0/2D15 85 00       STA $00    [$00:0000]   A:0D00 X:001E Y:0004 P:envMXdizc
----------- Set HW decompression!
$C0/2D17 A9 02       LDA #$02                A:0D00 X:001E Y:0004 P:envMXdizc
$C0/2D19 8D 0B 48    STA $480B  [$80:480B]   A:0D02 X:001E Y:0004 P:envMXdizc
$C0/2D1C A5 06       LDA $06    [$00:0006]   A:0D02 X:001E Y:0004 P:envMXdizc
$C0/2D1E 8D 01 48    STA $4801  [$80:4801]   A:0D00 X:001E Y:0004 P:envMXdiZc
$C0/2D21 A5 07       LDA $07    [$00:0007]   A:0D00 X:001E Y:0004 P:envMXdiZc
$C0/2D23 8D 02 48    STA $4802  [$80:4802]   A:0D88 X:001E Y:0004 P:eNvMXdizc
$C0/2D26 A5 08       LDA $08    [$00:0008]   A:0D88 X:001E Y:0004 P:eNvMXdizc
$C0/2D28 8D 03 48    STA $4803  [$80:4803]   A:0D2A X:001E Y:0004 P:envMXdizc
$C0/2D2B AD 0B 48    LDA $480B  [$80:480B]   A:0D2A X:001E Y:0004 P:envMXdizc
$C0/2D2E A5 00       LDA $00    [$00:0000]   A:0D02 X:001E Y:0004 P:envMXdizc
$C0/2D30 8D 04 48    STA $4804  [$80:4804]   A:0D00 X:001E Y:0004 P:envMXdiZc
$C0/2D33 8D 04 48    STA $4804  [$80:4804]   A:0D00 X:001E Y:0004 P:envMXdiZc
----------- Match DMA channel
$C0/2D36 A9 01       LDA #$01                A:0D00 X:001E Y:0004 P:envMXdiZc
$C0/2D38 8D 07 48    STA $4807  [$80:4807]   A:0D01 X:001E Y:0004 P:envMXdizc
$C0/2D3B AF C1 2E 7E LDA $7E2EC1[$7E:2EC1]   A:0D01 X:001E Y:0004 P:envMXdizc
$C0/2D3F 29 1F       AND #$1F                A:0D00 X:001E Y:0004 P:envMXdiZc
$C0/2D41 85 02       STA $02    [$00:0002]   A:0D00 X:001E Y:0004 P:envMXdiZc
$C0/2D43 AF C1 2E 7E LDA $7E2EC1[$7E:2EC1]   A:0D00 X:001E Y:0004 P:envMXdiZc
$C0/2D47 29 E0       AND #$E0                A:0D00 X:001E Y:0004 P:envMXdiZc
$C0/2D49 8D 05 48    STA $4805  [$80:4805]   A:0D00 X:001E Y:0004 P:envMXdiZc
$C0/2D4C AF C2 2E 7E LDA $7E2EC2[$7E:2EC2]   A:0D00 X:001E Y:0004 P:envMXdiZc
$C0/2D50 8D 06 48    STA $4806  [$80:4806]   A:0D00 X:001E Y:0004 P:envMXdiZc
------------ Wait for decompression finished
$C0/2D53 AD 0C 48    LDA $480C  [$80:480C]   A:0D00 X:001E Y:0004 P:envMXdiZc
$C0/2D56 10 FB       BPL $FB    [$2D53]      A:0D00 X:001E Y:0004 P:envMXdiZc
$C0/2D58 C6 02       DEC $02    [$00:0002]   A:0D80 X:001E Y:0004 P:eNvMXdizc
$C0/2D5A 30 05       BMI $05    [$2D61]      A:0D80 X:001E Y:0004 P:eNvMXdizc
$C0/2D61 6B          RTL                     A:0D80 X:001E Y:0004 P:eNvMXdizc

$C0/1667 FA          PLX                     A:0D80 X:001E Y:0004 P:eNvMXdizc
$C0/1668 7A          PLY                     A:0D80 X:00FF Y:0004 P:eNvMXdizc
$C0/1669 AB          PLB                     A:0D80 X:00FF Y:00FF P:eNvMXdizc
$C0/166A 6B          RTL                     A:0D80 X:00FF Y:00FF P:eNvMXdizc
User avatar
Charles MacDonald
Posts: 16
Joined: Sat Dec 30, 2006 9:20 pm
Contact:

Post by Charles MacDonald »

Hi Kammedo!

About the FEoEZ memory map, I took my SNES memory map viewing program and adapted it to run on the Game Genie, so I could plug in the FEoEZ cart and examine it after my program relocated itself to work RAM. (and yeah, I added a wire to connect the missing clock signal that isn't passed through the Genie to the cart edge connector).

What I got was this:

Banks
00-1F : SRAM @ 6000-7FFF, U1 ROM @ 8000-FFFF (1MB)
20-3F : SRAM @ 6000-7FFF, U2 ROM @ 8000-FFFF (banked?)
40-4F : Unused (reads return last value on data bus; e.g. bank address)
50 : 64K SPC7110 internal RAM :D
51-57 : Unused (as above)
58 : SPC7110 data port
59-7D : Unused (as above)
80-9F : 8K SRAM @ 6000-7FFF, U1 ROM @ 8000-FFFF (1MB)
A0-BF : 8K SRAM @ 6000-7FFF, U2 ROM @ 8000-FFFF (banked?)
C0-CF : U1 ROM (1MB)
D0-DF : U2 ROM (banked)
E0-EF : U2 ROM (banked)
F0-FF : U2 ROM (banked)

The SRAM is the 8K RAM chip on the PCB. The internal RAM is, I assume, internal the SPC7110 because there is no other RAM on the board to account for it, and it makes sense the chip would have some place to store its results.

Originally I assumed bank $50 was an auto-incrementing data port mapped to every byte, which would facilitate DMA transfers, block transfers, etc. out of that bank to work RAM or PPU RAM. However in the memory map viewing program, I found the data did not change across subsequent reads (if it was a data port the auto-incrementing would change the results continuously) and the data itself was not mirrored, and was unique for 64K. AFAIK I did a write test and the RAM was readable and writable with no mirroring of the write data at other addresses.

So that's my take on it. Within the scope of my tests it seems to be 64K of RAM at bank $50. Now if what I was seeing was a fixed pattern of random data, a mirror of ROM from elsewhere, or something like that, then so be it. :)
kammedo
Posts: 57
Joined: Wed May 28, 2008 5:43 am

Post by kammedo »

Charles MacDonald wrote:Hi Kammedo!
Hey man! I was just about to drop you a line. Nice to see you around ^^!

Charles MacDonald wrote:About the FEoEZ memory map, I took my SNES memory map viewing program and adapted it to run on the Game Genie, so I could plug in the FEoEZ cart and examine it after my program relocated itself to work RAM. (and yeah, I added a wire to connect the missing clock signal that isn't passed through the Genie to the cart edge connector).

What I got was this:

Banks
00-1F : SRAM @ 6000-7FFF, U1 ROM @ 8000-FFFF (1MB)
20-3F : SRAM @ 6000-7FFF, U2 ROM @ 8000-FFFF (banked?)
40-4F : Unused (reads return last value on data bus; e.g. bank address)
50 : 64K SPC7110 internal RAM :D
51-57 : Unused (as above)
58 : SPC7110 data port
59-7D : Unused (as above)
80-9F : 8K SRAM @ 6000-7FFF, U1 ROM @ 8000-FFFF (1MB)
A0-BF : 8K SRAM @ 6000-7FFF, U2 ROM @ 8000-FFFF (banked?)
C0-CF : U1 ROM (1MB)
D0-DF : U2 ROM (banked)
E0-EF : U2 ROM (banked)
F0-FF : U2 ROM (banked)

The SRAM is the 8K RAM chip on the PCB. The internal RAM is, I assume, internal the SPC7110 because there is no other RAM on the board to account for it, and it makes sense the chip would have some place to store its results.

Originally I assumed bank $50 was an auto-incrementing data port mapped to every byte, which would facilitate DMA transfers, block transfers, etc. out of that bank to work RAM or PPU RAM. However in the memory map viewing program, I found the data did not change across subsequent reads (if it was a data port the auto-incrementing would change the results continuously) and the data itself was not mirrored, and was unique for 64K. AFAIK I did a write test and the RAM was readable and writable with no mirroring of the write data at other addresses.

So that's my take on it. Within the scope of my tests it seems to be 64K of RAM at bank $50. Now if what I was seeing was a fixed pattern of random data, a mirror of ROM from elsewhere, or something like that, then so be it. :)
Hm. So it looks like neviksti is missing something, if his writes arent going through. Btw : if I recall, you were totally sure that the U2 bus was read only (that is, there would be no know way to mirror SNES writes to the U2 bus). Is that correct?

Nice to see you joining the conversation! This is the good time to get that beast cracked! :D
User avatar
Charles MacDonald
Posts: 16
Joined: Sat Dec 30, 2006 9:20 pm
Contact:

Post by Charles MacDonald »

kammedo wrote:Hm. So it looks like neviksti is missing something, if his writes arent going through. Btw : if I recall, you were totally sure that the U2 bus was read only (that is, there would be no know way to mirror SNES writes to the U2 bus). Is that correct?
But it's just as possible that my testing methods were flawed and the interpretation of the results were inaccurate. I could never claim to have final authority in any SNES-related matters! :)

About the U2 bus this is how it worked: The mask ROM at U2 has /CE grounded and /OE connected directly by the SPC7110. This means the ROM is always selected and drives the U2 data bus during reads only. In order to write, we need to consider some things:

With /CE grounded, assuming a RAM was on the U2 bus it would have to have a write strobe restricted to the memory range the U2 device is mapped to, just like /OE. So it would have to be a SPC7110 generated write strobe, and not the 65816 /WR. I don't think we know of any such pin on the SPC7110.

We could assume the /OE output is really /CE, because you get faster access to ROMs where /CE=ground and /OE is used to enable output from the device. In this case /OE (really /CE) is restricted to the U2 memory range, and 65816 /RD and /WR could be directly connected to the RAM in question.

How to verify this? With a oscilloscope or logic analyzer, see if /OE on the mask ROM is pulsed when a write to the U2 region occurs. If it doesn't, then /OE really is /OE, and we have a /CS and /WR strobe that are unaccounted for and may not exist. If nobody has done this I will try it!

If it does happen, then /OE is /CE and we can use the 65816 /RD and /WR strobes directly. That would be very good news, and would allow a RAM to be access over the U2 bus.

Oh and if it wasn't mentioned already, the mask ROM is in byte mode so the data bus is just 8 bits.
kammedo
Posts: 57
Joined: Wed May 28, 2008 5:43 am

Post by kammedo »

Charles MacDonald wrote:
kammedo wrote:Hm. So it looks like neviksti is missing something, if his writes arent going through. Btw : if I recall, you were totally sure that the U2 bus was read only (that is, there would be no know way to mirror SNES writes to the U2 bus). Is that correct?
But it's just as possible that my testing methods were flawed and the interpretation of the results were inaccurate. I could never claim to have final authority in any SNES-related matters! :)

About the U2 bus this is how it worked: The mask ROM at U2 has /CE grounded and /OE connected directly by the SPC7110. This means the ROM is always selected and drives the U2 data bus during reads only. In order to write, we need to consider some things:

With /CE grounded, assuming a RAM was on the U2 bus it would have to have a write strobe restricted to the memory range the U2 device is mapped to, just like /OE. So it would have to be a SPC7110 generated write strobe, and not the 65816 /WR. I don't think we know of any such pin on the SPC7110.

We could assume the /OE output is really /CE, because you get faster access to ROMs where /CE=ground and /OE is used to enable output from the device. In this case /OE (really /CE) is restricted to the U2 memory range, and 65816 /RD and /WR could be directly connected to the RAM in question.

How to verify this? With a oscilloscope or logic analyzer, see if /OE on the mask ROM is pulsed when a write to the U2 region occurs. If it doesn't, then /OE really is /OE, and we have a /CS and /WR strobe that are unaccounted for and may not exist. If nobody has done this I will try it!

If it does happen, then /OE is /CE and we can use the 65816 /RD and /WR strobes directly. That would be very good news, and would allow a RAM to be access over the U2 bus.

Oh and if it wasn't mentioned already, the mask ROM is in byte mode so the data bus is just 8 bits.
I dont think anybody tried that - perhaps caitsith? But anyway, I still recall you saying you had a logical analyzier hanged up to the SPC U2 bus and the data pins seemed to be input only. But of course, my memory could be faulty :P.
caitsith2
Posts: 74
Joined: Mon May 26, 2008 11:41 pm

Post by caitsith2 »

Wasn't me that had the logic analyzer. Still don't have one.
User avatar
Charles MacDonald
Posts: 16
Joined: Sat Dec 30, 2006 9:20 pm
Contact:

Post by Charles MacDonald »

Nothing like a test on The Real Thing to answer questions.

1. I can't write to whatever is at $50. OK, so officially I have no idea what it is. ;)

2. SPC7110 pin 48 is pulsed for reads AND writes to the U2 space at any location it shows up in my memory map. Wonderful!

So if we were to map a RAM there, we could use pin 48 as /CE, then 65816 /RD and /WR as RAM /OE and /WE.

On a slightly different matter:

Is there a need for logging data (of any amount) from the chip with the regular FEoEZ mask ROM installed? I know we can't change the data to generate custom sets of data for testing so the usefulness is limited. Or had one of us already done something like this?
neviksti
Posts: 205
Joined: Thu Jun 22, 2006 11:39 pm

Post by neviksti »

Charles MacDonald wrote:50 : 64K SPC7110 internal RAM :D
51-57 : Unused (as above)
58 : SPC7110 data port
59-7D : Unused (as above)
Thanks for joining in!
It's really great to get information from you first hand, thanks for sharing with us.

What is different between bank 50, and 58? I want to make sure I understand.
Charles MacDonald wrote:The SRAM is the 8K RAM chip on the PCB. The internal RAM is, I assume, internal the SPC7110 because there is no other RAM on the board to account for it, and it makes sense the chip would have some place to store its results.
I think it is reasonable that there is some kind of FIFO for the decompressor (maybe that 'ready' signal is just saying it has filled the FIFO starting with the requested data). But I see no advantage of random access memory that would be worth spending on 64kB worth.

I agree with Kammedo that it seems weird there are two means of accessing what appears to be the same thing, so maybe I'm missing something. But I also don't see the use in the strange adjust/increment features either.
Charles MacDonald wrote:Originally I assumed bank $50 was an auto-incrementing data port mapped to every byte, which would facilitate DMA transfers, block transfers, etc. out of that bank to work RAM or PPU RAM. However in the memory map viewing program, I found the data did not change across subsequent reads (if it was a data port the auto-incrementing would change the results continuously) and the data itself was not mirrored, and was unique for 64K.
Hmmm... I should definitely try that out myself.
And how does register $480B affect this? I think that may be a key part to my not understanding.
Charles MacDonald wrote:2. SPC7110 pin 48 is pulsed for reads AND writes to the U2 space at any location it shows up in my memory map. Wonderful!

So if we were to map a RAM there, we could use pin 48 as /CE, then 65816 /RD and /WR as RAM /OE and /WE.
I am not understanding what you are suggesting here, for isn't the whole point of that extra data bus and control structure that the SPC7110 can be accessing it completely separately of what the SNES is doing? I don't think the decompresions would work anymore if the SPC7110 lost that control.

The simplest mod we came up with so far, which should let us do decompressions of custom data, was the one chip FIFO mod that was listed previously in this thread ( http://nesdev.com/bbs/viewtopic.php?p=33974#33974 ). It however requires some means to run arbitrary code with the SPC7110 cart connected (which we were going to use a copier for, but which you have already achieved a different way). Do you have a way to read/dump the SRAM on the cartridge afterwards? If so, since you appear to have the equipment to help debug such a setup if it didn't work immediately, would you be willing to try this mod for us?


In the mean time I will be setting asside questions of the memory map details for a bit (since we got decompressions working anyway), and trying to figure out what the 4th byte in the table entry does by decompressing every table entry of the form $xx $00 $00 $00 I can find in the U2 ROM. It is likely I can get all 256 combinations, or at least most of them.

Then I'll record decompressions of every possible first compressed byte, and valid "indicator byte in the table entry" value. This should be a good start of play data and won't require changing any hardware.
kammedo
Posts: 57
Joined: Wed May 28, 2008 5:43 am

Post by kammedo »

Charles MacDonald wrote:Nothing like a test on The Real Thing to answer questions.

1. I can't write to whatever is at $50. OK, so officially I have no idea what it is. ;)

2. SPC7110 pin 48 is pulsed for reads AND writes to the U2 space at any location it shows up in my memory map. Wonderful!

So if we were to map a RAM there, we could use pin 48 as /CE, then 65816 /RD and /WR as RAM /OE and /WE.
Wow that is great news! ^^ Now all we need to check is if data gets mirrored through the SPC too (but thats secondary?).
Charles MacDonald wrote: On a slightly different matter:

Is there a need for logging data (of any amount) from the chip with the regular FEoEZ mask ROM installed? I know we can't change the data to generate custom sets of data for testing so the usefulness is limited. Or had one of us already done something like this?
Neviksti had some good points about getting test data through decompressing random (but specifically) choosen locations of the U2 rom.
User avatar
Charles MacDonald
Posts: 16
Joined: Sat Dec 30, 2006 9:20 pm
Contact:

Post by Charles MacDonald »

What is different between bank 50, and 58? I want to make sure I understand.
Right now I have no idea what bank $50 is. When I was running tests over a year ago, I thought it was RAM. Who knows what I was doing right or wrong then. :)

Bank $58 has an auto incrementing data port mapped to every byte, which references compressed data in the U2 ROM. So you could set the base offset, and do a block copy (MVP/MVN) from bank $50 to elsewhere.

There is some register that does this function, so consider bank $58 to be one huge mirror of that register.
I am not understanding what you are suggesting here, for isn't the whole point of that extra data bus and control structure that the SPC7110 can be accessing it completely separately of what the SNES is doing? I don't think the decompresions would work anymore if the SPC7110 lost that control.
Originally Kammedo and I had discussed removing the U2 ROM and replacing it with RAM, so that the SNES could populate the RAM chip with test data to be decompressed. Having the SNES be able to write to the U2 bus is important as it means the RAM could be written to. Otherwise whatever memory device would be read only, and a different course of action (such as connecting an EPROM emulator in place of the mask ROM) would be necessary.

I am not familiar with the other efforts that have been made on the SPC7110, but the only thing I was interested in was finding a way to provide user-specified data for the SPC7110 to decompress.
The simplest mod we came up with so far, which should let us do decompressions of custom data, was the one chip FIFO mod that was listed previously in this thread
Great idea, how far along has this gotten?
Do you have a way to read/dump the SRAM on the cartridge afterwards? If so, since you appear to have the equipment to help debug such a setup if it didn't work immediately, would you be willing to try this mod for us?
Sort of, I made a EPROM emulator that uses dual port RAM so in theory the 65816 can write data to it, and the PC utility can save blocks of data to disk. But it depends on if the Game Genie enables the ROM during writes, and if the write strobe works with the rather 68000-centric design of the emulator. I would need to test and confirm that this works reliably first.

Two things about the FIFO mod:
steps for modification:
- cut trace to /CE on the compressed data ROM (U2), and tie pin to Vcc
- attach Vcc and GND to FIFO, and attach /XI, D8, /FL to Vcc
- attach FIFO output data lines 0-7 to U2-ROM data lines
- attach FIFO input data lines 0-7 to SRAM data lines
- attach FIFO /R to U2-ROM /OE from SPC7110
- attach FIFO /W to SRAM /CE
- attach FIFO /RESET to SNES /RESET (or RTC /CE if you want to have sofware reset capability)
If we are using SRAM /CE to trigger the write, do we know for a fact that the data bus is valid at the negative edge of /CE as that's when the data is latched by the FIFO? Or do we need to wait until /CE *and* /WR are asserted?

A pulse on FIFO /R gets the next byte out. Have we verified that when reading data for decompression specifically that the SPC7110 doesn't leave /OE asserted and just change the address? I'm not suggesting it does, but I like weeding out the edge cases beforehand.

I would like to help with this, but I have very little free time these days. I will do what I can though plan on nothing happening. :)
Post Reply