1 votes
Game of Life
submitted 405 days ago by FireFly to Games
(0 comments | 1597 views)
An implementation of Conway's Game of Life [1] in DCPU-16 assembly. The initial state is hard-coded.
Try it out in DeNULL's emulator [2]!
[1] http://en.wikipedia.org/wiki/Conway's_Game_of_Life
[2] http://denull.ru/dcpu/dcpu.htm
Source Code
Download .dasm16 file |
; X : width
; Y : height
; C : current cell mask (01b or 10b)
; 0x1000 ... : cell states
; Set width/height
set X, 0x10 ; width
set Y, 0x08 ; height
set C, 0x1 ; 01b
; Setup a glider in the top left corner
set A, 0x01
set B, 0x00
jsr toggle
set A, 0x02
set B, 0x01
jsr toggle
set A, 0x00
set B, 0x02
jsr toggle
set A, 0x01
set B, 0x02
jsr toggle
set A, 0x02
set B, 0x02
jsr toggle
:mainloop jsr output
jsr tick
set PC, mainloop
; Toggles the given cell. NOTE: only safe before starting
:toggle ;(x, y)
mul B, X
add A, B
add A, 0x1000 ; A : correct cell offset
xor [A], 0x1 ; toggle it!
set PC, POP
; Uses the observation that the GoL rules can be summarized as `(t | n) == 3`,
; where `t` is the state of the current cell (1 or 0) and `n` is the sum of the
; states of the neighbours (i.e. the number of living neighbours).
; In each cell memory slot, two statse are stored (in bit 0 and bit 1); the
; `C` register keeps track of a bitmask of which state is the "current" one.
; Advance a generation (in-memory)
:tick
set I, Y ; let I be loop counter
mul I, X
:loop ife I, 0 ; loop until I=0
set PC, loopend
add I, 0xfff ; (Temporarily)
set A, [1+I] ; set A to value at cell (t)
and A, C
; Set B to (sum of neighbours << (C - 1))
set B, [I]
and B, C
set J, [2+I]
and J, C
add B, J
sub I, X
set J, [I]
and J, C
add B, J
set J, [1+I]
and J, C
add B, J
set J, [2+I]
and J, C
add B, J
add I, X
add I, X
set J, [I]
and J, C
add B, J
set J, [1+I]
and J, C
add B, J
set J, [2+I]
and J, C
add B, J
; Prepare stuff
sub C, 1
shr B, C
shr A, C
; Set B to (t | n)
bor B, A
; Set the new state
ifn B, 3
set B, 0
and B, 0x2 ; B to {00b, 10b} >> (c-1)
shr B, C
add C, 1
sub I, X
and [1+I], C
xor [1+I], B
sub I, 0x1000 ; Restore I again, also decrement by 1
; Next iteration
set PC, loop
:loopend ; clean up & return
xor C, 0x3
set PC, POP
; Output current state to display
:output
set I, Y ; let I be loop counter
mul I, X
:loop2 ife I, 0 ; loop until I=0
set PC, loop2end
sub I, 1
set A, [0x1000+I] ; set A to value at cell (t)
and A, C
sub C, 1
shr A, C
add C, 1
mul A, 3
add A, 0xf120
set Z, I ; prepare output position
set J, I
div Z, X
mod J, X
mul Z, 0x20 ; 0x20 = display width
add J, Z
add J, 0x8000
set [J], A
; Next iteration
set PC, loop2
:loop2end ; clean up & return
set PC, POP

Comments
Sign in to comment and vote
No comments yet