471 lines
13 KiB
NASM
471 lines
13 KiB
NASM
;***************************************
|
||
;* MS-DOS Utilities *
|
||
;* *
|
||
;* (C) Copyright 1984,1985 by Texas *
|
||
;* Instruments Incorporated. *
|
||
;* All rights reserved. *
|
||
;* *
|
||
;* Date Written: 21 June 1984 *
|
||
;* Last Modification: 9 June 1986 *
|
||
;***************************************
|
||
|
||
MSDOS equ 021h ; MS-DOS interrupt number
|
||
GETTIME equ 02Ch ; "get_time" function request id
|
||
READ equ 0
|
||
WRITE equ 1
|
||
SELDISK equ 0EH ; select disk
|
||
CURDISK equ 019H ; get the current disk
|
||
SETADDR equ 01AH ; set disk transfer address
|
||
CHNGDIR equ 03BH ; change the current directory
|
||
CRFILE equ 03CH ; create a file
|
||
OPENFILE equ 03DH ; open a file
|
||
CLFILE equ 03EH ; close a file
|
||
RFILE equ 03FH ; read from a file
|
||
WFILE equ 040H ; write to a file
|
||
DELFILE equ 041H ; delete a file function request id
|
||
MOVPTR equ 042H ; move file pointer
|
||
CURRDIR equ 047H ; return text of current directory
|
||
FINDFILE equ 04EH ; find match file
|
||
FINDNEXT equ 04FH ; step through a directory, matching files
|
||
CHGNAME equ 056H ; move a directory entry
|
||
|
||
DGROUP group data
|
||
data segment word public 'DATA'
|
||
assume DS:DGROUP
|
||
curdrv db 0
|
||
db 3AH ; ':'
|
||
db 5CH ; '\'
|
||
curdir db 64 dup (0)
|
||
dta db 43 dup (0)
|
||
filespec db 13 dup (0)
|
||
data ends
|
||
|
||
XGROUP group progx
|
||
progx segment byte public 'PROGX'
|
||
assume CS:XGROUP,DS:DGROUP
|
||
;;;
|
||
;;; Delete a file
|
||
;;;
|
||
del_arg struc
|
||
dw ? ; caller's BP
|
||
dd ? ; return address (long)
|
||
dw ? ; original return address (short)
|
||
filename dw ? ; file name
|
||
del_arg ends
|
||
|
||
dos%del proc far
|
||
push BP
|
||
mov BP,SP
|
||
mov DX,[BP].filename ; DX points to ASCIZ pathname
|
||
mov AH,DELFILE ; delete a file
|
||
int MSDOS
|
||
jc del_ret
|
||
xor AX,AX ; carry not set, return zero
|
||
del_ret: pop BP
|
||
ret
|
||
dos%del endp
|
||
;;;
|
||
;;; Copy a file
|
||
;;;
|
||
copy_arg struc
|
||
handle1 dw ? ; source file handle
|
||
handle2 dw ? ; destination file handle
|
||
copy_buf db 128 dup (0) ; temporary buffer for copy
|
||
copy_BP dw ? ; caller's BP
|
||
dd ? ; return address
|
||
dw ? ; original return address
|
||
file1 dw ? ; source file name
|
||
file2 dw ? ; destination file name
|
||
copy_arg ends
|
||
|
||
dos%copy proc far
|
||
push BP
|
||
sub SP,offset copy_BP ; allocate local storage
|
||
mov BP,SP
|
||
mov DX,[BP].file1
|
||
mov AH,OPENFILE ; open a file (source)
|
||
mov AL,READ ; access mode: read
|
||
int MSDOS
|
||
jc copy_ret ; carry set, return
|
||
mov [BP].handle1,AX
|
||
mov DX,[BP].file2
|
||
mov CX,0 ; file attribute
|
||
mov AH,CRFILE ; create a file (destination)
|
||
int MSDOS
|
||
jc copy_ret
|
||
mov [BP].handle2,AX
|
||
; copy bytes from source file to destination file
|
||
copy_01: lea DX,[BP].copy_buf
|
||
mov CX,128
|
||
mov BX,[BP].handle1
|
||
mov AH,RFILE ; read from file
|
||
int MSDOS
|
||
cmp AX,0 ; end of file?
|
||
je copy_10 ; yes, jump
|
||
mov CX,AX ; number of bytes to move
|
||
lea DX,[BP].copy_buf
|
||
mov BX,[BP].handle2
|
||
mov AH,WFILE ; write to a file
|
||
int MSDOS
|
||
jmp copy_01
|
||
; close source file and destination file
|
||
copy_10: mov BX,[BP].handle1
|
||
mov AH,CLFILE ; close a file
|
||
int MSDOS
|
||
mov BX,[BP].handle2
|
||
mov AH,CLFILE ; close a file
|
||
int MSDOS
|
||
xor AX,AX
|
||
copy_ret: add SP,offset copy_BP ; release local storage
|
||
pop BP
|
||
ret
|
||
dos%copy endp
|
||
;;;
|
||
;;; Rename files under current directory
|
||
;;;
|
||
ren%mov proc near
|
||
cmp byte ptr [DI],2ah ; an '*'
|
||
je renmv1
|
||
cmp byte ptr [DI],3fh ; a '?'
|
||
je renmv1
|
||
mov AL,byte ptr [DI] ; otherwise move in the new file char
|
||
renmv1: mov byte ptr [BX],AL
|
||
ret
|
||
ren%mov endp
|
||
|
||
ren_arg struc
|
||
ren_BP dw ? ; caller's BP
|
||
dd ? ; return address
|
||
dw ? ; original return address
|
||
oldfile dw ? ; old file name
|
||
newfile dw ? ; new file name
|
||
ren_arg ends
|
||
|
||
dos%ren proc far
|
||
push BP
|
||
mov BP,SP
|
||
|
||
mov DX,offset DGROUP:dta
|
||
mov AH,SETADDR ; set disk transfer address
|
||
int MSDOS
|
||
|
||
mov DX,[BP].oldfile
|
||
mov CX,0 ; search attribute
|
||
mov AH,FINDFILE ; find match file
|
||
int MSDOS
|
||
jc ren_ret
|
||
|
||
ren_01: mov SI,offset DGROUP:dta
|
||
add SI,29 ; points to filespec
|
||
mov DI,[BP].newfile
|
||
mov BX,offset DGROUP:filespec
|
||
|
||
ren_02: inc SI
|
||
cmp byte ptr ES:[SI],00h ; end of the string
|
||
je ren_03
|
||
cmp byte ptr ES:[SI],2eh ; an '.'?
|
||
je ren_03
|
||
mov AL,byte ptr ES:[SI]
|
||
call ren%mov
|
||
inc DI
|
||
inc BX
|
||
cmp byte ptr [DI-1],2ah
|
||
jne ren_02
|
||
cmp byte ptr [SI+1],2eh ;next char a '.'?
|
||
je ren_02
|
||
dec DI
|
||
jmp ren_02
|
||
;
|
||
ren_03:
|
||
cmp byte ptr [DI],00h ; end of the string
|
||
je ren_04
|
||
cmp byte ptr [DI],3fh ; a '?'
|
||
je ren_04
|
||
cmp byte ptr [DI],2ah ; an '*'
|
||
je ren_04
|
||
cmp byte ptr [DI-1],2eh ; previous character a '.'?
|
||
je ren_02
|
||
mov AL,byte ptr ES:[SI-1]
|
||
call ren%mov
|
||
inc DI
|
||
inc BX
|
||
jmp ren_03
|
||
;
|
||
; rename the file
|
||
;
|
||
ren_04: mov byte ptr [BX],0
|
||
mov DI,offset DGROUP:filespec
|
||
mov DX,offset DGROUP:dta
|
||
add DX,30
|
||
mov AH,CHGNAME ; move a directory entry
|
||
int MSDOS
|
||
|
||
mov AH,FINDNEXT ; find next match file
|
||
int MSDOS
|
||
jnc ren_01 ; carry not set, do next file
|
||
ren_100: xor AX,AX
|
||
ren_ret: pop BP
|
||
ret
|
||
dos%ren endp
|
||
|
||
;;;
|
||
;;; Get the file size
|
||
;;;
|
||
size_arg struc
|
||
dw ? ; caller's BP
|
||
dd ? ; caller's return address
|
||
dw ?
|
||
file dw ?
|
||
size_arg ends
|
||
|
||
dos%size proc far
|
||
push BP
|
||
mov BP,SP
|
||
mov DX,offset DGROUP:dta
|
||
mov AH,SETADDR ; set disk transfer address
|
||
int MSDOS
|
||
mov DX,[BP].file
|
||
mov CX,0 ; search attribute
|
||
mov AH,FINDFILE ; find match file
|
||
int MSDOS
|
||
jnc size_01
|
||
xor BX,BX ; return 0 for invalid access
|
||
xor AX,AX
|
||
jmp size_ret
|
||
size_01: mov DI,offset DGROUP:dta
|
||
mov AX,word ptr [DI+28] ; high word of file size
|
||
mov BX,word ptr [DI+26] ; low word of file size
|
||
size_ret: pop BP
|
||
ret
|
||
dos%size endp
|
||
;;;
|
||
;;; Change the current directory
|
||
;;;
|
||
cd_arg struc
|
||
cd_BP dw ? ; caller's BP
|
||
dd ? ; caller's return address
|
||
dw ?
|
||
dir dw ?
|
||
cd_arg ends
|
||
dos%cd proc far
|
||
push BP
|
||
mov BP,SP
|
||
mov AH,CURDISK ; current disk
|
||
int MSDOS
|
||
inc AL
|
||
mov DL,AL ; drive number
|
||
add AL,40H ; drive character
|
||
mov curdrv,AL
|
||
mov SI,offset DGROUP:curdir
|
||
mov AH,CURRDIR ; return current directory
|
||
int MSDOS
|
||
mov DX,[BP].dir
|
||
mov AH,CHNGDIR ; change the current directory
|
||
int MSDOS
|
||
mov AX,offset DGROUP:curdrv
|
||
cd_ret: pop BP
|
||
ret
|
||
dos%cd endp
|
||
;;;
|
||
;;; Change the current drive
|
||
;;;
|
||
drv_arg struc
|
||
dw ? ; caller's BP
|
||
dd ? ; caller's return address
|
||
dw ?
|
||
drive db ?
|
||
drv_arg ends
|
||
dos%drv proc far
|
||
push BP
|
||
mov BP,SP
|
||
mov DL,[BP].drive
|
||
mov AH,CURDISK ; current disk
|
||
int MSDOS
|
||
mov [BP].drive,AL
|
||
sub DL,41H ; get the drive number
|
||
cmp DL,0
|
||
jl drv_ret
|
||
cmp DL,10 ; maximum nuber of drive?
|
||
jg drv_ret
|
||
mov AH,SELDISK ; select disk
|
||
int MSDOS
|
||
cmp DL,AL ; AL = number of drives
|
||
jl drv_01
|
||
mov DL,[BP].drive ; get the current disk
|
||
mov AH,SELDISK ; select disk
|
||
int MSDOS
|
||
jmp drv_ret
|
||
drv_01: xor AX,AX
|
||
jmp drv_ret1
|
||
drv_ret: mov AX,-1 ; error
|
||
drv_ret1: pop BP
|
||
ret
|
||
dos%drv endp
|
||
;;;
|
||
;;; Move the file pointer right before EOF character and overwrite it
|
||
;;; to fix the bug in open-extend-file
|
||
;;;
|
||
mov_arg struc
|
||
m_buffer dw 0
|
||
mov_BP dw ? ; caller's BP
|
||
dd ? ; caller's return address
|
||
dw ?
|
||
fhandle dw ? ; file handle
|
||
mov_arg ends
|
||
|
||
mov%fptr proc far
|
||
push BP
|
||
sub SP,offset mov_BP ; allocate for local variable
|
||
mov BP,SP
|
||
mov AL,2 ; move the pointer to end of file
|
||
mov DX,-128 ; and with offset (one record size)
|
||
mov CX,-1
|
||
mov AH,MOVPTR
|
||
mov BX,[BP].fhandle ; file handle
|
||
int MSDOS
|
||
jc mov_ret
|
||
cmp DX,0 ; small file?
|
||
jge mov_001
|
||
mov AL,0
|
||
xor CX,CX
|
||
xor DX,DX
|
||
mov AH,MOVPTR
|
||
int MSDOS
|
||
jc mov_ret
|
||
mov_001: lea DX,[BP].m_buffer ; address of buffer
|
||
mov_01: mov CX,1 ; read one character at a time
|
||
mov AH,RFILE ; read it
|
||
int MSDOS
|
||
jc mov_ret
|
||
mov CL,byte ptr [BP].m_buffer
|
||
cmp CL,1AH ; reach eof character?
|
||
je mov_05 ; yes, go overwrite it
|
||
cmp AX,0 ; at eof, but no eof char?
|
||
je mov_ret ; Yes, return
|
||
jmp short mov_01 ; No, loop
|
||
; file pointer right after the EOF character
|
||
mov_05: mov AL,1 ; move the pointer to the current
|
||
mov DX,-1 ; location plus offset
|
||
mov CX,-1
|
||
mov AH,MOVPTR
|
||
int MSDOS
|
||
jc mov_ret
|
||
; file pointer points to EOF character
|
||
mov CX,1 ; write one byte
|
||
mov BX,[BP].fhandle ; file handle
|
||
mov [BP].m_buffer,0
|
||
lea DX,[BP].m_buffer ; address of buffer
|
||
mov AH,WFILE ; write it
|
||
int MSDOS
|
||
jc mov_ret
|
||
mov AL,1 ; move the pointer to the current
|
||
mov DX,-1 ; location plus offset
|
||
mov CX,DX
|
||
mov AH,MOVPTR
|
||
mov BX,[BP].fhandle ; file handle
|
||
int MSDOS
|
||
jc mov_ret
|
||
xor AX,AX
|
||
mov_ret: add SP,offset mov_BP ; release local storage
|
||
pop BP
|
||
ret
|
||
mov%fptr endp
|
||
progx ends
|
||
|
||
PGROUP group prog
|
||
prog segment byte public 'PROG'
|
||
assume CS:PGROUP
|
||
|
||
get_args struc
|
||
dw ? ; caller's BP
|
||
dw ? ; return address
|
||
get_ary dw ? ; pointer to result array
|
||
get_args ends
|
||
|
||
time_fmt struc ; format of data returned by get_time()
|
||
tim_hour dw ? ; hour
|
||
tim_min dw ? ; minute
|
||
tim_sec dw ? ; seconds
|
||
tim_hnds dw ? ; hundredths
|
||
time_fmt ends
|
||
|
||
public get_time
|
||
get_time proc near
|
||
push BP ; save caller's BP
|
||
mov BP,SP ; establish operand addressability
|
||
|
||
mov AH,GETTIME ; load "get_time" service call id
|
||
int MSDOS ; request service from MS-DOS
|
||
mov BX,[BP].get_ary ; load pointer to result array
|
||
xor AX,AX ; clear AX
|
||
mov AL,CH ; copy hours
|
||
mov [BX].tim_hour,AX ; and store into result array
|
||
mov AL,CL ; copy minutes
|
||
mov [BX].tim_min,AX ; and store into result array
|
||
mov AL,DH ; copy seconds
|
||
mov [BX].tim_sec,AX ; and store into result array
|
||
mov AL,DL ; copy hundredths
|
||
mov [BX].tim_hnds,AX ; and store into result array
|
||
|
||
pop BP
|
||
ret
|
||
get_time endp
|
||
;*************************************************************************
|
||
; Link to Delete a file support
|
||
;*************************************************************************
|
||
public delete
|
||
delete proc near
|
||
call dos%del
|
||
ret
|
||
delete endp
|
||
;*************************************************************************
|
||
; Link to Copy a file support
|
||
;*************************************************************************
|
||
public copy_fil
|
||
copy_fil proc near
|
||
call dos%copy
|
||
ret
|
||
copy_fil endp
|
||
;*************************************************************************
|
||
; Link to Rename a file support
|
||
;*************************************************************************
|
||
public rename
|
||
rename proc near
|
||
call dos%ren
|
||
ret
|
||
rename endp
|
||
;*************************************************************************
|
||
; Link to file size support
|
||
;*************************************************************************
|
||
public filesize
|
||
filesize proc near
|
||
call dos%size
|
||
ret
|
||
filesize endp
|
||
;*************************************************************************
|
||
; Link to Change directory support
|
||
;*************************************************************************
|
||
public chgdir
|
||
chgdir proc near
|
||
call dos%cd
|
||
ret
|
||
chgdir endp
|
||
;*************************************************************************
|
||
; Link to Change drive support
|
||
;*************************************************************************
|
||
public chgdrv
|
||
chgdrv proc near
|
||
call dos%drv
|
||
ret
|
||
chgdrv endp
|
||
;
|
||
public mov_fptr
|
||
mov_fptr proc near
|
||
call mov%fptr
|
||
ret
|
||
mov_fptr endp
|
||
|
||
|
||
prog ends
|
||
end
|
||
|