BASIC Interpreter from MikeOS is functioning

This commit is contained in:
2026-01-20 18:38:51 +00:00
parent e0809f84dc
commit 0f6f8f33f6
22 changed files with 4677 additions and 96 deletions

View File

@@ -22,20 +22,23 @@ ebr_volume_label: db 'CRAWOS0.0.6' ; must be 11 bytes
ebr_system_id: db 'FAT12 ' ; must be 8 bytes
; String operations
fat12_file_name: db ' ' ; 11 free bytes to store a filename in
boot_message: db 'OK] Kernel successfully loaded!\n\n', 0
boot_message: db 'OK] Kernel successfully loaded!\n"HELP" to see a list of available commands\n', 0
user_input: times 20 db 0
prompt_length: db 20
prompt: db 'sh > ', 0
help_string: db 'HELP', 0
clear_string: db 'CLEAR', 0
reboot_string: db 'REBOOT', 0
pong_string: db 'PONG', 0
basic_string: db 'BAS', 0
cat_string: db 'CAT', 0
ls_string: db 'LS', 0
help_text: db 'This is for Cowards:\n"LS" to list the directory,\n"CAT" to output the contents of a file,\n"HELP" for this helpful text,\n"CLEAR" to clear the screen,\n"REBOOT" or esc to reboot\n', 0
help_text: db 'This is for Cowards:\n"LS" to list the directory,\n"CAT" to output the contents of a file,\n"BAS" to run a basic script,\n"HELP" for this helpful text,\n"CLEAR" to clear the screen,\n"REBOOT" or esc to reboot\n', 0
basic_text: db 'BASIC PROGRAM BEGUN:\n', 0
command_result_text: db 'You typed: ', 0
unknown_command: db 'Error: Unkown Command..\n ', 0
stringified_int: db 0,0,0,0,0,0 ; Can store up to 6 digits
; Disk operations
disk_read_fail: db 'Error: Could not read disk\n', 0

File diff suppressed because it is too large Load Diff

View File

@@ -18,7 +18,7 @@ os_start_cli:
os_read_cli:
pusha
mov si, user_input
call os_upper_case ; Make the input uppercase so it's case insensitive
call string_upper_case ; Make the input uppercase so it's case insensitive
.output_the_user_input:
call os_print_newline
@@ -45,6 +45,13 @@ os_read_cli:
cmp cl, 1
je power_reboot
; Basic
mov si, user_input
mov di, basic_string
call os_compare_strings
cmp cl, 1
je basic
; Cat
mov si, user_input
mov di, cat_string
@@ -59,13 +66,6 @@ os_read_cli:
cmp cl, 1
je ls
; Pong
mov si, user_input
mov di, pong_string
call os_compare_strings
cmp cl, 1
je pong
jmp .unkown
.unkown:
@@ -88,10 +88,9 @@ help:
call os_print_string
call os_read_cli.finish
pong:
call game_pong
basic:
call util_basic
call os_read_cli.finish
cat:
call util_cat
call os_read_cli.finish

View File

@@ -173,7 +173,7 @@ disk_clear_output_buffer:
; TODO use predefined data for calculations
disk_load_file:
pusha
call os_string_length ; cl = string length
call string_length ; cl = string length
cmp cl, 11
ja .filename_too_long
@@ -244,7 +244,7 @@ disk_load_file:
disk_write_file:
pusha
; Check if file name is too long
call os_string_length ; cl = string length
call string_length ; cl = string length
cmp cl, 11
ja .filename_too_long
; Convert file name to a fat filename
@@ -302,6 +302,7 @@ disk_write_file:
ret
; TODO support long file names
; TODO don't work twice
; Store a list of the files in file_buffer
; in a human readable format
; OUT
@@ -374,3 +375,14 @@ disk_list_contents:
stosb
popa
ret
disk_file_exists:
ret
disk_file_size:
ret
disk_file_list:
ret
disk_remove_file:
ret
disk_rename_file:
ret

View File

@@ -51,3 +51,10 @@ section .data
y_end dw 0
colour db 1111b
graphics_dialogue_box:
ret
graphics_file_selector:
ret
graphics_list_dialogue:
ret

View File

@@ -7,10 +7,10 @@ os_read_input:
hlt
jmp os_read_input
.key_pressed:
mov ah, 10h
int 16h
ret
.key_pressed:
mov ah, 10h
int 16h
ret
; -------------------------------------------
@@ -18,60 +18,73 @@ os_display_input:
pusha
mov cx, [prompt_length]
.loop:
call .check_key_pressed
.loop:
call .check_key_pressed
jmp .loop
jmp .loop
.check_key_pressed:
call os_read_input
.check_key_pressed:
call os_read_input
cmp al, 08h
je .backspace
cmp al, 08h
je .backspace
cmp al, 0Dh
je .enter_key
cmp al, 0Dh
je .enter_key
cmp al, 1Bh
je .esc_key
cmp al, 1Bh
je .esc_key
cmp cx, 0
jb .check_key_pressed
cmp cx, 0
jb .check_key_pressed
call .print_current_input
dec cx
jmp .check_key_pressed
call .print_current_input
dec cx
jmp .check_key_pressed
.esc_key:
call power_reboot
.esc_key:
call power_reboot
.enter_key:
mov al, 0
stosb
popa
call os_read_cli
.enter_key:
mov al, 0
stosb
popa
call os_read_cli
.backspace:
call .move_cursor_back ; then .move_cursor_back
call .loop ; Else .loop
.backspace:
call .move_cursor_back ; then .move_cursor_back
call .loop ; Else .loop
.move_cursor_back:
mov ah, 0Eh
.move_cursor_back:
mov ah, 0Eh
mov al, 08h
int 10h
mov al, 20h
int 10h
mov al, 08h
int 10h
mov al, 08h
int 10h
mov al, 20h
int 10h
mov al, 08h
int 10h
dec di
jmp os_display_input
dec di
jmp os_display_input
.print_current_input:
stosb
.print_current_input:
stosb
mov ah, 0Eh
int 10h
mov ah, 0Eh
int 10h
ret
keyboard_get_cursor_pos: ;TODO
ret
keyboard_wait_for_key: ;TODO
ret
keyboard_show_cursor:
ret
keyboard_hide_cursor:
ret
keyboard_move_cursor:
ret
keyboard_check_key:
ret

View File

@@ -52,3 +52,5 @@ math_lba_to_chs:
pop ax
ret
math_get_random:
ret

View File

@@ -0,0 +1,4 @@
misc_pause:
ret
misc_get_api_version:
ret

View File

@@ -0,0 +1,10 @@
port_byte_out:
ret
port_byte_in:
ret
port_serial_enable:
ret
port_send_via_serial:
ret
port_get_via_serial:
ret

View File

@@ -0,0 +1,4 @@
sound_speaker_tone:
ret
sound_speaker_off:
ret

View File

@@ -11,35 +11,176 @@
os_compare_strings:
cld
.compare:
mov al, 0
scasb
je .di_ended
dec di
lodsb
scasb ; Compare di to si
jne .unequal ; If they are not equal, jump to .unequal
jmp .compare ; Finally, repeat
.compare:
mov al, 0
scasb
je .di_ended
dec di
lodsb
scasb ; Compare di to si
jne .unequal ; If they are not equal, jump to .unequal
jmp .compare ; Finally, repeat
.unequal:
mov cl, 0 ; Change to 0 if unquality is proven
ret
.di_ended:
lodsb
cmp al, 20h ; 20h = space
je .equal
cmp al, 0
je .equal
jmp .unequal
.equal:
mov cl, 1
.unequal:
mov cl, 0 ; Change to 0 if unquality is proven
ret
.di_ended:
lodsb
cmp al, 20h ; 20h = space
je .equal
cmp al, 0
je .equal
jmp .unequal
.equal:
mov cl, 1
ret
; ------------------------------------------------------------------
; os_string_compare -- See if two strings match
; IN: SI = string one, DI = string two
; OUT: carry set if same, clear if different
; from MikeOS kernel
string_direct_compare:
pusha
.more:
mov al, [si] ; Retrieve string contents
mov bl, [di]
cmp al, bl ; Compare characters at current location
jne .not_same
cmp al, 0 ; End of first string? Must also be end of second
je .end
inc si
inc di
jmp .more
.not_same: ; If unequal lengths with same beginning, the byte
popa ; comparison fails at shortest string terminator
clc ; Clear carry flag
ret
.end: ; Both strings terminated at the same position
popa
stc ; Set carry flag
ret
; --------------------------------------------------------------------
; Copies a string from si to di
; IN:
; si: points to first character of source string
; OUT:
; di: points to first character of destination string
string_copy:
pusha
.loop:
; TODO could this cause issue when a character is > 1 byte?
lodsb ; Load si character into ax and increment si by 1
stosb ; Store ax in di location and increment di by 1
cmp ax, 0 ; if ax is a 0, quit
jne .loop
.done:
popa
ret
; --------------------------------------------------------------------
; Joins two strings together into a new string
; IN/OUT:
; ax: string1
; bx: string2
; cx: result string
string_join:
pusha
.copy_string1:
mov si, ax
mov di, cx
call string_copy
mov ax, cx ; TODO check this bit
call string_length
add cx, ax
.copy_string2:
mov si, bx
mov di, dx
call string_copy
.done:
popa
ret
; ------------------------------------------------------------------------
; TODO
string_cast_to_int:
ret
; ------------------------------------------------------------------------
; IN: AX = int
; OUT: AX = string location (output buffer)
string_cast_from_int: ; TODO I think this algorithm could be optimised
pusha
; Initialise base to decimal (base 10)
mov bx, 10
; clear the strigified int location
mov cx, 6
push ax
xor ax,ax
.clear_loop:
stosb
dec cx
cmp cx, 0
ja .clear_loop
; setup
pop ax
push ax
mov cx, -1
; loop over number to get the value of count (cx)
.count_loop:
xor dx,dx
div bx ; ax = ax // bx
inc cx
cmp ax, 0
ja .count_loop ; Jump if greater
pop ax
; loop over count downwards until count is 0
mov di, stringified_int
.stringify_loop:
mov cx,1 ;DEL
push cx
push bx
push ax
; Generate power of 10
mov ax, 1
mov cx,0 ;DEL
cmp cx, 1
jl .after_power_loop
.power_loop:
mul bx
dec cx
cmp cx, 0
ja .power_loop
.after_power_loop:
mov bx,ax
pop ax
pop cx
; ax = ax DIV bx
; dx = ax MOD bx
xor dx,dx
div bx
pop bx
add ax, 30h
stosb
mov ax, dx
dec cx
cmp cx, 0
ja .stringify_loop
.finish:
popa
;mov ax, stringified_int
ret
; Get the length of a string
; 'hello world', 0 is 11 characters long (excluding the terminator)
; input: si points to the string to be counted
; output: cl holds the length
os_string_length:
string_length:
push si
xor cl,cl ; Clear the al register
.loop:
@@ -52,6 +193,8 @@ os_string_length:
pop si
ret
; convert a string to fat's filename format
; It will be capitalised and 11 characters long,
; 8 for the filename, 3 for the extension
@@ -60,8 +203,8 @@ os_string_length:
; output: di points to the fat formatted filename
os_format_fat_filename:
pusha
call os_upper_case
call os_string_length ; Stores the length of the string in cl
call string_upper_case
call string_length ; Stores the length of the string in cl
xor ch,ch ; Clear ch to reset it to 0
.character_loop:
lodsb
@@ -147,7 +290,7 @@ string_unformat_fat_filename:
; Convert a string to all upper/lower case
; INPUT: si pointing to a string
; OUPUT: the same string in memory will now be capitalised/decapitalised
os_upper_case: ; to upper case
string_upper_case: ; to upper case
pusha
mov di, si
.loop:
@@ -187,3 +330,9 @@ os_lower_case: ; to lower case
popa
ret
string_lower_case:
ret
string_input:
ret
string_print_2hex:
ret

View File

@@ -17,12 +17,30 @@ util_cat:
util_ls:
pusha
call disk_clear_output_buffer
call disk_load_root
call disk_list_contents
mov si, output_buffer
call os_print_string
call disk_clear_output_buffer
popa
ret
util_basic:
pusha
call disk_load_root
; TODO make this more consistent to account for double spaces
;add si, 3 ; Move si to after 'BAS'
call disk_load_file
mov si, file_buffer
mov ax, si
mov si, 0
call basic_run_basic
popa
ret

View File

@@ -10,8 +10,12 @@ start:
mov si, boot_message
call os_print_string
mov si, help_text
call os_print_string
; TESTING
;mov ax, 3
;call string_cast_from_int
;mov si, stringified_int
;call os_print_string
call os_start_cli
hlt
@@ -24,16 +28,18 @@ halt:
; FEATURES -- Code to pull into the kernel
%INCLUDE "source/kernel/features/text.asm"
%INCLUDE "source/kernel/features/keyboard.asm"
%INCLUDE "source/kernel/features/cli.asm"
%INCLUDE "source/kernel/features/ports.asm"
%INCLUDE "source/kernel/features/power.asm"
%INCLUDE "source/kernel/features/strings.asm"
%INCLUDE "source/kernel/features/graphics.asm"
%INCLUDE "source/kernel/features/sound.asm"
%INCLUDE "source/kernel/features/disk.asm"
%INCLUDE "source/kernel/features/math.asm"
%INCLUDE "source/kernel/features/time.asm"
%INCLUDE "source/kernel/features/utils.asm"
; GAMES -- Games that I wrote for it
%INCLUDE "source/kernel/games/pong.asm"
%INCLUDE "source/kernel/features/cli.asm"
%INCLUDE "source/kernel/features/misc.asm"
%INCLUDE "source/kernel/features/basic.asm"
; DATA/VARIABLES
%INCLUDE "source/kernel/data.asm"

View File