;
Source / Exemple :
;The Game of Life is a cellular automata program, where each pixel on the screen
;will live or die in each generation based upon some arbitrary rules.
;Specifically, if a pixel has three neighbors, it lives to the next generation.
;If an empty cell has two neighbors, it becomes populated in the next generation.
;Otherwise, that pixel gets cleared for the next generation. In this program, we
;generate an initial screen image using the paint program from last class. We
;then make a future image of the video screen in our offscreen buffer, then when
;complete, copy to the video.
; source file for assembling to binary files
; build with:
; nasmw -f bin -o life.com life.asm
org 100h
section .text
mov ax,13h
int 10h ;256 color graphics mode
mov ax,0a000h ;video buffer
mov es,ax ;pointer for segment
xor di,di ;offset
mov cx,32000 ;number of words in video
xor ax,ax ;clear AX
rep stosw ;and store in video buffer
mov ax,1 ;show mouse
int 33h
M0:
mov ax,0b21h ;check keyboard status
int 21h
cmp al,0 ;are any characters pending?
jne Game
mov ax,3 ;get mouse status call
int 33h
cmp bx,0 ;is mouse up
je M0 ;loop till pressed
M1: mov ax,0b21h ;check keyboard status
int 21h
cmp al,0 ;are any characters pending?
jne Game
mov ax,3 ;get fresh copy of mouse coordinates
int 33h
mov ah,0ch ;write dot at coordinate
mov al,1 ;color value
shr cx,1 ;mouse scale offset fix
dec cx ;escape mouse overwrite in win95
int 10h
mov ax,3
int 33h
cmp bx,0
jne M1
mov ax,0b21h ;check keyboard status
int 21h
cmp al,0 ;are any characters pending?
je M0
Game:
mov ax,2 ;hide cursor function
int 33h
mov cx,100
G1: mov ax,ds ;segment address
mov es,ax ;now pointed to by ES
push cx
mov di,Screen
mov cx,32000 ;number of words in video
xor ax,ax ;clear AX
rep stosw ;and store in video buffer (cleared)
mov word [X],318 ;X goes from 1 to 318 (0 to 319 excluding boundaries)
G2: mov word [Y],198 ;Y goes from 1 to 198 (0 to 199 excluding boundaries)
G3: call Count ;count of neighbors lands in AX
cmp AX,2 ;survive threshold
jne G4 ;if not, check for three
call GetDot ;do we have a current cell here to survive?
je G4 ;if not, don't set
call SetDot ;make color 2
G4: cmp AX,3 ;check generation
jne G5 ;no spawn if not 3
call SetDot ;else set color 3
G5: dec word[Y] ;move up
jne G3 ;if not at top
dec word[X] ;move left
jne G2 ;if not at left
mov ax,0a000h ;video buffer
mov es,ax
xor di,di ;destination pointer
mov si,Screen ;source pointer
mov cx,32000
rep movsw ;copy to video
mov ax,ds ;reset extra segment to data segment
mov es,ax
pop cx
loop G1
mov ax,3 ;put video back into text mode
int 10h
mov ax,4c00h
int 21h
GetDot: ;check for cell on screen at coordinates in X and Y
push ax
push bx
push dx
push es
mov ax,0a000h ;video segment
mov es,ax ;pointer
mov ax,[Y] ;y coord
mov bx,320 ;dots per Y
mul bx ;DX:AX has answer (DX = 0, AX = row offset)
add ax,[X] ;add X coordinate
mov bx,ax ;use BX as pointer
mov al,[es:bx] ;get
cmp al,0 ;is cell zero? return in flag
pop es
pop dx
pop bx
pop ax
ret
SetDot: ;mov al to coordinates in X and Y
push ax
push bx
push dx
push ax ;store data on stack
mov ax,[Y] ;y coord
mov bx,320 ;dots per Y
mul bx ;DX:AX has answer (DX = 0, AX = row offset)
add ax,[X] ;add X coordinate
mov bx,ax ;use BX as pointer
add bx,Screen ;add in offset of screen buffer
pop ax ;get count value as color
mov [es:bx],al ;store
pop dx
pop bx
pop ax
ret
Count:
push bx
push cx
push dx
push es
mov ax,0a000h ;video buffer segment
mov es,ax
mov ax,[Y] ;y coord
mov bx,320 ;dots per Y
mul bx ;DX:AX has answer (DX = 0, AX = row offset)
add ax,[X] ;add X coordinate
mov bx,ax ;use BX as pointer
xor ax,ax ;clear AX
xor dx,dx ;just a convenient zero
; 2 3 4
; 0 1
; 5 6 7
cmp dl,[es:bx-1] ;check left
je C1 ;if clear, skip add
inc ax
C1: cmp dl,[es:bx+1] ;check right
je C2 ;if clear, skip add
inc ax
C2: cmp dl,[es:bx-321] ;check top left
je C3 ;if clear, skip add
inc ax
C3: cmp dl,[es:bx-320] ;check above
je C4 ;if clear, skip add
inc ax
C4: cmp dl,[es:bx-319] ;check upper right
je C5 ;if clear, skip add
inc ax
C5: cmp dl,[es:bx+319] ;check below left
je C6 ;if clear, skip add
inc ax
C6: cmp dl,[es:bx+320] ;check below
je C7 ;if clear, skip add
inc ax
C7: cmp dl,[es:bx+321] ;check below right
je C8 ;if clear, skip add
inc ax
C8: pop es
pop dx
pop cx
pop bx
ret
section .data
X dw 0 ;X coordinate during regeneration
Y dw 0 ;Y coordinate during regeneration
section .bss
Screen resb 64000 ;copy of screen in mode 13H
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.