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

253 lines
9.8 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
buff0 EQU 0x08A0
buff1 EQU 0x08A4
REENTER EQU 0x03CB
frameCount EQU 0x0E
sysFn EQU 0x22
srcAddr EQU 0x30
dstAddr EQU 0x32
backBuffer EQU 0x34
spriteData EQU 0x36
vbase EQU 0x38
pixels EQU 0x3A
xyPos EQU 0x3C
xyVel EQU 0x3E
frame EQU 0x40
rowBuffer0 EQU 0x50
rowBuffer1 EQU 0x54
rowBuffer2 EQU 0x58
rowBuffer3 EQU 0x5C
xExtent EQU 0x9C
yExtent EQU 0x74
_startAddress_ EQU 0x0200 ; entry point for the code, if this is missing defaults to 0x0200
_callTable_ EQU 0x007E ; 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 xyPos ; the single step debugger watches this variable location to decide when to step,
; choose a variable that is updated often
SYS_SpriteRow_118 EQU 0x2300 ; 16 pixel memory copy
LDWI vram
STW vbase ; vram base address
STW pixels ; pixel address
LDWI 0x0101
STW xyPos
LDWI 0x0101
STW xyVel ; XY velocity
LDWI buff0
STW spriteData
LDWI buff1
STW backBuffer
LDWI SYS_SpriteRow_118
STW sysFn
LDW vbase ; generate vram address
ADDW xyPos
STW pixels
STW srcAddr
LDW backBuffer
STW dstAddr
SYS 118
LD frameCount
STW frame
xbounds LD xyPos ; x position bounds checking
BEQ xflip
SUBI xExtent
BLT ybounds
xflip LD xyVel
XORI 0xFE ; flip x velocity
ST xyVel
ybounds LD xyPos+1 ; y position bounds checking
BEQ yflip
SUBI yExtent
BLT velocity
yflip LD xyVel+1
XORI 0xFE ; flip y velocity
ST xyVel+1
velocity LD xyPos
ADDW xyVel
ST xyPos
LD xyPos+1
ADDW xyVel+1
ST xyPos+1
vblank LD frameCount
SUBW frame
BEQ vblank
LD frameCount
STW frame
LDW backBuffer
STW srcAddr
LDW pixels
STW dstAddr
SYS 118
LDW vbase ; generate vram address
ADDW xyPos
STW pixels
STW srcAddr
LDW backBuffer
STW dstAddr
SYS 118
LDW srcAddr
STW dstAddr
LDW spriteData
STW srcAddr
SYS 118
BRA xbounds
; 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
SYS_SpriteRow_118 .LD [srcAddr],X ; src line 0
.LD [srcAddr+1],Y
.LD [Y,X]
.ST [rowBuffer0+0]
.ST [Y,X++] ; hack increment
.LD [Y,X]
.ST [rowBuffer0+1]
.ST [Y,X++] ; hack increment
.LD [Y,X]
.ST [rowBuffer0+2]
.ST [Y,X++] ; hack increment
.LD [Y,X]
.ST [rowBuffer0+3]
.LD [srcAddr],X ; src line1
.LD 0x01
.ADDA [srcAddr+1],Y
.LD [Y,X]
.ST [rowBuffer1+0]
.ST [Y,X++] ; hack increment
.LD [Y,X]
.ST [rowBuffer1+1]
.ST [Y,X++] ; hack increment
.LD [Y,X]
.ST [rowBuffer1+2]
.ST [Y,X++] ; hack increment
.LD [Y,X]
.ST [rowBuffer1+3]
.LD [srcAddr],X ; src line2
.LD 0x02
.ADDA [srcAddr+1],Y
.LD [Y,X]
.ST [rowBuffer2+0]
.ST [Y,X++] ; hack increment
.LD [Y,X]
.ST [rowBuffer2+1]
.ST [Y,X++] ; hack increment
.LD [Y,X]
.ST [rowBuffer2+2]
.ST [Y,X++] ; hack increment
.LD [Y,X]
.ST [rowBuffer2+3]
.LD [srcAddr],X ; src line3
.LD 0x03
.ADDA [srcAddr+1],Y
.LD [Y,X]
.ST [rowBuffer3+0]
.ST [Y,X++] ; hack increment
.LD [Y,X]
.ST [rowBuffer3+1]
.ST [Y,X++] ; hack increment
.LD [Y,X]
.ST [rowBuffer3+2]
.ST [Y,X++] ; hack increment
.LD [Y,X]
.ST [rowBuffer3+3]
.LD [dstAddr],X ; dst line 0
.LD [dstAddr+1],Y
.LD [rowBuffer0+0]
.ST [Y,X++]
.LD [rowBuffer0+1]
.ST [Y,X++]
.LD [rowBuffer0+2]
.ST [Y,X++]
.LD [rowBuffer0+3]
.ST [Y,X++]
.LD [dstAddr],X ; dst line 1
.LD 0x01
.ADDA [dstAddr+1],Y
.LD [rowBuffer1+0]
.ST [Y,X++]
.LD [rowBuffer1+1]
.ST [Y,X++]
.LD [rowBuffer1+2]
.ST [Y,X++]
.LD [rowBuffer1+3]
.ST [Y,X++]
.LD [dstAddr],X ; dst line 2
.LD 0x02
.ADDA [dstAddr+1],Y
.LD [rowBuffer2+0]
.ST [Y,X++]
.LD [rowBuffer2+1]
.ST [Y,X++]
.LD [rowBuffer2+2]
.ST [Y,X++]
.LD [rowBuffer2+3]
.ST [Y,X++]
.LD [dstAddr],X ; dst line 3
.LD 0x03
.ADDA [dstAddr+1],Y
.LD [rowBuffer3+0]
.ST [Y,X++]
.LD [rowBuffer3+1]
.ST [Y,X++]
.LD [rowBuffer3+2]
.ST [Y,X++]
.LD [rowBuffer3+3]
.ST [Y,X++]
.LD REENTER >>8,y
.JMP y,REENTER
.LD 0xC5 ; 0 - ((14 + number of instructions + 3) / 2), odd(14 + number of instructions) = true