DSP2

Summary

Not yet.

I have got almost all information about DSP2 from http://users.tpg.com.au/trauma/dsp/dsp2.html. And I thanks much for essential information there.

About DSP2 Gamepaks, Copyright Snes9x DSP Team 2003-2004. Maintained by Overload. (Added on May 03, 2004)

Anyway, this document is published without its author's recommendation/permission. (Added on May 03, 2004)

Journey to implement DSP2 on ZSNES?

Disclaimer

This document does NOT represent anything about official ZSNES developer's intention.

This is only my trial and official ZSNES developer team do NOT affiliate with this plan at all!

Acquire footprint

Necessity of that work

I had prepared well workable footprint decoder. In other words, it is limited SNES Disassembler.

General disassembler decodes the binary codes from first to last with tweak able options.

For some cases, it doesn't produce useful assembler codes, because 65816 processor proper spec has wit to trick the disassembler.

It means some of all required information is not available for disassembler when it tries to disassemble.

For example, byte codes of LDA opecode has 2 bytes in 8-bit mode, it has 3 bytes in 16-bit mode. That X-bit mode is selected by running program in game rom. However there may be possible to read the changes of X-bit mode by processing intelligent disassembling, usually program uses jump or likeness to branch the running position. In this case, it is very difficult to track the actual status with branch able codes. So, this information is not available while disassembling and it tricks disassembler.

My customized version of ZSNES will produce the footprints for the decoder.

To collect footprint with the ZSNES, I had to play DM and walk around in the game for a while.

Sample

Next partial lines shows from my one. The decoder internally combines the footprint into disassembled assembler code.

00/8000|18          |      1|CLC 
00/8001|FB          |      1|XCE 
00/8002|D8          |      1|CLD 
00/8003|C2 30       |      1|REP #$30 
00/8005|A2 FF       |      1|LDX #$1FFF 
00/8008|9A          |      1|TXS 
00/8009|F4 00 00    |      1|PEA 
00/800C|AB          |      1|PLB 
00/800D|AB          |      1|PLB 
00/800E|A9 00       |      1|LDA #$0000 
00/8011|5B          |      1|TCD 
00/8012|E2 20       |      1|SEP #$20 
00/8014|A9 0F       |      1|LDA #$0F 
00/8016|8F 00 80 3F |      1|STA $3F8000 
00/801A|8F 00 80 3F |      1|STA $3F8000 
00/801E|8F 00 80 3F |      1|STA $3F8000 
00/8022|8F 00 80 3F |      1|STA $3F8000 
00/8026|8F 00 80 3F |      1|STA $3F8000 
00/802A|8F 00 80 3F |      1|STA $3F8000 
00/802E|A9 00       |      1|LDA #$00 
00/8030|8D 81 21    |      1|STA $2181 
00/8033|8D 82 21    |      1|STA $2182 
00/8036|8D 83 21    |      1|STA $2183 
00/8039|A2 00       |      1|LDX #$0000 
              L1.1:
00/803C|8D 80 21    |  65536|STA $2180 
00/803F|8D 80 21    |  65536|STA $2180 
00/8042|CA          |  65536|DEX 
00/8043|D0 F7       |  65536|BNE $803C ; To L1.1-1

This shows address, byte codes, encountered count, opecode and operand. For some cases, there are also labels.

My hack code

Where have I inserted my codes into ZSNES?

%macro endloop 0
    mov bl,[esi]
    inc esi
    sub dh,[cpucycle+ebx]
    jc %%cpuover
    Hack_Enter_Now
    jmp dword near [edi+ebx*4]
%%cpuover
    ret
%endmacro

I have inserted much Hack_Enter_Now macros before it uses jump or call to run emulated codes.

About implement of Hack_Enter_Now, you should check it in you own way.

Find byte codes that comm. with DSP-2

How to

I have footprint, so it is time to search possible codes and modify it in order to prevent the game from providing collect result.

In concrete; there is available DSP-2 info, and you can know that there are some commands and they are started by single byte. find some legends, for example, a command 01H. To have comm. with DSP,  there is only way, just writing it to memory. You find some codes like LDA #$01. And sequent code stores register A in possible DSP memory address? If so, changes the command with meaningless command like 0FH -- NOP. now it is turn to run S9X. S9X shows the strange result you expect? If so, you seem to succeed to locate DSP comm. code.

The client code

Later shows the code that sends command byte to DSP.

Command 01H

Access from 00/98B1 and 00/9A30.

00/98AF|A9 01       |  16800|LDA #$01 
              L30.18:
00/98B1|8F 00 80 3F |  16800|STA $3F8000 
              L30.19:
00/98B5|C2 20       |  16800|REP #$20 

00/9A2E|A9 01       |     70|LDA #$01 
00/9A30|8F 00 80 3F |     70|STA $3F8000 
00/9A34|C2 20       |     70|REP #$20 

Command 03H

Access from 04/87EC.

04/87EA|A9 03       |    211|LDA #$03 
04/87EC|8F 00 80 3F |    211|STA $3F8000 

Command 05H

Access from 04/8871.

04/886F|A9 05       |  11072|LDA #$05 
              L30.368:
04/8871|8F 00 80 3F |  11072|STA $3F8000 

Command 09H

Access from 04/86B7.

04/86B5|A9 09       |    265|LDA #$09 
04/86B7|8F 00 80 3F |    265|STA $3F8000 

Command 0DH

Access from 04/84BF.

04/84BD|A9 0D       |   1436|LDA #$0D 
04/84BF|8F 00 80 3F |   1436|STA $3F8000 

Command 0FH

Too much to show, omitted.

Technical hints to implement

Terms

Bitmap

For Windows developer, it is just 4-bit packed pixel bitmap image.
A byte has two pixels.
The upper 4-bits for first pixel, the lower 4-bit for second pixel.

Bitplane

Unknown for me.

Command 0FH

Input byte(0FH)
Output No

Just no-op.

Command 09H

Input byte(09H) word(nibble1) word(nibble2)
Output dword(?)

Unknown for me.

My implement seems to return (float)(nibble1 * nibble2).

Command 01H

Input byte(01H) byte(bitmap1[32])
Output byte(result_bitplane[32])

Convert bitmap to bit plane?

I have just made a conversion table.
The cell format is "source byte/source bit #".
The header column and row show destination byte and bit #.

Or you'll be able to get this table with next expressions.

int v = src_bit + 8 * src_byte;
int dst_byte = (((v & 2) != 0) ? 16 : 0) + (v & 1) + 2 * (v / 32);
int dst_bitn = ((((v & 31) / 4) & 6) ^ 6) + (((v & 31) / 4) & 1);

Command 03H

Input byte(03H) byte(color_key)
Output No

Select a new color key.

Command 05H

Input byte(05H) byte(n) byte(bitmap1[n]) byte(bitmap2[n])
Output byte(result_bitmap[n])

Combine the two bitmaps and produce a new bitmap.

The bitmap1 is main plane. You are to overlap the bitmap2 as overlay plane. Any pixels having color key in bitmap2 cause transparent action. It is all.

Command 0DH

Input byte(0DH) byte(n1) byte(n2) byte(bitmap1[n1/2])
Output byte(result_bitmap[n2/2])

Stretch the bitmap1 and produce a new bitmap.

I don't know whether this is for byte-oriented stretch or pixel-oriented stretch.

Command 06H

Input byte(06H) byte(n1) byte(bitmap1[n1])
Output byte(result_bitmap[n1])

Mirror the bitmap.

This is for pixel-oriented mirror operation.

Appendix

Some footprint of DSP2

Some are here.

Legend Description
WB
Write-byte
RB
Read-byte
RW
Read-word
[xx/xxxx]
PB/PC then
!$xxxx 
Address for DSP

Command 01H

WB 01    [00/98B1] !$8000
-- -- 01 [00/98B1]
WB 88    [00/98BF] !$8000
WB 88    [00/98BF] !$8001
WB 88    [00/98BF] !$8002
WB 88    [00/98BF] !$8003
WB 66    [00/98CD] !$8004
WB 66    [00/98CD] !$8005
WB 66    [00/98CD] !$8006
WB 6F    [00/98CD] !$8007
WB 6E    [00/98D9] !$8008
WB 66    [00/98D9] !$8009
WB DE    [00/98D9] !$800A
WB EE    [00/98D9] !$800B
WB 6E    [00/98E5] !$800C
WB 6D    [00/98E5] !$800D
WB DE    [00/98E5] !$800E
WB A8    [00/98E5] !$800F
WB D8    [00/98F1] !$8010
WB 8A    [00/98F1] !$8011
WB AC    [00/98F1] !$8012
WB EE    [00/98F1] !$8013
WB EA    [00/98FD] !$8014
WB AA    [00/98FD] !$8015
WB D6    [00/98FD] !$8016
WB 6D    [00/98FD] !$8017
WB 6D    [00/9909] !$8018
WB ED    [00/9909] !$8019
WB DE    [00/9909] !$801A
WB EE    [00/9909] !$801B
WB 6E    [00/9915] !$801C
WB EE    [00/9915] !$801D
WB 6E    [00/9915] !$801E
WB EE    [00/9915] !$801F
RB 00    [00/9920] !$8000
RB 00    [00/9920] !$8001
RB 01    [00/9920] !$8002
RB FF    [00/9920] !$8003
RB 08    [00/9920] !$8004
RB F7    [00/9920] !$8005
RB 18    [00/9920] !$8006
RB E6    [00/9920] !$8007
RB 80    [00/9920] !$8008
RB 1B    [00/9920] !$8009
RB 09    [00/9920] !$800A
RB F6    [00/9920] !$800B
RB 58    [00/9920] !$800C
RB A7    [00/9920] !$800D
RB 00    [00/9920] !$800E
RB FF    [00/9920] !$800F
RB 00    [00/9920] !$8010
RB FF    [00/9920] !$8011
RB FF    [00/9920] !$8012
RB 01    [00/9920] !$8013
RB FF    [00/9920] !$8014
RB 4F    [00/9920] !$8015
RB FC    [00/9920] !$8016
RB 5F    [00/9920] !$8017
RB 87    [00/9920] !$8018
RB FF    [00/9920] !$8019
RB 8F    [00/9920] !$801A
RB F9    [00/9920] !$801B
RB FF    [00/9920] !$801C
RB 7F    [00/9920] !$801D
RB FF    [00/9920] !$801E
RB 77    [00/9920] !$801F

Command 03H

WB 03    [04/87EC] !$8000
-- -- 03 [04/87EC]
WB 0A    [04/87F5] !$8000

Command 05H

WB 05    [04/8871] !$8000
-- -- 05 [04/8871]
WB 04    [04/8876] !$8000
WB 00    [04/8888] !$8000
WB CC    [04/8888] !$8001
WB CC    [04/8888] !$8002
WB CC    [04/8888] !$8003
WB 00    [04/8893] !$8000
WB AA    [04/8893] !$8001
WB AA    [04/8893] !$8002
WB AA    [04/8893] !$8003
RW 00 00 [04/8898] !$C000
RB 00    [04/88A8] !$8000
RB CC    [04/88A8] !$8001
RB CC    [04/88A8] !$8002
RB CC    [04/88A8] !$8003

Command 06H

WB 06    [04/9056] !$8000
-- -- 06 [04/9056]
WB 28    [04/905C] !$8000
WB 77    [04/906B] !$8000
WB 77    [04/906B] !$8001
WB 77    [04/906B] !$8002
WB 77    [04/906B] !$8003
WB 77    [04/906B] !$8004
WB 77    [04/906B] !$8005
WB 77    [04/906B] !$8006
WB 77    [04/906B] !$8007
WB 77    [04/906B] !$8008
WB 77    [04/906B] !$8009
WB 77    [04/906B] !$800A
WB 77    [04/906B] !$800B
WB 77    [04/906B] !$800C
WB 77    [04/906B] !$800D
WB 77    [04/906B] !$800E
WB 77    [04/906B] !$800F
WB 77    [04/906B] !$8010
WB 77    [04/906B] !$8011
WB 77    [04/906B] !$8012
WB 57    [04/906B] !$8013
WB 77    [04/906B] !$8014
WB 85    [04/906B] !$8015
WB 77    [04/906B] !$8016
WB 77    [04/906B] !$8017
WB 77    [04/906B] !$8018
WB 79    [04/906B] !$8019
WB 57    [04/906B] !$801A
WB 98    [04/906B] !$801B
WB 77    [04/906B] !$801C
WB 78    [04/906B] !$801D
WB 88    [04/906B] !$801E
WB 77    [04/906B] !$801F
WB 77    [04/906B] !$8020
WB 77    [04/906B] !$8021
WB 77    [04/906B] !$8022
WB 00    [04/906B] !$8023
WB 00    [04/906B] !$8024
WB 00    [04/906B] !$8025
WB 00    [04/906B] !$8026
WB 00    [04/906B] !$8027
RB 00    [04/9074] !$8000
RB 00    [04/9074] !$8001
RB 00    [04/9074] !$8002
RB 00    [04/9074] !$8003
RB 00    [04/9074] !$8004
RB 77    [04/9074] !$8005
RB 77    [04/9074] !$8006
RB 77    [04/9074] !$8007
RB 77    [04/9074] !$8008
RB 88    [04/9074] !$8009
RB 87    [04/9074] !$800A
RB 77    [04/9074] !$800B
RB 89    [04/9074] !$800C
RB 75    [04/9074] !$800D
RB 97    [04/9074] !$800E
RB 77    [04/9074] !$800F
RB 77    [04/9074] !$8010
RB 77    [04/9074] !$8011
RB 58    [04/9074] !$8012
RB 77    [04/9074] !$8013
RB 75    [04/9074] !$8014
RB 77    [04/9074] !$8015
RB 77    [04/9074] !$8016
RB 77    [04/9074] !$8017
RB 77    [04/9074] !$8018
RB 77    [04/9074] !$8019
RB 77    [04/9074] !$801A
RB 77    [04/9074] !$801B
RB 77    [04/9074] !$801C
RB 77    [04/9074] !$801D
RB 77    [04/9074] !$801E
RB 77    [04/9074] !$801F
RB 77    [04/9074] !$8020
RB 77    [04/9074] !$8021
RB 77    [04/9074] !$8022
RB 77    [04/9074] !$8023
RB 77    [04/9074] !$8024
RB 77    [04/9074] !$8025
RB 77    [04/9074] !$8026
RB 77    [04/9074] !$8027

Command 09H

WB 09    [04/86B7] !$8000
-- -- 09 [04/86B7]
WB 00    [04/86BD] !$8000
WB 00    [04/86C3] !$8000
WB 54    [04/86C9] !$8000
WB 00    [04/86CF] !$8000
RB 00    [04/86D3] !$8000
RB 00    [04/86D8] !$8000
RB 00    [04/86DE] !$8000
RB 00    [04/86E2] !$8000

Command 0DH

WB 0D    [04/84BF] !$8000
-- -- 0D [04/84BF]
WB 6C    [04/84C5] !$8000
WB 46    [04/84CE] !$8000
WB 77    [04/84DE] !$8000
WB 77    [04/84DE] !$8001
WB 77    [04/84DE] !$8002
WB 77    [04/84DE] !$8003
WB 77    [04/84DE] !$8004
WB 77    [04/84DE] !$8005
WB 77    [04/84DE] !$8006
WB 77    [04/84DE] !$8007
WB 77    [04/84DE] !$8008
WB 77    [04/84DE] !$8009
WB 77    [04/84DE] !$800A
WB 77    [04/84DE] !$800B
WB 77    [04/84DE] !$800C
WB 77    [04/84DE] !$800D
WB 77    [04/84DE] !$800E
WB 77    [04/84DE] !$800F
WB 77    [04/84DE] !$8010
WB 77    [04/84DE] !$8011
WB 77    [04/84DE] !$8012
WB 77    [04/84DE] !$8013
WB 77    [04/84DE] !$8014
WB 77    [04/84DE] !$8015
WB 77    [04/84DE] !$8016
WB 77    [04/84DE] !$8017
WB 77    [04/84DE] !$8018
WB 77    [04/84DE] !$8019
WB 77    [04/84DE] !$801A
WB 77    [04/84DE] !$801B
WB 78    [04/84DE] !$801C
WB 57    [04/84DE] !$801D
WB 77    [04/84DE] !$801E
WB 77    [04/84DE] !$801F
WB 85    [04/84DE] !$8020
WB 77    [04/84DE] !$8021
WB 77    [04/84DE] !$8022
WB 77    [04/84DE] !$8023
WB 77    [04/84DE] !$8024
WB 77    [04/84DE] !$8025
WB 79    [04/84DE] !$8026
WB 98    [04/84DE] !$8027
WB 57    [04/84DE] !$8028
WB 98    [04/84DE] !$8029
WB 57    [04/84DE] !$802A
WB 77    [04/84DE] !$802B
WB 78    [04/84DE] !$802C
WB 88    [04/84DE] !$802D
WB 88    [04/84DE] !$802E
WB 77    [04/84DE] !$802F
WB 77    [04/84DE] !$8030
WB 77    [04/84DE] !$8031
WB 77    [04/84DE] !$8032
WB 77    [04/84DE] !$8033
WB 77    [04/84DE] !$8034
WB 77    [04/84DE] !$8035
RB 00    [04/84E3] !$C000
RB 77    [04/84F7] !$8000
RB 77    [04/84F7] !$8001
RB 77    [04/84F7] !$8002
RB 77    [04/84F7] !$8003
RB 77    [04/84F7] !$8004
RB 77    [04/84F7] !$8005
RB 77    [04/84F7] !$8006
RB 77    [04/84F7] !$8007
RB 77    [04/84F7] !$8008
RB 77    [04/84F7] !$8009
RB 77    [04/84F7] !$800A
RB 77    [04/84F7] !$800B
RB 77    [04/84F7] !$800C
RB 77    [04/84F7] !$800D
RB 77    [04/84F7] !$800E
RB 77    [04/84F7] !$800F
RB 77    [04/84F7] !$8010
RB 77    [04/84F7] !$8011
RB 77    [04/84F7] !$8012
RB 57    [04/84F7] !$8013
RB 77    [04/84F7] !$8014
RB 85    [04/84F7] !$8015
RB 77    [04/84F7] !$8016
RB 77    [04/84F7] !$8017
RB 77    [04/84F7] !$8018
RB 79    [04/84F7] !$8019
RB 57    [04/84F7] !$801A
RB 98    [04/84F7] !$801B
RB 77    [04/84F7] !$801C
RB 78    [04/84F7] !$801D
RB 88    [04/84F7] !$801E
RB 77    [04/84F7] !$801F
RB 77    [04/84F7] !$8020
RB 77    [04/84F7] !$8021
RB 77    [04/84F7] !$8022

Personal Contact

mailto: danmasu-lj@infoseek.jp