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
%include <stdio.inc>
;******************************************************************************
-; @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)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; 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)
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
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
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)
dw 0
dw _handler_time
+ dw hash_touch
+ dw 0
+ dw _handler_touch
+
dw hash_type
dw 0
dw _handler_type
--- /dev/null
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; @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)
;; 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.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Create File Using Handle.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;db HEX (3C)
- ;dw _int21_3C
+ db HEX (3C)
+ dw _int21_3C
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Open File Using Handle.
_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
_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
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
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
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)