* mikeOS 16 bit and amd64 baremetal
[mascara-docs.git] / i86 / mikeos-4.1.2 / source / kernel.asm
blob79e130e98b196f8d0f75422cda7e4464fe8eb16e
1 ; ==================================================================
2 ; MikeOS -- The Mike Operating System kernel
3 ; Copyright (C) 2006 - 2011 MikeOS Developers -- see doc/LICENSE.TXT
5 ; This is loaded from the floppy/CD, by BOOTLOAD.BIN, as KERNEL.BIN.
6 ; First we have the system call vectors, which start at a static point
7 ; for programs to jump to. Following that is the main kernel code and
8 ; then additional system call code is included.
9 ; ==================================================================
12 BITS 16
14 %DEFINE MIKEOS_VER '4.1.2' ; OS version number
15 %DEFINE MIKEOS_API_VER 13 ; API version for programs to check
18 ; This is the location in RAM for kernel disk operations, 24K
19 ; after the point where the kernel has loaded; it's 8K in size,
20 ; because external programs load after it at the 32K point:
22 disk_buffer equ 24576
25 ; ------------------------------------------------------------------
26 ; OS CALL VECTORS -- Static locations for system call vectors
27 ; Note: these cannot be moved, or it'll break the calls!
29 ; The comments show exact locations of instructions in this section,
30 ; and are used in programs/mikedev.inc so that an external program can
31 ; use a MikeOS system call without having to know its exact position
32 ; in the kernel source code...
34 os_call_vectors:
35 jmp os_main ; 0000h -- Called from bootloader
36 jmp os_print_string ; 0003h
37 jmp os_move_cursor ; 0006h
38 jmp os_clear_screen ; 0009h
39 jmp os_print_horiz_line ; 000Ch
40 jmp os_print_newline ; 000Fh
41 jmp os_wait_for_key ; 0012h
42 jmp os_check_for_key ; 0015h
43 jmp os_int_to_string ; 0018h
44 jmp os_speaker_tone ; 001Bh
45 jmp os_speaker_off ; 001Eh
46 jmp os_load_file ; 0021h
47 jmp os_pause ; 0024h
48 jmp os_fatal_error ; 0027h
49 jmp os_draw_background ; 002Ah
50 jmp os_string_length ; 002Dh
51 jmp os_string_uppercase ; 0030h
52 jmp os_string_lowercase ; 0033h
53 jmp os_input_string ; 0036h
54 jmp os_string_copy ; 0039h
55 jmp os_dialog_box ; 003Ch
56 jmp os_string_join ; 003Fh
57 jmp os_get_file_list ; 0042h
58 jmp os_string_compare ; 0045h
59 jmp os_string_chomp ; 0048h
60 jmp os_string_strip ; 004Bh
61 jmp os_string_truncate ; 004Eh
62 jmp os_bcd_to_int ; 0051h
63 jmp os_get_time_string ; 0055h
64 jmp os_get_api_version ; 0057h
65 jmp os_file_selector ; 005Ah
66 jmp os_get_date_string ; 005Dh
67 jmp os_send_via_serial ; 0060h
68 jmp os_get_via_serial ; 0063h
69 jmp os_find_char_in_string ; 0066h
70 jmp os_get_cursor_pos ; 0069h
71 jmp os_print_space ; 006Ch
72 jmp os_dump_string ; 006Fh
73 jmp os_print_digit ; 0072h
74 jmp os_print_1hex ; 0075h
75 jmp os_print_2hex ; 0078h
76 jmp os_print_4hex ; 007Bh
77 jmp os_long_int_to_string ; 007Eh
78 jmp os_long_int_negate ; 0081h
79 jmp os_set_time_fmt ; 0084h
80 jmp os_set_date_fmt ; 0087h
81 jmp os_show_cursor ; 008Ah
82 jmp os_hide_cursor ; 008Dh
83 jmp os_dump_registers ; 0090h
84 jmp os_string_strincmp ; 0093h
85 jmp os_write_file ; 0096h
86 jmp os_file_exists ; 0099h
87 jmp os_create_file ; 009Ch
88 jmp os_remove_file ; 009Fh
89 jmp os_rename_file ; 00A2h
90 jmp os_get_file_size ; 00A5h
91 jmp os_input_dialog ; 00A8h
92 jmp os_list_dialog ; 00ABh
93 jmp os_string_reverse ; 00AEh
94 jmp os_string_to_int ; 00B1h
95 jmp os_draw_block ; 00B4h
96 jmp os_get_random ; 00B7h
97 jmp os_string_charchange ; 00BAh
98 jmp os_serial_port_enable ; 00BDh
99 jmp os_sint_to_string ; 00C0h
100 jmp os_string_parse ; 00C3h
101 jmp os_run_basic ; 00C6h
102 jmp os_port_byte_out ; 00C9h
103 jmp os_port_byte_in ; 00CCh
106 ; ------------------------------------------------------------------
107 ; START OF MAIN KERNEL CODE
109 os_main:
110 cli ; Clear interrupts
111 mov ax, 0
112 mov ss, ax ; Set stack segment and pointer
113 mov sp, 0FFFFh
114 sti ; Restore interrupts
116 cld ; The default direction for string operations
117 ; will be 'up' - incrementing address in RAM
119 mov ax, 2000h ; Set all segments to match where kernel is loaded
120 mov ds, ax ; After this, we don't need to bother with
121 mov es, ax ; segments ever again, as MikeOS and its programs
122 mov fs, ax ; live entirely in 64K
123 mov gs, ax
125 mov ax, 1003h ; Set text output with certain attributes
126 mov bx, 0 ; to be bright, and not blinking
127 int 10h
129 call os_seed_random ; Seed random number generator
132 ; Let's see if there's a file called AUTORUN.BIN and execute
133 ; it if so, before going to the program launcher menu
135 mov ax, autorun_bin_file_name
136 call os_file_exists
137 jc no_autorun_bin ; Skip next three lines if AUTORUN.BIN doesn't exist
139 mov cx, 32768 ; Otherwise load the program into RAM...
140 call os_load_file
141 jmp execute_bin_program ; ...and move on to the executing part
144 ; Or perhaps there's an AUTORUN.BAS file?
146 no_autorun_bin:
147 mov ax, autorun_bas_file_name
148 call os_file_exists
149 jc option_screen ; Skip next section if AUTORUN.BAS doesn't exist
151 mov cx, 32768 ; Otherwise load the program into RAM
152 call os_load_file
153 call os_clear_screen
154 mov ax, 32768
155 call os_run_basic ; Run the kernel's BASIC interpreter
157 jmp app_selector ; And go to the app selector menu when BASIC ends
160 ; Now we display a dialog box offering the user a choice of
161 ; a menu-driven program selector, or a command-line interface
163 option_screen:
164 mov ax, os_init_msg ; Set up the welcome screen
165 mov bx, os_version_msg
166 mov cx, 10011111b ; Colour: white text on light blue
167 call os_draw_background
169 mov ax, dialog_string_1 ; Ask if user wants app selector or command-line
170 mov bx, dialog_string_2
171 mov cx, dialog_string_3
172 mov dx, 1 ; We want a two-option dialog box (OK or Cancel)
173 call os_dialog_box
175 cmp ax, 1 ; If OK (option 0) chosen, start app selector
176 jne near app_selector
178 call os_clear_screen ; Otherwise clean screen and start the CLI
179 call os_command_line
181 jmp option_screen ; Offer menu/CLI choice after CLI has exited
184 ; Data for the above code...
186 os_init_msg db 'Welcome to MikeOS', 0
187 os_version_msg db 'Version ', MIKEOS_VER, 0
189 dialog_string_1 db 'Thanks for trying out MikeOS!', 0
190 dialog_string_2 db 'Please select an interface: OK for the', 0
191 dialog_string_3 db 'program menu, Cancel for command line.', 0
195 app_selector:
196 mov ax, os_init_msg ; Draw main screen layout
197 mov bx, os_version_msg
198 mov cx, 10011111b ; Colour: white text on light blue
199 call os_draw_background
201 call os_file_selector ; Get user to select a file, and store
202 ; the resulting string location in AX
203 ; (other registers are undetermined)
205 jc option_screen ; Return to the CLI/menu choice screen if Esc pressed
207 mov si, ax ; Did the user try to run 'KERNEL.BIN'?
208 mov di, kern_file_name
209 call os_string_compare
210 jc no_kernel_execute ; Show an error message if so
213 ; Next, we need to check that the program we're attempting to run is
214 ; valid -- in other words, that it has a .BIN extension
216 push si ; Save filename temporarily
218 mov bx, si
219 mov ax, si
220 call os_string_length
222 mov si, bx
223 add si, ax ; SI now points to end of filename...
225 dec si
226 dec si
227 dec si ; ...and now to start of extension!
229 mov di, bin_ext
230 mov cx, 3
231 rep cmpsb ; Are final 3 chars 'BIN'?
232 jne not_bin_extension ; If not, it might be a '.BAS'
234 pop si ; Restore filename
237 mov ax, si
238 mov cx, 32768 ; Where to load the program file
239 call os_load_file ; Load filename pointed to by AX
242 execute_bin_program:
243 call os_clear_screen ; Clear screen before running
245 mov ax, 0 ; Clear all registers
246 mov bx, 0
247 mov cx, 0
248 mov dx, 0
249 mov si, 0
250 mov di, 0
252 call 32768 ; Call the external program code,
253 ; loaded at second 32K of segment
254 ; (program must end with 'ret')
256 call os_clear_screen ; When finished, clear screen
257 jmp app_selector ; and go back to the program list
260 no_kernel_execute: ; Warn about trying to executing kernel!
261 mov ax, kerndlg_string_1
262 mov bx, kerndlg_string_2
263 mov cx, kerndlg_string_3
264 mov dx, 0 ; One button for dialog box
265 call os_dialog_box
267 jmp app_selector ; Start over again...
270 not_bin_extension:
271 pop si ; We pushed during the .BIN extension check
273 push si ; Save it again in case of error...
275 mov bx, si
276 mov ax, si
277 call os_string_length
279 mov si, bx
280 add si, ax ; SI now points to end of filename...
282 dec si
283 dec si
284 dec si ; ...and now to start of extension!
286 mov di, bas_ext
287 mov cx, 3
288 rep cmpsb ; Are final 3 chars 'BAS'?
289 jne not_bas_extension ; If not, error out
292 pop si
294 mov ax, si
295 mov cx, 32768 ; Where to load the program file
296 call os_load_file ; Load filename pointed to by AX
298 call os_clear_screen ; Clear screen before running
300 mov ax, 32768
301 call os_run_basic ; And run our BASIC interpreter on the code!
303 mov si, basic_finished_msg
304 call os_print_string
305 call os_wait_for_key
307 call os_clear_screen
308 jmp app_selector ; and go back to the program list
311 not_bas_extension:
312 pop si
314 mov ax, ext_string_1
315 mov bx, ext_string_2
316 mov cx, 0
317 mov dx, 0 ; One button for dialog box
318 call os_dialog_box
320 jmp app_selector ; Start over again...
323 ; And now data for the above code...
325 kern_file_name db 'KERNEL.BIN', 0
327 autorun_bin_file_name db 'AUTORUN.BIN', 0
328 autorun_bas_file_name db 'AUTORUN.BAS', 0
330 bin_ext db 'BIN'
331 bas_ext db 'BAS'
333 kerndlg_string_1 db 'Cannot load and execute MikeOS kernel!', 0
334 kerndlg_string_2 db 'KERNEL.BIN is the core of MikeOS, and', 0
335 kerndlg_string_3 db 'is not a normal program.', 0
337 ext_string_1 db 'Invalid filename extension! You can', 0
338 ext_string_2 db 'only execute .BIN or .BAS programs.', 0
340 basic_finished_msg db '>>> BASIC program finished -- press a key', 0
343 ; ------------------------------------------------------------------
344 ; SYSTEM VARIABLES -- Settings for programs and system calls
347 ; Time and date formatting
349 fmt_12_24 db 0 ; Non-zero = 24-hr format
351 fmt_date db 0, '/' ; 0, 1, 2 = M/D/Y, D/M/Y or Y/M/D
352 ; Bit 7 = use name for months
353 ; If bit 7 = 0, second byte = separator character
356 ; ------------------------------------------------------------------
357 ; FEATURES -- Code to pull into the kernel
360 %INCLUDE "features/cli.asm"
361 %INCLUDE "features/basic.asm"
362 %INCLUDE "features/disk.asm"
363 %INCLUDE "features/keyboard.asm"
364 %INCLUDE "features/math.asm"
365 %INCLUDE "features/misc.asm"
366 %INCLUDE "features/ports.asm"
367 %INCLUDE "features/screen.asm"
368 %INCLUDE "features/sound.asm"
369 %INCLUDE "features/string.asm"
372 ; ==================================================================
373 ; END OF KERNEL
374 ; ==================================================================