; BOMBER - a tiny game - by Tylisha C. Andersen & Tenie Remmel
; the original idea for this was from a 256-byte-game contest
; our version has a score display, and is still only 248 bytes!
;
; commands: <esc> = exit; <space> = drop a bomb.
o equ <offset>
b equ <byte ptr>
w equ <word ptr>
.model tiny
.code
.186
org 100h
;-----------------------------------------------------------
main: xor ax, ax ; set video mode 0 (40x25)
int 10h
mov ah, 11h ; set chars C0 and C1 to airplane bitmap
mov bx, 0F00h
mov cx, 2
mov dx, 0C0h
mov bp, o font1
int 10h
dec cx ; set char 00 to bomb bitmap
xor dx, dx
mov bp, o font2
int 10h
mov ah, 1 ; turn off cursor
mov ch, 20h
int 10h
push 0B800h ; es = video-memory
pop es
mov b es:[78], 30h ; draw the initial score (0)
;-----------------------------------------------------------
m_bigloop: push 0 ; ds = segment 0
pop ds
mov dx, 1996 ; dx = end of screen (2000-4)
mov bx, 38 ; 38 bars to draw
m_randloop: mov cx, ds:[046Ch] ; generate random number
xor cx, bx
xor cx, di
mov ax, 7DB1h ; ah = random color, al = 50% gray
and ah, cl
inc ah
and cx, 0Fh ; cx = random length 1-16
inc cx
mov di, dx ; di = starting offset
m_barloop: stosw ; draw this char
sub di, 82 ; next char
loop m_barloop ; loop
dec dx ; next bar
dec dx
dec bx ; loop
jnz m_randloop
mov di, 82 ; initial di for main loop
mov bx, 2000 ; bx = offset of bomb flag
inc cx ; cx:dx = 01B800h for delay
mov dx, es
push es ; ds = video memory
pop ds
;-----------------------------------------------------------
m_mainloop: mov b [di-2], 20h ; clear char at [di-2]
cmp di, bx ; made it to the bottom, start again
je m_bigloop
mov ax, 09C0h ; draw bomber at current position
stosw ; and move forward by one char
inc ax
mov [di], ax
cmp b [di+2], 0B1h ; hit a building, game over
je m_gameover
cmp b [bx], cl ; check if a bomb is falling (cl = 1)
jne m_cont
;-----------------------------------------------------------
mov w [bx+si], 0720h ; erase the bomb
add si, 80 ; move down 1 line
sbb b [bx], ch ; clear bomb flag if off screen (ch = 0)
jz m_cont ; jump if flag was cleared
cmp b [bx+si], 0B1h ; test this position
mov w [bx+si], 0E00h ; draw the bomb again
jne m_cont ; skip if not block
push si ; save si
mov si, 78 ; offset of last char in score
m_incloop: or b [si], 30h ; turn space into zero
inc b [si] ; increment char
cmp b [si], '9' ; if no carry, then quit
jbe m_incdone
mov b [si], '0' ; otherwise, set to 0,
dec si ; and continue
dec si
jmp m_incloop
m_incdone: pop si ; restore si
;-----------------------------------------------------------
m_cont: mov ah, 086h ; delay 1/9 second
int 15h
mov ah, 1 ; check for a key
int 16h
jz m_mainloop
xor ax, ax ; get the key
int 16h
cmp al, 1Bh ; escape = done
je m_done
sub al, 20h ; space = drop bomb:
jnz m_mainloop
cmp b [bx], cl ; if a bomb is already falling,
je m_mainloop ; then do nothing, otherwise,
lea si, [di-1920] ; set the bomb position
mov b [bx], cl ; set the bomb flag (cl = 1)
jmp m_mainloop ; loop
m_gameover: xchg ax, cx ; wait for a key (ch = 0)
int 16h
m_done: mov ax, 3 ; restore text mode and return
int 10h
ret
;-----------------------------------------------------------
font1 db 000h,000h,000h,000h,000h,0C0h,040h,0F1h
db 07Fh,07Fh,03Dh,01Bh,007h,00Fh,000h
db 000h,000h,000h,000h,000h,03Ch,0EAh,0BFh
db 0FFh,0EEh,0DCh,080h
font2 db 000h,000h,000h,000h,000h,018h,03Ch,066h
db 0EBh,0E7h,0EBh,066h,03Ch,018h,000h
end main