--- /dev/null
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; @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)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Delete/Unlink File.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
- ;db HEX (41)
- ;dw _int21_41
+ db HEX (41)
+ dw _int21_41
- ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Move File Pointer Using Handle.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
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