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