From: Robert Pengelly Date: Mon, 5 Aug 2024 09:40:46 +0000 (+0100) Subject: Implemented mkdir X-Git-Url: https://git.candlhat.org/?a=commitdiff_plain;h=fd6310a0f64eeab1dd1dd22fd5a33287a265b316;p=chimaera.git Implemented mkdir --- diff --git a/build/chimaera.img b/build/chimaera.img index b02386d..c8767c1 100644 Binary files a/build/chimaera.img and b/build/chimaera.img differ diff --git a/build/chimaera.vhd b/build/chimaera.vhd index 98393de..38de489 100644 Binary files a/build/chimaera.vhd and b/build/chimaera.vhd differ diff --git a/src/Makefile.unix b/src/Makefile.unix index 2f65ea2..5fc7711 100644 --- a/src/Makefile.unix +++ b/src/Makefile.unix @@ -34,9 +34,12 @@ chimaera.img: all chimaera.vhd: all if [ -f $@ ]; then rm -rf $@; fi +# utils/parted/parted --arca --boot boot/mbr/dosmbr.bin mkpart 128,06,17,65535 $@ +# utils/dosfstools/mkdosfs --arca --boot boot/freeldr/bootsect/fat16.bin --offset 17 --sectors 65535 -F 16 -n "CHIMAERA OS" $@ + utils/parted/parted --arca --boot boot/mbr/dosmbr.bin mkpart 128,11,17,66623 $@ utils/dosfstools/mkdosfs --arca --boot boot/freeldr/bootsect/fat32_chs.bin --offset 17 --sectors 66623 -F 32 -n "CHIMAERA OS" $@ - + utils/dosfstools/mmd --arca --offset 17 -i $@ boot boot/freeldr utils/dosfstools/mcopy --arca --offset 17 -i $@ $(SRCDIR)/boot/freeldr/freeldr.cfg ::/boot/freeldr/ diff --git a/src/Makefile.w32 b/src/Makefile.w32 index ce995b5..9b4bec3 100644 --- a/src/Makefile.w32 +++ b/src/Makefile.w32 @@ -33,7 +33,7 @@ chimaera.img: all chimaera.vhd: all if exist $@ ( del /q $@ ) - utils/parted/parted --arca --boot boot/mbr/dosmbr.bin mkpart 128,11,17,65535 $@ + utils/parted/parted --arca --boot boot/mbr/dosmbr.bin mkpart 128,06,17,65535 $@ utils/dosfstools/mkdosfs --arca --boot boot/freeldr/bootsect/fat16.bin --offset 17 --sectors 65535 -F 16 -n "CHIMAERA OS" $@ utils/dosfstools/mmd --arca --offset 17 -i $@ boot boot/freeldr diff --git a/src/apps/hello/hello.asm b/src/apps/hello/hello.asm index f477f8e..cea0de6 100644 --- a/src/apps/hello/hello.asm +++ b/src/apps/hello/hello.asm @@ -16,20 +16,41 @@ _main: call _writestr call _crlf - mov ah, HEX (08) +; mov ah, HEX (08) +; int HEX (21) +; +; call _writehex +; call _crlf +; +; mov ah, HEX (07) +; int HEX (21) +; +; call _writehex +; call _crlf +; +; xor ax, ax +; int HEX (16) + + mov ah, HEX (39) + mov dx, offset _dir_non_exist int HEX (21) call _writehex call _crlf - mov ah, HEX (07) + mov ah, HEX (39) + mov dx, offset _dir_exist int HEX (21) call _writehex call _crlf - xor ax, ax - int HEX (16) + mov ah, HEX (39) + mov dx, offset _dir_file + int HEX (21) + + call _writehex + call _crlf xor ax, ax ret @@ -38,3 +59,7 @@ _main: ;; Data area. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; msg_hello: db "Hello, world!", HEX (0D), HEX (0A), HEX (00) + +_dir_non_exist: db "abc\\123", HEX (00) +_dir_exist: db "temp", HEX (00) +_dir_file: db "hello.com", HEX (00) diff --git a/src/apps/pcomm/Makefile.unix b/src/apps/pcomm/Makefile.unix index ddb3cc1..7edf7ba 100644 --- a/src/apps/pcomm/Makefile.unix +++ b/src/apps/pcomm/Makefile.unix @@ -46,7 +46,7 @@ genver: genver.c gcc -o $@ $^ endif -pcomm.com: ../../lib/crt/crt0.o cbreak.o cd.o crlf.o date.o dir.o erase.o exit.o history.o pcomm.o time.o type.o vector.o writedec.o writehex.o writestr.o xmalloc.o xstrcpy.o ../../lib/crt/libc.a +pcomm.com: ../../lib/crt/crt0.o cbreak.o cd.o crlf.o date.o dir.o erase.o exit.o history.o mkdir.o pcomm.o time.o type.o vector.o writedec.o writehex.o writestr.o xmalloc.o xstrcpy.o ../../lib/crt/libc.a ../../utils/binutils/slink --oformat msdos -o $@ $^ %.o: %.asm diff --git a/src/apps/pcomm/Makefile.w32 b/src/apps/pcomm/Makefile.w32 index 176b539..4a11f17 100644 --- a/src/apps/pcomm/Makefile.w32 +++ b/src/apps/pcomm/Makefile.w32 @@ -30,7 +30,7 @@ genhash.exe: genhash.c genver.exe: genver.c gcc -o $@ $^ -pcomm.com: ../../lib/crt/crt0.o cbreak.o cd.o crlf.o date.o dir.o erase.o exit.o history.o pcomm.o time.o type.o vector.o writedec.o writestr.o xmalloc.o xstrcpy.o ../../lib/crt/libc.a +pcomm.com: ../../lib/crt/crt0.o cbreak.o cd.o crlf.o date.o dir.o erase.o exit.o history.o mkdir.o pcomm.o time.o type.o vector.o writedec.o writehex.o writestr.o xmalloc.o xstrcpy.o ../../lib/crt/libc.a ../../utils/binutils/slink --oformat msdos -o $@ $^ %.o: %.asm diff --git a/src/apps/pcomm/dir.asm b/src/apps/pcomm/dir.asm index 2e4a9d5..8a86bf5 100644 --- a/src/apps/pcomm/dir.asm +++ b/src/apps/pcomm/dir.asm @@ -72,7 +72,7 @@ _handler_dir.got_path: mov bx, offset _cmdline -_handler_dir.store_file: +_handler_dir.store_arg: cmp byte ptr [bx], 0 je _handler_dir.check2 @@ -111,7 +111,7 @@ _handler_dir.skip: je _handler_dir.check2 cmp byte ptr [bx], ' ' - ja _handler_dir.store_file + ja _handler_dir.store_arg inc bx jmp _handler_dir.skip diff --git a/src/apps/pcomm/mkdir.asm b/src/apps/pcomm/mkdir.asm new file mode 100644 index 0000000..416d917 --- /dev/null +++ b/src/apps/pcomm/mkdir.asm @@ -0,0 +1,189 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; @file mkdir.asm +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%ifndef HEX +% define HEX(y) 0x##y +%endif + +;****************************************************************************** +; @function _handler_mkdir +;****************************************************************************** +global _handler_mkdir +_handler_mkdir: + + push bp + + mov bp, sp + sub sp, 4 + + push ax + push bx + push cx + push dx + push si + push di + push es + push ds + + mov word ptr [bp - 4], 0 + mov word ptr [bp - 2], 0 + + cmp byte ptr [bx], 0 + jne _handler_mkdir.ok + + mov bx, offset _err_invalid + call _writestr + + jmp _handler_mkdir.done + +_handler_mkdir.ok: + + push bx + + call _strlen + add sp, 2 + + mov di, offset _cmdline + mov si, bx + + mov cx, ax + rep movsb + + xor al, al + stosb + + mov bx, offset _cmdline + +_handler_mkdir.store_arg: + + cmp byte ptr [bx], 0 + je _handler_mkdir.next + + mov si, bx + push si + + mov ax, offset _vec_files + push ax + + call _vec_push + add sp, 4 + +_handler_mkdir.check: + + mov ax, ' ' + push ax + + mov si, bx + push si + + call _strchr + add sp, 4 + + and ax, ax + jz _handler_mkdir.next + + mov bx, ax + mov byte ptr [bx], 0 + + inc bx + +_handler_mkdir.skip: + + cmp byte ptr [bx], 0 + je _handler_mkdir.next + + cmp byte ptr [bx], ' ' + ja _handler_mkdir.store_arg + + inc bx + jmp _handler_mkdir.skip + +_handler_mkdir.next: + + mov ax, word ptr [bp - 4] + inc ax + + cmp ax, cs:[_vec_files + 4] + ja _handler_mkdir.cleanup + + mov word ptr [bp - 4], ax + dec ax + + xor dx, dx + + mov cx, 2 + mul cx + + mov bx, ax + push es + + mov ax, cs:[_vec_files + 0] + mov es, ax + + mov ax, es:[bx] + mov bx, ax + + pop es + +_handler_mkdir.open: + + mov ah, HEX (39) + mov dx, bx + int HEX (21) + jnc _handler_mkdir.next + +_handler_mkdir.error: + + push bx + + mov bx, offset _err_failed + call _writestr + + pop bx + + call _writestr + call _crlf + + jmp _handler_mkdir.next + +_handler_mkdir.cleanup: + + mov ax, cs:[_vec_files + 0] + push ax + + call _free + add sp, 2 + + mov ax, cs + mov es, ax + + mov di, offset _vec_files + xor al, al + + mov cx, 6 + rep stosb + +_handler_mkdir.done: + + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax + + add sp, 4 + pop bp + + ret + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Data area. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +_vec_files: db 6 dup (0) +_cmdline: db 256 dup (0) + +_err_invalid: db "Invalid number of parameters", HEX (0D), HEX (0A), HEX (00) +_err_failed: db "Unable to create directory - ", HEX (00) diff --git a/src/apps/pcomm/pcomm.asm b/src/apps/pcomm/pcomm.asm index 703de21..e2aea7b 100644 --- a/src/apps/pcomm/pcomm.asm +++ b/src/apps/pcomm/pcomm.asm @@ -253,6 +253,31 @@ _main: call _strlen add sp, 2 + add bx, ax + +.L54: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If there was no string then we skip the following code. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + and ax, ax + jz .L55 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If the last character is not an asterisk then we have the + ;; right length. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp byte ptr [bx - 1], '*' + jne .L55 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Otherwise, decrement ax by one as our command line doesn't + ;; have the asterisk character. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + dec ax + +.L55: + mov bx, ax jmp .L41 @@ -1048,6 +1073,7 @@ _handler_help.msg: db "DIR Displays a list of files and subdirectories in a directory.", HEX (0D), HEX (0A) db "ECHO Specifies the text to display to the screen.", HEX (0D), HEX (0A) db "EXIT Exit the current shell if it's not the last instance.", HEX (0D), HEX (0A) + db "MKDIR Create a new directory.", HEX (0D), HEX (0A) db "REBOOT Reboots the machine.", HEX (0D), HEX (0A) db "TIME Displays the system time.", HEX (0D), HEX (0A) db "TYPE Displays the contents of a text file.", HEX (0D), HEX (0A) @@ -1267,6 +1293,10 @@ _cmd_table: dw 0 dw _handler_help + dw hash_mkdir + dw 0 + dw _handler_mkdir + dw hash_reboot dw 0 dw _handler_reboot diff --git a/src/apps/pcomm/type.asm b/src/apps/pcomm/type.asm index 4d504cf..da8d569 100644 --- a/src/apps/pcomm/type.asm +++ b/src/apps/pcomm/type.asm @@ -54,7 +54,7 @@ _handler_type.ok: mov bx, offset _cmdline -_handler_type.store_file: +_handler_type.store_arg: cmp byte ptr [bx], 0 je _handler_type.next @@ -93,7 +93,7 @@ _handler_type.skip: je _handler_type.next cmp byte ptr [bx], ' ' - ja _handler_type.store_file + ja _handler_type.store_arg inc bx jmp _handler_type.skip @@ -177,12 +177,6 @@ _handler_type.file_open: _handler_type.clear_and_read: - mov di, offset _buffer - xor al, al - - mov cx, 256 - rep stosb - mov ah, HEX (3F) mov cx, 255 mov dx, offset _buffer @@ -192,15 +186,13 @@ _handler_type.clear_and_read: and ax, ax jz _handler_type.close - mov si, offset _buffer + mov si, dx + mov cx, ax _handler_type.print_loop: lodsb - and al, al - jz _handler_type.clear_and_read - cmp al, HEX (0A) jne _handler_type.char_ok @@ -218,7 +210,12 @@ _handler_type.char_ok: mov dl, al int HEX (21) - jmp _handler_type.print_loop + dec cx + jnz _handler_type.print_loop + +_handler_type.read_done: + + jmp _handler_type.clear_and_read _handler_type.close: diff --git a/src/kernel/Makefile.unix b/src/kernel/Makefile.unix index 8be5e8a..ec98783 100644 --- a/src/kernel/Makefile.unix +++ b/src/kernel/Makefile.unix @@ -13,7 +13,7 @@ clean: for f in *.lst; do if [ -f $$f ]; then rm -rf $$f; fi; done if [ -f kernel.sys ]; then rm -rf kernel.sys; fi -kernel.sys: bootstrap.o crlf.o disk.o divide.o error.o fat.o file.o find.o int21.o int23.o invalid.o kernel.o kmalloc.o krealloc.o mangle.o mem.o prog.o query.o search.o vector.o walk.o writechr.o writedec.o writehex.o writestr.o ../lib/crt/libc.a +kernel.sys: bootstrap.o crlf.o disk.o divide.o error.o fat.o file.o find.o int21.o int23.o invalid.o kernel.o kmalloc.o krealloc.o make.o mangle.o mem.o prog.o query.o search.o vector.o walk.o writechr.o writedec.o writehex.o writestr.o ../lib/crt/libc.a ../utils/binutils/slink --oformat binary -o $@ $^ %.o: %.asm diff --git a/src/kernel/Makefile.w32 b/src/kernel/Makefile.w32 index d444a13..202bd39 100644 --- a/src/kernel/Makefile.w32 +++ b/src/kernel/Makefile.w32 @@ -13,7 +13,7 @@ clean: for %%f in (*.lst) do ( if exist %%f ( del /q %%f ) ) if exist kernel.sys ( del /q kernel.sys ) -kernel.sys: bootstrap.o crlf.o disk.o divide.o error.o fat.o file.o int21.o int23.o invalid.o kernel.o kmalloc.o krealloc.o mangle.o mem.o prog.o query.o search.o vector.o walk.o writechr.o writedec.o writehex.o writestr.o ../lib/crt/libc.a +kernel.sys: bootstrap.o crlf.o disk.o divide.o error.o fat.o file.o find.o int21.o int23.o invalid.o kernel.o kmalloc.o krealloc.o make.o mangle.o mem.o prog.o query.o search.o vector.o walk.o writechr.o writedec.o writehex.o writestr.o ../lib/crt/libc.a ../utils/binutils/slink --oformat binary -o $@ $^ %.o: %.asm diff --git a/src/kernel/disk.asm b/src/kernel/disk.asm index 64fba99..ded082d 100644 --- a/src/kernel/disk.asm +++ b/src/kernel/disk.asm @@ -139,7 +139,7 @@ _get_partition_info: ;; Set the base pointer to the stack pointer and reserve some space. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov bp, sp - sub sp, 24 + sub sp, 26 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Preserve registers. @@ -167,6 +167,7 @@ _get_partition_info: mov word ptr [bp - 20], 0 mov word ptr [bp - 22], 0 mov word ptr [bp - 24], 0 + mov word ptr [bp - 26], 0 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; MBR partitions start at offset 0x01BE and are 16 bytes in length. @@ -259,6 +260,9 @@ _get_partition_info: cmp byte ptr es:[bx + 1], HEX (58) jne .L12 + mov ax, es:[bx + 48] + mov word ptr [bp - 26], ax + mov ax, es:[bx + 44] mov dx, es:[bx + 46] @@ -484,6 +488,9 @@ _get_partition_info: mov ax, word ptr [bp - 20] stosw + mov ax, word ptr [bp - 26] + stosw + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Get drive parameters. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -533,14 +540,14 @@ _get_partition_info: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Clear the carry flag. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - add sp, 24 + add sp, 26 clc jmp .L20 .L22: - add sp, 24 + add sp, 26 stc .L20: @@ -952,6 +959,221 @@ _read_sectors.done: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ret +;****************************************************************************** +; @function _write_sectors +;****************************************************************************** +global _write_sectors +_write_sectors: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the registers that will get clobbered. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push bx + push cx + push si + push di + push es + +_write_sectors.next: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; The di regsiter will be our retry counter. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov di, HEX (0005) + +_write_sectors.retry: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the ax, cx and dx registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push ax + push cx + push dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If disk extensions aren't avaiable then we need to use CHS. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp word ptr cs:[_edd_available], 1 + jb _write_sectors.chs + +_write_sectors.lba: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; We'll create the LBA write on the stack. 8086 doesn't allow pushing + ;; values directly so we'll use si. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor si, si + push si + push si + + push dx + push ax + push es + push bx + + mov si, 1 + push si + + mov si, 16 + push si + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; The dl register needs to be set to the drive number before we alter + ;; the data segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov dl, cs:[_drive_no] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; We need to set si to sp as the LBA write requires ds:si. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov si, sp + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the data segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push ds + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve the ax and dx registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push ax + push dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Initialize the data segment to the stack segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push ss + pop ds + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; write the sector into memory. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ah, HEX (43) + stc + int HEX (13) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the ax and dx registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop dx + pop ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the data segment. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop ds + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Cleanup the stack. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add sp, 16 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If there was no carry the we successfully write the sector. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + jnc _write_sectors.success + +_write_sectors.chs: + + div word ptr cs:[_sectors_per_track] + ; ax = LBA / SPT + ; dx = LBA # SPT = sector - 1 + + mov cx, dx + inc cx + ; cx = sector no. + + xor dx, dx + div word ptr cs:[_heads_per_cylinder] + ; ax = (LBA / SPT) / HPC = cylinder + ; dx = (LBA / SPT) # HPC = head + + mov ch, al + ; ch = LSB 0...7 of cylinder no. + ror ah + ror ah + or cl, ah + ; cl = MSB 8...9 of cylinder no. + sector no. + mov dh, dl + ; dh = head no. + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; write the sector into es:bx. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, HEX (0301) + mov dl, cs:[_drive_no] + stc + int HEX (13) + jnc _write_sectors.success + +_write_sectors.failure: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Reset the disk. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor ah, ah + mov dl, cs:[_drive_no] + int HEX (13) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the ax, cx and dx registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop dx + pop cx + pop ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Decrement the loop counter and retry if greater than zero. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + dec di + jnz _write_sectors.retry + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Invoke the BIOS. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + int HEX (18) + +_write_sectors.success: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Add the bytes per sector to bx to get the next offset to write in to. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add bx, cs:[_bytes_per_sector] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the ax, cx and dx registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop dx + pop cx + pop ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Advance to the next sector. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + add ax, 1 + adc dx, 0 + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Loop until cx is zero. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + loop _write_sectors.next + +_write_sectors.done: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the registers that got clobbered. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop es + pop di + pop si + pop cx + pop bx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Return to caller. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ret + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Data area. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/src/kernel/fat.asm b/src/kernel/fat.asm index 7053b0c..4703318 100644 --- a/src/kernel/fat.asm +++ b/src/kernel/fat.asm @@ -10,6 +10,49 @@ ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; %include "fat.inc" +;****************************************************************************** +; @function _calculate_total +;****************************************************************************** +_calculate_total: + + push cx + push si + + mov ax, cs:[_total_sectors16] + xor dx, dx + + and ax, ax + jnz _calculate_total.have_secs + + mov ax, cs:[_total_sectors32] + mov dx, cs:[_total_sectors32 + 2] + +_calculate_total.have_secs: + + sub ax, cs:[_data_start] + sbb dx, cs:[_data_start + 2] + + xor ch, ch + mov cl, cs:[_sectors_per_cluster] + + xor si, si + push si + + push si + push cx + push dx + push ax + + call _udivmodsi4 + add sp, 10 + +_calculate_total.done: + + pop si + pop cx + ret + + ;****************************************************************************** ; @function _convert_cluster12 ;****************************************************************************** @@ -110,9 +153,448 @@ _convert_cluster32.c3: add dx, cx - add ax, cs:[_data_start] - adc dx, cs:[_data_start + 2] + add ax, cs:[_data_start] + adc dx, cs:[_data_start + 2] + + ret + +;****************************************************************************** +; @function _find_free12 +;****************************************************************************** +global _find_free12 +_find_free12: + + push bp + + mov bp, sp + sub sp, 2 + + push bx + push cx + push si + push di + push es + + mov ax, cs:[_fat_seg] + mov es, ax + + call _calculate_total + + mov si, ax + mov di, dx + + mov ax, 2 + xor dx, dx + +_find_free12.loop: + + mov bx, si + or bx, cx + + and bx, bx + jz _find_free12.error + + push ax + push dx + push si + push cx + + mov si, ax + + mov ax, 3 + mul si + + shr ax + pushf + + mov cx, cs:[_bytes_per_sector] + shl cx + + xor dx, dx + div cx + + push dx + xchg si, ax + + mov ax, cs:[_fat_start] + mov dx, cs:[_fat_start + 2] + + add ax, si + adc dx, 0 + + xor bx, bx + + cmp ax, cs:[_fat_sector] + jne _find_free12.read + + cmp dx, cs:[_fat_sector + 2] + je _find_free12.check + +_find_free12.read: + + mov cs:[_fat_sector], ax + mov cs:[_fat_sector + 2], dx + + mov cx, 2 + call _read_sectors + +_find_free12.check: + + pop si + popf + pop cx + + push ds + mov ax, es + mov ds, ax + mov ax, [si] + pop ds + jnc _find_free12.even_cluster + + mov cl, 4 + shr ax, cl + +_find_free12.even_cluster: + + and ax, HEX (0FFF) + + xor dx, dx + pop si + + mov bx, ax + or bx, dx + + and bx, bx + jnz _find_free12.next + + pop dx + pop ax + + jmp _find_free12.done + +_find_free12.next: + + pop dx + pop ax + + add ax, 1 + adc dx, 0 + + sub si, 1 + sbb di, 0 + + jmp _find_free12.loop + +_find_free12.error: + + pop es + pop di + pop si + pop cx + pop bx + + add sp, 2 + pop bp + + stc + ret + +_find_free12.done: + + pop es + pop di + pop si + pop cx + pop bx + + add sp, 2 + pop bp + + clc + ret + +;****************************************************************************** +; @function _find_free16 +;****************************************************************************** +global _find_free16 +_find_free16: + + push bp + + mov bp, sp + sub sp, 2 + + push bx + push cx + push si + push di + push es + + mov ax, cs:[_fat_seg] + mov es, ax + + call _calculate_total + + mov si, ax + mov di, dx + + mov ax, 2 + xor dx, dx + +_find_free16.loop: + + mov bx, si + or bx, cx + + and bx, bx + jz _find_free16.error + + push ax + push dx + push si + push cx + + shl ax + pushf + + mov cx, cs:[_bytes_per_sector] + shl cx + + xor dx, dx + div cx + + push dx + xchg si, ax + + mov ax, cs:[_fat_start] + mov dx, cs:[_fat_start + 2] + + add ax, si + adc dx, 0 + + xor bx, bx + + cmp ax, cs:[_fat_sector] + jne _find_free16.read + + cmp dx, cs:[_fat_sector + 2] + je _find_free16.check + +_find_free16.read: + + mov cs:[_fat_sector], ax + mov cs:[_fat_sector + 2], dx + + mov cx, 2 + call _read_sectors + +_find_free16.check: + + pop si + popf + pop cx + + mov ax, cs:[_fat_seg] + jnc _find_free16.first64 + + add ax, HEX (1000) + +_find_free16.first64: + + push ds + mov ds, ax + mov ax, [si] + pop ds + + xor dx, dx + pop si + + mov bx, ax + or bx, dx + + and bx, bx + jnz _find_free16.next + + pop dx + pop ax + + jmp _find_free16.done + +_find_free16.next: + + pop dx + pop ax + + add ax, 1 + adc dx, 0 + + sub si, 1 + sbb di, 0 + + jmp _find_free16.loop + +_find_free16.error: + + pop es + pop di + pop si + pop cx + pop bx + + add sp, 2 + pop bp + + stc + ret + +_find_free16.done: + + pop es + pop di + pop si + pop cx + pop bx + + add sp, 2 + pop bp + + clc + ret + +;****************************************************************************** +; @function _find_free32 +;****************************************************************************** +global _find_free32 +_find_free32: + + push bp + + mov bp, sp + sub sp, 2 + + push bx + push cx + push si + push di + push es + + mov ax, cs:[_fat_seg] + mov es, ax + + call _calculate_total + + mov si, ax + mov di, dx + + mov ax, 2 + xor dx, dx + +_find_free32.loop: + + mov bx, si + or bx, cx + + and bx, bx + jz _find_free32.error + + push ax + push dx + push di + push cx + + mov di, ax + + and di, cs:[_fat_secmask] + mov cx, cs:[_fat_secshift] + +_find_free32.cn_loop: + + shr dx + rcr ax + loop _find_free32.cn_loop + + shl di + shl di + mov word ptr [bp - 2], di + + pop cx + + add ax, cs:[_fat_start] + adc dx, cs:[_fat_start + 2] + + xor bx, bx + + cmp ax, cs:[_fat_sector] + jne _find_free32.read + + cmp dx, cs:[_fat_sector + 2] + je _find_free32.check + +_find_free32.read: + + mov cs:[_fat_sector], ax + mov cs:[_fat_sector + 2], dx + + mov cx, 2 + call _read_sectors + +_find_free32.check: + + mov ax, es:[di] + mov dx, es:[di + 2] + + pop di + + mov bx, ax + or bx, dx + + and bx, bx + jnz _find_free32.next + + pop dx + pop ax + + jmp _find_free32.done + +_find_free32.next: + + pop dx + pop ax + + add ax, 1 + adc dx, 0 + + sub si, 1 + sbb di, 0 + + jmp _find_free32.loop + +_find_free32.error: + + pop es + pop di + pop si + pop cx + pop bx + + add sp, 2 + pop bp + + stc + ret + +_find_free32.done: + + pop es + pop di + pop si + pop cx + pop bx + + add sp, 2 + pop bp + clc ret ;****************************************************************************** @@ -195,9 +677,15 @@ _getfattype.fat12: mov ax, offset _convert_cluster12 mov cs:[_convert_cluster], ax + mov ax, offset _find_free12 + mov cs:[_find_free], ax + mov ax, offset _nextcluster_fat12 mov cs:[_next_cluster], ax + mov ax, offset _update_cluster12 + mov cs:[_update_cluster], ax + jmp short _getfattype.done _getfattype.fat16: @@ -205,8 +693,14 @@ _getfattype.fat16: mov ax, offset _convert_cluster16 mov cs:[_convert_cluster], ax + mov ax, offset _find_free16 + mov cs:[_find_free], ax + mov ax, offset _nextcluster_fat16 mov cs:[_next_cluster], ax + + mov ax, offset _update_cluster16 + mov cs:[_update_cluster], ax _getfattype.done: @@ -479,6 +973,309 @@ _nextcluster_fat32.no_carry: clc ret +;****************************************************************************** +; @function _update_cluster12 +;****************************************************************************** +global _update_cluster12 +_update_cluster12: + + push ax + push bx + push cx + push dx + push si + push di + push es + + mov si, ax + mov di, cx + + mov ax, 3 + mul si + shr ax + + push cx + pushf + + mov cx, cs:[_bytes_per_sector] + shl cx + + xor dx, dx + div cx + + push dx + xchg si, ax + +_update_cluster12.read: + + mov bx, cs:[_fat_seg] + mov es, bx + xor bx, bx + + mov ax, cs:[_fat_start] + mov dx, cs:[_fat_start + 2] + + add ax, si + adc dx, 0 + + push ax + push dx + + mov cx, 2 + call _read_sectors + + pop dx + pop ax + + and di, HEX (0FFF) + + pop si + popf + pop cx + + push ax + push dx + + mov cx, es:[si] + jnc _update_cluster12.even + + shl di + shl di + shl di + shl di + mov ax, di + + and cl, HEX (0F) + or al, cl + + jmp _update_cluster12.update + +_update_cluster12.even: + + mov ax, di + + and ch, HEX (F0) + or ah, ch + +_update_cluster12.update: + + mov es:[si], ax + pop dx + pop ax + + mov cx, cs:[_sectors_per_fat] + call _write_sectors + + mov cx, cs:[_sectors_per_fat] + call _write_sectors + +_update_cluster12.done: + + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax + ret + +;****************************************************************************** +; @function _update_cluster16 +;****************************************************************************** +global _update_cluster16 +_update_cluster16: + + push ax + push bx + push cx + push dx + push si + push di + push es + + mov di, cx + shl ax + + push cx + pushf + + mov cx, cs:[_bytes_per_sector] + shl cx + + xor dx, dx + div cx + + push dx + xchg si, ax + +_update_cluster16.read: + + mov bx, cs:[_fat_seg] + mov es, bx + xor bx, bx + + mov ax, cs:[_fat_start] + mov dx, cs:[_fat_start + 2] + + add ax, si + adc dx, 0 + + push ax + push dx + + mov cx, 2 + call _read_sectors + + pop dx + pop ax + pop si + popf + pop cx + + push ax + push dx + + mov ax, es + jnc _update_cluster16.first64 + + add ax, HEX (1000) + +_update_cluster16.first64: + + push ds + mov ds, ax + mov [si], di + pop ds + + mov cx, 2 + + cmp cs:[_sectors_per_fat], cx + jae _update_cluster16.update + + mov cx, 1 + +_update_cluster16.update: + + pop dx + pop ax + + push ax + push dx + call _write_sectors + + pop dx + pop ax + + add ax, cs:[_sectors_per_fat] + adc dx, 0 + + call _write_sectors + +_update_cluster16.done: + + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax + ret + +;****************************************************************************** +; @function _update_cluster32 +;****************************************************************************** +global _update_cluster32 +_update_cluster32: + + push ax + push bx + push cx + push dx + push si + push di + push es + + push bx + push cx + + mov di, ax + + and di, cs:[_fat_secmask] + mov cx, cs:[_fat_secshift] + +_update_cluster32.cn_loop: + + shr dx + rcr ax + loop _update_cluster32.cn_loop + + pop cx + pop si + + shl di + shl di + + add ax, cs:[_fat_start] + adc dx, cs:[_fat_start + 2] + + push ax + push dx + push cx + + mov bx, cs:[_fat_seg] + mov es, bx + xor bx, bx + + mov cx, 1 + call _read_sectors + + and si, HEX (0FFF) + pop cx + + mov es:[di], cx + mov es:[di + 2], si + +_update_cluster32.update: + + pop dx + pop ax + + mov si, ax + mov di, dx + + mov cx, 1 + call _write_sectors + + mov ax, cs:[_data_start] + mov dx, cs:[_data_start + 2] + + sub ax, cs:[_fat_start] + sbb dx, cs:[_fat_start + 2] + + xor ch, ch + mov cl, cs:[_number_of_fats] + + div cx + + add ax, si + adc dx, di + + mov cx, 1 + call _write_sectors + +_update_cluster32.done: + + pop es + pop di + pop si + pop dx + pop cx + pop bx + pop ax + ret + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Data area. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -488,9 +1285,15 @@ _fat_bpb: db 25 dup (0) global _convert_cluster _convert_cluster: dw HEX (0000) +global _find_free +_find_free: dw HEX (0000) + global _next_cluster _next_cluster: dw HEX (0000) +global _update_cluster +_update_cluster: dw HEX (0000) + global _fat_seg _fat_seg: dw HEX (0000) @@ -500,6 +1303,9 @@ _fat_secmask: dw HEX (0000) global _fat_secshift _fat_secshift: dw HEX (0000) +global _info_sector +_info_sector: dw HEX (0000) + global _curr_cluster _curr_cluster: diff --git a/src/kernel/file.asm b/src/kernel/file.asm index f728c17..ac14024 100644 --- a/src/kernel/file.asm +++ b/src/kernel/file.asm @@ -77,7 +77,7 @@ _read_cluster.read: xor ch, ch mov cl, es:[si + 6] - mov bx, es:[si + 68] + mov bx, es:[si + 70] mov es, bx xor bx, bx @@ -127,8 +127,8 @@ _getc: _getc.is_eof: - mov ax, es:[si + 64] - mov dx, es:[si + 66] + mov ax, es:[si + 66] + mov dx, es:[si + 68] mov cx, ax @@ -137,27 +137,27 @@ _getc.is_eof: _getc.check: - cmp dx, es:[si + 62] + cmp dx, es:[si + 64] ja _getc.check2 - cmp dx, es:[si + 62] + cmp dx, es:[si + 64] jne _getc.done - cmp ax, es:[si + 60] + cmp ax, es:[si + 62] jbe _getc.done _getc.check2: - mov ax, es:[si + 60] - mov dx, es:[si + 62] + mov ax, es:[si + 62] + mov dx, es:[si + 64] mov cx, es:[si + 50] div cx - cmp word ptr es:[si + 52], 0 + cmp word ptr es:[si + 54], 0 je _getc.check_offset - mov word ptr es:[si + 52], 0 + mov word ptr es:[si + 54], 0 jmp short _getc.read _getc.check_offset: @@ -167,31 +167,29 @@ _getc.check_offset: _getc.read: - mov bx, es:[si + 56] - mov cx, es:[si + 58] + mov bx, es:[si + 58] + mov cx, es:[si + 60] call _read_cluster _getc.loaded: push es - mov bx, es:[si + 68] + mov bx, es:[si + 70] mov es, bx mov bx, dx mov al, es:[bx] mov bx, ds mov es, bx - stosb - - mov bx, es - mov ds, bx + stosb pop es + inc word ptr [bp - 2] - add word ptr es:[si + 60], 1 - adc word ptr es:[si + 62], 0 + add word ptr es:[si + 62], 1 + adc word ptr es:[si + 64], 0 _getc.done: @@ -714,6 +712,9 @@ _open_file.got_handle: mov ax, cs:[_clustsize] stosw + mov ax, cs:[_info_sector] + stosw + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Store the value 1 as the first word to indicate that we need ;; to be read @@ -905,7 +906,7 @@ _read_file: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Make sure we're not write-only. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - cmp word ptr es:[si + 54], 1 + cmp word ptr es:[si + 56], 1 je _read_file.error ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -915,6 +916,9 @@ _read_file: _read_file.loop: + and cx, cx + jz _read_file.done + call _getc jc _read_file.error @@ -922,7 +926,9 @@ _read_file.loop: jz _read_file.done inc word ptr [bp - 2] - loop _read_file.loop + + dec cx + jnz _read_file.loop _read_file.done: @@ -1077,25 +1083,25 @@ _seek_file.beginning: xor ax, ax - mov es:[si + 60], ax mov es:[si + 62], ax + mov es:[si + 64], ax jmp short _seek_file.offset _seek_file.end: - mov ax, es:[si + 64] - mov es:[si + 60], ax - mov ax, es:[si + 66] mov es:[si + 62], ax + + mov ax, es:[si + 68] + mov es:[si + 64], ax _seek_file.offset: - mov ax, es:[si + 60] + mov ax, es:[si + 62] add ax, cx - mov di, es:[si + 62] + mov di, es:[si + 64] adc di, dx cmp di, 0 @@ -1106,15 +1112,15 @@ _seek_file.offset: _seek_file.ptr_ok: - mov es:[si + 60], ax - mov es:[si + 62], di + mov es:[si + 62], ax + mov es:[si + 64], di _seek_file.done: mov word ptr es:[si + 52], 1 - mov ax, es:[si + 60] - mov dx, es:[si + 62] + mov ax, es:[si + 62] + mov dx, es:[si + 64] clc pop di diff --git a/src/kernel/int21.asm b/src/kernel/int21.asm index 9140701..cb56f04 100644 --- a/src/kernel/int21.asm +++ b/src/kernel/int21.asm @@ -5,6 +5,11 @@ % define HEX(y) 0x##y %endif +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Includes. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%include "fat.inc" + ;****************************************************************************** ; @function _bcd2int ;****************************************************************************** @@ -293,6 +298,9 @@ _get_disk_info.copy: lodsw mov cs:[_clustsize], ax + lodsw + mov cs:[_info_sector], ax + pop ds pop si @@ -312,8 +320,14 @@ _get_disk_info.fat32: mov ax, offset _convert_cluster32 mov cs:[_convert_cluster], ax + mov ax, offset _find_free32 + mov cs:[_find_free], ax + mov ax, offset _nextcluster_fat32 mov cs:[_next_cluster], ax + + mov ax, offset _update_cluster32 + mov cs:[_update_cluster], ax _get_disk_info.done: @@ -810,6 +824,12 @@ _int21_dispatch.list: db HEX (30) dw _int21_30 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Create Directory (mkdir). + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + db HEX (39) + dw _int21_39 + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Set Current Directory. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -1636,6 +1656,109 @@ _int21_30: iret +;****************************************************************************** +; @function _int21_39 +; @brief Create Directory (mkdir) +; +; @in DS:DX -> Pointer to ASCIIZ path name. +;****************************************************************************** +_int21_39: + + push bx + push cx + push dx + push si + push di + push es + push ds + + mov si, dx + + call _get_disk_info + jc _int21_39.error_path + + mov di, si + + call _walk_path + jc _int21_39.error_path + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Preserve registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push ax + push dx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Mangle the file name and search for it in the file system. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + call _mangle_dos_name + jc _int21_39.name_error + + call _search_dos_dir + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop dx + pop ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If the carry flag wasn't set then the entry already exists. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + jnc _int21_39.error_exists + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If we get here then the path is okay and the entry doesn't exist + ;; so lets try and create it. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, HEX (10) + + call _make_dos_entry + jc _int21_39.error + + jmp _int21_39.done + +_int21_39.name_error: + + pop dx + pop ax + +_int21_39.error_exists: + + mov ax, 5 + +_int21_39.error_path: + + mov ax, 3 + +_int21_39.error: + + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + + stc + jmp iretc + +_int21_39.done: + + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + + xor ax, ax + clc + + jmp iretc + ;****************************************************************************** ; @function _int21_3B ; @brief Set Current Directory @@ -1793,6 +1916,9 @@ _int21_3B.copy: lodsw mov cs:[_clustsize], ax + lodsw + mov cs:[_info_sector], ax + pop ds pop si pop es @@ -1813,8 +1939,14 @@ _int21_3B.fat32: mov ax, offset _convert_cluster32 mov cs:[_convert_cluster], ax + mov ax, offset _find_free32 + mov cs:[_find_free], ax + mov ax, offset _nextcluster_fat32 mov cs:[_next_cluster], ax + + mov ax, offset _update_cluster32 + mov cs:[_update_cluster], ax _int21_3B.get_path: @@ -1939,12 +2071,20 @@ _int21_3B.check_prev: _int21_3B.get_prev: - mov byte ptr es:[di - 1], 0 + cmp di, offset _int21_3B.path + je _int21_3B.no_slash2 + + cmp byte ptr es:[di - 1], '\\' + jne _int21_3B.no_slash2 + mov byte ptr es:[di - 1], 0 + +_int21_3B.no_slash2: + push si push ds - mov ax, es + mov ax, cs mov ds, ax mov ax, '\\' @@ -1959,10 +2099,20 @@ _int21_3B.get_prev: pop ds pop si + and ax, ax + jnz _int21_3B.got_index + + mov di, offset _int21_3B.path + jmp _int21_3B.zero + +_int21_3B.got_index: + mov di, ax inc di + +_int21_3B.zero: + mov byte ptr es:[di], 0 - jmp _int21_3B.loop _int21_3B.char_ok: @@ -2255,6 +2405,7 @@ _int21_3F.copy: push si push ds push ax + push cx mov ds, ax xor si, si @@ -2308,6 +2459,9 @@ _int21_3F.copy: lodsw mov cs:[_clustsize], ax + lodsw + mov cs:[_info_sector], ax + mov bx, cs:[_root_cluster] mov cx, cs:[_root_cluster + 2] @@ -2324,11 +2478,18 @@ _int21_3F.fat32: mov ax, offset _convert_cluster32 mov cs:[_convert_cluster], ax + mov ax, offset _find_free32 + mov cs:[_find_free], ax + mov ax, offset _nextcluster_fat32 mov cs:[_next_cluster], ax + + mov ax, offset _update_cluster32 + mov cs:[_update_cluster], ax _int21_3F.read: + pop cx pop ax pop ds pop si @@ -2698,12 +2859,12 @@ _int21_4C.check_file: mov ds, di xor di, di - mov ax, [di + 70] + mov ax, [di + 72] cmp ax, dx jne _int21_4C.next_file - mov ax, [di + 68] + mov ax, [di + 70] push es mov es, ax @@ -3215,6 +3376,9 @@ _int21_4F.copy: lodsw mov cs:[_clustsize], ax + lodsw + mov cs:[_info_sector], ax + pop di pop si pop ds @@ -3236,8 +3400,14 @@ _int21_4F.fat32: mov ax, offset _convert_cluster32 mov cs:[_convert_cluster], ax + mov ax, offset _find_free32 + mov cs:[_find_free], ax + mov ax, offset _nextcluster_fat32 mov cs:[_next_cluster], ax + + mov ax, offset _update_cluster32 + mov cs:[_update_cluster], ax _int21_4F.find: diff --git a/src/kernel/make.asm b/src/kernel/make.asm new file mode 100644 index 0000000..741438f --- /dev/null +++ b/src/kernel/make.asm @@ -0,0 +1,482 @@ +;****************************************************************************** +; @file make.asm +;****************************************************************************** +%ifndef HEX +% define HEX(y) 0x##y +%endif + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Include our fat.inc file for our BPB offsets. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%include "fat.inc" + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; @function _generate_timestamp +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +_generate_timestamp: + + push si + push cx + push dx + + mov ah, HEX (2C) + int HEX (21) + + xor ah, ah + mov al, dh + shr ax + mov si, ax + + push cx + xor ah, ah + mov al, cl + mov cl, 5 + shl ax, cl + pop cx + add si, ax + + push cx + xor ah, ah + mov al, ch + mov cl, 11 + shl ax, cl + pop cx + add si, ax + +_generate_timestamp.done: + + mov ax, si + + pop dx + pop cx + pop si + ret + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; @function _generate_datestamp +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +_generate_datestamp: + + push si + push cx + push dx + + mov ah, HEX (2A) + int HEX (21) + + xor ah, ah + mov al, dl + mov si, ax + + push cx + xor ah, ah + mov al, dh + mov cl, 5 + shl ax, cl + pop cx + add si, ax + + push cx + mov ax, cx + sub ax, 1980 + mov cl, 9 + shl ax, cl + pop cx + add si, ax + +_generate_datestamp.done: + + mov ax, si + + pop dx + pop cx + pop si + ret + + +;****************************************************************************** +; @function _make_dos_entry +;****************************************************************************** +global _make_dos_entry +_make_dos_entry: + + push bp + + mov bp, sp + sub sp, 48 + + push bx + push cx + push dx + push si + push di + push es + push ds + + mov word ptr [bp - 48], ax + mov word ptr [bp - 46], dx + + mov word ptr [bp - 36], cx + mov word ptr [bp - 32], bx + + mov word ptr [bp - 20], 0 + mov word ptr [bp - 16], 0 + + mov bx, ax + or bx, dx + + and bx, bx + jnz _make_dos_entry.not_root + + mov ax, cs:[_root_start] + mov dx, cs:[_root_start + 2] + +_make_dos_entry.got_root: + + mov word ptr [bp - 30], 1 + mov word ptr [bp - 24], 1 + + mov word ptr [bp - 28], ax + mov word ptr [bp - 26], dx + + mov ax, 32 + xor dx, dx + + mov cx, cs:[_root_entries] + mul cx + + mov cx, cs:[_bytes_per_sector] + div cx + + xchg cx, ax + dec cx + + xor dx, dx + mov word ptr [bp - 22], cx + + mov ax, word ptr [bp - 28] + mov dx, word ptr [bp - 26] + + mov word ptr [bp - 6], ax + mov word ptr [bp - 4], dx + + jmp _make_dos_entry.read + +_make_dos_entry.not_root: + + mov word ptr [bp - 30], 0 + mov word ptr [bp - 24], 1 + + mov word ptr [bp - 28], ax + mov word ptr [bp - 26], dx + + call cs:[_convert_cluster] + jc _make_dos_entry.error + + mov word ptr [bp - 6], ax + mov word ptr [bp - 4], dx + + xor ch, ch + mov cl, cs:[_sectors_per_cluster] + + mov word ptr [bp - 34], cx + dec word ptr [bp - 34] + +_make_dos_entry.read: + + mov bx, cs:[_disk_scratch] + mov es, bx + xor bx, bx + + mov ax, word ptr [bp - 6] + mov dx, word ptr [bp - 4] + + mov cx, word ptr [bp - 24] + call _read_sectors + + mov ax, cs:[_bytes_per_sector] + xor dx, dx + + mov cx, 32 + div cx + xchg cx, ax + + xor di, di + +_make_dos_entry.make: + + cmp byte ptr es:[di], 0 + je _make_dos_entry.found_free + + cmp byte ptr es:[di], HEX (E5) + je _make_dos_entry.found_free + +_make_dos_entry.advance: + + add di, 32 + loop _make_dos_entry.make + + cmp word ptr [bp - 30], 1 + jne _make_dos_entry.check + + mov ax, word ptr [bp - 22] + + and ax, ax + jz _make_dos_entry.error + + dec ax + mov word ptr [bp - 22], ax + + mov ax, word ptr [bp - 6] + mov dx, word ptr [bp - 4] + + add ax, word ptr [bp - 24] + adc dx, 0 + + mov word ptr [bp - 6], ax + mov word ptr [bp - 4], dx + + jmp _make_dos_entry.read + +_make_dos_entry.check: + + mov ax, word ptr [bp - 34] + + and ax, ax + jz _make_dos_entry.next_clust + + dec ax + mov word ptr [bp - 34], ax + + mov ax, word ptr [bp - 6] + mov dx, word ptr [bp - 4] + + add ax, word ptr [bp - 24] + adc dx, 0 + + mov word ptr [bp - 6], ax + mov word ptr [bp - 4], dx + + jmp _make_dos_entry.read + +_make_dos_entry.next_clust: + + mov ax, word ptr [bp - 28] + mov dx, word ptr [bp - 26] + + call cs:[_next_cluster] + jmp _make_dos_entry.not_root + +_make_dos_entry.found_free: + + call cs:[_find_free] + jc _make_dos_entry.error + +_make_dos_entry.got_clust: + + mov word ptr [bp - 38], ax + mov word ptr [bp - 40], dx + + call _generate_datestamp + mov word ptr [bp - 42], ax + + call _generate_timestamp + mov word ptr [bp - 44], ax + + push si + push ds + + mov si, cs + mov ds, si + + mov si, word ptr [bp - 32] + + mov cx, 11 + rep movsb + + pop ds + pop si + + mov ax, word ptr [bp - 36] + stosb + + xor ax, ax + stosw + + mov ax, word ptr [bp - 44] + stosw + + mov ax, word ptr [bp - 42] + stosw + + mov ax, word ptr [bp - 42] + stosw + + mov ax, word ptr [bp - 40] + stosw + + mov ax, word ptr [bp - 44] + stosw + + mov ax, word ptr [bp - 42] + stosw + + mov ax, word ptr [bp - 38] + stosw + + xor ax, ax + stosw + stosw + + mov ax, word ptr [bp - 6] + mov dx, word ptr [bp - 4] + + mov cx, word ptr [bp - 24] + call _write_sectors + + mov ax, word ptr [bp - 38] + mov dx, word ptr [bp - 40] + + mov bx, HEX (FFFF) + mov cx, HEX (FFF8) + + call cs:[_update_cluster] + + mov ax, cs:[_disk_scratch] + mov es, ax + + xor al, al + xor di, di + + mov cx, cs:[_clustsize] + rep stosb + + xor di, di + + mov al, '.' + stosb + + mov al, ' ' + + mov cx, 10 + rep stosb + + mov al, HEX (10) + stosb + + xor ax, ax + stosw + + mov ax, word ptr [bp - 44] + stosw + + mov ax, word ptr [bp - 42] + stosw + + mov ax, word ptr [bp - 42] + stosw + + mov ax, word ptr [bp - 40] + stosw + + mov ax, word ptr [bp - 44] + stosw + + mov ax, word ptr [bp - 42] + stosw + + mov ax, word ptr [bp - 38] + stosw + + xor ax, ax + stosw + stosw + + mov al, '.' + + mov cx, 2 + rep stosb + + mov al, ' ' + + mov cx, 9 + rep stosb + + mov al, HEX (10) + stosb + + xor ax, ax + stosw + + mov ax, word ptr [bp - 44] + stosw + + mov ax, word ptr [bp - 42] + stosw + + mov ax, word ptr [bp - 42] + stosw + + mov ax, word ptr [bp - 46] + stosw + + mov ax, word ptr [bp - 44] + stosw + + mov ax, word ptr [bp - 42] + stosw + + mov ax, word ptr [bp - 48] + stosw + + xor ax, ax + stosw + stosw + + mov ax, word ptr [bp - 38] + mov dx, word ptr [bp - 40] + call cs:[_convert_cluster] + + xor ch, ch + mov cl, cs:[_sectors_per_cluster] + + xor bx, bx + call _write_sectors + + jmp _make_dos_entry.done + +_make_dos_entry.error: + + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + + add sp, 48 + pop bp + + mov ax, 5 + stc + + ret + +_make_dos_entry.done: + + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + + add sp, 48 + pop bp + + xor ax, ax + clc + + ret diff --git a/src/kernel/walk.asm b/src/kernel/walk.asm index 98c1c4d..7fd3a25 100644 --- a/src/kernel/walk.asm +++ b/src/kernel/walk.asm @@ -70,6 +70,56 @@ _walk_path.end_path: call _mangle_dos_name jc _walk_path.not_found + cmp dx, cs:[_root_cluster + 2] + jne _walk_path.search + + cmp ax, cs:[_root_cluster] + jne _walk_path.search + +_walk_path.compare_curr: + + push ax + push ds + + mov ax, cs + mov ds, ax + + push bx + + mov ax, offset _curr_check + push ax + + call _strcmp + add sp, 4 + + and ax, ax + pop ds + pop ax + jz _walk_path.check + +_walk_path.compare_prev: + + push ax + push ds + + mov ax, cs + mov ds, ax + + push bx + + mov ax, offset _prev_check + push ax + + call _strcmp + add sp, 4 + + and ax, ax + pop ds + pop ax + jz _walk_path.check + +_walk_path.search: + call _search_dos_dir jc _walk_path.not_found @@ -82,14 +132,27 @@ _walk_path.end_path: mov ax, es:[bx + 0] mov dx, es:[bx + 2] - mov cl, es:[bx + 8] + + mov bx, ax + or bx, dx + + and bx, bx + jnz _walk_path.got_clust + + mov ax, cs:[_root_cluster] + mov dx, cs:[_root_cluster + 2] + +_walk_path.got_clust: + pop es pop bx test cl, HEX (10) jz _walk_path.not_found - + +_walk_path.check: + cmp byte ptr [di - 1], '\\' jne _walk_path.done @@ -108,3 +171,9 @@ _walk_path.done: clc ret + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Data area. +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +_curr_check: db ". ", HEX (00) +_prev_check: db ".. ", HEX (00)