Snake Game Code in Assembly Language
Snake Game Code in Assembly Language
jmp start
generaterandom:
pusha
mov ax,[cs:tickcount4]
checkifitisonoraboveupperboarder:
cmp ax,642
ja checkifitisonorbelowlowerboarder
add ax,160
cmp ax,642
jbe checkifitisonoraboveupperboarder
checkifitisonorbelowlowerboarder:
cmp ax,3516
jna checkifboarder
sub ax,160
cmp ax,3516
jae checkifitisonorbelowlowerboarder
checkifboarder:
mov ch,0x09
mov cl,'$'
mov bx,ax
cmp word[es:bx],cx
jne checkifonsnake
add ax,6
checkifonsnake:
mov bx,0
mov cx,[cs:lenght]
loopforcheckifonsnake:
cmp ax,[cs:screenpositon+bx]
je outofoutoflop
add bx,2
loop loopforcheckifonsnake
outofoutoflop:
mov bx,[cs:lenght]
shl bx,1
sub bx,2
outofloop:
mov cx,[cs:screenpositon+bx]
add cx,6
mov ax,cx
storefruitposition:
mov word[cs:positionoffruit],ax
popa
ret
printfruit:
pusha
mov ax,0xb800
mov es,ax
mov di,[cs:positionoffruit]
mov ah,0x04
mov al,'@'
mov word[es:di],ax
popa
ret
printscore:
pusha
mov ax,0xb800
mov es,ax
mov cx,13
mov di,278
mov ah,0x03
mov bx,0
loopforscoremessage:
mov al,[cs:scoremessage+bx]
mov word[es:di],ax
add di,2
inc bx
loop loopforscoremessage
mov ax,[cs:score]
push ax
call printnumforscore
popa
ret
printnumforscore:
push bp
mov bp, sp
push es
push ax
push bx
push cx
push dx
push di
nextdigitforscore:
mov dx, 0 ; zero upper half of dividend
div bx ; divide by 10
add dl, 0x30 ; convert digit into ascii value
push dx ; save ascii value on stack
inc cx ; increment count of values
cmp ax, 0 ; is the quotient zero
jnz nextdigitforscore ; if no divide it again
mov di, 304
nextposforscore:
pop dx ; remove a digit from the stack
mov dh, 0x04 ; use normal attribute
mov [es:di], dx ; print char on screen
add di, 2 ; move to next screen location
loop nextposforscore ; repeat for all digits on stack
pop di
pop dx
pop cx
pop bx
pop ax
pop es
pop bp
ret 2
increasespeed:
pusha
cmp word[cs:speed],1
je endofincreasespeed
cmp word[cs:speed],2
jne cmpfor4
mov word[cs:speed],1
jmp endofincreasespeed
cmpfor4:
cmp word[cs:speed],4
jne cmpfor8
mov word[cs:speed],2
jmp endofincreasespeed
cmpfor8:
cmp word[cs:speed],8
jne cmpfor32
mov word[cs:speed],4
jmp endofincreasespeed
cmpfor32:
cmp word[cs:speed],32
jne cmpfor16
mov word[cs:speed],16
jmp endofincreasespeed
cmpfor16:
cmp word[cs:speed],16
jne endofincreasespeed
mov word[cs:speed],8
endofincreasespeed:
popa
ret
printnum:
push bp
mov bp, sp
push es
push ax
push bx
push cx
push dx
push di
nextdigit:
mov dx, 0 ; zero upper half of dividend
div bx ; divide by 10
add dl, 0x30 ; convert digit into ascii value
push dx ; save ascii value on stack
inc cx ; increment count of values
cmp ax, 0 ; is the quotient zero
jnz nextdigit ; if no divide it again
mov di, 248
nextpos:
pop dx ; remove a digit from the stack
mov dh, 0x04 ; use normal attribute
mov [es:di], dx ; print char on screen
add di, 2 ; move to next screen location
loop nextpos ; repeat for all digits on stack
pop di
pop dx
pop cx
pop bx
pop ax
pop es
pop bp
ret 2
printtime:
pusha
mov ax,0xb800
mov es,ax
mov cx,12
mov di,220
mov ah,0x03
mov bx,0
loopfortimemessage:
mov al,[cs:timemessage+bx]
mov word[es:di],ax
add di,2
inc bx
loop loopfortimemessage
mov ah,0x04
mov al,[cs:minitues]
add al,0x30
mov word[es:di],ax
mov ah,0x04
mov al,':'
mov word[es:di+2],ax
mov ax,[cs:seconds]
cmp word[cs:seconds],9
jbe printsimpleseconds
push ax
call printnum
jmp endofprintnum
printsimpleseconds:
mov bx,[cs:seconds]
mov al,bl
add al,0x30
mov ah,0x04
mov bh,0x04
mov bl,'0'
mov word[es:di+4],bx
mov word[es:di+6],ax
endofprintnum:
popa
ret
printlives:
pusha
mov ax,0xb800
mov es,ax
mov cx,13
mov di,160
mov ah,0x03
mov bx,0
loopforlivesmessage:
mov al,[cs:livesmessage+bx]
mov word[es:di],ax
add di,2
inc bx
loop loopforlivesmessage
mov ah,0x04
mov al,[cs:lives]
add al,0x30
mov word[es:di],ax
popa
ret
extendlength:
pusha
mov cx,[cs:lenght]
mov bx,[cs:lenght]
sub bx,1
loopforextendlength:
mov al,[cs:snake+bx]
mov [cs:snake+bx+4],al
dec bx
loop loopforextendlength
mov cx,[cs:lenght]
mov bx,[cs:lenght]
shl bx,1
sub bx,2
loopforextendlengthofscreenpositon:
mov ax,[cs:screenpositon+bx]
mov word[cs:screenpositon+bx+8],ax
sub bx,2
loop loopforextendlengthofscreenpositon
add word[cs:lenght],4
popa
ret
reset:
pusha
call clrscr
call printboarders
call initializesnake
call printsnake
call generaterandom
call printfruit
mov word[cs:speed],32
mov word[cs:orientation],1
mov word[cs:score],0
call printscore
cmp byte[cs:lives],0
jne printingnormaltime
mov word[cs:seconds],0
mov byte[cs:minitues],0
call printtime
jmp endofreset
printingnormaltime:
mov word[cs:seconds],60
mov byte[cs:minitues],3
call printtime
endofreset:
popa
ret
clrscr:
push es
push ax
push cx
push di
xor di, di
mov ax, 0x0720
mov cx, 2000
cld
rep stosw
pop di
pop cx
pop ax
pop es
ret
printboarders:
pusha
mov ax,0xb800
mov es,ax
mov di,480
mov cx,160
mov ah,0x09
mov al,'$'
printupperboarder:
mov word[es:di],ax
add di,2
dec cx
loop printupperboarder
mov di,3520
mov cx,160
printlowerboarder:
mov word[es:di],ax
add di,2
dec cx
loop printlowerboarder
mov di,480
mov cx,20
printleftboarder:
mov word[es:di],ax
add di,160
loop printleftboarder
mov di,638
mov cx,20
printrightboarder:
mov word[es:di],ax
add di,160
loop printrightboarder
popa
ret
printsnake:
pusha
mov ax,0xb800
mov es,ax
mov di,1980
mov word cx,[cs:lenght]
mov bx,0
mov ah,0x06
mov si,0
loopforprintsnake:
mov al,[cs:snake+bx]
mov word[es:di],ax
mov word[cs:screenpositon+si],di
inc bx
add di,2
add si,2
loop loopforprintsnake
popa
ret
initializesnake:
pusha
mov word[cs:lenght],20
mov cx,20
mov byte[cs:snake+19],'+'
dec cx
mov bx,0
loopforinitializesnake:
mov byte[cs:snake+bx],'-'
inc bx
loop loopforinitializesnake
popa
ret
movright:
pusha
mov ax,0xb800
mov es,ax
cmp word[cs:orientation],3
je endofmovright
colissioncheckrightitself:
mov ah,0x06
mov al,'-'
mov di,[cs:screenpositon+si] ;Position OF HEAD
cmp ax,[es:di+2]
jne colissioncheckrightfruit
call reset
jmp endofmovright
colissioncheckrightfruit:
mov ah,0x04
mov al,'@'
mov di,[cs:screenpositon+si] ;Position OF HEAD
cmp ax,[es:di+2]
jne continuetomoveright
inc word[cs:score]
call generaterandom
call printfruit
call extendlength
mov si,[cs:screenpositon+8]
mov di,[cs:screenpositon+10]
sub di,si
checkupforrightfruit:
cmp di,160
jne checkdownforrightfruit
mov cx,4
mov ah,0x06
mov al,'-'
mov bx,6
placeupforrightfruit:
sub si,160
mov word[es:si],ax
mov [cs:screenpositon+bx],si
sub bx,2
loop placeupforrightfruit
jmp continuetomoveright
checkdownforrightfruit:
cmp di,-160
jne checkleftforrightfruit
mov cx,4
mov ah,0x06
mov al,'-'
mov bx,6
placedownforrightfruit:
add si,160
mov word[es:si],ax
mov [cs:screenpositon+bx],si
sub bx,2
loop placedownforrightfruit
jmp continuetomoveright
checkleftforrightfruit:
cmp di,2
jne checkrightforrightfruit
mov cx,4
mov ah,0x06
mov al,'-'
mov bx,6
placeleftforrightfruit:
sub si,2
mov word[es:si],ax
mov [cs:screenpositon+bx],si
sub bx,2
loop placeleftforrightfruit
jmp continuetomoveright
checkrightforrightfruit:
mov cx,4
mov ah,0x06
mov al,'-'
mov bx,6
placerightforrightfruit:
add si,2
mov word[es:si],ax
mov [cs:screenpositon+bx],si
sub bx,2
loop placerightforrightfruit
continuetomoveright:
mov word cx,[cs:lenght]
dec cx
mov word bx,[cs:lenght]
dec bx
mov ah,0x06
mov ax,[es:bx]
mov word[es:di],ax
mov [cs:screenpositon+si-2],di
mov di,bx
sub si,2
loop loopformovingright
mov dx,0x0720
mov word[es:di],dx
mov word[cs:orientation],1
endofmovright:
popa
ret
movup:
pusha
mov ax,0xb800
mov es,ax
cmp word[cs:orientation],4
je endofmovingup
colissioncheckupitself:
mov ah,0x06
mov al,'-'
mov di,[cs:screenpositon+si]
cmp ax,[es:di-160]
jne colissioncheckupfruit
call reset
jmp endofmovingup
colissioncheckupfruit:
mov ah,0x04
mov al,'@'
mov di,[cs:screenpositon+si]
cmp ax,[es:di-160]
jne continuetomoveup
inc word[cs:score]
call generaterandom
call printfruit
call extendlength
mov si,[cs:screenpositon+8]
mov di,[cs:screenpositon+10]
sub di,si
checkupforupfruit:
cmp di,160
jne checkdownforupfruit
mov cx,4
mov ah,0x06
mov al,'-'
mov bx,6
placeupforupfruit:
sub si,160
mov word[es:si],ax
mov [cs:screenpositon+bx],si
sub bx,2
loop placeupforupfruit
jmp continuetomoveup
checkdownforupfruit:
cmp di,-160
jne checkleftforupfruit
mov cx,4
mov ah,0x06
mov al,'-'
mov bx,6
placedownforupfruit:
add si,160
mov word[es:si],ax
mov [cs:screenpositon+bx],si
sub bx,2
loop placedownforupfruit
jmp continuetomoveup
checkleftforupfruit:
cmp di,2
jne checkrightforupfruit
mov cx,4
mov ah,0x06
mov al,'-'
mov bx,6
placeleftforupfruit:
sub si,2
mov word[es:si],ax
mov [cs:screenpositon+bx],si
sub bx,2
loop placeleftforupfruit
jmp continuetomoveup
checkrightforupfruit:
mov cx,4
mov ah,0x06
mov al,'-'
mov bx,6
placerightforupfruit:
add si,2
mov word[es:si],ax
mov [cs:screenpositon+bx],si
sub bx,2
loop placerightforupfruit
continuetomoveup:
mov word cx,[cs:lenght]
dec cx
mov word bx,[cs:lenght]
dec bx
mov ah,0x06
mov ax,[es:bx]
mov word[es:di],ax
mov [cs:screenpositon+si-2],di
mov di,bx
sub si,2
loop loopformovingup
mov dx,0x0720
mov word[es:di],dx
mov word[cs:orientation],2
endofmovingup:
popa
ret
movdown:
pusha
mov ax,0xb800
mov es,ax
cmp word[cs:orientation],2
je endofmovingdown
colissioncheckdownitself:
mov ah,0x06
mov al,'-'
mov di,[cs:screenpositon+si] ;Position OF HEAD
cmp ax,[es:di+160]
jne colissioncheckdownfruit
call reset
jmp endofmovingdown
colissioncheckdownfruit:
mov ah,0x04
mov al,'@'
mov di,[cs:screenpositon+si] ;Position OF HEAD
cmp ax,[es:di+160]
jne continuetomovedown
inc word[cs:score]
call generaterandom
call printfruit
call extendlength
mov si,[cs:screenpositon+8]
mov di,[cs:screenpositon+10]
sub di,si
checkupfordownfruit:
cmp di,160
jne checkdownfordownfruit
mov cx,4
mov ah,0x06
mov al,'-'
mov bx,6
placeupfordownfruit:
sub si,160
mov word[es:si],ax
mov [cs:screenpositon+bx],si
sub bx,2
loop placeupfordownfruit
jmp continuetomovedown
checkdownfordownfruit:
cmp di,-160
jne checkleftfordownfruit
mov cx,4
mov ah,0x06
mov al,'-'
mov bx,6
placedownfordownfruit:
add si,160
mov word[es:si],ax
mov [cs:screenpositon+bx],si
sub bx,2
loop placedownfordownfruit
jmp continuetomovedown
checkleftfordownfruit:
cmp di,2
jne checkrightfordownfruit
mov cx,4
mov ah,0x06
mov al,'-'
mov bx,6
placeleftfordownfruit:
sub si,2
mov word[es:si],ax
mov [cs:screenpositon+bx],si
sub bx,2
loop placeleftfordownfruit
jmp continuetomovedown
checkrightfordownfruit:
mov cx,4
mov ah,0x06
mov al,'-'
mov bx,6
placerightfordownfruit:
add si,2
mov word[es:si],ax
mov [cs:screenpositon+bx],si
sub bx,2
loop placerightfordownfruit
continuetomovedown:
mov ah,0x06
mov ax,[es:bx]
mov word[es:di],ax
mov [cs:screenpositon+si-2],di
mov di,bx
sub si,2
loop loopformovingdown
mov dx,0x0720
mov word[es:di],dx
mov word[cs:orientation],4
endofmovingdown:
popa
ret
movleft:
pusha
mov ax,0xb800
mov es,ax
cmp word[cs:orientation],1
je endofmovingleft
mov word si,[cs:lenght]
shl si,1
sub si,2
colissioncheckleft:
mov ah,0x09
mov al,'$'
mov di,[cs:screenpositon+si] ;Position OF HEAD
cmp ax,[es:di-2]
jne colissioncheckleftitself
call reset
jmp endofmovingleft
colissioncheckleftitself:
mov ah,0x06
mov al,'-'
mov di,[cs:screenpositon+si] ;Position OF HEAD
cmp ax,[es:di-2]
jne colissioncheckleftfruit
call reset
jmp endofmovingleft
colissioncheckleftfruit:
mov ah,0x04
mov al,'@'
mov di,[cs:screenpositon+si] ;Position OF HEAD
cmp ax,[es:di-2]
jne continuetomoveleft
inc word[cs:score]
call generaterandom
call printfruit
call extendlength
mov si,[cs:screenpositon+8]
mov di,[cs:screenpositon+10]
sub di,si
checkupforleftfruit:
cmp di,160
jne checkdownforleftfruit
mov cx,4
mov ah,0x06
mov al,'-'
mov bx,6
placeupforleftfruit:
sub si,160
mov word[es:si],ax
mov [cs:screenpositon+bx],si
sub bx,2
loop placeupforleftfruit
jmp continuetomoveleft
checkdownforleftfruit:
cmp di,-160
jne checkleftforleftfruit
mov cx,4
mov ah,0x06
mov al,'-'
mov bx,6
placedownforleftfruit:
add si,160
mov word[es:si],ax
mov [cs:screenpositon+bx],si
sub bx,2
loop placedownforleftfruit
jmp continuetomoveleft
checkleftforleftfruit:
cmp di,2
jne checkrightforleftfruit
mov cx,4
mov ah,0x06
mov al,'-'
mov bx,6
placeleftforleftfruit:
sub si,2
mov word[es:si],ax
mov [cs:screenpositon+bx],si
sub bx,2
loop placeleftforleftfruit
jmp continuetomoveleft
checkrightforleftfruit:
mov cx,4
mov ah,0x06
mov al,'-'
mov bx,6
placerightforleftfruit:
add si,2
mov word[es:si],ax
mov [cs:screenpositon+bx],si
sub bx,2
loop placerightforleftfruit
continuetomoveleft:
mov word cx,[cs:lenght]
dec cx
mov word bx,[cs:lenght]
dec bx
mov ah,0x06
mov ax,[es:bx]
mov word[es:di],ax
mov [cs:screenpositon+si-2],di
mov di,bx
sub si,2
loop loopformovingleft
mov dx,0x0720
mov word[es:di],dx
mov word[cs:orientation],3
endofmovingleft:
popa
ret
timer:
pusha
inc word[cs:tickcount]
inc word[cs:tickcount2]
inc word[cs:tickcount3]
inc word[cs:tickcount4]
inc word[cs:tickcount4]
checkrandom:
cmp word[cs:tickcount4],4000
jne check20seconds
mov word[cs:tickcount4],0
check20seconds:
cmp word[cs:tickcount3],364
jne checklive
call increasespeed
mov word[cs:tickcount3],0
checklive:
cmp byte[cs:lives],0
je endoftimer
checkminitues:
cmp word[cs:seconds],0
jne checkseconds
cmp byte[cs:minitues],0
jne checkremaining
call reset
jmp endoftimer
checkremaining:
dec byte[cs:minitues]
mov byte[cs:seconds],60
jmp checktickcount
checkseconds:
cmp word[cs:tickcount2],18
jne checktickcount
dec word[cs:seconds]
mov byte[cs:tickcount2],0
call printtime
call printscore
checktickcount:
mov ax,[cs:speed]
cmp word[cs:tickcount],ax
jng endoftimer
ifright:
cmp word[cs:orientation],1
jne ifup
call movright
mov word[cs:tickcount],0
ifup:
cmp word[cs:orientation],2
jne ifleft
call movup
mov word[cs:tickcount],0
ifleft:
cmp word[cs:orientation],3
jne ifdown
call movleft
mov word[cs:tickcount],0
ifdown:
cmp word[cs:orientation],4
jne endoftimer
call movdown
mov word[cs:tickcount],0
endoftimer:
mov al, 0x20
out 0x20, al ; end of interrupt
popa
iret ; return from interrupt
kbisr:
pusha
cmp byte[cs:lives],0
je endofkbisr
in al,0x60
cmp al,0x4D ;compare with Right
jne compareUp
call movright
jmp endofkbisr
compareUp:
cmp al,0x48 ;compare
jne compareDown
call movup
jmp endofkbisr
compareDown:
cmp al,0x50
jne compareLeft
call movdown
jmp endofkbisr
compareLeft:
cmp al,0x4B
jne endofkbisr
call movleft
endofkbisr:
mov al,0x20
out 0x20,al
popa
iret
start:
call clrscr
call printboarders
call initializesnake
call printsnake
call printlives
call printtime
call printscore
;call generaterandom
mov ax,0xb800
mov es,ax
mov ah,0x04
mov al,'@'
mov [es:2060],ax
mov word[cs:orientation],1
xor ax, ax
mov es, ax ; point es to IVT base
cli ; disable interrupts
mov word [es:9*4], kbisr; store offset at n*4
mov [es:9*4+2], cs ; store segment at n*4+2
sti ; enable interrupts
xor ax, ax
mov es, ax ; point es to IVT base
cli ; disable interrupts
mov word [es:8*4], timer; store offset at n*4
mov [es:8*4+2], cs ; store segment at n*4+2
sti ; enable interrupts
exit: