https://github.com/akkartik/mu/blob/main/boot.subx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 == code
25
26
27
28
29
30
31
32
33
34 fa/disable-interrupts
35
36
37 b8/copy-to-ax 0/imm16
38 8e/->seg 3/mod/direct 0/rm32/ax 3/r32/ds
39 8e/->seg 3/mod/direct 0/rm32/ax 0/r32/es
40 8e/->seg 3/mod/direct 0/rm32/ax 4/r32/fs
41 8e/->seg 3/mod/direct 0/rm32/ax 5/r32/gs
42
43
44
45
46
47 b8/copy-to-ax 0x7000/imm16
48 8e/->seg 3/mod/direct 0/rm32/ax 2/r32/ss
49 bc/copy-to-esp 0/imm16
50
51
52
53 {
54 e4/read-port-into-al 0x64/imm8
55 a8/test-bits-in-al 0x02/imm8
56 75/jump-if-!zero loop/imm8
57 b0/copy-to-al 0xd1/imm8
58 e6/write-al-into-port 0x64/imm8
59 }
60 {
61 e4/read-port-into-al 0x64/imm8
62 a8/test-bits-in-al 0x02/imm8
63 75/jump-if-!zero loop/imm8
64 b0/copy-to-al 0xdf/imm8
65 e6/write-al-into-port 0x64/imm8
66 }
67
68
69 b4/copy-to-ah 2/imm8/read-drive
70
71 b5/copy-to-ch 0/imm8/cylinder
72 b6/copy-to-dh 0/imm8/head
73 b1/copy-to-cl 2/imm8/sector
74 b0/copy-to-al 0x7d/imm8/num-sectors
75
76 bb/copy-to-bx 0/imm16
77 8e/->seg 3/mod/direct 3/rm32/bx 0/r32/es
78 bb/copy-to-bx 0x7e00/imm16
79 cd/syscall 0x13/imm8/bios-disk-services
80 0f 82/jump-if-carry disk_error/disp16
81
82
83 b4/copy-to-ah 2/imm8/read-drive
84
85 b5/copy-to-ch 0/imm8/cylinder
86 b6/copy-to-dh 2/imm8/head
87 b1/copy-to-cl 1/imm8/sector
88 b0/copy-to-al 0x7e/imm8/num-sectors
89
90 bb/copy-to-bx 0x1780/imm16
91 8e/->seg 3/mod/direct 3/rm32/bx 0/r32/es
92 bb/copy-to-bx 0/imm16
93 cd/syscall 0x13/imm8/bios-disk-services
94 0f 82/jump-if-carry disk_error/disp16
95
96
97 b4/copy-to-ah 2/imm8/read-drive
98
99 b5/copy-to-ch 0/imm8/cylinder
100 b6/copy-to-dh 4/imm8/head
101 b1/copy-to-cl 1/imm8/sector
102 b0/copy-to-al 0x7e/imm8/num-sectors
103
104 bb/copy-to-bx 0x2740/imm16
105 8e/->seg 3/mod/direct 3/rm32/bx 0/r32/es
106 bb/copy-to-bx 0/imm16
107 cd/syscall 0x13/imm8/bios-disk-services
108 0f 82/jump-if-carry disk_error/disp16
109
110
111 bb/copy-to-bx 0/imm16
112 8e/->seg 3/mod/direct 3/rm32/bx 0/r32/es
113
114
115 b4/copy-to-ah 0x4f/imm8
116 b0/copy-to-al 2/imm8
117 bb/copy-to-bx 0x4105/imm16
118
119
120
121 cd/syscall 0x10/imm8/bios-video-services
122
123
124
125 b4/copy-to-ah 0x4f/imm8
126 b0/copy-to-al 1/imm8
127 b9/copy-to-cx 0x0105/imm16
128 bf/copy-to-di Video-mode-info/imm16
129 cd/syscall 0x10/imm8/bios-video-services
130
131
132
133
134
135
136 0f 01 2/subop/lgdt 0/mod/indirect 6/rm32/use-disp16 0x7ce0/disp16/gdt_descriptor
137
138 0f 20/<-cr 3/mod/direct 0/rm32/eax 0/r32/cr0
139 66 83 1/subop/or 3/mod/direct 0/rm32/eax 1/imm8
140 0f 22/->cr 3/mod/direct 0/rm32/eax 0/r32/cr0
141
142
143
144 ea/jump-far-absolute 0x00087d00/disp32
145
146 disk_error:
147
148
149 bb/copy-to-bx 0xb800/imm16
150 8e/->seg 3/mod/direct 3/rm32/bx 3/r32/ds
151 b0/copy-to-al 0x44/imm8/D
152 b4/copy-to-ah 0x0f/imm8/white-on-black
153 bb/copy-to-bx 0/imm16
154 89/<- 0/mod/indirect 7/rm32/bx 0/r32/ax
155
156 {
157 eb/jump loop/disp8
158 }
159
160
161 == data 0x7ce0
162 gdt_descriptor:
163 0x17/imm16
164 gdt_start/imm32/start
165
166 gdt_start:
167
168 00 00 00 00 00 00 00 00
169
170 ff ff
171 00 00 00
172 9a
173
174 cf
175
176 00
177
178 ff ff
179 00 00 00
180 92
181
182 cf
183 00
184
185
186
187
188 == code 0x7d00
189 initialize_32bit_mode:
190 66 b8/copy-to-ax 0x10/imm16
191 8e/->seg 3/mod/direct 0/rm32/ax 3/r32/ds
192 8e/->seg 3/mod/direct 0/rm32/ax 2/r32/ss
193 8e/->seg 3/mod/direct 0/rm32/ax 0/r32/es
194 8e/->seg 3/mod/direct 0/rm32/ax 4/r32/fs
195 8e/->seg 3/mod/direct 0/rm32/ax 5/r32/gs
196
197 bc/copy-to-esp 0x00070000/imm32
198
199
200
201
202
203 0f 01 3/subop/lidt 0/mod/indirect 5/rm32/use-disp32 0x7e00/disp32/idt_descriptor
204
205
206
207
208
209
210
211
212
213
214
215 b0/copy-to-al 0xfd/imm8
216 e6/write-al-into-port 0x21/imm8
217
218 fb/enable-interrupts
219
220 (initialize-mouse)
221
222
223 db/floating-point-coprocessor e3/initialize
224
225 0f 20/<-cr 3/mod/direct 0/rm32/eax 4/r32/cr4
226
227 0f ba/bit-test 5/subop/bit-test-and-set 3/mod/direct 0/rm32/eax 9/imm8
228
229 0f 22/->cr 3/mod/direct 0/rm32/eax 4/r32/cr4
230
231 e9/jump Entry/disp32
232
233 == boot-sector-marker 0x7dfe
234
235 55 aa
236
237
238
239 == data 0x7e00
240 idt_descriptor:
241 ff 03
242 idt_start/imm32/start
243
244 +-- 55 lines: # interrupt descriptor table ----------------------------------------------------------------------------------------------------------------------------------------------
299
300 == code
301
302 null-interrupt-handler:
303 cf/return-from-interrupt
304
305 keyboard-interrupt-handler:
306
307 fa/disable-interrupts
308 60/push-all-registers
309
310 b0/copy-to-al 0x20/imm8
311 e6/write-al-into-port 0x20/imm8
312 31/xor %eax 0/r32/eax
313
314 e4/read-port-into-al 0x64/imm8
315 a8/test-bits-in-al 0x01/imm8
316 74/jump-if-not-set $keyboard-interrupt-handler:epilogue/disp8
317
318
319 31/xor %ecx 1/r32/ecx
320 8a/byte-> *Keyboard-buffer:write 1/r32/cl
321 81 0/subop/add %ecx Keyboard-buffer:data/imm32
322
323 8a/byte-> *ecx 0/r32/al
324
325 3c/compare-al-and 0/imm8
326 75/jump-if-!= $keyboard-interrupt-handler:epilogue/disp8
327
328 e4/read-port-into-al 0x60/imm8
329
330
331 {
332 3c/compare-al-and 0xaa/imm8
333 75/jump-if-!= break/disp8
334
335 c7 0/subop/copy *Keyboard-shift-pressed? 0/imm32
336 }
337
338 {
339 3c/compare-al-and 0xb6/imm8
340 75/jump-if-!= break/disp8
341
342 c7 0/subop/copy *Keyboard-shift-pressed? 0/imm32
343 }
344
345 {
346 3c/compare-al-and 0x9d/imm8
347 75/jump-if-!= break/disp8
348
349 c7 0/subop/copy *Keyboard-ctrl-pressed? 0/imm32
350 }
351
352 50/push-eax
353 24/and-al-with 0x80/imm8
354 3c/compare-al-and 0/imm8
355 58/pop-to-eax
356 75/jump-if-!= $keyboard-interrupt-handler:epilogue/disp8
357
358
359 {
360 3c/compare-al-and 0x2a/imm8
361 75/jump-if-!= break/disp8
362
363 c7 0/subop/copy *Keyboard-shift-pressed? 1/imm32
364
365 eb/jump $keyboard-interrupt-handler:epilogue/disp8
366 }
367
368 {
369 3c/compare-al-and 0x36/imm8
370 75/jump-if-!= break/disp8
371
372 c7 0/subop/copy *Keyboard-shift-pressed? 1/imm32
373
374 eb/jump $keyboard-interrupt-handler:epilogue/disp8
375 }
376
377 {
378 3c/compare-al-and 0x1d/imm8
379 75/jump-if-!= break/disp8
380
381 c7 0/subop/copy *Keyboard-ctrl-pressed? 1/imm32
382
383 eb/jump $keyboard-interrupt-handler:epilogue/disp8
384 }
385
386
387 {
388 81 7/subop/compare *Keyboard-shift-pressed? 0/imm32
389 74/jump-if-= break/disp8
390
391 05/add-to-eax Keyboard-shift-map/imm32
392 8a/byte-> *eax 0/r32/al
393 eb/jump $keyboard-interrupt-handler:select-map-done/disp8
394 }
395
396 {
397 81 7/subop/compare *Keyboard-ctrl-pressed? 0/imm32
398 74/jump-if-= break/disp8
399 05/add-to-eax Keyboard-ctrl-map/imm32
400 8a/byte-> *eax 0/r32/al
401 eb/jump $keyboard-interrupt-handler:select-map-done/disp8
402 }
403
404 05/add-to-eax Keyboard-normal-map/imm32
405 8a/byte-> *eax 0/r32/al
406 $keyboard-interrupt-handler:select-map-done:
407
408 {
409 3c/compare-al-and 0/imm8
410 74/jump-if-= break/disp8
411
412 88/<- *ecx 0/r32/al
413
414 fe/increment-byte *Keyboard-buffer:write
415
416 80 4/subop/and-byte *Keyboard-buffer:write 0x0f/imm8
417 }
418 $keyboard-interrupt-handler:epilogue:
419
420 61/pop-all-registers
421 fb/enable-interrupts
422 cf/return-from-interrupt
423
424 == data
425 Keyboard-shift-pressed?:
426 0/imm32
427
428 Keyboard-ctrl-pressed?:
429 0/imm32
430
431
432 Keyboard-buffer:write:
433 0/imm32
434 Keyboard-buffer:read:
435 0/imm32
436 Keyboard-buffer:data:
437 00 00 00 00
438 00 00 00 00
439 00 00 00 00
440 00 00 00 00
441
442 +-- 70 lines: # Keyboard maps for translating keys to ASCII -----------------------------------------------------------------------------------------------------------------------------
512
513 Video-mode-info:
514 +-- 53 lines: # video mode info ---------------------------------------------------------------------------------------------------------------------------------------------------------
567
568 Font:
569 +--236 lines: # Bitmaps for some ASCII characters (soon Unicode) ------------------------------------------------------------------------------------------------------------------------
805
806 == code
807
808
809
810
811
812
813
814
815
816
817 load-first-sector-from-primary-bus-secondary-drive:
818
819 55/push-ebp
820 89/<- %ebp 4/r32/esp
821
822 50/push-eax
823 51/push-ecx
824 52/push-edx
825
826 (secondary-drive-exists?)
827 3d/compare-eax-and 0/imm32/false
828 0f 84/jump-if-= $load-first-sector-from-primary-bus-secondary-drive:end/disp32
829
830 (ata-drive-select 0xf0)
831 (clear-ata-error)
832 (ata-sector-count 1)
833 (ata-lba 0 0 0)
834 (ata-command 0x20)
835
836 (while-ata-busy)
837 (until-ata-data-available)
838
839 31/xor %eax 0/r32/eax
840 ba/copy-to-edx 0x1f0/imm32
841 b9/copy-to-ecx 0x200/imm32
842 {
843 81 7/subop/compare %ecx 0/imm32
844 74/jump-if-= break/disp8
845 66 ed/read-port-dx-into-ax
846
847 (append-byte *(ebp+8) %eax)
848 49/decrement-ecx
849 c1/shift 5/subop/right-padding-zeroes %eax 8/imm8
850 (append-byte *(ebp+8) %eax)
851 49/decrement-ecx
852 eb/jump loop/disp8
853 }
854 $load-first-sector-from-primary-bus-secondary-drive:end:
855
856 5a/pop-to-edx
857 59/pop-to-ecx
858 58/pop-to-eax
859
860 89/<- %esp 5/r32/ebp
861 5d/pop-to-ebp
862 c3/return
863
864 store-first-sector-to-primary-bus-secondary-drive:
865
866 55/push-ebp
867 89/<- %ebp 4/r32/esp
868
869 50/push-eax
870 51/push-ecx
871 52/push-edx
872 53/push-ebx
873
874 (secondary-drive-exists?)
875 3d/compare-eax-and 0/imm32/false
876 0f 84/jump-if-= $store-first-sector-to-primary-bus-secondary-drive:end/disp32
877
878 (ata-drive-select 0xf0)
879 (clear-ata-error)
880 (ata-sector-count 1)
881 (ata-lba 0 0 0)
882 (ata-command 0x30)
883
884 (while-ata-busy)
885 (until-ata-ready-for-data)
886
887 ba/copy-to-edx 0x1f0/imm32
888 b9/copy-to-ecx 0x200/imm32
889
890
891 bb/copy-to-ebx 0xffff/imm32
892 $store-first-sector-to-primary-bus-secondary-drive:loop:
893 {
894 81 7/subop/compare %ecx 0/imm32
895 74/jump-if-= break/disp8
896
897 (stream-empty? *(ebp+8))
898 3d/compare-eax-and 0/imm32/false
899 75/jump-if-!= break/disp8
900
901 (read-byte *(ebp+8))
902
903 81 7/subop/compare %ebx 0xff/imm32
904 {
905 7e/jump-if-<= break/disp8
906 89/<- %ebx 0/r32/eax
907 eb/jump $store-first-sector-to-primary-bus-secondary-drive:loop/disp8
908 }
909
910 c1/shift 4/subop/left %eax 8/imm8
911 09/or %eax 3/r32/ebx
912 66 ef/write-ax-into-port-dx
913 49/decrement-ecx
914 49/decrement-ecx
915
916 bb/copy-to-ebx 0xffff/imm32
917 eb/jump loop/disp8
918 }
919
920 81 7/subop/compare %ebx 0xff/imm32
921 {
922 7f/jump-if-> break/disp8
923 89/<- %eax 3/r32/ebx
924 66 ef/write-ax-into-port-dx
925 49/decrement-ecx
926 49/decrement-ecx
927 }
928
929 31/xor %eax 0/r32/eax
930 {
931 81 7/subop/compare %ecx 0/imm32
932 74/jump-if-= break/disp8
933 66 ef/write-ax-into-port-dx
934 49/decrement-ecx
935 49/decrement-ecx
936 eb/jump loop/disp8
937 }
938 $store-first-sector-to-primary-bus-secondary-drive:end:
939
940 5b/pop-to-ebx
941 5a/pop-to-edx
942 59/pop-to-ecx
943 58/pop-to-eax
944
945 89/<- %esp 5/r32/ebp
946 5d/pop-to-ebp
947 c3/return
948
949 +--241 lines: # disk helpers ------------------------------------------------------------------------------------------------------------------------------------------------------------
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200 read-mouse-event:
1201
1202 55/push-ebp
1203 89/<- %ebp 4/r32/esp
1204
1205 52/push-edx
1206 53/push-ebx
1207
1208 b8/copy-to-eax 0/imm32
1209 b9/copy-to-ecx 0/imm32
1210 (any-mouse-event?)
1211 3d/compare-eax-and 0/imm32/false
1212 74/jump-if-= $read-mouse-event:end/disp8
1213
1214 31/xor %eax 0/r32/eax
1215 e4/read-port-into-al 0x60/imm8
1216 89/<- %edx 0/r32/eax
1217 (wait-for-mouse-event)
1218
1219 31/xor %eax 0/r32/eax
1220 e4/read-port-into-al 0x60/imm8
1221 89/<- %ebx 0/r32/eax
1222 (wait-for-mouse-event)
1223
1224 31/xor %eax 0/r32/eax
1225 e4/read-port-into-al 0x60/imm8
1226 89/<- %ecx 0/r32/eax
1227
1228 89/<- %eax 3/r32/ebx
1229
1230 {
1231 f6 0/subop/test-bits %dl 0x10/imm8
1232 74/jump-if-zero break/disp8
1233 0d/or-eax-with 0xffffff00/imm32
1234 }
1235
1236 {
1237 f6 0/subop/test-bits %dl 0x20/imm8
1238 74/jump-if-zero break/disp8
1239 81 1/subop/or %ecx 0xffffff00/imm32
1240 }
1241 $read-mouse-event:end:
1242
1243 5b/pop-to-ebx
1244 5a/pop-to-edx
1245
1246 89/<- %esp 5/r32/ebp
1247 5d/pop-to-ebp
1248 c3/return
1249
1250 +--152 lines: # mouse helpers -----------------------------------------------------------------------------------------------------------------------------------------------------------
1402
1403