Grapple code documentation and disassembly. We start off at the main weapons projectile spawn routine @ $90/DD3D. This will check $0D32 (pointer to code for grapple beam) which is initialized to #$C4F0 (not sure when). #$C4F0 basically is the default secondary routine run from the main grapple routine. If $0D32 is not #$C4F0 it does some stuff unrelated to grapple. If it is, then it loads the current HUD selection and jumps to specific projectile routines. The one it jumps to for grapple being selected is @ $90/DD6F. This JSL's to $9B/C490. This is THE routine that handles everything for grapple beam. So let's look at $9BC490 then. $9BC490 PHP : PHB : PHK : PLB : REP #$30 ;the usual JSL setup stuffs LDA $0CF6 : BEQ + ;some sort of grapple specific timer? set to A when grapple fired DEC A : STA $0CF6 + LDA $0A64 : AND #$FFFE : STA $0A64 ;turn off the flag for samus currently grappled to something JSR $B861 ;use movement type and current position/state to check if grapple beam needs to force-cancel ;has the possibility of changing $0D32 to #$C856 (force cancel) or #$C51E (unknown atm) PEA $C4B0 ;push effective address onto stack. next RTS will return to right after this set address JMP ($0D32) ;jump to address pointer stored in $0D32. This is where the "meat" of grapple's stuff happens LDA $0D32 ;after the jump is run, this is where we return to. reload $0D32 CMP #$C4F0 : BEQ ++ ;check if default pointer, branch if so (clear flag for samus in liquid?) CMP #$C856 : BPL ++ ;check if pointer is greater than or equal to #$C856, branch if so (clear flag for samus in liquid?) LDA $0A74 : BIT #$0004 : BNE ++ ;Samus palette index? check for bit 4, branch if so (clear flag for samus in liquid?) LDA $196E : BEQ ++ ;FX3 type, branch if no FX3 (clear flag for samus in liquid?) JSL $90EC58 ;calculate Samus's lower and upper boundaries, then puts them in $12 and $14 respectively LDA $195E : BMI ++ ;actual FX3 height, branch if Samus is above FX3 (clear flag for samus in liquid?) CMP $12 : BPL ++ ;currently holds samus lower boundary, branch if 0 or greater (clear flag for samus in liquid?) LDA $0CF4 : ORA #$0001 : STA $0CF4 ;after ALL that, we've determined that apparently Samus is in a liquid of some sort, so set the flag PLB : PLP : RTL ;and end the routine ++ LDA $0CF4 ;Flags. First bit set if Samus is in liquid, last bit cleared when grapple beam hits grapple block. AND #$FFFE : STA $0CF4 ;clearing a flag, not sure why PLB : PLP : RTL ;and end $9BB861 LDA $0A1F : AND #$00FF : TAX ;load Samus' current movement type LDA $B8B8,x : AND #$00FF ;and use as index to load a value from a table BEQ + ;branch if value is 00 (will either be 00 or 01) ;basically, it will branch if samus' movement type allows for a beam firing of any kind +-+ LDA $0D32 : CMP #$C4F0 : BEQ ++ ;load grapple code pointer, if default then branch to end LDA #$C856 : STA $0D32 ;if not default pointer, load a new one and store it (#$C856 force-cancel grapple beam?) ++ RTS + LDA $0D32 ;if Samus' movement type allows for beam firing, we come here CMP #$C4F0 : BEQ ++ ;end if default pointer CMP #$C77E : BPL ++ ;if pointer is #$C77E or greater, end LDA $0A1C : ASL A : ASL A : ASL A ;load current position/state TAX : LDA $91B62C,x ;and use as index for a table in $91 (unknown use) AND #$00FF : BIT #$00F0 : BNE +-+ ;probably similar to $9BB8B8 table, checks to see if it should force cancel beam CMP $0D34 : BNE +++ : RTS ;check direction to fire grapple, if non-zero (assumed up direction) then branch +++ LDA $0CF6 : BEQ +-+ ;some sort of grapple specific timer? set to A when grapple fired. if 0 check for force cancel beam LDA #$0007 : JSL $809049 ;play short grapple sound LDA #$C51E : STA $0D32 : RTS ;store #$C51E to grapple code pointer and end $9BB8B8 table value | movement type value | | movement type description | | | 00 00 = Standing 00 01 = Walking/running 00 02 = normal jump 01 03 = spin jump 01 04 = morph ball on ground 00 05 = crouch 00 06 = falling 01 07 = Glitchy (morph ball/spinjump), unused? 01 08 = morph ball in air 01 09 = Glitchy morph ball, unused? 01 0A = Hurt 00 0B = Can fire grapple beam, not moving. (unused?) 00 0C = Can fire grapple beam and change pose, no movement. (unused?) 01 0D = Can change pose, no movement or firing. (unused?) 01 0E = Turning around 01 0F = Standing/crouching, and crouching/morphball 00 10 = Moonwalking 01 11 = spring ball on ground 01 12 = spring ball in air 01 13 = falling with spring ball 01 14 = wall jump 00 15 = Ran into a wall 00 16 = Grappling 01 17 = Turning in mid-air (jumping) 01 18 = Turning while falling? 01 19 = Spin back 00 1A = Grabbed by Draygon 01 1B = Superjump / Drained by Metroid / Damaged by MB's attacks / CF And that's the main grapple routine. It has a lot more possible code to run though because of $0D32. ;-------------------------------------------------------------------------- Next we'll look at each of the possible code pointers stored to $0D32. #$C4F0 LDA $8F : BIT $09B2 : BNE ++ ;controller 1 buttons newly pressed this frame, shoot button, branch if pressed LDA $0E00 : BIT $09B2 : BNE ++ ;$8F from last frame, shoot button, branch if pressed LDA $0CD0 : BEQ + ;current charge of arm cannon. this should always branch if this is running >.> STZ $0CD0 : STZ $0CD6 : STZ $0CD8 ;clear charge and it's animations and reset palette STZ $0CDA : STZ $0CDC : STZ $0CDE STZ $0CE0 : JSL $91DEBA + RTS ++ LDA $0A1C : CMP #$00F0 : BEQ $25 [$C54B] ;check position/state (grabbed by Draygon facing left, moving) CMP #$00BE : BEQ $20 [$C54B] ;check position/state (grabbed by Draygon facing right, moving) $9BC52B 0A ASL A $9BC52C 0A ASL A $9BC52D 0A ASL A $9BC52E AA TAX $9BC52F BF 2D B6 91 LDA $91B62D,x[$91:B975] $9BC533 29 FF 00 AND #$00FF $9BC536 85 16 STA $16 [$7E:0016] $9BC538 BF 2C B6 91 LDA $91B62C,x[$91:B974] $9BC53C 29 FF 00 AND #$00FF $9BC53F 89 F0 00 BIT #$00F0 $9BC542 F0 0C BEQ $0C [$C550] $9BC550 8D 34 0D STA $0D34 [$7E:0D34] $9BC553 0A ASL A $9BC554 AA TAX $9BC555 BD DB C0 LDA $C0DB,x[$9B:C0DD] $9BC558 8D 22 0D STA $0D22 [$7E:0D22] $9BC55B BD EF C0 LDA $C0EF,x[$9B:C0F1] $9BC55E 8D 24 0D STA $0D24 [$7E:0D24] $9BC561 BD 04 C1 LDA $C104,x[$9B:C106] $9BC564 8D FA 0C STA $0CFA [$7E:0CFA] $9BC567 8D FC 0C STA $0CFC [$7E:0CFC] $9BC56A A9 0A 00 LDA #$000A $9BC56D 8D F6 0C STA $0CF6 [$7E:0CF6] $9BC570 AD 1C 0A LDA $0A1C [$7E:0A1C] $9BC573 C9 49 00 CMP #$0049 $9BC576 F0 10 BEQ $10 [$C588] $9BC578 C9 4A 00 CMP #$004A $9BC57B F0 0B BEQ $0B [$C588] $9BC57D AD 1F 0A LDA $0A1F [$7E:0A1F] $9BC580 29 FF 00 AND #$00FF $9BC583 C9 01 00 CMP #$0001 $9BC586 F0 40 BEQ $40 [$C5C8] $9BC588 BD 22 C1 LDA $C122,x[$9B:C124] $9BC58B 8D 02 0D STA $0D02 [$7E:0D02] $9BC58E BD 36 C1 LDA $C136,x[$9B:C138] $9BC591 38 SEC $9BC592 E5 16 SBC $16 [$7E:0016] $9BC594 8D 04 0D STA $0D04 [$7E:0D04] $9BC597 AD F6 0A LDA $0AF6 [$7E:0AF6] $9BC59A 48 PHA $9BC59B 18 CLC $9BC59C 7D 22 C1 ADC $C122,x[$9B:C124] $9BC59F 8D 08 0D STA $0D08 [$7E:0D08] $9BC5A2 8D 16 0D STA $0D16 [$7E:0D16] $9BC5A5 68 PLA $9BC5A6 18 CLC $9BC5A7 7D 4A C1 ADC $C14A,x[$9B:C14C] $9BC5AA 8D 1A 0D STA $0D1A [$7E:0D1A] $9BC5AD AD FA 0A LDA $0AFA [$7E:0AFA] $9BC5B0 38 SEC $9BC5B1 E5 16 SBC $16 [$7E:0016] $9BC5B3 48 PHA $9BC5B4 18 CLC $9BC5B5 7D 36 C1 ADC $C136,x[$9B:C138] $9BC5B8 8D 0C 0D STA $0D0C [$7E:0D0C] $9BC5BB 8D 18 0D STA $0D18 [$7E:0D18] $9BC5BE 68 PLA $9BC5BF 18 CLC $9BC5C0 7D 5E C1 ADC $C15E,x[$9B:C160] $9BC5C3 8D 1C 0D STA $0D1C [$7E:0D1C] $9BC5C6 80 3E BRA $3E [$C606] $9BC5C8 BD 72 C1 LDA $C172,x[$9B:C182] $9BC5CB 8D 02 0D STA $0D02 [$7E:0D02] $9BC5CE BD 86 C1 LDA $C186,x[$9B:C196] $9BC5D1 38 SEC $9BC5D2 E5 16 SBC $16 [$7E:0016] $9BC5D4 8D 04 0D STA $0D04 [$7E:0D04] $9BC5D7 AD F6 0A LDA $0AF6 [$7E:0AF6] $9BC5DA 48 PHA $9BC5DB 18 CLC $9BC5DC 7D 72 C1 ADC $C172,x[$9B:C182] $9BC5DF 8D 08 0D STA $0D08 [$7E:0D08] $9BC5E2 8D 16 0D STA $0D16 [$7E:0D16] $9BC5E5 68 PLA $9BC5E6 18 CLC $9BC5E7 7D 9A C1 ADC $C19A,x[$9B:C1AA] $9BC5EA 8D 1A 0D STA $0D1A [$7E:0D1A] $9BC5ED AD FA 0A LDA $0AFA [$7E:0AFA] $9BC5F0 38 SEC $9BC5F1 E5 16 SBC $16 [$7E:0016] $9BC5F3 48 PHA $9BC5F4 18 CLC $9BC5F5 7D 86 C1 ADC $C186,x[$9B:C196] $9BC5F8 8D 0C 0D STA $0D0C [$7E:0D0C] $9BC5FB 8D 18 0D STA $0D18 [$7E:0D18] $9BC5FE 68 PLA $9BC5FF 18 CLC $9BC600 7D AE C1 ADC $C1AE,x[$9B:C1BE] $9BC603 8D 1C 0D STA $0D1C [$7E:0D1C] $9BC606 9C 06 0D STZ $0D06 [$7E:0D06] $9BC609 9C 0A 0D STZ $0D0A [$7E:0D0A] $9BC60C 9C 0E 0D STZ $0D0E [$7E:0D0E] $9BC60F 9C 10 0D STZ $0D10 [$7E:0D10] $9BC612 9C 12 0D STZ $0D12 [$7E:0D12] $9BC615 9C 14 0D STZ $0D14 [$7E:0D14] $9BC618 9C F4 0C STZ $0CF4 [$7E:0CF4] $9BC61B A9 0C 00 LDA #$000C $9BC61E 8D 00 0D STA $0D00 [$7E:0D00] $9BC621 9C FE 0C STZ $0CFE [$7E:0CFE] $9BC624 9C 26 0D STZ $0D26 [$7E:0D26] $9BC627 9C 28 0D STZ $0D28 [$7E:0D28] $9BC62A 9C 2A 0D STZ $0D2A [$7E:0D2A] $9BC62D 9C 2C 0D STZ $0D2C [$7E:0D2C] $9BC630 9C 2E 0D STZ $0D2E [$7E:0D2E] $9BC633 9C 30 0D STZ $0D30 [$7E:0D30] $9BC636 9C 1E 0D STZ $0D1E [$7E:0D1E] $9BC639 9C 20 0D STZ $0D20 [$7E:0D20] $9BC63C A9 02 00 LDA #$0002 $9BC63F 8D 3A 0D STA $0D3A [$7E:0D3A] $9BC642 9C 3C 0D STZ $0D3C [$7E:0D3C] $9BC645 A9 05 00 LDA #$0005 $9BC648 8D 3E 0D STA $0D3E [$7E:0D3E] $9BC64B AD 42 C3 LDA $C342 [$9B:C342] $9BC64E 8D 40 0D STA $0D40 [$7E:0D40] $9BC651 9C 82 0D STZ $0D82 [$7E:0D82] $9BC654 9C 84 0D STZ $0D84 [$7E:0D84] $9BC657 9C 86 0D STZ $0D86 [$7E:0D86] $9BC65A 9C 88 0D STZ $0D88 [$7E:0D88] $9BC65D 9C 8A 0D STZ $0D8A [$7E:0D8A] $9BC660 9C 8C 0D STZ $0D8C [$7E:0D8C] $9BC663 9C 8E 0D STZ $0D8E [$7E:0D8E] $9BC666 9C 90 0D STZ $0D90 [$7E:0D90] $9BC669 9C 38 0D STZ $0D38 [$7E:0D38] $9BC66C 9C 36 0D STZ $0D36 [$7E:0D36] $9BC66F 9C F8 0C STZ $0CF8 [$7E:0CF8] $9BC672 22 87 AF 94 JSL $94AF87[$94:AF87] $9BC676 A9 86 EB LDA #$EB86 $9BC679 8D 5C 0A STA $0A5C [$7E:0A5C] $9BC67C 9C 9E 0A STZ $0A9E [$7E:0A9E] $9BC67F A9 02 00 LDA #$0002 $9BC682 22 F0 AC 90 JSL $90ACF0[$90:ACF0] $9BC686 A9 91 7F LDA #$7F91 $9BC689 8F BE C1 7E STA $7EC1BE[$7E:C1BE] $9BC68D A9 03 C7 LDA #$C703 $9BC690 8D 32 0D STA $0D32 [$7E:0D32] $9BC693 A9 05 00 LDA #$0005 $9BC696 22 3F 90 80 JSL $80903F[$80:903F] $9BC69A A9 01 00 LDA #$0001 $9BC69D 8D D0 0C STA $0CD0 [$7E:0CD0] $9BC6A0 9C C0 0D STZ $0DC0 [$7E:0DC0] $9BC6A3 AD 58 0A LDA $0A58 [$7E:0A58] $9BC6A6 C9 6E 94 CMP #$946E $9BC6A9 D0 06 BNE $06 [$C6B1] $9BC6AB A9 37 A3 LDA #$A337 $9BC6AE 8D 58 0A STA $0A58 [$7E:0A58] $9BC6B1 60 RTS $9BC703 A5 8B LDA $8B [$7E:008B] $9BC705 2C B2 09 BIT $09B2 [$7E:09B2] $9BC708 D0 07 BNE $07 [$C711] $9BC70A A9 56 C8 LDA #$C856 $9BC70D 8D 32 0D STA $0D32 [$7E:0D32] $9BC710 60 RTS $9BC711 20 D4 B8 JSR $B8D4 [$9B:B8D4] $9BC714 AD FE 0C LDA $0CFE [$7E:0CFE] $9BC717 18 CLC $9BC718 6D 00 0D ADC $0D00 [$7E:0D00] $9BC71B 8D FE 0C STA $0CFE [$7E:0CFE] $9BC71E C9 80 00 CMP #$0080 $9BC721 30 02 BMI $02 [$C725] $9BC723 80 E5 BRA $E5 [$C70A] $9BC725 22 9A 9E A0 JSL $A09E9A[$A0:9E9A] $9BC729 20 07 B9 JSR $B907 [$9B:B907] $9BC72C 90 05 BCC $05 [$C733] $9BC72E A8 TAY $9BC72F D0 F2 BNE $F2 [$C723] $9BC731 80 08 BRA $08 [$C73B] $9BC733 22 5B A8 94 JSL $94A85B[$94:A85B] $9BC737 90 1F BCC $1F [$C758] $9BC739 50 E8 BVC $E8 [$C723] $9BC73B A9 06 00 LDA #$0006 $9BC73E 22 49 90 80 JSL $809049[$80:9049] $9BC742 20 7C B9 JSR $B97C [$9B:B97C] $9BC745 A9 08 00 LDA #$0008 $9BC748 49 FF FF EOR #$FFFF $9BC74B 1A INC A $9BC74C 8D 00 0D STA $0D00 [$7E:0D00] $9BC74F AD 64 0A LDA $0A64 [$7E:0A64] $9BC752 09 01 00 ORA #$0001 $9BC755 8D 64 0A STA $0A64 [$7E:0A64] $9BC758 60 RTS