User Tools

Site Tools


m1:disassembly:game_engine_page

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

m1:disassembly:game_engine_page [2016/03/06 17:29] – created - external edit 127.0.0.1m1:disassembly:game_engine_page [2025/06/18 09:34] (current) felixwright
Line 1: Line 1:
-The game engine bank contains most of the code for the game engine. +~~REDIRECT>m1:docs:disasm:engine~~
-<code> +
-; ------------------- +
-; METROID source code +
-; ------------------- +
-; MAIN PROGRAMMERS +
-;     HAI YUKAMI +
-;   ZARU SOBAJIMA +
-;    GPZ SENGOKU +
-;    N.SHIOTANI +
-;     M.HOUDAI +
-; (C) 1986 NINTENDO +
-+
-; Disassembled, reconstructed and commented +
-; by SnowBro [Kent Hansen] <kentmhan@online.no> +
-; Continued by Dirty McDingus (nmikstas@yahoo.com) +
-; Can be reassembled using Ophis. +
-; A work in progress. +
-;Last updated3/9/2010 +
- +
-;Hosted on wiki.metroidconstruction.com, with possible additions by wiki contributors. +
- +
-;Game engine (memory page 7) +
- +
-.org $C000 +
- +
-.include "MetroidDefines.txt" +
- +
-;-------------------------------------[ Forward declarations ]-------------------------------------- +
- +
-.alias ObjectAnimIndexTbl       $8572 +
-.alias FramePtrTable            $860B +
-.alias PlacePtrTable            $86DF +
-.alias StarPalSwitch            $8AC7 +
-.alias SamusEnterDoor           $8B13 +
-.alias AreaPointers             $9598 +
-.alias AreaRoutine              $95C3 +
-.alias EnemyHitPointTbl         $962B +
-.alias EnemyInitDelayTbl        $96BB +
-.alias DecSpriteYCoord          $988A +
-.alias NMIScreenWrite           $9A07 +
-.alias EndGamePalWrite          $9F54 +
-.alias SpecItmsTable            $9598 +
-.alias CopyMap                  $A93E +
-.alias SoundEngine              $B3B4 +
- +
-;----------------------------------------[ Start of code ]------------------------------------------ +
- +
-;This routine generates pseudo random numbers and updates those numbers +
-;every frame. The random numbers are used for several purposes including +
-;password scrambling and determinig what items, if any, an enemy leaves +
-;behind after it is killed. +
- +
-RandomNumbers: +
-LC000 txa                             ;                +
-LC001:  pha                             ; +
-LC002:  ldx #$05                        ; +
-LC004:* lda RandomNumber1               ; +
-LC006:  clc                             ; +
-LC007:  adc #$05                        ; +
-LC009:  sta RandomNumber1               ;2E is increased by #$19 every frame and--> +
-LC00B:  lda RandomNumber2               ;2F is increased by #$5F every frame.                    +
-LC00D:  clc                             ; +
-LC00E:  adc #$13                        ; +
-LC010:  sta RandomNumber2               ; +
-LC012:  dex                             ; +
-LC013:  bne -                           ; +
-LC015:  pla                             ; +
-LC016:  tax                             ; +
-LC017:  lda RandomNumber1               ; +
-LC019:  rts                             ; +
- +
-;------------------------------------------[ Startup ]---------------------------------------------- +
- +
-Startup: +
-LC01A:  lda #$00                        ; +
-LC01C:  sta MMC1Reg1                    ;Clear bit 0. MMC1 is serial controlled +
-LC01F:  sta MMC1Reg1                    ;Clear bit 1 +
-LC022:  sta MMC1Reg1                    ;Clear bit 2 +
-LC024:  sta MMC1Reg1                    ;Clear bit 3 +
-LC027:  sta MMC1Reg1                    ;Clear bit 4  +
-LC02B:  sta MMC1Reg2                    ;Clear bit 0 +
-LC02E:  sta MMC1Reg2                    ;Clear bit 1 +
-LC031:  sta MMC1Reg2                    ;Clear bit 2 +
-LC034:  sta MMC1Reg2                    ;Clear bit 3 +
-LC037:  sta MMC1Reg2                    ;Clear bit 4  +
-LC03A:  jsr MMCWriteReg3                ;($C4FA)Swap to PRG bank #0 at $8000 +
-LC03D:  dex                             ;X = $FF +
-LC03E:  txs                             ;S points to end of stack page +
- +
-;Clear RAM at $000-$7FF. +
-LC03F:  ldy #$07                        ;High byte of start address. +
-LC041:  sty $01                         ; +
-LC043:  ldy #$00                        ;Low byte of start address. +
-LC045:  sty $00                         ;$0000 = #$0700 +
-LC047:  tya                             ;A = 0 +
-LC048:* sta ($00),                    ;clear address +
-LC04A:  iny                             ; +
-LC04B:  bne -                           ;Repeat for entire page. +
-LC04D:  dec $01                         ;Decrement high byte of address. +
-LC04F:  bmi +                           ;If $01 < 0, all pages are cleared. +
-LC051:  ldx $01                         ; +
-LC053:  cpx #$01                        ;Keep looping until ram is cleared. +
-LC055:  bne -                           ; +
- +
-;Clear cartridge RAM at $6000-$7FFF. +
-LC057:* ldy #$7F                        ;High byte of start address. +
-LC059:  sty $01                         ; +
-LC05B:  ldy #$00                        ;Low byte of start address. +
-LC05D:  sty $00                         ;$0000 points to $7F00 +
-LC05F:  tya                             ;A = 0 +
-LC060:* sta ($00),                    ; +
-LC062:  iny                             ;Clears 256 bytes of memory before decrementing to next--> +
-LC063:  bne -                           ;256 bytes. +
-LC065:  dec $01                         ; +
-LC067:  ldx $01                         ;Is address < $6000?--> +
-LC069:  cpx #$60                        ;If not, do another page. +
-LC06B:  bcs -                           ;  +
- +
-LC06D:  lda #%00001110                  ;Verticle mirroring. +
-                                        ;H/V mirroring (As opposed to one-screen mirroring). +
-                                        ;Switch low PRGROM area during a page switch. +
-                                        ;16KB PRGROM switching enabled. +
-                                        ;8KB CHRROM switching enabled. +
-LC06F:  sta MMCReg0Cntrl                ; +
- +
-LC071:  lda #$00                        ;Clear bits 3 and 4 of MMC1 register 3. +
-LC073:  sta SwitchUpperBits             ; +
- +
-LC075:  ldy #$00                        ; +
-LC077:  sty ScrollX                     ;ScrollX = 0 +
-LC079:  sty ScrollY                     ;ScrollY = 0 +
-LC07B:  sty PPUScroll                   ;Clear hardware scroll x +
-LC07E:  sty PPUScroll                   ;Clear hardware scroll y +
-LC081:  iny                             ;Y = #$01 +
-LC082:  sty GameMode                    ;Title screen mode +
-LC084:  jsr ClearNameTables             ;($C158) +
-LC087:  jsr EraseAllSprites             ;($C1A3) +
- +
-LC08A:  lda #%10010000                  ;NMI = enabled +
-                                        ;Sprite size = 8x8 +
-                                        ;BG pattern table address = $1000 +
-                                        ;SPR pattern table address = $0000 +
-                                        ;PPU address increment = 1 +
-                                        ;Name table address = $2000 +
-LC08C:  sta PPUControl0                 ; +
-LC08F:  sta PPUCNT0ZP                   ; +
- +
-LC091:  lda #%00000010                  ;Sprites visible = no +
-                                        ;Background visible = no +
-                                        ;Sprite clipping = yes +
-                                        ;Background clipping = no +
-                                        ;Display type = color +
-LC093:  sta PPUCNT1ZP                   ; +
- +
-LC095:  lda #$47                        ; +
-LC097:  sta MirrorCntrl                 ;Prepare to set PPU to vertical mirroring. +
-LC099:  jsr PrepVertMirror              ;($C4B2) +
- +
-LC09C:  lda #$00                        ; +
-LC09E:  sta DMCCntrl1                   ;PCM volume = 0 - disables DMC channel +
-LC0A1:  lda #$0F                        ; +
-LC0A3:  sta APUCommonCntrl0             ;Enable sound channel 0,1,2,3 +
- +
-LC0A6:  ldy #$00                        ; +
-LC0A8:  sty TitleRoutine                ;Set title routine and and main routine function--> +
-LC0AA:  sty MainRoutine                 ;pointers equal to 0. +
-LC0AC:  lda #$11                        ; +
-LC0AE:  sta RandomNumber1               ;Initialize RandomNumber1 to #$11 +
-LC0B0:  lda #$FF                        ; +
-LC0B2:  sta RandomNumber2               ;Initialize RandomNumber2 to #$FF +
- +
-LC0B4:  iny                             ;Y = 1 +
-LC0B5:  sty SwitchPending               ;Prepare to switch page 0 into lower PRGROM. +
-LC0B7:  jsr CheckSwitch                 ;($C4DE) +
-LC0BA:  bne WaitNMIEnd                  ;Branch always +
- +
-;-----------------------------------------[ Main loop ]---------------------------------------------- +
- +
-;The main loop runs all the routines that take place outside of the NMI. +
- +
-MainLoop: +
-LC0BC:  jsr CheckSwitch                 ;($C4DE)Check to see if memory page needs to be switched. +
-LC0BF:  jsr UpdateTimer                 ;($C266)Update Timers 1, 2 and 3. +
-LC0C2:  jsr GoMainRoutine               ;($C114)Go to main routine for updating game. +
-LC0C5:  inc FrameCount                  ;Increment frame counter. +
-LC0C7:  lda #$00                        ; +
-LC0C9:  sta NMIStatus                   ;Wait for next NMI to end. +
- +
-WaitNMIEnd: +
-LC0CB:  tay                             ; +
-LC0CC:  lda NMIStatus                   ; +
-LC0CE:  bne +                           ;If nonzero, NMI has ended. Else keep waiting. +
-LC0D0:  jmp WaitNMIEnd                  ; +
- +
-LC0D3:* jsr RandomNumbers               ;($C000)Update pseudo random numbers. +
-LC0D6:  jmp MainLoop                    ;($C0BC)Jump to top of subroutine. +
- +
-;-------------------------------------[ Non-Maskable Interrupt ]------------------------------------- +
- +
-;The NMI is called 60 times a second by the VBlank signal from the PPU. When the +
-;NMI routine is called, the game should already be waiting for it in the main  +
-;loop routine in the WaitNMIEnd loop.  It is possible that the main loop routine +
-;will not be waiting as it is bogged down with excess calculations. This causes +
-;the game to slow down. +
- +
-NMI: +
-LC0D9:  php                             ;Save processor status, A, X and Y on stack. +
-LC0DA:  pha                             ;Save A. +
-LC0DB:  txa                             ; +
-LC0DC:  pha                             ;Save X. +
-LC0DD:  tya                             ; +
-LC0DE:  pha                             ;Save Y. +
-LC0DF:  lda #$00                        ; +
-LC0E1:  sta SPRAddress                  ;Sprite RAM address = 0. +
-LC0E4:  lda #$02                        ; +
-LC0E6:  sta SPRDMAReg                   ;Transfer page 2 ($200-$2FF) to Sprite RAM. +
-LC0E9:  lda NMIStatus                   ; +
-LC0EB:  bne ++                          ;Skip if the frame couldn't finish in time. +
-LC0ED:  lda GameMode                    ; +
-LC0EF:  beq +                           ;Branch if mode=Play. +
-LC0F1:  jsr NMIScreenWrite              ;($9A07)Write end message on screen(If appropriate). +
-LC0F4:* jsr CheckPalWrite               ;($C1E0)Check if palette data pending. +
-LC0F7:  jsr CheckPPUWrite               ;($C2CA)check if data needs to be written to PPU. +
-LC0FA:  jsr WritePPUCtrl                ;($C44D)Update $2000 & $2001. +
-LC0FD:  jsr WriteScroll                 ;($C29A)Update h/v scroll reg. +
-LC100:  jsr ReadJoyPads                 ;($C215)Read both joypads. +
-LC103:* jsr SoundEngine                 ;($B3B4)Update music and SFX. +
-LC106:  jsr UpdateAge                   ;($C97E)Update Samus' age. +
-LC109:  ldy #$01                        ; NMI = finished. +
-LC10B:  sty NMIStatus                   ; +
-LC10D:  pla                             ;Restore Y. +
-LC10E:  tay                             ; +
-LC10F:  pla                             ;Restore X. +
-LC110:  tax                             ; +
-LC111:  pla                             ;restore A. +
-LC112:  plp                             ;Restore processor status flags. +
-LC113:  rti                             ;Return from NMI. +
- +
-;----------------------------------------[ GoMainRoutine ]------------------------------------------- +
- +
-;This is where the real code of each frame is executed. +
-;MainRoutine or TitleRoutine (Depending on the value of GameMode) +
-;is used as an index into a code pointer table, and this routine +
-;is executed. +
- +
-GoMainRoutine: +
-LC114:  lda GameMode                    ;0 if game is running, 1 if at intro screen. +
-LC116:  beq +                           ;Branch if mode=Play. +
-LC118:  jmp $8000                       ;Jump to $8000, where a routine similar to the one--> +
-                                        ;below is executed, only using TitleRoutine instead +
-                                        ;of MainRoutine as index into a jump table. +
-LC11B:* lda Joy1Change                  ; +
-LC11D:  and #$10                        ;Has START been pressed?--> +
-LC11F:  beq +++                         ;if not, execute current routine as normal. +
- +
-LC121:  lda MainRoutine                 ; +
-LC123:  cmp #$03                        ;Is game engine running?--> +
-LC125:  beq +                           ;If yes, check for routine #5 (pause game). +
-LC127:  cmp #$05                        ;Is game paused?--> +
-LC129:  bne +++                         ;If not routine #5 either, don't care about START being pressed. +
-LC12B:  lda #$03                        ;Otherwise, switch to routine #3 (game engine). +
-LC12D:  bne ++                          ;Branch always. +
-LC12F:* lda #$05                        ;Switch to pause routine. +
-LC131:* sta MainRoutine                 ;(MainRoutine = 5 if game paused, 3 if game engine running). +
-LC133:  lda GamePaused                  ; +
-LC135:  eor #$01                        ;Toggle game paused. +
-LC137:  sta GamePaused                  ; +
-LC139:  jsr PauseMusic                  ;($CB92)Silences music while game paused. +
- +
-LC13c:* lda MainRoutine                 ; +
-LC13E:  jsr ChooseRoutine               ;($C27C)Use MainRoutine as index into routine table below. +
- +
-;Pointer table to code. +
- +
-LC141:  .word AreaInit                  ;($C801)Area init. +
-LC143:  .word MoreInit                  ;($C81D)More area init. +
-LC145:  .word SamusInit                 ;($C8D1)Samus init. +
-LC147:  .word GameEngine                ;($C92B)Game engine. +
-LC149:  .word GameOver                  ;($C9A6)Display GAME OVER. +
-LC14B:  .word PauseMode                 ;($C9B1)Pause game. +
-LC14D:  .word GoPassword                ;($C9C4)Display password. +
-LC14F:  .word IncrementRoutine          ;($C155)Just advances to next routine in table. +
-LC151:  .word SamusIntro                ;($C9D7)Intro. +
-LC153:  .word WaitTimer                 ;($C494)Delay. +
- +
-IncrementRoutine: +
-LC155:  inc MainRoutine                 ;Increment to next routine in above table. +
-LC157:  rts                             ; +
- +
-;-------------------------------------[ Clear name tables ]------------------------------------------ +
- +
-ClearNameTables: +
-LC158:  jsr ClearNameTable0             ;($C16D)Always clear name table 0 first. +
-LC15B:  lda GameMode                    ; +
-LC15D:  beq +                           ;Branch if mode = Play. +
-LC15F:  lda TitleRoutine                ; +
-LC161:  cmp #$1D                        ;If running the end game routine, clear--> +
-LC163:  beq ++                          ;name table 2, else clear name table 1. +
-LC165:* lda #$02                        ;Name table to clear + 1 (name table 1). +
-LC167:  bne +++                         ;Branch always. +
-LC169:* lda #$03                        ;Name table to clear + 1 (name table 2). +
-LC16B:  bne ++                          ;Branch always. +
- +
-ClearNameTable0: +
-LC16D:* lda #$01                        ;Name table to clear + 1 (name table 0). +
-LC16F:* sta $01                         ;Stores name table to clear. +
-LC171:  lda #$FF                        ; +
-LC173:  sta $00                         ;Value to fill with. +
- +
-ClearNameTable: +
-LC175:  ldx PPUStatus                   ;Reset PPU address latch. +
-LC178:  lda PPUCNT0ZP                   ; +
-LC17A:  and #$FB                        ;PPU increment = 1. +
-LC17C:  sta PPUCNT0ZP                   ; +
-LC17E:  sta PPUControl0                 ;Store control bits in PPU. +
-LC181:  ldx $01                         ; +
-LC183:  dex                             ;Name table = X - 1. +
-LC184:  lda HiPPUTable,               ;get high PPU address.  pointer table at $C19F. +
-LC187:  sta PPUAddress                  ; +
-LC18A:  lda #$00                        ;Set PPU start address (High byte first). +
-LC18C:  sta PPUAddress                  ; +
-LC18F:  ldx #$04                        ;Prepare to loop 4 times. +
-LC191:  ldy #$00                        ;Inner loop value. +
-LC193:  lda $00                         ;Fill-value. +
-LC195:* sta PPUIOReg                    ; +
-LC198:  dey                             ; +
-LC199:  bne -                           ;Loops until the desired name table is cleared.--> +
-LC19B:  dex                             ;It also clears the associated attribute table. +
-LC19C:  bne -                           ; +
-LC19E:  rts                             ; +
- +
-;The following table is used by the above routine for finding +
-;the high byte of the proper name table to clear. +
- +
-HiPPUTable: +
-LC19F:  .byte $20                       ;Name table 0. +
-LC1A0:  .byte $24                       ;Name table 1. +
-LC1A1:  .byte $28                       ;Name table 2. +
-LC1A2:  .byte $2C                       ;Name table 3. +
- +
-;-------------------------------------[ Erase all sprites ]------------------------------------------ +
- +
-EraseAllSprites: +
-LC1A3:  ldy #$02                        ; +
-LC1A5:  sty $01                         ;Loads locations $00 and $01 with --> +
-LC1A7:  ldy #$00                        ;#$00 and #$02 respectively +
-LC1A9:  sty $00                         ; +
-LC1AB:  ldy #$00                        ; +
-LC1AD:  lda #$F0                        ; +
-LC1AF:* sta ($00),                    ;Stores #$F0 in memory addresses $0200 thru $02FF. +
-LC1B1:  iny                             ;  +
-LC1B2:  bne -                           ;Loop while more sprite RAM to clear. +
-LC1B4:  lda GameMode                    ; +
-LC1B6:  beq Exit101                     ;Exit subroutine if GameMode=Play(#$00) +
-LC1B8:  jmp DecSpriteYCoord             ;($988A)Find proper y coord of sprites. +
- +
-Exit101: +
-LC1BB:  rts                             ;Return used by subroutines above and below. +
- +
-;---------------------------------------[ Remove intro sprites ]------------------------------------- +
- +
-;The following routine is used in the Intro to remove the sparkle sprites and the crosshairs +
-;sprites every frame.  It does this by loading the sprite values with #$F4 which moves the  +
-;sprite to the bottom right of the screen and uses a blank graphic for the sprite. +
- +
-RemoveIntroSprites: +
-LC1BC:  ldy #$02                        ;Start at address $200. +
-LC1BE:  sty $01                         ; +
-LC1C0:  ldy #$00                        ; +
-LC1C2:  sty $00                         ;($00) = $0200 (sprite page) +
-LC1C4:  ldy #$5F                        ;Prepare to clear RAM $0200-$025F +
-LC1C6:  lda #$F4                        ; +
-LC1C8:* sta ($00),                    ; +
-LC1CA:  dey                             ;Loop unitl $200 thru $25F is filled with #$F4. +
-LC1CB:  bpl -                           ; +
-LC1CD:  lda GameMode                    ; +
-LC1CF:  beq Exit101                     ; branch if mode = Play. +
-LC1D1:  jmp DecSpriteYCoord             ;($988A)Find proper y coord of sprites. +
- +
-;-------------------------------------[Clear RAM $33 thru $DF]--------------------------------------- +
- +
-;The routine below clears RAM associated with rooms and enemies. +
- +
-ClearRAM_33_DF: +
-LC1D4:  ldx #$33                        ; +
-LC1D6:  lda #$00                        ; +
-LC1D8:* sta $00,x                       ;Clear RAM addresses $33 through $DF. +
-LC1DA:  inx                             ; +
-LC1DB:  cpx #$E0                        ; +
-LC1DD:  bcc -                           ;Loop until all desired addresses are cleared. +
-LC1DF:  rts                             ; +
- +
-;--------------------------------[ Check and prepare palette write ]--------------------------------- +
- +
-CheckPalWrite: +
-LC1E0:  lda GameMode                    ; +
-LC1E2:  beq +                           ;Is game being played? If so, branch to exit. +
-LC1E4:  lda TitleRoutine                ; +
-LC1E6:  cmp #$1D                        ;Is Game at ending sequence? If not, branch +
-LC1E8:  bcc +                           ; +
-LC1EA:  jmp EndGamePalWrite             ;($9F54)Write palette data for ending. +
-LC1ED:* ldy PalDataPending              ; +
-LC1EF:  bne ++                          ;Is palette data pending? If so, branch. +
-LC1F1:  lda GameMode                    ; +
-LC1F3:  beq +                           ;Is game being played? If so, branch to exit. +
-LC1F5:  lda TitleRoutine                ; +
-LC1F7:  cmp #$15                        ;Is intro playing? If not, branch. +
-LC1F9:  bcs +                           ; +
-LC1FB:  jmp StarPalSwitch               ;($8AC7)Cycles palettes for intro stars twinkle. +
-LC1FE:* rts                             ;Exit when no palette data pending. +
- +
-;Prepare to write palette data to PPU. +
- +
-LC1FF:* dey                             ;Palette # = PalDataPending - 1. +
-LC200:  tya                             ; +
-LC201:  asl                             ;* 2, each pal data ptr is 2 bytes (16-bit). +
-LC202:  tay                             ; +
-LC203:  ldx $9560,                    ;X = low byte of PPU data pointer. +
-LC206:  lda $9561,                    ; +
-LC209:  tay                             ;Y = high byte of PPU data pointer. +
-LC20A:  lda #$00                        ;Clear A. +
-LC20C:  sta PalDataPending              ;Reset palette data pending byte. +
- +
-PreparePPUProcess_: +
-LC20E:  stx $00                         ;Lower byte of pointer to PPU string. +
-LC210:  sty $01                         ;Upper byte of pointer to PPU string. +
-LC212:  jmp ProcessPPUString            ;($C30C)Write data string to PPU. +
- +
-;----------------------------------------[Read joy pad status ]-------------------------------------- +
- +
-;The following routine reads the status of both joypads +
- +
-ReadJoyPads: +
-LC215:  ldx #$00                        ;Load x with #$00. Used to read status of joypad 1. +
-LC217:  stx $01                         ; +
-LC219:  jsr ReadOnePad                  ; +
-LC21C:  inx                             ;Load x with #$01. Used to read status of joypad 2. +
-LC21D:  inc $01                         ; +
- +
-ReadOnePad: +
-LC21F:  ldy #$01                        ;These lines strobe the -->        +
-LC221:  sty CPUJoyPad1                  ;joystick to enable the --> +
-LC224:  dey                             ;program to read the --> +
-LC225:  sty CPUJoyPad1                  ;buttons pressed. +
-         +
-LC228:  ldy #$08                        ;Do 8 buttons. +
-LC22A:* pha                             ;Store A. +
-LC22B:  lda CPUJoyPad1,               ;Read button status. Joypad 1 or 2. +
-LC22E:  sta $00                         ;Store button press at location $00. +
-LC230:  lsr                             ;Move button push to carry bit. +
-LC231:  ora $00                         ;If joystick not connected, --> +
-LC233:  lsr                             ;fills Joy1Status with all 1s. +
-LC234:  pla                             ;Restore A. +
-LC235:  rol                             ;Add button press status to A. +
-LC236:  dey                             ;Loop 8 times to get --> +
-LC237:  bne -                           ;status of all 8 buttons. +
- +
-LC239:  ldx $01                         ;Joypad #(0 or 1). +
-LC23B:  ldy Joy1Status,               ;Get joypad status of previous refresh. +
-LC23D:  sty $00                         ;Store at $00. +
-LC23F:  sta Joy1Status,               ;Store current joypad status. +
-LC241:  eor $00                         ; +
-LC243:  beq +                           ;Branch if no buttons changed. +
-LC245:  lda $00                         ;                        +
-LC247:  and #$BF                        ;Remove the previous status of the B button. +
-LC249:  sta $00                         ; +
-LC24B:  eor Joy1Status,               ; +
-LC24D:* and Joy1Status,               ;Save any button changes from the current frame--> +
-LC24F:  sta Joy1Change,               ;and the last frame to the joy change addresses. +
-LC251:  sta Joy1Retrig,               ;Store any changed buttons in JoyRetrig address. +
-LC253:  ldy #$20                        ; +
-LC255:  lda Joy1Status,               ;Checks to see if same buttons are being--> +
-LC257:  cmp $00                         ;pressed this frame as last frame.--> +
-LC259:  bne +                           ;If none, branch. +
-LC25B:  dec RetrigDelay1,             ;Decrement RetrigDelay if same buttons pressed. +
-LC25D:  bne ++                          ;                +
-LC25F:  sta Joy1Retrig,               ;Once RetrigDelay=#$00, store buttons to retrigger. +
-LC261:  ldy #$08                        ; +
-LC263:* sty RetrigDelay1,             ;Reset retrigger delay to #$20(32 frames)--> +
-LC265:* rts                             ;or #$08(8 frames) if already retriggering. +
- +
-;-------------------------------------------[ Update timer ]----------------------------------------- +
- +
-;This routine is used for timing - or for waiting around, rather. +
-;TimerDelay is decremented every frame. When it hits zero, $2A, $2B and $2C are +
-;decremented if they aren't already zero. The program can then check +
-;these variables (it usually just checks $2C) to determine when it's time +
-;to "move on". This is used for the various sequences of the intro screen, +
-;when the game is started, when Samus takes a special item, and when GAME +
-;OVER is displayed, to mention a few examples. +
- +
-UpdateTimer: +
-LC266:  ldx #$01                        ;First timer to decrement is Timer2. +
-LC268:  dec TimerDelay                  ; +
-LC26A:  bpl DecTimer                    ; +
-LC26C:  lda #$09                        ;TimerDelay hits #$00 every 10th frame. +
-LC26E:  sta TimerDelay                  ;Reset TimerDelay after it hits #$00. +
-LC270:  ldx #$02                        ;Decrement Timer3 every 10 frames. +
- +
-DecTimer: +
-LC272:  lda Timer1,                   ; +
-LC274:  beq +                           ;Don't decrease if timer is already zero. +
-LC276:  dec Timer1,                   ; +
-LC278:* dex                             ;Timer1 and Timer2 decremented every frame. +
-LC279:  bpl DecTimer                    ; +
-LC27B:  rts                             ; +
- +
-;-----------------------------------------[ Choose routine ]----------------------------------------- +
- +
-;This is an indirect jump routine. A is used as an index into a code +
-;pointer table, and the routine at that position is executed. The programmers +
-;always put the pointer table itself directly after the JSR to ChooseRoutine, +
-;meaning that its address can be popped from the stack. +
- +
-ChooseRoutine: +
-LC27C:  asl                             ;* 2, each ptr is 2 bytes (16-bit). +
-LC27D:  sty TempY                       ;Temp storage. +
-LC27F:  stx TempX                       ;Temp storage. +
-LC281:  tay                             ; +
-LC282:  iny                             ; +
-LC283:  pla                             ;Low byte of ptr table address. +
-LC284:  sta CodePtr                     ; +
-LC286:  pla                             ;High byte of ptr table address. +
-LC287:  sta CodePtr+1                   ; +
-LC289:  lda (CodePtr),                ;Low byte of code ptr. +
-LC28B:  tax                             ; +
-LC28C:  iny                             ; +
-LC28D:  lda (CodePtr),                ;High byte of code ptr. +
-LC28F:  sta CodePtr+1                   ; +
-LC291:  stx CodePtr                     ; +
-LC293:  ldx TempX                       ;Restore X. +
-LC295:  ldy TempY                       ;Restore Y. +
-LC297:  jmp (CodePtr)                   ; +
- +
-;--------------------------------------[ Write to scroll registers ]--------------------------------- +
- +
-WriteScroll: +
-LC29A:  lda PPUStatus                   ;Reset scroll register flip/flop +
-LC29D:  lda ScrollX                     ; +
-LC29F:  sta PPUScroll                   ; +
-LC2A2:  lda ScrollY                     ;X and Y scroll offsets are loaded serially. +
-LC2A4:  sta PPUScroll                   ; +
-LC2A7:  rts                             ; +
- +
-;----------------------------------[ Add y index to stored addresses ]------------------------------- +
- +
-;Add Y to pointer at $0000.  +
- +
-AddYToPtr00: +
-LC2A8:  tya                             ; +
-LC2A9:  clc                             ;Add value stored in Y to lower address--> +
-LC2AA:  adc $00                         ;byte stored in $00. +
-LC2AC:  sta $00                         ; +
-LC2AE:  bcc +                           ;Increment $01(upper address byte) if carry--> +
-LC2B0:  inc $01                         ;has occurred. +
-LC2B2:* rts                             ; +
- +
-;Add Y to pointer at $0002 +
- +
-AddYToPtr02: +
-LC2B3:  tya                             ; +
-LC2B4:  clc                             ;Add value stored in Y to lower address--> +
-LC2B5:  adc $02                         ;byte stored in $02. +
-LC2B7:  sta $02                         ; +
-LC2B9:  bcc +                           ;Increment $01(upper address byte) if carry--> +
-LC2BB:  inc $03                         ;has occurred. +
-LC2BD:* rts                             ; +
- +
-;--------------------------------[ Simple divide and multiply routines ]----------------------------- +
- +
-Adiv32:  +
-LC2BE:  lsr                             ;Divide by 32. +
- +
-Adiv16:  +
-LC2BF:  lsr                             ;Divide by 16. +
- +
-Adiv8:   +
-LC2C0:  lsr                             ;Divide by 8. +
-LC2C1:  lsr                             ; +
-LC2C2:  lsr                             ;Divide by shifting A right. +
-LC2C3:  rts                             ; +
- +
-Amul32:  +
-LC2C4:  asl                             ;Multiply by 32. +
- +
-Amul16:  +
-LC2C5:  asl                             ;Multiply by 16. +
- +
-Amul8: +
-LC2C6:  asl                             ;Multiply by 8. +
-LC2C7:  asl                             ; +
-LC2C8:  asl                             ;Multiply by shifting A left. +
-LC2C9:  rts                             ; +
- +
-;-------------------------------------[ PPU writing routines ]--------------------------------------- +
- +
-;Checks if any data is waiting to be written to the PPU. +
-;RLE data is one tile that repeats several times in a row.  RLE-Repeat Last Entry +
- +
-CheckPPUWrite: +
-LC2CA:  lda PPUDataPending              ; +
-LC2CC:  beq +                           ;If zero no PPU data to write, branch to exit. +
-LC2CE:  lda #$A1                        ;                        +
-LC2D0:  sta $00                         ;Sets up PPU writer to start at address $07A1. +
-LC2D2:  lda #$07                        ; +
-LC2D4:  sta $01                         ;$0000 = ptr to PPU data string ($07A1). +
-LC2D6:  jsr ProcessPPUString            ;($C30C)write it to PPU. +
-LC2D9:  lda #$00                        ; +
-LC2DB:  sta PPUStrIndex                 ;PPU data string has been written so the data--> +
-LC2DE:  sta PPUDataString               ;stored for the write is now erased. +
-LC2E1:  sta PPUDataPending              ; +
-LC2E3:* rts                             ; +
- +
-PPUWrite: +
-LC2E4:  sta PPUAddress                  ;Set high PPU address. +
-LC2E7:  iny                             ; +
-LC2E8:  lda ($00),                    ; +
-LC2EA:  sta PPUAddress                  ;Set low PPU address. +
-LC2ED:  iny                             ; +
-LC2EE:  lda ($00),                    ;Get data byte containing rep length & RLE status. +
-LC2F0:  asl                             ;Carry Flag = PPU address increment (0 = 1, 1 = 32). +
-LC2F1:  jsr SetPPUInc                   ;($C318)Update PPUCtrl0 according to Carry Flag. +
-LC2F4:  asl                             ;Carry Flag = bit 6 of byte at ($00),y (1 = RLE). +
-LC2F5:  lda ($00),                    ;Get data byte again. +
-LC2F7:  and #$3F                        ;Keep lower 6 bits as loop counter. +
-LC2F9:  tax                             ; +
-LC2FA:  bcc PPUWriteLoop                ;If Carry Flag not set, the data is not RLE. +
-LC2FC:  iny                             ;Data is RLE, advance to data byte. +
- +
-PPUWriteLoop: +
-LC2FD:  bcs +                           ; +
-LC2FF:  iny                             ;Only inc Y if data is not RLE. +
-LC300:* lda ($00),                    ;Get data byte. +
-LC302:  sta PPUIOReg                    ;Write to PPU. +
-LC305:  dex                             ;Decrease loop counter. +
-LC306:  bne PPUWriteLoop                ;Keep going until X=0. +
-LC308:  iny                             ; +
-LC309:  jsr AddYToPtr00                 ;($C2A8)Point to next data chunk. +
- +
-;Write data string at ($00) to PPU. +
- +
-ProcessPPUString: +
-LC30C:  ldx PPUStatus                   ;Reset PPU address flip/flop. +
-LC30F:  ldy #$00                        ; +
-LC311:  lda ($00),                    ; +
-LC313:  bne PPUWrite                    ;If A is non-zero, PPU data string follows,--> +
-LC315:  jmp WriteScroll                 ;($C29A)Otherwise we're done. +
- +
-;In: CF = desired PPU address increment (0 = 1, 1 = 32). +
-;Out: PPU control #0 ($2000) updated accordingly. +
- +
-SetPPUInc: +
-LC318:  pha                             ;Preserve A. +
-LC319:  lda PPUCNT0ZP                   ; +
-LC31B:  ora #$04                        ; +
-LC31D:  bcs +                           ;PPU increment = 32 only if Carry Flag set,--> +
-LC31F:  and #$FB                        ;else PPU increment = 1. +
-LC321:* sta PPUControl0                 ; +
-LC323:  sta PPUCNT0ZP                   ; +
-LC326:  pla                             ;Restore A. +
-LC327:  rts                             ; +
- +
-;Erase blasted tile on nametable.  Each screen is 16 tiles across and 15 tiles down. +
-EraseTile: +
-LC328:  ldy #$01                        ; +
-LC32A:  sty PPUDataPending              ;data pending = YES. +
-LC32C:  dey                             ; +
-LC32D:  lda ($02),                    ; +
-LC32F:  and #$0F                        ; +
-LC331:  sta $05                         ;# of tiles horizontally. +
-LC333:  lda ($02),                    ; +
-LC335:  jsr Adiv16                      ;($C2BF)/ 16. +
-LC338:  sta $04                         ;# of tiles vertically. +
-LC33A:  ldx PPUStrIndex                 ; +
-LC33D:* lda $01                         ; +
-LC33F:  jsr WritePPUByte                ;($C36B)write PPU high address to $07A1,PPUStrIndex. +
-LC342:  lda $00                         ; +
-LC344:  jsr WritePPUByte                ;($C36B)write PPU low address to $07A1,PPUStrIndex. +
-LC347:  lda $05                         ;data length. +
-LC349:  sta $06                         ; +
-LC34B:  jsr WritePPUByte                ;($C36B)write PPU string length to $07A1,PPUStrIndex. +
-LC34E:* iny                             ; +
-LC34F:  lda ($02),                    ;Get new tile to replace old tile. +
-LC351:  jsr WritePPUByte                ;($C36B)Write it to $07A1,PPUStrIndex, inc x. +
-LC354:  dec $06                         ; +
-LC356:  bne -                           ;Branch if more horizontal tiles to replace. +
-LC358:  stx PPUStrIndex                 ; +
-LC35B:  sty $06                         ; +
-LC35D:  ldy #$20                        ; +
-LC35F:  jsr AddYToPtr00                 ;($C2A8)Move to next name table line. +
-LC362:  ldy $06                         ;Store index to find next tile info. +
-LC364:  dec $04                         ; +
-LC366:  bne --                          ;Branch if more lines need to be changed on name table. +
-LC368:  jsr EndPPUString                ;($c376)Finish writing PPU string and exit. +
- +
-WritePPUByte: +
-LC36B:  sta PPUDataString,            ;Store data byte at end of PPUDataString. +
- +
-NextPPUByte: +
-LC36E:  inx                             ;PPUDataString has increased in size by 1 byte. +
-LC36F:  cpx #$4F                        ;PPU byte writer can only write a maximum of #$4F bytes +
-LC371:  bcc +                           ;If PPU string not full, branch to get more data. +
-LC373:  ldx PPUStrIndex                 ; +
- +
-EndPPUString: +
-LC376:  lda #$00                        ;If PPU string is already full, or all PPU bytes loaded,--> +
-LC378:  sta PPUDataString,            ;add #$00 as last byte to the PPU byte string. +
-LC37B:  pla                             ; +
-LC37C:  pla                             ;Remove last return address from stack and jump out of--> +
-LC37D:* rts                             ;PPU writing routines. +
- +
-;The following routine is only used by the intro routine to load the sprite  +
-;palette data for the twinkling stars. The following memory addresses are used: +
-;$00-$01 Destination address for PPU write, $02-$03 Source address for PPU data, +
-;$04 Temp storage for PPU data byte, $05 PPU data string counter byte, +
-;$06 Temp storage for index byte. +
- +
-PrepPPUPaletteString: +
-LC37E:  ldy #$01                        ; +
-LC380:  sty PPUDataPending              ;Indicate data waiting to be written to PPU. +
-LC382:  dey                             ; +
-LC383:  beq ++++                        ;Branch always +
- +
-LC385:* sta $04                         ;$04 now contains next data byte to be put into the PPU string. +
-LC387:  lda $01                         ;High byte of staring address to write PPU data  +
-LC389:  jsr WritePPUByte                ;($C36B)Put data byte into PPUDataString. +
-LC38c:  lda $00                         ;Low byte of starting address to write PPU data. +
-LC38E:  jsr WritePPUByte                ;($C36B)Put data byte into PPUDataString. +
-LC391:  lda $04                         ;A now contains next data byte to be put into the PPU string. +
-LC393:  jsr SeparateControlBits         ;($C3C6)Break control byte into two bytes. +
- +
-LC396:  bit $04                         ;Check to see if RLE bit is set in control byte.--> +
-LC398:  bvc WritePaletteStringByte      ;If not set, branch to load byte. Else increment index--> +
-LC39A:  iny                             ;to find repeating data byte. +
- +
-WritePaletteStringByte: +
-LC39B:  bit $04                         ;Check if RLE bit is set (again). if set, load same--> +
-LC39D:  bvs +                           ;byte over and over again until counter = #$00. +
-LC39F:  iny                             ;Non-repeating data byte. Increment for next byte. +
-LC3A0:* lda ($02),                    ; +
-LC3A2:  jsr WritePPUByte                ;($C36B)Put data byte into PPUDataString. +
-LC3A5:  sty $06                         ;Temporarily store data index. +
-LC3A7:  ldy #$01                        ;PPU address increment = 1. +
-LC3A9:  bit $04                         ;If MSB set in control bit, it looks like this routine might--> +
-LC3AB:  bpl +                           ;have been used for a software control verticle mirror, but--> +
-                                        ;the starting address has already been written to the PPU--> +
-                                        ;string so this section has no effect whether the MSB is set--> +
-                                        ;or not. The PPU is always incremented by 1. +
-LC3AD:  ldy #$20                        ;PPU address increment = 32. +
-LC3AF:* jsr AddYToPtr00                 ;($C2A8)Set next PPU write address.(Does nothing, already set). +
-LC3B2:  ldy $06                         ;Restore data index to Y. +
-LC3B4:  dec $05                         ;Decrement counter byte. +
-LC3B6:  bne WritePaletteStringByte      ;If more bytes to write, branch to write another byte. +
-LC3B8:  stx PPUStrIndex                 ;Store total length, in bytes, of PPUDataString. +
-LC3BB:  iny                             ;Move to next data byte(should be #$00). +
- +
-LC3BC:* ldx PPUStrIndex                 ;X now contains current length of PPU data string. +
-LC3BF:  lda ($02),                    ; +
-LC3C1:  bne ----                        ;Is PPU string done loading (#$00)? If so exit,--> +
-LC3C3:  jsr EndPPUString                ;($C376)else branch to process PPU byte. +
- +
-SeparateControlBits: +
-LC3C6:  sta $04                         ;Store current byte  +
-LC3C8:  and #$BF                        ; +
-LC3CA:  sta PPUDataString,            ;Remove RLE bit and save control bit in PPUDataString. +
-LC3CD:  and #$3F                        ; +
-LC3CF:  sta $05                         ;Extract counter bits and save them for use above. +
-LC3D1:  jmp NextPPUByte                 ;($C36E) +
- +
-;----------------------------------------[ Math routines ]------------------------------------------- +
- +
-TwosCompliment: +
-LC3D4:  eor #$FF                        ; +
-LC3D6:  clc                             ;Generate twos compliment of value stored in A. +
-LC3D7:  adc #$01                        ; +
-LC3D9:  rts                             ; +
- +
-;The following two routines add a Binary coded decimal (BCD) number to another BCD number. +
-;A base number is stored in $03 and the number in A is added/subtracted from $03.  $01 and $02  +
-;contain the lower and upper digits of the value in A respectively.  If an overflow happens after +
-;the addition/subtraction, the carry bit is set before the routine returns. +
- +
-Base10Add: +
-LC3DA:  jsr ExtractNibbles              ;($C41D)Separate upper 4 bits and lower 4 bits. +
-LC3DD:  adc $01                         ;Add lower nibble to number. +
-LC3DF:  cmp #$0A                        ; +
-LC3E1:  bcc +                           ;If result is greater than 9, add 5 to create--> +
-LC3E3:  adc #$05                        ;valid result(skip #$0A thru #$0F). +
-LC3E5:* clc                             ; +
-LC3E6:  adc $02                         ;Add upper nibble to number. +
-LC3E8:  sta $02                         ; +
-LC3EA:  lda $03                         ; +
-LC3EC:  and #$F0                        ;Keep upper 4 bits of HealthLo/HealthHi in A. +
-LC3EE:  adc $02                         ; +
-LC3F0:  bcc ++                          ; +
-LC3F2:* adc #$5F                        ;If upper result caused a carry, add #$5F to create--> +
-LC3F4:  sec                             ;valid result. Set carry indicating carry to next digit. +
-LC3F5:  rts                             ; +
-LC3F6:* cmp #$A0                        ;If result of upper nibble add is greater than #$90,--> +
-LC3F8:  bcs --                          ;Branch to add #$5F to create valid result. +
-LC3FA:  rts                             ; +
- +
-Base10Subtract: +
-LC3FB:  jsr ExtractNibbles              ;($C41D)Separate upper 4 bits and lower 4 bits. +
-LC3FE:  sbc $01                         ;Subtract lower nibble from number. +
-LC400:  sta $01                         ; +
-LC402:  bcs +                           ;If result is less than zero, add 10 to create--> +
-LC404:  adc #$0A                        ;valid result. +
-LC406:  sta $01                         ; +
-LC408:  lda $02                         ; +
-LC40A:  adc #$0F                        ;Adjust $02 to account for borrowing. +
-LC40C:  sta $02                         ; +
-LC40E:* lda $03                         ;Keep upper 4 bits of HealthLo/HealthHi in A. +
-LC410:  and #$F0                        ; +
-LC412:  sec                             ; +
-LC413:  sbc $02                         ;If result is greater than zero, branch to finish. +
-LC415:  bcs +                           ; +
-LC417:  adc #$A0                        ;Add 10 to create valid result. +
-LC419:  clc                             ; +
-LC41A:* ora $01                         ;Combine A and $01 to create final value. +
-LC41C:  rts                             ; +
- +
-ExtractNibbles: +
-LC41D:  pha                             ; +
-LC41E:  and #$0F                        ;Lower 4 bits of value to change HealthLo/HealthHi by. +
-LC420:  sta $01                         ; +
-LC422:  pla                             ; +
-LC423:  and #$F0                        ;Upper 4 bits of value to change HealthLo/HealthHi by. +
-LC425:  sta $02                         ; +
-LC427:  lda $03                         ; +
-LC429:  and #$0F                        ;Keep lower 4 bits of HealthLo/HealthHi in A. +
-LC42B:  rts                             ; +
- +
-;---------------------------[ NMI and PPU control routines ]-------------------------------- +
- +
-; Wait for the NMI to end. +
- +
-WaitNMIPass:     +
-LC42C:  jsr ClearNMIStat                ;($C434)Indicate currently in NMI. +
-LC42F:* lda NMIStatus                   ; +
-LC431:  beq -                           ;Wait for NMI to end. +
-LC433:  rts                             ; +
- +
-ClearNMIStat: +
-LC434:  lda #$00                        ;Clear NMI byte to indicate the game is--> +
-LC436:  sta NMIStatus                   ;currently running NMI routines. +
-LC438:  rts                             ; +
- +
-ScreenOff: +
-LC439:  lda PPUCNT1ZP                   ; +
-LC43B:  and #$E7                        ; BG & SPR visibility = off +
- +
-WriteAndWait: +
-LC43D:* sta PPUCNT1ZP                   ;Update value to be loaded into PPU control register. +
- +
-WaitNMIPass_: +
-LC43F:  jsr ClearNMIStat                ;($C434)Indicate currently in NMI. +
-LC442:* lda NMIStatus                   ; +
-LC444:  beq -                           ;Wait for NMI to end before continuing. +
-LC446:  rts                             ; +
- +
-ScreenOn: +
-LC447:  lda PPUCNT1ZP                   ; +
-LC449:  ora #$1E                        ;BG & SPR visibility = on +
-LC44B:  bne --                          ;Branch always +
- +
-;Update the actual PPU control registers. +
- +
-WritePPUCtrl: +
-LC44D:  lda PPUCNT0ZP                   ; +
-LC44F:  sta PPUControl0                 ; +
-LC452:  lda PPUCNT1ZP                   ;Update PPU control registers. +
-LC454:  sta PPUControl1                 ; +
-LC457:  lda MirrorCntrl                 ; +
-LC459:  jsr PrepPPUMirror               ;($C4D9)Setup vertical or horizontal mirroring. +
- +
-ExitSub: +
-LC45C:  rts                             ;Exit subroutines. +
- +
-;Turn off both screen and NMI. +
- +
-ScreenNmiOff: +
-LC45D:  lda PPUCNT1ZP                   ; +
-LC45F:  and #$E7                        ;BG & SPR visibility = off +
-LC461:  jsr WriteAndWait                ;($C43D)Wait for end of NMI. +
-LC464:  lda PPUCNT0ZP                   ;Prepare to turn off NMI in PPU. +
-LC466:  and #$7F                        ;NMI = off +
-LC468:  sta PPUCNT0ZP                   ; +
-LC46A:  sta PPUControl0                 ;Actually load PPU register with NMI off value. +
-LC46D:  rts                             ; +
- +
-;The following routine does not appear to be used. +
- +
-LC46E:  lda PPUCNT0ZP                   ;Enable VBlank. +
-LC470:  ora #$80                        ; +
-LC472:  sta PPUCNT0ZP                   ;Write PPU control register 0 and PPU status byte. +
-LC474:  sta PPUControl0                 ; +
-LC477:  lda PPUCNT1ZP                   ;Turn sprites and screen on. +
-LC479:  ora #$1E                        ; +
-LC47B:  bne --                          ;Branch always. +
- +
-VBOffAndHorzWrite:  +
-LC47D:  lda PPUCNT0ZP                   ; +
-LC47F:  and #$7B                        ;Horizontal write, disable VBlank.  +
-LC481:* sta PPUControl0                 ;Save new values in the PPU control register--> +
-LC484:  sta PPUCNT0ZP                   ;and PPU status byte. +
-LC486:  rts                             ; +
- +
-NmiOn: +
-LC487:* lda PPUStatus                   ; +
-LC48A:  and #$80                        ;Wait for end of VBlank. +
-LC48C:  bne -                           ; +
-LC48E:  lda PPUCNT0ZP                   ; +
-LC490:  ora #$80                        ;Enable VBlank interrupts. +
-LC492:  bne --                          ;Branch always. +
- +
-;--------------------------------------[ Timer routines ]-------------------------------------------- +
- +
-;The following routines set the timer and decrement it. The timer is set after Samus dies and +
-;before the GAME OVER message is dispayed.  The timer is also set while the item pickup music +
-;is playing. +
- +
-WaitTimer: +
-LC494:  lda Timer3                      ;Exit if timer hasn't hit zero yet +
-LC496:  bne +                           ; +
-LC498:  lda NextRoutine                 ;Set GameOver as next routine. +
-LC49A:  cmp #$04                        ; +
-LC49C:  beq SetMainRoutine              ;Set GoPassword as main routine. +
-LC49E:  cmp #$06                        ; +
-LC4A0:  beq SetMainRoutine              ; +
-LC4A2:  jsr StartMusic                  ;($D92C)Assume power up was picked up and GameEngine--> +
-LC4A5:  lda NextRoutine                 ;is next routine. Start area music before exiting. +
- +
-SetMainRoutine: +
-LC4A7:  sta MainRoutine                 ;Set next routine to run. +
-LC4A9:* rts                             ; +
- +
-SetTimer: +
-LC4AA:  sta Timer3                      ;Set Timer3. Frames to wait is value stored in A*10. +
-LC4AC:  stx NextRoutine                 ;Save routine to jump to after Timer3 expires. +
-LC4AE:  lda #$09                        ;Next routine to run is WaitTimer. +
-LC4B0:  bne SetMainRoutine              ;Branch always. +
- +
-;-----------------------------------[ PPU mirroring routines ]--------------------------------------- +
- +
-PrepVertMirror: +
-LC4B2:  nop                             ; +
-LC4B3:  nop                             ;Prepare to set PPU for vertical mirroring (again). +
-LC4B4:  lda #$47                        ; +
- +
-SetPPUMirror: +
-LC4B6:  lsr                             ; +
-LC4B7:  lsr                             ;Move bit 3 to bit 0 position. +
-LC4B8:  lsr                             ; +
-LC4B9:  and #$01                        ;Remove all other bits. +
-LC4BB:  sta $00                         ;Store at address $00. +
-LC4BD:  lda MMCReg0Cntrl                ; +
-LC4BF:  and #$FE                        ;Load MMCReg0Cntrl and remove bit 0. +
-LC4C1:  ora $00                         ;Replace bit 0 with stored bit at $00. +
-LC4C3:  sta MMCReg0Cntrl                ; +
-LC4C5:  sta MMC1Reg0                    ; +
-LC4C8:  lsr                             ; +
-LC4C9:  sta MMC1Reg0                    ; +
-LC4Cc:  lsr                             ; +
-LC4CD:  sta MMC1Reg0                    ; +
-LC4D0:  lsr                             ;Load new configuration data serially--> +
-LC4D1:  sta MMC1Reg0                    ;into MMC1Reg0. +
-LC4D4:  lsr                             ; +
-LC4D5:  sta MMC1Reg0                    ; +
-LC4D8:  rts                             ; +
- +
-PrepPPUMirror: +
-LC4D9:  lda MirrorCntrl                 ;Load MirrorCntrl into A. +
-LC4DB:  jmp SetPPUMirror                ;($C4B6)Set mirroring through MMC1 chip. +
- +
-;-----------------------------[ Switch bank and init bank routines ]--------------------------------- +
- +
-;This is how the bank switching works... Every frame, the routine below +
-;is executed. First, it checks the value of SwitchPending. If it is zero, +
-;the routine will simply exit. If it is non-zero, it means that a bank +
-;switch has been issued, and must be performed. SwitchPending then contains +
-;the bank to switch to, plus one. +
- +
-CheckSwitch: +
-LC4DE:  ldy SwitchPending               ; +
-LC4E0:  beq +                           ;Exit if zero(no bank switch issued). else Y contains bank#+1. +
-LC4E2:  jsr SwitchOK                    ;($C4E8)Perform bank switch. +
-LC4E5:  jmp GoBankInit                  ;($C510)Initialize bank switch data. +
- +
-SwitchOK: +
-LC4E8:  lda #$00                        ;Reset(so that the bank switch won't be performed--> +
-LC4EA:  sta SwitchPending               ;every succeeding frame too). +
-LC4EC:  dey                             ;Y now contains the bank to switch to. +
-LC4ED:  sty CurrentBank                 ; +
- +
-ROMSwitch: +
-LC4EF:  tya                             ; +
-LC4F0:  sta $00                         ;Bank to switch to is stored at location $00. +
-LC4F2:  lda SwitchUpperBits             ;Load upper two bits for Reg 3 (they should always be 0). +
-LC4F4:  and #$18                        ;Extract bits 3 and 4 and add them to the current--> +
-LC4F6:  ora $00                         ;bank to switch to. +
-LC4F8:  sta SwitchUpperBits             ;Store any new bits set in 3 or 4(there should be none). +
- +
-;Loads the lower memory page with the bank specified in A. +
- +
-MMCWriteReg3: +
-LC4FA:  sta MMC1Reg3                    ;Write bit 0 of ROM bank #. +
-LC4FD:  lsr                             ; +
-LC4FE:  sta MMC1Reg3                    ;Write bit 1 of ROM bank #. +
-LC501:  lsr                             ; +
-LC502:  sta MMC1Reg3                    ;Write bit 2 of ROM bank #. +
-LC505:  lsr                             ; +
-LC506:  sta MMC1Reg3                    ;Write bit 3 of ROM bank #. +
-LC509:  lsr                             ; +
-LC50A:  sta MMC1Reg3                    ;Write bit 4 of ROM bank #. +
-LC50D:  lda $00                         ;Restore A with current bank number before exiting. +
-LC50F:* rts                             ; +
- +
-;Calls the proper routine according to the bank number in A. +
- +
-GoBankInit: +
-LC510:  asl                             ;*2 For proper table offset below. +
-LC511:  tay                             ; +
-LC512:  lda BankInitTable,            ; +
-LC515:  sta $0A                         ;Load appropriate subroutine address into $0A and $0B. +
-LC517:  lda BankInitTable+1,          ; +
-LC51A:  sta $0B                         ; +
-LC51C:  jmp ($000A)                     ;Jump to appropriate initialization routine. +
- +
-BankInitTable: +
-LC51F:  .word InitBank0                 ;($C531)Initialize bank 0. +
-LC521:  .word InitBank1                 ;($C552)Initialize bank 1. +
-LC523:  .word InitBank2                 ;($C583)Initialize bank 2. +
-LC525:  .word InitBank3                 ;($C590)Initialize bank 3. +
-LC527:  .word InitBank4                 ;($C5B6)Initialize bank 4. +
-LC529:  .word InitBank5                 ;($C5C3)Initialize bank 5. +
-LC52B:  .word ExitSub                   ;($C45C)Rts +
-LC52D:  .word ExitSub                   ;($C45C)Rts +
-LC52F:  .word ExitSub                   ;($C45C)Rts +
- +
-;Title screen memory page. +
- +
-InitBank0: +
-LC531:  ldy #$00                        ; +
-LC533:  sty GamePaused                  ;Ensure game is not paused. +
-LC535:  iny                             ;Y=1. +
-LC536:  sty GameMode                    ;Game is at title routines. +
-LC538:  jsr ScreenNmiOff                ;($C45D)Waits for NMI to end then turns it off. +
-LC53B:  jsr CopyMap                     ;($A93E)Copy game map from ROM to cartridge RAM $7000-$73FF +
-LC53E:  jsr ClearNameTables             ;($C158)Erase name table data. +
- +
-LC541:  ldy #$A0                        ; +
-LC543:* lda $98BF,                    ; +
-LC546:  sta $6DFF,                    ;Loads sprite info for stars into RAM $6E00 thru 6E9F. +
-LC549:  dey                             ; +
-LC54A:  bne -                           ; +
- +
-LC54C:  jsr InitTitleGFX                ;($C5D7)Load title GFX. +
-LC54F:  jmp NmiOn                       ;($C487)Turn on VBlank interrupts. +
- +
-;Brinstar memory page. +
- +
-InitBank1: +
-LC552:  lda #$00                        ; +
-LC554:  sta GameMode                    ;GameMode = play. +
-LC556:  jsr ScreenNmiOff                ;($C45D)Disable screen and Vblank. +
-LC559:  lda MainRoutine                 ; +
-LC55B:  cmp #$03                        ;Is game engine running? if so, branch.--> +
-LC55D:  beq +                           ;Else do some housekeeping first. +
-LC55F:  lda #$00                        ; +
-LC561:  sta MainRoutine                 ;Run InitArea routine next. +
-LC563:  sta InArea                      ;Start in Brinstar. +
-LC565:  sta GamePaused                  ;Make sure game is not paused. +
-LC567:  jsr ClearRAM_33_DF              ;($C1D4)Clear game engine memory addresses. +
-LC56A:  jsr ClearSamusStats             ;($C578)Clear Samus' stats memory addresses. +
-LC56D:* ldy #$00                        ; +
-LC56F:  jsr ROMSwitch                   ;($C4EF)Load Brinstar memory page into lower 16Kb memory. +
-LC572:  jsr InitBrinstarGFX             ;($C604)Load Brinstar GFX. +
-LC575:  jmp NmiOn                       ;($C487)Turn on VBlank interrupts. +
- +
-ClearSamusStats: +
-LC578:  ldy #$0F                        ; +
-LC57A:  lda #$00                        ;Clears Samus stats(Health, full tanks, game timer, etc.). +
-LC57C:* sta $0100,                    ;Load $100 thru $10F with #$00. +
-LC57F:  dey                             ; +
-LC580:  bpl -                           ;Loop 16 times. +
-LC582:  rts                             ; +
- +
-;Norfair memory page. +
- +
-InitBank2: +
-LC583:  lda #$00                        ;GameMode = play. +
-LC585:  sta GameMode                    ; +
-LC587:  jsr ScreenNmiOff                ;($C45D)Disable screen and Vblank. +
-LC58A:  jsr InitNorfairGFX              ;($C622)Load Norfair GFX. +
-LC58D:  jmp NmiOn                       ;($C487)Turn on VBlank interrupts. +
- +
-;Tourian memory page. +
- +
-InitBank3: +
-LC590:  lda #$00                        ;GameMode = play. +
-LC592:  sta GameMode                    ; +
-LC594:  jsr ScreenNmiOff                ;($C45D)Disable screen and Vblank. +
-LC597:  ldy #$0D                        ; +
-LC599:* lda MetroidData,              ;Load info from table below into--> +
-LC59C:  sta $77F0,                    ;$77F0 thru $77FD. +
-LC59F:  dey                             ; +
-LC5A0:  bpl -                           ; +
-LC5A2:  jsr InitTourianGFX              ;($C645)Load Tourian GFX. +
-LC5A5:  jmp NmiOn                       ;($C487)Turn on VBlank interrupts. +
- +
-;Table used by above subroutine and loads the initial data used to describe +
-;metroid's behavior in the Tourian section of the game. +
- +
-MetroidData: +
-LC5A8:  .byte $F8, $08, $30, $D0, $60, $A0, $02, $04, $00, $00, $00, $00, $00, $00 +
- +
-;Kraid memory page. +
- +
-InitBank4: +
-LC5B6:  lda #$00                        ;GameMode = play. +
-LC5B8:  sta GameMode                    ; +
-LC5BA:  jsr ScreenNmiOff                ;($C45D)Disable screen and Vblank. +
-LC5BD:  jsr InitKraidGFX                ;($C677)Load Kraid GFX. +
-LC5C0:  jmp NmiOn                       ;($C487)Turn on VBlank interrupts. +
- +
-;Ridley memory page. +
- +
-InitBank5: +
-LC5C3:  lda #$00                        ;GameMode = play. +
-LC5C5:  sta GameMode                    ; +
-LC5C7:  jsr ScreenNmiOff                ;($C45D)Disable screen and Vblank. +
-LC5CA:  jsr InitRidleyGFX               ;($C69F)Loag Ridley GFX. +
-LC5CD:  jmp NmiOn                       ;($C487)Turn on VBlank interrupts. +
- +
-InitEndGFX: +
-LC5D0:  lda #$01                        ; +
-LC5D2:  sta GameMode                    ;Game is at title/end game. +
-LC5D4:  jmp InitGFX6                    ;($C6C2)Load end game GFX. +
- +
-InitTitleGFX: +
-LC5D7:  ldy #$15                        ;Entry 21 in GFXInfo table. +
-LC5D9:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
- +
-LoadSamusGFX: +
-LC5DC:  ldy #$00                        ;Entry 0 in GFXInfo table. +
-LC5DE:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC5E1:  lda JustInBailey                ; +
-LC5E4:  beq +                           ;Branch if wearing suit +
-LC5E6:  ldy #$1B                        ;Entry 27 in GFXInfo table. +
-LC5E8:  jsr LoadGFX                     ;($C7AB)Switch to girl gfx +
-LC5EB:* ldy #$14                        ;Entry 20 in GFXInfo table. +
-LC5ED:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC5F0:  ldy #$17                        ;Entry 23 in GFXInfo table. +
-LC5F2:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC5F5:  ldy #$18                        ;Entry 24 in GFXInfo table. +
-LC5F7:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC5FA:  ldy #$19                        ;Entry 25 in GFXInfo table. +
-LC5FC:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC5FF:  ldy #$16                        ;Entry 22 in GFXInfo table. +
-LC601:  jmp LoadGFX                     ;($C7AB)Load pattern table GFX. +
- +
-InitBrinstarGFX: +
-LC604:  ldy #$03                        ;Entry 3 in GFXInfo table. +
-LC606:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-Lc609:  ldy #$04                        ;Entry 4 in GFXInfo table. +
-LC60B:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC60E:  ldy #$05                        ;Entry 5 in GFXInfo table. +
-LC610:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC613:  ldy #$06                        ;Entry 6 in GFXInfo table. +
-LC615:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC618:  ldy #$19                        ;Entry 25 in GFXInfo table. +
-LC61A:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC61D:  ldy #$16                        ;Entry 22 in GFXInfo table. +
-LC61F:  jmp LoadGFX                     ;($C7AB)Load pattern table GFX. +
- +
-InitNorfairGFX: +
-LC622:  ldy #$04                        ;Entry 4 in GFXInfo table. +
-LC624:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC627:  ldy #$05                        ;Entry 5 in GFXInfo table. +
-LC629:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC62C:  ldy #$07                        ;Entry 7 in GFXInfo table. +
-LC62E:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC631:  ldy #$08                        ;Entry 8 in GFXInfo table. +
-LC633:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC636:  ldy #$09                        ;Entry 9 in GFXInfo table. +
-LC638:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC63B:  ldy #$19                        ;Entry 25 in GFXInfo table. +
-LC63D:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC640:  ldy #$16                        ;Entry 22 in GFXInfo table. +
-LC642:  jmp LoadGFX                     ;($C7AB)Load pattern table GFX. +
- +
-InitTourianGFX: +
-LC645:  ldy #$05                        ;Entry 5 in GFXInfo table. +
-LC647:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC64A:  ldy #$0A                        ;Entry 10 in GFXInfo table. +
-LC64C:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC64F:  ldy #$0B                        ;Entry 11 in GFXInfo table. +
-LC651:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC654:  ldy #$0C                        ;Entry 12 in GFXInfo table. +
-LC656:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC659:  ldy #$0D                        ;Entry 13 in GFXInfo table. +
-LC65B:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC65E:  ldy #$0E                        ;Entry 14 in GFXInfo table. +
-LC660:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC663:  ldy #$1A                        ;Entry 26 in GFXInfo table. +
-LC665:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC668:  ldy #$1C                        ;Entry 28 in GFXInfo table. +
-LC66A:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC66D:  ldy #$19                        ;Entry 25 in GFXInfo table. +
-LC66F:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC672:  ldy #$16                        ;Entry 22 in GFXInfo table. +
-LC674:  jmp LoadGFX                     ;($C7AB)Load pattern table GFX. +
- +
-InitKraidGFX: +
-LC677:  ldy #$04                        ;Entry 4 in GFXInfo table. +
-LC679:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC67C:  ldy #$05                        ;Entry 5 in GFXInfo table. +
-LC67E:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC681:  ldy #$0A                        ;Entry 10 in GFXInfo table. +
-LC683:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC686:  ldy #$0F                        ;Entry 15 in GFXInfo table. +
-LC688:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC68B:  ldy #$10                        ;Entry 16 in GFXInfo table. +
-LC68D:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC690:  ldy #$11                        ;Entry 17 in GFXInfo table. +
-LC692:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC695:  ldy #$19                        ;Entry 25 in GFXInfo table. +
-LC697:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC69A:  ldy #$16                        ;Entry 22 in GFXInfo table. +
-LC69C:  jmp LoadGFX                     ;($C7AB)Load pattern table GFX. +
- +
-InitRidleyGFX: +
-LC69F:  ldy #$04                        ;Entry 4 in GFXInfo table. +
-LC6A1:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC6A4:  ldy #$05                        ;Entry 5 in GFXInfo table. +
-LC6A6:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC6A9:  ldy #$0A                        ;Entry 10 in GFXInfo table. +
-LC6AB:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC6AE:  ldy #$12                        ;Entry 18 in GFXInfo table. +
-LC6B0:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC6B3:  ldy #$13                        ;Entry 19 in GFXInfo table. +
-LC6B5:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC6B8:  ldy #$19                        ;Entry 25 in GFXInfo table. +
-LC6BA:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC6BD:  ldy #$16                        ;Entry 22 in GFXInfo table. +
-LC6BF:  jmp LoadGFX                     ;($C7AB)Load pattern table GFX. +
- +
-InitGFX6: +
-LC6C2:  ldy #$01                        ;Entry 1 in GFXInfo table. +
-LC6C4:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC6C7:  ldy #$02                        ;Entry 2 in GFXInfo table. +
-LC6C9:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC6CC:  ldy #$19                        ;Entry 25 in GFXInfo table. +
-LC6CE:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC6D1:  ldy #$16                        ;Entry 22 in GFXInfo table. +
-LC6D3:  jmp LoadGFX                     ;($C7AB)Load pattern table GFX. +
- +
-InitGFX7: +
-LC6D6:  ldy #$17                        ;Entry 23 in GFXInfo table. +
-LC6D8:  jsr LoadGFX                     ;($C7AB)Load pattern table GFX. +
-LC6DB:  ldy #$16                        ;Entry 22 in GFXInfo table. +
-LC6DD:  jmp LoadGFX                     ;($C7AB)Load pattern table GFX. +
- +
-;The table below contains info for each tile data block in the ROM. +
-;Each entry is 7 bytes long. The format is as follows: +
-;byte 0: ROM bank where GFX data is located. +
-;byte 1-2: 16-bit ROM start address (src). +
-;byte 3-4: 16-bit PPU start address (dest). +
-;byte 5-6: data length (16-bit). +
- +
-GFXInfo: +
-LC6E0:  .byte $06                       ;[SPR]Samus, items.             Entry 0. +
-LC6E1:  .word $8000, $0000, $09A0 +
-LC6E7:  .byte $04                       ;[SPR]Samus in ending.          Entry 1. +
-LC6E8:  .word $8D60, $0000, $0520 +
-LC6EE:  .byte $01                       ;[BGR]Partial font, "The End" Entry 2. +
-LC6EF:  .word $8D60, $1000, $0400 +
-LC6F5:  .byte $06                       ;[BGR]Brinstar rooms.           Entry 3. +
-LC6F6:  .word $9DA0, $1000, $0150 +
-LC6FC:  .byte $05                       ;[BGR]Misc. objects.            Entry 4. +
-LC6FD:  .word $8D60, $1200, $0450 +
-LC703:  .byte $06                       ;[BGR]More Brinstar rooms.      Entry 5. +
-LC704:  .word $9EF0, $1800, $0800 +
-LC70A:  .byte $01                       ;[SPR]Brinstar enemies.         Entry 6. +
-LC70B:  .word $9160, $0C00, $0400 +
-LC711:  .byte $06                       ;[BGR]Norfair rooms.            Entry 7. +
-LC712:  .word $A6F0, $1000, $0260 +
-LC718:  .byte $06                       ;[BGR]More Norfair rooms.       Entry 8. +
-LC719:  .word $A950, $1700, $0070 +
-LC71F:  .byte $02                       ;[SPR]Norfair enemies.          Entry 9. +
-LC720:  .word $8D60, $0C00, $0400 +
-LC726:  .byte $06                       ;[BGR]Tourian rooms.            Entry 10. +
-LC727:  .word $A9C0, $1000, $02E0 +
-LC72D:  .byte $06                       ;[BGR]More Tourian rooms.       Entry 11. +
-LC72E:  .word $ACA0, $1200, $0600 +
-LC734:  .byte $06                       ;[BGR]Mother Brain room.        Entry 12. +
-LC735:  .word $B2A0, $1900, $0090 +
-LC73B:  .byte $05                       ;[BGR]Misc. object.             Entry 13. +
-LC73C:  .word $91B0, $1D00, $0300 +
-LC742:  .byte $02                       ;[SPR]Tourian enemies.          Entry 14. +
-LC743:  .word $9160, $0C00, $0400 +
-LC749:  .byte $06                       ;[BGR]More Tourian rooms.       Entry 15. +
-LC74A:  .word $B330, $1700, $00C0 +
-LC750:  .byte $04                       ;[BGR]Misc. object and fonts.   Entry 16. +
-LC751:  .word $9360, $1E00, $0200 +
-LC757:  .byte $03                       ;[SPR]Miniboss I enemies.       Entry 17. +
-LC758:  .word $8D60, $0C00, $0400 +
-LC75E:  .byte $06                       ;[BGR]More Tourian Rooms.       Entry 18. +
-LC75F:  .word $B3F0, $1700, $00C0 +
-LC765:  .byte $03                       ;[SPR]Miniboss II enemies.      Entry 19. +
-LC766:  .word $9160, $0C00, $0400 +
-LC76C:  .byte $06                       ;[SPR]Inrto/End sprites.        Entry 20. +
-LC76D:  .word $89A0, $0C00, $0100 +
-LC773:  .byte $06                       ;[BGR]Title.                    Entry 21. +
-LC774:  .word $8BE0, $1400, $0500 +
-LC77A:  .byte $06                       ;[BGR]Solid tiles.              Entry 22. +
-LC77B:  .word $9980, $1FC0, $0040 +
-LC781:  .byte $06                       ;[BGR]Complete font.            Entry 23. +
-LC782:  .word $B4C0, $1000, $0400 +
-LC788:  .byte $06                       ;[BGR]Complete font.            Entry 24. +
-LC789:  .word $B4C0, $0A00, $00A0 +
-LC78F:  .byte $06                       ;[BGR]Solid tiles.              Entry 25. +
-LC790:  .word $9980, $0FC0, $0040 +
-LC796:  .byte $06                       ;[BGR]Complete font.            Entry 26. +
-LC797:  .word $B4C0, $1D00, $02A0 +
-LC79D:  .byte $06                       ;[SPR]Suitless Samus.           Entry 27. +
-LC79E:  .word $90E0, $0000, $07B0 +
-LC7A4:  .byte $06                       ;[BGR]Exclaimation point.       Entry 28. +
-LC7A5:  .word $9890, $1F40, $0010 +
- +
-;--------------------------------[ Pattern table loading routines ]--------------------------------- +
- +
-;Y contains the GFX header to fetch from the table above, GFXInfo. +
- +
-LoadGFX: +
-LC7AB:  lda #$FF                        ; +
-LC7AD:* clc                             ;Every time y decrements, the entry into the table--> +
-LC7AE:  adc #$07                        ;is increased by 7.  When y is less than 0, A points--> +
-LC7B0:  dey                             ;to the last byte of the entry in the table. +
-LC7B1:  bpl -                           ; +
-LC7B3:  tay                             ;Transfer offset into table to Y. +
- +
-LC7B4:  ldx #$06                        ; +
-LC7B6:* lda GFXInfo,                  ; +
-LC7B9:  sta $00,x                       ;Copy entries from GFXInfo to $00-$06. +
-LC7BB:  dey                             ; +
-LC7BC:  dex                             ; +
-LC7BD:  bpl -                           ; +
- +
-LC7BF:  ldy $00                         ;ROM bank containing the GFX data. +
-LC7C1:  jsr ROMSwitch                   ;($C4EF)Switch to that bank. +
-LC7C4:  lda PPUCNT0ZP                   ; +
-LC7C6:  and #$FB                        ; +
-LC7C8:  sta PPUCNT0ZP                   ;Set the PPU to increment by 1. +
-LC7CA:  sta PPUControl0                 ; +
-LC7CD:  jsr CopyGFXBlock                ;($C7D5)Copy graphics into pattern tables. +
-LC7D0:  ldy CurrentBank                 ; +
-LC7D2:  jmp ROMSwitch                   ;($C4FE)Switch back to the "old" bank. +
- +
-;Writes tile data from ROM to VRAM, according to the gfx header data +
-;contained in $00-$06. +
- +
-CopyGFXBlock: +
-LC7D5:  lda $05                         ; +
-LC7D7:  bne GFXCopyLoop                 ;If $05 is #$00, decrement $06 before beginning. +
-LC7D9:  dec $06                         ; +
- +
-GFXCopyLoop: +
-LC7DB:  lda $04                         ; +
-LC7DD:  sta PPUAddress                  ;Set PPU to proper address for GFX block write. +
-LC7E0:  lda $03                         ; +
-LC7E2:  sta PPUAddress                  ; +
-LC7E5:  ldy #$00                        ;Set offset for GFX data to 0. +
-LC7E7:* lda ($01),                    ; +
-LC7E9:  sta PPUIOReg                    ;Copy GFX data byte from ROM to Pattern table. +
-LC7EC:  dec $05                         ;Decrement low byte of data length. +
-LC7EE:  bne +                           ;Branch if high byte does not need decrementing. +
-LC7F0:  lda $06                         ; +
-LC7F2:  beq ++                          ;If copying complete, branch to exit. +
-LC7F4:  dec $06                         ;Decrement when low byte has reached 0. +
-LC7F6:* iny                             ;Increment to next byte to copy. +
-LC7F7:  bne --                          ; +
-LC7F9:  inc $02                         ;After 256 bytes loaded, increment upper bits of--> +
-LC7FB:  inc $04                         ;Source and destination addresses. +
-LC7FD:  jmp GFXCopyLoop                 ;(&C7DB)Repeat copy routine. +
-LC800:* rts                             ; +
- +
-;-------------------------------------------[ AreaInit ]--------------------------------------------- +
- +
-AreaInit: +
-LC801:  lda #$00                        ; +
-LC803:  sta ScrollX                     ;Clear ScrollX. +
-LC805:  sta ScrollY                     ;Clear ScrollY. +
-LC807:  lda PPUCNT0ZP                   ;        +
-LC809:  and #$FC                        ;Sets nametable address = $2000. +
-LC80B:  sta PPUCNT0ZP                   ; +
-LC80D:  inc MainRoutine                 ;Increment MainRoutine to MoreInit. +
-LC80F:  lda Joy1Status                  ; +
-LC811:  and #$C0                        ;Stores status of both the A and B buttons. +
-LC813:  sta ABStatus                    ;Appears to never be accessed. +
-LC815:  jsr EraseAllSprites             ;($C1A3)Clear all sprite info. +
-LC818:  lda #$10                        ;Prepare to load Brinstar memory page. +
-LC81A:  jsr IsEngineRunning             ;($CA18)Check to see if ok to switch lower memory page. +
- +
-;------------------------------------------[ MoreInit ]--------------------------------------------- +
- +
-MoreInit: +
-LC81D:  ldy #$01                        ; +
-LC81F:  sty PalDataPending              ;Palette data pending = yes. +
-LC821:  ldx #$FF                        ; +
-LC823:  stx SpareMem75                  ;$75 Not referenced ever again in the game. +
-LC825:  inx                             ;X=0. +
-LC826:  stx AtEnding                    ;Not playing ending scenes. +
-LC829:  stx DoorStatus                  ;Samus not in door. +
-LC82B:  stx SamusDoorData               ;Samus is not inside a door. +
-LC82D:  stx UpdatingProjectile          ;No projectiles need to be updated. +
-LC82F:  txa                             ;A=0. +
- +
-LC830:* cpx #$65                        ;Check to see if more RAM to clear in $7A thru $DE. +
-LC832:  bcs +                           ; +
-LC834:  sta $7A,x                       ;Clear RAM $7A thru $DE. +
-LC836:* cpx #$FF                        ;Check to see if more RAM to clear in $300 thru $3FE. +
-LC838:  bcs +                           ; +
-LC83A:  sta ObjAction,                ;Clear RAM $300 thru $3FE. +
-LC83D:* inx                             ; +
-LC83E:  bne ---                         ;Loop until all required RAM is cleared. +
- +
-LC840:  jsr ScreenOff                   ;($C439)Turn off Background and visibility. +
-LC843:  jsr ClearNameTables             ;($C158)Clear screen data. +
-LC846:  jsr EraseAllSprites             ;($C1A3)Erase all sprites from sprite RAM. +
-LC849:  jsr DestroyEnemies              ;($C8BB) +
- +
-        stx DoorOnNameTable3            ;Clear data about doors on the name tables. +
-        stx DoorOnNameTable0            ; +
-        inx                             ;X=1. +
-        stx SpareMem30                  ;Not accessed by game. +
-        inx                             ;X=2. +
-LC854:  stx ScrollDir                   ;Set initial scroll direction as left. +
- +
-        lda $95D7                       ;Get Samus start x pos on map. +
-        sta MapPosX                     ; +
-        lda $95D8                       ;Get Samus start y pos on map. +
-        sta MapPosY                     ; +
- +
-LC860:  lda $95DA       ; Get ??? Something to do with palette switch +
-        sta PalToggle +
-        lda #$FF +
-        sta RoomNumber                  ;Room number = $FF(undefined room). +
-LC869:  jsr CopyPtrs    ; copy pointers from ROM to RAM  +
-LC86C:  jsr GetRoomNum                  ;($E720)Put room number at current map pos in $5A. +
-*       jsr SetupRoom                   ;($EA2B) +
-        ldy RoomNumber  ; load room number +
-        iny +
-        bne - +
- +
-        ldy CartRAMPtr+1 +
-        sty $01 +
-        ldy CartRAMPtr +
-        sty $00 +
-        lda PPUCNT0ZP +
-        and #$FB        ; PPU increment = 1 +
-        sta PPUCNT0ZP +
-        sta PPUControl0 +
-        ldy PPUStatus   ; reset PPU addr flip/flop +
- +
-; Copy room RAM #0 ($6000) to PPU Name Table #0 ($2000) +
- +
-        ldy #$20 +
-        sty PPUAddress +
-        ldy #$00 +
-        sty PPUAddress +
-        ldx #$04        ; prepare to write 4 pages +
-*       lda ($00),y +
-        sta PPUIOReg +
-        iny +
-        bne - +
-        inc $01 +
-        dex +
-        bne - +
- +
-        stx $91 +
-        inx          ; X = 1 +
-        stx PalDataPending +
-        stx SpareMem30                  ;Not accessed by game. +
-        inc MainRoutine                 ;SamusInit is next routine to run. +
-        jmp ScreenOn +
- +
-; CopyPtrs +
-; ======== +
-; Copy 7 16-bit pointers from $959A thru $95A7 to $3B thru $48. +
- +
-CopyPtrs: +
-        ldx #$0D +
-*       lda AreaPointers+2,+
-        sta RoomPtrTable,+
-        dex +
-        bpl - +
-        rts +
- +
-; DestroyEnemies +
-; ============== +
- +
-DestroyEnemies: +
-LC8BB:  lda #$00 +
-        tax +
-*       cpx #$48 +
-        bcs + +
-        sta $97,x +
-*       sta EnStatus,+
-        pha +
-        pla +
-        inx +
-        bne -- +
-        stx MetroidOnSamus              ;Samus had no Metroid stuck to her. +
-        jmp $95AB +
- +
-; SamusInit +
-; ========= +
-; Code that sets up Samus, when the game is first started. +
- +
-SamusInit: +
-LC8D1:  lda #$08                        ; +
-LC8D3:  sta MainRoutine                 ;SamusIntro will be executed next frame. +
-LC8D5:  lda #$2C                        ;440 frames to fade in Samus(7.3 seconds). +
-LC8D7:  sta Timer3                      ; +
-LC8D9:  jsr IntroMusic                  ;($CBFD)Start the intro music. +
-LC8DC:  ldy #sa_FadeIn0                 ; +
-        sty ObjAction                   ;Set Samus status as fading onto screen. +
-        ldx #$00 +
-        stx SamusBlink +
-        dex                             ;X = $FF +
-        stx $0728 +
-        stx $0730 +
-        stx $0732 +
-        stx $0738 +
-        stx EndTimerLo                  ;Set end timer bytes to #$FF as--> +
-        stx EndTimerHi                  ;escape timer not currently active. +
-        stx $8B +
-        stx $8E +
-        ldy #$27 +
-        lda InArea +
-        and #$0F +
-        beq +                           ;Branch if Samus starting in Brinstar. +
-        lsr ScrollDir                   ;If not in Brinstar, change scroll direction from left--> +
-        ldy #$2F                        ;to down. and set PPU for horizontal mirroring. +
-*       sty MirrorCntrl                 ; +
-        sty MaxMissilePickup +
-        sty MaxEnergyPickup +
-        lda $95D9                       ;Samus' initial vertical position +
-        sta ObjectY                     ; +
-        lda #$80                        ;Samus' initial horizontal position +
-        sta ObjectX                     ; +
-        lda PPUCNT0ZP                   ; +
-        and #$01                        ;Set Samus' name table position to current name table--> +
-        sta ObjectHi                    ;active in PPU. +
-        lda #$00                        ; +
-        sta HealthLo                    ;Starting health is--> +
-        lda #$03                        ;set to 30 units. +
-        sta HealthHi                    ; +
-*       rts                             ; +
- +
-;------------------------------------[ Main game engine ]-------------------------------------------- +
- +
-GameEngine: +
-LC92B:  jsr ScrollDoor                  ;($E1F1)Scroll doors, if needed. 2 routine calls scrolls--> +
-LC92E:  jsr ScrollDoor                  ;($E1F1)twice as fast as 1 routine call. +
- +
-LC931:  lda NARPASSWORD                 ; +
-LC934:  beq +                           ; +
-LC936:  lda #$03                        ;The following code is only accessed if --> +
-LC938:  sta HealthHi                    ;NARPASSWORD has been entered at the --> +
-LC93B:  lda #$FF                        ;password screen. Gives you new health,--> +
-LC93D:  sta SamusGear                   ;missiles and every power-up every frame. +
-LC940:  lda #$05                        ; +
-LC942:  sta MissileCount                ; +
- +
-LC945:* jsr UpdateWorld                 ;($CB29)Update Samus, enemies and room tiles. +
-LC948:  lda MiniBossKillDelay           ; +
-LC94B:  ora PowerUpDelay                ;Check if mini boss was just killed or powerup aquired.--> +
-LC94E:  beq +                           ;If not, branch. +
- +
-LC950:  lda #$00                        ; +
-LC952:  sta MiniBossKillDelay           ;Reset delay indicators. +
-LC955:  sta PowerUpDelay                ; +
-LC958:  lda #$18                        ;Set timer for 240 frames(4 seconds). +
-LC95A:  ldx #$03                        ;GameEngine routine to run after delay expires +
-LC95C:  jsr SetTimer                    ;($C4AA)Set delay timer and game engine routine. +
- +
-LC95F:* lda ObjAction                   ;Check is Samus is dead. +
-LC962:  cmp #sa_Dead2                   ;Is Samus dead?--> +
-LC964:  bne ---                         ;exit if not. +
-LC966:  lda AnimDelay                   ;Is Samus still exploding?--> +
-LC969:  bne ---                         ;Exit if still exploding. +
-LC96B:  jsr SilenceMusic                ;Turn off music. +
-LC96E:  lda MotherBrainStatus           ; +
-LC970:  cmp #$0A                        ;Is mother brain already dead? If so, branch. +
-LC972:  beq +                           ; +
-LC974:  lda #$04                        ;Set timer for 40 frames (.667 seconds). +
-LC976:  ldx #$04                        ;GameOver routine to run after delay expires. +
-LC978:  jmp SetTimer                    ;($C4AA)Set delay timer and run game over routine. +
- +
-LC97B:* inc MainRoutine                 ;Next routine to run is GameOver. +
-LC97D:  rts                             ; +
- +
-;----------------------------------------[ Update age ]---------------------------------------------- +
- +
-;This is the routine which keeps track of Samus' age. It is called in the +
-;NMI. Basically, this routine just increments a 24-bit variable every +
-;256th frame. (Except it's not really 24-bit, because the lowest age byte +
-;overflows at $D0.) +
- +
-UpdateAge: +
-LC97E:  lda GameMode                    ; +
-LC980:  bne ++                          ;Exit if at title/password screen. +
-LC982:  lda MainRoutine                 ; +
-LC984:  cmp #$03                        ;Is game engine running? +
-LC986:  bne ++                          ;If not, don't update age. +
-LC988:  ldx FrameCount                  ;Only update age when FrameCount is zero--> +
-LC98A:  bne ++                          ;(which is approx. every 4.266666666667 seconds). +
-LC98C:  inc SamusAge,                 ;Minor Age = Minor Age + 1. +
-LC98F:  lda SamusAge                    ; +
-LC992:  cmp #$D0                        ;Has Minor Age reached $D0?--> +
-LC994:  bcc ++                          ;If not, we're done.--> +
-LC996:  lda #$00                        ;Else reset minor age. +
-LC998:  sta SamusAge                    ; +
-LC99B:* cpx #$03                        ; +
-LC99D:  bcs +                           ;Loop to update middle age and possibly major age. +
-LC99F:  inx                             ; +
-LC9A0:  inc SamusAge,                 ; +
-LC9A3:  beq -                           ;Branch if middle age overflowed, need to increment-->  +
-LC9A5:* rts                             ;major age too. Else exit. +
- +
-;-------------------------------------------[ Game over ]-------------------------------------------- +
- +
-GameOver: +
-LC9A6:  lda #$1C                        ;GameOver is the next routine to run. +
-LC9A8:  sta TitleRoutine                ; +
-LC9AA:  lda #$01                        ; +
-LC9AC:  sta SwitchPending               ;Prepare to switch to title memory page. +
-LC9AE:  jmp ScreenOff                   ;($C439)Turn screen off. +
- +
-;------------------------------------------[ Pause mode ]-------------------------------------------- +
- +
-PauseMode: +
-LC9B1:  lda Joy2Status                  ;Load buttons currently being pressed on joypad 2. +
-LC9B3:  and #$88                        ; +
-LC9B5:  eor #$88                        ;both A & UP pressed?--> +
-LC9B7:  bne Exit14                      ;Exit if not. +
-LC9B9:  ldy EndTimerHi                  ; +
-LC9BC:  iny                             ;Is escape timer active?--> +
-LC9BD:  bne Exit14                      ;Sorry, can't quit if this is during escape scence. +
-LC9BF:  sta GamePaused                  ;Clear pause game indicator. +
-LC9C1:  inc MainRoutine                 ;Display password is the next routine to run. +
- +
-Exit14: +
-LC9C3:  rts                             ;Exit for routines above and below. +
- +
-;------------------------------------------[ GoPassword ]-------------------------------------------- +
- +
-GoPassword: +
-LC9C4:  lda #$19                        ;DisplayPassword is next routine to run. +
-LC9C6:  sta TitleRoutine                ; +
-LC9C8:  lda #$01                        ; +
-LC9CA:  sta SwitchPending               ;Prepare to switch to intro memory page. +
-LC9CC:  lda NoiseSFXFlag                ; +
-LC9CF:  ora #$01                        ;Silence music. +
-LC9D1:  sta NoiseSFXFlag                ; +
-LC9D4:  jmp ScreenOff                   ;($C439)Turn off screen. +
- +
-;-----------------------------------------[ Samus intro ]-------------------------------------------- +
- +
-SamusIntro: +
-LC9D7:  jsr EraseAllSprites             ;($C1A3)Clear all sprites off screen. +
-LC9DA:  ldy ObjAction                   ;Load Samus' fade in status. +
-LC9DD:  lda Timer3                      ; +
-LC9E0:  bne +                           ;Branch if Intro still playing. +
-         +
-;Fade in complete. +
-LC9E2:  sta ItemRoomMusicStatus         ;Make sure item room music is not playing. +
-LC9E4:  lda #sa_Begin                   ;Samus facing forward and can't be hurt. +
-LC9E6:  sta ObjAction                   ; +
-LC9E8:  jsr StartMusic                  ;($D92C)Start main music. +
-LC9EB:  jsr SelectSamusPal              ;($CB73)Select proper Samus palette. +
-LC9EE:  lda #$03                        ; +
-LC9F0:  sta MainRoutine                 ;Game engine will be called next frame. +
- +
-;Still fading in. +
-LC9F2:* cmp #$1F                        ;When 310 frames left of intro, display Samus. +
-LC9F4:  bcs Exit14                      ;Branch if not time to start drawing Samus. +
-LC9F6:  cmp SamusFadeInTimeTbl-20,    ;sa_FadeIn0 is beginning of table. +
-LC9F9:  bne +                           ;Every time Timer3 equals one of the entries in the table--> +
-LC9FB:  inc ObjAction                   ;below, change the palette used to color Samus. +
-LC9FE:  sty PalDataPending              ; +
-LCA00:* lda FrameCount                  ;Is game currently on an odd frame?--> +
-LCA02:  lsr                             ;If not, branch to exit. +
-LCA03:  bcc Exit14                      ;Only display Samus on odd frames [the blink effect]. +
-LCA05:  lda #an_SamusFront              ;Samus front animation is animation to display.--> +
-LCA07:  jsr SetSamusAnim                ;($CF6B)while fading in. +
-LCA0A:  lda #$00                        ; +
-LCA0C:  sta SpritePagePos               ;Samus sprites start at Sprite00RAM. +
-LCA0E:  sta PageIndex                   ;Samus RAM is first set of RAM. +
-LCA10:  jmp AnimDrawObject              ;($DE47)Draw Samus on screen. +
- +
-;The following table marks the time remaining in Timer3 when a palette change should occur during +
-;the Samus fade-in sequence. This creates the fade-in effect. +
- +
-SamusFadeInTimeTbl: +
-LCA13:  .byte $1E,$14,$0B,$04,$FF +
- +
-;---------------------------------[ Check if game engine running ]----------------------------------- +
- +
-IsEngineRunning: +
-LCA18:  ldy MainRoutine                 ;If Samus is fading in or the wait timer is--> +
-LCA1A:  cpy #$07                        ;active, return from routine. +
-LCA1C:  beq +                           ; +
-LCA1E:  cpy #$03                        ;Is game engine running? +
-LCA20:  beq ++                          ;If yes, branch to SwitchBank. +
-LCA22:* rts                             ;Exit if can't switch bank. +
- +
-;-----------------------------------------[ Switch bank ]-------------------------------------------- +
- +
-;Switch to appropriate area bank +
- +
-SwitchBank: +
-LCA23:* sta InArea                      ;Save current area Samus is in. +
-LCA25:  and #$0F                        ; +
-LCA27:  tay                             ;Use 4 LSB to load switch pending offset from BankTable table. +
-LCA28:  lda BankTable,                ;Base is $CA30. +
-LCA2B:  sta SwitchPending               ;Store switch data. +
-LCA2D:  jmp CheckSwitch                 ;($C4DE)Switch lower 16KB to appropriate memory page. +
- +
-;Table used by above subroutine. +
-;Each value is the area bank number plus one. +
- +
-BankTable: +
-LCA30:  .byte $02                       ;Brinstar. +
-LCA31:  .byte $03                       ;Norfair. +
-LCA32:  .byte $05                       ;Kraid hideout. +
-LCA33:  .byte $04                       ;Tourian. +
-LCA34:  .byte $06                       ;Ridley hideout. +
- +
-;----------------------------------[ Saved game routines (not used) ]-------------------------------- +
- +
-AccessSavedGame: +
-LCA35:  pha                             ;Save two copies of A. Why? Who knows. This code is--> +
-LCA36:  pha                             ;Never implemented. A contains data slot to work on. +
-LCA37:  jsr GetGameDataIndex            ;($CA96)Get index to this save game Samus data info. +
-LCA3A:  lda EraseGame                   ; +
-LCA3D:  bpl +                           ;Is MSB set? If so, erase saved game data. Else branch. +
-LCA3F:  and #$01                        ; +
-LCA41:  sta EraseGame                   ;Clear MSB so saved game data is not erased again. +
-LCA44:  jsr EraseAllGameData            ;($CAA1)Erase selected saved game data. +
-LCA47:  lda #$01                        ;Indicate this saved game has been erased.--> +
-LCA49:  sta $7800,                    ;Saved game 0=$780C, saved game 1=$781C, saved game 2=$782C.  +
-LCA4C:* lda MainRoutine                 ; +
-LCA4E:  cmp #$01                        ;If initializing the area at the start of the game, branch--> +
-LCA50:  beq +++                         ;to load Samus' saved game info. +
- +
-SaveGameData: +
-LCA52:  lda InArea                      ;Save game based on current area Samus is in. Don't know why. +
-LCA54:  jsr SavedDataBaseAddr           ;($CAC6)Find index to unique item history for this saved game. +
-LCA57:  ldy #$3F                        ;Prepare to save unique item history which is 64 bytes--> +
-LCA59:* lda NumberOfUniqueItems,      ;in length. +
-LCA5C:  sta ($00),                    ;Save unique item history in appropriate saved game slot. +
-LCA5E:  dey                             ; +
-LCA5F:  bpl -                           ;Loop until unique item history transfer complete. +
-LCA61:  ldy SamusDataIndex              ;Prepare to save Samus' data. +
-LCA64:  ldx #$00                        ; +
-LCA66:* lda SamusStat00,              ; +
-LCA69:  sta SamusData,                ;Save Samus' data in appropriate saved game slot. +
-LCA6C:  iny                             ; +
-LCA6D:  inx                             ; +
-LCA6E:  cpx #$10                        ; +
-LCA70:  bne -                           ;Loop until Samus' data transfer complete. +
- +
-LoadGameData: +
-LCA72:* pla                             ;Restore A to find appropriate saved game to load. +
-LCA73:  jsr SavedDataBaseAddr           ;($CAC6)Find index to unique item history for this saved game. +
-LCA76:  ldy #$3F                        ;Prepare to load unique item history which is 64 bytes--> +
-LCA78:* lda ($00),                    ;in length. +
-LCA7A:  sta NumberOfUniqueItems,      ;Loop until unique item history is loaded. +
-LCA7D:  dey                             ; +
-LCA7E:  bpl -                           ; +
-LCA80:  bmi +                           ;Branch always. +
-LCA82:  pha                             ; +
-LCA83:* ldy SamusDataIndex              ;Prepare to load Samus' data. +
-LCA86:  ldx #$00                        ; +
-LCA88:* lda SamusData,                ; +
-LCA8B:  sta SamusStat00,              ;Load Samus' data from appropriate saved game slot. +
-LCA8E:  iny                             ; +
-LCA8F:  inx                             ; +
-LCA90:  cpx #$10                        ; +
-LCA92:  bne -                           ;Loop until Samus' data transfer complete. +
-LCA94:  pla                             ; +
-LCA95:  rts                             ; +
- +
-GetGameDataIndex: +
-LCA96:  lda DataSlot                    ; +
-LCA99:  asl                             ;A contains the save game slot to work on (0 1 or 2).--> +
-LCA9A:  asl                             ;This number is transferred to the upper four bits to--> +
-LCA9B:  asl                             ;find the offset for Samus' data for this particular--> +
-LCA9C:  asl                             ;saved game (#$00, #$10 or #$20). +
-LCA9D:  sta SamusDataIndex              ; +
-LCAA0:  rts                             ; +
- +
-EraseAllGameData: +
-LCAA1:  lda #$00                        ;Always start at saved game 0. Erase all 3 saved games. +
-LCAA3:  jsr SavedDataBaseAddr           ;($CAC6)Find index to unique item history for this saved game. +
-LCAA6:  inc $03                         ;Prepare to erase saved game info at $6A00 and above. +
-LCAA8:  ldy #$00                        ;Fill saved game data with #$00. +
-LCAAA:  tya                             ; +
-LCAAB:* sta ($00),                    ;Erase unique item histories from $69B4 to $69FF.  +
-LCAAD:  cpy #$40                        ; +
-LCAAF:  bcs +                           ;IF 64 bytes alrady erased, no need to erase any more--> +
-LCAB1:  sta ($02),                    ;in the $6A00 and above range. +
-LCAB3:* iny                             ; +
-LCAB4:  bne --                          ;Lop until all saved game data is erased. +
-LCAB6:  ldy SamusDataIndex              ;Load proper index to desired Samus data to erase. +
-LCAB9:  ldx #$00                        ; +
-LCABB:  txa                             ; +
-LCABC:* sta SamusData,                ;Erase Samus' data. +
-LCABF:  iny                             ; +
-LCAC0:  inx                             ; +
-LCAC1:  cpx #$0C                        ; +
-LCAC3:  bne -                           ;Loop until all data is erased. +
-LCAC5:  rts                             ; +
- +
-;This routine finds the base address of the unique item history for the desired saved game (0, 1 or 2). +
-;The memory set aside for each unique item history is 64 bytes and occupies memory addresses $69B4 thru +
-;$6A73. +
- +
-SavedDataBaseAddr: +
-LCAC6:  pha                             ;Save contents of A. +
-LCAC7:  lda DataSlot                    ;Load saved game data slot to load. +
-LCACA:  asl                             ;*2. Table values below are two bytes. +
-LCACB:  tax                             ; +
-LCACC:  lda SavedDataTable,           ; +
-LCACF:  sta $00                         ;Load $0000 and $0002 with base addresses from--> +
-LCAD1:  sta $02                         ;table below($69B4). +
-LCAD3:  lda SavedDataTable+1,         ; +
-LCAD6:  sta $01                         ; +
-LCAD8:  sta $03                         ; +
-LCADA:  pla                             ;Restore A. +
-LCADB:  and #$0F                        ;Discard upper four bits in A. +
-LCADD:  tax                             ;X used for counting loop. +
-LCADE:  beq +++                         ;Exit if at saved game 0.  No further calculations required. +
-LCAE0:* lda $00                         ; +
-LCAE2:  clc                             ; +
-LCAE3:  adc #$40                        ; +
-LCAE5:  sta $00                         ;Loop to add #$40 to base address of $69B4 in order to find--> +
-LCAE7:  bcc +                           ;the proper base address for this saved game data. (save--> +
-LCAE9:  inc $01                         ;slot 0 = $69B4, save slot 1 = $69F4, save slot 2 = $6A34). +
-LCAEB:* dex                             ; +
-LCAEC:  bne --                          ; +
-LCAEE:* rts                             ; +
- +
-;Table used by above subroutine to find base address to load saved game data from. The slot 0 +
-;starts at $69B4, slot 1 starts at $69F4 and slot 2 starts at $6A34. +
- +
-SavedDataTable: +
-LCAEF:  .word ItmeHistory               ;($69B4)Base for save game slot 0. +
-LCAF1:  .word ItmeHistory               ;($69B4)Base for save game slot 1. +
-LCAF3:  .word ItmeHistory               ;($69B4)Base for save game slot 2. +
- +
-;----------------------------------------[ Choose ending ]------------------------------------------- +
- +
-;Determine what type of ending is to be shown, based on Samus' age. +
-ChooseEnding: +
-LCAF5:  ldy #$01                        ; +
-LCAF7:* lda SamusAge+2                  ;If SamusAge+2 anything but #$00, load worst--> +
-LCAFA:  bne +                           ;ending(more than 37 hours of gameplay). +
-LCAFC:  lda SamusAge+1                  ; +
-LCAFF:  cmp AgeTable-1,               ;Loop four times to determine--> +
-LCB02:  bcs +                           ;ending type from table below. +
-LCB04:  iny                             ; +
-LCB05:  cpy #$05                        ; +
-LCB07:  bne -                           ; +
-LCB09:* sty EndingType                  ;Store the ending # (1..5), 5=best ending +
-LCB0C:  lda #$00                        ; +
-LCB0E:  cpy #$04                        ;Was the best or 2nd best ending achieved? +
-LCB10:  bcc +                           ;Branch if not (suit stays on) +
-LCB12:  lda #$01                        ; +
-LCB14:* sta JustInBailey                ;Suit OFF, baby! +
-LCB17:  rts                             ; +
- +
-;Table used by above subroutine to determine ending type. +
-AgeTable: +
-LCB18:  .byte $7A                       ;Max. 37 hours +
-LCB19:  .byte $16                       ;Max. 6.7 hours +
-LCB1A:  .byte $0A                       ;Max. 3.0 hours +
-LCB1B:  .byte $04                       ;Best ending. Max. 1.2 hours +
- +
-;--------------------------------[ Clear screen data (not used) ]------------------------------------ +
- +
-ClearScreenData: +
-LCB1C:  jsr ScreenOff                   ;($C439)Turn off screen. +
-LCB1F:  lda #$FF                        ; +
-LCB21:  sta $00                         ;Prepare to fill nametable with #$FF. +
-LCB23:  jsr ClearNameTable              ;($C175)Clear selected nametable. +
-LCD26:  jmp EraseAllSprites             ;($C1A3)Clear sprite data. +
- +
-;---------------------------------------------------------------------------------------------------- +
- +
-; ===== THE REAL GUTS OF THE GAME ENGINE! ===== +
- +
-UpdateWorld: +
-LCB29:  ldx #$00                        ;Set start of sprite RAM to $0200. +
-LCB2B:  stx SpritePagePos               ; +
- +
-LCB2D:  jsr UpdateEnemies               ;($F345)Display of enemies. +
-LCB30:  jsr UpdateProjectiles           ;($D4BF)Display of bullets/missiles/bombs. +
-LCB33:  jsr UpdateSamus                 ;($CC0D)Display/movement of Samus. +
-LCB36:  jsr AreaRoutine                 ;($95C3)Area specific routine. +
-LCB39:  jsr UpdateElevator              ;($D7B3)Display of elevators. +
-LCB3C:  jsr UpdateStatues               ;($D9D4)Display of Ridley & Kraid statues. +
-LCB3F:  jsr $FA9D       ; destruction of enemies +
-LCB42:  jsr LFC65       ; update of Mellow/Memu enemies +
-LCB45:  jsr LF93B +
-LCB48:  jsr LFBDD       ; destruction of green spinners +
-LCB4B:  jsr SamusEnterDoor              ;($8B13)Check if Samus entered a door. +
-LCB4E:  jsr $8B79       ; display of doors +
-LCB51:  jsr UpdateTiles ; tile de/regeneration +
-LCB54:  jsr LF034       ; Samus <--> enemies crash detection +
-LCB57:  jsr DisplayBar                  ;($E0C1)Display of status bar. +
-        jsr LFAF2 +
-        jsr CheckMissileToggle +
-        jsr UpdateItems                 ;($DB37)Display of power-up items. +
-        jsr UpdateTourianItems          ;($FDE3) +
- +
-;Clear remaining sprite RAM +
-        ldx SpritePagePos +
-        lda #$F4 +
-*       sta Sprite00RAM,+
-        jsr Xplus4       ; X = X + 4 +
-        bne - +
-        rts +
- +
-;------------------------------------[ Select Samus palette ]---------------------------------------- +
- +
-; Select the proper palette for Samus based on: +
-; - Is Samus wearing Varia (protective suit)? +
-; - Is Samus firing missiles or regular bullets? +
-; - Is Samus with or without suit? +
- +
-SelectSamusPal: +
-LCB73:  tya                             ; +
-        pha                             ;Temp storage of Y on the stack. +
-        lda SamusGear +
-        asl +
-        asl +
-        asl                             ;CF contains Varia status (1 = Samus has it) +
-        lda MissileToggle               ;A = 1 if Samus is firing missiles, else 0 +
-        rol                             ;Bit 0 of A = 1 if Samus is wearing Varia +
-        adc #$02 +
-        ldy JustInBailey                ;In suit?--> +
-        beq +                           ;If so, Branch. +
-        clc +
-        adc #$17                        ;Add #$17 to the pal # to reach "no suit"-palettes. +
-*       sta PalDataPending              ;Palette will be written next NMI. +
-        pla                             ; +
-        tay                             ;Restore the contents of y. +
-        rts                             ; +
- +
-;----------------------------------[ Initiate SFX and music routines ]------------------------------- +
- +
-;Initiate sound effects. +
- +
-SilenceMusic:                           ;The sound flags are stored in memory--> +
-LCB8E:  lda #$01                        ;starting at $0680. The following is a--> +
-LCB90:  bne SFX_SetX0                   ;list of sound effects played when the--> +
-                                        ;flags are set: +
-PauseMusic:                             ; +
-LCB92:  lda #$02                        ;$0680: These SFX use noise channel. +
-LCB94:  bne SFX_SetX0                   ;Bit 7 - No sound. +
-                                        ;Bit 6 - ScrewAttack. +
-SFX_SamusWalk:                          ;Bit 5 - MissileLaunch. +
-LCB96:  lda #$08                        ;Bit 4 - BombExplode. +
-LCB98:  bne SFX_SetX0                   ;Bit 3 - SamusWalk. +
-                                        ;Bit 2 - SpitFlame. +
-SFX_BombExplode:                        ;Bit 1 - No sound. +
-LCB9A:  lda #$10                        ;Bit 0 - No sound. +
-LCB9C:  bne SFX_SetX0                   ; +
-                                        ;$0681: These SFX use sq1 channel. +
-SFX_MissileLaunch:                      ;Bit 7 - MissilePickup. +
-LCB9E:  lda #$20                        ;Bit 6 - EnergyPickup. +
-                                        ;Bit 5 - Metal. +
-SFX_SetX0:                              ;Bit 4 - BulletFire. +
-LCBA0:  ldx #$00                        ;Bit 3 - OutOfHole. +
-LCBA2:  beq SFX_SetSoundFlag            ;Bit 2 - EnemyHit. +
-                                        ;Bit 1 - SamusJump. +
-SFX_OutOfHole:                          ;Bit 0 - WaveFire. +
-LCBA4:  lda #$08                        ; +
-LCBA6:  bne SFX_SetX1                   ;$0682: Not used. +
-                                        ; +
-SFX_BombLaunch:                         ;$0683: These SFX use tri channel. +
-LCBA8:  lda #$01                        ;Bit 7 - SamusDie. +
-LCBAA:  bne SFX_SetX3                   ;Bit 6 - DoorOpenClose. +
-                                        ;Bit 5 - MetroidHit. +
-SFX_SamusJump:                          ;Bit 4 - StatueRaise. +
-LCBAC:  lda #$02                        ;Bit 3 - Beep. +
-LCBAE:  bne SFX_SetX1                   ;Bit 2 - BigEnemyHit. +
-                                        ;Bit 1 - SamusBall. +
-SFX_EnemyHit:                           ;Bit 0 - BombLaunch. +
-LCBB0:  lda #$04                        ; +
-LCBB2:  bne SFX_SetX1                   ;$0684: These SFX use multi channels. +
-                                        ;Bit 7 - FadeInMusic            (music). +
-SFX_BulletFire:                         ;Bit 6 - PowerUpMusic           (music). +
-LCBB4:  lda #$10                        ;Bit 5 - EndMusic  (Page 0 only)(music). +
-LCBB6:  bne SFX_SetX1                   ;Bit 4 - IntroMusic(Page 0 only)(music). +
-                                        ;Bit 3 - not used               (SFX). +
-SFX_Metal:                              ;Bit 2 - SamusHit               (SFX). +
-LCBB8:  lda #$20                        ;Bit 1 - BossHit                (SFX). +
-LCBBA:  bne SFX_SetX1                   ;Bit 0 - IncorrectPassword      (SFX). +
-                                        ; +
-SFX_EnergyPickup:                       ;$0685: Music flags. The music flags start different--> +
-LCBBC:  lda #$40                        ;music depending on what memory page is loaded. The--> +
-LCBBD:  bne SFX_SetX1                   ;following lists what bits start what music for each--> +
-                                        ;memory page. +
-SFX_MissilePickup:                      ; +
-LCBC0:  lda #$80                        ;Page 0: Intro/ending. +
-                                        ;Bit 7 - Not used. +
-SFX_SetX1:                              ;Bit 6 - TourianMusic. +
-LCBC2:  ldx #$01                        ;Bit 5 - ItemRoomMusic. +
-LCBC4:  bne SFX_SetSoundFlag            ;Bit 4 - Not used. +
-                                        ;Bit 3 - Not used. +
-SFX_WaveFire:                           ;Bit 2 - Not used. +
-LCBC6:  lda #$01                        ;Bit 1 - Not used. +
-LCBC8:  bne SFX_SetX1                   ;Bit 0 - Not used. +
-                                        ; +
-SFX_ScrewAttack:                        ;Page 1: Brinstar. +
-LCBCA:  lda #$40                        ;Bit 7 - Not used. +
-LCBCC:  bne SFX_SetX0                   ;Bit 6 - TourianMusic. +
-                                        ;Bit 5 - ItemRoomMusic. +
-SFX_BigEnemyHit:                        ;Bit 4 - Not used. +
-LCBCE:  lda #$04                        ;Bit 3 - Not used. +
-LCBD0:  bne SFX_SetX3                   ;Bit 2 - Not used. +
-                                        ;Bit 1 - Not used. +
-SFX_MetroidHit:                         ;Bit 0 - BrinstarMusic. +
-LCBD2:  lda #$20                        ; +
-LCBD4:  bne SFX_SetX3                   ;Page 2: Norfair. +
-                                        ;Bit 7 - Not used. +
-SFX_BossHit:                            ;Bit 6 - TourianMusic. +
-LCBD6:  lda #$02                        ;Bit 5 - ItemRoomMusic. +
-LCBD8:  bne SFX_SetX4                   ;Bit 4 - Not used. +
-                                        ;Bit 3 - NorfairMusic. +
-SFX_Door:                               ;Bit 2 - Not used. +
-LCBDA:  lda #$40                        ;Bit 1 - Not used. +
-LCBDC:  bne SFX_SetX3                   ;Bit 0 - Not used. +
-                                        ; +
-SFX_SamusHit:                           ;Page 3: Tourian. +
-LCBDE:  lda #$04                        ;Bit 7 - Not used. +
-LCBE0:  bne SFX_SetX4                   ;Bit 6 - TourianMusic +
-                                        ;Bit 5 - ItemRoomMusic. +
-SFX_SamusDie:                           ;Bit 4 - Not used. +
-LCBE2:  lda #$80                        ;Bit 3 - Not used. +
-LCBE4:  bne SFX_SetX3                   ;Bit 2 - EscapeMusic. +
-                                        ;Bit 1 - MotherBrainMusic +
-SFX_SetX2:                              ;Bit 0 - Not used. +
-LCBE6:  ldx #$02                        ; +
-                                        ;Page 4: Kraid. +
-SFX_SetSoundFlag:                       ;Bit 7 - RidleyAreaMusic. +
-LCBE8:  ora $0680,                    ;Bit 6 - TourianMusic. +
-LCBEB:  sta $0680,                    ;Bit 5 - ItemRoomMusic. +
-LCBEE:  rts                             ;Bit 4 - KraidAreaMusic. +
-                                        ;Bit 3 - Not used. +
-SFX_SamusBall:                          ;Bit 2 - Not used. +
-LCBEF:  lda #$02                        ;Bit 1 - Not used. +
-LCBF1:  bne SFX_SetX3                   ;Bit 0 - Not used. +
-                                        ; +
-SFX_Beep:                               ;Page 5: Ridley. +
-LCBF3:  lda #$08                        ;Bit 7 - RidleyAreaMusic. +
-                                        ;Bit 6 - TourianMusic. +
-SFX_SetX3:                              ;Bit 5 - ItemRoomMusic. +
-LCBF5:  ldx #$03                        ;Bit 4 - KraidAreaMusic. +
-LCBF7:  bne SFX_SetSoundFlag            ;Bit 3 - Not used. +
-                                        ;Bit 2 - Not used. +
-;Initiate music                         ;Bit 1 - Not used. +
-                                        ;Bit 0 - Not used. +
-PowerUpMusic:                           ; +
-LCBF9:  lda #$40                        ; +
-LCBFB:  bne SFX_SetX4                   ; +
-                                        ; +
-IntroMusic:                             ; +
-LCBFD:  lda #$80                        ; +
-                                        ; +
-SFX_SetX4:                              ; +
-LCBFF:  ldx #$04                        ; +
-LCC01:  bne SFX_SetSoundFlag            ; +
-                                        ; +
-MotherBrainMusic:                       ; +
-LCC03:  lda #$02                        ; +
-LCC05:  bne SFX_SetX5                   ; +
-                                        ; +
-TourianMusic:                           ; +
-LCC07:  lda #$40                        ; +
-                                        ; +
-SFX_SetX5:                              ; +
-LCC09:  ldx #$05                        ; +
-LCC0B:  bne SFX_SetSoundFlag            ; +
- +
-;--------------------------------------[ Update Samus ]---------------------------------------------- +
- +
-UpdateSamus: +
-LCC0D:  ldx #$00                        ;Samus data is located at index #$00. +
-LCC0F:  stx PageIndex                   ; +
-LCC11:  inx                             ;x=1. +
-LCC12:  stx IsSamus                     ;Indicate Samus is the object being updated. +
-LCC14:  jsr GoSamusHandler              ;($CC1A)Find proper Samus handler routine. +
-LCC17:  dec IsSamus                     ;Update of Samus complete. +
-LCC19:  rts                             ; +
- +
-GoSamusHandler: +
-LCC1A:  lda ObjAction                   ; +
-LCC1D:  bmi SamusStand                  ;Branch if Samus is standing. +
-LCC1F:  jsr ChooseRoutine               ;($C27C)Goto proper Samus handler routine. +
- +
-;Pointer table for Samus' action handlers. +
- +
-LCC22:  .word SamusStand                ;($CC36)Standing. +
-LCC24:  .word SamusRun                  ;($CCC2)Running. +
-LCC26:  .word SamusJump                 ;($D002)Jumping. +
-LCC28:  .word SamusRoll                 ;($D0E1)Rolling. +
-LCC2A:  .word SamusPntUp                ;($D198)Pointing up. +
-LCC2C:  .word SamusDoor                 ;($D3A8)Inside door while screen scrolling. +
-LCC2E:  .word SamusJump                 ;($D002)Jumping while pointing up. +
-LCC30:  .word SamusDead                 ;($D41A)Dead. +
-LCC32:  .word SamusDead2                ;($D41F)More dead. +
-LCC34:  .word SamusElevator             ;($D423)Samus on elevator. +
- +
-;---------------------------------------[ Samus standing ]------------------------------------------- +
- +
-SamusStand: +
-LCC36:  lda Joy1Status                  ;Status of joypad 1. +
-LCC38:  and #$CF                        ;Remove SELECT & START status bits. +
-LCC3A:  beq +                           ;Branch if no buttons pressed. +
-LCC3C:  jsr ClearHorzMvmtAnimData       ;($CF5D)Set no horiontal movement and single frame animation. +
-LCC3F:  lda Joy1Status                  ; +
-LCC41:* and #$07                        ;Keep status of DOWN/LEFT/RIGHT. +
-LCC43:  bne +                           ;Branch if any are pressed. +
-LCC45:  lda Joy1Change                  ; +
-LCC47:  and #$08                        ;Check if UP was pressed last frame.--> +
-LCC49:  beq +++                         ;If not, branch. +
-LCC4B:* jsr BitScan                     ;($E1E1)Find which directional button is pressed. +
-LCC4E:  cmp #$02                        ;Is down pressed?--> +
-LCC50:  bcs +                           ;If so, branch. +
-LCC52:  sta SamusDir                    ;1=left, 0=right. +
-LCC54:* tax                             ; +
-LCC55:  lda ActionTable,              ;Load proper Samus status from table below. +
-LCC58:  sta ObjAction                   ;Save Samus status. +
-LCC5B:* lda Joy1Change                  ; +
-LCC5D:  ora Joy1Retrig                  ;Check if fire was just pressed or needs to retrigger. +
-LCC5F:  asl                             ; +
-LCC60:  bpl +                           ;Branch if FIRE not pressed. +
-LCC62:  jsr FireWeapon                  ;($D1EE)Shoot left/right. +
-LCC65:* bit Joy1Change                  ;Check if jump was just pressed. +
-LCC67:  bpl +                           ;Branch if JUMP not pressed. +
-LCC69:  lda #sa_Jump                    ; +
-LCC6B:  sta ObjAction                   ;Set Samus status as jumping. +
-LCC6E:* lda #$04                        ;Prepare to set animation delay to 4 frames. +
-LCC70:  jsr SetSamusData                ;($CD6D)Set Samus control data and animation. +
-LCC73:  lda ObjAction                   ; +
-LCC76:  cmp #sa_Door                    ;Is Samus inside a door, dead or pointing up and jumping?--> +
-LCC78:  bcs +                           ;If so, branch to exit. +
-LCC7A:  jsr ChooseRoutine               ;Select routine below. +
- +
-;Pointer table to code. +
- +
-LCC7D:  .word ExitSub                   ;($C45C)Rts. +
-LCC7F:  .word SetSamusRun               ;($CC98)Samus is running. +
-LCC81:  .word SetSamusJump              ;($CFC3)Samus is jumping. +
-LCC83:  .word SetSamusRoll              ;($D0B5)Samus is in a ball. +
-LCC85:  .word SetSamusPntUp             ;($CF77)Samus is pointing up. +
- +
-;Table used by above subroutine. +
- +
-ActionTable: +
-LCC87:  .byte sa_Run                    ;Run right. +
-LCC88:  .byte sa_Run                    ;Run left. +
-LCC89:  .byte sa_Roll +
-LCC8A:  .byte sa_PntUp +
- +
-;---------------------------------------------------------------------------------------------------- +
- +
-SetSamusExplode: +
-LCC8B:  lda #$50 +
-        sta SamusJumpDsplcmnt +
-        lda #an_Explode +
-        jsr SetSamusAnim +
-        sta ObjectCounter +
-*       rts +
- +
-SetSamusRun: +
-LCC98:  lda #$09 +
-        sta WalkSoundDelay +
-        ldx #$00 +
-        lda AnimResetIndex +
-        cmp #an_SamusStand +
-        beq + +
-        inx +
-        cmp #$27 +
-        beq + +
-        lda #$04 +
-        jsr SetSamusNextAnim +
-*       lda RunAnimationTbl,+
-        sta AnimResetIndex +
-        ldx SamusDir +
-LCCB7:  lda RunAccelerationTbl,+
-        sta SamusHorzAccel +
-        rts +
- +
-RunAnimationTbl: +
-LCCBE:  .byte an_SamusRun +
-        .byte an_SamusRunPntUp +
- +
-RunAccelerationTbl: +
-LCCC0:  .byte $30                       ;Accelerate right. +
-        .byte $D0                       ;Accelerate left. +
- +
-; SamusRun +
-; ======== +
- +
-SamusRun: +
-LCCC2:  ldx SamusDir +
-        lda SamusGravity +
-        beq +++++++ +
-        ldy SamusJumpDsplcmnt +
-        bit ObjVertSpeed +
-        bmi + +
-        cpy #$18 +
-        bcs ++++ +
-        lda #an_SamusJump +
-        sta AnimResetIndex +
-        bcc ++++          ; branch always +
-*       cpy #$18 +
-        bcc +++ +
-        lda AnimResetIndex +
-        cmp #an_SamusFireJump +
-        beq + +
-        lda #an_SamusSalto +
-        sta AnimResetIndex +
-*       cpy #$20 +
-        bcc ++ +
-        lda Joy1Status +
-        and #$08 +
-        beq + +
-        lda #an_SamusJumpPntUp +
-        sta AnimResetIndex +
-*       bit Joy1Status +
-        bmi + +
-        jsr StopVertMovement            ;($D147) +
-*       lda #an_SamusRun +
-        cmp AnimResetIndex +
-        bne + +
-        lda #an_SamusJump +
-        sta AnimResetIndex +
-*       lda SamusInLava +
-        beq + +
-        lda Joy1Change +
-        bmi LCD40       ; branch if JUMP pressed +
-*       jsr LCF88 +
-        jsr LD09C +
-        jsr LCF2E +
-        lda #$02 +
-        bne SetSamusData       ; branch always +
-*       lda SamusOnElevator +
-        bne + +
-        jsr LCCB7 +
-*       jsr LCDBF +
-        dec WalkSoundDelay  ; time to play walk sound? +
-        bne +          ; branch if not +
-        lda #$09 +
-        sta WalkSoundDelay  ; # of frames till next walk sound trigger +
-        jsr SFX_SamusWalk +
-*       jsr LCF2E +
-        lda Joy1Change +
-        bpl +      ; branch if JUMP not pressed +
-LCD40:  jsr LCFC3 +
-        lda #$12 +
-        sta SamusHorzSpeedMax +
-        jmp LCD6B +
- +
-*       ora Joy1Retrig +
-        asl +
-        bpl +      ; branch if FIRE not pressed +
-        jsr LCDD7 +
-*       lda Joy1Status +
-        and #$03 +
-        bne + +
-        jsr LCF55 +
-        jmp LCD6B +
- +
-*       jsr BitScan                     ;($E1E1) +
-        cmp SamusDir +
-        beq LCD6B +
-        sta SamusDir +
-        jsr LCC98 +
-LCD6B:  lda #$03 +
- +
-;---------------------------------------[ Set Samus data ]------------------------------------------- +
- +
-;The following function sets various animation and control data bytes for Samus. +
- +
-SetSamusData: +
-LCD6D:  jsr UpdateObjAnim               ;($DC8F)Update animation if needed. +
-LCD70:  jsr IsScrewAttackActive         ;($CD9C)Check if screw attack active to change palette. +
-LCD73:  bcs +                           ;If screw attack not active, branch to skip palette change. +
-LCD75:  lda FrameCount                  ; +
-LCD77:  lsr                             ; +
-LCD78:  and #$03                        ;Every other frame, change Samus palette while screw--> +
-LCD7A:  ora #$A0                        ;Attack is active. +
-LCD7C:  sta ObjectCntrl                 ; +
-LCD7E:* jsr CheckHealthStatus           ;($CDFA)Check if Samus hit, blinking or Health low. +
-LCD81:  jsr LavaAndMoveCheck            ;($E269)Check if Samus is in lava or moving. +
-LCD84:  lda MetroidOnSamus              ;Is a Metroid stuck to Samus?--> +
-LCD86:  beq +                           ;If not, branch. +
-LCD88:  lda #$A1                        ;Metroid on Samus. Turn Samus blue. +
-LCD8A:  sta ObjectCntrl                 ; +
-LCD8C:* jsr SetmirrorCntrlBit           ;($CD92)Mirror Samus, if necessary. +
-LCD8F:  jmp DrawFrame                   ;($DE4A)Display Samus. +
- +
-;---------------------------------[ Set mirror control bit ]----------------------------------------- +
- +
-SetmirrorCntrlBit: +
-LCD92:  lda SamusDir                    ;Facing left=#$01, facing right=#$00. +
-LCD94:  jsr Amul16                      ;($C2C5)*16. Move bit 0 to bit 4 position. +
-LCD97:  ora ObjectCntrl                 ; +
-LCD99:  sta ObjectCntrl                 ;Use SamusDir bit to set mirror bit. +
-LCD9B:  rts                             ; +
- +
-;------------------------------[ Check if screw attack is active ]----------------------------------- +
- +
-IsScrewAttackActive: +
-LCD9C:  sec                             ;Assume screw attack is not active. +
-LCD9D:  ldy ObjAction                   ; +
-LCDA0:  dey                             ;Is Samus running?--> +
-LCDA1:  bne ++                          ;If not, branch to exit. +
-LCDA3:  lda SamusGear                   ; +
-LCDA6:  and #gr_SCREWATTACK             ;Does Samus have screw attack?--> +
-LCDA8:  beq ++                          ;If not, branch to exit. +
-LCDAA:  lda AnimResetIndex              ; +
-LCDAD:  cmp #an_SamusSalto              ;Is Samus summersaulting?--> +
-LCDAF:  beq +                           ;If so, branch to clear carry(screw attack active). +
-LCDB1:  cmp #an_SamusJump               ; +
-LCDB3:  sec                             ;Is Samus jumping?--> +
-LCDB4:  bne ++                          ;If not, branch to exit. +
-LCDB6:  bit ObjVertSpeed                ;If Samus is jumping and still moving upwards, screw-->  +
-LCDB9:  bpl ++                          ;attack is active. +
-LCDBB:* cmp AnimIndex                   ;Screw attack will still be active if not spinning, but--> +
-LCDBE:* rts                             ;jumping while running and still moving upwards. +
- +
-;---------------------------------------------------------------------------------------------------- +
- +
-LCDBF:  lda Joy1Status +
-        and #$08 +
-        lsr +
-        lsr +
-        lsr +
-        tax +
-        lda LCCBE,x +
-        cmp AnimResetIndex +
-        beq - +
-        jsr SetSamusAnim +
-        pla +
-        pla +
-        jmp LCD6B +
- +
-LCDD7:  jsr FireWeapon                  ;($D1EE)Shoot left/right. +
-        lda Joy1Status +
-        and #$08 +
-        bne + +
-        lda #an_SamusFireRun +
-        sta AnimIndex +
-        rts +
- +
-*       lda AnimIndex +
-        sec +
-        sbc AnimResetIndex +
-        and #$03 +
-        tax +
-        lda Table05,x +
-        jmp SetSamusNextAnim +
- +
-; Table used by above subroutine +
- +
-Table05: +
-        .byte $3F +
-        .byte $3B +
-        .byte $3D +
-        .byte $3F +
- +
-CheckHealthStatus: +
-LCDFA:  lda SamusHit                    ; +
-        and #$20                        ;Has Samus been hit?--> +
-        beq +++                         ;If not, branch to check if still blinking from recent hit. +
-        lda #$32                        ; +
-        sta SamusBlink                  ;Samus has been hit. Set blink for 32 frames. +
-        lda #$FF +
-        sta DamagePushDirection +
-        lda $73 +
-        sta $77 +
-        beq ++ +
-        bpl + +
-        jsr SFX_SamusHit +
-*       lda SamusHit +
-        and #$08 +
-        lsr +
-        lsr +
-        lsr +
-        sta DamagePushDirection +
-*       lda #$FD +
-        sta ObjVertSpeed +
-        lda #$38                        ;Samus is hit. Store Samus hit gravity. +
-        sta SamusGravity                ; +
-        jsr IsSamusDead +
-        bne + +
-        jmp CheckHealthBeep +
- +
-*       lda SamusBlink +
-        beq CheckHealthBeep +
-        dec SamusBlink +
-        ldx DamagePushDirection +
-        inx +
-        beq +++ +
-        jsr Adiv16       ; / 16 +
-        cmp #$03 +
-        bcs + +
-        ldy SamusHorzAccel +
-        bne +++ +
-        jsr LCF4E +
-*       dex +
-        bne + +
-        jsr TwosCompliment              ;($C3D4) +
-*       sta ObjHorzSpeed +
-*       lda $77 +
-        bpl CheckHealthBeep +
-        lda FrameCount +
-        and #$01 +
-        bne CheckHealthBeep +
-        tay +
-        sty AnimDelay +
-        ldy #$F7 +
-        sty AnimFrame +
- +
-CheckHealthBeep: +
-        ldy HealthHi +
-        dey +
-        bmi + +
-        bne ++ +
-        lda HealthLo +
-        cmp #$70 +
-        bcs ++ +
-; health < 17 +
-*       lda FrameCount +
-        and #$0F +
-        bne +                           ;Only beep every 16th frame. +
-        jsr SFX_Beep +
-*       lda #$00 +
-        sta SamusHit +
-LCE83:  rts +
- +
-;----------------------------------------[ Is Samus dead ]------------------------------------------- +
- +
-IsSamusDead: +
-LCE84:  lda ObjAction                   ; +
-LCE87:  cmp #sa_Dead                    ; +
-LCE89:  beq Exit3                       ;Samus is dead. Zero flag is set. +
-LCE8B:  cmp #sa_Dead2                   ; +
-LCE8D:  beq Exit3                       ; +
-LCE8F:  cmp #$FF                        ;Samus not dead. Clear zero flag. +
- +
-Exit3:   +
-LCE91:  rts                             ;Exit for routines above and below. +
- +
-;----------------------------------------[ Subtract health ]----------------------------------------- +
- +
-SubtractHealth: +
-LCE92:  lda HealthLoChange              ;Check to see if health needs to be changed.--> +
-LCE94:  ora HealthHiChange              ;If not, branch to exit. +
-LCE96:  beq Exit3                       ; +
-LCE98:  jsr IsSamusDead                 ;($CE84)Check if Samus is already dead. +
-LCE9B:  beq ClearDamage                 ;Samus is dead. Branch to clear damage values. +
-LCE9D:  ldy EndTimerHi                  ;If end escape timer is running, Samus cannot be hurt. +
-LCEA0:  iny                             ; +
-LCEA1:  beq +                           ;Branch if end escape timer not active. +
- +
-ClearDamage: +
-LCEA3:  jmp ClearHealthChange           ;($F323)Clear health change values. +
- +
-LCEA6:* lda MotherBrainStatus           ;If mother brain is in the process of dying, receive--> +
-LCEA8:  cmp #$03                        ;no damage. +
-LCEAA:  bcs ClearDamage                 ; +
- +
-LCEAC:  lda SamusGear                   ; +
-LCEAF:  and #gr_VARIA                   ;Check is Samus has Varia. +
-LCEB1:  beq +                           ; +
-LCEB3:  lsr HealthLoChange              ;If Samus has Varia, divide damage by 2. +
-LCEB5:  lsr HealthHiChange              ; +
-LCEB7:  bcc +                           ;If HealthHi moved a bit into the carry flag while--> +
-LCEB9:  lda #$4F                        ;dividing, add #$4F to HealthLo for proper--> +
-LCEBB:  adc HealthLoChange              ;division results. +
-LCEBD:  sta HealthLoChange              ; +
- +
-LCEBF:* lda HealthLo                    ;Prepare to subtract from HealthLo. +
-LCEC2:  sta $03                         ; +
-LCEC4:  lda HealthLoChange              ;Amount to subtract from HealthLo. +
-LCEC6:  sec                             ; +
-LCEC7:  jsr Base10Subtract              ;($C3FB)Perform base 10 subtraction. +
-LCECA:  sta HealthLo                    ;Save results. +
- +
-LCECD:   lda HealthHi                   ;Prepare to subtract from HealthHi. +
-LCED0:  sta $03                         ; +
-LCED2:  lda HealthHiChange              ;Amount to subtract from HealthHi. +
-LCED4:  jsr Base10Subtract              ;($C3FB)Perform base 10 subtraction. +
-LCED7:  sta HealthHi                    ;Save Results. +
- +
-LCEDA:  lda HealthLo                    ; +
-LCEDD:  and #$F0                        ;Is Samus health at 0?  If so, branch to--> +
-LCEDF:  ora HealthHi                    ;begin death routine. +
-LCEE2:  beq +                           ; +
-LCEE4:  bcs ++                          ;Samus not dead. Branch to exit. +
- +
-LCEE6:* lda #$00                        ;Samus is dead. +
-LCEE8:  sta HealthLo                    ; +
-LCEEB:  sta HealthHi                    ;Set health to #$00. +
-LCEEE:  lda #sa_Dead                    ; +
-LCEF0:  sta ObjAction                   ;Death handler. +
-LCEF3:  jsr SFX_SamusDie                ;($CBE2)Start Samus die SFX. +
-LCEF6:  jmp SetSamusExplode             ;($CC8B)Set Samus exlpode routine. +
- +
-;----------------------------------------[ Add health ]---------------------------------------------- +
- +
-AddHealth: +
-LCEF9:  lda HealthLo                    ;Prepare to add to HealthLo. +
-LCEFC:  sta $03                         ; +
-LCEFE:  lda HealthLoChange              ;Amount to add to HealthLo. +
-LCF00:  clc                             ; +
-LCF01:  jsr Base10Add                   ;($C3DA)Perform base 10 addition. +
-LCF04:  sta HealthLo                    ;Save results. +
- +
-LCF07:  lda HealthHi                    ;Prepare to add to HealthHi. +
-LCF0A:  sta $03                         ; +
-LCF0C:  lda HealthHiChange              ;Amount to add to HealthHi. +
-LCF0E:  jsr Base10Add                   ;($C3DA)Perform base 10 addition. +
-LCF11:  sta HealthHi                    ;Save results. +
- +
-LCF14:  lda TankCount                   ; +
-LCF17:  jsr Amul16                      ;($C2C5)*16. Move tank count to upper 4 bits. +
-LCF1A:  ora #$0F                        ;Set lower 4 bits. +
-LCF1C:  cmp HealthHi                    ; +
-LCF1F:  bcs +                           ;Is life less than max? if so, branch. +
-LCF21:  and #$F9                        ;Life is more than max amount.  +
-LCF23:  sta HealthHi                    ; +
-LCF26:  lda #$99                        ;Set life to max amount. +
-LCF28:  sta HealthLo                    ; +
-LCF2B:* jmp ClearHealthChange           ;($F323) +
- +
-;---------------------------------------------------------------------------------------------------- +
- +
-LCF2E:  lda SamusHit +
-LCF31:  lsr +
-        and #$02 +
-        beq +++ +
-        bcs + +
-        lda SamusHorzAccel +
-        bmi +++ +
-        bpl ++ +
-*       lda SamusHorzAccel +
-        bmi + +
-        bne ++ +
-*       jsr TwosCompliment              ;($C3D4) +
-        sta SamusHorzAccel +
- +
-ClearHorzMvmntData: +
-LCF4C:  ldy #$00                        ; +
-LCF4E:  sty ObjHorzSpeed                ;Set Samus Horizontal speed and horizontal--> +
-        sty HorzCntrLinear              ;linear counter to #$00. +
-*       rts                             ; +
- +
-StopHorzMovement: +
-LCF55:  lda SamusHorzAccel              ;Is Samus moving horizontally?--> +
-        bne ClearHorzMvmtAnimData       ;If so, branch to stop movement. +
-        jsr SFX_SamusWalk               ;($CB96)Play walk SFX. +
- +
-ClearHorzMvmtAnimData: +
-LCF5D:  jsr NoHorzMoveNoDelay           ;($CF81)Clear horizontal movement and animation delay data. +
-        sty ObjAction                   ;Samus is standing. +
-        lda Joy1Status                  ; +
-        and #$08                        ;Is The up button being pressed?--> +
-        bne +                           ;If so, branch. +
-        lda #an_SamusStand              ;Set Samus animation for standing. +
- +
-SetSamusAnim: +
-LCF6B:  sta AnimResetIndex              ;Set new animation reset index. +
- +
-SetSamusNextAnim: +
-        sta AnimIndex                   ;Set new animation data index. +
-        lda #$00                        ; +
-        sta AnimDelay                   ;New animation to take effect immediately. +
-        rts                             ; +
- +
-SetSamusPntUp: +
-LCF77:* lda #sa_PntUp                   ; +
-        sta ObjAction                   ;Samus is pointing up. +
-        lda #an_SamusPntUp              ; +
-        jsr SetSamusAnim                ;($CF6B)Set new animation values. +
- +
-NoHorzMoveNoDelay: +
-LCF81:  jsr ClearHorzData               ;($CFB7)Clear all horizontal movement data. +
-        sty AnimDelay                   ;Clear animation delay data. +
-        rts                             ; +
- +
-LCF88:  lda Joy1Status +
-        and #$03 +
-        beq + +
-        jsr BitScan                     ;($E1E1) +
-        tax +
-        jsr LCCB7 +
-        lda SamusGravity +
-        bmi ++ +
-        lda AnimResetIndex +
-        cmp #an_SamusSalto +
-        beq ++ +
-        stx SamusDir +
-        lda Table06+1,+
-        jmp SetSamusAnim +
- +
-*       lda SamusGravity +
-        bmi + +
-        beq + +
-        lda AnimResetIndex +
-        cmp #an_SamusJump +
-        bne + +
- +
-ClearHorzData: +
-LCFB7:  jsr ClearHorzMvmntData          ;($CF4C)Clear horizontal speed and linear counter. +
-        sty SamusHorzAccel              ;Clear horizontal acceleration data. +
-*       rts                             ; +
- +
-LCFBE:  ldy #an_SamusJumpPntUp +
-        jmp + +
- +
-SetSamusJump: +
-LCFC3:  ldy #an_SamusJump +
-*       sty AnimResetIndex +
-        dey +
-        sty AnimIndex +
-        lda #$04 +
-        sta AnimDelay +
-        lda #$00 +
-        sta SamusJumpDsplcmnt +
-        lda #$FC +
-        sta ObjVertSpeed +
-        ldx ObjAction +
-        dex +
-        bne +      ; branch if Samus is standing still +
-        lda SamusGear +
-        and #gr_SCREWATTACK +
-        beq +      ; branch if Samus doesn't have Screw Attack +
-        lda #$00 +
-        sta $0686 +
-        jsr SFX_ScrewAttack +
-*       jsr SFX_SamusJump +
-LCFF3:  ldy #$18        ; gravity (high value -> low jump) +
-        lda SamusGear +
-        and #gr_HIGHJUMP +
-        beq +      ; branch if Samus doesn't have High Jump +
-        ldy #$12        ; lower gravity value -> high jump! +
-*       sty SamusGravity +
-        rts +
- +
-SamusJump: +
-        lda SamusJumpDsplcmnt +
-        bit ObjVertSpeed +
-        bpl +      ; branch if falling down +
-        cmp #$20 +
-        bcc +      ; branch if jumped less than 32 pixels upwards +
-        bit Joy1Status +
-        bmi +      ; branch if JUMP button still pressed +
-        jsr StopVertMovement            ;($D147)Stop jump (start falling). +
-*       jsr LD055 +
-        jsr LCF2E +
-        lda Joy1Status +
-        and #$08     ; UP pressed? +
-        beq +      ; branch if not +
-        lda #an_SamusJumpPntUp +
-        sta AnimResetIndex +
-        lda #sa_PntJump      ; "jumping & pointing up" handler +
-        sta ObjAction +
-*       jsr LD09C +
-        lda SamusInLava +
-        beq + +
-        lda Joy1Change +
-        bpl +      ; branch if JUMP not pressed +
-        jsr LCFC3 +
-        jmp LCD6B +
- +
-*       lda SamusGravity +
-        bne ++ +
-        lda ObjAction +
-        cmp #sa_PntJump +
-        bne + +
-        jsr LCF77 +
-        bne ++ +
-*       jsr LCF55 +
-*       lda #$03 +
-        jmp SetSamusData                ;($CD6D)Set Samus control data and animation. +
- +
-LD055:  ldx #$01 +
-        ldy #$00 +
-        lda Joy1Status +
-        lsr +
-        bcs +      ; branch if RIGHT pressed +
-        dex +
-        lsr +
-        bcc ++++       ; branch if LEFT not pressed +
-        dex +
-        iny +
-*       cpy SamusDir +
-        beq +++ +
-        lda ObjAction +
-        cmp #sa_PntJump +
-        bne + +
-        lda AnimResetIndex +
-        cmp Table04,y +
-        bne ++ +
-        lda Table04+1,+
-        jmp ++ +
- +
-*       lda AnimResetIndex +
-        cmp Table06,y +
-        bne + +
-        lda Table06+1,+
-*       jsr SetSamusAnim +
-        lda #$08 +
-        sta AnimDelay +
-        sty SamusDir +
-*       stx ObjHorzSpeed +
-*       rts +
- +
-; Table used by above subroutine +
- +
-Table06: +
-        .byte $0C +
-        .byte $0C +
-        .byte $0C +
-Table04: +
-        .byte $35 +
-        .byte $35 +
-        .byte $35 +
- +
-LD09C:  lda Joy1Change +
-        ora Joy1Retrig +
-        asl +
-        bpl -      ; exit if FIRE not pressed +
-        lda AnimResetIndex +
-        cmp #an_SamusJumpPntUp +
-        bne + +
-        jmp LD275 +
- +
-*       jsr LD210 +
-        lda #an_SamusFireJump +
-        jmp SetSamusAnim +
- +
-SetSamusRoll: +
-LD0B5:  lda SamusGear +
-        and #gr_MARUMARI +
-        beq +      ; branch if Samus doesn't have Maru Mari +
-        lda SamusGravity +
-        bne + +
- +
-;Turn Samus into ball +
-        ldx SamusDir +
-        lda #an_SamusRoll +
-        sta AnimResetIndex +
-        lda #an_SamusRunJump +
-        sta AnimIndex +
-        lda LCCC0,x +
-        sta SamusHorzAccel +
-        lda #$01 +
-        sta $0686 +
-        jmp SFX_SamusBall +
- +
-*       lda #sa_Stand +
-        sta ObjAction +
-        rts +
- +
-; SamusRoll +
-; ========= +
- +
-        SamusRoll: +
-        lda Joy1Change +
-        and #$08     ; UP pressed? +
-        bne +      ; branch if yes +
-        bit Joy1Change  ; JUMP pressed? +
-        bpl ++    ; branch if no +
-*       lda Joy1Status +
-        and #$04           ; DOWN pressed? +
-        bne +     ; branch if yes +
-;break out of "ball mode" +
-        lda ObjRadY +
-        clc +
-        adc #$08 +
-        sta ObjRadY +
-        jsr CheckMoveUp +
-        bcc +     ; branch if not possible to stand up +
-        ldx #$00 +
-        jsr LE8BE +
-        stx $05 +
-        lda #$F5 +
-        sta $04 +
-        jsr LFD8F +
-        jsr LD638 +
-        jsr LCF55 +
-        dec AnimIndex +
-        jsr StopVertMovement            ;($D147) +
-        lda #$04 +
-        jmp LD144 +
- +
-*       lda Joy1Change +
-        jsr BitScan                     ;($E1E1) +
-        cmp #$02 +
-        bcs + +
-        sta SamusDir +
-        lda #an_SamusRoll +
-        jsr SetSamusAnim +
-*       ldx SamusDir +
-        jsr LCCB7 +
-        jsr LCF2E +
-        jsr CheckBombLaunch +
-        lda Joy1Status +
-        and #$03 +
-        bne + +
-        jsr LCFB7 +
-*       lda #$02 +
-LD144:  jmp SetSamusData                ;($CD6D)Set Samus control data and animation. +
- +
-StopVertMovement: +
-LD147:  ldy #$00 +
-        sty ObjVertSpeed +
-        sty VertCntrLinear +
-        rts +
- +
-; CheckBombLaunch +
-; =============== +
-; This routine is called only when Samus is rolled into a ball. +
-; It does the following: +
-; - Checks if Samus has bombs +
-; - If so, checks if the FIRE button has been pressed +
-; - If so, checks if there are any object "slots" available +
-;   (only 3 bullets/bombs can be active at the same time) +
-; - If so, a bomb is launched. +
- +
-        CheckBombLaunch: +
-        lda SamusGear +
-        lsr +
-        bcc ++    ; exit if Samus doesn't have Bombs +
-        lda Joy1Change +
-        ora Joy1Retrig +
-        asl             ; bit 7 = status of FIRE button +
-        bpl ++    ; exit if FIRE not pressed +
-        lda ObjVertSpeed +
-        ora SamusOnElevator +
-        bne ++ +
-        ldx #$D0        ; try object slot D +
-        lda ObjAction,+
-        beq +      ; launch bomb if slot available +
-        ldx #$E0        ; try object slot E +
-        lda ObjAction,+
-        beq +      ; launch bomb if slot available +
-        ldx #$F0        ; try object slot F +
-        lda ObjAction,+
-        bne ++    ; no bomb slots available, exit +
-; launch bomb... give it same coords as Samus +
-*       lda ObjectHi +
-        sta ObjectHi,+
-        lda ObjectX +
-        sta ObjectX,x +
-        lda ObjectY +
-        clc +
-        adc #$04        ; 4 pixels further down than Samus' center +
-        sta ObjectY,x +
-        lda #wa_LayBomb +
-        sta ObjAction,+
-        jsr SFX_BombLaunch +
-*       rts +
- +
-        SamusPntUp: +
-        lda Joy1Status +
-        and #$08     ; UP still pressed? +
-        bne +      ; branch if yes +
-        lda #sa_Stand   ; stand handler +
-        sta ObjAction +
-*       lda Joy1Status +
-        and #$07        ; DOWN, LEFT, RIGHT pressed? +
-        beq ++    ; branch if no +
-        jsr BitScan                     ;($E1E1) +
-        cmp #$02 +
-        bcs + +
-        sta SamusDir +
-*       tax +
-        lda Table07,x +
-        sta ObjAction +
-*       lda Joy1Change +
-        ora Joy1Retrig +
-        asl +
-        bpl +      ; branch if FIRE not pressed +
-        jsr FireWeapon                  ;($D1EE)Shoot up. +
-*       bit Joy1Change +
-        bpl +      ; branch if JUMP not pressed +
-        lda #sa_PntJump +
-        sta ObjAction +
-*       lda #$04 +
-        jsr SetSamusData                ;($CD6D)Set Samus control data and animation. +
-        lda ObjAction +
-        jsr ChooseRoutine +
- +
-; Pointer table to code +
- +
-        .word $CF55 +
-        .word $CC98 +
-        .word ExitSub       ;($C45C)rts +
-        .word $D0B5 +
-        .word ExitSub       ;($C45C)rts +
-        .word ExitSub       ;($C45C)rts +
-        .word $CFBE +
-        .word ExitSub       ;($C45C)rts +
-        .word ExitSub       ;($C45C)rts +
-        .word ExitSub       ;($C45C)rts +
- +
-; Table used by above subroutine +
- +
-Table07: +
-        .byte sa_Run +
-        .byte sa_Run +
-        .byte sa_Roll +
- +
-FireWeapon: +
-LD1EE:  lda Joy1Status +
-        and #$08 +
-        beq LD210 +
-        jmp LD275 +
- +
-LD1F7:  ldy #$D0 +
-*       lda ObjAction,+
-        beq + +
-        jsr Yplus16 +
-        bne - +
-        iny +
-        rts +
- +
-*       sta $030A,y +
-        lda MissileToggle +
-        beq + +
-        cpy #$D0 +
-*       rts +
- +
-LD210:  lda MetroidOnSamus +
-        bne + +
-        jsr LD1F7 +
-        bne + +
-        jsr LD2EB +
-        jsr LD359 +
-        jsr LD38E +
-        lda #$0C +
-        sta $030F,y +
-        ldx SamusDir +
-        lda Table99,  ; get bullet speed +
-        sta ObjHorzSpeed,    ; -4 or 4, depending on Samus' direction +
-        lda #$00 +
-        sta ObjVertSpeed,+
-        lda #$01 +
-        sta ObjectOnScreen,+
-        jsr CheckMissileLaunch +
-        lda ObjAction,+
-        asl +
-        ora SamusDir +
-        and #$03 +
-        tax +
-        lda Table08,x +
-        sta $05 +
-        lda #$FA +
-        sta $04 +
-        jsr LD306 +
-        lda SamusGear +
-        and #gr_LONGBEAM +
-        lsr +
-        lsr +
-        lsr +
-        ror +
-        ora $061F +
-        sta $061F +
-        ldx ObjAction,+
-        dex +
-        bne + +
-        jsr SFX_BulletFire +
-*       ldy #$09 +
-LD26B:  tya +
-        jmp SetSamusNextAnim +
- +
-Table08: +
-        .byte $0C +
-        .byte $F4 +
-        .byte $08 +
-        .byte $F8 +
- +
-Table99: +
-        .byte $04 +
-        .byte $FC +
- +
-LD275:  lda MetroidOnSamus +
-        bne + +
-        jsr LD1F7 +
-        bne + +
-        jsr LD2EB +
-        jsr LD38A +
-        jsr LD38E +
-        lda #$0C +
-        sta $030F,y +
-        lda #$FC +
-        sta ObjVertSpeed,+
-        lda #$00 +
-        sta ObjHorzSpeed,+
-        lda #$01 +
-        sta ObjectOnScreen,+
-        jsr LD340 +
-        ldx SamusDir +
-        lda Table09+4,+
-        sta $05 +
-        lda ObjAction,+
-        and #$01 +
-        tax +
-        lda Table09+6,+
-        sta $04 +
-        jsr LD306 +
-        lda SamusGear +
-        and #gr_LONGBEAM +
-        lsr +
-        lsr +
-        lsr +
-        ror +
-        ora $061F +
-        sta $061F +
-        lda ObjAction,+
-        cmp #$01 +
-        bne + +
-        jsr SFX_BulletFire +
-*       ldx SamusDir +
-        ldy Table09,x +
-        lda SamusGravity +
-        beq + +
-        ldy Table09+2,+
-*       lda ObjAction +
-        cmp #$01 +
-        beq + +
-        jmp LD26B +
- +
-; Table used by above subroutine +
- +
-Table09: +
-        .byte $26 +
-        .byte $26 +
-        .byte $34 +
-        .byte $34 +
-        .byte $01 +
-        .byte $FF +
-        .byte $EC +
-        .byte $F0 +
- +
-LD2EB:  tya +
-        tax +
-        inc ObjAction,+
-        lda #$02 +
-        sta ObjRadY,y +
-        sta ObjRadX,y +
-        lda #an_Bullet +
- +
-SetProjectileAnim: +
-LD2FA:  sta AnimResetIndex,+
-        sta AnimIndex,+
-        lda #$00 +
-        sta AnimDelay,+
-*       rts +
- +
-LD306:  ldx #$00 +
-        jsr LE8BE +
-        tya +
-        tax +
-        jsr LFD8F +
-        txa +
-        tay +
-        jmp LD638 +
- +
-CheckMissileLaunch: +
-        lda MissileToggle +
-        beq Exit4       ; exit if Samus not in "missile fire" mode +
-        cpy #$D0 +
-        bne Exit4 +
-        ldx SamusDir +
-        lda MissileAnims,+
-*       jsr SetBulletAnim +
-        jsr SFX_MissileLaunch +
-        lda #wa_Missile ; missile handler +
-        sta ObjAction,+
-        lda #$FF +
-        sta $030F,    ; # of frames projectile should last +
-        dec MissileCount +
-        bne Exit4       ; exit if not the last missile +
-; Samus has no more missiles left +
-        dec MissileToggle       ; put Samus in "regular fire" mode +
-        jmp SelectSamusPal      ; update Samus' palette to reflect this +
- +
-MissileAnims: +
-        .byte an_MissileRight +
-        .byte an_MissileLeft +
- +
-LD340:  lda MissileToggle +
-        beq Exit4 +
-        cpy #$D0 +
-        bne Exit4 +
-        lda #$8F +
-        bne - +
- +
-SetBulletAnim: +
-        sta AnimIndex,+
-        sta AnimResetIndex,+
-        lda #$00 +
-        sta AnimDelay,+
-Exit4:  rts +
- +
-LD359:  lda SamusDir +
-*       sta $0502,y +
-        bit SamusGear +
-        bvc Exit4       ; branch if Samus doesn't have Wave Beam +
-        lda MissileToggle +
-        bne Exit4 +
-        lda #$00 +
-        sta $0501,y +
-        sta $0304,y +
-        tya +
-        jsr Adiv32      ; / 32 +
-        lda #$00 +
-        bcs + +
-        lda #$0C +
-*       sta $0500,y +
-        lda #wa_WaveBeam +
-        sta ObjAction,+
-        lda #an_WaveBeam +
-        jsr SetBulletAnim +
-        jmp SFX_WaveFire +
- +
-LD38A:  lda #$02 +
-        bne -- +
-LD38E:  lda MissileToggle +
-        bne Exit4 +
-        lda SamusGear +
-        bpl Exit4       ; branch if Samus doesn't have Ice Beam +
-        lda #wa_IceBeam +
-        sta ObjAction,+
-        lda $061F +
-        ora #$01 +
-        sta $061F +
-        jmp SFX_BulletFire +
- +
-; SamusDoor +
-; ========= +
- +
-SamusDoor: +
-        lda DoorStatus +
-        cmp #$05 +
-        bcc +++++++ +
-    ; move Samus out of door, how far depends on initial value of DoorDelay +
-        dec DoorDelay +
-        bne MoveOutDoor +
-    ; done moving +
-        asl +
-        bcc + +
-        lsr +
-        sta DoorStatus +
-        bne +++++++ +
-*       jsr LD48C +
-        jsr LED65 +
-        jsr $95AB +
-        lda ItemRoomMusicStatus +
-        beq ++ +
-        pha +
-        jsr LD92C       ; start music +
-        pla +
-        bpl ++ +
-        lda #$00 +
-        sta ItemRoomMusicStatus +
-        beq ++ +
-*       lda #$80 +
-        sta ItemRoomMusicStatus +
-*       lda KraidRidleyPresent +
-        beq + +
-        jsr LCC07 +
-        lda #$00 +
-        sta KraidRidleyPresent +
-        beq --     ; branch always +
-*       lda SamusDoorData +
-        and #$0F +
-        sta ObjAction +
-        lda #$00 +
-        sta SamusDoorData +
-        sta DoorStatus +
-        jsr StopVertMovement            ;($D147) +
- +
-MoveOutDoor: +
-        lda SamusDoorDir +
-        beq ++    ; branch if door leads to the right +
-        ldy ObjectX +
-        bne + +
-        jsr ToggleSamusHi       ; toggle 9th bit of Samus' X coord +
-*       dec ObjectX +
-        jmp ++ +
- +
-*       inc ObjectX +
-        bne + +
-        jsr ToggleSamusHi       ; toggle 9th bit of Samus' X coord +
-*       jsr CheckHealthStatus           ;($CDFA)Check if Samus hit, blinking or Health low. +
-        jsr SetmirrorCntrlBit +
-        jmp DrawFrame       ; display Samus +
- +
-SamusDead: +
-D41A:   lda #$01 +
-        jmp SetSamusData                ;($CD6D)Set Samus control data and animation. +
- +
-SamusDead2: +
-        dec AnimDelay +
-        rts +
- +
-; SamusElevator +
-; ============= +
- +
-SamusElevator: +
-        lda ElevatorStatus +
-        cmp #$03 +
-        beq + +
-        cmp #$08 +
-        bne +++++++ +
-*       lda $032F +
-        bmi +++ +
-        lda ObjectY +
-        sec +
-        sbc ScrollY     ; A = Samus' Y position on the visual screen +
-        cmp #$84 +
-        bcc +      ; if ScreenY < $84, don't scroll +
-        jsr ScrollDown  ; otherwise, attempt to scroll +
-*       ldy ObjectY +
-        cpy #239        ; wrap-around required? +
-        bne + +
-        jsr ToggleSamusHi       ; toggle 9th bit of Samus' Y coord +
-        ldy #$FF        ; ObjectY will now be 0 +
-*       iny +
-        sty ObjectY +
-        jmp LD47E +
- +
-*       lda ObjectY +
-        sec +
-        sbc ScrollY     ; A = Samus' Y position on the visual screen +
-        cmp #$64 +
-        bcs +      ; if ScreenY >= $64, don't scroll +
-        jsr ScrollUp    ; otherwise, attempt to scroll +
-*       ldy ObjectY +
-        bne +      ; wraparound required? (branch if not) +
-        jsr ToggleSamusHi       ; toggle 9th bit of Samus' Y coord +
-        ldy #240        ; ObjectY will now be 239 +
-*       dey +
-        sty ObjectY +
-        jmp LD47E +
- +
-*       ldy #$00 +
-        sty ObjVertSpeed +
-        cmp #$05 +
-        beq + +
-        cmp #$07 +
-        beq + +
-LD47E:  lda FrameCount +
-        lsr +
-        bcc ++ +
-*       jsr SetmirrorCntrlBit           ;($CD92)Mirror Samus, if necessary. +
-        lda #$01 +
-        jmp AnimDrawObject +
-*       rts +
- +
-LD48C:  ldx #$60 +
-        sec +
-*       jsr LD4B4 +
-        txa +
-        sbc #$20 +
-        tax +
-        bpl - +
-        jsr GetNameTable                ;($EB85) +
-        tay +
-        ldx #$18 +
-*       jsr LD4A8 +
-        txa +
-        sec +
-        sbc #$08 +
-        tax +
-        bne - +
-LD4A8:  tya +
-        cmp $072C,x +
-        bne + +
-        lda #$FF +
-        sta $0728,x +
-*       rts +
- +
-LD4B4:  lda $0405,x +
-LD4B7:  and #$02 +
-LD4B9:  bne + +
-LD4BB:  sta EnStatus,+
-LD4BE:* rts +
- +
-; UpdateProjectiles +
-; ================= +
- +
-UpdateProjectiles: +
-        ldx #$D0 +
-jsr DoOneProjectile +
-        ldx #$E0 +
-jsr DoOneProjectile +
-        ldx #$F0 +
-DoOneProjectile: +
-        stx PageIndex +
-        lda ObjAction,+
-LD4D0:  jsr ChooseRoutine +
- +
-LD4D3:  .word ExitSub     ;($C45C) rts +
-LD4D5:  .word UpdateBullet ; regular beam +
-        .word UpdateWaveBullet      ; wave beam +
-        .word UpdateIceBullet       ; ice beam +
-        .word BulletExplode    ; bullet/missile explode +
-        .word $D65E       ; lay bomb +
-        .word $D670       ; lay bomb +
-        .word $D691       ; lay bomb +
-        .word $D65E       ; lay bomb +
-        .word $D670       ; bomb countdown +
-        .word $D691       ; bomb explode +
-        .word UpdateBullet  ; missile +
- +
-UpdateBullet: +
-        lda #$01 +
-        sta UpdatingProjectile +
-        jsr LD5FC +
-        jsr LD5DA +
-        jsr LD609 +
-CheckBulletStat: +
-        ldx PageIndex +
-        bcc + +
-        lda SamusGear +
-        and #gr_LONGBEAM +
-        bne DrawBullet  ; branch if Samus has Long Beam +
-        dec $030F,    ; decrement bullet timer +
-        bne DrawBullet +
-        lda #$00        ; timer hit 0, kill bullet +
-        sta ObjAction,+
-        beq DrawBullet  ; branch always +
-*       lda ObjAction,+
-        beq + +
-        jsr LD5E4 +
-DrawBullet: +
-        lda #$01 +
-        jsr AnimDrawObject +
-*       dec UpdatingProjectile +
-        rts +
- +
-*       inc $0500,x +
-LD522:  inc $0500,x +
-        lda #$00 +
-        sta $0501,x +
-        beq +      ; branch always +
- +
-UpdateWaveBullet: +
-        lda #$01 +
-        sta UpdatingProjectile +
-        jsr LD5FC +
-        jsr LD5DA +
-        lda $0502,x +
-        and #$FE +
-        tay +
-        lda Table0A,y +
-        sta $0A +
-        lda Table0A+1,+
-        sta $0B +
-*       ldy $0500,x +
-        lda ($0A),y +
-        cmp #$FF +
-        bne + +
-        sta $0500,x +
-        jmp LD522 +
- +
-*       cmp $0501,x +
-        beq --- +
-        inc $0501,x +
-        iny +
-        lda ($0A),y +
-        jsr $8296 +
-        ldx PageIndex +
-        sta ObjVertSpeed,+
-        lda ($0A),y +
-        jsr $832F +
-        ldx PageIndex +
-        sta ObjHorzSpeed,+
-        tay +
-        lda $0502,x +
-        lsr +
-        bcc + +
-        tya +
-        jsr TwosCompliment              ;($C3D4) +
-        sta ObjHorzSpeed,+
-*       jsr LD609 +
-        bcs + +
-        jsr LD624 +
-*       jmp CheckBulletStat +
- +
-Table0A: +
-        .word Table0C     ; pointer to table #1 below +
-        .word Table0D     ; pointer to table #2 below +
- +
-; Table #1 (size: 25 bytes) +
- +
-Table0C: +
-        .byte $01 +
-        .byte $F3 +
-        .byte $01 +
-        .byte $D3 +
-        .byte $01 +
-        .byte $93 +
-        .byte $01 +
-        .byte $13 +
-        .byte $01 +
-        .byte $53 +
-        .byte $01 +
-        .byte $73 +
-        .byte $01 +
-        .byte $73 +
-        .byte $01 +
-        .byte $53 +
-        .byte $01 +
-        .byte $13 +
-        .byte $01 +
-        .byte $93 +
-        .byte $01 +
-        .byte $D3 +
-        .byte $01 +
-        .byte $F3 +
-        .byte $FF +
- +
-; Table #2 (size: 25 bytes) +
- +
-Table0D: +
-        .byte $01 +
-        .byte $B7 +
-        .byte $01 +
-        .byte $B5 +
-        .byte $01 +
-        .byte $B1 +
-        .byte $01 +
-        .byte $B9 +
-        .byte $01 +
-        .byte $BD +
-        .byte $01 +
-        .byte $BF +
-        .byte $01 +
-        .byte $BF +
-        .byte $01 +
-        .byte $BD +
-        .byte $01 +
-        .byte $B9 +
-        .byte $01 +
-        .byte $B1 +
-        .byte $01 +
-        .byte $B5 +
-        .byte $01 +
-        .byte $B7 +
-        .byte $FF +
- +
-; UpdateIceBullet +
-; =============== +
- +
-        UpdateIceBullet: +
-        lda #$81 +
-        sta ObjectCntrl +
-        jmp UpdateBullet +
- +
-; BulletExplode +
-; ============= +
-; bullet/missile explode +
- +
-        BulletExplode: +
-        lda #$01 +
-        sta UpdatingProjectile +
-        lda $0303,x +
-        sec +
-        sbc #$F7 +
-        bne + +
-        sta ObjAction, ; kill bullet +
-*       jmp DrawBullet +
- +
-LD5DA:  lda $030A,x +
-        beq Exit5 +
-        lda #$00 +
-        sta $030A,x +
-LD5E4:  lda #$1D +
-        ldy ObjAction,+
-        cpy #wa_BulletExplode +
-        beq Exit5 +
-        cpy #wa_Missile +
-        bne + +
-        lda #an_MissileExplode +
-*       jsr SetProjectileAnim +
-        lda #wa_BulletExplode +
-*       sta ObjAction,+
-Exit5:  rts +
- +
-LD5FC:  lda ObjectOnScreen,+
-        lsr +
-        bcs Exit5 +
-*       lda #$00 +
-        beq --   ; branch always +
-*       jmp LE81E +
- +
-; bullet <--> background crash detection +
- +
-LD609:  jsr GetObjCoords +
-        ldy #$00 +
-        lda ($04),    ; get tile # that bullet touches +
-        cmp #$A0 +
-        bcs LD624 +
-        jsr $95C0 +
-        cmp #$4E +
-        beq - +
-        jsr LD651 +
-        bcc ++ +
-        clc +
-        jmp IsBlastTile +
- +
-LD624:  ldx PageIndex +
-        lda ObjHorzSpeed,+
-        sta $05 +
-        lda ObjVertSpeed,+
-        sta $04 +
-        jsr LE8BE +
-        jsr LFD8F +
-        bcc -- +
-LD638:  lda $08 +
-        sta ObjectY,x +
-        lda $09 +
-        sta ObjectX,x +
-        lda $0B +
-        and #$01 +
-        bpl +      ; branch always +
-        ToggleObjectHi: +
-        lda ObjectHi,+
-        eor #$01 +
-*       sta ObjectHi,+
-*       rts +
- +
-LD651:  ldy InArea +
-        cpy #$10 +
-        beq + +
-        cmp #$70 +
-        bcs ++ +
-*       cmp #$80 +
-*       rts +
- +
-LD65E:  lda #an_BombTick +
-        jsr SetProjectileAnim +
-        lda #$18        ; fuse length :-) +
-        sta $030F,x +
-        inc ObjAction,      ; bomb update handler +
-        DrawBomb: +
-        lda #$03 +
-        jmp AnimDrawObject +
- +
-LD670:  lda FrameCount +
-        lsr +
-        bcc ++    ; only update counter on odd frames +
-        dec $030F,x +
-        bne ++ +
-        lda #$37 +
-        ldy ObjAction,+
-        cpy #$09 +
-        bne + +
-        lda #an_BombExplode +
-*       jsr SetProjectileAnim +
-        inc ObjAction,+
-        jsr SFX_BombExplode +
-*       jmp DrawBomb +
- +
-LD691:  inc $030F,x +
-        jsr LD6A7 +
-        ldx PageIndex +
-        lda $0303,x +
-        sec +
-        sbc #$F7 +
-        bne + +
-        sta ObjAction,    ; kill bomb +
-*       jmp DrawBomb +
- +
-LD6A7:  jsr GetObjCoords +
-        lda $04 +
-        sta $0A +
-        lda $05 +
-        sta $0B +
-        ldx PageIndex +
-        ldy $030F,x +
-        dey +
-        beq ++ +
-        dey +
-        bne +++ +
-        lda #$40 +
-        jsr LD78B +
-        txa +
-        bne + +
-        lda $04 +
-        and #$20 +
-        beq Exit6 +
-*       lda $05 +
-        and #$03 +
-        cmp #$03 +
-        bne + +
-        lda $04 +
-        cmp #$C0 +
-        bcc + +
-        lda ScrollDir +
-        and #$02 +
-        bne Exit6 +
-        lda #$80 +
-        jsr LD78B +
-*       jsr LD76A +
-Exit6:  rts +
- +
-*       dey +
-        bne +++ +
-        lda #$40 +
-        jsr LD77F +
-        txa +
-        bne + +
-        lda $04 +
-        and #$20 +
-        bne Exit6 +
-*       lda $05 +
-        and #$03 +
-        cmp #$03 +
-        bne + +
-        lda $04 +
-        cmp #$C0 +
-        bcc + +
-        lda ScrollDir +
-        and #$02 +
-        bne Exit6 +
-        lda #$80 +
-        jsr LD77F +
-*       jmp LD76A +
- +
-*       dey +
-        bne +++ +
-        lda #$02 +
-        jsr LD78B +
-        txa +
-        bne + +
-        lda $04 +
-        lsr +
-        bcc Exit7 +
-*       lda $04 +
-        and #$1F +
-        cmp #$1E +
-        bcc + +
-        lda ScrollDir +
-        and #$02 +
-        beq Exit7 +
-        lda #$1E +
-        jsr LD77F +
-        lda $05 +
-        eor #$04 +
-        sta $05 +
-*       jmp LD76A +
- +
-*       dey +
-        bne Exit7 +
-        lda #$02 +
-        jsr LD77F +
-        txa +
-        bne + +
-        lda $04 +
-        lsr +
-        bcs Exit7 +
-*       lda $04 +
-        and #$1F +
-        cmp #$02 +
-        bcs LD76A +
-        lda ScrollDir +
-        and #$02 +
-        beq Exit7 +
-        lda #$1E +
-        jsr LD78B +
-        lda $05 +
-        eor #$04 +
-        sta $05 +
-LD76A:  txa +
-        pha +
-        ldy #$00 +
-        lda ($04),y +
-        jsr LD651 +
-        bcc + +
-        cmp #$A0 +
-        bcs + +
-        jsr LE9C2 +
-*       pla +
-        tax +
-Exit7:  rts +
- +
-LD77F:  clc +
-        adc $0A +
-        sta $04 +
-        lda $0B +
-        adc #$00 +
-        jmp LD798 +
- +
-LD78B:  sta $00 +
-        lda $0A +
-        sec +
-        sbc $00 +
-        sta $04 +
-        lda $0B +
-        sbc #$00 +
-LD798:  and #$07 +
-        ora #$60 +
-        sta $05 +
-*       rts +
- +
-;-------------------------------------[ Get object coordinates ]------------------------------------ +
- +
-GetObjCoords: +
-LD79F:  ldx PageIndex                   ;Load index into object RAM to find proper object. +
-LD7A1:  lda ObjectY,                  ; +
-LD7A4:  sta $02                         ;Load and save temp copy of object y coord. +
-LD7A6:  lda ObjectX,                  ; +
-LD7A9:  sta $03                         ;Load and save temp copy of object x coord. +
-LD7AB:  lda ObjectHi,                 ; +
-LD7AE:  sta $0B                         ;Load and save temp copy of object nametable. +
-LD7B0:  jmp MakeCartRAMPtr              ;($E96A)Find object position in room RAM. +
- +
-;--------------------------------------------------------------------------------------------------- +
- +
-UpdateElevator: +
-        ldx #$20 +
-        stx PageIndex +
-        lda ObjAction,+
-        jsr ChooseRoutine +
- +
-; Pointer table to elevator handlers +
- +
-        .word ExitSub       ;($C45C) rts +
-        .word ElevatorIdle +
-        .word $D80E +
-        .word ElevatorMove +
-        .word ElevatorScroll +
-        .word $D8A3 +
-        .word $D8BF +
-        .word $D8A3 +
-        .word ElevatorMove +
-        .word ElevatorStop +
- +
-        ElevatorIdle: +
-        lda SamusOnElevator +
-        beq ShowElevator +
-        lda #$04 +
-        bit $032F       ; elevator direction in bit 7 (1 = up) +
-        bpl + +
-        asl             ; btn_UP +
-*       and Joy1Status +
-        beq ShowElevator +
-    ; start elevator! +
-        jsr StopVertMovement            ;($D147) +
-        sty AnimDelay +
-        sty SamusGravity +
-        tya +
-        sta ObjVertSpeed,+
-        inc ObjAction,+
-        lda #sa_Elevator +
-        sta ObjAction +
-        lda #an_SamusFront +
-        jsr SetSamusAnim +
-        lda #128 +
-        sta ObjectX     ; center +
-        lda #112 +
-        sta ObjectY     ; center +
-        ShowElevator: +
-        lda FrameCount +
-        lsr +
-        bcc --    ; only display elevator at odd frames +
-        jmp DrawFrame       ; display elevator +
- +
-LD80E:  lda ScrollX +
-        bne + +
-        lda MirrorCntrl +
-        ora #$08 +
-        sta MirrorCntrl +
-        lda ScrollDir +
-        and #$01 +
-        sta ScrollDir +
-        inc ObjAction,+
-        jmp ShowElevator +
- +
-*       lda #$80 +
-        sta ObjectX +
-        lda ObjectX,x +
-        sec +
-        sbc ScrollX +
-        bmi + +
-        jsr ScrollLeft +
-        jmp ShowElevator +
- +
-*       jsr ScrollRight +
-        jmp ShowElevator +
- +
-        ElevatorMove: +
-        lda $030F,x +
-        bpl ++    ; branch if elevator going down +
-    ; move elevator up one pixel +
-        ldy ObjectY,x +
-        bne + +
-        jsr ToggleObjectHi +
-        ldy #240 +
-*       dey +
-        tya +
-        sta ObjectY,x +
-        jmp ++ +
- +
-    ; move elevator down one pixel +
-*       inc ObjectY,x +
-        lda ObjectY,x +
-        cmp #240 +
-        bne + +
-        jsr ToggleObjectHi +
-        lda #$00 +
-        sta ObjectY,x +
-*       cmp #$83 +
-        bne +      ; move until Y coord = $83 +
-        inc ObjAction,+
-*       jmp ShowElevator +
- +
-        ElevatorScroll: +
-        lda ScrollY +
-        bne ElevScrollRoom  ; scroll until ScrollY = 0 +
-        lda #$4E +
-        sta AnimResetIndex +
-        lda #$41 +
-        sta AnimIndex +
-        lda #$5D +
-        sta AnimResetIndex,+
-        lda #$50 +
-        sta AnimIndex,+
-        inc ObjAction,+
-        lda #$40 +
-        sta Timer1 +
-        jmp ShowElevator +
- +
-        ElevScrollRoom: +
-        lda $030F,x +
-        bpl +      ; branch if elevator going down +
-        jsr ScrollUp +
-        jmp ShowElevator +
- +
-*       jsr ScrollDown +
-        jmp ShowElevator +
- +
-LD8A3:  inc ObjAction,+
-        lda ObjAction,+
-        cmp #$08        ; ElevatorMove +
-        bne + +
-        lda #$23 +
-        sta $0303,x +
-        lda #an_SamusFront +
-        jsr SetSamusAnim +
-        jmp ShowElevator +
- +
-*       lda #$01 +
-        jmp AnimDrawObject +
- +
-LD8BF:  lda $030F,x +
-        tay +
-        cmp #$8F        ; Leads-To-Ending elevator? +
-        bne + +
-    ; Samus made it! YAY! +
-        lda #$07 +
-        sta MainRoutine +
-        inc AtEnding +
-        ldy #$00 +
-        sty $33 +
-        iny +
-        sty SwitchPending   ; switch to bank 0 +
-        lda #$1D        ; ending +
-        sta TitleRoutine +
-        rts +
- +
-*       tya +
-        bpl ++ +
-        ldy #$00 +
-        cmp #$84 +
-        bne + +
-        iny +
-*       tya +
-*       ora #$10 +
-        jsr LCA18 +
-        lda PalToggle +
-        eor #$07 +
-        sta PalToggle +
-        ldy InArea +
-        cpy #$12 +
-        bcc + +
-        lda #$01 +
-*       sta PalDataPending +
-        jsr WaitNMIPass_ +
-        jsr SelectSamusPal +
-        jsr StartMusic                  ;($LD92C)Start music. +
-        jsr ScreenOn +
-        jsr CopyPtrs +
-        jsr DestroyEnemies +
-        ldx #$20 +
-        stx PageIndex +
-        lda #$6B +
-        sta AnimResetIndex +
-        lda #$5F +
-        sta AnimIndex +
-        lda #$7A +
-        sta AnimResetIndex,+
-        lda #$6E +
-        sta AnimIndex,+
-        inc ObjAction,+
-        lda #$40 +
-        sta Timer1 +
-        rts +
- +
-StartMusic: +
-LD92C:  lda ElevatorStatus +
-        cmp #$06 +
-        bne + +
-        lda $032F +
-        bmi ++ +
-*       lda $95CD                       ;Load proper bit flag for area music. +
-        ldy ItemRoomMusicStatus +
-        bmi ++ +
-        beq ++ +
-*       lda #$81 +
-        sta ItemRoomMusicStatus +
-        lda #$20                        ;Set flag to play item room music. +
- +
-*       ora MusicInitFlag               ; +
-        sta MusicInitFlag               ;Store music flag info. +
-        rts                             ; +
- +
-ElevatorStop: +
-        lda ScrollY +
-        bne ++    ; scroll until ScrollY = 0 +
-        lda #sa_Stand +
-        sta ObjAction +
-        jsr LCF55 +
-        ldx PageIndex   ; #$20 +
-        lda #$01        ; ElevatorIdle +
-        sta ObjAction,+
-        lda $030F,x +
-        eor #$80        ; switch elevator direction +
-        sta $030F,x +
-        bmi + +
-        jsr ToggleScroll +
-        sta MirrorCntrl +
-*       jmp ShowElevator +
-*       jmp ElevScrollRoom +
- +
-SamusOnElevatorOrEnemy: +
-LD976:  lda #$00                        ; +
-        sta SamusOnElevator             ;Assume Samus is not on an elevator or on a frozen enemy. +
-        sta OnFrozenEnemy               ; +
-        tay +
-        ldx #$50 +
-        jsr LF186 +
-*       lda EnStatus,+
-        cmp #$04 +
-        bne + +
-        jsr LF152 +
-        jsr LF1BF +
-        jsr LF1FA +
-        bcs + +
-        jsr LD9BA +
-        bne + +
-D99A:   inc OnFrozenEnemy               ;Samus is standing on a frozen enemy. +
-        bne ++ +
-*       jsr Xminus16 +
-        bpl -- +
-*       lda ElevatorStatus +
-        beq + +
-        ldy #$00 +
-        ldx #$20 +
-        jsr LDC82 +
-        bcs + +
-        jsr LD9BA +
-        bne + +
-        inc SamusOnElevator             ;Samus is standing on elevator. +
-*       rts +
- +
-LD9BA:  lda $10 +
-        and #$02 +
-        bne + +
-        ldy $11 +
-        iny +
-        cpy $04 +
-        beq Exit8 +
-*       lda SamusHit +
-        and #$38 +
-        ora $10 +
-        ora #$40 +
-        sta SamusHit +
-Exit8:  rts +
- +
-; UpdateStatues +
-; ============= +
- +
-        UpdateStatues: +
-        lda #$60 +
-        sta PageIndex +
-        ldy $0360 +
-        beq Exit8          ; exit if no statue present +
-        dey +
-        bne + +
-        jsr LDAB0 +
-        ldy #$01 +
-        jsr LDAB0 +
-        bcs + +
-        inc $0360 +
-*       ldy $0360 +
-        cpy #$02 +
-        bne +++ +
-        lda KraidStatueStatus +
-        bpl + +
-        ldy #$02 +
-        jsr LDAB0 +
-*       lda $687C +
-        bpl + +
-        ldy #$03 +
-        jsr LDAB0 +
-*       bcs + +
-        inc $0360 +
-*       ldx #$60 +
-        jsr LDA1A +
-        ldx #$61 +
-        jsr LDA1A +
-        jmp LDADA +
- +
-LDA1A:  jsr LDA3D +
-        jsr LDA7C +
-        txa +
-        and #$01 +
-        tay +
-        lda LDA3B,y +
-        sta $0363 +
-        lda $681B,x +
-        beq + +
-        bmi + +
-        lda FrameCount +
-        lsr +
-        bcc ++    ; only display statue at odd frames +
-*       jmp DrawFrame       ; display statue +
- +
-LDA39:  .byte $88 +
-        .byte $68 +
-LDA3B:  .byte $65 +
-        .byte $66 +
- +
-LDA3D:  lda $0304,x +
-        bmi + +
-        lda #$01 +
-        sta $0304,x +
-        lda $030F,x +
-        and #$0F +
-        beq + +
-        inc $0304,x +
-        dec $030F,x +
-        lda $030F,x +
-        and #$0F +
-        bne + +
-        lda $0304,x +
-        ora #$80 +
-        sta $0304,x +
-        sta $681B,x +
-        inc $0304,x +
-        txa +
-        pha +
-        and #$01 +
-        pha +
-        tay +
-        jsr LDAB0 +
-        pla +
-        tay +
-        iny +
-        iny +
-        jsr LDAB0 +
-        pla +
-        tax +
-*       rts +
- +
-LDA7C:  lda $030F,x +
-        sta $036D +
-        txa +
-        and #$01 +
-        tay +
-        lda LDA39,y +
-        sta $036E +
-        lda $681B,x +
-        beq + +
-        bmi + +
-        lda $0304,x +
-        cmp #$01 +
-        bne + +
-        lda $0306,x +
-        beq + +
-        dec $030F,x +
-        lda $0683 +
-        ora #$10 +
-        sta $0683 +
-*       lda #$00 +
-        sta $0306,x +
-        rts +
- +
-LDAB0:  lda Table0E,y +
-        sta $05C8 +
-        lda $036C +
-        asl +
-        asl +
-        ora Table1B,y +
-        sta $05C9 +
-        lda #$09 +
-        sta $05C3 +
-        lda #$C0 +
-        sta PageIndex +
-        jsr DrawTileBlast +
-        lda #$60 +
-        sta PageIndex +
-        rts +
- +
-; Table used by above subroutine +
- +
-Table0E: +
-        .byte $30 +
-        .byte $AC +
-        .byte $F0 +
-        .byte $6C +
-Table1B: +
-        .byte $61 +
-        .byte $60 +
-        .byte $60 +
-        .byte $60 +
- +
-LDADA:  lda $54 +
-        bmi Exit0 +
-        lda DoorStatus +
-        bne Exit0 +
-        lda KraidStatueStatus +
-        and $687C +
-        bpl Exit0 +
-        sta $54 +
-        ldx #$70 +
-        ldy #$08 +
-*       lda #$03 +
-        sta $0500,x +
-        tya +
-        asl +
-        sta $0507,x +
-        lda #$04 +
-        sta TileType,+
-        lda $036C +
-        asl +
-        asl +
-        ora #$62 +
-        sta TileWRAMHi,+
-        tya +
-        asl +
-        adc #$08 +
-        sta TileWRAMLo,+
-        jsr Xminus16 +
-        dey +
-        bne - +
-Exit0:  rts +
- +
-; CheckMissileToggle +
-; ================== +
-; Toggles between bullets/missiles (if Samus has any missiles). +
- +
-CheckMissileToggle: +
-        lda MissileCount +
-        beq Exit0       ; exit if Samus has no missiles +
-        lda Joy1Change +
-        ora Joy1Retrig +
-        and #$20         +
-        beq Exit0       ; exit if SELECT not pressed +
-        lda MissileToggle +
-        eor #$01        ; 0 = fire bullets, 1 = fire missiles +
-        sta MissileToggle +
-        jmp SelectSamusPal +
- +
-; MakeBitMask +
-; =========== +
-;In: Y = bit index. Out: A = bit Y set, other 7 bits zero. +
- +
-MakeBitMask: +
-LDB2F:  sec +
-LDB30:  lda #$00 +
-LDB32:* rol +
-LDB33:  dey +
-LDB34:  bpl - +
-LDB36:* rts +
- +
-;------------------------------------------[ Update items ]----------------------------------------- +
- +
-UpdateItems: +
-LDB37:  lda #$40                        ;PowerUp RAM starts at $0340. +
-LDB39:  sta PageIndex                   ; +
-LDB3B:  ldx #$00                        ;Check first item slot. +
-LDB3D:  jsr CheckOneItem                ;($DB42)Check current item slot. +
-LDB40:  ldx #$08                        ;Check second item slot. +
- +
-CheckOneItem: +
-LDB42:  stx ItemIndex                   ;First or second item slot index(#$00 or #$08). +
-LDB44:  ldy PowerUpType,              ; +
-LDB47:  iny                             ;Is no item present in item slot(#$FF)?--> +
-LDB48:  beq -                           ;If so, branch to exit. +
- +
-LDB4A:  lda PowerUpYCoord,            ; +
-LDB4D:  sta PowerUpY                    ; +
-LDB50:  lda PowerUpXCoord,            ;Store y, x and name table coordinates of power up item. +
-LDB53:  sta PowerUpX                    ; +
-LDB56:  lda PowerUpNameTable,         ; +
-LDB59:  sta PowerUpHi                   ; +
-LDB5C:  jsr GetObjCoords                ;($D79F)Find object position in room RAM. +
-LDB5F:  ldx ItemIndex                   ;Index to proper power up item. +
-LDB61:  ldy #$00                        ;Reset index. +
-LDB63:  lda ($04),                    ;Load pointer into room RAM. +
-LDB65:  cmp #$A0                        ;Is object being placed on top of a solid tile?--> +
-LDB67:  bcc -                           ;If so, branch to exit. +
-LDB69:  lda PowerUpType,              ; +
-LDB6C:  and #$0F                        ;Load power up type byte and keep only bits 0 thru 3. +
-LDB6E:  ora #$50                        ;Set bits 4 and 6. +
-LDB70:  sta PowerUpAnimFrame            ;Save index to find object animation. +
-LDB73:  lda FrameCount                  ; +
-LDB75:  lsr                             ;Color affected every other frame. +
-LDB76:  and #$03                        ;the 2 LSBs of object control byte change palette of object. +
-LDB78:  ora #$80                        ;Indicate ObjectCntrl contains valid data by setting MSB. +
-LDB7A:  sta ObjectCntrl                 ;Change color of item every other frame. +
-LDB7C:  lda SpritePagePos               ;Load current index into sprite RAM. +
-LDB7E:  pha                             ;Temp save sprite RAM position. +
-LDB7F:  lda PowerUpAnimIndex,         ;Load entry into FramePtrTable for item animation. +
-LDB82:  jsr DrawFrame                   ;($DE4A)Display special item. +
- +
-LDB85:  pla                             ;Restore sprite page position byte. +
-LDB86:  cmp SpritePagePos               ;Was power up item successfully drawn?--> +
-LDB88:  beq Exit9                       ;If not, branch to exit. +
-LDB8A:  tax                             ;Store sprite page position in x. +
-LDB8B:  ldy ItemIndex                   ;Load index to proper power up data slot. +
-LDB8D:  lda PowerUpType,              ;Reload power up type data. +
-LDB90:  ldy #$01                        ;Set power up color for ice beam orb. +
-LDB92:  cmp #$07                        ;Is power up item the ice beam?--> +
-LDB94:  beq +                           ;If so, branch. +
- +
-LDB96:  dey                             ;Set power up color for long/wave beam orb. +
-LDB97:  cmp #$06                        ;Is power up item the wave beam?--> +
-LDB99:  beq +                           ;If so, branch. +
-LDB9B:  cmp #$02                        ;Is power up item the long beam?--> +
-LDB9D:  bne ++                          ;If not, branch. +
-LDB9F:* tya                             ;Transfer color data to A. +
-LDBA0:  sta Sprite01RAM+2,            ;Store power up color for beam weapon. +
-LDBA3:  lda #$FF                        ;Indicate power up obtained is a beam weapon. +
- +
-LDBA5:* pha                             ;Temporarily store power up type. +
-LDBA6:  ldx #$00                        ;Index to object 0(Samus). +
-LDBA8:  ldy #$40                        ;Index to object 1(power up). +
-LDBAA:  jsr AreObjectsTouching          ;($DC7F)Determine if Samus is touching power up. +
-LDBAD:  pla                             ;Restore power up type byte. +
-LDBAE:  bcs Exit9                       ;Carry clear=Samus touching power up. Carry set=not touching. +
- +
-LDBB0:  tay                             ;Store power-up type byte in Y. +
-LDBB1:  jsr PowerUpMusic                ;($CBF9)Power up obtained! Play power up music. +
-LDBB4:  ldx ItemIndex                   ;X=index to power up item slot. +
-LDBB6:  iny                             ;Is item obtained a beam weapon?--> +
-LDBB7:  beq +                           ;If so, branch. +
-LDBB9:  lda PowerUpNameTable,         ; +
-LDBBC:  sta $08                         ;Temp storage of nametable and power-up type in $08--> +
-LDBBE:  lda PowerUpType,              ;and $09 respectively. +
-LDBC1:  sta $09                         ; +
-LDBC3:  jsr GetItemXYPos                ;($DC1C)Get proper X and Y coords of item, save in history. +
-LDBC6:* lda PowerUpType,              ;Get power-up type byte again. +
-LDBC9:  tay                             ; +
-LDBCA:  cpy #$08                        ;Is power-up item a missile or energy tank?--> +
-LDBCC:  bcs ++++                        ;If so, branch. +
-LDBCE:  cpy #$06                        ;Is item the wave beam or ice beam?--> +
-LDBD0:  bcc +                           ;If not, branch. +
-LDBD2:  lda SamusGear                   ;Clear status of wave beam and ice beam power ups. +
-LDBD5:  and #$3F                        ; +
-LDBD7:  sta SamusGear                   ;Remove beam weapon data from Samus gear byte. +
-LDBDA:* jsr MakeBitMask                 ;($DB2F)Create a bit mask for beam weapon just obtained. +
-LDBDD:  ora SamusGear                   ; +
-LDBE0:  sta SamusGear                   ;Update Samus gear with new beam weapon. +
-LDBE3:* lda #$FF                        ; +
-LDBE5:  sta PowerUpDelay                ;Initiate delay while power up music plays. +
-LDBE8:  sta PowerUpType,              ;Clear out item data from RAM. +
-LDBEB:  ldy ItemRoomMusicStatus         ;Is Samus not in an item room?--> +
-LDBED:  beq +                           ;If not, branch. +
-LDBEF:  ldy #$01                        ;Restart item room music after special item music is done. +
-LDBF1:* sty ItemRoomMusicStatus         ; +
-LDBF3:  jmp SelectSamusPal              ;($CB73)Set Samus new palette. +
- +
-Exit9: +
-LDBF6:  rts                             ;Exit for multiple routines above. +
- +
-MissileEnergyPickup: +
-LDBF7:* beq +                           ;Branch if item is an energy tank. +
-LDBF9:  lda #$05                        ; +
-LDBFB:  jsr AddToMaxMissiles            ;($DD97)Increase missile capacity by 5. +
-LDBFE:  bne ---                         ;Branch always. +
- +
-LDC00:* lda TankCount                   ; +
-LDC03:  cmp #$06                        ;Has Samus got 6 energy tanks?--> +
-LDC05:  beq +                           ;If so, she can't have any more.--> +
-LDC07:  inc TankCount                   ;Otherwise give her a new tank. +
-LDC0A:* lda TankCount                   ; +
-LDC0D:  jsr Amul16                      ;Get tank count and shift into upper nibble. +
-LDC10:  ora #$09                        ; +
-LDC12:  sta HealthHi                    ;Set new tank count. Upper health digit set to 9. +
-LDC15:  lda #$99                        ;Max out low health digit. +
-LDC17:  sta HealthLo                    ;Health is now FULL! +
-LDC1A:  bne -----                       ;Branch always. +
- +
-;It is possible for the current nametable in the PPU to not be the actual nametable the special item +
-;is on so this function checks for the proper location of the special item so the item ID can be +
-;properly calculated. +
- +
-GetItemXYPos: +
-LDC1C:  lda MapPosX                     ; +
-LDC1E:  sta $07                         ;Temp storage of Samus map position x and y in $07--> +
-LDC20:  lda MapPosY                     ;and $06 respectively. +
-LDC22:  sta $06                         ; +
-LDC24:  lda ScrollDir                   ;Load scroll direction and shift LSB into carry bit. +
-LDC26:  lsr                             ; +
-LDC27:  php                             ;Temp storage of processor status. +
-LDC28:  beq +                           ;Branch if scrolling up/down. +
-LDC2A:  bcc ++                          ;Branch if scrolling right. +
- +
-;Scrolling left. +
-LDC2C:  lda ScrollX                     ;Unless the scroll x offset is 0, the actual room x pos--> +
-LDC2E:  beq ++                          ;needs to be decremented in order to be correct. +
-LDC30:  dec $07                         ; +
-LDC32:  bcs ++                          ;Branch always. +
- +
-LDC34:* bcc +                           ;Branch if scrolling up. +
- +
-;Scrolling down. +
-LDC36:  lda ScrollY                     ;Unless the scroll y offset is 0, the actual room y pos--> +
-LDC38:  beq +                           ;needs to be decremented in order to be correct. +
-LDC3A:  dec $06                         ; +
- +
-LDC3C:* lda PPUCNT0ZP                   ;If item is on the same nametable as current nametable,--> +
-LDC3E:  eor $08                         ;then no further adjustment to item x and y position needed. +
-LDC40:  and #$01                        ; +
-LDC42:  plp                             ;Restore the processor status and clear the carry bit. +
-LDC43:  clc                             ; +
-LDC44:  beq +                           ;If Scrolling up/down, branch to adjust item y position. +
- +
-LDC46:  adc $07                         ;Scrolling left/right. Make any necessary adjustments to--> +
-LDC48:  sta $07                         ;item x position before writing to unique item history. +
- +
-LDC4A:  jmp AddItemToHistory            ;($DC51)Add unique item to unique item history. +
- +
-LDC4D:* adc $06                         ;Scrolling up/down. Make any necessary adjustments to--> +
-LDC4F:  sta $06                         ;item y position before writing to unique item history. +
- +
-AddItemToHistory: +
-LDC51:  jsr CreateItemID                ;($DC67)Create an item ID to put into unique item history. +
-LDC54:  ldy NumberOfUniqueItems         ;Store number of uniqie items in Y. +
-LDC57:  lda $06                         ; +
-LDC59:  sta UniqueItemHistory,        ;Store item ID in inuque item history. +
-LDC5C:  lda $07                         ; +
-LDC5E:  sta UniqueItemHistory+1,      ; +
-LDC61:  iny                             ;Add 2 to Y. 2 bytes ber unique item. +
-LDC62:  iny                             ; +
-LDC63:  sty NumberOfUniqueItems         ;Store new number of unique items. +
-LDC66:  rts                             ; +
- +
-;------------------------------------------[ Create item ID ]----------------------------------------- +
- +
-;The following routine creates a unique two byte item ID number for that item.  The description +
-;of the format of the item ID number is as follows: +
-+
-;IIIIIIXX XXXYYYYY. I = item type, X = X coordinate on world map, Y = Y coordinate +
-;on world map.  The items have the following values of IIIIII: +
-;High jump     = 000001 +
-;Long beam     = 000010 (Not considered a unique item). +
-;Screw attack  = 000011 +
-;Maru Mari     = 000100 +
-;Varia suit    = 000101 +
-;Wave beam     = 000110 (Not considered a unique item). +
-;Ice beam      = 000111 (Not considered a unique item). +
-;Energy tank   = 001000 +
-;Missiles      = 001001 +
-;Missile door  = 001010 +
-;Bombs         = 001100 +
-;Mother brain  = 001110 +
-;1st Zeebetite = 001111 +
-;2nd Zeebetite = 010000 +
-;3rd Zeebetite = 010001 +
-;4th Zeebetite = 010010 +
-;5th Zeebetite = 010011 +
-+
-;The results are stored in $06(upper byte) and $07(lower byte). +
- +
-CreateItemID: +
-LDC67:  lda $07                         ;Load x map position of item. +
-LDC69:  jsr Amul32                      ;($C2C$)*32. Move lower 3 bytes to upper 3 bytes. +
-LDC6C:  ora $06                         ;combine Y coordinates into data byte. +
-LDC6E:  sta $06                         ;Lower data byte complete. Save in $06. +
-LDC70:  lsr $07                         ; +
-LDC72:  lsr $07                         ;Move upper two bits of X coordinate to LSBs. +
-LDC74:  lsr $07                         ; +
-LDC76:  lda $09                         ;Load item type bits. +
-LDC78:  asl                             ;Move the 6 bits of item type to upper 6 bits of byte. +
-LDC79:  asl                             ; +
-LDC7A:  ora $07                         ;Add upper two bits of X coordinate to byte. +
-LDC7C:  sta $07                         ;Upper data byte complete. Save in #$06. +
-LDC7E:  rts                             ; +
- +
-;----------------------------------------------------------------------------------------------------- +
- +
-AreObjectsTouching: +
-LDC7F:  jsr LF186 +
-LDC82:  jsr LF172 +
-LDC85:  jsr LF1A7 +
-LDC88:  jmp LF1FA +
- +
-;The following table is used to rotate the sprites of both Samus and enemies when they explode. +
- +
-ExplodeRotationTbl: +
-LDC8B:  .byte $00                       ;No sprite flipping. +
-LDC8C:  .byte $80                       ;Flip sprite vertically. +
-LDC8D:  .byte $C0                       ;Flip sprite vertically and horizontally. +
-LDC8E:  .byte $40                       ;Flip sprite horizontally. +
- +
-; UpdateObjAnim +
-; ============= +
-; Advance to object's next frame of animation +
- +
-UpdateObjAnim: +
-LDC8F:  ldx PageIndex +
-        ldy AnimDelay,+
-        beq +      ; is it time to advance to the next anim frame? +
-        dec AnimDelay,    ; nope +
-        bne +++   ; exit if still not zero (don't update animation) +
-*       sta AnimDelay,    ; set initial anim countdown value +
-        ldy AnimIndex,+
-*       lda ObjectAnimIndexTbl,               ;($8572)Load frame number. +
-        cmp #$FF        ; has end of anim been reached? +
-        beq ++ +
-        sta AnimFrame,    ; store frame number +
-        iny          ; inc anim index +
-        tya +
-        sta AnimIndex,    ; store anim index +
-*       rts +
- +
-*       ldy AnimResetIndex,    ; reset anim frame index +
-        jmp ---    ; do first frame of animation +
- +
-LDCB7:  pha +
-        lda #$00 +
-        sta $06 +
-        pla +
-        bpl + +
-        dec $06 +
-*       clc +
-        rts +
- +
-;--------------------------------[ Get sprite control byte ]----------------------------------------- +
- +
-;The sprite control byte extracted from the frame data has the following format: AABBXXXX. +
-;Where AA are the two bits used to control the horizontal and verticle mirroring of the +
-;sprite and BB are the two bits used control the sprite colors. XXXX is the entry number +
-;in the PlacePtrTbl used to place the sprite on the screen. +
- +
-GetSpriteCntrlData: +
-LDCC3:  ldy #$00                        ; +
-LDCC5:  sty $0F                         ;Clear index into placement data. +
-LDCC7:  lda ($00),                    ;Load control byte from frame pointer data. +
-LDCC9:  sta $04                         ;Store value in $04 for processing below. +
-LDCCB:  tax                             ;Keep a copy of the value in x as well. +
-LDCCC:  jsr Adiv16                      ;($C2BF)Move upper 4 bits to lower 4 bits. +
-LDCCF:  and #$03                        ; +
-LDCD1:  sta $05                         ;The following lines take the upper 4 bits in the--> +
-LDCD3:  txa                             ;control byte and transfer bits 4 and 5 into $05 bits 0--> +
-LDCD4:  and #$C0                        ;and 1(sprite color bits).  Bits 6 and 7 are--> +
-LDCD6:  ora #$20                        ;transferred into $05 bits 6 and 7(sprite flip bits).--> +
-LDCD8:  ora $05                         ;bit 5 is then set(sprite always drawn behind background). +
-LDCDA:  sta $05                         ; +
-LDCDC:  lda ObjectCntrl                 ;Extract bit from control byte that controls the +
-LDCDE:  and #$10                        ;object mirroring. +
-LDCE0:  asl                             ; +
-LDCE1:  asl                             ; +
-LDCE2:  eor $04                         ;Move it to the bit 6 position and use it to flip the--> +
-LDCE4:  sta $04                         ;horizontal mirroring of the sprite if set. +
-LDCE6:  lda ObjectCntrl                 ; +
-LDCE8:  bpl +                           ;If MSB is set in ObjectCntrl, use its flip bits(6 and 7). +
-LDCEA:  asl ObjectCntrl                 ; +
-LDCEC:  jsr SpriteFlipBitsOveride       ;($E038)Use object flip bits as priority over sprite flip bits.  +
-LDCEF:* txa                             ;Discard upper nibble so only entry number into--> +
-LDCF0:  and #$0F                        ;PlacePtrTbl remains. +
-LDCF2:  asl                             ;*2. pointers in PlacePntrTbl are 2 bytes in size. +
-LDCF3:  tax                             ;Transfer to X to use as an index to find proper--> +
-LDCF4:  rts                             ;placement data segment. +
- +
-;----------------------------------------------------------------------------------------------------- +
- +
-LDCF5:  jsr ClearObjectCntrl            ;($DF2D)Clear object control byte. +
-        pla +
-        pla +
-        ldx PageIndex +
-LDCFC:  lda InArea +
-        cmp #$13 +
-        bne + +
-        lda EnDataIndex,+
-        cmp #$04 +
-        beq +++++ +
-        cmp #$02 +
-        beq +++++ +
-*       lda $040C,x +
-        asl +
-        bmi LDD75 +
-        jsr LF74B +
-        sta $00 +
-        jsr $80B0 +
-        and #$20 +
-        sta EnDataIndex,+
-        lda #$05 +
-        sta EnStatus,+
-        lda #$60 +
-        sta $040D,x +
-        lda RandomNumber1 +
-        cmp #$10 +
-        bcc LDD5B +
-*       and #$07 +
-        tay +
-        lda ItemDropTbl,+
-        sta EnAnimFrame,+
-        cmp #$80 +
-        bne ++ +
-        ldy MaxMissilePickup +
-        cpy CurrentMissilePickups +
-        beq LDD5B +
-        lda MaxMissiles +
-        beq LDD5B +
-        inc CurrentMissilePickups +
-*       rts +
- +
-*       ldy MaxEnergyPickup +
-        cpy CurrentEnergyPickups +
-        beq LDD5B +
-        inc CurrentEnergyPickups +
-        cmp #$89 +
-        bne -- +
-        lsr $00 +
-        bcs -- +
- +
-LDD5B:  ldx PageIndex +
-        lda InArea +
-        cmp #$13 +
-        beq ++ +
-*       jmp KillObject                  ;($FA18)Free enemy data slot. +
- +
-*       lda RandomNumber1 +
-        ldy #$00 +
-        sty CurrentEnergyPickups +
-        sty CurrentMissilePickups +
-        iny +
-        sty MaxMissilePickup +
-        sty MaxEnergyPickup +
-        bne ----- +
- +
-LDD75:  jsr PowerUpMusic +
-        lda InArea +
-        and #$0F +
-        sta MiniBossKillDelay +
-        lsr +
-        tay +
-        sta MaxMissiles,+
-        lda #75 +
-        jsr AddToMaxMissiles +
-        bne LDD5B +
- +
-LDD8B:  ldx PageIndex +
-        lda EnAnimFrame,+
-        cmp #$F7 +
-        bne +++ +
-        jmp ClearObjectCntrl            ;($DF2D)Clear object control byte. +
- +
-; AddToMaxMissiles +
-; ================ +
-; Adds A to both MissileCount & MaxMissiles, storing the new count +
-; (255 if it overflows) +
- +
-AddToMaxMissiles: +
-        pha                             ;Temp storage of # of missiles to add. +
-        clc +
-        adc MissileCount +
-        bcc + +
-        lda #$FF +
-*       sta MissileCount +
-        pla +
-        clc +
-        adc MaxMissiles +
-        bcc + +
-        lda #$FF +
-*       sta MaxMissiles +
-        rts +
- +
-*       lda EnYRoomPos,+
-        sta $0A  ; Y coord +
-        lda EnXRoomPos,+
-        sta $0B  ; X coord +
-        lda EnNameTable,+
-        sta $06  ; hi coord +
-        lda EnAnimFrame,+
-        asl +
-        tay +
-        lda ($41),y +
-        bcc + +
-        lda ($43),y +
-*       sta $00 +
-        iny +
-        lda ($41),y +
-        bcc + +
-        lda ($43),y +
-*       sta $01 +
-        jsr GetSpriteCntrlData          ;($DCC3)Get place pointer index and sprite control data. +
-        tay +
-        lda ($45),y +
-        sta $02 +
-        iny +
-        lda ($45),y +
-        sta $03 +
-        ldy #$00 +
-        cpx #$02 +
-        bne + +
-        ldx PageIndex +
-        inc EnCounter,+
-        lda EnCounter,+
-        pha +
-        and #$03 +
-        tax +
-        lda $05 +
-        and #$3F +
-        ora ExplodeRotationTbl,+
-        sta $05 +
-        pla +
-        cmp #$19 +
-        bne + +
-        jmp LDCF5 +
- +
-*       ldx PageIndex +
-        iny +
-        lda ($00),y +
-        sta EnRadY,x +
-        jsr ReduceYRadius               ;($DE3D)Reduce temp y radius by #$10. +
-        iny +
-        lda ($00),y +
-        sta EnRadX,x +
-        sta $09 +
-        iny +
-        sty $11 +
-        jsr IsObjectVisible             ;($DFDF)Determine if object is within screen boundaries. +
-        txa +
-        asl +
-        sta $08 +
-        ldx PageIndex +
-        lda $0405,x +
-        and #$FD +
-        ora $08 +
-        sta $0405,x +
-        lda $08 +
-        beq ++ +
-        jmp LDEDE +
- +
-;----------------------------------------[ Item drop table ]----------------------------------------- +
- +
-;The following table determines what, if any, items an enemy will drop when it is killed. +
- +
-ItemDropTbl: +
-LDE35:  .byte $80                       ;Missile. +
-LDE36:  .byte $81                       ;Energy. +
-LDE37:  .byte $89                       ;No item. +
-LDE38:  .byte $80                       ;Missile. +
-LDE39:  .byte $81                       ;Energy. +
-LDE3A:  .byte $89                       ;No item. +
-LDE3B:  .byte $81                       ;Energy. +
-LDE3C:  .byte $89                       ;No item. +
- +
-;------------------------------------[ Object drawing routines ]------------------------------------- +
- +
-;The following function effectively sets an object's temporary y radius to #$00 if the object +
-;is 4 tiles tall or less.  If it is taller, #$10 is subtracted from the temporary y radius. +
- +
-ReduceYRadius: +
-LDE3D:  sec                             ; +
-LDE3E:  sbc #$10                        ;Subtract #$10 from object y radius. +
-LDE40:  bcs +                           ;If number is still a positive number, branch to store value. +
-LDE42:  lda #$00                        ;Number is negative.  Set Y radius to #$00. +
-LDE44:* sta $08                         ;Store result and return. +
-LDE46:  rts                             ; +
- +
-AnimDrawObject: +
-LDE47:  jsr UpdateObjAnim               ;($DC8F)Update animation if needed. +
- +
-DrawFrame: +
-LDE4A:  ldx PageIndex                   ;Get index to proper object to work with. +
-LDE4C:  lda AnimFrame,                ; +
-LDE4F:  cmp #$F7                        ;Is the frame valid?--> +
-LDE51:  bne ++                          ;Branch if yes. +
-LDE53:* jmp ClearObjectCntrl            ;($DF2D)Clear object control byte. +
-LDE56:* cmp #$07                        ;Is the animation of Samus facing forward?--> +
-LDE58:  bne +                           ;If not, branch. +
- +
-LDE5A:  lda ObjectCntrl                 ;Ensure object mirroring bit is clear so Samus'--> +
-LDE5C:  and #$EF                        ;sprite appears properly when going up and down--> +
-LDE5E:  sta ObjectCntrl                 ;elevators. +
- +
-LDE60:* lda ObjectY,                  ; +
-LDE63:  sta $0A                         ; +
-LDE65:  lda ObjectX,                  ;Copy object y and x room position and name table--> +
-LDE68:  sta $0B                         ;data into $0A, $0B and $06 respectively. +
-LDE6A:  lda ObjectHi,                 ; +
-LDE6D:  sta $06                         ; +
-LDE6F:  lda AnimFrame,                ;Load A with index into FramePtrTable. +
-LDE72:  asl                             ;*2. Frame pointers are two bytes. +
-LDE73:  tax                             ;X is now the index into the FramePtrTable. +
-LDE74:  lda FramePtrTable,            ; +
-LDE77:  sta $00                         ; +
-LDE79:  lda FramePtrTable+1,          ;Entry from FramePtrTable is stored in $0000. +
-LDE7C:  sta $01                         ; +
-LDE7E:  jsr GetSpriteCntrlData          ;($DCC3)Get place pointer index and sprite control data. +
-LDE81:  lda PlacePtrTable,            ; +
-LDE84:  sta $02                         ; +
-LDE86:  lda PlacePtrTable+1,          ;Store pointer from PlacePtrTbl in $0002. +
-LDE89:  sta $03                         ; +
-LDE8B:  lda IsSamus                     ;Is Samus the object being drawn?--> +
-LDE8D:  beq +                           ;If not, branch. +
- +
-;Special case for Samus exploding. +
-LDE8F:  cpx #$0E                        ;Is Samus exploding?--> +
-LDE91:  bne +                           ;If not, branch to skip this section of code. +
-LDE93:  ldx PageIndex                   ;X=0. +
-LDE95:  inc ObjectCounter               ;Incremented every frame during explode sequence.--> +
-LDE97:  lda ObjectCounter               ;Bottom two bits used for index into ExplodeRotationTbl. +
-LDE99:  pha                             ;Save value of A. +
-LDE9A:  and #$03                        ;Use 2 LSBs for index into ExplodeRotationTbl. +
-LDE9C:  tax                             ; +
-LDE9D:  lda $05                         ;Drop mirror control bits from sprite control byte. +
-LDE9F:  and #$3F                        ; +
-LDEA1:  ora ExplodeRotationTbl,       ;Use mirror control bytes from table(Base is $DC8B). +
-LDEA4:  sta $05                         ;Save modified sprite control byte. +
-LDEA6:  pla                             ;Restore A +
-LDEA7:  cmp #$19                        ;After 25 frames, Move on to second part of death-->  +
-LDEA9:  bne +                           ;handler, else branch to skip the rest of this code. +
-LDEAB:  ldx PageIndex                   ;X=0. +
-LDEAD:  lda #sa_Dead2                   ; +
-LDEAF:  sta ObjAction,                ;Move to next part of the death handler. +
-LDEB2:  lda #$28                        ; +
-LDEB4:  sta AnimDelay,                ;Set animation delay for 40 frames(.667 seconds). +
-LDEB7:  pla                             ;Pull last return address off of the stack. +
-LDEB8:  pla                             ; +
-LDEB9:  jmp ClearObjectCntrl            ;($DF2D)Clear object control byte. +
- +
-LDEBC:* ldx PageIndex                   ; +
-LDEBE:  iny                             ;Increment to second frame data byte. +
-LDEBF:  lda ($00),                    ; +
-LDEC1:  sta ObjRadY,                  ;Get verticle radius in pixles of object. +
-LDEC3:  jsr ReduceYRadius               ;($DE3D)Reduce temp y radius by #$10. +
-LDEC6:  iny                             ;Increment to third frame data byte. +
-LDEC7:  lda ($00),                    ;Get horizontal radius in pixels of object. +
-LDEC9:  sta ObjRadX,                  ; +
-LDECB:  sta $09                         ;Temp storage for object x radius. +
-LDECD:  iny                             ;Set index to 4th byte of frame data. +
-LDECE:  sty $11                         ;Store current index into frame data. +
-LDED0:  jsr IsObjectVisible             ;($DFDF)Determine if object is within the screen boundaries. +
-LDED3:  txa                             ; +
-LDED4:  ldx PageIndex                   ;Get index to object. +
-LDED6:  sta ObjectOnScreen,           ;Store visibility status of object. +
-LDEDB:  tax                             ; +
-LDEDC:  beq +                           ;Branch if object is not within the screen boundaries. +
-LDEDE:  ldx SpritePagePos               ;Load index into next unused sprite RAM segment. +
-LDEE0:  jmp DrawSpriteObject            ;($DF19)Start drawing object. +
- +
-LDEE3:* jmp ClearObjectCntrl            ;($DF2D)Clear object control byte then exit. +
- +
-WriteSpriteRAM: +
-LDEE6:* ldy $0F                         ;Load index for placement data. +
-LDEE8:  jsr YDisplacement               ;($DF6B)Get displacement for y direction. +
-LDEEB:  adc $10                         ;Add initial Y position. +
-LDEED:  sta Sprite00RAM,              ;Store sprite Y coord. +
-LDEF0:  dec Sprite00RAM,              ;Because PPU uses Y + 1 as real Y coord. +
-LDEF3:  inc $0F                         ;Increment index to next byte of placement data. +
-LDEF5:  ldy $11                         ;Get index to frame data. +
-LDEF7:  lda ($00),                    ;Tile value. +
-LDEF9:  sta Sprite00RAM+1,            ;Store tile value in sprite RAM. +
-LDEFC:  lda ObjectCntrl                 ; +
-LDEFE:  asl                             ;Move horizontal mirror control byte to bit 6 and--> +
-LDEFF:  asl                             ;discard all other bits. +
-LDF00:  and #$40                        ; +
-LDF02:  eor $05                         ;Use it to override sprite horz mirror bit. +
-LDF04:  sta Sprite00RAM+2,            ;Store sprite control byte in sprite RAM. +
-LDF07:  inc $11                         ;Increment to next byte of frame data. +
-LDF09:  ldy $0F                         ;Load index for placement data. +
-LDF0B:  jsr XDisplacement               ;($DFA3)Get displacement for x direction. +
-LDF0E:  adc $0E                         ;Add initial X pos +
-LDF10:  sta Sprite00RAM+3,            ;Store sprite X coord +
-LDF13:  inc $0F                         ;Increment to next placement data byte. +
-LDF15:  inx                             ; +
-LDF16:  inx                             ; +
-LDF17:  inx                             ;Advance to next sprite. +
-LDF18:  inx                             ; +
- +
-DrawSpriteObject: +
-LDF19:  ldy $11                         ;Get index into frame data. +
- +
-GetNextFrameByte: +
-LDF1B:  lda ($00),                    ;Get next frame data byte. +
-LDF1D:  cmp #$FC                        ;If byte < #$FC, byte is tile data. If >= #$FC, byte is-->  +
-LDF1F:  bcc WriteSpriteRAM              ;frame data control info. Branch to draw sprite. +
-LDF21:  beq OffsetObjectPosition        ;#$FC changes object's x and y position. +
-LDF23:  cmp #$FD                        ; +
-LDF25:  beq GetNewControlByte           ;#$FD sets new control byte information for the next sprites. +
-LDF27:  cmp #$FE                        ;#$FE skips next sprite placement x and y bytes. +
-LDF29:  beq SkipPlacementData           ; +
-LDF2B:  stx SpritePagePos               ;Keep track of current position in sprite RAM. +
- +
-ClearObjectCntrl: +
-LDF2D:  lda #$00                        ; +
-LDF2F:  sta ObjectCntrl                 ;Clear object control byte. +
-LDF31:  rts                             ; +
- +
-SkipPlacementData: +
-LDF32:* inc $0F                         ;Skip next y and x placement data bytes. +
-LDF34:  inc $0F                         ; +
-LDF36:  inc $11                         ;Increment to next data item in frame data. +
-LDF38:  jmp DrawSpriteObject            ;($DF19)Draw next sprite. +
- +
-GetNewControlByte: +
-LDF3B:* iny                             ;Increment index to next byte of frame data. +
-LDF3C:  asl ObjectCntrl                 ;If MSB of ObjectCntrl is not set, no overriding of--> +
-LDF3E:  bcc +                           ;flip bits needs to be performed. +
-LDF40:  jsr SpriteFlipBitsOveride       ;($E038)Use object flip bits as priority over sprite flip bits. +
-LDF43:  bne ++                          ;Branch always. +
-LDF45:* lsr ObjectCntrl                 ;Restore MSB of ObjectCntrl. +
-LDF47:  lda ($00),                    ; +
-LDF49:  sta $05                         ;Save new sprite control byte. +
-LDF4B:* iny                             ;Increment past sprite control byte. +
-LDF4C:  sty $11                         ;Save index of frame data. +
-LDF4E:  jmp GetNextFrameByte            ;($DF1B)Load next frame data byte. +
- +
-OffsetObjectPosition: +
-LDF51:* iny                             ;Increment index to next byte of frame data. +
-LDF52:  lda ($00),                    ;This data byte is used to offset the object from--> +
-LDF54:  clc                             ;its current y positon. +
-LDF55:  adc $10                         ; +
-LDF57:  sta $10                         ;Add offset amount to object y screen position. +
-LDF59:  inc $11                         ; +
-LDF5B:  inc $11                         ;Increment past control byte and y offset byte. +
-LDF5D:  ldy $11                         ; +
-LDF5F:  lda ($00),                    ;Load x offset data byte. +
-LDF61:  clc                             ; +
-LDF62:  adc $0E                         ;Add offset amount to object x screen position. +
-LDF64:  sta $0E                         ; +
-LDF66:  inc $11                         ;Increment past x offset byte. +
-LDF68:  jmp DrawSpriteObject            ;($DF19)Draw next sprite. +
- +
-;----------------------------------[ Sprite placement routines ]------------------------------------- +
- +
-YDisplacement: +
-LDF6B:  lda ($02),                    ;Load placement data byte. +
-LDF6D:  tay                             ; +
-LDF6E:  and #$F0                        ;Check to see if this is placement data for the object--> +
-LDF70:  cmp #$80                        ;exploding.  If so, branch. +
-LDF72:  beq ++                          ; +
-LDF74:  tya                             ;Restore placement data byte to A. +
-LDF75:* bit $04                         ; +
-LDF77:  bmi NegativeDisplacement        ;Branch if MSB in $04 is set(Flips object). +
-LDF79:  clc                             ;Clear carry before returning. +
-LDF7A:  rts                             ; +
- +
-ExplodeYDisplace: +
-LDF7B:* tya                             ;Transfer placement byte back into A. +
-LDF7C:  and #$0E                        ;Discard bits 7,6,5,4 and 0. +
-LDF7E:  lsr                             ;/2. +
-LDF7F:  tay                             ; +
-LDF80:  lda ExplodeIndexTbl,          ;Index into ExplodePlacementTbl. +
-LDF83:  ldy IsSamus                     ; +
-LDF85:  bne +                           ;Is Samus the object exploding? if so, branch. +
-LDF87:  ldy PageIndex                   ;Load index to proper enemy data. +
-LDF89:  adc EnCounter,                ;Increment every frame enemy is exploding. Initial=#$01. +
-LDF8C:  jmp ++                          ;Jump to load explode placement data. +
- +
- +
-;Special case for Samus exploding. +
-LDF8F:* adc ObjectCounter               ;Increments every frame Samus is exploding. Initial=#$01. +
-LDF91:* tay                             ; +
-LDF92:  lda ExplodeIndexTbl+2,        ;Get data from ExplodePlacementTbl. +
-LDF95:  pha                             ;Save data on stack. +
-LDF96:  lda $0F                         ;Load placement data index. +
-LDF98:  clc                             ; +
-LDF99:  adc #$0C                        ;Move index forward by 12 bytes. to find y--> +
-LDF9B:  tay                             ;placement data. +
-LDF9C:  pla                             ;Restore A with ExplodePlacementTbl data. +
-LDF9D:  clc                             ; +
-LDF9E:  adc ($02),                    ;Add table displacements with sprite placement data. +
-LDFA0:  jmp ----                        ;Branch to add y placement values to sprite coords. +
- +
-XDisplacement: +
-LDFA3:  lda ($02),                    ;Load placement data byte. +
-LDFA5:  tay                             ; +
-LDFA6:  and #$F0                        ;Check to see if this is placement data for the object--> +
-LDFA8:  cmp #$80                        ;exploding.  If so, branch. +
-LDFAA:  beq +++                         ; +
-LDFAC:  tya                             ;Restore placement data byte to A. +
-LDFAD:* bit $04                         ; +
-LDFAF:  bvc +                           ;Branch if bit 6 cleared, else data is negative displacement. +
- +
-NegativeDisplacement: +
-LDFB1:  eor #$FF                        ; +
-LDFB3:  sec                             ;NOTE:Setting carry makes solution 1 higher than expected. +
-LDFB4:  adc #$F8                        ;If flip bit is set in $04, this function flips the--> +
-LDFB6:* clc                             ;object by using two compliment minus 8(Each sprite is--> +
-LDFB7:  rts                             ;8x8 pixels). +
- +
-ExplodeXDisplace: +
-LDFB8:* ldy PageIndex                   ;Load index to proper enemy slot. +
-LDFBA:  lda EnCounter,                ;Load counter value. +
-LDFBD:  ldy IsSamus                     ;Is Samus the one exploding?--> +
-LDFBF:  beq +                           ;If not, branch. +
-LDFC1:  lda ObjectCounter               ;Load object counter if it is Samus who is exploding. +
-LDFC3:* asl                             ;*2. Move sprite in x direction 2 pixels every frame. +
-LDFC4:  pha                             ;Store value on stack. +
-LDFC5:  ldy $0F                         ; +
-LDFC7:  lda ($02),                    ;Load placement data byte. +
-LDFC9:  lsr                             ; +
-LDFCA:  bcs +                           ;Check if LSB is set. If not, the byte stored on stack--> +
-LDFCC:  pla                             ;Will be twos complimented and used to move sprite in--> +
-LDFCD:  eor #$FF                        ;the negative x direction. +
-LDFCF:  adc #$01                        ; +
-LDFD1:  pha                             ; +
-LDFD2:* lda $0F                         ;Load placement data index. +
-LDFD4:  clc                             ; +
-LDFD5:  adc #$0C                        ;Move index forward by 12 bytes. to find x--> +
-LDFD7:  tay                             ;placement data. +
-LDFD8:  pla                             ;Restore A with x displacement data. +
-LDFD9:  clc                             ; +
-LDFDA:  adc ($02),                    ;Add x displacement with sprite placement data. +
-LDFDC:  jmp -----                       ;Branch to add x placement values to sprite coords. +
- +
-;---------------------------------[ Check if object is on screen ]---------------------------------- +
- +
-;The following set of functions determine if an object is visible on the screen.  If the object +
-;is visible, X-1 when the function returns, X=0 if the object is not within the boundaries of the +
-;current screen.  The function needs to know what nametable is currently in the PPU, what nametable +
-;the object is on and what the scroll offsets are.  +
- +
-IsObjectVisible: +
-LDFDF:  ldx #$01                        ;Assume object is visible on screen. +
-LDFE1:  lda $0A                         ;Object Y position in room. +
-LDFE3:  tay                             ; +
-LDFE4:  sec                             ;Subtract y scroll to find sprite's y position on screen. +
-LDFE5:  sbc ScrollY                     ; +
-LDFE7:  sta $10                         ;Store result in $10. +
-LDFE9:  lda $0B                         ;Object X position in room. +
-LDFEB:  sec                             ; +
-LDFEC:  sbc ScrollX                     ;Subtract x scroll to find sprite's x position on screen. +
-LDFEE:  sta $0E                         ;Store result in $0E. +
-LDFF0:  lda ScrollDir                   ; +
-LDFF2:  and #$02                        ;Is Samus scrolling left or right?--> +
-LDFF4:  bne HorzScrollCheck             ;($E01C)If so, branch. +
- +
-VertScrollCheck: +
-LDFF6:  cpy ScrollY                     ;If object room pos is >= scrollY, set carry. +
-LDFF8:  lda $06                         ;Check if object is on different name table as current--> +
-LDFFA:  eor PPUCNT0ZP                   ;name table active in PPU.--> +
-LDFFC:  and #$01                        ;If not, branch. +
-LDFFE:  beq +                           ; +
-LE000:  bcs ++                          ;If carry is still set, sprite is not in screen boundaries. +
-LE002:  lda $10                         ; +
-LE004:  sbc #$0F                        ;Move sprite y position up 15 pixles. +
-LE006:  sta $10                         ; +
-LE008:  lda $09                         ; +
-LE00A:  clc                             ;If a portion of the object is outside the sceen--> +
-LE00B:  adc $10                         ;boundaries, treat object as if the whole thing is--> +
-LE00D:  cmp #$F0                        ;not visible. +
-LE00F:  bcc +++                         ; +
-LE011:  clc                             ;Causes next statement to branch always. +
-LE012:* bcc +                           ; +
-LE014:  lda $09                         ;If object is on same name table as the current one in--> +
-LE016:  cmp $10                         ;the PPU, check if part of object is out of screen-->  +
-LE018:  bcc ++                          ;boundaries.  If so, branch. +
-LE01A:* dex                             ;Sprite is not within screen boundaries. Decrement X. +
-LE01B:* rts                             ; +
- +
-HorzScrollCheck: +
-LE01C:  lda $06                         ; +
-LE01E:  eor PPUCNT0ZP                   ;Check if object is on different name table as current--> +
-LE020:  and #$01                        ;name table active in PPU.--> +
-LE022:  beq +                           ;If not, branch. +
-LE024:  bcs ++                          ;If carry is still set, sprite is not in screen boundaries. +
-LE026:  lda $09                         ; +
-LE028:  clc                             ;If a portion of the object is outside the sceen--> +
-LE029:  adc $0E                         ;boundaries, treat object as if the whole thing is--> +
-LE02B:  bcc +++                         ;not visible. +
-LE02D:  clc                             ;Causes next statement to branch always. +
-LE02E:* bcc +                           ; +
-LE030:  lda $09                         ;If object is on same name table as the current one in--> +
-LE032:  cmp $0E                         ;the PPU, check if part of object is out of screen-->  +
-LE034:  bcc ++                          ;boundaries.  If so, branch. +
-LE036:* dex                             ;Sprite is not within screen boundaries. Decrement X. +
-LE037:* rts                             ; +
- +
-;------------------------[ Override sprite flip bits with object flip bits ]------------------------- +
- +
-;If the MSB is set in ObjectCntrl, its two upper bits that control sprite flipping take priority +
-;over the sprite control bits.  This function modifies the sprite control byte with any flipping +
-;bits found in ObjectCntrl. +
- +
-SpriteFlipBitsOveride: +
-LE038:  lsr ObjectCntrl                 ;Restore MSB. +
-LE03A:  lda ($00),                    ;Reload frame data control byte into A. +
-LE03C:  and #$C0                        ;Extract the two sprite flip bytes from theoriginal--> +
-LE03E:  ora ObjectCntrl                 ;control byte and set any additional bits from ObjectCntrl. +
-LE040:  sta $05                         ;Store modified byte to load in sprite control byte later. +
-LE042:  lda ObjectCntrl                 ; +
-LE044:  ora #$80                        ; +
-LE046:  sta ObjectCntrl                 ;Ensure MSB of object control byte remains set. +
-LE048:  rts                             ; +
- +
-;--------------------------------[ Explosion placement data ]--------------------------------------- +
- +
-;The following table has the index values into the table after it for finding the placement data +
-;for an exploding object. +
- +
-ExplodeIndexTbl: +
-LE049:  .byte $00, $18, $30 +
- +
-;The following table is used to produce the arcing motion of exploding objects.  It is displacement +
-;data for the y directions only.  The x displacement is constant. +
- +
-ExplodePlacementTbl: +
- +
-;Bottom sprites. +
-LE04C:  .byte $FC, $F8, $F4, $F0, $EE, $EC, $EA, $E8, $E7, $E6, $E6, $E5, $E5, $E4, $E4, $E3 +
-LE05C:  .byte $E5, $E7, $E9, $EB, $EF, $F3, $F7, $FB +
- +
-;Middle sprites. +
-LE064:  .byte $FE, $FC, $FA, $F8, $F6, $F4, $F2, $F0, $EE, $ED, $EB, $EA, $E9, $E8, $E7, $E6 +
-LE074:  .byte $E6, $E6, $E6, $E6, $E8, $EA, $EC, $EE +
- +
-;Top sprites. +
-LE07C:  .byte $FE, $FC, $FA, $F8, $F7, $F6, $F5, $F4, $F3, $F2, $F1, $F1, $F0, $F0, $EF, $EF +
-LE08C:  .byte $EF, $EF, $EF, $EF, $F0, $F0, $F1, $F2 +
- +
-;--------------------------------------[ Update enemy animation ]----------------------------------- +
- +
-;Advance to next frame of enemy's animation. Basically the same as UpdateObjAnim, only for enemies. +
- +
-UpdateEnemyAnim: +
-LE094:  ldx PageIndex                   ;Load index to desired enemy. +
-LE096:  ldy EnStatus,                 ; +
-LE099:  cpy #$05                        ;Is enemy in the process of dying?--> +
-LE09B:  beq +++                         ;If so, branch to exit. +
-LE09D:  ldy EnAnimDelay,              ; +
-LE0A0:  beq +                           ;Check if current anumation frame is ready to be updated. +
-LE0A2:  dec EnAnimDelay,              ;Not ready to update. decrement delay timer and--> +
-LE0A5:  bne +++                         ;branch to exit. +
-LE0A7:* sta EnAnimDelay,              ;Save new animation delay value. +
-LE0AA:  ldy EnAnimIndex,              ;Load enemy animation index. +
-LE0AD:* lda (EnemyAnimPtr),           ;Get animation data. +
-LE0AF:  cmp #$FF                        ;End of animation? +
-LE0B1:  beq ++                          ;If so, branch to reset animation. +
-LE0B3:  sta EnAnimFrame,              ;Store current animation frame data. +
-LE0B6:  iny                             ;Increment to next animation data index. +
-LE0B7:  tya                             ; +
-LE0B8:  sta EnAnimIndex,              ;Save new animation index. +
-LE0BB:* rts                             ; +
- +
-LE0BC:* ldy EnResetAnimIndex,         ;reset animation index. +
-LE0BF:  bcs ---                         ;Branch always. +
- +
-;---------------------------------------[ Display status bar ]--------------------------------------- +
- +
-;Displays Samus' status bar components. +
- +
-DisplayBar: +
-LE0C1:  ldy #$00                        ;Reset data index. +
-LE0C3:  lda SpritePagePos               ;Load current sprite index. +
-LE0C5:  pha                             ;save sprite page pos. +
-LE0C6:  tax                             ; +
-LE0C7:* lda DataDisplayTbl,           ; +
-LE0CA:  sta Sprite00RAM,              ;Stor contents of DataDisplayTbl in sprite RAM. +
-LE0CD:  inx                             ; +
-LE0CE:  iny                             ; +
-LE0CF:  cpy #$28                        ;10*4. At end of DataDisplayTbl? If not, loop to--> +
-LE0D1:  bne -                           ;load next byte from table. +
- +
-;Display 2-digit health count. +
-LE0D3:  stx SpritePagePos               ;Save new location in sprite RAM. +
-LE0D5:  pla                             ;Restore initial sprite page pos. +
-LE0D6:  tax                             ; +
-LE0D7:  lda HealthHi                    ; +
-LE0DA:  and #$0F                        ;Extract upper health digit. +
-LE0DC:  jsr SPRWriteDigit               ;($E173)Display digit on screen. +
-LE0DF:  lda HealthLo                    ; +
-LE0E2:  jsr Adiv16                      ;($C2BF)Move lower health digit to 4 LSBs. +
-LE0E5:  jsr SPRWriteDigit               ;($E173)Display digit on screen. +
-LE0E8:  ldy EndTimerHi                  ; +
-LE0EB:  iny                             ;Is Samus in escape sequence?--> +
-LE0EC:  bne ++                          ;If so, branch. +
-LE0EE:  ldy MaxMissiles                 ; +
-LE0F1:  beq +                           ;Don't show missile count if Samus has no missile containers. +
- +
-;Display 3-digit missile count. +
-LE0F3:  lda MissileCount                ; +
-LE0F6:  jsr HexToDec                    ;($E198)Convert missile hex count to decimal cout. +
-LE0F9:  lda $02                         ;Upper digit. +
-LE0FB:  jsr SPRWriteDigit               ;($E173)Display digit on screen. +
-LE0FE:  lda $01                         ;Middle digit. +
-LE100:  jsr SPRWriteDigit               ;($E173)Display digit on screen. +
-LE103:  lda $00                         ;Lower digit. +
-LE105:  jsr SPRWriteDigit               ;($E173)Display digit on screen. +
-LE108:  bne +++                         ;Branch always. +
- +
-;Samus has no missiles, erase missile sprite. +
-LE10A:* lda #$FF                        ;"Blank" tile. +
-LE10C:  cpx #$F4                        ;If at last 3 sprites, branch to skip. +
-LE10E:  bcs ++                          ; +
-LE110:  sta Sprite03RAM+1,            ;Erase left half of missile. +
-LE113:  cpx #$F0                        ;If at last 4 sprites, branch to skip. +
-LE115:  bcs ++                          ; +
-LE117:  sta Sprite04RAM+1,            ;Erase right half of missile. +
-LE11A:  bne ++                          ;Branch always. +
- +
-;Display 3-digit end sequence timer. +
-LE11C:* lda EndTimerHi                  ; +
-LE11F:  jsr Adiv16                      ;($C2BF)Upper timer digit. +
-LE122:  jsr SPRWriteDigit               ;($E173)Display digit on screen. +
-LE125:  lda EndTimerHi                  ; +
-LE128:  and #$0F                        ;Middle timer digit. +
-LE12A:  jsr SPRWriteDigit               ;($E173)Display digit on screen. +
-LE12D:  lda EndTimerLo                  ; +
-LE130:  jsr Adiv16                      ;($C2BF)Lower timer digit. +
-LE133:  jsr SPRWriteDigit               ;($E173)Display digit on screen. +
-LE136:  lda #$58                        ;"TI" sprite(left half of "TIME"). +
-LE138:  sta Sprite00RAM+1,            ; +
-LE13B:  inc Sprite00RAM+2,            ;Change color of sprite. +
-LE13E:  cpx #$FC                        ;If at last sprite, branch to skip. +
-LE140:  bcs +                           ; +
-LE142:  lda #$59                        ;"ME" sprite(right half of "TIME"). +
-LE144:  sta Sprite01RAM+1,            ; +
-LE147:  inc Sprite01RAM+2,            ;Change color of sprite. +
- +
-LE14A:* ldx SpritePagePos               ;Restore initial sprite page pos. +
-LE14C:  lda TankCount                   ; +
-LE14F:  beq ++                          ;Branch to exit if Samus has no energy tanks. +
- +
-;Display full/empty energy tanks. +
-LE151:  sta $03                         ;Temp store tank count. +
-LE153:  lda #$40                        ;X coord of right-most energy tank. +
-LE155:  sta $00                         ;Energy tanks are drawn from right to left. +
-LE157:  ldy #$6F                        ;"Full energy tank" tile. +
-LE159:  lda HealthHi                    ; +
-LE15C:  jsr Adiv16                      ;($C2BF)/16. A contains # of full energy tanks. +
-LE15F:  sta $01                         ;Storage of full tanks. +
-LE161:  bne AddTanks                    ;Branch if at least 1 tank is full. +
-LE163:  dey                             ;Else switch to "empty energy tank" tile. +
- +
-AddTanks: +
-LE164:  jsr AddOneTank                  ;($E17B)Add energy tank to display. +
-LE167:  dec $01                         ;Any more full energy tanks left?--> +
-LE169:  bne +                           ;If so, then branch.--> +
-LE16B:  dey                             ;Otherwise, switch to "empty energy tank" tile. +
-LE16C:* dec $03                         ;done all tanks?--> +
-LE16E:  bne AddTanks                    ;if not, loop to do another. +
- +
-LE170:  stx SpritePagePos               ;Store new sprite page position. +
-LE172:* rts                             ; +
- +
-;----------------------------------------[Sprite write digit ]--------------------------------------- +
- +
-;A=value in range 0..9. #$A0 is added to A(the number sprites begin at $A0), and the result is stored +
-;as the tile # for the sprite indexed by X. +
- +
-SPRWriteDigit: +
-LE173:  ora #$A0                        ;#$A0 is index into pattern table for numbers. +
-LE175:  sta Sprite00RAM+1,            ;Store proper nametable pattern in sprite RAM. +
-LE178:  jmp Xplus4                      ;Find next sprite pattern table byte. +
- +
-;----------------------------------[ Add energy tank to display ]------------------------------------ +
- +
-;Add energy tank to Samus' data display. +
- +
-AddOneTank: +
-LE17B:  lda #$17                        ;Y coord-1. +
-LE17D:  sta Sprite00RAM,              ; +
-LE180:  tya                             ;Tile value. +
-LE181:  sta Sprite00RAM+1,            ; +
-LE184:  lda #$01                        ;Palette #. +
-LE186:  sta Sprite00RAM+2,            ; +
-LE189:  lda $00                         ;X coord. +
-LE18B:  sta Sprite00RAM+3,            ; +
-LE18E:  sec                             ; +
-LE18F:  sbc #$0A                        ;Find x coord of next energy tank. +
-LE191:  sta $00                         ; +
- +
-;-----------------------------------------[ Add 4 to x ]--------------------------------------------- +
- +
-Xplus4: +
-LE193:  inx                             ; +
-LE194:  inx                             ; +
-LE195:  inx                             ;Add 4 to value stored in X. +
-LE196:  inx                             ; +
-LE197:  rts                             ; +
- +
-;------------------------------------[ Convert hex to decimal ]-------------------------------------- +
- +
-;Convert 8-bit value in A to 3 decimal digits. Upper digit put in $02, middle in $01 and lower in $00. +
- +
-HexToDec: +
-LE198:  ldy #100                        ;Find upper digit. +
-LE19A:  sty $0A                         ; +
-LE19C:  jsr GetDigit                    ;($E1AD)Extract hundreds digit. +
-LE19F:  sty $02                         ;Store upper digit in $02. +
-LE1A1:  ldy #10                         ;Find middle digit. +
-LE1A3:  sty $0A                         ; +
-LE1A5:  jsr GetDigit                    ;($E1AD)Extract tens digit. +
-LE1A8:  sty $01                         ;Store middle digit in $01. +
-LE1AA:  sta $00                         ;Store lower digit in $00 +
-LE1AC:  rts                             ; +
- +
-GetDigit: +
-LE1AD:  ldy #$00                        ; +
-LE1AF:  sec                             ; +
-LE1B0:* iny                             ; +
-LE1B1:  sbc $0A                         ;Loop and subtract value in $0A from A until carry flag--> +
-LE1B3:  bcs -                           ;is not set.  The resulting number of loops is the decimal--> +
-LE1B5:  dey                             ;number extracted and A is the remainder. +
-LE1B6:  adc $0A                         ; +
-LE1B8:  rts                             ; +
- +
-;-------------------------------------[ Status bar sprite data ]------------------------------------- +
- +
-;Sprite data for Samus' data display +
- +
-DataDisplayTbl: +
-LE1B9:  .byte $21,$A0,$01,$30           ;Upper health digit. +
-LE1BD:  .byte $21,$A0,$01,$38           ;Lower health digit. +
-LE1C1:  .byte $2B,$FF,$01,$28           ;Upper missile digit. +
-LE1C5:  .byte $2B,$FF,$01,$30           ;Middle missile digit. +
-LE1C9:  .byte $2B,$FF,$01,$38           ;Lower missile digit. +
-LE1CD:  .byte $2B,$5E,$00,$18           ;Left half of missile. +
-LE1D1:  .byte $2B,$5F,$00,$20           ;Right half of missile. +
-LE1D5:  .byte $21,$76,$01,$18           ;E +
-LE1D9:  .byte $21,$7F,$01,$20           ;N +
-LE1DD:  .byte $21,$3A,$00,$28           ;.. +
- +
-;-------------------------------------------[ Bit scan ]--------------------------------------------- +
- +
-;This function takes the value stored in A and right shifts it until a set bit is encountered. +
-;Once a set bit is encountered, the function exits and returns the bit number of the set bit. +
-;The returned value is stored in A.  +
- +
-BitScan: +
-LE1E1:  stx $0E                         ;Save X. +
-LE1E3:  ldx #$00                        ;First bit is bit 0. +
-LE1E5:* lsr                             ;Transfer bit to carry flag. +
-LE1E6:  bcs +                           ;If the shifted bit was 1, Branch out of loop. +
-LE1E8:  inx                             ;Increment X to keep of # of bits checked. +
-LE1E9:  cpx #$08                        ;Have all 8 bit been tested?--> +
-LE1EB:  bne -                           ;If not, branch to check the next bit. +
-LE1ED:* txa                             ;Return which bit number was set. +
-LE1EE:  ldx $0E                         ;Restore X. +
-LE1F0:* rts                             ; +
- +
-;------------------------------------------[ Scroll door ]------------------------------------------- +
- +
-;Scrolls the screen if Samus is inside a door. +
- +
-ScrollDoor: +
-LE1F1:  ldx DoorStatus                  ; +
-LE1F3:  beq -                           ;Exit if Samus isn't in a door. +
-LE1F5:  dex                             ; +
-LE1F6:  bne +                           ;Not in right door. branch to check left door. +
-LE1F8:  jsr ScrollRight                 ;($E6D2)DoorStatus=1, scroll 1 pixel right. +
-LE1FB:  jmp ++                          ;Jump to check if door scroll is finished. +
- +
-LE1FE:* dex                             ;Check if in left door. +
-LE1FF:  bne ++                          ; +
-LE201:  jsr ScrollLeft                  ;($E6A7)DoorStatus=2, scroll 1 pixel left. +
-LE204:* ldx ScrollX                     ;Has x scroll offset reached 0?--> +
-LE206:  bne Exit15                      ;If not, branch to exit. +
- +
-;Scrolled one full screen, time to exit door. +
-LE208:  ldx #$05                        ;Samus is exiting the door. +
-LE20A:  bne DoOneDoorScroll             ;Branch always. +
- +
-LE20C:* dex                             ; +
-LE20D:  bne +                           ;Check if need to scroll down to center door. +
-LE20F:  jsr ScrollDown                  ;($E519)DoorStatus=3, scroll 1 pixel down. +
-LE212:  jmp ++                          ;Jump to check y scrolling value. +
-LE215:* dex                             ; +
-LE216:  bne Exit15                      ;Check if need to scroll up to center door. +
-LE218:  jsr ScrollUp                    ;($E4F1)DoorStatus=4, scroll 1 pixel up. +
- +
-VerticalRoomCentered: +
-LE21B:* ldx ScrollY                     ;Has room been centered on screen?--> +
-LE21D:  bne Exit15                      ;If not, branch to exit. +
-LE21F:  stx DoorOnNameTable3            ; +
-LE221:  stx DoorOnNameTable0            ;Erase door nametable data. +
-LE223:  inx                             ;X=1. +
-LE224:  lda ObjectX                     ;Did Samus enter in the right hand door?--> +
-LE227:  bmi ++                          ;If so, branch. +
-LE229:  inx                             ;X=2. Samus is in left door. +
-LE22A:  bne ++                          ;Branch always. +
- +
-;This function is called once after door scrolling is complete. +
- +
-DoOneDoorScroll: +
-LE22C:  lda #$20                        ;Set DoorDelay to 32 frames(comming out of door). +
-LE22E:  sta DoorDelay                   ; +
-LE230:  lda SamusDoorData               ;Check if scrolling should be toggled. +
-LE232:  jsr Amul8                       ;($C2C6)*8. Is door not to toggle scrolling(item room,--> +
-LE235:  bcs +                           ;bridge room, etc.)? If so, branch to NOT toggle scrolling. +
-LE237:  ldy DoorScrollStatus            ;If comming from vertical shaft, skip ToggleScroll because--> +
-LE239:  cpy #$03                        ;the scroll was already toggled after room was centered--> +
-LE23B:  bcc ++                          ;by the routine just above. +
-LE23D:* lda #$47                        ;Set mirroring for vertical mirroring(horz scrolling). +
-LE23F:  bne ++                          ;Branch always. +
- +
-LE241:* jsr ToggleScroll                ;($E252)Toggle scrolling and mirroring. +
-LE244:* sta MirrorCntrl                 ;Store new mirror control data. +
-LE246:  stx DoorStatus                  ;DoorStatus=5. Done with door scrolling. +
- +
-Exit15: +
-LE248:  rts                             ;Exit for several routines above. +
- +
-;------------------------------------[ Toggle Samus nametable ]-------------------------------------- +
- +
-ToggleSamusHi: +
-LE249:  lda ObjectHi                    ; +
-LE24C:  eor #$01                        ;Change Samus' current nametable from one to the other. +
-LE24E:  sta ObjectHi                    ; +
-LE251:  rts                             ; +
- +
-;-------------------------------------------[ Toggle scroll ]---------------------------------------- +
- +
-;Toggles both mirroring and scroll direction when Samus has moved from +
-;a horizontal shaft to a vertical shaft or vice versa. +
- +
-ToggleScroll: +
-LE252:  lda ScrollDir                   ; +
-LE254:  eor #$03                        ;Toggle scroll direction. +
-LE256:  sta ScrollDir                   ; +
-LE258:  lda MirrorCntrl                 ;Toggle mirroring. +
-LE25A:  eor #$08                        ; +
-LE25C:  rts                             ; +
- +
-;----------------------------------------[ Is Samus in lava ]---------------------------------------- +
- +
-;The following function checks to see if Samus is in lava.  If she is, the carry bit is cleared, +
-;if she is not, the carry bit is set. Samus can only be in lava if in a horizontally scrolling +
-;room. If Samus is 24 pixels or less away from the bottom of the screen, she is considered to be +
-;in lava whether its actually there or not. +
- +
-IsSamusInLava: +
-LE25D:  lda #$01                        ; +
-LE25F:  cmp ScrollDir                   ;Set carry bit(and exit) if scrolling up or down. +
-LE261:  bcs +                           ; +
-LE263:  lda #$D8                        ;If Samus is Scrolling left or right and within 24 pixels--> +
-LE265:  cmp ObjectY                     ;of the bottom of the screen, she is in lava. Clear carry bit. +
-LE268:* rts                             ; +
- +
-;----------------------------------[ Check lava and movement routines ]------------------------------ +
- +
-LavaAndMoveCheck: +
-LE269:  lda ObjAction                   ; +
-LE26C:  cmp #sa_Elevator                ;Is Samus on elevator?--> +
-LE26E:  beq +                           ;If so, branch. +
-LE270:  cmp #sa_Dead                    ;Is Samus Dead--> +
-LE272:  bcs -                           ;If so, branch to exit. +
-LE274:* jsr IsSamusInLava               ;($E25D)Clear carry flag if Samus is in lava. +
-LE277:  ldy #$FF                        ;Assume Samus not in lava. +
-LE279:  bcs ++++                        ;Samus not in lava so branch. +
- +
-;Samus is in lava. +
-LE27B:  sty DamagePushDirection         ;Don't push Samus from lava damage. +
-LE27D:  jsr ClearHealthChange           ;($F323)Clear any pending health changes to Samus. +
-LE280:  lda #$32                        ; +
-LE282:  sta SamusBlink                  ;Make Samus blink. +
-LE284:  lda FrameCount                  ; +
-LE286:  and #$03                        ;Start the jump SFX every 4th frame while in lava. +
-LE288:  bne +                           ; +
-LE28A:  jsr SFX_SamusJump               ;($CBAC)Initiate jump SFX. +
-LE28D:* lda FrameCount                  ; +
-LE28F:  lsr                             ;This portion of the code causes Samus to be damaged by--> +
-LE290:  and #$03                        ;lava twice every 8 frames if she does not have the varia--> +
-LE292:  bne ++                          ;but only once every 8 frames if she does. +
-LE294:  lda SamusGear                   ; +
-LE297:  and #gr_VARIA                   ;Does Samus have the Varia?--> +
-LE299:  beq +                           ;If not, branch. +
-LE29B:  bcc ++                          ;Samus has varia. Carry set every other frame. Half damage. +
-LE29D:* lda #$07                        ; +
-LE29F:  sta HealthLoChange              ;Samus takes lava damage. +
-LE2A1:  jsr SubtractHealth              ;($CE92) +
-LE2A4:* ldy #$00                        ;Prepare to indicate Samus is in lava. +
-LE2A6:* iny                             ;Set Samus lava status. +
-LE2A7:  sty SamusInLava                 ; +
- +
-SamusMoveVertically: +
-LE2A9:  jsr VertAccelerate              ;($E37A)Calculate vertical acceleration. +
-LE2AC:  lda ObjectY                     ; +
-LE2AF:  sec                             ; +
-LE2B0:  sbc ScrollY                     ;Calculate Samus' screen y position. +
-LE2B2:  sta SamusScrY                   ; +
-LE2B4:  lda $00                         ;Load temp copy of vertical speed. +
-LE2B6:  bpl ++++                        ;If Samus is moving downwards, branch. +
- +
-LE2B8:  jsr TwosCompliment              ;($C3D4)Get twos compliment of vertical speed. +
-LE2BB:  ldy SamusInLava                 ;Is Samus in lava? +
-LE2BD:  beq +                           ;If not, branch,--> +
-LE2BF:  lsr                             ;else cut vertical speed in half. +
-LE2C0:  beq SamusMoveHorizontally       ;($E31A)Branch if no vertical mvmnt to Check left/right mvmnt. +
- +
-;Samus is moving upwards. +
-LE2C2:* sta ObjectCounter               ;Store number of pixels to move Samus this frame. +
-LE2C4:* jsr MoveSamusUp                 ;($E457)Attempt to move Samus up 1 pixel. +
-LE2C7:  bcs +                           ;Branch if Samus successfully moved up 1 pixel. +
- +
-LE2C9:  sec                             ;Samus blocked upwards. Divide her speed by 2 and set the +
-LE2CA:  ror ObjVertSpeed                ;MSB to reverse her direction of travel. +
-LE2CD:  ror VertCntrLinear              ; +
-LE2D0:  jmp SamusMoveHorizontally       ;($E31A)Attempt to move Samus left/right. +
- +
-LE2D3:* dec ObjectCounter               ;1 pixel movement is complete. +
-LE2D5:  bne --                          ;Branch if Samus needs to be moved another pixel. +
- +
-;Samus is moving downwards. +
-LE2D7:* beq SamusMoveHorizontally       ;($E31A)Branch if no vertical mvmnt to Check left/right mvmnt. +
-LE2D9:  ldy SamusInLava                 ;Is Samus in lava? +
-LE2DB:  beq +                           ;If not, branch,--> +
-LE2DD:  lsr                             ;Else reduce Samus speed by 75%(divide by 4). +
-LE2DE:  lsr                             ; +
-LE2DF:  beq SamusMoveHorizontally       ;($E31A)Attempt to move Samus left/right. +
- +
-LE2E1:* sta ObjectCounter               ;Store number of pixels to move Samus this frame. +
-LE2E3:* jsr MoveSamusDown               ;($E4A3)Attempt to move Samus 1 pixel down. +
-LE2E6:  bcs +++                         ;Branch if Samus successfully moved down 1 pixel. +
- +
-;Samus bounce after hitting the ground in ball form. +
-LE2E8:  lda ObjAction                   ; +
-LE2EB:  cmp #sa_Roll                    ;Is Samus rolled into a ball?--> +
-LE2ED:  bne +                           ;If not, branch. +
-LE2EF:  lsr ObjVertSpeed                ;Divide verticle speed by 2. +
-LE2F2:  beq ++                          ;Speed not fast enough to bounce. branch to skip. +
-LE2F4:  ror VertCntrLinear              ;Move carry bit into MSB to reverse Linear counter. +
-LE2F7:  lda #$00                        ; +
-LE2F9:  sec                             ; +
-LE2FA:  sbc VertCntrLinear              ;Subtract linear counter from 0 and save the results.--> +
-LE2FD:  sta VertCntrLinear              ;Carry will be cleared. +
-LE300:  lda #$00                        ; +
-LE302:  sbc ObjVertSpeed                ;Subtract vertical speed from 0. this will reverse the--> +
-LE305:  sta ObjVertSpeed                ;vertical direction of travel(bounce up). +
-LE308:  jmp SamusMoveHorizontally       ;($E31A)Attempt to move Samus left/right. +
- +
-;Samus has hit the ground after moving downwards.  +
-LE30B:* jsr SFX_SamusWalk               ;($CB96)Play walk SFX. +
-LE30E:* jsr StopVertMovement            ;($D147)Clear vertical movement data. +
-LE311:  sty SamusGravity                ;Clear Samus gravity value. +
-LE314:  beq SamusMoveHorizontally       ;($E31A)Attempt to move Samus left/right. +
- +
-LE316:* dec ObjectCounter               ;1 pixel movement is complete. +
-LE318:  bne ----                        ;Branch if Samus needs to be moved another pixel. +
- +
-SamusMoveHorizontally: +
-LE31A:  jsr HorzAccelerate              ;($E3E5)Horizontally accelerate Samus. +
-LE31D:  lda ObjectX                     ; +
-LE320:  sec                             ;Calculate Samus' x position on screen. +
-LE321:  sbc ScrollX                     ; +
-LE323:  sta SamusScrX                   ;Save Samus' x position. +
-LE325:  lda $00                         ;Load Samus' current horizontal speed. +
-LE327:  bpl +++                         ;Branch if moving right. +
- +
-;Samus is moving left. +
-LE329:  jsr TwosCompliment              ;($C3D4)Get twos compliment of horizontal speed. +
-LE32C:  ldy SamusInLava                 ;Is Samus in lava?--> +
-LE32E:  beq +                           ;If not, branch,--> +
-LE330:  lsr                             ;else cut horizontal speed in half. +
-LE331:  beq Exit10                      ;Branch to exit if Samus not going to move this frame. +
- +
-LE333:* sta ObjectCounter               ;Store number of pixels to move Samus this frame. +
-LE335:* jsr MoveSamusLeft               ;($E626)Attempt to move Samus 1 pixel to the left. +
-LE338:  jsr CheckStopHorzMvmt           ;($E365)Check if horizontal movement needs to be stopped. +
-LE33B:  dec ObjectCounter               ;1 pixel movement is complete. +
-LE33D:  bne -                           ;Branch if Samus needs to be moved another pixel. +
- +
-LE33F:  lda SamusDoorData               ;Has Samus entered a door?--> +
-LE341:  beq Exit10                      ;If not, branch to exit. +
-LE343:  lda #$01                        ;Door leads to the left. +
-LE345:  bne ++++                        ;Branch always. +
- +
-;Samus is moving right. +
-LE347:* beq Exit10                      ;Branch to exit if Samus not moving horizontally. +
-LE349:  ldy SamusInLava                 ;Is Samus in lava?--> +
-LE34B:  beq +                           ;If not, branch,--> +
-LE34D:  lsr                             ;else cut horizontal speed in half. +
-LE34E:  beq Exit10                      ;Branch to exit if Samus not going to move this frame. +
- +
-LE350:* sta ObjectCounter               ;Store number of pixels to move Samus this frame. +
-LE352:* jsr MoveSamusRight              ;($E668)Attempt to move Samus 1 pixel to the right. +
-LE355:  jsr CheckStopHorzMvmt           ;($E365)Check if horizontal movement needs to be stopped. +
-LE358:  dec ObjectCounter               ;1 pixel movement is complete. +
-LE35A:  bne -                           ;Branch if Samus needs to be moved another pixel. +
- +
-LE35C:  lda SamusDoorData               ;Has Samus entered a door?--> +
-LE35E:  beq Exit10                      ;If not, branch to exit. +
-LE360:  lda #$00                        ; +
-LE362:* sta SamusDoorDir                ;Door leads to the right. +
- +
-Exit10: +
-LE364:  rts                             ;Exit for routines above and below. +
- +
-CheckStopHorzMvmt: +
-LE365:  bcs Exit10                      ;Samus moved successfully. Branch to exit. +
-LE367:  lda #$01                        ;Load counter with #$01 so this function will not be--> +
-LE369:  sta ObjectCounter               ;called again. +
-LE36C:  lda SamusGravity                ;Is Samus on the ground?--> +
-LE36E:  bne Exit10                      ;If not, branch to exit. +
-LE370:  lda ObjAction                   ; +
-LE373:  cmp #sa_Roll                    ;Is Samus rolled into a ball?--> +
-LE375:  beq Exit10                      ;If so, branch to exit. +
-LE377:  jmp StopHorzMovement            ;($CF55)Stop horizontal movement or play walk SFX if stopped. +
- +
-;-------------------------------------[ Samus vertical acceleration ]-------------------------------- +
- +
-;The following code accelerates/decelerates Samus vertically.  There are 4 possible values for +
-;gravity used in the acceleration calculation. The higher the number, the more intense the gravity. +
-;The possible values for gravity are as follows: +
-;#$38-When Samus has been hit by an enemy. +
-;#$1A-When Samus is falling. +
-;#$18-Jump without high jump boots. +
-;#$12-Jump with high jump boots. +
- +
-VertAccelerate: +
-LE37A:  lda SamusGravity                ;Is Samus rising or falling?--> +
-LE37D:  bne ++                          ;Branch if yes. +
-LE37F:  lda #$18                        ; +
-LE381:  sta SamusHorzSpeedMax           ;Set Samus maximum running speed. +
-LE384:  lda ObjectY                     ; +
-LE387:  clc                             ; +
-LE388:  adc ObjRadY                     ;Check is Samus is obstructed downwards on y room--> +
-LE38B:  and #$07                        ;positions divisible by 8(every 8th pixel). +
-LE38D:  bne +                           ; +
-LE38F:  jsr CheckMoveDown               ;($E7AD)Is Samus obstructed downwards?--> +
-LE392:  bcc ++                          ;Branch if yes. +
-LE394:* jsr SamusOnElevatorOrEnemy      ;($D976)Calculate if Samus standing on elevator or enemy. +
-LE397:  lda SamusOnElevator             ;Is Samus on an elevator?--> +
-LE39A:  bne +                           ;Branch if yes. +
-LE39C:  lda OnFrozenEnemy               ;Is Samus standing on a frozen enemy?--> +
-LE39E:  bne +                           ;Branch if yes. +
-LE3A0:  lda #$1A                        ;Samus is falling. Store falling gravity value. +
-LE3A2:  sta SamusGravity                ; +
- +
-LE3A5:* ldx #$05                        ;Load X with maximum downward speed. +
-LE3A7:  lda VertCntrLinear              ; +
-LE3AA:  clc                             ;The higher the gravity, the faster this addition overflows--> +
-LE3AB:  adc SamusGravity                ;and the faster ObjVertSpeed is incremented. +
-LE3AE:  sta VertCntrLinear              ; +
-LE3B1:  lda ObjVertSpeed                ;Every time above addition sets carry bit, ObjVertSpeed is--> +
-LE3B4:  adc #$00                        ;incremented. This has the effect of speeding up a fall--> +
-LE3B6:  sta ObjVertSpeed                ;and slowing down a jump. +
-LE3B9:  bpl +                           ;Branch if Samus is moving downwards. +
- +
-;Check if maximum upward speed has been exceeded. If so, prepare to set maximum speed. +
-LE3BB:  lda #$00                        ; +
-LE3BD:  cmp VertCntrLinear              ;Sets carry bit. +
-LE3C0:  sbc ObjVertSpeed                ;Subtract ObjVertSpeed to see if maximum speed has--> +
-LE3C3:  cmp #$06                        ;been exceeded. +
-LE3C5:  ldx #$FA                        ;Load X with maximum upward speed. +
-LE3C7:  bne ++                          ;Branch always. +
- +
-;Check if maximum downward speed has been reached. If so, prepare to set maximum speed. +
-LE3C9:* cmp #$05                        ;Has maximum downward speed been reached?--> +
-LE3CB:* bcc +                           ;If not, branch. +
- +
-;Max verticle speed reached or exceeded. Adjust Samus verticle speed to max. +
-LE3CD:  jsr StopVertMovement            ;($D147)Clear verticle movement data. +
-LE3D0:  stx ObjVertSpeed                ;Set Samus vertical speed to max. +
- +
-;This portion of the function creates an exponential increase/decrease in verticle speed. This is the +
-;part of the function that does all the work to make Samus' jump seem natural. +
-LE3D3:* lda VertCntrNonLinear           ; +
-LE3D6:  clc                             ;This function adds itself plus the linear verticle counter--> +
-LE3D7:  adc VertCntrLinear              ;onto itself every frame.  This causes the non-linear--> +
-LE3DA:  sta VertCntrNonLinear           ;counter to increase exponentially.  This function will--> +
-LE3DD:  lda #$00                        ;cause Samus to reach maximum speed first in most--> +
-LE3DF:  adc ObjVertSpeed                ;situations before the linear counter. +
-LE3E2:  sta $00                         ;$00 stores temp copy of current verticle speed. +
-LE3E4:  rts                             ; +
- +
-;---------------------------------------------------------------------------------------------------- +
- +
-HorzAccelerate: +
-LE3E5:  lda SamusHorzSpeedMax +
-        jsr Amul16       ; * 16 +
-        sta $00 +
-        sta $02 +
-        lda SamusHorzSpeedMax +
-        jsr Adiv16       ; / 16 +
-        sta $01 +
-        sta $03 +
- +
-        lda HorzCntrLinear +
-        clc +
-        adc SamusHorzAccel +
-        sta HorzCntrLinear +
-        tax +
-        lda #$00 +
-        bit SamusHorzAccel +
-        bpl +                           ;Branch if Samus accelerating to the right. +
- +
-        lda #$FF +
- +
-*       adc ObjHorzSpeed +
-        sta ObjHorzSpeed +
-        tay +
-        bpl +                           ;Branch if Samus accelerating to the right. +
- +
-        lda #$00 +
-        sec +
-        sbc HorzCntrLinear +
-        tax +
-        lda #$00 +
-        sbc ObjHorzSpeed +
-        tay +
-        jsr LE449 +
- +
-*       cpx $02 +
-        tya +
-        sbc $03 +
-        bcc + +
-        lda $00 +
-        sta HorzCntrLinear +
-        lda $01 +
-        sta ObjHorzSpeed +
-*       lda HorzCntrNonLinear +
-        clc +
-        adc HorzCntrLinear +
-        sta HorzCntrNonLinear +
-        lda #$00 +
-        adc ObjHorzSpeed +
-        sta $00                         ;$00 stores temp copy of current horizontal speed. +
-        rts                             ; +
- +
-LE449:  lda #$00 +
-        sec +
-        sbc $00 +
-        sta $00 +
-        lda #$00 +
-        sbc $01 +
-        sta $01 +
-        rts +
- +
-;---------------------------------------------------------------------------------------------------- +
- +
-;Attempt to move Samus one pixel up. +
- +
-MoveSamusUp: +
-LE457:  lda ObjectY                     ;Get Samus' y position in room. +
-        sec                             ; +
-        sbc ObjRadY                     ;Subtract Samus' vertical radius. +
-LE45E:  and #$07                        ;Check if result is a multiple of 8. If so, branch to--> +
-LE460:  bne +                           ;Only call crash detection every 8th pixel. +
-LE462:  jsr CheckMoveUp                 ;($E7A2)Check if Samus obstructed UPWARDS.--> +
-        bcc +++++++                     ;If so, branch to exit(can't move any further). +
-*       lda ObjAction                   ; +
-        cmp #sa_Elevator                ;Is Samus riding elevator?--> +
-        beq +                           ;If so, branch. +
-        jsr SamusOnElevatorOrEnemy      ;($D976)Calculate if Samus standing on elevator or enemy. +
-        lda SamusHit +
-        and #$42 +
-        cmp #$42 +
-        clc +
-        beq ++++++ +
-*       lda SamusScrY +
-        cmp #$66        ; reached up scroll limit? +
-        bcs +      ; branch if not +
-        jsr ScrollUp +
-        bcc ++ +
-*       dec SamusScrY +
-*       lda ObjectY +
-        bne ++ +
-        lda ScrollDir +
-        and #$02 +
-        bne + +
-        jsr ToggleSamusHi       ; toggle 9th bit of Samus' Y coord +
-*       lda #240 +
-        sta ObjectY +
-*       dec ObjectY +
-        inc SamusJumpDsplcmnt +
-        sec +
-*       rts +
- +
-; attempt to move Samus one pixel down +
- +
-MoveSamusDown: +
-        lda ObjectY +
-        clc +
-        adc ObjRadY +
-        and #$07 +
-        bne +              ; only call crash detection every 8th pixel +
-        jsr CheckMoveDown       ; check if Samus obstructed DOWNWARDS +
-        bcc +++++++      ; exit if yes +
-*       lda ObjAction +
-        cmp #sa_Elevator        ; is Samus in elevator? +
-        beq + +
-        jsr LD976 +
-        lda SamusOnElevator +
-        clc +
-        bne ++++++ +
-        lda OnFrozenEnemy +
-        bne ++++++ +
-*       lda SamusScrY +
-        cmp #$84        ; reached down scroll limit? +
-        bcc +      ; branch if not +
-        jsr ScrollDown +
-        bcc ++ +
-*       inc SamusScrY +
-*       lda ObjectY +
-        cmp #239 +
-        bne ++ +
-        lda ScrollDir +
-        and #$02 +
-        bne + +
-        jsr ToggleSamusHi       ; toggle 9th bit of Samus' Y coord +
-*       lda #$FF +
-        sta ObjectY +
-*       inc ObjectY +
-        dec SamusJumpDsplcmnt +
-        sec +
-*       rts +
- +
-; Attempt to scroll UP +
- +
-        ScrollUp: +
-        lda ScrollDir +
-        beq + +
-        cmp #$01 +
-        bne ++++ +
-        dec ScrollDir +
-        lda ScrollY +
-        beq + +
-        dec MapPosY +
-*       ldx ScrollY +
-        bne + +
-        dec MapPosY     ; decrement MapY +
-        jsr GetRoomNum  ; put room # at current map pos in $5A +
-        bcs ++   ; if function returns CF = 1, moving up is not possible +
-        jsr LE9B7       ; switch to the opposite Name Table +
-        ldx #240        ; new Y coord +
-*       dex +
-        jmp LE53F +
- +
-*       inc MapPosY +
-*       sec +
-        rts +
- +
-; Attempt to scroll DOWN +
- +
-        ScrollDown: +
-        ldx ScrollDir +
-        dex +
-        beq + +
-        bpl +++++ +
-        inc ScrollDir +
-        lda ScrollY +
-        beq + +
-        inc MapPosY +
-*       lda ScrollY +
-        bne + +
-        inc MapPosY     ; increment MapY +
-        jsr GetRoomNum  ; put room # at current map pos in $5A +
-        bcs +++   ; if function returns CF = 1, moving down is not possible +
-*       ldx ScrollY +
-        cpx #239 +
-        bne + +
-        jsr LE9B7       ; switch to the opposite Name Table +
-        ldx #$FF +
-*       inx +
-LE53F:  stx ScrollY +
-        jsr LE54A       ; check if it's time to update Name Table +
-        clc +
-        rts +
- +
-*       dec MapPosY +
-*       sec +
-*       rts +
- +
-LE54A:  jsr SetupRoom +
-        ldx RoomNumber +
-        inx +
-        bne - +
-        lda ScrollDir +
-        and #$02 +
-        bne + +
-        jmp LE571 +
-*       jmp LE701 +
- +
-; Table +
- +
-Table11: +
-        .byte $07 +
-        .byte $00 +
- +
-;---------------------------------[ Get PPU and RoomRAM addresses ]---------------------------------- +
- +
-PPUAddrs: +
-LE560:  .byte $20                       ;High byte of nametable #0(PPU). +
-LE561:  .byte $2C                       ;High byte of nametable #3(PPU) +
- +
-WRAMAddrs: +
-LE562:  .byte $60                       ;High byte of RoomRAMA(cart RAM). +
-LE563:  .byte $64                       ;High byte of RoomRAMB(cart RAM). +
- +
-GetNameAddrs: +
-LE564:  jsr GetNameTable                ;($EB85)Get current name table number. +
-LE567:  and #$01                        ;Update name table 0 or 3. +
-LE569:  tay                             ; +
-LE56A:  lda PPUAddrs,                 ;Get high PPU addr of nametable(dest). +
-LE56D:  ldx WRAMAddrs,                ;Get high cart RAM addr of nametable(src). +
-LE570:  rts                             ; +
- +
-;---------------------------------------------------------------------------------------------------- +
- +
-; check if it's time to update nametable (when scrolling is VERTICAL) +
- +
-LE571:  ldx ScrollDir +
-        lda ScrollY +
-        and #$07        ; compare value = 0 if ScrollDir = down, else 7 +
-        cmp Table11,x +
-        bne --     ; exit if not equal (no nametable update) +
- +
-LE57C:  ldx ScrollDir                   ; +
-        cpx TempScrollDir               ;Still scrolling same direction when room was loaded?--> +
-        bne --                          ;If not, branch to exit. +
-        lda ScrollY +
-        and #$F8        ; keep upper 5 bits +
-        sta $00 +
-        lda #$00 +
-        asl $00 +
-        rol +
-        asl $00 +
-        rol +
- +
-LE590:  sta $01  ; $0001 = (ScrollY & 0xF8) << 2 = row offset +
-        jsr GetNameAddrs +
-        ora $01 +
-        sta $03 +
-        txa +
-        ora $01 +
-        sta $01 +
-        lda $00 +
-        sta $02 +
-        lda ScrollDir +
-        lsr             ; A = 0 if vertical scrolling, 1 if horizontal +
-        tax +
-        lda Table01,x +
-        sta $04 +
-        ldy #$01 +
-        sty PPUDataPending      ; data pending = YES +
-        dey +
-        ldx PPUStrIndex +
-        lda $03 +
-        jsr WritePPUByte                ;($C36B)Put data byte into PPUDataString. +
-        lda $02 +
-        jsr WritePPUByte +
-        lda $04 +
-        jsr SeparateControlBits         ;($C3C6) +
-*       lda ($00),y +
-        jsr WritePPUByte +
-        sty $06 +
-        ldy #$01        ; WRAM pointer increment = 1... +
-        bit $04  ; ... if bit 7 (PPU inc) of $04 clear +
-        bpl + +
-        ldy #$20        ; else ptr inc = 32 +
-*       jsr AddYToPtr00                 ;($C2A8) +
-        ldy $06 +
-        dec $05 +
-        bne -- +
-        stx PPUStrIndex +
-        jsr EndPPUString +
- +
-Table01: +
-        .byte $20                       ;Horizontal write. PPU inc = 1, length = 32 tiles. +
-        .byte $9E                       ;Vertical write... PPU inc = 32, length = 30 tiles. +
- +
-;---------------------------------[Write PPU attribute table data ]---------------------------------- +
- +
-WritePPUAttribTbl: +
-LE5E2:  ldx #$C0                        ;Low byte of First row of attribute table. +
-LE5E4:  lda RoomNumber                  ; +
-LE5E6:  cmp #$F2                        ;Is this the second pass through the routine?--> +
-LE5E8:  beq +                           ;If so, branch. +
-LE5EA:  ldx #$E0                        ;Low byte of second row of attribute table. +
-LE5EC:* stx $00                         ;$0000=RoomRAM atrrib table starting address. +
-LE5EE:  stx $02                         ;$0002=PPU attrib table starting address. +
-LE5F0:  jsr GetNameAddrs                ;($E564)Get name table addr and corresponding RoomRAM addr. +
-LE5F3:  ora #$03                        ;#$23 for attrib table 0, #$2F for attrib table 3. +
-LE5F5:  sta $03                         ;Store results. +
-LE5F7:  txa                             ;move high byte of RoomRAM to A. +
-LE5F8:  ora #$03                        ;#$63 for RoomRAMA, #$67 for RoomRAMB(Attrib tables). +
-LE5FA:  sta $01                         ;Store results. +
-LE5FC:  lda #$01                        ; +
-LE5FE:  sta PPUDataPending              ;Data pending = YES. +
-LE600:  ldx PPUStrIndex                 ;Load current index into PPU strng to append data. +
-LE603:  lda $03                         ;Store high byte of starting address(attrib table). +
-LE605:  jsr WritePPUByte                ;($C36B)Put data byte into PPUDataString. +
-LE608:  lda $02                         ;Store low byte of starting address(attrib table). +
-LE60A:  jsr WritePPUByte                ;($C36B)Put data byte into PPUDataString. +
-LE60D:  lda #$20                        ;Length of data to write(1 row of attrib data). +
-LE60F:  sta $04                         ; +
-LE611:  jsr WritePPUByte                ;($C36B)Write control byte. Horizontal write. +
-LE614:  ldy #$00                        ;Reset index into data string. +
-LE616:* lda ($00),                    ;Get data byte. +
-LE618:  jsr WritePPUByte                ;($C36B)Put data byte into PPUDataString. +
-LE61B:  iny                             ;Increment to next attrib data byte. +
-LE61C:  dec $04                         ; +
-LE61E:  bne -                           ;Loop until all attrib data loaded into PPU. +
-LE620:  stx PPUStrIndex                 ;Store updated PPU string index. +
-LE623:  jsr EndPPUString                ;($C376)Append end marker(#$00) and exit writing routines. +
- +
-;---------------------------------------------------------------------------------------------------- +
- +
-; attempt to move Samus one pixel left +
- +
-MoveSamusLeft: +
-LE626:  lda ObjectX +
-        sec +
-        sbc ObjRadX +
-        and #$07 +
-        bne +              ; only call crash detection every 8th pixel +
-        jsr CheckMoveLeft       ; check if player is obstructed to the LEFT +
-        bcc +++++        ; branch if yes! (CF = 0) +
-*       jsr LD976 +
-        lda SamusHit +
-        and #$41 +
-        cmp #$41 +
-        clc +
-        beq ++++ +
-        lda SamusScrX +
-        cmp #$71        ; reached left scroll limit? +
-        bcs +      ; branch if not +
-        jsr ScrollLeft +
-        bcc ++ +
-*       dec SamusScrX +
-*       lda ObjectX +
-        bne + +
-        lda ScrollDir +
-        and #$02 +
-        beq + +
-        jsr ToggleSamusHi       ; toggle 9th bit of Samus' X coord +
-*       dec ObjectX +
-        sec +
-        rts +
- +
-; crash with object on the left +
- +
-*       lda #$00 +
-        sta SamusDoorData +
-        rts +
- +
-; attempt to move Samus one pixel right +
- +
-MoveSamusRight: +
-        lda ObjectX +
-        clc +
-        adc ObjRadX +
-        and #$07 +
-        bne +              ; only call crash detection every 8th pixel +
-        jsr CheckMoveRight      ; check if Samus is obstructed to the RIGHT +
-        bcc +++++       ; branch if yes! (CF = 0) +
-*       jsr LD976 +
-        lda SamusHit +
-        and #$41 +
-        cmp #$40 +
-        clc +
-        beq ++++ +
-        lda SamusScrX +
-        cmp #$8F        ; reached right scroll limit? +
-        bcc +      ; branch if not +
-        jsr ScrollRight +
-        bcc ++ +
-*       inc SamusScrX +
-*       inc ObjectX      ; go right, Samus! +
-        bne + +
-        lda ScrollDir +
-        and #$02 +
-        beq + +
-        jsr ToggleSamusHi       ; toggle 9th bit of Samus' X coord +
-*       sec +
-        rts +
- +
-; crash with object on the right +
- +
-*       lda #$00 +
-        sta SamusDoorData +
-        rts +
- +
-; Attempt to scroll LEFT +
- +
-        ScrollLeft: +
-        lda ScrollDir +
-        cmp #$02 +
-        beq + +
-        cmp #$03 +
-        bne ++++ +
-        dec ScrollDir +
-        lda ScrollX +
-        beq + +
-        dec MapPosX +
-*       lda ScrollX +
-        bne + +
-        dec MapPosX     ; decrement MapX +
-        jsr GetRoomNum  ; put room # at current map pos in $5A +
-        bcs ++  ; if function returns CF=1, scrolling left is not possible +
-        jsr LE9B7       ; switch to the opposite Name Table +
-*       dec ScrollX +
-        jsr LE54A       ; check if it's time to update Name Table +
-        clc +
-        rts +
- +
-*       inc MapPosX +
-*       sec +
-        rts +
- +
-; Attempt to scroll RIGHT +
- +
-ScrollRight: +
-        lda ScrollDir +
-        cmp #$03 +
-        beq + +
-        cmp #$02 +
-        bne +++++ +
-        inc ScrollDir +
-        lda ScrollX +
-        beq + +
-        inc MapPosX +
-*       lda ScrollX +
-        bne + +
-        inc MapPosX +
-        jsr GetRoomNum  ; put room # at current map pos in $5A +
-        bcs +++   ; if function returns CF=1, scrolling right is not possible +
-*       inc ScrollX +
-        bne + +
-        jsr LE9B7       ; switch to the opposite Name Table +
-*       jsr LE54A       ; check if it's time to update Name Table +
-        clc +
-        rts +
- +
-*       dec MapPosX +
-*       sec +
-*       rts +
- +
-Table02: +
-        .byte $07,$00 +
- +
-; check if it's time to update nametable (when scrolling is HORIZONTAL) +
- +
-LE701:  ldx ScrollDir +
-        lda ScrollX +
-        and #$07        ; keep lower 3 bits +
-        cmp Table02-2,x ; compare value = 0 if ScrollDir = right, else 7 +
-        bne -      ; exit if not equal (no nametable update) +
- +
-LE70C:  ldx ScrollDir +
-        cpx TempScrollDir +
-        bne - +
-        lda ScrollX +
-        and #$F8        ; keep upper five bits +
-        jsr Adiv8       ; / 8 (make 'em lower five) +
-        sta $00 +
-        lda #$00 +
-        jmp LE590 +
- +
-;---------------------------------------[ Get room number ]------------------------------------------- +
- +
-;Gets room number at current map position. Sets carry flag if room # at map position is FF. +
-;If valid room number, the room number is stored in $5A. +
- +
-GetRoomNum: +
-LE720:  lda ScrollDir                   ; +
-LE722:  lsr                             ;Branch if scrolling vertical. +
-LE723:  beq +                           ; +
- +
-LE725:  rol                             ;Restore value of a +
-LE726:  adc #$FF                        ;A=#$01 if scrolling left, A=#$02 if scrolling right. +
-LE728:  pha                             ;Save A. +
-LE729:  jsr OnNameTable0                ;($EC93)Y=1 if name table=0, Y=0 if name table=3. +
-LE72C:  pla                             ;Restore A. +
-LE72D:  and $006C,                    ; +
-LE730:  sec                             ; +
-LE731:  bne +++++                       ;Can't load room, a door is in the way. This has the--> +
-                                        ;effect of stopping the scrolling until Samus walks--> +
-                                        ;through the door(horizontal scrolling only). +
- +
-LE733:* lda MapPosY                     ;Map pos y. +
-LE735:  jsr Amul16                      ;($C2C5)Multiply by 16. +
-LE738:  sta $00                         ;Store multiplied value in $00. +
-LE73A:  lda #$00                        ; +
-LE73C:  rol                             ;Save carry, if any. +
-LE73D:  rol $00                         ;Multiply value in $00 by 2. +
-LE73F:  rol                             ;Save carry, if any. +
-LE740:  sta $01                         ; +
-LE742:  lda $00                         ; +
-LE744:  adc MapPosX                     ;Add map pos X to A. +
-LE746:  sta $00                         ;Store result. +
-LE748:  lda $01                         ; +
-LE74A:  adc #$70                        ;Add #$7000 to result. +
-LE74C:  sta $01                         ;$0000 = (MapY*32)+MapX+#$7000. +
-LE74E:  ldy #$00                        ; +
-LE750:  lda ($00),                    ;Load room number. +
-LE752:  cmp #$FF                        ;Is it unused?--> +
-LE754:  beq ++++                        ;If so, branch to exit with carry flag set. +
- +
-LE756:  sta RoomNumber                  ;Store room number. +
- +
-LE758:* cmp $95D0,                    ;Is it a special room?--> +
-LE75B:  beq +                           ;If so, branch to set flag to play item room music. +
-LE75D:  iny                             ; +
-LE75E:  cpy #$07                        ; +
-LE760:  bne -                           ;Loop until all special room numbers are checked. +
- +
-LE762:  lda ItemRoomMusicStatus         ;Load item room music status. +
-LE764:  beq ++                          ;Branch if not in special room. +
-LE766:  lda #$80                        ;Ptop playing item room music after next music start. +
-LE768:  bne ++                          ;Branch always. +
- +
-LE76A:* lda #$01                        ;Start item room music on next music start. +
-LE76C:* sta ItemRoomMusicStatus         ; +
-LE76E:  clc                             ;Clear carry flag. was able to get room number. +
-LE76F:* rts                             ; +
- +
-;----------------------------------------------------------------------------------------------------- +
- +
-LE770:  ldx PageIndex +
-        lda EnRadY,x +
-        clc +
-        adc #$08 +
-        jmp LE783 +
- +
-LE77B:  ldx PageIndex +
-        lda #$00 +
-        sec +
-        sbc EnRadY,x +
-LE783:  sta $02 +
-        lda #$08 +
-        sta $04 +
-        jsr LE792 +
-        lda EnRadX,x +
-        jmp LE7BD +
- +
-LE792:  lda EnXRoomPos,+
-        sta $09     ; X coord +
-        lda EnYRoomPos,+
-        sta $08     ; Y coord +
-        lda EnNameTable,+
-        sta $0B     ; hi coord +
-        rts +
- +
-CheckMoveUp: +
-LE7A2:  ldx PageIndex +
-        lda ObjRadY,x +
-        clc +
-        adc #$08 +
-        jmp + +
- +
-CheckMoveDown: +
-        ldx PageIndex +
-        lda #$00 +
-        sec +
-        sbc ObjRadY,x +
-*       sta $02 +
-        jsr LE8BE +
-        lda ObjRadX,x +
-LE7BD:  bne + +
-        sec +
-        rts +
- +
-*       sta $03 +
-        tay +
-        ldx #$00 +
-        lda $09 +
-        sec +
-        sbc $03 +
-        and #$07 +
-        beq + +
-        inx +
-*       jsr LE8CE +
-        sta $04 +
-        jsr LE90F +
-        ldx #$00 +
-        ldy #$08 +
-        lda $00 +
-LE7DE:  bne +++ +
-        stx $06 +
-        sty $07 +
-        ldx $04 +
- +
-; object<-->background crash detection +
- +
-LE7E6:  jsr MakeCartRAMPtr              ;($E96A)Find object position in room RAM. +
-        ldy #$00 +
-        lda ($04),    ; get tile value +
-        cmp #$4E +
-        beq LE81E +
-        jsr $95C0 +
-        jsr LD651 +
-        bcc Exit16      ; CF = 0 if tile # < $80 (solid tile)... CRASH!!! +
-        cmp #$A0        ; is tile >= A0h? (walkable tile) +
-        bcs IsWalkableTile +
-        jmp IsBlastTile  ; tile is $80-$9F (blastable tiles) +
- +
-IsWalkableTile: +
-        ldy IsSamus +
-        beq ++ +
-    ; special case for Samus +
-        dey          ; = 0 +
-        sty SamusDoorData +
-        cmp #$A0        ; crash with tile #$A0? (scroll toggling door) +
-        beq + +
-        cmp #$A1        ; crash with tile #$A1? (horizontal scrolling door) +
-        bne ++ +
-        inc SamusDoorData +
-*       inc SamusDoorData +
-*       dex +
-        beq + +
-        jsr LE98E +
-        jmp LE7E6 +
- +
-*       sec          ; no crash +
-        Exit16: +
-        rts +
- +
-LE81E:  ldx UpdatingProjectile +
-        beq ClcExit +
-        ldx #$06 +
-*       lda $05 +
-        eor $5D,x +
-        and #$04 +
-        bne +++ +
-        lda $04 +
-        eor $5C,x +
-        and #$1F +
-        bne +++ +
-        txa +
-        jsr Amul8       ; * 8 +
-        ora #$80 +
-        tay +
-        lda ObjAction,+
-        beq +++ +
-        lda $0307,y +
-        lsr +
-        bcs ++ +
-        ldx PageIndex +
-        lda ObjAction,+
-        eor #$0B +
-        beq + +
-        lda ObjAction,+
-        eor #$04 +
-        bne PlaySnd4 +
-        lda AnimResetIndex,+
-        eor #$91 +
-        bne PlaySnd4 +
-*       lda $0683 +
-        ora #$02 +
-        sta $0683 +
-*       lda #$04 +
-        sta $030A,y +
-        bne ClcExit +
-*       dex +
-        dex +
-        bpl ---- +
-        lda $04 +
-        jsr Adiv8       ; / 8 +
-        and #$01 +
-        tax +
-        inc $0366,x +
- +
-ClcExit: +
-        clc +
-        rts +
- +
-PlaySnd4: +
-        jmp SFX_Metal +
- +
-CheckMoveLeft: +
-        ldx PageIndex +
-        lda ObjRadX,x +
-        clc +
-        adc #$08 +
-        jmp + +
- +
-CheckMoveRight: +
-        ldx PageIndex +
-        lda #$00 +
-        sec +
-        sbc ObjRadX,x +
-*       sta $03 +
-        jsr LE8BE +
-        ldy ObjRadY,x +
-LE89B:  bne + +
-        sec +
-        rts +
- +
-*       sty $02 +
-        ldx #$00 +
-        lda $08 +
-        sec +
-        sbc $02 +
-        and #$07 +
-        beq + +
-        inx +
-*       jsr LE8CE +
-        sta $04 +
-        jsr LE90F +
-        ldx #$08 +
-        ldy #$00 +
-        lda $01 +
-        jmp LE7DE +
- +
-LE8BE:  lda ObjectHi,+
-        sta $0B +
-        lda ObjectY,x +
-        sta $08 +
-        lda ObjectX,x +
-        sta $09 +
-        rts +
- +
-LE8CE:  eor #$FF +
-        clc +
-        adc #$01 +
-        and #$07 +
-        sta $04 +
-        tya +
-        asl +
-        sec +
-        sbc $04 +
-        bcs + +
-        adc #$08 +
-*       tay +
-        lsr +
-        lsr +
-        lsr +
-        sta $04 +
-        tya +
-        and #$07 +
-        beq + +
-        inx +
-*       txa +
-        clc +
-        adc $04 +
-        rts +
- +
-LE8F1:  ldx PageIndex +
-        lda EnRadX,x +
-        clc +
-        adc #$08 +
-        jmp LE904 +
- +
-LE8FC:  ldx PageIndex +
-        lda #$00 +
-        sec +
-        sbc EnRadX,x +
-LE904:  sta $03 +
-        jsr LE792 +
-        ldy EnRadY,x +
-        jmp LE89B +
- +
-LE90F:  lda $02 +
-        bpl ++ +
-        jsr LE95F +
-        bcs + +
-        cpx #$F0 +
-        bcc +++ +
-*       txa +
-        adc #$0F +
-        jmp LE934 +
- +
-*       jsr LE95F +
-        lda $08 +
-        sec +
-        sbc $02 +
-        tax +
-        and #$07 +
-        sta $00 +
-        bcs + +
-        txa +
-        sbc #$0F +
-LE934:  tax +
-        lda ScrollDir +
-        and #$02 +
-        bne + +
-        inc $0B +
-*       stx $02 +
-        ldx #$00 +
-        lda $03 +
-        bmi + +
-        dex +
-*       lda $09 +
-        sec +
-        sbc $03 +
-        sta $03 +
-        and #$07 +
-        sta $01 +
-        txa +
-        adc #$00 +
-        beq + +
-        lda ScrollDir +
-        and #$02 +
-        beq + +
-        inc $0B +
-*       rts +
- +
-LE95F:  lda $08 +
-        sec +
-        sbc $02 +
-        tax +
-        and #$07 +
-        sta $00 +
-        rts +
- +
-;------------------------------------[ Object pointer into cart RAM ]------------------------------- +
- +
-;Find object's equivalent position in room RAM based on object's coordinates. +
-;In: $02 = ObjectY, $03 = ObjectX, $0B = ObjectHi. Out: $04 = cart RAM pointer. +
- +
-MakeCartRAMPtr: +
-LE96A:  lda #$18                        ;Set pointer to $6xxx(cart RAM). +
-LE96C:  sta $05                         ; +
-LE96E:  lda $02                         ;Object Y room position. +
-LE970:  and #$F8                        ;Drop 3 LSBs. Only use multiples of 8. +
-LE972:  asl                             ; +
-LE973:  rol $05                         ; +
-LE975:  asl                             ;Move upper 2 bits to lower 2 bits of $05 and move y bits--> +
-LE976:  rol $05                         ;3, 4, 5 to upper 3 bits of $04. +
-LR978:  sta $04                         ; +
-LE97A:  lda $03                         ;Object X room position. +
-LE97C:  lsr                             ; +
-LE97D:  lsr                             ; +
-LE97E:  lsr                             ;A=ObjectX/8. +
-LE97F:  ora $04                         ; +
-LE981:  sta $04                         ;Put bits 0 thru 4 into $04. +
-LE983:  lda $0B                         ;Object nametable. +
-LE985:  asl                             ; +
-LE986:  asl                             ; A=ObjectHi*4. +
-LE987:  and #$04                        ;Set bit 2 if object is on nametable 3. +
-LE989:  ora $05                         ; +
-LE98B:  sta $05                         ;Include nametable bit in $05. +
-LE98D:  rts                             ;Return pointer in $04 = 01100HYY YYYXXXXX. +
- +
-;--------------------------------------------------------------------------------------------------- +
- +
-LE98E:  lda $02 +
-        clc +
-        adc $06 +
-        sta $02 +
-        cmp #$F0 +
-        bcc + +
-        adc #$0F +
-        sta $02 +
-        lda ScrollDir +
-        and #$02 +
-        bne + +
-        inc $0B +
-*       lda $03 +
-        clc +
-        adc $07 +
-        sta $03 +
-        bcc + +
-        lda ScrollDir +
-        and #$02 +
-        beq + +
-        inc $0B +
-*       rts +
- +
-LE9B7:  lda PPUCNT0ZP +
-        eor #$03 +
-        sta PPUCNT0ZP +
-        rts +
- +
-IsBlastTile: +
-        ldy UpdatingProjectile +
-        beq Exit18 +
-LE9C2:  tay +
-        jsr $95BD +
-        cpy #$98 +
-        bcs +++++ +
-; attempt to find a vacant tile slot +
-        ldx #$C0 +
-*       lda TileRoutine,+
-        beq +                           ; 0 = free slot +
-        jsr Xminus16 +
-        bne - +
-        lda TileRoutine,+
-        bne ++++                        ; no more slots, can't blast tile +
-*       inc TileRoutine,+
-        lda $04 +
-        and #$DE +
-        sta TileWRAMLo,+
-        lda $05 +
-        sta TileWRAMHi,+
-        lda InArea +
-        cmp #$11                        ; In Norfair? +
-        bne + +
-        cpy #$76                        ; Special case for the four-small-bubbles breakable block +
-        bne + +
-        lda #$04 +
-        bne ++ +
-*       tya                             ; Destroyed block ID +
-        clc +
-        adc #$10 +
-        and #$3C +
-        lsr +
-*       lsr +
-        sta TileType,+
-*       clc +
-Exit18: rts +
- +
-;------------------------------------------[ Select room RAM ]--------------------------------------- +
- +
-SelectRoomRAM: +
-LEA05:  jsr GetNameTable                ;($EB85)Find name table to draw room on. +
-LEA08:  asl                             ; +
-LEA09:  asl                             ; +
-LEA0A:  ora #$60                        ;A=#$64 for name table 3, A=#$60 for name table 0. +
-LEA0C:  sta CartRAMPtr+1                ; +
-LEA0E:  lda #$00                        ; +
-LEA10:  sta CartRAMPtr                  ;Save two byte pointer to start of proper room RAM. +
-LEA12:  rts                             ; +
- +
-;------------------------------------[ write attribute table data ]---------------------------------- +
- +
-AttribTableWrite: +
-LEA13:* lda RoomNumber                  ; +
-LEA15:  and #$0F                        ;Determine what row of PPU attribute table data, if any,--> +
-LEA17:  inc RoomNumber                  ;to load from RoomRAM into PPU. +
-LEA19:  jsr ChooseRoutine               ; +
- +
-;The following table is used by the code above to determine when to write to the PPU attribute table. +
- +
-LEA1c:  .word ExitSub                   ;($C45C)Rts. +
-LEA1E:  .word WritePPUAttribTbl         ;($E5E2)Write first row of PPU attrib data. +
-LEA20:  .word ExitSub                   ;($C45C)Rts. +
-LEA22:  .word WritePPUAttribTbl         ;($E5E2)Write second row of PPU attrib data. +
-LEA24:  .word RoomFinished              ;($EA26)Finished writing attribute table data. +
- +
-;-----------------------------------[ Finished writing room data ]----------------------------------- +
- +
-RoomFinished: +
-LEA26:  lda #$FF                        ;No more tasks to perform on current room.--> +
-LEA28:  sta RoomNumber                  ;Set RoomNumber to #$FF. +
-LEA2A:* rts                             ; +
- +
-;------------------------------------------[ Setup room ]-------------------------------------------- +
- +
-SetupRoom: +
-LEA2B:  lda RoomNumber                  ;Room number. +
-LEA2D:  cmp #$FF                        ; +
-LEA2F:  beq -                           ;Branch to exit if room is undefined. +
-LEA31:  cmp #$FE                        ; +
-LEA33:  beq +                           ;Branch if empty place holder byte found in room data. +
-LEA35:  cmp #$F0                        ; +
-LEA37:  bcs --                          ;Branch if time to write PPU attribute table data. +
-LEA39:  jsr UpdateRoomSpriteInfo        ;($EC9B)Update which sprite belongs on which name table. +
- +
-LEA3C:  jsr ScanForItems                ;($ED98)Set up any special items. +
-LEA3F:  lda RoomNumber                  ;Room number to load. +
-LEA41:  asl                             ;*2(for loading address of room pointer). +
-LEA42:  tay                             ; +
-LEA43:  lda (RoomPtrTable),           ;Low byte of 16-bit room pointer.--> +
-LEA45:  sta RoomPtr                     ;Base copied from $959A to $3B. +
-LEA47:  iny                             ; +
-LEA48:  lda (RoomPtrTable),           ;High byte of 16-bit room pointer.--> +
-LEA4A:  sta RoomPtr+1                   ;Base copied from $959B to $3C. +
-LEA4C:  ldy #$00                        ; +
-LEA4E:  lda (RoomPtr),                ;First byte of room data. +
-LEA50:  sta RoomPal                     ;store initial palette # to fill attrib table with. +
-LEA52:  lda #$01                        ; +
-LEA54:  jsr AddToRoomPtr                ;($EAC0)Increment room data pointer. +
-LEA57:  jsr SelectRoomRAM               ;($EA05)Determine where to draw room in RAM, $6000 or $6400. +
-LEA5A:  jsr InitTables                  ;($EFF8)clear Name Table & do initial Attrib table setup. +
-LEA5D:* jmp DrawRoom                    ;($EAAA)Load room contents into room RAM. +
- +
-;---------------------------------------[ Draw room object ]----------------------------------------- +
- +
-DrawObject: +
-LEA60:  sta $0E                         ;Store object position byte(%yyyyxxxx). +
-LEA62:  lda CartRAMPtr                  ; +
-LEA64:  sta CartRAMWorkPtr              ;Set the working pointer equal to the room pointer--> +
-LEA66:  lda CartRAMPtr+1                ;(start at beginning of the room). +
-LEA68:  sta CartRAMWorkPtr+1            ; +
-LEA6A:  lda $0E                         ;Reload object position byte. +
-LEA6C:  jsr Adiv16                      ;($C2BF)/16. Lower nibble contains object y position.--> +
-LEA6F:  tax                             ;Transfer it to X, prepare for loop. +
-LEA70:  beq +++                         ;Skip y position calculation loop as y position=0 and--> +
-                                        ;does not need to be calculated. +
-LEA72:* lda CartRAMWorkPtr              ;LoW byte of pointer working in room RAM. +
-LEA74:  clc                             ; +
-LEA75:  adc #$40                        ;Advance two rows in room RAM(one y unit). +
-LEA77:  sta CartRAMWorkPtr              ; +
-LEA79:  bcc +                           ;If carry occurred, increment high byte of pointer--> +
-LEA7B:  inc CartRAMWorkPtr+1            ;in room RAM. +
-LEA7D:* dex                             ; +
-LEA7E:  bne --                          ;Repeat until at desired y position(X=0). +
- +
-LEA80:* lda $0E                         ;Reload object position byte. +
-LEA82:  and #$0F                        ;Remove y position upper nibble. +
-LEA84:  asl                             ;Each x unit is 2 tiles. +
-LEA85:  adc CartRAMWorkPtr              ; +
-LEA87:  sta CartRAMWorkPtr              ;Add x position to room RAM work pointer. +
-LEA89:  bcc +                           ;If carry occurred, increment high byte of room RAM work--> +
-LEA8B:  inc CartRAMWorkPtr+1            ;pointer, else branch to draw object. +
- +
-;CartRAMWorkPtr now points to the object's starting location (upper left corner) +
-;on the room RAM which will eventually be loaded into a name table. +
- +
-LEA8D:* iny                             ;Move to the next byte of room data which is--> +
-LEA8E:  lda (RoomPtr),                ;the index into the structure pointer table. +
-LEA90:  tax                             ;Transfer structure pointer index into X. +
-LEA91:  iny                             ;Move to the next byte of room data which is--> +
-LEA92:  lda (RoomPtr),                ;the attrib table info for the structure. +
-LEA94:  sta ObjectPal                   ;Save attribute table info. +
-LEA96:  txa                             ;Restore structure pointer to A. +
-LEA97:  asl                             ;*2. Structure pointers are two bytes in size. +
-LEA98:  tay                             ; +
-LEA99:  lda (StructPtrTable),         ;Low byte of 16-bit structure ptr. +
-LEA9B:  sta StructPtr                   ; +
-LEA9D:  iny                             ; +
-LEA9E:  lda (StructPtrTable),         ;High byte of 16-bit structure ptr. +
-LEAA0:  sta StructPtr+1                 ; +
-LEAA2:  jsr DrawStruct                  ;($EF8C)Draw one structure. +
-LEAA5:  lda #$03                        ;Move to next set of structure data. +
-LEAA7:  jsr AddToRoomPtr                ;($EAC0)Add A to room data pointer. +
- +
-;-------------------------------------------[ Draw room ]-------------------------------------------- +
- +
-;The following function draws a room in the room RAM which is eventually loaded into a name table. +
- +
-DrawRoom: +
-LEAAA:  ldy #$00                        ;Zero index. +
-LEAAC:  lda (RoomPtr),                ;Load byte of room data.--> +
-LEAAE:  cmp #$FF                        ;Is it #$FF(end-of-room)?--> +
-LEAB0:  beq EndOfRoom                   ;If so, branch to exit. +
-LEAB2:  cmp #$FE                        ;Place holder for empty room objects(not used). +
-LEAB4:  beq +                           ; +
-LEAB6:  cmp #$FD                        ;is A=#$FD(end-of-objects)?--> +
-LEAB8:  bne DrawObject                  ;If not, branch to draw room object.--> +
-LEABA:  beq EndOfObjs                   ;Else branch to set up enemies/doors. +
-LEABC:* sta RoomNumber                  ;Store #$FE if room object is empty. +
-LEABE:  lda #$01                        ;Prepare to increment RoomPtr. +
- +
-;-------------------------------------[ Add A to room pointer ]-------------------------------------- +
- +
-AddToRoomPtr: +
-LEAC0:  clc                             ;Prepare to add index in A to room pointer. +
-LEAC1:  adc RoomPtr                     ; +
-LEAC3:  sta RoomPtr                     ; +
-LEAC5:  bcc +                           ;Did carry occur? If not branch to exit. +
-LEAC7:  inc RoomPtr+1                   ;Increment high byte of room pointer if carry occured. +
-LEAC9:* rts                             ; +
- +
-;---------------------------------------------------------------------------------------------------- +
- +
-EndOfObjs: +
-LEACA:  lda RoomPtr                     ; +
-LEACC:  sta $00                         ;Store room pointer in $0000. +
-LEACE:  lda RoomPtr+1                   ; +
-LEAD0:  sta $01                         ; +
-LEAD2:  lda #$01                        ;Prepare to increment to enemy/door data. +
- +
-EnemyLoop: +
-LEAD4:  jsr AddToPtr00                  ;($EF09)Add A to pointer at $0000. +
-LEAD7:  ldy #$00                        ; +
-LEAD9:  lda ($00),                    ;Get first byte of enemy/door data. +
-LEADB:  cmp #$FF                        ;End of enemy/door data?--> +
-LEADD:  beq EndOfRoom                   ;If so, branch to finish room setup. +
-LEADF:  and #$0F                        ;Discard upper four bits of data. +
-LEAE1:  jsr ChooseRoutine               ;Jump to proper enemy/door handling routine. +
- +
-;Pointer table to code. +
- +
-LEAE4:  .word ExitSub                   ;($C45C)Rts. +
-LEAE6:  .word LoadEnemy                 ;($EB06)Room enemies. +
-LEAE8:  .word LoadDoor                  ;($EB8C)Room doors. +
-LEAEA:  .word ExitSub                   ;($C45C)Rts. +
-LEAEC:  .word LoadElevator              ;($EC04)Elevator. +
-LEAEE:  .word ExitSub                   ;($C45C)Rts. +
-LEAF0:  .word LoadStatues               ;($EC2F)Kraid & Ridley statues. +
-LEAF2:  .word ZebHole                   ;($EC57)Regenerating enemies(such as Zeb). +
- +
-EndOfRoom: +
-LEAF4:  ldx #$F0                        ;Prepare for PPU attribute table write. +
-        stx RoomNumber                  ; +
-        lda ScrollDir                   ; +
-        sta TempScrollDir               ;Make temp copy of ScrollDir. +
-        and #$02                        ;Check if scrolling left or right. +
-        bne +                           ; +
-        jmp LE57C +
-*       jmp LE70C +
- +
-LoadEnemy: +
-LEB06:  jsr GetEnemyData                ;($EB0C)Get enemy data from room data. +
-LEB09:  jmp EnemyLoop                   ;($EAD4)Do next room object. +
- +
-GetEnemyData: +
-LEB0C:  lda ($00),                    ;Get 1st byte again. +
-        and #$F0                        ;Get object slot that enemy will occupy. +
-        tax                             ; +
-        jsr IsSlotTaken                 ;($EB7A)Check if object slot is already in use. +
-        bne ++                          ;Exit if object slot taken. +
-        iny                             ; +
-        lda ($00),                    ;Get enemy type. +
-        jsr GetEnemyType                ;($EB28)Load data about enemy. +
-        ldy #$02                        ; +
-        lda ($00),                    ;Get enemy initial position(%yyyyxxxx). +
-        jsr LEB4D +
-        pha +
-*       pla +
-*       lda #$03                        ;Number of bytes to add to ptr to find next room item. +
-        rts                             ; +
- +
-GetEnemyType: +
-LEB28:  pha                             ;Store enemy type. +
-        and #$C0                        ;If MSB is set, the "tough" version of the enemy   +
-        sta EnSpecialAttribs,         ;is to be loaded(more hit points, except rippers). +
-        asl                             ; +
-        bpl ++                          ;If bit 6 is set, the enemy is either Kraid or Ridley. +
-        lda InArea                      ;Load current area Samus is in(to check if Kraid or--> +
-        and #$06                        ;Ridley is alive or dead). +
-        lsr                             ;Use InArea to find status of Kraid/Ridley statue. +
-        tay                             ; +
-        lda MaxMissiles,              ;Load status of Kraid/Ridley statue. +
-        beq +                           ;Branch if Kraid or Ridley needs to be loaded. +
-        pla                             ; +
-        pla                             ;Mini boss is dead so pull enemy info and last address off--> +
-        jmp --                          ;stack so next enemy/door item can be loaded. +
- +
-*       lda #$01                        ;Samus is in Kraid or Ridley's room and the--> +
-        sta KraidRidleyPresent          ;mini boss is alive and needs to be loaded. +
- +
-*       pla                             ;Restore enemy type data. +
-        and #$3F                        ;Keep 6 lower bits to use as index for enemy data tables. +
-        sta EnDataIndex,              ;Store index byte. +
-        rts                             ; +
- +
-LEB4D:  tay                             ;Save enemy position data in Y. +
-        and #$F0                        ;Extract Enemy y position. +
-        ora #$08                        ;Add 8 pixels to y position so enemy is always on screen.  +
-        sta EnYRoomPos,               ;Store enemy y position. +
-        tya                             ;Restore enemy position data. +
-        jsr Amul16                      ;*16 to extract enemy x position. +
-        ora #$0C                        ;Add 12 pixels to x position so enemy is always on screen. +
-        sta EnXRoomPos,               ;Store enemy x position. +
-        lda #$01                        ; +
-        sta EnStatus,                 ;Indicate object slot is taken. +
-        lda #$00 +
-        sta $0404,x +
-        jsr GetNameTable                ;($EB85)Get name table to place enemy on. +
-        sta EnNameTable,              ;Store name table. +
-        ldy EnDataIndex,              ;Load A with index to enemy data. +
-        asl $0405,                    ;*2 +
-        jsr LFB7B +
-        jmp LF85A +
- +
-IsSlotTaken: +
-LEB7A:  lda EnStatus,+
-        beq + +
-        lda $0405,x +
-        and #$02 +
-*       rts +
- +
-;------------------------------------------[ Get name table ]---------------------------------------- +
- +
-;The following routine is small but is called by several other routines so it is important and +
-;requires some explaining to understand its function.  First of all, as Samus moves from one room +
-;to the next, she is also moving from one name table to the next.  Samus does not move from one +
-;name table to the next as one might think. Samus moves diagonally through the name tables. To +
-;understand this concept, one must first know how the name tables are arranged.  They are arranged +
-;like so: +
-+
-; +-----+-----+                                                  +-----+-----+ +
-; |         | The following is an incorrect example of how             | +
-; |  2  |  3  | Samus goes from one name table to the next-----> |  2  |  3  | +
-; |                                                          |         | +
-; +-----+-----+                                                  +-----+-----+ +
-; |                                                          |         | +
-; |  0  |  1  |                               INCORRECT!------>  |  0<-|->+
-; |                                                          |         | +
-; +-----+-----+                                                  +-----+-----+ +
-+
-;The following are examples of how the name tables are properly traversed while walking through rooms: +
-+
-;          +-----+-----+                                     +-----+-----+ +
-;          |                                                     | +
-;          |  2  | ->3 |                                      2  |  3<-|-+ +
-;          |     |/    |                                             | | +
-;          +-----+-----+     <--------CORRECT!-------->      +-----+-----+ | +
-;          |    /|                                                 | | +
-;          | 0<- |  1  |                                   +-|-> |  1  | | +
-;          |                                           | |         | | +
-;          +-----+-----+                                   | +-----+-----+ | +
-;                                                          +---------------+ +
-+
-;The same diagonal traversal of the name tables illustrated above applies to vetricle traversal as +
-;well. Since Samus can only travel between 2 name tables and not 4, the name table placement for +
-;objects is simplified.  The following code determines which name table to use next: +
- +
-GetNameTable: +
-LEB85:  lda PPUCNT0ZP                   ; +
-LEB87:  eor ScrollDir                   ;Store #$01 if object should be loaded onto name table 3--> +
-LEB89:  and #$01                        ;store #$00 if it should be loaded onto name table 0. +
-LEB8B:  rts                             ; +
- +
-;---------------------------------------------------------------------------------------------------- +
- +
-; LoadDoor +
-; ======== +
- +
-        LoadDoor: +
-        jsr LEB92 +
-*       jmp EnemyLoop    ; do next room object +
- +
-LEB92:  iny +
-        lda ($00),    ; door info byte +
-        pha +
-        jsr Amul16      ; CF = door side (0=right, 1=left) +
-        php +
-        lda MapPosX +
-        clc +
-        adc MapPosY +
-        plp +
-        rol +
-        and #$03 +
-        tay +
-        ldx $EC00,y +
-        pla          ; retrieve door info +
-        and #$03 +
-        sta $0307,    ; door palette +
-        tya +
-        pha +
-        lda $0307,x +
-        cmp #$01 +
-        beq ++ +
-        cmp #$03 +
-        beq ++ +
-        lda #$0A +
-        sta $09 +
-        ldy MapPosX +
-        txa +
-        jsr Amul16       ; * 16 +
-        bcc + +
-        dey +
-*       tya +
-        jsr LEE41 +
-        jsr LEE4A +
-        bcs ++ +
-*       lda #$01 +
-        sta ObjAction,+
-*       pla +
-        and #$01        ; A = door side (0=right, 1=left) +
-        tay +
-        jsr GetNameTable                ;($EB85) +
-        sta ObjectHi,+
-        lda DoorXs,   ; get door's X coordinate +
-        sta ObjectX,x +
-        lda #$68        ; door Y coord is always #$68 +
-        sta ObjectY,x +
-        lda LEBFE,y +
-        tay +
-        jsr GetNameTable                ;($EB85) +
-        eor #$01 +
-        tax +
-        tya +
-        ora DoorOnNameTable3,+
-        sta DoorOnNameTable3,+
-        lda #$02 +
-        rts +
- +
-DoorXs: +
-        .byte $F0        ; X coord of RIGHT door +
-        .byte $10        ; X coord of LEFT door +
-LEBFE:  .byte $02 +
-        .byte $01 +
-LEC00:  .byte $80 +
-        .byte $B0 +
-        .byte $A0 +
-        .byte $90 +
- +
-; LoadElevator +
-; ============ +
- +
-        LoadElevator: +
-        jsr LEC09 +
-        bne ----           ; branch always +
- +
-LEC09:  lda ElevatorStatus +
-        bne +      ; exit if elevator already present +
-        iny +
-        lda ($00),y +
-        sta $032F +
-        ldy #$83 +
-        sty $032D       ; elevator Y coord +
-        lda #$80 +
-        sta $032E       ; elevator X coord +
-        jsr GetNameTable                ;($EB85) +
-        sta $032C       ; high Y coord +
-        lda #$23 +
-        sta $0323       ; elevator frame +
-        inc ElevatorStatus              ;1 +
-*       lda #$02 +
-        rts +
- +
-; LoadStatues +
-; =========== +
- +
-        LoadStatues: +
-        jsr GetNameTable                ;($EB85) +
-        sta $036C +
-        lda #$40 +
-        ldx RidleyStatueStatus +
-        bpl +      ; branch if Ridley statue not hit +
-        lda #$30 +
-*       sta $0370 +
-        lda #$60 +
-        ldx KraidStatueStatus +
-        bpl +      ; branch if Kraid statue not hit +
-        lda #$50 +
-*       sta $036F +
-        sty $54 +
-        lda #$01 +
-        sta $0360 +
-*       jmp EnemyLoop   ; do next room object +
- +
-ZebHole: +
-LEC57:  ldx #$20 +
-*       txa +
-        sec +
-        sbc #$08 +
-        bmi + +
-        tax +
-        ldy $0728,x +
-        iny +
-        bne - +
-        ldy #$00 +
-        lda ($00),y +
-        and #$F0 +
-        sta $0729,x +
-        iny +
-        lda ($00),y +
-        sta $0728,x +
-        iny +
-        lda ($00),y +
-        tay +
-        and #$F0 +
-        ora #$08 +
-        sta $072A,x +
-        tya +
-        jsr Amul16       ; * 16 +
-        ora #$00 +
-        sta $072B,x +
-        jsr GetNameTable                ;($EB85) +
-        sta $072C,x +
-*       lda #$03 +
-        bne --- +
- +
-OnNameTable0: +
-LEC93:  lda PPUCNT0ZP                   ; +
-        eor #$01                        ;If currently on name table 0,--> +
-        and #$01                        ;return #$01. Else return #$00. +
-        tay                             ; +
-        rts                             ; +
- +
-UpdateRoomSpriteInfo: +
-LEC9B:  ldx ScrollDir +
-        dex +
-        ldy #$00 +
-        jsr UpdateDoorData              ;($ED51)Update name table 0 door data. +
-        iny +
-        jsr UpdateDoorData              ;($ED51)Update name table 3 door data. +
-        ldx #$50 +
-        jsr GetNameTable                ;($EB85) +
-        tay +
-*       tya +
-        eor EnNameTable,+
-        lsr +
-        bcs + +
-        lda $0405,x +
-        and #$02 +
-        bne + +
-        sta EnStatus,+
-*       jsr Xminus16 +
-        bpl -- +
-        ldx #$18 +
-*       tya +
-        eor $B3,x +
-        lsr +
-        bcs + +
-        lda #$00 +
-        sta $B0,x +
-*       txa +
-        sec +
-        sbc #$08 +
-        tax +
-        bpl -- +
-        jsr LED65 +
-        jsr LED5B +
-        jsr GetNameTable                ;(EB85) +
-        asl +
-        asl +
-        tay +
-        ldx #$C0 +
-*       tya +
-        eor TileWRAMHi,+
-        and #$04 +
-        bne + +
-        sta $0500,x +
-*       jsr Xminus16 +
-        cmp #$F0 +
-        bne -- +
-        tya +
-        lsr +
-        lsr +
-        tay +
-        ldx #$D0 +
-        jsr LED7A +
-        ldx #$E0 +
-        jsr LED7A +
-        ldx #$F0 +
-        jsr LED7A +
-        tya +
-        sec +
-        sbc $032C +
-        bne + +
-        sta ElevatorStatus +
-*       ldx #$1E +
-*       lda $0704,x +
-        bne + +
-        lda #$FF +
-        sta $0700,x +
-*       txa +
-        sec +
-        sbc #$06 +
-        tax +
-        bpl -- +
-        cpy $036C +
-        bne + +
-        lda #$00 +
-        sta $0360 +
-*       ldx #$18 +
-*       tya +
-        cmp $072C,x +
-        bne + +
-        lda #$FF +
-        sta $0728,x +
-*       txa +
-        sec +
-        sbc #$08 +
-        tax +
-        bpl -- +
-        ldx #$00 +
-        jsr LED8C +
-        ldx #$08 +
-        jsr LED8C +
-        jmp $95AE +
- +
-UpdateDoorData: +
-LED51:  txa                             ; +
-LED52:  eor #$03                        ; +
-LED54:  and $006C,                    ;Moves door info from one name table to the next--> +
-LED57:* sta $006C,                    ;when the room is transferred across name tables. +
-LED5A:  rts                             ; +
- +
-LED5B:  jsr GetNameTable                ;($EB85) +
-        eor #$01 +
-        tay +
-        lda #$00 +
-        beq - +
-LED65:  ldx #$B0 +
-*       lda ObjAction,+
-        beq + +
-        lda ObjectOnScreen,+
-        bne + +
-        sta ObjAction,+
-*       jsr Xminus16 +
-        bmi -- +
-        rts +
- +
-LED7A:  lda ObjAction,+
-        cmp #$05 +
-        bcc + +
-        tya +
-        eor ObjectHi,+
-        lsr +
-        bcs + +
-        sta ObjAction,+
-*       rts +
- +
-LED8C:  tya +
-        cmp PowerUpNameTable,+
-        bne Exit11 +
-        lda #$FF +
-        sta PowerUpType,+
-Exit11: rts +
- +
-;---------------------------------------[ Setup special items ]-------------------------------------- +
- +
-;The following routines look for special items on the game map and jump to +
-;the appropriate routine to handle those items. +
- +
-ScanForItems: +
-LED98:  lda SpecItmsTable               ;Low byte of ptr to 1st item data. +
-LED9B:  sta $00                         ; +
-LED9D:  lda SpecItmsTable+1             ;High byte of ptr to 1st item data. +
- +
-ScanOneItem: +
-LEDA0:  sta $01                         ; +
-LEDA2:  ldy #$00                        ;Index starts at #$00. +
-LEDA4:  lda ($00),                    ;Load map Ypos of item.--> +
-LEDA6:  cmp MapPosY                     ;Does it equal Samus' Ypos on map?--> +
-LEDA8:  beq +                           ;If yes, check Xpos too. +
- +
-LEDAA:  bcs Exit11                      ;Exit if item Y pos >  Samus Y Pos. +
-LEDAC:  iny                             ; +
-LEDAD:  lda ($00),                    ;Low byte of ptr to next item data. +
-LEDAF:  tax                             ; +
-LEDB0:  iny                             ; +
-LEDB1:  and ($00),                    ;AND with hi byte of item ptr. +
-LEDB3:  cmp #$FF                        ;if result is FFh, then this was the last item--> +
-LEDB5:  beq Exit11                      ;(item ptr = FFFF). Branch to exit. +
- +
-LEDB7:  lda ($00),                    ;High byte of ptr to next item data. +
-LEDB9:  stx $00                         ;Write low byte for next item. +
-LEDBB:  jmp ScanOneItem                 ;Process next item. +
- +
-LEDBE:* lda #$03                        ;Get ready to look at byte containing X pos. +
-LEDC0:  jsr AddToPtr00                  ;($EF09)Add 3 to pointer at $0000. +
- +
-ScanItemX: +
-LEDC3:  ldy #$00                        ; +
-LEDC5:  lda ($00),                    ;Load map Xpos of object.--> +
-LEDC7:  cmp MapPosX                     ;Does it equal Samus' Xpos on map?--> +
-LEDC9:  beq +                           ;If so, then load object. +
-LEDCB:  bcs Exit11                      ;Exit if item pos X > Samus Pos X. +
- +
-LEDCD:  iny                             ; +
-LEDCE:  jsr AnotherItem                 ;($EF00)Check for another item on same Y pos. +
-LEDD1:  jmp ScanItemX                   ;Try next X coord. +
- +
-LEDD4:* lda #$02                        ;Move ahead two bytes to find item data. +
- +
-ChooseHandlerRoutine: +
-LEDD6:  jsr AddToPtr00                  ;($EF09)Add A to pointer at $0000. +
-LEDD9:  ldy #$00                        ; +
-LEDDB:  lda ($00),                    ;Object type +
-LEDDD:  and #$0F                        ;Object handling routine index stored in 4 LSBs. +
-LEDDF:  jsr ChooseRoutine               ;($C27C)Load proper handling routine from table below. +
- +
-;Handler routines jumped to by above code. +
- +
-LEDE2:  .word ExitSub                   ;($C45C)rts. +
-LEDE4:  .word SqueeptHandler            ;($EDF8)Some squeepts. +
-LEDE6:  .word PowerUpHandler            ;($EDFE)power-ups. +
-LEDE8:  .word SpecEnemyHandler          ;($EE63)Special enemies(Mellows, Melias and Memus). +
-LEDEA:  .word ElevatorHandler           ;($EEA1)Elevators. +
-LEDEC:  .word CannonHandler             ;($EEA6)Mother brain room cannons. +
-LEDEE:  .word MotherBrainHandler        ;($EEAE)Mother brain. +
-LEDF0:  .word ZeebetiteHandler          ;($EECA)Zeebetites. +
-LEDF2:  .word RinkaHandler              ;($EEEE)Rinkas. +
-LEDF4:  .word DoorHandler               ;($EEF4)Some doors. +
-LEDF6:  .word PaletteHandler            ;($EEFA)Background palette change. +
- +
-;---------------------------------------[ Squeept handler ]------------------------------------------ +
- +
-SqueeptHandler: +
-LEDF8:  jsr GetEnemyData                ;($EB0C)Load Squeept data. +
-LEDFB:* jmp ChooseHandlerRoutine        ;($EDD6)Exit handler routines. +
- +
-;--------------------------------------[ Power-up Handler ]------------------------------------------ +
- +
-PowerUpHandler: +
-LEDFE:  iny                             ;Prepare to store item type. +
-LEDFF:  ldx #$00                        ; +
-LEE01:  lda #$FF                        ; +
-LEE03:  cmp PowerUpType                 ;Is first power-up item slot available?--> +
-LEE06:  beq +                           ;if yes, branch to load item. +
- +
-LEE08:  ldx #$08                        ;Prepare to check second power-up item slot. +
-LEE0A:  cmp PowerUpBType                ;Is second power-up item slot available?-->                      +
-LEE0D:  bne ++                          ;If not, branch to exit. +
-LEE0F:* lda ($00),                    ;Power-up item type. +
-LEE11:  jsr PrepareItemID               ;($EE3D)Get unique item ID. +
-LEE14:  jsr CheckForItem                ;($EE4A)Check if Samus already has item. +
-LEE17:  bcs +                           ;Samus already has item. do not load it. +
- +
-LEE19:  ldy #$02                        ;Prepare to load item coordinates. +
-LEE1B:  lda $09                         ; +
-LEE1D:  sta PowerUpType,              ;Store power-up type in available item slot. +
-LEE20:  lda ($00),                    ;Load x and y screen positions of item. +
-LEE22:  tay                             ;Save position data for later processing. +
-LEE23:  and #$F0                        ;Extract Y coordinate. +
-LEE25:  ora #$08                        ;+ 8 to find  Y coordinate center. +
-LEE27:  sta PowerUpYCoord,            ;Store center Y coord +
-LEE2A:  tya                             ;Reload position data. +
-LEE2B:  jsr Amul16                      ;($C2C5)*16. Move lower 4 bits to upper 4 bits. +
-LEE2E:  ora #$08                        ;+ 8 to find X coordinate center. +
-LEE30:  sta PowerUpXCoord,            ;Store center X coord +
-LEE33:  jsr GetNameTable                ;($EB85)Get name table to place item on. +
-LEE36:  sta PowerUpNameTable,         ;Store name table Item is located on. +
- +
-LEE39:* lda #$03                        ;Get next data byte(Always #$00). +
-LEE3B:  bne ---                         ;Branch always to exit handler routines. +
-         +
-PrepareItemID: +
-LEE3D:  sta $09                         ;Store item type. +
-LEE3E:  lda MapPosX                     ; +
- +
-LEE41:  sta $07                         ;Store item X coordinate. +
-LEE42:  lda MapPosY                     ; +
-LEE45:  sta $06                         ;Store item Y coordinate. +
-LEE47:  jmp CreateItemID                ;($DC67)Get unique item ID. +
- +
-CheckForItem: +
-LEE4A:  ldy NumberOfUniqueItems         ; +
-LEE4D:  beq +++                         ;Samus has no unique items. Load item and exit. +
-LEE4F:* lda $07                         ; +
-LEE51:  cmp NumberOfUniqueItems,      ;Look for lower byte of unique item. +
-LEE54:  bne +                           ; +
-LEE56:  lda $06                         ;Look for upper byte of unique item. +
-LEE58:  cmp DataSlot,                 ; +
-LEE5B:  beq +++                         ;Samus already has item. Branch to exit. +
-LEE5D:* dey                             ; +
-LEE5E:  dey                             ; +
-LEE5F:  bne --                          ;Loop until all Samus' unique items are checked. +
-LEE61:* clc                             ;Samus does not have the item. It will be placed on screen. +
-LEE62:* rts                             ; +
- +
-;----------------------------------------------------------------------------------------------------- +
- +
-SpecEnemyHandler: +
-LEE63:  ldx #$18 +
-        lda RandomNumber1 +
-        adc FrameCount +
-        sta $8A +
-*       jsr LEE86 +
-        txa +
-        sec +
-        sbc #$08 +
-        tax +
-        bpl - +
-        lda $95E4 +
-        sta $6BE9 +
-        sta $6BEA +
-        lda #$01 +
-        sta $6BE4 +
-*       jmp ChooseHandlerRoutine        ;($EDD6)Exit handler routines. +
- +
-LEE86:  lda $B0,x +
-        bne + +
-        txa +
-        adc $8A +
-        and #$7F +
-        sta $B1,x +
-        adc RandomNumber2 +
-        sta $B2,x +
-        jsr GetNameTable                ;($EB85) +
-        sta $B3,x +
-        lda #$01 +
-        sta $B0,x +
-        rol $8A +
-*       rts +
- +
-ElevatorHandler: +
-LEEA1:  jsr LEC09 +
-        bne --                          ;Branch always. +
- +
-CannonHandler: +
-LEEA6:  jsr $95B1 +
-        lda #$02 +
-*       jmp ChooseHandlerRoutine        ;($EDD6)Exit handler routines. +
- +
-MotherBrainHandler: +
-LEEAE:  jsr $95B4 +
-        lda #$38 +
-        sta $07 +
-        lda #$00 +
-        sta $06 +
-        jsr LEE4A +
-        bcc LEEC6 +
-        lda #$08 +
-        sta MotherBrainStatus +
-        lda #$00 +
-        sta MotherBrainHits +
-LEEC6:  lda #$01 +
-        bne - +
- +
-ZeebetiteHandler: +
-LEECA:  jsr $95B7 +
-        txa +
-        lsr +
-        adc #$3C +
-        sta $07 +
-        lda #$00 +
-        sta $06 +
-        jsr LEE4A +
-        bcc + +
-        lda #$81 +
-        sta $0758,x +
-        lda #$01 +
-        sta $075D,x +
-        lda #$07 +
-        sta $075B,x +
-*       jmp LEEC6 +
- +
-RinkaHandler: +
-LEEEE:  jsr $95BA +
-        jmp LEEC6 +
- +
-DoorHandler: +
-LEEF4:  jsr LEB92 +
-        jmp ChooseHandlerRoutine        ;($EDD6)Exit handler routines. +
- +
-PaletteHandler: +
-LEEFA:  lda ScrollDir +
-        sta $91 +
-        bne LEEC6 +
- +
-AnotherItem: +
-LEF00:  lda ($00),                    ;Is there another item with same Y pos?--> +
-        cmp #$FF                        ;If so, A is amount to add to ptr. to find X pos. +
-        bne AddToPtr00                  ;($EF09) +
-        pla                             ; +
-        pla                             ;No more items to check. Pull last subroutine--> +
-        rts                             ;off stack and exit. +
- +
-AddToPtr00: +
-LEF09:  clc                             ; +
-        adc $00                         ; +
-        sta $00                         ;A is added to the 16 bit address stored in $0000. +
-        bcc +                           ; +
-        inc $01                         ; +
-*       rts                             ; +
- +
-;----------------------------------[ Draw structure routines ]---------------------------------------- +
- +
-;Draws one row of the structure. +
-;A = number of 2x2 tile macros to draw horizontally. +
- +
-DrawStructRow: +
-LEF13:  and #$0F                        ;Row length(in macros). Range #$00 thru #$0F. +
-LEF15:  bne +                           ; +
-LEF17:  lda #$10                        ;#$00 in row length=16. +
-LEF19:* sta $0E                         ;Store horizontal macro count. +
-LEF1B:  lda (StructPtr),              ;Get length byte again. +
-LEF1D:  jsr Adiv16                      ;($C2BF)/16. Upper nibble contains x coord offset(if any). +
-LEF20:  asl                             ;*2, because a macro is 2 tiles wide. +
-LEF21:  adc CartRAMWorkPtr              ;Add x coord offset to CartRAMWorkPtr and save in $00. +
-LEF23:  sta $00                         ; +
-LEF25:  lda #$00                        ; +
-LEF27:  adc CartRAMWorkPtr+1            ;Save high byte of work pointer in $01. +
-LEF29:  sta $01                         ;$0000 = work pointer. +
- +
-DrawMacro: +
-LEF2B:  lda $01                         ;High byte of current location in room RAM. +
-LEF2D:  cmp #$63                        ;Check high byte of room RAM address for both room RAMs--> +
-LEF2F:  beq +                           ;to see if the attribute table data for the room RAM has--> +
-LEF31:  cmp #$67                        ;been reached.  If so, branch to check lower byte as well. +
-LEF33:  bcc ++                          ;If not at end of room RAM, branch to draw macro. +
-LEF35:  beq +                           ; +
-LEF37:  rts                             ;Return if have gone past room RAM(should never happen). +
- +
-LEF38:* lda $00                         ;Low byte of current nametable address. +
-LEF3A:  cmp #$A0                        ;Reached attrib table?--> +
-LEF3C:  bcc +                           ;If not, branch to draw the macro. +
-LEF3E:  rts                             ;Can't draw any more of the structure, exit. +
- +
-LEF3F:* inc $10                         ;Increase struct data index. +
-LEF41:  ldy $10                         ;Load struct data index into Y. +
-LEF43:  lda (StructPtr),              ;Get macro number. +
-LEF45:  asl                             ; +
-LEF46:  asl                             ;A=macro number * 4. Each macro is 4 bytes long. +
-LEF47:  sta $11                         ;Store macro index. +
-LEF49:  ldx #$03                        ;Prepare to copy four tile numbers. +
-LEF4B:* ldy $11                         ;Macro index loaded into Y. +
-LEF4D:  lda (MacroPtr),               ;Get tile number. +
-LEF4F:  inc $11                         ;Increase macro index +
-LEF51:  ldy TilePosTable,             ;get tile position in macro. +
-LEF54:  sta ($00),                    ;Write tile number to room RAM. +
-LEF56:  dex                             ;Done four tiles yet?--> +
-LEF57:  bpl -                           ;If not, loop to do another. +
-LEF59:  jsr UpdateAttrib                ;($EF9E)Update attribute table if necessary +
-LEF5C:  ldy #$02                        ;Macro width(in tiles). +
-LEF5E:  jsr AddYToPtr00                 ;($C2A8)Add 2 to pointer to move to next macro. +
-LEF61:  lda $00                         ;Low byte of current room RAM work pointer. +
-LEF63:  and #$1F                        ;Still room left in current row?--> +
-LEF65:  bne +                           ;If yes, branch to do another macro. +
- +
-;End structure row early to prevent it from wrapping on to the next row.. +
-LEF67:  lda $10                         ;Struct index. +
-LEF69:  clc                             ; +
-LEF6A:  adc $0E                         ;Add number of macros remaining in current row. +
-LEF6C:  sec                             ; +
-LEF6D:  sbc #$01                        ;-1 from macros remaining in current row. +
-LEF6F:  jmp AdvanceRow                  ;($EF78)Move to next row of structure. +
- +
-LEF72:* dec $0E                         ;Have all macros been drawn on this row?--> +
-LEF74:  bne DrawMacro                   ;If not, branch to draw another macro. +
-LEF76:  lda $10                         ;Load struct index. +
- +
-AdvanceRow: +
-LEF78:  sec                             ;Since carry bit is set,--> +
-LEF79:  adc StructPtr                   ;addition will be one more than expected. +
-LEF7B:  sta StructPtr                   ;Update the struct pointer. +
-LEF7D:  bcc +                           ; +
-LEF7F:  inc StructPtr+1                 ;Update high byte of struct pointer if carry occured. +
-LEF81:* lda #$40                        ; +
-LEF83:  clc                             ; +
-LEF84:  adc CartRAMWorkPtr              ;Advance to next macro row in room RAM(two tile rows). +
-LEF86:  sta CartRAMWorkPtr              ; +
-LEF88:  bcc DrawStruct                  ;Begin drawing next structure row. +
-LEF8A:  inc CartRAMWorkPtr+1            ;Increment high byte of pointer if necessary. +
- +
-DrawStruct: +
-LEF8C:  ldy #$00                        ;Reset struct index. +
-LEF8E:  sty $10                         ; +
-LEF90:  lda (StructPtr),              ;Load data byte. +
-LEF92:  cmp #$FF                        ;End-of-struct?--> +
-LEF94:  beq +                           ;If so, branch to exit. +
-LEF96:  jmp DrawStructRow               ;($EF13)Draw a row of macros. +
-LEF99:* rts                             ; +
- +
-;The following table is used to draw macros in room RAM. Each macro is 2 x 2 tiles. +
-;The following table contains the offsets required to place the tiles in each macro. +
- +
-TilePosTable: +
-LEF9A:  .byte $21                       ;Lower right tile. +
-LEF9B:  .byte $20                       ;Lower left tile. +
-LEF9C:  .byte $01                       ;Upper right tile. +
-LEF9D:  .byte $00                       ;Upper left tile. +
- +
-;---------------------------------[ Update attribute table bits ]------------------------------------ +
- +
-;The following routine updates attribute bits for one 2x2 tile section on the screen. +
- +
-UpdateAttrib: +
-LEF9E:  lda ObjectPal                   ;Load attribute data of structure. +
-LEFA0:  cmp RoomPal                     ;Is it the same as the room's default attribute data?--> +
-LEFA2:  beq +++++                       ;If so, no need to modify the attribute table, exit. +
- +
-;Figure out cart RAM address of the byte containing the relevant bits. +
- +
-LEFA4:  lda $00                         ; +
-LEFA6:  sta $02                         ; +
-LEFA8:  lda $01                         ; +
-LEFAA:  lsr                             ; +
-LEFAB:  ror $02                         ; +
-LEFAD:  lsr                             ; +
-LEFAE:  ror $02                         ; +
-LEFB0:  lda $02                         ;The following section of code calculates the--> +
-LEFB2:  and #$07                        ;proper attribute byte that corresponds to the--> +
-LEFB4:  sta $03                         ;macro that has just been placed in the room RAM. +
-LEFB6:  lda $02                         ; +
-LEFB8:  lsr                             ; +
-LEFB9:  lsr                             ; +
-LEFBA:  and #$38                        ; +
-LEFBC:  ora $03                         ; +
-LEFBE:  ora #$C0                        ; +
-LEFC0:  sta $02                         ; +
-LEFC2:  lda #$63                        ; +
-LEFC4:  sta $03                         ;$0002 contains pointer to attribute byte. +
- +
-LEFC6:  ldx #$00                        ; +
-LEFC8:  bit $00                         ; +
-LEFCA:  bvc +                           ; +
-LEFCC:  ldx #$02                        ;The following section of code figures out which--> +
-LEFCE:* lda $00                         ;pair of bits to modify in the attribute table byte--> +
-LEFD0:  and #$02                        ;for the macro that has just been placed in the--> +
-LEFD2:  beq +                           ;room RAM. +
-LEFD4:  inx                             ; +
- +
-;X now contains which macro attribute table bits to modify: +
-;+---+---+ +
-;| 0 | 1 | +
-;+---+---+ +
-;| 2 | 3 | +
-;+---+---+ +
-;Where each box represents a macro(2x2 tiles). +
- +
-;The following code clears the old attribute table bits and sets the new ones. +
-LEFD5:* lda $01                         ;Load high byte of work pointer in room RAM. +
-LEFD7:  and #$04                        ; +
-LEFD9:  ora $03                         ;Choose proper attribute table associated with the--> +
-LEFDB:  sta $03                         ;current room RAM. +
-LEFDD:  lda AttribMaskTable,          ;Choose appropriate attribute table bit mask from table below. +
-LEFE0:  ldy #$00                        ; +
-LEFE2:  and ($02),                    ;clear the old attribute table bits. +
-LEFE4:  sta ($02),                    ; +
-LEFE6:  lda ObjectPal                   ;Load new attribute table data(#$00 thru #$03). +
-LEFE8:* dex                             ; +
-LEFE9:  bmi +                           ; +
-LEFEB:  asl                             ; +
-LEFEC:  asl                             ;Attribute table bits shifted one step left +
-LEFED:  bcc -                           ;Loop until attribute table bits are in the proper location. +
-LEFEF:* ora ($02),                    ; +
-LEFF1:  sta ($02),                    ;Set attribute table bits. +
-LEFF3:* rts                             ; +
- +
-AttribMaskTable: +
-LEFF4:  .byte %11111100                 ;Upper left macro. +
-LEFF5:  .byte %11110011                 ;Upper right macro. +
-LEFF6:  .byte %11001111                 ;Lower left macro. +
-LEFF7:  .byte %00111111                 ;Lower right macro. +
- +
-;------------------------[ Initialize room RAM and associated attribute table ]----------------------- +
- +
-InitTables: +
-LEFF8:  lda CartRAMPtr+1                ;#$60 or #$64. +
-LEFFA:  tay                             ; +
-LEFFB:  tax                             ;Save value to create counter later. +
-LEFFC:  iny                             ; +
-LEFFD:  iny                             ;High byte of address to fill to ($63 or $67). +
-LEFFE:  iny                             ; +
-LEFFF:  lda #$FF                        ;Value to fill room RAM with. +
-LF001:  jsr FillRoomRAM                 ;($F01C)Fill entire RAM for designated room with #$FF. +
- +
-LF004:  ldx $01                         ;#$5F or #$63 depening on which room RAM was initialized. +
-LF006:  jsr Xplus4                      ;($E193)X = X + 4. +
-LF009:  stx $01                         ;Set high byte for attribute table write(#$63 or #$67). +
-LF00B:  ldx RoomPal                     ;Index into table below (Lowest 2 bits). +
-LF00D:  lda ATDataTable,              ;Load attribute table data from table below. +
-LF010:  ldy #$C0                        ;Low byte of start of all attribute tables. +
-LF012:* sta ($00),                    ;Fill attribute table. +
-LF014:  iny                             ; +
-LF015:  bne -                           ;Loop until entire attribute table is filled. +
-LF017:  rts                             ; +
- +
-ATDataTable:        +
-LF018:  .byte %00000000                 ; +
-LF019:  .byte %01010101                 ;Data to fill attribute tables with. +
-LF01A:  .byte %10101010                 ; +
-LF01B:  .byte %11111111                 ; +
- +
-FillRoomRAM: +
-LF01C:  pha                             ;Temporarily store A. +
-LF01D:  txa                             ; +
-LF01E:  sty $01                         ;Calculate value to store in X to use as upper byte--> +
-LF020:  clc                             ;counter for initilaizing room RAM(X=#$FC).--> +
-LF021:  sbc $01                         ;Since carry bit is cleared, result is one less than expected. +
-LF023:  tax                             ; +
-LF024:  pla                             ;Restore value to fill room RAM with(#$FF). +
-LF025:  ldy #$00                        ;Lower address byte to start at. +
-LF027:  sty $00                         ; +
-LF029:* sta ($00),                    ; +
-LF02B:  dey                             ; +
-LF02C:  bne -                           ; +
-LF02E:  dec $01                         ;Loop until all the room RAM is filled with #$FF(black). +
-LF030:  inx                             ; +
-LF031:  bne -                           ; +
-LF033:  rts                             ; +
- +
-;---------------------------------------------------------------------------------------------------- +
- +
-; Crash detection +
-; =============== +
- +
-LF034:  lda #$FF +
-        sta $73 +
-        sta $010F +
-; check for crash with Memus +
-        ldx #$18 +
-*      lda $B0,x +
-        beq +++++           ; branch if no Memu in slot +
-        cmp #$03 +
-        beq +++++ +
-        jsr LF19A +
-        jsr IsSamusDead +
-        beq + +
-        lda SamusBlink +
-        bne + +
-        ldy #$00 +
-        jsr LF149 +
-        jsr LF2B4 +
-    ; check for crash with bullets +
-*       ldy #$D0 +
-*       lda ObjAction,      ; projectile active? +
-        beq ++            ; try next one if not +
-        cmp #wa_BulletExplode +
-        bcc + +
-        cmp #$07 +
-        beq + +
-        cmp #wa_BombExplode +
-        beq + +
-        cmp #wa_Missile +
-        bne ++ +
-*       jsr LF149 +
-        jsr LF32A +
-*      jsr Yplus16 +
-        bne --- +
-*       txa +
-        sec +
-        sbc #$08                ; each Memu occupies 8 bytes +
-        tax +
-        bpl ------ +
- +
-        ldx #$B0 +
-*       lda ObjAction,+
-        cmp #$02 +
-        bne + +
-        ldy #$00 +
-        jsr IsSamusDead +
-        beq ++ +
-        jsr AreObjectsTouching          ;($DC7F) +
-        jsr LF277 +
-*       jsr Xminus16 +
-        bmi -- +
-; enemy <--> bullet/missile/bomb detection +
-*       ldx #$50                ; start with enemy slot #5 +
-LF09F:  lda EnStatus,      ; slot active? +
-        beq +              ; branch if not +
-        cmp #$03 +
-*       beq NextEnemy      ; next slot +
-        jsr LF152 +
-        lda EnStatus,+
-        cmp #$05 +
-        beq ++++ +
-        ldy #$D0                ; first projectile slot +
-*       lda ObjAction, ; is it active? +
-        beq ++            ; branch if not +
-        cmp #wa_BulletExplode +
-        bcc + +
-        cmp #$07 +
-        beq + +
-        cmp #wa_BombExplode +
-        beq + +
-        cmp #wa_Missile +
-        bne ++ +
-; check if enemy is actually hit +
-*       jsr LF140 +
-        jsr LF2CA +
-*       jsr Yplus16          ; next projectile slot +
-        bne --- +
-*       ldy #$00 +
-        lda SamusBlink +
-        bne NextEnemy +
-        jsr IsSamusDead +
-        beq NextEnemy +
-        jsr LF140 +
-        jsr LF282 +
-        NextEnemy: +
-        jsr Xminus16 +
-        bmi + +
-        jmp LF09F +
- +
-*       ldx #$00 +
-        jsr LF172 +
-        ldy #$60 +
-*       lda EnStatus,+
-        beq + +
-        cmp #$05 +
-        beq + +
-        lda SamusBlink +
-        bne + +
-        jsr IsSamusDead +
-        beq + +
-        jsr LF1B3 +
-        jsr LF162 +
-        jsr LF1FA +
-        jsr LF2ED +
-*       jsr Yplus16 +
-        cmp #$C0 +
-        bne -- +
-        ldy #$00 +
-        jsr IsSamusDead +
-        beq ++++ +
-        jsr LF186 +
-        ldx #$F0 +
-*       lda ObjAction,+
-        cmp #$07 +
-        beq + +
-        cmp #$0A +
-        bne ++ +
-*       jsr LDC82 +
-        jsr LF311 +
-*       jsr Xminus16 +
-        cmp #$C0 +
-        bne ---                  +
-*       jmp SubtractHealth              ;($CE92) +
- +
-LF140:  jsr LF1BF +
-        jsr LF186 +
-        jmp LF1FA +
- +
-LF149:  jsr LF186 +
-        jsr LF1D2 +
-        jmp LF1FA +
- +
-LF152:  lda EnYRoomPos,+
-        sta $07  ; Y coord +
-        lda EnXRoomPos,+
-        sta $09  ; X coord +
-        lda EnNameTable,    ; hi coord +
-        jmp LF17F +
- +
-LF162:  lda EnYRoomPos,    ; Y coord +
-        sta $06 +
-        lda EnXRoomPos,    ; X coord +
-        sta $08 +
-        lda EnNameTable,    ; hi coord +
-        jmp LF193 +
- +
-GetObject0CoordData: +
-LF172:  lda ObjectY,x +
-        sta $07 +
-        lda ObjectX,x +
-        sta $09 +
-        lda ObjectHi,+
- +
-LF17F:  eor PPUCNT0ZP +
-        and #$01 +
-        sta $0B +
-        rts +
- +
-GetObject1CoordData: +
-LF186:  lda ObjectY,y +
-        sta $06 +
-        lda ObjectX,y +
-        sta $08 +
-        lda ObjectHi,+
- +
-LF193:  eor PPUCNT0ZP +
-        and #$01 +
-        sta $0A +
-        rts +
- +
-LF19A:  lda $B1,x +
-        sta $07 +
-        lda $B2,x +
-        sta $09 +
-        lda $B3,x +
-        jmp LF17F +
- +
-DistFromObj0ToObj1: +
-LF1A7:  lda ObjRadY,x +
-        jsr LF1E0 +
-        lda ObjRadX,x +
-        jmp LF1D9 +
- +
-DistFromObj0ToEn1: +
-LF1B3:  lda ObjRadY,x +
-        jsr LF1E7 +
-        lda ObjRadX,x +
-        jmp LF1CB +
- +
-DistFromEn0ToObj1: +
-LF1BF:  lda EnRadY,x +
-        jsr LF1E0 +
-        lda EnRadX,x +
-        jmp LF1D9 +
- +
-AddEnemy1XRadius: +
-LF1CB:  clc +
-        adc EnRadX,y +
-        sta $05 +
-        rts +
- +
-LF1D2:  lda #$04 +
-        jsr LF1E0 +
-        lda #$08 +
- +
-AddObject1XRadius: +
-LF1D9:  clc +
-        adc ObjRadX,y +
-        sta $05 +
-        rts +
- +
-AddObject1YRadius: +
-LF1E0:  clc +
-        adc ObjRadY,y +
-        sta $04 +
-        rts +
- +
-LF1E7:  clc +
-        adc EnRadY,y +
-        sta $04 +
-        rts +
- +
-; Y = Y + 16 +
- +
-Yplus16: +
-        tya +
-        clc +
-        adc #$10 +
-        tay +
-        rts +
- +
-; X = X - 16 +
- +
-Xminus16: +
-        txa +
-        sec +
-        sbc #$10 +
-        tax +
-        rts +
- +
-LF1FA:  lda #$02 +
-        sta $10 +
-        and ScrollDir +
-        sta $03 +
-        lda $07                         ;Load object 0 y coord. +
-        sec                             ; +
-        sbc $06                         ;Subtract object 1 y coord. +
-        sta $00                         ;Store difference in $00. +
-        lda $03 +
-        bne ++ +
-        lda $0B +
-        eor $0A +
-        beq ++ +
-        jsr LF262 +
-        lda $00 +
-        sec +
-        sbc #$10 +
-        sta $00 +
-        bcs + +
-        dec $01 +
-*       jmp LF22B +
- +
-*       lda #$00 +
-        sbc #$00 +
-        jsr LF266 +
- +
-LF22B:  sec +
-        lda $01 +
-        bne ++ +
-        lda $00 +
-        sta $11 +
-        cmp $04 +
-        bcs ++ +
-        asl $10 +
-        lda $09 +
-        sec +
-        sbc $08 +
-        sta $00 +
-        lda $03 +
-        beq + +
-        lda $0B +
-        eor $0A +
-        beq + +
-        jsr LF262 +
-        jmp LF256 +
- +
-*       sbc #$00 +
-        jsr LF266 +
-LF256:  sec +
-        lda $01 +
-        bne + +
-        lda $00 +
-        sta $0F +
-        cmp $05 +
-*       rts +
- +
-LF262:  lda $0B +
-        sbc $0A +
- +
-LF266:  sta $01 +
-        bpl + +
-        jsr LE449 +
-        inc $10 +
-*       rts +
- +
-LF270:  ora $030A,x +
-        sta $030A,x +
-        rts +
- +
-LF277:  bcs Exit17 +
-LF279:  lda $10 +
-LF27B:  ora $030A,y +
-        sta $030A,y +
-        Exit17: +
-        rts +
- +
-LF282:  bcs Exit17 +
-        jsr LF2E8 +
-        jsr IsScrewAttackActive         ;($CD9C)Check if screw attack active. +
-        ldy #$00 +
-        bcc +++ +
-        lda EnStatus,+
-        cmp #$04 +
-        bcs Exit17 +
-        lda EnDataIndex,+
-*       sta $010F +
-        tay +
-        bmi + +
-        lda $968B,y +
-        and #$10 +
-        bne Exit17 +
-*       ldy #$00 +
-        jsr LF338 +
-        jmp LF306 +
- +
-*       lda #$81 +
-        sta $040E,x +
-        bne ++ +
-LF2B4:  bcs + +
-        jsr IsScrewAttackActive         ;($CD9C)Check if screw attack active. +
-        ldy #$00 +
-        lda #$C0 +
-        bcs --- +
-LF2BF:  lda $B6,x +
-        and #$F8 +
-        ora $10 +
-        eor #$03 +
-        sta $B6,x +
-*       rts +
- +
-LF2CA:  bcs +++ +
-        lda ObjAction,+
-        sta $040E,x +
-        jsr LF279 +
-*       jsr LF332 +
-*       ora $0404,x +
-        sta $0404,x +
-*       rts +
- +
-LF2DF:  lda $10 +
-        ora $0404,y +
-        sta $0404,y +
-        rts +
- +
-LF2E8:  jsr LF340 +
-        bne -- +
-LF2ED:  bcs + +
-        jsr LF2DF +
-        tya +
-        pha +
-        jsr IsScrewAttackActive         ;($CD9C)Check if screw attack active. +
-        pla +
-        tay +
-        bcc + +
-        lda #$80 +
-        sta $010F +
-        jsr LF332 +
-        jsr LF270 +
-LF306:  lda $95CE +
-        sta HealthLoChange +
-        lda $95CF +
-        sta HealthHiChange +
-*       rts +
- +
-LF311:  bcs Exit22 +
-        lda #$E0 +
-        sta $010F +
-        jsr LF338 +
-        lda $0F +
-        beq + +
-        lda #$01 +
-*       sta $73 +
- +
-ClearHealthChange: +
-LF323:  lda #$00 +
-LF325:  sta HealthLoChange +
-LF327:  sta HealthHiChange +
- +
-Exit22:  +
-LF329:  rts                             ;Return for routine above and below. +
- +
-LF32A:  bcs Exit22 +
-        jsr LF279 +
-        jmp LF2BF +
- +
-LF332:  jsr LF340 +
-        jmp Amul8       ; * 8 +
- +
-LF338:  lda $10 +
-        asl +
-        asl +
-        asl +
-        jmp LF27B +
- +
-LF340:  lda $10 +
-        eor #$03 +
-        rts +
- +
-; UpdateEnemies +
-; ============= +
- +
-UpdateEnemies: +
-LF345:  ldx #$50                ;Load x with #$50 +
-*       jsr DoOneEnemy                  ;($F351) +
-        ldx PageIndex +
-        jsr Xminus16 +
-        bne - +
-DoOneEnemy: +
-LF351:  stx PageIndex                   ;PageIndex starts at $50 and is subtracted by #$0F each--> +
-                                        ;iteration. There is a max of 6 enemies at a time. +
-        ldy EnStatus,+
-        beq + +
-        cpy #$03 +
-        bcs + +
-        jsr LF37F +
-*       jsr LF3AA +
-        lda EnStatus,+
-        sta $81 +
-        cmp #$07 +
-        bcs + +
-        jsr ChooseRoutine +
- +
-; Pointer table to code +
- +
-        .word ExitSub       ;($C45C) rts +
-        .word $F3BE +
-        .word $F3E6 +
-        .word $F40D +
-        .word $F43E +
-        .word $F483 +
-        .word $F4EE +
- +
-*       jmp KillObject                  ;($FA18)Free enemy data slot. +
- +
-LF37F:  lda $0405,x +
-        and #$02 +
-        bne + +
-        lda EnYRoomPos,    ; Y coord +
-        sta $0A +
-        lda EnXRoomPos,    ; X coord +
-        sta $0B +
-        lda EnNameTable,    ; hi coord +
-        sta $06 +
-        lda EnRadY,x +
-        sta $08 +
-        lda EnRadX,x +
-        sta $09 +
-        jsr IsObjectVisible             ;($DFDF)Determine if object is within the screen boundaries. +
-        txa +
-        bne + +
-        pla +
-        pla +
-*       ldx PageIndex +
-        rts +
- +
-LF3AA:  lda $0405,x +
-        asl +
-        rol +
-        tay +
-        txa +
-        jsr Adiv16                      ;($C2BF)/16. +
-        eor FrameCount +
-        lsr +
-        tya +
-        ror +
-        ror +
-        sta $0405,x +
-        rts +
- +
-LF3BE:  lda $0405,x +
-        asl +
-        bmi + +
-        lda #$00 +
-        sta $6B01,x +
-        sta EnCounter,+
-        sta $040A,x +
-        jsr LF6B9 +
-        jsr LF75B +
-        jsr LF682 +
-        jsr LF676 +
-        lda EnDelay,x +
-        beq + +
-        jsr LF7BA +
-*       jmp ++ +
- +
-LF3E6:  lda $0405,x +
-        asl +
-        bmi ++ +
-        lda $0405,x +
-        and #$20 +
-        beq + +
-        ldy EnDataIndex,+
-        lda EnemyInitDelayTbl,        ;($96BB) +
-        sta EnDelay,x +
-        dec EnStatus,+
-        bne ++ +
-*       jsr LF6B9 +
-        jsr LF75B +
-        jsr LF51E +
-LF40A:* jsr LF536 +
-        jmp $95E5 +
- +
-LF410:  jsr UpdateEnemyAnim +
-        jsr $8058 +
-LF416:  ldx PageIndex +
-        lda EnSpecialAttribs,+
-        bpl + +
-        lda ObjectCntrl +
-        bmi + +
-        lda #$A3 +
-LF423:  sta ObjectCntrl +
-*       lda EnStatus,+
-        beq LF42D +
-        jsr LDD8B +
-LF42D:  ldx PageIndex +
-        lda #$00 +
-        sta $0404,x +
-        sta $040E,x +
-        rts +
- +
-LF438:  jsr UpdateEnemyAnim +
-LF43B:  jmp LF416 +
- +
-LF43E:  jsr LF536 +
-        lda EnStatus,+
-        cmp #$03 +
-        beq LF410 +
-        bit ObjectCntrl +
-        bmi + +
-        lda #$A1 +
-        sta ObjectCntrl +
-*       lda FrameCount +
-        and #$07 +
-        bne + +
-        dec $040D,x +
-        bne + +
-        lda EnStatus,+
-        cmp #$03 +
-        beq + +
-        lda $040C,x +
-        sta EnStatus,+
-        ldy EnDataIndex,+
-        lda $969B,y +
-        sta $040D,x +
-*       lda $040D,x +
-        cmp #$0B +
-        bcs + +
-        lda FrameCount +
-        and #$02 +
-        beq + +
-        asl ObjectCntrl +
-*       jmp LF416 +
- +
-LF483:  lda $0404,x +
-        and #$24 +
-        beq ++++++ +
-        jsr KillObject                  ;($FA18)Free enemy data slot. +
-        ldy EnAnimFrame,+
-        cpy #$80 +
-        beq PickupMissile +
-        tya +
-        pha +
-        lda EnDataIndex,+
-        pha +
-        ldy #$00 +
-        ldx #$03 +
-        pla +
-        bne ++ +
-        dex +
-        pla +
-        cmp #$81 +
-        bne + +
-        ldx #$00                        ;Increase HealthHi by 0. +
-        ldy #$50                        ;Increase HealthLo by 5. +
-*       pha +
-*       pla                              +
-        sty HealthLoChange +
-        stx HealthHiChange +
-        jsr AddHealth                   ;($CEF9)Add health to Samus. +
-        jmp SFX_EnergyPickup +
- +
-PickupMissile: +
-        lda #$02 +
-        ldy EnDataIndex,+
-        beq + +
-        lda #$1E +
-*       clc +
-        adc MissileCount +
-        bcs +              ; can't have more than 255 missiles +
-        cmp MaxMissiles  ; can Samus hold this many missiles? +
-        bcc ++            ; branch if yes +
-*       lda MaxMissiles  ; set to max. # of missiles allowed +
-*       sta MissileCount +
-        jmp SFX_MissilePickup +
- +
-*       lda FrameCount +
-        and #$03 +
-        bne + +
-        dec $040D,x +
-        bne + +
-        jsr KillObject                  ;($FA18)Free enemy data slot. +
-*       lda FrameCount +
-        and #$02 +
-        lsr +
-        ora #$A0 +
-        sta ObjectCntrl +
-        jmp LF416 +
- +
-LF4EE:  dec EnSpecialAttribs,+
-        bne ++ +
-        lda $040C,x +
-        tay +
-        and #$C0 +
-        sta EnSpecialAttribs,+
-        tya +
-        and #$3F +
-        sta EnStatus,+
-        pha +
-        jsr $80B0 +
-        and #$20 +
-        beq + +
-        pla +
-        jsr LF515 +
-        pha +
-*       pla +
-*       lda #$A0 +
-        jmp LF423 +
- +
-LF515:  sta $040C,x +
-LF518:  lda #$04 +
-        sta EnStatus,+
-        rts +
- +
-LF51E:  lda ScrollDir +
-        ldx PageIndex +
-        cmp #$02 +
-        bcc ++ +
-        lda EnYRoomPos,    ; Y coord +
-        cmp #$EC +
-        bcc ++ +
-        jmp KillObject                  ;($FA18)Free enemy data slot. +
- +
-*       jsr SFX_MetroidHit +
-        jmp GetPageIndex +
- +
-LF536:  lda EnSpecialAttribs,+
-        sta $0A +
-        lda $0404,x +
-        and #$20 +
-        beq + +
-        lda $040E,x +
-        cmp #$03 +
-        bne +++ +
-        bit $0A +
-        bvs +++ +
-        lda EnStatus,+
-        cmp #$04 +
-        beq +++ +
-        jsr LF515 +
-        lda #$40 +
-        sta $040D,x +
-        jsr $80B0 +
-        and #$20 +
-        beq + +
-        lda #$05 +
-        sta EnHitPoints,+
-        jmp $95A8 +
-*       rts +
- +
-*       jsr $80B0 +
-        and #$20 +
-        bne --- +
-        jsr SFX_Metal +
-        jmp LF42D +
- +
-*       lda EnHitPoints,+
-        cmp #$FF +
-        beq -- +
-        bit $0A +
-        bvc + +
-        jsr SFX_BossHit +
-        bne ++ +
-*       jsr LF74B +
-        and #$0C +
-        beq PlaySnd1 +
-        cmp #$04 +
-        beq PlaySnd2 +
-        cmp #$08 +
-        beq PlaySnd3 +
-        jsr SFX_MetroidHit +
-        bne +       ; branch always +
-PlaySnd1: +
-        jsr SFX_EnemyHit +
-        bne +       ; branch always +
-PlaySnd2: +
-        jsr SFX_EnemyHit +
-        bne +       ; branch always +
-PlaySnd3: +
-        jsr SFX_BigEnemyHit             ;($CBCE) +
-*       ldx PageIndex +
-        jsr $80B0 +
-        and #$20 +
-        beq + +
-        lda $040E,x +
-        cmp #$0B +
-        bne ---- +
-*       lda EnStatus,+
-        cmp #$04 +
-        bne + +
-        lda $040C,x +
-*       ora $0A +
-        sta $040C,x +
-        asl +
-        bmi + +
-        jsr $80B0 +
-        and #$20 +
-        bne + +
-        ldy $040E,x +
-        cpy #$0B +
-        beq +++++ +
-        cpy #$81 +
-        beq +++++ +
-*       lda #$06 +
-        sta EnStatus,+
-        lda #$0A +
-        bit $0A +
-        bvc + +
-        lda #$03 +
-*       sta EnSpecialAttribs,+
-        cpy #$02 +
-        beq + +
-        bit $0A +
-        bvc ++ +
-        ldy $040E,x +
-        cpy #$0B +
-        bne ++ +
-        dec EnHitPoints,+
-        beq +++ +
-        dec EnHitPoints,+
-        beq +++ +
-*       dec EnHitPoints,+
-        beq ++ +
-*       dec EnHitPoints,+
-        bne GetPageIndex +
-*       lda #$03 +
-        sta EnStatus,+
-        bit $0A +
-        bvs + +
-        lda $040E,x +
-        cmp #$02 +
-        bcs + +
-        lda #$00 +
-        jsr LDCFC +
-        ldx PageIndex +
-*       jsr LF844 +
-        lda $960B,y +
-        jsr LF68D +
-        sta EnCounter,+
-        ldx #$C0 +
-*       lda EnStatus,+
-        beq + +
-        txa +
-        clc +
-        adc #$08 +
-        tax +
-        cmp #$E0 +
-        bne - +
-        beq GetPageIndex +
-*       lda $95DD +
-        jsr LF68D +
-        lda #$0A +
-        sta EnCounter,+
-        inc EnStatus,+
-        lda #$00 +
-        bit $0A +
-        bvc + +
-        lda #$03 +
-*       sta $0407,x +
-        ldy PageIndex +
-        lda EnYRoomPos,+
-        sta EnYRoomPos,+
-        lda EnXRoomPos,+
-        sta EnXRoomPos,+
-        lda EnNameTable,+
-        sta EnNameTable,+
-        GetPageIndex: +
-        ldx PageIndex +
-        rts +
- +
-LF676:  jsr $80B0 +
-        asl +
-        asl +
-        asl +
-        and #$C0 +
-        sta $6B03,x +
-        rts +
- +
-LF682:  jsr LF844 +
-        lda $963B,y +
-        cmp EnResetAnimIndex,+
-        beq + +
-LF68D:  sta EnResetAnimIndex,+
-LF690:  sta EnAnimIndex,+
-LF693:  lda #$00 +
-        sta EnAnimDelay,+
-*       rts +
- +
-LF699:  jsr LF844 +
-        lda $965B,y +
-        cmp EnResetAnimIndex,+
-        beq Exit12 +
-        jsr LF68D +
-        ldy EnDataIndex,+
-        lda $967B,y +
-        and #$7F +
-        beq Exit12 +
-        tay +
-*       dec EnAnimIndex,+
-        dey +
-        bne - +
-Exit12: rts +
- +
-LF6B9:  lda #$00 +
-        sta $82 +
-        jsr LF74B +
-        tay +
-        lda EnStatus,+
-        cmp #$02 +
-        bne + +
-        tya +
-        and #$02 +
-        beq Exit12 +
-*       tya +
-        dec $040D,x +
-        bne Exit12 +
-        pha +
-        ldy EnDataIndex,+
-        lda $969B,y +
-        sta $040D,x +
-        pla +
-        bpl ++++ +
-        lda #$FE +
-        jsr LF7B3 +
-        lda ScrollDir +
-        cmp #$02 +
-        bcc + +
-        jsr LF752 +
-        bcc + +
-        tya +
-        eor PPUCNT0ZP +
-        bcs +++ +
-*       lda EnXRoomPos,+
-        cmp ObjectX +
-        bne + +
-        inc $82 +
-*       rol +
-*       and #$01 +
-        jsr LF744 +
-        lsr +
-        ror +
-        eor $0403,x +
-        bpl + +
-        jsr $81DA +
-*       lda #$FB +
-        jsr LF7B3 +
-        lda ScrollDir +
-        cmp #$02 +
-        bcs + +
-        jsr LF752 +
-        bcc + +
-        tya +
-        eor PPUCNT0ZP +
-        bcs +++ +
-*       lda EnYRoomPos,+
-        cmp ObjectY +
-        bne + +
-        inc $82 +
-        inc $82 +
-*       rol +
-*       and #$01 +
-        asl +
-        asl +
-        jsr LF744 +
-        lsr +
-        lsr +
-        lsr +
-        ror +
-        eor $0402,x +
-        bpl + +
-        jmp $820F +
- +
-LF744:  ora $0405,x +
-        sta $0405,x +
-*       rts +
- +
-LF74B:  ldy EnDataIndex,+
-        lda $968B,y +
-        rts +
- +
-LF752:  lda EnNameTable,+
-        tay +
-        eor ObjectHi +
-        lsr +
-        rts +
- +
-LF75B:  lda #$E7 +
-        sta $06 +
-        lda #$18 +
-        jsr LF744 +
-        ldy EnDataIndex,+
-        lda $96AB,y +
-        beq +++++ +
-        tay +
-        lda $0405,x +
-        and #$02 +
-        beq ++++ +
-        tya +
-        ldy #$F7 +
-        asl +
-        bcs + +
-        ldy #$EF +
-*       lsr +
-        sta $02 +
-        sty $06 +
-        lda ObjectY +
-        sta $00 +
-        ldy EnYRoomPos,+
-        lda $0405,x +
-        bmi + +
-        ldy ObjectX +
-        sty $00 +
-        ldy EnXRoomPos,+
-*       lda ObjectHi +
-        lsr +
-        ror $00 +
-        lda EnNameTable,+
-        lsr +
-        tya +
-        ror +
-        sec +
-        sbc $00 +
-        bpl + +
-        jsr TwosCompliment              ;($C3D4) +
-*       lsr +
-        lsr +
-        lsr +
-        cmp $02 +
-        bcc ++ +
-*       lda $06 +
-LF7B3:  and $0405,x +
-        sta $0405,x +
-*       rts +
- +
-LF7BA:  dec EnDelay,x +
-        bne + +
-        lda $0405,x +
-        and #$08 +
-        bne ++ +
-        inc EnDelay,x +
-*       rts +
- +
-*       lda EnDataIndex,+
-        cmp #$07 +
-        bne + +
-        jsr SFX_OutOfHole +
-        ldx PageIndex +
-*       inc EnStatus,+
-        jsr LF699 +
-        ldy EnDataIndex,+
-        lda $96CB,y +
-        clc +
-        adc #$D1 +
-        sta $00 +
-        lda #$00 +
-        adc #$97 +
-        sta $01 +
-        lda FrameCount +
-        eor RandomNumber1 +
-        ldy #$00 +
-        and ($00),y +
-        tay +
-        iny +
-        lda ($00),y +
-        sta $0408,x +
-        jsr $80B0 +
-        bpl ++ +
-        lda #$00 +
-        sta EnCounter,+
-        sta $0407,x +
-        ldy $0408,x +
-        lda $972B,y +
-        sta $6AFE,x +
-        lda $973F,y +
-        sta $6AFF,x +
-        lda $9753,y +
-        sta $0402,x +
-        lda $9767,y +
-        sta $0403,x +
-        lda $0405,x +
-        bmi + +
-        lsr +
-        bcc ++ +
-        jsr $81D1 +
-        jmp ++ +
- +
-*       and #$04 +
-        beq + +
-        jsr $8206 +
-*       lda #$DF +
-        jmp LF7B3 +
- +
-LF83E:  lda $0405,x +
-LF841:  jmp + +
- +
-LF844:  lda $0405,x +
-        bpl + +
-        lsr +
-        lsr +
-*       lsr +
-        lda EnDataIndex,+
-        rol +
-        tay +
-        rts +
- +
-LF852:  txa +
-        lsr +
-        lsr +
-        lsr +
-        adc FrameCount +
-        lsr +
-        rts +
- +
-LF85A:  ldy EnDataIndex,+
-        lda $969B,y +
-        sta $040D,x +
-        lda EnemyHitPointTbl,         ;($962B) +
-        ldy EnSpecialAttribs,+
-        bpl + +
-        asl +
-*       sta EnHitPoints,+
-*       rts +
- +
-LF870:  lda $0405,x +
-        and #$10 +
-        beq - +
-        lda $87 +
-        and EnStatus,+
-        beq - +
-        lda $87 +
-        bpl + +
-        ldy $6B01,x +
-        bne - +
-*       jsr LF8E8 +
-        bcs ++ +
-        sta $0404,y +
-        jsr LF92C +
-        lda $0405,x +
-        lsr +
-        lda $85 +
-        pha +
-        rol +
-        tax +
-        lda $978B,x +
-        pha +
-        tya +
-        tax +
-        pla +
-        jsr LF68D +
-        ldx PageIndex +
-        lda #$01 +
-        sta EnStatus,+
-        and $0405,x +
-        tax +
-        lda Table15,x +
-        sta $0403,y +
-        lda #$00 +
-        sta $0402,y +
-        ldx PageIndex +
-        jsr LF8F8 +
-        lda $0405,x +
-        lsr +
-        pla +
-        tax +
-        lda $97A3,x +
-        sta $04 +
-        txa +
-        rol +
-        tax +
-        lda $979B,x +
-        sta $05 +
-        jsr LF91D +
-        ldx PageIndex +
-        bit $87 +
-        bvc ++ +
-        lda $0405,x +
-        and #$01 +
-        tay +
-        lda $0083,y +
-        jmp LF690 +
- +
-LF8E8:  ldy #$60 +
-        clc +
-*       lda EnStatus,+
-        beq + +
-        jsr Yplus16 +
-        cmp #$C0 +
-        bne - +
-*       rts +
- +
-LF8F8:  lda $85 +
-        cmp #$02 +
-        bcc + +
-        ldx PageIndex +
-        lda $0405,x +
-        lsr +
-        lda $88 +
-        rol +
-        and #$07 +
-        sta $040A,y +
-        lda #$02 +
-        sta EnStatus,+
-        lda #$00 +
-        sta EnDelay,y +
-        sta EnAnimDelay,+
-        sta $0408,y +
-*       rts +
- +
-LF91D:  ldx PageIndex +
-        jsr LE792 +
-        tya +
-        tax +
-        jsr LFD8F +
-        jmp LFA49 +
- +
-; Table used by above subroutine +
- +
-Table15: +
-        .byte $02 +
-        .byte $FE +
- +
-LF92C:  lda #$02 +
-        sta EnRadY,y +
-        sta EnRadX,y +
-        ora $0405,y +
-        sta $0405,y +
-        rts +
- +
-LF93B:  ldx #$B0 +
-*       jsr LF949 +
-        ldx PageIndex +
-        jsr Xminus16 +
-        cmp #$60 +
-        bne - +
-LF949:  stx PageIndex +
-        lda $0405,x +
-        and #$02 +
-        bne + +
-        jsr KillObject                  ;($FA18)Free enemy data slot. +
-*       lda EnStatus,+
-        beq Exit19 +
-        jsr ChooseRoutine +
- +
-; Pointer table to code +
- +
-        .word ExitSub     ;($C45C) rts +
-        .word $F96A +
-        .word LF991       ; spit dragon's fireball +
-        .word ExitSub     ;($C45C) rts +
-        .word $FA6B +
-        .word $FA91 +
- +
-Exit19: rts +
- +
-LF96A:  jsr LFA5B +
-        jsr LFA1E +
-        ldx PageIndex +
-        bcs LF97C +
-        lda EnStatus,+
-        beq Exit19 +
-        jsr LFA60 +
-LF97C:  lda #$01 +
-LF97E:  jsr UpdateEnemyAnim +
-        jmp LDD8B +
- +
-*       inc $0408,x +
-LF987:  inc $0408,x +
-        lda #$00 +
-        sta EnDelay,x +
-        beq + +
-LF991:  jsr LFA5B +
-        lda $040A,x +
-        and #$FE +
-        tay +
-        lda $97A7,y +
-        sta $0A +
-        lda $97A8,y +
-        sta $0B +
-*       ldy $0408,x +
-        lda ($0A),y +
-        cmp #$FF +
-        bne + +
-        sta $0408,x +
-        jmp LF987 +
- +
-*       cmp EnDelay,x +
-        beq --- +
-        inc EnDelay,x +
-        iny +
-        lda ($0A),y +
-        jsr $8296 +
-        ldx PageIndex +
-        sta $0402,x +
-        lda ($0A),y +
-        jsr $832F +
-        ldx PageIndex +
-        sta $0403,x +
-        tay +
-        lda $040A,x +
-        lsr +
-        php +
-        bcc + +
-        tya +
-        jsr TwosCompliment              ;($C3D4) +
-        sta $0403,x +
-*       plp +
-        bne + +
-        lda $0402,x +
-        beq + +
-        bmi + +
-        ldy $040A,x +
-        lda $95E0,y +
-        sta EnResetAnimIndex,+
-*       jsr LFA1E +
-        ldx PageIndex +
-        bcs ++ +
-        lda EnStatus,+
-        beq Exit20 +
-        ldy #$00 +
-        lda $040A,x +
-        lsr +
-        beq + +
-        iny +
-*       lda $95E2,y +
-        jsr LF68D +
-        jsr LF518 +
-        lda #$0A +
-        sta EnDelay,x +
-*       jmp LF97C +
- +
-KillObject: +
-LFA18:  lda #$00                        ; +
-LFA1A:  sta EnStatus,                 ;Store #$00 as enemy status(enemy slot is open). +
-LFA1D:  rts                             ; +
- +
-; enemy<-->background crash detection +
- +
-LFA1E:  lda InArea +
-        cmp #$11 +
-        bne + +
-        lda EnStatus,+
-        lsr +
-        bcc ++ +
-*       jsr LFA7D +
-        ldy #$00 +
-        lda ($04),y +
-        cmp #$A0 +
-        bcc ++ +
-        ldx PageIndex +
-*       lda $0403,x +
-        sta $05 +
-        lda $0402,x +
-        sta $04 +
-LFA41:  jsr LE792 +
-        jsr LFD8F +
-        bcc KillObject                  ;($FA18)Free enemy data slot. +
-LFA49:  lda $08 +
-        sta EnYRoomPos,+
-        lda $09 +
-        sta EnXRoomPos,+
-        lda $0B +
-        and #$01 +
-        sta EnNameTable,+
-*       rts +
- +
-LFA5B:  lda $0404,x +
-        beq Exit20 +
-LFA60:  lda #$00 +
-        sta $0404,x +
-        lda #$05 +
-        sta EnStatus,+
-Exit20: rts +
- +
-LFA6B:  lda EnAnimFrame,+
-        cmp #$F7 +
-        beq + +
-        dec EnDelay,x +
-        bne ++ +
-*       jsr KillObject                  ;($FA18)Free enemy data slot. +
-*       jmp LF97C +
- +
-LFA7D:  ldx PageIndex +
-        lda EnYRoomPos,+
-        sta $02 +
-        lda EnXRoomPos,+
-        sta $03 +
-        lda EnNameTable,+
-        sta $0B +
-        jmp MakeCartRAMPtr              ;($E96A)Find enemy position in room RAM. +
- +
-LFA91:  jsr KillObject                  ;($FA18)Free enemy data slot. +
-        lda $95DC +
-        jsr LF68D +
-        jmp LF97C +
- +
-LFA9D:  ldx #$C0 +
-*       stx PageIndex +
-        lda EnStatus,+
-        beq + +
-        jsr LFAB4 +
-*       lda PageIndex +
-        clc +
-        adc #$08 +
-        tax +
-        cmp #$E0 +
-        bne -- +
-*      rts +
- +
-LFAB4:  dec EnCounter,+
-        bne ++ +
-        lda #$0C +
-        sta EnCounter,+
-        dec $0407,x +
-        bmi + +
-        bne ++ +
-*       jsr KillObject                  ;($FA18)Free enemy data slot. +
-*       lda EnCounter,+
-        cmp #$09 +
-        bne + +
-        lda $0407,x +
-        asl +
-        tay +
-        lda Table16,y +
-        sta $04 +
-        lda Table16+1,+
-        sta $05 +
-        jsr LFA41 +
-*       lda #$80 +
-        sta ObjectCntrl +
-        lda #$03 +
-        jmp LF97E +
- +
-; Table used by above subroutine +
- +
-Table16: +
-        .byte $00 +
-        .byte $00 +
-        .byte $0C +
-        .byte $1C +
-        .byte $10 +
-        .byte $F0 +
-        .byte $F0 +
-        .byte $08 +
- +
-LFAF2:  ldy #$18 +
-*       jsr LFAFF +
-        lda PageIndex +
-        sec +
-        sbc #$08 +
-        tay +
-        bne - +
- +
-LFAFF:  sty PageIndex +
-        ldx $0728,y +
-        inx +
-        beq ----- +
-        ldx $0729,y +
-        lda EnStatus,+
-        beq + +
-        lda $0405,x +
-        and #$02 +
-        bne Exit13 +
-*       sta $0404,x +
-        lda #$FF +
-        cmp EnDataIndex,+
-        bne + +
-        dec EnDelay,x +
-        bne Exit13 +
-        lda $0728,y +
-        jsr LEB28 +
-        ldy PageIndex +
-        lda $072A,y +
-        sta EnYRoomPos,+
-        lda $072B,y +
-        sta EnXRoomPos,+
-        lda $072C,y +
-        sta EnNameTable,+
-        lda #$18 +
-        sta EnRadX,x +
-        lda #$0C +
-        sta EnRadY,x +
-        ldy #$00 +
-        jsr LF186 +
-        jsr LF152 +
-        jsr LF1BF +
-        jsr LF1FA +
-        bcc Exit13 +
-        lda #$01 +
-        sta EnDelay,x +
-        sta EnStatus,+
-        and ScrollDir +
-        asl +
-        sta $0405,x +
-        ldy EnDataIndex,+
-        jsr LFB7B +
-        jmp LF85A +
- +
-*       sta EnDataIndex,+
-        lda #$01 +
-        sta EnDelay,x +
-        jmp KillObject                  ;($FA18)Free enemy data slot. +
- +
-LFB7B:  jsr $80B0 +
-        ror $0405,x +
-        lda EnemyInitDelayTbl,        ;($96BB)Load initial delay for enemy movement. +
-        sta EnDelay,          ; +
- +
-Exit13:  +
-        rts                             ;Exit from multiple routines. +
- +
-LFB88:  ldx PageIndex +
-        jsr LF844 +
-        lda $6B01,x +
-        inc $6B03,x +
-        dec $6B03,x +
-        bne + +
-        pha +
-        pla +
-*       bpl + +
-        jsr TwosCompliment              ;($C3D4) +
-*       cmp #$08 +
-        bcc + +
-        cmp #$10 +
-        bcs Exit13 +
-        tya +
-        and #$01 +
-        tay +
-        lda $0085,y +
-        cmp EnResetAnimIndex,+
-        beq Exit13 +
-        sta EnAnimIndex,+
-        dec EnAnimIndex,+
-        sta EnResetAnimIndex,+
-        jmp LF693 +
- +
-*       lda $963B,y +
-        cmp EnResetAnimIndex,+
-        beq Exit13 +
-        jmp LF68D +
- +
-LFBCA:  ldx PageIndex +
-        jsr LF844 +
-        lda $965B,y +
-        cmp EnResetAnimIndex,+
-        beq Exit13 +
-        sta EnResetAnimIndex,+
-        jmp LF690 +
- +
-LFBDD:  lda #$40 +
-        sta PageIndex +
-        ldx #$0C +
-*       jsr LFBEC +
-        dex +
-        dex +
-        dex +
-        dex +
-        bne - +
-LFBEC:  lda $A0,x +
-        beq ++ +
-        dec $A0,x +
-        txa +
-        lsr +
-        tay +
-        lda Table17,y +
-        sta $04 +
-        lda Table17+1,+
-        sta $05 +
-        lda $A1,x +
-        sta $08 +
-        lda $A2,x +
-        sta $09 +
-        lda $A3,x +
-        sta $0B +
-        jsr LFD8F +
-        bcc +++ +
-        lda $08 +
-        sta $A1,x +
-        sta $034D +
-        lda $09 +
-        sta $A2,x +
-        sta $034E +
-        lda $0B +
-        and #$01 +
-        sta $A3,x +
-        sta $034C +
-        lda $A3,x +
-        sta $034C +
-        lda #$5A +
-        sta PowerUpAnimFrame            ;Save index to find object animation. +
-        txa +
-        pha +
-        jsr DrawFrame +
-        lda SamusBlink +
-        bne + +
-        ldy #$00 +
-        ldx #$40 +
-        jsr AreObjectsTouching          ;($DC7F) +
-        bcs + +
-        jsr IsScrewAttackActive         ;($CD9C)Check if screw attack active. +
-        ldy #$00 +
-        bcc + +
-        clc +
-        jsr LF311 +
-        lda #$50 +
-        sta HealthLoChange +
-        jsr SubtractHealth              ;($CE92) +
-*       pla +
-        tax +
-*       rts +
- +
-*       lda #$00 +
-        sta $A0,x +
-        rts +
- +
-; Table used by above subroutine +
- +
-Table17: +
-        .byte $00 +
-        .byte $FB +
-        .byte $FB +
-        .byte $FE +
-        .byte $FB +
-        .byte $02 +
-        .byte $00 +
-        .byte $05 +
- +
-LFC65:  lda $6BE4 +
-        beq ++ +
-        ldx #$F0 +
-        stx PageIndex +
-        lda $6BE9 +
-        cmp $95E4 +
-        bne +++ +
-        lda #$03 +
-        jsr UpdateEnemyAnim +
-        lda RandomNumber1 +
-        sta $8A +
-        lda #$18 +
-*       pha +
-        tax +
-        jsr LFC98 +
-        pla +
-        tax +
-        lda $B6,x +
-        and #$F8 +
-        sta $B6,x +
-        txa +
-        sec +
-        sbc #$08 +
-        bpl - +
-*       rts +
- +
-*      jmp KillObject                   ;($FA18)Free enemy data slot. +
- +
-LFC98:  lda $B0,x +
-        jsr ChooseRoutine +
- +
-; Pointer table to code +
- +
-        .word ExitSub       ;($C45C) rts +
-        .word $FCA5 +
-        .word $FCB1 +
-        .word $FCBA +
- +
-LFCA5:  jsr LFD84 +
-        jsr LFD08 +
-        jsr LFD25 +
-        jmp LDD8B +
- +
-LFCB1:  jsr LFD84 +
-        jsr LFCC1 +
-        jmp LDD8B +
- +
-LFCBA:  lda #$00 +
-        sta $B0,x +
-        jmp SFX_EnemyHit +
- +
-LFCC1:  jsr LFD5F +
-        lda $B4,x +
-        cmp #$02 +
-        bcs + +
-        ldy $08 +
-        cpy ObjectY +
-        bcc + +
-        ora #$02 +
-        sta $B4,x +
-*       ldy #$01 +
-        lda $B4,x +
-        lsr +
-        bcc + +
-        ldy #$FF +
-*       sty $05 +
-        ldy #$04 +
-        lsr +
-        lda $B5,x +
-        bcc + +
-        ldy #$FD +
-*       sty $04 +
-        inc $B5,x +
-        jsr LFD8F +
-        bcs + +
-        lda $B4,x +
-        ora #$02 +
-        sta $B4,x +
-*       bcc + +
-        jsr LFD6C +
-*       lda $B5,x +
-        cmp #$50 +
-        bcc + +
-        lda #$01 +
-        sta $B0,x +
-*       rts +
- +
-LFD08:  lda #$00 +
-        sta $B5,x +
-        tay +
-        lda ObjectX +
-        sec +
-        sbc $B2,x +
-        bpl + +
-        iny +
-        jsr TwosCompliment              ;($C3D4) +
-*       cmp #$10 +
-        bcs + +
-        tya +
-        sta $B4,x +
-        lda #$02 +
-        sta $B0,x +
-*       rts +
- +
-LFD25:  txa +
-        lsr +
-        lsr +
-        lsr +
-        adc $8A +
-        sta $8A +
-        lsr $8A +
-        and #$03 +
-        tay +
-        lda Table18,y +
-        sta $04 +
-        lda Table18+1,+
-        sta $05 +
-        jsr LFD5F +
-        lda $08 +
-        sec +
-        sbc ScrollY +
-        tay +
-        lda #$02 +
-        cpy #$20 +
-        bcc + +
-        jsr TwosCompliment              ;($C3D4) +
-        cpy #$80 +
-        bcc ++ +
-*       sta $04 +
-*      jsr LFD8F +
-        jmp LFD6C +
- +
-; Table used by above subroutine +
- +
-Table18: +
-        .byte $02 +
-        .byte $FE +
-        .byte $01 +
-        .byte $FF +
-        .byte $02 +
- +
-LFD5F:  lda $B3,x +
-        sta $0B +
-        lda $B1,x +
-        sta $08 +
-        lda $B2,x +
-        sta $09 +
-        rts +
- +
-LFD6C:  lda $08 +
-        sta $B1,x +
-        sta $04F0 +
-        lda $09 +
-        sta $B2,x +
-        sta $04F1 +
-        lda $0B +
-        and #$01 +
-        sta $B3,x +
-        sta $6BEB +
-        rts +
- +
-LFD84:  lda $B6,x +
-        and #$04 +
-        beq + +
-        lda #$03 +
-        sta $B0,x +
-*       rts +
- +
-LFD8F:  lda ScrollDir +
-        and #$02 +
-        sta $02 +
-        lda $04 +
-        clc +
-        bmi +++ +
-        beq LFDBF +
-        adc $08 +
-        bcs + +
-        cmp #$F0 +
-        bcc ++ +
-*       adc #$0F +
-        ldy $02 +
-        bne ClcExit2 +
-        inc $0B +
-*       sta $08 +
-        jmp LFDBF +
- +
-*       adc $08 +
-        bcs + +
-        sbc #$0F +
-        ldy $02 +
-        bne ClcExit2 +
-        inc $0B +
-*       sta $08 +
-LFDBF:  lda $05 +
-        clc +
-        bmi ++ +
-        beq SecExit +
-        adc $09 +
-        bcc + +
-        ldy $02 +
-        beq ClcExit2 +
-        inc $0B +
-*       jmp ++ +
- +
-*       adc $09 +
-        bcs + +
-        ldy $02 +
-        beq ClcExit2 +
-        inc $0B +
-*       sta $09 +
-        SecExit: +
-        sec +
-        rts +
- +
-        ClcExit2: +
-        clc +
-*       rts +
- +
-UpdateTourianItems: +
-; Adds mother brain and zebetite  +
-LFDE3:  lda EndTimerHi          ; Determine if this is the first frame the end timer is running +
-        cmp #$99                ; (it will have a value of 99.99 the first frame) +
-        bne +                    +
-        clc                      +
-        sbc EndTimerLo           +
-        bne +                   ; On the first frame of the end timer: +
-                                 +
-        sta $06                 ;  +
-        lda #$38                ; +
-        sta $07                 ;    Add [mother brain defeated] to item history +
-        jsr LDC54               ;  +
-                                 +
-*       ldx #$20                ; Loop through zebetites (@ x = 20, 18, 10, 8, 0) +
-*       jsr CheckZebetite       ;     ($FE05) Update one zebetite +
-        txa                     ;     (Subtract 8 from x) +
-        sec                      +
-        sbc #$08                 +
-        tax                      +
-        bne -                    +
-                                 +
-CheckZebetite                    +
-LFE05:  lda $0758,            ;  +
-        sec                      +
-        sbc #$02                ;  +
-        bne ---                 ; Exit if zebetite state != 2 +
-        sta $06                 ; Store 0 to $06 +
-        inc $0758,            ; Set zebetite state to 3 +
-        txa                      +
-        lsr                     ; A =  zebetite index * 4 (10, C, 8, 4, or 0) +
-        adc #$3C                ;      + $3C +
-        sta $07                  +
-        jmp LDC54               ; Add zebetite to item history +
- +
-; Tile degenerate/regenerate +
- +
-UpdateTiles: +
-        ldx #$C0 +
-*       jsr DoOneTile +
-        ldx PageIndex +
-        jsr Xminus16 +
-        bne - +
-        DoOneTile: +
-        stx PageIndex +
-        lda TileRoutine,+
-        beq +          ; exit if tile not active +
-        jsr ChooseRoutine +
- +
-; Pointer table to code +
- +
-        .word ExitSub       ;($C45C) rts +
-        .word $FE3D +
-        .word $FE54 +
-        .word $FE59 +
-        .word $FE54 +
-        .word $FE83 +
- +
-LFE3D:  inc TileRoutine,+
-        lda #$00 +
-        jsr SetTileAnim +
-        lda #$50 +
-        sta TileDelay,+
-        lda TileWRAMLo,    ; low WRAM addr of blasted tile +
-        sta $00 +
-        lda TileWRAMHi,    ; high WRAM addr +
-        sta $01 +
- +
-LFE54:  lda #$02 +
-        jmp UpdateTileAnim +
- +
-LFE59:  lda FrameCount +
-        and #$03 +
-        bne +       ; only update tile timer every 4th frame +
-        dec TileDelay,+
-        bne +       ; exit if timer not reached zero +
-        inc TileRoutine,+
-        ldy TileType,+
-        lda Table19,y +
-        SetTileAnim: +
-        sta TileAnimIndex,+
-        sta $0505,x +
-        lda #$00 +
-        sta TileAnimDelay,+
-*       rts +
- +
-; Table used for indexing the animations in TileBlastAnim (see below) +
- +
-Table19: +
-        .byte $18,$1C,$20,$00,$04,$08,$0C,$10,$24,$14 +
- +
-LFE83:  lda #$00 +
-        sta TileRoutine,      ; tile = respawned +
-        lda TileWRAMLo,+
-        clc +
-        adc #$21 +
-        sta $00 +
-        lda TileWRAMHi,+
-        sta $01 +
-        jsr LFF3C +
-        lda $02 +
-        sta $07 +
-        lda $03 +
-        sta $09 +
-        lda $01 +
-        lsr +
-        lsr +
-        and #$01 +
-        sta $0B +
-        ldy #$00 +
-        jsr LF186 +
-        lda #$04 +
-        clc +
-        adc ObjRadY +
-        sta $04 +
-        lda #$04 +
-        clc +
-        adc ObjRadX +
-        sta $05 +
-        jsr LF1FA +
-        bcs Exit23 +
-        jsr LF311 +
-        lda #$50 +
-        sta HealthLoChange +
-        jmp SubtractHealth              ;($CE92) +
- +
-        GetTileFramePtr: +
-        lda TileAnimFrame,+
-        asl +
-        tay +
-        lda $97AF,y +
-        sta $02 +
-        lda $97B0,y +
-        sta $03 +
-Exit23: rts +
- +
-        DrawTileBlast: +
-        lda PPUStrIndex +
-        cmp #$1F +
-        bcs Exit23 +
-        ldx PageIndex +
-        lda TileWRAMLo,+
-        sta $00 +
-        lda TileWRAMHi,+
-        sta $01 +
-        jsr GetTileFramePtr +
-        ldy #$00 +
-        sty $11 +
-        lda ($02),y +
-        tax +
-        jsr Adiv16       ; / 16 +
-        sta $04 +
-        txa +
-        and #$0F +
-        sta $05 +
-        iny +
-        sty $10 +
-*       ldx $05 +
-*       ldy $10 +
-        lda ($02),y +
-        inc $10 +
-        ldy $11 +
-        sta ($00),y +
-        inc $11 +
-        dex +
-        bne - +
-        lda $11 +
-        clc +
-        adc #$20 +
-        sec +
-        sbc $05 +
-        sta $11 +
-        dec $04 +
-        bne -- +
-        lda $01 +
-        and #$04 +
-        beq + +
-        lda $01 +
-        ora #$0C +
-        sta $01 +
-*       lda $01 +
-        and #$2F +
-        sta $01 +
-        jsr LC328 +
-        clc +
-        rts +
- +
-LFF3C:  lda $00 +
-        tay +
-        and #$E0 +
-        sta $02 +
-        lda $01 +
-        lsr +
-        ror $02 +
-        lsr +
-        ror $02 +
-        tya +
-        and #$1F +
-        jsr Amul8       ; * 8 +
-        sta $03 +
-        rts +
- +
-UpdateTileAnim: +
-        ldx PageIndex +
-        ldy TileAnimDelay,+
-        beq + +
-        dec TileAnimDelay,+
-        bne ++ +
-*       sta TileAnimDelay,+
-        ldy TileAnimIndex,+
-        lda TileBlastAnim,+
-        cmp #$FE            ; end of "tile-blast" animation? +
-        beq ++ +
-        sta TileAnimFrame,+
-        iny +
-        tya +
-        sta TileAnimIndex,+
-        jsr DrawTileBlast +
-        bcc + +
-        ldx PageIndex +
-        dec TileAnimIndex,+
-*       rts +
- +
-*       inc TileRoutine,+
-        pla +
-        pla +
-        rts +
- +
-; Frame data for tile blasts +
- +
-        TileBlastAnim: +
-        .byte $06,$07,$00,$FE +
-        .byte $07,$06,$01,$FE +
-        .byte $07,$06,$02,$FE +
-        .byte $07,$06,$03,$FE +
-        .byte $07,$06,$04,$FE +
-        .byte $07,$06,$05,$FE +
-        .byte $07,$06,$09,$FE +
-        .byte $07,$06,$0A,$FE +
-        .byte $07,$06,$0B,$FE +
-        .byte $07,$06,$08,$FE +
- +
-        .byte $00 +
-        .byte $00 +
- +
-;-----------------------------------------------[ RESET ]-------------------------------------------- +
- +
-RESET: +
-LFFB0:  SEI                             ;Disables interrupt +
-LFFB1:  CLD                             ;Sets processor to binary mode +
-LFFB2:  LDX #$00                        ; +
-LFFB4:  STX PPUControl0                 ;Clear PPU control registers +
-LFFB7:  STX PPUControl1                 ; +
-LFFBA:* LDA PPUStatus                   ; +
-LFFBD:  BPL -                           ;Wait for VBlank +
-LFFBF:* LDA PPUStatus                   ; +
-LFFC2:  BPL -                           ; +
-LFFC4:  ORA #$FF                        ; +
-LFFC6:  STA MMC1Reg0                    ;Reset MMC1 chip +
-LFFC9:  STA MMC1Reg1                    ;(MSB is set) +
-LFFCC:  STA MMC1Reg2                    ; +
-LFFCF:  STA MMC1Reg3                    ; +
-LFFD2:  JMP Startup                     ;($C01A)Do preliminary housekeeping. +
- +
-;Not used. +
-LFFD5:  .byte $FF, $FF, $FF, $4C, $E4, $B3, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF, $FF +
-LFFE5:  .byte $FF, $FF, $FF, $FF, $4D, $45, $54, $52, $4F, $49, $44, $E4, $8D, $00, $00, $38 +
-LFFF5:  .byte $04, $01, $06, $01, $BC +
- +
-;-----------------------------------------[ Interrupt vectors ]-------------------------------------- +
- +
-LBFFA:  .word NMI                       ;($C0D9)NMI vector. +
-LBFFC:  .word RESET                     ;($FFB0)Reset vector. +
-LBFFE:  .word RESET                     ;($FFB0)IRQ vector. +
-</code> +
m1/disassembly/game_engine_page.1457285342.txt.gz · Last modified: by 127.0.0.1