Mirai's Miscellaneous Misadventures
M27 / 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_x86_boot
10mimimi_x86_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 VBE
59 xor eax, eax
60 mov es, ax
61 mov es, ax
62 mov fs, ax
63 mov gs, ax
64 mov ss, ax
65 call 0:mimimi_vbe_set_mode
66 jc mimimi_x86_exit
67
68# establish keyboard IRQ handler
69 cli
70 mov word ptr [9*4], offset handle_key
71 mov word ptr [9*4+2], 0
72 sti
73
74# set up game state
75 cld
76 mov eax, 0
77 mov ebx, 0
78 mov ecx, 0
79 mov edx, 0
80 mov ds, ax
81 mov es, ax
82 mov fs, ax
83 mov gs, ax
84 mov ss, ax
85 mov esp, 0x7C00
86 mov ebp, esp
87 call 0:mimimi_x86_start
88
89measure_time:
90 mov ah, 0x86
91 mov al, 0
92 mov cx, 2
93 mov dx, 0
94 int 0x15
95 jc measure_time
96
97 lfence ; rdtsc ; lfence
98 mov [time], eax
99 mov [time + 4], edx
100
101 mov ah, 0x86
102 mov al, 0
103 mov cx, 0x08
104 mov dx, 0x2355
105 int 0x15
106 jc measure_time
107
108 lfence ; rdtsc ; lfence
109 sub eax, [time]
110 sbb edx, [time + 4]
111
112 mov ecx, edx
113 and ecx, 0x0F
114 shl ecx, 28
115 shr eax, 4
116 shr edx, 4
117 or eax, ecx
118
119 mov [delta], eax
120 mov [delta + 4], edx
121
122loop:
123 pause
124 lfence ; rdtsc ; lfence
125
126 cmp [time + 4], edx
127 ja loop
128 jb step
129 cmp [time], eax
130 ja loop
131
132step:
133 mov [time], eax
134 mov [time + 4], edx
135
136 mov eax, [delta]
137 mov edx, [delta + 4]
138 add [time], eax
139 adc [time + 4], edx
140
141# switch video modes
142 cmp byte ptr [return], 0
143 jz main
144 mov byte ptr [return], 0
145 call mimimi_vbe_next_mode
146
147main:
148 cld
149 mov eax, 0
150 mov ebx, 0
151 mov ecx, 0
152 mov edx, 0
153 mov ds, ax
154 mov es, ax
155 mov fs, ax
156 mov gs, ax
157 mov ss, ax
158 mov esp, 0x7C00
159 mov ebp, esp
160 call 0:mimimi_x86_step
161
162 jmp loop
163
164lba_to_chs:
165
166 push es
167 push bx
168
169 mov cx, ax
170
171 mov bl, [sectors_per_track]
172 div bl
173 inc ah
174 mov [sector_number], ah
175
176 mov ax, cx
177 mov bl, [sectors_per_track]
178 div bl
179 cbw
180 mov bl, [heads_per_cylinder]
181 div bl
182 mov [cylinder_number], al
183 mov [head_number], ah
184
185 mov ah, 2
186 mov al, 0x40
187 pop bx
188 mov ch, [cylinder_number]
189 mov cl, [sector_number]
190 mov dl, 0x80
191 mov dh, [head_number]
192 pop es
193
194 int 0x13
195 ret
196
197load_data:
198 mov ecx, 6
199load_loop:
200 dec ecx
201 jz load_end
202
203 push ecx
204 call lba_to_chs
205 pop ecx
206
207 cmp ah, 0
208 jne load_loop
209load_end:
210 ret
211
212handle_key:
213 pusha
214
215 in al, 0x60
216
217 cmp al, 0x4B
218 jne break_left
219 mov byte ptr [mimimi_x86_left], 1
220
221break_left:
222 cmp al, 0xCB
223 jne make_right
224 mov byte ptr [mimimi_x86_left], 0
225
226make_right:
227 cmp al, 0x4D
228 jne break_right
229 mov byte ptr [mimimi_x86_right], 1
230
231break_right:
232 cmp al, 0xCD
233 jne break_return
234 mov byte ptr [mimimi_x86_right], 0
235
236break_return:
237 cmp al, 0x9C
238 jne handle_key_done
239 mov byte ptr [return], 1
240
241handle_key_done:
242 in al, 0x61
243 mov ah, al
244 or al, 0x80
245 out 0x61, al
246 mov al, ah
247 out 0x61, al
248
249 mov al, 0x20
250 out 0x20, al
251
252 popa
253 iret
254
255.global mimimi_x86_exit
256mimimi_x86_exit:
257 cli
258 hlt
259 jmp mimimi_x86_exit
260
261.global mimimi_x86_left, mimimi_x86_right
262mimimi_x86_left: .zero 1
263mimimi_x86_right: .zero 1
264return: .zero 1
265
266sectors_per_track: .zero 1
267heads_per_cylinder: .zero 1
268sector_number: .zero 1
269cylinder_number: .zero 1
270head_number: .zero 1
271
272delta: .zero 8
273time: .zero 8