wok-tiny view 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 source
1 ;
2 ; F-bird text game in a bootsector
3 ;
4 ; by Oscar Toledo G.
5 ; http://nanochess.org/
6 ;
7 ; Creation date: Jun/04/2017. A messy unoptimized thing.
8 ; Revision date: Jun/05/2017. Better usage of graphic charset.
9 ; Removed a non-8088 long jump. Added
10 ; sound. Solved bug when overwriting
11 ; previous score.
12 ;
14 %define MDA_SUPPORT
16 use16
17 cpu 8086
19 %ifdef FAT_BOOT
20 jmp bootbr
21 nop
22 times 0x3B db 0
23 bootbr:
24 %endif
25 cld ; Reset direction flag (so stosw increments registers)
26 sti ; Allow interrupts
27 push cs
28 pop ss
29 mov sp,0xb800 ; Point to video segment
30 SetSegments:
31 mov ds,sp ; Both the source (common access)
32 mov es,sp ; and target segments
33 ;
34 ; Game restart
35 ;
36 fb21:
37 mov ax,0x0002 ; Set 80x25 text mode
38 int 0x10 ; Call BIOS
39 mov di,next ; Init variables in video segment (saves big bytes)
40 %ifdef MDA_SUPPORT
41 mov sp,0xb000
42 inc byte [di]
43 je SetSegments
44 %endif
45 mov ax,0x60a0
46 stosw ; next, bird
47 xor ax,ax
48 stosw ; grav, pipe
49 stosb
51 ; Disable text mode cursor
52 ; https://wiki.osdev.org/Text_Mode_Cursor#Disabling_the_Cursor
53 mov ah, 0x01
54 mov ch, 0x3f
55 int 0x10
57 mov di,0x004a ; Game title
58 call print_string
59 db 'F-BIRD'
60 mov bp,80 ; Introduce 80 columns of scenery
61 fb1: call scroll_scenery
62 %define SI(n) [si+n-0x0fa2]
63 dec bp
64 jnz fb1
66 fb23: mov ah,0x01 ; Check if key pressed
67 int 0x16
68 pushf
69 xor ax,ax ; Wait for a key
70 int 0x16
71 popf
72 jnz fb23 ; Jump if key was accumulated, if not already waited for key ;)
74 ;
75 ; Main loop
76 ;
77 fb12: mov ax,[bird] ; Bird falls...
78 add al,ah ; ...because of gravity...
79 mov [bird],al ; ...into new position.
80 and al,0xf8 ; Row is a 5.3 fraction, nullify fraction
81 mov ah,0x14 ; Given integer is x8, multiply by 20 to get 160 per line
82 mul ah ; Row into screen
83 add ax,$0020 ; Fixed column
84 xchg ax,di ; Pass to DI (AX cannot be used as pointer)
85 mov dx,$0d1f ; Draw body
86 mov ax,bp ; [frame]
87 mov bx,-160
88 and al,4 ; Wing movement each 4 frames
89 jz fb15
90 mov ax,$0d1e ; Draw upper wing
91 xchg ax,[bx+di] ; Get character below
92 jmp short fb16
93 ;
94 ; Stars and game over
95 ;
96 fb19: mov al,$2a ; '*' Asterisks to indicate crashing
97 stosb
98 inc di
99 stosb
100 mov di,0x07CA
101 call print_string
102 db 'BONK!'
103 mov bp,-100 ; Wait 100 frames
104 fb20: call wait_frame
105 jnz fb20
106 jmp fb21 ; Restart
108 fb4: mov al,[bird]
109 cmp al,0x18 ; Make sure the bird doesn't fly free outside screen
110 jb fb18
111 sub al,0x10 ; Move bird two rows upward
112 fb18: cbw ; Reset gravity
113 mov [bird],ax
114 mov al,0xb6 ; Flap sound
115 out (0x43),al
116 mov al,0x90
117 out (0x42),al
118 mov al,0x4a
119 out (0x42),al
120 in al,(0x61)
121 or al,0x03 ; Turn on sound
122 out (0x61),al
123 fb26: jmp fb12
125 fb16: mov dl,$14 ; Draw body
126 fb15: or al,[di] ; Add another character below
127 mov [di],dx ; Draw body
128 mov dl,$10 ; Draw head
129 xchg dx,[di+2] ; Get character below head
130 add al,dl
131 cmp al,0x40 ; Collision with scenery?
132 jnz fb19
133 call wait_frame ; Wait for frame
134 mov ax,bp ; [frame]
135 and al,7 ; 8 frames have passed?
136 jnz fb17 ; No, jump
137 inc byte SI(grav) ; Increase gravity
138 fb17:
139 mov al,$20
140 mov [bx+di],al ; Delete bird from screen
141 stosb
142 inc di
143 stosb
144 call scroll_scenery ; Scroll scenery
145 call scroll_scenery ; Scroll scenery
146 mov di,bx
147 mov al,0xb0
148 scasb ; Passed a column?
149 jz fb27
150 inc di
151 scasb ; Passed a column?
152 jnz fb24
153 fb27: mov di,0x008e ; Show current score
154 fb25: dec di
155 dec di
156 mov ax,0x0c30 ; Convert remaining 0-9 to ASCII, also put color
157 xchg [di], ax
158 or al, 0x30
159 cmp al, '9'
160 je fb25
161 inc ax
162 stosb
163 fb24: mov ah,0x01 ; Any key pressed?
164 int 0x16
165 jz fb26 ; No, go to main loop
166 mov ah,0x00
167 int 0x16 ; Get key
168 dec ah ; Escape key?
169 jne fb4 ; No, jump
170 quit: mov al,3
171 int 0x10
172 int 0x20 ; Exit to DOS or to oblivion (boot sector)
173 int 0x19
175 ;
176 ; Scroll scenery one column at a time
177 ;
178 scroll_scenery:
179 ;
180 ; Move whole screen
181 ;
182 mov si,0x00a2 ; Point to row 1, column 1 in SI
183 mov di,0x00a0 ; Point to row 1, column 0 in DI
184 mov bx,di
185 fb2: mov cx,79 ; 79 columns
186 repz ; Scroll!!!
187 movsw
188 mov ax,0x0e20 ; Clean last character
189 stosw
190 lodsw ; Advance source to keep pair source/target
191 cmp si,0x0fa2 ; All scrolled?
192 jnz fb2 ; No, jump
193 ;
194 ; Insert houses
195 ;
196 mov word SI(0x0f9e),0x02df ; Terrain
197 in al,(0x40) ; Get "random" number
198 test al,0x70
199 jz fb5
200 mov dx,0x0408 ; House of one floor
201 mov di,0x0e5e
202 mov [bx+di],dx
203 test al,0x20 ; Check "random" number
204 jz fb3
205 mov [di],dx ; House of two floors
206 sub di,bx
207 fb3: mov word [di],0x091e ; Add roof
208 ;
209 ; Check if it's time to insert a column
210 ;
211 fb5: dec byte SI(next) ; Decrease time (column really) for next pipe
212 mov dh,SI(next)
213 mov dl,0xb1 ; Leftmost
214 mov cl,3
215 cmp dh,cl ; bl = 3,2,1,0 for the four columns making the pipe
216 ja fb6 ; No yet, jump
217 jne fb8 ; No leftmost, jump
218 and al,0x07 ; Between 0 and 7
219 add al,0x04 ; Between 4 and 11
220 mov SI(tall),al ; This will tell how tall the pipe is
221 jmp fb7 ; Leftmost, jump
223 fb8: mov dl,0xdb
224 or dh,dh ; Rightmost?
225 jnz fb7 ; No, jump
226 mov dl,0xb0
227 dec word SI(pipe) ; Increase total pipes shown
228 or byte SI(pipe+1),0xfe
229 mov ax,SI(pipe)
230 sar ax,cl
231 add al,0x50 ; Decrease distance between pipes
232 mov SI(next),al ; Time for next pipe
233 fb7: mov di,0x013e ; Start from top of screen
234 xchg ax,dx
235 mov ah,0x0a
236 push ax
237 mov dx,0x009e
238 mov cl,SI(tall)
239 fb9: stosw
240 add di,dx
241 loop fb9
242 mov al,0xc4
243 stosw
244 add di,0x009e*6+10
245 mov al,0xdf
246 stosw
247 pop ax
248 fb10: add di,dx
249 stosw
250 cmp di,0x0ea0
251 jb fb10
252 fb6: ret
254 ;
255 ; Wait for a frame
256 ;
257 wait_frame:
258 fb14: hlt ; Wait for clock interrupt
259 mov ah,0x00 ; Use base clock tick
260 int 0x1a
261 cmp dx,[tick]
262 jz fb14
263 mov [tick],dx
264 in al,(0x61)
265 and al,0xfc ; Turn off sound
266 out (0x61),al
267 inc bp ; Increase frame count
268 ret
270 ;
271 ; Print a string
272 ;
273 print_string:
274 pop si
275 mov ah, 0xf ; white
276 db 0x3C ; cmp al,0xab
277 pr1: stosw
278 cs lodsb
279 cmp al,0xbd
280 jne pr1
281 dec si
282 push si
283 ret
285 times 510 - ($-$$) db 0 ; pad remaining 510 bytes with zeroes
287 db 0x55,0xaa ; Bootable signature
289 tick: equ 0x0fa0 ; word
291 next: equ tick+2 ; byte
292 bird: equ tick+3 ; byte
293 grav: equ bird+1 ; byte
294 pipe: equ tick+5 ; word
296 tall: equ tick+7 ; byte