Add horizontal BG1 offset support; frame lock demo to 60 fps

This commit is contained in:
Lucas Scharenbroich 2021-07-20 00:02:20 -05:00
parent 9cdba9a537
commit 1fcd4589f7
5 changed files with 244 additions and 236 deletions

View File

@ -1,108 +1,136 @@
MoveLeft
clc
adc StartX ; Increment the virtual X-position
jsr SetBG0XPos
adc StartX ; Increment the virtual X-position
jsr SetBG0XPos
lda StartX
lda StartX
lsr
jsr SetBG1XPos
jsr SetBG1XPos
jsr DoFrame
jsr DoFrame
rts
MoveRight
pha
lda StartX
lda StartX
sec
sbc 1,s
bpl *+5
lda #0
jsr SetBG0XPos
sbc 1,s
bpl *+5
lda #0
jsr SetBG0XPos
lda StartX
lda StartX
lsr
jsr SetBG1XPos
jsr SetBG1XPos
jsr DoFrame
jsr DoFrame
pla
rts
MoveUp
clc
adc StartY ; Increment the virtual Y-position
jsr SetBG0YPos
adc StartY ; Increment the virtual Y-position
jsr SetBG0YPos
lda StartY
lda StartY
lsr
jsr SetBG1YPos
jsr SetBG1YPos
jsr DoFrame
jsr DoFrame
rts
MoveDown
pha
lda StartY
lda StartY
sec
sbc 1,s
bpl *+5
lda #0
jsr SetBG0YPos
sbc 1,s
bpl *+5
lda #0
jsr SetBG0YPos
lda StartY
lda StartY
lsr
jsr SetBG1YPos
jsr SetBG1YPos
jsr DoFrame
jsr DoFrame
pla
rts
; Very simple, scroll as fast as possible
oldOneSecondCounter ds 2
frameCount ds 2
oldOneSecondCounter ds 2
frameCount ds 2
lastTick ds 2
Demo
lda OneSecondCounter
sta oldOneSecondCounter
stz frameCount
lda OneSecondCounter
sta oldOneSecondCounter
stz frameCount
:loop
lda #1
jsr MoveLeft
inc frameCount
ldal KBD_STROBE_REG
bit #$0080
beq :nokey
and #$007F
cmp #'s'
bne :nokey
PushLong #0
_GetTick
pla
plx
cmp lastTick ; Throttle to 60 fps
beq :loop
sta lastTick
and #$003C ; An 4-step animation that fires every 16 ticks
lsr
sta BG1OffsetIndex ; Set the value
lda #1
jsr MoveLeft
jsr DoFrame
inc frameCount
ldal KBD_STROBE_REG
bit #$0080
beq :nokey
and #$007F
cmp #'s'
bne :nokey
rts
:nokey
lda OneSecondCounter
cmp oldOneSecondCounter
beq :loop
lda OneSecondCounter
cmp oldOneSecondCounter
beq :loop
sta oldOneSecondCounter
lda ScreenWidth
cmp #150
bcs :loop
lda #FPSStr
ldx #0 ; top-left corner
ldy #$7777
jsr DrawString
lda frameCount
ldx #4*4
jsr DrawWord
stz frameCount
bra :loop
FPSStr str 'FPS'
sta oldOneSecondCounter
lda ScreenWidth
cmp #150
bcs :loop
lda #FPSStr
ldx #0 ; top-left corner
ldy #$7777
jsr DrawString
lda frameCount
ldx #4*4
jsr DrawWord
stz frameCount
bra :loop
FPSStr str 'FPS'

View File

@ -42,7 +42,7 @@ SHR_PALETTES equ $E19E00
tiledata ext
; Feature flags
NO_INTERRUPTS equ 1 ; turn off for crossrunner debugging
NO_INTERRUPTS equ 0 ; turn off for crossrunner debugging
; Typical init
@ -873,6 +873,7 @@ BlitInit
stz BG1StartXMod164
stz BG1StartY
stz BG1StartYMod208
stz BG1OffsetIndex
]step equ 0
lup 13
@ -1283,6 +1284,11 @@ qtRec adrl $0000

View File

@ -6,31 +6,31 @@ _InitBG1
SetBG1XPos
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)
sta BG1StartX ; Save the new position
ldx BG1StartX ; Load the old value (but don't save it yet)
sta BG1StartX ; Save the new position
lda #DIRTY_BIT_BG1_X
tsb DirtyBits ; Check if the value is already dirty, if so exit
bne :out ; without overwriting the original value
tsb DirtyBits ; Check if the value is already dirty, if so exit
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
SetBG1YPos
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)
sta BG1StartY ; Save the new position
ldx BG1StartY ; Load the old value (but don't save it yet)
sta BG1StartY ; Save the new position
lda #DIRTY_BIT_BG1_Y
tsb DirtyBits ; Check if the value is already dirty, if so exit
bne :out ; without overwriting the original value
tsb DirtyBits ; Check if the value is already dirty, if so exit
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
@ -58,23 +58,19 @@ _ApplyBG1XPos
sbc #164
tay
phd ; save the direct page because we are going to switch to the
lda BlitterDP ; blitter direct page space and fill in the addresses
phd ; save the direct page because we are going to switch to the
lda BlitterDP ; blitter direct page space and fill in the addresses
tcd
ldx #162
tya
:loop
tya
clc
adc affine,x
sta 00,x ; store the value
dey
dey
sta 00,x ; store the value
dec
dec
bpl :nowrap
tya
clc
adc #164
tay
:nowrap
dex
@ -83,40 +79,6 @@ _ApplyBG1XPos
pld
rts
affine ds 164
; Pass accumulator to set every (A / 256) pitch
SetAffine
ldx #0
ldy #0
and #$00FF
pha ; step size
pea $0000
:loop lda 1,s
clc
adc 3,s
cmp #256
bcc :skip
tya
clc
adc #256 ; Move to next BG1 line
tay
:skip and #$00FF ; always clamp to 256
sta 1,s
tya
sta affine,x
inx
inx
cpx #164
bcc :loop
pla
pla
rts
_ClearBG1Buffer
phb
pha
@ -150,10 +112,10 @@ _ApplyBG1YPos
lda BG1StartY
jsr Mod208
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
sta :virt_line ; Keep track of it
lda StartYMod208 ; This is the base line of the virtual screen
sta :virt_line ; Keep track of it
lda ScreenHeight
sta :lines_left
@ -162,13 +124,13 @@ _ApplyBG1YPos
lda :virt_line
asl
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
sep #$20
ldal BTableHigh,x
pha
plb ; This is the bank that will receive the updates
pha ; push the bank on the stack
plb
rep #$20
lda :virt_line
@ -179,24 +141,24 @@ _ApplyBG1YPos
adc #16
min :lines_left
sta :draw_count ; Do this many lines
sta :draw_count ; Do this many lines
asl
tax
lda :ytbl_idx ; Read from this location in the BG1YTable
lda :ytbl_idx ; Read from this location in the BG1YTable
asl
jsr CopyBG1YTableToBG1Addr
jsr CopyBG1YTableToBG1Addr2
lda :virt_line ; advance to the virtual line after the segment we just
clc ; filled in
lda :virt_line ; advance to the virtual line after the segment we just
clc ; filled in
adc :draw_count
sta :virt_line
lda :ytbl_idx ; advance the index into the YTable
lda :ytbl_idx ; advance the index into the YTable
adc :draw_count
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
sbc :draw_count
sta :lines_left
@ -285,12 +247,28 @@ CopyBG1YTableToBG1Addr
:none rts
; Unrolled copy routine to move BG1YTable entries into BG1_ADDR position with an additional
; shift
; shift. This has to be split into two
;
; A = index into the BG1YTable array (x2)
; Y = starting line * $1000
; X = number of lines (x2)
CopyBG1YTableToBG1Addr2
phy ; save the registers
phx
phb
phk ; restore access to this bank
plb
ldy BG1OffsetIndex ; Get the offset and save the values
jsr SaveBG1OffsetValues
plb
plx ; x is used directly in this routine
ply
jsr ApplyBG1OffsetValues
rts
SaveBG1OffsetValues
jmp (:tbl,x)
:tbl da :none
da :do01,:do02,:do03,:do04
@ -314,54 +292,54 @@ CopyBG1YTableToBG1Addr2
: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
lda BG1YTable+30,x
adc BG1YOffsetTable+30,y
sta BG1YCache+30
:x15 lda BG1YTable+28,x
adc BG1YOffsetTable+28,y
sta BG1YCache+28
:x14 lda BG1YTable+26,x
adc BG1YOffsetTable+26,y
sta BG1YCache+26
:x13 lda BG1YTable+24,x
adc BG1YOffsetTable+24,y
sta BG1YCache+24
:x12 lda BG1YTable+22,x
adc BG1YOffsetTable+22,y
sta BG1YCache+22
:x11 lda BG1YTable+20,x
adc BG1YOffsetTable+20,y
sta BG1YCache+20
:x10 lda BG1YTable+18,x
adc BG1YOffsetTable+18,y
sta BG1YCache+18
:x09 lda BG1YTable+16,x
adc BG1YOffsetTable+16,y
sta BG1YCache+16
:x08 lda BG1YTable+14,x
adc BG1YOffsetTable+14,y
sta BG1YCache+14
:x07 lda BG1YTable+12,x
adc BG1YOffsetTable+12,y
sta BG1YCache+12
:x06 lda BG1YTable+10,x
adc BG1YOffsetTable+10,y
sta BG1YCache+10
:x05 lda BG1YTable+08,x
adc BG1YOffsetTable+08,y
sta BG1YCache+08
:x04 lda BG1YTable+06,x
adc BG1YOffsetTable+06,y
sta BG1YCache+06
:x03 lda BG1YTable+04,x
adc BG1YOffsetTable+04,y
sta BG1YCache+04
:x02 lda BG1YTable+02,x
adc BG1YOffsetTable+02,y
sta BG1YCache+02
:x01 lda BG1YTable+00,x
adc BG1YOffsetTable+00,y
sta BG1YCache+00
:none rts
:do07 tax
bra :x07
@ -379,62 +357,48 @@ CopyBG1YTableToBG1Addr2
bra :x01
ApplyBG1OffsetValues
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
:do16 ldal BG1YCache+30
sta BG1_ADDR+$F000,y
:do15 ldal BG1YCache+28
sta BG1_ADDR+$E000,y
:do14 ldal BG1YCache+26
sta BG1_ADDR+$D000,y
:do13 ldal BG1YCache+24
sta BG1_ADDR+$C000,y
:do12 ldal BG1YCache+22
sta BG1_ADDR+$B000,y
:do11 ldal BG1YCache+20
sta BG1_ADDR+$A000,y
:do10 ldal BG1YCache+18
sta BG1_ADDR+$9000,y
:do09 ldal BG1YCache+16
sta BG1_ADDR+$8000,y
:do08 ldal BG1YCache+14
sta BG1_ADDR+$7000,y
:do07 ldal BG1YCache+12
sta BG1_ADDR+$6000,y
:do06 ldal BG1YCache+10
sta BG1_ADDR+$5000,y
:do05 ldal BG1YCache+08
sta: BG1_ADDR+$4000,y
:do04 ldal BG1YCache+06
sta BG1_ADDR+$3000,y
:do03 ldal BG1YCache+04
sta BG1_ADDR+$2000,y
:do02 ldal BG1YCache+02
sta BG1_ADDR+$1000,y
:do01 ldal BG1YCache+00
sta: BG1_ADDR+$0000,y
:none rts
BG1YCache ds 32

View File

@ -35,6 +35,8 @@ BG1StartYMod208 equ 46
OldBG1StartX equ 48
OldBG1StartY equ 50
BG1OffsetIndex equ 52
BankLoad equ 128
bstk equ 208 ; 16-byte stack to push bank addresses
@ -80,5 +82,6 @@ DIRTY_BIT_BG1_Y equ $0008

View File

@ -238,6 +238,13 @@ BG1YTable lup 208
]step = ]step+256
--^
BG1YOffsetTable ds 208*2*2
; Repeat
BG1YOffsetTable lup 26
dw 1,1,1,1,2,2,2,2,1,1,1,1,0,0,0,0
--^