Refactor original demo driver to use GTE Core; move functions around

This commit is contained in:
Lucas Scharenbroich 2021-08-26 08:52:43 -05:00
parent d261745347
commit fe18759759
20 changed files with 657 additions and 774 deletions

View File

@ -1,4 +1,4 @@
; IIgs Game Engine
; Fatdog Demos
TYP $B3 ; S16 file
DSK GTEShooter
@ -20,3 +20,4 @@
ALI BANK
SNA RotData

View File

@ -2,6 +2,7 @@
DSK MAINSEG
use EDS.GSOS.MACS.s
use Tool222.Macs.s
use ../../src/GTE.s
use ../../src/Defs.s
@ -121,55 +122,3 @@ StackAddress ds 2
PUT sprites/Ships.s

View File

@ -13,7 +13,7 @@
"scripts": {
"test": "npm run build && build-image.bat %npm_package_config_cadius% && %npm_package_config_gsport%",
"debug": "%npm_package_config_crossrunner% src\\GTETestApp -Source src\\GTETestApp_S02_MAINSEG_Output.txt -Debug -CompatibilityLayer",
"build": "%npm_package_config_merlin32% -V %npm_package_config_macros% src\\App.s",
"build": "%npm_package_config_merlin32% -V .\\macros src\\App.s",
"build:watch": "watch \"npm run build\" src",
"build:assets-smw": "node ./tools/png2iigs.js ./assets/donut-plains-2-8-color.png ./emu/bg1a.bin --start-index 6 && node ./tools/png2iigs.js ./assets/donut-plains-2-8-color-shift.png ./emu/bg1b.bin --start-index 6 && node ./tools/png2iigs.js ./assets/donut-plains-1-6-color.png ./emu/fg1.bin",
"build:assets-fatdog": "node ./tools/png2iigs.js ./assets/armada-7-color.png ./emu/bg1a.bin --start-index 8 && node ./tools/png2iigs.js ./assets/armada-7-color-shift.png ./emu/bg1b.bin --start-index 8 && node ./tools/png2iigs.js ./assets/armada-7-color-shuffle.png ./emu/fg1.bin --start-index 1",

View File

@ -1,13 +1,13 @@
MoveLeft
clc
adc StartX ; Increment the virtual X-position
jsr SetBG0XPos
jsl SetBG0XPos
lda StartX
lsr
jsr SetBG1XPos
jsl SetBG1XPos
jsr _Render
jsl Render
rts
MoveRight
@ -17,13 +17,13 @@ MoveRight
sbc 1,s
bpl *+5
lda #0
jsr SetBG0XPos
jsl SetBG0XPos
lda StartX
lsr
jsr SetBG1XPos
jsl SetBG1XPos
jsr _Render
jsl Render
pla
rts
@ -39,14 +39,14 @@ MoveUp
cmp 1,s
bcc *+4
lda 1,s
jsr SetBG0YPos
jsl SetBG0YPos
pla
; lda StartY
; lsr
; jsr SetBG1YPos
; jsl SetBG1YPos
jsr _Render
jsl Render
rts
MoveDown
@ -56,13 +56,13 @@ MoveDown
sbc 1,s
bpl *+5
lda #0
jsr SetBG0YPos
jsl SetBG0YPos
; lda StartY
; lsr
; jsr SetBG1YPos
; jsl SetBG1YPos
jsr _Render
jsl Render
pla
rts
@ -71,25 +71,17 @@ oldOneSecondCounter ds 2
frameCount ds 2
lastTick ds 2
Demo
lda OneSecondCounter
ldal OneSecondCounter
sta oldOneSecondCounter
stz frameCount
; Set a timer to fire every 16 ticks
; lda #6
; sta Timers
; sta Timers+2
; lda #UpdateBG1Rotation
; sta Timers+4
; Every 3 ticks (20 fps) cycle some colors
lda #3
sta Timers+8
sta Timers+10
lda #DoColorCycle
sta Timers+12
ldx #^DoColorCycle
ldy #3
jsl AddTimer
:loop
PushLong #0
_GetTick
@ -108,7 +100,7 @@ Demo
; jsr MoveLeft
jsr UpdateBG1Rotation
; jsr DoColorCycle
jsr _Render
jsl Render
inc frameCount
@ -122,7 +114,7 @@ Demo
rts
:nokey
lda OneSecondCounter
ldal OneSecondCounter
cmp oldOneSecondCounter
beq :loop
@ -190,7 +182,7 @@ AngleUp
sbc #64
sta angle
jsr _ApplyAngle
jsr _Render
jsl Render
rts
AngleDown
@ -201,7 +193,7 @@ AngleDown
adc #64
sta angle
jsr _ApplyAngle
jsr _Render
jsl Render
rts
angle dw 0
@ -225,74 +217,13 @@ _ApplyAngle
ldal x_angles,x ; load the address of addressed for this angle
tay
phx
jsr _ApplyBG1XPosAngle
jsl ApplyBG1XPosAngle
plx
ldal y_angles,x ; load the address of addresses for this angle
tay
jsr _ApplyBG1YPosAngle
jsl ApplyBG1YPosAngle
rts
; A collection of 8 timers that are triggered when their countdown
; goes below zero. Each timer takes up 8 bytes
;
; A timer can fire multiple times during a singular evaluation. For example, if the
; timer delay is set to 1 and 3 VBL ticks happen, then the timer delta is -2, will fire,
; have the delay added and get -1, fire again, increment to zero, first again and then
; finally reset to 1.
;
; +0 counter decremented by the number of ticks since last run
; +2 reset copied into counter when triggered. 0 turns off the timer.
; +4 addr address of time routine
; +6 reserved
MAX_TIMERS equ 4
Timers ds 8*MAX_TIMERS
; Countdown the timers
;
; A = number of elapsed ticks
_DoTimers
pha
ldx #0
:loop
lda Timers,x ; A zero means do not fire
beq :skip
sec
sbc 1,s ; subtract the number of ticks
sta Timers,x
:retry beq :fire ; getting <= zero triggers
bpl :skip
:fire pha ; Save the counter
phx ; Save our index
jsr (Timers+4,x)
plx
pla
clc
adc Timers+2,x ; Add the increment
sta Timers,x ; Store in the count
bra :retry ; See if we have >0 ticks to wait until the next trigger
:skip txa
clc
adc #8
tax
cpx #8*MAX_TIMERS
bcc :loop
pla
rts

View File

@ -124,6 +124,14 @@ AllocOneBank PushLong #0
rts
; Variation that returns the pointer in the X/A registers (X = low, A = high)
AllocBank ENT
phb
phk
plb
jsr AllocOneBank2
plb
rtl
AllocOneBank2 PushLong #0
PushLong #$10000
PushWord UserId
@ -134,3 +142,4 @@ AllocOneBank2 PushLong #0
pla ; high address 00XX of the new handle (bank)
_Deref
rts

View File

@ -3,8 +3,13 @@
REL
DSK MAINSEG
use Locator.Macs.s
use Misc.Macs.s
use EDS.GSOS.MACS.s
put ./GTE.s
use Tool222.Macs.s
use Util.Macs.s
use ./GTE.s
use ./Defs.s
mx %00
@ -16,7 +21,6 @@ NO_INTERRUPTS equ 1 ; turn off for crossrunne
NO_MUSIC equ 1 ; turn music + tool loading off
; Typical init
phk
plb
@ -25,18 +29,13 @@ NO_MUSIC equ 1 ; turn music + tool loadi
ldx #0
jsl SetScreenMode
jsr _InitBG1 ; Initialize the second background
lda #0
jsr _ClearBG1Buffer
; Set up our level data
jsr BG0SetUp
jsr BG1SetUp
; Allocate room to load data
jsr AllocOneBank2 ; Alloc 64KB for Load/Unpack
jsl AllocBank ; Alloc 64KB for Load/Unpack
sta BankLoad ; Store "Bank Pointer"
jsr MovePlayerToOrigin ; Put the player at the beginning of the map
@ -86,7 +85,7 @@ EvtLoop
sec
sbc #'1'
tax
jsr SetScreenMode
jsl SetScreenMode
jsr MovePlayerToOrigin
brl EvtLoop
@ -158,9 +157,9 @@ StartMusic
; Position the screen with the botom-left corner of the tilemap visible
MovePlayerToOrigin
lda #0 ; Set the player's position
jsr SetBG0XPos
jsl SetBG0XPos
lda #0
jsr SetBG1XPos
jsl SetBG1XPos
lda TileMapHeight
asl
@ -169,9 +168,9 @@ MovePlayerToOrigin
sec
sbc ScreenHeight
pha
jsr SetBG0YPos
jsl SetBG0YPos
pla
jsr SetBG1YPos
jsl SetBG1YPos
rts
@ -237,7 +236,7 @@ DoTiles
lda :column,s
tax
lda :tile,s
jsr CopyTile
jsl CopyBG0Tile
lda :column,s
inc
@ -297,423 +296,7 @@ DoLoadPic
ldx BankLoad ; Copy it into the code field
lda #0
jsr CopyPicToField
rts
; Copy a raw data file into the code field
;
; A=low word of picture address
; X=high word of pixture address
CopyBinToField
:srcptr equ tmp0
:line_cnt equ tmp2
:dstptr equ tmp3
:col_cnt equ tmp5
:mask equ tmp6
:data equ tmp7
:mask_color equ tmp8
sta :srcptr
stx :srcptr+2
; Check that this is a GTERAW image and save the transparent color
ldy #4
:chkloop
lda [:srcptr],y
cmp :headerStr,y
beq *+3
rts
dey
dey
bpl :chkloop
; We have a valid header, now get the transparency word and load it in
ldy #6
lda [:srcptr],y
sta :mask_color
; Advance over the header
lda :srcptr
clc
adc #8
sta :srcptr
stz :line_cnt
:rloop
lda :line_cnt ; get the pointer to the code field line
asl
tax
lda BTableLow,x
sta :dstptr
lda BTableHigh,x
sta :dstptr+2
; ldx #162 ; move backwards in the code field
ldy #0 ; move forward in the image data
lda #82 ; keep a running column count
sta :col_cnt
:cloop
phy
lda [:srcptr],y ; load the picture data
cmp :mask_color
beq :transparent ; a value of $0000 is transparent
jsr :toMask ; Infer a mask value for this. If it's $0000, then
cmp #$0000
bne :mixed ; the data is solid, otherwise mixed
; This is a solid word
:solid
lda [:srcptr],y
pha ; Save the data
lda Col2CodeOffset,y ; Get the offset to the code from the line start
tay
lda #$00F4 ; PEA instruction
sta [:dstptr],y
iny
pla
sta [:dstptr],y ; PEA operand
bra :next
:transparent
lda :mask_color ; Make sure we actually have to mask
cmp #$A5A5
beq :solid
lda Col2CodeOffset,y ; Get the offset to the code from the line start
tay
lda #$B1 ; LDA (dp),y
sta [:dstptr],y
iny
lda 1,s ; load the saved Y-index
ora #$4800 ; put a PHA after the offset
sta [:dstptr],y
bra :next
:mixed
sta :mask ; Save the mask
lda [:srcptr],y ; Refetch the screen data
sta :data
tyx
lda Col2CodeOffset,y ; Get the offset into the code field
tay
lda #$4C ; JMP exception
sta [:dstptr],y
iny
lda JTableOffset,x ; Get the address offset and add to the base address
clc
adc :dstptr
sta [:dstptr],y
ldy JTableOffset,x ; This points to the code fragment
lda 1,s ; load the offset
xba
ora #$00B1
sta [:dstptr],y ; write the LDA (--),y instruction
iny
iny
iny ; advance to the AND #imm operand
lda :mask
sta [:dstptr],y
iny
iny
iny ; advance to the ORA #imm operand
lda :mask
eor #$FFFF ; invert the mask to clear up the data
and :data
sta [:dstptr],y
:next
ply
; dex
; dex
iny
iny
dec :col_cnt
bne :cloop
lda :srcptr
clc
adc #164
sta :srcptr
inc :line_cnt
lda :line_cnt
cmp #200
bcs :exit
brl :rloop
:exit
rts
:toMask pha ; save original
lda 1,s
eor :mask_color ; only identical bits produce zero
and #$F000
beq *+7
pea #$0000
bra *+5
pea #$F000
lda 3,s
eor :mask_color
and #$0F00
beq *+7
pea #$0000
bra *+5
pea #$0F00
lda 5,s
eor :mask_color
and #$00F0
beq *+7
pea #$0000
bra *+5
pea #$00F0
lda 7,s
eor :mask_color
and #$000F
beq *+7
lda #$0000
bra *+5
lda #$000F
ora 1,s
sta 1,s
pla
ora 1,s
sta 1,s
pla
ora 1,s
sta 1,s
pla
sta 1,s ; pop the saved word
pla
rts
:headerStr asc 'GTERAW'
; Copy a loaded SHR picture into the code field
;
; A=low word of picture address
; X=high workd of pixture address
;
; Picture must be within one bank
CopyPicToField
:srcptr equ tmp0
:line_cnt equ tmp2
:dstptr equ tmp3
:col_cnt equ tmp5
:mask equ tmp6
:data equ tmp7
sta :srcptr
stx :srcptr+2
stz :line_cnt
:rloop
lda :line_cnt ; get the pointer to the code field line
asl
tax
lda BTableLow,x
sta :dstptr
lda BTableHigh,x
sta :dstptr+2
; ldx #162 ; move backwards in the code field
ldy #0 ; move forward in the image data
lda #80 ; keep a running column count
; lda #82 ; keep a running column count
sta :col_cnt
:cloop
phy
lda [:srcptr],y ; load the picture data
beq :transparent ; a value of $0000 is transparent
jsr :toMask ; Infer a mask value for this. If it's $0000, then
bne :mixed ; the data is solid, otherwise mixed
; This is a solid word
lda [:srcptr],y
pha ; Save the data
lda Col2CodeOffset,y ; Get the offset to the code from the line start
tay
lda #$00F4 ; PEA instruction
sta [:dstptr],y
iny
pla
sta [:dstptr],y ; PEA operand
bra :next
:transparent
lda Col2CodeOffset,y ; Get the offset to the code from the line start
tay
lda #$B1 ; LDA (dp),y
sta [:dstptr],y
iny
lda 1,s ; load the saved Y-index
ora #$4800 ; put a PHA after the offset
sta [:dstptr],y
bra :next
:mixed
sta :mask ; Save the mask
lda [:srcptr],y ; Refetch the screen data
sta :data
tyx
lda Col2CodeOffset,y ; Get the offset into the code field
tay
lda #$4C ; JMP exception
sta [:dstptr],y
iny
lda JTableOffset,x ; Get the address offset and add to the base address
clc
adc :dstptr
sta [:dstptr],y
ldy JTableOffset,x ; This points to the code fragment
lda 1,s ; load the offset
xba
ora #$00B1
sta [:dstptr],y ; write the LDA (--),y instruction
iny
iny
iny ; advance to the AND #imm operand
lda :mask
sta [:dstptr],y
iny
iny
iny ; advance to the ORA #imm operand
lda :data
sta [:dstptr],y
:next
ply
; dex
; dex
iny
iny
dec :col_cnt
bne :cloop
lda :srcptr
clc
; adc #164
adc #160
sta :srcptr
inc :line_cnt
lda :line_cnt
; cmp #208
cmp #200
bcs :exit
brl :rloop
:exit
rts
:toMask bit #$F000
beq *+7
and #$0FFF
bra *+5
ora #$F000
bit #$0F00
beq *+7
and #$F0FF
bra *+5
ora #$0F00
bit #$00F0
beq *+7
and #$FF0F
bra *+5
ora #$00F0
bit #$000F
beq *+7
and #$FFF0
bra *+5
ora #$000F
rts
; Copy a binary image data file into BG1. Assumes the file is the correct size.
;
; A=low word of picture address
; X=high word of pixture address
; Y=high word of BG1 bank
CopyBinToBG1
:srcptr equ tmp0
:line_cnt equ tmp2
:dstptr equ tmp3
:col_cnt equ tmp5
sta :srcptr
stx :srcptr+2
sty :dstptr+2 ; Everything goes into this bank
; Advance over the header
lda :srcptr
clc
adc #8
sta :srcptr
stz :line_cnt
:rloop
lda :line_cnt ; get the pointer to the code field line
asl
tax
lda BG1YTable,x
sta :dstptr
ldy #0 ; move forward in the image data and image data
:cloop
lda [:srcptr],y
sta [:dstptr],y
iny
iny
cpy #164
bcc :cloop
lda [:srcptr] ; Duplicate the last byte in the extra space at the end of the line
sta [:dstptr],y
lda :srcptr
clc
adc #164 ; Each line is 328 pixels
sta :srcptr
inc :line_cnt
lda :line_cnt
cmp #208 ; A total of 208 lines
bcc :rloop
jsl CopyPicToField
rts
;DefaultPalette dw $0000,$007F,$0090,$0FF0
@ -842,8 +425,6 @@ BG1AltDataFile strl '1/bg1b.bin'
ImageName strl '1/test.pic'
FGName strl '1/fg1.bin'
;MasterId ds 2
;UserId ds 2
openRec dw 2 ; pCount
ds 2 ; refNum
@ -865,6 +446,11 @@ closeRec dw 1 ; pCount
qtRec adrl $0000
da $00
PUT App.Msg.s
PUT Actions.s
PUT font.s
PUT Overlay.s
PUT App.TileMapBG0.s
PUT App.TileMapBG1.s
@ -885,6 +471,13 @@ qtRec adrl $0000

View File

@ -12,7 +12,12 @@
ALI None ; Boundary Alignment (None)
SNA Main
; Segment #2 -- 64KB Tile Memory
; Segment #2 -- Core GTE Code
ASM Core.s
SNA Core
; Segment #3 -- 64KB Tile Memory
ASM App.TileSet.s
DS 0
@ -20,7 +25,7 @@
; ALI BANK
SNA Tiles
; Segment #3 -- Rotation table data
; Segment #4 -- Rotation table data
ASM RotData.s
DS 0
@ -28,4 +33,3 @@
ALI BANK
SNA RotData

View File

@ -170,7 +170,8 @@ OneSecHandler mx %11
rtl
mx %00
OneSecondCounter dw 0
OneSecondCounter ENT
dw 0
OldOneSecVec ds 4
VBLTASK hex 00000000
@ -353,11 +354,9 @@ ReadControl ENT
put App.Init.s
put Graphics.s
; put App.Msg.s
; put Actions.s
; put font.s
put Render.s
; put Overlay.s
put Timer.s
put Script.s
put blitter/Blitter.s
put blitter/Horz.s
put blitter/PEISlammer.s
@ -365,64 +364,9 @@ ReadControl ENT
put blitter/Template.s
put blitter/Tiles.s
put blitter/Vert.s
put blitter/BG0.s
put blitter/BG1.s
put TileMap.s

View File

@ -6,8 +6,23 @@ EngineShutDown EXT
SetScreenMode EXT
ReadControl EXT
SetBG0XPos EXT
SetBG0YPos EXT
SetBG1XPos EXT
SetBG1YPos EXT
CopyBG0Tile EXT
CopyBG1Tile EXT
Render EXT
; Rotation
ApplyBG1XPosAngle EXT
ApplyBG1YPosAngle EXT
CopyPicToField EXT
CopyBinToField EXT
CopyBinToBG1 EXT
AddTimer EXT
RemoveTimer EXT
DoTimers EXT
@ -15,8 +30,13 @@ DoTimers EXT
StartScript EXT
StopScript EXT
; Allocate a full 64K bank
AllocBank EXT
; Data references
;
; Super Hires line address lookup table for convenience
ScreenAddr EXT
OneSecondCounter EXT
BlitBuff EXT

View File

@ -10,6 +10,13 @@ InitGraphics
ldx #DefaultPalette
lda #0
jsr SetPalette
jsr _InitBG0 ; Initialize the background layers
jsr _InitBG1
lda #0
jsr _ClearBG1Buffer
rts
DefaultPalette dw $0000,$007F,$0090,$0FF0
@ -116,3 +123,5 @@ WaitForVBL sep #$20
rts

View File

@ -7,29 +7,29 @@ Overlay
ldx #{160*:top+4}
jsr DrawString
ldx #{160*:top+12}
lda LastTop
jsr DrawWord
; lda LastTop
; jsr DrawWord
lda #BottomLabel
ldx #{160*:top+32}
jsr DrawString
ldx #{160*:top+40}
lda LastBottom
jsr DrawWord
; lda LastBottom
; jsr DrawWord
lda #LeftLabel
ldx #{160*:top+60}
jsr DrawString
ldx #{160*:top+68}
lda LastLeft
jsr DrawWord
; lda LastLeft
; jsr DrawWord
lda #RightLabel
ldx #{160*:top+88}
jsr DrawString
ldx #{160*:top+96}
lda LastRight
jsr DrawWord
; lda LastRight
; jsr DrawWord
lda #XLabel
@ -99,3 +99,4 @@ STWLabel str 'STW:'
STHLabel str 'STH:'

View File

@ -119,7 +119,7 @@ _DoScriptSeq
plx ; Pop off the update command address
bit #$8000 ; If the stop bit is set, we're done with this sequence
beq :continue ; Otherwise, keep going and fetch the next command word
beq :loop ; Otherwise, keep going and fetch the next command word
txa ; save the current command address
plb ; restore the data bank and the timer index
@ -147,82 +147,26 @@ _SetPalEntry
_SwapPalEntry txy
ldx ARG1,y ; Load palette values
ldx: ARG1,y ; Load palette values
ldal SHR_PALETTES,x
pha
ldx ARG2,y
ldx: ARG2,y
ldal SHR_PALETTES,x
ldx ARG1,y ; and swap
ldx: ARG1,y ; and swap
stal SHR_PALETTES,x
ldx ARG2,y
ldx: ARG2,y
pla
stal SHR_PALETTES,x
rts
_UserCallback lda ARG1,x
_UserCallback lda: ARG1,x
sta :dispatch+1
lda ARG1+1,x
lda: ARG1+1,x
sta :dispatch+2
lda ARG3,x
lda: ARG3,x
:dispatch jsl $000000
rts

View File

@ -313,7 +313,7 @@ _UpdateBG0TileMap
ldx :BlkX
ldy :BlkY
jsr CopyTile
jsr _CopyBG0Tile
lda :BlkX
inc
@ -611,7 +611,7 @@ _DrawRectBG1
ldx :BlkX
ldy :BlkY
jsr CopyTileBG1
jsr _CopyBG1Tile
lda :BlkX
inc
@ -663,3 +663,4 @@ _DrawRectBG1

View File

@ -84,22 +84,22 @@ AddTimer ENT
bra :notimers
:freeslot pla
sta Timer+0,x ; set the counter and
stz Timer+2,x ; default to a zero reset value
sta Timers+0,x ; set the counter and
stz Timers+2,x ; default to a zero reset value
pla
sta Timer+4,x ; set the callback address
sta Timers+4,x ; set the callback address
pla
sta Timer+6,x
sta Timers+6,x
stz Timer+8,x ; Clear the user data space
stz Timer+10,x ; Clear the user data space
stz Timer+12,x ; Clear the user data space
stz Timer+14,x ; Clear the user data space
stz Timers+8,x ; Clear the user data space
stz Timers+10,x ; Clear the user data space
stz Timers+12,x ; Clear the user data space
stz Timers+14,x ; Clear the user data space
plp
bcc :oneshot
lda Timer+0,x ; if not a one-shot, put the counter
sta Timer+2,x ; value into the reset field
lda Timers+0,x ; if not a one-shot, put the counter
sta Timers+2,x ; value into the reset field
:oneshot plb
txa ; return the slot ID and a success status
@ -127,10 +127,10 @@ RemoveTimer ENT
bcs :exit
tax
stz Timer,x
stz Timer+2,x
stz Timer+4,x
stz Timer+6,x
stz Timers,x
stz Timers+2,x
stz Timers+4,x
stz Timers+6,x
:exit
plb
@ -240,5 +240,6 @@ _DoTimers

386
src/blitter/BG0.s Normal file
View File

@ -0,0 +1,386 @@
; Support routinges for the primary background
_InitBG0
jsr _ApplyBG0YPos
jsr _ApplyBG0XPos
rts
; Copy a raw data file into the code field
;
; A=low word of picture address
; X=high word of pixture address
CopyBinToField ENT
phb
phk
plb
jsr _CopyBinToField
plb
rtl
_CopyBinToField
:srcptr equ tmp0
:line_cnt equ tmp2
:dstptr equ tmp3
:col_cnt equ tmp5
:mask equ tmp6
:data equ tmp7
:mask_color equ tmp8
sta :srcptr
stx :srcptr+2
; Check that this is a GTERAW image and save the transparent color
ldy #4
:chkloop
lda [:srcptr],y
cmp :headerStr,y
beq *+3
rts
dey
dey
bpl :chkloop
; We have a valid header, now get the transparency word and load it in
ldy #6
lda [:srcptr],y
sta :mask_color
; Advance over the header
lda :srcptr
clc
adc #8
sta :srcptr
stz :line_cnt
:rloop
lda :line_cnt ; get the pointer to the code field line
asl
tax
lda BTableLow,x
sta :dstptr
lda BTableHigh,x
sta :dstptr+2
; ldx #162 ; move backwards in the code field
ldy #0 ; move forward in the image data
lda #82 ; keep a running column count
sta :col_cnt
:cloop
phy
lda [:srcptr],y ; load the picture data
cmp :mask_color
beq :transparent ; a value of $0000 is transparent
jsr :toMask ; Infer a mask value for this. If it's $0000, then
cmp #$0000
bne :mixed ; the data is solid, otherwise mixed
; This is a solid word
:solid
lda [:srcptr],y
pha ; Save the data
lda Col2CodeOffset,y ; Get the offset to the code from the line start
tay
lda #$00F4 ; PEA instruction
sta [:dstptr],y
iny
pla
sta [:dstptr],y ; PEA operand
bra :next
:transparent
lda :mask_color ; Make sure we actually have to mask
cmp #$A5A5
beq :solid
lda Col2CodeOffset,y ; Get the offset to the code from the line start
tay
lda #$B1 ; LDA (dp),y
sta [:dstptr],y
iny
lda 1,s ; load the saved Y-index
ora #$4800 ; put a PHA after the offset
sta [:dstptr],y
bra :next
:mixed
sta :mask ; Save the mask
lda [:srcptr],y ; Refetch the screen data
sta :data
tyx
lda Col2CodeOffset,y ; Get the offset into the code field
tay
lda #$4C ; JMP exception
sta [:dstptr],y
iny
lda JTableOffset,x ; Get the address offset and add to the base address
clc
adc :dstptr
sta [:dstptr],y
ldy JTableOffset,x ; This points to the code fragment
lda 1,s ; load the offset
xba
ora #$00B1
sta [:dstptr],y ; write the LDA (--),y instruction
iny
iny
iny ; advance to the AND #imm operand
lda :mask
sta [:dstptr],y
iny
iny
iny ; advance to the ORA #imm operand
lda :mask
eor #$FFFF ; invert the mask to clear up the data
and :data
sta [:dstptr],y
:next
ply
; dex
; dex
iny
iny
dec :col_cnt
bne :cloop
lda :srcptr
clc
adc #164
sta :srcptr
inc :line_cnt
lda :line_cnt
cmp #200
bcs :exit
brl :rloop
:exit
rts
:toMask pha ; save original
lda 1,s
eor :mask_color ; only identical bits produce zero
and #$F000
beq *+7
pea #$0000
bra *+5
pea #$F000
lda 3,s
eor :mask_color
and #$0F00
beq *+7
pea #$0000
bra *+5
pea #$0F00
lda 5,s
eor :mask_color
and #$00F0
beq *+7
pea #$0000
bra *+5
pea #$00F0
lda 7,s
eor :mask_color
and #$000F
beq *+7
lda #$0000
bra *+5
lda #$000F
ora 1,s
sta 1,s
pla
ora 1,s
sta 1,s
pla
ora 1,s
sta 1,s
pla
sta 1,s ; pop the saved word
pla
rts
:headerStr asc 'GTERAW'
; Copy a loaded SHR picture into the code field
;
; A=low word of picture address
; X=high workd of pixture address
;
; Picture must be within one bank
CopyPicToField ENT
phb
phk
plb
jsr _CopyPicToField
plb
rtl
_CopyPicToField
:srcptr equ tmp0
:line_cnt equ tmp2
:dstptr equ tmp3
:col_cnt equ tmp5
:mask equ tmp6
:data equ tmp7
sta :srcptr
stx :srcptr+2
stz :line_cnt
:rloop
lda :line_cnt ; get the pointer to the code field line
asl
tax
lda BTableLow,x
sta :dstptr
lda BTableHigh,x
sta :dstptr+2
; ldx #162 ; move backwards in the code field
ldy #0 ; move forward in the image data
lda #80 ; keep a running column count
; lda #82 ; keep a running column count
sta :col_cnt
:cloop
phy
lda [:srcptr],y ; load the picture data
beq :transparent ; a value of $0000 is transparent
jsr :toMask ; Infer a mask value for this. If it's $0000, then
bne :mixed ; the data is solid, otherwise mixed
; This is a solid word
lda [:srcptr],y
pha ; Save the data
lda Col2CodeOffset,y ; Get the offset to the code from the line start
tay
lda #$00F4 ; PEA instruction
sta [:dstptr],y
iny
pla
sta [:dstptr],y ; PEA operand
bra :next
:transparent
lda Col2CodeOffset,y ; Get the offset to the code from the line start
tay
lda #$B1 ; LDA (dp),y
sta [:dstptr],y
iny
lda 1,s ; load the saved Y-index
ora #$4800 ; put a PHA after the offset
sta [:dstptr],y
bra :next
:mixed
sta :mask ; Save the mask
lda [:srcptr],y ; Refetch the screen data
sta :data
tyx
lda Col2CodeOffset,y ; Get the offset into the code field
tay
lda #$4C ; JMP exception
sta [:dstptr],y
iny
lda JTableOffset,x ; Get the address offset and add to the base address
clc
adc :dstptr
sta [:dstptr],y
ldy JTableOffset,x ; This points to the code fragment
lda 1,s ; load the offset
xba
ora #$00B1
sta [:dstptr],y ; write the LDA (--),y instruction
iny
iny
iny ; advance to the AND #imm operand
lda :mask
sta [:dstptr],y
iny
iny
iny ; advance to the ORA #imm operand
lda :data
sta [:dstptr],y
:next
ply
; dex
; dex
iny
iny
dec :col_cnt
bne :cloop
lda :srcptr
clc
; adc #164
adc #160
sta :srcptr
inc :line_cnt
lda :line_cnt
; cmp #208
cmp #200
bcs :exit
brl :rloop
:exit
rts
:toMask bit #$F000
beq *+7
and #$0FFF
bra *+5
ora #$F000
bit #$0F00
beq *+7
and #$F0FF
bra *+5
ora #$0F00
bit #$00F0
beq *+7
and #$FF0F
bra *+5
ora #$00F0
bit #$000F
beq *+7
and #$FFF0
bra *+5
ora #$000F
rts

View File

@ -4,7 +4,74 @@ _InitBG1
jsr _ApplyBG1XPos
rts
SetBG1XPos
; Copy a binary image data file into BG1. Assumes the file is the correct size.
;
; A=low word of picture address
; X=high word of pixture address
; Y=high word of BG1 bank
CopyBinToBG1 ENT
phb
phk
plb
jsr _CopyBinToBG1
plb
rtl
_CopyBinToBG1
:srcptr equ tmp0
:line_cnt equ tmp2
:dstptr equ tmp3
:col_cnt equ tmp5
sta :srcptr
stx :srcptr+2
sty :dstptr+2 ; Everything goes into this bank
; Advance over the header
lda :srcptr
clc
adc #8
sta :srcptr
stz :line_cnt
:rloop
lda :line_cnt ; get the pointer to the code field line
asl
tax
lda BG1YTable,x
sta :dstptr
ldy #0 ; move forward in the image data and image data
:cloop
lda [:srcptr],y
sta [:dstptr],y
iny
iny
cpy #164
bcc :cloop
lda [:srcptr] ; Duplicate the last byte in the extra space at the end of the line
sta [:dstptr],y
lda :srcptr
clc
adc #164 ; Each line is 328 pixels
sta :srcptr
inc :line_cnt
lda :line_cnt
cmp #208 ; A total of 208 lines
bcc :rloop
rts
SetBG1XPos ENT
jsr _SetBG1XPos
rtl
_SetBG1XPos
cmp BG1StartX
beq :out ; Easy, if nothing changed, then nothing changes
@ -19,7 +86,11 @@ SetBG1XPos
:out rts
SetBG1YPos
SetBG1YPos ENT
jsr _SetBG1YPos
rtl
_SetBG1YPos
cmp BG1StartY
beq :out ; Easy, if nothing changed, then nothing changes
@ -82,6 +153,14 @@ _ApplyBG1XPos
rts
ANGLEBNK ext
ApplyBG1XPosAngle ENT
phb
phk
plb
jsr _ApplyBG1XPosAngle
plb
rtl
_ApplyBG1XPosAngle
; phy
@ -146,6 +225,13 @@ _ClearBG1Buffer
plb
rts
ApplyBG1YPosAngle ENT
phb
phk
plb
jsr _ApplyBG1YPosAngle
plb
rtl
_ApplyBG1YPosAngle
:virt_line equ tmp0

View File

@ -12,7 +12,11 @@
; continuously overwrite it.
;
; We assume that there is a clean code field in this routine
SetBG0XPos
SetBG0XPos ENT
jsr _SetBG0XPos
rtl
_SetBG0XPos
cmp StartX
beq :out ; Easy, if nothing changed, then nothing changes
@ -746,17 +750,3 @@ SetCodeEntryOpcode
sta CODE_ENTRY_OPCODE+$1000,y
sta: CODE_ENTRY_OPCODE+$0000,y
:bottom rts

View File

@ -229,7 +229,8 @@ RTable ds 400
ds 400
; Array of addresses for the banks that hold the blitter.
BlitBuff ds 4*13
BlitBuff ENT
ds 4*13
; The blitter table (BTable) is a double-length table that holds the full 4-byte address of each
; line of the blit fields. We decompose arrays of pointers into separate high and low words so
@ -258,3 +259,4 @@ BG1YOffsetTable lup 26

View File

@ -667,14 +667,22 @@ dyn_masked
plx
rts
; CopyTile
; CopyBG0Tile
;
; A low-level function that copies 8x8 tiles directly into the code field space.
;
; A = Tile ID (0 - 511)
; X = Tile column (0 - 40)
; Y = Tile row (0 - 25)
CopyTile
CopyBG0Tile ENT
phb
phk
plb
jsr _CopyBG0Tile
plb
rtl
_CopyBG0Tile
phb ; save the current bank
phx ; save the original x-value
pha ; save the tile ID
@ -734,7 +742,15 @@ CopyTile
; A = Tile ID (0 - 511)
; X = Tile column (0 - 40)
; Y = Tile row (0 - 25)
CopyTileBG1
CopyBG1Tile
phb
phk
plb
jsr _CopyBG1Tile
plb
rtl
_CopyBG1Tile
phb ; save the current bank
phx ; save the original x-value
pha ; save the tile ID
@ -769,11 +785,3 @@ CopyTileBG1

View File

@ -6,7 +6,11 @@
; SetBG0YPos
;
; Set the virtual position of the primary background layer.
SetBG0YPos
SetBG0YPos ENT
jsr _SetBG0YPos
rtl
_SetBG0YPos
cmp StartY
beq :out ; Easy, if nothing changed, then nothing changes