11 March 2016 - Forum Rules

Main Menu

Compression (Again!)

Started by justin3009, July 03, 2015, 09:04:26 AM

Previous topic - Next topic


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.

$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.
'We have to find some way to incorporate the general civilians in the plot.'

'We'll kill off children in the Juuban district with an infection where they cough up blood and are found hanging themselves from cherry blossom trees.'