From d6dc33f1643e9ad5ea7a61eea3157716db698302 Mon Sep 17 00:00:00 2001 From: shikhin Date: Thu, 16 Mar 2023 15:40:03 +0530 Subject: [PATCH] Begin work on filesystem support --- Makefile | 2 +- filesystem.asm | 14 ++++ ponydos.asm | 171 +++++++++++++++++++++++++++++++++++++++++-------- 3 files changed, 158 insertions(+), 29 deletions(-) create mode 100644 filesystem.asm diff --git a/Makefile b/Makefile index ce40e01..94114bc 100644 --- a/Makefile +++ b/Makefile @@ -9,7 +9,7 @@ all: ponydos.img ponydos.img: ponydos.bin wallpaper.bin rw -i /dev/zero -o $@ -c 1440K rw -i ponydos.bin -o $@ - rw -i wallpaper.bin -o $@ -O 512 + rw -i wallpaper.bin -o $@ -O 1024 .asm.bin: $(NASM) -fbin -o $@ $< diff --git a/filesystem.asm b/filesystem.asm new file mode 100644 index 0000000..18edef4 --- /dev/null +++ b/filesystem.asm @@ -0,0 +1,14 @@ +; TODO: have tooling for this + +; 128 sector files, starting at 2 + +; dirent: +; 2 bytes size in 512B sectors, 0 for end of listing +; 30 bytes null-terminated name + +wallpaper: + dw 8 + db 'wallpaper.bin', 0 + times 512+32-($-$$) db 0 + +times 1024-($-$$) db 0 \ No newline at end of file diff --git a/ponydos.asm b/ponydos.asm index 3a9dc5e..1db5054 100644 --- a/ponydos.asm +++ b/ponydos.asm @@ -8,12 +8,14 @@ ROWS equ 25 WALLPAPER equ 0x500 +DIRENTS equ 0x2000 +DIRENT_SIZE equ 32 +FILE_MAX_SIZE equ 128 + jmp 0:start start: cld - cli - ; Set up segments and stack mov ax, cs mov ds, ax @@ -21,12 +23,10 @@ start: mov ss, ax mov sp, $$ - sti - ; Clear BSS + ;xor al, al mov di, _bss_start mov cx, _bss_end - _bss_start - xor al, al rep stosb mov [boot_disk], dl @@ -65,11 +65,11 @@ initialize_mouse: .done: load_wallpaper: - mov ax, 1 - mov bl, [boot_disk] - mov cx, 8 - mov di, WALLPAPER + mov si, wallpaper_name + call open_file + mov bx, WALLPAPER call read_sectors + ; TODO: error management? Surely this works... initialize_screen: ; Disable text cursor @@ -164,35 +164,31 @@ flip_mouse_cursor: ; in: ; ax = LBA of first sector -; bl = drive number +;; bl = drive number ; cx = number of sectors to read (must be at least 1) -; es:di = output buffer +; es:bx = output buffer read_sectors: push ax push cx - push di + push bx .loop: call read_sector inc ax - add di, 512 + add bx, 512 loop .loop - pop di + pop bx pop cx pop ax ret ; in: -; ax = LBA of first sector -; bl = drive number -; es:di = output buffer -read_sector: - push ax - push bx - push cx - push dx - +; ax = LBA of sector +; out: +; cx, dx = appropriately set for int 0x13 +; ax clobbered +prepare_geometry: mov cx, 18 div cx @@ -209,10 +205,19 @@ read_sector: mov ch, al ; dl = drive number - mov dl, bl + mov dl, [boot_disk] + ret - ; es:bx = output buffer - mov bx, di +; in: +; ax = LBA of first sector +;; bl = drive number, use [boot_disk] for now +; es:bx = output buffer +read_sector: + push ax + push cx + push dx + + call prepare_geometry .retry: mov ax, 0x0201 ; read one sector @@ -221,7 +226,6 @@ read_sector: pop dx pop cx - pop bx pop ax ret @@ -233,6 +237,112 @@ read_sector: int 0x10 jmp .retry +; in: +; ax = LBA of first sector +;; bl = drive number, use [boot_disk] for now +; es:bx = input buffer +write_sector: + push ax + push cx + push dx + + call prepare_geometry + + .retry: + mov ax, 0x0301 ; write one sector + int 0x13 + jc .error + + pop dx + pop cx + pop ax + ret + + .error: + xor ah, ah + int 0x10 + jmp .retry + +; ------------------------------------------------------------------ +; Filesystem +; ------------------------------------------------------------------ + +wallpaper_name: db 'wallpaper.bin', 0 + +; in: +; es:si = file name +; out: +; ax = LBA of first sector, 0 if no space left +; cx = length in sectors +open_file: + push si + push di + push bx + + ; Stolen from https://stackoverflow.com/a/72746473, get strlen in cx + mov di, si + mov cx, -1 + xor ax, ax + repne scasb + not cx + dec cx + + ;mov ax, 1 + mov al, 1 + mov bx, DIRENTS + call read_sector + + mov ax, 2 + mov di, bx + .loop: + cmp word [di], 0 + je .create_file + + inc di + inc di + + push cx + push di + push si + repe cmpsb + pop si + pop di + pop cx + je .success + + add ax, FILE_MAX_SIZE + add di, DIRENT_SIZE - 2 + cmp di, DIRENTS + 0x200 + jl .loop + + .error: + xor ax, ax + ; Return with mangled cx + .success: + mov cx, [di - 2] + .return: + pop bx + pop di + pop si + ret + + .create_file: + ; TODO: zero out the sector for this file? + inc word [di] + inc di + inc di + rep movsb + + push ax + mov ax, 1 + ;mov bx, DIRENTS + call write_sector + pop ax + + ;mov cx, 1 + mov cl, 1 + jmp .return + ; ------------------------------------------------------------------ ; Mouse callback ; ------------------------------------------------------------------ @@ -315,6 +425,7 @@ mouse_handler: ; Debug routines ; ------------------------------------------------------------------ +%if 0 hexprint16: xchg ah, al call hexprint8 @@ -347,15 +458,19 @@ hexprint4: hang: hlt jmp hang +%endif ; ------------------------------------------------------------------ ; Padding and boot sector signature ; ------------------------------------------------------------------ times 510-($-$$) db 0 + db 0x55 db 0xaa +%include "filesystem.asm" + ; ------------------------------------------------------------------ ; Zero-initialized variables ; ------------------------------------------------------------------ @@ -372,4 +487,4 @@ mouse_row resw 1 boot_disk resb 1 -_bss_end: +_bss_end: \ No newline at end of file