Added support for \n, \t and \\ in the string printing function

This commit is contained in:
2025-11-01 12:38:02 +00:00
parent 015d4d1fce
commit 7906c48a2e
8 changed files with 125 additions and 85 deletions

View File

@@ -23,36 +23,29 @@ os_read_cli:
.check_matches: ; Check if the user input matches any internal commands .check_matches: ; Check if the user input matches any internal commands
; Help ; Help
mov di, user_input mov si, user_input
mov si, help_string mov di, help_string
call os_compare_strings call os_compare_strings
cmp cl, 1 cmp cl, 1
je help je help
; Clear screen ; Clear screen
mov di, user_input mov si, user_input
mov si, clear_string mov di, clear_string
call os_compare_strings call os_compare_strings
cmp cl, 1 cmp cl, 1
je clear je clear
; Reboot ; Reboot
mov di, user_input mov si, user_input
mov si, reboot_string mov di, reboot_string
call os_compare_strings call os_compare_strings
cmp cl, 1 cmp cl, 1
je os_reboot je power_reboot
; Reboot
mov di, user_input
mov si, cat_string
call os_compare_strings
cmp cl, 1
je cat
; Pong ; Pong
mov di, user_input mov si, user_input
mov si, pong_string mov di, pong_string
call os_compare_strings call os_compare_strings
cmp cl, 1 cmp cl, 1
je pong je pong
@@ -63,7 +56,7 @@ os_read_cli:
mov si, unknown_command mov si, unknown_command
call os_print_string call os_print_string
mov si, user_input mov si, user_input
call os_print_string_nl call os_print_string
jmp .finish jmp .finish
.finish: .finish:
@@ -76,11 +69,7 @@ clear:
help: help:
mov si, help_text mov si, help_text
call os_print_string_nl call os_print_string
call os_read_cli.finish
cat:
call util_cat
call os_read_cli.finish call os_read_cli.finish
pong: pong:
@@ -88,7 +77,7 @@ pong:
call os_read_cli.finish call os_read_cli.finish
section .data section .data
welcome_text db 'Welcome to CrawOS, the Cool, Real and AWsome Operating System', 0 welcome_text db 'Welcome to CrawOS, the Cwick, Real and AWsome Operating System\n', 0
user_input times 20 db 0 user_input times 20 db 0
prompt_length db 20 prompt_length db 20
prompt db 'CrawOS sh> ', 0 prompt db 'CrawOS sh> ', 0
@@ -97,6 +86,6 @@ section .data
reboot_string db 'REBOOT', 0 reboot_string db 'REBOOT', 0
cat_string db 'CAT', 0 cat_string db 'CAT', 0
pong_string db 'PONG', 0 pong_string db 'PONG', 0
help_text db 'This is for Cowards: "HELP" for this help text, "CLEAR" to clear the screen, esc or "REBOOT" to reboot', 0 help_text db 'This is for Cowards:\n"HELP" for this helpful text,\n"CLEAR" to clear the screen,\n"REBOOT" or esc to reboot\n', 0
command_result_text db 'You typed: ', 0 command_result_text db 'You typed: ', 0
unknown_command db 'Error: Unkown Command.. ', 0 unknown_command db 'Error: Unkown Command.. \n', 0

View File

@@ -43,7 +43,7 @@ os_display_input:
jmp .check_key_pressed jmp .check_key_pressed
.esc_key: .esc_key:
call os_reboot call power_reboot
.enter_key: .enter_key:
mov al, 0 mov al, 0

View File

@@ -0,0 +1,53 @@
; LBA = index of data segment on disk
; CHS = cylinder, header, sector
; T = LBA/sectors per track
; S = (LBA%sectors per track) + 1
; H = T % heads
; C = T / headers
; input, LBA index: ax
; sector number: cl
; cylinder: ch
; head: dh
; Example where LBA = 50h (CHS = 2,0,9)
; ax = 0050h, push this to the stack
; dx = 0000h
; dx = 50h % 12h = 0008h
; ax = 50h / 12h = 0004h
; dx = 0009h
; cx = 0009h
; dx = 0000h
; dx = 04h % 02h = 0000h
; ax = 04h / 02h = 0002h
; dh = 00h (dx = 0000h)
; ch = 02h (cx = 0209h)
; ah = 00h (ax = 0002h)
; cl = 09h OR 00h = 09h (cx = 0209h)
; ax = 0050h
; dl = 50h (dx = 0050h)
; ax = 0050h
; thus:
; cylinder (ch) = 02h
; head (cl) = 00h
; sector (dh) = 09h
os_lba_to_chs:
push ax
push dx
xor dx,dx ; clear dx
div word [bdb_sectors_per_track] ; (LBA % sectors per track) + 1 = sector
inc dx ; sector, dx stores the remainder so we increment that.
mov cx,dx
xor dx,dx ; clear dx
div word [bdb_number_of_heads]
mov dh,dl ; head, dx stores remainder so we move that up 8 bits to dh
mov ch,al
shl ah, 6 ; * 32
or cl, ah ; cylinder
pop ax
mov dl,al
pop ax
ret

View File

@@ -1,6 +1,9 @@
os_reboot: power_reboot:
mov ax, 0x5307 mov ax, 0x5307
mov bx, 0x0001 mov bx, 0x0001
mov cx, 0x0003 mov cx, 0x0003
int 0x19 int 0x19
; Not done
power_shutdown:
ret

View File

@@ -6,21 +6,31 @@
; memory address 2: |s|n|a|k|e|0| ; memory address 2: |s|n|a|k|e|0|
; ^ ; ^
; SI => lodsb loads value stored at SI to AX and then increments SI if DF is 0 ; SI => lodsb loads value stored at SI to AX and then increments SI if DF is 0
; Additionaly, if the di string ends and the relevant character in si contains a space, it will still return
; the strings as being equal, this is to allow for command line arquments
os_compare_strings: os_compare_strings:
cld cld
.compare: .compare:
mov al, 0
scasb
je .di_ended
dec di
lodsb lodsb
scasb ; Compare di to si scasb ; Compare di to si
jne .unequal ; If they are not equal, jump to .unequal jne .unequal ; If they are not equal, jump to .unequal
cmp al, 0 ; Check if string is finished
je .equal ; If it has, return true
jmp .compare ; Finally, repeat jmp .compare ; Finally, repeat
.unequal: .unequal:
mov cl, 0 ; Change to 0 if unquality is proven mov cl, 0 ; Change to 0 if unquality is proven
ret ret
.di_ended:
lodsb
cmp al, 20h ; 20h = space
je .equal
cmp al, 0
je .equal
jmp .unequal
.equal: .equal:
mov cl, 1 mov cl, 1
ret ret
@@ -32,13 +42,13 @@ os_compare_strings:
os_string_length: os_string_length:
push si push si
xor cl,cl ; Clear the al register xor cl,cl ; Clear the al register
.loop .loop:
lodsb lodsb
cmp al, 0 cmp al, 0
je .finish je .finish
inc cl inc cl
jmp .loop jmp .loop
.finish .finish:
pop si pop si
ret ret
@@ -78,7 +88,7 @@ os_format_fat_filename:
; Convert a string to all upper/lower case ; Convert a string to all upper/lower case
; INPUT: si pointing to a string ; INPUT: si pointing to a string
; OUPUT: the same string in memory will now be capitalised/decapitalised ; OUPUT: the same string in memory will now be capitalised/decapitalised
os_upper_case: os_upper_case: ; to upper case
pusha pusha
mov di, si mov di, si
.loop: .loop:
@@ -98,7 +108,7 @@ os_upper_case:
popa popa
ret ret
os_lower_case: os_lower_case: ; to lower case
pusha pusha
mov di, si mov di, si
.loop: .loop:

View File

@@ -1,4 +1,7 @@
; SI = pointer to start of string to be printed ; SI = pointer to start of string to be printed
; \n for newline
; \t for tab
; \\ for a single backslash
os_print_string: os_print_string:
pusha pusha
@@ -8,34 +11,43 @@ os_print_string:
lodsb ; Get char from si into al lodsb ; Get char from si into al
cmp al, 0 ; Compare al to 0 cmp al, 0 ; Compare al to 0
je .done ; If char is zero, end of string je .done ; If char is zero, end of string
cmp al, 5Ch ; backslash
je .backslash
int 10h ; Otherwise, print it int 10h ; Otherwise, print it
jmp .repeat ; And move on to next char jmp .repeat ; And move on to next char
.backslash: ; If there is a '\', do what it says, \n for newline, \t for tab etc
lodsb
dec si
cmp al, 6Eh ; 'n'
je .newline
cmp al, 74h ; \t
je .tab
cmp al, 5Ch ; '\'
je .another_backslash
jmp .repeat
.newline:
mov al, 0Ah ; new line
int 10h
mov al, 0Dh ; carriage return
int 10h
jmp .finish_backslash
.tab:
mov al, 09h ; tab
int 10h
jmp .finish_backslash
.another_backslash: ; This just prints 1 backslash
mov al, 5Ch
int 10h
jmp .finish_backslash
.finish_backslash:
inc si
jmp .repeat
.done: .done:
popa popa
ret ret
; Exact same as the above procedure, but this adds a newline
; after priting, similar to the difference between Rust's print! and println!
os_print_string_nl:
pusha
mov ah, 0Eh ; int 10h teletype function, we're telling the BIOS we will print something
.repeat:
lodsb ; Get char from si into al
cmp al, 0 ; Compare al to 0
je .done ; If char is zero, end of string
int 10h ; Otherwise, print it
jmp .repeat ; And move on to next char
.done:
call os_print_newline
popa
ret
; -------------------------------------------- ; --------------------------------------------
os_print_newline: os_print_newline:

View File

@@ -1,18 +0,0 @@
; Outputs the contents of a file
util_cat:
pusha
call os_print_newline
mov si, cat_prompt
call os_print_string
mov ax, 11 ; length of input
mov di, user_input
popa
ret
section .data:
cat_prompt db 'Enter file name: ', 0

View File

@@ -3,17 +3,10 @@ BITS 16
start: start:
mov si, boot_message mov si, boot_message
call os_print_string_nl call os_print_string
mov si, help_text mov si, help_text
call os_print_string_nl call os_print_string
mov si, file_name
call os_print_string_nl
mov di, fat_file_name
call os_format_fat_filename
mov si, fat_file_name
call os_print_string_nl
call os_start_cli call os_start_cli
hlt hlt
@@ -21,9 +14,7 @@ start:
halt: halt:
jmp halt jmp halt
boot_message: db 'OK] Kernel successfully loaded!', 0 boot_message: db 'OK] Kernel successfully loaded!\n', 0
file_name: db 'hello.cws', 0
fat_file_name: db ' ',0 ; 11 characters
; ------------------------------------------------------------------ ; ------------------------------------------------------------------
; FEATURES -- Code to pull into the kernel ; FEATURES -- Code to pull into the kernel
@@ -33,6 +24,6 @@ fat_file_name: db ' ',0 ; 11 characters
%INCLUDE "source/kernel/features/power.asm" %INCLUDE "source/kernel/features/power.asm"
%INCLUDE "source/kernel/features/strings.asm" %INCLUDE "source/kernel/features/strings.asm"
%INCLUDE "source/kernel/features/graphics.asm" %INCLUDE "source/kernel/features/graphics.asm"
%INCLUDE "source/kernel/features/utils.asm" %INCLUDE "source/kernel/features/disk.asm"
; GAMES -- Games that I wrote for it ; GAMES -- Games that I wrote for it
%INCLUDE "source/kernel/games/pong.asm" %INCLUDE "source/kernel/games/pong.asm"