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

594 lines
18 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
%include ../include/gigatron.i
vram EQU 0x0800
buff0 EQU 0x08B0
buff1 EQU 0x08D0
REENTER EQU 0x03CB
rand EQU 0x06
videoY EQU 0x09
frameCount EQU 0x0E
sysFn EQU 0x22
srcAddr EQU 0x30
dstAddr EQU 0x32
backBuffer EQU 0x34
spriteData EQU 0x36
vbase EQU 0x38
pixels EQU 0x3A
frame EQU 0x3C
xyPos EQU 0x3E
xyPosHi EQU 0x40
xyVel EQU 0x42
xyVelHi EQU 0x44
colour EQU 0x46
i EQU 0x48
j EQU 0x4A
k EQU 0x4C
delay EQU 0x4E
one EQU 0x50
mask1 EQU 0x52
mask2 EQU 0x54
scratch EQU 0x56
rowBuffer0 EQU 0x70
rowBuffer1 EQU 0x74
rowBuffer2 EQU 0x78
rowBuffer3 EQU 0x7C
pixelsArray EQU 0x90
xyPosArray EQU 0xB0
xyVelArray EQU 0xD0
xExtent EQU 0x9C
yExtent EQU 0x74
numSprites EQU 4
_startAddress_ EQU 0x0200 ; entry point for the code, if this is missing defaults to 0x0200
_callTable_ EQU 0x008E ; 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_SpriteCopy_118 EQU 0x2300 ; 16 pixel memory copy
start EQU 0x200
loopinit EQU 0x300
vblank0 EQU 0x400
fillSprites EQU 0x500
start LDWI vram
STW vbase ; vram base address
LDWI buff0
STW spriteData
LDWI buff1
STW backBuffer
LDWI xyPosArray
STW xyPos
LDWI xyPosArray + 1
STW xyPosHi
LDWI xyVelArray
STW xyVel
LDWI xyVelArray + 1
STW xyVelHi
LDWI pixelsArray
STW pixels
LDWI SYS_SpriteCopy_118
STW sysFn
; fill sprite data
CALL fillSprites ; doesn't return, does a far jump to constants
; 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
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
randpos LDW rand
ANDW mask1
ORW mask2
DOKE xyPos
ADDW vbase ; generate vram address
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
LDWI buff0
STW spriteData
LDWI buff1
STW backBuffer
LDI 0x00
ST i
xbounds LDW xyPos ; x position bounds checking
PEEK
BEQ xflip
SUBI xExtent
BLT ybounds
xflip LDW xyVel
PEEK
XORI 0xFE ; flip x velocity
POKE xyVel
ybounds LDW xyPosHi ; y position bounds checking
PEEK
BEQ yflip
SUBI yExtent
BLT velocity
yflip LDW xyVelHi
PEEK
XORI 0xFE ; flip y velocity
POKE xyVelHi
velocity LDW xyPos ; xpos += xvel
PEEK
ST scratch
LDW xyVel
PEEK
ADDW scratch
POKE xyPos
LDW xyPosHi ; ypos += yvel
PEEK
ST scratch
LDW xyVelHi
PEEK
ADDW scratch
POKE xyPosHi
LDW xyPos
DEEK
ADDW vbase ; generate vram address
DOKE pixels
save STW srcAddr
LDW backBuffer
STW dstAddr
SYS 118
INC xyPos ; increment array pointers
INC xyPos
INC xyPosHi
INC xyPosHi
INC xyVel
INC xyVel
INC xyVelHi
INC xyVelHi
INC pixels
INC pixels
LD backBuffer + 1
ADDI 0x04
ST backBuffer + 1
INC i
LD i
SUBI numSprites
BLT xbounds
LDWI pixelsArray
STW pixels
LDI 0x00
ST k
draw LDW pixels
DEEK
STW dstAddr
LDW spriteData
STW srcAddr
SYS 118
INC pixels
INC pixels
LD spriteData + 1
ADDI 0x04
ST spriteData + 1
INC k
LD k
SUBI numSprites
BLT draw
;CALL vblank0
;CALL vblank1
CALL vblank2
LDWI buff1
STW backBuffer
LDWI pixelsArray
STW pixels
LDI 0x00
ST i
restore LDW backBuffer
STW srcAddr
LDW pixels
DEEK
STW dstAddr
SYS 118
INC pixels
INC pixels
LD backBuffer + 1
ADDI 0x04
ST backBuffer + 1
INC i
LD i
SUBI numSprites
BLT restore
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
waitScanln LD videoY
STW scratch
ADDW videoY
STW scratch
LDW xyPosHi ; ypos
PEEK
SUBW scratch
BGT waitScanln
RET
fillsprite LDI 0x00
ST j
fill_i LDI 0x00
ST i
fill_c LD i
LD colour
POKE spriteData
INC spriteData
INC i
LD i
SUBI 0x04
BLT fill_c
LDI buff0
ST spriteData
LD spriteData + 1
ADDI 0x01
ST spriteData + 1
INC j
LD j
SUBI 0x04
BLT fill_i
RET
fillSprites LDI 0x1F
ST colour
LDWI 0x08B0
STW spriteData
CALL fillsprite
LDI 0x30
ST colour
LDWI 0x0CB0
STW spriteData
CALL fillsprite
LDI 0x0C
ST colour
LDWI 0x10B0
STW spriteData
CALL fillsprite
LDI 0x03
ST colour
LDWI 0x14B0
STW spriteData
CALL fillsprite
LDI 0x0F
ST colour
LDWI 0x18B0
STW spriteData
CALL fillsprite
LDI 0x3C
ST colour
LDWI 0x1CB0
STW spriteData
CALL fillsprite
LDI 0x33
ST colour
LDWI 0x20B0
STW spriteData
CALL fillsprite
LDI 0x1A
ST colour
LDWI 0x24B0
STW spriteData
CALL fillsprite
LDI 0x5F
ST colour
LDWI 0x28B0
STW spriteData
CALL fillsprite
LDI 0x63
ST colour
LDWI 0x2CB0
STW spriteData
CALL fillsprite
LDI 0x7A
ST colour
LDWI 0x30B0
STW spriteData
CALL fillsprite
LDI 0x07
ST colour
LDWI 0x34B0
STW spriteData
CALL fillsprite
LDI 0x00
ST colour
LDWI 0x38B0
STW spriteData
CALL fillsprite
LDI 0x25
ST colour
LDWI 0x3CB0
STW spriteData
CALL fillsprite
LDI 0x52
ST colour
LDWI 0x40B0
STW spriteData
CALL fillsprite
LDI 0x36
ST colour
LDWI 0x44B0
STW spriteData
CALL fillsprite
CALL constants
; 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_SpriteCopy_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]
;.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