From: Robert Pengelly Date: Tue, 6 Aug 2024 11:14:40 +0000 (+0100) Subject: Implemented int 21h/AH=3C X-Git-Url: https://git.candlhat.org/?a=commitdiff_plain;h=44f9aac8cddfa8da0b5d8f1b7d49dddec3321c1f;p=chimaera.git Implemented int 21h/AH=3C --- diff --git a/build/chimaera.img b/build/chimaera.img index c5dc8e7..d52add0 100644 Binary files a/build/chimaera.img and b/build/chimaera.img differ diff --git a/build/chimaera.vhd b/build/chimaera.vhd index dcb9b66..cc78046 100644 Binary files a/build/chimaera.vhd and b/build/chimaera.vhd differ diff --git a/src/Makefile.unix b/src/Makefile.unix index 7c0b071..1d5aab0 100644 --- a/src/Makefile.unix +++ b/src/Makefile.unix @@ -30,6 +30,7 @@ chimaera.img: all utils/dosfstools/mcopy -i $@ boot/freeldr/core/freeldr.sys :: utils/dosfstools/mcopy -i $@ kernel/kernel.sys :: utils/dosfstools/mcopy -i $@ apps/pcomm/pcomm.com ::command.com +# utils/dosfstools/mcopy -i $@ apps/hello/hello.com ::hello.com chimaera.vhd: all if [ -f $@ ]; then rm -rf $@; fi diff --git a/src/apps/hello/hello.asm b/src/apps/hello/hello.asm index ff2b84e..07f1f9f 100644 --- a/src/apps/hello/hello.asm +++ b/src/apps/hello/hello.asm @@ -11,14 +11,33 @@ %include ;****************************************************************************** -; @function _free +; @function _main ;****************************************************************************** global _main _main: - mov bx, offset msg_hello + mov bx, offset _msg_hello call _writestr - + +; mov ah, HEX (3C) +; mov cx, HEX (20) +; mov dx, offset _existing_file +; mov dx, offset _new_file +; int HEX (21) +; jc .exit +; +; call _writehex +; call _crlf +; +; mov bx, ax +; +; mov ah, HEX (3E) +; int HEX (21) +; jnc .exit +; +; call _writehex +; call _crlf +; ; call _crlf ; ; mov ah, HEX (08) @@ -115,4 +134,6 @@ _main: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Data area. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -msg_hello: db "Hello, world!", HEX (0D), HEX (0A), HEX (00) +_msg_hello: db "Hello, world!", HEX (0D), HEX (0A), HEX (00) +_new_file: db "temp.txt", HEX (00) +;_existing_file: db "\\boot\\freeldr\\freeldr.cfg", HEX (00) diff --git a/src/apps/pcomm/Makefile.unix b/src/apps/pcomm/Makefile.unix index 7edf7ba..b39d307 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 mkdir.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 touch.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 4a11f17..e56edd9 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 mkdir.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 touch.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/pcomm.asm b/src/apps/pcomm/pcomm.asm index e2aea7b..f06e924 100644 --- a/src/apps/pcomm/pcomm.asm +++ b/src/apps/pcomm/pcomm.asm @@ -1076,6 +1076,7 @@ _handler_help.msg: 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 "TOUCH Create a new file if it doesn't already exist.", HEX (0D), HEX (0A) db "TYPE Displays the contents of a text file.", HEX (0D), HEX (0A) db HEX (00) @@ -1305,6 +1306,10 @@ _cmd_table: dw 0 dw _handler_time + dw hash_touch + dw 0 + dw _handler_touch + dw hash_type dw 0 dw _handler_type diff --git a/src/apps/pcomm/touch.asm b/src/apps/pcomm/touch.asm new file mode 100644 index 0000000..ca254e9 --- /dev/null +++ b/src/apps/pcomm/touch.asm @@ -0,0 +1,220 @@ +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; @file touch.asm +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +%ifndef HEX +% define HEX(y) 0x##y +%endif + +;****************************************************************************** +; @function _handler_touch +;****************************************************************************** +global _handler_touch +_handler_touch: + + 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_touch.ok + + mov bx, offset _err_invalid + call _writestr + + jmp _handler_touch.done + +_handler_touch.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_touch.store_arg: + + cmp byte ptr [bx], 0 + je _handler_touch.next + + mov si, bx + push si + + mov ax, offset _vec_files + push ax + + call _vec_push + add sp, 4 + +_handler_touch.check: + + mov ax, ' ' + push ax + + mov si, bx + push si + + call _strchr + add sp, 4 + + and ax, ax + jz _handler_touch.next + + mov bx, ax + mov byte ptr [bx], 0 + + inc bx + +_handler_touch.skip: + + cmp byte ptr [bx], 0 + je _handler_touch.next + + cmp byte ptr [bx], ' ' + ja _handler_touch.store_arg + + inc bx + jmp _handler_touch.skip + +_handler_touch.next: + + mov ax, word ptr [bp - 4] + inc ax + + cmp ax, cs:[_vec_files + 4] + ja _handler_touch.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_touch.open: + + push bx + + mov ax, HEX (3D02) + mov dx, bx + int HEX (21) + jnc _handler_touch.close + + mov ah, HEX (3C) + mov cx, HEX (20) + mov dx, bx + int HEX (21) + jnc _handler_touch.close + + cmp ax, 3 + jne _handler_touch.unhandled + + mov bx, offset _err_no_path + jmp _handler_touch.error + +_handler_touch.unhandled: + + pop bx + mov bx, offset _err_unhandled + +_handler_touch.error: + + call _writestr + + cmp ax, 3 + jne _handler_touch.next + + pop bx + + call _writestr + call _crlf + + jmp _handler_touch.next + +_handler_touch.close: + + pop bx + mov bx, ax + + mov ah, HEX (3E) + int HEX (21) + + jmp _handler_touch.next + +_handler_touch.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_touch.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_no_path: db "Path not found: ", HEX (00) +_err_unhandled: db "Unhandled error code", HEX (0D), HEX (0A), HEX (00) diff --git a/src/kernel/file.asm b/src/kernel/file.asm index ac14024..0c73b04 100644 --- a/src/kernel/file.asm +++ b/src/kernel/file.asm @@ -757,12 +757,15 @@ _open_file.got_handle: ;; Allocate memory for a buffer that will be used to keep track of ;; the current data read. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push si xor si, si mov ax, es:[si + 50] xor dx, dx call _kmalloc + pop si + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Store the value. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @@ -774,6 +777,21 @@ _open_file.got_handle: mov ax, cs:[_curr_psp] stosw + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Store information about where the entry is located on disk. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, cs:[si + 10] + stosw + + mov ax, cs:[si + 12] + stosw + + mov ax, cs:[si + 14] + stosw + + mov ax, cs:[si + 16] + stosw + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Restore ax and re-push it to the stack. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/src/kernel/int21.asm b/src/kernel/int21.asm index d9bf5f0..a6f0a11 100644 --- a/src/kernel/int21.asm +++ b/src/kernel/int21.asm @@ -839,8 +839,8 @@ _int21_dispatch.list: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Create File Using Handle. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - ;db HEX (3C) - ;dw _int21_3C + db HEX (3C) + dw _int21_3C ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Open File Using Handle. @@ -2268,6 +2268,367 @@ _int21_3B.done: _int21_3B.path: db 66 dup (0) +;****************************************************************************** +; @function _int21_3C +; @brief Create File Using Handle +; +; @in CX -> File attributes. +; @in DS:DX -> Pointer to an ASCIIZ file name. +; +; @out AX -> File handle. Error code if CF is set. +;****************************************************************************** +_int21_3C: + + push bp + + mov bp, sp + sub sp, 10 + + push bx + push cx + push dx + push si + push di + push es + push ds + + xor bh, bh + mov bl, al + + mov si, dx + + call _get_disk_info + jc _int21_3C.error_path + + mov di, si + +_int21_3C.open: + + call _open_file + jnc _int21_3C.zero + +_int21_3C.create: + + mov word ptr [bp - 4], si + mov word ptr [bp - 2], di + + call _walk_path + jc _int21_3C.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_3C.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_3C.error_denied + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If we get here then the path is okay and the entry doesn't exist + ;; so lets try and create the entry. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + call _make_dos_entry + jc _int21_3C.error_denied + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the origin si and di values. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov si, word ptr [bp - 4] + mov di, word ptr [bp - 2] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Try and open the file again. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + call _open_file + jc _int21_3C.error + + jmp _int21_3C.done + +_int21_3C.zero: + + mov word ptr [bp - 6], ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; First thing we need to do is get the index into the file info vector. + ;; + ;; Note: We should need to do a compare here as _open_file should + ;; give us a value of at least 3. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor dx, dx + sub ax, 3 + + mov cx, 2 + mul cx + + mov bx, ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Okay, we should have the correct index into the file info vector + ;; so get the + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, cs:[_vec_files + 0] + mov es, ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If the vector entry is zero then the file handle is invalid. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + cmp word ptr es:[bx], 0 + je _int21_3C.error_denied + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Re-initialize the extra segment but this time with the address + ;; of the vector entry. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, es:[bx] + mov es, ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; We'll use si register as the index into the info. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor si, si + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the file size. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, es:[si + 66] + mov dx, es:[si + 68] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; If we don't have a file size then we can got straight to done. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov bx, ax + or bx, dx + + and bx, bx + jz _int21_3C.done + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Convert the size into the amount of cluster. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, es:[si + 50] + div cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Move the value into the cx register. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov cx, ax + inc cx + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the starting cluster. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, es:[si + 58] + mov dx, es:[si + 60] + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Save the value in cx. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + push cx + +_int21_3C.clear: + + and cx, cx + jz _int21_3C.update + + push ax + push dx + + call cs:[_next_cluster] + + mov word ptr [bp - 8], ax + mov word ptr [bp - 10], dx + + pop dx + pop ax + + push cx + push bx + + xor bx, bx + xor cx, cx + call cs:[_update_cluster] + + pop bx + pop cx + + mov ax, word ptr [bp - 8] + mov dx, word ptr [bp - 10] + + dec cx + jnz _int21_3C.clear + +_int21_3C.update: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Clear out the starting sector. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor ax, ax + mov es:[si + 58], ax + mov es:[si + 60], ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Update the entry on disk. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, es:[si + 74] + mov dx, es:[si + 76] + + mov cx, es:[si + 78] + mov di, es:[si + 80] + + push es + push bx + push ax + push dx + push cx + + mov bx, cs:[_disk_scratch] + mov es, bx + + xor bx, bx + call _read_sectors + + xor ax, ax + mov es:[di + 26], ax + mov es:[di + 20], ax + mov es:[di + 28], ax + mov es:[di + 30], ax + + pop cx + pop dx + pop ax + + xor bx, bx + call _write_sectors + + pop bx + pop es + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Make sure our file info size is zero. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor ax, ax + mov es:[si + 66], ax + mov es:[si + 68], ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore the value in the cx register. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + pop si + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Check if we have an info sector. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, cs:[_info_sector] + + and ax, ax + jz _int21_3C.no_info + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Update the free clusters. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + xor dx, dx + + add ax, cs:[_hidden_sectors] + adc dx, cs:[_hidden_sectors + 2] + + mov bx, cs:[_disk_scratch] + mov es, bx + xor bx, bx + + mov cx, 1 + call _read_sectors + + mov di, HEX (01E0) + + mov ax, es:[di + 8] + mov dx, es:[di + 10] + + add ax, si + adc dx, 0 + + mov es:[di + 8], ax + mov es:[di + 10], dx + + mov ax, cs:[_info_sector] + xor dx, dx + + add ax, cs:[_hidden_sectors] + adc dx, cs:[_hidden_sectors + 2] + + mov cx, 1 + call _write_sectors + +_int21_3C.no_info: + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Put the file pointer back into the ax register and jump to done. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp - 6] + jmp _int21_3C.done + +_int21_3C.error_path: + + mov ax, 3 + jmp _int21_3C.error + +_int21_3C.name_error: + + pop dx + pop ax + +_int21_3C.error_denied: + + mov ax, 5 + +_int21_3C.error: + + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + + add sp, 10 + stc + + pop bp + jmp iretc + +_int21_3C.done: + + pop ds + pop es + pop di + pop si + pop dx + pop cx + pop bx + + add sp, 10 + clc + + pop bp + jmp iretc + ;****************************************************************************** ; @function _int21_3D ; @brief Open File Using Handle diff --git a/src/kernel/make.asm b/src/kernel/make.asm index 4216d22..0a24ef1 100644 --- a/src/kernel/make.asm +++ b/src/kernel/make.asm @@ -289,6 +289,72 @@ _make_dos_entry.next_clust: _make_dos_entry.found_free: + mov ax, word ptr [bp - 36] + + and ax, HEX (20) + jz _make_dos_entry.create_dir + + 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 + + xor ax, ax + stosw + + mov ax, word ptr [bp - 44] + stosw + + mov ax, word ptr [bp - 42] + stosw + + xor ax, ax + 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 + + jmp _make_dos_entry.done + +_make_dos_entry.create_dir: + call cs:[_find_free] jc _make_dos_entry.error diff --git a/src/kernel/search.asm b/src/kernel/search.asm index 4ce90fc..2cf47a1 100644 --- a/src/kernel/search.asm +++ b/src/kernel/search.asm @@ -226,6 +226,9 @@ _search_dos_dir.found: mov ds, ax mov bx, offset _file_info + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the starting cluster and file size of the entry. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov ax, es:[di + 26] mov [bx + 0], ax @@ -238,9 +241,35 @@ _search_dos_dir.found: mov ax, es:[di + 30] mov [bx + 6], ax + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Get the entry type. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov al, es:[di + 11] mov [bx + 8], al + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Save the starting sector of the entry. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp - 6] + mov [bx + 10], ax + + mov ax, word ptr [bp - 4] + mov [bx + 12], ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Save the size. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov ax, word ptr [bp - 24] + mov [bx + 14], ax + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Save the index info the directort sector where the entry starts. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + mov [bx + 16], di + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Restore registers. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; pop ds pop es pop di @@ -249,15 +278,24 @@ _search_dos_dir.found: pop cx pop bx + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Clean up the stack and restore the base pointer. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; add sp, 34 pop bp + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Set ax as the offset of the file info and clear the carry flag. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; mov ax, offset _file_info clc + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + ;; Return to caller. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ret ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; Data area. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -_file_info: db 9 dup (0) +_file_info: db 20 dup (0)