Added a os_upper_case function
This commit is contained in:
4
Makefile
4
Makefile
@@ -9,6 +9,8 @@ cdrom: $(BUILD_DIR)/crawos.iso
|
||||
$(BUILD_DIR)/crawos.iso: floppy_image
|
||||
mkdir -p 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
|
||||
# Fat12
|
||||
@@ -36,4 +38,4 @@ $(BUILD_DIR)/kernel.bin:
|
||||
|
||||
# Clean
|
||||
clean:
|
||||
rm -f disk-images/*
|
||||
rm -f disk_images/*
|
||||
|
||||
@@ -5,27 +5,27 @@ jmp short main
|
||||
nop
|
||||
|
||||
; Define Fat12 header
|
||||
bdb_oem: db 'MSWIN4.1'
|
||||
bdb_bytes_per_sector: dw 512
|
||||
bdb_sectors_per_cluster: db 1
|
||||
bdb_reserved_sectors: dw 1
|
||||
bdb_fat_count: db 2
|
||||
bdb_dir_entries_count: dw 0E0h
|
||||
bdb_total_sectors: dw 2880
|
||||
bdb_media_descriptor_type: db 0F0h
|
||||
bdb_sectors_per_fat: dw 9
|
||||
bdb_sectors_per_track: dw 18
|
||||
bdb_heads: dw 2
|
||||
bdb_hidden_sectors: dd 0
|
||||
bdb_large_sector_count: dd 0
|
||||
bdb_oem: db 'MSWIN4.1' ; ignore
|
||||
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_total_sectors: dw 0B40h ; = 2880d
|
||||
bdb_media_descriptor_type: db 0F0h ; ignore
|
||||
bdb_sectors_per_fat: dw 09h
|
||||
bdb_sectors_per_track: dw 12h ; = 18d
|
||||
bdb_number_of_heads: dw 02h ; top and bottom of the floppy disk
|
||||
bdb_hidden_sectors: dd 0 ; ignore
|
||||
bdb_large_sector_count: dd 0 ; total sector count for fat32 (0 for fat12 or fat16)
|
||||
|
||||
; extended boot record
|
||||
ebr_drive_number: db 0
|
||||
db 0
|
||||
ebr_signature: db 29h
|
||||
ebr_volume_id: db 12h, 34h, 56h, 78h
|
||||
ebr_volume_label: db 'CrawShaw OS'
|
||||
ebr_system_id: db 'FAT12 '
|
||||
ebr_drive_number: db 0 ; ignore
|
||||
db 0 ; ignore
|
||||
ebr_signature: db 29h ; boot signature, indicates that the next three fields are present (0x29)
|
||||
ebr_volume_id: db 12h, 34h, 56h, 78h ; unique id for volume tracking
|
||||
ebr_volume_label: db 'CrawShaw OS' ; must be 11 bytes
|
||||
ebr_system_id: db 'FAT12 ' ' ; must be 8 bytes
|
||||
|
||||
main:
|
||||
; Setup registers
|
||||
@@ -54,46 +54,54 @@ main:
|
||||
; root dir: gives location of data
|
||||
; data: stores the actual data
|
||||
|
||||
; Get LBA of root dir
|
||||
mov ax, [bdb_sectors_per_fat]
|
||||
mov bl, [bdb_fat_count]
|
||||
; Get LBA of root dir (sectors per fat * fat count) + number of reserved sectors
|
||||
mov ax, [bdb_sectors_per_fat] ; ax = 09h
|
||||
mov bl, [bdb_fat_count] ; bl = 02h
|
||||
xor bh,bh ; clear bh
|
||||
mul bx ; 9 * 2 = 18
|
||||
add ax, [bdb_reserved_sectors] ; The LBA of root dir
|
||||
mul bx ; ax*bx = sectors per fat * fat count = 09h * 02h = 18
|
||||
add ax, [bdb_reserved_sectors] ; then add on the reserved sector (1) = The LBA of root dir = 19d = 13h
|
||||
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)
|
||||
xor dx,dx ; Clear dx
|
||||
div word [bdb_bytes_per_sector] ;32*num of entries)/bytes per sector
|
||||
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
|
||||
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:
|
||||
; read the data from the root directory from disk
|
||||
mov cl, al
|
||||
pop ax ; LBA of root dir
|
||||
mov dl, [ebr_drive_number]
|
||||
mov bx, buffer
|
||||
call disk_read
|
||||
call disk_read ; convert the LBA of the root directory to a CHS
|
||||
|
||||
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:
|
||||
mov si, file_kernel_bin ; Move the name of the kernel into si
|
||||
mov cx, 11
|
||||
mov si, file_kernel_bin ; Move the name of the kernel into si (string pointer)
|
||||
mov cx, 11 ; length of 'KERNEL BIN'
|
||||
push di ; Preserve di
|
||||
repe cmpsb ; Repeat a comparison of bytes between kernel name and current bytes until it finds a match
|
||||
pop di ; Retrieve di
|
||||
je found_kernel
|
||||
|
||||
add di, 32 ; Next directory entry
|
||||
add di, 32 ; increment di to the next directory entry
|
||||
inc bx
|
||||
cmp bx, [bdb_dir_entries_count] ; Have we reached the number of directories that exist
|
||||
jl search_for_kernel ; Repeat search
|
||||
|
||||
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:
|
||||
mov si, kernel_load_error
|
||||
call print_string
|
||||
@@ -101,11 +109,12 @@ kernel_not_found:
|
||||
hlt
|
||||
jmp halt
|
||||
|
||||
; The kernel has been found
|
||||
found_kernel:
|
||||
mov si, kernel_found_text
|
||||
call print_string
|
||||
; 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 ax, [bdb_reserved_sectors]
|
||||
@@ -160,6 +169,8 @@ next_cluster_after:
|
||||
jmp load_kernel_loop
|
||||
|
||||
read_finish: ; Load kernel
|
||||
mov si, kernel_loading
|
||||
call print_string
|
||||
mov dl, [ebr_drive_number]
|
||||
mov ax, kernel_load_segment
|
||||
mov ds, ax
|
||||
@@ -174,10 +185,35 @@ halt:
|
||||
|
||||
; 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: cx [0-5]
|
||||
; cylinder: cx [6-15]
|
||||
; 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
|
||||
lba_to_chs:
|
||||
push ax
|
||||
push dx
|
||||
@@ -188,19 +224,26 @@ lba_to_chs:
|
||||
mov cx,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
|
||||
shl ah, 6
|
||||
or CL, AH ; cylinder
|
||||
shl ah, 6 ; * 32
|
||||
or cl, ah ; cylinder
|
||||
|
||||
pop ax
|
||||
mov dl,al
|
||||
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:
|
||||
push ax
|
||||
push bx
|
||||
@@ -209,22 +252,32 @@ disk_read:
|
||||
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)
|
||||
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:
|
||||
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
|
||||
jnc done_read
|
||||
jnc done_read ; jump if cf = 0
|
||||
|
||||
call disk_reset ; Reset drivers of disk
|
||||
|
||||
dec di
|
||||
test di, di
|
||||
dec di ; di -= 1
|
||||
test di, di ; if di = 0
|
||||
jnz retry
|
||||
|
||||
fail_disk_read:
|
||||
@@ -233,6 +286,7 @@ fail_disk_read:
|
||||
hlt
|
||||
jmp halt
|
||||
|
||||
; int 13h / ah = 00h reset disk system
|
||||
disk_reset:
|
||||
pusha
|
||||
mov ah, 0 ; Reset drive
|
||||
@@ -280,14 +334,15 @@ print_string:
|
||||
pop si
|
||||
ret
|
||||
|
||||
boot_text: db '[OK] Boot sequence begun...', 0
|
||||
kernel_found_text: db '[OK] Kernel located...', 0
|
||||
disk_read_fail: db '[ERR] Failed to read disk!', 0
|
||||
boot_text: db 'OK] Boot sequence begun', 0
|
||||
kernel_found_text: db 'OK] Kernel located', 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
|
||||
kernel_load_error: db '[ERR] Kernel not found!', 0
|
||||
kernel_load_error: db 'ERR] Kernel not found', 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
|
||||
|
||||
|
||||
|
||||
@@ -22,30 +22,41 @@ os_read_cli:
|
||||
call os_print_newline
|
||||
|
||||
.check_matches: ; Check if the user input matches any internal commands
|
||||
mov si, user_input
|
||||
mov di, help_string
|
||||
; Help
|
||||
mov di, user_input
|
||||
mov si, help_string
|
||||
call os_compare_strings
|
||||
cmp cl, 1
|
||||
je help
|
||||
|
||||
mov si, user_input
|
||||
mov di, clear_string
|
||||
; Clear screen
|
||||
mov di, user_input
|
||||
mov si, clear_string
|
||||
call os_compare_strings
|
||||
cmp cl, 1
|
||||
je clear
|
||||
|
||||
mov si, user_input
|
||||
mov di, pong_string
|
||||
; Reboot
|
||||
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
|
||||
cmp cl, 1
|
||||
je pong
|
||||
|
||||
mov si, user_input
|
||||
mov di, snake_string
|
||||
call os_compare_strings
|
||||
cmp cl, 1
|
||||
je snake
|
||||
|
||||
jmp .unkown
|
||||
|
||||
.unkown:
|
||||
@@ -68,12 +79,12 @@ help:
|
||||
call os_print_string_nl
|
||||
call os_read_cli.finish
|
||||
|
||||
pong:
|
||||
call game_pong
|
||||
cat:
|
||||
call util_cat
|
||||
call os_read_cli.finish
|
||||
|
||||
snake:
|
||||
call game_snake
|
||||
pong:
|
||||
call game_pong
|
||||
call os_read_cli.finish
|
||||
|
||||
section .data
|
||||
@@ -83,8 +94,9 @@ section .data
|
||||
prompt db 'CrawOS sh> ', 0
|
||||
help_string db 'HELP', 0
|
||||
clear_string db 'CLEAR', 0
|
||||
reboot_string db 'REBOOT', 0
|
||||
cat_string db 'CAT', 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 to reboot', 0
|
||||
help_text db 'This is for Cowards: "HELP" for this help text, "CLEAR" to clear the screen, esc or "REBOOT" to reboot', 0
|
||||
command_result_text db 'You typed: ', 0
|
||||
unknown_command db 'Error: Unkown Command.. ', 0
|
||||
|
||||
@@ -12,7 +12,7 @@ os_compare_strings:
|
||||
.compare:
|
||||
lodsb
|
||||
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
|
||||
je .equal ; If it has, return true
|
||||
jmp .compare ; Finally, repeat
|
||||
@@ -24,3 +24,26 @@ os_compare_strings:
|
||||
.equal:
|
||||
mov cl, 1
|
||||
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
|
||||
|
||||
|
||||
18
source/kernel/features/utils.asm
Normal file
18
source/kernel/features/utils.asm
Normal 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
|
||||
@@ -2,6 +2,8 @@ ORG 0h
|
||||
BITS 16
|
||||
|
||||
start:
|
||||
mov si, boot_message
|
||||
call os_upper_case
|
||||
mov si, boot_message
|
||||
call os_print_string_nl
|
||||
|
||||
@@ -14,7 +16,7 @@ start:
|
||||
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
|
||||
@@ -24,9 +26,7 @@ boot_message: db 0Dh, 'Welcome to CrawOS!', 0Dh, 0
|
||||
%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/basic.asm"
|
||||
%INCLUDE "source/kernel/features/math.asm"
|
||||
%INCLUDE "source/kernel/features/utils.asm"
|
||||
; GAMES -- Games that I wrote for it
|
||||
%INCLUDE "source/kernel/games/pong.asm"
|
||||
%INCLUDE "source/kernel/games/snake.asm"
|
||||
|
||||
Reference in New Issue
Block a user