mirror of
https://github.com/lscharen/iigs-game-engine.git
synced 2025-02-19 13:30:30 +00:00
Add all minimal function in place; not onto debugging
This commit is contained in:
parent
5d713caf5c
commit
469e8bb74a
145
src/App.Main.s
145
src/App.Main.s
@ -126,7 +126,11 @@ EvtLoop
|
||||
tax
|
||||
jsr SetScreenMode
|
||||
|
||||
:6 bra EvtLoop
|
||||
:6 cmp #'t'
|
||||
bne :7
|
||||
jsr DoTiles
|
||||
|
||||
:7 bra EvtLoop
|
||||
|
||||
; Exit code
|
||||
Exit
|
||||
@ -222,37 +226,25 @@ DoHUP
|
||||
jsr DrawWord
|
||||
rts
|
||||
|
||||
|
||||
; Set up the code field and render it
|
||||
DoFrame
|
||||
|
||||
; Render some tiles
|
||||
:bank equ 1
|
||||
; Fill up the virtual buffer with tile data
|
||||
DoTiles
|
||||
:row equ 1
|
||||
:column equ 3
|
||||
:tile equ 5
|
||||
|
||||
|
||||
pea $0000 ; Allocate local variable space
|
||||
pea $0000
|
||||
pea $0000
|
||||
|
||||
:bankloop
|
||||
lda :bank,s
|
||||
tax
|
||||
ldal BlitBuff+1,x ; set the data bank to the code field
|
||||
pha
|
||||
plb
|
||||
plb
|
||||
|
||||
:rowloop
|
||||
lda #0
|
||||
sta :column,s
|
||||
|
||||
:tileloop
|
||||
:colloop
|
||||
lda :row,s
|
||||
tay
|
||||
lda :column,s
|
||||
tax
|
||||
ldal Col2CodeOffset,x
|
||||
tay
|
||||
iny
|
||||
lda :tile,s
|
||||
jsr CopyTile
|
||||
|
||||
@ -262,36 +254,24 @@ DoFrame
|
||||
sta :tile,s
|
||||
|
||||
lda :column,s
|
||||
clc
|
||||
adc #4
|
||||
inc
|
||||
sta :column,s
|
||||
cmp #4*40
|
||||
bcc :tileloop
|
||||
cmp #40
|
||||
bcc :colloop
|
||||
|
||||
lda :bank,s
|
||||
clc
|
||||
adc #4
|
||||
sta :bank,s
|
||||
cmp #4*13
|
||||
bcc :bankloop
|
||||
lda :row,s
|
||||
inc
|
||||
sta :row,s
|
||||
cmp #25
|
||||
bcc :rowloop
|
||||
|
||||
phk
|
||||
plb
|
||||
|
||||
; This sets up the environment for calling the blitter. The blitter code takes care of moving from
|
||||
; line to line and should be set up ahead of time with appropriate epilogues for lines to periodically
|
||||
; enable interrupts and other stuff. In short, we call into the code once and, when it returns, all of
|
||||
; the lines set up to render will be finished.
|
||||
|
||||
sep #$20 ; 8-bit acc
|
||||
lda BlitBuff+2 ; set the data bank to the code field
|
||||
sta blt_entry+3 ; Patch into the long jump
|
||||
pha
|
||||
pha ; push twice because we will use it later
|
||||
rep #$20
|
||||
|
||||
; Set the Y-Position within the virtual buffer
|
||||
pla ; restore the stack
|
||||
pla
|
||||
pla
|
||||
rts
|
||||
|
||||
; Set up the code field and render it
|
||||
DoFrame
|
||||
lda #0 ; Set the virtual Y-position
|
||||
jsr SetBG0YPos
|
||||
|
||||
@ -299,65 +279,10 @@ DoFrame
|
||||
jsr SetBG0XPos
|
||||
|
||||
jsr Render ; Render the play field
|
||||
|
||||
rts
|
||||
|
||||
; Just load the screen width here. This is not semantically right; we actually are taking the nummber
|
||||
; of tiles in the width of the playfield, multiplying by two to get the number of words and then
|
||||
; multiplying by two again to get an index offset. It just happens that TILES * 4 = BYTES.
|
||||
;
|
||||
; TODO: Once we start scrolling, this will be ScreenWidth + BG0_X
|
||||
|
||||
ldx ScreenWidth ; This is the word to exit from
|
||||
ldy Col2CodeOffset,x ; Get the offset
|
||||
|
||||
sep #$20 ; 8-bit acc
|
||||
lda BlitBuff+2 ; set the data bank to the code field
|
||||
sta blt_entry+3 ; Patch into the long jump
|
||||
rep #$20
|
||||
|
||||
plb ; set the data bank to the code field
|
||||
|
||||
ldx #16*2 ; Y-register is set correctly
|
||||
lda #OPCODE_SAVE
|
||||
jsr SaveOpcode
|
||||
|
||||
ldx ScreenWidth ; X-register is overwritten by SaveOpcode
|
||||
ldal CodeFieldEvenBRA,x ; Get the value to place there
|
||||
ldx #16*2
|
||||
jsr SetConst
|
||||
|
||||
|
||||
; Fill in the screen address of each line. This routine must be called whenever the
|
||||
; lda #{$2000+159+15*160} ; Set the stack address to the right edge of the screen
|
||||
; ldy #0
|
||||
; ldx #16*2
|
||||
; jsr SetScreenAddrs
|
||||
|
||||
sep #$20 ; only need to do an 8-bit store
|
||||
lda #$06 ; This is the entry address to start drawing
|
||||
ldy #CODE_ENTRY ; don't actually need to set these again
|
||||
ldx #16*2
|
||||
jsr SetConst
|
||||
rep #$30
|
||||
|
||||
; ldy #$7000 ; Set the return after line 200 (Bank 13, line 8)
|
||||
; jsr SetReturn
|
||||
|
||||
plb ; set the bank back to the code field
|
||||
ldx ScreenWidth ; This is the word to exit from
|
||||
ldal Col2CodeOffset,x ; Get the offset
|
||||
tay
|
||||
ldx #16*2
|
||||
lda #OPCODE_SAVE
|
||||
; jsr RestoreOpcode
|
||||
|
||||
phk ; restore data bank
|
||||
plb
|
||||
|
||||
pla ; restore the stack
|
||||
pla
|
||||
pla
|
||||
rts
|
||||
; Load a simple picture format onto the SHR screen
|
||||
|
||||
DoLoadPic
|
||||
lda BankLoad
|
||||
@ -370,7 +295,7 @@ DoLoadPic
|
||||
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 $E12000,x ; store to SHR screen
|
||||
stal SHR_SCREEN,x ; store to SHR screen
|
||||
dex
|
||||
dex
|
||||
bpl :copySHR
|
||||
@ -687,6 +612,18 @@ qtRec adrl $0000
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
29
src/Render.s
29
src/Render.s
@ -54,6 +54,35 @@
|
||||
; and internal data structure to properly render the play field. Then the update pipeline is
|
||||
; executed.
|
||||
Render
|
||||
|
||||
; TODO -- actually check the dirty bits and be selective on what gets updated. For example, if
|
||||
; only the Y position changes, then we should only need to set new values on the
|
||||
; virtual lines that were brought on screen. If the X position only changes by one
|
||||
; byte, then we may have to change the CODE_ENTRY values or restore/set new OPCODE
|
||||
; values, but not both.
|
||||
|
||||
jsr ShadowOff
|
||||
jsr ShadowOn
|
||||
|
||||
jsr _ApplyBG0XPos ; Patch the PEA instructions with exit BRA opcode
|
||||
jsr _ApplyBG0YPos ; Set stack addresses for the virtual lines to the physical screen
|
||||
|
||||
ldx #0 ; Blit the full virtual buffer to the screen
|
||||
ldy ScreenHeight
|
||||
jsr _BltRange
|
||||
|
||||
lda StartY ; Restore the fields back to their original state
|
||||
ldx ScreenHeight
|
||||
jsr _RestoreBG0Opcodes
|
||||
|
||||
rts
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -3,36 +3,39 @@
|
||||
; data in the code fields is set up properly.
|
||||
;
|
||||
; X = first line (inclusive), valid range of 0 to 199
|
||||
; Y = last line (inclusive), valid range >X up to 199
|
||||
; Y = last line (exclusive), valid range >X up to 200
|
||||
;
|
||||
; The lines are based on the appearance of lines in the play field, so blitting lines 0 through
|
||||
; 19 will draw the first 20 lines on the play field, regardless of where the playfield is physically
|
||||
; on the SHR screen or the current value of StartY
|
||||
exit_ptr equ tmp0
|
||||
jmp_low_save equ tmp2
|
||||
BltRange
|
||||
clc`
|
||||
_BltRange
|
||||
|
||||
tya ; Get the address of the line that we want to return from
|
||||
adc StartY ; and create a pointer to it
|
||||
asl
|
||||
tay
|
||||
lda BTableLow,y
|
||||
sta exit_ptr
|
||||
lda BTableHigh,y
|
||||
sta exit_ptr+2
|
||||
:exit_ptr equ tmp0
|
||||
:jmp_low_save equ tmp2
|
||||
|
||||
txa ; get the first line (0 - 199)
|
||||
adc StartY ; add in the virtual offset (0, 207) -- max value of 406
|
||||
asl
|
||||
tax ; this is the offset into the blitter table
|
||||
clc`
|
||||
|
||||
sep #$20 ; 8-bit Acc
|
||||
lda BTableHigh,x ; patch in the bank
|
||||
sta blt_entry+3
|
||||
dey
|
||||
tya ; Get the address of the line that we want to return from
|
||||
adc StartY ; and create a pointer to it
|
||||
asl
|
||||
tay
|
||||
lda BTableLow,y
|
||||
sta :exit_ptr
|
||||
lda BTableHigh,y
|
||||
sta :exit_ptr+2
|
||||
|
||||
lda BTableLow+1,x ; patch in the page
|
||||
sta blt_entry+2
|
||||
txa ; get the first line (0 - 199)
|
||||
adc StartY ; add in the virtual offset (0, 207) -- max value of 406
|
||||
asl
|
||||
tax ; this is the offset into the blitter table
|
||||
|
||||
sep #$20 ; 8-bit Acc
|
||||
lda BTableHigh,x ; patch in the bank
|
||||
sta blt_entry+3
|
||||
|
||||
lda BTableLow+1,x ; patch in the page
|
||||
sta blt_entry+2
|
||||
|
||||
; The way we patch the exit code is subtle, but very fast. The CODE_EXIT offset points to
|
||||
; an JMP/JML instruction that transitions to the next line after all of the code has been
|
||||
@ -41,43 +44,42 @@ BltRange
|
||||
; The trick we use is to patch the low byte to force the code to jump to a special return
|
||||
; function (jml blt_return) in the *next* code field line.
|
||||
|
||||
ldy #CODE_EXIT+1 ; this is a JMP or JML instruction that points to the next line.
|
||||
lda [exit_ptr],y
|
||||
sta jmp_low_save
|
||||
lda #FULL_RETURN ; this is the offset of the return code
|
||||
sta [exit_ptr],y ; patch out the low byte of the JMP/JML
|
||||
ldy #CODE_EXIT+1 ; this is a JMP or JML instruction that points to the next line.
|
||||
lda [:exit_ptr],y
|
||||
sta :jmp_low_save
|
||||
lda #FULL_RETURN ; this is the offset of the return code
|
||||
sta [:exit_ptr],y ; patch out the low byte of the JMP/JML
|
||||
|
||||
; Now we need to set up the Bank, Stack Pointer and Direct Page registers for calling into
|
||||
; the code field
|
||||
|
||||
lda BG1DataBank ; Set the data bank for BG1 data
|
||||
pha
|
||||
plb
|
||||
rep #$20
|
||||
lda BG1DataBank ; Set the data bank for BG1 data
|
||||
pha
|
||||
plb
|
||||
rep #$20
|
||||
|
||||
phd ; Save the application direct page
|
||||
lda BlitterDP ; Set the direct page to the blitter data
|
||||
tcd
|
||||
phd ; Save the application direct page
|
||||
lda BlitterDP ; Set the direct page to the blitter data
|
||||
tcd
|
||||
|
||||
sei ; disable interrupts
|
||||
_R0W1
|
||||
tsc ; save the stack pointer
|
||||
stal stk_save+1
|
||||
sei ; disable interrupts
|
||||
_R0W1
|
||||
tsc ; save the stack pointer
|
||||
stal stk_save+1
|
||||
|
||||
blt_entry jml $000000 ; Jump into the blitter code $XX/YY00
|
||||
blt_entry jml $000000 ; Jump into the blitter code $XX/YY00
|
||||
|
||||
blt_return _R0W0
|
||||
stk_save lda #0000 ; load the stack
|
||||
tcs
|
||||
cli ; re-enable interrupts
|
||||
pld ; restore the direct page
|
||||
blt_return _R0W0
|
||||
stk_save lda #0000 ; load the stack
|
||||
tcs
|
||||
cli ; re-enable interrupts
|
||||
pld ; restore the direct page
|
||||
|
||||
sep #$20
|
||||
ldy #CODE_EXIT+1
|
||||
lda jmp_low_save
|
||||
sta [exit_ptr],y
|
||||
rep #$20
|
||||
|
||||
rts
|
||||
sep #$20
|
||||
ldy #CODE_EXIT+1
|
||||
lda :jmp_low_save
|
||||
sta [:exit_ptr],y
|
||||
rep #$20
|
||||
|
||||
rts
|
||||
|
||||
|
@ -37,6 +37,10 @@ tmp7 equ 254
|
||||
|
||||
DIRTY_BIT_BG0_X equ $0001
|
||||
DIRTY_BIT_BG0_Y equ $0002
|
||||
DIRTY_BIT_BG1_X equ $0004
|
||||
DIRTY_BIT_BG1_Y equ $0008
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -13,18 +13,96 @@
|
||||
;
|
||||
; We assume that there is a clean code field in this routine
|
||||
SetBG0XPos
|
||||
cmp StartX
|
||||
beq :out ; Easy, if nothing changed, then nothing changes
|
||||
cmp StartX
|
||||
beq :out ; Easy, if nothing changed, then nothing changes
|
||||
|
||||
ldx StartX ; Load the old value (but don't save it yet)
|
||||
sta StartX ; Save the new position
|
||||
ldx StartX ; Load the old value (but don't save it yet)
|
||||
sta StartX ; Save the new position
|
||||
|
||||
lda #DIRTY_BIT_BG0_X
|
||||
tsb DirtyBits ; Check if the value is already dirty, if so exit
|
||||
bne :out ; without overwriting the original value
|
||||
lda #DIRTY_BIT_BG0_X
|
||||
tsb DirtyBits ; Check if the value is already dirty, if so exit
|
||||
bne :out ; without overwriting the original value
|
||||
|
||||
stx OldStartX ; First change, so preserve the value
|
||||
:out rts
|
||||
stx OldStartX ; First change, so preserve the value
|
||||
:out rts
|
||||
|
||||
; Simple function that restores the saved opcode that are stached in _applyBG0Xpos. It is
|
||||
; very important that opcodes are restored before new ones are inserted, because there is
|
||||
; only one, fixed storage location and old values will be overwritten if operations are not
|
||||
; performed in order.
|
||||
;
|
||||
; Experimental -- this is a parameterized version that does not rely on direct page
|
||||
; state variabled for input and attempts to be more optimized.
|
||||
;
|
||||
; A = starting virtual line in the code field (0 - 207)
|
||||
; X = number of lines to render (0 - 200)
|
||||
|
||||
_RestoreBG0Opcodes
|
||||
|
||||
:virt_line_x2 equ tmp1
|
||||
:lines_left_x2 equ tmp2
|
||||
:draw_count_x2 equ tmp3
|
||||
:exit_offset equ tmp4
|
||||
|
||||
asl
|
||||
sta :virt_line_x2 ; Keep track of it
|
||||
|
||||
txa
|
||||
asl
|
||||
sta :lines_left_x2
|
||||
|
||||
lda StartX ; Repeat with adding the screen width
|
||||
clc ; to calculate the exit column
|
||||
adc ScreenWidth
|
||||
and #$FFFE
|
||||
tax
|
||||
lda Col2CodeOffset,X
|
||||
sta :exit_offset
|
||||
|
||||
:loop
|
||||
ldx :virt_line_x2
|
||||
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
|
||||
|
||||
txa ; lda :virt_line_x2
|
||||
and #$001E
|
||||
eor #$FFFF
|
||||
inc
|
||||
clc
|
||||
adc #32
|
||||
min :lines_left_x2
|
||||
sta :draw_count_x2 ; Do half of this many lines
|
||||
|
||||
; y is already set to :base_address
|
||||
tax ; :draw_count * 2
|
||||
|
||||
tya
|
||||
clc
|
||||
adc :exit_offset ; Add some offsets to get the base address in the code field line
|
||||
|
||||
jsr 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
|
||||
sec
|
||||
sbc :draw_count_x2
|
||||
sta :lines_left_x2
|
||||
|
||||
jne :loop
|
||||
|
||||
phk
|
||||
plb
|
||||
rts
|
||||
|
||||
; Based on the current value of StartX in the direct page, patch up the code fields
|
||||
; to render the correct data. Note that we do *not* do the OpcodeRestore in this
|
||||
@ -33,23 +111,23 @@ SetBG0XPos
|
||||
; up the code field.
|
||||
_ApplyBG0XPos
|
||||
|
||||
:virt_line equ tmp1
|
||||
:lines_left equ tmp2
|
||||
:draw_count equ tmp3
|
||||
:exit_offset equ tmp4
|
||||
:entry_offset equ tmp5
|
||||
:exit_bra equ tmp6
|
||||
:exit_address equ tmp7
|
||||
:base_address equ tmp8
|
||||
:draw_count_x2 equ tmp9
|
||||
:virt_line equ tmp1
|
||||
:lines_left equ tmp2
|
||||
:draw_count equ tmp3
|
||||
:exit_offset equ tmp4
|
||||
:entry_offset equ tmp5
|
||||
:exit_bra equ tmp6
|
||||
:exit_address equ tmp7
|
||||
:base_address equ tmp8
|
||||
:draw_count_x2 equ tmp9
|
||||
|
||||
; This code is fairly succinct. See the corresponding code in Vert.s for more detailed comments.
|
||||
|
||||
lda StartY ; This is the base line of the virtual screen
|
||||
sta :virt_line ; Keep track of it
|
||||
lda StartY ; This is the base line of the virtual screen
|
||||
sta :virt_line ; Keep track of it
|
||||
|
||||
lda ScreenHeight
|
||||
sta :lines_left
|
||||
lda ScreenHeight
|
||||
sta :lines_left
|
||||
|
||||
; 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.
|
||||
@ -89,32 +167,32 @@ _ApplyBG0XPos
|
||||
; So, in short, the entry tile position is rounded up from the x-position and the exit
|
||||
; 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
|
||||
tax
|
||||
lda Col2CodeOffset,X ; This is an offset from the base page boundary
|
||||
sta :entry_offset
|
||||
lda StartX ; This is the starting byte offset (0 - 163)
|
||||
inc ; round up to calculate the entry column
|
||||
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
|
||||
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
|
||||
and #$FFFE
|
||||
tax
|
||||
lda CodeFieldEvenBRA,x
|
||||
sta :exit_bra
|
||||
bra :wasEven
|
||||
:isOdd
|
||||
and #$FFFE
|
||||
tax
|
||||
lda CodeFieldOddBRA,x
|
||||
sta :exit_bra
|
||||
and #$FFFE
|
||||
tax
|
||||
lda CodeFieldOddBRA,x
|
||||
sta :exit_bra
|
||||
:wasEven
|
||||
lda Col2CodeOffset,X
|
||||
sta :exit_offset
|
||||
lda Col2CodeOffset,X
|
||||
sta :exit_offset
|
||||
|
||||
; Main loop that
|
||||
;
|
||||
@ -123,32 +201,32 @@ _ApplyBG0XPos
|
||||
; 3. Writes the JMP entry point to enter the code field
|
||||
|
||||
:loop
|
||||
lda :virt_line
|
||||
asl ; This will clear the carry bit
|
||||
tax
|
||||
ldal BTableLow,x ; Get the address of the first code field line
|
||||
tay ; Save it to use as the base address
|
||||
adc :exit_offset ; Add some offsets to get the base address in the code field line
|
||||
sta :exit_address
|
||||
sty :base_address
|
||||
lda :virt_line
|
||||
asl ; This will clear the carry bit
|
||||
tax
|
||||
ldal BTableLow,x ; Get the address of the first code field line
|
||||
tay ; Save it to use as the base address
|
||||
adc :exit_offset ; Add some offsets to get the base address in the code field line
|
||||
sta :exit_address
|
||||
sty :base_address
|
||||
|
||||
sep #$20
|
||||
ldal BTableHigh,x
|
||||
pha
|
||||
plb ; This is the bank that will receive the updates
|
||||
rep #$20
|
||||
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
|
||||
lda :virt_line
|
||||
and #$000F
|
||||
eor #$FFFF
|
||||
inc
|
||||
clc
|
||||
adc #16
|
||||
min :lines_left
|
||||
|
||||
sta :draw_count ; Do this many lines
|
||||
asl
|
||||
sta :draw_count_x2
|
||||
sta :draw_count ; Do this many lines
|
||||
asl
|
||||
sta :draw_count_x2
|
||||
|
||||
; First step is to set the BRA instruction to exit the code field at the proper location. There
|
||||
; are two sub-steps to do here; we need to save the 16-bit value that exists at the location and
|
||||
@ -158,44 +236,44 @@ _ApplyBG0XPos
|
||||
; used in odd-aligned cases to determine how to draw the 8-bit value on the left edge of the
|
||||
; screen
|
||||
|
||||
; y is already set to :base_address
|
||||
tax ; :draw_count_x2
|
||||
lda :exit_address ; Save from this location
|
||||
jsr SaveOpcode
|
||||
; y is already set to :base_address
|
||||
tax ; :draw_count_x2
|
||||
lda :exit_address ; Save from this location
|
||||
jsr SaveOpcode
|
||||
|
||||
ldx :draw_count_x2 ; Do this many lines
|
||||
lda :exit_bra ; Copy this value into all of the lines
|
||||
ldy :exit_address ; starting at this address
|
||||
jsr SetConst
|
||||
ldx :draw_count_x2 ; Do this many lines
|
||||
lda :exit_bra ; Copy this value into all of the lines
|
||||
ldy :exit_address ; starting at this address
|
||||
jsr SetConst
|
||||
|
||||
; 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
|
||||
|
||||
sep #$20
|
||||
ldx :draw_count_x2
|
||||
lda :entry_offset
|
||||
ldy :base_address
|
||||
jsr SetCodeEntry
|
||||
rep #$20
|
||||
sep #$20
|
||||
ldx :draw_count_x2
|
||||
lda :entry_offset
|
||||
ldy :base_address
|
||||
jsr SetCodeEntry
|
||||
rep #$20
|
||||
|
||||
; Do the end of the loop -- update the virtual line counter and reduce the number
|
||||
; of lines left to render
|
||||
|
||||
lda :virt_line ; advance to the virtual line after the segment we just
|
||||
clc ; filled in
|
||||
adc :draw_count
|
||||
sta :virt_line
|
||||
lda :virt_line ; advance to the virtual line after the segment we just
|
||||
clc ; filled in
|
||||
adc :draw_count
|
||||
sta :virt_line
|
||||
|
||||
lda :lines_left ; subtract the number of lines we just completed
|
||||
sec
|
||||
sbc :draw_count
|
||||
sta :lines_left
|
||||
lda :lines_left ; subtract the number of lines we just completed
|
||||
sec
|
||||
sbc :draw_count
|
||||
sta :lines_left
|
||||
|
||||
jne :loop
|
||||
jne :loop
|
||||
|
||||
phk
|
||||
plb
|
||||
rts
|
||||
phk
|
||||
plb
|
||||
rts
|
||||
|
||||
; SaveOpcode
|
||||
;
|
||||
@ -206,78 +284,160 @@ _ApplyBG0XPos
|
||||
; Y = starting line * $1000
|
||||
; A = code field location * $1000
|
||||
SaveOpcode
|
||||
jmp (:tbl,x)
|
||||
jmp (:tbl,x)
|
||||
|
||||
:tbl 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
|
||||
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
|
||||
:x16 lda $F000,x
|
||||
sta OPCODE_SAVE+$F000,y
|
||||
:x15 lda $E000,x
|
||||
sta OPCODE_SAVE+$E000,y
|
||||
:x14 lda $D000,x
|
||||
sta OPCODE_SAVE+$D000,y
|
||||
:x13 lda $C000,x
|
||||
sta OPCODE_SAVE+$C000,y
|
||||
:x12 lda $B000,x
|
||||
sta OPCODE_SAVE+$B000,y
|
||||
:x11 lda $A000,x
|
||||
sta OPCODE_SAVE+$A000,y
|
||||
:x10 lda $9000,x
|
||||
sta OPCODE_SAVE+$9000,y
|
||||
:x09 lda $8000,x
|
||||
sta OPCODE_SAVE+$8000,y
|
||||
:x08 lda $7000,x
|
||||
sta OPCODE_SAVE+$7000,y
|
||||
:x07 lda $6000,x
|
||||
sta OPCODE_SAVE+$6000,y
|
||||
:x06 lda $5000,x
|
||||
sta OPCODE_SAVE+$5000,y
|
||||
:x05 lda $4000,x
|
||||
sta OPCODE_SAVE+$4000,y
|
||||
:x04 lda $3000,x
|
||||
sta OPCODE_SAVE+$3000,y
|
||||
:x03 lda $2000,x
|
||||
sta OPCODE_SAVE+$2000,y
|
||||
:x02 lda $1000,x
|
||||
sta OPCODE_SAVE+$1000,y
|
||||
:x01 lda: $0000,x
|
||||
sta: OPCODE_SAVE+$0000,y
|
||||
:bottom rts
|
||||
: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
|
||||
:x16 lda $F000,x
|
||||
sta OPCODE_SAVE+$F000,y
|
||||
:x15 lda $E000,x
|
||||
sta OPCODE_SAVE+$E000,y
|
||||
:x14 lda $D000,x
|
||||
sta OPCODE_SAVE+$D000,y
|
||||
:x13 lda $C000,x
|
||||
sta OPCODE_SAVE+$C000,y
|
||||
:x12 lda $B000,x
|
||||
sta OPCODE_SAVE+$B000,y
|
||||
:x11 lda $A000,x
|
||||
sta OPCODE_SAVE+$A000,y
|
||||
:x10 lda $9000,x
|
||||
sta OPCODE_SAVE+$9000,y
|
||||
:x09 lda $8000,x
|
||||
sta OPCODE_SAVE+$8000,y
|
||||
:x08 lda $7000,x
|
||||
sta OPCODE_SAVE+$7000,y
|
||||
:x07 lda $6000,x
|
||||
sta OPCODE_SAVE+$6000,y
|
||||
:x06 lda $5000,x
|
||||
sta OPCODE_SAVE+$5000,y
|
||||
:x05 lda $4000,x
|
||||
sta OPCODE_SAVE+$4000,y
|
||||
:x04 lda $3000,x
|
||||
sta OPCODE_SAVE+$3000,y
|
||||
:x03 lda $2000,x
|
||||
sta OPCODE_SAVE+$2000,y
|
||||
:x02 lda $1000,x
|
||||
sta OPCODE_SAVE+$1000,y
|
||||
:x01 lda: $0000,x
|
||||
sta: OPCODE_SAVE+$0000,y
|
||||
:bottom rts
|
||||
|
||||
|
||||
; RestoreOpcode
|
||||
;
|
||||
; Restore the values back to the code field.
|
||||
;
|
||||
; X = number of lines * 2, 0 to 32
|
||||
; Y = starting line * $1000
|
||||
; A = code field location * $1000
|
||||
RestoreOpcode
|
||||
jmp (:tbl,x)
|
||||
|
||||
:tbl da :bottom
|
||||
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
|
||||
:x16 lda OPCODE_SAVE+$F000,y
|
||||
sta $F000,x
|
||||
:x15 lda OPCODE_SAVE+$E000,y
|
||||
sta $E000,x
|
||||
:x14 lda OPCODE_SAVE+$D000,y
|
||||
sta $D000,x
|
||||
:x13 lda OPCODE_SAVE+$C000,y
|
||||
sta $C000,x
|
||||
:x12 lda OPCODE_SAVE+$B000,y
|
||||
sta $B000,x
|
||||
:x11 lda OPCODE_SAVE+$A000,y
|
||||
sta $A000,x
|
||||
:x10 lda OPCODE_SAVE+$9000,y
|
||||
sta $9000,x
|
||||
:x09 lda OPCODE_SAVE+$8000,y
|
||||
sta $8000,x
|
||||
:x08 lda OPCODE_SAVE+$7000,y
|
||||
sta $7000,x
|
||||
:x07 lda OPCODE_SAVE+$6000,y
|
||||
sta $6000,x
|
||||
:x06 lda OPCODE_SAVE+$5000,y
|
||||
sta $5000,x
|
||||
:x05 lda OPCODE_SAVE+$4000,y
|
||||
sta $4000,x
|
||||
:x04 lda OPCODE_SAVE+$3000,y
|
||||
sta $3000,x
|
||||
:x03 lda OPCODE_SAVE+$2000,y
|
||||
sta $2000,x
|
||||
:x02 lda OPCODE_SAVE+$1000,y
|
||||
sta $1000,x
|
||||
:x01 lda: OPCODE_SAVE+$0000,y
|
||||
sta: $0000,x
|
||||
:bottom rts
|
||||
|
||||
; SetCodeEntry
|
||||
;
|
||||
@ -287,29 +447,67 @@ SaveOpcode
|
||||
; Y = starting line * $1000
|
||||
; A = address low byte
|
||||
SetCodeEntry
|
||||
jmp (:tbl,x)
|
||||
:tbl da :bottom-00,:bottom-03,:bottom-06,:bottom-09
|
||||
da :bottom-12,:bottom-15,:bottom-18,:bottom-21
|
||||
da :bottom-24,:bottom-27,:bottom-30,:bottom-33
|
||||
da :bottom-36,:bottom-39,:bottom-42,:bottom-45
|
||||
da :bottom-48
|
||||
:top sta CODE_ENTRY+$F000,y
|
||||
sta CODE_ENTRY+$E000,y
|
||||
sta CODE_ENTRY+$D000,y
|
||||
sta CODE_ENTRY+$C000,y
|
||||
sta CODE_ENTRY+$B000,y
|
||||
sta CODE_ENTRY+$A000,y
|
||||
sta CODE_ENTRY+$9000,y
|
||||
sta CODE_ENTRY+$8000,y
|
||||
sta CODE_ENTRY+$7000,y
|
||||
sta CODE_ENTRY+$6000,y
|
||||
sta CODE_ENTRY+$5000,y
|
||||
sta CODE_ENTRY+$4000,y
|
||||
sta CODE_ENTRY+$3000,y
|
||||
sta CODE_ENTRY+$2000,y
|
||||
sta CODE_ENTRY+$1000,y
|
||||
sta: CODE_ENTRY+$0000,y
|
||||
:bottom rts
|
||||
jmp (:tbl,x)
|
||||
:tbl da :bottom-00,:bottom-03,:bottom-06,:bottom-09
|
||||
da :bottom-12,:bottom-15,:bottom-18,:bottom-21
|
||||
da :bottom-24,:bottom-27,:bottom-30,:bottom-33
|
||||
da :bottom-36,:bottom-39,:bottom-42,:bottom-45
|
||||
da :bottom-48
|
||||
:top sta CODE_ENTRY+$F000,y
|
||||
sta CODE_ENTRY+$E000,y
|
||||
sta CODE_ENTRY+$D000,y
|
||||
sta CODE_ENTRY+$C000,y
|
||||
sta CODE_ENTRY+$B000,y
|
||||
sta CODE_ENTRY+$A000,y
|
||||
sta CODE_ENTRY+$9000,y
|
||||
sta CODE_ENTRY+$8000,y
|
||||
sta CODE_ENTRY+$7000,y
|
||||
sta CODE_ENTRY+$6000,y
|
||||
sta CODE_ENTRY+$5000,y
|
||||
sta CODE_ENTRY+$4000,y
|
||||
sta CODE_ENTRY+$3000,y
|
||||
sta CODE_ENTRY+$2000,y
|
||||
sta CODE_ENTRY+$1000,y
|
||||
sta: CODE_ENTRY+$0000,y
|
||||
:bottom rts
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -463,170 +463,6 @@ SetConst ; Need a blank line here
|
||||
sta: $0000,y
|
||||
:bottom rts
|
||||
|
||||
; SaveOpcode
|
||||
;
|
||||
; Save the values to the restore location. This should only be used to patch the
|
||||
; code field since the save location is fixed.
|
||||
;
|
||||
; X = number of lines * 2, 0 to 32
|
||||
; Y = starting line * $1000
|
||||
; A = store location * $1000
|
||||
SaveOpcode0
|
||||
jmp (:tbl,x)
|
||||
|
||||
:tbl da :bottom
|
||||
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
|
||||
:x16 lda $F000,y
|
||||
sta $F000,x
|
||||
:x15 lda $E000,y
|
||||
sta $E000,x
|
||||
:x14 lda $D000,y
|
||||
sta $D000,x
|
||||
:x13 lda $C000,y
|
||||
sta $C000,x
|
||||
:x12 lda $B000,y
|
||||
sta $B000,x
|
||||
:x11 lda $A000,y
|
||||
sta $A000,x
|
||||
:x10 lda $9000,y
|
||||
sta $9000,x
|
||||
:x09 lda $8000,y
|
||||
sta $8000,x
|
||||
:x08 lda $7000,y
|
||||
sta $7000,x
|
||||
:x07 lda $6000,y
|
||||
sta $6000,x
|
||||
:x06 lda $5000,y
|
||||
sta $5000,x
|
||||
:x05 lda $4000,y
|
||||
sta $4000,x
|
||||
:x04 lda $3000,y
|
||||
sta $3000,x
|
||||
:x03 lda $2000,y
|
||||
sta $2000,x
|
||||
:x02 lda $1000,y
|
||||
sta $1000,x
|
||||
:x01 lda: $0000,y
|
||||
sta: $0000,x
|
||||
:bottom rts
|
||||
|
||||
; RestoreOpcode
|
||||
;
|
||||
; Restore the values to the opcode location. This should only be used to restore the
|
||||
; code field.
|
||||
;
|
||||
; X = number of lines * 2, 0 to 32
|
||||
; Y = starting line * $1000
|
||||
; A = store location * $1000
|
||||
RestoreOpcode
|
||||
jmp (:tbl,x)
|
||||
|
||||
:tbl da :bottom
|
||||
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
|
||||
:x16 lda $F000,x
|
||||
sta $F000,y
|
||||
:x15 lda $E000,x
|
||||
sta $E000,y
|
||||
:x14 lda $D000,x
|
||||
sta $D000,y
|
||||
:x13 lda $C000,x
|
||||
sta $C000,y
|
||||
:x12 lda $B000,x
|
||||
sta $B000,y
|
||||
:x11 lda $A000,x
|
||||
sta $A000,y
|
||||
:x10 lda $9000,x
|
||||
sta $9000,y
|
||||
:x09 lda $8000,x
|
||||
sta $8000,y
|
||||
:x08 lda $7000,x
|
||||
sta $7000,y
|
||||
:x07 lda $6000,x
|
||||
sta $6000,y
|
||||
:x06 lda $5000,x
|
||||
sta $5000,y
|
||||
:x05 lda $4000,x
|
||||
sta $4000,y
|
||||
:x04 lda $3000,x
|
||||
sta $3000,y
|
||||
:x03 lda $2000,x
|
||||
sta $2000,y
|
||||
:x02 lda $1000,x
|
||||
sta $1000,y
|
||||
:x01 lda: $0000,x
|
||||
sta: $0000,y
|
||||
:bottom rts
|
||||
|
||||
; CopyFromArray
|
||||
;
|
||||
; Copy values from an array with a stride of two bytes into the code field
|
||||
@ -1094,5 +930,6 @@ top
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -8,20 +8,56 @@
|
||||
; CopyTileLinear -- copies the tile data from the tile bank in linear order, e.g.
|
||||
; 32 consecutive bytes are copied
|
||||
|
||||
|
||||
; CopyTile
|
||||
;
|
||||
; 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)
|
||||
CopyTile
|
||||
phb ; save the current bank
|
||||
pha ; save the tile ID
|
||||
|
||||
tya ; lookup the address of the virtual line (y * 8)
|
||||
asl
|
||||
asl
|
||||
asl
|
||||
tay
|
||||
|
||||
sep #$20 ; set the bank register
|
||||
lda BTableHigh,y
|
||||
pha ; save for a few instruction
|
||||
rep #$20
|
||||
|
||||
txa ; there are two columns per tile, so multiple by 4
|
||||
asl
|
||||
asl ; asl will clear the carry bit
|
||||
tax
|
||||
lda Col2CodeOffset,x
|
||||
adc BTableLow,y
|
||||
tay
|
||||
|
||||
plb ; set the bank
|
||||
pla ; pop the tile ID
|
||||
jsr _CopyTile
|
||||
|
||||
plb ; restre the data bank and return
|
||||
rts
|
||||
|
||||
; _CopyTile
|
||||
;
|
||||
; Copy a solid tile into one of the code banks
|
||||
;
|
||||
; B = bank of the code field
|
||||
; A = Tile ID (0 - 1023)
|
||||
; Y = Base Adddress in the code field
|
||||
|
||||
CopyTile cmp #$0010
|
||||
_CopyTile cmp #$0010
|
||||
bcc :FillWord
|
||||
cmp #$0400
|
||||
bcc :CopyTileMem
|
||||
rts ; Tile number is too large
|
||||
rts ; Tile number is too large
|
||||
|
||||
:TilePatterns dw $0000,$1111,$2222,$3333
|
||||
dw $4444,$5555,$6666,$7777
|
||||
@ -92,3 +128,15 @@ CopyTileLinear ldal tiledata+0,x
|
||||
rts
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user