gigatron/rom/Contrib/at67/gasm/sprites/sprites_test3_ntv.gasm
2025-01-28 19:17:01 +03:00

507 lines
16 KiB
Plaintext

; **************************************************************************************************
; **************************************************************************************************
; THIS WILL NOT RUN ON REAL HARDWARE UNLESS YOU BURN THE NATIVE CODE AT THE BOTTOM
; OF THIS FILE INTO THE GIGATRONS ROM AT THE CORRECT ADDRESS, EMULATION ONLY!
; **************************************************************************************************
; **************************************************************************************************
; sprite test
vram EQU 0x0800
hscroll EQU 0x0101
REENTER EQU 0x03CB
rand EQU 0x06
videoY EQU 0x09
frameCount EQU 0x0E
sysFn EQU 0x22
dstAddr EQU 0x30
vbase EQU 0x32
pixels EQU 0x34
frame EQU 0x36
xyPos EQU 0x38
xyPosHi EQU 0x3A
xyVel EQU 0x3C
xyVelHi EQU 0x3E
i EQU 0x40
j EQU 0x42
k EQU 0x44
delay EQU 0x46
one EQU 0x48
mask1 EQU 0x4A
mask2 EQU 0x4C
scratch EQU 0x4E
pixelsArray EQU 0x60
xyPosArray EQU 0x82
xyVelArray EQU 0xA2
sysFnArray EQU 0xC2
hscrollAddr EQU 0xE2
xExtent EQU 0x96
yExtent EQU 0x6e
numSprites EQU 16
_startAddress_ EQU 0x0200 ; entry point for the code, if this is missing defaults to 0x0200
_callTable_ EQU 0x005E ; call addresses are automatically stored here by the assembler, it grows downwards
; *NOTE* gt1 spec only allows for one zero page segment, .vasm files use this for the call table
; do *NOT* make this address higher than 0x00BE, it will conflict with future ROM loading mechanisms
; do *NOT* define constants, (DB or DW), between 0x30 -> 0x44 and 0xc0 -> 0xFF, these addresses are
; used by the loader and the vCPU stack, you can create variables in these areas as long as you don't
; corrupt your nested CALL return addresses on the stack
_singleStepWatch_ EQU k ; the single step debugger watches this variable location to decide when to step,
; choose a variable that is updated often
SYS_BlinkyBlast_142 EQU 0x2300 ; 10x10 pixel blast, sprite data is embedded in instructions
SYS_ClearRow32_56 EQU 0x2400 ; clear 32 pixels at a time
start EQU 0x200
loopinit EQU 0x300
vblank0 EQU 0x400
; vram base address
start LDWI vram
STW vbase
; horizontal scroll address
LDWI hscroll
STW hscrollAddr
LDWI xyPosArray
STW xyPos
LDWI xyPosArray + 1
STW xyPosHi
LDWI xyVelArray
STW xyVel
LDWI xyVelArray + 1
STW xyVelHi
LDWI pixelsArray
STW pixels
; clear screen, (including hidden areas), fast
LDWI SYS_ClearRow32_56 ; clears 32 row pixels at a time
STW sysFn
clear SYS 56
LDWI 0x0020
ADDW vbase
STW vbase
LD vbase+1
SUBI 0x7F
BLT clear
LDI 0x08 ; finish off last row
ST i
last_row SYS 56
LDWI 0x0020
ADDW vbase
STW vbase
LD i
SUBI 0x01
ST i
BGT last_row
LDWI SYS_BlinkyBlast_142
STW sysFn
LDWI vram
STW vbase
; constants
constants LDWI 0x3F7F
STW mask1
LDWI 0x0707
STW mask2
LDI 0x00
ST i
LDWI 0x0001
STW one
LDWI 192
STW delay
; vblank counter
LD frameCount
STW frame
; random positions
init LD rand
ANDI 0x03
BEQ case0
SUBI 0x01
BEQ case1
SUBI 0x01
BEQ case2
SUBI 0x01
BEQ case3
case0 LDWI 0x0101
DOKE xyVel
BRA randpos
case1 LDWI 0x01FF
DOKE xyVel
BRA randpos
case2 LDWI 0xFF01
DOKE xyVel
BRA randpos
case3 LDWI 0xFFFF
DOKE xyVel
; generate vram address
randpos LDW rand
ANDW mask1
ORW mask2
DOKE xyPos
ADDW vbase
DOKE pixels
INC xyPos
INC xyPos
INC xyVel
INC xyVel
INC pixels
INC pixels
CALL vblank0
INC i
LD i
SUBI numSprites
BLT init
CALL loopinit
; main loop
loopinit LDWI xyPosArray
STW xyPos
LDWI xyPosArray + 1
STW xyPosHi
LDWI xyVelArray
STW xyVel
LDWI xyVelArray + 1
STW xyVelHi
LDWI pixelsArray
STW pixels
LDI 0x00
ST i
; x position bounds checking
xbounds LDW xyPos
PEEK
BEQ xflip
SUBI xExtent
BLT ybounds
; flip x velocity
xflip LDW xyVel
PEEK
XORI 0xFE
POKE xyVel
; y position bounds checking
ybounds LDW xyPosHi
PEEK
BEQ yflip
SUBI yExtent
BLT velocity
; flip y velocity
yflip LDW xyVelHi
PEEK
XORI 0xFE
POKE xyVelHi
; xpos += xvel
velocity LDW xyPos
PEEK
ST scratch
LDW xyVel
PEEK
ADDW scratch
POKE xyPos
; ypos += yvel
LDW xyPosHi
PEEK
ST scratch
LDW xyVelHi
PEEK
ADDW scratch
POKE xyPosHi
; generate vram address
LDW xyPos
DEEK
ADDW vbase
DOKE pixels
; increment array pointers
INC xyPos
INC xyPos
INC xyPosHi
INC xyPosHi
INC xyVel
INC xyVel
INC xyVelHi
INC xyVelHi
INC pixels
INC pixels
; do it for numSprites
INC i
LD i
SUBI numSprites
BLT xbounds
LDWI pixelsArray
STW pixels
LDI 0x00
ST k
; scroll playfield
LD frameCount
POKE hscrollAddr
; draw sprite
draw LDW pixels
DEEK
STW dstAddr
SYS 142
INC pixels
INC pixels
INC k
LD k
SUBI numSprites
BLT draw
CALL vblank1
BRA loopinit
; subroutines
vblank0 LD frameCount
SUBW frame
BEQ vblank0
LD frameCount
STW frame
RET
vblank1 LD videoY
ANDI 0x01
BEQ vblank1
RET
vblank2 LD 0x0000
STW i
loopdelay LDW i
ADDW one
STW i
SUBW delay
BLT loopdelay
RET
; native code routines that are written into the emulator's fake ROM using either the DBR/DWR commands or the native instruction set
; the native instruction assembler has access to the same functionality as the vasm assembler, (labels, equates, mutables, etc).
; it's only caveats are:
; 1: each instruction is prefaced with a period to clearly differentiate it from a vasm instruction
; 2: you cannot mix and match vasm instructions with native instructions within the same segment, (in reality they are executed in
; completely different parts of the memory map, i.e. native in fake ROM and vasm in RAM)
; 3: you must follow the SYS calling conventions exactly
; accumulator holds [dstAddr + 1] for entire sprite blast
SYS_BlinkyBlast_142 .LD [dstAddr],X ; dst line 0
.LD [dstAddr + 1]
.ADDA $00,Y
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.LD [dstAddr],X ; dst line 1
.ADDA $01,Y
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.LD [dstAddr],X ; dst line 2
.ADDA $02,Y
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.LD [dstAddr],X ; dst line 3
.ADDA $03,Y
.ST $00,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $FF,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $FF,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $00,[Y,X++]
.LD [dstAddr],X ; dst line 4
.ADDA $04,Y
.ST $00,[Y,X++]
.ST $03,[Y,X++]
.ST $FF,[Y,X++]
.ST $30,[Y,X++]
.ST $FF,[Y,X++]
.ST $FF,[Y,X++]
.ST $30,[Y,X++]
.ST $FF,[Y,X++]
.ST $03,[Y,X++]
.ST $00,[Y,X++]
.LD [dstAddr],X ; dst line 5
.ADDA $05,Y
.ST $00,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $FF,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $FF,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $00,[Y,X++]
.LD [dstAddr],X ; dst line 6
.ADDA $06,Y
.ST $00,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $00,[Y,X++]
.LD [dstAddr],X ; dst line 7
.ADDA $07,Y
.ST $00,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $03,[Y,X++]
.ST $00,[Y,X++]
.LD [dstAddr],X ; dst line 8
.ADDA $08,Y
.ST $00,[Y,X++]
.ST $03,[Y,X++]
.ST $00,[Y,X++]
.ST $03,[Y,X++]
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.ST $03,[Y,X++]
.ST $00,[Y,X++]
.ST $03,[Y,X++]
.ST $00,[Y,X++]
.LD [dstAddr],X ; dst line 9
.ADDA $09,Y
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.ST $00,[Y,X++]
.NOP ; pad instructions so odd(14 + number of instructions) = true
.LD REENTER >>8,y
.JMP y,REENTER
.LD 0xB9 ; 0 - ((14 + number of instructions + 3) / 2), odd(14 + number of instructions) = true
SYS_ClearRow32_56 .LD [vbase],X
.LD [vbase+1],Y
.LD 0x00
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.ST [Y,X++]
.NOP ; pad instructions so odd(14 + number of instructions) = true
.LD REENTER >>8,y
.JMP y,REENTER
.LD 0xE4 ; 0 - ((14 + number of instructions + 3) / 2), odd(14 + number of instructions) = true