Implemented int 21h/AH=41
authorRobert Pengelly <robertapengelly@hotmail.com>
Tue, 6 Aug 2024 12:56:44 +0000 (13:56 +0100)
committerRobert Pengelly <robertapengelly@hotmail.com>
Tue, 6 Aug 2024 12:56:44 +0000 (13:56 +0100)
build/chimaera.img
build/chimaera.vhd
src/apps/hello/hello.asm
src/apps/pcomm/Makefile.unix
src/apps/pcomm/Makefile.w32
src/apps/pcomm/del.asm [new file with mode: 0644]
src/apps/pcomm/pcomm.asm
src/kernel/int21.asm

index d52add0355fc3a6b7e03549ba94739d682f4b10f..f77702e5bbb893147a8f231df71b79af0ebca794 100644 (file)
Binary files a/build/chimaera.img and b/build/chimaera.img differ
index cc7804661feabfe608240b18426d9c6a6baeae70..768d5a4138b0ca71e18a031c535a20c76a742a7e 100644 (file)
Binary files a/build/chimaera.vhd and b/build/chimaera.vhd differ
index 07f1f9f8674c2f6a729f6f47ec98a3de426091a3..4aac207ce1d62cb5654e288002d994c1efa5f043 100644 (file)
@@ -19,10 +19,15 @@ _main:
     mov     bx,     offset _msg_hello
     call    _writestr
     
+    mov     ah,     HEX (3C)
+    mov     cx,     HEX (20)
+    mov     dx,     offset _new_file
+    int     HEX (21)
+    jc      .exit
+    
 ;    mov     ah,     HEX (3C)
 ;    mov     cx,     HEX (20)
 ;    mov     dx,     offset _existing_file
-;    mov     dx,     offset _new_file
 ;    int     HEX (21)
 ;    jc      .exit
 ;    
index b39d307f578d7f6af45e4c0cdbac3c01e8da327b..b256c626af262c3855f0c69636161d253ab773c8 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 touch.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 del.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 e56edd95ad8a13a828067abf60073d5bb488ae7a..ddfdcfc6777767e8a50c8504644fc4e23aca66a0 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 touch.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 del.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/del.asm b/src/apps/pcomm/del.asm
new file mode 100644 (file)
index 0000000..154872a
--- /dev/null
@@ -0,0 +1,222 @@
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; @file            type.asm
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+%ifndef     HEX
+% define        HEX(y)                  0x##y
+%endif
+
+;******************************************************************************
+; @function         _handler_del
+;******************************************************************************
+global      _handler_del
+_handler_del:
+
+    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_del.ok
+    
+    mov     bx,     offset _err_invalid
+    call    _writestr
+    
+    jmp     _handler_del.done
+
+_handler_del.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_del.store_arg:
+
+    cmp     byte ptr [bx],      0
+    je      _handler_del.next
+    
+    mov     si,     bx
+    push    si
+    
+    mov     ax,     offset _vec_files
+    push    ax
+    
+    call    _vec_push
+    add     sp,     4
+
+_handler_del.check:
+
+    mov     ax,     ' '
+    push    ax
+    
+    mov     si,     bx
+    push    si
+    
+    call    _strchr
+    add     sp,     4
+    
+    and     ax,     ax
+    jz      _handler_del.next
+    
+    mov     bx,     ax
+    mov     byte ptr [bx],      0
+    
+    inc     bx
+
+_handler_del.skip:
+
+    cmp     byte ptr [bx],      0
+    je      _handler_del.next
+    
+    cmp     byte ptr [bx],      ' '
+    ja      _handler_del.store_arg
+    
+    inc     bx
+    jmp     _handler_del.skip
+
+_handler_del.next:
+
+    mov     ax,     word ptr [bp - 4]
+    inc     ax
+    
+    cmp     ax,     cs:[_vec_files + 4]
+    ja      _handler_del.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_del.delete:
+
+    push    bx
+    
+    mov     ah,     HEX (41)
+    mov     dx,     bx
+    int     HEX (21)
+    jnc     _handler_del.deleted
+    
+    cmp     ax,     2
+    jne     _handler_del.check3
+    
+    mov     bx,     offset _err_no_file
+    jmp     _handler_del.error
+
+_handler_del.check3:
+
+    cmp     ax,     3
+    jne     _handler_del.unhandled
+    
+    mov     bx,     offset _err_no_dir
+    jmp     _handler_del.error
+
+_handler_del.unhandled:
+
+    pop     bx
+    mov     bx,     offset _err_unhandled
+
+_handler_del.error:
+
+    call    _writestr
+    
+    cmp     ax,     3
+    ja      _handler_del.next
+    
+    cmp     ax,     2
+    jb      _handler_del.next
+    
+    pop     bx
+    
+    call    _writestr
+    call    _crlf
+    
+    jmp     _handler_del.cleanup
+
+_handler_del.deleted:
+
+    pop     bx
+    jmp     _handler_del.next
+
+_handler_del.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_del.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_dir:                    db      "Path not found: ",     HEX (00)
+_err_no_file:                   db      "File not found: ",     HEX (00)
+
+_err_unhandled:                 db      "Unhandled error code",     HEX (0D),   HEX (0A),   HEX (00)
index f06e924ae36da1d3b53aea0aa3ee2081031e0ee6..755fc5fa1150f75f6067f88a1b84192f9d79318b 100644 (file)
@@ -1070,6 +1070,7 @@ _handler_help.msg:
     db      "CD         Change the current directory to the specified path.",               HEX (0D),   HEX (0A)
     db      "CLS        Clears the screen.",                                                HEX (0D),   HEX (0A)
     db      "DATE       Displays the system date.",                                         HEX (0D),   HEX (0A)
+    db      "DEL        Delete the specified files.",                                       HEX (0D),   HEX (0A)
     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)
@@ -1278,6 +1279,10 @@ _cmd_table:
     dw      0
     dw      _handler_date
     
+    dw      hash_del
+    dw      0
+    dw      _handler_del
+    
     dw      hash_dir
     dw      0
     dw      _handler_dir
index a6f0a119c58f607a1ec5969e8ab438112265cd7e..6f189c3e05304180efa909f077739888d9522d91 100644 (file)
@@ -869,10 +869,9 @@ _int21_dispatch.list:
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     ;; Delete/Unlink File.
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-    ;db      HEX (41)
-    ;dw      _int21_41
+    db      HEX (41)
+    dw      _int21_41
     
-    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     ;; Move File Pointer Using Handle.
     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@ -3116,6 +3115,282 @@ _int21_40.done:
     
     jmp     iretc
 
+;******************************************************************************
+; @function         _int21_41
+; @brief            Delete/Unlink File
+;
+; @in               DS:DX -> Pointer to ASCIIZ filename.
+; @out              AX -> Error code if CF is set.
+;******************************************************************************
+_int21_41:
+
+    push    bp
+    
+    mov     bp,     sp
+    sub     sp,     6
+    
+    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_41.path_error
+    
+    mov     di,     si
+
+_int21_41.open:
+
+    call    _open_file
+    jc      _int21_41.error
+    
+    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_41.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_41.update
+    
+    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    ;; 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_41.clear:
+
+    and     cx,     cx
+    jz      _int21_41.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_41.clear
+
+_int21_41.update:
+
+    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    ;; 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
+    
+    mov     byte ptr es:[di + 0],   HEX (E5)
+    pop     cx
+    pop     dx
+    pop     ax
+    
+    xor     bx,     bx
+    call    _write_sectors
+    
+    pop     bx
+    pop     es
+    
+    ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+    ;; 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_41.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_41.no_info:
+
+    mov     ax,     word ptr [bp - 6]
+    jmp     _int21_41.done
+
+_int21_41.denied:
+
+    mov     ax,     5
+    jmp     _int21_41.error
+
+_int21_41.path_error:
+
+    mov     ax,     3
+
+_int21_41.error:
+
+    pop     ds
+    pop     es
+    pop     di
+    pop     si
+    pop     dx
+    pop     cx
+    pop     bx
+    
+    add     sp,     6
+    stc
+    
+    pop     bp
+    jmp     iretc
+
+_int21_41.done:
+
+    pop     ds
+    pop     es
+    pop     di
+    pop     si
+    pop     dx
+    pop     cx
+    pop     bx
+    
+    add     sp,     6
+    clc
+    
+    pop     bp
+    jmp     iretc
+
 ;******************************************************************************
 ; @function         _int21_42
 ; @brief            Move File Pointer Using Handle