Add routine to do horizontal displacement of BG1

This commit is contained in:
Lucas Scharenbroich 2021-07-19 22:52:42 -05:00
parent c5eb84ea37
commit 9cdba9a537
2 changed files with 318 additions and 221 deletions

View File

@ -1,37 +1,37 @@
; Initialization and setup routines for the second background ; Initialization and setup routines for the second background
_InitBG1 _InitBG1
jsr _ApplyBG1YPos jsr _ApplyBG1YPos
jsr _ApplyBG1XPos jsr _ApplyBG1XPos
rts rts
SetBG1XPos SetBG1XPos
cmp BG1StartX cmp BG1StartX
beq :out ; Easy, if nothing changed, then nothing changes beq :out ; Easy, if nothing changed, then nothing changes
ldx BG1StartX ; Load the old value (but don't save it yet) ldx BG1StartX ; Load the old value (but don't save it yet)
sta BG1StartX ; Save the new position sta BG1StartX ; Save the new position
lda #DIRTY_BIT_BG1_X lda #DIRTY_BIT_BG1_X
tsb DirtyBits ; Check if the value is already dirty, if so exit tsb DirtyBits ; Check if the value is already dirty, if so exit
bne :out ; without overwriting the original value bne :out ; without overwriting the original value
stx OldBG1StartX ; First change, so preserve the value stx OldBG1StartX ; First change, so preserve the value
:out rts :out rts
SetBG1YPos SetBG1YPos
cmp BG1StartY cmp BG1StartY
beq :out ; Easy, if nothing changed, then nothing changes beq :out ; Easy, if nothing changed, then nothing changes
ldx BG1StartY ; Load the old value (but don't save it yet) ldx BG1StartY ; Load the old value (but don't save it yet)
sta BG1StartY ; Save the new position sta BG1StartY ; Save the new position
lda #DIRTY_BIT_BG1_Y lda #DIRTY_BIT_BG1_Y
tsb DirtyBits ; Check if the value is already dirty, if so exit tsb DirtyBits ; Check if the value is already dirty, if so exit
bne :out ; without overwriting the original value bne :out ; without overwriting the original value
stx OldBG1StartY ; First change, so preserve the value stx OldBG1StartY ; First change, so preserve the value
:out rts :out rts
; Everytime either BG1 or BG0 X-position changes, we have to update the direct page values. We ; Everytime either BG1 or BG0 X-position changes, we have to update the direct page values. We
@ -41,248 +41,344 @@ SetBG1YPos
; ;
; Note: This routine can be optimized as an unrolled loop of PEI instructions ; Note: This routine can be optimized as an unrolled loop of PEI instructions
_ApplyBG1XPos _ApplyBG1XPos
lda BG1StartX lda BG1StartX
jsr Mod164 jsr Mod164
sta BG1StartXMod164 sta BG1StartXMod164
lda #162 lda #162
sec sec
sbc StartXMod164 sbc StartXMod164
bpl *+6 bpl *+6
clc clc
adc #164 adc #164
clc clc
adc BG1StartXMod164 adc BG1StartXMod164
cmp #164 cmp #164
bcc *+5 bcc *+5
sbc #164 sbc #164
tay tay
phd ; save the direct page because we are going to switch to the phd ; save the direct page because we are going to switch to the
lda BlitterDP ; blitter direct page space and fill in the addresses lda BlitterDP ; blitter direct page space and fill in the addresses
tcd tcd
ldx #162 ldx #162
:loop :loop
tya tya
clc clc
adc affine,x adc affine,x
sta 00,x ; store the value sta 00,x ; store the value
dey dey
dey dey
bpl :nowrap bpl :nowrap
tya tya
clc clc
adc #164 adc #164
tay tay
:nowrap :nowrap
dex dex
dex dex
bpl :loop bpl :loop
pld pld
rts rts
affine ds 164 affine ds 164
; Pass accumulator to set every (A / 256) pitch ; Pass accumulator to set every (A / 256) pitch
SetAffine SetAffine
ldx #0 ldx #0
ldy #0 ldy #0
and #$00FF and #$00FF
pha ; step size pha ; step size
pea $0000 pea $0000
:loop lda 1,s :loop lda 1,s
clc clc
adc 3,s adc 3,s
cmp #256 cmp #256
bcc :skip bcc :skip
tya tya
clc clc
adc #256 ; Move to next BG1 line adc #256 ; Move to next BG1 line
tay tay
:skip and #$00FF ; always clamp to 256 :skip and #$00FF ; always clamp to 256
sta 1,s sta 1,s
tya tya
sta affine,x sta affine,x
inx inx
inx inx
cpx #164 cpx #164
bcc :loop bcc :loop
pla pla
pla pla
rts rts
_ClearBG1Buffer _ClearBG1Buffer
phb phb
pha pha
sep #$20 sep #$20
lda BG1DataBank lda BG1DataBank
pha pha
plb plb
rep #$20 rep #$20
pla pla
ldx #0 ldx #0
:loop :loop
sta: $0000,x sta: $0000,x
inc inc
inx inx
inx inx
cpx #0 cpx #0
bne :loop bne :loop
plb plb
rts rts
; Everytime either BG1 or BG0 Y-position changes, we have to update the Y-register ; Everytime either BG1 or BG0 Y-position changes, we have to update the Y-register
; value in all of the code fields (within the visible screen) ; value in all of the code fields (within the visible screen)
_ApplyBG1YPos _ApplyBG1YPos
:virt_line equ tmp0 :virt_line equ tmp0
:lines_left equ tmp1 :lines_left equ tmp1
:draw_count equ tmp2 :draw_count equ tmp2
:ytbl_idx equ tmp3 :ytbl_idx equ tmp3
lda BG1StartY lda BG1StartY
jsr Mod208 jsr Mod208
sta BG1StartYMod208 sta BG1StartYMod208
sta :ytbl_idx ; Start copying from the first entry in the table sta :ytbl_idx ; Start copying from the first entry in the table
lda StartYMod208 ; This is the base line of the virtual screen lda StartYMod208 ; This is the base line of the virtual screen
sta :virt_line ; Keep track of it sta :virt_line ; Keep track of it
lda ScreenHeight lda ScreenHeight
sta :lines_left sta :lines_left
:loop :loop
lda :virt_line lda :virt_line
asl asl
tax tax
ldal BTableLow,x ; Get the address of the first code field line ldal BTableLow,x ; Get the address of the first code field line
tay tay
sep #$20 sep #$20
ldal BTableHigh,x ldal BTableHigh,x
pha pha
plb ; This is the bank that will receive the updates plb ; This is the bank that will receive the updates
rep #$20 rep #$20
lda :virt_line lda :virt_line
and #$000F and #$000F
eor #$FFFF eor #$FFFF
inc inc
clc clc
adc #16 adc #16
min :lines_left min :lines_left
sta :draw_count ; Do this many lines sta :draw_count ; Do this many lines
asl asl
tax tax
lda :ytbl_idx ; Read from this location in the BG1YTable lda :ytbl_idx ; Read from this location in the BG1YTable
asl asl
jsr CopyBG1YTableToBG1Addr jsr CopyBG1YTableToBG1Addr
lda :virt_line ; advance to the virtual line after the segment we just lda :virt_line ; advance to the virtual line after the segment we just
clc ; filled in clc ; filled in
adc :draw_count adc :draw_count
sta :virt_line sta :virt_line
lda :ytbl_idx ; advance the index into the YTable lda :ytbl_idx ; advance the index into the YTable
adc :draw_count adc :draw_count
sta :ytbl_idx sta :ytbl_idx
lda :lines_left ; subtract the number of lines we just completed lda :lines_left ; subtract the number of lines we just completed
sec sec
sbc :draw_count sbc :draw_count
sta :lines_left sta :lines_left
jne :loop jne :loop
phk phk
plb plb
rts rts
; Unrolled copy routine to move BG1YTable entries into BG1_ADDR position. ; Unrolled copy routine to move BG1YTable entries into BG1_ADDR position.
; ;
; A = intect into the BG1YTable array (x2) ; A = index into the BG1YTable array (x2)
; Y = starting line * $1000 ; Y = starting line * $1000
; X = number of lines (x2) ; X = number of lines (x2)
CopyBG1YTableToBG1Addr CopyBG1YTableToBG1Addr
jmp (:tbl,x) jmp (:tbl,x)
:tbl da :none :tbl da :none
da :do01,:do02,:do03,:do04 da :do01,:do02,:do03,:do04
da :do05,:do06,:do07,:do08 da :do05,:do06,:do07,:do08
da :do09,:do10,:do11,:do12 da :do09,:do10,:do11,:do12
da :do13,:do14,:do15,:do16 da :do13,:do14,:do15,:do16
:do15 tax :do15 tax
bra :x15 bra :x15
:do14 tax :do14 tax
bra :x14 bra :x14
:do13 tax :do13 tax
bra :x13 bra :x13
:do12 tax :do12 tax
bra :x12 bra :x12
:do11 tax :do11 tax
bra :x11 bra :x11
:do10 tax :do10 tax
bra :x10 bra :x10
:do09 tax :do09 tax
bra :x09 bra :x09
:do08 tax :do08 tax
bra :x08 bra :x08
:do07 tax :do07 tax
bra :x07 bra :x07
:do06 tax :do06 tax
bra :x06 bra :x06
:do05 tax :do05 tax
bra :x05 bra :x05
:do04 tax :do04 tax
bra :x04 bra :x04
:do03 tax :do03 tax
bra :x03 bra :x03
:do02 tax :do02 tax
bra :x02 bra :x02
:do01 tax :do01 tax
bra :x01 bra :x01
:do16 tax :do16 tax
ldal BG1YTable+30,x ldal BG1YTable+30,x
sta BG1_ADDR+$F000,y sta BG1_ADDR+$F000,y
:x15 ldal BG1YTable+28,x :x15 ldal BG1YTable+28,x
sta BG1_ADDR+$E000,y sta BG1_ADDR+$E000,y
:x14 ldal BG1YTable+26,x :x14 ldal BG1YTable+26,x
sta BG1_ADDR+$D000,y sta BG1_ADDR+$D000,y
:x13 ldal BG1YTable+24,x :x13 ldal BG1YTable+24,x
sta BG1_ADDR+$C000,y sta BG1_ADDR+$C000,y
:x12 ldal BG1YTable+22,x :x12 ldal BG1YTable+22,x
sta BG1_ADDR+$B000,y sta BG1_ADDR+$B000,y
:x11 ldal BG1YTable+20,x :x11 ldal BG1YTable+20,x
sta BG1_ADDR+$A000,y sta BG1_ADDR+$A000,y
:x10 ldal BG1YTable+18,x :x10 ldal BG1YTable+18,x
sta BG1_ADDR+$9000,y sta BG1_ADDR+$9000,y
:x09 ldal BG1YTable+16,x :x09 ldal BG1YTable+16,x
sta BG1_ADDR+$8000,y sta BG1_ADDR+$8000,y
:x08 ldal BG1YTable+14,x :x08 ldal BG1YTable+14,x
sta BG1_ADDR+$7000,y sta BG1_ADDR+$7000,y
:x07 ldal BG1YTable+12,x :x07 ldal BG1YTable+12,x
sta BG1_ADDR+$6000,y sta BG1_ADDR+$6000,y
:x06 ldal BG1YTable+10,x :x06 ldal BG1YTable+10,x
sta BG1_ADDR+$5000,y sta BG1_ADDR+$5000,y
:x05 ldal BG1YTable+08,x :x05 ldal BG1YTable+08,x
sta: BG1_ADDR+$4000,y sta: BG1_ADDR+$4000,y
:x04 ldal BG1YTable+06,x :x04 ldal BG1YTable+06,x
sta BG1_ADDR+$3000,y sta BG1_ADDR+$3000,y
:x03 ldal BG1YTable+04,x :x03 ldal BG1YTable+04,x
sta BG1_ADDR+$2000,y sta BG1_ADDR+$2000,y
:x02 ldal BG1YTable+02,x :x02 ldal BG1YTable+02,x
sta BG1_ADDR+$1000,y sta BG1_ADDR+$1000,y
:x01 ldal BG1YTable+00,x :x01 ldal BG1YTable+00,x
sta: BG1_ADDR+$0000,y sta: BG1_ADDR+$0000,y
:none rts :none rts
; Unrolled copy routine to move BG1YTable entries into BG1_ADDR position with an additional
; shift
;
; A = index into the BG1YTable array (x2)
; Y = starting line * $1000
; X = number of lines (x2)
CopyBG1YTableToBG1Addr2
jmp (:tbl,x)
:tbl da :none
da :do01,:do02,:do03,:do04
da :do05,:do06,:do07,:do08
da :do09,:do10,:do11,:do12
da :do13,:do14,:do15,:do16
:do15 tax
bra :x15
:do14 tax
bra :x14
:do13 tax
bra :x13
:do12 tax
bra :x12
:do11 tax
bra :x11
:do10 tax
bra :x10
:do09 tax
bra :x09
:do08 tax
bra :x08
:do16 tax
ldal BG1YTable+30,x
adcl BG1YOffsetTable+30,x
sta BG1_ADDR+$F000,y
:x15 ldal BG1YTable+28,x
adcl BG1YOffsetTable+28,x
sta BG1_ADDR+$E000,y
:x14 ldal BG1YTable+26,x
adcl BG1YOffsetTable+26,x
sta BG1_ADDR+$D000,y
:x13 ldal BG1YTable+24,x
adcl BG1YOffsetTable+24,x
sta BG1_ADDR+$C000,y
:x12 ldal BG1YTable+22,x
adcl BG1YOffsetTable+22,x
sta BG1_ADDR+$B000,y
:x11 ldal BG1YTable+20,x
adcl BG1YOffsetTable+20,x
sta BG1_ADDR+$A000,y
:x10 ldal BG1YTable+18,x
adcl BG1YOffsetTable+18,x
sta BG1_ADDR+$9000,y
:x09 ldal BG1YTable+16,x
adcl BG1YOffsetTable+16,x
sta BG1_ADDR+$8000,y
:x08 ldal BG1YTable+14,x
adcl BG1YOffsetTable+14,x
sta BG1_ADDR+$7000,y
:x07 ldal BG1YTable+12,x
adcl BG1YOffsetTable+12,x
sta BG1_ADDR+$6000,y
:x06 ldal BG1YTable+10,x
adcl BG1YOffsetTable+10,x
sta BG1_ADDR+$5000,y
:x05 ldal BG1YTable+08,x
adcl BG1YOffsetTable+08,x
sta: BG1_ADDR+$4000,y
:x04 ldal BG1YTable+06,x
adcl BG1YOffsetTable+06,x
sta BG1_ADDR+$3000,y
:x03 ldal BG1YTable+04,x
adcl BG1YOffsetTable+04,x
sta BG1_ADDR+$2000,y
:x02 ldal BG1YTable+02,x
adcl BG1YOffsetTable+02,x
sta BG1_ADDR+$1000,y
:x01 ldal BG1YTable+00,x
adcl BG1YOffsetTable+00,x
sta: BG1_ADDR+$0000,y
:none rts
:do07 tax
bra :x07
:do06 tax
bra :x06
:do05 tax
bra :x05
:do04 tax
bra :x04
:do03 tax
bra :x03
:do02 tax
bra :x02
:do01 tax
bra :x01

View File

@ -238,5 +238,6 @@ BG1YTable lup 208
]step = ]step+256 ]step = ]step+256
--^ --^
BG1YOffsetTable ds 208*2*2