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

@ -1,22 +1,42 @@
; Collection of the EXTernal labels exported by GTE. This is the closest thing
; we have to an API definition.
EngineStartUp EXT
EngineShutDown EXT
EngineStartUp EXT
EngineShutDown EXT
SetScreenMode EXT
ReadControl EXT
Render EXT
SetScreenMode EXT
ReadControl EXT
AddTimer EXT
RemoveTimer EXT
DoTimers EXT
SetBG0XPos EXT
SetBG0YPos EXT
SetBG1XPos EXT
SetBG1YPos EXT
CopyBG0Tile EXT
CopyBG1Tile EXT
Render EXT
StartScript EXT
StopScript EXT
; Rotation
ApplyBG1XPosAngle EXT
ApplyBG1YPosAngle EXT
CopyPicToField EXT
CopyBinToField EXT
CopyBinToBG1 EXT
AddTimer EXT
RemoveTimer EXT
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
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