The Little Mermaid/ROM map

From Data Crystal
Jump to navigation Jump to search

Chip tiny.png The following article is a ROM map for The Little Mermaid.

Page 06 (0x8000-0xBFFF)

Address in ROM: 0x18010-0x1C00F

Function 0x8000

Runs the action scripts of every object slot from lowest to highest and checks for collisions each frame.

06:8000:A5 B1     LDA $00B1   ; Check Ariel's health
06:8002:F0 3A     BEQ $803E   ; Exit if zero 
06:8004:A2 01     LDX #$01
06:8006:86 EF     STX $00EF   ; Current slot #
06:8008:A9 06     LDA #$06
06:800A:85 99     STA $0099   ; ?

06:800C:BD 00 03  LDA $0300,X 
06:800F:10 25     BPL $8036   ; Skip ahead if slot is empty
06:8011:BD A0 04  LDA $04A0,X ; Check if object is stunned
06:8014:D0 16     BNE $802C   ;  If so, skip action script

06:8016:BC 10 03  LDY $0310,X
06:8019:B9 20 85  LDA $8520,Y ; Obtain address of action script
06:801C:85 00     STA $0000   ;  from jump table
06:801E:B9 80 85  LDA $8580,Y ; 
06:8021:85 01     STA $0001
06:8023:A9 80     LDA #$80    ; Set return address
06:8025:48        PHA
06:8026:A9 2B     LDA #$2B
06:8028:48        PHA
06:8029:6C 00 00  JMP ($0000) ; Run object's action script

06:802C:E0 03     CPX #$03    ; Check if object is a bubble
06:802E:90 06     BCC $8036   ; Jump ahead if so
06:8030:20 3F 80  JSR $803F   ; Test collision with Ariel
06:8033:20 FF 80  JSR $80FF   ; Test collision with bubble

06:8036:E6 EF     INC $00EF   ; Tick up to next object slot
06:8038:A6 EF     LDX $00EF   
06:803A:E0 10     CPX #$10    ; Loop until all slots examined
06:803C:D0 CA     BNE $8008
06:803E:60        RTS -----------------------------------------

Function 0x803F

Checks if Ariel is colliding with object X and performs appropriate action if so.

06:803F:20 F2 FA  JSR $FAF2   ; Check if Ariel is colliding with object X
06:8042:B0 79     BCS $80BD   ; Exit if not

06:8044:BD C0 03  LDA $03C0,X ; Check if item has damage flag
06:8047:29 40     AND #$40    ;
06:8049:F0 73     BEQ $80BE   ; Skip to next section if not

ARIEL COLLIDES WITH DAMAGING OBJECT

06:804B:A5 3F     LDA $003F
06:804D:05 2F     ORA $002F
06:804F:D0 6C     BNE $80BD   ; Exit unless both are zero

06:8051:A5 BB     LDA $00BB
06:8053:D0 68     BNE $80BD   ; Exit if not zero

06:8055:A9 07     LDA #$07
06:8057:C5 30     CMP $0030
06:8059:F0 62     BEQ $80BD   ; Exit if Ariel is already in damage animation

ARIEL TAKES DAMAGE

06:805B:C6 B1     DEC $00B1   ; Tick down health
06:805D:D0 05     BNE $8064   ; Jump ahead if not zero

06:805F:A0 00     LDY #$00
06:8061:8C 80 04  STY $0480   ; Clear Parameter 3

06:8064:A4 30     LDY $0030
06:8066:8C 60 04  STY $0460   ; Preserve Ariel's previous action phase
06:8069:85 30     STA $0030   ; Set damage animation
06:806B:A9 1D     LDA #$1D
06:806D:20 A0 FC  JSR $FCA0
06:8070:C0 04     CPY #$04
06:8072:F0 27     BEQ $809B
06:8074:C0 05     CPY #$05
06:8076:F0 23     BEQ $809B
06:8078:A9 08     LDA #$08
06:807A:8D 30 04  STA $0430
06:807D:A9 00     LDA #$00
06:807F:8D 18 04  STA $0418
06:8082:8D 48 04  STA $0448
06:8085:8D 60 04  STA $0460
06:8088:C0 02     CPY #$02
06:808A:D0 0F     BNE $809B
06:808C:8C 60 04  STY $0460
06:808F:AC B0 03  LDY $03B0
06:8092:30 29     BMI $80BD
06:8094:8D A0 03  STA $03A0
06:8097:8D B0 03  STA $03B0
06:809A:60        RTS -----------------------------------------
06:809B:A9 00     LDA #$00
06:809D:85 3A     STA $003A
06:809F:8D 80 03  STA $0380
06:80A2:A9 01     LDA #$01
06:80A4:8D 90 03  STA $0390
06:80A7:A9 10     LDA #$10
06:80A9:8D 70 04  STA $0470
06:80AC:A9 01     LDA #$01
06:80AE:8D D0 03  STA $03D0
06:80B1:AD 00 04  LDA $0400
06:80B4:29 40     AND #$40
06:80B6:F0 21     BEQ $80D9
06:80B8:A9 02     LDA #$02
06:80BA:8D D0 03  STA $03D0
06:80BD:60        RTS -----------------------------------------

ARIEL COLLIDES WITH CARRYABLE OBJECT

06:80BE:A5 3A     LDA $003A
06:80C0:05 30     ORA $0030
06:80C2:D0 15     BNE $80D9
06:80C4:BD 10 03  LDA $0310,X 
06:80C7:C9 30     CMP #$30    ; Check if object is shell
06:80C9:F0 0C     BEQ $80D7   ; If so, set as carried object
06:80CB:C9 02     CMP #$02    ; Check if object is bubble
06:80CD:D0 0A     BNE $80D9   ; If not, exit

06:80CF:86 3A     STX $003A   ; Set bubble as carried object
06:80D1:A9 00     LDA #$00
06:80D3:9D 80 04  STA $0480,X ; Set bubble's parameter 3 as zero
06:80D6:60        RTS -----------------------------------------
06:80D7:86 3A     STX $003A
06:80D9:60        RTS -----------------------------------------

Function 0x81C4

06:81C4:86 04     STX $0004   ; Temp storage for current object slot
06:81C6:BD 00 04  LDA $0400,X ; Object orientation
06:81C9:30 03     BMI $81CE
06:81CB:4C 84 82  JMP $8284   
06:81CE:A9 00     LDA #$00    
06:81D0:85 07     STA $0007
06:81D2:BD C0 03  LDA $03C0,X ; 
06:81D5:29 1F     AND #$1F
06:81D7:C9 02     CMP #$02
06:81D9:F0 04     BEQ $81DF
06:81DB:C9 03     CMP #$03
06:81DD:D0 04     BNE $81E3
06:81DF:A9 08     LDA #$08
06:81E1:85 07     STA $0007
06:81E3:A0 0F     LDY #$0F
06:81E5:BD 60 03  LDA $0360,X ; Object y-position low byte
06:81E8:38        SEC
06:81E9:E5 FA     SBC $00FA
06:81EB:B0 03     BCS $81F0
06:81ED:E9 0F     SBC #$0F
06:81EF:18        CLC
06:81F0:85 05     STA $0005
06:81F2:BD 70 03  LDA $0370,X ; Object y-position high byte
06:81F5:E5 FB     SBC $00FB
06:81F7:29 01     AND #$01
06:81F9:F0 03     BEQ $81FE
06:81FB:4C 84 82  JMP $8284
06:81FE:C4 04     CPY $0004
06:8200:F0 7A     BEQ $827C
06:8202:B9 00 03  LDA $0300,Y
06:8205:10 75     BPL $827C
06:8207:B9 00 04  LDA $0400,Y
06:820A:10 70     BPL $827C
06:820C:29 04     AND #$04
06:820E:D0 6C     BNE $827C
06:8210:B9 C0 03  LDA $03C0,Y
06:8213:29 40     AND #$40
06:8215:F0 65     BEQ $827C
06:8217:BE 10 03  LDX $0310,Y
06:821A:BD C0 84  LDA $84C0,X
06:821D:F0 5D     BEQ $827C
06:821F:B9 A0 04  LDA $04A0,Y
06:8222:D0 58     BNE $827C
06:8224:B9 C0 03  LDA $03C0,Y
06:8227:29 1F     AND #$1F
06:8229:AA        TAX
06:822A:BD 80 FB  LDA $FB80,X
06:822D:18        CLC
06:822E:65 07     ADC $0007
06:8230:85 02     STA $0002
06:8232:C6 02     DEC $0002
06:8234:BD 60 FB  LDA $FB60,X
06:8237:18        CLC
06:8238:65 07     ADC $0007
06:823A:85 03     STA $0003
06:823C:A6 04     LDX $0004
06:823E:B9 30 03  LDA $0330,Y
06:8241:38        SEC
06:8242:FD 30 03  SBC $0330,X
06:8245:48        PHA
06:8246:B9 40 03  LDA $0340,Y
06:8249:FD 40 03  SBC $0340,X
06:824C:68        PLA
06:824D:B0 04     BCS $8253
06:824F:49 FF     EOR #$FF
06:8251:69 01     ADC #$01
06:8253:C5 02     CMP $0002
06:8255:B0 25     BCS $827C
06:8257:B9 60 03  LDA $0360,Y
06:825A:38        SEC
06:825B:E5 FA     SBC $00FA
06:825D:B0 03     BCS $8262
06:825F:E9 0F     SBC #$0F
06:8261:18        CLC
06:8262:85 1F     STA $001F
06:8264:B9 70 03  LDA $0370,Y
06:8267:E5 FB     SBC $00FB
06:8269:29 01     AND #$01
06:826B:D0 0F     BNE $827C
06:826D:A5 1F     LDA $001F
06:826F:38        SEC
06:8270:E5 05     SBC $0005
06:8272:B0 04     BCS $8278
06:8274:49 FF     EOR #$FF
06:8276:69 01     ADC #$01
06:8278:C5 03     CMP $0003
06:827A:90 12     BCC $828E
06:827C:88        DEY
06:827D:C0 02     CPY #$02
06:827F:F0 03     BEQ $8284
06:8281:4C FE 81  JMP $81FE
06:8284:A6 04     LDX $0004
06:8286:38        SEC
06:8287:60        RTS -----------------------------------------

Data Table 0x8520

Jump table for object action functions

Action # Address Description
0x00 0x85E0 Blank (used for Ariel)
0x01 0x85E1 Thrown objects
0x02 0x888F Enemy in bubble
0x03 0x8A14 Fish, Type 1
0x04 0x867A
0x05 0x8A65 Seahorse
0x06 0x8A9B
0x07 0x8BDC
0x08 0x8BE2 Spitting fish
0x09 0x8CA3
0x0A 0x8CBA Octopus
0x0B 0x8DC5 Octopus' rock
0x0C 0x9BA7 Stage 1 Boss (Shark): Sending Fish
0x0D 0x9CC4 Stage 1 Boss (Shark): Dashing
0x0E 0x9D37 Fish (Stage 1 Boss fight)
0x0F 0xA3B3 Cannon (Stage 4 Boss fight)
0x10 0x8F89
0x11 0x8FC7
0x12 0x9046 Fish, Type 2
0x13 0xAF50
0x14 0xAF50
0x15 0x908F Crab (Stage 2 Boss fight)
0x16 0x91D9 Tiny fish (following Ariel)
0x17 0x913F
0x18 0x913F
0x19 0x913F
0x1A 0x913F
0x1B 0x913F
0x1C 0x92A9 Sleeper fish
0x1D 0x9229 Tiny fish (default action)
0x1E 0x9367
0x1F 0x9274 Tiny fish (quad pattern)
0x20 0x940C Shrimp
0x21 0x9460 Poor Unfortunate Soul (Stage 5)
0x22 0x9461 Starfish spawner
0x23 0x954F Starfish (shooting upward)
0x24 0x9604 Frozen fish
0x25 0x908F Helmet crab
0x26 0x869D Crab (walking)
0x27 0x86C1 Crab (ducking/falling)
0x28 0x86F1
0x29 0x8715
0x2A 0x9D3A Stage 3 Boss (Walrus): Default
0x2B 0x9EC7 Stage 3 Boss (Walrus): Dropping item
0x2C 0x9F60 Stage 2 Boss (Eel) #1
0x2D 0x9F60 Stage 2 Boss (Eel) #2
0x2E 0xA1CF Stage 4 Boss (Seahorse)
0x2F 0xA324 Fish (Stage 4 Boss fight)
0x30 0x986D Carried item
0x31 0x97D5
0x32 0x97D5
0x33 0x97D5
0x34 0x9A36
0x35 0x9A36
0x36 0x9A11
0x37 0x87EE
0x38 0x998B Red Orb
0x39 0x998B Green Orb
0x3A 0x9A69
0x3B 0x9A69
0x3C 0x8DCB Volcano
0x3D 0x878B
0x3E 0xA63D
0x3F 0x888E
0x40 0x888E Water splash
0x41 0x8EE3
0x42 0x877D End-of-stage jar
0x43 0x8DCB Upside-down volcano
0x44 0x8E8C Volcanic rock
0x45 0x9654
0x46 0x96E1
0x47 0xA3D9 Stage 5 Boss (Ursula 1)
0x48 0xA54F Enemy Spawn 1 (Stage 5 Boss fight)
0x49 0xA5F0 Enemy Spawn 2 (Stage 5 Boss fight)
0x4A 0xA5F6 Orb (Stage 5 Boss fight)
0x4B 0x8F6E
0x4C 0x876B
0x4D 0x9AA1 Hidden item (?)
0x4E 0x9AA1 Hidden item (?)
0x4F 0x9AA1 Hidden item (?)
0x50 0x9AA1 Hidden item (?)
0x51 0x9AA1 Hidden item (?)
0x52 0x9B0A Flounder
0x53 0x9B0A
0x54 0x9B0A
0x55 0x9B0A
0x56 0x9B0A
0x57 0xA692 Stage 6 Boss (Ursula 2)
0x58 0xA83E Fish (Stage 6 Boss fight)
0x59 0xA879
0x5A 0xA0D8 Crab spawner (Stage 2 Boss fight)
0x5B 0xA324
0x5C 0x8821
0x5D 0x8872
0x5E 0x887F
0x5F 0x888E Urchin (Stage 4 Boss fight)

Function 0x85E0

Action script 0x00 (Ariel)

06:85E0:60        RTS -----------------------------------------

Function 0x85E1

Action script 0x01 (Thrown objects)

06:85E1:20 C4 81  JSR $81C4 
06:85E4:B0 0A     BCS $85F0 
06:85E6:BD 30 04  LDA $0430,X ; Animation loop
06:85E9:C9 40     CMP #$40    ; Check if shell
06:85EB:D0 F3     BNE $85E0   
06:85ED:4C 47 86  JMP $8647   ; Function that handles thrown shell
06:85F0:20 35 D5  JSR $D535
06:85F3:B0 06     BCS $85FB
06:85F5:A9 00     LDA #$00
06:85F7:9D 00 03  STA $0300,X
06:85FA:60        RTS -----------------------------------------
06:85FB:BD 30 04  LDA $0430,X
06:85FE:C9 40     CMP #$40
06:8600:F0 1D     BEQ $861F
06:8602:A0 08     LDY #$08
06:8604:20 B9 FC  JSR $FCB9
06:8607:B0 0E     BCS $8617
06:8609:A0 06     LDY #$06
06:860B:20 CC FC  JSR $FCCC
06:860E:A5 10     LDA $0010
06:8610:F0 05     BEQ $8617
06:8612:B0 03     BCS $8617
06:8614:4C 4E 98  JMP $984E
06:8617:20 71 83  JSR $8371
06:861A:A9 1B     LDA #$1B
06:861C:4C A0 FC  JMP $FCA0
06:861F:A0 08     LDY #$08
06:8621:20 B9 FC  JSR $FCB9
06:8624:20 4E 98  JSR $984E
06:8627:90 13     BCC $863C
06:8629:A5 BE     LDA $00BE
06:862B:C9 30     CMP #$30
06:862D:D0 18     BNE $8647
06:862F:A5 1A     LDA $001A
06:8631:D0 46     BNE $8679
06:8633:20 BA E7  JSR $E7BA
06:8636:20 64 FE  JSR $FE64
06:8639:4C 47 86  JMP $8647
06:863C:A0 06     LDY #$06
06:863E:20 CC FC  JSR $FCCC
06:8641:A5 10     LDA $0010
06:8643:F0 02     BEQ $8647
06:8645:90 32     BCC $8679
06:8647:BD D0 03  LDA $03D0,X
06:864A:29 08     AND #$08
06:864C:F0 14     BEQ $8662
06:864E:BD 60 03  LDA $0360,X
06:8651:38        SEC
06:8652:E5 FA     SBC $00FA
06:8654:B0 02     BCS $8658
06:8656:E9 0F     SBC #$0F
06:8658:C9 04     CMP #$04
06:865A:B0 06     BCS $8662
06:865C:A9 00     LDA #$00
06:865E:9D 00 03  STA $0300,X
06:8661:60        RTS -----------------------------------------
06:8662:A9 04     LDA #$04
06:8664:9D D0 03  STA $03D0,X
06:8667:A9 00     LDA #$00
06:8669:9D A0 03  STA $03A0,X
06:866C:9D B0 03  STA $03B0,X
06:866F:A9 81     LDA #$81
06:8671:9D 00 03  STA $0300,X
06:8674:A9 30     LDA #$30
06:8676:9D 10 03  STA $0310,X
06:8679:60        RTS -----------------------------------------

Page 07 (0xC000-0xFFFF)

Location in ROM: 0x1C010-0x2000F

Function 0xC250

Advance random number generator each frame

07:C250:A2 00     LDX #$00
07:C252:A0 04     LDY #$04
07:C254:B5 E4     LDA $E4,X
07:C256:29 02     AND #$02
07:C258:85 00     STA $0000
07:C25A:B5 E5     LDA $E5,X
07:C25C:29 02     AND #$02
07:C25E:45 00     EOR $0000 ; If 0x02 bits of 0xE4 and 0xE5
07:C260:18        CLC       ;  are the same, highest bit of
07:C261:F0 01     BEQ $C264 ;   new RNG value will be zero.
07:C263:38        SEC       ;    Otherwise, it will be one.
07:C264:76 E4     ROR $E4,X ;     Then shift all previous bits right.
07:C266:E8        INX
07:C267:88        DEY
07:C268:D0 FA     BNE $C264
07:C26A:60        RTS -----------------------------------------

Function 0xFFC8

Set RAM bank 0x8000-0xBFFF to Page A

07:FFC8:AA        TAX
07:FFC9:9D DE FF  STA $FFDE,X
07:FFCC:60        RTS -----------------------------------------

Function 0xFFCD

Set RAM bank 0x8000-0xBFFF to Page A, retaining X/Y values

Store Page # to 0x9B/0x9C?

07:FFCD:85 9B     STA $009B
07:FFCF:85 BF     STA $00BF
07:FFD1:86 9C     STX $009C
07:FFD3:84 9D     STY $009D
07:FFD5:AA        TAX
07:FFD6:9D DE FF  STA $FFDE,X
07:FFD9:A6 9C     LDX $009C
07:FFDB:A4 9D     LDY $009D
07:FFDD:60        RTS -----------------------------------------

Data Table 0xFFDE=

Used by functions 0xFFC8 and 0xFFCD for bank switching.

See here for more info.

07:FFDE:00
07:FFDF:01
07:FFE0:02
07:FFE1:03
07:FFE2:04
07:FFE3:05
07:FFE4:06