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

1
.gitignore vendored
View File

@@ -1,3 +1,4 @@
*.swp
disk_images/*
tmp-loop/*
detailed.log

View File

@@ -1,2 +1,3 @@
Kernel written in Assmebly<br/>
I'm using a modified JazzOS Bootloader<br/>
And the MikeOS BASIC Interpreter<br/>

2
data/hello.bas Normal file
View File

@@ -0,0 +1,2 @@
PRINT "Hello World!"
END

View File

@@ -1 +0,0 @@
output 'Hello World'

0
log.txt Normal file
View File

View File

@@ -10,7 +10,7 @@ bdb_bytes_per_sector: dw 200h ; = 512d
bdb_sectors_per_cluster: db 01h ; sector = cluster
bdb_reserved_sectors: dw 01h
bdb_fat_count: db 02h ; We've got a fat1 and fat2
bdb_dir_entries_count: dw 0E0h ; Maximum number of root directory entries
bdb_dir_entries_count: dw 0E0h ; = 224d Maximum number of root directory entries
bdb_total_sectors: dw 0B40h ; = 2880d
bdb_media_descriptor_type: db 0F0h ; ignore
bdb_sectors_per_fat: dw 09h
@@ -68,7 +68,7 @@ main:
shl ax,5 ; ax *= 32 (shifting 5 times)
xor dx,dx ; Clear dx (remainder)
div word [bdb_bytes_per_sector] ;(32*num of entries)/bytes per sector = total number of sectors we need to read
test dx,dx ; See if there's a remainder
test dx,dx ; See if there's a remainder, ie the root directory doesn't take up a whole number of sectors
jz root_dir_after
inc ax ; Add one if there's a remainder (this is like rounding up)

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

@@ -75,3 +75,16 @@ os_display_input:
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

@@ -35,11 +35,152 @@ os_compare_strings:
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

View File

@@ -5,5 +5,7 @@ sudo chown $(whoami) disk_images/*
qemu-system-i386\
-drive file=disk_images/crawos.img,if=floppy,format=raw\
-m 512m\
-object memory-backend-file,id=pc.ram,size=512m,mem-path=/dev/shm/qemu-ram,share=on -machine memory-backend=pc.ram\
-object memory-backend-file,id=pc.ram,size=512m,mem-path=/dev/shm/qemu-ram,share=on\
-machine memory-backend=pc.ram\
-d in_asm,int -D ./detailed.log\
$1 $2

0
to_implement Normal file
View File