mirror of
https://github.com/microsoft/MS-DOS.git
synced 2026-01-26 13:22:55 +00:00
MZ is back!
This commit is contained in:
241
v4.0/src/CMD/COMMAND/COMEQU.ASM
Normal file
241
v4.0/src/CMD/COMMAND/COMEQU.ASM
Normal file
@@ -0,0 +1,241 @@
|
||||
; SCCSID = @(#)comequ.asm 1.1 85/05/14
|
||||
; SCCSID = @(#)comequ.asm 1.1 85/05/14
|
||||
;*************************************
|
||||
; COMMAND EQUs which are not switch dependant
|
||||
|
||||
EMGDEBUG = FALSE
|
||||
|
||||
SYM EQU ">"
|
||||
|
||||
LINESPERPAGE EQU 25 ;AC000; default lines per page
|
||||
NORMPERLIN EQU 1
|
||||
WIDEPERLIN EQU 5
|
||||
COMBUFLEN EQU 128 ; Length of commmand buffer
|
||||
BatLen EQU 32 ; buffer for batch files
|
||||
YES_ECHO EQU 1 ; echo line
|
||||
NO_ECHO EQU 0 ; don't echo line
|
||||
No_Echo_Char EQU "@" ; don't echo line if this is first char
|
||||
call_in_progress EQU 1 ; indicate we're in the CALL command
|
||||
length_call EQU 4 ; length of CALL
|
||||
max_nest EQU 10 ; max # levels of batch nesting allowed
|
||||
fail_allowed EQU 00001000b ; critical error
|
||||
retry_allowed EQU 00010000b ; critical error
|
||||
Ignore_allowed EQU 00100000b ; critical error
|
||||
nullcommand EQU 1 ; no command on command line
|
||||
end_of_line EQU -1 ;AN000; end of line return from parser
|
||||
end_of_line_out EQU 0 ;AN000; end of line for output
|
||||
end_of_line_in EQU 0dh ;AN000; end of line for input
|
||||
result_number EQU 1 ;AN000; number returned from parser
|
||||
result_string EQU 3 ;AN000; string returned from parser
|
||||
result_filespec EQU 5 ;AN000; filespec returned from parser
|
||||
result_drive EQU 6 ;AN000; drive returned from parser
|
||||
result_date EQU 7 ;AN000; date returned from parser
|
||||
result_time EQU 8 ;AN000; time returned from parser
|
||||
result_no_error EQU 0 ;AN000; no error returned from parser
|
||||
no_cont_flag EQU 0 ;AN000; no control flags for message
|
||||
util_msg_class EQU -1 ;AN000; message class for utility
|
||||
ext_msg_class EQU 1 ;AN000; message class for extended error
|
||||
parse_msg_class EQU 2 ;AN000; message class for parse error
|
||||
crit_msg_class EQU 3 ;AN000; message class for critical error
|
||||
ext_crlf_class EQU 081h ;AN054; message class for extended error with no CRLF
|
||||
colon_char EQU ":" ;AN000; colon character
|
||||
crt_ioctl_ln EQU 14 ;AN000; default length of data for display ioctl
|
||||
text_mode EQU 1 ;AN000; text mode return from ioctl
|
||||
get_generic EQU 07Fh ;AN000; generic ioctl - get device info
|
||||
set_crit_dev EQU 0100H ;AN000; device attribute for critical error on I/0
|
||||
mult_ansi EQU 01Ah ;AC064; multiplex for ansi.sys
|
||||
mult_shell_get EQU 01902h ;AC065; multiplex for Shell - get next command
|
||||
mult_shell_brk EQU 01903h ;AN000; multiplex for Shell - ^C batch check
|
||||
shell_action equ 0ffh ;AN000; SHELL - return for taking SHELL specific action
|
||||
bat_not_open EQU -1 ;AN000; batch handle will be set to this if not open
|
||||
bat_open_handle EQU 19 ;AN000; handle will be in this position in JFN table
|
||||
Ptr_seg_pos equ 7 ;AN000; Offset from start of message block for subst segment
|
||||
Ptr_off_pos equ 5 ;AN000; Offset from start of message block for subst offset
|
||||
Parm_off_pos equ word ptr 2 ;AN000; Offset from start of subst list for subst offset
|
||||
parm_block_size equ 11 ;AN000; size of message subst block
|
||||
blank equ " " ;AN000; blank character
|
||||
no_subst equ 0 ;AN000; no substitutions for messages
|
||||
one_subst equ 1 ;AN000; one substitution for messages
|
||||
no_handle_out equ -1 ;AN000; use function 1 thru 12 for message retriever
|
||||
res_subst equ 2 ;AN000; offset from start of message definition to number of subst
|
||||
read_open_mode equ 0000000000000000b ;AN024; extended open mode for read
|
||||
read_open_flag equ 0000000100000001b ;AN000; extended open flags for read
|
||||
write_open_mode equ 0000000000000001b ;AN024; extended open mode for read
|
||||
write_open_flag equ 0000000100000001b ;AN000; extended open flags for read
|
||||
creat_open_flag equ 0000000100010010b ;AN000; extended open flags for read
|
||||
get_CPSW equ 3 ;AN000; minor function for get CPSW status
|
||||
CPSW_off equ 0 ;AN000; CPSW return from function - OFF
|
||||
Get_XA equ 2 ;AN030; minor function for get extended attributes
|
||||
Set_XA equ 4 ;AN000; minor function for set extended attributes
|
||||
file_no_cpage equ 0 ;AN000; file has no code page tag
|
||||
file_inv_cpage equ -1 ;AN000; file has invalid code page tag
|
||||
do_xa equ -1 ;AN000; flag to get extended attributes
|
||||
inv_cp_tag equ 0 ;AC039; tag for invalid code page
|
||||
no_xa_seg equ -1 ;AN000; no segment for extended attributes - COPY
|
||||
capital_A equ 'A' ;AC000;
|
||||
vbar equ '|' ;AC000;
|
||||
labracket equ '<' ;AC000;
|
||||
rabracket equ '>' ;AC000;
|
||||
dollar equ '$' ;AC000;
|
||||
lparen equ '(' ;AC000;
|
||||
rparen equ ')' ;AC000;
|
||||
nullrparen equ 29h ;AC000;
|
||||
in_word equ 4e49h ;AC000; 'NI' ('IN' backwards)
|
||||
do_word equ 4f44h ;AC000; 'OD' ('DO' backwards)
|
||||
star equ '*' ;AC000;
|
||||
plus_chr equ '+' ;AC000;
|
||||
small_a equ 'a' ;AC000;
|
||||
small_z equ 'z' ;AC000;
|
||||
dot_chr equ '.' ;AC000;
|
||||
tab_chr equ 9 ;AN032;
|
||||
equal_chr equ '=' ;AN032;
|
||||
semicolon equ ';' ;AN049;
|
||||
dot_qmark equ 2e3fh ;AC000; '.?'
|
||||
dot_colon equ 2e3ah ;AC000; '.:'
|
||||
capital_n equ 0 ;AC000; result from Y/N call if N entered
|
||||
capital_y equ 1 ;AC000; result from Y/N call if Y entered
|
||||
AppendInstall equ 0B700H ;AN020; append install check
|
||||
AppendDOS equ 0B702H ;AN020; append DOS version check
|
||||
AppendGetState equ 0B706H ;AN020; append get current state
|
||||
AppendSetState equ 0B707H ;AN020; append set current state
|
||||
AppendTruename equ 0B711H ;AN042; Get file's real location for Batch
|
||||
search_attr equ attr_read_only+attr_hidden+attr_directory ;AC042;
|
||||
|
||||
;*************************************
|
||||
;* PARSE ERROR MESSAGES
|
||||
;*************************************
|
||||
|
||||
MoreArgs_Ptr equ 1 ;AN000;"Too many parameters" message number
|
||||
LessArgs_Ptr equ 2 ;AN000;"Required parameter missing" message number
|
||||
BadSwt_Ptr equ 3 ;AN000;"Invalid switch" message number
|
||||
BadParm_Ptr equ 10 ;AN000;"Invalid parameter" message number
|
||||
|
||||
;*************************************
|
||||
;* EQUATES FOR MESSAGE RETRIEVER
|
||||
;*************************************
|
||||
|
||||
GET_EXTENDED_MSG EQU 0 ;AN000; get extended message address
|
||||
SET_EXTENDED_MSG EQU 1 ;AN000; set extended message address
|
||||
GET_PARSE_MSG EQU 2 ;AN000; get parse message address
|
||||
SET_PARSE_MSG EQU 3 ;AN000; set parse message address
|
||||
GET_CRITICAL_MSG EQU 4 ;AN000; get critical message address
|
||||
SET_CRITICAL_MSG EQU 5 ;AN000; set critical message address
|
||||
MESSAGE_2F EQU 46 ;AN000; minor code for message retriever
|
||||
|
||||
;*********************************
|
||||
;* EQUATES FOR INT 10H
|
||||
;*********************************
|
||||
|
||||
VIDEO_IO_INT EQU 10H ;AN000; equate for int 10h
|
||||
SET_VIDEO_MODE EQU 0 ;AN000; set video mode
|
||||
SET_CURSOR_POSITION EQU 2 ;AN000; set new cursor position
|
||||
SCROLL_VIDEO_PAGE EQU 6 ;AN000; scroll active page up
|
||||
VIDEO_ATTRIBUTE EQU 7 ;AN000; attribute to be used on blank line
|
||||
SET_COLOR_PALETTE EQU 11 ;AN000; set color for video
|
||||
GET_VIDEO_STATE EQU 15 ;AN000; get current video state
|
||||
VIDEO_ALPHA EQU 3 ;AN000; alpha video is 3 or below
|
||||
VIDEO_BW EQU 7 ;AN000; mode for 80X25 black & white
|
||||
|
||||
AltPipeChr equ "|" ; alternate pipe character
|
||||
|
||||
FCB EQU 5CH
|
||||
|
||||
VARSTRUC STRUC
|
||||
ISDIR DB ?
|
||||
SIZ DB ?
|
||||
TTAIL DW ?
|
||||
INFO DB ?
|
||||
BUF DB DIRSTRLEN + 20 DUP (?)
|
||||
VARSTRUC ENDS
|
||||
|
||||
fCheckDrive equ 00000001b
|
||||
fSwitchAllowed equ 00000010b
|
||||
|
||||
;
|
||||
; Test switches
|
||||
;
|
||||
fParse EQU 0001h ; display results of parseline
|
||||
|
||||
;
|
||||
; Batch segment structure
|
||||
;
|
||||
; BYTE type of segment
|
||||
; BYTE echo state of parent on entry to batch file
|
||||
; WORD segment of last batch file
|
||||
; WORD segment for FOR command
|
||||
; BYTE FOR flag state on entry to batch file
|
||||
; DWORD offset for next line
|
||||
; 10 WORD pointers to parameters. -1 is empty parameter
|
||||
; ASCIZ file name (with . and ..)
|
||||
; BYTES CR-terminated parameters
|
||||
; BYTE 0 flag to indicate end of parameters
|
||||
;
|
||||
|
||||
BatchType equ 0
|
||||
|
||||
BatchSegment struc
|
||||
BatType DB BatchType ; signature
|
||||
Batechoflag DB 0 ; G state of echo
|
||||
Batlast DW 0 ; G segment of last batch file
|
||||
Batforptr DW 0 ; G segment for FOR command
|
||||
Batforflag DB 0 ; G state of FOR
|
||||
BatSeek DD ? ; lseek position of next char
|
||||
BatParm DW 10 dup (?) ; pointers to parameters
|
||||
BatFile DB ? ; beginning of batch file name
|
||||
BatchSegment ends
|
||||
|
||||
ANULL equ 0 ; terminates an argv string
|
||||
ARGMAX equ 64 ; max args on a command line
|
||||
ARGBLEN equ 2*128 ; 1char each plus term NUL
|
||||
tplen equ 64 ; max size of one argument
|
||||
arg_cnt_error equ 1 ; number of args > MAXARG
|
||||
arg_buf_ovflow equ 2 ; overflowed argbuffer
|
||||
|
||||
argv_ele STRUC ; elements in the argv array
|
||||
argpointer DW (?) ; pointer to the argstring
|
||||
argflags DB (?) ; cparse flags for this argstring
|
||||
argstartel DW (?) ; the result of cparse's [STARTEL]
|
||||
arglen DW (?) ; cparse's char count + one (for null)
|
||||
argsw_word DW (?) ; any switches after this? what kinds?
|
||||
arg_ocomptr DW (?) ; pointer into original command string
|
||||
argv_ele ENDS
|
||||
|
||||
arg_unit STRUC
|
||||
argv DB (ARGMAX * SIZE argv_ele) DUP (?)
|
||||
argvcnt DW (?) ; number of arguments
|
||||
argswinfo DW (?) ; Switch information for entire line
|
||||
argbuf DW ARGBLEN DUP (?) ; storage for argv strings
|
||||
argforcombuf db COMBUFLEN DUP (?) ; Original for loop command string
|
||||
arg_unit ENDS
|
||||
|
||||
parseflags RECORD special_delim:1, unused:4, path_sep:1, wildcard:1, sw_flag:1
|
||||
|
||||
SwitchV EQU 10h
|
||||
SwitchB EQU 08h
|
||||
SwitchA EQU 04h
|
||||
SwitchP EQU 02h
|
||||
SwitchW EQU 01h
|
||||
fSwitch EQU 8000h
|
||||
fBadSwitch EQU 4000h
|
||||
|
||||
SwitchDir EQU SwitchP + SwitchW + fSwitch
|
||||
SwitchCopy EQU SwitchV + SwitchA + SwitchB + fSwitch
|
||||
|
||||
break <Trap: Get the attention of MSDOS>
|
||||
; TRAP snares the operating system for a service call
|
||||
; AX, as well as any other registers MS-DOS takes a fancy to, will be crunched.
|
||||
trap MACRO dos_function,dos_info
|
||||
ifnb <dos_info>
|
||||
mov AX, (dos_function SHL 8) + dos_info
|
||||
else
|
||||
mov AX, (dos_function SHL 8)
|
||||
endif
|
||||
int int_command
|
||||
ENDM
|
||||
|
||||
;
|
||||
; Equates for initialization
|
||||
;
|
||||
initInit equ 01h ; initialization in progress
|
||||
initSpecial equ 02h ; in initialization time/date routine
|
||||
initCtrlC equ 04h ; already in ^C handler
|
||||
6
v4.0/src/CMD/COMMAND/COMMAND.LNK
Normal file
6
v4.0/src/CMD/COMMAND/COMMAND.LNK
Normal file
@@ -0,0 +1,6 @@
|
||||
/map COMMAND1.OBJ COMMAND2.OBJ RUCODE.OBJ RDATA.OBJ INIT.OBJ IPARSE.OBJ +
|
||||
UINIT.OBJ TCODE.OBJ TBATCH.OBJ TBATCH2.OBJ TFOR.OBJ TCMD1A.OBJ TCMD1B.OBJ +
|
||||
TCMD2A.OBJ TCMD2B.OBJ TENV.OBJ TENV2.OBJ TMISC1.OBJ TMISC2.OBJ TPIPE.OBJ +
|
||||
PARSE2.OBJ PATH1.OBJ PATH2.OBJ TUCODE.OBJ COPY.OBJ COPYPR1.OBJ COPYPR2.OBJ +
|
||||
CPARSE.OBJ TPARSE.OBJ TPRINTF.OBJ TDATA.OBJ TSPC.OBJ,COMMAND.EXE,,;
|
||||
|
||||
213
v4.0/src/CMD/COMMAND/COMMAND.SKL
Normal file
213
v4.0/src/CMD/COMMAND/COMMAND.SKL
Normal file
@@ -0,0 +1,213 @@
|
||||
|
||||
;*************************
|
||||
;* MESSAGE SKELETON FILE *
|
||||
;*************************
|
||||
|
||||
:util COMMAND ;AC000;
|
||||
|
||||
:class 1 ;AC000; Transient extended errors
|
||||
|
||||
:use EXTEND2 ;AC000; "File not found"
|
||||
:use EXTEND3 ;AC000; "Path not found"
|
||||
:use EXTEND8 ;AC000; "Insufficient memory"
|
||||
|
||||
:class 2 ;AC000; Transient parse errors
|
||||
|
||||
:class 3 ;AC000; Resident extended errors
|
||||
:use -1 EXTEND999 ;AN000; "Extended error #"
|
||||
|
||||
:class 4 ;AC000; Resident parse errors
|
||||
:use -1 PARSE999 ;AN000; "Parse error #"
|
||||
|
||||
:class A ;AC000; resident messages
|
||||
|
||||
:use 220 COMMON17 ;AC000; "File allocation table bad, drive %1"
|
||||
:use 223 COMMON28 ;AC000; "Press any key to continue"
|
||||
:def 201 "A" ;AC000;
|
||||
:def 202 "R" ;AC000;
|
||||
:def 203 "I" ;AC000;
|
||||
:def 204 "F" ;AC000;
|
||||
:def 205 "Y" ;AC000;
|
||||
:def 206 "N" ;AC000;
|
||||
:def 210 "Abort" ;AC000;
|
||||
:def 211 ", Retry" ;AC000;
|
||||
:def 212 ", Ignore" ;AC000;
|
||||
:def 213 ", Fail" ;AC000;
|
||||
:def 214 "?" ;AC000;
|
||||
:def 215 "reading",0 ;AC000;
|
||||
:def 216 "writing",0 ;AC000;
|
||||
:def 217 " %1 drive %2",CR,LF ;AC000;
|
||||
:def 218 " %1 device %2",CR,LF ;AC000;
|
||||
:def 219 "Please insert volume %1 serial %2-%3",CR,LF ;AC009;
|
||||
:def 221 "Invalid COMMAND.COM",CR,LF ;AC000;
|
||||
:def 222 "Insert disk with %1 in drive %2",CR,LF ;AC000;
|
||||
:def 224 CR,LF,"Terminate batch job (Y/N)?" ;AC000;
|
||||
:def 225 "Cannot execute %1",CR,LF ;AC000;
|
||||
:def 226 "Error in EXE file",CR,LF ;AC000;
|
||||
:def 227 "Program too big to fit in memory",CR,LF ;AC000;
|
||||
:def 228 CR,LF,"No free file handles" ;AC000;
|
||||
:def 229 "Bad Command or file name",CR,LF ;AC000;
|
||||
:use 230 EXTEND5 ;AC000;
|
||||
:def 231 CR,LF,"Memory allocation error" ;AC000;
|
||||
:def 232 CR,LF,"Cannot load COMMAND, system halted",CR,LF;AC000;
|
||||
:def 233 CR,LF,"Cannot start COMMAND, exiting",CR,LF ;AC000;
|
||||
:def 234 CR,LF,"Top level process aborted, cannot continue",CR,LF;AC000;
|
||||
:def 235 CR,LF ;AC000;
|
||||
|
||||
|
||||
:class B ;AC000; Initialization messages
|
||||
|
||||
:use 461 COMMON1 ;AC000; "Incorrect DOS version"
|
||||
:def 463 "Out of environment space",CR,LF ;AC000;
|
||||
:def 464 CR,LF,CR,LF,"MS DOS ",CR,LF
|
||||
"Version 4.00 (C)Copyright International Business Machines Corp 1981,1988",CR,LF
|
||||
" (C)Copyright Microsoft Corp 1981, 1988",CR,LF ;AC000;
|
||||
:def 465 "Specified COMMAND search directory bad",CR,LF ;AC025;
|
||||
:def 466 "Specified COMMAND search directory bad access denied",CR,LF ;AC025;
|
||||
|
||||
:class C ;AC000; Parse messages
|
||||
|
||||
:use PARSE1 ;AC000; "Too many parameters"
|
||||
:use PARSE2 ;AC000; "Required parameter missing"
|
||||
:use PARSE3 ;AC000; "Invalid switch"
|
||||
:use PARSE4 ;AC000; "Invalid keyword"
|
||||
:use PARSE6 ;AC000; "Parameter value not in allowed range"
|
||||
:use PARSE7 ;AC000; "Parameter value not allowed"
|
||||
:use PARSE8 ;AC000; "Parameter value not allowed"
|
||||
:use PARSE9 ;AC000; "Parameter format not correct"
|
||||
:use PARSE10 ;AC000; "Invalid parameter"
|
||||
:use PARSE11 ;AC000; "Invalid parameter combination"
|
||||
|
||||
:class D ;AC000; Extended errors - critical
|
||||
|
||||
:use EXTEND19 ;AC000; "Write protect"
|
||||
:use EXTEND20 ;AC000; "Invalid unit"
|
||||
:use EXTEND21 ;AC000; "Drive not ready"
|
||||
:use EXTEND22 ;AC000; "Invalid device request"
|
||||
:use EXTEND23 ;AC000; "Data error"
|
||||
:use EXTEND24 ;AC000; "Invalid device request parameters"
|
||||
:use EXTEND25 ;AC000; "Seek error"
|
||||
:use EXTEND26 ;AC000; "Invalid media type"
|
||||
:use EXTEND27 ;AC000; "Sector not found"
|
||||
:use EXTEND28 ;AC000; "Printer out of paper"
|
||||
:use EXTEND29 ;AC000; "Write fault error"
|
||||
:use EXTEND30 ;AC000; "Read fault error"
|
||||
:use EXTEND31 ;AC000; "General Failure"
|
||||
:use EXTEND32 ;AC000; "Sharing Violation"
|
||||
:use EXTEND33 ;AC000; "Lock Violation"
|
||||
:use EXTEND34 ;AC000; "Invalid Disk Change"
|
||||
:use EXTEND35 ;AC000; "FCB unavailable"
|
||||
:use EXTEND36 ;AC000; "System resource exhausted"
|
||||
:use EXTEND37 ;AC000; "Code page mismatch"
|
||||
:use EXTEND38 ;AC026; "Out of input"
|
||||
:use EXTEND39 ;AC026; "Insufficient disk space"
|
||||
|
||||
:class E ;AC000; extended errors
|
||||
|
||||
:use EXTEND1 ;AC000; "Invalid Function"
|
||||
:use EXTEND2 ;AC000; "File not found"
|
||||
:use EXTEND3 ;AC000; "Path not found"
|
||||
:use EXTEND4 ;AC000; "Too many open files"
|
||||
:use EXTEND5 ;AC000; "Access denied"
|
||||
:use EXTEND6 ;AC000; "Invalid handle"
|
||||
:use EXTEND7 ;AC000; "Memory control blocks destroyed"
|
||||
:use EXTEND8 ;AC000; "Insufficient memory"
|
||||
:use EXTEND9 ;AC000; "Invalid memory block address"
|
||||
:use EXTEND10 ;AC000; "Invalid Environment"
|
||||
:use EXTEND11 ;AC000; "Invalid format"
|
||||
:use EXTEND12 ;AC000; "Invalid function parameter"
|
||||
:use EXTEND13 ;AC000; "Invalid data"
|
||||
:use EXTEND15 ;AC000; "Invalid drive specification"
|
||||
:use EXTEND16 ;AC000; "Attempt to remove current directory"
|
||||
:use EXTEND17 ;AC000; "Not same device"
|
||||
:use EXTEND18 ;AC000; "No more files"
|
||||
:use EXTEND80 ;AC000; "File already exists"
|
||||
:use EXTEND82 ;AC000; "Can not make directory entry"
|
||||
:use EXTEND83 ;AC000; "Fail requested to Critical Error"
|
||||
:use EXTEND84 ;AC000; "Too many attaches"
|
||||
:use EXTEND85 ;AC000; "Device or file already attached"
|
||||
:use EXTEND86 ;AC000; "Invalid password"
|
||||
:use EXTEND87 ;AC000; "Invalid parameter"
|
||||
:use EXTEND88 ;AC000; "File system data fault"
|
||||
:use EXTEND89 ;AC000; "Function not supported by file system"
|
||||
:use EXTEND90 ;AC000;
|
||||
|
||||
|
||||
:class F ;AC000; Transient messages
|
||||
|
||||
:use 1020 COMMON4 ;AC000; "%1 bytes free",CR,LF
|
||||
:use 1015 COMMON18 ;AC000; "File cannot be copied onto itself",CR,LF
|
||||
:use 1004 COMMON20 ;AC000; "Insufficient disk space",CR,LF
|
||||
:use 1026 COMMON22 ;AC000; "Invalid code page",CR,LF
|
||||
:use 1031 COMMON23 ;AC000; "Invalid date"
|
||||
:use 1035 COMMON24 ;AC000; "Invalid time"
|
||||
:use 1062 COMMON25 ;AC000; "Invalid path"
|
||||
:use 1028 COMMON28 ;AC000; "Press any key to continue"
|
||||
:use 1045 COMMON32 ;AC000; "Unable to create directory",CR,LF
|
||||
:use 1041 COMMON33 ;AC000; "Volume in drive %1 has no label"
|
||||
:use 1042 COMMON34 ;AC000; "Volume in drive %1 is %2"
|
||||
:use 1043 COMMON36 ;AC000; "Volume Serial Number is %1"
|
||||
:def 1002 "Duplicate file name or file not found",CR,LF ;AC000;
|
||||
:def 1003 "Invalid path or file name",CR,LF ;AC000;
|
||||
:def 1007 "Out of environment space",CR,LF ;AC000;
|
||||
:def 1008 "File creation error",CR,LF ;AC000;
|
||||
:def 1009 "Batch file missing",CR,LF ;AC000;
|
||||
:def 1010 CR,LF,"Insert disk with batch file",CR,LF ;AC000;
|
||||
:def 1011 "Bad command or file name",CR,LF ;AC000;
|
||||
:use 1014 EXTEND5 ;AC000;
|
||||
:def 1016 "Content of destination lost before copy",CR,LF ;AC000;
|
||||
:def 1017 "Invalid filename or file not found",CR,LF ;AC000;
|
||||
:def 1018 "%1 File(s) copied",CR,LF ;AC000;
|
||||
:def 1019 "%1 File(s) " ;AC000;
|
||||
:use 1021 EXTEND15 ;AC000;
|
||||
:def 1022 "Code page %1 not prepared for system",CR,LF ;AC000;
|
||||
:def 1023 "Code page %1 not prepared for all devices",CR,LF ;AC000;
|
||||
:def 1024 "Active code page: %1",CR,LF ;AC000;
|
||||
:def 1025 "NLSFUNC not installed",CR,LF ;AC000;
|
||||
:def 1027 "Current drive is no longer valid" ;AC000;
|
||||
:def 1029 "Label not found",CR,LF ;AC000;
|
||||
:def 1030 "Syntax error",CR,LF ;AC000;
|
||||
:def 1032 "Current date is %1 %2",CR,LF ;AC000;
|
||||
:def 1033 "SunMonTueWedThuFriSat" ;AC000;
|
||||
:def 1034 "Enter new date (%1): " ;AC031;
|
||||
:def 1036 "Current time is %1",CR,LF ;AC000;
|
||||
:def 1037 "Enter new time: " ;AC031;
|
||||
:def 1038 ", Delete (Y/N)?" ;AC000;
|
||||
:def 1039 "All files in directory will be deleted!",CR,LF
|
||||
"Are you sure (Y/N)?" ;AC000;
|
||||
:def 1040 "Microsoft DOS Version %1.%2",CR,LF ;AC000;
|
||||
:def 1044 "Invalid directory",CR,LF ;AC000;
|
||||
:def 1046 "Invalid path, not directory,",CR,LF,"or directory not empty",CR,LF ;AC000;
|
||||
:def 1047 "Must specify ON or OFF",CR,LF ;AC000;
|
||||
:def 1048 "Directory of %1",CR,LF ;AC000;
|
||||
:def 1049 "No Path",CR,LF ;AC000;
|
||||
:def 1050 "Invalid drive in search path",CR,LF ;AC000;
|
||||
:def 1051 "Invalid device",CR,LF ;AC000;
|
||||
:def 1052 "FOR cannot be nested",CR,LF ;AC000;
|
||||
:def 1053 "Intermediate file error during pipe",CR,LF ;AC000;
|
||||
:def 1054 "Cannot do binary reads from a device",CR,LF ;AC000;
|
||||
:def 1055 "BREAK is %1",CR,LF ;AC000;
|
||||
:def 1056 "VERIFY is %1",CR,LF ;AC000;
|
||||
:def 1057 "ECHO is %1",CR,LF ;AC000;
|
||||
:def 1059 "off",0 ;AC000;
|
||||
:def 1060 "on",0 ;AC000;
|
||||
:def 1061 "Error writing to device",CR,LF ;AC000;
|
||||
:def 1063 "%1" ;AC000;
|
||||
:def 1064 "%1" ;AC000;
|
||||
:def 1065 "%1" ;AC000;
|
||||
:def 1066 "%1" ;AC000;
|
||||
:def 1067 9 ;AC000;
|
||||
:def 1068 " <DIR> " ;AC000;
|
||||
:def 1069 8," ",8 ;AC000;
|
||||
:def 1070 CR,LF ;AC000;
|
||||
:def 1071 "%1" ;AC000;
|
||||
:def 1072 "mm-dd-yy" ;AC000;
|
||||
:def 1073 "dd-mm-yy" ;AC000;
|
||||
:def 1074 "yy-mm-dd" ;AC000;
|
||||
:def 1075 "%1 %2" ;AC000;
|
||||
:def 1076 "%1" ;AC000;
|
||||
:def 1077 " %1 %2" ;AC053;
|
||||
:def 1078 "Directory already exists",CR,LF ;AC000;
|
||||
|
||||
:end ;AC000;
|
||||
|
||||
638
v4.0/src/CMD/COMMAND/COMMAND1.ASM
Normal file
638
v4.0/src/CMD/COMMAND/COMMAND1.ASM
Normal file
@@ -0,0 +1,638 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)command1.asm 1.1 85/05/14
|
||||
; SCCSID = @(#)command1.asm 1.1 85/05/14
|
||||
TITLE COMMAND - resident code for COMMAND.COM
|
||||
NAME COMMAND
|
||||
|
||||
;*****************************************************************************
|
||||
;
|
||||
; MODULE: COMMAND.COM
|
||||
;
|
||||
; DESCRIPTIVE NAME: Default DOS command interpreter
|
||||
;
|
||||
; FUNCTION: This version of COMMAND is divided into three distinct
|
||||
; parts. First is the resident portion, which includes
|
||||
; handlers for interrupts 23H (Cntrl-C), 24H (fatal
|
||||
; error), and 2EH (command line execute); it also has
|
||||
; code to test and, if necessary, reload the transient
|
||||
; portion. Following the resident is the init code, which
|
||||
; is overwritten after use. Then comes the transient
|
||||
; portion, which includes all command processing (whether
|
||||
; internal or external). The transient portion loads at
|
||||
; the end of physical memory, and it may be overlayed by
|
||||
; programs that need as much memory as possible. When the
|
||||
; resident portion of command regains control from a user
|
||||
; program, a check sum is performed on the transient
|
||||
; portion to see if it must be reloaded. Thus programs
|
||||
; which do not need maximum memory will save the time
|
||||
; required to reload COMMAND when they terminate.
|
||||
;
|
||||
; ENTRY POINT: PROGSTART
|
||||
;
|
||||
; INPUT: command line at offset 81H
|
||||
;
|
||||
; EXIT_NORMAL: No exit from root level command processor. Can exit
|
||||
; from a secondary command processor via the EXIT
|
||||
; internal command.
|
||||
;
|
||||
; EXIT_ERROR: Exit to prior command processor if possible, otherwise
|
||||
; hang the system.
|
||||
;
|
||||
; INTERNAL REFERENCES:
|
||||
;
|
||||
; ROUTINES: See the COMMAND Subroutine Description Document
|
||||
; (COMMAND.DOC)
|
||||
;
|
||||
; DATA AREAS: See the COMMAND Subroutine Description Document
|
||||
; (COMMAND.DOC)
|
||||
;
|
||||
; EXTERNAL REFERENCES:
|
||||
;
|
||||
; ROUTINES: none
|
||||
;
|
||||
; DATA AREAS: none
|
||||
;
|
||||
;*****************************************************************************
|
||||
;
|
||||
; REVISION HISTORY
|
||||
; ----------------
|
||||
;
|
||||
; DOS 1.00 to DOS 3.30
|
||||
; --------------------------
|
||||
; SEE REVISION LOG IN COPY.ASM ALSO
|
||||
;
|
||||
; REV 1.17
|
||||
; 05/19/82 Fixed bug in BADEXE error (relocation error must return to
|
||||
; resident since the EXELOAD may have overwritten the transient.
|
||||
;
|
||||
; REV 1.18
|
||||
; 05/21/82 IBM version always looks on drive A
|
||||
; MSVER always looks on default drive
|
||||
;
|
||||
; REV 1.19
|
||||
; 06/03/82 Drive spec now entered in command line
|
||||
; 06/07/82 Added VER command (print DOS version number) and VOL command
|
||||
; (print volume label)
|
||||
;
|
||||
; REV 1.20
|
||||
; 06/09/82 Prints "directory" after directories
|
||||
; 06/13/82 MKDIR, CHDIR, PWD, RMDIR added
|
||||
;
|
||||
; REV 1.50
|
||||
; Some code for new 2.0 DOS, sort of HACKey. Not enough time to
|
||||
; do it right.
|
||||
;
|
||||
; REV 1.70
|
||||
; EXEC used to fork off new processes
|
||||
;
|
||||
; REV 1.80
|
||||
; C switch for single command execution
|
||||
;
|
||||
; REV 1.90
|
||||
; Batch uses XENIX
|
||||
;
|
||||
; Rev 2.00
|
||||
; Lots of neato stuff
|
||||
; IBM 2.00 level
|
||||
;
|
||||
; Rev 2.01
|
||||
; 'D' switch for date time suppression
|
||||
;
|
||||
; Rev 2.02
|
||||
; Default userpath is NUL rather than BIN
|
||||
; same as IBM
|
||||
; COMMAND split into pieces
|
||||
;
|
||||
; Rev 2.10
|
||||
; INTERNATIONAL SUPPORT
|
||||
;
|
||||
; Rev 2.50
|
||||
; all the 2.x new stuff -MU
|
||||
;
|
||||
; Rev 3.30 (Ellen G)
|
||||
; CALL internal command (TBATCH2.ASM)
|
||||
; CHCP internal command (TCMD2B.ASM)
|
||||
; INT 24H support of abort, retry, ignore, and fail prompt
|
||||
; @ sign suppression of batch file line
|
||||
; Replaceable environment value support in batch files
|
||||
; INT 2FH calls for APPEND
|
||||
; Lots of PTR fixes!
|
||||
;
|
||||
; Beyond 3.30 to forever (Ellen G)
|
||||
; ----------------------
|
||||
;
|
||||
; A000 DOS 4.00 - Use SYSPARSE for internal commands
|
||||
; Use Message Retriever services
|
||||
; /MSG switch for resident extended error msg
|
||||
; Convert to new capitalization support
|
||||
; Better error recovery on CHCP command
|
||||
; Code page file tag support
|
||||
; TRUENAME internal command
|
||||
; Extended screen line support
|
||||
; /P switch on DEL/ERASE command
|
||||
; Improved file redirection error recovery
|
||||
; (removed) Improved batch file performance
|
||||
; Unconditional DBCS support
|
||||
; Volume serial number support
|
||||
; (removed) COMMENT=?? support
|
||||
;
|
||||
; A001 PTM P20 Move system_cpage from TDATA to TSPC
|
||||
;
|
||||
; A002 PTM P74 Fix PRESCAN so that redirection symbols do not
|
||||
; require delimiters.
|
||||
;
|
||||
; A003 PTM P5,P9,P111 Included in A000 development
|
||||
;
|
||||
; A004 PTM P86 Fix IF command to turn off piping before
|
||||
; executing
|
||||
;
|
||||
; A005 DCR D17 If user specifies an extension on the command
|
||||
; line search for that extension only.
|
||||
;
|
||||
; A006 DCR D15 New message for MkDir - "Directory already
|
||||
; exists"
|
||||
;
|
||||
; A007 DCR D2 Change CTTY so that a write is done before XDUP
|
||||
;
|
||||
; A008 PTM P182 Change COPY to set default if invalid function
|
||||
; returned from code page call.
|
||||
;
|
||||
; A009 PTM P179 Add CRLF to invalid disk change message
|
||||
;
|
||||
; A010 DCR D43 Allow APPEND to do a far call to SYSPARSE in
|
||||
; transient COMMAND.
|
||||
;
|
||||
; A011 DCR D130 Change redirection to overwrite an EOF mark
|
||||
; before appending to a file.
|
||||
;
|
||||
; A012 PTM P189 Fix redirection error recovery.
|
||||
;
|
||||
; A013 PTM P330 Change date format
|
||||
;
|
||||
; A014 PTM P455 Fix echo parsing
|
||||
;
|
||||
; A015 PTM P517 Fix DIR problem with * vs *.
|
||||
;
|
||||
; A016 PTM P354 Fix extended error message addressing
|
||||
;
|
||||
; A017 PTM P448 Fix appending to 0 length files
|
||||
;
|
||||
; A018 PTM P566,P3903 Fix parse error messages to print out parameter
|
||||
; the parser fails on. Fail on duplicate switches.
|
||||
;
|
||||
; A019 PTM P542 Fix device name to be printed correctly during
|
||||
; critical error
|
||||
;
|
||||
; A020 DCR D43 Set append state off while in DIR
|
||||
;
|
||||
; A021 PTM P709 Fix CTTY printing ascii characters.
|
||||
;
|
||||
; A022 DCR D209 Enhanced error recovery
|
||||
;
|
||||
; A023 PTM P911 Fix ANSI.SYS IOCTL structure.
|
||||
;
|
||||
; A024 PTM P899 Fix EXTOPEN open modes.
|
||||
;
|
||||
; A025 PTM P922 Fix messages and optimize PARSE switches
|
||||
;
|
||||
; A026 DCR D191 Change redirection error recovery support.
|
||||
;
|
||||
; A027 PTM P991 Fix so that KAUTOBAT & AUTOEXEC are terminated
|
||||
; with a carriage return.
|
||||
;
|
||||
; A028 PTM P1076 Print a blank line before printing invalid
|
||||
; date and invalid time messages.
|
||||
;
|
||||
; A029 PTM P1084 Eliminate calls to parse_check_eol in DATE
|
||||
; and TIME.
|
||||
;
|
||||
; A030 DCR D201 New extended attribute format.
|
||||
;
|
||||
; A031 PTM P1149 Fix DATE/TIME add blank before prompt.
|
||||
;
|
||||
; A032 PTM P931 Fix =ON, =OFF for BREAK, VERIFY, ECHO
|
||||
;
|
||||
; A033 PTM P1298 Fix problem with system crashes on ECHO >""
|
||||
;
|
||||
; A034 PTM P1387 Fix COPY D:fname+,, to work
|
||||
;
|
||||
; A035 PTM P1407 Fix so that >> (appending) to a device does
|
||||
; do a read to determine eof.
|
||||
;
|
||||
; A036 PTM P1406 Use 69h instead of 44h to get volume serial
|
||||
; so that ASSIGN works correctly.
|
||||
;
|
||||
; A037 PTM P1335 Fix COMMAND /C with FOR
|
||||
;
|
||||
; A038 PTM P1635 Fix COPY so that it doesn't accept /V /V
|
||||
;
|
||||
; A039 DCR D284 Change invalid code page tag from -1 to 0.
|
||||
;
|
||||
; A040 PTM P1787 Fix redirection to cause error when no file is
|
||||
; specified.
|
||||
;
|
||||
; A041 PTM P1705 Close redirected files after internal APPEND
|
||||
; executes.
|
||||
;
|
||||
; A042 PTM P1276 Fix problem of APPEND paths changes in batch
|
||||
; files causing loss of batch file.
|
||||
;
|
||||
; A043 PTM P2208 Make sure redirection is not set up twice for
|
||||
; CALL'ed batch files.
|
||||
;
|
||||
; A044 PTM P2315 Set switch on PARSE so that 0ah is not used
|
||||
; as an end of line character
|
||||
;
|
||||
; A045 PTM P2560 Make sure we don't lose parse, critical error,
|
||||
; and extended message pointers when we EXIT if
|
||||
; COMMAND /P is the top level process.
|
||||
;
|
||||
; A046 PTM P2690 Change COPY message "fn File not found" to
|
||||
; "File not found - fn"
|
||||
;
|
||||
; A047 PTM P2819 Fix transient reload prompt message
|
||||
;
|
||||
; A048 PTM P2824 Fix COPY path to be upper cased. This was broken
|
||||
; when DBCS code was added.
|
||||
;
|
||||
; A049 PTM P2891 Fix PATH so that it doesn't accept extra characters
|
||||
; on line.
|
||||
;
|
||||
; A050 PTM P3030 Fix TYPE to work properly on files > 64K
|
||||
;
|
||||
; A051 PTM P3011 Fix DIR header to be compatible with prior releases.
|
||||
;
|
||||
; A052 PTM P3063,P3228 Fix COPY message for invalid filename on target.
|
||||
;
|
||||
; A053 PTM P2865 Fix DIR to work in 40 column mode.
|
||||
;
|
||||
; A054 PTM P3407 Code reduction and critical error on single line
|
||||
; PTM P3672 (Change to single parser exported under P3407)
|
||||
;
|
||||
; A055 PTM P3282 Reset message service variables in INT 23h to fix
|
||||
; problems with breaking out of INT 24h
|
||||
;
|
||||
; A056 PTM P3389 Fix problem of environment overlaying transient.
|
||||
;
|
||||
; A057 PTM P3384 Fix COMMAND /C so that it works if there is no space
|
||||
; before the "string". EX: COMMAND /CDIR
|
||||
;
|
||||
; A058 PTM P3493 Fix DBCS so that CPARSE eats second character of
|
||||
; DBCS switch.
|
||||
;
|
||||
; A059 PTM P3394 Change the TIME command to right align the display of
|
||||
; the time.
|
||||
;
|
||||
; A060 PTM P3672 Code reduction - change PARSE and EXTENDED ERROR
|
||||
; messages to be disk based. Only keep them if /MSG
|
||||
; is used.
|
||||
;
|
||||
; A061 PTM P3928 Fix so that transient doesn't reload when breaking
|
||||
; out of internal commands, due to substitution blocks
|
||||
; not being reset.
|
||||
;
|
||||
; A062 PTM P4079 Fix segment override for fetching address of environment
|
||||
; of parent copy of COMMAND when no COMSPEC exists in
|
||||
; secondary copy of environment. Change default slash in
|
||||
; default comspec string to backslash.
|
||||
|
||||
; A063 PTM P4140 REDIRECTOR and IFSFUNC changed interface for getting
|
||||
; text for critical error messages.
|
||||
|
||||
; A064 PTM P4934 Multiplex number for ANSI.SYS changed due to conflict
|
||||
; 5/20/88 with Microsoft product already shipped.
|
||||
|
||||
; A065 PTM P4935 Multiplex number for SHELL changed due to conflict with
|
||||
; 5/20/88 with Microsoft product already shipped.
|
||||
|
||||
; A066 PTM P4961 DIR /W /P scrolled first line off the screen in some
|
||||
; 5/24/88 cases; where the listing would barely fit without the
|
||||
; header and space remaining.
|
||||
|
||||
; A067 PTM P5011 For /E: values of 993 to 1024 the COMSPEC was getting
|
||||
; 6/6/88 trashed. Turns out that the SETBLOCK for the new
|
||||
; environment was putting a "Z block" marker in the old
|
||||
; environment. The fix is to move to the old environment
|
||||
; to the new environment before doing the SETBLOCK.
|
||||
;***********************************************************************************
|
||||
|
||||
.XCREF
|
||||
.XLIST
|
||||
INCLUDE DOSSYM.INC
|
||||
INCLUDE comsw.asm
|
||||
INCLUDE comequ.asm
|
||||
INCLUDE resmsg.equ ;AN000;
|
||||
.LIST
|
||||
.CREF
|
||||
|
||||
CODERES SEGMENT PUBLIC BYTE ;AC000;
|
||||
CODERES ENDS
|
||||
|
||||
DATARES SEGMENT PUBLIC BYTE
|
||||
EXTRN BATCH:WORD
|
||||
EXTRN ECHOFLAG:BYTE
|
||||
EXTRN disp_class:byte ;AN055;
|
||||
EXTRN execemes_block:byte ;AC000;
|
||||
EXTRN execemes_off:word ;AC000;
|
||||
EXTRN execemes_subst:byte ;AC000;
|
||||
EXTRN execemes_seg:word ;AC000;
|
||||
EXTRN EXTCOM:BYTE
|
||||
EXTRN FORFLAG:BYTE
|
||||
EXTRN IFFlag:BYTE
|
||||
EXTRN InitFlag:BYTE
|
||||
EXTRN NEST:WORD
|
||||
EXTRN number_subst:byte ;AC000;
|
||||
EXTRN PIPEFLAG:BYTE
|
||||
EXTRN RETCODE:WORD
|
||||
EXTRN SINGLECOM:WORD
|
||||
DATARES ENDS
|
||||
|
||||
BATARENA SEGMENT PUBLIC PARA ;AC000;
|
||||
BATARENA ENDS
|
||||
|
||||
BATSEG SEGMENT PUBLIC PARA ;AC000;
|
||||
BATSEG ENDS
|
||||
|
||||
ENVARENA SEGMENT PUBLIC PARA ;AC000;
|
||||
ENVARENA ENDS
|
||||
|
||||
ENVIRONMENT SEGMENT PUBLIC PARA ; Default COMMAND environment
|
||||
ENVIRONMENT ENDS
|
||||
|
||||
INIT SEGMENT PUBLIC PARA
|
||||
EXTRN CONPROC:NEAR
|
||||
EXTRN init_contc_specialcase:near
|
||||
INIT ENDS
|
||||
|
||||
TAIL SEGMENT PUBLIC PARA
|
||||
TAIL ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC PARA
|
||||
TRANCODE ENDS
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE
|
||||
TRANDATA ENDS
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE
|
||||
TRANSPACE ENDS
|
||||
|
||||
TRANTAIL SEGMENT PUBLIC PARA
|
||||
TRANTAIL ENDS
|
||||
|
||||
RESGROUP GROUP CODERES,DATARES,BATARENA,BATSEG,ENVARENA,ENVIRONMENT,INIT,TAIL
|
||||
TRANGROUP GROUP TRANCODE,TRANDATA,TRANSPACE,TRANTAIL
|
||||
|
||||
INCLUDE envdata.asm
|
||||
|
||||
; START OF RESIDENT PORTION
|
||||
|
||||
CODERES SEGMENT PUBLIC BYTE ;AC000;
|
||||
|
||||
|
||||
PUBLIC EXT_EXEC
|
||||
PUBLIC CONTC
|
||||
PUBLIC Exec_Wait
|
||||
|
||||
ASSUME CS:RESGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
|
||||
EXTRN lodcom:near
|
||||
EXTRN LODCOM1:near
|
||||
|
||||
ORG 0
|
||||
ZERO = $
|
||||
|
||||
ORG 80h-1
|
||||
PUBLIC RESCOM
|
||||
RESCOM LABEL BYTE
|
||||
|
||||
ORG 100H
|
||||
|
||||
PROGSTART:
|
||||
JMP RESGROUP:CONPROC
|
||||
|
||||
;
|
||||
; COMMAND has issued an EXEC system call and it has returned an error. We
|
||||
; examine the error code and select an appropriate message.
|
||||
;
|
||||
EXEC_ERR:
|
||||
push ds ;AC000; get transient segment
|
||||
pop es ;AC000; into ES
|
||||
push cs ;AC000; get resident segment
|
||||
pop ds ;AC000; into DS
|
||||
ASSUME DS:RESGROUP ;AN000;
|
||||
MOV BX,RBADNAM ;AC000; Get message number for Bad command
|
||||
CMP AX,error_file_not_found
|
||||
JZ GOTEXECEMES
|
||||
MOV BX,TOOBIG ;AC000; Get message number for file not found
|
||||
CMP AX,error_not_enough_memory
|
||||
JZ GOTEXECEMES
|
||||
MOV BX,EXEBAD ;AC000; Get message number for bad exe file
|
||||
CMP AX,error_bad_format
|
||||
JZ GOTEXECEMES
|
||||
MOV BX,AccDen ;AC000; Get message number for access denied
|
||||
CMP AX,error_access_denied
|
||||
JZ GOTEXECEMES ;AC000; go print message
|
||||
|
||||
DEFAULT_MESSAGE:
|
||||
MOV BX,EXECEMES ;AC000; Get message number for default message
|
||||
MOV EXECEMES_OFF,DX ;AN000; put offset of EXEC string in subst block
|
||||
MOV EXECEMES_SEG,ES ;AN000; put segment of EXEC string in subst block
|
||||
MOV AL,EXECEMES_SUBST ;AN000; get number of substitutions
|
||||
MOV NUMBER_SUBST,AL ;AN000;
|
||||
MOV SI,OFFSET RESGROUP:EXECEMES_BLOCK ;AN000; get address of subst block
|
||||
GOTEXECEMES:
|
||||
PUSH CS
|
||||
POP ES ;AC000; get resident segment into ES
|
||||
ASSUME ES:RESGROUP ;AN000;
|
||||
MOV DX,BX ;AN000; get message number in DX
|
||||
INVOKE RPRINT
|
||||
JMP SHORT NOEXEC
|
||||
;
|
||||
; The transient has set up everything for an EXEC system call. For
|
||||
; cleanliness, we issue the EXEC here in the resident so that we may be able
|
||||
; to recover cleanly upon success.
|
||||
;
|
||||
EXT_EXEC:
|
||||
push dx ;AN000; save the command name offset
|
||||
INT int_command ; Do the EXEC
|
||||
pop dx ;AN000; restore the command name offset
|
||||
JC EXEC_ERR ; EXEC failed
|
||||
;
|
||||
; The exec has completed. Retrieve the exit code.
|
||||
;
|
||||
EXEC_WAIT:
|
||||
push cs ;AC000; get resident segment
|
||||
pop ds ;AC000; into DS
|
||||
MOV AH,WAITPROCESS ;AC000; Get errorlevel
|
||||
INT int_command ; Get the return code
|
||||
MOV [RETCODE],AX
|
||||
;
|
||||
; We need to test to see if we can reload the transient. THe external command
|
||||
; may have overwritten part of the transient.
|
||||
;
|
||||
NOEXEC:
|
||||
JMP LODCOM
|
||||
;
|
||||
; This is the default system INT 23 handler. All processes (including
|
||||
; COMMAND) get it by default. There are some games that are played: We
|
||||
; ignore ^C during most of the INIT code. This is because we may perform an
|
||||
; ALLOC and diddle the header! Also, if we are prompting for date/time in the
|
||||
; init code, we are to treat ^C as empty responses.
|
||||
;
|
||||
CONTC PROC FAR
|
||||
ASSUME CS:ResGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
test InitFlag,initINIT ; in initialization?
|
||||
jz NotAtInit ; no
|
||||
test InitFlag,initSpecial ; doing special stuff?
|
||||
jz CmdIRet ; no, ignore ^C
|
||||
jmp resgroup:init_contc_specialcase ; Yes, go handle it
|
||||
CmdIret:
|
||||
iret ; yes, ignore the ^C
|
||||
NotAtInit:
|
||||
test InitFlag,initCtrlC ; are we already in a ^C?
|
||||
jz NotInit ; nope too.
|
||||
;
|
||||
; We are interrupting ourselves in this ^C handler. We need to set carry
|
||||
; and return to the user sans flags only if the system call was a 1-12 one.
|
||||
; Otherwise, we ignore the ^C.
|
||||
;
|
||||
cmp ah,1
|
||||
jb CmdIRet
|
||||
cmp ah,12
|
||||
ja CmdIRet
|
||||
add sp,6 ; remove int frame
|
||||
stc
|
||||
ret 2 ; remove those flags...
|
||||
;
|
||||
; We have now received a ^C for some process (maybe ourselves but not at INIT).
|
||||
;
|
||||
; Note that we are running on the user's stack!!! Bad news if any of the
|
||||
; system calls below go and issue another INT 24... Massive stack overflow!
|
||||
; Another bad point is that SavHand will save an already saved handle, thus
|
||||
; losing a possible redirection...
|
||||
;
|
||||
; All we need to do is set the flag to indicate nested ^C. The above code
|
||||
; will correctly flag the ^C diring the message output and prompting while
|
||||
; ignoring the ^C the rest of the time.
|
||||
;
|
||||
; Clean up: flush disk. If we are in the middle of a batch file, we ask if
|
||||
; he wants to terminate it. If he does, then we turn off all internal flags
|
||||
; and let the DOS abort.
|
||||
;
|
||||
NotInit:
|
||||
or InitFlag,initCtrlC ; nested ^c is on
|
||||
STI
|
||||
PUSH CS ; El Yucko! Change the user's DS!!
|
||||
POP DS
|
||||
ASSUME DS:RESGROUP
|
||||
MOV DISP_CLASS,UTIL_MSG_CLASS ;AN055; reset display class
|
||||
MOV NUMBER_SUBST,NO_SUBST ;AN055; reset number of substitutions
|
||||
MOV AX,SingleCom
|
||||
OR AX,AX
|
||||
JNZ NoReset
|
||||
PUSH AX
|
||||
MOV AH,DISK_RESET
|
||||
INT int_command ; Reset disks in case files were open
|
||||
POP AX
|
||||
NoReset:
|
||||
;
|
||||
; In the generalized version of FOR, PIPE and BATCH, we would walk the entire
|
||||
; active list and free each segment. Here, we just free the single batch
|
||||
; segment.
|
||||
;
|
||||
TEST Batch,-1
|
||||
JZ CONTCTERM
|
||||
OR AX,AX
|
||||
JNZ Contcterm
|
||||
invoke SavHand
|
||||
invoke ASKEND ; See if user wants to terminate batch
|
||||
;
|
||||
; If the carry flag is clear, we do NOT free up the batch file
|
||||
;
|
||||
JNC ContBatch
|
||||
mov cl,echoflag ;AN000; get current echo flag
|
||||
PUSH BX ;G
|
||||
|
||||
ClearBatch:
|
||||
MOV ES,[BATCH] ; get batch segment
|
||||
mov di,batfile ;AN000; get offset of batch file name
|
||||
mov ax,mult_shell_brk ;AN000; does the SHELL want this terminated?
|
||||
int 2fh ;AN000; call the SHELL
|
||||
cmp al,shell_action ;AN000; does shell want this batch?
|
||||
jz shell_bat_cont ;AN000; yes - keep it
|
||||
|
||||
MOV BX,ES:[BATFORPTR] ;G get old FOR segment
|
||||
cmp bx,0 ;G is a FOR in progress
|
||||
jz no_bat_for ;G no - don't deallocate
|
||||
push es ;G
|
||||
mov es,bx ;G yes - free it up...
|
||||
MOV AH,DEALLOC ;G
|
||||
INT 21H ;G
|
||||
pop es ;G restore to batch segment
|
||||
|
||||
no_bat_for:
|
||||
mov cl,ES:[batechoflag] ;G get old echo flag
|
||||
MOV BX,ES:[BATLAST] ;G get old batch segment
|
||||
MOV AH,DEALLOC ; free it up...
|
||||
INT 21H
|
||||
MOV [BATCH],BX ;G get ready to deallocate next batch
|
||||
DEC NEST ;G Is there another batch file?
|
||||
JNZ CLEARBATCH ;G Keep going until no batch file
|
||||
|
||||
;
|
||||
; We are terminating a batch file; restore the echo status
|
||||
;
|
||||
|
||||
shell_bat_cont: ;AN000; continue batch for SHELL
|
||||
|
||||
POP BX ;G
|
||||
MOV ECHOFLAG,CL ;G reset echo status
|
||||
MOV PIPEFLAG,0 ;G turn off pipeflag
|
||||
ContBatch:
|
||||
invoke CRLF ;G print out crlf before returning
|
||||
invoke RestHand
|
||||
;
|
||||
; Yes, we are terminating. Turn off flags and allow the DOS to abort.
|
||||
;
|
||||
CONTCTERM:
|
||||
XOR AX,AX ; Indicate no read
|
||||
MOV BP,AX
|
||||
;
|
||||
; The following resetting of the state flags is good for the generalized batch
|
||||
; processing.
|
||||
;
|
||||
MOV IfFlag,AL ; turn off iffing
|
||||
MOV [FORFLAG],AL ; Turn off for processing
|
||||
call ResPipeOff
|
||||
CMP [SINGLECOM],AX ; See if we need to set SINGLECOM
|
||||
JZ NOSETSING
|
||||
MOV [SINGLECOM],-1 ; Cause termination on pipe, batch, for
|
||||
NOSETSING:
|
||||
;
|
||||
; If we are doing an internal command, go through the reload process. If we
|
||||
; are doing an external, let DOS abort the process. In both cases, we are
|
||||
; now done with the ^C processing.
|
||||
;
|
||||
AND InitFlag,NOT initCtrlC
|
||||
CMP [EXTCOM],AL
|
||||
JNZ DODAB ; Internal ^C
|
||||
JMP LODCOM1
|
||||
DODAB:
|
||||
STC ; Tell DOS to abort
|
||||
RET ; Leave flags on stack
|
||||
ContC ENDP
|
||||
|
||||
public ResPipeOff
|
||||
assume ds:nothing,es:nothing
|
||||
ResPipeOff:
|
||||
SaveReg <AX>
|
||||
xor ax,ax
|
||||
xchg PipeFlag,al
|
||||
or al,al
|
||||
jz NoPipePop
|
||||
shr EchoFlag,1
|
||||
NoPipePop:
|
||||
RestoreReg <AX>
|
||||
return
|
||||
CODERES ENDS
|
||||
END PROGSTART
|
||||
619
v4.0/src/CMD/COMMAND/COMMAND2.ASM
Normal file
619
v4.0/src/CMD/COMMAND/COMMAND2.ASM
Normal file
@@ -0,0 +1,619 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)command2.asm 4.3 85/10/16
|
||||
; SCCSID = @(#)command2.asm 4.3 85/10/16
|
||||
TITLE COMMAND2 - resident code for COMMAND.COM part II
|
||||
NAME COMMAND2
|
||||
.XCREF
|
||||
.XLIST
|
||||
INCLUDE DOSSYM.INC
|
||||
INCLUDE comsw.asm
|
||||
INCLUDE comequ.asm
|
||||
INCLUDE resmsg.equ ;AN000;
|
||||
.LIST
|
||||
.CREF
|
||||
|
||||
tokenized = FALSE
|
||||
|
||||
CODERES SEGMENT PUBLIC BYTE ;AC000;
|
||||
CODERES ENDS
|
||||
|
||||
DATARES SEGMENT PUBLIC BYTE
|
||||
EXTRN append_state:word ;AN020;
|
||||
EXTRN append_flag:byte ;AN020;
|
||||
EXTRN COMDRV:BYTE
|
||||
EXTRN comprmt1_block:byte ;AN000;
|
||||
EXTRN comprmt1_subst:byte ;AN000;
|
||||
EXTRN COMSPEC:BYTE
|
||||
EXTRN cpdrv:byte
|
||||
EXTRN envirseg:word
|
||||
EXTRN EXTCOM:BYTE
|
||||
EXTRN HANDLE01:WORD
|
||||
EXTRN InitFlag:BYTE
|
||||
EXTRN INT_2E_RET:DWORD ;AC000;
|
||||
EXTRN IO_SAVE:WORD
|
||||
EXTRN LOADING:BYTE
|
||||
EXTRN LTPA:WORD
|
||||
EXTRN MEMSIZ:WORD
|
||||
EXTRN number_subst:byte ;AN000;
|
||||
EXTRN OldTerm:DWORD ;AC000;
|
||||
EXTRN PARENT:WORD ;AC000;
|
||||
EXTRN PERMCOM:BYTE
|
||||
EXTRN RDIRCHAR:BYTE
|
||||
EXTRN RES_TPA:WORD
|
||||
EXTRN RETCODE:WORD
|
||||
EXTRN rsrc_xa_seg:word ;AN030;
|
||||
EXTRN RSWITCHAR:BYTE
|
||||
EXTRN SAVE_PDB:WORD
|
||||
EXTRN SINGLECOM:WORD
|
||||
EXTRN SUM:WORD
|
||||
EXTRN TRANS:WORD
|
||||
EXTRN TranVarEnd:BYTE
|
||||
EXTRN TRANVARS:BYTE
|
||||
EXTRN TRNSEG:WORD
|
||||
EXTRN VERVAL:WORD
|
||||
DATARES ENDS
|
||||
|
||||
BATARENA SEGMENT PUBLIC PARA ;AC000;
|
||||
BATARENA ENDS
|
||||
|
||||
BATSEG SEGMENT PUBLIC PARA ;AC000;
|
||||
BATSEG ENDS
|
||||
|
||||
ENVARENA SEGMENT PUBLIC PARA ;AC000;
|
||||
ENVARENA ENDS
|
||||
|
||||
ENVIRONMENT SEGMENT PUBLIC PARA ; Default COMMAND environment
|
||||
ENVIRONMENT ENDS
|
||||
|
||||
INIT SEGMENT PUBLIC PARA
|
||||
EXTRN envsiz:word
|
||||
EXTRN oldenv:word
|
||||
EXTRN resetenv:byte
|
||||
EXTRN usedenv:word
|
||||
INIT ENDS
|
||||
|
||||
TAIL SEGMENT PUBLIC PARA
|
||||
TAIL ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC PARA
|
||||
TRANCODE ENDS
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE
|
||||
EXTRN TRANDATAEND:BYTE
|
||||
TRANDATA ENDS
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE
|
||||
EXTRN TRANSPACEEND:BYTE
|
||||
EXTRN HEADCALL:DWORD
|
||||
TRANSPACE ENDS
|
||||
|
||||
TRANTAIL SEGMENT PUBLIC PARA
|
||||
TRANTAIL ENDS
|
||||
|
||||
RESGROUP GROUP CODERES,DATARES,BATARENA,BATSEG,ENVARENA,ENVIRONMENT,INIT,TAIL
|
||||
TRANGROUP GROUP TRANCODE,TRANDATA,TRANSPACE,TRANTAIL
|
||||
|
||||
; START OF RESIDENT PORTION
|
||||
|
||||
CODERES SEGMENT PUBLIC BYTE ;AC000;
|
||||
|
||||
PUBLIC CHKSUM
|
||||
PUBLIC endinit
|
||||
PUBLIC GETCOMDSK2
|
||||
PUBLIC INT_2E
|
||||
PUBLIC LOADCOM
|
||||
PUBLIC LODCOM
|
||||
PUBLIC LODCOM1
|
||||
PUBLIC RESTHAND
|
||||
PUBLIC SAVHAND
|
||||
PUBLIC SETVECT
|
||||
PUBLIC THEADFIX
|
||||
PUBLIC TREMCHECK
|
||||
PUBLIC tjmp
|
||||
|
||||
ASSUME CS:RESGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
|
||||
EXTRN contc:near
|
||||
EXTRN DSKERR:NEAR
|
||||
EXTRN rstack:word
|
||||
;
|
||||
; If we cannot allocate enough memory for the transient or there was some
|
||||
; other allocation error, we display a message and then die.
|
||||
;
|
||||
BADMEMERR: ; Allocation error loading transient
|
||||
MOV DX,BMEMMES ;AC000; get message number
|
||||
FATALC:
|
||||
PUSH CS
|
||||
POP DS
|
||||
ASSUME DS:ResGroup
|
||||
invoke RPRINT
|
||||
;
|
||||
; If this is NOT a permanent (top-level) COMMAND, then we exit; we can't do
|
||||
; anything else!
|
||||
;
|
||||
CMP PERMCOM,0
|
||||
JZ FATALRET
|
||||
;
|
||||
; We are a permanent command. If we are in the process of the magic interrupt
|
||||
; (Singlecom) then exit too.
|
||||
;
|
||||
CMP SINGLECOM,0 ; If PERMCOM and SINGLECOM
|
||||
JNZ FATALRET ; Must take INT_2E exit
|
||||
;
|
||||
; Permanent command. We can't do ANYthing except halt.
|
||||
;
|
||||
MOV DX,HALTMES ;AC000; get message number
|
||||
invoke RPRINT
|
||||
STI
|
||||
STALL:
|
||||
JMP STALL ; Crash the system nicely
|
||||
|
||||
FATALRET:
|
||||
MOV DX,FRETMES ;AC000; get message number
|
||||
invoke RPRINT
|
||||
FATALRET2:
|
||||
CMP [PERMCOM],0 ; If we get here and PERMCOM,
|
||||
JNZ RET_2E ; must be INT_2E
|
||||
invoke reset_msg_pointers ;AN000; reset critical & parse error messages
|
||||
MOV AX,[PARENT]
|
||||
MOV WORD PTR CS:[PDB_Parent_PID],AX
|
||||
MOV AX,WORD PTR OldTerm
|
||||
MOV WORD PTR CS:[PDB_Exit],AX
|
||||
MOV AX,WORD PTR OldTerm+2
|
||||
MOV WORD PTR CS:[PDB_Exit+2],AX
|
||||
MOV AX,(EXIT SHL 8) ; Return to lower level
|
||||
INT int_command
|
||||
|
||||
RET_2E:
|
||||
PUSH CS
|
||||
POP DS
|
||||
ASSUME DS:RESGROUP,ES:NOTHING,SS:NOTHING
|
||||
MOV [SINGLECOM],0 ; Turn off singlecom
|
||||
MOV ES,[RES_TPA]
|
||||
MOV AH,DEALLOC
|
||||
INT int_command ; Free up space used by transient
|
||||
MOV BX,[SAVE_PDB]
|
||||
MOV AH,SET_CURRENT_PDB
|
||||
INT int_command ; Current process is user
|
||||
MOV AX,[RETCODE]
|
||||
CMP [EXTCOM],0
|
||||
JNZ GOTECODE
|
||||
XOR AX,AX ; Internals always return 0
|
||||
GOTECODE:
|
||||
MOV [EXTCOM],1 ; Force external
|
||||
JMP [INT_2E_RET] ;"IRET"
|
||||
|
||||
INT_2E: ; Magic command executer
|
||||
ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
POP WORD PTR [INT_2E_RET]
|
||||
POP WORD PTR [INT_2E_RET+2] ;Get return address
|
||||
POP AX ;Chuck flags
|
||||
PUSH CS
|
||||
POP ES
|
||||
MOV DI,80H
|
||||
MOV CX,64
|
||||
REP MOVSW
|
||||
MOV AH,GET_CURRENT_PDB
|
||||
INT int_command ; Get user's header
|
||||
MOV [SAVE_PDB],BX
|
||||
MOV AH,SET_CURRENT_PDB
|
||||
MOV BX,CS
|
||||
INT int_command ; Current process is me
|
||||
MOV [SINGLECOM],81H
|
||||
MOV [EXTCOM],1 ; Make sure this case forced
|
||||
|
||||
LODCOM: ; Termination handler
|
||||
CMP [EXTCOM],0
|
||||
jz lodcom1 ; if internal, memory already allocated
|
||||
mov bx,0ffffh
|
||||
MOV AH,ALLOC
|
||||
INT int_command
|
||||
CALL SetSize
|
||||
ADD AX,20H
|
||||
CMP BX,AX ; Is less than 512 byte buffer worth it?
|
||||
JNC MEMOK
|
||||
BADMEMERRJ:
|
||||
JMP BADMEMERR ; Not enough memory
|
||||
|
||||
; SetSize - get transient size in paragraphs
|
||||
Procedure SetSize,NEAR
|
||||
MOV AX,OFFSET TRANGROUP:TRANSPACEEND + 15
|
||||
MOV CL,4
|
||||
SHR AX,CL
|
||||
return
|
||||
EndProc SetSize
|
||||
|
||||
MEMOK:
|
||||
MOV AH,ALLOC
|
||||
INT int_command
|
||||
JC BADMEMERRJ ; Memory arenas probably trashed
|
||||
MOV [EXTCOM],0 ; Flag not to ALLOC again
|
||||
MOV [RES_TPA], AX ; Save current TPA segment
|
||||
AND AX, 0F000H
|
||||
ADD AX, 01000H ; Round up to next 64K boundary
|
||||
JC BAD_TPA ; Memory wrap if carry set
|
||||
; Make sure that new boundary is within allocated range
|
||||
MOV DX, [RES_TPA]
|
||||
ADD DX, BX ; Compute maximum address
|
||||
CMP DX, AX ; Is 64K address out of range?
|
||||
JBE BAD_TPA
|
||||
; Must have 64K of usable space.
|
||||
SUB DX, AX ; Compute the usable space
|
||||
CMP DX, 01000H ; Is space >= 64K ?
|
||||
JAE LTPASET
|
||||
BAD_TPA:
|
||||
MOV AX, [RES_TPA]
|
||||
LTPASET:
|
||||
MOV [LTPA],AX ; Usable TPA is 64k buffer aligned
|
||||
MOV AX, [RES_TPA] ; Actual TPA is buffer allocated
|
||||
ADD BX,AX
|
||||
MOV [MEMSIZ],BX
|
||||
CALL SetSize
|
||||
SUB BX,AX
|
||||
MOV [TRNSEG],BX ; Transient starts here
|
||||
LODCOM1:
|
||||
MOV AX,CS
|
||||
MOV SS,AX
|
||||
ASSUME SS:RESGROUP
|
||||
MOV SP,OFFSET RESGROUP:RSTACK
|
||||
MOV DS,AX
|
||||
ASSUME DS:RESGROUP
|
||||
CALL HEADFIX ; Make sure files closed stdin and stdout restored
|
||||
XOR BP,BP ; Flag command ok
|
||||
MOV AX,-1
|
||||
XCHG AX,[VERVAL]
|
||||
CMP AX,-1
|
||||
JZ NOSETVER
|
||||
MOV AH,SET_VERIFY_ON_WRITE ; AL has correct value
|
||||
INT int_command
|
||||
NOSETVER:
|
||||
CMP [SINGLECOM],-1
|
||||
JNZ NOSNG
|
||||
JMP FATALRET2 ; We have finished the single command
|
||||
NOSNG:
|
||||
CALL CHKSUM ; Check the transient
|
||||
CMP DX,[SUM]
|
||||
JZ HAVCOM ; Transient OK
|
||||
BOGUS_COM:
|
||||
MOV [LOADING],1 ; Flag DSKERR routine
|
||||
CALL LOADCOM
|
||||
CHKSAME:
|
||||
|
||||
CALL CHKSUM
|
||||
CMP DX,[SUM]
|
||||
JZ HAVCOM ; Same COMMAND
|
||||
ALSO_BOGUS:
|
||||
CALL WRONGCOM
|
||||
JMP SHORT CHKSAME
|
||||
HAVCOM:
|
||||
MOV AX,CHAR_OPER SHL 8
|
||||
INT int_command
|
||||
MOV [RSWITCHAR],DL
|
||||
CMP DL,'/'
|
||||
JNZ USESLASH
|
||||
mov cl,'\'
|
||||
MOV [RDIRCHAR],cl ; Select alt path separator
|
||||
USESLASH:
|
||||
MOV [LOADING],0 ; Flag to DSKERR
|
||||
MOV SI,OFFSET RESGROUP:TRANVARS
|
||||
MOV DI,OFFSET TRANGROUP:HEADCALL
|
||||
MOV ES,[TRNSEG]
|
||||
CLD
|
||||
MOV CX,OFFSET ResGroup:TranVarEnd
|
||||
SUB CX,SI
|
||||
REP MOVSB ; Transfer INFO to transient
|
||||
MOV AX,[MEMSIZ]
|
||||
MOV WORD PTR DS:[PDB_block_len],AX ; Adjust my own header
|
||||
|
||||
; Just a public label so this spot can be found easily.
|
||||
tjmp:
|
||||
JMP DWORD PTR [TRANS]
|
||||
|
||||
; Far call to REMCHECK for TRANSIENT
|
||||
TREMCHECK PROC FAR
|
||||
CALL REMCHECK
|
||||
RET
|
||||
TREMCHECK ENDP
|
||||
|
||||
REMCHECK:
|
||||
;All registers preserved. Returns ZF set if media removable, NZ if fixed
|
||||
; AL is drive (0=DEF, 1=A,...).
|
||||
SaveReg <AX,BX>
|
||||
MOV BX,AX
|
||||
MOV AX,(IOCTL SHL 8) + 8
|
||||
INT 21h
|
||||
jnc RCcont ; If an error occurred, assume the media
|
||||
or ax,ax ; is NON-removable.
|
||||
; AX contains the non-zero error code
|
||||
; from the INT 21, so the OR AX,AX sets
|
||||
; Non-zero. This behavior makes Network
|
||||
; drives appear to be non-removable.
|
||||
jmp SHORT ResRegs
|
||||
RCcont:
|
||||
AND AX,1
|
||||
NOT AX
|
||||
ResRegs:
|
||||
RestoreReg <BX,AX>
|
||||
return
|
||||
|
||||
; Far call to HEADFIX for TRANSIENT
|
||||
THEADFIX PROC FAR
|
||||
CALL HEADFIX
|
||||
RET
|
||||
THEADFIX ENDP
|
||||
|
||||
HEADFIX:
|
||||
CALL SETVECT
|
||||
XOR BX,BX ; Clean up header
|
||||
MOV CX,[IO_SAVE]
|
||||
MOV DX,WORD PTR DS:[PDB_JFN_Table]
|
||||
CMP CL,DL
|
||||
JZ CHK1 ; Stdin matches
|
||||
MOV AH,CLOSE
|
||||
INT int_command
|
||||
MOV DS:[PDB_JFN_Table],CL ; Restore stdin
|
||||
CHK1:
|
||||
INC BX
|
||||
CMP CH,DH ; Stdout matches
|
||||
JZ CHKOTHERHAND
|
||||
MOV AH,CLOSE
|
||||
INT int_command
|
||||
MOV DS:[PDB_JFN_Table+1],CH ; Restore stdout
|
||||
CHKOTHERHAND:
|
||||
ADD BX,4 ; Skip 2,3,4
|
||||
MOV CX,FilPerProc - 5 ; Already done 0,1,2,3,4
|
||||
CLOSELOOP:
|
||||
MOV AH,CLOSE
|
||||
INT int_command
|
||||
INC BX
|
||||
LOOP CLOSELOOP
|
||||
push ds ;AN020; save data segment
|
||||
push cs ;AN020; Get local segment into DS
|
||||
pop ds ;AN020;
|
||||
cmp append_flag,-1 ;AN020; Do we need to reset APPEND?
|
||||
jnz append_fix_end ;AN030; no - just exit
|
||||
mov ax,AppendSetState ;AN020; Set the state of Append
|
||||
mov bx,Append_state ;AN020; back to the original state
|
||||
int 2fh ;AN020;
|
||||
mov append_flag,0 ;AN020; Set append flag to invalid
|
||||
append_fix_end: ;AN030;
|
||||
cmp [rsrc_xa_seg],no_xa_seg ;AN030; Is there any active XA segment?
|
||||
jz xa_fix_end ;AN030; no - exit
|
||||
push es ;AN030; Yes - deallocate it
|
||||
mov es,rsrc_xa_seg ;AN030;
|
||||
mov ax,(Dealloc SHL 8) ;AN030; Deallocate memory call
|
||||
int int_command ;AN030;
|
||||
pop es ;AN030;
|
||||
mov [rsrc_xa_seg],no_xa_seg ;AN030; reset to no segment
|
||||
xa_fix_end:
|
||||
pop ds ;AN020; get data segment back
|
||||
return
|
||||
|
||||
SAVHAND:
|
||||
ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
PUSH DS
|
||||
PUSH BX ; Set stdin to sterr, stdout to stderr
|
||||
PUSH AX
|
||||
MOV AH,GET_CURRENT_PDB
|
||||
INT int_command ; Get user's header
|
||||
MOV DS,BX
|
||||
LDS BX,DS:[PDB_JFN_POINTER] ; get pointer to JFN table...
|
||||
MOV AX,WORD PTR DS:[BX]
|
||||
MOV [HANDLE01],AX ; Save user's stdin, stdout
|
||||
MOV AL,CS:[PDB_JFN_Table+2] ; get COMMAND stderr
|
||||
MOV AH,AL
|
||||
MOV WORD PTR DS:[BX],AX ; Dup stderr
|
||||
POP AX
|
||||
POP BX
|
||||
POP DS
|
||||
return
|
||||
|
||||
ASSUME DS:RESGROUP
|
||||
GETCOMDSK2:
|
||||
CALL GETCOMDSK
|
||||
JMP LODCOM1 ; Memory already allocated
|
||||
|
||||
RESTHAND:
|
||||
PUSH DS
|
||||
PUSH BX ; Restore stdin, stdout to user
|
||||
PUSH AX
|
||||
MOV AH,GET_CURRENT_PDB
|
||||
INT int_command ; Point to user's header
|
||||
MOV AX,[HANDLE01]
|
||||
MOV DS,BX
|
||||
ASSUME DS:NOTHING
|
||||
LDS BX,DS:[PDB_JFN_POINTER] ; get pointer to JFN table...
|
||||
MOV WORD PTR DS:[BX],AX ; Stuff his old 0 and 1
|
||||
POP AX
|
||||
POP BX
|
||||
POP DS
|
||||
return
|
||||
ASSUME DS:RESGROUP,SS:RESGROUP
|
||||
|
||||
HOPELESS:
|
||||
MOV DX,COMBAD ;AC000;
|
||||
JMP FATALC
|
||||
|
||||
GETCOMDSK:
|
||||
mov al,[comdrv]
|
||||
CALL REMCHECK
|
||||
jNZ HOPELESS ;Non-removable media
|
||||
getcomdsk3:
|
||||
cmp dx,combad ;AC000;
|
||||
jnz getcomdsk4
|
||||
mov dx,combad ;AN000; get message number
|
||||
invoke RPRINT ; Say command is invalid
|
||||
getcomdsk4:
|
||||
cmp [cpdrv],0 ;g is there a drive in the comspec?
|
||||
jnz users_drive ;g yes - use it
|
||||
mov ah,Get_default_drive ;g use default drive
|
||||
int 21h ;g
|
||||
add al,"A" ;g convert to ascii
|
||||
mov [cpdrv],al ;g put in message to print out
|
||||
|
||||
users_drive: ;g
|
||||
mov dx,comprmt1 ;AC000; Prompt for diskette containing command
|
||||
IF tokenized
|
||||
or byte ptr [si],80h
|
||||
endif
|
||||
MOV AL,COMPRMT1_SUBST ;AN000; get number of substitutions
|
||||
MOV SI,OFFSET RESGROUP:COMPRMT1_BLOCK ;AN000; get address of subst block
|
||||
MOV NUMBER_SUBST,AL ;AN000;
|
||||
invoke rprint
|
||||
if tokenized
|
||||
and byte ptr [si],NOT 80h
|
||||
endif
|
||||
mov dx,prompt ;AN047; Tell the user to strike a key
|
||||
invoke rprint ;AN047;
|
||||
CALL GetRawFlushedByte
|
||||
return
|
||||
|
||||
; flush world and get raw input
|
||||
GetRawFlushedByte:
|
||||
MOV AX,(STD_CON_INPUT_FLUSH SHL 8) OR RAW_CON_INPUT
|
||||
INT int_command ; Get char without testing or echo
|
||||
MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0
|
||||
INT int_command
|
||||
return
|
||||
|
||||
LOADCOM: ; Load in transient
|
||||
INC BP ; Flag command read
|
||||
MOV DX,OFFSET RESGROUP:COMSPEC
|
||||
MOV AX,OPEN SHL 8
|
||||
INT int_command ; Open COMMAND.COM
|
||||
JNC READCOM
|
||||
CMP AX,error_too_many_open_files
|
||||
JNZ TRYDOOPEN
|
||||
MOV DX,NOHANDMES ;AC000;
|
||||
JMP FATALC ; Fatal, will never find a handle
|
||||
|
||||
TRYDOOPEN:
|
||||
CALL GETCOMDSK
|
||||
JMP LOADCOM
|
||||
|
||||
READCOM:
|
||||
MOV BX,AX ; Handle
|
||||
MOV DX,OFFSET RESGROUP:TRANSTART
|
||||
XOR CX,CX ; Seek loc
|
||||
MOV AX,LSEEK SHL 8
|
||||
INT int_command
|
||||
JC WRONGCOM1
|
||||
MOV CX,OFFSET TRANGROUP:TRANSPACEEND - 100H
|
||||
|
||||
PUSH DS
|
||||
MOV DS,[TRNSEG]
|
||||
ASSUME DS:NOTHING
|
||||
MOV DX,100H
|
||||
MOV AH,READ
|
||||
INT int_command
|
||||
POP DS
|
||||
ASSUME DS:RESGROUP
|
||||
WRONGCOM1:
|
||||
PUSHF
|
||||
PUSH AX
|
||||
MOV AH,CLOSE
|
||||
INT int_command ; Close COMMAND.COM
|
||||
POP AX
|
||||
POPF
|
||||
JC WRONGCOM ; If error on READ
|
||||
CMP AX,CX
|
||||
retz ; Size matched
|
||||
WRONGCOM:
|
||||
MOV DX,COMBAD ;AC000;
|
||||
CALL GETCOMDSK
|
||||
JMP LOADCOM ; Try again
|
||||
|
||||
CHKSUM: ; Compute transient checksum
|
||||
PUSH DS
|
||||
MOV DS,[TRNSEG]
|
||||
MOV SI,100H
|
||||
MOV CX,OFFSET TRANGROUP:TranDataEnd - 100H
|
||||
|
||||
CHECK_SUM:
|
||||
CLD
|
||||
SHR CX,1
|
||||
XOR DX,DX
|
||||
CHK:
|
||||
LODSW
|
||||
ADD DX,AX
|
||||
ADC DX,0
|
||||
LOOP CHK
|
||||
POP DS
|
||||
return
|
||||
|
||||
SETVECT: ; Set useful vectors
|
||||
MOV DX,OFFSET RESGROUP:LODCOM
|
||||
MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 22H
|
||||
MOV WORD PTR DS:[PDB_EXIT],DX
|
||||
MOV WORD PTR DS:[PDB_EXIT+2],DS
|
||||
INT int_command
|
||||
MOV DX,OFFSET RESGROUP:CONTC
|
||||
INC AL
|
||||
INT int_command
|
||||
MOV DX,OFFSET RESGROUP:DSKERR
|
||||
INC AL
|
||||
INT int_command
|
||||
return
|
||||
|
||||
|
||||
;
|
||||
; This routine moves the environment to a newly allocated segment
|
||||
; at the end of initialization
|
||||
;
|
||||
|
||||
ENDINIT:
|
||||
push ds ;g save segments
|
||||
push es ;g
|
||||
push cs ;g get resident segment to DS
|
||||
pop ds ;g
|
||||
ASSUME DS:RESGROUP
|
||||
mov cx,usedenv ;g get number of bytes to move
|
||||
mov es,envirseg ;g get target environment segment
|
||||
|
||||
ASSUME ES:NOTHING
|
||||
mov DS:[PDB_environ],es ;g put new environment in my header ;AM067;
|
||||
mov ds,oldenv ;g source environment segment ;AM067;
|
||||
ASSUME DS:NOTHING ;AM067;
|
||||
xor si,si ;g set up offsets to start of segments ;AM067;
|
||||
xor di,di ;g ;AM067;
|
||||
cld ;g make sure we move the right way! ;AM067;
|
||||
rep movsb ;g move it ;AM067;
|
||||
xor ax,ax ;g ;AM067;
|
||||
stosb ;g make sure there are double 0 at end ;AM067;
|
||||
|
||||
cmp resetenv,1 ;eg Do we need to setblock to env end?
|
||||
jnz noreset ;eg no - we already did it
|
||||
mov bx,envsiz ;eg get size of environment in paragraphs
|
||||
push es ;eg save environment - just to make sure
|
||||
mov ah,SETBLOCK ;eg
|
||||
int int_command ;eg
|
||||
pop es ;eg
|
||||
|
||||
noreset:
|
||||
mov InitFlag,FALSE ;AC042; Turn off init flag
|
||||
pop es ;g
|
||||
pop ds ;g
|
||||
jmp lodcom ;g allocate transient
|
||||
|
||||
CODERES ENDS
|
||||
|
||||
; This TAIL segment is used to produce a PARA aligned label in the resident
|
||||
; group which is the location where the transient segments will be loaded
|
||||
; initial.
|
||||
|
||||
TAIL SEGMENT PUBLIC PARA
|
||||
ORG 0
|
||||
PUBLIC TranStart
|
||||
TRANSTART LABEL WORD
|
||||
TAIL ENDS
|
||||
|
||||
; This TAIL segment is used to produce a PARA aligned label in the transient
|
||||
; group which is the location where the exec segments will be loaded
|
||||
; initial.
|
||||
|
||||
TRANTAIL SEGMENT PUBLIC PARA
|
||||
ORG 0
|
||||
EXECSTART LABEL WORD
|
||||
TRANTAIL ENDS
|
||||
|
||||
END
|
||||
43
v4.0/src/CMD/COMMAND/COMSEG.ASM
Normal file
43
v4.0/src/CMD/COMMAND/COMSEG.ASM
Normal file
@@ -0,0 +1,43 @@
|
||||
; SCCSID = @(#)comseg.asm 1.1 85/05/14
|
||||
; SCCSID = @(#)comseg.asm 1.1 85/05/14
|
||||
; The following are all of the segments used in the load order
|
||||
|
||||
CODERES SEGMENT PUBLIC BYTE ;AC000; resident code
|
||||
CODERES ENDS
|
||||
|
||||
DATARES SEGMENT PUBLIC BYTE ;AC000; resident data
|
||||
DATARES ENDS
|
||||
|
||||
BATARENA SEGMENT PUBLIC PARA ;AC000; space for DOS ALLOCATE header
|
||||
BATARENA ENDS
|
||||
|
||||
BATSEG SEGMENT PUBLIC PARA ;AC000; AUTOEXEC batch segment
|
||||
BATSEG ENDS
|
||||
|
||||
ENVARENA SEGMENT PUBLIC PARA ;AC000; space for DOS ALLOCATE header
|
||||
ENVARENA ENDS
|
||||
|
||||
ENVIRONMENT SEGMENT PUBLIC PARA ;AC000; Default COMMAND environment
|
||||
ENVIRONMENT ENDS
|
||||
|
||||
INIT SEGMENT PUBLIC PARA ;AC000; Initialization code
|
||||
INIT ENDS
|
||||
|
||||
TAIL SEGMENT PUBLIC PARA ;AC000; End of Init - start of Transient
|
||||
TAIL ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC BYTE ;AC000; Transient code
|
||||
TRANCODE ENDS
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE ;AC000; Transient data area
|
||||
TRANDATA ENDS
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000; Transient modifiable data area
|
||||
TRANSPACE ENDS
|
||||
|
||||
TRANTAIL SEGMENT PUBLIC PARA ;AC000; End of Transient
|
||||
TRANTAIL ENDS
|
||||
|
||||
RESGROUP GROUP CODERES,DATARES,BATARENA,BATSEG,ENVARENA,ENVIRONMENT,INIT,TAIL
|
||||
TRANGROUP GROUP TRANCODE,TRANDATA,TRANSPACE,TRANTAIL
|
||||
|
||||
6
v4.0/src/CMD/COMMAND/COMSW.ASM
Normal file
6
v4.0/src/CMD/COMMAND/COMSW.ASM
Normal file
@@ -0,0 +1,6 @@
|
||||
; SCCSID = @(#)comsw.asm 1.1 85/05/14
|
||||
; SCCSID = @(#)comsw.asm 1.1 85/05/14
|
||||
|
||||
include version.inc
|
||||
|
||||
|
||||
1001
v4.0/src/CMD/COMMAND/COPY.ASM
Normal file
1001
v4.0/src/CMD/COMMAND/COPY.ASM
Normal file
File diff suppressed because it is too large
Load Diff
276
v4.0/src/CMD/COMMAND/COPYPR1.ASM
Normal file
276
v4.0/src/CMD/COMMAND/COPYPR1.ASM
Normal file
@@ -0,0 +1,276 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)copypr1.asm 1.1 85/05/14
|
||||
; SCCSID = @(#)copypr1.asm 1.1 85/05/14
|
||||
INCLUDE comsw.asm
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE DOSSYM.INC
|
||||
; INCLUDE DEVSYM.INC
|
||||
INCLUDE comseg.asm
|
||||
INCLUDE comequ.asm
|
||||
.list
|
||||
.cref
|
||||
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN DEVWMES_ptr:word
|
||||
EXTRN ext_open_parms:byte ;AN000;
|
||||
EXTRN ext_open_seg:word ;AN000;
|
||||
EXTRN ext_open_off:word ;AN000;
|
||||
EXTRN Extend_buf_sub:byte ;AN000;
|
||||
EXTRN LOSTERR_ptr:word
|
||||
EXTRN NOSPACE_ptr:word
|
||||
EXTRN OVERWR_ptr:word
|
||||
TRANDATA ENDS
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN ASCII:BYTE
|
||||
EXTRN BINARY:BYTE
|
||||
EXTRN CFLAG:BYTE
|
||||
EXTRN CONCAT:BYTE
|
||||
EXTRN concat_xa:byte ;AC000;
|
||||
EXTRN DESTBUF:BYTE
|
||||
EXTRN DESTCLOSED:BYTE
|
||||
EXTRN DESTHAND:WORD
|
||||
EXTRN DESTISDEV:BYTE
|
||||
EXTRN DESTSWITCH:WORD
|
||||
EXTRN INEXACT:BYTE
|
||||
EXTRN NOWRITE:BYTE
|
||||
EXTRN NXTADD:WORD
|
||||
EXTRN plus_comma:byte ;AN000;
|
||||
EXTRN RDEOF:BYTE
|
||||
EXTRN src_xa_seg:word ;AN000;
|
||||
EXTRN SRCISDEV:BYTE
|
||||
EXTRN string_ptr_2:word ;AN000;
|
||||
EXTRN TERMREAD:BYTE
|
||||
EXTRN TPA:WORD
|
||||
EXTRN WRITTEN:WORD
|
||||
TRANSPACE ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC BYTE
|
||||
|
||||
EXTRN ENDCOPY:NEAR
|
||||
|
||||
PUBLIC FLSHFIL
|
||||
PUBLIC TRYFLUSH
|
||||
|
||||
ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING
|
||||
|
||||
TRYFLUSH:
|
||||
mov al,[CONCAT]
|
||||
push ax
|
||||
call FLSHFIL
|
||||
pop ax
|
||||
cmp al,[CONCAT]
|
||||
return
|
||||
|
||||
FLSHFIL:
|
||||
;
|
||||
; Write out any data remaining in memory.
|
||||
; Inputs:
|
||||
; [NXTADD] = No. of bytes to write
|
||||
; [CFLAG] <> 0 if file has been created
|
||||
; Outputs:
|
||||
; [NXTADD] = 0
|
||||
;
|
||||
MOV [TERMREAD],0
|
||||
cmp [CFLAG],0
|
||||
JZ NOTEXISTS
|
||||
JMP EXISTS
|
||||
|
||||
NOTEXISTS:
|
||||
invoke BUILDDEST ; Find out all about the destination
|
||||
invoke COMPNAME ; Source and dest. the same?
|
||||
JNZ PROCDEST ; If not, go ahead
|
||||
CMP [SRCISDEV],0
|
||||
JNZ PROCDEST ; Same name on device OK
|
||||
CMP [CONCAT],0 ; Concatenation?
|
||||
MOV DX,OFFSET TRANGROUP:OVERWR_ptr
|
||||
JNZ NO_CONCAT_ERR ;AC000; If not, overwrite error
|
||||
JMP COPERR ;AC000;
|
||||
|
||||
NO_CONCAT_ERR: ;AC000;
|
||||
MOV [NOWRITE],1 ; Flag not writting (just seeking)
|
||||
|
||||
PROCDEST:
|
||||
MOV AX,EXTOPEN SHL 8 ;AC000; open the file
|
||||
mov si,offset trangroup:destbuf ;AN030; get file name
|
||||
mov di,-1 ;AN030; indicate no parameters
|
||||
cmp src_xa_seg,no_xa_seg ;AN030; is there an XA segment?
|
||||
jz cont_no_xa ;AN030; no - no parameters
|
||||
mov di,offset trangroup:Ext_open_parms ;AN030; get parameters
|
||||
mov bx,src_xa_seg ;AN030; get extended attribute segment
|
||||
mov ext_open_seg,bx ;AN030; put it in parameter list
|
||||
mov ext_open_off,0 ;AN030; offset is 0
|
||||
|
||||
cont_no_xa: ;AN030;
|
||||
mov bx,write_open_mode ;AN000; get open mode for COPY
|
||||
xor cx,cx ;AN000; no special files
|
||||
mov dx,write_open_flag ;AN000; set up open flags
|
||||
|
||||
CMP [NOWRITE],0
|
||||
JNZ DODESTOPEN ; Don't actually create if NOWRITE set
|
||||
mov dx,creat_open_flag ;AC000; set up create flags
|
||||
|
||||
DODESTOPEN:
|
||||
INT int_command
|
||||
;
|
||||
; We assume that the error is normal. TriageError will correct the DX value
|
||||
; appropriately.
|
||||
;
|
||||
JNC dest_open_okay ;AC030;
|
||||
|
||||
xa_set_error: ;AN030; error occurred on XA
|
||||
invoke set_ext_error_msg ;AN030; get extended error
|
||||
|
||||
ext_err_set: ;AN030;
|
||||
mov string_ptr_2,offset trangroup:destbuf ;AN000; get address of failed string
|
||||
mov Extend_buf_sub,one_subst ;AN030; put number of subst in control block
|
||||
|
||||
COPERRJ2: ;AN030;
|
||||
jmp COPERR ;AN030; go issue message
|
||||
|
||||
dest_open_okay: ;AC030
|
||||
mov [DESTHAND],ax ; Save handle
|
||||
mov [CFLAG],1 ; Destination now exists
|
||||
mov bx,ax
|
||||
mov cx,bx ;AN030; get handle into CX
|
||||
invoke set_file_code_page ;AN030; set the code page for the target
|
||||
jc ext_err_set ;AN030; if no error, continue
|
||||
|
||||
mov [concat_xa],0 ;AN000; set first file flag off
|
||||
mov ax,(IOCTL SHL 8)
|
||||
INT int_command ; Get device stuff
|
||||
mov [DESTISDEV],dl ; Set dest info
|
||||
test dl,devid_ISDEV
|
||||
jz exists ;AC030; Dest a device
|
||||
|
||||
mov al,BYTE PTR [DESTSWITCH]
|
||||
AND AL,SwitchA+SwitchB
|
||||
JNZ TESTBOTH
|
||||
MOV AL,[ASCII] ; Neither set, use current setting
|
||||
OR AL,[BINARY]
|
||||
JZ EXSETA ; Neither set, default to ASCII
|
||||
|
||||
TESTBOTH:
|
||||
JPE EXISTS ; Both are set, ignore
|
||||
test AL,SwitchB
|
||||
jz EXISTS ; Leave in cooked mode
|
||||
mov ax,(IOCTL SHL 8) OR 1
|
||||
xor dh,dh
|
||||
or dl,devid_RAW
|
||||
mov [DESTISDEV],dl ; New value
|
||||
INT int_command ; Set device to RAW mode
|
||||
jmp short EXISTS
|
||||
|
||||
COPERRJ:
|
||||
jmp SHORT COPERR
|
||||
|
||||
EXSETA:
|
||||
;
|
||||
; What we read in may have been in binary mode, flag zapped write OK
|
||||
;
|
||||
mov [ASCII],SwitchA ; Set ASCII mode
|
||||
or [INEXACT],SwitchA ; ASCII -> INEXACT
|
||||
|
||||
EXISTS:
|
||||
cmp [NOWRITE],0
|
||||
jnz NOCHECKING ; If nowrite don't bother with name check
|
||||
cmp plus_comma,1 ;g don't check if just doing +,,
|
||||
jz NOCHECKING ;g
|
||||
invoke COMPNAME ; Source and dest. the same?
|
||||
JNZ NOCHECKING ; If not, go ahead
|
||||
CMP [SRCISDEV],0
|
||||
JNZ NOCHECKING ; Same name on device OK
|
||||
;
|
||||
; At this point we know in append (would have gotten overwrite error on first
|
||||
; destination create otherwise), and user trying to specify destination which
|
||||
; has been scribbled already (if dest had been named first, NOWRITE would
|
||||
; be set).
|
||||
;
|
||||
MOV DX,OFFSET TRANGROUP:LOSTERR_ptr ; Tell him he's not going to get it
|
||||
invoke std_Eprintf ;AC022;
|
||||
MOV [NXTADD],0 ; Set return
|
||||
INC [TERMREAD] ; Tell Read to give up
|
||||
|
||||
RET60:
|
||||
return
|
||||
|
||||
NOCHECKING:
|
||||
mov bx,[DESTHAND] ; Get handle
|
||||
XOR CX,CX
|
||||
XCHG CX,[NXTADD]
|
||||
JCXZ RET60 ; If Nothing to write, forget it
|
||||
INC [WRITTEN] ; Flag that we wrote something
|
||||
CMP [NOWRITE],0 ; If NOWRITE set, just seek CX bytes
|
||||
JNZ SEEKEND
|
||||
XOR DX,DX
|
||||
PUSH DS
|
||||
MOV DS,[TPA]
|
||||
ASSUME DS:NOTHING
|
||||
MOV AH,WRITE
|
||||
INT int_command
|
||||
POP DS
|
||||
ASSUME DS:TRANGROUP
|
||||
MOV DX,OFFSET TRANGROUP:NOSPACE_ptr
|
||||
JC xa_set_error_Jmp ;AC022; Failure
|
||||
sub cx,ax
|
||||
retz ; Wrote all supposed to
|
||||
test [DESTISDEV],devid_ISDEV
|
||||
jz COPERR ; Is a file, error
|
||||
test [DESTISDEV],devid_RAW
|
||||
jnz DEVWRTERR ; Is a raw device, error
|
||||
cmp [INEXACT],0
|
||||
retnz ; INEXACT so OK
|
||||
dec cx
|
||||
retz ; Wrote one byte less (the ^Z)
|
||||
|
||||
DEVWRTERR:
|
||||
MOV DX,OFFSET TRANGROUP:DEVWMES_ptr
|
||||
|
||||
PUBLIC COPERR
|
||||
COPERR:
|
||||
INVOKE std_Eprintf ;AC022;
|
||||
|
||||
COPERRP:
|
||||
inc [DESTCLOSED]
|
||||
cmp [CFLAG],0
|
||||
jz ENDCOPYJ ; Never actually got it open
|
||||
MOV bx,[DESTHAND]
|
||||
CMP BX,0
|
||||
JLE NoClose
|
||||
MOV AH,CLOSE ; Close the file
|
||||
INT int_command
|
||||
|
||||
NoClose:
|
||||
MOV DX,OFFSET TRANGROUP:DESTBUF
|
||||
MOV AH,UNLINK
|
||||
INT int_command ; And delete it
|
||||
MOV [CFLAG],0
|
||||
|
||||
ENDCOPYJ:
|
||||
JMP ENDCOPY
|
||||
|
||||
XA_SET_ERROR_JMP: ;AN022; Go set up error message
|
||||
jmp xa_set_error ;AN022;
|
||||
|
||||
SEEKEND:
|
||||
xor dx,dx ; Zero high half of offset
|
||||
xchg dx,cx ; cx:dx is seek location
|
||||
mov ax,(LSEEK SHL 8) OR 1
|
||||
INT int_command ; Seek ahead in the file
|
||||
cmp [RDEOF],0
|
||||
retz
|
||||
;
|
||||
; If a ^Z has been read we must set the file size to the current
|
||||
; file pointer location
|
||||
;
|
||||
MOV AH,WRITE
|
||||
INT int_command ; CX is zero, truncates file
|
||||
jc xa_set_error_Jmp ;AC022; Failure
|
||||
return
|
||||
|
||||
TRANCODE ENDS
|
||||
END
|
||||
|
||||
450
v4.0/src/CMD/COMMAND/COPYPR2.ASM
Normal file
450
v4.0/src/CMD/COMMAND/COPYPR2.ASM
Normal file
@@ -0,0 +1,450 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)copypr2.asm 1.1 85/05/14
|
||||
; SCCSID = @(#)copypr2.asm 1.1 85/05/14
|
||||
INCLUDE comsw.asm
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE DOSSYM.INC
|
||||
INCLUDE comseg.asm
|
||||
INCLUDE comequ.asm
|
||||
.list
|
||||
.cref
|
||||
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN FulDir_ptr:word ;AN052;
|
||||
TRANDATA ENDS
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN ASCII:BYTE
|
||||
EXTRN BINARY:BYTE
|
||||
EXTRN CONCAT:BYTE
|
||||
EXTRN DESTBUF:BYTE
|
||||
EXTRN DESTFCB:BYTE
|
||||
EXTRN DESTINFO:BYTE
|
||||
EXTRN DESTISDIR:BYTE
|
||||
EXTRN DESTTAIL:WORD
|
||||
EXTRN DESTVARS:BYTE
|
||||
EXTRN DIRBUF:BYTE
|
||||
EXTRN DIRCHAR:BYTE
|
||||
EXTRN FIRSTDEST:BYTE
|
||||
EXTRN INEXACT:BYTE
|
||||
EXTRN MELCOPY:BYTE
|
||||
EXTRN NXTADD:WORD
|
||||
EXTRN PLUS:BYTE
|
||||
EXTRN SDIRBUF:BYTE
|
||||
EXTRN SRCINFO:BYTE
|
||||
EXTRN srcxname:byte
|
||||
EXTRN TPA:WORD
|
||||
EXTRN trgxname:byte
|
||||
EXTRN USERDIR1:BYTE
|
||||
TRANSPACE ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC BYTE
|
||||
|
||||
EXTRN BADPATH_ERR:NEAR ;AN022;
|
||||
EXTRN COPERR:NEAR ;AN052;
|
||||
EXTRN EXTEND_SETUP:NEAR ;AN022;
|
||||
|
||||
PUBLIC BUILDPATH
|
||||
PUBLIC SETSTARS
|
||||
PUBLIC SETASC
|
||||
|
||||
ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING
|
||||
|
||||
SETASC:
|
||||
;
|
||||
; Given switch vector in AX,
|
||||
; Set ASCII switch if A is set
|
||||
; Clear ASCII switch if B is set
|
||||
; BINARY set if B specified
|
||||
; Leave ASCII unchanged if neither or both are set
|
||||
; Also sets INEXACT if ASCII is ever set. AL = ASCII on exit, flags set
|
||||
;
|
||||
AND AL,SwitchA+SwitchB
|
||||
JPE LOADSW ; PE means both or neither are set
|
||||
PUSH AX
|
||||
AND AL,SwitchB
|
||||
MOV [BINARY],AL
|
||||
POP AX
|
||||
AND AL,SwitchA
|
||||
MOV [ASCII],AL
|
||||
OR [INEXACT],AL
|
||||
|
||||
LOADSW:
|
||||
MOV AL,[ASCII]
|
||||
OR AL,AL
|
||||
return
|
||||
|
||||
public builddest
|
||||
BUILDDEST:
|
||||
cmp [DESTISDIR],-1
|
||||
jnz KNOWABOUTDEST ; Already done the figuring
|
||||
MOV DI,OFFSET TRANGROUP:USERDIR1
|
||||
mov bp,offset trangroup:DESTVARS
|
||||
call BUILDPATH
|
||||
invoke RESTUDIR1
|
||||
|
||||
; Now know all about the destination
|
||||
|
||||
KNOWABOUTDEST:
|
||||
xor al,al
|
||||
xchg al,[FIRSTDEST]
|
||||
or al,al
|
||||
jnz FIRSTDST
|
||||
jmp NOTFIRSTDEST
|
||||
|
||||
FIRSTDST:
|
||||
mov si,[DESTTAIL] ; Create an FCB of the original DEST
|
||||
mov di,offset trangroup:DESTFCB
|
||||
mov ax,PARSE_FILE_DESCRIPTOR SHL 8
|
||||
INT int_command
|
||||
CMP BYTE PTR [SI],0
|
||||
JZ GoodParse
|
||||
;AD052; MOV BYTE PTR [DI+1],"|" ; must be illegal file name character
|
||||
mov dx,offset trangroup:fuldir_ptr ;AN052; Issue "File creation error"
|
||||
jmp coperr ;AN052;
|
||||
|
||||
GoodParse:
|
||||
mov ax,word ptr [DESTBUF] ; Get drive
|
||||
cmp ah,':'
|
||||
jz DRVSPEC4
|
||||
mov al,'@'
|
||||
|
||||
DRVSPEC4:
|
||||
MOV CL,[ASCII] ; Save current ASCII setting
|
||||
or al,20h
|
||||
sub al,60h
|
||||
mov [DESTFCB],al
|
||||
mov al,[DESTINFO]
|
||||
mov ah,[SRCINFO]
|
||||
and ax,0202H
|
||||
or al,al
|
||||
jz NOTMELCOPY
|
||||
cmp al,ah
|
||||
jnz NOTMELCOPY
|
||||
cmp [PLUS],0
|
||||
jz NOTMELCOPY
|
||||
inc [MELCOPY] ; ambig source, ambig dest, and pluses
|
||||
xor al,al
|
||||
jmp short SETCONC
|
||||
|
||||
NOTMELCOPY:
|
||||
xor al,2 ; al=2 if unambig dest, =0 if ambig dest
|
||||
and al,ah
|
||||
shr al,1 ; al=1 if unambig dest AND ambig sorce
|
||||
; Implies concatenation
|
||||
SETCONC:
|
||||
or al,[PLUS] ; al=1 if concat
|
||||
mov [CONCAT],al
|
||||
shl al,1
|
||||
shl al,1
|
||||
mov [INEXACT],al ; Concat -> inexact copy
|
||||
cmp [BINARY],0
|
||||
jnz NOTFIRSTDEST ; Binary explicitly given, all OK
|
||||
mov [ASCII],al ; Concat -> ASCII
|
||||
or cl,cl
|
||||
jnz NOTFIRSTDEST ; ASCII flag set before, DATA read correctly
|
||||
or al,al
|
||||
JZ NOTFIRSTDEST ; ASCII flag did not change states
|
||||
;
|
||||
; At this point there may already be binary read data in the read buffer.
|
||||
; We need to find the first ^Z (if there is one) and trim the amount
|
||||
; of data in the buffer correctly.
|
||||
;
|
||||
MOV CX,[NXTADD]
|
||||
JCXZ NOTFIRSTDEST ; No data, everything OK
|
||||
MOV AL,1AH
|
||||
PUSH ES
|
||||
XOR DI,DI
|
||||
MOV ES,[TPA]
|
||||
REPNE SCASB ; Scan for EOF
|
||||
POP ES
|
||||
JNZ NOTFIRSTDEST ; No ^Z in buffer, everything OK
|
||||
DEC DI ; Point at ^Z
|
||||
MOV [NXTADD],DI ; New buffer
|
||||
|
||||
NOTFIRSTDEST:
|
||||
mov bx,offset trangroup:DIRBUF+1 ; Source of replacement chars
|
||||
cmp [CONCAT],0
|
||||
jz GOTCHRSRC ; Not a concat
|
||||
mov bx,offset trangroup:SDIRBUF+1 ; Source of replacement chars
|
||||
|
||||
GOTCHRSRC:
|
||||
mov si,offset trangroup:DESTFCB+1 ; Original dest name
|
||||
mov di,[DESTTAIL] ; Where to put result
|
||||
|
||||
public buildname
|
||||
BUILDNAME:
|
||||
mov cx,8
|
||||
|
||||
BUILDMAIN:
|
||||
lodsb
|
||||
cmp al,'?'
|
||||
jnz NOTAMBIG
|
||||
mov al,byte ptr [BX]
|
||||
|
||||
NOTAMBIG:
|
||||
cmp al,' '
|
||||
jz NOSTORE
|
||||
stosb
|
||||
|
||||
NOSTORE:
|
||||
inc bx
|
||||
loop BUILDMAIN
|
||||
mov cl,3
|
||||
mov al,' '
|
||||
cmp byte ptr [SI],al
|
||||
jz ENDDEST ; No extension
|
||||
mov al,dot_chr
|
||||
stosb
|
||||
|
||||
BUILDEXT:
|
||||
lodsb
|
||||
cmp al,'?'
|
||||
jnz NOTAMBIGE
|
||||
mov al,byte ptr [BX]
|
||||
|
||||
NOTAMBIGE:
|
||||
cmp al,' '
|
||||
jz NOSTOREE
|
||||
stosb
|
||||
|
||||
NOSTOREE:
|
||||
inc bx
|
||||
loop BUILDEXT
|
||||
ENDDEST:
|
||||
xor al,al
|
||||
stosb ; NUL terminate
|
||||
return
|
||||
|
||||
BUILDPATH:
|
||||
test [BP.INFO],2
|
||||
jnz NOTPFILE ; If ambig don't bother with open
|
||||
mov dx,bp
|
||||
add dx,BUF ; Set DX to spec
|
||||
|
||||
push di ;AN000;
|
||||
MOV AX,EXTOPEN SHL 8 ;AC000; open the file
|
||||
mov bx,read_open_mode ;AN000; get open mode for COPY
|
||||
xor cx,cx ;AN000; no special files
|
||||
mov si,dx ;AN030; get file name offset
|
||||
mov di,-1 ;AN030; no parm list
|
||||
mov dx,read_open_flag ;AN000; set up open flags
|
||||
INT int_command
|
||||
pop di ;AN000;
|
||||
jnc pure_file ;AN022; is pure file
|
||||
invoke get_ext_error_number ;AN022; get the extended error
|
||||
cmp ax,error_file_not_found ;AN022; if file not found - okay
|
||||
jz notpfile ;AN022;
|
||||
cmp ax,error_path_not_found ;AN022; if path not found - okay
|
||||
jz notpfile ;AN022;
|
||||
cmp ax,error_access_denied ;AN022; if access denied - okay
|
||||
jz notpfile ;AN022;
|
||||
jmp extend_setup ;AN022; exit with error
|
||||
|
||||
pure_file:
|
||||
mov bx,ax ; Is pure file
|
||||
mov ax,IOCTL SHL 8
|
||||
INT int_command
|
||||
mov ah,CLOSE
|
||||
INT int_command
|
||||
test dl,devid_ISDEV
|
||||
jnz ISADEV ; If device, done
|
||||
test [BP.INFO],4
|
||||
jz ISSIMPFILE ; If no path seps, done
|
||||
|
||||
NOTPFILE:
|
||||
mov dx,word ptr [BP.BUF]
|
||||
cmp dl,0 ;AN034; If no drive specified, get
|
||||
jz set_drive_spec ;AN034; default drive dir
|
||||
cmp dh,':'
|
||||
jz DRVSPEC5
|
||||
|
||||
set_drive_spec: ;AN034;
|
||||
mov dl,'@'
|
||||
|
||||
DRVSPEC5:
|
||||
or dl,20h
|
||||
sub dl,60h ; A = 1
|
||||
invoke SAVUDIR1
|
||||
jnc curdir_ok ;AN022; if error - exit
|
||||
invoke get_ext_error_number ;AN022; get the extended error
|
||||
jmp extend_setup ;AN022; exit with error
|
||||
|
||||
curdir_ok: ;AN022;
|
||||
mov dx,bp
|
||||
add dx,BUF ; Set DX for upcomming CHDIRs
|
||||
mov bh,[BP.INFO]
|
||||
and bh,6
|
||||
cmp bh,6 ; Ambig and path ?
|
||||
jnz CHECKAMB ; jmp if no
|
||||
mov si,[BP.TTAIL]
|
||||
mov bl,':'
|
||||
cmp byte ptr [si-2],bl
|
||||
jnz KNOWNOTSPEC
|
||||
mov [BP.ISDIR],2 ; Know is d:/file
|
||||
jmp short DOPCDJ
|
||||
|
||||
KNOWNOTSPEC:
|
||||
mov [BP.ISDIR],1 ; Know is path/file
|
||||
dec si ; Point to the /
|
||||
|
||||
DOPCDJ:
|
||||
jmp DOPCD ;AC022; need long jump
|
||||
|
||||
CHECKAMB:
|
||||
cmp bh,2
|
||||
jnz CHECKCD
|
||||
|
||||
ISSIMPFILE:
|
||||
ISADEV:
|
||||
mov [BP.ISDIR],0 ; Know is file since ambig but no path
|
||||
return
|
||||
|
||||
CHECKCD:
|
||||
invoke SETREST1
|
||||
mov ah,CHDIR
|
||||
INT int_command
|
||||
jc NOTPDIR
|
||||
mov di,dx
|
||||
xor ax,ax
|
||||
mov cx,ax
|
||||
dec cx
|
||||
|
||||
Kloop: ;AN000; 3/3/KK
|
||||
MOV AL,ES:[DI] ;AN000; 3/3/KK
|
||||
INC DI ;AN000; 3/3/KK
|
||||
OR AL,AL ;AN000; 3/3/KK
|
||||
JZ Done ;AN000; 3/3/KK
|
||||
xor ah,ah ;AN000; 3/3/KK
|
||||
invoke Testkanj ;AN000; 3/3/KK
|
||||
JZ Kloop ;AN000; 3/3/KK
|
||||
INC DI ;AN000; 3/3/KK
|
||||
INC AH ;AN000; 3/3/KK
|
||||
jmp Kloop ;AN000; 3/3/KK
|
||||
|
||||
Done: ;AN000; 3/3/KK
|
||||
dec di
|
||||
mov al,[DIRCHAR]
|
||||
mov [bp.ISDIR],2 ; assume d:/file
|
||||
OR AH, AH ;AN000; 3/3/KK
|
||||
JNZ Store_pchar ;AN000; 3/3/KK this is the trailing byte of ECS code
|
||||
cmp al,[di-1]
|
||||
jz GOTSRCSLSH
|
||||
|
||||
Store_pchar: ;AN000; 3/3/KK
|
||||
stosb
|
||||
mov [bp.ISDIR],1 ; know path/file
|
||||
|
||||
GOTSRCSLSH:
|
||||
or [bp.INFO],6
|
||||
call SETSTARS
|
||||
return
|
||||
|
||||
|
||||
NOTPDIR:
|
||||
invoke get_ext_error_number ;AN022; get the extended error
|
||||
cmp ax,error_path_not_found ;AN022; if path not found - okay
|
||||
jz notpdir_try ;AN022;
|
||||
cmp ax,error_access_denied ;AN022; if access denied - okay
|
||||
jnz extend_setupj ;AN022; otherwise - exit error
|
||||
|
||||
notpdir_try: ;AN022;
|
||||
mov [bp.ISDIR],0 ; assume pure file
|
||||
mov bh,[bp.INFO]
|
||||
test bh,4
|
||||
retz ; Know pure file, no path seps
|
||||
mov [bp.ISDIR],2 ; assume d:/file
|
||||
mov si,[bp.TTAIL]
|
||||
cmp byte ptr [si],0
|
||||
jz BADCDERRJ2 ; Trailing '/'
|
||||
mov bl,dot_chr
|
||||
cmp byte ptr [si],bl
|
||||
jz BADCDERRJ2 ; If . or .. pure cd should have worked
|
||||
mov bl,':'
|
||||
cmp byte ptr [si-2],bl
|
||||
jz DOPCD ; Know d:/file
|
||||
mov [bp.ISDIR],1 ; Know path/file
|
||||
dec si ; Point at last '/'
|
||||
|
||||
DOPCD:
|
||||
xor bl,bl
|
||||
xchg bl,[SI] ; Stick in a NUL
|
||||
invoke SETREST1
|
||||
CMP DX,SI ;AN000; 3/3/KK
|
||||
JAE LookBack ;AN000; 3/3/KK
|
||||
PUSH SI ;AN000; 3/3/KK
|
||||
PUSH CX ;AN000; 3/3/KK
|
||||
MOV CX,SI ;AN000; 3/3/KK
|
||||
MOV SI,DX ;AN000; 3/3/KK
|
||||
|
||||
Kloop2: ;AN000; 3/3/KK
|
||||
LODSB ;AN000; 3/3/KK
|
||||
invoke TestKanj ;AN000; 3/3/KK
|
||||
jz NotKanj4 ;AN000; 3/3/KK
|
||||
LODSB ;AN000; 3/3/KK
|
||||
CMP SI,CX ;AN000; 3/3/KK
|
||||
JB Kloop2 ;AN000; 3/3/KK
|
||||
POP CX ;AN000; 3/3/KK
|
||||
POP SI ;AN000; 3/3/KK
|
||||
JMP SHORT DoCdr ;AN000; 3/3/KK Last char is ECS code, don't check for
|
||||
; trailing path sep
|
||||
NotKanj4: ;AN000; 3/3/KK
|
||||
CMP SI,CX ;AN000; 3/3/KK
|
||||
JB Kloop2 ;AN000; 3/3/KK
|
||||
POP CX ;AN000; 3/3/KK
|
||||
POP SI ;AN000; 3/3/KK
|
||||
|
||||
LookBack: ;AN000; 3/3/KK
|
||||
CMP BL,[SI-1] ; if double slash, then complain.
|
||||
JZ BadCDErrJ2
|
||||
|
||||
DoCdr: ;AN000; 3/3/KK
|
||||
mov ah,CHDIR
|
||||
INT int_command
|
||||
xchg bl,[SI]
|
||||
retnc
|
||||
invoke get_ext_error_number ;AN022; get the extended error
|
||||
|
||||
EXTEND_SETUPJ: ;AN022;
|
||||
JMP EXTEND_SETUP ;AN022; go issue the error message
|
||||
|
||||
BADCDERRJ2:
|
||||
jmp badpath_err ;AC022; go issue path not found message
|
||||
|
||||
SETSTARS:
|
||||
mov [bp.TTAIL],DI
|
||||
add [bp.SIZ],12
|
||||
mov ax,dot_qmark
|
||||
mov cx,8
|
||||
rep stosb
|
||||
xchg al,ah
|
||||
stosb
|
||||
xchg al,ah
|
||||
mov cl,3
|
||||
rep stosb
|
||||
xor al,al
|
||||
stosb
|
||||
return
|
||||
|
||||
PUBLIC CompName
|
||||
COMPNAME:
|
||||
|
||||
mov si,offset trangroup:DESTBUF ;g do name translate of target
|
||||
mov di,offset trangroup:TRGXNAME ;g save for name comparison
|
||||
mov ah,xnametrans ;g
|
||||
int int_command ;g
|
||||
|
||||
MOV si,offset trangroup:SRCXNAME ;g get name translate of source
|
||||
MOV di,offset trangroup:TRGXNAME ;g get name translate of target
|
||||
|
||||
|
||||
invoke STRCOMP
|
||||
|
||||
return
|
||||
|
||||
TRANCODE ENDS
|
||||
END
|
||||
|
||||
417
v4.0/src/CMD/COMMAND/CPARSE.ASM
Normal file
417
v4.0/src/CMD/COMMAND/CPARSE.ASM
Normal file
@@ -0,0 +1,417 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)cparse.asm 1.1 85/05/14
|
||||
; SCCSID = @(#)cparse.asm 1.1 85/05/14
|
||||
INCLUDE comsw.asm
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE DOSSYM.INC
|
||||
INCLUDE DEVSYM.INC
|
||||
INCLUDE comseg.asm
|
||||
INCLUDE comequ.asm
|
||||
.list
|
||||
.cref
|
||||
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN BADCD_PTR:WORD ;AC022;
|
||||
EXTRN BADCPMES_ptr:word ;AC000;
|
||||
TRANDATA ENDS
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN comma:byte
|
||||
EXTRN cpyflag:byte
|
||||
EXTRN CURDRV:BYTE
|
||||
EXTRN ELCNT:BYTE
|
||||
EXTRN ELPOS:BYTE
|
||||
EXTRN EXPAND_STAR:BYTE
|
||||
EXTRN SKPDEL:BYTE
|
||||
EXTRN STARTEL:WORD
|
||||
EXTRN SWITCHAR:BYTE
|
||||
EXTRN switch_list:byte
|
||||
EXTRN TPA:WORD
|
||||
TRANSPACE ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC BYTE
|
||||
|
||||
ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING
|
||||
|
||||
EXTRN CERROR:NEAR
|
||||
|
||||
PUBLIC BADCDERR ;AC022;
|
||||
PUBLIC CPARSE
|
||||
|
||||
SWCOUNT EQU 5 ; Must agree with length of switch_list
|
||||
|
||||
;-----------------------------------------------------------------------;
|
||||
; ENTRY: ;
|
||||
; DS:SI Points input buffer ;
|
||||
; ES:DI Points to the token buffer ;
|
||||
; BL Special delimiter for this call ;
|
||||
; Always checked last ;
|
||||
; set it to space if there is no special delimiter ;
|
||||
; EXIT: ;
|
||||
; DS:SI Points to next char in the input buffer ;
|
||||
; ES:DI Points to the token buffer ;
|
||||
; [STARTEL] Points to start of last element of path in token ;
|
||||
; points to a NUL for no element strings 'd:' 'd:/' ;
|
||||
; CX Character count ;
|
||||
; BH Condition Code ;
|
||||
; Bit 1H of BH set if switch character ;
|
||||
; Token buffer contains char after ;
|
||||
; switch character ;
|
||||
; BP has switch bits set (ORing only) ;
|
||||
; Bit 2H of BH set if ? or * in token ;
|
||||
; if * found element ? filled ;
|
||||
; Bit 4H of BH set if path sep in token ;
|
||||
; Bit 80H of BH set if the special delimiter ;
|
||||
; was skipped at the start of this token ;
|
||||
; Token buffer always starts d: for non switch tokens ;
|
||||
; CARRY SET ;
|
||||
; if CR on input ;
|
||||
; token buffer not altered ;
|
||||
; ;
|
||||
; DOES NOT RETURN ON BAD PATH, OR TRAILING SWITCH CHAR ERROR ;
|
||||
; MODIFIES: ;
|
||||
; CX, SI, AX, BH, DX and the Carry Flag ; ;
|
||||
; ;
|
||||
; -----------------------------------------------------------------------;
|
||||
;---------------
|
||||
; Modifications to cparse: recognition of right and left parentheses
|
||||
; as integral tokens, and removal of automatic upper-case conversion code.
|
||||
;
|
||||
; Both modifications were installed in the course of adding a coherent
|
||||
; command-line parser to COMMAND.COM which builds a UNIX-style argv[]/argc
|
||||
; structure for command-line arguments. This parser relies on cparse to
|
||||
; recognize individual tokens.
|
||||
;
|
||||
; To process for-loops correctly, parentheses must therefore be
|
||||
; recognized as tokens. The upper-case conversion code was removed so
|
||||
; that commands (such as for and echo) would be able to use the "original"
|
||||
; text of the command line.
|
||||
;
|
||||
; Note also the modification to prevent the automatic conversion of colons
|
||||
; into spaces WITHIN THE SOURCE TEXT!
|
||||
;
|
||||
; Also note that BP is also clobbered if cparse recognizes any switches
|
||||
; on the command line.
|
||||
;
|
||||
; Alan L, OS/MSDOS 14 August 1983
|
||||
;---------------
|
||||
|
||||
CPARSE:
|
||||
ASSUME DS:TRANGROUP,ES:TRANGROUP
|
||||
|
||||
xor ax,ax
|
||||
mov [STARTEL],DI ; No path element (Is DI correct?)
|
||||
mov [ELPOS],al ; Start in 8 char prefix
|
||||
mov [SKPDEL],al ; No skip delimiter yet
|
||||
mov bh,al ; Init nothing
|
||||
pushf ; save flags
|
||||
push di ; save the token buffer addrss
|
||||
xor cx,cx ; no chars in token buffer
|
||||
mov comma,cl ;g reset comma flag
|
||||
moredelim:
|
||||
LODSB
|
||||
INVOKE DELIM
|
||||
JNZ SCANCDONE
|
||||
CMP AL,' '
|
||||
JZ moredelim
|
||||
CMP AL,9
|
||||
JZ moredelim
|
||||
xchg al,[SKPDEL]
|
||||
or al,al
|
||||
jz moredelim ; One non space/tab delimiter allowed
|
||||
test bh,080h ;g has a special char been found?
|
||||
jz no_comma ;g no - just exit
|
||||
mov comma,1 ;g set comma flag
|
||||
no_comma:
|
||||
JMP x_done ; Nul argument
|
||||
|
||||
SCANCDONE:
|
||||
|
||||
;;;; IF NOT KANJI 3/3/KK
|
||||
;---------------
|
||||
; Mod to avoid upper-case conversion.
|
||||
; cmp cpyflag,1 3/3/KK
|
||||
; jnz cpcont1 3/3/KK
|
||||
; invoke UPCONV 3/3/KK
|
||||
cpcont1:
|
||||
;---------------
|
||||
;;;; ENDIF 3/3/KK
|
||||
|
||||
cmp al,bl ; Special delimiter?
|
||||
jnz nospec
|
||||
or bh,80H
|
||||
jmp short moredelim
|
||||
|
||||
nospec:
|
||||
cmp al,0DH ; a CR?
|
||||
jne ncperror
|
||||
jmp cperror
|
||||
|
||||
ncperror:
|
||||
cmp al,[SWITCHAR] ; is the char the switch char?
|
||||
jne na_switch ; yes, process...
|
||||
jmp a_switch
|
||||
|
||||
na_switch:
|
||||
mov dl,':'
|
||||
cmp byte ptr [si],dl
|
||||
jne anum_chard ; Drive not specified
|
||||
|
||||
;;;; IF KANJI 3/3/KK
|
||||
;---------------
|
||||
; Mod to avoid upper-case conversion.
|
||||
cmp cpyflag,1
|
||||
jnz cpcont2
|
||||
invoke UPCONV
|
||||
cpcont2:
|
||||
;---------------
|
||||
;;;; ENDIF 3/3/KK
|
||||
|
||||
call move_char
|
||||
lodsb ; Get the ':'
|
||||
call move_char
|
||||
mov [STARTEL],di
|
||||
mov [ELCNT],0
|
||||
jmp anum_test
|
||||
|
||||
anum_chard:
|
||||
mov [STARTEL],di
|
||||
mov [ELCNT],0 ; Store of this char sets it to one
|
||||
cmp cpyflag,1 ; Was CPARSE called from COPY?
|
||||
jnz anum_char ; No, don't add drive spec.
|
||||
invoke PATHCHRCMP ; Starts with a pathchar?
|
||||
jnz anum_char ; no
|
||||
push ax
|
||||
mov al,[CURDRV] ; Insert drive spec
|
||||
add al,capital_A
|
||||
call move_char
|
||||
mov al,':'
|
||||
call move_char
|
||||
pop ax
|
||||
mov [STARTEL],di
|
||||
mov [ELCNT],0
|
||||
|
||||
anum_char:
|
||||
|
||||
;;;; IF KANJI 3/3/KK
|
||||
invoke TESTKANJ
|
||||
jz NOTKANJ ;AC048;
|
||||
call move_char
|
||||
lodsb
|
||||
jmp short notspecial
|
||||
|
||||
NOTKANJ: ;AN048; If not kanji
|
||||
cmp cpyflag,1 ;AN048; and if we're in COPY
|
||||
jnz testdot ;AN048;
|
||||
invoke upconv ;AN048; upper case the char
|
||||
|
||||
TESTDOT:
|
||||
;;;; ENDIF 3/3/KK
|
||||
|
||||
cmp al,dot_chr
|
||||
jnz testquest
|
||||
inc [ELPOS] ; flag in extension
|
||||
mov [ELCNT],0FFH ; Store of the '.' resets it to 0
|
||||
|
||||
testquest:
|
||||
cmp al,'?'
|
||||
jnz testsplat
|
||||
or bh,2
|
||||
|
||||
testsplat:
|
||||
cmp al,star
|
||||
jnz testpath
|
||||
or bh,2
|
||||
cmp byte ptr [expand_star],0
|
||||
jnz expand_filename
|
||||
jmp SHORT testpath
|
||||
|
||||
badperr2j:
|
||||
jmp badperr2
|
||||
|
||||
expand_filename:
|
||||
mov ah,7
|
||||
cmp [ELPOS],0
|
||||
jz gotelcnt
|
||||
mov ah,2
|
||||
|
||||
gotelcnt:
|
||||
mov al,'?'
|
||||
sub ah,[ELCNT]
|
||||
jc badperr2j
|
||||
xchg ah,cl
|
||||
jcxz testpathx
|
||||
|
||||
qmove:
|
||||
xchg ah,cl
|
||||
call move_char
|
||||
xchg ah,cl
|
||||
loop qmove
|
||||
|
||||
testpathx:
|
||||
xchg ah,cl
|
||||
|
||||
testpath:
|
||||
invoke PATHCHRCMP
|
||||
jnz notspecial
|
||||
or bh,4
|
||||
cmp byte ptr [expand_star],0
|
||||
jz no_err_check
|
||||
test bh,2 ; If just hit a '/', cannot have ? or * yet
|
||||
jnz badperr
|
||||
|
||||
no_err_check:
|
||||
mov [STARTEL],di ; New element
|
||||
INC [STARTEL] ; Point to char after /
|
||||
mov [ELCNT],0FFH ; Store of '/' sets it to 0
|
||||
mov [ELPOS],0
|
||||
|
||||
notspecial:
|
||||
call move_char ; just an alphanum string
|
||||
anum_test:
|
||||
|
||||
lodsb
|
||||
|
||||
;;;; IF NOT KANJI 3/3/KK
|
||||
;---------------
|
||||
; Mod to avoid upper-case conversion.
|
||||
; cmp cpyflag,1 3/3/KK
|
||||
; jnz cpcont3 3/3/KK
|
||||
; invoke UPCONV 3/3/KK
|
||||
cpcont3:
|
||||
;---------------
|
||||
;;;; ENDIF 3/3/KK
|
||||
|
||||
INVOKE DELIM
|
||||
je x_done
|
||||
|
||||
cmp al,0DH
|
||||
je x_done
|
||||
cmp al,[SWITCHAR]
|
||||
je x_done
|
||||
cmp al,bl
|
||||
je x_done
|
||||
cmp al,':' ; ':' allowed as trailer because
|
||||
; of devices
|
||||
;;;; IF KANJI 3/3/KK
|
||||
je FOO15
|
||||
jmp anum_char
|
||||
FOO15:
|
||||
;;; ELSE 3/3/KK
|
||||
;;; jne anum_charj 3/3/KK
|
||||
;;; ENDIF 3/3/KK
|
||||
|
||||
;---------------
|
||||
; Modification made for parseline.
|
||||
; Why would it be necessary to change colons to spaces? In this
|
||||
; case, EVERY colon is changed to a space; e.g., 'f:' yields 'f ',
|
||||
; but so does 'echo foo:bar' yield 'echo foo bar'.
|
||||
;---------------
|
||||
cmp cpyflag,2 ; Is CPARSE parsing the 1st token from
|
||||
; from PARSELINE?
|
||||
jnz cpcont4 ; No, continue
|
||||
call move_char ; Yes, save the ':' and go get another
|
||||
jmp anum_test ; character.
|
||||
|
||||
cpcont4:
|
||||
inc si ;Skip the ':'
|
||||
jmp short x_done
|
||||
|
||||
anum_charj:
|
||||
jmp anum_char
|
||||
|
||||
badperr2:
|
||||
mov dx,offset trangroup:BADCPMES_ptr
|
||||
jmp CERROR
|
||||
|
||||
badperr:
|
||||
BADCDERR: ;AC022; Issue "Invalid Directory"
|
||||
MOV DX,OFFSET TRANGROUP:BADCD_ptr ;AC022; message
|
||||
JMP CERROR ;AC022;
|
||||
|
||||
cperror:
|
||||
dec si ; adjust the pointer
|
||||
pop di ; retrive token buffer address
|
||||
popf ; restore flags
|
||||
stc ; set the carry bit
|
||||
return
|
||||
|
||||
x_done:
|
||||
dec si ; adjust for next round
|
||||
;---------------
|
||||
; Mod to recognize right and left parens as integral tokens.
|
||||
x_done2:
|
||||
;---------------
|
||||
jmp short out_token
|
||||
|
||||
a_switch:
|
||||
OR BH,1 ; Indicate switch
|
||||
OR BP,fSwitch
|
||||
INVOKE SCANOFF
|
||||
INC SI
|
||||
invoke testkanj ;AN057; See if DBCS lead byte
|
||||
jz a_switch_notkanj ;AN057; no - continue processing
|
||||
call move_char ;AN057; DBCS - store first byte
|
||||
lodsb ;AN057; get second byte
|
||||
call move_char ;AN057; store second byte
|
||||
or bp,fBadSwitch ;AN057; DBCS switch is invalid
|
||||
jmp short out_token ;AN057; don't bother checking switch
|
||||
a_switch_notkanj: ;AN057;
|
||||
cmp al,0DH
|
||||
jne Store_swt
|
||||
mov al,0
|
||||
stosb ; null at the end
|
||||
OR BP,fBadSwitch
|
||||
jmp cperror ; Trailing switch character error
|
||||
; BP = fSwitch but no switch
|
||||
; bit is set (unknown switch)
|
||||
Store_swt:
|
||||
call move_char ; store the character
|
||||
;
|
||||
;---------------
|
||||
; This upconv call must stay. It is used to identify copy-switches
|
||||
; on the command line, and won't store anything into the output buffer.
|
||||
invoke UPCONV
|
||||
;---------------
|
||||
;
|
||||
PUSH ES
|
||||
PUSH DI
|
||||
PUSH CX
|
||||
PUSH CS
|
||||
POP ES
|
||||
ASSUME ES:TRANGROUP
|
||||
MOV DI,OFFSET TRANGROUP:switch_list
|
||||
MOV CX,SWCOUNT
|
||||
OR BP,fBadSwitch
|
||||
REPNE SCASB
|
||||
JNZ out_tokenp
|
||||
AND BP,NOT fBadSwitch
|
||||
MOV AX,1
|
||||
SHL AX,CL
|
||||
OR BP,AX
|
||||
|
||||
out_tokenp:
|
||||
POP CX
|
||||
POP DI
|
||||
POP ES
|
||||
|
||||
ASSUME ES:NOTHING
|
||||
out_token:
|
||||
mov al,0
|
||||
stosb ; null at the end
|
||||
pop di ; restore token buffer pointer
|
||||
popf
|
||||
clc ; clear carry flag
|
||||
return
|
||||
|
||||
move_char:
|
||||
stosb ; store char in token buffer
|
||||
inc cx ; increment char count
|
||||
inc [ELCNT] ; increment element count for * substi
|
||||
return
|
||||
|
||||
TRANCODE ENDS
|
||||
END
|
||||
28
v4.0/src/CMD/COMMAND/ENVDATA.ASM
Normal file
28
v4.0/src/CMD/COMMAND/ENVDATA.ASM
Normal file
@@ -0,0 +1,28 @@
|
||||
; SCCSID = @(#)envdata.asm 1.1 85/05/14
|
||||
; SCCSID = @(#)envdata.asm 1.1 85/05/14
|
||||
; This file is included by command.asm and is used as the default command
|
||||
; environment.
|
||||
|
||||
ENVARENA SEGMENT PUBLIC PARA
|
||||
ORG 0
|
||||
DB 10h DUP (?) ;Pad for memory allocation addr mark
|
||||
ENVARENA ENDS
|
||||
|
||||
ENVIRONMENT SEGMENT PUBLIC PARA ; Default COMMAND environment
|
||||
|
||||
PUBLIC ECOMSPEC,ENVIREND,PATHSTRING
|
||||
|
||||
ORG 0
|
||||
PATHSTRING DB "PATH="
|
||||
USERPATH LABEL BYTE
|
||||
|
||||
DB 0 ; Null path
|
||||
DB "COMSPEC="
|
||||
ECOMSPEC DB "\COMMAND.COM" ;AC062
|
||||
DB 134 DUP (0)
|
||||
|
||||
ENVIREND LABEL BYTE
|
||||
|
||||
ENVIRONSIZ EQU $-PATHSTRING
|
||||
ENVIRONSIZ2 EQU $-ECOMSPEC
|
||||
ENVIRONMENT ENDS
|
||||
19
v4.0/src/CMD/COMMAND/FORDATA.ASM
Normal file
19
v4.0/src/CMD/COMMAND/FORDATA.ASM
Normal file
@@ -0,0 +1,19 @@
|
||||
; SCCSID = @(#)fordata.asm 1.1 85/05/14
|
||||
; SCCSID = @(#)fordata.asm 1.1 85/05/14
|
||||
; Data structure definitions included by tfor.asm
|
||||
|
||||
for_info STRUC
|
||||
for_args DB (SIZE arg_unit) DUP (?) ; argv[] structure
|
||||
FOR_COM_START DB (?) ; beginning of <command>
|
||||
FOR_EXPAND DW (?) ; * or ? item in <list>?
|
||||
FOR_MINARG DW (?) ; beginning of <list>
|
||||
FOR_MAXARG DW (?) ; end of <list>
|
||||
forbuf DW 64 DUP (?) ; temporary buffer
|
||||
fordma DW 64 DUP (?) ; FindFirst/Next buffer
|
||||
FOR_VAR DB (?) ; loop control variable
|
||||
for_info ENDS
|
||||
|
||||
; empty segment done for bogus addressing
|
||||
for_segment segment
|
||||
f LABEL BYTE
|
||||
for_segment ends
|
||||
18
v4.0/src/CMD/COMMAND/IFEQU.ASM
Normal file
18
v4.0/src/CMD/COMMAND/IFEQU.ASM
Normal file
@@ -0,0 +1,18 @@
|
||||
; SCCSID = @(#)ifequ.asm 1.1 85/05/14
|
||||
; SCCSID = @(#)ifequ.asm 1.1 85/05/14
|
||||
;*************************************
|
||||
; COMMAND EQUs which are switch dependant
|
||||
|
||||
IF1
|
||||
IF IBM
|
||||
%OUT DBCS Enabled IBM version
|
||||
ELSE
|
||||
%OUT Normal version
|
||||
ENDIF
|
||||
|
||||
;; IF KANJI 3/3/KK
|
||||
;; %OUT Kanji version 3/3/KK
|
||||
;; ENDIF 3/3/KK
|
||||
|
||||
ENDIF
|
||||
|
||||
1685
v4.0/src/CMD/COMMAND/INIT.ASM
Normal file
1685
v4.0/src/CMD/COMMAND/INIT.ASM
Normal file
File diff suppressed because it is too large
Load Diff
38
v4.0/src/CMD/COMMAND/IPARSE.ASM
Normal file
38
v4.0/src/CMD/COMMAND/IPARSE.ASM
Normal file
@@ -0,0 +1,38 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)iparse.asm 4.1 87/04/28
|
||||
; SCCSID = @(#)iparse.asm 4.1 87/04/28
|
||||
TITLE COMMAND interface to SYSPARSE
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE comseg.asm ;AN000;
|
||||
.list
|
||||
.cref
|
||||
|
||||
|
||||
INIT SEGMENT PUBLIC PARA ;AN000;
|
||||
|
||||
ASSUME CS:RESGROUP,DS:RESGROUP,ES:NOTHING,SS:NOTHING ;AN000;
|
||||
|
||||
|
||||
;AD054; public SYSPARSE ;AN000;
|
||||
|
||||
DateSW equ 0 ;AN000; do not Check date format
|
||||
TimeSW equ 0 ;AN000; do not Check time format
|
||||
CmpxSW equ 0 ;AN000; do not check complex list
|
||||
KeySW equ 0 ;AN025; do not support keywords
|
||||
Val2SW equ 0 ;AN025; do not Support value definition 2
|
||||
Val3SW equ 0 ;AN000; do not Support value definition 3
|
||||
QusSW equ 0 ;AN025; do not include quoted string
|
||||
DrvSW equ 0 ;AN025; do not include drive only
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
;AD054; INCLUDE parse.asm ;AN000;
|
||||
.list
|
||||
.cref
|
||||
|
||||
|
||||
INIT ends ;AN000;
|
||||
end ;AN000;
|
||||
|
||||
134
v4.0/src/CMD/COMMAND/MAKEFILE
Normal file
134
v4.0/src/CMD/COMMAND/MAKEFILE
Normal file
@@ -0,0 +1,134 @@
|
||||
#************************** makefile for cmd\append ***************************
|
||||
|
||||
msg =..\..\messages
|
||||
dos =..\..\dos
|
||||
inc =..\..\inc
|
||||
hinc =..\..\h
|
||||
|
||||
#
|
||||
####################### dependencies begin here. #########################
|
||||
#
|
||||
|
||||
all: command.com
|
||||
|
||||
$(inc)\dossym.inc: $(inc)\dosmac.inc $(inc)\bpb.inc \
|
||||
$(inc)\buffer.inc $(inc)\sysvar.inc $(inc)\vector.inc \
|
||||
$(inc)\mult.inc $(inc)\dirent.inc $(inc)\dpb.inc $(inc)\curdir.inc \
|
||||
$(inc)\cpmfcb.inc $(inc)\find.inc $(inc)\pdb.inc $(inc)\exe.inc \
|
||||
$(inc)\sf.inc $(inc)\arena.inc $(inc)\intnat.inc $(inc)\mi.inc \
|
||||
$(inc)\filemode.inc $(inc)\error.inc $(inc)\syscall.inc
|
||||
echo "touch $(inc)\dossym.inc"
|
||||
|
||||
command.ctl: command.skl $(msg)\$(COUNTRY).msg makefile
|
||||
|
||||
command1.obj: command1.asm $(inc)\dossym.inc \
|
||||
$(inc)\devsym.inc comsw.asm comequ.asm resmsg.equ \
|
||||
envdata.asm
|
||||
|
||||
command2.obj: command2.asm $(inc)\dossym.inc \
|
||||
$(inc)\devsym.inc comsw.asm comequ.asm resmsg.equ \
|
||||
envdata.asm
|
||||
|
||||
copy.obj: copy.asm comsw.asm $(inc)\dossym.inc \
|
||||
$(inc)\devsym.inc comseg.asm comequ.asm
|
||||
|
||||
copypr1.obj: copypr1.asm comsw.asm $(inc)\dossym.inc \
|
||||
$(inc)\devsym.inc comseg.asm comequ.asm
|
||||
|
||||
copypr2.obj: copypr2.asm comsw.asm $(inc)\dossym.inc \
|
||||
$(inc)\devsym.inc comseg.asm comequ.asm
|
||||
|
||||
cparse.obj: cparse.asm comsw.asm $(inc)\dossym.inc \
|
||||
$(inc)\devsym.inc comseg.asm comequ.asm
|
||||
|
||||
init.obj: init.asm $(inc)\dossym.inc $(inc)\devsym.inc \
|
||||
comsw.asm comseg.asm comequ.asm resmsg.equ $(inc)\sysmsg.inc \
|
||||
$(inc)\msgserv.asm command.ctl
|
||||
|
||||
iparse.obj: iparse.asm comseg.asm $(inc)\parse.asm $(inc)\psdata.inc
|
||||
|
||||
parse2.obj: parse2.asm $(inc)\dossym.inc $(inc)\devsym.inc comsw.asm \
|
||||
comseg.asm comequ.asm
|
||||
|
||||
path1.obj: path1.asm $(inc)\dossym.inc $(inc)\devsym.inc comsw.asm \
|
||||
comseg.asm comequ.asm
|
||||
|
||||
path2.obj: path2.asm $(inc)\dossym.inc $(inc)\devsym.inc comsw.asm \
|
||||
comseg.asm comequ.asm
|
||||
|
||||
rdata.obj: rdata.asm comsw.asm comseg.asm $(inc)\sysmsg.inc \
|
||||
$(inc)\msgserv.asm command.cla command.cl3 command.cl4 \
|
||||
command.cld command.clc command.cle command.ctl
|
||||
|
||||
rucode.obj: rucode.asm $(inc)\dossym.inc $(inc)\devsym.inc \
|
||||
$(inc)\doscntry.inc resmsg.equ $(inc)\sysmsg.inc \
|
||||
$(inc)\msgserv.asm comsw.asm comseg.asm comequ.asm command.ctl
|
||||
|
||||
tbatch.obj: tbatch.asm comsw.asm $(inc)\dossym.inc $(inc)\doscntry.inc \
|
||||
$(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm
|
||||
|
||||
tbatch2.obj: tbatch2.asm comsw.asm $(inc)\dossym.inc $(inc)\doscntry.inc \
|
||||
$(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm
|
||||
|
||||
tcmd1a.obj: tcmd1a.asm comsw.asm $(inc)\dossym.inc $(inc)\ioctl.inc \
|
||||
$(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm
|
||||
|
||||
tcmd1b.obj: tcmd1b.asm comsw.asm $(inc)\dossym.inc $(inc)\ioctl.inc \
|
||||
$(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm $(inc)\ea.inc
|
||||
|
||||
tcmd2a.obj: tcmd2a.asm comsw.asm $(inc)\dossym.inc $(inc)\ioctl.inc \
|
||||
$(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm
|
||||
|
||||
tcmd2b.obj: tcmd2b.asm comsw.asm $(inc)\dossym.inc \
|
||||
$(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm
|
||||
|
||||
tcode.obj: tcode.asm comsw.asm $(inc)\dossym.inc \
|
||||
$(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm \
|
||||
$(inc)\mshalo.asm
|
||||
|
||||
tdata.obj: tdata.asm comsw.asm comseg.asm $(inc)\curdir.inc \
|
||||
$(inc)\error.inc ifequ.asm comequ.asm $(inc)\sysmsg.inc \
|
||||
$(inc)\msgserv.asm tranmsg.asm command.clf command.cl1 command.cl2 \
|
||||
command.ctl $(inc)\ea.inc
|
||||
|
||||
tenv.obj: tenv.asm comsw.asm $(inc)\dossym.inc $(inc)\devsym.inc \
|
||||
comseg.asm comequ.asm ifequ.asm $(inc)\doscntry.inc
|
||||
|
||||
tenv2.obj: tenv2.asm comsw.asm $(inc)\dossym.inc $(inc)\devsym.inc \
|
||||
comseg.asm comequ.asm ifequ.asm
|
||||
|
||||
tfor.obj: tfor.asm comsw.asm $(inc)\dossym.inc $(inc)\devsym.inc \
|
||||
comseg.asm comequ.asm ifequ.asm fordata.asm
|
||||
|
||||
tmisc1.obj: tmisc1.asm comsw.asm $(inc)\dossym.inc \
|
||||
$(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm
|
||||
|
||||
tmisc2.obj: tmisc2.asm comsw.asm $(inc)\dossym.inc $(inc)\ioctl.inc \
|
||||
$(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm
|
||||
|
||||
tparse.obj: tparse.asm comseg.asm $(inc)\parse.asm $(inc)\psdata.inc
|
||||
|
||||
tpipe.obj: tpipe.asm comsw.asm $(inc)\dossym.inc \
|
||||
$(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm
|
||||
|
||||
tprintf.obj: tprintf.asm comsw.asm $(inc)\dosmac.inc \
|
||||
comseg.asm comequ.asm $(inc)\sysmsg.inc $(inc)\msgserv.asm \
|
||||
command.ctl
|
||||
|
||||
tspc.obj: tspc.asm comsw.asm $(inc)\dossym.inc comequ.asm \
|
||||
ifequ.asm comseg.asm $(inc)\ea.inc
|
||||
|
||||
tucode.obj: tucode.asm $(inc)\dosmac.inc $(inc)\dossym.inc \
|
||||
comsw.asm comseg.asm comequ.asm ifequ.asm
|
||||
|
||||
uinit.obj: uinit.asm comsw.asm comseg.asm ifequ.asm command.clb \
|
||||
$(inc)\sysmsg.inc $(inc)\msgserv.asm command.ctl
|
||||
|
||||
command.com: command1.obj command2.obj rucode.obj rdata.obj init.obj iparse.obj \
|
||||
uinit.obj tcode.obj tbatch.obj tbatch2.obj tfor.obj tcmd1a.obj tcmd1b.obj \
|
||||
tcmd2a.obj tcmd2b.obj tenv.obj tenv2.obj tmisc1.obj tmisc2.obj tpipe.obj \
|
||||
parse2.obj path1.obj path2.obj tucode.obj copy.obj copypr1.obj copypr2.obj \
|
||||
cparse.obj tparse.obj tprintf.obj tdata.obj tspc.obj
|
||||
link @command.lnk
|
||||
exe2bin command.exe command.com
|
||||
del command.exe
|
||||
422
v4.0/src/CMD/COMMAND/PARSE2.ASM
Normal file
422
v4.0/src/CMD/COMMAND/PARSE2.ASM
Normal file
@@ -0,0 +1,422 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)parse.asm 1.1 85/05/14
|
||||
; SCCSID = @(#)parse.asm 1.1 85/05/14
|
||||
.sall
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE DOSSYM.INC
|
||||
INCLUDE DEVSYM.INC
|
||||
include comsw.asm
|
||||
include comseg.asm
|
||||
include comequ.asm
|
||||
.list
|
||||
.cref
|
||||
|
||||
|
||||
break <Parse.Asm>
|
||||
;----------------------------------------------------------------------------
|
||||
; PARSE.ASM contains the routines to perform command line parsing.
|
||||
; Parse and Path share a buffer and argv[] definitions.
|
||||
; Invoking <Parseline> maps the unparsed command line in COMBUF into an
|
||||
; array of pointers to the parsed tokens. The resulting array, argv[],
|
||||
; also contains extra information provided by cparse about each token
|
||||
; <Parseline> should be executed prior to <Path_Search>
|
||||
;
|
||||
; Alan L, OS/MSDOS August 15, 1983
|
||||
;
|
||||
;
|
||||
; ENTRY:
|
||||
; <Parseline>: command line in COMTAB.
|
||||
; EXIT:
|
||||
; <Parseline>: success flag, argcnt (number of args), argv[].
|
||||
; NOTE(S):
|
||||
; * <Argv_calc> handily turns an array index into an absolute pointer.
|
||||
; The computation depends on the size of an argv[] element (arg_ele).
|
||||
; * <Parseline> calls <cparse> for chunks of the command line. <Cparse>
|
||||
; does not function as specified; see <Parseline> for more details.
|
||||
; * <Parseline> now knows about the flags the internals of COMMAND.COM
|
||||
; need to know about. This extra information is stored in a switch_flag
|
||||
; word with each command-line argument; the switches themselves will not
|
||||
; appear in the resulting arg structure.
|
||||
; * With the exception of CARRY, flags are generally preserved across calls.
|
||||
;---------------
|
||||
; CONSTANTS:
|
||||
;---------------
|
||||
DEBUGx equ FALSE ; prints out debug info
|
||||
;---------------
|
||||
; DATA:
|
||||
;---------------
|
||||
|
||||
DATARES SEGMENT PUBLIC BYTE
|
||||
EXTRN FORFLAG:BYTE
|
||||
DATARES ENDS
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN combuf:byte
|
||||
EXTRN cpyflag:byte
|
||||
EXTRN expand_star:byte
|
||||
EXTRN RESSEG:word
|
||||
EXTRN STARTEL:word
|
||||
TRANSPACE ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC BYTE ;AC000;
|
||||
PUBLIC argv_calc ; convert array index into address
|
||||
PUBLIC parseline
|
||||
|
||||
|
||||
assume cs:trangroup, ds:trangroup, es:trangroup, ss:nothing
|
||||
|
||||
|
||||
break <Parseline: Munch on the command line>
|
||||
;----------------------------------------------------------------------------
|
||||
; PARSELINE takes an MSDOS command line and maps it into a UNIX-style
|
||||
; argv[argvcnt] array. The most important difference between this array and
|
||||
; the tradition UNIX format is the extra cparse information included with
|
||||
; each argument element.
|
||||
;---------------
|
||||
; ENTRY:
|
||||
; (BL special delimiter for cparse -- not implemented)
|
||||
;---------------
|
||||
; EXIT:
|
||||
; CF set if error
|
||||
; AL error code (carry set). Note AH clobbered in any event.
|
||||
; argv[] array of cparse flags and pointers to arguments
|
||||
; argvcnt argument count
|
||||
;---------------
|
||||
; NOTE(S):
|
||||
; * BL (special delimiter) is ignored, for now (set to space).
|
||||
; * Parseflags record contains cparse flags, as follows:
|
||||
; sw_flag -- was this arg a switch?
|
||||
; wildcard -- whether or not it contained a * or ?
|
||||
; path_sep -- maybe it was a pathname
|
||||
; unused -- for future expansion
|
||||
; special_delim -- was there an initial special delimiter?
|
||||
; * argv[] and argvcnt are undefined if CF/AL indicates an error.
|
||||
; * Relationship between input, cparse output, and comtail can be
|
||||
; found in the following chart. Despite the claim of the cparse
|
||||
; documentation that, "Token buffer always starts d: for non switch
|
||||
; tokens", such is not the case (see column two, row two).
|
||||
; Similarly, [STARTEL] is not null when the command line is one of
|
||||
; the forms, "d:", "d:\", or "d:/". In fact, *STARTEL (i.e., what
|
||||
; STARTEL addresses) will be null. This is clearly just a
|
||||
; documentation error.
|
||||
; * cparse also returns a switch code in BP for each switch it
|
||||
; recognizes on the command line.
|
||||
; * arglen for each token does NOT include the terminating null.
|
||||
; * Finally, note that interesting constructions like 'foodir/*.exe'
|
||||
; parse as three separate tokens, and the asterisk is NOT a wildcard.
|
||||
; For example, 'for %i in (foodir/*.exe) do echo %i' will first
|
||||
; echo 'foodir', then '*', then '.exe'. Using cparse for command-
|
||||
; line parsing may result in slightly different behavior than
|
||||
; previously observed with the old COMMAND.COM command-line parser.
|
||||
;
|
||||
; Input Cparse Command Line (80H)
|
||||
; \alan\foo.bat c:\alan\foo.bat \alan\foo.bat
|
||||
; alan\foo.bat alan\foo.bat alan\foo.bat
|
||||
; foo.bat foo.bat foo.bat
|
||||
; c:\alan\foo.bat c:\alan\foo.bat c:\alan\foo.bat
|
||||
; c:alan\foo.bat c:alan\foo.bat c:alan\foo.bat
|
||||
; c:foo.bat c:foo.bat c:foo.bat
|
||||
;---------------
|
||||
; CONSTANTS:
|
||||
;---------------
|
||||
;---------------
|
||||
; DATA:
|
||||
;---------------
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN arg:byte
|
||||
EXTRN argbufptr:word
|
||||
EXTRN comptr:word
|
||||
EXTRN last_arg:word
|
||||
EXTRN tpbuf:byte
|
||||
TRANSPACE ENDS
|
||||
|
||||
;---------------
|
||||
parseline:
|
||||
;---------------
|
||||
|
||||
push AX ; most of these are clobbered
|
||||
push BX ; by cparse...
|
||||
push CX
|
||||
push DX
|
||||
push DI
|
||||
push SI
|
||||
pushf
|
||||
mov cpyflag,0 ; Turn "CPARSE called from COPY flag" off
|
||||
|
||||
mov [LAST_ARG], -1 ; last argument at which to accumulate
|
||||
xor ax,ax
|
||||
mov cx,SIZE arg_unit
|
||||
mov di,offset trangroup:arg
|
||||
rep stosb
|
||||
mov argbufptr,offset trangroup:arg.argbuf
|
||||
mov arg.argswinfo, 0 ; switch information, and info to date
|
||||
mov arg.argvcnt, 0 ; initialize argvcnt/argv[]
|
||||
mov SI, OFFSET TRANGROUP:combuf+2 ; prescan leaves cooked input in combuf
|
||||
|
||||
; This next section of code (up to pcont:) makes sure that si is set up for
|
||||
; parsing. It should point at COMBUF if FORFLAG is set and arg.argforcombuf
|
||||
; otherwise. This is done so that commands can get arg pointers into their
|
||||
; original command line (or an exact copy of it) in arg_ocomptr.
|
||||
; Arg.argforcombuf is used so that the for loop processor will always be able
|
||||
; to get a hold of its original command line; even after COMBUF is blasted by
|
||||
; the command to be repeated or the transient part of command has been
|
||||
; reloaded.
|
||||
|
||||
push ds
|
||||
mov ds,[RESSEG]
|
||||
assume ds:resgroup
|
||||
cmp FORFLAG,0
|
||||
pop ds
|
||||
assume ds:trangroup
|
||||
jnz pcont
|
||||
mov di,OFFSET TRANGROUP:arg.argforcombuf
|
||||
xor ch,ch
|
||||
mov cl,[COMBUF+1]
|
||||
inc cl
|
||||
rep movsb
|
||||
mov si,OFFSET TRANGROUP:arg.argforcombuf
|
||||
|
||||
pcont:
|
||||
mov DI, OFFSET TRANGROUP:tpbuf ; destination is temporary token buffer
|
||||
mov BL, ' ' ; no special delimiter, for now
|
||||
|
||||
parseloop:
|
||||
mov comptr,si ; save ptr into original command buffer
|
||||
xor BP, BP ; switch information put here by cparse
|
||||
mov byte ptr [expand_star],0 ; don't expand *'s to ?'s
|
||||
invoke scanoff ; skip leading blanks...
|
||||
invoke cparse ; byte off a token (args in SI, DI, BL)
|
||||
jnc More_prse
|
||||
or BP,BP ; Check for trailing switch character
|
||||
jz parsedone
|
||||
call newarg ; We hit CR but BP is non-zero. The
|
||||
; typical cause of this is that a
|
||||
; switch char IMMEDIATELY preceeds
|
||||
; the CR. We have an argument, but it
|
||||
; is sort of an error.
|
||||
jmp short parsedone ; We're done (found the CR).
|
||||
|
||||
More_prse:
|
||||
mov cpyflag,2 ; tell CPARSE that 1st token is done
|
||||
call newarg ; add to argv array (CX has char count)
|
||||
jnc parseloop ; was everything OK?
|
||||
jmp short parse_error ; NO, it wasn't -- bug out (CF set)
|
||||
|
||||
parsedone: ; successful completion of parseline
|
||||
popf
|
||||
clc
|
||||
jmp short parse_exit
|
||||
|
||||
parse_error: ; error entry (er, exit) point
|
||||
popf
|
||||
stc
|
||||
parse_exit: ; depend on not changing CF
|
||||
pop SI
|
||||
pop DI
|
||||
pop DX
|
||||
pop CX
|
||||
pop BX
|
||||
pop AX
|
||||
ret
|
||||
|
||||
;---------------
|
||||
; parseline ends
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
|
||||
break <NewArg>
|
||||
;----------------------------------------------------------------------------
|
||||
; NEWARG adds the supplied argstring and cparse data to arg.argv[].
|
||||
; ENTRY:
|
||||
; BH argflags
|
||||
; CX character count in argstring
|
||||
; DI pointer to argstring
|
||||
; comptr ptr to starting loc of current token in original command
|
||||
; [STARTEL] cparse's answer to where the last element starts
|
||||
; EXIT:
|
||||
; argbufptr points to next free section of argbuffer
|
||||
; arg.argbuf contains null-terminated argument strings
|
||||
; arg.argvcnt argument count
|
||||
; arg.argv[] array of flags and pointers
|
||||
; arg.arg_ocomptr ptr to starting loc of current token in original command
|
||||
; CF set if error
|
||||
; AL carry set: error code; otherwise, zero
|
||||
;---------------
|
||||
newarg:
|
||||
;---------------
|
||||
|
||||
push BX
|
||||
push CX
|
||||
push DX ; one never knows, do one?
|
||||
push DI
|
||||
push SI
|
||||
pushf
|
||||
call arg_switch ; if it's a switch, record switch info
|
||||
; LEAVE SWITCH ON COMMAND LINE!!
|
||||
;;; jc newarg_done ; previous arg's switches -- and leave
|
||||
|
||||
cmp arg.argvcnt, ARGMAX ; check to ensure we've not
|
||||
jge too_many_args ; exceeded array limits
|
||||
mov DH, BH ; save argflags
|
||||
mov BX, arg.argvcnt ; argv[argvcnt++] = arg data
|
||||
inc arg.argvcnt
|
||||
mov AX, OFFSET TRANGROUP:arg.argv
|
||||
call argv_calc ; convert offset to pointer
|
||||
mov [BX].argsw_word, 0 ; no switch information, yet...
|
||||
mov [BX].arglen, CX ; argv[argvcnt].arglen = arg length
|
||||
mov [BX].argflags, DH ; argv[argvcnt].argflags = cparse flags
|
||||
mov SI, argbufptr
|
||||
mov [BX].argpointer, SI ; argv[argvcnt].argpointer = [argbufptr]
|
||||
add SI, [STARTEL] ; save startel from new location
|
||||
sub SI, DI ; form pointer into argbuf
|
||||
mov [BX].argstartel, SI ; argv[argvcnt].argstartel = new [STARTEL]
|
||||
mov si,[comptr]
|
||||
mov [BX].arg_ocomptr,si ; arg_ocomptr=ptr into original com line
|
||||
|
||||
mov SI, DI ; now save argstring in argbuffer
|
||||
mov DI, argbufptr ; load the argbuf pointer and make
|
||||
add DI, CX ; sure we're not about to run off
|
||||
cmp DI, OFFSET TRANGROUP:arg.argbuf+ARGBLEN-1
|
||||
jge buf_ovflow ; the end of the buffer (plus null byte)
|
||||
sub DI, CX ; adjust the pointer
|
||||
cld
|
||||
rep movsb ; and save the string in argbuffer
|
||||
mov AL, ANULL ; tack a null byte on the end
|
||||
stosb
|
||||
mov argbufptr, DI ; update argbufptr after copy
|
||||
|
||||
newarg_done:
|
||||
popf
|
||||
clc
|
||||
jmp short newarg_exit
|
||||
|
||||
too_many_args:
|
||||
mov AX, arg_cnt_error
|
||||
jmp short newarg_error
|
||||
|
||||
buf_ovflow:
|
||||
mov AX, arg_buf_ovflow
|
||||
|
||||
newarg_error:
|
||||
popf
|
||||
stc
|
||||
|
||||
newarg_exit:
|
||||
pop SI
|
||||
pop DI
|
||||
pop DX
|
||||
pop CX
|
||||
pop BX
|
||||
ret
|
||||
|
||||
;---------------
|
||||
; NewArg ends
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
|
||||
break <Arg_Switch>
|
||||
;----------------------------------------------------------------------------
|
||||
; ARG_SWITCH decides if an argument might really be a switch. In the
|
||||
; event that it is, and we can recognize
|
||||
; ENTRY:
|
||||
; As in <newarg>.
|
||||
; EXIT:
|
||||
; CF -- clear (wasn't a switch); set (was a switch)
|
||||
; NOTE(S):
|
||||
; * The mechanism mapping a switch into a bit-value depends entirely
|
||||
; on the order of definition in the <switch_list> variable and the
|
||||
; values chosen to define the bits in CMDT:COMEQU.ASM. Change either
|
||||
; <switch_list> or the definitions in CMDT:COMEQU.ASM -- and rewrite
|
||||
; this mechanism. This code taken from CMDT:TCODE.ASM.
|
||||
; * The <switch_list> declared below is redundant to one declared in
|
||||
; TDATA.ASM, and used in TCODE.ASM.
|
||||
; * An ugly routine.
|
||||
;---------------
|
||||
; CONSTANTS:
|
||||
;---------------
|
||||
; Constants come from the definitions in CMDT:COMEQU.ASM.
|
||||
;---------------
|
||||
; DATA:
|
||||
;---------------
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
extrn switch_list:byte
|
||||
switch_count EQU $-switch_list
|
||||
transpace ends
|
||||
|
||||
;---------------
|
||||
Arg_Switch:
|
||||
;---------------
|
||||
|
||||
push AX
|
||||
push BX
|
||||
push CX
|
||||
push DI
|
||||
pushf
|
||||
test BH, MASK sw_flag ; is it a switch? (preserve flag word)
|
||||
jz arg_no_switch0
|
||||
cmp [LAST_ARG], -1 ; have we encountered any REAL args yet?
|
||||
je arg_no_switch1 ; no, so leading switches don't matter
|
||||
mov BX, [LAST_ARG] ; yes, add switch info to last REAL arg
|
||||
mov AX, OFFSET TRANGROUP:arg.argv
|
||||
call argv_calc
|
||||
or [BX].argsw_word, BP
|
||||
or arg.argswinfo, BP
|
||||
|
||||
arg_yes_switch: ; ah, sweet success...
|
||||
popf
|
||||
stc
|
||||
jmp short arg_switch_exit
|
||||
|
||||
arg_no_switch0:
|
||||
mov AX, arg.argvcnt ; future switches should then affect
|
||||
mov [LAST_ARG], AX ; this argument
|
||||
|
||||
arg_no_switch1: ; wasn't a switch, or we're pretending
|
||||
popf
|
||||
clc
|
||||
|
||||
arg_switch_exit:
|
||||
pop DI
|
||||
pop CX
|
||||
pop BX
|
||||
pop AX
|
||||
ret
|
||||
|
||||
;---------------
|
||||
; Arg_Switch ends
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
|
||||
break <Argv_calc>
|
||||
;----------------------------------------------------------------------------
|
||||
; ARGV_CALC maps an array index into a byte-offset from the base of
|
||||
; the supplied array. Method used for computing the address is:
|
||||
; Array Index * Array Elt Size + Base Addr = Elt Addr
|
||||
; ENTRY:
|
||||
; AX -- base of array
|
||||
; BX -- array index
|
||||
; EXIT:
|
||||
; BX -- byte offset
|
||||
;---------------
|
||||
|
||||
argv_calc:
|
||||
push ax ; Save base
|
||||
mov al,bl ; al = array index
|
||||
mov bl,SIZE argv_ele ; bl = size of an argv element
|
||||
mul bl ; ax = base offset
|
||||
pop bx ; Get base
|
||||
add ax,bx ; Add in base offset
|
||||
xchg ax,bx ; Restore ax and put byte offset in bx
|
||||
ret
|
||||
|
||||
;---------------
|
||||
; argv_calc ends
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
trancode ends
|
||||
end
|
||||
507
v4.0/src/CMD/COMMAND/PATH1.ASM
Normal file
507
v4.0/src/CMD/COMMAND/PATH1.ASM
Normal file
@@ -0,0 +1,507 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)path1.asm 1.1 85/05/14
|
||||
; SCCSID = @(#)path1.asm 1.1 85/05/14
|
||||
.sall
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE DOSSYM.INC
|
||||
include comsw.asm
|
||||
include comseg.asm
|
||||
include comequ.asm
|
||||
.list
|
||||
.cref
|
||||
|
||||
break <Path.Asm>
|
||||
;----------------------------------------------------------------------------
|
||||
; PATH.ASM contains the routines to perform pathname incovation. Path and
|
||||
; Parse share a temporary buffer and argv[] definitions. <Path_Search>,
|
||||
; given a pathname, attempts to find a corresponding executable or batch
|
||||
; file on disk. Directories specified in the user's search path will be
|
||||
; searched for a matching file, if a match is not found in the current
|
||||
; directory and if the pathname is actually only an MSDOS filename.
|
||||
; <Path_Search> assumes that the parsed command name can be found in
|
||||
; argv[0] -- in other words, <Parseline> should be executed prior to
|
||||
; <Path_Search>. Alternatively, the command name and appropriate
|
||||
; information could be placed in argv[0], or <Path_Search> could be
|
||||
; (easily) modified to make no assumptions about where its input is found.
|
||||
; Please find enclosed yet another important routine, <Save_Args>, which
|
||||
; places the entire arg/argv[]/argbuf structure on a piece of newly
|
||||
; allocated memory. This is handy for for-loop processing, and anything
|
||||
; else that wants to save the whole shebang and then process other command
|
||||
; lines.
|
||||
;
|
||||
; Alan L, OS/MSDOS August 15, 1983
|
||||
;
|
||||
; ENTRY:
|
||||
; <Path_Search>: argv[0].
|
||||
; <Save_Args>: bytes to allocate in addition to arg structure
|
||||
; EXIT:
|
||||
; <Path_Search>: success flag, best pathname match in EXECPATH.
|
||||
; <Save_Args>: success flag, segment address of new memory
|
||||
; NOTE(S):
|
||||
; * <Argv_calc> handily turns an array index into an absolute pointer.
|
||||
; The computation depends on the size of an argv[] element (arg_ele).
|
||||
; * <Parseline> calls <cparse> for chunks of the command line. <Cparse>
|
||||
; does not function as specified; see <Parseline> for more details.
|
||||
; * <Parseline> now knows about the flags the internals of COMMAND.COM
|
||||
; need to know about. This extra information is stored in a switch_flag
|
||||
; word with each command-line argument; the switches themselves will not
|
||||
; appear in the resulting arg structure.
|
||||
; * With the exception of CARRY, flags are generally preserved across calls.
|
||||
;---------------
|
||||
; CONSTANTS:
|
||||
;---------------
|
||||
DEBUGx equ FALSE ; prints out debug info
|
||||
;---------------
|
||||
; DATA:
|
||||
;---------------
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN baddrv_ptr:word
|
||||
TRANDATA ENDS
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN arg:byte
|
||||
EXTRN BADPMES_ptr:word
|
||||
EXTRN curdrv:byte
|
||||
EXTRN EXECPATH:byte
|
||||
EXTRN search_best_buf:byte
|
||||
EXTRN search_error:word
|
||||
EXTRN string_ptr_2:word
|
||||
EXTRN tpbuf:byte
|
||||
TRANSPACE ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC BYTE ;AC000;
|
||||
|
||||
assume cs:trangroup, ds:trangroup, es:trangroup, ss:nothing
|
||||
|
||||
break <Path_Search>
|
||||
;------------------------------------------------------------------------------
|
||||
; PATH_SEARCH tries to find the file it's given, somewhere. An initial value
|
||||
; of *argv[0].argstartel == 0 implies that there is no command (empty line
|
||||
; or 'd:' or 'd:/'). This check is done in strip; otherwise, strip formats
|
||||
; the filename/pathname into tpbuf. Search(tpbuf) is executed to see if we
|
||||
; have a match, either in the current working directory if we were handed
|
||||
; a filename, or in the specified directory, given a pathname. If this call
|
||||
; fails, and we were given a pathname, then Path_Search fails. Otherwise,
|
||||
; Path_Crunch is repeatedly invoked on tpbuf[STARTEL] (if there's a drive
|
||||
; prefix, we want to skip it) for each pathstring in userpath. Success on
|
||||
; either the first invocation of search or on one of the succeeding calls
|
||||
; sets up the appropriate information for copying the successful pathname
|
||||
; prefix (if any) into the result buffer, followed by the successful filename
|
||||
; match (from [search_best_buf]). The result is returned in in EXECPATH.
|
||||
; ENTRY:
|
||||
; argv[0] -- command name and associated information
|
||||
; EXIT:
|
||||
; AX -- non-zero indicates type of file found
|
||||
; EXECPATH -- successful pathname (AX non-zero)
|
||||
; NOTE(S):
|
||||
; 1) Uses the temporary buffer, tpbuf, from the parse routines.
|
||||
; 2) Some files are more equal than others. See search: for rankings.
|
||||
; 3) Path_Search terminates as soon as a call to search succeeds, even
|
||||
; if search returns an .exe or .bat.
|
||||
; 5) Clobbers dma address.
|
||||
|
||||
pbuflen equ 128 ; length of EXECPATH
|
||||
path_sep_char equ ';'
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN fbuf:byte
|
||||
EXTRN pathinfo:word
|
||||
EXTRN psep_char:byte
|
||||
TRANSPACE ENDS
|
||||
|
||||
Procedure Path_Search,NEAR
|
||||
|
||||
push BX
|
||||
push CX
|
||||
push DX ; could use a "stack 'em" instruction
|
||||
push SI
|
||||
push DI
|
||||
push BP
|
||||
pushf
|
||||
test DS:arg.argv[0].argflags, (MASK wildcard) + (MASK sw_flag)
|
||||
jz path_search_ok
|
||||
|
||||
path_failure_jmp:
|
||||
jmp path_failure ; ambiguous commands not allowed
|
||||
|
||||
path_search_ok:
|
||||
call store_pchar ; figure out the pathname separator
|
||||
mov DX, OFFSET TRANGROUP:fbuf ; clobber old dma value with
|
||||
trap set_dma ; a pointer to our dma buffer
|
||||
push ES
|
||||
invoke find_path ; get a handle (ES:DI) on user path
|
||||
mov DS:pathinfo[0], ES ; and squirrel it away
|
||||
mov DS:pathinfo[2], DI ; "old" pathstring pointer
|
||||
mov DS:pathinfo[4], DI ; "new" pathstring pointer
|
||||
pop ES
|
||||
|
||||
mov BX, pbuflen ; copy/format argv[0] into temp buffer
|
||||
mov SI, OFFSET TRANGROUP:EXECPATH
|
||||
invoke strip
|
||||
jc path_failure_jmp ; if possible, of course
|
||||
|
||||
mov DX, SI ; search(EXECPATH, error_message)
|
||||
mov [search_error], OFFSET TRANGROUP:BADDRV_ptr
|
||||
invoke search ; must do at least one search
|
||||
or AX, AX ; find anything?
|
||||
jz path_noinit ; failure ... search farther
|
||||
|
||||
mov BP, AX ; success... save filetype code
|
||||
mov DI, OFFSET TRANGROUP:EXECPATH
|
||||
mov SI, DS:arg.argv[0].argpointer
|
||||
mov CX, DS:arg.argv[0].argstartel
|
||||
sub CX, SI ; compute prefix bytes to copy
|
||||
;
|
||||
; We have the number of bytes in the prefix (up to the final component).
|
||||
; We need to form the complete pathname including leading drive and current
|
||||
; directory.
|
||||
;
|
||||
; Is there a drive letter present?
|
||||
;
|
||||
|
||||
mov ah,':'
|
||||
cmp cx,2 ; room for drive letter?
|
||||
jb AddDrive ; no, stick it in
|
||||
cmp [si+1],ah ; colon present?
|
||||
jz MoveDrive ; yes, just move it
|
||||
|
||||
AddDrive:
|
||||
mov al,curdrv ; get current drive
|
||||
add al,"A" ; convert to uppercase letter
|
||||
stosw ; store d:
|
||||
jmp short CheckPath
|
||||
|
||||
MoveDrive:
|
||||
lodsw ; move d:
|
||||
stosw
|
||||
sub cx,2 ; 2 bytes less to move
|
||||
|
||||
CheckPath:
|
||||
or al,20h
|
||||
mov dl,al
|
||||
sub dl,"a"-1 ; convert to 1-based for current dir
|
||||
;
|
||||
; Stick in beginning path char
|
||||
;
|
||||
mov al,psep_char
|
||||
stosb
|
||||
;
|
||||
; Is there a leading /? If so, then no current dir copy is necessary.
|
||||
; Otherwise, get current dir for DL.
|
||||
;
|
||||
cmp cx,1 ; is there room for path char?
|
||||
jb AddPath ; no, go add path
|
||||
lodsb
|
||||
dec cx
|
||||
cmp al,psep_char ; is there a path separator?
|
||||
jz MovePath ; yes, go move remainder of path
|
||||
inc cx
|
||||
dec si ; undo the lodsb
|
||||
|
||||
AddPath:
|
||||
SaveReg <SI>
|
||||
mov si,di ; remainder of buffer
|
||||
trap Current_dir
|
||||
;
|
||||
; The previous current dir will succeed a previous find_first already worked.
|
||||
;
|
||||
; Find end of string.
|
||||
;
|
||||
mov di,si
|
||||
RestoreReg <SI>
|
||||
mov al,psep_char
|
||||
cmp byte ptr [di],0 ; root (empty dir string)?
|
||||
jz MovePath ; yes, no need for path char
|
||||
|
||||
ScanEnd:
|
||||
cmp byte ptr [dI],0 ; end of string?
|
||||
jz FoundEnd
|
||||
inc di
|
||||
jmp ScanEnd
|
||||
;
|
||||
; Stick in a trailing path char
|
||||
;
|
||||
FoundEnd:
|
||||
stosb
|
||||
;
|
||||
; Move remaining part of path. Skip leading path char if present.
|
||||
;
|
||||
MovePath:
|
||||
cmp [si],al ; first char a path char?
|
||||
jnz CopyPath
|
||||
inc si ; move past leading char
|
||||
dec cx ; drop from count
|
||||
|
||||
CopyPath:
|
||||
jcxz CopyDone ; no chars to move!
|
||||
rep movsb
|
||||
|
||||
CopyDone:
|
||||
jmp path_success ; run off and form complete pathname
|
||||
|
||||
path_noinit:
|
||||
test DS:arg.argv[0].argflags, MASK path_sep
|
||||
jnz path_failure ; complete pathname specified ==> fail
|
||||
|
||||
mov BH, path_sep_char ; semicolon terminates pathstring
|
||||
mov DX, DS:arg.argv[0].argstartel ; this is where the last element starts
|
||||
sub DX, DS:arg.argv[0].argpointer ; form pointer into EXECPATH,
|
||||
add DX, OFFSET TRANGROUP:EXECPATH ; skipping over drive spec, if any
|
||||
|
||||
path_loop:
|
||||
call path_crunch ; pcrunch(EXECPATH, pathinfo)
|
||||
mov BP, AX ; save filetype code
|
||||
|
||||
lahf ; save flags, just in case
|
||||
or BP, BP ; did path_crunch find anything?
|
||||
jne path_found
|
||||
sahf ; see? needed those flags, after all!
|
||||
jnc path_loop ; is there anything left to the path?
|
||||
|
||||
path_failure:
|
||||
xor AX, AX
|
||||
;; jmp short path_exit ; 3/3/KK
|
||||
jmp path_exit ;AC000; 3/3/KK
|
||||
|
||||
path_found: ; pathinfo[] points to winner
|
||||
mov DI, OFFSET TRANGROUP:EXECPATH
|
||||
mov CX, pathinfo[4] ; "new" pointer -- end of string
|
||||
mov SI, pathinfo[2] ; "old" pointer -- beginning of string
|
||||
|
||||
;
|
||||
; BAS Nov 20/84
|
||||
; Look at the pathname and expand . and .. if they are the first element
|
||||
; in the pathname (after the drive letter)
|
||||
;
|
||||
push ES
|
||||
push pathinfo[0]
|
||||
pop ES
|
||||
cmp Byte Ptr ES:[SI+2],'.' ; Look for Current dir at start of path
|
||||
jnz path_cpy
|
||||
|
||||
push CX ; Save pointer to end of string
|
||||
mov AL, ES:[SI]
|
||||
mov [DI],AL ; Copy drive letter, :, and root char
|
||||
mov AL, ES:[SI+1] ; to EXECPATH
|
||||
mov [DI+1],AL
|
||||
mov AL,psep_char
|
||||
mov [DI+2],AL
|
||||
push SI ; Save pointer to begining of string
|
||||
mov DL,ES:[SI] ; Convert device letter for cur dir
|
||||
or DL,20h
|
||||
sub DL,"a"-1
|
||||
mov SI,DI ; pointer to EXECPATH
|
||||
add SI, 3 ; Don't wipe out drive and root info
|
||||
trap Current_dir
|
||||
invoke DStrlen ; Determine length of present info
|
||||
add SI,CX ; Don't copy over drive and root info
|
||||
dec SI
|
||||
mov DI,SI ; Point to end of target string
|
||||
pop SI ; Restore pointer to begining of string
|
||||
add SI, 3 ; Point past drive letter, :, .
|
||||
pop CX ; Restore pointer to end of string
|
||||
|
||||
path_cpy:
|
||||
pop ES
|
||||
sub CX, SI ; yields character count
|
||||
push DS ; time to switch segments
|
||||
push pathinfo[0] ; string lives in this segment
|
||||
pop DS
|
||||
cld
|
||||
;; rep movsb 3/3/KK ; copy the prefix path into EXECPATH
|
||||
|
||||
Kloop: ;AN000; 3/3/KK
|
||||
lodsb ;AN000; 3/3/KK
|
||||
stosb ;AN000; 3/3/KK
|
||||
invoke testkanj ;AN000; 3/3/KK
|
||||
jz NotKanj1 ;AN000; 3/3/KK
|
||||
dec cx ;AN000; 3/3/KK
|
||||
JCXZ PopDone ;AN000; Ignore boundary error 3/3/KK
|
||||
movsb ;AN000; 3/3/KK
|
||||
dec cx ;AN000; 3/3/KK
|
||||
cmp cx,1 ;AN000; One char (the terminator) left ? 3/3/KK
|
||||
ja Kloop ;AN000; no. 3/3/KK
|
||||
|
||||
PopDone: ;AN000; 3/3/KK
|
||||
POP DS ;AN000; Yes ES:DI->terminator, last char is 3/3/KK
|
||||
mov AL, psep_char ;AN000; KANJI 3/3/KK
|
||||
jmp Short path_store ;AN000; 3/3/KK
|
||||
|
||||
NotKanj1:
|
||||
loop Kloop
|
||||
pop DS ; return to our segment
|
||||
dec DI ; overwrite terminator
|
||||
mov AL, psep_char ; with a pathname separator
|
||||
cmp al,byte ptr [di-1]
|
||||
jz path_success
|
||||
|
||||
path_store: ;AN000; 3/3/KK
|
||||
stosb
|
||||
|
||||
path_success:
|
||||
mov SI, OFFSET TRANGROUP:search_best_buf
|
||||
xor CX, CX
|
||||
|
||||
path_succ_loop:
|
||||
lodsb ; append winning filename to path
|
||||
stosb ; (including terminating null)
|
||||
or al,al
|
||||
jnz path_succ_loop
|
||||
mov AX, BP ; retrieve filetype code
|
||||
|
||||
path_exit:
|
||||
popf
|
||||
pop BP
|
||||
pop DI
|
||||
pop SI ; chill out...
|
||||
pop DX
|
||||
pop CX
|
||||
pop BX
|
||||
ret
|
||||
EndProc Path_Search
|
||||
|
||||
break <Store_Pchar>
|
||||
;----------------------------------------------------------------------------
|
||||
; STORE_PCHAR determines the pathname-element separator and squirrels
|
||||
; it away. In other words, must we say '/bin/ls' or '\bin\ls'?
|
||||
; ENTRY:
|
||||
; EXIT:
|
||||
; NOTE(S):
|
||||
; * Uses <psep_char>, defined in <path_search>.
|
||||
;---------------
|
||||
;---------------
|
||||
Procedure Store_PChar,NEAR
|
||||
;---------------
|
||||
|
||||
push AX
|
||||
mov AL, '/' ; is the pathname-element separator
|
||||
invoke pathchrcmp ; a regular slash?
|
||||
jz store_slash ; if yes, remember slash
|
||||
mov al,'\'
|
||||
mov [psep_char], al ; otherwise, remember back-slash
|
||||
pop ax
|
||||
ret
|
||||
|
||||
store_slash:
|
||||
mov [psep_char], al
|
||||
pop ax
|
||||
return
|
||||
;---------------
|
||||
EndProc Store_Pchar
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
break <Path_Crunch>
|
||||
;----------------------------------------------------------------------------
|
||||
; PATH_CRUNCH takes a prefix from a prefix string, and a suffix from
|
||||
; EXECPATH, and smooshes them into tpbuf. The caller may supply an
|
||||
; additional separator to use for breaking up the path-string. Null is the
|
||||
; default. Once the user-string has been formed, search is invoked to see
|
||||
; what's out there.
|
||||
; ENTRY:
|
||||
; BH -- additional terminator character
|
||||
; SI -- pointer into pathstring to be dissected
|
||||
; DX -- pointer to stripped filename
|
||||
; EXIT:
|
||||
; AX -- non-zero (file type), zero (nothing found)
|
||||
; SI -- moves along pathstring from call to call
|
||||
; [search_best_buf] -- name of best file (AX non-zero)
|
||||
; [tpbuf] -- clobbered
|
||||
; NOTE(S):
|
||||
; * Implicit in this code is the ability to specify when to search
|
||||
; the current directory (if at all) through the PATH defined by
|
||||
; the user, a la UNIX (e.g., PATH=;c:\bin;c:\etc searches the
|
||||
; current directory before the bin and etc directories of drive c).
|
||||
;---------------
|
||||
Procedure Path_Crunch,NEAR
|
||||
;---------------
|
||||
push BX
|
||||
push CX
|
||||
push DX
|
||||
push DI
|
||||
push SI
|
||||
pushf
|
||||
call store_pchar ; figure out pathname separator
|
||||
mov DI, OFFSET TRANGROUP:tpbuf ; destination of concatenated string
|
||||
mov SI, pathinfo[4] ; "new" pointer to start with
|
||||
mov pathinfo[2], SI ; becomes "old" pointer
|
||||
push DS ; save old segment pointer
|
||||
push pathinfo[0] ; replace with pointer to userpath's
|
||||
pop DS ; segment
|
||||
xor cl,cl ;AN000; clear flag for later use 3/3/KK
|
||||
|
||||
path_cr_copy:
|
||||
lodsb ; get a pathname byte
|
||||
or al,al ; check for terminator(s)
|
||||
jz path_seg ; null terminates segment & pathstring
|
||||
cmp AL, BH
|
||||
jz path_seg ; BH terminates a pathstring segment
|
||||
invoke testkanj ;AN000; 3/3/KK
|
||||
jz NotKanj2 ;AN000; 3/3/KK
|
||||
stosb ;AN000; 3/3/KK
|
||||
movsb ;AN000; 3/3/KK
|
||||
MOV CL,1 ;AN000; CL=1 means latest stored char is DBCS 3/3/KK
|
||||
jmp path_cr_copy ;AN000; 3/3/KK
|
||||
|
||||
NotKanj2: ;AN000; 3/3/KK
|
||||
xor cl,cl ;AN000; CL=0 means latest stored char is SBCS 3/3/KK
|
||||
stosb ; save byte in concat buffer
|
||||
jmp path_cr_copy ; loop until we see a terminator
|
||||
|
||||
path_seg:
|
||||
pop DS ; restore old data segment
|
||||
mov pathinfo[4], SI ; save "new" pointer for next time
|
||||
mov BL, AL ; remember if we saw null or not...
|
||||
;;; REMOVE NEXT 3 LINES FOR CURDIR SPEC
|
||||
xor AX, AX ; in case nothing in pathstr...
|
||||
cmp DI, OFFSET TRANGROUP:tpbuf ; was there really anything in pathstr?
|
||||
je path_cr_leave ; if nothing was copied, pathstr empty
|
||||
|
||||
path_cr_look: ; form complete pathname
|
||||
mov al, psep_char ; add pathname separator for suffix
|
||||
or cl,cl ;AN000; 3/3/KK
|
||||
jnz path_cr_store ;AN000; this is a trailing byte of ECS code 3/3/KK
|
||||
cmp al,byte ptr [di-1]
|
||||
jz path_cr_l1
|
||||
|
||||
path_cr_store: ;AN000; 3/3/KK
|
||||
stosb
|
||||
|
||||
path_cr_l1:
|
||||
mov SI, DX
|
||||
|
||||
path_cr_l2:
|
||||
lodsb ; tack the stripped filename onto
|
||||
stosb ; the end of the path, up to and
|
||||
or AL, AL ; including the terminating null
|
||||
jnz path_cr_l2
|
||||
mov DX, OFFSET TRANGROUP:tpbuf ; and look for an appropriate file...
|
||||
mov [search_error], OFFSET TRANGROUP:BADPMES_ptr
|
||||
invoke search ; results are in AX & search_best_buf
|
||||
|
||||
path_cr_leave:
|
||||
or BL, BL ; did we finish off the pathstring?
|
||||
jz path_cr_empty ; null in BL means all gone...
|
||||
popf ; otherwise, plenty left
|
||||
clc
|
||||
jmp short path_cr_exit
|
||||
|
||||
path_cr_empty:
|
||||
popf
|
||||
stc
|
||||
|
||||
path_cr_exit:
|
||||
pop SI
|
||||
pop DI
|
||||
pop DX
|
||||
pop CX
|
||||
pop BX
|
||||
ret
|
||||
;---------------
|
||||
EndProc Path_Crunch
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
|
||||
trancode ends
|
||||
END
|
||||
458
v4.0/src/CMD/COMMAND/PATH2.ASM
Normal file
458
v4.0/src/CMD/COMMAND/PATH2.ASM
Normal file
@@ -0,0 +1,458 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)path2.asm 1.1 85/05/14
|
||||
; SCCSID = @(#)path2.asm 1.1 85/05/14
|
||||
.sall
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE DOSSYM.INC
|
||||
include comsw.asm
|
||||
include comseg.asm
|
||||
include comequ.asm
|
||||
.list
|
||||
.cref
|
||||
|
||||
|
||||
DATARES SEGMENT PUBLIC BYTE
|
||||
EXTRN FORFLAG:BYTE
|
||||
DATARES ENDS
|
||||
|
||||
|
||||
break <Path.Asm>
|
||||
;----------------------------------------------------------------------------
|
||||
; PATH.ASM contains the routines to perform pathname incovation. Path and
|
||||
; Parse share a temporary buffer and argv[] definitions. <Path_Search>,
|
||||
; given a pathname, attempts to find a corresponding executable or batch
|
||||
; file on disk. Directories specified in the user's search path will be
|
||||
; searched for a matching file, if a match is not found in the current
|
||||
; directory and if the pathname is actually only an MSDOS filename.
|
||||
; <Path_Search> assumes that the parsed command name can be found in
|
||||
; argv[0] -- in other words, <Parseline> should be executed prior to
|
||||
; <Path_Search>. Alternatively, the command name and appropriate
|
||||
; information could be placed in argv[0], or <Path_Search> could be
|
||||
; (easily) modified to make no assumptions about where its input is found.
|
||||
; Please find enclosed yet another important routine, <Save_Args>, which
|
||||
; places the entire arg/argv[]/argbuf structure on a piece of newly
|
||||
; allocated memory. This is handy for for-loop processing, and anything
|
||||
; else that wants to save the whole shebang and then process other command
|
||||
; lines.
|
||||
;
|
||||
; Alan L, OS/MSDOS August 15, 1983
|
||||
;
|
||||
; ENTRY:
|
||||
; <Path_Search>: argv[0].
|
||||
; <Save_Args>: bytes to allocate in addition to arg structure
|
||||
; EXIT:
|
||||
; <Path_Search>: success flag, best pathname match in EXECPATH.
|
||||
; <Save_Args>: success flag, segment address of new memory
|
||||
; NOTE(S):
|
||||
; * <Argv_calc> handily turns an array index into an absolute pointer.
|
||||
; The computation depends on the size of an argv[] element (arg_ele).
|
||||
; * <Parseline> calls <cparse> for chunks of the command line. <Cparse>
|
||||
; does not function as specified; see <Parseline> for more details.
|
||||
; * <Parseline> now knows about the flags the internals of COMMAND.COM
|
||||
; need to know about. This extra information is stored in a switch_flag
|
||||
; word with each command-line argument; the switches themselves will not
|
||||
; appear in the resulting arg structure.
|
||||
; * With the exception of CARRY, flags are generally preserved across calls.
|
||||
;---------------
|
||||
; CONSTANTS:
|
||||
;---------------
|
||||
DEBUGx equ FALSE ; prints out debug info
|
||||
;---------------
|
||||
; DATA:
|
||||
;---------------
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN arg:byte
|
||||
EXTRN BADPMES_ptr:word
|
||||
EXTRN curdrv:byte
|
||||
EXTRN EXECPATH:byte
|
||||
EXTRN ext_entered:byte ;AN005;
|
||||
EXTRN fbuf:byte
|
||||
EXTRN pathinfo:word
|
||||
EXTRN psep_char:byte
|
||||
EXTRN string_ptr_2:word
|
||||
EXTRN tpbuf:byte
|
||||
TRANSPACE ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC BYTE ;AC000;
|
||||
|
||||
assume cs:trangroup, ds:trangroup, es:trangroup, ss:nothing
|
||||
|
||||
|
||||
break <Search>
|
||||
;----------------------------------------------------------------------------
|
||||
; SEARCH, when given a pathname, attempts to find a file with
|
||||
; one of the following extensions: .com, .exe, .bat (highest to
|
||||
; lowest priority). Where conflicts arise, the extension with
|
||||
; the highest priority is favored.
|
||||
; ENTRY:
|
||||
; DX -- pointer to null-terminated pathname
|
||||
; fbuf -- dma buffer for findfirst/next
|
||||
; EXIT:
|
||||
; AX -- 8) file found with .com extension
|
||||
; 4) file found with .exe extension
|
||||
; 2) file found with .bat extension
|
||||
; 0) no such file to be found
|
||||
; (if AX is non-zero:)
|
||||
; [search_best] identical to AX
|
||||
; [search_best_buf] null-terminated filename
|
||||
; NOTES:
|
||||
; 1) Requires caller to have allocated a dma buffer and executed a setdma.
|
||||
;---------------
|
||||
; CONSTANTS:
|
||||
;---------------
|
||||
search_file_not_found equ 0
|
||||
search_com equ 8
|
||||
search_exe equ 4
|
||||
search_bat equ 2
|
||||
fname_len equ 8
|
||||
fname_max_len equ 13
|
||||
dot equ '.'
|
||||
wildchar equ '?'
|
||||
|
||||
;---------------
|
||||
; DATA:
|
||||
;---------------
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN search_best:byte
|
||||
EXTRN search_best_buf:byte
|
||||
EXTRN search_curdir_buf:byte
|
||||
EXTRN search_error:word
|
||||
TRANSPACE ENDS
|
||||
|
||||
;---------------
|
||||
Procedure Search,NEAR
|
||||
;---------------
|
||||
push CX
|
||||
push DX
|
||||
push DI
|
||||
push SI
|
||||
pushf
|
||||
|
||||
push DX ; check drivespec (save pname ptr)
|
||||
mov DI, DX ; working copy of pathname
|
||||
mov SI, OFFSET TRANGROUP:search_curdir_buf
|
||||
xor DX, DX ; zero means current drive
|
||||
cmp BYTE PTR [DI+1],':' ; is there a drive spec?
|
||||
jne search_dir_check
|
||||
mov DL, [DI] ; get the drive byte
|
||||
and DL, NOT 20H ; uppercase the sucker
|
||||
sub DL, '@' ; and convert to drive number
|
||||
|
||||
search_dir_check:
|
||||
trap Current_Dir ; can we get the drive's current
|
||||
pop DX ; directory? If we can't we'll
|
||||
jc search_invalid_drive ; assume it's a bad drive...
|
||||
|
||||
mov CX, search_attr ; filetypes to search for
|
||||
trap Find_First ; request first match, if any
|
||||
jc search_no_file
|
||||
mov search_best, search_file_not_found
|
||||
mov [search_best_buf], ANULL ; nothing's been found, yet
|
||||
|
||||
search_loop:
|
||||
call search_ftype ; determine if .com, &c...
|
||||
cmp AL, search_best ; better than what we've found so far?
|
||||
jle search_next ; no, look for another
|
||||
mov search_best, AL ; found something... save its code
|
||||
mov SI, OFFSET TRANGROUP:fbuf.find_buf_pname
|
||||
mov DI, OFFSET TRANGROUP:search_best_buf
|
||||
mov CX, fname_max_len
|
||||
cld
|
||||
rep movsb ; save complete pathname representation
|
||||
cmp AL, search_com ; have we found the best of all?
|
||||
je search_done
|
||||
|
||||
search_next: ; keep on looking
|
||||
mov CX, search_attr
|
||||
trap Find_Next ; next match
|
||||
jnc search_loop
|
||||
|
||||
search_done: ; it's all over with...
|
||||
mov AL, search_best ; pick best to return with
|
||||
cmp ext_entered,1 ;AN005; Did user request a specific ext?
|
||||
jz search_exit ;AN005; no - exit
|
||||
mov al,ext_entered ;AN005; yes - get the real file type back
|
||||
mov search_best,al ;AN005; save the real file type
|
||||
jmp short search_exit
|
||||
|
||||
search_invalid_drive: ; Tell the user path/drive
|
||||
mov DX, [search_error] ; appropriate error message
|
||||
invoke std_printf ; and pretend no file found
|
||||
|
||||
search_no_file: ; couldn't find a match
|
||||
mov AX, search_file_not_found
|
||||
|
||||
search_exit:
|
||||
popf
|
||||
pop SI
|
||||
pop DI
|
||||
pop DX
|
||||
pop CX
|
||||
ret
|
||||
;---------------
|
||||
EndProc Search
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
|
||||
break <Search_Ftype>
|
||||
;----------------------------------------------------------------------------
|
||||
; SEARCH_FTYPE determines the type of a file by examining its extension.
|
||||
; ENTRY:
|
||||
; fbuf -- dma buffer containing filename
|
||||
; EXIT:
|
||||
; AX -- file code, as given in search header
|
||||
; NOTE(S):
|
||||
; * Implicit assumption that NULL == search_file_not_found
|
||||
;---------------
|
||||
; DATA:
|
||||
;---------------
|
||||
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
|
||||
extrn comext:byte,exeext:byte,batext:byte
|
||||
trandata ends
|
||||
;---------------
|
||||
Procedure Search_Ftype,NEAR
|
||||
;---------------
|
||||
push DI
|
||||
push si
|
||||
mov AX, ANULL ; find the end of the filename
|
||||
mov DI, OFFSET TRANGROUP:fbuf.find_buf_pname
|
||||
mov CX, fname_max_len
|
||||
cld
|
||||
repnz scasb ; search for the terminating null
|
||||
jnz ftype_exit ; weird... no null byte at end
|
||||
sub di,5 ; . + E + X + T + NULL
|
||||
;
|
||||
; Compare .COM
|
||||
;
|
||||
mov si,offset trangroup:comext
|
||||
mov ax,di
|
||||
cmpsw
|
||||
jnz ftype_exe
|
||||
cmpsw
|
||||
jnz ftype_exe
|
||||
mov AX, search_com ; success!
|
||||
jmp short ftype_exit
|
||||
;
|
||||
; Compare .EXE
|
||||
;
|
||||
|
||||
ftype_exe: ; still looking... now for '.exe'
|
||||
mov di,ax
|
||||
mov si,offset trangroup:exeext
|
||||
cmpsw
|
||||
jnz ftype_bat
|
||||
cmpsw
|
||||
jnz ftype_bat
|
||||
mov AX, search_exe ; success!
|
||||
jmp short ftype_exit
|
||||
;
|
||||
; Compare .BAT
|
||||
;
|
||||
|
||||
ftype_bat: ; still looking... now for '.bat'
|
||||
mov di,ax
|
||||
mov si,offset trangroup:batext
|
||||
cmpsw
|
||||
jnz ftype_fail
|
||||
cmpsw
|
||||
jnz ftype_fail
|
||||
mov AX, search_bat ; success!
|
||||
jmp short ftype_exit
|
||||
|
||||
ftype_fail: ; file doesn't match what we need
|
||||
mov ax,ANULL
|
||||
|
||||
ftype_exit:
|
||||
cmp ext_entered,1 ;AN005; was an extension entered?
|
||||
jz ftype_done ;AN005; no - exit
|
||||
cmp ax,ANULL ;AN005; was any match found
|
||||
jz ftype_done ;AN005; no - exit
|
||||
mov ext_entered,al ;AN005; save the match type found
|
||||
mov AX, search_com ;AN005; send back best was found to stop search
|
||||
|
||||
ftype_done: ;AN005;
|
||||
pop SI
|
||||
pop DI
|
||||
ret
|
||||
|
||||
;---------------
|
||||
EndProc Search_Ftype
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
|
||||
break <Strip>
|
||||
;----------------------------------------------------------------------------
|
||||
; STRIP copies the source string (argv[0]) into the destination buffer,
|
||||
; replacing any extension with wildcards.
|
||||
; ENTRY:
|
||||
; BX -- maximum length of destination buffer
|
||||
; DS:SI -- address of destination buffer
|
||||
; argv[0] -- command name to be stripped
|
||||
; EXIT:
|
||||
; CF -- set if failure, clear if successful
|
||||
; NOTE(S):
|
||||
;---------------
|
||||
Procedure Strip,NEAR
|
||||
;---------------
|
||||
push AX
|
||||
push BX
|
||||
push CX
|
||||
push DX
|
||||
push DI
|
||||
push SI
|
||||
pushf
|
||||
|
||||
mov ext_entered,1 ;AN005; assume no extension on file name
|
||||
mov DX, DS:arg.argv[0].argpointer ; save pointer to beginning of argstring
|
||||
mov DI, DS:arg.argv[0].argstartel ; beginning of last pathname element
|
||||
cmp BYTE PTR [DI], 0 ; *STARTEL == NULL means no command
|
||||
jz strip_error
|
||||
mov CX, DX ; compute where end of argstring lies
|
||||
add CX, DS:arg.argv[0].arglen
|
||||
sub CX, DI ; and then find length of last element
|
||||
inc CX ; include null as well
|
||||
mov AL, dot ; let's find the filetype extension
|
||||
cld
|
||||
repnz scasb ; wind up pointing to either null or dot
|
||||
jcxz process_ext ;AN005; if no extension found, just continue
|
||||
mov ext_entered,0 ;AN005; we found an extension
|
||||
mov al,ANULL ;AN005; continue scanning until the
|
||||
repnz scasb ;AN005; end of line is reached.
|
||||
|
||||
process_ext: ;AN005;
|
||||
mov CX, DI ; pointer to end of argstring yields
|
||||
sub CX, DX ; number of bytes to be copied
|
||||
sub BX, 4 ; can argstring fit into dest. buffer?
|
||||
cmp CX, BX
|
||||
jg strip_error ; if not, we must have a bad pathname
|
||||
mov DI, SI ; destination buffer
|
||||
mov SI, DX ; source is beginning of pathname
|
||||
cld
|
||||
rep movsb ; SI=arg,DI=buffer,CX=argend-argbeg
|
||||
cmp ext_entered,1 ;AN005; if an extension was entered
|
||||
jnz skip_wilds ;AN005; don't set up wildcard ext.
|
||||
|
||||
dec DI ; overwrite null or dot
|
||||
stosb ; with a dot
|
||||
mov AL, wildchar ; now add wildcards
|
||||
stosb
|
||||
stosb
|
||||
stosb
|
||||
mov AL, ANULL ; and a terminating null
|
||||
stosb
|
||||
|
||||
skip_wilds: ;AN005;
|
||||
popf
|
||||
clc ; chill out...
|
||||
jmp short strip_exit
|
||||
|
||||
strip_error:
|
||||
popf
|
||||
stc
|
||||
|
||||
strip_exit:
|
||||
pop SI
|
||||
pop DI
|
||||
pop DX
|
||||
pop CX
|
||||
pop BX
|
||||
pop AX
|
||||
ret
|
||||
;---------------
|
||||
EndProc Strip
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
|
||||
break <Save_Args>
|
||||
;----------------------------------------------------------------------------
|
||||
; SAVE_ARGS attempts to preserve the existing argv[]/argvcnt/argbuffer
|
||||
; structure in newly allocated memory. The argv[] structure is found at the
|
||||
; beginning of this area. The caller indicates how much extra space is
|
||||
; needed in the resulting structure; Save_Args returns a segment number and
|
||||
; an offset into that area, indicating where the caller may preserve its own
|
||||
; data. Note that <argvcnt> can be found at <offset-2>.
|
||||
; ENTRY:
|
||||
; BX -- size (in bytes) of extra area to allocate
|
||||
; EXIT:
|
||||
; AX -- segment of new area.
|
||||
; CF -- set if unable to save a copy.
|
||||
; NOTE(S):
|
||||
; 1) The allocated area will be AT LEAST the size requested -- since
|
||||
; the underlying MSDOS call, <alloc> returns an integral number of
|
||||
; paragraphs.
|
||||
; 2) It is an error if MSDOS can't allocate AT LEAST as much memory
|
||||
; as the caller of Save_Args requests.
|
||||
; 3) AX is undefined if CF indicates an error.
|
||||
;---------------
|
||||
Procedure Save_Args,NEAR
|
||||
;---------------
|
||||
push BX
|
||||
push CX
|
||||
push DX
|
||||
push DI
|
||||
push SI
|
||||
push BP
|
||||
pushf
|
||||
add BX, SIZE arg_unit + 0FH ; space for arg structure, round up
|
||||
mov CL, 4 ; to paragraph size and convert
|
||||
shr BX, CL ; size in bytes to size in paragraphs
|
||||
trap Alloc
|
||||
jc save_error
|
||||
mov BP, AX ; save segment id
|
||||
push ES ; save TRANGROUP address
|
||||
mov ES, AX ; switch to new memory segment
|
||||
assume ES:nothing
|
||||
mov CX, SIZE arg_unit ; get back structure size
|
||||
xor DI, DI ; destination is new memory area
|
||||
mov SI, OFFSET TRANGROUP:arg ; source is arg structure
|
||||
rep movsb ; move that sucker!
|
||||
mov CX, arg.argvcnt ; adjust argv pointers
|
||||
xor AX, AX ; base address for argv_calc
|
||||
mov SI, OFFSET TRANGROUP:arg.argbuf - OFFSET arg_unit.argbuf
|
||||
|
||||
save_ptr_loop:
|
||||
dec CX ; exhausted all args?
|
||||
jl save_done
|
||||
mov BX, CX ; get arg index and
|
||||
invoke argv_calc ; convert to a pointer
|
||||
mov DX, DS:arg.argv[BX].argpointer
|
||||
sub DX, SI ; adjust argpointer
|
||||
mov ES:argv[BX].argpointer, DX
|
||||
mov DX, DS:arg.argv[BX].argstartel
|
||||
sub DX, SI ; and adjust argstartel
|
||||
mov ES:argv[BX].argstartel, DX
|
||||
mov DX, DS:arg.argv[BX].arg_ocomptr
|
||||
sub DX, SI ; and adjust arg_ocomptr
|
||||
mov ES:argv[BX].arg_ocomptr, DX
|
||||
jmp save_ptr_loop
|
||||
|
||||
save_done:
|
||||
pop ES ; back we go to TRANGROUP
|
||||
assume ES:trangroup
|
||||
mov AX, BP ; restore segment id
|
||||
jmp short save_ok
|
||||
|
||||
save_error:
|
||||
popf
|
||||
stc
|
||||
jmp short save_exit
|
||||
|
||||
save_ok:
|
||||
popf
|
||||
clc
|
||||
save_exit:
|
||||
pop BP
|
||||
pop SI
|
||||
pop DI
|
||||
pop DX
|
||||
pop CX
|
||||
pop BX
|
||||
ret
|
||||
;---------------
|
||||
EndProc Save_Args
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
trancode ends
|
||||
END
|
||||
611
v4.0/src/CMD/COMMAND/RDATA.ASM
Normal file
611
v4.0/src/CMD/COMMAND/RDATA.ASM
Normal file
@@ -0,0 +1,611 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)rdata.asm 4.2 85/09/22
|
||||
; SCCSID = @(#)rdata.asm 4.2 85/09/22
|
||||
TITLE COMMAND Resident DATA
|
||||
|
||||
include comsw.asm
|
||||
.xlist
|
||||
.xcref
|
||||
include comseg.asm
|
||||
.list
|
||||
.cref
|
||||
|
||||
;
|
||||
; Equates for initialization (from COMEQU)
|
||||
;
|
||||
initInit equ 01h ; initialization in progress
|
||||
initSpecial equ 02h ; in initialization time/date routine
|
||||
initCtrlC equ 04h ; already in ^C handler
|
||||
|
||||
Tokenized = FALSE
|
||||
|
||||
CODERES SEGMENT PUBLIC BYTE ;AC000;
|
||||
PUBLIC RSTACK
|
||||
EXTRN EXT_EXEC:NEAR
|
||||
EXTRN THEADFIX:NEAR
|
||||
EXTRN TREMCHECK:NEAR
|
||||
|
||||
DB (80H - 3) DUP (?)
|
||||
|
||||
RSTACK LABEL WORD
|
||||
|
||||
CODERES ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN COMMAND:NEAR
|
||||
TRANCODE ENDS
|
||||
|
||||
; Data for resident portion
|
||||
|
||||
DATARES SEGMENT PUBLIC BYTE
|
||||
|
||||
IF Tokenized
|
||||
PUBLIC IOTYP
|
||||
PUBLIC MESADD
|
||||
ENDIF
|
||||
|
||||
PUBLIC abort_char
|
||||
PUBLIC append_flag ;AN020;
|
||||
PUBLIC append_state ;AN020;
|
||||
PUBLIC BADFAT_BLOCK ;AC000;
|
||||
PUBLIC BADFAT_OP_SEG ;AC000;
|
||||
PUBLIC BADFAT_SUBST ;AC000;
|
||||
PUBLIC BATCH
|
||||
PUBLIC Batch_Abort
|
||||
PUBLIC call_batch_flag
|
||||
PUBLIC call_flag
|
||||
PUBLIC CDEVAT ;AC000;
|
||||
PUBLIC COM_FCB1
|
||||
PUBLIC COM_FCB2
|
||||
PUBLIC COM_PTR
|
||||
PUBLIC COM_XLAT_ADDR
|
||||
PUBLIC COMDRV
|
||||
PUBLIC COMPRMT1_BLOCK ;AC000;
|
||||
PUBLIC COMPRMT1_SEG ;AC000;
|
||||
PUBLIC COMPRMT1_SEG2 ;AC000;
|
||||
PUBLIC COMPRMT1_SUBST ;AC000;
|
||||
PUBLIC COMSPEC
|
||||
PUBLIC crit_msg_off ;AC000;
|
||||
PUBLIC crit_msg_seg ;AC000;
|
||||
PUBLIC critical_msg_start ;AC000;
|
||||
PUBLIC comspec_print
|
||||
PUBLIC comspec_end
|
||||
PUBLIC cpdrv
|
||||
PUBLIC crit_err_INFO
|
||||
PUBLIC DATARESEND
|
||||
PUBLIC dbcs_vector_addr ;AN000;
|
||||
PUBLIC DEVE_OP_OFF ;AC000;
|
||||
PUBLIC DEVE_OP_SEG ;AC000;
|
||||
PUBLIC DEVE_OP_SEG2 ;AC000;
|
||||
PUBLIC DEVEMES_BLOCK ;AC000;
|
||||
PUBLIC DEVEMES_SUBST ;AC000;
|
||||
PUBLIC DEVENAM ;AC000;
|
||||
PUBLIC DISP_CLASS ;AN000;
|
||||
PUBLIC DRVLET
|
||||
PUBLIC DRVNUM_BLOCK ;AC000;
|
||||
PUBLIC DRVNUM_OP_OFF ;AC000;
|
||||
PUBLIC DRVNUM_OP_SEG ;AC000;
|
||||
PUBLIC DRVNUM_OP_SEG2 ;AC000;
|
||||
PUBLIC DRVNUM_SUBST ;AC000;
|
||||
PUBLIC ECHOFLAG
|
||||
PUBLIC ENVIRSEG
|
||||
PUBLIC ERR15_OP_SEG ;AC000;
|
||||
PUBLIC ERR15_OP_SEG2 ;AC000;
|
||||
PUBLIC ERR15_OP_SEG3 ;AC000;
|
||||
PUBLIC ERR15MES_BLOCK ;AC000;
|
||||
PUBLIC ERR15MES_SUBST ;AC000;
|
||||
PUBLIC ERRCD_24
|
||||
PUBLIC ErrType
|
||||
PUBLIC EXEC_BLOCK
|
||||
PUBLIC EXECEMES_BLOCK ;AC000;
|
||||
PUBLIC EXECEMES_SUBST ;AC000;
|
||||
PUBLIC EXECEMES_OFF ;AC000;
|
||||
PUBLIC EXECEMES_SEG ;AC000;
|
||||
PUBLIC EXTCOM
|
||||
PUBLIC extended_msg_start ;AN000;
|
||||
PUBLIC extmsgend ;AN000;
|
||||
PUBLIC fail_char ;AC000;
|
||||
PUBLIC fFail
|
||||
PUBLIC FORFLAG
|
||||
PUBLIC forptr
|
||||
PUBLIC fucase_addr ;AN000;
|
||||
PUBLIC HANDLE01
|
||||
PUBLIC IFFlag
|
||||
PUBLIC ignore_char
|
||||
PUBLIC In_Batch
|
||||
PUBLIC InitFlag
|
||||
PUBLIC INPIPEPTR
|
||||
PUBLIC INT_2E_RET
|
||||
PUBLIC IO_SAVE
|
||||
PUBLIC LOADING
|
||||
PUBLIC LTPA
|
||||
PUBLIC MEMSIZ
|
||||
;AD054; PUBLIC MESBAS ;AC000;
|
||||
PUBLIC MYSEG
|
||||
PUBLIC MYSEG1
|
||||
PUBLIC MYSEG2
|
||||
PUBLIC nest
|
||||
PUBLIC next_batch
|
||||
PUBLIC no_char
|
||||
PUBLIC NULLFLAG
|
||||
PUBLIC NUMBER_SUBST ;AN000;
|
||||
PUBLIC olderrno
|
||||
PUBLIC OldTerm
|
||||
PUBLIC OUTPIPEPTR
|
||||
PUBLIC PARENT
|
||||
;AD060; PUBLIC pars_msg_off ;AN000;
|
||||
;AD060; PUBLIC pars_msg_seg ;AN000;
|
||||
PUBLIC parse_msg_start ;AN000;
|
||||
PUBLIC PERMCOM
|
||||
PUBLIC PIPE1
|
||||
PUBLIC pipe1t
|
||||
PUBLIC PIPE2
|
||||
PUBLIC pipe2t
|
||||
PUBLIC PIPEFILES
|
||||
PUBLIC PIPEFLAG
|
||||
PUBLIC PIPEPTR
|
||||
PUBLIC PIPESTR
|
||||
PUBLIC RDIRCHAR
|
||||
PUBLIC RE_OUT_APP
|
||||
PUBLIC RE_OUTSTR
|
||||
PUBLIC RemMsg
|
||||
PUBLIC resmsgend ;AN000;
|
||||
PUBLIC RES_TPA
|
||||
PUBLIC RESTDIR
|
||||
PUBLIC ResTest
|
||||
PUBLIC RETCODE
|
||||
PUBLIC retry_char
|
||||
PUBLIC rsrc_xa_seg ;AN030;
|
||||
PUBLIC RSWITCHAR
|
||||
PUBLIC SAVE_PDB
|
||||
PUBLIC SINGLECOM
|
||||
PUBLIC SUM
|
||||
PUBLIC SUPPRESS
|
||||
PUBLIC TRANS
|
||||
PUBLIC TranVarEnd
|
||||
PUBLIC TRANVARS
|
||||
PUBLIC TRNSEG
|
||||
PUBLIC TrnMvFlg
|
||||
PUBLIC VERVAL
|
||||
PUBLIC VolName
|
||||
PUBLIC VOLSER ;AN000;
|
||||
PUBLIC yes_char
|
||||
|
||||
;AD054;MESBAS DW 19 ;AC000; error_write_protect
|
||||
;AD054; DW 20 ;AC000; error_bad_unit
|
||||
;AD054; DW 21 ;AC000; error_not_ready
|
||||
;AD054; DW 22 ;AC000; error_bad_command
|
||||
;AD054; DW 23 ;AC000; error_CRC
|
||||
;AD054; DW 24 ;AC000; error_bad_length
|
||||
;AD054; DW 25 ;AC000; error_Seek
|
||||
;AD054; DW 26 ;AC000; error_not_DOS_disk
|
||||
;AD054; DW 27 ;AC000; error_sector_not_found
|
||||
;AD054; DW 28 ;AC000; error_out_of_paper
|
||||
;AD054; DW 29 ;AC000; error_write_fault
|
||||
;AD054; DW 30 ;AC000; error_read_fault
|
||||
;AD054; DW 31 ;AC000; error_gen_failure
|
||||
;AD054; DW 32 ;AC000; error_sharing_violation
|
||||
;AD054; DW 33 ;AC000; error_lock_violation
|
||||
;AD054; DW 34 ;AC000; error_wrong_disk
|
||||
;AD054; DW 35 ;AC000; error_FCB_unavailable
|
||||
;AD054; DW 36 ;AC000; error_sharing_buffer_exceeded
|
||||
;AD054; DW 37 ;AC000; error_code_page_mismatch
|
||||
;AD054; DW 38 ;AC026; error_out_of_input
|
||||
;AD054; DW 39 ;AN026; error_insufficient_disk_space
|
||||
|
||||
|
||||
|
||||
IF Tokenized
|
||||
MESADD LABEL WORD
|
||||
DW OFFSET ResGroup:NEWLIN ;"0"
|
||||
DW OFFSET ResGroup:COM$1 ;"1"
|
||||
DW OFFSET ResGroup:ERR3 ;"2"
|
||||
DW OFFSET ResGroup:ALLOC$3 ;"3"
|
||||
DW OFFSET ResGroup:FILE$4 ;"4"
|
||||
DW OFFSET ResGroup:RROR$5 ;"5"
|
||||
DW OFFSET ResGroup:CAN$6 ;"6"
|
||||
DW OFFSET ResGroup:EMORY$7 ;"7"
|
||||
DW OFFSET ResGroup:BAT$8 ;"8"
|
||||
DW OFFSET ResGroup:INS$9 ;"9"
|
||||
|
||||
ERR0 DB "Write protec","t"+80h
|
||||
ERR1 DB "Bad uni","t"+80h
|
||||
ERR2 DB "Not read","y"+80h
|
||||
ERR3 DB "Bad command"," "+80h
|
||||
ERR4 DB "Dat","a"+80h
|
||||
ERR5 DB "Bad call forma","t"+80h
|
||||
ERR6 DB "See","k"+80h
|
||||
ERR7 DB "Non-DOS dis","k"+80h
|
||||
ERR8 DB "Sector not foun","d"+80h
|
||||
ERR9 DB "No pape","r"+80h
|
||||
ERR10 DB "Write faul","t"+80h
|
||||
ERR11 DB "Read faul","t"+80h
|
||||
ERR12 DB "General Failur","e"+80h
|
||||
ERR13 DB "Sharing Violatio","n"+80h
|
||||
ERR14 DB "Lock Violatio","n"+80h
|
||||
ERR15 DB "Invalid Disk Chang","e"+80h
|
||||
ERR16 DB "FCB unavailabl","e"+80h
|
||||
ERR17 DB "Sharing buffer exceede","d"+80h
|
||||
|
||||
;--- Extra message for error 15
|
||||
Err15Mes db "Please Insert disk "
|
||||
VolName db 11 dup(?)
|
||||
db 13,10,"$"
|
||||
|
||||
MREAD DB "read"
|
||||
MWRITE DB "writ"
|
||||
ERRMES DB " e5"
|
||||
IOTYP DB "writin","g"+80h
|
||||
DRVNUM DB " drive "
|
||||
DRVLET DB "A"
|
||||
NEWLIN DB 13,10+80h
|
||||
DEVEMES DB " device "
|
||||
DEVENAM DB 8 DUP (?)
|
||||
DB 13,10,"$" ;Must be $ terminated
|
||||
COM$1 DB " COMMAN","D"+80h
|
||||
ALLOC$3 DB " allocation"," "+80h
|
||||
FILE$4 DB " file"," "+80h
|
||||
RROR$5 DB "rror"," "+80h
|
||||
CAN$6 DB "Cannot"," "+80h
|
||||
EMORY$7 DB "emor","y"+80h
|
||||
BAT$8 DB " batc","h"+80h
|
||||
INS$9 DB "Inser","t"+80h
|
||||
|
||||
|
||||
CDEVAT DB ?
|
||||
BADFAT DB "0File 3table bad",","+80h
|
||||
COMBAD DB "0Invalid1.COM","0"+80h
|
||||
comprmt1 DB "9 disk with"," "+80h
|
||||
comprmt2 DB " in drive "
|
||||
cpdrv DB " "
|
||||
PROMPT DB "0and strike any key when ready","0"+80h
|
||||
ENDBATMES DB "0Terminate8 job (Y/N)?"," "+80h
|
||||
EXECEMES DB "EXEC failure","0"+80h
|
||||
EXEBAD DB "E5in EXE4","0"+80h
|
||||
TOOBIG DB "Program too big to fit in m7","0"+80h
|
||||
NOHANDMES DB "0No free4handle","s"+80h
|
||||
BMEMMES DB "0M73e","5"+80h
|
||||
HALTMES DB "06load1, system halte","d"+80h
|
||||
FRETMES DB "06start1, exiting","0"+80h
|
||||
RBADNAM DB "2or4name","0"+80h
|
||||
AccDen DB "Access Denied","0"+80h
|
||||
Patricide DB 13,10,"Top level process aborted, cannot continue."," "+80h
|
||||
COMSPEC_PRINT DW ?
|
||||
|
||||
ELSE
|
||||
|
||||
|
||||
parm_block_size EQU 11 ;AN000; size of message subst block
|
||||
blank EQU " " ;AN000; blank character
|
||||
|
||||
DISP_CLASS DB -1 ;AN000; utility message class
|
||||
NUMBER_SUBST DB 0 ;AN000; number of message substitutions - def 0
|
||||
|
||||
|
||||
DRVNUM_SUBST db 2 ;AN000; number of subst
|
||||
DRVNUM_BLOCK db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
DRVNUM_OP_OFF dw 0 ;AN000;offset of arg
|
||||
DRVNUM_OP_SEG dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Char_field_ASCIIZ ;AN000;character string
|
||||
db 128 ;AN000;maximum width
|
||||
db 0 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET RESGROUP:DRVLET ;AN000;offset of arg
|
||||
DRVNUM_OP_SEG2 dw 0 ;AN000;segment of arg
|
||||
db 2 ;AN000;second subst
|
||||
db Char_field_Char ;AN000;one character
|
||||
db 1 ;AN000;maximum width
|
||||
db 1 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
DRVLET DB "A"
|
||||
|
||||
DEVEMES_SUBST db 2 ;AN000; number of subst
|
||||
DEVEMES_BLOCK db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
DEVE_OP_OFF dw 0 ;AN000;offset of arg
|
||||
DEVE_OP_SEG dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Char_field_ASCIIZ ;AN000;character string
|
||||
db 128 ;AN000;maximum width
|
||||
db 0 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET RESGROUP:DEVENAM ;AN000;offset of arg
|
||||
DEVE_OP_SEG2 dw 0 ;AN000;segment of arg
|
||||
db 2 ;AN000;second subst
|
||||
db Char_field_ASCIIZ ;AN000;character string
|
||||
db 8 ;AN019;maximum width
|
||||
db 8 ;AN019;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
DEVENAM DB 8 DUP (?)
|
||||
|
||||
;--- Extra message for error 15
|
||||
ERR15MES_SUBST db 3 ;AN000; number of subst
|
||||
ERR15MES_BLOCK db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET RESGROUP:VOLNAME ;AN000;offset of arg
|
||||
ERR15_OP_SEG dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Char_field_ASCIIZ ;AN000;character string
|
||||
db 12 ;AN000;maximum width
|
||||
db 12 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET RESGROUP:VOLSER+2;AN000;offset of arg
|
||||
ERR15_OP_SEG2 dw 0 ;AN000;segment of arg
|
||||
db 2 ;AN000;second subst
|
||||
db right_align+Bin_Hex_Word ;AN000;long binary to decimal
|
||||
db 4 ;AN000;maximum width
|
||||
db 4 ;AN000;minimum width
|
||||
db "0" ;AN000;pad character
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET RESGROUP:VOLSER ;AN000;offset of arg
|
||||
ERR15_OP_SEG3 dw 0 ;AN000;segment of arg
|
||||
db 3 ;AN000;third subst
|
||||
db right_align+Bin_Hex_Word ;AN000;long binary to decimal
|
||||
db 4 ;AN000;maximum width
|
||||
db 4 ;AN000;minimum width
|
||||
db "0" ;AN000;pad character
|
||||
|
||||
;************************************
|
||||
;* DO NOT SEPARATE VOLNAME & VOLSER *
|
||||
;************************************
|
||||
;*
|
||||
VolName DB 11 dup(?) ;*
|
||||
DB 0 ;*
|
||||
VolSer DD 0 ;*
|
||||
;*
|
||||
;************************************
|
||||
|
||||
|
||||
CDEVAT DB ?
|
||||
|
||||
BADFAT_SUBST db 1 ;AN000; number of subst
|
||||
BADFAT_BLOCK db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET RESGROUP:DRVLET ;AN000;offset of arg
|
||||
BADFAT_OP_SEG dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Char_field_Char ;AN000;one character
|
||||
db 1 ;AN000;maximum width
|
||||
db 1 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
|
||||
COMPRMT1_SUBST db 2 ;AN000; number of subst
|
||||
COMPRMT1_BLOCK db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
COMSPEC_PRINT dw ? ;AN000;offset of arg
|
||||
COMPRMT1_SEG dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Char_field_ASCIIZ ;AN000;character string
|
||||
db 64 ;AN000;maximum width
|
||||
db 0 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET RESGROUP:CPDRV ;AN000;offset of arg
|
||||
COMPRMT1_SEG2 dw 0 ;AN000;segment of arg
|
||||
db 2 ;AN000;second subst
|
||||
db Char_field_Char ;AN000;one character
|
||||
db 1 ;AN000;maximum width
|
||||
db 1 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
cpdrv DB " "
|
||||
;
|
||||
; Exec error messages
|
||||
;
|
||||
EXECEMES_SUBST db 1 ;AN000; number of subst
|
||||
EXECEMES_BLOCK db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
EXECEMES_OFF dw 0 ;AN000;offset of arg
|
||||
EXECEMES_SEG dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Char_field_ASCIIZ ;AN000;character string
|
||||
db 64 ;AN000;maximum width
|
||||
db 0 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
;
|
||||
; These characters MUST remain in order
|
||||
;
|
||||
abort_char db "A"
|
||||
retry_char db "R"
|
||||
ignore_char db "I"
|
||||
fail_char db "F"
|
||||
yes_char db "Y"
|
||||
no_char db "N"
|
||||
;
|
||||
; End of characters that MUST remain in order
|
||||
;
|
||||
ENDIF
|
||||
|
||||
RemMsg DD ? ;Pointer to message in error 15
|
||||
ErrType DB ? ; Error message style, 0=old, 1=new
|
||||
|
||||
INT_2E_RET DD ? ; Magic command executer return address
|
||||
SAVE_PDB DW ?
|
||||
PARENT DW ?
|
||||
OldTerm DD ?
|
||||
ERRCD_24 DW ?
|
||||
HANDLE01 DW ?
|
||||
LOADING DB 0
|
||||
BATCH DW 0 ; Assume no batch mode initially
|
||||
COMSPEC DB 64 DUP(0)
|
||||
comspec_end dw ?
|
||||
TRANS DW OFFSET TRANGROUP:COMMAND
|
||||
TRNSEG DW ?
|
||||
; BAS DEBUG
|
||||
TrnMvFlg DB 0 ; Indicate if transient portion has been moved
|
||||
|
||||
In_Batch DB 0 ; Indicate if we are in Batch processing mode.
|
||||
Batch_Abort DB 0 ; Indicate if user wants to abort from batch mode.
|
||||
|
||||
COMDRV DB ? ; DRIVE SPEC TO LOAD AUTOEXEC AND COMMAND
|
||||
MEMSIZ DW ?
|
||||
SUM DW ?
|
||||
EXTCOM DB 1 ; For init, pretend just did an external
|
||||
RETCODE DW ?
|
||||
CRIT_ERR_INFO DB ? ;G hold critical error flags for R,I,F
|
||||
rsrc_xa_seg DW -1 ;AN030; holds segment of xa copy buffer
|
||||
|
||||
;
|
||||
; The echo flag needs to be pushed and popped around pipes and batch files.
|
||||
; We implement this as a bit queue that is shr/shl for push and pop.
|
||||
;
|
||||
ECHOFLAG DB 00000001B ; low bit TRUE => echo commands
|
||||
SUPPRESS DB 1 ; used for echo, 1=echo line
|
||||
IO_SAVE DW ?
|
||||
RESTDIR DB 0
|
||||
PERMCOM DB 0 ; TRUE => permanent command
|
||||
SINGLECOM DW 0 ; TRUE => single command version
|
||||
VERVAL DW -1
|
||||
fFail DB 0 ; TRUE => FAIL all INT 24s
|
||||
IFFLAG DB 0 ; TRUE => If statement in progress
|
||||
|
||||
FORFLAG DB 0 ; TRUE => FOR statement in progress
|
||||
FORPTR DW 0
|
||||
|
||||
NEST DW 0 ; NESTED BATCH FILE COUNTER
|
||||
CALL_FLAG DB 0 ; NO CALL (BATCH COMMAND) IN PROGRESS
|
||||
CALL_BATCH_FLAG DB 0
|
||||
NEXT_BATCH DW 0 ; ADDRESS OF NEXT BATCH SEGMENT
|
||||
NULLFLAG DB 0 ; FLAG IF NO COMMAND ON COMMAND LINE
|
||||
COM_XLAT_ADDR DB 5 DUP (0) ;G BUFFER FOR TRANSLATE TABLE ADDRESS
|
||||
FUCASE_ADDR DB 5 DUP (0) ;AN000; BUFFER FOR FILE UCASE ADDRESS
|
||||
CRIT_MSG_OFF DW 0 ;AN000; SAVED CRITICAL ERROR MESSAGE OFFSET
|
||||
CRIT_MSG_SEG DW 0 ;AN000; SAVED CRITICAL ERROR MESSAGE SEGMENT
|
||||
;AD060; PARS_MSG_OFF DW 0 ;AN000; SAVED PARSE ERROR MESSAGE OFFSET
|
||||
;AD060; PARS_MSG_SEG DW 0 ;AN000; SAVED PARSE ERROR MESSAGE SEGMENT
|
||||
Dbcs_vector_addr DW 0 ;AN000; DBCS vector offset
|
||||
DW 0 ;AN000; DBCS vector segment
|
||||
APPEND_STATE DW 0 ;AN020; current state of append (if flag = -1)
|
||||
APPEND_FLAG DB 0 ;AN020; set if APPEND state valid
|
||||
|
||||
RE_OUT_APP DB 0
|
||||
RE_OUTSTR DB 64+3+13 DUP (?)
|
||||
|
||||
;
|
||||
; We flag the state of COMMAND in order to correctly handle the ^Cs at
|
||||
; various times. Here is the breakdown:
|
||||
;
|
||||
; initINIT We are in the init code.
|
||||
; initSpecial We are in the date/time prompt
|
||||
; initCtrlC We are handling a ^C already.
|
||||
;
|
||||
; If we get a ^C in the initialization but not in the date/time prompt, we
|
||||
; ignore the ^C. This is so the system calls work on nested commands.
|
||||
;
|
||||
; If we are in the date/time prompt at initialization, we stuff the user's
|
||||
; input buffer with a CR to pretend an empty response.
|
||||
;
|
||||
; If we are already handling a ^C, we set the carry bit and return to the user
|
||||
; (ourselves). We can then detect the carry set and properly retry the
|
||||
; operation.
|
||||
;
|
||||
|
||||
InitFlag DB initINIT
|
||||
|
||||
;These two bytes refed as a word
|
||||
PIPEFLAG DB 0
|
||||
PIPEFILES DB 0
|
||||
|
||||
;--- 2.x data for piping
|
||||
;
|
||||
; All the "_" are substituted later, the one before the : is substituted
|
||||
; by the current drive, and the others by the CreateTemp call with the
|
||||
; unique file name. Note that the first 0 is the first char of the pipe
|
||||
; name. -MU
|
||||
;
|
||||
;--- Order dependant, do not change
|
||||
|
||||
Pipe1 db "_:/"
|
||||
Pipe1T db 0
|
||||
db "_______.___",0
|
||||
Pipe2 db "_:/"
|
||||
Pipe2T db 0
|
||||
db "_______.___",0
|
||||
|
||||
PIPEPTR DW ?
|
||||
PIPESTR DB 129 DUP(?)
|
||||
INPIPEPTR DW OFFSET ResGroup:PIPE1
|
||||
OUTPIPEPTR DW OFFSET ResGroup:PIPE2
|
||||
|
||||
EXEC_BLOCK LABEL BYTE ; The data block for EXEC calls
|
||||
ENVIRSEG DW ?
|
||||
COM_PTR LABEL DWORD
|
||||
DW 80H ; Point at unformatted parameters
|
||||
DW ?
|
||||
COM_FCB1 LABEL DWORD
|
||||
DW 5CH
|
||||
DW ?
|
||||
COM_FCB2 LABEL DWORD
|
||||
DW 6CH
|
||||
DW ?
|
||||
|
||||
TRANVARS LABEL BYTE ; Variables passed to transient
|
||||
DW OFFSET ResGroup:THEADFIX
|
||||
MYSEG DW 0 ; Put our own segment here
|
||||
LTPA DW 0 ; WILL STORE TPA SEGMENT HERE
|
||||
RSWITCHAR DB "-"
|
||||
RDIRCHAR DB "/"
|
||||
DW OFFSET ResGroup:EXT_EXEC
|
||||
MYSEG1 DW ?
|
||||
DW OFFSET ResGroup:TREMCHECK
|
||||
MYSEG2 DW 0
|
||||
ResTest DW 0
|
||||
RES_TPA DW 0 ; Original TPA (not rounded to 64K)
|
||||
TranVarEnd LABEL BYTE
|
||||
|
||||
olderrno dw ?
|
||||
|
||||
RESMSGEND DW 0 ;AN000;; holds offset of msg end (end of resident)
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
|
||||
INCLUDE SYSMSG.INC ;AN000; include message services
|
||||
|
||||
.list
|
||||
.cref
|
||||
|
||||
ASSUME DS:RESGROUP,ES:RESGROUP,CS:RESGROUP
|
||||
|
||||
MSG_UTILNAME <COMMAND> ;AN000; define utility name
|
||||
|
||||
;AD054; MSG_SERVICES <COMR,MSGDATA,COMMAND.CLA,COMMAND.CL3,COMMAND.CL4> ;AN000; get message services data and resident messages
|
||||
MSG_SERVICES <COMR,MSGDATA,COMMAND.CLA> ;AN054; get message services data and resident messages
|
||||
|
||||
|
||||
CRITICAL_MSG_START LABEL BYTE ;AN000; start of critical error messages
|
||||
|
||||
MSG_SERVICES <COMR,COMMAND.CLD> ;AN000; get critical error messages
|
||||
|
||||
DATARESEND LABEL BYTE ;AC060; end of resident portion if /msg not used
|
||||
|
||||
PARSE_MSG_START LABEL BYTE ;AN000; start of parse error messages
|
||||
|
||||
MSG_SERVICES <COMR,COMMAND.CLC> ;AN000; get parse error messages
|
||||
|
||||
;AD060; DATARESEND LABEL BYTE ; end of resident portion if /msg not used
|
||||
|
||||
EXTENDED_MSG_START LABEL BYTE ;AN000; start of extended error messages
|
||||
|
||||
MSG_SERVICES <COMR,COMMAND.CLE> ;AN000; get extended error messages
|
||||
|
||||
EXTMSGEND LABEL BYTE ;AN000; end of extended error messages
|
||||
|
||||
include msgdcl.inc
|
||||
|
||||
DATARES ENDS
|
||||
END
|
||||
43
v4.0/src/CMD/COMMAND/RESMSG.EQU
Normal file
43
v4.0/src/CMD/COMMAND/RESMSG.EQU
Normal file
@@ -0,0 +1,43 @@
|
||||
; SCCSID = @(#)resmsg.equ 4.1 85/09/10
|
||||
; SCCSID = @(#)resmsg.equ 4.1 85/09/10
|
||||
|
||||
;****************************
|
||||
;* RESIDENT MESSAGE EQUATES *
|
||||
;****************************
|
||||
|
||||
REQ_ABORT EQU 210 ;AC000; "Abort"
|
||||
REQ_RETRY EQU 211 ;AC000; ", Retry"
|
||||
REQ_IGNORE EQU 212 ;AC000; ", Ignore"
|
||||
REQ_FAIL EQU 213 ;AC000; ", Fail"
|
||||
REQ_END EQU 214 ;AC000; "? "
|
||||
MREAD EQU 215 ;AC000; "reading"
|
||||
MWRITE EQU 216 ;AC000; "writing"
|
||||
DRVNUM EQU 217 ;AC000; "%1 drive %2"
|
||||
DEVEMES EQU 218 ;AC000; "%1 device %2"
|
||||
Err15Mes EQU 219 ;AC000; "Please insert volume %1 serial %2"
|
||||
BADFAT EQU 220 ;AC000; "File allocation table bad, drive %1"
|
||||
COMBAD EQU 221 ;AC000; 13,10,"Invalid COMMAND.COM",13,10"
|
||||
comprmt1 EQU 222 ;AC000; "Insert disk with %1 in drive %1"
|
||||
PROMPT EQU 223 ;AC000; "Press any key to continue"
|
||||
ENDBATMES EQU 224 ;AC000; 13,10,"Terminate batch job (Y/N)? "
|
||||
EXECEMES EQU 225 ;AC000; "Cannot execute %1",13,10
|
||||
EXEBAD EQU 226 ;AC000; "Error in EXE file",13,10
|
||||
TOOBIG EQU 227 ;AC000; "Program too big to fit in memory",13,10
|
||||
NOHANDMES EQU 228 ;AC000; 13,10,"No free file handles"
|
||||
RBADNAM EQU 229 ;AC000; "Bad Command or file name",13,10
|
||||
AccDen EQU 230 ;AC000; Extended error - "Access denied",13,10
|
||||
BMEMMES EQU 231 ;AC000; 13,10,"Memory allocation error "
|
||||
HALTMES EQU 232 ;AC000; 13,10,"Cannot load COMMAND, system halted"
|
||||
FRETMES EQU 233 ;AC000; 13,10,"Cannot start COMMAND, exiting",13,10
|
||||
Patricide EQU 234 ;AC000; 13,10,"Top level process aborted, cannot continue."
|
||||
NEWLIN EQU 235 ;AC000; 13,10
|
||||
|
||||
;************************
|
||||
;* INIT MESSAGE EQUATES *
|
||||
;************************
|
||||
|
||||
BADVER EQU 461 ;AC000; "Incorrect DOS version",13,10,"$"
|
||||
OUTENVERR_PTR EQU 463 ;AC000; "Out of environment space",13,10,0
|
||||
HEADER_PTR EQU 464 ;AC000; Long Copyright Notice
|
||||
BADCOMLKMES_PTR EQU 465 ;AC000;"Specified COMMAND search directory bad",13,10,0
|
||||
BADCOMACCMES_PTR EQU 466 ;AC000; "Specified COMMAND search directory bad access denied",13,10,0
|
||||
739
v4.0/src/CMD/COMMAND/RUCODE.ASM
Normal file
739
v4.0/src/CMD/COMMAND/RUCODE.ASM
Normal file
@@ -0,0 +1,739 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)rucode.asm 4.5 85/07/22
|
||||
; SCCSID = @(#)rucode.asm 4.5 85/07/22
|
||||
TITLE COMMAND Language modifiable Code Resident
|
||||
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE DOSSYM.INC ;AC000;
|
||||
include doscntry.inc ;AC000;
|
||||
DEBUG = 0 ; NEED TO SET IT TO WHAT IT IS IN DOSSYM.INC
|
||||
|
||||
|
||||
INCLUDE DEVSYM.INC
|
||||
INCLUDE comsw.asm
|
||||
INCLUDE comseg.asm
|
||||
INCLUDE comequ.asm
|
||||
include resmsg.equ ;AN000;
|
||||
.list
|
||||
.cref
|
||||
|
||||
|
||||
Tokenized = FALSE
|
||||
|
||||
DATARES SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN abort_char:byte
|
||||
EXTRN badfat_block:byte ;AC000;
|
||||
EXTRN badfat_subst:byte ;AC000;
|
||||
EXTRN Batch_Abort:byte
|
||||
EXTRN CDEVAT:BYTE
|
||||
EXTRN COMSPEC:BYTE ;AN060;
|
||||
EXTRN com_xlat_addr:word
|
||||
EXTRN crit_err_info:byte
|
||||
EXTRN crit_msg_off:word ;AC000;
|
||||
EXTRN crit_msg_seg:word ;AC000;
|
||||
EXTRN dbcs_vector_addr:dword ;AN000;
|
||||
EXTRN devemes_block:byte ;AC000;
|
||||
EXTRN devemes_subst:byte ;AC000;
|
||||
EXTRN DEVENAM:BYTE
|
||||
EXTRN deve_op_off:word ;AC000;
|
||||
EXTRN disp_class:byte ;AC000;
|
||||
EXTRN DRVLET:BYTE
|
||||
EXTRN drvnum_block:byte ;AC000;
|
||||
EXTRN drvnum_op_off:word ;AC000;
|
||||
EXTRN drvnum_subst:byte ;AC000;
|
||||
EXTRN err15mes_block:byte ;AC000;
|
||||
EXTRN err15mes_subst:byte ;AC000;
|
||||
EXTRN ERRCD_24:WORD
|
||||
EXTRN ErrType:BYTE
|
||||
EXTRN fail_char:byte
|
||||
EXTRN fFail:BYTE
|
||||
EXTRN FORFLAG:BYTE
|
||||
EXTRN ignore_char:byte
|
||||
EXTRN InitFlag:BYTE
|
||||
EXTRN In_Batch:byte
|
||||
EXTRN LOADING:BYTE
|
||||
;AD054; EXTRN MESBAS:BYTE
|
||||
EXTRN no_char:byte
|
||||
EXTRN number_subst:byte ;AC000;
|
||||
EXTRN olderrno:word
|
||||
EXTRN PARENT:WORD
|
||||
;AD060; EXTRN pars_msg_off:word ;AC000;
|
||||
;AD060; EXTRN pars_msg_seg:word ;AC000;
|
||||
EXTRN PERMCOM:BYTE
|
||||
EXTRN RemMsg:DWORD
|
||||
EXTRN retry_char:byte
|
||||
EXTRN PIPEFLAG:BYTE
|
||||
EXTRN SINGLECOM:WORD
|
||||
EXTRN VolName:BYTE
|
||||
EXTRN yes_char:byte
|
||||
|
||||
IF Tokenized
|
||||
EXTRN IOTYP:BYTE
|
||||
EXTRN MESADD:BYTE
|
||||
ENDIF
|
||||
|
||||
DATARES ENDS
|
||||
|
||||
|
||||
CODERES SEGMENT PUBLIC BYTE
|
||||
|
||||
EXTRN GETCOMDSK2:NEAR
|
||||
|
||||
PUBLIC ASKEND
|
||||
PUBLIC CRLF
|
||||
PUBLIC DSKERR
|
||||
PUBLIC ITESTKANJ ;AN000;
|
||||
PUBLIC RESET_MSG_POINTERS ;AC000;
|
||||
PUBLIC RPRINT
|
||||
|
||||
ASSUME CS:RESGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
|
||||
;
|
||||
; AskEnd - prompt the user to see if he should terminate the batch file. If
|
||||
; any system call returns with carry set or if RPRINT returns with carry set,
|
||||
; we jump to the top and start over.
|
||||
;
|
||||
; Returns: carry set if response indicates that the batch file should
|
||||
; be terminated.
|
||||
; carry clear otherwise.
|
||||
;
|
||||
|
||||
ASSUME DS:RESGROUP
|
||||
ASKEND:
|
||||
MOV DX,ENDBATMES ;AC000; get batch terminate question
|
||||
CALL RPRINT
|
||||
MOV AX,(STD_CON_INPUT_FLUSH SHL 8)+STD_CON_INPUT
|
||||
INT 21H
|
||||
call in_char_xlat ;g change to upper case
|
||||
CMP AL,no_char
|
||||
retz ; carry is clear => no free
|
||||
CMP AL,yes_char
|
||||
JNZ ASKEND
|
||||
stc ; carry set => free batch
|
||||
return
|
||||
|
||||
DSKERR:
|
||||
ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
; ******************************************************
|
||||
; THIS IS THE DEFAULT DISK ERROR HANDLING CODE
|
||||
; AVAILABLE TO ALL USERS IF THEY DO NOT TRY TO
|
||||
; INTERCEPT INTERRUPT 24H.
|
||||
; ******************************************************
|
||||
STI
|
||||
PUSH DS
|
||||
PUSH ES
|
||||
PUSH SI ;AN000; save si
|
||||
PUSH CX
|
||||
PUSH DI
|
||||
PUSH CX
|
||||
PUSH AX
|
||||
MOV DS,BP
|
||||
MOV AX,[SI.SDEVATT]
|
||||
MOV [CDEVAT],AH
|
||||
PUSH CS
|
||||
POP ES
|
||||
MOV DI,OFFSET RESGROUP:DEVENAM
|
||||
MOV CX,8
|
||||
ADD SI,SDEVNAME ; Suck up device name (even on Block)
|
||||
REP MOVSB
|
||||
POP AX
|
||||
POP CX
|
||||
POP DI ; Stack just contains DS and ES
|
||||
; at this point
|
||||
INVOKE SAVHAND
|
||||
PUSH CS
|
||||
POP DS ; Set up local data segment
|
||||
ASSUME DS:RESGROUP
|
||||
|
||||
PUSH DX
|
||||
CALL CRLF
|
||||
POP DX
|
||||
MOV CRIT_ERR_INFO,AH ;G save so we know if R,I,F are valid
|
||||
|
||||
ADD AL,'A' ; Compute drive letter (even on character)
|
||||
MOV [DRVLET],AL
|
||||
TEST AH,80H ; Check if hard disk error
|
||||
JZ NOHARDE
|
||||
TEST [CDEVAT],DEVTYP SHR 8
|
||||
JNZ NOHARDE
|
||||
JMP FATERR
|
||||
|
||||
NOHARDE:
|
||||
MOV SI,MREAD ;AC000;
|
||||
TEST AH,1
|
||||
JZ SAVMES
|
||||
MOV SI,MWRITE ;AC000;
|
||||
|
||||
SAVMES:
|
||||
IF Tokenized
|
||||
LODSW
|
||||
MOV WORD PTR [IOTYP],AX
|
||||
LODSW
|
||||
MOV WORD PTR [IOTYP+2],AX
|
||||
ENDIF
|
||||
|
||||
mov olderrno,di ; keep code in a safe place
|
||||
PUSH ES ;AN000;
|
||||
PUSH DS ; GetExtendedError likes to STOMP
|
||||
PUSH BP
|
||||
PUSH SI
|
||||
PUSH DX
|
||||
PUSH CX
|
||||
PUSH BX
|
||||
mov ah,GetExtendedError ; get extended error code
|
||||
INT 21H
|
||||
POP BX
|
||||
POP CX
|
||||
POP DX
|
||||
POP SI
|
||||
POP BP
|
||||
POP DS
|
||||
mov word ptr cs:[RemMsg],di ;AC000; save pointer to remote message
|
||||
mov word ptr cs:[RemMsg+2],es ;AC000; (only used on code 15)
|
||||
pop ES ;AN000;
|
||||
XOR AH,AH
|
||||
mov di,ax ; REAL error code to DI
|
||||
;
|
||||
; DI is now the correct error code. Classify things to see what we are
|
||||
; allowed to report. We convert DI into a 0-based index into a message table.
|
||||
; This presumes that the int 24 errors (oldstyle) and new errors (sharing and
|
||||
; the like) are contiguous.
|
||||
;
|
||||
SUB DI,error_write_protect
|
||||
JAE HavCod
|
||||
MOV DI,error_Gen_failure-error_write_protect
|
||||
;
|
||||
; DI now has the mapped error code. Old style errors are:
|
||||
; FOOBAR <read|writ>ing drive ZZ.
|
||||
; New style errors are:
|
||||
; FOOBAR
|
||||
; We need to figure out which the particular error belongs to.
|
||||
;
|
||||
|
||||
HAVCOD:
|
||||
mov ErrType,0 ; assume Old style
|
||||
cmp di,error_FCB_Unavailable-error_write_protect
|
||||
jz SetStyle
|
||||
cmp di,error_sharing_buffer_exceeded-error_write_protect
|
||||
jnz GotStyle
|
||||
|
||||
SetStyle:
|
||||
mov ErrType,1 ; must be new type
|
||||
|
||||
GotStyle:
|
||||
MOV [ERRCD_24],DI
|
||||
cmp di,error_handle_disk_full-error_write_protect ;AC026;
|
||||
; If the error message is unknown
|
||||
jbe NormalError ; redirector, continue. Otherwise,
|
||||
;
|
||||
; We do not know how to handle this error. Ask IFSFUNC if she knows
|
||||
; how to handle things
|
||||
;
|
||||
|
||||
;input to IFSFUNC: AL=1
|
||||
; BX=extended error number
|
||||
|
||||
;output from IFSFUNC: AL=error type (0 or 1)
|
||||
; 0=<message> error (read/writ)ing (drive/device) xxx
|
||||
; Abort, Retry, Ignore
|
||||
; 1=<message>
|
||||
; Abort, Retry, Ignore
|
||||
; ES:DI=pointer to message text
|
||||
; carry set=>no message
|
||||
|
||||
MOV DI,AX ; retrieve correct extended error...
|
||||
mov ax,0500h ; Is the redir there?
|
||||
int 2fh
|
||||
cmp al,0ffh
|
||||
jnz NoHandler ; No, go to NoHandler
|
||||
push bx ;AN063;
|
||||
mov bx,di ; Get ErrType and ptr to error msg ;AC063;
|
||||
mov ax,0501h ;AC063;
|
||||
int 2fh
|
||||
pop bx ;AC063;
|
||||
jc NoHandler
|
||||
|
||||
mov ErrType,al
|
||||
push ds
|
||||
push es
|
||||
pop ds
|
||||
mov dx,di
|
||||
mov cx,-1 ; Find the end of the error msg and turn
|
||||
xor al,al ; the high byte on for rprint
|
||||
repnz scasb
|
||||
|
||||
IF Tokenized
|
||||
or byte ptr [di-2],80h
|
||||
call rprint ; Print the message
|
||||
and byte ptr [di-2], NOT 80h ; Restore msg to original condition
|
||||
ELSE
|
||||
mov byte ptr [di-1],'$'
|
||||
MOV AH,Std_con_string_output ;AC000; Print the message
|
||||
INT 21h ;AN000;
|
||||
mov byte ptr [di-1],0 ; Restore msg to original condition
|
||||
ENDIF
|
||||
|
||||
pop ds ; Clean up and continue processing
|
||||
jmp short CheckErrType
|
||||
|
||||
NoHandler: ; Redir isn't available or doesn't
|
||||
mov ErrType,0 ; recognize the error. Reset vars and
|
||||
mov di,olderrno ; regs to unextended err and continue
|
||||
mov ERRCD_24,di ; normally.
|
||||
|
||||
NormalError:
|
||||
;AD054; SHL DI,1
|
||||
;AD054; MOV DI,WORD PTR [DI+MESBAS] ; Get pointer to error message
|
||||
add DI,error_write_protect ;AN054;
|
||||
XCHG DI,DX ; May need DX later
|
||||
MOV DISP_CLASS,EXT_CRLF_CLASS ;AN054; printing extended error class
|
||||
CALL RPRINT ; Print error type
|
||||
|
||||
CheckErrType:
|
||||
cmp ErrType,0 ; Check error style...
|
||||
je ContOld
|
||||
call CRLF ; if new style then done printing
|
||||
jmp short ASK
|
||||
|
||||
ContOld:
|
||||
IF NOT Tokenized
|
||||
MOV AX,SI ;AN000; get reading/writing for message
|
||||
MOV DH,UTIL_MSG_CLASS ;AN000; this is a utility message
|
||||
CALL SYSGETMSG ;AN000; get the message
|
||||
ENDIF
|
||||
|
||||
TEST [CDEVAT],DEVTYP SHR 8
|
||||
JZ BLKERR
|
||||
MOV DX,DEVEMES ;AC000; get message number for device message
|
||||
MOV DEVE_OP_OFF,SI ;AN000; put address of read/write in subst block
|
||||
MOV AL,DEVEMES_SUBST ;AN000; get number of substitutions
|
||||
MOV NUMBER_SUBST,AL ;AN000;
|
||||
MOV SI,OFFSET RESGROUP:DEVEMES_BLOCK;AN000; get address of subst block
|
||||
|
||||
CALL RPRINT ;AC000; print the message
|
||||
JMP SHORT ASK ; Don't ralph on COMMAND
|
||||
|
||||
BLKERR:
|
||||
MOV DX,DRVNUM ;AN000; get drive message number
|
||||
MOV DRVNUM_OP_OFF,SI ;AN000; put address of read/write in subst block
|
||||
MOV AL,DRVNUM_SUBST ;AN000; get number of substitutions
|
||||
MOV NUMBER_SUBST,AL ;AN000;
|
||||
MOV SI,OFFSET RESGROUP:DRVNUM_BLOCK ;AN000; get address of subst block
|
||||
CALL RPRINT
|
||||
CMP [LOADING],0
|
||||
JZ ASK
|
||||
INVOKE RESTHAND
|
||||
JMP GETCOMDSK2 ; If error loading COMMAND, re-prompt
|
||||
|
||||
ASK:
|
||||
cmp [ERRCD_24],15 ; Wait! Error 15 has an extra message
|
||||
jne Not15
|
||||
PUSH CX
|
||||
push ds
|
||||
pop es
|
||||
lds si,[RemMsg]
|
||||
assume ds:nothing
|
||||
push di
|
||||
mov di,offset resgroup:VolName
|
||||
mov cx,16 ;AC000; extra message volume name & serial number
|
||||
cld ; just in case!
|
||||
rep movsb
|
||||
pop di
|
||||
push es
|
||||
pop ds
|
||||
POP CX
|
||||
assume ds:resgroup
|
||||
mov dx,Err15Mes ;AC000; get message number
|
||||
MOV AL,ERR15MES_SUBST ;AN000; get number of substitutions
|
||||
MOV NUMBER_SUBST,AL ;AN000;
|
||||
MOV SI,OFFSET RESGROUP:ERR15MES_BLOCK ;AN000; get address of subst block
|
||||
CALL RPRINT
|
||||
|
||||
; PRINT OUT ABORT, RETRY, IGNORE, FAIL MESSAGE. ONLY PRINT OUT OPTIONS
|
||||
; THAT ARE VALID
|
||||
|
||||
Not15:
|
||||
MOV DX,REQ_ABORT ;AC000;G print out abort message
|
||||
CALL RPRINT ;G
|
||||
TEST CRIT_ERR_INFO,RETRY_ALLOWED ;G is retry allowed?
|
||||
JZ TRY_IGNORE ;G
|
||||
MOV DX,REQ_RETRY ;AC000;G yes,print out retry message
|
||||
CALL RPRINT ;G
|
||||
|
||||
try_ignore:
|
||||
TEST CRIT_ERR_INFO,IGNORE_ALLOWED ;G is ignore allowed?
|
||||
JZ TRY_FAIL ;G
|
||||
MOV DX,REQ_IGNORE ;AC000;G yes,print out ignore message
|
||||
CALL RPRINT ;G
|
||||
|
||||
try_fail:
|
||||
TEST CRIT_ERR_INFO,FAIL_ALLOWED ;G is FAIL allowed?
|
||||
JZ TERM_QUESTION ;G
|
||||
MOV DX,REQ_FAIL ;AC000;G yes,print out FAIL message
|
||||
CALL RPRINT ;G
|
||||
|
||||
Term_Question:
|
||||
MOV DX,REQ_END ;AC000;G terminate the string
|
||||
CALL RPRINT ;G
|
||||
;
|
||||
; If the /f switch was given, we fail all requests...
|
||||
;
|
||||
TEST fFail,-1
|
||||
JZ DoPrompt
|
||||
MOV AH,3 ; signal fail
|
||||
JMP EExit
|
||||
|
||||
DoPrompt:
|
||||
MOV AX,(STD_CON_INPUT_FLUSH SHL 8)+STD_CON_INPUT
|
||||
INT 21H ; Get response
|
||||
|
||||
invoke TestKanjR ;AN000; 3/3/KK
|
||||
jz notkanj ;AN000; 3/3/KK
|
||||
MOV AX,(STD_CON_INPUT SHL 8) ;AN000; eat the 2nd byte of ECS code 3/3/KK
|
||||
INT 21H ;AN000; 3/3/KK
|
||||
CALL CRLF ;AN000; 3/3/KK
|
||||
JMP ASK ;AN000; 3/3/KK
|
||||
|
||||
notkanj: ;AN000; 3/3/KK
|
||||
CALL CRLF
|
||||
CALL IN_CHAR_XLAT ;G Convert to upper case
|
||||
MOV AH,0 ; Return code for ignore
|
||||
TEST CRIT_ERR_INFO,IGNORE_ALLOWED ;G is IGNORE allowed?
|
||||
JZ USER_RETRY ;G
|
||||
CMP AL,ignore_char ; Ignore?
|
||||
JZ EEXITJ
|
||||
|
||||
USER_RETRY:
|
||||
INC AH ; return code for retry
|
||||
TEST CRIT_ERR_INFO,RETRY_ALLOWED ;G is RETRY allowed?
|
||||
JZ USER_ABORT ;G
|
||||
CMP AL,retry_char ; Retry?
|
||||
JZ EEXITJ
|
||||
|
||||
USER_ABORT:
|
||||
INC AH ; return code for abort - always allowed
|
||||
CMP AL,abort_char ; Abort?
|
||||
JZ abort_process ;G exit user program
|
||||
INC AH ;G return code for fail
|
||||
TEST CRIT_ERR_INFO,FAIL_ALLOWED ;G is FAIL allowed?
|
||||
JZ ASKJ ;G
|
||||
CMP AL,fail_char ;G fail?
|
||||
JZ EEXITJ ;G
|
||||
|
||||
ASKJ:
|
||||
JMP ASK ;G
|
||||
|
||||
EEXITJ:
|
||||
JMP SHORT EEXIT ;G
|
||||
|
||||
abort_process:
|
||||
test InitFlag,initINIT ; Was command initialization interrupted
|
||||
jz AbortCont ; No, handle it normally
|
||||
cmp PERMCOM,0 ; Is this the top level process?
|
||||
jz JustExit ; Yes, just exit
|
||||
mov dx,Patricide ;AC000; No, load ptr to error msg
|
||||
call RPRINT ; Print it
|
||||
|
||||
DeadInTheWater:
|
||||
jmp DeadInTheWater ; Loop until the user reboots
|
||||
|
||||
JustExit:
|
||||
ASSUME DS:RESGROUP
|
||||
call reset_msg_pointers ;AN000; reset critical & parse message addresses
|
||||
mov ax,[PARENT] ; Load real parent PID
|
||||
mov word ptr ds:[PDB_Parent_PID],ax ; Put it back where it belongs
|
||||
mov ax,(Exit SHL 8) OR 255
|
||||
int 21H
|
||||
|
||||
AbortCont:
|
||||
test byte ptr [In_Batch],-1 ; Are we accessing a batch file?
|
||||
jz Not_Batch_Abort
|
||||
mov byte ptr [Batch_Abort],1 ; set flag for abort
|
||||
|
||||
Not_Batch_Abort:
|
||||
mov dl,PipeFlag
|
||||
invoke ResPipeOff
|
||||
OR DL,DL
|
||||
JZ CHECKFORA
|
||||
CMP [SINGLECOM],0
|
||||
JZ CHECKFORA
|
||||
MOV [SINGLECOM],-1 ; Make sure SINGLECOM exits
|
||||
|
||||
CHECKFORA:
|
||||
CMP [ERRCD_24],0 ; Write protect
|
||||
JZ ABORTFOR
|
||||
CMP [ERRCD_24],2 ; Drive not ready
|
||||
JNZ EEXIT ; Don't abort the FOR
|
||||
|
||||
ABORTFOR:
|
||||
MOV [FORFLAG],0 ; Abort a FOR in progress
|
||||
CMP [SINGLECOM],0
|
||||
JZ EEXIT
|
||||
MOV [SINGLECOM],-1 ; Make sure SINGLECOM exits
|
||||
|
||||
EEXIT:
|
||||
MOV AL,AH
|
||||
MOV DX,DI
|
||||
|
||||
RESTHD:
|
||||
INVOKE RESTHAND
|
||||
POP CX
|
||||
POP SI ;AN000; restore registers
|
||||
POP ES
|
||||
POP DS
|
||||
IRET
|
||||
|
||||
FATERR:
|
||||
MOV DX,BADFAT ;AC000;
|
||||
MOV AL,BADFAT_SUBST ;AN000; get number of substitutions
|
||||
MOV NUMBER_SUBST,AL ;AN000;
|
||||
MOV SI,OFFSET RESGROUP:BADFAT_BLOCK ;AN000; get address of subst block
|
||||
CALL RPRINT
|
||||
|
||||
IF Tokenized
|
||||
MOV DX,OFFSET RESGROUP:ERRMES
|
||||
CALL RPRINT
|
||||
ENDIF
|
||||
|
||||
MOV AL,2 ; Abort
|
||||
JMP RESTHD
|
||||
|
||||
;*********************************************
|
||||
; Print routines for Tokenized resident messages
|
||||
|
||||
ASSUME DS:RESGROUP,SS:RESGROUP
|
||||
|
||||
CRLF:
|
||||
MOV DX,NEWLIN ;AC000;
|
||||
|
||||
;
|
||||
; RPRINT prints out a message on the user's console. We clear carry before
|
||||
; each system call. We do this so that the ^C checker may change things so
|
||||
; that carry is set. If we detect a system call that returns with carry set,
|
||||
; we merely return.
|
||||
;
|
||||
; Inputs: DX has the message number as an offset from DS.
|
||||
; Outputs: Carry clear: no carries detected in the system calls
|
||||
; Carry set: at least one system call returned with carry set
|
||||
; Registers modified: none
|
||||
;
|
||||
|
||||
RPRINT:
|
||||
|
||||
;
|
||||
; If we are not tokenized, the message consists of a $-terminated string.
|
||||
; Use CPM io to output it.
|
||||
;
|
||||
|
||||
if NOT tokenized
|
||||
PUSH AX
|
||||
PUSH BX ;AC000; save BX register
|
||||
PUSH CX ;AC000; save CX register
|
||||
PUSH DX ;AC000; save DX register
|
||||
MOV AX,DX ;AC000; get message number
|
||||
MOV DH,DISP_CLASS ;AC000; get display class
|
||||
MOV DL,NO_CONT_FLAG ;AN000; set control flags off
|
||||
MOV BX,NO_HANDLE_OUT ;AC000; set message handler to use function 1-12
|
||||
XOR CH,CH ;AC000; clear upper part of cx
|
||||
MOV CL,NUMBER_SUBST ;AC000; set number of substitutions
|
||||
CALL SYSDISPMSG ;AC000; display the message
|
||||
MOV DISP_CLASS,UTIL_MSG_CLASS ;AC000; reset display class
|
||||
MOV NUMBER_SUBST,NO_SUBST ;AC000; reset number of substitutions
|
||||
POP DX ;AC000; restore registers
|
||||
POP CX ;AC000;
|
||||
POP BX ;AC000;
|
||||
POP AX
|
||||
|
||||
return
|
||||
endif
|
||||
|
||||
;
|
||||
; If we are tokenized, output character-by-character. If there is a digit in
|
||||
; the output, look up that substring in the tokenization table. Use the high
|
||||
; bit to determine the end-of-string.
|
||||
;
|
||||
|
||||
If Tokenized
|
||||
SaveReg <AX,DX,SI>
|
||||
MOV SI,DX
|
||||
|
||||
RPRINT1:
|
||||
LODSB
|
||||
PUSH AX ; save for EOS testing
|
||||
AND AL,7FH
|
||||
CMP AL,'0'
|
||||
JB RPRINT2
|
||||
CMP AL,'9'
|
||||
JA RPRINT2
|
||||
SUB AL,'0'
|
||||
CBW ; DS must be RESGROUP if we get here
|
||||
SHL AX,1 ; clear carry
|
||||
XCHG SI,AX
|
||||
MOV DX,[SI + OFFSET RESGroup:MesADD]
|
||||
CALL RPrint
|
||||
XCHG SI,AX
|
||||
JMP SHORT RPRINT3
|
||||
|
||||
RPRINT2:
|
||||
MOV DL,AL
|
||||
MOV AH,STD_CON_OUTPUT
|
||||
clc ; set ok flag
|
||||
INT 21H
|
||||
|
||||
RPRINT3:
|
||||
POP AX
|
||||
JC RPrint5 ; Abnormal termination?
|
||||
TEST AL,80h ; High bit set indicates end (carry clear)
|
||||
JZ RPRINT1
|
||||
|
||||
RPRINT5:
|
||||
RestoreReg <SI,DX,AX>
|
||||
RET
|
||||
endif
|
||||
|
||||
|
||||
;g
|
||||
;g This routine returns the upper case of the character in AL
|
||||
;g from the upper case table in DOS if character if above
|
||||
;g ascii 128, else subtract 20H if between "a" and "z"
|
||||
;g
|
||||
|
||||
assume ds:resgroup
|
||||
|
||||
in_char_xlat proc near
|
||||
|
||||
cmp al,80h ;g see if char is above ascii 128
|
||||
jb other_xlat ;g no - upper case math
|
||||
sub al,80h ;g only upper 128 characters in table
|
||||
push ds
|
||||
push bx
|
||||
lds bx,dword ptr com_xlat_addr+1 ;g get table address
|
||||
add bx,2 ;g skip over first word, of table
|
||||
xlat ds:byte ptr [bx] ;g convert to upper case
|
||||
pop bx
|
||||
pop ds
|
||||
jmp short in_char_xlat_end ;g we finished - exit
|
||||
|
||||
other_xlat:
|
||||
cmp al,'a' ;g if between "a" and "z", subtract
|
||||
jb in_char_xlat_end ;g 20h to get upper case
|
||||
cmp al,'z' ;g equivalent.
|
||||
ja in_char_xlat_end ;g
|
||||
sub al,20h ;g Lower-case changed to upper-case
|
||||
|
||||
in_char_xlat_end:
|
||||
|
||||
ret
|
||||
|
||||
in_char_xlat endp
|
||||
;---------------------- DBCS lead byte check. this is resident code ; 3/3/KK
|
||||
|
||||
ITESTKANJ: ;AN000;
|
||||
TestKanjR: ;AN000; 3/3/KK
|
||||
push ds ;AN000; 3/3/KK
|
||||
push si ;AN000; 3/3/KK
|
||||
push ax ;AN000; 3/3/KK
|
||||
lds si,dbcs_vector_addr ;AN000; GET DBCS VECTOR
|
||||
|
||||
ktlop: ;AN000; 3/3/KK
|
||||
cmp word ptr ds:[si],0 ;AN000; 3/3/KK end of Lead Byte Table
|
||||
je notlead ;AN000; 3/3/KK
|
||||
pop ax ;AN000; 3/3/KK
|
||||
push ax ;AN000; 3/3/KK
|
||||
cmp al, byte ptr ds:[si] ;AN000; 3/3/KK
|
||||
jb notlead ;AN000; 3/3/KK
|
||||
inc si ;AN000; 3/3/KK
|
||||
cmp al, byte ptr ds:[si] ;AN000; 3/3/KK
|
||||
jbe islead ;AN000; 3/3/KK
|
||||
inc si ;AN000; 3/3/KK
|
||||
jmp short ktlop ;AN000; 3/3/KK try another range
|
||||
|
||||
Notlead: ;AN000; 3/3/KK
|
||||
xor ax,ax ;AN000; 3/3/KK set zero
|
||||
jmp short ktret ;AN000; 3/3/KK
|
||||
|
||||
Islead: ;AN000; 3/3/KK
|
||||
xor ax,ax ;AN000; 3/3/KK reset zero
|
||||
inc ax ;AN000; 3/3/KK
|
||||
|
||||
ktret: ;AN000; 3/3/KK
|
||||
pop ax ;AN000; 3/3/KK
|
||||
pop si ;AN000; 3/3/KK
|
||||
pop ds ;AN000; 3/3/KK
|
||||
return ;AN000; 3/3/KK
|
||||
|
||||
|
||||
; ****************************************************************
|
||||
; *
|
||||
; * ROUTINE: RESET_MSG_POINTERS
|
||||
; *
|
||||
; * FUNCTION: Resets addresses for parse and critical error
|
||||
; * messages in DOS via INT 2fh. This routine
|
||||
; * is invoked before command exits.
|
||||
; *
|
||||
; * INPUT: none
|
||||
; *
|
||||
; * OUTPUT: none
|
||||
; *
|
||||
; ****************************************************************
|
||||
|
||||
reset_msg_pointers proc near
|
||||
|
||||
assume ds:resgroup, es:nothing
|
||||
|
||||
push es ;AN000; save used registers
|
||||
push ax ;AN000;
|
||||
push dx ;AN000;
|
||||
push di ;AN000;
|
||||
;AD060; mov ah,multdos ;AN000; reset parse message pointers
|
||||
;AD060; mov al,message_2f ;AN000; call for message retriever
|
||||
;AD060; mov dl,set_parse_msg ;AN000; set up parse message address
|
||||
;AD060; mov di,pars_msg_off ;AN000; old offset of parse messages
|
||||
;AD060; mov es,pars_msg_seg ;AN000; old segment of parse messages
|
||||
;AD060; int 2fh ;AN000; go set it
|
||||
|
||||
;AD060; mov ah,multdos ;AN000; set up to call DOS through int 2fh
|
||||
;AD060; mov al,message_2f ;AN000; call for message retriever
|
||||
mov ax,(multdos shl 8 or message_2f);AN060; reset critical message pointers
|
||||
mov dl,set_critical_msg ;AN000; set up critical error message address
|
||||
mov di,crit_msg_off ;AN000; old offset of critical messages
|
||||
mov es,crit_msg_seg ;AN000; old segment of critical messages
|
||||
int 2fh ;AN000; go set it
|
||||
pop di ;AN000; restore used registers
|
||||
pop dx ;AN000;
|
||||
pop ax ;AN000;
|
||||
pop es ;AN000;
|
||||
|
||||
ret
|
||||
|
||||
|
||||
reset_msg_pointers endp
|
||||
|
||||
PUBLIC MSG_SERV_ST ;AN000;
|
||||
MSG_SERV_ST LABEL BYTE ;AN000;
|
||||
|
||||
PUBLIC SYSGETMSG,SYSDISPMSG
|
||||
|
||||
ASSUME DS:RESGROUP, ES:RESGROUP
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
|
||||
INCLUDE SYSMSG.INC ;AN000; include message services
|
||||
|
||||
.list
|
||||
.cref
|
||||
|
||||
MSG_UTILNAME <COMMAND> ;AN000; define utility name
|
||||
|
||||
MSG_SERVICES <COMR,NEARmsg,DISK_PROC,GETmsg,DISPLAYmsg,CHARmsg,NUMmsg> ;AC060; include message services macro
|
||||
|
||||
PUBLIC RES_CODE_END ;AN000;
|
||||
RES_CODE_END LABEL BYTE ;AN000;
|
||||
|
||||
include msgdcl.inc
|
||||
|
||||
CODERES ENDS
|
||||
END
|
||||
1045
v4.0/src/CMD/COMMAND/TBATCH.ASM
Normal file
1045
v4.0/src/CMD/COMMAND/TBATCH.ASM
Normal file
File diff suppressed because it is too large
Load Diff
753
v4.0/src/CMD/COMMAND/TBATCH2.ASM
Normal file
753
v4.0/src/CMD/COMMAND/TBATCH2.ASM
Normal file
@@ -0,0 +1,753 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)tbatch2.asm 4.2 85/07/22
|
||||
; SCCSID = @(#)tbatch2.asm 4.2 85/07/22
|
||||
TITLE Batch processing routines part II
|
||||
|
||||
INCLUDE comsw.asm
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE DOSSYM.INC
|
||||
INCLUDE comseg.asm
|
||||
INCLUDE comequ.asm
|
||||
.list
|
||||
.cref
|
||||
|
||||
|
||||
DATARES SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN BATCH:WORD
|
||||
EXTRN Batch_Abort:byte
|
||||
EXTRN call_batch_flag:byte
|
||||
EXTRN call_flag:byte
|
||||
EXTRN IFFlag:BYTE
|
||||
EXTRN In_Batch:byte
|
||||
EXTRN Nest:word
|
||||
EXTRN PIPEFILES:BYTE
|
||||
EXTRN RETCODE:WORD
|
||||
EXTRN SINGLECOM:WORD
|
||||
DATARES ENDS
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN BADLAB_PTR:WORD
|
||||
EXTRN BatBufLen:WORD
|
||||
EXTRN IFTAB:BYTE
|
||||
EXTRN SYNTMES_PTR:WORD
|
||||
TRANDATA ENDS
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN arg:byte ; the arg structure!
|
||||
EXTRN BatBuf:BYTE
|
||||
EXTRN BatBufEnd:WORD
|
||||
EXTRN BatBufPos:WORD
|
||||
EXTRN BATHAND:WORD
|
||||
EXTRN COMBUF:BYTE
|
||||
EXTRN DIRBUF:BYTE
|
||||
EXTRN GOTOLEN:WORD
|
||||
EXTRN if_not_count:word
|
||||
EXTRN IFNOTFLAG:BYTE
|
||||
EXTRN RESSEG:WORD
|
||||
TRANSPACE ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC BYTE
|
||||
|
||||
ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
|
||||
EXTRN cerror:near
|
||||
EXTRN docom1:near
|
||||
EXTRN tcommand:near
|
||||
|
||||
public $if,iferlev,goto,shift,ifexists,ifnot,forerror,$call
|
||||
|
||||
|
||||
Break <GetBatByt - retrieve a byte from the batch file>
|
||||
|
||||
; Get one byte from the batch file and return it in AL. End-of-file returns
|
||||
; <CR> and ends batch mode. DS must be set to resident segment.
|
||||
; AH, DX destroyed.
|
||||
|
||||
Procedure GETBATBYT,NEAR
|
||||
|
||||
ASSUME DS:RESGROUP
|
||||
|
||||
SaveReg <BX,CX,DS>
|
||||
test byte ptr [Batch_Abort],-1
|
||||
jnz BatEOF
|
||||
TEST Batch,-1
|
||||
JZ BatEOF
|
||||
PUSH ES
|
||||
MOV ES,Batch
|
||||
ASSUME ES:NOTHING
|
||||
ADD WORD PTR ES:[BatSeek],1
|
||||
ADC WORD PTR ES:[BatSeek+2],0
|
||||
POP ES
|
||||
;
|
||||
; See if we have bytes buffered...
|
||||
;
|
||||
MOV AX,CS
|
||||
MOV DS,AX
|
||||
ASSUME DS:TranGroup
|
||||
MOV BX,BatBufPos
|
||||
CMP BX,-1
|
||||
JNZ UnBuf
|
||||
;
|
||||
; There are no bytes in the buffer. Let's try to fill it up.
|
||||
;
|
||||
MOV DX,OFFSET TranGROUP:BatBuf
|
||||
MOV CX,BatBufLen ; max to read.
|
||||
MOV BX,BatHand
|
||||
MOV AH,READ
|
||||
INT int_command ; Get one more byte from batch file
|
||||
jnc bat_read_ok ;AN022; if no error - continue
|
||||
invoke get_ext_error_number ;AN022; get the error
|
||||
push ds ;AN022; save local segment
|
||||
mov ds,[resseg] ;AN022; get resident segment
|
||||
assume ds:resgroup ;AN022;
|
||||
mov dx,ax ;AN022; put error in DX
|
||||
invoke output_batch_name ;AN022; set up to print the error
|
||||
pop ds ;AN022;
|
||||
assume ds:trangroup ;AN022;
|
||||
invoke std_eprintf ;AN022; print out the error
|
||||
mov byte ptr combuf+2,end_of_line_in;AN022; terminate the batch line for parsing
|
||||
mov byte ptr combuf+3,end_of_line_out ;AN022; terminate the batch line for output
|
||||
jmp bateof ;AN022; terminate the batch file
|
||||
|
||||
bat_read_ok: ;AN022;
|
||||
MOV CX,AX
|
||||
JCXZ BATEOFDS
|
||||
MOV BatBufEnd,CX
|
||||
XOR BX,BX
|
||||
MOV BatBufPos,BX
|
||||
;
|
||||
; Buffered bytes!
|
||||
;
|
||||
UnBuf:
|
||||
MOV AL,BatBuf[BX] ; get next byte
|
||||
INC BX
|
||||
CMP BX,BatBufEnd ; beyond end of buffer?
|
||||
JB SetBufPos
|
||||
MOV BX,-1
|
||||
|
||||
SetBufPos:
|
||||
MOV BatBufPos,BX
|
||||
CMP AL,1AH ; ^Z for termination?
|
||||
jnz GetByteDone
|
||||
|
||||
BatEOFDS:
|
||||
ASSUME DS:TranGroup
|
||||
MOV DS,ResSeg
|
||||
ASSUME DS:ResGroup
|
||||
|
||||
BATEOF:
|
||||
invoke BatchOff
|
||||
CALL BATCLOSE
|
||||
MOV AL,0DH ; If end-of-file, then end of line
|
||||
test byte ptr [Batch_Abort],-1
|
||||
mov byte ptr [Batch_Abort],0
|
||||
jz Cont_Get_Byt
|
||||
mov di,offset TRANGROUP:COMBUF+2 ; reset pointer to beginning of buffer
|
||||
xor cx,cx ; zero line length
|
||||
jmp short GetByteDone
|
||||
|
||||
Cont_Get_Byt:
|
||||
CMP [SINGLECOM],0FFF0H ; See if we need to set SINGLECOM
|
||||
JNZ GetByteDone
|
||||
CMP NEST,0 ;G See if we have nested batch files
|
||||
JNZ GETBYTEDONE ;G Yes - don't exit just yet
|
||||
MOV [SINGLECOM],-1 ; Cause termination
|
||||
|
||||
GetByteDone:
|
||||
RestoreReg <DS,CX,BX>
|
||||
|
||||
return
|
||||
|
||||
EndProc GetBatByt
|
||||
|
||||
break <$If - conditional execution>
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
IFERRORP:
|
||||
POP AX
|
||||
IFERROR:
|
||||
FORERROR:
|
||||
MOV DX,OFFSET TRANGROUP:SYNTMES_ptr
|
||||
JMP CERROR
|
||||
|
||||
$IF:
|
||||
;
|
||||
; Turn off any pipes in progress.
|
||||
;
|
||||
push ds ;AN004; save local DS
|
||||
mov ds,[resseg] ;AN004; get resident segment
|
||||
assume ds:resgroup ;AN004;
|
||||
cmp [PIPEFILES],0 ;AN004; Only turn off if present.
|
||||
jz IFNoPipe ;AN004; no pipe - continue
|
||||
invoke PipeDel ;AN004; turn off piping
|
||||
|
||||
IFNoPipe: ;AN004;
|
||||
pop ds ;AN004; get local DS back
|
||||
assume ds:trangroup ;AN004;
|
||||
MOV [IFNOTFLAG],0
|
||||
mov [if_not_count], 0
|
||||
MOV SI,81H
|
||||
|
||||
IFREENT:
|
||||
invoke SCANOFF
|
||||
CMP AL,0DH
|
||||
JZ IFERROR
|
||||
MOV BP,SI
|
||||
MOV DI,OFFSET TRANGROUP:IFTAB ; Prepare to search if table
|
||||
MOV CH,0
|
||||
|
||||
IFINDCOM:
|
||||
MOV SI,BP
|
||||
MOV CL,[DI]
|
||||
INC DI
|
||||
JCXZ IFSTRING
|
||||
JMP SHORT FIRSTCOMP
|
||||
|
||||
IFCOMP:
|
||||
JNZ IF_DIF ;AC000;
|
||||
|
||||
FIRSTCOMP:
|
||||
LODSB
|
||||
MOV AH,ES:[DI]
|
||||
INC DI
|
||||
CMP AL,AH
|
||||
JZ IFLP
|
||||
OR AH,20H ; Try lower case
|
||||
CMP AL,AH
|
||||
|
||||
IFLP:
|
||||
LOOP IFCOMP
|
||||
|
||||
IF_DIF: ;AC000;
|
||||
LAHF
|
||||
ADD DI,CX ; Bump to next position without affecting flags
|
||||
MOV BX,[DI] ; Get handler address
|
||||
INC DI
|
||||
INC DI
|
||||
SAHF
|
||||
JNZ IFINDCOM
|
||||
LODSB
|
||||
CMP AL,0DH
|
||||
|
||||
IFERRORJ:
|
||||
JZ IFERROR
|
||||
invoke DELIM
|
||||
JNZ IFINDCOM
|
||||
invoke SCANOFF
|
||||
JMP BX
|
||||
|
||||
IFNOT:
|
||||
NOT [IFNOTFLAG]
|
||||
inc [if_not_count]
|
||||
JMP IFREENT
|
||||
|
||||
;
|
||||
; We are comparing two strings for equality. First, find the end of the
|
||||
; first string.
|
||||
;
|
||||
|
||||
IFSTRING:
|
||||
PUSH SI ; save away pointer for later compare
|
||||
XOR CX,CX ; count of chars in first string
|
||||
|
||||
FIRST_STRING:
|
||||
LODSB ; get character
|
||||
CMP AL,0DH ; end of line?
|
||||
JZ IFERRORP ; yes => error
|
||||
invoke DELIM ; is it a delimiter?
|
||||
JZ EQUAL_CHECK ; yes, go find equal sign
|
||||
INC CX ; remember 1 byte for the length
|
||||
JMP FIRST_STRING ; go back for more
|
||||
;
|
||||
; We have found the end of the first string. Unfortunately, we CANNOT use
|
||||
; scanoff to find the next token; = is a valid separator and will be skipped
|
||||
; over.
|
||||
;
|
||||
|
||||
EQUAL_CHECK:
|
||||
CMP AL,'=' ; is char we have an = sign?
|
||||
JZ EQUAL_CHECK2 ; yes, go find second one.
|
||||
CMP AL,0DH ; end of line?
|
||||
JZ IFERRORPj ;AC004; yes, syntax error
|
||||
LODSB ; get next char
|
||||
JMP EQUAL_CHECK
|
||||
;
|
||||
; The first = has been found. The next char had better be an = too.
|
||||
;
|
||||
|
||||
EQUAL_CHECK2:
|
||||
LODSB ; get potential = char
|
||||
CMP AL,'=' ; is it good?
|
||||
jnz iferrorpj ; no, error
|
||||
;
|
||||
; Find beginning of second string.
|
||||
;
|
||||
invoke SCANOFF
|
||||
CMP AL,0DH
|
||||
jz iferrorpj
|
||||
POP DI
|
||||
;
|
||||
; DS:SI points to second string
|
||||
; CX has number of chars in first string
|
||||
; ES:DI points to first string
|
||||
;
|
||||
; Perform compare to elicit match
|
||||
;
|
||||
REPE CMPSB
|
||||
JZ MATCH ; match found!
|
||||
;
|
||||
; No match. Let's find out what was wrong. The character that did not match
|
||||
; has been advanced over. Let's back up to it.
|
||||
;
|
||||
DEC SI
|
||||
;
|
||||
; If it is EOL, then syntax error
|
||||
;
|
||||
CMP BYTE PTR [SI],0DH
|
||||
JZ IFERRORJ
|
||||
;
|
||||
; Advance pointer over remainder of unmatched text to next delimiter
|
||||
;
|
||||
|
||||
SKIPSTRINGEND:
|
||||
LODSB
|
||||
|
||||
NOTMATCH:
|
||||
CMP AL,0DH
|
||||
|
||||
IFERRORJ2:
|
||||
JZ IFERRORJ
|
||||
invoke DELIM
|
||||
JNZ SKIPSTRINGEND
|
||||
;
|
||||
; Signal that we did NOT have a match
|
||||
;
|
||||
MOV AL,-1
|
||||
JMP SHORT IFRET
|
||||
|
||||
iferrorpj:
|
||||
jmp iferrorp
|
||||
;
|
||||
; The compare succeeded. Was the second string longer than the first? We
|
||||
; do this by seeing if the next char is a delimiter.
|
||||
;
|
||||
|
||||
MATCH:
|
||||
LODSB
|
||||
invoke DELIM
|
||||
JNZ NOTMATCH ; not same.
|
||||
XOR AL,AL
|
||||
JMP SHORT IFRET
|
||||
|
||||
IFEXISTS:
|
||||
ifexist_attr EQU attr_hidden+attr_system
|
||||
|
||||
moredelim:
|
||||
lodsb ; move command line pointer over
|
||||
invoke delim ; pathname -- have to do it ourselves
|
||||
jnz moredelim ; 'cause parse_file_descriptor is dumb
|
||||
mov DX, OFFSET TRANGROUP:dirbuf
|
||||
trap set_dma
|
||||
mov BX, 2 ; if(0) [|not](|1) exist[1|2] file(2|3)
|
||||
add BX, [if_not_count]
|
||||
mov AX, OFFSET TRANGROUP:arg.argv
|
||||
invoke argv_calc ; convert arg index to pointer
|
||||
mov DX, [BX].argpointer ; get pointer to supposed filename
|
||||
mov CX, ifexist_attr ; filetypes to search for
|
||||
trap Find_First ; request first match, if any
|
||||
jc if_ex_c ; carry is how to determine error
|
||||
xor AL, AL
|
||||
jmp ifret
|
||||
|
||||
if_ex_c:
|
||||
mov AL, -1 ; false 'n' fall through...
|
||||
|
||||
IFRET:
|
||||
TEST [IFNOTFLAG],-1
|
||||
JZ REALTEST
|
||||
NOT AL
|
||||
|
||||
REALTEST:
|
||||
OR AL,AL
|
||||
JZ IFTRUE
|
||||
JMP TCOMMAND
|
||||
|
||||
IFTRUE:
|
||||
invoke SCANOFF
|
||||
MOV CX,SI
|
||||
SUB CX,81H
|
||||
SUB DS:[80H],CL
|
||||
MOV CL,DS:[80H]
|
||||
MOV [COMBUF+1],CL
|
||||
MOV DI,OFFSET TRANGROUP:COMBUF+2
|
||||
CLD
|
||||
REP MOVSB
|
||||
MOV AL,0DH
|
||||
STOSB
|
||||
;
|
||||
; Signal that an IF was done. This prevents the redirections from getting
|
||||
; lost.
|
||||
;
|
||||
PUSH DS
|
||||
MOV DS,ResSeg
|
||||
ASSUME DS:RESGROUP
|
||||
MOV IFFlag,-1
|
||||
POP DS
|
||||
ASSUME DS:TRANGROUP
|
||||
;
|
||||
; Go do the command
|
||||
;
|
||||
JMP DOCOM1
|
||||
|
||||
iferrorj3:
|
||||
jmp iferrorj2
|
||||
|
||||
IFERLEV:
|
||||
MOV BH,10
|
||||
XOR BL,BL
|
||||
|
||||
GETNUMLP:
|
||||
LODSB
|
||||
CMP AL,0DH
|
||||
jz iferrorj3
|
||||
invoke DELIM
|
||||
JZ GOTNUM
|
||||
SUB AL,'0'
|
||||
XCHG AL,BL
|
||||
MUL BH
|
||||
ADD AL,BL
|
||||
XCHG AL,BL
|
||||
JMP SHORT GETNUMLP
|
||||
|
||||
GOTNUM:
|
||||
PUSH DS
|
||||
MOV DS,[RESSEG]
|
||||
ASSUME DS:RESGROUP
|
||||
MOV AH,BYTE PTR [RETCODE]
|
||||
POP DS
|
||||
ASSUME DS:TRANGROUP
|
||||
XOR AL,AL
|
||||
CMP AH,BL
|
||||
JAE IFRET
|
||||
DEC AL
|
||||
JMP SHORT IFRET
|
||||
|
||||
|
||||
break <Shift - advance arguments>
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
;
|
||||
; Shift the parameters in the batch structure by 1 and set up the new argument.
|
||||
; This is a NOP if no batch in progress.
|
||||
;
|
||||
|
||||
Procedure Shift,NEAR
|
||||
|
||||
MOV DS,[RESSEG]
|
||||
ASSUME DS:RESGROUP
|
||||
MOV AX,[BATCH] ; get batch pointer
|
||||
OR AX,AX ; in batch mode?
|
||||
retz ; no, done.
|
||||
MOV ES,AX ; operate in batch segment
|
||||
MOV DS,AX
|
||||
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
|
||||
;
|
||||
; Now move the batch args down by 1 word
|
||||
;
|
||||
MOV DI,BatParm ; point to parm table
|
||||
LEA SI,[DI+2] ; make source = dest + 2
|
||||
MOV CX,9 ; move 9 parameters
|
||||
REP MOVSW ; SHIFT down
|
||||
;
|
||||
; If the last parameter (the one not moved) is empty (= -1) then we are done.
|
||||
; We have copied it into the previous position
|
||||
;
|
||||
CMP WORD PTR [DI],-1 ; if last one was not in use then
|
||||
retz ; No new parm
|
||||
;
|
||||
; This last pointer is NOT nul. Get it and scan to find the next argument.
|
||||
; Assume, first, that there is no next argument
|
||||
;
|
||||
MOV SI,[DI]
|
||||
MOV WORD PTR [DI],-1 ; Assume no parm
|
||||
;
|
||||
; The parameters are CR separated. Scan for end of this parm
|
||||
;
|
||||
SKIPCRLP:
|
||||
LODSB
|
||||
CMP AL,0DH
|
||||
JNZ SKIPCRLP
|
||||
;
|
||||
; We are now pointing at next arg. If it is 0 (end of original line) then we
|
||||
; are finished. There ARE no more parms and the pointer has been previously
|
||||
; initialized to indicate it.
|
||||
;
|
||||
CMP BYTE PTR [SI],0
|
||||
retz ; End of parms
|
||||
MOV [DI],SI ; Pointer to next parm as %9
|
||||
|
||||
return
|
||||
|
||||
EndProc Shift
|
||||
|
||||
;
|
||||
; Skip delim reads bytes from the batch file until a non-delimiter is seen.
|
||||
; returns char in AL, carry set -> eof
|
||||
;
|
||||
|
||||
Procedure SkipDelim,NEAR
|
||||
|
||||
ASSUME DS:ResGroup,ES:NOTHING
|
||||
TEST Batch,-1
|
||||
JZ SkipErr ; batch file empty. OOPS!
|
||||
CALL GetBatByt ; get a char
|
||||
invoke Delim ; check for ignoreable chars
|
||||
JZ SkipDelim ; ignore this char.
|
||||
clc
|
||||
return
|
||||
|
||||
SkipErr:
|
||||
stc
|
||||
return
|
||||
|
||||
EndProc SkipDelim
|
||||
|
||||
break $Call
|
||||
|
||||
; CALL is an internal command that transfers control to a .bat, .exe, or
|
||||
; .com file. This routine strips the CALL off the command line, sets
|
||||
; the CALL_FLAG to indicate a call in progress, and returns control to
|
||||
; DOCOM1 in TCODE to reprocess the command line and execute the file
|
||||
; being CALLed.
|
||||
|
||||
$CALL:
|
||||
|
||||
; strip off CALL from command line
|
||||
|
||||
ASSUME DS:trangroup,ES:trangroup
|
||||
push si
|
||||
push di
|
||||
push ax
|
||||
push cx
|
||||
mov si,offset trangroup:combuf+2
|
||||
invoke scanoff ;get to first non-delimeter
|
||||
add si,length_call ;point to char past CALL
|
||||
mov di,offset trangroup:combuf+2
|
||||
mov cx,combuflen-length_call ;get length of buffer
|
||||
rep movsb ;move it
|
||||
pop cx
|
||||
pop ax
|
||||
pop di
|
||||
pop si
|
||||
|
||||
|
||||
; set call flag to indicate call in progress
|
||||
|
||||
push ds
|
||||
mov ds,[resseg]
|
||||
ASSUME DS:resgroup,ES:resgroup
|
||||
mov call_flag, call_in_progress
|
||||
mov call_batch_flag, call_in_progress
|
||||
;
|
||||
; Turn off any pipes in progress.
|
||||
;
|
||||
cmp [PIPEFILES],0 ; Only turn off if present.
|
||||
jz NoPipe
|
||||
invoke PipeDel
|
||||
NoPipe:
|
||||
pop ds
|
||||
|
||||
ret
|
||||
|
||||
break Goto
|
||||
|
||||
GOTO:
|
||||
|
||||
assume ds:trangroup,es:trangroup
|
||||
MOV DS,[RESSEG]
|
||||
ASSUME DS:RESGROUP
|
||||
TEST [BATCH],-1
|
||||
retz ; If not in batch mode, a nop
|
||||
XOR DX,DX
|
||||
PUSH DS
|
||||
MOV DS,Batch
|
||||
MOV WORD PTR DS:[BatSeek],DX ; Back to start
|
||||
MOV WORD PTR DS:[BatSeek+2],DX ; Back to start
|
||||
POP DS
|
||||
|
||||
GotoOpen:
|
||||
invoke promptBat
|
||||
MOV DI,FCB+1 ; Get the label
|
||||
MOV CX,11
|
||||
MOV AL,' '
|
||||
REPNE SCASB
|
||||
JNZ NOINC
|
||||
INC CX
|
||||
|
||||
NOINC:
|
||||
SUB CX,11
|
||||
NEG CX
|
||||
MOV [GOTOLEN],CX
|
||||
;
|
||||
; At beginning of file. Skip to first non-delimiter char
|
||||
;
|
||||
CALL SkipDelim
|
||||
JC BadGoto
|
||||
CMP AL,':'
|
||||
JZ CHKLABEL
|
||||
|
||||
LABLKLP: ; Look for the label
|
||||
CALL GETBATBYT
|
||||
CMP AL,0AH
|
||||
JNZ LABLKTST
|
||||
;
|
||||
; At beginning of line. Skip to first non-delimiter char
|
||||
;
|
||||
CALL SkipDelim
|
||||
JC BadGoto
|
||||
CMP AL,':'
|
||||
JZ CHKLABEL
|
||||
|
||||
LABLKTST:
|
||||
TEST [BATCH],-1
|
||||
JNZ LABLKLP
|
||||
|
||||
BadGoto:
|
||||
CALL BATCLOSE
|
||||
PUSH CS
|
||||
POP DS
|
||||
MOV DX,OFFSET TRANGROUP:BADLAB_ptr
|
||||
JMP CERROR
|
||||
|
||||
;
|
||||
; Found the :. Skip to first non-delimiter char
|
||||
;
|
||||
|
||||
CHKLABEL:
|
||||
CALL SkipDelim
|
||||
JC BadGoto
|
||||
MOV DI,FCB+1
|
||||
MOV CX,[GOTOLEN]
|
||||
JMP SHORT GotByte
|
||||
|
||||
NEXTCHRLP:
|
||||
PUSH CX
|
||||
CALL GETBATBYT
|
||||
POP CX
|
||||
|
||||
GotByte:
|
||||
INVOKE TESTKANJ ;AN000; 3/3/KK
|
||||
JZ NOTKANJ1 ;AN000; 3/3/KK
|
||||
CMP AL, ES:[DI] ;AN000; 3/3/KK
|
||||
JNZ LABLKTST ;AN000; 3/3/KK
|
||||
INC DI ;AN000; 3/3/KK
|
||||
DEC CX ;AN000; 3/3/KK
|
||||
JCXZ LABLKTST ;AN000; 3/3/KK
|
||||
PUSH CX ;AN000; 3/3/KK
|
||||
CALL GETBATBYT ;AN000; 3/3/KK
|
||||
POP CX ;AN000; 3/3/KK
|
||||
CMP AL, ES:[DI] ;AN000; 3/3/KK
|
||||
JMP SHORT KNEXTLABCHR ;AN000; 3/3/KK
|
||||
|
||||
NOTKANJ1: ;AN000; 3/3/KK
|
||||
OR AL,20H
|
||||
CMP AL,ES:[DI]
|
||||
JNZ TRYUPPER
|
||||
JMP SHORT NEXTLABCHR
|
||||
|
||||
TRYUPPER:
|
||||
SUB AL,20H
|
||||
CMP AL,ES:[DI]
|
||||
|
||||
KNEXTLABCHR: ;AN000; 3/3/KK
|
||||
JNZ LABLKTST
|
||||
|
||||
NEXTLABCHR:
|
||||
INC DI
|
||||
LOOP NEXTCHRLP
|
||||
CALL GETBATBYT
|
||||
cmp [GOTOLEN],8 ; Is the label atleast 8 chars long?
|
||||
jge gotocont ; Yes, then the next char doesn't matter
|
||||
CMP AL,' '
|
||||
JA LABLKTST
|
||||
|
||||
gotocont:
|
||||
CMP AL,0DH
|
||||
JZ SKIPLFEED
|
||||
|
||||
TONEXTBATLIN:
|
||||
CALL GETBATBYT
|
||||
CMP AL,0DH
|
||||
JNZ TONEXTBATLIN
|
||||
|
||||
SKIPLFEED:
|
||||
CALL GETBATBYT
|
||||
CALL BatClose
|
||||
|
||||
return
|
||||
|
||||
Procedure BatClose,NEAR
|
||||
|
||||
MOV BX,CS:[BATHAND]
|
||||
CMP BX,5
|
||||
JB CloseReturn
|
||||
MOV AH,CLOSE
|
||||
INT int_command
|
||||
|
||||
CloseReturn:
|
||||
mov byte ptr [In_Batch],0 ; reset flag
|
||||
return
|
||||
|
||||
EndProc BatClose
|
||||
|
||||
;
|
||||
; Open the BATCH file, If open fails, AL is drive of batch file (A=1)
|
||||
; Also, fills internal batch buffer. If access denied, then AX = -1
|
||||
;
|
||||
|
||||
Procedure BatOpen,NEAR
|
||||
|
||||
ASSUME DS:RESGROUP,ES:TRANGROUP
|
||||
|
||||
PUSH DS
|
||||
MOV DS,[BATCH]
|
||||
ASSUME DS:NOTHING
|
||||
|
||||
MOV DX,BatFile
|
||||
MOV AX,OPEN SHL 8
|
||||
INT int_command ; Open the batch file
|
||||
JC SETERRDL
|
||||
MOV DX,WORD PTR DS:[BatSeek]
|
||||
MOV CX,WORD PTR DS:[BatSeek+2]
|
||||
POP DS
|
||||
ASSUME DS:RESGROUP
|
||||
|
||||
MOV [BATHAND],AX
|
||||
MOV BX,AX
|
||||
MOV AX,LSEEK SHL 8 ; Go to the right spot
|
||||
INT int_command
|
||||
MOV BatBufPos,-1 ; nuke batch buffer position
|
||||
|
||||
return
|
||||
|
||||
SETERRDL:
|
||||
MOV BX,DX
|
||||
invoke get_ext_error_number ;AN022; get the extended error
|
||||
mov dx,ax ;AN022; save extended error in DX
|
||||
MOV AL,[BX] ; Get drive spec
|
||||
SUB AL,'@' ; A = 1
|
||||
POP DS
|
||||
STC ; SUB mucked over carry
|
||||
|
||||
return
|
||||
|
||||
EndProc BatOpen
|
||||
|
||||
|
||||
TRANCODE ENDS
|
||||
END
|
||||
|
||||
598
v4.0/src/CMD/COMMAND/TCMD1A.ASM
Normal file
598
v4.0/src/CMD/COMMAND/TCMD1A.ASM
Normal file
@@ -0,0 +1,598 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)tcmd1a.asm 1.1 85/05/14
|
||||
; SCCSID = @(#)tcmd1a.asm 1.1 85/05/14
|
||||
TITLE PART4 COMMAND Transient routines.
|
||||
|
||||
; Internal commands DIR,PAUSE,ERASE,TYPE,VOL,VER
|
||||
|
||||
INCLUDE comsw.asm
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE DOSSYM.INC
|
||||
INCLUDE comseg.asm
|
||||
INCLUDE comequ.asm ;AC000;
|
||||
include ioctl.inc ;AN000;
|
||||
.list
|
||||
.cref
|
||||
|
||||
DATARES SEGMENT PUBLIC BYTE ;AN020;
|
||||
EXTRN append_flag:byte ;AN020;
|
||||
EXTRN append_state:word ;AN020;
|
||||
DATARES ENDS ;AN020;
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN BadCD_ptr:word
|
||||
EXTRN bits:word
|
||||
EXTRN Bytmes_ptr:word
|
||||
EXTRN comsw:word
|
||||
EXTRN dir_w_syn:word ;AC000;
|
||||
EXTRN dirdat_mo_day:word ;AC000;
|
||||
EXTRN dirdat_yr:word ;AC000;
|
||||
EXTRN dirdattim_ptr:word
|
||||
EXTRN dirhead_ptr:word
|
||||
EXTRN dirtim_hr_min:word ;AC000;
|
||||
EXTRN Dirmes_ptr:word
|
||||
EXTRN disp_file_size_ptr:word
|
||||
EXTRN Dmes_ptr:word
|
||||
EXTRN Extend_buf_ptr:word ;AN000;
|
||||
EXTRN msg_disp_class:byte ;AN000;
|
||||
EXTRN parse_dir:byte ;AC000;
|
||||
EXTRN slash_p_syn:word ;AC000;
|
||||
EXTRN string_buf_ptr:word
|
||||
EXTRN tab_ptr:word ;AC000;
|
||||
TRANDATA ENDS
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN bytes_free:word
|
||||
EXTRN charbuf:byte
|
||||
EXTRN COM:byte
|
||||
EXTRN Destisdir:byte
|
||||
EXTRN Desttail:word
|
||||
EXTRN dir_num:word
|
||||
EXTRN Dirbuf:byte
|
||||
EXTRN dirflag:byte ;AN015;
|
||||
EXTRN display_ioctl:word ;AC000;
|
||||
EXTRN display_mode:byte ;AC000;
|
||||
EXTRN filecnt:word
|
||||
EXTRN file_size_high:word
|
||||
EXTRN file_size_low:word
|
||||
EXTRN fullscr:word
|
||||
EXTRN ID:byte
|
||||
EXTRN lincnt:byte ;AC000;
|
||||
EXTRN linlen:byte
|
||||
EXTRN linperpag:word ;AC000;
|
||||
EXTRN msg_numb:word ;AN022;
|
||||
EXTRN parse1_addr:dword ;AC000;
|
||||
EXTRN parse1_syn:word ;AC000;
|
||||
EXTRN parse1_type:byte ;AC000;
|
||||
EXTRN pathcnt:word ;AN000;
|
||||
EXTRN pathpos:word ;AN000;
|
||||
EXTRN resseg:word ;AN020;
|
||||
EXTRN srcbuf:byte ;AC000;
|
||||
EXTRN string_ptr_2:word
|
||||
TRANSPACE ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC BYTE
|
||||
|
||||
ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
|
||||
;---------------
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN arg:byte ; the arg structure!
|
||||
TRANSPACE ENDS
|
||||
;---------------
|
||||
|
||||
EXTRN cerror:near
|
||||
EXTRN std_printf:near
|
||||
|
||||
|
||||
PUBLIC catalog
|
||||
|
||||
|
||||
break Catalog - Directory command
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
;
|
||||
; The DIR command displays the contents of a directory.
|
||||
;
|
||||
; ****************************************************************
|
||||
; *
|
||||
; * ROUTINE: CATALOG - display file(s) in directory
|
||||
; *
|
||||
; * FUNCTION: PARSE command line for drive, file, or path name.
|
||||
; * DIR allows two switches, /P (pause) and /W (wide).
|
||||
; * If an error occurs issue and error message and
|
||||
; * transfer control to CERROR.
|
||||
; *
|
||||
; * INPUT: command line at offset 81H
|
||||
; *
|
||||
; * OUTPUT: none
|
||||
; *
|
||||
; ****************************************************************
|
||||
|
||||
CATALOG:
|
||||
|
||||
;
|
||||
; Set up DTA for dir search firsts
|
||||
;
|
||||
mov dx,offset trangroup:Dirbuf ;AC000; Set Disk transfer address
|
||||
mov ah,Set_DMA ;AC000;
|
||||
int int_command ;AC000;
|
||||
;
|
||||
; Set up defaults for switches and parse the command line.
|
||||
;
|
||||
mov msg_numb,0 ;AN022; initialize message flag
|
||||
mov di,offset trangroup:srcbuf ;AN000; get address of srcbuf
|
||||
mov [pathpos],di ;AN000; this is start of path
|
||||
mov [pathcnt],1 ;AN000; initialize length to 1 char
|
||||
mov al,star ;AN000; initialize srcbuf to *,0d
|
||||
stosb ;AN000;
|
||||
mov al,end_of_line_in ;AN000;
|
||||
stosb ;AN000;
|
||||
mov si,81H ;AN000; Get command line
|
||||
mov di,offset trangroup:parse_dir ;AN000; Get adderss of PARSE_DIR
|
||||
xor cx,cx ;AC000; clear counter for positionals
|
||||
mov ComSw,cx ;AC000; initialize flags
|
||||
mov bits,cx ;AC000; initialize switches
|
||||
mov linperpag,linesperpage ;AC000; Set default for lines per page
|
||||
mov linlen,normperlin ;AC000; Set number of entries per line
|
||||
mov lincnt,normperlin ;AC000;
|
||||
|
||||
dirscan:
|
||||
xor dx,dx ;AN000;
|
||||
invoke parse_with_msg ;AC018; call parser
|
||||
cmp ax,end_of_line ;AN000; are we at end of line?
|
||||
jne dirscan_cont ;AN000; No - continue parsing
|
||||
jmp scandone ;AN000; yes - go process
|
||||
|
||||
dirscan_cont:
|
||||
cmp ax,result_no_error ;AN000; did we have an error?
|
||||
jz dirscan_cont2 ;AN000; No - continue parsing
|
||||
jmp badparm ;AN000; yes - exit
|
||||
|
||||
dirscan_cont2:
|
||||
cmp parse1_syn,offset trangroup:dir_w_syn ;AN000; was /W entered?
|
||||
je set_dir_width ;AN000; yes - go set wide lines
|
||||
cmp parse1_syn,offset trangroup:slash_p_syn ;AN000; was /P entered?
|
||||
je set_dir_pause ;AN000; yes - go set pause at end of screen
|
||||
;
|
||||
; Must be filespec since no other matches occurred. move filename to srcbuf
|
||||
;
|
||||
push si ;AC000; save position in line
|
||||
lds si,parse1_addr ;AC000; get address of filespec
|
||||
push si ;AN000; save address
|
||||
invoke move_to_srcbuf ;AC000; move to srcbuf
|
||||
pop dx ;AC000; get address in DX
|
||||
|
||||
;
|
||||
; The user may have specified a device. Search for the path and see if the
|
||||
; attributes indicate a device.
|
||||
;
|
||||
mov ah,Find_First ;AC000; find the file
|
||||
int int_command ;AC000;
|
||||
jnc Dir_check_device ;AN022; if no error - check device
|
||||
invoke get_ext_error_number ;AN022; get the extended error
|
||||
cmp ax,error_no_more_files ;AN022; was error no file found
|
||||
jz Dir_fspec_end ;AC022; yes -> obviously not a device
|
||||
cmp ax,error_path_not_found ;AN022; was error no file found
|
||||
jz Dir_fspec_end ;AC022; yes -> obviously not a device
|
||||
jmp dir_err_setup ;AN022; otherwise - go issue error message
|
||||
|
||||
dir_check_device: ;AN022;
|
||||
test byte ptr (DirBuf+find_buf_attr),attr_device ;AC000;
|
||||
jz Dir_fspec_end ;AC000; no, go do normal operation
|
||||
mov ComSw,-2 ;AC000; signal device
|
||||
|
||||
dir_fspec_end:
|
||||
pop si ;AC000; restore position in line
|
||||
jmp short dirscan ;AC000; keep parsing
|
||||
|
||||
set_dir_width:
|
||||
test byte ptr[bits],SwitchW ;AN018; /W already set?
|
||||
jz ok_set_width ;AN018; no - okay to set width
|
||||
mov ax,moreargs_ptr ;AN018; set up too many arguments
|
||||
invoke setup_parse_error_msg ;AN018; set up an error message
|
||||
jmp badparm ;AN018; exit
|
||||
|
||||
ok_set_width:
|
||||
or bits,switchw ;AC000; indicate /w was selected
|
||||
mov linlen,wideperlin ;AC000; Set number of entries per line
|
||||
mov lincnt,wideperlin ;AC000;
|
||||
jmp short dirscan ;AC000; keep parsing
|
||||
|
||||
set_dir_pause:
|
||||
test byte ptr[bits],SwitchP ;AN018; /p already set?
|
||||
jz ok_set_pause ;AN018; no - okay to set width
|
||||
mov ax,moreargs_ptr ;AN018; set up too many arguments
|
||||
invoke setup_parse_error_msg ;AN018; set up an error message
|
||||
jmp badparm ;AN018; exit
|
||||
|
||||
ok_set_pause:
|
||||
or bits,switchp ;AC000; indicate /p was selected
|
||||
push cx ;AN000; save necessary registers
|
||||
push si ;AN000;
|
||||
mov ax,(IOCTL SHL 8) + generic_ioctl_handle ;AN000; get lines per page on display
|
||||
mov bx,stdout ;AN000; lines for stdout
|
||||
mov ch,ioc_sc ;AN000; type is display
|
||||
mov cl,get_generic ;AN000; get information
|
||||
mov dx,offset trangroup:display_ioctl ;AN000;
|
||||
int int_command ;AN000;
|
||||
|
||||
lines_set:
|
||||
dec linperpag ;AN000; lines per actual page should
|
||||
dec linperpag ;AN000; two less than the max
|
||||
mov ax,linperpag ;AN000; get number of lines into
|
||||
mov [fullscr],ax ;AC000; screen line counter
|
||||
pop si ;AN000; restore registers
|
||||
pop cx ;AN000;
|
||||
jmp dirscan ;AC000; keep parsing
|
||||
|
||||
;
|
||||
; The syntax is incorrect. Report only message we can.
|
||||
;
|
||||
BadParm:
|
||||
jmp cerror ;AC000; invalid switches get displayed
|
||||
|
||||
ScanDone:
|
||||
|
||||
;
|
||||
; Find and display the volume ID on the drive.
|
||||
;
|
||||
|
||||
invoke okvolarg ;AC000;
|
||||
mov [filecnt],0 ;AC000; Keep track of how many files found
|
||||
cmp comsw,0 ;AC000; did an error occur?
|
||||
jnz doheader ;AC000; yes - don't bother to fix path
|
||||
|
||||
mov dirflag,-1 ;AN015; set pathcrunch called from DIR
|
||||
invoke pathcrunch ;AC000; set up FCB for dir
|
||||
mov dirflag,0 ;AN015; reset dirflag
|
||||
jc DirCheckPath ;AC015; no CHDIRs worked.
|
||||
jz doheader ;AC015; chdirs worked - path\*.*
|
||||
mov si,[desttail] ;AN015; get filename back
|
||||
jmp short DoRealParse ;AN015; go parse it
|
||||
|
||||
DirCheckPath:
|
||||
mov ax,[msg_numb] ;AN022; get message number
|
||||
cmp ax,0 ;AN022; Is there a message?
|
||||
jnz dir_err_setup ;AN022; yes - there's an error
|
||||
cmp [destisdir],0 ;AC000; Were pathchars found?
|
||||
jz doparse ;AC000; no - no problem
|
||||
inc comsw ;AC000; indicate error
|
||||
jmp short doheader ;AC000; go print header
|
||||
|
||||
DirNF:
|
||||
mov ax,error_file_not_found ;AN022; get message number in control block
|
||||
|
||||
dir_err_setup:
|
||||
mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class
|
||||
mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
|
||||
mov extend_buf_ptr,ax ;AN022;
|
||||
|
||||
DirError:
|
||||
jmp Cerror
|
||||
|
||||
;
|
||||
; We have changed to something. We also have a file. Parse it into a
|
||||
; reasonable form, leaving drive alone, leaving extention alone and leaving
|
||||
; filename alone. We need to special case ... If we are at the root, the
|
||||
; parse will fail and it will give us a file not found instead of file not
|
||||
; found.
|
||||
;
|
||||
DoParse:
|
||||
mov si,offset trangroup:srcbuf ;AN000; Get address of source
|
||||
cmp byte ptr [si+1],colon_char ;AN000; Is there a drive?
|
||||
jnz dir_no_drive ;AN000; no - keep going
|
||||
lodsw ;AN000; bypass drive
|
||||
|
||||
dir_no_drive:
|
||||
cmp [si],".."
|
||||
jnz DoRealParse
|
||||
cmp byte ptr [si+2],0
|
||||
jnz DoRealParse
|
||||
inc ComSw
|
||||
jmp short DoHeader
|
||||
|
||||
DoRealParse:
|
||||
mov di,FCB ; where to put the file name
|
||||
mov ax,(Parse_File_Descriptor SHL 8) OR 0EH
|
||||
int int_command
|
||||
|
||||
;
|
||||
; Check to see if APPEND installed. If it is installed, set all flags
|
||||
; off. This will be reset in the HEADFIX routine
|
||||
;
|
||||
|
||||
DoHeader:
|
||||
mov ax,AppendInstall ;AN020; see if append installed
|
||||
int 2fh ;AN020;
|
||||
cmp al,0 ;AN020; append installed?
|
||||
je DoHeaderCont ;AN020; no - continue
|
||||
mov ax,AppendDOS ;AN020; see if append DOS version right
|
||||
int 2fh ;AN020;
|
||||
cmp ax,-1 ;AN020; append version correct?
|
||||
jne DoHeaderCont ;AN020; no - continue
|
||||
mov ax,AppendGetState ;AN020; Get the state of Append
|
||||
int 2fh ;AN020;
|
||||
push ds ;AN020; save current data segment
|
||||
mov ds,[resseg] ;AN020; get resident segment
|
||||
assume ds:resgroup ;AN020;
|
||||
mov append_state,bx ;AN020; save append state
|
||||
mov append_flag,-1 ;AN020; set append flag
|
||||
xor bx,bx ;AN020; clear out state
|
||||
mov ax,AppendSetState ;AN020; Set the state of Append
|
||||
int 2fh ;AN020; set everything off
|
||||
pop ds ;AN020; save current data segment
|
||||
assume ds:trangroup ;AN020;
|
||||
|
||||
;
|
||||
; Display the header
|
||||
;
|
||||
|
||||
DoHeaderCont:
|
||||
mov al,blank ;AN051; Print out a blank
|
||||
invoke print_char ;AN051; before DIR header
|
||||
invoke build_dir_string ; get current dir string
|
||||
mov dx,offset trangroup:Dirhead_ptr
|
||||
invoke printf_crlf ; bang!
|
||||
|
||||
;
|
||||
; If there were chars left after parse or device, then invalid file name
|
||||
;
|
||||
cmp ComSw,0
|
||||
jz DoSearch ; nothing left; good parse
|
||||
jl DirNFFix ; not .. => error file not found
|
||||
invoke RestUDir
|
||||
mov dx,offset TranGroup:BadCD_ptr
|
||||
jmp Cerror ; was .. => error directory not found
|
||||
DirNFFix:
|
||||
invoke RestUDir
|
||||
jmp DirNF
|
||||
;
|
||||
; We are assured that everything is correct. Let's go and search. Use
|
||||
; attributes that will include finding directories. perform the first search
|
||||
; and reset our directory afterward.
|
||||
;
|
||||
DoSearch:
|
||||
mov byte ptr DS:[FCB-7],0FFH
|
||||
mov byte ptr DS:[FCB-1],010H
|
||||
;
|
||||
; Caution! Since we are using an extended FCB, we will *also* be returning
|
||||
; the directory information as an extended FCB. We must bias all fetches into
|
||||
; DIRBUF by 8 (Extended FCB part + drive)
|
||||
;
|
||||
mov ah,Dir_Search_First
|
||||
mov dx,FCB-7
|
||||
int int_command
|
||||
|
||||
push ax ;AN022; save return state
|
||||
inc al ;AN022; did an error occur?
|
||||
pop ax ;AN022; get return state back
|
||||
jnz found_first_file ;AN022; no error - start dir
|
||||
invoke set_ext_error_msg ;AN022; yes - set up error message
|
||||
push dx ;AN022; save message
|
||||
invoke restudir ;AN022; restore user's dir
|
||||
pop dx ;AN022; restore message
|
||||
cmp word ptr Extend_Buf_Ptr,Error_No_More_Files ;AN022; convert no more files to
|
||||
jnz DirCerrorJ ;AN022; file not found
|
||||
mov Extend_Buf_Ptr,Error_File_Not_Found ;AN022;
|
||||
|
||||
DirCerrorJ: ;AN022;
|
||||
jmp Cerror ;AN022; exit
|
||||
|
||||
;
|
||||
; Restore the user's directory. We preserve, though, the return from the
|
||||
; previous system call for later checking.
|
||||
;
|
||||
|
||||
found_first_file:
|
||||
push ax
|
||||
invoke restudir
|
||||
pop ax
|
||||
;
|
||||
; Main scanning loop. Entry has AL = Search first/next error code. Test for
|
||||
; no more.
|
||||
;
|
||||
DIRSTART:
|
||||
inc al ; FF = file not found
|
||||
jnz Display
|
||||
jmp DirDone ; Either an error or we are finished
|
||||
;
|
||||
; Note that we've seen a file and display the found file.
|
||||
;
|
||||
|
||||
Display:
|
||||
inc [filecnt] ; Keep track of how many we find
|
||||
mov si,offset trangroup:dirbuf+8 ; SI -> information returned by sys call
|
||||
call shoname
|
||||
;
|
||||
; If we are displaying in wide mode, do not output the file info
|
||||
;
|
||||
test byte ptr[bits],SwitchW ; W switch set?
|
||||
jz DirTest
|
||||
jmp nexent ; If so, no size, date, or time
|
||||
|
||||
;
|
||||
; Test for directory.
|
||||
;
|
||||
DirTest:
|
||||
test [dirbuf+8].dir_attr,attr_directory
|
||||
jz fileent
|
||||
;
|
||||
; We have a directory. Display the <DIR> field in place of the file size
|
||||
;
|
||||
mov dx,offset trangroup:Dmes_ptr
|
||||
call std_printf
|
||||
jmp short nofsiz
|
||||
;
|
||||
; We have a file. Display the file size
|
||||
;
|
||||
fileent:
|
||||
mov dx,[DirBuf+8].dir_size_l
|
||||
mov file_size_low,dx
|
||||
mov dx,[DirBuf+8].dir_size_h
|
||||
mov file_size_high,dx
|
||||
mov dx,offset trangroup:disp_file_size_ptr
|
||||
call std_printf
|
||||
;
|
||||
; Display time and date of last modification
|
||||
;
|
||||
nofsiz:
|
||||
mov ax,[DirBuf+8].dir_date ; Get date
|
||||
;
|
||||
; If the date is 0, then we have found a 1.x level diskette. We skip the
|
||||
; date/time fields as 1.x did not have them.
|
||||
;
|
||||
or ax,ax
|
||||
jz nexent ; Skip if no date
|
||||
mov bx,ax
|
||||
and ax,1FH ; get day
|
||||
mov dl,al
|
||||
mov ax,bx
|
||||
mov cl,5
|
||||
shr ax,cl ; Align month
|
||||
and al,0FH ; Get month
|
||||
mov dh,al
|
||||
mov cl,bh
|
||||
shr cl,1 ; Align year
|
||||
xor ch,ch
|
||||
add cx,80 ; Relative 1980
|
||||
cmp cl,100
|
||||
jb millenium
|
||||
sub cl,100
|
||||
|
||||
millenium:
|
||||
xchg dh,dl ;AN000; switch month & day
|
||||
mov DirDat_yr,cx ;AC000; put year into message control block
|
||||
mov DirDat_mo_day,dx ;AC000; put month and day into message control block
|
||||
mov cx,[DirBuf+8].dir_time ; Get time
|
||||
jcxz prbuf ; Time field present?
|
||||
shr cx,1
|
||||
shr cx,1
|
||||
shr cx,1
|
||||
shr cl,1
|
||||
shr cl,1 ; Hours in CH, minutes in CL
|
||||
xchg ch,cl ;AN000; switch hours & minutes
|
||||
mov DirTim_hr_min,cx ;AC000; put hours and minutes into message subst block
|
||||
|
||||
prbuf:
|
||||
mov dx,offset trangroup:DirDatTim_ptr
|
||||
call std_printf
|
||||
invoke crlf2 ;AC066;end the line
|
||||
dec byte ptr [fullscr] ;AC066;count the line
|
||||
jnz endif04 ;AN066;IF the last on the screen THEN
|
||||
call check_for_P ;AN066; pause if /P requested
|
||||
endif04: ;AN066;
|
||||
jmp scroll ; If not, just continue
|
||||
;AD061; mov DirDat_yr,0 ;AC000; reset year, month and day
|
||||
;AD061; mov DirDat_mo_day,0 ;AC000; in control block
|
||||
;AD061; mov DirTim_hr_min,0 ;AC000; reset hour & minute in control block
|
||||
;
|
||||
; We are done displaying an entry. The code between "noexent:" and "scroll:"
|
||||
; is only for /W case.
|
||||
;
|
||||
nexent:
|
||||
mov bl,[lincnt] ;AN066;save for check for first entry on line
|
||||
dec [lincnt] ;count this entry on the line
|
||||
jnz else01 ;AX066;IF last entry on line THEN
|
||||
mov al,[linlen]
|
||||
mov [lincnt],al
|
||||
invoke crlf2
|
||||
cmp [fullscr],0 ;AC066;IF have filled the screen THEN
|
||||
jnz endif02 ;AN066;
|
||||
call check_for_P ;AN066; reinitialize fullscr,
|
||||
endif02: ;AN066; IF P requested THEN pause
|
||||
jmp short endif01 ;AN066;
|
||||
else01: ;AN066;ELSE since screen not full
|
||||
cmp bl,[linlen] ;AN066; IF starting new line THEN
|
||||
jne endif03 ; count the line
|
||||
dec byte ptr [fullscr] ;AN066; ENDIF
|
||||
endif03: ;AC066;We are outputting on the same line, between fields, we tab.
|
||||
mov dx,offset trangroup:tab_ptr ;Output a tab
|
||||
call std_printf
|
||||
endif01: ;AX066;
|
||||
;
|
||||
; All we need to do now is to get the next directory entry.
|
||||
;
|
||||
scroll:
|
||||
mov ah,Dir_Search_Next
|
||||
mov dx,FCB-7 ; DX -> Unopened FCB
|
||||
int int_command ; Search for a file to match FCB
|
||||
jmp DirStart
|
||||
;
|
||||
; If no files have been found, display a not-found message
|
||||
;
|
||||
DirDone:
|
||||
invoke get_ext_error_number ;AN022; get the extended error number
|
||||
cmp ax,error_no_more_files ;AN022; was error file not found?
|
||||
jnz dir_err_setup_jmp ;AN022; no - setup error message
|
||||
test [filecnt],-1
|
||||
jnz Trailer
|
||||
mov ax,error_file_not_found ;AN022;
|
||||
|
||||
dir_err_setup_jmp: ;AN022;
|
||||
jmp dir_err_setup ;AN022; go setup error msg & print it
|
||||
;
|
||||
; If we have printed the maximum number of files per line, terminate it with
|
||||
; CRLF.
|
||||
;
|
||||
Trailer:
|
||||
mov al,[linlen]
|
||||
cmp al,[lincnt] ; Will be equal if just had CR/LF
|
||||
jz mmessage
|
||||
invoke crlf2
|
||||
cmp [fullscr],0 ;AN066;IF on last line of screen THEN
|
||||
jnz endif06 ;AN066; pause before going on
|
||||
call check_for_P ;AN066; to number and freespace
|
||||
endif06: ;AN066; displays
|
||||
|
||||
mmessage:
|
||||
mov dx,offset trangroup:Dirmes_ptr
|
||||
mov si,[filecnt]
|
||||
mov dir_num,si
|
||||
call std_printf
|
||||
mov ah,Get_Drive_Freespace
|
||||
mov dl,byte ptr DS:[FCB]
|
||||
int int_command
|
||||
cmp ax,-1
|
||||
retz
|
||||
mul cx ; AX is bytes per cluster
|
||||
mul bx
|
||||
mov bytes_free,ax ;AC000;
|
||||
mov bytes_free+2,dx ;AC000;
|
||||
MOV DX,OFFSET TRANGROUP:BYTMES_ptr
|
||||
jmp std_printf
|
||||
|
||||
shoname:
|
||||
mov di,offset trangroup:charbuf
|
||||
mov cx,8
|
||||
rep movsb
|
||||
mov al,' '
|
||||
stosb
|
||||
mov cx,3
|
||||
rep movsb
|
||||
xor ax,ax
|
||||
stosb
|
||||
push dx
|
||||
mov dx,offset trangroup:charbuf
|
||||
mov string_ptr_2,dx
|
||||
mov dx,offset trangroup:string_buf_ptr
|
||||
call std_printf
|
||||
pop DX
|
||||
return
|
||||
|
||||
check_for_P PROC NEAR ;AN066;
|
||||
|
||||
test byte ptr[bits],SwitchP ;P switch present?
|
||||
jz endif05 ;AN066;
|
||||
mov ax,linperpag ;AN000; transfer lines per page
|
||||
mov [fullscr],ax ;AC000; to fullscr
|
||||
invoke Pause
|
||||
endif05:
|
||||
ret ;AN066;
|
||||
|
||||
check_for_P ENDP ;AN066;
|
||||
|
||||
trancode ends
|
||||
end
|
||||
730
v4.0/src/CMD/COMMAND/TCMD1B.ASM
Normal file
730
v4.0/src/CMD/COMMAND/TCMD1B.ASM
Normal file
@@ -0,0 +1,730 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)tcmd1b.asm 1.1 85/05/14
|
||||
; SCCSID = @(#)tcmd1b.asm 1.1 85/05/14
|
||||
TITLE PART4 COMMAND Transient routines.
|
||||
|
||||
; Internal commands DIR,PAUSE,ERASE,TYPE,VOL,VER
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE DOSSYM.INC
|
||||
INCLUDE comseg.asm
|
||||
INCLUDE comsw.asm ;AC000;
|
||||
INCLUDE comequ.asm
|
||||
INCLUDE ioctl.inc ;AN000;
|
||||
INCLUDE ea.inc ;AN030;
|
||||
.list
|
||||
.cref
|
||||
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN badcpmes_ptr:word ;AC022;
|
||||
EXTRN Extend_buf_ptr:word ;AC000;
|
||||
EXTRN Extend_buf_sub:byte ;AN000;
|
||||
EXTRN inornot_ptr:word
|
||||
EXTRN msg_disp_class:byte ;AC000;
|
||||
EXTRN parse_erase:byte ;AC000;
|
||||
EXTRN parse_mrdir:byte ;AC000;
|
||||
EXTRN parse_rename:byte ;AC000;
|
||||
EXTRN parse_vol:byte ;AC000;
|
||||
EXTRN PauseMes_ptr:word
|
||||
EXTRN renerr_ptr:word
|
||||
EXTRN slash_p_syn:word ;AC000;
|
||||
EXTRN volmes_ptr:word ;AC000;
|
||||
EXTRN volmes_ptr_2:word ;AC000;
|
||||
EXTRN volsermes_ptr:word ;AC000;
|
||||
EXTRN xa_cp:byte ;AN030;
|
||||
TRANDATA ENDS
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN bytcnt:word
|
||||
EXTRN charbuf:byte
|
||||
EXTRN comsw:word
|
||||
EXTRN cpyflag:byte ;AC000;
|
||||
EXTRN curdrv:byte
|
||||
EXTRN destinfo:byte
|
||||
EXTRN destisdir:byte
|
||||
EXTRN dirbuf:byte
|
||||
EXTRN msg_numb:word ;AN022;
|
||||
EXTRN one_char_val:byte
|
||||
EXTRN parse1_addr:dword ;AN000;
|
||||
EXTRN parse1_syn:word ;AN000;
|
||||
EXTRN srcbuf:byte ;AN000;
|
||||
EXTRN string_ptr_2:word ;AN000;
|
||||
EXTRN TPA:word
|
||||
EXTRN vol_drv:byte
|
||||
EXTRN vol_ioctl_buf:byte ;AC000;
|
||||
EXTRN vol_label:byte ;AC000;
|
||||
EXTRN vol_serial:dword ;AC000;
|
||||
EXTRN xa_cp_out:byte ;AN030;
|
||||
EXTRN xa_cp_length:word ;AN030;
|
||||
EXTRN xa_list_attr:word ;AC030;
|
||||
EXTRN zflag:byte
|
||||
TRANSPACE ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC BYTE
|
||||
|
||||
ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
|
||||
;---------------
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN arg:byte ; the arg structure!
|
||||
transpace ends
|
||||
;---------------
|
||||
|
||||
EXTRN cerror:near
|
||||
EXTRN error_output:near
|
||||
EXTRN notest2:near
|
||||
EXTRN slashp_erase:near ;AN000;
|
||||
EXTRN std_printf:near
|
||||
EXTRN tcommand:near
|
||||
|
||||
PUBLIC badpath_err ;AN022;
|
||||
PUBLIC crename
|
||||
PUBLIC erase
|
||||
PUBLIC extend_setup ;AN022;
|
||||
PUBLIC Get_ext_error_number ;AN022;
|
||||
PUBLIC Get_file_code_page_tag ;AN000;
|
||||
PUBLIC pause
|
||||
PUBLIC Set_ext_error_msg ;AN000;
|
||||
PUBLIC set_file_code_page ;AN000;
|
||||
PUBLIC typefil
|
||||
PUBLIC volume
|
||||
|
||||
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
break Pause
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
PAUSE:
|
||||
mov dx,offset trangroup:pausemes_ptr
|
||||
call std_printf
|
||||
invoke GetKeystroke
|
||||
invoke crlf2
|
||||
return
|
||||
|
||||
break Erase
|
||||
|
||||
;****************************************************************
|
||||
;*
|
||||
;* ROUTINE: DEL/ERASE - erase file(s)
|
||||
;*
|
||||
;* FUNCTION: PARSE command line for file or path name and /P
|
||||
;* and invoke PATHCRUNCH. If an error occurs, set
|
||||
;* up an error message and transfer control to CERROR.
|
||||
;* Otherwise, transfer control to NOTEST2 if /P not
|
||||
;* entered or SLASHP_ERASE if /P entered.
|
||||
;*
|
||||
;* INPUT: command line at offset 81H
|
||||
;*
|
||||
;* OUTPUT: if no error:
|
||||
;* FCB at 5ch set up with filename(s) entered
|
||||
;* Current directory set to entered directory
|
||||
;*
|
||||
;****************************************************************
|
||||
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
ERASE:
|
||||
mov si,81H ;AC000; get command line
|
||||
mov comsw,0 ;AN000; clear switch indicator
|
||||
mov di,offset trangroup:parse_erase ;AN000; Get adderss of PARSE_erase
|
||||
xor cx,cx ;AN000; clear cx,dx
|
||||
|
||||
erase_scan:
|
||||
xor dx,dx ;AN000;
|
||||
invoke parse_with_msg ;AC018; call parser
|
||||
cmp ax,end_of_line ;AN000; are we at end of line?
|
||||
jz good_line ;AN000; yes - done parsing
|
||||
cmp ax,result_no_error ;AC000; did we have an error?
|
||||
jnz errj2 ;AC000; yes exit
|
||||
|
||||
cmp parse1_syn,offset trangroup:slash_p_syn ;AN000; was /P entered?
|
||||
je set_erase_prompt ;AN000; yes - go set prompt
|
||||
|
||||
;
|
||||
; Must be filespec since no other matches occurred. move filename to srcbuf
|
||||
;
|
||||
push si ;AC000; save position in line
|
||||
lds si,parse1_addr ;AC000; get address of filespec
|
||||
cmp byte ptr[si+1],colon_char ;AC000; drive specified?
|
||||
jnz Erase_drive_ok ;AC000; no - continue
|
||||
cmp byte ptr[si+2],end_of_line_out ;AC000; was only drive entered?
|
||||
jnz erase_drive_ok ;AC000; no - continue
|
||||
mov ax,error_file_not_found ;AN022; get message number in control block
|
||||
jmp short extend_setup ;AC000; exit
|
||||
|
||||
erase_drive_ok:
|
||||
invoke move_to_srcbuf ;AC000; move to srcbuf
|
||||
pop si ;AC000; get position back
|
||||
jmp short erase_scan ;AN000; continue parsing
|
||||
|
||||
set_erase_prompt:
|
||||
cmp comsw,0 ;AN018; was /P already entered?
|
||||
jz ok_to_set_erase_prompt ;AN018; no go set switch
|
||||
mov ax,moreargs_ptr ;AN018; set up too many arguments
|
||||
invoke setup_parse_error_msg ;AN018; set up an error message
|
||||
jmp short errj2 ;AN018; exit
|
||||
|
||||
ok_to_set_erase_prompt: ;AN018;
|
||||
inc comsw ;AN000; indicate /p specified
|
||||
jmp short erase_scan ;AN000; continue parsing
|
||||
|
||||
good_line: ;G We know line is good
|
||||
invoke pathcrunch
|
||||
jnc checkdr
|
||||
mov ax,[msg_numb] ;AN022; get message number
|
||||
cmp ax,0 ;AN022; was message flag set?
|
||||
jnz extend_setup ;AN022; yes - print out message
|
||||
cmp [destisdir],0 ; No CHDIRs worked
|
||||
jnz badpath_err ;AC022; see if they should have
|
||||
|
||||
checkdr:
|
||||
cmp comsw,0 ;AN000; was /p specified
|
||||
jz notest2j ;AN000; no - go to notest2
|
||||
jmp slashp_erase ;AN000; yes - go to slashp_erase
|
||||
|
||||
notest2j:
|
||||
jmp notest2
|
||||
|
||||
badpath_err: ;AN022; "Path not found" message
|
||||
mov ax,error_path_not_found ;AN022; set up error number
|
||||
|
||||
extend_setup: ;AN022;
|
||||
mov msg_disp_class,ext_msg_class ;AN022; set up extended error msg class
|
||||
mov dx,offset TranGroup:Extend_Buf_ptr ;AC022; get extended message pointer
|
||||
mov Extend_Buf_ptr,ax ;AN022; get message number in control block
|
||||
errj2: ;AC022; exit jump
|
||||
jmp Cerror ;AN022;
|
||||
|
||||
break Rename
|
||||
|
||||
; ****************************************************************
|
||||
; *
|
||||
; * ROUTINE: CRENAME - rename file(s)
|
||||
; *
|
||||
; * FUNCTION: PARSE command line for one full filespec and one
|
||||
; * filename. Invoke PATHCRUNCH on the full filespec.
|
||||
; * Make sure the second filespec only contains a
|
||||
; * filename. If both openands are valid, attempt
|
||||
; * to rename the file.
|
||||
; *
|
||||
; * INPUT: command line at offset 81H
|
||||
; *
|
||||
; * OUTPUT: none
|
||||
; *
|
||||
; ****************************************************************
|
||||
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
CRENAME:
|
||||
|
||||
mov si,81H ;AC000; Point to command line
|
||||
mov di,offset trangroup:parse_rename;AN000; Get adderss of PARSE_RENAME
|
||||
xor cx,cx ;AN000; clear cx,dx
|
||||
xor dx,dx ;AN000;
|
||||
invoke parse_with_msg ;AC018; call parser
|
||||
cmp ax,result_no_error ;AC000; did we have an error?
|
||||
jz crename_no_parse_error ;AC000; no - continue
|
||||
JMP crename_parse_error ;AC000; Yes, fail. (need long jump)
|
||||
|
||||
;
|
||||
; Get first file name returned from parse into our buffer
|
||||
;
|
||||
crename_no_parse_error:
|
||||
push si ;AN000; save position in line
|
||||
lds si,parse1_addr ;AN000; get address of filespec
|
||||
invoke move_to_srcbuf ;AN000; move to srcbuf
|
||||
pop si ;AN000; restore position in line
|
||||
|
||||
xor dx,dx ;AN000; clear dx
|
||||
invoke parse_with_msg ;AC018; call parser
|
||||
cmp ax,result_no_error ;AN000; did we have an error?
|
||||
JNZ crename_parse_error ;AN000; Yes, fail.
|
||||
|
||||
;
|
||||
; Check the second file name for drive letter colon
|
||||
;
|
||||
push si ;AN000; save position in line
|
||||
lds si,parse1_addr ;AC000; get address of path
|
||||
|
||||
mov al,':' ;AC000;
|
||||
cmp [si+1],al ;AC000; Does the 2nd parm have a drive spec?
|
||||
jnz ren_no_drive ;AN000; Yes, error
|
||||
mov msg_disp_class,parse_msg_class ;AN000; set up parse error msg class
|
||||
mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
|
||||
mov Extend_Buf_ptr,BadParm_ptr ;AN000; get "Invalid parameter" message number
|
||||
|
||||
pop si ;AN000;
|
||||
crename_parse_error: ;AC022;
|
||||
jmp short errj ;AC000;
|
||||
|
||||
;
|
||||
; Get second file name returned from parse into the fCB. Save
|
||||
; character after file name so we can later check to make sure it
|
||||
; isn't a path character.
|
||||
;
|
||||
|
||||
ren_no_drive:
|
||||
mov di,FCB+10H ;AC000; set up to parse second file name
|
||||
mov ax,(Parse_File_Descriptor SHL 8) OR 01H ;AC000;
|
||||
int int_command ;AC000; do the function
|
||||
lodsb ;AC000; Load char after filename
|
||||
mov one_char_val,al ;AN000; save char after filename
|
||||
pop si ;AN000; get line position back
|
||||
|
||||
;
|
||||
; We have source and target. See if any args beyond.
|
||||
;
|
||||
|
||||
mov di,offset trangroup:parse_rename;AC000; get address of parse_rename
|
||||
invoke parse_check_eol ;AC000; are we at end of line?
|
||||
jnz crename_parse_error ;AN000; no, fail.
|
||||
|
||||
invoke pathcrunch
|
||||
mov dx,offset trangroup:badcpmes_ptr
|
||||
jz errj2 ; If 1st parm a dir, print error msg
|
||||
jnc notest3
|
||||
mov ax,[msg_numb] ;AN022; get message number
|
||||
cmp ax,0 ;AN022; was message flag set?
|
||||
jnz extend_setup ;AN022; yes - print out message
|
||||
cmp [destisdir],0 ; No CHDIRs worked
|
||||
jz notest3 ; see if they should have
|
||||
Jmp badpath_err ;AC022; set up error
|
||||
|
||||
notest3:
|
||||
mov al,one_char_val ;AN000; move char into AX
|
||||
mov dx,offset trangroup:inornot_ptr ; Load invalid fname error ptr
|
||||
invoke pathchrcmp ; Is the char in al a path sep?
|
||||
jz errj ; Yes, error - 2nd arg must be
|
||||
; filename only.
|
||||
|
||||
mov ah,FCB_Rename
|
||||
mov dx,FCB
|
||||
int int_command
|
||||
cmp al, 0FFH ; Did an error occur??
|
||||
jnz renameok
|
||||
|
||||
invoke get_ext_error_number ;AN022; get extended error
|
||||
SaveReg <AX> ;AC022; Save results
|
||||
mov al, 0FFH ; Restore original error state
|
||||
|
||||
renameok:
|
||||
push ax
|
||||
invoke restudir
|
||||
pop ax
|
||||
inc al
|
||||
retnz
|
||||
|
||||
RestoreReg <AX> ;AC022; get the error number back
|
||||
cmp ax,error_file_not_found ;AN022; error file not found?
|
||||
jz use_renerr ;AN022; yes - use generic error message
|
||||
cmp ax,error_access_denied ;AN022; error file not found?
|
||||
jz use_renerr ;AN022; yes - use generic error message
|
||||
jmp extend_setup ;AN022; need long jump - use extended error
|
||||
|
||||
use_renerr:
|
||||
mov dx,offset trangroup:RenErr_ptr ;AC022;
|
||||
|
||||
ERRJ:
|
||||
jmp Cerror
|
||||
|
||||
ret56: ret
|
||||
|
||||
break Type
|
||||
|
||||
;****************************************************************
|
||||
;*
|
||||
;* ROUTINE: TYPEFIL - Display the contents of a file to the
|
||||
;* standard output device
|
||||
;*
|
||||
;* SYNTAX: TYPE filespec
|
||||
;*
|
||||
;* FUNCTION: If a valid filespec is found, read the file until
|
||||
;* 1Ah and display the contents to STDOUT.
|
||||
;*
|
||||
;* INPUT: command line at offset 81H
|
||||
;*
|
||||
;* OUTPUT: none
|
||||
;*
|
||||
;****************************************************************
|
||||
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
TYPEFIL:
|
||||
mov si,81H
|
||||
mov di,offset trangroup:parse_mrdir ;AN000; Get adderss of PARSE_MRDIR
|
||||
xor cx,cx ;AN000; clear cx,dx
|
||||
xor dx,dx ;AN000;
|
||||
invoke parse_with_msg ;AC018; call parser
|
||||
cmp ax,result_no_error ;AC000; did we have an error?
|
||||
jnz typefil_parse_error ;AN000; yes - issue error message
|
||||
|
||||
push si ;AC000; save position in line
|
||||
lds si,parse1_addr ;AC000; get address of filespec
|
||||
invoke move_to_srcbuf ;AC000; move to srcbuf
|
||||
pop si ;AC000; get position back
|
||||
mov di,offset trangroup:parse_mrdir ;AC000; get address of parse_mrdir
|
||||
invoke parse_check_eol ;AC000; are we at end of line?
|
||||
jz gottarg ;AC000; yes - continue
|
||||
|
||||
typefil_parse_error: ;AN000; no - set up error message and exit
|
||||
jmp Cerror
|
||||
|
||||
gottarg:
|
||||
invoke setpath
|
||||
test [destinfo],00000010b ; Does the filespec contain wildcards
|
||||
jz nowilds ; No, continue processing
|
||||
mov dx,offset trangroup:inornot_ptr ; Yes, report error
|
||||
jmp Cerror
|
||||
nowilds:
|
||||
mov ax,ExtOpen SHL 8 ;AC000; open the file
|
||||
mov bx,read_open_mode ;AN000; get open mode for TYPE
|
||||
xor cx,cx ;AN000; no special files
|
||||
mov dx,read_open_flag ;AN000; set up open flags
|
||||
mov di,-1 ;AN030; no parm list
|
||||
mov si,offset trangroup:srcbuf ;AN030; get file name
|
||||
int int_command
|
||||
jnc typecont ; If open worked, continue. Otherwise load
|
||||
|
||||
Typerr: ;AN022;
|
||||
push cs ;AN022; make sure we have local segment
|
||||
pop ds ;AN022;
|
||||
invoke set_ext_error_msg ;AN022;
|
||||
|
||||
Typerr2: ;AN022;
|
||||
mov string_ptr_2,offset trangroup:srcbuf ;AC022; get address of failed string
|
||||
mov Extend_buf_sub,one_subst ;AC022; put number of subst in control block
|
||||
jmp cerror ;AC022; exit
|
||||
|
||||
typecont:
|
||||
mov bx,ax ;AC000; get Handle
|
||||
mov cx,stdout ;AN000; set output to STDOUT
|
||||
call set_file_code_page ;AN000; Set code page on output device
|
||||
jc typerr2 ;AN022; exit if error
|
||||
|
||||
mov zflag,0 ; Reset ^Z flag
|
||||
mov ds,[TPA]
|
||||
xor dx,dx
|
||||
ASSUME DS:NOTHING
|
||||
|
||||
typelp:
|
||||
cmp cs:[zflag],0 ;AC050; Is the ^Z flag set?
|
||||
retnz ; Yes, return
|
||||
mov cx,cs:[bytcnt] ;AC056; No, continue
|
||||
mov ah,read
|
||||
int int_command
|
||||
jc typerr ;AN022; Exit if error
|
||||
mov cx,ax
|
||||
jcxz typelp_ret ;AC000; exit if nothing read
|
||||
push ds
|
||||
pop es ; Check to see if a ^Z was read.
|
||||
assume es:nothing
|
||||
xor di,di
|
||||
push ax
|
||||
mov al,1ah
|
||||
repnz scasb
|
||||
pop ax
|
||||
xchg ax,cx
|
||||
cmp ax,0
|
||||
jnz foundz ; Yes, handle it
|
||||
cmp byte ptr [di-1],1ah ; No, double check
|
||||
jnz typecont2 ; No ^Z, continue
|
||||
|
||||
foundz:
|
||||
sub cx,ax ; Otherwise change cx so that only those
|
||||
dec cx ; bytes up to but NOT including the ^Z
|
||||
push cs ; will be typed.
|
||||
pop es
|
||||
assume es:trangroup
|
||||
not zflag ; Turn on ^Z flag so that the routine
|
||||
|
||||
typecont2: ; will quit after this write.
|
||||
push bx
|
||||
mov bx,1
|
||||
mov ah,write
|
||||
int int_command
|
||||
pop bx
|
||||
jc Error_outputj
|
||||
cmp ax,cx
|
||||
jz typelp
|
||||
dec cx
|
||||
cmp ax,cx
|
||||
retz ; One less byte OK (^Z)
|
||||
|
||||
Error_outputj:
|
||||
mov bx,1
|
||||
mov ax,IOCTL SHL 8
|
||||
int int_command
|
||||
test dl,devid_ISDEV
|
||||
retnz ; If device, no error message
|
||||
jmp error_output
|
||||
|
||||
typelp_ret:
|
||||
ret
|
||||
|
||||
break Volume
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
;
|
||||
; VOLUME command displays the volume ID on the specified drive
|
||||
;
|
||||
VOLUME:
|
||||
|
||||
mov si,81H
|
||||
mov di,offset trangroup:parse_vol ;AN000; Get adderss of PARSE_VOL
|
||||
xor cx,cx ;AN000; clear cx,dx
|
||||
xor dx,dx ;AN000;
|
||||
invoke parse_with_msg ;AC018; call parser
|
||||
cmp ax,end_of_line ;AC000; are we at end of line?
|
||||
jz OkVolArg ;AC000; Yes, display default volume ID
|
||||
cmp ax,result_no_error ;AC000; did we have an error?
|
||||
jnz BadVolArg ;AC000; Yes, fail.
|
||||
;
|
||||
; We have parsed off the drive. See if there are any more chars left
|
||||
;
|
||||
|
||||
mov di,offset trangroup:parse_vol ;AC000; get address of parse_vol
|
||||
xor dx,dx ;AC000;
|
||||
invoke parse_check_eol ;AC000; call parser
|
||||
jz OkVolArg ;AC000; yes, end of road
|
||||
;
|
||||
; The line was not interpretable. Report an error.
|
||||
;
|
||||
badvolarg:
|
||||
jmp Cerror
|
||||
;
|
||||
; Find the Volume ID on the disk.
|
||||
;
|
||||
PUBLIC OkVolArg
|
||||
OKVOLARG:
|
||||
invoke crlf2
|
||||
mov al,blank ;AN051; Print out a blank
|
||||
invoke print_char ;AN051; before volume message
|
||||
push ds
|
||||
pop es
|
||||
;
|
||||
; Volume IDs are only findable via extended FCBs or find_first with attributes
|
||||
; of volume_id ONLY.
|
||||
;
|
||||
|
||||
mov di,FCB-7 ; Point to extended FCB beginning
|
||||
mov al,-1 ; Tag to indicate Extention
|
||||
stosb
|
||||
xor ax,ax ; Zero padding to volume label
|
||||
stosw
|
||||
stosw
|
||||
stosb
|
||||
mov al,attr_volume_ID ; Look for volume label
|
||||
stosb
|
||||
inc di ; Skip drive byte; it is already set
|
||||
mov cx,11 ; fill in remainder of file
|
||||
mov al,'?'
|
||||
rep stosb
|
||||
;
|
||||
; Set up transfer address (destination of search first information)
|
||||
;
|
||||
mov dx,offset trangroup:dirbuf
|
||||
mov ah,set_DMA
|
||||
int int_command
|
||||
;
|
||||
; Do the search
|
||||
;
|
||||
mov dx,FCB-7
|
||||
mov ah,Dir_Search_First
|
||||
int int_command
|
||||
|
||||
;********************************
|
||||
; Print volume ID info
|
||||
|
||||
push ax ;AC000; AX return from SEARCH_FIRST for VOL ID
|
||||
mov al,DS:[FCB] ;AC000; get drive letter
|
||||
add al,'@'
|
||||
cmp al,'@'
|
||||
jnz drvok
|
||||
mov al,[curdrv]
|
||||
add al,capital_A
|
||||
drvok:
|
||||
mov vol_drv,al ;AC000; get drive letter into argument
|
||||
pop ax ;AC000; get return code back
|
||||
or al,al ;AC000; volume label found?
|
||||
jz Get_vol_name ;AC000; volume label exists - go get it
|
||||
mov dx,offset trangroup:VolMes_ptr_2 ;AC000; set up no volume message
|
||||
jmp short print_serial ;AC000; go print it
|
||||
|
||||
Get_vol_name:
|
||||
mov di,offset trangroup:charbuf
|
||||
mov dx,di
|
||||
mov si,offset trangroup:dirbuf + 8 ;AN000; 3/3/KK
|
||||
mov cx,11 ;AN000; 3/3/KK
|
||||
rep movsb ;AN000; 3/3/KK
|
||||
|
||||
xor al,al ;AC000; store a zero to terminate the string
|
||||
stosb
|
||||
mov dx,offset trangroup:VolMes_ptr ;AC000; set up message
|
||||
|
||||
PRINT_SERIAL:
|
||||
|
||||
;
|
||||
; Attempt to get the volume serial number from the disk. If an error
|
||||
; occurs, do not print volume serial number.
|
||||
;
|
||||
|
||||
push dx ;AN000; save message offset
|
||||
mov ax,(GetSetMediaID SHL 8) ;AC036; Get the volume serial info
|
||||
mov bl,DS:[FCB] ;AN000; get drive number from FCB
|
||||
mov dx,offset trangroup:vol_ioctl_buf ;AN000;target buffer
|
||||
int int_command ;AN000; do the call
|
||||
pop dx ;AN000; get message offset back
|
||||
jc printvol_end ;AN000; if error, just go print label
|
||||
call std_printf ;AC000; go print volume message
|
||||
mov al,blank ;AN051; Print out a blank
|
||||
invoke print_char ;AN051; before volume message
|
||||
mov dx,offset trangroup:VolSerMes_ptr ;AN000; get serial number message
|
||||
|
||||
printvol_end:
|
||||
jmp std_printf ;AC000; go print and exit
|
||||
|
||||
;****************************************************************
|
||||
;*
|
||||
;* ROUTINE: Set file Code page
|
||||
;*
|
||||
;* FUNCTION: Check CPSW status, if CPSW is on, get the file's
|
||||
;* code page and attempt to invoke it on the
|
||||
;* output device.
|
||||
;*
|
||||
;* INPUT: file handle in BX - unless copyflg is set
|
||||
;* handle of output device in CX
|
||||
;*
|
||||
;* OUTPUT: if carry set (code page invoke failed)
|
||||
;* ax = extended error
|
||||
;* otherwise
|
||||
;* ax modified
|
||||
;*
|
||||
;*
|
||||
;****************************************************************
|
||||
|
||||
Set_file_code_page proc near ;AN000;
|
||||
|
||||
push bx ;AN000; save registers
|
||||
push di ;AN000;
|
||||
push dx ;AN000;
|
||||
|
||||
cmp cpyflag,1 ;AN000; were we called from COPY?
|
||||
jz Already_have_cp ;AN000; yes - already have code page
|
||||
call get_file_code_page_tag ;AN000; get the file's code page
|
||||
jc cp_set_error ;AN000; if error - just continue
|
||||
|
||||
already_have_cp: ;AN000; See what was returned.
|
||||
mov ax,(file_times SHL 8)+set_XA ;AC030; set code page
|
||||
mov di,offset trangroup:xa_cp_out ;AC030; offset of attr list
|
||||
mov bx,cx ;AN000; get handle of output device
|
||||
int int_command ;AN000;
|
||||
jnc set_file_cp_end ;AN000; all okay - return
|
||||
cp_set_error:
|
||||
pop dx ;AC030; we don't restore DX for error -
|
||||
call Set_Ext_Error_msg ;AN000; we return error message
|
||||
jmp short set_file_cp_exit ;AC030; exit
|
||||
|
||||
set_file_cp_end: ;AN000; finished
|
||||
pop dx ;AN000; restore registers
|
||||
|
||||
set_file_cp_exit:
|
||||
pop di ;AN000;
|
||||
pop bx ;AN000;
|
||||
|
||||
ret ;AN000; return
|
||||
|
||||
Set_file_code_page endp ;AN000;
|
||||
|
||||
|
||||
;****************************************************************
|
||||
;*
|
||||
;* ROUTINE: Get file Code page tag
|
||||
;*
|
||||
;* FUNCTION: Get code page file attribute.
|
||||
;*
|
||||
;* INPUT: file handle in BX
|
||||
;*
|
||||
;* OUTPUT: if error - carry set
|
||||
;* otherwise - xa_list_attr set to file's code page
|
||||
;*
|
||||
;* AX and DI modified
|
||||
;*
|
||||
;****************************************************************
|
||||
|
||||
|
||||
Get_file_code_page_tag proc near ;AN000;
|
||||
|
||||
push cx ;AN030;
|
||||
push si ;AN030;
|
||||
push di ;AN030;
|
||||
mov xa_list_attr,0 ;AN030; initialize code page
|
||||
mov ax,(file_times SHL 8)+get_XA ;AC030; get extended attributes
|
||||
mov si,offset trangroup:xa_cp ;AN030; get xa request buffer
|
||||
mov di,offset trangroup:xa_cp_out ;AC030; get xa output buffer
|
||||
mov cx,xa_cp_length ;AN030; length of buffer
|
||||
int int_command ;AN000;
|
||||
pop di ;AN030;
|
||||
pop si ;AN030;
|
||||
pop cx ;AN030;
|
||||
|
||||
ret ;AN000; return
|
||||
|
||||
Get_file_code_page_tag endp ;AN000;
|
||||
|
||||
|
||||
;****************************************************************
|
||||
;*
|
||||
;* ROUTINE: Set_ext_error_msg
|
||||
;*
|
||||
;* FUNCTION: Sets up extended error message for printing
|
||||
;*
|
||||
;* INPUT: return from INT 21
|
||||
;*
|
||||
;* OUTPUT: extended error message set up in extended error
|
||||
;* buffer.
|
||||
;*
|
||||
;****************************************************************
|
||||
|
||||
Set_ext_error_msg proc near ;AN000;
|
||||
|
||||
call get_ext_error_number ;AC022; get the extended error
|
||||
mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class
|
||||
mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
|
||||
mov Extend_Buf_ptr,ax ;AN000; get message number in control block
|
||||
stc ;AN000; make sure carry is set
|
||||
|
||||
ret ;AN000; return
|
||||
|
||||
Set_ext_error_msg endp ;AN000;
|
||||
|
||||
;****************************************************************
|
||||
;*
|
||||
;* ROUTINE: Get_ext_error_number
|
||||
;*
|
||||
;* FUNCTION: Does get extended error function call
|
||||
;*
|
||||
;* INPUT: return from INT 21
|
||||
;*
|
||||
;* OUTPUT: AX - extended error number
|
||||
;*
|
||||
;****************************************************************
|
||||
|
||||
Get_ext_error_number proc near ;AN022;
|
||||
|
||||
SaveReg <BX,CX,DX,SI,DI,BP,ES,DS> ;AN022; save registers
|
||||
mov ah,GetExtendedError ;AN022; get extended error
|
||||
xor bx,bx ;AN022; clear BX
|
||||
int int_command ;AN022;
|
||||
RestoreReg <DS,ES,BP,DI,SI,DX,CX,BX> ;AN022; restore registers
|
||||
|
||||
ret ;AN022; return
|
||||
|
||||
Get_ext_error_number endp ;AN022;
|
||||
|
||||
trancode ends
|
||||
end
|
||||
|
||||
552
v4.0/src/CMD/COMMAND/TCMD2A.ASM
Normal file
552
v4.0/src/CMD/COMMAND/TCMD2A.ASM
Normal file
@@ -0,0 +1,552 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)tcmd2a.asm 4.1 85/06/25
|
||||
; SCCSID = @(#)tcmd2a.asm 4.1 85/06/25
|
||||
TITLE PART5 COMMAND Transient routines.
|
||||
|
||||
INCLUDE comsw.asm
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE DOSSYM.INC
|
||||
INCLUDE comequ.asm
|
||||
INCLUDE comseg.asm
|
||||
include ioctl.inc
|
||||
.list
|
||||
.cref
|
||||
|
||||
|
||||
CODERES SEGMENT PUBLIC BYTE ;AC000;
|
||||
CODERES ENDS
|
||||
|
||||
DATARES SEGMENT PUBLIC BYTE ;AC000;
|
||||
DATARES ENDS
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN arg_buf_ptr:word
|
||||
EXTRN BadCurDrv:byte ;AC000;
|
||||
EXTRN clsstring:byte
|
||||
EXTRN dback_ptr:word
|
||||
EXTRN display_ioctl:word ;AN000;
|
||||
EXTRN display_width:word ;AN000;
|
||||
EXTRN Extend_buf_ptr:word ;AN049;
|
||||
EXTRN linperpag:word ;AN000;
|
||||
EXTRN msg_disp_class:byte ;AN049;
|
||||
EXTRN nulpath_ptr:word
|
||||
EXTRN prompt_table:word
|
||||
EXTRN string_buf_ptr:word ;AC000;
|
||||
EXTRN vermes_ptr:word
|
||||
TRANDATA ENDS
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN Arg_Buf:byte
|
||||
EXTRN bwdbuf:byte
|
||||
EXTRN curdrv:byte
|
||||
EXTRN dirchar:byte
|
||||
EXTRN major_ver_num:word
|
||||
EXTRN minor_ver_num:word
|
||||
EXTRN srcxname:byte ;AN049;
|
||||
EXTRN string_ptr_2:word
|
||||
TRANSPACE ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC BYTE
|
||||
|
||||
ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
|
||||
;---------------
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN arg:byte ; the arg structure!
|
||||
transpace ends
|
||||
;---------------
|
||||
|
||||
EXTRN cerror:near ;AN049;
|
||||
EXTRN crlf2:near
|
||||
EXTRN drvbad:near
|
||||
EXTRN std_printf:near
|
||||
|
||||
PUBLIC build_dir_for_chdir
|
||||
PUBLIC build_dir_for_prompt
|
||||
PUBLIC build_dir_string
|
||||
PUBLIC cls
|
||||
PUBLIC path
|
||||
PUBLIC print_char
|
||||
PUBLIC print_drive
|
||||
PUBLIC print_version
|
||||
PUBLIC print_b
|
||||
PUBLIC print_back
|
||||
PUBLIC print_eq
|
||||
PUBLIC print_esc
|
||||
PUBLIC print_g
|
||||
PUBLIC print_l
|
||||
PUBLIC print_prompt
|
||||
PUBLIC version
|
||||
|
||||
break Version
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
VERSION:
|
||||
call crlf2
|
||||
call print_version
|
||||
jmp crlf2
|
||||
|
||||
print_version:
|
||||
mov ah,Get_version
|
||||
int int_command
|
||||
push ax
|
||||
xor ah,ah
|
||||
mov major_ver_num,ax
|
||||
pop ax
|
||||
xchg ah,al
|
||||
xor ah,ah
|
||||
mov minor_ver_num,ax
|
||||
mov dx,offset trangroup:vermes_ptr
|
||||
jmp std_printf
|
||||
|
||||
print_prompt:
|
||||
push ds
|
||||
push cs
|
||||
pop ds ; MAKE SURE DS IS IN TRANGROUP
|
||||
push es
|
||||
invoke find_prompt ; LOOK FOR PROMPT STRING
|
||||
jc PP0 ; CAN'T FIND ONE
|
||||
cmp byte ptr es:[di],0
|
||||
jnz PP1
|
||||
PP0:
|
||||
call print_drive ; USE DEFAULT PROMPT
|
||||
mov al,sym
|
||||
call print_char
|
||||
jmp short PP5
|
||||
|
||||
PP1:
|
||||
mov al,es:[di] ; GET A CHAR
|
||||
inc di
|
||||
or al,al
|
||||
jz PP5 ; NUL TERMINATED
|
||||
cmp al,dollar ; META CHARACTER?
|
||||
jz PP2 ; NOPE
|
||||
PPP1:
|
||||
call print_char
|
||||
jmp PP1
|
||||
|
||||
PP2:
|
||||
mov al,es:[di]
|
||||
inc di
|
||||
mov bx,offset trangroup:prompt_table-3
|
||||
or al,al
|
||||
jz PP5
|
||||
|
||||
PP3:
|
||||
add bx,3
|
||||
invoke upconv
|
||||
cmp al,[bx]
|
||||
jz PP4
|
||||
cmp byte ptr [bx],0
|
||||
jnz PP3
|
||||
jmp PP1
|
||||
|
||||
PP4:
|
||||
push es
|
||||
push di
|
||||
push cs
|
||||
pop es
|
||||
call [bx+1]
|
||||
pop di
|
||||
pop es
|
||||
jmp PP1
|
||||
|
||||
PP5:
|
||||
pop es ; RESTORE SEGMENTS
|
||||
pop ds
|
||||
return
|
||||
|
||||
|
||||
print_back:
|
||||
mov dx,offset trangroup:dback_ptr
|
||||
jmp std_printf
|
||||
|
||||
print_EQ:
|
||||
mov al,'='
|
||||
jmp short print_char
|
||||
|
||||
print_esc:
|
||||
mov al,1BH
|
||||
jmp short print_char
|
||||
|
||||
print_G:
|
||||
mov al,rabracket
|
||||
jmp short print_char
|
||||
|
||||
print_L:
|
||||
mov al,labracket
|
||||
jmp short print_char
|
||||
|
||||
print_B:
|
||||
mov al,vbar
|
||||
|
||||
print_char:
|
||||
push es
|
||||
push ds
|
||||
pop es
|
||||
push di
|
||||
push dx
|
||||
mov dl,al ;AC000; Get char into al
|
||||
mov ah,Std_CON_output ;AC000; print the char to stdout
|
||||
int int_command ;AC000;
|
||||
pop dx
|
||||
pop di
|
||||
pop es
|
||||
ret
|
||||
|
||||
print_drive:
|
||||
mov ah,Get_Default_drive
|
||||
int int_command
|
||||
add al,capital_A
|
||||
call print_char
|
||||
ret
|
||||
|
||||
ASSUME DS:TRANGROUP,ES:TRANGROUP
|
||||
|
||||
build_dir_for_prompt:
|
||||
xor dl,dl
|
||||
mov si,offset trangroup:bwdbuf
|
||||
mov di,SI
|
||||
mov al,CurDrv
|
||||
add al,'A'
|
||||
mov ah,':'
|
||||
stosw
|
||||
mov al,[dirchar]
|
||||
stosb
|
||||
xchg si,di
|
||||
mov string_ptr_2,di
|
||||
mov ah,Current_dir
|
||||
int int_command
|
||||
mov dx,offset trangroup:string_buf_ptr
|
||||
jnc DoPrint
|
||||
mov dx,offset trangroup:BadCurDrv
|
||||
DoPrint:
|
||||
call std_printf
|
||||
|
||||
ret
|
||||
|
||||
build_dir_for_chdir:
|
||||
call build_dir_string
|
||||
mov dx,offset trangroup:bwdbuf
|
||||
mov string_ptr_2,dx
|
||||
mov dx,offset trangroup:string_buf_ptr
|
||||
call std_printf
|
||||
ret
|
||||
|
||||
build_dir_string:
|
||||
mov dl,ds:[FCB]
|
||||
mov al,DL
|
||||
add al,'@'
|
||||
cmp al,'@'
|
||||
jnz gotdrive
|
||||
add al,[CURDRV]
|
||||
inc al
|
||||
|
||||
gotdrive:
|
||||
push ax
|
||||
mov si,offset trangroup:bwdbuf+3
|
||||
mov ah,Current_dir
|
||||
int int_command
|
||||
jnc dpbisok
|
||||
push cs
|
||||
pop ds
|
||||
jmp drvbad
|
||||
|
||||
dpbisok:
|
||||
mov di,offset trangroup:bwdbuf
|
||||
mov dx,di
|
||||
pop ax
|
||||
mov ah,':'
|
||||
stosw
|
||||
mov al,[dirchar]
|
||||
stosb
|
||||
|
||||
ret
|
||||
|
||||
break Path
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
PATH:
|
||||
xor al,al ;AN049; Set up holding buffer
|
||||
mov di,offset Trangroup:srcxname ;AN049; for PATH while parsing
|
||||
stosb ;AN049; Initialize PATH to null
|
||||
dec di ;AN049; point to the start of buffer
|
||||
invoke PGetarg ; Pre scan for arguments
|
||||
jz disppath ; Print the current path
|
||||
cmp al,semicolon ;AC049; NUL path argument?
|
||||
jnz pathslp ;AC049;
|
||||
inc si ;AN049; point past semicolon
|
||||
jmp short scan_white ;AC049; Yes - make sure nothing else on line
|
||||
|
||||
pathslp: ; Get the user specified path
|
||||
lodsb ; Get a character
|
||||
cmp al,end_of_line_in ;AC049; Is it end of line?
|
||||
jz path_eol ;AC049; yes - end of command
|
||||
|
||||
invoke testkanj ;See if DBCS
|
||||
jz notkanj2 ;No - continue
|
||||
stosb ;AC049; Yes - store the first byte
|
||||
lodsb ;skip second byte of DBCS
|
||||
|
||||
path_hold: ;AN049;
|
||||
stosb ;AC049; Store a byte in the PATH buffer
|
||||
jmp short pathslp ;continue parsing
|
||||
|
||||
notkanj2:
|
||||
invoke upconv ;upper case the character
|
||||
cmp al,semicolon ;AC049; ';' not a delimiter on PATH
|
||||
jz path_hold ;AC049; go store it
|
||||
invoke delim ;delimiter?
|
||||
jnz path_hold ;AC049; no - go store character
|
||||
|
||||
scan_white: ;AN049; make sure were at EOL
|
||||
lodsb ;AN049; get a character
|
||||
cmp al,end_of_line_in ;AN049; end of line?
|
||||
jz path_eol ;AN049; yes - go set path
|
||||
cmp al,blank ;AN049; whitespace?
|
||||
jz scan_white ;AN049; yes - continue scanning
|
||||
cmp al,tab_chr ;AN049; whitespace?
|
||||
jz scan_white ;AN049; yes - continue scanning
|
||||
|
||||
mov dx,offset TranGroup:Extend_Buf_ptr ;AN049; no - set up error message
|
||||
mov Extend_Buf_ptr,MoreArgs_ptr ;AN049; get "Too many parameters" message number
|
||||
mov msg_disp_class,parse_msg_class ;AN049; set up parse error msg class
|
||||
jmp cerror ;AN049;
|
||||
|
||||
path_eol: ;AN049; Parsing was clean
|
||||
xor al,al ;AN049; null terminate the PATH
|
||||
stosb ;AN049; buffer
|
||||
invoke find_path ;AN049; Find PATH in environment
|
||||
invoke delete_path ;AC049; Delete any offending name
|
||||
invoke scan_double_null ;AC049; Scan to end of environment
|
||||
invoke move_name ;AC049; move in PATH=
|
||||
mov si,offset Trangroup:srcxname ;AN049; Set up source as PATH buffer
|
||||
|
||||
store_path: ;AN049; Store the PATH in the environment
|
||||
lodsb ;AN049; Get a character
|
||||
cmp al,end_of_line_out ;AN049; null character?
|
||||
jz got_paths ;AN049; yes - exit
|
||||
invoke store_char ;AN049; no - store character
|
||||
jmp short store_path ;AN049; continue
|
||||
|
||||
got_paths: ;AN049; we're finished
|
||||
xor ax,ax ;null terminate the PATH in
|
||||
stosw ; the environment
|
||||
return
|
||||
|
||||
disppath:
|
||||
invoke find_path ;AN049;
|
||||
call print_path
|
||||
call crlf2
|
||||
return
|
||||
|
||||
print_path:
|
||||
cmp byte ptr es:[di],0
|
||||
jnz path1
|
||||
|
||||
path0:
|
||||
mov dx,offset trangroup:nulpath_ptr
|
||||
push cs
|
||||
pop es
|
||||
push cs
|
||||
pop ds
|
||||
jmp std_printf
|
||||
|
||||
path1:
|
||||
push es
|
||||
pop ds
|
||||
sub di,5
|
||||
mov si,di
|
||||
ASSUME DS:RESGROUP
|
||||
invoke scasb2 ; LOOK FOR NUL
|
||||
cmp cx,0FFH
|
||||
jz path0
|
||||
push cs
|
||||
pop es
|
||||
mov di,offset trangroup:arg_buf
|
||||
mov dx,100h
|
||||
sub dx,cx
|
||||
xchg dx,cx
|
||||
rep movsb
|
||||
mov dx,offset trangroup:arg_buf_ptr
|
||||
push cs
|
||||
pop ds
|
||||
jmp std_printf
|
||||
|
||||
ASSUME DS:TRANGROUP
|
||||
|
||||
break Cls
|
||||
|
||||
; ****************************************************************
|
||||
; *
|
||||
; * ROUTINE: CLS
|
||||
; *
|
||||
; * FUNCTION: Clear the screen using INT 10h. If ANSI.SYS is
|
||||
; * installed, send a control string to clear the
|
||||
; * screen.
|
||||
; *
|
||||
; * INPUT: command line at offset 81H
|
||||
; *
|
||||
; * OUTPUT: none
|
||||
; *
|
||||
; ****************************************************************
|
||||
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
ANSI_installed equ 0ffh
|
||||
|
||||
CLS:
|
||||
mov ah,Mult_ANSI ;AN000; see if ANSI.SYS installed
|
||||
mov al,0 ;AN000;
|
||||
int 2fh ;AN000;
|
||||
cmp al,ANSI_installed ;AN000;
|
||||
jz ansicls ;AN000; installed - go do ANSI CLS
|
||||
|
||||
check_lines:
|
||||
mov ax,(IOCTL SHL 8) + generic_ioctl_handle ;AN000; get lines per page on display
|
||||
mov bx,stdout ;AN000; lines for stdout
|
||||
mov ch,ioc_sc ;AN000; type is display
|
||||
mov cl,get_generic ;AN000; get information
|
||||
mov dx,offset trangroup:display_ioctl ;AN000;
|
||||
int int_command ;AN000;
|
||||
jc no_variable ;AN000; function had error, use default
|
||||
mov ax,linperpag ;AN000; get number of rows returned
|
||||
mov dh,al ;AN000; set number of rows
|
||||
mov ax,display_width ;AN000; get number of columns returned
|
||||
mov dl,al ;AN000; set number of columns
|
||||
jmp short regcls ;AN000; go do cls
|
||||
|
||||
no_variable:
|
||||
mov bx,stdout ;AC000; set handle as stdout
|
||||
mov ax,IOCTL SHL 8 ;AC000; do ioctl - get device
|
||||
int int_command ;AC000; info
|
||||
test dl,devid_ISDEV ;AC000; is handle a device
|
||||
jz ANSICLS ;AC000; If a file put out ANSI
|
||||
test dl,devid_SPECIAL ;AC000;
|
||||
jnz cls_normal ;AC000; If not special CON, do ANSI
|
||||
|
||||
ansicls:
|
||||
call ansi_cls ;AN000; clear the screen
|
||||
jmp short cls_ret ;AN000; exit
|
||||
|
||||
;
|
||||
; Get video mode
|
||||
;
|
||||
|
||||
cls_normal: ;AC000;
|
||||
|
||||
mov ah,get_video_state ;AC000; set up to get video state
|
||||
int video_io_int ;AC000; do int 10h - BIOS video IO
|
||||
cmp al,video_alpha ;AC000; see if in text mode
|
||||
jbe DoAlpha
|
||||
cmp al,video_bw ;AC000; see if black & white card
|
||||
jz DoAlpha
|
||||
;
|
||||
; We are in graphics mode. Bogus IBM ROM does not scroll correctly. We will
|
||||
; be just as bogus and set the mode that we just got. This will blank the
|
||||
; screen too.
|
||||
;
|
||||
mov ah,set_video_mode ;AC000; set video mode call
|
||||
int video_io_int ;AC000; do int 10h - BIOS video IO
|
||||
jmp short cls_ret ;AC000; exit
|
||||
|
||||
DoAlpha:
|
||||
;
|
||||
; Get video mode and number of columns to scroll
|
||||
;
|
||||
mov ah,get_video_state ;AC000; set up to get current video state
|
||||
int video_io_int ;AC000; do int 10h - BIOS video IO
|
||||
mov dl,ah
|
||||
mov dh,linesperpage ;AC000; have 25 rows on the screen
|
||||
|
||||
regcls:
|
||||
call reg_cls ;AC000; go clear the screen
|
||||
|
||||
cls_ret:
|
||||
ret ;AC000; exit
|
||||
|
||||
; ****************************************************************
|
||||
; *
|
||||
; * ROUTINE: REG_CLS
|
||||
; *
|
||||
; * FUNCTION: Clear the screen using INT 10H.
|
||||
; *
|
||||
; * INPUT: DL = NUMBER OF COLUMNS
|
||||
; * DH = NUMBER OF ROWS
|
||||
; *
|
||||
; * OUTPUT: none
|
||||
; *
|
||||
; ****************************************************************
|
||||
|
||||
reg_cls proc near ;AC000;
|
||||
|
||||
;
|
||||
; Set overscan to black.
|
||||
;
|
||||
|
||||
dec dh ;AC000; decrement rows and columns
|
||||
dec dl ;AC000; to zero base
|
||||
push dx ;AN000; save rows,columns
|
||||
mov ah,set_color_palette ;AC000; set up to set the color to blank
|
||||
xor bx,bx
|
||||
int video_io_int ;AC000; do int 10h - BIOS video IO
|
||||
pop dx ;AN000; retore rows,colums
|
||||
|
||||
xor ax,ax ;AC000; zero out ax
|
||||
mov CX,ax ;AC000; an cx
|
||||
;
|
||||
; Scroll active page
|
||||
;
|
||||
mov ah,scroll_video_page ;AC000; set up to scroll page up
|
||||
mov bh,video_attribute ;AC000; attribute for blank line
|
||||
xor bl,bl ;AC000; set BL to 0
|
||||
int video_io_int ;AC000; do int 10h - BIOS video IO
|
||||
;
|
||||
; Seek to cursor to 0,0
|
||||
;
|
||||
mov ah,set_cursor_position ;AC000; set up to set cursor position
|
||||
xor dx,dx ;AC000; row and column 0
|
||||
mov bh,0 ;AC000;
|
||||
int video_io_int ;AC000; do into 10h - BIOS video IO
|
||||
|
||||
ret ;AC000;
|
||||
|
||||
reg_cls endp ;AC000;
|
||||
|
||||
|
||||
|
||||
; ****************************************************************
|
||||
; *
|
||||
; * ROUTINE: ANSI_CLS
|
||||
; *
|
||||
; * FUNCTION: Clear the screen using by writing a control code
|
||||
; * to STDOUT.
|
||||
; *
|
||||
; * INPUT: none
|
||||
; *
|
||||
; * OUTPUT: none
|
||||
; *
|
||||
; ****************************************************************
|
||||
|
||||
ansi_cls proc near ;AC000;
|
||||
|
||||
mov si,offset trangroup:clsstring
|
||||
lodsb
|
||||
mov cl,al
|
||||
xor ch,ch
|
||||
mov ah,Raw_CON_IO
|
||||
clrloop:
|
||||
lodsb
|
||||
mov DL,al
|
||||
int int_command
|
||||
loop clrloop
|
||||
return
|
||||
|
||||
ansi_cls endp ;AC000;
|
||||
|
||||
trancode ends
|
||||
end
|
||||
|
||||
597
v4.0/src/CMD/COMMAND/TCMD2B.ASM
Normal file
597
v4.0/src/CMD/COMMAND/TCMD2B.ASM
Normal file
@@ -0,0 +1,597 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)tcmd2b.asm 4.1 85/09/22
|
||||
; SCCSID = @(#)tcmd2b.asm 4.1 85/09/22
|
||||
TITLE PART5 COMMAND Transient routines.
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE comsw.asm
|
||||
INCLUDE DOSSYM.INC
|
||||
INCLUDE comseg.asm
|
||||
INCLUDE comequ.asm
|
||||
.list
|
||||
.cref
|
||||
|
||||
|
||||
CODERES SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN LODCOM1:NEAR
|
||||
CODERES ENDS
|
||||
|
||||
DATARES SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN crit_msg_off:word ;AC000;
|
||||
EXTRN crit_msg_seg:word ;AC000;
|
||||
EXTRN IO_SAVE:WORD
|
||||
EXTRN OldTerm:DWORD
|
||||
EXTRN PARENT:WORD
|
||||
;AD060; EXTRN pars_msg_off:word ;AC000;
|
||||
;AD060; EXTRN pars_msg_seg:word ;AC000;
|
||||
EXTRN PERMCOM:BYTE ;AN045;
|
||||
EXTRN RetCode:WORD
|
||||
DATARES ENDS
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN ACRLF_PTR:WORD ;AN007;
|
||||
EXTRN baddev_ptr:word
|
||||
EXTRN CP_active_Ptr:word
|
||||
EXTRN CP_not_all_Ptr:word
|
||||
EXTRN CP_not_set_Ptr:word
|
||||
EXTRN Extend_buf_ptr:word ;AN000;
|
||||
EXTRN Extend_buf_sub:byte ;AN000;
|
||||
EXTRN inv_code_page:word ;AC000;
|
||||
EXTRN msg_disp_class:byte ;AN000;
|
||||
EXTRN NLSFUNC_Ptr:word ;AC000;
|
||||
EXTRN parse_chcp:byte ;AC000;
|
||||
EXTRN parse_chdir:byte ;AC000;
|
||||
EXTRN parse_ctty:byte ;AC000;
|
||||
EXTRN string_buf_ptr:word ;AC000;
|
||||
|
||||
TRANDATA ENDS
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN COMBUF:BYTE
|
||||
EXTRN parse_last:word ;AN018;
|
||||
EXTRN parse1_addr:dword ;AC000;
|
||||
EXTRN parse1_type:byte ;AC000;
|
||||
EXTRN RESSEG:WORD
|
||||
EXTRN srcbuf:byte
|
||||
EXTRN srcxname:byte ;AC000;
|
||||
EXTRN string_ptr_2:word
|
||||
EXTRN system_cpage:word
|
||||
EXTRN TRAN_TPA:WORD
|
||||
TRANSPACE ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC BYTE
|
||||
|
||||
ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
|
||||
;---------------
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN arg:byte ; the arg structure!
|
||||
TRANSPACE ENDS
|
||||
;---------------
|
||||
|
||||
EXTRN cerror:near
|
||||
|
||||
PUBLIC $exit
|
||||
PUBLIC chcp
|
||||
PUBLIC ctty
|
||||
PUBLIC parse_check_eol ;AN000;
|
||||
PUBLIC parse_with_msg ;AN018;
|
||||
PUBLIC setup_parse_error_msg ;AN018;
|
||||
PUBLIC truename ;AN000;
|
||||
|
||||
break Ctty
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
; ****************************************************************
|
||||
; *
|
||||
; * ROUTINE: CTTY - Change console
|
||||
; *
|
||||
; * SYNTAX: CTTY device
|
||||
; *
|
||||
; * FUNCTION: If a valid console device is specified, CTTY will
|
||||
; * duplicate the device handle to STDIN, STDOUT and
|
||||
; * STDERR. This routine returns to LODCOM1.
|
||||
; *
|
||||
; * INPUT: command line at offset 81H
|
||||
; *
|
||||
; * OUTPUT: none
|
||||
; *
|
||||
; ****************************************************************
|
||||
|
||||
CTTY:
|
||||
push ds ;AN000; Get local ES
|
||||
pop es ;AN000;
|
||||
mov si,81H ;AC000; Get command argument for CTTY
|
||||
|
||||
mov di,offset trangroup:parse_ctty ;AC000; Get adderss of PARSE_CTTY
|
||||
xor cx,cx ;AC000; clear cx,dx
|
||||
xor dx,dx ;AC000;
|
||||
invoke cmd_parse ;AC000; call parser
|
||||
cmp ax,end_of_line ;AN000; are we at end of line?
|
||||
jz ctty_error ;AN000; yes - error
|
||||
cmp ax,result_no_error ;AN000; did an error occur
|
||||
jnz ctty_error ;AN000; YES -ERROR
|
||||
|
||||
push si ;AN000; save position in line
|
||||
lds si,parse1_addr ;AN000; get address of filespec
|
||||
mov di,offset trangroup:srcbuf ;AN000; get address of srcbuf
|
||||
|
||||
ctty_move_filename: ;AN000; put filespec in srcbuf
|
||||
lodsb ;AN000; get a char from buffer
|
||||
stosb ;AN000; store in srcbuf
|
||||
cmp al,end_of_line_out ;AN000; it char a terminator?
|
||||
jnz ctty_move_filename ;AN000; no - keep moving
|
||||
pop si ;AN000; get line position back
|
||||
mov di,offset trangroup:parse_ctty ;AC000; Get adderss of PARSE_CTTY
|
||||
call parse_check_eol ;AN000; are we at end of line?
|
||||
jz nocolon ;AN000; yes - continue
|
||||
|
||||
ctty_error:
|
||||
jmp isbaddev ;AC000; yes - exit
|
||||
|
||||
nocolon:
|
||||
mov dx,offset trangroup:srcbuf ;AN000; get address of srcbuf
|
||||
MOV AX,(OPEN SHL 8) OR 2 ; Read and write
|
||||
INT int_command ; Open new device
|
||||
JC ISBADDEV
|
||||
MOV BX,AX
|
||||
MOV AX,IOCTL SHL 8
|
||||
INT int_command
|
||||
TEST DL,80H
|
||||
JNZ DEVISOK
|
||||
|
||||
CLOSEDEV: ;AN007;
|
||||
MOV AH,CLOSE ; Close initial handle
|
||||
INT int_command
|
||||
|
||||
ISBADDEV:
|
||||
MOV DX,OFFSET TRANGROUP:BADDEV_ptr
|
||||
invoke std_printf
|
||||
JMP RESRET
|
||||
|
||||
DEVISOK:
|
||||
push dx ;AN007; save device info
|
||||
mov ax,acrlf_ptr ;AN021; get message number for 0d, 0a
|
||||
mov dh,util_msg_class ;AN021; this is a utility message
|
||||
push bx ;AN021; save handle
|
||||
invoke Tsysgetmsg ;AN021; get the address of the message
|
||||
mov dx,si ;AN021; get address into dx
|
||||
mov ax,(write shl 8) ;AN007; write to device
|
||||
mov cx,2 ;AN007; write two bytes
|
||||
int int_command ;AN007;
|
||||
pop bx ;AN021; get back handle
|
||||
pop dx ;AN007; get back device info
|
||||
jc closedev ;AN007; if error, quit
|
||||
XOR DH,DH
|
||||
OR DL,3 ; Make sure has CON attributes
|
||||
MOV AX,(IOCTL SHL 8) OR 1
|
||||
INT int_command
|
||||
PUSH BX ; Save handle
|
||||
MOV CX,3
|
||||
XOR BX,BX
|
||||
|
||||
ICLLOOP: ; Close basic handles
|
||||
MOV AH,CLOSE
|
||||
INT int_command
|
||||
INC BX
|
||||
LOOP ICLLOOP
|
||||
POP BX ; Get handle
|
||||
MOV AH,XDUP
|
||||
INT int_command ; Dup it to 0
|
||||
MOV AH,XDUP
|
||||
INT int_command ; Dup to 1
|
||||
MOV AH,XDUP
|
||||
INT int_command ; Dup to 2
|
||||
MOV AH,CLOSE ; Close initial handle
|
||||
INT int_command
|
||||
|
||||
RESRET:
|
||||
MOV DS,[RESSEG]
|
||||
ASSUME DS:RESGROUP
|
||||
PUSH DS
|
||||
MOV AX,WORD PTR DS:[PDB_JFN_Table] ; Get new 0 and 1
|
||||
MOV [IO_SAVE],AX
|
||||
MOV AX,OFFSET RESGROUP:LODCOM1
|
||||
PUSH AX
|
||||
|
||||
ZMMMM PROC FAR
|
||||
RET ; Force header to be checked
|
||||
ZMMMM ENDP
|
||||
|
||||
break Chcp
|
||||
|
||||
;****************************************************************
|
||||
;*
|
||||
;* ROUTINE: CHCP - Change code page internal command
|
||||
;* (added DOS 3.30 07/21/86)
|
||||
;*
|
||||
;* SYNTAX: CHCP [xxx]
|
||||
;* where xxx is a valid code page
|
||||
;*
|
||||
;* FUNCTION: If xxx is specified, CHCP will use INT 21H function
|
||||
;* 6402H to set the code page to xxxx. If no parameters
|
||||
;* are specified, CHCP will use INT 21H function 6401H
|
||||
;* to get global code page and display it to the user.
|
||||
;*
|
||||
;* INPUT: command line at offset 81H
|
||||
;*
|
||||
;* OUTPUT: none
|
||||
;*
|
||||
;****************************************************************
|
||||
|
||||
NLSFUNC_installed equ 0ffh
|
||||
set_global_cp equ 2
|
||||
get_global_cp equ 1
|
||||
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
CHCP:
|
||||
push ds ;AN000; Get local ES
|
||||
pop es ;AN000;
|
||||
mov si,81H ;AC000; Get command argument for CHCP
|
||||
|
||||
mov di,offset trangroup:parse_chcp ;AN000; Get adderss of PARSE_CHCP
|
||||
xor cx,cx ;AC000; clear cx,dx
|
||||
xor dx,dx ;AC000;
|
||||
call parse_with_msg ;AC018; call parser
|
||||
cmp ax,end_of_line ;AN000; are we at end of line?
|
||||
|
||||
jnz setcp ;AC000; no go get number & set code page
|
||||
jmp getcp ;AC000; yes - no parm - get code page
|
||||
|
||||
setcp:
|
||||
cmp ax,result_no_error ;AN000; did we have an error?
|
||||
jne cp_error ;AC018; yes - go issue message
|
||||
|
||||
push cx ;AN000; save positional count
|
||||
mov bx,offset trangroup:parse1_addr ;AN000; get number returned
|
||||
mov cx,word ptr [bx] ;AN000; into cx
|
||||
mov system_cpage,cx ;AN000; save user input number
|
||||
pop cx ;AC000; restore positional count
|
||||
mov di,offset trangroup:parse_chcp ;AN000; Get adderss of PARSE_CHCP
|
||||
call parse_check_eol ;AN000; are we at end of line?
|
||||
jnz cp_error ;AC000; no - exit
|
||||
|
||||
okset:
|
||||
mov ah,NLSFUNC ;AN000; see if NLSFUNC installed
|
||||
mov al,0 ;AN000;
|
||||
int 2fh ;AN000;
|
||||
cmp al,NLSFUNC_installed ;AN000;
|
||||
jz got_NLS ;AN000; Yes - continue
|
||||
mov dx,offset trangroup:NLSFUNC_ptr ;AN000; no - set up error message
|
||||
jmp short cp_error ;AN000; error exit
|
||||
|
||||
got_NLS:
|
||||
mov bx,system_cpage ;AN000; get user input code page
|
||||
mov ah,getsetcdpg ;get/set global code page function
|
||||
mov al,set_global_cp ;minor - set
|
||||
int int_command
|
||||
jnc chcp_return ;no error - exit
|
||||
;
|
||||
;added for p716
|
||||
;
|
||||
cmp ax,error_file_not_found ;p716 was the error file not found?
|
||||
jnz chcp_other_error ;no - country.sys was found
|
||||
|
||||
mov ah,GetExtendedError ;p850 see if error is invalid data
|
||||
xor bx,bx ; which is file was found but CP
|
||||
int int_command ; information was not found.
|
||||
cmp ax,error_invalid_data ;AC000; invalid code page
|
||||
jnz no_countrysys ;no - use file not found
|
||||
mov dx,offset trangroup:inv_code_page ;AN000; get message
|
||||
jmp short cp_error ;AC000; error exit
|
||||
|
||||
no_countrysys:
|
||||
mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class
|
||||
mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
|
||||
mov Extend_Buf_ptr,error_file_not_found ;AN000; get message number in control block
|
||||
jmp short cp_error ;AC000; error exit
|
||||
|
||||
chcp_other_error:
|
||||
;
|
||||
; end of p716
|
||||
;
|
||||
mov ah,GetExtendedError ;error - see what it is
|
||||
xor bx,bx
|
||||
int int_command
|
||||
cmp ax,65 ;was it access denied?
|
||||
jnz none_set ;no - assume all failed
|
||||
mov dx,offset trangroup:cp_not_all_ptr ;set up message
|
||||
jmp short cp_error ;AC000; error exit
|
||||
|
||||
none_set:
|
||||
mov dx,offset trangroup:cp_not_set_ptr ;set up message
|
||||
cp_error: ;AN000;
|
||||
jmp cerror ;exit
|
||||
|
||||
getcp:
|
||||
mov ah,getsetcdpg ;get/set global code page function
|
||||
mov al,get_global_cp ;minor - get
|
||||
int int_command
|
||||
mov system_cpage,bx ;get active cp for output
|
||||
mov dx,offset trangroup:cp_active_ptr
|
||||
invoke std_printf ;print it out
|
||||
|
||||
chcp_return:
|
||||
|
||||
RET
|
||||
|
||||
break TRUENAME ;AN000;
|
||||
|
||||
|
||||
; ****************************************************************
|
||||
; *
|
||||
; * ROUTINE: TRUENAME
|
||||
; *
|
||||
; * FUNCTION: Entry point for the internal TRUENAME command.
|
||||
; * Parses the command line. If a path is found, set
|
||||
; * SRCXNAME to path. If only a drive letter is
|
||||
; * found, set SRCXNAME to the drive letter. If
|
||||
; * no path is found, set the path of SRCXNAME to
|
||||
; * dot (.) for current directory. Use the NAME
|
||||
; * TRANSLATE system call to get the real name and
|
||||
; * then display the real name. If an error occurs
|
||||
; * issue an error message and transfer control to
|
||||
; * CERROR.
|
||||
; *
|
||||
; * INPUT: command line at offset 81H
|
||||
; *
|
||||
; * OUTPUT: none
|
||||
; *
|
||||
; ****************************************************************
|
||||
|
||||
assume ds:trangroup,es:trangroup ;AN000;
|
||||
|
||||
TRUENAME: ;AN000; TRUENAME entry point
|
||||
push ds ;AN000; Get local ES
|
||||
pop es ;AN000;
|
||||
mov si,81H ;AN000; Get command line
|
||||
mov di,offset trangroup:parse_chdir ;AN000; Get adderss of PARSE_CHDIR
|
||||
xor cx,cx ;AN000; clear cx,dx
|
||||
xor dx,dx ;AN000;
|
||||
call parse_with_msg ;AC018; call parser
|
||||
|
||||
mov di,offset trangroup:srcxname ;AN000; get address of srcxname
|
||||
cmp ax,end_of_line ;AN000; are we at end of line?
|
||||
je tn_eol ;AN000; yes - go process
|
||||
cmp ax,result_no_error ;AN000; did we have an error?
|
||||
jne tn_parse_error ;AN000; yes - go issue message
|
||||
cmp parse1_type,result_drive ;AN000; was a drive entered?
|
||||
je tn_drive ;AN000; yes - go process
|
||||
jmp short tn_filespec ;AN000; nothing else - must be filespec
|
||||
|
||||
tn_eol: ;AN000; no parameters on line
|
||||
mov ah,end_of_line_out ;AN000; set buffer to .
|
||||
mov al,dot_chr ;AN000; for current dir
|
||||
stosw ;AN000; store in srcxname
|
||||
jmp short tn_doit ;AN000; go do command
|
||||
|
||||
tn_drive: ;AN000; a drive was entered
|
||||
push si ;AN000; save position in line
|
||||
mov si,offset trangroup:parse1_addr ;AN000; get address of drive
|
||||
lodsb ;AN000; get the drive number
|
||||
add al,"A"-1 ;AN000; convert it to char
|
||||
stosb ;AN000; store it in srcxname
|
||||
mov ax,dot_colon ;AN000; get colon and . and
|
||||
stosw ;AN000; store in srcxname
|
||||
mov al,end_of_line_out ;AN000; put a terminator char
|
||||
stosb ;AN000;
|
||||
pop si ;AN000; get line position back
|
||||
jmp short tn_check_eol ;AN000; check to make sure eol
|
||||
|
||||
tn_filespec: ;AN000; a filespec was entered
|
||||
push si ;AN000; save position in line
|
||||
lds si,parse1_addr ;AN000; get address of filespec
|
||||
|
||||
tn_move_filename: ;AN000; put filespec in srcxname
|
||||
lodsb ;AN000; get a char from buffer
|
||||
stosb ;AN000; store in srcxname
|
||||
cmp al,end_of_line_out ;AN000; it char a terminator?
|
||||
jnz tn_move_filename ;AN000; no - keep moving
|
||||
pop si ;AN000; get line position back
|
||||
|
||||
tn_check_eol: ;AN000; make sure no extra parms
|
||||
mov di,offset trangroup:parse_chdir ;AN000; get address of parse_chdir
|
||||
call parse_check_eol ;AN000; are we at end of line?
|
||||
je tn_doit ;AN000; Yes - do the command
|
||||
|
||||
tn_parse_error: ;AN000; A parse error occurred
|
||||
jmp cerror ;AN000; Go to error routine
|
||||
|
||||
tn_doit: ;AN000;
|
||||
mov si,offset trangroup:srcxname ;AN000; set up srcxname as source
|
||||
mov di,offset trangroup:combuf ;AN000; set up combuf as target (need big target)
|
||||
mov ah,xnametrans ;AN000; do name translate call
|
||||
int int_command ;AN000;
|
||||
jnc tn_print_xname ;AN000; If no error - print result
|
||||
|
||||
invoke Set_ext_error_msg ;AN000; get extended message
|
||||
mov string_ptr_2,offset trangroup:srcxname ;AN000; get address of failed string
|
||||
mov Extend_buf_sub,one_subst ;AN000; put number of subst in control block
|
||||
jmp cerror ;AN000; Go to error routine
|
||||
|
||||
tn_print_xname: ;AN000;
|
||||
mov string_ptr_2,offset Trangroup:combuf ;AN000; Set up address of combuf
|
||||
mov dx,offset trangroup:string_buf_ptr ;AN000; Set up address of print control block
|
||||
invoke crlf2 ;AN000; print a crlf
|
||||
invoke printf_crlf ;AN000; print it out
|
||||
|
||||
ret ;AN000;
|
||||
|
||||
break $Exit
|
||||
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
$EXIT:
|
||||
push ds ;AN000; save data segment
|
||||
mov ds,[resseg] ;AN000; get resident data segment
|
||||
|
||||
assume ds:resgroup ;AN000;
|
||||
|
||||
cmp [permcom],0 ;AN045; is this a permanent COMMAND?
|
||||
jnz no_reset ;AN045; Yes - don't do anything
|
||||
;AD060; mov ah,multdos ;AN000; reset parse message pointers
|
||||
;AD060; mov al,message_2f ;AN000; call for message retriever
|
||||
;AD060; mov dl,set_parse_msg ;AN000; set up parse message address
|
||||
;AD060; mov di,pars_msg_off ;AN000; old offset of parse messages
|
||||
;AD060; mov es,pars_msg_seg ;AN000; old segment of parse messages
|
||||
;AD060; int 2fh ;AN000; go set it
|
||||
|
||||
;AD060; mov ah,multdos ;AN000; set up to call DOS through int 2fh
|
||||
;AD060; mov al,message_2f ;AN000; call for message retriever
|
||||
mov ax,(multdos shl 8 or message_2f);AN060; reset parse message pointers
|
||||
mov dl,set_critical_msg ;AN000; set up critical error message address
|
||||
mov di,crit_msg_off ;AN000; old offset of critical messages
|
||||
mov es,crit_msg_seg ;AN000; old segment of critical messages
|
||||
int 2fh ;AN000; go set it
|
||||
no_reset: ;AN045;
|
||||
pop ds ;AN000; restore local data segment
|
||||
|
||||
assume ds:trangroup ;AN000;
|
||||
|
||||
MOV ES,[RESSEG]
|
||||
|
||||
assume es:resgroup
|
||||
|
||||
MOV AX,[PARENT]
|
||||
MOV WORD PTR ES:[PDB_Parent_PID],AX
|
||||
MOV AX,WORD PTR OldTerm
|
||||
MOV WORD PTR ES:[PDB_Exit],AX
|
||||
MOV AX,WORD PTR OldTerm+2
|
||||
MOV WORD PTR ES:[PDB_Exit+2],AX
|
||||
|
||||
PUSH ES
|
||||
MOV ES,[TRAN_TPA]
|
||||
MOV AH,DEALLOC
|
||||
INT int_command ; Now running in "free" space
|
||||
POP ES
|
||||
|
||||
MOV AH,Exit
|
||||
MOV AL,BYTE PTR RetCode
|
||||
INT int_command
|
||||
|
||||
|
||||
; ****************************************************************
|
||||
; *
|
||||
; * ROUTINE: PARSE_CHECK_EOL
|
||||
; *
|
||||
; * FUNCTION: Calls parser to see if end of line occurred.
|
||||
; * If not end of line, set up to print parse
|
||||
; * error message. ASSUMES NO MORE PARAMETERS ARE
|
||||
; * EXPECTED!
|
||||
; *
|
||||
; * INPUT: DS:SI last output from parser
|
||||
; * ES:DI points to parse block
|
||||
; * CX last output from parser
|
||||
; *
|
||||
; * OUTPUT: AX parser return code
|
||||
; *
|
||||
; * if end of line found
|
||||
; * zero flag set
|
||||
; * else
|
||||
; * MSG_DISPLAY_CLASS set to parse error
|
||||
; *
|
||||
; ****************************************************************
|
||||
|
||||
ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:NOTHING ;AN000;
|
||||
|
||||
parse_check_eol Proc near ;AN000;
|
||||
|
||||
xor dx,dx ;AN000;
|
||||
mov [parse_last],si ;AN018; save start of parameter
|
||||
invoke cmd_parse ;AN000; call parser
|
||||
cmp al,end_of_line ;AN000; Are we at end of line?
|
||||
jz parse_good_eol ;AN000; yes - no problem
|
||||
|
||||
cmp ax,result_no_error ;AN018; was any error found?
|
||||
jnz ok_to_setup_pmsg ;AN018; yes - continue
|
||||
inc ax ;AN018; set AX to 1 and turn off zero flag
|
||||
|
||||
ok_to_setup_pmsg:
|
||||
call setup_parse_error_msg ;AN018; go set up error message
|
||||
|
||||
parse_good_eol:
|
||||
ret ;AN000;
|
||||
|
||||
parse_check_eol endp ;AN000;
|
||||
|
||||
; ****************************************************************
|
||||
; *
|
||||
; * ROUTINE: PARSE_WITH_MSG
|
||||
; *
|
||||
; * FUNCTION: Calls parser. If an error occurred, the error
|
||||
; * message is set up.
|
||||
; *
|
||||
; * INPUT: DS:SI last output from parser
|
||||
; * ES:DI points to parse block
|
||||
; * CX last output from parser
|
||||
; *
|
||||
; * OUTPUT: AX parser return code
|
||||
; *
|
||||
; * if no error
|
||||
; * outputs from parser
|
||||
; * else
|
||||
; * MSG_DISPLAY_CLASS set to parse error
|
||||
; * error message set up for STD_PRINTF
|
||||
; *
|
||||
; ****************************************************************
|
||||
|
||||
ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:NOTHING ;AN018;
|
||||
|
||||
parse_with_msg Proc near ;AN018;
|
||||
|
||||
mov [parse_last],si ;AN018; save start of parameter
|
||||
invoke cmd_parse ;AN018; call parser
|
||||
cmp al,end_of_line ;AN018; Are we at end of line?
|
||||
jz parse_msg_good ;AN018; yes - no problem
|
||||
cmp ax,result_no_error ;AN018; did an error occur
|
||||
jz parse_msg_good ;AN018; yes - no problem
|
||||
|
||||
call setup_parse_error_msg ;AN018; go set up error message
|
||||
|
||||
parse_msg_good:
|
||||
ret ;AN018;
|
||||
|
||||
parse_with_msg endp ;AN018;
|
||||
|
||||
; ****************************************************************
|
||||
; *
|
||||
; * ROUTINE: SETUP_PARSE_ERROR_MSG
|
||||
; *
|
||||
; * FUNCTION: Calls parser. If an error occurred, the error
|
||||
; * message is set up.
|
||||
; *
|
||||
; * INPUT: AX Parse error number
|
||||
; * SI Set to past last parameter
|
||||
; * Parse_last Set to start of last parameter
|
||||
; *
|
||||
; * OUTPUT: MSG_DISPLAY_CLASS set to parse error
|
||||
; * error message set up for STD_PRINTF
|
||||
; *
|
||||
; ****************************************************************
|
||||
|
||||
ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:NOTHING ;AN018;
|
||||
|
||||
SETUP_PARSE_ERROR_MSG Proc near ;AN018;
|
||||
|
||||
mov msg_disp_class,parse_msg_class ;AC018; Set up parse message class
|
||||
mov dx,offset TranGroup:Extend_Buf_ptr ;AC018; get extended message pointer
|
||||
mov byte ptr [si],end_of_line_out ;AC018; terminate the parameter string
|
||||
mov Extend_Buf_ptr,ax ;AC018; get message number in control block
|
||||
cmp ax,lessargs_ptr ;AC018; if required parameter missing
|
||||
jz Setup_parse_msg_ret ;AN018; no subst
|
||||
mov si,[parse_last] ;AC018; get start of parameter
|
||||
mov string_ptr_2,si ;AC018; get address of failed string
|
||||
mov Extend_buf_sub,one_subst ;AC018; put number of subst in control block
|
||||
|
||||
setup_parse_msg_ret:
|
||||
inc si ;AN018; make sure zero flag not set
|
||||
|
||||
ret ;AC018;
|
||||
|
||||
SETUP_PARSE_ERROR_MSG Endp ;AN018;
|
||||
|
||||
trancode ends
|
||||
end
|
||||
540
v4.0/src/CMD/COMMAND/TCODE.ASM
Normal file
540
v4.0/src/CMD/COMMAND/TCODE.ASM
Normal file
@@ -0,0 +1,540 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)tcode.asm 1.1 85/05/14
|
||||
; SCCSID = @(#)tcode.asm 1.1 85/05/14
|
||||
TITLE Part1 COMMAND Transient Routines
|
||||
|
||||
INCLUDE comsw.asm
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE DOSSYM.INC
|
||||
INCLUDE comseg.asm
|
||||
INCLUDE comequ.asm
|
||||
.list
|
||||
.cref
|
||||
|
||||
|
||||
CODERES SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN EXEC_WAIT:NEAR
|
||||
CODERES ENDS
|
||||
|
||||
DATARES SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN BATCH:WORD
|
||||
EXTRN CALL_BATCH_FLAG:byte
|
||||
EXTRN CALL_FLAG:BYTE
|
||||
EXTRN ECHOFLAG:BYTE
|
||||
EXTRN envirseg:word
|
||||
EXTRN EXTCOM:BYTE
|
||||
EXTRN FORFLAG:BYTE
|
||||
EXTRN IFFLAG:BYTE
|
||||
EXTRN next_batch:word
|
||||
EXTRN nullflag:byte
|
||||
EXTRN PIPEFILES:BYTE
|
||||
EXTRN PIPEFLAG:BYTE
|
||||
EXTRN RE_OUT_APP:BYTE
|
||||
EXTRN RE_OUTSTR:BYTE
|
||||
EXTRN RESTDIR:BYTE
|
||||
EXTRN SINGLECOM:WORD
|
||||
EXTRN VERVAL:WORD
|
||||
DATARES ENDS
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN BadNam_Ptr:word ;AC000;
|
||||
TRANDATA ENDS
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN APPEND_EXEC:BYTE ;AN041;
|
||||
EXTRN ARG1S:WORD
|
||||
EXTRN ARG2S:WORD
|
||||
EXTRN ARGTS:WORD
|
||||
EXTRN BYTCNT:WORD
|
||||
EXTRN COMBUF:BYTE
|
||||
EXTRN COMSW:WORD
|
||||
EXTRN CURDRV:BYTE
|
||||
EXTRN HEADCALL:DWORD
|
||||
EXTRN IDLEN:BYTE
|
||||
EXTRN INTERNATVARS:BYTE
|
||||
EXTRN PARM1:BYTE
|
||||
EXTRN PARM2:BYTE
|
||||
EXTRN RE_INSTR:BYTE
|
||||
EXTRN RESSEG:WORD
|
||||
EXTRN SPECDRV:BYTE
|
||||
EXTRN STACK:WORD
|
||||
EXTRN SWITCHAR:BYTE
|
||||
EXTRN TPA:WORD
|
||||
EXTRN UCOMBUF:BYTE
|
||||
EXTRN USERDIR1:BYTE
|
||||
IF IBM
|
||||
EXTRN ROM_CALL:BYTE
|
||||
EXTRN ROM_CS:WORD
|
||||
EXTRN ROM_IP:WORD
|
||||
ENDIF
|
||||
|
||||
TRANSPACE ENDS
|
||||
|
||||
; ********************************************************************
|
||||
; START OF TRANSIENT PORTION
|
||||
; This code is loaded at the end of memory and may be overwritten by
|
||||
; memory-intensive user programs.
|
||||
|
||||
TRANCODE SEGMENT PUBLIC BYTE ;AC000;
|
||||
|
||||
ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
|
||||
EXTRN $EXIT:NEAR
|
||||
EXTRN DRVBAD:NEAR
|
||||
EXTRN EXTERNAL:NEAR
|
||||
EXTRN FNDCOM:NEAR
|
||||
EXTRN FORPROC:NEAR
|
||||
EXTRN PIPEPROC:NEAR
|
||||
EXTRN PIPEPROCSTRT:NEAR
|
||||
|
||||
PUBLIC COMMAND
|
||||
PUBLIC DOCOM
|
||||
PUBLIC DOCOM1
|
||||
PUBLIC NOPIPEPROC
|
||||
PUBLIC TCOMMAND
|
||||
|
||||
IF IBM
|
||||
PUBLIC ROM_EXEC
|
||||
PUBLIC ROM_SCAN
|
||||
ENDIF
|
||||
|
||||
ORG 0
|
||||
ZERO = $
|
||||
|
||||
ORG 100H ; Allow for 100H parameter area
|
||||
|
||||
SETDRV:
|
||||
MOV AH,SET_DEFAULT_DRIVE
|
||||
INT int_command
|
||||
;
|
||||
; TCOMMAND is the recycle point in COMMAND. Nothing is known here.
|
||||
; No registers (CS:IP) no flags, nothing.
|
||||
;
|
||||
|
||||
TCOMMAND:
|
||||
MOV DS,[RESSEG]
|
||||
ASSUME DS:RESGROUP
|
||||
MOV AX,-1
|
||||
XCHG AX,[VERVAL]
|
||||
CMP AX,-1
|
||||
JZ NOSETVER2
|
||||
MOV AH,SET_VERIFY_ON_WRITE ; AL has correct value
|
||||
INT int_command
|
||||
|
||||
NOSETVER2:
|
||||
CALL [HEADCALL] ; Make sure header fixed
|
||||
XOR BP,BP ; Flag transient not read
|
||||
CMP [SINGLECOM],-1
|
||||
JNZ COMMAND
|
||||
|
||||
$EXITPREP:
|
||||
PUSH CS
|
||||
POP DS
|
||||
JMP $EXIT ; Have finished the single command
|
||||
ASSUME DS:NOTHING
|
||||
;
|
||||
; Main entry point from resident portion.
|
||||
;
|
||||
; If BP <> 0, then we have just loaded transient portion otherwise we are
|
||||
; just beginning the processing of another command.
|
||||
;
|
||||
|
||||
COMMAND:
|
||||
|
||||
;
|
||||
; We are not always sure of the state of the world at this time. We presume
|
||||
; worst case and initialize the relevant registers: segments and stack.
|
||||
;
|
||||
ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
CLD
|
||||
MOV AX,CS
|
||||
CLI
|
||||
MOV SS,AX
|
||||
ASSUME SS:TRANGROUP
|
||||
MOV SP,OFFSET TRANGROUP:STACK
|
||||
STI
|
||||
MOV ES,AX
|
||||
MOV DS,AX ;AN000; set DS to transient
|
||||
ASSUME ES:TRANGROUP,DS:TRANGROUP ;AC000;
|
||||
invoke TSYSLOADMSG ;AN000; preload messages
|
||||
invoke SETSTDINOFF ;AN026; turn off critical error on STDIN
|
||||
invoke SETSTDOUTOFF ;AN026; turn off critical error on STDOUT
|
||||
mov append_exec,0 ;AN041; set internal append state off
|
||||
|
||||
MOV DS,[RESSEG]
|
||||
ASSUME DS:RESGROUP
|
||||
|
||||
MOV [UCOMBUF],COMBUFLEN ; Init UCOMBUF
|
||||
MOV [COMBUF],COMBUFLEN ; Init COMBUF (Autoexec doing DATE)
|
||||
;
|
||||
; If we have just loaded the transient, then we do NOT need to initialize the
|
||||
; command buffer. ???? DO WE NEED TO RESTORE THE USERS DIRECTORY ???? I
|
||||
; guess not: the only circumstances in which we reload the command processor
|
||||
; is after a transient program execution. In this case, we let the current
|
||||
; directory lie where it may.
|
||||
;
|
||||
OR BP,BP ; See if just read
|
||||
JZ TESTRDIR ; Not read, check user directory
|
||||
MOV WORD PTR [UCOMBUF+1],0D01H ; Reset buffer
|
||||
JMP SHORT NOSETBUF
|
||||
|
||||
TESTRDIR:
|
||||
CMP [RESTDIR],0
|
||||
JZ NOSETBUF ; User directory OK
|
||||
PUSH DS
|
||||
;
|
||||
; We have an unusual situation to handle. The user *may* have changed his
|
||||
; directory as a result of an internal command that got aborted. Restoring it
|
||||
; twice may not help us: the problem may never go away. We just attempt it
|
||||
; once and give up.
|
||||
;
|
||||
MOV [RESTDIR],0 ; Flag users dirs OK
|
||||
PUSH CS
|
||||
POP DS
|
||||
ASSUME DS:TRANGROUP
|
||||
MOV DX,OFFSET TRANGROUP:USERDIR1
|
||||
MOV AH,CHDIR
|
||||
INT int_command ; Restore users directory
|
||||
POP DS
|
||||
ASSUME DS:RESGROUP
|
||||
|
||||
NOSETBUF:
|
||||
CMP [PIPEFILES],0
|
||||
JZ NOPCLOSE ; Don't bother if they don't exist
|
||||
CMP [PIPEFLAG],0
|
||||
JNZ NOPCLOSE ; Don't del if still piping
|
||||
INVOKE PIPEDEL
|
||||
|
||||
NOPCLOSE:
|
||||
MOV [EXTCOM],0 ; Flag internal command
|
||||
MOV AX,CS ; Get segment we're in
|
||||
MOV DS,AX
|
||||
ASSUME DS:TRANGROUP
|
||||
|
||||
PUSH AX
|
||||
MOV DX,OFFSET TRANGROUP:INTERNATVARS
|
||||
MOV AX,INTERNATIONAL SHL 8
|
||||
INT 21H
|
||||
POP AX
|
||||
SUB AX,[TPA] ; AX=size of TPA in paragraphs
|
||||
PUSH BX
|
||||
MOV BX,16
|
||||
MUL BX ; DX:AX=size of TPA in bytes
|
||||
POP BX
|
||||
OR DX,DX ; See if over 64K
|
||||
JZ SAVSIZ ; OK if not
|
||||
MOV AX,-1 ; If so, limit to 65535 bytes
|
||||
|
||||
SAVSIZ:
|
||||
;
|
||||
; AX is the number of bytes free in the buffer between the resident and the
|
||||
; transient with a maximum of 64K-1. We round this down to a multiple of 512.
|
||||
;
|
||||
CMP AX,512
|
||||
JBE GotSize
|
||||
AND AX,0FE00h ; NOT 511 = NOT 1FF
|
||||
|
||||
GotSize:
|
||||
MOV [BYTCNT],AX ; Max no. of bytes that can be buffered
|
||||
MOV DS,[RESSEG] ; All batch work must use resident seg.
|
||||
ASSUME DS:RESGROUP
|
||||
|
||||
TEST [ECHOFLAG],1
|
||||
JZ GETCOM ; Don't do the CRLF
|
||||
INVOKE SINGLETEST
|
||||
JB GETCOM
|
||||
TEST [PIPEFLAG],-1
|
||||
JNZ GETCOM
|
||||
TEST [FORFLAG],-1 ; G Don't print prompt in FOR
|
||||
JNZ GETCOM ; G
|
||||
TEST [BATCH], -1 ; G Don't print prompt if in batch
|
||||
JNZ GETCOM ; G
|
||||
INVOKE CRLF2
|
||||
|
||||
GETCOM:
|
||||
MOV CALL_FLAG,0 ; G Reset call flags
|
||||
MOV CALL_BATCH_FLAG,0 ; G
|
||||
MOV AH,GET_DEFAULT_DRIVE
|
||||
INT int_command
|
||||
MOV [CURDRV],AL
|
||||
TEST [PIPEFLAG],-1 ; Pipe has highest presedence
|
||||
JZ NOPIPE
|
||||
JMP PIPEPROC ; Continue the pipeline
|
||||
|
||||
NOPIPE:
|
||||
TEST [ECHOFLAG],1
|
||||
JZ NOPDRV ; No prompt if echo off
|
||||
INVOKE SINGLETEST
|
||||
JB NOPDRV
|
||||
TEST [FORFLAG],-1 ; G Don't print prompt in FOR
|
||||
JNZ NOPDRV ; G
|
||||
TEST [BATCH], -1 ; G Don't print prompt if in batch
|
||||
JNZ TESTFORBAT ; G
|
||||
INVOKE PRINT_PROMPT ; Prompt the user
|
||||
|
||||
NOPDRV:
|
||||
TEST [FORFLAG],-1 ; FOR has next highest precedence
|
||||
JZ TESTFORbat
|
||||
JMP FORPROC ; Continue the FOR
|
||||
|
||||
TESTFORBAT:
|
||||
MOV [RE_INSTR],0 ; Turn redirection back off
|
||||
MOV [RE_OUTSTR],0
|
||||
MOV [RE_OUT_APP],0
|
||||
MOV IFFlag,0 ; no more ifs...
|
||||
TEST [BATCH],-1 ; Batch has lowest precedence
|
||||
JZ ISNOBAT
|
||||
|
||||
push es ;AN000; save ES
|
||||
push ds ;AN000; save DS
|
||||
mov ax,mult_shell_get ;AN000; check to see if SHELL has command
|
||||
mov es,[batch] ;AN000; get batch segment
|
||||
mov di,batfile ;AN000; get batch file name
|
||||
push cs ;AN000; get local segment to DS
|
||||
pop ds ;AN000;
|
||||
mov dx,offset trangroup:combuf ;AN000; pass communications buffer
|
||||
int 2fh ;AN000; call the shell
|
||||
cmp al,shell_action ;AN000; does shell have a commmand?
|
||||
pop ds ;AN000; restore DS
|
||||
pop es ;AN000; restore ES
|
||||
jz jdocom1 ;AN000; yes - go process command
|
||||
|
||||
PUSH DS ;G
|
||||
INVOKE READBAT ; Continue BATCH
|
||||
POP DS ;G
|
||||
mov nullflag,0 ;G reset no command flag
|
||||
TEST [BATCH],-1 ;G
|
||||
JNZ JDOCOM1 ;G if batch still in progress continue
|
||||
MOV BX,NEXT_BATCH ;G
|
||||
CMP BX,0 ;G see if there is a new batch file
|
||||
JZ JDOCOM1 ;G no - go do command
|
||||
MOV BATCH,BX ;G get segment of next batch file
|
||||
MOV NEXT_BATCH,0 ;G reset next batch
|
||||
JDOCOM1:
|
||||
PUSH CS ;G
|
||||
POP DS ;G
|
||||
JMP SHORT DoCom1 ; echoing already done
|
||||
|
||||
ISNOBAT:
|
||||
CMP [SINGLECOM],0
|
||||
JZ REGCOM
|
||||
MOV SI,-1
|
||||
XCHG SI,[SINGLECOM]
|
||||
MOV DI,OFFSET TRANGROUP:COMBUF + 2
|
||||
XOR CX,CX
|
||||
|
||||
SINGLELOOP:
|
||||
LODSB
|
||||
STOSB
|
||||
INC CX
|
||||
CMP AL,0DH
|
||||
JNZ SINGLELOOP
|
||||
DEC CX
|
||||
PUSH CS
|
||||
POP DS
|
||||
ASSUME DS:TRANGROUP
|
||||
MOV [COMBUF + 1],CL
|
||||
;
|
||||
; do NOT issue a trailing CRLF...
|
||||
;
|
||||
JMP DOCOM1
|
||||
|
||||
;
|
||||
; We have a normal command.
|
||||
; Printers are a bizarre quantity. Sometimes they are a stream and
|
||||
; sometimes they aren't. At this point, we automatically close all spool
|
||||
; files and turn on truncation mode.
|
||||
;
|
||||
|
||||
REGCOM:
|
||||
MOV AX,(ServerCall SHL 8) + 9
|
||||
INT 21h
|
||||
MOV AX,(ServerCall SHL 8) + 8
|
||||
MOV DL,1
|
||||
INT 21h
|
||||
|
||||
PUSH CS
|
||||
POP DS ; Need local segment to point to buffer
|
||||
MOV DX,OFFSET TRANGROUP:UCOMBUF
|
||||
MOV AH,STD_CON_STRING_INPUT
|
||||
INT int_command ; Get a command
|
||||
MOV CL,[UCOMBUF]
|
||||
XOR CH,CH
|
||||
ADD CX,3
|
||||
MOV SI,OFFSET TRANGROUP:UCOMBUF
|
||||
MOV DI,OFFSET TRANGROUP:COMBUF
|
||||
REP MOVSB ; Transfer it to the cooked buffer
|
||||
|
||||
;---------------
|
||||
|
||||
transpace segment
|
||||
extrn arg:byte ; the arg structure!
|
||||
transpace ends
|
||||
;---------------
|
||||
|
||||
|
||||
DOCOM:
|
||||
INVOKE CRLF2
|
||||
|
||||
DOCOM1:
|
||||
INVOKE PRESCAN ; Cook the input buffer
|
||||
JZ NOPIPEPROC
|
||||
JMP PIPEPROCSTRT ; Fire up the pipe
|
||||
|
||||
nullcomj:
|
||||
jmp nullcom
|
||||
|
||||
NOPIPEPROC:
|
||||
invoke parseline
|
||||
jnc OkParse ; user error? or maybe we goofed?
|
||||
|
||||
BadParse:
|
||||
PUSH CS
|
||||
POP DS
|
||||
MOV DX,OFFSET TRANGROUP:BADNAM_ptr
|
||||
INVOKE std_eprintf
|
||||
JMP TCOMMAND
|
||||
|
||||
OkParse:
|
||||
test arg.argv[0].argflags, MASK wildcard
|
||||
jnz BadParse ; ambiguous commands not allowed
|
||||
cmp arg.argvcnt, 0 ; there WAS a command, wasn't there?
|
||||
jz nullcomj
|
||||
cmp arg.argv[0].arglen, 0 ; probably an unnecessary check...
|
||||
jz nullcomj ; guarantees argv[0] at least x<NULL>
|
||||
|
||||
MOV SI,OFFSET TRANGROUP:COMBUF+2
|
||||
MOV DI,OFFSET TRANGROUP:IDLEN
|
||||
MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H ; Make FCB with blank scan-off
|
||||
INT int_command
|
||||
mov BX, arg.argv[0].argpointer
|
||||
cmp BYTE PTR [BX+1],':' ; was a drive specified?
|
||||
jne short drvgd ; no, use default of zero...
|
||||
|
||||
mov DL, BYTE PTR [BX] ; pick-up drive letter
|
||||
and DL, NOT 20H ; uppercase the sucker
|
||||
sub DL, capital_A ; convert it to a drive number, A=0
|
||||
|
||||
CMP AL,-1 ; See what PARSE said about our drive letter.
|
||||
JZ drvbadj2 ; It was invalid.
|
||||
|
||||
mov DI, arg.argv[0].argstartel
|
||||
cmp BYTE PTR [DI], 0 ; is there actually a command there?
|
||||
jnz drvgd ; if not, we have: "d:", "d:\", "d:/"
|
||||
jmp setdrv ; and set drive to new drive spec
|
||||
|
||||
drvbadj2:
|
||||
jmp drvbad
|
||||
|
||||
DRVGD:
|
||||
MOV AL,[DI]
|
||||
MOV [SPECDRV],AL
|
||||
MOV AL,' '
|
||||
MOV CX,9
|
||||
INC DI
|
||||
REPNE SCASB ; Count no. of letters in command name
|
||||
MOV AL,8
|
||||
SUB AL,CL
|
||||
MOV [IDLEN],AL ; IDLEN is truly the length
|
||||
MOV DI,81H
|
||||
PUSH SI
|
||||
|
||||
mov si, OFFSET TRANGROUP:COMBUF+2 ; Skip over all leading delims
|
||||
invoke scanoff
|
||||
|
||||
do_skipcom:
|
||||
lodsb ; move command line pointer over
|
||||
invoke delim ; pathname -- have to do it ourselves
|
||||
jz do_skipped ; 'cause parse_file_descriptor is dumb
|
||||
cmp AL, 0DH ; can't always depend on argv[0].arglen
|
||||
jz do_skipped ; to be the same length as the user-
|
||||
cmp AL, [SWITCHAR] ; specified command string
|
||||
jnz do_skipcom
|
||||
|
||||
do_skipped:
|
||||
dec SI
|
||||
XOR CX,CX
|
||||
|
||||
COMTAIL:
|
||||
LODSB
|
||||
STOSB ; Move command tail to 80H
|
||||
CMP AL,13
|
||||
LOOPNZ COMTAIL
|
||||
DEC DI
|
||||
MOV BP,DI
|
||||
NOT CL
|
||||
MOV BYTE PTR DS:[80H],CL
|
||||
POP SI
|
||||
|
||||
;-----
|
||||
; Some of these comments are sadly at odds with this brave new code.
|
||||
;-----
|
||||
; If the command has 0 parameters must check here for
|
||||
; any switches that might be present.
|
||||
; SI -> first character after the command.
|
||||
|
||||
mov DI, arg.argv[0].argsw_word
|
||||
mov [COMSW], DI ; ah yes, the old addressing mode problem...
|
||||
mov SI, arg.argv[1 * SIZE argv_ele].argpointer ; s = argv[1];
|
||||
OR SI,SI ; if (s == NULL)
|
||||
JNZ DoParse
|
||||
MOV SI,BP ; s = bp; (buffer end)
|
||||
|
||||
DoParse:
|
||||
MOV DI,FCB
|
||||
MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H
|
||||
INT int_command
|
||||
MOV [PARM1],AL ; Save result of parse
|
||||
|
||||
mov DI, arg.argv[1*SIZE argv_ele].argsw_word
|
||||
mov [ARG1S], DI
|
||||
mov SI, arg.argv[2*SIZE argv_ele].argpointer ; s = argv[2];
|
||||
OR SI,SI ; if (s == NULL)
|
||||
JNZ DoParse2
|
||||
MOV SI,BP ; s = bp; (bufend)1
|
||||
|
||||
DoParse2:
|
||||
MOV DI,FCB+10H
|
||||
MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H
|
||||
INT int_command ; Parse file name
|
||||
MOV [PARM2],AL ; Save result
|
||||
|
||||
mov DI, arg.argv[2*SIZE argv_ele].argsw_word
|
||||
mov [ARG2S], DI
|
||||
mov DI, arg.argv[0].argsw_word
|
||||
not DI ; ARGTS doesn't include the flags
|
||||
and DI, arg.argswinfo ; from COMSW...
|
||||
mov [ARGTS], DI
|
||||
|
||||
MOV AL,[IDLEN]
|
||||
MOV DL,[SPECDRV]
|
||||
or DL, DL ; if a drive was specified...
|
||||
jnz externalj1 ; it MUST be external, by this time
|
||||
dec al ; (I don't know why -- old code did it)
|
||||
jmp fndcom ; otherwise, check internal com table
|
||||
|
||||
externalj1:
|
||||
jmp external
|
||||
|
||||
nullcom:
|
||||
MOV DS,[RESSEG]
|
||||
ASSUME DS:RESGROUP
|
||||
TEST [BATCH], -1 ;G Are we in a batch file?
|
||||
JZ nosetflag ;G only set flag if in batch
|
||||
mov nullflag,nullcommand ;G set flag to indicate no command
|
||||
|
||||
nosetflag:
|
||||
CMP [SINGLECOM],-1
|
||||
JZ EXITJ
|
||||
JMP GETCOM
|
||||
|
||||
EXITJ:
|
||||
JMP $EXITPREP
|
||||
|
||||
IF IBM
|
||||
include mshalo.asm
|
||||
ENDIF
|
||||
|
||||
TRANCODE ENDS
|
||||
END
|
||||
777
v4.0/src/CMD/COMMAND/TDATA.ASM
Normal file
777
v4.0/src/CMD/COMMAND/TDATA.ASM
Normal file
@@ -0,0 +1,777 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)tdata.asm 4.3 85/05/17
|
||||
; SCCSID = @(#)tdata.asm 4.3 85/05/17
|
||||
TITLE COMMAND Transient Initialized DATA
|
||||
|
||||
; MODIFICATION HISTORY
|
||||
;
|
||||
; EE 10-20-83 Changed the drive check indicator bytes (DCIB's) in
|
||||
; COMTAB to be a flag byte in which bit 0 is now the
|
||||
; DCIB(bit) and bit 1 is on if the command can take
|
||||
; switches.
|
||||
|
||||
fmt macro name,string,args
|
||||
local a
|
||||
a db string
|
||||
PUBLIC name
|
||||
name dw offset trangroup:a
|
||||
irp val,<args>
|
||||
dw offset trangroup:val
|
||||
endm
|
||||
endm
|
||||
|
||||
btab macro b,sym
|
||||
db b
|
||||
dw offset trangroup:sym
|
||||
endm
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE comsw.asm ;AC000;
|
||||
INCLUDE comseg.asm
|
||||
INCLUDE EA.inc ;AN030;
|
||||
INCLUDE dirent.inc ;AN042;
|
||||
.list
|
||||
.cref
|
||||
|
||||
BREAK MACRO subtitle
|
||||
SUBTTL subtitle
|
||||
PAGE
|
||||
ENDM
|
||||
|
||||
;
|
||||
; WARNING: DO NOT INCLUDE DOSSYM.INC BECAUSE IT DESTROYS THE MACRO 'FMT' THAT
|
||||
; has been defined above - RS.
|
||||
;
|
||||
INCLUDE CURDIR.INC
|
||||
INCLUDE ERROR.INC
|
||||
INCLUDE ifequ.asm
|
||||
INCLUDE comequ.asm
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN arg_buf:BYTE
|
||||
EXTRN bwdbuf:byte
|
||||
EXTRN bytes_free:WORD
|
||||
EXTRN charbuf:byte
|
||||
EXTRN copy_Num:WORD
|
||||
EXTRN cpyflag:BYTE
|
||||
EXTRN DATE_OUTPUT:BYTE ;AC000;
|
||||
EXTRN Dir_Num:WORD
|
||||
EXTRN DRIVE_OUTPUT:BYTE ;AC000;
|
||||
EXTRN file_size_high:WORD
|
||||
EXTRN file_size_low:WORD
|
||||
EXTRN major_ver_num:WORD
|
||||
EXTRN minor_ver_num:WORD
|
||||
EXTRN one_char_val:BYTE
|
||||
EXTRN PARSE1_OUTPUT:BYTE ;AC000;
|
||||
EXTRN srcbuf:byte
|
||||
EXTRN string_ptr_2:WORD
|
||||
EXTRN system_cpage:word
|
||||
EXTRN TIME_OUTPUT:BYTE ;AC000;
|
||||
EXTRN vol_drv:BYTE
|
||||
EXTRN vol_serial:dword ;AN000;
|
||||
TRANSPACE ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN $CALL:NEAR
|
||||
EXTRN $CHDIR:NEAR
|
||||
EXTRN $EXIT:NEAR
|
||||
EXTRN $FOR:NEAR
|
||||
EXTRN $IF:NEAR
|
||||
EXTRN $MKDIR:NEAR
|
||||
EXTRN $RMDIR:NEAR
|
||||
EXTRN ADD_NAME_TO_ENVIRONMENT:NEAR
|
||||
EXTRN ADD_PROMPT:NEAR
|
||||
EXTRN build_dir_for_prompt:near
|
||||
EXTRN CATALOG:NEAR
|
||||
EXTRN CHCP:NEAR
|
||||
EXTRN CLS:NEAR
|
||||
EXTRN CNTRLC:NEAR
|
||||
EXTRN COPY:NEAR
|
||||
EXTRN CRENAME:NEAR
|
||||
EXTRN CRLF2:NEAR
|
||||
EXTRN CTIME:NEAR
|
||||
EXTRN CTTY:NEAR
|
||||
EXTRN DATE:NEAR
|
||||
EXTRN ECHO:NEAR
|
||||
EXTRN ERASE:NEAR
|
||||
EXTRN GOTO:NEAR
|
||||
EXTRN IFERLEV:NEAR
|
||||
EXTRN IFEXISTS:NEAR
|
||||
EXTRN IFNOT:NEAR
|
||||
EXTRN PATH:NEAR
|
||||
EXTRN PAUSE:NEAR
|
||||
EXTRN PRINT_B:NEAR
|
||||
EXTRN PRINT_BACK:NEAR
|
||||
EXTRN PRINT_DATE:NEAR
|
||||
EXTRN PRINT_CHAR:NEAR
|
||||
EXTRN PRINT_DRIVE:NEAR
|
||||
EXTRN PRINT_EQ:NEAR
|
||||
EXTRN PRINT_ESC:NEAR
|
||||
EXTRN PRINT_G:NEAR
|
||||
EXTRN PRINT_L:NEAR
|
||||
EXTRN PRINT_TIME:NEAR
|
||||
EXTRN PRINT_VERSION:NEAR
|
||||
EXTRN SHIFT:NEAR
|
||||
EXTRN TCOMMAND:NEAR
|
||||
EXTRN TRUENAME:NEAR ;AN000;
|
||||
EXTRN TYPEFIL:NEAR
|
||||
EXTRN VERSION:NEAR
|
||||
EXTRN VOLUME:NEAR
|
||||
EXTRN VERIFY:NEAR
|
||||
;
|
||||
; WARNING!!! No code may appear after this label!!!!
|
||||
;
|
||||
PUBLIC TranCodeLast
|
||||
TranCodeLast LABEL BYTE
|
||||
TRANCODE ENDS
|
||||
|
||||
; Data for transient portion
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE
|
||||
|
||||
PUBLIC accden_ptr ;AN000;
|
||||
PUBLIC acrlf_ptr ;AN000;
|
||||
PUBLIC arg_buf_ptr ;AN000;
|
||||
PUBLIC badbat_ptr ;AN000;
|
||||
PUBLIC badcd_ptr ;AN000;
|
||||
PUBLIC badCPmes_ptr ;AN000;
|
||||
PUBLIC badcurdrv ;AN000;
|
||||
PUBLIC baddat_ptr ;AN000;
|
||||
PUBLIC baddev_ptr ;AN000;
|
||||
PUBLIC baddrv_ptr ;AN000;
|
||||
PUBLIC badlab_ptr ;AN000;
|
||||
PUBLIC badmkd_ptr ;AN000;
|
||||
PUBLIC badnam_ptr ;AN000;
|
||||
PUBLIC bad_on_off_ptr ;AN000;
|
||||
PUBLIC badPmes_ptr ;AN000;
|
||||
PUBLIC badrmd_ptr ;AN000;
|
||||
PUBLIC badtim_ptr ;AN000;
|
||||
PUBLIC batext
|
||||
PUBLIC bytmes_ptr ;AN000;
|
||||
PUBLIC CLSSTRING
|
||||
PUBLIC comext
|
||||
PUBLIC COMSPECSTR
|
||||
PUBLIC COMTAB
|
||||
PUBLIC copied_ptr ;AN000;
|
||||
PUBLIC cp_active_ptr ;AN000;
|
||||
PUBLIC cp_not_all_ptr ;AN000;
|
||||
PUBLIC cp_not_set_ptr ;AN000;
|
||||
PUBLIC ctrlcmes_ptr ;AN000;
|
||||
PUBLIC curdat_mo_day ;AN000;
|
||||
PUBLIC curdat_ptr ;AN000;
|
||||
PUBLIC curdat_yr ;AN000;
|
||||
PUBLIC curtim_hr_min ;AN000;
|
||||
PUBLIC curtim_ptr ;AN000;
|
||||
PUBLIC curtim_sec_hn ;AN000;
|
||||
PUBLIC dback_ptr ;AN000;
|
||||
PUBLIC del_Y_N_ptr ;AN000;
|
||||
PUBLIC devwmes_ptr ;AN000;
|
||||
PUBLIC dirdattim_ptr ;AN000;
|
||||
PUBLIC dirdat_mo_day ;AN000;
|
||||
PUBLIC dirdat_yr ;AN000;
|
||||
PUBLIC dirhead_ptr ;AN000;
|
||||
PUBLIC dirmes_ptr ;AN000;
|
||||
PUBLIC dirtim_hr_min ;AN000;
|
||||
PUBLIC dirtim_sec_hn ;AN000;
|
||||
PUBLIC DIR_W_SYN ;AN000;
|
||||
PUBLIC disp_file_size_ptr ;AN000;
|
||||
PUBLIC dmes_ptr ;AN000;
|
||||
PUBLIC echomes_ptr ;AN000;
|
||||
PUBLIC enverr_ptr ;AN000;
|
||||
PUBLIC eurdat_ptr ;AN000;
|
||||
PUBLIC exeext
|
||||
PUBLIC extend_buf_off ;AN000;
|
||||
PUBLIC extend_buf_ptr ;AN000;
|
||||
PUBLIC extend_buf_seg ;AN000;
|
||||
PUBLIC extend_buf_sub ;AN000;
|
||||
PUBLIC file_name_ptr ;AN000;
|
||||
PUBLIC fornestmes_ptr ;AN000;
|
||||
PUBLIC fuldir_ptr ;AN000;
|
||||
PUBLIC IFTAB
|
||||
PUBLIC inBdev_ptr ;AN000;
|
||||
PUBLIC inornot_ptr ;AN000;
|
||||
PUBLIC Inv_code_page ;AN000;
|
||||
PUBLIC inval_path_ptr ;AN000;
|
||||
PUBLIC japdat_ptr ;AN000;
|
||||
PUBLIC Losterr_ptr ;AN000;
|
||||
PUBLIC md_exists_ptr ;AN006;
|
||||
PUBLIC msg_cont_flag ;AN000;
|
||||
PUBLIC msg_disp_class ;AN000;
|
||||
PUBLIC needbat_ptr ;AN000;
|
||||
PUBLIC newdat_format ;AN000;
|
||||
PUBLIC newdat_ptr ;AN000;
|
||||
PUBLIC newtim_ptr ;AN000;
|
||||
PUBLIC NLSFUNC_ptr ;AN000;
|
||||
PUBLIC nospace_ptr ;AN000;
|
||||
PUBLIC no_values ;AN000;
|
||||
PUBLIC nulpath_ptr ;AN000;
|
||||
PUBLIC offmes_ptr ;AN000;
|
||||
PUBLIC onmes_ptr ;AN000;
|
||||
PUBLIC overwr_ptr ;AN000;
|
||||
PUBLIC PARSE_BREAK ;AN000;
|
||||
PUBLIC PARSE_CHCP ;AN000;
|
||||
PUBLIC PARSE_CHDIR ;AN000;
|
||||
PUBLIC PARSE_CTTY ;AN000;
|
||||
PUBLIC PARSE_DATE ;AN000;
|
||||
PUBLIC PARSE_DIR ;AN000;
|
||||
PUBLIC PARSE_ERASE ;AN000;
|
||||
PUBLIC PARSE_MRDIR ;AN000;
|
||||
PUBLIC PARSE_RENAME ;AN000;
|
||||
PUBLIC PARSE_TIME ;AN000;
|
||||
PUBLIC PARSE_VOL ;AN000;
|
||||
PUBLIC PATH_TEXT
|
||||
PUBLIC pausemes_ptr ;AN000;
|
||||
PUBLIC pipeEmes_ptr ;AN000;
|
||||
PUBLIC promptdat_moday ;AN000;
|
||||
PUBLIC promptdat_ptr ;AN000;
|
||||
PUBLIC promptdat_yr ;AN000;
|
||||
PUBLIC PROMPT_TABLE
|
||||
PUBLIC PROMPT_TEXT
|
||||
PUBLIC promtim_hr_min ;AN000;
|
||||
PUBLIC promtim_ptr ;AN000;
|
||||
PUBLIC promtim_sec_hn ;AN000;
|
||||
PUBLIC renerr_ptr ;AN000;
|
||||
PUBLIC SLASH_P_SYN ;AN000;
|
||||
PUBLIC string_buf_ptr ;AN000;
|
||||
PUBLIC suremes_ptr ;AN000;
|
||||
PUBLIC switch_list
|
||||
PUBLIC syntmes_ptr ;AN000;
|
||||
PUBLIC tab_ptr ;AN000;
|
||||
PUBLIC TRANDATAEND
|
||||
PUBLIC usadat_ptr ;AN000;
|
||||
PUBLIC verimes_ptr ;AN000;
|
||||
PUBLIC vermes_ptr ;AN000;
|
||||
PUBLIC volmes_ptr ;AN000;
|
||||
PUBLIC volmes_ptr_2 ;AN000;
|
||||
PUBLIC volsermes_ptr ;AN000;
|
||||
PUBLIC WEEKTAB
|
||||
PUBLIC xa_cp ;AN030;
|
||||
|
||||
INCLUDE tranmsg.asm
|
||||
|
||||
CLSSTRING DB 4,01BH,"[2J" ; ANSI Clear screen
|
||||
|
||||
PROMPT_TABLE LABEL BYTE
|
||||
btab "B",Print_B
|
||||
btab "D",PRINT_DATE
|
||||
btab "E",PRINT_ESC
|
||||
btab "G",PRINT_G
|
||||
btab "H",PRINT_BACK
|
||||
btab "L",PRINT_L
|
||||
btab "N",PRINT_DRIVE
|
||||
btab "P",build_dir_for_prompt
|
||||
btab "Q",PRINT_EQ
|
||||
btab "T",PRINT_TIME
|
||||
btab "V",PRINT_VERSION
|
||||
btab "_",CRLF2
|
||||
btab "$",PRINT_CHAR
|
||||
DB 0 ; NUL TERMINATED
|
||||
|
||||
IFTAB LABEL BYTE ; Table of IF conditionals
|
||||
DB 3,"NOT" ; First byte is count
|
||||
DW OFFSET TRANGROUP:IFNOT
|
||||
DB 10,"ERRORLEVEL"
|
||||
DW OFFSET TRANGROUP:IFERLEV
|
||||
DB 5,"EXIST"
|
||||
DW OFFSET TRANGROUP:IFEXISTS
|
||||
DB 0
|
||||
|
||||
; Table for internal command names
|
||||
COMTAB DB 3,"DIR",fSwitchAllowed+fCheckDrive
|
||||
DW OFFSET TRANGROUP:CATALOG ; In TCMD1.ASM
|
||||
DB 4,"CALL",fSwitchAllowed
|
||||
DW OFFSET TRANGROUP:$CALL ; In TBATCH2.ASM
|
||||
DB 4,"CHCP",fSwitchAllowed
|
||||
DW OFFSET TRANGROUP:CHCP ; In TCMD2B.ASM
|
||||
DB 6,"RENAME",fSwitchAllowed+fCheckDrive ;AC018; P3903
|
||||
DW OFFSET TRANGROUP:CRENAME ; In TCMD1.ASM
|
||||
DB 3,"REN",fSwitchAllowed+fCheckDrive ;AC018; P3903
|
||||
DW OFFSET TRANGROUP:CRENAME ; In TCMD1.ASM
|
||||
DB 5,"ERASE",fSwitchAllowed+fCheckDrive
|
||||
DW OFFSET TRANGROUP:ERASE ; In TCMD1.ASM
|
||||
DB 3,"DEL",fSwitchAllowed+fCheckDrive
|
||||
DW OFFSET TRANGROUP:ERASE ; In TCMD1.ASM
|
||||
DB 4,"TYPE",fSwitchAllowed+fCheckDrive ;AC018; P3903
|
||||
DW OFFSET TRANGROUP:TYPEFIL ; In TCMD1.ASM
|
||||
DB 3,"REM",fSwitchAllowed
|
||||
DW OFFSET TRANGROUP:TCOMMAND ; In TCODE.ASM
|
||||
DB 4,"COPY",fSwitchAllowed+fCheckDrive
|
||||
DW OFFSET TRANGROUP:COPY ; In COPY.ASM
|
||||
DB 5,"PAUSE",fSwitchAllowed
|
||||
DW OFFSET TRANGROUP:PAUSE ; In TCMD1.ASM
|
||||
DB 4,"DATE",fSwitchAllowed
|
||||
DW OFFSET TRANGROUP:DATE ; In TPIPE.ASM
|
||||
DB 4,"TIME",fSwitchAllowed ;AC018; P3903
|
||||
DW OFFSET TRANGROUP:CTIME ; In TPIPE.ASM
|
||||
DB 3,"VER",0
|
||||
DW OFFSET TRANGROUP:VERSION ; In TCMD2.ASM
|
||||
DB 3,"VOL",fSwitchAllowed+fCheckDrive ;AC018; P3903
|
||||
DW OFFSET TRANGROUP:VOLUME ; In TCMD1.ASM
|
||||
DB 2,"CD",fSwitchAllowed+fCheckDrive ;AC018; P3903
|
||||
DW OFFSET TRANGROUP:$CHDIR ; In TENV.ASM
|
||||
DB 5,"CHDIR",fSwitchAllowed+fCheckDrive ;AC018; P3903
|
||||
DW OFFSET TRANGROUP:$CHDIR ; In TENV.ASM
|
||||
DB 2,"MD",fSwitchAllowed+fCheckDrive ;AC018; P3903
|
||||
DW OFFSET TRANGROUP:$MKDIR ; In TENV.ASM
|
||||
DB 5,"MKDIR",fSwitchAllowed+fCheckDrive ;AC018; P3903
|
||||
DW OFFSET TRANGROUP:$MKDIR ; In TENV.ASM
|
||||
DB 2,"RD",fSwitchAllowed+fCheckDrive ;AC018; P3903
|
||||
DW OFFSET TRANGROUP:$RMDIR ; In TENV.ASM
|
||||
DB 5,"RMDIR",fSwitchAllowed+fCheckDrive ;AC018; P3903
|
||||
DW OFFSET TRANGROUP:$RMDIR ; In TENV.ASM
|
||||
DB 5,"BREAK",fSwitchAllowed ;AC018; P3903
|
||||
DW OFFSET TRANGROUP:CNTRLC ; In TUCODE.ASM
|
||||
DB 6,"VERIFY",fSwitchAllowed ;AC018; P3903
|
||||
DW OFFSET TRANGROUP:VERIFY ; In TUCODE.ASM
|
||||
DB 3,"SET",fSwitchAllowed
|
||||
DW OFFSET TRANGROUP:ADD_NAME_TO_ENVIRONMENT; In TENV.ASM
|
||||
DB 6,"PROMPT",fSwitchAllowed
|
||||
DW OFFSET TRANGROUP:ADD_PROMPT ; In TENV.ASM
|
||||
DB 4,"PATH",fSwitchAllowed
|
||||
DW OFFSET TRANGROUP:PATH ; In TCMD2.ASM
|
||||
DB 4,"EXIT",0
|
||||
DW OFFSET TRANGROUP:$EXIT ; In TCMD2.ASM
|
||||
DB 4,"CTTY",fCheckDrive+fSwitchAllowed
|
||||
DW OFFSET TRANGROUP:CTTY ; In TCMD2.ASM
|
||||
DB 4,"ECHO",fSwitchAllowed
|
||||
DW OFFSET TRANGROUP:ECHO ; In TUCODE.ASM
|
||||
DB 4,"GOTO",fSwitchAllowed
|
||||
DW OFFSET TRANGROUP:GOTO ; In TBATCH.ASM
|
||||
DB 5,"SHIFT",fSwitchAllowed
|
||||
DW OFFSET TRANGROUP:SHIFT ; In TBATCH.ASM
|
||||
DB 2,"IF",fSwitchAllowed
|
||||
DW OFFSET TRANGROUP:$IF ; In TBATCH.ASM
|
||||
DB 3,"FOR",fSwitchAllowed
|
||||
DW OFFSET TRANGROUP:$FOR ; In TBATCH.ASM
|
||||
DB 3,"CLS",0
|
||||
DW OFFSET TRANGROUP:CLS ; In TCMD2.ASM
|
||||
DB 8,"TRUENAME",fSwitchAllowed+fCheckDrive ;AN000; P3903 changed
|
||||
DW OFFSET TRANGROUP:TRUENAME ;AN000;
|
||||
DB 0 ; Terminate command table
|
||||
|
||||
|
||||
comext dB ".COM"
|
||||
exeext dB ".EXE"
|
||||
batext dB ".BAT"
|
||||
|
||||
switch_list DB "VBAPW" ; flags we can recognize
|
||||
|
||||
|
||||
XA_cp Label byte ;AN030; list for one extended attribute
|
||||
DW 1 ;AN030;
|
||||
DB EAISBINARY ;AN030; type
|
||||
DW EASYSTEM ;AN030; flags
|
||||
DB 2 ;AN030; name length
|
||||
DB "CP" ;AN030; name
|
||||
|
||||
|
||||
|
||||
|
||||
PUBLIC BatBufLen
|
||||
BatBufLen DW BatLen
|
||||
|
||||
; *****************************************************
|
||||
; EMG 4.00
|
||||
; DATA STARTING HERE WAS ADDED BY EMG FOR 4.00
|
||||
; FOR IMPLEMENTATION OF COMMON PARSE ROUTINE
|
||||
; *****************************************************
|
||||
|
||||
;
|
||||
; COMMON PARSE BLOCKS
|
||||
;
|
||||
|
||||
;
|
||||
; Indicates no value list for PARSE.
|
||||
;
|
||||
|
||||
NO_VALUES DW 0 ;AN000; no values
|
||||
|
||||
;
|
||||
; PARSE control block for a required file specification (upper cased)
|
||||
;
|
||||
|
||||
FILE_REQUIRED LABEL BYTE ;AN000;
|
||||
DW 0200H ;AN000; filespec - required
|
||||
DW 1 ;AN000; capitalize - file table
|
||||
DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer
|
||||
DW TRANGROUP:NO_VALUES ;AN000;
|
||||
DB 0 ;AN000; no keywords
|
||||
|
||||
;
|
||||
; PARSE control block for an optional file specification (upper cased)
|
||||
; or drive number
|
||||
;
|
||||
|
||||
FILE_OPTIONAL LABEL BYTE ;AN000;
|
||||
DW 0301H ;AN000; filespec or drive number
|
||||
; optional
|
||||
DW 1 ;AN000; capitalize - file table
|
||||
DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer
|
||||
DW TRANGROUP:NO_VALUES ;AN000;
|
||||
DB 0 ;AN000; no keywords
|
||||
|
||||
;
|
||||
; PARSE control block for an optional file specification (upper cased)
|
||||
;
|
||||
|
||||
FILE_OPTIONAL2 LABEL BYTE ;AN000;
|
||||
DW 0201H ;AN000; filespec or drive number
|
||||
; optional
|
||||
DW 1 ;AN000; capitalize - file table
|
||||
DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer
|
||||
DW TRANGROUP:NO_VALUES ;AN000;
|
||||
DB 0 ;AN000; no keywords
|
||||
|
||||
;
|
||||
; PARSE control block for an optional /P switch
|
||||
;
|
||||
|
||||
SLASH_P_SWITCH LABEL BYTE ;AN000;
|
||||
DW 0 ;AN000; no match flags
|
||||
DW 2 ;AN000; capitalize - char table
|
||||
DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer
|
||||
DW TRANGROUP:NO_VALUES ;AN000;
|
||||
DB 1 ;AN000; 1 keyword
|
||||
SLASH_P_SYN DB "/P",0 ;AN000; /P switch
|
||||
|
||||
|
||||
|
||||
; PARSE BLOCK FOR BREAK, VERIFY, ECHO
|
||||
|
||||
;
|
||||
; The following parse control block can be used for any command which
|
||||
; needs only the optional "ON" and "OFF" keywords as operands. Allows
|
||||
; the equal sign as an additional delimiter. Returns verified result
|
||||
; in PARSE1_OUTPUT. Currently used for the BREAK, VERIFY, and ECHO
|
||||
; internal commands.
|
||||
;
|
||||
|
||||
PARSE_BREAK LABEL BYTE ;AN000;
|
||||
DW TRANGROUP:BREAK_PARMS ;AN000;
|
||||
DB 0 ;AN032; no extra delimiter
|
||||
|
||||
BREAK_PARMS LABEL BYTE ;AN000;
|
||||
DB 0,1 ;AN000; 1 positional parm
|
||||
DW TRANGROUP:BREAK_CONTROL1;AN000;
|
||||
DB 0 ;AN000; no switches
|
||||
DB 0 ;AN000; no keywords
|
||||
|
||||
BREAK_CONTROL1 LABEL BYTE ;AN000;
|
||||
DW 2001H ;AN000; string value - optional
|
||||
DW 2 ;AN000; capitalize - char table
|
||||
DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer
|
||||
DW TRANGROUP:BREAK_VALUES ;AN000;
|
||||
DB 0 ;AN000; no keywords
|
||||
|
||||
BREAK_VALUES LABEL BYTE ;AN000;
|
||||
DB 3 ;AN000;
|
||||
DB 0 ;AN000; no ranges
|
||||
DB 0 ;AN000; no numeric values
|
||||
DB 2 ;AN000; 2 string values
|
||||
DB 0 ;AN000; returned if ON
|
||||
DW TRANGROUP:BREAK_ON ;AN000; point to ON string
|
||||
DB 'f' ;AN000; returned if OFF
|
||||
DW TRANGROUP:BREAK_OFF ;AN000; point to OFF string
|
||||
|
||||
BREAK_ON DB "ON",0 ;AN000;
|
||||
BREAK_OFF DB "OFF",0 ;AN000;
|
||||
|
||||
;
|
||||
; PARSE BLOCK FOR CHCP
|
||||
;
|
||||
|
||||
;
|
||||
; The following parse control block can be used for any command which
|
||||
; needs only one optional three digit decimal parameter for operands.
|
||||
; Returns verified result in PARSE1_OUTPUT. Currently used for the
|
||||
; CHCP internal command.
|
||||
;
|
||||
CHCP_MINVAL EQU 100 ;AN000;
|
||||
CHCP_MAXVAL EQU 999 ;AN000;
|
||||
|
||||
PARSE_CHCP LABEL BYTE ;AN000;
|
||||
DW TRANGROUP:CHCP_PARMS ;AN000;
|
||||
DB 0 ;AN000; no extra delimiter
|
||||
|
||||
CHCP_PARMS LABEL BYTE ;AN000;
|
||||
DB 0,1 ;AN000; 1 positional parm
|
||||
DW TRANGROUP:CHCP_CONTROL1 ;AN000;
|
||||
DB 0 ;AN000; no switches
|
||||
DB 0 ;AN000; no keywords
|
||||
|
||||
CHCP_CONTROL1 LABEL BYTE ;AN000;
|
||||
DW 8001H ;AN000; numeric value - optional
|
||||
DW 0 ;AN000; no function flags
|
||||
DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer
|
||||
DW TRANGROUP:CHCP_VALUES ;AN000;
|
||||
DB 0 ;AN000; no keywords
|
||||
|
||||
CHCP_VALUES LABEL BYTE ;AN000;
|
||||
DB 1 ;AN000;
|
||||
DB 1 ;AN000; 1 range
|
||||
DB 1 ;AN000; returned if result
|
||||
DD CHCP_MINVAL,CHCP_MAXVAL ;AN000; minimum & maximum value
|
||||
DB 0 ;AN000; no numeric values
|
||||
DB 0 ;AN000; no string values
|
||||
|
||||
|
||||
;
|
||||
; PARSE BLOCK FOR DATE
|
||||
;
|
||||
|
||||
;
|
||||
; The following parse control block can be used for any command which
|
||||
; needs only an optional date string as an operand. Returns unverified
|
||||
; result in DATE_OUTPUT. Currently used for the DATE internal command.
|
||||
;
|
||||
|
||||
PARSE_DATE LABEL BYTE ;AN000;
|
||||
DW TRANGROUP:DATE_PARMS ;AN000;
|
||||
DB 0 ;AN000; no extra delimiter
|
||||
|
||||
DATE_PARMS LABEL BYTE ;AN000;
|
||||
DB 0,1 ;AN000; 1 positional parm
|
||||
DW TRANGROUP:DATE_CONTROL1 ;AN000;
|
||||
DB 0 ;AN000; no switches
|
||||
DB 0 ;AN000; no keywords
|
||||
|
||||
DATE_CONTROL1 LABEL BYTE ;AN000;
|
||||
DW 1001H ;AN000; date - optional
|
||||
DW 0 ;AN000; no function flags
|
||||
DW TRANGROUP:DATE_OUTPUT ;AN000; result buffer
|
||||
DW TRANGROUP:NO_VALUES ;AN000;
|
||||
DB 0 ;AN000; no keywords
|
||||
|
||||
;
|
||||
; PARSE BLOCK FOR TIME
|
||||
;
|
||||
|
||||
;
|
||||
; The following parse control block can be used for any command which
|
||||
; needs only an optional time string as an operand. Returns unverified
|
||||
; result in TIME_OUTPUT. Currently used for the TIME internal command.
|
||||
;
|
||||
|
||||
PARSE_TIME LABEL BYTE ;AN000;
|
||||
DW TRANGROUP:TIME_PARMS ;AN000;
|
||||
DB 0 ;AN000; no extra delimiter
|
||||
|
||||
TIME_PARMS LABEL BYTE ;AN000;
|
||||
DB 0,1 ;AN000; 1 positional parm
|
||||
DW TRANGROUP:TIME_CONTROL1 ;AN000;
|
||||
DB 0 ;AN000; no switches
|
||||
DB 0 ;AN000; no keywords
|
||||
|
||||
TIME_CONTROL1 LABEL BYTE ;AN000;
|
||||
DW 0801H ;AN000; TIME - optional
|
||||
DW 0 ;AN000; no function flags
|
||||
DW TRANGROUP:TIME_OUTPUT ;AN000; result buffer
|
||||
DW TRANGROUP:NO_VALUES ;AN000;
|
||||
DB 0 ;AN000; no keywords
|
||||
|
||||
|
||||
;
|
||||
; PARSE BLOCK FOR VOL
|
||||
;
|
||||
|
||||
;
|
||||
; The following parse control block can be used for any command which
|
||||
; needs only an optional drive letter as an operand. Returns unverified
|
||||
; drive number (one based) in DRIVE_OUTPUT. Currently used for the VOL
|
||||
; internal command.
|
||||
;
|
||||
|
||||
PARSE_VOL LABEL BYTE ;AN000;
|
||||
DW TRANGROUP:VOL_PARMS ;AN000;
|
||||
DB 0 ;AN000; no extra delimiter
|
||||
|
||||
VOL_PARMS LABEL BYTE ;AN000;
|
||||
DB 0,1 ;AN000; 1 positional parm
|
||||
DW TRANGROUP:DRIVE_CONTROL1;AN000;
|
||||
DB 0 ;AN000; no switches
|
||||
DB 0 ;AN000; no keywords
|
||||
|
||||
DRIVE_CONTROL1 LABEL BYTE ;AN000;
|
||||
DW 0101H ;AN000; DRIVE - optional
|
||||
DW 1 ;AN000; capitalize - file table
|
||||
DW TRANGROUP:DRIVE_OUTPUT ;AN000; result buffer
|
||||
DW TRANGROUP:NO_VALUES ;AN000;
|
||||
DB 0 ;AN000; no keywords
|
||||
|
||||
|
||||
;
|
||||
; PARSE BLOCK FOR MKDIR, RMDIR, TYPE
|
||||
;
|
||||
|
||||
;
|
||||
; The following parse control block can be used for any command which
|
||||
; needs only one required file specification as an operand. Returns a
|
||||
; pointer to the unverified string in PARSE1_OUTPUT. Currently used
|
||||
; for the MKDIR, RMDIR, and TYPE internal commands.
|
||||
;
|
||||
|
||||
PARSE_MRDIR LABEL BYTE ;AN000;
|
||||
DW TRANGROUP:MRDIR_PARMS ;AN000;
|
||||
DB 0 ;AN000; no extra delimiter
|
||||
|
||||
MRDIR_PARMS LABEL BYTE ;AN000;
|
||||
DB 1,1 ;AN000; 1 positional parm
|
||||
DW TRANGROUP:FILE_REQUIRED ;AN000;
|
||||
DB 0 ;AN000; no switches
|
||||
DB 0 ;AN000; no keywords
|
||||
|
||||
;
|
||||
; PARSE BLOCK FOR CHDIR, TRUENAME
|
||||
;
|
||||
|
||||
;
|
||||
; The following parse control block can be used for any command which
|
||||
; needs only one optional file specification an operand. Returns a
|
||||
; pointer to the unverified string in PARSE1_OUTPUT. Currently used
|
||||
; for the CHDIR and TRUENAME internal commands.
|
||||
;
|
||||
|
||||
PARSE_CHDIR LABEL BYTE ;AN000;
|
||||
DW TRANGROUP:CHDIR_PARMS ;AN000;
|
||||
DB 0 ;AN000; no extra delimiter
|
||||
|
||||
CHDIR_PARMS LABEL BYTE ;AN000;
|
||||
DB 0,1 ;AN000; 1 positional parm
|
||||
DW TRANGROUP:FILE_OPTIONAL ;AN000;
|
||||
DB 0 ;AN000; no switches
|
||||
DB 0 ;AN000; no keywords
|
||||
|
||||
;
|
||||
; PARSE BLOCK FOR ERASE
|
||||
;
|
||||
|
||||
;
|
||||
; The following parse control block is used for the DEL/ERASE internal
|
||||
; commands. This command has one required file specification and an
|
||||
; optional switch (/p) as operands. The verified switch or unverified
|
||||
; file specification is returned in PARSE1_OUTPUT.
|
||||
;
|
||||
|
||||
PARSE_ERASE LABEL BYTE ;AN000;
|
||||
DW TRANGROUP:ERASE_PARMS ;AN000;
|
||||
DB 0 ;AN000; no extra delimiter
|
||||
|
||||
ERASE_PARMS LABEL BYTE ;AN000;
|
||||
DB 1,1 ;AN000; 1 positional parm
|
||||
DW TRANGROUP:FILE_REQUIRED ;AN000;
|
||||
DB 1 ;AN000; 1 switch
|
||||
DW TRANGROUP:SLASH_P_SWITCH;AN000;
|
||||
DB 0 ;AN000; no keywords
|
||||
|
||||
;
|
||||
; PARSE BLOCK FOR DIR
|
||||
;
|
||||
|
||||
;
|
||||
; The following parse control block is used for the DIR internal command.
|
||||
; This command has one optional file specification and two optional
|
||||
; switches (/p and /w) as operands. The verified switch or unverified
|
||||
; file specification is returned in PARSE1_OUTPUT.
|
||||
;
|
||||
|
||||
PARSE_DIR LABEL BYTE ;AN000;
|
||||
DW TRANGROUP:DIR_PARMS ;AN000;
|
||||
DB 0 ;AN000; no extra delimiter
|
||||
|
||||
DIR_PARMS LABEL BYTE ;AN000;
|
||||
DB 0,1 ;AN000; 1 positional parm
|
||||
DW TRANGROUP:FILE_OPTIONAL2;AN000;
|
||||
DB 2 ;AN000; 2 switches
|
||||
DW TRANGROUP:SLASH_P_SWITCH;AN000;
|
||||
DW TRANGROUP:DIR_SWITCH1 ;AN000;
|
||||
DB 0 ;AN000; no keywords
|
||||
|
||||
DIR_SWITCH1 LABEL BYTE ;AN000;
|
||||
DW 0 ;AN000; no match flags
|
||||
DW 2 ;AN000; capitalize by char table
|
||||
DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer
|
||||
DW TRANGROUP:NO_VALUES ;AN000;
|
||||
DB 1 ;AN000; 1 keyword
|
||||
DIR_W_SYN DB "/W",0 ;AN000; /W switch
|
||||
|
||||
;
|
||||
; PARSE BLOCK FOR RENAME
|
||||
;
|
||||
|
||||
;
|
||||
; The following parse control block can be used for any command which
|
||||
; needs only two required file specifications as operands. Returns
|
||||
; pointers to the unverified string in PARSE1_OUTPUT.
|
||||
; Currently used for the RENAME internal command.
|
||||
;
|
||||
|
||||
PARSE_RENAME LABEL BYTE ;AN000;
|
||||
DW TRANGROUP:RENAME_PARMS ;AN000;
|
||||
DB 0 ;AN000; no extra delimiter
|
||||
|
||||
RENAME_PARMS LABEL BYTE ;AN000;
|
||||
DB 2,2 ;AN000; 2 positional parms
|
||||
DW TRANGROUP:FILE_REQUIRED ;AN000;
|
||||
DW TRANGROUP:FILE_REQUIRED ;AN000;
|
||||
DB 0 ;AN000; no switches
|
||||
DB 0 ;AN000; no keywords
|
||||
|
||||
;
|
||||
; PARSE BLOCK FOR CTTY
|
||||
;
|
||||
|
||||
;
|
||||
; The following parse control block can be used for any command which
|
||||
; needs one required device name as an operand. Returns a pointer to
|
||||
; unverified string in PARSE1_OUTPUT. Currently used for the CTTY
|
||||
; internal command.
|
||||
;
|
||||
|
||||
PARSE_CTTY LABEL BYTE ;AN000;
|
||||
DW TRANGROUP:CTTY_PARMS ;AN000;
|
||||
DB 0 ;AN000; no extra delimiter
|
||||
|
||||
CTTY_PARMS LABEL BYTE ;AN000;
|
||||
DB 1,1 ;AN000; 1 positional parm
|
||||
DW TRANGROUP:CTTY_CONTROL1 ;AN000;
|
||||
DB 0 ;AN000; no switches
|
||||
DB 0 ;AN000; no keywords
|
||||
|
||||
CTTY_CONTROL1 LABEL BYTE ;AN000;
|
||||
DW 2000H ;AN000; string value - required
|
||||
DW 11H ;AN000; capitalize - file table
|
||||
;AN000; remove colon at end
|
||||
DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer
|
||||
DW TRANGROUP:NO_VALUES ;AN000;
|
||||
DB 0 ;AN000; no keywords
|
||||
|
||||
TRANDATA ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC BYTE ;AN000;
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
|
||||
INCLUDE SYSMSG.INC ;AN000;
|
||||
|
||||
.list
|
||||
.cref
|
||||
|
||||
ASSUME DS:TRANGROUP,ES:TRANGROUP,CS:TRANGROUP
|
||||
|
||||
MSG_UTILNAME <COMMAND> ;AN000; define utility name
|
||||
|
||||
MSG_SERVICES <COMT,COMMAND.CLF,COMMAND.CL1,COMMAND.CL2> ;AN000; The transient messages
|
||||
|
||||
include msgdcl.inc
|
||||
|
||||
TRANCODE ENDS ;AN000;
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE
|
||||
|
||||
TRANDATAEND LABEL BYTE
|
||||
|
||||
TRANDATA ENDS ;AN000;
|
||||
|
||||
END
|
||||
633
v4.0/src/CMD/COMMAND/TENV.ASM
Normal file
633
v4.0/src/CMD/COMMAND/TENV.ASM
Normal file
@@ -0,0 +1,633 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)tenv.asm 4.2 85/08/16
|
||||
; SCCSID = @(#)tenv.asm 4.2 85/08/16
|
||||
TITLE Part6 COMMAND Transient routines.
|
||||
|
||||
; Environment utilities and misc. routines
|
||||
|
||||
INCLUDE comsw.asm
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE DOSSYM.INC
|
||||
INCLUDE comseg.asm
|
||||
INCLUDE comequ.asm
|
||||
INCLUDE DOSCNTRY.INC ;AN000;
|
||||
.list
|
||||
.cref
|
||||
|
||||
|
||||
DATARES SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN comdrv:byte
|
||||
EXTRN comspec_end:word
|
||||
EXTRN comspec_print:word
|
||||
EXTRN cpdrv:byte
|
||||
EXTRN dbcs_vector_addr:dword ;AN000;
|
||||
EXTRN ENVIRSEG:WORD
|
||||
EXTRN fucase_addr:word ;AC000;
|
||||
EXTRN RESTDIR:BYTE
|
||||
DATARES ENDS
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN arg_buf_ptr:word
|
||||
EXTRN comspec:byte
|
||||
EXTRN comspec_flag:byte
|
||||
EXTRN comspecstr:byte
|
||||
EXTRN ENVERR_PTR:WORD
|
||||
EXTRN PATH_TEXT:byte
|
||||
EXTRN PROMPT_TEXT:byte
|
||||
EXTRN SYNTMES_PTR:WORD
|
||||
TRANDATA ENDS
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN Arg_Buf:BYTE
|
||||
EXTRN RESSEG:WORD
|
||||
EXTRN USERDIR1:BYTE
|
||||
TRANSPACE ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC byte
|
||||
|
||||
ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
|
||||
EXTRN cerror:near
|
||||
|
||||
PUBLIC add_name_to_environment
|
||||
PUBLIC add_prompt
|
||||
PUBLIC delete_path
|
||||
PUBLIC find_name_in_environment
|
||||
PUBLIC find_path
|
||||
PUBLIC find_prompt
|
||||
PUBLIC move_name
|
||||
PUBLIC restudir
|
||||
PUBLIC restudir1
|
||||
PUBLIC scan_double_null
|
||||
PUBLIC scasb2
|
||||
PUBLIC store_char
|
||||
PUBLIC Testkanj ;AN000; 3/3/KK
|
||||
PUBLIC upconv
|
||||
|
||||
BREAK <Environment utilities>
|
||||
ASSUME DS:TRANGROUP
|
||||
|
||||
break Prompt command
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
ADD_PROMPT:
|
||||
CALL DELETE_PROMPT ; DELETE ANY EXISTING PROMPT
|
||||
CALL SCAN_DOUBLE_NULL
|
||||
|
||||
ADD_PROMPT2:
|
||||
PUSH SI
|
||||
CALL GETARG
|
||||
POP SI
|
||||
retz ; PRE SCAN FOR ARGUMENTS
|
||||
CALL MOVE_NAME ; MOVE IN NAME
|
||||
CALL GETARG
|
||||
PUSH SI
|
||||
JMP SHORT ADD_NAME
|
||||
|
||||
|
||||
break The SET command
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
;
|
||||
; Input: DS:SI points to a CR terminated string
|
||||
; Output: carry flag is set if no room
|
||||
; otherwise name is added to environment
|
||||
;
|
||||
|
||||
DISP_ENVj:
|
||||
jmp DISP_ENV
|
||||
|
||||
ADD_NAME_TO_ENVIRONMENT:
|
||||
CALL GETARG
|
||||
JZ DISP_ENVj
|
||||
;
|
||||
; check if line contains exactly one equals sign
|
||||
;
|
||||
XOR BX,BX ;= COUNT IS 0
|
||||
PUSH SI ;SAVE POINTER TO BEGINNING OF LINE
|
||||
|
||||
EQLP:
|
||||
LODSB ;GET A CHAR
|
||||
CMP AL,13 ;IF CR WE'RE ALL DONE
|
||||
JZ QUEQ
|
||||
CMP AL,'=' ;LOOK FOR = SIGN
|
||||
JNZ EQLP ;NOT THERE, GET NEXT CHAR
|
||||
INC BL ;OTHERWISE INCREMENT EQ COUNT
|
||||
CMP BYTE PTR [SI],13 ;LOOK FOR CR FOLLOWING = SIGN
|
||||
JNZ EQLP
|
||||
INC BH ;SET BH=1 MEANS NO PARAMETERS
|
||||
JMP EQLP ;AND LOOK FOR MORE
|
||||
|
||||
QUEQ:
|
||||
POP SI ;RESTORE BEGINNING OF LINE
|
||||
DEC BL ;ZERO FLAG MEANS ONLY ONE EQ
|
||||
JZ ONEQ ;GOOD LINE
|
||||
MOV DX,OFFSET TRANGROUP:SYNTMES_ptr
|
||||
JMP CERROR
|
||||
|
||||
ONEQ:
|
||||
PUSH BX
|
||||
CALL DELETE_NAME_IN_ENVIRONMENT
|
||||
POP BX
|
||||
DEC BH
|
||||
retz
|
||||
|
||||
CALL SCAN_DOUBLE_NULL
|
||||
mov bx,di ; Save ptr to beginning of env var name
|
||||
CALL MOVE_NAME
|
||||
push si
|
||||
xchg bx,di ; Switch ptrs to beginning and end of
|
||||
; env var name
|
||||
;
|
||||
; We want to special-case COMSPEC. This is to reduce the amount of code
|
||||
; necessary in the resident for re-reading the transient. Let's look for
|
||||
; COMSPEC=
|
||||
;
|
||||
mov si,offset trangroup:comspecstr ; Load ptr to string "COMSPEC"
|
||||
mov cx,4 ; If the new env var is comspec, set
|
||||
repz cmpsw ; the comspec_flag
|
||||
;
|
||||
; Zero set => exact match
|
||||
;
|
||||
jnz not_comspec
|
||||
mov comspec_flag,1
|
||||
|
||||
not_comspec:
|
||||
mov di,bx ; Load ptr to end of env var name
|
||||
|
||||
ADD_NAME: ; Add the value of the new env var
|
||||
pop si ; to the environment.
|
||||
push si
|
||||
|
||||
add_name1:
|
||||
LODSB
|
||||
CMP AL,13
|
||||
jz add_name_ret
|
||||
CALL STORE_CHAR
|
||||
JMP ADD_NAME1
|
||||
|
||||
add_name_ret:
|
||||
pop si
|
||||
cmp comspec_flag,0 ; If the new env var is comspec,
|
||||
retz ; copy the value into the
|
||||
;
|
||||
; We have changed the COMSPEC variable. We need to update the resident
|
||||
; pieces necessary to reread in the info. First, skip all delimiters
|
||||
;
|
||||
invoke ScanOff
|
||||
mov es,[resseg] ; comspec var in the resident
|
||||
assume es:resgroup
|
||||
;
|
||||
; Make sure that the printer knows where the beginning of the string is
|
||||
;
|
||||
mov di,offset resgroup:comspec
|
||||
mov bx,di
|
||||
;
|
||||
; Generate drive letter for display
|
||||
;
|
||||
xor ax,ax ;g assume no drive first
|
||||
mov comdrv,al ;g
|
||||
push ax ;AN000; 3/3/KK
|
||||
mov al,[si] ;AN000; 3/3/KK
|
||||
call testkanj ;AN000; 3/3/KK
|
||||
pop ax ;AN000; 3/3/KK
|
||||
jnz GotDrive
|
||||
cmp byte ptr [si+1],':' ; drive specified?
|
||||
jnz GotDrive
|
||||
mov al,[si] ; get his specified drive
|
||||
call UpConv ; convert to uppercase
|
||||
sub al,'A' ; convert to 0-based
|
||||
add di,2
|
||||
inc al ; convert to 1-based number
|
||||
mov comdrv,al
|
||||
;
|
||||
; Stick the drive letter in the prompt message. Nothing special needs to be
|
||||
; done here..
|
||||
;
|
||||
|
||||
add al,'A'-1
|
||||
|
||||
GotDrive: ;g
|
||||
mov comspec_print,di ;g point to beginning of name after drive
|
||||
mov es:cpdrv,al
|
||||
;
|
||||
; Copy chars until delim
|
||||
;
|
||||
|
||||
mov di,bx
|
||||
|
||||
copy_comspec:
|
||||
lodsb
|
||||
invoke Delim
|
||||
jz CopyDone
|
||||
cmp al,13
|
||||
jz CopyDone
|
||||
stosb
|
||||
jmp short copy_comspec
|
||||
|
||||
CopyDone:
|
||||
xor al,al ; Null terminate the string and quit
|
||||
stosb
|
||||
mov comspec_flag,0
|
||||
dec di
|
||||
mov comspec_end,di
|
||||
|
||||
ret
|
||||
|
||||
DISP_ENV:
|
||||
MOV DS,[RESSEG]
|
||||
ASSUME DS:RESGROUP
|
||||
MOV DS,[ENVIRSEG]
|
||||
ASSUME DS:NOTHING
|
||||
XOR SI,SI
|
||||
|
||||
PENVLP:
|
||||
CMP BYTE PTR [SI],0
|
||||
retz
|
||||
mov di,offset trangroup:arg_buf
|
||||
|
||||
PENVLP2:
|
||||
LODSB
|
||||
stosb
|
||||
OR AL,AL
|
||||
JNZ PENVLP2
|
||||
mov dx,offset trangroup:arg_buf_ptr
|
||||
push ds
|
||||
push es
|
||||
pop ds
|
||||
invoke printf_crlf
|
||||
pop ds
|
||||
JMP PENVLP
|
||||
|
||||
ASSUME DS:TRANGROUP
|
||||
|
||||
DELETE_PATH:
|
||||
MOV SI,OFFSET TRANGROUP:PATH_TEXT
|
||||
JMP SHORT DELETE_NAME_IN_environment
|
||||
|
||||
DELETE_PROMPT:
|
||||
MOV SI,OFFSET TRANGROUP:PROMPT_TEXT
|
||||
|
||||
DELETE_NAME_IN_environment:
|
||||
;
|
||||
; Input: DS:SI points to a "=" terminated string
|
||||
; Output: carry flag is set if name not found
|
||||
; otherwise name is deleted
|
||||
;
|
||||
PUSH SI
|
||||
PUSH DS
|
||||
CALL FIND ; ES:DI POINTS TO NAME
|
||||
JC DEL1
|
||||
MOV SI,DI ; SAVE IT
|
||||
CALL SCASB2 ; SCAN FOR THE NUL
|
||||
XCHG SI,DI
|
||||
CALL GETENVSIZ
|
||||
SUB CX,SI
|
||||
PUSH ES
|
||||
POP DS ; ES:DI POINTS TO NAME, DS:SI POINTS TO NEXT NAME
|
||||
REP MOVSB ; DELETE THE NAME
|
||||
|
||||
DEL1:
|
||||
POP DS
|
||||
POP SI
|
||||
return
|
||||
|
||||
FIND_PATH:
|
||||
MOV SI,OFFSET TRANGROUP:PATH_TEXT
|
||||
JMP SHORT FIND_NAME_IN_environment
|
||||
|
||||
FIND_PROMPT:
|
||||
MOV SI,OFFSET TRANGROUP:PROMPT_TEXT
|
||||
|
||||
FIND_NAME_IN_environment:
|
||||
;
|
||||
; Input: DS:SI points to a "=" terminated string
|
||||
; Output: ES:DI points to the arguments in the environment
|
||||
; zero is set if name not found
|
||||
; carry flag is set if name not valid format
|
||||
;
|
||||
CALL FIND ; FIND THE NAME
|
||||
retc ; CARRY MEANS NOT FOUND
|
||||
JMP SCASB1 ; SCAN FOR = SIGN
|
||||
;
|
||||
; On return of FIND1, ES:DI points to beginning of name
|
||||
;
|
||||
FIND:
|
||||
CLD
|
||||
CALL COUNT0 ; CX = LENGTH OF NAME
|
||||
MOV ES,[RESSEG]
|
||||
ASSUME ES:RESGROUP
|
||||
MOV ES,[ENVIRSEG]
|
||||
ASSUME ES:NOTHING
|
||||
XOR DI,DI
|
||||
|
||||
FIND1:
|
||||
PUSH CX
|
||||
PUSH SI
|
||||
PUSH DI
|
||||
|
||||
FIND11:
|
||||
LODSB
|
||||
CALL TESTKANJ
|
||||
JZ NOTKANJ3
|
||||
DEC SI
|
||||
LODSW
|
||||
INC DI
|
||||
INC DI
|
||||
CMP AX,ES:[DI-2]
|
||||
JNZ FIND12
|
||||
DEC CX
|
||||
LOOP FIND11
|
||||
JMP SHORT FIND12
|
||||
|
||||
NOTKANJ3:
|
||||
CALL UPCONV
|
||||
INC DI
|
||||
CMP AL,ES:[DI-1]
|
||||
JNZ FIND12
|
||||
LOOP FIND11
|
||||
|
||||
FIND12:
|
||||
POP DI
|
||||
POP SI
|
||||
POP CX
|
||||
retz
|
||||
PUSH CX
|
||||
CALL SCASB2 ; SCAN FOR A NUL
|
||||
POP CX
|
||||
CMP BYTE PTR ES:[DI],0
|
||||
JNZ FIND1
|
||||
STC ; INDICATE NOT FOUND
|
||||
return
|
||||
|
||||
COUNT0:
|
||||
PUSH DS
|
||||
POP ES
|
||||
MOV DI,SI
|
||||
|
||||
COUNT1:
|
||||
PUSH DI ; COUNT NUMBER OF CHARS UNTIL "="
|
||||
CALL SCASB1
|
||||
JMP SHORT COUNTX
|
||||
|
||||
COUNT2:
|
||||
PUSH DI ; COUNT NUMBER OF CHARS UNTIL NUL
|
||||
CALL SCASB2
|
||||
|
||||
COUNTX:
|
||||
POP CX
|
||||
SUB DI,CX
|
||||
XCHG DI,CX
|
||||
return
|
||||
|
||||
MOVE_NAME:
|
||||
CMP BYTE PTR DS:[SI],13
|
||||
retz
|
||||
LODSB
|
||||
|
||||
;;;; IF KANJI 3/3/KK
|
||||
CALL TESTKANJ
|
||||
JZ NOTKANJ1
|
||||
CALL STORE_CHAR
|
||||
LODSB
|
||||
CALL STORE_CHAR
|
||||
JMP SHORT MOVE_NAME
|
||||
|
||||
NOTKANJ1:
|
||||
;;;; ENDIF 3/3/KK
|
||||
|
||||
CALL UPCONV
|
||||
CALL STORE_CHAR
|
||||
CMP AL,'='
|
||||
JNZ MOVE_NAME
|
||||
return
|
||||
|
||||
GETARG:
|
||||
MOV SI,80H
|
||||
LODSB
|
||||
OR AL,AL
|
||||
retz
|
||||
invoke SCANOFF
|
||||
CMP AL,13
|
||||
return
|
||||
|
||||
;
|
||||
; Point ES:DI to the final NULL string. Note that in an empty environment,
|
||||
; there is NO double NULL, merely a string that is empty.
|
||||
;
|
||||
SCAN_DOUBLE_NULL:
|
||||
MOV ES,[RESSEG]
|
||||
ASSUME ES:RESGROUP
|
||||
MOV ES,[ENVIRSEG]
|
||||
ASSUME ES:NOTHING
|
||||
XOR DI,DI
|
||||
;
|
||||
; Top cycle-point. If the string here is empty, then we are done
|
||||
;
|
||||
SDN1:
|
||||
cmp byte ptr es:[di],0 ; nul string?
|
||||
retz ; yep, all done
|
||||
CALL SCASB2
|
||||
JMP SDN1
|
||||
|
||||
SCASB1:
|
||||
MOV AL,'=' ; SCAN FOR AN =
|
||||
JMP SHORT SCASBX
|
||||
SCASB2:
|
||||
XOR AL,AL ; SCAN FOR A NUL
|
||||
SCASBX:
|
||||
MOV CX,100H
|
||||
REPNZ SCASB
|
||||
return
|
||||
|
||||
TESTKANJ:
|
||||
push ds ;AN000; 3/3/KK
|
||||
push si ;AN000; 3/3/KK
|
||||
push ax ;AN000; 3/3/KK
|
||||
mov ds,cs:[resseg] ;AN000; Get resident segment
|
||||
assume ds:resgroup ;AN000;
|
||||
lds si,dbcs_vector_addr ;AN000; get DBCS vector
|
||||
ktlop: ;AN000; 3/3/KK
|
||||
cmp word ptr ds:[si],0 ;AN000; end of Table 3/3/KK
|
||||
je notlead ;AN000; 3/3/KK
|
||||
pop ax ;AN000; 3/3/KK
|
||||
push ax ;AN000; 3/3/KK
|
||||
cmp al, byte ptr ds:[si] ;AN000; 3/3/KK
|
||||
jb notlead ;AN000; 3/3/KK
|
||||
inc si ;AN000; 3/3/KK
|
||||
cmp al, byte ptr ds:[si] ;AN000; 3/3/KK
|
||||
jbe islead ;AN000; 3/3/KK
|
||||
inc si ;AN000; 3/3/KK
|
||||
jmp short ktlop ;AN000; try another range ; 3/3/KK
|
||||
Notlead: ;AN000; 3/3/KK
|
||||
xor ax,ax ;AN000; set zero 3/3/KK
|
||||
jmp short ktret ;AN000; 3/3/KK
|
||||
Islead: ;AN000; 3/3/KK
|
||||
xor ax,ax ;AN000; reset zero 3/3/KK
|
||||
inc ax ;AN000; 3/3/KK
|
||||
ktret: ;AN000; 3/3/KK
|
||||
pop ax ;AN000; 3/3/KK
|
||||
pop si ;AN000; 3/3/KK
|
||||
pop ds ;AN000; 3/3/KK
|
||||
return ;AN000; 3/3/KK
|
||||
;------------------------------------- ;3/3/KK
|
||||
|
||||
|
||||
; ****************************************************************
|
||||
; *
|
||||
; * ROUTINE: UPCONV (ADDED BY EMG 4.00)
|
||||
; *
|
||||
; * FUNCTION: This routine returns the upper case equivalent of
|
||||
; * the character in AL from the file upper case table
|
||||
; * in DOS if character if above ascii 128, else
|
||||
; * subtracts 20H if between "a" and "z".
|
||||
; *
|
||||
; * INPUT: AL char to be upper cased
|
||||
; * FUCASE_ADDR set to the file upper case table
|
||||
; *
|
||||
; * OUTPUT: AL upper cased character
|
||||
; *
|
||||
; ****************************************************************
|
||||
|
||||
assume ds:trangroup ;AN000;
|
||||
|
||||
upconv proc near ;AN000;
|
||||
|
||||
cmp al,80h ;AN000; see if char is > ascii 128
|
||||
jb oth_fucase ;AN000; no - upper case math
|
||||
sub al,80h ;AN000; only upper 128 chars in table
|
||||
push ds ;AN000;
|
||||
push bx ;AN000;
|
||||
mov ds,[resseg] ;AN000; get resident data segment
|
||||
assume ds:resgroup ;AN000;
|
||||
lds bx,dword ptr fucase_addr+1 ;AN000; get table address
|
||||
add bx,2 ;AN000; skip over first word
|
||||
xlat ds:byte ptr [bx] ;AN000; convert to upper case
|
||||
pop bx ;AN000;
|
||||
pop ds ;AN000;
|
||||
assume ds:trangroup ;AN000;
|
||||
jmp short upconv_end ;AN000; we finished - exit
|
||||
|
||||
oth_fucase: ;AN000;
|
||||
cmp al,small_a ;AC000; if between "a" and "z",
|
||||
jb upconv_end ;AC000; subtract 20h to get
|
||||
cmp al,small_z ;AC000; upper case equivalent.
|
||||
ja upconv_end ;AC000;
|
||||
sub al,20h ;AC000; Change lower-case to upper
|
||||
|
||||
upconv_end: ;AN000;
|
||||
ret
|
||||
|
||||
upconv endp ;AN000;
|
||||
|
||||
|
||||
;
|
||||
; STORE A CHAR IN environment, GROWING IT IF NECESSARY
|
||||
;
|
||||
STORE_CHAR:
|
||||
PUSH CX
|
||||
PUSH BX
|
||||
PUSH ES ;AN056;
|
||||
PUSH DS ;AN056; Save local DS
|
||||
MOV DS,[RESSEG] ;AN056; Get resident segment
|
||||
ASSUME DS:RESGROUP ;AN056;
|
||||
MOV ES,[ENVIRSEG] ;AN056; Get environment segment
|
||||
ASSUME ES:NOTHING ;AN056;
|
||||
POP DS ;AN056; Get local segment back
|
||||
ASSUME DS:TRANGROUP ;AN056;
|
||||
CALL GETENVSIZ
|
||||
MOV BX,CX
|
||||
SUB BX,2 ; SAVE ROOM FOR DOUBLE NULL
|
||||
CMP DI,BX
|
||||
JB STORE1
|
||||
|
||||
PUSH AX
|
||||
PUSH CX
|
||||
PUSH BX ; Save Size of environment
|
||||
invoke FREE_TPA
|
||||
POP BX
|
||||
ADD BX,2 ; Recover true environment size
|
||||
|
||||
CMP BX, 8000H ; Don't let environment grow > 32K
|
||||
JB ENVSIZ_OK
|
||||
BAD_ENV_SIZE: ;AN056;
|
||||
STC
|
||||
JMP ENVNOSET
|
||||
ENVSIZ_OK:
|
||||
|
||||
MOV CL,4
|
||||
SHR BX,CL ; Convert back to paragraphs
|
||||
INC BX ; Try to grow environment by one para
|
||||
MOV CX,ES ;AN056; Get environment segment
|
||||
ADD CX,BX ;AN056; Add in size of environment
|
||||
ADD CX,020H ;AN056; Add in some TPA
|
||||
MOV AX,CS ;AN056; Get the transient segment
|
||||
CMP CX,AX ;AN056; Are we hitting the transient?
|
||||
JNB BAD_ENV_SIZE ;AN056; Yes - don't do it!!!
|
||||
MOV AH,SETBLOCK
|
||||
INT int_command
|
||||
ENVNOSET:
|
||||
PUSHF
|
||||
PUSH ES
|
||||
MOV ES,[RESSEG]
|
||||
invoke ALLOC_TPA
|
||||
POP ES
|
||||
POPF
|
||||
POP CX
|
||||
POP AX
|
||||
JNC STORE1
|
||||
POP ES ;AN056;
|
||||
MOV DX,OFFSET TRANGROUP:ENVERR_ptr
|
||||
JMP CERROR
|
||||
STORE1:
|
||||
STOSB
|
||||
MOV WORD PTR ES:[DI],0 ; NULL IS AT END
|
||||
POP ES ;AN056;
|
||||
POP BX
|
||||
POP CX
|
||||
return
|
||||
|
||||
GETENVSIZ:
|
||||
;Get size of environment in bytes, rounded up to paragraph boundry
|
||||
;ES has environment segment
|
||||
;Size returned in CX, all other registers preserved
|
||||
|
||||
PUSH ES
|
||||
PUSH AX
|
||||
MOV AX,ES
|
||||
DEC AX ;Point at arena
|
||||
MOV ES,AX
|
||||
MOV AX,ES:[arena_size]
|
||||
MOV CL,4
|
||||
SHL AX,CL ;Convert to bytes
|
||||
MOV CX,AX
|
||||
POP AX
|
||||
POP ES
|
||||
return
|
||||
|
||||
|
||||
ASSUME DS:TRANGROUP
|
||||
|
||||
|
||||
RESTUDIR1:
|
||||
PUSH DS
|
||||
MOV DS,[RESSEG]
|
||||
ASSUME DS:RESGROUP
|
||||
CMP [RESTDIR],0
|
||||
POP DS
|
||||
ASSUME DS:TRANGROUP
|
||||
retz
|
||||
|
||||
RESTUDIR:
|
||||
MOV DX,OFFSET TRANGROUP:USERDIR1
|
||||
MOV AH,CHDIR
|
||||
INT int_command ; Restore users DIR
|
||||
XOR AL,AL
|
||||
invoke SETREST
|
||||
RET56:
|
||||
return
|
||||
|
||||
trancode ends
|
||||
end
|
||||
663
v4.0/src/CMD/COMMAND/TENV2.ASM
Normal file
663
v4.0/src/CMD/COMMAND/TENV2.ASM
Normal file
@@ -0,0 +1,663 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)tenv2.asm 1.1 85/05/14
|
||||
; SCCSID = @(#)tenv2.asm 1.1 85/05/14
|
||||
TITLE Part6 COMMAND Transient routines.
|
||||
|
||||
; Environment utilities and misc. routines
|
||||
|
||||
INCLUDE comsw.asm
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE DOSSYM.INC
|
||||
INCLUDE comseg.asm
|
||||
INCLUDE comequ.asm
|
||||
.list
|
||||
.cref
|
||||
|
||||
|
||||
DATARES SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN pipeflag:byte
|
||||
DATARES ENDS
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN ACRLF_PTR:WORD
|
||||
EXTRN BadCD_Ptr:WORD
|
||||
EXTRN Badmkd_ptr:word
|
||||
EXTRN BADRMD_PTR:WORD
|
||||
EXTRN Extend_buf_ptr:word ;AN000;
|
||||
EXTRN Extend_buf_sub:byte ;AN022;
|
||||
EXTRN MD_exists_ptr:word ;AN006;
|
||||
EXTRN msg_disp_class:byte ;AC000;
|
||||
EXTRN NOSPACE_PTR:WORD
|
||||
EXTRN parse_chdir:byte ;AC000;
|
||||
EXTRN parse_mrdir:byte ;AC000;
|
||||
EXTRN PIPEEMES_PTR:WORD
|
||||
EXTRN string_buf_ptr:word
|
||||
TRANDATA ENDS
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN CURDRV:BYTE
|
||||
EXTRN DESTINFO:BYTE
|
||||
EXTRN DESTTAIL:WORD
|
||||
EXTRN DIRCHAR:BYTE
|
||||
EXTRN dirflag:byte ;AN015;
|
||||
EXTRN KPARSE:BYTE ;AC000; 3/3/KK
|
||||
EXTRN msg_numb:word ;AN022;
|
||||
EXTRN parse1_addr:dword ;AC000;
|
||||
EXTRN parse1_type:byte ;AC000;
|
||||
EXTRN PATHPOS:WORD
|
||||
EXTRN RESSEG:WORD
|
||||
EXTRN srcxname:byte ;AC000;
|
||||
EXTRN string_ptr_2:word
|
||||
EXTRN SWITCHAR:BYTE
|
||||
EXTRN USERDIR1:BYTE
|
||||
TRANSPACE ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC byte
|
||||
|
||||
ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
|
||||
EXTRN cerror:near
|
||||
|
||||
PUBLIC $chdir
|
||||
PUBLIC $mkdir
|
||||
PUBLIC $rmdir
|
||||
PUBLIC crlf2
|
||||
PUBLIC crprint
|
||||
PUBLIC delim
|
||||
PUBLIC error_output
|
||||
PUBLIC fcb_to_ascz
|
||||
PUBLIC pathchrcmp
|
||||
PUBLIC pathcrunch
|
||||
PUBLIC savudir
|
||||
PUBLIC savudir1
|
||||
PUBLIC scanoff
|
||||
PUBLIC strcomp
|
||||
|
||||
break $Chdir
|
||||
|
||||
; ****************************************************************
|
||||
; *
|
||||
; * ROUTINE: $CHDIR
|
||||
; *
|
||||
; * FUNCTION: Entry point for CHDIR command. Parse the command
|
||||
; * line. If path is found, CHDIR to path. If a drive
|
||||
; * letter is found, get and display the current dir
|
||||
; * of the specified drive. If nothing is found, get
|
||||
; * and display the current dir of the default drive.
|
||||
; *
|
||||
; * INPUT: command line at offset 81H
|
||||
; *
|
||||
; * OUTPUT: none
|
||||
; *
|
||||
; ****************************************************************
|
||||
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
$CHDIR:
|
||||
|
||||
mov si,81H
|
||||
mov di,offset trangroup:parse_chdir ;AN000; Get adderss of PARSE_CHDIR
|
||||
xor cx,cx ;AN000; clear cx,dx
|
||||
xor dx,dx ;AN000;
|
||||
invoke parse_with_msg ;AC018; call parser
|
||||
|
||||
cmp ax,end_of_line ;AC000; are we at end of line?
|
||||
jz bwdJ ; No args
|
||||
cmp ax,result_no_error ;AC000; did we have an error?
|
||||
jnz ChDirErr ;AC018; yes - exit
|
||||
|
||||
cmp parse1_type,result_drive ;AC000; was a drive entered?
|
||||
jnz REALCD ; no
|
||||
;
|
||||
; D: was found. See if there is anything more.
|
||||
;
|
||||
mov di,offset trangroup:parse_chdir ;AC000; get address of parse_chdir
|
||||
xor dx,dx ;AC000;
|
||||
invoke parse_check_eol ;AC000; call parser
|
||||
jnz ChDirErr ;AC000;
|
||||
|
||||
bwdJ:
|
||||
invoke build_dir_for_chdir ; Drive only specified
|
||||
call crlf2
|
||||
return
|
||||
|
||||
REALCD:
|
||||
|
||||
push si ;AN000; save position in line
|
||||
lds si,parse1_addr ;AN000; get address of filespec
|
||||
invoke move_to_srcbuf ;AN000; move to srcbuf
|
||||
pop si ;AN000; restore position in line
|
||||
mov di,offset trangroup:parse_chdir ;AC000; get address of parse_chdir
|
||||
xor dx,dx ;AC000;
|
||||
invoke parse_check_eol ;AC000; call parser
|
||||
jnz ChDirErr ;AC000;
|
||||
|
||||
invoke SETPATH
|
||||
TEST [DESTINFO],2
|
||||
JNZ BadChdir
|
||||
MOV AH,CHDIR
|
||||
INT int_command
|
||||
retnc
|
||||
|
||||
invoke get_ext_error_number ;AN022; get the extended error
|
||||
cmp ax,error_path_not_found ;AN022; see if path not found
|
||||
jz BadChDir ;AN022; yes - issue old message
|
||||
call Set_Ext_Error_Subst ;AN022;
|
||||
jmp short chdirerr ;AN022;
|
||||
|
||||
BadChDir:
|
||||
MOV DX,OFFSET TRANGROUP:BADCD_ptr
|
||||
|
||||
ChDirErr:
|
||||
invoke Std_Eprintf
|
||||
return
|
||||
|
||||
break $Mkdir
|
||||
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
$MKDIR:
|
||||
CALL SETRMMK
|
||||
JC MkDirErr
|
||||
MOV AH,MKDIR
|
||||
INT int_command
|
||||
retnc
|
||||
|
||||
invoke get_ext_error_number ;AN022; get the extended error
|
||||
cmp ax,error_path_not_found ;AN022; see if path not found
|
||||
jz MD_other_err ;AN022; yes - issue old message
|
||||
cmp ax,error_access_denied ;AN022; access denied?
|
||||
jz badmderr ;AN022; yes - see if file exists
|
||||
|
||||
call Set_Ext_Error_Subst ;AN022;
|
||||
jmp short MkDirerr ;AC022; yes - go print it
|
||||
|
||||
BADMDERR:
|
||||
mov dx,offset trangroup:srcxname ;AN006; Set Disk transfer address
|
||||
mov ah,Set_DMA ;AN006;
|
||||
int int_command ;AN006;
|
||||
MOV AH,Find_First ;AN006; see if file/dir exists
|
||||
mov cx,attr_directory ;AN006; search for directory
|
||||
INT int_command ;AN006;
|
||||
jc MD_other_err ;AN006; doesn't exist - must be something else
|
||||
mov dl,srcxname.find_buf_attr ;AN006; we found a file/dir
|
||||
test dl,attr_directory ;AN006; was it a directory?
|
||||
jz MD_other_err ;AN006; no - must have been a file
|
||||
mov dx,offset trangroup:MD_exists_ptr ;AN006; set up already exists error
|
||||
jmp short MkDirErr ;AN006; make sure we didn't have network error
|
||||
MD_other_err: ;AN006;
|
||||
MOV DX,OFFSET TRANGROUP:BADMKD_ptr
|
||||
MkDirErr:
|
||||
invoke Std_Eprintf
|
||||
return
|
||||
|
||||
Break <Common MkDir/RmDir set up code>
|
||||
|
||||
;****************************************************************
|
||||
;*
|
||||
;* ROUTINE: SETRMMK
|
||||
;*
|
||||
;* FUNCTION: Parse routine for the internal MKDIR and RMDIR
|
||||
;* commands. Parses the command line for a required
|
||||
;* filespec.
|
||||
;*
|
||||
;* INPUT: command line at offset 81H
|
||||
;*
|
||||
;* OUTPUT: carry clear
|
||||
;* DS:DX points to ASCIIZ argument
|
||||
;* carry set
|
||||
;* DS:DX has error message pointer
|
||||
;*
|
||||
;****************************************************************
|
||||
|
||||
SETRMMK:
|
||||
mov si,81H
|
||||
mov di,offset trangroup:parse_mrdir ;AN000; Get adderss of PARSE_MRDIR
|
||||
xor cx,cx ;AN000; clear cx,dx
|
||||
xor dx,dx ;AN000;
|
||||
invoke parse_with_msg ;AC000; call parser
|
||||
cmp ax,result_no_error ;AC000; did we have an error?
|
||||
jnz NOARGERR ;AC000; yes - exit
|
||||
|
||||
mov di,offset trangroup:srcxname ;AN000; get address of srcxname
|
||||
push di ;AN000; save address
|
||||
push si ;AN000; save position in line
|
||||
lds si,parse1_addr ;AN000; get address of path
|
||||
|
||||
mrdir_move_filename: ;AN000; put filespec in srcxname
|
||||
lodsb ;get a char from buffer
|
||||
stosb ;AN000; store in srcxname
|
||||
cmp al,end_of_line_out ;AC000; it char a terminator?
|
||||
jnz mrdir_move_filename ;AC000; no - keep moving
|
||||
pop si ;AN000; get line position back
|
||||
|
||||
;
|
||||
; we have scanned an argument. See if any args beyond.
|
||||
;
|
||||
|
||||
mov di,offset trangroup:parse_mrdir ;AC000; get address of parse_mrdir
|
||||
invoke parse_check_eol ;AC000; are we at end of line?
|
||||
pop dx ;AC000; get address of SRCXNAME
|
||||
retz ;yes - return no error
|
||||
NOARGERR:
|
||||
mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
|
||||
XOR AX,AX
|
||||
STC
|
||||
return
|
||||
|
||||
break $Rmdir
|
||||
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
$RMDIR:
|
||||
CALL SETRMMK
|
||||
JC RmDirErr
|
||||
JNZ BADRDERR
|
||||
MOV AH,RMDIR
|
||||
INT int_command
|
||||
retnc
|
||||
|
||||
invoke get_ext_error_number ;AN022; get the extended error
|
||||
cmp ax,error_path_not_found ;AN022; see if path not found
|
||||
jz badrderr ;AN022; yes - issue old message
|
||||
cmp ax,error_access_denied ;AN022; access denied?
|
||||
jz badrderr ;AN022; yes - issue old message
|
||||
|
||||
call Set_Ext_Error_Subst ;AN022;
|
||||
jmp short RmDirerr ;AC022; yes - go print it
|
||||
|
||||
BADRDERR:
|
||||
MOV DX,OFFSET TRANGROUP:BADRMD_ptr
|
||||
|
||||
RmDirErr:
|
||||
invoke STD_Eprintf
|
||||
return
|
||||
|
||||
;****************************************************************
|
||||
;*
|
||||
;* ROUTINE: Set_ext_error_subst
|
||||
;*
|
||||
;* FUNCTION: Sets up substitution for extended error
|
||||
;*
|
||||
;* INPUT: AX - extended error number
|
||||
;* DX - offset of string
|
||||
;*
|
||||
;* OUTPUT: Extend_Buf_Ptr set up for STD_EPRINTF
|
||||
;*
|
||||
;****************************************************************
|
||||
|
||||
Set_ext_error_subst proc near ;AN022;
|
||||
|
||||
mov msg_disp_class,ext_msg_class ;AN022; set up extended error msg class
|
||||
mov string_ptr_2,dx ;AN022; get address of failed string
|
||||
mov Extend_buf_sub,one_subst ;AN022; put number of subst in control block
|
||||
mov dx,offset TranGroup:Extend_Buf_ptr ;AN022; get extended message pointer
|
||||
mov Extend_Buf_ptr,ax ;AN022; get message number in control block
|
||||
|
||||
ret ;AN022; return
|
||||
|
||||
Set_ext_error_subst endp ;AN022;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Break <SavUDir - preserve the users current directory on a particular drive>
|
||||
|
||||
;
|
||||
; SavUDir - move the user's current directory on a drive into UserDir1
|
||||
; SavUDir1 - move the user's current directory on a drive into a specified
|
||||
; buffer
|
||||
;
|
||||
; Inputs: DL has 1-based drive number
|
||||
; ES:DI has destination buffer (SavUDir1 only)
|
||||
; Outputs: Carry Clear
|
||||
; DS = TranGroup
|
||||
; Carry Set
|
||||
; AX has error code
|
||||
; Registers Modified: AX, SI
|
||||
;
|
||||
|
||||
SAVUDIR:
|
||||
MOV DI,OFFSET TRANGROUP:USERDIR1
|
||||
|
||||
SAVUDIR1:
|
||||
MOV AL,DL
|
||||
ADD AL,'@'
|
||||
CMP AL,'@'
|
||||
JNZ GOTUDRV
|
||||
ADD AL,[CURDRV]
|
||||
INC AL ; A = 1
|
||||
|
||||
GOTUDRV:
|
||||
STOSB
|
||||
MOV AH,[DIRCHAR]
|
||||
MOV AL,':'
|
||||
STOSW
|
||||
PUSH ES
|
||||
POP DS
|
||||
ASSUME DS:NOTHING
|
||||
|
||||
MOV SI,DI
|
||||
MOV AH,CURRENT_DIR ; Get the Directory Text
|
||||
INT int_command
|
||||
retc
|
||||
PUSH CS
|
||||
POP DS
|
||||
ASSUME DS:TRANGROUP
|
||||
|
||||
return
|
||||
|
||||
|
||||
CRLF2:
|
||||
PUSH DX
|
||||
MOV DX,OFFSET TRANGROUP:ACRLF_ptr
|
||||
|
||||
PR:
|
||||
PUSH DS
|
||||
PUSH CS
|
||||
POP DS
|
||||
invoke std_printf
|
||||
POP DS
|
||||
POP DX
|
||||
|
||||
return
|
||||
|
||||
;
|
||||
; These routines (SCANOFF, DELIM) are called in batch processing when DS
|
||||
; may NOT be TRANGROUP
|
||||
;
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
|
||||
SCANOFF:
|
||||
LODSB
|
||||
CALL DELIM
|
||||
JZ SCANOFF
|
||||
DEC SI ; Point to first non-delimiter
|
||||
return
|
||||
|
||||
;
|
||||
; Input: AL is character to classify
|
||||
; Output: Z set if delimiter
|
||||
; NZ set otherwise
|
||||
; Registers modified: none
|
||||
;
|
||||
|
||||
DELIM:
|
||||
CMP AL,' '
|
||||
retz
|
||||
CMP AL,'='
|
||||
retz
|
||||
CMP AL,','
|
||||
retz
|
||||
CMP AL,';'
|
||||
retz
|
||||
CMP AL,9 ; Check for TAB character
|
||||
retz
|
||||
CMP AL,0ah ; Check for line feed character - BAS
|
||||
return
|
||||
|
||||
|
||||
ASSUME DS:TRANGROUP,ES:TRANGROUP
|
||||
|
||||
|
||||
FCB_TO_ASCZ: ; Convert DS:SI to ASCIZ ES:DI
|
||||
MOV CX,8
|
||||
|
||||
MAINNAME:
|
||||
LODSB
|
||||
CMP AL,' '
|
||||
JZ SKIPSPC
|
||||
STOSB
|
||||
|
||||
SKIPSPC:
|
||||
LOOP MAINNAME
|
||||
LODSB
|
||||
CMP AL,' '
|
||||
JZ GOTNAME
|
||||
MOV AH,AL
|
||||
MOV AL,dot_chr
|
||||
STOSB
|
||||
XCHG AL,AH
|
||||
STOSB
|
||||
MOV CL,2
|
||||
|
||||
EXTNAME:
|
||||
LODSB
|
||||
CMP AL,' '
|
||||
JZ GOTNAME
|
||||
STOSB
|
||||
LOOP EXTNAME
|
||||
|
||||
GOTNAME:
|
||||
XOR AL,AL
|
||||
STOSB
|
||||
return
|
||||
|
||||
STRCOMP:
|
||||
;
|
||||
; Compare ASCIZ DS:SI with ES:DI.
|
||||
; SI,DI destroyed.
|
||||
;
|
||||
CMPSB
|
||||
retnz ; Strings not equal
|
||||
cmp byte ptr [SI-1],0 ; Hit NUL terminator?
|
||||
retz ; Yes, strings equal
|
||||
jmp short STRCOMP ; Equal so far, keep going
|
||||
|
||||
|
||||
CRPRINT:
|
||||
PUSH AX
|
||||
MOV AL,13
|
||||
PUSH CX
|
||||
PUSH DI
|
||||
MOV DI,DX
|
||||
MOV CX,-1
|
||||
PUSH ES
|
||||
PUSH DS
|
||||
POP ES
|
||||
|
||||
REPNZ SCASB ; LOOK FOR TERMINATOR
|
||||
mov byte ptr [di-1],0 ; nul terminate the string
|
||||
POP ES
|
||||
mov string_ptr_2,dx
|
||||
mov dx,offset trangroup:string_buf_ptr
|
||||
invoke std_printf
|
||||
mov ds:byte ptr [di-1],13 ; now put the CR back
|
||||
JC ERROR_OUTPUT
|
||||
|
||||
POP DI
|
||||
POP CX
|
||||
POP AX
|
||||
|
||||
return
|
||||
|
||||
ERROR_OUTPUT:
|
||||
PUSH CS
|
||||
POP DS
|
||||
ASSUME DS:TRANGROUP
|
||||
MOV ES,[RESSEG]
|
||||
ASSUME ES:RESGROUP
|
||||
|
||||
MOV DX,OFFSET TRANGROUP:NOSPACE_ptr
|
||||
CMP [PIPEFLAG],0
|
||||
JZ GO_TO_ERROR
|
||||
|
||||
invoke PipeOff
|
||||
MOV DX,OFFSET TRANGROUP:PIPEEMES_ptr
|
||||
GO_TO_ERROR:
|
||||
JMP CERROR
|
||||
|
||||
ASSUME DS:TRANGROUP,ES:TRANGROUP
|
||||
|
||||
PATHCHRCMP:
|
||||
;---- Mod for path invocation ----
|
||||
PUBLIC pathchrcmp
|
||||
;----
|
||||
|
||||
push ax
|
||||
mov ah,'/'
|
||||
CMP [SWITCHAR],ah
|
||||
JZ NOSLASHT
|
||||
CMP AL,'/'
|
||||
jz pccont
|
||||
|
||||
NOSLASHT:
|
||||
CMP AL,'\'
|
||||
pccont:
|
||||
pop ax
|
||||
|
||||
return
|
||||
|
||||
; Drive taken from FCB
|
||||
; User dir saved in userdir1
|
||||
;
|
||||
; Zero set if path dir, CHDIR to this dir, FCB filled with ?
|
||||
; NZ set if path/file, CHDIR to file, FCB has file (parsed fill ' ')
|
||||
; [DESTTAIL] points to parse point
|
||||
; Carry set if no CHDIRs worked, FCB not altered.
|
||||
; DESTISDIR set non zero if PATHCHRs in path (via SETPATH)
|
||||
;
|
||||
PATHCRUNCH:
|
||||
mov [msg_numb],0 ;AN022; Set up message flag
|
||||
MOV DL,DS:[FCB]
|
||||
CALL SAVUDIR
|
||||
jc pcrunch_cderrJ ;AN022; if error on current dir - report
|
||||
|
||||
invoke SETPATH
|
||||
TEST [DESTINFO],2
|
||||
JNZ TRYPEEL ; If ? or * cannot be pure dir
|
||||
|
||||
MOV AH,CHDIR
|
||||
INT int_command
|
||||
jnc chdir_worked ;AN022; no error - continue
|
||||
|
||||
invoke get_ext_error_number ;AN022; get the extended error
|
||||
cmp ax,error_path_not_found ;AN022; if path not found
|
||||
jz trypeel ;AC022; keep trying
|
||||
cmp ax,error_access_denied ;AN022; if access denied
|
||||
jz trypeel ;AC022; keep trying
|
||||
mov [msg_numb],ax ;AN022; set up message flag
|
||||
jmp peelfail ;AN022; exit with other error
|
||||
|
||||
chdir_worked:
|
||||
invoke SETREST1
|
||||
MOV AL,'?' ; *.* is default file spec if pure dir
|
||||
MOV DI,5DH
|
||||
MOV CX,11
|
||||
REP STOSB
|
||||
XOR AL,AL ; Set zero
|
||||
return
|
||||
|
||||
pcrunch_cderrj: ;AN022; need this for long jmp
|
||||
jmp pcrunch_cderr ;AN022;
|
||||
|
||||
TRYPEEL:
|
||||
MOV SI,[PATHPOS]
|
||||
DEC SI ; Point at NUL
|
||||
MOV AL,[SI-1]
|
||||
|
||||
CMP [KPARSE],0
|
||||
JNZ DELSTRT ; Last char is second KANJI byte, might be '\'
|
||||
|
||||
CALL PATHCHRCMP
|
||||
JZ PEELFAIL ; Trailing '/'
|
||||
|
||||
DELSTRT:
|
||||
MOV CX,SI
|
||||
MOV SI,DX
|
||||
PUSH DX
|
||||
DELLOOP:
|
||||
CMP SI,CX
|
||||
JZ GOTDELE
|
||||
LODSB
|
||||
invoke TESTKANJ
|
||||
JZ NOTKANJ8
|
||||
INC SI
|
||||
JMP DELLOOP
|
||||
|
||||
NOTKANJ8:
|
||||
CALL PATHCHRCMP
|
||||
JNZ DELLOOP
|
||||
MOV DX,SI
|
||||
DEC DX
|
||||
JMP DELLOOP
|
||||
|
||||
GOTDELE:
|
||||
MOV SI,DX
|
||||
POP DX
|
||||
CMP SI,DX
|
||||
JZ BADRET
|
||||
MOV CX,SI
|
||||
MOV SI,DX
|
||||
DELLOOP2: ; Set value of KPARSE
|
||||
CMP SI,CX
|
||||
JZ TRYCD
|
||||
MOV [KPARSE],0
|
||||
LODSB
|
||||
INVOKE TESTKANJ
|
||||
JZ DELLOOP2
|
||||
INC SI
|
||||
INC [KPARSE]
|
||||
JMP DELLOOP2
|
||||
|
||||
TRYCD:
|
||||
push ax
|
||||
mov al,dot_chr
|
||||
CMP BYTE PTR [SI+1],al
|
||||
pop ax
|
||||
JZ PEELFAIL ; If . or .., pure cd should have worked
|
||||
mov al,[si-1]
|
||||
CMP al,':' ; Special case d:\file
|
||||
JZ BADRET
|
||||
|
||||
CMP [KPARSE],0
|
||||
JNZ NOTDOUBLESL ; Last char is second KANJI byte, might be '\'
|
||||
|
||||
CALL PATHCHRCMP
|
||||
JNZ NOTDOUBLESL
|
||||
PEELFAIL:
|
||||
STC ; //
|
||||
return
|
||||
NOTDOUBLESL:
|
||||
MOV BYTE PTR [SI],0
|
||||
MOV AH,CHDIR
|
||||
INT int_command
|
||||
JNC CDSUCC
|
||||
pcrunch_cderr:
|
||||
invoke get_ext_error_number ;AN022; get the extended error
|
||||
mov [msg_numb],ax ;AN022; set up message flag
|
||||
or si,si ;AN022; set up zero flag to not zero
|
||||
stc ;AN022; set up carry flag
|
||||
return
|
||||
|
||||
BADRET:
|
||||
MOV AL,[SI]
|
||||
CALL PATHCHRCMP ; Special case 'DIRCHAR'file
|
||||
STC
|
||||
retnz
|
||||
XOR BL,BL
|
||||
XCHG BL,[SI+1]
|
||||
MOV AH,CHDIR
|
||||
INT int_command
|
||||
jc pcrunch_cderr ;AN022; go to error exit
|
||||
MOV [SI+1],BL
|
||||
CDSUCC:
|
||||
invoke SETREST1
|
||||
INC SI ; Reset zero
|
||||
MOV [DESTTAIL],SI
|
||||
pushf ;AN015; save flags
|
||||
cmp dirflag,-1 ;AN015; don't do parse if in DIR
|
||||
jz pcrunch_end ;AN015;
|
||||
MOV DI,FCB
|
||||
MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 02H ; Parse with default drive
|
||||
INT int_command
|
||||
pcrunch_end:
|
||||
popf ;AN015; get flags back
|
||||
return
|
||||
|
||||
trancode ends
|
||||
end
|
||||
|
||||
551
v4.0/src/CMD/COMMAND/TFOR.ASM
Normal file
551
v4.0/src/CMD/COMMAND/TFOR.ASM
Normal file
@@ -0,0 +1,551 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)tfor.asm 4.1 85/09/17
|
||||
; SCCSID = @(#)tfor.asm 4.1 85/09/17
|
||||
TITLE Part3 COMMAND Transient Routines
|
||||
|
||||
; For loop processing routines
|
||||
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
include comsw.asm
|
||||
INCLUDE DOSSYM.INC
|
||||
INCLUDE DEVSYM.INC
|
||||
include comseg.asm
|
||||
include comequ.asm
|
||||
.list
|
||||
.cref
|
||||
|
||||
|
||||
DATARES SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN BATCH:WORD
|
||||
EXTRN ECHOFLAG:BYTE
|
||||
EXTRN FORFLAG:BYTE
|
||||
EXTRN FORPTR:WORD
|
||||
EXTRN NEST:WORD
|
||||
EXTRN NULLFLAG:BYTE
|
||||
EXTRN PIPEFILES:BYTE
|
||||
EXTRN SINGLECOM:WORD
|
||||
DATARES ENDS
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN Extend_buf_ptr:word ;AN000;
|
||||
extrn fornestmes_ptr:word
|
||||
EXTRN msg_disp_class:byte ;AN000;
|
||||
extrn string_buf_ptr:word
|
||||
TRANDATA ENDS
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
extrn arg:byte ; the arg structure!
|
||||
EXTRN COMBUF:BYTE
|
||||
EXTRN RESSEG:WORD
|
||||
EXTRN string_ptr_2:word
|
||||
TRANSPACE ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC BYTE
|
||||
|
||||
ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
|
||||
EXTRN cerror:near
|
||||
EXTRN docom:near
|
||||
EXTRN docom1:near
|
||||
EXTRN forerror:near
|
||||
EXTRN tcommand:near
|
||||
|
||||
PUBLIC $for
|
||||
PUBLIC forproc
|
||||
|
||||
|
||||
; All batch proccessing has DS set to segment of resident portion
|
||||
ASSUME DS:RESGROUP,ES:TRANGROUP
|
||||
|
||||
|
||||
FORTERM:
|
||||
push cs ;AN037; Get local segment into
|
||||
pop ds ;AN037; DS, ES
|
||||
push cs ;AN037;
|
||||
pop es ;AN037;
|
||||
call ForOff
|
||||
mov ds,ResSeg
|
||||
ASSUME DS:RESGROUP
|
||||
CMP [SINGLECOM],0FF00H
|
||||
JNZ BATCRLF
|
||||
CMP NEST,0 ;G See if we have nested batch files
|
||||
JNZ BATCRLF ;G Yes - don't exit just yet
|
||||
MOV [SINGLECOM],-1 ; Cause a terminate
|
||||
JMP SHORT NOFORP2
|
||||
|
||||
BATCRLF:
|
||||
test [ECHOFLAG],1 ;G Is echo on?
|
||||
JZ NOFORP2 ;G no - exit
|
||||
TEST [BATCH], -1 ;G print CRLF if in batch
|
||||
JZ NOFORP2 ;G
|
||||
invoke CRLF2
|
||||
|
||||
NOFORP2:
|
||||
JMP TCOMMAND
|
||||
|
||||
|
||||
;------
|
||||
; For-loop processing. For loops are of the form:
|
||||
; for %<loop-variable> in (<list>) do <command>
|
||||
; where <command> may contain references of the form %<variable>, which are
|
||||
; later substituted with the items in <list>. The for-loop structure is
|
||||
; set-up by the procedure '$for'; successive calls to 'forproc' execute
|
||||
; <command> once for each item in <list>. All of the information needed for
|
||||
; loop processing is stored on a piece of memory gotten from 'alloc'. This
|
||||
; structure is actually fairly large, on the order of 700 bytes, and includes
|
||||
; a complete copy of the original command-line structure as parsed by
|
||||
; 'parseline', loop control variables, and a dma buffer for the
|
||||
; 'FindFirst/FindNext' expansion of wildcard filenames in <list>. When loop
|
||||
; processing has completed, this chunk of memory is returned to the system.
|
||||
;
|
||||
; All of the previously defined variables, in 'datares', used for loop
|
||||
; processing may be erased. Only one, (DW) ForPtr, need be allocated.
|
||||
;
|
||||
; The error message, 'for_alloc_mes', should be moved into the file
|
||||
; containing all of the other error messages.
|
||||
;
|
||||
; Referencing the allocated for-loop structure is a little tricky.
|
||||
; At the moment, a byte is defined as part of a new segment, 'for_segment'.
|
||||
; When 'forproc' actually runs, ES and DS are set to point to the base of the
|
||||
; new chunk of memory. References to this byte, 'f', thus assemble correctly
|
||||
; as offsets of ES or DS. 'f' would not be necessary, except that the
|
||||
; assembler translates an instruction such as 'mov AX, [for_minarg]' as an
|
||||
; immediate move of the offset of 'for_minarg' into AX. In other words, in
|
||||
; terms of PDP-11 mnemonics, the assembler ACTUALLY assembles
|
||||
; mov AX, #for_minarg ; AX := 02CA (for example)
|
||||
; instead of
|
||||
; mov AX, for_minarg ; AX := [02CA] (contents of 02CA)
|
||||
; By using 'f', we pretend that we are actually referencing an allocated
|
||||
; structure, and the assembler coughs up the code we want. Notice that it
|
||||
; doesn't matter whether we put brackets around the location or not -- the
|
||||
; assembler is "smart" enough to know that we want an address instead of the
|
||||
; contents of that location.
|
||||
;
|
||||
; Finally, there now exists the potential to easily implement nested loops.
|
||||
; One method would be to have a link field in each for-structure pointing to
|
||||
; its parent. Variable references that couldn't be resolved in the local
|
||||
; frame would cause a search of prior frames. For-structures would still be
|
||||
; allocated and released in exactly the same fashion. The only limit on the
|
||||
; number of nested loops would be memory size (although at 700 bytes a pop,
|
||||
; memory wouldn't last THAT long). Alternately, a small structure could be
|
||||
; maintained in the resident data area. This structure would be an array of
|
||||
; control-variable names and pointers to for-structure blocks. This would
|
||||
; greatly speed up the resolution of non-local variable references. However,
|
||||
; since space in the resident is precious, we would have to compromise on a
|
||||
; "reasonable" level of nesting -- 10, 16, 32 levels, whatever. For-structure
|
||||
; allocation and de-allocation would have to be modified slightly to take this
|
||||
; new structure into account.
|
||||
;
|
||||
; Oops, just one more thing. Forbuf need not be a part of the for-structure.
|
||||
; It could just as well be one structure allocated in 'transpace'. Actually,
|
||||
; it may be easier to allocate it as part of 'for_segment'.
|
||||
;------
|
||||
|
||||
include fordata.asm
|
||||
|
||||
$for_exit:
|
||||
jmp forterm ; exceeding maxarg means all done
|
||||
|
||||
forproc:
|
||||
assume DS:resgroup
|
||||
mov AX, [ForPtr]
|
||||
mov DS, AX
|
||||
mov ES, AX ; operate in for-info area
|
||||
assume DS:for_segment, ES:for_segment
|
||||
|
||||
mov DX, OFFSET fordma
|
||||
trap Set_Dma
|
||||
for_begin:
|
||||
cmp f.for_expand, 0 ; non-zero for_expand equals FALSE
|
||||
je for_begin1
|
||||
inc f.for_minarg
|
||||
for_begin1:
|
||||
mov BX, f.for_minarg ; current item in <list> to examine
|
||||
cmp BX, f.for_maxarg
|
||||
jg $for_exit ; exceeding maxarg means all done
|
||||
mov AX, OFFSET for_args.argv
|
||||
invoke argv_calc ; compute argv[x] address
|
||||
|
||||
mov CX, [BX].argstartel
|
||||
mov DX, [BX].argpointer
|
||||
test [bx].argflags,00000100b ; Is there a path separator in this arg?
|
||||
jnz forsub ; Yes, argstartel should be correct
|
||||
mov si, [BX].argpointer
|
||||
mov al,lparen
|
||||
cmp byte ptr [si-1],al ; If the current token is the first
|
||||
jnz forsub ; one in the list and originally had
|
||||
inc cx ; the opening paren as its first char,
|
||||
; the argstartel ptr needs to be
|
||||
; advanced passed it before the prefix
|
||||
; length is computed.
|
||||
mov al,':'
|
||||
cmp byte ptr [si+1],al ; If the token begins with "(d:",
|
||||
jnz forsub ; argstartel has to be moved over the
|
||||
add cx,2 ; rest of the prefix as well.
|
||||
|
||||
forsub:
|
||||
sub CX, DX ; compute length of pathname prefix
|
||||
cmp f.for_expand, 0 ; are we still expanding a name?
|
||||
je for_find_next ; if so, get next matching filename
|
||||
|
||||
test [BX].argflags, MASK wildcard
|
||||
jnz for_find_first ; should we expand THIS (new) arg?
|
||||
mov CX, [BX].arglen ; else, just copy all of it directly
|
||||
jmp for_smoosh
|
||||
|
||||
for_find_first:
|
||||
PUSH CX
|
||||
XOR CX,CX
|
||||
trap Find_First ; and search for first filename match
|
||||
POP CX
|
||||
jmp for_result
|
||||
for_find_next:
|
||||
trap Find_Next ; search for next filename match
|
||||
|
||||
for_result:
|
||||
mov AX, -1 ; assume worst case
|
||||
jc forCheck
|
||||
mov ax,0
|
||||
forCheck: ; Find* returns 0 for SUCCESS
|
||||
mov f.FOR_EXPAND, AX ; record success of findfirst/next
|
||||
or AX, AX ; anything out there?
|
||||
jnz for_begin ; if not, try next arg
|
||||
|
||||
for_smoosh:
|
||||
mov SI, [BX].argpointer ; copy argv[arg][0,CX] into destbuf
|
||||
mov DI, OFFSET forbuf ; some days this will be the entire
|
||||
rep movsb ; arg, some days just the path prefix
|
||||
|
||||
cmp f.FOR_EXPAND, 0 ; if we're not expanding, we can
|
||||
jnz for_make_com ; skip the following
|
||||
|
||||
mov SI, OFFSET fordma.find_buf_pname
|
||||
for_more: ; tack on matching filename
|
||||
cmp BYTE PTR [SI], 0
|
||||
je for_make_com
|
||||
movsb
|
||||
jnz for_more
|
||||
|
||||
for_make_com:
|
||||
xor AL, AL ; tack a null byte onto the end
|
||||
stosb ; of the substitute string
|
||||
|
||||
xor CX, CX ; character count for command line
|
||||
not CX ; negate it -- take advantage of loopnz
|
||||
xor BX, BX ; argpointer
|
||||
mov DI, OFFSET TRANGROUP:COMBUF+2
|
||||
mov bl, f.FOR_COM_START ; argindex
|
||||
mov DH, f.FOR_VAR ; %<for-var> is replaced by [forbuf]
|
||||
; time to form the <command> string
|
||||
push CS
|
||||
pop ES
|
||||
assume ES:trangroup
|
||||
|
||||
mov AX, OFFSET for_args ; translate offset to pointer
|
||||
invoke argv_calc
|
||||
mov si,[bx].arg_ocomptr
|
||||
inc si ; mov ptr passed beginning space
|
||||
|
||||
for_make_loop:
|
||||
mov al,[si] ; the <command> arg, byte by byte
|
||||
inc si
|
||||
cmp AL,'%' ; looking for %<control-variable>
|
||||
jne for_stosb ; no % ... add byte to string
|
||||
cmp BYTE PTR [SI], DH ; got the right <variable>?
|
||||
jne for_stosb ; got a %, but wrong <variable>
|
||||
inc SI ; skip over <for-variable>
|
||||
|
||||
push SI
|
||||
mov SI, OFFSET forbuf ; substitute the <item> for <variable>
|
||||
; to make a final <command> to execute
|
||||
sloop:
|
||||
lodsb ; grab all those <item> bytes, and
|
||||
stosb ; add 'em to the <command> string,
|
||||
or AL, AL ; until we run into a null
|
||||
loopnz sloop
|
||||
dec DI ; adjust length and <command> pointer
|
||||
inc CX ; so we can overwrite the null
|
||||
|
||||
pop SI
|
||||
jmp for_make_loop ; got back for more <command> bytes
|
||||
for_stosb:
|
||||
stosb ; take a byte from the <command> arg
|
||||
dec CX ; and put it into the <command> to be
|
||||
; executed (and note length, too)
|
||||
cmp al,0dh ; If not done, loop.
|
||||
jne for_make_loop
|
||||
|
||||
for_made_com: ; finished all the <command> args
|
||||
not CL ; compute and record command length
|
||||
mov [COMBUF+1], CL
|
||||
|
||||
mov DS, [RESSEG]
|
||||
assume DS:resgroup
|
||||
|
||||
test [ECHOFLAG],1 ; shall we echo this <command>, dearie?
|
||||
jz noecho3
|
||||
cmp nullflag,nullcommand ;G was there a command last time?
|
||||
jz No_crlf_pr ;G no - don't print crlf
|
||||
invoke CRLF2 ;G Print out prompt
|
||||
|
||||
no_crlf_pr:
|
||||
mov nullflag,0 ;G reset no command flag
|
||||
push CS
|
||||
pop DS
|
||||
assume DS:trangroup
|
||||
push di
|
||||
invoke PRINT_PROMPT ;G Prompt the user
|
||||
pop di
|
||||
mov BYTE PTR ES:[DI-1],0 ; yeah, PRINT it out...
|
||||
mov string_ptr_2,OFFSET TRANGROUP:COMBUF+2
|
||||
mov dx,offset trangroup:string_buf_ptr
|
||||
invoke std_printf
|
||||
mov BYTE PTR ES:[DI-1], 0DH
|
||||
jmp DoCom
|
||||
noecho3: ; run silent, run deep...
|
||||
assume DS:resgroup
|
||||
mov nullflag,0 ;G reset no command flag
|
||||
push CS
|
||||
pop DS
|
||||
assume DS:trangroup
|
||||
jmp docom1
|
||||
|
||||
|
||||
fornesterrj: ; no multi-loop processing... yet!
|
||||
assume ES:resgroup
|
||||
call ForOff
|
||||
jmp fornesterr
|
||||
|
||||
forerrorj:
|
||||
jmp forerror
|
||||
|
||||
break $For
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
$for:
|
||||
mov ES, [RESSEG]
|
||||
assume ES:resgroup
|
||||
|
||||
cmp ForFlag,0 ; is another one already running?
|
||||
jnz fornesterrj ; if flag is set.... boom!
|
||||
|
||||
;
|
||||
; Turn off any pipes in progress.
|
||||
;
|
||||
cmp [PIPEFILES],0 ; Only turn off if present.
|
||||
jz NoPipe
|
||||
invoke PipeDel
|
||||
NoPipe:
|
||||
xor DX, DX ; counter (0 <= DX < argvcnt)
|
||||
call nextarg ; move to next argv[n]
|
||||
jc forerrorj ; no more args -- bad forloop
|
||||
cmp AL,'%' ; next arg MUST start with '%'...
|
||||
jne forerrorj
|
||||
mov BP, AX ; save forloop variable
|
||||
lodsb
|
||||
or AL, AL ; and MUST end immediately...
|
||||
jne forerrorj
|
||||
|
||||
call nextarg ; let's make sure the next arg is 'in'
|
||||
jc forerrorj
|
||||
and AX, NOT 2020H ; uppercase the letters
|
||||
cmp AX, in_word
|
||||
jne forerrorj
|
||||
lodsb
|
||||
or AL, AL ; it, too, must end right away
|
||||
je CheckLParen
|
||||
;
|
||||
; Not null. Perhaps there are no spaces between this and the (:
|
||||
; FOR %i in(foo bar...
|
||||
; Check for the Lparen here
|
||||
;
|
||||
CMP AL,lparen
|
||||
JNZ forerrorj
|
||||
;
|
||||
; The token was in(... We strip off the "in" part to simulate a separator
|
||||
; being there in the first place.
|
||||
;
|
||||
ADD [BX].argpointer,2 ; advance source pointer
|
||||
ADD [BX].arg_ocomptr,2 ; advance original string
|
||||
SUB [BX].arglen,2 ; decrement the appropriate length
|
||||
;
|
||||
; SI now points past the in(. Simulate a nextarg call that results in the
|
||||
; current value.
|
||||
;
|
||||
MOV ax,[si-1] ; get lparen and next char
|
||||
jmp short lpcheck
|
||||
|
||||
CheckLParen:
|
||||
call nextarg ; lparen delimits beginning of <list>
|
||||
jc forerrorj
|
||||
lpcheck:
|
||||
cmp al, lparen
|
||||
jne forerrorj
|
||||
cmp ah,0
|
||||
je for_paren_token
|
||||
|
||||
cmp ah, rparen ; special case: null list
|
||||
jne for_list_not_empty
|
||||
jmp forterm
|
||||
|
||||
for_list_not_empty:
|
||||
inc [bx].argpointer ; Advance ptr past "("
|
||||
; Adjust the rest of this argv entry
|
||||
dec [bx].arglen ; to agree.
|
||||
inc si ; Inc si so check for ")" works
|
||||
jmp for_list
|
||||
|
||||
for_paren_token:
|
||||
call nextarg ; what have we in our <list>?
|
||||
jc forerrorj
|
||||
cmp ax, nullrparen ; special case: null list
|
||||
jne for_list
|
||||
jmp forterm
|
||||
|
||||
forerrorjj:
|
||||
jmp forerror
|
||||
|
||||
for_list: ; skip over rest of <list>
|
||||
mov CX, DX ; first arg of <list>
|
||||
skip_list:
|
||||
add si,[bx].arglen
|
||||
sub si,3 ; si = ptr to last char of token
|
||||
mov al,rparen
|
||||
cmp byte ptr [si],al ; Is this the last element in <list>
|
||||
je for_end_list ; Yes, exit loop.
|
||||
call nextarg ; No, get next arg <list>
|
||||
jc forerrorjj ; If no more and no rparen, error.
|
||||
jmp skip_list
|
||||
for_end_list:
|
||||
mov DI, DX ; record position of last arg in <list>
|
||||
mov byte ptr [si],0 ; Zap the rparen
|
||||
cmp ax,nullrparen ; Was this token only a rparen
|
||||
jz for_do ; Yes, continue
|
||||
inc di ; No, inc position of last arg
|
||||
|
||||
for_do:
|
||||
call nextarg ; now we had BETTER find a 'do'...
|
||||
jc forerrorjj
|
||||
and AX, NOT 2020H ; uppercase the letters
|
||||
cmp AX, do_word
|
||||
jne forerrorjj
|
||||
lodsb
|
||||
or AL, AL ; and it had BETTER be ONLY a 'do'...
|
||||
jne forerrorjj
|
||||
|
||||
call nextarg ; on to the beginning of <command>
|
||||
jc forerrorjj ; null <command> not legal
|
||||
|
||||
push AX
|
||||
push BX
|
||||
push CX
|
||||
push DX ; preserve registers against disaster
|
||||
push DI
|
||||
push SI
|
||||
push BP
|
||||
invoke FREE_TPA ; need to make free memory, first
|
||||
ASSUME ES:RESGROUP
|
||||
call ForOff
|
||||
mov BX, SIZE for_info - SIZE arg_unit
|
||||
invoke Save_Args ; extra bytes needed for for-info
|
||||
pushf
|
||||
mov [ForPtr], AX
|
||||
invoke ALLOC_TPA ; ALLOC_TPA clobbers registers...
|
||||
popf
|
||||
pop BP
|
||||
pop SI
|
||||
pop DI
|
||||
pop DX
|
||||
pop CX
|
||||
pop BX
|
||||
pop AX
|
||||
jc for_alloc_err
|
||||
|
||||
push ES ; save resgroup seg...
|
||||
push [ForPtr]
|
||||
pop ES
|
||||
assume ES:for_segment ; make references to for-info segment
|
||||
|
||||
dec CX ; forproc wants min pointing before
|
||||
dec DI ; first arg, max right at last one
|
||||
mov f.for_minarg, CX
|
||||
mov f.for_maxarg, DI
|
||||
mov f.for_com_start, DL
|
||||
mov f.for_expand, -1 ; non-zero means FALSE
|
||||
mov AX, BP
|
||||
mov f.for_var, AH
|
||||
pop ES
|
||||
assume ES:resgroup
|
||||
|
||||
inc [FORFLAG]
|
||||
cmp [SINGLECOM], -1
|
||||
jnz for_ret
|
||||
mov [SINGLECOM], 0FF00H
|
||||
for_ret:
|
||||
ret
|
||||
|
||||
for_alloc_err:
|
||||
mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class
|
||||
mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
|
||||
mov Extend_Buf_ptr,error_not_enough_memory ;AN000; get message number in control block
|
||||
jmp cerror
|
||||
|
||||
nextarg:
|
||||
inc DX ; next argv[n]
|
||||
cmp DX, arg.argvcnt ; make sure we don't run off end
|
||||
jge nextarg_err ; of argv[]...
|
||||
mov BX, DX
|
||||
mov AX, OFFSET TRANGROUP:arg.argv
|
||||
invoke argv_calc ; convert array index to pointer
|
||||
mov SI, [BX].argpointer ; load pointer to argstring
|
||||
lodsw ; and load first two chars
|
||||
clc
|
||||
ret
|
||||
nextarg_err:
|
||||
stc
|
||||
ret
|
||||
|
||||
|
||||
ASSUME DS:TRANGROUP,ES:TRANGROUP
|
||||
|
||||
FORNESTERR:
|
||||
PUSH DS
|
||||
MOV DS,[RESSEG]
|
||||
ASSUME DS:RESGROUP
|
||||
MOV DX,OFFSET TRANGROUP:FORNESTMES_ptr
|
||||
CMP [SINGLECOM],0FF00H
|
||||
JNZ NOFORP3
|
||||
MOV [SINGLECOM],-1 ; Cause termination
|
||||
NOFORP3:
|
||||
POP DS
|
||||
ASSUME DS:TRANGROUP
|
||||
JMP CERROR
|
||||
;
|
||||
; General routine called to free the for segment. We also clear the forflag
|
||||
; too. Change no registers.
|
||||
;
|
||||
PUBLIC ForOff
|
||||
ForOff:
|
||||
assume DS:NOTHING,ES:NOTHING
|
||||
SaveReg <AX,ES>
|
||||
mov es,ResSeg
|
||||
assume es:ResGroup
|
||||
mov AX,ForPtr
|
||||
or ax,ax
|
||||
jz FreeDone
|
||||
push es
|
||||
mov es,ax
|
||||
mov ah,dealloc
|
||||
int 21h
|
||||
pop es
|
||||
FreeDone:
|
||||
mov ForPtr,0
|
||||
mov ForFlag,0
|
||||
RestoreReg <ES,AX>
|
||||
return
|
||||
|
||||
trancode ends
|
||||
end
|
||||
|
||||
655
v4.0/src/CMD/COMMAND/TMISC1.ASM
Normal file
655
v4.0/src/CMD/COMMAND/TMISC1.ASM
Normal file
@@ -0,0 +1,655 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)tmisc1.asm 4.1 85/09/22
|
||||
; SCCSID = @(#)tmisc1.asm 4.1 85/09/22
|
||||
TITLE Part7 COMMAND Transient Routines
|
||||
|
||||
; More misc routines
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE comsw.asm
|
||||
INCLUDE DOSSYM.INC
|
||||
INCLUDE comseg.asm
|
||||
INCLUDE comequ.asm
|
||||
.list
|
||||
.cref
|
||||
|
||||
|
||||
|
||||
CODERES SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN RSTACK:BYTE
|
||||
CodeRes ENDS
|
||||
|
||||
DATARES SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN CALL_FLAG:BYTE
|
||||
EXTRN EchoFlag:BYTE
|
||||
EXTRN EXEC_BLOCK:BYTE
|
||||
EXTRN EXTCOM:BYTE
|
||||
EXTRN PIPEFLAG:BYTE
|
||||
EXTRN PIPEPTR:WORD
|
||||
EXTRN PIPESTR:BYTE
|
||||
EXTRN RESTDIR:BYTE
|
||||
EXTRN RE_OUT_APP:BYTE
|
||||
EXTRN RE_OUTSTR:BYTE
|
||||
DATARES ENDS
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN BADDRV_PTR:WORD
|
||||
EXTRN BADNAM_PTR:WORD
|
||||
EXTRN COMTAB:BYTE ;AC000;
|
||||
EXTRN extend_buf_ptr:word ;AN000;
|
||||
EXTRN msg_disp_class:byte ;AN000;
|
||||
TRANDATA ENDS
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN arg:byte ; the arg structure!
|
||||
EXTRN APPEND_EXEC:BYTE ;AN041;
|
||||
EXTRN CHKDRV:BYTE
|
||||
EXTRN COMBUF:BYTE
|
||||
EXTRN EXECPATH:BYTE
|
||||
EXTRN EXEC_ADDR:DWORD
|
||||
EXTRN FILTYP:BYTE
|
||||
EXTRN IDLEN:BYTE
|
||||
EXTRN KPARSE:BYTE ;AC000;
|
||||
EXTRN PARM1:BYTE
|
||||
EXTRN PARM2:BYTE
|
||||
EXTRN PathPos:word
|
||||
EXTRN RESSEG:WORD
|
||||
EXTRN RE_INSTR:BYTE
|
||||
EXTRN SPECDRV:BYTE
|
||||
EXTRN SWITCHAR:BYTE
|
||||
EXTRN switch_list:byte
|
||||
EXTRN TRAN_TPA:WORD
|
||||
|
||||
IF IBM
|
||||
EXTRN ROM_CALL:BYTE
|
||||
EXTRN ROM_CS:WORD
|
||||
EXTRN ROM_IP:WORD
|
||||
ENDIF
|
||||
|
||||
TRANSPACE ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC byte
|
||||
|
||||
ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
|
||||
EXTRN APPEND_PARSE:NEAR ;AN010;
|
||||
EXTRN BATCOM:NEAR
|
||||
EXTRN DOCOM1:NEAR
|
||||
EXTRN PIPEERRSYN:NEAR
|
||||
EXTRN TCOMMAND:NEAR
|
||||
|
||||
IF IBM
|
||||
EXTRN ROM_EXEC:NEAR
|
||||
EXTRN ROM_SCAN:NEAR
|
||||
ENDIF
|
||||
|
||||
PUBLIC CERROR
|
||||
PUBLIC DRVBAD
|
||||
PUBLIC EXTERNAL
|
||||
PUBLIC FNDCOM
|
||||
PUBLIC PRESCAN
|
||||
PUBLIC SWITCH
|
||||
|
||||
|
||||
ASSUME DS:TRANGROUP
|
||||
|
||||
;---------------------------
|
||||
; We can get rid of this switch processing code if we can take
|
||||
; care of the remaining two calls to switch, later in the file.
|
||||
; However, I have not checked whether or not any other files use
|
||||
; switch -- after all, it IS public!
|
||||
;---------------------------
|
||||
RETSW:
|
||||
XCHG AX,BX ; Put switches in AX
|
||||
return
|
||||
|
||||
SWITCH:
|
||||
XOR BX,BX ; Initialize - no switches set
|
||||
SWLOOP:
|
||||
INVOKE SCANOFF ; Skip any delimiters
|
||||
CMP AL,[SWITCHAR] ; Is it a switch specifier?
|
||||
JNZ RETSW ; No -- we're finished
|
||||
OR BX,fSwitch ; Indicate there is a switch specified
|
||||
INC SI ; Skip over the switch character
|
||||
INVOKE SCANOFF
|
||||
CMP AL,0DH
|
||||
JZ RETSW ; Oops
|
||||
INC SI
|
||||
; Convert lower case input to upper case
|
||||
INVOKE UPCONV
|
||||
MOV DI,OFFSET TRANGROUP:switch_list
|
||||
MOV CX,SWCOUNT
|
||||
REPNE SCASB ; Look for matching switch
|
||||
JNZ BADSW
|
||||
MOV AX,1
|
||||
SHL AX,CL ; Set a bit for the switch
|
||||
OR BX,AX
|
||||
JMP SHORT SWLOOP
|
||||
|
||||
BADSW:
|
||||
JMP SHORT SWLOOP
|
||||
|
||||
SWCOUNT EQU 5 ; Length of switch_list
|
||||
|
||||
DRVBAD:
|
||||
MOV DX,OFFSET TRANGROUP:BADDRV_ptr
|
||||
JMP CERROR
|
||||
|
||||
externalj:
|
||||
jmp EXTERNAL
|
||||
|
||||
fndcom: ; search the internal command table
|
||||
OR AL,AL ; Get real length of first arg
|
||||
jz externalj ; If 0, it must begin with "\" so has
|
||||
; to be external.
|
||||
; barryf code starts here
|
||||
|
||||
IF IBM
|
||||
call test_append ; see if APPEND installed
|
||||
je contcom ; not loaded
|
||||
|
||||
append_internal:
|
||||
mov cl,TRANGROUP:IDLEN
|
||||
mov ch,0
|
||||
mov pathpos,cx
|
||||
inc append_exec ;AN041; set APPEND to ON
|
||||
|
||||
invoke ioset ; re-direct the o'l io
|
||||
|
||||
mov SI, offset TRANGROUP:IDLEN ; address command name, DS already set
|
||||
mov DX,-1 ; set invoke function
|
||||
mov di,offset TRANGROUP:APPEND_PARSE;AN010; Get the entry point for PARSE for APPEND
|
||||
mov AX,0AE01H
|
||||
int 2FH ; execute command
|
||||
cmp TRANGROUP:IDLEN,0 ; execute requested
|
||||
jne contcom
|
||||
jmp Cmd_done
|
||||
|
||||
contcom: ; continue with internal scan
|
||||
ENDIF
|
||||
|
||||
; barryf code ends here
|
||||
|
||||
mov DI, OFFSET TRANGROUP:COMTAB
|
||||
XOR CX,CX
|
||||
|
||||
findcom:
|
||||
mov SI, offset TRANGROUP:IDLEN+1 ; pointer to command argument
|
||||
mov CL, [DI] ; load length of internal command
|
||||
inc di ; advance past length
|
||||
jcxz externalj ; if it's zero, we're out of internals
|
||||
cmp CL, IDLEN ; that of the command argument
|
||||
jnz abcd ; lengths not equal ==> strings not eq
|
||||
MOV PathPos,CX ; store length of command
|
||||
repz cmpsb
|
||||
|
||||
abcd:
|
||||
lahf ; save the good ol' flags
|
||||
add DI, CX ; skip over remaining internal, if any
|
||||
mov AL, BYTE PTR [DI] ; load drive-check indicator byte (DCIB)
|
||||
mov [CHKDRV], AL ; save command flag byte in chkdrv
|
||||
inc DI ; increment DI (OK, OK, I'll stop)
|
||||
mov BX, WORD PTR [DI] ; load internal command address
|
||||
inc DI ; skip over the puppy
|
||||
inc DI
|
||||
sahf ; remember those flags?
|
||||
jnz findcom ; well, if all the cmps worked...
|
||||
;
|
||||
; All messages get redirected.
|
||||
;
|
||||
cmp append_exec,0 ;AN041; APPEND just executed?
|
||||
jnz dont_set_io ;AN041; Yes - this junk is already set
|
||||
invoke ioset ; re-direct the ol' i/o
|
||||
|
||||
dont_set_io: ;AN041;
|
||||
invoke SETSTDINON ;AN026; turn on critical error on STDIN
|
||||
invoke SETSTDOUTOFF ;AN026; turn off critical error on STDOUT
|
||||
test [CHKDRV], fCheckDrive ; did we wanna check those drives?
|
||||
jz nocheck
|
||||
mov AL, [PARM1] ; parse_file_descriptor results tell
|
||||
or AL, [PARM2] ; us whether those drives were OK
|
||||
cmp AL, -1
|
||||
jnz nocheck
|
||||
jmp drvbad
|
||||
|
||||
|
||||
;
|
||||
; The user may have omitted the space between the command and its arguments.
|
||||
; We need to copy the remainder of the user's command line into the buffer.
|
||||
; Note that thisdoes not screw up the arg structure; it points into COMBUF not
|
||||
; into the command line at 80.
|
||||
;
|
||||
nocheck:
|
||||
call cmd_copy
|
||||
|
||||
switcheck:
|
||||
test [CHKDRV], fSwitchAllowed ; Does the command take switches
|
||||
jnz realwork ; Yes, process the command
|
||||
call noswit ; No, check to see if any switches
|
||||
jnz realwork ; None, process the command
|
||||
mov msg_disp_class,parse_msg_class ;AN000; set up parse error msg class
|
||||
MOV DX,OFFSET TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
|
||||
mov Extend_Buf_ptr,BadSwt_ptr ;AN000; get "Invalid switch" message number
|
||||
jmp CERROR ; Print error and chill out...
|
||||
realwork:
|
||||
call BX ; do some real work, at last
|
||||
|
||||
; See if we're in a batch CALL command. If we are, reprocess the command line,
|
||||
; otherwise, go get another command.
|
||||
|
||||
Cmd_done:
|
||||
push cs ; g restore data segment
|
||||
pop ds ; g
|
||||
push ds ; g save data segment
|
||||
mov ds,[resseg] ; g get segment containing call flag
|
||||
ASSUME ds:resgroup
|
||||
cmp call_flag, call_in_progress ; G Is a call in progress?
|
||||
mov call_flag, 0 ; G Either way, reset flag
|
||||
pop ds ; g get data segment back
|
||||
jz incall ; G
|
||||
jmp tcommand ; chill out...
|
||||
|
||||
incall:
|
||||
JMP DOCOM1
|
||||
|
||||
noswit:
|
||||
push di ; Save di
|
||||
mov di,81h ; di = ptr to command args
|
||||
mov si,80h ; Get address of length of command args
|
||||
lodsb ; Load length
|
||||
mov cl,al ; Move length to cl
|
||||
xor ch,ch ; Zero ch
|
||||
mov al,[SWITCHAR] ; al = switch character
|
||||
cmp al,0 ; Turn off ZF
|
||||
repnz scasb ; Scan for a switch character and return
|
||||
pop di ; with ZF set if one was found
|
||||
ret
|
||||
|
||||
EXTERNAL:
|
||||
|
||||
IF IBM
|
||||
call test_append ; check to see if append installed
|
||||
je not_barryf ; no - truly external command
|
||||
jmp append_internal ; yes - go to Barryf code
|
||||
|
||||
not_barryf:
|
||||
|
||||
ENDIF
|
||||
|
||||
MOV [FILTYP],0
|
||||
MOV DL,[SPECDRV]
|
||||
MOV [IDLEN],DL
|
||||
IF IBM
|
||||
MOV [ROM_CALL],0
|
||||
PUSH DX
|
||||
MOV DX,OFFSET TRANGROUP:IDLEN
|
||||
CALL ROM_SCAN
|
||||
POP DX
|
||||
JNC DO_SCAN
|
||||
INC [ROM_CALL]
|
||||
JMP PostSave
|
||||
DO_SCAN:
|
||||
ENDIF
|
||||
IF IBM
|
||||
PostSave:
|
||||
ENDIF
|
||||
MOV DI,OFFSET TRANGROUP:EXECPATH
|
||||
MOV BYTE PTR [DI],0 ; Initialize to current directory
|
||||
IF IBM
|
||||
CMP [ROM_CALL],0
|
||||
JZ Research
|
||||
JMP NeoExecute
|
||||
ENDIF
|
||||
RESEARCH:
|
||||
invoke path_search ; find the mother (result in execpath)
|
||||
or AX, AX ; did we find anything?
|
||||
je badcomj45 ; null means no (sob)
|
||||
cmp AX, 04H ; 04H and 08H are .exe and .com
|
||||
jl rsrch_br1 ; fuckin' sixteen-bit machine ought
|
||||
jmp execute ; to be able to handle a SIXTEEN-BIT
|
||||
rsrch_br1: ; DISPLACEMENT!!
|
||||
jmp batcom ; 02H is .bat
|
||||
BADCOMJ45:
|
||||
JMP BADCOM
|
||||
|
||||
ASSUME DS:TRANGROUP,ES:TRANGROUP
|
||||
|
||||
EXECUTE:
|
||||
NeoExecute:
|
||||
invoke IOSET
|
||||
invoke SETSTDINOFF ;AN026; turn off critical error on STDIN
|
||||
invoke SETSTDOUTOFF ;AN026; turn off critical error on STDOUT
|
||||
MOV ES,[TRAN_TPA]
|
||||
MOV AH,DEALLOC
|
||||
INT int_command ; Now running in "free" space
|
||||
MOV ES,[RESSEG]
|
||||
ASSUME ES:RESGROUP
|
||||
INC [EXTCOM] ; Indicate external command
|
||||
MOV [RESTDIR],0 ; Since USERDIR1 is in transient, insure
|
||||
; this flag value for re-entry to COMMAND
|
||||
MOV DI,FCB
|
||||
MOV SI,DI
|
||||
MOV CX,052H ; moving (100h-5Ch)/2 = 80h-2Eh
|
||||
REP MOVSW ; Transfer parameters to resident header
|
||||
MOV DX,OFFSET TRANGROUP:EXECPATH
|
||||
MOV BX,OFFSET RESGROUP:EXEC_BLOCK
|
||||
MOV AX,EXEC SHL 8
|
||||
IF IBM
|
||||
TEST [ROM_CALL],-1
|
||||
JZ OK_EXEC
|
||||
JMP ROM_EXEC
|
||||
OK_EXEC:
|
||||
ENDIF
|
||||
;
|
||||
; we are now running in free space. anything we do from here on may get
|
||||
; trashed. Move the stack (also in free space) to allocated space because
|
||||
; since EXEC restores the stack, somebody may trash what is on the stack.
|
||||
;
|
||||
MOV CX,ES
|
||||
MOV SS,CX
|
||||
MOV SP,OFFSET RESGROUP:RSTACK
|
||||
JMP [EXEC_ADDR] ; Jmp to the EXEC in the resident
|
||||
|
||||
BADCOM:
|
||||
PUSH CS
|
||||
POP DS
|
||||
MOV DX,OFFSET TRANGROUP:BADNAM_ptr
|
||||
|
||||
CERROR:
|
||||
INVOKE std_eprintf
|
||||
JMP TCOMMAND
|
||||
|
||||
;
|
||||
; Prescan converts the input buffer into a canonicalized form. All
|
||||
; redirections and pipes are removed.
|
||||
;
|
||||
PRESCAN: ; Cook the input buffer
|
||||
|
||||
ASSUME DS:TRANGROUP,ES:TRANGROUP
|
||||
|
||||
XOR CX,CX
|
||||
MOV ES,[RESSEG]
|
||||
ASSUME ES:RESGROUP
|
||||
MOV SI,OFFSET TRANGROUP:COMBUF+2
|
||||
MOV DI,SI
|
||||
|
||||
CountQuotes:
|
||||
LODSB ; get a byte
|
||||
CMP AL,22h ; is it a quote?
|
||||
JNZ CountEnd ; no, try for end of road
|
||||
INC CH ; bump count
|
||||
JMP CountQuotes ; go get next char
|
||||
|
||||
CountEnd:
|
||||
CMP AL,13 ; end of road?
|
||||
JNZ CountQuotes ; no, go back for next char
|
||||
|
||||
;;;; IF KANJI 3/3/KK
|
||||
PUSH CX ; save count
|
||||
MOV SI,DI ; get back beginning of buffer
|
||||
|
||||
KanjiScan:
|
||||
LODSB ; get a byte
|
||||
INVOKE TestKanj ; is it a leadin byte
|
||||
JZ KanjiQuote ; no, check for quotes
|
||||
MOV AH,AL ; save leadin
|
||||
LODSB ; get trailing byte
|
||||
CMP AX,8140h ; is it Kanji space
|
||||
JNZ KanjiScan ; no, go get next
|
||||
MOV [SI-2],2020h ; replace with spaces
|
||||
JMP KanjiScan ; go get next char
|
||||
|
||||
KanjiQuote:
|
||||
CMP AL,22h ; beginning of quoted string
|
||||
JNZ KanjiEnd ; no, check for end
|
||||
DEC CH ; drop count
|
||||
JZ KanjiScan ; if count is zero, no quoting
|
||||
|
||||
KanjiQuoteLoop:
|
||||
LODSB ; get next byte
|
||||
CMP AL,22h ; is it another quote
|
||||
JNZ KanjiQuoteLoop ; no, get another
|
||||
DEC CH ; yes, drop count
|
||||
JMP KanjiScan ; go get next char
|
||||
|
||||
KanjiEnd:
|
||||
CMP AL,13 ; end of line character?
|
||||
JNZ KanjiScan ; go back to beginning
|
||||
POP CX ; get back original count
|
||||
;;;; ENDIF 3/3/KK
|
||||
|
||||
MOV SI,DI ; restore pointer to begining
|
||||
|
||||
PRESCANLP:
|
||||
LODSB
|
||||
|
||||
;;;; IF KANJI 3/3/KK
|
||||
INVOKE TESTKANJ
|
||||
JZ NOTKANJ6
|
||||
MOV [DI],AL
|
||||
INC DI ; fake STOSB into DS
|
||||
LODSB ; grab second byte
|
||||
MOV [DI],AL ; fake stosb into DS
|
||||
INC DI
|
||||
INC CL
|
||||
INC CL
|
||||
JMP PRESCANLP
|
||||
|
||||
NOTKANJ6:
|
||||
;;;; ENDIF 3/3/KK
|
||||
|
||||
CMP AL,'"' ; " character
|
||||
JNZ TRYGREATER
|
||||
DEC CH
|
||||
JZ TRYGREATER
|
||||
|
||||
QLOOP:
|
||||
MOV [DI],AL
|
||||
INC DI
|
||||
INC CL
|
||||
LODSB
|
||||
CMP AL,'"' ; " character
|
||||
JNZ QLOOP
|
||||
DEC CH
|
||||
|
||||
TRYGREATER:
|
||||
CMP AL,rabracket
|
||||
JNZ NOOUT
|
||||
;
|
||||
; We have found a ">" char. We need to see if there is another ">"
|
||||
; following it.
|
||||
;
|
||||
CMP BYTE PTR [SI],al
|
||||
JNZ NOAPPND
|
||||
LODSB
|
||||
INC [RE_OUT_APP] ; Flag >>
|
||||
|
||||
NOAPPND:
|
||||
;
|
||||
; Now we attempt to find the file name. First, scan off all whitespace
|
||||
;
|
||||
INVOKE SCANOFF
|
||||
CMP AL,labracket ;AN040; was there no filename?
|
||||
JZ REOUT_ERRSET ;AN040; yes - set up error
|
||||
CMP AL,0DH
|
||||
JNZ GOTREOFIL
|
||||
;
|
||||
; There was no file present. Set us up at end-of-line.
|
||||
;
|
||||
REOUT_ERRSET: ;AN040; set up for an error
|
||||
mov byte ptr [di], 0dh ; Clobber first ">"
|
||||
MOV WORD PTR [RE_OUTSTR],09H ; Cause an error later
|
||||
JMP PRESCANEND
|
||||
|
||||
GOTREOFIL:
|
||||
PUSH DI
|
||||
MOV DI,OFFSET RESGROUP:RE_OUTSTR
|
||||
MOV BX,DI
|
||||
PUSH ES
|
||||
|
||||
SETREOUTSTR: ; Get the output redirection name
|
||||
LODSB
|
||||
CMP AL,0DH
|
||||
JZ GOTRESTR
|
||||
INVOKE DELIM
|
||||
JZ GOTRESTR
|
||||
CMP AL,[SWITCHAR]
|
||||
JZ GOTRESTR
|
||||
CMP AL,'"' ;AN033; Is the character a quote?
|
||||
JZ PIPEERRSYNJ5 ;AN033; Yes - get out quick - or system crashes
|
||||
CMP AL,labracket ;AN002; Is char for input redirection
|
||||
JZ ABRACKET_TERM ;AN002; yes - end of string
|
||||
CMP AL,rabracket ;AN002; Is char for output redirection
|
||||
JNZ NO_ABRACKET ;AN002; no - not end of string
|
||||
|
||||
abracket_term: ;AN002; have end of string by < or >
|
||||
DEC SI ;AN002; back up over symbol
|
||||
MOV AL,BLANK ;AN002; show delimiter as char
|
||||
JMP SHORT GOTRESTR ;AN002; go process it
|
||||
|
||||
no_abracket: ;AN002; not at end of string
|
||||
STOSB ; store it into resgroup
|
||||
JMP SHORT SETREOUTSTR
|
||||
|
||||
NOOUT:
|
||||
CMP AL,labracket
|
||||
JNZ CHKPIPE
|
||||
mov bx,si ; Save loc of "<"
|
||||
INVOKE SCANOFF
|
||||
CMP AL,rabracket ;AN040; was there no filename?
|
||||
JZ REIN_ERRSET ;AN040; yes - set up error
|
||||
CMP AL,0DH
|
||||
JNZ GOTREIFIL
|
||||
|
||||
REIN_ERRSET: ;AN040; set up for error
|
||||
mov byte ptr [di],0dh ; Clobber "<"
|
||||
MOV WORD PTR [RE_INSTR],09H ; Cause an error later
|
||||
JMP SHORT PRESCANEND
|
||||
|
||||
GOTREIFIL:
|
||||
PUSH DI
|
||||
MOV DI,OFFSET TranGROUP:RE_INSTR
|
||||
MOV BX,DI
|
||||
PUSH ES
|
||||
PUSH CS
|
||||
POP ES ; store in TRANGROUP
|
||||
JMP SHORT SETREOUTSTR ; Get the input redirection name
|
||||
|
||||
CHKPIPE:
|
||||
MOV AH,AL
|
||||
CMP AH,AltPipeChr
|
||||
JZ IsPipe3
|
||||
CMP AH,vbar
|
||||
JNZ CONTPRESCAN
|
||||
|
||||
IsPipe3:
|
||||
;
|
||||
; Only push the echo flag if we are entering the pipe for the first time.
|
||||
;
|
||||
CMP PipeFlag,0
|
||||
JNZ NoEchoPush
|
||||
SHL EchoFlag,1 ; push echo state and turn it off
|
||||
NoEchoPush:
|
||||
INC [PIPEFLAG]
|
||||
INVOKE SCANOFF
|
||||
CMP AL,0DH
|
||||
JZ PIPEERRSYNJ5
|
||||
CMP AL,AltPipeChr
|
||||
JZ PIPEERRSYNJ5
|
||||
CMP AL,vbar ; Double '|'?
|
||||
JNZ CONTPRESCAN
|
||||
|
||||
PIPEERRSYNJ5:
|
||||
PUSH ES
|
||||
POP DS ; DS->RESGROUP
|
||||
JMP PIPEERRSYN
|
||||
|
||||
;
|
||||
; Trailing :s are allowed on devices. Check to be sure that there is more
|
||||
; than just a : in the redir string.
|
||||
;
|
||||
GOTRESTR:
|
||||
XCHG AH,AL
|
||||
mov al,':'
|
||||
SUB BX,DI ; compute negatinve of number of chars
|
||||
CMP BX,-1 ; is there just a :?
|
||||
JZ NotTrailCol ; yep, don't change
|
||||
CMP BYTE PTR ES:[DI-1],al ; Trailing ':' OK on devices
|
||||
JNZ NOTTRAILCOL
|
||||
DEC DI ; Back up over trailing ':'
|
||||
|
||||
NOTTRAILCOL:
|
||||
XOR AL,AL
|
||||
STOSB ; NUL terminate the string
|
||||
POP ES
|
||||
POP DI ; Remember the start
|
||||
|
||||
CONTPRESCAN:
|
||||
MOV [DI],AH ; "delete" the redirection string
|
||||
INC DI
|
||||
CMP AH,0DH
|
||||
JZ PRESCANEND
|
||||
INC CL
|
||||
JMP PRESCANLP
|
||||
|
||||
PRESCANEND:
|
||||
CMP [PIPEFLAG],0
|
||||
JZ ISNOPIPE
|
||||
MOV DI,OFFSET RESGROUP:PIPESTR
|
||||
MOV [PIPEPTR],DI
|
||||
MOV SI,OFFSET TRANGROUP:COMBUF+2
|
||||
INVOKE SCANOFF
|
||||
|
||||
PIPESETLP: ; Transfer the pipe into the resident
|
||||
LODSB ; pipe buffer
|
||||
STOSB
|
||||
CMP AL,0DH
|
||||
JNZ PIPESETLP
|
||||
|
||||
ISNOPIPE:
|
||||
MOV [COMBUF+1],CL
|
||||
CMP [PIPEFLAG],0
|
||||
PUSH CS
|
||||
POP ES
|
||||
return
|
||||
|
||||
cmd_copy proc near
|
||||
|
||||
MOV SI,OFFSET TRANGROUP:COMBUF+2
|
||||
INVOKE Scanoff ; advance past separators...
|
||||
add si,PathPos
|
||||
mov di,81h
|
||||
xor cx,cx
|
||||
|
||||
CmdCopy:
|
||||
lodsb
|
||||
stosb
|
||||
cmp al,0dh
|
||||
jz CopyDone
|
||||
inc cx
|
||||
jmp CmdCopy
|
||||
|
||||
CopyDone:
|
||||
mov byte ptr ds:[80h],cl ; Store count
|
||||
|
||||
ret
|
||||
cmd_copy endp
|
||||
|
||||
|
||||
test_append proc near
|
||||
|
||||
mov BX,offset TRANGROUP:COMBUF ; barry can address
|
||||
mov SI, offset TRANGROUP:IDLEN ; address command name, DS already set
|
||||
mov DX,-1 ; set install check function
|
||||
mov AX,0AE00H
|
||||
int 2FH ; see if loaded
|
||||
cmp AL,00H
|
||||
|
||||
ret
|
||||
|
||||
test_append endp
|
||||
|
||||
TRANCODE ENDS
|
||||
END
|
||||
|
||||
487
v4.0/src/CMD/COMMAND/TMISC2.ASM
Normal file
487
v4.0/src/CMD/COMMAND/TMISC2.ASM
Normal file
@@ -0,0 +1,487 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)tmisc2.asm 4.3 85/06/25
|
||||
; SCCSID = @(#)tmisc2.asm 4.3 85/06/25
|
||||
TITLE Part7 COMMAND Transient Routines
|
||||
|
||||
; More misc routines
|
||||
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE comsw.asm
|
||||
INCLUDE DOSSYM.INC
|
||||
INCLUDE comseg.asm
|
||||
INCLUDE comequ.asm
|
||||
INCLUDE ioctl.inc
|
||||
.list
|
||||
.cref
|
||||
|
||||
|
||||
CODERES SEGMENT PUBLIC BYTE ;AC000;
|
||||
CodeRes ENDS
|
||||
|
||||
DATARES SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN IFFlag:BYTE
|
||||
EXTRN PIPEFLAG:BYTE
|
||||
EXTRN RE_OUTSTR:BYTE
|
||||
EXTRN RE_OUT_APP:BYTE
|
||||
DATARES ENDS
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN AccDen_PTR:WORD
|
||||
EXTRN Extend_buf_ptr:word ;AN000;
|
||||
EXTRN FULDIR_PTR:WORD
|
||||
EXTRN msg_disp_class:byte ;AN000;
|
||||
TRANDATA ENDS
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN DESTINFO:BYTE
|
||||
EXTRN DESTISDIR:BYTE
|
||||
EXTRN KPARSE:BYTE ;AC000;
|
||||
EXTRN ONE_CHAR_VAL:BYTE ;AN011;
|
||||
EXTRN PATHCNT:WORD
|
||||
EXTRN PATHPOS:WORD
|
||||
EXTRN PATHSW:WORD
|
||||
EXTRN RE_INSTR:BYTE
|
||||
EXTRN RESSEG:WORD
|
||||
EXTRN SRCBUF:BYTE
|
||||
EXTRN SWITCHAR:BYTE
|
||||
|
||||
IF IBM
|
||||
EXTRN ROM_CALL:BYTE
|
||||
EXTRN ROM_CS:WORD
|
||||
EXTRN ROM_IP:WORD
|
||||
ENDIF
|
||||
|
||||
TRANSPACE ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC byte
|
||||
|
||||
ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
|
||||
EXTRN CERROR:NEAR
|
||||
|
||||
IF IBM
|
||||
EXTRN ROM_EXEC:NEAR
|
||||
EXTRN ROM_SCAN:NEAR
|
||||
ENDIF
|
||||
|
||||
PUBLIC IOSET
|
||||
PUBLIC MOVE_TO_SRCBUF ;AN000;
|
||||
PUBLIC PGETARG
|
||||
PUBLIC SETPATH
|
||||
PUBLIC TESTDOREIN
|
||||
PUBLIC TESTDOREOUT
|
||||
|
||||
|
||||
ASSUME DS:TRANGROUP
|
||||
|
||||
SETPATH:
|
||||
;
|
||||
; Get an ASCIZ argument from the unformatted parms
|
||||
; DESTISDIR set if pathchars in string
|
||||
; DESTINFO set if ? or * in string
|
||||
;
|
||||
MOV AX,[PATHCNT] ;AC000; get length of string
|
||||
MOV SI,[PATHPOS] ;AC000; get start of source buffer
|
||||
|
||||
GETPATH:
|
||||
MOV [DESTINFO],0
|
||||
MOV [DESTISDIR],0
|
||||
MOV SI,[PATHPOS]
|
||||
MOV CX,[PATHCNT]
|
||||
MOV DX,SI
|
||||
JCXZ PATHDONE
|
||||
PUSH CX
|
||||
PUSH SI
|
||||
INVOKE SWITCH
|
||||
MOV [PATHSW],AX
|
||||
POP BX
|
||||
SUB BX,SI
|
||||
POP CX
|
||||
ADD CX,BX
|
||||
MOV DX,SI
|
||||
|
||||
SKIPPATH:
|
||||
|
||||
;;;; IF KANJI 3/3/KK
|
||||
MOV [KPARSE],0
|
||||
|
||||
SKIPPATH2:
|
||||
;;;; ENDIF 3/3/KK
|
||||
|
||||
JCXZ PATHDONE
|
||||
DEC CX
|
||||
LODSB
|
||||
|
||||
;;;; IF KANJI 3/3/KK
|
||||
INVOKE TESTKANJ
|
||||
JZ TESTPPSEP
|
||||
DEC CX
|
||||
INC SI
|
||||
INC [KPARSE]
|
||||
JMP SKIPPATH2
|
||||
|
||||
TESTPPSEP:
|
||||
;;;; ENDIF 3/3/KK
|
||||
|
||||
INVOKE PATHCHRCMP
|
||||
JNZ TESTPMETA
|
||||
INC [DESTISDIR]
|
||||
|
||||
TESTPMETA:
|
||||
CMP AL,'?'
|
||||
JNZ TESTPSTAR
|
||||
OR [DESTINFO],2
|
||||
|
||||
TESTPSTAR:
|
||||
CMP AL,star
|
||||
JNZ TESTPDELIM
|
||||
OR [DESTINFO],2
|
||||
|
||||
TESTPDELIM:
|
||||
INVOKE DELIM
|
||||
JZ PATHDONEDEC
|
||||
CMP AL,[SWITCHAR]
|
||||
JNZ SKIPPATH
|
||||
|
||||
PATHDONEDEC:
|
||||
DEC SI
|
||||
|
||||
PATHDONE:
|
||||
XOR AL,AL
|
||||
XCHG AL,[SI]
|
||||
INC SI
|
||||
CMP AL,0DH
|
||||
JNZ NOPSTORE
|
||||
MOV [SI],AL ;Don't loose the CR
|
||||
|
||||
NOPSTORE:
|
||||
MOV [PATHPOS],SI
|
||||
MOV [PATHCNT],CX
|
||||
return
|
||||
|
||||
PGETARG:
|
||||
MOV SI,80H
|
||||
LODSB
|
||||
OR AL,AL
|
||||
retz
|
||||
CALL PSCANOFF
|
||||
CMP AL,13
|
||||
return
|
||||
|
||||
PSCANOFF:
|
||||
LODSB
|
||||
INVOKE DELIM
|
||||
JNZ PSCANOFFD
|
||||
CMP AL,';'
|
||||
JNZ PSCANOFF ; ';' is not a delimiter
|
||||
|
||||
PSCANOFFD:
|
||||
DEC SI ; Point to first non-delimiter
|
||||
return
|
||||
|
||||
IOSET:
|
||||
;
|
||||
; ALL REGISTERS PRESERVED
|
||||
;
|
||||
ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
|
||||
PUSH DS
|
||||
PUSH DX
|
||||
PUSH AX
|
||||
PUSH BX
|
||||
PUSH CX
|
||||
MOV DS,[RESSEG]
|
||||
ASSUME DS:RESGROUP
|
||||
|
||||
CMP [PIPEFLAG],0
|
||||
JNZ NOREDIR ; Don't muck up the pipe
|
||||
TEST IFFlag,-1
|
||||
JNZ NoRedir
|
||||
CALL TESTDOREIN
|
||||
CALL TESTDOREOUT
|
||||
|
||||
NOREDIR:
|
||||
POP CX
|
||||
POP BX
|
||||
POP AX
|
||||
POP DX
|
||||
POP DS
|
||||
ASSUME DS:NOTHING
|
||||
return
|
||||
|
||||
TESTDOREIN:
|
||||
|
||||
ASSUME DS:RESGROUP
|
||||
|
||||
CMP [RE_INSTR],0
|
||||
retz
|
||||
PUSH DS
|
||||
PUSH CS
|
||||
POP DS
|
||||
MOV DX,OFFSET tranGROUP:RE_INSTR
|
||||
MOV AX,(OPEN SHL 8)
|
||||
MOV BX,AX
|
||||
INT int_command
|
||||
POP DS
|
||||
JC REDIRERR
|
||||
MOV BX,AX
|
||||
MOV AL,0FFH
|
||||
;
|
||||
; Mega sleaze!! We move the SFN from the new handle spot into the old stdin
|
||||
; spot. We invalidate the new JFN we got.
|
||||
;
|
||||
XCHG AL,[BX.PDB_JFN_Table]
|
||||
MOV DS:[PDB_JFN_Table],AL
|
||||
|
||||
return
|
||||
;
|
||||
; We had some kind of error on the redirection. Figure out what the
|
||||
; appropriate message should be; BX has the system call that failed
|
||||
;
|
||||
REDIRERR:
|
||||
PUSH CS
|
||||
POP DS
|
||||
Call TriageError
|
||||
;
|
||||
; At this point, we have recognized the network-generated access denied error.
|
||||
; The correct message is in DX
|
||||
;
|
||||
CMP AX,65
|
||||
JZ CERRORJ ;AC000; just issue message returned
|
||||
CMP BH,OPEN
|
||||
JZ OpenError
|
||||
;
|
||||
; The error was for a create operation. Report the error as a creation error.
|
||||
;
|
||||
MOV DX,OFFSET TranGroup:FULDIR_PTR
|
||||
|
||||
CERRORJ:
|
||||
JMP CERROR
|
||||
;
|
||||
; The system call was an OPEN. Report either file not found or path not found.
|
||||
;
|
||||
|
||||
OpenError:
|
||||
mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class
|
||||
mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
|
||||
mov Extend_Buf_ptr,ax ;AN000; get message number in control block
|
||||
JMP CERROR
|
||||
|
||||
TESTDOREOUT:
|
||||
|
||||
ASSUME DS:RESGROUP
|
||||
|
||||
CMP [RE_OUTSTR],0
|
||||
JNZ REOUTEXISTS ;AN017; need long jump
|
||||
JMP NOREOUT ;AN017;
|
||||
|
||||
REOUTEXISTS:
|
||||
CMP [RE_OUT_APP],0
|
||||
JZ REOUTCRT
|
||||
;
|
||||
; The output redirection was for append. We open for write and seek to the
|
||||
; end.
|
||||
;
|
||||
MOV DX,OFFSET RESGROUP:RE_OUTSTR
|
||||
MOV AX,(OPEN SHL 8) OR 2 ;AC011; Open for read/write
|
||||
PUSH AX
|
||||
INT int_command
|
||||
POP BX
|
||||
JC OpenWriteError
|
||||
|
||||
MOV BX,AX
|
||||
MOV AX,IOCTL SHL 8 ;AN035; Get attributes of handle
|
||||
INT int_command ;AN035;
|
||||
TEST DL,devid_ISDEV ;AN035; Is it a device?
|
||||
JNZ SET_REOUT ;AN035; Yes, don't read from it
|
||||
|
||||
MOV AX,(LSEEK SHL 8) OR 2
|
||||
MOV CX,-1 ;AC011; MOVE TO EOF -1
|
||||
MOV DX,CX ;AC011;
|
||||
INT int_command
|
||||
PUSH CS ;AN011; Get transient seg to DS
|
||||
POP DS ;AN011;
|
||||
assume DS:Trangroup ;AN011;
|
||||
MOV AX,(READ SHL 8) ;AN011; Read one byte from the
|
||||
MOV CX,1 ;AN011; file into one_char_val
|
||||
MOV DX,OFFSET Trangroup:ONE_CHAR_VAL;AN011;
|
||||
INT int_command ;AN011;
|
||||
JC OpenWriteError ;AN011; If error, exit
|
||||
cmp ax,cx ;AN017; Did we read 1 byte?
|
||||
jnz reout_0_length ;AN017; No - file must be 0 length
|
||||
|
||||
cmp one_char_val,01ah ;AN011; Was char an eof mark?
|
||||
mov DS,[resseg] ;AN011; Get resident segment back
|
||||
assume DS:Resgroup ;AN011;
|
||||
JNZ SET_REOUT ;AN011; No, just continue
|
||||
MOV AX,(LSEEK SHL 8) OR 1 ;AN011; EOF mark found
|
||||
MOV CX,-1 ;AN011; LSEEK back one byte
|
||||
MOV DX,CX ;AN011;
|
||||
INT int_command ;AN011;
|
||||
JMP SHORT SET_REOUT
|
||||
|
||||
reout_0_length: ;AN017; We have a 0 length file
|
||||
mov DS,[resseg] ;AN017; Get resident segment back
|
||||
assume DS:Resgroup ;AN017;
|
||||
MOV AX,(LSEEK SHL 8) ;AN017; Move to beginning of file
|
||||
XOR CX,CX ;AN017; Offset is 0
|
||||
MOV DX,CX ;AN017;
|
||||
INT int_command ;AN017;
|
||||
JMP SHORT SET_REOUT ;AN017; now finish setting up redirection
|
||||
|
||||
OpenWriteError:
|
||||
CMP AX,error_access_denied
|
||||
STC ; preserve error
|
||||
JNZ REOUTCRT ;AN017; need long jump
|
||||
JMP REDIRERR ;AN017;
|
||||
|
||||
REOUTCRT:
|
||||
MOV DX,OFFSET RESGROUP:RE_OUTSTR
|
||||
XOR CX,CX
|
||||
MOV AH,CREAT
|
||||
PUSH AX
|
||||
INT int_command
|
||||
POP BX
|
||||
JNC NOREDIRERR ;AC011;
|
||||
JMP REDIRERR ;AC011;
|
||||
|
||||
NOREDIRERR: ;AN011;
|
||||
MOV BX,AX
|
||||
|
||||
SET_REOUT:
|
||||
;
|
||||
; Mega sleaze!! We move the SFN from the new handle spot into the old stdout
|
||||
; spot. We invalidate the new JFN we got.
|
||||
;
|
||||
MOV AL,0FFH
|
||||
XCHG AL,[BX.PDB_JFN_Table]
|
||||
MOV DS:[PDB_JFN_Table+1],AL
|
||||
|
||||
NOREOUT:
|
||||
return
|
||||
|
||||
;
|
||||
; Compute length of string (including NUL) in DS:SI into CX. Change no other
|
||||
; registers
|
||||
;
|
||||
Procedure DSTRLEN,NEAR
|
||||
|
||||
SaveReg <AX>
|
||||
XOR CX,CX
|
||||
CLD
|
||||
|
||||
DLoop: LODSB
|
||||
INC CX
|
||||
OR AL,AL
|
||||
JNZ DLoop
|
||||
SUB SI,CX
|
||||
RestoreReg <AX>
|
||||
return
|
||||
|
||||
EndProc DSTRLEN
|
||||
|
||||
Break <Extended error support>
|
||||
|
||||
;
|
||||
; TriageError will examine the return from a carry-set system call and
|
||||
; return the correct error if applicable.
|
||||
;
|
||||
; Inputs: outputs from a carry-settable system call
|
||||
; No system calls may be done in the interrim
|
||||
; Outputs: If carry was set on input
|
||||
; carry set on output
|
||||
; DX contains trangroup offset to printf message
|
||||
; else
|
||||
; No registers changed
|
||||
;
|
||||
|
||||
Procedure TriageError,NEAR
|
||||
|
||||
retnc ; no carry => do nothing...
|
||||
PUSHF
|
||||
SaveReg <BX,CX,SI,DI,BP,ES,DS,AX,DX>
|
||||
MOV AH,GetExtendedError
|
||||
INT 21h
|
||||
RestoreReg <CX,BX> ; restore original AX
|
||||
MOV DX,OFFSET TranGroup:AccDen_PTR
|
||||
CMP AX,65 ; network access denied?
|
||||
JZ NoMove ; Yes, return it.
|
||||
MOV AX,BX
|
||||
MOV DX,CX
|
||||
|
||||
NoMove:
|
||||
RestoreReg <DS,ES,BP,DI,SI,CX,BX>
|
||||
popf
|
||||
return
|
||||
|
||||
EndProc TriageError
|
||||
|
||||
PUBLIC Triage_Init
|
||||
Triage_Init proc FAR
|
||||
call TriageError
|
||||
ret
|
||||
Triage_Init endp
|
||||
|
||||
|
||||
; ****************************************************************
|
||||
; *
|
||||
; * ROUTINE: MOVE_TO_SRCBUF
|
||||
; *
|
||||
; * FUNCTION: Move ASCIIZ string from DS:SI to SRCBUF. Change
|
||||
; * terminating 0 to 0dH. Set PATHCNT to length of
|
||||
; * string. Set PATHPOS to start of SRCBUF.
|
||||
; *
|
||||
; * INPUT: DS:SI points to ASCIIZ string
|
||||
; * ES points to TRANGROUP
|
||||
; *
|
||||
; * OUTPUT: SRCBUF filled in with string terminated by 0dH
|
||||
; * PATHCNT set to length of string
|
||||
; * PATHPOS set to start of SRCBUF
|
||||
; * CX,AX changed
|
||||
; *
|
||||
; ****************************************************************
|
||||
|
||||
assume es:trangroup,ds:nothing ;AN000;
|
||||
|
||||
MOVE_TO_SRCBUF PROC NEAR ;AN000;
|
||||
|
||||
push si ;AN000; save si,di
|
||||
push di ;AN000;
|
||||
push cx ;AN000;
|
||||
mov di,offset TRANGROUP:srcbuf ;AN000; set ES:DI to srcbuf
|
||||
xor cx,cx ;AN000; clear cx for counint
|
||||
mov ax,cx ;AN000; clear ax
|
||||
push di ;AN000; save start of srcbuf
|
||||
lodsb ;AN000; get a character from DS:SI
|
||||
|
||||
mts_get_chars: ;AN000;
|
||||
cmp al,0 ;AN000; was it a null char?
|
||||
jz mts_end_string ;AN000; yes - exit
|
||||
stosb ;AN000; no - store it in srcbuf
|
||||
inc cx ;AN000; increment length count
|
||||
lodsb ;AN000; get a character from DS:SI
|
||||
jmp short mts_get_chars ;AN000; go check it
|
||||
|
||||
mts_end_string: ;AN000; we've reached the end of line
|
||||
mov al,end_of_line_in ;AN000; store 0dH in srcbuf
|
||||
stosb ;AN000;
|
||||
pop di ;AN000; restore start of srcbuf
|
||||
|
||||
push cs ;AN000; set DS to local segment
|
||||
pop ds ;AN000;
|
||||
assume ds:trangroup ;AN000;
|
||||
mov [pathcnt],cx ;AN000; set patchcnt to length count
|
||||
mov [pathpos],di ;AN000; set pathpos to start of srcbuf
|
||||
pop cx ;AN000; restore cx,di,si
|
||||
pop di ;AN000;
|
||||
pop si ;AN000;
|
||||
|
||||
RET ;AN000; exit
|
||||
|
||||
MOVE_TO_SRCBUF ENDP ;AN000;
|
||||
|
||||
TRANCODE ENDS
|
||||
END
|
||||
|
||||
76
v4.0/src/CMD/COMMAND/TPARSE.ASM
Normal file
76
v4.0/src/CMD/COMMAND/TPARSE.ASM
Normal file
@@ -0,0 +1,76 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)tparse.asm 4.1 87/04/28
|
||||
; SCCSID = @(#)tparse.asm 4.1 87/04/28
|
||||
TITLE COMMAND interface to SYSPARSE
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE comseg.asm ;AN000;
|
||||
.list
|
||||
.cref
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AN000;
|
||||
|
||||
CmpxSW equ 0 ;AN000; do not check complex list
|
||||
KeySW equ 0 ;AN000; do not support keywords
|
||||
Val2SW equ 0 ;AN000; do not Support value definition 2
|
||||
IncSW equ 0 ;AN000; do not include psdata.inc
|
||||
QusSW equ 0 ;AN025; do not include quoted string
|
||||
LFEOLSW equ 0 ;AN044; do not use 0ah as line terminator
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
|
||||
include psdata.inc ;AN000;
|
||||
|
||||
.list
|
||||
.cref
|
||||
|
||||
TRANSPACE ENDS ;AN000;
|
||||
|
||||
TRANCODE SEGMENT PUBLIC BYTE ;AN000;
|
||||
|
||||
ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING ;AN054;
|
||||
|
||||
; ****************************************************************
|
||||
; *
|
||||
; * ROUTINE: CMD_PARSE
|
||||
; *
|
||||
; * FUNCTION: Interface for transient COMMAND to invoke
|
||||
; * SYSPARSE.
|
||||
; *
|
||||
; * INPUT: inputs to SYSPARSE
|
||||
; *
|
||||
; * OUTPUT: outputs from SYSPARSE
|
||||
; *
|
||||
; ****************************************************************
|
||||
|
||||
public Cmd_parse ;AN000;
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE parse.asm ;AN000;
|
||||
.list
|
||||
.cref
|
||||
|
||||
Cmd_parse Proc near ;AN000;
|
||||
|
||||
call sysparse ;AN000;
|
||||
|
||||
ret ;AN000;
|
||||
|
||||
Cmd_parse endp ;AN000;
|
||||
|
||||
public Append_parse ;AN010;
|
||||
|
||||
Append_parse Proc Far ;AN010;
|
||||
|
||||
call sysparse ;AN010;
|
||||
|
||||
ret ;AN010;
|
||||
|
||||
Append_parse endp ;AN010;
|
||||
|
||||
trancode ends ;AN000;
|
||||
end ;AN000;
|
||||
|
||||
660
v4.0/src/CMD/COMMAND/TPIPE.ASM
Normal file
660
v4.0/src/CMD/COMMAND/TPIPE.ASM
Normal file
@@ -0,0 +1,660 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)tpipe.asm 1.1 85/05/14
|
||||
; SCCSID = @(#)tpipe.asm 1.1 85/05/14
|
||||
TITLE PART8 COMMAND Transient routines.
|
||||
|
||||
|
||||
INCLUDE comsw.asm
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE DOSSYM.INC
|
||||
INCLUDE comseg.asm
|
||||
INCLUDE comequ.asm
|
||||
.list
|
||||
.cref
|
||||
|
||||
|
||||
DATARES SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN ECHOFLAG:BYTE
|
||||
EXTRN InitFlag:byte
|
||||
EXTRN INPIPEPTR:WORD
|
||||
EXTRN OUTPIPEPTR:WORD
|
||||
EXTRN PIPE1:BYTE
|
||||
EXTRN PIPE1T:BYTE
|
||||
EXTRN PIPE2:BYTE
|
||||
EXTRN PIPE2T:BYTE
|
||||
EXTRN PIPEFILES:BYTE
|
||||
EXTRN PIPEFLAG:BYTE
|
||||
EXTRN PIPEPTR:WORD
|
||||
EXTRN RESTDIR:BYTE
|
||||
EXTRN SINGLECOM:WORD
|
||||
DATARES ENDS
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN BADDAT_PTR:WORD
|
||||
EXTRN BADTIM_PTR:WORD
|
||||
EXTRN curdat_mo_day:word ;AN000;
|
||||
EXTRN CURDAT_PTR:WORD
|
||||
EXTRN curdat_yr:word ;AN000;
|
||||
EXTRN curtim_hr_min:word ;AN000;
|
||||
EXTRN CURTIM_PTR:WORD
|
||||
EXTRN curtim_sec_hn:word ;AN000;
|
||||
EXTRN eurdat_ptr:word
|
||||
EXTRN japdat_ptr:word
|
||||
EXTRN newdat_format:word ;AN000;
|
||||
EXTRN NEWDAT_PTR:WORD
|
||||
EXTRN NEWTIM_PTR:WORD
|
||||
EXTRN parse_date:byte ;AN000;
|
||||
EXTRN parse_time:byte ;AN000;
|
||||
EXTRN PIPEEMES_PTR:WORD
|
||||
EXTRN promtim_hr_min:word ;AN000;
|
||||
EXTRN promtim_ptr:word ;AN000;
|
||||
EXTRN promtim_sec_hn:word ;AN000;
|
||||
EXTRN STRING_BUF_PTR:WORD ;AC000;
|
||||
EXTRN SYNTMES_PTR:WORD
|
||||
EXTRN usadat_ptr:word
|
||||
|
||||
TRANDATA ENDS
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN COMBUF:BYTE
|
||||
EXTRN date_day:byte ;AN000;
|
||||
EXTRN date_month:byte ;AN000;
|
||||
EXTRN date_year:word ;AN000;
|
||||
EXTRN INTERNATVARS:BYTE
|
||||
EXTRN RESSEG:WORD
|
||||
EXTRN time_fraction:byte ;AN000;
|
||||
EXTRN time_hour:byte ;AN000;
|
||||
EXTRN time_minutes:byte ;AN000;
|
||||
EXTRN time_seconds:byte ;AN000;
|
||||
TRANSPACE ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC BYTE
|
||||
ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING
|
||||
|
||||
EXTRN CERROR:NEAR
|
||||
EXTRN NOPIPEPROC:NEAR
|
||||
EXTRN STD_PRINTF:NEAR
|
||||
EXTRN TCOMMAND:NEAR
|
||||
EXTRN TESTDOREIN:NEAR
|
||||
EXTRN TESTDOREOUT:NEAR
|
||||
EXTRN TESTKANJ:NEAR ;AN000;3/3/KK
|
||||
EXTRN TSYSGETMSG:NEAR ;AN000;
|
||||
|
||||
PUBLIC CTIME
|
||||
PUBLIC DATE
|
||||
PUBLIC DATINIT
|
||||
PUBLIC PIPEDEL
|
||||
PUBLIC PIPEERRSYN
|
||||
PUBLIC PIPEPROC
|
||||
PUBLIC PIPEPROCSTRT
|
||||
PUBLIC PRINT_TIME
|
||||
PUBLIC SETREST
|
||||
PUBLIC SETREST1
|
||||
PUBLIC SINGLETEST
|
||||
|
||||
SINGLETEST:
|
||||
ASSUME DS:NOTHING
|
||||
push ds
|
||||
MOV DS,ResSeg
|
||||
ASSUME DS:ResGroup
|
||||
CMP [SINGLECOM],0
|
||||
JZ TestDone
|
||||
CMP [SINGLECOM],0EFFFH
|
||||
TestDone:
|
||||
pop ds
|
||||
return
|
||||
|
||||
|
||||
ASSUME DS:TRANGROUP
|
||||
SETREST1:
|
||||
MOV AL,1
|
||||
SETREST:
|
||||
PUSH DS
|
||||
MOV DS,[RESSEG]
|
||||
ASSUME DS:RESGROUP
|
||||
MOV [RESTDIR],AL
|
||||
POP DS
|
||||
ASSUME DS:TRANGROUP
|
||||
return
|
||||
|
||||
ASSUME DS:RESGROUP
|
||||
|
||||
;
|
||||
; Note that we need to handle the same thing that RestDir handles: the
|
||||
; requirement that we try only once to restore the user's environment after
|
||||
; and INT 24 or the like. If the condition that causes the INT 24 does not
|
||||
; disappear, we just give up.
|
||||
;
|
||||
|
||||
PIPEDEL:
|
||||
assume ds:nothing
|
||||
push ds
|
||||
PUSH DX
|
||||
mov ds,ResSeg
|
||||
assume ds:ResGroup
|
||||
mov DX,OFFSET RESGROUP:PIPE1 ; Clean up in case ^C
|
||||
MOV AH,UNLINK
|
||||
INT int_command
|
||||
MOV DX,OFFSET RESGROUP:PIPE2
|
||||
MOV AH,UNLINK
|
||||
INT int_command
|
||||
POP DX
|
||||
call PipeOff
|
||||
mov PipeFiles,0
|
||||
pop ds
|
||||
return
|
||||
|
||||
PIPEERRSYN:
|
||||
MOV DX,OFFSET TRANGROUP:SYNTMES_ptr
|
||||
CALL PIPEDEL
|
||||
PUSH CS
|
||||
POP DS
|
||||
JMP CERROR
|
||||
PIPEERR:
|
||||
pushf
|
||||
invoke triageError
|
||||
SaveReg <AX,DX> ; Save results from TriageError
|
||||
MOV DX,OFFSET TRANGROUP:PIPEEMES_ptr
|
||||
CALL PIPEDEL
|
||||
PUSH CS
|
||||
POP DS
|
||||
invoke std_eprintf
|
||||
RestoreReg <DX,AX> ; Restore results from TriageError
|
||||
popf
|
||||
cmp ax, 65
|
||||
jnz tcommandj
|
||||
JMP CERROR
|
||||
tcommandj:
|
||||
jmp tcommand
|
||||
|
||||
PIPEPROCSTRT:
|
||||
ASSUME DS:TRANGROUP,ES:TRANGROUP
|
||||
MOV DS,[RESSEG]
|
||||
ASSUME DS:RESGROUP
|
||||
INC [PIPEFILES] ; Flag that the pipe files exist
|
||||
MOV AH,Get_Default_Drive ; Get current drive
|
||||
INT int_command
|
||||
ADD AL,capital_A
|
||||
MOV [PIPE2],AL ; Make pipe files in root of def drv
|
||||
MOV BX,OFFSET RESGROUP:PIPE1
|
||||
MOV [BX],AL
|
||||
xor ah,ah ; nul terminate path names
|
||||
mov [Pipe1T],ah
|
||||
mov [Pipe2T],ah
|
||||
MOV DX,BX
|
||||
XOR CX,CX
|
||||
mov ah,CreateTempFile ; the CreateTemp call
|
||||
INT int_command
|
||||
JC PIPEERR ; Couldn't create
|
||||
MOV BX,AX
|
||||
MOV AH,CLOSE ; Don't proliferate handles
|
||||
INT int_command
|
||||
|
||||
MOV DX,OFFSET RESGROUP:PIPE2
|
||||
mov ah,createTempFile ; the CreateTemp call
|
||||
INT int_command
|
||||
JC PIPEERR
|
||||
MOV BX,AX
|
||||
MOV AH,CLOSE
|
||||
INT int_command
|
||||
|
||||
CALL TESTDOREIN ; Set up a redirection if specified
|
||||
MOV SI,[PIPEPTR]
|
||||
CMP [SINGLECOM],-1
|
||||
JNZ NOSINGP
|
||||
MOV [SINGLECOM],0F000H ; Flag single command pipe
|
||||
NOSINGP:
|
||||
JMP SHORT FIRSTPIPE
|
||||
|
||||
PIPEPROC:
|
||||
ASSUME DS:RESGROUP
|
||||
AND [ECHOFLAG],0FEh ; force current echo to be off
|
||||
MOV SI,[PIPEPTR]
|
||||
LODSB
|
||||
CMP AL,AltPipeChr ; Alternate pipe char?
|
||||
JZ IsPipe1 ; Yes
|
||||
CMP AL,vbar
|
||||
jz IsPipe1
|
||||
jmp PIPEEND ; Pipe done
|
||||
IsPipe1:
|
||||
MOV DX,[INPIPEPTR] ; Get the input file name
|
||||
MOV AX,(OPEN SHL 8)
|
||||
INT int_command
|
||||
PIPEERRJ:
|
||||
jnc no_pipeerr
|
||||
JMP PIPEERR ; Lost the pipe file
|
||||
no_pipeerr:
|
||||
MOV BX,AX
|
||||
MOV AL,0FFH
|
||||
XCHG AL,[BX.PDB_JFN_Table]
|
||||
MOV DS:[PDB_JFN_Table],AL ; Redirect
|
||||
|
||||
FIRSTPIPE:
|
||||
MOV DI,OFFSET TRANGROUP:COMBUF + 2
|
||||
XOR CX,CX
|
||||
CMP BYTE PTR [SI],0DH ; '|<CR>'
|
||||
JNZ PIPEOK1
|
||||
PIPEERRSYNJ:
|
||||
JMP PIPEERRSYN
|
||||
PIPEOK1:
|
||||
mov al,vbar
|
||||
CMP BYTE PTR [SI],al ; '||'
|
||||
JZ PIPEERRSYNJ
|
||||
CMP BYTE PTR [SI],AltPipeChr ; '##' or '|#'?
|
||||
JZ PipeErrSynJ ; Yes, Error
|
||||
PIPECOMLP:
|
||||
LODSB
|
||||
STOSB
|
||||
|
||||
;;;; IF KANJI 3/3/KK
|
||||
CALL TESTKANJ
|
||||
JZ NOTKANJ5
|
||||
MOVSB
|
||||
;
|
||||
; Added following 2 commands to the fix pipe bug.
|
||||
;
|
||||
inc cx ;AN000; 3/3/KK
|
||||
inc cx ;AN000; 3/3/KK
|
||||
;
|
||||
JMP PIPECOMLP
|
||||
|
||||
NOTKANJ5:
|
||||
;;;; ENDIF ; 3/3/KK
|
||||
|
||||
CMP AL,0DH
|
||||
JZ LASTPIPE
|
||||
INC CX
|
||||
CMP AL,AltPipeChr
|
||||
JZ IsPipe2
|
||||
CMP AL,vbar
|
||||
JNZ PIPECOMLP
|
||||
IsPipe2:
|
||||
MOV BYTE PTR ES:[DI-1],0DH
|
||||
DEC CX
|
||||
MOV [COMBUF+1],CL
|
||||
DEC SI
|
||||
MOV [PIPEPTR],SI ; On to next pipe element
|
||||
MOV DX,[OUTPIPEPTR]
|
||||
PUSH CX
|
||||
XOR CX,CX
|
||||
MOV AX,(CREAT SHL 8)
|
||||
INT int_command
|
||||
POP CX
|
||||
JC PIPEERRJ ; Lost the file
|
||||
MOV BX,AX
|
||||
MOV AL,0FFH
|
||||
XCHG AL,[BX.PDB_JFN_Table]
|
||||
MOV DS:[PDB_JFN_Table+1],AL
|
||||
XCHG DX,[INPIPEPTR] ; Swap for next element of pipe
|
||||
MOV [OUTPIPEPTR],DX
|
||||
JMP SHORT PIPECOM
|
||||
|
||||
LASTPIPE:
|
||||
MOV [COMBUF+1],CL
|
||||
DEC SI
|
||||
MOV [PIPEPTR],SI ; Point at the CR (anything not '|' will do)
|
||||
CALL TESTDOREOUT ; Set up the redirection if specified
|
||||
PIPECOM:
|
||||
PUSH CS
|
||||
POP DS
|
||||
JMP NOPIPEPROC ; Process the pipe element
|
||||
|
||||
PIPEEND:
|
||||
CALL PIPEDEL
|
||||
CMP [SINGLECOM],0F000H
|
||||
JNZ NOSINGP2
|
||||
MOV [SINGLECOM],-1 ; Make it return
|
||||
NOSINGP2:
|
||||
JMP TCOMMAND
|
||||
|
||||
ASSUME DS:TRANGROUP,ES:TRANGROUP
|
||||
|
||||
; Date and time are set during initialization and use
|
||||
; this routines since they need to do a long return
|
||||
|
||||
DATINIT PROC FAR
|
||||
mov cs:[resseg],ds ; SetInitFlag needs resseg initialized
|
||||
PUSH ES
|
||||
PUSH DS ; Going to use the previous stack
|
||||
MOV AX,CS ; Set up the appropriate segment registers
|
||||
MOV ES,AX
|
||||
MOV DS,AX
|
||||
invoke TSYSLOADMSG ;AN000; preload messages
|
||||
invoke SETSTDINON ;AN026; turn on critical error on STDIN
|
||||
invoke SETSTDOUTOFF ;AN026; turn off critical error on STDOUT
|
||||
MOV DX,OFFSET TRANGROUP:INTERNATVARS;Set up internat vars
|
||||
MOV AX,INTERNATIONAL SHL 8
|
||||
INT 21H
|
||||
MOV WORD PTR DS:[81H],13 ; Want to prompt for date during initialization
|
||||
MOV [COMBUF],COMBUFLEN ; Init COMBUF
|
||||
MOV WORD PTR [COMBUF+1],0D01H
|
||||
CALL DATE
|
||||
CALL CTIME
|
||||
POP DS
|
||||
POP ES
|
||||
RET
|
||||
DATINIT ENDP
|
||||
|
||||
; DATE - Gets and sets the time
|
||||
|
||||
|
||||
break Date
|
||||
|
||||
|
||||
; ****************************************************************
|
||||
; *
|
||||
; * ROUTINE: DATE - Set system date
|
||||
; *
|
||||
; * FUNCTION: If a date is specified, set the system date,
|
||||
; * otherwise display the current system date and
|
||||
; * prompt the user for a new date. If an invalid
|
||||
; * date is specified, issue an error message and
|
||||
; * prompt for a new date. If the user enters
|
||||
; * nothing when prompted for a date, terminate.
|
||||
; *
|
||||
; * INPUT: command line at offset 81H
|
||||
; *
|
||||
; * OUTPUT: none
|
||||
; *
|
||||
; ****************************************************************
|
||||
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
DATE:
|
||||
MOV SI,81H ; Accepting argument for date inline
|
||||
mov di,offset trangroup:parse_date ;AN000; Get adderss of PARSE_DATE
|
||||
xor cx,cx ;AN000; clear counter for positionals
|
||||
xor dx,dx ;AN000;
|
||||
invoke cmd_parse ;AC000; call parser
|
||||
cmp ax,end_of_line ;AC000; are we at end of line?
|
||||
JZ PRMTDAT ;AC000; yes - go ask for date
|
||||
cmp ax,result_no_error ;AN000; did we have an error?
|
||||
jne daterr ;AN000; yes - go issue message
|
||||
JMP COMDAT ;AC000; we have a date
|
||||
|
||||
PRMTDAT:
|
||||
; Print "Current date is
|
||||
|
||||
invoke GetDate ;AN000; get date for output
|
||||
xchg dh,dl ;AN000; switch month & day
|
||||
mov CurDat_yr,cx ;AC000; put year into message control block
|
||||
mov CurDat_mo_day,dx ;AC000; put month and day into message control block
|
||||
mov dx,offset trangroup:CurDat_ptr ;AC000; set up message for output
|
||||
invoke std_printf
|
||||
;AD061; mov CurDat_yr,0 ;AC000; reset year, month and day
|
||||
;AD061; mov CurDat_mo_day,0 ;AC000; pointers in control block
|
||||
|
||||
GET_NEW_DATE: ;AN000;
|
||||
call getdat ;AC000; prompt user for date
|
||||
cmp ax,end_of_line ;AC000; are we at end of line?
|
||||
jz date_end ;AC000; yes - exit
|
||||
cmp ax,result_no_error ;AN000; did we have an error?
|
||||
jne daterr ;AN000; yes - go issue message
|
||||
COMDAT:
|
||||
mov cx,date_year ;AC000; get parts of date in
|
||||
mov dh,date_month ;AC000; cx and dx for set
|
||||
mov dl,date_day ;AC000; date function call.
|
||||
push cx ;AC000; save date
|
||||
push dx ;AC000;
|
||||
mov cx,1 ;AC000; set 1 positional entered
|
||||
xor dx,dx ;AN029;
|
||||
invoke cmd_parse ;AN029; call parser
|
||||
cmp al,end_of_line ;AN029; Are we at end of line?
|
||||
pop dx ;AC000; retrieve date
|
||||
pop cx ;AC000;
|
||||
jnz daterr ;AC000; extra stuff on line - try again
|
||||
MOV AH,SET_DATE ;yes - set date
|
||||
INT int_command
|
||||
OR AL,AL
|
||||
JNZ DATERR
|
||||
date_end:
|
||||
ret
|
||||
|
||||
DATERR:
|
||||
invoke crlf2 ;AN028; print out a blank line
|
||||
MOV DX,OFFSET TRANGROUP:BADDAT_ptr
|
||||
invoke std_printf
|
||||
JMP GET_NEW_DATE ;AC000; get date again
|
||||
|
||||
|
||||
; TIME gets and sets the time
|
||||
|
||||
break Time
|
||||
|
||||
; ****************************************************************
|
||||
; *
|
||||
; * ROUTINE: TIME - Set system time
|
||||
; *
|
||||
; * FUNCTION: If a time is specified, set the system time,
|
||||
; * otherwise display the current system time and
|
||||
; * prompt the user for a new time. If an invalid
|
||||
; * time is specified, issue an error message and
|
||||
; * prompt for a new time. If the user enters
|
||||
; * nothing when prompted for a time, terminate.
|
||||
; *
|
||||
; * INPUT: command line at offset 81H
|
||||
; *
|
||||
; * OUTPUT: none
|
||||
; *
|
||||
; ****************************************************************
|
||||
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
CTIME:
|
||||
MOV SI,81H ; Accepting argument for time inline
|
||||
mov di,offset trangroup:parse_time ;AN000; Get adderss of PARSE_time
|
||||
xor cx,cx ;AN000; clear counter for positionals
|
||||
xor dx,dx ;AN000;
|
||||
invoke cmd_parse ;AC000; call parser
|
||||
cmp ax,end_of_line ;AC000; are we at end of line?
|
||||
JZ PRMTTIM ;AC000; yes - prompt for time
|
||||
cmp ax,result_no_error ;AN000; did we have an error?
|
||||
jne timerr ;AN000; yes - go issue message
|
||||
JMP COMTIM ;AC000; we have a time
|
||||
|
||||
PRMTTIM:
|
||||
;Printf "Current time is ... "
|
||||
|
||||
MOV AH,GET_TIME ;AC000; get the current time
|
||||
INT int_command ;AC000; Get time in CX:DX
|
||||
xchg ch,cl ;AN000; switch hours & minutes
|
||||
xchg dh,dl ;AN000; switch seconds & hundredths
|
||||
mov CurTim_hr_min,cx ;AC000; put hours and minutes into message subst block
|
||||
mov CurTim_sec_hn,dx ;AC000; put seconds and hundredths into message subst block
|
||||
mov dx,offset trangroup:CurTim_ptr ;AC000; set up message for output
|
||||
invoke std_printf
|
||||
;AD061; mov CurTim_hr_min,0 ;AC000; reset hour, minutes, seconds, and hundredths
|
||||
;AD061; mov CurTim_sec_hn,0 ;AC000; pointers in control block
|
||||
|
||||
GET_NEW_TIME:
|
||||
call gettim ;AC000;
|
||||
cmp ax,end_of_line ;AC000; are we at end of line?
|
||||
jz time_end ;AC000;
|
||||
cmp ax,result_no_error ;AN000; did we have an error?
|
||||
jne timerr ;AN000; yes - go issue message
|
||||
|
||||
COMTIM:
|
||||
mov ch,time_hour ;AC000; get parts of time in
|
||||
mov cl,time_minutes ;AC000; cx and dx for set
|
||||
mov dh,time_seconds ;AC000; time function call
|
||||
mov dl,time_fraction ;AC000;
|
||||
push cx ;AC000; save time
|
||||
push dx ;AC000;
|
||||
mov cx,1 ;AC000; set 1 positional parm entered
|
||||
xor dx,dx ;AN029;
|
||||
invoke cmd_parse ;AN029; call parser
|
||||
cmp al,end_of_line ;AN029; Are we at end of line?
|
||||
pop dx ;AC000; retieve time
|
||||
pop cx ;AC000;
|
||||
jnz timerr ;AC000; extra stuff on line - try again
|
||||
|
||||
SAVTIM:
|
||||
MOV AH,SET_TIME
|
||||
INT int_command
|
||||
OR AL,AL
|
||||
JNZ TIMERR ;AC000; if an error occured, try again
|
||||
|
||||
TIME_END:
|
||||
|
||||
ret
|
||||
|
||||
TIMERR:
|
||||
invoke crlf2 ;AN028; print out a blank line
|
||||
MOV DX,OFFSET TRANGROUP:BADTIM_ptr
|
||||
invoke std_printf ; Print error message
|
||||
JMP GET_NEW_TIME ;AC000; Try again
|
||||
|
||||
|
||||
;
|
||||
; Set the special flag in the INIT flag to the value in CX.
|
||||
;
|
||||
SetInitFlag:
|
||||
mov ds,[RESSEG]
|
||||
assume ds:resgroup
|
||||
and InitFlag,NOT initSpecial
|
||||
or InitFlag,cL
|
||||
push cs
|
||||
pop ds
|
||||
return
|
||||
|
||||
Public PipeOff
|
||||
PipeOff:
|
||||
ASSUME DS:NOTHING,ES:NOTHING
|
||||
SaveReg <DS,AX>
|
||||
MOV DS,ResSeg
|
||||
ASSUME DS:RESGroup
|
||||
XOR AL,AL
|
||||
XCHG PipeFlag,AL
|
||||
OR AL,AL
|
||||
JZ PipeOffDone
|
||||
SHR EchoFlag,1
|
||||
PipeOffDone:
|
||||
RestoreReg <AX,DS>
|
||||
return
|
||||
|
||||
|
||||
PRINT_TIME:
|
||||
|
||||
MOV AH,GET_TIME
|
||||
INT int_command ; Get time in CX:DX
|
||||
|
||||
PUSH ES
|
||||
PUSH CS
|
||||
POP ES
|
||||
xchg ch,cl ;AN000; switch hours & minutes
|
||||
xchg dh,dl ;AN000; switch seconds & hundredths
|
||||
mov promTim_hr_min,cx ;AC000; put hours and minutes into message subst block
|
||||
mov promTim_sec_hn,dx ;AC000; put seconds and hundredths into message subst block
|
||||
mov dx,offset trangroup:promTim_ptr ;AC000; set up message for output
|
||||
invoke std_printf
|
||||
;AD061; mov promTim_hr_min,0 ;AC000; reset hour, minutes, seconds, and hundredths
|
||||
;AD061; mov promTim_sec_hn,0 ;AC000; pointers in control block
|
||||
|
||||
POP ES
|
||||
return
|
||||
|
||||
|
||||
; ****************************************************************
|
||||
; *
|
||||
; * ROUTINE: GETDAT - Prompt user for date
|
||||
; *
|
||||
; * FUNCTION: Gets the date format from the COUNTRY DEPENDENT
|
||||
; * INFORMATION and issues the "Enter new date"
|
||||
; * message with the proper date format. COMBUF
|
||||
; * is reset to get a date from the command line.
|
||||
; * The PARSE_DATE blocks are then reset and the
|
||||
; * PARSE function call is issued.
|
||||
; *
|
||||
; * INPUT: NONE
|
||||
; *
|
||||
; * OUTPUT: COMBUF
|
||||
; * PARSER RETURN CODES
|
||||
; *
|
||||
; ****************************************************************
|
||||
|
||||
|
||||
GETDAT proc near ;AC000;
|
||||
|
||||
mov ax,(International SHL 8) ; Determine what format the date
|
||||
mov dx,5ch ; should be entered in and
|
||||
int int_command ; print a message describing it
|
||||
mov si,dx
|
||||
lodsw
|
||||
mov dx,usadat_ptr ;AC000; get mm-dd-yy
|
||||
dec ax
|
||||
js printformat
|
||||
mov dx,eurdat_ptr ;AC000; get dd-mm-yy
|
||||
jz printformat
|
||||
mov dx,japdat_ptr ;AC000; get yy-mm-dd
|
||||
printformat:
|
||||
mov ax,dx ;AN000; get message number of format
|
||||
mov dh,util_msg_class ;AN000; this is a utility message
|
||||
call Tsysgetmsg ;AN000; get the address of the message
|
||||
mov newdat_format,si ;AN000; put the address in subst block
|
||||
MOV DX,OFFSET TRANGROUP:NEWDAT_ptr ;AC000; get address of message to print
|
||||
invoke std_printf
|
||||
mov newdat_format,no_subst ;AN000; reset subst block
|
||||
|
||||
MOV AH,STD_CON_STRING_INPUT
|
||||
MOV DX,OFFSET TRANGROUP:COMBUF
|
||||
mov cx,initSpecial ; Set bit in InitFlag that indicates
|
||||
call SetInitFlag ; prompting for date.
|
||||
INT int_command ; Get input line
|
||||
xor cx,cx ; Reset bit in InitFlag that indicates
|
||||
call SetInitFlag ; prompting for date.
|
||||
invoke CRLF2
|
||||
MOV SI,OFFSET TRANGROUP:COMBUF+2
|
||||
mov di,offset trangroup:parse_date ;AN000; Get adderss of PARSE_DATE
|
||||
xor cx,cx ;AN000; clear counter for positionals
|
||||
xor dx,dx ;AN000;
|
||||
invoke cmd_parse ;AC000; call parser
|
||||
|
||||
ret
|
||||
|
||||
GETDAT endp ;AC000;
|
||||
|
||||
|
||||
; ****************************************************************
|
||||
; *
|
||||
; * ROUTINE: GETTIME - Prompt user for time
|
||||
; *
|
||||
; * FUNCTION: Gets the time format from the COUNTRY DEPENDENT
|
||||
; * INFORMATION and issues the "Enter new time"
|
||||
; * message. COMBUF is reset to get a time from the
|
||||
; * command line. The PARSE_TIME blocks are then
|
||||
; * reset and the PARSE function call is issued.
|
||||
; *
|
||||
; * INPUT: NONE
|
||||
; *
|
||||
; * OUTPUT: COMBUF
|
||||
; * PARSER RETURN CODES
|
||||
; *
|
||||
; ****************************************************************
|
||||
|
||||
|
||||
GETTIM proc near ;AC000;
|
||||
|
||||
XOR CX,CX ; Initialize hours and minutes to zero
|
||||
MOV DX,OFFSET TRANGROUP:NEWTIM_ptr
|
||||
invoke std_printf
|
||||
MOV AH,STD_CON_STRING_INPUT
|
||||
MOV DX,OFFSET TRANGROUP:COMBUF
|
||||
mov cx,initSpecial ; Set bit in InitFlag that indicates
|
||||
call SetInitFlag ; prompting for time.
|
||||
INT int_command ; Get input line
|
||||
xor cx,cx ; Reset bit in InitFlag that indicates
|
||||
call SetInitFlag ; prompting for time.
|
||||
invoke CRLF2
|
||||
MOV SI,OFFSET TRANGROUP:COMBUF+2
|
||||
mov di,offset trangroup:parse_time ;AN000; Get adderss of PARSE_TIME
|
||||
xor cx,cx ;AN000; clear counter for positionals
|
||||
xor dx,dx ;AN000;
|
||||
invoke cmd_parse ;AC000; call parser
|
||||
|
||||
ret
|
||||
|
||||
GETTIM endp ;AC000;
|
||||
|
||||
TRANCODE ENDS
|
||||
END
|
||||
365
v4.0/src/CMD/COMMAND/TPRINTF.ASM
Normal file
365
v4.0/src/CMD/COMMAND/TPRINTF.ASM
Normal file
@@ -0,0 +1,365 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)tprintf.asm 4.3 85/07/02
|
||||
; SCCSID = @(#)tprintf.asm 4.3 85/07/02
|
||||
TITLE COMMAND Transient Printf routine
|
||||
|
||||
;****************************************************************
|
||||
;*
|
||||
;* ROUTINE: STD_PRINTF/STD_EPRINTF
|
||||
;*
|
||||
;* FUNCTION: Set up to print out a message using SYSDISPMSG.
|
||||
;* Set up substitutions if utility message. Make
|
||||
;* sure any changes to message variables in TDATA
|
||||
;* are reset to avoid reloading the transient.
|
||||
;*
|
||||
;* INPUT: Msg_Disp_Class - set to message class
|
||||
;* Msg_Cont_Flag - set to control flags
|
||||
;* DS points to transient segment
|
||||
;*
|
||||
;* if utility message:
|
||||
;* DX points to a block with message number
|
||||
;* (word), number of substitutions (byte),
|
||||
;* followed by substitution list if there
|
||||
;* are substitutions. If substitutions
|
||||
;* are not in transient segment they must
|
||||
;* be set.
|
||||
;* else
|
||||
;* AX set to message number
|
||||
;*
|
||||
;* OUTPUT: none
|
||||
;*
|
||||
;****************************************************************
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE comsw.asm ;AC000;
|
||||
INCLUDE DOSSYM.INC
|
||||
INCLUDE comseg.asm
|
||||
INCLUDE comequ.asm ;AN000;
|
||||
INCLUDE SYSMSG.INC ;AN000;
|
||||
.list
|
||||
.cref
|
||||
|
||||
datares segment public
|
||||
extrn pipeflag:byte
|
||||
datares ends
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN extend_buf_off:word ;AN000;
|
||||
EXTRN Extend_Buf_ptr:word ;AN000;
|
||||
EXTRN Extend_Buf_seg:word ;AN000;
|
||||
EXTRN Msg_Cont_Flag:byte ;AN000;
|
||||
EXTRN Msg_disp_Class:byte ;AN000;
|
||||
EXTRN pipeemes_ptr:word
|
||||
TRANDATA ENDS
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN msg_flag:byte ;AN022;
|
||||
EXTRN print_err_flag:word ;AN000;
|
||||
EXTRN RESSEG:WORD
|
||||
EXTRN String_ptr_2:word ;AC000;
|
||||
EXTRN Subst_buffer:byte ;AN061;
|
||||
;AD061; EXTRN String_ptr_2_sb:word ;AN000;
|
||||
|
||||
; include data area for message services
|
||||
|
||||
MSG_UTILNAME <COMMAND> ;AN000; define utility name
|
||||
|
||||
MSG_SERVICES <MSGDATA> ;AN000;
|
||||
|
||||
PRINTF_HANDLE DW ? ;AC000;
|
||||
|
||||
TRANSPACE ENDS ;AC000;
|
||||
|
||||
TRANCODE SEGMENT PUBLIC BYTE ;AC000;
|
||||
|
||||
EXTRN cerror:near
|
||||
EXTRN crlf2:near
|
||||
EXTRN tcommand:near ;AN026;
|
||||
|
||||
ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:NOTHING,SS:NOTHING ;AC000;
|
||||
|
||||
PUBLIC SETSTDINOFF ;AN026;
|
||||
PUBLIC SETSTDINON ;AN026;
|
||||
PUBLIC SETSTDOUTOFF ;AN026;
|
||||
PUBLIC SETSTDOUTON ;AN026;
|
||||
PUBLIC TSYSGETMSG ;AN000;
|
||||
PUBLIC TSYSLOADMSG ;AN000;
|
||||
|
||||
PUBLIC Printf_Init
|
||||
printf_init proc far
|
||||
call std_printf
|
||||
ret
|
||||
printf_init endp
|
||||
|
||||
Public Printf_Crlf
|
||||
PRINTF_CRLF:
|
||||
CALL STD_PRINTF
|
||||
CALL CRLF2
|
||||
RET
|
||||
|
||||
PUBLIC Std_EPrintf
|
||||
STD_EPRINTF:
|
||||
mov Printf_Handle,2 ;AC000;Print to STDERR
|
||||
jmp short NEW_PRINTF ;AC000;
|
||||
PUBLIC Std_Printf
|
||||
STD_PRINTF:
|
||||
mov Printf_Handle,1 ;AC000;Print to STDOUT
|
||||
|
||||
NEW_PRINTF:
|
||||
push ax ;AN000;save registers
|
||||
push bx ;AN000;
|
||||
push cx ;AN000;
|
||||
push es ;AN000;get local ES
|
||||
push ds ;AN000;
|
||||
pop es ;AN000;
|
||||
push di ;AN000;
|
||||
push si ;AN000;
|
||||
push dx ;AN000;
|
||||
assume es:trangroup ;AN000;
|
||||
;AD061; mov string_ptr_2_sb,0 ;AN000;initialize
|
||||
mov print_err_flag,0 ;AN000;
|
||||
|
||||
UTILITY_SETUP:
|
||||
mov si,dx ;AN000;Get offset of message number
|
||||
lodsw ;AN000;load message number
|
||||
push ax ;AN000;save it
|
||||
lodsb ;AN000;get number of substitutions
|
||||
mov cl,al ;AN000;set up CX as # of subst
|
||||
xor ch,ch ;AN000; SI now points to subst list
|
||||
pop ax ;AN000;get message number back
|
||||
cmp cx,0 ;AN000;Any substitutions?
|
||||
jz READY_TO_PRINT ;AN000;No - continue
|
||||
|
||||
;AD061; add dx,Ptr_Seg_Pos ;AN000;Point to position of first segment
|
||||
;AD061; push cx ;AN000;save substitution count
|
||||
|
||||
;AD061;SET_SUBST:
|
||||
;AD061; mov bx,dx ;AN000;get dx into base register
|
||||
;AD061; cmp word ptr [bx],0 ;AN000;has segment been set?
|
||||
;AD061; jnz SUBST_SEG_SET ;AN000;if not 0, don't replace it
|
||||
;AD061; test word ptr [bx+3],date_type ;AN000;if date or time - don't set segment
|
||||
;AD061; jnz subst_seg_set ;AN000;yes - skip it
|
||||
;AD061; mov word ptr [bx],cs ;AN000;put segment of subst parm in list
|
||||
|
||||
;AD061;SUBST_SEG_SET:
|
||||
;AD061; add dx,Parm_Block_Size ;AN000;point to position of next segment
|
||||
;AD061; loop SET_SUBST ;AN000;keep replacing until complete
|
||||
;AD061; pop cx ;AN000;
|
||||
|
||||
;AD061;NO_REPLACEMENT:
|
||||
;AD061; mov bx,parm_off_pos [si] ;AN000;get subst offset
|
||||
;AD061; cmp bx,offset trangroup:string_ptr_2 ;AN000;this is used for double indirection
|
||||
;AD061; jnz ready_to_print ;AN000;we already have address
|
||||
;AD061; mov dx,string_ptr_2 ;AN000;get address in string_ptr_2
|
||||
;AD061; mov parm_off_pos [si],dx ;AN000;put proper address in table
|
||||
;AD061; mov string_ptr_2_sb,si ;AN000;save block changed
|
||||
|
||||
mov di,offset trangroup:subst_buffer;AN061; Get address of message subst buffer
|
||||
push di ;AN061; save it
|
||||
push cx ;AN061; save number of subst
|
||||
|
||||
MOVE_SUBST:
|
||||
push cx ;AN061;save number of subst
|
||||
mov bx,si ;AN061;save start of sublist
|
||||
mov cx,parm_block_size ;AN061;get size of sublist
|
||||
rep movsb ;AN061;move sublist
|
||||
test byte ptr [bx.$M_S_FLAG],date_type ;AN061;are we doing date/time?
|
||||
jz move_subst_cont ;AN061;no - no need to reset
|
||||
mov word ptr [bx.$M_S_VALUE],0 ;AN061;reset original date or time to 0
|
||||
mov word ptr [bx.$M_S_VALUE+2],0 ;AN061;
|
||||
|
||||
MOVE_SUBST_CONT: ;AN061;
|
||||
pop cx ;AN061;get number of subst back
|
||||
loop move_subst ;AN061;move cx sublists
|
||||
|
||||
pop cx ;AN061;get number of subst
|
||||
push ax ;AN061;save message number
|
||||
cmp Msg_Disp_Class,Util_Msg_Class ;AN061;Is this a utility message
|
||||
jz CHECK_FIX ;AN061;YES - go see if substitutions
|
||||
mov msg_flag,ext_msg_class ;AN061;set message flag
|
||||
mov di,offset trangroup:extend_buf_ptr ;AN061; Get address of extended message block
|
||||
xor ax,ax ;AN061;clear ax register
|
||||
stosw ;AN061;clear out message number
|
||||
stosb ;AN061;clear out subst count
|
||||
|
||||
CHECK_FIX: ;AN061;
|
||||
pop ax ;AN061;get message number back
|
||||
pop di ;AN061;get start of sublists
|
||||
mov si,di ;AN061;get into SI for msgserv
|
||||
mov bx,si ;AN061;get into BX for addressing
|
||||
push cx ;AN061;save number of subst
|
||||
|
||||
SET_SUBST: ;AN061;store the segment of the subst
|
||||
cmp word ptr [bx.$M_S_VALUE+2],0 ;AN061;was it set already?
|
||||
jnz subst_seg_set ;AN061;if not 0, don't replace it
|
||||
test byte ptr [bx.$M_S_FLAG],date_type ;AN061;don't replace if date or time
|
||||
jnz subst_seg_set ;AN061;yes - skip it
|
||||
mov word ptr [bx.$M_S_VALUE+2],cs ;AN061;set segment value
|
||||
|
||||
SUBST_SEG_SET: ;AN061;
|
||||
add bx,parm_block_size ;AN061;go to next sublist
|
||||
loop set_subst ;AN061;loop CX times
|
||||
pop cx ;AN061;get number of subst back
|
||||
|
||||
mov bx,si ;AN061;get start of sublist to BX
|
||||
cmp word ptr [bx.$M_S_VALUE],offset trangroup:string_ptr_2 ;AN061;are we using double indirection?
|
||||
jnz ready_to_print ;AN061;no - we already have address
|
||||
mov dx,string_ptr_2 ;AN061;get address in string_ptr_2
|
||||
mov word ptr [bx.$M_S_VALUE],dx ;AN061;put it into the subst block
|
||||
|
||||
READY_TO_PRINT:
|
||||
mov bx,Printf_Handle ;AN000;get print handle
|
||||
mov dl,Msg_Cont_Flag ;AN000;set up control flag
|
||||
mov dh,Msg_Disp_Class ;AN000;set up display class
|
||||
mov Msg_Cont_Flag,No_Cont_Flag ;AN061;reset flags to avoid
|
||||
mov Msg_Disp_Class,Util_Msg_Class ;AN061; transient reload
|
||||
|
||||
;AD061; push bx ;AN026; save registers
|
||||
;AD061; push cx ;AN026;
|
||||
;AD061; push dx ;AN026;
|
||||
;AD061; push si ;AN026;
|
||||
;AD061; push di ;AN026;
|
||||
push ds ;AN026;
|
||||
push es ;AN026;
|
||||
|
||||
|
||||
call SYSDISPMSG ;AN000;call Rod
|
||||
|
||||
pop es ;AN026; restore registers
|
||||
pop ds ;AN026;
|
||||
;AD061; pop di ;AN026;
|
||||
;AD061; pop si ;AN026;
|
||||
;AD061; pop dx ;AN026;
|
||||
;AD061; pop cx ;AN026;
|
||||
;AD061; pop bx ;AN026;
|
||||
|
||||
jnc Print_success ;AN000; everything went okay
|
||||
mov print_err_flag,ax ;AN000;
|
||||
|
||||
print_success:
|
||||
;AD061; cmp Msg_Disp_Class,Util_Msg_Class ;AN000;Is this a utility message
|
||||
;AD061; jz CHECK_FIX ;AN000;YES - go see if substitutions
|
||||
;AD061; mov msg_flag,ext_msg_class ;AN022;set message flag
|
||||
;AD061; mov di,offset trangroup:extend_buf_ptr ;AN000; Get address of extended message block
|
||||
;AD061; xor ax,ax ;AN000;clear ax register
|
||||
;AD061; stosw ;AN000;clear out message number
|
||||
;AD061; stosb ;AN000;clear out subst count
|
||||
|
||||
;AD061; CHECK_FIX:
|
||||
;AD061; pop dx ;AN000;restore dx
|
||||
;AD061; cmp cx,0 ;AN000;Any substitutions?
|
||||
;AD061; jz NO_FIXUP ;AN000;No - leave
|
||||
|
||||
;AD061; mov si,dx ;AN000;Reset changes so transient won't reload
|
||||
;AD061; add si,Ptr_Seg_Pos ;AN000;Point to position of first segment
|
||||
|
||||
;AD061;FIX_SUBST:
|
||||
;AD061; mov word ptr [si],0 ;AN000;reset segment to 0
|
||||
;AD061; add si,Parm_Block_Size ;AN000;point to position of next segment
|
||||
;AD061; loop FIX_SUBST ;AN000;keep replacing until complete
|
||||
;AD061; cmp string_ptr_2_sb,no_subst ;AN000;was double indirection used?
|
||||
;AD061; jz no_fixup ;AN000;no - we're finished
|
||||
;AD061; mov si,string_ptr_2_sb ;AN000;get offset changed
|
||||
;AD061; mov parm_off_pos [si],offset trangroup:string_ptr_2 ;AN000; set address back to string_ptr_2
|
||||
|
||||
;AD061;NO_FIXUP:
|
||||
;AD061; mov Msg_Cont_Flag,No_Cont_Flag ;AN000;reset flags to avoid
|
||||
;AD061; mov Msg_Disp_Class,Util_Msg_Class ;AN000; transient reload
|
||||
pop dx ;AN061;restore dx
|
||||
pop si ;AN000;restore registers
|
||||
pop di ;AN000;
|
||||
pop es ;AN000;restore registers
|
||||
pop cx ;AN000;
|
||||
pop bx ;AN000;
|
||||
pop ax ;AN000;
|
||||
cmp print_err_flag,0 ;AN000; if an error occurred - handle it
|
||||
jnz print_err ;AN000;
|
||||
|
||||
ret ;AC000;
|
||||
|
||||
print_err:
|
||||
push cs
|
||||
pop es
|
||||
cmp Printf_Handle,2 ;AN026;Print to STDERR?
|
||||
jnz not_stderr ;AN026;no - continue
|
||||
jmp tcommand ;AN026;Yes - hopless - just exit
|
||||
|
||||
not_stderr:
|
||||
mov ax,print_err_flag ;AN026;get extended error number back
|
||||
mov es,[resseg] ; No, set up for error, load the
|
||||
assume es:resgroup ; right error msg, and jmp to cerror.
|
||||
test PipeFlag,-1
|
||||
jz go_to_error
|
||||
invoke PipeOff
|
||||
mov dx,offset trangroup:pipeemes_ptr
|
||||
jmp print_err_exit ;AC000;
|
||||
|
||||
go_to_error:
|
||||
mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class
|
||||
mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
|
||||
mov Extend_Buf_ptr,ax ;AN000; get message number in control block
|
||||
|
||||
PRINT_ERR_EXIT: ;AC000;
|
||||
push cs
|
||||
pop es
|
||||
JMP CERROR
|
||||
|
||||
;****************************************************************
|
||||
;*
|
||||
;* ROUTINE: TSYSLOADMSG
|
||||
;*
|
||||
;* FUNCTION: Interface to call SYSLOADMSG to avoid duplicate
|
||||
;* names since these routines are also used in the
|
||||
;* resident.
|
||||
;*
|
||||
;* INPUT: Inputs to SYSLOADMSG
|
||||
;*
|
||||
;* OUTPUT: Outputs from SYSLOADMSG
|
||||
;*
|
||||
;****************************************************************
|
||||
|
||||
|
||||
TSYSLOADMSG PROC NEAR ;AN000;
|
||||
|
||||
push bx ;AN000;
|
||||
call sysloadmsg ;AN000; call routine
|
||||
pop bx ;AN000;
|
||||
ret ;AN000; exit
|
||||
|
||||
TSYSLOADMSG ENDP ;AN000;
|
||||
|
||||
;****************************************************************
|
||||
;*
|
||||
;* ROUTINE: TSYSGETMSG
|
||||
;*
|
||||
;* FUNCTION: Interface to call SYSGETMSG to avoid duplicate
|
||||
;* names since these routines are also used in the
|
||||
;* resident.
|
||||
;*
|
||||
;* INPUT: Inputs to SYSGETMSG
|
||||
;*
|
||||
;* OUTPUT: Outputs from SYSGETMSG
|
||||
;*
|
||||
;****************************************************************
|
||||
|
||||
|
||||
TSYSGETMSG PROC NEAR ;AN000;
|
||||
|
||||
push cx ;AN000;
|
||||
call sysgetmsg ;AN000; call routine
|
||||
pop cx ;AN000;
|
||||
ret ;AN000; exit
|
||||
|
||||
TSYSGETMSG ENDP ;AN000;
|
||||
|
||||
MSG_SERVICES <COMT,NOVERCHECKmsg,NEARmsg,LOADmsg,NOCHECKSTDIN,NOCHECKSTDOUT,GETmsg> ;AC026; The message services
|
||||
MSG_SERVICES <COMT,NEARmsg,SETSTDIO,DISPLAYmsg,CHARmsg,NUMmsg,TIMEmsg,DATEmsg> ;AC026; The message services
|
||||
|
||||
PRINTF_LAST LABEL WORD
|
||||
|
||||
include msgdcl.inc
|
||||
|
||||
|
||||
TRANCODE ENDS
|
||||
END
|
||||
671
v4.0/src/CMD/COMMAND/TRANMSG.ASM
Normal file
671
v4.0/src/CMD/COMMAND/TRANMSG.ASM
Normal file
@@ -0,0 +1,671 @@
|
||||
|
||||
;****************************************************
|
||||
;* TRANSIENT MESSAGE POINTERS & SUBSTITUTION BLOCKS *
|
||||
;****************************************************
|
||||
|
||||
msg_disp_class db Util_msg_class
|
||||
msg_cont_flag db No_cont_flag
|
||||
|
||||
; extended error string output
|
||||
;
|
||||
Extend_Buf_ptr dw 0 ;AN000;set to no message
|
||||
Extend_Buf_sub db 0 ;AN000;set to no substitutions
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
Extend_Buf_off dw OFFSET TranGroup:String_ptr_2 ;AN000;offset of arg
|
||||
Extend_Buf_seg dw 0 ;AN000;segment of arg
|
||||
db 0 ;AN000;first subst
|
||||
db Char_field_ASCIIZ ;AN000;character string
|
||||
db 128 ;AN000;maximum width
|
||||
db 0 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
; "Duplicate file name or file not found"
|
||||
;
|
||||
Renerr_Ptr dw 1002 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Invalid path or file name"
|
||||
;
|
||||
BadCPMes_Ptr dw 1003 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Insufficient disk space"
|
||||
;
|
||||
NoSpace_Ptr dw 1004 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Out of environment space"
|
||||
;
|
||||
EnvErr_Ptr dw 1007 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "File creation error"
|
||||
;
|
||||
FulDir_Ptr dw 1008 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Batch file missing",13,10
|
||||
;
|
||||
BadBat_Ptr dw 1009 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Insert disk with batch file",13,10
|
||||
;
|
||||
NeedBat_Ptr dw 1010 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Bad command or file name",13,10
|
||||
;
|
||||
BadNam_Ptr dw 1011 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
|
||||
; "Access denied",13,10
|
||||
;
|
||||
AccDen_Ptr dw 1014 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "File cannot be copied onto itself",13,10
|
||||
;
|
||||
OverWr_Ptr dw 1015 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Content of destination lost before copy",13,10
|
||||
;
|
||||
LostErr_Ptr dw 1016 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Invalid filename or file not found",13,10
|
||||
;
|
||||
InOrNot_Ptr dw 1017 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "%1 File(s) copied",13,10
|
||||
;
|
||||
Copied_Ptr dw 1018 ;AN000;message number
|
||||
db 1 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET TranGroup:Copy_num ;AN000;offset of arg
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Right_Align+Unsgn_Bin_Word ;AN000;binary to decimal
|
||||
db 9 ;AN000;maximum width
|
||||
db 9 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
; "%1 File(s) "
|
||||
;
|
||||
DirMes_Ptr dw 1019 ;AN000;message number
|
||||
db 1 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET TranGroup:Dir_num ;AN000;offset of arg
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Right_Align+Unsgn_Bin_Word ;AN000;binary to decimal
|
||||
db 9 ;AN000;maximum width
|
||||
db 9 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
; "%1 bytes free",13,10
|
||||
;
|
||||
BytMes_Ptr dw 1020 ;AN000;message number
|
||||
db 1 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET TranGroup:Bytes_Free ;AN000;offset of arg
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Right_Align+Unsgn_Bin_DWord ;AN000;long binary to decimal
|
||||
db 10 ;AN000;maximum width
|
||||
db 10 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
; "Invalid drive specification",13,10
|
||||
;
|
||||
BadDrv_Ptr dw 1021 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
|
||||
; "Code page %1 not prepared for system",13,10
|
||||
;
|
||||
CP_not_set_Ptr dw 1022 ;AN000;message number
|
||||
db 1 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET TranGroup:System_cpage ;AN000;offset of arg
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Right_Align+Unsgn_Bin_Word ;AN000;binary to decimal
|
||||
db 5 ;AN000;maximum width
|
||||
db 1 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
; "Code page %1 not prepared for all devices",13,10
|
||||
;
|
||||
CP_not_all_Ptr dw 1023 ;AN000;message number
|
||||
db 1 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET TranGroup:System_cpage ;AN000;offset of arg
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Right_Align+Unsgn_Bin_Word ;AN000;binary to decimal
|
||||
db 5 ;AN000;maximum width
|
||||
db 1 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
; "Active code page: %1",13,10
|
||||
;
|
||||
CP_active_Ptr dw 1024 ;AN000;message number
|
||||
db 1 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET TranGroup:System_cpage ;AN000;offset of arg
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Right_Align+Unsgn_Bin_Word ;AN000;binary to decimal
|
||||
db 5 ;AN000;maximum width
|
||||
db 1 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
; "NLSFUNC not installed",13,10
|
||||
;
|
||||
NLSFUNC_Ptr dw 1025 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Invalid code page",13,10
|
||||
;
|
||||
Inv_Code_Page dw 1026 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Current drive is no longer valid"
|
||||
;
|
||||
BadCurDrv dw 1027 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Press any key to continue"
|
||||
;
|
||||
PauseMes_Ptr dw 1028 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Label not found",13,10
|
||||
;
|
||||
BadLab_Ptr dw 1029 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Syntax error",13,10
|
||||
;
|
||||
SyntMes_Ptr dw 1030 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Invalid date",13,10
|
||||
;
|
||||
BadDat_Ptr dw 1031 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Current date is %1 %2",13,10
|
||||
;
|
||||
CurDat_Ptr dw 1032 ;AN000;message number
|
||||
db 2 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET TranGroup:Arg_Buf ;AN000;offset of arg
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Char_field_ASCIIZ ;AN000;character string
|
||||
db 3 ;AN000;maximum width
|
||||
db 3 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
CurDat_yr dw 0 ;AN000;year
|
||||
CurDat_mo_day dw 0 ;AN000;month,day
|
||||
db 2 ;AN000;second subst
|
||||
db DATE_MDY_4 ;AN000;date
|
||||
db 10 ;AN000;maximum width
|
||||
db 10 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
|
||||
; "SunMonTueWedThuFriSat"
|
||||
;
|
||||
WeekTab dw 1033 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Enter new date (%1):"
|
||||
;
|
||||
NewDat_Ptr dw 1034 ;AN000;message number
|
||||
db 1 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
NewDat_Format dw 0 ;AN000;offset of replacement
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Char_field_ASCIIZ ;AN000;character string
|
||||
db 8 ;AN000;maximum width
|
||||
db 8 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
; "Invalid time",13,10
|
||||
;
|
||||
BadTim_Ptr dw 1035 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Current time is %1",13,10
|
||||
;
|
||||
CurTim_Ptr dw 1036 ;AN000;message number
|
||||
db 1 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
CurTim_hr_min dw 0 ;AN000;hours,minutes
|
||||
CurTim_Sec_hn dw 0 ;AN000;seconds,hundredths
|
||||
db 1 ;AN000;first subst
|
||||
db Right_Align+TIME_HHMMSSHH_Cty ;AC059;time
|
||||
db 12 ;AC059;maximum width
|
||||
db 12 ;AC059;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
; "Enter new time:"
|
||||
;
|
||||
NewTim_Ptr dw 1037 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; ", Delete (Y/N)?",13,10
|
||||
;
|
||||
Del_Y_N_Ptr dw 1038 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "All files in directory will be deleted!",13,10
|
||||
; "Are you sure (Y/N)?",13,10
|
||||
;
|
||||
SureMes_Ptr dw 1039 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Microsoft DOS Version %1.%2",13,10
|
||||
;
|
||||
VerMes_Ptr dw 1040 ;AN000;message number
|
||||
db 2 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET TranGroup:Major_Ver_Num ;AN000;offset of arg
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Right_Align+Unsgn_Bin_Word ;AN000;binary to decimal
|
||||
db 1 ;AN000;maximum width
|
||||
db 1 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET TranGroup:Minor_Ver_Num ;AN000;offset of arg
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 2 ;AN000;second subst
|
||||
db Unsgn_Bin_Word ;AN000;binary to decimal
|
||||
db 2 ;AN000;maximum width
|
||||
db 2 ;AN000;minimum width
|
||||
db "0" ;AN000;pad character
|
||||
|
||||
; "Volume in drive %1 has no label",13,10
|
||||
;
|
||||
VolMes_Ptr_2 dw 1041 ;AN000;message number
|
||||
db 1 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET TranGroup:vol_drv ;AN000;offset of drive
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Char_field_Char ;AN000;character
|
||||
db 128 ;AN000;maximum width
|
||||
db 1 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
; "Volume in drive %1 is %2",13,10
|
||||
;
|
||||
VolMes_Ptr dw 1042 ;AN000;message number
|
||||
db 2 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET TranGroup:vol_drv ;AN000;offset of drive
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db 00000000b ;AN000;character
|
||||
db 128 ;AN000;maximum width
|
||||
db 1 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET TranGroup:CHARBUF ;AN000;offset of string
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 2 ;AN000;second subst
|
||||
db Char_field_ASCIIZ ;AN000;character string
|
||||
db 128 ;AN000;maximum width
|
||||
db 1 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
; "Volume Serial Number is %1-%2",13,10
|
||||
;
|
||||
VolSerMes_Ptr dw 1043 ;AN000;message number
|
||||
db 2 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET TranGroup:vol_serial+2 ;AN000;offset of serial
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Right_Align+Bin_Hex_Word ;AN000;binary to hex
|
||||
db 4 ;AN000;maximum width
|
||||
db 4 ;AN000;minimum width
|
||||
db "0" ;AN000;pad character
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET TranGroup:vol_serial ;AN000;offset of serial
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 2 ;AN000;second subst
|
||||
db Right_Align+Bin_Hex_Word ;AN000;binary to hex
|
||||
db 4 ;AN000;maximum width
|
||||
db 4 ;AN000;minimum width
|
||||
db "0" ;AN000;pad character
|
||||
|
||||
; "Invalid directory",13,10
|
||||
;
|
||||
BadCD_Ptr dw 1044 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Unable to create directory",13,10
|
||||
;
|
||||
BadMkD_Ptr dw 1045 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Invalid path, not directory,",13,10
|
||||
; "or directory not empty",13,10
|
||||
;
|
||||
BadRmD_Ptr dw 1046 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Must specify ON or OFF",13,10
|
||||
;
|
||||
Bad_ON_OFF_Ptr dw 1047 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Directory of %1",13,10
|
||||
;
|
||||
DirHead_Ptr dw 1048 ;AN000;message number
|
||||
db 1 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET TranGroup:BWDBUF ;AN000;offset of arg
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Char_field_ASCIIZ ;AN000;character string
|
||||
db 128 ;AN000;maximum width
|
||||
db 0 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
; "No Path",13,10
|
||||
;
|
||||
NulPath_Ptr dw 1049 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Invalid drive in search path",13,10
|
||||
;
|
||||
BadPMes_Ptr dw 1050 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Invalid device",13,10
|
||||
;
|
||||
BadDev_Ptr dw 1051 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "FOR cannot be nested",13,10
|
||||
;
|
||||
ForNestMes_Ptr dw 1052 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Intermediate file error during pipe",13,10
|
||||
;
|
||||
PipeEMes_Ptr dw 1053 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Cannot do binary reads from a device",13,10
|
||||
;
|
||||
InBDev_Ptr dw 1054 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "BREAK is %1",13,10
|
||||
;
|
||||
CtrlcMes_Ptr dw 1055 ;AN000;message number
|
||||
db 1 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw 0 ;AN000;offset of on/off (new)
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Char_field_ASCIIZ ;AN000;character string
|
||||
db 128 ;AN000;maximum width
|
||||
db 1 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
; "VERIFY is %1",13,10
|
||||
;
|
||||
VeriMes_Ptr dw 1056 ;AN000;message number
|
||||
db 1 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw 0 ;AN000;offset of on/off (new)
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Char_field_ASCIIZ ;AN000;character string
|
||||
db 128 ;AN000;maximum width
|
||||
db 1 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
; "ECHO is %1",13,10
|
||||
;
|
||||
EchoMes_Ptr dw 1057 ;AN000;message number
|
||||
db 1 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw 0 ;AN000;offset of on/off (new)
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Char_field_ASCIIZ ;AN000;character string
|
||||
db 128 ;AN000;maximum width
|
||||
db 1 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
; "off"
|
||||
;
|
||||
OffMes_Ptr dw 1059 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "on"
|
||||
;
|
||||
OnMes_Ptr dw 1060 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Error writing to device",13,10
|
||||
;
|
||||
DevWMes_Ptr dw 1061 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "Invalid path",13,10
|
||||
;
|
||||
Inval_Path_Ptr dw 1062 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; unformatted string output
|
||||
;
|
||||
arg_Buf_Ptr dw 1063 ;AN000;message number
|
||||
db 1 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET TranGroup:Arg_Buf ;AN000;offset of arg
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Char_field_ASCIIZ ;AN000;character string
|
||||
db 128 ;AN000;maximum width
|
||||
db 0 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
; file name output
|
||||
;
|
||||
File_Name_Ptr dw 1064 ;AN000;message number
|
||||
db 1 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET TranGroup:SRCBUF ;AN000;offset of arg
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Char_field_ASCIIZ ;AN000;character string
|
||||
db 128 ;AN000;maximum width
|
||||
db 0 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
; file size output for dir
|
||||
;
|
||||
Disp_File_Size_Ptr dw 1065 ;AN000;message number
|
||||
db 1 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET TranGroup:File_size_low ;AN000;offset of arg
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Right_Align+Unsgn_Bin_DWord ;AN000;long binary to decimal
|
||||
db 10 ;AN000;maximum width
|
||||
db 10 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
; unformatted string output
|
||||
; %s
|
||||
String_Buf_Ptr dw 1066 ;AN000;message number
|
||||
db 1 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET TranGroup:String_ptr_2 ;AN000;offset of arg
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Char_field_ASCIIZ ;AN000;character string
|
||||
db 128 ;AN000;maximum width
|
||||
db 0 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
db 0 ;AN000;
|
||||
|
||||
; tab character
|
||||
;
|
||||
Tab_ptr dw 1067 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; " <DIR> "
|
||||
;
|
||||
DMes_Ptr dw 1068 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; destructive back space
|
||||
;
|
||||
Dback_Ptr dw 1069 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; carriage return / line feed
|
||||
;
|
||||
ACRLF_Ptr dw 1070 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; output a single character
|
||||
;
|
||||
;One_Char_Buf_Ptr dw 1071 ;AN000;message number
|
||||
; db 1 ;AN000;number of subst
|
||||
; db parm_block_size ;AN000;size of sublist
|
||||
; db 0 ;AN000;reserved
|
||||
; dw OFFSET TranGroup:One_Char_Val ;AN000;offset of charcacter
|
||||
; dw 0 ;AN000;segment of arg
|
||||
; db 1 ;AN000;first subst
|
||||
; db Char_field_Char ;AN000;character
|
||||
; db 1 ;AN000;maximum width
|
||||
; db 1 ;AN000;minimum width
|
||||
; db blank ;AN000;pad character
|
||||
|
||||
; "mm-dd-yy"
|
||||
;
|
||||
USADat_Ptr dw 1072 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "dd-mm-yy"
|
||||
;
|
||||
EurDat_Ptr dw 1073 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; "yy-mm-dd"
|
||||
;
|
||||
JapDat_Ptr dw 1074 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
; date string for prompt
|
||||
;
|
||||
promptDat_Ptr dw 1075 ;AN000;message number
|
||||
db 2 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
dw OFFSET TranGroup:Arg_Buf ;AN000;offset of arg
|
||||
dw 0 ;AN000;segment of arg
|
||||
db 1 ;AN000;first subst
|
||||
db Char_field_ASCIIZ ;AN000;character string
|
||||
db 3 ;AN000;maximum width
|
||||
db 3 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
promptDat_yr dw 0 ;AN000;year
|
||||
promptDat_moday dw 0 ;AN000;month,day
|
||||
db 2 ;AN000;second subst
|
||||
db DATE_MDY_4 ;AN000;date
|
||||
db 10 ;AN000;maximum width
|
||||
db 8 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
|
||||
; Time for prompt
|
||||
;
|
||||
promTim_Ptr dw 1076 ;AN000;message number
|
||||
db 1 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
PromTim_hr_min dw 0 ;AN000;hours,minutes
|
||||
PromTim_Sec_hn dw 0 ;AN000;seconds,hundredths
|
||||
db 1 ;AN000;first subst
|
||||
db Right_Align+TIME_HHMMSSHH_24 ;AC013;time
|
||||
db 11 ;AN000;maximum width
|
||||
db 11 ;AC013;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
; Date and time for DIR
|
||||
;
|
||||
DirDatTim_Ptr dw 1077 ;AN000;message number
|
||||
db 2 ;AN000;number of subst
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
DirDat_yr dw 0 ;AN000;year
|
||||
DirDat_mo_day dw 0 ;AN000;month,day
|
||||
db 1 ;AN000;first subst
|
||||
db Right_Align+DATE_MDY_2 ;AN000;date
|
||||
db 10 ;AN000;maximum width
|
||||
db 8 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
db parm_block_size ;AN000;size of sublist
|
||||
db 0 ;AN000;reserved
|
||||
DirTim_hr_min dw 0 ;AN000;hours,minutes
|
||||
DirTim_Sec_hn dw 0 ;AN000;seconds,hundredths
|
||||
db 2 ;AN000;second subst
|
||||
db Right_align+TIME_HHMM_Cty ;AN000;time
|
||||
db 6 ;AN000;maximum width
|
||||
db 6 ;AN000;minimum width
|
||||
db blank ;AN000;pad character
|
||||
|
||||
; "Directory already exists"
|
||||
;
|
||||
MD_exists_ptr dw 1078 ;AN000;message number
|
||||
db no_subst ;AN000;number of subst
|
||||
|
||||
PATH_TEXT DB "PATH="
|
||||
PROMPT_TEXT DB "PROMPT="
|
||||
comspecstr db "COMSPEC="
|
||||
488
v4.0/src/CMD/COMMAND/TSPC.ASM
Normal file
488
v4.0/src/CMD/COMMAND/TSPC.ASM
Normal file
@@ -0,0 +1,488 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)tspc.asm 4.1 85/09/22
|
||||
; SCCSID = @(#)tspc.asm 4.1 85/09/22
|
||||
TITLE COMMAND Transient Uninitialized DATA
|
||||
|
||||
INCLUDE comsw.asm
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE DOSSYM.INC
|
||||
INCLUDE comequ.asm
|
||||
INCLUDE comseg.asm
|
||||
INCLUDE EA.inc ;AN030;
|
||||
.list
|
||||
.cref
|
||||
|
||||
; Uninitialized transient data
|
||||
TRANSPACE SEGMENT PUBLIC BYTE
|
||||
|
||||
PUBLIC ALLSWITCH
|
||||
PUBLIC append_exec ;AN041;
|
||||
PUBLIC arg
|
||||
PUBLIC argbufptr
|
||||
PUBLIC ARGC
|
||||
PUBLIC ARG1S
|
||||
PUBLIC ARG2S
|
||||
PUBLIC ARGTS
|
||||
PUBLIC arg_buf
|
||||
PUBLIC ASCII
|
||||
PUBLIC BatBuf
|
||||
PUBLIC BatBufEnd
|
||||
PUBLIC BatBufPos
|
||||
PUBLIC BATHAND
|
||||
PUBLIC BINARY
|
||||
PUBLIC BITS
|
||||
PUBLIC BWDBUF
|
||||
PUBLIC BYTCNT
|
||||
PUBLIC bytes_free
|
||||
PUBLIC CFLAG
|
||||
PUBLIC CHARBUF
|
||||
PUBLIC CHKDRV
|
||||
PUBLIC COM
|
||||
PUBLIC COMBUF
|
||||
PUBLIC comma
|
||||
PUBLIC comptr
|
||||
PUBLIC comspec_flag
|
||||
PUBLIC COMSW
|
||||
PUBLIC CONCAT
|
||||
PUBLIC concat_xa ;AN000;
|
||||
PUBLIC copy_Num
|
||||
PUBLIC CPDATE
|
||||
PUBLIC CPTIME
|
||||
PUBLIC cpyflag
|
||||
PUBLIC CURDRV
|
||||
PUBLIC DATE_DAY ;AN000;
|
||||
PUBLIC DATE_MONTH ;AN000;
|
||||
PUBLIC DATE_OUTPUT ;AN000;
|
||||
PUBLIC DATE_TYPE ;AN000;
|
||||
PUBLIC DATE_YEAR ;AN000;
|
||||
PUBLIC DEST
|
||||
PUBLIC DESTBUF
|
||||
PUBLIC DestClosed
|
||||
PUBLIC DESTDIR
|
||||
PUBLIC DESTFCB
|
||||
PUBLIC DESTFCB2
|
||||
PUBLIC DESTHAND
|
||||
PUBLIC DESTINFO
|
||||
PUBLIC DESTISDEV
|
||||
PUBLIC DESTISDIR
|
||||
PUBLIC DESTNAME
|
||||
PUBLIC DESTSIZ
|
||||
PUBLIC DESTSWITCH
|
||||
PUBLIC DESTTAIL
|
||||
PUBLIC DESTVARS
|
||||
PUBLIC DIRBUF
|
||||
PUBLIC DIRCHAR
|
||||
PUBLIC dirflag ;AN015;
|
||||
PUBLIC Dir_Num
|
||||
PUBLIC display_ioctl ;AN000;
|
||||
PUBLIC display_mode ;AN000;
|
||||
PUBLIC display_width ;AN000;
|
||||
PUBLIC DRIVE_NUMBER ;AN000;
|
||||
PUBLIC DRIVE_OUTPUT ;AN000;
|
||||
PUBLIC DRIVE_TYPE ;AN000;
|
||||
PUBLIC DRIVE_VALUE ;AN000;
|
||||
PUBLIC ELCNT
|
||||
PUBLIC ELPOS
|
||||
PUBLIC EXECPATH
|
||||
PUBLIC EXEC_ADDR
|
||||
PUBLIC EXEFCB
|
||||
PUBLIC expand_star
|
||||
PUBLIC ext_entered ;AN005;
|
||||
PUBLIC ext_open_off ;AN000;
|
||||
PUBLIC ext_open_parms ;AN000;
|
||||
PUBLIC ext_open_seg ;AN000;
|
||||
PUBLIC FBUF
|
||||
PUBLIC FILECNT
|
||||
PUBLIC file_size_high
|
||||
PUBLIC file_size_low
|
||||
PUBLIC FILTYP
|
||||
PUBLIC FIRSTDEST
|
||||
PUBLIC FRSTSRCH
|
||||
PUBLIC FULLSCR
|
||||
PUBLIC GOTOLEN
|
||||
PUBLIC HEADCALL
|
||||
PUBLIC ID
|
||||
PUBLIC IDLEN
|
||||
PUBLIC IFNOTFLAG
|
||||
PUBLIC if_not_count
|
||||
PUBLIC INEXACT
|
||||
PUBLIC INTERNATVARS
|
||||
PUBLIC KPARSE
|
||||
PUBLIC last_arg
|
||||
PUBLIC LINCNT
|
||||
PUBLIC LINLEN
|
||||
PUBLIC linperpag ;AN000;
|
||||
PUBLIC major_ver_num
|
||||
PUBLIC MELCOPY
|
||||
PUBLIC MELSTART
|
||||
PUBLIC minor_ver_num
|
||||
PUBLIC msg_flag ;AN022;
|
||||
PUBLIC msg_numb ;AN022;
|
||||
PUBLIC NOWRITE
|
||||
PUBLIC NXTADD
|
||||
PUBLIC objcnt
|
||||
PUBLIC one_char_val
|
||||
PUBLIC PARM1
|
||||
PUBLIC PARM2
|
||||
PUBLIC parse_last ;AN018;
|
||||
PUBLIC PARSE1_ADDR ;AN000;
|
||||
PUBLIC PARSE1_CODE ;AN000;
|
||||
PUBLIC PARSE1_OUTPUT ;AN000;
|
||||
PUBLIC PARSE1_SYN ;AN000;
|
||||
PUBLIC PARSE1_TYPE ;AN000;
|
||||
PUBLIC PATHCNT
|
||||
PUBLIC pathinfo
|
||||
PUBLIC PATHPOS
|
||||
PUBLIC PATHSW
|
||||
PUBLIC PLUS
|
||||
PUBLIC plus_comma
|
||||
PUBLIC print_err_flag ;AN000;
|
||||
PUBLIC psep_char
|
||||
PUBLIC RCH_ADDR
|
||||
PUBLIC RDEOF
|
||||
PUBLIC RE_INSTR
|
||||
PUBLIC RESSEG
|
||||
PUBLIC SCANBUF
|
||||
PUBLIC SDIRBUF
|
||||
PUBLIC search_best
|
||||
PUBLIC search_best_buf
|
||||
PUBLIC search_curdir_buf
|
||||
PUBLIC search_error
|
||||
PUBLIC SKPDEL
|
||||
PUBLIC SOURCE
|
||||
PUBLIC SPECDRV
|
||||
PUBLIC SRCBUF
|
||||
PUBLIC SRCHAND
|
||||
PUBLIC SRCINFO
|
||||
PUBLIC SRCISDEV
|
||||
PUBLIC SRCISDIR
|
||||
PUBLIC SRCPT
|
||||
PUBLIC SRCSIZ
|
||||
PUBLIC SRCTAIL
|
||||
PUBLIC SRCVARS
|
||||
PUBLIC srcxname
|
||||
PUBLIC src_xa_seg ;AN000;
|
||||
PUBLIC src_xa_size ;AN000;
|
||||
PUBLIC STACK
|
||||
PUBLIC STARTEL
|
||||
PUBLIC string_ptr_2
|
||||
;AD061; PUBLIC string_ptr_2_sb ;AN000;
|
||||
PUBLIC subst_buffer ;AN061;
|
||||
PUBLIC SWITCHAR
|
||||
PUBLIC system_cpage
|
||||
PUBLIC TERMREAD
|
||||
PUBLIC TIME_FRACTION ;AN000;
|
||||
PUBLIC TIME_HOUR ;AN000;
|
||||
PUBLIC TIME_MINUTES ;AN000;
|
||||
PUBLIC TIME_OUTPUT ;AN000;
|
||||
PUBLIC TIME_SECONDS ;AN000;
|
||||
PUBLIC TIME_TYPE ;AN000;
|
||||
PUBLIC TPA
|
||||
PUBLIC tpbuf
|
||||
PUBLIC TRANSPACEEND
|
||||
PUBLIC TRAN_TPA
|
||||
PUBLIC trgxname
|
||||
PUBLIC UCOMBUF
|
||||
PUBLIC USERDIR1
|
||||
PUBLIC vol_drv
|
||||
PUBLIC vol_ioctl_buf ;AC030;
|
||||
PUBLIC vol_serial ;AC030;
|
||||
PUBLIC vol_label ;AC030;
|
||||
PUBLIC WRITTEN
|
||||
PUBLIC xa_cp_length ;AN030;
|
||||
PUBLIC xa_cp_out ;AN030;
|
||||
PUBLIC xa_list_attr ;AN030;
|
||||
PUBLIC zflag
|
||||
|
||||
IF IBM
|
||||
PUBLIC ROM_CALL
|
||||
PUBLIC ROM_CS
|
||||
PUBLIC ROM_IP
|
||||
ENDIF
|
||||
|
||||
|
||||
ORG 0
|
||||
ZERO = $
|
||||
SRCXNAME DB DIRSTRLEN + 20 DUP (?) ;g buffer for name translate
|
||||
TRGXNAME DB DIRSTRLEN + 20 DUP (?) ;g buffer for name translate
|
||||
UCOMBUF DB COMBUFLEN+3 DUP(?) ; Raw console buffer
|
||||
COMBUF DB COMBUFLEN+3 DUP(?) ; Cooked console buffer
|
||||
USERDIR1 DB DIRSTRLEN+3 DUP(?) ; Storage for users current directory
|
||||
EXECPATH DB COMBUFLEN+3 DUP(?) ; Path for external command
|
||||
RE_INSTR DB DIRSTRLEN+3+13 DUP (?) ; path for input to redirection
|
||||
|
||||
; Variables passed up from resident
|
||||
HEADCALL LABEL DWORD
|
||||
DW ?
|
||||
RESSEG DW ?
|
||||
TPA DW ?
|
||||
SWITCHAR DB ?
|
||||
DIRCHAR DB ?
|
||||
EXEC_ADDR DD ?
|
||||
RCH_ADDR DD ?
|
||||
fTest DW ?
|
||||
TRAN_TPA DW ?
|
||||
|
||||
CHKDRV DB ?
|
||||
RDEOF LABEL BYTE ; Misc flags
|
||||
IFNOTFLAG LABEL BYTE
|
||||
FILTYP DB ?
|
||||
CURDRV DB ?
|
||||
concat_xa db 0 ;AN000; flag for XA on file concatenations
|
||||
CONCAT LABEL BYTE
|
||||
PARM1 DB ?
|
||||
ARGC LABEL BYTE
|
||||
PARM2 DB ?
|
||||
COMSW DW ? ; Switches between command and 1st arg
|
||||
ARG1S DW ? ; Switches between 1st and 2nd arg
|
||||
DESTSWITCH LABEL WORD
|
||||
ARG2S DW ? ; Switches after 2nd arg
|
||||
ALLSWITCH LABEL WORD
|
||||
ARGTS DW ? ; ALL switches except for COMSW
|
||||
CFLAG DB ?
|
||||
DESTCLOSED LABEL BYTE
|
||||
SPECDRV DB ?
|
||||
BYTCNT DW ? ; Size of buffer between RES and TRANS
|
||||
NXTADD DW ?
|
||||
FRSTSRCH DB ?
|
||||
LINCNT DB ?
|
||||
LINLEN DB ?
|
||||
FILECNT DW ?
|
||||
CHARBUF DB 80 DUP (?) ;line byte character buffer for xenix write
|
||||
DESTFCB2 LABEL BYTE
|
||||
IDLEN DB ?
|
||||
ID DB 8 DUP(?)
|
||||
COM DB 3 DUP(?)
|
||||
DEST DB 37 DUP(?)
|
||||
DESTNAME DB 11 DUP(?)
|
||||
DESTFCB LABEL BYTE
|
||||
DESTDIR DB DIRSTRLEN DUP(?) ; Directory for PATH searches
|
||||
GOTOLEN LABEL WORD
|
||||
BWDBUF LABEL BYTE
|
||||
EXEFCB LABEL WORD
|
||||
DIRBUF DB DIRSTRLEN+3 DUP(?)
|
||||
SDIRBUF DB 12 DUP(?)
|
||||
BITS DW ?
|
||||
PATHCNT DW ?
|
||||
PATHPOS DW ?
|
||||
PATHSW DW ?
|
||||
FULLSCR DW ?
|
||||
comma db 0 ;g flag set if +,, occurs
|
||||
plus_comma db 0 ;g flag set if +,, occurs
|
||||
dirflag db 0 ;AN015; set when pathcrunch called from DIR
|
||||
parse_last dw 0 ;AN018; used to hold parsing position
|
||||
|
||||
system_cpage DW 0 ;AC001; used for CHCP variable
|
||||
src_XA_size DW 0 ;AN000; size of extended attributes
|
||||
src_XA_seg DW 0 ;AN000; segment of extended attributes
|
||||
|
||||
ext_open_parms label byte ;AN000; extended open parameter list
|
||||
;emg340 ext_open_off dw offset trangroup:srcbuf ;AN000; offset of file name
|
||||
ext_open_off dw ? ;AN030; offset of extended attributes
|
||||
ext_open_seg dw ? ;AN000; segment of extended attributes
|
||||
dw 0 ;AN000; no additional parameters
|
||||
|
||||
XA_cp_out label byte ;AN030; list for one extended attribute
|
||||
DW 1 ;AN030; count of entries
|
||||
DB EAISBINARY ;AN030; ea_type
|
||||
DW EASYSTEM ;AN030; ea_flags
|
||||
DB ? ;AN030; ea_rc
|
||||
DB 2 ;AN030; ea_namelen
|
||||
DW 2 ;AN030; ea_valuelen
|
||||
DB "CP" ;AN030; ea_name
|
||||
xa_list_attr DW 0 ;AC030; code page
|
||||
xa_cp_length DW $-XA_cp_out ;AN030; length of buffer
|
||||
|
||||
|
||||
|
||||
arg_buf db 128 dup (?)
|
||||
file_size_low dw ? ;AC000;
|
||||
file_size_high dw ? ;AC000;
|
||||
string_ptr_2 dw ?
|
||||
;AD061;string_ptr_2_sb dw ?
|
||||
copy_Num dw ?
|
||||
cpyflag db ?
|
||||
Dir_Num DW ?
|
||||
bytes_free dw ?
|
||||
dw ?
|
||||
major_ver_num dw ?
|
||||
minor_ver_num dw ?
|
||||
one_char_val db ?,0
|
||||
vol_drv db ?
|
||||
|
||||
IF IBM
|
||||
ROM_CALL DB ? ; flag for rom function
|
||||
ROM_IP DW ?
|
||||
ROM_CS DW ?
|
||||
ENDIF
|
||||
|
||||
DESTVARS LABEL BYTE
|
||||
DESTISDIR DB ?
|
||||
DESTSIZ DB ?
|
||||
DESTTAIL DW ?
|
||||
DESTINFO DB ?
|
||||
DESTBUF DB DIRSTRLEN + 20 DUP (?)
|
||||
|
||||
DESTHAND DW ?
|
||||
DESTISDEV DB ?
|
||||
FIRSTDEST DB ?
|
||||
MELCOPY DB ?
|
||||
MELSTART DW ?
|
||||
|
||||
SRCVARS LABEL BYTE
|
||||
SRCISDIR DB ?
|
||||
SRCSIZ DB ?
|
||||
SRCTAIL DW ?
|
||||
SRCINFO DB ?
|
||||
SRCBUF DB DIRSTRLEN + 20 DUP (?)
|
||||
|
||||
SRCHAND DW ?
|
||||
SRCISDEV DB ?
|
||||
|
||||
SCANBUF DB DIRSTRLEN + 20 DUP (?)
|
||||
|
||||
SRCPT DW ?
|
||||
INEXACT DB ?
|
||||
NOWRITE DB ?
|
||||
BINARY DB ?
|
||||
WRITTEN DW ?
|
||||
TERMREAD DB ?
|
||||
ASCII DB ?
|
||||
PLUS DB ?
|
||||
objcnt db ? ; Used in copy
|
||||
CPDATE DW ?
|
||||
CPTIME DW ?
|
||||
BATHAND DW ? ; Batch handle
|
||||
STARTEL DW ?
|
||||
ELCNT DB ?
|
||||
ELPOS DB ?
|
||||
SKPDEL DB ?
|
||||
SOURCE DB 11 DUP(?)
|
||||
|
||||
ext_entered db 0 ;AN005;
|
||||
|
||||
display_ioctl db 0 ;AN000; info level
|
||||
db 0 ;AN000; reserved
|
||||
dw crt_ioctl_ln ;AN000; length of data
|
||||
dw ? ;AN000; control flags
|
||||
display_mode db ? ;AN000; display mode, colors
|
||||
db 0 ;AN000; reserved
|
||||
dw ? ;AN023; colors
|
||||
dw ? ;AN000; display width (PELS)
|
||||
dw ? ;AN000; display length (PELS)
|
||||
display_width dw ? ;AN000; display width
|
||||
linperpag dw linesperpage ;AN000; display length (default to linesperpage)
|
||||
|
||||
vol_ioctl_buf label byte ;AN000; buffer for ioctl volume label/serial call
|
||||
dw 0 ;AN000; info level
|
||||
vol_serial dd 0 ;AN000; volume serial number
|
||||
vol_label db 11 dup (" ") ;AN000; volume label - init to blanks
|
||||
db 8 dup (" ") ;AN000; file system type
|
||||
|
||||
expand_star db ?
|
||||
comspec_flag db ?
|
||||
msg_flag db ? ;AN022; flag set if non-utility message issued
|
||||
msg_numb dw 0 ;AN022; set with extended error message issued
|
||||
append_exec db 0 ;AN041; set if internal append executed
|
||||
print_err_flag dw 0 ;AN000; flag set if error during sysdispmsg
|
||||
subst_buffer db parm_block_size*2 dup (0);AN061;
|
||||
|
||||
;;;; IF KANJI 3/3/KK
|
||||
KPARSE DB ?
|
||||
;;;; ENDIF 3/3/KK
|
||||
|
||||
; Data declarations taken out of parse.asm
|
||||
|
||||
arg arg_unit <> ; pointers, arg count, string buffer
|
||||
argbufptr DW ? ; index for argv[].argpointer
|
||||
tpbuf DB 128 DUP (?) ; temporary buffer
|
||||
LAST_ARG DW ? ; point at which to accumulate switch info
|
||||
comptr dw ? ; ptr into combuf
|
||||
|
||||
; Data declarations taken out of path.asm
|
||||
fbuf find_buf <> ; dma buffer for findfirst/findnext
|
||||
pathinfo DW 3 DUP (?) ; ES, SI(old), and SI(new) of user path
|
||||
psep_char DB ? ; '/' or '\'
|
||||
search_best DB (?) ; best code, best filename so far
|
||||
fname_max_len equ 13
|
||||
search_best_buf DB fname_max_len DUP (?)
|
||||
search_curdir_buf DB 64 DUP (?) ; a place for CurDir info, if successful
|
||||
search_error DW (?) ; address of error message to be printed
|
||||
|
||||
; Data declarations taken out of tbatch.asm
|
||||
if_not_count DW ?
|
||||
|
||||
zflag db ? ; Used by typefil to indicate ^Z's
|
||||
|
||||
DW 80H DUP(0) ; Init to 0 to make sure the linker is not fooled
|
||||
STACK LABEL WORD
|
||||
|
||||
INTERNATVARS internat_block <>
|
||||
DB (internat_block_max - ($ - INTERNATVARS)) DUP (?)
|
||||
|
||||
BatBufPos DW ? ; integer position in buffer of next byte
|
||||
BatBuf DB BatLen DUP (?)
|
||||
BatBufEnd DW ?
|
||||
|
||||
; *****************************************************
|
||||
; EMG 4.00
|
||||
; DATA STARTING HERE WAS ADDED BY EMG FOR 4.00
|
||||
; FOR IMPLEMENTATION OF COMMON PARSE ROUTINE
|
||||
; *****************************************************
|
||||
;
|
||||
; COMMON PARSE OUTPUT BLOCKS
|
||||
;
|
||||
|
||||
|
||||
;
|
||||
; Common output blocks for PARSE number, complex, or string values.
|
||||
;
|
||||
|
||||
PARSE1_OUTPUT LABEL BYTE ;AN000;
|
||||
PARSE1_TYPE DB 0 ;AN000; type
|
||||
PARSE1_CODE DB 0 ;AN000; return value
|
||||
PARSE1_SYN DW 0 ;AN000; es offset of synonym
|
||||
PARSE1_ADDR DD 0 ;AN000; numeric value / address
|
||||
; of string value
|
||||
|
||||
;
|
||||
; Common output block for PARSE date strings.
|
||||
;
|
||||
|
||||
DATE_OUTPUT LABEL BYTE ;AN000;
|
||||
DATE_TYPE DB 0 ;AN000; type
|
||||
DB 0 ;AN000; return value
|
||||
DW 0 ;AN000; es offset of synonym
|
||||
DATE_YEAR DW 0 ;AN000; year
|
||||
DATE_MONTH DB 0 ;AN000; month
|
||||
DATE_DAY DB 0 ;AN000; day
|
||||
|
||||
;
|
||||
; Common output block for PARSE time strings.
|
||||
;
|
||||
|
||||
TIME_OUTPUT LABEL BYTE ;AN000;
|
||||
TIME_TYPE DB 0 ;AN000; type
|
||||
DB 0 ;AN000; return value
|
||||
DW 0 ;AN000; es offset of synonym
|
||||
TIME_HOUR DB 0 ;AN000; hour
|
||||
TIME_MINUTES DB 0 ;AN000; minutes
|
||||
TIME_SECONDS DB 0 ;AN000; seconds
|
||||
TIME_FRACTION DB 0 ;AN000; hundredths
|
||||
|
||||
;
|
||||
; Common output block for PARSE drive specifier (one based drive number).
|
||||
;
|
||||
|
||||
DRIVE_OUTPUT LABEL BYTE ;AN000;
|
||||
DRIVE_TYPE DB 0 ;AN000; type
|
||||
DRIVE_VALUE DB 0 ;AN000; return value
|
||||
DW 0 ;AN000; es offset of synonym
|
||||
DRIVE_NUMBER DB 0 ;AN000; drive number
|
||||
DB 0,0,0 ;AN000; reserved
|
||||
|
||||
TRANSPACEEND LABEL BYTE
|
||||
|
||||
TRANSPACE ENDS
|
||||
END
|
||||
520
v4.0/src/CMD/COMMAND/TUCODE.ASM
Normal file
520
v4.0/src/CMD/COMMAND/TUCODE.ASM
Normal file
@@ -0,0 +1,520 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)tucode.asm 4.2 85/05/31
|
||||
; SCCSID = @(#)tucode.asm 4.2 85/05/31
|
||||
Title COMMAND Language midifiable Code Transient
|
||||
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
INCLUDE dossym.inc
|
||||
INCLUDE comsw.asm
|
||||
INCLUDE comseg.asm
|
||||
INCLUDE comequ.asm
|
||||
.list
|
||||
.cref
|
||||
|
||||
|
||||
DATARES SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN ECHOFLAG:BYTE
|
||||
DATARES ENDS
|
||||
|
||||
TRANDATA SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN BAD_ON_OFF_ptr:word
|
||||
EXTRN ctrlcmes_ptr:word
|
||||
EXTRN DEL_Y_N_PTR:WORD
|
||||
EXTRN ECHOMES_ptr:word
|
||||
EXTRN extend_buf_ptr:word ;AC000;
|
||||
EXTRN offmes_ptr:word
|
||||
EXTRN onmes_ptr:word
|
||||
EXTRN PARSE_BREAK:BYTE ;AN000;
|
||||
EXTRN promptdat_moday:word ;AC000;
|
||||
EXTRN promptdat_ptr:word ;AC000;
|
||||
EXTRN promptdat_yr:word ;AC000;
|
||||
EXTRN string_buf_ptr:word
|
||||
EXTRN SUREMES_ptr:word
|
||||
EXTRN VERIMES_ptr:BYTE
|
||||
EXTRN WeekTab:word
|
||||
TRANDATA ENDS
|
||||
|
||||
TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
|
||||
EXTRN arg_buf:byte
|
||||
EXTRN BWDBUF:BYTE
|
||||
EXTRN DEST:BYTE
|
||||
EXTRN destdir:byte
|
||||
EXTRN dirchar:byte
|
||||
EXTRN PARSE1_CODE:BYTE ;AN000;
|
||||
EXTRN RESSEG:WORD
|
||||
EXTRN string_ptr_2:word
|
||||
|
||||
TRANSPACE ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC BYTE
|
||||
|
||||
EXTRN CERROR:NEAR
|
||||
EXTRN CRLF2:NEAR
|
||||
EXTRN extend_setup:near ;AN022;
|
||||
|
||||
PUBLIC CNTRLC
|
||||
PUBLIC ECHO
|
||||
PUBLIC GetDate
|
||||
PUBLIC NOTEST2
|
||||
PUBLIC PRINT_DATE
|
||||
PUBLIC SLASHP_ERASE ;AN000;
|
||||
PUBLIC VERIFY
|
||||
|
||||
ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING
|
||||
|
||||
; ****************************************************************
|
||||
; *
|
||||
; * ROUTINE: NOTEST2 - execution of DEL/ERASE command
|
||||
; *
|
||||
; * FUNCTION: Delete files based on user parsed input. Prompt
|
||||
; * user for Y/N if necessary. If an error occurs,
|
||||
; * set up an error message and go to CERROR.
|
||||
; *
|
||||
; * INPUT: FCB at 5ch set up with filename(s) entered
|
||||
; * Current directory set to entered directory
|
||||
; *
|
||||
; * OUTPUT: none
|
||||
; *
|
||||
; ****************************************************************
|
||||
;
|
||||
; ARE YOU SURE prompt when deleting *.*
|
||||
|
||||
NOTEST2:
|
||||
MOV CX,11
|
||||
MOV SI,FCB+1
|
||||
|
||||
AMBSPEC:
|
||||
LODSB
|
||||
CMP AL,'?'
|
||||
JNZ ALLFIL
|
||||
LOOP AMBSPEC
|
||||
|
||||
ALLFIL:
|
||||
CMP CX,0
|
||||
JNZ NOPRMPT
|
||||
|
||||
ASKAGN:
|
||||
MOV DX,OFFSET TRANGROUP:SUREMES_ptr ; "Are you sure (Y/N)?"
|
||||
invoke std_printf
|
||||
MOV SI,80H
|
||||
MOV DX,SI
|
||||
MOV WORD PTR [SI],120 ; zero length
|
||||
MOV AX,(STD_CON_INPUT_FLUSH SHL 8) OR STD_CON_STRING_INPUT
|
||||
INT 21H
|
||||
LODSW
|
||||
OR AH,AH
|
||||
JZ ASKAGN
|
||||
INVOKE SCANOFF
|
||||
call char_in_xlat ;G Convert to upper case
|
||||
retc ;AN000; return if function not supported
|
||||
CMP AL,CAPITAL_N ;G
|
||||
retz
|
||||
CMP AL,CAPITAL_Y ;G
|
||||
PUSHF
|
||||
CALL CRLF2
|
||||
POPF
|
||||
JNZ ASKAGN
|
||||
|
||||
NOPRMPT:
|
||||
MOV AH,FCB_DELETE
|
||||
MOV DX,FCB
|
||||
INT 21H
|
||||
INC AL
|
||||
jz eraerr
|
||||
invoke RESTUDIR
|
||||
ret ; If no error, return
|
||||
|
||||
eraerr:
|
||||
invoke set_ext_error_msg ;AN022; set up the extended error
|
||||
push dx ;AN022; save message
|
||||
invoke RESTUDIR
|
||||
pop dx ;AN022; restore message
|
||||
|
||||
cmp word ptr extend_buf_ptr,error_no_more_files ;AN022; convert no more files to
|
||||
jnz cerrorj2 ;AN022; file not found
|
||||
mov Extend_Buf_ptr,error_file_not_found ;AN000; get message number in control block
|
||||
|
||||
cerrorj2:
|
||||
jmp cerror
|
||||
|
||||
|
||||
; ****************************************************************
|
||||
; *
|
||||
; * ROUTINE: SLASHP_ERASE - execution of DEL/ERASE /P
|
||||
; *
|
||||
; * FUNCTION: Delete files based on user parsed input. Prompt
|
||||
; * user for Y/N where necessary. If an error occurs
|
||||
; * set up and error message and transfer control
|
||||
; * to CERROR.
|
||||
; *
|
||||
; * INPUT: FCB at 5ch set up with filename(s) entered
|
||||
; * Current directory set to entered directory
|
||||
; *
|
||||
; * OUTPUT: none
|
||||
; *
|
||||
; ****************************************************************
|
||||
|
||||
ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING
|
||||
|
||||
SLASHP_ERASE: ;AN000; entry point
|
||||
invoke build_dir_string ;AN000; set up current directory string for output
|
||||
mov ah,Set_DMA ;AN000; issue set dta int 21h
|
||||
mov dx,offset trangroup:destdir ;AN000; use Destdir for target
|
||||
int 21H ;AN000;
|
||||
mov ah,Dir_Search_First ;AN000; do dir search first int 21h
|
||||
mov dx,FCB ;AN000; use FCB at 5Ch for target
|
||||
int 21H ;AN000;
|
||||
inc al ;AN000; did an error occur
|
||||
jz eraerr ;AN022; go to error exit
|
||||
|
||||
delete_prompt_loop: ;AN000;
|
||||
mov si,offset trangroup:destdir+1 ;AN000; set up FCB as source
|
||||
mov di,offset trangroup:dest ;AN000; set up dest as target
|
||||
mov al,dirchar ;AN000; store a "\" in the first char
|
||||
stosb ;AN000; of DEST
|
||||
invoke fcb_to_ascz ;AN000; convert filename from FCB to ASCIIZ string
|
||||
|
||||
slashp_askagn: ;AN000;
|
||||
call crlf2 ;AN000; print out carriage return, line feed
|
||||
mov dx,offset trangroup:bwdbuf ;AN000; print out current directory string
|
||||
mov bx,dx ;AN000; get string pointer in bx
|
||||
cmp byte ptr [bx+3],end_of_line_out ;AN000; see if only D:\,0
|
||||
jnz not_del_root ;AN000; no continue
|
||||
mov byte ptr [bx+2],end_of_line_out ;AN000; yes, get rid of \
|
||||
|
||||
Not_del_root: ;AN000;
|
||||
mov string_ptr_2,dx ;AN000;
|
||||
mov dx,offset trangroup:string_buf_ptr ;AN000;
|
||||
invoke std_printf ;AN000;
|
||||
mov dx,offset trangroup:dest ;AN000; print out file name string
|
||||
mov string_ptr_2,dx ;AN000;
|
||||
mov dx,offset trangroup:string_buf_ptr ;AN000;
|
||||
invoke std_printf ;AN000;
|
||||
mov dx,offset trangroup:Del_Y_N_Ptr ;AN000; issue ", Delete (Y/N)?" message
|
||||
invoke std_printf ;AN000;
|
||||
mov si,80H ;AN000; set up buffer for input
|
||||
mov dx,si ;AN000;
|
||||
mov word ptr [si],combuflen ;AN000;
|
||||
mov ax,(std_con_input_flush shl 8) or std_con_string_input ;AN000;
|
||||
int int_command ;AN000; get input from the user
|
||||
lodsw ;AN000;
|
||||
or ah,ah ;AN000; was a character entered?
|
||||
jz slashp_askagn ;AN000; no - ask again
|
||||
invoke scanoff ;AN000; scan off leading delimiters
|
||||
call char_in_xlat ;AN000; yes - upper case it
|
||||
retc ;AN000; return if function not supported
|
||||
cmp al,capital_n ;AN000; was it no?
|
||||
jz next_del_file ;AN000; yes - don't delete file
|
||||
cmp al,capital_y ;AN000; was it yes?
|
||||
jz delete_this_file ;AN000; yes - delete the file
|
||||
jmp short slashp_askagn ;AN000; it was neither - ask again
|
||||
|
||||
delete_this_file: ;AN000;
|
||||
mov ah,fcb_delete ;AN000; delete the file
|
||||
mov dx,offset trangroup:destdir ;AN000; use Destdir for target
|
||||
int int_command ;AN000;
|
||||
inc al ;AN000; did an error occur?
|
||||
jnz next_del_file ;AN000; no - get next file
|
||||
jmp eraerr ;AN022; go to error exit - need long jmp
|
||||
|
||||
next_del_file: ;AN000;
|
||||
mov ah,dir_search_next ;AN000; search for another file
|
||||
mov dx,FCB ;AN000;
|
||||
int int_command ;AN000;
|
||||
inc al ;AN000; was a file found?
|
||||
jz slash_p_exit ;AN000; no - exit
|
||||
jmp delete_prompt_loop ;AN000; yes - continue (need long jump)
|
||||
|
||||
slash_p_exit:
|
||||
invoke get_ext_error_number ;AN022; get the extended error number
|
||||
cmp ax,error_no_more_files ;AN022; was error file not found?
|
||||
jz good_erase_exit ;AN022; yes - clean exit
|
||||
jmp extend_setup ;AN022; go issue error message
|
||||
|
||||
good_erase_exit:
|
||||
invoke restudir ;AN000; we're finished - restore user's dir
|
||||
call crlf2 ;AN000; print out carriage return, line feed
|
||||
ret ;AN000; exit
|
||||
|
||||
|
||||
;************************************************
|
||||
; ECHO, BREAK, and VERIFY commands. Check for "ON" and "OFF"
|
||||
|
||||
break Echo
|
||||
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
ECHO:
|
||||
CALL ON_OFF
|
||||
JC DOEMES
|
||||
MOV DS,[RESSEG]
|
||||
ASSUME DS:RESGROUP
|
||||
JNZ ECH_OFF
|
||||
OR [ECHOFLAG],1
|
||||
RET
|
||||
ECH_OFF:
|
||||
AND [ECHOFLAG],NOT 1
|
||||
RET
|
||||
|
||||
|
||||
CERRORJ:
|
||||
JMP CERROR
|
||||
|
||||
;
|
||||
; There was no discrenable ON or OFF after the ECHO. If there is nothing but
|
||||
; delimiters on the command line, we issue the ECHO is ON/OFF message.
|
||||
;
|
||||
|
||||
ASSUME DS:TRANGROUP
|
||||
|
||||
DOEMES:
|
||||
cmp cl,0 ;AC000; was anything on the line?
|
||||
jz PEcho ; just display current state.
|
||||
MOV DX,82H ; Skip one char after "ECHO"
|
||||
invoke CRPRINT
|
||||
JMP CRLF2
|
||||
|
||||
PECHO:
|
||||
MOV DS,[RESSEG]
|
||||
ASSUME DS:RESGROUP
|
||||
MOV BL,[ECHOFLAG]
|
||||
PUSH CS
|
||||
POP DS
|
||||
ASSUME DS:TRANGROUP
|
||||
AND BL,1
|
||||
MOV DX,OFFSET TRANGROUP:ECHOMES_ptr
|
||||
JMP SHORT PYN
|
||||
|
||||
break Break
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
CNTRLC:
|
||||
CALL ON_OFF
|
||||
MOV AX,(SET_CTRL_C_TRAPPING SHL 8) OR 1
|
||||
JC PCNTRLC
|
||||
JNZ CNTRLC_OFF
|
||||
MOV DL,1
|
||||
INT 21H ; Set ^C
|
||||
RET
|
||||
|
||||
CNTRLC_OFF:
|
||||
XOR DL,DL
|
||||
INT 21H ; Turn off ^C check
|
||||
RET
|
||||
|
||||
PCNTRLC:
|
||||
CMP CL,0 ;AC000; rest of line blank?
|
||||
JNZ CERRORJ ; no, oops!
|
||||
|
||||
pccont:
|
||||
XOR AL,AL
|
||||
INT 21H
|
||||
MOV BL,DL
|
||||
MOV DX,OFFSET TRANGROUP:CTRLCMES_ptr
|
||||
|
||||
PYN:
|
||||
mov si,offset trangroup:onmes_ptr ;AC000; get ON pointer
|
||||
OR BL,BL
|
||||
JNZ PRINTVAL
|
||||
mov si,offset trangroup:offmes_ptr ;AC000; get OFF pointer
|
||||
|
||||
PRINTVAL:
|
||||
push dx ;AN000; save offset of message block
|
||||
mov bx,dx ;AN000; save offset value
|
||||
lodsw ;AN000; get message number of on or off
|
||||
mov dh,util_msg_class ;AN000; this is a utility message
|
||||
invoke Tsysgetmsg ;AN000; get the address of the message
|
||||
add bx,ptr_off_pos ;AN000; point to offset of ON/OFF
|
||||
mov word ptr [bx],si ;AN000; put the offset in the message block
|
||||
pop dx ;AN000; get message back
|
||||
invoke std_printf ;AC000; go print message
|
||||
mov word ptr [bx],0 ;AN000; zero out message pointer
|
||||
|
||||
ret ;AN000; exit
|
||||
|
||||
break Verify
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
VERIFY:
|
||||
CALL ON_OFF
|
||||
MOV AX,(SET_VERIFY_ON_WRITE SHL 8) OR 1
|
||||
JC PVERIFY
|
||||
JNZ VER_OFF
|
||||
INT 21H ; Set verify
|
||||
RET
|
||||
|
||||
VER_OFF:
|
||||
DEC AL
|
||||
INT 21H ; Turn off verify after write
|
||||
RET
|
||||
|
||||
PVERIFY:
|
||||
CMP CL,0 ;AC000; is rest of line blank?
|
||||
JNZ CERRORJ ; nope...
|
||||
MOV AH,GET_VERIFY_ON_WRITE
|
||||
INT 21H
|
||||
MOV BL,AL
|
||||
MOV DX,OFFSET TRANGROUP:VERIMES_ptr
|
||||
JMP PYN
|
||||
|
||||
; ****************************************************************
|
||||
; *
|
||||
; * ROUTINE: ON_OFF
|
||||
; *
|
||||
; * FUNCTION: Parse the command line for an optional ON or
|
||||
; * OFF string for the BREAK, VERIFY, and ECHO
|
||||
; * routines.
|
||||
; *
|
||||
; * INPUT: command line at offset 81H
|
||||
; * PARSE_BREAK control block
|
||||
; *
|
||||
; * OUTPUT: If carry is clear
|
||||
; * If ON is found
|
||||
; * Zero flag set
|
||||
; * If OFF is found
|
||||
; * Zero flag clear
|
||||
; * If carry set
|
||||
; * If nothing on command line
|
||||
; * CL set to zero
|
||||
; * If error
|
||||
; * CL contains error value from parse
|
||||
; *
|
||||
; ****************************************************************
|
||||
|
||||
assume ds:trangroup,es:trangroup
|
||||
|
||||
ON_OFF:
|
||||
MOV SI,81h
|
||||
|
||||
scan_on_off: ;AN032; scan off leading blanks & equal
|
||||
lodsb ;AN032; get a char
|
||||
cmp al,blank ;AN032; if whitespace
|
||||
jz scan_on_off ;AN032; keep scanning
|
||||
cmp al,tab_chr ;AN032; if tab
|
||||
jz scan_on_off ;AN032; keep scanning
|
||||
cmp al,equal_chr ;AN032; if equal char
|
||||
jz parse_on_off ;AN032; start parsing
|
||||
dec si ;AN032; if none of above - back up
|
||||
|
||||
parse_on_off: ;AN032; and start parsing
|
||||
mov di,offset trangroup:parse_break ;AN000; Get adderss of PARSE_BREAK
|
||||
xor cx,cx ;AN000; clear cx,dx
|
||||
xor dx,dx ;AN000;
|
||||
invoke cmd_parse ;AC000; call parser
|
||||
cmp ax,end_of_line ;AC000; are we at end of line?
|
||||
jz BADONF ;AC000; yes, return error
|
||||
cmp ax,result_no_error ;AN000; did an error occur
|
||||
jz on_off_there ;AN000; no - continue
|
||||
mov cx,ax ;AN000; yes - set cl to error code
|
||||
jmp short BADONF ;AN000; return error
|
||||
|
||||
on_off_there:
|
||||
cmp parse1_code,-1 ;AN014; was a valid positional present?
|
||||
jnz good_on_off ;AN014; yes - continue
|
||||
mov cx,badparm_ptr ;AN014; something other than ON/OFF
|
||||
jmp short BADONF ;AN014; return error
|
||||
|
||||
good_on_off: ;AN014;
|
||||
xor ax,ax ;AC000; set up return code for
|
||||
or al,parse1_code ;AC000; ON or OFF in AX
|
||||
pushf ;AN000; save flags
|
||||
mov di,offset trangroup:parse_break ;AN000; Get adderss of PARSE_BREAK
|
||||
xor dx,dx ;AN000;
|
||||
invoke cmd_parse ;AN000; call parser
|
||||
cmp ax,end_of_line ;AN000; are we at end of line?
|
||||
jnz BADONF_flags ;AN000; NO, return error
|
||||
popf ;AN000; restore flags
|
||||
clc ;AC000; no error
|
||||
jmp short on_off_end ;AN000; return to caller
|
||||
|
||||
BADONF_flags:
|
||||
mov cx,ax
|
||||
popf
|
||||
|
||||
;
|
||||
; No discernable ON or OFF has been found. Put an error message pointer in DX
|
||||
; and return the error
|
||||
;
|
||||
BADONF:
|
||||
MOV DX,OFFSET TRANGROUP:BAD_ON_OFF_ptr
|
||||
STC
|
||||
|
||||
ON_OFF_END:
|
||||
|
||||
RET
|
||||
|
||||
|
||||
|
||||
;*************************************************************************
|
||||
; print date
|
||||
|
||||
PRINT_DATE:
|
||||
PUSH ES
|
||||
PUSH DI
|
||||
PUSH CS
|
||||
POP ES
|
||||
CALL GetDate ; get date
|
||||
xchg dh,dl ;AN000; switch month & day
|
||||
mov promptDat_yr,cx ;AC000; put year into message control block
|
||||
mov promptDat_moday,dx ;AC000; put month and day into message control block
|
||||
mov dx,offset trangroup:promptDat_ptr ;AC000; set up message for output
|
||||
invoke std_printf
|
||||
;AD061; mov promptDat_yr,0 ;AC000; reset year, month and day
|
||||
;AD061; mov promptDat_moday,0 ;AC000; pointers in control block
|
||||
POP DI ;AC000; restore di,es
|
||||
POP ES ;AC000;
|
||||
return
|
||||
;
|
||||
; Do GET DATE system call and set up 3 character day of week in ARG_BUF
|
||||
; for output. Date will be returned in CX,DX.
|
||||
;
|
||||
|
||||
GetDate:
|
||||
mov di,offset trangroup:arg_buf ;AC000; target for day of week
|
||||
MOV AH,GET_DATE ;AC000; get current date
|
||||
INT int_command ;AC000; Get date in CX:DX
|
||||
CBW ;AC000;
|
||||
|
||||
push cx ;AN000; save date returned in
|
||||
push dx ;AN000; CX:DX
|
||||
MOV SI,AX
|
||||
SHL SI,1
|
||||
ADD SI,AX ; SI=AX*3
|
||||
mov cx,si ;AN000; save si
|
||||
mov ax,weektab ;AN000; get message number of weektab
|
||||
mov dh,util_msg_class ;AN000; this is a utility message
|
||||
push di ;AN000; save argument buffer
|
||||
invoke Tsysgetmsg ;AN000; get the address of the message
|
||||
pop di ;AN000; retrieve argument buffer
|
||||
add si,cx ;AC000; get day of week
|
||||
MOV CX,3
|
||||
REP MOVSB
|
||||
mov al,end_of_line_out ;AC000; terminate the string
|
||||
stosb
|
||||
pop dx ;AN000; get back date
|
||||
pop cx ;AN000;
|
||||
|
||||
return
|
||||
;g
|
||||
;g This routine determines whether the character in AL is a
|
||||
;g Yes or No character. On return, if AL=0, the character is
|
||||
;g No, if AL=1, the character is Yes.
|
||||
;g
|
||||
|
||||
assume ds:trangroup
|
||||
|
||||
char_in_xlat proc near
|
||||
|
||||
mov dl,al ;AC000; get character into DX
|
||||
xor dh,dh ;AC000;
|
||||
mov ax,(getextcntry SHL 8) + 35 ;AC000; Yes/No char call
|
||||
int int_command ;AC000;
|
||||
|
||||
ret
|
||||
|
||||
char_in_xlat endp
|
||||
|
||||
TRANCODE ENDS
|
||||
END
|
||||
270
v4.0/src/CMD/COMMAND/UINIT.ASM
Normal file
270
v4.0/src/CMD/COMMAND/UINIT.ASM
Normal file
@@ -0,0 +1,270 @@
|
||||
page 80,132
|
||||
; SCCSID = @(#)uinit.asm 4.5 85/12/04
|
||||
; SCCSID = @(#)uinit.asm 4.5 85/12/04
|
||||
TITLE COMMAND Initialization messages
|
||||
|
||||
.XCREF
|
||||
.XLIST
|
||||
include comsw.asm
|
||||
include comseg.asm
|
||||
include ifequ.asm
|
||||
.LIST
|
||||
.CREF
|
||||
|
||||
addr macro sym,name
|
||||
public name
|
||||
ifidn <name>,<>
|
||||
|
||||
dw offset resgroup:sym
|
||||
else
|
||||
|
||||
name dw offset resgroup:sym
|
||||
endif
|
||||
endm
|
||||
|
||||
|
||||
ENVIRONMENT SEGMENT PUBLIC PARA ;AC000;
|
||||
EXTRN ECOMSPEC:BYTE
|
||||
ENVIRONMENT ENDS
|
||||
|
||||
TRANCODE SEGMENT PUBLIC BYTE ;AC000;
|
||||
extrn Printf_init:FAR
|
||||
extrn Triage_Init:FAR
|
||||
extrn append_parse:FAR ;AN054;
|
||||
TranCode ENDS
|
||||
|
||||
INIT SEGMENT PUBLIC PARA ;AC000;
|
||||
|
||||
|
||||
public icondev
|
||||
public BADCSPFL
|
||||
public COMSPECT
|
||||
public AUTOBAT
|
||||
public fslash
|
||||
public bslash
|
||||
public space
|
||||
public PRDATTM
|
||||
public INITADD
|
||||
public print_add
|
||||
public CHUCKENV
|
||||
public scswitch
|
||||
public ucasea
|
||||
public ECOMLOC
|
||||
public equalsign
|
||||
public lcasea
|
||||
public lcasez
|
||||
public comspstring
|
||||
public EnvSiz
|
||||
public EnvMax
|
||||
public initend
|
||||
public trnsize
|
||||
public resetenv ;AC000;
|
||||
public ext_msg ;AC000;
|
||||
public num_positionals
|
||||
public internat_info
|
||||
public parsemes_ptr
|
||||
|
||||
PUBLIC triage_add
|
||||
PUBLIC oldenv
|
||||
PUBLIC usedenv
|
||||
PUBLIC KAUTOBAT ;AN000; 3/3/KK
|
||||
public eswitch ;AN018;
|
||||
public dswitch ;AN018;
|
||||
public init_parse ;AN054;
|
||||
public old_parse_ptr ;AN057;
|
||||
PUBLIC pars_msg_off ;AN060;
|
||||
PUBLIC pars_msg_seg ;AN060;
|
||||
|
||||
include resmsg.equ ;AC000;
|
||||
|
||||
|
||||
ICONDEV LABEL BYTE
|
||||
DB "/DEV/"
|
||||
DB "CON",0,0,0,0,0,0 ; Room for 8 char device
|
||||
BADCSPFL DB 0
|
||||
COMSPECT DB "/COMMAND.COM",0,0
|
||||
AUTOBAT DB 0,":\AUTOEXEC.BAT",0,0DH ;AC027;
|
||||
KAUTOBAT DB 0,":\KAUTOEXE.BAT",0,0DH ;AC027; 3/3/KK
|
||||
|
||||
PRDATTM DB -1 ;Init not to prompt for date time
|
||||
INITADD DD ?
|
||||
print_add LABEL DWORD
|
||||
DW OFFSET TranGroup:Printf_INIT
|
||||
DW 0
|
||||
triage_add LABEL DWORD
|
||||
DW OFFSET TranGroup:Triage_Init
|
||||
DW 0
|
||||
CHUCKENV DB 0
|
||||
;eg ECOMLOC DW OFFSET ENVIRONMENT:ECOMSPEC-10H
|
||||
ECOMLOC DW OFFSET ENVIRONMENT:ECOMSPEC ;eg
|
||||
|
||||
COMSPSTRING DB "COMSPEC="
|
||||
equalsign db "="
|
||||
lcasea db "a"
|
||||
lcasez db "z"
|
||||
fslash db "/"
|
||||
bslash db "\"
|
||||
space db " "
|
||||
scswitch db "C" ; Single command
|
||||
ucasea db "A"
|
||||
|
||||
EnvSiz DW 0 ; size user wants to allocate
|
||||
EnvMax DW 0 ; maximum size allowed.
|
||||
oldenv DW 0 ; envirseg at initialization
|
||||
usedenv DW 0 ; amount of envirseg used
|
||||
PARS_MSG_OFF DW 0 ;AN060; SAVED PARSE ERROR MESSAGE OFFSET
|
||||
PARS_MSG_SEG DW 0 ;AN060; SAVED PARSE ERROR MESSAGE SEGMENT
|
||||
|
||||
;Do not separate the following two words. Used to call transient PARSE routine
|
||||
|
||||
init_parse label dword ;AN054;
|
||||
init_p DW TRANGROUP:APPEND_PARSE ;AN054;
|
||||
initend DW 0 ;eg segment address of end of init
|
||||
|
||||
;End of data that shouldn't be separated.
|
||||
|
||||
trnsize DW 0 ;eg size of transient in paragraphs
|
||||
resetenv DB 0 ;eg set if we need to setblck env at endinit
|
||||
ext_msg DB 0 ;AN000; set if /MSG switch entered
|
||||
eswitch db 0 ;AN018; set if /e was entered
|
||||
dswitch db 0 ;AN018; set if /d was entered
|
||||
parsemes_ptr dw 0 ;AN000; word to store parse error number
|
||||
|
||||
;
|
||||
; PARSE BLOCK FOR COMMAND
|
||||
;
|
||||
PUBLIC PARSE_COMMAND ;AN000;
|
||||
PUBLIC COMND1_OUTPUT ;AN000;
|
||||
PUBLIC COMND1_TYPE ;AN000;
|
||||
PUBLIC COMND1_CODE ;AN000;
|
||||
PUBLIC COMND1_SYN ;AN000;
|
||||
PUBLIC COMND1_ADDR ;AN000;
|
||||
PUBLIC COMMAND_F_SYN ;AN000;
|
||||
PUBLIC COMMAND_P_SYN ;AN000;
|
||||
PUBLIC COMMAND_C_SYN ;AN000;
|
||||
PUBLIC COMMAND_D_SYN ;AN000;
|
||||
PUBLIC COMMAND_E_SYN ;AN000;
|
||||
PUBLIC COMMAND_M_SYN ;AN000;
|
||||
|
||||
;
|
||||
; The following parse control block is used for COMMAND. This block is
|
||||
; used for parsing during initialization. The sytax for COMMAND is:
|
||||
; COMMAND [d:][path][/P][/F][/D][/E:xxxxx][/MSG][/C executable]
|
||||
; Anything on the command line after the /C switch will be passed to the
|
||||
; executable command, so if /C is used, it must be specified last. The
|
||||
; /MSG switch can only be specified if the /P switch is specified.
|
||||
;
|
||||
|
||||
ENVBIG EQU 32768 ;AN000; maximum environment size
|
||||
ENVSML EQU 160 ;AN000; minimum environment size
|
||||
|
||||
INTERNAT_INFO LABEL BYTE ;AN000; used for country info after parsing is completed
|
||||
PARSE_COMMAND LABEL BYTE ;AN000;
|
||||
DW RESGROUP:COMMAND_PARMS ;AN000;
|
||||
DB 0 ;AN000; no extra delimiter
|
||||
|
||||
COMMAND_PARMS LABEL BYTE ;AN000;
|
||||
DB 0,1 ;AN000; 1 positional parm
|
||||
DW RESGROUP:COMMAND_FILE ;AN000;
|
||||
DB 6 ;AN000; 6 switches
|
||||
DW RESGROUP:COMMAND_SWITCH1 ;AN000;
|
||||
DW RESGROUP:COMMAND_SWITCH2 ;AN000;
|
||||
DW RESGROUP:COMMAND_SWITCH3 ;AN000;
|
||||
DW RESGROUP:COMMAND_SWITCH4 ;AN000;
|
||||
DW RESGROUP:COMMAND_SWITCH5 ;AN000;
|
||||
DW RESGROUP:COMMAND_SWITCH6 ;AN000;
|
||||
DB 0 ;AN000; no keywords
|
||||
|
||||
COMMAND_FILE LABEL BYTE ;AN000;
|
||||
DW 0201H ;AN000; filespec - optional
|
||||
DW 1 ;AN000; capitalize - file table
|
||||
DW RESGROUP:COMND1_OUTPUT ;AN000; result buffer
|
||||
DW RESGROUP:NO_VAL ;AN000;
|
||||
DB 0 ;AN000; no keywords
|
||||
|
||||
COMMAND_SWITCH1 LABEL BYTE ;AN000;
|
||||
DW 0 ;AN000; no match flags
|
||||
DW 2 ;AN000; capitalize by char table
|
||||
DW RESGROUP:COMND1_OUTPUT ;AN000; result buffer
|
||||
DW RESGROUP:NO_VAL ;AN000;
|
||||
DB 1 ;AN000; 1 keyword
|
||||
COMMAND_P_SYN DB "/P",0 ;AN000; /P switch
|
||||
|
||||
COMMAND_SWITCH2 LABEL BYTE ;AN000;
|
||||
DW 0 ;AN000; no match flags
|
||||
DW 2 ;AN000; capitalize by char table
|
||||
DW RESGROUP:COMND1_OUTPUT ;AN000; result buffer
|
||||
DW RESGROUP:NO_VAL ;AN000;
|
||||
DB 1 ;AN000; 1 keyword
|
||||
COMMAND_F_SYN DB "/F",0 ;AN000; /F switch
|
||||
|
||||
COMMAND_SWITCH3 LABEL BYTE ;AN000;
|
||||
DW 0 ;AN000; no match flags
|
||||
DW 2 ;AN000; capitalize by char table
|
||||
DW RESGROUP:COMND1_OUTPUT ;AN000; result buffer
|
||||
DW RESGROUP:NO_VAL ;AN000;
|
||||
DB 1 ;AN000; 1 keyword
|
||||
COMMAND_D_SYN DB "/D",0 ;AN000; /D switch
|
||||
|
||||
COMMAND_SWITCH4 LABEL BYTE ;AN000;
|
||||
DW 8000H ;AN000; numeric value - required
|
||||
DW 0 ;AN000; no function flags
|
||||
DW RESGROUP:COMND1_OUTPUT ;AN000; result buffer
|
||||
DW RESGROUP:COMMAND_E_VAL ;AN000; pointer to value list
|
||||
DB 1 ;AN000; 1 keyword
|
||||
COMMAND_E_SYN DB "/E",0 ;AN000; /E switch
|
||||
|
||||
COMMAND_E_VAL LABEL BYTE ;AN000;
|
||||
DB 1 ;AN000;
|
||||
DB 1 ;AN000; 1 range
|
||||
DB 1 ;AN000; returned if result
|
||||
DD ENVSML,ENVBIG ;AN000; minimum & maximum value
|
||||
DB 0 ;AN000; no numeric values
|
||||
DB 0 ;AN000; no string values
|
||||
|
||||
COMMAND_SWITCH5 LABEL BYTE ;AN000;
|
||||
DW 0 ;AN000; no match flags
|
||||
DW 2 ;AN000; capitalize by char table
|
||||
DW RESGROUP:COMND1_OUTPUT ;AN000; result buffer
|
||||
DW RESGROUP:NO_VAL ;AN000;
|
||||
DB 1 ;AN000; 1 keyword
|
||||
COMMAND_C_SYN DB "/C",0 ;AN000; /C switch
|
||||
|
||||
COMMAND_SWITCH6 LABEL BYTE ;AN000;
|
||||
DW 0 ;AN000; no match flags
|
||||
DW 2 ;AN000; capitalize by char table
|
||||
DW RESGROUP:COMND1_OUTPUT ;AN000; result buffer
|
||||
DW RESGROUP:NO_VAL ;AN000;
|
||||
DB 1 ;AN000; 1 keyword
|
||||
COMMAND_M_SYN DB "/MSG",0 ;AN000; /MSG switch
|
||||
|
||||
COMND1_OUTPUT LABEL BYTE ;AN000;
|
||||
COMND1_TYPE DB 0 ;AN000; type
|
||||
COMND1_CODE DB 0 ;AN000; return value
|
||||
COMND1_SYN DW 0 ;AN000; synonym pointer
|
||||
COMND1_ADDR DD 0 ;AN000; numeric value / address
|
||||
; of string value
|
||||
|
||||
NO_VAL DB 0 ;AN000; no values
|
||||
num_positionals DW 0 ;AN000; counter for positionals
|
||||
old_parse_ptr DW 0 ;AN057; SI position before calling parser
|
||||
|
||||
.xlist
|
||||
.xcref
|
||||
|
||||
INCLUDE SYSMSG.INC ;AN000; get message services routine
|
||||
|
||||
.list
|
||||
.cref
|
||||
|
||||
ASSUME DS:RESGROUP,ES:RESGROUP,CS:RESGROUP
|
||||
|
||||
MSG_UTILNAME <COMMAND> ;AN000; define utility name
|
||||
|
||||
MSG_SERVICES <COMR,COMMAND.CLB> ;AN000; include initialization messages
|
||||
|
||||
include msgdcl.inc
|
||||
|
||||
INIT ENDS
|
||||
|
||||
END
|
||||
Reference in New Issue
Block a user