Disk reading partly done

This commit is contained in:
2025-11-17 20:46:21 +00:00
parent 7906c48a2e
commit 0222a7adb9
10 changed files with 261 additions and 21 deletions

View File

@@ -17,6 +17,8 @@ os_start_cli:
os_read_cli:
pusha
mov si, user_input
call os_upper_case ; Make the input uppercase so it's case insensitive
.output_the_user_input:
call os_print_newline

View File

@@ -0,0 +1,175 @@
; Reset the disk system using int 13h / AH = 00h
disk_reset:
pusha
stc
mov ah, 00h
int 13h
popa
ret
; ------------------------------------
; Load the root directory into memory (into disk_buffer which is 24000h)
disk_load_root:
pusha
mov ax, 19 ; First sector of root entry
call math_lba_to_chs ; Assigns ch, cl and dh the correct values
xor ax,ax
mov dl, [ebr_drive_number] ; Drive number
mov ah, 02h ; BIOS ah code for read disk sectors to memory
mov al, 0Ch ; Root directory has 12 sectors
mov si, root_buffer ; ES:BX should point to our buffer
mov bx, si
; 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
.try_read_disk: ; Try read the floppy three times
; 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 ; jump if cf = 0
call disk_reset ; Reset drivers of disk
dec di ; di -= 1
test di, di ; if di = 0
jnz .try_read_disk
jmp .disk_error
.disk_error:
mov si, disk_read_fail
call os_print_string
popa
ret
.done_read:
popa
ret
; ---------------------------------------------
; Reads a certain number of sectors into memory
; 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
push cx
push dx
push di
; cl = sector
; ch = cylinder
; dh = head
; dl = drive
call math_lba_to_chs ; Get the chs address
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:
; 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 ; jump if cf = 0
call .disk_reset ; Reset drivers of disk
dec di ; di -= 1
test di, di ; if di = 0
jnz .retry
.fail_disk_read:
pop di
pop dx
pop cx
pop bx
pop ax
ret
; int 13h / ah = 00h reset disk system
.disk_reset:
pusha
mov ah, 0 ; Reset drive
stc
int 13h
jc .fail_disk_read
popa
ret
.done_read:
pop di
pop dx
pop cx
pop bx
pop ax
ret
; -------------------------------------
disk_load_file:
pusha
mov di, fat12_file_name
call os_format_fat_filename
; Prepare values
mov si, root_buffer
xor bx,bx
.search_root:
mov di, fat12_file_name ; Move the name of the kernel into di
mov cx, 11 ; length of 'KERNEL BIN'
push si ; Preserve si
repe cmpsb ; Repeat a comparison of bytes between file name and current bytes until it finds a match
pop si ; Retrieve si
je .found_file
add si, 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_root ; Repeat search
jmp .file_not_found ; If the last dir has been searched, then there is no kernel
.found_file:
mov ax, [si+26] ; ax is now a pointer to the pointer to the file relative to the data segments :D
add ax, 20h
mov [file_cluster], ax
; Setup registers for disk read
mov bx, data_buffer
mov dl, [ebr_drive_number]
call disk_read ; Load file from disk into memory
jmp .done
.file_not_found:
mov si, file_not_found
call os_print_string
jmp .done
.done:
popa
ret
section .data:
disk_read_fail: db 'Error: Could not read disk\n', 0
file_not_found: db 'File not found\n', 0
file_found: db 'File found\n', 0
loading_root: db 'Loading root diretory\n', 0
file_cluster: dw 0
fat12_file_name: db ' '

View File

@@ -5,6 +5,7 @@
; H = T % heads
; C = T / headers
; input, LBA index: ax
; ouput:
; sector number: cl
; cylinder: ch
; head: dh
@@ -29,7 +30,7 @@
; cylinder (ch) = 02h
; head (cl) = 00h
; sector (dh) = 09h
os_lba_to_chs:
math_lba_to_chs:
push ax
push dx

View File

@@ -48,6 +48,31 @@ os_print_string:
popa
ret
; This is similar to the previous, however it prints
; raw output (including null) and prints the number
; of character defined by ax
; IN:
; SI = pointer to start of string to be printed
; AX = Length of string to print
text_raw_output:
pusha
mov di, ax
mov ah, 0Eh ; int 10h teletype function, we're telling the BIOS we will print something
.repeat:
lodsb ; Get char from si into al
int 10h ; Otherwise, print it
dec di
cmp di, 00h
je .done
jne .repeat
.done:
popa
ret
; --------------------------------------------
os_print_newline:

View File

@@ -48,24 +48,24 @@ game_pong:
mov dx, [p1_y]
sub dx, 5
mov [p1_y], dx
jmp .detect_input
ret
.p1_down:
mov dx, [p1_y]
add dx, 5
mov [p1_y], dx
jmp .detect_input
ret
; Player 2 movements
.p2_up:
mov dx, [p2_y]
sub dx, 5
mov [p2_y], dx
jmp .detect_input
ret
.p2_down:
mov dx, [p2_y]
add dx, 5
mov [p2_y], dx
jmp .detect_input
ret
; Ball bouncing
; This should move the ball along one frame
@@ -97,17 +97,17 @@ game_pong:
; Player 1
cmp al, 77h ; Pressed 'w' (player 1 up)
je .p1_up
call .p1_up
cmp al, 73h ; Pressed 's' (player 1 down)
je .p1_down
call .p1_down
; Player 2
cmp al, 5bh ; Pressed '[' (player 2 up)
je .p2_up
call .p2_up
cmp al, 27h ; Pressed ''' (player 2 down)
je .p2_down
call .p2_down
call .bounce_ball
;call .bounce_ball
call .draw_screen
jmp .detect_input

View File

@@ -1,12 +1,17 @@
ORG 0h
ORG 00h
BITS 16
root_buffer equ 24000h
data_buffer equ 26000h
start:
mov si, boot_message
call os_print_string
mov si, help_text
call os_print_string
call disk_load_root ; Loads the root directory into disk_buffer
; Physical address = (segment * 16) + offset
mov si, file_name
call disk_load_file
call os_start_cli
hlt
@@ -14,7 +19,31 @@ start:
halt:
jmp halt
boot_message: db 'OK] Kernel successfully loaded!\n', 0
boot_message: db 'OK] Kernel successfully loaded!\n\n', 0
file_name: db 'hello.cws', 0
; Define Fat12 header
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 ; 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
; ------------------------------------------------------------------
; FEATURES -- Code to pull into the kernel
@@ -25,5 +54,8 @@ boot_message: db 'OK] Kernel successfully loaded!\n', 0
%INCLUDE "source/kernel/features/strings.asm"
%INCLUDE "source/kernel/features/graphics.asm"
%INCLUDE "source/kernel/features/disk.asm"
%INCLUDE "source/kernel/features/math.asm"
; GAMES -- Games that I wrote for it
%INCLUDE "source/kernel/games/pong.asm"