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 ; ==================================================================
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:
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...
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
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
110 cli ; Clear interrupts
112 mov ss, ax ; Set stack segment and pointer
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
125 mov ax, 1003h ; Set text output with certain attributes
126 mov bx, 0 ; to be bright, and not blinking
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
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...
141 jmp execute_bin_program
; ...and move on to the executing part
144 ; Or perhaps there's an AUTORUN.BAS file?
147 mov ax, autorun_bas_file_name
149 jc option_screen
; Skip next section if AUTORUN.BAS doesn't exist
151 mov cx, 32768 ; Otherwise load the program into RAM
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
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)
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
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
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
220 call os_string_length
223 add si, ax ; SI now points to end of filename...
227 dec si ; ...and now to start of extension!
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
238 mov cx, 32768 ; Where to load the program file
239 call os_load_file
; Load filename pointed to by AX
243 call os_clear_screen
; Clear screen before running
245 mov ax, 0 ; Clear all registers
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
267 jmp app_selector
; Start over again...
271 pop si ; We pushed during the .BIN extension check
273 push si ; Save it again in case of error...
277 call os_string_length
280 add si, ax ; SI now points to end of filename...
284 dec si ; ...and now to start of extension!
288 rep cmpsb ; Are final 3 chars 'BAS'?
289 jne not_bas_extension
; If not, error out
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
301 call os_run_basic
; And run our BASIC interpreter on the code!
303 mov si, basic_finished_msg
308 jmp app_selector
; and go back to the program list
317 mov dx, 0 ; One button for 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
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 ; ==================================================================
374 ; ==================================================================