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