/examples/snake.asm

https://github.com/willianma/emu8086 · Assembly · 259 lines · 136 code · 68 blank · 55 comment · 0 complexity · 4de350d797119f67cb119d113ea5acc3 MD5 · raw file

  1. ; this is the screen eating snake game...
  2. ;
  3. ; this game pushes the emulator to its limits,
  4. ; and even with maximum speed it still runs slowly.
  5. ; to enjoy this game it's recommended to run it on real
  6. ; computer, however the emulator can be useful to debug
  7. ; tiny games and other similar programs such as this before
  8. ; they become bug-free and workable.
  9. ;
  10. ; you can control the snake using arrow keys on your keyboard.
  11. ;
  12. ; all other keys will stop the snake.
  13. ;
  14. ; press esc to exit.
  15. name "snake"
  16. org 100h
  17. ; jump over data section:
  18. jmp start
  19. ; ------ data section ------
  20. s_size equ 7
  21. ; the snake coordinates
  22. ; (from head to tail)
  23. ; low byte is left, high byte
  24. ; is top - [top, left]
  25. snake dw s_size dup(0)
  26. tail dw ?
  27. ; direction constants
  28. ; (bios key codes):
  29. left equ 4bh
  30. right equ 4dh
  31. up equ 48h
  32. down equ 50h
  33. ; current snake direction:
  34. cur_dir db right
  35. wait_time dw 0
  36. ; welcome message
  37. msg db "==== how to play ====", 0dh,0ah
  38. db "this game was debugged on emu8086", 0dh,0ah
  39. db "but it is not designed to run on the emulator", 0dh,0ah
  40. db "because it requires relatively fast video card and cpu.", 0dh,0ah, 0ah
  41. db "if you want to see how this game really works,", 0dh,0ah
  42. db "run it on a real computer (click external->run from the menu).", 0dh,0ah, 0ah
  43. db "you can control the snake using arrow keys", 0dh,0ah
  44. db "all other keys will stop the snake.", 0dh,0ah, 0ah
  45. db "press esc to exit.", 0dh,0ah
  46. db "====================", 0dh,0ah, 0ah
  47. db "press any key to start...$"
  48. ; ------ code section ------
  49. start:
  50. ; print welcome message:
  51. mov dx, offset msg
  52. mov ah, 9
  53. int 21h
  54. ; wait for any key:
  55. mov ah, 00h
  56. int 16h
  57. ; hide text cursor:
  58. mov ah, 1
  59. mov ch, 2bh
  60. mov cl, 0bh
  61. int 10h
  62. game_loop:
  63. ; === select first video page
  64. mov al, 0 ; page number.
  65. mov ah, 05h
  66. int 10h
  67. ; === show new head:
  68. mov dx, snake[0]
  69. ; set cursor at dl,dh
  70. mov ah, 02h
  71. int 10h
  72. ; print '*' at the location:
  73. mov al, '*'
  74. mov ah, 09h
  75. mov bl, 0eh ; attribute.
  76. mov cx, 1 ; single char.
  77. int 10h
  78. ; === keep the tail:
  79. mov ax, snake[s_size * 2 - 2]
  80. mov tail, ax
  81. call move_snake
  82. ; === hide old tail:
  83. mov dx, tail
  84. ; set cursor at dl,dh
  85. mov ah, 02h
  86. int 10h
  87. ; print ' ' at the location:
  88. mov al, ' '
  89. mov ah, 09h
  90. mov bl, 0eh ; attribute.
  91. mov cx, 1 ; single char.
  92. int 10h
  93. check_for_key:
  94. ; === check for player commands:
  95. mov ah, 01h
  96. int 16h
  97. jz no_key
  98. mov ah, 00h
  99. int 16h
  100. cmp al, 1bh ; esc - key?
  101. je stop_game ;
  102. mov cur_dir, ah
  103. no_key:
  104. ; === wait a few moments here:
  105. ; get number of clock ticks
  106. ; (about 18 per second)
  107. ; since midnight into cx:dx
  108. mov ah, 00h
  109. int 1ah
  110. cmp dx, wait_time
  111. jb check_for_key
  112. add dx, 4
  113. mov wait_time, dx
  114. ; === eternal game loop:
  115. jmp game_loop
  116. stop_game:
  117. ; show cursor back:
  118. mov ah, 1
  119. mov ch, 0bh
  120. mov cl, 0bh
  121. int 10h
  122. ret
  123. ; ------ functions section ------
  124. ; this procedure creates the
  125. ; animation by moving all snake
  126. ; body parts one step to tail,
  127. ; the old tail goes away:
  128. ; [last part (tail)]-> goes away
  129. ; [part i] -> [part i+1]
  130. ; ....
  131. move_snake proc near
  132. ; set es to bios info segment:
  133. mov ax, 40h
  134. mov es, ax
  135. ; point di to tail
  136. mov di, s_size * 2 - 2
  137. ; move all body parts
  138. ; (last one simply goes away)
  139. mov cx, s_size-1
  140. move_array:
  141. mov ax, snake[di-2]
  142. mov snake[di], ax
  143. sub di, 2
  144. loop move_array
  145. cmp cur_dir, left
  146. je move_left
  147. cmp cur_dir, right
  148. je move_right
  149. cmp cur_dir, up
  150. je move_up
  151. cmp cur_dir, down
  152. je move_down
  153. jmp stop_move ; no direction.
  154. move_left:
  155. mov al, b.snake[0]
  156. dec al
  157. mov b.snake[0], al
  158. cmp al, -1
  159. jne stop_move
  160. mov al, es:[4ah] ; col number.
  161. dec al
  162. mov b.snake[0], al ; return to right.
  163. jmp stop_move
  164. move_right:
  165. mov al, b.snake[0]
  166. inc al
  167. mov b.snake[0], al
  168. cmp al, es:[4ah] ; col number.
  169. jb stop_move
  170. mov b.snake[0], 0 ; return to left.
  171. jmp stop_move
  172. move_up:
  173. mov al, b.snake[1]
  174. dec al
  175. mov b.snake[1], al
  176. cmp al, -1
  177. jne stop_move
  178. mov al, es:[84h] ; row number -1.
  179. mov b.snake[1], al ; return to bottom.
  180. jmp stop_move
  181. move_down:
  182. mov al, b.snake[1]
  183. inc al
  184. mov b.snake[1], al
  185. cmp al, es:[84h] ; row number -1.
  186. jbe stop_move
  187. mov b.snake[1], 0 ; return to top.
  188. jmp stop_move
  189. stop_move:
  190. ret
  191. move_snake endp