Romhacking => Programming => Topic started by: justin3009 on July 03, 2015, 09:04:26 am

Title: Compression (Again!)
Post by: justin3009 on July 03, 2015, 09:04:26 am
I'm going through the usual, Sailor Moon SuperS - Fuwa Fuwa Panic and have been trying to figure out what this routine type is.

..Not really sure if this is enough info to go on but it's a basic gist of what it does for sprites at least.

Code: [Select]
$80/D9AA A9 8F       LDA #$8F                A:1001 X:1000 Y:1000 P:eNvMxdizc ;Load bank of Portrait graphics
$80/D9AC A2 00 80    LDX #$8000              A:108F X:1000 Y:1000 P:eNvMxdizc ;Load pointer base of portrait graphics
$80/D9AF C2 20       REP #$20                A:108F X:8000 Y:1000 P:eNvMxdizc
$80/D9B1 29 FF 00    AND #$00FF              A:108F X:8000 Y:1000 P:eNvmxdizc
$80/D9B4 09 00 7F    ORA #$7F00              A:008F X:8000 Y:1000 P:envmxdizc
$80/D9B7 A0 00 00    LDY #$0000              A:7F8F X:8000 Y:1000 P:envmxdizc ;Load Y as 0000
$80/D9BA 22 31 CE 80 JSL $80CE31[$80:CE31]   A:7F8F X:8000 Y:0000 P:envmxdiZc

$80/CE31 08          PHP                     A:7F8F X:8000 Y:0000 P:envmxdiZc
$80/CE32 8B          PHB                     A:7F8F X:8000 Y:0000 P:envmxdiZc
$80/CE33 4B          PHK                     A:7F8F X:8000 Y:0000 P:envmxdiZc
$80/CE34 AB          PLB                     A:7F8F X:8000 Y:0000 P:envmxdiZc
$80/CE35 22 6D A1 80 JSL $80A16D[$80:A16D]   A:7F8F X:8000 Y:0000 P:eNvmxdizc

$80/A16D 08          PHP                     A:7F8F X:8000 Y:0000 P:eNvmxdizc
$80/A16E C2 30       REP #$30                A:7F8F X:8000 Y:0000 P:eNvmxdizc
$80/A170 8B          PHB                     A:7F8F X:8000 Y:0000 P:eNvmxdizc
$80/A171 86 0A       STX $0A    [$00:000A]   A:7F8F X:8000 Y:0000 P:eNvmxdizc ;Store base pointer of portrait graphics to 7E:000A
$80/A173 85 0C       STA $0C    [$00:000C]   A:7F8F X:8000 Y:0000 P:eNvmxdizc ;Store bank to 7E:000C
$80/A175 EB          XBA                     A:7F8F X:8000 Y:0000 P:eNvmxdizc ;Switch high and low bytes
$80/A176 64 0E       STZ $0E    [$00:000E]   A:8F7F X:8000 Y:0000 P:envmxdizc ;Store 00 to 7E:000E
$80/A178 85 10       STA $10    [$00:0010]   A:8F7F X:8000 Y:0000 P:envmxdizc ;Store RAM bank to 7E:0010?
$80/A17A 84 06       STY $06    [$00:0006]   A:8F7F X:8000 Y:0000 P:envmxdizc ;Store Y to 7E:0006
$80/A17C E2 20       SEP #$20                A:8F7F X:8000 Y:0000 P:envmxdizc
$80/A17E A9 7E       LDA #$7E                A:8F7F X:8000 Y:0000 P:envMxdizc ;Load #$7E
$80/A180 48          PHA                     A:8F7E X:8000 Y:0000 P:envMxdizc ;Push accumulator
$80/A181 AB          PLB                     A:8F7E X:8000 Y:0000 P:envMxdizc ;Pull bank register (Main bank set as $7E now)
$80/A182 C2 20       REP #$20                A:8F7E X:8000 Y:0000 P:envMxdizc
$80/A184 A9 01 20    LDA #$2001              A:8F7E X:8000 Y:0000 P:envmxdizc ;Load 2001 (?)
$80/A187 85 04       STA $04    [$00:0004]   A:2001 X:8000 Y:0000 P:envmxdizc ;Store to 7E:0004 (?)
$80/A189 A9 01 00    LDA #$0001              A:2001 X:8000 Y:0000 P:envmxdizc ;Load 0001 (?)
$80/A18C 85 08       STA $08    [$00:0008]   A:0001 X:8000 Y:0000 P:envmxdizc ;Store to 7E:0008 (?)
$80/A18E A4 06       LDY $06    [$00:0006]   A:0001 X:8000 Y:0000 P:envmxdizc ;Load Y from 7E:0006 (Counter)
$80/A190 A7 0A       LDA [$0A]  [$8F:8000]   A:0001 X:8000 Y:0000 P:envmxdiZc ;Load FDBE from $8F:8000
$80/A192 85 02       STA $02    [$00:0002]   A:BEFD X:8000 Y:0000 P:eNvmxdizc ;Store to 7E:0002
$80/A194 E6 0A       INC $0A    [$00:000A]   A:BEFD X:8000 Y:0000 P:eNvmxdizc ;Increase 7E:000A (Base pointer graphic)
$80/A196 E6 0A       INC $0A    [$00:000A]   A:BEFD X:8000 Y:0000 P:eNvmxdizc ;Increase 7E:000A (Base pointer graphic)
$80/A198 38          SEC                     A:BEFD X:8000 Y:0000 P:eNvmxdizc ;Set carry flag
$80/A199 26 02       ROL $02    [$00:0002]   A:BEFD X:8000 Y:0000 P:eNvmxdizC ;Rotate bit left 7E:0002
$80/A19B 90 2C       BCC $2C    [$A1C9]      A:BEFD X:8000 Y:0000 P:envmxdizC ;Branch to 80:A1C9 if greater than
$80/A19D 80 10       BRA $10    [$A1AF]      A:BEFD X:8000 Y:0000 P:envmxdizC ;Always branch to 80:A1AF

$80/A1AF E2 20       SEP #$20                A:BEFD X:8000 Y:0000 P:envmxdizC
$80/A1B1 A7 0A       LDA [$0A]  [$8F:8002]   A:BEFD X:8000 Y:0000 P:envMxdizC ;Load 00 from 8F:8002
$80/A1B3 A6 04       LDX $04    [$00:0004]   A:BE00 X:8000 Y:0000 P:envMxdiZC ;Load X from 7E:0004 (2001)
$80/A1B5 9D 00 00    STA $0000,x[$7E:2001]   A:BE00 X:2001 Y:0000 P:envMxdizC ;Store to 7E:0001
$80/A1B8 E8          INX                     A:BE00 X:2001 Y:0000 P:envMxdizC ;Increase X
$80/A1B9 97 0E       STA [$0E],y[$7F:0000]   A:BE00 X:2002 Y:0000 P:envMxdizC ;Store to 7F:0000
$80/A1BB C8          INY                     A:BE00 X:2002 Y:0000 P:envMxdizC ;Increase Y
$80/A1BC C8          INY                     A:BE00 X:2002 Y:0001 P:envMxdizC ;Increase Y
$80/A1BD C2 20       REP #$20                A:BE00 X:2002 Y:0002 P:envMxdizC
$80/A1BF 8A          TXA                     A:BE00 X:2002 Y:0002 P:envmxdizC ;Transfer X to A
$80/A1C0 29 FF 2F    AND #$2FFF              A:2002 X:2002 Y:0002 P:envmxdizC ;AND
$80/A1C3 85 04       STA $04    [$00:0004]   A:2002 X:2002 Y:0002 P:envmxdizC ;Store new value to 7E:0004
$80/A1C5 E6 0A       INC $0A    [$00:000A]   A:2002 X:2002 Y:0002 P:envmxdizC ;Increase 7E:000A (Base pointer graphic)
$80/A1C7 80 D6       BRA $D6    [$A19F]      A:2002 X:2002 Y:0002 P:eNvmxdizC ;Branch always to 80:A19F

$80/A19F 06 02       ASL $02    [$00:0002]   A:2002 X:2002 Y:0002 P:eNvmxdizC ;Double 7E:0002
$80/A1A1 D0 0A       BNE $0A    [$A1AD]      A:2002 X:2002 Y:0002 P:eNvmxdizc ;Break if =/= 0 to 80:A1AD
$80/A1AD 90 1A       BCC $1A    [$A1C9]      A:2002 X:2002 Y:0002 P:eNvmxdizc ;Branch to 80:A1C9 if greater than

$80/A1C9 A7 0A       LDA [$0A]  [$8F:8003]   A:2002 X:2002 Y:0002 P:eNvmxdizc ;Load 10 from 8F:8003
$80/A1CB E6 0A       INC $0A    [$00:000A]   A:0010 X:2002 Y:0002 P:envmxdizc ;Increase 7E:000A (Base pointer graphic)
$80/A1CD E6 0A       INC $0A    [$00:000A]   A:0010 X:2002 Y:0002 P:eNvmxdizc ;Increase 7E:000A (Base pointer graphic)
$80/A1CF AA          TAX                     A:0010 X:2002 Y:0002 P:eNvmxdizc ;Transfer A to X
$80/A1D0 4A          LSR A                   A:0010 X:0010 Y:0002 P:envmxdizc ;Divide accumulator
$80/A1D1 4A          LSR A                   A:0008 X:0010 Y:0002 P:envmxdizc ;Divide accumulator
$80/A1D2 F0 61       BEQ $61    [$A235]      A:0004 X:0010 Y:0002 P:envmxdizc ;Branch = to 80:A235
$80/A1D4 4A          LSR A                   A:0004 X:0010 Y:0002 P:envmxdizc ;Divide accumulator
$80/A1D5 4A          LSR A                   A:0002 X:0010 Y:0002 P:envmxdizc ;Divide accumulator
$80/A1D6 84 00       STY $00    [$00:0000]   A:0001 X:0010 Y:0002 P:envmxdizc ;Store Y to 7E:0000
$80/A1D8 09 00 20    ORA #$2000              A:0001 X:0010 Y:0002 P:envmxdizc ;OR accumulator with $2000
$80/A1DB 85 14       STA $14    [$00:0014]   A:2001 X:0010 Y:0002 P:envmxdizc ;Store to 7E:0014
$80/A1DD C9 F0 2F    CMP #$2FF0              A:2001 X:0010 Y:0002 P:envmxdizc ;Check if $2FF0
$80/A1E0 30 0E       BMI $0E    [$A1F0]      A:2001 X:0010 Y:0002 P:eNvmxdizc ;Branch if negative set to 80:A1F0

$80/A1F0 8A          TXA                     A:2001 X:0010 Y:0002 P:eNvmxdizc ;Transfer X to A
$80/A1F1 29 0F 00    AND #$000F              A:0010 X:0010 Y:0002 P:envmxdizc ;AND
$80/A1F4 1A          INC A                   A:0000 X:0010 Y:0002 P:envmxdiZc ;Increase accumulator
$80/A1F5 0A          ASL A                   A:0001 X:0010 Y:0002 P:envmxdizc ;Double accumulator
$80/A1F6 AA          TAX                     A:0002 X:0010 Y:0002 P:envmxdizc ;Transfer A to X
$80/A1F7 A5 10       LDA $10    [$00:0010]   A:0002 X:0002 Y:0002 P:envmxdizc ;Load 7E:0010
$80/A1F9 4A          LSR A                   A:8F7F X:0002 Y:0002 P:eNvmxdizc ;Divide A
$80/A1FA 90 06       BCC $06    [$A202]      A:47BF X:0002 Y:0002 P:envmxdizC ;Branch if Greater than to 80:A202
$80/A1FC BF 56 A3 80 LDA $80A356,x[$80:A358] A:47BF X:0002 Y:0002 P:envmxdizC ;Load pointer to routine data (Sprites use A3 26|A3 21|A3 1C|A3 17|A3 12)
$80/A200 80 04       BRA $04    [$A206]      A:A326 X:0002 Y:0002 P:eNvmxdizC ;Branch to 80:A206

$80/A206 85 12       STA $12    [$00:0012]   A:A326 X:0002 Y:0002 P:eNvmxdizC ;Store X to 7E:0012
$80/A208 8A          TXA                     A:A326 X:0002 Y:0002 P:eNvmxdizC ;Transfer X to A
$80/A209 4A          LSR A                   A:0002 X:0002 Y:0002 P:envmxdizC ;Divide A
$80/A20A A6 14       LDX $14    [$00:0014]   A:0001 X:0002 Y:0002 P:envmxdizc ;Load X from 7E:0014
$80/A20C A4 04       LDY $04    [$00:0004]   A:0001 X:2001 Y:0002 P:envmxdizc ;Load Y from 7E:0004
$80/A20E 54 7E 7E    MVN 7E 7E               A:0001 X:2001 Y:2002 P:envmxdizc
$80/A20E 54 7E 7E    MVN 7E 7E               A:0000 X:2002 Y:2003 P:envmxdizc
$80/A211 84 04       STY $04    [$00:0004]   A:FFFF X:2003 Y:2004 P:envmxdizc ;Store value to 7E:0004
$80/A213 C0 00 30    CPY #$3000              A:FFFF X:2003 Y:2004 P:envmxdizc ;Check Y if 3000
$80/A216 30 15       BMI $15    [$A22D]      A:FFFF X:2003 Y:2004 P:eNvmxdizc ;Branch if negative set to 80:A22D

$80/A22D A6 14       LDX $14    [$00:0014]   A:FFFF X:2003 Y:2004 P:eNvmxdizc ;Load X from 7E:0014
$80/A22F A4 00       LDY $00    [$00:0000]   A:FFFF X:2001 Y:2004 P:envmxdizc ;Load Y from 7E:0000
$80/A231 8B          PHB                     A:FFFF X:2001 Y:0002 P:envmxdizc ;Push register
$80/A232 6C 12 00    JMP ($0012)[$80:A326]   A:FFFF X:2001 Y:0002 P:envmxdizc ;Load JMP location based on 7E:0012

$80/A326 1A          INC A                   A:FFFF X:2001 Y:0002 P:envmxdizc ;Increase A
$80/A327 54 7F 7E    MVN 7E 7F               A:0000 X:2001 Y:0002 P:envmxdiZc
$80/A32A C8          INY                     A:FFFF X:2002 Y:0003 P:envmxdiZc
$80/A32B 1A          INC A                   A:FFFF X:2002 Y:0004 P:envmxdizc
$80/A32C 54 7F 7E    MVN 7E 7F               A:0000 X:2002 Y:0004 P:envmxdiZc
$80/A32F C8          INY                     A:FFFF X:2003 Y:0005 P:envmxdiZc
$80/A330 AB          PLB                     A:FFFF X:2003 Y:0006 P:envmxdizc
$80/A331 4C 9F A1    JMP $A19F  [$80:A19F]   A:FFFF X:2003 Y:0006 P:envmxdizc ;JMP back to beginning of routine

The very LAST section of code is essentially what ALL those JMP listings I have right above are, the whole 'Sprites use A3 26|A3 21|A3 1C|A3 17|A3 12' thing.  The only difference is that if it starts at A3 12, it essentially does more INC A MVN INC A MVN stuff but there's really not much more to it.

I'm confused on this as I haven't seen a game do something like this before where it just does a set of random JMPs instead of conditional branching or something.  It's different.  I can't really tell what kind of compression they use.  I haven't figured out quite yet when it starts jumping to the rest of the locations besides A3 26 yet but the sprites DEFINITELY use all those JMPS.