home *** CD-ROM | disk | FTP | other *** search
/ Chip 2005 March / CMCD0305.ISO / Software / Shareware / Utilitare / emu / Emu8086_Setup_307c.exe / {app} / Samples / snake.asm < prev    next >
Encoding:
Assembly Source File  |  2002-08-08  |  5.5 KB  |  309 lines

  1. ; This is the snake game...
  2. ;
  3. ; It's better to set the
  4. ; "step delay" to "0" before
  5. ; running, it requires fast
  6. ; processing.
  7. ;
  8. ; You can control the snake
  9. ; using arrow keys on your
  10. ; keyboard.
  11. ;
  12. ; All other keys will stop
  13. ; the snake.
  14. ;
  15. ; Press ESC to exit.
  16.  
  17.  
  18. #make_COM#
  19.  
  20. ORG     100h
  21.  
  22. ; jump over data section:
  23. JMP     start
  24.  
  25. ; ------ DATA section ------
  26.  
  27. s_size  EQU     7
  28.  
  29. ; the snake coordinates
  30. ; (from head to tail)
  31. ; low byte is left, high byte
  32. ; is top - [top, left]
  33. snake DW s_size DUP(0)
  34.  
  35. tail    DW      ?
  36.  
  37. ; direction constants
  38. ;          (BIOS key codes):
  39. LEFT    EQU     4Bh
  40. RIGHT   EQU     4Dh
  41. UP      EQU     48h
  42. DOWN    EQU     50h
  43.  
  44. ; current snake direction:
  45. cur_dir DB      RIGHT
  46.  
  47. wait_time DW    0
  48.  
  49. ; ------ CODE section ------
  50.  
  51. start:
  52.  
  53. CALL SayThis
  54. DB "==== HOW TO PLAY ====", 13, 10
  55. DB "It's better to set the", 13, 10
  56. DB '"step delay" to "0" before', 13, 10
  57. DB "running, it requires fast", 13, 10
  58. DB "processing.", 13, 10, 13, 10
  59.  
  60. DB "You can control the snake", 13, 10
  61. DB "using arrow keys on your", 13, 10
  62. DB "keyboard.", 13, 10, 13, 10
  63.  
  64. DB "All other keys will stop", 13, 10
  65. DB "the snake.", 13, 10, 13, 10
  66.  
  67. DB "Press ESC to exit.", 13, 10
  68. DB "====================", 13, 10, 13, 10
  69. DB "Press any key to start...", 0
  70.  
  71.  
  72. ; wait for any key:
  73. MOV AH, 00h
  74. INT 16h
  75.  
  76.  
  77. ; hide text cursor:
  78. ; (emulator shows
  79. ; text cursor only when
  80. ; it wait for input, so
  81. ; this is optional)
  82. MOV     AH, 1
  83. MOV     CH, 2Bh
  84. MOV     CL, 0Bh
  85. INT     10h
  86.  
  87.  
  88. game_loop:
  89.  
  90. ; === select first video page
  91. MOV     AL, 0  ; page number.
  92. MOV     AH, 05h
  93. INT     10h
  94.  
  95. ; === show new head:
  96. MOV     DX, snake[0]
  97.  
  98. ; set cursor at DL,DH
  99. MOV     AH, 02h
  100. INT     10h
  101.  
  102. ; print '*' at the location:
  103. MOV     AL, '*'
  104. MOV     AH, 09h
  105. MOV     BL, 0Eh ; attribute.
  106. MOV     CX, 1   ; single char.
  107. INT     10h
  108.  
  109. ; === keep the tail:
  110. MOV     AX, snake[s_size * 2 - 2]
  111. MOV     tail, AX
  112.  
  113. CALL    move_snake
  114.  
  115.  
  116. ; === hide old tail:
  117. MOV     DX, tail
  118.  
  119. ; set cursor at DL,DH
  120. MOV     AH, 02h
  121. INT     10h
  122.  
  123. ; print ' ' at the location:
  124. MOV     AL, ' '
  125. MOV     AH, 09h
  126. MOV     BL, 0Eh ; attribute.
  127. MOV     CX, 1   ; single char.
  128. INT     10h
  129.  
  130.  
  131.  
  132. check_for_key:
  133.  
  134. ; === check for player commands:
  135. MOV     AH, 01h
  136. INT     16h
  137. JZ      no_key
  138.  
  139. MOV     AH, 00h
  140. INT     16h
  141.  
  142. CMP     AL, 1Bh    ; ESC - key?
  143. JE      stop_game  ;
  144.  
  145. MOV     cur_dir, AH
  146.  
  147. no_key:
  148.  
  149.  
  150.  
  151. ; === wait a few moments here:
  152. ; get number of clock ticks
  153. ; (about 18 per second)
  154. ; since midnight into CX:DX
  155. MOV     AH, 00h
  156. INT     1Ah
  157. CMP     DX, wait_time
  158. JB      check_for_key
  159. ADD     DX, 4
  160. MOV     wait_time, DX
  161.  
  162.  
  163.  
  164. ; === eternal game loop:
  165. JMP     game_loop
  166.  
  167.  
  168. stop_game:
  169.  
  170. ; show cursor back:
  171. MOV     AH, 1
  172. MOV     CH, 0Bh
  173. MOV     CL, 0Bh
  174. INT     10h
  175.  
  176. RET
  177.  
  178. ; ------ functions section ------
  179.  
  180. ; This procedure creates the
  181. ; animation by moving all snake
  182. ; body parts one step to tail,
  183. ; the old tail goes away:
  184. ; [Last part (tail)]-> goes away
  185. ; [Part i] -> [Part i+1]
  186. ; ....
  187.  
  188. move_snake PROC NEAR
  189.  
  190. ; set ES to BIOS info segment:  
  191. MOV     AX, 40h
  192. MOV     ES, AX
  193.  
  194.   ; point DI to tail
  195.   MOV   DI, s_size * 2 - 2
  196.   ; move all body parts
  197.   ; (last one simply goes away)
  198.   MOV   CX, s_size-1
  199. move_array:
  200.   MOV   AX, snake[DI-2]
  201.   MOV   snake[DI], AX
  202.   SUB   DI, 2
  203.   LOOP  move_array
  204.  
  205.  
  206. CMP     cur_dir, LEFT
  207.   JE    move_left
  208. CMP     cur_dir, RIGHT
  209.   JE    move_right
  210. CMP     cur_dir, UP
  211.   JE    move_up
  212. CMP     cur_dir, DOWN
  213.   JE    move_down
  214.  
  215. JMP     stop_move       ; no direction.
  216.  
  217.  
  218. move_left:
  219.   MOV   AL, b.snake[0]
  220.   DEC   AL
  221.   MOV   b.snake[0], AL
  222.   CMP   AL, -1
  223.   JNE   stop_move       
  224.   MOV   AL, ES:[4Ah]    ; col number.
  225.   DEC   AL
  226.   MOV   b.snake[0], AL  ; return to right.
  227.   JMP   stop_move
  228.  
  229. move_right:
  230.   MOV   AL, b.snake[0]
  231.   INC   AL
  232.   MOV   b.snake[0], AL
  233.   CMP   AL, ES:[4Ah]    ; col number.   
  234.   JB    stop_move
  235.   MOV   b.snake[0], 0   ; return to left.
  236.   JMP   stop_move
  237.  
  238. move_up:
  239.   MOV   AL, b.snake[1]
  240.   DEC   AL
  241.   MOV   b.snake[1], AL
  242.   CMP   AL, -1
  243.   JNE   stop_move
  244.   MOV   AL, ES:[84h]    ; row number -1.
  245.   MOV   b.snake[1], AL  ; return to bottom.
  246.   JMP   stop_move
  247.  
  248. move_down:
  249.   MOV   AL, b.snake[1]
  250.   INC   AL
  251.   MOV   b.snake[1], AL
  252.   CMP   AL, ES:[84h]    ; row number -1.
  253.   JBE   stop_move
  254.   MOV   b.snake[1], 0   ; return to top.
  255.   JMP   stop_move
  256.  
  257. stop_move:
  258.   RET
  259. move_snake ENDP
  260.  
  261.  
  262.  
  263. ; Procedure to print a null terminated
  264. ; string at current cursor position.
  265. ; The ZERO TERMINATED string should be
  266. ; defined just after the CALL.
  267. ; For example:
  268. ;
  269. ; CALL SayThis
  270. ; db 'Hello World!', 0
  271. ;
  272. ; Address of string is stored in the Stack
  273. ; as return address.
  274. ; Procedure updates value in the Stack to
  275. ; make return after string definition.
  276. SayThis PROC NEAR
  277.  
  278. MOV     CS:temp1, SI  ; re-store SI register.
  279.  
  280. POP     SI            ; get return address (IP).
  281.  
  282. PUSH    AX            ; store AX register.
  283.  
  284. next_char:      
  285.         MOV     AL, CS:[SI]
  286.         INC     SI            ; next byte.
  287.         CMP     AL, 0
  288.         JZ      printed        
  289.         MOV     AH, 0Eh       ; teletype function.
  290.         INT     10h
  291.         JMP     next_char     ; loop.
  292. printed:
  293.  
  294. POP     AX            ; re-store AX register.
  295.  
  296. ; SI should point to next command after
  297. ; the CALL instruction and string definition:
  298. PUSH    SI            ; save new return address into the Stack.
  299.  
  300. MOV     SI, CS:temp1  ; re-store SI register.
  301.  
  302. RET
  303. temp1  DW  ?    ; variable to store original value of SI register.
  304. SayThis ENDP
  305.  
  306.  
  307.  
  308. END
  309.