Follow @CuttingRoomWiki on Twitter and TCRF on Facebook!
Notes:Atlantis no Nazo
From The Cutting Room Floor
This page contains notes for the game Atlantis no Nazo.
This page aims to be a complete disassembly of Atlantis no Nazo. Maybe putting it up here will motivate me to work on it some more. (Any changes you make will be erased when I update it unless you post them elsewhere, like here.)
*** INITIAL CODE BLOCK ***
8000: 78 SEI
8001: d8 CLD
8002: a2 3f LDX #$3f
8004: 9a TXS
8005: ae 02 20 LDX $2002 ; \ Loop until VBLANK ends
8008: 10 fb BPL .8005 ; |
800a: ae 02 20 LDX $2002 ; | twice
800d: 10 fb BPL .800a ; /
800f: a9 10 LDA #$10 ; \
8011: 8d 00 00 STA $0000 ; |
8014: 8d 00 20 STA $2000 ; | Set up the PPU
8017: a9 1e LDA #$1e ; |
8019: 8d 01 00 STA $0001 ; |
801c: 8d 01 20 STA $2001 ; /
801f: a2 01 LDX #$01 ; \
8021: a0 40 LDY #$40 ; | Zero-fill $40 (64) bytes
8023: a9 40 LDA #$40 ; | starting at $0140
8025: 20 47 84 JSR .8447 ; /
8028: a2 00 LDX #$00 ; \
802a: a0 02 LDY #$02 ; | Zero-fill $d (13) bytes
802c: a9 0d LDA #$0d ; | starting at $0002
802e: 20 47 84 JSR .8447 ; /
8031: a9 00 LDA #$00 ; \
8033: 8d 10 40 STA $4010 ; | Disable sound hardware interrupts
8036: a9 40 LDA #$40 ; |
8038: 8d 17 40 STA $4017 ; /
803b: 20 34 c7 JSR .c734 ; Initialize sound engine
803e: 20 6a 84 JSR .846a ; Soft-reset check
8041: 4c c4 80 JMP .80c4
*** NMI HANDLER ***
8044: 08 PHP
8045: 48 PHA
8046: 8e 0e 00 STX $000e
8049: 8c 0f 00 STY $000f
804c: ad 02 20 LDA $2002 ; Acknowledge VBlank
804f: ad 50 01 LDA $0150
8052: d0 03 BNE .8057
8054: 4c b5 80 JMP .80b5
8057: ad 56 01 LDA $0156
805a: f0 2f BEQ .808b
805c: ad 57 01 LDA $0157
805f: d0 2a BNE .808b
8061: a2 3f LDX #$3f ; \
8063: a0 00 LDY #$00 ; | Update palette
8065: 8e 06 20 STX $2006 ; |
8068: 8c 06 20 STY $2006 ; |
806b: b9 e0 01 LDA $01e0,Y ; |
806e: 8d 07 20 STA $2007 ; |
8071: c8 INY ; |
8072: c0 20 CPY #$20 ; |
8074: d0 f5 BNE .806b ; /
8076: a9 3f LDA #$3f
8078: 8d 06 20 STA $2006
807b: a9 00 LDA #$00
807d: 8d 06 20 STA $2006
8080: 8d 06 20 STA $2006
8083: 8d 06 20 STA $2006
8086: a9 00 LDA #$00
8088: 8d 56 01 STA $0156
808b: a9 00 LDA #$00 ; \
808d: 8d 03 20 STA $2003 ; | DMA sprites to PPU
8090: a9 07 LDA #$07 ; |
8092: 8d 14 40 STA $4014 ; /
8095: 20 2d 83 JSR .832d ; Do nothing...? (Might be link to old sprite code.)
8098: 20 f9 89 JSR .89f9 ; Screen updater
809b: ad 00 00 LDA $0000
809e: 8d 00 20 STA $2000
80a1: ae 09 00 LDX $0009
80a4: ac 05 00 LDY $0005
80a7: 8e 05 20 STX $2005
80aa: 8c 05 20 STY $2005
80ad: 20 7d c7 JSR .c77d ; Sound engine (skipping disassembly for now)
80b0: a9 00 LDA #$00
80b2: 8d 50 01 STA $0150
80b5: 20 95 84 JSR .8495 ; Decrement counters?
80b8: ce 40 01 DEC $0140
80bb: ac 0f 00 LDY $000f
80be: ae 0e 00 LDX $000e
80c1: 68 PLA
80c2: 28 PLP
80c3: 40 RTI
*** MAIN LOOP ***
80c4: a9 00 LDA #$00
80c6: 8d 51 01 STA $0151
80c9: a9 05 LDA #$05
80cb: 8d 41 01 STA $0141
80ce: a9 03 LDA #$03
80d0: 8d 4a 01 STA $014a
80d3: 20 34 c7 JSR .c734 ; Initialize sound engine
80d6: a9 04 LDA #$04 ; \ Play title screen music
80d8: 20 45 c7 JSR .c745 ; /
80db: 20 de bb JSR .bbde ; Draw title screen
80de: 20 d8 83 JSR .83d8 ; Controller setup (need to check this)
80e1: ad 4a 01 LDA $014a
80e4: d0 0a BNE .80f0
80e6: ad 07 02 LDA $0207
80e9: 29 10 AND #$10
80eb: d0 2f BNE .811c
80f0: 20 8a 84 JSR .848a ; Wait for NMI
80f3: ad 48 01 LDA $0148
80f6: d0 e6 BNE .80de
80f8: ce 48 01 DEC $0148
80fb: ce 41 01 DEC $0141
80fe: d0 de BNE .80de
8100: 20 4e 8c JSR .8c4e ; New game
8103: ad 5b 01 LDA $015b
8106: ee 5b 01 INC $015b
8109: 29 07 AND #$07
810b: aa TAX
810c: bd 62 86 LDA $8662,X ; Demo door IDs to load
810f: 8d 96 01 STA $0196
8112: 20 76 8c JSR .8c76 ; Load (demo) level
8115: a9 ff LDA #$ff
8117: 8d 81 01 STA $0181
811a: d0 28 BNE .8144
811c: a9 ff LDA #$ff
811e: 8d 48 01 STA $0148
8121: 20 4e 8c JSR .8c4e ; New game
8124: 20 f0 82 JSR .82f0 ; Enable debug codes
8127: 20 ea bc JSR .bcea ; MYSTERY ADVENTURE START..
812a: 20 34 c7 JSR .c734 ; Initialize sound
812d: a9 05 LDA #$05 ; \ Play Zone Start music
812f: 20 45 c7 JSR .c745 ; /
8132: a9 04 LDA #$04
8134: 8d 49 01 STA $0149 ; This appears to be a timer
8137: a9 00 LDA #$00 ; \ Clear pause
8139: 8d 52 01 STA $0152 ; /
813c: 20 8a 84 JSR .848a ; \
813f: ad 48 01 LDA $0148 ; | This appears to be a timer too
8142: d0 f8 BNE .813c ; /
8144: 20 c9 8f JSR .8fc9 ; Load the initial view of the zone
8147: 20 5c 90 JSR .905c Coming up next time: What does this subroutine do?
814a: a9 04 LDA #$04
814c: 8d 49 01 STA $0149
814f: 20 d8 83 JSR .83d8
8152: ad 51 01 LDA $0151
8155: f0 0d BEQ .8164
8157: ad 07 02 LDA $0207
815a: 29 10 AND #$10
815c: f0 03 BEQ .8161
815e: 4c c4 80 JMP .80c4
8161: 20 17 86 JSR .8617
8164: 20 99 82 JSR .8299
8167: 20 5c 84 JSR .845c
816a: 20 87 93 JSR .9387
816d: 20 15 8b JSR .8b15
8170: 20 9a 86 JSR .869a
8173: 20 cc 97 JSR .97cc
8176: 20 9f b9 JSR .b99f
8179: 20 c8 82 JSR .82c8
817c: 20 8e b8 JSR .b88e
817f: 20 65 ba JSR .ba65
8182: 20 6e 82 JSR .826e
8185: 20 2a b8 JSR .b82a
8188: 20 11 b4 JSR .b411
818b: 20 8a 84 JSR .848a
818e: ad 9f 01 LDA $019f
8191: f0 1d BEQ .81b0 ; This branch was always taken
8193: ad 07 02 LDA $0207 ; \
8196: 29 20 AND #$20 ; | This code did not run.
8198: f0 16 BEQ .81b0 ; |
819a: ae 9e 01 LDX $019e ; |
819d: e8 INX ; |
819e: e0 64 CPX #$64 ; |
81a0: f0 0e BEQ .81b0 ; |
81a2: 8e 9e 01 STX $019e ; |
81a5: bd e5 fe LDA $fee5,X ; |
81a8: 8d 96 01 STA $0196 ; |
81ab: a9 20 LDA #$20 ; |
81ad: 4c 1d 82 JMP .821d ; /
81b0: 20 77 85 JSR .8577
81b3: ad c3 01 LDA $01c3
81b6: f0 08 BEQ .81c0
81b8: ad 51 01 LDA $0151
81bb: d0 13 BNE .81d0
81bd: 4c d3 81 JMP .81d3
81c0: ad c2 01 LDA $01c2
81c3: f0 08 BEQ .81cd
81c5: ad 51 01 LDA $0151
81c8: d0 06 BNE .81d0
81ca: 4c 1b 82 JMP .821b
81cd: 4c 4f 81 JMP .814f
81d0: 4c c4 80 JMP .80c4
*** MAIN LOOP BRANCH A ***
81d3: a9 00 LDA #$00
81d5: 8d 52 04 STA $0452
81d8: 8d 56 04 STA $0456
81db: ad 57 04 LDA $0457
81de: f0 03 BEQ .81e3
81e0: ee 57 04 INC $0457
81e3: ad 91 01 LDA $0191
81e6: d0 30 BNE .8218
81e8: ce 94 01 DEC $0194
81eb: 10 2b BPL .8218
81ed: a9 02 LDA #$02
81ef: 8d 41 01 STA $0141
81f2: a9 50 LDA #$50
81f4: 8d 48 01 STA $0148
81f7: 20 3c 85 JSR .853c
81fa: 20 18 be JSR .be18
81fd: 20 34 c7 JSR .c734
8200: a9 06 LDA #$06
8202: 20 45 c7 JSR .c745
8205: 20 8a 84 JSR .848a
8208: ad 48 01 LDA $0148
820b: d0 f8 BNE .8205
820d: ce 48 01 DEC $0148
8210: ce 41 01 DEC $0141
8213: d0 f0 BNE .8205
8215: 4c c4 80 JMP .80c4
8218: 4c 1b 82 JMP .821b
*** MAIN LOOP BRANCH B ***
821b: a9 ff LDA #$ff
821d: 8d 48 01 STA $0148
8220: ad 16 02 LDA $0216
8223: 29 7f AND #$7f
8225: 8d 9a 01 STA $019a
8228: 20 76 8c JSR .8c76
822b: 20 02 bd JSR .bd02
822e: 20 34 c7 JSR .c734
8231: a9 05 LDA #$05
8233: 20 45 c7 JSR .c745
8236: a9 04 LDA #$04
8238: 8d 49 01 STA $0149
823b: a9 00 LDA #$00
823d: 8d 52 01 STA $0152
8240: 20 d8 83 JSR .83d8
8243: 20 99 82 JSR .8299
8246: 20 8a 84 JSR .848a
8249: ad 52 01 LDA $0152
824c: f0 05 BEQ .8253
824e: a9 45 LDA #$45
8250: 8d 48 01 STA $0148
8253: ad 48 01 LDA $0148
8256: d0 e8 BNE .8240
8258: 20 c9 8f JSR .8fc9
825b: ad 9a 01 LDA $019a
825e: 29 01 AND #$01
8260: 8d 16 02 STA $0216
8263: 20 5c 90 JSR .905c
8266: a9 04 LDA #$04
8268: 8d 49 01 STA $0149
826b: 4c 4f 81 JMP .814f
*** SUBROUTINE ***
Debug codes
82f0: a2 ff LDX #$ff ;
82f2: ad 5e 01 LDA $015e ; \
82f5: c9 21 CMP #$21 ; | Debug warp button combo:
82f7: d0 11 BNE .830a ; | Selet on either pad pressed 33 times,
82f9: ad 5c 01 LDA $015c ; | pad 2 A pressed 22 times,
82fc: c9 16 CMP #$16 ; | and hold an A and a B button
82fe: d0 0a BNE .830a ; | while starting.
8300: ad 5f 01 LDA $015f ; |
8303: c9 c0 CMP #$c0 ; |
8305: d0 03 BNE .830a ; |
8307: 8e 9f 01 STX $019f ; /
830a: ad 5c 01 LDA $015c ; \
830d: c9 0b CMP #$0b ; | Debug infinite lives button combo:
830f: d0 0a BNE .831b ; | Pad 2 A pressed 11 times,
8311: ad 5d 01 LDA $015d ; | and pad 1 B pressed 22 times.
8314: c9 16 CMP #$16 ; |
8316: d0 03 BNE .831b ; |
8318: 8e 91 01 STX $0191 ; /
831b: ad 5f 01 LDA $015f ; \
831e: c9 ec CMP #$ec ; | Debug invincibility button combo:A B Select Up Down
8320: d0 0a BNE .832c ; | Press pad 1 B 33 times,
8322: ad 5d 01 LDA $015d ; | and hold any pad A B select up down buttons
8325: c9 21 CMP #$21 ; | while starting.
8327: d0 03 BNE .832c ; |
8329: ee 57 04 INC $0457 ; /
832c: 60 RTS
*** SUBROUTINE ***
Update the PPU's OAM the hard way. Replace the first byte with EA (NOP) to make it run.
However, 18 (CLC) looks more appropriate - and works better, too!
832D 60 RTS
832E AD 59 01 LDA $0159 ; \
8331 AA TAX ; | It's too slow to update all of the OAM, so it updates 68 (104)
8332 AC 57 01 LDY $0157 ; | bytes on most frames and 28 (40) bytes when the nametable needs
8335 D0 03 BNE $833A ; | to be updated.
8337 69 40 ADC #$40 ; |
8339 18 CLC ; |
833A 69 28 ADC #$28 ; |
833C 8D 59 01 STA $0159 ; /
833F A0 40 LDY #$40 ; \ This doesn't look right. Change A0 40 to EA EA (NOP) and change
8341 8C 03 20 STY $2003 ; / 8C to 8E (STX). X is the offset into the updated object data,
8344 BD 00 07 LDA $0700,X ; so shouldn't it be the offset into OAM too?
8347 8D 04 20 STA $2004
834A E8 INX
834B EC 59 01 CPX $0159
834E D0 F4 BNE $8344
8350 60 RTS
*** SUBROUTINE ***
Enable VBlank
8351: ad 00 00 LDA $0000
8354: 09 80 ORA #$80
8356: 8d 00 00 STA $0000
8359: 8d 00 20 STA $2000
835c: ad 01 00 LDA $0001
835f: 8d 01 20 STA $2001
8362: 60 RTS
*** SUBROUTINE ***
Blackout PPU
8363: a9 00 LDA #$00 ; \ Kill rendering
8365: 8d 01 20 STA $2001 ; /
8368: ad 00 00 LDA $0000 ; \
836b: 29 7f AND #$7f ; | Disable VBlank
836d: 8d 00 00 STA $0000 ; |
8370: 8d 00 20 STA $2000 ; /
8373: a2 3f LDX #$3f ; \
8375: a0 00 LDY #$00 ; | Palette = all black
8377: 8e 06 20 STX $2006 ; | Also, typo.
837a: 8e 06 20 STX $2006 ; | The second STX should be STY.
837d: a9 0f LDA #$0f ; | It still works, though.
837f: a0 20 LDY #$20 ; | Lucky for them. :)
8381: 8d 07 20 STA $2007 ; |
8384: 88 DEY ; |
8385: d0 fa BNE .8381 ; /
8387: a9 3f LDA #$3f ; \
8389: 8d 06 20 STA $2006 ; | What?
838c: a9 00 LDA #$00 ; |
838e: 8d 06 20 STA $2006 ; |
8391: 8d 06 20 STA $2006 ; |
8394: 8d 06 20 STA $2006 ; /
8397: a9 ff LDA #$ff ; \ Update palette during next NMI
8399: 8d 56 01 STA $0156 ; /
839c: 60 RTS
*** SUBROUTINE ***
Set PPU address without affecting scroll
839d: 8e 06 20 STX $2006 ; \ Set PPU address
83a0: 8c 06 20 STY $2006 ; /
83a3: ad 09 00 LDA $0009 ; \
83a6: 8d 05 20 STA $2005 ; | Reload scroll
83a9: ad 05 00 LDA $0005 ; |
83ac: 8d 05 20 STA $2005 ; /
83af: 60 RTS
*** SUBROUTINE ***
A (very stupid) routine to clear the PPU RAM
83b0: a2 20 LDX #$20 ; Name table 0 (starting from here)
83b2: d0 02 BNE .83b6
83b4: a2 24 LDX #$24 ; Name table 1 (starting from here)
83b6: a0 00 LDY #$00
83b8: 8e 06 20 STX $2006
83bb: 8c 06 20 STY $2006
83be: a9 ff LDA #$ff ; \
83c0: a0 1e LDY #$1e ; | Wipe the name table.
83c2: a2 20 LDX #$20 ; |
83c4: 8d 07 20 STA $2007 ; |
83c7: ca DEX ; |
83c8: d0 fa BNE .83c4 ; |
83ca: 88 DEY ; |
83cb: d0 f5 BNE .83c2 ; /
83cd: a2 40 LDX #$40 ; \
83cf: a9 ff LDA #$ff ; | Then wipe the attribute table separately.
83d1: 8d 07 20 STA $2007 ; |
83d4: ca DEX ; | WHY? 8(
83d5: d0 fa BNE .83d1 ; /
83d7: 60 RTS
*** SUBROUTINE ***
Read controllers
83d8: ad 00 02 LDA $0200
83db: 8d 02 02 STA $0202
83de: ad 01 02 LDA $0201
83e1: 8d 03 02 STA $0203
83e4: a9 01 LDA #$01 ; \
83e6: 8d 16 40 STA $4016 ; | Set up controller
83e9: a9 00 LDA #$00 ; |
83eb: 8d 16 40 STA $4016 ; /
83ee: a2 08 LDX #$08 ; \
83f0: ad 16 40 LDA $4016 ; | Rotate it into $0200 and $0201
83f3: 29 06 AND #$06 ; |
83f5: c9 01 CMP #$01 ; |
83f7: 2e 00 02 ROL $0200 ; |
83fa: ad 17 40 LDA $4017 ; |
83fd: 29 03 AND #$03 ; |
83ff: c9 01 CMP #$01 ; |
8401: 2e 01 02 ROL $0201 ; |
8404: ca DEX ; |
8405: d0 e9 BNE .83f0 ; /
8407: ad 02 02 LDA $0202 ; \
840a: 4d 00 02 EOR $0200 ; | Update the controller status
840d: 2d 00 02 AND $0200 ; |
8410: 8d 04 02 STA $0204 ; |
8413: ad 03 02 LDA $0203 ; |
8416: 4d 01 02 EOR $0201 ; |
8419: 2d 01 02 AND $0201 ; |
841c: 8d 05 02 STA $0205 ; |
841f: 0d 04 02 ORA $0204 ; |
8422: 8d 07 02 STA $0207 ; |
8425: ad 00 02 LDA $0200 ; |
8428: 0d 01 02 ORA $0201 ; |
842b: 8d 06 02 STA $0206 ; /
842e: 60 RTS
*** SUBROUTINE ***
Zero-fill memory.
8447: 8e 1f 00 STX $001f
844a: 8c 1e 00 STY $001e
844d: 8d 2f 00 STA $002f
8450: a9 00 LDA #$00
8452: a8 TAY
8453: 91 1e STA ($1e),Y
8455: c8 INY
8456: cc 2f 00 CPY $002f
8459: d0 f8 BNE .8453
845b: 60 RTS
*** SUBROUTINE ***
Reset sprite data
845c: a2 00 LDX #$00
845e: 8e 55 01 STX $0155
8461: a9 f6 LDA #$f6
8463: 9d 00 07 STA $0700,X
8466: e8 INX
8467: d0 fa BNE .8463
8469: 60 RTS
*** SUBROUTINE ***
Check for soft reset, and clear the hi-score counter if the check fails
846a: a2 00 LDX #$00
846c: bd 89 84 LDA $8489,X ; Location of the check bytes
846f: dd 88 01 CMP $0188,X
8472: 9d 88 01 STA $0188,X
8475: d0 06 BNE .847d
8477: e8 INX
8478: e0 02 CPX #$02 ; Length of check data
847a: d0 f0 BNE .846c
847c: 60 RTS
847d: a0 07 LDY #$07 ; \
847f: a9 00 LDA #$00 ; | Nuke the high score
8481: 99 80 01 STA $0180,Y ; | (and also an extra byte?)
8484: 88 DEY ; |
8485: 10 fa BPL .8481 ; |
8487: 30 ee BMI .8477 ; /
*** SUBROUTINE ***
Wait for NMI.
848a: a9 ff LDA #$ff
848c: 8d 50 01 STA $0150
848f: ad 50 01 LDA $0150
8492: d0 fb BNE .848f
8494: 60 RTS
8495: a2 07 LDX #$07
8497: bd 48 01 LDA $0148,X
849a: 38 SEC
849b: e9 01 SBC #$01
849d: 90 03 BCC .84a2
849f: 9d 48 01 STA $0148,X
84a2: ca DEX
84a3: 10 f2 BPL .8497
84a5: 60 RTS
*** SUBROUTINE ***
Grab a halfscreen ID
85e8: 4a LSR A
85e9: 4a LSR A
85ea: 4a LSR A
85eb: a8 TAY
85ec: b1 ba LDA ($ba),Y
85ee: aa TAX
85ef: 60 RTS
*** SUBROUTINE ***
From 85f0, load zone CHR pages
From 85f6, set CHR pages
85f0: ae 92 01 LDX $0192
85f3: bd 7d fe LDA $fe7d,X
85f6: 8d 0a 00 STA $000a
85f9: 8d 00 60 STA $6000
85fc: 60 RTS
*** SUBROUTINE ***
Reset scroll
85fd: a9 00 LDA #$00 ; \
85ff: 8d 09 00 STA $0009 ; | Reset hardware scroll
8602: 8d 05 00 STA $0005 ; |
8605: 8d 05 20 STA $2005 ; |
8608: 8d 05 20 STA $2005 ; /
860b: ad 00 00 LDA $0000 ; \
860e: 29 fe AND #$fe ; | Also set horizontal name table to 0
8610: 8d 00 00 STA $0000 ; | (which is important when resetting the scroll)
8613: 8d 00 20 STA $2000 ; /
8616: 60 RTS
*** SUBROUTINE ***
Draw the zone
868a: 60 RTS
868b: ad 03 00 LDA $0003 ; \
868e: 8d 13 00 STA $0013 ; | To the left
8691: 38 SEC ; | (13) = (3)
8692: ad 02 00 LDA $0002 ; | (12) = (2) - 0x01
8695: e9 01 SBC #$01 ; |
8697: 4c 09 87 JMP .8709
869a: ad 02 00 LDA $0002 ; \
869d: 8d 10 00 STA $0010 ; | (2,3) -> (10,11)
86a0: ad 03 00 LDA $0003 ; | (6,7) -> (2,3)
86a3: 8d 11 00 STA $0011 ; |
86a6: ad 06 00 LDA $0006 ; | Shuffle
86a9: 8d 02 00 STA $0002 ; |
86ac: ad 07 00 LDA $0007 ; |
86af: 8d 03 00 STA $0003 ; /
86b2: ad 02 00 LDA $0002 ; \
86b5: 8d 08 00 STA $0008 ; | (8,9) = (2,3) >> 4
86b8: ad 03 00 LDA $0003 ; |
86bb: 4e 08 00 LSR $0008 ; | Divide by 16
86be: 6a ROR A ; |
86bf: 4e 08 00 LSR $0008 ; |
86c2: 6a ROR A ; |
86c3: 4e 08 00 LSR $0008 ; |
86c6: 6a ROR A ; |
86c7: 4e 08 00 LSR $0008 ; |
86ca: 6a ROR A ; |
86cb: 8d 09 00 STA $0009 ; /
86ce: 4e 00 00 LSR $0000 ; \
86d1: ad 08 00 LDA $0008 ; | Bit 0 of $0008 goes to bit 0 of
86d4: 4a LSR A ; | $0000
86d5: ad 00 00 LDA $0000 ; |
86d8: 2a ROL A ; |
86d9: 8d 00 00 STA $0000 ; /
86dc: ad 02 00 LDA $0002 ; \
86df: 29 01 AND #$01 ; | RTS if the difference between
86e1: 8d 20 00 STA $0020 ; | $0002 and $0010 is an even number.
86e4: ad 10 00 LDA $0010 ; |
86e7: 29 01 AND #$01 ; |
86e9: 4d 20 00 EOR $0020 ; |
86ec: f0 9c BEQ .868a ; /
86ee: 38 SEC ; \
86ef: ad 03 00 LDA $0003 ; | Check which direction we're going
86f2: ed 11 00 SBC $0011 ; |
86f5: ad 02 00 LDA $0002 ; |
86f8: ed 10 00 SBC $0010 ; |
86fb: 30 8e BMI .868b ; /
86fd: ad 03 00 LDA $0003 ; \
8700: 8d 13 00 STA $0013 ; | To the right
8703: 18 CLC ; | (13) = (3)
8704: ad 02 00 LDA $0002 ; | (12) = (2) + 0x11
8707: 69 11 ADC #$11 ; |
8709: 8d 12 00 STA $0012 ; /
870c: a2 20 LDX #$20 ; \
870e: a0 23 LDY #$23 ; | $12.4 ? $bf = 0x20 : $bf = 0x24
8710: 29 10 AND #$10 ; | $12.4 ? $bd = 0x23 : $bd = 0x27
8712: f0 04 BEQ .8718 ; |
8714: a2 24 LDX #$24 ; | Bit 4 of $12, but I don't know what
8716: a0 27 LDY #$27 ; | the other variables are yet.
8718: 8e bf 00 STX $00bf ; |
871b: 8c bd 00 STY $00bd ; /
871e: ad 12 00 LDA $0012
8721: 29 0f AND #$0f
8723: 0a ASL A
8724: 8d be 00 STA $00be ; ???
8727: 4a LSR A
8728: 4a LSR A
8729: 8d ab 00 STA $00ab ; ???
872c: 18 CLC
872d: 69 c0 ADC #$c0
872f: 8d bc 00 STA $00bc
8732: ad 12 00 LDA $0012 ; \
8735: 4a LSR A ; | Grab the ID of the halfscreen data
8736: 4a LSR A ; | to load
8737: 4a LSR A ; |
8738: a8 TAY ; |
8739: b1 ba LDA ($ba),Y ; /
873b: a2 00 LDX #$00 ; \
873d: 8e 15 00 STX $0015 ; | Calculate the address of the
8740: 0a ASL A ; | halfscreen layout data (relative to
8741: 2e 15 00 ROL $0015 ; | $ea50)
8744: 0a ASL A ; |
8745: 2e 15 00 ROL $0015 ; |
8748: 0a ASL A ; |
8749: 2e 15 00 ROL $0015 ; |
874c: 0a ASL A ; |
874d: 2e 15 00 ROL $0015 ; |
8750: 69 50 ADC #$50 ; |
8752: 8d 14 00 STA $0014 ; |
8755: ad 15 00 LDA $0015 ; |
8758: 69 ea ADC #$ea ; |
875a: 8d 15 00 STA $0015 ; /
875d: ad 12 00 LDA $0012 ; \
8760: 29 07 AND #$07 ; | Grab the ID of the first stripe to
8762: 0a ASL A ; | load
8763: a8 TAY ; |
8764: b1 14 LDA ($14),Y ; |
8766: 8d 23 00 STA $0023 ; /
8769: a2 00 LDX #$00 ; \
876b: 8e 17 00 STX $0017 ; | Calculate the address of the first
876e: 8e 19 00 STX $0019 ; | stripe layout (relative to $de50)
8771: 0a ASL A ; |
8772: 2e 17 00 ROL $0017 ; |
8775: 0a ASL A ; |
8776: 2e 17 00 ROL $0017 ; |
8779: 0a ASL A ; |
877a: 2e 17 00 ROL $0017 ; |
877d: 69 50 ADC #$50 ; |
877f: 8d 16 00 STA $0016 ; |
8782: ad 17 00 LDA $0017 ; |
8785: 69 de ADC #$de ; |
8787: 8d 17 00 STA $0017 ; /
878a: c8 INY ; \
878b: b1 14 LDA ($14),Y ; | Grab the second stripe ID
878d: 8d 24 00 STA $0024 ; /
8790: 0a ASL A ; \
8791: 2e 19 00 ROL $0019 ; | Calculate the second address
8794: 0a ASL A ; |
8795: 2e 19 00 ROL $0019 ; |
8798: 0a ASL A ; |
8799: 2e 19 00 ROL $0019 ; |
879c: 69 50 ADC #$50 ; |
879e: 8d 18 00 STA $0018 ; |
87a1: ad 19 00 LDA $0019 ; |
87a4: 69 de ADC #$de ; |
87a6: 8d 19 00 SDA $0019 ; /
87a9: a2 00 LDX #$00
87ab: 8e 25 00 STX $0025
87ae: a9 00 LDA #$00 ;/\ *** duplicated code ***
87b0: 8d 1b 00 STA $001b ; |
87b3: ac 25 00 LDY $0025 ; | Grab a block ID
87b6: b1 16 LDA ($16),Y ; /
87b8: 0a ASL A ; \
87b9: 2e 1b 00 ROL $001b ; | Calculate block layout address
87bc: 0a ASL A ; | (relative to $f3c0)
87bd: 2e 1b 00 ROL $001b ; |
87c0: 69 c0 ADC #$c0 ; |
87c2: 8d 1a 00 STA $001a ; |
87c5: ad 1b 00 LDA $001b ; |
87c8: 69 f3 ADC #$f3 ; |
87ca: 8d 1b 00 STA $001b ; /
87cd: a0 00 LDY #$00 ; \
87cf: b1 1a LDA ($1a),Y ; | Stuff tile data into RAM
87d1: 9d c0 00 STA $00c0,X ; |
87d4: c8 INY ; |
87d5: b1 1a LDA ($1a),Y ; |
87d7: 9d e0 00 STA $00e0,X ; |
87da: c8 INY ; |
87db: b1 1a LDA ($1a),Y ; |
87dd: 9d c1 00 STA $00c1,X ; |
87e0: c8 INY ; |
87e1: b1 1a LDA ($1a),Y ; |
87e3: 9d e1 00 STA $00e1,X ; /
87e6: ee 25 00 INC $0025
87e9: e8 INX
87ea: e8 INX
87eb: e0 10 CPX #$10 ; Run through 8 blocks
87ed: d0 bf BNE .87ae ;\/
87ef: a9 00 LDA #$00
87f1: 8d 25 00 STA $0025
87f4: a9 00 LDA #$00 ;/\
87f6: 8d 1b 00 STA $001b
87f9: ac 25 00 LDY $0025
87fc: b1 18 LDA ($18),Y ; Block ID is from second stripe
87fe: 0a ASL A
87ff: 2e 1b 00 ROL $001b
8802: 0a ASL A
8803: 2e 1b 00 ROL $001b
8806: 69 c0 ADC #$c0
8808: 8d 1a 00 STA $001a
880b: ad 1b 00 LDA $001b
880e: 69 f3 ADC #$f3
8810: 8d 1b 00 STA $001b
8813: a0 00 LDY #$00
8815: b1 1a LDA ($1a),Y
8817: 9d c0 00 STA $00c0,X
881a: c8 INY
881b: b1 1a LDA ($1a),Y
881d: 9d e0 00 STA $00e0,X
8820: c8 INY
8821: b1 1a LDA ($1a),Y
8823: 9d c1 00 STA $00c1,X
8826: c8 INY
8827: b1 1a LDA ($1a),Y
8829: 9d e1 00 STA $00e1,X
882c: ee 25 00 INC $0025
882f: e8 INX
8830: e8 INX
8831: e0 20 CPX #$20 ; Run through 8 more blocks
8833: d0 bf BNE .87f4 ;\/
8835: a2 00 LDX #$00
8837: ad 12 00 LDA $0012
883a: 29 10 AND #$10
883c: f0 02 BEQ .8840
883e: a2 40 LDX #$40
8840: 8a TXA
8841: 18 CLC
8842: 6d ab 00 ADC $00ab
8845: 8d ab 00 STA $00ab
8848: a2 cc LDX #$cc ; \
884a: a0 33 LDY #$33 ; | Set up masks for attribute updates
884c: ad 12 00 LDA $0012 ; |
884f: 4a LSR A ; | $00ad is the mask for new
8850: b0 04 BCS .8856 ; | $00ac is the mask for old
8852: a2 33 LDX #$33 ; |
8854: a0 cc LDY #$cc ; |
8856: 8e ad 00 STX $00ad ; |
8859: 8c ac 00 STY $00ac ; /
885c: ad 23 00 LDA $0023 ;/\ *** duplicated code ***
885f: a2 00 LDX #$00 ; | Calculate first stripe attribute
8861: 8e 1f 00 STX $001f ; | address (relative to $e650)
8864: 0a ASL A ; |
8865: 2e 1f 00 ROL $001f ; |
8868: 69 50 ADC #$50 ; |
886a: 8d 1e 00 STA $001e ; |
886d: ad 1f 00 LDA $001f ; |
8870: 69 e6 ADC #$e6 ; |
8872: 8d 1f 00 STA $001f ; /
8875: a0 00 LDY #$00 ; \
8877: b1 1e LDA ($1e),Y ; | Load and shuffle first stripe
8879: 8d 28 00 STA $0028 ; | attributes. Fairly straightforward,
887c: ac ab 00 LDY $00ab ; | so long as you understand how the
887f: 20 ae 89 JSR .89ae ; | PPU interprets attribute tables.
8882: b9 80 04 LDA $0480,Y ; |
8885: 2d ac 00 AND $00ac ; |
8888: 0d 2b 00 ORA $002b ; |
888b: 99 80 04 STA $0480,Y ; |
888e: 8d b0 00 STA $00b0 ; |
8891: 20 d5 89 JSR .89d5 ; |
8894: b9 88 04 LDA $0488,Y ; |
8897: 2d ac 00 AND $00ac ; |
889a: 0d 2b 00 ORA $002b ; |
889d: 99 88 04 STA $0488,Y ; |
88a0: 8d b1 00 STA $00b1 ; |
88a3: a0 01 LDY #$01 ; |
88a5: b1 1e LDA ($1e),Y ; |
88a7: 8d 28 00 STA $0028 ; |
88aa: ac ab 00 LDY $00ab ; |
88ad: 20 ae 89 JSR .89ae ; |
88b0: b9 90 04 LDA $0490,Y ; |
88b3: 2d ac 00 AND $00ac ; |
88b6: 0d 2b 00 ORA $002b ; |
88b9: 99 90 04 STA $0490,Y ; |
88bc: 8d b2 00 STA $00b2 ; |
88bf: 20 d5 89 JSR .89d5 ; |
88c2: b9 98 04 LDA $0498,Y ; |
88c5: 2d ac 00 AND $00ac ; |
88c8: 0d 2b 00 ORA $002b ; |
88cb: 99 98 04 STA $0498,Y ; |
88ce: 8d b3 00 STA $00b3 ;\/
88d1: ad 24 00 LDA $0024 ;/\
88d4: a2 00 LDX #$00 ; Like above, but for the second
88d6: 8e 1f 00 STX $001f ; stripe. (This would be a lot smaller
88d9: 0a ASL A ; as a loop.)
88da: 2e 1f 00 ROL $001f
88dd: 69 50 ADC #$50
88df: 8d 1e 00 STA $001e
88e2: ad 1f 00 LDA $001f
88e5: 69 e6 ADC #$e6
88e7: 8d 1f 00 STA $001f
88ea: a0 00 LDY #$00
88ec: b1 1e LDA ($1e),Y
88ee: 8d 28 00 STA $0028
88f1: ac ab 00 LDY $00ab
88f4: 20 ae 89 JSR .89ae
88f7: b9 a0 04 LDA $04a0
88fa: 2d ac 00 AND $00ac
88fd: 0d 2b 00 ORA $002b
8900: 99 a0 04 STA $04a0,Y
8903: 8d b4 00 STA $00b4
8906: 20 d5 89 JSR .89d5
8909: b9 a8 04 LDA $04a8,Y
890c: 2d ac 00 AND $00ac
890f: 0d 2b 00 ORA $002b
8912: 99 a8 04 STA $04a8,Y
8915: 8d b5 00 STA $00b5
8918: a0 01 LDY #$01
891a: b1 1e LDA ($1e),Y
891c: 8d 28 00 STA $0028
891f: ac ab 00 LDY $00ab
8922: 20 ae 89 JSR .89ae
8925: b9 b0 04 LDA $04b0,Y
8928: 2d ac 00 AND $00ac
892b: 0d 2b 00 ORA $002b
892e: 99 b0 04 STA $04b0,Y
8931: 8d b6 00 STA $00b6
8934: 20 d5 89 JSR .89d5
8937: b9 b8 04 LDA $04b8,Y
893a: 2d ac 00 AND $00ac
893d: 0d 2b 00 ORA $002b
8940: 99 b8 04 STA $04b8,Y
8943: 8d b7 00 STA $00b7 ;\/
8946: a2 00 LDX #$00
8948: bd 50 02 LDA $0250,X ; \ Door presence (visibility high bit
894b: 10 53 BPL .89a0 ; / set means it's a door)
894d: bd 51 02 LDA $0251,X ; \
8950: cd 12 00 CMP $0012 ; | Door X
8953: d0 4b BNE .89a0 ; /
8955: bd 52 02 LDA $0252,X ; \
8958: 4a LSR A ; | Door Y
8959: a8 TAY ; |
895a: 88 DEY ; |
895b: 8c 2f 00 STY $002f ; /
895e: 8e 2c 00 STX $002c
8961: bd 50 02 LDA $0250,X ; \ Door visibility: #$81, #$82, and
8964: 29 03 AND #$03 ; | #$c1 mean the door is visible.
8966: f0 38 BEQ .89a0 ; /
8968: a2 03 LDX #$03 ; \
896a: 29 01 AND #$01 ; | Also, #$82 means the door is open.
896c: d0 02 BNE .8970 ; |
896e: a2 07 LDX #$07 ; |
8970: 8e 2d 00 STX $002d ; /
8973: a9 03 LDA #$03 ; \
8975: 8d 2e 00 STA $002e ; | Load up the left side of the door
8978: bd 3e 8c LDA $8c3e,X ; |
897b: 99 c0 00 STA $00c0,Y ; |
897e: 88 DEY ; |
897f: ca DEX ; |
8980: ce 2e 00 DEC $002e ; |
8983: 10 f3 BPL .8978 ; /
8985: ae 2d 00 LDX $002d
8988: ac 2f 00 LDY $002f
898b: a9 03 LDA #$03 ; \
898d: 8d 2e 00 STA $002e ; | And the right side
8990: bd 46 8c LDA $8c46,X ; | (yes this is more duplicate code)
8993: 99 e0 00 STA $00e0,Y ; |
8996: 88 DEY ; |
8997: ca DEX ; |
8998: ce 2e 00 DEC $002e ; |
899b: 10 f3 BPL .8990 ; /
899d: ae 2c 00 LDX $002c
89a0: e8 INX
89a1: e8 INX
89a2: e8 INX
89a3: e8 INX
89a4: e0 10 CPX #$10
89a6: d0 a0 BNE .8948
89a8: a9 ff LDA #$ff ; \ Update nametable during VBlank
89aa: 8d 57 01 STA $0157 ; /
89ad: 60 RTS
*** SUBROUTINE ***
Load attributes for two blocks in a stripe
89ae: 29 c0 AND #$c0
89b0: 18 CLC
89b1: 2a ROL A
89b2: 2a ROL A
89b3: 2a ROL A
89b4: aa TAX
89b5: bd 36 8c LDA $8c36,X ; Lookup table to avoid bit shifts
89b8: 2d ad 00 AND $00ad
89bb: 8d 2b 00 STA $002b
89be: ad 28 00 LDA $0028
89c1: 29 30 AND #$30
89c3: 4a LSR A
89c4: 4a LSR A
89c5: 4a LSR A
89c6: 4a LSR A
89c7: aa TAX
89c8: bd 3a 8c LDA $8c3a,X ; Another lookup table
89cb: 2d ad 00 AND $00ad
89ce: 0d 2b 00 ORA $002b
89d1: 8d 2b 00 STA $002b
89d4: 60 RTS
*** SUBROUTINE ***
See above
89d5: ad 28 00 LDA $0028
89d8: 29 0c AND #$0c
89da: 4a LSR A
89db: 4a LSR A
89dc: aa TAX
89dd: bd 36 8c LDA $8c36,X
89e0: 2d ad 00 AND $00ad
89e3: 8d 2b 00 STA $002b
89e6: ad 28 00 LDA $0028
89e9: 29 03 AND #$03
89eb: aa TAX
89ec: bd 3a 8c LDA $8c3a,X
89ef: 2d ad 00 AND $00ad
89f2: 0d 2b 00 ORA $002b
89f5: 8d 2b 00 STA $002b
89f8: 60 RTS
*** SUBROUTINE ***
Update name/attribute tables
89f9: ad 57 01 LDA $0157 ; \
89fc: d0 03 BNE .8a01 ; | Check if it's uploading layout data
89fe: 4c e0 8b JMP .8be0 ; /
8a01: ad 00 00 LDA $0000 ; \
8a04: 09 04 ORA #$04 ; | Vertical nametable writing
8a06: 8d 00 00 STA $0000 ; |
8a09: 8d 00 20 STA $2000 ; /
8a0c: ae bf 00 LDX $00bf ; \
8a0f: ac be 00 LDY $00be ; | and the appropriate PPU address
8a12: 8e 06 20 STX $2006 ; |
8a15: 8c 06 20 STY $2006 ; /
8a18: a2 00 LDX #$00 ; \
8a1a: bd c0 00 LDA $00c0,X ; | Write 30 tiles
8a1d: 8d 07 20 STA $2007 ; |
8a20: e8 INX ; |
8a21: e0 1e CPX #$1e ; |
8a23: d0 f5 BNE .8a1a ; /
8a25: ae bf 00 LDX $00bf ; \
8a28: c8 INY ; | PPU address again
8a29: 8e 06 20 STX $2006 ; |
8a2c: 8c 06 20 STY $2006 ; /
8a2f: a2 20 LDX #$20 ; \
8a31: bd c0 00 LDA $00c0,X ; | Write another 30 tiles
8a34: 8d 07 20 STA $2007 ; |
8a37: e8 INX ; | I'm sure they could've done this
8a38: e0 3e CPX #$3e ; | in less space.
8a3a: d0 f5 BNE .8a31 ; /
8a3c: ad 00 00 LDA $0000 ; \
8a3f: 29 fb AND #$fb ; | Horizontal nametable writing
8a41: 8d 00 00 STA $0000 ; |
8a44: 8d 00 20 STA $2000 ; /
8a47: a0 00 LDY #$00
8a49: ae bd 00 LDX $00bd ; \
8a4c: ad bc 00 LDA $00bc ; | But it doesn't matter since the PPU
8a4f: 8e 06 20 STX $2006 ; | address is reset after each byte.
8a52: 8d 06 20 STA $2006 ; |
8a55: 18 CLC ; | Oh well. It works.
8a56: 69 08 ADC #$08 ; |
8a58: 8d bc 00 STA $00bc ; |
8a5b: b9 b0 00 LDA $00b0,Y ; |
8a5e: 8d 07 20 STA $2007 ; |
8a61: c8 INY ; |
8a62: c0 08 CPY #$08 ; |
8a64: d0 e6 BNE .8a4c ; /
8a66: a9 00 LDA #$00 ; \ Well that's one job done
8a68: 8d 57 01 STA $0157 ; /
8a6b: 60 RTS
8be0: ad 5a 01 LDA $015a ; \ Check if it's uploading door data
8be3: f0 50 BEQ .8c35 ; /
8be5: ad 00 00 LDA $0000 ; \
8be8: 09 04 ORA #$04 ; | Vertical nametables
8bea: 8d 00 00 STA $0000 ; |
8bed: 8d 00 20 STA $0020 ; /
8bf0: ae a7 00 LDX $00a7
8bf3: ac a6 00 LDY $00a6
8bf6: 8e 06 20 STX $2006
8bf9: 8c 06 20 STY $2006
8bfc: a0 04 LDY #$04
8bfe: ae a8 00 LDX $00a8
8c01: bd 3e 8c LDA $8c3e,X ; Door tilemap
8c04: 8d 07 20 STA $2007
8c07: e8 INX
8c08: 88 DEY
8c09: d0 f6 BNE .8c01
8c0b: ae a7 00 LDX $00a7
8c0e: ac a6 00 LDY $00a6
8c11: c8 INY
8c12: 8e 06 20 STX $2006
8c15: 8c 06 20 STY $2006
8c18: a0 04 LDY #$04
8c1a: ae a8 00 LDX $00a8
8c1d: bd 46 8c LDA $8c46,X ; More door tilemap
8c20: 8d 07 20 STA $2007
8c23: e8 INX
8c24: 88 DEY
8c25: d0 f6 BNE .8c1d
8c27: 8c 5a 01 STY $015a
8c2a: ad 00 00 LDA $0000 ; \
8c2d: 29 fb AND #$fb ; | Horizontal nametables (why bother?)
8c2f: 8d 00 00 STA $0000 ; |
8c32: 8d 00 20 STA $0020 ; /
8c35: 60 RTS
*** SUBROUTINE ***
New game
8c4e: a2 01 LDX #$01 ; \
8c50: a0 90 LDY #$90 ; | Clear $30 bytes starting at $0190
8c52: a9 30 LDA #$30 ; |
8c54: 20 47 84 JSR .8447 ; /
8c57: a2 04 LDX #$04 ; \
8c59: a0 00 LDY #$00 ; | Clear $80 bytes starting at $0400
8c5b: a9 80 LDA #$80 ; |
8c5d: 20 47 84 JSR .8447 ; /
8c60: ad 00 00 LDA $0000 ; \
8c63: 29 e7 AND #$e7 ; | Set pattern tables
8c65: 09 10 ORA #$10 ; |
8c67: 8d 00 00 STA $0000 ; |
8c6a: 8d 00 20 STA $2000 ; /
8c6d: 20 76 8c JSR .8c76 ; Load level
8c70: a9 06 LDA #$06 ; \ Give Wynn 7 lives
8c72: 8d 94 01 STA $0194 ; /
8c75: 60 RTS
*** SUBROUTINE ***
Load level
8c76: a2 01 LDX #$01 ; \
8c78: a0 c0 LDY #$c0 ; | Clear $20 bytes starting at $01c0
8c7a: a9 20 LDA #$20 ; |
8c7c: 20 47 84 JSR .8447 ; /
8c7f: a2 05 LDX #$05 ; \
8c81: a0 00 LDY #$00 ; | Clear $20 bytes starting at $0500
8c83: a9 20 LDA #$20 ; |
8c85: 20 47 84 JSR .8447 ; /
8c88: a2 02 LDX #$02 ; \
8c8a: a0 00 LDY #$00 ; | Clear $c0 bytes starting at $0200
8c8c: a9 c0 LDA #$c0 ; |
8c8e: 20 47 84 JSR .8447 ; /
8c91: a2 03 LDX #$03 ; \
8c93: a0 00 LDY #$00 ; | Clear $100 bytes starting at $0300
8c95: a9 00 LDA #$00 ; |
8c97: 20 47 84 JSR .8447 ; /
8c9a: 20 b3 8c JSR .8cb3 ; Load Wynn's starting position
8c9d: 20 e9 8c JSR .8ce9 ; Load collision data
8ca0: 20 fb 8d JSR .8dfb ; Load background palettes.
8ca3: 20 6b 8e JSR .8e6b ; Load sprite palettes.
8ca6: 20 c7 8e JSR .8ec7 ; Load door information
8ca9: 20 2b 8f JSR .8f2b ; Load treasure chests and powerups
8cac: 20 4a 90 JSR .904a ; Load LevelASM pointer
8caf: 20 10 90 JSR .9010 ; Load enemy ASM pointers
8cb2: 60 RTS
*** SUBROUTINE ***
Make Wynn appear in front of a door
8cb3: ad 96 01 LDA $0196 ; \
8cb6: a0 00 LDY #$00 ; | Calculate address of door data
8cb8: 8c 19 00 STY $0019 ; |
8cbb: 0a ASL A ; |
8cbc: 2e 19 00 ROL $0019 ; |
8cbf: 0a ASL A ; |
8cc0: 2e 19 00 ROL $0019 ; |
8cc3: 69 e0 ADC #$e0 ; |
8cc5: 8d 18 00 STA $0018 ; |
8cc8: ad 19 00 LDA $0019 ; |
8ccb: 69 d5 ADC #$d5 ; |
8ccd: 8d 19 00 STA $0019 ; /
8cd0: b1 18 LDA ($18),Y ; \ Load zone ID
8cd2: 8d 92 01 STA $0192 ; /
8cd5: c8 INY
8cd6: b1 18 LDA ($18),Y ; \ Load Wynn's X position
8cd8: 8d 10 02 STA $0210 ; /
8cdb: c8 INY
8cdc: b1 18 LDA ($18),Y ; \
8cde: 09 40 ORA #$40 ; | Load Wynn's Y position
8ce0: 8d 12 02 STA $0212 ; /
8ce3: a9 80 LDA #$80 ; \ Set Wynn's fine X position
8ce5: 8d 11 02 STA $0211 ; /
8ce8: 60 RTS
*** SUBROUTINE ***
Load collision data to $0500 (and set up pointers at $02c0)
8ce9: ad 92 01 LDA $0192 ; Load zone number
8cec: 0a ASL A ; Multiply by two
8ced: aa TAX ; Use it as X
8cee: bd 80 f7 LDA $f780,X ; \
8cf1: 8d ba 00 STA $00ba ; | Level address goes to $00ba
8cf4: bd 81 f7 LDA $f781,X ; |
8cf7: 8d bb 00 STA $00bb ; /
8cfa: a9 c0 LDA #$c0 ; \
8cfc: 8d b8 00 STA $00b8 ; | $02c0 goes to $00b8
8cff: a9 02 LDA #$02 ; |
8d01: 8d b9 00 STA $00b9 ; /
8d04: a0 00 LDY #$00
8d06: 8c 22 00 STY $0022
8d09: 8c 00 05 STY $0500
8d0c: c8 INY
8d0d: 8c 21 00 STY $0021
8d10: ac 21 00 LDY $0021 ; \
8d13: b1 ba LDA ($ba),Y ; | Huge freaking loop.
8d15: 8d 20 00 STA $0020 ; | Without figuring out exactly what it does,
8d18: a0 00 LDY #$00 ; | I can say it checks the level data for duplicate
8d1a: b1 ba LDA ($ba),Y ; | halfscreens and optimizes the collision data
8d1c: cd 20 00 CMP $0020 ; | pointers.
8d1f: f0 1e BEQ .8d3f ; |
8d21: c8 INY ; |
8d22: cc 21 00 CPY $0021 ; |
8d25: d0 f3 BNE .8d1a ; |
8d27: ee 22 00 INC $0022 ; |
8d2a: ad 22 00 LDA $0022 ; |
8d2d: 29 0f AND #$0f ; |
8d2f: ac 21 00 LDY $0021 ; |
8d32: 99 00 05 STA $0500,Y ; |
8d35: c8 INY ; |
8d36: 8c 21 00 STY $0021 ; |
8d39: c0 20 CPY #$20 ; |
8d3b: d0 d3 BNE .8d10 ; |
8d3d: f0 05 BEQ .8d44 ; | Actually, you know what?
8d3f: b9 00 05 LDA $0500,Y ; | Someone else can comment this subroutine.
8d42: 10 eb BPL .8d2f ; /
8d44: a2 00 LDX #$00
8d46: a0 00 LDY #$00
8d48: a9 00 LDA #$00
8d4a: 8d 13 00 STA $0013
8d4d: bd 00 05 LDA $0500,X
8d50: 0a ASL A
8d51: 2e 13 00 ROL $0013
8d54: 0a ASL A
8d55: 2e 13 00 ROL $0013
8d58: 0a ASL A
8d59: 2e 13 00 ROL $0013
8d5c: 0a ASL A
8d5d: 2e 13 00 ROL $0013
8d60: 0a ASL A
8d61: 2e 13 00 ROL $0013
8d64: 69 00 ADC #$00
8d66: 99 c0 02 STA $02c0,Y
8d69: ad 13 00 LDA $0013
8d6c: 69 05 ADC #$05
8d6e: c8 INY
8d6f: 99 c0 02 STA $02c0,Y
8d72: c8 INY
8d73: e8 INX
8d74: e0 20 CPX #$20
8d76: d0 d0 BNE .8d48
8d78: a9 00 LDA #$00
8d7a: 8d 20 00 STA $0020
8d7d: ac 20 00 LDY $0020
8d80: b1 ba LDA ($ba),Y
8d82: a2 00 LDX #$00
8d84: 8e 15 00 STX $0015
8d87: 0a ASL A
8d88: 2e 15 00 ROL $0015
8d8b: 0a ASL A
8d8c: 2e 15 00 ROL $0015
8d8f: 0a ASL A
8d90: 2e 15 00 ROL $0015
8d93: 0a ASL A
8d94: 2e 15 00 ROL $0015
8d97: 69 50 ADC #$50
8d99: 8d 14 00 STA $0014
8d9c: ad 15 00 LDA $0015
8d9f: 69 ea ADC #$ea
8da1: 8d 15 00 STA $0015
8da4: ad 20 00 LDA $0020
8da7: 0a ASL A
8da8: a8 TAY
8da9: b9 c0 02 LDA $02c0,Y
8dac: 8d 18 00 STA $0018
8daf: b9 c1 02 LDA $02c1,Y
8db2: 8d 19 00 STA $0019
8db5: a9 00 LDA #$00
8db7: 8d 23 00 STA $0023
8dba: ac 23 00 LDY $0023
8dbd: b1 14 LDA ($14),Y
8dbf: a2 00 LDX #$00
8dc1: 8e 1b 00 STX $001b
8dc4: 0a ASL A
8dc5: 2e 1b 00 ROL $001b
8dc8: 69 50 ADC #$50
8dca: 8d 1a 00 STA $001a
8dcd: ad 1b 00 LDA $001b
8dd0: 69 e8 ADC #$e8
8dd2: 8d 1b 00 STA $001b
8dd5: a0 00 LDY #$00
8dd7: b1 1a LDA ($1a),Y
8dd9: 91 18 STA ($18),Y
8ddb: c8 INY
8ddc: b1 1a LDA ($1a),Y
8dde: 91 18 STA ($18),Y
8de0: ee 18 00 INC $0018
8de3: ee 18 00 INC $0018
8de6: ee 23 00 INC $0023
8de9: ad 23 00 LDA $0023
8dec: c9 10 CMP #$10
8dee: d0 ca BNE .8dba
8df0: ee 20 00 INC $0020
8df3: ad 20 00 LDA $0020
8df6: c9 20 CMP #$20
8df8: d0 83 BNE .8d7d
8dfa: 60 RTS
*** SUBROUTINE ***
Load the background palette. Waste space.
8dfb: ad 92 01 LDA $0192
8dfe: 0a ASL A
8dff: aa TAX
8e00: bd 79 90 LDA $9079,X
8e03: 0a ASL A
8e04: 0a ASL A
8e05: 8d 25 00 STA $0025
8e08: bd 40 91 LDA $9140,X
8e0b: 0a ASL A
8e0c: 0a ASL A
8e0d: 8d 26 00 STA $0026
8e10: bd 41 91 LDA $9141,X
8e13: 0a ASL A
8e14: 0a ASL A
8e15: 8d 27 00 STA $0027
8e18: bd 78 90 LDA $9078,X
8e1b: 0a ASL A
8e1c: 0a ASL A
8e1d: aa TAX
8e1e: bd 76 92 LDA $9276,X
8e21: a0 1f LDY #$1f
8e23: 99 e0 01 STA $01e0,Y
8e26: 88 DEY
8e27: 10 fa BPL .8e23
8e29: a0 01 LDY #$01
8e2b: e8 INX
8e2c: bd 76 92 LDA $9276,X
8e2f: 99 e0 01 STA $01e0,Y
8e32: c8 INY
8e33: c0 04 CPY #$04
8e35: d0 f4 BNE .8e2b
8e37: ae 25 00 LDX $0025
8e3a: a0 01 LDY #$01
8e3c: e8 INX
8e3d: bd 76 92 LDA $9276,X
8e40: 99 e4 01 STA $01e4,Y
8e43: c8 INY
8e44: c0 04 CPY #$04
8e46: d0 f4 BNE .8e3c
8e48: ae 26 00 LDX #$0026
8e4b: a0 01 LDY #$01
8e4d: e8 INX
8e4e: bd 76 92 LDA $9276,X
8e51: 99 e8 01 STA $01e8,Y
8e54: c8 INY
8e55: c0 04 CPY #$04
8e57: d0 f4 BNE .8e4d
8e59: ae 27 00 LDX $0027
8e5c: a0 01 LDY #$01
8e5e: e8 INX
8e5f: bd 76 92 LDA $9276,X
8e62: 99 ec 01 STA $01ec,Y
8e65: c8 INY
8e66: c0 04 CPY #$04
8e68: d0 f4 BNE .8e5e
8e6a: 60 RTS
*** SUBROUTINE ***
Load the sprite palettes. Probably wasting space here too.
8e6b: a2 02 LDX #$02 ; \
8e6d: bd 70 92 LDA $9270,X ; | Load the palette used for bombs,
8e70: 9d f9 01 STA $01f9,X ; | the OSD, and a couple other things.
8e73: ca DEX ; |
8e74: 10 f7 BPL .8e6d ; /
8e76: a2 02 LDX #$02 ; \
8e78: bd 73 92 LDA $9273,X ; | Load the palette used for Wynn
8e7b: 9d fd 01 STA $01fd,X ; |
8e7e: ca DEX ; |
8e7f: 10 f7 BPL .8e78 ; /
8e81: ae 92 01 LDX $0192 ; \ Load the level sprite palette index
8e84: bd 08 92 LDA $9208,X ; /
8e87: 8d 23 00 STA $0023
8e8a: 29 f0 AND #$f0
8e8c: 4a LSR A
8e8d: 4a LSR A
8e8e: 4a LSR A
8e8f: 8d 24 00 STA $0024
8e92: 4a LSR A
8e93: 18 CLC
8e94: 6d 24 00 ADC $0024
8e97: aa TAX
8e98: a0 01 LDY #$01
8e9a: bd 56 93 LDA $9356,X
8e9d: 99 f0 01 STA $01f0,Y
8ea0: e8 INX
8ea1: c8 INY
8ea2: c0 04 CPY #$04
8ea4: d0 f4 BNE .8e9a
8ea6: ad 23 00 LDA $0023
8ea9: 29 0f AND #$0f
8eab: 8d 24 00 STA $0024
8eae: 0a ASL A
8eaf: 6d 24 00 ADC $0024
8eb2: aa TAX
8eb3: a0 01 LDY #$01
8eb5: bd 56 93 LDA $9356,X
8eb8: 99 f4 01 STA $01f4,Y
8ebb: e8 INX
8ebc: c8 INY
8ebd: c0 04 CPY #$04
8ebf: d0 f4 BNE .8eb5
8ec1: a9 ff LDA #$ff ; \ Flag to update palette during NMI?
8ec3: 8d 56 01 STA $0156 ; /
8ec6: 60 RTS
*** SUBROUTINE ***
Load doors for current zone
8ec7: a9 e0 LDA #$e0 ; \
8ec9: 8d 1c 00 STA $001c ; | Address of the main part of the door list
8ecc: a9 d5 LDA #$d5 ; | (zone, X, Y, destination)
8ece: 8d 1d 00 STA $001d ; /
8ed1: a9 50 LDA #$50 ; \
8ed3: 8d 1e 00 STA $001e ; | Address in RAM to store door information
8ed6: a9 02 LDA #$02 ; |
8ed8: 8d 1f 00 STA $001f ; /
8edb: a9 ff LDA #$ff
8edd: 8d 2e 00 STA $002e
8ee0: a0 00 LDY #$00
8ee2: b1 1c LDA ($1c),Y ; \
8ee4: c9 ff CMP #$ff ; | Check if this is the end of the list
8ee6: f0 42 BEQ .8f2a ; /
8ee8: ee 2e 00 INC $002e
8eeb: cd 92 01 CMP $0192 ; \ Check if a door is in the current zone
8eee: d0 29 BNE .8f19 ; /
8ef0: ae 2e 00 LDX $002e ; \
8ef3: a9 c1 LDA #$c1 ; | The door Wynn last came out of is always
8ef5: ec 96 01 CPX $0196 ; | visible and closed. The appearance of all
8ef8: f0 05 BEQ .8eff ; | other doors is determined by another list.
8efa: bd a0 d9 LDA $d9a0,X ; |
8efd: 09 80 ORA #$80 ; |
8eff: 91 1e STA ($1e),Y ; /
8f01: c8 INY ; \
8f02: b1 1c LDA ($1c),Y ; | The other three bytes are copied from the
8f04: 91 1e STA ($1e),Y ; | main list in ROM.
8f06: c8 INY ; |
8f07: b1 1c LDA ($1c),Y ; | It's stored in RAM like this:
8f09: 91 1e STA ($1e),Y ; | (visibility, X, Y, destination)
8f0b: c8 INY ; |
8f0c: b1 1c LDA ($1c),Y ; |
8f0e: 91 1e STA ($1e),Y ; /
8f10: 18 CLC ; \
8f11: ad 1e 00 LDA $001e ; | Increment RAM address
8f14: 69 04 ADC #$04 ; |
8f16: 8d 1e 00 STA $001e ; /
8f19: 18 CLC ; \
8f1a: ad 1c 00 LDA $001c ; | Increment ROM address
8f1d: 69 04 ADC #$04 ; |
8f1f: 8d 1c 00 STA $001c ; |
8f22: 90 bc BCC .8ee0 ; |
8f24: ee 1d 00 INC $001d ; /
8f27: 4c e0 8e JMP .8ee0
8f2a: 60 RTS
*** SUBROUTINE ***
Load treasure chests and powerups
WARNING! Powerup items MUST NOT be in front of treasure chests in ROM!
8f2b: a9 90 LDA #$90 ; \
8f2d: 8d 1c 00 STA $001c ; | Treasure table in ROM
8f30: a9 da LDA #$da ; | (zone, X, Y, treasure)
8f32: 8d 1d 00 STA $001d ; /
8f35: a9 30 LDA #$30 ; \
8f37: 8d 1e 00 STA $001e ; | Treasure data in RAM
8f3a: a9 02 LDA #$02 ; | (X, fine X, Y, fine Y, ???, ???, ID, value)
8f3c: 8d 1f 00 STA $001f ; /
8f3f: a9 00 LDA #$00
8f41: 8d 2f 00 STA $002f
8f44: a0 00 LDY #$00
8f46: b1 1c LDA ($1c),Y ; \
8f48: c9 ff CMP #$ff ; | Check if it's the end of the list
8f4a: f0 7c BEQ .8fc8 ; /
8f4c: cd 92 01 CMP $0192 ; \ Check if it's the current zone
8f4f: d0 63 BNE .8fb4 ; /
8f51: c8 INY ; \
8f52: b1 1c LDA ($1c),Y ; | Copy X to RAM
8f54: 88 DEY ; |
8f55: 91 1e STA ($1e),Y ; /
8f57: a9 80 LDA #$80 ; \
8f59: c8 INY ; | Set fine X
8f5a: 91 1e STA ($1e),Y ; /
8f5c: c8 INY ; \
8f5d: b1 1c LDA ($1c),Y ; | Set Y
8f5f: 91 1e STA ($1e),Y ; /
8f61: a9 00 LDA #$00 ; \
8f63: c8 INY ; | Set fine Y
8f64: 91 1e STA ($1e),Y ; /
8f66: b1 1c LDA ($1c),Y ; \ Check if it's a powerup
8f68: 30 20 BMI .8f8a ; /
8f6a: a8 TAY
8f6b: ad 2f 00 LDA $002f ; \
8f6e: 29 07 AND #$07 ; | Check if the treasure has already been
8f70: 8d 2e 00 STA $002e ; | collected
8f73: ad 2f 00 LDA $002f ; |
8f76: 4a LSR A ; |
8f77: 4a LSR A ; |
8f78: 4a LSR A ; |
8f79: aa TAX ; |
8f7a: bd 00 04 LDA $0400,X ; |
8f7d: ae 2e 00 LDX $002e ; |
8f80: 3d 68 90 AND $9068,X ; |
8f83: f0 1b BEQ .8fa0 ; |
8f85: a0 00 LDY #$00 ; /
8f87: 4c a0 8f JMP .8fa0
8f8a: a2 ff LDX #$ff ; \ This will break any treasure chests that
8f8c: 8e 2f 00 STX $002f ; / appear after a powerup in the ROM list.
8f8f: 29 07 AND #$07
8f91: a8 TAY
8f92: b9 50 04 LDA $0450,Y ; \
8f95: f0 09 BEQ .8fa0 ; | Check if Wynn still has the powerup, and
8f97: a0 01 LDY #$01 ; | set the fine X to zero if he does.
8f99: a9 00 LDA #$00 ; | (That makes it not appear for some reason.)
8f9b: 91 1e STA ($1e),Y ; | This will re-use RAM if the item need not appear.
8f9d: 4c b7 8f JMP .8fb7 ; /
8fa0: 98 TYA
8fa1: a0 07 LDY #$07 ; \ Set value
8fa3: 91 1e STA ($1e),Y ; /
8fa5: ad 2f 00 LDA $002f ; \
8fa8: 88 DEY ; | Set ID
8fa9: 91 1e STA ($1e),Y ; /
8fab: 18 CLC ; \
8fac: ad 1e 00 LDA $001e ; | Increment RAM address
8faf: 69 08 ADC #$08 ; |
8fb1: 8d 1e 00 STA $001e ; /
8fb4: ee 2f 00 INC $002f ; Increment ID
8fb7: 18 CLC ; \
8fb8: ad 1c 00 LDA $001c ; | Increment ROM address
8fbb: 69 04 ADC #$04 ; |
8fbd: 8d 1c 00 STA $001c ; |
8fc0: 90 82 BCC .8f44 ; |
8fc2: ee 1d 00 INC $001d ; /
8fc5: 4c 44 8f JMP .8f44
8fc8: 60 RTS
*** SUBROUTINE ***
Draw the initial view of the zone
8fc9: 20 63 83 JSR .8363 ; Blackout PPU
8fcc: 20 f0 85 JSR .85f0 ; Load zone CHR pages
8fcf: ad 10 02 LDA $0210 ; Wynn X
8fd2: 38 SEC
8fd3: e9 20 SBC #$20
8fd5: 8d 02 00 STA $0002
8fd8: a9 80 LDA #$80
8fda: 8d 03 00 STA $0003
8fdd: 8d 07 00 STA $0007
8fe0: 18 CLC
8fe1: ad 02 00 LDA $0002
8fe4: 69 01 ADC #$01
8fe6: 8d 06 00 STA $0006
8fe9: 20 9a 86 JSR .869a ; Draw part of the zone
8fec: 20 f9 89 JSR .89f9 ; And send it to the PPU
8fef: 38 SEC
8ff0: ad 10 02 LDA $0210
8ff3: e9 08 SBC #$08
8ff5: cd 02 00 CMP $0002
8ff8: d0 e6 BNE .8fe0
8ffa: ae 09 00 LDX $0009
8ffd: ac 05 00 LDY $0005
9000: ad 00 00 LDA $0000
9003: 8e 05 20 STX $2005
9006: 8c 05 20 STY $2005
9009: 8d 00 20 STA $2000
900c: 20 51 83 JSR .8351 ; Enable VBlank
900f: 60 RTS
*** SUBROUTINE ***
Load enemy ASM pointers
9010: ad 92 01 LDA $0192 ; \
9013: 0a ASL A ; | Get address of enemy data
9014: aa TAX ; |
9015: bd d9 af LDA $afd9,X ; |
9018: 8d 14 00 STA $0014 ; |
901b: bd da af LDA $afda,X ; |
901e: 8d 15 00 STA $0015 ; /
9021: a0 00 LDY #$00
9023: b1 14 LDA ($14),Y ; \
9025: 30 1e BMI .9045 ; | Load enemy ASM pointers
9027: 0a ASL A ; |
9028: aa TAX ; |
9029: bd 1a b1 LDA $b11a,X ; |
902c: 99 b0 02 STA $02b0,Y ; |
902f: bd 1b b1 LDA $b11b,X ; |
9032: 99 b8 02 STA $02b8,Y ; |
9035: c8 INY ; |
9036: d0 eb BNE .9023 ; /
9038: ad 1a b1 LDA $b11a ; \
903b: 99 b0 02 STA $02b0,Y ; | Fill extra slots with pointers
903e: ad 1b b1 LDA $b11b ; | to do nothing
9041: 99 b8 02 STA $02b8,Y ; |
9044: c8 INY ; |
9045: c0 08 CPY #$08 ; |
9047: d0 ef BNE .9038 ; /
9049: 60 RTS
*** SUBROUTINE ***
Load LevelASM pointer
904a: ad 92 01 LDA $0192
904d: 0a ASL A
904e: aa TAX
904f: bd a6 be LDA $bea6,X
9052: 8d de 01 STA $01de
9055: bd a7 be LDA $bea7,X
9058: 8d df 01 STA $01df
905b: 60 RTS
*** SUBROUTINE ***
Draw Wynn, be retarded
b88d: 60 RTS ; \
b88e: ad 17 02 LDA $0217 ; | Check if Wynn is on-screen
b891: 30 fa BMI .b88d ; /
b893: ac 14 02 LDY $0214
b896: 8c 28 00 STY $0028
b899: ac 15 02 LDY $0215
b89c: 8c 29 00 STY $0029
b89f: ad 10 02 LDA $0210 ; \ Grab a halfscreen ID based on
b8a2: 20 e8 85 JSR .85e8 ; / Wynn's X position
b8a5: a0 43 LDY #$43 ; \
b8a7: ad 16 02 LDA $0216 ; | Decide if Wynn should be flipped
b8aa: 29 01 AND #$01 ; | horizontally
b8ac: d0 02 BNE .b8b0 ; |
b8ae: a0 03 LDY #$03 ; /
b8b0: 98 TYA
b8b1: 1d e5 fd ORA $fde5,X ; Load priority bit from a table
b8b4: 8d 2a 00 STA $002a
b8b7: ad 16 02 LDA $0216
b8ba: a8 TAY
b8bb: 30 41 BMI .b8fe ; Wynn is dying
b8bd: 98 TYA ; \
b8be: 29 02 AND #$02 ; | Throwing
b8c0: d0 2f BNE .b8f1 ; /
b8c2: 98 TYA ; \
b8c3: 29 10 AND #$10 ; | Crouching
b8c5: d0 18 BNE .b8df ; /
b8c7: 98 TYA ; \
b8c8: 29 04 AND #$04 ; | In the air
b8ca: d0 17 BNE .b8e3 ; /
b8cc: ad 1c 02 LDA $021c ; \ Standing still
b8cf: f0 0a BEQ .b8db ; /
b8d1: ad 18 02 LDA $0218 ; \
b8d4: 29 0c AND #$0c ; | Wynn must be running, so pick frame
b8d6: 4a LSR A ; | 0, 1, 2, 3 in sequence.
b8d7: a8 TAY ; |
b8d8: 4c 0f b9 JMP .b90f ; /
b8db: a0 08 LDY #$08 ; \ Wynn standing still is frame 4
b8dd: d0 30 BNE .b90f ; /
b8df: a0 0c LDY #$0c ; \ Wynn crouching is frame 6
b8e1: d0 2c BNE .b90f ; /
b8e3: ad 29 00 LDA $0029 ; \ ***********************************
b8e6: 18 CLC ; | Completely screws up jumping if a
b8e7: 6d 04 00 ADC $0004 ; | specific memory address isn't zero
b8ea: 8d 29 00 STA $0029 ; / ***********************************
b8ed: a0 0a LDY #$0a ; \ Wynn in the air is frame 5
b8ef: d0 1e BNE .b90f ; /
b8f1: a0 10 LDY #$10 ; \
b8f3: ad 1a 02 LDA $021a ; | Wynn throwing is frames 8 and 9
b8f6: c9 02 CMP #$02 ; |
b8f8: 10 15 BPL .b90f ; |
b8fa: c8 INY ; |
b8fb: c8 INY ; |
b8fc: d0 11 BNE .b90f ; /
b8fe: 29 40 AND #$40 ; \ "Eww" death
b900: d0 0b BNE .b90d ; /
b902: ad 2a 00 LDA $002a ; \
b905: 29 fe AND #$fe ; | Wynn is petrified: regular graphics
b907: 8d 2a 00 STA $002a ; | with palette 3.
b90a: 4c bd b8 JMP .b8bd ; /
b90d: a0 0e LDY #$0e ; Wynn going "eww" is frame 7
b90f: b9 d7 ba LDA $bad7,Y ; \
b912: 8d 1a 00 STA $001a ; | Load pointer from within the
b915: b9 d8 ba LDA $bad8,Y ; | tilemap
b918: 8d 1b 00 STA $001b ; /
b91b: ae 55 01 LDX $0155 ; \
b91e: a0 00 LDY #$00 ; | Add Wynn to the sprite page.
b920: b1 1a LDA ($1a),Y ; |
b922: c9 ff CMP #$ff ; | For some reason, it has code to
b924: f0 3f BEQ .b965 ; | clip the sprite off the right side
b926: 9d 01 07 STA $0701,X ; | of the screen the same way the PPU
b929: ad 2a 00 LDA $002a ; | clips sprites off the left side. If
b92c: 9d 02 07 STA $0702,X ; | anyone can think of a good reason
b92f: 29 40 AND #$40 ; | to do it this way, I'd love to hear
b931: d0 06 BNE .b939 ; | it. (And by the way, it's already
b933: b9 ce ba LDA $bace,Y ; | checking for and preventing
b936: 4c 3c b9 JMP .b93c ; | wraparound.)
b939: b9 cf ba LDA $bacf,Y ; |
b93c: 18 CLC ; |
b93d: 30 09 BMI .b948 ; |
b93f: 6d 28 00 ADC $0028 ; |
b942: c9 fc CMP #$fc ; |
b944: b0 23 BCS .b969 ; |
b946: 90 09 BCC .b951 ; |
b948: 6d 28 00 ADC $0028 ; |
b94b: b0 04 BCS .b951 ; |
b94d: c9 fc CMP #$fc ; |
b94f: 90 18 BCC .b969 ; |
b951: 9d 03 07 STA $0703,X ; |
b954: b9 c6 ba LDA $bac6,Y ; |
b957: 18 CLC ; |
b958: 6d 29 00 ADC $0029 ; |
b95b: 9d 00 07 STA $0700,X ; |
b95e: c8 INY ; |
b95f: e8 INX ; |
b960: e8 INX ; |
b961: e8 INX ; |
b962: e8 INX ; |
b963: d0 bb BNE .b920 ; |
b965: 8e 55 01 STX $0155 ; |
b968: 60 RTS ; |
b969: c8 INY ; |
b96a: d0 b4 BNE .b920 ; /
*** SUBROUTINE ***
Draw title screen
bbde: 20 63 83 JSR .8363 ; Black screen
bbe1: 20 b0 83 JSR .83b0 ; Wipe name table 0
bbe4: 20 b4 83 JSR .83b4 ; Wipe name table 1
bbe7: 20 5c 84 JSR .845c ; Fill sprite area with dummy data ($0700)
bbea: a9 34 LDA #$34 ; \ Set CHR pages to 0x34
bbec: 20 f6 85 JSR .85f6 ; /
bbef: 20 fd 85 JSR .85fd ; Reset scrolling
bbf2: a9 20 LDA $#20 ; \
bbf4: 8d 20 00 STA $0020 ; | Write the title screen tiles to name table 0
bbf7: a9 81 LDA #$81 ; | Also it re-writes the address when it reaches
bbf9: 8d 21 00 STA $0021 ; | the page boundary ($2100) in PPU memory.
bbfc: a0 81 LDY #$81 ; | Utterly pointless, given how the PPU works.
bbfe: a2 00 LDX #$00 ; |
bc00: ad 20 00 LDA $0020 ; |
bc03: 8d 06 20 STA $2006 ; |
bc06: ad 21 00 LDA $0021 ; |
bc09: 8d 06 20 STA $2006 ; |
bc0c: bd 34 c6 LDA $c634,X ; |
bc0f: c9 80 CMP #$80 ; | (end-of-data code)
bc11: f0 10 BEQ .bc23 ; |
bc13: 8d 07 20 STA $2007 ; |
bc16: e8 INX ; |
bc17: c8 INY ; |
bc18: d0 f2 BNE .bc0c ; |
bc1a: 8c 21 00 STY $0021 ; |
bc1d: ee 20 00 INC $0020 ; |
bc20: 4c 00 bc JMP .bc00 ; /
bc23: a9 b0 LDA #$b0 ; \ (X-position)
bc25: 8d 21 00 STA $0021 ; | Write title screen "no" to sprite page ($0700)
bc28: a9 50 LDA #$50 ; | (Y-position)
bc2a: 8d 22 00 STA $0022 ; |
bc2d: a2 24 LDX #$24 ; |
bc2f: ac 55 01 LDY $0155 ; |
bc32: ad 22 00 LDA $0022 ; |
bc35: 99 00 07 STA $0700,Y ; |
bc38: c8 INY ; |
bc39: 8a TXA ; |
bc3a: 99 00 07 STA $0700,Y ; |
bc3d: c8 INY ; |
bc3e: a9 00 LDA #$00 ; |
bc40: 99 00 07 STA $0700,Y ; |
bc43: c8 INY ; |
bc44: ad 21 00 LDA $0021 ; |
bc47: 99 00 07 STA $0700,Y ; |
bc4a: c8 INY ; |
bc4b: e8 INX ; |
bc4c: ad 21 00 LDA $0021 ; |
bc4f: 18 CLC ; |
bc50: 69 08 ADC #$08 ; |
bc52: 8d 21 00 STA $0021 ; |
bc55: c9 c8 CMP #$c8 ; | (X-position + $18)
bc57: d0 d9 BNE .bc32 ; |
bc59: a9 b0 LDA #$b0 ; | (X-position)
bc5b: 8d 21 00 STA $0021 ; |
bc5e: ad 22 00 LDA $0022 ; |
bc61: 18 CLC ; |
bc62: 69 08 ADC #$08 ; |
bc64: 8d 22 00 STA $0022 ; |
bc67: c9 68 CMP #$68 ; | (Y-position + $18)
bc69: d0 c7 BNE .bc32 ; |
bc6b: 8c 55 01 STY $0155 ; /
bc6e: a9 01 LDA #$01 ; \
bc70: a2 22 LDX #$22 ; | Draw title screen text to name table
bc72: a0 26 LDY #$26 ; |
bc74: 20 82 be JSR .be82 ; | (1: -PUSH START BUTTON!-)
bc77: a9 02 LDA #$02 ; | (2: HI-SCORE)
bc79: a2 22 LDX #$22 ; |
bc7b: a0 88 LDY #$88 ; |
bc7d: 20 82 be JSR .be82 ; |
bc80: a9 00 LDA #$00 ; | (0: High score)
bc82: a2 22 LDX #$22 ; |
bc84: a0 92 LDY #$92 ; |
bc86: 20 82 be JSR .be82 ; |
bc89: a9 03 LDA #$03 ; | (3: © 1986 SUNSOFT)
bc8b: a2 23 LDX #$23 ; |
bc8d: a0 0a LDY #$0a ; |
bc8f: 20 82 be JSR .be82 ; |
bc92: a9 04 LDA #$04 ; | (4: SUN ELECTRONICS CORP.)
bc94: a2 23 LDX #$23 ; |
bc96: a0 46 LDY #$46 ; |
bc98: 20 82 be JSR .be82 ; /
bc9b: a2 23 LDX #$23 ; \
bc9d: a0 c0 LDY #$c0 ; | And attributes
bc9f: 20 9d 83 JSR .839d ; |
bca2: a9 55 LDA #$55 ; |
bca4: a0 20 LDY #$20 ; |
bca6: 8d 07 20 STA $2007 ; |
bca9: 88 DEY ; |
bcaa: d0 fa BNE .bca6 ; |
bcac: a9 aa LDA #$aa ; |
bcae: a0 10 LDY #$10 ; |
bcb0: 8d 07 20 STA $2007 ; |
bcb3: 88 DEY ; |
bcb4: d0 fa BNE .bcb0 ; |
bcb6: a9 ff LDA #$ff ; |
bcb8: a0 10 LDY #$10 ; |
bcba: 8d 07 20 STA $2007 ; |
bcbd: 88 DEY ; |
bcbe: d0 fa BNE .bcba ; /
bcc0: a0 20 LDY #$20
bcc2: a9 0f LDA #$0f
bcc4: 99 e0 01 STA $01e0,Y ; \
bcc7: 88 DEY ; | Blank palette stored in RAM
bcc8: d0 fa BNE .bcc4 ; /
bcca: a0 0f LDY #$0f ; \
bccc: b9 d9 bc LDA $bcd9,Y ; | Put title screen palettes in RAM
bccf: 99 e4 01 STA $01e4,Y ; |
bcd2: 88 DEY ; | $01e0 = palette stored in RAM
bcd3: 10 f7 BPL .bccc ; /
bcd5: 20 51 83 JSR .8351 ; Enable VBlank
bcd8: 60 RTS
*** SUBROUTINE ***
MYSTERY ADVENTURE START
bcea: 20 63 83 JSR .8363 ; Blackout ppu
bced: 20 74 be JSR .be74 ; Set up zone start screen
bcf0: 20 60 bd JSR .bd60 ; Draw zone start screen
bcf3: 20 b1 bd JSR .bdb1 ; Draw life counter
bcf6: a2 22 LDX #$22 ; \
bcf8: a0 24 LDY #$24 ; |
bcfa: a9 0a LDA #$0a ; | (10: MYSTERY ADVENTURE START..)
bcfc: 20 82 be JSR .be82 ; /
bcff: 4c 51 83 JMP .8351 ; Enable VBlank (and RTS)
*** SUBROUTINE ***
Draw zone start screen
bd60: ac 92 01 LDY $0192 ; \
bd63: c8 INY ; | Load zone number tilemap
bd64: 98 TYA ; |
bd65: 20 dd bd JSR .bddd ; /
bd68: a2 00 LDX #$00 ; \
bd6a: ad 92 01 LDA $0192 ; | Load ordinal indicator tilemap
bd6d: f0 1f BEQ .bd8e ; |
bd6f: e8 INX ; |
bd70: c9 01 CMP #$01 ; |
bd72: f0 1a BEQ .bd8e ; |
bd74: e8 INX ; |
bd75: c9 02 CMP #$02 ; |
bd77: f0 15 BEQ .bd8e ; |
bd79: e8 INX ; |
bd7a: c9 63 CMP #$63 ; |
bd7c: d0 10 BNE .bd8e ; |
bd7e: a9 0f LDA #$0f ; | Also replace zone number with "FIN"
bd80: 8d 20 00 STA $0020 ; | on zone 100
bd83: a9 12 LDA #$12 ; |
bd85: 8d 21 00 STA $0021 ; |
bd88: a9 17 LDA #$17 ; |
bd8a: 8d 22 00 STA $0022 ; |
bd8d: e8 INX ; |
bd8e: bd 2a c6 LDA $c62a,X ; | I wrote a better version of this.
bd91: 8d 23 00 STA $0023 ; | It fits exactly in this space.
bd94: bd 2f c6 LDA $c62f,X ; |
bd97: 8d 24 00 STA $0024 ; |
bd9a: a9 80 LDA #$80 ; |
bd9c: 8d 25 00 STA $0025 ; /
bd9f: a2 21 LDX #$21 ; \
bda1: a0 67 LDY #$67 ; | Draw the zone start screen text
bda3: a9 06 LDA #$06 ; | (6: variable)
bda5: 20 82 be JSR .be82 ; |
bda8: a2 21 LDX #$21 ; |
bdaa: a0 6d LDY #$6d ; |
bdac: a9 09 LDA #$09 ; | (9: ZONE !)
bdae: 4c 82 be JMP .be82 ; /
*** SUBROUTINE ***
Draw the life counter
bdb1: a9 28 LDA #$28 ; \
bdb3: 8d 20 00 STA $0020 ; | Draw x followed by the number of
bdb6: a9 ff LDA #$ff ; | lives
bdb8: 8d 21 00 STA $0021 ; |
bdbb: ac 94 01 LDY $0194 ; |
bdbe: c8 INY ; |
bdbf: 8c 22 00 STY $0022 ; |
bdc2: a9 80 LDA #$80 ; |
bdc4: 8d 23 00 STA $0023 ; |
bdc7: a2 23 LDX #$23 ; |
bdc9: a0 16 LDY #$16 ; |
bdcb: a9 06 LDA #$06 ; | (6: variable)
bdcd: 20 82 be JSR .be82 ; /
bdd0: a9 a0 LDA #$a0 ; \
bdd2: 8d 14 02 STA $0214 ; | Draw Wynn in the corner of the
bdd5: a9 d0 LDA #$d0 ; | screen
bdd7: 8d 15 02 STA $0215 ; |
bdda: 4c 8e b8 JMP .b88e ; /
*** SUBROUTINE ***
Put zone number tilemap in RAM
bddd: 8d 22 00 STA $0022
bde0: a9 00 LDA #$00
bde2: aa TAX
bde3: a8 TAY
bde4: ad 22 00 LDA $0022
bde7: c9 64 CMP #$64
bde9: 30 07 BMI .bdf2
bdeb: e8 INX
bdec: 38 SEC
bded: e9 64 SBC #$64
bdef: 4c e7 bd JMP .bde7
bdf2: c9 0a CMP #$0a
bdf4: 30 07 BMI .bdfd
bdf6: c8 INY
bdf7: 38 SEC
bdf8: e9 0a SBC #$0a
bdfa: 4c f2 bd JMP .bdf2
bdfd: e0 00 CPX #$00
bdff: d0 08 BNE .be09
be01: a2 ff LDX #$ff
be03: c0 00 CPY #$00
be05: d0 02 BNE .be09
be07: a0 ff LDY #$ff
be09: 8e 20 00 STX $0020
be0c: 8c 21 00 STY $0021
be0f: 8d 22 00 STA $0022
be12: a9 80 LDA #$80 ; \ This code only makes sense if this sub
be14: 8d 23 00 STA $0023 ; / is called from elsewhere.
be17: 60 RTS
*** SUBROUTINE ***
Set up zone start screen
be74: 20 5c 84 JSR .845c ; Clear sprites
be77: 20 b0 83 JSR .83b0 ; Clear name table 0
be7a: a9 34 LDA #$34 ; \ Set CHR to page #$34
be7c: 20 f6 85 JSR .85f6 ; /
be7f: 4c fd 85 JMP .85fd ; Reset scroll (then RTS)
*** SUBROUTINE ***
Draw title\zone start screen text
be82: 48 PHA
be83: 20 9d 83 JSR .839d ; Set up PPU
be86: 68 PLA
be87: 0a ASL A
be88: aa TAX
be89: bd 7f c5 LDA $c57f,X ; \
be8c: 8d 1e 00 STA $001e ; |
be8f: e8 INX ; | Prepare address for indirect-Y access
be90: bd 7f c5 LDA $c57f,X ; |
be93: 8d 1f 00 STA $001f ; /
be96: a0 00 LDY #$00
be98: b1 1e LDA ($1e),Y
be9a: c9 80 CMP #$80 ; End-of-data code
be9c: f0 07 BEQ .bea5
be9e: 8d 07 20 STA $2007
bea1: c8 INY
bea2: 4c 98 be JMP .be98
bea5: 60 RTS
*** SUBROUTINE ***
Initialize sound engine
c734: a2 40 LDX #$40 ; \
c736: a9 ff LDA #$ff ; | Fill $0030-$006f
c738: 9d 2f 00 STA $002f,X ; | with #$ff
c73b: ca DEX ; |
c73c: d0 fa BNE .c738 ; /
c73e: 8e 0b 00 STX $000b
c741: 8e 15 40 STX $4015 ; Mute everything
c744: 60 RTS
*** SUBROUTINE ***
Load data to sound engine
c745: 0a ASL A
c746: aa TAX
c747: bd 4d c9 LDA $c94d,X
c74a: 8d 1e 00 STA $001e
c74d: bd 4e c9 LDA $c94e,X
c750: 8d 1f 00 STA $001f
c753: a0 00 LDY #$00
c755: b1 1e LDA ($1e),Y
c757: 8d 2e 00 STA $002e
c75a: c8 INY
c75b: b1 1e LDA ($1e),Y
c75d: aa TAX
c75e: a9 01 LDA #$01
c760: 9d 54 00 STA $0054,X
c763: a9 ff LDA #$ff
c765: 9d 60 00 STA $0060,X
c768: c8 INY
c769: b1 1e LDA ($1e),Y
c76b: 9d 30 00 STA $0030,X
c76e: 8a TXA
c76f: 18 CLC
c770: 69 06 ADC #$06
c772: aa TAX
c773: e0 24 CPX #$24
c775: 90 f1 BCC .c768
c777: ce 2e 00 DEC $002e
c77a: d0 de BNE .c75a
c77c: 60 RTS
*** IRQ/BRK HANDLER ***
fff9: 40 RTI
fffa: 44 80 .addr $8044 ; NMI
fffc: 00 80 .addr $8000 ; Reset
fffe: f9 ff .addr $fff9 ; IRQ/BRK