Disk reading partly done
This commit is contained in:
BIN
.Makefile.swo
Normal file
BIN
.Makefile.swo
Normal file
Binary file not shown.
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
*.swp
|
*.swp
|
||||||
disk_images/*
|
disk_images/*
|
||||||
|
tmp-loop/*
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ ebr_drive_number: db 0 ; ignore
|
|||||||
ebr_signature: db 29h ; boot signature, indicates that the next three fields are present (0x29)
|
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_id: db 12h, 34h, 56h, 78h ; unique id for volume tracking
|
||||||
ebr_volume_label: db 'CrawShaw OS' ; must be 11 bytes
|
ebr_volume_label: db 'CrawShaw OS' ; must be 11 bytes
|
||||||
ebr_system_id: db 'FAT12 ' ' ; must be 8 bytes
|
ebr_system_id: db 'FAT12 ' ; must be 8 bytes
|
||||||
|
|
||||||
main:
|
main:
|
||||||
; Setup registers
|
; Setup registers
|
||||||
@@ -117,6 +117,7 @@ found_kernel:
|
|||||||
mov ax, [di+26] ; di is the address of the kernel, 26 is the offset
|
mov ax, [di+26] ; di is the address of the kernel, 26 is the offset
|
||||||
mov [kernel_cluster], ax
|
mov [kernel_cluster], ax
|
||||||
|
|
||||||
|
; Setup registers for disk read
|
||||||
mov ax, [bdb_reserved_sectors]
|
mov ax, [bdb_reserved_sectors]
|
||||||
mov bx, buffer
|
mov bx, buffer
|
||||||
mov cl, [bdb_sectors_per_fat]
|
mov cl, [bdb_sectors_per_fat]
|
||||||
@@ -334,7 +335,7 @@ print_string:
|
|||||||
pop si
|
pop si
|
||||||
ret
|
ret
|
||||||
|
|
||||||
boot_text: db 'OK] Boot sequence begun', 0
|
boot_text: db 'OK] Boot begun', 0
|
||||||
kernel_found_text: db 'OK] Kernel located', 0
|
kernel_found_text: db 'OK] Kernel located', 0
|
||||||
kernel_loading: db 'OK] Loading kernel', 0
|
kernel_loading: db 'OK] Loading kernel', 0
|
||||||
disk_read_fail: db 'ERR] Disk read fail', 0
|
disk_read_fail: db 'ERR] Disk read fail', 0
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ os_start_cli:
|
|||||||
|
|
||||||
os_read_cli:
|
os_read_cli:
|
||||||
pusha
|
pusha
|
||||||
|
mov si, user_input
|
||||||
|
call os_upper_case ; Make the input uppercase so it's case insensitive
|
||||||
|
|
||||||
.output_the_user_input:
|
.output_the_user_input:
|
||||||
call os_print_newline
|
call os_print_newline
|
||||||
|
|||||||
@@ -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 ' '
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
; H = T % heads
|
; H = T % heads
|
||||||
; C = T / headers
|
; C = T / headers
|
||||||
; input, LBA index: ax
|
; input, LBA index: ax
|
||||||
|
; ouput:
|
||||||
; sector number: cl
|
; sector number: cl
|
||||||
; cylinder: ch
|
; cylinder: ch
|
||||||
; head: dh
|
; head: dh
|
||||||
@@ -29,7 +30,7 @@
|
|||||||
; cylinder (ch) = 02h
|
; cylinder (ch) = 02h
|
||||||
; head (cl) = 00h
|
; head (cl) = 00h
|
||||||
; sector (dh) = 09h
|
; sector (dh) = 09h
|
||||||
os_lba_to_chs:
|
math_lba_to_chs:
|
||||||
push ax
|
push ax
|
||||||
push dx
|
push dx
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,31 @@ os_print_string:
|
|||||||
popa
|
popa
|
||||||
ret
|
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:
|
os_print_newline:
|
||||||
|
|||||||
@@ -48,24 +48,24 @@ game_pong:
|
|||||||
mov dx, [p1_y]
|
mov dx, [p1_y]
|
||||||
sub dx, 5
|
sub dx, 5
|
||||||
mov [p1_y], dx
|
mov [p1_y], dx
|
||||||
jmp .detect_input
|
ret
|
||||||
.p1_down:
|
.p1_down:
|
||||||
mov dx, [p1_y]
|
mov dx, [p1_y]
|
||||||
add dx, 5
|
add dx, 5
|
||||||
mov [p1_y], dx
|
mov [p1_y], dx
|
||||||
jmp .detect_input
|
ret
|
||||||
|
|
||||||
; Player 2 movements
|
; Player 2 movements
|
||||||
.p2_up:
|
.p2_up:
|
||||||
mov dx, [p2_y]
|
mov dx, [p2_y]
|
||||||
sub dx, 5
|
sub dx, 5
|
||||||
mov [p2_y], dx
|
mov [p2_y], dx
|
||||||
jmp .detect_input
|
ret
|
||||||
.p2_down:
|
.p2_down:
|
||||||
mov dx, [p2_y]
|
mov dx, [p2_y]
|
||||||
add dx, 5
|
add dx, 5
|
||||||
mov [p2_y], dx
|
mov [p2_y], dx
|
||||||
jmp .detect_input
|
ret
|
||||||
|
|
||||||
; Ball bouncing
|
; Ball bouncing
|
||||||
; This should move the ball along one frame
|
; This should move the ball along one frame
|
||||||
@@ -97,17 +97,17 @@ game_pong:
|
|||||||
|
|
||||||
; Player 1
|
; Player 1
|
||||||
cmp al, 77h ; Pressed 'w' (player 1 up)
|
cmp al, 77h ; Pressed 'w' (player 1 up)
|
||||||
je .p1_up
|
call .p1_up
|
||||||
cmp al, 73h ; Pressed 's' (player 1 down)
|
cmp al, 73h ; Pressed 's' (player 1 down)
|
||||||
je .p1_down
|
call .p1_down
|
||||||
|
|
||||||
; Player 2
|
; Player 2
|
||||||
cmp al, 5bh ; Pressed '[' (player 2 up)
|
cmp al, 5bh ; Pressed '[' (player 2 up)
|
||||||
je .p2_up
|
call .p2_up
|
||||||
cmp al, 27h ; Pressed ''' (player 2 down)
|
cmp al, 27h ; Pressed ''' (player 2 down)
|
||||||
je .p2_down
|
call .p2_down
|
||||||
|
|
||||||
call .bounce_ball
|
;call .bounce_ball
|
||||||
call .draw_screen
|
call .draw_screen
|
||||||
|
|
||||||
jmp .detect_input
|
jmp .detect_input
|
||||||
|
|||||||
@@ -1,12 +1,17 @@
|
|||||||
ORG 0h
|
ORG 00h
|
||||||
BITS 16
|
BITS 16
|
||||||
|
root_buffer equ 24000h
|
||||||
|
data_buffer equ 26000h
|
||||||
|
|
||||||
start:
|
start:
|
||||||
mov si, boot_message
|
mov si, boot_message
|
||||||
call os_print_string
|
call os_print_string
|
||||||
|
|
||||||
mov si, help_text
|
call disk_load_root ; Loads the root directory into disk_buffer
|
||||||
call os_print_string
|
|
||||||
|
; Physical address = (segment * 16) + offset
|
||||||
|
mov si, file_name
|
||||||
|
call disk_load_file
|
||||||
|
|
||||||
call os_start_cli
|
call os_start_cli
|
||||||
hlt
|
hlt
|
||||||
@@ -14,7 +19,31 @@ start:
|
|||||||
halt:
|
halt:
|
||||||
jmp 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
|
; 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/strings.asm"
|
||||||
%INCLUDE "source/kernel/features/graphics.asm"
|
%INCLUDE "source/kernel/features/graphics.asm"
|
||||||
%INCLUDE "source/kernel/features/disk.asm"
|
%INCLUDE "source/kernel/features/disk.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"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
make clean
|
||||||
# This script starts the QEMU PC emulator, booting from the
|
sudo make
|
||||||
# MikeOS floppy disk image
|
sudo chown $(whoami) disk_images/*
|
||||||
|
qemu-system-i386\
|
||||||
qemu-system-i386 -soundhw pcspk -drive format=raw,file=disk_images/mikeos.flp,index=0,if=floppy
|
-drive file=disk_images/crawos.img,if=floppy,format=raw\
|
||||||
|
-m 512m\
|
||||||
|
-object memory-backend-file,id=pc.ram,size=512m,mem-path=/dev/shm/qemu-ram,share=on -machine memory-backend=pc.ram\
|
||||||
|
$1 $2
|
||||||
|
|||||||
Reference in New Issue
Block a user