Fix tile rendering

This is not quite correct yet.  IT appears that two rows or columns are
drawn on the edges when only a single solumn or row is necessary.  Also,
this code is based on the old GTE codebase, so the initial rectangle for
rendering tiles is width+1, height+1. This can be improved.
This commit is contained in:
Lucas Scharenbroich 2021-08-10 07:59:14 -05:00
parent b9fced46cd
commit e3cb742626
8 changed files with 435 additions and 344 deletions

View File

@ -3,11 +3,11 @@ MoveLeft
adc StartX ; Increment the virtual X-position adc StartX ; Increment the virtual X-position
jsr SetBG0XPos jsr SetBG0XPos
lda StartX ; lda StartX
lsr ; lsr
jsr SetBG1XPos ; jsr SetBG1XPos
jsr DoFrame jsr Render
rts rts
MoveRight MoveRight
@ -19,11 +19,11 @@ MoveRight
lda #0 lda #0
jsr SetBG0XPos jsr SetBG0XPos
lda StartX ; lda StartX
lsr ; lsr
jsr SetBG1XPos ; jsr SetBG1XPos
jsr DoFrame jsr Render
pla pla
rts rts
@ -46,7 +46,7 @@ MoveUp
; lsr ; lsr
; jsr SetBG1YPos ; jsr SetBG1YPos
jsr DoFrame jsr Render
rts rts
MoveDown MoveDown
@ -58,11 +58,11 @@ MoveDown
lda #0 lda #0
jsr SetBG0YPos jsr SetBG0YPos
lda StartY ; lda StartY
lsr ; lsr
jsr SetBG1YPos ; jsr SetBG1YPos
jsr DoFrame jsr Render
pla pla
rts rts
@ -108,7 +108,7 @@ Demo
; jsr MoveLeft ; jsr MoveLeft
jsr UpdateBG1Rotation jsr UpdateBG1Rotation
; jsr DoColorCycle ; jsr DoColorCycle
jsr DoFrame jsr Render
inc frameCount inc frameCount
@ -190,7 +190,7 @@ AngleUp
sbc #64 sbc #64
sta angle sta angle
jsr _ApplyAngle jsr _ApplyAngle
jsr DoFrame jsr Render
rts rts
AngleDown AngleDown
@ -201,7 +201,7 @@ AngleDown
adc #64 adc #64
sta angle sta angle
jsr _ApplyAngle jsr _ApplyAngle
jsr DoFrame jsr Render
rts rts
angle dw 0 angle dw 0
@ -289,3 +289,8 @@ _DoTimers

View File

@ -26,7 +26,7 @@
SHADOW_REG equ $E0C035 SHADOW_REG equ $E0C035
STATE_REG equ $E0C068 STATE_REG equ $E0C068
NEW_VIDEO_REG equ $E0C029 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_VERT_REG equ $E0C02E
VBL_HORZ_REG equ $E0C02F VBL_HORZ_REG equ $E0C02F
@ -46,8 +46,8 @@ SHR_PALETTES equ $E19E00
tiledata ext tiledata ext
; Feature flags ; Feature flags
NO_INTERRUPTS equ 1 ; turn off for crossrunner debugging NO_INTERRUPTS equ 1 ; turn off for crossrunner debugging
NO_MUSIC equ 1 ; turn music + tool loading off NO_MUSIC equ 1 ; turn music + tool loading off
; Typical init ; Typical init
@ -56,14 +56,14 @@ NO_MUSIC equ 1 ; turn music + tool loading
; Tool startup ; Tool startup
_TLStartUp ; normal tool initialization _TLStartUp ; normal tool initialization
pha pha
_MMStartUp _MMStartUp
_Err ; should never happen _Err ; should never happen
pla pla
sta MasterId ; our master handle references the memory allocated to us sta MasterId ; our master handle references the memory allocated to us
ora #$0100 ; set auxID = $01 (valid values $01-0f) ora #$0100 ; set auxID = $01 (valid values $01-0f)
sta UserId ; any memory we request must use our own id sta UserId ; any memory we request must use our own id
_MTStartUp _MTStartUp
@ -85,7 +85,7 @@ NO_MUSIC equ 1 ; turn music + tool loading
pea #MusicFile pea #MusicFile
_NTPLoadOneMusic _NTPLoadOneMusic
pea $0001 ; loop pea $0001 ; loop
_NTPPlayMusic _NTPPlayMusic
:no_music :no_music
@ -97,37 +97,31 @@ NO_MUSIC equ 1 ; turn music + tool loading
lda #NO_INTERRUPTS lda #NO_INTERRUPTS
bne :no_interrupts bne :no_interrupts
PushLong #0 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 _GetVector
PullLong OldOneSecVec PullLong OldOneSecVec
pea $0015 ; Set the new handler and enable interrupts pea $0015 ; Set the new handler and enable interrupts
PushLong #OneSecHandler PushLong #OneSecHandler
_SetVector _SetVector
pea $0006 pea $0006
_IntSource _IntSource
PushLong #VBLTASK ; Also register a Heart Beat Task PushLong #VBLTASK ; Also register a Heart Beat Task
_SetHeartBeat _SetHeartBeat
:no_interrupts :no_interrupts
; Start up the graphics engine... ; Start up the graphics engine...
jsr MemInit ; Allocate memory jsr MemInit ; Allocate memory
jsr BlitInit ; Initialize the memory jsr BlitInit ; Initialize the memory
jsr GrafInit ; Initialize the graphics screen jsr GrafInit ; Initialize the graphics screen
ldx #0 ; Gameboy Advance size ldx #0 ;
jsr SetScreenMode jsr SetScreenMode
lda #0 ; Set the virtual Y-position jsr _InitBG1 ; Initialize the second background
jsr SetBG0YPos
lda #0 ; Set the virtual X-position
jsr SetBG0XPos
jsr _InitBG1 ; Initialize the second background
lda #0 lda #0
jsr _ClearBG1Buffer jsr _ClearBG1Buffer
@ -137,20 +131,20 @@ NO_MUSIC equ 1 ; turn music + tool loading
; Allocate room to load data ; Allocate room to load data
jsr AllocOneBank2 ; Alloc 64KB for Load/Unpack jsr AllocOneBank2 ; Alloc 64KB for Load/Unpack
sta BankLoad ; Store "Bank Pointer" sta BankLoad ; Store "Bank Pointer"
jsr MovePlayerToOrigin ; Put the player at the beginning of the map jsr MovePlayerToOrigin ; Put the player at the beginning of the map
lda #$FFFF ; Force a redraw of all the tiles
jsr _UpdateBG0TileMap
lda #DIRTY_BIT_BG0_REFRESH ; Redraw all of the tiles on the next Render
tsb DirtyBits
; jsr DoTiles ; jsr DoTiles
; jsr DoLoadBG1 ; jsr DoLoadBG1
; jsr Demo ; jsr Demo
EvtLoop EvtLoop
jsr ReadControl jsr ReadControl
and #$007F ; Ignore the buttons for now and #$007F ; Ignore the buttons for now
cmp #'q' cmp #'q'
bne :1 bne :1
@ -171,17 +165,17 @@ EvtLoop
jsr DumpBanks jsr DumpBanks
bra EvtLoop bra EvtLoop
:3 cmp #'f' ; render a 'f'rame :3 cmp #'f' ; render a 'f'rame
bne :4 bne :4
jsr DoFrame jsr Render
bra EvtLoop bra EvtLoop
:4 cmp #'h' ; Show the 'h'eads up display :4 cmp #'h' ; Show the 'h'eads up display
bne :5 bne :5
jsr DoHUP jsr DoHUP
bra EvtLoop bra EvtLoop
:5 cmp #'1' ; User selects a new screen size :5 cmp #'1' ; User selects a new screen size
bcc :6 bcc :6
cmp #'9'+1 cmp #'9'+1
bcs :6 bcs :6
@ -197,7 +191,7 @@ EvtLoop
jsr DoTiles jsr DoTiles
brl EvtLoop brl EvtLoop
:7 cmp #$15 ; left = $08, right = $15, up = $0B, down = $0A :7 cmp #$15 ; left = $08, right = $15, up = $0B, down = $0A
bne :8 bne :8
lda #1 lda #1
jsr MoveRight jsr MoveRight
@ -244,14 +238,14 @@ Exit
lda #NO_INTERRUPTS lda #NO_INTERRUPTS
bne :no_interrupts bne :no_interrupts
pea $0007 ; disable 1-second interrupts pea $0007 ; disable 1-second interrupts
_IntSource _IntSource
PushLong #VBLTASK ; Remove our heartbeat task PushLong #VBLTASK ; Remove our heartbeat task
_DelHeartBeat _DelHeartBeat
pea $0015 pea $0015
PushLong OldOneSecVec ; Reset the interrupt vector PushLong OldOneSecVec ; Reset the interrupt vector
_SetVector _SetVector
:no_interrupts :no_interrupts
@ -260,7 +254,7 @@ Exit
_NTPShutDown _NTPShutDown
:no_music :no_music
PushWord UserId ; Deallocate all of our memory PushWord UserId ; Deallocate all of our memory
_DisposeAll _DisposeAll
_QuitGS qtRec _QuitGS qtRec
@ -270,8 +264,9 @@ Fatal brk $00
; Position the screen with the botom-left corner of the tilemap visible ; Position the screen with the botom-left corner of the tilemap visible
MovePlayerToOrigin MovePlayerToOrigin
lda #0 ; Set the player's position lda #0 ; Set the player's position
jsr SetBG0XPos jsr SetBG0XPos
lda TileMapHeight lda TileMapHeight
asl asl
asl asl
@ -279,6 +274,7 @@ MovePlayerToOrigin
sec sec
sbc ScreenHeight sbc ScreenHeight
jsr SetBG0YPos jsr SetBG0YPos
rts rts
ClearBankLoad ClearBankLoad
@ -321,7 +317,7 @@ SetScreenMode cpx #9
asl asl
tax tax
lda #320 ; Calculate the screen offset lda #320 ; Calculate the screen offset
sec sec
sbc: ]ScreenModeWidth,x sbc: ]ScreenModeWidth,x
lsr lsr
@ -354,8 +350,8 @@ DoHUP
ldx #{160-12*4} ldx #{160-12*4}
ldy #$7777 ldy #$7777
jsr DrawString jsr DrawString
lda OneSecondCounter ; Number of elapsed seconds lda OneSecondCounter ; Number of elapsed seconds
ldx #{160-4*4} ; Render the word 4 charaters from right edge ldx #{160-4*4} ; Render the word 4 charaters from right edge
jsr DrawWord jsr DrawWord
lda #TicksStr lda #TicksStr
@ -376,7 +372,7 @@ DoTiles
:column equ 3 :column equ 3
:tile equ 5 :tile equ 5
pea $0000 ; Allocate local variable space pea $0000 ; Allocate local variable space
pea $0000 pea $0000
pea $0000 pea $0000
@ -410,18 +406,11 @@ DoTiles
cmp #26 cmp #26
bcc :rowloop bcc :rowloop
pla ; restore the stack pla ; restore the stack
pla pla
pla pla
rts rts
; Set up the code field and render it
DoFrame
lda #$FFFF
sta DirtyBits
jsr Render ; Render the play field
rts
; Load a binary file in the BG1 buffer ; Load a binary file in the BG1 buffer
DoLoadBG1 DoLoadBG1
lda BankLoad lda BankLoad
@ -450,7 +439,7 @@ DoLoadFG
ldx #FGName ldx #FGName
jsr LoadFile jsr LoadFile
ldx BankLoad ; Copy it into the code field ldx BankLoad ; Copy it into the code field
lda #0 lda #0
jsr CopyBinToField jsr CopyBinToField
rts rts
@ -458,10 +447,10 @@ DoLoadFG
; Load a simple picture format onto the SHR screen ; Load a simple picture format onto the SHR screen
DoLoadPic DoLoadPic
lda BankLoad lda BankLoad
ldx #ImageName ; Load+Unpack Boot Picture ldx #ImageName ; Load+Unpack Boot Picture
jsr LoadPicture ; X=Name, A=Bank to use for loading jsr LoadPicture ; X=Name, A=Bank to use for loading
ldx BankLoad ; Copy it into the code field ldx BankLoad ; Copy it into the code field
lda #0 lda #0
jsr CopyPicToField jsr CopyPicToField
rts rts
@ -507,7 +496,7 @@ CopyBinToField
stz :line_cnt stz :line_cnt
:rloop :rloop
lda :line_cnt ; get the pointer to the code field line lda :line_cnt ; get the pointer to the code field line
asl asl
tax tax
@ -516,78 +505,78 @@ CopyBinToField
lda BTableHigh,x lda BTableHigh,x
sta :dstptr+2 sta :dstptr+2
ldx #162 ; move backwards in the code field ldx #162 ; move backwards in the code field
ldy #0 ; move forward in the image data ldy #0 ; move forward in the image data
lda #82 ; keep a running column count lda #82 ; keep a running column count
sta :col_cnt sta :col_cnt
:cloop :cloop
phy phy
lda [:srcptr],y ; load the picture data lda [:srcptr],y ; load the picture data
cmp :mask_color cmp :mask_color
beq :transparent ; a value of $0000 is transparent beq :transparent ; a value of $0000 is transparent
jsr :toMask ; Infer a mask value for this. If it's $0000, then jsr :toMask ; Infer a mask value for this. If it's $0000, then
cmp #$0000 cmp #$0000
bne :mixed ; the data is solid, otherwise mixed bne :mixed ; the data is solid, otherwise mixed
; This is a solid word ; This is a solid word
:solid :solid
lda [:srcptr],y lda [:srcptr],y
ldy Col2CodeOffset,x ; Get the offset to the code from the line start ldy Col2CodeOffset,x ; Get the offset to the code from the line start
pha ; Save the data pha ; Save the data
lda #$00F4 ; PEA instruction lda #$00F4 ; PEA instruction
sta [:dstptr],y sta [:dstptr],y
iny iny
pla pla
sta [:dstptr],y ; PEA operand sta [:dstptr],y ; PEA operand
bra :next bra :next
:transparent :transparent
lda :mask_color ; Make sure we actually have to mask lda :mask_color ; Make sure we actually have to mask
cmp #$A5A5 cmp #$A5A5
beq :solid beq :solid
ldy Col2CodeOffset,x ; Get the offset to the code from the line start ldy Col2CodeOffset,x ; Get the offset to the code from the line start
lda #$B1 ; LDA (dp),y lda #$B1 ; LDA (dp),y
sta [:dstptr],y sta [:dstptr],y
iny iny
lda 1,s ; load the saved Y-index lda 1,s ; load the saved Y-index
ora #$4800 ; put a PHA after the offset ora #$4800 ; put a PHA after the offset
sta [:dstptr],y sta [:dstptr],y
bra :next bra :next
:mixed :mixed
sta :mask ; Save the mask sta :mask ; Save the mask
lda [:srcptr],y ; Refetch the screen data lda [:srcptr],y ; Refetch the screen data
sta :data sta :data
ldy Col2CodeOffset,x ; Get the offset into the code field ldy Col2CodeOffset,x ; Get the offset into the code field
lda #$4C ; JMP exception lda #$4C ; JMP exception
sta [:dstptr],y sta [:dstptr],y
iny iny
lda JTableOffset,x ; Get the address offset and add to the base address lda JTableOffset,x ; Get the address offset and add to the base address
clc clc
adc :dstptr adc :dstptr
sta [:dstptr],y sta [:dstptr],y
ldy JTableOffset,x ; This points to the code fragment ldy JTableOffset,x ; This points to the code fragment
lda 1,s ; load the offset lda 1,s ; load the offset
xba xba
ora #$00B1 ora #$00B1
sta [:dstptr],y ; write the LDA (--),y instruction sta [:dstptr],y ; write the LDA (--),y instruction
iny iny
iny iny
iny ; advance to the AND #imm operand iny ; advance to the AND #imm operand
lda :mask lda :mask
sta [:dstptr],y sta [:dstptr],y
iny iny
iny iny
iny ; advance to the ORA #imm operand iny ; advance to the ORA #imm operand
lda :mask lda :mask
eor #$FFFF ; invert the mask to clear up the data eor #$FFFF ; invert the mask to clear up the data
and :data and :data
sta [:dstptr],y sta [:dstptr],y
@ -616,10 +605,10 @@ CopyBinToField
:exit :exit
rts rts
:toMask pha ; save original :toMask pha ; save original
lda 1,s lda 1,s
eor :mask_color ; only identical bits produce zero eor :mask_color ; only identical bits produce zero
and #$F000 and #$F000
beq *+7 beq *+7
pea #$0000 pea #$0000
@ -661,7 +650,7 @@ CopyBinToField
sta 1,s sta 1,s
pla pla
sta 1,s ; pop the saved word sta 1,s ; pop the saved word
pla pla
rts rts
@ -686,7 +675,7 @@ CopyPicToField
stz :line_cnt stz :line_cnt
:rloop :rloop
lda :line_cnt ; get the pointer to the code field line lda :line_cnt ; get the pointer to the code field line
asl asl
tax tax
@ -695,70 +684,70 @@ CopyPicToField
lda BTableHigh,x lda BTableHigh,x
sta :dstptr+2 sta :dstptr+2
ldx #162 ; move backwards in the code field ldx #162 ; move backwards in the code field
ldy #0 ; move forward in the image data ldy #0 ; move forward in the image data
lda #80 ; keep a running column count lda #80 ; keep a running column count
; lda #82 ; keep a running column count ; lda #82 ; keep a running column count
sta :col_cnt sta :col_cnt
:cloop :cloop
phy phy
lda [:srcptr],y ; load the picture data lda [:srcptr],y ; load the picture data
beq :transparent ; a value of $0000 is transparent beq :transparent ; a value of $0000 is transparent
jsr :toMask ; Infer a mask value for this. If it's $0000, then jsr :toMask ; Infer a mask value for this. If it's $0000, then
bne :mixed ; the data is solid, otherwise mixed bne :mixed ; the data is solid, otherwise mixed
; This is a solid word ; This is a solid word
lda [:srcptr],y lda [:srcptr],y
ldy Col2CodeOffset,x ; Get the offset to the code from the line start ldy Col2CodeOffset,x ; Get the offset to the code from the line start
pha ; Save the data pha ; Save the data
lda #$00F4 ; PEA instruction lda #$00F4 ; PEA instruction
sta [:dstptr],y sta [:dstptr],y
iny iny
pla pla
sta [:dstptr],y ; PEA operand sta [:dstptr],y ; PEA operand
bra :next bra :next
:transparent :transparent
ldy Col2CodeOffset,x ; Get the offset to the code from the line start ldy Col2CodeOffset,x ; Get the offset to the code from the line start
lda #$B1 ; LDA (dp),y lda #$B1 ; LDA (dp),y
sta [:dstptr],y sta [:dstptr],y
iny iny
lda 1,s ; load the saved Y-index lda 1,s ; load the saved Y-index
ora #$4800 ; put a PHA after the offset ora #$4800 ; put a PHA after the offset
sta [:dstptr],y sta [:dstptr],y
bra :next bra :next
:mixed :mixed
sta :mask ; Save the mask sta :mask ; Save the mask
lda [:srcptr],y ; Refetch the screen data lda [:srcptr],y ; Refetch the screen data
sta :data sta :data
ldy Col2CodeOffset,x ; Get the offset into the code field ldy Col2CodeOffset,x ; Get the offset into the code field
lda #$4C ; JMP exception lda #$4C ; JMP exception
sta [:dstptr],y sta [:dstptr],y
iny iny
lda JTableOffset,x ; Get the address offset and add to the base address lda JTableOffset,x ; Get the address offset and add to the base address
clc clc
adc :dstptr adc :dstptr
sta [:dstptr],y sta [:dstptr],y
ldy JTableOffset,x ; This points to the code fragment ldy JTableOffset,x ; This points to the code fragment
lda 1,s ; load the offset lda 1,s ; load the offset
xba xba
ora #$00B1 ora #$00B1
sta [:dstptr],y ; write the LDA (--),y instruction sta [:dstptr],y ; write the LDA (--),y instruction
iny iny
iny iny
iny ; advance to the AND #imm operand iny ; advance to the AND #imm operand
lda :mask lda :mask
sta [:dstptr],y sta [:dstptr],y
iny iny
iny iny
iny ; advance to the ORA #imm operand iny ; advance to the ORA #imm operand
lda :data lda :data
sta [:dstptr],y sta [:dstptr],y
@ -828,9 +817,9 @@ CopyBinToBG1
sta :srcptr sta :srcptr
stx :srcptr+2 stx :srcptr+2
sty :dstptr+2 ; Everything goes into this bank sty :dstptr+2 ; Everything goes into this bank
; Advance over the header ; Advance over the header
lda :srcptr lda :srcptr
clc clc
adc #8 adc #8
@ -838,14 +827,14 @@ CopyBinToBG1
stz :line_cnt stz :line_cnt
:rloop :rloop
lda :line_cnt ; get the pointer to the code field line lda :line_cnt ; get the pointer to the code field line
asl asl
tax tax
lda BG1YTable,x lda BG1YTable,x
sta :dstptr sta :dstptr
ldy #0 ; move forward in the image data and image data ldy #0 ; move forward in the image data and image data
:cloop :cloop
lda [:srcptr],y lda [:srcptr],y
sta [:dstptr],y sta [:dstptr],y
@ -856,17 +845,17 @@ CopyBinToBG1
cpy #164 cpy #164
bcc :cloop bcc :cloop
lda [:srcptr] ; Duplicate the last byte in the extra space at the end of the line lda [:srcptr] ; Duplicate the last byte in the extra space at the end of the line
sta [:dstptr],y sta [:dstptr],y
lda :srcptr lda :srcptr
clc clc
adc #164 ; Each line is 328 pixels adc #164 ; Each line is 328 pixels
sta :srcptr sta :srcptr
inc :line_cnt inc :line_cnt
lda :line_cnt lda :line_cnt
cmp #208 ; A total of 208 lines cmp #208 ; A total of 208 lines
bcc :rloop bcc :rloop
rts rts
@ -898,7 +887,7 @@ OneSecHandler mx %11
sep #$20 sep #$20
ldal $E0C032 ldal $E0C032
and #%10111111 ;clear IRQ source and #%10111111 ;clear IRQ source
stal $E0C032 stal $E0C032
pla pla
@ -924,9 +913,13 @@ BlitInit
stz ScreenTileHeight stz ScreenTileHeight
stz ScreenTileWidth stz ScreenTileWidth
stz StartX stz StartX
stz OldStartX
stz StartXMod164 stz StartXMod164
stz StartY stz StartY
stz OldStartY
stz StartYMod208 stz StartYMod208
stz EngineMode stz EngineMode
stz DirtyBits stz DirtyBits
stz LastPatchOffset stz LastPatchOffset
@ -1017,26 +1010,26 @@ GetBorderColor lda #0000
rts rts
; Set the border color to the accumulator value. ; Set the border color to the accumulator value.
SetBorderColor sep #$20 ; ACC = $X_Y, REG = $W_Z SetBorderColor sep #$20 ; ACC = $X_Y, REG = $W_Z
eorl BORDER_REG ; ACC = $(X^Y)_(Y^Z) eorl BORDER_REG ; ACC = $(X^Y)_(Y^Z)
and #$0F ; ACC = $0_(Y^Z) and #$0F ; ACC = $0_(Y^Z)
eorl BORDER_REG ; ACC = $W_(Y^Z^Z) = $W_Y eorl BORDER_REG ; ACC = $W_(Y^Z^Z) = $W_Y
stal BORDER_REG stal BORDER_REG
rep #$20 rep #$20
rts rts
; Clear to SHR screen to a specific color ; 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 :clearloop dex
dex dex
stal SHR_SCREEN,x ;screen location stal SHR_SCREEN,x ;screen location
bne :clearloop ;loop until we've worked our way down to 0 bne :clearloop ;loop until we've worked our way down to 0
rts rts
; Set a palette values ; Set a palette values
; A = palette number, X = palette address ; A = palette number, X = palette address
SetPalette SetPalette
and #$000F ; palette values are 0 - 15 and each palette is 32 bytes and #$000F ; palette values are 0 - 15 and each palette is 32 bytes
asl asl
asl asl
asl asl
@ -1054,7 +1047,7 @@ SetPalette
rts rts
; Initialize the SCB ; Initialize the SCB
SetSCBs ldx #$0100 ;set all $100 scbs to A SetSCBs ldx #$0100 ;set all $100 scbs to A
:scbloop dex :scbloop dex
dex dex
stal SHR_SCB,x stal SHR_SCB,x
@ -1093,21 +1086,21 @@ GetVBL sep #$20
ldal VBL_HORZ_REG ldal VBL_HORZ_REG
asl asl
ldal VBL_VERT_REG 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 rep #$20
and #$00FF and #$00FF
rts rts
WaitForVBL sep #$20 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 bmi :wait1
:wait2 ldal VBL_STATE_REG :wait2 ldal VBL_STATE_REG
bpl :wait2 ; spin until transition into VBL bpl :wait2 ; spin until transition into VBL
rep #$20 rep #$20
rts rts
WaitForKey sep #$20 WaitForKey sep #$20
stal KBD_STROBE_REG ; clear the strobe stal KBD_STROBE_REG ; clear the strobe
:WFK ldal KBD_REG :WFK ldal KBD_REG
bpl :WFK bpl :WFK
rep #$20 rep #$20
@ -1120,9 +1113,9 @@ ClearKeyboardStrobe sep #$20
rts rts
ReadControl ReadControl
pea $0000 ; low byte = key code, high byte = %------AB pea $0000 ; low byte = key code, high byte = %------AB
ldal OPTION_KEY_REG ; 'B' button ldal OPTION_KEY_REG ; 'B' button
and #$0080 and #$0080
beq :BNotDown beq :BNotDown
@ -1140,9 +1133,9 @@ ReadControl
sta 1,s sta 1,s
:ANotDown :ANotDown
ldal KBD_STROBE_REG ; read the keyboard ldal KBD_STROBE_REG ; read the keyboard
bit #$0080 bit #$0080
beq :KbdNotDwn ; check the key-down status beq :KbdNotDwn ; check the key-down status
and #$007f and #$007f
ora 1,s ora 1,s
sta 1,s sta 1,s
@ -1154,43 +1147,43 @@ ReadControl
; Graphics helpers ; Graphics helpers
LoadPicture 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 bcc :loadOK
rts rts
:loadOK :loadOK
jsr UnpackPicture ; A=Packed Size jsr UnpackPicture ; A=Packed Size
rts rts
UnpackPicture sta UP_PackedSize ; Size of Packed Data UnpackPicture sta UP_PackedSize ; Size of Packed Data
lda #$8000 ; Size of output Data Buffer lda #$8000 ; Size of output Data Buffer
sta UP_UnPackedSize sta UP_UnPackedSize
lda BankLoad ; Banc de chargement / Decompression lda BankLoad ; Banc de chargement / Decompression
sta UP_Packed+1 ; Packed Data sta UP_Packed+1 ; Packed Data
clc clc
adc #$0080 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 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 PushWord #0 ; Space for Result : Number of bytes unpacked
PushLong UP_Packed ; Pointer to buffer containing the packed data PushLong UP_Packed ; Pointer to buffer containing the packed data
PushWord UP_PackedSize ; Size of the Packed Data PushWord UP_PackedSize ; Size of the Packed Data
PushLong #UP_UnPacked ; Pointer to Pointer to unpacked buffer PushLong #UP_UnPacked ; Pointer to Pointer to unpacked buffer
PushLong #UP_UnPackedSize ; Pointer to a Word containing size of unpacked data PushLong #UP_UnPackedSize ; Pointer to a Word containing size of unpacked data
_UnPackBytes _UnPackBytes
pla ; Number of byte unpacked pla ; Number of byte unpacked
rts rts
UP_Packed hex 00000000 ; Address of Packed Data UP_Packed hex 00000000 ; Address of Packed Data
UP_PackedSize hex 0000 ; Size of Packed Data UP_PackedSize hex 0000 ; Size of Packed Data
UP_UnPacked hex 00000000 ; Address of Unpacked Data Buffer (modified) UP_UnPacked hex 00000000 ; Address of Unpacked Data Buffer (modified)
UP_UnPackedSize hex 0000 ; Size of Unpacked Data Buffer (modified) UP_UnPackedSize hex 0000 ; Size of Unpacked Data Buffer (modified)
; Basic I/O function to load files ; Basic I/O function to load files
LoadFile LoadFile
stx openRec+4 ; X=File, A=Bank (high word) assumed zero for low stx openRec+4 ; X=File, A=Bank (high word) assumed zero for low
stz readRec+4 stz readRec+4
sta readRec+6 sta readRec+6
jsr ClearBankLoad jsr ClearBankLoad
@ -1212,7 +1205,7 @@ LoadFile
:closeFile _CloseGS closeRec :closeFile _CloseGS closeRec
clc clc
lda eofRec+4 ; File Size lda eofRec+4 ; File Size
rts rts
:openReadErr jsr :closeFile :openReadErr jsr :closeFile
@ -1247,22 +1240,22 @@ FGName strl '1/fg1.bin'
MasterId ds 2 MasterId ds 2
UserId ds 2 UserId ds 2
openRec dw 2 ; pCount openRec dw 2 ; pCount
ds 2 ; refNum ds 2 ; refNum
adrl FGName ; pathname adrl FGName ; pathname
eofRec dw 2 ; pCount eofRec dw 2 ; pCount
ds 2 ; refNum ds 2 ; refNum
ds 4 ; eof ds 4 ; eof
readRec dw 4 ; pCount readRec dw 4 ; pCount
ds 2 ; refNum ds 2 ; refNum
ds 4 ; dataBuffer ds 4 ; dataBuffer
ds 4 ; requestCount ds 4 ; requestCount
ds 4 ; transferCount ds 4 ; transferCount
closeRec dw 1 ; pCount closeRec dw 1 ; pCount
ds 2 ; refNum ds 2 ; refNum
qtRec adrl $0000 qtRec adrl $0000
da $00 da $00
@ -1272,6 +1265,7 @@ qtRec adrl $0000
put Actions.s put Actions.s
put font.s put font.s
put Render.s put Render.s
put Overlay.s
put blitter/Blitter.s put blitter/Blitter.s
put blitter/Horz.s put blitter/Horz.s
put blitter/PEISlammer.s put blitter/PEISlammer.s
@ -1291,17 +1285,6 @@ qtRec adrl $0000

View File

@ -43,11 +43,12 @@ Addr2ToString xba
; A=Value ; A=Value
; X=Screen offset ; X=Screen offset
DrawWord phx ; Save register value DrawWord phx ; Save register value
phy
ldy #WordBuff+1 ldy #WordBuff+1
jsr WordToString jsr WordToString
ply
plx plx
lda #WordBuff lda #WordBuff
ldy #$7777
jsr DrawString jsr DrawString
rts rts
@ -145,6 +146,8 @@ Addr3Buff str '000000' ; str adds leading length byte

View File

@ -93,6 +93,12 @@ Render
; ldy #8 ; ldy #8
; jsr _PEISlam ; jsr _PEISlam
; ldx #0 ; Blit the full virtual buffer to the screen
; ldy #16
; jsr _BltRange
; jsr Overlay
ldx #0 ; Blit the full virtual buffer to the screen ldx #0 ; Blit the full virtual buffer to the screen
ldy ScreenHeight ldy ScreenHeight
jsr _BltRange jsr _BltRange
@ -101,6 +107,12 @@ Render
ldx ScreenHeight ldx ScreenHeight
jsr _RestoreBG0Opcodes jsr _RestoreBG0Opcodes
lda StartY
sta OldStartY
lda StartX
sta OldStartX
stz DirtyBits
rts rts
@ -112,3 +124,10 @@ Render

View File

@ -10,6 +10,17 @@
; in actual games since the primary background is often large empty areas, or runs ; in actual games since the primary background is often large empty areas, or runs
; of repeating tiles. ; of repeating tiles.
; Debug locations
LastTop ds 2
LastBottom ds 2
LastLeft ds 2
LastRight ds 2
; The ranges are [:Left, :Right] and [:Top, :Bottom], so :Right can be, at most, 40
; if we are drawing all 41 tiles (Index 0 through 40). The :Bottom value can be
; at most 25.
MAX_TILE_X equ 40
MAX_TILE_Y equ 25
; _UpdateBG0TileMap ; _UpdateBG0TileMap
; ;
@ -23,13 +34,13 @@ _UpdateBG0TileMap
:Top equ tmp2 :Top equ tmp2
:Bottom equ tmp3 :Bottom equ tmp3
:Width equ tmp4 ; Used in DrawRectBG0 :Width equ tmp4 ; Used in DrawRectBG0
:Height equ tmp5 :Height equ tmp5
:MulA equ tmp6 ; Scratch space for multiplication :MulA equ tmp6 ; Scratch space for multiplication
:MulB equ tmp7 :MulB equ tmp7
:Offset equ tmp8 ; Address offset into the tilemap :Offset equ tmp8 ; Address offset into the tilemap
:Span equ tmp9 :Span equ tmp9
:GlobalTileIdxX equ tmp10 :GlobalTileIdxX equ tmp10
@ -38,35 +49,24 @@ _UpdateBG0TileMap
:BlkX equ tmp12 :BlkX equ tmp12
:BlkY equ tmp13 :BlkY equ tmp13
:Refresh equ tmp14 lda StartY ; calculate the tile index of the current location
cmp #$FFFF
lda #0
rol
sta :Refresh ; 1 if A = $FFFF, 0 otherwise
lda StartY ; calculate the tile index of the current location
and #$FFF8
lsr lsr
lsr lsr
lsr lsr
sta BG0TileOriginY sta BG0TileOriginY
lda OldStartY lda OldStartY
and #$FFF8
lsr lsr
lsr lsr
lsr lsr
sta OldBG0TileOriginY sta OldBG0TileOriginY
lda StartX lda StartX
and #$FFFC
lsr lsr
lsr lsr
sta BG0TileOriginX sta BG0TileOriginX
lda OldStartX lda OldStartX
and #$FFFC
lsr lsr
lsr lsr
sta OldBG0TileOriginX sta OldBG0TileOriginX
@ -91,48 +91,48 @@ _UpdateBG0TileMap
; | | ; | |
; +--- Left Right --+ ; +--- Left Right --+
stz :Left ; prepare to do the entire screen stz :Left ; prepare to do the entire screen
lda ScreenTileWidth ; and then whack off the parts lda ScreenTileWidth ; and then whack off the parts
sta :Right ; that are not needed sta :Right ; that are not needed
lda StartX
and #$0003 ; If not tile-aligned, then we need to draw one extra column
beq *+2
inc :Right
stz :Top stz :Top ; since the ranges are inclusive, we are
lda ScreenTileHeight lda ScreenTileHeight ; always going to be drawing width+1 tiles
sta :Bottom sta :Bottom ; which takes care of edge tiles.
and #$0007
beq *+2
inc :Bottom
; If we are supposed to refresh the whole field, just do that and return ; If we are supposed to refresh the whole field, just do that and return
lda :Refresh
lda #DIRTY_BIT_BG0_REFRESH
bit DirtyBits
beq :NoRefresh beq :NoRefresh
jmp :DrawRectBG0 ; Let the DrawRectBG0 RTS take care of the return for us trb DirtyBits ; Clear the dirty bit
:FullScreen jmp :DrawRectBG0 ; Let the DrawRectBG0 RTS take care of the return for us
:NoRefresh :NoRefresh
lda BG0TileOriginY lda BG0TileOriginY
cmp OldBG0TileOriginY cmp OldBG0TileOriginY
beq :NoYUpdate ; if equal, don't change Y beq :NoYUpdate ; if equal, don't change Y
sec sec
sbc OldBG0TileOriginY ; find the difference; D = Y_new - Y_old sbc OldBG0TileOriginY ; find the difference; D = Y_new - Y_old
bpl :DoBottom ; if we scrolled up, fill in the bottom row(s) bpl :DoBottom ; if we scrolled up, fill in the bottom row(s)
eor #$FFFF ; if we scrolled down, Y_new < Y_old and we need eor #$FFFF ; if we scrolled down, Y_new < Y_old and we need
sta :Bottom ; to fill in the top row(s) from 0 to Y_new - Y_old - 1 cmp :Bottom ; to fill in the top row(s) from 0 to Y_new - Y_old - 1
bcs :FullScreen ; If the displacement was very large, just fill in the whole screen
sta :Bottom
bra :DoYUpdate bra :DoYUpdate
:DoBottom :DoBottom
eor #$FFFF ; same explanation as above, except we are filling in from eor #$FFFF ; same explanation as above, except we are filling in from
inc a ; Bottom - (Y_new - Y_old) to Bottom inc ; Bottom - (Y_new - Y_old) to Bottom
clc clc
adc ScreenTileHeight adc ScreenTileHeight
bmi :FullScreen
sta :Top sta :Top
:DoYUpdate :DoYUpdate
jsr :DrawRectBG0 ; Fill in the rectangle. jsr :DrawRectBG0 ; Fill in the rectangle.
; We performed an update in the Y-direction, so now change the bounds so ; We performed an update in the Y-direction, so now change the bounds so
; an update in the X-direction will not draw too many rows ; an update in the X-direction will not draw too many rows
@ -155,14 +155,14 @@ _UpdateBG0TileMap
lda :Top lda :Top
beq :drewTop beq :drewTop
dec a ; already did Y to HEIGHT, so only need to draw from dec ; already did Y to HEIGHT, so only need to draw from
sta :Bottom ; 0 to (Y-1) for any horizontal updates sta :Bottom ; 0 to (Y-1) for any horizontal updates
stz :Top stz :Top
bra :NoYUpdate bra :NoYUpdate
:drewTop :drewTop
lda :Bottom ; opposite, did 0 to Y lda :Bottom ; opposite, did 0 to Y
inc a ; so do Y+1 to HEIGHT inc ; so do Y+1 to HEIGHT
sta :Top sta :Top
lda ScreenTileHeight lda ScreenTileHeight
sta :Bottom sta :Bottom
@ -186,17 +186,19 @@ _UpdateBG0TileMap
; The Top an Bottom are set the the correct values to draw in whatever potential range of tiles ; The Top an Bottom are set the the correct values to draw in whatever potential range of tiles
; need to be draws if there was any horizontal displacement ; need to be draws if there was any horizontal displacement
:NoYUpdate :NoYUpdate
lda BG0TileOriginX ; Did the first column of the tile map change from before? lda BG0TileOriginX ; Did the first column of the tile map change from before?
cmp OldBG0TileOriginX ; Did it change from before? cmp OldBG0TileOriginX ; Did it change from before?
beq :NoXUpdate ; no, so we can ignore this beq :NoXUpdate ; no, so we can ignore this
sec sec
sbc OldBG0TileOriginX ; find the difference sbc OldBG0TileOriginX ; find the difference
bpl :DoRightSide ; did we move in a pos or neg? bpl :DoRightSide ; did we move in a pos or neg?
; Handle the two sides in an analagous way as the vertical code ; Handle the two sides in an analagous way as the vertical code
eor #$FFFF eor #$FFFF
cmp :Right
bcs :FullScreen
sta :Right sta :Right
bra :DoXUpdate bra :DoXUpdate
@ -205,33 +207,41 @@ _UpdateBG0TileMap
inc inc
clc clc
adc ScreenTileWidth adc ScreenTileWidth
bmi :FullScreen
sta :Left sta :Left
:DoXUpdate :DoXUpdate
jsr :DrawRectBG0 ; Fill in the rectangle. jsr :DrawRectBG0 ; Fill in the rectangle.
:NoXUpdate :NoXUpdate
rts rts
;:Debug
; lda :Top ; Debugging
; sta LastTop
; lda :Bottom
; sta LastBottom
; lda :Left
; sta LastLeft
; lda :Right
; sta LastRight
; rts
; This is a private subroutine that draws in tiles into the code fields using the ; This is a private subroutine that draws in tiles into the code fields using the
; data from the tilemap and the local :Top, :Left, :Bottom and :Right parameters. ; data from the tilemap and the local :Top, :Left, :Bottom and :Right parameters.
;
; The ranges are [:Left, :Right) and [:Top, :Bottom), so :Right can be, at most, 41
; if we are drawing all 41 tiles (Index 0 through 40). The :Bottom value can be
; at most 26.
MAX_TILE_X equ 40
MAX_TILE_Y equ 25
:DrawRectBG0 :DrawRectBG0
lda :Bottom lda :Bottom
sec sec
sbc :Top sbc :Top
sta :Height ; Maximum value of 25 inc
sta :Height ; Maximum value of 26 (top = 0, bottom = 25)
lda :Right lda :Right
sec sec
sbc :Left sbc :Left
sta :Width ; Maximum value of 40 inc
sta :Width ; Maximum value of 41 (left = 0, right = 40)
; Compute the offset into the tile array of the top-left corner ; Compute the offset into the tile array of the top-left corner
@ -242,57 +252,63 @@ MAX_TILE_Y equ 25
lda :Top lda :Top
clc clc
adc BG0TileOriginY ; This is the global verical index adc BG0TileOriginY ; This is the global verical index
sta :GlobalTileIdxY sta :GlobalTileIdxY
ldx TileMapWidth ldx TileMapWidth
jsr :MulAX jsr :MulAX
clc clc
adc :GlobalTileIdxX adc :GlobalTileIdxX
asl ; Double for word sizes asl ; Double for word sizes
sta :Offset ; Stash the pointer offset in Y sta :Offset ; Stash the pointer offset in Y
; Draw the tiles
lda TileMapWidth lda TileMapWidth
sec sec
sbc :Width sbc :Width
asl ; This is the number of bytes to move the Offset to advance from the end of asl ; This is the number of bytes to move the Offset to advance from the end of
sta :Span ; one line to the beginning of the next sta :Span ; one line to the beginning of the next
; Now we need to figure out the code field tile coordinate of corner of ; Now we need to figure out the code field tile coordinate of corner of
; play field. That is, becuase the screen is scrolling, the location of ; play field. That is, becuase the screen is scrolling, the location of
; tile (0, 0) could be anywhere within the code field ; tile (0, 0) could be anywhere within the code field
lda StartYMod208 ; This is the code field line that is at the top of the screen lda StartYMod208 ; This is the code field line that is at the top of the screen
and #$FFF8 ; Clamp to the nearest block and #$FFF8 ; Clamp to the nearest block
lsr lsr
lsr lsr
lsr ; Could optimize because the Tile code shifts back.... lsr ; Could optimize because the Tile code shifts back....
clc clc
adc :Top adc :Top
sta :BlkY ; This is the Y-block we start drawing from cmp #MAX_TILE_Y+1 ; Top can be less than or equal to 25
bcc *+5
sbc #MAX_TILE_Y+1
sta :BlkY ; This is the Y-block we start drawing from
lda StartXMod164 ; Dx the same thing for X, except only need to clamp by 4 lda StartXMod164 ; Dx the same thing for X, except only need to clamp by 4
and #$FFFC and #$FFFC
lsr lsr
lsr lsr
clc clc
adc :Left adc :Left
cmp #MAX_TILE_X+1 ; Left can be less than or equal to 40
bcc *+5
sbc #MAX_TILE_X+1
sta :BlkX sta :BlkX
; Call the copy tile routine to blit the tile data into the playfield ; Call the copy tile routine to blit the tile data into the playfield
; ;
; A = Tile ID (0 - 1023) ; A = Tile ID (0 - 1023)
; X = Tile column (0 - 40) ; X = Tile column (0 - 40)
; Y = Tile row (0 - 25) ; Y = Tile row (0 - 25)
pei :BlkX ; cache the starting X-block index to restore later pei :BlkX ; cache the starting X-block index to restore later
pei :Width ; cache the Width value to restore later pei :Width ; cache the Width value to restore later
:yloop :yloop
:xloop :xloop
ldy :Offset ; Set up the arguments and call the tile blitter ldy :Offset ; Set up the arguments and call the tile blitter
lda [TileMapPtr],y lda [TileMapPtr],y
iny ; pre-increment the address. A bit faster than two "INC DP" instructions iny ; pre-increment the address. A bit faster than two "INC DP" instructions
iny iny
sty :Offset sty :Offset
@ -302,46 +318,45 @@ MAX_TILE_Y equ 25
lda :BlkX lda :BlkX
inc inc
cmp #MAX_TILE_X+1 ; If we go past the physical block index, wrap around cmp #MAX_TILE_X+1 ; If we go past the maximum block index, wrap around
bcc *+5 bcc *+5
lda #0 lda #0
sta :BlkX sta :BlkX
dec :Width ; Decrement out count dec :Width ; Decrement out count
bne :xloop bne :xloop
lda :Offset ; Move to the next line of the Tile Map lda :Offset ; Move to the next line of the Tile Map
clc clc
adc :Span adc :Span
sta :Offset sta :Offset
lda 3,s ; Reset the BlkX lda 3,s ; Reset the BlkX
sta :BlkX sta :BlkX
lda 1,s ; Reset the width lda 1,s ; Reset the width
sta :Width sta :Width
lda :BlkY ; The y lookup has a double0length array, may not need the bounds check lda :BlkY ; The y lookup has a double-length array, may not need the bounds check
inc inc
cmp #MAX_TILE_Y+1 cmp #MAX_TILE_Y+1
bcc *+5 bcc *+5
lda #0 lda #0
sta :BlkY sta :BlkY
dec :Height ; Have we done all of the rows? dec :Height ; Have we done all of the rows?
bne :yloop bne :yloop
pla ; Pop off cached values pla ; Pop off cached values
pla pla
rts rts
; Quick multiplication of the accumulator and x-register ; Quick multiplication of the accumulator and x-register
; A = A * X ; A = A * X
:MulAX :MulAX
stx :MulA stx :MulA
cmp :MulA ; Put the smaller value in MulA (less shifts on average) cmp :MulA ; Put the smaller value in MulA (less shifts on average)
bcc :swap bcc :swap
sta :MulB sta :MulB
bra :entry bra :entry
@ -357,13 +372,13 @@ MAX_TILE_Y equ 25
; branch on the inner loop ; branch on the inner loop
:loop :loop
lsr :MulA ; shift out the LSB lsr :MulA ; shift out the LSB
bcc :skip ; zero is no multiply bcc :skip ; zero is no multiply
clc clc
adc :MulB adc :MulB
:skip :skip
asl :MulB ; double the multplicand asl :MulB ; double the multplicand
ldx :MulA ldx :MulA
bne :loop bne :loop
@ -388,6 +403,60 @@ MAX_TILE_Y equ 25

View File

@ -1,81 +1,84 @@
; Direct page locations used by the engine ; Direct page locations used by the engine
ScreenHeight equ 0 ; Height of the playfield in scan lines ScreenHeight equ 0 ; Height of the playfield in scan lines
ScreenWidth equ 2 ; Width of the playfield in bytes ScreenWidth equ 2 ; Width of the playfield in bytes
ScreenY0 equ 4 ; First vertical line on the physical screen of the playfield ScreenY0 equ 4 ; First vertical line on the physical screen of the playfield
ScreenY1 equ 6 ; End of playfield on the physical screen. If the height is 20 and Y0 is ScreenY1 equ 6 ; End of playfield on the physical screen. If the height is 20 and Y0 is
ScreenX0 equ 8 ; 100, then ScreenY1 = 120. ScreenX0 equ 8 ; 100, then ScreenY1 = 120.
ScreenX1 equ 10 ScreenX1 equ 10
ScreenTileHeight equ 12 ; Height of the playfield in 8x8 blocks ScreenTileHeight equ 12 ; Height of the playfield in 8x8 blocks
ScreenTileWidth equ 14 ; Width of the playfield in 8x8 blocks ScreenTileWidth equ 14 ; Width of the playfield in 8x8 blocks
StartX equ 16 ; Which code buffer byte is the left edge of the screen. Range = 0 to 167 StartX equ 16 ; Which code buffer byte is the left edge of the screen. Range = 0 to 167
StartY equ 18 ; Which code buffer line is the top of the screen. Range = 0 to 207 StartY equ 18 ; Which code buffer line is the top of the screen. Range = 0 to 207
EngineMode equ 20 ; Defined the mode/capabilities that are enabled EngineMode equ 20 ; Defined the mode/capabilities that are enabled
; bit 0: 0 = Single Background, 1 = Parallax ; bit 0: 0 = Single Background, 1 = Parallax
DirtyBits equ 22 ; Identify values that have changed between frames DirtyBits equ 22 ; Identify values that have changed between frames
BG1DataBank equ 24 ; Data bank that holds BG1 layer data BG1DataBank equ 24 ; Data bank that holds BG1 layer data
BG1AltBank equ 26 ; Alternate BG1 bank BG1AltBank equ 26 ; Alternate BG1 bank
BlitterDP equ 28 ; Direct page address the holder blitter data BlitterDP equ 28 ; Direct page address the holder blitter data
OldStartX equ 30 OldStartX equ 30
OldStartY equ 32 OldStartY equ 32
LastPatchOffset equ 34 ; Offset into code field that was patched with BRA instructions LastPatchOffset equ 34 ; Offset into code field that was patched with BRA instructions
StartXMod164 equ 36 StartXMod164 equ 36
StartYMod208 equ 38 StartYMod208 equ 38
BG1StartX equ 40 ; Logical offset of the second background BG1StartX equ 40 ; Logical offset of the second background
BG1StartXMod164 equ 42 BG1StartXMod164 equ 42
BG1StartY equ 44 BG1StartY equ 44
BG1StartYMod208 equ 46 BG1StartYMod208 equ 46
OldBG1StartX equ 48 OldBG1StartX equ 48
OldBG1StartY equ 50 OldBG1StartY equ 50
BG1OffsetIndex equ 52 BG1OffsetIndex equ 52
BG0TileOriginX equ 54 ; Coordinate in the tile map that corresponds to the top-left corner BG0TileOriginX equ 54 ; Coordinate in the tile map that corresponds to the top-left corner
BG0TileOriginY equ 56 BG0TileOriginY equ 56
OldBG0TileOriginX equ 58 OldBG0TileOriginX equ 58
OldBG0TileOriginY equ 60 OldBG0TileOriginY equ 60
BG1TileOriginX equ 62 ; Coordinate in the tile map that corresponds to the top-left corner BG1TileOriginX equ 62 ; Coordinate in the tile map that corresponds to the top-left corner
BG1TileOriginY equ 64 BG1TileOriginY equ 64
OldBG1TileOriginX equ 66 OldBG1TileOriginX equ 66
OldBG1TileOriginY equ 68 OldBG1TileOriginY equ 68
TileMapWidth equ 70 TileMapWidth equ 70
TileMapHeight equ 72 TileMapHeight equ 72
TileMapPtr equ 74 TileMapPtr equ 74
Next equ 78 Next equ 78
BankLoad equ 128 BankLoad equ 128
blttmp equ 192 ; 32 bytes of local cache/scratch space blttmp equ 192 ; 32 bytes of local cache/scratch space
tmp8 equ 224 tmp8 equ 224
tmp9 equ 226 tmp9 equ 226
tmp10 equ 228 tmp10 equ 228
tmp11 equ 230 tmp11 equ 230
tmp12 equ 232 tmp12 equ 232
tmp13 equ 234 tmp13 equ 234
tmp14 equ 236 tmp14 equ 236
tmp15 equ 238 tmp15 equ 238
tmp0 equ 240 ; 16 bytes of temporary space to be used as scratch tmp0 equ 240 ; 16 bytes of temporary space to be used as scratch
tmp1 equ 242 tmp1 equ 242
tmp2 equ 244 tmp2 equ 244
tmp3 equ 246 tmp3 equ 246
tmp4 equ 248 tmp4 equ 248
tmp5 equ 250 tmp5 equ 250
tmp6 equ 252 tmp6 equ 252
tmp7 equ 254 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
DIRTY_BIT_BG0_REFRESH equ $0010
DIRTY_BIT_BG1_REFRESH equ $0020
DIRTY_BIT_BG0_X equ $0001
DIRTY_BIT_BG0_Y equ $0002
DIRTY_BIT_BG1_X equ $0004
DIRTY_BIT_BG1_Y equ $0008

View File

@ -42,6 +42,7 @@ CopyTile
asl ; asl will clear the carry bit asl ; asl will clear the carry bit
tax tax
lda Col2CodeOffset,x lda Col2CodeOffset,x
clc
adc BTableLow,y adc BTableLow,y
tay tay
@ -239,3 +240,9 @@ CopyTile

View File

@ -37,6 +37,7 @@ DrawString
NextChar lda ]F_CharIdx NextChar lda ]F_CharIdx
cmp ]F_Length cmp ]F_Length
bne :notDone bne :notDone
ldy ]F_StrClr ;restore the color pattern
pld pld
pla pla
pla pla
@ -662,5 +663,6 @@ s_Template hex 00000000