space invaders
[bootcard] / bootcard.asm
1 ; ---- boot me! ----
2 ; nasm -f bin -o bootcard.img bootcard.asm
3 ; cat bootcard.img >/dev/<usbstick>
4 ; reboot
5
6         org 7c00h
7         bits 16
8
9 data_start      equ 7e00h
10 nticks          equ data_start
11 muscur          equ nticks + 4
12 spkstat         equ muscur + 4
13 vol             equ spkstat + 4
14
15 OSC_FREQ        equ 1193182
16 PIT_DATA0       equ 40h
17 PIT_CMD         equ 43h
18 PIT_CMD_CHAN0   equ 00h
19 PIT_CMD_HILO    equ 30h
20 PIT_CMD_SQWAVE  equ 06h
21 KB_CTRL         equ 61h
22
23 %define DIV_ROUND(a, b) ((a) / (b) + ((a) % (b)) / ((b) / 2))
24
25 %macro setcursor 2
26         mov dl, %1
27         mov dh, %2
28         xor bx, bx
29         mov ah, 2
30         int 10h
31 %endmacro
32 %macro spkon 0
33         in al, KB_CTRL
34         or al, 3
35         out KB_CTRL, al
36 %endmacro
37 %macro spkoff 0
38         in al, KB_CTRL
39         and al, 0fch
40         out KB_CTRL, al
41 %endmacro
42 %macro settimer 2
43         mov al, (PIT_CMD_CHAN0 + (%1 << 6)) | PIT_CMD_HILO | PIT_CMD_SQWAVE
44         out PIT_CMD, al
45         mov ax, %2
46         out PIT_DATA0 + %1, al
47         mov al, ah
48         out PIT_DATA0 + %1, al
49 %endmacro
50
51         xor eax, eax
52         mov ds, ax
53         mov ss, ax
54         mov sp, 7c00h
55
56         mov [nticks], eax
57         mov [muscur], eax
58         ;mov [spkstat], eax
59         ;mov word [vol], 04h
60         mov word [32], timer_intr
61         mov word [34], 0
62
63         settimer 0, DIV_ROUND(OSC_FREQ, 100)
64
65         mov ax, 13h
66         int 10h
67         mov ax, 0a000h
68         mov es, ax
69
70         mov ax, 0303h
71         mov cx, 32000
72         xor di, di
73         rep stosw
74
75         setcursor 10, 12
76         mov si, str1
77         call textout
78         setcursor 12, 13
79         mov si, str2
80         call textout
81
82         sti
83
84 infloop:
85         hlt
86         jmp infloop
87
88 textout:
89         mov al, [si]
90         and al, al
91         jz .done
92         mov ah, 0eh
93         mov bx, 0fh
94         int 10h
95         inc si
96         jmp textout
97 .done:  ret
98
99 timer_intr:
100         pusha
101         mov ax, [nticks]
102         inc ax
103         mov [nticks], ax
104
105 .pmus:  mov bx, [muscur]
106         shl bx, 2
107         mov cx, [music + bx]    ; event time
108         cmp cx, 0ffffh
109         jz .loop
110         cmp ax, cx
111         jb .dopwm
112
113         inc dword [muscur]
114         mov ax, [music + 2 + bx] ; event counter reload
115         test ax, ax
116         jz .off
117         mov bx, ax
118         settimer 2, bx
119         spkon
120         mov word [spkstat], 1
121         jmp .dopwm
122
123 .off:   spkoff
124         mov word [spkstat], 0
125         jmp .eoi
126
127         ; PWM for volume control
128 .dopwm: jmp .eoi
129         spkoff
130         mov ax, [spkstat]
131         test ax, ax
132         jz .eoi
133         mov ax, [nticks]
134         and ax, 0fh
135         cmp ax, [vol]
136         jae .pwmoff
137         spkon
138         jmp .eoi
139 .pwmoff:
140         spkoff
141
142 .eoi:   mov al, 20h
143         out 20h, al     ; EOI
144         popa
145         iret
146
147 .loop:  neg cx
148         mov [muscur], cx
149         jmp .pmus
150         
151
152 str1:   db 'message message blah',0
153 str2:   db 'Michael & Athina',0
154
155 music:
156         dw 0, 2000
157         dw 10, 1900
158         dw 20, 1800
159         dw 30, 1700
160         dw 40, 1600
161         dw 50, 1500
162         dw 60, 1400
163         dw 70, 1300
164         dw 80, 1200
165         dw 90, 1100
166         dw 100, 1000
167         dw 110, 1100
168         dw 120, 1200
169         dw 130, 1300
170         dw 140, 1400
171         dw 150, 1500
172         dw 160, 1600
173         dw 170, 1700
174         dw 180, 1800
175         dw 190, 1900
176         dw 200, 2000
177         dw 210, 0
178         dw 0ffffh, 0
179
180         times 446-($-$$) db 0
181         dd 00212080h
182         dd 0820280ch
183         dd 00000800h
184         dd 0001f800h
185         times 510-($-$$) db 0
186         dw 0aa55h
187
188 ; vi:ft=nasm ts=8 sts=8 sw=8: