Move area and enemy data to Bank 1

develop^2
Christophe Parent 2023-12-13 00:22:53 -08:00
parent 2072532f1b
commit 839982c7bd
2 changed files with 74 additions and 39 deletions

View File

@ -16,10 +16,13 @@ SEGMENTS {
BSS: load = RAM, type = bss, optional = yes; BSS: load = RAM, type = bss, optional = yes;
HEADER: load = HDR, type = ro; HEADER: load = HDR, type = ro;
STARTUP: load = PRG0, type = ro; STARTUP: load = PRG0, type = ro;
BANK0: load = PRG0, type = ro, optional = yes;
AREADATA: load = PRG1, type = ro, optional = yes;
ENEMYDATA: load = PRG1, type = ro, optional = yes;
CHARS: load = PRG2, type = ro, optional = yes; CHARS: load = PRG2, type = ro, optional = yes;
COPYCHARS: load = PRG2, type = ro, optional = yes; COPYCHARS: load = PRG2, type = ro, optional = yes;
SOUNDENGINE: load = PRG2, type = ro, optional = yes; SOUNDENGINE: load = PRG2, type = ro, optional = yes;
CODE: load = PRG3, type = ro, optional = yes; BANK3: load = PRG3, type = ro, optional = yes;
BANKSWITCH: load = PRG3, type = ro, optional = yes; BANKSWITCH: load = PRG3, type = ro, optional = yes;
VECTORS: load = PRGV, type = ro; VECTORS: load = PRGV, type = ro;
} }

View File

@ -531,6 +531,7 @@ AltRegContentFlag = $07ca
CurrentBank = $15 ; The mapper is read-only; need to track its state separately CurrentBank = $15 ; The mapper is read-only; need to track its state separately
CharsCopy = $41 ; Reserving $41 and $42 CharsCopy = $41 ; Reserving $41 and $42
XStore = $43 ; To store the X register
;------------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------------
;CONSTANTS ;CONSTANTS
@ -3298,13 +3299,13 @@ ProcADLoop: stx ObjectOffset
lda #$00 ;reset flag lda #$00 ;reset flag
sta BehindAreaParserFlag sta BehindAreaParserFlag
ldy AreaDataOffset ;get offset of area data pointer ldy AreaDataOffset ;get offset of area data pointer
lda (AreaData),y ;get first byte of area object jsr AreaDataBankSwitch ;get first byte of area object
cmp #$fd ;if end-of-area, skip all this crap cmp #$fd ;if end-of-area, skip all this crap
beq RdyDecode beq RdyDecode
lda AreaObjectLength,x ;check area object buffer flag lda AreaObjectLength,x ;check area object buffer flag
bpl RdyDecode ;if buffer not negative, branch, otherwise bpl RdyDecode ;if buffer not negative, branch, otherwise
iny iny
lda (AreaData),y ;get second byte of area object jsr AreaDataBankSwitch ;get second byte of area object
asl ;check for page select bit (d7), branch if not set asl ;check for page select bit (d7), branch if not set
bcc Chk1Row13 bcc Chk1Row13
lda AreaObjectPageSel ;check page select lda AreaObjectPageSel ;check page select
@ -3312,19 +3313,19 @@ ProcADLoop: stx ObjectOffset
inc AreaObjectPageSel ;if not already set, set it now inc AreaObjectPageSel ;if not already set, set it now
inc AreaObjectPageLoc ;and increment page location inc AreaObjectPageLoc ;and increment page location
Chk1Row13: dey Chk1Row13: dey
lda (AreaData),y ;reread first byte of level object jsr AreaDataBankSwitch ;reread first byte of level object
and #$0f ;mask out high nybble and #$0f ;mask out high nybble
cmp #$0d ;row 13? cmp #$0d ;row 13?
bne Chk1Row14 bne Chk1Row14
iny ;if so, reread second byte of level object iny ;if so, reread second byte of level object
lda (AreaData),y jsr AreaDataBankSwitch
dey ;decrement to get ready to read first byte dey ;decrement to get ready to read first byte
and #%01000000 ;check for d6 set (if not, object is page control) and #%01000000 ;check for d6 set (if not, object is page control)
bne CheckRear bne CheckRear
lda AreaObjectPageSel ;if page select is set, do not reread lda AreaObjectPageSel ;if page select is set, do not reread
bne CheckRear bne CheckRear
iny ;if d6 not set, reread second byte iny ;if d6 not set, reread second byte
lda (AreaData),y jsr AreaDataBankSwitch
and #%00011111 ;mask out all but 5 LSB and store in page control and #%00011111 ;mask out all but 5 LSB and store in page control
sta AreaObjectPageLoc sta AreaObjectPageLoc
inc AreaObjectPageSel ;increment page select inc AreaObjectPageSel ;increment page select
@ -3349,7 +3350,8 @@ ProcLoopb: dex ;decrement buffer offset
lda BehindAreaParserFlag ;check for flag set if objects were behind renderer lda BehindAreaParserFlag ;check for flag set if objects were behind renderer
bne ProcessAreaData ;branch if true to load more level data, otherwise bne ProcessAreaData ;branch if true to load more level data, otherwise
lda BackloadingFlag ;check for flag set if starting right of page $00 lda BackloadingFlag ;check for flag set if starting right of page $00
bne ProcessAreaData ;branch if true to load more level data, otherwise leave beq EndAParse ;branch if true to load more level data, otherwise leave
jmp ProcessAreaData
EndAParse: rts EndAParse: rts
IncAreaObjOffset: IncAreaObjOffset:
@ -3364,7 +3366,7 @@ DecodeAreaData:
bmi Chk1stB bmi Chk1stB
ldy AreaObjOffsetBuffer,x ;if not, get offset from buffer ldy AreaObjOffsetBuffer,x ;if not, get offset from buffer
Chk1stB: ldx #$10 ;load offset of 16 for special row 15 Chk1stB: ldx #$10 ;load offset of 16 for special row 15
lda (AreaData),y ;get first byte of level object again jsr AreaDataBankSwitch ;get first byte of level object again
cmp #$fd cmp #$fd
beq EndAParse ;if end of level, leave this routine beq EndAParse ;if end of level, leave this routine
and #$0f ;otherwise, mask out low nybble and #$0f ;otherwise, mask out low nybble
@ -3387,10 +3389,10 @@ ChkRow13: cmp #$0d ;row 13?
lda #$22 ;if so, load offset with 34 lda #$22 ;if so, load offset with 34
sta $07 sta $07
iny ;get next byte iny ;get next byte
lda (AreaData),y jsr AreaDataBankSwitch
and #%01000000 ;mask out all but d6 (page control obj bit) and #%01000000 ;mask out all but d6 (page control obj bit)
beq LeavePar ;if d6 clear, branch to leave (we handled this earlier) beq LeavePar ;if d6 clear, branch to leave (we handled this earlier)
lda (AreaData),y ;otherwise, get byte again jsr AreaDataBankSwitch ;otherwise, get byte again
and #%01111111 ;mask out d7 and #%01111111 ;mask out d7
cmp #$4b ;check for loop command in low nybble cmp #$4b ;check for loop command in low nybble
bne Mask2MSB ;(plus d6 set for object other than page control) bne Mask2MSB ;(plus d6 set for object other than page control)
@ -3400,18 +3402,18 @@ Mask2MSB: and #%00111111 ;mask out d7 and d6
ChkSRows: cmp #$0c ;row 12-15? ChkSRows: cmp #$0c ;row 12-15?
bcs SpecObj bcs SpecObj
iny ;if not, get second byte of level object iny ;if not, get second byte of level object
lda (AreaData),y jsr AreaDataBankSwitch
and #%01110000 ;mask out all but d6-d4 and #%01110000 ;mask out all but d6-d4
bne LrgObj ;if any bits set, branch to handle large object bne LrgObj ;if any bits set, branch to handle large object
lda #$16 lda #$16
sta $07 ;otherwise set offset of 24 for small object sta $07 ;otherwise set offset of 24 for small object
lda (AreaData),y ;reload second byte of level object jsr AreaDataBankSwitch ;reload second byte of level object
and #%00001111 ;mask out higher nybble and jump and #%00001111 ;mask out higher nybble and jump
jmp NormObj jmp NormObj
LrgObj: sta $00 ;store value here (branch for large objects) LrgObj: sta $00 ;store value here (branch for large objects)
cmp #$70 ;check for vertical pipe object cmp #$70 ;check for vertical pipe object
bne NotWPipe bne NotWPipe
lda (AreaData),y ;if not, reload second byte jsr AreaDataBankSwitch ;if not, reload second byte
and #%00001000 ;mask out all but d3 (usage control bit) and #%00001000 ;mask out all but d3 (usage control bit)
beq NotWPipe ;if d3 clear, branch to get original value beq NotWPipe ;if d3 clear, branch to get original value
lda #$00 ;otherwise, nullify value for warp pipe lda #$00 ;otherwise, nullify value for warp pipe
@ -3419,7 +3421,7 @@ LrgObj: sta $00 ;store value here (branch for large objects
NotWPipe: lda $00 ;get value and jump ahead NotWPipe: lda $00 ;get value and jump ahead
jmp MoveAOId jmp MoveAOId
SpecObj: iny ;branch here for rows 12-15 SpecObj: iny ;branch here for rows 12-15
lda (AreaData),y jsr AreaDataBankSwitch
and #%01110000 ;get next byte and mask out all but d6-d4 and #%01110000 ;get next byte and mask out all but d6-d4
MoveAOId: lsr ;move d6-d4 to lower nybble MoveAOId: lsr ;move d6-d4 to lower nybble
lsr lsr
@ -3432,7 +3434,7 @@ NormObj: sta $00 ;store value here (branch for small objects
cmp CurrentPageLoc ;same page as the renderer, and if so, branch cmp CurrentPageLoc ;same page as the renderer, and if so, branch
beq InitRear beq InitRear
ldy AreaDataOffset ;if not, get old offset of level pointer ldy AreaDataOffset ;if not, get old offset of level pointer
lda (AreaData),y ;and reload first byte jsr AreaDataBankSwitch ;and reload first byte
and #%00001111 and #%00001111
cmp #$0e ;row 14? cmp #$0e ;row 14?
bne LeavePar bne LeavePar
@ -3447,7 +3449,7 @@ InitRear: lda BackloadingFlag ;check backloading flag to see if it's been
sta ObjectOffset sta ObjectOffset
LoopCmdE: rts LoopCmdE: rts
BackColC: ldy AreaDataOffset ;get first byte again BackColC: ldy AreaDataOffset ;get first byte again
lda (AreaData),y jsr AreaDataBankSwitch
and #%11110000 ;mask out low nybble and move high to low and #%11110000 ;mask out low nybble and move high to low
lsr lsr
lsr lsr
@ -3530,7 +3532,7 @@ RunAObj: lda $00 ;get stored value and add offset to it
AlterAreaAttributes: AlterAreaAttributes:
ldy AreaObjOffsetBuffer,x ;load offset for level object data saved in buffer ldy AreaObjOffsetBuffer,x ;load offset for level object data saved in buffer
iny ;load second byte iny ;load second byte
lda (AreaData),y jsr AreaDataBankSwitch
pha ;save in stack for now pha ;save in stack for now
and #%01000000 and #%01000000
bne Alter2 ;branch if d6 is set bne Alter2 ;branch if d6 is set
@ -4280,11 +4282,11 @@ LenSet: rts
GetLrgObjAttrib: GetLrgObjAttrib:
ldy AreaObjOffsetBuffer,x ;get offset saved from area obj decoding routine ldy AreaObjOffsetBuffer,x ;get offset saved from area obj decoding routine
lda (AreaData),y ;get first byte of level object jsr AreaDataBankSwitch ;get first byte of level object
and #%00001111 and #%00001111
sta $07 ;save row location sta $07 ;save row location
iny iny
lda (AreaData),y ;get next byte, save lower nybble (length or height) jsr AreaDataBankSwitch ;get next byte, save lower nybble (length or height)
and #%00001111 ;as Y, then leave and #%00001111 ;as Y, then leave
tay tay
rts rts
@ -4392,7 +4394,7 @@ GetAreaDataAddrs:
lda AreaDataAddrHigh,y lda AreaDataAddrHigh,y
sta AreaDataHigh sta AreaDataHigh
ldy #$00 ;load first byte of header ldy #$00 ;load first byte of header
lda (AreaData),y jsr AreaDataBankSwitch
pha ;save it to the stack for now pha ;save it to the stack for now
and #%00000111 ;save 3 LSB for foreground scenery or bg color control and #%00000111 ;save 3 LSB for foreground scenery or bg color control
cmp #$04 cmp #$04
@ -4415,7 +4417,7 @@ StoreFore: sta ForegroundScenery ;if less, save value here as foreground sce
rol rol
sta GameTimerSetting ;save value here as game timer setting sta GameTimerSetting ;save value here as game timer setting
iny iny
lda (AreaData),y ;load second byte of header jsr AreaDataBankSwitch ;load second byte of header
pha ;save to stack pha ;save to stack
and #%00001111 ;mask out all but lower nybble and #%00001111 ;mask out all but lower nybble
sta TerrainControl sta TerrainControl
@ -4512,6 +4514,8 @@ AreaDataAddrHigh:
.byte >L_GroundArea22, >L_UndergroundArea1, >L_UndergroundArea2, >L_UndergroundArea3, >L_CastleArea1 .byte >L_GroundArea22, >L_UndergroundArea1, >L_UndergroundArea2, >L_UndergroundArea3, >L_CastleArea1
.byte >L_CastleArea2, >L_CastleArea3, >L_CastleArea4, >L_CastleArea5, >L_CastleArea6 .byte >L_CastleArea2, >L_CastleArea3, >L_CastleArea4, >L_CastleArea5, >L_CastleArea6
.segment "ENEMYDATA"
;ENEMY OBJECT DATA ;ENEMY OBJECT DATA
;level 1-4/6-4 ;level 1-4/6-4
@ -4761,6 +4765,8 @@ E_WaterArea3:
.byte $56, $07, $88, $1b, $07, $9d, $2e, $65, $f0 .byte $56, $07, $88, $1b, $07, $9d, $2e, $65, $f0
.byte $ff .byte $ff
.segment "AREADATA"
;AREA OBJECT DATA ;AREA OBJECT DATA
;level 1-4/6-4 ;level 1-4/6-4
@ -5271,6 +5277,8 @@ L_WaterArea3:
.byte $4e, $0f, $ed, $47 .byte $4e, $0f, $ed, $47
.byte $fd .byte $fd
.segment "BANK0"
;------------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------------
;unused space ;unused space
@ -7689,7 +7697,7 @@ RedPTroopaGrav:
ldx ObjectOffset ;get enemy object offset and leave ldx ObjectOffset ;get enemy object offset and leave
rts rts
.segment "CODE" .segment "BANK3"
;------------------------------------------------------------------------------------- ;-------------------------------------------------------------------------------------
;$00 - used for downward force ;$00 - used for downward force
@ -7880,7 +7888,7 @@ ChkEnemyFrenzy:
ProcessEnemyData: ProcessEnemyData:
ldy EnemyDataOffset ;get offset of enemy object data ldy EnemyDataOffset ;get offset of enemy object data
lda (EnemyData),y ;load first byte jsr EnemyDataBankSwitch ;load first byte
cmp #$ff ;check for EOD terminator cmp #$ff ;check for EOD terminator
bne CheckEndofBuffer bne CheckEndofBuffer
jmp CheckFrenzyBuffer ;if found, jump to check frenzy buffer, otherwise jmp CheckFrenzyBuffer ;if found, jump to check frenzy buffer, otherwise
@ -7892,7 +7900,7 @@ CheckEndofBuffer:
cpx #$05 ;check for end of buffer cpx #$05 ;check for end of buffer
bcc CheckRightBounds ;if not at end of buffer, branch bcc CheckRightBounds ;if not at end of buffer, branch
iny iny
lda (EnemyData),y ;check for specific value here jsr EnemyDataBankSwitch ;check for specific value here
and #%00111111 ;not sure what this was intended for, exactly and #%00111111 ;not sure what this was intended for, exactly
cmp #$2e ;this part is quite possibly residual code cmp #$2e ;this part is quite possibly residual code
beq CheckRightBounds ;but it has the effect of keeping enemies out of beq CheckRightBounds ;but it has the effect of keeping enemies out of
@ -7909,7 +7917,7 @@ CheckRightBounds:
sta $06 ;store page location + carry sta $06 ;store page location + carry
ldy EnemyDataOffset ldy EnemyDataOffset
iny iny
lda (EnemyData),y ;if MSB of enemy object is clear, branch to check for row $0f jsr EnemyDataBankSwitch ;if MSB of enemy object is clear, branch to check for row $0f
asl asl
bcc CheckPageCtrlRow bcc CheckPageCtrlRow
lda EnemyObjectPageSel ;if page select already set, do not set again lda EnemyObjectPageSel ;if page select already set, do not set again
@ -7919,14 +7927,14 @@ CheckRightBounds:
CheckPageCtrlRow: CheckPageCtrlRow:
dey dey
lda (EnemyData),y ;reread first byte jsr EnemyDataBankSwitch ;reread first byte
and #$0f and #$0f
cmp #$0f ;check for special row $0f cmp #$0f ;check for special row $0f
bne PositionEnemyObj ;if not found, branch to position enemy object bne PositionEnemyObj ;if not found, branch to position enemy object
lda EnemyObjectPageSel ;if page select set, lda EnemyObjectPageSel ;if page select set,
bne PositionEnemyObj ;branch without reading second byte bne PositionEnemyObj ;branch without reading second byte
iny iny
lda (EnemyData),y ;otherwise, get second byte, mask out 2 MSB jsr EnemyDataBankSwitch ;otherwise, get second byte, mask out 2 MSB
and #%00111111 and #%00111111
sta EnemyObjectPageLoc ;store as page control for enemy object data sta EnemyObjectPageLoc ;store as page control for enemy object data
inc EnemyDataOffset ;increment enemy object data offset 2 bytes inc EnemyDataOffset ;increment enemy object data offset 2 bytes
@ -7937,14 +7945,14 @@ CheckPageCtrlRow:
PositionEnemyObj: PositionEnemyObj:
lda EnemyObjectPageLoc ;store page control as page location lda EnemyObjectPageLoc ;store page control as page location
sta Enemy_PageLoc,x ;for enemy object sta Enemy_PageLoc,x ;for enemy object
lda (EnemyData),y ;get first byte of enemy object jsr EnemyDataBankSwitch ;get first byte of enemy object
and #%11110000 and #%11110000
sta Enemy_X_Position,x ;store column position sta Enemy_X_Position,x ;store column position
cmp ScreenRight_X_Pos ;check column position against right boundary cmp ScreenRight_X_Pos ;check column position against right boundary
lda Enemy_PageLoc,x ;without subtracting, then subtract borrow lda Enemy_PageLoc,x ;without subtracting, then subtract borrow
sbc ScreenRight_PageLoc ;from page location sbc ScreenRight_PageLoc ;from page location
bcs CheckRightExtBounds ;if enemy object beyond or at boundary, branch bcs CheckRightExtBounds ;if enemy object beyond or at boundary, branch
lda (EnemyData),y jsr EnemyDataBankSwitch
and #%00001111 ;check for special row $0e and #%00001111 ;check for special row $0e
cmp #$0e ;if found, jump elsewhere cmp #$0e ;if found, jump elsewhere
beq ParseRow0e beq ParseRow0e
@ -7958,7 +7966,7 @@ CheckRightExtBounds:
bcc CheckFrenzyBuffer ;if enemy object beyond extended boundary, branch bcc CheckFrenzyBuffer ;if enemy object beyond extended boundary, branch
lda #$01 ;store value in vertical high byte lda #$01 ;store value in vertical high byte
sta Enemy_Y_HighPos,x sta Enemy_Y_HighPos,x
lda (EnemyData),y ;get first byte again jsr EnemyDataBankSwitch ;get first byte again
asl ;multiply by four to get the vertical asl ;multiply by four to get the vertical
asl ;coordinate asl ;coordinate
asl asl
@ -7967,14 +7975,14 @@ CheckRightExtBounds:
cmp #$e0 ;do one last check for special row $0e cmp #$e0 ;do one last check for special row $0e
beq ParseRow0e ;(necessary if branched to $c1cb) beq ParseRow0e ;(necessary if branched to $c1cb)
iny iny
lda (EnemyData),y ;get second byte of object jsr EnemyDataBankSwitch ;get second byte of object
and #%01000000 ;check to see if hard mode bit is set and #%01000000 ;check to see if hard mode bit is set
beq CheckForEnemyGroup ;if not, branch to check for group enemy objects beq CheckForEnemyGroup ;if not, branch to check for group enemy objects
lda SecondaryHardMode ;if set, check to see if secondary hard mode flag lda SecondaryHardMode ;if set, check to see if secondary hard mode flag
beq Inc2B ;is on, and if not, branch to skip this object completely beq Inc2B ;is on, and if not, branch to skip this object completely
CheckForEnemyGroup: CheckForEnemyGroup:
lda (EnemyData),y ;get second byte and mask out 2 MSB jsr EnemyDataBankSwitch ;get second byte and mask out 2 MSB
and #%00111111 and #%00111111
cmp #$37 ;check for value below $37 cmp #$37 ;check for value below $37
bcc BuzzyBeetleMutate bcc BuzzyBeetleMutate
@ -8016,7 +8024,7 @@ DoGroup:
ParseRow0e: ParseRow0e:
iny ;increment Y to load third byte of object iny ;increment Y to load third byte of object
iny iny
lda (EnemyData),y jsr EnemyDataBankSwitch
lsr ;move 3 MSB to the bottom, effectively lsr ;move 3 MSB to the bottom, effectively
lsr ;making %xxx00000 into %00000xxx lsr ;making %xxx00000 into %00000xxx
lsr lsr
@ -8025,17 +8033,17 @@ ParseRow0e:
cmp WorldNumber ;is it the same world number as we're on? cmp WorldNumber ;is it the same world number as we're on?
bne NotUse ;if not, do not use (this allows multiple uses bne NotUse ;if not, do not use (this allows multiple uses
dey ;of the same area, like the underground bonus areas) dey ;of the same area, like the underground bonus areas)
lda (EnemyData),y ;otherwise, get second byte and use as offset jsr EnemyDataBankSwitch ;otherwise, get second byte and use as offset
sta AreaPointer ;to addresses for level and enemy object data sta AreaPointer ;to addresses for level and enemy object data
iny iny
lda (EnemyData),y ;get third byte again, and this time mask out jsr EnemyDataBankSwitch ;get third byte again, and this time mask out
and #%00011111 ;the 3 MSB from before, save as page number to be and #%00011111 ;the 3 MSB from before, save as page number to be
sta EntrancePage ;used upon entry to area, if area is entered sta EntrancePage ;used upon entry to area, if area is entered
NotUse: jmp Inc3B NotUse: jmp Inc3B
CheckThreeBytes: CheckThreeBytes:
ldy EnemyDataOffset ;load current offset for enemy object data ldy EnemyDataOffset ;load current offset for enemy object data
lda (EnemyData),y ;get first byte jsr EnemyDataBankSwitch ;get first byte
and #%00001111 ;check for special row $0e and #%00001111 ;check for special row $0e
cmp #$0e cmp #$0e
bne Inc2B bne Inc2B
@ -16358,6 +16366,30 @@ NonMaskableInterruptBankSwitch:
jsr BankSwitchNoSave jsr BankSwitchNoSave
rti rti
AreaDataBankSwitch:
stx XStore
ldx #$01
jsr BankSwitchNoSave
lda (AreaData),y
pha
ldx #$00
jsr BankSwitchNoSave
pla
ldx XStore
rts
EnemyDataBankSwitch:
stx XStore
ldx #$01
jsr BankSwitchNoSave
lda (EnemyData),y
pha
ldx #$00
jsr BankSwitchNoSave
pla
ldx XStore
rts
CopyCharsBankSwitch: CopyCharsBankSwitch:
ldx #$02 ldx #$02
jsr BankSwitch jsr BankSwitch