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 TYP $B3 ; S16 file
DSK GTEShooter DSK GTEShooter
@ -20,3 +20,4 @@
ALI BANK ALI BANK
SNA RotData SNA RotData

View File

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

View File

@ -13,7 +13,7 @@
"scripts": { "scripts": {
"test": "npm run build && build-image.bat %npm_package_config_cadius% && %npm_package_config_gsport%", "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", "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: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-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", "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 MoveLeft
clc clc
adc StartX ; Increment the virtual X-position adc StartX ; Increment the virtual X-position
jsr SetBG0XPos jsl SetBG0XPos
lda StartX lda StartX
lsr lsr
jsr SetBG1XPos jsl SetBG1XPos
jsr _Render jsl Render
rts rts
MoveRight MoveRight
@ -17,13 +17,13 @@ MoveRight
sbc 1,s sbc 1,s
bpl *+5 bpl *+5
lda #0 lda #0
jsr SetBG0XPos jsl SetBG0XPos
lda StartX lda StartX
lsr lsr
jsr SetBG1XPos jsl SetBG1XPos
jsr _Render jsl Render
pla pla
rts rts
@ -39,14 +39,14 @@ MoveUp
cmp 1,s cmp 1,s
bcc *+4 bcc *+4
lda 1,s lda 1,s
jsr SetBG0YPos jsl SetBG0YPos
pla pla
; lda StartY ; lda StartY
; lsr ; lsr
; jsr SetBG1YPos ; jsl SetBG1YPos
jsr _Render jsl Render
rts rts
MoveDown MoveDown
@ -56,13 +56,13 @@ MoveDown
sbc 1,s sbc 1,s
bpl *+5 bpl *+5
lda #0 lda #0
jsr SetBG0YPos jsl SetBG0YPos
; lda StartY ; lda StartY
; lsr ; lsr
; jsr SetBG1YPos ; jsl SetBG1YPos
jsr _Render jsl Render
pla pla
rts rts
@ -71,25 +71,17 @@ oldOneSecondCounter ds 2
frameCount ds 2 frameCount ds 2
lastTick ds 2 lastTick ds 2
Demo Demo
lda OneSecondCounter ldal OneSecondCounter
sta oldOneSecondCounter sta oldOneSecondCounter
stz frameCount 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 ; Every 3 ticks (20 fps) cycle some colors
lda #3
sta Timers+8
sta Timers+10
lda #DoColorCycle lda #DoColorCycle
sta Timers+12 ldx #^DoColorCycle
ldy #3
jsl AddTimer
:loop :loop
PushLong #0 PushLong #0
_GetTick _GetTick
@ -108,7 +100,7 @@ Demo
; jsr MoveLeft ; jsr MoveLeft
jsr UpdateBG1Rotation jsr UpdateBG1Rotation
; jsr DoColorCycle ; jsr DoColorCycle
jsr _Render jsl Render
inc frameCount inc frameCount
@ -122,7 +114,7 @@ Demo
rts rts
:nokey :nokey
lda OneSecondCounter ldal OneSecondCounter
cmp oldOneSecondCounter cmp oldOneSecondCounter
beq :loop beq :loop
@ -190,7 +182,7 @@ AngleUp
sbc #64 sbc #64
sta angle sta angle
jsr _ApplyAngle jsr _ApplyAngle
jsr _Render jsl Render
rts rts
AngleDown AngleDown
@ -201,7 +193,7 @@ AngleDown
adc #64 adc #64
sta angle sta angle
jsr _ApplyAngle jsr _ApplyAngle
jsr _Render jsl Render
rts rts
angle dw 0 angle dw 0
@ -225,74 +217,13 @@ _ApplyAngle
ldal x_angles,x ; load the address of addressed for this angle ldal x_angles,x ; load the address of addressed for this angle
tay tay
phx phx
jsr _ApplyBG1XPosAngle jsl ApplyBG1XPosAngle
plx plx
ldal y_angles,x ; load the address of addresses for this angle ldal y_angles,x ; load the address of addresses for this angle
tay tay
jsr _ApplyBG1YPosAngle jsl ApplyBG1YPosAngle
rts 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 rts
; Variation that returns the pointer in the X/A registers (X = low, A = high) ; 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 AllocOneBank2 PushLong #0
PushLong #$10000 PushLong #$10000
PushWord UserId PushWord UserId
@ -134,3 +142,4 @@ AllocOneBank2 PushLong #0
pla ; high address 00XX of the new handle (bank) pla ; high address 00XX of the new handle (bank)
_Deref _Deref
rts rts

View File

@ -3,8 +3,13 @@
REL REL
DSK MAINSEG DSK MAINSEG
use Locator.Macs.s
use Misc.Macs.s
use EDS.GSOS.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 mx %00
@ -16,7 +21,6 @@ NO_INTERRUPTS equ 1 ; turn off for crossrunne
NO_MUSIC equ 1 ; turn music + tool loading off NO_MUSIC equ 1 ; turn music + tool loading off
; Typical init ; Typical init
phk phk
plb plb
@ -25,18 +29,13 @@ NO_MUSIC equ 1 ; turn music + tool loadi
ldx #0 ldx #0
jsl SetScreenMode jsl SetScreenMode
jsr _InitBG1 ; Initialize the second background
lda #0
jsr _ClearBG1Buffer
; Set up our level data ; Set up our level data
jsr BG0SetUp jsr BG0SetUp
jsr BG1SetUp jsr BG1SetUp
; Allocate room to load data ; Allocate room to load data
jsr AllocOneBank2 ; Alloc 64KB for Load/Unpack jsl AllocBank ; 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
@ -86,7 +85,7 @@ EvtLoop
sec sec
sbc #'1' sbc #'1'
tax tax
jsr SetScreenMode jsl SetScreenMode
jsr MovePlayerToOrigin jsr MovePlayerToOrigin
brl EvtLoop brl EvtLoop
@ -158,9 +157,9 @@ StartMusic
; 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 jsl SetBG0XPos
lda #0 lda #0
jsr SetBG1XPos jsl SetBG1XPos
lda TileMapHeight lda TileMapHeight
asl asl
@ -169,9 +168,9 @@ MovePlayerToOrigin
sec sec
sbc ScreenHeight sbc ScreenHeight
pha pha
jsr SetBG0YPos jsl SetBG0YPos
pla pla
jsr SetBG1YPos jsl SetBG1YPos
rts rts
@ -237,7 +236,7 @@ DoTiles
lda :column,s lda :column,s
tax tax
lda :tile,s lda :tile,s
jsr CopyTile jsl CopyBG0Tile
lda :column,s lda :column,s
inc inc
@ -297,423 +296,7 @@ DoLoadPic
ldx BankLoad ; Copy it into the code field ldx BankLoad ; Copy it into the code field
lda #0 lda #0
jsr CopyPicToField jsl 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
rts rts
;DefaultPalette dw $0000,$007F,$0090,$0FF0 ;DefaultPalette dw $0000,$007F,$0090,$0FF0
@ -842,8 +425,6 @@ BG1AltDataFile strl '1/bg1b.bin'
ImageName strl '1/test.pic' ImageName strl '1/test.pic'
FGName strl '1/fg1.bin' FGName strl '1/fg1.bin'
;MasterId ds 2
;UserId ds 2
openRec dw 2 ; pCount openRec dw 2 ; pCount
ds 2 ; refNum ds 2 ; refNum
@ -865,6 +446,11 @@ closeRec dw 1 ; pCount
qtRec adrl $0000 qtRec adrl $0000
da $00 da $00
PUT App.Msg.s
PUT Actions.s
PUT font.s
PUT Overlay.s
PUT App.TileMapBG0.s PUT App.TileMapBG0.s
PUT App.TileMapBG1.s PUT App.TileMapBG1.s
@ -885,6 +471,13 @@ qtRec adrl $0000

View File

@ -12,7 +12,12 @@
ALI None ; Boundary Alignment (None) ALI None ; Boundary Alignment (None)
SNA Main 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 ASM App.TileSet.s
DS 0 DS 0
@ -20,7 +25,7 @@
; ALI BANK ; ALI BANK
SNA Tiles SNA Tiles
; Segment #3 -- Rotation table data ; Segment #4 -- Rotation table data
ASM RotData.s ASM RotData.s
DS 0 DS 0
@ -28,4 +33,3 @@
ALI BANK ALI BANK
SNA RotData SNA RotData

View File

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

View File

@ -1,22 +1,42 @@
; Collection of the EXTernal labels exported by GTE. This is the closest thing ; Collection of the EXTernal labels exported by GTE. This is the closest thing
; we have to an API definition. ; we have to an API definition.
EngineStartUp EXT EngineStartUp EXT
EngineShutDown EXT EngineShutDown EXT
SetScreenMode EXT SetScreenMode EXT
ReadControl EXT ReadControl EXT
Render EXT
AddTimer EXT SetBG0XPos EXT
RemoveTimer EXT SetBG0YPos EXT
DoTimers EXT SetBG1XPos EXT
SetBG1YPos EXT
CopyBG0Tile EXT
CopyBG1Tile EXT
Render EXT
StartScript EXT ; Rotation
StopScript EXT 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 ; 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 ldx #DefaultPalette
lda #0 lda #0
jsr SetPalette jsr SetPalette
jsr _InitBG0 ; Initialize the background layers
jsr _InitBG1
lda #0
jsr _ClearBG1Buffer
rts rts
DefaultPalette dw $0000,$007F,$0090,$0FF0 DefaultPalette dw $0000,$007F,$0090,$0FF0
@ -116,3 +123,5 @@ WaitForVBL sep #$20
rts rts

View File

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

View File

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

View File

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

View File

@ -84,22 +84,22 @@ AddTimer ENT
bra :notimers bra :notimers
:freeslot pla :freeslot pla
sta Timer+0,x ; set the counter and sta Timers+0,x ; set the counter and
stz Timer+2,x ; default to a zero reset value stz Timers+2,x ; default to a zero reset value
pla pla
sta Timer+4,x ; set the callback address sta Timers+4,x ; set the callback address
pla pla
sta Timer+6,x sta Timers+6,x
stz Timer+8,x ; Clear the user data space stz Timers+8,x ; Clear the user data space
stz Timer+10,x ; Clear the user data space stz Timers+10,x ; Clear the user data space
stz Timer+12,x ; Clear the user data space stz Timers+12,x ; Clear the user data space
stz Timer+14,x ; Clear the user data space stz Timers+14,x ; Clear the user data space
plp plp
bcc :oneshot bcc :oneshot
lda Timer+0,x ; if not a one-shot, put the counter lda Timers+0,x ; if not a one-shot, put the counter
sta Timer+2,x ; value into the reset field sta Timers+2,x ; value into the reset field
:oneshot plb :oneshot plb
txa ; return the slot ID and a success status txa ; return the slot ID and a success status
@ -127,10 +127,10 @@ RemoveTimer ENT
bcs :exit bcs :exit
tax tax
stz Timer,x stz Timers,x
stz Timer+2,x stz Timers+2,x
stz Timer+4,x stz Timers+4,x
stz Timer+6,x stz Timers+6,x
:exit :exit
plb 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 jsr _ApplyBG1XPos
rts 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 cmp BG1StartX
beq :out ; Easy, if nothing changed, then nothing changes beq :out ; Easy, if nothing changed, then nothing changes
@ -19,7 +86,11 @@ SetBG1XPos
:out rts :out rts
SetBG1YPos SetBG1YPos ENT
jsr _SetBG1YPos
rtl
_SetBG1YPos
cmp BG1StartY cmp BG1StartY
beq :out ; Easy, if nothing changed, then nothing changes beq :out ; Easy, if nothing changed, then nothing changes
@ -82,6 +153,14 @@ _ApplyBG1XPos
rts rts
ANGLEBNK ext ANGLEBNK ext
ApplyBG1XPosAngle ENT
phb
phk
plb
jsr _ApplyBG1XPosAngle
plb
rtl
_ApplyBG1XPosAngle _ApplyBG1XPosAngle
; phy ; phy
@ -146,6 +225,13 @@ _ClearBG1Buffer
plb plb
rts rts
ApplyBG1YPosAngle ENT
phb
phk
plb
jsr _ApplyBG1YPosAngle
plb
rtl
_ApplyBG1YPosAngle _ApplyBG1YPosAngle
:virt_line equ tmp0 :virt_line equ tmp0

View File

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

View File

@ -229,7 +229,8 @@ RTable ds 400
ds 400 ds 400
; Array of addresses for the banks that hold the blitter. ; 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 ; 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 ; 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 plx
rts rts
; CopyTile ; CopyBG0Tile
; ;
; A low-level function that copies 8x8 tiles directly into the code field space. ; A low-level function that copies 8x8 tiles directly into the code field space.
; ;
; A = Tile ID (0 - 511) ; A = Tile ID (0 - 511)
; X = Tile column (0 - 40) ; X = Tile column (0 - 40)
; Y = Tile row (0 - 25) ; Y = Tile row (0 - 25)
CopyTile CopyBG0Tile ENT
phb
phk
plb
jsr _CopyBG0Tile
plb
rtl
_CopyBG0Tile
phb ; save the current bank phb ; save the current bank
phx ; save the original x-value phx ; save the original x-value
pha ; save the tile ID pha ; save the tile ID
@ -734,7 +742,15 @@ CopyTile
; A = Tile ID (0 - 511) ; A = Tile ID (0 - 511)
; X = Tile column (0 - 40) ; X = Tile column (0 - 40)
; Y = Tile row (0 - 25) ; Y = Tile row (0 - 25)
CopyTileBG1 CopyBG1Tile
phb
phk
plb
jsr _CopyBG1Tile
plb
rtl
_CopyBG1Tile
phb ; save the current bank phb ; save the current bank
phx ; save the original x-value phx ; save the original x-value
pha ; save the tile ID pha ; save the tile ID
@ -769,11 +785,3 @@ CopyTileBG1

View File

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