;Eye Door Disassembly ;by Herald83 ;Info { ; Eye doors consist of three PLMs, the eye itself (center two tiles), the top spike and the bottom spike. ; The Low byte is the door index, all three PLMs share the same index. The High byte is 00. ; Standard "hits to open" is 0003. ; The eye remains inactive when Samus is farther away, becomes active when within 6 horizontal tiles, goes inactive when Samus is too close. While active the eye opens, shoots three times, closes and cycles. The projectile deals 4 base damage (no suits) to Samus. ; Shooting with missile or super causes eye to flash and dust puff to be drawn. ; The spike PLMs wiggle while door is active and inflict spike damage if Samus touches them. You need to be in morph ball mode to actually hit them though, because the eye itself will prevent you from hitting it. } ;PLM Headers { ;tile AD isn't part of the door PLM itself, it's the terrain around the door ;AAE3 is shared with tons of other PLMs and just points an 86BC instruction. I'm not sure if/how it is used by the Top Spikes so I left it in for reference. ;KEJ regarding AAE3: these PLMs simply run their setup and do nothing else. ;Dir Part PLM -> Header Tile Table ;Left Eye DB56 -> DA8C D81E ; Top DB5A -> DAB9 D8E9 AAE3 ; Bottom DB60 -> DAB9 D91F ;Right Eye DB48 -> DA8C D955 CA-CD (open, mid, closed, flash) ; Top DB4C -> DAB9 DA20 AAE3 AA-AC ; Bottom DB52 -> DAB9 DA56 } ;DB56 & DB52: Eye PLM { ; Setup Routine { org $84DA8C PHY LDA $1DC7,Y ;PLM Room argument JSR $80818E LDA $7ED8B0,X ;Opened door bit array. D0-EF are never used PLY AND $05E7 : BNE + ;Often used to check bits for completed tasks/picked up items LDX $1C87,Y ; PLM's location in the room (nth block * 2) LDA #$C044,Y JSR $82B4 LDA $1DC7,Y : CLC : ADC $07A5 : ADC $07A5 : TAX ;Current room's width in blocks LDA #$D0FF JSR $82B4 + RTS } ; Shared Routines { org $84D77A ;fire projectile! LDA $0000,Y PHY LDY #$B743 : JSR $868097 ;KEJ: spawns some kind of projectiles? Only used by gate PLMs, so far as I can see. Also used by some enemies. LDA #$004C : JSR $8090CB PLY INY : INY RTS org $84D790 ;run once when hit, after checking for death, while eye is closed LDA $0000,Y PHY LDY #$B751 : JSR $868097 ;KEJ: spawns some kind of projectiles? Only used by gate PLMs, so far as I can see. Also used by some enemies. PLY INY : INY RTS org $84D79F ;wildly guessing this animates the smoke? that seems to have 4 frames worth of animation. run twice when hit plus twice after checking for death (either result) PHY LDA #$030A : LDY #$E517 : JSR $868097 ;KEJ: spawns some kind of projectiles? Only used by gate PLMs, so far as I can see. Also used by some enemies. LDA #$030A : LDY #$E517 : JSR $868097 ;KEJ: spawns some kind of projectiles? Only used by gate PLMs, so far as I can see. Also used by some enemies. PLY RTS org $84D7B6 ;run twice, only in death setup PHY LDA #$000B : LDY #$E517 : JSR $868097 ;KEJ: spawns some kind of projectiles? Only used by gate PLMs, so far as I can see. Also used by some enemies. PLY RTS org $84D7DA ;change blue door to shootable blue door PHX LDA $1C87,x : SEC : SBC $07A5 : SBC $07A5 : STA $1C87,x : TAX LDA #$C040 JSR $82B4 ;X must contain a block location in ram, and A has new status for it. High byte becomes the new block-prop (second nybble should be 0), and low byte becomes the new bts value. TXA : CLC : ADC $07A5 : ADC $07A5 : TAX LDA #$D0FF JSR $82B4 TXA : CLC : ADC $07A5 : ADC $07A5 : TAX LDA #$D0FE JSR $82B4 TXA : CLC : ADC $07A5 : ADC $07A5 : TAX LDA #$D0FD JSR $82B4 PLX RTS } ; DB56: Facing Left { ; Tile Draws { org $849BF7 ;eye closed + draw top/bot A db $04 db $80 db $AA,$84 db $CC,$84 db $CC,$8C db $AA,$8C dw $0000 org $849C03 ;eye closed db $02 db $80 db $CC,$84 db $CC,$8C dw $0000 org $849C0B ;eye changing db $02 db $80 db $CB,$84 db $CB,$8C dw $0000 org $849C13 ;eye open, shootable db $02 db $80 db $CA,$C4 db $CA,$DC dw $0000 org $849C1B ;eye flash when shot db $02 db $80 db $CD,$84 db $CD,$8C dw $0000 org $849C23 ;eye open, solid db $02 db $80 db $CA,$84 db $CA,$8C dw $0000 org $84A9A7 ;blue door; dunno if this is distinct from the blue door's routines db $04 db $80 db $0C,$80 db $2C,$D0 db $2C,$D8 db $0C,$D8 dw $0000 } ; Behavior { org $84D81E dw $8A72,$D8E3 ;Load the room argument, and if positive, check that door bit. If set, use the argument as the next instruction. ;$D822 - idle state: close eye if samus is out of range dw $0004,$9C03 ;draw eye closed dw $8D41 : db $06,$04 : dw $D830 ;detection of samus' proximity to the door, first argument is horizontal limit, second is vertical limit, execute program following if true dw $8724,$D822 ;Use the address given by the argument as the next instruction. ;D830 dw $8A24,$D880 ;Hit Animation, Store the argument as the target instruction for special routines. Stored in 7E:DEBC,X dw $86C1,$BD50 ;Projectile Detection (shared with Red Doors) dw $0008,$9C0B ;draw eye changing ;$D83C - active state: shoot samus when she's in range, close eye if too close dw $8D41 : db $01,$04 : dw $D878 ;check proximity and close eye if samus is too close dw $0040,$9C13 ;draw eye open, shootable dw $D77A,$0000 ;fire projectile! dw $0020,$9C13 ;draw eye open, shootable dw $D77A,$0000 ;fire projectile! dw $0020,$9C13 ;draw eye open, shootable dw $D77A,$0000 ;fire projectile! dw $0040,$9C13 ;draw eye open, shootable dw $0006,$9C0B ;draw eye changing dw $0030,$9C03 ;draw eye closed dw $0030,$9C03 ;draw eye closed dw $0006,$9C0B ;draw eye changing dw $8D41 : db $06,$04 : dw $D83C ;check proximity, loop if she stays within range dw $8724,$D822 ;idle if she's too far away ;D878 - close eye when samus is too close dw $0004,$9C03 ;draw eye closed dw $8724,$D83C ;return to active state ;$D880 - take a hit, check for death, return to active state dw $8C10 : db $09 ;go to $80:90CB and play sound dw $D79F dw $D79F dw $8A91 : db $03 : db $D8C4 ;Increment hit counter. If at least as much as the argument (1 byte), set the door as opened, disable preplm code, and goto the second argument (2 bytes) dw $0002,$9C1B ;draw eye flash when hit dw $0002,$9C23 ;draw eye open, solid dw $D79F dw $0002,$9C1B ;draw eye flash when hit dw $0002,$9C23 ;draw eye open, solid dw $0002,$9C1B ;draw eye flash when hit dw $D79F dw $0002,$9C23 ;draw eye open, solid dw $0004,$9C0B ;draw eye changing dw $0008,$9C03 ;draw eye closed dw $D790,$0000 dw $0038,$9C03 ;draw eye closed dw $0004,$9C0B ;draw eye changing dw $0004,$9C23 ;draw eye open, solid dw $8724,$D83C ;return to active state ;D8C4 - death sequence part one - death set up dw $86CA ;Stores #$86D0 to 7E:1CD7,X (RTS). Effectively disables pre-PLM instructions. dw $D7B6 dw $D7B6 dw $D79F dw $D79F dw $D7DA ;change blue door to shootable blue door dw $874E : db $0A ;Set 7E:1D77,X to the argument (# of cycles for door to flash) ;D8D3 - death sequence part two - death animation dw $0003,$9BF7 ;draw eye closed + top/bot A dw $0004,$A9A7 ;draw blue door dw $873F,$D8D3 ;Decrement 7E:1D77,X. loops through animation until zero. dw $8724,$C4B1 ;generate Blue Door facing left (External Pointer) ;D8E3 - Draw blue door if the door bit was set (door is already dead) dw $D7DA ;change blue door to shootable blue door dw $8724,$C4B1 ;generate Blue Door facing left (External Pointer) } } ; DB52: Facing Right { ; Tile Draws { org $849C4F db $04 db $80 db $AA,$80 db $CC,$80 db $CC,$88 db $AA,$88 dw $0000 org $849C5B db $02 db $80 db $CC,$80 db $CC,$88 dw $0000 org $849C63 db $02 db $80 db $CB,$80 db $CB,$88 dw $0000 org $849C6B db $02 db $80 db $CA,$C0 db $CA,$D8 dw $0000 org $849C73 db $02 db $80 db $CD,$80 db $CD,$88 dw $0000 org $849C7B db $02 db $80 db $CA,$80 db $CA,$88 dw $0000 org $84A9E3 db $04 db $80 db $0C,$84 db $2C,$D4 db $2C,$DC db $0C,$DC dw $0000 } ; Behavior { org $84D955 dw $8A72,$DA1A dw $0004,$9C5B dw $8D41 : db $06,$04 : dw $D967 dw $8724,$D959 dw $8A24,$D9B7 dw $86C1,$BD50 dw $0008,$9C63 dw $8D41 : db $01,$04 : dw $D9AF dw $0040,$9C6B dw $D77A,$0014 dw $0020,$9C6B dw $D77A,$0014 dw $0020,$9C6B dw $D77A,$0014 dw $0040,$9C6B dw $0006,$9C63 dw $0030,$9C5B dw $0030,$9C5B dw $0006,$9C63 dw $8D41 : db $06,$04 : dw $D973 dw $8724,$D959 dw $0004,$9C5B dw $8724,$D973 dw $8C10 : db $09 dw $D79F dw $D79F dw $8A91 : db $03 : dw $D9FB dw $0002,$9C73 dw $0002,$9C7B dw $D79F dw $0002,$9C73 dw $0002,$9C7B dw $0002,$9C73 dw $D79F dw $0002,$9C7B dw $0004,$9C63 dw $0008,$9C5B dw $D790,$0004 dw $0038,$9C5B dw $0004,$9C63 dw $0004,$9C7B dw $8724,$D973 dw $86CA dw $D7B6 dw $D7B6 dw $D79F dw $D79F dw $D7C3 dw $874E : db $0A dw $0003,$9C4F dw $0004,$A9E3 dw $873F,$DA0A dw $8724,$C4E2 dw $D7C3 dw $8724,$C4E2 } } } ;DB5A, DB60, DB4C & DB52: Spike Tile PLMs { ; Setup Routine { org $84DAB9 PHY LDA $1DC7,Y JSR $80818E LDA $7ED8B0,X PLY AND $05E7 : BNE + LDX $1C87,Y LDA #$A000 JSR $82B4 + RTS } ; Projectile Detection { ;Used by both spike tiles. Unsure if it's shared with other stuff or not. org $84D753 TXY LDA $1DC7,x JSL $80818E LDA $7ED8B0,x : AND $05E7 : BEQ + TYX LDA #$D779 : STA $1CD7,x LDA $7EDEBC,x : STA $1D27,x LDA #$0001 : STA $7EDE1C,x + RTS } ; DB5A: Left Top Tile { ;Animates the top wiggly spike block of the eye door if the door is still alive ; Tile Draws { org $849C2B ; db $01 db $00 db $AA,$A4 dw $0000 org $849C31 ; db $01 db $00 db $AB,$A4 dw $0000 org $849C37 ; db $01 db $00 db $AC,$A4 dw $0000 } ; Behavior { org $84D8E9 dw $8A72,$D91D ;Check if it still exists, else delete PLM ;D8ED - off loop: samus out of range dw $8D41 : db $06,$10 : dw $D8FB ;proximity detection dw $0008,$9C2B ;first tile dw $8724,$D8ED ;loop ;D8FB dw $8A24,$D91D ;Hit animation dw $86C1,$D753 ;Projectile Detection ;D903 - on loop: samus in range dw $0008,$9C2B ;first tile dw $0008,$9C31 ;second tile dw $0008,$9C37 ;third tile dw $0008,$9C31 ;second tile dw $8D41 : db $06,$10 : dw $D903 ;proximity detection dw $8724,$D8ED ;else return to off loop ;D91D - kill plm dw $86BC ;delete PLM } } ; DB60: Left Bottom Tile { ;Upside-down version of the top tile ; Tile Draws { org $849C3D db $01 db $00 db $AA,$AC dw $0000 org $849C43 db $01 db $00 db $AB,$AC dw $0000 org $849C49 db $01 db $00 db $AC,$AC dw $0000 } ; Behavior { org $84D91F dw $8A72,$D953 ;off loop dw $8D41 : db $06,$10 : dw $D931 dw $0008,$9C3D dw $8724,$D923 ; dw $8A24,$D953 dw $86C1,$D753 ;on loop dw $0008,$9C3D dw $0008,$9C43 dw $0008,$9C49 dw $0008,$9C43 dw $8D41 : db $06,$10 : dw $D939 dw $8724,$D923 ;kill plm dw $86BC } } ; DB4C: Right Top Tile { ; Tile Draws { org $849C83 db $01 db $00 db $AA,$A0 dw $0000 org $849C89 db $01 db $00 db $AB,$A0 dw $0000 org $849C8F db $01 db $00 db $AC,$A0 dw $0000 } ; Behavior { org $84DA20 dw $8A72,$DA54 ;off loop dw $8D41 : db $06,$10 : dw $DA32 dw $0008,$9C83 dw $8724,$DA24 ; dw $8A24,$DA54 dw $86C1,$D753 ;on loop dw $0006,$9C83 dw $0006,$9C89 dw $0006,$9C8F dw $0006,$9C89 dw $8D41 : db $06,$10 : dw $DA3A dw $8724,$DA24 ;kill plm dw $86BC } } ; DB52: Right Bottom Tile { ; Tile Draws { org $849C95 db $01 db $00 db $AA,$A8 dw $0000 org $849C9B db $01 db $00 db $AB,$A8 dw $0000 org $849CA1 db $01 db $00 db $AC,$A8 dw $0000 } ; Behavior { org $84DA56 dw $8A72,$DA8A ;off loop dw $8D41 : db $06,$10 : dw $DA68 dw $0008,$9C95 dw $8724,$DA5A ; dw $8A24,$DA8A dw $86C1,$D753 ;on loop dw $0006,$9C95 dw $0006,$9C9B dw $0006,$9CA1 dw $0006,$9C9B dw $8D41 : db $06,$10 : dw $DA70 dw $8724,$DA5A ;kill plm dw $86BC } } }