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