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

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