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
 |