wok-tiny annotate bootbricks/stuff/bricks.asm @ rev 182

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