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
25
26 == code
27
28
29
30
31
32
33
34
35
36 fa/disable-interrupts
37
38
39 b8/copy-to-ax 0/imm16
40 8e/->seg 3/mod/direct 0/rm32/ax 3/r32/ds
41 8e/->seg 3/mod/direct 0/rm32/ax 0/r32/es
42 8e/->seg 3/mod/direct 0/rm32/ax 4/r32/fs
43 8e/->seg 3/mod/direct 0/rm32/ax 5/r32/gs
44
45
46
47
48
49 b8/copy-to-ax 0x7000/imm16
50 8e/->seg 3/mod/direct 0/rm32/ax 2/r32/ss
51 bc/copy-to-esp 0/imm16
52
53
54
55 {
56 e4/read-port-into-al 0x64/imm8
57 a8/test-bits-in-al 0x02/imm8
58 75/jump-if-!zero loop/disp8
59 b0/copy-to-al 0xd1/imm8
60 e6/write-al-into-port 0x64/imm8
61 }
62 {
63 e4/read-port-into-al 0x64/imm8
64 a8/test-bits-in-al 0x02/imm8
65 75/jump-if-!zero loop/disp8
66 b0/copy-to-al 0xdf/imm8
67 e6/write-al-into-port 0x64/imm8
68 }
69
70
71 b4/copy-to-ah 2/imm8/read-drive
72
73 b5/copy-to-ch 0/imm8/cylinder
74 b6/copy-to-dh 0/imm8/head
75 b1/copy-to-cl 2/imm8/sector
76 b0/copy-to-al 0x7d/imm8/num-sectors
77
78 bb/copy-to-bx 0/imm16
79 8e/->seg 3/mod/direct 3/rm32/bx 0/r32/es
80 bb/copy-to-bx 0x7e00/imm16
81 cd/syscall 0x13/imm8/bios-disk-services
82 0f 82/jump-if-carry disk_error/disp16
83
84
85 b4/copy-to-ah 2/imm8/read-drive
86
87 b5/copy-to-ch 0/imm8/cylinder
88 b6/copy-to-dh 2/imm8/head
89 b1/copy-to-cl 1/imm8/sector
90 b0/copy-to-al 0x7e/imm8/num-sectors
91
92 bb/copy-to-bx 0x1780/imm16
93 8e/->seg 3/mod/direct 3/rm32/bx 0/r32/es
94 bb/copy-to-bx 0/imm16
95 cd/syscall 0x13/imm8/bios-disk-services
96 0f 82/jump-if-carry disk_error/disp16
97
98
99 b4/copy-to-ah 2/imm8/read-drive
100
101 b5/copy-to-ch 0/imm8/cylinder
102 b6/copy-to-dh 4/imm8/head
103 b1/copy-to-cl 1/imm8/sector
104 b0/copy-to-al 0x7e/imm8/num-sectors
105
106 bb/copy-to-bx 0x2740/imm16
107 8e/->seg 3/mod/direct 3/rm32/bx 0/r32/es
108 bb/copy-to-bx 0/imm16
109 cd/syscall 0x13/imm8/bios-disk-services
110 0f 82/jump-if-carry disk_error/disp16
111
112
113 b4/copy-to-ah 2/imm8/read-drive
114
115 b5/copy-to-ch 0/imm8/cylinder
116 b6/copy-to-dh 6/imm8/head
117 b1/copy-to-cl 1/imm8/sector
118 b0/copy-to-al 0x7e/imm8/num-sectors
119
120 bb/copy-to-bx 0x3700/imm16
121 8e/->seg 3/mod/direct 3/rm32/bx 0/r32/es
122 bb/copy-to-bx 0/imm16
123 cd/syscall 0x13/imm8/bios-disk-services
124 0f 82/jump-if-carry disk_error/disp16
125
126
127 b4/copy-to-ah 2/imm8/read-drive
128
129 b5/copy-to-ch 0/imm8/cylinder
130 b6/copy-to-dh 8/imm8/head
131 b1/copy-to-cl 1/imm8/sector
132 b0/copy-to-al 0x7e/imm8/num-sectors
133
134 bb/copy-to-bx 0x46c0/imm16
135 8e/->seg 3/mod/direct 3/rm32/bx 0/r32/es
136 bb/copy-to-bx 0/imm16
137 cd/syscall 0x13/imm8/bios-disk-services
138 0f 82/jump-if-carry disk_error/disp16
139
140
141 b4/copy-to-ah 2/imm8/read-drive
142
143 b5/copy-to-ch 0/imm8/cylinder
144 b6/copy-to-dh 0xa/imm8/head
145 b1/copy-to-cl 1/imm8/sector
146 b0/copy-to-al 0x7e/imm8/num-sectors
147
148 bb/copy-to-bx 0x5680/imm16
149 8e/->seg 3/mod/direct 3/rm32/bx 0/r32/es
150 bb/copy-to-bx 0/imm16
151 cd/syscall 0x13/imm8/bios-disk-services
152 0f 82/jump-if-carry disk_error/disp16
153
154
155 b4/copy-to-ah 2/imm8/read-drive
156
157 b5/copy-to-ch 0/imm8/cylinder
158 b6/copy-to-dh 0xc/imm8/head
159 b1/copy-to-cl 1/imm8/sector
160 b0/copy-to-al 0x7e/imm8/num-sectors
161
162 bb/copy-to-bx 0x6640/imm16
163 8e/->seg 3/mod/direct 3/rm32/bx 0/r32/es
164 bb/copy-to-bx 0/imm16
165 cd/syscall 0x13/imm8/bios-disk-services
166 0f 82/jump-if-carry disk_error/disp16
167
168
169 b4/copy-to-ah 2/imm8/read-drive
170
171 b5/copy-to-ch 0/imm8/cylinder
172 b6/copy-to-dh 0xe/imm8/head
173 b1/copy-to-cl 1/imm8/sector
174 b0/copy-to-al 0x3f/imm8/num-sectors=63
175
176 bb/copy-to-bx 0x7600/imm16
177 8e/->seg 3/mod/direct 3/rm32/bx 0/r32/es
178 bb/copy-to-bx 0/imm16
179 cd/syscall 0x13/imm8/bios-disk-services
180 0f 82/jump-if-carry disk_error/disp16
181
182
183
184
185 bb/copy-to-bx 0/imm16
186 8e/->seg 3/mod/direct 3/rm32/bx 0/r32/es
187
188
189 b4/copy-to-ah 0x4f/imm8
190 b0/copy-to-al 2/imm8
191 bb/copy-to-bx 0x4105/imm16
192
193
194
195 cd/syscall 0x10/imm8/bios-video-services
196
197
198
199 b4/copy-to-ah 0x4f/imm8
200 b0/copy-to-al 1/imm8
201 b9/copy-to-cx 0x0105/imm16
202 bf/copy-to-di Video-mode-info/imm16
203 cd/syscall 0x10/imm8/bios-video-services
204
205
206
207
208
209
210 0f 01 2/subop/lgdt 0/mod/indirect 6/rm32/use-disp16 0x7de0/disp16/gdt_descriptor
211
212 0f 20/<-cr 3/mod/direct 0/rm32/eax 0/r32/cr0
213 66 83 1/subop/or 3/mod/direct 0/rm32/eax 1/imm8
214 0f 22/->cr 3/mod/direct 0/rm32/eax 0/r32/cr0
215
216
217
218 ea/jump-far-absolute 0x00087e00/disp32
219
220 disk_error:
221
222
223 bb/copy-to-bx 0xb800/imm16
224 8e/->seg 3/mod/direct 3/rm32/bx 3/r32/ds
225 b0/copy-to-al 0x44/imm8/D
226 b4/copy-to-ah 0x0f/imm8/white-on-black
227 bb/copy-to-bx 0/imm16
228 89/<- 0/mod/indirect 7/rm32/bx 0/r32/ax
229
230 {
231 eb/jump loop/disp8
232 }
233
234
235 == data 0x7de0
236 gdt_descriptor:
237 0x17/imm16
238 gdt_start/imm32/start
239
240 gdt_start:
241
242 00 00 00 00 00 00 00 00
243
244 ff ff
245 00 00 00
246 9a
247
- `clear-screen`
- `draw-text-rightward`: draws a single line of text, stopping when it reaches
either the provided bound or the right screen margin.
- `draw-stream-rightward`
- `draw-text-rightward-over-full-screen`: does not provide a bound.
- `draw-text-wrapping-right-then-down`: draws multiple lines of text on screen
with simplistic word-wrap (no hyphenation) within (x, y) bounds.
- `draw-stream-wrapping-right-then-down`
- `draw-text-wrapping-right-then-down-over-full-screen`
- `draw-int32-hex-wrapping-right-then-down`
- `draw-int32-hex-wrapping-right-then-down-over-full-screen`
- `draw-int32-decimal-wrapping-right-then-down`
- `draw-int32-decimal-wrapping-right-then-down-over-full-screen`
Similar primitives for writing text top-to-bottom, left-to-right.
- `draw-text-downward`
- `draw-stream-downward`
- `draw-text-wrapping-down-then-right`
- `draw-stream-wrapping-down-then-right`
- `draw-text-wrapping-down-then-right-over-full-screen`
- `draw-int32-hex-wrapping-down-then-right`
- `draw-int32-hex-wrapping-down-then-right-over-full-screen`
- `draw-int32-decimal-wrapping-down-then-right`
- `draw-int32-decimal-wrapping-down-then-right-over-full-screen`
Screens remember the current cursor position.
- `cursor-position`
- `set-cursor-position`
- `draw-grapheme-at-cursor`
- `draw-code-point-at-cursor`
- `draw-cursor`: highlights the current position of the cursor. Programs must
pass in the grapheme to draw at the cursor position, and are responsible for
clearing the highlight when the cursor moves.
- `move-cursor-left`, `move-cursor-right`, `move-cursor-up`, `move-cursor-down`.
These primitives always silently fail if the desired movement would go out
of screen bounds.
- `move-cursor-to-left-margin-of-next-line`
- `move-cursor-rightward-and-downward`: move cursor one grapheme to the right
- `draw-text-rightward-from-cursor`
- `draw-text-wrapping-right-then-down-from-cursor`
- `draw-text-wrapping-right-then-down-from-cursor-over-full-screen`
- `draw-int32-hex-wrapping-right-then-down-from-cursor`
- `draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen`
- `draw-int32-decimal-wrapping-right-then-down-from-cursor`
- `draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen`
- `draw-text-wrapping-down-then-right-from-cursor`
- `draw-text-wrapping-down-then-right-from-cursor-over-full-screen`
Assertions for tests:
- `check-screen-row`: compare a screen from the left margin of a given row
index with a string. The row index counts downward from 0 at the top of the
screen. String can be smaller or larger than a single row, and defines the
region of interest. Strings longer than a row wrap around to the left margin
of the next screen row. Currently assumes text is printed left-to-right on
the screen.
- `check-screen-row-from`: compare a fragment of a screen (left to write, top
to bottom) starting from a given (x, y) coordinate with an expected string.
Currently assumes text is printed left-to-right and top-to-bottom on the
screen.
- `check-screen-row-in-color`: like `check-screen-row` but:
- also compares foreground color
- ignores screen locations where the expected string contains spaces
- `check-screen-row-in-color-from`
- `check-screen-row-in-background-color`
- `check-screen-row-in-background-color-from`
- `check-background-color-in-screen-row`: unlike previous functions, this
doesn't check screen contents, only background color. Ignores background
color where expected string contains spaces, and compares background color
where expected string does not contain spaces. Never compares the character
at any screen location.
- `check-background-color-in-screen-row-from`
#### events
`read-key` reads a single key from the keyboard and returns it if it exists.
Returns 0 if no key has been pressed.
`read-mouse-event` returns a recent change in x and y coordinate.
Mu doesn't currently support interrupt-based mouse events.
#### persistent storage
`load-sector` synchronously reads a single _sector_ from a _disk_ of persistent
storage. The disk must follow the ATA specification with a 28-bit sector
address. Each sector is 512 bytes. Therefore, Mu currently supports ATA hard
disks of up to 128GB capacity.
Similarly, `store-sector` synchronously writes a single sector to disk.
Mu doesn't currently support asynchronous transfers to or from a disk.