mirror of
https://github.com/Tom-on64/kern.git
synced 2026-11-03 18:22:22 +00:00
After C Switch
This commit is contained in:
@@ -1,32 +1,27 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Create ./build dir if it doesn't exist
|
[[ -d ./build ]] || mkdir build
|
||||||
if !(test -d ./build); then
|
|
||||||
mkdir ./build
|
rm -rf ./build/**
|
||||||
echo "Created ./build/ directory!"
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Bootloader
|
# Bootloader
|
||||||
nasm -fbin src/boot.asm -o ./build/boot.bin
|
nasm -fbin ./src/boot.asm -o ./build/boot.bin
|
||||||
nasm -fbin src/filetable.asm -o ./build/filetable.bin
|
|
||||||
|
|
||||||
# Kernel
|
# Kernel
|
||||||
nasm -fbin src/kernel.asm -o ./build/kernel.bin
|
nasm -felf32 ./src/kernel/entry.asm -o ./build/entry.o
|
||||||
|
|
||||||
# Programs
|
for file in ./src/kernel/**.c; do
|
||||||
nasm -fbin src/fs/calc.asm -o ./build/calc.bin
|
filename=$(basename "$file" .c)
|
||||||
nasm -fbin src/fs/edit.asm -o ./build/edit.bin
|
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
|
# OS Image
|
||||||
cat ./build/boot.bin ./build/filetable.bin ./build/kernel.bin ./build/files.bin > ./build/temp.bin
|
cat build/boot.bin build/kernel.bin > build/os.bin
|
||||||
dd if=/dev/zero of=./build/kern.iso bs=512 count=2880
|
dd if=/dev/zero of=./kern.iso bs=512 count=2880
|
||||||
dd if=./build/temp.bin of=./build/kern.iso conv=notrunc
|
dd if=./build/os.bin of=./kern.iso conv=notrunc
|
||||||
rm -rf ./build/**.bin
|
|
||||||
|
|
||||||
echo "Built kern.iso!"
|
|
||||||
|
|
||||||
# Run QEMU
|
# Run QEMU
|
||||||
echo "Running QEMU..."
|
qemu-system-x86_64 -drive format=raw,file="./kern.iso",index=0,media=disk -m 256M -accel tcg
|
||||||
qemu-system-x86_64 -drive format=raw,file="./build/kern.iso",index=0,media=disk -m 256M
|
|
||||||
|
|||||||
+119
-68
@@ -1,98 +1,149 @@
|
|||||||
[org 0x7c00]
|
|
||||||
[bits 16]
|
[bits 16]
|
||||||
|
[org 0x7c00]
|
||||||
[global start]
|
[global start]
|
||||||
|
|
||||||
|
%define KERNEL_LOC 0x1000
|
||||||
|
%define KERNEL_SIZE 20 ; 20 Sectors -> 10kB
|
||||||
|
%define ENDL 0x0a, 0x0d
|
||||||
|
%define VIDMEM 0xb800
|
||||||
|
|
||||||
start:
|
start:
|
||||||
; Setup
|
mov [driveNum], dl ; Store the drive number
|
||||||
|
|
||||||
|
; Set up the stack
|
||||||
xor ax, ax
|
xor ax, ax
|
||||||
mov es, ax
|
mov es, ax
|
||||||
mov ds, ax
|
mov ds, ax
|
||||||
mov bp, 0x7c00
|
mov bp, 0x7c00
|
||||||
mov sp, bp
|
mov sp, bp
|
||||||
|
|
||||||
; Save drive number
|
; Setup screen
|
||||||
mov byte [driveNumber], dl
|
mov ax, 3 ; 80x25 Text mode
|
||||||
|
int 0x10
|
||||||
|
mov ah, 1 ; Hide cursor
|
||||||
|
mov cx, 0x2607
|
||||||
|
int 0x10
|
||||||
|
|
||||||
; Print boot message
|
mov byte [0xb800], 'A'
|
||||||
mov si, bootMsg
|
.read:
|
||||||
call print
|
; Location
|
||||||
mov dl, byte [driveNumber]
|
mov bx, KERNEL_LOC
|
||||||
call printHex
|
|
||||||
mov si, newline
|
|
||||||
call print
|
|
||||||
|
|
||||||
; Read filetable from disk
|
; CHS Location
|
||||||
mov bx, FILETAB_LOC ; Filetable location in memory
|
mov al, KERNEL_SIZE
|
||||||
mov es, bx
|
mov ch, 0 ; Cylinder
|
||||||
xor bx, bx
|
mov dh, 0 ; Head
|
||||||
|
mov cl, 2 ; Sector
|
||||||
|
mov dl, [driveNum]
|
||||||
|
|
||||||
mov ah, 2 ; Read from disk
|
mov ah, 2 ; Read from disk
|
||||||
mov al, 1 ; Read 1 sector (512B)
|
int 0x13 ; Read interrupt
|
||||||
|
|
||||||
mov dl, byte [driveNumber] ; Drive number
|
jc .diskErr
|
||||||
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
|
cli
|
||||||
|
lgdt [GDT_Descriptor]
|
||||||
|
; Enable protected mode
|
||||||
|
mov eax, cr0
|
||||||
|
or eax, 1
|
||||||
|
mov cr0, eax
|
||||||
|
|
||||||
; Read filetable from disk
|
; Far jump to 32 bit mode!!
|
||||||
mov bx, KERNEL_LOC ; Filetable location in memory
|
jmp CODE_SEG:protected_start
|
||||||
mov es, bx
|
|
||||||
xor bx, bx
|
|
||||||
|
|
||||||
mov ah, 2 ; Read from disk
|
.diskErr:
|
||||||
mov al, 4 ; Read 4 sectors (2kB)
|
dec byte [counter]
|
||||||
|
jnz .read
|
||||||
|
|
||||||
mov dl, byte [driveNumber] ; Drive number
|
mov si, diskErrMsg
|
||||||
mov ch, 0 ; Cylinder
|
mov bl, 0x04
|
||||||
mov dh, 0 ; Head
|
call puts
|
||||||
mov cl, 3 ; Sector
|
|
||||||
int 0x13 ; INT 0x13 - Disk operations
|
|
||||||
|
|
||||||
jc readFail ; CF will be set if the read fails
|
cli
|
||||||
|
hlt
|
||||||
|
|
||||||
; Setup segmentation
|
;
|
||||||
mov ax, KERNEL_LOC
|
; Prints a string
|
||||||
mov ds, ax
|
; 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 es, ax
|
||||||
mov fs, ax
|
mov fs, ax
|
||||||
mov gs, ax
|
mov gs, ax
|
||||||
|
|
||||||
; Setup stack
|
; Set up the stack pointer in protected mode
|
||||||
mov bp, 0xffff
|
mov ebp, 0x90000
|
||||||
mov sp, bp
|
mov esp, ebp
|
||||||
mov ax, 0x9000
|
|
||||||
mov ss, ax
|
|
||||||
|
|
||||||
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
|
GDT_Descriptor:
|
||||||
mov ax, 0x0003
|
dw GDT_End - GDT_Start - 1 ; Size
|
||||||
int 0x10
|
dd GDT_Start ; GDT Pointer
|
||||||
mov ah, 0x0b
|
|
||||||
mov bx, 0x0001
|
|
||||||
int 0x10
|
|
||||||
|
|
||||||
; Far jump to the kernel (never returns)
|
CODE_SEG equ code_descriptor - GDT_Start
|
||||||
jmp KERNEL_LOC:0x0000
|
DATA_SEG equ data_descriptor - GDT_Start
|
||||||
|
|
||||||
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
|
times 510-($-$$) db 0
|
||||||
dw 0xaa55
|
dw 0xaa55
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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
@@ -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
@@ -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
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
[bits 32]
|
||||||
|
[global _start]
|
||||||
|
|
||||||
|
[extern main]
|
||||||
|
|
||||||
|
_start:
|
||||||
|
call main
|
||||||
|
cli
|
||||||
|
hlt
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
#include "screen.h"
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
print("Hello, World!", 0x0f);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -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
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
Binary file not shown.
@@ -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
|
|
||||||
Reference in New Issue
Block a user