263 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			263 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
; game of life coded by at67, original algorithm by John Conway
 | 
						|
; 32X32 runs about 1 fps on a 6.25MHz Gigatron TTL
 | 
						|
; non-optimised apart from a look up table to evalute neighbours count
 | 
						|
; this is an overlapping world
 | 
						|
 | 
						|
 | 
						|
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
 | 
						|
pattern     EQU     0x42
 | 
						|
watch       EQU     0x44
 | 
						|
scratch     EQU     0x46
 | 
						|
mask        EQU     0x48
 | 
						|
gliders     EQU     0x4A
 | 
						|
lut_modify  EQU     0x4C
 | 
						|
j_one       EQU     0x4E
 | 
						|
 | 
						|
ij_mask     EQU     0x1F1F  ; determines max size of world, limited by available ram in blank scanlines,
 | 
						|
                            ; using bytes per cell and two buffers means 0x20*0x20 is maximum size
 | 
						|
 | 
						|
                                        
 | 
						|
_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
 | 
						|
 | 
						|
 | 
						|
n_lut       EQU     0x0060  
 | 
						|
n_l_t       EQU     0x0300
 | 
						|
 | 
						|
 | 
						|
            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    ij_mask
 | 
						|
            STW     mask
 | 
						|
            LDWI    lut + 1     ; self modifying address
 | 
						|
            STW     lut_modify
 | 
						|
            LDWI    0x0100
 | 
						|
            STW     j_one
 | 
						|
            
 | 
						|
clear       LDI     0x00        ; clear screen and buffers
 | 
						|
            POKE    vbase
 | 
						|
            LDWI    0x0001
 | 
						|
            ADDW    vbase
 | 
						|
            STW     vbase
 | 
						|
            LD      vbase+1
 | 
						|
            SUBI    0x80
 | 
						|
            BLT     clear
 | 
						|
 | 
						|
            LDWI    0x08A2
 | 
						|
            STW     gliders
 | 
						|
 | 
						|
            LDI     0x07        ; number of gliders
 | 
						|
            ST      i
 | 
						|
 | 
						|
glider      LDW     gliders     
 | 
						|
            STW     pattern
 | 
						|
            LDI     0xFF        
 | 
						|
            POKE    pattern
 | 
						|
            LDW     j_one
 | 
						|
            ADDW    pattern
 | 
						|
            STW     pattern
 | 
						|
            LDI     0xFF
 | 
						|
            POKE    pattern
 | 
						|
            LDW     j_one
 | 
						|
            ADDW    pattern
 | 
						|
            STW     pattern
 | 
						|
            LDI     0xFF
 | 
						|
            POKE    pattern
 | 
						|
            LD      pattern
 | 
						|
            SUBI    0x01
 | 
						|
            ST      pattern
 | 
						|
            LDI     0xFF
 | 
						|
            POKE    pattern
 | 
						|
            LDW     pattern
 | 
						|
            SUBW    j_one
 | 
						|
            STW     pattern
 | 
						|
            LD      pattern
 | 
						|
            SUBI    0x01
 | 
						|
            ST      pattern
 | 
						|
            LDI     0xFF
 | 
						|
            POKE    pattern
 | 
						|
            
 | 
						|
            LD      gliders     ; gap between gliders
 | 
						|
            ADDI    0x04
 | 
						|
            ST      gliders
 | 
						|
            
 | 
						|
            LD      i
 | 
						|
            SUBI    0x01
 | 
						|
            ST      i
 | 
						|
            BGT     glider
 | 
						|
                        
 | 
						|
            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
 | 
						|
            LDW     i
 | 
						|
            ANDW    mask
 | 
						|
            ADDW    cbase0
 | 
						|
            PEEK
 | 
						|
            BEQ     n_m_t
 | 
						|
            INC     neighbours
 | 
						|
            
 | 
						|
n_m_t       INC     i           ; 0, -1 neighbour
 | 
						|
            LDW     i
 | 
						|
            ANDW    mask
 | 
						|
            ADDW    cbase0
 | 
						|
            PEEK
 | 
						|
            BEQ     n_r_t
 | 
						|
            INC     neighbours
 | 
						|
 | 
						|
n_r_t       INC     i           ; 1, -1 neighbour
 | 
						|
            LDW     i
 | 
						|
            ANDW    mask
 | 
						|
            ADDW    cbase0
 | 
						|
            PEEK
 | 
						|
            BEQ     n_r_m
 | 
						|
            INC     neighbours
 | 
						|
 | 
						|
n_r_m       INC     j           ; 1, 0 neighbour
 | 
						|
            LDW     i
 | 
						|
            ANDW    mask
 | 
						|
            ADDW    cbase0
 | 
						|
            PEEK
 | 
						|
            BEQ     n_r_b
 | 
						|
            INC     neighbours
 | 
						|
            
 | 
						|
n_r_b       INC     j           ; 1, 1 neighbour
 | 
						|
            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
 | 
						|
            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
 | 
						|
            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
 | 
						|
            LDW     i
 | 
						|
            ANDW    mask
 | 
						|
            ADDW    cbase0
 | 
						|
            PEEK
 | 
						|
            BEQ     cell_00
 | 
						|
            INC     neighbours                        
 | 
						|
            
 | 
						|
cell_00     INC     i           ; 0, 0 cell
 | 
						|
            LDW     i
 | 
						|
            ADDW    cbase0
 | 
						|
            STW     cells0      ; save buffer0 address
 | 
						|
            PEEK                ; get buffer0 cell
 | 
						|
            ST      0x62        ; save cell into neighbours lut
 | 
						|
            LDW     i
 | 
						|
            ADDW    cbase1
 | 
						|
            STW     cells1      ; save buffer1 address
 | 
						|
 | 
						|
            LD      neighbours  ; lut computes neighbours count
 | 
						|
            ADDI    0x60
 | 
						|
            POKE    lut_modify  ; lut_modify points to operand in "LD n_lut"
 | 
						|
lut         LD      0x60        ; self modifying code
 | 
						|
 | 
						|
            POKE    cells1      ; save new cell
 | 
						|
            ST      cell
 | 
						|
            
 | 
						|
            LDW     i           ; draw cell
 | 
						|
            ADDW    vbase
 | 
						|
            STW     pixels
 | 
						|
            LD      cell
 | 
						|
            POKE    pixels
 | 
						|
                                    
 | 
						|
            LD      i           ; inc i
 | 
						|
            ADDI    0x01
 | 
						|
            ANDI    ij_mask
 | 
						|
            ST      i
 | 
						|
            BNE     n_l_t
 | 
						|
 | 
						|
            LD      j           ; inc j
 | 
						|
            ADDI    0x01
 | 
						|
            ANDI    ij_mask
 | 
						|
            ST      j
 | 
						|
            BNE     n_l_t
 | 
						|
 | 
						|
            LDW     cbase0      ; swap buffers
 | 
						|
            STW     scratch
 | 
						|
            LDW     cbase1
 | 
						|
            STW     cbase0
 | 
						|
            LDW     scratch
 | 
						|
            STW     cbase1
 | 
						|
            
 | 
						|
            BRA     n_l_t
 |