If you appreciate the work done within the wiki, please consider supporting The Cutting Room Floor on Patreon. Thanks for all your support!
Notes:The Mystery of Atlantis
Jump to navigation
Jump to search
This page contains notes for the game The Mystery of Atlantis.
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