pcs/msdos.asm

471 lines
13 KiB
NASM
Raw Normal View History

2023-05-20 05:57:05 -04:00
;***************************************
;* 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