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