wok-tiny view bootbricks/stuff/bricks.asm @ rev 184

boot-man: handle ESC key
author Pascal Bellard <pascal.bellard@slitaz.org>
date Wed Sep 27 17:13:33 2023 +0000 (12 months ago)
parents bbb34fe4904d
children 61c76233911e
line source
1 ;
2 ; Bricks game in one boot sector
3 ;
4 ; by Oscar Toledo G.
5 ;
6 ; Creation date: Nov/02/2019.
7 ;
9 cpu 8086
11 ;
12 ; Press Left Shift to start the game
13 ; Press Left Ctrl to move the paddle to the left
14 ; Press Left Alt to move the paddle to the right
15 ;
17 old_time: equ 16 ; Old time
18 ball_x: equ 14 ; X-coordinate of ball (8.8 fraction)
19 ball_y: equ 12 ; Y-coordinate of ball (8.8 fraction)
20 ball_xs: equ 10 ; X-speed of ball (8.8 fraction)
21 ball_ys: equ 8 ; Y-speed of ball (8.8 fraction)
22 beep: equ 6 ; Frame count to turn off sound
23 bricks: equ 4 ; Remaining bricks
24 score: equ 2 ; Current score
25 balls: equ 0 ; Remaining balls
27 ;
28 ; Start of the game
29 ;
30 start:
31 sti ; Allow interrupts
32 mov ax,0xb800 ; Address of video screen
33 mov ds,ax ; Setup DS
34 mov es,ax ; Setup ES
35 sub sp,32
36 cbw
37 push ax ; Reset score
38 mov al,4
39 push ax ; Balls remaining
40 mov bp,sp ; Setup stack frame for globals
41 mov al,0x02 ; Text mode 80x25x16 colors
42 int 0x10 ; Setup
43 ;
44 ; Start another level
45 ;
46 another_level:
47 mov word [bp+bricks],273 ; 273 bricks on screen
48 xor di,di
49 mov ax,0x01b1 ; Draw top border
50 mov cx,80
51 cld
52 rep stosw
53 mov cl,24 ; 24 rows
54 .1:
55 stosw ; Draw left border
56 mov ax,0x20 ; No bricks on this row
57 push cx
58 cmp cl,23
59 jnb .2
60 sub cl,15
61 jbe .2
62 mov al,0xdb ; Bricks on this row
63 mov ah,cl
64 .2:
65 mov cl,39 ; 39 bricks per row
66 .3:
67 stosw
68 stosw
69 inc ah ; Increase attribute color
70 cmp ah,0x08
71 jne .4
72 mov ah,0x01
73 .4:
74 loop .3
75 pop cx
77 mov ax,0x01b1 ; Draw right border
78 stosw
79 loop .1
81 ;
82 ; Start another ball
83 ;
84 mov di,0x0f4a ; Position of paddle
85 another_ball:
86 mov byte [bp+ball_x+1],0x28 ; Center X
87 mov byte [bp+ball_y+1],0x14 ; Center Y
88 xor ax,ax
89 mov [bp+ball_xs],ax ; Static on screen
90 mov [bp+ball_ys],ax
91 mov byte [bp+beep],0x01
93 mov si,0x0ffe ; Don't erase ball yet
94 game_loop:
95 call wait_frame ; Wait 1/18.2 secs.
97 and word [si],0x0000 ; Erase ball
99 call update_score ; Update score
101 mov ah,0x01 ; Check for keys
102 int 0x16
103 jz .0
104 cbw ; Eat key
105 int 0x16
106 cmp al,27 ; ESC key ?
107 je exit
108 .0:
109 mov ah,0x02 ; Read modifier keys
110 int 0x16
111 test al,0x04 ; Left ctrl
112 je .1
113 mov byte [di+6],0 ; Erase right side of paddle
114 mov byte [di+8],0
115 sub di,byte 4 ; Move paddle to left
116 cmp di,0x0f02 ; Limit
117 ja .1
118 mov di,0x0f02
119 .1:
120 test al,0x08 ; Left alt
121 je .2
122 xor ax,ax ; Erase left side of paddle
123 stosw
124 stosw ; DI increased automatically
125 cmp di,0x0f94 ; Limit
126 jb .2
127 mov di,0x0f94
128 .2:
129 test al,0x02 ; Left shift
130 je .15
131 mov ax,[bp+ball_xs] ; Ball moving?
132 add ax,[bp+ball_ys]
133 jne .15 ; Yes, jump
134 ; Setup movement of ball
135 mov word [bp+ball_xs],0xff40
136 mov word [bp+ball_ys],0xff80
137 .15:
138 mov ax,0x0adf ; Paddle graphic and color
139 push di
140 stosw ; Draw paddle
141 stosw
142 stosw
143 stosw
144 stosw
145 pop di
147 mov bx,[bp+ball_x] ; Draw ball
148 mov ax,[bp+ball_y]
149 call locate_ball ; Locate on screen
150 test byte [bp+ball_y],0x80 ; Y-coordinate half fraction?
151 mov ah,0x60 ; Interchange colors for smooth mov.
152 je .12
153 mov ah,0x06
154 .12: mov al,0xdc ; Graphic
155 mov [bx],ax ; Draw
156 push bx
157 pop si
159 .14:
160 mov bx,[bp+ball_x] ; Ball position
161 mov ax,[bp+ball_y]
162 add bx,[bp+ball_xs] ; Add movement speed
163 add ax,[bp+ball_ys]
164 push ax
165 push bx
166 call locate_ball ; Locate on screen
167 mov al,[bx]
168 cmp al,0xb1 ; Touching borders
169 jne .3
170 mov cx,5423 ; 1193180 / 220
171 call speaker ; Generate sound
172 pop bx
173 pop ax
174 cmp bh,0x4f
175 je .8
176 test bh,bh
177 jne .7
178 .8:
179 neg word [bp+ball_xs] ; Negate X-speed if it touches a side
180 .7:
181 test ah,ah
182 jnz .9
183 neg word [bp+ball_ys] ; Negate Y-speed if it touches a side
184 .9: jmp .14
186 .3:
187 cmp al,0xdf ; Touching paddle
188 jne .4
189 sub bx,di ; Subtract paddle position
190 sub bx,byte 4
191 mov cl,6 ; Multiply by 64
192 shl bx,cl
193 mov [bp+ball_xs],bx ; New X speed for ball
194 mov word [bp+ball_ys],0xff80 ; Update Y speed for ball
195 mov cx,2711 ; 1193180 / 440
196 call speaker ; Generate sound
197 pop bx
198 pop ax
199 jmp .14
201 .4:
202 cmp al,0xdb ; Touching brick
203 jne .5
204 mov cx,1355 ; 1193180 / 880
205 call speaker ; Generate sound
206 test bl,2 ; Aligned with brick?
207 jne .10 ; Yes, jump
208 dec bx ; Align
209 dec bx
210 .10: xor ax,ax ; Erase brick
211 mov [bx],ax
212 mov [bx+2],ax
213 inc word [bp+score] ; Increase score
214 neg word [bp+ball_ys] ; Negate Y speed (rebound)
215 pop bx
216 pop ax
217 dec word [bp+bricks] ; One brick less on screen
218 jne .14 ; Fully completed? No, jump.
219 jmp another_level ; Start another level
221 .5:
222 pop bx
223 pop ax
224 .6:
225 mov [bp+ball_x],bx ; Update ball position
226 mov [bp+ball_y],ax
227 cmp ah,0x19 ; Ball exited through bottom?
228 je ball_lost ; Yes, jump
229 jmp game_loop ; No, repeat game loop
231 ;
232 ; Ball lost
233 ;
234 ball_lost:
235 mov cx,10846 ; 1193180 / 110
236 call speaker ; Generate sound
238 and word [si],0 ; Erase ball
239 dec byte [bp+balls] ; One ball less
240 js .1 ; All finished? Yes, jump
241 jmp another_ball ; Start another ball
243 .1: call wait_frame.2 ; Turn off sound
244 stc
245 exit:
246 pushf
247 mov ax,0x0003 ; Text mode 80x25x16 colors
248 int 0x10 ; Setup
249 int 0x20 ; Exit to DOS / bootOS
250 popf
251 jc .1
252 int 0x19
253 .1:
254 jmp start
256 wait_frame:
257 .0:
258 hlt ; Wait for clock interrupt
259 mov ah,0x00 ; Read ticks
260 int 0x1a ; Call BIOS
261 cmp dx,[bp+old_time] ; Wait for change
262 je .0
263 mov [bp+old_time],dx
265 dec byte [bp+beep] ; Decrease time to turn off beep
266 jne .1
267 .2:
268 in al,0x61
269 and al,0xfc ; Turn off
270 out 0x61,al
271 .1:
273 ret
275 ;
276 ; Generate sound on PC speaker
277 ;
278 speaker:
279 mov al,0xb6 ; Setup timer 2
280 out 0x43,al
281 mov al,cl ; Low byte of timer count
282 out 0x42,al
283 mov al,ch ; High byte of timer count
284 out 0x42,al
285 in al,0x61
286 or al,0x03 ; Connect PC speaker to timer 2
287 out 0x61,al
288 mov byte [bp+beep],3 ; Duration
289 ret
291 ;
292 ; Locate ball on screen
293 ;
294 locate_ball:
295 mov al,0xa0
296 mul ah ; AH = Y coordinate (row)
297 mov bl,bh ; BH = X coordinate (column)
298 mov bh,0
299 shl bx,1
300 add bx,ax
301 ret
303 ;
304 ; Update score indicator (from bootRogue)
305 ;
306 update_score:
307 mov bx,0x0f98 ; Point to bottom right corner
308 mov ax,[bp+score]
309 call .1
310 mov al,[bp+balls]
311 .1:
312 xor cx,cx ; CX = Quotient
313 .2: inc cx
314 sub ax,10 ; Division by subtraction
315 jnc .2
316 add ax,0x0a3a ; Convert remainder to ASCII digit + color
317 call .3 ; Put on screen
318 xchg ax,cx
319 dec ax ; Quotient is zero?
320 jnz .1 ; No, jump to show more digits.
322 .3: mov [bx],ax
323 dec bx
324 dec bx
325 ret
327 times 510-($-$$) db 0x4f
328 db 0x55,0xaa ; Make it a bootable sector