mirror of
				https://github.com/MarioSpore/Grinch-AP.git
				synced 2025-10-21 20:21:32 -06:00 
			
		
		
		
	
		
			
				
	
	
		
			1327 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			NASM
		
	
	
	
	
	
			
		
		
	
	
			1327 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			NASM
		
	
	
	
	
	
| lorom
 | |
| 
 | |
| 
 | |
| org $DFFFFD  ; expand ROM to 3MB
 | |
|     DB "EOF"
 | |
| org $80FFD8  ; expand SRAM to 32KB
 | |
|     DB $05                  ; overwrites DB $03
 | |
| 
 | |
| org $80809A  ; patch copy protection
 | |
|     CMP $710000             ; overwrites CMP $702000
 | |
| org $8080A6  ; patch copy protection
 | |
|     CMP $710000             ; overwrites CMP $702000
 | |
| 
 | |
| 
 | |
| 
 | |
| org $8AEAA3  ; skip gruberik intro dialogue
 | |
|     DB $1C,$86,$03          ; L2SASM JMP $8AE784+$0386
 | |
| org $8AEC82  ; skip gruberik save dialogue
 | |
|     DB $1C,$93,$01          ; L2SASM JMP $8AEB1C+$0193
 | |
| org $8AECFE  ; skip gruberik abandon dialogue
 | |
|     DB $1C,$32,$02          ; L2SASM JMP $8AEB1C+$0232
 | |
| org $8AF4E1  ; skip gruberik selan dialogue
 | |
|     DB $1C,$D8,$09          ; L2SASM JMP $8AEB1C+$09D8
 | |
| org $8AF528  ; skip gruberik guy dialogue
 | |
|     DB $1C,$1E,$0A          ; L2SASM JMP $8AEB1C+$0A1E
 | |
| org $8AF55F  ; skip gruberik arty dialogue
 | |
|     DB $1C,$67,$0A          ; L2SASM JMP $8AEB1C+$0A67
 | |
| org $8AF5B2  ; skip gruberik tia dialogue
 | |
|     DB $1C,$C3,$0A          ; L2SASM JMP $8AEB1C+$0AC3
 | |
| org $8AF61A  ; skip gruberik dekar dialogue
 | |
|     DB $1C,$23,$0B          ; L2SASM JMP $8AEB1C+$0B23
 | |
| org $8AF681  ; skip gruberik lexis dialogue
 | |
|     DB $1C,$85,$0B          ; L2SASM JMP $8AEB1C+$0B85
 | |
| 
 | |
| org $8EA349  ; skip ancient cave entrance dialogue
 | |
|     DB $1C,$B0,$01          ; L2SASM JMP $8EA1AD+$01B0
 | |
| org $8EA384  ; reset architect mode, skip ancient cave exit dialogue
 | |
|     DB $1B,$E1,$1C,$2B,$02  ; clear flag $E1, L2SASM JMP $8EA1AD+$022B
 | |
| org $8EA565  ; skip ancient cave leaving dialogue
 | |
|     DB $1C,$E9,$03          ; L2SASM JMP $8EA1AD+$03E9
 | |
| 
 | |
| org $8EA653  ; skip master intro dialogue
 | |
|     DB $1C,$0F,$01          ; L2SASM JMP $8EA5FA+$010F
 | |
| org $8EA721  ; skip master fight dialogue
 | |
|     DB $1C,$45,$01          ; L2SASM JMP $8EA5FA+$0145
 | |
| org $8EA74B  ; skip master victory dialogue
 | |
|     DB $1C,$AC,$01          ; L2SASM JMP $8EA5FA+$01AC
 | |
| org $8EA7AA  ; skip master key dialogue and animation
 | |
|     DB $1C,$EE,$01          ; L2SASM JMP $8EA5FA+$01EE
 | |
| org $8EA7F4  ; skip master goodbye dialogue
 | |
|     DB $1C,$05,$02          ; L2SASM JMP $8EA5FA+$0205
 | |
| org $8EA807  ; skip master not fight dialogue
 | |
|     DB $1C,$18,$02          ; L2SASM JMP $8EA5FA+$0218
 | |
| 
 | |
| org $94AC45  ; connect ancient cave exit stairs to gruberik entrance
 | |
|     DB $67,$09,$18,$68
 | |
| org $948DE1  ; connect gruberik west border to ancient cave entrance
 | |
|     DB $07,$08,$14,$F0
 | |
| org $948DEA  ; connect gruberik south border to ancient cave entrance
 | |
|     DB $07,$08,$14,$F0
 | |
| org $948DF3  ; connect gruberik north border to ancient cave entrance
 | |
|     DB $07,$08,$14,$F0
 | |
| 
 | |
| 
 | |
| 
 | |
| ; archipelago item
 | |
| org $96F9AD  ; properties
 | |
|     DB $00,$00,$00,$E4,$00,$00,$00,$00,$00,$00,$00,$00,$00
 | |
| org $9EDD60  ; name
 | |
|     DB "AP item     "       ; overwrites "Key30       "
 | |
| org $9FA900  ; sprite
 | |
|     incbin "ap_logo/ap_logo.bin"
 | |
|     warnpc $9FA980
 | |
| ; sold out item
 | |
| org $96F9BA  ; properties
 | |
|     DB $00,$00,$00,$10,$00,$00,$00,$00,$00,$00,$00,$00,$00
 | |
| org $9EDD6C  ; name
 | |
|     DB "SOLD OUT    "       ; overwrites "Crown       "
 | |
| 
 | |
| 
 | |
| org $D08000  ; signature, start of expanded data area
 | |
|     DB "ArchipelagoLufia"
 | |
| 
 | |
| 
 | |
| org $D09800  ; start of expanded code area
 | |
| 
 | |
| 
 | |
| 
 | |
| ; initialize
 | |
| pushpc
 | |
| org $808046
 | |
|     ; DB=$80, x=1, m=1
 | |
|     JSL Init                ; overwrites JSL $809037
 | |
| pullpc
 | |
| 
 | |
| Init:
 | |
| ; check signature
 | |
|     LDX.b #$0F
 | |
| -:  LDA $D08000,X
 | |
|     CMP $F02000,X
 | |
|     BNE +
 | |
|     DEX
 | |
|     BPL -
 | |
|     BRA ++
 | |
| ; set up DMA to clear expanded SRAM
 | |
| +:  STZ $211C               ; force multiplication results (MPYx) to zero
 | |
|     REP #$10
 | |
|     LDA.b #$80
 | |
|     STA $4300               ; transfer B-bus to A-bus, with A-bus increment
 | |
|     LDA.b #$34
 | |
|     STA $4301               ; B-bus source register $2134 (MPYL)
 | |
|     LDX.w #$2000
 | |
|     STX $4302               ; A-bus destination address $F02000 (SRAM)
 | |
|     LDA.b #$F0
 | |
|     STA $4304
 | |
|     LDX.w #$6000
 | |
|     STX $4305               ; transfer 24kB
 | |
|     LDA.b #$01
 | |
|     STA $420B               ; start DMA channel 1
 | |
| ; sign expanded SRAM
 | |
|     PHB
 | |
|     TDC
 | |
|     LDA.b #$3F
 | |
|     LDX.w #$8000
 | |
|     LDY.w #$2000
 | |
|     MVN $F0,$D0             ; copy 64B from $D08000 to $F02000
 | |
|     PLB
 | |
| ++: SEP #$30
 | |
|     JSL $809037             ; (overwritten instruction)
 | |
|     RTL
 | |
| 
 | |
| 
 | |
| 
 | |
| ; transmit checks from chests
 | |
| pushpc
 | |
| org $8EC1EB
 | |
|     JML TX                  ; overwrites JSL $83F559
 | |
| pullpc
 | |
| 
 | |
| TX:
 | |
|     JSL $83F559             ; (overwritten instruction) chest opening animation
 | |
|     REP #$20
 | |
|     LDA $7FD4EF             ; read chest item ID
 | |
|     BIT.w #$0200            ; test for iris item flag
 | |
|     BEQ +
 | |
|     JSR ReportLocationCheck
 | |
|     SEP #$20
 | |
|     JML $8EC2DC             ; skip item get process; consider chest emptied
 | |
| +:  BIT.w #$4200            ; test for blue chest flag
 | |
|     BEQ +
 | |
|     LDA $F02048             ; load total blue chests checked
 | |
|     CMP $D08010             ; compare against max AP item number
 | |
|     BPL +
 | |
|     LDA $F02040             ; load check counter
 | |
|     INC                     ; increment check counter
 | |
|     STA $F02040             ; store check counter
 | |
|     SEP #$20
 | |
|     JML $8EC2DC             ; skip item get process; consider chest emptied
 | |
| +:  SEP #$20
 | |
|     JML $8EC1EF             ; continue item get process
 | |
| 
 | |
| 
 | |
| 
 | |
| ; transmit checks from script events
 | |
| pushpc
 | |
| org $80A435
 | |
|     ; DB=$8E, x=0, m=1
 | |
|     JML ScriptTX            ; overwrites STA $7FD4F1
 | |
| pullpc
 | |
| 
 | |
| ScriptTX:
 | |
|     STA $7FD4F1             ; (overwritten instruction)
 | |
|     LDA $05AC               ; load map number
 | |
|     CMP.b #$F1              ; check if ancient cave final floor
 | |
|     BNE +
 | |
|     REP #$20
 | |
|     LDA $7FD4EF             ; read script item id
 | |
|     CMP.w #$01C2            ; test for ancient key
 | |
|     BNE +
 | |
|     JSR ReportLocationCheck
 | |
|     SEP #$20
 | |
|     JML $80A47F             ; skip item get process
 | |
| +:  SEP #$20
 | |
|     JML $80A439             ; continue item get process
 | |
| 
 | |
| 
 | |
| 
 | |
| ReportLocationCheck:
 | |
|     PHA                     ; remember item id
 | |
|     LDA $F0204A             ; load other locations count
 | |
|     INC                     ; increment check counter
 | |
|     STA $F0204A             ; store other locations count
 | |
|     DEC
 | |
|     ASL
 | |
|     TAX
 | |
|     PLA
 | |
|     STA $F02060,X           ; store item id in checked locations list
 | |
|     RTS
 | |
| 
 | |
| 
 | |
| 
 | |
| ; report event flag based goal completion
 | |
| Goal:
 | |
|     TDC
 | |
|     LDA $0797               ; load EV flags $C8-$CF (iris sword, iris shield, ..., iris pot)
 | |
|     TAX
 | |
|     LDA $0798               ; load EV flags $D0-$D7 (iris tiara, boss, others...)
 | |
|     TAY
 | |
|     AND.b #$02              ; test boss victory
 | |
|     LSR
 | |
|     STA $F02031             ; report boss victory goal
 | |
|     TYA
 | |
|     AND.b #$01              ; test iris tiara
 | |
|     ADC $97B418,X           ; test remaining iris items via predefined lookup table for number of bits set in a byte
 | |
|     CMP $D08017             ; compare with number of treasures required
 | |
|     BMI +
 | |
|     LDA.b #$01
 | |
|     STA $F02032             ; report iris treasures goal
 | |
|     AND $F02031
 | |
|     STA $F02033             ; report boss victory + iris treasures goal
 | |
| +:  RTS
 | |
| 
 | |
| 
 | |
| 
 | |
| ; receive items
 | |
| RX:
 | |
|     REP #$20
 | |
|     LDA $F02802             ; load snes side received items processed counter
 | |
|     CMP $F02800             ; compare with client side received items counter
 | |
|     BPL +
 | |
|     INC
 | |
|     STA $F02802             ; increase received items processed counter
 | |
|     ASL
 | |
|     TAX
 | |
|     LDA $F02802,X           ; load received item ID
 | |
|     BRA ++
 | |
| +:  LDA $F02046             ; load snes side found AP items processed counter
 | |
|     CMP $F02044             ; compare with client side found AP items counter
 | |
|     BPL +
 | |
|     LDA $F02044
 | |
|     STA $F02046             ; increase AP items processed counter
 | |
|     LDA.w #$01CA            ; load "AP item" ID
 | |
| ++: STA $7FD4EF             ; store it as a "chest"
 | |
|     JSR SpecialItemGet
 | |
|     SEP #$20
 | |
|     JSL $8EC1EF             ; call chest opening routine (but without chest opening animation)
 | |
|     STZ $A7                 ; cleanup
 | |
|     JSL $83AB4F             ; cleanup
 | |
| +:  SEP #$20
 | |
|     RTS
 | |
| 
 | |
| SpecialItemGet:
 | |
|     BPL +                   ; spells have high bit set
 | |
|     JSR LearnSpell
 | |
| +:  BIT.w #$0200            ; iris items
 | |
|     BEQ +
 | |
|     SEC
 | |
|     SBC.w #$039C
 | |
|     ASL
 | |
|     TAX
 | |
|     LDA $8ED8C3,X           ; load predefined bitmask with a single bit set
 | |
|     ORA $0797
 | |
|     STA $0797               ; set iris item EV flag ($C8-$D0)
 | |
|     BRA ++
 | |
| +:  CMP.w #$01C2            ; ancient key
 | |
|     BNE +
 | |
|     LDA.w #$0008
 | |
|     ORA $0796
 | |
|     STA $0796               ; set ancient key EV flag ($C3)
 | |
|     LDA.w #$0200
 | |
|     ORA $0797
 | |
|     STA $0797               ; set boss item EV flag ($D1)
 | |
|     BRA ++
 | |
| +:  CMP.w #$01BF            ; capsule monster items range from $01B8 to $01BE
 | |
|     BPL ++
 | |
|     SBC.w #$01B1            ; party member items range from $01B2 to $01B7
 | |
|     BMI ++
 | |
|     ASL
 | |
|     TAX
 | |
|     LDA $8ED8C7,X           ; load predefined bitmask with a single bit set
 | |
|     ORA $F02018             ; set unlock bit for party member/capsule monster
 | |
|     STA $F02018
 | |
| ++: RTS
 | |
| 
 | |
| LearnSpell:
 | |
|     STA $0A0B
 | |
|     SEP #$20
 | |
|     LDA.b #$06
 | |
| -:  PHA
 | |
|     JSL $82FD3D             ; teach spell in $0A0B to character determined by A
 | |
|     PLA
 | |
|     DEC
 | |
|     BPL -
 | |
|     REP #$20
 | |
|     LDA $0A0B
 | |
|     RTS
 | |
| 
 | |
| 
 | |
| 
 | |
| ; use items
 | |
| pushpc
 | |
| org $82AE6F
 | |
|     ; DB=$83, x=0, m=1
 | |
|     JSL SpecialItemUse      ; overwrites JSL $81EFDF
 | |
| org $8EFD2E  ; unused region at the end of bank $8E
 | |
|     DB $1E,$0B,$01,$2B,$01,$1A,$02,$00  ; add selan
 | |
|     DB $1E,$0B,$01,$2B,$02,$1A,$03,$00  ; add guy
 | |
|     DB $1E,$0B,$01,$2B,$03,$1A,$04,$00  ; add arty
 | |
|     DB $1E,$0B,$01,$2B,$05,$1A,$05,$00  ; add dekar
 | |
|     DB $1E,$0B,$01,$2B,$04,$1A,$06,$00  ; add tia
 | |
|     DB $1E,$0B,$01,$2B,$06,$1A,$07,$00  ; add lexis
 | |
|     DB $1F,$0B,$01,$2C,$01,$1B,$02,$00  ; remove selan
 | |
|     DB $1F,$0B,$01,$2C,$02,$1B,$03,$00  ; remove guy
 | |
|     DB $1F,$0B,$01,$2C,$03,$1B,$04,$00  ; remove arty
 | |
|     DB $1F,$0B,$01,$2C,$05,$1B,$05,$00  ; remove dekar
 | |
|     DB $1F,$0B,$01,$2C,$04,$1B,$06,$00  ; remove tia
 | |
|     DB $1F,$0B,$01,$2C,$06,$1B,$07,$00  ; remove lexis
 | |
| pullpc
 | |
| 
 | |
| SpecialItemUse:
 | |
|     JSL $81EFDF             ; (overwritten instruction)
 | |
|     REP #$20
 | |
|     LDA $0A06               ; get ID of item being used
 | |
|     CMP.w #$01B8
 | |
|     BPL +
 | |
|     SBC.w #$01B1            ; party member items range from $01B2 to $01B7
 | |
|     BMI +
 | |
|     ASL
 | |
|     TAX
 | |
|     ASL
 | |
|     ASL
 | |
|     ADC.w #$FD2E
 | |
|     STA $09B7               ; set pointer to L2SASM join script
 | |
|     SEP #$20
 | |
|     LDA $8ED8C7,X           ; load predefined bitmask with a single bit set
 | |
|     BIT $077E               ; check against EV flags $02 to $07 (party member flags)
 | |
|     BEQ ++
 | |
|     LDA.b #$30              ; character already present; modify pointer to point to L2SASM leave script
 | |
|     ADC $09B7
 | |
|     STA $09B7
 | |
|     BRA +++
 | |
| ++: LDA $07A9               ; character not present; load EV register $0B (party counter)
 | |
|     CMP.b #$03
 | |
|     BPL +                   ; abort if party full
 | |
| +++ LDA.b #$8E
 | |
|     STA $09B9
 | |
|     PHK
 | |
|     PEA ++
 | |
|     PEA $8DD8
 | |
|     JML $83BB76             ; initialize parser variables
 | |
| ++: NOP
 | |
|     JSL $809CB8             ; call L2SASM parser
 | |
|     TSX
 | |
|     INX #13
 | |
|     TXS
 | |
|     JML $82A45E             ; leave menu
 | |
| +:  SEP #$20
 | |
|     RTL
 | |
| 
 | |
| 
 | |
| 
 | |
| ; main loop
 | |
| pushpc
 | |
| org $83BC16
 | |
|     ; DB=$83, x=0, m=1
 | |
|     JSL MainLoop            ; overwrites LDA $09A7 : BIT.b #$01
 | |
|     NOP
 | |
| pullpc
 | |
| 
 | |
| MainLoop:
 | |
|     JSR RX
 | |
|     JSR Goal
 | |
|     JSR Unlocks
 | |
|     LDA $09A7               ; (overwritten instruction)
 | |
|     BIT.b #$01              ; (overwritten instruction)
 | |
|     RTL
 | |
| 
 | |
| 
 | |
| 
 | |
| Unlocks:
 | |
|     LDA $F02018             ; load party member unlocks from SRAM
 | |
|     STA $0780               ; transfer to flags (WRAM)
 | |
|     LDA $F02019             ; load capsule monster unlocks from SRAM
 | |
|     TAY
 | |
|     LDX.w #$0000
 | |
| -:  TYA
 | |
|     LSR
 | |
|     TAY
 | |
|     BCC +
 | |
|     LDA $82C33C
 | |
|     CMP $11BB,X
 | |
|     BMI +++
 | |
|     BRA ++
 | |
| +:  LDA.b #$00
 | |
| ++: STA $11BB,X             ; unlock/lock capsule monster #X
 | |
| +++ INX
 | |
|     CPX.w #$0007
 | |
|     BNE -
 | |
|     LDA $F02019
 | |
|     TAY
 | |
|     BNE +
 | |
|     LDA.b #$FF
 | |
|     STA $0A7F               ; lock capsule menu
 | |
|     BRA ++
 | |
| +:  LDA.b #$07
 | |
|     STA $0A7F               ; unlock capsule menu
 | |
|     LDA $F02019
 | |
|     BIT.b #$80              ; track whether one-time setup has been done before
 | |
|     BNE ++
 | |
|     ORA.b #$80
 | |
|     STA $F02019
 | |
|     CMP.b #$FF
 | |
|     BEQ ++                  ; all capsule monsters available; don't overwrite starting capsule
 | |
|     LDX.w #$FFFF
 | |
|     TYA
 | |
| -:  LSR
 | |
|     INX
 | |
|     BCC -
 | |
|     TXA
 | |
|     STA $11A3               ; activate first unlocked capsule monster
 | |
|     STA $7FB5FB
 | |
|     STA $F02016
 | |
|     JSL $82C2FD             ; run setup routine for capsule monsters
 | |
| ++: RTS
 | |
| 
 | |
| 
 | |
| 
 | |
| ; lock party members
 | |
| pushpc
 | |
| org $8AEC3E
 | |
|     DB $15,$C4,$A4,$01      ; L2SASM JMP $8AEB1C+$01A4 if flag $C4 set
 | |
| org $8AECC0
 | |
|     DB $6C,$65,$00,$FA          ; (overwritten instruction)
 | |
|     DB $15,$12,$AE,$01,$2E,$66  ; remove selan if flag $12 clear
 | |
|     DB $15,$13,$B4,$01,$2E,$67  ; remove guy if flag $13 clear
 | |
|     DB $15,$14,$BA,$01,$2E,$68  ; remove arty if flag $14 clear
 | |
|     DB $15,$15,$C0,$01,$2E,$6A  ; remove dekar if flag $15 clear
 | |
|     DB $15,$16,$C6,$01,$2E,$69  ; remove tia if flag $16 clear
 | |
|     DB $15,$17,$CC,$01,$2E,$6B  ; remove lexis if flag $17 clear
 | |
|     DB $00
 | |
| pullpc
 | |
| 
 | |
| 
 | |
| 
 | |
| ; party member items (IDs $01B2 - $01B7)
 | |
| pushpc
 | |
| org $96F875  ; properties
 | |
|     DB $40,$00,$00,$E9,$64,$00,$00,$00,$00,$00,$00,$00,$00
 | |
|     DB $40,$00,$00,$E0,$64,$00,$00,$00,$00,$00,$00,$00,$00
 | |
|     DB $40,$00,$00,$EB,$64,$00,$00,$00,$00,$00,$00,$00,$00
 | |
|     DB $40,$00,$00,$ED,$64,$00,$00,$00,$00,$00,$00,$00,$00
 | |
|     DB $40,$00,$00,$E8,$64,$00,$00,$00,$00,$00,$00,$00,$00
 | |
|     DB $40,$00,$00,$EF,$64,$00,$00,$00,$00,$00,$00,$00,$00
 | |
| org $979EC6  ; descriptions
 | |
|     DB "Parcelyte commander.    "    : DB $00
 | |
|     DB "A guy named Guy.  "          : DB $00
 | |
|     DB "(Or was it Artea?)         " : DB $00
 | |
|     DB "Strongest warrior.   "       : DB $00
 | |
|     DB "Elcid shopkeeper. "          : DB $00
 | |
|     DB "Great inventor."             : DB $00
 | |
| org $97FDAC  ; remove from scenario item list
 | |
|     DW $0000,$0000,$0000,$0000,$0000,$0000
 | |
| org $9EDC40  ; names
 | |
|     DB "Selan       "       ; overwrites "Wind key    "
 | |
|     DB "Guy         "       ; overwrites "Cloud key   "
 | |
|     DB "Arty        "       ; overwrites "Light key   "
 | |
|     DB "Dekar       "       ; overwrites "Sword key   "
 | |
|     DB "Tia         "       ; overwrites "Tree key    "
 | |
|     DB "Lexis       "       ; overwrites "Flower key  "
 | |
| pullpc
 | |
| 
 | |
| ; capsule monster items (IDs $01B8 - $01BE)
 | |
| pushpc
 | |
| org $96F8C3  ; properties
 | |
|     DB $00,$00,$00,$EE,$12,$00,$00,$00,$00,$00,$00,$00,$00
 | |
|     DB $00,$00,$00,$EE,$12,$00,$00,$00,$00,$00,$00,$00,$00
 | |
|     DB $00,$00,$00,$EE,$12,$00,$00,$00,$00,$00,$00,$00,$00
 | |
|     DB $00,$00,$00,$EE,$12,$00,$00,$00,$00,$00,$00,$00,$00
 | |
|     DB $00,$00,$00,$EE,$12,$00,$00,$00,$00,$00,$00,$00,$00
 | |
|     DB $00,$00,$00,$EE,$12,$00,$00,$00,$00,$00,$00,$00,$00
 | |
|     DB $00,$00,$00,$EE,$12,$00,$00,$00,$00,$00,$00,$00,$00
 | |
| org $979F47  ; descriptions
 | |
|     DB "NEUTRAL        "                : DB $00
 | |
|     DB "LIGHT             "             : DB $00
 | |
|     DB "WIND           "                : DB $00
 | |
|     DB "WATER                         " : DB $00
 | |
|     DB "DARK                      "     : DB $00
 | |
|     DB "SOIL                       "    : DB $00
 | |
|     DB "FIRE                       "    : DB $00
 | |
| org $9EDC88  ; names
 | |
|     DB "JELZE       "       ; overwrites "Magma key   "
 | |
|     DB "FLASH       "       ; overwrites "Heart key   "
 | |
|     DB "GUSTO       "       ; overwrites "Ghost key   "
 | |
|     DB "ZEPPY       "       ; overwrites "Trial key   "
 | |
|     DB "DARBI       "       ; overwrites "Dankirk key "
 | |
|     DB "SULLY       "       ; overwrites "Basement key"
 | |
|     DB "BLAZE       "       ; overwrites "Narcysus key"
 | |
| pullpc
 | |
| 
 | |
| 
 | |
| 
 | |
| ; allow inactive characters to gain exp
 | |
| pushpc
 | |
| org $81DADD
 | |
|     ; DB=$81, x=0, m=1
 | |
|     NOP                     ; overwrites BNE $81DAE2 : JMP $DBED
 | |
|     JML HandleActiveExp
 | |
| AwardExp:
 | |
|     ; isolate exp distribution into a subroutine, to be reused for both active party members and inactive characters
 | |
| org $81DAE9
 | |
|     NOP #2                  ; overwrites JMP $DBBD
 | |
|     RTL
 | |
| org $81DB42
 | |
|     NOP #2                  ; overwrites JMP $DBBD
 | |
|     RTL
 | |
| org $81DD11
 | |
|     ; DB=$81, x=0, m=1
 | |
|     JSL HandleInactiveExp    ; overwrites LDA $0A8A : CLC
 | |
| pullpc
 | |
| 
 | |
| HandleActiveExp:
 | |
|     BNE +                   ; (overwritten instruction; modified) check if statblock not empty
 | |
|     JML $81DBED             ; (overwritten instruction; modified) abort
 | |
| +:  JSL AwardExp            ; award exp (X=statblock pointer, Y=position in battle order, $00=position in menu order)
 | |
|     JML $81DBBD             ; (overwritten instruction; modified) continue to next level text
 | |
| 
 | |
| HandleInactiveExp:
 | |
|     LDA $F0201B             ; load inactive exp gain rate
 | |
|     BEQ +                   ; zero gain; skip everything
 | |
|     CMP.b #$64
 | |
|     BCS ++                  ; full gain
 | |
|     LSR $1607
 | |
|     ROR $1606               ; half gain
 | |
|     ROR $1605
 | |
| ++: LDY.w #$0000            ; start looping through all characters
 | |
| -:  TDC
 | |
|     TYA
 | |
|     LDX.w #$0003            ; start looping through active party
 | |
| --: CMP $0A7B,X
 | |
|     BEQ ++                  ; skip if character in active party
 | |
|     DEX
 | |
|     BPL --                  ; continue looping through active party
 | |
|     STA $153D               ; inactive character detected; overwrite character index of 1st slot in party battle order
 | |
|     ASL
 | |
|     TAX
 | |
|     REP #$20
 | |
|     LDA $859EBA,X           ; convert character index to statblock pointer
 | |
|     SEP #$20
 | |
|     TAX
 | |
|     PHY                     ; stash character loop index
 | |
|     LDY $0A80
 | |
|     PHY                     ; stash 1st (in menu order) party member statblock pointer
 | |
|     STX $0A80               ; overwrite 1st (in menu order) party member statblock pointer
 | |
|     LDY.w #$0000            ; set to use 1st position (in battle order)
 | |
|     STY $00                 ; set to use 1st position (in menu order)
 | |
|     JSL AwardExp            ; award exp (X=statblock pointer, Y=position in battle order, $00=position in menu order)
 | |
|     PLY                     ; restore 1st (in menu order) party member statblock pointer
 | |
|     STY $0A80
 | |
|     PLY                     ; restore character loop index
 | |
| ++: INY
 | |
|     CPY.w #$0007
 | |
|     BCC -                   ; continue looping through all characters
 | |
| +:  LDA $0A8A               ; (overwritten instruction) load current gold
 | |
|     CLC                     ; (overwritten instruction)
 | |
|     RTL
 | |
| 
 | |
| 
 | |
| 
 | |
| ; receive death link
 | |
| pushpc
 | |
| org $83BC91
 | |
|     ; DB=$83, x=0, m=1
 | |
|     JSL DeathLinkRX         ; overwrites LDA $7FD0AE
 | |
| pullpc
 | |
| 
 | |
| DeathLinkRX:
 | |
|     LDA $F0203F             ; check death link trigger
 | |
|     BEQ +
 | |
|     TDC
 | |
|     STA $F0203F             ; reset death link trigger
 | |
|     LDA $F0203D             ; check death link enabled
 | |
|     BEQ +
 | |
|     LDA.b #$04
 | |
|     STA $0BBC               ; kill maxim
 | |
|     STA $0C7A               ; kill selan
 | |
|     STA $0D38               ; kill guy
 | |
|     STA $0DF6               ; kill arty
 | |
|     STA $0EB4               ; kill tia
 | |
|     STA $0F72               ; kill dekar
 | |
|     STA $1030               ; kill lexis
 | |
|     LDA.b #$FE
 | |
|     STA $7FF8A3             ; select normal enemy battle
 | |
|     LDA.b #$82
 | |
|     STA $7FF8A4             ; select a formation containing only demise
 | |
|     JSL $8383EB             ; force battle
 | |
| +:  LDA $7FD0AE             ; (overwritten instruction)
 | |
|     RTL
 | |
| 
 | |
| DeathLinkTX:
 | |
|     LDA $F0203D             ; check death link enabled
 | |
|     BEQ +
 | |
|     LDA $7FF8A4             ; load formation number
 | |
|     CMP.b #$82              ; did we die from a death link?
 | |
|     BEQ +
 | |
|     STA $004202
 | |
|     LDA.b #$0A
 | |
|     STA $004203             ; multiply by 10 to get formation offset
 | |
|     TDC
 | |
|     NOP
 | |
|     LDA $004216
 | |
|     TAX
 | |
|     LDA $7FF756,X           ; read first monster in formation
 | |
|     INC
 | |
|     STA $F0203E             ; send death link by monster id + 1
 | |
| +:  RTL
 | |
| 
 | |
| 
 | |
| 
 | |
| ; clear receiving counters when starting new game; force "GIFT" mode
 | |
| pushpc
 | |
| org $83AD83
 | |
|     ; DB=$83, x=0, m=1
 | |
|     JSL ClearRX             ; overwrites BIT #$02 : BEQ $83ADAB
 | |
| pullpc
 | |
| 
 | |
| ClearRX:
 | |
|     REP #$20
 | |
|     TDC
 | |
|     STA $F02800             ; clear received count
 | |
|     STA $F02802             ; clear processed count
 | |
|     SEP #$20
 | |
|     ; absence of the overwritten instructions automatically leads to "GIFT" mode code path
 | |
|     RTL
 | |
| 
 | |
| 
 | |
| 
 | |
| ; store receiving counters when saving game
 | |
| pushpc
 | |
| org $82EB61
 | |
|     ; DB=$8A, x=0, m=1
 | |
|     JSL SaveRX              ; overwrites JSL $8090C9
 | |
| pullpc
 | |
| 
 | |
| SaveRX:
 | |
|     JSL $8090C9             ; (overwritten instruction) write save slot A to SRAM
 | |
|     SEP #$10
 | |
|     REP #$20
 | |
|     ASL
 | |
|     ASL
 | |
|     TAX
 | |
|     LDA $F02800             ;
 | |
|     STA $F027E0,X           ; save received count
 | |
|     LDA $F02802             ;
 | |
|     STA $F027E2,X           ; save processed count
 | |
|     SEP #$20
 | |
|     REP #$10
 | |
|     RTL
 | |
| 
 | |
| 
 | |
| 
 | |
| ; restore receiving counters when loading game
 | |
| pushpc
 | |
| org $82EAD5
 | |
|     ; DB=$83, x=0, m=1
 | |
|     JSL LoadRX              ; overwrites JSL $809099
 | |
| pullpc
 | |
| 
 | |
| LoadRX:
 | |
|     JSL $809099             ; (overwritten instruction) load save slot A from SRAM
 | |
|     SEP #$10
 | |
|     REP #$20
 | |
|     ASL
 | |
|     ASL
 | |
|     TAX
 | |
|     LDA $F027E0,X           ;
 | |
|     STA $F02800             ; restore received count
 | |
|     LDA $F027E2,X           ;
 | |
|     STA $F02802             ; restore processed count
 | |
|     SEP #$20
 | |
|     REP #$10
 | |
|     RTL
 | |
| 
 | |
| 
 | |
| 
 | |
| ; keep inventory after defeat
 | |
| pushpc
 | |
| org $848B9C
 | |
|     ; DB=$7E, x=0, m=1
 | |
|     NOP #5                  ; overwrites LDA.b #$FF : STA $7FE759 : JSR $8888
 | |
|     JSL DeathLinkTX
 | |
| pullpc
 | |
| 
 | |
| 
 | |
| 
 | |
| ; set initial floor number
 | |
| pushpc
 | |
| org $8487A9
 | |
|     JSL InitialFloor        ; overwrites TDC : STA $7FE696
 | |
|     NOP
 | |
| pullpc
 | |
| 
 | |
| InitialFloor:
 | |
|     LDA $D08015             ; read initial floor number
 | |
|     STA $7FE696             ; (overwritten instruction)
 | |
|     TDC                     ; (overwritten instruction)
 | |
|     RTL
 | |
| 
 | |
| 
 | |
| 
 | |
| ; report final floor goal completion
 | |
| pushpc
 | |
| org $839E87
 | |
|     JSL FinalFloor          ; overwrites STA $0005B0
 | |
| pullpc
 | |
| 
 | |
| FinalFloor:
 | |
|     STA $0005B0             ; (overwritten instruction)
 | |
|     LDA.b #$01
 | |
|     STA $F02034             ; report final floor goal
 | |
|     RTL
 | |
| 
 | |
| 
 | |
| 
 | |
| ; start with Providence
 | |
| pushpc
 | |
| org $8488BB
 | |
|     ; DB=$84, x=0, m=0
 | |
|     JSL Providence          ; overwrites LDX.w #$1402 : STX $0A8D
 | |
|     NOP #2
 | |
| pullpc
 | |
| 
 | |
| Providence:
 | |
|     LDX.w #$1402            ; (overwritten instruction)
 | |
|     STX $0A8D               ; (overwritten instruction) add Potion x10
 | |
|     LDX.w #$022D
 | |
|     STX $0A8F               ; add Providence
 | |
|     RTL
 | |
| 
 | |
| 
 | |
| 
 | |
| ; start inventory
 | |
| pushpc
 | |
| org $848901
 | |
|     ; DB=$84, x=0, m=1
 | |
|     JSL StartInventory      ; overwrites JSL $81ED35
 | |
| pullpc
 | |
| 
 | |
| StartInventory:
 | |
|     JSL $81ED35             ; (overwritten instruction)
 | |
|     REP #$20
 | |
|     LDA $F02802             ; number of items to process
 | |
|     DEC
 | |
|     BMI ++                  ; skip if empty
 | |
|     ASL
 | |
|     TAX
 | |
| -:  LDA $F02804,X           ; item ID
 | |
|     BPL +                   ; spells have high bit set
 | |
|     PHX
 | |
|     JSR LearnSpell
 | |
|     PLX
 | |
| +:  BIT.w #$C200            ; ignore spells, blue chest items, and iris items
 | |
|     BNE +
 | |
|     PHX
 | |
|     STA $09CF               ; specify item ID
 | |
|     TDC
 | |
|     INC
 | |
|     STA $09CD               ; specify quantity as 1
 | |
|     JSL $82E80C             ; add item to inventory
 | |
|     REP #$20
 | |
|     PLX
 | |
| +:  DEX
 | |
|     DEX
 | |
|     BPL -
 | |
| ++: SEP #$20
 | |
|     RTL
 | |
| 
 | |
| 
 | |
| 
 | |
| ; architect mode
 | |
| pushpc
 | |
| org $8EA1E7
 | |
| base = $8EA1AD  ; ancient cave entrance script base
 | |
|     DB $15,$E1 : DW .locked-base  ; L2SASM JMP .locked if flag $E1 set
 | |
|     DB $08,"Did you like the layout",$03, \
 | |
|            "of the last cave? I can",$03, \
 | |
|            "lock it down and prevent",$03, \
 | |
|            "the cave from changing.",$01
 | |
|     DB $08,"Do you want to lock",$03, \
 | |
|            "the cave layout?",$01
 | |
|     DB $10,$02 : DW .cancel-base,.lock-base  ; setup 2 choices: .cancel and .lock
 | |
|     DB $08,"Cancel",$0F,"LOCK IT DOWN!",$0B
 | |
| .cancel:
 | |
|     DB $4C,$54,$00  ; play sound $54, END
 | |
| .lock:
 | |
|     DB $5A,$05,$03,$7F,$37,$28,$56,$4C,$6B,$1A,$E1  ; shake, delay $28 f, stop shake, play sound $6B, set flag $E1
 | |
| .locked:
 | |
|     DB $08,"It's locked down.",$00
 | |
|     warnpc $8EA344
 | |
| org $839018
 | |
|     ; DB=$83, x=0, m=1
 | |
|     JSL ArchitectMode       ; overwrites LDA.b #$7E : PHA : PLB
 | |
| pullpc
 | |
| 
 | |
| ArchitectMode:
 | |
| ; check current mode
 | |
|     LDA $079A
 | |
|     BIT.b #$02
 | |
|     BEQ +                   ; go to write mode if flag $E1 (i.e., bit $02 in $079A) not set
 | |
| ; read mode (replaying the locked down layout)
 | |
|     JSR ArchitectBlockAddress
 | |
|     LDA $F00000,X           ; check if current block is marked as filled
 | |
|     BEQ +                   ; go to write mode if block unused
 | |
|     TDC
 | |
|     LDA.b #$36
 | |
|     LDY.w #$0521
 | |
|     INX
 | |
|     MVN $7E,$F0             ; restore 55 RNG values from $F00000,X to $7E0521
 | |
|     INX
 | |
|     LDA $F00000,X
 | |
|     STA $0559               ; restore current RNG index from $F00000,X to $7E0559
 | |
|     BRA ++
 | |
| ; write mode (recording the layout)
 | |
| +:  JSR ArchitectClearBlocks
 | |
|     JSR ArchitectBlockAddress
 | |
|     LDA $7FE696
 | |
|     STA $F00000,X           ; mark block as used
 | |
|     TDC
 | |
|     LDA.b #$36
 | |
|     LDX.w #$0521
 | |
|     INY
 | |
|     MVN $F0,$7E             ; backup 55 RNG values from $7E0521 to $F00000,Y
 | |
|     INY
 | |
|     LDA $7E0559
 | |
|     STA $0000,Y             ; backup current RNG index from $7E0559 to $F00000,Y
 | |
|     LDA.b #$7E              ; (overwritten instruction) set DB=$7E
 | |
|     PHA                     ; (overwritten instruction)
 | |
|     PLB                     ; (overwritten instruction)
 | |
| ++: RTL
 | |
| 
 | |
| ArchitectClearBlocks:
 | |
|     LDA $7FE696             ; read next floor number
 | |
|     CMP $D08015             ; compare initial floor number
 | |
|     BEQ +
 | |
|     BRL ++                  ; skip if not initial floor
 | |
| +:  LDA.b #$F0
 | |
|     PHA
 | |
|     PLB
 | |
|     !floor = 1
 | |
|     while !floor < 99       ; mark all blocks as unused
 | |
|         STZ !floor*$40+$6000
 | |
|         !floor #= !floor+1
 | |
|     endwhile
 | |
| ++: RTS
 | |
| 
 | |
| ArchitectBlockAddress:
 | |
| ; calculate target SRAM address
 | |
|     TDC
 | |
|     LDA $7FE696             ; read next floor number
 | |
|     REP #$20
 | |
|     ASL #6
 | |
|     ADC.w #$6000            ; target SRAM address = next_floor * $40 + $6000
 | |
|     TAX
 | |
|     TAY
 | |
|     SEP #$20
 | |
|     RTS
 | |
| 
 | |
| 
 | |
| 
 | |
| ; for architect mode: make red chest behavior for iris treasure replacements independent of current inventory
 | |
| ; by ensuring the same number of RNG calls, no matter if you have the iris item already or not
 | |
| ; (done by prefilling *all* chests first and potentially overwriting one of them with an iris item afterwards,
 | |
| ; instead of checking the iris item first and then potentially filling *one fewer* regular chest)
 | |
| pushpc
 | |
| org $8390C9
 | |
|     ; DB=$96, x=0, m=1
 | |
|     NOP                     ; overwrites LDY.w #$0000
 | |
|     BRA +                   ; go to regular red chest generation
 | |
| -:                          ; iris treasure handling happens below
 | |
| org $839114
 | |
|     ; DB=$7F, x=0, m=1
 | |
|     NOP #36                 ; overwrites all of providence handling
 | |
|     LDA.b #$83              ; (overwritten instruction from org $8391E9) set DB=$83 for floor layout generation
 | |
|     PHA                     ; (overwritten instruction from org $8391E9)
 | |
|     PLB                     ; (overwritten instruction from org $8391E9)
 | |
|     BRL ++                  ; go to end
 | |
| +:  LDY.w #$0000            ; (overwritten instruction from org $8390C9) initialize chest index
 | |
|                             ; red chests are filled below
 | |
| org $8391E9
 | |
|     ; DB=$7F, x=0, m=1
 | |
|     NOP                     ; overwrites LDA.b #$83 : PHA : PLB
 | |
|     BRL -                   ; go to iris treasure handling
 | |
| ++:                         ; floor layout generation happens below
 | |
| pullpc
 | |
| 
 | |
| 
 | |
| 
 | |
| ; for architect mode: make red chest behavior for spell replacements independent of currently learned spells
 | |
| ; by ensuring the same number of RNG calls, no matter if you have the spell already or not
 | |
| pushpc
 | |
| org $8391A6
 | |
|     ; DB=$7F, x=0, m=1
 | |
|     JSL SpellRNG            ; overwrites LDA.b #$80 : STA $E747,Y
 | |
|     NOP
 | |
| pullpc
 | |
| 
 | |
| SpellRNG:
 | |
|     LDA.b #$80              ; (overwritten instruction) mark chest item as spell
 | |
|     STA $E747,Y             ; (overwritten instruction)
 | |
|     JSL $8082C7             ;
 | |
|     JSL $8082C7             ; advance RNG twice
 | |
|     RTL
 | |
| 
 | |
| 
 | |
| 
 | |
| ; shops
 | |
| pushpc
 | |
| org $83B442
 | |
|     ; DB=$83, x=1, m=1
 | |
|     JSL Shop                ; overwrites STA $7FD0BF
 | |
| pullpc
 | |
| 
 | |
| Shop:
 | |
|     STA $7FD0BF             ; (overwritten instruction)
 | |
|     LDY $05AC               ; load map number
 | |
|     CPY.b #$F0              ; check if ancient cave
 | |
|     BCC +
 | |
|     LDA $05B4               ; check if going to ancient cave entrance
 | |
|     BEQ +
 | |
|     LDA $7FE696             ; load next to next floor number
 | |
|     DEC
 | |
|     CPY.b #$F1              ; check if going to final floor
 | |
|     BCS ++                  ; skip a decrement because next floor number is not incremented on final floor
 | |
|     DEC
 | |
| ++: CMP $D08015             ; check if past initial floor
 | |
|     BCC +
 | |
|     STA $4204               ; WRDIVL; dividend = floor number
 | |
|     STZ $4205               ; WRDIVH
 | |
|     TAX
 | |
|     LDA $D0801A
 | |
|     STA $4206               ; WRDIVB; divisor = shop_interval
 | |
|     STA $211C               ; M7B; second factor = shop_interval
 | |
|     JSL $8082C7             ; advance RNG (while waiting for division to complete)
 | |
|     LDY $4216               ; RDMPYL; skip if remainder (i.e., floor number mod shop_interval) is not 0
 | |
|     BNE +
 | |
|     STA $211B
 | |
|     STZ $211B               ; M7A; first factor = random number from 0 to 255
 | |
|     TXA
 | |
|     CLC
 | |
|     SBC $2135               ; MPYM; calculate (floor number) - (random number from 0 to shop_interval-1) - 1
 | |
|     STA $30                 ; set shop id
 | |
|     STZ $05A8               ; initialize variable for sold out item tracking
 | |
|     STZ $05A9
 | |
|     PHB
 | |
|     PHP
 | |
|     JML $80A33A             ; open shop menu (eventually causes return by reaching existing PLP : PLB : RTL at $809DB0)
 | |
| +:  RTL
 | |
| 
 | |
| ; shop item select
 | |
| pushpc
 | |
| org $82DF50
 | |
|     ; DB=$83, x=0, m=1
 | |
|     JML ShopItemSelected    ; overwrites JSR $8B08 : CMP.b #$01
 | |
| pullpc
 | |
| 
 | |
| ShopItemSelected:
 | |
|     LDA $1548               ; check inventory free space
 | |
|     BEQ +
 | |
|     JSR LoadShopSlotAsFlag
 | |
|     BIT $05A8               ; test item not already sold
 | |
|     BNE +
 | |
|     JML $82DF79             ; skip quantity selection and go directly to buy/equip
 | |
| +:  JML $82DF80             ; abort and go back to item selection
 | |
| 
 | |
| ; track bought shop items
 | |
| pushpc
 | |
| org $82E084
 | |
|     ; DB=$83, x=0, m=1
 | |
|     JSL ShopBuy             ; overwrites LDA.b #$05 : LDX.w #$0007
 | |
|     NOP
 | |
| org $82E10E
 | |
|     ; DB=$83, x=0, m=1
 | |
|     JSL ShopEquip           ; overwrites SEP #$10 : LDX $14DC
 | |
|     NOP
 | |
| pullpc
 | |
| 
 | |
| ShopBuy:
 | |
|     JSR LoadShopSlotAsFlag
 | |
|     TSB $05A8               ; mark item as sold
 | |
|     LDA.b #$05              ; (overwritten instruction)
 | |
|     LDX.w #$0007            ; (overwritten instruction)
 | |
|     RTL
 | |
| 
 | |
| ShopEquip:
 | |
|     JSR LoadShopSlotAsFlag
 | |
|     TSB $05A8               ; mark item as sold
 | |
|     SEP #$10                ; (overwritten instruction)
 | |
|     LDX $14DC               ; (overwritten instruction)
 | |
|     RTL
 | |
| 
 | |
| LoadShopSlotAsFlag:
 | |
|     TDC
 | |
|     LDA $14EC               ; load currently selected shop slot number
 | |
|     ASL
 | |
|     TAX
 | |
|     LDA $8ED8C3,X           ; load predefined bitmask with a single bit set
 | |
|     RTS
 | |
| 
 | |
| ; mark bought items as sold out
 | |
| pushpc
 | |
| org $8285EA
 | |
|     ; DB=$83, x=0, m=0
 | |
|     JSL SoldOut             ; overwrites LDA [$FC],Y : AND #$01FF
 | |
|     NOP
 | |
| pullpc
 | |
| 
 | |
| SoldOut:
 | |
|     LDA $8ED8C3,X           ; load predefined bitmask with a single bit set
 | |
|     BIT $05A8               ; test sold items
 | |
|     BEQ +
 | |
|     LDA.w #$01CB            ; load sold out item id
 | |
|     BRA ++
 | |
| +:  LDA [$FC],Y             ; (overwritten instruction)
 | |
|     AND #$01FF              ; (overwritten instruction)
 | |
| ++: RTL
 | |
| 
 | |
| 
 | |
| 
 | |
| ; increase variety of red chest gear after B9
 | |
| pushpc
 | |
| org $839176
 | |
|     ; DB=$7F, x=0, m=1
 | |
|     CLC                     ; {carry clear = disable this feature, carry set = enable this feature}
 | |
|     JSL RedChestGear        ; overwrites LDX.w #$1000 : LDA $60
 | |
| org $83917D
 | |
|     ; DB=$7F, x=0, m=1
 | |
|     JSL RunEquipmentRNG     ; overwrites LSR : JSR $9E11
 | |
| pullpc
 | |
| 
 | |
| RedChestGear:
 | |
|     BCC +
 | |
|     REP #$20                ; support more than 127 items
 | |
| +:  LDX.w #$1000            ; (overwritten instruction)
 | |
|     LDA $60                 ; (overwritten instruction)
 | |
|     RTL
 | |
| RunEquipmentRNG:
 | |
|     BCS +
 | |
|     SEP #$20
 | |
|     PHK
 | |
|     PEA ++
 | |
|     PEA $8DD8
 | |
|     LSR
 | |
|     JML $839E11
 | |
| +:  LSR                     ; (overwritten instruction) divide by 2 (translates max item offset to max item number)
 | |
|     SEP #$20                ; (the max item number fits in 8bits since there are always fewer than 256 eligible items)
 | |
|     STA $004202             ; run RNG: fill WRMPYA multiplicand register with max item number
 | |
|     JSL $8082C7             ; run RNG: load 8bit accumulator with 1st random number from PRNG
 | |
|     STA $004203             ; run RNG: fill WRMPYB multiplier register with 1st random number and start multiplication
 | |
|     NOP
 | |
|     REP #$20
 | |
|     LDA $004216             ; run RNG: read RDMPYL+H multiplication result
 | |
|     STA $E746,Y             ; save it for later
 | |
|     SEP #$20
 | |
|     JSL $8082C7             ; run RNG: load 8bit accumulator with 2nd random number from PRNG
 | |
|     STA $004203             ; run RNG: fill WRMPYB multiplier register with 2nd random number and start multiplication
 | |
|     CLC
 | |
|     TDC
 | |
|     LDA $004217             ; run RNG: read RDMPYH multiplication result
 | |
|     REP #$20
 | |
|     ADC $E746,Y
 | |
|     AND.w #$FF00
 | |
|     XBA
 | |
|     ASL                     ; multiply by 2 (translates selected item number to selected item offset)
 | |
| ++: TAX                     ; store result in 16bit X register
 | |
|     RTL
 | |
| 
 | |
| 
 | |
| 
 | |
| ; relocate capsule cravings table
 | |
| pushpc
 | |
| org $82C55A
 | |
|     LDA $D09200,X           ; overwrites LDA $95FF16,X
 | |
| org $82C55F
 | |
|     LDA $D09202,X           ; overwrites LDA $95FF18,X
 | |
| org $82C572
 | |
|     LDA $D09200,X           ; overwrites LDA $95FF16,X
 | |
| pullpc
 | |
| 
 | |
| 
 | |
| 
 | |
| ; set capsule monster starting xp
 | |
| pushpc
 | |
| org $82C313
 | |
|     ; DB=$84, x=0, m=1
 | |
|     JSL CapsuleStartingXp   ; overwrites LDX.w #$0000 : LDA.b #$00 : STA $7FF1AA,X : INX : CPX.w #$0015 : BNE $82C318
 | |
|     NOP #11
 | |
| pullpc
 | |
| 
 | |
| CapsuleStartingXp:
 | |
|     PHB
 | |
|     REP #$20
 | |
|     LDA $D08012
 | |
|     STA $7FF1AA             ; store low word of starting XP for first capsule monster
 | |
|     SEP #$20
 | |
|     LDA $D08014
 | |
|     STA $7FF1AC             ; store highest byte of starting XP for first capsule monster
 | |
|     TDC
 | |
|     LDA.b #$11
 | |
|     LDX.w #$F1AA
 | |
|     LDY.w #$F1AD
 | |
|     MVN $7F,$7F             ; pattern fill the remaining six capsule monster slots
 | |
|     PLB
 | |
|     RTL
 | |
| 
 | |
| 
 | |
| 
 | |
| ; set starting capsule monster
 | |
| pushpc
 | |
| org $82C36A
 | |
|     ; DB=$83, x=0, m=1
 | |
|     JSL StartingCapsule     ; overwrites STZ $11A3 : LDA.b #$01
 | |
|     NOP
 | |
| pullpc
 | |
| 
 | |
| StartingCapsule:
 | |
|     LDA $F02016             ; read starting capsule monster id
 | |
|     STA $11A3
 | |
|     LDA.b #$01              ; (overwritten instruction)
 | |
|     RTL
 | |
| 
 | |
| 
 | |
| 
 | |
| ; enter ancient cave as if coming from the world map
 | |
| pushpc
 | |
| org $83B773
 | |
|     ; DB=$7E, x=0, m=1
 | |
|     JSL CaveEntrance        ; overwrites LDA $05AC : STA $05B4
 | |
|     NOP #2
 | |
| pullpc
 | |
| 
 | |
| CaveEntrance:
 | |
|     LDA $05AC               ; (overwritten instruction)
 | |
|     CMP.b #$68
 | |
|     BNE +                   ; when leaving gruberik, act as if leaving world map
 | |
|     TDC
 | |
| +:  STA $05B4               ; (overwritten instruction)
 | |
|     RTL
 | |
| 
 | |
| 
 | |
| 
 | |
| ; enable run button
 | |
| ; directional input item crash fix
 | |
| pushpc
 | |
| org $83FC6C
 | |
|     REP #$10                ; overwrites BEQ $83FC8A : LDA.b #$80
 | |
|     LDA.b #$40
 | |
| pullpc
 | |
| 
 | |
| 
 | |
| 
 | |
| ; mid-turn death fix
 | |
| pushpc
 | |
| org $85B544
 | |
|     JSL MidTurnDeathFix     ; overwrites JSL $85CCCE
 | |
| pullpc
 | |
| 
 | |
| MidTurnDeathFix:
 | |
|     JSL $85CCCE             ; (overwritten instruction) clear shared battle registers after attack
 | |
|     LDY.w #$000F            ; offset to status effect byte
 | |
|     LDA ($BE),Y             ; offset to stat block of attacker
 | |
|     BIT.b #$04              ; check death
 | |
|     BEQ +
 | |
|     TSX                     ; attacker died; abort script
 | |
|     INX #3
 | |
|     TXS
 | |
|     JML $85B476
 | |
| +:  RTL                     ; attacker still alive; continue script
 | |
| 
 | |
| 
 | |
| 
 | |
| ; poison death fix
 | |
| pushpc
 | |
| org $818959
 | |
|     JSL PoisonDeathFix      ; overwrites JSL $859DD4
 | |
| pullpc
 | |
| 
 | |
| PoisonDeathFix:
 | |
|     JSL $859DD4             ; (overwritten instruction)
 | |
|     JSL $8593B7
 | |
|     RTL
 | |
| 
 | |
| 
 | |
| 
 | |
| ; single-node room fix
 | |
| pushpc
 | |
| org $839C64
 | |
|     ; DB=$7F, x=0, m=1
 | |
|     BNE +                   ; overwrites BNE $17
 | |
| org $839C7B
 | |
|     ; DB=$7F, x=0, m=1
 | |
|     JMP $9BE7               ; overwrites BRA $22 : LDX.w #$00FF
 | |
| +:  TDC
 | |
|     TAX
 | |
| org $839C99
 | |
|     ; DB=$7F, x=0, m=1
 | |
|     INX                     ; overwrites DEX : CPX.w #$0010 : BCS $E1
 | |
|     CPX.w #$0100
 | |
|     BCC $E1
 | |
| pullpc
 | |
| 
 | |
| 
 | |
| 
 | |
| ; door stairs fix
 | |
| pushpc
 | |
| org $839453
 | |
|     ; DB=$7F, x=0, m=1
 | |
|     JSL DoorStairsFix       ; overwrites JSR $9B18 : JSR $9D11
 | |
|     NOP #2
 | |
| pullpc
 | |
| 
 | |
| DoorStairsFix:
 | |
|     CLC
 | |
|     LDY.w #$0000
 | |
| --: LDX.w #$00FF            ; loop through floor layout starting from the bottom right
 | |
| -:  LDA $EA00,X             ; read node contents
 | |
|     BEQ +                   ; always skip empty nodes
 | |
|     BCC ++                  ; 1st pass: skip all blocked nodes (would cause door stairs or rare stairs)
 | |
|     LDA $E9F0,X             ; 2nd pass: skip only if the one above is also blocked (would cause door stairs)
 | |
| ++: BMI +
 | |
|     INY                     ; count usable nodes
 | |
| +:  DEX
 | |
|     BPL -
 | |
|     TYA
 | |
|     BNE ++                  ; all nodes blocked?
 | |
|     SEC                     ; set up 2nd, less restrictive pass
 | |
|     BRA --
 | |
| ++: JSL $8082C7             ; advance RNG
 | |
|     STA $00211B
 | |
|     TDC
 | |
|     STA $00211B             ; M7A; first factor = random number from 0 to 255
 | |
|     TYA
 | |
|     STA $00211C             ; M7B; second factor = number of possible stair positions
 | |
|     LDA $002135             ; MPYM; calculate random number from 0 to number of possible stair positions - 1
 | |
|     TAY
 | |
|     LDX.w #$00FF            ; loop through floor layout starting from the bottom right
 | |
| -:  LDA $EA00,X             ; read node contents
 | |
|     BEQ +                   ; always skip empty nodes
 | |
|     BCC ++                  ; if 1st pass was sufficient: skip all blocked nodes (prevent door stairs and rare stairs)
 | |
|     LDA $E9F0,X             ; if 2nd pass was needed: skip only if the one above is also blocked (prevent door stairs)
 | |
| ++: BMI +
 | |
|     DEY                     ; count down to locate the (Y+1)th usable node
 | |
|     BMI ++
 | |
| +:  DEX
 | |
|     BPL -
 | |
| ++: TXA                     ; return selected stair node coordinate
 | |
|     RTL
 | |
| 
 | |
| 
 | |
| 
 | |
| ; equipment text fix
 | |
| pushpc
 | |
| org $81F2E3
 | |
|     ; DB=$9E, x=0, m=1
 | |
|     NOP #2                  ; overwrites BPL $81F2D6
 | |
| pullpc
 | |
| 
 | |
| 
 | |
| 
 | |
| ; music menu fix
 | |
| pushpc
 | |
| org $82BF44
 | |
|     ; DB=$83, x=0, m=1
 | |
|     BNE $12                 ; overwrites BNE $06
 | |
| pullpc
 | |
| 
 | |
| 
 | |
| 
 | |
| ; logo skip
 | |
| pushpc
 | |
| org $80929A
 | |
|     ; DB=$80, x=0, m=1
 | |
|     LDA.b #$00              ; overwrites LDA.b #$80
 | |
| pullpc
 | |
| 
 | |
| 
 | |
| 
 | |
| ; intro skip
 | |
| pushpc
 | |
| org $8080CF
 | |
|     ; DB=$80, x=1, m=1
 | |
|     JML $8383BD             ; overwrites JML $808281
 | |
| pullpc
 | |
| 
 | |
| 
 | |
| 
 | |
| ; SRAM map
 | |
| ; $F02000   16  signature
 | |
| ; $F02010   2   blue chest count
 | |
| ; $F02012   3   capsule starting xp
 | |
| ; $F02015   1   initial floor
 | |
| ; $F02016   1   starting capsule
 | |
| ; $F02017   1   iris treasures required
 | |
| ; $F02018   1   party members available
 | |
| ; $F02019   1   capsule monsters available
 | |
| ; $F0201A   1   shop interval
 | |
| ; $F0201B   1   inactive exp gain rate
 | |
| ; $F02030   1   selected goal
 | |
| ; $F02031   1   goal completion: boss
 | |
| ; $F02032   1   goal completion: iris_treasure_hunt
 | |
| ; $F02033   1   goal completion: master_iris_treasure_hunt
 | |
| ; $F02034   1   goal completion: final_floor
 | |
| ; $F0203D   1   death link enabled
 | |
| ; $F0203E   1   death link sent (monster id + 1)
 | |
| ; $F0203F   1   death link received
 | |
| ; $F02040   2   check counter for this save file (snes_blue_chests_checked)
 | |
| ; $F02042   2   RESERVED
 | |
| ; $F02044   2   check counter (client_ap_items_found)
 | |
| ; $F02046   2   check counter (snes_ap_items_found)
 | |
| ; $F02048   2   check counter for the slot (total_blue_chests_checked)
 | |
| ; $F0204A   2   check counter for this save file (snes_other_locations_checked)
 | |
| ; $F02050   16  coop uuid
 | |
| ; $F02060   var list of checked locations
 | |
| ; $F027E0   16  saved RX counters
 | |
| ; $F02800   2   received counter
 | |
| ; $F02802   2   processed counter
 | |
| ; $F02804   var list of received items
 | |
| ; $F06000   var architect mode RNG state backups
 | 
