BASIC Interpreter from MikeOS is functioning
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user