Skip to content

Instantly share code, notes, and snippets.

@root42

root42/life.asm Secret

Last active May 27, 2020 06:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save root42/1da0be15cfd7c0edb302e52d107ba3ff to your computer and use it in GitHub Desktop.
Save root42/1da0be15cfd7c0edb302e52d107ba3ff to your computer and use it in GitHub Desktop.
Game of Life x86
.8086
.MODEL tiny
.CODE
org 100h
start:
mov ax,0013h
int 10h
mov al,MEMORY_MODE
mov ah,06h
mov dx,SC_INDEX
out dx,ax
mov al,UNDERLINE_LOCATION
mov ah,00h
mov dx,CRTC_INDEX
out dx,ax
mov al,MODE_CONTROL
mov ah,0e3h
out dx,ax
mov ax,01h ; c
push ax
mov ax,64h ; y
push ax
mov ax,100h ; x
push ax
mov ax,0h ; page
push ax
call set_pixel
mov ax,01h ; c
push ax
mov ax,64h ; y
push ax
mov ax,101h ; x
push ax
mov ax,0h ; page
push ax
call set_pixel
mov ax,01h ; c
push ax
mov ax,64h ; y
push ax
mov ax,102h ; x
push ax
mov ax,0h ; page
push ax
call set_pixel
mainloop:
; set vga page
mov dx,CRTC_INDEX
mov ax,vgapage1
mov al,START_REG_HIGH
out dx,ax
mov dx,CRTC_INDEX
mov ax,vgapage1
mov cl,8
shl ax,cl
mov al,START_REG_LOW
out dx,ax
; do vsync
loop1:
mov dx,INPUT_STATUS
in al,dx
and al,08h
jnz loop1
loop2:
mov dx,INPUT_STATUS
in al,dx
and al,08h
jz loop2
; update game state
call update_game
mov ax,vgapage1
mov bx,vgapage2
mov vgapage2,ax
mov vgapage1,bx
mov ah,01h
dec frames
jz exit
int 16h
jz mainloop
exit:
mov ax,0003h
int 10h
mov ax,4c00h
int 21h
update_game proc
push bp
mov bp,sp
mov ax,max_y
mov line,ax
loop_lines:
mov ax,max_x
mov column,ax
loop_columns:
call acc_neighbors
dec column
jnz loop_columns
dec line
jnz loop_lines
pop bp
ret
endp update_game
acc_neighbors proc
push bp
mov bp,sp
; read current pixel (alive or dead)
mov ax,line
mov pixel_y,ax
mov ax,column
mov pixel_x,ax
push pixel_y
push pixel_x
push vgapage1
call get_pixel
mov current_pixel,al
; accumulate all 8 neighbors
mov neighbors,0
; -1,-1
mov ax,line
mov pixel_y,ax
mov ax,column
mov pixel_x,ax
dec pixel_y
dec pixel_x
push pixel_y
push pixel_x
push vgapage1
call get_pixel
add neighbors,al
; 0,-1
inc pixel_x
push pixel_y
push pixel_x
push vgapage1
call get_pixel
add neighbors,al
; 1,-1
inc pixel_x
push pixel_y
push pixel_x
push vgapage1
call get_pixel
add neighbors,al
; 1,0
inc pixel_y
push pixel_y
push pixel_x
push vgapage1
call get_pixel
add neighbors,al
; -1,0
dec pixel_x
dec pixel_x
push pixel_y
push pixel_x
push vgapage1
call get_pixel
add neighbors,al
; -1,1
inc pixel_y
push pixel_y
push pixel_x
push vgapage1
call get_pixel
add neighbors,al
; 0,1
inc pixel_x
push pixel_y
push pixel_x
push vgapage1
call get_pixel
add neighbors,al
; 1,1
inc pixel_x
push pixel_y
push pixel_x
push vgapage1
call get_pixel
add neighbors,al
pop bp
ret
endp acc_neighbors
set_pixel proc
arg vgapage:word, x:word, y:word, c:byte
push bp
mov bp,sp
push ds
;select VGA plane
mov cx,x
and cl,3
mov ah,1
shl ah,cl
mov al,MAP_MASK
mov dx,SC_INDEX
out dx,ax
;compute vga offset
mov ax,y
mov bx,ax
mov cl,8
shl ax,cl
mov cl,6
shl bx,cl
add ax,bx
mov cl,2
shr ax,cl
mov bx,x
shr bx,cl
add ax,bx
add ax,vgapage
mov dx,VGA_MEM
mov ds,dx
mov di,ax
mov al,c
mov ds:[di],al
pop ds
pop bp
ret
set_pixel endp
get_pixel proc
arg vgapage:word, x:word, y:word
push bp
mov bp,sp
push ds
;select VGA plane
mov cx,x
and cl,3
mov ah,1
shl ah,cl
mov al,MAP_MASK
mov dx,SC_INDEX
out dx,ax
;compute vga offset
mov ax,y
mov bx,ax
mov cl,8
shl ax,cl
mov cl,6
shl bx,cl
add ax,bx
mov cl,2
shr ax,cl
mov bx,x
shr bx,cl
add ax,bx
add ax,vgapage
mov dx,VGA_MEM
mov ds,dx
mov di,ax
mov al,ds:[di]
pop ds
pop bp
ret
get_pixel endp
neighbors db 0
current_pixel db 0
column dw 0
line dw 0
pixel_x dw 0
pixel_y dw 0
frames dw 1000
vgapage1 dw 0
vgapage2 dw 16000
max_x dw 319
max_y dw 199
SC_INDEX equ 03c4h
SC_DATA equ 03c5h
CRTC_INDEX equ 03d4h
CRTC_DATA equ 03d5h
MEMORY_MODE equ 04h
UNDERLINE_LOCATION equ 014h
CRTC_INDEX equ 03d4h
INPUT_STATUS equ 03dah
MODE_CONTROL equ 017h
MAP_MASK equ 02h
VGA_MEM equ 0A000h
START_REG_HIGH equ 0ch
START_REG_LOW equ 0dh
end start
@rehaby
Copy link

rehaby commented May 27, 2020

I think you need to pop the function parameters than you are pushing. Apparently ret can take a number of bytes to pop off the stack

@root42
Copy link
Author

root42 commented May 27, 2020

Yes, indeed. We established that in the YouTube comments as well. :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment