-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathaux.inc
282 lines (214 loc) · 4.66 KB
/
aux.inc
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
init_screen:
pusha
mov edi, 0xb8000 ; Point to video memory
; Draw prompt (at 0,0)
mov ah, byte [CursorAttributes] ; Get cursor attributes
mov al, ' '
stosw
; Fill the screen with spaces
mov ah, byte [CharAttributes] ; Get char attributes
mov al, ' '
mov ecx, 0x07CF
rep stosw
; Set up the variables
mov dword [CursorLocation], 0xb8000
popa
ret
putchar:
pusha
test al, al ; Is 0x00 (null)?
jz .done ; Ignore
cmp al, 0x0A ; Is 0x0A?
je .next_line
cmp al, 0x08 ; Is 0x08?
je .backspace
mov ebx, dword [CursorLocation]
inc ebx
mov ah, byte [CharAttributes]
mov byte [ebx], ah ; Attributes first to avoid 'ghosting'
dec ebx
mov byte [ebx], al ; Print character
inc ebx
inc ebx
cmp ebx, 0xb8fa0 ; End of video memory?
je .scroll_screen_down
mov dword [CursorLocation], ebx
call draw_cursor ; Draw cursor
jmp .done
.next_line:
call get_cursor_position
xor ah, ah ; Set X to 0
cmp al, 24 ; Last line?
je .scroll_screen_down ; Scroll screen
inc al ; Y + 1
call set_cursor_position
jmp .done ; Done
.backspace:
call clear_cursor
sub dword [CursorLocation], 2
mov edi, dword [CursorLocation]
mov al, ' '
stosb
mov al, byte [CursorAttributes]
stosb
call draw_cursor
jmp .done
.scroll_screen_down:
call clear_cursor ; Destroy cursor
mov ebx, 0xb8000 + 160 ; Next line
.scroll_down_loop:
cmp ebx, 0xb8fa0 ; Last char?
je .clear_line
mov eax, dword [ebx] ; Get word
mov dword [ebx-160], eax ; Copy to previous line
add ebx, 4
jmp .scroll_down_loop
.clear_line:
sub ebx, 160
mov dword [CursorLocation], ebx ; New cursor location
mov al, byte [CharAttributes]
.clear_line_loop:
cmp ebx, 0xb8fa0
je .clear_line_done
mov byte [ebx], ' '
inc ebx
mov byte [ebx], al
inc ebx
jmp .clear_line_loop
.clear_line_done:
call draw_cursor ; Restore cursor
.done:
popa
ret
get_cursor_position:
; OUT: AH = cursor X
; AL = cursor Y
push ebx
push ecx
push edx
mov eax, dword [CursorLocation]
sub eax, 0xb8000
mov ebx, 160 ; Divide AX / 160
xor edx, edx
div ebx
and eax, 0x000000ff ; Clear high 8
push eax ; Push result, for now
mov eax, edx ; Load MOD
mov ebx, 2 ; Divide MOD / 2
xor edx, edx
div ebx
mov edx, eax ; Result in DX
pop eax ; Restore AX
mov ah, dl ; Move AH
pop edx
pop ecx
pop ebx
ret
set_cursor_position:
; IN: AH = cursor X
; AL = cursor Y
pusha
call clear_cursor
push eax ; Save AX
and eax, 0x000000ff ; Clear high 8
mov ebx, 160 ; Multiply Y * 160
mul ebx
mov dword [CursorLocation], eax ; Save for now
pop eax ; Restore AX
and eax, 0xffffff00 ; Clear low 8
shr eax, 8 ; Shift right 8
add eax, eax ; Multiply X * 2
add dword [CursorLocation], eax ; Add
add dword [CursorLocation], 0xb8000
call draw_cursor ; Draw cursor back
.done:
popa
ret
draw_cursor:
pusha
mov edi, dword [CursorLocation]
mov al, byte [edi]
mov ah, byte [CursorAttributes]
stosw
popa
ret
clear_cursor:
pusha
mov edi, dword [CursorLocation]
mov al, byte [edi]
mov ah, byte [CharAttributes]
stosw
popa
ret
CursorLocation dd 0xb8000
CharAttributes db 0x07
CursorAttributes db 0x70
getchar:
push ebx
cmp dword [.buffer_ptr], 0
jne .dump
; get scancode
.wait:
xor eax, eax
in al, 0x64
and al, 1
test al, al
jnz .ready
jmp .wait
.ready:
in al, 0x60 ; fetch code
cmp al, 0x36
je .shift
cmp al, 0x2a
je .shift
cmp al, 0xb6
je .shift
cmp al, 0xaa
je .shift
cmp al, 58
jae .wait
add eax, dword [.cur_tab]
mov al, byte [eax]
mov ebx, dword [.buffer_ptr]
cmp ebx, 127
ja .wait ; buffer full, do not accept
call putchar
xchg bx, bx
mov byte [.buffer + ebx], al
inc dword [.buffer_ptr]
cmp al, 0x0a
je .dump
jmp .wait
.dump:
mov eax, dword [.buffer_dmp]
mov al, byte [.buffer + eax]
cmp al, 0x0a
je .dumped
inc dword [.buffer_dmp]
jmp .done
.shift:
mov eax, dword [.last_tab]
xchg dword [.cur_tab], eax
mov dword [.last_tab], eax
jmp .wait
.dumped:
mov dword [.buffer_ptr], 0
mov dword [.buffer_dmp], 0
.done:
pop ebx
ret
.cur_tab dd .ascii_tab
.last_tab dd .ascii_shift_tab
.ascii_tab:
db 0, '?', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', 0x08, 0x09
db 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 0x0a, 0, 'a', 's'
db 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', "'", '`', 0, '\', 'z', 'x', 'c', 'v'
db 'b', 'n', 'm', ',', '.', '/', 0, 0, 0, ' '
.ascii_shift_tab:
db 0, '?', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', 0x08, 0x09
db 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 0x0a, 0, 'A', 'S'
db 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 0, '|', 'Z', 'X', 'C', 'V'
db 'B', 'N', 'M', '<', '>', '?', 0, 0, 0, ' '
.buffer times 128 db 0
.buffer_ptr dd 0
.buffer_dmp dd 0