Merge branch 'streamline-apply-bg0'

This commit is contained in:
Lucas Scharenbroich 2022-07-28 13:27:47 -05:00
commit 7c32c89493
5 changed files with 353 additions and 378 deletions

View File

@ -56,12 +56,6 @@ appTmp0 equ 28
stz StartY stz StartY
stz frameCount stz frameCount
; Initialize the graphics screen playfield
pea #320
pea #200
_GTESetScreenMode
; Load a tileset ; Load a tileset
pea #^tiledata pea #^tiledata

View File

@ -28,9 +28,7 @@ InitMemory lda EngineMode
_NewHandle ; returns LONG Handle on stack _NewHandle ; returns LONG Handle on stack
plx ; base address of the new handle plx ; base address of the new handle
pla ; high address 00XX of the new handle (bank) pla ; high address 00XX of the new handle (bank)
; _Deref
; stx Buff00
; sta Buff00+2
:no_bnk0_buff :no_bnk0_buff
PushLong #0 ; space for result PushLong #0 ; space for result
@ -41,9 +39,6 @@ InitMemory lda EngineMode
_NewHandle ; returns LONG Handle on stack _NewHandle ; returns LONG Handle on stack
plx ; base address of the new handle plx ; base address of the new handle
pla ; high address 00XX of the new handle (bank) pla ; high address 00XX of the new handle (bank)
; _Deref
; stx Buff01
; sta Buff01+2
PushLong #0 ; space for result PushLong #0 ; space for result

View File

@ -20,6 +20,7 @@ _RestoreBG0Opcodes
:lines_left_x2 equ tmp2 :lines_left_x2 equ tmp2
:draw_count_x2 equ tmp3 :draw_count_x2 equ tmp3
:exit_offset equ tmp4 :exit_offset equ tmp4
:stk_save equ tmp5
phb ; Save data bank phb ; Save data bank
@ -33,39 +34,36 @@ _RestoreBG0Opcodes
lda LastPatchOffset ; If zero, there are no saved opcodes lda LastPatchOffset ; If zero, there are no saved opcodes
sta :exit_offset sta :exit_offset
tsc
sta :stk_save
:loop :loop
ldx :virt_line_x2 ldx :virt_line_x2
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 ldal BTableHigh,x ; This intentionally leaks one byte on the stack
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
txa ; lda :virt_line_x2 txa ; lda :virt_line_x2
and #$001E and #$001E
eor #$FFFF eor #$FFFF
inc sec
clc
adc #32 adc #32
min :lines_left_x2 min :lines_left_x2
sta :draw_count_x2 ; Do half of this many lines sta :draw_count_x2 ; Do half of this many lines
; y is already set to :base_address ; y is already set to :base_address
tax ; :draw_count * 2 tax ; :draw_count * 2
clc
adc :virt_line_x2
sta :virt_line_x2
tya tya
clc
adc :exit_offset ; Add some offsets to get the base address in the code field line adc :exit_offset ; Add some offsets to get the base address in the code field line
jsr RestoreOpcode RestoreOpcode
lda :virt_line_x2 ; advance to the virtual line after the segment we just
clc ; filled in
adc :draw_count_x2
sta :virt_line_x2
lda :lines_left_x2 ; subtract the number of lines we just completed lda :lines_left_x2 ; subtract the number of lines we just completed
sec sec
@ -73,9 +71,11 @@ _RestoreBG0Opcodes
sta :lines_left_x2 sta :lines_left_x2
jne :loop jne :loop
stz LastPatchOffset ; Clear the value once completed stz LastPatchOffset ; Clear the value once completed
:out lda :stk_save
tcs
plb plb
rts rts
@ -113,16 +113,16 @@ _ApplyBG0XPosPre
_ApplyBG0XPos _ApplyBG0XPos
:virt_line equ tmp1 :stk_save equ tmp0
:lines_left equ tmp2 :virt_line_x2 equ tmp1
:draw_count equ tmp3 :lines_left_x2 equ tmp2
:draw_count_x2 equ tmp3
:exit_offset equ tmp4 :exit_offset equ tmp4
:entry_offset equ tmp5 :entry_offset equ tmp5
:exit_bra equ tmp6 :exit_bra equ tmp6
:exit_address equ tmp7 :exit_address equ tmp7
:base_address equ tmp8 :base_address equ tmp8
:draw_count_x2 equ tmp9 :opcode equ tmp9
:opcode equ tmp0
:odd_entry_offset equ tmp10 :odd_entry_offset equ tmp10
; If there are saved opcodes that have not been restored, do not run this routine ; If there are saved opcodes that have not been restored, do not run this routine
@ -133,10 +133,12 @@ _ApplyBG0XPos
; This code is fairly succinct. See the corresponding code in Vert.s for more detailed comments. ; This code is fairly succinct. See the corresponding code in Vert.s for more detailed comments.
:ok :ok
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 asl
sta :virt_line_x2 ; Keep track of it
lda ScreenHeight lda ScreenHeight
sta :lines_left asl
sta :lines_left_x2
; Calculate the exit and entry offsets into the code fields. This is a bit tricky, because odd-aligned ; Calculate the exit and entry offsets into the code fields. This is a bit tricky, because odd-aligned
; rendering causes the left and right edges to move in a staggered fashion. ; rendering causes the left and right edges to move in a staggered fashion.
@ -280,32 +282,30 @@ _ApplyBG0XPos
; 3. Writes the JMP entry point to enter the code field ; 3. Writes the JMP entry point to enter the code field
phb ; Save the existing bank phb ; Save the existing bank
tsc
sta :stk_save
:loop :loop
lda :virt_line ldx :virt_line_x2
asl ; This will clear the carry bit
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 ; Save it to use as the base address tay ; Save it to use as the base address
clc
adc :exit_offset ; Add some offsets to get the base address in the code field line adc :exit_offset ; Add some offsets to get the base address in the code field line
sta :exit_address sta :exit_address
sty :base_address sty :base_address
sep #$20
ldal BTableHigh,x ldal BTableHigh,x
pha pha
plb ; This is the bank that will receive the updates plb
rep #$20
lda :virt_line txa
and #$000F and #$001E
eor #$FFFF eor #$FFFF
inc sec
clc adc #32
adc #16 min :lines_left_x2
min :lines_left
sta :draw_count ; Do this many lines
asl
sta :draw_count_x2 sta :draw_count_x2
; First step is to set the BRA instruction to exit the code field at the proper location. There ; First step is to set the BRA instruction to exit the code field at the proper location. There
@ -317,64 +317,55 @@ _ApplyBG0XPos
; screen ; screen
; y is already set to :base_address ; y is already set to :base_address
tax ; :draw_count_x2 tax ; :draw_count_x2
lda :exit_address ; Save from this location clc ; advance to the virtual line after the segment we just
jsr SaveOpcode adc :virt_line_x2 ; filled in
sta :virt_line_x2
lda :exit_address ; Save from this location
SaveOpcode ; X = :exit_address on return
txy ; ldy :exit_address -- starting at this address
ldx :draw_count_x2 ; Do this many lines ldx :draw_count_x2 ; Do this many lines
lda :exit_bra ; Copy this value into all of the lines lda :exit_bra ; Copy this value into all of the lines
ldy :exit_address ; starting at this address SetConst ; All registers are preserved
jsr SetConst
; Next, patch in the CODE_ENTRY value, which is the low byte of a JMP instruction. This is an ; Next, patch in the CODE_ENTRY value, which is the low byte of a JMP instruction. This is an
; 8-bit operation and, since the PEA code is bank aligned, we use the entry_offset value directly ; 8-bit operation and, since the PEA code is bank aligned, we use the entry_offset value directly
sep #$20 sep #$20
ldx :draw_count_x2
lda :entry_offset lda :entry_offset
ldy :base_address ldy :base_address
jsr SetCodeEntry SetCodeEntry ; All registers are preserved
; Now, patch in the opcode ; Now, patch in the opcode
ldx :draw_count_x2
lda :opcode lda :opcode
ldy :base_address ; Y-register is preserved, this can be removed SetCodeEntryOpcode ; All registers are preserved
jsr SetCodeEntryOpcode
; If this is an odd entry, also set the odd_entry low byte and save the operand high byte ; If this is an odd entry, also set the odd_entry low byte and save the operand high byte
lda :odd_entry_offset lda :odd_entry_offset
beq :not_odd jeq :not_odd
ldx :draw_count_x2 SetOddCodeEntry ; All registers are preserved
ldy :base_address ; Y-register is preserved, this can be removed SaveHighOperand :exit_address ; Only used once, so "inline" it
jsr SetOddCodeEntry
ldx :draw_count_x2
ldy :base_address ; Y-register is preserved, this can be removed
pei :exit_address
jmp :SaveHighOperand ; Only used once, so "inline" it
:save_high_op_rtn
:not_odd :not_odd
rep #$20 rep #$21 ; clear the carry
; Do the end of the loop -- update the virtual line counter and reduce the number ; Do the end of the loop -- update the virtual line counter and reduce the number
; of lines left to render ; of lines left to render
lda :virt_line ; advance to the virtual line after the segment we just lda :lines_left_x2 ; subtract the number of lines we just completed
clc ; filled in
adc :draw_count
sta :virt_line
lda :lines_left ; subtract the number of lines we just completed
sec sec
sbc :draw_count sbc :draw_count_x2
sta :lines_left sta :lines_left_x2
jne :loop jne :loop
lda :stk_save
tcs
plb plb
rts rts
@ -386,79 +377,78 @@ _ApplyBG0XPos
; X = number of lines * 2, 0 to 32 ; X = number of lines * 2, 0 to 32
; Y = starting line * $1000 ; Y = starting line * $1000
; A = code field location * $1000 ; A = code field location * $1000
:SaveHighOperand SaveHighOperand mac
jmp (:tbl,x) jmp (dispTbl,x)
dispTbl da bottom
da do01,do02,do03,do04
da do05,do06,do07,do08
da do09,do10,do11,do12
da do13,do14,do15,do16
:tbl da :bottom do15 ldx ]1 ; accumulator is in 8-bit mode, so can't use TAX
da :do01,:do02,:do03,:do04 bra x15
da :do05,:do06,:do07,:do08 do14 ldx ]1
da :do09,:do10,:do11,:do12 bra x14
da :do13,:do14,:do15,:do16 do13 ldx ]1
bra x13
:do15 plx do12 ldx ]1
bra :x15 bra x12
:do14 plx do11 ldx ]1
bra :x14 bra x11
:do13 plx do10 ldx ]1
bra :x13 bra x10
:do12 plx do09 ldx ]1
bra :x12 bra x09
:do11 plx do08 ldx ]1
bra :x11 bra x08
:do10 plx do07 ldx ]1
bra :x10 bra x07
:do09 plx do06 ldx ]1
bra :x09 bra x06
:do08 plx do05 ldx ]1
bra :x08 bra x05
:do07 plx do04 ldx ]1
bra :x07 bra x04
:do06 plx do03 ldx ]1
bra :x06 bra x03
:do05 plx do02 ldx ]1
bra :x05 bra x02
:do04 plx do01 ldx ]1
bra :x04 bra x01
:do03 plx do16 ldx ]1
bra :x03 x16 lda $F002,x
:do02 plx
bra :x02
:do01 plx
bra :x01
:do16 plx
:x16 lda $F002,x
sta OPCODE_HIGH_SAVE+$F000,y sta OPCODE_HIGH_SAVE+$F000,y
:x15 lda $E002,x x15 lda $E002,x
sta OPCODE_HIGH_SAVE+$E000,y sta OPCODE_HIGH_SAVE+$E000,y
:x14 lda $D002,x x14 lda $D002,x
sta OPCODE_HIGH_SAVE+$D000,y sta OPCODE_HIGH_SAVE+$D000,y
:x13 lda $C002,x x13 lda $C002,x
sta OPCODE_HIGH_SAVE+$C000,y sta OPCODE_HIGH_SAVE+$C000,y
:x12 lda $B002,x x12 lda $B002,x
sta OPCODE_HIGH_SAVE+$B000,y sta OPCODE_HIGH_SAVE+$B000,y
:x11 lda $A002,x x11 lda $A002,x
sta OPCODE_HIGH_SAVE+$A000,y sta OPCODE_HIGH_SAVE+$A000,y
:x10 lda $9002,x x10 lda $9002,x
sta OPCODE_HIGH_SAVE+$9000,y sta OPCODE_HIGH_SAVE+$9000,y
:x09 lda $8002,x x09 lda $8002,x
sta OPCODE_HIGH_SAVE+$8000,y sta OPCODE_HIGH_SAVE+$8000,y
:x08 lda $7002,x x08 lda $7002,x
sta OPCODE_HIGH_SAVE+$7000,y sta OPCODE_HIGH_SAVE+$7000,y
:x07 lda $6002,x x07 lda $6002,x
sta OPCODE_HIGH_SAVE+$6000,y sta OPCODE_HIGH_SAVE+$6000,y
:x06 lda $5002,x x06 lda $5002,x
sta OPCODE_HIGH_SAVE+$5000,y sta OPCODE_HIGH_SAVE+$5000,y
:x05 lda $4002,x x05 lda $4002,x
sta OPCODE_HIGH_SAVE+$4000,y sta OPCODE_HIGH_SAVE+$4000,y
:x04 lda $3002,x x04 lda $3002,x
sta OPCODE_HIGH_SAVE+$3000,y sta OPCODE_HIGH_SAVE+$3000,y
:x03 lda $2002,x x03 lda $2002,x
sta OPCODE_HIGH_SAVE+$2000,y sta OPCODE_HIGH_SAVE+$2000,y
:x02 lda $1002,x x02 lda $1002,x
sta OPCODE_HIGH_SAVE+$1000,y sta OPCODE_HIGH_SAVE+$1000,y
:x01 lda: $0002,x x01 lda: $0002,x
sta: OPCODE_HIGH_SAVE+$0000,y sta: OPCODE_HIGH_SAVE+$0000,y
:bottom jmp :save_high_op_rtn bottom <<<
; SaveOpcode ; SaveOpcode
; ;
@ -468,79 +458,79 @@ _ApplyBG0XPos
; X = number of lines * 2, 0 to 32 ; X = number of lines * 2, 0 to 32
; Y = starting line * $1000 ; Y = starting line * $1000
; A = code field location * $1000 ; A = code field location * $1000
SaveOpcode SaveOpcode mac
jmp (:tbl,x) jmp (dispTbl,x)
dispTbl da bottom
da do01,do02,do03,do04
da do05,do06,do07,do08
da do09,do10,do11,do12
da do13,do14,do15,do16
:tbl da :bottom do15 tax
da :do01,:do02,:do03,:do04 bra x15
da :do05,:do06,:do07,:do08 do14 tax
da :do09,:do10,:do11,:do12 bra x14
da :do13,:do14,:do15,:do16 do13 tax
bra x13
:do15 tax do12 tax
bra :x15 bra x12
:do14 tax do11 tax
bra :x14 bra x11
:do13 tax do10 tax
bra :x13 bra x10
:do12 tax do09 tax
bra :x12 bra x09
:do11 tax do08 tax
bra :x11 bra x08
:do10 tax do07 tax
bra :x10 bra x07
:do09 tax do06 tax
bra :x09 bra x06
:do08 tax do05 tax
bra :x08 bra x05
:do07 tax do04 tax
bra :x07 bra x04
:do06 tax do03 tax
bra :x06 bra x03
:do05 tax do02 tax
bra :x05 bra x02
:do04 tax do01 tax
bra :x04 bra x01
:do03 tax do16 tax
bra :x03 x16 lda $F000,x
:do02 tax
bra :x02
:do01 tax
bra :x01
:do16 tax
:x16 lda $F000,x
sta OPCODE_SAVE+$F000,y sta OPCODE_SAVE+$F000,y
:x15 lda $E000,x x15 lda $E000,x
sta OPCODE_SAVE+$E000,y sta OPCODE_SAVE+$E000,y
:x14 lda $D000,x x14 lda $D000,x
sta OPCODE_SAVE+$D000,y sta OPCODE_SAVE+$D000,y
:x13 lda $C000,x x13 lda $C000,x
sta OPCODE_SAVE+$C000,y sta OPCODE_SAVE+$C000,y
:x12 lda $B000,x x12 lda $B000,x
sta OPCODE_SAVE+$B000,y sta OPCODE_SAVE+$B000,y
:x11 lda $A000,x x11 lda $A000,x
sta OPCODE_SAVE+$A000,y sta OPCODE_SAVE+$A000,y
:x10 lda $9000,x x10 lda $9000,x
sta OPCODE_SAVE+$9000,y sta OPCODE_SAVE+$9000,y
:x09 lda $8000,x x09 lda $8000,x
sta OPCODE_SAVE+$8000,y sta OPCODE_SAVE+$8000,y
:x08 lda $7000,x x08 lda $7000,x
sta OPCODE_SAVE+$7000,y sta OPCODE_SAVE+$7000,y
:x07 lda $6000,x x07 lda $6000,x
sta OPCODE_SAVE+$6000,y sta OPCODE_SAVE+$6000,y
:x06 lda $5000,x x06 lda $5000,x
sta OPCODE_SAVE+$5000,y sta OPCODE_SAVE+$5000,y
:x05 lda $4000,x x05 lda $4000,x
sta OPCODE_SAVE+$4000,y sta OPCODE_SAVE+$4000,y
:x04 lda $3000,x x04 lda $3000,x
sta OPCODE_SAVE+$3000,y sta OPCODE_SAVE+$3000,y
:x03 lda $2000,x x03 lda $2000,x
sta OPCODE_SAVE+$2000,y sta OPCODE_SAVE+$2000,y
:x02 lda $1000,x x02 lda $1000,x
sta OPCODE_SAVE+$1000,y sta OPCODE_SAVE+$1000,y
:x01 lda: $0000,x x01 lda: $0000,x
sta: OPCODE_SAVE+$0000,y sta: OPCODE_SAVE+$0000,y
:bottom rts bottom
<<<
; RestoreOpcode ; RestoreOpcode
; ;
@ -549,79 +539,79 @@ SaveOpcode
; X = number of lines * 2, 0 to 32 ; X = number of lines * 2, 0 to 32
; Y = starting line * $1000 ; Y = starting line * $1000
; A = code field location * $1000 ; A = code field location * $1000
RestoreOpcode RestoreOpcode mac
jmp (:tbl,x) jmp (dispTbl,x)
dispTbl da bottom
da do01,do02,do03,do04
da do05,do06,do07,do08
da do09,do10,do11,do12
da do13,do14,do15,do16
:tbl da :bottom do15 tax
da :do01,:do02,:do03,:do04 bra x15
da :do05,:do06,:do07,:do08 do14 tax
da :do09,:do10,:do11,:do12 bra x14
da :do13,:do14,:do15,:do16 do13 tax
bra x13
:do15 tax do12 tax
bra :x15 bra x12
:do14 tax do11 tax
bra :x14 bra x11
:do13 tax do10 tax
bra :x13 bra x10
:do12 tax do09 tax
bra :x12 bra x09
:do11 tax do08 tax
bra :x11 bra x08
:do10 tax do07 tax
bra :x10 bra x07
:do09 tax do06 tax
bra :x09 bra x06
:do08 tax do05 tax
bra :x08 bra x05
:do07 tax do04 tax
bra :x07 bra x04
:do06 tax do03 tax
bra :x06 bra x03
:do05 tax do02 tax
bra :x05 bra x02
:do04 tax do01 tax
bra :x04 bra x01
:do03 tax do16 tax
bra :x03 x16 lda OPCODE_SAVE+$F000,y
:do02 tax
bra :x02
:do01 tax
bra :x01
:do16 tax
:x16 lda OPCODE_SAVE+$F000,y
sta $F000,x sta $F000,x
:x15 lda OPCODE_SAVE+$E000,y x15 lda OPCODE_SAVE+$E000,y
sta $E000,x sta $E000,x
:x14 lda OPCODE_SAVE+$D000,y x14 lda OPCODE_SAVE+$D000,y
sta $D000,x sta $D000,x
:x13 lda OPCODE_SAVE+$C000,y x13 lda OPCODE_SAVE+$C000,y
sta $C000,x sta $C000,x
:x12 lda OPCODE_SAVE+$B000,y x12 lda OPCODE_SAVE+$B000,y
sta $B000,x sta $B000,x
:x11 lda OPCODE_SAVE+$A000,y x11 lda OPCODE_SAVE+$A000,y
sta $A000,x sta $A000,x
:x10 lda OPCODE_SAVE+$9000,y x10 lda OPCODE_SAVE+$9000,y
sta $9000,x sta $9000,x
:x09 lda OPCODE_SAVE+$8000,y x09 lda OPCODE_SAVE+$8000,y
sta $8000,x sta $8000,x
:x08 lda OPCODE_SAVE+$7000,y x08 lda OPCODE_SAVE+$7000,y
sta $7000,x sta $7000,x
:x07 lda OPCODE_SAVE+$6000,y x07 lda OPCODE_SAVE+$6000,y
sta $6000,x sta $6000,x
:x06 lda OPCODE_SAVE+$5000,y x06 lda OPCODE_SAVE+$5000,y
sta $5000,x sta $5000,x
:x05 lda OPCODE_SAVE+$4000,y x05 lda OPCODE_SAVE+$4000,y
sta $4000,x sta $4000,x
:x04 lda OPCODE_SAVE+$3000,y x04 lda OPCODE_SAVE+$3000,y
sta $3000,x sta $3000,x
:x03 lda OPCODE_SAVE+$2000,y x03 lda OPCODE_SAVE+$2000,y
sta $2000,x sta $2000,x
:x02 lda OPCODE_SAVE+$1000,y x02 lda OPCODE_SAVE+$1000,y
sta $1000,x sta $1000,x
:x01 lda: OPCODE_SAVE+$0000,y x01 lda: OPCODE_SAVE+$0000,y
sta: $0000,x sta: $0000,x
:bottom rts bottom
<<<
; SetCodeEntry ; SetCodeEntry
; ;
@ -630,14 +620,14 @@ RestoreOpcode
; X = number of lines * 2, 0 to 32 ; X = number of lines * 2, 0 to 32
; Y = starting line * $1000 ; Y = starting line * $1000
; A = address low byte ; A = address low byte
SetCodeEntry SetCodeEntry mac
jmp (:tbl,x) jmp (dispTbl,x)
:tbl da :bottom-00,:bottom-03,:bottom-06,:bottom-09 dispTbl da bottom-00,bottom-03,bottom-06,bottom-09
da :bottom-12,:bottom-15,:bottom-18,:bottom-21 da bottom-12,bottom-15,bottom-18,bottom-21
da :bottom-24,:bottom-27,:bottom-30,:bottom-33 da bottom-24,bottom-27,bottom-30,bottom-33
da :bottom-36,:bottom-39,:bottom-42,:bottom-45 da bottom-36,bottom-39,bottom-42,bottom-45
da :bottom-48 da bottom-48
:top sta CODE_ENTRY+$F000,y sta CODE_ENTRY+$F000,y
sta CODE_ENTRY+$E000,y sta CODE_ENTRY+$E000,y
sta CODE_ENTRY+$D000,y sta CODE_ENTRY+$D000,y
sta CODE_ENTRY+$C000,y sta CODE_ENTRY+$C000,y
@ -653,7 +643,8 @@ SetCodeEntry
sta CODE_ENTRY+$2000,y sta CODE_ENTRY+$2000,y
sta CODE_ENTRY+$1000,y sta CODE_ENTRY+$1000,y
sta: CODE_ENTRY+$0000,y sta: CODE_ENTRY+$0000,y
:bottom rts bottom
<<<
; SetOddCodeEntry ; SetOddCodeEntry
; ;
@ -662,14 +653,14 @@ SetCodeEntry
; X = number of lines * 2, 0 to 32 ; X = number of lines * 2, 0 to 32
; Y = starting line * $1000 ; Y = starting line * $1000
; A = address low byte ; A = address low byte
SetOddCodeEntry SetOddCodeEntry mac
jmp (:tbl,x) jmp (dispTbl,x)
:tbl da :bottom-00,:bottom-03,:bottom-06,:bottom-09 dispTbl da bottom-00,bottom-03,bottom-06,bottom-09
da :bottom-12,:bottom-15,:bottom-18,:bottom-21 da bottom-12,bottom-15,bottom-18,bottom-21
da :bottom-24,:bottom-27,:bottom-30,:bottom-33 da bottom-24,bottom-27,bottom-30,bottom-33
da :bottom-36,:bottom-39,:bottom-42,:bottom-45 da bottom-36,bottom-39,bottom-42,bottom-45
da :bottom-48 da bottom-48
:top sta ODD_ENTRY+$F000,y sta ODD_ENTRY+$F000,y
sta ODD_ENTRY+$E000,y sta ODD_ENTRY+$E000,y
sta ODD_ENTRY+$D000,y sta ODD_ENTRY+$D000,y
sta ODD_ENTRY+$C000,y sta ODD_ENTRY+$C000,y
@ -685,7 +676,8 @@ SetOddCodeEntry
sta ODD_ENTRY+$2000,y sta ODD_ENTRY+$2000,y
sta ODD_ENTRY+$1000,y sta ODD_ENTRY+$1000,y
sta: ODD_ENTRY+$0000,y sta: ODD_ENTRY+$0000,y
:bottom rts bottom
<<<
; SetCodeEntryOpcode ; SetCodeEntryOpcode
; ;
@ -694,14 +686,14 @@ SetOddCodeEntry
; X = number of lines * 2, 0 to 32 ; X = number of lines * 2, 0 to 32
; Y = starting line * $1000 ; Y = starting line * $1000
; A = opcode value ; A = opcode value
SetCodeEntryOpcode SetCodeEntryOpcode mac
jmp (:tbl,x) jmp (dispTbl,x)
:tbl da :bottom-00,:bottom-03,:bottom-06,:bottom-09 dispTbl da bottom-00,bottom-03,bottom-06,bottom-09
da :bottom-12,:bottom-15,:bottom-18,:bottom-21 da bottom-12,bottom-15,bottom-18,bottom-21
da :bottom-24,:bottom-27,:bottom-30,:bottom-33 da bottom-24,bottom-27,bottom-30,bottom-33
da :bottom-36,:bottom-39,:bottom-42,:bottom-45 da bottom-36,bottom-39,bottom-42,bottom-45
da :bottom-48 da bottom-48
:top sta CODE_ENTRY_OPCODE+$F000,y sta CODE_ENTRY_OPCODE+$F000,y
sta CODE_ENTRY_OPCODE+$E000,y sta CODE_ENTRY_OPCODE+$E000,y
sta CODE_ENTRY_OPCODE+$D000,y sta CODE_ENTRY_OPCODE+$D000,y
sta CODE_ENTRY_OPCODE+$C000,y sta CODE_ENTRY_OPCODE+$C000,y
@ -717,4 +709,5 @@ SetCodeEntryOpcode
sta CODE_ENTRY_OPCODE+$2000,y sta CODE_ENTRY_OPCODE+$2000,y
sta CODE_ENTRY_OPCODE+$1000,y sta CODE_ENTRY_OPCODE+$1000,y
sta: CODE_ENTRY_OPCODE+$0000,y sta: CODE_ENTRY_OPCODE+$0000,y
:bottom rts bottom
<<<

View File

@ -87,14 +87,14 @@ Counter equ tmp3
; A = value ; A = value
; ;
; Set M to 0 or 1 ; Set M to 0 or 1
SetConst ; Need a blank line here, otherwise the :tbl local variable resolveds backwards SetConst mac
jmp (:tbl,x) jmp (dispTbl,x)
:tbl da :bottom-00,:bottom-03,:bottom-06,:bottom-09 dispTbl da bottom-00,bottom-03,bottom-06,bottom-09
da :bottom-12,:bottom-15,:bottom-18,:bottom-21 da bottom-12,bottom-15,bottom-18,bottom-21
da :bottom-24,:bottom-27,:bottom-30,:bottom-33 da bottom-24,bottom-27,bottom-30,bottom-33
da :bottom-36,:bottom-39,:bottom-42,:bottom-45 da bottom-36,bottom-39,bottom-42,bottom-45
da :bottom-48 da bottom-48
:top sta $F000,y sta $F000,y
sta $E000,y sta $E000,y
sta $D000,y sta $D000,y
sta $C000,y sta $C000,y
@ -110,7 +110,8 @@ SetConst ; Need a blank line here, ot
sta $2000,y sta $2000,y
sta $1000,y sta $1000,y
sta: $0000,y sta: $0000,y
:bottom rts bottom
<<<
; SetDPAddrs ; SetDPAddrs
; ;

View File

@ -7,29 +7,36 @@
; lines in the correct order ; lines in the correct order
_ApplyBG0YPos _ApplyBG0YPos
:rtbl_idx equ tmp0 :rtbl_idx_x2 equ tmp0
:virt_line equ tmp1 :virt_line_x2 equ tmp1
:lines_left equ tmp2 :lines_left_x2 equ tmp2
:draw_count equ tmp3 :draw_count_x2 equ tmp3
:stk_save equ tmp4
; First task is to fill in the STK_ADDR values by copying them from the RTable array. We ; First task is to fill in the STK_ADDR values by copying them from the RTable array. We
; copy from RTable[i] into BlitField[StartY+i]. As with all of this code, the difficult part ; copy from RTable[i] into BlitField[StartY+i]. As with all of this code, the difficult part
; is decomposing the update across banks ; is decomposing the update across banks
stz :rtbl_idx ; Start copying from the first entry in the table stz :rtbl_idx_x2 ; Start copying from the first entry in the table
lda StartY ; This is the base line of the virtual screen lda StartY ; This is the base line of the virtual screen
jsr Mod208 jsr Mod208
sta StartYMod208 sta StartYMod208
sta :virt_line ; Keep track of it asl
sta :virt_line_x2 ; Keep track of it
phb ; Save the current bank
tsc ; we intentionally leak one byte of stack in each loop
sta :stk_save ; iteration, so save the stack to repair at the end
; copy a range of address from the table into the destination bank. If we restrict ourselves to ; copy a range of address from the table into the destination bank. If we restrict ourselves to
; rectangular playfields, this can be optimized to just subtracting a constant value. See the ; rectangular playfields, this can be optimized to just subtracting a constant value. See the
; Templates::SetScreenAddrs subroutine. ; Templates::SetScreenAddrs subroutine.
lda ScreenHeight lda ScreenHeight
sta :lines_left asl
sta :lines_left_x2
; This is the verbose part -- figure out how many lines to draw. We don't want to artificially limit ; This is the verbose part -- figure out how many lines to draw. We don't want to artificially limit
; the height of the visible screen (for example, doing an animated wipe while scrolling), so the screen ; the height of the visible screen (for example, doing an animated wipe while scrolling), so the screen
@ -38,62 +45,46 @@ _ApplyBG0YPos
; For larger values, we want to break things up on 16-line boundaries based on the virt_line value. So, ; For larger values, we want to break things up on 16-line boundaries based on the virt_line value. So,
; ;
; draw_count = min(lines_left, (16 - (virt_line % 16)) ; draw_count = min(lines_left, (16 - (virt_line % 16))
;
; Note that almost everything in this loop can be done with 8-bit operations sincc the values are
; all under 200. The one exception is the virt_line value which could exceed 256. This will be
; a later optimization and might save around 10 cycles per iteration, or up to ~120 cycles per frame
; and ~2,500 per secord. This is ~1% of our total CPU budget and is *just* enough cycles to be
; interesting.... Another 8 cycles could be removed by doing all calculatinos pre-multiplied by 2
; to avoid several 'asl' instructions
phb
:loop :loop
lda :virt_line ldx :virt_line_x2
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 tay
sep #$20 ldal BTableHigh,x ; Target bank in low byte, current bank in high
ldal BTableHigh,x
pha pha
plb ; This is the bank that will receive the updates
rep #$20
lda :virt_line txa
and #$000F and #$001E
eor #$FFFF eor #$FFFF
inc sec
clc adc #32
adc #16 min :lines_left_x2
min :lines_left
sta :draw_count ; Do this many lines sta :draw_count_x2 ; Do this many lines
asl
tax tax
lda :rtbl_idx ; Read from this location in the RTable clc ; pre-advance virt_line_2 because we have the value
asl adc :virt_line_x2
sta :virt_line_x2
jsr CopyRTableToStkAddr plb
CopyRTableToStkAddr :rtbl_idx_x2 ; X = rtbl_idx_x2 on return
lda :virt_line ; advance to the virtual line after the segment we just txa ; carry flag is unchanged
clc ; filled in adc :draw_count_x2 ; advance the index into the RTable
adc :draw_count sta :rtbl_idx_x2
sta :virt_line
lda :rtbl_idx ; advance the index into the RTable lda :lines_left_x2 ; subtract the number of lines we just completed
adc :draw_count
sta :rtbl_idx
lda :lines_left ; subtract the number of lines we just completed
sec sec
sbc :draw_count sbc :draw_count_x2
sta :lines_left sta :lines_left_x2
jne :loop jne :loop
plb
:out lda :stk_save
tcs
plb
rts rts
; Unrolled copy routine to move RTable intries into STK_ADDR position. ; Unrolled copy routine to move RTable intries into STK_ADDR position.
@ -101,74 +92,75 @@ _ApplyBG0YPos
; A = intect into the RTable array (x2) ; A = intect into the RTable array (x2)
; Y = starting line * $1000 ; Y = starting line * $1000
; X = number of lines (x2) ; X = number of lines (x2)
CopyRTableToStkAddr CopyRTableToStkAddr mac
jmp (:tbl,x) jmp (dispTbl,x)
:tbl da :none dispTbl da bottom
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 ldx ]1
bra :x15 bra x15
:do14 tax do14 ldx ]1
bra :x14 bra x14
:do13 tax do13 ldx ]1
bra :x13 bra x13
:do12 tax do12 ldx ]1
bra :x12 bra x12
:do11 tax do11 ldx ]1
bra :x11 bra x11
:do10 tax do10 ldx ]1
bra :x10 bra x10
:do09 tax do09 ldx ]1
bra :x09 bra x09
:do08 tax do08 ldx ]1
bra :x08 bra x08
:do07 tax do07 ldx ]1
bra :x07 bra x07
:do06 tax do06 ldx ]1
bra :x06 bra x06
:do05 tax do05 ldx ]1
bra :x05 bra x05
:do04 tax do04 ldx ]1
bra :x04 bra x04
:do03 tax do03 ldx ]1
bra :x03 bra x03
:do02 tax do02 ldx ]1
bra :x02 bra x02
:do01 tax do01 ldx ]1
bra :x01 bra x01
:do16 tax do16 ldx ]1
ldal RTable+30,x ldal RTable+30,x
sta STK_ADDR+$F000,y sta STK_ADDR+$F000,y
:x15 ldal RTable+28,x x15 ldal RTable+28,x
sta STK_ADDR+$E000,y sta STK_ADDR+$E000,y
:x14 ldal RTable+26,x x14 ldal RTable+26,x
sta STK_ADDR+$D000,y sta STK_ADDR+$D000,y
:x13 ldal RTable+24,x x13 ldal RTable+24,x
sta STK_ADDR+$C000,y sta STK_ADDR+$C000,y
:x12 ldal RTable+22,x x12 ldal RTable+22,x
sta STK_ADDR+$B000,y sta STK_ADDR+$B000,y
:x11 ldal RTable+20,x x11 ldal RTable+20,x
sta STK_ADDR+$A000,y sta STK_ADDR+$A000,y
:x10 ldal RTable+18,x x10 ldal RTable+18,x
sta STK_ADDR+$9000,y sta STK_ADDR+$9000,y
:x09 ldal RTable+16,x x09 ldal RTable+16,x
sta STK_ADDR+$8000,y sta STK_ADDR+$8000,y
:x08 ldal RTable+14,x x08 ldal RTable+14,x
sta STK_ADDR+$7000,y sta STK_ADDR+$7000,y
:x07 ldal RTable+12,x x07 ldal RTable+12,x
sta STK_ADDR+$6000,y sta STK_ADDR+$6000,y
:x06 ldal RTable+10,x x06 ldal RTable+10,x
sta STK_ADDR+$5000,y sta STK_ADDR+$5000,y
:x05 ldal RTable+08,x x05 ldal RTable+08,x
sta STK_ADDR+$4000,y sta STK_ADDR+$4000,y
:x04 ldal RTable+06,x x04 ldal RTable+06,x
sta STK_ADDR+$3000,y sta STK_ADDR+$3000,y
:x03 ldal RTable+04,x x03 ldal RTable+04,x
sta STK_ADDR+$2000,y sta STK_ADDR+$2000,y
:x02 ldal RTable+02,x x02 ldal RTable+02,x
sta STK_ADDR+$1000,y sta STK_ADDR+$1000,y
:x01 ldal RTable+00,x x01 ldal RTable+00,x
sta: STK_ADDR+$0000,y sta: STK_ADDR+$0000,y
:none rts bottom
<<<