Added a os_upper_case function

This commit is contained in:
2025-10-30 22:57:31 +00:00
parent 0b9014d846
commit d83871e161
7 changed files with 193 additions and 83 deletions

View File

@@ -9,6 +9,8 @@ cdrom: $(BUILD_DIR)/crawos.iso
$(BUILD_DIR)/crawos.iso: floppy_image $(BUILD_DIR)/crawos.iso: floppy_image
mkdir -p disk_images mkdir -p disk_images
mkisofs -quiet -V 'CRAWOS' -input-charset iso8859-1 -o disk_images/crawos.iso -b crawos.img disk_images/ mkisofs -quiet -V 'CRAWOS' -input-charset iso8859-1 -o disk_images/crawos.iso -b crawos.img disk_images/
chmod 755 disk_images/*
chgrp users disk_images/*
# Floppy image # Floppy image
# Fat12 # Fat12
@@ -36,4 +38,4 @@ $(BUILD_DIR)/kernel.bin:
# Clean # Clean
clean: clean:
rm -f disk-images/* rm -f disk_images/*

View File

@@ -5,27 +5,27 @@ jmp short main
nop nop
; Define Fat12 header ; Define Fat12 header
bdb_oem: db 'MSWIN4.1' bdb_oem: db 'MSWIN4.1' ; ignore
bdb_bytes_per_sector: dw 512 bdb_bytes_per_sector: dw 200h ; = 512d
bdb_sectors_per_cluster: db 1 bdb_sectors_per_cluster: db 01h ; sector = cluster
bdb_reserved_sectors: dw 1 bdb_reserved_sectors: dw 01h
bdb_fat_count: db 2 bdb_fat_count: db 02h ; We've got a fat1 and fat2
bdb_dir_entries_count: dw 0E0h bdb_dir_entries_count: dw 0E0h ; Maximum number of root directory entries
bdb_total_sectors: dw 2880 bdb_total_sectors: dw 0B40h ; = 2880d
bdb_media_descriptor_type: db 0F0h bdb_media_descriptor_type: db 0F0h ; ignore
bdb_sectors_per_fat: dw 9 bdb_sectors_per_fat: dw 09h
bdb_sectors_per_track: dw 18 bdb_sectors_per_track: dw 12h ; = 18d
bdb_heads: dw 2 bdb_number_of_heads: dw 02h ; top and bottom of the floppy disk
bdb_hidden_sectors: dd 0 bdb_hidden_sectors: dd 0 ; ignore
bdb_large_sector_count: dd 0 bdb_large_sector_count: dd 0 ; total sector count for fat32 (0 for fat12 or fat16)
; extended boot record ; extended boot record
ebr_drive_number: db 0 ebr_drive_number: db 0 ; ignore
db 0 db 0 ; ignore
ebr_signature: db 29h ebr_signature: db 29h ; boot signature, indicates that the next three fields are present (0x29)
ebr_volume_id: db 12h, 34h, 56h, 78h ebr_volume_id: db 12h, 34h, 56h, 78h ; unique id for volume tracking
ebr_volume_label: db 'CrawShaw OS' ebr_volume_label: db 'CrawShaw OS' ; must be 11 bytes
ebr_system_id: db 'FAT12 ' ebr_system_id: db 'FAT12 ' ' ; must be 8 bytes
main: main:
; Setup registers ; Setup registers
@@ -37,11 +37,11 @@ main:
mov sp, 7C00h mov sp, 7C00h
; Read from disk ; Read from disk
;mov [ebr_drive_number], dl ; mov [ebr_drive_number], dl
;mov ax, 1 ; mov ax, 1
;mov cl, 1 ; mov cl, 1
;mov bx, 7E00h ; mov bx, 7E00h
;call disk_read ; call disk_read
; Output boot text ; Output boot text
mov si, boot_text mov si, boot_text
@@ -54,46 +54,54 @@ main:
; root dir: gives location of data ; root dir: gives location of data
; data: stores the actual data ; data: stores the actual data
; Get LBA of root dir ; Get LBA of root dir (sectors per fat * fat count) + number of reserved sectors
mov ax, [bdb_sectors_per_fat] mov ax, [bdb_sectors_per_fat] ; ax = 09h
mov bl, [bdb_fat_count] mov bl, [bdb_fat_count] ; bl = 02h
xor bh,bh ; clear bh xor bh,bh ; clear bh
mul bx ; 9 * 2 = 18 mul bx ; ax*bx = sectors per fat * fat count = 09h * 02h = 18
add ax, [bdb_reserved_sectors] ; The LBA of root dir add ax, [bdb_reserved_sectors] ; then add on the reserved sector (1) = The LBA of root dir = 19d = 13h
push ax ; Push to stack push ax ; Push to stack
; the top of the ax stack now stores the LBA of the root directory
mov ax, [bdb_dir_entries_count] ; determine the size of the root directory
mov ax, [bdb_dir_entries_count] ; move the number of root directory entries into ax (E0h)
shl ax,5 ; ax *= 32 (shifting 5 times) shl ax,5 ; ax *= 32 (shifting 5 times)
xor dx,dx ; Clear dx xor dx,dx ; Clear dx (remainder)
div word [bdb_bytes_per_sector] ;32*num of entries)/bytes per sector 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
jz root_dir_after jz root_dir_after
inc ax ; Add one if there's a remainder inc ax ; Add one if there's a remainder (this is like rounding up)
; read the root directory tree into memory
root_dir_after: root_dir_after:
; read the data from the root directory from disk
mov cl, al mov cl, al
pop ax ; LBA of root dir pop ax ; LBA of root dir
mov dl, [ebr_drive_number] mov dl, [ebr_drive_number]
mov bx, buffer mov bx, buffer
call disk_read call disk_read ; convert the LBA of the root directory to a CHS
xor bx,bx ; clear bx xor bx,bx ; clear bx
mov di, buffer ; Loaded root dir into memory mov di, buffer ; Loaded root dir into memory, now we need to find the kernel
; di points to the start of this memory
; Search for 'KERNEL BIN' in a loop until all root files entries have been checked
search_for_kernel: search_for_kernel:
mov si, file_kernel_bin ; Move the name of the kernel into si mov si, file_kernel_bin ; Move the name of the kernel into si (string pointer)
mov cx, 11 mov cx, 11 ; length of 'KERNEL BIN'
push di ; Preserve di push di ; Preserve di
repe cmpsb ; Repeat a comparison of bytes between kernel name and current bytes until it finds a match repe cmpsb ; Repeat a comparison of bytes between kernel name and current bytes until it finds a match
pop di ; Retrieve di pop di ; Retrieve di
je found_kernel je found_kernel
add di, 32 ; Next directory entry add di, 32 ; increment di to the next directory entry
inc bx inc bx
cmp bx, [bdb_dir_entries_count] ; Have we reached the number of directories that exist cmp bx, [bdb_dir_entries_count] ; Have we reached the number of directories that exist
jl search_for_kernel ; Repeat search jl search_for_kernel ; Repeat search
jmp kernel_not_found ; If the last dir has been searched, then there is no kernel jmp kernel_not_found ; If the last dir has been searched, then there is no kernel
; The kernel has not been found so output an error and halt
kernel_not_found: kernel_not_found:
mov si, kernel_load_error mov si, kernel_load_error
call print_string call print_string
@@ -101,11 +109,12 @@ kernel_not_found:
hlt hlt
jmp halt jmp halt
; The kernel has been found
found_kernel: found_kernel:
mov si, kernel_found_text mov si, kernel_found_text
call print_string call print_string
; Find kernel cluster ; Find kernel cluster
mov ax, [di+26] mov ax, [di+26] ; di is the address of the kernel, 26 is the offset
mov [kernel_cluster], ax mov [kernel_cluster], ax
mov ax, [bdb_reserved_sectors] mov ax, [bdb_reserved_sectors]
@@ -160,6 +169,8 @@ next_cluster_after:
jmp load_kernel_loop jmp load_kernel_loop
read_finish: ; Load kernel read_finish: ; Load kernel
mov si, kernel_loading
call print_string
mov dl, [ebr_drive_number] mov dl, [ebr_drive_number]
mov ax, kernel_load_segment mov ax, kernel_load_segment
mov ds, ax mov ds, ax
@@ -174,33 +185,65 @@ halt:
; LBA = index of data segment on disk ; LBA = index of data segment on disk
; CHS = cylinder, header, sector ; 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 ; input, LBA index: ax
; sector number: cx [0-5] ; sector number: cl
; cylinder: cx [6-15] ; cylinder: ch
; head: dh ; 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
lba_to_chs: lba_to_chs:
push ax push ax
push dx push dx
xor dx,dx ; clear dx xor dx,dx ; clear dx
div word [bdb_sectors_per_track] ;(LBA % sectors per track) + 1 = sector div word [bdb_sectors_per_track] ; (LBA % sectors per track) + 1 = sector
inc dx ; sector, dx stores the remainder so we increment that. inc dx ; sector, dx stores the remainder so we increment that.
mov cx,dx mov cx,dx
xor dx,dx ; clear dx xor dx,dx ; clear dx
div word [bdb_heads] div word [bdb_number_of_heads]
mov dh,dl ; head, dx stores remainder so we move that up 8 bits to dh
mov dh,dl ; head
mov ch,al mov ch,al
shl ah, 6 shl ah, 6 ; * 32
or CL, AH ; cylinder or cl, ah ; cylinder
pop ax pop ax
mov dl,al mov dl,al
pop ax pop ax
RET ret
; int 13h/ah = 02h read disk sectors into memory
; al = number of sectors to read
; ch = cylinder number
; cl = sector number
; dh = head number
; dl = drive number
; es:bx = points to data buffer
disk_read: disk_read:
push ax push ax
push bx push bx
@@ -209,22 +252,32 @@ disk_read:
push di push di
call lba_to_chs ; cl = sector
; ch = cylinder
; dh = head
; dl = drive
call lba_to_chs ; Get the chs address
mov ah, 02h mov ah, 02h ; BIOS ah code for read disk sectors to memory
; repeat drive read 3 times (incase of random error) ; repeat drive read 3 times (incase of random error)
mov di, 3 ; counter mov di, 3 ; counter
; This is basically
; for di in range(3,1,1):
; We test to see if we can read the disk 3 times
retry: retry:
stc ; When the disk is tried to be read, the CF flag will be
; set if there's an error, so we just clear it to return it to
; the default state
stc ; sets the cf flag
int 13h int 13h
jnc done_read jnc done_read ; jump if cf = 0
call disk_reset ; Reset drivers of disk call disk_reset ; Reset drivers of disk
dec di dec di ; di -= 1
test di, di test di, di ; if di = 0
jnz retry jnz retry
fail_disk_read: fail_disk_read:
@@ -233,6 +286,7 @@ fail_disk_read:
hlt hlt
jmp halt jmp halt
; int 13h / ah = 00h reset disk system
disk_reset: disk_reset:
pusha pusha
mov ah, 0 ; Reset drive mov ah, 0 ; Reset drive
@@ -280,14 +334,15 @@ print_string:
pop si pop si
ret ret
boot_text: db '[OK] Boot sequence begun...', 0 boot_text: db 'OK] Boot sequence begun', 0
kernel_found_text: db '[OK] Kernel located...', 0 kernel_found_text: db 'OK] Kernel located', 0
disk_read_fail: db '[ERR] Failed to read disk!', 0 kernel_loading: db 'OK] Loading kernel', 0
disk_read_fail: db 'ERR] Disk read fail', 0
file_kernel_bin: db 'KERNEL BIN' ; Must have a double space between KERNEL and BIN file_kernel_bin: db 'KERNEL BIN' ; Must have a double space between KERNEL and BIN
kernel_load_error: db '[ERR] Kernel not found!', 0 kernel_load_error: db 'ERR] Kernel not found', 0
kernel_cluster: dw 0 kernel_cluster: dw 0
kernel_load_segment: equ 2000h kernel_load_segment: equ 2000h ; an area in memory we know should be available
kernel_load_offset: equ 0 kernel_load_offset: equ 0

View File

@@ -22,30 +22,41 @@ os_read_cli:
call os_print_newline call os_print_newline
.check_matches: ; Check if the user input matches any internal commands .check_matches: ; Check if the user input matches any internal commands
mov si, user_input ; Help
mov di, help_string mov di, user_input
mov si, help_string
call os_compare_strings call os_compare_strings
cmp cl, 1 cmp cl, 1
je help je help
mov si, user_input ; Clear screen
mov di, clear_string mov di, user_input
mov si, clear_string
call os_compare_strings call os_compare_strings
cmp cl, 1 cmp cl, 1
je clear je clear
mov si, user_input ; Reboot
mov di, pong_string mov di, user_input
mov si, reboot_string
call os_compare_strings
cmp cl, 1
je os_reboot
; Reboot
mov di, user_input
mov si, cat_string
call os_compare_strings
cmp cl, 1
je cat
; Pong
mov di, user_input
mov si, pong_string
call os_compare_strings call os_compare_strings
cmp cl, 1 cmp cl, 1
je pong je pong
mov si, user_input
mov di, snake_string
call os_compare_strings
cmp cl, 1
je snake
jmp .unkown jmp .unkown
.unkown: .unkown:
@@ -68,14 +79,14 @@ help:
call os_print_string_nl call os_print_string_nl
call os_read_cli.finish call os_read_cli.finish
cat:
call util_cat
call os_read_cli.finish
pong: pong:
call game_pong call game_pong
call os_read_cli.finish call os_read_cli.finish
snake:
call game_snake
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 Cool, Real and AWsome Operating System', 0
user_input times 20 db 0 user_input times 20 db 0
@@ -83,8 +94,9 @@ section .data
prompt db 'CrawOS sh> ', 0 prompt db 'CrawOS sh> ', 0
help_string db 'HELP', 0 help_string db 'HELP', 0
clear_string db 'CLEAR', 0 clear_string db 'CLEAR', 0
reboot_string db 'REBOOT', 0
cat_string db 'CAT', 0
pong_string db 'PONG', 0 pong_string db 'PONG', 0
snake_string db 'SNAKE', 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: "HELP" for this help text, "CLEAR" to clear the screen, esc to reboot', 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.. ', 0

View File

@@ -12,7 +12,7 @@ os_compare_strings:
.compare: .compare:
lodsb lodsb
scasb ; Compare di to si scasb ; Compare di to si
jne .unequal ; If they are no equal, jump to .unequal jne .unequal ; If they are not equal, jump to .unequal
cmp al, 0 ; Check if string is finished cmp al, 0 ; Check if string is finished
je .equal ; If it has, return true je .equal ; If it has, return true
jmp .compare ; Finally, repeat jmp .compare ; Finally, repeat
@@ -24,3 +24,26 @@ os_compare_strings:
.equal: .equal:
mov cl, 1 mov cl, 1
ret ret
; Convert a string to all upper case
os_upper_case:
pusha
mov di, si
.loop:
lodsb
inc di
cmp al, 0
je .finish
cmp al, 7Ah
jns .loop
cmp al, 61h
js .loop
sub al, 20h
dec di
stosb
jmp .loop
.finish:
popa
ret

View File

@@ -0,0 +1,18 @@
; 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

@@ -2,6 +2,8 @@ ORG 0h
BITS 16 BITS 16
start: start:
mov si, boot_message
call os_upper_case
mov si, boot_message mov si, boot_message
call os_print_string_nl call os_print_string_nl
@@ -14,7 +16,7 @@ start:
halt: halt:
jmp halt jmp halt
boot_message: db 0Dh, 'Welcome to CrawOS!', 0Dh, 0 boot_message: db 'kernel successfully loaded!', 0
; ------------------------------------------------------------------ ; ------------------------------------------------------------------
; FEATURES -- Code to pull into the kernel ; FEATURES -- Code to pull into the kernel
@@ -24,9 +26,7 @@ boot_message: db 0Dh, 'Welcome to CrawOS!', 0Dh, 0
%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/sound.asm" %INCLUDE "source/kernel/features/utils.asm"
%INCLUDE "source/kernel/features/basic.asm"
%INCLUDE "source/kernel/features/math.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"
%INCLUDE "source/kernel/games/snake.asm" %INCLUDE "source/kernel/games/snake.asm"