Mirai's Miscellaneous Misadventures
M25 / x86 / main.s
1# copyright 2022 zamfofex
2# license: AGPLv3 or later
3
4.intel_syntax noprefix
5.code16
6
7.section boot2
8
9.global mimimi_boot
10mimimi_boot:
11
12# query disc geometry
13
14 mov ah, 8
15 mov dl, 0x80
16
17 int 0x13
18 jc mimimi_x86_exit
19 cmp ah, 0
20 jne mimimi_x86_exit
21
22 and cl, 0x3F
23 mov [sectors_per_track], cl
24 inc dh
25 mov [heads_per_cylinder], dh
26
27# load parts after the bootloader
28
29 mov esp, 0x7C00
30 mov ebp, esp
31
32 mov ax, 0x3D
33 mov bx, 0x8000
34 call load_data
35
36 mov ax, 0x1000
37 mov es, ax
38
39 mov ax, 0x7D
40 mov bx, 0
41 call load_data
42
43 mov ax, 0xBD
44 mov bx, 0x8000
45 call load_data
46
47 mov ax, 0x2000
48 mov es, ax
49
50 mov ax, 0xFD
51 mov bx, 0
52 call load_data
53
54 mov ax, 0xFD
55 mov bx, 0x8000
56 call load_data
57
58# set up VESA
59
60 xor eax, eax
61 mov es, ax
62 mov es, ax
63 mov fs, ax
64 mov gs, ax
65 mov ss, ax
66
67 call 0:mimimi_vbe_set_mode
68 jc mimimi_x86_exit
69
70# establish keyboard IRQ handler
71 cli
72 mov [word ptr 9*4], offset handle_key
73 mov [word ptr 9*4+2], 0
74 sti
75
76# set up game state
77 cld
78 mov eax, 0
79 mov ebx, 0
80 mov ecx, 0
81 mov edx, 0
82 mov ds, ax
83 mov es, ax
84 mov fs, ax
85 mov gs, ax
86 mov ss, ax
87 mov esp, 0x7C00
88 mov ebp, esp
89 call 0:mimimi_x86_start
90
91measure_time:
92 mov ah, 0x86
93 mov al, 0
94 mov cx, 2
95 mov dx, 0
96 int 0x15
97 jc measure_time
98
99 lfence ; rdtsc ; lfence
100 mov [time], eax
101 mov [time + 4], edx
102
103 mov ah, 0x86
104 mov al, 0
105 mov cx, 0x08
106 mov dx, 0x2355
107 int 0x15
108 jc measure_time
109
110 lfence ; rdtsc ; lfence
111 sub eax, [time]
112 sbb edx, [time + 4]
113
114 mov ecx, edx
115 and ecx, 0x0F
116 shl ecx, 28
117 shr eax, 4
118 shr edx, 4
119 or eax, ecx
120
121 mov [delta], eax
122 mov [delta + 4], edx
123
124loop:
125 pause
126 lfence ; rdtsc ; lfence
127
128 cmp [time + 4], edx
129 ja loop
130 jb step
131 cmp [time], eax
132 ja loop
133
134step:
135 mov [time], eax
136 mov [time + 4], edx
137
138 mov eax, [delta]
139 mov edx, [delta + 4]
140 add [time], eax
141 adc [time + 4], edx
142
143# switch video modes
144 cmp [byte ptr return], 0
145 jz main
146 mov [byte ptr return], 0
147 call mimimi_vbe_next_mode
148
149main:
150 cld
151 mov eax, 0
152 mov ebx, 0
153 mov ecx, 0
154 mov edx, 0
155 mov ds, ax
156 mov es, ax
157 mov fs, ax
158 mov gs, ax
159 mov ss, ax
160 mov esp, 0x7C00
161 mov ebp, esp
162 call 0:mimimi_x86_step
163
164 jmp loop
165
166lba_to_chs:
167
168 push es
169 push bx
170
171 mov cx, ax
172
173 mov bl, [sectors_per_track]
174 div bl
175 inc ah
176 mov [sector_number], ah
177
178 mov ax, cx
179 mov bl, [sectors_per_track]
180 div bl
181 cbw
182 mov bl, [heads_per_cylinder]
183 div bl
184 mov [cylinder_number], al
185 mov [head_number], ah
186
187 mov ah, 2
188 mov al, 0x40
189 pop bx
190 mov ch, [cylinder_number]
191 mov cl, [sector_number]
192 mov dl, 0x80
193 mov dh, [head_number]
194 pop es
195
196 int 0x13
197 ret
198
199load_data:
200 mov ecx, 6
201load_loop:
202 dec ecx
203 jz load_end
204
205 push ecx
206 call lba_to_chs
207 pop ecx
208
209 cmp ah, 0
210 jne load_loop
211load_end:
212 ret
213
214handle_key:
215 pusha
216
217 in al, 0x60
218
219 cmp al, 0x4B
220 jne break_left
221 mov [byte ptr mimimi_x86_left], 1
222
223break_left:
224 cmp al, 0xCB
225 jne make_right
226 mov [byte ptr mimimi_x86_left], 0
227
228make_right:
229 cmp al, 0x4D
230 jne break_right
231 mov [byte ptr mimimi_x86_right], 1
232
233break_right:
234 cmp al, 0xCD
235 jne break_return
236 mov [byte ptr mimimi_x86_right], 0
237
238break_return:
239 cmp al, 0x9C
240 jne handle_key_done
241 mov [byte ptr return], 1
242
243handle_key_done:
244 in al, 0x61
245 mov ah, al
246 or al, 0x80
247 out 0x61, al
248 mov al, ah
249 out 0x61, al
250
251 mov al, 0x20
252 out 0x20, al
253
254 popa
255 iret
256
257.global mimimi_x86_exit
258mimimi_x86_exit:
259 cli
260 hlt
261 jmp mimimi_x86_exit
262
263.global mimimi_x86_left, mimimi_x86_right
264mimimi_x86_left: .zero 1
265mimimi_x86_right: .zero 1
266return: .zero 1
267
268sectors_per_track: .zero 1
269heads_per_cylinder: .zero 1
270sector_number: .zero 1
271cylinder_number: .zero 1
272head_number: .zero 1
273
274delta: .zero 8
275time: .zero 8