-
Notifications
You must be signed in to change notification settings - Fork 0
/
kernel.asm
284 lines (256 loc) · 4.48 KB
/
kernel.asm
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
283
284
[BITS 16]
[ORG 0x8800]
%include "bios.h"
%include "sys_dos.h"
%include "reg.h"
%include "fat.h"
ENTRYPOINT:
MOV AX, CS
MOV ES, AX
MOV DS, AX
MOV SS, AX
MOV GS, AX
MOV FS, AX
MOV SI, PAYLOAD_STRING
CALL PRINT
MOV DX, DOSILE_STUB
MOV AX, SYS_DOS
CALL MAP_INTERRUPT
MOV DL, BYTE [DRIVE_NUM]
MOV AH, DSK_SETDEFAULT
INT SYS_DOS
MOV DX, TESTFCB
MOV AH, 0xF
INT SYS_DOS
CLI
HLT
TESTFCB:
DB 0
DB "TEST "
DB "TXT"
;All INT 21H calls go here
DOSILE_STUB:
PUSHA
PUSH SS
PUSH DS
PUSH ES
PUSH BP
MOV BP, SP
SHR AX, 8
SHL AX, 1
ADD AX, JMP_TAB
MOV SI, AX
MOV AX, [CS:SI]
JMP AX
END_INT:
MOV SP, BP
POP BP
POP ES
POP DS
POP SS
POPA
IRET
;Assumes ES:SI=string
PRINT:
PUSHA
MOV AH, PUTCHAR
PRINTLOOP:
LODSB
OR AL, AL
JZ DONEPRINT
INT TEXT_SERVICE
JMP PRINTLOOP
DONEPRINT:
POPA
RET
;Puts a long address into the interrupt table
MAP_INTERRUPT:
PUSHA
SHL AX, 2
MOV BX, AX
XOR AX, AX
MOV ES, AX
MOV [ES:BX], DX
ADD BX, 2
MOV [ES:BX], DS
POPA
RET
;Print 4 bit number
PRINT_NIBBLE:
AND AL, 0x0F
CMP AL, 10
JGE IS_LETTER
ADD AL, '0'
JMP DONEPRINTNIBBLE
IS_LETTER:
SUB AL, 0x0A
ADD AL, 'A'
DONEPRINTNIBBLE:
MOV AH, PUTCHAR
INT TEXT_SERVICE
RET
;Print 8 bit number
PRINT_BYTE:
PUSHA
MOV BX, AX
SHR AX, 4
CALL PRINT_NIBBLE
MOV AX, BX
CALL PRINT_NIBBLE
POPA
RET
;Print 16 bit number
PRINT_WORD:
PUSHA
MOV BX, AX
MOV AL, BH
CALL PRINT_BYTE
MOV AL, BL
CALL PRINT_BYTE
POPA
RET
;Save SS:SP
SAVE_OLDSTACK:
MOV SI, PSTACKPTR
MOV AX, [CS:SI]
MOV SI, AX
MOV AX, [CS:SI] ;Get the current stack element
MOV SI, AX
MOV AX, SS
MOV [CS:SI], AX ;Save SS
ADD SI, 2
MOV AX, SP
ADD AX, 2 ;Account for the return address
MOV [CS:SI], AX ;Save SP
MOV SI, PSTACKPTR
ADD WORD [CS:SI], 4 ;Update the pstack pointer
RET
;Restore SS:SP
GET_OLDSTACK:
MOV SI, PSTACKPTR
MOV AX, [CS:SI]
MOV SI, AX
MOV AX, [CS:SI] ;Get the current stack element
MOV SI, AX
SUB SI, 2 ;Point to SP
MOV AX, [CS:SI]
MOV SP, AX ;Get SP
SUB SI, 2 ;Point to SS
MOV AX, [CS:SI]
MOV SS, AX ;Get SS
MOV SI, PSTACKPTR
SUB WORD [CS:SI], 4 ;Update pstack pointer
RET
;Prints the register status of the running process when the interrupt fired
REGISTER_DUMP:
MOV AX, CS
MOV ES, AX
MOV SI, STR_AX
CALL PRINT
MOV AX, REGISTER_AX
CALL PRINT_WORD
MOV SI, STR_BX
CALL PRINT
MOV AX, REGISTER_BX
CALL PRINT_WORD
MOV SI, STR_CX
CALL PRINT
MOV AX, REGISTER_CX
CALL PRINT_WORD
MOV SI, STR_DX
CALL PRINT
MOV AX, REGISTER_DX
CALL PRINT_WORD
MOV SI, STR_SI
CALL PRINT
MOV AX, REGISTER_SI
CALL PRINT_WORD
MOV SI, STR_DI
CALL PRINT
MOV AX, REGISTER_DI
CALL PRINT_WORD
MOV SI, STR_BP
CALL PRINT
MOV AX, REGISTER_BP
CALL PRINT_WORD
MOV SI, STR_CS
CALL PRINT
MOV AX, REGISTER_CS
CALL PRINT_WORD
MOV SI, STR_IP
CALL PRINT
MOV AX, REGISTER_IP
CALL PRINT_WORD
MOV SI, STR_CR
CALL PRINT
RET
;Jump table for the interrupt stub
JMP_TAB:
DW DOS_INT_0
DW DOS_INT_1
DW DOS_INT_2
DW NOT_SUPPORTED_TRAP ;Serial IO is #deprecated for Dosile
DW NOT_SUPPORTED_TRAP
DW NOT_SUPPORTED_TRAP ;Printers are #deprecated for Dosile
DW DOS_INT_6
DW DOS_INT_7
DW DOS_INT_8
DW DOS_INT_9
DW DOS_INT_10
DW DOS_INT_11
DW NOT_SUPPORTED_TRAP ;No need to clear the keyboard buffer so far
DW DOS_INT_13
DW DOS_INT_14
DW DOS_INT_15
TIMES 247 DW BAD_INT_TRAP
;Called for interrupts that have no standard in the DOS API
BAD_INT_TRAP:
MOV AX, CS
MOV ES, AX
MOV SI, TRAP_STRING
CALL PRINT
CALL REGISTER_DUMP
CLI
HLT
;Called for interrupts that have no intentions of being implemented
NOT_SUPPORTED_TRAP:
MOV AX, CS
MOV ES, AX
MOV SI, NOT_SUPPORTED
CALL PRINT
CALL REGISTER_DUMP
CLI
HLT
;Area for importing outside code
%include "exec.asm"
%include "con.asm"
%include "disk.asm"
%include "sys/disk.asm"
%include "sys/util.asm"
;Strings for dumping the registers
STR_AX: DB "AX=", 0
STR_BX: DB " BX=", 0
STR_CX: DB " CX=", 0
STR_DX: DB " DX=", 0
STR_SI: DB " SI=", 0
STR_DI: DB " DI=", 0
STR_BP: DB " BP=", 0
STR_CS: DB " EXEC=", 0
STR_IP: DB ":", 0
STR_CR: DB 13, 10, 0
;Stack for calling other programs
PSTACK:
TIMES 20 DW 0
PSTACKPTR:
DW PSTACK
;Current disk and path
DOS_DISK: DB 0
CURRENT_PATH: DB '\\'
TIMES 127 DB 0
;General strings for general kernel notifications etc.
PAYLOAD_STRING: DB "Kernel successfully entered.", 13, 10, 0
INTERRUPT_TEST: DB "Int 21h test call$", 13, 10, 0
TRAP_STRING: DB "Fatal: unknown interrupt option caught", 13, 10, 0
STUB_STRING: DB "Warning: stubbed function.", 13, 10, 0
NOT_SUPPORTED: DB "Unsupported int 21h call caught", 13, 10, 0
__END: