WIP on BG0X positioning; fix tile horizonal calculation

This commit is contained in:
Lucas Scharenbroich 2021-07-15 11:01:42 -05:00
parent be446589b0
commit 50f5da5608
6 changed files with 184 additions and 49 deletions

View File

@ -42,7 +42,7 @@ SHR_PALETTES equ $E19E00
tiledata ext
; Feature flags
NO_INTERRUPTS equ 0 ; turn off for crossrunner debugging
NO_INTERRUPTS equ 1 ; turn off for crossrunner debugging
; Typical init
@ -289,6 +289,8 @@ DoTiles
:rowloop
lda #0
sta :column,s
lda #$0010
sta :tile,s
:colloop
lda :row,s
@ -300,7 +302,6 @@ DoTiles
lda :tile,s
inc
and #$000F
sta :tile,s
lda :column,s
@ -322,6 +323,8 @@ DoTiles
; Set up the code field and render it
DoFrame
lda #$FFFF
sta DirtyBits
jsr Render ; Render the play field
rts
@ -737,6 +740,10 @@ qtRec adrl $0000

View File

@ -1,7 +1,40 @@
REL
DSK TILESEG
tiledata ENT
ds 65536
hex 0000F000
hex 000FF000
hex 0000F000
hex 0000F000
hex 0000F000
hex 0000F000
hex 000FFF00
hex 00000000
hex 000FF000
hex 00F00F00
hex 00000F00
hex 0000F000
hex 000F0000
hex 00F00000
hex 00FFFF00
hex 00000000
hex 000FF000
hex 00F00F00
hex 00000F00
hex 0000F000
hex 00000F00
hex 00F00F00
hex 000FF000
hex 00000000
tileend

View File

@ -109,6 +109,24 @@ _RestoreBG0Opcodes
; routine. The reason is that the restore *must* be applied using the (StartX, StartY)
; values from the previous frame, which requires logic that is not relevant to setting
; up the code field.
;
; This function is where the reverse-mapping aspect of the code field is compensated
; for. In the initialize case where X = 0, the exit point is at the *end* of
; the code buffer line
;
; +----+----+ ... +----+----+----+
; | 82 | 80 | | 04 | 02 | 00 |
; +----+----+ ... +----+----+----+
; ^ x=0
;
; As the screen scrolls right-to-left, the exit position moves to earlier memory
; locations until wrapping around from 163 to 0.
;
; The net calculation are
;
; x_exit = (164 - x) % 164
; x_enter = (164 - x - width) % 164
;
_ApplyBG0XPos
:virt_line equ tmp1
@ -168,31 +186,39 @@ _ApplyBG0XPos
; tile position is rounded down.
lda StartX ; This is the starting byte offset (0 - 163)
inc ; round up to calculate the entry column
and #$FFFE
jsr Mod164 ;
pha ; Save for a bit
lda #164 ; The left edge of the screen is the exit point
sec ; of the blitter. So calculate that location for
sbc 1,s ; the "starting" point of the render
tay ; cache this value
cmp #164
bcc :nomod1
lda #0 ; range check
:nomod1 and #$FFFE ; clamp and load the BRA for this column
tax
lda CodeFieldOddBRA,x
sta :exit_bra
lda Col2CodeOffset,X
sta :exit_offset
tya ; reload (164 - x) % 164
sec
sbc ScreenWidth ; back up to entry point, which corresponds to the
bpl :nomod2 ; right edge
clc
adc #184
:nomod2 inc ; round up to calculate the entry column
cmp #184
bcc :nomod3
lda #0
:nomod3 and #$FFFE
tax
lda Col2CodeOffset,X ; This is an offset from the base page boundary
sta :entry_offset
lda StartX ; Repeat with adding the screen width
clc ; to calculate the exit column
adc ScreenWidth
bit #$0001 ; Check if odd or even
bne :isOdd
and #$FFFE
tax
lda CodeFieldEvenBRA,x
sta :exit_bra
bra :wasEven
:isOdd
and #$FFFE
tax
lda CodeFieldOddBRA,x
sta :exit_bra
:wasEven
lda Col2CodeOffset,X
sta :exit_offset
pla ; Pop off the saved value
; Main loop that
;
@ -520,6 +546,21 @@ SetCodeEntry

View File

@ -13,9 +13,6 @@
; lda #DATA
; ldx Col2CodeOffset,y
; sta $0001,x
;
; This table is necessary, because due to the data being drawn via stack instructions, the
; tile order is reversed.
PER_TILE_SIZE equ 3
]step equ 0
@ -221,3 +218,4 @@ BTableLow ds 208*2*2

View File

@ -313,6 +313,46 @@ SetYPos sta StartY ; Save the position
plb
rts
; Special subroutine to divide the accumulator by 164 and return remainder in the Accumulator
;
; 164 = $A4 = 1010_0100
Mod164 cmp #%1010010000000000
bcc *+5
sbc #%1010010000000000
cmp #%0101001000000000
bcc *+5
sbc #%0101001000000000
cmp #%0010100100000000
bcc *+5
sbc #%0010100100000000
cmp #%0001010010000000
bcc *+5
sbc #%0001010010000000
cmp #%0000101001000000
bcc *+5
sbc #%0000101001000000
cmp #%0000010100100000
bcc *+5
sbc #%0000010100100000
cmp #%0000001010010000
bcc *+5
sbc #%0000001010010000
cmp #%0000000101001000
bcc *+5
sbc #%0000000101001000
cmp #%0000000010100100
bcc *+5
sbc #%0000000010100100
rts
; Special subroutine to divide the accumulator by 208 and return remainder in the Accumulator
;
; 208 = $D0 = 1101_0000
@ -930,6 +970,9 @@ top

View File

@ -13,8 +13,8 @@
; A low-level function that copies 8x8 tiles directly into the code field space.
;
; A = Tile ID (0 - 1023)
; X = Tile row (0 - 25)
; Y = Tile columns (0 - 40)
; X = Tile column (0 - 40)
; Y = Tile row (0 - 25)
CopyTile
phb ; save the current bank
pha ; save the tile ID
@ -31,8 +31,13 @@ CopyTile
pha ; save for a few instruction
rep #$20
txa ; there are two columns per tile, so multiple by 4
asl
phx ; Reverse the tile index since x = 0 is at the end
lda #40
sec
sbc 1,s
plx
asl ; there are two columns per tile, so multiple by 4
asl ; asl will clear the carry bit
tax
lda Col2CodeOffset,x
@ -88,45 +93,48 @@ CopyTileConst sta: $0000,y
sta $7003,y
rts
:CopyTileMem asl
:CopyTileMem sec
sbc #$0010
asl
asl
asl
asl
asl
tax
CopyTileLinear ldal tiledata+0,x
sta: $0000,y
ldal tiledata+2,x
CopyTileLinear ldal tiledata+0,x ; The low word goes in the *next* instruction
sta: $0003,y
ldal tiledata+2,x
sta: $0000,y
ldal tiledata+4,x
sta $1000,y
ldal tiledata+6,x
sta $1003,y
ldal tiledata+6,x
sta $1000,y
ldal tiledata+8,x
sta $2000,y
ldal tiledata+10,x
sta $2003,y
ldal tiledata+10,x
sta $2000,y
ldal tiledata+12,x
sta $3000,y
ldal tiledata+14,x
sta $3003,y
ldal tiledata+14,x
sta $3000,y
ldal tiledata+16,x
sta $4000,y
ldal tiledata+18,x
sta $4003,y
ldal tiledata+18,x
sta $4000,y
ldal tiledata+20,x
sta $5000,y
ldal tiledata+22,x
sta $5003,y
ldal tiledata+22,x
sta $5000,y
ldal tiledata+24,x
sta $6000,y
ldal tiledata+26,x
sta $6003,y
ldal tiledata+26,x
sta $6000,y
ldal tiledata+28,x
sta $7000,y
ldal tiledata+30,x
sta $7003,y
ldal tiledata+30,x
sta $7000,y
rts
@ -143,6 +151,11 @@ CopyTileLinear ldal tiledata+0,x