381 lines
10 KiB
Plaintext
381 lines
10 KiB
Plaintext
; game of life coded by at67, original algorithm by John Conway
|
|
|
|
vram EQU 0x0800
|
|
buffer0 EQU 0x08A0
|
|
buffer1 EQU 0x08C0
|
|
|
|
cells0 EQU 0x30
|
|
cells1 EQU 0x32
|
|
x EQU 0x34
|
|
y EQU 0x35
|
|
i EQU 0x36
|
|
j EQU 0x37
|
|
neighbours EQU 0x38
|
|
cell EQU 0x39
|
|
cbase0 EQU 0x3A
|
|
cbase1 EQU 0x3C
|
|
vbase EQU 0x3E
|
|
pixels EQU 0x40
|
|
xy_addr EQU 0x42
|
|
x_add_addr EQU 0x44
|
|
y_add_addr EQU 0x46
|
|
one EQU 0x48
|
|
test EQU 0x4A
|
|
watch EQU 0x4C
|
|
scratch EQU 0x4E
|
|
mask EQU 0x50
|
|
ones EQU 0x52
|
|
gliders EQU 0x54
|
|
lut_modify EQU 0x56
|
|
|
|
|
|
_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 watch ; the single step debugger watches this variable location to decide when to step,
|
|
; choose a variable that is updated often
|
|
|
|
data EQU 0x08A2 ; custom address for constant data space defined with DB and/or DW
|
|
|
|
n_lut EQU 0x0060
|
|
n_l_t EQU 0x0300
|
|
get_cell EQU 0x0400
|
|
|
|
|
|
LDI 0x00 ; look up table that is used to evaluate neighbour counts
|
|
ST n_lut
|
|
ST n_lut+1
|
|
ST n_lut+2 ; self modifying code updates this location with previous generation cell
|
|
ST n_lut+4
|
|
ST n_lut+5
|
|
ST n_lut+6
|
|
ST n_lut+7
|
|
ST n_lut+8
|
|
LDI 0xFF
|
|
ST n_lut+3
|
|
|
|
LDWI vram
|
|
STW vbase ; vram base address
|
|
STW pixels ; pixel address
|
|
|
|
LDWI buffer0
|
|
STW cbase0
|
|
LDWI buffer1
|
|
STW cbase1
|
|
|
|
LDWI 0x1F1F
|
|
STW mask
|
|
|
|
LDWI 0x0001
|
|
STW one
|
|
|
|
LDWI 0x0100
|
|
STW ones
|
|
|
|
LDWI lut + 1 ; self modifying address
|
|
STW lut_modify
|
|
|
|
clear LDI 0x00 ; clear screen and array
|
|
POKE vbase
|
|
LDW vbase
|
|
ADDW one
|
|
STW vbase
|
|
LD vbase+1
|
|
SUBI 0x80
|
|
BLT clear
|
|
|
|
LDWI 0x08A2
|
|
STW gliders
|
|
|
|
LDI 0x05
|
|
ST i
|
|
|
|
init LDW gliders ; glider
|
|
STW test
|
|
LDI 0xFF
|
|
POKE test
|
|
LDW ones
|
|
ADDW test
|
|
STW test
|
|
LDI 0xFF
|
|
POKE test
|
|
LDW ones
|
|
ADDW test
|
|
STW test
|
|
LDI 0xFF
|
|
POKE test
|
|
LD test
|
|
SUBI 0x01
|
|
ST test
|
|
LDI 0xFF
|
|
POKE test
|
|
LDW test
|
|
SUBW ones
|
|
STW test
|
|
LD test
|
|
SUBI 0x01
|
|
ST test
|
|
LDI 0xFF
|
|
POKE test
|
|
|
|
LD gliders
|
|
ADDI 0x04
|
|
ST gliders
|
|
|
|
LD i
|
|
SUBI 0x01
|
|
ST i
|
|
BGT init
|
|
|
|
LDWI 0x354A ; position in screen to render life
|
|
STW vbase
|
|
|
|
LDI 0x00
|
|
ST i
|
|
ST j
|
|
CALL n_l_t
|
|
|
|
|
|
n_l_t LDI 0x00 ; reset neighbour count
|
|
ST neighbours
|
|
LD i ; -1, -1 neighbour
|
|
SUBI 0x01
|
|
ST i
|
|
LD j
|
|
SUBI 0x01
|
|
ST j
|
|
;CALL get_cell
|
|
LDW i
|
|
ANDW mask
|
|
ADDW cbase0
|
|
PEEK
|
|
BEQ n_m_t
|
|
INC neighbours
|
|
|
|
n_m_t INC i ; 0, -1 neighbour
|
|
;CALL get_cell
|
|
LDW i
|
|
ANDW mask
|
|
ADDW cbase0
|
|
PEEK
|
|
BEQ n_r_t
|
|
INC neighbours
|
|
|
|
n_r_t INC i ; 1, -1 neighbour
|
|
;CALL get_cell
|
|
LDW i
|
|
ANDW mask
|
|
ADDW cbase0
|
|
PEEK
|
|
BEQ n_r_m
|
|
INC neighbours
|
|
|
|
n_r_m INC j ; 1, 0 neighbour
|
|
;CALL get_cell
|
|
LDW i
|
|
ANDW mask
|
|
ADDW cbase0
|
|
PEEK
|
|
BEQ n_r_b
|
|
INC neighbours
|
|
|
|
n_r_b INC j ; 1, 1 neighbour
|
|
;CALL get_cell
|
|
LDW i
|
|
ANDW mask
|
|
ADDW cbase0
|
|
PEEK
|
|
BEQ n_m_b
|
|
INC neighbours
|
|
|
|
n_m_b LD i ; 0, 1 neighbour
|
|
SUBI 0x01
|
|
ST i
|
|
;CALL get_cell
|
|
LDW i
|
|
ANDW mask
|
|
ADDW cbase0
|
|
PEEK
|
|
BEQ n_l_b
|
|
INC neighbours
|
|
|
|
n_l_b LD i ; -1, 1 neighbour
|
|
SUBI 0x01
|
|
ST i
|
|
;CALL get_cell
|
|
LDW i
|
|
ANDW mask
|
|
ADDW cbase0
|
|
PEEK
|
|
BEQ n_l_m
|
|
INC neighbours
|
|
|
|
n_l_m LD j ; -1, 0 neighbour
|
|
SUBI 0x01
|
|
ST j
|
|
;CALL get_cell
|
|
LDW i
|
|
ANDW mask
|
|
ADDW cbase0
|
|
PEEK
|
|
BEQ cell00
|
|
INC neighbours
|
|
|
|
cell00 INC i
|
|
;CALL get_cell00 ; 0, 0 cell
|
|
LDW i
|
|
ADDW cbase0
|
|
STW cells0
|
|
|
|
PEEK
|
|
ST cell
|
|
ST 0x62
|
|
;CALL set_cells
|
|
LDW i
|
|
ADDW cbase1
|
|
STW cells1
|
|
|
|
LD neighbours
|
|
ADDI 0x60
|
|
POKE lut_modify ; lut_modify points to operand in "LD n_lut"
|
|
lut LD 0x60 ; self modifying code
|
|
|
|
;check_3 LD neighbours
|
|
; SUBI 0x03
|
|
; BNE check_<2
|
|
; LDI 0xFF ; birth
|
|
; BRA draw
|
|
|
|
;check_<2 LD neighbours
|
|
; SUBI 0x02
|
|
; BGE check_>3
|
|
; LDI 0x00 ; death
|
|
; BRA draw
|
|
|
|
;check_>3 LD neighbours
|
|
; SUBI 0x03
|
|
; BLE old_cell
|
|
; LDI 0x00 ; death
|
|
; BRA draw
|
|
|
|
;old_cell LD cell
|
|
|
|
draw POKE cells1
|
|
ST cell
|
|
;CALL draw_1x1
|
|
;CALL draw_2x2
|
|
LDW i
|
|
ADDW vbase
|
|
STW pixels
|
|
LD cell
|
|
POKE pixels
|
|
|
|
LD i ; inc i
|
|
ADDI 0x01
|
|
ANDI 0x1F
|
|
ST i
|
|
BNE n_l_t
|
|
|
|
LD j ; inc j
|
|
ADDI 0x01
|
|
ANDI 0x1F
|
|
ST j
|
|
BNE n_l_t
|
|
|
|
LDW cbase0 ; toggle buffers between 0x08A0 and 0x08C0
|
|
STW test
|
|
LDW cbase1
|
|
STW cbase0
|
|
LDW test
|
|
STW cbase1
|
|
|
|
BRA n_l_t
|
|
|
|
|
|
get_cell LDW i
|
|
;LD i
|
|
;ANDI 0x1F
|
|
;ST xy_addr
|
|
;LD j
|
|
;ANDI 0x1F
|
|
;ST xy_addr+1
|
|
;LDW xy_addr
|
|
;ADDW cbase0
|
|
;STW cells0
|
|
;PEEK
|
|
|
|
ANDW mask
|
|
ADDW cbase0
|
|
STW cells0
|
|
PEEK
|
|
RET
|
|
|
|
|
|
get_cell00 LD i
|
|
ST xy_addr
|
|
LD j
|
|
ST xy_addr+1
|
|
|
|
LDW xy_addr
|
|
ADDW cbase0
|
|
STW cells0
|
|
RET
|
|
|
|
|
|
set_cells LD i
|
|
ST xy_addr
|
|
LD j
|
|
ST xy_addr+1
|
|
|
|
LDW xy_addr
|
|
ADDW cbase1
|
|
STW cells1
|
|
RET
|
|
|
|
|
|
draw_1x1 LD i
|
|
ST xy_addr
|
|
LD j
|
|
ST xy_addr+1
|
|
|
|
LDW xy_addr
|
|
ADDW vbase
|
|
STW pixels
|
|
LD cell
|
|
POKE pixels
|
|
RET
|
|
|
|
|
|
draw_2x2 LD i
|
|
LSLW
|
|
ST xy_addr
|
|
LD j
|
|
LSLW
|
|
ST xy_addr+1
|
|
LDW xy_addr
|
|
ADDW vbase
|
|
STW pixels
|
|
STW scratch
|
|
LD cell
|
|
POKE pixels
|
|
INC pixels
|
|
POKE pixels
|
|
LDW scratch
|
|
STW pixels
|
|
INC pixels+1
|
|
LD cell
|
|
POKE pixels
|
|
INC pixels
|
|
POKE pixels
|
|
RET
|
|
|
|
|
|
; an example of how to define your own data
|
|
data DB 0xFF 0xFF 0xFF
|