Improving initialization of code fields
This commit is contained in:
parent
9137440d41
commit
7e6c4a0c91
279
test/App.Main.s
279
test/App.Main.s
|
@ -27,7 +27,7 @@
|
|||
SHADOW_REG equ $E0C035
|
||||
STATE_REG equ $E0C068
|
||||
NEW_VIDEO_REG equ $E0C029
|
||||
BORDER_REG equ $E0C034 ; 0-3 = border 4-7 Text color
|
||||
BORDER_REG equ $E0C034 ; 0-3 = border 4-7 Text color
|
||||
VBL_VERT_REG equ $E0C02E
|
||||
VBL_HORZ_REG equ $E0C02F
|
||||
|
||||
|
@ -45,52 +45,53 @@ SHR_SCB equ $E19D00
|
|||
|
||||
; Tool startup
|
||||
|
||||
_TLStartUp ; normal tool initialization
|
||||
_TLStartUp ; normal tool initialization
|
||||
pha
|
||||
_MMStartUp
|
||||
_Err ; should never happen
|
||||
_Err ; should never happen
|
||||
pla
|
||||
sta MasterId ; our master handle references the memory allocated to us
|
||||
ora #$0100 ; set auxID = $01 (valid values $01-0f)
|
||||
sta UserId ; any memory we request must use our own id
|
||||
sta MasterId ; our master handle references the memory allocated to us
|
||||
ora #$0100 ; set auxID = $01 (valid values $01-0f)
|
||||
sta UserId ; any memory we request must use our own id
|
||||
|
||||
_MTStartUp
|
||||
|
||||
; Install interrupt handlers
|
||||
|
||||
PushLong #0
|
||||
pea $0015 ; Get the existing 1-second interrupt handler and save
|
||||
pea $0015 ; Get the existing 1-second interrupt handler and save
|
||||
_GetVector
|
||||
PullLong OldOneSecVec
|
||||
|
||||
pea $0015 ; Set the new handler and enable interrupts
|
||||
pea $0015 ; Set the new handler and enable interrupts
|
||||
PushLong #OneSecHandler
|
||||
_SetVector
|
||||
|
||||
pea $0006
|
||||
_IntSource
|
||||
|
||||
PushLong #VBLTASK ; Also register a Heart Beat Task
|
||||
PushLong #VBLTASK ; Also register a Heart Beat Task
|
||||
_SetHeartBeat
|
||||
|
||||
; Start up the graphics engine...
|
||||
|
||||
jsr MemInit
|
||||
jsr GrafInit
|
||||
jsr MemInit ; Allocate memory
|
||||
jsr BlitInit ; Initialize the memory
|
||||
jsr GrafInit ; Initialize the graphics screen
|
||||
|
||||
]step equ 0
|
||||
lup 13
|
||||
ldx #BlitBuff
|
||||
lda #^BlitBuff
|
||||
ldy #]step
|
||||
jsr BuildBank
|
||||
]step equ ]step+4
|
||||
--^
|
||||
lda #16*256+28 ; Place the playfield at (16, 28) with
|
||||
ldx #128 ; a width of 128 bytes (256 pixels) and
|
||||
ldy #144 ; 144 scan lines
|
||||
jsr SetScreenRect
|
||||
|
||||
lda #0 ; Set the virtual Y-position
|
||||
jsr SetYPos
|
||||
brl Exit
|
||||
|
||||
; Load a picture and copy it into Bank $E1. Then turn on the screen.
|
||||
|
||||
jsr AllocOneBank ; Alloc 64KB for Load/Unpack
|
||||
sta BankLoad ; Store "Bank Pointer"
|
||||
jsr AllocOneBank ; Alloc 64KB for Load/Unpack
|
||||
sta BankLoad ; Store "Bank Pointer"
|
||||
EvtLoop
|
||||
jsr WaitForKey
|
||||
cmp #'q'
|
||||
|
@ -102,36 +103,11 @@ EvtLoop
|
|||
:2 cmp #'m'
|
||||
bne :3
|
||||
brl DoMessage
|
||||
:3 cmp #'f' ; render a 'f'rame
|
||||
:3 cmp #'f' ; render a 'f'rame
|
||||
bne :4
|
||||
brl DoFrame
|
||||
:4 bra EvtLoop
|
||||
|
||||
; Set the screen address (right-edge) in all of the scan lines
|
||||
SetRightEdge
|
||||
sep #$20 ; push all the bank addresses on the stack
|
||||
ldx #0
|
||||
:loop1 lda BlitBuff+2,x
|
||||
pha
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
inx
|
||||
cpx #4*13
|
||||
bcc :loop1
|
||||
|
||||
lup 13
|
||||
lda #{$2000+159+15*160} ; Set the stack address to the right edge of the screen
|
||||
ldy #0
|
||||
ldx #16*2
|
||||
jsr SetScreenAddrs
|
||||
--^
|
||||
|
||||
phk
|
||||
plb
|
||||
rts
|
||||
|
||||
|
||||
|
||||
; Set up the code field and render it
|
||||
DoFrame
|
||||
|
@ -145,7 +121,7 @@ DoFrame
|
|||
stz :tile
|
||||
:bankloop
|
||||
ldx :bank
|
||||
ldal BlitBuff+1,x ; set the data bank to the code field
|
||||
ldal BlitBuff+1,x ; set the data bank to the code field
|
||||
pha
|
||||
plb
|
||||
plb
|
||||
|
@ -187,74 +163,74 @@ DoFrame
|
|||
; 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
|
||||
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
|
||||
pha ; push twice because we will use it later
|
||||
rep #$20
|
||||
|
||||
ldx #80*2 ; This is the word to exit from
|
||||
ldy Col2CodeOffset,x ; Get the offset
|
||||
ldx #80*2 ; 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
|
||||
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
|
||||
plb ; set the data bank to the code field
|
||||
|
||||
ldx #16*2 ; Y-register is set correctly
|
||||
ldx #16*2 ; Y-register is set correctly
|
||||
lda #OPCODE_SAVE
|
||||
jsr SaveOpcode
|
||||
|
||||
ldx #80*2 ; X-register is overwritten by SaveOpcode
|
||||
ldal CodeFieldEvenBRA,x ; Get the value to place there
|
||||
ldx #80*2 ; X-register is overwritten by SaveOpcode
|
||||
ldal CodeFieldEvenBRA,x ; Get the value to place there
|
||||
ldx #16*2
|
||||
jsr SetConst
|
||||
|
||||
lda #{$2000+159+15*160} ; Set the stack address to the right edge of the screen
|
||||
ldy #0
|
||||
ldx #16*2
|
||||
jsr SetScreenAddrs
|
||||
; 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
|
||||
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)
|
||||
ldy #$7000 ; Set the return after line 200 (Bank 13, line 8)
|
||||
jsr SetReturn
|
||||
|
||||
sei ; disable interrupts
|
||||
sei ; disable interrupts
|
||||
|
||||
ldal STATE_REG
|
||||
ora #$0010 ; Read Bank 0 / Write Bank 1
|
||||
ora #$0010 ; Read Bank 0 / Write Bank 1
|
||||
stal STATE_REG
|
||||
|
||||
tsc ; save the stack pointer
|
||||
tsc ; save the stack pointer
|
||||
stal stk_save+1
|
||||
|
||||
blt_entry jml $000006 ; Jump into the blitter code $XX/YY06
|
||||
blt_entry jml $000006 ; Jump into the blitter code $XX/YY06
|
||||
|
||||
blt_return ldal STATE_REG ; Read Bank 0 / Write Bank 0
|
||||
blt_return ldal STATE_REG ; Read Bank 0 / Write Bank 0
|
||||
and #$FFCF
|
||||
stal STATE_REG
|
||||
stk_save lda #0000 ; load the stack
|
||||
stk_save lda #0000 ; load the stack
|
||||
tcs
|
||||
cli ; re-enable interrupts
|
||||
cli ; re-enable interrupts
|
||||
|
||||
plb ; set the bank back to the code field
|
||||
ldx #80*2 ; This is the word to exit from
|
||||
ldal Col2CodeOffset,x ; Get the offset
|
||||
plb ; set the bank back to the code field
|
||||
ldx #80*2 ; 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
|
||||
phk ; restore data bank
|
||||
plb
|
||||
jmp EvtLoop
|
||||
|
||||
|
@ -339,33 +315,33 @@ DoMessage stz :addr
|
|||
|
||||
DoLoadPic
|
||||
lda BankLoad
|
||||
ldx #ImageName ; Load+Unpack Boot Picture
|
||||
jsr LoadPicture ; X=Name, A=Bank to use for loading
|
||||
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 ; get address of loaded/uncompressed picture
|
||||
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 $E12000,x ; store to SHR screen
|
||||
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 $E12000,x ; store to SHR screen
|
||||
dex
|
||||
dex
|
||||
bpl :copySHR
|
||||
jmp EvtLoop
|
||||
|
||||
Exit
|
||||
pea $0007 ; disable 1-second interrupts
|
||||
pea $0007 ; disable 1-second interrupts
|
||||
_IntSource
|
||||
|
||||
PushLong #VBLTASK ; Remove our heartbeat task
|
||||
PushLong #VBLTASK ; Remove our heartbeat task
|
||||
_DelHeartBeat
|
||||
|
||||
pea $0015
|
||||
PushLong OldOneSecVec ; Reset the interrupt vector
|
||||
PushLong OldOneSecVec ; Reset the interrupt vector
|
||||
_SetVector
|
||||
|
||||
PushWord UserId ; Deallocate all of our memory
|
||||
PushWord UserId ; Deallocate all of our memory
|
||||
_DisposeAll
|
||||
|
||||
_QuitGS qtRec
|
||||
|
@ -403,7 +379,7 @@ OneSecHandler mx %11
|
|||
sep #$20
|
||||
|
||||
ldal $E0C032
|
||||
and #%10111111 ;clear IRQ source
|
||||
and #%10111111 ;clear IRQ source
|
||||
stal $E0C032
|
||||
|
||||
pla
|
||||
|
@ -418,9 +394,20 @@ VBLTASK hex 00000000
|
|||
dw 0
|
||||
hex 5AA5
|
||||
|
||||
; Blitter initialization
|
||||
BlitInit
|
||||
]step equ 0
|
||||
lup 13
|
||||
ldx #BlitBuff
|
||||
lda #^BlitBuff
|
||||
ldy #]step
|
||||
jsr BuildBank
|
||||
]step equ ]step+4
|
||||
--^
|
||||
rts
|
||||
|
||||
|
||||
; Graphic screen initialization
|
||||
|
||||
GrafInit lda #$8888
|
||||
jsr ClearToColor
|
||||
lda #0000
|
||||
|
@ -438,24 +425,24 @@ GetBorderColor lda #0000
|
|||
rts
|
||||
|
||||
; Set the border color to the accumulator value.
|
||||
SetBorderColor sep #$20 ; ACC = $X_Y, REG = $W_Z
|
||||
eorl BORDER_REG ; ACC = $(X^Y)_(Y^Z)
|
||||
and #$0F ; ACC = $0_(Y^Z)
|
||||
eorl BORDER_REG ; ACC = $W_(Y^Z^Z) = $W_Y
|
||||
SetBorderColor sep #$20 ; ACC = $X_Y, REG = $W_Z
|
||||
eorl BORDER_REG ; ACC = $(X^Y)_(Y^Z)
|
||||
and #$0F ; ACC = $0_(Y^Z)
|
||||
eorl BORDER_REG ; ACC = $W_(Y^Z^Z) = $W_Y
|
||||
stal BORDER_REG
|
||||
rep #$20
|
||||
rts
|
||||
|
||||
; Clear to SHR screen to a specific color
|
||||
ClearToColor ldx #$7D00 ;start at top of pixel data! ($2000-9D00)
|
||||
ClearToColor ldx #$7D00 ;start at top of pixel data! ($2000-9D00)
|
||||
:clearloop dex
|
||||
dex
|
||||
stal SHR_SCREEN,x ;screen location
|
||||
bne :clearloop ;loop until we've worked our way down to 0
|
||||
stal SHR_SCREEN,x ;screen location
|
||||
bne :clearloop ;loop until we've worked our way down to 0
|
||||
rts
|
||||
|
||||
; Initialize the SCB
|
||||
SetSCBs ldx #$0100 ;set all $100 scbs to A
|
||||
SetSCBs ldx #$0100 ;set all $100 scbs to A
|
||||
:scbloop dex
|
||||
dex
|
||||
stal SHR_SCB,x
|
||||
|
@ -494,21 +481,21 @@ GetVBL sep #$20
|
|||
ldal VBL_HORZ_REG
|
||||
asl
|
||||
ldal VBL_VERT_REG
|
||||
rol ; put V5 into carry bit, if needed. See TN #39 for details.
|
||||
rol ; put V5 into carry bit, if needed. See TN #39 for details.
|
||||
rep #$20
|
||||
and #$00FF
|
||||
rts
|
||||
|
||||
WaitForVBL sep #$20
|
||||
:wait1 ldal VBL_STATE_REG ; If we are already in VBL, then wait
|
||||
:wait1 ldal VBL_STATE_REG ; If we are already in VBL, then wait
|
||||
bmi :wait1
|
||||
:wait2 ldal VBL_STATE_REG
|
||||
bpl :wait2 ; spin until transition into VBL
|
||||
bpl :wait2 ; spin until transition into VBL
|
||||
rep #$20
|
||||
rts
|
||||
|
||||
WaitForKey sep #$20
|
||||
stal KBD_STROBE_REG ; clear the strobe
|
||||
stal KBD_STROBE_REG ; clear the strobe
|
||||
:WFK ldal KBD_REG
|
||||
bpl :WFK
|
||||
rep #$20
|
||||
|
@ -523,42 +510,42 @@ ClearKeyboardStrobe sep #$20
|
|||
; Graphics helpers
|
||||
|
||||
LoadPicture
|
||||
jsr LoadFile ; X=Nom Image, A=Banc de chargement XX/00
|
||||
jsr LoadFile ; X=Nom Image, A=Banc de chargement XX/00
|
||||
bcc :loadOK
|
||||
rts
|
||||
:loadOK
|
||||
jsr UnpackPicture ; A=Packed Size
|
||||
jsr UnpackPicture ; A=Packed Size
|
||||
rts
|
||||
|
||||
|
||||
UnpackPicture sta UP_PackedSize ; Size of Packed Data
|
||||
lda #$8000 ; Size of output Data Buffer
|
||||
UnpackPicture sta UP_PackedSize ; Size of Packed Data
|
||||
lda #$8000 ; Size of output Data Buffer
|
||||
sta UP_UnPackedSize
|
||||
lda BankLoad ; Banc de chargement / Decompression
|
||||
sta UP_Packed+1 ; Packed Data
|
||||
lda BankLoad ; Banc de chargement / Decompression
|
||||
sta UP_Packed+1 ; Packed Data
|
||||
clc
|
||||
adc #$0080
|
||||
stz UP_UnPacked ; On remet a zero car modifie par l'appel
|
||||
stz UP_UnPacked ; On remet a zero car modifie par l'appel
|
||||
stz UP_UnPacked+2
|
||||
sta UP_UnPacked+1 ; Unpacked Data buffer
|
||||
sta UP_UnPacked+1 ; Unpacked Data buffer
|
||||
|
||||
PushWord #0 ; Space for Result : Number of bytes unpacked
|
||||
PushLong UP_Packed ; Pointer to buffer containing the packed data
|
||||
PushWord UP_PackedSize ; Size of the Packed Data
|
||||
PushLong #UP_UnPacked ; Pointer to Pointer to unpacked buffer
|
||||
PushLong #UP_UnPackedSize ; Pointer to a Word containing size of unpacked data
|
||||
PushWord #0 ; Space for Result : Number of bytes unpacked
|
||||
PushLong UP_Packed ; Pointer to buffer containing the packed data
|
||||
PushWord UP_PackedSize ; Size of the Packed Data
|
||||
PushLong #UP_UnPacked ; Pointer to Pointer to unpacked buffer
|
||||
PushLong #UP_UnPackedSize ; Pointer to a Word containing size of unpacked data
|
||||
_UnPackBytes
|
||||
pla ; Number of byte unpacked
|
||||
pla ; Number of byte unpacked
|
||||
rts
|
||||
|
||||
UP_Packed hex 00000000 ; Address of Packed Data
|
||||
UP_PackedSize hex 0000 ; Size of Packed Data
|
||||
UP_UnPacked hex 00000000 ; Address of Unpacked Data Buffer (modified)
|
||||
UP_UnPackedSize hex 0000 ; Size of Unpacked Data Buffer (modified)
|
||||
UP_Packed hex 00000000 ; Address of Packed Data
|
||||
UP_PackedSize hex 0000 ; Size of Packed Data
|
||||
UP_UnPacked hex 00000000 ; Address of Unpacked Data Buffer (modified)
|
||||
UP_UnPackedSize hex 0000 ; Size of Unpacked Data Buffer (modified)
|
||||
|
||||
; Basic I/O function to load files
|
||||
|
||||
LoadFile stx openRec+4 ; X=File, A=Bank/Page XX/00
|
||||
LoadFile stx openRec+4 ; X=File, A=Bank/Page XX/00
|
||||
sta readRec+5
|
||||
|
||||
:openFile _OpenGS openRec
|
||||
|
@ -578,7 +565,7 @@ LoadFile stx openRec+4 ; X=File, A=Bank/Page XX/00
|
|||
|
||||
:closeFile _CloseGS closeRec
|
||||
clc
|
||||
lda eofRec+4 ; File Size
|
||||
lda eofRec+4 ; File Size
|
||||
rts
|
||||
|
||||
:openReadErr jsr :closeFile
|
||||
|
@ -609,22 +596,22 @@ MasterId ds 2
|
|||
UserId ds 2
|
||||
BankLoad hex 0000
|
||||
|
||||
openRec dw 2 ; pCount
|
||||
ds 2 ; refNum
|
||||
adrl ImageName ; pathname
|
||||
openRec dw 2 ; pCount
|
||||
ds 2 ; refNum
|
||||
adrl ImageName ; pathname
|
||||
|
||||
eofRec dw 2 ; pCount
|
||||
ds 2 ; refNum
|
||||
ds 4 ; eof
|
||||
eofRec dw 2 ; pCount
|
||||
ds 2 ; refNum
|
||||
ds 4 ; eof
|
||||
|
||||
readRec dw 4 ; pCount
|
||||
ds 2 ; refNum
|
||||
ds 4 ; dataBuffer
|
||||
ds 4 ; requestCount
|
||||
ds 4 ; transferCount
|
||||
readRec dw 4 ; pCount
|
||||
ds 2 ; refNum
|
||||
ds 4 ; dataBuffer
|
||||
ds 4 ; requestCount
|
||||
ds 4 ; transferCount
|
||||
|
||||
closeRec dw 1 ; pCount
|
||||
ds 2 ; refNum
|
||||
closeRec dw 1 ; pCount
|
||||
ds 2 ; refNum
|
||||
|
||||
qtRec adrl $0000
|
||||
da $00
|
||||
|
@ -635,3 +622,17 @@ qtRec adrl $0000
|
|||
put blitter/Tables.s
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ ScreenX1 equ 10
|
|||
|
||||
StartY equ 12 ; Which code buffer line displays first on screen. Range = 0 to 207
|
||||
|
||||
bstk equ 224 ; 16-byte stack to push bank addresses
|
||||
|
||||
tmp0 equ 240 ; 16 bytes of temporary space to be used as scratch
|
||||
tmp1 equ 242
|
||||
tmp2 equ 244
|
||||
|
@ -18,3 +20,5 @@ tmp6 equ 252
|
|||
tmp7 equ 254
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ SetScreenRect sty ScreenHeight ; Save the screen height a
|
|||
rts
|
||||
|
||||
; Set the starting line of the virtual buffer that will be displayed on the first physical line
|
||||
; of the screen rect.
|
||||
; of the playfield.
|
||||
;
|
||||
; A = line number [0, 207]
|
||||
;
|
||||
|
@ -149,39 +149,35 @@ SetScreenRect sty ScreenHeight ; Save the screen height a
|
|||
; if (line_count > 0) {
|
||||
; do_action(curr_bank, 0, line_count)
|
||||
; }
|
||||
;
|
||||
; One hack we do is to push in *at least* enough bank values (ScreenHeight / 16) + 1 on the
|
||||
; stack ahead of time and just pop them off in order. At worst, this only adds about 10 cycles
|
||||
; of overhead and eliminates an awkward 16-bit <-> 8-bit state switch within the inner loops.
|
||||
;
|
||||
|
||||
bank_count equ tmp0
|
||||
start_mod_16 equ tmp1
|
||||
line_x2 equ tmp2 ; A physical screen line; used to index into RTable
|
||||
last_x2 equ tmp3
|
||||
start_mod_16 equ tmp0
|
||||
lines_left equ tmp1
|
||||
tblptr equ tmp2
|
||||
stksave equ tmp7
|
||||
|
||||
SetYPos sta StartY ; Save the position
|
||||
|
||||
asl
|
||||
sta line_x2
|
||||
lsr
|
||||
; First action is to calculate the number of code banks that we will be updating and push all of the
|
||||
; bank bytes onto the stack in order so that we can use a single 'plb' instruction to set the target
|
||||
; for updating the screen address of each blitter line.
|
||||
|
||||
; Now we need to calculate two things. First, we get the code bank index that we are starting on. This
|
||||
; is easy, it's just the value of floor(Y / 16), but we pre-multiple by 4 for indexing into the table
|
||||
; of bank addresses. Next, we need to calculate the number of banks that the current range spans. This
|
||||
; will be either floor(ScreenHeight / 16) or floor(ScreenHeight / 16) + 1 depending on the exact value
|
||||
; of the Y position, so we actually calculate floor((ScreenHeight + Y % 16) / 16) and pre-multiple by 2.
|
||||
|
||||
lsr ; divide by 4 (Y / 18 * 4 => Y / 4) and then truncate
|
||||
lsr ; the bottom two bits (and only keep relevant bits)
|
||||
and #$003C
|
||||
lsr ; divide by 4. This is really StartY / 16 but we
|
||||
lsr ; need to multiple by 4 to index into the array of
|
||||
and #$003C ; code bank addresses.
|
||||
tay
|
||||
|
||||
; Quick stack save because we re-point the stack into some direct page space to aboid having to
|
||||
; mix 8 and 16 bit modes for bank anipulation
|
||||
|
||||
tsc
|
||||
sta stksave
|
||||
|
||||
lda StartY
|
||||
and #$000F
|
||||
sta start_mod_16 ; Save for later
|
||||
lda ScreenHeight
|
||||
sta lines_left
|
||||
|
||||
lda StartY ; Now figure out exactly how many banks we cross by
|
||||
and #$000F ; calculating ((StartY % 16) + ScreenHeight) / 16
|
||||
sta start_mod_16
|
||||
clc
|
||||
adc ScreenHeight
|
||||
and #$00F0 ; Just keep the relevant nibble
|
||||
|
@ -189,16 +185,26 @@ SetYPos sta StartY ; Save the position
|
|||
lsr
|
||||
lsr
|
||||
tax ; Keep the value pre-multiplied by 2
|
||||
lsr
|
||||
sta bank_count ; This is the total number of action calls to make
|
||||
|
||||
ldy #0
|
||||
|
||||
jsr PushBanks ; Push the bank bytes on the stack
|
||||
brl :out
|
||||
|
||||
; Start of the main body of the function. First, see if there are any unaligned lines to
|
||||
; handle in the first code bank.
|
||||
; Start of the main body of the function. We need to get a pointer to the correct offset of
|
||||
; the RTable to copy screen addresses into the code fields
|
||||
|
||||
lda start_mod_16
|
||||
beq skip_pre
|
||||
lda ScreenY0
|
||||
asl
|
||||
clc
|
||||
adc #RTable
|
||||
sta tblptr
|
||||
|
||||
; Check to see where we start. If we are aligned with a code bank, then skip to the
|
||||
; fast inner loop. Otherwise to one iteration to get things lined up
|
||||
|
||||
:prologue lda start_mod_16
|
||||
beq :body
|
||||
|
||||
_Mul4096 ; Save the offset into the code bank of the
|
||||
tay ; first line.
|
||||
|
@ -209,60 +215,62 @@ SetYPos sta StartY ; Save the position
|
|||
cmp ScreenHeight ; the number of lines in the code bank, we need to clamp
|
||||
bcc :min_1 ; the maximum value
|
||||
lda ScreenHeight
|
||||
:min_1 asl ; multiply the count by two
|
||||
pha ; save it for a second
|
||||
:min_1 sta tmp4 ; save for updating the counters
|
||||
|
||||
clc
|
||||
adc line_x2
|
||||
sta line_x2 ; advance the line counter
|
||||
tax
|
||||
ldal RTable-2,x ; Load the ending address for this block
|
||||
asl
|
||||
tax ; do this many lines
|
||||
lda tblptr ; starting at this address
|
||||
|
||||
plx ; Pop the number of lines * 2 to fill
|
||||
plb ; Set the code field bank
|
||||
jsr SetScreenAddrs
|
||||
|
||||
skip_pre ldy #0
|
||||
lda line_x2
|
||||
clc
|
||||
adc #32
|
||||
cmp
|
||||
|
||||
jsr CopyFromArray2 ; Copy the right screen edge addresses
|
||||
|
||||
lda lines_left
|
||||
sec
|
||||
plb ; Set the code field bank
|
||||
ldal RTable+30,x ; Load the highest address for this code field bank
|
||||
jsr SetScreenAddrsTop ; to bypass the need to set the X register
|
||||
sbc tmp4
|
||||
sta lines_left
|
||||
|
||||
lda tblptr
|
||||
clc
|
||||
adc tmp4
|
||||
adc tmp4
|
||||
sta tblptr
|
||||
|
||||
; While the number of lines left to render is 16 or greater, loop
|
||||
:body lda lines_left
|
||||
cmp #16
|
||||
bcc :epilogue
|
||||
|
||||
ldy #0
|
||||
ldx tblptr
|
||||
:body0 plb ; Set the code field bank
|
||||
jsr CopyFromArray2Top ; to bypass the need to set the X register
|
||||
|
||||
txa
|
||||
clc
|
||||
adc #32
|
||||
tax
|
||||
|
||||
ldy #0
|
||||
jsr SetScreenAddrsTop ; bypass X-register
|
||||
lda lines_left
|
||||
sec
|
||||
sbc #16
|
||||
sta lines_left
|
||||
|
||||
dec loop_count
|
||||
cmp #16 ; Repeat the test here to we can skip some
|
||||
bcs :body0 ; redundant setup and spill the X register
|
||||
stx tblptr ; back into tblptr when done
|
||||
|
||||
lda line_count ; with some pre-calc, we can just decrement a
|
||||
sec ; counter because we know the remaining line
|
||||
sbc #16 ; count is line_count % 16
|
||||
sta line_count
|
||||
cmp #16
|
||||
bcs core_loop
|
||||
:epilogue lda lines_left
|
||||
beq :out
|
||||
|
||||
lda line_count
|
||||
beq :no_post
|
||||
|
||||
:no_post
|
||||
asl ; Y is still zero
|
||||
tax
|
||||
|
||||
lda tblptr
|
||||
plb ; Set the code field bank
|
||||
; jsr (action)
|
||||
jsr CopyFromArray2 ; to bypass the need to set the X register
|
||||
|
||||
|
||||
:out phk ; Need to restore the current bank
|
||||
:out lda stksave ; put the stack back
|
||||
tcs
|
||||
phk ; Need to restore the current bank
|
||||
plb
|
||||
rts
|
||||
|
||||
|
@ -276,39 +284,39 @@ skip_pre ldy #0
|
|||
|
||||
Mod208 cmp #%1101000000000000
|
||||
bcc *+5
|
||||
sbc #$1101000000000000
|
||||
sbc #%1101000000000000
|
||||
|
||||
cmp #%0110100000000000
|
||||
bcc *+5
|
||||
sbc #$0110100000000000
|
||||
sbc #%0110100000000000
|
||||
|
||||
cmp #%0011010000000000
|
||||
bcc *+5
|
||||
sbc #$0011010000000000
|
||||
sbc #%0011010000000000
|
||||
|
||||
cmp #%0001101000000000
|
||||
bcc *+5
|
||||
sbc #$0001101000000000
|
||||
sbc #%0001101000000000
|
||||
|
||||
cmp #%0000110100000000
|
||||
bcc *+5
|
||||
sbc #$0000110100000000
|
||||
sbc #%0000110100000000
|
||||
|
||||
cmp #%0000011010000000
|
||||
bcc *+5
|
||||
sbc #$0000011010000000
|
||||
sbc #%0000011010000000
|
||||
|
||||
cmp #%0000001101000000
|
||||
bcc *+5
|
||||
sbc #$0000001101000000
|
||||
sbc #%0000001101000000
|
||||
|
||||
cmp #%0000000110100000
|
||||
bcc *+5
|
||||
sbc #$0000000110100000
|
||||
sbc #%0000000110100000
|
||||
|
||||
cmp #%0000000011010000
|
||||
bcc *+5
|
||||
sbc #$0000000011010000
|
||||
sbc #%0000000011010000
|
||||
rts
|
||||
|
||||
; BankYSetup
|
||||
|
@ -370,57 +378,50 @@ SetNextLine lda #$F000+{entry_3-base}
|
|||
ldx #15*2
|
||||
jmp SetAbsAddrs
|
||||
|
||||
; Push a series of bank bytes onto the stack that are use to iterate among the
|
||||
; different code banks.
|
||||
; Copy a series of bank bytes onto the direct page, which we will later point the stack
|
||||
; at, and are use to iterate among the different code banks.
|
||||
;
|
||||
; Y = starting index * 4
|
||||
; X = number of bank
|
||||
;
|
||||
; Bytes are pushed in reverse order, so popping the banks will set the B register
|
||||
; in acending order, as expected (top to bottom)
|
||||
;
|
||||
; This is a bit of an unusual routine, we switch to 8-bit index registers and 16-bit accumulator.
|
||||
; That way we can cache the return address in the accumulator and use the index registers for
|
||||
; moving the data. This is OK, because the arrays are small, so X and Y are much smaller than 256.
|
||||
|
||||
PushBanks pla ; Pop off the return address
|
||||
sep #$10
|
||||
PushBanks sep #$20
|
||||
jmp (:tbl,x)
|
||||
:tbl da :bottom-04,:bottom-08,:bottom-12,:bottom-16
|
||||
da :bottom-20,:bottom-24,:bottom-28,:bottom-32
|
||||
da :bottom-36,:bottom-40,:bottom-44,:bottom-48
|
||||
da :bottom-52
|
||||
:top ldx: BlitBuff+48,y ; These are all 8-bit loads and pushes
|
||||
phx
|
||||
ldx: BlitBuff+44,y
|
||||
phx
|
||||
ldx: BlitBuff+42,y
|
||||
phx
|
||||
ldx: BlitBuff+38,y
|
||||
phx
|
||||
ldx: BlitBuff+34,y
|
||||
phx
|
||||
ldx: BlitBuff+30,y
|
||||
phx
|
||||
ldx: BlitBuff+26,y
|
||||
phx
|
||||
ldx: BlitBuff+22,y
|
||||
phx
|
||||
ldx: BlitBuff+18,y
|
||||
phx
|
||||
ldx: BlitBuff+14,y
|
||||
phx
|
||||
ldx: BlitBuff+10,y
|
||||
phx
|
||||
ldx: BlitBuff+6,y
|
||||
phx
|
||||
ldx: BlitBuff+2,y
|
||||
phx
|
||||
:bottom rep #$10
|
||||
pha ; Push the return address back to the top of the stack
|
||||
:top lda: BlitBuff+48,y ; These are all 8-bit loads and stores
|
||||
sta bstk+13
|
||||
lda: BlitBuff+44,y
|
||||
sta bstk+12
|
||||
lda: BlitBuff+42,y
|
||||
sta bstk+11
|
||||
lda: BlitBuff+38,y
|
||||
sta bstk+10
|
||||
lda: BlitBuff+34,y
|
||||
sta bstk+9
|
||||
lda: BlitBuff+30,y
|
||||
sta bstk+8
|
||||
lda: BlitBuff+26,y
|
||||
sta bstk+7
|
||||
lda: BlitBuff+22,y
|
||||
sta bstk+6
|
||||
lda: BlitBuff+18,y
|
||||
sta bstk+5
|
||||
lda: BlitBuff+14,y
|
||||
sta bstk+4
|
||||
lda: BlitBuff+10,y
|
||||
sta bstk+3
|
||||
lda: BlitBuff+6,y
|
||||
sta bstk+2
|
||||
lda: BlitBuff+2,y
|
||||
sta bstk+1
|
||||
lda: BlitBuff,y
|
||||
sta bstk
|
||||
:bottom rep #$20
|
||||
rts
|
||||
|
||||
; Patch an 8-bit or 16-bit value into the bank. These are a set up unrolled loops to
|
||||
; Patch an 8-bit or 16-bit valueS into the bank. These are a set up unrolled loops to
|
||||
; quickly patch in a constanct value, or a value from an array into a given set of
|
||||
; templates.
|
||||
;
|
||||
|
@ -568,6 +569,59 @@ RestoreOpcode pha ; save the accumulator
|
|||
sta: $0000,y
|
||||
:bottom rts
|
||||
|
||||
; CopyFromArray
|
||||
;
|
||||
; Copy values from an array with a stride of two bytes into the code field
|
||||
;
|
||||
; X = number of lines * 2, 0 to 32
|
||||
; Y = starting line * $1000
|
||||
; A = array address
|
||||
CopyFromArray2 pha ; save the accumulator
|
||||
ldal :tbl,x
|
||||
dec
|
||||
plx ; put the accumulator into X
|
||||
pha ; push the address into the stack
|
||||
rts ; and jump
|
||||
|
||||
:tbl da bottomCFA2-00,bottomCFA2-06,bottomCFA2-12,bottomCFA2-18
|
||||
da bottomCFA2-24,bottomCFA2-30,bottomCFA2-36,bottomCFA2-42
|
||||
da bottomCFA2-48,bottomCFA2-54,bottomCFA2-60,bottomCFA2-66
|
||||
da bottomCFA2-72,bottomCFA2-78,bottomCFA2-84,bottomCFA2-90
|
||||
da bottomCFA2-96
|
||||
|
||||
CopyFromArray2Top lda: $001E,x
|
||||
sta $F000,y
|
||||
lda: $001C,x
|
||||
sta $E000,y
|
||||
lda: $001A,x
|
||||
sta $D000,y
|
||||
lda: $0018,x
|
||||
sta $C000,y
|
||||
lda: $0016,x
|
||||
sta $B000,y
|
||||
lda: $0014,x
|
||||
sta $A000,y
|
||||
lda: $0012,x
|
||||
sta $9000,y
|
||||
lda: $0010,x
|
||||
sta $8000,y
|
||||
lda: $000E,x
|
||||
sta $7000,y
|
||||
lda: $000C,x
|
||||
sta $6000,y
|
||||
lda: $000A,x
|
||||
sta $5000,y
|
||||
lda: $0008,x
|
||||
sta $4000,y
|
||||
lda: $0006,x
|
||||
sta $3000,y
|
||||
lda: $0004,x
|
||||
sta $2000,y
|
||||
lda: $0002,x
|
||||
sta $1000,y
|
||||
lda: $0000,x
|
||||
sta: $0000,y
|
||||
bottomCFA2 rts
|
||||
|
||||
; SetScreenAddrs
|
||||
;
|
||||
|
@ -578,13 +632,13 @@ RestoreOpcode pha ; save the accumulator
|
|||
; Automatically decrements address by 160 bytes each line
|
||||
SetScreenAddrs sec
|
||||
jmp (:tbl,x)
|
||||
:tbl da :bottom-00,:bottom-03,:bottom-09,:bottom-15
|
||||
da :bottom-21,:bottom-27,:bottom-33,:bottom-39
|
||||
da :bottom-45,:bottom-51,:bottom-57,:bottom-63
|
||||
da :bottom-69,:bottom-75,:bottom-81,:bottom-87
|
||||
da :bottom-93
|
||||
SetScreenAddrsTop
|
||||
:top sta STK_ADDR+$F000,y
|
||||
:tbl da bottomSSA-00,bottomSSA-03,bottomSSA-09,bottomSSA-15
|
||||
da bottomSSA-21,bottomSSA-27,bottomSSA-33,bottomSSA-39
|
||||
da bottomSSA-45,bottomSSA-51,bottomSSA-57,bottomSSA-63
|
||||
da bottomSSA-69,bottomSSA-75,bottomSSA-81,bottomSSA-87
|
||||
da bottomSSA-93
|
||||
|
||||
SetScreenAddrsTop sta STK_ADDR+$F000,y
|
||||
sbc #160
|
||||
sta STK_ADDR+$E000,y
|
||||
sbc #160
|
||||
|
@ -615,7 +669,7 @@ SetScreenAddrsTop
|
|||
sta STK_ADDR+$1000,y
|
||||
sbc #160
|
||||
sta: STK_ADDR+$0000,y
|
||||
:bottom rts
|
||||
bottomSSA rts
|
||||
|
||||
; SetAbsAddrs
|
||||
;
|
||||
|
@ -953,120 +1007,6 @@ top
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue