After C Switch

This commit is contained in:
2024-03-08 19:30:37 +01:00
parent 2f3b4f6e6b
commit 8062dc98af
15 changed files with 180 additions and 1470 deletions
+16 -21
View File
@@ -1,32 +1,27 @@
#!/bin/bash
# Create ./build dir if it doesn't exist
if !(test -d ./build); then
mkdir ./build
echo "Created ./build/ directory!"
fi
[[ -d ./build ]] || mkdir build
rm -rf ./build/**
# Bootloader
nasm -fbin src/boot.asm -o ./build/boot.bin
nasm -fbin src/filetable.asm -o ./build/filetable.bin
nasm -fbin ./src/boot.asm -o ./build/boot.bin
# Kernel
nasm -fbin src/kernel.asm -o ./build/kernel.bin
nasm -felf32 ./src/kernel/entry.asm -o ./build/entry.o
# Programs
nasm -fbin src/fs/calc.asm -o ./build/calc.bin
nasm -fbin src/fs/edit.asm -o ./build/edit.bin
for file in ./src/kernel/**.c; do
filename=$(basename "$file" .c)
i386-elf-gcc -ffreestanding -Wall -Wextra -m32 -c $file -o ./build/$filename.o
done
cat ./build/calc.bin ./build/edit.bin > ./build/files.bin
i386-elf-ld -o ./build/kernel.bin -Ttext 0x1000 --oformat binary ./build/**.o
# Final binary
cat ./build/boot.bin ./build/filetable.bin ./build/kernel.bin ./build/files.bin > ./build/temp.bin
dd if=/dev/zero of=./build/kern.iso bs=512 count=2880
dd if=./build/temp.bin of=./build/kern.iso conv=notrunc
rm -rf ./build/**.bin
echo "Built kern.iso!"
# OS Image
cat build/boot.bin build/kernel.bin > build/os.bin
dd if=/dev/zero of=./kern.iso bs=512 count=2880
dd if=./build/os.bin of=./kern.iso conv=notrunc
# Run QEMU
echo "Running QEMU..."
qemu-system-x86_64 -drive format=raw,file="./build/kern.iso",index=0,media=disk -m 256M
qemu-system-x86_64 -drive format=raw,file="./kern.iso",index=0,media=disk -m 256M -accel tcg
+119 -68
View File
@@ -1,98 +1,149 @@
[org 0x7c00]
[bits 16]
[org 0x7c00]
[global start]
%define KERNEL_LOC 0x1000
%define KERNEL_SIZE 20 ; 20 Sectors -> 10kB
%define ENDL 0x0a, 0x0d
%define VIDMEM 0xb800
start:
; Setup
mov [driveNum], dl ; Store the drive number
; Set up the stack
xor ax, ax
mov es, ax
mov ds, ax
mov bp, 0x7c00
mov sp, bp
; Save drive number
mov byte [driveNumber], dl
; Setup screen
mov ax, 3 ; 80x25 Text mode
int 0x10
mov ah, 1 ; Hide cursor
mov cx, 0x2607
int 0x10
; Print boot message
mov si, bootMsg
call print
mov dl, byte [driveNumber]
call printHex
mov si, newline
call print
mov byte [0xb800], 'A'
.read:
; Location
mov bx, KERNEL_LOC
; Read filetable from disk
mov bx, FILETAB_LOC ; Filetable location in memory
mov es, bx
xor bx, bx
; CHS Location
mov al, KERNEL_SIZE
mov ch, 0 ; Cylinder
mov dh, 0 ; Head
mov cl, 2 ; Sector
mov dl, [driveNum]
mov ah, 2 ; Read from disk
mov al, 1 ; Read 1 sector (512B)
mov ah, 2 ; Read from disk
int 0x13 ; Read interrupt
mov dl, byte [driveNumber] ; Drive number
mov ch, 0 ; Cylinder
mov dh, 0 ; Head
mov cl, 2 ; Sector
int 0x13 ; INT 0x13 - Disk operations
jc .diskErr
jc readFail ; CF will be set if the read fails
cli
lgdt [GDT_Descriptor]
; Enable protected mode
mov eax, cr0
or eax, 1
mov cr0, eax
; Read filetable from disk
mov bx, KERNEL_LOC ; Filetable location in memory
mov es, bx
xor bx, bx
; Far jump to 32 bit mode!!
jmp CODE_SEG:protected_start
mov ah, 2 ; Read from disk
mov al, 4 ; Read 4 sectors (2kB)
.diskErr:
dec byte [counter]
jnz .read
mov dl, byte [driveNumber] ; Drive number
mov ch, 0 ; Cylinder
mov dh, 0 ; Head
mov cl, 3 ; Sector
int 0x13 ; INT 0x13 - Disk operations
mov si, diskErrMsg
mov bl, 0x04
call puts
jc readFail ; CF will be set if the read fails
cli
hlt
; Setup segmentation
mov ax, KERNEL_LOC
mov ds, ax
;
; Prints a string
; si: char* - String to print
; bl: byte - Color attribute
;
puts:
push ax
push es
mov ax, VIDMEM
mov es, ax
mov word di, [cursor]
mov ah, bl
.loop:
lodsb ; mov al, [si]; inc si
cmp al, 0
je .done
mov [es:di], ax ; Really smart thing
add di, 2
jmp .loop
.done:
mov [cursor], di
pop es
pop ax
ret
;; Data
driveNum: db 3
counter: db 0
cursor: dw 0
; Strings
msg: db "Booting...", 0
diskErrMsg: db "Failed while reading from disk!", 0
;; 32 Bit entry code
[bits 32]
protected_start:
; Set up data and stack segments
mov ax, DATA_SEG
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
; Setup stack
mov bp, 0xffff
mov sp, bp
mov ax, 0x9000
mov ss, ax
; Set up the stack pointer in protected mode
mov ebp, 0x90000
mov esp, ebp
mov bl, byte [driveNumber]
; Perform the far jump
jmp KERNEL_LOC
;; GDT
GDT_Start:
null_descriptor: ; No clue why this exists
dd 0
dd 0
code_descriptor: ; Memory for code
dw 0xffff ; First 16 bits of limit
dw 0 ; 16 bits +
db 0 ; + 8 bits = 24 bits
db 0b10011010 ; p, dpl, s, type flags
db 0b11001111 ; Other flags, last 4 bits of limit
db 0 ; Base
data_descriptor: ; Memory for data
dw 0xffff ; First 16 bits of limit
dw 0 ; 16 bits +
db 0 ; + 8 bits = 24 bits
db 0b10010010 ; p, dpl, s, type flags
db 0b11001111 ; Other flags, last 4 bits of limit
db 0 ; Base
GDT_End:
; Setup video mode
mov ax, 0x0003
int 0x10
mov ah, 0x0b
mov bx, 0x0001
int 0x10
GDT_Descriptor:
dw GDT_End - GDT_Start - 1 ; Size
dd GDT_Start ; GDT Pointer
; Far jump to the kernel (never returns)
jmp KERNEL_LOC:0x0000
readFail:
mov si, diskErrorMsg
call print
cli
hlt
%include "./src/lib/print.asm"
driveNumber: db 0
bootMsg: db ENDL, "Booting kern.", ENDL, "Booting from drive ", 0
diskErrorMsg: db "Disk Error!", ENDL, 0
FILETAB_LOC equ 0x1000
KERNEL_LOC equ 0x2000
CODE_SEG equ code_descriptor - GDT_Start
DATA_SEG equ data_descriptor - GDT_Start
times 510-($-$$) db 0
dw 0xaa55
-22
View File
@@ -1,22 +0,0 @@
; ------------------
; Simple Filetable
; ------------------
;
; 16 Byte entries
; 0-9 - Filename
; 10-12 - File extension (type)
; 13 - Number of filetable entries
; 14 - Starting Sector
; 15 - Filesize in sectors (n * 512)
;
; ------------------
filetable:
; db 'all',0,0,0,0,0,0,0,'txt',0,1,7 ; all - start: 1, size: 7
db 'boot',0,0,0,0,0,0, 'bin',0,1,1 ; boot.bin - start: 1, size: 1
db 'filetable',0, 'txt',0,2,1 ; filetable.txt - start: 2, size: 1
db 'kernel',0,0,0,0, 'bin',0,3,4 ; kernel.bin - start: 3, size: 4
db 'calc',0,0,0,0,0,0, 'bin',0,7,1 ; calc.bin - start: 7, size: 1
db 'edit',0,0,0,0,0,0, 'bin',0,8,4 ; edit.bin - start: 8, size: 2
times 512-($-$$) db 0
-32
View File
@@ -1,32 +0,0 @@
[bits 16]
start:
pusha
mov si, msg
call print
xor ax, ax
int 0x16
mov dl, ah
call printHexByte
xor ax, ax
int 0x16
popa
.return:
mov ax, 0x2000
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
jmp 0x2000:0x0000
%include "./src/lib/print.asm"
msg: db "Hello!", ENDL, 0
times 512-($-$$) db 0
-312
View File
@@ -1,312 +0,0 @@
[bits 16]
start:
pusha
mov byte [driveNum], dl
hexEditor:
call clearText
mov di, 0x0e60 ; Offset in vidmem (2nd to last line)
mov si, hexModeMsg
call drawString
mov di, 0x0f00 ; Last line
mov si, controlsMsg
call drawString
mov di, hexCode
xor cx, cx ; Clear counter
mov dx, [codeLen]
call printHexByte
mov si, bytesMsg
call print
mov si, newline
call print
cmp word [codeLen], 0
je getHexCh
mov cx, [codeLen]
.printCode:
mov dl, [di]
call printHexByte
mov ah, 0x0e
mov al, ' '
int 0x10
inc di
dec cx
jnz .printCode
mov cx, [codeLen]
getHexCh:
xor ax, ax
int 0x16
cmp al, RUN_CODE
je .runInput
cmp al, QUIT_EDIT
je return
cmp al, SAVE_FILE
je save
cmp al, OPEN_FILE
je open
cmp al, 0x08 ; Backspace
je .backspace
xor ah, ah
call asciiToHex ; Get the hex digit into bx
cmp ax, 15 ; Check if it's a hex character
jg getHexCh ; If not, ignore it
inc cx
cmp cx, 2 ; Check if we've gotten a whole byte (2 hex digits/nibbles)
je .putByte
mov [hexByte], al
jmp getHexCh
.putByte:
cmp di, hexCode+510
jge getHexCh ; Max length reached
rol byte [hexByte], 4
or byte [hexByte], al
mov al, [hexByte]
stosb
mov dx, [hexByte]
call printHexByte
inc word [codeLen]
xor cx, cx
mov al, ' '
mov ah, 0x0e
int 0x10
jmp getHexCh
.backspace:
cmp word [codeLen], 0 ; Check if there's anything to delete
je getHexCh ; If not, ignore
mov byte [hexByte], 0
dec word [codeLen]
xor cx, cx
mov byte [di], 0
dec di
mov si, hexBackspace
call print
jmp getHexCh
.runInput:
mov si, runMsg
call print
pusha
push es
call hexCode ;! Runs arbitrary code (may break everything)
pop es
popa
mov si, ranMsg
call print
xor ax, ax
int 0x16
jmp hexEditor
return:
popa
mov ax, 0x2000
mov es, ax
xor bx, bx
mov ds, ax
mov fs, ax
mov gs, ax
jmp 0x2000:0x0000
; Saves a file
save:
mov dl, 9
mov si, saveFileMsg
call getInput
mov byte al, [filename]
cmp byte al, 0
je getHexCh
; Call saveFile
mov byte dl, [driveNum]
push word filename
push word binFile ; Filetype, TODO: More filetypes other than .bin
push word 1 ; TODO: Dynamic filesize
push word 0x8000 ; Program location (this segment)
push word savedData ; Offset (hex code location)
call saveFile ; Returns exit code in al
add sp, 10 ; Stack bs
mov ax, 0x8000
mov es, ax
mov fs, ax
cmp al, 0 ; Won't be 1 (File not found) so must be disk error
jne .error
jmp getHexCh
.error:
mov si, diskErrMsg
mov di, 0x0f00 ; Last line
call drawString
jmp getHexCh
; Opens a file
open:
mov dl, 11
mov si, openFileMsg
call getInput
mov byte al, [filename]
cmp byte al, 0
je getHexCh
; Call loadFile
mov byte dl, [driveNum]
push word filename
push word 0x8000
push word hexCode
call loadFile
mov ax, 0x8000
mov es, ax
mov fs, ax
cmp al, 1
je .notFound
cmp al, 2
je .diskErr
; Success
jmp hexEditor
.notFound:
mov si, notFoundMsg
jmp .err
.diskErr:
mov si, diskErrMsg
.err:
mov di, 0x0f00
call drawString
xor ax, ax
int 0x16
jmp hexEditor
;
; Gets a filename (10 chars, If less, padded with Nulls)
; Outputs the filename in the filename buffer
; si - Prompt string (Null terminated)
; dl - String offset
;
getInput:
pusha
push es
mov di, 0x0f00 ; Last line
call drawString ; si should contain the string
mov ah, 2 ; Move cursor to input position
mov dh, 24 ; Last line
int 0x10
mov di, filename
xor cx, cx ; Entered filename length
.loop:
xor ax, ax
int 0x16
cmp al, 0xD ; User pressed enter
je .done
cmp al, 8 ; Backspace
je .backspace
cmp al, 27 ; Escape
je .escape
cmp cx, 10 ; Filename too long
je .loop
mov ah, 0x0e
int 0x10
mov [di], al
inc di
inc cx
jmp .loop
.backspace:
cmp cx, 0
je .loop
dec cx
dec di
mov si, textBackspace
call print
jmp .loop
.escape:
xor cx, cx
mov si, filename
.done:
cmp cx, 10
je .after
mov byte [di], 0
inc cx
inc di
.after:
mov ah, 2 ; Move cursor
xor dx, dx ; 0,0
int 0x10
pop es
popa
ret
; Expects al to contain an ASCII character, will set bx to it's hex equivalent
asciiToHex:
cmp al, 'F'
jle .upperCase
sub al, 32
.upperCase:
cmp al, '9'
jle .getHex
sub al, 7
.getHex:
sub al, '0'
ret
;; Includes
%include "./src/lib/print.asm"
%include "./src/lib/disk.asm"
;; Variables
hexModeMsg: db " -- HEX -- ", 0
textModeMsg: db " -- Text -- ", 0
controlsMsg: db "'$' Execute; ^Q Quit; ^S Save; ^O Open", 0
saveFileMsg: db "Save as: ", 0 ; Make sure to erase the controls
openFileMsg: db "Open file: ", 0
bytesMsg: db " Bytes", 0
; savedMsg: db "Saved file as '", 0
; openedMsg: db "Editing file '", 0
runMsg: db ENDL, ENDL, 0
ranMsg: db ENDL, ENDL, " - Finished Execution - ", ENDL, 0
notFoundMsg: db "File not found! ", 0 ; Erase the user input
diskErrMsg: db "Disk Error! ", 0
; Filetypes
binFile: db "bin"
txtFile: db "txt"
hexBackspace: db 8,8,8,' ',8,8,0
textBackspace: db 8,' ',8,0
driveNum: db 0
hexByte: db 0
filenameLen: db 0
filename: times 10 db 0
;; Constants
RUN_CODE equ '$'
QUIT_EDIT equ 'q'
NEW_FILE equ 'n'
SAVE_FILE equ 's'
OPEN_FILE equ 'o'
times 3*512-($-$$) db 0
savedData:
hexCode: times 510 db 0 ; Code buffer
codeLen: dw 0 ; Hopefully we don't overflow :)
-503
View File
@@ -1,503 +0,0 @@
[bits 16]
start:
; Save the drive number from stack
mov byte [driveNum], dl
mov bx, 0x2000
mov es, bx
xor bx, bx
call resetTextMode
call clearText
; Print start message
mov si, startMsg
call print
; Runs prompt
input:
mov si, prompt
call print
mov ax, 0x2000
mov ds, ax
mov es, ax
mov si, userInput
xor cx, cx
.loop:
xor ax, ax ; Clear ax
int 0x16 ; Get a character
cmp al, 0x0d ; Compare with CR
je .enter
cmp al, 0x08 ; Compare with BS
je .backspace
mov ah, 0x0e ; Echo back input
mov bh, 0
int 0x10
mov [si], al ; Add the input to userInput
inc cx
inc si
jmp .loop
.backspace:
cmp cx, 0 ; Check if we can backspace
je .loop
mov byte [si], 0
dec si
dec cx
mov al, 0x08
int 0x10
mov al, ' '
int 0x10
mov al, 0x08
int 0x10
jmp .loop
.enter:
push si
mov si, newline
call print
pop si
mov byte [si], 0 ; NULL terminate userInput (Replaces CR)
mov byte [inputLen], cl
cmp byte [inputLen], 0 ; Check if user input something
je input
tokenize: ; Tokenize
mov si, userInput
.loop:
inc si
cmp byte [si], 0
je .done
cmp byte [si], ' '
jne .loop
mov byte [si], 0
jmp .loop
.done:
; Runs a command in userInput
; Expects tokenized input
runCommand:
mov di, lsCmd
call .cmp
je fileList
mov di, gfxCmd
call .cmp
je graphicsTest
mov di, helpCmd
call .cmp
je help
mov di, rebootCmd
call .cmp
je reboot
mov di, clearCmd
call .cmp
je clear
mov di, exitCmd
call .cmp
je shutdown
mov di, rmCmd
call .cmp
je rmFile
jmp .end
.cmp:
push cx
mov si, userInput
repe cmpsb
pop cx
ret
.end:
;
; Load Program - Takes userInput and tries to run that file
;
loadProgram:
mov di, userInput
mov bx, FILETAB_LOC
mov es, bx
xor bx, bx ; Get [es:bx] to be start of filetable
.nextCh:
mov al, [es:bx]
cmp al, 0 ; Check for end of filetable
je .notFound
cmp al, [di] ; Check for starting character
je .beginSearch
add bx, 16 ; Move to the next entry
jmp .nextCh
.beginSearch:
push bx ; Save position, if it doesn't equal
mov byte cl, [inputLen]
.searchLoop:
mov al, [es:bx]
inc bx
cmp al, [di]
jne .restartSearch
dec cl
jz .match
inc di
jmp .searchLoop
.match:
mov al, [es:bx]
cmp al, 0 ; Check if we are at the end of a filename
je foundProgram
.restartSearch:
mov di, userInput
pop bx
inc bx
jmp .nextCh
.notFound:
mov si, fileNotFoundMsg
call print
jmp input
foundProgram:
mov al, [es:bx]
cmp al, 0 ; Loop until we find the extension
jne .getMetadata
inc bx
jmp foundProgram
.getMetadata:
mov al, [es:bx]
mov [fileExt], al
inc bx
mov al, [es:bx]
mov [fileExt+1], al
inc bx
mov al, [es:bx]
mov [fileExt+2], al
inc bx
inc bx ; Ignore Number of FT entries for now
; mov cl, [es:bx] ; Starting sector
; inc bx
; mov al, [es:bx] ; Number of sectors to read
; push ax ; Save file size
; mov ah, 0 ; Reset disk system
; mov dl, byte [driveNum]
; int 0x13
; mov bx, PROGRAM_LOC
; mov es, bx
; xor bx, bx ; [es:bx] - Place to load out program
; mov ah, 2 ; Read sectors into memory
; mov dl, byte [driveNum]
; mov ch, 0 ; Cylinder
; mov dh, 0 ; Head
; int 0x13
mov byte dl, [driveNum] ; Drive number
push word userInput ; Filename
push word PROGRAM_LOC ; Dest. segment
push word 0x0000 ; Dest. offset
call loadFile
cmp byte al, 0
je .loaded ; Loaded file successfully
mov si, programLoadFailMsg
call print
jmp input
.loaded:
; Check file extension. If 'bin', then run, if 'txt', print
pop ax ; Restore file size
mov cx, 3 ; Check file extension
mov si, fileExt
mov ax, 0x2000
mov es, ax
mov di, binExt
repe cmpsb
jne .printText ; TODO: Check for more file extensions
mov dl, [driveNum]
mov ax, PROGRAM_LOC
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
jmp PROGRAM_LOC:0x0000
.printText:
mov bx, PROGRAM_LOC
mov es, bx
xor bx, bx
mov cx, 512
mul cx
mov cx, ax
mov ah, 0x0e
.textLoop:
mov al, [es:bx]
cmp al, 0
je .rep
int 0x10
.rep:
inc bx
dec cx
jnz .textLoop
mov si, newline
call print
jmp input
;
; Help - Prints the help message (helpMsg)
;
help:
mov si, helpMsg
call print
jmp input
;
; Clears the screen
;
clear:
call clearText
jmp input
;
; Shuts the system down
; Only works for QEMU
;
shutdown:
mov ax, 0x2000
mov dx, 0x0604
out dx, ax
;
; Remove file (rm)
;
rmFile:
call removeFile
jmp input
;
; File list (ls)
;
fileList:
mov bx, FILETAB_LOC
mov es, bx
xor bx, bx
mov al, 2 ; Read from disk
mov byte dl, [driveNum]
mov ch, 0 ; Cylinder
mov dh, 0 ; Head
mov cl, 2 ; Sector
mov al, 1 ; Read 1 sector
int 0x13 ; Move filetable to es:bx
mov si, fileListMsg
call print
; Prints the filetable
printFiletable:
mov bx, FILETAB_LOC
mov es, bx
xor bx, bx
xor cx, cx ; Entry byte couter
mov ah, 0x0e ; Prepare for printing
.filenameLoop:
mov al, [es:bx] ; Get filename character
cmp al, 0 ; Check if it's NULL
je .filenameEnd ; If so, end the filename reading
cmp cx, 9 ; Check if we already read 10 Bytes
je .filenameEnd
int 0x10 ; Else print the character
inc cx ; Increment byte counter
inc bx
jmp .filenameLoop
.filenameEnd:
push cx
.skipNull:
cmp cx, 0
je .done
cmp cx, 10 ; Check if we're at the end of filename
je .fileExt ; If so, print extension
inc cx
inc bx
jmp .skipNull
.fileExt:
; push cx ; Save the counter
mov al, '.' ; Print a "." to separate filename from extension
int 0x10
.fileExtLoop:
mov al, [es:bx]
cmp cx, 13 ; Check if we printed 3 characters
je .fileExtEnd
cmp al, 0
je .fileExtEnd
int 0x10
inc cx
inc bx
jmp .fileExtLoop
.fileExtEnd:
cmp cx, 13
je .whitespace
inc cx
inc bx
mov al, ' ' ; Print whitespace
int 0x10
jmp .fileExtEnd
.whitespace:
pop cx
.wsLoop:
cmp cx, 11 ; Max filename length + 1 for spacing
je .fileInfo
mov al, ' '
int 0x10
inc cx
jmp .wsLoop
.fileInfo:
; Entry number
mov dl, [es:bx]
call printHexByte
inc bx
mov al, ' '
int 0x10
; Start sector
mov dl, [es:bx]
call printHexByte
inc bx
mov al, ' '
int 0x10
int 0x10
int 0x10
; File size
mov al, [es:bx]
inc bx
cmp al, 1
je .oneSector ; Only print 512B
shr al, 1 ; Divide by 2
jc .oneHalf ; We had an odd number of sectors
add al, '0'
int 0x10
mov si, kilobyteText
call print
jmp .repeat
.oneHalf:
add al, '0'
int 0x10
mov si, oneHalfText
call print
jmp .repeat
.oneSector:
mov si, sectorLenText
call print
.repeat:
mov si, newline
call print
xor cx, cx
jmp .filenameLoop
.done:
jmp input
;
; Graphics Mode Test
;
graphicsTest:
call resetGraphicsMode
; Test square
mov ah, 0x0c ; Write gfx pixel
mov al, 0x02 ; Green
mov bh, 0 ; Page number
mov cx, 100 ; Column number
mov dx, 100 ; Row number
int 0x10
.colLoop:
inc cx
int 0x10
cmp cx, 150
jne .colLoop
inc dx
int 0x10
mov cx, 99
cmp dx, 150
jne .colLoop
.done:
mov si, startMsg
call print
xor ax, ax
int 0x16
call resetTextMode
jmp input
;
; Reboots the OS
;
reboot: jmp 0xffff:0x0000
;; Includes
%include "./src/lib/print.asm"
%include "./src/lib/screen.asm"
%include "./src/lib/disk.asm"
;; Variables
driveNum: db 0
startMsg: db "kern.", ENDL, ENDL, 0 ; The bootup message
prompt: db "> ", 0 ; Prompt for input
fileNotFoundMsg: db "File not found!", ENDL, 0 ; User tries to load nonexistent file
programLoadFailMsg: db "Couldn't load file!", ENDL, 0 ; File load fail
sectorLenText: db "512B", 0
kilobyteText: db "kB", 0
oneHalfText: db ".5kB", 0
fileListMsg: db " Filename E# St Size ", ENDL, \
"---------- ------- ------", ENDL, 0
helpMsg: db "Available Commands:", ENDL, \
" clear | Clears the screen", ENDL, \
" edit | Opens the code editor", ENDL, \
" exit | Shuts the system down", ENDL, \
" gfx | Graphics mode test", ENDL, \
" help | Prints this message", ENDL, \
" ls | List all files", ENDL, \
" reboot | Reboots the system", ENDL, \
" rm | Removes a file", ENDL, ENDL, 0
; Commands
; TODO: Put these into a file or something
clearCmd: db "clear", 0
exitCmd: db "exit"
gfxCmd: db "gfx", 0
helpCmd: db "help", 0
lsCmd: db "ls", 0
rebootCmd: db "reboot", 0
rmCmd: db "rm", 0
; Files
fileExt: db " ", 0
binExt: db "bin", 0
txtExt: db "txt", 0
inputLen: db 0
tokenCount: db 0
userInput: times 80 db 0
;; Constants
FILETAB_LOC equ 0x1000
PROGRAM_LOC equ 0x8000
times 4*512-($-$$) db 0
+9
View File
@@ -0,0 +1,9 @@
[bits 32]
[global _start]
[extern main]
_start:
call main
cli
hlt
+6
View File
@@ -0,0 +1,6 @@
#include "screen.h"
void main() {
print("Hello, World!", 0x0f);
}
+21
View File
@@ -0,0 +1,21 @@
#include "screen.h"
unsigned int cursor = 0;
void putc(char c, char attr) {
int mem = VIDMEM + cursor * 2;
*(char*)(mem) = c;
*(char*)(mem+1) = attr;
cursor++;
}
void print(char* s, char attr) {
int i = 0;
char c = *s;
while (c != '\0') {
putc(c, attr);
c = *(s + ++i);
}
}
+9
View File
@@ -0,0 +1,9 @@
#ifndef SCREEN_H
#define SCREEN_H
#define VIDMEM 0xb8000
void putc(char c, char attr);
void print(char* s, char attr);
#endif
-334
View File
@@ -1,334 +0,0 @@
;
; Loads a file from the filetable into a memory location
; Params:
; dl - Disk number (byte)
; Filename (Null terminated)
; Destination location segment
; Destination location offset
;
; Returns:
; al - Exit code : 0 - Success; 1 - File not found; 2 - Disk error
;
loadFile:
; Func prologue
push bp
mov bp, sp
push bx
push fs
push cx
push dx
push si
push es
mov byte [diskNum], dl
mov bx, [bp+4] ; src Offset
mov fs, [bp+6] ; src Segment
mov si, [bp+8] ; Filename
push bx
mov cx, 10
mov di, fileName
.getFilename:
lodsb ; mov byte al, [si]; inc si
cmp al, 0 ; End of fileName
je .filenamePad
stosb
loop .getFilename
jmp .filenameDone
.filenamePad:
dec si ; Fill the rest with Null
.filenamePadLoop:
stosb
loop .filenamePadLoop
.filenameDone:
mov si, fileName
call print
mov ax, FILETAB_LOC
mov es, ax
xor di, di ; es:di - Filetable location
mov si, fileName
.fileNameCheck:
mov al, [es:di]
cmp al, 0 ; End of filetable
je .notFound
cmp al, [si]
je .beginCmp
add di, 16
jmp .fileNameCheck
.beginCmp:
push di
mov cl, 10
.cmpLoop:
mov al, [es:di]
inc di
cmp al, [si]
jne .redoCheck
dec cl
jz .found
inc si
jmp .cmpLoop
.redoCheck:
mov si, fileName
pop di
add di, 16
jmp .fileNameCheck
.notFound:
mov byte [exitCode], NOT_FOUND
jmp .done
.found:
add di, 3 ; Skip extension
inc di ; Skip Number of entries
xor ax, ax ; Reset disk
mov dl, [diskNum]
int 0x13
mov ch, 0 ; Cylinder
mov dh, 0 ; Head
mov cl, [es:di] ; Sector
inc di
mov al, [es:di] ; Length in sectors
mov bx, fs
mov es, bx
pop bx
mov dx, bx
call printHexByte
mov ah, 2 ; Read from disk
int 0x13
jnc .done
mov byte [exitCode], DISK_ERROR
.done:
; Func epilogue
pop es
pop si
pop dx
pop cx
pop fs
pop bx
mov sp, bp
pop bp
mov byte al, [exitCode]
ret
;
; Saves a file to the disk and updates filetable
; dl - Disk number
; Params:
; Filename (Null terminated)
; Filetype (Null terminated)
; Filesize (Byte)
; Source location segment
; Source location offset
;
; Returns:
; al - Exit code : 0 - Success; 1 - File not found; 2 - Disk error
;
saveFile:
; Func prologue
push bp
mov bp, sp
push bx
push fs
push cx
push dx
push si
push es
mov byte [diskNum], dl
mov bx, [bp+4] ; src Offset
mov fs, [bp+6] ; src Segment
mov cx, [bp+8] ; Filesize
mov ax, [bp+10] ; Filetype
push bx
mov byte [filesize], cl
mov si, ax
mov di, filetype
mov cx, 3
rep movsb
mov si, [bp+12] ; Filename
mov cx, 10
mov di, fileName
.getFilename:
lodsb ; mov byte al, [si]; inc si
cmp al, 0 ; End of fileName
je .filenamePad
stosb
loop .getFilename
jmp .filenameDone
.filenamePad:
dec si ; Fill the rest with Null
.filenamePadLoop:
stosb
loop .filenamePadLoop
.filenameDone:
mov ax, FILETAB_LOC
mov es, ax
xor di, di ; es:di - Filetable location
mov si, fileName
.fileNameCheck:
mov byte al, [es:di+14] ; Starting sector
cmp al, 0 ; No file, create one
je createFile
add byte al, [es:di+15] ; Filesize
mov byte [availableSector], al
mov al, [es:di]
cmp al, 0 ; End of filetable
je createFile ; File doesn't exist, create new one
cmp al, [si]
je .beginCmp
add di, 16
jmp .fileNameCheck
.beginCmp:
push di
mov cl, 10
.cmpLoop:
mov al, [es:di]
inc di
cmp al, [si]
jne .redoCheck
dec cl
jz .found
inc si
jmp .cmpLoop
.redoCheck:
mov si, fileName
pop di
add di, 16
jmp .fileNameCheck
.found: ; File already exists (override)
; TODO: Ask user if they want to override file
add di, 3 ; Skip extension
inc di ; Skip Number of entries
xor ax, ax ; Reset disk
mov dl, [diskNum]
int 0x13
; TODO: Override current file
; push fs
; mov ch, 0 ; Cylinder
; mov dh, 0 ; Head
; mov cl, [es:di] ; Sector
; inc di
; mov al, [es:di] ; Length in sectors
; mov ah, 3 ; Write to disk
; pop es ; es:bx - Destination
; int 0x13
; jnc returnToCaller
mov byte [exitCode], DISK_ERROR
jmp returnToCaller ; TODO: Fix this
createFile: ; Appends a file to the filetable.
mov di, FILETAB_LOC
mov es, di
xor di, di
.filetabEnd: ; Move to the end of filetable
cmp byte [es:di], 0
je .filetabEndDone
add di, 16
jmp .filetabEnd
.filetabEndDone:
mov cx, 10
mov si, fileName
rep movsb ; Append the fileName
mov cx, 3
mov si, filetype
rep movsb ; Append the extension
mov byte [es:di], 0 ; Number of entries
inc di
mov byte al, [availableSector]
stosb ; Starting sector
mov byte al, [filesize]
stosb ; File length in sectors
; Write changed filetable to disk
;! If filetable size changes, this will have to change (probably)
mov bx, FILETAB_LOC
mov es, bx
xor bx, bx ; es:bx - Filetable location
mov dl, [diskNum]
mov ah, 3 ; Write to disk
mov al, 1 ; Write 1 sector
mov ch, 0 ; Cylinder
mov dh, 0 ; Head
mov cl, 2 ; Sector
int 0x13
jnc writeFileData
mov byte [exitCode], DISK_ERROR
jmp returnToCaller
writeFileData: ; Writes file data to the disk
mov ax, 0x8000 ; Source segment
mov es, ax
pop bx ; es:bx - Source
mov ah, 3 ; Write to disk
mov byte al, [filesize]
mov dl, [diskNum]
mov ch, 0 ; Cylinder
mov dh, 0 ; Head
mov byte cl, [availableSector]
int 0x13
jnc returnToCaller
mov byte [exitCode], DISK_ERROR ; Exit code - Disk Error
returnToCaller:
; Func epilogue
pop es
pop si
pop dx
pop cx
pop fs
pop bx
mov sp, bp
pop bp
mov byte al, [exitCode]
ret
;
; Removes a file from the disk/filetable
;
; Params:
; Filename
;
removeFile:
ret
;; Variables
availableSector: db 0
exitCode: db 0
diskNum: db 0
filesize: db 0
filetype: times 3 db 0
fileName: times 10 db 0
;; Constants
FILETAB_LOC equ 0x1000
; Exit codes
SUCCESS equ 0
NOT_FOUND equ 1
DISK_ERROR equ 2
-129
View File
@@ -1,129 +0,0 @@
;
; Prints a string
; si - Pointer to NULL terminated string
;
print:
pusha
mov ah, 0x0e
mov bl, 0x1f
mov bh, 0
.loop:
lodsb ; Load [si] into al; Increment si
or al, al
jz .done
int 0x10
jmp .loop
.done:
popa
ret
;
; Prints a hex value
; dx - Value to print in Hex
;
printHex:
pusha
xor cx, cx ; Init counter
.loop:
cmp cx, 4 ; Check for loop end
je .done
mov ax, dx ; Copy dx to ax
and ax, 0x000f ; Get last nibble (4 bits) of ax
add ax, '0' ; Convert number to an ASCII number (0-9)
cmp ax, '9' ; Check if number was less than 9, meaning we can use it
jle .addChar
add ax, 0x07 ; Convert to letter (A-F)
.addChar:
mov bx, hexString + 5
sub bx, cx ; Get position of current hex character
mov [bx], al
ror dx, 4 ; Rotate bits of dx (0x1a2b -> 0xb1a2)
inc cx ; Increment the counter
jmp .loop
.done:
mov si, hexString
call print
popa
ret
;
; Prints a hex byte
; dl - Hex byte
;
printHexByte:
pusha
xor cx, cx
mov bh, 0
mov bl, 0x1f ; White on blue
.loop:
mov al, dl
and al, 0xF0
ror al, 4
add al, '0'
cmp al, '9'
jle .hexNum
add al, 7
.hexNum:
mov ah, 0x0e
int 0x10
inc cx
cmp cx, 2
je .done
ror dl, 4
jmp .loop
.done:
popa
ret
hexString: db "0x0000", 0
;
; Clears the screen in text mode
; Assumes VGA text 3 - 80x25, 16 color
;
clearText:
pusha
push es
mov ax, 0x0b800
mov es, ax
xor di, di ; es:di - b800:0000
mov al, ' ' ; Fill with spaces
mov ah, 0x17 ; White on blue
mov cx, 80*25
rep stosw
mov ah, 2
xor dx, dx ; Set cursor to 0,0
int 0x10
pop es
popa
ret
;
; Writes a string into video memory
; di - Video memory offset
; si - string
;
drawString:
pusha
push es ; For some reason doesn't get stored in pusha
mov ax, VIDMEM
mov es, ax
.loop:
cmp byte [si], 0
je .after
movsb
mov byte [es:di], 0x1f ; White on blue
inc di
jmp .loop
.after:
pop es
popa
ret
; Usefull definitions
%define ENDL 0x0a, 0x0d
VIDMEM equ 0x0b800
newline: db ENDL, 0 ; CRLF
-24
View File
@@ -1,24 +0,0 @@
resetTextMode:
pusha
mov ah, 0 ; Set mode
mov al, 0x03 ; 25x80, Text mode
int 0x10
mov ah, 0x0b ; Change color/palette
mov bh, 0x00 ; Change BG color
mov bl, 0x01 ; Blue BG
int 0x10
popa
ret
resetGraphicsMode:
pusha
mov ah, 0 ; Set mode
mov al, 0x13 ; 320x200, 256 color graphics mode
int 0x10
popa
ret
BIN
View File
Binary file not shown.
-25
View File
@@ -1,25 +0,0 @@
[bits 16]
start:
mov ah, 0x0e
mov al, 'H'
int 0x10
mov al, 'e'
int 0x10
mov al, 'l'
int 0x10
int 0x10
mov al, 'o'
int 0x10
mov al, '!'
int 0x10
xor ax, ax
int 0x16
mov ax, 0x2000
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
jmp 0x2000:0x0000