NotesWhat is notes.io?

Notes brand slogan

Notes - notes.io

;code is not well-commented, sorry about that, I'll try to comment it nice and well, but can't make any
;promises, Also, this code writes directly into the video memory instead of int 21H (21H is slow) except
;at some certain points (like displaying scores and the intro)

;and next time someone tells you to not use goto, ask them to code in assembly without goto... :P

left equ 0
top equ 2
row equ 15
col equ 40
right equ left+col
bottom equ top+row

.model small
.data
msg db "Welcome to the snake game!!",0
instructions db 0AH,0DH,"Use a, s, d and f to control your snake",0AH,0DH,"Use q anytime to quit",0DH,0AH, "Press any key to continue$"
quitmsg db "Thanks for playing! hope you enjoyed",0
gameovermsg db "OOPS!! your snake died! :P ", 0
scoremsg db "Score: ",0
head db '^',10,10
body db '*',10,11, 3*15 DUP(0)
segmentcount db 1
fruitactive db 1
fruitx db 8
fruity db 8
gameover db 0
quit db 0
delaytime db 5


.stack
dw 128 dup(0)


.code

main proc far
mov ax, @data
mov ds, ax

mov ax, 0b800H
mov es, ax

;clearing the screen
mov ax, 0003H
int 10H

lea bx, msg
mov dx,00
call writestringat

lea dx, instructions
mov ah, 09H
int 21h

mov ah, 07h
int 21h
mov ax, 0003H
int 10H
call printbox


mainloop:
call delay
lea bx, msg
mov dx, 00
call writestringat
call shiftsnake
cmp gameover,1
je gameover_mainloop

call keyboardfunctions
cmp quit, 1
je quitpressed_mainloop
call fruitgeneration
call draw

;TODO: check gameover and quit

jmp mainloop

gameover_mainloop:
mov ax, 0003H
int 10H
mov delaytime, 100
mov dx, 0000H
lea bx, gameovermsg
call writestringat
call delay
jmp quit_mainloop

quitpressed_mainloop:
mov ax, 0003H
int 10H
mov delaytime, 100
mov dx, 0000H
lea bx, quitmsg
call writestringat
call delay
jmp quit_mainloop




quit_mainloop:
;first clear screen
mov ax, 0003H
int 10h
mov ax, 4c00h
int 21h






delay proc

;this procedure uses 1A interrupt, more info can be found on
;http://www.computing.dcu.ie/~ray/teaching/CA296/notes/8086_bios_and_dos_interrupts.html
mov ah, 00
int 1Ah
mov bx, dx

jmp_delay:
int 1Ah
sub dx, bx
;there are about 18 ticks in a second, 10 ticks are about enough
cmp dl, delaytime
jl jmp_delay
ret

delay endp




fruitgeneration proc
mov ch, fruity
mov cl, fruitx
regenerate:

cmp fruitactive, 1
je ret_fruitactive
mov ah, 00
int 1Ah
;dx contains the ticks
push dx
mov ax, dx
xor dx, dx
xor bh, bh
mov bl, row
dec bl
div bx
mov fruity, dl
inc fruity


pop ax
mov bl, col
dec dl
xor bh, bh
xor dx, dx
div bx
mov fruitx, dl
inc fruitx

cmp fruitx, cl
jne nevermind
cmp fruity, ch
jne nevermind
jmp regenerate
nevermind:
mov al, fruitx
ror al,1
jc regenerate


add fruity, top
add fruitx, left

mov dh, fruity
mov dl, fruitx
call readcharat
cmp bl, '*'
je regenerate
cmp bl, '^'
je regenerate
cmp bl, '<'
je regenerate
cmp bl, '>'
je regenerate
cmp bl, 'v'
je regenerate

ret_fruitactive:
ret
fruitgeneration endp


dispdigit proc
add dl, '0'
mov ah, 02H
int 21H
ret
dispdigit endp

dispnum proc
test ax,ax
jz retz
xor dx, dx
;ax contains the number to be displayed
;bx must contain 10
mov bx,10
div bx
;dispnum ax first.
push dx
call dispnum
pop dx
call dispdigit
ret
retz:
mov ah, 02
ret
dispnum endp



;sets the cursor position, ax and bx used, dh=row, dl = column
;preserves other registers
setcursorpos proc
mov ah, 02H
push bx
mov bh,0
int 10h
pop bx
ret
setcursorpos endp



draw proc
lea bx, scoremsg
mov dx, 0109
call writestringat


add dx, 7
call setcursorpos
mov al, segmentcount
dec al
xor ah, ah
call dispnum

lea si, head
draw_loop:
mov bl, ds:[si]
test bl, bl
jz out_draw
mov dx, ds:[si+1]
call writecharat
add si,3
jmp draw_loop

out_draw:
mov bl, 'F'
mov dh, fruity
mov dl, fruitx
call writecharat
mov fruitactive, 1

ret



draw endp



;dl contains the ascii character if keypressed, else dl contains 0
;uses dx and ax, preserves other registers
readchar proc
mov ah, 01H
int 16H
jnz keybdpressed
xor dl, dl
ret
keybdpressed:
;extract the keystroke from the buffer
mov ah, 00H
int 16H
mov dl,al
ret


readchar endp







keyboardfunctions proc

call readchar
cmp dl, 0
je next_14

;so a key was pressed, which key was pressed then solti?
cmp dl, 'w'
jne next_11
cmp head, 'v'
je next_14
mov head, '^'
ret
next_11:
cmp dl, 's'
jne next_12
cmp head, '^'
je next_14
mov head, 'v'
ret
next_12:
cmp dl, 'a'
jne next_13
cmp head, '>'
je next_14
mov head, '<'
ret
next_13:
cmp dl, 'd'
jne next_14
cmp head, '<'
je next_14
mov head,'>'
next_14:
cmp dl, 'q'
je quit_keyboardfunctions
ret
quit_keyboardfunctions:
;conditions for quitting in here please
inc quit
ret

keyboardfunctions endp








shiftsnake proc
mov bx, offset head

;determine the where should the head go solti?
;preserve the head
xor ax, ax
mov al, [bx]
push ax
inc bx
mov ax, [bx]
inc bx
inc bx
xor cx, cx
l:
mov si, [bx]
test si, [bx]
jz outside
inc cx
inc bx
mov dx,[bx]
mov [bx], ax
mov ax,dx
inc bx
inc bx
jmp l

outside:


;hopefully, the snake will be shifted, i.e. moved.
;now shift the head in its proper direction and then clear the last segment.
;But don't clear the last segment if the snake has eaten the fruit
pop ax
;al contains the snake head direction

push dx
;dx now consists the coordinates of the last segment, we can use this to clear it


lea bx, head
inc bx
mov dx, [bx]

cmp al, '<'
jne next_1
dec dl
dec dl
jmp done_checking_the_head
next_1:
cmp al, '>'
jne next_2
inc dl
inc dl
jmp done_checking_the_head

next_2:
cmp al, '^'
jne next_3
dec dh


jmp done_checking_the_head

next_3:
;must be 'v'
inc dh

done_checking_the_head:
mov [bx],dx
;dx contains the new position of the head, now check whats in that position
call readcharat ;dx
;bl contains the result

cmp bl, 'F'
je i_ate_fruit

;if fruit was not eaten, then clear the last segment,
;it will be cleared where?
mov cx, dx
pop dx
cmp bl, '*' ;the snake bit itself, gameover
je game_over
mov bl, 0
call writecharat
mov dx, cx





;check whether the snake is within the boundary
cmp dh, top
je game_over
cmp dh, bottom
je game_over
cmp dl,left
je game_over
cmp dl, right
je game_over



;balance the stack, number of segment and the coordinate of the last segment

ret
game_over:
inc gameover
ret
i_ate_fruit:

; add a new segment then
mov al, segmentcount
xor ah, ah


lea bx, body
mov cx, 3
mul cx

pop dx
add bx, ax
mov byte ptr ds:[bx], '*'
mov [bx+1], dx
inc segmentcount
mov dh, fruity
mov dl, fruitx
mov bl, 0
call writecharat
mov fruitactive, 0
ret
shiftsnake endp













;Printbox
printbox proc
;Draw a box around
mov dh, top
mov dl, left
mov cx, col
mov bl, '*'
l1:
call writecharat
inc dl
loop l1

mov cx, row
l2:
call writecharat
inc dh
loop l2

mov cx, col
l3:
call writecharat
dec dl
loop l3

mov cx, row
l4:
call writecharat
dec dh
loop l4

ret
printbox endp









;dx contains row, col
;bl contains the character to write
;uses di.
writecharat proc
;80x25
push dx
mov ax, dx
and ax, 0FF00H
shr ax,1
shr ax,1
shr ax,1
shr ax,1
shr ax,1
shr ax,1
shr ax,1
shr ax,1


push bx
mov bh, 160
mul bh
pop bx
and dx, 0FFH
shl dx,1
add ax, dx
mov di, ax
mov es:[di], bl
pop dx
ret
writecharat endp









;dx contains row,col
;returns the character at bl
;uses di
readcharat proc
push dx
mov ax, dx
and ax, 0FF00H
shr ax,1
shr ax,1
shr ax,1
shr ax,1
shr ax,1
shr ax,1
shr ax,1
shr ax,1
push bx
mov bh, 160
mul bh
pop bx
and dx, 0FFH
shl dx,1
add ax, dx
mov di, ax
mov bl,es:[di]
pop dx
ret
readcharat endp








;dx contains row, col
;bx contains the offset of the string
writestringat proc
push dx
mov ax, dx
and ax, 0FF00H
shr ax,1
shr ax,1
shr ax,1
shr ax,1
shr ax,1
shr ax,1
shr ax,1
shr ax,1

push bx
mov bh, 160
mul bh

pop bx
and dx, 0FFH
shl dx,1
add ax, dx
mov di, ax
loop_writestringat:

mov al, [bx]
test al, al
jz exit_writestringat
mov es:[di], al
inc di
inc di
inc bx
jmp loop_writestringat


exit_writestringat:
pop dx
ret


writestringat endp






main endp

end main
     
 
what is notes.io
 

Notes.io is a web-based application for taking notes. You can take your notes and share with others people. If you like taking long notes, notes.io is designed for you. To date, over 8,000,000,000 notes created and continuing...

With notes.io;

  • * You can take a note from anywhere and any device with internet connection.
  • * You can share the notes in social platforms (YouTube, Facebook, Twitter, instagram etc.).
  • * You can quickly share your contents without website, blog and e-mail.
  • * You don't need to create any Account to share a note. As you wish you can use quick, easy and best shortened notes with sms, websites, e-mail, or messaging services (WhatsApp, iMessage, Telegram, Signal).
  • * Notes.io has fabulous infrastructure design for a short link and allows you to share the note as an easy and understandable link.

Fast: Notes.io is built for speed and performance. You can take a notes quickly and browse your archive.

Easy: Notes.io doesn’t require installation. Just write and share note!

Short: Notes.io’s url just 8 character. You’ll get shorten link of your note when you want to share. (Ex: notes.io/q )

Free: Notes.io works for 12 years and has been free since the day it was started.


You immediately create your first note and start sharing with the ones you wish. If you want to contact us, you can use the following communication channels;


Email: [email protected]

Twitter: http://twitter.com/notesio

Instagram: http://instagram.com/notes.io

Facebook: http://facebook.com/notesio



Regards;
Notes.io Team

     
 
Shortened Note Link
 
 
Looding Image
 
     
 
Long File
 
 

For written notes was greater than 18KB Unable to shorten.

To be smaller than 18KB, please organize your notes, or sign in.