Remove dead code and fix right edge of BG1 rendering

This commit is contained in:
Lucas Scharenbroich 2021-07-16 08:38:14 -05:00
parent abfcde54c2
commit 62233d4abc

View File

@ -146,176 +146,6 @@ FillScreen lda #0
bcc :yloop bcc :yloop
rts rts
; Set the starting line of the virtual buffer that will be displayed on the first physical line
; of the playfield.
;
; A = line number [0, 207]
;
; There are a few things that need to happen with the Y-position of the virtual buffer is changed:
;
; 1. The address of the stack in the code fields needs to be changed
; 2. The entry point into the code field needs to be set
; 3. The (old) return code needs to be removed
; 4. The new return code needs to be inserted after the last line
;
; If there is a second background, then the Y-register value in the code field needs to
; change as well, but that is deferred until later because we don't want to duplicate work
; if both the BG0 Y-position and the BG1 Y-position is changed on the same frame.
;
; We have routines that operate on a single blitter bank at time, so we need to break up the loop
; into blocks of code aligned mod 16. There is some housekeeping because the height of the screen
; could be less that one full bank.
;
; Each of the within-bank subroutine takes the following arguments
;
; X = number of lines * 2, 0 to 32
; Y = starting line * $1000
; A = value
;
; The pseudo-code for this subroutine is as follows.
;
; pre_line_count = 0
; curr_bank = StartY / 16
;
; // If the start is not bank aligned, then calculate the pre-work
; start_mod_16 = StartY % 16
; if (start_mod_16 !== 0) {
; pre_line_count = min(16 - start_mod_16, ScreenHeight)
; do_action(curr_bank, start_mod_16, pre_line_count)
; curr_bank = (curr_bank + 1) % 13
; }
;
; line_count = ScreenHeight - pre_line_count
; while (line_count > 16) {
; do_action(curr_bank, 0, 16)
; line_count -= 16
; curr_bank = (curr_bank + 1) % 13
; }
;
; if (line_count > 0) {
; do_action(curr_bank, 0, line_count)
; }
; Helper function to return the address of a specific blitter code field line
;
; Input: A = line number [0, 207]
; Output: A = low word, X = high word
GetBlitLineAddress
asl
tay
lda BTableLow,y
ldx BTableHigh,y
rts
lines_left ds 2
start_mod_16 ds 2
tblptr ds 2
stksave ds 2
SetYPos sta StartY ; Save the position
lda ScreenHeight
sta lines_left
lda StartY ; Now figure out exactly how many banks we cross by
and #$000F ; calculating ((StartY % 16) + ScreenHeight) / 16
sta start_mod_16
clc
adc ScreenHeight
and #$00F0 ; Just keep the relevant nibble
lsr
lsr
lsr
tax ; Keep the value pre-multiplied by 2
ldy #0
jsr PushBanks ; Push the bank bytes on the stack
brl :out
; Start of the main body of the function. We need to get a pointer to the correct offset of
; the RTable to copy screen addresses into the code fields
lda ScreenY0
asl
clc
adc #RTable
sta tblptr
; Check to see where we start. If we are aligned with a code bank, then skip to the
; fast inner loop. Otherwise do one iteration to get things lined up
:prologue lda start_mod_16
beq :body
_Mul4096 ; Save the offset into the code bank of the
tay ; first line.
lda #16 ; Now figure out how many lines to execute. Usually
sec ; this will just be the lines to the end of the code
sbc start_mod_16 ; bank, but if the total screen height is smaller than
cmp ScreenHeight ; the number of lines in the code bank, we need to clamp
bcc :min_1 ; the maximum value
lda ScreenHeight
:min_1 sta tmp4 ; save for updating the counters
asl
tax ; do this many lines
lda tblptr ; starting at this address
plb ; Set the code field bank
jsr CopyFromArray2 ; Copy the right screen edge addresses
lda lines_left
sec
sbc tmp4
sta lines_left
lda tblptr
clc
adc tmp4
adc tmp4
sta tblptr
; While the number of lines left to render is 16 or greater, loop
:body lda lines_left
cmp #16
bcc :epilogue
ldy #0
ldx tblptr
:body0 plb ; Set the code field bank
jsr CopyFromArray2Top ; to bypass the need to set the X register
txa
clc
adc #32
tax
lda lines_left
sec
sbc #16
sta lines_left
cmp #16 ; Repeat the test here to we can skip some
bcs :body0 ; redundant setup and spill the X register
stx tblptr ; back into tblptr when done
:epilogue lda lines_left
beq :out
asl ; Y is still zero
tax
lda tblptr
plb ; Set the code field bank
jsr CopyFromArray2 ; to bypass the need to set the X register
:out lda stksave ; put the stack back
tcs
phk ; Need to restore the current bank
plb
rts
; Special subroutine to divide the accumulator by 164 and return remainder in the Accumulator ; Special subroutine to divide the accumulator by 164 and return remainder in the Accumulator
; ;
; 164 = $A4 = 1010_0100 ; 164 = $A4 = 1010_0100
@ -401,71 +231,6 @@ Mod208 cmp #%1101000000000000
sbc #%0000000011010000 sbc #%0000000011010000
rts rts
; BankYSetup
;
; This is the set of function that have to be done to set up all of the code banks
; for execution when the Y-Origin of the virtual screen changes. The tasks are:
; Patch out the final JMP to jump to the long JML return code
;
; Y = starting line * $1000
SetReturn lda #$0280 ; BRA *+4
sta CODE_EXIT,y
rts
ResetReturn lda #$004C ; JMP $XX00
sta CODE_EXIT,y
rts
; Fill in the even_exit JMP instruction to jump to the next line (all but last line)
SetNextLine lda #$F000+{entry_3-base}
ldy #CODE_EXIT+1
ldx #15*2
jmp SetAbsAddrs
; Copy a series of bank bytes onto the direct page, which we will later point the stack
; at and use to iterate among the different code banks.
;
; Y = starting index * 4
; X = number of bank
PushBanks sep #$20
jmp (:tbl,x)
:tbl da :bottom-05,:bottom-10,:bottom-15,:bottom-20
da :bottom-25,:bottom-30,:bottom-35,:bottom-40
da :bottom-45,:bottom-50,:bottom-55,:bottom-60
da :bottom-65
:top lda: BlitBuff+48,y ; These are all 8-bit loads and stores
sta bstk+13
lda: BlitBuff+44,y
sta bstk+12
lda: BlitBuff+42,y
sta bstk+11
lda: BlitBuff+38,y
sta bstk+10
lda: BlitBuff+34,y
sta bstk+9
lda: BlitBuff+30,y
sta bstk+8
lda: BlitBuff+26,y
sta bstk+7
lda: BlitBuff+22,y
sta bstk+6
lda: BlitBuff+18,y
sta bstk+5
lda: BlitBuff+14,y
sta bstk+4
lda: BlitBuff+10,y
sta bstk+3
lda: BlitBuff+6,y
sta bstk+2
lda: BlitBuff+2,y
sta bstk+1
lda: BlitBuff,y
sta bstk
:bottom rep #$20
rts
; Patch an 8-bit or 16-bit valueS into the bank. These are a set up unrolled loops to ; Patch an 8-bit or 16-bit valueS into the bank. These are a set up unrolled loops to
; quickly patch in a constanct value, or a value from an array into a given set of ; quickly patch in a constanct value, or a value from an array into a given set of
; templates. ; templates.
@ -506,108 +271,6 @@ SetConst ; Need a blank line here
sta: $0000,y sta: $0000,y
:bottom rts :bottom rts
; CopyFromArray
;
; Copy values from an array with a stride of two bytes into the code field
;
; X = number of lines * 2, 0 to 32
; Y = starting line * $1000
; A = array address
CopyFromArray2 pha ; save the accumulator
ldal :tbl,x
dec
plx ; put the accumulator into X
pha ; push the address into the stack
rts ; and jump
:tbl da bottomCFA2-00,bottomCFA2-06,bottomCFA2-12,bottomCFA2-18
da bottomCFA2-24,bottomCFA2-30,bottomCFA2-36,bottomCFA2-42
da bottomCFA2-48,bottomCFA2-54,bottomCFA2-60,bottomCFA2-66
da bottomCFA2-72,bottomCFA2-78,bottomCFA2-84,bottomCFA2-90
da bottomCFA2-96
CopyFromArray2Top lda: $001E,x
sta $F000,y
lda: $001C,x
sta $E000,y
lda: $001A,x
sta $D000,y
lda: $0018,x
sta $C000,y
lda: $0016,x
sta $B000,y
lda: $0014,x
sta $A000,y
lda: $0012,x
sta $9000,y
lda: $0010,x
sta $8000,y
lda: $000E,x
sta $7000,y
lda: $000C,x
sta $6000,y
lda: $000A,x
sta $5000,y
lda: $0008,x
sta $4000,y
lda: $0006,x
sta $3000,y
lda: $0004,x
sta $2000,y
lda: $0002,x
sta $1000,y
lda: $0000,x
sta: $0000,y
bottomCFA2 rts
; SetScreenAddrs
;
; A = initial screen location (largest)
; Y = starting line * $1000
; X = number of lines
;
; Automatically decrements address by 160 bytes each line
SetScreenAddrs sec
jmp (:tbl,x)
:tbl da bottomSSA-00,bottomSSA-03,bottomSSA-09,bottomSSA-15
da bottomSSA-21,bottomSSA-27,bottomSSA-33,bottomSSA-39
da bottomSSA-45,bottomSSA-51,bottomSSA-57,bottomSSA-63
da bottomSSA-69,bottomSSA-75,bottomSSA-81,bottomSSA-87
da bottomSSA-93
SetScreenAddrsTop sta STK_ADDR+$F000,y
sbc #160
sta STK_ADDR+$E000,y
sbc #160
sta STK_ADDR+$D000,y
sbc #160
sta STK_ADDR+$C000,y
sbc #160
sta STK_ADDR+$B000,y
sbc #160
sta STK_ADDR+$A000,y
sbc #160
sta STK_ADDR+$9000,y
sbc #160
sta STK_ADDR+$8000,y
sbc #160
sta STK_ADDR+$7000,y
sbc #160
sta STK_ADDR+$6000,y
sbc #160
sta STK_ADDR+$5000,y
sbc #160
sta STK_ADDR+$4000,y
sbc #160
sta STK_ADDR+$3000,y
sbc #160
sta STK_ADDR+$2000,y
sbc #160
sta STK_ADDR+$1000,y
sbc #160
sta: STK_ADDR+$0000,y
bottomSSA rts
; SetAbsAddrs ; SetAbsAddrs
; ;
; A = absolute address (largest) ; A = absolute address (largest)
@ -660,18 +323,20 @@ SetAbsAddrs sec
; ;
; A = high word of bank table ; A = high word of bank table
; Y = index * 4 of the bank to initialize ; Y = index * 4 of the bank to initialize
bankArray equ tmp0
target equ tmp2
nextBank equ tmp4
BuildBank BuildBank
stx bankArray
sta bankArray+2
stz target :bankArray equ tmp0
:target equ tmp2
:nextBank equ tmp4
stx :bankArray
sta :bankArray+2
stz :target
iny iny
iny iny
lda [bankArray],y lda [:bankArray],y
sta target+2 sta :target+2
iny ; move to the next item iny ; move to the next item
iny iny
@ -679,19 +344,19 @@ BuildBank
cpy #4*13 ; if greater than the array length, wrap back to zero cpy #4*13 ; if greater than the array length, wrap back to zero
bcc :ok bcc :ok
ldy #1 ldy #1
:ok lda [bankArray],y ; Get the middle and high bytes of the address :ok lda [:bankArray],y ; Get the middle and high bytes of the address
sta nextBank sta :nextBank
:next :next
jsr BuildLine2 jsr :BuildLine2
lda target lda :target
clc clc
adc #$1000 adc #$1000
sta target sta :target
bcc :next bcc :next
phb phb
pei target+1 pei :target+1
plb plb
plb plb
@ -702,10 +367,10 @@ BuildBank
ldy #$F000+CODE_EXIT ; Patch the last line with a JML to go to the next bank ldy #$F000+CODE_EXIT ; Patch the last line with a JML to go to the next bank
lda #{$005C+{TWO_LYR_ENTRY}*256} lda #{$005C+{TWO_LYR_ENTRY}*256}
sta [target],y sta [:target],y
ldy #$F000+CODE_EXIT+2 ldy #$F000+CODE_EXIT+2
lda nextBank lda :nextBank
sta [target],y sta [:target],y
plb plb
rts rts
@ -715,11 +380,11 @@ BuildBank
; ;
; X = low word of address (must be a multiple of $1000) ; X = low word of address (must be a multiple of $1000)
; A = high word of address (bank) ; A = high word of address (bank)
BuildLine :BuildLine
stx target stx :target
sta target+2 sta :target+2
BuildLine2 :BuildLine2
lda #CODE_LEN ; round up to an even number of bytes lda #CODE_LEN ; round up to an even number of bytes
inc inc
and #$FFFE and #$FFFE
@ -728,7 +393,7 @@ BuildLine2
dec dec
tay tay
:loop lda base,y :loop lda base,y
sta [target],y sta [:target],y
dey dey
dey dey
@ -738,9 +403,9 @@ BuildLine2
sep #$20 sep #$20
ldx #0 ldx #0
lda target+2 ; patch in the bank for the absolute long addressing mode lda :target+2 ; patch in the bank for the absolute long addressing mode
:dobank ldy BankPatches,x :dobank ldy BankPatches,x
sta [target],y sta [:target],y
inx inx
inx inx
cpx #BankPatchNum cpx #BankPatchNum
@ -748,10 +413,10 @@ BuildLine2
ldx #0 ldx #0
:dopage ldy PagePatches,x ; patch the page addresses by adding the page offset to each :dopage ldy PagePatches,x ; patch the page addresses by adding the page offset to each
lda [target],y lda [:target],y
clc clc
adc target+1 adc :target+1
sta [target],y sta [:target],y
inx inx
inx inx
cpx #PagePatchNum cpx #PagePatchNum
@ -790,8 +455,8 @@ right_odd bit #$000B ; Check the bottom nibbl
bne r_is_jmp bne r_is_jmp
long_1 stal *+4-base long_1 stal *+4-base
dfb $00,$00 ; this here to avoid needing a BRA instruction back. So the fast-path dfb $00,$00
; gets a 1-cycle penalty, but we save 3 cycles here. bra r_is_pea+1
r_is_pea xba ; fast code for PEA r_is_pea xba ; fast code for PEA
sep #$20 sep #$20
@ -879,6 +544,7 @@ even_exit jmp $1000 ; Jump to the next line.
long_4 stal *+4-base long_4 stal *+4-base
dfb $00,$00 dfb $00,$00
xba
sep #$20 sep #$20
bra :left_byte bra :left_byte
@ -942,3 +608,10 @@ top