Implemented int 21h/AH=3C
authorRobert Pengelly <robertapengelly@hotmail.com>
Tue, 6 Aug 2024 11:14:40 +0000 (12:14 +0100)
committerRobert Pengelly <robertapengelly@hotmail.com>
Tue, 6 Aug 2024 11:14:40 +0000 (12:14 +0100)
12 files changed:
build/chimaera.img
build/chimaera.vhd
src/Makefile.unix
src/apps/hello/hello.asm
src/apps/pcomm/Makefile.unix
src/apps/pcomm/Makefile.w32
src/apps/pcomm/pcomm.asm
src/apps/pcomm/touch.asm [new file with mode: 0644]
src/kernel/file.asm
src/kernel/int21.asm
src/kernel/make.asm
src/kernel/search.asm

index c5dc8e7cfdbc5070a8ea341100aff353f6d767aa..d52add0355fc3a6b7e03549ba94739d682f4b10f 100644 (file)
Binary files a/build/chimaera.img and b/build/chimaera.img differ
index dcb9b66214d61b4c4710436cc3349bbaea786129..cc7804661feabfe608240b18426d9c6a6baeae70 100644 (file)
Binary files a/build/chimaera.vhd and b/build/chimaera.vhd differ
index 7c0b071ef2e71aade084d03623dac0552897ada1..1d5aab0b394ed0e3a065c6a450126d05276e069c 100644 (file)
@@ -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
index ff2b84e329334577764a0bd1974ec43abc61f095..07f1f9f8674c2f6a729f6f47ec98a3de426091a3 100644 (file)
 %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)
@@ -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)
index 7edf7ba199d0765ffa128c69f126347b77ae5ddf..b39d307f578d7f6af45e4c0cdbac3c01e8da327b 100644 (file)
@@ -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
index 4a11f17c0364edc236d92c268ba393d59cc722a1..e56edd95ad8a13a828067abf60073d5bb488ae7a 100644 (file)
@@ -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
index e2aea7b094baa91d07c0f6841b2ce3e985f3696d..f06e924ae36da1d3b53aea0aa3ee2081031e0ee6 100644 (file)
@@ -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 (file)
index 0000000..ca254e9
--- /dev/null
@@ -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)
index ac140241386ce64c12753c3a63093e74beacfa2c..0c73b04856c77a99881e7f5966277ec328252608 100644 (file)
@@ -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.
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
index d9bf5f0e450e029ea30a64a75f6062abfe396e0b..a6f0a119c58f607a1ec5969e8ab438112265cd7e 100644 (file)
@@ -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
index 4216d22b1f9780a8a23b7d0d7f29b1991298fe61..0a24ef17e096c5f32ef8094aafed4a45a2aeb9a2 100644 (file)
@@ -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
 
index 4ce90fcc845024631880ab98bc049c4b40a60056..2cf47a1018e4cf622f7baaa936e28002934b1297 100644 (file)
@@ -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)