Initial addition of BG1 support

This commit is contained in:
Lucas Scharenbroich 2021-07-16 00:34:58 -05:00
parent 63bfe5e8e7
commit abfcde54c2
9 changed files with 357 additions and 31 deletions

View File

@ -49,8 +49,11 @@ MemInit PushLong #0 ; space for result
plx ; base address of the new handle
pla ; high address 00XX of the new handle (bank)
_Deref
stx ZeroPage
sta ZeroPage+2
stx BlitterDP
; Allocate a bank of memory for BG1
jsr AllocOneBank2
sta BG1DataBank
; Allocate the 13 banks of memory we need and store in double-length array
]step equ 0
@ -101,7 +104,6 @@ MemInit PushLong #0 ; space for result
Buff00 ds 4
Buff01 ds 4
ZeroPage ds 4
; Bank allocator (for one full, fixed bank of memory. Can be immediately deferenced)
@ -189,6 +191,11 @@ ShutDown rts

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
@ -100,6 +100,8 @@ NO_INTERRUPTS equ 1 ; turn off for crossrunner
lda #0 ; Set the virtual X-position
jsr SetBG0XPos
jsr _InitBG1 ; Initialize the second background
; Load a picture and copy it into Bank $E1. Then turn on the screen.
jsr AllocOneBank ; Alloc 64KB for Load/Unpack
@ -176,7 +178,14 @@ EvtLoop
jsr Demo
brl EvtLoop
:12 brl EvtLoop
:12 cmp #'c'
bne :13
ldx #$00E1
lda #$2000
jsr CopyPicToField
brl EvtLoop
:13 brl EvtLoop
; Exit code
Exit
@ -329,22 +338,99 @@ DoFrame
rts
; Load a simple picture format onto the SHR screen
DoLoadPic
lda BankLoad
ldx #ImageName ; Load+Unpack Boot Picture
jsr LoadPicture ; X=Name, A=Bank to use for loading
lda BankLoad ; get address of loaded/uncompressed picture
lda BankLoad ; Copy it into the code field
clc
adc #$0080 ; skip header?
sta :copySHR+2 ; and store that over the 'ldal' address below
ldx #$7FFE ; copy all image data
:copySHR ldal $000000,x ; load from BankLoad we allocated
stal SHR_SCREEN,x ; store to SHR screen
adc #$0080
xba
pha
and #$00FF
tax
pla
and #$FF00
jsr CopyPicToField
rts
; Copy a loaded SHR picture into the code field
;
; A=low word of picture address
; X=high workd of pixture address
;
; Picture must be within one bank
CopyPicToField
:srcptr equ tmp0
:line_cnt equ tmp2
:dstptr equ tmp3
:col_cnt equ tmp5
sta :srcptr
stx :srcptr+2
stz :line_cnt
:rloop
lda :line_cnt ; get the pointer to the code field line
asl
tax
lda BTableLow,x
sta :dstptr
lda BTableHigh,x
sta :dstptr+2
ldx #162 ; move backwards in the code field
ldy #0 ; move forward in the image data
lda #80 ; keep a running column count
sta :col_cnt
:cloop
phy
lda [:srcptr],y
ldy Col2CodeOffset,x ; Get the offset to the code from the line start
cmp #0 ; Empty values are transparent
beq :transparent
pha
lda #$00F4 ; PEA instruction
sta [:dstptr],y
iny
pla
sta [:dstptr],y
bra :next
:transparent
lda #$B1 ; LDA (dp),y
sta [:dstptr],y
iny
lda 1,s ; load the saved Y-index
ora #$4800 ; put a PHA after the offset
sta [:dstptr],y
:next
ply
dex
dex
bpl :copySHR
iny
iny
dec :col_cnt
bne :cloop
lda :srcptr
clc
adc #160
sta :srcptr
inc :line_cnt
lda :line_cnt
cmp #200
bcc :rloop
rts
****************************************
@ -667,3 +753,12 @@ qtRec adrl $0000
put blitter/Template.s
put blitter/Tiles.s
put blitter/Vert.s
put blitter/BG1.s

View File

@ -66,6 +66,7 @@ Render
jsr _ApplyBG0XPos ; Patch the PEA instructions with exit BRA opcode
jsr _ApplyBG0YPos ; Set stack addresses for the virtual lines to the physical screen
jsr _ApplyBG1XPos ; Adjust the direct page pointers to the BG1 bank
ldx #0 ; Blit the full virtual buffer to the screen
ldy ScreenHeight
@ -86,3 +87,4 @@ Render

204
src/blitter/BG1.s Normal file
View File

@ -0,0 +1,204 @@
; Initialization and setup routines for the second background
_InitBG1
jsr _ApplyBG1XPos
jsr _ApplyBG1YPos
rts
; Everytime either BG1 or BG0 X-position changes, we have to update the direct page values. We
; *could* do this by adjusting the since address offset, but we have to change up to 200 values
; when the vertical position changes, and only 41 when the horizontal value changes. Plus
; these are all direct page values
;
; Note: This routine can be optimized as an unrolled loop of PEI instructions
_ApplyBG1XPos
lda #162
sec
sbc StartXMod164
bpl *+6
clc
adc #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
tcd
tya
ldx #162
:loop
sta 00,x ; store the value
dec
dec
bpl *+6
clc
adc #164
dex
dex
bpl :loop
pld
rts
; 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)
_ApplyBG1YPos
:virt_line equ tmp0
:lines_left equ tmp1
:draw_count equ tmp2
:ytbl_idx equ tmp3
stz :rtbl_idx ; Start copying from the first entry in the table
lda StartY ; This is the base line of the virtual screen
sta :virt_line ; Keep track of it
lda ScreenHeight
sta :lines_left
:loop
lda :virt_line
asl
tax
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
rep #$20
lda :virt_line
and #$000F
eor #$FFFF
inc
clc
adc #16
min :lines_left
sta :draw_count ; Do this many lines
asl
tax
lda :ytbl_idx ; Read from this location in the BG1YTable
asl
jsr CopyBG1YTableToBG1Addr
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
adc :draw_count
sta :ytbl_idx
lda :lines_left ; subtract the number of lines we just completed
sec
sbc :draw_count
sta :lines_left
jne :loop
phk
plb
rts
; Unrolled copy routine to move BG1YTable entries into BG1_ADDR position.
;
; A = intect into the BG1YTable array (x2)
; Y = starting line * $1000
; X = number of lines (x2)
CopyBG1YTableToBG1Addr
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
: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
:do16 tax
ldal BG1YTable+30,x
sta BG1_ADDR+$F000,y
:x15 ldal BG1YTable+28,x
sta BG1_ADDR+$E000,y
:x14 ldal BG1YTable+26,x
sta BG1_ADDR+$D000,y
:x13 ldal BG1YTable+24,x
sta BG1_ADDR+$C000,y
:x12 ldal BG1YTable+22,x
sta BG1_ADDR+$B000,y
:x11 ldal BG1YTable+20,x
sta BG1_ADDR+$A000,y
:x10 ldal BG1YTable+18,x
sta BG1_ADDR+$9000,y
:x09 ldal BG1YTable+16,x
sta BG1_ADDR+$8000,y
:x08 ldal BG1YTable+14,x
sta BG1_ADDR+$7000,y
:x07 ldal BG1YTable+12,x
sta BG1_ADDR+$6000,y
:x06 ldal BG1YTable+10,x
sta BG1_ADDR+$5000,y
:x05 ldal BG1YTable+08,x
sta: BG1_ADDR+$4000,y
:x04 ldal BG1YTable+06,x
sta BG1_ADDR+$3000,y
:x03 ldal BG1YTable+04,x
sta BG1_ADDR+$2000,y
:x02 ldal BG1YTable+02,x
sta BG1_ADDR+$1000,y
:x01 ldal BG1YTable+00,x
sta: BG1_ADDR+$0000,y
:none rts

View File

@ -15,12 +15,13 @@ EngineMode equ 20 ; Defined the mode/capabilities that are ena
DirtyBits equ 22 ; Identify values that have changed between frames
BG1DataBank equ 24 ; Data bank that holds BG1 layer data
BlitterDP equ 25 ; Direct page address the holder blitter data
BlitterDP equ 26 ; Direct page address the holder blitter data
OldStartX equ 26
OldStartY equ 28
OldStartX equ 28
OldStartY equ 30
LastPatchOffset equ 30 ; Offset into code field that was patched with BRA instructions
LastPatchOffset equ 32 ; Offset into code field that was patched with BRA instructions
StartXMod164 equ 34
bstk equ 208 ; 16-byte stack to push bank addresses
@ -56,3 +57,5 @@ DIRTY_BIT_BG1_Y equ $0008

View File

@ -192,7 +192,7 @@ _ApplyBG0XPos
lda StartX ; This is the starting byte offset (0 - 163)
jsr Mod164 ;
pha ; Save for a bit
sta StartXMod164
; Now, the left edge of the screen is pushed last, so we need to exit one instruction *after*
; the location (163 - StartX % 164)
@ -218,7 +218,7 @@ _ApplyBG0XPos
lda #163
sec
sbc 1,s
sbc StartXMod164
tay
; Right now we have the offset of the last visible byte. Add one to get the offset
@ -243,7 +243,7 @@ _ApplyBG0XPos
tax
lda CodeFieldEvenBRA,x
sta :exit_bra
lda Col2CodeOffset,X
lda Col2CodeOffset,x
sta :exit_offset
sta LastPatchOffset ; Cache as a flag for later
bra :do_entry
@ -294,7 +294,6 @@ _ApplyBG0XPos
lda #$00AF ; set the entry_jmp opcode to LDAL
sta :opcode
:prep_complete
pla ; Pop off the saved value
; Main loop that
;
@ -742,3 +741,7 @@ SetCodeEntryOpcode
sta CODE_ENTRY_OPCODE+$1000,y
sta: CODE_ENTRY_OPCODE+$0000,y
:bottom rts

View File

@ -215,3 +215,19 @@ BlitBuff ds 4*13
; that everything can use the same indexing offsets
BTableHigh ds 208*2*2
BTableLow ds 208*2*2
; A double-length table of addresses for the BG1 bank. The BG1 buffer is 208 rows of 256 bytes each and
; the first row starts 256 bytes in to give enough room for scroll adjustments
]step equ 256
BG1YTable lup 208
dw ]step
]step = ]step+256
--^
]step equ 256
lup 208
dw ]step
]step = ]step+256
--^

View File

@ -695,13 +695,13 @@ BuildBank
plb
plb
lda #$F000+{ONE_LYR_ENTRY} ; Set the address from each line to the next
lda #$F000+{TWO_LYR_ENTRY} ; Set the address from each line to the next
ldy #CODE_EXIT+1
ldx #15*2
jsr SetAbsAddrs
ldy #$F000+CODE_EXIT ; Patch the last line with a JML to go to the next bank
lda #{$005C+{ONE_LYR_ENTRY}*256}
lda #{$005C+{TWO_LYR_ENTRY}*256}
sta [target],y
ldy #$F000+CODE_EXIT+2
lda nextBank
@ -938,3 +938,7 @@ epilogue_1 tsc
; snippets ds 32*82
top

View File

@ -188,11 +188,3 @@ CopyRTableToStkAddr
sta: STK_ADDR+$0000,y
:none rts