263 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			263 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
; game of life coded by at67, original algorithm by John Conway
 | 
						|
; 32X32 runs about 1 fps on a 6.25MHz Gigatron TTL
 | 
						|
; some optimisation, pointer arithmetic with offsets and a look up table to evalute neighbours count
 | 
						|
; this world has boundaries
 | 
						|
 | 
						|
 | 
						|
vram        EQU     0x0800
 | 
						|
buff0       EQU     0x09A0
 | 
						|
buff1       EQU     0x09D0
 | 
						|
 | 
						|
cells0      EQU     0x30
 | 
						|
cells1      EQU     0x32
 | 
						|
i           EQU     0x34
 | 
						|
j           EQU     0x35
 | 
						|
neighbours  EQU     0x36
 | 
						|
cell        EQU     0x37
 | 
						|
buffer0     EQU     0x38
 | 
						|
buffer1     EQU     0x3A
 | 
						|
vbase       EQU     0x3C
 | 
						|
pixels      EQU     0x3E
 | 
						|
pattern     EQU     0x40
 | 
						|
watch       EQU     0x42
 | 
						|
scratch     EQU     0x44
 | 
						|
mask        EQU     0x46 
 | 
						|
gliders     EQU     0x48
 | 
						|
lut_modify  EQU     0x4A
 | 
						|
j_one       EQU     0x4C
 | 
						|
offset0     EQU     0x4E
 | 
						|
offset1     EQU     0x50
 | 
						|
offset2     EQU     0x52
 | 
						|
offset3     EQU     0x54
 | 
						|
offset4     EQU     0x56
 | 
						|
offset5     EQU     0x58
 | 
						|
offset6     EQU     0x5A
 | 
						|
offset7     EQU     0x5C
 | 
						|
 | 
						|
 | 
						|
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* define any data/constants in zero page using DB or DW, it will not work! (use code)
 | 
						|
                                        ; do *NOT* make this address higher than 0x00BE, it will conflict with future ROM loading mechanisms
 | 
						|
                                        
 | 
						|
_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     0x60
 | 
						|
n_lut_cell  EQU     0x62
 | 
						|
 | 
						|
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    buff0
 | 
						|
            STW     buffer0
 | 
						|
            LDWI    buff1
 | 
						|
            STW     buffer1
 | 
						|
            
 | 
						|
            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    0x09A3
 | 
						|
            STW     gliders
 | 
						|
 | 
						|
            LDI     0x06        ; 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    0x05
 | 
						|
            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
 | 
						|
 | 
						|
            LDWI    0x0101      ; -ve
 | 
						|
            STW     offset0
 | 
						|
            LDWI    0x0100      ; -ve
 | 
						|
            STW     offset1
 | 
						|
            LDWI    0x00FF      ; -ve
 | 
						|
            STW     offset2
 | 
						|
            LDWI    0x0001      ; +ve
 | 
						|
            STW     offset3
 | 
						|
            LDWI    0x0101      ; +ve
 | 
						|
            STW     offset4
 | 
						|
            LDWI    0x0100      ; +ve
 | 
						|
            STW     offset5
 | 
						|
            LDWI    0x00FF      ; +ve
 | 
						|
            STW     offset6
 | 
						|
            LDWI    0x0001      ; -ve
 | 
						|
            STW     offset7
 | 
						|
            
 | 
						|
            CALL    n_l_t
 | 
						|
            
 | 
						|
          
 | 
						|
n_l_t       LDI     0x00        ; reset neighbour count
 | 
						|
            ST      neighbours
 | 
						|
            
 | 
						|
            LDW     i           ; buffer0
 | 
						|
            ADDW    buffer0
 | 
						|
            STW     cells0      
 | 
						|
            LDW     i           ; buffer1
 | 
						|
            ADDW    buffer1
 | 
						|
            STW     cells1      
 | 
						|
 | 
						|
            LDW     cells0      ; -1, -1 neighbour
 | 
						|
            SUBW    offset0
 | 
						|
            PEEK
 | 
						|
            BEQ     n_m_t
 | 
						|
            INC     neighbours
 | 
						|
            
 | 
						|
n_m_t       LDW     cells0      ; 0, -1 neighbour
 | 
						|
            SUBW    offset1
 | 
						|
            PEEK
 | 
						|
            BEQ     n_r_t
 | 
						|
            INC     neighbours
 | 
						|
 | 
						|
n_r_t       LDW     cells0      ; 1, -1 neighbour
 | 
						|
            SUBW    offset2
 | 
						|
            PEEK
 | 
						|
            BEQ     n_r_m
 | 
						|
            INC     neighbours
 | 
						|
 | 
						|
n_r_m       LDW     cells0      ; 1, 0 neighbour
 | 
						|
            ADDW    offset3
 | 
						|
            PEEK
 | 
						|
            BEQ     n_r_b
 | 
						|
            INC     neighbours
 | 
						|
            
 | 
						|
n_r_b       LDW     cells0      ; 1, 1 neighbour
 | 
						|
            ADDW    offset4
 | 
						|
            PEEK
 | 
						|
            BEQ     n_m_b
 | 
						|
            INC     neighbours
 | 
						|
            
 | 
						|
n_m_b       LDW     cells0      ; 0, 1 neighbour
 | 
						|
            ADDW    offset5
 | 
						|
            PEEK
 | 
						|
            BEQ     n_l_b
 | 
						|
            INC     neighbours
 | 
						|
            
 | 
						|
n_l_b       LDW     cells0      ; -1, 1 neighbour
 | 
						|
            ADDW    offset6
 | 
						|
            PEEK
 | 
						|
            BEQ     n_l_m
 | 
						|
            INC     neighbours            
 | 
						|
            
 | 
						|
n_l_m       LDW     cells0      ; -1, 0 neighbour
 | 
						|
            SUBW    offset7
 | 
						|
            PEEK
 | 
						|
            BEQ     cell_00
 | 
						|
            INC     neighbours                        
 | 
						|
            
 | 
						|
cell_00     LDW     cells0      ; 0, 0 cell
 | 
						|
            PEEK                ; get buffer0 cell
 | 
						|
            ST      n_lut_cell  ; save cell into neighbours lut
 | 
						|
 | 
						|
            LD      neighbours  ; lut evaluates neighbours count
 | 
						|
            ADDI    n_lut
 | 
						|
            POKE    lut_modify  ; lut_modify points to operand in "LD n_lut"
 | 
						|
lut         LD      n_lut       ; 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     buffer0     ; swap buffers
 | 
						|
            STW     scratch
 | 
						|
            LDW     buffer1
 | 
						|
            STW     buffer0
 | 
						|
            LDW     scratch
 | 
						|
            STW     buffer1
 | 
						|
            
 | 
						|
            BRA     n_l_t
 | 
						|
 |