diff --git a/README.md b/README.md index 97dc021..cf1071d 100644 --- a/README.md +++ b/README.md @@ -38,4 +38,4 @@ _These images may be outdated, Idk_ ## Known issues - If you run the kernel.bin, loading files sorta breaks, because the program is running at 0x8000, but it thinks that it's at 0x2000 (i think) - If you run anything in the code editor and return to the kernel, you won't be able to load any files -- If you type only the starting letters of a command, it will still run (ie. 'he' will run help) +- If you type only the starting letters of a command, it will still run (i.e. 'he' will run help) diff --git a/asmSrc/boot.asm b/asmSrc/boot.asm new file mode 100644 index 0000000..efeec90 --- /dev/null +++ b/asmSrc/boot.asm @@ -0,0 +1,98 @@ +[org 0x7c00] +[bits 16] +[global start] + +start: + ; Setup + xor ax, ax + mov es, ax + mov ds, ax + mov bp, 0x7c00 + mov sp, bp + + ; Save drive number + mov byte [driveNumber], dl + + ; Print boot message + mov si, bootMsg + call print + mov dl, byte [driveNumber] + call printHex + mov si, newline + call print + + ; Read filetable from disk + mov bx, FILETAB_LOC ; Filetable location in memory + mov es, bx + xor bx, bx + + mov ah, 2 ; Read from disk + mov al, 1 ; Read 1 sector (512B) + + 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 readFail ; CF will be set if the read fails + + ; Read filetable from disk + mov bx, KERNEL_LOC ; Filetable location in memory + mov es, bx + xor bx, bx + + mov ah, 2 ; Read from disk + mov al, 4 ; Read 4 sectors (2kB) + + mov dl, byte [driveNumber] ; Drive number + mov ch, 0 ; Cylinder + mov dh, 0 ; Head + mov cl, 3 ; Sector + int 0x13 ; INT 0x13 - Disk operations + + jc readFail ; CF will be set if the read fails + + ; Setup segmentation + mov ax, KERNEL_LOC + mov ds, ax + mov es, ax + mov fs, ax + mov gs, ax + + ; Setup stack + mov bp, 0xffff + mov sp, bp + mov ax, 0x9000 + mov ss, ax + + mov bl, byte [driveNumber] + + ; Setup video mode + mov ax, 0x0003 + int 0x10 + mov ah, 0x0b + mov bx, 0x0001 + int 0x10 + + ; 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 + +times 510-($-$$) db 0 +dw 0xaa55 diff --git a/asmSrc/filetable.asm b/asmSrc/filetable.asm new file mode 100644 index 0000000..800cd3a --- /dev/null +++ b/asmSrc/filetable.asm @@ -0,0 +1,22 @@ +; ------------------ +; 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 diff --git a/src/fs/calc.asm b/asmSrc/fs/calc.asm similarity index 74% rename from src/fs/calc.asm rename to asmSrc/fs/calc.asm index ca71d2b..9713e03 100644 --- a/src/fs/calc.asm +++ b/asmSrc/fs/calc.asm @@ -1,12 +1,21 @@ [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 diff --git a/src/fs/edit.asm b/asmSrc/fs/edit.asm similarity index 80% rename from src/fs/edit.asm rename to asmSrc/fs/edit.asm index 9f43914..0e86338 100644 --- a/src/fs/edit.asm +++ b/asmSrc/fs/edit.asm @@ -1,10 +1,10 @@ [bits 16] start: + pusha mov byte [driveNum], dl hexEditor: - pusha call clearText mov di, 0x0e60 ; Offset in vidmem (2nd to last line) @@ -16,6 +16,29 @@ hexEditor: 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 @@ -42,7 +65,7 @@ getHexCh: mov [hexByte], al jmp getHexCh .putByte: - cmp di, hexCode+256 + cmp di, hexCode+510 jge getHexCh ; Max length reached rol byte [hexByte], 4 or byte [hexByte], al @@ -50,18 +73,18 @@ getHexCh: stosb mov dx, [hexByte] call printHexByte - inc byte [codeLen] + inc word [codeLen] xor cx, cx mov al, ' ' mov ah, 0x0e int 0x10 jmp getHexCh .backspace: - mov byte [hexByte], 0 - dec byte [codeLen] - xor cx, cx - cmp di, hexByte ; Check if there's anything to delete + 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 @@ -72,7 +95,9 @@ getHexCh: call print pusha - call hexCode ; Call the code + push es + call hexCode ;! Runs arbitrary code (may break everything) + pop es popa mov si, ranMsg @@ -80,16 +105,7 @@ getHexCh: xor ax, ax int 0x16 jmp hexEditor - return: - mov cx, 256 - mov di, hexCode -.loop: - mov byte [di], 0 - inc di - dec cx - jnz .loop - popa mov ax, 0x2000 @@ -105,7 +121,7 @@ return: save: mov dl, 9 mov si, saveFileMsg - call getFilename + call getInput mov byte al, [filename] cmp byte al, 0 je getHexCh @@ -113,14 +129,17 @@ save: ; Call saveFile mov byte dl, [driveNum] push word filename - ; TODO: More filetypes other than .bin - push word binFile ; Filetype + 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 hexCode ; Offset (hex code location) + 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 @@ -129,13 +148,14 @@ save: mov si, diskErrMsg mov di, 0x0f00 ; Last line call drawString + jmp getHexCh ; Opens a file open: mov dl, 11 mov si, openFileMsg - call getFilename + call getInput mov byte al, [filename] cmp byte al, 0 je getHexCh @@ -143,17 +163,21 @@ open: ; Call loadFile mov byte dl, [driveNum] push word filename - push 0x8000 - push hexCode + push word 0x8000 + push word hexCode call loadFile - add sp, 8 + + mov ax, 0x8000 + mov es, ax + mov fs, ax cmp al, 1 je .notFound cmp al, 2 je .diskErr - jmp getHexCh + ; Success + jmp hexEditor .notFound: mov si, notFoundMsg jmp .err @@ -162,7 +186,9 @@ open: .err: mov di, 0x0f00 call drawString - jmp getHexCh + xor ax, ax + int 0x16 + jmp hexEditor ; ; Gets a filename (10 chars, If less, padded with Nulls) @@ -170,7 +196,7 @@ open: ; si - Prompt string (Null terminated) ; dl - String offset ; -getFilename: +getInput: pusha push es @@ -247,6 +273,9 @@ 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 +; oepenedMsg: 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 @@ -264,7 +293,6 @@ hexByte: db 0 filenameLen: db 0 filename: times 10 db 0 -codeLen: db 0 ;; Constants RUN_CODE equ '$' @@ -275,5 +303,6 @@ OPEN_FILE equ 'o' times 3*512-($-$$) db 0 -hexCode: times 511 db 0 ; Code buffer - ret +savedData: + hexCode: times 510 db 0 ; Code buffer + codeLen: dw 0 ; Hopefully we don't overflow :) diff --git a/src/kernel.asm b/asmSrc/kernel.asm similarity index 91% rename from src/kernel.asm rename to asmSrc/kernel.asm index 29b7d5a..62e8118 100644 --- a/src/kernel.asm +++ b/asmSrc/kernel.asm @@ -65,7 +65,27 @@ input: cmp byte [inputLen], 0 ; Check if user input something je input +tokenize: ; Tokenize + mov byte cl, [inputLen] + mov di, tokens +.tokenLoop: + lodsb + cmp al, 0 ; Check for end of input + je runCommand +.wsLoop: + cmp al, ' ' ; Compare with whitespace + jne .stringLoop + lodsb + jmp .wsLoop +.stringLoop: + cmp al, ' ' + je .next + +.next: + + ; Runs a command in userInput +; Expects tokenized input runCommand: mov di, lsCmd call .cmp @@ -91,6 +111,10 @@ runCommand: call .cmp je shutdown + mov di, rmCmd + call .cmp + je rmFile + jmp .end .cmp: push cx @@ -255,6 +279,13 @@ shutdown: mov dx, 0x0604 out dx, ax +; +; Remove file (rm) +; +rmFile: + call removeFile + jmp input + ; ; File list (ls) ; @@ -419,6 +450,7 @@ reboot: jmp 0xffff:0x0000 ;; Includes %include "./src/lib/print.asm" %include "./src/lib/screen.asm" +%include "./src/lib/disk.asm" ;; Variables driveNum: db 0 @@ -441,24 +473,29 @@ helpMsg: db "Available Commands:", ENDL, \ " gfx | Graphics mode test", ENDL, \ " help | Prints this message", ENDL, \ " ls | List all files", ENDL, \ - " reboot | Reboots the system", ENDL, ENDL, 0 + " 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 -exitCmd: db "exit" rebootCmd: db "reboot", 0 +rmCmd: db "rm", 0 ; Files fileExt: db " ", 0 binExt: db "bin", 0 txtExt: db "txt", 0 +tokens: times 50 db 0 ; char[10][5] (List of 5 strings that are 10 chars long each or null terminated) +tokenLen: times 5 db 0 ; 5 lengths for each token +tokenCount: db 0 inputLen: db 0 -userInput: db 0 +userInput: times 80 db 0 ;; Constants FILETAB_LOC equ 0x1000 diff --git a/src/lib/disk.asm b/asmSrc/lib/disk.asm similarity index 90% rename from src/lib/disk.asm rename to asmSrc/lib/disk.asm index ade50d9..004e89f 100644 --- a/src/lib/disk.asm +++ b/asmSrc/lib/disk.asm @@ -21,9 +21,11 @@ loadFile: push es mov byte [diskNum], dl - mov bx, [bp+4] ; dest Offset - mov fs, [bp+6] ; dest Segment - mov si, [bp+8] ; Filename + 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 @@ -47,7 +49,7 @@ loadFile: .fileNameCheck: mov al, [es:di] cmp al, 0 ; End of filetable - je .notFound ; File doesn't exist, create new one + je .notFound cmp al, [si] je .beginCmp @@ -76,11 +78,6 @@ loadFile: mov byte [exitCode], NOT_FOUND jmp .done .found: - mov al, [es:di] - inc di - cmp al, 0 ; Skip NULLs untill extension - je .found - add di, 3 ; Skip extension inc di ; Skip Number of entries @@ -88,13 +85,16 @@ loadFile: mov dl, [diskNum] int 0x13 - mov ax, fs - mov es, ax 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 @@ -210,11 +210,6 @@ saveFile: jmp .fileNameCheck .found: ; File already exists (override) ; TODO: Ask user if they want to override file - mov al, [es:di] - inc di - cmp al, 0 ; Skip NULLs untill extension - je .found - add di, 3 ; Skip extension inc di ; Skip Number of entries @@ -236,7 +231,7 @@ saveFile: ; jnc returnToCaller mov byte [exitCode], DISK_ERROR - jmp return ; TODO: Fix this + jmp returnToCaller ; TODO: Fix this createFile: ; Appends a file to the filetable. mov di, FILETAB_LOC @@ -309,20 +304,14 @@ returnToCaller: mov byte al, [exitCode] ret -debug: - 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 +; +; Removes a file from the disk/filetable +; +; Params: +; Filename +; +removeFile: + ;; Variables availableSector: db 0 diff --git a/src/lib/print.asm b/asmSrc/lib/print.asm similarity index 100% rename from src/lib/print.asm rename to asmSrc/lib/print.asm diff --git a/src/lib/screen.asm b/asmSrc/lib/screen.asm similarity index 100% rename from src/lib/screen.asm rename to asmSrc/lib/screen.asm diff --git a/asmSrc/testing/hello b/asmSrc/testing/hello new file mode 100644 index 0000000..a710842 Binary files /dev/null and b/asmSrc/testing/hello differ diff --git a/asmSrc/testing/hello.asm b/asmSrc/testing/hello.asm new file mode 100644 index 0000000..7c638ea --- /dev/null +++ b/asmSrc/testing/hello.asm @@ -0,0 +1,25 @@ +[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 diff --git a/build.sh b/build.sh index a63ba66..392c47f 100644 --- a/build.sh +++ b/build.sh @@ -11,16 +11,16 @@ nasm -fbin src/boot.asm -o ./build/boot.bin nasm -fbin src/filetable.asm -o ./build/filetable.bin # Kernel -nasm -fbin src/kernel.asm -o ./build/kernel.bin +# nasm -fbin src/kernel.asm -o ./build/kernel.bin # Programs -nasm -fbin src/fs/calc.asm -o ./build/calc.bin -nasm -fbin src/fs/edit.asm -o ./build/edit.bin +# nasm -fbin src/fs/calc.asm -o ./build/calc.bin +# nasm -fbin src/fs/edit.asm -o ./build/edit.bin -cat ./build/calc.bin ./build/edit.bin > ./build/files.bin +# cat ./build/calc.bin ./build/edit.bin > ./build/files.bin # Final binary -cat ./build/boot.bin ./build/filetable.bin ./build/kernel.bin ./build/files.bin > ./build/temp.bin +cat ./build/boot.bin ./build/filetable.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 diff --git a/buildAsm.sh b/buildAsm.sh new file mode 100644 index 0000000..a63ba66 --- /dev/null +++ b/buildAsm.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +# Create ./build dir if it doesn't exist +if !(test -d ././build); then + mkdir ././build + echo "Created ./build/ directory!" +fi + +# Bootloader +nasm -fbin src/boot.asm -o ./build/boot.bin +nasm -fbin src/filetable.asm -o ./build/filetable.bin + +# Kernel +nasm -fbin src/kernel.asm -o ./build/kernel.bin + +# Programs +nasm -fbin src/fs/calc.asm -o ./build/calc.bin +nasm -fbin src/fs/edit.asm -o ./build/edit.bin + +cat ./build/calc.bin ./build/edit.bin > ./build/files.bin + +# 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!" + +# Run QEMU +echo "Running QEMU..." +qemu-system-x86_64 -drive format=raw,file="./build/kern.iso",index=0,media=disk -m 256M diff --git a/other/editor.png b/other/editor.png index c322030..d092915 100644 Binary files a/other/editor.png and b/other/editor.png differ diff --git a/src/boot.asm b/src/boot.asm index efeec90..aa488c3 100644 --- a/src/boot.asm +++ b/src/boot.asm @@ -2,6 +2,8 @@ [bits 16] [global start] +%define ENDL 0x0A, 0x0D + start: ; Setup xor ax, ax @@ -17,7 +19,7 @@ start: mov si, bootMsg call print mov dl, byte [driveNumber] - call printHex + call printHexByte mov si, newline call print @@ -84,13 +86,61 @@ readFail: cli hlt -%include "./src/lib/print.asm" +; +; 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 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 driveNumber: db 0 -bootMsg: db ENDL, "Booting kern.", ENDL, "Booting from drive ", 0 +bootMsg: db ENDL, "Booting kern.", ENDL, "Booting from drive 0x", 0 diskErrorMsg: db "Disk Error!", ENDL, 0 +newline: db ENDL + FILETAB_LOC equ 0x1000 KERNEL_LOC equ 0x2000