wok-tiny diff bootfbird/stuff/fbird.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 | 1e55ea7da8de |
children |
line diff
1.1 --- a/bootfbird/stuff/fbird.asm Tue Sep 26 17:09:38 2023 +0000 1.2 +++ b/bootfbird/stuff/fbird.asm Sun Feb 04 18:02:38 2024 +0000 1.3 @@ -11,45 +11,55 @@ 1.4 ; previous score. 1.5 ; 1.6 1.7 +%define MDA_SUPPORT 1.8 + 1.9 use16 1.10 cpu 8086 1.11 1.12 -restart: 1.13 - mov ax,0x0002 ; Set 80x25 text mode 1.14 - int 0x10 ; Call BIOS 1.15 +%ifdef FAT_BOOT 1.16 + jmp bootbr 1.17 + nop 1.18 + times 0x3B db 0 1.19 +bootbr: 1.20 +%endif 1.21 + cld ; Reset direction flag (so stosw increments registers) 1.22 + sti ; Allow interrupts 1.23 + push cs 1.24 + pop ss 1.25 + mov sp,0xb800 ; Point to video segment 1.26 +SetSegments: 1.27 + mov ds,sp ; Both the source (common access) 1.28 + mov es,sp ; and target segments 1.29 ; 1.30 ; Game restart 1.31 ; 1.32 -fb21: cld ; Reset direction flag (so stosw increments registers) 1.33 - sti ; Allow interrupts 1.34 - mov ax,0xb800 ; Point to video segment 1.35 - mov ds,ax ; Both the source (common access) 1.36 - mov es,ax ; and target segments 1.37 - mov di,pipe ; Init variables in video segment (saves big bytes) 1.38 - cbw 1.39 - stosw ; pipe 1.40 - stosw ; score 1.41 - stosw ; grav 1.42 - mov al,0xa0 1.43 - stosw ; next 1.44 - mov al,0x60 1.45 - stosw ; bird 1.46 +fb21: 1.47 + mov ax,0x0002 ; Set 80x25 text mode 1.48 + int 0x10 ; Call BIOS 1.49 + mov di,next ; Init variables in video segment (saves big bytes) 1.50 +%ifdef MDA_SUPPORT 1.51 + mov sp,0xb000 1.52 + inc byte [di] 1.53 + je SetSegments 1.54 +%endif 1.55 + mov ax,0x60a0 1.56 + stosw ; next, bird 1.57 + xor ax,ax 1.58 + stosw ; grav, pipe 1.59 + stosb 1.60 + 1.61 + ; Disable text mode cursor 1.62 + ; https://wiki.osdev.org/Text_Mode_Cursor#Disabling_the_Cursor 1.63 + mov ah, 0x01 1.64 + mov ch, 0x3f 1.65 + int 0x10 1.66 1.67 mov di,0x004a ; Game title 1.68 - mov ax,0x0f46 ; 'F' in white, good old ASCII 1.69 - stosw 1.70 - mov al,0x2d ; '-' 1.71 - stosw 1.72 - mov al,0x42 ; 'B' 1.73 - stosw 1.74 - mov al,0x49 ; 'I' 1.75 - stosw 1.76 - mov al,0x52 ; 'R' 1.77 - stosw 1.78 - mov al,0x44 ; 'D' 1.79 - stosw 1.80 + call print_string 1.81 + db 'F-BIRD' 1.82 mov bp,80 ; Introduce 80 columns of scenery 1.83 fb1: call scroll_scenery 1.84 +%define SI(n) [si+n-0x0fa2] 1.85 dec bp 1.86 jnz fb1 1.87 1.88 @@ -64,101 +74,43 @@ 1.89 ; 1.90 ; Main loop 1.91 ; 1.92 -fb12: mov si,bird 1.93 - lodsw ; Bird falls... 1.94 - add al,[grav] ; ...because of gravity... 1.95 +fb12: mov ax,[bird] ; Bird falls... 1.96 + add al,ah ; ...because of gravity... 1.97 mov [bird],al ; ...into new position. 1.98 and al,0xf8 ; Row is a 5.3 fraction, nullify fraction 1.99 mov ah,0x14 ; Given integer is x8, multiply by 20 to get 160 per line 1.100 mul ah ; Row into screen 1.101 add ax,$0020 ; Fixed column 1.102 xchg ax,di ; Pass to DI (AX cannot be used as pointer) 1.103 - lodsb ; mov al,[frame] 1.104 + mov dx,$0d1f ; Draw body 1.105 + mov ax,bp ; [frame] 1.106 + mov bx,-160 1.107 and al,4 ; Wing movement each 4 frames 1.108 jz fb15 1.109 - mov al,[di-160] ; Get character below 1.110 - mov word [di-160],$0d1e ; Draw upper wing 1.111 - add al,[di] ; Add another character below 1.112 - shr al,1 ; Normalize 1.113 - mov word [di],$0d14 ; Draw body 1.114 + mov ax,$0d1e ; Draw upper wing 1.115 + xchg ax,[bx+di] ; Get character below 1.116 jmp short fb16 1.117 - 1.118 -fb15: mov al,[di] ; Get character below 1.119 - mov word [di],$0d1f ; Draw body 1.120 -fb16: add al,[di+2] ; Get character below head 1.121 - mov word [di+2],$0d10 ; Draw head 1.122 - cmp al,0x40 ; Collision with scenery? 1.123 - jz fb19 1.124 ; 1.125 ; Stars and game over 1.126 ; 1.127 - mov byte [di],$2a ; '*' Asterisks to indicate crashing 1.128 - mov byte [di+2],$2a 1.129 +fb19: mov al,$2a ; '*' Asterisks to indicate crashing 1.130 + stosb 1.131 + inc di 1.132 + stosb 1.133 mov di,0x07CA 1.134 - mov ax,0x0f42 ; 'B' in white, good old ASCII 1.135 - stosw 1.136 - mov al,0x4F ; 'O' 1.137 - stosw 1.138 - mov al,0x4E ; 'N' 1.139 - stosw 1.140 - mov al,0x4B ; 'K' 1.141 - stosw 1.142 - mov al,0x21 ; '!' 1.143 - stosw 1.144 - mov bp,100 ; Wait 100 frames 1.145 + call print_string 1.146 + db 'BONK!' 1.147 + mov bp,-100 ; Wait 100 frames 1.148 fb20: call wait_frame 1.149 - dec bp 1.150 jnz fb20 1.151 jmp fb21 ; Restart 1.152 1.153 -fb19: call wait_frame ; Wait for frame 1.154 - mov al,[frame] 1.155 - and al,7 ; 8 frames have passed? 1.156 - jnz fb17 ; No, jump 1.157 - inc word [grav] ; Increase gravity 1.158 -fb17: 1.159 - mov al,$20 1.160 - mov [di-160],al ; Delete bird from screen 1.161 - mov [di+2],al 1.162 - stosb 1.163 - call scroll_scenery ; Scroll scenery 1.164 - call scroll_scenery ; Scroll scenery 1.165 - cmp byte [0x00a0],0xb0 ; Passed a column? 1.166 - jz fb27 1.167 - cmp byte [0x00a2],0xb0 ; Passed a column? 1.168 -fb27: jnz fb24 1.169 - inc word [score] ; Increase score 1.170 - mov ax,[score] 1.171 - mov di,0x008e ; Show current score 1.172 -fb25: xor dx,dx ; Extend AX to 32 bits 1.173 - mov bx,10 ; Divisor is 10 1.174 - div bx ; Divide 1.175 - add dx,0x0c30 ; Convert remaining 0-9 to ASCII, also put color 1.176 - xchg ax,dx 1.177 - std 1.178 - stosw 1.179 - mov byte [di],0x20 ; Clean at least one character of prev. score 1.180 - cld 1.181 - xchg ax,dx 1.182 - or ax,ax ; Score digits still remain? 1.183 - jnz fb25 ; Yes, jump 1.184 -fb24: mov ah,0x01 ; Any key pressed? 1.185 - int 0x16 1.186 - jz fb26 ; No, go to main loop 1.187 - mov ah,0x00 1.188 - int 0x16 ; Get key 1.189 - dec ah ; Escape key? 1.190 - jne fb4 ; No, jump 1.191 - mov al,3 1.192 - int 0x10 1.193 - int 0x20 ; Exit to DOS or to oblivion (boot sector) 1.194 - int 0x19 1.195 -fb4: mov ax,[bird] 1.196 - sub ax,0x10 ; Move bird two rows upward 1.197 - cmp ax,0x08 ; Make sure the bird doesn't fly free outside screen 1.198 +fb4: mov al,[bird] 1.199 + cmp al,0x18 ; Make sure the bird doesn't fly free outside screen 1.200 jb fb18 1.201 + sub al,0x10 ; Move bird two rows upward 1.202 +fb18: cbw ; Reset gravity 1.203 mov [bird],ax 1.204 -fb18: mov byte [grav],0 ; Reset gravity 1.205 mov al,0xb6 ; Flap sound 1.206 out (0x43),al 1.207 mov al,0x90 1.208 @@ -170,6 +122,56 @@ 1.209 out (0x61),al 1.210 fb26: jmp fb12 1.211 1.212 +fb16: mov dl,$14 ; Draw body 1.213 +fb15: or al,[di] ; Add another character below 1.214 + mov [di],dx ; Draw body 1.215 + mov dl,$10 ; Draw head 1.216 + xchg dx,[di+2] ; Get character below head 1.217 + add al,dl 1.218 + cmp al,0x40 ; Collision with scenery? 1.219 + jnz fb19 1.220 + call wait_frame ; Wait for frame 1.221 + mov ax,bp ; [frame] 1.222 + and al,7 ; 8 frames have passed? 1.223 + jnz fb17 ; No, jump 1.224 + inc byte SI(grav) ; Increase gravity 1.225 +fb17: 1.226 + mov al,$20 1.227 + mov [bx+di],al ; Delete bird from screen 1.228 + stosb 1.229 + inc di 1.230 + stosb 1.231 + call scroll_scenery ; Scroll scenery 1.232 + call scroll_scenery ; Scroll scenery 1.233 + mov di,bx 1.234 + mov al,0xb0 1.235 + scasb ; Passed a column? 1.236 + jz fb27 1.237 + inc di 1.238 + scasb ; Passed a column? 1.239 + jnz fb24 1.240 +fb27: mov di,0x008e ; Show current score 1.241 +fb25: dec di 1.242 + dec di 1.243 + mov ax,0x0c30 ; Convert remaining 0-9 to ASCII, also put color 1.244 + xchg [di], ax 1.245 + or al, 0x30 1.246 + cmp al, '9' 1.247 + je fb25 1.248 + inc ax 1.249 + stosb 1.250 +fb24: mov ah,0x01 ; Any key pressed? 1.251 + int 0x16 1.252 + jz fb26 ; No, go to main loop 1.253 + mov ah,0x00 1.254 + int 0x16 ; Get key 1.255 + dec ah ; Escape key? 1.256 + jne fb4 ; No, jump 1.257 +quit: mov al,3 1.258 + int 0x10 1.259 + int 0x20 ; Exit to DOS or to oblivion (boot sector) 1.260 + int 0x19 1.261 + 1.262 ; 1.263 ; Scroll scenery one column at a time 1.264 ; 1.265 @@ -179,6 +181,7 @@ 1.266 ; 1.267 mov si,0x00a2 ; Point to row 1, column 1 in SI 1.268 mov di,0x00a0 ; Point to row 1, column 0 in DI 1.269 + mov bx,di 1.270 fb2: mov cx,79 ; 79 columns 1.271 repz ; Scroll!!! 1.272 movsw 1.273 @@ -190,42 +193,49 @@ 1.274 ; 1.275 ; Insert houses 1.276 ; 1.277 - mov word [0x0f9e],0x02df ; Terrain 1.278 + mov word SI(0x0f9e),0x02df ; Terrain 1.279 in al,(0x40) ; Get "random" number 1.280 - and al,0x70 1.281 + test al,0x70 1.282 jz fb5 1.283 - mov bx,0x0408 ; House of one floor 1.284 - mov [0x0efe],bx 1.285 + mov dx,0x0408 ; House of one floor 1.286 mov di,0x0e5e 1.287 - and al,0x20 ; Check "random" number 1.288 + mov [bx+di],dx 1.289 + test al,0x20 ; Check "random" number 1.290 jz fb3 1.291 - mov [di],bx ; House of two floors 1.292 - sub di,0x00a0 1.293 + mov [di],dx ; House of two floors 1.294 + sub di,bx 1.295 fb3: mov word [di],0x091e ; Add roof 1.296 ; 1.297 ; Check if it's time to insert a column 1.298 ; 1.299 -fb5: dec word [next] ; Decrease time (column really) for next pipe 1.300 - mov bx,[next] 1.301 - cmp bx,0x03 ; bx = 3,2,1,0 for the four columns making the pipe 1.302 - ja fb6 1.303 - jne fb8 1.304 - in al,(0x40) ; Get "random" number 1.305 - and ax,0x0007 ; Between 0 and 7 1.306 +fb5: dec byte SI(next) ; Decrease time (column really) for next pipe 1.307 + mov dh,SI(next) 1.308 + mov dl,0xb1 ; Leftmost 1.309 + mov cl,3 1.310 + cmp dh,cl ; bl = 3,2,1,0 for the four columns making the pipe 1.311 + ja fb6 ; No yet, jump 1.312 + jne fb8 ; No leftmost, jump 1.313 + and al,0x07 ; Between 0 and 7 1.314 add al,0x04 ; Between 4 and 11 1.315 - mov [tall],ax ; This will tell how tall the pipe is 1.316 -fb8: mov cx,[tall] 1.317 - or bx,bx ; Rightmost? 1.318 + mov SI(tall),al ; This will tell how tall the pipe is 1.319 + jmp fb7 ; Leftmost, jump 1.320 + 1.321 +fb8: mov dl,0xdb 1.322 + or dh,dh ; Rightmost? 1.323 + jnz fb7 ; No, jump 1.324 mov dl,0xb0 1.325 - jz fb7 ; Yes, jump 1.326 - mov dl,0xdb 1.327 - cmp bx,0x03 ; Leftmost? 1.328 - jb fb7 ; No, jump 1.329 - mov dl,0xb1 1.330 + dec word SI(pipe) ; Increase total pipes shown 1.331 + or byte SI(pipe+1),0xfe 1.332 + mov ax,SI(pipe) 1.333 + sar ax,cl 1.334 + add al,0x50 ; Decrease distance between pipes 1.335 + mov SI(next),al ; Time for next pipe 1.336 fb7: mov di,0x013e ; Start from top of screen 1.337 + xchg ax,dx 1.338 mov ah,0x0a 1.339 - mov al,dl 1.340 + push ax 1.341 mov dx,0x009e 1.342 + mov cl,SI(tall) 1.343 fb9: stosw 1.344 add di,dx 1.345 loop fb9 1.346 @@ -234,56 +244,53 @@ 1.347 add di,0x009e*6+10 1.348 mov al,0xdf 1.349 stosw 1.350 - add di,dx 1.351 -fb10: mov al,dl 1.352 + pop ax 1.353 +fb10: add di,dx 1.354 stosw 1.355 - add di,dx 1.356 - cmp di,0x0f00 1.357 + cmp di,0x0ea0 1.358 jb fb10 1.359 - or bx,bx 1.360 - jnz fb6 1.361 - mov ax,[pipe] 1.362 - inc ax ; Increase total pipes shown 1.363 - mov [pipe],ax 1.364 - mov cl,3 1.365 - shr ax,cl 1.366 - mov ah,0x50 ; Decrease distance between pipes 1.367 - sub ah,al 1.368 - cmp ah,0x10 1.369 - ja fb11 1.370 - mov ah,0x10 1.371 -fb11: mov [next],ah ; Time for next pipe 1.372 fb6: ret 1.373 1.374 ; 1.375 ; Wait for a frame 1.376 ; 1.377 wait_frame: 1.378 - 1.379 - mov bx, tick 1.380 fb14: hlt ; Wait for clock interrupt 1.381 mov ah,0x00 ; Use base clock tick 1.382 int 0x1a 1.383 - cmp dx,[bx] 1.384 + cmp dx,[tick] 1.385 jz fb14 1.386 - mov [bx],dx 1.387 - inc word [bx+frame-tick] ; Increase frame count 1.388 + mov [tick],dx 1.389 in al,(0x61) 1.390 - and al,0xfc ; Turn off sound 1.391 + and al,0xfc ; Turn off sound 1.392 out (0x61),al 1.393 + inc bp ; Increase frame count 1.394 ret 1.395 1.396 - times 507 - ($-$$) db 0 ; pad remaining 507 bytes with zeroes 1.397 + ; 1.398 + ; Print a string 1.399 + ; 1.400 +print_string: 1.401 + pop si 1.402 + mov ah, 0xf ; white 1.403 + db 0x3C ; cmp al,0xab 1.404 +pr1: stosw 1.405 + cs lodsb 1.406 + cmp al,0xbd 1.407 + jne pr1 1.408 + dec si 1.409 + push si 1.410 + ret 1.411 1.412 - db "OTG" ; 3 unused bytes 1.413 + times 510 - ($-$$) db 0 ; pad remaining 510 bytes with zeroes 1.414 1.415 db 0x55,0xaa ; Bootable signature 1.416 1.417 -pipe: equ 0x0fa0 1.418 -score: equ 0x0fa2 1.419 -grav: equ 0x0fa4 1.420 -next: equ 0x0fa6 1.421 -bird: equ 0x0fa8 1.422 -frame: equ 0x0faa 1.423 -tall: equ 0x0fac 1.424 -tick: equ 0x0fae 1.425 +tick: equ 0x0fa0 ; word 1.426 + 1.427 +next: equ tick+2 ; byte 1.428 +bird: equ tick+3 ; byte 1.429 +grav: equ bird+1 ; byte 1.430 +pipe: equ tick+5 ; word 1.431 + 1.432 +tall: equ tick+7 ; byte