BASIC interpreter
This commit is contained in:
0
.gitignore
vendored
Executable file → Normal file
0
.gitignore
vendored
Executable file → Normal file
0
build-linux.sh
Executable file → Normal file
0
build-linux.sh
Executable file → Normal file
0
data/README.md
Executable file → Normal file
0
data/README.md
Executable file → Normal file
@@ -1,2 +1,4 @@
|
||||
PRINT "Hello World!"
|
||||
FOR A = 1 TO 10
|
||||
PRINT A
|
||||
NEXT A
|
||||
END
|
||||
|
||||
@@ -40,6 +40,7 @@ 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
|
||||
|
||||
int_tmp: dw 0
|
||||
; Disk operations
|
||||
disk_read_fail: db 'Error: Could not read disk\n', 0
|
||||
file_not_found: db 'File not found\n', 0
|
||||
@@ -59,3 +60,4 @@ read_write_flag: db 02
|
||||
empty_byte: db 0
|
||||
empty_word: dw 0
|
||||
empty_dword: dd 0
|
||||
tmp: db '97', 0
|
||||
|
||||
@@ -318,7 +318,6 @@ clear_ram:
|
||||
assign:
|
||||
cmp ax, VARIABLE ; Are we starting with a number var?
|
||||
je .do_num_var
|
||||
|
||||
mov di, string_vars ; Otherwise it's a string var
|
||||
mov ax, 128
|
||||
mul bx ; (BX = string number, passed back from get_token)
|
||||
|
||||
2
source/kernel/features/cli.asm
Executable file → Normal file
2
source/kernel/features/cli.asm
Executable file → Normal file
@@ -17,7 +17,7 @@ os_start_cli:
|
||||
|
||||
os_read_cli:
|
||||
pusha
|
||||
mov si, user_input
|
||||
mov ax, user_input
|
||||
call string_upper_case ; Make the input uppercase so it's case insensitive
|
||||
|
||||
.output_the_user_input:
|
||||
|
||||
@@ -308,6 +308,7 @@ disk_write_file:
|
||||
; OUT
|
||||
; output_buffer: the list (string)
|
||||
disk_list_contents:
|
||||
call disk_load_root
|
||||
pusha
|
||||
mov si, root_buffer
|
||||
mov di, output_buffer
|
||||
@@ -322,38 +323,22 @@ disk_list_contents:
|
||||
dec cx
|
||||
cmp cx, 0
|
||||
jne .space_loop
|
||||
|
||||
.file_attribute:
|
||||
add si, 11d
|
||||
lodsb
|
||||
mov ax, [si+28d]
|
||||
call string_cast_from_int
|
||||
push si
|
||||
|
||||
mov si, read_only
|
||||
cmp al, 1h
|
||||
je .add_string
|
||||
mov si, hidden
|
||||
cmp al, 2h
|
||||
je .add_string
|
||||
mov si, system
|
||||
cmp al, 4h
|
||||
je .add_string
|
||||
mov si, volume
|
||||
cmp al, 8h
|
||||
je .add_string
|
||||
mov si, directory
|
||||
cmp al, 10h
|
||||
je .add_string
|
||||
mov si, archive
|
||||
cmp al, 20h
|
||||
je .add_string
|
||||
|
||||
.after_file_attributes:
|
||||
mov si, stringified_int
|
||||
lodsb
|
||||
.output_file_size_loop:
|
||||
stosb
|
||||
lodsb
|
||||
cmp al, 0
|
||||
jne .output_file_size_loop
|
||||
.after_fs_loop:
|
||||
pop si
|
||||
|
||||
mov al, 0Ah
|
||||
stosb
|
||||
|
||||
add si, 20d
|
||||
add si, 20h
|
||||
lodsb ; +1
|
||||
dec si ; -1
|
||||
cmp al, 0 ; You've come to the end of the root entries
|
||||
@@ -361,13 +346,6 @@ disk_list_contents:
|
||||
cmp al, 00E5h ; E5h is a marker that the Fat entry is available
|
||||
je .finish
|
||||
jmp .loop
|
||||
.add_string:
|
||||
.add_string_loop:
|
||||
lodsb
|
||||
cmp ax, 00h
|
||||
je .after_file_attributes
|
||||
stosb
|
||||
jmp .add_string_loop
|
||||
.finish:
|
||||
mov cx, output_buffer
|
||||
sub di, cx
|
||||
|
||||
0
source/kernel/features/power.asm
Executable file → Normal file
0
source/kernel/features/power.asm
Executable file → Normal file
129
source/kernel/features/strings.asm
Executable file → Normal file
129
source/kernel/features/strings.asm
Executable file → Normal file
@@ -107,89 +107,84 @@ string_join:
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; TODO
|
||||
; Converts a null terminated string to an integer
|
||||
; IN: SI = string location (max 5 chars, up to '65536')
|
||||
; OUT: AX = number
|
||||
string_cast_to_int:
|
||||
pusha
|
||||
xor cx,cx
|
||||
.loop:
|
||||
xor ax,ax
|
||||
lodsb
|
||||
cmp al, 0
|
||||
je .finish
|
||||
sub al, 30h
|
||||
mov bx, ax
|
||||
mov ax, 10
|
||||
mul cx ; Multiple the current value by 10
|
||||
add ax, bx ; Then add the new digit
|
||||
mov cx, ax
|
||||
jmp .loop
|
||||
.finish:
|
||||
mov [int_tmp], cx
|
||||
popa
|
||||
mov ax, [int_tmp]
|
||||
ret
|
||||
|
||||
; ------------------------------------------------------------------------
|
||||
; IN: AX = integer (unsigned)
|
||||
; OUT: AX -> null-terminated string
|
||||
|
||||
; IN: AX = int
|
||||
; OUT: AX = string location (output buffer)
|
||||
string_cast_from_int: ; TODO I think this algorithm could be optimised
|
||||
string_cast_from_int:
|
||||
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
|
||||
cld ; Write backwards
|
||||
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
|
||||
|
||||
mov bx, 10 ; base
|
||||
mov cx, 0 ; digit count
|
||||
|
||||
.convert_loop:
|
||||
xor dx, dx
|
||||
div bx
|
||||
pop bx
|
||||
add ax, 30h
|
||||
div bx ; AX = AX / base, DX = remainder
|
||||
add dl, '0'
|
||||
push dx ; store digit
|
||||
inc cx
|
||||
test ax, ax
|
||||
jnz .convert_loop
|
||||
|
||||
.write_loop:
|
||||
pop ax
|
||||
stosb
|
||||
mov ax, dx
|
||||
dec cx
|
||||
cmp cx, 0
|
||||
ja .stringify_loop
|
||||
.finish:
|
||||
loop .write_loop
|
||||
|
||||
mov al, 0
|
||||
stosb ; null terminator
|
||||
|
||||
popa
|
||||
;mov ax, stringified_int
|
||||
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
|
||||
; input: ax points to the string to be counted
|
||||
; output: ax holds the length
|
||||
string_length:
|
||||
push si
|
||||
xor cl,cl ; Clear the al register
|
||||
push cx
|
||||
mov si, ax
|
||||
xor ax,ax ; Clear the cx register
|
||||
xor cx,cx
|
||||
.loop:
|
||||
lodsb
|
||||
cmp al, 0
|
||||
je .finish
|
||||
inc cl
|
||||
inc cx
|
||||
jmp .loop
|
||||
.finish:
|
||||
mov ax, cx
|
||||
pop cx
|
||||
pop si
|
||||
ret
|
||||
|
||||
@@ -204,7 +199,9 @@ string_length:
|
||||
os_format_fat_filename:
|
||||
pusha
|
||||
call string_upper_case
|
||||
mov ax, si
|
||||
call string_length ; Stores the length of the string in cl
|
||||
mov cl, al
|
||||
xor ch,ch ; Clear ch to reset it to 0
|
||||
.character_loop:
|
||||
lodsb
|
||||
@@ -287,11 +284,14 @@ string_unformat_fat_filename:
|
||||
popa
|
||||
ret
|
||||
|
||||
; -------------------------------------------------------------------------------------
|
||||
|
||||
; Convert a string to all upper/lower case
|
||||
; INPUT: si pointing to a string
|
||||
; INPUT: ax pointing to a string
|
||||
; OUPUT: the same string in memory will now be capitalised/decapitalised
|
||||
string_upper_case: ; to upper case
|
||||
pusha
|
||||
mov si,ax
|
||||
mov di,si
|
||||
.loop:
|
||||
lodsb ; Load the character into al
|
||||
@@ -310,8 +310,9 @@ string_upper_case: ; to upper case
|
||||
popa
|
||||
ret
|
||||
|
||||
os_lower_case: ; to lower case
|
||||
string_lower_case: ; to lower case
|
||||
pusha
|
||||
mov si, ax
|
||||
mov di, si
|
||||
.loop:
|
||||
lodsb ; Load the character into al
|
||||
@@ -330,8 +331,6 @@ os_lower_case: ; to lower case
|
||||
popa
|
||||
ret
|
||||
|
||||
string_lower_case:
|
||||
ret
|
||||
string_input:
|
||||
ret
|
||||
string_print_2hex:
|
||||
|
||||
0
source/kernel/features/text.asm
Executable file → Normal file
0
source/kernel/features/text.asm
Executable file → Normal file
@@ -17,7 +17,6 @@ util_cat:
|
||||
util_ls:
|
||||
pusha
|
||||
|
||||
call disk_load_root
|
||||
call disk_list_contents
|
||||
|
||||
mov si, output_buffer
|
||||
|
||||
@@ -11,11 +11,9 @@ start:
|
||||
mov si, boot_message
|
||||
call os_print_string
|
||||
|
||||
; TESTING
|
||||
;mov ax, 3
|
||||
;call string_cast_from_int
|
||||
;mov si, stringified_int
|
||||
;call os_print_string
|
||||
mov si, tmp
|
||||
mov ah, 0Eh
|
||||
int 10h
|
||||
|
||||
call os_start_cli
|
||||
hlt
|
||||
|
||||
@@ -4,8 +4,8 @@ sudo make
|
||||
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\
|
||||
-m 8m\
|
||||
-object memory-backend-file,id=pc.ram,size=8m,mem-path=/dev/shm/qemu-ram,share=on\
|
||||
-machine memory-backend=pc.ram\
|
||||
-d in_asm,int -D ./detailed.log\
|
||||
$1 $2
|
||||
|
||||
Reference in New Issue
Block a user