diff options
| author | 2024-04-25 21:24:10 +0100 | |
|---|---|---|
| committer | 2024-04-25 22:32:27 +0000 | |
| commit | 2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch) | |
| tree | 80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/CMD/COMMAND | |
| parent | Merge pull request #430 from jpbaltazar/typoptbr (diff) | |
| download | ms-dos-main.tar.gz ms-dos-main.tar.xz ms-dos-main.zip | |
Diffstat (limited to 'v4.0/src/CMD/COMMAND')
43 files changed, 20243 insertions, 0 deletions
diff --git a/v4.0/src/CMD/COMMAND/COMEQU.ASM b/v4.0/src/CMD/COMMAND/COMEQU.ASM new file mode 100644 index 0000000..40273e3 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/COMEQU.ASM | |||
| @@ -0,0 +1,241 @@ | |||
| 1 | ; SCCSID = @(#)comequ.asm 1.1 85/05/14 | ||
| 2 | ; SCCSID = @(#)comequ.asm 1.1 85/05/14 | ||
| 3 | ;************************************* | ||
| 4 | ; COMMAND EQUs which are not switch dependant | ||
| 5 | |||
| 6 | EMGDEBUG = FALSE | ||
| 7 | |||
| 8 | SYM EQU ">" | ||
| 9 | |||
| 10 | LINESPERPAGE EQU 25 ;AC000; default lines per page | ||
| 11 | NORMPERLIN EQU 1 | ||
| 12 | WIDEPERLIN EQU 5 | ||
| 13 | COMBUFLEN EQU 128 ; Length of commmand buffer | ||
| 14 | BatLen EQU 32 ; buffer for batch files | ||
| 15 | YES_ECHO EQU 1 ; echo line | ||
| 16 | NO_ECHO EQU 0 ; don't echo line | ||
| 17 | No_Echo_Char EQU "@" ; don't echo line if this is first char | ||
| 18 | call_in_progress EQU 1 ; indicate we're in the CALL command | ||
| 19 | length_call EQU 4 ; length of CALL | ||
| 20 | max_nest EQU 10 ; max # levels of batch nesting allowed | ||
| 21 | fail_allowed EQU 00001000b ; critical error | ||
| 22 | retry_allowed EQU 00010000b ; critical error | ||
| 23 | Ignore_allowed EQU 00100000b ; critical error | ||
| 24 | nullcommand EQU 1 ; no command on command line | ||
| 25 | end_of_line EQU -1 ;AN000; end of line return from parser | ||
| 26 | end_of_line_out EQU 0 ;AN000; end of line for output | ||
| 27 | end_of_line_in EQU 0dh ;AN000; end of line for input | ||
| 28 | result_number EQU 1 ;AN000; number returned from parser | ||
| 29 | result_string EQU 3 ;AN000; string returned from parser | ||
| 30 | result_filespec EQU 5 ;AN000; filespec returned from parser | ||
| 31 | result_drive EQU 6 ;AN000; drive returned from parser | ||
| 32 | result_date EQU 7 ;AN000; date returned from parser | ||
| 33 | result_time EQU 8 ;AN000; time returned from parser | ||
| 34 | result_no_error EQU 0 ;AN000; no error returned from parser | ||
| 35 | no_cont_flag EQU 0 ;AN000; no control flags for message | ||
| 36 | util_msg_class EQU -1 ;AN000; message class for utility | ||
| 37 | ext_msg_class EQU 1 ;AN000; message class for extended error | ||
| 38 | parse_msg_class EQU 2 ;AN000; message class for parse error | ||
| 39 | crit_msg_class EQU 3 ;AN000; message class for critical error | ||
| 40 | ext_crlf_class EQU 081h ;AN054; message class for extended error with no CRLF | ||
| 41 | colon_char EQU ":" ;AN000; colon character | ||
| 42 | crt_ioctl_ln EQU 14 ;AN000; default length of data for display ioctl | ||
| 43 | text_mode EQU 1 ;AN000; text mode return from ioctl | ||
| 44 | get_generic EQU 07Fh ;AN000; generic ioctl - get device info | ||
| 45 | set_crit_dev EQU 0100H ;AN000; device attribute for critical error on I/0 | ||
| 46 | mult_ansi EQU 01Ah ;AC064; multiplex for ansi.sys | ||
| 47 | mult_shell_get EQU 01902h ;AC065; multiplex for Shell - get next command | ||
| 48 | mult_shell_brk EQU 01903h ;AN000; multiplex for Shell - ^C batch check | ||
| 49 | shell_action equ 0ffh ;AN000; SHELL - return for taking SHELL specific action | ||
| 50 | bat_not_open EQU -1 ;AN000; batch handle will be set to this if not open | ||
| 51 | bat_open_handle EQU 19 ;AN000; handle will be in this position in JFN table | ||
| 52 | Ptr_seg_pos equ 7 ;AN000; Offset from start of message block for subst segment | ||
| 53 | Ptr_off_pos equ 5 ;AN000; Offset from start of message block for subst offset | ||
| 54 | Parm_off_pos equ word ptr 2 ;AN000; Offset from start of subst list for subst offset | ||
| 55 | parm_block_size equ 11 ;AN000; size of message subst block | ||
| 56 | blank equ " " ;AN000; blank character | ||
| 57 | no_subst equ 0 ;AN000; no substitutions for messages | ||
| 58 | one_subst equ 1 ;AN000; one substitution for messages | ||
| 59 | no_handle_out equ -1 ;AN000; use function 1 thru 12 for message retriever | ||
| 60 | res_subst equ 2 ;AN000; offset from start of message definition to number of subst | ||
| 61 | read_open_mode equ 0000000000000000b ;AN024; extended open mode for read | ||
| 62 | read_open_flag equ 0000000100000001b ;AN000; extended open flags for read | ||
| 63 | write_open_mode equ 0000000000000001b ;AN024; extended open mode for read | ||
| 64 | write_open_flag equ 0000000100000001b ;AN000; extended open flags for read | ||
| 65 | creat_open_flag equ 0000000100010010b ;AN000; extended open flags for read | ||
| 66 | get_CPSW equ 3 ;AN000; minor function for get CPSW status | ||
| 67 | CPSW_off equ 0 ;AN000; CPSW return from function - OFF | ||
| 68 | Get_XA equ 2 ;AN030; minor function for get extended attributes | ||
| 69 | Set_XA equ 4 ;AN000; minor function for set extended attributes | ||
| 70 | file_no_cpage equ 0 ;AN000; file has no code page tag | ||
| 71 | file_inv_cpage equ -1 ;AN000; file has invalid code page tag | ||
| 72 | do_xa equ -1 ;AN000; flag to get extended attributes | ||
| 73 | inv_cp_tag equ 0 ;AC039; tag for invalid code page | ||
| 74 | no_xa_seg equ -1 ;AN000; no segment for extended attributes - COPY | ||
| 75 | capital_A equ 'A' ;AC000; | ||
| 76 | vbar equ '|' ;AC000; | ||
| 77 | labracket equ '<' ;AC000; | ||
| 78 | rabracket equ '>' ;AC000; | ||
| 79 | dollar equ '$' ;AC000; | ||
| 80 | lparen equ '(' ;AC000; | ||
| 81 | rparen equ ')' ;AC000; | ||
| 82 | nullrparen equ 29h ;AC000; | ||
| 83 | in_word equ 4e49h ;AC000; 'NI' ('IN' backwards) | ||
| 84 | do_word equ 4f44h ;AC000; 'OD' ('DO' backwards) | ||
| 85 | star equ '*' ;AC000; | ||
| 86 | plus_chr equ '+' ;AC000; | ||
| 87 | small_a equ 'a' ;AC000; | ||
| 88 | small_z equ 'z' ;AC000; | ||
| 89 | dot_chr equ '.' ;AC000; | ||
| 90 | tab_chr equ 9 ;AN032; | ||
| 91 | equal_chr equ '=' ;AN032; | ||
| 92 | semicolon equ ';' ;AN049; | ||
| 93 | dot_qmark equ 2e3fh ;AC000; '.?' | ||
| 94 | dot_colon equ 2e3ah ;AC000; '.:' | ||
| 95 | capital_n equ 0 ;AC000; result from Y/N call if N entered | ||
| 96 | capital_y equ 1 ;AC000; result from Y/N call if Y entered | ||
| 97 | AppendInstall equ 0B700H ;AN020; append install check | ||
| 98 | AppendDOS equ 0B702H ;AN020; append DOS version check | ||
| 99 | AppendGetState equ 0B706H ;AN020; append get current state | ||
| 100 | AppendSetState equ 0B707H ;AN020; append set current state | ||
| 101 | AppendTruename equ 0B711H ;AN042; Get file's real location for Batch | ||
| 102 | search_attr equ attr_read_only+attr_hidden+attr_directory ;AC042; | ||
| 103 | |||
| 104 | ;************************************* | ||
| 105 | ;* PARSE ERROR MESSAGES | ||
| 106 | ;************************************* | ||
| 107 | |||
| 108 | MoreArgs_Ptr equ 1 ;AN000;"Too many parameters" message number | ||
| 109 | LessArgs_Ptr equ 2 ;AN000;"Required parameter missing" message number | ||
| 110 | BadSwt_Ptr equ 3 ;AN000;"Invalid switch" message number | ||
| 111 | BadParm_Ptr equ 10 ;AN000;"Invalid parameter" message number | ||
| 112 | |||
| 113 | ;************************************* | ||
| 114 | ;* EQUATES FOR MESSAGE RETRIEVER | ||
| 115 | ;************************************* | ||
| 116 | |||
| 117 | GET_EXTENDED_MSG EQU 0 ;AN000; get extended message address | ||
| 118 | SET_EXTENDED_MSG EQU 1 ;AN000; set extended message address | ||
| 119 | GET_PARSE_MSG EQU 2 ;AN000; get parse message address | ||
| 120 | SET_PARSE_MSG EQU 3 ;AN000; set parse message address | ||
| 121 | GET_CRITICAL_MSG EQU 4 ;AN000; get critical message address | ||
| 122 | SET_CRITICAL_MSG EQU 5 ;AN000; set critical message address | ||
| 123 | MESSAGE_2F EQU 46 ;AN000; minor code for message retriever | ||
| 124 | |||
| 125 | ;********************************* | ||
| 126 | ;* EQUATES FOR INT 10H | ||
| 127 | ;********************************* | ||
| 128 | |||
| 129 | VIDEO_IO_INT EQU 10H ;AN000; equate for int 10h | ||
| 130 | SET_VIDEO_MODE EQU 0 ;AN000; set video mode | ||
| 131 | SET_CURSOR_POSITION EQU 2 ;AN000; set new cursor position | ||
| 132 | SCROLL_VIDEO_PAGE EQU 6 ;AN000; scroll active page up | ||
| 133 | VIDEO_ATTRIBUTE EQU 7 ;AN000; attribute to be used on blank line | ||
| 134 | SET_COLOR_PALETTE EQU 11 ;AN000; set color for video | ||
| 135 | GET_VIDEO_STATE EQU 15 ;AN000; get current video state | ||
| 136 | VIDEO_ALPHA EQU 3 ;AN000; alpha video is 3 or below | ||
| 137 | VIDEO_BW EQU 7 ;AN000; mode for 80X25 black & white | ||
| 138 | |||
| 139 | AltPipeChr equ "|" ; alternate pipe character | ||
| 140 | |||
| 141 | FCB EQU 5CH | ||
| 142 | |||
| 143 | VARSTRUC STRUC | ||
| 144 | ISDIR DB ? | ||
| 145 | SIZ DB ? | ||
| 146 | TTAIL DW ? | ||
| 147 | INFO DB ? | ||
| 148 | BUF DB DIRSTRLEN + 20 DUP (?) | ||
| 149 | VARSTRUC ENDS | ||
| 150 | |||
| 151 | fCheckDrive equ 00000001b | ||
| 152 | fSwitchAllowed equ 00000010b | ||
| 153 | |||
| 154 | ; | ||
| 155 | ; Test switches | ||
| 156 | ; | ||
| 157 | fParse EQU 0001h ; display results of parseline | ||
| 158 | |||
| 159 | ; | ||
| 160 | ; Batch segment structure | ||
| 161 | ; | ||
| 162 | ; BYTE type of segment | ||
| 163 | ; BYTE echo state of parent on entry to batch file | ||
| 164 | ; WORD segment of last batch file | ||
| 165 | ; WORD segment for FOR command | ||
| 166 | ; BYTE FOR flag state on entry to batch file | ||
| 167 | ; DWORD offset for next line | ||
| 168 | ; 10 WORD pointers to parameters. -1 is empty parameter | ||
| 169 | ; ASCIZ file name (with . and ..) | ||
| 170 | ; BYTES CR-terminated parameters | ||
| 171 | ; BYTE 0 flag to indicate end of parameters | ||
| 172 | ; | ||
| 173 | |||
| 174 | BatchType equ 0 | ||
| 175 | |||
| 176 | BatchSegment struc | ||
| 177 | BatType DB BatchType ; signature | ||
| 178 | Batechoflag DB 0 ; G state of echo | ||
| 179 | Batlast DW 0 ; G segment of last batch file | ||
| 180 | Batforptr DW 0 ; G segment for FOR command | ||
| 181 | Batforflag DB 0 ; G state of FOR | ||
| 182 | BatSeek DD ? ; lseek position of next char | ||
| 183 | BatParm DW 10 dup (?) ; pointers to parameters | ||
| 184 | BatFile DB ? ; beginning of batch file name | ||
| 185 | BatchSegment ends | ||
| 186 | |||
| 187 | ANULL equ 0 ; terminates an argv string | ||
| 188 | ARGMAX equ 64 ; max args on a command line | ||
| 189 | ARGBLEN equ 2*128 ; 1char each plus term NUL | ||
| 190 | tplen equ 64 ; max size of one argument | ||
| 191 | arg_cnt_error equ 1 ; number of args > MAXARG | ||
| 192 | arg_buf_ovflow equ 2 ; overflowed argbuffer | ||
| 193 | |||
| 194 | argv_ele STRUC ; elements in the argv array | ||
| 195 | argpointer DW (?) ; pointer to the argstring | ||
| 196 | argflags DB (?) ; cparse flags for this argstring | ||
| 197 | argstartel DW (?) ; the result of cparse's [STARTEL] | ||
| 198 | arglen DW (?) ; cparse's char count + one (for null) | ||
| 199 | argsw_word DW (?) ; any switches after this? what kinds? | ||
| 200 | arg_ocomptr DW (?) ; pointer into original command string | ||
| 201 | argv_ele ENDS | ||
| 202 | |||
| 203 | arg_unit STRUC | ||
| 204 | argv DB (ARGMAX * SIZE argv_ele) DUP (?) | ||
| 205 | argvcnt DW (?) ; number of arguments | ||
| 206 | argswinfo DW (?) ; Switch information for entire line | ||
| 207 | argbuf DW ARGBLEN DUP (?) ; storage for argv strings | ||
| 208 | argforcombuf db COMBUFLEN DUP (?) ; Original for loop command string | ||
| 209 | arg_unit ENDS | ||
| 210 | |||
| 211 | parseflags RECORD special_delim:1, unused:4, path_sep:1, wildcard:1, sw_flag:1 | ||
| 212 | |||
| 213 | SwitchV EQU 10h | ||
| 214 | SwitchB EQU 08h | ||
| 215 | SwitchA EQU 04h | ||
| 216 | SwitchP EQU 02h | ||
| 217 | SwitchW EQU 01h | ||
| 218 | fSwitch EQU 8000h | ||
| 219 | fBadSwitch EQU 4000h | ||
| 220 | |||
| 221 | SwitchDir EQU SwitchP + SwitchW + fSwitch | ||
| 222 | SwitchCopy EQU SwitchV + SwitchA + SwitchB + fSwitch | ||
| 223 | |||
| 224 | break <Trap: Get the attention of MSDOS> | ||
| 225 | ; TRAP snares the operating system for a service call | ||
| 226 | ; AX, as well as any other registers MS-DOS takes a fancy to, will be crunched. | ||
| 227 | trap MACRO dos_function,dos_info | ||
| 228 | ifnb <dos_info> | ||
| 229 | mov AX, (dos_function SHL 8) + dos_info | ||
| 230 | else | ||
| 231 | mov AX, (dos_function SHL 8) | ||
| 232 | endif | ||
| 233 | int int_command | ||
| 234 | ENDM | ||
| 235 | |||
| 236 | ; | ||
| 237 | ; Equates for initialization | ||
| 238 | ; | ||
| 239 | initInit equ 01h ; initialization in progress | ||
| 240 | initSpecial equ 02h ; in initialization time/date routine | ||
| 241 | initCtrlC equ 04h ; already in ^C handler | ||
diff --git a/v4.0/src/CMD/COMMAND/COMMAND.LNK b/v4.0/src/CMD/COMMAND/COMMAND.LNK new file mode 100644 index 0000000..29a639a --- /dev/null +++ b/v4.0/src/CMD/COMMAND/COMMAND.LNK | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | /map COMMAND1.OBJ COMMAND2.OBJ RUCODE.OBJ RDATA.OBJ INIT.OBJ IPARSE.OBJ + | ||
| 2 | UINIT.OBJ TCODE.OBJ TBATCH.OBJ TBATCH2.OBJ TFOR.OBJ TCMD1A.OBJ TCMD1B.OBJ + | ||
| 3 | TCMD2A.OBJ TCMD2B.OBJ TENV.OBJ TENV2.OBJ TMISC1.OBJ TMISC2.OBJ TPIPE.OBJ + | ||
| 4 | PARSE2.OBJ PATH1.OBJ PATH2.OBJ TUCODE.OBJ COPY.OBJ COPYPR1.OBJ COPYPR2.OBJ + | ||
| 5 | CPARSE.OBJ TPARSE.OBJ TPRINTF.OBJ TDATA.OBJ TSPC.OBJ,COMMAND.EXE,,; | ||
| 6 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/COMMAND/COMMAND.SKL b/v4.0/src/CMD/COMMAND/COMMAND.SKL new file mode 100644 index 0000000..44b1eef --- /dev/null +++ b/v4.0/src/CMD/COMMAND/COMMAND.SKL | |||
| @@ -0,0 +1,213 @@ | |||
| 1 | |||
| 2 | ;************************* | ||
| 3 | ;* MESSAGE SKELETON FILE * | ||
| 4 | ;************************* | ||
| 5 | |||
| 6 | :util COMMAND ;AC000; | ||
| 7 | |||
| 8 | :class 1 ;AC000; Transient extended errors | ||
| 9 | |||
| 10 | :use EXTEND2 ;AC000; "File not found" | ||
| 11 | :use EXTEND3 ;AC000; "Path not found" | ||
| 12 | :use EXTEND8 ;AC000; "Insufficient memory" | ||
| 13 | |||
| 14 | :class 2 ;AC000; Transient parse errors | ||
| 15 | |||
| 16 | :class 3 ;AC000; Resident extended errors | ||
| 17 | :use -1 EXTEND999 ;AN000; "Extended error #" | ||
| 18 | |||
| 19 | :class 4 ;AC000; Resident parse errors | ||
| 20 | :use -1 PARSE999 ;AN000; "Parse error #" | ||
| 21 | |||
| 22 | :class A ;AC000; resident messages | ||
| 23 | |||
| 24 | :use 220 COMMON17 ;AC000; "File allocation table bad, drive %1" | ||
| 25 | :use 223 COMMON28 ;AC000; "Press any key to continue" | ||
| 26 | :def 201 "A" ;AC000; | ||
| 27 | :def 202 "R" ;AC000; | ||
| 28 | :def 203 "I" ;AC000; | ||
| 29 | :def 204 "F" ;AC000; | ||
| 30 | :def 205 "Y" ;AC000; | ||
| 31 | :def 206 "N" ;AC000; | ||
| 32 | :def 210 "Abort" ;AC000; | ||
| 33 | :def 211 ", Retry" ;AC000; | ||
| 34 | :def 212 ", Ignore" ;AC000; | ||
| 35 | :def 213 ", Fail" ;AC000; | ||
| 36 | :def 214 "?" ;AC000; | ||
| 37 | :def 215 "reading",0 ;AC000; | ||
| 38 | :def 216 "writing",0 ;AC000; | ||
| 39 | :def 217 " %1 drive %2",CR,LF ;AC000; | ||
| 40 | :def 218 " %1 device %2",CR,LF ;AC000; | ||
| 41 | :def 219 "Please insert volume %1 serial %2-%3",CR,LF ;AC009; | ||
| 42 | :def 221 "Invalid COMMAND.COM",CR,LF ;AC000; | ||
| 43 | :def 222 "Insert disk with %1 in drive %2",CR,LF ;AC000; | ||
| 44 | :def 224 CR,LF,"Terminate batch job (Y/N)?" ;AC000; | ||
| 45 | :def 225 "Cannot execute %1",CR,LF ;AC000; | ||
| 46 | :def 226 "Error in EXE file",CR,LF ;AC000; | ||
| 47 | :def 227 "Program too big to fit in memory",CR,LF ;AC000; | ||
| 48 | :def 228 CR,LF,"No free file handles" ;AC000; | ||
| 49 | :def 229 "Bad Command or file name",CR,LF ;AC000; | ||
| 50 | :use 230 EXTEND5 ;AC000; | ||
| 51 | :def 231 CR,LF,"Memory allocation error" ;AC000; | ||
| 52 | :def 232 CR,LF,"Cannot load COMMAND, system halted",CR,LF;AC000; | ||
| 53 | :def 233 CR,LF,"Cannot start COMMAND, exiting",CR,LF ;AC000; | ||
| 54 | :def 234 CR,LF,"Top level process aborted, cannot continue",CR,LF;AC000; | ||
| 55 | :def 235 CR,LF ;AC000; | ||
| 56 | |||
| 57 | |||
| 58 | :class B ;AC000; Initialization messages | ||
| 59 | |||
| 60 | :use 461 COMMON1 ;AC000; "Incorrect DOS version" | ||
| 61 | :def 463 "Out of environment space",CR,LF ;AC000; | ||
| 62 | :def 464 CR,LF,CR,LF,"MS DOS ",CR,LF | ||
| 63 | "Version 4.00 (C)Copyright International Business Machines Corp 1981,1988",CR,LF | ||
| 64 | " (C)Copyright Microsoft Corp 1981, 1988",CR,LF ;AC000; | ||
| 65 | :def 465 "Specified COMMAND search directory bad",CR,LF ;AC025; | ||
| 66 | :def 466 "Specified COMMAND search directory bad access denied",CR,LF ;AC025; | ||
| 67 | |||
| 68 | :class C ;AC000; Parse messages | ||
| 69 | |||
| 70 | :use PARSE1 ;AC000; "Too many parameters" | ||
| 71 | :use PARSE2 ;AC000; "Required parameter missing" | ||
| 72 | :use PARSE3 ;AC000; "Invalid switch" | ||
| 73 | :use PARSE4 ;AC000; "Invalid keyword" | ||
| 74 | :use PARSE6 ;AC000; "Parameter value not in allowed range" | ||
| 75 | :use PARSE7 ;AC000; "Parameter value not allowed" | ||
| 76 | :use PARSE8 ;AC000; "Parameter value not allowed" | ||
| 77 | :use PARSE9 ;AC000; "Parameter format not correct" | ||
| 78 | :use PARSE10 ;AC000; "Invalid parameter" | ||
| 79 | :use PARSE11 ;AC000; "Invalid parameter combination" | ||
| 80 | |||
| 81 | :class D ;AC000; Extended errors - critical | ||
| 82 | |||
| 83 | :use EXTEND19 ;AC000; "Write protect" | ||
| 84 | :use EXTEND20 ;AC000; "Invalid unit" | ||
| 85 | :use EXTEND21 ;AC000; "Drive not ready" | ||
| 86 | :use EXTEND22 ;AC000; "Invalid device request" | ||
| 87 | :use EXTEND23 ;AC000; "Data error" | ||
| 88 | :use EXTEND24 ;AC000; "Invalid device request parameters" | ||
| 89 | :use EXTEND25 ;AC000; "Seek error" | ||
| 90 | :use EXTEND26 ;AC000; "Invalid media type" | ||
| 91 | :use EXTEND27 ;AC000; "Sector not found" | ||
| 92 | :use EXTEND28 ;AC000; "Printer out of paper" | ||
| 93 | :use EXTEND29 ;AC000; "Write fault error" | ||
| 94 | :use EXTEND30 ;AC000; "Read fault error" | ||
| 95 | :use EXTEND31 ;AC000; "General Failure" | ||
| 96 | :use EXTEND32 ;AC000; "Sharing Violation" | ||
| 97 | :use EXTEND33 ;AC000; "Lock Violation" | ||
| 98 | :use EXTEND34 ;AC000; "Invalid Disk Change" | ||
| 99 | :use EXTEND35 ;AC000; "FCB unavailable" | ||
| 100 | :use EXTEND36 ;AC000; "System resource exhausted" | ||
| 101 | :use EXTEND37 ;AC000; "Code page mismatch" | ||
| 102 | :use EXTEND38 ;AC026; "Out of input" | ||
| 103 | :use EXTEND39 ;AC026; "Insufficient disk space" | ||
| 104 | |||
| 105 | :class E ;AC000; extended errors | ||
| 106 | |||
| 107 | :use EXTEND1 ;AC000; "Invalid Function" | ||
| 108 | :use EXTEND2 ;AC000; "File not found" | ||
| 109 | :use EXTEND3 ;AC000; "Path not found" | ||
| 110 | :use EXTEND4 ;AC000; "Too many open files" | ||
| 111 | :use EXTEND5 ;AC000; "Access denied" | ||
| 112 | :use EXTEND6 ;AC000; "Invalid handle" | ||
| 113 | :use EXTEND7 ;AC000; "Memory control blocks destroyed" | ||
| 114 | :use EXTEND8 ;AC000; "Insufficient memory" | ||
| 115 | :use EXTEND9 ;AC000; "Invalid memory block address" | ||
| 116 | :use EXTEND10 ;AC000; "Invalid Environment" | ||
| 117 | :use EXTEND11 ;AC000; "Invalid format" | ||
| 118 | :use EXTEND12 ;AC000; "Invalid function parameter" | ||
| 119 | :use EXTEND13 ;AC000; "Invalid data" | ||
| 120 | :use EXTEND15 ;AC000; "Invalid drive specification" | ||
| 121 | :use EXTEND16 ;AC000; "Attempt to remove current directory" | ||
| 122 | :use EXTEND17 ;AC000; "Not same device" | ||
| 123 | :use EXTEND18 ;AC000; "No more files" | ||
| 124 | :use EXTEND80 ;AC000; "File already exists" | ||
| 125 | :use EXTEND82 ;AC000; "Can not make directory entry" | ||
| 126 | :use EXTEND83 ;AC000; "Fail requested to Critical Error" | ||
| 127 | :use EXTEND84 ;AC000; "Too many attaches" | ||
| 128 | :use EXTEND85 ;AC000; "Device or file already attached" | ||
| 129 | :use EXTEND86 ;AC000; "Invalid password" | ||
| 130 | :use EXTEND87 ;AC000; "Invalid parameter" | ||
| 131 | :use EXTEND88 ;AC000; "File system data fault" | ||
| 132 | :use EXTEND89 ;AC000; "Function not supported by file system" | ||
| 133 | :use EXTEND90 ;AC000; | ||
| 134 | |||
| 135 | |||
| 136 | :class F ;AC000; Transient messages | ||
| 137 | |||
| 138 | :use 1020 COMMON4 ;AC000; "%1 bytes free",CR,LF | ||
| 139 | :use 1015 COMMON18 ;AC000; "File cannot be copied onto itself",CR,LF | ||
| 140 | :use 1004 COMMON20 ;AC000; "Insufficient disk space",CR,LF | ||
| 141 | :use 1026 COMMON22 ;AC000; "Invalid code page",CR,LF | ||
| 142 | :use 1031 COMMON23 ;AC000; "Invalid date" | ||
| 143 | :use 1035 COMMON24 ;AC000; "Invalid time" | ||
| 144 | :use 1062 COMMON25 ;AC000; "Invalid path" | ||
| 145 | :use 1028 COMMON28 ;AC000; "Press any key to continue" | ||
| 146 | :use 1045 COMMON32 ;AC000; "Unable to create directory",CR,LF | ||
| 147 | :use 1041 COMMON33 ;AC000; "Volume in drive %1 has no label" | ||
| 148 | :use 1042 COMMON34 ;AC000; "Volume in drive %1 is %2" | ||
| 149 | :use 1043 COMMON36 ;AC000; "Volume Serial Number is %1" | ||
| 150 | :def 1002 "Duplicate file name or file not found",CR,LF ;AC000; | ||
| 151 | :def 1003 "Invalid path or file name",CR,LF ;AC000; | ||
| 152 | :def 1007 "Out of environment space",CR,LF ;AC000; | ||
| 153 | :def 1008 "File creation error",CR,LF ;AC000; | ||
| 154 | :def 1009 "Batch file missing",CR,LF ;AC000; | ||
| 155 | :def 1010 CR,LF,"Insert disk with batch file",CR,LF ;AC000; | ||
| 156 | :def 1011 "Bad command or file name",CR,LF ;AC000; | ||
| 157 | :use 1014 EXTEND5 ;AC000; | ||
| 158 | :def 1016 "Content of destination lost before copy",CR,LF ;AC000; | ||
| 159 | :def 1017 "Invalid filename or file not found",CR,LF ;AC000; | ||
| 160 | :def 1018 "%1 File(s) copied",CR,LF ;AC000; | ||
| 161 | :def 1019 "%1 File(s) " ;AC000; | ||
| 162 | :use 1021 EXTEND15 ;AC000; | ||
| 163 | :def 1022 "Code page %1 not prepared for system",CR,LF ;AC000; | ||
| 164 | :def 1023 "Code page %1 not prepared for all devices",CR,LF ;AC000; | ||
| 165 | :def 1024 "Active code page: %1",CR,LF ;AC000; | ||
| 166 | :def 1025 "NLSFUNC not installed",CR,LF ;AC000; | ||
| 167 | :def 1027 "Current drive is no longer valid" ;AC000; | ||
| 168 | :def 1029 "Label not found",CR,LF ;AC000; | ||
| 169 | :def 1030 "Syntax error",CR,LF ;AC000; | ||
| 170 | :def 1032 "Current date is %1 %2",CR,LF ;AC000; | ||
| 171 | :def 1033 "SunMonTueWedThuFriSat" ;AC000; | ||
| 172 | :def 1034 "Enter new date (%1): " ;AC031; | ||
| 173 | :def 1036 "Current time is %1",CR,LF ;AC000; | ||
| 174 | :def 1037 "Enter new time: " ;AC031; | ||
| 175 | :def 1038 ", Delete (Y/N)?" ;AC000; | ||
| 176 | :def 1039 "All files in directory will be deleted!",CR,LF | ||
| 177 | "Are you sure (Y/N)?" ;AC000; | ||
| 178 | :def 1040 "Microsoft DOS Version %1.%2",CR,LF ;AC000; | ||
| 179 | :def 1044 "Invalid directory",CR,LF ;AC000; | ||
| 180 | :def 1046 "Invalid path, not directory,",CR,LF,"or directory not empty",CR,LF ;AC000; | ||
| 181 | :def 1047 "Must specify ON or OFF",CR,LF ;AC000; | ||
| 182 | :def 1048 "Directory of %1",CR,LF ;AC000; | ||
| 183 | :def 1049 "No Path",CR,LF ;AC000; | ||
| 184 | :def 1050 "Invalid drive in search path",CR,LF ;AC000; | ||
| 185 | :def 1051 "Invalid device",CR,LF ;AC000; | ||
| 186 | :def 1052 "FOR cannot be nested",CR,LF ;AC000; | ||
| 187 | :def 1053 "Intermediate file error during pipe",CR,LF ;AC000; | ||
| 188 | :def 1054 "Cannot do binary reads from a device",CR,LF ;AC000; | ||
| 189 | :def 1055 "BREAK is %1",CR,LF ;AC000; | ||
| 190 | :def 1056 "VERIFY is %1",CR,LF ;AC000; | ||
| 191 | :def 1057 "ECHO is %1",CR,LF ;AC000; | ||
| 192 | :def 1059 "off",0 ;AC000; | ||
| 193 | :def 1060 "on",0 ;AC000; | ||
| 194 | :def 1061 "Error writing to device",CR,LF ;AC000; | ||
| 195 | :def 1063 "%1" ;AC000; | ||
| 196 | :def 1064 "%1" ;AC000; | ||
| 197 | :def 1065 "%1" ;AC000; | ||
| 198 | :def 1066 "%1" ;AC000; | ||
| 199 | :def 1067 9 ;AC000; | ||
| 200 | :def 1068 " <DIR> " ;AC000; | ||
| 201 | :def 1069 8," ",8 ;AC000; | ||
| 202 | :def 1070 CR,LF ;AC000; | ||
| 203 | :def 1071 "%1" ;AC000; | ||
| 204 | :def 1072 "mm-dd-yy" ;AC000; | ||
| 205 | :def 1073 "dd-mm-yy" ;AC000; | ||
| 206 | :def 1074 "yy-mm-dd" ;AC000; | ||
| 207 | :def 1075 "%1 %2" ;AC000; | ||
| 208 | :def 1076 "%1" ;AC000; | ||
| 209 | :def 1077 " %1 %2" ;AC053; | ||
| 210 | :def 1078 "Directory already exists",CR,LF ;AC000; | ||
| 211 | |||
| 212 | :end ;AC000; | ||
| 213 | |||
diff --git a/v4.0/src/CMD/COMMAND/COMMAND1.ASM b/v4.0/src/CMD/COMMAND/COMMAND1.ASM new file mode 100644 index 0000000..3ee909a --- /dev/null +++ b/v4.0/src/CMD/COMMAND/COMMAND1.ASM | |||
| @@ -0,0 +1,638 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)command1.asm 1.1 85/05/14 | ||
| 3 | ; SCCSID = @(#)command1.asm 1.1 85/05/14 | ||
| 4 | TITLE COMMAND - resident code for COMMAND.COM | ||
| 5 | NAME COMMAND | ||
| 6 | |||
| 7 | ;***************************************************************************** | ||
| 8 | ; | ||
| 9 | ; MODULE: COMMAND.COM | ||
| 10 | ; | ||
| 11 | ; DESCRIPTIVE NAME: Default DOS command interpreter | ||
| 12 | ; | ||
| 13 | ; FUNCTION: This version of COMMAND is divided into three distinct | ||
| 14 | ; parts. First is the resident portion, which includes | ||
| 15 | ; handlers for interrupts 23H (Cntrl-C), 24H (fatal | ||
| 16 | ; error), and 2EH (command line execute); it also has | ||
| 17 | ; code to test and, if necessary, reload the transient | ||
| 18 | ; portion. Following the resident is the init code, which | ||
| 19 | ; is overwritten after use. Then comes the transient | ||
| 20 | ; portion, which includes all command processing (whether | ||
| 21 | ; internal or external). The transient portion loads at | ||
| 22 | ; the end of physical memory, and it may be overlayed by | ||
| 23 | ; programs that need as much memory as possible. When the | ||
| 24 | ; resident portion of command regains control from a user | ||
| 25 | ; program, a check sum is performed on the transient | ||
| 26 | ; portion to see if it must be reloaded. Thus programs | ||
| 27 | ; which do not need maximum memory will save the time | ||
| 28 | ; required to reload COMMAND when they terminate. | ||
| 29 | ; | ||
| 30 | ; ENTRY POINT: PROGSTART | ||
| 31 | ; | ||
| 32 | ; INPUT: command line at offset 81H | ||
| 33 | ; | ||
| 34 | ; EXIT_NORMAL: No exit from root level command processor. Can exit | ||
| 35 | ; from a secondary command processor via the EXIT | ||
| 36 | ; internal command. | ||
| 37 | ; | ||
| 38 | ; EXIT_ERROR: Exit to prior command processor if possible, otherwise | ||
| 39 | ; hang the system. | ||
| 40 | ; | ||
| 41 | ; INTERNAL REFERENCES: | ||
| 42 | ; | ||
| 43 | ; ROUTINES: See the COMMAND Subroutine Description Document | ||
| 44 | ; (COMMAND.DOC) | ||
| 45 | ; | ||
| 46 | ; DATA AREAS: See the COMMAND Subroutine Description Document | ||
| 47 | ; (COMMAND.DOC) | ||
| 48 | ; | ||
| 49 | ; EXTERNAL REFERENCES: | ||
| 50 | ; | ||
| 51 | ; ROUTINES: none | ||
| 52 | ; | ||
| 53 | ; DATA AREAS: none | ||
| 54 | ; | ||
| 55 | ;***************************************************************************** | ||
| 56 | ; | ||
| 57 | ; REVISION HISTORY | ||
| 58 | ; ---------------- | ||
| 59 | ; | ||
| 60 | ; DOS 1.00 to DOS 3.30 | ||
| 61 | ; -------------------------- | ||
| 62 | ; SEE REVISION LOG IN COPY.ASM ALSO | ||
| 63 | ; | ||
| 64 | ; REV 1.17 | ||
| 65 | ; 05/19/82 Fixed bug in BADEXE error (relocation error must return to | ||
| 66 | ; resident since the EXELOAD may have overwritten the transient. | ||
| 67 | ; | ||
| 68 | ; REV 1.18 | ||
| 69 | ; 05/21/82 IBM version always looks on drive A | ||
| 70 | ; MSVER always looks on default drive | ||
| 71 | ; | ||
| 72 | ; REV 1.19 | ||
| 73 | ; 06/03/82 Drive spec now entered in command line | ||
| 74 | ; 06/07/82 Added VER command (print DOS version number) and VOL command | ||
| 75 | ; (print volume label) | ||
| 76 | ; | ||
| 77 | ; REV 1.20 | ||
| 78 | ; 06/09/82 Prints "directory" after directories | ||
| 79 | ; 06/13/82 MKDIR, CHDIR, PWD, RMDIR added | ||
| 80 | ; | ||
| 81 | ; REV 1.50 | ||
| 82 | ; Some code for new 2.0 DOS, sort of HACKey. Not enough time to | ||
| 83 | ; do it right. | ||
| 84 | ; | ||
| 85 | ; REV 1.70 | ||
| 86 | ; EXEC used to fork off new processes | ||
| 87 | ; | ||
| 88 | ; REV 1.80 | ||
| 89 | ; C switch for single command execution | ||
| 90 | ; | ||
| 91 | ; REV 1.90 | ||
| 92 | ; Batch uses XENIX | ||
| 93 | ; | ||
| 94 | ; Rev 2.00 | ||
| 95 | ; Lots of neato stuff | ||
| 96 | ; IBM 2.00 level | ||
| 97 | ; | ||
| 98 | ; Rev 2.01 | ||
| 99 | ; 'D' switch for date time suppression | ||
| 100 | ; | ||
| 101 | ; Rev 2.02 | ||
| 102 | ; Default userpath is NUL rather than BIN | ||
| 103 | ; same as IBM | ||
| 104 | ; COMMAND split into pieces | ||
| 105 | ; | ||
| 106 | ; Rev 2.10 | ||
| 107 | ; INTERNATIONAL SUPPORT | ||
| 108 | ; | ||
| 109 | ; Rev 2.50 | ||
| 110 | ; all the 2.x new stuff -MU | ||
| 111 | ; | ||
| 112 | ; Rev 3.30 (Ellen G) | ||
| 113 | ; CALL internal command (TBATCH2.ASM) | ||
| 114 | ; CHCP internal command (TCMD2B.ASM) | ||
| 115 | ; INT 24H support of abort, retry, ignore, and fail prompt | ||
| 116 | ; @ sign suppression of batch file line | ||
| 117 | ; Replaceable environment value support in batch files | ||
| 118 | ; INT 2FH calls for APPEND | ||
| 119 | ; Lots of PTR fixes! | ||
| 120 | ; | ||
| 121 | ; Beyond 3.30 to forever (Ellen G) | ||
| 122 | ; ---------------------- | ||
| 123 | ; | ||
| 124 | ; A000 DOS 4.00 - Use SYSPARSE for internal commands | ||
| 125 | ; Use Message Retriever services | ||
| 126 | ; /MSG switch for resident extended error msg | ||
| 127 | ; Convert to new capitalization support | ||
| 128 | ; Better error recovery on CHCP command | ||
| 129 | ; Code page file tag support | ||
| 130 | ; TRUENAME internal command | ||
| 131 | ; Extended screen line support | ||
| 132 | ; /P switch on DEL/ERASE command | ||
| 133 | ; Improved file redirection error recovery | ||
| 134 | ; (removed) Improved batch file performance | ||
| 135 | ; Unconditional DBCS support | ||
| 136 | ; Volume serial number support | ||
| 137 | ; (removed) COMMENT=?? support | ||
| 138 | ; | ||
| 139 | ; A001 PTM P20 Move system_cpage from TDATA to TSPC | ||
| 140 | ; | ||
| 141 | ; A002 PTM P74 Fix PRESCAN so that redirection symbols do not | ||
| 142 | ; require delimiters. | ||
| 143 | ; | ||
| 144 | ; A003 PTM P5,P9,P111 Included in A000 development | ||
| 145 | ; | ||
| 146 | ; A004 PTM P86 Fix IF command to turn off piping before | ||
| 147 | ; executing | ||
| 148 | ; | ||
| 149 | ; A005 DCR D17 If user specifies an extension on the command | ||
| 150 | ; line search for that extension only. | ||
| 151 | ; | ||
| 152 | ; A006 DCR D15 New message for MkDir - "Directory already | ||
| 153 | ; exists" | ||
| 154 | ; | ||
| 155 | ; A007 DCR D2 Change CTTY so that a write is done before XDUP | ||
| 156 | ; | ||
| 157 | ; A008 PTM P182 Change COPY to set default if invalid function | ||
| 158 | ; returned from code page call. | ||
| 159 | ; | ||
| 160 | ; A009 PTM P179 Add CRLF to invalid disk change message | ||
| 161 | ; | ||
| 162 | ; A010 DCR D43 Allow APPEND to do a far call to SYSPARSE in | ||
| 163 | ; transient COMMAND. | ||
| 164 | ; | ||
| 165 | ; A011 DCR D130 Change redirection to overwrite an EOF mark | ||
| 166 | ; before appending to a file. | ||
| 167 | ; | ||
| 168 | ; A012 PTM P189 Fix redirection error recovery. | ||
| 169 | ; | ||
| 170 | ; A013 PTM P330 Change date format | ||
| 171 | ; | ||
| 172 | ; A014 PTM P455 Fix echo parsing | ||
| 173 | ; | ||
| 174 | ; A015 PTM P517 Fix DIR problem with * vs *. | ||
| 175 | ; | ||
| 176 | ; A016 PTM P354 Fix extended error message addressing | ||
| 177 | ; | ||
| 178 | ; A017 PTM P448 Fix appending to 0 length files | ||
| 179 | ; | ||
| 180 | ; A018 PTM P566,P3903 Fix parse error messages to print out parameter | ||
| 181 | ; the parser fails on. Fail on duplicate switches. | ||
| 182 | ; | ||
| 183 | ; A019 PTM P542 Fix device name to be printed correctly during | ||
| 184 | ; critical error | ||
| 185 | ; | ||
| 186 | ; A020 DCR D43 Set append state off while in DIR | ||
| 187 | ; | ||
| 188 | ; A021 PTM P709 Fix CTTY printing ascii characters. | ||
| 189 | ; | ||
| 190 | ; A022 DCR D209 Enhanced error recovery | ||
| 191 | ; | ||
| 192 | ; A023 PTM P911 Fix ANSI.SYS IOCTL structure. | ||
| 193 | ; | ||
| 194 | ; A024 PTM P899 Fix EXTOPEN open modes. | ||
| 195 | ; | ||
| 196 | ; A025 PTM P922 Fix messages and optimize PARSE switches | ||
| 197 | ; | ||
| 198 | ; A026 DCR D191 Change redirection error recovery support. | ||
| 199 | ; | ||
| 200 | ; A027 PTM P991 Fix so that KAUTOBAT & AUTOEXEC are terminated | ||
| 201 | ; with a carriage return. | ||
| 202 | ; | ||
| 203 | ; A028 PTM P1076 Print a blank line before printing invalid | ||
| 204 | ; date and invalid time messages. | ||
| 205 | ; | ||
| 206 | ; A029 PTM P1084 Eliminate calls to parse_check_eol in DATE | ||
| 207 | ; and TIME. | ||
| 208 | ; | ||
| 209 | ; A030 DCR D201 New extended attribute format. | ||
| 210 | ; | ||
| 211 | ; A031 PTM P1149 Fix DATE/TIME add blank before prompt. | ||
| 212 | ; | ||
| 213 | ; A032 PTM P931 Fix =ON, =OFF for BREAK, VERIFY, ECHO | ||
| 214 | ; | ||
| 215 | ; A033 PTM P1298 Fix problem with system crashes on ECHO >"" | ||
| 216 | ; | ||
| 217 | ; A034 PTM P1387 Fix COPY D:fname+,, to work | ||
| 218 | ; | ||
| 219 | ; A035 PTM P1407 Fix so that >> (appending) to a device does | ||
| 220 | ; do a read to determine eof. | ||
| 221 | ; | ||
| 222 | ; A036 PTM P1406 Use 69h instead of 44h to get volume serial | ||
| 223 | ; so that ASSIGN works correctly. | ||
| 224 | ; | ||
| 225 | ; A037 PTM P1335 Fix COMMAND /C with FOR | ||
| 226 | ; | ||
| 227 | ; A038 PTM P1635 Fix COPY so that it doesn't accept /V /V | ||
| 228 | ; | ||
| 229 | ; A039 DCR D284 Change invalid code page tag from -1 to 0. | ||
| 230 | ; | ||
| 231 | ; A040 PTM P1787 Fix redirection to cause error when no file is | ||
| 232 | ; specified. | ||
| 233 | ; | ||
| 234 | ; A041 PTM P1705 Close redirected files after internal APPEND | ||
| 235 | ; executes. | ||
| 236 | ; | ||
| 237 | ; A042 PTM P1276 Fix problem of APPEND paths changes in batch | ||
| 238 | ; files causing loss of batch file. | ||
| 239 | ; | ||
| 240 | ; A043 PTM P2208 Make sure redirection is not set up twice for | ||
| 241 | ; CALL'ed batch files. | ||
| 242 | ; | ||
| 243 | ; A044 PTM P2315 Set switch on PARSE so that 0ah is not used | ||
| 244 | ; as an end of line character | ||
| 245 | ; | ||
| 246 | ; A045 PTM P2560 Make sure we don't lose parse, critical error, | ||
| 247 | ; and extended message pointers when we EXIT if | ||
| 248 | ; COMMAND /P is the top level process. | ||
| 249 | ; | ||
| 250 | ; A046 PTM P2690 Change COPY message "fn File not found" to | ||
| 251 | ; "File not found - fn" | ||
| 252 | ; | ||
| 253 | ; A047 PTM P2819 Fix transient reload prompt message | ||
| 254 | ; | ||
| 255 | ; A048 PTM P2824 Fix COPY path to be upper cased. This was broken | ||
| 256 | ; when DBCS code was added. | ||
| 257 | ; | ||
| 258 | ; A049 PTM P2891 Fix PATH so that it doesn't accept extra characters | ||
| 259 | ; on line. | ||
| 260 | ; | ||
| 261 | ; A050 PTM P3030 Fix TYPE to work properly on files > 64K | ||
| 262 | ; | ||
| 263 | ; A051 PTM P3011 Fix DIR header to be compatible with prior releases. | ||
| 264 | ; | ||
| 265 | ; A052 PTM P3063,P3228 Fix COPY message for invalid filename on target. | ||
| 266 | ; | ||
| 267 | ; A053 PTM P2865 Fix DIR to work in 40 column mode. | ||
| 268 | ; | ||
| 269 | ; A054 PTM P3407 Code reduction and critical error on single line | ||
| 270 | ; PTM P3672 (Change to single parser exported under P3407) | ||
| 271 | ; | ||
| 272 | ; A055 PTM P3282 Reset message service variables in INT 23h to fix | ||
| 273 | ; problems with breaking out of INT 24h | ||
| 274 | ; | ||
| 275 | ; A056 PTM P3389 Fix problem of environment overlaying transient. | ||
| 276 | ; | ||
| 277 | ; A057 PTM P3384 Fix COMMAND /C so that it works if there is no space | ||
| 278 | ; before the "string". EX: COMMAND /CDIR | ||
| 279 | ; | ||
| 280 | ; A058 PTM P3493 Fix DBCS so that CPARSE eats second character of | ||
| 281 | ; DBCS switch. | ||
| 282 | ; | ||
| 283 | ; A059 PTM P3394 Change the TIME command to right align the display of | ||
| 284 | ; the time. | ||
| 285 | ; | ||
| 286 | ; A060 PTM P3672 Code reduction - change PARSE and EXTENDED ERROR | ||
| 287 | ; messages to be disk based. Only keep them if /MSG | ||
| 288 | ; is used. | ||
| 289 | ; | ||
| 290 | ; A061 PTM P3928 Fix so that transient doesn't reload when breaking | ||
| 291 | ; out of internal commands, due to substitution blocks | ||
| 292 | ; not being reset. | ||
| 293 | ; | ||
| 294 | ; A062 PTM P4079 Fix segment override for fetching address of environment | ||
| 295 | ; of parent copy of COMMAND when no COMSPEC exists in | ||
| 296 | ; secondary copy of environment. Change default slash in | ||
| 297 | ; default comspec string to backslash. | ||
| 298 | |||
| 299 | ; A063 PTM P4140 REDIRECTOR and IFSFUNC changed interface for getting | ||
| 300 | ; text for critical error messages. | ||
| 301 | |||
| 302 | ; A064 PTM P4934 Multiplex number for ANSI.SYS changed due to conflict | ||
| 303 | ; 5/20/88 with Microsoft product already shipped. | ||
| 304 | |||
| 305 | ; A065 PTM P4935 Multiplex number for SHELL changed due to conflict with | ||
| 306 | ; 5/20/88 with Microsoft product already shipped. | ||
| 307 | |||
| 308 | ; A066 PTM P4961 DIR /W /P scrolled first line off the screen in some | ||
| 309 | ; 5/24/88 cases; where the listing would barely fit without the | ||
| 310 | ; header and space remaining. | ||
| 311 | |||
| 312 | ; A067 PTM P5011 For /E: values of 993 to 1024 the COMSPEC was getting | ||
| 313 | ; 6/6/88 trashed. Turns out that the SETBLOCK for the new | ||
| 314 | ; environment was putting a "Z block" marker in the old | ||
| 315 | ; environment. The fix is to move to the old environment | ||
| 316 | ; to the new environment before doing the SETBLOCK. | ||
| 317 | ;*********************************************************************************** | ||
| 318 | |||
| 319 | .XCREF | ||
| 320 | .XLIST | ||
| 321 | INCLUDE DOSSYM.INC | ||
| 322 | INCLUDE comsw.asm | ||
| 323 | INCLUDE comequ.asm | ||
| 324 | INCLUDE resmsg.equ ;AN000; | ||
| 325 | .LIST | ||
| 326 | .CREF | ||
| 327 | |||
| 328 | CODERES SEGMENT PUBLIC BYTE ;AC000; | ||
| 329 | CODERES ENDS | ||
| 330 | |||
| 331 | DATARES SEGMENT PUBLIC BYTE | ||
| 332 | EXTRN BATCH:WORD | ||
| 333 | EXTRN ECHOFLAG:BYTE | ||
| 334 | EXTRN disp_class:byte ;AN055; | ||
| 335 | EXTRN execemes_block:byte ;AC000; | ||
| 336 | EXTRN execemes_off:word ;AC000; | ||
| 337 | EXTRN execemes_subst:byte ;AC000; | ||
| 338 | EXTRN execemes_seg:word ;AC000; | ||
| 339 | EXTRN EXTCOM:BYTE | ||
| 340 | EXTRN FORFLAG:BYTE | ||
| 341 | EXTRN IFFlag:BYTE | ||
| 342 | EXTRN InitFlag:BYTE | ||
| 343 | EXTRN NEST:WORD | ||
| 344 | EXTRN number_subst:byte ;AC000; | ||
| 345 | EXTRN PIPEFLAG:BYTE | ||
| 346 | EXTRN RETCODE:WORD | ||
| 347 | EXTRN SINGLECOM:WORD | ||
| 348 | DATARES ENDS | ||
| 349 | |||
| 350 | BATARENA SEGMENT PUBLIC PARA ;AC000; | ||
| 351 | BATARENA ENDS | ||
| 352 | |||
| 353 | BATSEG SEGMENT PUBLIC PARA ;AC000; | ||
| 354 | BATSEG ENDS | ||
| 355 | |||
| 356 | ENVARENA SEGMENT PUBLIC PARA ;AC000; | ||
| 357 | ENVARENA ENDS | ||
| 358 | |||
| 359 | ENVIRONMENT SEGMENT PUBLIC PARA ; Default COMMAND environment | ||
| 360 | ENVIRONMENT ENDS | ||
| 361 | |||
| 362 | INIT SEGMENT PUBLIC PARA | ||
| 363 | EXTRN CONPROC:NEAR | ||
| 364 | EXTRN init_contc_specialcase:near | ||
| 365 | INIT ENDS | ||
| 366 | |||
| 367 | TAIL SEGMENT PUBLIC PARA | ||
| 368 | TAIL ENDS | ||
| 369 | |||
| 370 | TRANCODE SEGMENT PUBLIC PARA | ||
| 371 | TRANCODE ENDS | ||
| 372 | |||
| 373 | TRANDATA SEGMENT PUBLIC BYTE | ||
| 374 | TRANDATA ENDS | ||
| 375 | |||
| 376 | TRANSPACE SEGMENT PUBLIC BYTE | ||
| 377 | TRANSPACE ENDS | ||
| 378 | |||
| 379 | TRANTAIL SEGMENT PUBLIC PARA | ||
| 380 | TRANTAIL ENDS | ||
| 381 | |||
| 382 | RESGROUP GROUP CODERES,DATARES,BATARENA,BATSEG,ENVARENA,ENVIRONMENT,INIT,TAIL | ||
| 383 | TRANGROUP GROUP TRANCODE,TRANDATA,TRANSPACE,TRANTAIL | ||
| 384 | |||
| 385 | INCLUDE envdata.asm | ||
| 386 | |||
| 387 | ; START OF RESIDENT PORTION | ||
| 388 | |||
| 389 | CODERES SEGMENT PUBLIC BYTE ;AC000; | ||
| 390 | |||
| 391 | |||
| 392 | PUBLIC EXT_EXEC | ||
| 393 | PUBLIC CONTC | ||
| 394 | PUBLIC Exec_Wait | ||
| 395 | |||
| 396 | ASSUME CS:RESGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 397 | |||
| 398 | EXTRN lodcom:near | ||
| 399 | EXTRN LODCOM1:near | ||
| 400 | |||
| 401 | ORG 0 | ||
| 402 | ZERO = $ | ||
| 403 | |||
| 404 | ORG 80h-1 | ||
| 405 | PUBLIC RESCOM | ||
| 406 | RESCOM LABEL BYTE | ||
| 407 | |||
| 408 | ORG 100H | ||
| 409 | |||
| 410 | PROGSTART: | ||
| 411 | JMP RESGROUP:CONPROC | ||
| 412 | |||
| 413 | ; | ||
| 414 | ; COMMAND has issued an EXEC system call and it has returned an error. We | ||
| 415 | ; examine the error code and select an appropriate message. | ||
| 416 | ; | ||
| 417 | EXEC_ERR: | ||
| 418 | push ds ;AC000; get transient segment | ||
| 419 | pop es ;AC000; into ES | ||
| 420 | push cs ;AC000; get resident segment | ||
| 421 | pop ds ;AC000; into DS | ||
| 422 | ASSUME DS:RESGROUP ;AN000; | ||
| 423 | MOV BX,RBADNAM ;AC000; Get message number for Bad command | ||
| 424 | CMP AX,error_file_not_found | ||
| 425 | JZ GOTEXECEMES | ||
| 426 | MOV BX,TOOBIG ;AC000; Get message number for file not found | ||
| 427 | CMP AX,error_not_enough_memory | ||
| 428 | JZ GOTEXECEMES | ||
| 429 | MOV BX,EXEBAD ;AC000; Get message number for bad exe file | ||
| 430 | CMP AX,error_bad_format | ||
| 431 | JZ GOTEXECEMES | ||
| 432 | MOV BX,AccDen ;AC000; Get message number for access denied | ||
| 433 | CMP AX,error_access_denied | ||
| 434 | JZ GOTEXECEMES ;AC000; go print message | ||
| 435 | |||
| 436 | DEFAULT_MESSAGE: | ||
| 437 | MOV BX,EXECEMES ;AC000; Get message number for default message | ||
| 438 | MOV EXECEMES_OFF,DX ;AN000; put offset of EXEC string in subst block | ||
| 439 | MOV EXECEMES_SEG,ES ;AN000; put segment of EXEC string in subst block | ||
| 440 | MOV AL,EXECEMES_SUBST ;AN000; get number of substitutions | ||
| 441 | MOV NUMBER_SUBST,AL ;AN000; | ||
| 442 | MOV SI,OFFSET RESGROUP:EXECEMES_BLOCK ;AN000; get address of subst block | ||
| 443 | GOTEXECEMES: | ||
| 444 | PUSH CS | ||
| 445 | POP ES ;AC000; get resident segment into ES | ||
| 446 | ASSUME ES:RESGROUP ;AN000; | ||
| 447 | MOV DX,BX ;AN000; get message number in DX | ||
| 448 | INVOKE RPRINT | ||
| 449 | JMP SHORT NOEXEC | ||
| 450 | ; | ||
| 451 | ; The transient has set up everything for an EXEC system call. For | ||
| 452 | ; cleanliness, we issue the EXEC here in the resident so that we may be able | ||
| 453 | ; to recover cleanly upon success. | ||
| 454 | ; | ||
| 455 | EXT_EXEC: | ||
| 456 | push dx ;AN000; save the command name offset | ||
| 457 | INT int_command ; Do the EXEC | ||
| 458 | pop dx ;AN000; restore the command name offset | ||
| 459 | JC EXEC_ERR ; EXEC failed | ||
| 460 | ; | ||
| 461 | ; The exec has completed. Retrieve the exit code. | ||
| 462 | ; | ||
| 463 | EXEC_WAIT: | ||
| 464 | push cs ;AC000; get resident segment | ||
| 465 | pop ds ;AC000; into DS | ||
| 466 | MOV AH,WAITPROCESS ;AC000; Get errorlevel | ||
| 467 | INT int_command ; Get the return code | ||
| 468 | MOV [RETCODE],AX | ||
| 469 | ; | ||
| 470 | ; We need to test to see if we can reload the transient. THe external command | ||
| 471 | ; may have overwritten part of the transient. | ||
| 472 | ; | ||
| 473 | NOEXEC: | ||
| 474 | JMP LODCOM | ||
| 475 | ; | ||
| 476 | ; This is the default system INT 23 handler. All processes (including | ||
| 477 | ; COMMAND) get it by default. There are some games that are played: We | ||
| 478 | ; ignore ^C during most of the INIT code. This is because we may perform an | ||
| 479 | ; ALLOC and diddle the header! Also, if we are prompting for date/time in the | ||
| 480 | ; init code, we are to treat ^C as empty responses. | ||
| 481 | ; | ||
| 482 | CONTC PROC FAR | ||
| 483 | ASSUME CS:ResGroup,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 484 | test InitFlag,initINIT ; in initialization? | ||
| 485 | jz NotAtInit ; no | ||
| 486 | test InitFlag,initSpecial ; doing special stuff? | ||
| 487 | jz CmdIRet ; no, ignore ^C | ||
| 488 | jmp resgroup:init_contc_specialcase ; Yes, go handle it | ||
| 489 | CmdIret: | ||
| 490 | iret ; yes, ignore the ^C | ||
| 491 | NotAtInit: | ||
| 492 | test InitFlag,initCtrlC ; are we already in a ^C? | ||
| 493 | jz NotInit ; nope too. | ||
| 494 | ; | ||
| 495 | ; We are interrupting ourselves in this ^C handler. We need to set carry | ||
| 496 | ; and return to the user sans flags only if the system call was a 1-12 one. | ||
| 497 | ; Otherwise, we ignore the ^C. | ||
| 498 | ; | ||
| 499 | cmp ah,1 | ||
| 500 | jb CmdIRet | ||
| 501 | cmp ah,12 | ||
| 502 | ja CmdIRet | ||
| 503 | add sp,6 ; remove int frame | ||
| 504 | stc | ||
| 505 | ret 2 ; remove those flags... | ||
| 506 | ; | ||
| 507 | ; We have now received a ^C for some process (maybe ourselves but not at INIT). | ||
| 508 | ; | ||
| 509 | ; Note that we are running on the user's stack!!! Bad news if any of the | ||
| 510 | ; system calls below go and issue another INT 24... Massive stack overflow! | ||
| 511 | ; Another bad point is that SavHand will save an already saved handle, thus | ||
| 512 | ; losing a possible redirection... | ||
| 513 | ; | ||
| 514 | ; All we need to do is set the flag to indicate nested ^C. The above code | ||
| 515 | ; will correctly flag the ^C diring the message output and prompting while | ||
| 516 | ; ignoring the ^C the rest of the time. | ||
| 517 | ; | ||
| 518 | ; Clean up: flush disk. If we are in the middle of a batch file, we ask if | ||
| 519 | ; he wants to terminate it. If he does, then we turn off all internal flags | ||
| 520 | ; and let the DOS abort. | ||
| 521 | ; | ||
| 522 | NotInit: | ||
| 523 | or InitFlag,initCtrlC ; nested ^c is on | ||
| 524 | STI | ||
| 525 | PUSH CS ; El Yucko! Change the user's DS!! | ||
| 526 | POP DS | ||
| 527 | ASSUME DS:RESGROUP | ||
| 528 | MOV DISP_CLASS,UTIL_MSG_CLASS ;AN055; reset display class | ||
| 529 | MOV NUMBER_SUBST,NO_SUBST ;AN055; reset number of substitutions | ||
| 530 | MOV AX,SingleCom | ||
| 531 | OR AX,AX | ||
| 532 | JNZ NoReset | ||
| 533 | PUSH AX | ||
| 534 | MOV AH,DISK_RESET | ||
| 535 | INT int_command ; Reset disks in case files were open | ||
| 536 | POP AX | ||
| 537 | NoReset: | ||
| 538 | ; | ||
| 539 | ; In the generalized version of FOR, PIPE and BATCH, we would walk the entire | ||
| 540 | ; active list and free each segment. Here, we just free the single batch | ||
| 541 | ; segment. | ||
| 542 | ; | ||
| 543 | TEST Batch,-1 | ||
| 544 | JZ CONTCTERM | ||
| 545 | OR AX,AX | ||
| 546 | JNZ Contcterm | ||
| 547 | invoke SavHand | ||
| 548 | invoke ASKEND ; See if user wants to terminate batch | ||
| 549 | ; | ||
| 550 | ; If the carry flag is clear, we do NOT free up the batch file | ||
| 551 | ; | ||
| 552 | JNC ContBatch | ||
| 553 | mov cl,echoflag ;AN000; get current echo flag | ||
| 554 | PUSH BX ;G | ||
| 555 | |||
| 556 | ClearBatch: | ||
| 557 | MOV ES,[BATCH] ; get batch segment | ||
| 558 | mov di,batfile ;AN000; get offset of batch file name | ||
| 559 | mov ax,mult_shell_brk ;AN000; does the SHELL want this terminated? | ||
| 560 | int 2fh ;AN000; call the SHELL | ||
| 561 | cmp al,shell_action ;AN000; does shell want this batch? | ||
| 562 | jz shell_bat_cont ;AN000; yes - keep it | ||
| 563 | |||
| 564 | MOV BX,ES:[BATFORPTR] ;G get old FOR segment | ||
| 565 | cmp bx,0 ;G is a FOR in progress | ||
| 566 | jz no_bat_for ;G no - don't deallocate | ||
| 567 | push es ;G | ||
| 568 | mov es,bx ;G yes - free it up... | ||
| 569 | MOV AH,DEALLOC ;G | ||
| 570 | INT 21H ;G | ||
| 571 | pop es ;G restore to batch segment | ||
| 572 | |||
| 573 | no_bat_for: | ||
| 574 | mov cl,ES:[batechoflag] ;G get old echo flag | ||
| 575 | MOV BX,ES:[BATLAST] ;G get old batch segment | ||
| 576 | MOV AH,DEALLOC ; free it up... | ||
| 577 | INT 21H | ||
| 578 | MOV [BATCH],BX ;G get ready to deallocate next batch | ||
| 579 | DEC NEST ;G Is there another batch file? | ||
| 580 | JNZ CLEARBATCH ;G Keep going until no batch file | ||
| 581 | |||
| 582 | ; | ||
| 583 | ; We are terminating a batch file; restore the echo status | ||
| 584 | ; | ||
| 585 | |||
| 586 | shell_bat_cont: ;AN000; continue batch for SHELL | ||
| 587 | |||
| 588 | POP BX ;G | ||
| 589 | MOV ECHOFLAG,CL ;G reset echo status | ||
| 590 | MOV PIPEFLAG,0 ;G turn off pipeflag | ||
| 591 | ContBatch: | ||
| 592 | invoke CRLF ;G print out crlf before returning | ||
| 593 | invoke RestHand | ||
| 594 | ; | ||
| 595 | ; Yes, we are terminating. Turn off flags and allow the DOS to abort. | ||
| 596 | ; | ||
| 597 | CONTCTERM: | ||
| 598 | XOR AX,AX ; Indicate no read | ||
| 599 | MOV BP,AX | ||
| 600 | ; | ||
| 601 | ; The following resetting of the state flags is good for the generalized batch | ||
| 602 | ; processing. | ||
| 603 | ; | ||
| 604 | MOV IfFlag,AL ; turn off iffing | ||
| 605 | MOV [FORFLAG],AL ; Turn off for processing | ||
| 606 | call ResPipeOff | ||
| 607 | CMP [SINGLECOM],AX ; See if we need to set SINGLECOM | ||
| 608 | JZ NOSETSING | ||
| 609 | MOV [SINGLECOM],-1 ; Cause termination on pipe, batch, for | ||
| 610 | NOSETSING: | ||
| 611 | ; | ||
| 612 | ; If we are doing an internal command, go through the reload process. If we | ||
| 613 | ; are doing an external, let DOS abort the process. In both cases, we are | ||
| 614 | ; now done with the ^C processing. | ||
| 615 | ; | ||
| 616 | AND InitFlag,NOT initCtrlC | ||
| 617 | CMP [EXTCOM],AL | ||
| 618 | JNZ DODAB ; Internal ^C | ||
| 619 | JMP LODCOM1 | ||
| 620 | DODAB: | ||
| 621 | STC ; Tell DOS to abort | ||
| 622 | RET ; Leave flags on stack | ||
| 623 | ContC ENDP | ||
| 624 | |||
| 625 | public ResPipeOff | ||
| 626 | assume ds:nothing,es:nothing | ||
| 627 | ResPipeOff: | ||
| 628 | SaveReg <AX> | ||
| 629 | xor ax,ax | ||
| 630 | xchg PipeFlag,al | ||
| 631 | or al,al | ||
| 632 | jz NoPipePop | ||
| 633 | shr EchoFlag,1 | ||
| 634 | NoPipePop: | ||
| 635 | RestoreReg <AX> | ||
| 636 | return | ||
| 637 | CODERES ENDS | ||
| 638 | END PROGSTART | ||
diff --git a/v4.0/src/CMD/COMMAND/COMMAND2.ASM b/v4.0/src/CMD/COMMAND/COMMAND2.ASM new file mode 100644 index 0000000..0f6c5b5 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/COMMAND2.ASM | |||
| @@ -0,0 +1,619 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)command2.asm 4.3 85/10/16 | ||
| 3 | ; SCCSID = @(#)command2.asm 4.3 85/10/16 | ||
| 4 | TITLE COMMAND2 - resident code for COMMAND.COM part II | ||
| 5 | NAME COMMAND2 | ||
| 6 | .XCREF | ||
| 7 | .XLIST | ||
| 8 | INCLUDE DOSSYM.INC | ||
| 9 | INCLUDE comsw.asm | ||
| 10 | INCLUDE comequ.asm | ||
| 11 | INCLUDE resmsg.equ ;AN000; | ||
| 12 | .LIST | ||
| 13 | .CREF | ||
| 14 | |||
| 15 | tokenized = FALSE | ||
| 16 | |||
| 17 | CODERES SEGMENT PUBLIC BYTE ;AC000; | ||
| 18 | CODERES ENDS | ||
| 19 | |||
| 20 | DATARES SEGMENT PUBLIC BYTE | ||
| 21 | EXTRN append_state:word ;AN020; | ||
| 22 | EXTRN append_flag:byte ;AN020; | ||
| 23 | EXTRN COMDRV:BYTE | ||
| 24 | EXTRN comprmt1_block:byte ;AN000; | ||
| 25 | EXTRN comprmt1_subst:byte ;AN000; | ||
| 26 | EXTRN COMSPEC:BYTE | ||
| 27 | EXTRN cpdrv:byte | ||
| 28 | EXTRN envirseg:word | ||
| 29 | EXTRN EXTCOM:BYTE | ||
| 30 | EXTRN HANDLE01:WORD | ||
| 31 | EXTRN InitFlag:BYTE | ||
| 32 | EXTRN INT_2E_RET:DWORD ;AC000; | ||
| 33 | EXTRN IO_SAVE:WORD | ||
| 34 | EXTRN LOADING:BYTE | ||
| 35 | EXTRN LTPA:WORD | ||
| 36 | EXTRN MEMSIZ:WORD | ||
| 37 | EXTRN number_subst:byte ;AN000; | ||
| 38 | EXTRN OldTerm:DWORD ;AC000; | ||
| 39 | EXTRN PARENT:WORD ;AC000; | ||
| 40 | EXTRN PERMCOM:BYTE | ||
| 41 | EXTRN RDIRCHAR:BYTE | ||
| 42 | EXTRN RES_TPA:WORD | ||
| 43 | EXTRN RETCODE:WORD | ||
| 44 | EXTRN rsrc_xa_seg:word ;AN030; | ||
| 45 | EXTRN RSWITCHAR:BYTE | ||
| 46 | EXTRN SAVE_PDB:WORD | ||
| 47 | EXTRN SINGLECOM:WORD | ||
| 48 | EXTRN SUM:WORD | ||
| 49 | EXTRN TRANS:WORD | ||
| 50 | EXTRN TranVarEnd:BYTE | ||
| 51 | EXTRN TRANVARS:BYTE | ||
| 52 | EXTRN TRNSEG:WORD | ||
| 53 | EXTRN VERVAL:WORD | ||
| 54 | DATARES ENDS | ||
| 55 | |||
| 56 | BATARENA SEGMENT PUBLIC PARA ;AC000; | ||
| 57 | BATARENA ENDS | ||
| 58 | |||
| 59 | BATSEG SEGMENT PUBLIC PARA ;AC000; | ||
| 60 | BATSEG ENDS | ||
| 61 | |||
| 62 | ENVARENA SEGMENT PUBLIC PARA ;AC000; | ||
| 63 | ENVARENA ENDS | ||
| 64 | |||
| 65 | ENVIRONMENT SEGMENT PUBLIC PARA ; Default COMMAND environment | ||
| 66 | ENVIRONMENT ENDS | ||
| 67 | |||
| 68 | INIT SEGMENT PUBLIC PARA | ||
| 69 | EXTRN envsiz:word | ||
| 70 | EXTRN oldenv:word | ||
| 71 | EXTRN resetenv:byte | ||
| 72 | EXTRN usedenv:word | ||
| 73 | INIT ENDS | ||
| 74 | |||
| 75 | TAIL SEGMENT PUBLIC PARA | ||
| 76 | TAIL ENDS | ||
| 77 | |||
| 78 | TRANCODE SEGMENT PUBLIC PARA | ||
| 79 | TRANCODE ENDS | ||
| 80 | |||
| 81 | TRANDATA SEGMENT PUBLIC BYTE | ||
| 82 | EXTRN TRANDATAEND:BYTE | ||
| 83 | TRANDATA ENDS | ||
| 84 | |||
| 85 | TRANSPACE SEGMENT PUBLIC BYTE | ||
| 86 | EXTRN TRANSPACEEND:BYTE | ||
| 87 | EXTRN HEADCALL:DWORD | ||
| 88 | TRANSPACE ENDS | ||
| 89 | |||
| 90 | TRANTAIL SEGMENT PUBLIC PARA | ||
| 91 | TRANTAIL ENDS | ||
| 92 | |||
| 93 | RESGROUP GROUP CODERES,DATARES,BATARENA,BATSEG,ENVARENA,ENVIRONMENT,INIT,TAIL | ||
| 94 | TRANGROUP GROUP TRANCODE,TRANDATA,TRANSPACE,TRANTAIL | ||
| 95 | |||
| 96 | ; START OF RESIDENT PORTION | ||
| 97 | |||
| 98 | CODERES SEGMENT PUBLIC BYTE ;AC000; | ||
| 99 | |||
| 100 | PUBLIC CHKSUM | ||
| 101 | PUBLIC endinit | ||
| 102 | PUBLIC GETCOMDSK2 | ||
| 103 | PUBLIC INT_2E | ||
| 104 | PUBLIC LOADCOM | ||
| 105 | PUBLIC LODCOM | ||
| 106 | PUBLIC LODCOM1 | ||
| 107 | PUBLIC RESTHAND | ||
| 108 | PUBLIC SAVHAND | ||
| 109 | PUBLIC SETVECT | ||
| 110 | PUBLIC THEADFIX | ||
| 111 | PUBLIC TREMCHECK | ||
| 112 | PUBLIC tjmp | ||
| 113 | |||
| 114 | ASSUME CS:RESGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 115 | |||
| 116 | EXTRN contc:near | ||
| 117 | EXTRN DSKERR:NEAR | ||
| 118 | EXTRN rstack:word | ||
| 119 | ; | ||
| 120 | ; If we cannot allocate enough memory for the transient or there was some | ||
| 121 | ; other allocation error, we display a message and then die. | ||
| 122 | ; | ||
| 123 | BADMEMERR: ; Allocation error loading transient | ||
| 124 | MOV DX,BMEMMES ;AC000; get message number | ||
| 125 | FATALC: | ||
| 126 | PUSH CS | ||
| 127 | POP DS | ||
| 128 | ASSUME DS:ResGroup | ||
| 129 | invoke RPRINT | ||
| 130 | ; | ||
| 131 | ; If this is NOT a permanent (top-level) COMMAND, then we exit; we can't do | ||
| 132 | ; anything else! | ||
| 133 | ; | ||
| 134 | CMP PERMCOM,0 | ||
| 135 | JZ FATALRET | ||
| 136 | ; | ||
| 137 | ; We are a permanent command. If we are in the process of the magic interrupt | ||
| 138 | ; (Singlecom) then exit too. | ||
| 139 | ; | ||
| 140 | CMP SINGLECOM,0 ; If PERMCOM and SINGLECOM | ||
| 141 | JNZ FATALRET ; Must take INT_2E exit | ||
| 142 | ; | ||
| 143 | ; Permanent command. We can't do ANYthing except halt. | ||
| 144 | ; | ||
| 145 | MOV DX,HALTMES ;AC000; get message number | ||
| 146 | invoke RPRINT | ||
| 147 | STI | ||
| 148 | STALL: | ||
| 149 | JMP STALL ; Crash the system nicely | ||
| 150 | |||
| 151 | FATALRET: | ||
| 152 | MOV DX,FRETMES ;AC000; get message number | ||
| 153 | invoke RPRINT | ||
| 154 | FATALRET2: | ||
| 155 | CMP [PERMCOM],0 ; If we get here and PERMCOM, | ||
| 156 | JNZ RET_2E ; must be INT_2E | ||
| 157 | invoke reset_msg_pointers ;AN000; reset critical & parse error messages | ||
| 158 | MOV AX,[PARENT] | ||
| 159 | MOV WORD PTR CS:[PDB_Parent_PID],AX | ||
| 160 | MOV AX,WORD PTR OldTerm | ||
| 161 | MOV WORD PTR CS:[PDB_Exit],AX | ||
| 162 | MOV AX,WORD PTR OldTerm+2 | ||
| 163 | MOV WORD PTR CS:[PDB_Exit+2],AX | ||
| 164 | MOV AX,(EXIT SHL 8) ; Return to lower level | ||
| 165 | INT int_command | ||
| 166 | |||
| 167 | RET_2E: | ||
| 168 | PUSH CS | ||
| 169 | POP DS | ||
| 170 | ASSUME DS:RESGROUP,ES:NOTHING,SS:NOTHING | ||
| 171 | MOV [SINGLECOM],0 ; Turn off singlecom | ||
| 172 | MOV ES,[RES_TPA] | ||
| 173 | MOV AH,DEALLOC | ||
| 174 | INT int_command ; Free up space used by transient | ||
| 175 | MOV BX,[SAVE_PDB] | ||
| 176 | MOV AH,SET_CURRENT_PDB | ||
| 177 | INT int_command ; Current process is user | ||
| 178 | MOV AX,[RETCODE] | ||
| 179 | CMP [EXTCOM],0 | ||
| 180 | JNZ GOTECODE | ||
| 181 | XOR AX,AX ; Internals always return 0 | ||
| 182 | GOTECODE: | ||
| 183 | MOV [EXTCOM],1 ; Force external | ||
| 184 | JMP [INT_2E_RET] ;"IRET" | ||
| 185 | |||
| 186 | INT_2E: ; Magic command executer | ||
| 187 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 188 | POP WORD PTR [INT_2E_RET] | ||
| 189 | POP WORD PTR [INT_2E_RET+2] ;Get return address | ||
| 190 | POP AX ;Chuck flags | ||
| 191 | PUSH CS | ||
| 192 | POP ES | ||
| 193 | MOV DI,80H | ||
| 194 | MOV CX,64 | ||
| 195 | REP MOVSW | ||
| 196 | MOV AH,GET_CURRENT_PDB | ||
| 197 | INT int_command ; Get user's header | ||
| 198 | MOV [SAVE_PDB],BX | ||
| 199 | MOV AH,SET_CURRENT_PDB | ||
| 200 | MOV BX,CS | ||
| 201 | INT int_command ; Current process is me | ||
| 202 | MOV [SINGLECOM],81H | ||
| 203 | MOV [EXTCOM],1 ; Make sure this case forced | ||
| 204 | |||
| 205 | LODCOM: ; Termination handler | ||
| 206 | CMP [EXTCOM],0 | ||
| 207 | jz lodcom1 ; if internal, memory already allocated | ||
| 208 | mov bx,0ffffh | ||
| 209 | MOV AH,ALLOC | ||
| 210 | INT int_command | ||
| 211 | CALL SetSize | ||
| 212 | ADD AX,20H | ||
| 213 | CMP BX,AX ; Is less than 512 byte buffer worth it? | ||
| 214 | JNC MEMOK | ||
| 215 | BADMEMERRJ: | ||
| 216 | JMP BADMEMERR ; Not enough memory | ||
| 217 | |||
| 218 | ; SetSize - get transient size in paragraphs | ||
| 219 | Procedure SetSize,NEAR | ||
| 220 | MOV AX,OFFSET TRANGROUP:TRANSPACEEND + 15 | ||
| 221 | MOV CL,4 | ||
| 222 | SHR AX,CL | ||
| 223 | return | ||
| 224 | EndProc SetSize | ||
| 225 | |||
| 226 | MEMOK: | ||
| 227 | MOV AH,ALLOC | ||
| 228 | INT int_command | ||
| 229 | JC BADMEMERRJ ; Memory arenas probably trashed | ||
| 230 | MOV [EXTCOM],0 ; Flag not to ALLOC again | ||
| 231 | MOV [RES_TPA], AX ; Save current TPA segment | ||
| 232 | AND AX, 0F000H | ||
| 233 | ADD AX, 01000H ; Round up to next 64K boundary | ||
| 234 | JC BAD_TPA ; Memory wrap if carry set | ||
| 235 | ; Make sure that new boundary is within allocated range | ||
| 236 | MOV DX, [RES_TPA] | ||
| 237 | ADD DX, BX ; Compute maximum address | ||
| 238 | CMP DX, AX ; Is 64K address out of range? | ||
| 239 | JBE BAD_TPA | ||
| 240 | ; Must have 64K of usable space. | ||
| 241 | SUB DX, AX ; Compute the usable space | ||
| 242 | CMP DX, 01000H ; Is space >= 64K ? | ||
| 243 | JAE LTPASET | ||
| 244 | BAD_TPA: | ||
| 245 | MOV AX, [RES_TPA] | ||
| 246 | LTPASET: | ||
| 247 | MOV [LTPA],AX ; Usable TPA is 64k buffer aligned | ||
| 248 | MOV AX, [RES_TPA] ; Actual TPA is buffer allocated | ||
| 249 | ADD BX,AX | ||
| 250 | MOV [MEMSIZ],BX | ||
| 251 | CALL SetSize | ||
| 252 | SUB BX,AX | ||
| 253 | MOV [TRNSEG],BX ; Transient starts here | ||
| 254 | LODCOM1: | ||
| 255 | MOV AX,CS | ||
| 256 | MOV SS,AX | ||
| 257 | ASSUME SS:RESGROUP | ||
| 258 | MOV SP,OFFSET RESGROUP:RSTACK | ||
| 259 | MOV DS,AX | ||
| 260 | ASSUME DS:RESGROUP | ||
| 261 | CALL HEADFIX ; Make sure files closed stdin and stdout restored | ||
| 262 | XOR BP,BP ; Flag command ok | ||
| 263 | MOV AX,-1 | ||
| 264 | XCHG AX,[VERVAL] | ||
| 265 | CMP AX,-1 | ||
| 266 | JZ NOSETVER | ||
| 267 | MOV AH,SET_VERIFY_ON_WRITE ; AL has correct value | ||
| 268 | INT int_command | ||
| 269 | NOSETVER: | ||
| 270 | CMP [SINGLECOM],-1 | ||
| 271 | JNZ NOSNG | ||
| 272 | JMP FATALRET2 ; We have finished the single command | ||
| 273 | NOSNG: | ||
| 274 | CALL CHKSUM ; Check the transient | ||
| 275 | CMP DX,[SUM] | ||
| 276 | JZ HAVCOM ; Transient OK | ||
| 277 | BOGUS_COM: | ||
| 278 | MOV [LOADING],1 ; Flag DSKERR routine | ||
| 279 | CALL LOADCOM | ||
| 280 | CHKSAME: | ||
| 281 | |||
| 282 | CALL CHKSUM | ||
| 283 | CMP DX,[SUM] | ||
| 284 | JZ HAVCOM ; Same COMMAND | ||
| 285 | ALSO_BOGUS: | ||
| 286 | CALL WRONGCOM | ||
| 287 | JMP SHORT CHKSAME | ||
| 288 | HAVCOM: | ||
| 289 | MOV AX,CHAR_OPER SHL 8 | ||
| 290 | INT int_command | ||
| 291 | MOV [RSWITCHAR],DL | ||
| 292 | CMP DL,'/' | ||
| 293 | JNZ USESLASH | ||
| 294 | mov cl,'\' | ||
| 295 | MOV [RDIRCHAR],cl ; Select alt path separator | ||
| 296 | USESLASH: | ||
| 297 | MOV [LOADING],0 ; Flag to DSKERR | ||
| 298 | MOV SI,OFFSET RESGROUP:TRANVARS | ||
| 299 | MOV DI,OFFSET TRANGROUP:HEADCALL | ||
| 300 | MOV ES,[TRNSEG] | ||
| 301 | CLD | ||
| 302 | MOV CX,OFFSET ResGroup:TranVarEnd | ||
| 303 | SUB CX,SI | ||
| 304 | REP MOVSB ; Transfer INFO to transient | ||
| 305 | MOV AX,[MEMSIZ] | ||
| 306 | MOV WORD PTR DS:[PDB_block_len],AX ; Adjust my own header | ||
| 307 | |||
| 308 | ; Just a public label so this spot can be found easily. | ||
| 309 | tjmp: | ||
| 310 | JMP DWORD PTR [TRANS] | ||
| 311 | |||
| 312 | ; Far call to REMCHECK for TRANSIENT | ||
| 313 | TREMCHECK PROC FAR | ||
| 314 | CALL REMCHECK | ||
| 315 | RET | ||
| 316 | TREMCHECK ENDP | ||
| 317 | |||
| 318 | REMCHECK: | ||
| 319 | ;All registers preserved. Returns ZF set if media removable, NZ if fixed | ||
| 320 | ; AL is drive (0=DEF, 1=A,...). | ||
| 321 | SaveReg <AX,BX> | ||
| 322 | MOV BX,AX | ||
| 323 | MOV AX,(IOCTL SHL 8) + 8 | ||
| 324 | INT 21h | ||
| 325 | jnc RCcont ; If an error occurred, assume the media | ||
| 326 | or ax,ax ; is NON-removable. | ||
| 327 | ; AX contains the non-zero error code | ||
| 328 | ; from the INT 21, so the OR AX,AX sets | ||
| 329 | ; Non-zero. This behavior makes Network | ||
| 330 | ; drives appear to be non-removable. | ||
| 331 | jmp SHORT ResRegs | ||
| 332 | RCcont: | ||
| 333 | AND AX,1 | ||
| 334 | NOT AX | ||
| 335 | ResRegs: | ||
| 336 | RestoreReg <BX,AX> | ||
| 337 | return | ||
| 338 | |||
| 339 | ; Far call to HEADFIX for TRANSIENT | ||
| 340 | THEADFIX PROC FAR | ||
| 341 | CALL HEADFIX | ||
| 342 | RET | ||
| 343 | THEADFIX ENDP | ||
| 344 | |||
| 345 | HEADFIX: | ||
| 346 | CALL SETVECT | ||
| 347 | XOR BX,BX ; Clean up header | ||
| 348 | MOV CX,[IO_SAVE] | ||
| 349 | MOV DX,WORD PTR DS:[PDB_JFN_Table] | ||
| 350 | CMP CL,DL | ||
| 351 | JZ CHK1 ; Stdin matches | ||
| 352 | MOV AH,CLOSE | ||
| 353 | INT int_command | ||
| 354 | MOV DS:[PDB_JFN_Table],CL ; Restore stdin | ||
| 355 | CHK1: | ||
| 356 | INC BX | ||
| 357 | CMP CH,DH ; Stdout matches | ||
| 358 | JZ CHKOTHERHAND | ||
| 359 | MOV AH,CLOSE | ||
| 360 | INT int_command | ||
| 361 | MOV DS:[PDB_JFN_Table+1],CH ; Restore stdout | ||
| 362 | CHKOTHERHAND: | ||
| 363 | ADD BX,4 ; Skip 2,3,4 | ||
| 364 | MOV CX,FilPerProc - 5 ; Already done 0,1,2,3,4 | ||
| 365 | CLOSELOOP: | ||
| 366 | MOV AH,CLOSE | ||
| 367 | INT int_command | ||
| 368 | INC BX | ||
| 369 | LOOP CLOSELOOP | ||
| 370 | push ds ;AN020; save data segment | ||
| 371 | push cs ;AN020; Get local segment into DS | ||
| 372 | pop ds ;AN020; | ||
| 373 | cmp append_flag,-1 ;AN020; Do we need to reset APPEND? | ||
| 374 | jnz append_fix_end ;AN030; no - just exit | ||
| 375 | mov ax,AppendSetState ;AN020; Set the state of Append | ||
| 376 | mov bx,Append_state ;AN020; back to the original state | ||
| 377 | int 2fh ;AN020; | ||
| 378 | mov append_flag,0 ;AN020; Set append flag to invalid | ||
| 379 | append_fix_end: ;AN030; | ||
| 380 | cmp [rsrc_xa_seg],no_xa_seg ;AN030; Is there any active XA segment? | ||
| 381 | jz xa_fix_end ;AN030; no - exit | ||
| 382 | push es ;AN030; Yes - deallocate it | ||
| 383 | mov es,rsrc_xa_seg ;AN030; | ||
| 384 | mov ax,(Dealloc SHL 8) ;AN030; Deallocate memory call | ||
| 385 | int int_command ;AN030; | ||
| 386 | pop es ;AN030; | ||
| 387 | mov [rsrc_xa_seg],no_xa_seg ;AN030; reset to no segment | ||
| 388 | xa_fix_end: | ||
| 389 | pop ds ;AN020; get data segment back | ||
| 390 | return | ||
| 391 | |||
| 392 | SAVHAND: | ||
| 393 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 394 | PUSH DS | ||
| 395 | PUSH BX ; Set stdin to sterr, stdout to stderr | ||
| 396 | PUSH AX | ||
| 397 | MOV AH,GET_CURRENT_PDB | ||
| 398 | INT int_command ; Get user's header | ||
| 399 | MOV DS,BX | ||
| 400 | LDS BX,DS:[PDB_JFN_POINTER] ; get pointer to JFN table... | ||
| 401 | MOV AX,WORD PTR DS:[BX] | ||
| 402 | MOV [HANDLE01],AX ; Save user's stdin, stdout | ||
| 403 | MOV AL,CS:[PDB_JFN_Table+2] ; get COMMAND stderr | ||
| 404 | MOV AH,AL | ||
| 405 | MOV WORD PTR DS:[BX],AX ; Dup stderr | ||
| 406 | POP AX | ||
| 407 | POP BX | ||
| 408 | POP DS | ||
| 409 | return | ||
| 410 | |||
| 411 | ASSUME DS:RESGROUP | ||
| 412 | GETCOMDSK2: | ||
| 413 | CALL GETCOMDSK | ||
| 414 | JMP LODCOM1 ; Memory already allocated | ||
| 415 | |||
| 416 | RESTHAND: | ||
| 417 | PUSH DS | ||
| 418 | PUSH BX ; Restore stdin, stdout to user | ||
| 419 | PUSH AX | ||
| 420 | MOV AH,GET_CURRENT_PDB | ||
| 421 | INT int_command ; Point to user's header | ||
| 422 | MOV AX,[HANDLE01] | ||
| 423 | MOV DS,BX | ||
| 424 | ASSUME DS:NOTHING | ||
| 425 | LDS BX,DS:[PDB_JFN_POINTER] ; get pointer to JFN table... | ||
| 426 | MOV WORD PTR DS:[BX],AX ; Stuff his old 0 and 1 | ||
| 427 | POP AX | ||
| 428 | POP BX | ||
| 429 | POP DS | ||
| 430 | return | ||
| 431 | ASSUME DS:RESGROUP,SS:RESGROUP | ||
| 432 | |||
| 433 | HOPELESS: | ||
| 434 | MOV DX,COMBAD ;AC000; | ||
| 435 | JMP FATALC | ||
| 436 | |||
| 437 | GETCOMDSK: | ||
| 438 | mov al,[comdrv] | ||
| 439 | CALL REMCHECK | ||
| 440 | jNZ HOPELESS ;Non-removable media | ||
| 441 | getcomdsk3: | ||
| 442 | cmp dx,combad ;AC000; | ||
| 443 | jnz getcomdsk4 | ||
| 444 | mov dx,combad ;AN000; get message number | ||
| 445 | invoke RPRINT ; Say command is invalid | ||
| 446 | getcomdsk4: | ||
| 447 | cmp [cpdrv],0 ;g is there a drive in the comspec? | ||
| 448 | jnz users_drive ;g yes - use it | ||
| 449 | mov ah,Get_default_drive ;g use default drive | ||
| 450 | int 21h ;g | ||
| 451 | add al,"A" ;g convert to ascii | ||
| 452 | mov [cpdrv],al ;g put in message to print out | ||
| 453 | |||
| 454 | users_drive: ;g | ||
| 455 | mov dx,comprmt1 ;AC000; Prompt for diskette containing command | ||
| 456 | IF tokenized | ||
| 457 | or byte ptr [si],80h | ||
| 458 | endif | ||
| 459 | MOV AL,COMPRMT1_SUBST ;AN000; get number of substitutions | ||
| 460 | MOV SI,OFFSET RESGROUP:COMPRMT1_BLOCK ;AN000; get address of subst block | ||
| 461 | MOV NUMBER_SUBST,AL ;AN000; | ||
| 462 | invoke rprint | ||
| 463 | if tokenized | ||
| 464 | and byte ptr [si],NOT 80h | ||
| 465 | endif | ||
| 466 | mov dx,prompt ;AN047; Tell the user to strike a key | ||
| 467 | invoke rprint ;AN047; | ||
| 468 | CALL GetRawFlushedByte | ||
| 469 | return | ||
| 470 | |||
| 471 | ; flush world and get raw input | ||
| 472 | GetRawFlushedByte: | ||
| 473 | MOV AX,(STD_CON_INPUT_FLUSH SHL 8) OR RAW_CON_INPUT | ||
| 474 | INT int_command ; Get char without testing or echo | ||
| 475 | MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0 | ||
| 476 | INT int_command | ||
| 477 | return | ||
| 478 | |||
| 479 | LOADCOM: ; Load in transient | ||
| 480 | INC BP ; Flag command read | ||
| 481 | MOV DX,OFFSET RESGROUP:COMSPEC | ||
| 482 | MOV AX,OPEN SHL 8 | ||
| 483 | INT int_command ; Open COMMAND.COM | ||
| 484 | JNC READCOM | ||
| 485 | CMP AX,error_too_many_open_files | ||
| 486 | JNZ TRYDOOPEN | ||
| 487 | MOV DX,NOHANDMES ;AC000; | ||
| 488 | JMP FATALC ; Fatal, will never find a handle | ||
| 489 | |||
| 490 | TRYDOOPEN: | ||
| 491 | CALL GETCOMDSK | ||
| 492 | JMP LOADCOM | ||
| 493 | |||
| 494 | READCOM: | ||
| 495 | MOV BX,AX ; Handle | ||
| 496 | MOV DX,OFFSET RESGROUP:TRANSTART | ||
| 497 | XOR CX,CX ; Seek loc | ||
| 498 | MOV AX,LSEEK SHL 8 | ||
| 499 | INT int_command | ||
| 500 | JC WRONGCOM1 | ||
| 501 | MOV CX,OFFSET TRANGROUP:TRANSPACEEND - 100H | ||
| 502 | |||
| 503 | PUSH DS | ||
| 504 | MOV DS,[TRNSEG] | ||
| 505 | ASSUME DS:NOTHING | ||
| 506 | MOV DX,100H | ||
| 507 | MOV AH,READ | ||
| 508 | INT int_command | ||
| 509 | POP DS | ||
| 510 | ASSUME DS:RESGROUP | ||
| 511 | WRONGCOM1: | ||
| 512 | PUSHF | ||
| 513 | PUSH AX | ||
| 514 | MOV AH,CLOSE | ||
| 515 | INT int_command ; Close COMMAND.COM | ||
| 516 | POP AX | ||
| 517 | POPF | ||
| 518 | JC WRONGCOM ; If error on READ | ||
| 519 | CMP AX,CX | ||
| 520 | retz ; Size matched | ||
| 521 | WRONGCOM: | ||
| 522 | MOV DX,COMBAD ;AC000; | ||
| 523 | CALL GETCOMDSK | ||
| 524 | JMP LOADCOM ; Try again | ||
| 525 | |||
| 526 | CHKSUM: ; Compute transient checksum | ||
| 527 | PUSH DS | ||
| 528 | MOV DS,[TRNSEG] | ||
| 529 | MOV SI,100H | ||
| 530 | MOV CX,OFFSET TRANGROUP:TranDataEnd - 100H | ||
| 531 | |||
| 532 | CHECK_SUM: | ||
| 533 | CLD | ||
| 534 | SHR CX,1 | ||
| 535 | XOR DX,DX | ||
| 536 | CHK: | ||
| 537 | LODSW | ||
| 538 | ADD DX,AX | ||
| 539 | ADC DX,0 | ||
| 540 | LOOP CHK | ||
| 541 | POP DS | ||
| 542 | return | ||
| 543 | |||
| 544 | SETVECT: ; Set useful vectors | ||
| 545 | MOV DX,OFFSET RESGROUP:LODCOM | ||
| 546 | MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 22H | ||
| 547 | MOV WORD PTR DS:[PDB_EXIT],DX | ||
| 548 | MOV WORD PTR DS:[PDB_EXIT+2],DS | ||
| 549 | INT int_command | ||
| 550 | MOV DX,OFFSET RESGROUP:CONTC | ||
| 551 | INC AL | ||
| 552 | INT int_command | ||
| 553 | MOV DX,OFFSET RESGROUP:DSKERR | ||
| 554 | INC AL | ||
| 555 | INT int_command | ||
| 556 | return | ||
| 557 | |||
| 558 | |||
| 559 | ; | ||
| 560 | ; This routine moves the environment to a newly allocated segment | ||
| 561 | ; at the end of initialization | ||
| 562 | ; | ||
| 563 | |||
| 564 | ENDINIT: | ||
| 565 | push ds ;g save segments | ||
| 566 | push es ;g | ||
| 567 | push cs ;g get resident segment to DS | ||
| 568 | pop ds ;g | ||
| 569 | ASSUME DS:RESGROUP | ||
| 570 | mov cx,usedenv ;g get number of bytes to move | ||
| 571 | mov es,envirseg ;g get target environment segment | ||
| 572 | |||
| 573 | ASSUME ES:NOTHING | ||
| 574 | mov DS:[PDB_environ],es ;g put new environment in my header ;AM067; | ||
| 575 | mov ds,oldenv ;g source environment segment ;AM067; | ||
| 576 | ASSUME DS:NOTHING ;AM067; | ||
| 577 | xor si,si ;g set up offsets to start of segments ;AM067; | ||
| 578 | xor di,di ;g ;AM067; | ||
| 579 | cld ;g make sure we move the right way! ;AM067; | ||
| 580 | rep movsb ;g move it ;AM067; | ||
| 581 | xor ax,ax ;g ;AM067; | ||
| 582 | stosb ;g make sure there are double 0 at end ;AM067; | ||
| 583 | |||
| 584 | cmp resetenv,1 ;eg Do we need to setblock to env end? | ||
| 585 | jnz noreset ;eg no - we already did it | ||
| 586 | mov bx,envsiz ;eg get size of environment in paragraphs | ||
| 587 | push es ;eg save environment - just to make sure | ||
| 588 | mov ah,SETBLOCK ;eg | ||
| 589 | int int_command ;eg | ||
| 590 | pop es ;eg | ||
| 591 | |||
| 592 | noreset: | ||
| 593 | mov InitFlag,FALSE ;AC042; Turn off init flag | ||
| 594 | pop es ;g | ||
| 595 | pop ds ;g | ||
| 596 | jmp lodcom ;g allocate transient | ||
| 597 | |||
| 598 | CODERES ENDS | ||
| 599 | |||
| 600 | ; This TAIL segment is used to produce a PARA aligned label in the resident | ||
| 601 | ; group which is the location where the transient segments will be loaded | ||
| 602 | ; initial. | ||
| 603 | |||
| 604 | TAIL SEGMENT PUBLIC PARA | ||
| 605 | ORG 0 | ||
| 606 | PUBLIC TranStart | ||
| 607 | TRANSTART LABEL WORD | ||
| 608 | TAIL ENDS | ||
| 609 | |||
| 610 | ; This TAIL segment is used to produce a PARA aligned label in the transient | ||
| 611 | ; group which is the location where the exec segments will be loaded | ||
| 612 | ; initial. | ||
| 613 | |||
| 614 | TRANTAIL SEGMENT PUBLIC PARA | ||
| 615 | ORG 0 | ||
| 616 | EXECSTART LABEL WORD | ||
| 617 | TRANTAIL ENDS | ||
| 618 | |||
| 619 | END | ||
diff --git a/v4.0/src/CMD/COMMAND/COMSEG.ASM b/v4.0/src/CMD/COMMAND/COMSEG.ASM new file mode 100644 index 0000000..81cfa30 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/COMSEG.ASM | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | ; SCCSID = @(#)comseg.asm 1.1 85/05/14 | ||
| 2 | ; SCCSID = @(#)comseg.asm 1.1 85/05/14 | ||
| 3 | ; The following are all of the segments used in the load order | ||
| 4 | |||
| 5 | CODERES SEGMENT PUBLIC BYTE ;AC000; resident code | ||
| 6 | CODERES ENDS | ||
| 7 | |||
| 8 | DATARES SEGMENT PUBLIC BYTE ;AC000; resident data | ||
| 9 | DATARES ENDS | ||
| 10 | |||
| 11 | BATARENA SEGMENT PUBLIC PARA ;AC000; space for DOS ALLOCATE header | ||
| 12 | BATARENA ENDS | ||
| 13 | |||
| 14 | BATSEG SEGMENT PUBLIC PARA ;AC000; AUTOEXEC batch segment | ||
| 15 | BATSEG ENDS | ||
| 16 | |||
| 17 | ENVARENA SEGMENT PUBLIC PARA ;AC000; space for DOS ALLOCATE header | ||
| 18 | ENVARENA ENDS | ||
| 19 | |||
| 20 | ENVIRONMENT SEGMENT PUBLIC PARA ;AC000; Default COMMAND environment | ||
| 21 | ENVIRONMENT ENDS | ||
| 22 | |||
| 23 | INIT SEGMENT PUBLIC PARA ;AC000; Initialization code | ||
| 24 | INIT ENDS | ||
| 25 | |||
| 26 | TAIL SEGMENT PUBLIC PARA ;AC000; End of Init - start of Transient | ||
| 27 | TAIL ENDS | ||
| 28 | |||
| 29 | TRANCODE SEGMENT PUBLIC BYTE ;AC000; Transient code | ||
| 30 | TRANCODE ENDS | ||
| 31 | |||
| 32 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; Transient data area | ||
| 33 | TRANDATA ENDS | ||
| 34 | |||
| 35 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; Transient modifiable data area | ||
| 36 | TRANSPACE ENDS | ||
| 37 | |||
| 38 | TRANTAIL SEGMENT PUBLIC PARA ;AC000; End of Transient | ||
| 39 | TRANTAIL ENDS | ||
| 40 | |||
| 41 | RESGROUP GROUP CODERES,DATARES,BATARENA,BATSEG,ENVARENA,ENVIRONMENT,INIT,TAIL | ||
| 42 | TRANGROUP GROUP TRANCODE,TRANDATA,TRANSPACE,TRANTAIL | ||
| 43 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/COMMAND/COMSW.ASM b/v4.0/src/CMD/COMMAND/COMSW.ASM new file mode 100644 index 0000000..dbad747 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/COMSW.ASM | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | ; SCCSID = @(#)comsw.asm 1.1 85/05/14 | ||
| 2 | ; SCCSID = @(#)comsw.asm 1.1 85/05/14 | ||
| 3 | |||
| 4 | include version.inc | ||
| 5 | |||
| 6 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/COMMAND/COPY.ASM b/v4.0/src/CMD/COMMAND/COPY.ASM new file mode 100644 index 0000000..37bb886 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/COPY.ASM | |||
| @@ -0,0 +1,1001 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)copy.asm 1.1 85/05/14 | ||
| 3 | ; SCCSID = @(#)copy.asm 1.1 85/05/14 | ||
| 4 | TITLE COMMAND COPY routines. | ||
| 5 | |||
| 6 | ; MODIFICATION HISTORY | ||
| 7 | ; | ||
| 8 | ; 11/01/83 EE Added a few lines at the end of SCANSRC2 to get multiple | ||
| 9 | ; file concatenations (eg copy a.*+b.*+c.*) to work properly. | ||
| 10 | ; 11/02/83 EE Commented out the code in CPARSE which added drive designators | ||
| 11 | ; to tokens which begin with path characters so that PARSELINE | ||
| 12 | ; will work correctly. | ||
| 13 | ; 11/04/83 EE Commented out the code in CPARSE that considered paren's to be | ||
| 14 | ; individual tokens. That distinction is no longer needed for | ||
| 15 | ; FOR loop processing. | ||
| 16 | ; 11/17/83 EE CPARSE upper case conversion is now flag dependent. Flag is | ||
| 17 | ; 1 when Cparse is called from COPY. | ||
| 18 | ; 11/17/83 EE Took out the comment chars around code described in 11/04/83 | ||
| 19 | ; mod. It now is conditional on flag like previous mod. | ||
| 20 | ; 11/21/83 NP Added printf | ||
| 21 | ; 12/09/83 EE CPARSE changed to use CPYFLAG to determine when a colon should | ||
| 22 | ; be added to a token. | ||
| 23 | ; 05/30/84 MZ Initialize all copy variables. Fix confusion with destclosed | ||
| 24 | ; NOTE: DestHand is the destination handle. There are two | ||
| 25 | ; special values: -1 meaning destination was never opened and | ||
| 26 | ; 0 which means that the destination has been openned and | ||
| 27 | ; closed. | ||
| 28 | ; 06/01/84 MZ Above reasoning totally specious. Returned things to normal | ||
| 29 | ; 06/06/86 EG Change to fix problem of source switches /a and /b getting | ||
| 30 | ; lost on large and multiple file (wildcard) copies. | ||
| 31 | ; 06/09/86 EG Change to use xnametrans call to verify that source and | ||
| 32 | ; destination are not equal. | ||
| 33 | |||
| 34 | |||
| 35 | .xlist | ||
| 36 | .xcref | ||
| 37 | INCLUDE comsw.asm | ||
| 38 | INCLUDE DOSSYM.INC | ||
| 39 | INCLUDE comseg.asm | ||
| 40 | INCLUDE comequ.asm | ||
| 41 | .list | ||
| 42 | .cref | ||
| 43 | |||
| 44 | |||
| 45 | DATARES SEGMENT PUBLIC BYTE ;AC000; | ||
| 46 | EXTRN VERVAL:WORD | ||
| 47 | EXTRN RSRC_XA_SEG:WORD ;AN030; | ||
| 48 | DATARES ENDS | ||
| 49 | |||
| 50 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 51 | EXTRN BADCD_ptr:word | ||
| 52 | EXTRN COPIED_ptr:word | ||
| 53 | EXTRN Extend_buf_ptr:word ;AN000; | ||
| 54 | EXTRN Extend_buf_sub:byte ;AN000; | ||
| 55 | EXTRN file_name_ptr:word | ||
| 56 | EXTRN INBDEV_ptr:word ;AC000; | ||
| 57 | EXTRN msg_disp_class:byte ;AN000; | ||
| 58 | EXTRN overwr_ptr:word | ||
| 59 | TRANDATA ENDS | ||
| 60 | |||
| 61 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 62 | EXTRN ALLSWITCH:WORD | ||
| 63 | EXTRN ARGC:BYTE | ||
| 64 | EXTRN ASCII:BYTE | ||
| 65 | EXTRN BINARY:BYTE | ||
| 66 | EXTRN BYTCNT:WORD | ||
| 67 | EXTRN CFLAG:BYTE | ||
| 68 | EXTRN comma:byte | ||
| 69 | EXTRN CONCAT:BYTE | ||
| 70 | EXTRN concat_xa:byte ;AN000; | ||
| 71 | EXTRN copy_num:word ;AC000; | ||
| 72 | EXTRN CPDATE:WORD | ||
| 73 | EXTRN CPTIME:WORD | ||
| 74 | EXTRN cpyflag:byte ;AC000; | ||
| 75 | EXTRN CURDRV:BYTE | ||
| 76 | EXTRN DESTBUF:BYTE | ||
| 77 | EXTRN DestClosed:BYTE | ||
| 78 | EXTRN DESTFCB:BYTE | ||
| 79 | EXTRN DESTFCB2:BYTE | ||
| 80 | EXTRN DESTHAND:WORD | ||
| 81 | EXTRN DESTINFO:BYTE | ||
| 82 | EXTRN DESTISDIR:BYTE | ||
| 83 | EXTRN DESTSIZ:BYTE | ||
| 84 | EXTRN DESTSWITCH:WORD | ||
| 85 | EXTRN DESTTAIL:WORD | ||
| 86 | EXTRN DESTVARS:BYTE | ||
| 87 | EXTRN DIRBUF:BYTE | ||
| 88 | EXTRN expand_star:byte | ||
| 89 | EXTRN FILECNT:WORD | ||
| 90 | EXTRN FIRSTDEST:BYTE | ||
| 91 | EXTRN FRSTSRCH:BYTE | ||
| 92 | EXTRN INEXACT:BYTE | ||
| 93 | EXTRN MELCOPY:BYTE | ||
| 94 | EXTRN MELSTART:WORD | ||
| 95 | EXTRN msg_flag:byte ;AN022; | ||
| 96 | EXTRN NOWRITE:BYTE | ||
| 97 | EXTRN NXTADD:WORD | ||
| 98 | EXTRN objcnt:byte | ||
| 99 | EXTRN one_char_val:byte ;AN000; | ||
| 100 | EXTRN parse_last:word ;AN018; | ||
| 101 | EXTRN PLUS:BYTE | ||
| 102 | EXTRN plus_comma:byte | ||
| 103 | EXTRN RDEOF:BYTE | ||
| 104 | EXTRN RESSEG:WORD | ||
| 105 | EXTRN SCANBUF:BYTE | ||
| 106 | EXTRN SDIRBUF:BYTE | ||
| 107 | EXTRN src_xa_size:word ;AN000; | ||
| 108 | EXTRN src_xa_seg:word ;AN000; | ||
| 109 | EXTRN SRCBUF:BYTE | ||
| 110 | EXTRN SRCHAND:WORD | ||
| 111 | EXTRN SRCINFO:BYTE | ||
| 112 | EXTRN SRCISDEV:BYTE | ||
| 113 | EXTRN SRCPT:WORD | ||
| 114 | EXTRN SRCSIZ:BYTE | ||
| 115 | EXTRN SRCTAIL:WORD | ||
| 116 | EXTRN SRCVARS:BYTE | ||
| 117 | EXTRN srcxname:byte | ||
| 118 | EXTRN STARTEL:WORD | ||
| 119 | EXTRN string_ptr_2:word | ||
| 120 | EXTRN TERMREAD:BYTE | ||
| 121 | EXTRN TPA:WORD | ||
| 122 | EXTRN USERDIR1:BYTE | ||
| 123 | EXTRN WRITTEN:WORD | ||
| 124 | EXTRN xa_cp_out:byte ;AN030; | ||
| 125 | EXTRN xa_list_attr:word ;AC030; | ||
| 126 | TRANSPACE ENDS | ||
| 127 | |||
| 128 | |||
| 129 | ; ****************************************** | ||
| 130 | ; COPY CODE | ||
| 131 | ; | ||
| 132 | |||
| 133 | TRANCODE SEGMENT PUBLIC BYTE | ||
| 134 | |||
| 135 | EXTRN CERROR:NEAR | ||
| 136 | EXTRN COPERR:NEAR | ||
| 137 | EXTRN TCOMMAND:NEAR | ||
| 138 | |||
| 139 | PUBLIC COPY | ||
| 140 | |||
| 141 | ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING | ||
| 142 | break Copy | ||
| 143 | assume ds:trangroup,es:trangroup | ||
| 144 | |||
| 145 | COPY: | ||
| 146 | ; First order of buisness is to find out about the destination | ||
| 147 | ; | ||
| 148 | ; initialize all internal variables | ||
| 149 | ; | ||
| 150 | xor ax,ax | ||
| 151 | mov copy_num,ax | ||
| 152 | mov SrcPt,AX | ||
| 153 | mov SrcTail,AX | ||
| 154 | mov CFlag,AL | ||
| 155 | mov NxtAdd,AX | ||
| 156 | mov DestSwitch,AX | ||
| 157 | mov StartEl,AX | ||
| 158 | mov DestTail,AX | ||
| 159 | mov DestClosed,AL | ||
| 160 | mov DestSiz,AL | ||
| 161 | mov SrcSiz,AL | ||
| 162 | mov DestInfo,AL | ||
| 163 | mov SrcInfo,AL | ||
| 164 | mov InExact,AL | ||
| 165 | mov DestVars,AL | ||
| 166 | mov SrcVars,AL | ||
| 167 | mov UserDir1,AL | ||
| 168 | mov NoWrite,AL | ||
| 169 | mov RdEOF,AL | ||
| 170 | mov SrcHand,AX | ||
| 171 | mov CpDate,AX | ||
| 172 | mov CpTime,AX | ||
| 173 | mov xa_list_attr,ax ;AN030; initialize code page to none | ||
| 174 | mov SrcIsDev,AL | ||
| 175 | mov TermRead,AL | ||
| 176 | mov comma,al ;g | ||
| 177 | mov plus_comma,al ;g | ||
| 178 | mov msg_flag,al ;AN022; | ||
| 179 | mov [ALLSWITCH],AX ; no switches | ||
| 180 | mov [ARGC],al ; no arguments | ||
| 181 | mov [PLUS],al ; no concatenation | ||
| 182 | mov [BINARY],al ; Binary not specifically specified | ||
| 183 | mov [ASCII],al ; ASCII not specifically specified | ||
| 184 | mov [FILECNT],ax ; No files yet | ||
| 185 | mov [WRITTEN],ax ; Nothing written yet | ||
| 186 | mov [CONCAT],al ; No concatenation | ||
| 187 | mov [MELCOPY],al ; Not a Mel Hallerman copy | ||
| 188 | mov [concat_xa],al ;AN000; initialize flag for concatenation XA | ||
| 189 | mov MelStart,ax ; Not a Mel Hallerman copy | ||
| 190 | mov word ptr [SCANBUF],ax ; Init buffer | ||
| 191 | mov word ptr [DESTBUF],ax ; Init buffer | ||
| 192 | mov word ptr [SRCBUF],ax ; Init buffer | ||
| 193 | mov word ptr [SDIRBUF],ax ; Init buffer | ||
| 194 | mov word ptr [DIRBUF],ax ; Init buffer | ||
| 195 | mov word ptr [DESTFCB],ax ; Init buffer | ||
| 196 | mov objcnt,al ; Init command line object count | ||
| 197 | dec ax | ||
| 198 | mov DestHand,AX ; destination has never been opened | ||
| 199 | mov [FRSTSRCH],al ; First search call | ||
| 200 | mov [FIRSTDEST],al ; First time | ||
| 201 | mov [DESTISDIR],al ; Don't know about dest | ||
| 202 | mov src_xa_seg,ax ;AN000; initialize attribute segment to -1 | ||
| 203 | mov si,81H | ||
| 204 | mov bl,plus_chr ; include '+' as a delimiter | ||
| 205 | inc byte ptr [expand_star] ; want to include * expansion in cparse | ||
| 206 | mov cpyflag,1 ; Turn "CPARSE called from COPY flag" on | ||
| 207 | |||
| 208 | DESTSCAN: | ||
| 209 | xor bp,bp ; no switches | ||
| 210 | mov di,offset trangroup:SCANBUF | ||
| 211 | mov parse_last,si ;AN018; save start of parsed string | ||
| 212 | invoke CPARSE | ||
| 213 | PUSHF ; save flags | ||
| 214 | inc objcnt | ||
| 215 | test bh,80H ; A '+' argument? | ||
| 216 | jz NOPLUS ; no | ||
| 217 | mov [PLUS],1 ; yes | ||
| 218 | NOPLUS: | ||
| 219 | test bh,1 ; Switch? | ||
| 220 | jz TESTP2 ; no | ||
| 221 | |||
| 222 | test bp,SwitchV ;AN038; Verify requested? | ||
| 223 | jz not_slashv ;AN038; No - set the switch | ||
| 224 | test [allswitch],SwitchV ;AN038; Verify already entered? | ||
| 225 | jz not_slashv ;AN038; No - set the switch | ||
| 226 | ;AD018; or [allswitch],FBadSwitch ;AN038; Set up bad switch | ||
| 227 | or BP,FBadSwitch ;AN018; Set up bad switch | ||
| 228 | |||
| 229 | not_slashv: ;AN038; | ||
| 230 | or [DESTSWITCH],BP ; Yes, assume destination | ||
| 231 | or [ALLSWITCH],BP ; keep tabs on all switches | ||
| 232 | |||
| 233 | test BP,NOT SwitchCopy ;AN018; Bad switch? | ||
| 234 | jz NOT_BAD_SWITCH ;AN018; Switches are okay | ||
| 235 | popf ;AN018; fix up stack | ||
| 236 | mov ax,BadSwt_ptr ;AN018; get "Invalid switch" message number | ||
| 237 | invoke Setup_parse_error_msg ;AN018; setup to print the message | ||
| 238 | jmp CERROR ;AC018; exit | ||
| 239 | |||
| 240 | NOT_BAD_SWITCH: ;AN018; switch okay | ||
| 241 | POPF ; get flags back | ||
| 242 | jc CHECKDONE ; Hit CR? | ||
| 243 | jmp short DESTSCAN | ||
| 244 | |||
| 245 | TESTP2: | ||
| 246 | POPF ; get flags back | ||
| 247 | jc CHECKDONE ; Hit CR? | ||
| 248 | test bh,80H ; Plus? | ||
| 249 | jnz GOTPLUS ; Yes, not a separate arg | ||
| 250 | inc [ARGC] ; found a real arg | ||
| 251 | GOTPLUS: | ||
| 252 | push SI | ||
| 253 | mov ax,[STARTEL] | ||
| 254 | mov SI,offset trangroup:SCANBUF ; Adjust to copy | ||
| 255 | sub ax,SI | ||
| 256 | mov DI,offset trangroup:DESTBUF | ||
| 257 | add ax,DI | ||
| 258 | mov [DESTTAIL],AX | ||
| 259 | mov [DESTSIZ],cl ; Save its size | ||
| 260 | inc cx ; Include the nul | ||
| 261 | rep movsb ; Save potential destination | ||
| 262 | mov [DESTINFO],bh ; Save info about it | ||
| 263 | mov [DESTSWITCH],0 ; reset switches | ||
| 264 | pop SI | ||
| 265 | jmp DESTSCAN ;AC018; keep going | ||
| 266 | |||
| 267 | CHECKDONE: | ||
| 268 | cmp plus,1 ; If a statement like "copy file+" is | ||
| 269 | jnz cdcont ; entered, complain about it. | ||
| 270 | cmp argc,1 | ||
| 271 | jnz cdcont | ||
| 272 | cmp objcnt,2 | ||
| 273 | jnz cdcont | ||
| 274 | mov dx,offset trangroup:overwr_ptr | ||
| 275 | jmp coperr | ||
| 276 | cdcont: | ||
| 277 | mov al,[PLUS] | ||
| 278 | mov [CONCAT],al ; PLUS -> Concatination | ||
| 279 | shl al,1 | ||
| 280 | shl al,1 | ||
| 281 | mov [INEXACT],al ; CONCAT -> inexact copy | ||
| 282 | mov al,[ARGC] | ||
| 283 | or al,al ; Good number of args? | ||
| 284 | jnz TRY_TOO_MANY ;AC000; there are args, see if too many | ||
| 285 | MOV DX,OFFSET TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer | ||
| 286 | mov Extend_Buf_ptr,LessArgs_ptr ;AN000; get "Required parameters missing" message number | ||
| 287 | jmp short cerror_parsej ;AN000; exit | ||
| 288 | |||
| 289 | TRY_TOO_MANY: | ||
| 290 | cmp al,2 | ||
| 291 | jbe ACOUNTOK | ||
| 292 | MOV DX,OFFSET TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer | ||
| 293 | mov Extend_Buf_ptr,MoreArgs_ptr ;AN000; get "Too many parameters" message number | ||
| 294 | |||
| 295 | CERROR_PARSEJ: | ||
| 296 | mov msg_disp_class,parse_msg_class ;AN000; set up parse error msg class | ||
| 297 | CERROR4J: | ||
| 298 | jmp CERROR ; no, too many | ||
| 299 | |||
| 300 | ACOUNTOK: | ||
| 301 | mov bp,offset trangroup:DESTVARS | ||
| 302 | cmp al,1 | ||
| 303 | jnz GOT2ARGS | ||
| 304 | mov al,[CURDRV] ; Dest is default drive:*.* | ||
| 305 | add al,capital_A | ||
| 306 | mov ah,':' | ||
| 307 | mov [bp.SIZ],2 | ||
| 308 | mov di,offset trangroup:DESTBUF | ||
| 309 | stosw | ||
| 310 | mov [DESTSWITCH],0 ; no switches on dest | ||
| 311 | mov [bp.INFO],2 ; Flag dest is ambig | ||
| 312 | mov [bp.ISDIR],0 ; Know destination specs file | ||
| 313 | invoke SETSTARS | ||
| 314 | GOT2ARGS: | ||
| 315 | cmp [bp.SIZ],2 | ||
| 316 | jnz NOTSHORTDEST | ||
| 317 | mov al,':' | ||
| 318 | cmp [DESTBUF+1],al | ||
| 319 | jnz NOTSHORTDEST ; Two char file name | ||
| 320 | or [bp.INFO],2 ; Know dest is d: | ||
| 321 | mov di,offset trangroup:DESTBUF + 2 | ||
| 322 | mov [bp.ISDIR],0 ; Know destination specs file | ||
| 323 | invoke SETSTARS | ||
| 324 | NOTSHORTDEST: | ||
| 325 | mov di,[bp.TTAIL] | ||
| 326 | cmp byte ptr [DI],0 | ||
| 327 | jnz CHKSWTCHES | ||
| 328 | mov dx,offset trangroup:BADCD_ptr | ||
| 329 | mov al,':' | ||
| 330 | cmp byte ptr [DI-2],al | ||
| 331 | jnz CERROR4J ; Trailing '/' error | ||
| 332 | mov [bp.ISDIR],2 ; Know destination is d:/ | ||
| 333 | or [bp.INFO],6 | ||
| 334 | invoke SETSTARS | ||
| 335 | CHKSWTCHES: | ||
| 336 | ;AD018; mov ax,[ALLSWITCH] | ||
| 337 | ;AD018; test ax,NOT SwitchCopy | ||
| 338 | ;AD018; jz NOT_BAD_SWITCH ;AN000; Switches are okay | ||
| 339 | ;AD018; MOV DX,OFFSET TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer | ||
| 340 | ;AD018; mov Extend_Buf_ptr,BadSwt_ptr ;AN000; get "Invalid switch" message number | ||
| 341 | ;AD018; jmp short CERROR_PARSEJ ;AC000; Switch specified which is not known | ||
| 342 | |||
| 343 | ; Now know most of the information needed about the destination | ||
| 344 | |||
| 345 | ;AD018; NOT_BAD_SWITCH: | ||
| 346 | if not ibmcopyright | ||
| 347 | mov ax, [allswitch] ; Which switches were requested? Hmmm? | ||
| 348 | endif | ||
| 349 | TEST AX,SwitchV ; Verify requested? | ||
| 350 | JZ NOVERIF ; No | ||
| 351 | MOV AH,GET_VERIFY_ON_WRITE | ||
| 352 | INT int_command ; Get current setting | ||
| 353 | PUSH DS | ||
| 354 | MOV DS,[RESSEG] | ||
| 355 | ASSUME DS:RESGROUP | ||
| 356 | XOR AH,AH | ||
| 357 | MOV [VERVAL],AX ; Save current setting | ||
| 358 | POP DS | ||
| 359 | ASSUME DS:TRANGROUP | ||
| 360 | MOV AX,(SET_VERIFY_ON_WRITE SHL 8) OR 1 ; Set verify | ||
| 361 | INT int_command | ||
| 362 | NOVERIF: | ||
| 363 | xor bp,bp ; no switches | ||
| 364 | mov si,81H | ||
| 365 | mov bl,plus_chr ; include '+' as a delimiter | ||
| 366 | SCANFSRC: | ||
| 367 | mov di,offset trangroup:SCANBUF | ||
| 368 | invoke CPARSE ; Parse first source name | ||
| 369 | test bh,1 ; Switch? | ||
| 370 | jnz SCANFSRC ; Yes, try again | ||
| 371 | or [DESTSWITCH],bp ; Include copy wide switches on dest | ||
| 372 | test bp,SwitchB | ||
| 373 | jnz NOSETCASC ; Binary explicit | ||
| 374 | cmp [CONCAT],0 | ||
| 375 | JZ NOSETCASC ; Not Concat | ||
| 376 | mov [ASCII],SwitchA ; Concat -> ASCII copy if no B switch | ||
| 377 | mov [concat_xa],do_xa ;AN000; set up to do XA only on first file | ||
| 378 | NOSETCASC: | ||
| 379 | call source_set | ||
| 380 | call FRSTSRC | ||
| 381 | jmp FIRSTENT | ||
| 382 | |||
| 383 | PUBLIC EndCopy | ||
| 384 | ENDCOPY: | ||
| 385 | CALL CLOSEDEST | ||
| 386 | ENDCOPY2: | ||
| 387 | call deallocate_src_xa ;AN030; deallocate xa segment | ||
| 388 | invoke free_tpa ;AN000; Make sure work area | ||
| 389 | invoke alloc_tpa ;AN000; is reset properly | ||
| 390 | MOV DX,OFFSET TRANGROUP:COPIED_ptr | ||
| 391 | MOV SI,[FILECNT] | ||
| 392 | mov copy_num,si | ||
| 393 | invoke std_printf | ||
| 394 | JMP TCOMMAND ; Stack could be messed up | ||
| 395 | |||
| 396 | SRCNONEXIST: | ||
| 397 | cmp [CONCAT],0 | ||
| 398 | jnz NEXTSRC ; If in concat mode, ignore error | ||
| 399 | mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class | ||
| 400 | mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer | ||
| 401 | mov Extend_Buf_ptr,error_file_not_found ;AN000; get message number in control block | ||
| 402 | mov string_ptr_2,offset trangroup:srcbuf ;AC046; get address of failed string | ||
| 403 | mov Extend_buf_sub,one_subst ;AC046; put number of subst in control block | ||
| 404 | jmp COPERR | ||
| 405 | |||
| 406 | SOURCEPROC: | ||
| 407 | call source_set | ||
| 408 | cmp [CONCAT],0 | ||
| 409 | jnz LEAVECFLAG ; Leave CFLAG if concatination | ||
| 410 | FRSTSRC: | ||
| 411 | xor ax,ax | ||
| 412 | mov [CFLAG],al ; Flag destination not created | ||
| 413 | mov [NXTADD],ax ; Zero out buffer | ||
| 414 | mov DestClosed,AL | ||
| 415 | LEAVECFLAG: | ||
| 416 | mov [SRCPT],SI ; remember where we are | ||
| 417 | mov di,offset trangroup:USERDIR1 | ||
| 418 | mov bp,offset trangroup:SRCVARS | ||
| 419 | invoke BUILDPATH ; Figure out everything about the source | ||
| 420 | mov si,[SRCTAIL] ; Create the search FCB | ||
| 421 | return | ||
| 422 | |||
| 423 | NEXTSRC: | ||
| 424 | cmp [PLUS],0 | ||
| 425 | jnz MORECP | ||
| 426 | ENDCOPYJ2: | ||
| 427 | jmp ENDCOPY ; Done | ||
| 428 | MORECP: | ||
| 429 | xor bp,bp ; no switches | ||
| 430 | mov si,[SRCPT] | ||
| 431 | mov bl,plus_chr ; include '+' as a delimiter | ||
| 432 | SCANSRC: | ||
| 433 | mov di,offset trangroup:SCANBUF | ||
| 434 | invoke CPARSE ; Parse first source name | ||
| 435 | JC EndCopyJ2 ; if error, then end (trailing + case) | ||
| 436 | test bh,80H | ||
| 437 | jz ENDCOPYJ2 ; If no '+' we're done | ||
| 438 | test bh,1 ; Switch? | ||
| 439 | jnz SCANSRC ; Yes, try again | ||
| 440 | call SOURCEPROC | ||
| 441 | cmp comma,1 ;g was +,, found last time? | ||
| 442 | jnz nostamp ;g no - try for a file | ||
| 443 | mov plus_comma,1 ;g yes - set flag | ||
| 444 | jmp srcnonexist ;g we know we won't find it | ||
| 445 | nostamp: ;g | ||
| 446 | mov plus_comma,0 ;g reset +,, flag | ||
| 447 | FIRSTENT: | ||
| 448 | mov di,FCB | ||
| 449 | mov ax,PARSE_FILE_DESCRIPTOR SHL 8 | ||
| 450 | INT int_command | ||
| 451 | CMP BYTE PTR [SI],0 ; parse everything? | ||
| 452 | JNZ SrchDone ; no, error, simulate no more search | ||
| 453 | mov ax,word ptr [SRCBUF] ; Get drive | ||
| 454 | cmp ah,':' | ||
| 455 | jz DRVSPEC1 | ||
| 456 | mov al,'@' | ||
| 457 | DRVSPEC1: | ||
| 458 | or al,20h | ||
| 459 | sub al,60h | ||
| 460 | mov ds:[FCB],al | ||
| 461 | mov ah,DIR_SEARCH_FIRST | ||
| 462 | call SEARCH | ||
| 463 | SrchDone: | ||
| 464 | pushf ; Save result of search | ||
| 465 | invoke RESTUDIR1 ; Restore users dir | ||
| 466 | popf | ||
| 467 | jz NEXTAMBIG0 | ||
| 468 | jmp SRCNONEXIST ; Failed | ||
| 469 | NEXTAMBIG0: | ||
| 470 | xor al,al | ||
| 471 | xchg al,[FRSTSRCH] | ||
| 472 | or al,al | ||
| 473 | jz NEXTAMBIG | ||
| 474 | SETNMEL: | ||
| 475 | mov cx,12 | ||
| 476 | mov di,OFFSET TRANGROUP:SDIRBUF | ||
| 477 | mov si,OFFSET TRANGROUP:DIRBUF | ||
| 478 | rep movsb ; Save very first source name | ||
| 479 | NEXTAMBIG: | ||
| 480 | xor al,al | ||
| 481 | mov [NOWRITE],al ; Turn off NOWRITE | ||
| 482 | mov di,[SRCTAIL] | ||
| 483 | mov si,offset trangroup:DIRBUF + 1 | ||
| 484 | invoke FCB_TO_ASCZ ; SRCBUF has complete name | ||
| 485 | MELDO: | ||
| 486 | cmp [CONCAT],0 | ||
| 487 | jnz SHOWCPNAM ; Show name if concat | ||
| 488 | test [SRCINFO],2 ; Show name if multi | ||
| 489 | jz DOREAD | ||
| 490 | SHOWCPNAM: | ||
| 491 | mov dx,offset trangroup:file_name_ptr | ||
| 492 | invoke std_printf | ||
| 493 | invoke CRLF2 | ||
| 494 | DOREAD: | ||
| 495 | call DOCOPY | ||
| 496 | cmp [CONCAT],0 | ||
| 497 | jnz NODCLOSE ; If concat, do not close | ||
| 498 | call CLOSEDEST ; else close current destination | ||
| 499 | jc NODCLOSE ; Concat flag got set, close didn't really happen | ||
| 500 | mov [CFLAG],0 ; Flag destination not created | ||
| 501 | NODCLOSE: | ||
| 502 | cmp [CONCAT],0 ; Check CONCAT again | ||
| 503 | jz NOFLUSH | ||
| 504 | invoke FLSHFIL ; Flush output between source files on | ||
| 505 | ; CONCAT so LOSTERR stuff works | ||
| 506 | ; correctly | ||
| 507 | TEST [MELCOPY],0FFH | ||
| 508 | jz NOFLUSH | ||
| 509 | jmp SHORT DOMELCOPY | ||
| 510 | |||
| 511 | NOFLUSH: | ||
| 512 | call SEARCHNEXT ; Try next match | ||
| 513 | jnz NEXTSRCJ ; Finished with this source spec | ||
| 514 | mov [DESTCLOSED],0 ; Not created or concat ->... | ||
| 515 | jmp NEXTAMBIG ; Do next ambig | ||
| 516 | |||
| 517 | DOMELCOPY: | ||
| 518 | cmp [MELCOPY],0FFH | ||
| 519 | jz CONTMEL | ||
| 520 | mov SI,[SRCPT] | ||
| 521 | mov [MELSTART],si | ||
| 522 | mov [MELCOPY],0FFH | ||
| 523 | CONTMEL: | ||
| 524 | xor BP,BP | ||
| 525 | mov si,[SRCPT] | ||
| 526 | mov bl,plus_chr | ||
| 527 | SCANSRC2: | ||
| 528 | mov di,OFFSET TRANGROUP:SCANBUF | ||
| 529 | invoke CPARSE | ||
| 530 | test bh,80H | ||
| 531 | jz NEXTMEL ; Go back to start | ||
| 532 | test bh,1 ; Switch ? | ||
| 533 | jnz SCANSRC2 ; Yes | ||
| 534 | call SOURCEPROC | ||
| 535 | invoke RESTUDIR1 | ||
| 536 | mov di,OFFSET TRANGROUP:DESTFCB2 | ||
| 537 | mov ax,PARSE_FILE_DESCRIPTOR SHL 8 | ||
| 538 | INT int_command | ||
| 539 | mov bx,OFFSET TRANGROUP:SDIRBUF + 1 | ||
| 540 | mov si,OFFSET TRANGROUP:DESTFCB2 + 1 | ||
| 541 | mov di,[SRCTAIL] | ||
| 542 | invoke BUILDNAME | ||
| 543 | cmp [CONCAT],0 ; Are we concatenating? | ||
| 544 | jz meldoj ; No, continue. | ||
| 545 | ; | ||
| 546 | ; Yes, turn off nowrite because this part of the code is only reached after | ||
| 547 | ; the first file has been dealt with. | ||
| 548 | ; | ||
| 549 | mov [NOWRITE],0 | ||
| 550 | meldoj: | ||
| 551 | jmp MELDO | ||
| 552 | |||
| 553 | NEXTSRCJ: | ||
| 554 | jmp NEXTSRC | ||
| 555 | |||
| 556 | NEXTMEL: | ||
| 557 | call CLOSEDEST | ||
| 558 | xor ax,ax | ||
| 559 | mov [CFLAG],al | ||
| 560 | mov [NXTADD],ax | ||
| 561 | mov [DESTCLOSED],al | ||
| 562 | mov si,[MELSTART] | ||
| 563 | mov [SRCPT],si | ||
| 564 | call SEARCHNEXT | ||
| 565 | jz SETNMELJ | ||
| 566 | jmp ENDCOPY2 | ||
| 567 | SETNMELJ: | ||
| 568 | jmp SETNMEL | ||
| 569 | |||
| 570 | SEARCHNEXT: | ||
| 571 | MOV AH,DIR_SEARCH_NEXT | ||
| 572 | TEST [SRCINFO],2 | ||
| 573 | JNZ SEARCH ; Do search-next if ambig | ||
| 574 | OR AH,AH ; Reset zero flag | ||
| 575 | return | ||
| 576 | SEARCH: | ||
| 577 | PUSH AX | ||
| 578 | MOV AH,SET_DMA | ||
| 579 | MOV DX,OFFSET TRANGROUP:DIRBUF | ||
| 580 | INT int_command ; Put result of search in DIRBUF | ||
| 581 | POP AX ; Restore search first/next command | ||
| 582 | MOV DX,FCB | ||
| 583 | INT int_command ; Do the search | ||
| 584 | OR AL,AL | ||
| 585 | return | ||
| 586 | |||
| 587 | DOCOPY: | ||
| 588 | mov si,offset trangroup:SRCBUF ;g do name translate of source | ||
| 589 | mov di,offset trangroup:SRCXNAME ;g save for name comparison | ||
| 590 | mov ah,xnametrans ;g | ||
| 591 | int int_command ;g | ||
| 592 | |||
| 593 | mov [RDEOF],0 ; No EOF yet | ||
| 594 | |||
| 595 | MOV AX,EXTOPEN SHL 8 ;AC000; open the file | ||
| 596 | mov bx,read_open_mode ;AN000; get open mode for COPY | ||
| 597 | xor cx,cx ;AN000; no special files | ||
| 598 | mov dx,read_open_flag ;AN000; set up open flags | ||
| 599 | mov di,-1 ;AN030; no parameter list | ||
| 600 | INT int_command | ||
| 601 | |||
| 602 | jnc OpenOK | ||
| 603 | ; | ||
| 604 | ; Bogosity: IBM wants us to issue Access denied in this case. THey asked | ||
| 605 | ; for it... | ||
| 606 | ; | ||
| 607 | jmp error_on_source ;AC022; clean up and exit | ||
| 608 | |||
| 609 | OpenOK: | ||
| 610 | mov bx,ax ; Save handle | ||
| 611 | mov [SRCHAND],bx ; Save handle | ||
| 612 | mov ax,(FILE_TIMES SHL 8) | ||
| 613 | INT int_command | ||
| 614 | jc src_cp_error ;AN022; If error, exit | ||
| 615 | mov [CPDATE],dx ; Save DATE | ||
| 616 | mov [CPTIME],cx ; Save TIME | ||
| 617 | |||
| 618 | mov cx,xa_list_attr ;AN000; get old code page in cx | ||
| 619 | push cx ;AN000; save old attribute | ||
| 620 | mov xa_list_attr,0 ;AN000; initialize code page | ||
| 621 | |||
| 622 | mov ax,(file_times SHL 8)+get_XA ;AC030; get extended attribute size | ||
| 623 | mov si,-1 ;AN030; no querylist | ||
| 624 | xor cx,cx ;AN030; indicate we want size | ||
| 625 | int int_command ;AC000; | ||
| 626 | jc src_cp_error ;AN022; If error, exit | ||
| 627 | mov src_xa_size,cx ;AN000; save size | ||
| 628 | cmp cx,0 ;AN000; are there any? | ||
| 629 | pop cx ;AN000; get old attribute | ||
| 630 | jz no_cp_get ;AN030; no - don't get attributes | ||
| 631 | |||
| 632 | push cx ;AN030; save old code page | ||
| 633 | invoke get_file_code_page_tag ;AN000; get file's code page | ||
| 634 | pop cx ;AN030 retrieve old code page | ||
| 635 | jnc no_cp_get ;AN000; no error - continue | ||
| 636 | src_cp_error: ;AN022; | ||
| 637 | jmp error_on_source ;AC022; and exit | ||
| 638 | |||
| 639 | no_cp_get: | ||
| 640 | cmp [concat],0 ;AN000; are we doing concatenation | ||
| 641 | jz get_src_xa ;AN000; no get source extended attrib | ||
| 642 | cmp [concat_xa],do_xa ;AN000; is this the first file? | ||
| 643 | jz get_src_xa ;AN000; yes - get extended attributes | ||
| 644 | cmp cx,xa_list_attr ;AN000; no - see if code pages match | ||
| 645 | jz no_copy_xa_jmp ;AN000; code pages match - continue | ||
| 646 | mov xa_list_attr,inv_cp_tag ;AN000; set invalid code page tag | ||
| 647 | no_copy_xa_jmp: ;AC022; | ||
| 648 | jmp no_copy_xa ;AN000; don't get extended attributes | ||
| 649 | |||
| 650 | get_src_xa: | ||
| 651 | call deallocate_src_xa ;AN030; deallocate any existing XA segment | ||
| 652 | cmp src_xa_size,0 ;AN000; are there any extended attributes? | ||
| 653 | jz no_copy_xa_jmp ;AC022; nothing there - don't allocate memory | ||
| 654 | push bx ;AN000; save handle | ||
| 655 | invoke free_tpa ;AN000; need to make free memory, first | ||
| 656 | mov bx,src_xa_size ;AN000; get bytes (size of XA) into bx | ||
| 657 | mov cl,4 ;AN000; divide bytes by 16 to convert | ||
| 658 | shr bx,cl ;AN000; to paragraphs | ||
| 659 | inc bx ;AN000; round up | ||
| 660 | mov ax,(alloc SHL 8) ;AN000; allocate memory for XA | ||
| 661 | int int_command ;AN000; | ||
| 662 | pushf ;AN000; save flags | ||
| 663 | mov [src_xa_seg], AX ;AN000; save new segment | ||
| 664 | push ds ;AN030; get resident segment | ||
| 665 | mov ds,[resseg] ;AN030; and save copy of xa | ||
| 666 | assume ds:resgroup ;AN030; segment in resident | ||
| 667 | mov [rsrc_xa_seg],ax ;AN030; in case user breaks | ||
| 668 | pop ds ;AN030; out or has critical | ||
| 669 | assume ds:trangroup ;AN030; error | ||
| 670 | invoke alloc_tpa ;AN000; reallocate the work area | ||
| 671 | popf ;AN000; restore flags | ||
| 672 | pop bx ;AN000; restore handle | ||
| 673 | jnc Alloc_for_xa_okay ;AN000; no carry - everything okay | ||
| 674 | call closesrc ;AN000; close the source file | ||
| 675 | mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class | ||
| 676 | mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer | ||
| 677 | mov Extend_Buf_ptr,error_not_enough_memory ;AN000; get message number in control block | ||
| 678 | jmp cerror ;AN000; exit | ||
| 679 | |||
| 680 | Alloc_for_xa_okay: | ||
| 681 | |||
| 682 | mov ax,(file_times SHL 8)+get_XA ;AN000; get extended attributes | ||
| 683 | push es ;AN000; save es | ||
| 684 | mov es,[src_xa_seg] ;AN000; get segment for XA list | ||
| 685 | xor di,di ;AN000; offset of return list | ||
| 686 | mov si,-1 ;AN030; get all attributes | ||
| 687 | mov cx,[src_xa_size] ;AN000; get size of list | ||
| 688 | int int_command ;AN000; get all the attributes | ||
| 689 | pop es ;AN000; restore es | ||
| 690 | jnc no_copy_xa ;AC022; no error - continue | ||
| 691 | |||
| 692 | error_on_source: ;AN022; we have a BAD error | ||
| 693 | invoke set_ext_error_msg ;AN022; set up the error message | ||
| 694 | mov string_ptr_2,offset trangroup:srcbuf ;AN022; get address of failed string | ||
| 695 | mov Extend_buf_sub,one_subst ;AN022; put number of subst in control block | ||
| 696 | invoke std_Eprintf ;AN022; print it | ||
| 697 | cmp [srchand],0 ;AN022; did we open the file? | ||
| 698 | jz no_close_src ;AN022; no - don't close | ||
| 699 | call closesrc ;AN022; clean up | ||
| 700 | no_close_src: ;AN022; | ||
| 701 | cmp [cflag],0 ;AN022; was destination created? | ||
| 702 | jz endcopyj3 ;AN022; no - just cleanup and exit | ||
| 703 | jmp endcopy ;AN022; clean up concatenation and exit | ||
| 704 | endcopyj3: ;AN022; | ||
| 705 | jmp endcopy2 ;AN022; | ||
| 706 | no_copy_xa: | ||
| 707 | mov bx,[srchand] ;AN022; get handle back | ||
| 708 | mov ax,(IOCTL SHL 8) | ||
| 709 | INT int_command ; Get device stuff | ||
| 710 | and dl,devid_ISDEV | ||
| 711 | mov [SRCISDEV],dl ; Set source info | ||
| 712 | jz COPYLP ; Source not a device | ||
| 713 | cmp [BINARY],0 | ||
| 714 | jz COPYLP ; ASCII device OK | ||
| 715 | mov dx,offset trangroup:INBDEV_ptr ; Cannot do binary input | ||
| 716 | jmp COPERR | ||
| 717 | |||
| 718 | COPYLP: | ||
| 719 | mov bx,[SRCHAND] | ||
| 720 | mov cx,[BYTCNT] | ||
| 721 | mov dx,[NXTADD] | ||
| 722 | sub cx,dx ; Compute available space | ||
| 723 | jnz GOTROOM | ||
| 724 | invoke FLSHFIL | ||
| 725 | CMP [TERMREAD],0 | ||
| 726 | JNZ CLOSESRC ; Give up | ||
| 727 | mov cx,[BYTCNT] | ||
| 728 | GOTROOM: | ||
| 729 | push ds | ||
| 730 | mov ds,[TPA] | ||
| 731 | ASSUME DS:NOTHING | ||
| 732 | mov ah,READ | ||
| 733 | INT int_command | ||
| 734 | pop ds | ||
| 735 | ASSUME DS:TRANGROUP | ||
| 736 | jc error_on_source ;AC022; Give up if error | ||
| 737 | mov cx,ax ; Get count | ||
| 738 | jcxz CLOSESRC ; No more to read | ||
| 739 | cmp [SRCISDEV],0 | ||
| 740 | jnz NOTESTA ; Is a device, ASCII mode | ||
| 741 | cmp [ASCII],0 | ||
| 742 | jz BINREAD | ||
| 743 | NOTESTA: | ||
| 744 | MOV DX,CX | ||
| 745 | MOV DI,[NXTADD] | ||
| 746 | MOV AL,1AH | ||
| 747 | PUSH ES | ||
| 748 | MOV ES,[TPA] | ||
| 749 | REPNE SCASB ; Scan for EOF | ||
| 750 | POP ES | ||
| 751 | JNZ USEALL | ||
| 752 | INC [RDEOF] | ||
| 753 | INC CX | ||
| 754 | USEALL: | ||
| 755 | SUB DX,CX | ||
| 756 | MOV CX,DX | ||
| 757 | BINREAD: | ||
| 758 | ADD CX,[NXTADD] | ||
| 759 | MOV [NXTADD],CX | ||
| 760 | CMP CX,[BYTCNT] ; Is buffer full? | ||
| 761 | JB TESTDEV ; If not, we may have found EOF | ||
| 762 | invoke FLSHFIL | ||
| 763 | CMP [TERMREAD],0 | ||
| 764 | JNZ CLOSESRC ; Give up | ||
| 765 | JMP SHORT COPYLP | ||
| 766 | |||
| 767 | TESTDEV: | ||
| 768 | cmp [SRCISDEV],0 | ||
| 769 | JZ CLOSESRC ; If file then EOF | ||
| 770 | CMP [RDEOF],0 | ||
| 771 | JZ COPYLP ; On device, go till ^Z | ||
| 772 | CLOSESRC: | ||
| 773 | mov bx,[SRCHAND] | ||
| 774 | mov ah,CLOSE | ||
| 775 | INT int_command | ||
| 776 | return | ||
| 777 | |||
| 778 | ; | ||
| 779 | ; We are called to close the destination. We need to note whether or not | ||
| 780 | ; there is any internal data left to be flushed out. | ||
| 781 | ; | ||
| 782 | CLOSEDEST: | ||
| 783 | cmp [DESTCLOSED],0 | ||
| 784 | retnz ; Don't double close | ||
| 785 | MOV AL,BYTE PTR [DESTSWITCH] | ||
| 786 | invoke SETASC ; Check for B or A switch on destination | ||
| 787 | JZ BINCLOS | ||
| 788 | MOV BX,[NXTADD] | ||
| 789 | CMP BX,[BYTCNT] ; Is memory full? | ||
| 790 | JNZ PUTZ | ||
| 791 | invoke TRYFLUSH ; Make room for one lousy byte | ||
| 792 | jz NOCONC | ||
| 793 | CONCHNG: ; Concat flag changed on us | ||
| 794 | stc | ||
| 795 | return | ||
| 796 | NOCONC: | ||
| 797 | XOR BX,BX | ||
| 798 | PUTZ: | ||
| 799 | PUSH DS | ||
| 800 | MOV DS,[TPA] | ||
| 801 | MOV WORD PTR [BX],1AH ; Add End-of-file mark (Ctrl-Z) | ||
| 802 | POP DS | ||
| 803 | INC [NXTADD] | ||
| 804 | MOV [NOWRITE],0 ; Make sure our ^Z gets written | ||
| 805 | MOV AX,[WRITTEN] | ||
| 806 | ADD AX,[NXTADD] | ||
| 807 | JC BINCLOS ; > 1 | ||
| 808 | CMP AX,1 | ||
| 809 | JZ FORGETITJ ; WRITTEN = 0 NXTADD = 1 (the ^Z) | ||
| 810 | BINCLOS: | ||
| 811 | invoke TRYFLUSH | ||
| 812 | jnz CONCHNG | ||
| 813 | cmp [WRITTEN],0 | ||
| 814 | ForgetItJ: | ||
| 815 | jnz no_forget ;AC000; Wrote something | ||
| 816 | jmp FORGETIT ;AC000; Never wrote nothing | ||
| 817 | no_forget: | ||
| 818 | MOV BX,[DESTHAND] | ||
| 819 | MOV CX,[CPTIME] | ||
| 820 | MOV DX,[CPDATE] | ||
| 821 | CMP [INEXACT],0 ; Copy not exact? | ||
| 822 | JZ DODCLOSE ; If no, copy date & time | ||
| 823 | MOV AH,GET_TIME | ||
| 824 | INT int_command | ||
| 825 | SHL CL,1 | ||
| 826 | SHL CL,1 ; Left justify min in CL | ||
| 827 | SHL CX,1 | ||
| 828 | SHL CX,1 | ||
| 829 | SHL CX,1 ; hours to high 5 bits, min to 5-10 | ||
| 830 | SHR DH,1 ; Divide seconds by 2 (now 5 bits) | ||
| 831 | OR CL,DH ; And stick into low 5 bits of CX | ||
| 832 | PUSH CX ; Save packed time | ||
| 833 | MOV AH,GET_DATE | ||
| 834 | INT int_command | ||
| 835 | SUB CX,1980 | ||
| 836 | XCHG CH,CL | ||
| 837 | SHL CX,1 ; Year to high 7 bits | ||
| 838 | SHL DH,1 ; Month to high 3 bits | ||
| 839 | SHL DH,1 | ||
| 840 | SHL DH,1 | ||
| 841 | SHL DH,1 | ||
| 842 | SHL DH,1 ; Most sig bit of month in carry | ||
| 843 | ADC CH,0 ; Put that bit next to year | ||
| 844 | OR DL,DH ; Or low three of month into day | ||
| 845 | MOV DH,CH ; Get year and high bit of month | ||
| 846 | POP CX ; Get time back | ||
| 847 | DODCLOSE: | ||
| 848 | CMP BX,0 | ||
| 849 | JLE CloseDone | ||
| 850 | MOV AX,(FILE_TIMES SHL 8) OR 1 | ||
| 851 | INT int_command ; Set date and time | ||
| 852 | jc xa_cleanup_err ;AN022; handle error | ||
| 853 | |||
| 854 | mov ax,(file_times SHL 8)+set_XA ;AN000; set code page | ||
| 855 | mov di,offset trangroup:xa_cp_out ;AC030; offset of attr list | ||
| 856 | int int_command ;AN000; | ||
| 857 | jc xa_cleanup_err ;AN030; exit if error | ||
| 858 | |||
| 859 | ; | ||
| 860 | ; See if the destination has *anything* in it. If not, just close and delete | ||
| 861 | ; it. | ||
| 862 | ; | ||
| 863 | no_xa_cleanup_err: | ||
| 864 | mov ax,(lseek shl 8) + 2 ; seek to EOF | ||
| 865 | xor dx,dx | ||
| 866 | mov cx,dx | ||
| 867 | int 21h | ||
| 868 | ; | ||
| 869 | ; DX:AX is file size | ||
| 870 | ; | ||
| 871 | or dx,ax | ||
| 872 | pushf | ||
| 873 | mov ax,(IOCTL SHL 8) + 0 ; get the destination attributes | ||
| 874 | int 21h | ||
| 875 | push dx ; save them away | ||
| 876 | MOV AH,CLOSE | ||
| 877 | INT int_command | ||
| 878 | pop dx | ||
| 879 | jnc close_cont ;AN022; handle error on close | ||
| 880 | popf ;AN022; get the flags back | ||
| 881 | xa_cleanup_err: ;AN022; | ||
| 882 | call cleanuperr ;AN022; attempt to delete the target | ||
| 883 | call DestDelete ;AN022; attempt to delete the target | ||
| 884 | jmp short fileclosed ;AN022; close the file | ||
| 885 | close_cont: ;AN022; no error - continue | ||
| 886 | popf | ||
| 887 | jnz CloseDone | ||
| 888 | test dx,80h ; is the destination a device? | ||
| 889 | jnz CloseDone ; yes, copy succeeded | ||
| 890 | call DestDelete | ||
| 891 | jmp short FileClosed | ||
| 892 | CloseDone: | ||
| 893 | INC [FILECNT] | ||
| 894 | FileClosed: | ||
| 895 | INC [DESTCLOSED] | ||
| 896 | RET50: | ||
| 897 | CLC | ||
| 898 | return | ||
| 899 | |||
| 900 | |||
| 901 | FORGETIT: | ||
| 902 | MOV BX,[DESTHAND] | ||
| 903 | CALL DODCLOSE ; Close the dest | ||
| 904 | call DestDelete | ||
| 905 | MOV [FILECNT],0 ; No files transferred | ||
| 906 | JMP RET50 | ||
| 907 | |||
| 908 | DestDelete: | ||
| 909 | MOV DX,OFFSET TRANGROUP:DESTBUF | ||
| 910 | MOV AH,UNLINK | ||
| 911 | INT int_command ; And delete it | ||
| 912 | return | ||
| 913 | |||
| 914 | source_set proc near | ||
| 915 | |||
| 916 | push SI | ||
| 917 | mov ax,[STARTEL] | ||
| 918 | mov SI,offset trangroup:SCANBUF ; Adjust to copy | ||
| 919 | sub ax,SI | ||
| 920 | mov DI,offset trangroup:SRCBUF | ||
| 921 | add ax,DI | ||
| 922 | mov [SRCTAIL],AX | ||
| 923 | mov [SRCSIZ],cl ; Save its size | ||
| 924 | inc cx ; Include the nul | ||
| 925 | rep movsb ; Save this source | ||
| 926 | mov [SRCINFO],bh ; Save info about it | ||
| 927 | pop SI | ||
| 928 | mov ax,bp ; Switches so far | ||
| 929 | invoke SETASC ; Set A,B switches accordingly | ||
| 930 | invoke SWITCH ; Get any more switches on this arg | ||
| 931 | invoke SETASC ; Set | ||
| 932 | return | ||
| 933 | |||
| 934 | source_set endp | ||
| 935 | |||
| 936 | |||
| 937 | ;**************************************************************** | ||
| 938 | ;* | ||
| 939 | ;* ROUTINE: Cleanuperr | ||
| 940 | ;* | ||
| 941 | ;* FUNCTION: Issues extended error message for destination | ||
| 942 | ;* if not alreay issued | ||
| 943 | ;* | ||
| 944 | ;* INPUT: return from INT 21 | ||
| 945 | ;* | ||
| 946 | ;* OUTPUT: none | ||
| 947 | ;* | ||
| 948 | ;**************************************************************** | ||
| 949 | |||
| 950 | cleanuperr proc near ;AN022; | ||
| 951 | |||
| 952 | cmp msg_flag,0 ;AN022; have we already issued a message? | ||
| 953 | jnz cleanuperr_cont ;AN022; yes - don't issue duplicate error | ||
| 954 | invoke set_ext_error_msg ;AN022; set up error message | ||
| 955 | mov string_ptr_2,offset trangroup:destbuf ;AN022; get address of failed string | ||
| 956 | mov Extend_buf_sub,one_subst ;AN022; put number of subst in control block | ||
| 957 | invoke std_eprintf ;AN022; issue the error message | ||
| 958 | cleanuperr_cont: ;AN022; | ||
| 959 | |||
| 960 | ret ;AN022; return to caller | ||
| 961 | cleanuperr endp ;AN022; | ||
| 962 | |||
| 963 | ;**************************************************************** | ||
| 964 | ;* | ||
| 965 | ;* ROUTINE: Deallocate_Src_XA | ||
| 966 | ;* | ||
| 967 | ;* FUNCTION: Deallocates source extended attribute segment | ||
| 968 | ;* and resets both resident and transient variables. | ||
| 969 | ;* | ||
| 970 | ;* | ||
| 971 | ;* INPUT: none | ||
| 972 | ;* | ||
| 973 | ;* OUTPUT: none | ||
| 974 | ;* | ||
| 975 | ;**************************************************************** | ||
| 976 | |||
| 977 | Deallocate_Src_XA proc near ;AN030; | ||
| 978 | |||
| 979 | cmp [src_xa_seg],no_xa_seg ;AN030; has any XA segment been allocated | ||
| 980 | jz no_src_xa ;AN030; no - continue | ||
| 981 | push es ;AN030; | ||
| 982 | mov es,src_xa_seg ;AN030; yes - free it | ||
| 983 | mov ax,(Dealloc SHL 8) ;AN030; Deallocate memory call | ||
| 984 | int int_command ;AN030; | ||
| 985 | pop es ;AN030; | ||
| 986 | mov [src_xa_seg],no_xa_seg ;AN030; reset to no segment | ||
| 987 | push ds ;AN030; reinitialize resident | ||
| 988 | mov ds,[resseg] ;AN030; copy of xa segment | ||
| 989 | assume ds:resgroup ;AN030; | ||
| 990 | mov [rsrc_xa_seg],no_xa_seg ;AN030; reset to no segment | ||
| 991 | pop ds ;AN030; | ||
| 992 | assume ds:trangroup ;AN030; | ||
| 993 | no_src_xa: ;AN030; | ||
| 994 | |||
| 995 | ret ;AN030; return to caller | ||
| 996 | Deallocate_Src_XA endp ;AN030; | ||
| 997 | |||
| 998 | |||
| 999 | TRANCODE ENDS | ||
| 1000 | END | ||
| 1001 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/COMMAND/COPYPR1.ASM b/v4.0/src/CMD/COMMAND/COPYPR1.ASM new file mode 100644 index 0000000..e727910 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/COPYPR1.ASM | |||
| @@ -0,0 +1,276 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)copypr1.asm 1.1 85/05/14 | ||
| 3 | ; SCCSID = @(#)copypr1.asm 1.1 85/05/14 | ||
| 4 | INCLUDE comsw.asm | ||
| 5 | |||
| 6 | .xlist | ||
| 7 | .xcref | ||
| 8 | INCLUDE DOSSYM.INC | ||
| 9 | ; INCLUDE DEVSYM.INC | ||
| 10 | INCLUDE comseg.asm | ||
| 11 | INCLUDE comequ.asm | ||
| 12 | .list | ||
| 13 | .cref | ||
| 14 | |||
| 15 | |||
| 16 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 17 | EXTRN DEVWMES_ptr:word | ||
| 18 | EXTRN ext_open_parms:byte ;AN000; | ||
| 19 | EXTRN ext_open_seg:word ;AN000; | ||
| 20 | EXTRN ext_open_off:word ;AN000; | ||
| 21 | EXTRN Extend_buf_sub:byte ;AN000; | ||
| 22 | EXTRN LOSTERR_ptr:word | ||
| 23 | EXTRN NOSPACE_ptr:word | ||
| 24 | EXTRN OVERWR_ptr:word | ||
| 25 | TRANDATA ENDS | ||
| 26 | |||
| 27 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 28 | EXTRN ASCII:BYTE | ||
| 29 | EXTRN BINARY:BYTE | ||
| 30 | EXTRN CFLAG:BYTE | ||
| 31 | EXTRN CONCAT:BYTE | ||
| 32 | EXTRN concat_xa:byte ;AC000; | ||
| 33 | EXTRN DESTBUF:BYTE | ||
| 34 | EXTRN DESTCLOSED:BYTE | ||
| 35 | EXTRN DESTHAND:WORD | ||
| 36 | EXTRN DESTISDEV:BYTE | ||
| 37 | EXTRN DESTSWITCH:WORD | ||
| 38 | EXTRN INEXACT:BYTE | ||
| 39 | EXTRN NOWRITE:BYTE | ||
| 40 | EXTRN NXTADD:WORD | ||
| 41 | EXTRN plus_comma:byte ;AN000; | ||
| 42 | EXTRN RDEOF:BYTE | ||
| 43 | EXTRN src_xa_seg:word ;AN000; | ||
| 44 | EXTRN SRCISDEV:BYTE | ||
| 45 | EXTRN string_ptr_2:word ;AN000; | ||
| 46 | EXTRN TERMREAD:BYTE | ||
| 47 | EXTRN TPA:WORD | ||
| 48 | EXTRN WRITTEN:WORD | ||
| 49 | TRANSPACE ENDS | ||
| 50 | |||
| 51 | TRANCODE SEGMENT PUBLIC BYTE | ||
| 52 | |||
| 53 | EXTRN ENDCOPY:NEAR | ||
| 54 | |||
| 55 | PUBLIC FLSHFIL | ||
| 56 | PUBLIC TRYFLUSH | ||
| 57 | |||
| 58 | ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING | ||
| 59 | |||
| 60 | TRYFLUSH: | ||
| 61 | mov al,[CONCAT] | ||
| 62 | push ax | ||
| 63 | call FLSHFIL | ||
| 64 | pop ax | ||
| 65 | cmp al,[CONCAT] | ||
| 66 | return | ||
| 67 | |||
| 68 | FLSHFIL: | ||
| 69 | ; | ||
| 70 | ; Write out any data remaining in memory. | ||
| 71 | ; Inputs: | ||
| 72 | ; [NXTADD] = No. of bytes to write | ||
| 73 | ; [CFLAG] <> 0 if file has been created | ||
| 74 | ; Outputs: | ||
| 75 | ; [NXTADD] = 0 | ||
| 76 | ; | ||
| 77 | MOV [TERMREAD],0 | ||
| 78 | cmp [CFLAG],0 | ||
| 79 | JZ NOTEXISTS | ||
| 80 | JMP EXISTS | ||
| 81 | |||
| 82 | NOTEXISTS: | ||
| 83 | invoke BUILDDEST ; Find out all about the destination | ||
| 84 | invoke COMPNAME ; Source and dest. the same? | ||
| 85 | JNZ PROCDEST ; If not, go ahead | ||
| 86 | CMP [SRCISDEV],0 | ||
| 87 | JNZ PROCDEST ; Same name on device OK | ||
| 88 | CMP [CONCAT],0 ; Concatenation? | ||
| 89 | MOV DX,OFFSET TRANGROUP:OVERWR_ptr | ||
| 90 | JNZ NO_CONCAT_ERR ;AC000; If not, overwrite error | ||
| 91 | JMP COPERR ;AC000; | ||
| 92 | |||
| 93 | NO_CONCAT_ERR: ;AC000; | ||
| 94 | MOV [NOWRITE],1 ; Flag not writting (just seeking) | ||
| 95 | |||
| 96 | PROCDEST: | ||
| 97 | MOV AX,EXTOPEN SHL 8 ;AC000; open the file | ||
| 98 | mov si,offset trangroup:destbuf ;AN030; get file name | ||
| 99 | mov di,-1 ;AN030; indicate no parameters | ||
| 100 | cmp src_xa_seg,no_xa_seg ;AN030; is there an XA segment? | ||
| 101 | jz cont_no_xa ;AN030; no - no parameters | ||
| 102 | mov di,offset trangroup:Ext_open_parms ;AN030; get parameters | ||
| 103 | mov bx,src_xa_seg ;AN030; get extended attribute segment | ||
| 104 | mov ext_open_seg,bx ;AN030; put it in parameter list | ||
| 105 | mov ext_open_off,0 ;AN030; offset is 0 | ||
| 106 | |||
| 107 | cont_no_xa: ;AN030; | ||
| 108 | mov bx,write_open_mode ;AN000; get open mode for COPY | ||
| 109 | xor cx,cx ;AN000; no special files | ||
| 110 | mov dx,write_open_flag ;AN000; set up open flags | ||
| 111 | |||
| 112 | CMP [NOWRITE],0 | ||
| 113 | JNZ DODESTOPEN ; Don't actually create if NOWRITE set | ||
| 114 | mov dx,creat_open_flag ;AC000; set up create flags | ||
| 115 | |||
| 116 | DODESTOPEN: | ||
| 117 | INT int_command | ||
| 118 | ; | ||
| 119 | ; We assume that the error is normal. TriageError will correct the DX value | ||
| 120 | ; appropriately. | ||
| 121 | ; | ||
| 122 | JNC dest_open_okay ;AC030; | ||
| 123 | |||
| 124 | xa_set_error: ;AN030; error occurred on XA | ||
| 125 | invoke set_ext_error_msg ;AN030; get extended error | ||
| 126 | |||
| 127 | ext_err_set: ;AN030; | ||
| 128 | mov string_ptr_2,offset trangroup:destbuf ;AN000; get address of failed string | ||
| 129 | mov Extend_buf_sub,one_subst ;AN030; put number of subst in control block | ||
| 130 | |||
| 131 | COPERRJ2: ;AN030; | ||
| 132 | jmp COPERR ;AN030; go issue message | ||
| 133 | |||
| 134 | dest_open_okay: ;AC030 | ||
| 135 | mov [DESTHAND],ax ; Save handle | ||
| 136 | mov [CFLAG],1 ; Destination now exists | ||
| 137 | mov bx,ax | ||
| 138 | mov cx,bx ;AN030; get handle into CX | ||
| 139 | invoke set_file_code_page ;AN030; set the code page for the target | ||
| 140 | jc ext_err_set ;AN030; if no error, continue | ||
| 141 | |||
| 142 | mov [concat_xa],0 ;AN000; set first file flag off | ||
| 143 | mov ax,(IOCTL SHL 8) | ||
| 144 | INT int_command ; Get device stuff | ||
| 145 | mov [DESTISDEV],dl ; Set dest info | ||
| 146 | test dl,devid_ISDEV | ||
| 147 | jz exists ;AC030; Dest a device | ||
| 148 | |||
| 149 | mov al,BYTE PTR [DESTSWITCH] | ||
| 150 | AND AL,SwitchA+SwitchB | ||
| 151 | JNZ TESTBOTH | ||
| 152 | MOV AL,[ASCII] ; Neither set, use current setting | ||
| 153 | OR AL,[BINARY] | ||
| 154 | JZ EXSETA ; Neither set, default to ASCII | ||
| 155 | |||
| 156 | TESTBOTH: | ||
| 157 | JPE EXISTS ; Both are set, ignore | ||
| 158 | test AL,SwitchB | ||
| 159 | jz EXISTS ; Leave in cooked mode | ||
| 160 | mov ax,(IOCTL SHL 8) OR 1 | ||
| 161 | xor dh,dh | ||
| 162 | or dl,devid_RAW | ||
| 163 | mov [DESTISDEV],dl ; New value | ||
| 164 | INT int_command ; Set device to RAW mode | ||
| 165 | jmp short EXISTS | ||
| 166 | |||
| 167 | COPERRJ: | ||
| 168 | jmp SHORT COPERR | ||
| 169 | |||
| 170 | EXSETA: | ||
| 171 | ; | ||
| 172 | ; What we read in may have been in binary mode, flag zapped write OK | ||
| 173 | ; | ||
| 174 | mov [ASCII],SwitchA ; Set ASCII mode | ||
| 175 | or [INEXACT],SwitchA ; ASCII -> INEXACT | ||
| 176 | |||
| 177 | EXISTS: | ||
| 178 | cmp [NOWRITE],0 | ||
| 179 | jnz NOCHECKING ; If nowrite don't bother with name check | ||
| 180 | cmp plus_comma,1 ;g don't check if just doing +,, | ||
| 181 | jz NOCHECKING ;g | ||
| 182 | invoke COMPNAME ; Source and dest. the same? | ||
| 183 | JNZ NOCHECKING ; If not, go ahead | ||
| 184 | CMP [SRCISDEV],0 | ||
| 185 | JNZ NOCHECKING ; Same name on device OK | ||
| 186 | ; | ||
| 187 | ; At this point we know in append (would have gotten overwrite error on first | ||
| 188 | ; destination create otherwise), and user trying to specify destination which | ||
| 189 | ; has been scribbled already (if dest had been named first, NOWRITE would | ||
| 190 | ; be set). | ||
| 191 | ; | ||
| 192 | MOV DX,OFFSET TRANGROUP:LOSTERR_ptr ; Tell him he's not going to get it | ||
| 193 | invoke std_Eprintf ;AC022; | ||
| 194 | MOV [NXTADD],0 ; Set return | ||
| 195 | INC [TERMREAD] ; Tell Read to give up | ||
| 196 | |||
| 197 | RET60: | ||
| 198 | return | ||
| 199 | |||
| 200 | NOCHECKING: | ||
| 201 | mov bx,[DESTHAND] ; Get handle | ||
| 202 | XOR CX,CX | ||
| 203 | XCHG CX,[NXTADD] | ||
| 204 | JCXZ RET60 ; If Nothing to write, forget it | ||
| 205 | INC [WRITTEN] ; Flag that we wrote something | ||
| 206 | CMP [NOWRITE],0 ; If NOWRITE set, just seek CX bytes | ||
| 207 | JNZ SEEKEND | ||
| 208 | XOR DX,DX | ||
| 209 | PUSH DS | ||
| 210 | MOV DS,[TPA] | ||
| 211 | ASSUME DS:NOTHING | ||
| 212 | MOV AH,WRITE | ||
| 213 | INT int_command | ||
| 214 | POP DS | ||
| 215 | ASSUME DS:TRANGROUP | ||
| 216 | MOV DX,OFFSET TRANGROUP:NOSPACE_ptr | ||
| 217 | JC xa_set_error_Jmp ;AC022; Failure | ||
| 218 | sub cx,ax | ||
| 219 | retz ; Wrote all supposed to | ||
| 220 | test [DESTISDEV],devid_ISDEV | ||
| 221 | jz COPERR ; Is a file, error | ||
| 222 | test [DESTISDEV],devid_RAW | ||
| 223 | jnz DEVWRTERR ; Is a raw device, error | ||
| 224 | cmp [INEXACT],0 | ||
| 225 | retnz ; INEXACT so OK | ||
| 226 | dec cx | ||
| 227 | retz ; Wrote one byte less (the ^Z) | ||
| 228 | |||
| 229 | DEVWRTERR: | ||
| 230 | MOV DX,OFFSET TRANGROUP:DEVWMES_ptr | ||
| 231 | |||
| 232 | PUBLIC COPERR | ||
| 233 | COPERR: | ||
| 234 | INVOKE std_Eprintf ;AC022; | ||
| 235 | |||
| 236 | COPERRP: | ||
| 237 | inc [DESTCLOSED] | ||
| 238 | cmp [CFLAG],0 | ||
| 239 | jz ENDCOPYJ ; Never actually got it open | ||
| 240 | MOV bx,[DESTHAND] | ||
| 241 | CMP BX,0 | ||
| 242 | JLE NoClose | ||
| 243 | MOV AH,CLOSE ; Close the file | ||
| 244 | INT int_command | ||
| 245 | |||
| 246 | NoClose: | ||
| 247 | MOV DX,OFFSET TRANGROUP:DESTBUF | ||
| 248 | MOV AH,UNLINK | ||
| 249 | INT int_command ; And delete it | ||
| 250 | MOV [CFLAG],0 | ||
| 251 | |||
| 252 | ENDCOPYJ: | ||
| 253 | JMP ENDCOPY | ||
| 254 | |||
| 255 | XA_SET_ERROR_JMP: ;AN022; Go set up error message | ||
| 256 | jmp xa_set_error ;AN022; | ||
| 257 | |||
| 258 | SEEKEND: | ||
| 259 | xor dx,dx ; Zero high half of offset | ||
| 260 | xchg dx,cx ; cx:dx is seek location | ||
| 261 | mov ax,(LSEEK SHL 8) OR 1 | ||
| 262 | INT int_command ; Seek ahead in the file | ||
| 263 | cmp [RDEOF],0 | ||
| 264 | retz | ||
| 265 | ; | ||
| 266 | ; If a ^Z has been read we must set the file size to the current | ||
| 267 | ; file pointer location | ||
| 268 | ; | ||
| 269 | MOV AH,WRITE | ||
| 270 | INT int_command ; CX is zero, truncates file | ||
| 271 | jc xa_set_error_Jmp ;AC022; Failure | ||
| 272 | return | ||
| 273 | |||
| 274 | TRANCODE ENDS | ||
| 275 | END | ||
| 276 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/COMMAND/COPYPR2.ASM b/v4.0/src/CMD/COMMAND/COPYPR2.ASM new file mode 100644 index 0000000..2913cab --- /dev/null +++ b/v4.0/src/CMD/COMMAND/COPYPR2.ASM | |||
| @@ -0,0 +1,450 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)copypr2.asm 1.1 85/05/14 | ||
| 3 | ; SCCSID = @(#)copypr2.asm 1.1 85/05/14 | ||
| 4 | INCLUDE comsw.asm | ||
| 5 | |||
| 6 | .xlist | ||
| 7 | .xcref | ||
| 8 | INCLUDE DOSSYM.INC | ||
| 9 | INCLUDE comseg.asm | ||
| 10 | INCLUDE comequ.asm | ||
| 11 | .list | ||
| 12 | .cref | ||
| 13 | |||
| 14 | |||
| 15 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 16 | EXTRN FulDir_ptr:word ;AN052; | ||
| 17 | TRANDATA ENDS | ||
| 18 | |||
| 19 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 20 | EXTRN ASCII:BYTE | ||
| 21 | EXTRN BINARY:BYTE | ||
| 22 | EXTRN CONCAT:BYTE | ||
| 23 | EXTRN DESTBUF:BYTE | ||
| 24 | EXTRN DESTFCB:BYTE | ||
| 25 | EXTRN DESTINFO:BYTE | ||
| 26 | EXTRN DESTISDIR:BYTE | ||
| 27 | EXTRN DESTTAIL:WORD | ||
| 28 | EXTRN DESTVARS:BYTE | ||
| 29 | EXTRN DIRBUF:BYTE | ||
| 30 | EXTRN DIRCHAR:BYTE | ||
| 31 | EXTRN FIRSTDEST:BYTE | ||
| 32 | EXTRN INEXACT:BYTE | ||
| 33 | EXTRN MELCOPY:BYTE | ||
| 34 | EXTRN NXTADD:WORD | ||
| 35 | EXTRN PLUS:BYTE | ||
| 36 | EXTRN SDIRBUF:BYTE | ||
| 37 | EXTRN SRCINFO:BYTE | ||
| 38 | EXTRN srcxname:byte | ||
| 39 | EXTRN TPA:WORD | ||
| 40 | EXTRN trgxname:byte | ||
| 41 | EXTRN USERDIR1:BYTE | ||
| 42 | TRANSPACE ENDS | ||
| 43 | |||
| 44 | TRANCODE SEGMENT PUBLIC BYTE | ||
| 45 | |||
| 46 | EXTRN BADPATH_ERR:NEAR ;AN022; | ||
| 47 | EXTRN COPERR:NEAR ;AN052; | ||
| 48 | EXTRN EXTEND_SETUP:NEAR ;AN022; | ||
| 49 | |||
| 50 | PUBLIC BUILDPATH | ||
| 51 | PUBLIC SETSTARS | ||
| 52 | PUBLIC SETASC | ||
| 53 | |||
| 54 | ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING | ||
| 55 | |||
| 56 | SETASC: | ||
| 57 | ; | ||
| 58 | ; Given switch vector in AX, | ||
| 59 | ; Set ASCII switch if A is set | ||
| 60 | ; Clear ASCII switch if B is set | ||
| 61 | ; BINARY set if B specified | ||
| 62 | ; Leave ASCII unchanged if neither or both are set | ||
| 63 | ; Also sets INEXACT if ASCII is ever set. AL = ASCII on exit, flags set | ||
| 64 | ; | ||
| 65 | AND AL,SwitchA+SwitchB | ||
| 66 | JPE LOADSW ; PE means both or neither are set | ||
| 67 | PUSH AX | ||
| 68 | AND AL,SwitchB | ||
| 69 | MOV [BINARY],AL | ||
| 70 | POP AX | ||
| 71 | AND AL,SwitchA | ||
| 72 | MOV [ASCII],AL | ||
| 73 | OR [INEXACT],AL | ||
| 74 | |||
| 75 | LOADSW: | ||
| 76 | MOV AL,[ASCII] | ||
| 77 | OR AL,AL | ||
| 78 | return | ||
| 79 | |||
| 80 | public builddest | ||
| 81 | BUILDDEST: | ||
| 82 | cmp [DESTISDIR],-1 | ||
| 83 | jnz KNOWABOUTDEST ; Already done the figuring | ||
| 84 | MOV DI,OFFSET TRANGROUP:USERDIR1 | ||
| 85 | mov bp,offset trangroup:DESTVARS | ||
| 86 | call BUILDPATH | ||
| 87 | invoke RESTUDIR1 | ||
| 88 | |||
| 89 | ; Now know all about the destination | ||
| 90 | |||
| 91 | KNOWABOUTDEST: | ||
| 92 | xor al,al | ||
| 93 | xchg al,[FIRSTDEST] | ||
| 94 | or al,al | ||
| 95 | jnz FIRSTDST | ||
| 96 | jmp NOTFIRSTDEST | ||
| 97 | |||
| 98 | FIRSTDST: | ||
| 99 | mov si,[DESTTAIL] ; Create an FCB of the original DEST | ||
| 100 | mov di,offset trangroup:DESTFCB | ||
| 101 | mov ax,PARSE_FILE_DESCRIPTOR SHL 8 | ||
| 102 | INT int_command | ||
| 103 | CMP BYTE PTR [SI],0 | ||
| 104 | JZ GoodParse | ||
| 105 | ;AD052; MOV BYTE PTR [DI+1],"|" ; must be illegal file name character | ||
| 106 | mov dx,offset trangroup:fuldir_ptr ;AN052; Issue "File creation error" | ||
| 107 | jmp coperr ;AN052; | ||
| 108 | |||
| 109 | GoodParse: | ||
| 110 | mov ax,word ptr [DESTBUF] ; Get drive | ||
| 111 | cmp ah,':' | ||
| 112 | jz DRVSPEC4 | ||
| 113 | mov al,'@' | ||
| 114 | |||
| 115 | DRVSPEC4: | ||
| 116 | MOV CL,[ASCII] ; Save current ASCII setting | ||
| 117 | or al,20h | ||
| 118 | sub al,60h | ||
| 119 | mov [DESTFCB],al | ||
| 120 | mov al,[DESTINFO] | ||
| 121 | mov ah,[SRCINFO] | ||
| 122 | and ax,0202H | ||
| 123 | or al,al | ||
| 124 | jz NOTMELCOPY | ||
| 125 | cmp al,ah | ||
| 126 | jnz NOTMELCOPY | ||
| 127 | cmp [PLUS],0 | ||
| 128 | jz NOTMELCOPY | ||
| 129 | inc [MELCOPY] ; ambig source, ambig dest, and pluses | ||
| 130 | xor al,al | ||
| 131 | jmp short SETCONC | ||
| 132 | |||
| 133 | NOTMELCOPY: | ||
| 134 | xor al,2 ; al=2 if unambig dest, =0 if ambig dest | ||
| 135 | and al,ah | ||
| 136 | shr al,1 ; al=1 if unambig dest AND ambig sorce | ||
| 137 | ; Implies concatenation | ||
| 138 | SETCONC: | ||
| 139 | or al,[PLUS] ; al=1 if concat | ||
| 140 | mov [CONCAT],al | ||
| 141 | shl al,1 | ||
| 142 | shl al,1 | ||
| 143 | mov [INEXACT],al ; Concat -> inexact copy | ||
| 144 | cmp [BINARY],0 | ||
| 145 | jnz NOTFIRSTDEST ; Binary explicitly given, all OK | ||
| 146 | mov [ASCII],al ; Concat -> ASCII | ||
| 147 | or cl,cl | ||
| 148 | jnz NOTFIRSTDEST ; ASCII flag set before, DATA read correctly | ||
| 149 | or al,al | ||
| 150 | JZ NOTFIRSTDEST ; ASCII flag did not change states | ||
| 151 | ; | ||
| 152 | ; At this point there may already be binary read data in the read buffer. | ||
| 153 | ; We need to find the first ^Z (if there is one) and trim the amount | ||
| 154 | ; of data in the buffer correctly. | ||
| 155 | ; | ||
| 156 | MOV CX,[NXTADD] | ||
| 157 | JCXZ NOTFIRSTDEST ; No data, everything OK | ||
| 158 | MOV AL,1AH | ||
| 159 | PUSH ES | ||
| 160 | XOR DI,DI | ||
| 161 | MOV ES,[TPA] | ||
| 162 | REPNE SCASB ; Scan for EOF | ||
| 163 | POP ES | ||
| 164 | JNZ NOTFIRSTDEST ; No ^Z in buffer, everything OK | ||
| 165 | DEC DI ; Point at ^Z | ||
| 166 | MOV [NXTADD],DI ; New buffer | ||
| 167 | |||
| 168 | NOTFIRSTDEST: | ||
| 169 | mov bx,offset trangroup:DIRBUF+1 ; Source of replacement chars | ||
| 170 | cmp [CONCAT],0 | ||
| 171 | jz GOTCHRSRC ; Not a concat | ||
| 172 | mov bx,offset trangroup:SDIRBUF+1 ; Source of replacement chars | ||
| 173 | |||
| 174 | GOTCHRSRC: | ||
| 175 | mov si,offset trangroup:DESTFCB+1 ; Original dest name | ||
| 176 | mov di,[DESTTAIL] ; Where to put result | ||
| 177 | |||
| 178 | public buildname | ||
| 179 | BUILDNAME: | ||
| 180 | mov cx,8 | ||
| 181 | |||
| 182 | BUILDMAIN: | ||
| 183 | lodsb | ||
| 184 | cmp al,'?' | ||
| 185 | jnz NOTAMBIG | ||
| 186 | mov al,byte ptr [BX] | ||
| 187 | |||
| 188 | NOTAMBIG: | ||
| 189 | cmp al,' ' | ||
| 190 | jz NOSTORE | ||
| 191 | stosb | ||
| 192 | |||
| 193 | NOSTORE: | ||
| 194 | inc bx | ||
| 195 | loop BUILDMAIN | ||
| 196 | mov cl,3 | ||
| 197 | mov al,' ' | ||
| 198 | cmp byte ptr [SI],al | ||
| 199 | jz ENDDEST ; No extension | ||
| 200 | mov al,dot_chr | ||
| 201 | stosb | ||
| 202 | |||
| 203 | BUILDEXT: | ||
| 204 | lodsb | ||
| 205 | cmp al,'?' | ||
| 206 | jnz NOTAMBIGE | ||
| 207 | mov al,byte ptr [BX] | ||
| 208 | |||
| 209 | NOTAMBIGE: | ||
| 210 | cmp al,' ' | ||
| 211 | jz NOSTOREE | ||
| 212 | stosb | ||
| 213 | |||
| 214 | NOSTOREE: | ||
| 215 | inc bx | ||
| 216 | loop BUILDEXT | ||
| 217 | ENDDEST: | ||
| 218 | xor al,al | ||
| 219 | stosb ; NUL terminate | ||
| 220 | return | ||
| 221 | |||
| 222 | BUILDPATH: | ||
| 223 | test [BP.INFO],2 | ||
| 224 | jnz NOTPFILE ; If ambig don't bother with open | ||
| 225 | mov dx,bp | ||
| 226 | add dx,BUF ; Set DX to spec | ||
| 227 | |||
| 228 | push di ;AN000; | ||
| 229 | MOV AX,EXTOPEN SHL 8 ;AC000; open the file | ||
| 230 | mov bx,read_open_mode ;AN000; get open mode for COPY | ||
| 231 | xor cx,cx ;AN000; no special files | ||
| 232 | mov si,dx ;AN030; get file name offset | ||
| 233 | mov di,-1 ;AN030; no parm list | ||
| 234 | mov dx,read_open_flag ;AN000; set up open flags | ||
| 235 | INT int_command | ||
| 236 | pop di ;AN000; | ||
| 237 | jnc pure_file ;AN022; is pure file | ||
| 238 | invoke get_ext_error_number ;AN022; get the extended error | ||
| 239 | cmp ax,error_file_not_found ;AN022; if file not found - okay | ||
| 240 | jz notpfile ;AN022; | ||
| 241 | cmp ax,error_path_not_found ;AN022; if path not found - okay | ||
| 242 | jz notpfile ;AN022; | ||
| 243 | cmp ax,error_access_denied ;AN022; if access denied - okay | ||
| 244 | jz notpfile ;AN022; | ||
| 245 | jmp extend_setup ;AN022; exit with error | ||
| 246 | |||
| 247 | pure_file: | ||
| 248 | mov bx,ax ; Is pure file | ||
| 249 | mov ax,IOCTL SHL 8 | ||
| 250 | INT int_command | ||
| 251 | mov ah,CLOSE | ||
| 252 | INT int_command | ||
| 253 | test dl,devid_ISDEV | ||
| 254 | jnz ISADEV ; If device, done | ||
| 255 | test [BP.INFO],4 | ||
| 256 | jz ISSIMPFILE ; If no path seps, done | ||
| 257 | |||
| 258 | NOTPFILE: | ||
| 259 | mov dx,word ptr [BP.BUF] | ||
| 260 | cmp dl,0 ;AN034; If no drive specified, get | ||
| 261 | jz set_drive_spec ;AN034; default drive dir | ||
| 262 | cmp dh,':' | ||
| 263 | jz DRVSPEC5 | ||
| 264 | |||
| 265 | set_drive_spec: ;AN034; | ||
| 266 | mov dl,'@' | ||
| 267 | |||
| 268 | DRVSPEC5: | ||
| 269 | or dl,20h | ||
| 270 | sub dl,60h ; A = 1 | ||
| 271 | invoke SAVUDIR1 | ||
| 272 | jnc curdir_ok ;AN022; if error - exit | ||
| 273 | invoke get_ext_error_number ;AN022; get the extended error | ||
| 274 | jmp extend_setup ;AN022; exit with error | ||
| 275 | |||
| 276 | curdir_ok: ;AN022; | ||
| 277 | mov dx,bp | ||
| 278 | add dx,BUF ; Set DX for upcomming CHDIRs | ||
| 279 | mov bh,[BP.INFO] | ||
| 280 | and bh,6 | ||
| 281 | cmp bh,6 ; Ambig and path ? | ||
| 282 | jnz CHECKAMB ; jmp if no | ||
| 283 | mov si,[BP.TTAIL] | ||
| 284 | mov bl,':' | ||
| 285 | cmp byte ptr [si-2],bl | ||
| 286 | jnz KNOWNOTSPEC | ||
| 287 | mov [BP.ISDIR],2 ; Know is d:/file | ||
| 288 | jmp short DOPCDJ | ||
| 289 | |||
| 290 | KNOWNOTSPEC: | ||
| 291 | mov [BP.ISDIR],1 ; Know is path/file | ||
| 292 | dec si ; Point to the / | ||
| 293 | |||
| 294 | DOPCDJ: | ||
| 295 | jmp DOPCD ;AC022; need long jump | ||
| 296 | |||
| 297 | CHECKAMB: | ||
| 298 | cmp bh,2 | ||
| 299 | jnz CHECKCD | ||
| 300 | |||
| 301 | ISSIMPFILE: | ||
| 302 | ISADEV: | ||
| 303 | mov [BP.ISDIR],0 ; Know is file since ambig but no path | ||
| 304 | return | ||
| 305 | |||
| 306 | CHECKCD: | ||
| 307 | invoke SETREST1 | ||
| 308 | mov ah,CHDIR | ||
| 309 | INT int_command | ||
| 310 | jc NOTPDIR | ||
| 311 | mov di,dx | ||
| 312 | xor ax,ax | ||
| 313 | mov cx,ax | ||
| 314 | dec cx | ||
| 315 | |||
| 316 | Kloop: ;AN000; 3/3/KK | ||
| 317 | MOV AL,ES:[DI] ;AN000; 3/3/KK | ||
| 318 | INC DI ;AN000; 3/3/KK | ||
| 319 | OR AL,AL ;AN000; 3/3/KK | ||
| 320 | JZ Done ;AN000; 3/3/KK | ||
| 321 | xor ah,ah ;AN000; 3/3/KK | ||
| 322 | invoke Testkanj ;AN000; 3/3/KK | ||
| 323 | JZ Kloop ;AN000; 3/3/KK | ||
| 324 | INC DI ;AN000; 3/3/KK | ||
| 325 | INC AH ;AN000; 3/3/KK | ||
| 326 | jmp Kloop ;AN000; 3/3/KK | ||
| 327 | |||
| 328 | Done: ;AN000; 3/3/KK | ||
| 329 | dec di | ||
| 330 | mov al,[DIRCHAR] | ||
| 331 | mov [bp.ISDIR],2 ; assume d:/file | ||
| 332 | OR AH, AH ;AN000; 3/3/KK | ||
| 333 | JNZ Store_pchar ;AN000; 3/3/KK this is the trailing byte of ECS code | ||
| 334 | cmp al,[di-1] | ||
| 335 | jz GOTSRCSLSH | ||
| 336 | |||
| 337 | Store_pchar: ;AN000; 3/3/KK | ||
| 338 | stosb | ||
| 339 | mov [bp.ISDIR],1 ; know path/file | ||
| 340 | |||
| 341 | GOTSRCSLSH: | ||
| 342 | or [bp.INFO],6 | ||
| 343 | call SETSTARS | ||
| 344 | return | ||
| 345 | |||
| 346 | |||
| 347 | NOTPDIR: | ||
| 348 | invoke get_ext_error_number ;AN022; get the extended error | ||
| 349 | cmp ax,error_path_not_found ;AN022; if path not found - okay | ||
| 350 | jz notpdir_try ;AN022; | ||
| 351 | cmp ax,error_access_denied ;AN022; if access denied - okay | ||
| 352 | jnz extend_setupj ;AN022; otherwise - exit error | ||
| 353 | |||
| 354 | notpdir_try: ;AN022; | ||
| 355 | mov [bp.ISDIR],0 ; assume pure file | ||
| 356 | mov bh,[bp.INFO] | ||
| 357 | test bh,4 | ||
| 358 | retz ; Know pure file, no path seps | ||
| 359 | mov [bp.ISDIR],2 ; assume d:/file | ||
| 360 | mov si,[bp.TTAIL] | ||
| 361 | cmp byte ptr [si],0 | ||
| 362 | jz BADCDERRJ2 ; Trailing '/' | ||
| 363 | mov bl,dot_chr | ||
| 364 | cmp byte ptr [si],bl | ||
| 365 | jz BADCDERRJ2 ; If . or .. pure cd should have worked | ||
| 366 | mov bl,':' | ||
| 367 | cmp byte ptr [si-2],bl | ||
| 368 | jz DOPCD ; Know d:/file | ||
| 369 | mov [bp.ISDIR],1 ; Know path/file | ||
| 370 | dec si ; Point at last '/' | ||
| 371 | |||
| 372 | DOPCD: | ||
| 373 | xor bl,bl | ||
| 374 | xchg bl,[SI] ; Stick in a NUL | ||
| 375 | invoke SETREST1 | ||
| 376 | CMP DX,SI ;AN000; 3/3/KK | ||
| 377 | JAE LookBack ;AN000; 3/3/KK | ||
| 378 | PUSH SI ;AN000; 3/3/KK | ||
| 379 | PUSH CX ;AN000; 3/3/KK | ||
| 380 | MOV CX,SI ;AN000; 3/3/KK | ||
| 381 | MOV SI,DX ;AN000; 3/3/KK | ||
| 382 | |||
| 383 | Kloop2: ;AN000; 3/3/KK | ||
| 384 | LODSB ;AN000; 3/3/KK | ||
| 385 | invoke TestKanj ;AN000; 3/3/KK | ||
| 386 | jz NotKanj4 ;AN000; 3/3/KK | ||
| 387 | LODSB ;AN000; 3/3/KK | ||
| 388 | CMP SI,CX ;AN000; 3/3/KK | ||
| 389 | JB Kloop2 ;AN000; 3/3/KK | ||
| 390 | POP CX ;AN000; 3/3/KK | ||
| 391 | POP SI ;AN000; 3/3/KK | ||
| 392 | JMP SHORT DoCdr ;AN000; 3/3/KK Last char is ECS code, don't check for | ||
| 393 | ; trailing path sep | ||
| 394 | NotKanj4: ;AN000; 3/3/KK | ||
| 395 | CMP SI,CX ;AN000; 3/3/KK | ||
| 396 | JB Kloop2 ;AN000; 3/3/KK | ||
| 397 | POP CX ;AN000; 3/3/KK | ||
| 398 | POP SI ;AN000; 3/3/KK | ||
| 399 | |||
| 400 | LookBack: ;AN000; 3/3/KK | ||
| 401 | CMP BL,[SI-1] ; if double slash, then complain. | ||
| 402 | JZ BadCDErrJ2 | ||
| 403 | |||
| 404 | DoCdr: ;AN000; 3/3/KK | ||
| 405 | mov ah,CHDIR | ||
| 406 | INT int_command | ||
| 407 | xchg bl,[SI] | ||
| 408 | retnc | ||
| 409 | invoke get_ext_error_number ;AN022; get the extended error | ||
| 410 | |||
| 411 | EXTEND_SETUPJ: ;AN022; | ||
| 412 | JMP EXTEND_SETUP ;AN022; go issue the error message | ||
| 413 | |||
| 414 | BADCDERRJ2: | ||
| 415 | jmp badpath_err ;AC022; go issue path not found message | ||
| 416 | |||
| 417 | SETSTARS: | ||
| 418 | mov [bp.TTAIL],DI | ||
| 419 | add [bp.SIZ],12 | ||
| 420 | mov ax,dot_qmark | ||
| 421 | mov cx,8 | ||
| 422 | rep stosb | ||
| 423 | xchg al,ah | ||
| 424 | stosb | ||
| 425 | xchg al,ah | ||
| 426 | mov cl,3 | ||
| 427 | rep stosb | ||
| 428 | xor al,al | ||
| 429 | stosb | ||
| 430 | return | ||
| 431 | |||
| 432 | PUBLIC CompName | ||
| 433 | COMPNAME: | ||
| 434 | |||
| 435 | mov si,offset trangroup:DESTBUF ;g do name translate of target | ||
| 436 | mov di,offset trangroup:TRGXNAME ;g save for name comparison | ||
| 437 | mov ah,xnametrans ;g | ||
| 438 | int int_command ;g | ||
| 439 | |||
| 440 | MOV si,offset trangroup:SRCXNAME ;g get name translate of source | ||
| 441 | MOV di,offset trangroup:TRGXNAME ;g get name translate of target | ||
| 442 | |||
| 443 | |||
| 444 | invoke STRCOMP | ||
| 445 | |||
| 446 | return | ||
| 447 | |||
| 448 | TRANCODE ENDS | ||
| 449 | END | ||
| 450 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/COMMAND/CPARSE.ASM b/v4.0/src/CMD/COMMAND/CPARSE.ASM new file mode 100644 index 0000000..f751086 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/CPARSE.ASM | |||
| @@ -0,0 +1,417 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)cparse.asm 1.1 85/05/14 | ||
| 3 | ; SCCSID = @(#)cparse.asm 1.1 85/05/14 | ||
| 4 | INCLUDE comsw.asm | ||
| 5 | |||
| 6 | .xlist | ||
| 7 | .xcref | ||
| 8 | INCLUDE DOSSYM.INC | ||
| 9 | INCLUDE DEVSYM.INC | ||
| 10 | INCLUDE comseg.asm | ||
| 11 | INCLUDE comequ.asm | ||
| 12 | .list | ||
| 13 | .cref | ||
| 14 | |||
| 15 | |||
| 16 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 17 | EXTRN BADCD_PTR:WORD ;AC022; | ||
| 18 | EXTRN BADCPMES_ptr:word ;AC000; | ||
| 19 | TRANDATA ENDS | ||
| 20 | |||
| 21 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 22 | EXTRN comma:byte | ||
| 23 | EXTRN cpyflag:byte | ||
| 24 | EXTRN CURDRV:BYTE | ||
| 25 | EXTRN ELCNT:BYTE | ||
| 26 | EXTRN ELPOS:BYTE | ||
| 27 | EXTRN EXPAND_STAR:BYTE | ||
| 28 | EXTRN SKPDEL:BYTE | ||
| 29 | EXTRN STARTEL:WORD | ||
| 30 | EXTRN SWITCHAR:BYTE | ||
| 31 | EXTRN switch_list:byte | ||
| 32 | EXTRN TPA:WORD | ||
| 33 | TRANSPACE ENDS | ||
| 34 | |||
| 35 | TRANCODE SEGMENT PUBLIC BYTE | ||
| 36 | |||
| 37 | ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING | ||
| 38 | |||
| 39 | EXTRN CERROR:NEAR | ||
| 40 | |||
| 41 | PUBLIC BADCDERR ;AC022; | ||
| 42 | PUBLIC CPARSE | ||
| 43 | |||
| 44 | SWCOUNT EQU 5 ; Must agree with length of switch_list | ||
| 45 | |||
| 46 | ;-----------------------------------------------------------------------; | ||
| 47 | ; ENTRY: ; | ||
| 48 | ; DS:SI Points input buffer ; | ||
| 49 | ; ES:DI Points to the token buffer ; | ||
| 50 | ; BL Special delimiter for this call ; | ||
| 51 | ; Always checked last ; | ||
| 52 | ; set it to space if there is no special delimiter ; | ||
| 53 | ; EXIT: ; | ||
| 54 | ; DS:SI Points to next char in the input buffer ; | ||
| 55 | ; ES:DI Points to the token buffer ; | ||
| 56 | ; [STARTEL] Points to start of last element of path in token ; | ||
| 57 | ; points to a NUL for no element strings 'd:' 'd:/' ; | ||
| 58 | ; CX Character count ; | ||
| 59 | ; BH Condition Code ; | ||
| 60 | ; Bit 1H of BH set if switch character ; | ||
| 61 | ; Token buffer contains char after ; | ||
| 62 | ; switch character ; | ||
| 63 | ; BP has switch bits set (ORing only) ; | ||
| 64 | ; Bit 2H of BH set if ? or * in token ; | ||
| 65 | ; if * found element ? filled ; | ||
| 66 | ; Bit 4H of BH set if path sep in token ; | ||
| 67 | ; Bit 80H of BH set if the special delimiter ; | ||
| 68 | ; was skipped at the start of this token ; | ||
| 69 | ; Token buffer always starts d: for non switch tokens ; | ||
| 70 | ; CARRY SET ; | ||
| 71 | ; if CR on input ; | ||
| 72 | ; token buffer not altered ; | ||
| 73 | ; ; | ||
| 74 | ; DOES NOT RETURN ON BAD PATH, OR TRAILING SWITCH CHAR ERROR ; | ||
| 75 | ; MODIFIES: ; | ||
| 76 | ; CX, SI, AX, BH, DX and the Carry Flag ; ; | ||
| 77 | ; ; | ||
| 78 | ; -----------------------------------------------------------------------; | ||
| 79 | ;--------------- | ||
| 80 | ; Modifications to cparse: recognition of right and left parentheses | ||
| 81 | ; as integral tokens, and removal of automatic upper-case conversion code. | ||
| 82 | ; | ||
| 83 | ; Both modifications were installed in the course of adding a coherent | ||
| 84 | ; command-line parser to COMMAND.COM which builds a UNIX-style argv[]/argc | ||
| 85 | ; structure for command-line arguments. This parser relies on cparse to | ||
| 86 | ; recognize individual tokens. | ||
| 87 | ; | ||
| 88 | ; To process for-loops correctly, parentheses must therefore be | ||
| 89 | ; recognized as tokens. The upper-case conversion code was removed so | ||
| 90 | ; that commands (such as for and echo) would be able to use the "original" | ||
| 91 | ; text of the command line. | ||
| 92 | ; | ||
| 93 | ; Note also the modification to prevent the automatic conversion of colons | ||
| 94 | ; into spaces WITHIN THE SOURCE TEXT! | ||
| 95 | ; | ||
| 96 | ; Also note that BP is also clobbered if cparse recognizes any switches | ||
| 97 | ; on the command line. | ||
| 98 | ; | ||
| 99 | ; Alan L, OS/MSDOS 14 August 1983 | ||
| 100 | ;--------------- | ||
| 101 | |||
| 102 | CPARSE: | ||
| 103 | ASSUME DS:TRANGROUP,ES:TRANGROUP | ||
| 104 | |||
| 105 | xor ax,ax | ||
| 106 | mov [STARTEL],DI ; No path element (Is DI correct?) | ||
| 107 | mov [ELPOS],al ; Start in 8 char prefix | ||
| 108 | mov [SKPDEL],al ; No skip delimiter yet | ||
| 109 | mov bh,al ; Init nothing | ||
| 110 | pushf ; save flags | ||
| 111 | push di ; save the token buffer addrss | ||
| 112 | xor cx,cx ; no chars in token buffer | ||
| 113 | mov comma,cl ;g reset comma flag | ||
| 114 | moredelim: | ||
| 115 | LODSB | ||
| 116 | INVOKE DELIM | ||
| 117 | JNZ SCANCDONE | ||
| 118 | CMP AL,' ' | ||
| 119 | JZ moredelim | ||
| 120 | CMP AL,9 | ||
| 121 | JZ moredelim | ||
| 122 | xchg al,[SKPDEL] | ||
| 123 | or al,al | ||
| 124 | jz moredelim ; One non space/tab delimiter allowed | ||
| 125 | test bh,080h ;g has a special char been found? | ||
| 126 | jz no_comma ;g no - just exit | ||
| 127 | mov comma,1 ;g set comma flag | ||
| 128 | no_comma: | ||
| 129 | JMP x_done ; Nul argument | ||
| 130 | |||
| 131 | SCANCDONE: | ||
| 132 | |||
| 133 | ;;;; IF NOT KANJI 3/3/KK | ||
| 134 | ;--------------- | ||
| 135 | ; Mod to avoid upper-case conversion. | ||
| 136 | ; cmp cpyflag,1 3/3/KK | ||
| 137 | ; jnz cpcont1 3/3/KK | ||
| 138 | ; invoke UPCONV 3/3/KK | ||
| 139 | cpcont1: | ||
| 140 | ;--------------- | ||
| 141 | ;;;; ENDIF 3/3/KK | ||
| 142 | |||
| 143 | cmp al,bl ; Special delimiter? | ||
| 144 | jnz nospec | ||
| 145 | or bh,80H | ||
| 146 | jmp short moredelim | ||
| 147 | |||
| 148 | nospec: | ||
| 149 | cmp al,0DH ; a CR? | ||
| 150 | jne ncperror | ||
| 151 | jmp cperror | ||
| 152 | |||
| 153 | ncperror: | ||
| 154 | cmp al,[SWITCHAR] ; is the char the switch char? | ||
| 155 | jne na_switch ; yes, process... | ||
| 156 | jmp a_switch | ||
| 157 | |||
| 158 | na_switch: | ||
| 159 | mov dl,':' | ||
| 160 | cmp byte ptr [si],dl | ||
| 161 | jne anum_chard ; Drive not specified | ||
| 162 | |||
| 163 | ;;;; IF KANJI 3/3/KK | ||
| 164 | ;--------------- | ||
| 165 | ; Mod to avoid upper-case conversion. | ||
| 166 | cmp cpyflag,1 | ||
| 167 | jnz cpcont2 | ||
| 168 | invoke UPCONV | ||
| 169 | cpcont2: | ||
| 170 | ;--------------- | ||
| 171 | ;;;; ENDIF 3/3/KK | ||
| 172 | |||
| 173 | call move_char | ||
| 174 | lodsb ; Get the ':' | ||
| 175 | call move_char | ||
| 176 | mov [STARTEL],di | ||
| 177 | mov [ELCNT],0 | ||
| 178 | jmp anum_test | ||
| 179 | |||
| 180 | anum_chard: | ||
| 181 | mov [STARTEL],di | ||
| 182 | mov [ELCNT],0 ; Store of this char sets it to one | ||
| 183 | cmp cpyflag,1 ; Was CPARSE called from COPY? | ||
| 184 | jnz anum_char ; No, don't add drive spec. | ||
| 185 | invoke PATHCHRCMP ; Starts with a pathchar? | ||
| 186 | jnz anum_char ; no | ||
| 187 | push ax | ||
| 188 | mov al,[CURDRV] ; Insert drive spec | ||
| 189 | add al,capital_A | ||
| 190 | call move_char | ||
| 191 | mov al,':' | ||
| 192 | call move_char | ||
| 193 | pop ax | ||
| 194 | mov [STARTEL],di | ||
| 195 | mov [ELCNT],0 | ||
| 196 | |||
| 197 | anum_char: | ||
| 198 | |||
| 199 | ;;;; IF KANJI 3/3/KK | ||
| 200 | invoke TESTKANJ | ||
| 201 | jz NOTKANJ ;AC048; | ||
| 202 | call move_char | ||
| 203 | lodsb | ||
| 204 | jmp short notspecial | ||
| 205 | |||
| 206 | NOTKANJ: ;AN048; If not kanji | ||
| 207 | cmp cpyflag,1 ;AN048; and if we're in COPY | ||
| 208 | jnz testdot ;AN048; | ||
| 209 | invoke upconv ;AN048; upper case the char | ||
| 210 | |||
| 211 | TESTDOT: | ||
| 212 | ;;;; ENDIF 3/3/KK | ||
| 213 | |||
| 214 | cmp al,dot_chr | ||
| 215 | jnz testquest | ||
| 216 | inc [ELPOS] ; flag in extension | ||
| 217 | mov [ELCNT],0FFH ; Store of the '.' resets it to 0 | ||
| 218 | |||
| 219 | testquest: | ||
| 220 | cmp al,'?' | ||
| 221 | jnz testsplat | ||
| 222 | or bh,2 | ||
| 223 | |||
| 224 | testsplat: | ||
| 225 | cmp al,star | ||
| 226 | jnz testpath | ||
| 227 | or bh,2 | ||
| 228 | cmp byte ptr [expand_star],0 | ||
| 229 | jnz expand_filename | ||
| 230 | jmp SHORT testpath | ||
| 231 | |||
| 232 | badperr2j: | ||
| 233 | jmp badperr2 | ||
| 234 | |||
| 235 | expand_filename: | ||
| 236 | mov ah,7 | ||
| 237 | cmp [ELPOS],0 | ||
| 238 | jz gotelcnt | ||
| 239 | mov ah,2 | ||
| 240 | |||
| 241 | gotelcnt: | ||
| 242 | mov al,'?' | ||
| 243 | sub ah,[ELCNT] | ||
| 244 | jc badperr2j | ||
| 245 | xchg ah,cl | ||
| 246 | jcxz testpathx | ||
| 247 | |||
| 248 | qmove: | ||
| 249 | xchg ah,cl | ||
| 250 | call move_char | ||
| 251 | xchg ah,cl | ||
| 252 | loop qmove | ||
| 253 | |||
| 254 | testpathx: | ||
| 255 | xchg ah,cl | ||
| 256 | |||
| 257 | testpath: | ||
| 258 | invoke PATHCHRCMP | ||
| 259 | jnz notspecial | ||
| 260 | or bh,4 | ||
| 261 | cmp byte ptr [expand_star],0 | ||
| 262 | jz no_err_check | ||
| 263 | test bh,2 ; If just hit a '/', cannot have ? or * yet | ||
| 264 | jnz badperr | ||
| 265 | |||
| 266 | no_err_check: | ||
| 267 | mov [STARTEL],di ; New element | ||
| 268 | INC [STARTEL] ; Point to char after / | ||
| 269 | mov [ELCNT],0FFH ; Store of '/' sets it to 0 | ||
| 270 | mov [ELPOS],0 | ||
| 271 | |||
| 272 | notspecial: | ||
| 273 | call move_char ; just an alphanum string | ||
| 274 | anum_test: | ||
| 275 | |||
| 276 | lodsb | ||
| 277 | |||
| 278 | ;;;; IF NOT KANJI 3/3/KK | ||
| 279 | ;--------------- | ||
| 280 | ; Mod to avoid upper-case conversion. | ||
| 281 | ; cmp cpyflag,1 3/3/KK | ||
| 282 | ; jnz cpcont3 3/3/KK | ||
| 283 | ; invoke UPCONV 3/3/KK | ||
| 284 | cpcont3: | ||
| 285 | ;--------------- | ||
| 286 | ;;;; ENDIF 3/3/KK | ||
| 287 | |||
| 288 | INVOKE DELIM | ||
| 289 | je x_done | ||
| 290 | |||
| 291 | cmp al,0DH | ||
| 292 | je x_done | ||
| 293 | cmp al,[SWITCHAR] | ||
| 294 | je x_done | ||
| 295 | cmp al,bl | ||
| 296 | je x_done | ||
| 297 | cmp al,':' ; ':' allowed as trailer because | ||
| 298 | ; of devices | ||
| 299 | ;;;; IF KANJI 3/3/KK | ||
| 300 | je FOO15 | ||
| 301 | jmp anum_char | ||
| 302 | FOO15: | ||
| 303 | ;;; ELSE 3/3/KK | ||
| 304 | ;;; jne anum_charj 3/3/KK | ||
| 305 | ;;; ENDIF 3/3/KK | ||
| 306 | |||
| 307 | ;--------------- | ||
| 308 | ; Modification made for parseline. | ||
| 309 | ; Why would it be necessary to change colons to spaces? In this | ||
| 310 | ; case, EVERY colon is changed to a space; e.g., 'f:' yields 'f ', | ||
| 311 | ; but so does 'echo foo:bar' yield 'echo foo bar'. | ||
| 312 | ;--------------- | ||
| 313 | cmp cpyflag,2 ; Is CPARSE parsing the 1st token from | ||
| 314 | ; from PARSELINE? | ||
| 315 | jnz cpcont4 ; No, continue | ||
| 316 | call move_char ; Yes, save the ':' and go get another | ||
| 317 | jmp anum_test ; character. | ||
| 318 | |||
| 319 | cpcont4: | ||
| 320 | inc si ;Skip the ':' | ||
| 321 | jmp short x_done | ||
| 322 | |||
| 323 | anum_charj: | ||
| 324 | jmp anum_char | ||
| 325 | |||
| 326 | badperr2: | ||
| 327 | mov dx,offset trangroup:BADCPMES_ptr | ||
| 328 | jmp CERROR | ||
| 329 | |||
| 330 | badperr: | ||
| 331 | BADCDERR: ;AC022; Issue "Invalid Directory" | ||
| 332 | MOV DX,OFFSET TRANGROUP:BADCD_ptr ;AC022; message | ||
| 333 | JMP CERROR ;AC022; | ||
| 334 | |||
| 335 | cperror: | ||
| 336 | dec si ; adjust the pointer | ||
| 337 | pop di ; retrive token buffer address | ||
| 338 | popf ; restore flags | ||
| 339 | stc ; set the carry bit | ||
| 340 | return | ||
| 341 | |||
| 342 | x_done: | ||
| 343 | dec si ; adjust for next round | ||
| 344 | ;--------------- | ||
| 345 | ; Mod to recognize right and left parens as integral tokens. | ||
| 346 | x_done2: | ||
| 347 | ;--------------- | ||
| 348 | jmp short out_token | ||
| 349 | |||
| 350 | a_switch: | ||
| 351 | OR BH,1 ; Indicate switch | ||
| 352 | OR BP,fSwitch | ||
| 353 | INVOKE SCANOFF | ||
| 354 | INC SI | ||
| 355 | invoke testkanj ;AN057; See if DBCS lead byte | ||
| 356 | jz a_switch_notkanj ;AN057; no - continue processing | ||
| 357 | call move_char ;AN057; DBCS - store first byte | ||
| 358 | lodsb ;AN057; get second byte | ||
| 359 | call move_char ;AN057; store second byte | ||
| 360 | or bp,fBadSwitch ;AN057; DBCS switch is invalid | ||
| 361 | jmp short out_token ;AN057; don't bother checking switch | ||
| 362 | a_switch_notkanj: ;AN057; | ||
| 363 | cmp al,0DH | ||
| 364 | jne Store_swt | ||
| 365 | mov al,0 | ||
| 366 | stosb ; null at the end | ||
| 367 | OR BP,fBadSwitch | ||
| 368 | jmp cperror ; Trailing switch character error | ||
| 369 | ; BP = fSwitch but no switch | ||
| 370 | ; bit is set (unknown switch) | ||
| 371 | Store_swt: | ||
| 372 | call move_char ; store the character | ||
| 373 | ; | ||
| 374 | ;--------------- | ||
| 375 | ; This upconv call must stay. It is used to identify copy-switches | ||
| 376 | ; on the command line, and won't store anything into the output buffer. | ||
| 377 | invoke UPCONV | ||
| 378 | ;--------------- | ||
| 379 | ; | ||
| 380 | PUSH ES | ||
| 381 | PUSH DI | ||
| 382 | PUSH CX | ||
| 383 | PUSH CS | ||
| 384 | POP ES | ||
| 385 | ASSUME ES:TRANGROUP | ||
| 386 | MOV DI,OFFSET TRANGROUP:switch_list | ||
| 387 | MOV CX,SWCOUNT | ||
| 388 | OR BP,fBadSwitch | ||
| 389 | REPNE SCASB | ||
| 390 | JNZ out_tokenp | ||
| 391 | AND BP,NOT fBadSwitch | ||
| 392 | MOV AX,1 | ||
| 393 | SHL AX,CL | ||
| 394 | OR BP,AX | ||
| 395 | |||
| 396 | out_tokenp: | ||
| 397 | POP CX | ||
| 398 | POP DI | ||
| 399 | POP ES | ||
| 400 | |||
| 401 | ASSUME ES:NOTHING | ||
| 402 | out_token: | ||
| 403 | mov al,0 | ||
| 404 | stosb ; null at the end | ||
| 405 | pop di ; restore token buffer pointer | ||
| 406 | popf | ||
| 407 | clc ; clear carry flag | ||
| 408 | return | ||
| 409 | |||
| 410 | move_char: | ||
| 411 | stosb ; store char in token buffer | ||
| 412 | inc cx ; increment char count | ||
| 413 | inc [ELCNT] ; increment element count for * substi | ||
| 414 | return | ||
| 415 | |||
| 416 | TRANCODE ENDS | ||
| 417 | END | ||
diff --git a/v4.0/src/CMD/COMMAND/ENVDATA.ASM b/v4.0/src/CMD/COMMAND/ENVDATA.ASM new file mode 100644 index 0000000..ed4cd9e --- /dev/null +++ b/v4.0/src/CMD/COMMAND/ENVDATA.ASM | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | ; SCCSID = @(#)envdata.asm 1.1 85/05/14 | ||
| 2 | ; SCCSID = @(#)envdata.asm 1.1 85/05/14 | ||
| 3 | ; This file is included by command.asm and is used as the default command | ||
| 4 | ; environment. | ||
| 5 | |||
| 6 | ENVARENA SEGMENT PUBLIC PARA | ||
| 7 | ORG 0 | ||
| 8 | DB 10h DUP (?) ;Pad for memory allocation addr mark | ||
| 9 | ENVARENA ENDS | ||
| 10 | |||
| 11 | ENVIRONMENT SEGMENT PUBLIC PARA ; Default COMMAND environment | ||
| 12 | |||
| 13 | PUBLIC ECOMSPEC,ENVIREND,PATHSTRING | ||
| 14 | |||
| 15 | ORG 0 | ||
| 16 | PATHSTRING DB "PATH=" | ||
| 17 | USERPATH LABEL BYTE | ||
| 18 | |||
| 19 | DB 0 ; Null path | ||
| 20 | DB "COMSPEC=" | ||
| 21 | ECOMSPEC DB "\COMMAND.COM" ;AC062 | ||
| 22 | DB 134 DUP (0) | ||
| 23 | |||
| 24 | ENVIREND LABEL BYTE | ||
| 25 | |||
| 26 | ENVIRONSIZ EQU $-PATHSTRING | ||
| 27 | ENVIRONSIZ2 EQU $-ECOMSPEC | ||
| 28 | ENVIRONMENT ENDS | ||
diff --git a/v4.0/src/CMD/COMMAND/FORDATA.ASM b/v4.0/src/CMD/COMMAND/FORDATA.ASM new file mode 100644 index 0000000..b46ba3d --- /dev/null +++ b/v4.0/src/CMD/COMMAND/FORDATA.ASM | |||
| @@ -0,0 +1,19 @@ | |||
| 1 | ; SCCSID = @(#)fordata.asm 1.1 85/05/14 | ||
| 2 | ; SCCSID = @(#)fordata.asm 1.1 85/05/14 | ||
| 3 | ; Data structure definitions included by tfor.asm | ||
| 4 | |||
| 5 | for_info STRUC | ||
| 6 | for_args DB (SIZE arg_unit) DUP (?) ; argv[] structure | ||
| 7 | FOR_COM_START DB (?) ; beginning of <command> | ||
| 8 | FOR_EXPAND DW (?) ; * or ? item in <list>? | ||
| 9 | FOR_MINARG DW (?) ; beginning of <list> | ||
| 10 | FOR_MAXARG DW (?) ; end of <list> | ||
| 11 | forbuf DW 64 DUP (?) ; temporary buffer | ||
| 12 | fordma DW 64 DUP (?) ; FindFirst/Next buffer | ||
| 13 | FOR_VAR DB (?) ; loop control variable | ||
| 14 | for_info ENDS | ||
| 15 | |||
| 16 | ; empty segment done for bogus addressing | ||
| 17 | for_segment segment | ||
| 18 | f LABEL BYTE | ||
| 19 | for_segment ends | ||
diff --git a/v4.0/src/CMD/COMMAND/IFEQU.ASM b/v4.0/src/CMD/COMMAND/IFEQU.ASM new file mode 100644 index 0000000..9c0ee29 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/IFEQU.ASM | |||
| @@ -0,0 +1,18 @@ | |||
| 1 | ; SCCSID = @(#)ifequ.asm 1.1 85/05/14 | ||
| 2 | ; SCCSID = @(#)ifequ.asm 1.1 85/05/14 | ||
| 3 | ;************************************* | ||
| 4 | ; COMMAND EQUs which are switch dependant | ||
| 5 | |||
| 6 | IF1 | ||
| 7 | IF IBM | ||
| 8 | %OUT DBCS Enabled IBM version | ||
| 9 | ELSE | ||
| 10 | %OUT Normal version | ||
| 11 | ENDIF | ||
| 12 | |||
| 13 | ;; IF KANJI 3/3/KK | ||
| 14 | ;; %OUT Kanji version 3/3/KK | ||
| 15 | ;; ENDIF 3/3/KK | ||
| 16 | |||
| 17 | ENDIF | ||
| 18 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/COMMAND/INIT.ASM b/v4.0/src/CMD/COMMAND/INIT.ASM new file mode 100644 index 0000000..3ac84b6 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/INIT.ASM | |||
| @@ -0,0 +1,1685 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)init.asm 4.13 85/11/03 | ||
| 3 | ; SCCSID = @(#)init.asm 4.13 85/11/03 | ||
| 4 | TITLE COMMAND Initialization | ||
| 5 | |||
| 6 | INCLUDE comsw.asm | ||
| 7 | |||
| 8 | .xlist | ||
| 9 | .xcref | ||
| 10 | INCLUDE DOSSYM.INC | ||
| 11 | include doscntry.inc ;AC000; | ||
| 12 | INCLUDE comseg.asm | ||
| 13 | INCLUDE comequ.asm | ||
| 14 | include resmsg.equ ;AN000; | ||
| 15 | .list | ||
| 16 | .cref | ||
| 17 | |||
| 18 | |||
| 19 | ENVIRONSIZ EQU 0A0H ;Must agree with values in EVIRONMENT segment | ||
| 20 | ENVIRONSIZ2 EQU 092H | ||
| 21 | |||
| 22 | ENVBIG EQU 32768 | ||
| 23 | ENVSML EQU 160 | ||
| 24 | KOREA_COUNTRY_CODE EQU 82 | ||
| 25 | |||
| 26 | CODERES SEGMENT PUBLIC BYTE ;AC000; | ||
| 27 | EXTRN CONTC:NEAR | ||
| 28 | EXTRN DskErr:NEAR | ||
| 29 | EXTRN endinit:near | ||
| 30 | EXTRN INT_2E:NEAR | ||
| 31 | EXTRN LODCOM:NEAR | ||
| 32 | EXTRN RSTACK:WORD | ||
| 33 | CODERES ENDS | ||
| 34 | |||
| 35 | DATARES SEGMENT PUBLIC BYTE ;AC000; | ||
| 36 | EXTRN abort_char:byte ;AN000; | ||
| 37 | EXTRN append_state:word ;AN042; | ||
| 38 | EXTRN BADFAT_OP_SEG:WORD ;AN000; | ||
| 39 | EXTRN BATCH:WORD | ||
| 40 | EXTRN COM_FCB1:DWORD | ||
| 41 | EXTRN COM_FCB2:DWORD | ||
| 42 | EXTRN COM_PTR:DWORD | ||
| 43 | EXTRN com_xlat_addr:word | ||
| 44 | EXTRN COMDRV:BYTE | ||
| 45 | EXTRN COMPRMT1_SEG:WORD ;AN000; | ||
| 46 | EXTRN COMPRMT1_SEG2:WORD ;AN000; | ||
| 47 | EXTRN COMSPEC:BYTE | ||
| 48 | EXTRN comspec_print:word | ||
| 49 | EXTRN comspec_end:word | ||
| 50 | EXTRN cpdrv:byte | ||
| 51 | EXTRN crit_msg_off:word ;AN000; | ||
| 52 | EXTRN crit_msg_seg:word ;AN000; | ||
| 53 | EXTRN critical_msg_start:byte ;AN000; | ||
| 54 | EXTRN DATARESEND:BYTE ;AC000; | ||
| 55 | EXTRN dbcs_vector_addr:word ;AN000; | ||
| 56 | EXTRN DEVE_OP_SEG:WORD ;AN000; | ||
| 57 | EXTRN DEVE_OP_SEG2:WORD ;AN000; | ||
| 58 | EXTRN disp_class:byte ;AN000; | ||
| 59 | EXTRN DRVNUM_OP_SEG:WORD ;AN000; | ||
| 60 | EXTRN DRVNUM_OP_SEG2:WORD ;AN000; | ||
| 61 | EXTRN EchoFlag:BYTE | ||
| 62 | EXTRN ENVIRSEG:WORD | ||
| 63 | EXTRN ERR15_OP_SEG:WORD ;AN000; | ||
| 64 | EXTRN ERR15_OP_SEG2:WORD ;AN000; | ||
| 65 | EXTRN ERR15_OP_SEG3:WORD ;AN000; | ||
| 66 | EXTRN extended_msg_start:byte ;AN000; | ||
| 67 | EXTRN extmsgend:byte ;AN000; | ||
| 68 | EXTRN fFail:BYTE | ||
| 69 | EXTRN fucase_addr:word ;AN000; | ||
| 70 | EXTRN InitFlag:BYTE | ||
| 71 | EXTRN IO_SAVE:WORD | ||
| 72 | EXTRN LTPA:WORD ;AC000; | ||
| 73 | EXTRN MEMSIZ:WORD | ||
| 74 | EXTRN MYSEG:WORD ;AC000; | ||
| 75 | EXTRN MYSEG1:WORD | ||
| 76 | EXTRN MYSEG2:WORD | ||
| 77 | EXTRN nest:word | ||
| 78 | EXTRN number_subst:byte ;AN000; | ||
| 79 | EXTRN OldTerm:DWORD | ||
| 80 | EXTRN PARENT:WORD | ||
| 81 | ;AD060; EXTRN pars_msg_off:word ;AN000; | ||
| 82 | ;AD060; EXTRN pars_msg_seg:word ;AN000; | ||
| 83 | EXTRN parse_msg_start:byte ;AN000; | ||
| 84 | EXTRN parsemes_ptr:word ;AN000; | ||
| 85 | EXTRN PERMCOM:BYTE | ||
| 86 | EXTRN RES_TPA:WORD | ||
| 87 | EXTRN resmsgend:word ;AN000; | ||
| 88 | EXTRN RSWITCHAR:BYTE | ||
| 89 | EXTRN SINGLECOM:WORD | ||
| 90 | EXTRN SUM:WORD | ||
| 91 | EXTRN TRNSEG:WORD | ||
| 92 | EXTRN TrnMvFlg:BYTE | ||
| 93 | DATARES ENDS | ||
| 94 | |||
| 95 | BATARENA SEGMENT PUBLIC PARA ;AC000; | ||
| 96 | BATARENA ENDS | ||
| 97 | |||
| 98 | BATSEG SEGMENT PUBLIC PARA ;AC000; | ||
| 99 | BATSEG ENDS | ||
| 100 | |||
| 101 | ENVARENA SEGMENT PUBLIC PARA ;AC000; | ||
| 102 | ENVARENA ENDS | ||
| 103 | |||
| 104 | ENVIRONMENT SEGMENT PUBLIC PARA ; Default COMMAND environment | ||
| 105 | EXTRN ECOMSPEC:BYTE | ||
| 106 | EXTRN ENVIREND:BYTE | ||
| 107 | EXTRN PATHSTRING:BYTE | ||
| 108 | ENVIRONMENT ENDS | ||
| 109 | |||
| 110 | TAIL SEGMENT PUBLIC PARA | ||
| 111 | EXTRN TRANSTART:WORD | ||
| 112 | TAIL ENDS | ||
| 113 | |||
| 114 | TRANCODE SEGMENT PUBLIC BYTE ;AC000; | ||
| 115 | EXTRN DATINIT:FAR | ||
| 116 | EXTRN printf_init:far | ||
| 117 | TRANCODE ENDS | ||
| 118 | |||
| 119 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 120 | EXTRN TRANSPACEEND:BYTE | ||
| 121 | TRANSPACE ENDS | ||
| 122 | |||
| 123 | ; This is the area used for the autoexec.bat file. BATARENA is a pad for the | ||
| 124 | ; the address mark placed by DOS. | ||
| 125 | |||
| 126 | BATARENA SEGMENT PUBLIC PARA | ||
| 127 | |||
| 128 | ORG 0 | ||
| 129 | DB 10h DUP (?) ;Pad for memory allocation addr mark | ||
| 130 | |||
| 131 | BATARENA ENDS | ||
| 132 | |||
| 133 | BATSEG SEGMENT PUBLIC PARA ;Autoexec.bat segment | ||
| 134 | |||
| 135 | ORG 0 | ||
| 136 | initbat batchsegment <> ;batch segment | ||
| 137 | DB 31 DUP (0) ;reserve area for batch file name & pad | ||
| 138 | |||
| 139 | BATSEG ENDS | ||
| 140 | |||
| 141 | ; ******************************************************************* | ||
| 142 | ; START OF INIT PORTION | ||
| 143 | ; This code is overlayed the first time the TPA is used. | ||
| 144 | |||
| 145 | INIT SEGMENT PUBLIC PARA | ||
| 146 | |||
| 147 | EXTRN AUTOBAT:byte | ||
| 148 | EXTRN BADCSPFL:byte | ||
| 149 | EXTRN bslash:byte | ||
| 150 | EXTRN CHUCKENV:byte | ||
| 151 | EXTRN command_c_syn:byte ;AN000; | ||
| 152 | EXTRN command_d_syn:byte ;AN000; | ||
| 153 | EXTRN command_e_syn:byte ;AN000; | ||
| 154 | EXTRN command_f_syn:byte ;AN000; | ||
| 155 | EXTRN command_m_syn:byte ;AN000; | ||
| 156 | EXTRN command_p_syn:byte ;AN000; | ||
| 157 | EXTRN comnd1_syn:word ;AN000; | ||
| 158 | EXTRN comnd1_addr:dword ;AN000; | ||
| 159 | EXTRN COMSPECT:byte | ||
| 160 | EXTRN comspstring:byte | ||
| 161 | EXTRN dswitch:byte ;AN018; | ||
| 162 | EXTRN ECOMLOC:word | ||
| 163 | EXTRN EnvMax:WORD | ||
| 164 | EXTRN EnvSiz:WORD | ||
| 165 | EXTRN equalsign:byte | ||
| 166 | EXTRN eswitch:byte ;AN018; | ||
| 167 | EXTRN ext_msg:byte ;AN000; | ||
| 168 | EXTRN fslash:byte | ||
| 169 | EXTRN INITADD:dword | ||
| 170 | EXTRN initend:word | ||
| 171 | EXTRN init_parse:dword ;AN054; | ||
| 172 | EXTRN INTERNAT_INFO:BYTE ;AN000; 3/3/KK | ||
| 173 | EXTRN KAUTOBAT:byte ;AN000; 3/3/KK | ||
| 174 | EXTRN lcasea:byte | ||
| 175 | EXTRN lcasez:byte | ||
| 176 | EXTRN num_positionals:word ;AN000; | ||
| 177 | EXTRN oldenv:word | ||
| 178 | EXTRN old_parse_ptr:word ;AN057; | ||
| 179 | EXTRN parse_command:byte ;AN000; | ||
| 180 | EXTRN pars_msg_off:word ;AN060; | ||
| 181 | EXTRN pars_msg_seg:word ;AN060; | ||
| 182 | EXTRN PRDATTM:byte | ||
| 183 | EXTRN resetenv:word ;AC000; | ||
| 184 | EXTRN scswitch:byte | ||
| 185 | EXTRN space:byte | ||
| 186 | EXTRN triage_add:dword ;AC000; | ||
| 187 | EXTRN trnsize:word | ||
| 188 | EXTRN ucasea:byte | ||
| 189 | EXTRN usedenv:word | ||
| 190 | |||
| 191 | |||
| 192 | ;AD054; EXTRN SYSPARSE:NEAR | ||
| 193 | |||
| 194 | PUBLIC CONPROC | ||
| 195 | PUBLIC init_contc_specialcase | ||
| 196 | |||
| 197 | ASSUME CS:RESGROUP,DS:RESGROUP,ES:RESGROUP,SS:RESGROUP | ||
| 198 | |||
| 199 | ORG 0 | ||
| 200 | ZERO = $ | ||
| 201 | |||
| 202 | |||
| 203 | CONPROC: | ||
| 204 | MOV SP,OFFSET RESGROUP:RSTACK ; MUST be first instruction | ||
| 205 | |||
| 206 | CALL SYSLOADMSG ;AN000; check dos version | ||
| 207 | JNC OKDOS ;AN000; if no problem - continue | ||
| 208 | |||
| 209 | mov ax,badver ;AN000; set DOS version | ||
| 210 | invoke sysdispmsg ;AN000; must be incorrect version | ||
| 211 | mov ax,es | ||
| 212 | cmp es:[PDB_Parent_PID],AX ; If command is its own parent, | ||
| 213 | here: ; loop forever. | ||
| 214 | Jz here | ||
| 215 | int 20h ; Otherwise, exit. | ||
| 216 | |||
| 217 | ; | ||
| 218 | ; Turn APPEND off during initialization processing | ||
| 219 | ; | ||
| 220 | okdos: | ||
| 221 | mov ax,AppendInstall ;AN042; see if append installed | ||
| 222 | int 2fh ;AN042; | ||
| 223 | cmp al,0 ;AN042; append installed? | ||
| 224 | je set_msg_addr ;AN042; no - continue | ||
| 225 | mov ax,AppendDOS ;AN042; see if append DOS version right | ||
| 226 | int 2fh ;AN042; | ||
| 227 | cmp ax,-1 ;AN042; append version correct? | ||
| 228 | jne set_msg_addr ;AN042; no - continue | ||
| 229 | mov ax,AppendGetState ;AN042; Get the state of Append | ||
| 230 | int 2fh ;AN042; | ||
| 231 | mov append_state,bx ;AN042; save append state | ||
| 232 | xor bx,bx ;AN042; clear out state | ||
| 233 | mov ax,AppendSetState ;AN042; Set the state of Append | ||
| 234 | int 2fh ;AN042; set everything off | ||
| 235 | |||
| 236 | set_msg_addr: | ||
| 237 | ; | ||
| 238 | ; Get addresses of old critical and parse errors and save so they can | ||
| 239 | ; be reset if COMMAND needs to exit | ||
| 240 | ; | ||
| 241 | |||
| 242 | push es ;AN000; SAVE ES DESTROYED BY INT 2FH | ||
| 243 | ;AD060; mov ah,multdos ;AN000; set up to call DOS through int 2fh | ||
| 244 | ;AD060; mov al,message_2f ;AN000; call for message retriever | ||
| 245 | mov ax,(multdos shl 8 or message_2f);AN060; set up to call DOS through int 2fh | ||
| 246 | mov dl,get_parse_msg ;AN000; get parse message address | ||
| 247 | int 2fh ;AN000; | ||
| 248 | mov cs:pars_msg_seg,es ;AN000; save returned segment | ||
| 249 | mov cs:pars_msg_off,di ;AN000; save returned offset | ||
| 250 | |||
| 251 | ;AD060; mov ah,multdos ;AN000; set up to call DOS through int 2fh | ||
| 252 | ;AD060; mov al,message_2f ;AN000; call for message retriever | ||
| 253 | mov ax,(multdos shl 8 or message_2f);AN060; set up to call DOS through int 2fh | ||
| 254 | mov dl,get_critical_msg ;AN000; get critical error message address | ||
| 255 | int 2fh ;AN000; | ||
| 256 | mov cs:crit_msg_seg,es ;AN000; save returned segment | ||
| 257 | mov cs:crit_msg_off,di ;AN000; save returned offset | ||
| 258 | pop es ;AN000; RESTORE ES DESTROYED BY INT 2FH | ||
| 259 | |||
| 260 | ; | ||
| 261 | ; Set addresses of critical and parse errors in this level of COMMAND | ||
| 262 | ; | ||
| 263 | |||
| 264 | ;AD060; mov ah,multdos ;AN000; set up to call DOS through int 2fh | ||
| 265 | ;AD060; mov al,message_2f ;AN000; call for message retriever | ||
| 266 | ;AD060; mov dl,set_parse_msg ;AN000; set up parse message address | ||
| 267 | mov di,offset resgroup:parse_msg_start ;AN000; start address | ||
| 268 | ;AD060; int 2fh ;AN000; | ||
| 269 | call set_parse_2f ;AN060; set parse error address | ||
| 270 | |||
| 271 | |||
| 272 | ;AD060; mov ah,multdos ;AN000; set up to call DOS through int 2fh | ||
| 273 | ;AD060; mov al,message_2f ;AN000; call for message retriever | ||
| 274 | mov ax,(multdos shl 8 or message_2f);AN060; set up to call DOS through int 2fh | ||
| 275 | mov dl,set_critical_msg ;AN000; set up critical error message address | ||
| 276 | mov di,offset resgroup:critical_msg_start ;AN000; start address | ||
| 277 | int 2fh ;AN000; | ||
| 278 | |||
| 279 | mov di,offset resgroup:dataresend+15 ;AN000; get address of resident end | ||
| 280 | mov [resmsgend],di ;AN000; save it | ||
| 281 | call sysloadmsg ;AN000; load message addresses | ||
| 282 | call get_msg_ptr ;AN000; set up pointers to some translated chars | ||
| 283 | mov ah,GetExtCntry ;g get extended country information | ||
| 284 | mov al,2 ;g minor function - ucase table | ||
| 285 | mov dx,-1 ;g | ||
| 286 | mov bx,-1 ;g | ||
| 287 | mov cx,5 ;g number of bytes we want | ||
| 288 | mov di,offset resgroup:com_xlat_addr ;g buffer to put address in | ||
| 289 | int int_command ;g | ||
| 290 | |||
| 291 | mov ah,GetExtCntry ;AN000; get extended country info | ||
| 292 | mov al,4 ;AN000; get file ucase table | ||
| 293 | mov dx,-1 ;AN000; | ||
| 294 | mov bx,-1 ;AN000; | ||
| 295 | mov cx,5 ;AN000; number of bytes we want | ||
| 296 | mov di,offset resgroup:fucase_addr ;AN000; buffer for address | ||
| 297 | int int_command ;AN000; | ||
| 298 | |||
| 299 | mov dx,offset resgroup:transtart+15 ;eg get end of init code | ||
| 300 | mov cl,4 ;eg change to paragraphs | ||
| 301 | shr dx,cl ;eg | ||
| 302 | mov ax,cs ;eg get current segment | ||
| 303 | add ax,dx ;eg calculate segment of end of init | ||
| 304 | mov [initend],ax ;eg save this | ||
| 305 | |||
| 306 | push ds ;AN000; | ||
| 307 | mov ax, (ECS_call SHL 8) OR GetLeadBTbl ;AN000; get dbcs vector | ||
| 308 | int int_command ;AN000; | ||
| 309 | mov bx,ds ;AN000; get segment to bx | ||
| 310 | pop ds ;AN000; | ||
| 311 | mov dbcs_vector_addr,si ;AN000; save address of | ||
| 312 | mov dbcs_vector_addr+2,bx ;AN000; dbcs vector | ||
| 313 | |||
| 314 | |||
| 315 | mov ax,word ptr ds:[PDB_Parent_PID] ; Init PARENT so we can exit | ||
| 316 | mov [PARENT],ax ; correctly. | ||
| 317 | MOV AX,WORD PTR DS:[PDB_Exit] | ||
| 318 | MOV WORD PTR OldTerm,AX | ||
| 319 | MOV AX,WORD PTR DS:[PDB_Exit+2] | ||
| 320 | MOV WORD PTR OldTerm+2,AX | ||
| 321 | |||
| 322 | MOV AX,OFFSET RESGROUP:ENVIREND + 15 | ||
| 323 | MOV CL,4 ; ax = size of resident part of | ||
| 324 | SHR AX,CL ; command in paragraphs. Add | ||
| 325 | MOV CX,CS ; this to CS and you get the | ||
| 326 | ADD AX,CX ; segment of the TPA. | ||
| 327 | |||
| 328 | MOV [RES_TPA], AX ; Temporarily save the TPA segment | ||
| 329 | AND AX, 0F000H | ||
| 330 | ADD AX, 01000H ; Round up to next 64K boundary | ||
| 331 | JNC TPASET ; Memory wrap if carry set | ||
| 332 | MOV AX, [RES_TPA] | ||
| 333 | TPASET: | ||
| 334 | MOV [LTPA],AX ; Good enough for the moment | ||
| 335 | MOV AX,WORD PTR DS:[PDB_block_len] ; ax = # of paras given to command | ||
| 336 | |||
| 337 | MOV [MYSEG1],DS ; These 3 variables are used as part of | ||
| 338 | MOV [MYSEG2],DS ; 3 long ptrs that the transient will | ||
| 339 | MOV [MYSEG],DS ; use to call resident routines. | ||
| 340 | MOV [MEMSIZ],AX ; Needed for execing other programs | ||
| 341 | ; | ||
| 342 | ; Compute maximum size of environment | ||
| 343 | ; | ||
| 344 | MOV EnvMax,(Environsiz + 15) / 16 + (EnvMaximum-zero + 15)/16 - 1 | ||
| 345 | ; | ||
| 346 | ; Compute minimum size of environment | ||
| 347 | ; | ||
| 348 | |||
| 349 | MOV EnvSiz, ENVSML / 16 | ||
| 350 | |||
| 351 | MOV DX,OFFSET TRANGROUP:TRANSPACEEND + 15 ; dx = size of transient | ||
| 352 | MOV CL,4 ; in paragraphs. | ||
| 353 | SHR DX,CL | ||
| 354 | mov [trnsize],dx ;eg save size of transient in paragraphs | ||
| 355 | |||
| 356 | SUB AX,DX ; max seg addr - # para's needed for transient | ||
| 357 | MOV [TRNSEG],AX ; = seg addr to load the transient at. | ||
| 358 | MOV AX,DS:[PDB_environ] ; ax = environment segment | ||
| 359 | OR AX,AX ; If there is no environment segment, | ||
| 360 | JZ BUILDENV ; go compute one. | ||
| 361 | INC BYTE PTR [CHUCKENV] ; Flag no new ENVIRONSEG to set up | ||
| 362 | JMP SHORT ENVIRONPASSED ; Otherwise one was passed to us. | ||
| 363 | |||
| 364 | BUILDENV: ; (this label isn't very accurate) | ||
| 365 | MOV AX,OFFSET RESGROUP:PATHSTRING ; Compute the segment of the | ||
| 366 | MOV CL,4 ; environment and put it in | ||
| 367 | SHR AX,CL ; ax. | ||
| 368 | MOV DX,DS | ||
| 369 | ADD AX,DX | ||
| 370 | |||
| 371 | ENVIRONPASSED: | ||
| 372 | MOV [ENVIRSEG],AX ; Save the environment's segment and | ||
| 373 | MOV ES,AX ; load into es. | ||
| 374 | ASSUME ES:ENVIRONMENT | ||
| 375 | |||
| 376 | GOTTHEENVIR: | ||
| 377 | MOV AX,CHAR_OPER SHL 8 ; Get the switch character and store it | ||
| 378 | INT int_command ; in RSWITCHAR. | ||
| 379 | MOV [RSWITCHAR],DL | ||
| 380 | |||
| 381 | CMP DL,fslash ; If backslashes are being used as the | ||
| 382 | JNZ IUSESLASH ; path separator, change the forward | ||
| 383 | mov al,bslash ; slash in COMSPECT and ECOMSPEC (if | ||
| 384 | MOV [COMSPECT],al ; there is a new ENVIRONSEG) to | ||
| 385 | CMP BYTE PTR [CHUCKENV],0 ; backslash. | ||
| 386 | JNZ IUSESLASH | ||
| 387 | MOV ES:[ECOMSPEC],al ;eg | ||
| 388 | |||
| 389 | IUSESLASH: | ||
| 390 | ; | ||
| 391 | ; Initialize the command drive | ||
| 392 | ; | ||
| 393 | MOV AH,Get_Default_Drive | ||
| 394 | INT 21h | ||
| 395 | INC AL | ||
| 396 | MOV ComDrv,AL | ||
| 397 | |||
| 398 | MOV AL,BYTE PTR DS:[FCB] ; al = default drive number for command | ||
| 399 | OR AL,AL | ||
| 400 | JZ NoComDrv ; no drive specified | ||
| 401 | |||
| 402 | MOV AH,':' | ||
| 403 | MOV [COMDRV],AL | ||
| 404 | ADD AL,40H ; Convert number to uppercase character | ||
| 405 | |||
| 406 | STD | ||
| 407 | CMP BYTE PTR [CHUCKENV],0 ; If a new environment is being built, | ||
| 408 | JNZ NOTWIDENV ; move the default comspec string in it | ||
| 409 | PUSH DS ; 2 bytes to make room for a drivespec. | ||
| 410 | PUSH ES ; The drivespec is in ax and is copied | ||
| 411 | POP DS ; on to the front of the string. | ||
| 412 | MOV DI,OFFSET ENVIRONMENT:ECOMSPEC + ENVIRONSIZ2 - 1 ;eg | ||
| 413 | MOV SI,OFFSET ENVIRONMENT:ECOMSPEC + ENVIRONSIZ2 - 3 ;eg | ||
| 414 | |||
| 415 | MOV CX,ENVIRONSIZ2 - 2 | ||
| 416 | REP MOVSB | ||
| 417 | POP DS | ||
| 418 | MOV WORD PTR ES:[ECOMSPEC],AX | ||
| 419 | |||
| 420 | NOTWIDENV: | ||
| 421 | CLD ; Add the drivespec to the string | ||
| 422 | MOV WORD PTR [AUTOBAT],AX ; used to reference autoexec.bat | ||
| 423 | MOV WORD PTR [KAUTOBAT],AX ;AN000; used to reference kautoexe.bat 3/3/KK | ||
| 424 | |||
| 425 | NOCOMDRV: | ||
| 426 | INVOKE SETVECT ; Set interrupt vectors 22h, 23h, & 24h | ||
| 427 | |||
| 428 | ;********************************* | ||
| 429 | ; PARSING STARTS HERE | ||
| 430 | ;********************************* | ||
| 431 | |||
| 432 | push cs ;AN000; get local segment | ||
| 433 | push cs ;AN000; into DS,ES | ||
| 434 | pop ds ;AN000; | ||
| 435 | pop es ;AN000; | ||
| 436 | |||
| 437 | ASSUME DS:RESGROUP,ES:RESGROUP ;AN000; | ||
| 438 | |||
| 439 | MOV SI,80H ;AC000; get command line | ||
| 440 | LODSB ;AC000; get length of line | ||
| 441 | MOV DI,SI ;AN000; get line position in DI | ||
| 442 | XOR AH,AH ;AC000; ax = length of command line | ||
| 443 | ; | ||
| 444 | ; Insure that the command line correctly ends with a CR | ||
| 445 | ; | ||
| 446 | ADD DI,AX ;AC000; go to end of command line | ||
| 447 | MOV BYTE PTR [DI],0Dh ;AC000; insert a carriage return | ||
| 448 | xor cx,cx ;AC000; clear cx | ||
| 449 | mov num_positionals,cx ;AC000; initialize positionals | ||
| 450 | ; | ||
| 451 | ; Scan the command line looking for the parameters | ||
| 452 | ; | ||
| 453 | |||
| 454 | parse_command_line: | ||
| 455 | mov di,offset resgroup:parse_command;AN000; Get address of parse_command | ||
| 456 | mov cx,num_positionals ;AN000; Get number of positionals | ||
| 457 | xor dx,dx ;AN000; clear dx | ||
| 458 | mov old_parse_ptr,si ;AN057; save position before calling parser | ||
| 459 | call init_parse ;AN054; call parser | ||
| 460 | mov num_positionals,cx ;AN000; Save number of positionals | ||
| 461 | cmp ax,end_of_line ;AC000; are we at end of line? | ||
| 462 | jz ArgsDoneJ3 ;AC000; yes - exit | ||
| 463 | cmp ax,result_no_error ;AN000; did an error occur | ||
| 464 | jz parse_cont ;AN000; no - continue | ||
| 465 | |||
| 466 | ; | ||
| 467 | ; Before issuing error message - make sure switch is not /C | ||
| 468 | ; | ||
| 469 | |||
| 470 | parse_line_error: | ||
| 471 | push si ;AN057; save line position | ||
| 472 | push ax ;AN057; save error number | ||
| 473 | cmp ax,BadSwt_Ptr ;AN057; Was error invalid switch? | ||
| 474 | jnz parse_line_error_disp ;AN057; No - just issue message | ||
| 475 | mov di,si ;AN057; Get terminating pointer in DI | ||
| 476 | mov si,old_parse_ptr ;AN057; Get starting pointer in SI | ||
| 477 | |||
| 478 | init_chk_delim: | ||
| 479 | cmp si,di ;AN057; at end of parsed parameter? | ||
| 480 | jz parse_line_error_disp ;AN057; Yes - just display message | ||
| 481 | lodsb ;AN057; | ||
| 482 | cmp al,space ;AN057; Skip blank spaces | ||
| 483 | jz init_chk_delim ;AN057; | ||
| 484 | cmp al,tab_chr ;AN057; Skip tab characters | ||
| 485 | jz init_chk_delim ;AN057; | ||
| 486 | |||
| 487 | cmp al,[rswitchar] ;AN057; Switch? | ||
| 488 | jnz parse_line_error_disp ;AN057; No - just issue message | ||
| 489 | lodsb ;AN057; Get the char after the switch | ||
| 490 | invoke itestkanj ;AN057; Is it DBCS? | ||
| 491 | jnz parse_line_error_disp ;AN057; Yes - can't be /C | ||
| 492 | invoke iupconv ;AN057; upper case it | ||
| 493 | cmp al,scswitch ;AN057; it is /C? | ||
| 494 | jnz parse_line_error_disp ;AN057; | ||
| 495 | pop dx ;AN057; even up stack | ||
| 496 | pop dx ;AN057; even up stack | ||
| 497 | jmp setSSwitch ;AN057; Yes - go set COMMAND /C | ||
| 498 | |||
| 499 | parse_line_error_disp: | ||
| 500 | pop ax ;AN057; restore error number | ||
| 501 | pop si ;AN057; restore line position | ||
| 502 | mov disp_class,parse_msg_class ;AN000; set up parse error msg class | ||
| 503 | mov dx,ax ;AN000; get message number | ||
| 504 | call print_message ;AN000; issue error message | ||
| 505 | jmp short parse_command_line ;AN000; continue parsing | ||
| 506 | |||
| 507 | parse_cont: | ||
| 508 | ; | ||
| 509 | ; See if a switch was entered | ||
| 510 | ; | ||
| 511 | |||
| 512 | cmp comnd1_syn,offset resgroup:command_f_syn ;AC000; was /F entered? | ||
| 513 | jz SetFSwitch ;AC000; yes go set fail switch | ||
| 514 | cmp comnd1_syn,offset resgroup:command_p_syn ;AC000; was /P entered? | ||
| 515 | Jz SetPSwitch ;AC000; yes go set up PERMCOM | ||
| 516 | cmp comnd1_syn,offset resgroup:command_d_syn ;AC000; was /D entered? | ||
| 517 | jz SetDSwitch ;AC000; yes go set date switch | ||
| 518 | cmp comnd1_syn,offset resgroup:command_c_syn ;AC000; was /C entered? | ||
| 519 | jz SetSSwitch ;AC000; yes go set up SINGLECOM | ||
| 520 | cmp comnd1_syn,offset resgroup:command_e_syn ;AC000; was /E entered? | ||
| 521 | jz SetESwitch ;AC000; yes go set up environment | ||
| 522 | cmp comnd1_syn,offset resgroup:command_m_syn ;AN000; was /MSG entered? | ||
| 523 | jz SetMSwitchjmp ;AN000; yes go set up message flag | ||
| 524 | jmp chkotherargs ;AC000; Must be something else | ||
| 525 | |||
| 526 | SetMSwitchjmp: ;AN018; long jump needed | ||
| 527 | jmp SetMswitch ;AN018; | ||
| 528 | |||
| 529 | ArgsdoneJ3: ;AN018; long jump needed | ||
| 530 | jmp ArgsDone ;AN018; | ||
| 531 | |||
| 532 | SetFSwitch: | ||
| 533 | cmp fFail,-1 ;AN018; has fail switch been set? | ||
| 534 | jnz failok ;AN018; no - set it | ||
| 535 | mov ax,moreargs_ptr ;AN018; set up too many arguments | ||
| 536 | jmp parse_line_error ;AN018; go issue error message | ||
| 537 | |||
| 538 | failok: | ||
| 539 | MOV fFail,-1 ;AC000; fail all INT 24s. | ||
| 540 | JMP parse_command_line ;AC000; | ||
| 541 | |||
| 542 | SetPSwitch: | ||
| 543 | ; | ||
| 544 | ; We have a permanent COMMAND switch /P. Flag this and stash the | ||
| 545 | ; termination address. | ||
| 546 | ; | ||
| 547 | cmp [permcom],0 ;AN018; has /p switch been set? | ||
| 548 | jz permcomok ;AN018; no - set it | ||
| 549 | mov ax,moreargs_ptr ;AN018; set up too many arguments | ||
| 550 | jmp parse_line_error ;AN018; go issue error message | ||
| 551 | |||
| 552 | permcomok: | ||
| 553 | INC [PERMCOM] | ||
| 554 | MOV WORD PTR [oldTerm],OFFSET RESGROUP:LODCOM | ||
| 555 | MOV WORD PTR [oldTerm+2],DS | ||
| 556 | ; | ||
| 557 | ; Make sure that we display the date and time. If the flag was not | ||
| 558 | ; initialized, set it to indicate yes, do prompt. | ||
| 559 | ; | ||
| 560 | CMP BYTE PTR [PRDATTM],-1 | ||
| 561 | JNZ parse_command_line_jmp ;AC018; keep parsing | ||
| 562 | MOV BYTE PTR [PRDATTM],0 ; If not set explicit, set to prompt | ||
| 563 | |||
| 564 | Parse_command_line_jmp: ;AN018; | ||
| 565 | JMP parse_command_line ;AC000; keep parsing | ||
| 566 | |||
| 567 | ArgsDoneJump: | ||
| 568 | JMP ArgsDone | ||
| 569 | |||
| 570 | SetDSwitch: | ||
| 571 | ; | ||
| 572 | ; Flag no date/time prompting. | ||
| 573 | ; | ||
| 574 | cmp dswitch,0 ;AN018; has /D switch been set? | ||
| 575 | jz setdateok ;AN018; no - set it | ||
| 576 | mov ax,moreargs_ptr ;AN018; set up too many arguments | ||
| 577 | jmp parse_line_error ;AN018; go issue error message | ||
| 578 | |||
| 579 | setdateok: | ||
| 580 | inc dswitch ;AN018; indicate /D entered | ||
| 581 | MOV BYTE PTR [PRDATTM],1 ; User explicitly says no date time | ||
| 582 | JMP parse_command_line ;AC000; continue parsing | ||
| 583 | |||
| 584 | SetSSwitch: | ||
| 585 | ; | ||
| 586 | ; Set up pointer to command line, flag no date/time and turn off singlecom. | ||
| 587 | ; | ||
| 588 | MOV [SINGLECOM],SI ; Point to the rest of the command line | ||
| 589 | MOV [PERMCOM],0 ; A SINGLECOM must not be a PERMCOM | ||
| 590 | MOV BYTE PTR [PRDATTM],1 ; No date or time either, explicit | ||
| 591 | JMP ArgsDone | ||
| 592 | ; | ||
| 593 | ; Look for environment-size setting switch | ||
| 594 | ; | ||
| 595 | ; The environment size is represented in decimal bytes and is | ||
| 596 | ; converted into pargraphs (rounded up to the next paragraph). | ||
| 597 | ; | ||
| 598 | |||
| 599 | SetESwitch: | ||
| 600 | cmp eswitch,0 ;AN018; has fail switch been set? | ||
| 601 | jz eswitchok ;AN018; no - set it | ||
| 602 | mov ax,moreargs_ptr ;AN018; set up too many arguments | ||
| 603 | jmp parse_line_error ;AN018; go issue error message | ||
| 604 | |||
| 605 | eswitchok: | ||
| 606 | inc eswitch ;AN018; indicate /E entered | ||
| 607 | mov di,offset resgroup:comnd1_addr ;AN000; get number returned | ||
| 608 | mov bx,word ptr [di] ;AN000; into bx | ||
| 609 | |||
| 610 | ADD BX, 0FH ; Round up to next paragraph | ||
| 611 | mov cl,4 ;AC000; convert to pargraphs | ||
| 612 | SHR BX, cl ;AC000; by right 4 | ||
| 613 | |||
| 614 | MOV EnvSiz,BX ; EnvSiz is in paragraphs | ||
| 615 | JMP parse_command_line ;AC000; continue parsing command line | ||
| 616 | |||
| 617 | SetMSwitch: | ||
| 618 | cmp ext_msg,set_extended_msg ;AN018; has /MSG switch been set? | ||
| 619 | jnz setMswitchok ;AN018; no - set it | ||
| 620 | mov ax,moreargs_ptr ;AN018; set up too many arguments | ||
| 621 | jmp parse_line_error ;AN018; go issue error message | ||
| 622 | setMswitchok: | ||
| 623 | MOV Ext_msg,set_extended_msg ;AN000; set /MSG switch | ||
| 624 | JMP parse_command_line ;AN000; keep parsing | ||
| 625 | |||
| 626 | ARGSDONEJ: | ||
| 627 | JMP ARGSDONE | ||
| 628 | |||
| 629 | ; | ||
| 630 | ; We have a non-switch character here. | ||
| 631 | ; | ||
| 632 | CHKOTHERARGS: | ||
| 633 | push ds ;AN054; | ||
| 634 | push si ;AC000; save place in command line | ||
| 635 | lds si,comnd1_addr ;AN000; get address of filespec | ||
| 636 | assume ds:nothing ;AN054; | ||
| 637 | |||
| 638 | mov dx,si ;AN000; put in dx also | ||
| 639 | MOV AX,(OPEN SHL 8) OR 2 ; Read and write | ||
| 640 | INT int_command | ||
| 641 | JC CHKSRCHSPEC ; Wasn't a file | ||
| 642 | MOV BX,AX | ||
| 643 | MOV AX,IOCTL SHL 8 | ||
| 644 | INT int_command | ||
| 645 | TEST DL,80H | ||
| 646 | JNZ ISADEVICE | ||
| 647 | |||
| 648 | BADSETCON: ;AN022; | ||
| 649 | MOV AH,CLOSE ; Close initial handle, wasn't a device | ||
| 650 | INT int_command | ||
| 651 | JMP CHKSRCHSPEC | ||
| 652 | |||
| 653 | ISADEVICE: | ||
| 654 | XOR DH,DH | ||
| 655 | OR DL,3 ; Make sure has CON attributes | ||
| 656 | MOV AX,(IOCTL SHL 8) OR 1 | ||
| 657 | INT int_command | ||
| 658 | JC BADSETCON ;AN022; Can't set attributes - quit | ||
| 659 | MOV DX,BX ; Save new handle | ||
| 660 | ;eg POP BX ; Throw away saved SI | ||
| 661 | ;eg POP BX ; Throw away saved CX | ||
| 662 | PUSH CX | ||
| 663 | MOV CX,3 | ||
| 664 | XOR BX,BX | ||
| 665 | |||
| 666 | RCCLLOOP: ; Close 0,1 and 2 | ||
| 667 | MOV AH,CLOSE | ||
| 668 | INT int_command | ||
| 669 | INC BX | ||
| 670 | LOOP RCCLLOOP | ||
| 671 | MOV BX,DX ; New device handle | ||
| 672 | MOV AH,XDUP | ||
| 673 | INT int_command ; Dup to 0 | ||
| 674 | MOV AH,XDUP | ||
| 675 | INT int_command ; Dup to 1 | ||
| 676 | MOV AH,XDUP | ||
| 677 | INT int_command ; Dup to 2 | ||
| 678 | MOV AH,CLOSE | ||
| 679 | INT int_command ; Close initial handle | ||
| 680 | POP CX | ||
| 681 | pop si ;AN000; restore position of command line | ||
| 682 | pop ds ;AN054; | ||
| 683 | JMP parse_command_line ;AC000; continue parsing | ||
| 684 | |||
| 685 | CHKSRCHSPEC: ; Not a device, so must be directory spec | ||
| 686 | |||
| 687 | MOV BYTE PTR [CHUCKENV],0 ; If search specified -- no inheritance | ||
| 688 | MOV AX,OFFSET RESGROUP:PATHSTRING ; Figure environment pointer | ||
| 689 | MOV CL,4 | ||
| 690 | SHR AX,CL | ||
| 691 | ;AD054; MOV DX,DS | ||
| 692 | MOV DX,CS ;AC054; | ||
| 693 | ADD AX,DX | ||
| 694 | MOV [ENVIRSEG],AX | ||
| 695 | |||
| 696 | MOV ES,AX | ||
| 697 | push si ;AN000; remember location of file | ||
| 698 | xor cx,cx ;AN000; clear cx for counting | ||
| 699 | |||
| 700 | countloop: | ||
| 701 | lodsb ;AN000; get a character | ||
| 702 | inc cx ;AN000; increment counter | ||
| 703 | cmp al,end_of_line_out ;AN000; are we at end of line? | ||
| 704 | jnz countloop ;AN000; no - keep counting | ||
| 705 | |||
| 706 | mov al,space | ||
| 707 | dec si ;AN000; move back one | ||
| 708 | MOV BYTE PTR [SI],al ;AN000; put a space at end of line | ||
| 709 | pop si ;AC000; get location back | ||
| 710 | |||
| 711 | MOV DI,[ECOMLOC] | ||
| 712 | |||
| 713 | COMTRLOOP: | ||
| 714 | LODSB | ||
| 715 | DEC CX | ||
| 716 | CMP AL,space | ||
| 717 | JZ SETCOMSR | ||
| 718 | STOSB | ||
| 719 | |||
| 720 | ;;; IF KANJI 3/3/KK | ||
| 721 | XOR AH,AH | ||
| 722 | ;;; ENDIF 3/3/KK | ||
| 723 | |||
| 724 | JCXZ SETCOMSR | ||
| 725 | |||
| 726 | ;;;; IF KANJI 3/3/KK | ||
| 727 | PUSH DS ;AN054; Make sure we have | ||
| 728 | PUSH CS ;AN054; local DS for | ||
| 729 | POP DS ;AN054; ITESTKANJ | ||
| 730 | INVOKE ITESTKANJ | ||
| 731 | POP DS ;AN054; restore PARSER DS | ||
| 732 | JZ COMTRLOOP | ||
| 733 | DEC CX | ||
| 734 | MOVSB | ||
| 735 | INC AH | ||
| 736 | JCXZ SETCOMSR | ||
| 737 | ;;;; ENDIF 3/3/KK | ||
| 738 | |||
| 739 | JMP SHORT COMTRLOOP | ||
| 740 | |||
| 741 | SETCOMSR: | ||
| 742 | PUSH CX | ||
| 743 | |||
| 744 | PUSH CS ;AN054; Get local segment | ||
| 745 | POP DS ;AN054; | ||
| 746 | assume ds:resgroup ;AN054; | ||
| 747 | |||
| 748 | PUSH DS | ||
| 749 | MOV SI,OFFSET RESGROUP:COMSPECT | ||
| 750 | MOV CX,14 | ||
| 751 | |||
| 752 | MOV AL,ES:[DI-1] | ||
| 753 | |||
| 754 | ;;;; IF KANJI 3/3/KK | ||
| 755 | OR AH,AH | ||
| 756 | JNZ INOTROOT ; Last char was KANJI second byte, might be '\' | ||
| 757 | ;;;; ENDIF 3/3/KK | ||
| 758 | |||
| 759 | CALL PATHCHRCMPR | ||
| 760 | JNZ INOTROOT | ||
| 761 | INC SI ; Don't make a double / | ||
| 762 | DEC CX | ||
| 763 | |||
| 764 | INOTROOT: | ||
| 765 | REP MOVSB | ||
| 766 | |||
| 767 | MOV DX,[ECOMLOC] ; Now lets make sure its good! | ||
| 768 | PUSH ES | ||
| 769 | POP DS | ||
| 770 | |||
| 771 | MOV AX,OPEN SHL 8 | ||
| 772 | INT int_command ; Open COMMAND.COM | ||
| 773 | POP DS | ||
| 774 | JC SETCOMSRBAD ; No COMMAND.COM here | ||
| 775 | MOV BX,AX ; Handle | ||
| 776 | MOV AH,CLOSE | ||
| 777 | INT int_command ; Close COMMAND.COM | ||
| 778 | |||
| 779 | SETCOMSRRET: | ||
| 780 | POP CX | ||
| 781 | POP SI | ||
| 782 | POP DS ;AN054; | ||
| 783 | assume ds:resgroup ;AN054; | ||
| 784 | |||
| 785 | ARGSDONEJ2: | ||
| 786 | PUSH CS ;AN000; Make sure local ES is | ||
| 787 | POP ES ;AN000; restored | ||
| 788 | JMP parse_command_line ;AC000; continue parsing command line | ||
| 789 | |||
| 790 | SETCOMSRBAD: | ||
| 791 | MOV DX,BADCOMLKMES_ptr ;AC000; get message number | ||
| 792 | invoke triageError | ||
| 793 | cmp ax, 65 | ||
| 794 | jnz doprt | ||
| 795 | mov dx,BADCOMACCMES_ptr ;AC000; get error message number | ||
| 796 | doprt: | ||
| 797 | call print_message | ||
| 798 | MOV SI,OFFSET RESGROUP:COMSPECT | ||
| 799 | MOV DI,[ECOMLOC] | ||
| 800 | MOV CX,14 | ||
| 801 | REP MOVSB ; Get my default back | ||
| 802 | |||
| 803 | JMP SHORT SETCOMSRRET | ||
| 804 | |||
| 805 | ;********************************* | ||
| 806 | ; PARSING ENDS HERE | ||
| 807 | ;********************************* | ||
| 808 | |||
| 809 | ARGSDONE: | ||
| 810 | mov es,[envirseg] ;AC000; get environment back | ||
| 811 | ASSUME ES:ENVIRONMENT ;AN000; | ||
| 812 | ;AD060; cmp ext_msg,set_extended_msg ;AN000; was /msg specified? | ||
| 813 | ;AD060; jnz check_permcom ;AN000; No, go check permcom | ||
| 814 | ;AD060; cmp [permcom],0 ;AN000; Yes - was permcom set? | ||
| 815 | ;AD060; jz permcom_error ;AN000; No - error cannot have /MSG without /P | ||
| 816 | |||
| 817 | ;AD060; mov ah,multdos ;AN000; set up to call DOS through int 2fh | ||
| 818 | ;AD060; mov al,message_2f ;AN000; call for message retriever | ||
| 819 | ;AD060; mov dl,set_extended_msg ;AN000; set up extended error message address | ||
| 820 | ;AD060; push es ;AN016; save environment segment | ||
| 821 | ;AD060; push cs ;AN016; get local segment to ES | ||
| 822 | ;AD060; pop es ;AN016; | ||
| 823 | ;AD060; mov di,offset resgroup:extended_msg_start ;AN000; start address | ||
| 824 | ;AD060; int 2fh ;AN000; | ||
| 825 | ;AD060; pop es ;AN016; restore environment segment | ||
| 826 | ;AD060; mov di,offset resgroup:extmsgend+15 ;AN000; get address of resident end | ||
| 827 | ;AD060; mov [resmsgend],di ;AN000; save it | ||
| 828 | ;AD060; call sysloadmsg ;AN000; load message addresses | ||
| 829 | ;AD060; jmp short process_permcom ;AN000; now go process /P switch | ||
| 830 | |||
| 831 | ;AD060;permcom_error: | ||
| 832 | ;AD060; mov disp_class,parse_msg_class ;AN000; set up parse error msg class | ||
| 833 | ;AD060; mov dx,LessArgs_Ptr ;AN000; get message number for "Required parameter missing" | ||
| 834 | ;AD060; call print_message ;AN000; issue error message | ||
| 835 | ;AD060; jmp short comreturns ;AN000; we already know /P wasn't entered | ||
| 836 | |||
| 837 | ;AD060;check_permcom: | ||
| 838 | CMP [PERMCOM],0 | ||
| 839 | JZ COMRETURNS | ||
| 840 | |||
| 841 | ;AD060;process_permcom: | ||
| 842 | PUSH ES ; Save environment pointer | ||
| 843 | MOV AH,SET_CURRENT_PDB | ||
| 844 | MOV BX,DS | ||
| 845 | MOV ES,BX | ||
| 846 | INT int_command ; Current process is me | ||
| 847 | MOV DI,PDB_Exit ; Diddle the addresses in my header | ||
| 848 | MOV AX,OFFSET RESGROUP:LODCOM | ||
| 849 | STOSW | ||
| 850 | MOV AX,DS | ||
| 851 | STOSW | ||
| 852 | MOV AX,OFFSET RESGROUP:CONTC | ||
| 853 | STOSW | ||
| 854 | MOV AX,DS | ||
| 855 | STOSW | ||
| 856 | MOV AX,OFFSET RESGROUP:DskErr | ||
| 857 | STOSW | ||
| 858 | MOV AX,DS | ||
| 859 | STOSW | ||
| 860 | MOV WORD PTR DS:[PDB_Parent_PID],DS ; Parent is me forever | ||
| 861 | |||
| 862 | MOV DX,OFFSET RESGROUP:INT_2E | ||
| 863 | MOV AX,(SET_INTERRUPT_VECTOR SHL 8) OR 02EH | ||
| 864 | INT int_command ;Set magic interrupt | ||
| 865 | POP ES ;Remember environment | ||
| 866 | |||
| 867 | COMRETURNS: | ||
| 868 | MOV AX,WORD PTR DS:[PDB_Parent_PID] | ||
| 869 | MOV [PARENT],AX ; Save parent | ||
| 870 | MOV WORD PTR DS:[PDB_Parent_PID],DS ; Parent is me | ||
| 871 | MOV AX,WORD PTR DS:[PDB_JFN_Table] | ||
| 872 | MOV [IO_SAVE],AX ; Get the default stdin and out | ||
| 873 | MOV WORD PTR [COM_PTR+2],DS ; Set all these to resident | ||
| 874 | MOV WORD PTR [COM_FCB1+2],DS | ||
| 875 | MOV WORD PTR [COM_FCB2+2],DS | ||
| 876 | MOV DI,OFFSET RESGROUP:COMSPEC | ||
| 877 | |||
| 878 | MOV SI,[ECOMLOC] | ||
| 879 | CMP BYTE PTR [CHUCKENV],0 | ||
| 880 | |||
| 881 | MOV AX,DS ; XCHG ES,DS | ||
| 882 | PUSH ES | ||
| 883 | POP DS | ||
| 884 | MOV ES,AX | ||
| 885 | |||
| 886 | JZ COPYCOMSP ; All set up for copy | ||
| 887 | |||
| 888 | PUSH CS | ||
| 889 | POP DS | ||
| 890 | |||
| 891 | MOV SI,OFFSET RESGROUP:COMSPSTRING | ||
| 892 | PUSH ES | ||
| 893 | PUSH DI | ||
| 894 | CALL IFINDE | ||
| 895 | MOV SI,DI | ||
| 896 | PUSH ES | ||
| 897 | POP DS | ||
| 898 | POP DI | ||
| 899 | POP ES | ||
| 900 | JNC COPYCOMSP | ||
| 901 | |||
| 902 | COMSPECNOFND: | ||
| 903 | MOV SI,CS:[ECOMLOC] ;AC062 | ||
| 904 | ADD SI,OFFSET RESGROUP:PATHSTRING | ||
| 905 | PUSH CS | ||
| 906 | POP DS | ||
| 907 | |||
| 908 | assume es:resgroup | ||
| 909 | COPYCOMSP: | ||
| 910 | mov es:comspec_print,di ; Save ptr to beginning of comspec path | ||
| 911 | cmp byte ptr [si+1],':' ; Is there a drive specifier in comspec | ||
| 912 | jnz COPYCOMSPLOOP ; If not, do not skip over first 2 bytes | ||
| 913 | add es:comspec_print,2 | ||
| 914 | |||
| 915 | COPYCOMSPLOOP: | ||
| 916 | LODSB | ||
| 917 | STOSB | ||
| 918 | OR AL,AL | ||
| 919 | JNZ COPYCOMSPLOOP | ||
| 920 | mov es:comspec_end,di ; Save ptr to end of comspec path | ||
| 921 | dec es:comspec_end | ||
| 922 | mov ah,es:comdrv | ||
| 923 | add ah,'A'-1 | ||
| 924 | mov es:cpdrv,ah ; Load drive letter in comprmt2 | ||
| 925 | assume es:environment | ||
| 926 | |||
| 927 | call setup_for_messages ;AN060; set up parse and extended error messages | ||
| 928 | PUSH CS | ||
| 929 | POP DS | ||
| 930 | MOV BX,[RESMSGEND] ;AC000; get end of resident | ||
| 931 | MOV CL,4 | ||
| 932 | SHR BX,CL | ||
| 933 | Public EnvMaximum | ||
| 934 | EnvMaximum: | ||
| 935 | ; | ||
| 936 | ; NOTE: The transient has to loaded directly after shrinking to the | ||
| 937 | ; resident size. | ||
| 938 | ; There is an assumption made when loading the transient that it | ||
| 939 | ; still intact after the resident portion. | ||
| 940 | ; If any other ALLOC/DEALLOC/SETBLOCK operations are performed | ||
| 941 | ; inbetween, then there is a real good chance that the non-resident | ||
| 942 | ; portion will be overwritten by arena information. | ||
| 943 | ; | ||
| 944 | MOV AH,SETBLOCK | ||
| 945 | INT int_command ; Shrink me to the resident only | ||
| 946 | ; | ||
| 947 | ; Load in the transient and compute the checksum. We may do this in one of | ||
| 948 | ; two ways: First, cheat and use the transient loading code that exists in | ||
| 949 | ; the resident piece. This may be OK except that it will hit the disk. | ||
| 950 | ; | ||
| 951 | ; But we do not need to hit the disk! The transient is already loaded but is | ||
| 952 | ; in the wrong place. We need to block transfer it up to the correct spot. | ||
| 953 | ; | ||
| 954 | GOTENVIR: | ||
| 955 | MOV TrnMvFlg, 1 ; Indicate that transient has been moved | ||
| 956 | PUSH ES | ||
| 957 | MOV SI,OFFSET RESGroup:TranStart | ||
| 958 | MOV DI,0 | ||
| 959 | mov ES,Trnseg | ||
| 960 | MOV CX,OFFSET TRANGROUP:TRANSPACEEND | ||
| 961 | ; | ||
| 962 | ; We need to ensure that we do not have the potential of overwriting our | ||
| 963 | ; existing code in this move | ||
| 964 | ; It is OK to move if (SI+CX+Segment of Transient < TrnSeg). | ||
| 965 | ; | ||
| 966 | push cx | ||
| 967 | mov ax,cx ; Get size of transient in bytes | ||
| 968 | add ax,si ; Calculate end of transient section | ||
| 969 | mov cl,4 | ||
| 970 | shr ax,cl ; Convert to paragraphs | ||
| 971 | inc ax ; Round up (for partial paragraph) | ||
| 972 | mov cx,ds | ||
| 973 | add ax,cx ; Add in current segment | ||
| 974 | cmp ax,Trnseg ; See if there is overlap | ||
| 975 | pop cx | ||
| 976 | ; If we are too close to be safe, call LOADCOM instead of moving the code. | ||
| 977 | jb Ok_To_Move | ||
| 978 | invoke LOADCOM | ||
| 979 | jmp short Trans_Loaded | ||
| 980 | Ok_To_Move: | ||
| 981 | ; | ||
| 982 | ; Everything is set for an upward move. WRONG! We must move downward. | ||
| 983 | ; | ||
| 984 | ADD SI,CX | ||
| 985 | DEC SI | ||
| 986 | ADD DI,CX | ||
| 987 | DEC DI | ||
| 988 | STD | ||
| 989 | REP MOVSB | ||
| 990 | CLD | ||
| 991 | |||
| 992 | Trans_Loaded: | ||
| 993 | POP ES | ||
| 994 | |||
| 995 | INVOKE CHKSUM ; Compute the checksum | ||
| 996 | MOV [SUM],DX ; Save it | ||
| 997 | |||
| 998 | CMP BYTE PTR [PRDATTM],0 ;eg | ||
| 999 | JNZ NOBATCHSEG ;eg Don't do AUTOEXEC or date time | ||
| 1000 | ; | ||
| 1001 | ; Allocate batch segment for D:/autoexec.bat + no arguments | ||
| 1002 | ; | ||
| 1003 | MOV BX,((SIZE BatchSegment) + 15 + 1 + 0Fh)/16 ;eg | ||
| 1004 | MOV AH,ALLOC ;eg | ||
| 1005 | INT int_command ;eg | ||
| 1006 | JC NOBATCHSEG ;eg didn't allocate - pretend no batch | ||
| 1007 | MOV BATCH,AX ;eg save batch segment | ||
| 1008 | |||
| 1009 | NOBATCHSEG: | ||
| 1010 | MOV BX, 0FFFFH ; Get size of largest block for env | ||
| 1011 | MOV AH, ALLOC | ||
| 1012 | INT int_command | ||
| 1013 | |||
| 1014 | ; Only allocate maximum 64K worth of environment | ||
| 1015 | |||
| 1016 | SUB BX,TRNSIZE ;eg subtract # of transient paragraphs | ||
| 1017 | SUB BX,128 ;eg make sure we have 2K left | ||
| 1018 | MOV EnvMax, BX | ||
| 1019 | CMP BX, 4096 ; 64K = 4096 paragraphs | ||
| 1020 | JB MAXOK | ||
| 1021 | MOV BX, 4096-1 | ||
| 1022 | MOV EnvMax, BX | ||
| 1023 | MAXOK: | ||
| 1024 | |||
| 1025 | MOV AH, ALLOC ; Get max size | ||
| 1026 | INT int_command | ||
| 1027 | |||
| 1028 | mov bx,[envirseg] ;g get old environment segment | ||
| 1029 | mov oldenv,bx ;g save it | ||
| 1030 | mov usedenv,0 ;g initialize env size counter | ||
| 1031 | MOV DS,bx | ||
| 1032 | ASSUME DS:NOTHING | ||
| 1033 | MOV [ENVIRSEG],AX | ||
| 1034 | MOV ES,AX | ||
| 1035 | XOR SI,SI | ||
| 1036 | MOV DI,SI | ||
| 1037 | MOV BX,EnvMax ; Copy over as much of the environment | ||
| 1038 | ; as possible | ||
| 1039 | SHL BX,1 | ||
| 1040 | SHL BX,1 | ||
| 1041 | SHL BX,1 | ||
| 1042 | SHL BX,1 | ||
| 1043 | MOV EnvMax, BX ; Convert EnvMax to bytes | ||
| 1044 | DEC BX ; Dec by one to leave room for double 0 | ||
| 1045 | XOR DX,DX ; Use DX to indicate that there was | ||
| 1046 | ; no environment size error. | ||
| 1047 | Public Nxtstr | ||
| 1048 | Nxtstr: | ||
| 1049 | CALL GetStrLen ; Get the size of the current env string | ||
| 1050 | push ds ;g get addressability to environment | ||
| 1051 | push cs ;g counter | ||
| 1052 | pop ds ;g | ||
| 1053 | ASSUME DS:RESGROUP | ||
| 1054 | add usedenv,cx ;g add the string length to env size | ||
| 1055 | pop ds ;g | ||
| 1056 | ASSUME DS:NOTHING | ||
| 1057 | CMP CX,1 ; End of environment was encountered. | ||
| 1058 | JZ EnvExit | ||
| 1059 | SUB BX,CX | ||
| 1060 | JAE OKCpyStr ; Can't fit in all of enviroment. | ||
| 1061 | INC DX ; Out of env space msg must be displayed | ||
| 1062 | JMP EnvExit | ||
| 1063 | OKCpyStr: | ||
| 1064 | JMP Nxtstr | ||
| 1065 | EnvExit: | ||
| 1066 | |||
| 1067 | PUSH CS | ||
| 1068 | POP DS | ||
| 1069 | ASSUME DS:RESGroup | ||
| 1070 | OR DX,DX ; DX will be non-zero if error | ||
| 1071 | JZ EnvNoErr | ||
| 1072 | MOV DX,OUTENVERR_ptr ;AC000; get message number | ||
| 1073 | call print_message | ||
| 1074 | |||
| 1075 | EnvNoErr: | ||
| 1076 | ; BX now has the left over size of the maximum environment | ||
| 1077 | ; We want to shrink the environment down to the minimum size | ||
| 1078 | ; Set the environment size to max(Envsiz,Env used) | ||
| 1079 | |||
| 1080 | MOV CX, EnvMax | ||
| 1081 | SUB CX, BX ; CX now has the environment used | ||
| 1082 | ADD CX, 16 ; Round up to next paragraph | ||
| 1083 | SHR CX, 1 | ||
| 1084 | SHR CX, 1 | ||
| 1085 | SHR CX, 1 | ||
| 1086 | SHR CX, 1 | ||
| 1087 | CMP CX, Envsiz ; Is environment used > Envsiz | ||
| 1088 | JB EnvSet | ||
| 1089 | MOV Envsiz, CX | ||
| 1090 | EnvSet: | ||
| 1091 | MOV BX, Envsiz ; Set environment to size needed | ||
| 1092 | mov ax,es ;eg get environment segment | ||
| 1093 | add ax,bx ;eg add number of environment paragraphs | ||
| 1094 | cmp ax,initend ;eg does this go past end of init? | ||
| 1095 | ja envsetok ;eg yes - do the setblock | ||
| 1096 | mov ax,es ;eg no - get back the environment segment | ||
| 1097 | mov bx,initend ;eg get the segment at end of init | ||
| 1098 | sub bx,ax ;eg setblock envir segment to end of init code | ||
| 1099 | mov resetenv,1 ;eg set flag so we know to set envir later | ||
| 1100 | |||
| 1101 | envsetok: | ||
| 1102 | MOV AH, SETBLOCK | ||
| 1103 | INT int_command | ||
| 1104 | |||
| 1105 | IF MSVER | ||
| 1106 | CMP [SINGLECOM],0 | ||
| 1107 | JNZ NOPHEAD ; Don't print header if SINGLECOM | ||
| 1108 | MOV DX,HEADER_ptr ;AC000; get message number | ||
| 1109 | call print_message | ||
| 1110 | NOPHEAD: | ||
| 1111 | ENDIF | ||
| 1112 | |||
| 1113 | CMP [BATCH],0 ;eg did we set up a batch segment? | ||
| 1114 | JNZ dodate ;eg yes - go initialize it | ||
| 1115 | JMP NODTTM ; Don't do AUTOEXEC or date time | ||
| 1116 | ; | ||
| 1117 | ; Allocate batch segment for D:/autoexec.bat + no arguments | ||
| 1118 | ; | ||
| 1119 | dodate: | ||
| 1120 | MOV AX,BATCH ;eg get batch segment | ||
| 1121 | MOV EchoFlag,3 ; set batch echo | ||
| 1122 | MOV NEST,1 ; g set nest flag to 1 batch | ||
| 1123 | MOV ES,AX | ||
| 1124 | ; | ||
| 1125 | ; Initialize the segment | ||
| 1126 | ; | ||
| 1127 | XOR DI,DI | ||
| 1128 | MOV AL,BatchType | ||
| 1129 | STOSB | ||
| 1130 | MOV AL,1 ; G initialize echo for batch exit | ||
| 1131 | STOSB ; G | ||
| 1132 | XOR AX,AX ; initialize to zero | ||
| 1133 | STOSW ; G batch segment of last job - batlast | ||
| 1134 | STOSW ; G segment for FOR | ||
| 1135 | STOSB ; G FOR flag | ||
| 1136 | STOSW ; position in file - batseek | ||
| 1137 | STOSW | ||
| 1138 | ; | ||
| 1139 | ; Clean out the parameters | ||
| 1140 | ; | ||
| 1141 | MOV AX,-1 ; initialize to no parameters | ||
| 1142 | MOV CX,10 | ||
| 1143 | REP STOSW | ||
| 1144 | ; | ||
| 1145 | ; Decide whether we should grab the default drive | ||
| 1146 | ; | ||
| 1147 | CMP BYTE PTR [AUTOBAT],0 | ||
| 1148 | |||
| 1149 | JNZ NOAUTSET | ||
| 1150 | MOV AH,GET_DEFAULT_DRIVE | ||
| 1151 | INT int_command | ||
| 1152 | ADD AL,ucasea | ||
| 1153 | |||
| 1154 | MOV [AUTOBAT],AL | ||
| 1155 | MOV [KAUTOBAT],AL ;AN000; 3/3/KK | ||
| 1156 | |||
| 1157 | NOAUTSET: | ||
| 1158 | ; | ||
| 1159 | ; Copy in the batch file name (including NUL) | ||
| 1160 | ; | ||
| 1161 | MOV SI,OFFSET RESGROUP:AUTOBAT | ||
| 1162 | MOV CX,8 | ||
| 1163 | REP MOVSW | ||
| 1164 | MOVSB ;AN027; move in carraige return to terminate string | ||
| 1165 | |||
| 1166 | MOV DX,OFFSET RESGROUP:AUTOBAT | ||
| 1167 | MOV AX,OPEN SHL 8 | ||
| 1168 | INT int_command ; See if AUTOEXEC.BAT exists | ||
| 1169 | JC NOABAT | ||
| 1170 | MOV BX,AX | ||
| 1171 | MOV AH,CLOSE | ||
| 1172 | INT int_command | ||
| 1173 | JMP DRV0 ;AC000; go process autoexec | ||
| 1174 | |||
| 1175 | NOABAT: | ||
| 1176 | push ax | ||
| 1177 | call setup_seg | ||
| 1178 | mov word ptr [triage_add+2],ax | ||
| 1179 | pop ax | ||
| 1180 | call triage_add | ||
| 1181 | cmp ax, 65 | ||
| 1182 | jz AccDenErr ;AN000; was network access denied | ||
| 1183 | |||
| 1184 | |||
| 1185 | ; If AUTOEXEC.BAT is not found, then check for KAUTOEXE.BAT. Changed | ||
| 1186 | ; by Ellen to check only when in Korea. The country information | ||
| 1187 | ; returned will overlay the old parse data area, but we don't care | ||
| 1188 | ; since we won't need the parse information or country information. | ||
| 1189 | ; We only care about the country code returned in BX. | ||
| 1190 | |||
| 1191 | MOV DX,OFFSET RESGROUP:INTERNAT_INFO ;AN000; Set up internat vars | ||
| 1192 | MOV AX,INTERNATIONAL SHL 8 ;AN000; get country dependent info | ||
| 1193 | INT 21H ;AN000; | ||
| 1194 | JC NOKABAT ;AN000; Error - don't bother with it | ||
| 1195 | CMP BX,KOREA_COUNTRY_CODE ;AN000; Are we speaking Korean? | ||
| 1196 | JNZ OPENERR ;AN000; No, don't check for KAUTOEXE | ||
| 1197 | |||
| 1198 | MOV DI, OFFSET BatFile ;AN000; 3/3/KK | ||
| 1199 | MOV SI,OFFSET RESGROUP:KAUTOBAT ;AN000; Another trial to do 3/3/KK | ||
| 1200 | MOV CX,8 ;AN000; auto execution for the 3/3/KK | ||
| 1201 | REP MOVSW ;AN000; non-English country 3/3/KK | ||
| 1202 | MOVSB ;AN027; move in carraige return to terminate string | ||
| 1203 | MOV DX,OFFSET RESGROUP:KAUTOBAT ;AN000; 3/3/KK | ||
| 1204 | MOV AX,OPEN SHL 8 ;AN000; 3/3/KK | ||
| 1205 | INT int_command ;AN000; See if KAUTOEXE.BAT exists 3/3/KK | ||
| 1206 | JC NOKABAT ;AN000; 3/3/KK | ||
| 1207 | MOV BX,AX ;AN000; 3/3/KK | ||
| 1208 | MOV AH,CLOSE ;AN000; 3/3/KK | ||
| 1209 | INT int_command ;AN000; 3/3/KK | ||
| 1210 | JMP SHORT DRV0 ;AN000; 3/3/KK | ||
| 1211 | |||
| 1212 | NOKABAT: ;AN000; 3/3/KK | ||
| 1213 | call triage_add ;AN000; get extended error | ||
| 1214 | cmp ax, 65 ;AN000; network access denied? | ||
| 1215 | jnz openerr ;AN000; no - go deallocate batch | ||
| 1216 | |||
| 1217 | AccDenErr: ;AN000; yes - put out message | ||
| 1218 | mov DX,ACCDEN ;AC000; get message number | ||
| 1219 | call print_message | ||
| 1220 | |||
| 1221 | openerr: | ||
| 1222 | MOV ES,[BATCH] ; Not found--turn off batch job | ||
| 1223 | MOV AH,DEALLOC | ||
| 1224 | INT int_command | ||
| 1225 | MOV [BATCH],0 ; AFTER DEALLOC in case of ^C | ||
| 1226 | MOV EchoFlag,1 | ||
| 1227 | mov nest,0 ;g indicate no batch in progress | ||
| 1228 | |||
| 1229 | DODTTM: | ||
| 1230 | MOV AX,OFFSET TRANGROUP:DATINIT | ||
| 1231 | MOV WORD PTR[INITADD],AX | ||
| 1232 | MOV AX,[TRNSEG] | ||
| 1233 | MOV WORD PTR[INITADD+2],AX | ||
| 1234 | CALL DWORD PTR [INITADD] | ||
| 1235 | |||
| 1236 | NODTTM: | ||
| 1237 | |||
| 1238 | IF IBMVER | ||
| 1239 | CMP [SINGLECOM],0 | ||
| 1240 | JNZ DRV0 ; Don't print header if SINGLECOM | ||
| 1241 | MOV DX,HEADER_ptr ;AC000; get message number | ||
| 1242 | call print_message | ||
| 1243 | ENDIF | ||
| 1244 | |||
| 1245 | DRV0: ; Reset APPEND state | ||
| 1246 | push ds ;AN042; save data segment | ||
| 1247 | push cs ;AN042; Get local segment into DS | ||
| 1248 | pop ds ;AN042; | ||
| 1249 | mov ax,AppendSetState ;AN042; Set the state of Append | ||
| 1250 | mov bx,Append_state ;AN042; back to the original state | ||
| 1251 | int 2fh ;AN042; | ||
| 1252 | pop ds ;AN042; get data segment back | ||
| 1253 | JMP ENDINIT ;G Finish initializing | ||
| 1254 | |||
| 1255 | ; | ||
| 1256 | ; Get length of string pointed to by DS:SI. Length includes NULL. | ||
| 1257 | ; Length is returned in CX | ||
| 1258 | ; | ||
| 1259 | GetStrLen: | ||
| 1260 | xor cx,cx | ||
| 1261 | NxtChar: | ||
| 1262 | lodsb | ||
| 1263 | inc cx | ||
| 1264 | or al,al | ||
| 1265 | jnz NxtChar | ||
| 1266 | ret | ||
| 1267 | ; | ||
| 1268 | ; If the transient has been loaded in TranSeg, then we need to use that | ||
| 1269 | ; segment for calls to routines in the transient area. Otherwise, the current | ||
| 1270 | ; code segment is used | ||
| 1271 | ; Segment returned in AX. | ||
| 1272 | ; | ||
| 1273 | setup_seg: | ||
| 1274 | mov ax,[trnseg] | ||
| 1275 | cmp TrnMvFlg, 1 ; Has transient portion been moved | ||
| 1276 | jz setup_end | ||
| 1277 | push bx | ||
| 1278 | mov bx,cs | ||
| 1279 | mov ax,OFFSET RESGroup:TranStart | ||
| 1280 | shr ax,1 | ||
| 1281 | shr ax,1 | ||
| 1282 | shr ax,1 | ||
| 1283 | shr ax,1 | ||
| 1284 | add ax,bx | ||
| 1285 | pop bx | ||
| 1286 | setup_end: | ||
| 1287 | ret | ||
| 1288 | |||
| 1289 | print_message: | ||
| 1290 | push ax | ||
| 1291 | PUSH DS ;AN000; save data and extra segment | ||
| 1292 | PUSH ES ;AN000; registers | ||
| 1293 | MOV AX,CS ;AN000; get local segment | ||
| 1294 | MOV ES,AX ;AN000; set ES and DS to point to it | ||
| 1295 | MOV DS,AX ;AN000; | ||
| 1296 | ;AD054; PUSH BX ;AC000; save BX register | ||
| 1297 | ;AD054; PUSH CX ;AC000; save CX register | ||
| 1298 | ;AD054; PUSH DX ;AC000; save DX register | ||
| 1299 | ;AD054; MOV AX,DX ;AC000; get message number | ||
| 1300 | ;AD054; MOV DH,DISP_CLASS ;AC000; get display class | ||
| 1301 | ;AD054; MOV DL,NO_CONT_FLAG ;AN000; set control flags off | ||
| 1302 | ;AD054; MOV BX,NO_HANDLE_OUT ;AC000; set message handler to use function 1-12 | ||
| 1303 | ;AD054; XOR CH,CH ;AC000; clear upper part of cx | ||
| 1304 | ;AD054; MOV CL,NUMBER_SUBST ;AC000; set number of substitutions | ||
| 1305 | ;AD054; invoke SYSDISPMSG ;AC000; display the message | ||
| 1306 | ;AD054; MOV DISP_CLASS,UTIL_MSG_CLASS ;AC000; reset display class | ||
| 1307 | ;AD054; MOV NUMBER_SUBST,NO_SUBST ;AC000; reset number of substitutions | ||
| 1308 | ;AD054; POP DX ;AC000; restore registers | ||
| 1309 | ;AD054; POP CX ;AC000; | ||
| 1310 | ;AD054; POP BX ;AC000; | ||
| 1311 | invoke rprint ;AC054; | ||
| 1312 | |||
| 1313 | POP ES ;AN000; | ||
| 1314 | POP DS ;AN000; | ||
| 1315 | pop ax | ||
| 1316 | ret | ||
| 1317 | |||
| 1318 | PATHCHRCMPR: | ||
| 1319 | push dx | ||
| 1320 | mov dl,fslash | ||
| 1321 | CMP [RSWITCHAR],dl | ||
| 1322 | JZ RNOSLASHT | ||
| 1323 | CMP AL,dl | ||
| 1324 | JZ RET41 | ||
| 1325 | RNOSLASHT: | ||
| 1326 | CMP AL,bslash | ||
| 1327 | RET41: | ||
| 1328 | pop dx | ||
| 1329 | RET | ||
| 1330 | |||
| 1331 | |||
| 1332 | IFINDE: | ||
| 1333 | CALL IFIND ; FIND THE NAME | ||
| 1334 | JC IFIND2 ; CARRY MEANS NOT FOUND | ||
| 1335 | JMP ISCASB1 ; SCAN FOR = SIGN | ||
| 1336 | ; | ||
| 1337 | ; On return of FIND1, ES:DI points to beginning of name | ||
| 1338 | ; | ||
| 1339 | IFIND: | ||
| 1340 | CLD | ||
| 1341 | CALL ICOUNT0 ; CX = LENGTH OF NAME | ||
| 1342 | MOV ES,[ENVIRSEG] | ||
| 1343 | XOR DI,DI | ||
| 1344 | |||
| 1345 | IFIND1: | ||
| 1346 | PUSH CX | ||
| 1347 | PUSH SI | ||
| 1348 | PUSH DI | ||
| 1349 | |||
| 1350 | IFIND11: | ||
| 1351 | LODSB | ||
| 1352 | |||
| 1353 | ;;;; IF KANJI 3/3/KK | ||
| 1354 | INVOKE ITESTKANJ | ||
| 1355 | JZ NOTKANJ4 | ||
| 1356 | DEC SI | ||
| 1357 | LODSW | ||
| 1358 | INC DI | ||
| 1359 | INC DI | ||
| 1360 | CMP AX,ES:[DI-2] | ||
| 1361 | JNZ IFIND12 | ||
| 1362 | DEC CX | ||
| 1363 | LOOP IFIND11 | ||
| 1364 | JMP SHORT IFIND12 | ||
| 1365 | |||
| 1366 | NOTKANJ4: | ||
| 1367 | ;;;; ENDIF 3/3/KK | ||
| 1368 | |||
| 1369 | CALL IUPCONV | ||
| 1370 | INC DI | ||
| 1371 | CMP AL,ES:[DI-1] | ||
| 1372 | JNZ IFIND12 | ||
| 1373 | LOOP IFIND11 | ||
| 1374 | |||
| 1375 | IFIND12: | ||
| 1376 | POP DI | ||
| 1377 | POP SI | ||
| 1378 | POP CX | ||
| 1379 | JZ IFIND2 | ||
| 1380 | PUSH CX | ||
| 1381 | CALL ISCASB2 ; SCAN FOR A NUL | ||
| 1382 | POP CX | ||
| 1383 | CMP BYTE PTR ES:[DI],0 | ||
| 1384 | JNZ IFIND1 | ||
| 1385 | STC ; INDICATE NOT FOUND | ||
| 1386 | |||
| 1387 | IFIND2: | ||
| 1388 | RET | ||
| 1389 | |||
| 1390 | ICOUNT0: | ||
| 1391 | PUSH DS | ||
| 1392 | POP ES | ||
| 1393 | MOV DI,SI | ||
| 1394 | |||
| 1395 | PUSH DI ; COUNT NUMBER OF CHARS UNTIL "=" | ||
| 1396 | CALL ISCASB1 | ||
| 1397 | JMP SHORT ICOUNTX | ||
| 1398 | PUSH DI ; COUNT NUMBER OF CHARS UNTIL NUL | ||
| 1399 | CALL ISCASB2 | ||
| 1400 | |||
| 1401 | ICOUNTX: | ||
| 1402 | POP CX | ||
| 1403 | SUB DI,CX | ||
| 1404 | XCHG DI,CX | ||
| 1405 | RET | ||
| 1406 | |||
| 1407 | ISCASB1: | ||
| 1408 | MOV AL,equalsign ; SCAN FOR AN = | ||
| 1409 | JMP SHORT ISCASBX | ||
| 1410 | |||
| 1411 | ISCASB2: | ||
| 1412 | XOR AL,AL ; SCAN FOR A NUL | ||
| 1413 | |||
| 1414 | ISCASBX: | ||
| 1415 | MOV CX,100H | ||
| 1416 | REPNZ SCASB | ||
| 1417 | RET | ||
| 1418 | |||
| 1419 | |||
| 1420 | ; **************************************************************** | ||
| 1421 | ; * | ||
| 1422 | ; * ROUTINE: IUPCONV (ADDED BY EMG 4.00) | ||
| 1423 | ; * | ||
| 1424 | ; * FUNCTION: This routine returns the upper case equivalent of | ||
| 1425 | ; * the character in AL from the file upper case table | ||
| 1426 | ; * in DOS if character if above ascii 128, else | ||
| 1427 | ; * subtracts 20H if between "a" and "z". | ||
| 1428 | ; * | ||
| 1429 | ; * INPUT: DS set to resident | ||
| 1430 | ; * AL char to be upper cased | ||
| 1431 | ; * FUCASE_ADDR set to the file upper case table | ||
| 1432 | ; * | ||
| 1433 | ; * OUTPUT: AL upper cased character | ||
| 1434 | ; * | ||
| 1435 | ; **************************************************************** | ||
| 1436 | |||
| 1437 | assume ds:resgroup ;AN000; | ||
| 1438 | |||
| 1439 | iupconv proc near ;AN000; | ||
| 1440 | |||
| 1441 | cmp al,80h ;AN000; see if char is > ascii 128 | ||
| 1442 | jb other_fucase ;AN000; no - upper case math | ||
| 1443 | sub al,80h ;AN000; only upper 128 chars in table | ||
| 1444 | push ds ;AN000; | ||
| 1445 | push bx ;AN000; | ||
| 1446 | lds bx,dword ptr fucase_addr+1 ;AN000; get table address | ||
| 1447 | add bx,2 ;AN000; skip over first word | ||
| 1448 | xlat ds:byte ptr [bx] ;AN000; convert to upper case | ||
| 1449 | pop bx ;AN000; | ||
| 1450 | pop ds ;AN000; | ||
| 1451 | jmp short iupconv_end ;AN000; we finished - exit | ||
| 1452 | |||
| 1453 | other_fucase: ;AN000; | ||
| 1454 | cmp al,lcasea ;AC000; if between "a" and "z", | ||
| 1455 | jb iupconv_end ;AC000; subtract 20h to get | ||
| 1456 | cmp al,lcasez ;AC000; upper case equivalent. | ||
| 1457 | ja iupconv_end ;AC000; | ||
| 1458 | sub al,20h ;AC000; Change lower-case to upper | ||
| 1459 | |||
| 1460 | iupconv_end: ;AN000; | ||
| 1461 | ret | ||
| 1462 | |||
| 1463 | iupconv endp ;AN000; | ||
| 1464 | |||
| 1465 | init_contc_specialcase: | ||
| 1466 | ; This routine is called if control-C | ||
| 1467 | add sp,6 ; is type during the date/time prompt | ||
| 1468 | push si ; at initialization time. The desired | ||
| 1469 | mov si,dx ; response is to make it look like the | ||
| 1470 | mov word ptr [si+1],0d00h ; user typed <CR> by "popping" the | ||
| 1471 | pop si ; INT 21h stuff off the stack, putting | ||
| 1472 | iret ; a <CR> in the user's buffer, and | ||
| 1473 | ; returning directly to the user. | ||
| 1474 | ; In this case the user is TCODE. | ||
| 1475 | |||
| 1476 | ; **************************************************************** | ||
| 1477 | ; * | ||
| 1478 | ; * ROUTINE: GET_MSG_PTR | ||
| 1479 | ; * | ||
| 1480 | ; * FUNCTION: Fill in translatable char table starting at | ||
| 1481 | ; * at Abort_char with translated characters. | ||
| 1482 | ; Set segments of resident messages. | ||
| 1483 | ; * | ||
| 1484 | ; * INPUT: none | ||
| 1485 | ; * | ||
| 1486 | ; * OUTPUT: none | ||
| 1487 | ; * | ||
| 1488 | ; **************************************************************** | ||
| 1489 | |||
| 1490 | CHAR_START EQU 201 ;AN000; first character translate is 1 | ||
| 1491 | CHAR_END EQU 207 ;AN000; last is 6 | ||
| 1492 | |||
| 1493 | GET_MSG_PTR PROC NEAR ;AN000; | ||
| 1494 | |||
| 1495 | MOV AX,CHAR_START ;AN000; get first char translation | ||
| 1496 | MOV BX,OFFSET RESGROUP:ABORT_CHAR ;AN000; get first char offset | ||
| 1497 | MOVEMES: ;AN000; | ||
| 1498 | MOV DH,-1 ;AN000; utility message | ||
| 1499 | INVOKE SYSGETMSG ;AN000; get the offset of the char | ||
| 1500 | MOV CL,BYTE PTR [SI] ;AN000; get the character in CL | ||
| 1501 | MOV BYTE PTR [BX],CL ;AN000; put the character in the table | ||
| 1502 | INC BX ;AN000; point to next position in table | ||
| 1503 | INC AX ;AN000; increment message number | ||
| 1504 | CMP AX,CHAR_END ;AN000; are we at the end? | ||
| 1505 | JNZ MOVEMES ;AN000; no - keep loading | ||
| 1506 | |||
| 1507 | MOV AX,DS ;AN000; get data segment | ||
| 1508 | MOV DRVNUM_OP_SEG,AX ;AN000; set up segments for | ||
| 1509 | MOV DRVNUM_OP_SEG2,AX ;AN000; message substitutions | ||
| 1510 | MOV DEVE_OP_SEG,AX ;AN000; used in the resident | ||
| 1511 | MOV DEVE_OP_SEG2,AX ;AN000; portion of command | ||
| 1512 | MOV ERR15_OP_SEG,AX ;AN000; during initialization | ||
| 1513 | MOV ERR15_OP_SEG2,AX ;AN000; to save resident | ||
| 1514 | MOV ERR15_OP_SEG3,AX ;AN000; space. | ||
| 1515 | MOV BADFAT_OP_SEG,AX ;AN000; | ||
| 1516 | MOV COMPRMT1_SEG,AX ;AN000; | ||
| 1517 | MOV COMPRMT1_SEG2,AX ;AN000; | ||
| 1518 | |||
| 1519 | RET ;AN000; | ||
| 1520 | |||
| 1521 | GET_MSG_PTR ENDP ;AN000; | ||
| 1522 | |||
| 1523 | |||
| 1524 | ; **************************************************************** | ||
| 1525 | ; * | ||
| 1526 | ; * ROUTINE: Setup_for_messages | ||
| 1527 | ; * | ||
| 1528 | ; * FUNCTION: Sets up system for PARSE and EXTENDED ERROR | ||
| 1529 | ; * messages as follows: | ||
| 1530 | ; * | ||
| 1531 | ; * IF /P and /MSG are entered | ||
| 1532 | ; * keep PARSE and EXTENDED ERRORS in memory | ||
| 1533 | ; * ELSE IF /P is entered | ||
| 1534 | ; * use PARSE and EXTENDED ERRORS on disk | ||
| 1535 | ; * remove PARSE ERRORS from memory | ||
| 1536 | ; * ELSE | ||
| 1537 | ; * remove PARSE ERRORS from memory | ||
| 1538 | ; * ENDIF | ||
| 1539 | ; * | ||
| 1540 | ; * INPUT: PERMCOM Set up with user input | ||
| 1541 | ; * EXT_MSG Set up with user input | ||
| 1542 | ; * System set up to retain PARSE ERRORS | ||
| 1543 | ; * | ||
| 1544 | ; * OUTPUT: registers unchanged | ||
| 1545 | ; * | ||
| 1546 | ; **************************************************************** | ||
| 1547 | |||
| 1548 | |||
| 1549 | setup_for_messages proc near ;AN060; | ||
| 1550 | |||
| 1551 | push ds ;AN060; save data segment | ||
| 1552 | push es ;AN060; save environment segment | ||
| 1553 | push ax ;AN060; | ||
| 1554 | push dx ;AN060; | ||
| 1555 | push di ;AN060; | ||
| 1556 | mov ax,cs ;AN060; get local segment to ES and DS | ||
| 1557 | mov ds,ax ;AN060; | ||
| 1558 | mov es,ax ;AN060; | ||
| 1559 | |||
| 1560 | cmp [permcom],0 ;AN060; was permcom set? | ||
| 1561 | jz no_permcom ;AN060; No - don't worry about messages | ||
| 1562 | cmp ext_msg,set_extended_msg ;AN060; was /msg specified? | ||
| 1563 | jz permcom_slash_msg ;AN060; Yes - go process it | ||
| 1564 | push es ;AN060; | ||
| 1565 | mov ax,1 ;AN060; Set ES to 1 as a flag to the message | ||
| 1566 | mov es,ax ;AN060; services that messages are on disk | ||
| 1567 | mov di,offset resgroup:extended_msg_start-100h ;AN060; start address | ||
| 1568 | call set_ext_2f ;AN060; set extended error address | ||
| 1569 | mov di,offset resgroup:parse_msg_start-0100h ;AN060; start address | ||
| 1570 | call set_parse_2f ;AN060; set parse error address | ||
| 1571 | pop es ;AN060; | ||
| 1572 | IF2 ;AN060;; | ||
| 1573 | IFNDEF READ_DISK_INFO ;AN060;; | ||
| 1574 | Extrn READ_DISK_PROC:Far ;AN060;; | ||
| 1575 | ENDIF ;AN060;; | ||
| 1576 | ENDIF ;AN060;; | ||
| 1577 | MOV AX,DOS_GET_EXT_PARSE_ADD ;AN060;; 2FH Interface | ||
| 1578 | MOV DL,DOS_SET_ADDR ;AN060;; Set the READ_DISK_PROC address | ||
| 1579 | LEA DI,READ_DISK_PROC ;AN060;; | ||
| 1580 | INT 2FH ;AN060;; Private interface | ||
| 1581 | jmp short permcom_end ;AN060; and exit | ||
| 1582 | |||
| 1583 | permcom_slash_msg: ;AN060; Keep messages in memory | ||
| 1584 | mov di,offset resgroup:extended_msg_start ;AN060; start address | ||
| 1585 | call set_ext_2f ;AN060; set the extended message address | ||
| 1586 | mov di,offset resgroup:extmsgend+15 ;AN060; get address of resident end | ||
| 1587 | mov [resmsgend],di ;AN060; save it | ||
| 1588 | jmp short permcom_end ;AN060; exit | ||
| 1589 | |||
| 1590 | no_permcom: ;AN060; | ||
| 1591 | cmp ext_msg,set_extended_msg ;AN060; was /msg specified? | ||
| 1592 | jnz no_slash_msg ;AN060; no - no error | ||
| 1593 | mov disp_class,parse_msg_class ;AN060; set up parse error msg class | ||
| 1594 | mov dx,LessArgs_Ptr ;AN060; get message number for "Required parameter missing" | ||
| 1595 | call print_message ;AN060; issue error message | ||
| 1596 | |||
| 1597 | no_slash_msg: | ||
| 1598 | mov ax,(multdos shl 8 or message_2f);AN060; reset parse message pointers | ||
| 1599 | mov dl,set_parse_msg ;AN060; set up parse message address | ||
| 1600 | mov di,pars_msg_off ;AN060; old offset of parse messages | ||
| 1601 | mov es,pars_msg_seg ;AN060; old segment of parse messages | ||
| 1602 | int 2fh ;AN060; go set it | ||
| 1603 | |||
| 1604 | permcom_end: | ||
| 1605 | call sysloadmsg ;AN060; load message addresses | ||
| 1606 | pop di ;AN060; | ||
| 1607 | pop dx ;AN060; | ||
| 1608 | pop ax ;AN060; | ||
| 1609 | pop es ;AN060; get environment back | ||
| 1610 | pop ds ;AN060; | ||
| 1611 | |||
| 1612 | ret ;AN060; | ||
| 1613 | |||
| 1614 | setup_for_messages endp ;AN060; | ||
| 1615 | |||
| 1616 | ; **************************************************************** | ||
| 1617 | ; * | ||
| 1618 | ; * ROUTINE: Set_parse_2f | ||
| 1619 | ; * | ||
| 1620 | ; * FUNCTION: Does the INT 2Fh to DOS to set the PARSE | ||
| 1621 | ; * message address that will later be retrieved | ||
| 1622 | ; * by the message services. | ||
| 1623 | ; * | ||
| 1624 | ; * INPUT: ES set to segment of messages | ||
| 1625 | ; * DI points to offset of messages | ||
| 1626 | ; * | ||
| 1627 | ; * OUTPUT: none | ||
| 1628 | ; * | ||
| 1629 | ; **************************************************************** | ||
| 1630 | |||
| 1631 | Set_parse_2f proc near ;AN060; | ||
| 1632 | |||
| 1633 | mov ax,(multdos shl 8 or message_2f);AN060; set up to call DOS through int 2fh | ||
| 1634 | mov dl,set_parse_msg ;AN060; set up parse message address | ||
| 1635 | int 2fh ;AN060; | ||
| 1636 | |||
| 1637 | ret ;AN060; | ||
| 1638 | |||
| 1639 | Set_parse_2f endp ;AN060; | ||
| 1640 | |||
| 1641 | ; **************************************************************** | ||
| 1642 | ; * | ||
| 1643 | ; * ROUTINE: Set_ext_2f | ||
| 1644 | ; * | ||
| 1645 | ; * FUNCTION: Does the INT 2Fh to DOS to set the EXTENDED | ||
| 1646 | ; * message address that will later be retrieved | ||
| 1647 | ; * by the message services. | ||
| 1648 | ; * | ||
| 1649 | ; * INPUT: ES set to segment of messages | ||
| 1650 | ; * DI points to offset of messages | ||
| 1651 | ; * | ||
| 1652 | ; * OUTPUT: none | ||
| 1653 | ; * | ||
| 1654 | ; **************************************************************** | ||
| 1655 | |||
| 1656 | Set_ext_2f proc near ;AN060; | ||
| 1657 | |||
| 1658 | mov ax,(multdos shl 8 or message_2f);AN060; set up to call DOS through int 2fh | ||
| 1659 | mov dl,set_extended_msg ;AN060; set up extended error message address | ||
| 1660 | int 2fh ;AN060; | ||
| 1661 | |||
| 1662 | ret ;AN060; | ||
| 1663 | |||
| 1664 | Set_ext_2f endp ;AN060; | ||
| 1665 | |||
| 1666 | |||
| 1667 | ASSUME DS:RESGROUP, ES:RESGROUP | ||
| 1668 | |||
| 1669 | .xlist | ||
| 1670 | .xcref | ||
| 1671 | |||
| 1672 | INCLUDE SYSMSG.INC ;AN000; include message services | ||
| 1673 | |||
| 1674 | .list | ||
| 1675 | .cref | ||
| 1676 | |||
| 1677 | MSG_UTILNAME <COMMAND> ;AN000; define utility name | ||
| 1678 | |||
| 1679 | MSG_SERVICES <COMR,NEARmsg,LOADmsg,NOCHECKSTDIN,NOCHECKSTDOUT> ;AC026; include message services macro | ||
| 1680 | |||
| 1681 | include msgdcl.inc | ||
| 1682 | |||
| 1683 | INIT ENDS | ||
| 1684 | |||
| 1685 | END | ||
diff --git a/v4.0/src/CMD/COMMAND/IPARSE.ASM b/v4.0/src/CMD/COMMAND/IPARSE.ASM new file mode 100644 index 0000000..5205fe9 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/IPARSE.ASM | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)iparse.asm 4.1 87/04/28 | ||
| 3 | ; SCCSID = @(#)iparse.asm 4.1 87/04/28 | ||
| 4 | TITLE COMMAND interface to SYSPARSE | ||
| 5 | |||
| 6 | .xlist | ||
| 7 | .xcref | ||
| 8 | INCLUDE comseg.asm ;AN000; | ||
| 9 | .list | ||
| 10 | .cref | ||
| 11 | |||
| 12 | |||
| 13 | INIT SEGMENT PUBLIC PARA ;AN000; | ||
| 14 | |||
| 15 | ASSUME CS:RESGROUP,DS:RESGROUP,ES:NOTHING,SS:NOTHING ;AN000; | ||
| 16 | |||
| 17 | |||
| 18 | ;AD054; public SYSPARSE ;AN000; | ||
| 19 | |||
| 20 | DateSW equ 0 ;AN000; do not Check date format | ||
| 21 | TimeSW equ 0 ;AN000; do not Check time format | ||
| 22 | CmpxSW equ 0 ;AN000; do not check complex list | ||
| 23 | KeySW equ 0 ;AN025; do not support keywords | ||
| 24 | Val2SW equ 0 ;AN025; do not Support value definition 2 | ||
| 25 | Val3SW equ 0 ;AN000; do not Support value definition 3 | ||
| 26 | QusSW equ 0 ;AN025; do not include quoted string | ||
| 27 | DrvSW equ 0 ;AN025; do not include drive only | ||
| 28 | |||
| 29 | .xlist | ||
| 30 | .xcref | ||
| 31 | ;AD054; INCLUDE parse.asm ;AN000; | ||
| 32 | .list | ||
| 33 | .cref | ||
| 34 | |||
| 35 | |||
| 36 | INIT ends ;AN000; | ||
| 37 | end ;AN000; | ||
| 38 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/COMMAND/MAKEFILE b/v4.0/src/CMD/COMMAND/MAKEFILE new file mode 100644 index 0000000..707fb00 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/MAKEFILE | |||
| @@ -0,0 +1,134 @@ | |||
| 1 | #************************** makefile for cmd\append *************************** | ||
| 2 | |||
| 3 | msg =..\..\messages | ||
| 4 | dos =..\..\dos | ||
| 5 | inc =..\..\inc | ||
| 6 | hinc =..\..\h | ||
| 7 | |||
| 8 | # | ||
| 9 | ####################### dependencies begin here. ######################### | ||
| 10 | # | ||
| 11 | |||
| 12 | all: command.com | ||
| 13 | |||
| 14 | $(inc)\dossym.inc: $(inc)\dosmac.inc $(inc)\bpb.inc \ | ||
| 15 | $(inc)\buffer.inc $(inc)\sysvar.inc $(inc)\vector.inc \ | ||
| 16 | $(inc)\mult.inc $(inc)\dirent.inc $(inc)\dpb.inc $(inc)\curdir.inc \ | ||
| 17 | $(inc)\cpmfcb.inc $(inc)\find.inc $(inc)\pdb.inc $(inc)\exe.inc \ | ||
| 18 | $(inc)\sf.inc $(inc)\arena.inc $(inc)\intnat.inc $(inc)\mi.inc \ | ||
| 19 | $(inc)\filemode.inc $(inc)\error.inc $(inc)\syscall.inc | ||
| 20 | echo "touch $(inc)\dossym.inc" | ||
| 21 | |||
| 22 | command.ctl: command.skl $(msg)\$(COUNTRY).msg makefile | ||
| 23 | |||
| 24 | command1.obj: command1.asm $(inc)\dossym.inc \ | ||
| 25 | $(inc)\devsym.inc comsw.asm comequ.asm resmsg.equ \ | ||
| 26 | envdata.asm | ||
| 27 | |||
| 28 | command2.obj: command2.asm $(inc)\dossym.inc \ | ||
| 29 | $(inc)\devsym.inc comsw.asm comequ.asm resmsg.equ \ | ||
| 30 | envdata.asm | ||
| 31 | |||
| 32 | copy.obj: copy.asm comsw.asm $(inc)\dossym.inc \ | ||
| 33 | $(inc)\devsym.inc comseg.asm comequ.asm | ||
| 34 | |||
| 35 | copypr1.obj: copypr1.asm comsw.asm $(inc)\dossym.inc \ | ||
| 36 | $(inc)\devsym.inc comseg.asm comequ.asm | ||
| 37 | |||
| 38 | copypr2.obj: copypr2.asm comsw.asm $(inc)\dossym.inc \ | ||
| 39 | $(inc)\devsym.inc comseg.asm comequ.asm | ||
| 40 | |||
| 41 | cparse.obj: cparse.asm comsw.asm $(inc)\dossym.inc \ | ||
| 42 | $(inc)\devsym.inc comseg.asm comequ.asm | ||
| 43 | |||
| 44 | init.obj: init.asm $(inc)\dossym.inc $(inc)\devsym.inc \ | ||
| 45 | comsw.asm comseg.asm comequ.asm resmsg.equ $(inc)\sysmsg.inc \ | ||
| 46 | $(inc)\msgserv.asm command.ctl | ||
| 47 | |||
| 48 | iparse.obj: iparse.asm comseg.asm $(inc)\parse.asm $(inc)\psdata.inc | ||
| 49 | |||
| 50 | parse2.obj: parse2.asm $(inc)\dossym.inc $(inc)\devsym.inc comsw.asm \ | ||
| 51 | comseg.asm comequ.asm | ||
| 52 | |||
| 53 | path1.obj: path1.asm $(inc)\dossym.inc $(inc)\devsym.inc comsw.asm \ | ||
| 54 | comseg.asm comequ.asm | ||
| 55 | |||
| 56 | path2.obj: path2.asm $(inc)\dossym.inc $(inc)\devsym.inc comsw.asm \ | ||
| 57 | comseg.asm comequ.asm | ||
| 58 | |||
| 59 | rdata.obj: rdata.asm comsw.asm comseg.asm $(inc)\sysmsg.inc \ | ||
| 60 | $(inc)\msgserv.asm command.cla command.cl3 command.cl4 \ | ||
| 61 | command.cld command.clc command.cle command.ctl | ||
| 62 | |||
| 63 | rucode.obj: rucode.asm $(inc)\dossym.inc $(inc)\devsym.inc \ | ||
| 64 | $(inc)\doscntry.inc resmsg.equ $(inc)\sysmsg.inc \ | ||
| 65 | $(inc)\msgserv.asm comsw.asm comseg.asm comequ.asm command.ctl | ||
| 66 | |||
| 67 | tbatch.obj: tbatch.asm comsw.asm $(inc)\dossym.inc $(inc)\doscntry.inc \ | ||
| 68 | $(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm | ||
| 69 | |||
| 70 | tbatch2.obj: tbatch2.asm comsw.asm $(inc)\dossym.inc $(inc)\doscntry.inc \ | ||
| 71 | $(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm | ||
| 72 | |||
| 73 | tcmd1a.obj: tcmd1a.asm comsw.asm $(inc)\dossym.inc $(inc)\ioctl.inc \ | ||
| 74 | $(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm | ||
| 75 | |||
| 76 | tcmd1b.obj: tcmd1b.asm comsw.asm $(inc)\dossym.inc $(inc)\ioctl.inc \ | ||
| 77 | $(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm $(inc)\ea.inc | ||
| 78 | |||
| 79 | tcmd2a.obj: tcmd2a.asm comsw.asm $(inc)\dossym.inc $(inc)\ioctl.inc \ | ||
| 80 | $(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm | ||
| 81 | |||
| 82 | tcmd2b.obj: tcmd2b.asm comsw.asm $(inc)\dossym.inc \ | ||
| 83 | $(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm | ||
| 84 | |||
| 85 | tcode.obj: tcode.asm comsw.asm $(inc)\dossym.inc \ | ||
| 86 | $(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm \ | ||
| 87 | $(inc)\mshalo.asm | ||
| 88 | |||
| 89 | tdata.obj: tdata.asm comsw.asm comseg.asm $(inc)\curdir.inc \ | ||
| 90 | $(inc)\error.inc ifequ.asm comequ.asm $(inc)\sysmsg.inc \ | ||
| 91 | $(inc)\msgserv.asm tranmsg.asm command.clf command.cl1 command.cl2 \ | ||
| 92 | command.ctl $(inc)\ea.inc | ||
| 93 | |||
| 94 | tenv.obj: tenv.asm comsw.asm $(inc)\dossym.inc $(inc)\devsym.inc \ | ||
| 95 | comseg.asm comequ.asm ifequ.asm $(inc)\doscntry.inc | ||
| 96 | |||
| 97 | tenv2.obj: tenv2.asm comsw.asm $(inc)\dossym.inc $(inc)\devsym.inc \ | ||
| 98 | comseg.asm comequ.asm ifequ.asm | ||
| 99 | |||
| 100 | tfor.obj: tfor.asm comsw.asm $(inc)\dossym.inc $(inc)\devsym.inc \ | ||
| 101 | comseg.asm comequ.asm ifequ.asm fordata.asm | ||
| 102 | |||
| 103 | tmisc1.obj: tmisc1.asm comsw.asm $(inc)\dossym.inc \ | ||
| 104 | $(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm | ||
| 105 | |||
| 106 | tmisc2.obj: tmisc2.asm comsw.asm $(inc)\dossym.inc $(inc)\ioctl.inc \ | ||
| 107 | $(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm | ||
| 108 | |||
| 109 | tparse.obj: tparse.asm comseg.asm $(inc)\parse.asm $(inc)\psdata.inc | ||
| 110 | |||
| 111 | tpipe.obj: tpipe.asm comsw.asm $(inc)\dossym.inc \ | ||
| 112 | $(inc)\devsym.inc comseg.asm comequ.asm ifequ.asm | ||
| 113 | |||
| 114 | tprintf.obj: tprintf.asm comsw.asm $(inc)\dosmac.inc \ | ||
| 115 | comseg.asm comequ.asm $(inc)\sysmsg.inc $(inc)\msgserv.asm \ | ||
| 116 | command.ctl | ||
| 117 | |||
| 118 | tspc.obj: tspc.asm comsw.asm $(inc)\dossym.inc comequ.asm \ | ||
| 119 | ifequ.asm comseg.asm $(inc)\ea.inc | ||
| 120 | |||
| 121 | tucode.obj: tucode.asm $(inc)\dosmac.inc $(inc)\dossym.inc \ | ||
| 122 | comsw.asm comseg.asm comequ.asm ifequ.asm | ||
| 123 | |||
| 124 | uinit.obj: uinit.asm comsw.asm comseg.asm ifequ.asm command.clb \ | ||
| 125 | $(inc)\sysmsg.inc $(inc)\msgserv.asm command.ctl | ||
| 126 | |||
| 127 | command.com: command1.obj command2.obj rucode.obj rdata.obj init.obj iparse.obj \ | ||
| 128 | uinit.obj tcode.obj tbatch.obj tbatch2.obj tfor.obj tcmd1a.obj tcmd1b.obj \ | ||
| 129 | tcmd2a.obj tcmd2b.obj tenv.obj tenv2.obj tmisc1.obj tmisc2.obj tpipe.obj \ | ||
| 130 | parse2.obj path1.obj path2.obj tucode.obj copy.obj copypr1.obj copypr2.obj \ | ||
| 131 | cparse.obj tparse.obj tprintf.obj tdata.obj tspc.obj | ||
| 132 | link @command.lnk | ||
| 133 | exe2bin command.exe command.com | ||
| 134 | del command.exe | ||
diff --git a/v4.0/src/CMD/COMMAND/PARSE2.ASM b/v4.0/src/CMD/COMMAND/PARSE2.ASM new file mode 100644 index 0000000..2695927 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/PARSE2.ASM | |||
| @@ -0,0 +1,422 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)parse.asm 1.1 85/05/14 | ||
| 3 | ; SCCSID = @(#)parse.asm 1.1 85/05/14 | ||
| 4 | .sall | ||
| 5 | .xlist | ||
| 6 | .xcref | ||
| 7 | INCLUDE DOSSYM.INC | ||
| 8 | INCLUDE DEVSYM.INC | ||
| 9 | include comsw.asm | ||
| 10 | include comseg.asm | ||
| 11 | include comequ.asm | ||
| 12 | .list | ||
| 13 | .cref | ||
| 14 | |||
| 15 | |||
| 16 | break <Parse.Asm> | ||
| 17 | ;---------------------------------------------------------------------------- | ||
| 18 | ; PARSE.ASM contains the routines to perform command line parsing. | ||
| 19 | ; Parse and Path share a buffer and argv[] definitions. | ||
| 20 | ; Invoking <Parseline> maps the unparsed command line in COMBUF into an | ||
| 21 | ; array of pointers to the parsed tokens. The resulting array, argv[], | ||
| 22 | ; also contains extra information provided by cparse about each token | ||
| 23 | ; <Parseline> should be executed prior to <Path_Search> | ||
| 24 | ; | ||
| 25 | ; Alan L, OS/MSDOS August 15, 1983 | ||
| 26 | ; | ||
| 27 | ; | ||
| 28 | ; ENTRY: | ||
| 29 | ; <Parseline>: command line in COMTAB. | ||
| 30 | ; EXIT: | ||
| 31 | ; <Parseline>: success flag, argcnt (number of args), argv[]. | ||
| 32 | ; NOTE(S): | ||
| 33 | ; * <Argv_calc> handily turns an array index into an absolute pointer. | ||
| 34 | ; The computation depends on the size of an argv[] element (arg_ele). | ||
| 35 | ; * <Parseline> calls <cparse> for chunks of the command line. <Cparse> | ||
| 36 | ; does not function as specified; see <Parseline> for more details. | ||
| 37 | ; * <Parseline> now knows about the flags the internals of COMMAND.COM | ||
| 38 | ; need to know about. This extra information is stored in a switch_flag | ||
| 39 | ; word with each command-line argument; the switches themselves will not | ||
| 40 | ; appear in the resulting arg structure. | ||
| 41 | ; * With the exception of CARRY, flags are generally preserved across calls. | ||
| 42 | ;--------------- | ||
| 43 | ; CONSTANTS: | ||
| 44 | ;--------------- | ||
| 45 | DEBUGx equ FALSE ; prints out debug info | ||
| 46 | ;--------------- | ||
| 47 | ; DATA: | ||
| 48 | ;--------------- | ||
| 49 | |||
| 50 | DATARES SEGMENT PUBLIC BYTE | ||
| 51 | EXTRN FORFLAG:BYTE | ||
| 52 | DATARES ENDS | ||
| 53 | |||
| 54 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 55 | EXTRN combuf:byte | ||
| 56 | EXTRN cpyflag:byte | ||
| 57 | EXTRN expand_star:byte | ||
| 58 | EXTRN RESSEG:word | ||
| 59 | EXTRN STARTEL:word | ||
| 60 | TRANSPACE ENDS | ||
| 61 | |||
| 62 | TRANCODE SEGMENT PUBLIC BYTE ;AC000; | ||
| 63 | PUBLIC argv_calc ; convert array index into address | ||
| 64 | PUBLIC parseline | ||
| 65 | |||
| 66 | |||
| 67 | assume cs:trangroup, ds:trangroup, es:trangroup, ss:nothing | ||
| 68 | |||
| 69 | |||
| 70 | break <Parseline: Munch on the command line> | ||
| 71 | ;---------------------------------------------------------------------------- | ||
| 72 | ; PARSELINE takes an MSDOS command line and maps it into a UNIX-style | ||
| 73 | ; argv[argvcnt] array. The most important difference between this array and | ||
| 74 | ; the tradition UNIX format is the extra cparse information included with | ||
| 75 | ; each argument element. | ||
| 76 | ;--------------- | ||
| 77 | ; ENTRY: | ||
| 78 | ; (BL special delimiter for cparse -- not implemented) | ||
| 79 | ;--------------- | ||
| 80 | ; EXIT: | ||
| 81 | ; CF set if error | ||
| 82 | ; AL error code (carry set). Note AH clobbered in any event. | ||
| 83 | ; argv[] array of cparse flags and pointers to arguments | ||
| 84 | ; argvcnt argument count | ||
| 85 | ;--------------- | ||
| 86 | ; NOTE(S): | ||
| 87 | ; * BL (special delimiter) is ignored, for now (set to space). | ||
| 88 | ; * Parseflags record contains cparse flags, as follows: | ||
| 89 | ; sw_flag -- was this arg a switch? | ||
| 90 | ; wildcard -- whether or not it contained a * or ? | ||
| 91 | ; path_sep -- maybe it was a pathname | ||
| 92 | ; unused -- for future expansion | ||
| 93 | ; special_delim -- was there an initial special delimiter? | ||
| 94 | ; * argv[] and argvcnt are undefined if CF/AL indicates an error. | ||
| 95 | ; * Relationship between input, cparse output, and comtail can be | ||
| 96 | ; found in the following chart. Despite the claim of the cparse | ||
| 97 | ; documentation that, "Token buffer always starts d: for non switch | ||
| 98 | ; tokens", such is not the case (see column two, row two). | ||
| 99 | ; Similarly, [STARTEL] is not null when the command line is one of | ||
| 100 | ; the forms, "d:", "d:\", or "d:/". In fact, *STARTEL (i.e., what | ||
| 101 | ; STARTEL addresses) will be null. This is clearly just a | ||
| 102 | ; documentation error. | ||
| 103 | ; * cparse also returns a switch code in BP for each switch it | ||
| 104 | ; recognizes on the command line. | ||
| 105 | ; * arglen for each token does NOT include the terminating null. | ||
| 106 | ; * Finally, note that interesting constructions like 'foodir/*.exe' | ||
| 107 | ; parse as three separate tokens, and the asterisk is NOT a wildcard. | ||
| 108 | ; For example, 'for %i in (foodir/*.exe) do echo %i' will first | ||
| 109 | ; echo 'foodir', then '*', then '.exe'. Using cparse for command- | ||
| 110 | ; line parsing may result in slightly different behavior than | ||
| 111 | ; previously observed with the old COMMAND.COM command-line parser. | ||
| 112 | ; | ||
| 113 | ; Input Cparse Command Line (80H) | ||
| 114 | ; \alan\foo.bat c:\alan\foo.bat \alan\foo.bat | ||
| 115 | ; alan\foo.bat alan\foo.bat alan\foo.bat | ||
| 116 | ; foo.bat foo.bat foo.bat | ||
| 117 | ; c:\alan\foo.bat c:\alan\foo.bat c:\alan\foo.bat | ||
| 118 | ; c:alan\foo.bat c:alan\foo.bat c:alan\foo.bat | ||
| 119 | ; c:foo.bat c:foo.bat c:foo.bat | ||
| 120 | ;--------------- | ||
| 121 | ; CONSTANTS: | ||
| 122 | ;--------------- | ||
| 123 | ;--------------- | ||
| 124 | ; DATA: | ||
| 125 | ;--------------- | ||
| 126 | |||
| 127 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 128 | EXTRN arg:byte | ||
| 129 | EXTRN argbufptr:word | ||
| 130 | EXTRN comptr:word | ||
| 131 | EXTRN last_arg:word | ||
| 132 | EXTRN tpbuf:byte | ||
| 133 | TRANSPACE ENDS | ||
| 134 | |||
| 135 | ;--------------- | ||
| 136 | parseline: | ||
| 137 | ;--------------- | ||
| 138 | |||
| 139 | push AX ; most of these are clobbered | ||
| 140 | push BX ; by cparse... | ||
| 141 | push CX | ||
| 142 | push DX | ||
| 143 | push DI | ||
| 144 | push SI | ||
| 145 | pushf | ||
| 146 | mov cpyflag,0 ; Turn "CPARSE called from COPY flag" off | ||
| 147 | |||
| 148 | mov [LAST_ARG], -1 ; last argument at which to accumulate | ||
| 149 | xor ax,ax | ||
| 150 | mov cx,SIZE arg_unit | ||
| 151 | mov di,offset trangroup:arg | ||
| 152 | rep stosb | ||
| 153 | mov argbufptr,offset trangroup:arg.argbuf | ||
| 154 | mov arg.argswinfo, 0 ; switch information, and info to date | ||
| 155 | mov arg.argvcnt, 0 ; initialize argvcnt/argv[] | ||
| 156 | mov SI, OFFSET TRANGROUP:combuf+2 ; prescan leaves cooked input in combuf | ||
| 157 | |||
| 158 | ; This next section of code (up to pcont:) makes sure that si is set up for | ||
| 159 | ; parsing. It should point at COMBUF if FORFLAG is set and arg.argforcombuf | ||
| 160 | ; otherwise. This is done so that commands can get arg pointers into their | ||
| 161 | ; original command line (or an exact copy of it) in arg_ocomptr. | ||
| 162 | ; Arg.argforcombuf is used so that the for loop processor will always be able | ||
| 163 | ; to get a hold of its original command line; even after COMBUF is blasted by | ||
| 164 | ; the command to be repeated or the transient part of command has been | ||
| 165 | ; reloaded. | ||
| 166 | |||
| 167 | push ds | ||
| 168 | mov ds,[RESSEG] | ||
| 169 | assume ds:resgroup | ||
| 170 | cmp FORFLAG,0 | ||
| 171 | pop ds | ||
| 172 | assume ds:trangroup | ||
| 173 | jnz pcont | ||
| 174 | mov di,OFFSET TRANGROUP:arg.argforcombuf | ||
| 175 | xor ch,ch | ||
| 176 | mov cl,[COMBUF+1] | ||
| 177 | inc cl | ||
| 178 | rep movsb | ||
| 179 | mov si,OFFSET TRANGROUP:arg.argforcombuf | ||
| 180 | |||
| 181 | pcont: | ||
| 182 | mov DI, OFFSET TRANGROUP:tpbuf ; destination is temporary token buffer | ||
| 183 | mov BL, ' ' ; no special delimiter, for now | ||
| 184 | |||
| 185 | parseloop: | ||
| 186 | mov comptr,si ; save ptr into original command buffer | ||
| 187 | xor BP, BP ; switch information put here by cparse | ||
| 188 | mov byte ptr [expand_star],0 ; don't expand *'s to ?'s | ||
| 189 | invoke scanoff ; skip leading blanks... | ||
| 190 | invoke cparse ; byte off a token (args in SI, DI, BL) | ||
| 191 | jnc More_prse | ||
| 192 | or BP,BP ; Check for trailing switch character | ||
| 193 | jz parsedone | ||
| 194 | call newarg ; We hit CR but BP is non-zero. The | ||
| 195 | ; typical cause of this is that a | ||
| 196 | ; switch char IMMEDIATELY preceeds | ||
| 197 | ; the CR. We have an argument, but it | ||
| 198 | ; is sort of an error. | ||
| 199 | jmp short parsedone ; We're done (found the CR). | ||
| 200 | |||
| 201 | More_prse: | ||
| 202 | mov cpyflag,2 ; tell CPARSE that 1st token is done | ||
| 203 | call newarg ; add to argv array (CX has char count) | ||
| 204 | jnc parseloop ; was everything OK? | ||
| 205 | jmp short parse_error ; NO, it wasn't -- bug out (CF set) | ||
| 206 | |||
| 207 | parsedone: ; successful completion of parseline | ||
| 208 | popf | ||
| 209 | clc | ||
| 210 | jmp short parse_exit | ||
| 211 | |||
| 212 | parse_error: ; error entry (er, exit) point | ||
| 213 | popf | ||
| 214 | stc | ||
| 215 | parse_exit: ; depend on not changing CF | ||
| 216 | pop SI | ||
| 217 | pop DI | ||
| 218 | pop DX | ||
| 219 | pop CX | ||
| 220 | pop BX | ||
| 221 | pop AX | ||
| 222 | ret | ||
| 223 | |||
| 224 | ;--------------- | ||
| 225 | ; parseline ends | ||
| 226 | ;---------------------------------------------------------------------------- | ||
| 227 | |||
| 228 | |||
| 229 | break <NewArg> | ||
| 230 | ;---------------------------------------------------------------------------- | ||
| 231 | ; NEWARG adds the supplied argstring and cparse data to arg.argv[]. | ||
| 232 | ; ENTRY: | ||
| 233 | ; BH argflags | ||
| 234 | ; CX character count in argstring | ||
| 235 | ; DI pointer to argstring | ||
| 236 | ; comptr ptr to starting loc of current token in original command | ||
| 237 | ; [STARTEL] cparse's answer to where the last element starts | ||
| 238 | ; EXIT: | ||
| 239 | ; argbufptr points to next free section of argbuffer | ||
| 240 | ; arg.argbuf contains null-terminated argument strings | ||
| 241 | ; arg.argvcnt argument count | ||
| 242 | ; arg.argv[] array of flags and pointers | ||
| 243 | ; arg.arg_ocomptr ptr to starting loc of current token in original command | ||
| 244 | ; CF set if error | ||
| 245 | ; AL carry set: error code; otherwise, zero | ||
| 246 | ;--------------- | ||
| 247 | newarg: | ||
| 248 | ;--------------- | ||
| 249 | |||
| 250 | push BX | ||
| 251 | push CX | ||
| 252 | push DX ; one never knows, do one? | ||
| 253 | push DI | ||
| 254 | push SI | ||
| 255 | pushf | ||
| 256 | call arg_switch ; if it's a switch, record switch info | ||
| 257 | ; LEAVE SWITCH ON COMMAND LINE!! | ||
| 258 | ;;; jc newarg_done ; previous arg's switches -- and leave | ||
| 259 | |||
| 260 | cmp arg.argvcnt, ARGMAX ; check to ensure we've not | ||
| 261 | jge too_many_args ; exceeded array limits | ||
| 262 | mov DH, BH ; save argflags | ||
| 263 | mov BX, arg.argvcnt ; argv[argvcnt++] = arg data | ||
| 264 | inc arg.argvcnt | ||
| 265 | mov AX, OFFSET TRANGROUP:arg.argv | ||
| 266 | call argv_calc ; convert offset to pointer | ||
| 267 | mov [BX].argsw_word, 0 ; no switch information, yet... | ||
| 268 | mov [BX].arglen, CX ; argv[argvcnt].arglen = arg length | ||
| 269 | mov [BX].argflags, DH ; argv[argvcnt].argflags = cparse flags | ||
| 270 | mov SI, argbufptr | ||
| 271 | mov [BX].argpointer, SI ; argv[argvcnt].argpointer = [argbufptr] | ||
| 272 | add SI, [STARTEL] ; save startel from new location | ||
| 273 | sub SI, DI ; form pointer into argbuf | ||
| 274 | mov [BX].argstartel, SI ; argv[argvcnt].argstartel = new [STARTEL] | ||
| 275 | mov si,[comptr] | ||
| 276 | mov [BX].arg_ocomptr,si ; arg_ocomptr=ptr into original com line | ||
| 277 | |||
| 278 | mov SI, DI ; now save argstring in argbuffer | ||
| 279 | mov DI, argbufptr ; load the argbuf pointer and make | ||
| 280 | add DI, CX ; sure we're not about to run off | ||
| 281 | cmp DI, OFFSET TRANGROUP:arg.argbuf+ARGBLEN-1 | ||
| 282 | jge buf_ovflow ; the end of the buffer (plus null byte) | ||
| 283 | sub DI, CX ; adjust the pointer | ||
| 284 | cld | ||
| 285 | rep movsb ; and save the string in argbuffer | ||
| 286 | mov AL, ANULL ; tack a null byte on the end | ||
| 287 | stosb | ||
| 288 | mov argbufptr, DI ; update argbufptr after copy | ||
| 289 | |||
| 290 | newarg_done: | ||
| 291 | popf | ||
| 292 | clc | ||
| 293 | jmp short newarg_exit | ||
| 294 | |||
| 295 | too_many_args: | ||
| 296 | mov AX, arg_cnt_error | ||
| 297 | jmp short newarg_error | ||
| 298 | |||
| 299 | buf_ovflow: | ||
| 300 | mov AX, arg_buf_ovflow | ||
| 301 | |||
| 302 | newarg_error: | ||
| 303 | popf | ||
| 304 | stc | ||
| 305 | |||
| 306 | newarg_exit: | ||
| 307 | pop SI | ||
| 308 | pop DI | ||
| 309 | pop DX | ||
| 310 | pop CX | ||
| 311 | pop BX | ||
| 312 | ret | ||
| 313 | |||
| 314 | ;--------------- | ||
| 315 | ; NewArg ends | ||
| 316 | ;---------------------------------------------------------------------------- | ||
| 317 | |||
| 318 | |||
| 319 | break <Arg_Switch> | ||
| 320 | ;---------------------------------------------------------------------------- | ||
| 321 | ; ARG_SWITCH decides if an argument might really be a switch. In the | ||
| 322 | ; event that it is, and we can recognize | ||
| 323 | ; ENTRY: | ||
| 324 | ; As in <newarg>. | ||
| 325 | ; EXIT: | ||
| 326 | ; CF -- clear (wasn't a switch); set (was a switch) | ||
| 327 | ; NOTE(S): | ||
| 328 | ; * The mechanism mapping a switch into a bit-value depends entirely | ||
| 329 | ; on the order of definition in the <switch_list> variable and the | ||
| 330 | ; values chosen to define the bits in CMDT:COMEQU.ASM. Change either | ||
| 331 | ; <switch_list> or the definitions in CMDT:COMEQU.ASM -- and rewrite | ||
| 332 | ; this mechanism. This code taken from CMDT:TCODE.ASM. | ||
| 333 | ; * The <switch_list> declared below is redundant to one declared in | ||
| 334 | ; TDATA.ASM, and used in TCODE.ASM. | ||
| 335 | ; * An ugly routine. | ||
| 336 | ;--------------- | ||
| 337 | ; CONSTANTS: | ||
| 338 | ;--------------- | ||
| 339 | ; Constants come from the definitions in CMDT:COMEQU.ASM. | ||
| 340 | ;--------------- | ||
| 341 | ; DATA: | ||
| 342 | ;--------------- | ||
| 343 | |||
| 344 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 345 | extrn switch_list:byte | ||
| 346 | switch_count EQU $-switch_list | ||
| 347 | transpace ends | ||
| 348 | |||
| 349 | ;--------------- | ||
| 350 | Arg_Switch: | ||
| 351 | ;--------------- | ||
| 352 | |||
| 353 | push AX | ||
| 354 | push BX | ||
| 355 | push CX | ||
| 356 | push DI | ||
| 357 | pushf | ||
| 358 | test BH, MASK sw_flag ; is it a switch? (preserve flag word) | ||
| 359 | jz arg_no_switch0 | ||
| 360 | cmp [LAST_ARG], -1 ; have we encountered any REAL args yet? | ||
| 361 | je arg_no_switch1 ; no, so leading switches don't matter | ||
| 362 | mov BX, [LAST_ARG] ; yes, add switch info to last REAL arg | ||
| 363 | mov AX, OFFSET TRANGROUP:arg.argv | ||
| 364 | call argv_calc | ||
| 365 | or [BX].argsw_word, BP | ||
| 366 | or arg.argswinfo, BP | ||
| 367 | |||
| 368 | arg_yes_switch: ; ah, sweet success... | ||
| 369 | popf | ||
| 370 | stc | ||
| 371 | jmp short arg_switch_exit | ||
| 372 | |||
| 373 | arg_no_switch0: | ||
| 374 | mov AX, arg.argvcnt ; future switches should then affect | ||
| 375 | mov [LAST_ARG], AX ; this argument | ||
| 376 | |||
| 377 | arg_no_switch1: ; wasn't a switch, or we're pretending | ||
| 378 | popf | ||
| 379 | clc | ||
| 380 | |||
| 381 | arg_switch_exit: | ||
| 382 | pop DI | ||
| 383 | pop CX | ||
| 384 | pop BX | ||
| 385 | pop AX | ||
| 386 | ret | ||
| 387 | |||
| 388 | ;--------------- | ||
| 389 | ; Arg_Switch ends | ||
| 390 | ;---------------------------------------------------------------------------- | ||
| 391 | |||
| 392 | |||
| 393 | break <Argv_calc> | ||
| 394 | ;---------------------------------------------------------------------------- | ||
| 395 | ; ARGV_CALC maps an array index into a byte-offset from the base of | ||
| 396 | ; the supplied array. Method used for computing the address is: | ||
| 397 | ; Array Index * Array Elt Size + Base Addr = Elt Addr | ||
| 398 | ; ENTRY: | ||
| 399 | ; AX -- base of array | ||
| 400 | ; BX -- array index | ||
| 401 | ; EXIT: | ||
| 402 | ; BX -- byte offset | ||
| 403 | ;--------------- | ||
| 404 | |||
| 405 | argv_calc: | ||
| 406 | push ax ; Save base | ||
| 407 | mov al,bl ; al = array index | ||
| 408 | mov bl,SIZE argv_ele ; bl = size of an argv element | ||
| 409 | mul bl ; ax = base offset | ||
| 410 | pop bx ; Get base | ||
| 411 | add ax,bx ; Add in base offset | ||
| 412 | xchg ax,bx ; Restore ax and put byte offset in bx | ||
| 413 | ret | ||
| 414 | |||
| 415 | ;--------------- | ||
| 416 | ; argv_calc ends | ||
| 417 | ;---------------------------------------------------------------------------- | ||
| 418 | |||
| 419 | |||
| 420 | |||
| 421 | trancode ends | ||
| 422 | end | ||
diff --git a/v4.0/src/CMD/COMMAND/PATH1.ASM b/v4.0/src/CMD/COMMAND/PATH1.ASM new file mode 100644 index 0000000..4567174 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/PATH1.ASM | |||
| @@ -0,0 +1,507 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)path1.asm 1.1 85/05/14 | ||
| 3 | ; SCCSID = @(#)path1.asm 1.1 85/05/14 | ||
| 4 | .sall | ||
| 5 | .xlist | ||
| 6 | .xcref | ||
| 7 | INCLUDE DOSSYM.INC | ||
| 8 | include comsw.asm | ||
| 9 | include comseg.asm | ||
| 10 | include comequ.asm | ||
| 11 | .list | ||
| 12 | .cref | ||
| 13 | |||
| 14 | break <Path.Asm> | ||
| 15 | ;---------------------------------------------------------------------------- | ||
| 16 | ; PATH.ASM contains the routines to perform pathname incovation. Path and | ||
| 17 | ; Parse share a temporary buffer and argv[] definitions. <Path_Search>, | ||
| 18 | ; given a pathname, attempts to find a corresponding executable or batch | ||
| 19 | ; file on disk. Directories specified in the user's search path will be | ||
| 20 | ; searched for a matching file, if a match is not found in the current | ||
| 21 | ; directory and if the pathname is actually only an MSDOS filename. | ||
| 22 | ; <Path_Search> assumes that the parsed command name can be found in | ||
| 23 | ; argv[0] -- in other words, <Parseline> should be executed prior to | ||
| 24 | ; <Path_Search>. Alternatively, the command name and appropriate | ||
| 25 | ; information could be placed in argv[0], or <Path_Search> could be | ||
| 26 | ; (easily) modified to make no assumptions about where its input is found. | ||
| 27 | ; Please find enclosed yet another important routine, <Save_Args>, which | ||
| 28 | ; places the entire arg/argv[]/argbuf structure on a piece of newly | ||
| 29 | ; allocated memory. This is handy for for-loop processing, and anything | ||
| 30 | ; else that wants to save the whole shebang and then process other command | ||
| 31 | ; lines. | ||
| 32 | ; | ||
| 33 | ; Alan L, OS/MSDOS August 15, 1983 | ||
| 34 | ; | ||
| 35 | ; ENTRY: | ||
| 36 | ; <Path_Search>: argv[0]. | ||
| 37 | ; <Save_Args>: bytes to allocate in addition to arg structure | ||
| 38 | ; EXIT: | ||
| 39 | ; <Path_Search>: success flag, best pathname match in EXECPATH. | ||
| 40 | ; <Save_Args>: success flag, segment address of new memory | ||
| 41 | ; NOTE(S): | ||
| 42 | ; * <Argv_calc> handily turns an array index into an absolute pointer. | ||
| 43 | ; The computation depends on the size of an argv[] element (arg_ele). | ||
| 44 | ; * <Parseline> calls <cparse> for chunks of the command line. <Cparse> | ||
| 45 | ; does not function as specified; see <Parseline> for more details. | ||
| 46 | ; * <Parseline> now knows about the flags the internals of COMMAND.COM | ||
| 47 | ; need to know about. This extra information is stored in a switch_flag | ||
| 48 | ; word with each command-line argument; the switches themselves will not | ||
| 49 | ; appear in the resulting arg structure. | ||
| 50 | ; * With the exception of CARRY, flags are generally preserved across calls. | ||
| 51 | ;--------------- | ||
| 52 | ; CONSTANTS: | ||
| 53 | ;--------------- | ||
| 54 | DEBUGx equ FALSE ; prints out debug info | ||
| 55 | ;--------------- | ||
| 56 | ; DATA: | ||
| 57 | ;--------------- | ||
| 58 | |||
| 59 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 60 | EXTRN baddrv_ptr:word | ||
| 61 | TRANDATA ENDS | ||
| 62 | |||
| 63 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 64 | EXTRN arg:byte | ||
| 65 | EXTRN BADPMES_ptr:word | ||
| 66 | EXTRN curdrv:byte | ||
| 67 | EXTRN EXECPATH:byte | ||
| 68 | EXTRN search_best_buf:byte | ||
| 69 | EXTRN search_error:word | ||
| 70 | EXTRN string_ptr_2:word | ||
| 71 | EXTRN tpbuf:byte | ||
| 72 | TRANSPACE ENDS | ||
| 73 | |||
| 74 | TRANCODE SEGMENT PUBLIC BYTE ;AC000; | ||
| 75 | |||
| 76 | assume cs:trangroup, ds:trangroup, es:trangroup, ss:nothing | ||
| 77 | |||
| 78 | break <Path_Search> | ||
| 79 | ;------------------------------------------------------------------------------ | ||
| 80 | ; PATH_SEARCH tries to find the file it's given, somewhere. An initial value | ||
| 81 | ; of *argv[0].argstartel == 0 implies that there is no command (empty line | ||
| 82 | ; or 'd:' or 'd:/'). This check is done in strip; otherwise, strip formats | ||
| 83 | ; the filename/pathname into tpbuf. Search(tpbuf) is executed to see if we | ||
| 84 | ; have a match, either in the current working directory if we were handed | ||
| 85 | ; a filename, or in the specified directory, given a pathname. If this call | ||
| 86 | ; fails, and we were given a pathname, then Path_Search fails. Otherwise, | ||
| 87 | ; Path_Crunch is repeatedly invoked on tpbuf[STARTEL] (if there's a drive | ||
| 88 | ; prefix, we want to skip it) for each pathstring in userpath. Success on | ||
| 89 | ; either the first invocation of search or on one of the succeeding calls | ||
| 90 | ; sets up the appropriate information for copying the successful pathname | ||
| 91 | ; prefix (if any) into the result buffer, followed by the successful filename | ||
| 92 | ; match (from [search_best_buf]). The result is returned in in EXECPATH. | ||
| 93 | ; ENTRY: | ||
| 94 | ; argv[0] -- command name and associated information | ||
| 95 | ; EXIT: | ||
| 96 | ; AX -- non-zero indicates type of file found | ||
| 97 | ; EXECPATH -- successful pathname (AX non-zero) | ||
| 98 | ; NOTE(S): | ||
| 99 | ; 1) Uses the temporary buffer, tpbuf, from the parse routines. | ||
| 100 | ; 2) Some files are more equal than others. See search: for rankings. | ||
| 101 | ; 3) Path_Search terminates as soon as a call to search succeeds, even | ||
| 102 | ; if search returns an .exe or .bat. | ||
| 103 | ; 5) Clobbers dma address. | ||
| 104 | |||
| 105 | pbuflen equ 128 ; length of EXECPATH | ||
| 106 | path_sep_char equ ';' | ||
| 107 | |||
| 108 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 109 | EXTRN fbuf:byte | ||
| 110 | EXTRN pathinfo:word | ||
| 111 | EXTRN psep_char:byte | ||
| 112 | TRANSPACE ENDS | ||
| 113 | |||
| 114 | Procedure Path_Search,NEAR | ||
| 115 | |||
| 116 | push BX | ||
| 117 | push CX | ||
| 118 | push DX ; could use a "stack 'em" instruction | ||
| 119 | push SI | ||
| 120 | push DI | ||
| 121 | push BP | ||
| 122 | pushf | ||
| 123 | test DS:arg.argv[0].argflags, (MASK wildcard) + (MASK sw_flag) | ||
| 124 | jz path_search_ok | ||
| 125 | |||
| 126 | path_failure_jmp: | ||
| 127 | jmp path_failure ; ambiguous commands not allowed | ||
| 128 | |||
| 129 | path_search_ok: | ||
| 130 | call store_pchar ; figure out the pathname separator | ||
| 131 | mov DX, OFFSET TRANGROUP:fbuf ; clobber old dma value with | ||
| 132 | trap set_dma ; a pointer to our dma buffer | ||
| 133 | push ES | ||
| 134 | invoke find_path ; get a handle (ES:DI) on user path | ||
| 135 | mov DS:pathinfo[0], ES ; and squirrel it away | ||
| 136 | mov DS:pathinfo[2], DI ; "old" pathstring pointer | ||
| 137 | mov DS:pathinfo[4], DI ; "new" pathstring pointer | ||
| 138 | pop ES | ||
| 139 | |||
| 140 | mov BX, pbuflen ; copy/format argv[0] into temp buffer | ||
| 141 | mov SI, OFFSET TRANGROUP:EXECPATH | ||
| 142 | invoke strip | ||
| 143 | jc path_failure_jmp ; if possible, of course | ||
| 144 | |||
| 145 | mov DX, SI ; search(EXECPATH, error_message) | ||
| 146 | mov [search_error], OFFSET TRANGROUP:BADDRV_ptr | ||
| 147 | invoke search ; must do at least one search | ||
| 148 | or AX, AX ; find anything? | ||
| 149 | jz path_noinit ; failure ... search farther | ||
| 150 | |||
| 151 | mov BP, AX ; success... save filetype code | ||
| 152 | mov DI, OFFSET TRANGROUP:EXECPATH | ||
| 153 | mov SI, DS:arg.argv[0].argpointer | ||
| 154 | mov CX, DS:arg.argv[0].argstartel | ||
| 155 | sub CX, SI ; compute prefix bytes to copy | ||
| 156 | ; | ||
| 157 | ; We have the number of bytes in the prefix (up to the final component). | ||
| 158 | ; We need to form the complete pathname including leading drive and current | ||
| 159 | ; directory. | ||
| 160 | ; | ||
| 161 | ; Is there a drive letter present? | ||
| 162 | ; | ||
| 163 | |||
| 164 | mov ah,':' | ||
| 165 | cmp cx,2 ; room for drive letter? | ||
| 166 | jb AddDrive ; no, stick it in | ||
| 167 | cmp [si+1],ah ; colon present? | ||
| 168 | jz MoveDrive ; yes, just move it | ||
| 169 | |||
| 170 | AddDrive: | ||
| 171 | mov al,curdrv ; get current drive | ||
| 172 | add al,"A" ; convert to uppercase letter | ||
| 173 | stosw ; store d: | ||
| 174 | jmp short CheckPath | ||
| 175 | |||
| 176 | MoveDrive: | ||
| 177 | lodsw ; move d: | ||
| 178 | stosw | ||
| 179 | sub cx,2 ; 2 bytes less to move | ||
| 180 | |||
| 181 | CheckPath: | ||
| 182 | or al,20h | ||
| 183 | mov dl,al | ||
| 184 | sub dl,"a"-1 ; convert to 1-based for current dir | ||
| 185 | ; | ||
| 186 | ; Stick in beginning path char | ||
| 187 | ; | ||
| 188 | mov al,psep_char | ||
| 189 | stosb | ||
| 190 | ; | ||
| 191 | ; Is there a leading /? If so, then no current dir copy is necessary. | ||
| 192 | ; Otherwise, get current dir for DL. | ||
| 193 | ; | ||
| 194 | cmp cx,1 ; is there room for path char? | ||
| 195 | jb AddPath ; no, go add path | ||
| 196 | lodsb | ||
| 197 | dec cx | ||
| 198 | cmp al,psep_char ; is there a path separator? | ||
| 199 | jz MovePath ; yes, go move remainder of path | ||
| 200 | inc cx | ||
| 201 | dec si ; undo the lodsb | ||
| 202 | |||
| 203 | AddPath: | ||
| 204 | SaveReg <SI> | ||
| 205 | mov si,di ; remainder of buffer | ||
| 206 | trap Current_dir | ||
| 207 | ; | ||
| 208 | ; The previous current dir will succeed a previous find_first already worked. | ||
| 209 | ; | ||
| 210 | ; Find end of string. | ||
| 211 | ; | ||
| 212 | mov di,si | ||
| 213 | RestoreReg <SI> | ||
| 214 | mov al,psep_char | ||
| 215 | cmp byte ptr [di],0 ; root (empty dir string)? | ||
| 216 | jz MovePath ; yes, no need for path char | ||
| 217 | |||
| 218 | ScanEnd: | ||
| 219 | cmp byte ptr [dI],0 ; end of string? | ||
| 220 | jz FoundEnd | ||
| 221 | inc di | ||
| 222 | jmp ScanEnd | ||
| 223 | ; | ||
| 224 | ; Stick in a trailing path char | ||
| 225 | ; | ||
| 226 | FoundEnd: | ||
| 227 | stosb | ||
| 228 | ; | ||
| 229 | ; Move remaining part of path. Skip leading path char if present. | ||
| 230 | ; | ||
| 231 | MovePath: | ||
| 232 | cmp [si],al ; first char a path char? | ||
| 233 | jnz CopyPath | ||
| 234 | inc si ; move past leading char | ||
| 235 | dec cx ; drop from count | ||
| 236 | |||
| 237 | CopyPath: | ||
| 238 | jcxz CopyDone ; no chars to move! | ||
| 239 | rep movsb | ||
| 240 | |||
| 241 | CopyDone: | ||
| 242 | jmp path_success ; run off and form complete pathname | ||
| 243 | |||
| 244 | path_noinit: | ||
| 245 | test DS:arg.argv[0].argflags, MASK path_sep | ||
| 246 | jnz path_failure ; complete pathname specified ==> fail | ||
| 247 | |||
| 248 | mov BH, path_sep_char ; semicolon terminates pathstring | ||
| 249 | mov DX, DS:arg.argv[0].argstartel ; this is where the last element starts | ||
| 250 | sub DX, DS:arg.argv[0].argpointer ; form pointer into EXECPATH, | ||
| 251 | add DX, OFFSET TRANGROUP:EXECPATH ; skipping over drive spec, if any | ||
| 252 | |||
| 253 | path_loop: | ||
| 254 | call path_crunch ; pcrunch(EXECPATH, pathinfo) | ||
| 255 | mov BP, AX ; save filetype code | ||
| 256 | |||
| 257 | lahf ; save flags, just in case | ||
| 258 | or BP, BP ; did path_crunch find anything? | ||
| 259 | jne path_found | ||
| 260 | sahf ; see? needed those flags, after all! | ||
| 261 | jnc path_loop ; is there anything left to the path? | ||
| 262 | |||
| 263 | path_failure: | ||
| 264 | xor AX, AX | ||
| 265 | ;; jmp short path_exit ; 3/3/KK | ||
| 266 | jmp path_exit ;AC000; 3/3/KK | ||
| 267 | |||
| 268 | path_found: ; pathinfo[] points to winner | ||
| 269 | mov DI, OFFSET TRANGROUP:EXECPATH | ||
| 270 | mov CX, pathinfo[4] ; "new" pointer -- end of string | ||
| 271 | mov SI, pathinfo[2] ; "old" pointer -- beginning of string | ||
| 272 | |||
| 273 | ; | ||
| 274 | ; BAS Nov 20/84 | ||
| 275 | ; Look at the pathname and expand . and .. if they are the first element | ||
| 276 | ; in the pathname (after the drive letter) | ||
| 277 | ; | ||
| 278 | push ES | ||
| 279 | push pathinfo[0] | ||
| 280 | pop ES | ||
| 281 | cmp Byte Ptr ES:[SI+2],'.' ; Look for Current dir at start of path | ||
| 282 | jnz path_cpy | ||
| 283 | |||
| 284 | push CX ; Save pointer to end of string | ||
| 285 | mov AL, ES:[SI] | ||
| 286 | mov [DI],AL ; Copy drive letter, :, and root char | ||
| 287 | mov AL, ES:[SI+1] ; to EXECPATH | ||
| 288 | mov [DI+1],AL | ||
| 289 | mov AL,psep_char | ||
| 290 | mov [DI+2],AL | ||
| 291 | push SI ; Save pointer to begining of string | ||
| 292 | mov DL,ES:[SI] ; Convert device letter for cur dir | ||
| 293 | or DL,20h | ||
| 294 | sub DL,"a"-1 | ||
| 295 | mov SI,DI ; pointer to EXECPATH | ||
| 296 | add SI, 3 ; Don't wipe out drive and root info | ||
| 297 | trap Current_dir | ||
| 298 | invoke DStrlen ; Determine length of present info | ||
| 299 | add SI,CX ; Don't copy over drive and root info | ||
| 300 | dec SI | ||
| 301 | mov DI,SI ; Point to end of target string | ||
| 302 | pop SI ; Restore pointer to begining of string | ||
| 303 | add SI, 3 ; Point past drive letter, :, . | ||
| 304 | pop CX ; Restore pointer to end of string | ||
| 305 | |||
| 306 | path_cpy: | ||
| 307 | pop ES | ||
| 308 | sub CX, SI ; yields character count | ||
| 309 | push DS ; time to switch segments | ||
| 310 | push pathinfo[0] ; string lives in this segment | ||
| 311 | pop DS | ||
| 312 | cld | ||
| 313 | ;; rep movsb 3/3/KK ; copy the prefix path into EXECPATH | ||
| 314 | |||
| 315 | Kloop: ;AN000; 3/3/KK | ||
| 316 | lodsb ;AN000; 3/3/KK | ||
| 317 | stosb ;AN000; 3/3/KK | ||
| 318 | invoke testkanj ;AN000; 3/3/KK | ||
| 319 | jz NotKanj1 ;AN000; 3/3/KK | ||
| 320 | dec cx ;AN000; 3/3/KK | ||
| 321 | JCXZ PopDone ;AN000; Ignore boundary error 3/3/KK | ||
| 322 | movsb ;AN000; 3/3/KK | ||
| 323 | dec cx ;AN000; 3/3/KK | ||
| 324 | cmp cx,1 ;AN000; One char (the terminator) left ? 3/3/KK | ||
| 325 | ja Kloop ;AN000; no. 3/3/KK | ||
| 326 | |||
| 327 | PopDone: ;AN000; 3/3/KK | ||
| 328 | POP DS ;AN000; Yes ES:DI->terminator, last char is 3/3/KK | ||
| 329 | mov AL, psep_char ;AN000; KANJI 3/3/KK | ||
| 330 | jmp Short path_store ;AN000; 3/3/KK | ||
| 331 | |||
| 332 | NotKanj1: | ||
| 333 | loop Kloop | ||
| 334 | pop DS ; return to our segment | ||
| 335 | dec DI ; overwrite terminator | ||
| 336 | mov AL, psep_char ; with a pathname separator | ||
| 337 | cmp al,byte ptr [di-1] | ||
| 338 | jz path_success | ||
| 339 | |||
| 340 | path_store: ;AN000; 3/3/KK | ||
| 341 | stosb | ||
| 342 | |||
| 343 | path_success: | ||
| 344 | mov SI, OFFSET TRANGROUP:search_best_buf | ||
| 345 | xor CX, CX | ||
| 346 | |||
| 347 | path_succ_loop: | ||
| 348 | lodsb ; append winning filename to path | ||
| 349 | stosb ; (including terminating null) | ||
| 350 | or al,al | ||
| 351 | jnz path_succ_loop | ||
| 352 | mov AX, BP ; retrieve filetype code | ||
| 353 | |||
| 354 | path_exit: | ||
| 355 | popf | ||
| 356 | pop BP | ||
| 357 | pop DI | ||
| 358 | pop SI ; chill out... | ||
| 359 | pop DX | ||
| 360 | pop CX | ||
| 361 | pop BX | ||
| 362 | ret | ||
| 363 | EndProc Path_Search | ||
| 364 | |||
| 365 | break <Store_Pchar> | ||
| 366 | ;---------------------------------------------------------------------------- | ||
| 367 | ; STORE_PCHAR determines the pathname-element separator and squirrels | ||
| 368 | ; it away. In other words, must we say '/bin/ls' or '\bin\ls'? | ||
| 369 | ; ENTRY: | ||
| 370 | ; EXIT: | ||
| 371 | ; NOTE(S): | ||
| 372 | ; * Uses <psep_char>, defined in <path_search>. | ||
| 373 | ;--------------- | ||
| 374 | ;--------------- | ||
| 375 | Procedure Store_PChar,NEAR | ||
| 376 | ;--------------- | ||
| 377 | |||
| 378 | push AX | ||
| 379 | mov AL, '/' ; is the pathname-element separator | ||
| 380 | invoke pathchrcmp ; a regular slash? | ||
| 381 | jz store_slash ; if yes, remember slash | ||
| 382 | mov al,'\' | ||
| 383 | mov [psep_char], al ; otherwise, remember back-slash | ||
| 384 | pop ax | ||
| 385 | ret | ||
| 386 | |||
| 387 | store_slash: | ||
| 388 | mov [psep_char], al | ||
| 389 | pop ax | ||
| 390 | return | ||
| 391 | ;--------------- | ||
| 392 | EndProc Store_Pchar | ||
| 393 | ;---------------------------------------------------------------------------- | ||
| 394 | |||
| 395 | break <Path_Crunch> | ||
| 396 | ;---------------------------------------------------------------------------- | ||
| 397 | ; PATH_CRUNCH takes a prefix from a prefix string, and a suffix from | ||
| 398 | ; EXECPATH, and smooshes them into tpbuf. The caller may supply an | ||
| 399 | ; additional separator to use for breaking up the path-string. Null is the | ||
| 400 | ; default. Once the user-string has been formed, search is invoked to see | ||
| 401 | ; what's out there. | ||
| 402 | ; ENTRY: | ||
| 403 | ; BH -- additional terminator character | ||
| 404 | ; SI -- pointer into pathstring to be dissected | ||
| 405 | ; DX -- pointer to stripped filename | ||
| 406 | ; EXIT: | ||
| 407 | ; AX -- non-zero (file type), zero (nothing found) | ||
| 408 | ; SI -- moves along pathstring from call to call | ||
| 409 | ; [search_best_buf] -- name of best file (AX non-zero) | ||
| 410 | ; [tpbuf] -- clobbered | ||
| 411 | ; NOTE(S): | ||
| 412 | ; * Implicit in this code is the ability to specify when to search | ||
| 413 | ; the current directory (if at all) through the PATH defined by | ||
| 414 | ; the user, a la UNIX (e.g., PATH=;c:\bin;c:\etc searches the | ||
| 415 | ; current directory before the bin and etc directories of drive c). | ||
| 416 | ;--------------- | ||
| 417 | Procedure Path_Crunch,NEAR | ||
| 418 | ;--------------- | ||
| 419 | push BX | ||
| 420 | push CX | ||
| 421 | push DX | ||
| 422 | push DI | ||
| 423 | push SI | ||
| 424 | pushf | ||
| 425 | call store_pchar ; figure out pathname separator | ||
| 426 | mov DI, OFFSET TRANGROUP:tpbuf ; destination of concatenated string | ||
| 427 | mov SI, pathinfo[4] ; "new" pointer to start with | ||
| 428 | mov pathinfo[2], SI ; becomes "old" pointer | ||
| 429 | push DS ; save old segment pointer | ||
| 430 | push pathinfo[0] ; replace with pointer to userpath's | ||
| 431 | pop DS ; segment | ||
| 432 | xor cl,cl ;AN000; clear flag for later use 3/3/KK | ||
| 433 | |||
| 434 | path_cr_copy: | ||
| 435 | lodsb ; get a pathname byte | ||
| 436 | or al,al ; check for terminator(s) | ||
| 437 | jz path_seg ; null terminates segment & pathstring | ||
| 438 | cmp AL, BH | ||
| 439 | jz path_seg ; BH terminates a pathstring segment | ||
| 440 | invoke testkanj ;AN000; 3/3/KK | ||
| 441 | jz NotKanj2 ;AN000; 3/3/KK | ||
| 442 | stosb ;AN000; 3/3/KK | ||
| 443 | movsb ;AN000; 3/3/KK | ||
| 444 | MOV CL,1 ;AN000; CL=1 means latest stored char is DBCS 3/3/KK | ||
| 445 | jmp path_cr_copy ;AN000; 3/3/KK | ||
| 446 | |||
| 447 | NotKanj2: ;AN000; 3/3/KK | ||
| 448 | xor cl,cl ;AN000; CL=0 means latest stored char is SBCS 3/3/KK | ||
| 449 | stosb ; save byte in concat buffer | ||
| 450 | jmp path_cr_copy ; loop until we see a terminator | ||
| 451 | |||
| 452 | path_seg: | ||
| 453 | pop DS ; restore old data segment | ||
| 454 | mov pathinfo[4], SI ; save "new" pointer for next time | ||
| 455 | mov BL, AL ; remember if we saw null or not... | ||
| 456 | ;;; REMOVE NEXT 3 LINES FOR CURDIR SPEC | ||
| 457 | xor AX, AX ; in case nothing in pathstr... | ||
| 458 | cmp DI, OFFSET TRANGROUP:tpbuf ; was there really anything in pathstr? | ||
| 459 | je path_cr_leave ; if nothing was copied, pathstr empty | ||
| 460 | |||
| 461 | path_cr_look: ; form complete pathname | ||
| 462 | mov al, psep_char ; add pathname separator for suffix | ||
| 463 | or cl,cl ;AN000; 3/3/KK | ||
| 464 | jnz path_cr_store ;AN000; this is a trailing byte of ECS code 3/3/KK | ||
| 465 | cmp al,byte ptr [di-1] | ||
| 466 | jz path_cr_l1 | ||
| 467 | |||
| 468 | path_cr_store: ;AN000; 3/3/KK | ||
| 469 | stosb | ||
| 470 | |||
| 471 | path_cr_l1: | ||
| 472 | mov SI, DX | ||
| 473 | |||
| 474 | path_cr_l2: | ||
| 475 | lodsb ; tack the stripped filename onto | ||
| 476 | stosb ; the end of the path, up to and | ||
| 477 | or AL, AL ; including the terminating null | ||
| 478 | jnz path_cr_l2 | ||
| 479 | mov DX, OFFSET TRANGROUP:tpbuf ; and look for an appropriate file... | ||
| 480 | mov [search_error], OFFSET TRANGROUP:BADPMES_ptr | ||
| 481 | invoke search ; results are in AX & search_best_buf | ||
| 482 | |||
| 483 | path_cr_leave: | ||
| 484 | or BL, BL ; did we finish off the pathstring? | ||
| 485 | jz path_cr_empty ; null in BL means all gone... | ||
| 486 | popf ; otherwise, plenty left | ||
| 487 | clc | ||
| 488 | jmp short path_cr_exit | ||
| 489 | |||
| 490 | path_cr_empty: | ||
| 491 | popf | ||
| 492 | stc | ||
| 493 | |||
| 494 | path_cr_exit: | ||
| 495 | pop SI | ||
| 496 | pop DI | ||
| 497 | pop DX | ||
| 498 | pop CX | ||
| 499 | pop BX | ||
| 500 | ret | ||
| 501 | ;--------------- | ||
| 502 | EndProc Path_Crunch | ||
| 503 | ;---------------------------------------------------------------------------- | ||
| 504 | |||
| 505 | |||
| 506 | trancode ends | ||
| 507 | END | ||
diff --git a/v4.0/src/CMD/COMMAND/PATH2.ASM b/v4.0/src/CMD/COMMAND/PATH2.ASM new file mode 100644 index 0000000..8f8d8b8 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/PATH2.ASM | |||
| @@ -0,0 +1,458 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)path2.asm 1.1 85/05/14 | ||
| 3 | ; SCCSID = @(#)path2.asm 1.1 85/05/14 | ||
| 4 | .sall | ||
| 5 | .xlist | ||
| 6 | .xcref | ||
| 7 | INCLUDE DOSSYM.INC | ||
| 8 | include comsw.asm | ||
| 9 | include comseg.asm | ||
| 10 | include comequ.asm | ||
| 11 | .list | ||
| 12 | .cref | ||
| 13 | |||
| 14 | |||
| 15 | DATARES SEGMENT PUBLIC BYTE | ||
| 16 | EXTRN FORFLAG:BYTE | ||
| 17 | DATARES ENDS | ||
| 18 | |||
| 19 | |||
| 20 | break <Path.Asm> | ||
| 21 | ;---------------------------------------------------------------------------- | ||
| 22 | ; PATH.ASM contains the routines to perform pathname incovation. Path and | ||
| 23 | ; Parse share a temporary buffer and argv[] definitions. <Path_Search>, | ||
| 24 | ; given a pathname, attempts to find a corresponding executable or batch | ||
| 25 | ; file on disk. Directories specified in the user's search path will be | ||
| 26 | ; searched for a matching file, if a match is not found in the current | ||
| 27 | ; directory and if the pathname is actually only an MSDOS filename. | ||
| 28 | ; <Path_Search> assumes that the parsed command name can be found in | ||
| 29 | ; argv[0] -- in other words, <Parseline> should be executed prior to | ||
| 30 | ; <Path_Search>. Alternatively, the command name and appropriate | ||
| 31 | ; information could be placed in argv[0], or <Path_Search> could be | ||
| 32 | ; (easily) modified to make no assumptions about where its input is found. | ||
| 33 | ; Please find enclosed yet another important routine, <Save_Args>, which | ||
| 34 | ; places the entire arg/argv[]/argbuf structure on a piece of newly | ||
| 35 | ; allocated memory. This is handy for for-loop processing, and anything | ||
| 36 | ; else that wants to save the whole shebang and then process other command | ||
| 37 | ; lines. | ||
| 38 | ; | ||
| 39 | ; Alan L, OS/MSDOS August 15, 1983 | ||
| 40 | ; | ||
| 41 | ; ENTRY: | ||
| 42 | ; <Path_Search>: argv[0]. | ||
| 43 | ; <Save_Args>: bytes to allocate in addition to arg structure | ||
| 44 | ; EXIT: | ||
| 45 | ; <Path_Search>: success flag, best pathname match in EXECPATH. | ||
| 46 | ; <Save_Args>: success flag, segment address of new memory | ||
| 47 | ; NOTE(S): | ||
| 48 | ; * <Argv_calc> handily turns an array index into an absolute pointer. | ||
| 49 | ; The computation depends on the size of an argv[] element (arg_ele). | ||
| 50 | ; * <Parseline> calls <cparse> for chunks of the command line. <Cparse> | ||
| 51 | ; does not function as specified; see <Parseline> for more details. | ||
| 52 | ; * <Parseline> now knows about the flags the internals of COMMAND.COM | ||
| 53 | ; need to know about. This extra information is stored in a switch_flag | ||
| 54 | ; word with each command-line argument; the switches themselves will not | ||
| 55 | ; appear in the resulting arg structure. | ||
| 56 | ; * With the exception of CARRY, flags are generally preserved across calls. | ||
| 57 | ;--------------- | ||
| 58 | ; CONSTANTS: | ||
| 59 | ;--------------- | ||
| 60 | DEBUGx equ FALSE ; prints out debug info | ||
| 61 | ;--------------- | ||
| 62 | ; DATA: | ||
| 63 | ;--------------- | ||
| 64 | |||
| 65 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 66 | EXTRN arg:byte | ||
| 67 | EXTRN BADPMES_ptr:word | ||
| 68 | EXTRN curdrv:byte | ||
| 69 | EXTRN EXECPATH:byte | ||
| 70 | EXTRN ext_entered:byte ;AN005; | ||
| 71 | EXTRN fbuf:byte | ||
| 72 | EXTRN pathinfo:word | ||
| 73 | EXTRN psep_char:byte | ||
| 74 | EXTRN string_ptr_2:word | ||
| 75 | EXTRN tpbuf:byte | ||
| 76 | TRANSPACE ENDS | ||
| 77 | |||
| 78 | TRANCODE SEGMENT PUBLIC BYTE ;AC000; | ||
| 79 | |||
| 80 | assume cs:trangroup, ds:trangroup, es:trangroup, ss:nothing | ||
| 81 | |||
| 82 | |||
| 83 | break <Search> | ||
| 84 | ;---------------------------------------------------------------------------- | ||
| 85 | ; SEARCH, when given a pathname, attempts to find a file with | ||
| 86 | ; one of the following extensions: .com, .exe, .bat (highest to | ||
| 87 | ; lowest priority). Where conflicts arise, the extension with | ||
| 88 | ; the highest priority is favored. | ||
| 89 | ; ENTRY: | ||
| 90 | ; DX -- pointer to null-terminated pathname | ||
| 91 | ; fbuf -- dma buffer for findfirst/next | ||
| 92 | ; EXIT: | ||
| 93 | ; AX -- 8) file found with .com extension | ||
| 94 | ; 4) file found with .exe extension | ||
| 95 | ; 2) file found with .bat extension | ||
| 96 | ; 0) no such file to be found | ||
| 97 | ; (if AX is non-zero:) | ||
| 98 | ; [search_best] identical to AX | ||
| 99 | ; [search_best_buf] null-terminated filename | ||
| 100 | ; NOTES: | ||
| 101 | ; 1) Requires caller to have allocated a dma buffer and executed a setdma. | ||
| 102 | ;--------------- | ||
| 103 | ; CONSTANTS: | ||
| 104 | ;--------------- | ||
| 105 | search_file_not_found equ 0 | ||
| 106 | search_com equ 8 | ||
| 107 | search_exe equ 4 | ||
| 108 | search_bat equ 2 | ||
| 109 | fname_len equ 8 | ||
| 110 | fname_max_len equ 13 | ||
| 111 | dot equ '.' | ||
| 112 | wildchar equ '?' | ||
| 113 | |||
| 114 | ;--------------- | ||
| 115 | ; DATA: | ||
| 116 | ;--------------- | ||
| 117 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 118 | EXTRN search_best:byte | ||
| 119 | EXTRN search_best_buf:byte | ||
| 120 | EXTRN search_curdir_buf:byte | ||
| 121 | EXTRN search_error:word | ||
| 122 | TRANSPACE ENDS | ||
| 123 | |||
| 124 | ;--------------- | ||
| 125 | Procedure Search,NEAR | ||
| 126 | ;--------------- | ||
| 127 | push CX | ||
| 128 | push DX | ||
| 129 | push DI | ||
| 130 | push SI | ||
| 131 | pushf | ||
| 132 | |||
| 133 | push DX ; check drivespec (save pname ptr) | ||
| 134 | mov DI, DX ; working copy of pathname | ||
| 135 | mov SI, OFFSET TRANGROUP:search_curdir_buf | ||
| 136 | xor DX, DX ; zero means current drive | ||
| 137 | cmp BYTE PTR [DI+1],':' ; is there a drive spec? | ||
| 138 | jne search_dir_check | ||
| 139 | mov DL, [DI] ; get the drive byte | ||
| 140 | and DL, NOT 20H ; uppercase the sucker | ||
| 141 | sub DL, '@' ; and convert to drive number | ||
| 142 | |||
| 143 | search_dir_check: | ||
| 144 | trap Current_Dir ; can we get the drive's current | ||
| 145 | pop DX ; directory? If we can't we'll | ||
| 146 | jc search_invalid_drive ; assume it's a bad drive... | ||
| 147 | |||
| 148 | mov CX, search_attr ; filetypes to search for | ||
| 149 | trap Find_First ; request first match, if any | ||
| 150 | jc search_no_file | ||
| 151 | mov search_best, search_file_not_found | ||
| 152 | mov [search_best_buf], ANULL ; nothing's been found, yet | ||
| 153 | |||
| 154 | search_loop: | ||
| 155 | call search_ftype ; determine if .com, &c... | ||
| 156 | cmp AL, search_best ; better than what we've found so far? | ||
| 157 | jle search_next ; no, look for another | ||
| 158 | mov search_best, AL ; found something... save its code | ||
| 159 | mov SI, OFFSET TRANGROUP:fbuf.find_buf_pname | ||
| 160 | mov DI, OFFSET TRANGROUP:search_best_buf | ||
| 161 | mov CX, fname_max_len | ||
| 162 | cld | ||
| 163 | rep movsb ; save complete pathname representation | ||
| 164 | cmp AL, search_com ; have we found the best of all? | ||
| 165 | je search_done | ||
| 166 | |||
| 167 | search_next: ; keep on looking | ||
| 168 | mov CX, search_attr | ||
| 169 | trap Find_Next ; next match | ||
| 170 | jnc search_loop | ||
| 171 | |||
| 172 | search_done: ; it's all over with... | ||
| 173 | mov AL, search_best ; pick best to return with | ||
| 174 | cmp ext_entered,1 ;AN005; Did user request a specific ext? | ||
| 175 | jz search_exit ;AN005; no - exit | ||
| 176 | mov al,ext_entered ;AN005; yes - get the real file type back | ||
| 177 | mov search_best,al ;AN005; save the real file type | ||
| 178 | jmp short search_exit | ||
| 179 | |||
| 180 | search_invalid_drive: ; Tell the user path/drive | ||
| 181 | mov DX, [search_error] ; appropriate error message | ||
| 182 | invoke std_printf ; and pretend no file found | ||
| 183 | |||
| 184 | search_no_file: ; couldn't find a match | ||
| 185 | mov AX, search_file_not_found | ||
| 186 | |||
| 187 | search_exit: | ||
| 188 | popf | ||
| 189 | pop SI | ||
| 190 | pop DI | ||
| 191 | pop DX | ||
| 192 | pop CX | ||
| 193 | ret | ||
| 194 | ;--------------- | ||
| 195 | EndProc Search | ||
| 196 | ;---------------------------------------------------------------------------- | ||
| 197 | |||
| 198 | |||
| 199 | break <Search_Ftype> | ||
| 200 | ;---------------------------------------------------------------------------- | ||
| 201 | ; SEARCH_FTYPE determines the type of a file by examining its extension. | ||
| 202 | ; ENTRY: | ||
| 203 | ; fbuf -- dma buffer containing filename | ||
| 204 | ; EXIT: | ||
| 205 | ; AX -- file code, as given in search header | ||
| 206 | ; NOTE(S): | ||
| 207 | ; * Implicit assumption that NULL == search_file_not_found | ||
| 208 | ;--------------- | ||
| 209 | ; DATA: | ||
| 210 | ;--------------- | ||
| 211 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 212 | extrn comext:byte,exeext:byte,batext:byte | ||
| 213 | trandata ends | ||
| 214 | ;--------------- | ||
| 215 | Procedure Search_Ftype,NEAR | ||
| 216 | ;--------------- | ||
| 217 | push DI | ||
| 218 | push si | ||
| 219 | mov AX, ANULL ; find the end of the filename | ||
| 220 | mov DI, OFFSET TRANGROUP:fbuf.find_buf_pname | ||
| 221 | mov CX, fname_max_len | ||
| 222 | cld | ||
| 223 | repnz scasb ; search for the terminating null | ||
| 224 | jnz ftype_exit ; weird... no null byte at end | ||
| 225 | sub di,5 ; . + E + X + T + NULL | ||
| 226 | ; | ||
| 227 | ; Compare .COM | ||
| 228 | ; | ||
| 229 | mov si,offset trangroup:comext | ||
| 230 | mov ax,di | ||
| 231 | cmpsw | ||
| 232 | jnz ftype_exe | ||
| 233 | cmpsw | ||
| 234 | jnz ftype_exe | ||
| 235 | mov AX, search_com ; success! | ||
| 236 | jmp short ftype_exit | ||
| 237 | ; | ||
| 238 | ; Compare .EXE | ||
| 239 | ; | ||
| 240 | |||
| 241 | ftype_exe: ; still looking... now for '.exe' | ||
| 242 | mov di,ax | ||
| 243 | mov si,offset trangroup:exeext | ||
| 244 | cmpsw | ||
| 245 | jnz ftype_bat | ||
| 246 | cmpsw | ||
| 247 | jnz ftype_bat | ||
| 248 | mov AX, search_exe ; success! | ||
| 249 | jmp short ftype_exit | ||
| 250 | ; | ||
| 251 | ; Compare .BAT | ||
| 252 | ; | ||
| 253 | |||
| 254 | ftype_bat: ; still looking... now for '.bat' | ||
| 255 | mov di,ax | ||
| 256 | mov si,offset trangroup:batext | ||
| 257 | cmpsw | ||
| 258 | jnz ftype_fail | ||
| 259 | cmpsw | ||
| 260 | jnz ftype_fail | ||
| 261 | mov AX, search_bat ; success! | ||
| 262 | jmp short ftype_exit | ||
| 263 | |||
| 264 | ftype_fail: ; file doesn't match what we need | ||
| 265 | mov ax,ANULL | ||
| 266 | |||
| 267 | ftype_exit: | ||
| 268 | cmp ext_entered,1 ;AN005; was an extension entered? | ||
| 269 | jz ftype_done ;AN005; no - exit | ||
| 270 | cmp ax,ANULL ;AN005; was any match found | ||
| 271 | jz ftype_done ;AN005; no - exit | ||
| 272 | mov ext_entered,al ;AN005; save the match type found | ||
| 273 | mov AX, search_com ;AN005; send back best was found to stop search | ||
| 274 | |||
| 275 | ftype_done: ;AN005; | ||
| 276 | pop SI | ||
| 277 | pop DI | ||
| 278 | ret | ||
| 279 | |||
| 280 | ;--------------- | ||
| 281 | EndProc Search_Ftype | ||
| 282 | ;---------------------------------------------------------------------------- | ||
| 283 | |||
| 284 | |||
| 285 | break <Strip> | ||
| 286 | ;---------------------------------------------------------------------------- | ||
| 287 | ; STRIP copies the source string (argv[0]) into the destination buffer, | ||
| 288 | ; replacing any extension with wildcards. | ||
| 289 | ; ENTRY: | ||
| 290 | ; BX -- maximum length of destination buffer | ||
| 291 | ; DS:SI -- address of destination buffer | ||
| 292 | ; argv[0] -- command name to be stripped | ||
| 293 | ; EXIT: | ||
| 294 | ; CF -- set if failure, clear if successful | ||
| 295 | ; NOTE(S): | ||
| 296 | ;--------------- | ||
| 297 | Procedure Strip,NEAR | ||
| 298 | ;--------------- | ||
| 299 | push AX | ||
| 300 | push BX | ||
| 301 | push CX | ||
| 302 | push DX | ||
| 303 | push DI | ||
| 304 | push SI | ||
| 305 | pushf | ||
| 306 | |||
| 307 | mov ext_entered,1 ;AN005; assume no extension on file name | ||
| 308 | mov DX, DS:arg.argv[0].argpointer ; save pointer to beginning of argstring | ||
| 309 | mov DI, DS:arg.argv[0].argstartel ; beginning of last pathname element | ||
| 310 | cmp BYTE PTR [DI], 0 ; *STARTEL == NULL means no command | ||
| 311 | jz strip_error | ||
| 312 | mov CX, DX ; compute where end of argstring lies | ||
| 313 | add CX, DS:arg.argv[0].arglen | ||
| 314 | sub CX, DI ; and then find length of last element | ||
| 315 | inc CX ; include null as well | ||
| 316 | mov AL, dot ; let's find the filetype extension | ||
| 317 | cld | ||
| 318 | repnz scasb ; wind up pointing to either null or dot | ||
| 319 | jcxz process_ext ;AN005; if no extension found, just continue | ||
| 320 | mov ext_entered,0 ;AN005; we found an extension | ||
| 321 | mov al,ANULL ;AN005; continue scanning until the | ||
| 322 | repnz scasb ;AN005; end of line is reached. | ||
| 323 | |||
| 324 | process_ext: ;AN005; | ||
| 325 | mov CX, DI ; pointer to end of argstring yields | ||
| 326 | sub CX, DX ; number of bytes to be copied | ||
| 327 | sub BX, 4 ; can argstring fit into dest. buffer? | ||
| 328 | cmp CX, BX | ||
| 329 | jg strip_error ; if not, we must have a bad pathname | ||
| 330 | mov DI, SI ; destination buffer | ||
| 331 | mov SI, DX ; source is beginning of pathname | ||
| 332 | cld | ||
| 333 | rep movsb ; SI=arg,DI=buffer,CX=argend-argbeg | ||
| 334 | cmp ext_entered,1 ;AN005; if an extension was entered | ||
| 335 | jnz skip_wilds ;AN005; don't set up wildcard ext. | ||
| 336 | |||
| 337 | dec DI ; overwrite null or dot | ||
| 338 | stosb ; with a dot | ||
| 339 | mov AL, wildchar ; now add wildcards | ||
| 340 | stosb | ||
| 341 | stosb | ||
| 342 | stosb | ||
| 343 | mov AL, ANULL ; and a terminating null | ||
| 344 | stosb | ||
| 345 | |||
| 346 | skip_wilds: ;AN005; | ||
| 347 | popf | ||
| 348 | clc ; chill out... | ||
| 349 | jmp short strip_exit | ||
| 350 | |||
| 351 | strip_error: | ||
| 352 | popf | ||
| 353 | stc | ||
| 354 | |||
| 355 | strip_exit: | ||
| 356 | pop SI | ||
| 357 | pop DI | ||
| 358 | pop DX | ||
| 359 | pop CX | ||
| 360 | pop BX | ||
| 361 | pop AX | ||
| 362 | ret | ||
| 363 | ;--------------- | ||
| 364 | EndProc Strip | ||
| 365 | ;---------------------------------------------------------------------------- | ||
| 366 | |||
| 367 | |||
| 368 | break <Save_Args> | ||
| 369 | ;---------------------------------------------------------------------------- | ||
| 370 | ; SAVE_ARGS attempts to preserve the existing argv[]/argvcnt/argbuffer | ||
| 371 | ; structure in newly allocated memory. The argv[] structure is found at the | ||
| 372 | ; beginning of this area. The caller indicates how much extra space is | ||
| 373 | ; needed in the resulting structure; Save_Args returns a segment number and | ||
| 374 | ; an offset into that area, indicating where the caller may preserve its own | ||
| 375 | ; data. Note that <argvcnt> can be found at <offset-2>. | ||
| 376 | ; ENTRY: | ||
| 377 | ; BX -- size (in bytes) of extra area to allocate | ||
| 378 | ; EXIT: | ||
| 379 | ; AX -- segment of new area. | ||
| 380 | ; CF -- set if unable to save a copy. | ||
| 381 | ; NOTE(S): | ||
| 382 | ; 1) The allocated area will be AT LEAST the size requested -- since | ||
| 383 | ; the underlying MSDOS call, <alloc> returns an integral number of | ||
| 384 | ; paragraphs. | ||
| 385 | ; 2) It is an error if MSDOS can't allocate AT LEAST as much memory | ||
| 386 | ; as the caller of Save_Args requests. | ||
| 387 | ; 3) AX is undefined if CF indicates an error. | ||
| 388 | ;--------------- | ||
| 389 | Procedure Save_Args,NEAR | ||
| 390 | ;--------------- | ||
| 391 | push BX | ||
| 392 | push CX | ||
| 393 | push DX | ||
| 394 | push DI | ||
| 395 | push SI | ||
| 396 | push BP | ||
| 397 | pushf | ||
| 398 | add BX, SIZE arg_unit + 0FH ; space for arg structure, round up | ||
| 399 | mov CL, 4 ; to paragraph size and convert | ||
| 400 | shr BX, CL ; size in bytes to size in paragraphs | ||
| 401 | trap Alloc | ||
| 402 | jc save_error | ||
| 403 | mov BP, AX ; save segment id | ||
| 404 | push ES ; save TRANGROUP address | ||
| 405 | mov ES, AX ; switch to new memory segment | ||
| 406 | assume ES:nothing | ||
| 407 | mov CX, SIZE arg_unit ; get back structure size | ||
| 408 | xor DI, DI ; destination is new memory area | ||
| 409 | mov SI, OFFSET TRANGROUP:arg ; source is arg structure | ||
| 410 | rep movsb ; move that sucker! | ||
| 411 | mov CX, arg.argvcnt ; adjust argv pointers | ||
| 412 | xor AX, AX ; base address for argv_calc | ||
| 413 | mov SI, OFFSET TRANGROUP:arg.argbuf - OFFSET arg_unit.argbuf | ||
| 414 | |||
| 415 | save_ptr_loop: | ||
| 416 | dec CX ; exhausted all args? | ||
| 417 | jl save_done | ||
| 418 | mov BX, CX ; get arg index and | ||
| 419 | invoke argv_calc ; convert to a pointer | ||
| 420 | mov DX, DS:arg.argv[BX].argpointer | ||
| 421 | sub DX, SI ; adjust argpointer | ||
| 422 | mov ES:argv[BX].argpointer, DX | ||
| 423 | mov DX, DS:arg.argv[BX].argstartel | ||
| 424 | sub DX, SI ; and adjust argstartel | ||
| 425 | mov ES:argv[BX].argstartel, DX | ||
| 426 | mov DX, DS:arg.argv[BX].arg_ocomptr | ||
| 427 | sub DX, SI ; and adjust arg_ocomptr | ||
| 428 | mov ES:argv[BX].arg_ocomptr, DX | ||
| 429 | jmp save_ptr_loop | ||
| 430 | |||
| 431 | save_done: | ||
| 432 | pop ES ; back we go to TRANGROUP | ||
| 433 | assume ES:trangroup | ||
| 434 | mov AX, BP ; restore segment id | ||
| 435 | jmp short save_ok | ||
| 436 | |||
| 437 | save_error: | ||
| 438 | popf | ||
| 439 | stc | ||
| 440 | jmp short save_exit | ||
| 441 | |||
| 442 | save_ok: | ||
| 443 | popf | ||
| 444 | clc | ||
| 445 | save_exit: | ||
| 446 | pop BP | ||
| 447 | pop SI | ||
| 448 | pop DI | ||
| 449 | pop DX | ||
| 450 | pop CX | ||
| 451 | pop BX | ||
| 452 | ret | ||
| 453 | ;--------------- | ||
| 454 | EndProc Save_Args | ||
| 455 | ;---------------------------------------------------------------------------- | ||
| 456 | |||
| 457 | trancode ends | ||
| 458 | END | ||
diff --git a/v4.0/src/CMD/COMMAND/RDATA.ASM b/v4.0/src/CMD/COMMAND/RDATA.ASM new file mode 100644 index 0000000..65fd4bb --- /dev/null +++ b/v4.0/src/CMD/COMMAND/RDATA.ASM | |||
| @@ -0,0 +1,611 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)rdata.asm 4.2 85/09/22 | ||
| 3 | ; SCCSID = @(#)rdata.asm 4.2 85/09/22 | ||
| 4 | TITLE COMMAND Resident DATA | ||
| 5 | |||
| 6 | include comsw.asm | ||
| 7 | .xlist | ||
| 8 | .xcref | ||
| 9 | include comseg.asm | ||
| 10 | .list | ||
| 11 | .cref | ||
| 12 | |||
| 13 | ; | ||
| 14 | ; Equates for initialization (from COMEQU) | ||
| 15 | ; | ||
| 16 | initInit equ 01h ; initialization in progress | ||
| 17 | initSpecial equ 02h ; in initialization time/date routine | ||
| 18 | initCtrlC equ 04h ; already in ^C handler | ||
| 19 | |||
| 20 | Tokenized = FALSE | ||
| 21 | |||
| 22 | CODERES SEGMENT PUBLIC BYTE ;AC000; | ||
| 23 | PUBLIC RSTACK | ||
| 24 | EXTRN EXT_EXEC:NEAR | ||
| 25 | EXTRN THEADFIX:NEAR | ||
| 26 | EXTRN TREMCHECK:NEAR | ||
| 27 | |||
| 28 | DB (80H - 3) DUP (?) | ||
| 29 | |||
| 30 | RSTACK LABEL WORD | ||
| 31 | |||
| 32 | CODERES ENDS | ||
| 33 | |||
| 34 | TRANCODE SEGMENT PUBLIC BYTE ;AC000; | ||
| 35 | EXTRN COMMAND:NEAR | ||
| 36 | TRANCODE ENDS | ||
| 37 | |||
| 38 | ; Data for resident portion | ||
| 39 | |||
| 40 | DATARES SEGMENT PUBLIC BYTE | ||
| 41 | |||
| 42 | IF Tokenized | ||
| 43 | PUBLIC IOTYP | ||
| 44 | PUBLIC MESADD | ||
| 45 | ENDIF | ||
| 46 | |||
| 47 | PUBLIC abort_char | ||
| 48 | PUBLIC append_flag ;AN020; | ||
| 49 | PUBLIC append_state ;AN020; | ||
| 50 | PUBLIC BADFAT_BLOCK ;AC000; | ||
| 51 | PUBLIC BADFAT_OP_SEG ;AC000; | ||
| 52 | PUBLIC BADFAT_SUBST ;AC000; | ||
| 53 | PUBLIC BATCH | ||
| 54 | PUBLIC Batch_Abort | ||
| 55 | PUBLIC call_batch_flag | ||
| 56 | PUBLIC call_flag | ||
| 57 | PUBLIC CDEVAT ;AC000; | ||
| 58 | PUBLIC COM_FCB1 | ||
| 59 | PUBLIC COM_FCB2 | ||
| 60 | PUBLIC COM_PTR | ||
| 61 | PUBLIC COM_XLAT_ADDR | ||
| 62 | PUBLIC COMDRV | ||
| 63 | PUBLIC COMPRMT1_BLOCK ;AC000; | ||
| 64 | PUBLIC COMPRMT1_SEG ;AC000; | ||
| 65 | PUBLIC COMPRMT1_SEG2 ;AC000; | ||
| 66 | PUBLIC COMPRMT1_SUBST ;AC000; | ||
| 67 | PUBLIC COMSPEC | ||
| 68 | PUBLIC crit_msg_off ;AC000; | ||
| 69 | PUBLIC crit_msg_seg ;AC000; | ||
| 70 | PUBLIC critical_msg_start ;AC000; | ||
| 71 | PUBLIC comspec_print | ||
| 72 | PUBLIC comspec_end | ||
| 73 | PUBLIC cpdrv | ||
| 74 | PUBLIC crit_err_INFO | ||
| 75 | PUBLIC DATARESEND | ||
| 76 | PUBLIC dbcs_vector_addr ;AN000; | ||
| 77 | PUBLIC DEVE_OP_OFF ;AC000; | ||
| 78 | PUBLIC DEVE_OP_SEG ;AC000; | ||
| 79 | PUBLIC DEVE_OP_SEG2 ;AC000; | ||
| 80 | PUBLIC DEVEMES_BLOCK ;AC000; | ||
| 81 | PUBLIC DEVEMES_SUBST ;AC000; | ||
| 82 | PUBLIC DEVENAM ;AC000; | ||
| 83 | PUBLIC DISP_CLASS ;AN000; | ||
| 84 | PUBLIC DRVLET | ||
| 85 | PUBLIC DRVNUM_BLOCK ;AC000; | ||
| 86 | PUBLIC DRVNUM_OP_OFF ;AC000; | ||
| 87 | PUBLIC DRVNUM_OP_SEG ;AC000; | ||
| 88 | PUBLIC DRVNUM_OP_SEG2 ;AC000; | ||
| 89 | PUBLIC DRVNUM_SUBST ;AC000; | ||
| 90 | PUBLIC ECHOFLAG | ||
| 91 | PUBLIC ENVIRSEG | ||
| 92 | PUBLIC ERR15_OP_SEG ;AC000; | ||
| 93 | PUBLIC ERR15_OP_SEG2 ;AC000; | ||
| 94 | PUBLIC ERR15_OP_SEG3 ;AC000; | ||
| 95 | PUBLIC ERR15MES_BLOCK ;AC000; | ||
| 96 | PUBLIC ERR15MES_SUBST ;AC000; | ||
| 97 | PUBLIC ERRCD_24 | ||
| 98 | PUBLIC ErrType | ||
| 99 | PUBLIC EXEC_BLOCK | ||
| 100 | PUBLIC EXECEMES_BLOCK ;AC000; | ||
| 101 | PUBLIC EXECEMES_SUBST ;AC000; | ||
| 102 | PUBLIC EXECEMES_OFF ;AC000; | ||
| 103 | PUBLIC EXECEMES_SEG ;AC000; | ||
| 104 | PUBLIC EXTCOM | ||
| 105 | PUBLIC extended_msg_start ;AN000; | ||
| 106 | PUBLIC extmsgend ;AN000; | ||
| 107 | PUBLIC fail_char ;AC000; | ||
| 108 | PUBLIC fFail | ||
| 109 | PUBLIC FORFLAG | ||
| 110 | PUBLIC forptr | ||
| 111 | PUBLIC fucase_addr ;AN000; | ||
| 112 | PUBLIC HANDLE01 | ||
| 113 | PUBLIC IFFlag | ||
| 114 | PUBLIC ignore_char | ||
| 115 | PUBLIC In_Batch | ||
| 116 | PUBLIC InitFlag | ||
| 117 | PUBLIC INPIPEPTR | ||
| 118 | PUBLIC INT_2E_RET | ||
| 119 | PUBLIC IO_SAVE | ||
| 120 | PUBLIC LOADING | ||
| 121 | PUBLIC LTPA | ||
| 122 | PUBLIC MEMSIZ | ||
| 123 | ;AD054; PUBLIC MESBAS ;AC000; | ||
| 124 | PUBLIC MYSEG | ||
| 125 | PUBLIC MYSEG1 | ||
| 126 | PUBLIC MYSEG2 | ||
| 127 | PUBLIC nest | ||
| 128 | PUBLIC next_batch | ||
| 129 | PUBLIC no_char | ||
| 130 | PUBLIC NULLFLAG | ||
| 131 | PUBLIC NUMBER_SUBST ;AN000; | ||
| 132 | PUBLIC olderrno | ||
| 133 | PUBLIC OldTerm | ||
| 134 | PUBLIC OUTPIPEPTR | ||
| 135 | PUBLIC PARENT | ||
| 136 | ;AD060; PUBLIC pars_msg_off ;AN000; | ||
| 137 | ;AD060; PUBLIC pars_msg_seg ;AN000; | ||
| 138 | PUBLIC parse_msg_start ;AN000; | ||
| 139 | PUBLIC PERMCOM | ||
| 140 | PUBLIC PIPE1 | ||
| 141 | PUBLIC pipe1t | ||
| 142 | PUBLIC PIPE2 | ||
| 143 | PUBLIC pipe2t | ||
| 144 | PUBLIC PIPEFILES | ||
| 145 | PUBLIC PIPEFLAG | ||
| 146 | PUBLIC PIPEPTR | ||
| 147 | PUBLIC PIPESTR | ||
| 148 | PUBLIC RDIRCHAR | ||
| 149 | PUBLIC RE_OUT_APP | ||
| 150 | PUBLIC RE_OUTSTR | ||
| 151 | PUBLIC RemMsg | ||
| 152 | PUBLIC resmsgend ;AN000; | ||
| 153 | PUBLIC RES_TPA | ||
| 154 | PUBLIC RESTDIR | ||
| 155 | PUBLIC ResTest | ||
| 156 | PUBLIC RETCODE | ||
| 157 | PUBLIC retry_char | ||
| 158 | PUBLIC rsrc_xa_seg ;AN030; | ||
| 159 | PUBLIC RSWITCHAR | ||
| 160 | PUBLIC SAVE_PDB | ||
| 161 | PUBLIC SINGLECOM | ||
| 162 | PUBLIC SUM | ||
| 163 | PUBLIC SUPPRESS | ||
| 164 | PUBLIC TRANS | ||
| 165 | PUBLIC TranVarEnd | ||
| 166 | PUBLIC TRANVARS | ||
| 167 | PUBLIC TRNSEG | ||
| 168 | PUBLIC TrnMvFlg | ||
| 169 | PUBLIC VERVAL | ||
| 170 | PUBLIC VolName | ||
| 171 | PUBLIC VOLSER ;AN000; | ||
| 172 | PUBLIC yes_char | ||
| 173 | |||
| 174 | ;AD054;MESBAS DW 19 ;AC000; error_write_protect | ||
| 175 | ;AD054; DW 20 ;AC000; error_bad_unit | ||
| 176 | ;AD054; DW 21 ;AC000; error_not_ready | ||
| 177 | ;AD054; DW 22 ;AC000; error_bad_command | ||
| 178 | ;AD054; DW 23 ;AC000; error_CRC | ||
| 179 | ;AD054; DW 24 ;AC000; error_bad_length | ||
| 180 | ;AD054; DW 25 ;AC000; error_Seek | ||
| 181 | ;AD054; DW 26 ;AC000; error_not_DOS_disk | ||
| 182 | ;AD054; DW 27 ;AC000; error_sector_not_found | ||
| 183 | ;AD054; DW 28 ;AC000; error_out_of_paper | ||
| 184 | ;AD054; DW 29 ;AC000; error_write_fault | ||
| 185 | ;AD054; DW 30 ;AC000; error_read_fault | ||
| 186 | ;AD054; DW 31 ;AC000; error_gen_failure | ||
| 187 | ;AD054; DW 32 ;AC000; error_sharing_violation | ||
| 188 | ;AD054; DW 33 ;AC000; error_lock_violation | ||
| 189 | ;AD054; DW 34 ;AC000; error_wrong_disk | ||
| 190 | ;AD054; DW 35 ;AC000; error_FCB_unavailable | ||
| 191 | ;AD054; DW 36 ;AC000; error_sharing_buffer_exceeded | ||
| 192 | ;AD054; DW 37 ;AC000; error_code_page_mismatch | ||
| 193 | ;AD054; DW 38 ;AC026; error_out_of_input | ||
| 194 | ;AD054; DW 39 ;AN026; error_insufficient_disk_space | ||
| 195 | |||
| 196 | |||
| 197 | |||
| 198 | IF Tokenized | ||
| 199 | MESADD LABEL WORD | ||
| 200 | DW OFFSET ResGroup:NEWLIN ;"0" | ||
| 201 | DW OFFSET ResGroup:COM$1 ;"1" | ||
| 202 | DW OFFSET ResGroup:ERR3 ;"2" | ||
| 203 | DW OFFSET ResGroup:ALLOC$3 ;"3" | ||
| 204 | DW OFFSET ResGroup:FILE$4 ;"4" | ||
| 205 | DW OFFSET ResGroup:RROR$5 ;"5" | ||
| 206 | DW OFFSET ResGroup:CAN$6 ;"6" | ||
| 207 | DW OFFSET ResGroup:EMORY$7 ;"7" | ||
| 208 | DW OFFSET ResGroup:BAT$8 ;"8" | ||
| 209 | DW OFFSET ResGroup:INS$9 ;"9" | ||
| 210 | |||
| 211 | ERR0 DB "Write protec","t"+80h | ||
| 212 | ERR1 DB "Bad uni","t"+80h | ||
| 213 | ERR2 DB "Not read","y"+80h | ||
| 214 | ERR3 DB "Bad command"," "+80h | ||
| 215 | ERR4 DB "Dat","a"+80h | ||
| 216 | ERR5 DB "Bad call forma","t"+80h | ||
| 217 | ERR6 DB "See","k"+80h | ||
| 218 | ERR7 DB "Non-DOS dis","k"+80h | ||
| 219 | ERR8 DB "Sector not foun","d"+80h | ||
| 220 | ERR9 DB "No pape","r"+80h | ||
| 221 | ERR10 DB "Write faul","t"+80h | ||
| 222 | ERR11 DB "Read faul","t"+80h | ||
| 223 | ERR12 DB "General Failur","e"+80h | ||
| 224 | ERR13 DB "Sharing Violatio","n"+80h | ||
| 225 | ERR14 DB "Lock Violatio","n"+80h | ||
| 226 | ERR15 DB "Invalid Disk Chang","e"+80h | ||
| 227 | ERR16 DB "FCB unavailabl","e"+80h | ||
| 228 | ERR17 DB "Sharing buffer exceede","d"+80h | ||
| 229 | |||
| 230 | ;--- Extra message for error 15 | ||
| 231 | Err15Mes db "Please Insert disk " | ||
| 232 | VolName db 11 dup(?) | ||
| 233 | db 13,10,"$" | ||
| 234 | |||
| 235 | MREAD DB "read" | ||
| 236 | MWRITE DB "writ" | ||
| 237 | ERRMES DB " e5" | ||
| 238 | IOTYP DB "writin","g"+80h | ||
| 239 | DRVNUM DB " drive " | ||
| 240 | DRVLET DB "A" | ||
| 241 | NEWLIN DB 13,10+80h | ||
| 242 | DEVEMES DB " device " | ||
| 243 | DEVENAM DB 8 DUP (?) | ||
| 244 | DB 13,10,"$" ;Must be $ terminated | ||
| 245 | COM$1 DB " COMMAN","D"+80h | ||
| 246 | ALLOC$3 DB " allocation"," "+80h | ||
| 247 | FILE$4 DB " file"," "+80h | ||
| 248 | RROR$5 DB "rror"," "+80h | ||
| 249 | CAN$6 DB "Cannot"," "+80h | ||
| 250 | EMORY$7 DB "emor","y"+80h | ||
| 251 | BAT$8 DB " batc","h"+80h | ||
| 252 | INS$9 DB "Inser","t"+80h | ||
| 253 | |||
| 254 | |||
| 255 | CDEVAT DB ? | ||
| 256 | BADFAT DB "0File 3table bad",","+80h | ||
| 257 | COMBAD DB "0Invalid1.COM","0"+80h | ||
| 258 | comprmt1 DB "9 disk with"," "+80h | ||
| 259 | comprmt2 DB " in drive " | ||
| 260 | cpdrv DB " " | ||
| 261 | PROMPT DB "0and strike any key when ready","0"+80h | ||
| 262 | ENDBATMES DB "0Terminate8 job (Y/N)?"," "+80h | ||
| 263 | EXECEMES DB "EXEC failure","0"+80h | ||
| 264 | EXEBAD DB "E5in EXE4","0"+80h | ||
| 265 | TOOBIG DB "Program too big to fit in m7","0"+80h | ||
| 266 | NOHANDMES DB "0No free4handle","s"+80h | ||
| 267 | BMEMMES DB "0M73e","5"+80h | ||
| 268 | HALTMES DB "06load1, system halte","d"+80h | ||
| 269 | FRETMES DB "06start1, exiting","0"+80h | ||
| 270 | RBADNAM DB "2or4name","0"+80h | ||
| 271 | AccDen DB "Access Denied","0"+80h | ||
| 272 | Patricide DB 13,10,"Top level process aborted, cannot continue."," "+80h | ||
| 273 | COMSPEC_PRINT DW ? | ||
| 274 | |||
| 275 | ELSE | ||
| 276 | |||
| 277 | |||
| 278 | parm_block_size EQU 11 ;AN000; size of message subst block | ||
| 279 | blank EQU " " ;AN000; blank character | ||
| 280 | |||
| 281 | DISP_CLASS DB -1 ;AN000; utility message class | ||
| 282 | NUMBER_SUBST DB 0 ;AN000; number of message substitutions - def 0 | ||
| 283 | |||
| 284 | |||
| 285 | DRVNUM_SUBST db 2 ;AN000; number of subst | ||
| 286 | DRVNUM_BLOCK db parm_block_size ;AN000;size of sublist | ||
| 287 | db 0 ;AN000;reserved | ||
| 288 | DRVNUM_OP_OFF dw 0 ;AN000;offset of arg | ||
| 289 | DRVNUM_OP_SEG dw 0 ;AN000;segment of arg | ||
| 290 | db 1 ;AN000;first subst | ||
| 291 | db Char_field_ASCIIZ ;AN000;character string | ||
| 292 | db 128 ;AN000;maximum width | ||
| 293 | db 0 ;AN000;minimum width | ||
| 294 | db blank ;AN000;pad character | ||
| 295 | db parm_block_size ;AN000;size of sublist | ||
| 296 | db 0 ;AN000;reserved | ||
| 297 | dw OFFSET RESGROUP:DRVLET ;AN000;offset of arg | ||
| 298 | DRVNUM_OP_SEG2 dw 0 ;AN000;segment of arg | ||
| 299 | db 2 ;AN000;second subst | ||
| 300 | db Char_field_Char ;AN000;one character | ||
| 301 | db 1 ;AN000;maximum width | ||
| 302 | db 1 ;AN000;minimum width | ||
| 303 | db blank ;AN000;pad character | ||
| 304 | |||
| 305 | DRVLET DB "A" | ||
| 306 | |||
| 307 | DEVEMES_SUBST db 2 ;AN000; number of subst | ||
| 308 | DEVEMES_BLOCK db parm_block_size ;AN000;size of sublist | ||
| 309 | db 0 ;AN000;reserved | ||
| 310 | DEVE_OP_OFF dw 0 ;AN000;offset of arg | ||
| 311 | DEVE_OP_SEG dw 0 ;AN000;segment of arg | ||
| 312 | db 1 ;AN000;first subst | ||
| 313 | db Char_field_ASCIIZ ;AN000;character string | ||
| 314 | db 128 ;AN000;maximum width | ||
| 315 | db 0 ;AN000;minimum width | ||
| 316 | db blank ;AN000;pad character | ||
| 317 | db parm_block_size ;AN000;size of sublist | ||
| 318 | db 0 ;AN000;reserved | ||
| 319 | dw OFFSET RESGROUP:DEVENAM ;AN000;offset of arg | ||
| 320 | DEVE_OP_SEG2 dw 0 ;AN000;segment of arg | ||
| 321 | db 2 ;AN000;second subst | ||
| 322 | db Char_field_ASCIIZ ;AN000;character string | ||
| 323 | db 8 ;AN019;maximum width | ||
| 324 | db 8 ;AN019;minimum width | ||
| 325 | db blank ;AN000;pad character | ||
| 326 | |||
| 327 | DEVENAM DB 8 DUP (?) | ||
| 328 | |||
| 329 | ;--- Extra message for error 15 | ||
| 330 | ERR15MES_SUBST db 3 ;AN000; number of subst | ||
| 331 | ERR15MES_BLOCK db parm_block_size ;AN000;size of sublist | ||
| 332 | db 0 ;AN000;reserved | ||
| 333 | dw OFFSET RESGROUP:VOLNAME ;AN000;offset of arg | ||
| 334 | ERR15_OP_SEG dw 0 ;AN000;segment of arg | ||
| 335 | db 1 ;AN000;first subst | ||
| 336 | db Char_field_ASCIIZ ;AN000;character string | ||
| 337 | db 12 ;AN000;maximum width | ||
| 338 | db 12 ;AN000;minimum width | ||
| 339 | db blank ;AN000;pad character | ||
| 340 | db parm_block_size ;AN000;size of sublist | ||
| 341 | db 0 ;AN000;reserved | ||
| 342 | dw OFFSET RESGROUP:VOLSER+2;AN000;offset of arg | ||
| 343 | ERR15_OP_SEG2 dw 0 ;AN000;segment of arg | ||
| 344 | db 2 ;AN000;second subst | ||
| 345 | db right_align+Bin_Hex_Word ;AN000;long binary to decimal | ||
| 346 | db 4 ;AN000;maximum width | ||
| 347 | db 4 ;AN000;minimum width | ||
| 348 | db "0" ;AN000;pad character | ||
| 349 | db parm_block_size ;AN000;size of sublist | ||
| 350 | db 0 ;AN000;reserved | ||
| 351 | dw OFFSET RESGROUP:VOLSER ;AN000;offset of arg | ||
| 352 | ERR15_OP_SEG3 dw 0 ;AN000;segment of arg | ||
| 353 | db 3 ;AN000;third subst | ||
| 354 | db right_align+Bin_Hex_Word ;AN000;long binary to decimal | ||
| 355 | db 4 ;AN000;maximum width | ||
| 356 | db 4 ;AN000;minimum width | ||
| 357 | db "0" ;AN000;pad character | ||
| 358 | |||
| 359 | ;************************************ | ||
| 360 | ;* DO NOT SEPARATE VOLNAME & VOLSER * | ||
| 361 | ;************************************ | ||
| 362 | ;* | ||
| 363 | VolName DB 11 dup(?) ;* | ||
| 364 | DB 0 ;* | ||
| 365 | VolSer DD 0 ;* | ||
| 366 | ;* | ||
| 367 | ;************************************ | ||
| 368 | |||
| 369 | |||
| 370 | CDEVAT DB ? | ||
| 371 | |||
| 372 | BADFAT_SUBST db 1 ;AN000; number of subst | ||
| 373 | BADFAT_BLOCK db parm_block_size ;AN000;size of sublist | ||
| 374 | db 0 ;AN000;reserved | ||
| 375 | dw OFFSET RESGROUP:DRVLET ;AN000;offset of arg | ||
| 376 | BADFAT_OP_SEG dw 0 ;AN000;segment of arg | ||
| 377 | db 1 ;AN000;first subst | ||
| 378 | db Char_field_Char ;AN000;one character | ||
| 379 | db 1 ;AN000;maximum width | ||
| 380 | db 1 ;AN000;minimum width | ||
| 381 | db blank ;AN000;pad character | ||
| 382 | |||
| 383 | |||
| 384 | COMPRMT1_SUBST db 2 ;AN000; number of subst | ||
| 385 | COMPRMT1_BLOCK db parm_block_size ;AN000;size of sublist | ||
| 386 | db 0 ;AN000;reserved | ||
| 387 | COMSPEC_PRINT dw ? ;AN000;offset of arg | ||
| 388 | COMPRMT1_SEG dw 0 ;AN000;segment of arg | ||
| 389 | db 1 ;AN000;first subst | ||
| 390 | db Char_field_ASCIIZ ;AN000;character string | ||
| 391 | db 64 ;AN000;maximum width | ||
| 392 | db 0 ;AN000;minimum width | ||
| 393 | db blank ;AN000;pad character | ||
| 394 | db parm_block_size ;AN000;size of sublist | ||
| 395 | db 0 ;AN000;reserved | ||
| 396 | dw OFFSET RESGROUP:CPDRV ;AN000;offset of arg | ||
| 397 | COMPRMT1_SEG2 dw 0 ;AN000;segment of arg | ||
| 398 | db 2 ;AN000;second subst | ||
| 399 | db Char_field_Char ;AN000;one character | ||
| 400 | db 1 ;AN000;maximum width | ||
| 401 | db 1 ;AN000;minimum width | ||
| 402 | db blank ;AN000;pad character | ||
| 403 | |||
| 404 | cpdrv DB " " | ||
| 405 | ; | ||
| 406 | ; Exec error messages | ||
| 407 | ; | ||
| 408 | EXECEMES_SUBST db 1 ;AN000; number of subst | ||
| 409 | EXECEMES_BLOCK db parm_block_size ;AN000;size of sublist | ||
| 410 | db 0 ;AN000;reserved | ||
| 411 | EXECEMES_OFF dw 0 ;AN000;offset of arg | ||
| 412 | EXECEMES_SEG dw 0 ;AN000;segment of arg | ||
| 413 | db 1 ;AN000;first subst | ||
| 414 | db Char_field_ASCIIZ ;AN000;character string | ||
| 415 | db 64 ;AN000;maximum width | ||
| 416 | db 0 ;AN000;minimum width | ||
| 417 | db blank ;AN000;pad character | ||
| 418 | |||
| 419 | ; | ||
| 420 | ; These characters MUST remain in order | ||
| 421 | ; | ||
| 422 | abort_char db "A" | ||
| 423 | retry_char db "R" | ||
| 424 | ignore_char db "I" | ||
| 425 | fail_char db "F" | ||
| 426 | yes_char db "Y" | ||
| 427 | no_char db "N" | ||
| 428 | ; | ||
| 429 | ; End of characters that MUST remain in order | ||
| 430 | ; | ||
| 431 | ENDIF | ||
| 432 | |||
| 433 | RemMsg DD ? ;Pointer to message in error 15 | ||
| 434 | ErrType DB ? ; Error message style, 0=old, 1=new | ||
| 435 | |||
| 436 | INT_2E_RET DD ? ; Magic command executer return address | ||
| 437 | SAVE_PDB DW ? | ||
| 438 | PARENT DW ? | ||
| 439 | OldTerm DD ? | ||
| 440 | ERRCD_24 DW ? | ||
| 441 | HANDLE01 DW ? | ||
| 442 | LOADING DB 0 | ||
| 443 | BATCH DW 0 ; Assume no batch mode initially | ||
| 444 | COMSPEC DB 64 DUP(0) | ||
| 445 | comspec_end dw ? | ||
| 446 | TRANS DW OFFSET TRANGROUP:COMMAND | ||
| 447 | TRNSEG DW ? | ||
| 448 | ; BAS DEBUG | ||
| 449 | TrnMvFlg DB 0 ; Indicate if transient portion has been moved | ||
| 450 | |||
| 451 | In_Batch DB 0 ; Indicate if we are in Batch processing mode. | ||
| 452 | Batch_Abort DB 0 ; Indicate if user wants to abort from batch mode. | ||
| 453 | |||
| 454 | COMDRV DB ? ; DRIVE SPEC TO LOAD AUTOEXEC AND COMMAND | ||
| 455 | MEMSIZ DW ? | ||
| 456 | SUM DW ? | ||
| 457 | EXTCOM DB 1 ; For init, pretend just did an external | ||
| 458 | RETCODE DW ? | ||
| 459 | CRIT_ERR_INFO DB ? ;G hold critical error flags for R,I,F | ||
| 460 | rsrc_xa_seg DW -1 ;AN030; holds segment of xa copy buffer | ||
| 461 | |||
| 462 | ; | ||
| 463 | ; The echo flag needs to be pushed and popped around pipes and batch files. | ||
| 464 | ; We implement this as a bit queue that is shr/shl for push and pop. | ||
| 465 | ; | ||
| 466 | ECHOFLAG DB 00000001B ; low bit TRUE => echo commands | ||
| 467 | SUPPRESS DB 1 ; used for echo, 1=echo line | ||
| 468 | IO_SAVE DW ? | ||
| 469 | RESTDIR DB 0 | ||
| 470 | PERMCOM DB 0 ; TRUE => permanent command | ||
| 471 | SINGLECOM DW 0 ; TRUE => single command version | ||
| 472 | VERVAL DW -1 | ||
| 473 | fFail DB 0 ; TRUE => FAIL all INT 24s | ||
| 474 | IFFLAG DB 0 ; TRUE => If statement in progress | ||
| 475 | |||
| 476 | FORFLAG DB 0 ; TRUE => FOR statement in progress | ||
| 477 | FORPTR DW 0 | ||
| 478 | |||
| 479 | NEST DW 0 ; NESTED BATCH FILE COUNTER | ||
| 480 | CALL_FLAG DB 0 ; NO CALL (BATCH COMMAND) IN PROGRESS | ||
| 481 | CALL_BATCH_FLAG DB 0 | ||
| 482 | NEXT_BATCH DW 0 ; ADDRESS OF NEXT BATCH SEGMENT | ||
| 483 | NULLFLAG DB 0 ; FLAG IF NO COMMAND ON COMMAND LINE | ||
| 484 | COM_XLAT_ADDR DB 5 DUP (0) ;G BUFFER FOR TRANSLATE TABLE ADDRESS | ||
| 485 | FUCASE_ADDR DB 5 DUP (0) ;AN000; BUFFER FOR FILE UCASE ADDRESS | ||
| 486 | CRIT_MSG_OFF DW 0 ;AN000; SAVED CRITICAL ERROR MESSAGE OFFSET | ||
| 487 | CRIT_MSG_SEG DW 0 ;AN000; SAVED CRITICAL ERROR MESSAGE SEGMENT | ||
| 488 | ;AD060; PARS_MSG_OFF DW 0 ;AN000; SAVED PARSE ERROR MESSAGE OFFSET | ||
| 489 | ;AD060; PARS_MSG_SEG DW 0 ;AN000; SAVED PARSE ERROR MESSAGE SEGMENT | ||
| 490 | Dbcs_vector_addr DW 0 ;AN000; DBCS vector offset | ||
| 491 | DW 0 ;AN000; DBCS vector segment | ||
| 492 | APPEND_STATE DW 0 ;AN020; current state of append (if flag = -1) | ||
| 493 | APPEND_FLAG DB 0 ;AN020; set if APPEND state valid | ||
| 494 | |||
| 495 | RE_OUT_APP DB 0 | ||
| 496 | RE_OUTSTR DB 64+3+13 DUP (?) | ||
| 497 | |||
| 498 | ; | ||
| 499 | ; We flag the state of COMMAND in order to correctly handle the ^Cs at | ||
| 500 | ; various times. Here is the breakdown: | ||
| 501 | ; | ||
| 502 | ; initINIT We are in the init code. | ||
| 503 | ; initSpecial We are in the date/time prompt | ||
| 504 | ; initCtrlC We are handling a ^C already. | ||
| 505 | ; | ||
| 506 | ; If we get a ^C in the initialization but not in the date/time prompt, we | ||
| 507 | ; ignore the ^C. This is so the system calls work on nested commands. | ||
| 508 | ; | ||
| 509 | ; If we are in the date/time prompt at initialization, we stuff the user's | ||
| 510 | ; input buffer with a CR to pretend an empty response. | ||
| 511 | ; | ||
| 512 | ; If we are already handling a ^C, we set the carry bit and return to the user | ||
| 513 | ; (ourselves). We can then detect the carry set and properly retry the | ||
| 514 | ; operation. | ||
| 515 | ; | ||
| 516 | |||
| 517 | InitFlag DB initINIT | ||
| 518 | |||
| 519 | ;These two bytes refed as a word | ||
| 520 | PIPEFLAG DB 0 | ||
| 521 | PIPEFILES DB 0 | ||
| 522 | |||
| 523 | ;--- 2.x data for piping | ||
| 524 | ; | ||
| 525 | ; All the "_" are substituted later, the one before the : is substituted | ||
| 526 | ; by the current drive, and the others by the CreateTemp call with the | ||
| 527 | ; unique file name. Note that the first 0 is the first char of the pipe | ||
| 528 | ; name. -MU | ||
| 529 | ; | ||
| 530 | ;--- Order dependant, do not change | ||
| 531 | |||
| 532 | Pipe1 db "_:/" | ||
| 533 | Pipe1T db 0 | ||
| 534 | db "_______.___",0 | ||
| 535 | Pipe2 db "_:/" | ||
| 536 | Pipe2T db 0 | ||
| 537 | db "_______.___",0 | ||
| 538 | |||
| 539 | PIPEPTR DW ? | ||
| 540 | PIPESTR DB 129 DUP(?) | ||
| 541 | INPIPEPTR DW OFFSET ResGroup:PIPE1 | ||
| 542 | OUTPIPEPTR DW OFFSET ResGroup:PIPE2 | ||
| 543 | |||
| 544 | EXEC_BLOCK LABEL BYTE ; The data block for EXEC calls | ||
| 545 | ENVIRSEG DW ? | ||
| 546 | COM_PTR LABEL DWORD | ||
| 547 | DW 80H ; Point at unformatted parameters | ||
| 548 | DW ? | ||
| 549 | COM_FCB1 LABEL DWORD | ||
| 550 | DW 5CH | ||
| 551 | DW ? | ||
| 552 | COM_FCB2 LABEL DWORD | ||
| 553 | DW 6CH | ||
| 554 | DW ? | ||
| 555 | |||
| 556 | TRANVARS LABEL BYTE ; Variables passed to transient | ||
| 557 | DW OFFSET ResGroup:THEADFIX | ||
| 558 | MYSEG DW 0 ; Put our own segment here | ||
| 559 | LTPA DW 0 ; WILL STORE TPA SEGMENT HERE | ||
| 560 | RSWITCHAR DB "-" | ||
| 561 | RDIRCHAR DB "/" | ||
| 562 | DW OFFSET ResGroup:EXT_EXEC | ||
| 563 | MYSEG1 DW ? | ||
| 564 | DW OFFSET ResGroup:TREMCHECK | ||
| 565 | MYSEG2 DW 0 | ||
| 566 | ResTest DW 0 | ||
| 567 | RES_TPA DW 0 ; Original TPA (not rounded to 64K) | ||
| 568 | TranVarEnd LABEL BYTE | ||
| 569 | |||
| 570 | olderrno dw ? | ||
| 571 | |||
| 572 | RESMSGEND DW 0 ;AN000;; holds offset of msg end (end of resident) | ||
| 573 | |||
| 574 | .xlist | ||
| 575 | .xcref | ||
| 576 | |||
| 577 | INCLUDE SYSMSG.INC ;AN000; include message services | ||
| 578 | |||
| 579 | .list | ||
| 580 | .cref | ||
| 581 | |||
| 582 | ASSUME DS:RESGROUP,ES:RESGROUP,CS:RESGROUP | ||
| 583 | |||
| 584 | MSG_UTILNAME <COMMAND> ;AN000; define utility name | ||
| 585 | |||
| 586 | ;AD054; MSG_SERVICES <COMR,MSGDATA,COMMAND.CLA,COMMAND.CL3,COMMAND.CL4> ;AN000; get message services data and resident messages | ||
| 587 | MSG_SERVICES <COMR,MSGDATA,COMMAND.CLA> ;AN054; get message services data and resident messages | ||
| 588 | |||
| 589 | |||
| 590 | CRITICAL_MSG_START LABEL BYTE ;AN000; start of critical error messages | ||
| 591 | |||
| 592 | MSG_SERVICES <COMR,COMMAND.CLD> ;AN000; get critical error messages | ||
| 593 | |||
| 594 | DATARESEND LABEL BYTE ;AC060; end of resident portion if /msg not used | ||
| 595 | |||
| 596 | PARSE_MSG_START LABEL BYTE ;AN000; start of parse error messages | ||
| 597 | |||
| 598 | MSG_SERVICES <COMR,COMMAND.CLC> ;AN000; get parse error messages | ||
| 599 | |||
| 600 | ;AD060; DATARESEND LABEL BYTE ; end of resident portion if /msg not used | ||
| 601 | |||
| 602 | EXTENDED_MSG_START LABEL BYTE ;AN000; start of extended error messages | ||
| 603 | |||
| 604 | MSG_SERVICES <COMR,COMMAND.CLE> ;AN000; get extended error messages | ||
| 605 | |||
| 606 | EXTMSGEND LABEL BYTE ;AN000; end of extended error messages | ||
| 607 | |||
| 608 | include msgdcl.inc | ||
| 609 | |||
| 610 | DATARES ENDS | ||
| 611 | END | ||
diff --git a/v4.0/src/CMD/COMMAND/RESMSG.EQU b/v4.0/src/CMD/COMMAND/RESMSG.EQU new file mode 100644 index 0000000..9eb5187 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/RESMSG.EQU | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | ; SCCSID = @(#)resmsg.equ 4.1 85/09/10 | ||
| 2 | ; SCCSID = @(#)resmsg.equ 4.1 85/09/10 | ||
| 3 | |||
| 4 | ;**************************** | ||
| 5 | ;* RESIDENT MESSAGE EQUATES * | ||
| 6 | ;**************************** | ||
| 7 | |||
| 8 | REQ_ABORT EQU 210 ;AC000; "Abort" | ||
| 9 | REQ_RETRY EQU 211 ;AC000; ", Retry" | ||
| 10 | REQ_IGNORE EQU 212 ;AC000; ", Ignore" | ||
| 11 | REQ_FAIL EQU 213 ;AC000; ", Fail" | ||
| 12 | REQ_END EQU 214 ;AC000; "? " | ||
| 13 | MREAD EQU 215 ;AC000; "reading" | ||
| 14 | MWRITE EQU 216 ;AC000; "writing" | ||
| 15 | DRVNUM EQU 217 ;AC000; "%1 drive %2" | ||
| 16 | DEVEMES EQU 218 ;AC000; "%1 device %2" | ||
| 17 | Err15Mes EQU 219 ;AC000; "Please insert volume %1 serial %2" | ||
| 18 | BADFAT EQU 220 ;AC000; "File allocation table bad, drive %1" | ||
| 19 | COMBAD EQU 221 ;AC000; 13,10,"Invalid COMMAND.COM",13,10" | ||
| 20 | comprmt1 EQU 222 ;AC000; "Insert disk with %1 in drive %1" | ||
| 21 | PROMPT EQU 223 ;AC000; "Press any key to continue" | ||
| 22 | ENDBATMES EQU 224 ;AC000; 13,10,"Terminate batch job (Y/N)? " | ||
| 23 | EXECEMES EQU 225 ;AC000; "Cannot execute %1",13,10 | ||
| 24 | EXEBAD EQU 226 ;AC000; "Error in EXE file",13,10 | ||
| 25 | TOOBIG EQU 227 ;AC000; "Program too big to fit in memory",13,10 | ||
| 26 | NOHANDMES EQU 228 ;AC000; 13,10,"No free file handles" | ||
| 27 | RBADNAM EQU 229 ;AC000; "Bad Command or file name",13,10 | ||
| 28 | AccDen EQU 230 ;AC000; Extended error - "Access denied",13,10 | ||
| 29 | BMEMMES EQU 231 ;AC000; 13,10,"Memory allocation error " | ||
| 30 | HALTMES EQU 232 ;AC000; 13,10,"Cannot load COMMAND, system halted" | ||
| 31 | FRETMES EQU 233 ;AC000; 13,10,"Cannot start COMMAND, exiting",13,10 | ||
| 32 | Patricide EQU 234 ;AC000; 13,10,"Top level process aborted, cannot continue." | ||
| 33 | NEWLIN EQU 235 ;AC000; 13,10 | ||
| 34 | |||
| 35 | ;************************ | ||
| 36 | ;* INIT MESSAGE EQUATES * | ||
| 37 | ;************************ | ||
| 38 | |||
| 39 | BADVER EQU 461 ;AC000; "Incorrect DOS version",13,10,"$" | ||
| 40 | OUTENVERR_PTR EQU 463 ;AC000; "Out of environment space",13,10,0 | ||
| 41 | HEADER_PTR EQU 464 ;AC000; Long Copyright Notice | ||
| 42 | BADCOMLKMES_PTR EQU 465 ;AC000;"Specified COMMAND search directory bad",13,10,0 | ||
| 43 | BADCOMACCMES_PTR EQU 466 ;AC000; "Specified COMMAND search directory bad access denied",13,10,0 | ||
diff --git a/v4.0/src/CMD/COMMAND/RUCODE.ASM b/v4.0/src/CMD/COMMAND/RUCODE.ASM new file mode 100644 index 0000000..5a6f413 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/RUCODE.ASM | |||
| @@ -0,0 +1,739 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)rucode.asm 4.5 85/07/22 | ||
| 3 | ; SCCSID = @(#)rucode.asm 4.5 85/07/22 | ||
| 4 | TITLE COMMAND Language modifiable Code Resident | ||
| 5 | |||
| 6 | |||
| 7 | .xlist | ||
| 8 | .xcref | ||
| 9 | INCLUDE DOSSYM.INC ;AC000; | ||
| 10 | include doscntry.inc ;AC000; | ||
| 11 | DEBUG = 0 ; NEED TO SET IT TO WHAT IT IS IN DOSSYM.INC | ||
| 12 | |||
| 13 | |||
| 14 | INCLUDE DEVSYM.INC | ||
| 15 | INCLUDE comsw.asm | ||
| 16 | INCLUDE comseg.asm | ||
| 17 | INCLUDE comequ.asm | ||
| 18 | include resmsg.equ ;AN000; | ||
| 19 | .list | ||
| 20 | .cref | ||
| 21 | |||
| 22 | |||
| 23 | Tokenized = FALSE | ||
| 24 | |||
| 25 | DATARES SEGMENT PUBLIC BYTE ;AC000; | ||
| 26 | EXTRN abort_char:byte | ||
| 27 | EXTRN badfat_block:byte ;AC000; | ||
| 28 | EXTRN badfat_subst:byte ;AC000; | ||
| 29 | EXTRN Batch_Abort:byte | ||
| 30 | EXTRN CDEVAT:BYTE | ||
| 31 | EXTRN COMSPEC:BYTE ;AN060; | ||
| 32 | EXTRN com_xlat_addr:word | ||
| 33 | EXTRN crit_err_info:byte | ||
| 34 | EXTRN crit_msg_off:word ;AC000; | ||
| 35 | EXTRN crit_msg_seg:word ;AC000; | ||
| 36 | EXTRN dbcs_vector_addr:dword ;AN000; | ||
| 37 | EXTRN devemes_block:byte ;AC000; | ||
| 38 | EXTRN devemes_subst:byte ;AC000; | ||
| 39 | EXTRN DEVENAM:BYTE | ||
| 40 | EXTRN deve_op_off:word ;AC000; | ||
| 41 | EXTRN disp_class:byte ;AC000; | ||
| 42 | EXTRN DRVLET:BYTE | ||
| 43 | EXTRN drvnum_block:byte ;AC000; | ||
| 44 | EXTRN drvnum_op_off:word ;AC000; | ||
| 45 | EXTRN drvnum_subst:byte ;AC000; | ||
| 46 | EXTRN err15mes_block:byte ;AC000; | ||
| 47 | EXTRN err15mes_subst:byte ;AC000; | ||
| 48 | EXTRN ERRCD_24:WORD | ||
| 49 | EXTRN ErrType:BYTE | ||
| 50 | EXTRN fail_char:byte | ||
| 51 | EXTRN fFail:BYTE | ||
| 52 | EXTRN FORFLAG:BYTE | ||
| 53 | EXTRN ignore_char:byte | ||
| 54 | EXTRN InitFlag:BYTE | ||
| 55 | EXTRN In_Batch:byte | ||
| 56 | EXTRN LOADING:BYTE | ||
| 57 | ;AD054; EXTRN MESBAS:BYTE | ||
| 58 | EXTRN no_char:byte | ||
| 59 | EXTRN number_subst:byte ;AC000; | ||
| 60 | EXTRN olderrno:word | ||
| 61 | EXTRN PARENT:WORD | ||
| 62 | ;AD060; EXTRN pars_msg_off:word ;AC000; | ||
| 63 | ;AD060; EXTRN pars_msg_seg:word ;AC000; | ||
| 64 | EXTRN PERMCOM:BYTE | ||
| 65 | EXTRN RemMsg:DWORD | ||
| 66 | EXTRN retry_char:byte | ||
| 67 | EXTRN PIPEFLAG:BYTE | ||
| 68 | EXTRN SINGLECOM:WORD | ||
| 69 | EXTRN VolName:BYTE | ||
| 70 | EXTRN yes_char:byte | ||
| 71 | |||
| 72 | IF Tokenized | ||
| 73 | EXTRN IOTYP:BYTE | ||
| 74 | EXTRN MESADD:BYTE | ||
| 75 | ENDIF | ||
| 76 | |||
| 77 | DATARES ENDS | ||
| 78 | |||
| 79 | |||
| 80 | CODERES SEGMENT PUBLIC BYTE | ||
| 81 | |||
| 82 | EXTRN GETCOMDSK2:NEAR | ||
| 83 | |||
| 84 | PUBLIC ASKEND | ||
| 85 | PUBLIC CRLF | ||
| 86 | PUBLIC DSKERR | ||
| 87 | PUBLIC ITESTKANJ ;AN000; | ||
| 88 | PUBLIC RESET_MSG_POINTERS ;AC000; | ||
| 89 | PUBLIC RPRINT | ||
| 90 | |||
| 91 | ASSUME CS:RESGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 92 | |||
| 93 | ; | ||
| 94 | ; AskEnd - prompt the user to see if he should terminate the batch file. If | ||
| 95 | ; any system call returns with carry set or if RPRINT returns with carry set, | ||
| 96 | ; we jump to the top and start over. | ||
| 97 | ; | ||
| 98 | ; Returns: carry set if response indicates that the batch file should | ||
| 99 | ; be terminated. | ||
| 100 | ; carry clear otherwise. | ||
| 101 | ; | ||
| 102 | |||
| 103 | ASSUME DS:RESGROUP | ||
| 104 | ASKEND: | ||
| 105 | MOV DX,ENDBATMES ;AC000; get batch terminate question | ||
| 106 | CALL RPRINT | ||
| 107 | MOV AX,(STD_CON_INPUT_FLUSH SHL 8)+STD_CON_INPUT | ||
| 108 | INT 21H | ||
| 109 | call in_char_xlat ;g change to upper case | ||
| 110 | CMP AL,no_char | ||
| 111 | retz ; carry is clear => no free | ||
| 112 | CMP AL,yes_char | ||
| 113 | JNZ ASKEND | ||
| 114 | stc ; carry set => free batch | ||
| 115 | return | ||
| 116 | |||
| 117 | DSKERR: | ||
| 118 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 119 | ; ****************************************************** | ||
| 120 | ; THIS IS THE DEFAULT DISK ERROR HANDLING CODE | ||
| 121 | ; AVAILABLE TO ALL USERS IF THEY DO NOT TRY TO | ||
| 122 | ; INTERCEPT INTERRUPT 24H. | ||
| 123 | ; ****************************************************** | ||
| 124 | STI | ||
| 125 | PUSH DS | ||
| 126 | PUSH ES | ||
| 127 | PUSH SI ;AN000; save si | ||
| 128 | PUSH CX | ||
| 129 | PUSH DI | ||
| 130 | PUSH CX | ||
| 131 | PUSH AX | ||
| 132 | MOV DS,BP | ||
| 133 | MOV AX,[SI.SDEVATT] | ||
| 134 | MOV [CDEVAT],AH | ||
| 135 | PUSH CS | ||
| 136 | POP ES | ||
| 137 | MOV DI,OFFSET RESGROUP:DEVENAM | ||
| 138 | MOV CX,8 | ||
| 139 | ADD SI,SDEVNAME ; Suck up device name (even on Block) | ||
| 140 | REP MOVSB | ||
| 141 | POP AX | ||
| 142 | POP CX | ||
| 143 | POP DI ; Stack just contains DS and ES | ||
| 144 | ; at this point | ||
| 145 | INVOKE SAVHAND | ||
| 146 | PUSH CS | ||
| 147 | POP DS ; Set up local data segment | ||
| 148 | ASSUME DS:RESGROUP | ||
| 149 | |||
| 150 | PUSH DX | ||
| 151 | CALL CRLF | ||
| 152 | POP DX | ||
| 153 | MOV CRIT_ERR_INFO,AH ;G save so we know if R,I,F are valid | ||
| 154 | |||
| 155 | ADD AL,'A' ; Compute drive letter (even on character) | ||
| 156 | MOV [DRVLET],AL | ||
| 157 | TEST AH,80H ; Check if hard disk error | ||
| 158 | JZ NOHARDE | ||
| 159 | TEST [CDEVAT],DEVTYP SHR 8 | ||
| 160 | JNZ NOHARDE | ||
| 161 | JMP FATERR | ||
| 162 | |||
| 163 | NOHARDE: | ||
| 164 | MOV SI,MREAD ;AC000; | ||
| 165 | TEST AH,1 | ||
| 166 | JZ SAVMES | ||
| 167 | MOV SI,MWRITE ;AC000; | ||
| 168 | |||
| 169 | SAVMES: | ||
| 170 | IF Tokenized | ||
| 171 | LODSW | ||
| 172 | MOV WORD PTR [IOTYP],AX | ||
| 173 | LODSW | ||
| 174 | MOV WORD PTR [IOTYP+2],AX | ||
| 175 | ENDIF | ||
| 176 | |||
| 177 | mov olderrno,di ; keep code in a safe place | ||
| 178 | PUSH ES ;AN000; | ||
| 179 | PUSH DS ; GetExtendedError likes to STOMP | ||
| 180 | PUSH BP | ||
| 181 | PUSH SI | ||
| 182 | PUSH DX | ||
| 183 | PUSH CX | ||
| 184 | PUSH BX | ||
| 185 | mov ah,GetExtendedError ; get extended error code | ||
| 186 | INT 21H | ||
| 187 | POP BX | ||
| 188 | POP CX | ||
| 189 | POP DX | ||
| 190 | POP SI | ||
| 191 | POP BP | ||
| 192 | POP DS | ||
| 193 | mov word ptr cs:[RemMsg],di ;AC000; save pointer to remote message | ||
| 194 | mov word ptr cs:[RemMsg+2],es ;AC000; (only used on code 15) | ||
| 195 | pop ES ;AN000; | ||
| 196 | XOR AH,AH | ||
| 197 | mov di,ax ; REAL error code to DI | ||
| 198 | ; | ||
| 199 | ; DI is now the correct error code. Classify things to see what we are | ||
| 200 | ; allowed to report. We convert DI into a 0-based index into a message table. | ||
| 201 | ; This presumes that the int 24 errors (oldstyle) and new errors (sharing and | ||
| 202 | ; the like) are contiguous. | ||
| 203 | ; | ||
| 204 | SUB DI,error_write_protect | ||
| 205 | JAE HavCod | ||
| 206 | MOV DI,error_Gen_failure-error_write_protect | ||
| 207 | ; | ||
| 208 | ; DI now has the mapped error code. Old style errors are: | ||
| 209 | ; FOOBAR <read|writ>ing drive ZZ. | ||
| 210 | ; New style errors are: | ||
| 211 | ; FOOBAR | ||
| 212 | ; We need to figure out which the particular error belongs to. | ||
| 213 | ; | ||
| 214 | |||
| 215 | HAVCOD: | ||
| 216 | mov ErrType,0 ; assume Old style | ||
| 217 | cmp di,error_FCB_Unavailable-error_write_protect | ||
| 218 | jz SetStyle | ||
| 219 | cmp di,error_sharing_buffer_exceeded-error_write_protect | ||
| 220 | jnz GotStyle | ||
| 221 | |||
| 222 | SetStyle: | ||
| 223 | mov ErrType,1 ; must be new type | ||
| 224 | |||
| 225 | GotStyle: | ||
| 226 | MOV [ERRCD_24],DI | ||
| 227 | cmp di,error_handle_disk_full-error_write_protect ;AC026; | ||
| 228 | ; If the error message is unknown | ||
| 229 | jbe NormalError ; redirector, continue. Otherwise, | ||
| 230 | ; | ||
| 231 | ; We do not know how to handle this error. Ask IFSFUNC if she knows | ||
| 232 | ; how to handle things | ||
| 233 | ; | ||
| 234 | |||
| 235 | ;input to IFSFUNC: AL=1 | ||
| 236 | ; BX=extended error number | ||
| 237 | |||
| 238 | ;output from IFSFUNC: AL=error type (0 or 1) | ||
| 239 | ; 0=<message> error (read/writ)ing (drive/device) xxx | ||
| 240 | ; Abort, Retry, Ignore | ||
| 241 | ; 1=<message> | ||
| 242 | ; Abort, Retry, Ignore | ||
| 243 | ; ES:DI=pointer to message text | ||
| 244 | ; carry set=>no message | ||
| 245 | |||
| 246 | MOV DI,AX ; retrieve correct extended error... | ||
| 247 | mov ax,0500h ; Is the redir there? | ||
| 248 | int 2fh | ||
| 249 | cmp al,0ffh | ||
| 250 | jnz NoHandler ; No, go to NoHandler | ||
| 251 | push bx ;AN063; | ||
| 252 | mov bx,di ; Get ErrType and ptr to error msg ;AC063; | ||
| 253 | mov ax,0501h ;AC063; | ||
| 254 | int 2fh | ||
| 255 | pop bx ;AC063; | ||
| 256 | jc NoHandler | ||
| 257 | |||
| 258 | mov ErrType,al | ||
| 259 | push ds | ||
| 260 | push es | ||
| 261 | pop ds | ||
| 262 | mov dx,di | ||
| 263 | mov cx,-1 ; Find the end of the error msg and turn | ||
| 264 | xor al,al ; the high byte on for rprint | ||
| 265 | repnz scasb | ||
| 266 | |||
| 267 | IF Tokenized | ||
| 268 | or byte ptr [di-2],80h | ||
| 269 | call rprint ; Print the message | ||
| 270 | and byte ptr [di-2], NOT 80h ; Restore msg to original condition | ||
| 271 | ELSE | ||
| 272 | mov byte ptr [di-1],'$' | ||
| 273 | MOV AH,Std_con_string_output ;AC000; Print the message | ||
| 274 | INT 21h ;AN000; | ||
| 275 | mov byte ptr [di-1],0 ; Restore msg to original condition | ||
| 276 | ENDIF | ||
| 277 | |||
| 278 | pop ds ; Clean up and continue processing | ||
| 279 | jmp short CheckErrType | ||
| 280 | |||
| 281 | NoHandler: ; Redir isn't available or doesn't | ||
| 282 | mov ErrType,0 ; recognize the error. Reset vars and | ||
| 283 | mov di,olderrno ; regs to unextended err and continue | ||
| 284 | mov ERRCD_24,di ; normally. | ||
| 285 | |||
| 286 | NormalError: | ||
| 287 | ;AD054; SHL DI,1 | ||
| 288 | ;AD054; MOV DI,WORD PTR [DI+MESBAS] ; Get pointer to error message | ||
| 289 | add DI,error_write_protect ;AN054; | ||
| 290 | XCHG DI,DX ; May need DX later | ||
| 291 | MOV DISP_CLASS,EXT_CRLF_CLASS ;AN054; printing extended error class | ||
| 292 | CALL RPRINT ; Print error type | ||
| 293 | |||
| 294 | CheckErrType: | ||
| 295 | cmp ErrType,0 ; Check error style... | ||
| 296 | je ContOld | ||
| 297 | call CRLF ; if new style then done printing | ||
| 298 | jmp short ASK | ||
| 299 | |||
| 300 | ContOld: | ||
| 301 | IF NOT Tokenized | ||
| 302 | MOV AX,SI ;AN000; get reading/writing for message | ||
| 303 | MOV DH,UTIL_MSG_CLASS ;AN000; this is a utility message | ||
| 304 | CALL SYSGETMSG ;AN000; get the message | ||
| 305 | ENDIF | ||
| 306 | |||
| 307 | TEST [CDEVAT],DEVTYP SHR 8 | ||
| 308 | JZ BLKERR | ||
| 309 | MOV DX,DEVEMES ;AC000; get message number for device message | ||
| 310 | MOV DEVE_OP_OFF,SI ;AN000; put address of read/write in subst block | ||
| 311 | MOV AL,DEVEMES_SUBST ;AN000; get number of substitutions | ||
| 312 | MOV NUMBER_SUBST,AL ;AN000; | ||
| 313 | MOV SI,OFFSET RESGROUP:DEVEMES_BLOCK;AN000; get address of subst block | ||
| 314 | |||
| 315 | CALL RPRINT ;AC000; print the message | ||
| 316 | JMP SHORT ASK ; Don't ralph on COMMAND | ||
| 317 | |||
| 318 | BLKERR: | ||
| 319 | MOV DX,DRVNUM ;AN000; get drive message number | ||
| 320 | MOV DRVNUM_OP_OFF,SI ;AN000; put address of read/write in subst block | ||
| 321 | MOV AL,DRVNUM_SUBST ;AN000; get number of substitutions | ||
| 322 | MOV NUMBER_SUBST,AL ;AN000; | ||
| 323 | MOV SI,OFFSET RESGROUP:DRVNUM_BLOCK ;AN000; get address of subst block | ||
| 324 | CALL RPRINT | ||
| 325 | CMP [LOADING],0 | ||
| 326 | JZ ASK | ||
| 327 | INVOKE RESTHAND | ||
| 328 | JMP GETCOMDSK2 ; If error loading COMMAND, re-prompt | ||
| 329 | |||
| 330 | ASK: | ||
| 331 | cmp [ERRCD_24],15 ; Wait! Error 15 has an extra message | ||
| 332 | jne Not15 | ||
| 333 | PUSH CX | ||
| 334 | push ds | ||
| 335 | pop es | ||
| 336 | lds si,[RemMsg] | ||
| 337 | assume ds:nothing | ||
| 338 | push di | ||
| 339 | mov di,offset resgroup:VolName | ||
| 340 | mov cx,16 ;AC000; extra message volume name & serial number | ||
| 341 | cld ; just in case! | ||
| 342 | rep movsb | ||
| 343 | pop di | ||
| 344 | push es | ||
| 345 | pop ds | ||
| 346 | POP CX | ||
| 347 | assume ds:resgroup | ||
| 348 | mov dx,Err15Mes ;AC000; get message number | ||
| 349 | MOV AL,ERR15MES_SUBST ;AN000; get number of substitutions | ||
| 350 | MOV NUMBER_SUBST,AL ;AN000; | ||
| 351 | MOV SI,OFFSET RESGROUP:ERR15MES_BLOCK ;AN000; get address of subst block | ||
| 352 | CALL RPRINT | ||
| 353 | |||
| 354 | ; PRINT OUT ABORT, RETRY, IGNORE, FAIL MESSAGE. ONLY PRINT OUT OPTIONS | ||
| 355 | ; THAT ARE VALID | ||
| 356 | |||
| 357 | Not15: | ||
| 358 | MOV DX,REQ_ABORT ;AC000;G print out abort message | ||
| 359 | CALL RPRINT ;G | ||
| 360 | TEST CRIT_ERR_INFO,RETRY_ALLOWED ;G is retry allowed? | ||
| 361 | JZ TRY_IGNORE ;G | ||
| 362 | MOV DX,REQ_RETRY ;AC000;G yes,print out retry message | ||
| 363 | CALL RPRINT ;G | ||
| 364 | |||
| 365 | try_ignore: | ||
| 366 | TEST CRIT_ERR_INFO,IGNORE_ALLOWED ;G is ignore allowed? | ||
| 367 | JZ TRY_FAIL ;G | ||
| 368 | MOV DX,REQ_IGNORE ;AC000;G yes,print out ignore message | ||
| 369 | CALL RPRINT ;G | ||
| 370 | |||
| 371 | try_fail: | ||
| 372 | TEST CRIT_ERR_INFO,FAIL_ALLOWED ;G is FAIL allowed? | ||
| 373 | JZ TERM_QUESTION ;G | ||
| 374 | MOV DX,REQ_FAIL ;AC000;G yes,print out FAIL message | ||
| 375 | CALL RPRINT ;G | ||
| 376 | |||
| 377 | Term_Question: | ||
| 378 | MOV DX,REQ_END ;AC000;G terminate the string | ||
| 379 | CALL RPRINT ;G | ||
| 380 | ; | ||
| 381 | ; If the /f switch was given, we fail all requests... | ||
| 382 | ; | ||
| 383 | TEST fFail,-1 | ||
| 384 | JZ DoPrompt | ||
| 385 | MOV AH,3 ; signal fail | ||
| 386 | JMP EExit | ||
| 387 | |||
| 388 | DoPrompt: | ||
| 389 | MOV AX,(STD_CON_INPUT_FLUSH SHL 8)+STD_CON_INPUT | ||
| 390 | INT 21H ; Get response | ||
| 391 | |||
| 392 | invoke TestKanjR ;AN000; 3/3/KK | ||
| 393 | jz notkanj ;AN000; 3/3/KK | ||
| 394 | MOV AX,(STD_CON_INPUT SHL 8) ;AN000; eat the 2nd byte of ECS code 3/3/KK | ||
| 395 | INT 21H ;AN000; 3/3/KK | ||
| 396 | CALL CRLF ;AN000; 3/3/KK | ||
| 397 | JMP ASK ;AN000; 3/3/KK | ||
| 398 | |||
| 399 | notkanj: ;AN000; 3/3/KK | ||
| 400 | CALL CRLF | ||
| 401 | CALL IN_CHAR_XLAT ;G Convert to upper case | ||
| 402 | MOV AH,0 ; Return code for ignore | ||
| 403 | TEST CRIT_ERR_INFO,IGNORE_ALLOWED ;G is IGNORE allowed? | ||
| 404 | JZ USER_RETRY ;G | ||
| 405 | CMP AL,ignore_char ; Ignore? | ||
| 406 | JZ EEXITJ | ||
| 407 | |||
| 408 | USER_RETRY: | ||
| 409 | INC AH ; return code for retry | ||
| 410 | TEST CRIT_ERR_INFO,RETRY_ALLOWED ;G is RETRY allowed? | ||
| 411 | JZ USER_ABORT ;G | ||
| 412 | CMP AL,retry_char ; Retry? | ||
| 413 | JZ EEXITJ | ||
| 414 | |||
| 415 | USER_ABORT: | ||
| 416 | INC AH ; return code for abort - always allowed | ||
| 417 | CMP AL,abort_char ; Abort? | ||
| 418 | JZ abort_process ;G exit user program | ||
| 419 | INC AH ;G return code for fail | ||
| 420 | TEST CRIT_ERR_INFO,FAIL_ALLOWED ;G is FAIL allowed? | ||
| 421 | JZ ASKJ ;G | ||
| 422 | CMP AL,fail_char ;G fail? | ||
| 423 | JZ EEXITJ ;G | ||
| 424 | |||
| 425 | ASKJ: | ||
| 426 | JMP ASK ;G | ||
| 427 | |||
| 428 | EEXITJ: | ||
| 429 | JMP SHORT EEXIT ;G | ||
| 430 | |||
| 431 | abort_process: | ||
| 432 | test InitFlag,initINIT ; Was command initialization interrupted | ||
| 433 | jz AbortCont ; No, handle it normally | ||
| 434 | cmp PERMCOM,0 ; Is this the top level process? | ||
| 435 | jz JustExit ; Yes, just exit | ||
| 436 | mov dx,Patricide ;AC000; No, load ptr to error msg | ||
| 437 | call RPRINT ; Print it | ||
| 438 | |||
| 439 | DeadInTheWater: | ||
| 440 | jmp DeadInTheWater ; Loop until the user reboots | ||
| 441 | |||
| 442 | JustExit: | ||
| 443 | ASSUME DS:RESGROUP | ||
| 444 | call reset_msg_pointers ;AN000; reset critical & parse message addresses | ||
| 445 | mov ax,[PARENT] ; Load real parent PID | ||
| 446 | mov word ptr ds:[PDB_Parent_PID],ax ; Put it back where it belongs | ||
| 447 | mov ax,(Exit SHL 8) OR 255 | ||
| 448 | int 21H | ||
| 449 | |||
| 450 | AbortCont: | ||
| 451 | test byte ptr [In_Batch],-1 ; Are we accessing a batch file? | ||
| 452 | jz Not_Batch_Abort | ||
| 453 | mov byte ptr [Batch_Abort],1 ; set flag for abort | ||
| 454 | |||
| 455 | Not_Batch_Abort: | ||
| 456 | mov dl,PipeFlag | ||
| 457 | invoke ResPipeOff | ||
| 458 | OR DL,DL | ||
| 459 | JZ CHECKFORA | ||
| 460 | CMP [SINGLECOM],0 | ||
| 461 | JZ CHECKFORA | ||
| 462 | MOV [SINGLECOM],-1 ; Make sure SINGLECOM exits | ||
| 463 | |||
| 464 | CHECKFORA: | ||
| 465 | CMP [ERRCD_24],0 ; Write protect | ||
| 466 | JZ ABORTFOR | ||
| 467 | CMP [ERRCD_24],2 ; Drive not ready | ||
| 468 | JNZ EEXIT ; Don't abort the FOR | ||
| 469 | |||
| 470 | ABORTFOR: | ||
| 471 | MOV [FORFLAG],0 ; Abort a FOR in progress | ||
| 472 | CMP [SINGLECOM],0 | ||
| 473 | JZ EEXIT | ||
| 474 | MOV [SINGLECOM],-1 ; Make sure SINGLECOM exits | ||
| 475 | |||
| 476 | EEXIT: | ||
| 477 | MOV AL,AH | ||
| 478 | MOV DX,DI | ||
| 479 | |||
| 480 | RESTHD: | ||
| 481 | INVOKE RESTHAND | ||
| 482 | POP CX | ||
| 483 | POP SI ;AN000; restore registers | ||
| 484 | POP ES | ||
| 485 | POP DS | ||
| 486 | IRET | ||
| 487 | |||
| 488 | FATERR: | ||
| 489 | MOV DX,BADFAT ;AC000; | ||
| 490 | MOV AL,BADFAT_SUBST ;AN000; get number of substitutions | ||
| 491 | MOV NUMBER_SUBST,AL ;AN000; | ||
| 492 | MOV SI,OFFSET RESGROUP:BADFAT_BLOCK ;AN000; get address of subst block | ||
| 493 | CALL RPRINT | ||
| 494 | |||
| 495 | IF Tokenized | ||
| 496 | MOV DX,OFFSET RESGROUP:ERRMES | ||
| 497 | CALL RPRINT | ||
| 498 | ENDIF | ||
| 499 | |||
| 500 | MOV AL,2 ; Abort | ||
| 501 | JMP RESTHD | ||
| 502 | |||
| 503 | ;********************************************* | ||
| 504 | ; Print routines for Tokenized resident messages | ||
| 505 | |||
| 506 | ASSUME DS:RESGROUP,SS:RESGROUP | ||
| 507 | |||
| 508 | CRLF: | ||
| 509 | MOV DX,NEWLIN ;AC000; | ||
| 510 | |||
| 511 | ; | ||
| 512 | ; RPRINT prints out a message on the user's console. We clear carry before | ||
| 513 | ; each system call. We do this so that the ^C checker may change things so | ||
| 514 | ; that carry is set. If we detect a system call that returns with carry set, | ||
| 515 | ; we merely return. | ||
| 516 | ; | ||
| 517 | ; Inputs: DX has the message number as an offset from DS. | ||
| 518 | ; Outputs: Carry clear: no carries detected in the system calls | ||
| 519 | ; Carry set: at least one system call returned with carry set | ||
| 520 | ; Registers modified: none | ||
| 521 | ; | ||
| 522 | |||
| 523 | RPRINT: | ||
| 524 | |||
| 525 | ; | ||
| 526 | ; If we are not tokenized, the message consists of a $-terminated string. | ||
| 527 | ; Use CPM io to output it. | ||
| 528 | ; | ||
| 529 | |||
| 530 | if NOT tokenized | ||
| 531 | PUSH AX | ||
| 532 | PUSH BX ;AC000; save BX register | ||
| 533 | PUSH CX ;AC000; save CX register | ||
| 534 | PUSH DX ;AC000; save DX register | ||
| 535 | MOV AX,DX ;AC000; get message number | ||
| 536 | MOV DH,DISP_CLASS ;AC000; get display class | ||
| 537 | MOV DL,NO_CONT_FLAG ;AN000; set control flags off | ||
| 538 | MOV BX,NO_HANDLE_OUT ;AC000; set message handler to use function 1-12 | ||
| 539 | XOR CH,CH ;AC000; clear upper part of cx | ||
| 540 | MOV CL,NUMBER_SUBST ;AC000; set number of substitutions | ||
| 541 | CALL SYSDISPMSG ;AC000; display the message | ||
| 542 | MOV DISP_CLASS,UTIL_MSG_CLASS ;AC000; reset display class | ||
| 543 | MOV NUMBER_SUBST,NO_SUBST ;AC000; reset number of substitutions | ||
| 544 | POP DX ;AC000; restore registers | ||
| 545 | POP CX ;AC000; | ||
| 546 | POP BX ;AC000; | ||
| 547 | POP AX | ||
| 548 | |||
| 549 | return | ||
| 550 | endif | ||
| 551 | |||
| 552 | ; | ||
| 553 | ; If we are tokenized, output character-by-character. If there is a digit in | ||
| 554 | ; the output, look up that substring in the tokenization table. Use the high | ||
| 555 | ; bit to determine the end-of-string. | ||
| 556 | ; | ||
| 557 | |||
| 558 | If Tokenized | ||
| 559 | SaveReg <AX,DX,SI> | ||
| 560 | MOV SI,DX | ||
| 561 | |||
| 562 | RPRINT1: | ||
| 563 | LODSB | ||
| 564 | PUSH AX ; save for EOS testing | ||
| 565 | AND AL,7FH | ||
| 566 | CMP AL,'0' | ||
| 567 | JB RPRINT2 | ||
| 568 | CMP AL,'9' | ||
| 569 | JA RPRINT2 | ||
| 570 | SUB AL,'0' | ||
| 571 | CBW ; DS must be RESGROUP if we get here | ||
| 572 | SHL AX,1 ; clear carry | ||
| 573 | XCHG SI,AX | ||
| 574 | MOV DX,[SI + OFFSET RESGroup:MesADD] | ||
| 575 | CALL RPrint | ||
| 576 | XCHG SI,AX | ||
| 577 | JMP SHORT RPRINT3 | ||
| 578 | |||
| 579 | RPRINT2: | ||
| 580 | MOV DL,AL | ||
| 581 | MOV AH,STD_CON_OUTPUT | ||
| 582 | clc ; set ok flag | ||
| 583 | INT 21H | ||
| 584 | |||
| 585 | RPRINT3: | ||
| 586 | POP AX | ||
| 587 | JC RPrint5 ; Abnormal termination? | ||
| 588 | TEST AL,80h ; High bit set indicates end (carry clear) | ||
| 589 | JZ RPRINT1 | ||
| 590 | |||
| 591 | RPRINT5: | ||
| 592 | RestoreReg <SI,DX,AX> | ||
| 593 | RET | ||
| 594 | endif | ||
| 595 | |||
| 596 | |||
| 597 | ;g | ||
| 598 | ;g This routine returns the upper case of the character in AL | ||
| 599 | ;g from the upper case table in DOS if character if above | ||
| 600 | ;g ascii 128, else subtract 20H if between "a" and "z" | ||
| 601 | ;g | ||
| 602 | |||
| 603 | assume ds:resgroup | ||
| 604 | |||
| 605 | in_char_xlat proc near | ||
| 606 | |||
| 607 | cmp al,80h ;g see if char is above ascii 128 | ||
| 608 | jb other_xlat ;g no - upper case math | ||
| 609 | sub al,80h ;g only upper 128 characters in table | ||
| 610 | push ds | ||
| 611 | push bx | ||
| 612 | lds bx,dword ptr com_xlat_addr+1 ;g get table address | ||
| 613 | add bx,2 ;g skip over first word, of table | ||
| 614 | xlat ds:byte ptr [bx] ;g convert to upper case | ||
| 615 | pop bx | ||
| 616 | pop ds | ||
| 617 | jmp short in_char_xlat_end ;g we finished - exit | ||
| 618 | |||
| 619 | other_xlat: | ||
| 620 | cmp al,'a' ;g if between "a" and "z", subtract | ||
| 621 | jb in_char_xlat_end ;g 20h to get upper case | ||
| 622 | cmp al,'z' ;g equivalent. | ||
| 623 | ja in_char_xlat_end ;g | ||
| 624 | sub al,20h ;g Lower-case changed to upper-case | ||
| 625 | |||
| 626 | in_char_xlat_end: | ||
| 627 | |||
| 628 | ret | ||
| 629 | |||
| 630 | in_char_xlat endp | ||
| 631 | ;---------------------- DBCS lead byte check. this is resident code ; 3/3/KK | ||
| 632 | |||
| 633 | ITESTKANJ: ;AN000; | ||
| 634 | TestKanjR: ;AN000; 3/3/KK | ||
| 635 | push ds ;AN000; 3/3/KK | ||
| 636 | push si ;AN000; 3/3/KK | ||
| 637 | push ax ;AN000; 3/3/KK | ||
| 638 | lds si,dbcs_vector_addr ;AN000; GET DBCS VECTOR | ||
| 639 | |||
| 640 | ktlop: ;AN000; 3/3/KK | ||
| 641 | cmp word ptr ds:[si],0 ;AN000; 3/3/KK end of Lead Byte Table | ||
| 642 | je notlead ;AN000; 3/3/KK | ||
| 643 | pop ax ;AN000; 3/3/KK | ||
| 644 | push ax ;AN000; 3/3/KK | ||
| 645 | cmp al, byte ptr ds:[si] ;AN000; 3/3/KK | ||
| 646 | jb notlead ;AN000; 3/3/KK | ||
| 647 | inc si ;AN000; 3/3/KK | ||
| 648 | cmp al, byte ptr ds:[si] ;AN000; 3/3/KK | ||
| 649 | jbe islead ;AN000; 3/3/KK | ||
| 650 | inc si ;AN000; 3/3/KK | ||
| 651 | jmp short ktlop ;AN000; 3/3/KK try another range | ||
| 652 | |||
| 653 | Notlead: ;AN000; 3/3/KK | ||
| 654 | xor ax,ax ;AN000; 3/3/KK set zero | ||
| 655 | jmp short ktret ;AN000; 3/3/KK | ||
| 656 | |||
| 657 | Islead: ;AN000; 3/3/KK | ||
| 658 | xor ax,ax ;AN000; 3/3/KK reset zero | ||
| 659 | inc ax ;AN000; 3/3/KK | ||
| 660 | |||
| 661 | ktret: ;AN000; 3/3/KK | ||
| 662 | pop ax ;AN000; 3/3/KK | ||
| 663 | pop si ;AN000; 3/3/KK | ||
| 664 | pop ds ;AN000; 3/3/KK | ||
| 665 | return ;AN000; 3/3/KK | ||
| 666 | |||
| 667 | |||
| 668 | ; **************************************************************** | ||
| 669 | ; * | ||
| 670 | ; * ROUTINE: RESET_MSG_POINTERS | ||
| 671 | ; * | ||
| 672 | ; * FUNCTION: Resets addresses for parse and critical error | ||
| 673 | ; * messages in DOS via INT 2fh. This routine | ||
| 674 | ; * is invoked before command exits. | ||
| 675 | ; * | ||
| 676 | ; * INPUT: none | ||
| 677 | ; * | ||
| 678 | ; * OUTPUT: none | ||
| 679 | ; * | ||
| 680 | ; **************************************************************** | ||
| 681 | |||
| 682 | reset_msg_pointers proc near | ||
| 683 | |||
| 684 | assume ds:resgroup, es:nothing | ||
| 685 | |||
| 686 | push es ;AN000; save used registers | ||
| 687 | push ax ;AN000; | ||
| 688 | push dx ;AN000; | ||
| 689 | push di ;AN000; | ||
| 690 | ;AD060; mov ah,multdos ;AN000; reset parse message pointers | ||
| 691 | ;AD060; mov al,message_2f ;AN000; call for message retriever | ||
| 692 | ;AD060; mov dl,set_parse_msg ;AN000; set up parse message address | ||
| 693 | ;AD060; mov di,pars_msg_off ;AN000; old offset of parse messages | ||
| 694 | ;AD060; mov es,pars_msg_seg ;AN000; old segment of parse messages | ||
| 695 | ;AD060; int 2fh ;AN000; go set it | ||
| 696 | |||
| 697 | ;AD060; mov ah,multdos ;AN000; set up to call DOS through int 2fh | ||
| 698 | ;AD060; mov al,message_2f ;AN000; call for message retriever | ||
| 699 | mov ax,(multdos shl 8 or message_2f);AN060; reset critical message pointers | ||
| 700 | mov dl,set_critical_msg ;AN000; set up critical error message address | ||
| 701 | mov di,crit_msg_off ;AN000; old offset of critical messages | ||
| 702 | mov es,crit_msg_seg ;AN000; old segment of critical messages | ||
| 703 | int 2fh ;AN000; go set it | ||
| 704 | pop di ;AN000; restore used registers | ||
| 705 | pop dx ;AN000; | ||
| 706 | pop ax ;AN000; | ||
| 707 | pop es ;AN000; | ||
| 708 | |||
| 709 | ret | ||
| 710 | |||
| 711 | |||
| 712 | reset_msg_pointers endp | ||
| 713 | |||
| 714 | PUBLIC MSG_SERV_ST ;AN000; | ||
| 715 | MSG_SERV_ST LABEL BYTE ;AN000; | ||
| 716 | |||
| 717 | PUBLIC SYSGETMSG,SYSDISPMSG | ||
| 718 | |||
| 719 | ASSUME DS:RESGROUP, ES:RESGROUP | ||
| 720 | |||
| 721 | .xlist | ||
| 722 | .xcref | ||
| 723 | |||
| 724 | INCLUDE SYSMSG.INC ;AN000; include message services | ||
| 725 | |||
| 726 | .list | ||
| 727 | .cref | ||
| 728 | |||
| 729 | MSG_UTILNAME <COMMAND> ;AN000; define utility name | ||
| 730 | |||
| 731 | MSG_SERVICES <COMR,NEARmsg,DISK_PROC,GETmsg,DISPLAYmsg,CHARmsg,NUMmsg> ;AC060; include message services macro | ||
| 732 | |||
| 733 | PUBLIC RES_CODE_END ;AN000; | ||
| 734 | RES_CODE_END LABEL BYTE ;AN000; | ||
| 735 | |||
| 736 | include msgdcl.inc | ||
| 737 | |||
| 738 | CODERES ENDS | ||
| 739 | END | ||
diff --git a/v4.0/src/CMD/COMMAND/TBATCH.ASM b/v4.0/src/CMD/COMMAND/TBATCH.ASM new file mode 100644 index 0000000..6ec51b5 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/TBATCH.ASM | |||
| @@ -0,0 +1,1045 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)tbatch.asm 4.5 85/10/01 | ||
| 3 | ; SCCSID = @(#)tbatch.asm 4.5 85/10/01 | ||
| 4 | TITLE Batch processing routines | ||
| 5 | |||
| 6 | |||
| 7 | .xlist | ||
| 8 | .xcref | ||
| 9 | INCLUDE comsw.asm | ||
| 10 | INCLUDE DOSSYM.INC | ||
| 11 | INCLUDE comseg.asm | ||
| 12 | INCLUDE comequ.asm | ||
| 13 | include doscntry.inc ;AN000; | ||
| 14 | include version.inc | ||
| 15 | .list | ||
| 16 | .cref | ||
| 17 | |||
| 18 | |||
| 19 | DATARES SEGMENT PUBLIC BYTE ;AC000; | ||
| 20 | EXTRN BATCH:WORD | ||
| 21 | EXTRN Batch_Abort:byte | ||
| 22 | EXTRN call_batch_flag:byte | ||
| 23 | EXTRN ECHOFLAG:BYTE | ||
| 24 | EXTRN forflag:byte | ||
| 25 | EXTRN forptr:word | ||
| 26 | EXTRN IFFlag:BYTE | ||
| 27 | EXTRN In_Batch:byte | ||
| 28 | EXTRN LTPA:WORD | ||
| 29 | EXTRN Nest:word | ||
| 30 | EXTRN next_batch:word | ||
| 31 | EXTRN nullflag:byte | ||
| 32 | EXTRN PIPEFLAG:BYTE | ||
| 33 | EXTRN RES_TPA:WORD | ||
| 34 | EXTRN SINGLECOM:WORD | ||
| 35 | EXTRN SUPPRESS:BYTE ;AC000; | ||
| 36 | DATARES ENDS | ||
| 37 | |||
| 38 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 39 | EXTRN BADBAT_PTR:WORD | ||
| 40 | EXTRN Extend_buf_ptr:word ;AC000; | ||
| 41 | EXTRN Extend_buf_sub:byte ;AN022; | ||
| 42 | EXTRN msg_disp_class:byte ;AC000; | ||
| 43 | EXTRN NEEDBAT_PTR:WORD | ||
| 44 | EXTRN pausemes_ptr:word ;AC000; | ||
| 45 | TRANDATA ENDS | ||
| 46 | |||
| 47 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 48 | EXTRN BatBufPos:WORD | ||
| 49 | EXTRN BATHAND:WORD | ||
| 50 | EXTRN bwdbuf:byte ;AN022; | ||
| 51 | EXTRN BYTCNT:WORD | ||
| 52 | EXTRN COMBUF:BYTE | ||
| 53 | EXTRN EXECPATH:BYTE | ||
| 54 | EXTRN ID:BYTE | ||
| 55 | EXTRN RCH_ADDR:DWORD | ||
| 56 | EXTRN RESSEG:WORD | ||
| 57 | EXTRN string_ptr_2:word ;AC000; | ||
| 58 | EXTRN TPA:WORD | ||
| 59 | EXTRN TRAN_TPA:WORD | ||
| 60 | TRANSPACE ENDS | ||
| 61 | |||
| 62 | TRANCODE SEGMENT PUBLIC BYTE | ||
| 63 | |||
| 64 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 65 | |||
| 66 | EXTRN cerror:near | ||
| 67 | EXTRN tcommand:near | ||
| 68 | |||
| 69 | ;--------------- | ||
| 70 | |||
| 71 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 72 | extrn arg:byte ; the arg structure! | ||
| 73 | transpace ends | ||
| 74 | ;--------------- | ||
| 75 | |||
| 76 | Break <PromptBat - Open or wait for batch file> | ||
| 77 | |||
| 78 | ; | ||
| 79 | ; Open the batch file. If we cannot find the batch file. If the media is | ||
| 80 | ; changeable, we prompt for the change. Otherwise, we terminate the batch | ||
| 81 | ; file. Leave segment registers alone. | ||
| 82 | ; | ||
| 83 | |||
| 84 | Procedure PromptBat,NEAR | ||
| 85 | ASSUME DS:ResGroup,ES:NOTHING | ||
| 86 | invoke BATOPEN ; attempt to open batch file | ||
| 87 | retnc | ||
| 88 | cmp dx,error_file_not_found ;AN022; Ask for diskette if file not found | ||
| 89 | jz Bat_Remcheck ;AN022; | ||
| 90 | cmp dx,error_path_not_found ;AN022; Ask for diskette if path not found | ||
| 91 | jz Bat_Remcheck ;AN022; Otherwise, issue message and exit | ||
| 92 | invoke output_batch_name ;AN022; set up batch name in bwdbuf | ||
| 93 | jmp short BatDie ;AN022; | ||
| 94 | |||
| 95 | Bat_Remcheck: ;AN022; Go see if media is removable | ||
| 96 | CALL [RCH_ADDR] ; DX has error number | ||
| 97 | JZ AskForBat ; Media is removable | ||
| 98 | ; | ||
| 99 | ; The media is not changeable. Turn everything off. | ||
| 100 | ; | ||
| 101 | invoke ForOff | ||
| 102 | invoke PipeOff | ||
| 103 | MOV IfFlag,AL ; No If in progress. | ||
| 104 | MOV DX,OFFSET TRANGROUP:BADBAT_ptr | ||
| 105 | |||
| 106 | BatDie: | ||
| 107 | call BatchOff | ||
| 108 | PUSH CS | ||
| 109 | POP DS | ||
| 110 | ASSUME DS:TranGroup | ||
| 111 | invoke std_eprintf ;AC022; display message | ||
| 112 | |||
| 113 | ; | ||
| 114 | ; TCOMMAND resets the stack. This is the equivalent of a non-local goto. | ||
| 115 | ; | ||
| 116 | JMP TCOMMAND ; he cleans off stack | ||
| 117 | |||
| 118 | ; | ||
| 119 | ; Ask the user to reinsert the batch file | ||
| 120 | ; | ||
| 121 | ASKFORBAT: | ||
| 122 | ASSUME DS:ResGroup | ||
| 123 | PUSH DS | ||
| 124 | PUSH CS | ||
| 125 | POP DS | ||
| 126 | ASSUME DS:TranGroup | ||
| 127 | MOV DX,OFFSET TRANGROUP:NEEDBAT_ptr ;AN022; | ||
| 128 | invoke std_eprintf ;Prompt for batch file on stderr | ||
| 129 | mov dx,offset trangroup:pausemes_ptr ;AN000; get second part of message | ||
| 130 | invoke std_eprintf ;AN000; print it to stderr | ||
| 131 | CALL GetKeystroke | ||
| 132 | POP DS | ||
| 133 | ASSUME DS:ResGroup | ||
| 134 | jmp PromptBat | ||
| 135 | EndProc PromptBat | ||
| 136 | |||
| 137 | ;**************************************************************** | ||
| 138 | ;* | ||
| 139 | ;* ROUTINE: Output_batch_name | ||
| 140 | ;* | ||
| 141 | ;* FUNCTION: Sets up batch name to be printed on extended error | ||
| 142 | ;* | ||
| 143 | ;* INPUT: DX - extended error number | ||
| 144 | ;* | ||
| 145 | ;* OUTPUT: Ready to call print routine | ||
| 146 | ;* | ||
| 147 | ;**************************************************************** | ||
| 148 | |||
| 149 | public output_batch_name ;AN022; | ||
| 150 | |||
| 151 | Output_batch_name proc near ;AN022; | ||
| 152 | |||
| 153 | push ds ;AN022; save resident segment | ||
| 154 | mov ds,[batch] ;AN022; get batch file segment | ||
| 155 | assume DS:nothing ;AN022; | ||
| 156 | mov SI,BatFile ;AN022; get offset of batch file | ||
| 157 | invoke dstrlen ;AN022; get length of string | ||
| 158 | mov di,offset Trangroup:bwdbuf ;AN022; target for batch name | ||
| 159 | rep movsb ;AN022; move the name | ||
| 160 | |||
| 161 | push cs ;AN022; get local segment | ||
| 162 | pop ds ;AN022; | ||
| 163 | assume DS:trangroup ;AN022; | ||
| 164 | mov extend_buf_ptr,dx ;AN022; put message number in block | ||
| 165 | mov msg_disp_class,ext_msg_class ;AN022; set up extended error msg class | ||
| 166 | mov dx,offset TranGroup:Extend_Buf_ptr ;AN022; get extended message pointer | ||
| 167 | mov string_ptr_2,offset trangroup:bwdbuf ;AN022; point to substitution | ||
| 168 | mov extend_buf_sub,one_subst ;AN022; set up for one subst | ||
| 169 | pop ds ;AN022; restore data segment | ||
| 170 | |||
| 171 | ret ;AN022; return | ||
| 172 | |||
| 173 | Output_batch_name endp ;AN022; | ||
| 174 | |||
| 175 | Break <GetKeystroke - get a keystroke and flush queue> | ||
| 176 | |||
| 177 | ; | ||
| 178 | ; read the next keystroke. Since there may be several characters in the queue | ||
| 179 | ; after the one we ask for (function keys/Kanji), we need to flush the queue | ||
| 180 | ; AFTER waiting. | ||
| 181 | ; | ||
| 182 | Procedure GetKeyStroke,NEAR | ||
| 183 | ; | ||
| 184 | ; read any character at any mode, interim mode or not. | ||
| 185 | ; | ||
| 186 | |||
| 187 | PUSH DX ;AN000; 3/3/KK | ||
| 188 | MOV AX,(ECS_call SHL 8) OR GetInterimMode ;AN000; 3/3/KK | ||
| 189 | INT int_command ;AN000; 3/3/KK | ||
| 190 | PUSH DX ;AN000; save interim state 3/3/KK | ||
| 191 | MOV AX,(ECS_call SHL 8) OR SetInterimMode ;AN000; 3/3/KK | ||
| 192 | MOV DL,InterimMode ;AN000; 3/3/KK | ||
| 193 | INT int_command ;AN000; 3/3/KK | ||
| 194 | |||
| 195 | MOV AX,(STD_CON_INPUT_FLUSH SHL 8) OR STD_CON_INPUT_no_echo | ||
| 196 | INT int_command ; Get character with KB buffer flush | ||
| 197 | MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0 | ||
| 198 | INT int_command | ||
| 199 | |||
| 200 | MOV AX,(ECS_call SHL 8) OR SetInterimMode ;AN000; 3/3/KK | ||
| 201 | POP DX ;AN000; restore interim state 3/3/KK | ||
| 202 | INT int_command ;AN000; 3/3/KK | ||
| 203 | POP DX ;AN000; 3/3/KK | ||
| 204 | |||
| 205 | return | ||
| 206 | EndProc GetKeyStroke | ||
| 207 | |||
| 208 | Break <ReadBat - read 1 line from batch file> | ||
| 209 | |||
| 210 | ; | ||
| 211 | ; ReadBat - read a single line from the batch file. Perform all substitutions | ||
| 212 | ; as appropriate | ||
| 213 | ; | ||
| 214 | |||
| 215 | Procedure ReadBat,NEAR | ||
| 216 | ASSUME DS:ResGroup,ES:TranGroup | ||
| 217 | mov suppress,yes_echo ;g initialize line suppress status | ||
| 218 | test byte ptr [Batch_Abort],-1 | ||
| 219 | jnz Trying_To_Abort | ||
| 220 | mov byte ptr [In_Batch],1 ; set flag to indicate batch job | ||
| 221 | CALL PromptBat | ||
| 222 | |||
| 223 | Trying_To_Abort: | ||
| 224 | MOV DI,OFFSET TRANGROUP:COMBUF+2 | ||
| 225 | |||
| 226 | ; | ||
| 227 | ; Save position and try to scan for first non delimiter. | ||
| 228 | ; | ||
| 229 | |||
| 230 | TESTNOP: | ||
| 231 | MOV AX,DS | ||
| 232 | MOV DS,Batch | ||
| 233 | ASSUME DS:NOTHING | ||
| 234 | PUSH WORD PTR DS:[BatSeek] | ||
| 235 | PUSH WORD PTR DS:[BatSeek+2] ; save current location. | ||
| 236 | MOV DS,AX | ||
| 237 | ASSUME DS:ResGroup | ||
| 238 | invoke SkipDelim ; skip to first non-delim | ||
| 239 | ; | ||
| 240 | ; If the first non-delimiter is not a : (label), we reseek back to the | ||
| 241 | ; beginning and read the line. | ||
| 242 | ; | ||
| 243 | CMP AL,':' ; is it a label? | ||
| 244 | POP CX | ||
| 245 | POP DX ; restore position in bat file | ||
| 246 | JZ NopLine ; yes, resync everything. | ||
| 247 | TEST [BATCH],-1 ; are we done with the batch file? | ||
| 248 | JZ RdBat | ||
| 249 | |||
| 250 | CMP AL, NO_ECHO_CHAR ;g see if user wants to suppress line | ||
| 251 | JNZ SET_BAT_POS ;g no - go and set batch file position | ||
| 252 | MOV SUPPRESS, NO_ECHO ;g yes set flag to indicate | ||
| 253 | jmp Rdbat ;g go read batch file | ||
| 254 | |||
| 255 | SET_BAT_POS: ;g | ||
| 256 | PUSH DS | ||
| 257 | MOV DS,Batch | ||
| 258 | ASSUME DS:NOTHING | ||
| 259 | MOV WORD PTR DS:[BatSeek],DX ; reseek back to beginning | ||
| 260 | MOV WORD PTR DS:[BatSeek+2],CX | ||
| 261 | POP DS | ||
| 262 | ASSUME DS:ResGroup | ||
| 263 | MOV AX,(LSEEK SHL 8) + 0 ; seek back | ||
| 264 | INT int_command | ||
| 265 | MOV BatBufPos,-1 ; nuke batch buffer position | ||
| 266 | xor cx,cx ; Initialize line length to zero | ||
| 267 | JMP RdBat | ||
| 268 | ; | ||
| 269 | ; The first non-delimiter is a :. This line is not echoed and is ignored. | ||
| 270 | ; We eat characters until a CR is seen. | ||
| 271 | ; | ||
| 272 | |||
| 273 | NOPLINE: | ||
| 274 | CALL SkipToEOL | ||
| 275 | invoke GetBatByt ; eat trailing LF | ||
| 276 | TEST [BATCH],-1 ; are we done with the batch file? | ||
| 277 | JNZ TESTNOP ; no, go get another line | ||
| 278 | return ; Hit EOF | ||
| 279 | |||
| 280 | ; | ||
| 281 | ; Read a line into the buffer pointed to by ES:DI. If any %s are seen in the | ||
| 282 | ; input, we are to consider two special cases: | ||
| 283 | ; | ||
| 284 | ; %0 to %9 These represent replaceable parameters from the batch segment | ||
| 285 | ; %sym% This is a symbol from the environment | ||
| 286 | ; | ||
| 287 | |||
| 288 | RDBAT: | ||
| 289 | invoke GetBatByt | ||
| 290 | inc cx ; Inc the line length | ||
| 291 | cmp cx,COMBUFLEN ; Is it too long? | ||
| 292 | jae TooLong ; Yes - handle it, handle it | ||
| 293 | ; | ||
| 294 | ; See if we have a parameter character. | ||
| 295 | ; | ||
| 296 | CMP AL,'%' ; Check for parameter | ||
| 297 | JZ NEEDPARM | ||
| 298 | ; | ||
| 299 | ; no parameter character. Store it as usual and see if we are done. | ||
| 300 | ; | ||
| 301 | |||
| 302 | SAVBATBYT: | ||
| 303 | STOSB | ||
| 304 | CMP AL,0DH ; End of line found? | ||
| 305 | JNZ RDBAT ; no, go for more | ||
| 306 | ; | ||
| 307 | ; We have read in an entire line. Decide whether we should echo the command | ||
| 308 | ; line or not. | ||
| 309 | ; | ||
| 310 | |||
| 311 | Found_EOL: | ||
| 312 | SUB DI,OFFSET TRANGROUP:COMBUF+3 | ||
| 313 | MOV AX,DI ; remember that we've not counted the CR | ||
| 314 | MOV ES:[COMBUF+1],AL ; Set length of line | ||
| 315 | invoke GetBatByt ; Eat linefeed | ||
| 316 | invoke BATCLOSE | ||
| 317 | CMP SUPPRESS, NO_ECHO ;G | ||
| 318 | JZ Reset ;G | ||
| 319 | test [echoflag],1 ; To echo or not to echo, that is the | ||
| 320 | jnz try_nextflag | ||
| 321 | |||
| 322 | Reset: | ||
| 323 | PUSH CS ; question. (Profound, huh?) | ||
| 324 | POP DS ; Go back to local segment | ||
| 325 | retz ; no echoing here... | ||
| 326 | ; | ||
| 327 | ; Echo the command line with appropriate CRLF... | ||
| 328 | ; | ||
| 329 | |||
| 330 | |||
| 331 | try_nextflag: | ||
| 332 | cmp nullflag,nullcommand ;G was there a command last time? | ||
| 333 | jz No_crlf_print ;G no - don't print crlf | ||
| 334 | invoke CRLF2 ;G Print out prompt | ||
| 335 | |||
| 336 | no_crlf_print: | ||
| 337 | invoke PRINT_PROMPT ;G | ||
| 338 | PUSH CS ;G change data segment | ||
| 339 | POP DS ;G | ||
| 340 | |||
| 341 | ASSUME DS:TRANGROUP | ||
| 342 | mov dx,OFFSET TRANGROUP:COMBUF+2 ; get command line for echoing | ||
| 343 | invoke CRPRINT | ||
| 344 | invoke CRLF2 | ||
| 345 | return | ||
| 346 | ; | ||
| 347 | ; The line was too long. Eat remainder of input text up until the CR | ||
| 348 | ; | ||
| 349 | TooLong: | ||
| 350 | ASSUME DS:ResGroup | ||
| 351 | cmp al,0dh ; Has the end of the line been reached? | ||
| 352 | jz Ltlcont ; Yes, continue | ||
| 353 | CALL SkipToEOL ; Eat remainder of line | ||
| 354 | |||
| 355 | Ltlcont: | ||
| 356 | stosb ; Terminate the command | ||
| 357 | jmp Found_EOL ; Go process the valid part of the line | ||
| 358 | ; | ||
| 359 | ; We have found a parameter lead-in character. Check for the 0-9 case first | ||
| 360 | ; | ||
| 361 | |||
| 362 | NEEDPARM: | ||
| 363 | invoke GetBatByt ; get next character | ||
| 364 | CMP AL,'%' ; Check for two consecutive % | ||
| 365 | JZ SAVBATBYT ; if so, replace with a single % | ||
| 366 | CMP AL,0Dh ; Check for end-of-line | ||
| 367 | JZ SAVBATBYT ; yes, treat it normally | ||
| 368 | ; | ||
| 369 | ; We have found %<something>. If the <something> is in the range 0-9, we | ||
| 370 | ; retrieve the appropriate parameter from the batch segment. Otherwise we | ||
| 371 | ; see if the <something> has a terminating % and then look up the contents | ||
| 372 | ; in the environment | ||
| 373 | ; | ||
| 374 | PAROK: | ||
| 375 | SUB AL,'0' | ||
| 376 | JB NEEDENV ; look for parameter in the environment | ||
| 377 | CMP AL,9 | ||
| 378 | JA NEEDENV | ||
| 379 | ; | ||
| 380 | ; We have found %<number>. This is taken from the parameters in the | ||
| 381 | ; allocated batch area. | ||
| 382 | ; | ||
| 383 | CBW | ||
| 384 | MOV BX,AX ; move index into AX | ||
| 385 | SHL BX,1 ; convert word index into byte ptr | ||
| 386 | SaveReg <ES> | ||
| 387 | MOV ES,Batch | ||
| 388 | ; | ||
| 389 | ; The structure of the batch area is: | ||
| 390 | ; | ||
| 391 | ; BYTE type of segment | ||
| 392 | ; DWORD offset for next line | ||
| 393 | ; 10 WORD pointers to parameters. -1 is empty parameter | ||
| 394 | ; ASCIZ file name (with . and ..) | ||
| 395 | ; BYTES CR-terminated parameters | ||
| 396 | ; BYTE 0 flag to indicate end of parameters | ||
| 397 | ; | ||
| 398 | ; Get pointer to BX'th argument | ||
| 399 | ; | ||
| 400 | MOV SI,ES:BatParm[BX] | ||
| 401 | RestoreReg <ES> | ||
| 402 | ; | ||
| 403 | ; Is there a parameter here? | ||
| 404 | ; | ||
| 405 | CMP SI,-1 ; Check if parameter exists | ||
| 406 | JNZ Yes_there_is ;G Yes go get it | ||
| 407 | JMP RDBAT ; Ignore if it doesn't | ||
| 408 | ; | ||
| 409 | ; Copy in the found parameter from batch segment | ||
| 410 | ; | ||
| 411 | |||
| 412 | Yes_there_is: | ||
| 413 | PUSH DS | ||
| 414 | MOV DS,Batch | ||
| 415 | ASSUME DS:NOTHING | ||
| 416 | dec cx ; Don't count '%' in line length | ||
| 417 | |||
| 418 | CopyParm: | ||
| 419 | LODSB ; From resident segment | ||
| 420 | CMP AL,0DH ; Check for end of parameter | ||
| 421 | JZ EndParam | ||
| 422 | inc cx ; Inc the line length | ||
| 423 | cmp cx,COMBUFLEN ; Is it too long? | ||
| 424 | jae LineTooL ; Yes - handle it, handle it | ||
| 425 | STOSB | ||
| 426 | JMP CopyParm | ||
| 427 | ; | ||
| 428 | ; We have copied up to the limit. Stop copying and eat remainder of batch | ||
| 429 | ; line. We need to make sure that the tooLong code isn't fooled into | ||
| 430 | ; believing that we are at EOL. Clobber AL too. | ||
| 431 | ; | ||
| 432 | |||
| 433 | LineTooL: | ||
| 434 | XOR AL,AL | ||
| 435 | POP DS | ||
| 436 | ASSUME DS:RESGROUP | ||
| 437 | JMP TooLong | ||
| 438 | ; | ||
| 439 | ; We have copied in an entire parameter. Go back for more | ||
| 440 | ; | ||
| 441 | |||
| 442 | EndParam: | ||
| 443 | POP DS | ||
| 444 | JMP RDBat | ||
| 445 | ; | ||
| 446 | ; We have found % followed by something other than 0-9. We presume that there | ||
| 447 | ; will be a following % character. In between is an environment variable that | ||
| 448 | ; we will fetch and replace in the batch line with its value. | ||
| 449 | ; | ||
| 450 | |||
| 451 | NEEDENV: | ||
| 452 | SaveReg <DS,DI> | ||
| 453 | MOV DI,OFFSET TRANGROUP:ID ; temp spot for name | ||
| 454 | ADD AL,'0' ; reconvert character | ||
| 455 | STOSB ; store it in appropriate place | ||
| 456 | ; | ||
| 457 | ; loop getting characters until the next % is found or until EOL | ||
| 458 | ; | ||
| 459 | |||
| 460 | GETENV1: | ||
| 461 | invoke GetBatByt ; get the byte | ||
| 462 | STOSB ; store it | ||
| 463 | CMP AL,0Dh ; EOL? | ||
| 464 | JNZ GETENV15 ; no, see if it the term char | ||
| 465 | ; | ||
| 466 | ; The user entered a string with a % but no trailing %. We copy the string. | ||
| 467 | ; | ||
| 468 | mov byte ptr es:[di-1],0 ; nul terminate the string | ||
| 469 | mov si,offset TranGroup:ID ; point to buffer | ||
| 470 | pop di ; point to line buffer | ||
| 471 | push cs | ||
| 472 | pop ds | ||
| 473 | call StrCpy | ||
| 474 | IF IBMCOPYRIGHT | ||
| 475 | dec di | ||
| 476 | pop ds | ||
| 477 | ELSE | ||
| 478 | pop ds | ||
| 479 | jc LineTooL | ||
| 480 | ENDIF | ||
| 481 | jmp SavBatByt | ||
| 482 | |||
| 483 | getenv15: | ||
| 484 | CMP AL,'%' ; terminating %? | ||
| 485 | JNZ GETENV1 ; no, go suck out more characters | ||
| 486 | mov al,'=' ; terminate with = | ||
| 487 | MOV ES:[DI-1],al | ||
| 488 | ; | ||
| 489 | ; ID now either has a =-terminated string which we are to find in the | ||
| 490 | ; environment or a non =-terminated string which will not be found in the | ||
| 491 | ; environment. | ||
| 492 | ; | ||
| 493 | GETENV2: | ||
| 494 | MOV SI,OFFSET TRANGROUP:ID | ||
| 495 | PUSH CS | ||
| 496 | POP DS ; DS:SI POINTS TO NAME | ||
| 497 | ASSUME DS:TRANGROUP | ||
| 498 | PUSH CX | ||
| 499 | INVOKE FIND_NAME_IN_environment | ||
| 500 | ASSUME ES:RESGROUP | ||
| 501 | POP CX | ||
| 502 | PUSH ES | ||
| 503 | POP DS | ||
| 504 | assume ds:resgroup | ||
| 505 | PUSH CS | ||
| 506 | POP ES | ||
| 507 | ASSUME ES:TRANGROUP | ||
| 508 | MOV SI,DI | ||
| 509 | POP DI ; get back pointer to command line | ||
| 510 | ; | ||
| 511 | ; If the parameter was not found, there is no need to perform any replacement. | ||
| 512 | ; We merely pretend that we've copied the parameter. | ||
| 513 | ; | ||
| 514 | IF IBMCOPYRIGHT | ||
| 515 | JC GETENV6 | ||
| 516 | ELSE | ||
| 517 | jnc GETENV4 | ||
| 518 | pop ds | ||
| 519 | jmp rdbat | ||
| 520 | ENDIF | ||
| 521 | ; | ||
| 522 | ; ES:DI points to command line being built | ||
| 523 | ; DS:SI points either to nul-terminated environment object AFTER = | ||
| 524 | ; | ||
| 525 | |||
| 526 | GETENV4: | ||
| 527 | ASSUME ES:NOTHING | ||
| 528 | call StrCpy | ||
| 529 | |||
| 530 | IF IBMCOPYRIGHT | ||
| 531 | dec di | ||
| 532 | |||
| 533 | GETENV6: | ||
| 534 | POP DS ; restore pointer to resgroup | ||
| 535 | ELSE | ||
| 536 | pop ds | ||
| 537 | jc LineTooL | ||
| 538 | ENDIF | ||
| 539 | JMP RDBAT ; no, go back to batch file | ||
| 540 | |||
| 541 | EndProc ReadBat | ||
| 542 | |||
| 543 | ; | ||
| 544 | ; SkipToEOL - read from batch file until end of line | ||
| 545 | ; | ||
| 546 | |||
| 547 | Procedure SkipToEOL,NEAR | ||
| 548 | |||
| 549 | ASSUME DS:ResGroup,ES:NOTHING | ||
| 550 | |||
| 551 | TEST Batch,-1 | ||
| 552 | retz ; no batch file in effect | ||
| 553 | invoke GetBatByt | ||
| 554 | CMP AL,0Dh ; eol character? | ||
| 555 | JNZ SkipToEOL ; no, go eat another | ||
| 556 | return | ||
| 557 | |||
| 558 | EndProc SkipToEOL | ||
| 559 | |||
| 560 | Break <Allocate and deallocate the transient portion> | ||
| 561 | |||
| 562 | ; | ||
| 563 | ; Free Transient. Modify ES,AX,flags | ||
| 564 | ; | ||
| 565 | |||
| 566 | Procedure Free_TPA,NEAR | ||
| 567 | |||
| 568 | ASSUME DS:TRANGROUP,ES:RESGROUP | ||
| 569 | |||
| 570 | PUSH ES | ||
| 571 | MOV ES,[RESSEG] | ||
| 572 | MOV ES,[RES_TPA] | ||
| 573 | MOV AH,DEALLOC | ||
| 574 | INT int_command ; Make lots of free memory | ||
| 575 | POP ES | ||
| 576 | |||
| 577 | return | ||
| 578 | |||
| 579 | EndProc Free_TPA | ||
| 580 | |||
| 581 | ; | ||
| 582 | ; Allocate transient. Modify AX,BX,DX,flags | ||
| 583 | ; | ||
| 584 | |||
| 585 | Procedure Alloc_TPA,NEAR | ||
| 586 | |||
| 587 | ASSUME DS:TRANGROUP,ES:RESGROUP | ||
| 588 | |||
| 589 | PUSH ES | ||
| 590 | MOV ES,[RESSEG] | ||
| 591 | MOV BX,0FFFFH ; Re-allocate the transient | ||
| 592 | MOV AH,ALLOC | ||
| 593 | INT int_command | ||
| 594 | PUSH BX ; Save size of block | ||
| 595 | MOV AH,ALLOC | ||
| 596 | INT int_command | ||
| 597 | ; | ||
| 598 | ; Attempt to align TPA on 64K boundary | ||
| 599 | ; | ||
| 600 | POP BX ; Restore size of block | ||
| 601 | MOV [RES_TPA], AX ; Save segment to beginning of block | ||
| 602 | MOV [TRAN_TPA], AX | ||
| 603 | ; | ||
| 604 | ; Is the segment already aligned on a 64K boundary | ||
| 605 | ; | ||
| 606 | MOV DX, AX ; Save segment | ||
| 607 | AND AX, 0FFFH ; Test if above boundary | ||
| 608 | JNZ Calc_TPA | ||
| 609 | MOV AX, DX | ||
| 610 | AND AX, 0F000H ; Test if multiple of 64K | ||
| 611 | JNZ NOROUND | ||
| 612 | |||
| 613 | Calc_TPA: | ||
| 614 | MOV AX, DX | ||
| 615 | AND AX, 0F000H | ||
| 616 | ADD AX, 01000H ; Round up to next 64K boundary | ||
| 617 | JC NOROUND ; Memory wrap if carry set | ||
| 618 | ; | ||
| 619 | ; Make sure that new boundary is within allocated range | ||
| 620 | ; | ||
| 621 | MOV DX, [RES_TPA] | ||
| 622 | ADD DX, BX ; Compute maximum address | ||
| 623 | CMP DX, AX ; Is 64K address out of range? | ||
| 624 | JB NOROUND | ||
| 625 | ; | ||
| 626 | ; Make sure that we won't overwrite the transient | ||
| 627 | ; | ||
| 628 | MOV BX, CS ; CS is beginning of transient | ||
| 629 | CMP BX, AX | ||
| 630 | JB NOROUND | ||
| 631 | ; | ||
| 632 | ; The area from the 64K boundary to the beginning of the transient must | ||
| 633 | ; be at least 64K. | ||
| 634 | ; | ||
| 635 | SUB BX, AX | ||
| 636 | CMP BX, 4096 ; Size greater than 64K? | ||
| 637 | JAE ROUNDDONE | ||
| 638 | |||
| 639 | NOROUND: | ||
| 640 | MOV AX, [RES_TPA] | ||
| 641 | |||
| 642 | ROUNDDONE: | ||
| 643 | MOV [LTPA],AX ; Re-compute everything | ||
| 644 | MOV [TPA],AX | ||
| 645 | MOV BX,AX | ||
| 646 | MOV AX,CS | ||
| 647 | SUB AX,BX | ||
| 648 | PUSH BX | ||
| 649 | MOV BX,16 | ||
| 650 | MUL BX | ||
| 651 | POP BX | ||
| 652 | OR DX,DX | ||
| 653 | JZ SAVSIZ2 | ||
| 654 | MOV AX,-1 | ||
| 655 | |||
| 656 | SAVSIZ2: | ||
| 657 | ; | ||
| 658 | ; AX is the number of bytes free in the buffer between the resident and the | ||
| 659 | ; transient with a maximum of 64K-1. We round this down to a multiple of 512. | ||
| 660 | ; | ||
| 661 | CMP AX,512 | ||
| 662 | JBE GotSize | ||
| 663 | AND AX,0FE00h ; NOT 511 = NOT 1FF | ||
| 664 | |||
| 665 | GotSize: | ||
| 666 | MOV [BYTCNT],AX | ||
| 667 | POP ES | ||
| 668 | |||
| 669 | return | ||
| 670 | |||
| 671 | EndProc Alloc_TPA | ||
| 672 | |||
| 673 | Break <BatCom - enter a batch file> | ||
| 674 | |||
| 675 | ; | ||
| 676 | ; The exec search has determined that the user has requested a batch file for | ||
| 677 | ; execution. We parse the arguments, create the batch segment, and signal | ||
| 678 | ; batch processing. | ||
| 679 | ; | ||
| 680 | Procedure BatCom,NEAR | ||
| 681 | |||
| 682 | ASSUME DS:TRANGROUP, ES:NOTHING | ||
| 683 | |||
| 684 | ; | ||
| 685 | ; Batch parameters are read with ES set to segment of resident part | ||
| 686 | ; | ||
| 687 | |||
| 688 | MOV ES,[RESSEG] | ||
| 689 | ASSUME ES:RESGROUP | ||
| 690 | cmp es:[call_batch_flag],call_in_progress ;AN043; If in CALL, | ||
| 691 | jz skip_ioset ;AN043; redirection was already set up | ||
| 692 | invoke IOSET ; Set up any redirection | ||
| 693 | |||
| 694 | skip_ioset: ;AN043; | ||
| 695 | CALL FREE_TPA ; G | ||
| 696 | cmp es:[call_batch_flag],call_in_progress ;G | ||
| 697 | jz getecho ; G if we're in a call, don't execute | ||
| 698 | ; | ||
| 699 | ; Since BATCH has lower precedence than PIPE or FOR. If a new BATCH file is | ||
| 700 | ; being started it MUST be true that no FOR or PIPE is currently in progress. | ||
| 701 | ; Don't execute if in call | ||
| 702 | ; | ||
| 703 | invoke ForOff | ||
| 704 | |||
| 705 | getecho: | ||
| 706 | invoke PipeOff | ||
| 707 | mov al,EchoFlag ; preserve echo state for chaining | ||
| 708 | |||
| 709 | and al, 1 ; Save current echo state | ||
| 710 | push ax | ||
| 711 | |||
| 712 | xor ax,ax ;G | ||
| 713 | test es:[batch],-1 ;G Are we in a batch file? | ||
| 714 | jz leavebat ;G No, nothing to save | ||
| 715 | mov ax,es:[batch] ;G get current batch segment | ||
| 716 | cmp es:[call_batch_flag],call_in_progress ;G | ||
| 717 | jz leavebat ;G | ||
| 718 | ; | ||
| 719 | ; We are in a chained batch file, save batlast from previous batch segment | ||
| 720 | ; so that if we're in a CALL, we will return to the correct batch file. | ||
| 721 | ; | ||
| 722 | push es ;G | ||
| 723 | mov es,ax ;G get current batch segment | ||
| 724 | mov ax,es:[batlast] ;G get previous batch segment | ||
| 725 | pop es ;G | ||
| 726 | |||
| 727 | leavebat: ;G | ||
| 728 | push ax ;G keep segment until new one created | ||
| 729 | cmp es:[call_batch_flag],call_in_progress ;G are we in a CALL? | ||
| 730 | jz startbat ;G Yes, keep current batch segment | ||
| 731 | call BatchOff ;G No, deallocate old batch segment | ||
| 732 | |||
| 733 | ; | ||
| 734 | ; Find length of batch file | ||
| 735 | ; | ||
| 736 | |||
| 737 | startbat: ;G | ||
| 738 | ASSUME ES:RESGROUP | ||
| 739 | MOV es:[CALL_BATCH_FLAG], 0 ;G reset call flag | ||
| 740 | mov SI, OFFSET TRANGROUP:EXECPATH | ||
| 741 | |||
| 742 | mov ax,AppendTruename ;AN042; Get the real path where the batch file | ||
| 743 | int 2fh ;AN042; was found with APPEND | ||
| 744 | mov ah,Find_First ;AN042; The find_first will return it | ||
| 745 | mov dx,si ;AN042; Get the string | ||
| 746 | mov cx,search_attr ;AN042; filetypes to search for | ||
| 747 | int int_command ;AN042; | ||
| 748 | |||
| 749 | invoke DStrLen | ||
| 750 | ; | ||
| 751 | ; Allocate batch area: | ||
| 752 | ; BYTE type of segment | ||
| 753 | ; WORD segment of last batch file | ||
| 754 | ; WORD segment for FOR command | ||
| 755 | ; BYTE FOR flag state on entry to batch file | ||
| 756 | ; DWORD offset for next line | ||
| 757 | ; 10 WORD pointers to parameters. -1 is empty parameter | ||
| 758 | ; ASCIZ file name (with . and ..) | ||
| 759 | ; BYTES CR-terminated parameters | ||
| 760 | ; BYTE 0 flag to indicate end of parameters | ||
| 761 | ; | ||
| 762 | ; We allocate the maximum size for the command line and use setblock to shrink | ||
| 763 | ; later when we've squeezed out the extra | ||
| 764 | ; | ||
| 765 | |||
| 766 | MOV BX,CX ; length of file name. | ||
| 767 | ADD BX,0Fh + (SIZE BatchSegment) + COMBUFLEN + 0Fh | ||
| 768 | ; structure + max len + round up | ||
| 769 | SaveReg <CX> | ||
| 770 | MOV CL,4 | ||
| 771 | SHR BX,CL ; convert to paragraphs | ||
| 772 | PUSH BX ;G save size of batch segment | ||
| 773 | MOV AH,ALLOC | ||
| 774 | INT int_command ; Allocate batch segment | ||
| 775 | POP BX ;G get size of batch segment | ||
| 776 | ; | ||
| 777 | ; This should *NEVER* return an error. The transient is MUCH bigger than | ||
| 778 | ; the batch segment. This may not be true, however, in a multitasking system. | ||
| 779 | ; G This error will occur with nesting of batch files. We also need to | ||
| 780 | ; G make sure that we don't overlay the transient. | ||
| 781 | ; | ||
| 782 | jc mem_error ;G not enough memory - exit | ||
| 783 | push ax ;G save batch segment | ||
| 784 | add ax,bx ;G get end of batch segment | ||
| 785 | add ax,20h ;G add some tpa work area | ||
| 786 | mov bx,cs ;G get the transient segment | ||
| 787 | cmp ax,bx ;G do we end before the transient | ||
| 788 | pop ax ;G get batch segment back | ||
| 789 | jb enough_mem ;G we have enough memory - continue | ||
| 790 | push es ;G no we're hitting the transient | ||
| 791 | mov es,ax | ||
| 792 | mov ax,DEALLOC SHL 8 ;G deallocate the batch segment | ||
| 793 | int int_command | ||
| 794 | pop es | ||
| 795 | |||
| 796 | mem_error: | ||
| 797 | jmp no_memory ;G Set up for message and exit | ||
| 798 | |||
| 799 | enough_mem: | ||
| 800 | MOV [BATCH],AX | ||
| 801 | CALL ALLOC_TPA | ||
| 802 | ; | ||
| 803 | ; Initialize batch segment | ||
| 804 | ; | ||
| 805 | RestoreReg <DX> ; length of name | ||
| 806 | POP AX ;G get saved batch segment back | ||
| 807 | inc es:nest ;G increment # batch files in progress | ||
| 808 | PUSH ES | ||
| 809 | MOV ES,[BATCH] | ||
| 810 | ASSUME ES:NOTHING | ||
| 811 | MOV ES:[BatType],BatchType ; signal batch file type | ||
| 812 | MOV ES:[batlast],ax ;G save segment of last batch file | ||
| 813 | push DS ;G | ||
| 814 | mov DS,[resseg] ;G set to resident data | ||
| 815 | ASSUME DS:RESGROUP | ||
| 816 | xor ax,ax ;G | ||
| 817 | mov bl,forflag ;G get the current FOR state | ||
| 818 | mov ES:[batforflag],bl ;G save it in the batch segment | ||
| 819 | test bl,-1 ;G are we in a FOR? | ||
| 820 | jz for_not_on ;G no, for segment set to 0 | ||
| 821 | mov ax,forptr ;G yes, get current FOR segment | ||
| 822 | mov forflag,0 ;G reset forflag | ||
| 823 | |||
| 824 | for_not_on: | ||
| 825 | mov ES:[batforptr],ax ;G save FOR segment in batch segment | ||
| 826 | XOR AX,AX | ||
| 827 | mov forptr,ax ;G make sure for segment is not active | ||
| 828 | mov bl,echoflag ;G | ||
| 829 | pop DS ;G | ||
| 830 | |||
| 831 | mov byte ptr es:[Batechoflag],bl ;G save echo state of parent | ||
| 832 | MOV WORD PTR ES:[BatSeek],AX ; point to beginning of file | ||
| 833 | MOV WORD PTR ES:[BatSeek+2],AX | ||
| 834 | ; | ||
| 835 | ; Initialize pointers | ||
| 836 | ; | ||
| 837 | DEC AX ; put -1 into AX | ||
| 838 | MOV DI,BatParm ; point to parm area | ||
| 839 | MOV BX,DI | ||
| 840 | MOV CX,10 | ||
| 841 | REP STOSW ; Init to no parms | ||
| 842 | ; | ||
| 843 | ; Move in batch file name | ||
| 844 | ; | ||
| 845 | MOV CX,DX | ||
| 846 | rep movsb ; including NUL. | ||
| 847 | ; | ||
| 848 | ; Now copy the command line into batch segment, parsing the arguments along | ||
| 849 | ; the way. Segment will look like this: | ||
| 850 | ; | ||
| 851 | ; <arg0>CR<arg1>CR...<arg9>CR<arg10>CR...<ARGn>CR 0 | ||
| 852 | ; | ||
| 853 | ; or, in the case of fewer arguments: | ||
| 854 | ; | ||
| 855 | ; <arg0>CR<arg1>CR...<arg6>CR CR CR ... CR 0 | ||
| 856 | ; | ||
| 857 | MOV SI,OFFSET TRANGROUP:COMBUF+2 | ||
| 858 | MOV CX,10 ; at most 10 arguments | ||
| 859 | ; | ||
| 860 | ; Look for beginning of next argument | ||
| 861 | ; | ||
| 862 | EACHPARM: | ||
| 863 | invoke SCANOFF ; skip to argument | ||
| 864 | ; | ||
| 865 | ; AL is first non-delimiter. DS:SI points to char = AL | ||
| 866 | ; | ||
| 867 | CMP AL,0DH ; end of road? | ||
| 868 | JZ HAVPARM ; yes, no more arguments | ||
| 869 | ; | ||
| 870 | ; If CX = 0 then we have stored the most parm we can. Skip store | ||
| 871 | ; | ||
| 872 | JCXZ MOVPARM ; Only first 10 parms get pointers | ||
| 873 | ; | ||
| 874 | ; Go into allocated piece and stick in new argument pointer. | ||
| 875 | ; | ||
| 876 | MOV ES:[BX],DI ; store batch pointer | ||
| 877 | ADD BX,2 ; advance arg counter | ||
| 878 | ; | ||
| 879 | ; Move the parameter into batch segment | ||
| 880 | ; | ||
| 881 | MOVPARM: | ||
| 882 | LODSB ; get byte | ||
| 883 | INVOKE DELIM ; if delimiter | ||
| 884 | JZ ENDPARM ; then done with parm | ||
| 885 | STOSB ; store byte | ||
| 886 | CMP AL,0DH ; if CR then not delimiter | ||
| 887 | JZ HAVPARM ; but end of parm list, finish | ||
| 888 | JMP SHORT MOVPARM | ||
| 889 | ; | ||
| 890 | ; We have copied a parameter up until the first separator. Terminate it with | ||
| 891 | ; CR | ||
| 892 | ; | ||
| 893 | |||
| 894 | ENDPARM: | ||
| 895 | MOV AL,0DH | ||
| 896 | STOSB | ||
| 897 | JCXZ EACHPARM ; if no parameters, don't dec | ||
| 898 | DEC CX ; remember that we've seen one. | ||
| 899 | JMP SHORT EACHPARM | ||
| 900 | ; | ||
| 901 | ; We have parsed the entire line. Terminate the arg list | ||
| 902 | ; | ||
| 903 | |||
| 904 | HAVPARM: | ||
| 905 | XOR AL,AL | ||
| 906 | STOSB ; Nul terminate the parms | ||
| 907 | ; | ||
| 908 | ; Now we know EXACTLY how big the BATCH segment is. Round up size (from DI) | ||
| 909 | ; into paragraphs and setblock to the appropriate size | ||
| 910 | ; | ||
| 911 | LEA BX,[DI+15] | ||
| 912 | MOV CL,4 | ||
| 913 | SHR BX,CL | ||
| 914 | MOV AH,SetBlock | ||
| 915 | INT int_command | ||
| 916 | |||
| 917 | POP ES | ||
| 918 | ASSUME ES:RESGROUP | ||
| 919 | PUSH ES | ||
| 920 | POP DS ; Simply batch FCB setup | ||
| 921 | ASSUME DS:RESGROUP | ||
| 922 | CMP [SINGLECOM],-1 | ||
| 923 | JNZ NOBATSING | ||
| 924 | MOV [SINGLECOM],0FFF0H ; Flag single command BATCH job | ||
| 925 | |||
| 926 | NOBATSING: | ||
| 927 | ; | ||
| 928 | ; Enter the batch file with the current echo state | ||
| 929 | ; | ||
| 930 | pop ax ; Get original echo state | ||
| 931 | mov echoflag,al ;g restore it | ||
| 932 | JMP TCOMMAND | ||
| 933 | |||
| 934 | ; | ||
| 935 | ; The following is executed if there isn't enough memory for batch segment | ||
| 936 | ; | ||
| 937 | |||
| 938 | NO_MEMORY: | ||
| 939 | assume ds:trangroup,es:resgroup | ||
| 940 | pop dx ;g even up our stack | ||
| 941 | pop ax ;g | ||
| 942 | pop ax ;g | ||
| 943 | call Alloc_tpa ;g reallocate memory | ||
| 944 | mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class | ||
| 945 | mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer | ||
| 946 | mov Extend_Buf_ptr,error_not_enough_memory ;AN000; get message number in control block | ||
| 947 | jmp cerror ;g print error message and go... | ||
| 948 | |||
| 949 | EndProc BatCom | ||
| 950 | |||
| 951 | Procedure BatchOff | ||
| 952 | |||
| 953 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 954 | |||
| 955 | SaveReg <AX,ES> | ||
| 956 | PUSH DS ;G | ||
| 957 | PUSH BX ;G | ||
| 958 | MOV ES,ResSeg | ||
| 959 | MOV DS,ResSeg ;G | ||
| 960 | ASSUME ES:ResGroup,DS:Resgroup ;G | ||
| 961 | MOV AX,Batch ; Free the batch segment | ||
| 962 | OR AX,AX | ||
| 963 | JZ nofree | ||
| 964 | |||
| 965 | PUSH ES | ||
| 966 | MOV ES,AX | ||
| 967 | test [echoflag],1 ;G Is echo on? | ||
| 968 | jnz echo_last_line ;G Yes - echo last line in file | ||
| 969 | mov suppress,no_echo ;G no - don't echo last line in file | ||
| 970 | |||
| 971 | echo_last_line: | ||
| 972 | MOV BL,ES:[BATECHOFLAG] ;G Get echo state | ||
| 973 | mov [echoflag],bl ;G and restore it | ||
| 974 | MOV BX,ES:[BATFORPTR] ;G Get FOR segment | ||
| 975 | MOV FORPTR,BX ;G and restore it | ||
| 976 | MOV BL,ES:[BATFORFLAG] ;G Get FOR flag | ||
| 977 | MOV FORFLAG,BL ;G and restore it | ||
| 978 | MOV BX,es:[batlast] ;G get old batch segment | ||
| 979 | MOV AH,DEALLOC | ||
| 980 | INT int_command | ||
| 981 | POP ES | ||
| 982 | MOV Next_BATCH,BX ;G reset batch segment | ||
| 983 | DEC es:NEST ;G | ||
| 984 | |||
| 985 | XOR AX,AX | ||
| 986 | MOV Batch,AX ; No batch in progress | ||
| 987 | |||
| 988 | NoFree: | ||
| 989 | POP BX ;G | ||
| 990 | pop ds ;G | ||
| 991 | RestoreReg <ES,AX> | ||
| 992 | |||
| 993 | return | ||
| 994 | |||
| 995 | EndProc BatchOff | ||
| 996 | |||
| 997 | |||
| 998 | IF IBMCOPYRIGHT | ||
| 999 | |||
| 1000 | Procedure StrCpy,near | ||
| 1001 | |||
| 1002 | push ax | ||
| 1003 | cycle: | ||
| 1004 | lodsb | ||
| 1005 | stosb | ||
| 1006 | or al,al | ||
| 1007 | jnz cycle | ||
| 1008 | pop ax | ||
| 1009 | |||
| 1010 | return | ||
| 1011 | |||
| 1012 | EndProc StrCpy | ||
| 1013 | |||
| 1014 | ELSE | ||
| 1015 | ; StrCpy - copy string, checking count in CX against COMBUFLEN | ||
| 1016 | ; Entry : DS:SI ==> source string | ||
| 1017 | ; ES:DI ==> destination string | ||
| 1018 | ; CX = current length of destination string | ||
| 1019 | ; Exit : string copied, CX updated, Carry set if length limit exceeded | ||
| 1020 | Procedure StrCpy,NEAR | ||
| 1021 | push ax | ||
| 1022 | ccycle: | ||
| 1023 | lodsb | ||
| 1024 | inc cx | ||
| 1025 | cmp cx,COMBUFLEN | ||
| 1026 | jb ccopy | ||
| 1027 | stc ; set carry to signal error | ||
| 1028 | jmp short ccend | ||
| 1029 | ccopy: | ||
| 1030 | stosb | ||
| 1031 | or al,al | ||
| 1032 | jnz ccycle | ||
| 1033 | |||
| 1034 | ccend: | ||
| 1035 | dec cx ; discount extra byte | ||
| 1036 | dec di ; back up pointer | ||
| 1037 | pop ax | ||
| 1038 | return ; return carry clear | ||
| 1039 | EndProc StrCpy | ||
| 1040 | |||
| 1041 | ENDIF | ||
| 1042 | |||
| 1043 | TRANCODE ENDS | ||
| 1044 | END | ||
| 1045 | |||
diff --git a/v4.0/src/CMD/COMMAND/TBATCH2.ASM b/v4.0/src/CMD/COMMAND/TBATCH2.ASM new file mode 100644 index 0000000..501c637 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/TBATCH2.ASM | |||
| @@ -0,0 +1,753 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)tbatch2.asm 4.2 85/07/22 | ||
| 3 | ; SCCSID = @(#)tbatch2.asm 4.2 85/07/22 | ||
| 4 | TITLE Batch processing routines part II | ||
| 5 | |||
| 6 | INCLUDE comsw.asm | ||
| 7 | |||
| 8 | .xlist | ||
| 9 | .xcref | ||
| 10 | INCLUDE DOSSYM.INC | ||
| 11 | INCLUDE comseg.asm | ||
| 12 | INCLUDE comequ.asm | ||
| 13 | .list | ||
| 14 | .cref | ||
| 15 | |||
| 16 | |||
| 17 | DATARES SEGMENT PUBLIC BYTE ;AC000; | ||
| 18 | EXTRN BATCH:WORD | ||
| 19 | EXTRN Batch_Abort:byte | ||
| 20 | EXTRN call_batch_flag:byte | ||
| 21 | EXTRN call_flag:byte | ||
| 22 | EXTRN IFFlag:BYTE | ||
| 23 | EXTRN In_Batch:byte | ||
| 24 | EXTRN Nest:word | ||
| 25 | EXTRN PIPEFILES:BYTE | ||
| 26 | EXTRN RETCODE:WORD | ||
| 27 | EXTRN SINGLECOM:WORD | ||
| 28 | DATARES ENDS | ||
| 29 | |||
| 30 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 31 | EXTRN BADLAB_PTR:WORD | ||
| 32 | EXTRN BatBufLen:WORD | ||
| 33 | EXTRN IFTAB:BYTE | ||
| 34 | EXTRN SYNTMES_PTR:WORD | ||
| 35 | TRANDATA ENDS | ||
| 36 | |||
| 37 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 38 | EXTRN arg:byte ; the arg structure! | ||
| 39 | EXTRN BatBuf:BYTE | ||
| 40 | EXTRN BatBufEnd:WORD | ||
| 41 | EXTRN BatBufPos:WORD | ||
| 42 | EXTRN BATHAND:WORD | ||
| 43 | EXTRN COMBUF:BYTE | ||
| 44 | EXTRN DIRBUF:BYTE | ||
| 45 | EXTRN GOTOLEN:WORD | ||
| 46 | EXTRN if_not_count:word | ||
| 47 | EXTRN IFNOTFLAG:BYTE | ||
| 48 | EXTRN RESSEG:WORD | ||
| 49 | TRANSPACE ENDS | ||
| 50 | |||
| 51 | TRANCODE SEGMENT PUBLIC BYTE | ||
| 52 | |||
| 53 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 54 | |||
| 55 | EXTRN cerror:near | ||
| 56 | EXTRN docom1:near | ||
| 57 | EXTRN tcommand:near | ||
| 58 | |||
| 59 | public $if,iferlev,goto,shift,ifexists,ifnot,forerror,$call | ||
| 60 | |||
| 61 | |||
| 62 | Break <GetBatByt - retrieve a byte from the batch file> | ||
| 63 | |||
| 64 | ; Get one byte from the batch file and return it in AL. End-of-file returns | ||
| 65 | ; <CR> and ends batch mode. DS must be set to resident segment. | ||
| 66 | ; AH, DX destroyed. | ||
| 67 | |||
| 68 | Procedure GETBATBYT,NEAR | ||
| 69 | |||
| 70 | ASSUME DS:RESGROUP | ||
| 71 | |||
| 72 | SaveReg <BX,CX,DS> | ||
| 73 | test byte ptr [Batch_Abort],-1 | ||
| 74 | jnz BatEOF | ||
| 75 | TEST Batch,-1 | ||
| 76 | JZ BatEOF | ||
| 77 | PUSH ES | ||
| 78 | MOV ES,Batch | ||
| 79 | ASSUME ES:NOTHING | ||
| 80 | ADD WORD PTR ES:[BatSeek],1 | ||
| 81 | ADC WORD PTR ES:[BatSeek+2],0 | ||
| 82 | POP ES | ||
| 83 | ; | ||
| 84 | ; See if we have bytes buffered... | ||
| 85 | ; | ||
| 86 | MOV AX,CS | ||
| 87 | MOV DS,AX | ||
| 88 | ASSUME DS:TranGroup | ||
| 89 | MOV BX,BatBufPos | ||
| 90 | CMP BX,-1 | ||
| 91 | JNZ UnBuf | ||
| 92 | ; | ||
| 93 | ; There are no bytes in the buffer. Let's try to fill it up. | ||
| 94 | ; | ||
| 95 | MOV DX,OFFSET TranGROUP:BatBuf | ||
| 96 | MOV CX,BatBufLen ; max to read. | ||
| 97 | MOV BX,BatHand | ||
| 98 | MOV AH,READ | ||
| 99 | INT int_command ; Get one more byte from batch file | ||
| 100 | jnc bat_read_ok ;AN022; if no error - continue | ||
| 101 | invoke get_ext_error_number ;AN022; get the error | ||
| 102 | push ds ;AN022; save local segment | ||
| 103 | mov ds,[resseg] ;AN022; get resident segment | ||
| 104 | assume ds:resgroup ;AN022; | ||
| 105 | mov dx,ax ;AN022; put error in DX | ||
| 106 | invoke output_batch_name ;AN022; set up to print the error | ||
| 107 | pop ds ;AN022; | ||
| 108 | assume ds:trangroup ;AN022; | ||
| 109 | invoke std_eprintf ;AN022; print out the error | ||
| 110 | mov byte ptr combuf+2,end_of_line_in;AN022; terminate the batch line for parsing | ||
| 111 | mov byte ptr combuf+3,end_of_line_out ;AN022; terminate the batch line for output | ||
| 112 | jmp bateof ;AN022; terminate the batch file | ||
| 113 | |||
| 114 | bat_read_ok: ;AN022; | ||
| 115 | MOV CX,AX | ||
| 116 | JCXZ BATEOFDS | ||
| 117 | MOV BatBufEnd,CX | ||
| 118 | XOR BX,BX | ||
| 119 | MOV BatBufPos,BX | ||
| 120 | ; | ||
| 121 | ; Buffered bytes! | ||
| 122 | ; | ||
| 123 | UnBuf: | ||
| 124 | MOV AL,BatBuf[BX] ; get next byte | ||
| 125 | INC BX | ||
| 126 | CMP BX,BatBufEnd ; beyond end of buffer? | ||
| 127 | JB SetBufPos | ||
| 128 | MOV BX,-1 | ||
| 129 | |||
| 130 | SetBufPos: | ||
| 131 | MOV BatBufPos,BX | ||
| 132 | CMP AL,1AH ; ^Z for termination? | ||
| 133 | jnz GetByteDone | ||
| 134 | |||
| 135 | BatEOFDS: | ||
| 136 | ASSUME DS:TranGroup | ||
| 137 | MOV DS,ResSeg | ||
| 138 | ASSUME DS:ResGroup | ||
| 139 | |||
| 140 | BATEOF: | ||
| 141 | invoke BatchOff | ||
| 142 | CALL BATCLOSE | ||
| 143 | MOV AL,0DH ; If end-of-file, then end of line | ||
| 144 | test byte ptr [Batch_Abort],-1 | ||
| 145 | mov byte ptr [Batch_Abort],0 | ||
| 146 | jz Cont_Get_Byt | ||
| 147 | mov di,offset TRANGROUP:COMBUF+2 ; reset pointer to beginning of buffer | ||
| 148 | xor cx,cx ; zero line length | ||
| 149 | jmp short GetByteDone | ||
| 150 | |||
| 151 | Cont_Get_Byt: | ||
| 152 | CMP [SINGLECOM],0FFF0H ; See if we need to set SINGLECOM | ||
| 153 | JNZ GetByteDone | ||
| 154 | CMP NEST,0 ;G See if we have nested batch files | ||
| 155 | JNZ GETBYTEDONE ;G Yes - don't exit just yet | ||
| 156 | MOV [SINGLECOM],-1 ; Cause termination | ||
| 157 | |||
| 158 | GetByteDone: | ||
| 159 | RestoreReg <DS,CX,BX> | ||
| 160 | |||
| 161 | return | ||
| 162 | |||
| 163 | EndProc GetBatByt | ||
| 164 | |||
| 165 | break <$If - conditional execution> | ||
| 166 | assume ds:trangroup,es:trangroup | ||
| 167 | |||
| 168 | IFERRORP: | ||
| 169 | POP AX | ||
| 170 | IFERROR: | ||
| 171 | FORERROR: | ||
| 172 | MOV DX,OFFSET TRANGROUP:SYNTMES_ptr | ||
| 173 | JMP CERROR | ||
| 174 | |||
| 175 | $IF: | ||
| 176 | ; | ||
| 177 | ; Turn off any pipes in progress. | ||
| 178 | ; | ||
| 179 | push ds ;AN004; save local DS | ||
| 180 | mov ds,[resseg] ;AN004; get resident segment | ||
| 181 | assume ds:resgroup ;AN004; | ||
| 182 | cmp [PIPEFILES],0 ;AN004; Only turn off if present. | ||
| 183 | jz IFNoPipe ;AN004; no pipe - continue | ||
| 184 | invoke PipeDel ;AN004; turn off piping | ||
| 185 | |||
| 186 | IFNoPipe: ;AN004; | ||
| 187 | pop ds ;AN004; get local DS back | ||
| 188 | assume ds:trangroup ;AN004; | ||
| 189 | MOV [IFNOTFLAG],0 | ||
| 190 | mov [if_not_count], 0 | ||
| 191 | MOV SI,81H | ||
| 192 | |||
| 193 | IFREENT: | ||
| 194 | invoke SCANOFF | ||
| 195 | CMP AL,0DH | ||
| 196 | JZ IFERROR | ||
| 197 | MOV BP,SI | ||
| 198 | MOV DI,OFFSET TRANGROUP:IFTAB ; Prepare to search if table | ||
| 199 | MOV CH,0 | ||
| 200 | |||
| 201 | IFINDCOM: | ||
| 202 | MOV SI,BP | ||
| 203 | MOV CL,[DI] | ||
| 204 | INC DI | ||
| 205 | JCXZ IFSTRING | ||
| 206 | JMP SHORT FIRSTCOMP | ||
| 207 | |||
| 208 | IFCOMP: | ||
| 209 | JNZ IF_DIF ;AC000; | ||
| 210 | |||
| 211 | FIRSTCOMP: | ||
| 212 | LODSB | ||
| 213 | MOV AH,ES:[DI] | ||
| 214 | INC DI | ||
| 215 | CMP AL,AH | ||
| 216 | JZ IFLP | ||
| 217 | OR AH,20H ; Try lower case | ||
| 218 | CMP AL,AH | ||
| 219 | |||
| 220 | IFLP: | ||
| 221 | LOOP IFCOMP | ||
| 222 | |||
| 223 | IF_DIF: ;AC000; | ||
| 224 | LAHF | ||
| 225 | ADD DI,CX ; Bump to next position without affecting flags | ||
| 226 | MOV BX,[DI] ; Get handler address | ||
| 227 | INC DI | ||
| 228 | INC DI | ||
| 229 | SAHF | ||
| 230 | JNZ IFINDCOM | ||
| 231 | LODSB | ||
| 232 | CMP AL,0DH | ||
| 233 | |||
| 234 | IFERRORJ: | ||
| 235 | JZ IFERROR | ||
| 236 | invoke DELIM | ||
| 237 | JNZ IFINDCOM | ||
| 238 | invoke SCANOFF | ||
| 239 | JMP BX | ||
| 240 | |||
| 241 | IFNOT: | ||
| 242 | NOT [IFNOTFLAG] | ||
| 243 | inc [if_not_count] | ||
| 244 | JMP IFREENT | ||
| 245 | |||
| 246 | ; | ||
| 247 | ; We are comparing two strings for equality. First, find the end of the | ||
| 248 | ; first string. | ||
| 249 | ; | ||
| 250 | |||
| 251 | IFSTRING: | ||
| 252 | PUSH SI ; save away pointer for later compare | ||
| 253 | XOR CX,CX ; count of chars in first string | ||
| 254 | |||
| 255 | FIRST_STRING: | ||
| 256 | LODSB ; get character | ||
| 257 | CMP AL,0DH ; end of line? | ||
| 258 | JZ IFERRORP ; yes => error | ||
| 259 | invoke DELIM ; is it a delimiter? | ||
| 260 | JZ EQUAL_CHECK ; yes, go find equal sign | ||
| 261 | INC CX ; remember 1 byte for the length | ||
| 262 | JMP FIRST_STRING ; go back for more | ||
| 263 | ; | ||
| 264 | ; We have found the end of the first string. Unfortunately, we CANNOT use | ||
| 265 | ; scanoff to find the next token; = is a valid separator and will be skipped | ||
| 266 | ; over. | ||
| 267 | ; | ||
| 268 | |||
| 269 | EQUAL_CHECK: | ||
| 270 | CMP AL,'=' ; is char we have an = sign? | ||
| 271 | JZ EQUAL_CHECK2 ; yes, go find second one. | ||
| 272 | CMP AL,0DH ; end of line? | ||
| 273 | JZ IFERRORPj ;AC004; yes, syntax error | ||
| 274 | LODSB ; get next char | ||
| 275 | JMP EQUAL_CHECK | ||
| 276 | ; | ||
| 277 | ; The first = has been found. The next char had better be an = too. | ||
| 278 | ; | ||
| 279 | |||
| 280 | EQUAL_CHECK2: | ||
| 281 | LODSB ; get potential = char | ||
| 282 | CMP AL,'=' ; is it good? | ||
| 283 | jnz iferrorpj ; no, error | ||
| 284 | ; | ||
| 285 | ; Find beginning of second string. | ||
| 286 | ; | ||
| 287 | invoke SCANOFF | ||
| 288 | CMP AL,0DH | ||
| 289 | jz iferrorpj | ||
| 290 | POP DI | ||
| 291 | ; | ||
| 292 | ; DS:SI points to second string | ||
| 293 | ; CX has number of chars in first string | ||
| 294 | ; ES:DI points to first string | ||
| 295 | ; | ||
| 296 | ; Perform compare to elicit match | ||
| 297 | ; | ||
| 298 | REPE CMPSB | ||
| 299 | JZ MATCH ; match found! | ||
| 300 | ; | ||
| 301 | ; No match. Let's find out what was wrong. The character that did not match | ||
| 302 | ; has been advanced over. Let's back up to it. | ||
| 303 | ; | ||
| 304 | DEC SI | ||
| 305 | ; | ||
| 306 | ; If it is EOL, then syntax error | ||
| 307 | ; | ||
| 308 | CMP BYTE PTR [SI],0DH | ||
| 309 | JZ IFERRORJ | ||
| 310 | ; | ||
| 311 | ; Advance pointer over remainder of unmatched text to next delimiter | ||
| 312 | ; | ||
| 313 | |||
| 314 | SKIPSTRINGEND: | ||
| 315 | LODSB | ||
| 316 | |||
| 317 | NOTMATCH: | ||
| 318 | CMP AL,0DH | ||
| 319 | |||
| 320 | IFERRORJ2: | ||
| 321 | JZ IFERRORJ | ||
| 322 | invoke DELIM | ||
| 323 | JNZ SKIPSTRINGEND | ||
| 324 | ; | ||
| 325 | ; Signal that we did NOT have a match | ||
| 326 | ; | ||
| 327 | MOV AL,-1 | ||
| 328 | JMP SHORT IFRET | ||
| 329 | |||
| 330 | iferrorpj: | ||
| 331 | jmp iferrorp | ||
| 332 | ; | ||
| 333 | ; The compare succeeded. Was the second string longer than the first? We | ||
| 334 | ; do this by seeing if the next char is a delimiter. | ||
| 335 | ; | ||
| 336 | |||
| 337 | MATCH: | ||
| 338 | LODSB | ||
| 339 | invoke DELIM | ||
| 340 | JNZ NOTMATCH ; not same. | ||
| 341 | XOR AL,AL | ||
| 342 | JMP SHORT IFRET | ||
| 343 | |||
| 344 | IFEXISTS: | ||
| 345 | ifexist_attr EQU attr_hidden+attr_system | ||
| 346 | |||
| 347 | moredelim: | ||
| 348 | lodsb ; move command line pointer over | ||
| 349 | invoke delim ; pathname -- have to do it ourselves | ||
| 350 | jnz moredelim ; 'cause parse_file_descriptor is dumb | ||
| 351 | mov DX, OFFSET TRANGROUP:dirbuf | ||
| 352 | trap set_dma | ||
| 353 | mov BX, 2 ; if(0) [|not](|1) exist[1|2] file(2|3) | ||
| 354 | add BX, [if_not_count] | ||
| 355 | mov AX, OFFSET TRANGROUP:arg.argv | ||
| 356 | invoke argv_calc ; convert arg index to pointer | ||
| 357 | mov DX, [BX].argpointer ; get pointer to supposed filename | ||
| 358 | mov CX, ifexist_attr ; filetypes to search for | ||
| 359 | trap Find_First ; request first match, if any | ||
| 360 | jc if_ex_c ; carry is how to determine error | ||
| 361 | xor AL, AL | ||
| 362 | jmp ifret | ||
| 363 | |||
| 364 | if_ex_c: | ||
| 365 | mov AL, -1 ; false 'n' fall through... | ||
| 366 | |||
| 367 | IFRET: | ||
| 368 | TEST [IFNOTFLAG],-1 | ||
| 369 | JZ REALTEST | ||
| 370 | NOT AL | ||
| 371 | |||
| 372 | REALTEST: | ||
| 373 | OR AL,AL | ||
| 374 | JZ IFTRUE | ||
| 375 | JMP TCOMMAND | ||
| 376 | |||
| 377 | IFTRUE: | ||
| 378 | invoke SCANOFF | ||
| 379 | MOV CX,SI | ||
| 380 | SUB CX,81H | ||
| 381 | SUB DS:[80H],CL | ||
| 382 | MOV CL,DS:[80H] | ||
| 383 | MOV [COMBUF+1],CL | ||
| 384 | MOV DI,OFFSET TRANGROUP:COMBUF+2 | ||
| 385 | CLD | ||
| 386 | REP MOVSB | ||
| 387 | MOV AL,0DH | ||
| 388 | STOSB | ||
| 389 | ; | ||
| 390 | ; Signal that an IF was done. This prevents the redirections from getting | ||
| 391 | ; lost. | ||
| 392 | ; | ||
| 393 | PUSH DS | ||
| 394 | MOV DS,ResSeg | ||
| 395 | ASSUME DS:RESGROUP | ||
| 396 | MOV IFFlag,-1 | ||
| 397 | POP DS | ||
| 398 | ASSUME DS:TRANGROUP | ||
| 399 | ; | ||
| 400 | ; Go do the command | ||
| 401 | ; | ||
| 402 | JMP DOCOM1 | ||
| 403 | |||
| 404 | iferrorj3: | ||
| 405 | jmp iferrorj2 | ||
| 406 | |||
| 407 | IFERLEV: | ||
| 408 | MOV BH,10 | ||
| 409 | XOR BL,BL | ||
| 410 | |||
| 411 | GETNUMLP: | ||
| 412 | LODSB | ||
| 413 | CMP AL,0DH | ||
| 414 | jz iferrorj3 | ||
| 415 | invoke DELIM | ||
| 416 | JZ GOTNUM | ||
| 417 | SUB AL,'0' | ||
| 418 | XCHG AL,BL | ||
| 419 | MUL BH | ||
| 420 | ADD AL,BL | ||
| 421 | XCHG AL,BL | ||
| 422 | JMP SHORT GETNUMLP | ||
| 423 | |||
| 424 | GOTNUM: | ||
| 425 | PUSH DS | ||
| 426 | MOV DS,[RESSEG] | ||
| 427 | ASSUME DS:RESGROUP | ||
| 428 | MOV AH,BYTE PTR [RETCODE] | ||
| 429 | POP DS | ||
| 430 | ASSUME DS:TRANGROUP | ||
| 431 | XOR AL,AL | ||
| 432 | CMP AH,BL | ||
| 433 | JAE IFRET | ||
| 434 | DEC AL | ||
| 435 | JMP SHORT IFRET | ||
| 436 | |||
| 437 | |||
| 438 | break <Shift - advance arguments> | ||
| 439 | assume ds:trangroup,es:trangroup | ||
| 440 | |||
| 441 | ; | ||
| 442 | ; Shift the parameters in the batch structure by 1 and set up the new argument. | ||
| 443 | ; This is a NOP if no batch in progress. | ||
| 444 | ; | ||
| 445 | |||
| 446 | Procedure Shift,NEAR | ||
| 447 | |||
| 448 | MOV DS,[RESSEG] | ||
| 449 | ASSUME DS:RESGROUP | ||
| 450 | MOV AX,[BATCH] ; get batch pointer | ||
| 451 | OR AX,AX ; in batch mode? | ||
| 452 | retz ; no, done. | ||
| 453 | MOV ES,AX ; operate in batch segment | ||
| 454 | MOV DS,AX | ||
| 455 | |||
| 456 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 457 | |||
| 458 | ; | ||
| 459 | ; Now move the batch args down by 1 word | ||
| 460 | ; | ||
| 461 | MOV DI,BatParm ; point to parm table | ||
| 462 | LEA SI,[DI+2] ; make source = dest + 2 | ||
| 463 | MOV CX,9 ; move 9 parameters | ||
| 464 | REP MOVSW ; SHIFT down | ||
| 465 | ; | ||
| 466 | ; If the last parameter (the one not moved) is empty (= -1) then we are done. | ||
| 467 | ; We have copied it into the previous position | ||
| 468 | ; | ||
| 469 | CMP WORD PTR [DI],-1 ; if last one was not in use then | ||
| 470 | retz ; No new parm | ||
| 471 | ; | ||
| 472 | ; This last pointer is NOT nul. Get it and scan to find the next argument. | ||
| 473 | ; Assume, first, that there is no next argument | ||
| 474 | ; | ||
| 475 | MOV SI,[DI] | ||
| 476 | MOV WORD PTR [DI],-1 ; Assume no parm | ||
| 477 | ; | ||
| 478 | ; The parameters are CR separated. Scan for end of this parm | ||
| 479 | ; | ||
| 480 | SKIPCRLP: | ||
| 481 | LODSB | ||
| 482 | CMP AL,0DH | ||
| 483 | JNZ SKIPCRLP | ||
| 484 | ; | ||
| 485 | ; We are now pointing at next arg. If it is 0 (end of original line) then we | ||
| 486 | ; are finished. There ARE no more parms and the pointer has been previously | ||
| 487 | ; initialized to indicate it. | ||
| 488 | ; | ||
| 489 | CMP BYTE PTR [SI],0 | ||
| 490 | retz ; End of parms | ||
| 491 | MOV [DI],SI ; Pointer to next parm as %9 | ||
| 492 | |||
| 493 | return | ||
| 494 | |||
| 495 | EndProc Shift | ||
| 496 | |||
| 497 | ; | ||
| 498 | ; Skip delim reads bytes from the batch file until a non-delimiter is seen. | ||
| 499 | ; returns char in AL, carry set -> eof | ||
| 500 | ; | ||
| 501 | |||
| 502 | Procedure SkipDelim,NEAR | ||
| 503 | |||
| 504 | ASSUME DS:ResGroup,ES:NOTHING | ||
| 505 | TEST Batch,-1 | ||
| 506 | JZ SkipErr ; batch file empty. OOPS! | ||
| 507 | CALL GetBatByt ; get a char | ||
| 508 | invoke Delim ; check for ignoreable chars | ||
| 509 | JZ SkipDelim ; ignore this char. | ||
| 510 | clc | ||
| 511 | return | ||
| 512 | |||
| 513 | SkipErr: | ||
| 514 | stc | ||
| 515 | return | ||
| 516 | |||
| 517 | EndProc SkipDelim | ||
| 518 | |||
| 519 | break $Call | ||
| 520 | |||
| 521 | ; CALL is an internal command that transfers control to a .bat, .exe, or | ||
| 522 | ; .com file. This routine strips the CALL off the command line, sets | ||
| 523 | ; the CALL_FLAG to indicate a call in progress, and returns control to | ||
| 524 | ; DOCOM1 in TCODE to reprocess the command line and execute the file | ||
| 525 | ; being CALLed. | ||
| 526 | |||
| 527 | $CALL: | ||
| 528 | |||
| 529 | ; strip off CALL from command line | ||
| 530 | |||
| 531 | ASSUME DS:trangroup,ES:trangroup | ||
| 532 | push si | ||
| 533 | push di | ||
| 534 | push ax | ||
| 535 | push cx | ||
| 536 | mov si,offset trangroup:combuf+2 | ||
| 537 | invoke scanoff ;get to first non-delimeter | ||
| 538 | add si,length_call ;point to char past CALL | ||
| 539 | mov di,offset trangroup:combuf+2 | ||
| 540 | mov cx,combuflen-length_call ;get length of buffer | ||
| 541 | rep movsb ;move it | ||
| 542 | pop cx | ||
| 543 | pop ax | ||
| 544 | pop di | ||
| 545 | pop si | ||
| 546 | |||
| 547 | |||
| 548 | ; set call flag to indicate call in progress | ||
| 549 | |||
| 550 | push ds | ||
| 551 | mov ds,[resseg] | ||
| 552 | ASSUME DS:resgroup,ES:resgroup | ||
| 553 | mov call_flag, call_in_progress | ||
| 554 | mov call_batch_flag, call_in_progress | ||
| 555 | ; | ||
| 556 | ; Turn off any pipes in progress. | ||
| 557 | ; | ||
| 558 | cmp [PIPEFILES],0 ; Only turn off if present. | ||
| 559 | jz NoPipe | ||
| 560 | invoke PipeDel | ||
| 561 | NoPipe: | ||
| 562 | pop ds | ||
| 563 | |||
| 564 | ret | ||
| 565 | |||
| 566 | break Goto | ||
| 567 | |||
| 568 | GOTO: | ||
| 569 | |||
| 570 | assume ds:trangroup,es:trangroup | ||
| 571 | MOV DS,[RESSEG] | ||
| 572 | ASSUME DS:RESGROUP | ||
| 573 | TEST [BATCH],-1 | ||
| 574 | retz ; If not in batch mode, a nop | ||
| 575 | XOR DX,DX | ||
| 576 | PUSH DS | ||
| 577 | MOV DS,Batch | ||
| 578 | MOV WORD PTR DS:[BatSeek],DX ; Back to start | ||
| 579 | MOV WORD PTR DS:[BatSeek+2],DX ; Back to start | ||
| 580 | POP DS | ||
| 581 | |||
| 582 | GotoOpen: | ||
| 583 | invoke promptBat | ||
| 584 | MOV DI,FCB+1 ; Get the label | ||
| 585 | MOV CX,11 | ||
| 586 | MOV AL,' ' | ||
| 587 | REPNE SCASB | ||
| 588 | JNZ NOINC | ||
| 589 | INC CX | ||
| 590 | |||
| 591 | NOINC: | ||
| 592 | SUB CX,11 | ||
| 593 | NEG CX | ||
| 594 | MOV [GOTOLEN],CX | ||
| 595 | ; | ||
| 596 | ; At beginning of file. Skip to first non-delimiter char | ||
| 597 | ; | ||
| 598 | CALL SkipDelim | ||
| 599 | JC BadGoto | ||
| 600 | CMP AL,':' | ||
| 601 | JZ CHKLABEL | ||
| 602 | |||
| 603 | LABLKLP: ; Look for the label | ||
| 604 | CALL GETBATBYT | ||
| 605 | CMP AL,0AH | ||
| 606 | JNZ LABLKTST | ||
| 607 | ; | ||
| 608 | ; At beginning of line. Skip to first non-delimiter char | ||
| 609 | ; | ||
| 610 | CALL SkipDelim | ||
| 611 | JC BadGoto | ||
| 612 | CMP AL,':' | ||
| 613 | JZ CHKLABEL | ||
| 614 | |||
| 615 | LABLKTST: | ||
| 616 | TEST [BATCH],-1 | ||
| 617 | JNZ LABLKLP | ||
| 618 | |||
| 619 | BadGoto: | ||
| 620 | CALL BATCLOSE | ||
| 621 | PUSH CS | ||
| 622 | POP DS | ||
| 623 | MOV DX,OFFSET TRANGROUP:BADLAB_ptr | ||
| 624 | JMP CERROR | ||
| 625 | |||
| 626 | ; | ||
| 627 | ; Found the :. Skip to first non-delimiter char | ||
| 628 | ; | ||
| 629 | |||
| 630 | CHKLABEL: | ||
| 631 | CALL SkipDelim | ||
| 632 | JC BadGoto | ||
| 633 | MOV DI,FCB+1 | ||
| 634 | MOV CX,[GOTOLEN] | ||
| 635 | JMP SHORT GotByte | ||
| 636 | |||
| 637 | NEXTCHRLP: | ||
| 638 | PUSH CX | ||
| 639 | CALL GETBATBYT | ||
| 640 | POP CX | ||
| 641 | |||
| 642 | GotByte: | ||
| 643 | INVOKE TESTKANJ ;AN000; 3/3/KK | ||
| 644 | JZ NOTKANJ1 ;AN000; 3/3/KK | ||
| 645 | CMP AL, ES:[DI] ;AN000; 3/3/KK | ||
| 646 | JNZ LABLKTST ;AN000; 3/3/KK | ||
| 647 | INC DI ;AN000; 3/3/KK | ||
| 648 | DEC CX ;AN000; 3/3/KK | ||
| 649 | JCXZ LABLKTST ;AN000; 3/3/KK | ||
| 650 | PUSH CX ;AN000; 3/3/KK | ||
| 651 | CALL GETBATBYT ;AN000; 3/3/KK | ||
| 652 | POP CX ;AN000; 3/3/KK | ||
| 653 | CMP AL, ES:[DI] ;AN000; 3/3/KK | ||
| 654 | JMP SHORT KNEXTLABCHR ;AN000; 3/3/KK | ||
| 655 | |||
| 656 | NOTKANJ1: ;AN000; 3/3/KK | ||
| 657 | OR AL,20H | ||
| 658 | CMP AL,ES:[DI] | ||
| 659 | JNZ TRYUPPER | ||
| 660 | JMP SHORT NEXTLABCHR | ||
| 661 | |||
| 662 | TRYUPPER: | ||
| 663 | SUB AL,20H | ||
| 664 | CMP AL,ES:[DI] | ||
| 665 | |||
| 666 | KNEXTLABCHR: ;AN000; 3/3/KK | ||
| 667 | JNZ LABLKTST | ||
| 668 | |||
| 669 | NEXTLABCHR: | ||
| 670 | INC DI | ||
| 671 | LOOP NEXTCHRLP | ||
| 672 | CALL GETBATBYT | ||
| 673 | cmp [GOTOLEN],8 ; Is the label atleast 8 chars long? | ||
| 674 | jge gotocont ; Yes, then the next char doesn't matter | ||
| 675 | CMP AL,' ' | ||
| 676 | JA LABLKTST | ||
| 677 | |||
| 678 | gotocont: | ||
| 679 | CMP AL,0DH | ||
| 680 | JZ SKIPLFEED | ||
| 681 | |||
| 682 | TONEXTBATLIN: | ||
| 683 | CALL GETBATBYT | ||
| 684 | CMP AL,0DH | ||
| 685 | JNZ TONEXTBATLIN | ||
| 686 | |||
| 687 | SKIPLFEED: | ||
| 688 | CALL GETBATBYT | ||
| 689 | CALL BatClose | ||
| 690 | |||
| 691 | return | ||
| 692 | |||
| 693 | Procedure BatClose,NEAR | ||
| 694 | |||
| 695 | MOV BX,CS:[BATHAND] | ||
| 696 | CMP BX,5 | ||
| 697 | JB CloseReturn | ||
| 698 | MOV AH,CLOSE | ||
| 699 | INT int_command | ||
| 700 | |||
| 701 | CloseReturn: | ||
| 702 | mov byte ptr [In_Batch],0 ; reset flag | ||
| 703 | return | ||
| 704 | |||
| 705 | EndProc BatClose | ||
| 706 | |||
| 707 | ; | ||
| 708 | ; Open the BATCH file, If open fails, AL is drive of batch file (A=1) | ||
| 709 | ; Also, fills internal batch buffer. If access denied, then AX = -1 | ||
| 710 | ; | ||
| 711 | |||
| 712 | Procedure BatOpen,NEAR | ||
| 713 | |||
| 714 | ASSUME DS:RESGROUP,ES:TRANGROUP | ||
| 715 | |||
| 716 | PUSH DS | ||
| 717 | MOV DS,[BATCH] | ||
| 718 | ASSUME DS:NOTHING | ||
| 719 | |||
| 720 | MOV DX,BatFile | ||
| 721 | MOV AX,OPEN SHL 8 | ||
| 722 | INT int_command ; Open the batch file | ||
| 723 | JC SETERRDL | ||
| 724 | MOV DX,WORD PTR DS:[BatSeek] | ||
| 725 | MOV CX,WORD PTR DS:[BatSeek+2] | ||
| 726 | POP DS | ||
| 727 | ASSUME DS:RESGROUP | ||
| 728 | |||
| 729 | MOV [BATHAND],AX | ||
| 730 | MOV BX,AX | ||
| 731 | MOV AX,LSEEK SHL 8 ; Go to the right spot | ||
| 732 | INT int_command | ||
| 733 | MOV BatBufPos,-1 ; nuke batch buffer position | ||
| 734 | |||
| 735 | return | ||
| 736 | |||
| 737 | SETERRDL: | ||
| 738 | MOV BX,DX | ||
| 739 | invoke get_ext_error_number ;AN022; get the extended error | ||
| 740 | mov dx,ax ;AN022; save extended error in DX | ||
| 741 | MOV AL,[BX] ; Get drive spec | ||
| 742 | SUB AL,'@' ; A = 1 | ||
| 743 | POP DS | ||
| 744 | STC ; SUB mucked over carry | ||
| 745 | |||
| 746 | return | ||
| 747 | |||
| 748 | EndProc BatOpen | ||
| 749 | |||
| 750 | |||
| 751 | TRANCODE ENDS | ||
| 752 | END | ||
| 753 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/COMMAND/TCMD1A.ASM b/v4.0/src/CMD/COMMAND/TCMD1A.ASM new file mode 100644 index 0000000..fd662b3 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/TCMD1A.ASM | |||
| @@ -0,0 +1,598 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)tcmd1a.asm 1.1 85/05/14 | ||
| 3 | ; SCCSID = @(#)tcmd1a.asm 1.1 85/05/14 | ||
| 4 | TITLE PART4 COMMAND Transient routines. | ||
| 5 | |||
| 6 | ; Internal commands DIR,PAUSE,ERASE,TYPE,VOL,VER | ||
| 7 | |||
| 8 | INCLUDE comsw.asm | ||
| 9 | .xlist | ||
| 10 | .xcref | ||
| 11 | INCLUDE DOSSYM.INC | ||
| 12 | INCLUDE comseg.asm | ||
| 13 | INCLUDE comequ.asm ;AC000; | ||
| 14 | include ioctl.inc ;AN000; | ||
| 15 | .list | ||
| 16 | .cref | ||
| 17 | |||
| 18 | DATARES SEGMENT PUBLIC BYTE ;AN020; | ||
| 19 | EXTRN append_flag:byte ;AN020; | ||
| 20 | EXTRN append_state:word ;AN020; | ||
| 21 | DATARES ENDS ;AN020; | ||
| 22 | |||
| 23 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 24 | EXTRN BadCD_ptr:word | ||
| 25 | EXTRN bits:word | ||
| 26 | EXTRN Bytmes_ptr:word | ||
| 27 | EXTRN comsw:word | ||
| 28 | EXTRN dir_w_syn:word ;AC000; | ||
| 29 | EXTRN dirdat_mo_day:word ;AC000; | ||
| 30 | EXTRN dirdat_yr:word ;AC000; | ||
| 31 | EXTRN dirdattim_ptr:word | ||
| 32 | EXTRN dirhead_ptr:word | ||
| 33 | EXTRN dirtim_hr_min:word ;AC000; | ||
| 34 | EXTRN Dirmes_ptr:word | ||
| 35 | EXTRN disp_file_size_ptr:word | ||
| 36 | EXTRN Dmes_ptr:word | ||
| 37 | EXTRN Extend_buf_ptr:word ;AN000; | ||
| 38 | EXTRN msg_disp_class:byte ;AN000; | ||
| 39 | EXTRN parse_dir:byte ;AC000; | ||
| 40 | EXTRN slash_p_syn:word ;AC000; | ||
| 41 | EXTRN string_buf_ptr:word | ||
| 42 | EXTRN tab_ptr:word ;AC000; | ||
| 43 | TRANDATA ENDS | ||
| 44 | |||
| 45 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 46 | EXTRN bytes_free:word | ||
| 47 | EXTRN charbuf:byte | ||
| 48 | EXTRN COM:byte | ||
| 49 | EXTRN Destisdir:byte | ||
| 50 | EXTRN Desttail:word | ||
| 51 | EXTRN dir_num:word | ||
| 52 | EXTRN Dirbuf:byte | ||
| 53 | EXTRN dirflag:byte ;AN015; | ||
| 54 | EXTRN display_ioctl:word ;AC000; | ||
| 55 | EXTRN display_mode:byte ;AC000; | ||
| 56 | EXTRN filecnt:word | ||
| 57 | EXTRN file_size_high:word | ||
| 58 | EXTRN file_size_low:word | ||
| 59 | EXTRN fullscr:word | ||
| 60 | EXTRN ID:byte | ||
| 61 | EXTRN lincnt:byte ;AC000; | ||
| 62 | EXTRN linlen:byte | ||
| 63 | EXTRN linperpag:word ;AC000; | ||
| 64 | EXTRN msg_numb:word ;AN022; | ||
| 65 | EXTRN parse1_addr:dword ;AC000; | ||
| 66 | EXTRN parse1_syn:word ;AC000; | ||
| 67 | EXTRN parse1_type:byte ;AC000; | ||
| 68 | EXTRN pathcnt:word ;AN000; | ||
| 69 | EXTRN pathpos:word ;AN000; | ||
| 70 | EXTRN resseg:word ;AN020; | ||
| 71 | EXTRN srcbuf:byte ;AC000; | ||
| 72 | EXTRN string_ptr_2:word | ||
| 73 | TRANSPACE ENDS | ||
| 74 | |||
| 75 | TRANCODE SEGMENT PUBLIC BYTE | ||
| 76 | |||
| 77 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 78 | |||
| 79 | ;--------------- | ||
| 80 | |||
| 81 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 82 | EXTRN arg:byte ; the arg structure! | ||
| 83 | TRANSPACE ENDS | ||
| 84 | ;--------------- | ||
| 85 | |||
| 86 | EXTRN cerror:near | ||
| 87 | EXTRN std_printf:near | ||
| 88 | |||
| 89 | |||
| 90 | PUBLIC catalog | ||
| 91 | |||
| 92 | |||
| 93 | break Catalog - Directory command | ||
| 94 | assume ds:trangroup,es:trangroup | ||
| 95 | |||
| 96 | ; | ||
| 97 | ; The DIR command displays the contents of a directory. | ||
| 98 | ; | ||
| 99 | ; **************************************************************** | ||
| 100 | ; * | ||
| 101 | ; * ROUTINE: CATALOG - display file(s) in directory | ||
| 102 | ; * | ||
| 103 | ; * FUNCTION: PARSE command line for drive, file, or path name. | ||
| 104 | ; * DIR allows two switches, /P (pause) and /W (wide). | ||
| 105 | ; * If an error occurs issue and error message and | ||
| 106 | ; * transfer control to CERROR. | ||
| 107 | ; * | ||
| 108 | ; * INPUT: command line at offset 81H | ||
| 109 | ; * | ||
| 110 | ; * OUTPUT: none | ||
| 111 | ; * | ||
| 112 | ; **************************************************************** | ||
| 113 | |||
| 114 | CATALOG: | ||
| 115 | |||
| 116 | ; | ||
| 117 | ; Set up DTA for dir search firsts | ||
| 118 | ; | ||
| 119 | mov dx,offset trangroup:Dirbuf ;AC000; Set Disk transfer address | ||
| 120 | mov ah,Set_DMA ;AC000; | ||
| 121 | int int_command ;AC000; | ||
| 122 | ; | ||
| 123 | ; Set up defaults for switches and parse the command line. | ||
| 124 | ; | ||
| 125 | mov msg_numb,0 ;AN022; initialize message flag | ||
| 126 | mov di,offset trangroup:srcbuf ;AN000; get address of srcbuf | ||
| 127 | mov [pathpos],di ;AN000; this is start of path | ||
| 128 | mov [pathcnt],1 ;AN000; initialize length to 1 char | ||
| 129 | mov al,star ;AN000; initialize srcbuf to *,0d | ||
| 130 | stosb ;AN000; | ||
| 131 | mov al,end_of_line_in ;AN000; | ||
| 132 | stosb ;AN000; | ||
| 133 | mov si,81H ;AN000; Get command line | ||
| 134 | mov di,offset trangroup:parse_dir ;AN000; Get adderss of PARSE_DIR | ||
| 135 | xor cx,cx ;AC000; clear counter for positionals | ||
| 136 | mov ComSw,cx ;AC000; initialize flags | ||
| 137 | mov bits,cx ;AC000; initialize switches | ||
| 138 | mov linperpag,linesperpage ;AC000; Set default for lines per page | ||
| 139 | mov linlen,normperlin ;AC000; Set number of entries per line | ||
| 140 | mov lincnt,normperlin ;AC000; | ||
| 141 | |||
| 142 | dirscan: | ||
| 143 | xor dx,dx ;AN000; | ||
| 144 | invoke parse_with_msg ;AC018; call parser | ||
| 145 | cmp ax,end_of_line ;AN000; are we at end of line? | ||
| 146 | jne dirscan_cont ;AN000; No - continue parsing | ||
| 147 | jmp scandone ;AN000; yes - go process | ||
| 148 | |||
| 149 | dirscan_cont: | ||
| 150 | cmp ax,result_no_error ;AN000; did we have an error? | ||
| 151 | jz dirscan_cont2 ;AN000; No - continue parsing | ||
| 152 | jmp badparm ;AN000; yes - exit | ||
| 153 | |||
| 154 | dirscan_cont2: | ||
| 155 | cmp parse1_syn,offset trangroup:dir_w_syn ;AN000; was /W entered? | ||
| 156 | je set_dir_width ;AN000; yes - go set wide lines | ||
| 157 | cmp parse1_syn,offset trangroup:slash_p_syn ;AN000; was /P entered? | ||
| 158 | je set_dir_pause ;AN000; yes - go set pause at end of screen | ||
| 159 | ; | ||
| 160 | ; Must be filespec since no other matches occurred. move filename to srcbuf | ||
| 161 | ; | ||
| 162 | push si ;AC000; save position in line | ||
| 163 | lds si,parse1_addr ;AC000; get address of filespec | ||
| 164 | push si ;AN000; save address | ||
| 165 | invoke move_to_srcbuf ;AC000; move to srcbuf | ||
| 166 | pop dx ;AC000; get address in DX | ||
| 167 | |||
| 168 | ; | ||
| 169 | ; The user may have specified a device. Search for the path and see if the | ||
| 170 | ; attributes indicate a device. | ||
| 171 | ; | ||
| 172 | mov ah,Find_First ;AC000; find the file | ||
| 173 | int int_command ;AC000; | ||
| 174 | jnc Dir_check_device ;AN022; if no error - check device | ||
| 175 | invoke get_ext_error_number ;AN022; get the extended error | ||
| 176 | cmp ax,error_no_more_files ;AN022; was error no file found | ||
| 177 | jz Dir_fspec_end ;AC022; yes -> obviously not a device | ||
| 178 | cmp ax,error_path_not_found ;AN022; was error no file found | ||
| 179 | jz Dir_fspec_end ;AC022; yes -> obviously not a device | ||
| 180 | jmp dir_err_setup ;AN022; otherwise - go issue error message | ||
| 181 | |||
| 182 | dir_check_device: ;AN022; | ||
| 183 | test byte ptr (DirBuf+find_buf_attr),attr_device ;AC000; | ||
| 184 | jz Dir_fspec_end ;AC000; no, go do normal operation | ||
| 185 | mov ComSw,-2 ;AC000; signal device | ||
| 186 | |||
| 187 | dir_fspec_end: | ||
| 188 | pop si ;AC000; restore position in line | ||
| 189 | jmp short dirscan ;AC000; keep parsing | ||
| 190 | |||
| 191 | set_dir_width: | ||
| 192 | test byte ptr[bits],SwitchW ;AN018; /W already set? | ||
| 193 | jz ok_set_width ;AN018; no - okay to set width | ||
| 194 | mov ax,moreargs_ptr ;AN018; set up too many arguments | ||
| 195 | invoke setup_parse_error_msg ;AN018; set up an error message | ||
| 196 | jmp badparm ;AN018; exit | ||
| 197 | |||
| 198 | ok_set_width: | ||
| 199 | or bits,switchw ;AC000; indicate /w was selected | ||
| 200 | mov linlen,wideperlin ;AC000; Set number of entries per line | ||
| 201 | mov lincnt,wideperlin ;AC000; | ||
| 202 | jmp short dirscan ;AC000; keep parsing | ||
| 203 | |||
| 204 | set_dir_pause: | ||
| 205 | test byte ptr[bits],SwitchP ;AN018; /p already set? | ||
| 206 | jz ok_set_pause ;AN018; no - okay to set width | ||
| 207 | mov ax,moreargs_ptr ;AN018; set up too many arguments | ||
| 208 | invoke setup_parse_error_msg ;AN018; set up an error message | ||
| 209 | jmp badparm ;AN018; exit | ||
| 210 | |||
| 211 | ok_set_pause: | ||
| 212 | or bits,switchp ;AC000; indicate /p was selected | ||
| 213 | push cx ;AN000; save necessary registers | ||
| 214 | push si ;AN000; | ||
| 215 | mov ax,(IOCTL SHL 8) + generic_ioctl_handle ;AN000; get lines per page on display | ||
| 216 | mov bx,stdout ;AN000; lines for stdout | ||
| 217 | mov ch,ioc_sc ;AN000; type is display | ||
| 218 | mov cl,get_generic ;AN000; get information | ||
| 219 | mov dx,offset trangroup:display_ioctl ;AN000; | ||
| 220 | int int_command ;AN000; | ||
| 221 | |||
| 222 | lines_set: | ||
| 223 | dec linperpag ;AN000; lines per actual page should | ||
| 224 | dec linperpag ;AN000; two less than the max | ||
| 225 | mov ax,linperpag ;AN000; get number of lines into | ||
| 226 | mov [fullscr],ax ;AC000; screen line counter | ||
| 227 | pop si ;AN000; restore registers | ||
| 228 | pop cx ;AN000; | ||
| 229 | jmp dirscan ;AC000; keep parsing | ||
| 230 | |||
| 231 | ; | ||
| 232 | ; The syntax is incorrect. Report only message we can. | ||
| 233 | ; | ||
| 234 | BadParm: | ||
| 235 | jmp cerror ;AC000; invalid switches get displayed | ||
| 236 | |||
| 237 | ScanDone: | ||
| 238 | |||
| 239 | ; | ||
| 240 | ; Find and display the volume ID on the drive. | ||
| 241 | ; | ||
| 242 | |||
| 243 | invoke okvolarg ;AC000; | ||
| 244 | mov [filecnt],0 ;AC000; Keep track of how many files found | ||
| 245 | cmp comsw,0 ;AC000; did an error occur? | ||
| 246 | jnz doheader ;AC000; yes - don't bother to fix path | ||
| 247 | |||
| 248 | mov dirflag,-1 ;AN015; set pathcrunch called from DIR | ||
| 249 | invoke pathcrunch ;AC000; set up FCB for dir | ||
| 250 | mov dirflag,0 ;AN015; reset dirflag | ||
| 251 | jc DirCheckPath ;AC015; no CHDIRs worked. | ||
| 252 | jz doheader ;AC015; chdirs worked - path\*.* | ||
| 253 | mov si,[desttail] ;AN015; get filename back | ||
| 254 | jmp short DoRealParse ;AN015; go parse it | ||
| 255 | |||
| 256 | DirCheckPath: | ||
| 257 | mov ax,[msg_numb] ;AN022; get message number | ||
| 258 | cmp ax,0 ;AN022; Is there a message? | ||
| 259 | jnz dir_err_setup ;AN022; yes - there's an error | ||
| 260 | cmp [destisdir],0 ;AC000; Were pathchars found? | ||
| 261 | jz doparse ;AC000; no - no problem | ||
| 262 | inc comsw ;AC000; indicate error | ||
| 263 | jmp short doheader ;AC000; go print header | ||
| 264 | |||
| 265 | DirNF: | ||
| 266 | mov ax,error_file_not_found ;AN022; get message number in control block | ||
| 267 | |||
| 268 | dir_err_setup: | ||
| 269 | mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class | ||
| 270 | mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer | ||
| 271 | mov extend_buf_ptr,ax ;AN022; | ||
| 272 | |||
| 273 | DirError: | ||
| 274 | jmp Cerror | ||
| 275 | |||
| 276 | ; | ||
| 277 | ; We have changed to something. We also have a file. Parse it into a | ||
| 278 | ; reasonable form, leaving drive alone, leaving extention alone and leaving | ||
| 279 | ; filename alone. We need to special case ... If we are at the root, the | ||
| 280 | ; parse will fail and it will give us a file not found instead of file not | ||
| 281 | ; found. | ||
| 282 | ; | ||
| 283 | DoParse: | ||
| 284 | mov si,offset trangroup:srcbuf ;AN000; Get address of source | ||
| 285 | cmp byte ptr [si+1],colon_char ;AN000; Is there a drive? | ||
| 286 | jnz dir_no_drive ;AN000; no - keep going | ||
| 287 | lodsw ;AN000; bypass drive | ||
| 288 | |||
| 289 | dir_no_drive: | ||
| 290 | cmp [si],".." | ||
| 291 | jnz DoRealParse | ||
| 292 | cmp byte ptr [si+2],0 | ||
| 293 | jnz DoRealParse | ||
| 294 | inc ComSw | ||
| 295 | jmp short DoHeader | ||
| 296 | |||
| 297 | DoRealParse: | ||
| 298 | mov di,FCB ; where to put the file name | ||
| 299 | mov ax,(Parse_File_Descriptor SHL 8) OR 0EH | ||
| 300 | int int_command | ||
| 301 | |||
| 302 | ; | ||
| 303 | ; Check to see if APPEND installed. If it is installed, set all flags | ||
| 304 | ; off. This will be reset in the HEADFIX routine | ||
| 305 | ; | ||
| 306 | |||
| 307 | DoHeader: | ||
| 308 | mov ax,AppendInstall ;AN020; see if append installed | ||
| 309 | int 2fh ;AN020; | ||
| 310 | cmp al,0 ;AN020; append installed? | ||
| 311 | je DoHeaderCont ;AN020; no - continue | ||
| 312 | mov ax,AppendDOS ;AN020; see if append DOS version right | ||
| 313 | int 2fh ;AN020; | ||
| 314 | cmp ax,-1 ;AN020; append version correct? | ||
| 315 | jne DoHeaderCont ;AN020; no - continue | ||
| 316 | mov ax,AppendGetState ;AN020; Get the state of Append | ||
| 317 | int 2fh ;AN020; | ||
| 318 | push ds ;AN020; save current data segment | ||
| 319 | mov ds,[resseg] ;AN020; get resident segment | ||
| 320 | assume ds:resgroup ;AN020; | ||
| 321 | mov append_state,bx ;AN020; save append state | ||
| 322 | mov append_flag,-1 ;AN020; set append flag | ||
| 323 | xor bx,bx ;AN020; clear out state | ||
| 324 | mov ax,AppendSetState ;AN020; Set the state of Append | ||
| 325 | int 2fh ;AN020; set everything off | ||
| 326 | pop ds ;AN020; save current data segment | ||
| 327 | assume ds:trangroup ;AN020; | ||
| 328 | |||
| 329 | ; | ||
| 330 | ; Display the header | ||
| 331 | ; | ||
| 332 | |||
| 333 | DoHeaderCont: | ||
| 334 | mov al,blank ;AN051; Print out a blank | ||
| 335 | invoke print_char ;AN051; before DIR header | ||
| 336 | invoke build_dir_string ; get current dir string | ||
| 337 | mov dx,offset trangroup:Dirhead_ptr | ||
| 338 | invoke printf_crlf ; bang! | ||
| 339 | |||
| 340 | ; | ||
| 341 | ; If there were chars left after parse or device, then invalid file name | ||
| 342 | ; | ||
| 343 | cmp ComSw,0 | ||
| 344 | jz DoSearch ; nothing left; good parse | ||
| 345 | jl DirNFFix ; not .. => error file not found | ||
| 346 | invoke RestUDir | ||
| 347 | mov dx,offset TranGroup:BadCD_ptr | ||
| 348 | jmp Cerror ; was .. => error directory not found | ||
| 349 | DirNFFix: | ||
| 350 | invoke RestUDir | ||
| 351 | jmp DirNF | ||
| 352 | ; | ||
| 353 | ; We are assured that everything is correct. Let's go and search. Use | ||
| 354 | ; attributes that will include finding directories. perform the first search | ||
| 355 | ; and reset our directory afterward. | ||
| 356 | ; | ||
| 357 | DoSearch: | ||
| 358 | mov byte ptr DS:[FCB-7],0FFH | ||
| 359 | mov byte ptr DS:[FCB-1],010H | ||
| 360 | ; | ||
| 361 | ; Caution! Since we are using an extended FCB, we will *also* be returning | ||
| 362 | ; the directory information as an extended FCB. We must bias all fetches into | ||
| 363 | ; DIRBUF by 8 (Extended FCB part + drive) | ||
| 364 | ; | ||
| 365 | mov ah,Dir_Search_First | ||
| 366 | mov dx,FCB-7 | ||
| 367 | int int_command | ||
| 368 | |||
| 369 | push ax ;AN022; save return state | ||
| 370 | inc al ;AN022; did an error occur? | ||
| 371 | pop ax ;AN022; get return state back | ||
| 372 | jnz found_first_file ;AN022; no error - start dir | ||
| 373 | invoke set_ext_error_msg ;AN022; yes - set up error message | ||
| 374 | push dx ;AN022; save message | ||
| 375 | invoke restudir ;AN022; restore user's dir | ||
| 376 | pop dx ;AN022; restore message | ||
| 377 | cmp word ptr Extend_Buf_Ptr,Error_No_More_Files ;AN022; convert no more files to | ||
| 378 | jnz DirCerrorJ ;AN022; file not found | ||
| 379 | mov Extend_Buf_Ptr,Error_File_Not_Found ;AN022; | ||
| 380 | |||
| 381 | DirCerrorJ: ;AN022; | ||
| 382 | jmp Cerror ;AN022; exit | ||
| 383 | |||
| 384 | ; | ||
| 385 | ; Restore the user's directory. We preserve, though, the return from the | ||
| 386 | ; previous system call for later checking. | ||
| 387 | ; | ||
| 388 | |||
| 389 | found_first_file: | ||
| 390 | push ax | ||
| 391 | invoke restudir | ||
| 392 | pop ax | ||
| 393 | ; | ||
| 394 | ; Main scanning loop. Entry has AL = Search first/next error code. Test for | ||
| 395 | ; no more. | ||
| 396 | ; | ||
| 397 | DIRSTART: | ||
| 398 | inc al ; FF = file not found | ||
| 399 | jnz Display | ||
| 400 | jmp DirDone ; Either an error or we are finished | ||
| 401 | ; | ||
| 402 | ; Note that we've seen a file and display the found file. | ||
| 403 | ; | ||
| 404 | |||
| 405 | Display: | ||
| 406 | inc [filecnt] ; Keep track of how many we find | ||
| 407 | mov si,offset trangroup:dirbuf+8 ; SI -> information returned by sys call | ||
| 408 | call shoname | ||
| 409 | ; | ||
| 410 | ; If we are displaying in wide mode, do not output the file info | ||
| 411 | ; | ||
| 412 | test byte ptr[bits],SwitchW ; W switch set? | ||
| 413 | jz DirTest | ||
| 414 | jmp nexent ; If so, no size, date, or time | ||
| 415 | |||
| 416 | ; | ||
| 417 | ; Test for directory. | ||
| 418 | ; | ||
| 419 | DirTest: | ||
| 420 | test [dirbuf+8].dir_attr,attr_directory | ||
| 421 | jz fileent | ||
| 422 | ; | ||
| 423 | ; We have a directory. Display the <DIR> field in place of the file size | ||
| 424 | ; | ||
| 425 | mov dx,offset trangroup:Dmes_ptr | ||
| 426 | call std_printf | ||
| 427 | jmp short nofsiz | ||
| 428 | ; | ||
| 429 | ; We have a file. Display the file size | ||
| 430 | ; | ||
| 431 | fileent: | ||
| 432 | mov dx,[DirBuf+8].dir_size_l | ||
| 433 | mov file_size_low,dx | ||
| 434 | mov dx,[DirBuf+8].dir_size_h | ||
| 435 | mov file_size_high,dx | ||
| 436 | mov dx,offset trangroup:disp_file_size_ptr | ||
| 437 | call std_printf | ||
| 438 | ; | ||
| 439 | ; Display time and date of last modification | ||
| 440 | ; | ||
| 441 | nofsiz: | ||
| 442 | mov ax,[DirBuf+8].dir_date ; Get date | ||
| 443 | ; | ||
| 444 | ; If the date is 0, then we have found a 1.x level diskette. We skip the | ||
| 445 | ; date/time fields as 1.x did not have them. | ||
| 446 | ; | ||
| 447 | or ax,ax | ||
| 448 | jz nexent ; Skip if no date | ||
| 449 | mov bx,ax | ||
| 450 | and ax,1FH ; get day | ||
| 451 | mov dl,al | ||
| 452 | mov ax,bx | ||
| 453 | mov cl,5 | ||
| 454 | shr ax,cl ; Align month | ||
| 455 | and al,0FH ; Get month | ||
| 456 | mov dh,al | ||
| 457 | mov cl,bh | ||
| 458 | shr cl,1 ; Align year | ||
| 459 | xor ch,ch | ||
| 460 | add cx,80 ; Relative 1980 | ||
| 461 | cmp cl,100 | ||
| 462 | jb millenium | ||
| 463 | sub cl,100 | ||
| 464 | |||
| 465 | millenium: | ||
| 466 | xchg dh,dl ;AN000; switch month & day | ||
| 467 | mov DirDat_yr,cx ;AC000; put year into message control block | ||
| 468 | mov DirDat_mo_day,dx ;AC000; put month and day into message control block | ||
| 469 | mov cx,[DirBuf+8].dir_time ; Get time | ||
| 470 | jcxz prbuf ; Time field present? | ||
| 471 | shr cx,1 | ||
| 472 | shr cx,1 | ||
| 473 | shr cx,1 | ||
| 474 | shr cl,1 | ||
| 475 | shr cl,1 ; Hours in CH, minutes in CL | ||
| 476 | xchg ch,cl ;AN000; switch hours & minutes | ||
| 477 | mov DirTim_hr_min,cx ;AC000; put hours and minutes into message subst block | ||
| 478 | |||
| 479 | prbuf: | ||
| 480 | mov dx,offset trangroup:DirDatTim_ptr | ||
| 481 | call std_printf | ||
| 482 | invoke crlf2 ;AC066;end the line | ||
| 483 | dec byte ptr [fullscr] ;AC066;count the line | ||
| 484 | jnz endif04 ;AN066;IF the last on the screen THEN | ||
| 485 | call check_for_P ;AN066; pause if /P requested | ||
| 486 | endif04: ;AN066; | ||
| 487 | jmp scroll ; If not, just continue | ||
| 488 | ;AD061; mov DirDat_yr,0 ;AC000; reset year, month and day | ||
| 489 | ;AD061; mov DirDat_mo_day,0 ;AC000; in control block | ||
| 490 | ;AD061; mov DirTim_hr_min,0 ;AC000; reset hour & minute in control block | ||
| 491 | ; | ||
| 492 | ; We are done displaying an entry. The code between "noexent:" and "scroll:" | ||
| 493 | ; is only for /W case. | ||
| 494 | ; | ||
| 495 | nexent: | ||
| 496 | mov bl,[lincnt] ;AN066;save for check for first entry on line | ||
| 497 | dec [lincnt] ;count this entry on the line | ||
| 498 | jnz else01 ;AX066;IF last entry on line THEN | ||
| 499 | mov al,[linlen] | ||
| 500 | mov [lincnt],al | ||
| 501 | invoke crlf2 | ||
| 502 | cmp [fullscr],0 ;AC066;IF have filled the screen THEN | ||
| 503 | jnz endif02 ;AN066; | ||
| 504 | call check_for_P ;AN066; reinitialize fullscr, | ||
| 505 | endif02: ;AN066; IF P requested THEN pause | ||
| 506 | jmp short endif01 ;AN066; | ||
| 507 | else01: ;AN066;ELSE since screen not full | ||
| 508 | cmp bl,[linlen] ;AN066; IF starting new line THEN | ||
| 509 | jne endif03 ; count the line | ||
| 510 | dec byte ptr [fullscr] ;AN066; ENDIF | ||
| 511 | endif03: ;AC066;We are outputting on the same line, between fields, we tab. | ||
| 512 | mov dx,offset trangroup:tab_ptr ;Output a tab | ||
| 513 | call std_printf | ||
| 514 | endif01: ;AX066; | ||
| 515 | ; | ||
| 516 | ; All we need to do now is to get the next directory entry. | ||
| 517 | ; | ||
| 518 | scroll: | ||
| 519 | mov ah,Dir_Search_Next | ||
| 520 | mov dx,FCB-7 ; DX -> Unopened FCB | ||
| 521 | int int_command ; Search for a file to match FCB | ||
| 522 | jmp DirStart | ||
| 523 | ; | ||
| 524 | ; If no files have been found, display a not-found message | ||
| 525 | ; | ||
| 526 | DirDone: | ||
| 527 | invoke get_ext_error_number ;AN022; get the extended error number | ||
| 528 | cmp ax,error_no_more_files ;AN022; was error file not found? | ||
| 529 | jnz dir_err_setup_jmp ;AN022; no - setup error message | ||
| 530 | test [filecnt],-1 | ||
| 531 | jnz Trailer | ||
| 532 | mov ax,error_file_not_found ;AN022; | ||
| 533 | |||
| 534 | dir_err_setup_jmp: ;AN022; | ||
| 535 | jmp dir_err_setup ;AN022; go setup error msg & print it | ||
| 536 | ; | ||
| 537 | ; If we have printed the maximum number of files per line, terminate it with | ||
| 538 | ; CRLF. | ||
| 539 | ; | ||
| 540 | Trailer: | ||
| 541 | mov al,[linlen] | ||
| 542 | cmp al,[lincnt] ; Will be equal if just had CR/LF | ||
| 543 | jz mmessage | ||
| 544 | invoke crlf2 | ||
| 545 | cmp [fullscr],0 ;AN066;IF on last line of screen THEN | ||
| 546 | jnz endif06 ;AN066; pause before going on | ||
| 547 | call check_for_P ;AN066; to number and freespace | ||
| 548 | endif06: ;AN066; displays | ||
| 549 | |||
| 550 | mmessage: | ||
| 551 | mov dx,offset trangroup:Dirmes_ptr | ||
| 552 | mov si,[filecnt] | ||
| 553 | mov dir_num,si | ||
| 554 | call std_printf | ||
| 555 | mov ah,Get_Drive_Freespace | ||
| 556 | mov dl,byte ptr DS:[FCB] | ||
| 557 | int int_command | ||
| 558 | cmp ax,-1 | ||
| 559 | retz | ||
| 560 | mul cx ; AX is bytes per cluster | ||
| 561 | mul bx | ||
| 562 | mov bytes_free,ax ;AC000; | ||
| 563 | mov bytes_free+2,dx ;AC000; | ||
| 564 | MOV DX,OFFSET TRANGROUP:BYTMES_ptr | ||
| 565 | jmp std_printf | ||
| 566 | |||
| 567 | shoname: | ||
| 568 | mov di,offset trangroup:charbuf | ||
| 569 | mov cx,8 | ||
| 570 | rep movsb | ||
| 571 | mov al,' ' | ||
| 572 | stosb | ||
| 573 | mov cx,3 | ||
| 574 | rep movsb | ||
| 575 | xor ax,ax | ||
| 576 | stosb | ||
| 577 | push dx | ||
| 578 | mov dx,offset trangroup:charbuf | ||
| 579 | mov string_ptr_2,dx | ||
| 580 | mov dx,offset trangroup:string_buf_ptr | ||
| 581 | call std_printf | ||
| 582 | pop DX | ||
| 583 | return | ||
| 584 | |||
| 585 | check_for_P PROC NEAR ;AN066; | ||
| 586 | |||
| 587 | test byte ptr[bits],SwitchP ;P switch present? | ||
| 588 | jz endif05 ;AN066; | ||
| 589 | mov ax,linperpag ;AN000; transfer lines per page | ||
| 590 | mov [fullscr],ax ;AC000; to fullscr | ||
| 591 | invoke Pause | ||
| 592 | endif05: | ||
| 593 | ret ;AN066; | ||
| 594 | |||
| 595 | check_for_P ENDP ;AN066; | ||
| 596 | |||
| 597 | trancode ends | ||
| 598 | end | ||
diff --git a/v4.0/src/CMD/COMMAND/TCMD1B.ASM b/v4.0/src/CMD/COMMAND/TCMD1B.ASM new file mode 100644 index 0000000..7a45e9d --- /dev/null +++ b/v4.0/src/CMD/COMMAND/TCMD1B.ASM | |||
| @@ -0,0 +1,730 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)tcmd1b.asm 1.1 85/05/14 | ||
| 3 | ; SCCSID = @(#)tcmd1b.asm 1.1 85/05/14 | ||
| 4 | TITLE PART4 COMMAND Transient routines. | ||
| 5 | |||
| 6 | ; Internal commands DIR,PAUSE,ERASE,TYPE,VOL,VER | ||
| 7 | |||
| 8 | .xlist | ||
| 9 | .xcref | ||
| 10 | INCLUDE DOSSYM.INC | ||
| 11 | INCLUDE comseg.asm | ||
| 12 | INCLUDE comsw.asm ;AC000; | ||
| 13 | INCLUDE comequ.asm | ||
| 14 | INCLUDE ioctl.inc ;AN000; | ||
| 15 | INCLUDE ea.inc ;AN030; | ||
| 16 | .list | ||
| 17 | .cref | ||
| 18 | |||
| 19 | |||
| 20 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 21 | EXTRN badcpmes_ptr:word ;AC022; | ||
| 22 | EXTRN Extend_buf_ptr:word ;AC000; | ||
| 23 | EXTRN Extend_buf_sub:byte ;AN000; | ||
| 24 | EXTRN inornot_ptr:word | ||
| 25 | EXTRN msg_disp_class:byte ;AC000; | ||
| 26 | EXTRN parse_erase:byte ;AC000; | ||
| 27 | EXTRN parse_mrdir:byte ;AC000; | ||
| 28 | EXTRN parse_rename:byte ;AC000; | ||
| 29 | EXTRN parse_vol:byte ;AC000; | ||
| 30 | EXTRN PauseMes_ptr:word | ||
| 31 | EXTRN renerr_ptr:word | ||
| 32 | EXTRN slash_p_syn:word ;AC000; | ||
| 33 | EXTRN volmes_ptr:word ;AC000; | ||
| 34 | EXTRN volmes_ptr_2:word ;AC000; | ||
| 35 | EXTRN volsermes_ptr:word ;AC000; | ||
| 36 | EXTRN xa_cp:byte ;AN030; | ||
| 37 | TRANDATA ENDS | ||
| 38 | |||
| 39 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 40 | EXTRN bytcnt:word | ||
| 41 | EXTRN charbuf:byte | ||
| 42 | EXTRN comsw:word | ||
| 43 | EXTRN cpyflag:byte ;AC000; | ||
| 44 | EXTRN curdrv:byte | ||
| 45 | EXTRN destinfo:byte | ||
| 46 | EXTRN destisdir:byte | ||
| 47 | EXTRN dirbuf:byte | ||
| 48 | EXTRN msg_numb:word ;AN022; | ||
| 49 | EXTRN one_char_val:byte | ||
| 50 | EXTRN parse1_addr:dword ;AN000; | ||
| 51 | EXTRN parse1_syn:word ;AN000; | ||
| 52 | EXTRN srcbuf:byte ;AN000; | ||
| 53 | EXTRN string_ptr_2:word ;AN000; | ||
| 54 | EXTRN TPA:word | ||
| 55 | EXTRN vol_drv:byte | ||
| 56 | EXTRN vol_ioctl_buf:byte ;AC000; | ||
| 57 | EXTRN vol_label:byte ;AC000; | ||
| 58 | EXTRN vol_serial:dword ;AC000; | ||
| 59 | EXTRN xa_cp_out:byte ;AN030; | ||
| 60 | EXTRN xa_cp_length:word ;AN030; | ||
| 61 | EXTRN xa_list_attr:word ;AC030; | ||
| 62 | EXTRN zflag:byte | ||
| 63 | TRANSPACE ENDS | ||
| 64 | |||
| 65 | TRANCODE SEGMENT PUBLIC BYTE | ||
| 66 | |||
| 67 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 68 | |||
| 69 | ;--------------- | ||
| 70 | |||
| 71 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 72 | EXTRN arg:byte ; the arg structure! | ||
| 73 | transpace ends | ||
| 74 | ;--------------- | ||
| 75 | |||
| 76 | EXTRN cerror:near | ||
| 77 | EXTRN error_output:near | ||
| 78 | EXTRN notest2:near | ||
| 79 | EXTRN slashp_erase:near ;AN000; | ||
| 80 | EXTRN std_printf:near | ||
| 81 | EXTRN tcommand:near | ||
| 82 | |||
| 83 | PUBLIC badpath_err ;AN022; | ||
| 84 | PUBLIC crename | ||
| 85 | PUBLIC erase | ||
| 86 | PUBLIC extend_setup ;AN022; | ||
| 87 | PUBLIC Get_ext_error_number ;AN022; | ||
| 88 | PUBLIC Get_file_code_page_tag ;AN000; | ||
| 89 | PUBLIC pause | ||
| 90 | PUBLIC Set_ext_error_msg ;AN000; | ||
| 91 | PUBLIC set_file_code_page ;AN000; | ||
| 92 | PUBLIC typefil | ||
| 93 | PUBLIC volume | ||
| 94 | |||
| 95 | |||
| 96 | assume ds:trangroup,es:trangroup | ||
| 97 | |||
| 98 | break Pause | ||
| 99 | assume ds:trangroup,es:trangroup | ||
| 100 | |||
| 101 | PAUSE: | ||
| 102 | mov dx,offset trangroup:pausemes_ptr | ||
| 103 | call std_printf | ||
| 104 | invoke GetKeystroke | ||
| 105 | invoke crlf2 | ||
| 106 | return | ||
| 107 | |||
| 108 | break Erase | ||
| 109 | |||
| 110 | ;**************************************************************** | ||
| 111 | ;* | ||
| 112 | ;* ROUTINE: DEL/ERASE - erase file(s) | ||
| 113 | ;* | ||
| 114 | ;* FUNCTION: PARSE command line for file or path name and /P | ||
| 115 | ;* and invoke PATHCRUNCH. If an error occurs, set | ||
| 116 | ;* up an error message and transfer control to CERROR. | ||
| 117 | ;* Otherwise, transfer control to NOTEST2 if /P not | ||
| 118 | ;* entered or SLASHP_ERASE if /P entered. | ||
| 119 | ;* | ||
| 120 | ;* INPUT: command line at offset 81H | ||
| 121 | ;* | ||
| 122 | ;* OUTPUT: if no error: | ||
| 123 | ;* FCB at 5ch set up with filename(s) entered | ||
| 124 | ;* Current directory set to entered directory | ||
| 125 | ;* | ||
| 126 | ;**************************************************************** | ||
| 127 | |||
| 128 | assume ds:trangroup,es:trangroup | ||
| 129 | |||
| 130 | ERASE: | ||
| 131 | mov si,81H ;AC000; get command line | ||
| 132 | mov comsw,0 ;AN000; clear switch indicator | ||
| 133 | mov di,offset trangroup:parse_erase ;AN000; Get adderss of PARSE_erase | ||
| 134 | xor cx,cx ;AN000; clear cx,dx | ||
| 135 | |||
| 136 | erase_scan: | ||
| 137 | xor dx,dx ;AN000; | ||
| 138 | invoke parse_with_msg ;AC018; call parser | ||
| 139 | cmp ax,end_of_line ;AN000; are we at end of line? | ||
| 140 | jz good_line ;AN000; yes - done parsing | ||
| 141 | cmp ax,result_no_error ;AC000; did we have an error? | ||
| 142 | jnz errj2 ;AC000; yes exit | ||
| 143 | |||
| 144 | cmp parse1_syn,offset trangroup:slash_p_syn ;AN000; was /P entered? | ||
| 145 | je set_erase_prompt ;AN000; yes - go set prompt | ||
| 146 | |||
| 147 | ; | ||
| 148 | ; Must be filespec since no other matches occurred. move filename to srcbuf | ||
| 149 | ; | ||
| 150 | push si ;AC000; save position in line | ||
| 151 | lds si,parse1_addr ;AC000; get address of filespec | ||
| 152 | cmp byte ptr[si+1],colon_char ;AC000; drive specified? | ||
| 153 | jnz Erase_drive_ok ;AC000; no - continue | ||
| 154 | cmp byte ptr[si+2],end_of_line_out ;AC000; was only drive entered? | ||
| 155 | jnz erase_drive_ok ;AC000; no - continue | ||
| 156 | mov ax,error_file_not_found ;AN022; get message number in control block | ||
| 157 | jmp short extend_setup ;AC000; exit | ||
| 158 | |||
| 159 | erase_drive_ok: | ||
| 160 | invoke move_to_srcbuf ;AC000; move to srcbuf | ||
| 161 | pop si ;AC000; get position back | ||
| 162 | jmp short erase_scan ;AN000; continue parsing | ||
| 163 | |||
| 164 | set_erase_prompt: | ||
| 165 | cmp comsw,0 ;AN018; was /P already entered? | ||
| 166 | jz ok_to_set_erase_prompt ;AN018; no go set switch | ||
| 167 | mov ax,moreargs_ptr ;AN018; set up too many arguments | ||
| 168 | invoke setup_parse_error_msg ;AN018; set up an error message | ||
| 169 | jmp short errj2 ;AN018; exit | ||
| 170 | |||
| 171 | ok_to_set_erase_prompt: ;AN018; | ||
| 172 | inc comsw ;AN000; indicate /p specified | ||
| 173 | jmp short erase_scan ;AN000; continue parsing | ||
| 174 | |||
| 175 | good_line: ;G We know line is good | ||
| 176 | invoke pathcrunch | ||
| 177 | jnc checkdr | ||
| 178 | mov ax,[msg_numb] ;AN022; get message number | ||
| 179 | cmp ax,0 ;AN022; was message flag set? | ||
| 180 | jnz extend_setup ;AN022; yes - print out message | ||
| 181 | cmp [destisdir],0 ; No CHDIRs worked | ||
| 182 | jnz badpath_err ;AC022; see if they should have | ||
| 183 | |||
| 184 | checkdr: | ||
| 185 | cmp comsw,0 ;AN000; was /p specified | ||
| 186 | jz notest2j ;AN000; no - go to notest2 | ||
| 187 | jmp slashp_erase ;AN000; yes - go to slashp_erase | ||
| 188 | |||
| 189 | notest2j: | ||
| 190 | jmp notest2 | ||
| 191 | |||
| 192 | badpath_err: ;AN022; "Path not found" message | ||
| 193 | mov ax,error_path_not_found ;AN022; set up error number | ||
| 194 | |||
| 195 | extend_setup: ;AN022; | ||
| 196 | mov msg_disp_class,ext_msg_class ;AN022; set up extended error msg class | ||
| 197 | mov dx,offset TranGroup:Extend_Buf_ptr ;AC022; get extended message pointer | ||
| 198 | mov Extend_Buf_ptr,ax ;AN022; get message number in control block | ||
| 199 | errj2: ;AC022; exit jump | ||
| 200 | jmp Cerror ;AN022; | ||
| 201 | |||
| 202 | break Rename | ||
| 203 | |||
| 204 | ; **************************************************************** | ||
| 205 | ; * | ||
| 206 | ; * ROUTINE: CRENAME - rename file(s) | ||
| 207 | ; * | ||
| 208 | ; * FUNCTION: PARSE command line for one full filespec and one | ||
| 209 | ; * filename. Invoke PATHCRUNCH on the full filespec. | ||
| 210 | ; * Make sure the second filespec only contains a | ||
| 211 | ; * filename. If both openands are valid, attempt | ||
| 212 | ; * to rename the file. | ||
| 213 | ; * | ||
| 214 | ; * INPUT: command line at offset 81H | ||
| 215 | ; * | ||
| 216 | ; * OUTPUT: none | ||
| 217 | ; * | ||
| 218 | ; **************************************************************** | ||
| 219 | |||
| 220 | assume ds:trangroup,es:trangroup | ||
| 221 | |||
| 222 | CRENAME: | ||
| 223 | |||
| 224 | mov si,81H ;AC000; Point to command line | ||
| 225 | mov di,offset trangroup:parse_rename;AN000; Get adderss of PARSE_RENAME | ||
| 226 | xor cx,cx ;AN000; clear cx,dx | ||
| 227 | xor dx,dx ;AN000; | ||
| 228 | invoke parse_with_msg ;AC018; call parser | ||
| 229 | cmp ax,result_no_error ;AC000; did we have an error? | ||
| 230 | jz crename_no_parse_error ;AC000; no - continue | ||
| 231 | JMP crename_parse_error ;AC000; Yes, fail. (need long jump) | ||
| 232 | |||
| 233 | ; | ||
| 234 | ; Get first file name returned from parse into our buffer | ||
| 235 | ; | ||
| 236 | crename_no_parse_error: | ||
| 237 | push si ;AN000; save position in line | ||
| 238 | lds si,parse1_addr ;AN000; get address of filespec | ||
| 239 | invoke move_to_srcbuf ;AN000; move to srcbuf | ||
| 240 | pop si ;AN000; restore position in line | ||
| 241 | |||
| 242 | xor dx,dx ;AN000; clear dx | ||
| 243 | invoke parse_with_msg ;AC018; call parser | ||
| 244 | cmp ax,result_no_error ;AN000; did we have an error? | ||
| 245 | JNZ crename_parse_error ;AN000; Yes, fail. | ||
| 246 | |||
| 247 | ; | ||
| 248 | ; Check the second file name for drive letter colon | ||
| 249 | ; | ||
| 250 | push si ;AN000; save position in line | ||
| 251 | lds si,parse1_addr ;AC000; get address of path | ||
| 252 | |||
| 253 | mov al,':' ;AC000; | ||
| 254 | cmp [si+1],al ;AC000; Does the 2nd parm have a drive spec? | ||
| 255 | jnz ren_no_drive ;AN000; Yes, error | ||
| 256 | mov msg_disp_class,parse_msg_class ;AN000; set up parse error msg class | ||
| 257 | mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer | ||
| 258 | mov Extend_Buf_ptr,BadParm_ptr ;AN000; get "Invalid parameter" message number | ||
| 259 | |||
| 260 | pop si ;AN000; | ||
| 261 | crename_parse_error: ;AC022; | ||
| 262 | jmp short errj ;AC000; | ||
| 263 | |||
| 264 | ; | ||
| 265 | ; Get second file name returned from parse into the fCB. Save | ||
| 266 | ; character after file name so we can later check to make sure it | ||
| 267 | ; isn't a path character. | ||
| 268 | ; | ||
| 269 | |||
| 270 | ren_no_drive: | ||
| 271 | mov di,FCB+10H ;AC000; set up to parse second file name | ||
| 272 | mov ax,(Parse_File_Descriptor SHL 8) OR 01H ;AC000; | ||
| 273 | int int_command ;AC000; do the function | ||
| 274 | lodsb ;AC000; Load char after filename | ||
| 275 | mov one_char_val,al ;AN000; save char after filename | ||
| 276 | pop si ;AN000; get line position back | ||
| 277 | |||
| 278 | ; | ||
| 279 | ; We have source and target. See if any args beyond. | ||
| 280 | ; | ||
| 281 | |||
| 282 | mov di,offset trangroup:parse_rename;AC000; get address of parse_rename | ||
| 283 | invoke parse_check_eol ;AC000; are we at end of line? | ||
| 284 | jnz crename_parse_error ;AN000; no, fail. | ||
| 285 | |||
| 286 | invoke pathcrunch | ||
| 287 | mov dx,offset trangroup:badcpmes_ptr | ||
| 288 | jz errj2 ; If 1st parm a dir, print error msg | ||
| 289 | jnc notest3 | ||
| 290 | mov ax,[msg_numb] ;AN022; get message number | ||
| 291 | cmp ax,0 ;AN022; was message flag set? | ||
| 292 | jnz extend_setup ;AN022; yes - print out message | ||
| 293 | cmp [destisdir],0 ; No CHDIRs worked | ||
| 294 | jz notest3 ; see if they should have | ||
| 295 | Jmp badpath_err ;AC022; set up error | ||
| 296 | |||
| 297 | notest3: | ||
| 298 | mov al,one_char_val ;AN000; move char into AX | ||
| 299 | mov dx,offset trangroup:inornot_ptr ; Load invalid fname error ptr | ||
| 300 | invoke pathchrcmp ; Is the char in al a path sep? | ||
| 301 | jz errj ; Yes, error - 2nd arg must be | ||
| 302 | ; filename only. | ||
| 303 | |||
| 304 | mov ah,FCB_Rename | ||
| 305 | mov dx,FCB | ||
| 306 | int int_command | ||
| 307 | cmp al, 0FFH ; Did an error occur?? | ||
| 308 | jnz renameok | ||
| 309 | |||
| 310 | invoke get_ext_error_number ;AN022; get extended error | ||
| 311 | SaveReg <AX> ;AC022; Save results | ||
| 312 | mov al, 0FFH ; Restore original error state | ||
| 313 | |||
| 314 | renameok: | ||
| 315 | push ax | ||
| 316 | invoke restudir | ||
| 317 | pop ax | ||
| 318 | inc al | ||
| 319 | retnz | ||
| 320 | |||
| 321 | RestoreReg <AX> ;AC022; get the error number back | ||
| 322 | cmp ax,error_file_not_found ;AN022; error file not found? | ||
| 323 | jz use_renerr ;AN022; yes - use generic error message | ||
| 324 | cmp ax,error_access_denied ;AN022; error file not found? | ||
| 325 | jz use_renerr ;AN022; yes - use generic error message | ||
| 326 | jmp extend_setup ;AN022; need long jump - use extended error | ||
| 327 | |||
| 328 | use_renerr: | ||
| 329 | mov dx,offset trangroup:RenErr_ptr ;AC022; | ||
| 330 | |||
| 331 | ERRJ: | ||
| 332 | jmp Cerror | ||
| 333 | |||
| 334 | ret56: ret | ||
| 335 | |||
| 336 | break Type | ||
| 337 | |||
| 338 | ;**************************************************************** | ||
| 339 | ;* | ||
| 340 | ;* ROUTINE: TYPEFIL - Display the contents of a file to the | ||
| 341 | ;* standard output device | ||
| 342 | ;* | ||
| 343 | ;* SYNTAX: TYPE filespec | ||
| 344 | ;* | ||
| 345 | ;* FUNCTION: If a valid filespec is found, read the file until | ||
| 346 | ;* 1Ah and display the contents to STDOUT. | ||
| 347 | ;* | ||
| 348 | ;* INPUT: command line at offset 81H | ||
| 349 | ;* | ||
| 350 | ;* OUTPUT: none | ||
| 351 | ;* | ||
| 352 | ;**************************************************************** | ||
| 353 | |||
| 354 | assume ds:trangroup,es:trangroup | ||
| 355 | |||
| 356 | TYPEFIL: | ||
| 357 | mov si,81H | ||
| 358 | mov di,offset trangroup:parse_mrdir ;AN000; Get adderss of PARSE_MRDIR | ||
| 359 | xor cx,cx ;AN000; clear cx,dx | ||
| 360 | xor dx,dx ;AN000; | ||
| 361 | invoke parse_with_msg ;AC018; call parser | ||
| 362 | cmp ax,result_no_error ;AC000; did we have an error? | ||
| 363 | jnz typefil_parse_error ;AN000; yes - issue error message | ||
| 364 | |||
| 365 | push si ;AC000; save position in line | ||
| 366 | lds si,parse1_addr ;AC000; get address of filespec | ||
| 367 | invoke move_to_srcbuf ;AC000; move to srcbuf | ||
| 368 | pop si ;AC000; get position back | ||
| 369 | mov di,offset trangroup:parse_mrdir ;AC000; get address of parse_mrdir | ||
| 370 | invoke parse_check_eol ;AC000; are we at end of line? | ||
| 371 | jz gottarg ;AC000; yes - continue | ||
| 372 | |||
| 373 | typefil_parse_error: ;AN000; no - set up error message and exit | ||
| 374 | jmp Cerror | ||
| 375 | |||
| 376 | gottarg: | ||
| 377 | invoke setpath | ||
| 378 | test [destinfo],00000010b ; Does the filespec contain wildcards | ||
| 379 | jz nowilds ; No, continue processing | ||
| 380 | mov dx,offset trangroup:inornot_ptr ; Yes, report error | ||
| 381 | jmp Cerror | ||
| 382 | nowilds: | ||
| 383 | mov ax,ExtOpen SHL 8 ;AC000; open the file | ||
| 384 | mov bx,read_open_mode ;AN000; get open mode for TYPE | ||
| 385 | xor cx,cx ;AN000; no special files | ||
| 386 | mov dx,read_open_flag ;AN000; set up open flags | ||
| 387 | mov di,-1 ;AN030; no parm list | ||
| 388 | mov si,offset trangroup:srcbuf ;AN030; get file name | ||
| 389 | int int_command | ||
| 390 | jnc typecont ; If open worked, continue. Otherwise load | ||
| 391 | |||
| 392 | Typerr: ;AN022; | ||
| 393 | push cs ;AN022; make sure we have local segment | ||
| 394 | pop ds ;AN022; | ||
| 395 | invoke set_ext_error_msg ;AN022; | ||
| 396 | |||
| 397 | Typerr2: ;AN022; | ||
| 398 | mov string_ptr_2,offset trangroup:srcbuf ;AC022; get address of failed string | ||
| 399 | mov Extend_buf_sub,one_subst ;AC022; put number of subst in control block | ||
| 400 | jmp cerror ;AC022; exit | ||
| 401 | |||
| 402 | typecont: | ||
| 403 | mov bx,ax ;AC000; get Handle | ||
| 404 | mov cx,stdout ;AN000; set output to STDOUT | ||
| 405 | call set_file_code_page ;AN000; Set code page on output device | ||
| 406 | jc typerr2 ;AN022; exit if error | ||
| 407 | |||
| 408 | mov zflag,0 ; Reset ^Z flag | ||
| 409 | mov ds,[TPA] | ||
| 410 | xor dx,dx | ||
| 411 | ASSUME DS:NOTHING | ||
| 412 | |||
| 413 | typelp: | ||
| 414 | cmp cs:[zflag],0 ;AC050; Is the ^Z flag set? | ||
| 415 | retnz ; Yes, return | ||
| 416 | mov cx,cs:[bytcnt] ;AC056; No, continue | ||
| 417 | mov ah,read | ||
| 418 | int int_command | ||
| 419 | jc typerr ;AN022; Exit if error | ||
| 420 | mov cx,ax | ||
| 421 | jcxz typelp_ret ;AC000; exit if nothing read | ||
| 422 | push ds | ||
| 423 | pop es ; Check to see if a ^Z was read. | ||
| 424 | assume es:nothing | ||
| 425 | xor di,di | ||
| 426 | push ax | ||
| 427 | mov al,1ah | ||
| 428 | repnz scasb | ||
| 429 | pop ax | ||
| 430 | xchg ax,cx | ||
| 431 | cmp ax,0 | ||
| 432 | jnz foundz ; Yes, handle it | ||
| 433 | cmp byte ptr [di-1],1ah ; No, double check | ||
| 434 | jnz typecont2 ; No ^Z, continue | ||
| 435 | |||
| 436 | foundz: | ||
| 437 | sub cx,ax ; Otherwise change cx so that only those | ||
| 438 | dec cx ; bytes up to but NOT including the ^Z | ||
| 439 | push cs ; will be typed. | ||
| 440 | pop es | ||
| 441 | assume es:trangroup | ||
| 442 | not zflag ; Turn on ^Z flag so that the routine | ||
| 443 | |||
| 444 | typecont2: ; will quit after this write. | ||
| 445 | push bx | ||
| 446 | mov bx,1 | ||
| 447 | mov ah,write | ||
| 448 | int int_command | ||
| 449 | pop bx | ||
| 450 | jc Error_outputj | ||
| 451 | cmp ax,cx | ||
| 452 | jz typelp | ||
| 453 | dec cx | ||
| 454 | cmp ax,cx | ||
| 455 | retz ; One less byte OK (^Z) | ||
| 456 | |||
| 457 | Error_outputj: | ||
| 458 | mov bx,1 | ||
| 459 | mov ax,IOCTL SHL 8 | ||
| 460 | int int_command | ||
| 461 | test dl,devid_ISDEV | ||
| 462 | retnz ; If device, no error message | ||
| 463 | jmp error_output | ||
| 464 | |||
| 465 | typelp_ret: | ||
| 466 | ret | ||
| 467 | |||
| 468 | break Volume | ||
| 469 | assume ds:trangroup,es:trangroup | ||
| 470 | |||
| 471 | ; | ||
| 472 | ; VOLUME command displays the volume ID on the specified drive | ||
| 473 | ; | ||
| 474 | VOLUME: | ||
| 475 | |||
| 476 | mov si,81H | ||
| 477 | mov di,offset trangroup:parse_vol ;AN000; Get adderss of PARSE_VOL | ||
| 478 | xor cx,cx ;AN000; clear cx,dx | ||
| 479 | xor dx,dx ;AN000; | ||
| 480 | invoke parse_with_msg ;AC018; call parser | ||
| 481 | cmp ax,end_of_line ;AC000; are we at end of line? | ||
| 482 | jz OkVolArg ;AC000; Yes, display default volume ID | ||
| 483 | cmp ax,result_no_error ;AC000; did we have an error? | ||
| 484 | jnz BadVolArg ;AC000; Yes, fail. | ||
| 485 | ; | ||
| 486 | ; We have parsed off the drive. See if there are any more chars left | ||
| 487 | ; | ||
| 488 | |||
| 489 | mov di,offset trangroup:parse_vol ;AC000; get address of parse_vol | ||
| 490 | xor dx,dx ;AC000; | ||
| 491 | invoke parse_check_eol ;AC000; call parser | ||
| 492 | jz OkVolArg ;AC000; yes, end of road | ||
| 493 | ; | ||
| 494 | ; The line was not interpretable. Report an error. | ||
| 495 | ; | ||
| 496 | badvolarg: | ||
| 497 | jmp Cerror | ||
| 498 | ; | ||
| 499 | ; Find the Volume ID on the disk. | ||
| 500 | ; | ||
| 501 | PUBLIC OkVolArg | ||
| 502 | OKVOLARG: | ||
| 503 | invoke crlf2 | ||
| 504 | mov al,blank ;AN051; Print out a blank | ||
| 505 | invoke print_char ;AN051; before volume message | ||
| 506 | push ds | ||
| 507 | pop es | ||
| 508 | ; | ||
| 509 | ; Volume IDs are only findable via extended FCBs or find_first with attributes | ||
| 510 | ; of volume_id ONLY. | ||
| 511 | ; | ||
| 512 | |||
| 513 | mov di,FCB-7 ; Point to extended FCB beginning | ||
| 514 | mov al,-1 ; Tag to indicate Extention | ||
| 515 | stosb | ||
| 516 | xor ax,ax ; Zero padding to volume label | ||
| 517 | stosw | ||
| 518 | stosw | ||
| 519 | stosb | ||
| 520 | mov al,attr_volume_ID ; Look for volume label | ||
| 521 | stosb | ||
| 522 | inc di ; Skip drive byte; it is already set | ||
| 523 | mov cx,11 ; fill in remainder of file | ||
| 524 | mov al,'?' | ||
| 525 | rep stosb | ||
| 526 | ; | ||
| 527 | ; Set up transfer address (destination of search first information) | ||
| 528 | ; | ||
| 529 | mov dx,offset trangroup:dirbuf | ||
| 530 | mov ah,set_DMA | ||
| 531 | int int_command | ||
| 532 | ; | ||
| 533 | ; Do the search | ||
| 534 | ; | ||
| 535 | mov dx,FCB-7 | ||
| 536 | mov ah,Dir_Search_First | ||
| 537 | int int_command | ||
| 538 | |||
| 539 | ;******************************** | ||
| 540 | ; Print volume ID info | ||
| 541 | |||
| 542 | push ax ;AC000; AX return from SEARCH_FIRST for VOL ID | ||
| 543 | mov al,DS:[FCB] ;AC000; get drive letter | ||
| 544 | add al,'@' | ||
| 545 | cmp al,'@' | ||
| 546 | jnz drvok | ||
| 547 | mov al,[curdrv] | ||
| 548 | add al,capital_A | ||
| 549 | drvok: | ||
| 550 | mov vol_drv,al ;AC000; get drive letter into argument | ||
| 551 | pop ax ;AC000; get return code back | ||
| 552 | or al,al ;AC000; volume label found? | ||
| 553 | jz Get_vol_name ;AC000; volume label exists - go get it | ||
| 554 | mov dx,offset trangroup:VolMes_ptr_2 ;AC000; set up no volume message | ||
| 555 | jmp short print_serial ;AC000; go print it | ||
| 556 | |||
| 557 | Get_vol_name: | ||
| 558 | mov di,offset trangroup:charbuf | ||
| 559 | mov dx,di | ||
| 560 | mov si,offset trangroup:dirbuf + 8 ;AN000; 3/3/KK | ||
| 561 | mov cx,11 ;AN000; 3/3/KK | ||
| 562 | rep movsb ;AN000; 3/3/KK | ||
| 563 | |||
| 564 | xor al,al ;AC000; store a zero to terminate the string | ||
| 565 | stosb | ||
| 566 | mov dx,offset trangroup:VolMes_ptr ;AC000; set up message | ||
| 567 | |||
| 568 | PRINT_SERIAL: | ||
| 569 | |||
| 570 | ; | ||
| 571 | ; Attempt to get the volume serial number from the disk. If an error | ||
| 572 | ; occurs, do not print volume serial number. | ||
| 573 | ; | ||
| 574 | |||
| 575 | push dx ;AN000; save message offset | ||
| 576 | mov ax,(GetSetMediaID SHL 8) ;AC036; Get the volume serial info | ||
| 577 | mov bl,DS:[FCB] ;AN000; get drive number from FCB | ||
| 578 | mov dx,offset trangroup:vol_ioctl_buf ;AN000;target buffer | ||
| 579 | int int_command ;AN000; do the call | ||
| 580 | pop dx ;AN000; get message offset back | ||
| 581 | jc printvol_end ;AN000; if error, just go print label | ||
| 582 | call std_printf ;AC000; go print volume message | ||
| 583 | mov al,blank ;AN051; Print out a blank | ||
| 584 | invoke print_char ;AN051; before volume message | ||
| 585 | mov dx,offset trangroup:VolSerMes_ptr ;AN000; get serial number message | ||
| 586 | |||
| 587 | printvol_end: | ||
| 588 | jmp std_printf ;AC000; go print and exit | ||
| 589 | |||
| 590 | ;**************************************************************** | ||
| 591 | ;* | ||
| 592 | ;* ROUTINE: Set file Code page | ||
| 593 | ;* | ||
| 594 | ;* FUNCTION: Check CPSW status, if CPSW is on, get the file's | ||
| 595 | ;* code page and attempt to invoke it on the | ||
| 596 | ;* output device. | ||
| 597 | ;* | ||
| 598 | ;* INPUT: file handle in BX - unless copyflg is set | ||
| 599 | ;* handle of output device in CX | ||
| 600 | ;* | ||
| 601 | ;* OUTPUT: if carry set (code page invoke failed) | ||
| 602 | ;* ax = extended error | ||
| 603 | ;* otherwise | ||
| 604 | ;* ax modified | ||
| 605 | ;* | ||
| 606 | ;* | ||
| 607 | ;**************************************************************** | ||
| 608 | |||
| 609 | Set_file_code_page proc near ;AN000; | ||
| 610 | |||
| 611 | push bx ;AN000; save registers | ||
| 612 | push di ;AN000; | ||
| 613 | push dx ;AN000; | ||
| 614 | |||
| 615 | cmp cpyflag,1 ;AN000; were we called from COPY? | ||
| 616 | jz Already_have_cp ;AN000; yes - already have code page | ||
| 617 | call get_file_code_page_tag ;AN000; get the file's code page | ||
| 618 | jc cp_set_error ;AN000; if error - just continue | ||
| 619 | |||
| 620 | already_have_cp: ;AN000; See what was returned. | ||
| 621 | mov ax,(file_times SHL 8)+set_XA ;AC030; set code page | ||
| 622 | mov di,offset trangroup:xa_cp_out ;AC030; offset of attr list | ||
| 623 | mov bx,cx ;AN000; get handle of output device | ||
| 624 | int int_command ;AN000; | ||
| 625 | jnc set_file_cp_end ;AN000; all okay - return | ||
| 626 | cp_set_error: | ||
| 627 | pop dx ;AC030; we don't restore DX for error - | ||
| 628 | call Set_Ext_Error_msg ;AN000; we return error message | ||
| 629 | jmp short set_file_cp_exit ;AC030; exit | ||
| 630 | |||
| 631 | set_file_cp_end: ;AN000; finished | ||
| 632 | pop dx ;AN000; restore registers | ||
| 633 | |||
| 634 | set_file_cp_exit: | ||
| 635 | pop di ;AN000; | ||
| 636 | pop bx ;AN000; | ||
| 637 | |||
| 638 | ret ;AN000; return | ||
| 639 | |||
| 640 | Set_file_code_page endp ;AN000; | ||
| 641 | |||
| 642 | |||
| 643 | ;**************************************************************** | ||
| 644 | ;* | ||
| 645 | ;* ROUTINE: Get file Code page tag | ||
| 646 | ;* | ||
| 647 | ;* FUNCTION: Get code page file attribute. | ||
| 648 | ;* | ||
| 649 | ;* INPUT: file handle in BX | ||
| 650 | ;* | ||
| 651 | ;* OUTPUT: if error - carry set | ||
| 652 | ;* otherwise - xa_list_attr set to file's code page | ||
| 653 | ;* | ||
| 654 | ;* AX and DI modified | ||
| 655 | ;* | ||
| 656 | ;**************************************************************** | ||
| 657 | |||
| 658 | |||
| 659 | Get_file_code_page_tag proc near ;AN000; | ||
| 660 | |||
| 661 | push cx ;AN030; | ||
| 662 | push si ;AN030; | ||
| 663 | push di ;AN030; | ||
| 664 | mov xa_list_attr,0 ;AN030; initialize code page | ||
| 665 | mov ax,(file_times SHL 8)+get_XA ;AC030; get extended attributes | ||
| 666 | mov si,offset trangroup:xa_cp ;AN030; get xa request buffer | ||
| 667 | mov di,offset trangroup:xa_cp_out ;AC030; get xa output buffer | ||
| 668 | mov cx,xa_cp_length ;AN030; length of buffer | ||
| 669 | int int_command ;AN000; | ||
| 670 | pop di ;AN030; | ||
| 671 | pop si ;AN030; | ||
| 672 | pop cx ;AN030; | ||
| 673 | |||
| 674 | ret ;AN000; return | ||
| 675 | |||
| 676 | Get_file_code_page_tag endp ;AN000; | ||
| 677 | |||
| 678 | |||
| 679 | ;**************************************************************** | ||
| 680 | ;* | ||
| 681 | ;* ROUTINE: Set_ext_error_msg | ||
| 682 | ;* | ||
| 683 | ;* FUNCTION: Sets up extended error message for printing | ||
| 684 | ;* | ||
| 685 | ;* INPUT: return from INT 21 | ||
| 686 | ;* | ||
| 687 | ;* OUTPUT: extended error message set up in extended error | ||
| 688 | ;* buffer. | ||
| 689 | ;* | ||
| 690 | ;**************************************************************** | ||
| 691 | |||
| 692 | Set_ext_error_msg proc near ;AN000; | ||
| 693 | |||
| 694 | call get_ext_error_number ;AC022; get the extended error | ||
| 695 | mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class | ||
| 696 | mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer | ||
| 697 | mov Extend_Buf_ptr,ax ;AN000; get message number in control block | ||
| 698 | stc ;AN000; make sure carry is set | ||
| 699 | |||
| 700 | ret ;AN000; return | ||
| 701 | |||
| 702 | Set_ext_error_msg endp ;AN000; | ||
| 703 | |||
| 704 | ;**************************************************************** | ||
| 705 | ;* | ||
| 706 | ;* ROUTINE: Get_ext_error_number | ||
| 707 | ;* | ||
| 708 | ;* FUNCTION: Does get extended error function call | ||
| 709 | ;* | ||
| 710 | ;* INPUT: return from INT 21 | ||
| 711 | ;* | ||
| 712 | ;* OUTPUT: AX - extended error number | ||
| 713 | ;* | ||
| 714 | ;**************************************************************** | ||
| 715 | |||
| 716 | Get_ext_error_number proc near ;AN022; | ||
| 717 | |||
| 718 | SaveReg <BX,CX,DX,SI,DI,BP,ES,DS> ;AN022; save registers | ||
| 719 | mov ah,GetExtendedError ;AN022; get extended error | ||
| 720 | xor bx,bx ;AN022; clear BX | ||
| 721 | int int_command ;AN022; | ||
| 722 | RestoreReg <DS,ES,BP,DI,SI,DX,CX,BX> ;AN022; restore registers | ||
| 723 | |||
| 724 | ret ;AN022; return | ||
| 725 | |||
| 726 | Get_ext_error_number endp ;AN022; | ||
| 727 | |||
| 728 | trancode ends | ||
| 729 | end | ||
| 730 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/COMMAND/TCMD2A.ASM b/v4.0/src/CMD/COMMAND/TCMD2A.ASM new file mode 100644 index 0000000..9dcb066 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/TCMD2A.ASM | |||
| @@ -0,0 +1,552 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)tcmd2a.asm 4.1 85/06/25 | ||
| 3 | ; SCCSID = @(#)tcmd2a.asm 4.1 85/06/25 | ||
| 4 | TITLE PART5 COMMAND Transient routines. | ||
| 5 | |||
| 6 | INCLUDE comsw.asm | ||
| 7 | |||
| 8 | .xlist | ||
| 9 | .xcref | ||
| 10 | INCLUDE DOSSYM.INC | ||
| 11 | INCLUDE comequ.asm | ||
| 12 | INCLUDE comseg.asm | ||
| 13 | include ioctl.inc | ||
| 14 | .list | ||
| 15 | .cref | ||
| 16 | |||
| 17 | |||
| 18 | CODERES SEGMENT PUBLIC BYTE ;AC000; | ||
| 19 | CODERES ENDS | ||
| 20 | |||
| 21 | DATARES SEGMENT PUBLIC BYTE ;AC000; | ||
| 22 | DATARES ENDS | ||
| 23 | |||
| 24 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 25 | EXTRN arg_buf_ptr:word | ||
| 26 | EXTRN BadCurDrv:byte ;AC000; | ||
| 27 | EXTRN clsstring:byte | ||
| 28 | EXTRN dback_ptr:word | ||
| 29 | EXTRN display_ioctl:word ;AN000; | ||
| 30 | EXTRN display_width:word ;AN000; | ||
| 31 | EXTRN Extend_buf_ptr:word ;AN049; | ||
| 32 | EXTRN linperpag:word ;AN000; | ||
| 33 | EXTRN msg_disp_class:byte ;AN049; | ||
| 34 | EXTRN nulpath_ptr:word | ||
| 35 | EXTRN prompt_table:word | ||
| 36 | EXTRN string_buf_ptr:word ;AC000; | ||
| 37 | EXTRN vermes_ptr:word | ||
| 38 | TRANDATA ENDS | ||
| 39 | |||
| 40 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 41 | EXTRN Arg_Buf:byte | ||
| 42 | EXTRN bwdbuf:byte | ||
| 43 | EXTRN curdrv:byte | ||
| 44 | EXTRN dirchar:byte | ||
| 45 | EXTRN major_ver_num:word | ||
| 46 | EXTRN minor_ver_num:word | ||
| 47 | EXTRN srcxname:byte ;AN049; | ||
| 48 | EXTRN string_ptr_2:word | ||
| 49 | TRANSPACE ENDS | ||
| 50 | |||
| 51 | TRANCODE SEGMENT PUBLIC BYTE | ||
| 52 | |||
| 53 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 54 | |||
| 55 | ;--------------- | ||
| 56 | |||
| 57 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 58 | EXTRN arg:byte ; the arg structure! | ||
| 59 | transpace ends | ||
| 60 | ;--------------- | ||
| 61 | |||
| 62 | EXTRN cerror:near ;AN049; | ||
| 63 | EXTRN crlf2:near | ||
| 64 | EXTRN drvbad:near | ||
| 65 | EXTRN std_printf:near | ||
| 66 | |||
| 67 | PUBLIC build_dir_for_chdir | ||
| 68 | PUBLIC build_dir_for_prompt | ||
| 69 | PUBLIC build_dir_string | ||
| 70 | PUBLIC cls | ||
| 71 | PUBLIC path | ||
| 72 | PUBLIC print_char | ||
| 73 | PUBLIC print_drive | ||
| 74 | PUBLIC print_version | ||
| 75 | PUBLIC print_b | ||
| 76 | PUBLIC print_back | ||
| 77 | PUBLIC print_eq | ||
| 78 | PUBLIC print_esc | ||
| 79 | PUBLIC print_g | ||
| 80 | PUBLIC print_l | ||
| 81 | PUBLIC print_prompt | ||
| 82 | PUBLIC version | ||
| 83 | |||
| 84 | break Version | ||
| 85 | assume ds:trangroup,es:trangroup | ||
| 86 | |||
| 87 | VERSION: | ||
| 88 | call crlf2 | ||
| 89 | call print_version | ||
| 90 | jmp crlf2 | ||
| 91 | |||
| 92 | print_version: | ||
| 93 | mov ah,Get_version | ||
| 94 | int int_command | ||
| 95 | push ax | ||
| 96 | xor ah,ah | ||
| 97 | mov major_ver_num,ax | ||
| 98 | pop ax | ||
| 99 | xchg ah,al | ||
| 100 | xor ah,ah | ||
| 101 | mov minor_ver_num,ax | ||
| 102 | mov dx,offset trangroup:vermes_ptr | ||
| 103 | jmp std_printf | ||
| 104 | |||
| 105 | print_prompt: | ||
| 106 | push ds | ||
| 107 | push cs | ||
| 108 | pop ds ; MAKE SURE DS IS IN TRANGROUP | ||
| 109 | push es | ||
| 110 | invoke find_prompt ; LOOK FOR PROMPT STRING | ||
| 111 | jc PP0 ; CAN'T FIND ONE | ||
| 112 | cmp byte ptr es:[di],0 | ||
| 113 | jnz PP1 | ||
| 114 | PP0: | ||
| 115 | call print_drive ; USE DEFAULT PROMPT | ||
| 116 | mov al,sym | ||
| 117 | call print_char | ||
| 118 | jmp short PP5 | ||
| 119 | |||
| 120 | PP1: | ||
| 121 | mov al,es:[di] ; GET A CHAR | ||
| 122 | inc di | ||
| 123 | or al,al | ||
| 124 | jz PP5 ; NUL TERMINATED | ||
| 125 | cmp al,dollar ; META CHARACTER? | ||
| 126 | jz PP2 ; NOPE | ||
| 127 | PPP1: | ||
| 128 | call print_char | ||
| 129 | jmp PP1 | ||
| 130 | |||
| 131 | PP2: | ||
| 132 | mov al,es:[di] | ||
| 133 | inc di | ||
| 134 | mov bx,offset trangroup:prompt_table-3 | ||
| 135 | or al,al | ||
| 136 | jz PP5 | ||
| 137 | |||
| 138 | PP3: | ||
| 139 | add bx,3 | ||
| 140 | invoke upconv | ||
| 141 | cmp al,[bx] | ||
| 142 | jz PP4 | ||
| 143 | cmp byte ptr [bx],0 | ||
| 144 | jnz PP3 | ||
| 145 | jmp PP1 | ||
| 146 | |||
| 147 | PP4: | ||
| 148 | push es | ||
| 149 | push di | ||
| 150 | push cs | ||
| 151 | pop es | ||
| 152 | call [bx+1] | ||
| 153 | pop di | ||
| 154 | pop es | ||
| 155 | jmp PP1 | ||
| 156 | |||
| 157 | PP5: | ||
| 158 | pop es ; RESTORE SEGMENTS | ||
| 159 | pop ds | ||
| 160 | return | ||
| 161 | |||
| 162 | |||
| 163 | print_back: | ||
| 164 | mov dx,offset trangroup:dback_ptr | ||
| 165 | jmp std_printf | ||
| 166 | |||
| 167 | print_EQ: | ||
| 168 | mov al,'=' | ||
| 169 | jmp short print_char | ||
| 170 | |||
| 171 | print_esc: | ||
| 172 | mov al,1BH | ||
| 173 | jmp short print_char | ||
| 174 | |||
| 175 | print_G: | ||
| 176 | mov al,rabracket | ||
| 177 | jmp short print_char | ||
| 178 | |||
| 179 | print_L: | ||
| 180 | mov al,labracket | ||
| 181 | jmp short print_char | ||
| 182 | |||
| 183 | print_B: | ||
| 184 | mov al,vbar | ||
| 185 | |||
| 186 | print_char: | ||
| 187 | push es | ||
| 188 | push ds | ||
| 189 | pop es | ||
| 190 | push di | ||
| 191 | push dx | ||
| 192 | mov dl,al ;AC000; Get char into al | ||
| 193 | mov ah,Std_CON_output ;AC000; print the char to stdout | ||
| 194 | int int_command ;AC000; | ||
| 195 | pop dx | ||
| 196 | pop di | ||
| 197 | pop es | ||
| 198 | ret | ||
| 199 | |||
| 200 | print_drive: | ||
| 201 | mov ah,Get_Default_drive | ||
| 202 | int int_command | ||
| 203 | add al,capital_A | ||
| 204 | call print_char | ||
| 205 | ret | ||
| 206 | |||
| 207 | ASSUME DS:TRANGROUP,ES:TRANGROUP | ||
| 208 | |||
| 209 | build_dir_for_prompt: | ||
| 210 | xor dl,dl | ||
| 211 | mov si,offset trangroup:bwdbuf | ||
| 212 | mov di,SI | ||
| 213 | mov al,CurDrv | ||
| 214 | add al,'A' | ||
| 215 | mov ah,':' | ||
| 216 | stosw | ||
| 217 | mov al,[dirchar] | ||
| 218 | stosb | ||
| 219 | xchg si,di | ||
| 220 | mov string_ptr_2,di | ||
| 221 | mov ah,Current_dir | ||
| 222 | int int_command | ||
| 223 | mov dx,offset trangroup:string_buf_ptr | ||
| 224 | jnc DoPrint | ||
| 225 | mov dx,offset trangroup:BadCurDrv | ||
| 226 | DoPrint: | ||
| 227 | call std_printf | ||
| 228 | |||
| 229 | ret | ||
| 230 | |||
| 231 | build_dir_for_chdir: | ||
| 232 | call build_dir_string | ||
| 233 | mov dx,offset trangroup:bwdbuf | ||
| 234 | mov string_ptr_2,dx | ||
| 235 | mov dx,offset trangroup:string_buf_ptr | ||
| 236 | call std_printf | ||
| 237 | ret | ||
| 238 | |||
| 239 | build_dir_string: | ||
| 240 | mov dl,ds:[FCB] | ||
| 241 | mov al,DL | ||
| 242 | add al,'@' | ||
| 243 | cmp al,'@' | ||
| 244 | jnz gotdrive | ||
| 245 | add al,[CURDRV] | ||
| 246 | inc al | ||
| 247 | |||
| 248 | gotdrive: | ||
| 249 | push ax | ||
| 250 | mov si,offset trangroup:bwdbuf+3 | ||
| 251 | mov ah,Current_dir | ||
| 252 | int int_command | ||
| 253 | jnc dpbisok | ||
| 254 | push cs | ||
| 255 | pop ds | ||
| 256 | jmp drvbad | ||
| 257 | |||
| 258 | dpbisok: | ||
| 259 | mov di,offset trangroup:bwdbuf | ||
| 260 | mov dx,di | ||
| 261 | pop ax | ||
| 262 | mov ah,':' | ||
| 263 | stosw | ||
| 264 | mov al,[dirchar] | ||
| 265 | stosb | ||
| 266 | |||
| 267 | ret | ||
| 268 | |||
| 269 | break Path | ||
| 270 | assume ds:trangroup,es:trangroup | ||
| 271 | |||
| 272 | PATH: | ||
| 273 | xor al,al ;AN049; Set up holding buffer | ||
| 274 | mov di,offset Trangroup:srcxname ;AN049; for PATH while parsing | ||
| 275 | stosb ;AN049; Initialize PATH to null | ||
| 276 | dec di ;AN049; point to the start of buffer | ||
| 277 | invoke PGetarg ; Pre scan for arguments | ||
| 278 | jz disppath ; Print the current path | ||
| 279 | cmp al,semicolon ;AC049; NUL path argument? | ||
| 280 | jnz pathslp ;AC049; | ||
| 281 | inc si ;AN049; point past semicolon | ||
| 282 | jmp short scan_white ;AC049; Yes - make sure nothing else on line | ||
| 283 | |||
| 284 | pathslp: ; Get the user specified path | ||
| 285 | lodsb ; Get a character | ||
| 286 | cmp al,end_of_line_in ;AC049; Is it end of line? | ||
| 287 | jz path_eol ;AC049; yes - end of command | ||
| 288 | |||
| 289 | invoke testkanj ;See if DBCS | ||
| 290 | jz notkanj2 ;No - continue | ||
| 291 | stosb ;AC049; Yes - store the first byte | ||
| 292 | lodsb ;skip second byte of DBCS | ||
| 293 | |||
| 294 | path_hold: ;AN049; | ||
| 295 | stosb ;AC049; Store a byte in the PATH buffer | ||
| 296 | jmp short pathslp ;continue parsing | ||
| 297 | |||
| 298 | notkanj2: | ||
| 299 | invoke upconv ;upper case the character | ||
| 300 | cmp al,semicolon ;AC049; ';' not a delimiter on PATH | ||
| 301 | jz path_hold ;AC049; go store it | ||
| 302 | invoke delim ;delimiter? | ||
| 303 | jnz path_hold ;AC049; no - go store character | ||
| 304 | |||
| 305 | scan_white: ;AN049; make sure were at EOL | ||
| 306 | lodsb ;AN049; get a character | ||
| 307 | cmp al,end_of_line_in ;AN049; end of line? | ||
| 308 | jz path_eol ;AN049; yes - go set path | ||
| 309 | cmp al,blank ;AN049; whitespace? | ||
| 310 | jz scan_white ;AN049; yes - continue scanning | ||
| 311 | cmp al,tab_chr ;AN049; whitespace? | ||
| 312 | jz scan_white ;AN049; yes - continue scanning | ||
| 313 | |||
| 314 | mov dx,offset TranGroup:Extend_Buf_ptr ;AN049; no - set up error message | ||
| 315 | mov Extend_Buf_ptr,MoreArgs_ptr ;AN049; get "Too many parameters" message number | ||
| 316 | mov msg_disp_class,parse_msg_class ;AN049; set up parse error msg class | ||
| 317 | jmp cerror ;AN049; | ||
| 318 | |||
| 319 | path_eol: ;AN049; Parsing was clean | ||
| 320 | xor al,al ;AN049; null terminate the PATH | ||
| 321 | stosb ;AN049; buffer | ||
| 322 | invoke find_path ;AN049; Find PATH in environment | ||
| 323 | invoke delete_path ;AC049; Delete any offending name | ||
| 324 | invoke scan_double_null ;AC049; Scan to end of environment | ||
| 325 | invoke move_name ;AC049; move in PATH= | ||
| 326 | mov si,offset Trangroup:srcxname ;AN049; Set up source as PATH buffer | ||
| 327 | |||
| 328 | store_path: ;AN049; Store the PATH in the environment | ||
| 329 | lodsb ;AN049; Get a character | ||
| 330 | cmp al,end_of_line_out ;AN049; null character? | ||
| 331 | jz got_paths ;AN049; yes - exit | ||
| 332 | invoke store_char ;AN049; no - store character | ||
| 333 | jmp short store_path ;AN049; continue | ||
| 334 | |||
| 335 | got_paths: ;AN049; we're finished | ||
| 336 | xor ax,ax ;null terminate the PATH in | ||
| 337 | stosw ; the environment | ||
| 338 | return | ||
| 339 | |||
| 340 | disppath: | ||
| 341 | invoke find_path ;AN049; | ||
| 342 | call print_path | ||
| 343 | call crlf2 | ||
| 344 | return | ||
| 345 | |||
| 346 | print_path: | ||
| 347 | cmp byte ptr es:[di],0 | ||
| 348 | jnz path1 | ||
| 349 | |||
| 350 | path0: | ||
| 351 | mov dx,offset trangroup:nulpath_ptr | ||
| 352 | push cs | ||
| 353 | pop es | ||
| 354 | push cs | ||
| 355 | pop ds | ||
| 356 | jmp std_printf | ||
| 357 | |||
| 358 | path1: | ||
| 359 | push es | ||
| 360 | pop ds | ||
| 361 | sub di,5 | ||
| 362 | mov si,di | ||
| 363 | ASSUME DS:RESGROUP | ||
| 364 | invoke scasb2 ; LOOK FOR NUL | ||
| 365 | cmp cx,0FFH | ||
| 366 | jz path0 | ||
| 367 | push cs | ||
| 368 | pop es | ||
| 369 | mov di,offset trangroup:arg_buf | ||
| 370 | mov dx,100h | ||
| 371 | sub dx,cx | ||
| 372 | xchg dx,cx | ||
| 373 | rep movsb | ||
| 374 | mov dx,offset trangroup:arg_buf_ptr | ||
| 375 | push cs | ||
| 376 | pop ds | ||
| 377 | jmp std_printf | ||
| 378 | |||
| 379 | ASSUME DS:TRANGROUP | ||
| 380 | |||
| 381 | break Cls | ||
| 382 | |||
| 383 | ; **************************************************************** | ||
| 384 | ; * | ||
| 385 | ; * ROUTINE: CLS | ||
| 386 | ; * | ||
| 387 | ; * FUNCTION: Clear the screen using INT 10h. If ANSI.SYS is | ||
| 388 | ; * installed, send a control string to clear the | ||
| 389 | ; * screen. | ||
| 390 | ; * | ||
| 391 | ; * INPUT: command line at offset 81H | ||
| 392 | ; * | ||
| 393 | ; * OUTPUT: none | ||
| 394 | ; * | ||
| 395 | ; **************************************************************** | ||
| 396 | |||
| 397 | assume ds:trangroup,es:trangroup | ||
| 398 | |||
| 399 | ANSI_installed equ 0ffh | ||
| 400 | |||
| 401 | CLS: | ||
| 402 | mov ah,Mult_ANSI ;AN000; see if ANSI.SYS installed | ||
| 403 | mov al,0 ;AN000; | ||
| 404 | int 2fh ;AN000; | ||
| 405 | cmp al,ANSI_installed ;AN000; | ||
| 406 | jz ansicls ;AN000; installed - go do ANSI CLS | ||
| 407 | |||
| 408 | check_lines: | ||
| 409 | mov ax,(IOCTL SHL 8) + generic_ioctl_handle ;AN000; get lines per page on display | ||
| 410 | mov bx,stdout ;AN000; lines for stdout | ||
| 411 | mov ch,ioc_sc ;AN000; type is display | ||
| 412 | mov cl,get_generic ;AN000; get information | ||
| 413 | mov dx,offset trangroup:display_ioctl ;AN000; | ||
| 414 | int int_command ;AN000; | ||
| 415 | jc no_variable ;AN000; function had error, use default | ||
| 416 | mov ax,linperpag ;AN000; get number of rows returned | ||
| 417 | mov dh,al ;AN000; set number of rows | ||
| 418 | mov ax,display_width ;AN000; get number of columns returned | ||
| 419 | mov dl,al ;AN000; set number of columns | ||
| 420 | jmp short regcls ;AN000; go do cls | ||
| 421 | |||
| 422 | no_variable: | ||
| 423 | mov bx,stdout ;AC000; set handle as stdout | ||
| 424 | mov ax,IOCTL SHL 8 ;AC000; do ioctl - get device | ||
| 425 | int int_command ;AC000; info | ||
| 426 | test dl,devid_ISDEV ;AC000; is handle a device | ||
| 427 | jz ANSICLS ;AC000; If a file put out ANSI | ||
| 428 | test dl,devid_SPECIAL ;AC000; | ||
| 429 | jnz cls_normal ;AC000; If not special CON, do ANSI | ||
| 430 | |||
| 431 | ansicls: | ||
| 432 | call ansi_cls ;AN000; clear the screen | ||
| 433 | jmp short cls_ret ;AN000; exit | ||
| 434 | |||
| 435 | ; | ||
| 436 | ; Get video mode | ||
| 437 | ; | ||
| 438 | |||
| 439 | cls_normal: ;AC000; | ||
| 440 | |||
| 441 | mov ah,get_video_state ;AC000; set up to get video state | ||
| 442 | int video_io_int ;AC000; do int 10h - BIOS video IO | ||
| 443 | cmp al,video_alpha ;AC000; see if in text mode | ||
| 444 | jbe DoAlpha | ||
| 445 | cmp al,video_bw ;AC000; see if black & white card | ||
| 446 | jz DoAlpha | ||
| 447 | ; | ||
| 448 | ; We are in graphics mode. Bogus IBM ROM does not scroll correctly. We will | ||
| 449 | ; be just as bogus and set the mode that we just got. This will blank the | ||
| 450 | ; screen too. | ||
| 451 | ; | ||
| 452 | mov ah,set_video_mode ;AC000; set video mode call | ||
| 453 | int video_io_int ;AC000; do int 10h - BIOS video IO | ||
| 454 | jmp short cls_ret ;AC000; exit | ||
| 455 | |||
| 456 | DoAlpha: | ||
| 457 | ; | ||
| 458 | ; Get video mode and number of columns to scroll | ||
| 459 | ; | ||
| 460 | mov ah,get_video_state ;AC000; set up to get current video state | ||
| 461 | int video_io_int ;AC000; do int 10h - BIOS video IO | ||
| 462 | mov dl,ah | ||
| 463 | mov dh,linesperpage ;AC000; have 25 rows on the screen | ||
| 464 | |||
| 465 | regcls: | ||
| 466 | call reg_cls ;AC000; go clear the screen | ||
| 467 | |||
| 468 | cls_ret: | ||
| 469 | ret ;AC000; exit | ||
| 470 | |||
| 471 | ; **************************************************************** | ||
| 472 | ; * | ||
| 473 | ; * ROUTINE: REG_CLS | ||
| 474 | ; * | ||
| 475 | ; * FUNCTION: Clear the screen using INT 10H. | ||
| 476 | ; * | ||
| 477 | ; * INPUT: DL = NUMBER OF COLUMNS | ||
| 478 | ; * DH = NUMBER OF ROWS | ||
| 479 | ; * | ||
| 480 | ; * OUTPUT: none | ||
| 481 | ; * | ||
| 482 | ; **************************************************************** | ||
| 483 | |||
| 484 | reg_cls proc near ;AC000; | ||
| 485 | |||
| 486 | ; | ||
| 487 | ; Set overscan to black. | ||
| 488 | ; | ||
| 489 | |||
| 490 | dec dh ;AC000; decrement rows and columns | ||
| 491 | dec dl ;AC000; to zero base | ||
| 492 | push dx ;AN000; save rows,columns | ||
| 493 | mov ah,set_color_palette ;AC000; set up to set the color to blank | ||
| 494 | xor bx,bx | ||
| 495 | int video_io_int ;AC000; do int 10h - BIOS video IO | ||
| 496 | pop dx ;AN000; retore rows,colums | ||
| 497 | |||
| 498 | xor ax,ax ;AC000; zero out ax | ||
| 499 | mov CX,ax ;AC000; an cx | ||
| 500 | ; | ||
| 501 | ; Scroll active page | ||
| 502 | ; | ||
| 503 | mov ah,scroll_video_page ;AC000; set up to scroll page up | ||
| 504 | mov bh,video_attribute ;AC000; attribute for blank line | ||
| 505 | xor bl,bl ;AC000; set BL to 0 | ||
| 506 | int video_io_int ;AC000; do int 10h - BIOS video IO | ||
| 507 | ; | ||
| 508 | ; Seek to cursor to 0,0 | ||
| 509 | ; | ||
| 510 | mov ah,set_cursor_position ;AC000; set up to set cursor position | ||
| 511 | xor dx,dx ;AC000; row and column 0 | ||
| 512 | mov bh,0 ;AC000; | ||
| 513 | int video_io_int ;AC000; do into 10h - BIOS video IO | ||
| 514 | |||
| 515 | ret ;AC000; | ||
| 516 | |||
| 517 | reg_cls endp ;AC000; | ||
| 518 | |||
| 519 | |||
| 520 | |||
| 521 | ; **************************************************************** | ||
| 522 | ; * | ||
| 523 | ; * ROUTINE: ANSI_CLS | ||
| 524 | ; * | ||
| 525 | ; * FUNCTION: Clear the screen using by writing a control code | ||
| 526 | ; * to STDOUT. | ||
| 527 | ; * | ||
| 528 | ; * INPUT: none | ||
| 529 | ; * | ||
| 530 | ; * OUTPUT: none | ||
| 531 | ; * | ||
| 532 | ; **************************************************************** | ||
| 533 | |||
| 534 | ansi_cls proc near ;AC000; | ||
| 535 | |||
| 536 | mov si,offset trangroup:clsstring | ||
| 537 | lodsb | ||
| 538 | mov cl,al | ||
| 539 | xor ch,ch | ||
| 540 | mov ah,Raw_CON_IO | ||
| 541 | clrloop: | ||
| 542 | lodsb | ||
| 543 | mov DL,al | ||
| 544 | int int_command | ||
| 545 | loop clrloop | ||
| 546 | return | ||
| 547 | |||
| 548 | ansi_cls endp ;AC000; | ||
| 549 | |||
| 550 | trancode ends | ||
| 551 | end | ||
| 552 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/COMMAND/TCMD2B.ASM b/v4.0/src/CMD/COMMAND/TCMD2B.ASM new file mode 100644 index 0000000..4db1f11 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/TCMD2B.ASM | |||
| @@ -0,0 +1,597 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)tcmd2b.asm 4.1 85/09/22 | ||
| 3 | ; SCCSID = @(#)tcmd2b.asm 4.1 85/09/22 | ||
| 4 | TITLE PART5 COMMAND Transient routines. | ||
| 5 | |||
| 6 | .xlist | ||
| 7 | .xcref | ||
| 8 | INCLUDE comsw.asm | ||
| 9 | INCLUDE DOSSYM.INC | ||
| 10 | INCLUDE comseg.asm | ||
| 11 | INCLUDE comequ.asm | ||
| 12 | .list | ||
| 13 | .cref | ||
| 14 | |||
| 15 | |||
| 16 | CODERES SEGMENT PUBLIC BYTE ;AC000; | ||
| 17 | EXTRN LODCOM1:NEAR | ||
| 18 | CODERES ENDS | ||
| 19 | |||
| 20 | DATARES SEGMENT PUBLIC BYTE ;AC000; | ||
| 21 | EXTRN crit_msg_off:word ;AC000; | ||
| 22 | EXTRN crit_msg_seg:word ;AC000; | ||
| 23 | EXTRN IO_SAVE:WORD | ||
| 24 | EXTRN OldTerm:DWORD | ||
| 25 | EXTRN PARENT:WORD | ||
| 26 | ;AD060; EXTRN pars_msg_off:word ;AC000; | ||
| 27 | ;AD060; EXTRN pars_msg_seg:word ;AC000; | ||
| 28 | EXTRN PERMCOM:BYTE ;AN045; | ||
| 29 | EXTRN RetCode:WORD | ||
| 30 | DATARES ENDS | ||
| 31 | |||
| 32 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 33 | EXTRN ACRLF_PTR:WORD ;AN007; | ||
| 34 | EXTRN baddev_ptr:word | ||
| 35 | EXTRN CP_active_Ptr:word | ||
| 36 | EXTRN CP_not_all_Ptr:word | ||
| 37 | EXTRN CP_not_set_Ptr:word | ||
| 38 | EXTRN Extend_buf_ptr:word ;AN000; | ||
| 39 | EXTRN Extend_buf_sub:byte ;AN000; | ||
| 40 | EXTRN inv_code_page:word ;AC000; | ||
| 41 | EXTRN msg_disp_class:byte ;AN000; | ||
| 42 | EXTRN NLSFUNC_Ptr:word ;AC000; | ||
| 43 | EXTRN parse_chcp:byte ;AC000; | ||
| 44 | EXTRN parse_chdir:byte ;AC000; | ||
| 45 | EXTRN parse_ctty:byte ;AC000; | ||
| 46 | EXTRN string_buf_ptr:word ;AC000; | ||
| 47 | |||
| 48 | TRANDATA ENDS | ||
| 49 | |||
| 50 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 51 | EXTRN COMBUF:BYTE | ||
| 52 | EXTRN parse_last:word ;AN018; | ||
| 53 | EXTRN parse1_addr:dword ;AC000; | ||
| 54 | EXTRN parse1_type:byte ;AC000; | ||
| 55 | EXTRN RESSEG:WORD | ||
| 56 | EXTRN srcbuf:byte | ||
| 57 | EXTRN srcxname:byte ;AC000; | ||
| 58 | EXTRN string_ptr_2:word | ||
| 59 | EXTRN system_cpage:word | ||
| 60 | EXTRN TRAN_TPA:WORD | ||
| 61 | TRANSPACE ENDS | ||
| 62 | |||
| 63 | TRANCODE SEGMENT PUBLIC BYTE | ||
| 64 | |||
| 65 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 66 | |||
| 67 | ;--------------- | ||
| 68 | |||
| 69 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 70 | EXTRN arg:byte ; the arg structure! | ||
| 71 | TRANSPACE ENDS | ||
| 72 | ;--------------- | ||
| 73 | |||
| 74 | EXTRN cerror:near | ||
| 75 | |||
| 76 | PUBLIC $exit | ||
| 77 | PUBLIC chcp | ||
| 78 | PUBLIC ctty | ||
| 79 | PUBLIC parse_check_eol ;AN000; | ||
| 80 | PUBLIC parse_with_msg ;AN018; | ||
| 81 | PUBLIC setup_parse_error_msg ;AN018; | ||
| 82 | PUBLIC truename ;AN000; | ||
| 83 | |||
| 84 | break Ctty | ||
| 85 | assume ds:trangroup,es:trangroup | ||
| 86 | |||
| 87 | ; **************************************************************** | ||
| 88 | ; * | ||
| 89 | ; * ROUTINE: CTTY - Change console | ||
| 90 | ; * | ||
| 91 | ; * SYNTAX: CTTY device | ||
| 92 | ; * | ||
| 93 | ; * FUNCTION: If a valid console device is specified, CTTY will | ||
| 94 | ; * duplicate the device handle to STDIN, STDOUT and | ||
| 95 | ; * STDERR. This routine returns to LODCOM1. | ||
| 96 | ; * | ||
| 97 | ; * INPUT: command line at offset 81H | ||
| 98 | ; * | ||
| 99 | ; * OUTPUT: none | ||
| 100 | ; * | ||
| 101 | ; **************************************************************** | ||
| 102 | |||
| 103 | CTTY: | ||
| 104 | push ds ;AN000; Get local ES | ||
| 105 | pop es ;AN000; | ||
| 106 | mov si,81H ;AC000; Get command argument for CTTY | ||
| 107 | |||
| 108 | mov di,offset trangroup:parse_ctty ;AC000; Get adderss of PARSE_CTTY | ||
| 109 | xor cx,cx ;AC000; clear cx,dx | ||
| 110 | xor dx,dx ;AC000; | ||
| 111 | invoke cmd_parse ;AC000; call parser | ||
| 112 | cmp ax,end_of_line ;AN000; are we at end of line? | ||
| 113 | jz ctty_error ;AN000; yes - error | ||
| 114 | cmp ax,result_no_error ;AN000; did an error occur | ||
| 115 | jnz ctty_error ;AN000; YES -ERROR | ||
| 116 | |||
| 117 | push si ;AN000; save position in line | ||
| 118 | lds si,parse1_addr ;AN000; get address of filespec | ||
| 119 | mov di,offset trangroup:srcbuf ;AN000; get address of srcbuf | ||
| 120 | |||
| 121 | ctty_move_filename: ;AN000; put filespec in srcbuf | ||
| 122 | lodsb ;AN000; get a char from buffer | ||
| 123 | stosb ;AN000; store in srcbuf | ||
| 124 | cmp al,end_of_line_out ;AN000; it char a terminator? | ||
| 125 | jnz ctty_move_filename ;AN000; no - keep moving | ||
| 126 | pop si ;AN000; get line position back | ||
| 127 | mov di,offset trangroup:parse_ctty ;AC000; Get adderss of PARSE_CTTY | ||
| 128 | call parse_check_eol ;AN000; are we at end of line? | ||
| 129 | jz nocolon ;AN000; yes - continue | ||
| 130 | |||
| 131 | ctty_error: | ||
| 132 | jmp isbaddev ;AC000; yes - exit | ||
| 133 | |||
| 134 | nocolon: | ||
| 135 | mov dx,offset trangroup:srcbuf ;AN000; get address of srcbuf | ||
| 136 | MOV AX,(OPEN SHL 8) OR 2 ; Read and write | ||
| 137 | INT int_command ; Open new device | ||
| 138 | JC ISBADDEV | ||
| 139 | MOV BX,AX | ||
| 140 | MOV AX,IOCTL SHL 8 | ||
| 141 | INT int_command | ||
| 142 | TEST DL,80H | ||
| 143 | JNZ DEVISOK | ||
| 144 | |||
| 145 | CLOSEDEV: ;AN007; | ||
| 146 | MOV AH,CLOSE ; Close initial handle | ||
| 147 | INT int_command | ||
| 148 | |||
| 149 | ISBADDEV: | ||
| 150 | MOV DX,OFFSET TRANGROUP:BADDEV_ptr | ||
| 151 | invoke std_printf | ||
| 152 | JMP RESRET | ||
| 153 | |||
| 154 | DEVISOK: | ||
| 155 | push dx ;AN007; save device info | ||
| 156 | mov ax,acrlf_ptr ;AN021; get message number for 0d, 0a | ||
| 157 | mov dh,util_msg_class ;AN021; this is a utility message | ||
| 158 | push bx ;AN021; save handle | ||
| 159 | invoke Tsysgetmsg ;AN021; get the address of the message | ||
| 160 | mov dx,si ;AN021; get address into dx | ||
| 161 | mov ax,(write shl 8) ;AN007; write to device | ||
| 162 | mov cx,2 ;AN007; write two bytes | ||
| 163 | int int_command ;AN007; | ||
| 164 | pop bx ;AN021; get back handle | ||
| 165 | pop dx ;AN007; get back device info | ||
| 166 | jc closedev ;AN007; if error, quit | ||
| 167 | XOR DH,DH | ||
| 168 | OR DL,3 ; Make sure has CON attributes | ||
| 169 | MOV AX,(IOCTL SHL 8) OR 1 | ||
| 170 | INT int_command | ||
| 171 | PUSH BX ; Save handle | ||
| 172 | MOV CX,3 | ||
| 173 | XOR BX,BX | ||
| 174 | |||
| 175 | ICLLOOP: ; Close basic handles | ||
| 176 | MOV AH,CLOSE | ||
| 177 | INT int_command | ||
| 178 | INC BX | ||
| 179 | LOOP ICLLOOP | ||
| 180 | POP BX ; Get handle | ||
| 181 | MOV AH,XDUP | ||
| 182 | INT int_command ; Dup it to 0 | ||
| 183 | MOV AH,XDUP | ||
| 184 | INT int_command ; Dup to 1 | ||
| 185 | MOV AH,XDUP | ||
| 186 | INT int_command ; Dup to 2 | ||
| 187 | MOV AH,CLOSE ; Close initial handle | ||
| 188 | INT int_command | ||
| 189 | |||
| 190 | RESRET: | ||
| 191 | MOV DS,[RESSEG] | ||
| 192 | ASSUME DS:RESGROUP | ||
| 193 | PUSH DS | ||
| 194 | MOV AX,WORD PTR DS:[PDB_JFN_Table] ; Get new 0 and 1 | ||
| 195 | MOV [IO_SAVE],AX | ||
| 196 | MOV AX,OFFSET RESGROUP:LODCOM1 | ||
| 197 | PUSH AX | ||
| 198 | |||
| 199 | ZMMMM PROC FAR | ||
| 200 | RET ; Force header to be checked | ||
| 201 | ZMMMM ENDP | ||
| 202 | |||
| 203 | break Chcp | ||
| 204 | |||
| 205 | ;**************************************************************** | ||
| 206 | ;* | ||
| 207 | ;* ROUTINE: CHCP - Change code page internal command | ||
| 208 | ;* (added DOS 3.30 07/21/86) | ||
| 209 | ;* | ||
| 210 | ;* SYNTAX: CHCP [xxx] | ||
| 211 | ;* where xxx is a valid code page | ||
| 212 | ;* | ||
| 213 | ;* FUNCTION: If xxx is specified, CHCP will use INT 21H function | ||
| 214 | ;* 6402H to set the code page to xxxx. If no parameters | ||
| 215 | ;* are specified, CHCP will use INT 21H function 6401H | ||
| 216 | ;* to get global code page and display it to the user. | ||
| 217 | ;* | ||
| 218 | ;* INPUT: command line at offset 81H | ||
| 219 | ;* | ||
| 220 | ;* OUTPUT: none | ||
| 221 | ;* | ||
| 222 | ;**************************************************************** | ||
| 223 | |||
| 224 | NLSFUNC_installed equ 0ffh | ||
| 225 | set_global_cp equ 2 | ||
| 226 | get_global_cp equ 1 | ||
| 227 | |||
| 228 | assume ds:trangroup,es:trangroup | ||
| 229 | |||
| 230 | CHCP: | ||
| 231 | push ds ;AN000; Get local ES | ||
| 232 | pop es ;AN000; | ||
| 233 | mov si,81H ;AC000; Get command argument for CHCP | ||
| 234 | |||
| 235 | mov di,offset trangroup:parse_chcp ;AN000; Get adderss of PARSE_CHCP | ||
| 236 | xor cx,cx ;AC000; clear cx,dx | ||
| 237 | xor dx,dx ;AC000; | ||
| 238 | call parse_with_msg ;AC018; call parser | ||
| 239 | cmp ax,end_of_line ;AN000; are we at end of line? | ||
| 240 | |||
| 241 | jnz setcp ;AC000; no go get number & set code page | ||
| 242 | jmp getcp ;AC000; yes - no parm - get code page | ||
| 243 | |||
| 244 | setcp: | ||
| 245 | cmp ax,result_no_error ;AN000; did we have an error? | ||
| 246 | jne cp_error ;AC018; yes - go issue message | ||
| 247 | |||
| 248 | push cx ;AN000; save positional count | ||
| 249 | mov bx,offset trangroup:parse1_addr ;AN000; get number returned | ||
| 250 | mov cx,word ptr [bx] ;AN000; into cx | ||
| 251 | mov system_cpage,cx ;AN000; save user input number | ||
| 252 | pop cx ;AC000; restore positional count | ||
| 253 | mov di,offset trangroup:parse_chcp ;AN000; Get adderss of PARSE_CHCP | ||
| 254 | call parse_check_eol ;AN000; are we at end of line? | ||
| 255 | jnz cp_error ;AC000; no - exit | ||
| 256 | |||
| 257 | okset: | ||
| 258 | mov ah,NLSFUNC ;AN000; see if NLSFUNC installed | ||
| 259 | mov al,0 ;AN000; | ||
| 260 | int 2fh ;AN000; | ||
| 261 | cmp al,NLSFUNC_installed ;AN000; | ||
| 262 | jz got_NLS ;AN000; Yes - continue | ||
| 263 | mov dx,offset trangroup:NLSFUNC_ptr ;AN000; no - set up error message | ||
| 264 | jmp short cp_error ;AN000; error exit | ||
| 265 | |||
| 266 | got_NLS: | ||
| 267 | mov bx,system_cpage ;AN000; get user input code page | ||
| 268 | mov ah,getsetcdpg ;get/set global code page function | ||
| 269 | mov al,set_global_cp ;minor - set | ||
| 270 | int int_command | ||
| 271 | jnc chcp_return ;no error - exit | ||
| 272 | ; | ||
| 273 | ;added for p716 | ||
| 274 | ; | ||
| 275 | cmp ax,error_file_not_found ;p716 was the error file not found? | ||
| 276 | jnz chcp_other_error ;no - country.sys was found | ||
| 277 | |||
| 278 | mov ah,GetExtendedError ;p850 see if error is invalid data | ||
| 279 | xor bx,bx ; which is file was found but CP | ||
| 280 | int int_command ; information was not found. | ||
| 281 | cmp ax,error_invalid_data ;AC000; invalid code page | ||
| 282 | jnz no_countrysys ;no - use file not found | ||
| 283 | mov dx,offset trangroup:inv_code_page ;AN000; get message | ||
| 284 | jmp short cp_error ;AC000; error exit | ||
| 285 | |||
| 286 | no_countrysys: | ||
| 287 | mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class | ||
| 288 | mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer | ||
| 289 | mov Extend_Buf_ptr,error_file_not_found ;AN000; get message number in control block | ||
| 290 | jmp short cp_error ;AC000; error exit | ||
| 291 | |||
| 292 | chcp_other_error: | ||
| 293 | ; | ||
| 294 | ; end of p716 | ||
| 295 | ; | ||
| 296 | mov ah,GetExtendedError ;error - see what it is | ||
| 297 | xor bx,bx | ||
| 298 | int int_command | ||
| 299 | cmp ax,65 ;was it access denied? | ||
| 300 | jnz none_set ;no - assume all failed | ||
| 301 | mov dx,offset trangroup:cp_not_all_ptr ;set up message | ||
| 302 | jmp short cp_error ;AC000; error exit | ||
| 303 | |||
| 304 | none_set: | ||
| 305 | mov dx,offset trangroup:cp_not_set_ptr ;set up message | ||
| 306 | cp_error: ;AN000; | ||
| 307 | jmp cerror ;exit | ||
| 308 | |||
| 309 | getcp: | ||
| 310 | mov ah,getsetcdpg ;get/set global code page function | ||
| 311 | mov al,get_global_cp ;minor - get | ||
| 312 | int int_command | ||
| 313 | mov system_cpage,bx ;get active cp for output | ||
| 314 | mov dx,offset trangroup:cp_active_ptr | ||
| 315 | invoke std_printf ;print it out | ||
| 316 | |||
| 317 | chcp_return: | ||
| 318 | |||
| 319 | RET | ||
| 320 | |||
| 321 | break TRUENAME ;AN000; | ||
| 322 | |||
| 323 | |||
| 324 | ; **************************************************************** | ||
| 325 | ; * | ||
| 326 | ; * ROUTINE: TRUENAME | ||
| 327 | ; * | ||
| 328 | ; * FUNCTION: Entry point for the internal TRUENAME command. | ||
| 329 | ; * Parses the command line. If a path is found, set | ||
| 330 | ; * SRCXNAME to path. If only a drive letter is | ||
| 331 | ; * found, set SRCXNAME to the drive letter. If | ||
| 332 | ; * no path is found, set the path of SRCXNAME to | ||
| 333 | ; * dot (.) for current directory. Use the NAME | ||
| 334 | ; * TRANSLATE system call to get the real name and | ||
| 335 | ; * then display the real name. If an error occurs | ||
| 336 | ; * issue an error message and transfer control to | ||
| 337 | ; * CERROR. | ||
| 338 | ; * | ||
| 339 | ; * INPUT: command line at offset 81H | ||
| 340 | ; * | ||
| 341 | ; * OUTPUT: none | ||
| 342 | ; * | ||
| 343 | ; **************************************************************** | ||
| 344 | |||
| 345 | assume ds:trangroup,es:trangroup ;AN000; | ||
| 346 | |||
| 347 | TRUENAME: ;AN000; TRUENAME entry point | ||
| 348 | push ds ;AN000; Get local ES | ||
| 349 | pop es ;AN000; | ||
| 350 | mov si,81H ;AN000; Get command line | ||
| 351 | mov di,offset trangroup:parse_chdir ;AN000; Get adderss of PARSE_CHDIR | ||
| 352 | xor cx,cx ;AN000; clear cx,dx | ||
| 353 | xor dx,dx ;AN000; | ||
| 354 | call parse_with_msg ;AC018; call parser | ||
| 355 | |||
| 356 | mov di,offset trangroup:srcxname ;AN000; get address of srcxname | ||
| 357 | cmp ax,end_of_line ;AN000; are we at end of line? | ||
| 358 | je tn_eol ;AN000; yes - go process | ||
| 359 | cmp ax,result_no_error ;AN000; did we have an error? | ||
| 360 | jne tn_parse_error ;AN000; yes - go issue message | ||
| 361 | cmp parse1_type,result_drive ;AN000; was a drive entered? | ||
| 362 | je tn_drive ;AN000; yes - go process | ||
| 363 | jmp short tn_filespec ;AN000; nothing else - must be filespec | ||
| 364 | |||
| 365 | tn_eol: ;AN000; no parameters on line | ||
| 366 | mov ah,end_of_line_out ;AN000; set buffer to . | ||
| 367 | mov al,dot_chr ;AN000; for current dir | ||
| 368 | stosw ;AN000; store in srcxname | ||
| 369 | jmp short tn_doit ;AN000; go do command | ||
| 370 | |||
| 371 | tn_drive: ;AN000; a drive was entered | ||
| 372 | push si ;AN000; save position in line | ||
| 373 | mov si,offset trangroup:parse1_addr ;AN000; get address of drive | ||
| 374 | lodsb ;AN000; get the drive number | ||
| 375 | add al,"A"-1 ;AN000; convert it to char | ||
| 376 | stosb ;AN000; store it in srcxname | ||
| 377 | mov ax,dot_colon ;AN000; get colon and . and | ||
| 378 | stosw ;AN000; store in srcxname | ||
| 379 | mov al,end_of_line_out ;AN000; put a terminator char | ||
| 380 | stosb ;AN000; | ||
| 381 | pop si ;AN000; get line position back | ||
| 382 | jmp short tn_check_eol ;AN000; check to make sure eol | ||
| 383 | |||
| 384 | tn_filespec: ;AN000; a filespec was entered | ||
| 385 | push si ;AN000; save position in line | ||
| 386 | lds si,parse1_addr ;AN000; get address of filespec | ||
| 387 | |||
| 388 | tn_move_filename: ;AN000; put filespec in srcxname | ||
| 389 | lodsb ;AN000; get a char from buffer | ||
| 390 | stosb ;AN000; store in srcxname | ||
| 391 | cmp al,end_of_line_out ;AN000; it char a terminator? | ||
| 392 | jnz tn_move_filename ;AN000; no - keep moving | ||
| 393 | pop si ;AN000; get line position back | ||
| 394 | |||
| 395 | tn_check_eol: ;AN000; make sure no extra parms | ||
| 396 | mov di,offset trangroup:parse_chdir ;AN000; get address of parse_chdir | ||
| 397 | call parse_check_eol ;AN000; are we at end of line? | ||
| 398 | je tn_doit ;AN000; Yes - do the command | ||
| 399 | |||
| 400 | tn_parse_error: ;AN000; A parse error occurred | ||
| 401 | jmp cerror ;AN000; Go to error routine | ||
| 402 | |||
| 403 | tn_doit: ;AN000; | ||
| 404 | mov si,offset trangroup:srcxname ;AN000; set up srcxname as source | ||
| 405 | mov di,offset trangroup:combuf ;AN000; set up combuf as target (need big target) | ||
| 406 | mov ah,xnametrans ;AN000; do name translate call | ||
| 407 | int int_command ;AN000; | ||
| 408 | jnc tn_print_xname ;AN000; If no error - print result | ||
| 409 | |||
| 410 | invoke Set_ext_error_msg ;AN000; get extended message | ||
| 411 | mov string_ptr_2,offset trangroup:srcxname ;AN000; get address of failed string | ||
| 412 | mov Extend_buf_sub,one_subst ;AN000; put number of subst in control block | ||
| 413 | jmp cerror ;AN000; Go to error routine | ||
| 414 | |||
| 415 | tn_print_xname: ;AN000; | ||
| 416 | mov string_ptr_2,offset Trangroup:combuf ;AN000; Set up address of combuf | ||
| 417 | mov dx,offset trangroup:string_buf_ptr ;AN000; Set up address of print control block | ||
| 418 | invoke crlf2 ;AN000; print a crlf | ||
| 419 | invoke printf_crlf ;AN000; print it out | ||
| 420 | |||
| 421 | ret ;AN000; | ||
| 422 | |||
| 423 | break $Exit | ||
| 424 | |||
| 425 | assume ds:trangroup,es:trangroup | ||
| 426 | |||
| 427 | $EXIT: | ||
| 428 | push ds ;AN000; save data segment | ||
| 429 | mov ds,[resseg] ;AN000; get resident data segment | ||
| 430 | |||
| 431 | assume ds:resgroup ;AN000; | ||
| 432 | |||
| 433 | cmp [permcom],0 ;AN045; is this a permanent COMMAND? | ||
| 434 | jnz no_reset ;AN045; Yes - don't do anything | ||
| 435 | ;AD060; mov ah,multdos ;AN000; reset parse message pointers | ||
| 436 | ;AD060; mov al,message_2f ;AN000; call for message retriever | ||
| 437 | ;AD060; mov dl,set_parse_msg ;AN000; set up parse message address | ||
| 438 | ;AD060; mov di,pars_msg_off ;AN000; old offset of parse messages | ||
| 439 | ;AD060; mov es,pars_msg_seg ;AN000; old segment of parse messages | ||
| 440 | ;AD060; int 2fh ;AN000; go set it | ||
| 441 | |||
| 442 | ;AD060; mov ah,multdos ;AN000; set up to call DOS through int 2fh | ||
| 443 | ;AD060; mov al,message_2f ;AN000; call for message retriever | ||
| 444 | mov ax,(multdos shl 8 or message_2f);AN060; reset parse message pointers | ||
| 445 | mov dl,set_critical_msg ;AN000; set up critical error message address | ||
| 446 | mov di,crit_msg_off ;AN000; old offset of critical messages | ||
| 447 | mov es,crit_msg_seg ;AN000; old segment of critical messages | ||
| 448 | int 2fh ;AN000; go set it | ||
| 449 | no_reset: ;AN045; | ||
| 450 | pop ds ;AN000; restore local data segment | ||
| 451 | |||
| 452 | assume ds:trangroup ;AN000; | ||
| 453 | |||
| 454 | MOV ES,[RESSEG] | ||
| 455 | |||
| 456 | assume es:resgroup | ||
| 457 | |||
| 458 | MOV AX,[PARENT] | ||
| 459 | MOV WORD PTR ES:[PDB_Parent_PID],AX | ||
| 460 | MOV AX,WORD PTR OldTerm | ||
| 461 | MOV WORD PTR ES:[PDB_Exit],AX | ||
| 462 | MOV AX,WORD PTR OldTerm+2 | ||
| 463 | MOV WORD PTR ES:[PDB_Exit+2],AX | ||
| 464 | |||
| 465 | PUSH ES | ||
| 466 | MOV ES,[TRAN_TPA] | ||
| 467 | MOV AH,DEALLOC | ||
| 468 | INT int_command ; Now running in "free" space | ||
| 469 | POP ES | ||
| 470 | |||
| 471 | MOV AH,Exit | ||
| 472 | MOV AL,BYTE PTR RetCode | ||
| 473 | INT int_command | ||
| 474 | |||
| 475 | |||
| 476 | ; **************************************************************** | ||
| 477 | ; * | ||
| 478 | ; * ROUTINE: PARSE_CHECK_EOL | ||
| 479 | ; * | ||
| 480 | ; * FUNCTION: Calls parser to see if end of line occurred. | ||
| 481 | ; * If not end of line, set up to print parse | ||
| 482 | ; * error message. ASSUMES NO MORE PARAMETERS ARE | ||
| 483 | ; * EXPECTED! | ||
| 484 | ; * | ||
| 485 | ; * INPUT: DS:SI last output from parser | ||
| 486 | ; * ES:DI points to parse block | ||
| 487 | ; * CX last output from parser | ||
| 488 | ; * | ||
| 489 | ; * OUTPUT: AX parser return code | ||
| 490 | ; * | ||
| 491 | ; * if end of line found | ||
| 492 | ; * zero flag set | ||
| 493 | ; * else | ||
| 494 | ; * MSG_DISPLAY_CLASS set to parse error | ||
| 495 | ; * | ||
| 496 | ; **************************************************************** | ||
| 497 | |||
| 498 | ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:NOTHING ;AN000; | ||
| 499 | |||
| 500 | parse_check_eol Proc near ;AN000; | ||
| 501 | |||
| 502 | xor dx,dx ;AN000; | ||
| 503 | mov [parse_last],si ;AN018; save start of parameter | ||
| 504 | invoke cmd_parse ;AN000; call parser | ||
| 505 | cmp al,end_of_line ;AN000; Are we at end of line? | ||
| 506 | jz parse_good_eol ;AN000; yes - no problem | ||
| 507 | |||
| 508 | cmp ax,result_no_error ;AN018; was any error found? | ||
| 509 | jnz ok_to_setup_pmsg ;AN018; yes - continue | ||
| 510 | inc ax ;AN018; set AX to 1 and turn off zero flag | ||
| 511 | |||
| 512 | ok_to_setup_pmsg: | ||
| 513 | call setup_parse_error_msg ;AN018; go set up error message | ||
| 514 | |||
| 515 | parse_good_eol: | ||
| 516 | ret ;AN000; | ||
| 517 | |||
| 518 | parse_check_eol endp ;AN000; | ||
| 519 | |||
| 520 | ; **************************************************************** | ||
| 521 | ; * | ||
| 522 | ; * ROUTINE: PARSE_WITH_MSG | ||
| 523 | ; * | ||
| 524 | ; * FUNCTION: Calls parser. If an error occurred, the error | ||
| 525 | ; * message is set up. | ||
| 526 | ; * | ||
| 527 | ; * INPUT: DS:SI last output from parser | ||
| 528 | ; * ES:DI points to parse block | ||
| 529 | ; * CX last output from parser | ||
| 530 | ; * | ||
| 531 | ; * OUTPUT: AX parser return code | ||
| 532 | ; * | ||
| 533 | ; * if no error | ||
| 534 | ; * outputs from parser | ||
| 535 | ; * else | ||
| 536 | ; * MSG_DISPLAY_CLASS set to parse error | ||
| 537 | ; * error message set up for STD_PRINTF | ||
| 538 | ; * | ||
| 539 | ; **************************************************************** | ||
| 540 | |||
| 541 | ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:NOTHING ;AN018; | ||
| 542 | |||
| 543 | parse_with_msg Proc near ;AN018; | ||
| 544 | |||
| 545 | mov [parse_last],si ;AN018; save start of parameter | ||
| 546 | invoke cmd_parse ;AN018; call parser | ||
| 547 | cmp al,end_of_line ;AN018; Are we at end of line? | ||
| 548 | jz parse_msg_good ;AN018; yes - no problem | ||
| 549 | cmp ax,result_no_error ;AN018; did an error occur | ||
| 550 | jz parse_msg_good ;AN018; yes - no problem | ||
| 551 | |||
| 552 | call setup_parse_error_msg ;AN018; go set up error message | ||
| 553 | |||
| 554 | parse_msg_good: | ||
| 555 | ret ;AN018; | ||
| 556 | |||
| 557 | parse_with_msg endp ;AN018; | ||
| 558 | |||
| 559 | ; **************************************************************** | ||
| 560 | ; * | ||
| 561 | ; * ROUTINE: SETUP_PARSE_ERROR_MSG | ||
| 562 | ; * | ||
| 563 | ; * FUNCTION: Calls parser. If an error occurred, the error | ||
| 564 | ; * message is set up. | ||
| 565 | ; * | ||
| 566 | ; * INPUT: AX Parse error number | ||
| 567 | ; * SI Set to past last parameter | ||
| 568 | ; * Parse_last Set to start of last parameter | ||
| 569 | ; * | ||
| 570 | ; * OUTPUT: MSG_DISPLAY_CLASS set to parse error | ||
| 571 | ; * error message set up for STD_PRINTF | ||
| 572 | ; * | ||
| 573 | ; **************************************************************** | ||
| 574 | |||
| 575 | ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:NOTHING ;AN018; | ||
| 576 | |||
| 577 | SETUP_PARSE_ERROR_MSG Proc near ;AN018; | ||
| 578 | |||
| 579 | mov msg_disp_class,parse_msg_class ;AC018; Set up parse message class | ||
| 580 | mov dx,offset TranGroup:Extend_Buf_ptr ;AC018; get extended message pointer | ||
| 581 | mov byte ptr [si],end_of_line_out ;AC018; terminate the parameter string | ||
| 582 | mov Extend_Buf_ptr,ax ;AC018; get message number in control block | ||
| 583 | cmp ax,lessargs_ptr ;AC018; if required parameter missing | ||
| 584 | jz Setup_parse_msg_ret ;AN018; no subst | ||
| 585 | mov si,[parse_last] ;AC018; get start of parameter | ||
| 586 | mov string_ptr_2,si ;AC018; get address of failed string | ||
| 587 | mov Extend_buf_sub,one_subst ;AC018; put number of subst in control block | ||
| 588 | |||
| 589 | setup_parse_msg_ret: | ||
| 590 | inc si ;AN018; make sure zero flag not set | ||
| 591 | |||
| 592 | ret ;AC018; | ||
| 593 | |||
| 594 | SETUP_PARSE_ERROR_MSG Endp ;AN018; | ||
| 595 | |||
| 596 | trancode ends | ||
| 597 | end | ||
diff --git a/v4.0/src/CMD/COMMAND/TCODE.ASM b/v4.0/src/CMD/COMMAND/TCODE.ASM new file mode 100644 index 0000000..17ad82d --- /dev/null +++ b/v4.0/src/CMD/COMMAND/TCODE.ASM | |||
| @@ -0,0 +1,540 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)tcode.asm 1.1 85/05/14 | ||
| 3 | ; SCCSID = @(#)tcode.asm 1.1 85/05/14 | ||
| 4 | TITLE Part1 COMMAND Transient Routines | ||
| 5 | |||
| 6 | INCLUDE comsw.asm | ||
| 7 | .xlist | ||
| 8 | .xcref | ||
| 9 | INCLUDE DOSSYM.INC | ||
| 10 | INCLUDE comseg.asm | ||
| 11 | INCLUDE comequ.asm | ||
| 12 | .list | ||
| 13 | .cref | ||
| 14 | |||
| 15 | |||
| 16 | CODERES SEGMENT PUBLIC BYTE ;AC000; | ||
| 17 | EXTRN EXEC_WAIT:NEAR | ||
| 18 | CODERES ENDS | ||
| 19 | |||
| 20 | DATARES SEGMENT PUBLIC BYTE ;AC000; | ||
| 21 | EXTRN BATCH:WORD | ||
| 22 | EXTRN CALL_BATCH_FLAG:byte | ||
| 23 | EXTRN CALL_FLAG:BYTE | ||
| 24 | EXTRN ECHOFLAG:BYTE | ||
| 25 | EXTRN envirseg:word | ||
| 26 | EXTRN EXTCOM:BYTE | ||
| 27 | EXTRN FORFLAG:BYTE | ||
| 28 | EXTRN IFFLAG:BYTE | ||
| 29 | EXTRN next_batch:word | ||
| 30 | EXTRN nullflag:byte | ||
| 31 | EXTRN PIPEFILES:BYTE | ||
| 32 | EXTRN PIPEFLAG:BYTE | ||
| 33 | EXTRN RE_OUT_APP:BYTE | ||
| 34 | EXTRN RE_OUTSTR:BYTE | ||
| 35 | EXTRN RESTDIR:BYTE | ||
| 36 | EXTRN SINGLECOM:WORD | ||
| 37 | EXTRN VERVAL:WORD | ||
| 38 | DATARES ENDS | ||
| 39 | |||
| 40 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 41 | EXTRN BadNam_Ptr:word ;AC000; | ||
| 42 | TRANDATA ENDS | ||
| 43 | |||
| 44 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 45 | EXTRN APPEND_EXEC:BYTE ;AN041; | ||
| 46 | EXTRN ARG1S:WORD | ||
| 47 | EXTRN ARG2S:WORD | ||
| 48 | EXTRN ARGTS:WORD | ||
| 49 | EXTRN BYTCNT:WORD | ||
| 50 | EXTRN COMBUF:BYTE | ||
| 51 | EXTRN COMSW:WORD | ||
| 52 | EXTRN CURDRV:BYTE | ||
| 53 | EXTRN HEADCALL:DWORD | ||
| 54 | EXTRN IDLEN:BYTE | ||
| 55 | EXTRN INTERNATVARS:BYTE | ||
| 56 | EXTRN PARM1:BYTE | ||
| 57 | EXTRN PARM2:BYTE | ||
| 58 | EXTRN RE_INSTR:BYTE | ||
| 59 | EXTRN RESSEG:WORD | ||
| 60 | EXTRN SPECDRV:BYTE | ||
| 61 | EXTRN STACK:WORD | ||
| 62 | EXTRN SWITCHAR:BYTE | ||
| 63 | EXTRN TPA:WORD | ||
| 64 | EXTRN UCOMBUF:BYTE | ||
| 65 | EXTRN USERDIR1:BYTE | ||
| 66 | IF IBM | ||
| 67 | EXTRN ROM_CALL:BYTE | ||
| 68 | EXTRN ROM_CS:WORD | ||
| 69 | EXTRN ROM_IP:WORD | ||
| 70 | ENDIF | ||
| 71 | |||
| 72 | TRANSPACE ENDS | ||
| 73 | |||
| 74 | ; ******************************************************************** | ||
| 75 | ; START OF TRANSIENT PORTION | ||
| 76 | ; This code is loaded at the end of memory and may be overwritten by | ||
| 77 | ; memory-intensive user programs. | ||
| 78 | |||
| 79 | TRANCODE SEGMENT PUBLIC BYTE ;AC000; | ||
| 80 | |||
| 81 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 82 | |||
| 83 | EXTRN $EXIT:NEAR | ||
| 84 | EXTRN DRVBAD:NEAR | ||
| 85 | EXTRN EXTERNAL:NEAR | ||
| 86 | EXTRN FNDCOM:NEAR | ||
| 87 | EXTRN FORPROC:NEAR | ||
| 88 | EXTRN PIPEPROC:NEAR | ||
| 89 | EXTRN PIPEPROCSTRT:NEAR | ||
| 90 | |||
| 91 | PUBLIC COMMAND | ||
| 92 | PUBLIC DOCOM | ||
| 93 | PUBLIC DOCOM1 | ||
| 94 | PUBLIC NOPIPEPROC | ||
| 95 | PUBLIC TCOMMAND | ||
| 96 | |||
| 97 | IF IBM | ||
| 98 | PUBLIC ROM_EXEC | ||
| 99 | PUBLIC ROM_SCAN | ||
| 100 | ENDIF | ||
| 101 | |||
| 102 | ORG 0 | ||
| 103 | ZERO = $ | ||
| 104 | |||
| 105 | ORG 100H ; Allow for 100H parameter area | ||
| 106 | |||
| 107 | SETDRV: | ||
| 108 | MOV AH,SET_DEFAULT_DRIVE | ||
| 109 | INT int_command | ||
| 110 | ; | ||
| 111 | ; TCOMMAND is the recycle point in COMMAND. Nothing is known here. | ||
| 112 | ; No registers (CS:IP) no flags, nothing. | ||
| 113 | ; | ||
| 114 | |||
| 115 | TCOMMAND: | ||
| 116 | MOV DS,[RESSEG] | ||
| 117 | ASSUME DS:RESGROUP | ||
| 118 | MOV AX,-1 | ||
| 119 | XCHG AX,[VERVAL] | ||
| 120 | CMP AX,-1 | ||
| 121 | JZ NOSETVER2 | ||
| 122 | MOV AH,SET_VERIFY_ON_WRITE ; AL has correct value | ||
| 123 | INT int_command | ||
| 124 | |||
| 125 | NOSETVER2: | ||
| 126 | CALL [HEADCALL] ; Make sure header fixed | ||
| 127 | XOR BP,BP ; Flag transient not read | ||
| 128 | CMP [SINGLECOM],-1 | ||
| 129 | JNZ COMMAND | ||
| 130 | |||
| 131 | $EXITPREP: | ||
| 132 | PUSH CS | ||
| 133 | POP DS | ||
| 134 | JMP $EXIT ; Have finished the single command | ||
| 135 | ASSUME DS:NOTHING | ||
| 136 | ; | ||
| 137 | ; Main entry point from resident portion. | ||
| 138 | ; | ||
| 139 | ; If BP <> 0, then we have just loaded transient portion otherwise we are | ||
| 140 | ; just beginning the processing of another command. | ||
| 141 | ; | ||
| 142 | |||
| 143 | COMMAND: | ||
| 144 | |||
| 145 | ; | ||
| 146 | ; We are not always sure of the state of the world at this time. We presume | ||
| 147 | ; worst case and initialize the relevant registers: segments and stack. | ||
| 148 | ; | ||
| 149 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 150 | CLD | ||
| 151 | MOV AX,CS | ||
| 152 | CLI | ||
| 153 | MOV SS,AX | ||
| 154 | ASSUME SS:TRANGROUP | ||
| 155 | MOV SP,OFFSET TRANGROUP:STACK | ||
| 156 | STI | ||
| 157 | MOV ES,AX | ||
| 158 | MOV DS,AX ;AN000; set DS to transient | ||
| 159 | ASSUME ES:TRANGROUP,DS:TRANGROUP ;AC000; | ||
| 160 | invoke TSYSLOADMSG ;AN000; preload messages | ||
| 161 | invoke SETSTDINOFF ;AN026; turn off critical error on STDIN | ||
| 162 | invoke SETSTDOUTOFF ;AN026; turn off critical error on STDOUT | ||
| 163 | mov append_exec,0 ;AN041; set internal append state off | ||
| 164 | |||
| 165 | MOV DS,[RESSEG] | ||
| 166 | ASSUME DS:RESGROUP | ||
| 167 | |||
| 168 | MOV [UCOMBUF],COMBUFLEN ; Init UCOMBUF | ||
| 169 | MOV [COMBUF],COMBUFLEN ; Init COMBUF (Autoexec doing DATE) | ||
| 170 | ; | ||
| 171 | ; If we have just loaded the transient, then we do NOT need to initialize the | ||
| 172 | ; command buffer. ???? DO WE NEED TO RESTORE THE USERS DIRECTORY ???? I | ||
| 173 | ; guess not: the only circumstances in which we reload the command processor | ||
| 174 | ; is after a transient program execution. In this case, we let the current | ||
| 175 | ; directory lie where it may. | ||
| 176 | ; | ||
| 177 | OR BP,BP ; See if just read | ||
| 178 | JZ TESTRDIR ; Not read, check user directory | ||
| 179 | MOV WORD PTR [UCOMBUF+1],0D01H ; Reset buffer | ||
| 180 | JMP SHORT NOSETBUF | ||
| 181 | |||
| 182 | TESTRDIR: | ||
| 183 | CMP [RESTDIR],0 | ||
| 184 | JZ NOSETBUF ; User directory OK | ||
| 185 | PUSH DS | ||
| 186 | ; | ||
| 187 | ; We have an unusual situation to handle. The user *may* have changed his | ||
| 188 | ; directory as a result of an internal command that got aborted. Restoring it | ||
| 189 | ; twice may not help us: the problem may never go away. We just attempt it | ||
| 190 | ; once and give up. | ||
| 191 | ; | ||
| 192 | MOV [RESTDIR],0 ; Flag users dirs OK | ||
| 193 | PUSH CS | ||
| 194 | POP DS | ||
| 195 | ASSUME DS:TRANGROUP | ||
| 196 | MOV DX,OFFSET TRANGROUP:USERDIR1 | ||
| 197 | MOV AH,CHDIR | ||
| 198 | INT int_command ; Restore users directory | ||
| 199 | POP DS | ||
| 200 | ASSUME DS:RESGROUP | ||
| 201 | |||
| 202 | NOSETBUF: | ||
| 203 | CMP [PIPEFILES],0 | ||
| 204 | JZ NOPCLOSE ; Don't bother if they don't exist | ||
| 205 | CMP [PIPEFLAG],0 | ||
| 206 | JNZ NOPCLOSE ; Don't del if still piping | ||
| 207 | INVOKE PIPEDEL | ||
| 208 | |||
| 209 | NOPCLOSE: | ||
| 210 | MOV [EXTCOM],0 ; Flag internal command | ||
| 211 | MOV AX,CS ; Get segment we're in | ||
| 212 | MOV DS,AX | ||
| 213 | ASSUME DS:TRANGROUP | ||
| 214 | |||
| 215 | PUSH AX | ||
| 216 | MOV DX,OFFSET TRANGROUP:INTERNATVARS | ||
| 217 | MOV AX,INTERNATIONAL SHL 8 | ||
| 218 | INT 21H | ||
| 219 | POP AX | ||
| 220 | SUB AX,[TPA] ; AX=size of TPA in paragraphs | ||
| 221 | PUSH BX | ||
| 222 | MOV BX,16 | ||
| 223 | MUL BX ; DX:AX=size of TPA in bytes | ||
| 224 | POP BX | ||
| 225 | OR DX,DX ; See if over 64K | ||
| 226 | JZ SAVSIZ ; OK if not | ||
| 227 | MOV AX,-1 ; If so, limit to 65535 bytes | ||
| 228 | |||
| 229 | SAVSIZ: | ||
| 230 | ; | ||
| 231 | ; AX is the number of bytes free in the buffer between the resident and the | ||
| 232 | ; transient with a maximum of 64K-1. We round this down to a multiple of 512. | ||
| 233 | ; | ||
| 234 | CMP AX,512 | ||
| 235 | JBE GotSize | ||
| 236 | AND AX,0FE00h ; NOT 511 = NOT 1FF | ||
| 237 | |||
| 238 | GotSize: | ||
| 239 | MOV [BYTCNT],AX ; Max no. of bytes that can be buffered | ||
| 240 | MOV DS,[RESSEG] ; All batch work must use resident seg. | ||
| 241 | ASSUME DS:RESGROUP | ||
| 242 | |||
| 243 | TEST [ECHOFLAG],1 | ||
| 244 | JZ GETCOM ; Don't do the CRLF | ||
| 245 | INVOKE SINGLETEST | ||
| 246 | JB GETCOM | ||
| 247 | TEST [PIPEFLAG],-1 | ||
| 248 | JNZ GETCOM | ||
| 249 | TEST [FORFLAG],-1 ; G Don't print prompt in FOR | ||
| 250 | JNZ GETCOM ; G | ||
| 251 | TEST [BATCH], -1 ; G Don't print prompt if in batch | ||
| 252 | JNZ GETCOM ; G | ||
| 253 | INVOKE CRLF2 | ||
| 254 | |||
| 255 | GETCOM: | ||
| 256 | MOV CALL_FLAG,0 ; G Reset call flags | ||
| 257 | MOV CALL_BATCH_FLAG,0 ; G | ||
| 258 | MOV AH,GET_DEFAULT_DRIVE | ||
| 259 | INT int_command | ||
| 260 | MOV [CURDRV],AL | ||
| 261 | TEST [PIPEFLAG],-1 ; Pipe has highest presedence | ||
| 262 | JZ NOPIPE | ||
| 263 | JMP PIPEPROC ; Continue the pipeline | ||
| 264 | |||
| 265 | NOPIPE: | ||
| 266 | TEST [ECHOFLAG],1 | ||
| 267 | JZ NOPDRV ; No prompt if echo off | ||
| 268 | INVOKE SINGLETEST | ||
| 269 | JB NOPDRV | ||
| 270 | TEST [FORFLAG],-1 ; G Don't print prompt in FOR | ||
| 271 | JNZ NOPDRV ; G | ||
| 272 | TEST [BATCH], -1 ; G Don't print prompt if in batch | ||
| 273 | JNZ TESTFORBAT ; G | ||
| 274 | INVOKE PRINT_PROMPT ; Prompt the user | ||
| 275 | |||
| 276 | NOPDRV: | ||
| 277 | TEST [FORFLAG],-1 ; FOR has next highest precedence | ||
| 278 | JZ TESTFORbat | ||
| 279 | JMP FORPROC ; Continue the FOR | ||
| 280 | |||
| 281 | TESTFORBAT: | ||
| 282 | MOV [RE_INSTR],0 ; Turn redirection back off | ||
| 283 | MOV [RE_OUTSTR],0 | ||
| 284 | MOV [RE_OUT_APP],0 | ||
| 285 | MOV IFFlag,0 ; no more ifs... | ||
| 286 | TEST [BATCH],-1 ; Batch has lowest precedence | ||
| 287 | JZ ISNOBAT | ||
| 288 | |||
| 289 | push es ;AN000; save ES | ||
| 290 | push ds ;AN000; save DS | ||
| 291 | mov ax,mult_shell_get ;AN000; check to see if SHELL has command | ||
| 292 | mov es,[batch] ;AN000; get batch segment | ||
| 293 | mov di,batfile ;AN000; get batch file name | ||
| 294 | push cs ;AN000; get local segment to DS | ||
| 295 | pop ds ;AN000; | ||
| 296 | mov dx,offset trangroup:combuf ;AN000; pass communications buffer | ||
| 297 | int 2fh ;AN000; call the shell | ||
| 298 | cmp al,shell_action ;AN000; does shell have a commmand? | ||
| 299 | pop ds ;AN000; restore DS | ||
| 300 | pop es ;AN000; restore ES | ||
| 301 | jz jdocom1 ;AN000; yes - go process command | ||
| 302 | |||
| 303 | PUSH DS ;G | ||
| 304 | INVOKE READBAT ; Continue BATCH | ||
| 305 | POP DS ;G | ||
| 306 | mov nullflag,0 ;G reset no command flag | ||
| 307 | TEST [BATCH],-1 ;G | ||
| 308 | JNZ JDOCOM1 ;G if batch still in progress continue | ||
| 309 | MOV BX,NEXT_BATCH ;G | ||
| 310 | CMP BX,0 ;G see if there is a new batch file | ||
| 311 | JZ JDOCOM1 ;G no - go do command | ||
| 312 | MOV BATCH,BX ;G get segment of next batch file | ||
| 313 | MOV NEXT_BATCH,0 ;G reset next batch | ||
| 314 | JDOCOM1: | ||
| 315 | PUSH CS ;G | ||
| 316 | POP DS ;G | ||
| 317 | JMP SHORT DoCom1 ; echoing already done | ||
| 318 | |||
| 319 | ISNOBAT: | ||
| 320 | CMP [SINGLECOM],0 | ||
| 321 | JZ REGCOM | ||
| 322 | MOV SI,-1 | ||
| 323 | XCHG SI,[SINGLECOM] | ||
| 324 | MOV DI,OFFSET TRANGROUP:COMBUF + 2 | ||
| 325 | XOR CX,CX | ||
| 326 | |||
| 327 | SINGLELOOP: | ||
| 328 | LODSB | ||
| 329 | STOSB | ||
| 330 | INC CX | ||
| 331 | CMP AL,0DH | ||
| 332 | JNZ SINGLELOOP | ||
| 333 | DEC CX | ||
| 334 | PUSH CS | ||
| 335 | POP DS | ||
| 336 | ASSUME DS:TRANGROUP | ||
| 337 | MOV [COMBUF + 1],CL | ||
| 338 | ; | ||
| 339 | ; do NOT issue a trailing CRLF... | ||
| 340 | ; | ||
| 341 | JMP DOCOM1 | ||
| 342 | |||
| 343 | ; | ||
| 344 | ; We have a normal command. | ||
| 345 | ; Printers are a bizarre quantity. Sometimes they are a stream and | ||
| 346 | ; sometimes they aren't. At this point, we automatically close all spool | ||
| 347 | ; files and turn on truncation mode. | ||
| 348 | ; | ||
| 349 | |||
| 350 | REGCOM: | ||
| 351 | MOV AX,(ServerCall SHL 8) + 9 | ||
| 352 | INT 21h | ||
| 353 | MOV AX,(ServerCall SHL 8) + 8 | ||
| 354 | MOV DL,1 | ||
| 355 | INT 21h | ||
| 356 | |||
| 357 | PUSH CS | ||
| 358 | POP DS ; Need local segment to point to buffer | ||
| 359 | MOV DX,OFFSET TRANGROUP:UCOMBUF | ||
| 360 | MOV AH,STD_CON_STRING_INPUT | ||
| 361 | INT int_command ; Get a command | ||
| 362 | MOV CL,[UCOMBUF] | ||
| 363 | XOR CH,CH | ||
| 364 | ADD CX,3 | ||
| 365 | MOV SI,OFFSET TRANGROUP:UCOMBUF | ||
| 366 | MOV DI,OFFSET TRANGROUP:COMBUF | ||
| 367 | REP MOVSB ; Transfer it to the cooked buffer | ||
| 368 | |||
| 369 | ;--------------- | ||
| 370 | |||
| 371 | transpace segment | ||
| 372 | extrn arg:byte ; the arg structure! | ||
| 373 | transpace ends | ||
| 374 | ;--------------- | ||
| 375 | |||
| 376 | |||
| 377 | DOCOM: | ||
| 378 | INVOKE CRLF2 | ||
| 379 | |||
| 380 | DOCOM1: | ||
| 381 | INVOKE PRESCAN ; Cook the input buffer | ||
| 382 | JZ NOPIPEPROC | ||
| 383 | JMP PIPEPROCSTRT ; Fire up the pipe | ||
| 384 | |||
| 385 | nullcomj: | ||
| 386 | jmp nullcom | ||
| 387 | |||
| 388 | NOPIPEPROC: | ||
| 389 | invoke parseline | ||
| 390 | jnc OkParse ; user error? or maybe we goofed? | ||
| 391 | |||
| 392 | BadParse: | ||
| 393 | PUSH CS | ||
| 394 | POP DS | ||
| 395 | MOV DX,OFFSET TRANGROUP:BADNAM_ptr | ||
| 396 | INVOKE std_eprintf | ||
| 397 | JMP TCOMMAND | ||
| 398 | |||
| 399 | OkParse: | ||
| 400 | test arg.argv[0].argflags, MASK wildcard | ||
| 401 | jnz BadParse ; ambiguous commands not allowed | ||
| 402 | cmp arg.argvcnt, 0 ; there WAS a command, wasn't there? | ||
| 403 | jz nullcomj | ||
| 404 | cmp arg.argv[0].arglen, 0 ; probably an unnecessary check... | ||
| 405 | jz nullcomj ; guarantees argv[0] at least x<NULL> | ||
| 406 | |||
| 407 | MOV SI,OFFSET TRANGROUP:COMBUF+2 | ||
| 408 | MOV DI,OFFSET TRANGROUP:IDLEN | ||
| 409 | MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H ; Make FCB with blank scan-off | ||
| 410 | INT int_command | ||
| 411 | mov BX, arg.argv[0].argpointer | ||
| 412 | cmp BYTE PTR [BX+1],':' ; was a drive specified? | ||
| 413 | jne short drvgd ; no, use default of zero... | ||
| 414 | |||
| 415 | mov DL, BYTE PTR [BX] ; pick-up drive letter | ||
| 416 | and DL, NOT 20H ; uppercase the sucker | ||
| 417 | sub DL, capital_A ; convert it to a drive number, A=0 | ||
| 418 | |||
| 419 | CMP AL,-1 ; See what PARSE said about our drive letter. | ||
| 420 | JZ drvbadj2 ; It was invalid. | ||
| 421 | |||
| 422 | mov DI, arg.argv[0].argstartel | ||
| 423 | cmp BYTE PTR [DI], 0 ; is there actually a command there? | ||
| 424 | jnz drvgd ; if not, we have: "d:", "d:\", "d:/" | ||
| 425 | jmp setdrv ; and set drive to new drive spec | ||
| 426 | |||
| 427 | drvbadj2: | ||
| 428 | jmp drvbad | ||
| 429 | |||
| 430 | DRVGD: | ||
| 431 | MOV AL,[DI] | ||
| 432 | MOV [SPECDRV],AL | ||
| 433 | MOV AL,' ' | ||
| 434 | MOV CX,9 | ||
| 435 | INC DI | ||
| 436 | REPNE SCASB ; Count no. of letters in command name | ||
| 437 | MOV AL,8 | ||
| 438 | SUB AL,CL | ||
| 439 | MOV [IDLEN],AL ; IDLEN is truly the length | ||
| 440 | MOV DI,81H | ||
| 441 | PUSH SI | ||
| 442 | |||
| 443 | mov si, OFFSET TRANGROUP:COMBUF+2 ; Skip over all leading delims | ||
| 444 | invoke scanoff | ||
| 445 | |||
| 446 | do_skipcom: | ||
| 447 | lodsb ; move command line pointer over | ||
| 448 | invoke delim ; pathname -- have to do it ourselves | ||
| 449 | jz do_skipped ; 'cause parse_file_descriptor is dumb | ||
| 450 | cmp AL, 0DH ; can't always depend on argv[0].arglen | ||
| 451 | jz do_skipped ; to be the same length as the user- | ||
| 452 | cmp AL, [SWITCHAR] ; specified command string | ||
| 453 | jnz do_skipcom | ||
| 454 | |||
| 455 | do_skipped: | ||
| 456 | dec SI | ||
| 457 | XOR CX,CX | ||
| 458 | |||
| 459 | COMTAIL: | ||
| 460 | LODSB | ||
| 461 | STOSB ; Move command tail to 80H | ||
| 462 | CMP AL,13 | ||
| 463 | LOOPNZ COMTAIL | ||
| 464 | DEC DI | ||
| 465 | MOV BP,DI | ||
| 466 | NOT CL | ||
| 467 | MOV BYTE PTR DS:[80H],CL | ||
| 468 | POP SI | ||
| 469 | |||
| 470 | ;----- | ||
| 471 | ; Some of these comments are sadly at odds with this brave new code. | ||
| 472 | ;----- | ||
| 473 | ; If the command has 0 parameters must check here for | ||
| 474 | ; any switches that might be present. | ||
| 475 | ; SI -> first character after the command. | ||
| 476 | |||
| 477 | mov DI, arg.argv[0].argsw_word | ||
| 478 | mov [COMSW], DI ; ah yes, the old addressing mode problem... | ||
| 479 | mov SI, arg.argv[1 * SIZE argv_ele].argpointer ; s = argv[1]; | ||
| 480 | OR SI,SI ; if (s == NULL) | ||
| 481 | JNZ DoParse | ||
| 482 | MOV SI,BP ; s = bp; (buffer end) | ||
| 483 | |||
| 484 | DoParse: | ||
| 485 | MOV DI,FCB | ||
| 486 | MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H | ||
| 487 | INT int_command | ||
| 488 | MOV [PARM1],AL ; Save result of parse | ||
| 489 | |||
| 490 | mov DI, arg.argv[1*SIZE argv_ele].argsw_word | ||
| 491 | mov [ARG1S], DI | ||
| 492 | mov SI, arg.argv[2*SIZE argv_ele].argpointer ; s = argv[2]; | ||
| 493 | OR SI,SI ; if (s == NULL) | ||
| 494 | JNZ DoParse2 | ||
| 495 | MOV SI,BP ; s = bp; (bufend)1 | ||
| 496 | |||
| 497 | DoParse2: | ||
| 498 | MOV DI,FCB+10H | ||
| 499 | MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H | ||
| 500 | INT int_command ; Parse file name | ||
| 501 | MOV [PARM2],AL ; Save result | ||
| 502 | |||
| 503 | mov DI, arg.argv[2*SIZE argv_ele].argsw_word | ||
| 504 | mov [ARG2S], DI | ||
| 505 | mov DI, arg.argv[0].argsw_word | ||
| 506 | not DI ; ARGTS doesn't include the flags | ||
| 507 | and DI, arg.argswinfo ; from COMSW... | ||
| 508 | mov [ARGTS], DI | ||
| 509 | |||
| 510 | MOV AL,[IDLEN] | ||
| 511 | MOV DL,[SPECDRV] | ||
| 512 | or DL, DL ; if a drive was specified... | ||
| 513 | jnz externalj1 ; it MUST be external, by this time | ||
| 514 | dec al ; (I don't know why -- old code did it) | ||
| 515 | jmp fndcom ; otherwise, check internal com table | ||
| 516 | |||
| 517 | externalj1: | ||
| 518 | jmp external | ||
| 519 | |||
| 520 | nullcom: | ||
| 521 | MOV DS,[RESSEG] | ||
| 522 | ASSUME DS:RESGROUP | ||
| 523 | TEST [BATCH], -1 ;G Are we in a batch file? | ||
| 524 | JZ nosetflag ;G only set flag if in batch | ||
| 525 | mov nullflag,nullcommand ;G set flag to indicate no command | ||
| 526 | |||
| 527 | nosetflag: | ||
| 528 | CMP [SINGLECOM],-1 | ||
| 529 | JZ EXITJ | ||
| 530 | JMP GETCOM | ||
| 531 | |||
| 532 | EXITJ: | ||
| 533 | JMP $EXITPREP | ||
| 534 | |||
| 535 | IF IBM | ||
| 536 | include mshalo.asm | ||
| 537 | ENDIF | ||
| 538 | |||
| 539 | TRANCODE ENDS | ||
| 540 | END | ||
diff --git a/v4.0/src/CMD/COMMAND/TDATA.ASM b/v4.0/src/CMD/COMMAND/TDATA.ASM new file mode 100644 index 0000000..c80c588 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/TDATA.ASM | |||
| @@ -0,0 +1,777 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)tdata.asm 4.3 85/05/17 | ||
| 3 | ; SCCSID = @(#)tdata.asm 4.3 85/05/17 | ||
| 4 | TITLE COMMAND Transient Initialized DATA | ||
| 5 | |||
| 6 | ; MODIFICATION HISTORY | ||
| 7 | ; | ||
| 8 | ; EE 10-20-83 Changed the drive check indicator bytes (DCIB's) in | ||
| 9 | ; COMTAB to be a flag byte in which bit 0 is now the | ||
| 10 | ; DCIB(bit) and bit 1 is on if the command can take | ||
| 11 | ; switches. | ||
| 12 | |||
| 13 | fmt macro name,string,args | ||
| 14 | local a | ||
| 15 | a db string | ||
| 16 | PUBLIC name | ||
| 17 | name dw offset trangroup:a | ||
| 18 | irp val,<args> | ||
| 19 | dw offset trangroup:val | ||
| 20 | endm | ||
| 21 | endm | ||
| 22 | |||
| 23 | btab macro b,sym | ||
| 24 | db b | ||
| 25 | dw offset trangroup:sym | ||
| 26 | endm | ||
| 27 | |||
| 28 | .xlist | ||
| 29 | .xcref | ||
| 30 | INCLUDE comsw.asm ;AC000; | ||
| 31 | INCLUDE comseg.asm | ||
| 32 | INCLUDE EA.inc ;AN030; | ||
| 33 | INCLUDE dirent.inc ;AN042; | ||
| 34 | .list | ||
| 35 | .cref | ||
| 36 | |||
| 37 | BREAK MACRO subtitle | ||
| 38 | SUBTTL subtitle | ||
| 39 | PAGE | ||
| 40 | ENDM | ||
| 41 | |||
| 42 | ; | ||
| 43 | ; WARNING: DO NOT INCLUDE DOSSYM.INC BECAUSE IT DESTROYS THE MACRO 'FMT' THAT | ||
| 44 | ; has been defined above - RS. | ||
| 45 | ; | ||
| 46 | INCLUDE CURDIR.INC | ||
| 47 | INCLUDE ERROR.INC | ||
| 48 | INCLUDE ifequ.asm | ||
| 49 | INCLUDE comequ.asm | ||
| 50 | |||
| 51 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 52 | EXTRN arg_buf:BYTE | ||
| 53 | EXTRN bwdbuf:byte | ||
| 54 | EXTRN bytes_free:WORD | ||
| 55 | EXTRN charbuf:byte | ||
| 56 | EXTRN copy_Num:WORD | ||
| 57 | EXTRN cpyflag:BYTE | ||
| 58 | EXTRN DATE_OUTPUT:BYTE ;AC000; | ||
| 59 | EXTRN Dir_Num:WORD | ||
| 60 | EXTRN DRIVE_OUTPUT:BYTE ;AC000; | ||
| 61 | EXTRN file_size_high:WORD | ||
| 62 | EXTRN file_size_low:WORD | ||
| 63 | EXTRN major_ver_num:WORD | ||
| 64 | EXTRN minor_ver_num:WORD | ||
| 65 | EXTRN one_char_val:BYTE | ||
| 66 | EXTRN PARSE1_OUTPUT:BYTE ;AC000; | ||
| 67 | EXTRN srcbuf:byte | ||
| 68 | EXTRN string_ptr_2:WORD | ||
| 69 | EXTRN system_cpage:word | ||
| 70 | EXTRN TIME_OUTPUT:BYTE ;AC000; | ||
| 71 | EXTRN vol_drv:BYTE | ||
| 72 | EXTRN vol_serial:dword ;AN000; | ||
| 73 | TRANSPACE ENDS | ||
| 74 | |||
| 75 | TRANCODE SEGMENT PUBLIC BYTE ;AC000; | ||
| 76 | EXTRN $CALL:NEAR | ||
| 77 | EXTRN $CHDIR:NEAR | ||
| 78 | EXTRN $EXIT:NEAR | ||
| 79 | EXTRN $FOR:NEAR | ||
| 80 | EXTRN $IF:NEAR | ||
| 81 | EXTRN $MKDIR:NEAR | ||
| 82 | EXTRN $RMDIR:NEAR | ||
| 83 | EXTRN ADD_NAME_TO_ENVIRONMENT:NEAR | ||
| 84 | EXTRN ADD_PROMPT:NEAR | ||
| 85 | EXTRN build_dir_for_prompt:near | ||
| 86 | EXTRN CATALOG:NEAR | ||
| 87 | EXTRN CHCP:NEAR | ||
| 88 | EXTRN CLS:NEAR | ||
| 89 | EXTRN CNTRLC:NEAR | ||
| 90 | EXTRN COPY:NEAR | ||
| 91 | EXTRN CRENAME:NEAR | ||
| 92 | EXTRN CRLF2:NEAR | ||
| 93 | EXTRN CTIME:NEAR | ||
| 94 | EXTRN CTTY:NEAR | ||
| 95 | EXTRN DATE:NEAR | ||
| 96 | EXTRN ECHO:NEAR | ||
| 97 | EXTRN ERASE:NEAR | ||
| 98 | EXTRN GOTO:NEAR | ||
| 99 | EXTRN IFERLEV:NEAR | ||
| 100 | EXTRN IFEXISTS:NEAR | ||
| 101 | EXTRN IFNOT:NEAR | ||
| 102 | EXTRN PATH:NEAR | ||
| 103 | EXTRN PAUSE:NEAR | ||
| 104 | EXTRN PRINT_B:NEAR | ||
| 105 | EXTRN PRINT_BACK:NEAR | ||
| 106 | EXTRN PRINT_DATE:NEAR | ||
| 107 | EXTRN PRINT_CHAR:NEAR | ||
| 108 | EXTRN PRINT_DRIVE:NEAR | ||
| 109 | EXTRN PRINT_EQ:NEAR | ||
| 110 | EXTRN PRINT_ESC:NEAR | ||
| 111 | EXTRN PRINT_G:NEAR | ||
| 112 | EXTRN PRINT_L:NEAR | ||
| 113 | EXTRN PRINT_TIME:NEAR | ||
| 114 | EXTRN PRINT_VERSION:NEAR | ||
| 115 | EXTRN SHIFT:NEAR | ||
| 116 | EXTRN TCOMMAND:NEAR | ||
| 117 | EXTRN TRUENAME:NEAR ;AN000; | ||
| 118 | EXTRN TYPEFIL:NEAR | ||
| 119 | EXTRN VERSION:NEAR | ||
| 120 | EXTRN VOLUME:NEAR | ||
| 121 | EXTRN VERIFY:NEAR | ||
| 122 | ; | ||
| 123 | ; WARNING!!! No code may appear after this label!!!! | ||
| 124 | ; | ||
| 125 | PUBLIC TranCodeLast | ||
| 126 | TranCodeLast LABEL BYTE | ||
| 127 | TRANCODE ENDS | ||
| 128 | |||
| 129 | ; Data for transient portion | ||
| 130 | |||
| 131 | TRANDATA SEGMENT PUBLIC BYTE | ||
| 132 | |||
| 133 | PUBLIC accden_ptr ;AN000; | ||
| 134 | PUBLIC acrlf_ptr ;AN000; | ||
| 135 | PUBLIC arg_buf_ptr ;AN000; | ||
| 136 | PUBLIC badbat_ptr ;AN000; | ||
| 137 | PUBLIC badcd_ptr ;AN000; | ||
| 138 | PUBLIC badCPmes_ptr ;AN000; | ||
| 139 | PUBLIC badcurdrv ;AN000; | ||
| 140 | PUBLIC baddat_ptr ;AN000; | ||
| 141 | PUBLIC baddev_ptr ;AN000; | ||
| 142 | PUBLIC baddrv_ptr ;AN000; | ||
| 143 | PUBLIC badlab_ptr ;AN000; | ||
| 144 | PUBLIC badmkd_ptr ;AN000; | ||
| 145 | PUBLIC badnam_ptr ;AN000; | ||
| 146 | PUBLIC bad_on_off_ptr ;AN000; | ||
| 147 | PUBLIC badPmes_ptr ;AN000; | ||
| 148 | PUBLIC badrmd_ptr ;AN000; | ||
| 149 | PUBLIC badtim_ptr ;AN000; | ||
| 150 | PUBLIC batext | ||
| 151 | PUBLIC bytmes_ptr ;AN000; | ||
| 152 | PUBLIC CLSSTRING | ||
| 153 | PUBLIC comext | ||
| 154 | PUBLIC COMSPECSTR | ||
| 155 | PUBLIC COMTAB | ||
| 156 | PUBLIC copied_ptr ;AN000; | ||
| 157 | PUBLIC cp_active_ptr ;AN000; | ||
| 158 | PUBLIC cp_not_all_ptr ;AN000; | ||
| 159 | PUBLIC cp_not_set_ptr ;AN000; | ||
| 160 | PUBLIC ctrlcmes_ptr ;AN000; | ||
| 161 | PUBLIC curdat_mo_day ;AN000; | ||
| 162 | PUBLIC curdat_ptr ;AN000; | ||
| 163 | PUBLIC curdat_yr ;AN000; | ||
| 164 | PUBLIC curtim_hr_min ;AN000; | ||
| 165 | PUBLIC curtim_ptr ;AN000; | ||
| 166 | PUBLIC curtim_sec_hn ;AN000; | ||
| 167 | PUBLIC dback_ptr ;AN000; | ||
| 168 | PUBLIC del_Y_N_ptr ;AN000; | ||
| 169 | PUBLIC devwmes_ptr ;AN000; | ||
| 170 | PUBLIC dirdattim_ptr ;AN000; | ||
| 171 | PUBLIC dirdat_mo_day ;AN000; | ||
| 172 | PUBLIC dirdat_yr ;AN000; | ||
| 173 | PUBLIC dirhead_ptr ;AN000; | ||
| 174 | PUBLIC dirmes_ptr ;AN000; | ||
| 175 | PUBLIC dirtim_hr_min ;AN000; | ||
| 176 | PUBLIC dirtim_sec_hn ;AN000; | ||
| 177 | PUBLIC DIR_W_SYN ;AN000; | ||
| 178 | PUBLIC disp_file_size_ptr ;AN000; | ||
| 179 | PUBLIC dmes_ptr ;AN000; | ||
| 180 | PUBLIC echomes_ptr ;AN000; | ||
| 181 | PUBLIC enverr_ptr ;AN000; | ||
| 182 | PUBLIC eurdat_ptr ;AN000; | ||
| 183 | PUBLIC exeext | ||
| 184 | PUBLIC extend_buf_off ;AN000; | ||
| 185 | PUBLIC extend_buf_ptr ;AN000; | ||
| 186 | PUBLIC extend_buf_seg ;AN000; | ||
| 187 | PUBLIC extend_buf_sub ;AN000; | ||
| 188 | PUBLIC file_name_ptr ;AN000; | ||
| 189 | PUBLIC fornestmes_ptr ;AN000; | ||
| 190 | PUBLIC fuldir_ptr ;AN000; | ||
| 191 | PUBLIC IFTAB | ||
| 192 | PUBLIC inBdev_ptr ;AN000; | ||
| 193 | PUBLIC inornot_ptr ;AN000; | ||
| 194 | PUBLIC Inv_code_page ;AN000; | ||
| 195 | PUBLIC inval_path_ptr ;AN000; | ||
| 196 | PUBLIC japdat_ptr ;AN000; | ||
| 197 | PUBLIC Losterr_ptr ;AN000; | ||
| 198 | PUBLIC md_exists_ptr ;AN006; | ||
| 199 | PUBLIC msg_cont_flag ;AN000; | ||
| 200 | PUBLIC msg_disp_class ;AN000; | ||
| 201 | PUBLIC needbat_ptr ;AN000; | ||
| 202 | PUBLIC newdat_format ;AN000; | ||
| 203 | PUBLIC newdat_ptr ;AN000; | ||
| 204 | PUBLIC newtim_ptr ;AN000; | ||
| 205 | PUBLIC NLSFUNC_ptr ;AN000; | ||
| 206 | PUBLIC nospace_ptr ;AN000; | ||
| 207 | PUBLIC no_values ;AN000; | ||
| 208 | PUBLIC nulpath_ptr ;AN000; | ||
| 209 | PUBLIC offmes_ptr ;AN000; | ||
| 210 | PUBLIC onmes_ptr ;AN000; | ||
| 211 | PUBLIC overwr_ptr ;AN000; | ||
| 212 | PUBLIC PARSE_BREAK ;AN000; | ||
| 213 | PUBLIC PARSE_CHCP ;AN000; | ||
| 214 | PUBLIC PARSE_CHDIR ;AN000; | ||
| 215 | PUBLIC PARSE_CTTY ;AN000; | ||
| 216 | PUBLIC PARSE_DATE ;AN000; | ||
| 217 | PUBLIC PARSE_DIR ;AN000; | ||
| 218 | PUBLIC PARSE_ERASE ;AN000; | ||
| 219 | PUBLIC PARSE_MRDIR ;AN000; | ||
| 220 | PUBLIC PARSE_RENAME ;AN000; | ||
| 221 | PUBLIC PARSE_TIME ;AN000; | ||
| 222 | PUBLIC PARSE_VOL ;AN000; | ||
| 223 | PUBLIC PATH_TEXT | ||
| 224 | PUBLIC pausemes_ptr ;AN000; | ||
| 225 | PUBLIC pipeEmes_ptr ;AN000; | ||
| 226 | PUBLIC promptdat_moday ;AN000; | ||
| 227 | PUBLIC promptdat_ptr ;AN000; | ||
| 228 | PUBLIC promptdat_yr ;AN000; | ||
| 229 | PUBLIC PROMPT_TABLE | ||
| 230 | PUBLIC PROMPT_TEXT | ||
| 231 | PUBLIC promtim_hr_min ;AN000; | ||
| 232 | PUBLIC promtim_ptr ;AN000; | ||
| 233 | PUBLIC promtim_sec_hn ;AN000; | ||
| 234 | PUBLIC renerr_ptr ;AN000; | ||
| 235 | PUBLIC SLASH_P_SYN ;AN000; | ||
| 236 | PUBLIC string_buf_ptr ;AN000; | ||
| 237 | PUBLIC suremes_ptr ;AN000; | ||
| 238 | PUBLIC switch_list | ||
| 239 | PUBLIC syntmes_ptr ;AN000; | ||
| 240 | PUBLIC tab_ptr ;AN000; | ||
| 241 | PUBLIC TRANDATAEND | ||
| 242 | PUBLIC usadat_ptr ;AN000; | ||
| 243 | PUBLIC verimes_ptr ;AN000; | ||
| 244 | PUBLIC vermes_ptr ;AN000; | ||
| 245 | PUBLIC volmes_ptr ;AN000; | ||
| 246 | PUBLIC volmes_ptr_2 ;AN000; | ||
| 247 | PUBLIC volsermes_ptr ;AN000; | ||
| 248 | PUBLIC WEEKTAB | ||
| 249 | PUBLIC xa_cp ;AN030; | ||
| 250 | |||
| 251 | INCLUDE tranmsg.asm | ||
| 252 | |||
| 253 | CLSSTRING DB 4,01BH,"[2J" ; ANSI Clear screen | ||
| 254 | |||
| 255 | PROMPT_TABLE LABEL BYTE | ||
| 256 | btab "B",Print_B | ||
| 257 | btab "D",PRINT_DATE | ||
| 258 | btab "E",PRINT_ESC | ||
| 259 | btab "G",PRINT_G | ||
| 260 | btab "H",PRINT_BACK | ||
| 261 | btab "L",PRINT_L | ||
| 262 | btab "N",PRINT_DRIVE | ||
| 263 | btab "P",build_dir_for_prompt | ||
| 264 | btab "Q",PRINT_EQ | ||
| 265 | btab "T",PRINT_TIME | ||
| 266 | btab "V",PRINT_VERSION | ||
| 267 | btab "_",CRLF2 | ||
| 268 | btab "$",PRINT_CHAR | ||
| 269 | DB 0 ; NUL TERMINATED | ||
| 270 | |||
| 271 | IFTAB LABEL BYTE ; Table of IF conditionals | ||
| 272 | DB 3,"NOT" ; First byte is count | ||
| 273 | DW OFFSET TRANGROUP:IFNOT | ||
| 274 | DB 10,"ERRORLEVEL" | ||
| 275 | DW OFFSET TRANGROUP:IFERLEV | ||
| 276 | DB 5,"EXIST" | ||
| 277 | DW OFFSET TRANGROUP:IFEXISTS | ||
| 278 | DB 0 | ||
| 279 | |||
| 280 | ; Table for internal command names | ||
| 281 | COMTAB DB 3,"DIR",fSwitchAllowed+fCheckDrive | ||
| 282 | DW OFFSET TRANGROUP:CATALOG ; In TCMD1.ASM | ||
| 283 | DB 4,"CALL",fSwitchAllowed | ||
| 284 | DW OFFSET TRANGROUP:$CALL ; In TBATCH2.ASM | ||
| 285 | DB 4,"CHCP",fSwitchAllowed | ||
| 286 | DW OFFSET TRANGROUP:CHCP ; In TCMD2B.ASM | ||
| 287 | DB 6,"RENAME",fSwitchAllowed+fCheckDrive ;AC018; P3903 | ||
| 288 | DW OFFSET TRANGROUP:CRENAME ; In TCMD1.ASM | ||
| 289 | DB 3,"REN",fSwitchAllowed+fCheckDrive ;AC018; P3903 | ||
| 290 | DW OFFSET TRANGROUP:CRENAME ; In TCMD1.ASM | ||
| 291 | DB 5,"ERASE",fSwitchAllowed+fCheckDrive | ||
| 292 | DW OFFSET TRANGROUP:ERASE ; In TCMD1.ASM | ||
| 293 | DB 3,"DEL",fSwitchAllowed+fCheckDrive | ||
| 294 | DW OFFSET TRANGROUP:ERASE ; In TCMD1.ASM | ||
| 295 | DB 4,"TYPE",fSwitchAllowed+fCheckDrive ;AC018; P3903 | ||
| 296 | DW OFFSET TRANGROUP:TYPEFIL ; In TCMD1.ASM | ||
| 297 | DB 3,"REM",fSwitchAllowed | ||
| 298 | DW OFFSET TRANGROUP:TCOMMAND ; In TCODE.ASM | ||
| 299 | DB 4,"COPY",fSwitchAllowed+fCheckDrive | ||
| 300 | DW OFFSET TRANGROUP:COPY ; In COPY.ASM | ||
| 301 | DB 5,"PAUSE",fSwitchAllowed | ||
| 302 | DW OFFSET TRANGROUP:PAUSE ; In TCMD1.ASM | ||
| 303 | DB 4,"DATE",fSwitchAllowed | ||
| 304 | DW OFFSET TRANGROUP:DATE ; In TPIPE.ASM | ||
| 305 | DB 4,"TIME",fSwitchAllowed ;AC018; P3903 | ||
| 306 | DW OFFSET TRANGROUP:CTIME ; In TPIPE.ASM | ||
| 307 | DB 3,"VER",0 | ||
| 308 | DW OFFSET TRANGROUP:VERSION ; In TCMD2.ASM | ||
| 309 | DB 3,"VOL",fSwitchAllowed+fCheckDrive ;AC018; P3903 | ||
| 310 | DW OFFSET TRANGROUP:VOLUME ; In TCMD1.ASM | ||
| 311 | DB 2,"CD",fSwitchAllowed+fCheckDrive ;AC018; P3903 | ||
| 312 | DW OFFSET TRANGROUP:$CHDIR ; In TENV.ASM | ||
| 313 | DB 5,"CHDIR",fSwitchAllowed+fCheckDrive ;AC018; P3903 | ||
| 314 | DW OFFSET TRANGROUP:$CHDIR ; In TENV.ASM | ||
| 315 | DB 2,"MD",fSwitchAllowed+fCheckDrive ;AC018; P3903 | ||
| 316 | DW OFFSET TRANGROUP:$MKDIR ; In TENV.ASM | ||
| 317 | DB 5,"MKDIR",fSwitchAllowed+fCheckDrive ;AC018; P3903 | ||
| 318 | DW OFFSET TRANGROUP:$MKDIR ; In TENV.ASM | ||
| 319 | DB 2,"RD",fSwitchAllowed+fCheckDrive ;AC018; P3903 | ||
| 320 | DW OFFSET TRANGROUP:$RMDIR ; In TENV.ASM | ||
| 321 | DB 5,"RMDIR",fSwitchAllowed+fCheckDrive ;AC018; P3903 | ||
| 322 | DW OFFSET TRANGROUP:$RMDIR ; In TENV.ASM | ||
| 323 | DB 5,"BREAK",fSwitchAllowed ;AC018; P3903 | ||
| 324 | DW OFFSET TRANGROUP:CNTRLC ; In TUCODE.ASM | ||
| 325 | DB 6,"VERIFY",fSwitchAllowed ;AC018; P3903 | ||
| 326 | DW OFFSET TRANGROUP:VERIFY ; In TUCODE.ASM | ||
| 327 | DB 3,"SET",fSwitchAllowed | ||
| 328 | DW OFFSET TRANGROUP:ADD_NAME_TO_ENVIRONMENT; In TENV.ASM | ||
| 329 | DB 6,"PROMPT",fSwitchAllowed | ||
| 330 | DW OFFSET TRANGROUP:ADD_PROMPT ; In TENV.ASM | ||
| 331 | DB 4,"PATH",fSwitchAllowed | ||
| 332 | DW OFFSET TRANGROUP:PATH ; In TCMD2.ASM | ||
| 333 | DB 4,"EXIT",0 | ||
| 334 | DW OFFSET TRANGROUP:$EXIT ; In TCMD2.ASM | ||
| 335 | DB 4,"CTTY",fCheckDrive+fSwitchAllowed | ||
| 336 | DW OFFSET TRANGROUP:CTTY ; In TCMD2.ASM | ||
| 337 | DB 4,"ECHO",fSwitchAllowed | ||
| 338 | DW OFFSET TRANGROUP:ECHO ; In TUCODE.ASM | ||
| 339 | DB 4,"GOTO",fSwitchAllowed | ||
| 340 | DW OFFSET TRANGROUP:GOTO ; In TBATCH.ASM | ||
| 341 | DB 5,"SHIFT",fSwitchAllowed | ||
| 342 | DW OFFSET TRANGROUP:SHIFT ; In TBATCH.ASM | ||
| 343 | DB 2,"IF",fSwitchAllowed | ||
| 344 | DW OFFSET TRANGROUP:$IF ; In TBATCH.ASM | ||
| 345 | DB 3,"FOR",fSwitchAllowed | ||
| 346 | DW OFFSET TRANGROUP:$FOR ; In TBATCH.ASM | ||
| 347 | DB 3,"CLS",0 | ||
| 348 | DW OFFSET TRANGROUP:CLS ; In TCMD2.ASM | ||
| 349 | DB 8,"TRUENAME",fSwitchAllowed+fCheckDrive ;AN000; P3903 changed | ||
| 350 | DW OFFSET TRANGROUP:TRUENAME ;AN000; | ||
| 351 | DB 0 ; Terminate command table | ||
| 352 | |||
| 353 | |||
| 354 | comext dB ".COM" | ||
| 355 | exeext dB ".EXE" | ||
| 356 | batext dB ".BAT" | ||
| 357 | |||
| 358 | switch_list DB "VBAPW" ; flags we can recognize | ||
| 359 | |||
| 360 | |||
| 361 | XA_cp Label byte ;AN030; list for one extended attribute | ||
| 362 | DW 1 ;AN030; | ||
| 363 | DB EAISBINARY ;AN030; type | ||
| 364 | DW EASYSTEM ;AN030; flags | ||
| 365 | DB 2 ;AN030; name length | ||
| 366 | DB "CP" ;AN030; name | ||
| 367 | |||
| 368 | |||
| 369 | |||
| 370 | |||
| 371 | PUBLIC BatBufLen | ||
| 372 | BatBufLen DW BatLen | ||
| 373 | |||
| 374 | ; ***************************************************** | ||
| 375 | ; EMG 4.00 | ||
| 376 | ; DATA STARTING HERE WAS ADDED BY EMG FOR 4.00 | ||
| 377 | ; FOR IMPLEMENTATION OF COMMON PARSE ROUTINE | ||
| 378 | ; ***************************************************** | ||
| 379 | |||
| 380 | ; | ||
| 381 | ; COMMON PARSE BLOCKS | ||
| 382 | ; | ||
| 383 | |||
| 384 | ; | ||
| 385 | ; Indicates no value list for PARSE. | ||
| 386 | ; | ||
| 387 | |||
| 388 | NO_VALUES DW 0 ;AN000; no values | ||
| 389 | |||
| 390 | ; | ||
| 391 | ; PARSE control block for a required file specification (upper cased) | ||
| 392 | ; | ||
| 393 | |||
| 394 | FILE_REQUIRED LABEL BYTE ;AN000; | ||
| 395 | DW 0200H ;AN000; filespec - required | ||
| 396 | DW 1 ;AN000; capitalize - file table | ||
| 397 | DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer | ||
| 398 | DW TRANGROUP:NO_VALUES ;AN000; | ||
| 399 | DB 0 ;AN000; no keywords | ||
| 400 | |||
| 401 | ; | ||
| 402 | ; PARSE control block for an optional file specification (upper cased) | ||
| 403 | ; or drive number | ||
| 404 | ; | ||
| 405 | |||
| 406 | FILE_OPTIONAL LABEL BYTE ;AN000; | ||
| 407 | DW 0301H ;AN000; filespec or drive number | ||
| 408 | ; optional | ||
| 409 | DW 1 ;AN000; capitalize - file table | ||
| 410 | DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer | ||
| 411 | DW TRANGROUP:NO_VALUES ;AN000; | ||
| 412 | DB 0 ;AN000; no keywords | ||
| 413 | |||
| 414 | ; | ||
| 415 | ; PARSE control block for an optional file specification (upper cased) | ||
| 416 | ; | ||
| 417 | |||
| 418 | FILE_OPTIONAL2 LABEL BYTE ;AN000; | ||
| 419 | DW 0201H ;AN000; filespec or drive number | ||
| 420 | ; optional | ||
| 421 | DW 1 ;AN000; capitalize - file table | ||
| 422 | DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer | ||
| 423 | DW TRANGROUP:NO_VALUES ;AN000; | ||
| 424 | DB 0 ;AN000; no keywords | ||
| 425 | |||
| 426 | ; | ||
| 427 | ; PARSE control block for an optional /P switch | ||
| 428 | ; | ||
| 429 | |||
| 430 | SLASH_P_SWITCH LABEL BYTE ;AN000; | ||
| 431 | DW 0 ;AN000; no match flags | ||
| 432 | DW 2 ;AN000; capitalize - char table | ||
| 433 | DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer | ||
| 434 | DW TRANGROUP:NO_VALUES ;AN000; | ||
| 435 | DB 1 ;AN000; 1 keyword | ||
| 436 | SLASH_P_SYN DB "/P",0 ;AN000; /P switch | ||
| 437 | |||
| 438 | |||
| 439 | |||
| 440 | ; PARSE BLOCK FOR BREAK, VERIFY, ECHO | ||
| 441 | |||
| 442 | ; | ||
| 443 | ; The following parse control block can be used for any command which | ||
| 444 | ; needs only the optional "ON" and "OFF" keywords as operands. Allows | ||
| 445 | ; the equal sign as an additional delimiter. Returns verified result | ||
| 446 | ; in PARSE1_OUTPUT. Currently used for the BREAK, VERIFY, and ECHO | ||
| 447 | ; internal commands. | ||
| 448 | ; | ||
| 449 | |||
| 450 | PARSE_BREAK LABEL BYTE ;AN000; | ||
| 451 | DW TRANGROUP:BREAK_PARMS ;AN000; | ||
| 452 | DB 0 ;AN032; no extra delimiter | ||
| 453 | |||
| 454 | BREAK_PARMS LABEL BYTE ;AN000; | ||
| 455 | DB 0,1 ;AN000; 1 positional parm | ||
| 456 | DW TRANGROUP:BREAK_CONTROL1;AN000; | ||
| 457 | DB 0 ;AN000; no switches | ||
| 458 | DB 0 ;AN000; no keywords | ||
| 459 | |||
| 460 | BREAK_CONTROL1 LABEL BYTE ;AN000; | ||
| 461 | DW 2001H ;AN000; string value - optional | ||
| 462 | DW 2 ;AN000; capitalize - char table | ||
| 463 | DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer | ||
| 464 | DW TRANGROUP:BREAK_VALUES ;AN000; | ||
| 465 | DB 0 ;AN000; no keywords | ||
| 466 | |||
| 467 | BREAK_VALUES LABEL BYTE ;AN000; | ||
| 468 | DB 3 ;AN000; | ||
| 469 | DB 0 ;AN000; no ranges | ||
| 470 | DB 0 ;AN000; no numeric values | ||
| 471 | DB 2 ;AN000; 2 string values | ||
| 472 | DB 0 ;AN000; returned if ON | ||
| 473 | DW TRANGROUP:BREAK_ON ;AN000; point to ON string | ||
| 474 | DB 'f' ;AN000; returned if OFF | ||
| 475 | DW TRANGROUP:BREAK_OFF ;AN000; point to OFF string | ||
| 476 | |||
| 477 | BREAK_ON DB "ON",0 ;AN000; | ||
| 478 | BREAK_OFF DB "OFF",0 ;AN000; | ||
| 479 | |||
| 480 | ; | ||
| 481 | ; PARSE BLOCK FOR CHCP | ||
| 482 | ; | ||
| 483 | |||
| 484 | ; | ||
| 485 | ; The following parse control block can be used for any command which | ||
| 486 | ; needs only one optional three digit decimal parameter for operands. | ||
| 487 | ; Returns verified result in PARSE1_OUTPUT. Currently used for the | ||
| 488 | ; CHCP internal command. | ||
| 489 | ; | ||
| 490 | CHCP_MINVAL EQU 100 ;AN000; | ||
| 491 | CHCP_MAXVAL EQU 999 ;AN000; | ||
| 492 | |||
| 493 | PARSE_CHCP LABEL BYTE ;AN000; | ||
| 494 | DW TRANGROUP:CHCP_PARMS ;AN000; | ||
| 495 | DB 0 ;AN000; no extra delimiter | ||
| 496 | |||
| 497 | CHCP_PARMS LABEL BYTE ;AN000; | ||
| 498 | DB 0,1 ;AN000; 1 positional parm | ||
| 499 | DW TRANGROUP:CHCP_CONTROL1 ;AN000; | ||
| 500 | DB 0 ;AN000; no switches | ||
| 501 | DB 0 ;AN000; no keywords | ||
| 502 | |||
| 503 | CHCP_CONTROL1 LABEL BYTE ;AN000; | ||
| 504 | DW 8001H ;AN000; numeric value - optional | ||
| 505 | DW 0 ;AN000; no function flags | ||
| 506 | DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer | ||
| 507 | DW TRANGROUP:CHCP_VALUES ;AN000; | ||
| 508 | DB 0 ;AN000; no keywords | ||
| 509 | |||
| 510 | CHCP_VALUES LABEL BYTE ;AN000; | ||
| 511 | DB 1 ;AN000; | ||
| 512 | DB 1 ;AN000; 1 range | ||
| 513 | DB 1 ;AN000; returned if result | ||
| 514 | DD CHCP_MINVAL,CHCP_MAXVAL ;AN000; minimum & maximum value | ||
| 515 | DB 0 ;AN000; no numeric values | ||
| 516 | DB 0 ;AN000; no string values | ||
| 517 | |||
| 518 | |||
| 519 | ; | ||
| 520 | ; PARSE BLOCK FOR DATE | ||
| 521 | ; | ||
| 522 | |||
| 523 | ; | ||
| 524 | ; The following parse control block can be used for any command which | ||
| 525 | ; needs only an optional date string as an operand. Returns unverified | ||
| 526 | ; result in DATE_OUTPUT. Currently used for the DATE internal command. | ||
| 527 | ; | ||
| 528 | |||
| 529 | PARSE_DATE LABEL BYTE ;AN000; | ||
| 530 | DW TRANGROUP:DATE_PARMS ;AN000; | ||
| 531 | DB 0 ;AN000; no extra delimiter | ||
| 532 | |||
| 533 | DATE_PARMS LABEL BYTE ;AN000; | ||
| 534 | DB 0,1 ;AN000; 1 positional parm | ||
| 535 | DW TRANGROUP:DATE_CONTROL1 ;AN000; | ||
| 536 | DB 0 ;AN000; no switches | ||
| 537 | DB 0 ;AN000; no keywords | ||
| 538 | |||
| 539 | DATE_CONTROL1 LABEL BYTE ;AN000; | ||
| 540 | DW 1001H ;AN000; date - optional | ||
| 541 | DW 0 ;AN000; no function flags | ||
| 542 | DW TRANGROUP:DATE_OUTPUT ;AN000; result buffer | ||
| 543 | DW TRANGROUP:NO_VALUES ;AN000; | ||
| 544 | DB 0 ;AN000; no keywords | ||
| 545 | |||
| 546 | ; | ||
| 547 | ; PARSE BLOCK FOR TIME | ||
| 548 | ; | ||
| 549 | |||
| 550 | ; | ||
| 551 | ; The following parse control block can be used for any command which | ||
| 552 | ; needs only an optional time string as an operand. Returns unverified | ||
| 553 | ; result in TIME_OUTPUT. Currently used for the TIME internal command. | ||
| 554 | ; | ||
| 555 | |||
| 556 | PARSE_TIME LABEL BYTE ;AN000; | ||
| 557 | DW TRANGROUP:TIME_PARMS ;AN000; | ||
| 558 | DB 0 ;AN000; no extra delimiter | ||
| 559 | |||
| 560 | TIME_PARMS LABEL BYTE ;AN000; | ||
| 561 | DB 0,1 ;AN000; 1 positional parm | ||
| 562 | DW TRANGROUP:TIME_CONTROL1 ;AN000; | ||
| 563 | DB 0 ;AN000; no switches | ||
| 564 | DB 0 ;AN000; no keywords | ||
| 565 | |||
| 566 | TIME_CONTROL1 LABEL BYTE ;AN000; | ||
| 567 | DW 0801H ;AN000; TIME - optional | ||
| 568 | DW 0 ;AN000; no function flags | ||
| 569 | DW TRANGROUP:TIME_OUTPUT ;AN000; result buffer | ||
| 570 | DW TRANGROUP:NO_VALUES ;AN000; | ||
| 571 | DB 0 ;AN000; no keywords | ||
| 572 | |||
| 573 | |||
| 574 | ; | ||
| 575 | ; PARSE BLOCK FOR VOL | ||
| 576 | ; | ||
| 577 | |||
| 578 | ; | ||
| 579 | ; The following parse control block can be used for any command which | ||
| 580 | ; needs only an optional drive letter as an operand. Returns unverified | ||
| 581 | ; drive number (one based) in DRIVE_OUTPUT. Currently used for the VOL | ||
| 582 | ; internal command. | ||
| 583 | ; | ||
| 584 | |||
| 585 | PARSE_VOL LABEL BYTE ;AN000; | ||
| 586 | DW TRANGROUP:VOL_PARMS ;AN000; | ||
| 587 | DB 0 ;AN000; no extra delimiter | ||
| 588 | |||
| 589 | VOL_PARMS LABEL BYTE ;AN000; | ||
| 590 | DB 0,1 ;AN000; 1 positional parm | ||
| 591 | DW TRANGROUP:DRIVE_CONTROL1;AN000; | ||
| 592 | DB 0 ;AN000; no switches | ||
| 593 | DB 0 ;AN000; no keywords | ||
| 594 | |||
| 595 | DRIVE_CONTROL1 LABEL BYTE ;AN000; | ||
| 596 | DW 0101H ;AN000; DRIVE - optional | ||
| 597 | DW 1 ;AN000; capitalize - file table | ||
| 598 | DW TRANGROUP:DRIVE_OUTPUT ;AN000; result buffer | ||
| 599 | DW TRANGROUP:NO_VALUES ;AN000; | ||
| 600 | DB 0 ;AN000; no keywords | ||
| 601 | |||
| 602 | |||
| 603 | ; | ||
| 604 | ; PARSE BLOCK FOR MKDIR, RMDIR, TYPE | ||
| 605 | ; | ||
| 606 | |||
| 607 | ; | ||
| 608 | ; The following parse control block can be used for any command which | ||
| 609 | ; needs only one required file specification as an operand. Returns a | ||
| 610 | ; pointer to the unverified string in PARSE1_OUTPUT. Currently used | ||
| 611 | ; for the MKDIR, RMDIR, and TYPE internal commands. | ||
| 612 | ; | ||
| 613 | |||
| 614 | PARSE_MRDIR LABEL BYTE ;AN000; | ||
| 615 | DW TRANGROUP:MRDIR_PARMS ;AN000; | ||
| 616 | DB 0 ;AN000; no extra delimiter | ||
| 617 | |||
| 618 | MRDIR_PARMS LABEL BYTE ;AN000; | ||
| 619 | DB 1,1 ;AN000; 1 positional parm | ||
| 620 | DW TRANGROUP:FILE_REQUIRED ;AN000; | ||
| 621 | DB 0 ;AN000; no switches | ||
| 622 | DB 0 ;AN000; no keywords | ||
| 623 | |||
| 624 | ; | ||
| 625 | ; PARSE BLOCK FOR CHDIR, TRUENAME | ||
| 626 | ; | ||
| 627 | |||
| 628 | ; | ||
| 629 | ; The following parse control block can be used for any command which | ||
| 630 | ; needs only one optional file specification an operand. Returns a | ||
| 631 | ; pointer to the unverified string in PARSE1_OUTPUT. Currently used | ||
| 632 | ; for the CHDIR and TRUENAME internal commands. | ||
| 633 | ; | ||
| 634 | |||
| 635 | PARSE_CHDIR LABEL BYTE ;AN000; | ||
| 636 | DW TRANGROUP:CHDIR_PARMS ;AN000; | ||
| 637 | DB 0 ;AN000; no extra delimiter | ||
| 638 | |||
| 639 | CHDIR_PARMS LABEL BYTE ;AN000; | ||
| 640 | DB 0,1 ;AN000; 1 positional parm | ||
| 641 | DW TRANGROUP:FILE_OPTIONAL ;AN000; | ||
| 642 | DB 0 ;AN000; no switches | ||
| 643 | DB 0 ;AN000; no keywords | ||
| 644 | |||
| 645 | ; | ||
| 646 | ; PARSE BLOCK FOR ERASE | ||
| 647 | ; | ||
| 648 | |||
| 649 | ; | ||
| 650 | ; The following parse control block is used for the DEL/ERASE internal | ||
| 651 | ; commands. This command has one required file specification and an | ||
| 652 | ; optional switch (/p) as operands. The verified switch or unverified | ||
| 653 | ; file specification is returned in PARSE1_OUTPUT. | ||
| 654 | ; | ||
| 655 | |||
| 656 | PARSE_ERASE LABEL BYTE ;AN000; | ||
| 657 | DW TRANGROUP:ERASE_PARMS ;AN000; | ||
| 658 | DB 0 ;AN000; no extra delimiter | ||
| 659 | |||
| 660 | ERASE_PARMS LABEL BYTE ;AN000; | ||
| 661 | DB 1,1 ;AN000; 1 positional parm | ||
| 662 | DW TRANGROUP:FILE_REQUIRED ;AN000; | ||
| 663 | DB 1 ;AN000; 1 switch | ||
| 664 | DW TRANGROUP:SLASH_P_SWITCH;AN000; | ||
| 665 | DB 0 ;AN000; no keywords | ||
| 666 | |||
| 667 | ; | ||
| 668 | ; PARSE BLOCK FOR DIR | ||
| 669 | ; | ||
| 670 | |||
| 671 | ; | ||
| 672 | ; The following parse control block is used for the DIR internal command. | ||
| 673 | ; This command has one optional file specification and two optional | ||
| 674 | ; switches (/p and /w) as operands. The verified switch or unverified | ||
| 675 | ; file specification is returned in PARSE1_OUTPUT. | ||
| 676 | ; | ||
| 677 | |||
| 678 | PARSE_DIR LABEL BYTE ;AN000; | ||
| 679 | DW TRANGROUP:DIR_PARMS ;AN000; | ||
| 680 | DB 0 ;AN000; no extra delimiter | ||
| 681 | |||
| 682 | DIR_PARMS LABEL BYTE ;AN000; | ||
| 683 | DB 0,1 ;AN000; 1 positional parm | ||
| 684 | DW TRANGROUP:FILE_OPTIONAL2;AN000; | ||
| 685 | DB 2 ;AN000; 2 switches | ||
| 686 | DW TRANGROUP:SLASH_P_SWITCH;AN000; | ||
| 687 | DW TRANGROUP:DIR_SWITCH1 ;AN000; | ||
| 688 | DB 0 ;AN000; no keywords | ||
| 689 | |||
| 690 | DIR_SWITCH1 LABEL BYTE ;AN000; | ||
| 691 | DW 0 ;AN000; no match flags | ||
| 692 | DW 2 ;AN000; capitalize by char table | ||
| 693 | DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer | ||
| 694 | DW TRANGROUP:NO_VALUES ;AN000; | ||
| 695 | DB 1 ;AN000; 1 keyword | ||
| 696 | DIR_W_SYN DB "/W",0 ;AN000; /W switch | ||
| 697 | |||
| 698 | ; | ||
| 699 | ; PARSE BLOCK FOR RENAME | ||
| 700 | ; | ||
| 701 | |||
| 702 | ; | ||
| 703 | ; The following parse control block can be used for any command which | ||
| 704 | ; needs only two required file specifications as operands. Returns | ||
| 705 | ; pointers to the unverified string in PARSE1_OUTPUT. | ||
| 706 | ; Currently used for the RENAME internal command. | ||
| 707 | ; | ||
| 708 | |||
| 709 | PARSE_RENAME LABEL BYTE ;AN000; | ||
| 710 | DW TRANGROUP:RENAME_PARMS ;AN000; | ||
| 711 | DB 0 ;AN000; no extra delimiter | ||
| 712 | |||
| 713 | RENAME_PARMS LABEL BYTE ;AN000; | ||
| 714 | DB 2,2 ;AN000; 2 positional parms | ||
| 715 | DW TRANGROUP:FILE_REQUIRED ;AN000; | ||
| 716 | DW TRANGROUP:FILE_REQUIRED ;AN000; | ||
| 717 | DB 0 ;AN000; no switches | ||
| 718 | DB 0 ;AN000; no keywords | ||
| 719 | |||
| 720 | ; | ||
| 721 | ; PARSE BLOCK FOR CTTY | ||
| 722 | ; | ||
| 723 | |||
| 724 | ; | ||
| 725 | ; The following parse control block can be used for any command which | ||
| 726 | ; needs one required device name as an operand. Returns a pointer to | ||
| 727 | ; unverified string in PARSE1_OUTPUT. Currently used for the CTTY | ||
| 728 | ; internal command. | ||
| 729 | ; | ||
| 730 | |||
| 731 | PARSE_CTTY LABEL BYTE ;AN000; | ||
| 732 | DW TRANGROUP:CTTY_PARMS ;AN000; | ||
| 733 | DB 0 ;AN000; no extra delimiter | ||
| 734 | |||
| 735 | CTTY_PARMS LABEL BYTE ;AN000; | ||
| 736 | DB 1,1 ;AN000; 1 positional parm | ||
| 737 | DW TRANGROUP:CTTY_CONTROL1 ;AN000; | ||
| 738 | DB 0 ;AN000; no switches | ||
| 739 | DB 0 ;AN000; no keywords | ||
| 740 | |||
| 741 | CTTY_CONTROL1 LABEL BYTE ;AN000; | ||
| 742 | DW 2000H ;AN000; string value - required | ||
| 743 | DW 11H ;AN000; capitalize - file table | ||
| 744 | ;AN000; remove colon at end | ||
| 745 | DW TRANGROUP:PARSE1_OUTPUT ;AN000; result buffer | ||
| 746 | DW TRANGROUP:NO_VALUES ;AN000; | ||
| 747 | DB 0 ;AN000; no keywords | ||
| 748 | |||
| 749 | TRANDATA ENDS | ||
| 750 | |||
| 751 | TRANCODE SEGMENT PUBLIC BYTE ;AN000; | ||
| 752 | |||
| 753 | .xlist | ||
| 754 | .xcref | ||
| 755 | |||
| 756 | INCLUDE SYSMSG.INC ;AN000; | ||
| 757 | |||
| 758 | .list | ||
| 759 | .cref | ||
| 760 | |||
| 761 | ASSUME DS:TRANGROUP,ES:TRANGROUP,CS:TRANGROUP | ||
| 762 | |||
| 763 | MSG_UTILNAME <COMMAND> ;AN000; define utility name | ||
| 764 | |||
| 765 | MSG_SERVICES <COMT,COMMAND.CLF,COMMAND.CL1,COMMAND.CL2> ;AN000; The transient messages | ||
| 766 | |||
| 767 | include msgdcl.inc | ||
| 768 | |||
| 769 | TRANCODE ENDS ;AN000; | ||
| 770 | |||
| 771 | TRANDATA SEGMENT PUBLIC BYTE | ||
| 772 | |||
| 773 | TRANDATAEND LABEL BYTE | ||
| 774 | |||
| 775 | TRANDATA ENDS ;AN000; | ||
| 776 | |||
| 777 | END | ||
diff --git a/v4.0/src/CMD/COMMAND/TENV.ASM b/v4.0/src/CMD/COMMAND/TENV.ASM new file mode 100644 index 0000000..e1d43f6 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/TENV.ASM | |||
| @@ -0,0 +1,633 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)tenv.asm 4.2 85/08/16 | ||
| 3 | ; SCCSID = @(#)tenv.asm 4.2 85/08/16 | ||
| 4 | TITLE Part6 COMMAND Transient routines. | ||
| 5 | |||
| 6 | ; Environment utilities and misc. routines | ||
| 7 | |||
| 8 | INCLUDE comsw.asm | ||
| 9 | |||
| 10 | .xlist | ||
| 11 | .xcref | ||
| 12 | INCLUDE DOSSYM.INC | ||
| 13 | INCLUDE comseg.asm | ||
| 14 | INCLUDE comequ.asm | ||
| 15 | INCLUDE DOSCNTRY.INC ;AN000; | ||
| 16 | .list | ||
| 17 | .cref | ||
| 18 | |||
| 19 | |||
| 20 | DATARES SEGMENT PUBLIC BYTE ;AC000; | ||
| 21 | EXTRN comdrv:byte | ||
| 22 | EXTRN comspec_end:word | ||
| 23 | EXTRN comspec_print:word | ||
| 24 | EXTRN cpdrv:byte | ||
| 25 | EXTRN dbcs_vector_addr:dword ;AN000; | ||
| 26 | EXTRN ENVIRSEG:WORD | ||
| 27 | EXTRN fucase_addr:word ;AC000; | ||
| 28 | EXTRN RESTDIR:BYTE | ||
| 29 | DATARES ENDS | ||
| 30 | |||
| 31 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 32 | EXTRN arg_buf_ptr:word | ||
| 33 | EXTRN comspec:byte | ||
| 34 | EXTRN comspec_flag:byte | ||
| 35 | EXTRN comspecstr:byte | ||
| 36 | EXTRN ENVERR_PTR:WORD | ||
| 37 | EXTRN PATH_TEXT:byte | ||
| 38 | EXTRN PROMPT_TEXT:byte | ||
| 39 | EXTRN SYNTMES_PTR:WORD | ||
| 40 | TRANDATA ENDS | ||
| 41 | |||
| 42 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 43 | EXTRN Arg_Buf:BYTE | ||
| 44 | EXTRN RESSEG:WORD | ||
| 45 | EXTRN USERDIR1:BYTE | ||
| 46 | TRANSPACE ENDS | ||
| 47 | |||
| 48 | TRANCODE SEGMENT PUBLIC byte | ||
| 49 | |||
| 50 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 51 | |||
| 52 | EXTRN cerror:near | ||
| 53 | |||
| 54 | PUBLIC add_name_to_environment | ||
| 55 | PUBLIC add_prompt | ||
| 56 | PUBLIC delete_path | ||
| 57 | PUBLIC find_name_in_environment | ||
| 58 | PUBLIC find_path | ||
| 59 | PUBLIC find_prompt | ||
| 60 | PUBLIC move_name | ||
| 61 | PUBLIC restudir | ||
| 62 | PUBLIC restudir1 | ||
| 63 | PUBLIC scan_double_null | ||
| 64 | PUBLIC scasb2 | ||
| 65 | PUBLIC store_char | ||
| 66 | PUBLIC Testkanj ;AN000; 3/3/KK | ||
| 67 | PUBLIC upconv | ||
| 68 | |||
| 69 | BREAK <Environment utilities> | ||
| 70 | ASSUME DS:TRANGROUP | ||
| 71 | |||
| 72 | break Prompt command | ||
| 73 | assume ds:trangroup,es:trangroup | ||
| 74 | |||
| 75 | ADD_PROMPT: | ||
| 76 | CALL DELETE_PROMPT ; DELETE ANY EXISTING PROMPT | ||
| 77 | CALL SCAN_DOUBLE_NULL | ||
| 78 | |||
| 79 | ADD_PROMPT2: | ||
| 80 | PUSH SI | ||
| 81 | CALL GETARG | ||
| 82 | POP SI | ||
| 83 | retz ; PRE SCAN FOR ARGUMENTS | ||
| 84 | CALL MOVE_NAME ; MOVE IN NAME | ||
| 85 | CALL GETARG | ||
| 86 | PUSH SI | ||
| 87 | JMP SHORT ADD_NAME | ||
| 88 | |||
| 89 | |||
| 90 | break The SET command | ||
| 91 | assume ds:trangroup,es:trangroup | ||
| 92 | |||
| 93 | ; | ||
| 94 | ; Input: DS:SI points to a CR terminated string | ||
| 95 | ; Output: carry flag is set if no room | ||
| 96 | ; otherwise name is added to environment | ||
| 97 | ; | ||
| 98 | |||
| 99 | DISP_ENVj: | ||
| 100 | jmp DISP_ENV | ||
| 101 | |||
| 102 | ADD_NAME_TO_ENVIRONMENT: | ||
| 103 | CALL GETARG | ||
| 104 | JZ DISP_ENVj | ||
| 105 | ; | ||
| 106 | ; check if line contains exactly one equals sign | ||
| 107 | ; | ||
| 108 | XOR BX,BX ;= COUNT IS 0 | ||
| 109 | PUSH SI ;SAVE POINTER TO BEGINNING OF LINE | ||
| 110 | |||
| 111 | EQLP: | ||
| 112 | LODSB ;GET A CHAR | ||
| 113 | CMP AL,13 ;IF CR WE'RE ALL DONE | ||
| 114 | JZ QUEQ | ||
| 115 | CMP AL,'=' ;LOOK FOR = SIGN | ||
| 116 | JNZ EQLP ;NOT THERE, GET NEXT CHAR | ||
| 117 | INC BL ;OTHERWISE INCREMENT EQ COUNT | ||
| 118 | CMP BYTE PTR [SI],13 ;LOOK FOR CR FOLLOWING = SIGN | ||
| 119 | JNZ EQLP | ||
| 120 | INC BH ;SET BH=1 MEANS NO PARAMETERS | ||
| 121 | JMP EQLP ;AND LOOK FOR MORE | ||
| 122 | |||
| 123 | QUEQ: | ||
| 124 | POP SI ;RESTORE BEGINNING OF LINE | ||
| 125 | DEC BL ;ZERO FLAG MEANS ONLY ONE EQ | ||
| 126 | JZ ONEQ ;GOOD LINE | ||
| 127 | MOV DX,OFFSET TRANGROUP:SYNTMES_ptr | ||
| 128 | JMP CERROR | ||
| 129 | |||
| 130 | ONEQ: | ||
| 131 | PUSH BX | ||
| 132 | CALL DELETE_NAME_IN_ENVIRONMENT | ||
| 133 | POP BX | ||
| 134 | DEC BH | ||
| 135 | retz | ||
| 136 | |||
| 137 | CALL SCAN_DOUBLE_NULL | ||
| 138 | mov bx,di ; Save ptr to beginning of env var name | ||
| 139 | CALL MOVE_NAME | ||
| 140 | push si | ||
| 141 | xchg bx,di ; Switch ptrs to beginning and end of | ||
| 142 | ; env var name | ||
| 143 | ; | ||
| 144 | ; We want to special-case COMSPEC. This is to reduce the amount of code | ||
| 145 | ; necessary in the resident for re-reading the transient. Let's look for | ||
| 146 | ; COMSPEC= | ||
| 147 | ; | ||
| 148 | mov si,offset trangroup:comspecstr ; Load ptr to string "COMSPEC" | ||
| 149 | mov cx,4 ; If the new env var is comspec, set | ||
| 150 | repz cmpsw ; the comspec_flag | ||
| 151 | ; | ||
| 152 | ; Zero set => exact match | ||
| 153 | ; | ||
| 154 | jnz not_comspec | ||
| 155 | mov comspec_flag,1 | ||
| 156 | |||
| 157 | not_comspec: | ||
| 158 | mov di,bx ; Load ptr to end of env var name | ||
| 159 | |||
| 160 | ADD_NAME: ; Add the value of the new env var | ||
| 161 | pop si ; to the environment. | ||
| 162 | push si | ||
| 163 | |||
| 164 | add_name1: | ||
| 165 | LODSB | ||
| 166 | CMP AL,13 | ||
| 167 | jz add_name_ret | ||
| 168 | CALL STORE_CHAR | ||
| 169 | JMP ADD_NAME1 | ||
| 170 | |||
| 171 | add_name_ret: | ||
| 172 | pop si | ||
| 173 | cmp comspec_flag,0 ; If the new env var is comspec, | ||
| 174 | retz ; copy the value into the | ||
| 175 | ; | ||
| 176 | ; We have changed the COMSPEC variable. We need to update the resident | ||
| 177 | ; pieces necessary to reread in the info. First, skip all delimiters | ||
| 178 | ; | ||
| 179 | invoke ScanOff | ||
| 180 | mov es,[resseg] ; comspec var in the resident | ||
| 181 | assume es:resgroup | ||
| 182 | ; | ||
| 183 | ; Make sure that the printer knows where the beginning of the string is | ||
| 184 | ; | ||
| 185 | mov di,offset resgroup:comspec | ||
| 186 | mov bx,di | ||
| 187 | ; | ||
| 188 | ; Generate drive letter for display | ||
| 189 | ; | ||
| 190 | xor ax,ax ;g assume no drive first | ||
| 191 | mov comdrv,al ;g | ||
| 192 | push ax ;AN000; 3/3/KK | ||
| 193 | mov al,[si] ;AN000; 3/3/KK | ||
| 194 | call testkanj ;AN000; 3/3/KK | ||
| 195 | pop ax ;AN000; 3/3/KK | ||
| 196 | jnz GotDrive | ||
| 197 | cmp byte ptr [si+1],':' ; drive specified? | ||
| 198 | jnz GotDrive | ||
| 199 | mov al,[si] ; get his specified drive | ||
| 200 | call UpConv ; convert to uppercase | ||
| 201 | sub al,'A' ; convert to 0-based | ||
| 202 | add di,2 | ||
| 203 | inc al ; convert to 1-based number | ||
| 204 | mov comdrv,al | ||
| 205 | ; | ||
| 206 | ; Stick the drive letter in the prompt message. Nothing special needs to be | ||
| 207 | ; done here.. | ||
| 208 | ; | ||
| 209 | |||
| 210 | add al,'A'-1 | ||
| 211 | |||
| 212 | GotDrive: ;g | ||
| 213 | mov comspec_print,di ;g point to beginning of name after drive | ||
| 214 | mov es:cpdrv,al | ||
| 215 | ; | ||
| 216 | ; Copy chars until delim | ||
| 217 | ; | ||
| 218 | |||
| 219 | mov di,bx | ||
| 220 | |||
| 221 | copy_comspec: | ||
| 222 | lodsb | ||
| 223 | invoke Delim | ||
| 224 | jz CopyDone | ||
| 225 | cmp al,13 | ||
| 226 | jz CopyDone | ||
| 227 | stosb | ||
| 228 | jmp short copy_comspec | ||
| 229 | |||
| 230 | CopyDone: | ||
| 231 | xor al,al ; Null terminate the string and quit | ||
| 232 | stosb | ||
| 233 | mov comspec_flag,0 | ||
| 234 | dec di | ||
| 235 | mov comspec_end,di | ||
| 236 | |||
| 237 | ret | ||
| 238 | |||
| 239 | DISP_ENV: | ||
| 240 | MOV DS,[RESSEG] | ||
| 241 | ASSUME DS:RESGROUP | ||
| 242 | MOV DS,[ENVIRSEG] | ||
| 243 | ASSUME DS:NOTHING | ||
| 244 | XOR SI,SI | ||
| 245 | |||
| 246 | PENVLP: | ||
| 247 | CMP BYTE PTR [SI],0 | ||
| 248 | retz | ||
| 249 | mov di,offset trangroup:arg_buf | ||
| 250 | |||
| 251 | PENVLP2: | ||
| 252 | LODSB | ||
| 253 | stosb | ||
| 254 | OR AL,AL | ||
| 255 | JNZ PENVLP2 | ||
| 256 | mov dx,offset trangroup:arg_buf_ptr | ||
| 257 | push ds | ||
| 258 | push es | ||
| 259 | pop ds | ||
| 260 | invoke printf_crlf | ||
| 261 | pop ds | ||
| 262 | JMP PENVLP | ||
| 263 | |||
| 264 | ASSUME DS:TRANGROUP | ||
| 265 | |||
| 266 | DELETE_PATH: | ||
| 267 | MOV SI,OFFSET TRANGROUP:PATH_TEXT | ||
| 268 | JMP SHORT DELETE_NAME_IN_environment | ||
| 269 | |||
| 270 | DELETE_PROMPT: | ||
| 271 | MOV SI,OFFSET TRANGROUP:PROMPT_TEXT | ||
| 272 | |||
| 273 | DELETE_NAME_IN_environment: | ||
| 274 | ; | ||
| 275 | ; Input: DS:SI points to a "=" terminated string | ||
| 276 | ; Output: carry flag is set if name not found | ||
| 277 | ; otherwise name is deleted | ||
| 278 | ; | ||
| 279 | PUSH SI | ||
| 280 | PUSH DS | ||
| 281 | CALL FIND ; ES:DI POINTS TO NAME | ||
| 282 | JC DEL1 | ||
| 283 | MOV SI,DI ; SAVE IT | ||
| 284 | CALL SCASB2 ; SCAN FOR THE NUL | ||
| 285 | XCHG SI,DI | ||
| 286 | CALL GETENVSIZ | ||
| 287 | SUB CX,SI | ||
| 288 | PUSH ES | ||
| 289 | POP DS ; ES:DI POINTS TO NAME, DS:SI POINTS TO NEXT NAME | ||
| 290 | REP MOVSB ; DELETE THE NAME | ||
| 291 | |||
| 292 | DEL1: | ||
| 293 | POP DS | ||
| 294 | POP SI | ||
| 295 | return | ||
| 296 | |||
| 297 | FIND_PATH: | ||
| 298 | MOV SI,OFFSET TRANGROUP:PATH_TEXT | ||
| 299 | JMP SHORT FIND_NAME_IN_environment | ||
| 300 | |||
| 301 | FIND_PROMPT: | ||
| 302 | MOV SI,OFFSET TRANGROUP:PROMPT_TEXT | ||
| 303 | |||
| 304 | FIND_NAME_IN_environment: | ||
| 305 | ; | ||
| 306 | ; Input: DS:SI points to a "=" terminated string | ||
| 307 | ; Output: ES:DI points to the arguments in the environment | ||
| 308 | ; zero is set if name not found | ||
| 309 | ; carry flag is set if name not valid format | ||
| 310 | ; | ||
| 311 | CALL FIND ; FIND THE NAME | ||
| 312 | retc ; CARRY MEANS NOT FOUND | ||
| 313 | JMP SCASB1 ; SCAN FOR = SIGN | ||
| 314 | ; | ||
| 315 | ; On return of FIND1, ES:DI points to beginning of name | ||
| 316 | ; | ||
| 317 | FIND: | ||
| 318 | CLD | ||
| 319 | CALL COUNT0 ; CX = LENGTH OF NAME | ||
| 320 | MOV ES,[RESSEG] | ||
| 321 | ASSUME ES:RESGROUP | ||
| 322 | MOV ES,[ENVIRSEG] | ||
| 323 | ASSUME ES:NOTHING | ||
| 324 | XOR DI,DI | ||
| 325 | |||
| 326 | FIND1: | ||
| 327 | PUSH CX | ||
| 328 | PUSH SI | ||
| 329 | PUSH DI | ||
| 330 | |||
| 331 | FIND11: | ||
| 332 | LODSB | ||
| 333 | CALL TESTKANJ | ||
| 334 | JZ NOTKANJ3 | ||
| 335 | DEC SI | ||
| 336 | LODSW | ||
| 337 | INC DI | ||
| 338 | INC DI | ||
| 339 | CMP AX,ES:[DI-2] | ||
| 340 | JNZ FIND12 | ||
| 341 | DEC CX | ||
| 342 | LOOP FIND11 | ||
| 343 | JMP SHORT FIND12 | ||
| 344 | |||
| 345 | NOTKANJ3: | ||
| 346 | CALL UPCONV | ||
| 347 | INC DI | ||
| 348 | CMP AL,ES:[DI-1] | ||
| 349 | JNZ FIND12 | ||
| 350 | LOOP FIND11 | ||
| 351 | |||
| 352 | FIND12: | ||
| 353 | POP DI | ||
| 354 | POP SI | ||
| 355 | POP CX | ||
| 356 | retz | ||
| 357 | PUSH CX | ||
| 358 | CALL SCASB2 ; SCAN FOR A NUL | ||
| 359 | POP CX | ||
| 360 | CMP BYTE PTR ES:[DI],0 | ||
| 361 | JNZ FIND1 | ||
| 362 | STC ; INDICATE NOT FOUND | ||
| 363 | return | ||
| 364 | |||
| 365 | COUNT0: | ||
| 366 | PUSH DS | ||
| 367 | POP ES | ||
| 368 | MOV DI,SI | ||
| 369 | |||
| 370 | COUNT1: | ||
| 371 | PUSH DI ; COUNT NUMBER OF CHARS UNTIL "=" | ||
| 372 | CALL SCASB1 | ||
| 373 | JMP SHORT COUNTX | ||
| 374 | |||
| 375 | COUNT2: | ||
| 376 | PUSH DI ; COUNT NUMBER OF CHARS UNTIL NUL | ||
| 377 | CALL SCASB2 | ||
| 378 | |||
| 379 | COUNTX: | ||
| 380 | POP CX | ||
| 381 | SUB DI,CX | ||
| 382 | XCHG DI,CX | ||
| 383 | return | ||
| 384 | |||
| 385 | MOVE_NAME: | ||
| 386 | CMP BYTE PTR DS:[SI],13 | ||
| 387 | retz | ||
| 388 | LODSB | ||
| 389 | |||
| 390 | ;;;; IF KANJI 3/3/KK | ||
| 391 | CALL TESTKANJ | ||
| 392 | JZ NOTKANJ1 | ||
| 393 | CALL STORE_CHAR | ||
| 394 | LODSB | ||
| 395 | CALL STORE_CHAR | ||
| 396 | JMP SHORT MOVE_NAME | ||
| 397 | |||
| 398 | NOTKANJ1: | ||
| 399 | ;;;; ENDIF 3/3/KK | ||
| 400 | |||
| 401 | CALL UPCONV | ||
| 402 | CALL STORE_CHAR | ||
| 403 | CMP AL,'=' | ||
| 404 | JNZ MOVE_NAME | ||
| 405 | return | ||
| 406 | |||
| 407 | GETARG: | ||
| 408 | MOV SI,80H | ||
| 409 | LODSB | ||
| 410 | OR AL,AL | ||
| 411 | retz | ||
| 412 | invoke SCANOFF | ||
| 413 | CMP AL,13 | ||
| 414 | return | ||
| 415 | |||
| 416 | ; | ||
| 417 | ; Point ES:DI to the final NULL string. Note that in an empty environment, | ||
| 418 | ; there is NO double NULL, merely a string that is empty. | ||
| 419 | ; | ||
| 420 | SCAN_DOUBLE_NULL: | ||
| 421 | MOV ES,[RESSEG] | ||
| 422 | ASSUME ES:RESGROUP | ||
| 423 | MOV ES,[ENVIRSEG] | ||
| 424 | ASSUME ES:NOTHING | ||
| 425 | XOR DI,DI | ||
| 426 | ; | ||
| 427 | ; Top cycle-point. If the string here is empty, then we are done | ||
| 428 | ; | ||
| 429 | SDN1: | ||
| 430 | cmp byte ptr es:[di],0 ; nul string? | ||
| 431 | retz ; yep, all done | ||
| 432 | CALL SCASB2 | ||
| 433 | JMP SDN1 | ||
| 434 | |||
| 435 | SCASB1: | ||
| 436 | MOV AL,'=' ; SCAN FOR AN = | ||
| 437 | JMP SHORT SCASBX | ||
| 438 | SCASB2: | ||
| 439 | XOR AL,AL ; SCAN FOR A NUL | ||
| 440 | SCASBX: | ||
| 441 | MOV CX,100H | ||
| 442 | REPNZ SCASB | ||
| 443 | return | ||
| 444 | |||
| 445 | TESTKANJ: | ||
| 446 | push ds ;AN000; 3/3/KK | ||
| 447 | push si ;AN000; 3/3/KK | ||
| 448 | push ax ;AN000; 3/3/KK | ||
| 449 | mov ds,cs:[resseg] ;AN000; Get resident segment | ||
| 450 | assume ds:resgroup ;AN000; | ||
| 451 | lds si,dbcs_vector_addr ;AN000; get DBCS vector | ||
| 452 | ktlop: ;AN000; 3/3/KK | ||
| 453 | cmp word ptr ds:[si],0 ;AN000; end of Table 3/3/KK | ||
| 454 | je notlead ;AN000; 3/3/KK | ||
| 455 | pop ax ;AN000; 3/3/KK | ||
| 456 | push ax ;AN000; 3/3/KK | ||
| 457 | cmp al, byte ptr ds:[si] ;AN000; 3/3/KK | ||
| 458 | jb notlead ;AN000; 3/3/KK | ||
| 459 | inc si ;AN000; 3/3/KK | ||
| 460 | cmp al, byte ptr ds:[si] ;AN000; 3/3/KK | ||
| 461 | jbe islead ;AN000; 3/3/KK | ||
| 462 | inc si ;AN000; 3/3/KK | ||
| 463 | jmp short ktlop ;AN000; try another range ; 3/3/KK | ||
| 464 | Notlead: ;AN000; 3/3/KK | ||
| 465 | xor ax,ax ;AN000; set zero 3/3/KK | ||
| 466 | jmp short ktret ;AN000; 3/3/KK | ||
| 467 | Islead: ;AN000; 3/3/KK | ||
| 468 | xor ax,ax ;AN000; reset zero 3/3/KK | ||
| 469 | inc ax ;AN000; 3/3/KK | ||
| 470 | ktret: ;AN000; 3/3/KK | ||
| 471 | pop ax ;AN000; 3/3/KK | ||
| 472 | pop si ;AN000; 3/3/KK | ||
| 473 | pop ds ;AN000; 3/3/KK | ||
| 474 | return ;AN000; 3/3/KK | ||
| 475 | ;------------------------------------- ;3/3/KK | ||
| 476 | |||
| 477 | |||
| 478 | ; **************************************************************** | ||
| 479 | ; * | ||
| 480 | ; * ROUTINE: UPCONV (ADDED BY EMG 4.00) | ||
| 481 | ; * | ||
| 482 | ; * FUNCTION: This routine returns the upper case equivalent of | ||
| 483 | ; * the character in AL from the file upper case table | ||
| 484 | ; * in DOS if character if above ascii 128, else | ||
| 485 | ; * subtracts 20H if between "a" and "z". | ||
| 486 | ; * | ||
| 487 | ; * INPUT: AL char to be upper cased | ||
| 488 | ; * FUCASE_ADDR set to the file upper case table | ||
| 489 | ; * | ||
| 490 | ; * OUTPUT: AL upper cased character | ||
| 491 | ; * | ||
| 492 | ; **************************************************************** | ||
| 493 | |||
| 494 | assume ds:trangroup ;AN000; | ||
| 495 | |||
| 496 | upconv proc near ;AN000; | ||
| 497 | |||
| 498 | cmp al,80h ;AN000; see if char is > ascii 128 | ||
| 499 | jb oth_fucase ;AN000; no - upper case math | ||
| 500 | sub al,80h ;AN000; only upper 128 chars in table | ||
| 501 | push ds ;AN000; | ||
| 502 | push bx ;AN000; | ||
| 503 | mov ds,[resseg] ;AN000; get resident data segment | ||
| 504 | assume ds:resgroup ;AN000; | ||
| 505 | lds bx,dword ptr fucase_addr+1 ;AN000; get table address | ||
| 506 | add bx,2 ;AN000; skip over first word | ||
| 507 | xlat ds:byte ptr [bx] ;AN000; convert to upper case | ||
| 508 | pop bx ;AN000; | ||
| 509 | pop ds ;AN000; | ||
| 510 | assume ds:trangroup ;AN000; | ||
| 511 | jmp short upconv_end ;AN000; we finished - exit | ||
| 512 | |||
| 513 | oth_fucase: ;AN000; | ||
| 514 | cmp al,small_a ;AC000; if between "a" and "z", | ||
| 515 | jb upconv_end ;AC000; subtract 20h to get | ||
| 516 | cmp al,small_z ;AC000; upper case equivalent. | ||
| 517 | ja upconv_end ;AC000; | ||
| 518 | sub al,20h ;AC000; Change lower-case to upper | ||
| 519 | |||
| 520 | upconv_end: ;AN000; | ||
| 521 | ret | ||
| 522 | |||
| 523 | upconv endp ;AN000; | ||
| 524 | |||
| 525 | |||
| 526 | ; | ||
| 527 | ; STORE A CHAR IN environment, GROWING IT IF NECESSARY | ||
| 528 | ; | ||
| 529 | STORE_CHAR: | ||
| 530 | PUSH CX | ||
| 531 | PUSH BX | ||
| 532 | PUSH ES ;AN056; | ||
| 533 | PUSH DS ;AN056; Save local DS | ||
| 534 | MOV DS,[RESSEG] ;AN056; Get resident segment | ||
| 535 | ASSUME DS:RESGROUP ;AN056; | ||
| 536 | MOV ES,[ENVIRSEG] ;AN056; Get environment segment | ||
| 537 | ASSUME ES:NOTHING ;AN056; | ||
| 538 | POP DS ;AN056; Get local segment back | ||
| 539 | ASSUME DS:TRANGROUP ;AN056; | ||
| 540 | CALL GETENVSIZ | ||
| 541 | MOV BX,CX | ||
| 542 | SUB BX,2 ; SAVE ROOM FOR DOUBLE NULL | ||
| 543 | CMP DI,BX | ||
| 544 | JB STORE1 | ||
| 545 | |||
| 546 | PUSH AX | ||
| 547 | PUSH CX | ||
| 548 | PUSH BX ; Save Size of environment | ||
| 549 | invoke FREE_TPA | ||
| 550 | POP BX | ||
| 551 | ADD BX,2 ; Recover true environment size | ||
| 552 | |||
| 553 | CMP BX, 8000H ; Don't let environment grow > 32K | ||
| 554 | JB ENVSIZ_OK | ||
| 555 | BAD_ENV_SIZE: ;AN056; | ||
| 556 | STC | ||
| 557 | JMP ENVNOSET | ||
| 558 | ENVSIZ_OK: | ||
| 559 | |||
| 560 | MOV CL,4 | ||
| 561 | SHR BX,CL ; Convert back to paragraphs | ||
| 562 | INC BX ; Try to grow environment by one para | ||
| 563 | MOV CX,ES ;AN056; Get environment segment | ||
| 564 | ADD CX,BX ;AN056; Add in size of environment | ||
| 565 | ADD CX,020H ;AN056; Add in some TPA | ||
| 566 | MOV AX,CS ;AN056; Get the transient segment | ||
| 567 | CMP CX,AX ;AN056; Are we hitting the transient? | ||
| 568 | JNB BAD_ENV_SIZE ;AN056; Yes - don't do it!!! | ||
| 569 | MOV AH,SETBLOCK | ||
| 570 | INT int_command | ||
| 571 | ENVNOSET: | ||
| 572 | PUSHF | ||
| 573 | PUSH ES | ||
| 574 | MOV ES,[RESSEG] | ||
| 575 | invoke ALLOC_TPA | ||
| 576 | POP ES | ||
| 577 | POPF | ||
| 578 | POP CX | ||
| 579 | POP AX | ||
| 580 | JNC STORE1 | ||
| 581 | POP ES ;AN056; | ||
| 582 | MOV DX,OFFSET TRANGROUP:ENVERR_ptr | ||
| 583 | JMP CERROR | ||
| 584 | STORE1: | ||
| 585 | STOSB | ||
| 586 | MOV WORD PTR ES:[DI],0 ; NULL IS AT END | ||
| 587 | POP ES ;AN056; | ||
| 588 | POP BX | ||
| 589 | POP CX | ||
| 590 | return | ||
| 591 | |||
| 592 | GETENVSIZ: | ||
| 593 | ;Get size of environment in bytes, rounded up to paragraph boundry | ||
| 594 | ;ES has environment segment | ||
| 595 | ;Size returned in CX, all other registers preserved | ||
| 596 | |||
| 597 | PUSH ES | ||
| 598 | PUSH AX | ||
| 599 | MOV AX,ES | ||
| 600 | DEC AX ;Point at arena | ||
| 601 | MOV ES,AX | ||
| 602 | MOV AX,ES:[arena_size] | ||
| 603 | MOV CL,4 | ||
| 604 | SHL AX,CL ;Convert to bytes | ||
| 605 | MOV CX,AX | ||
| 606 | POP AX | ||
| 607 | POP ES | ||
| 608 | return | ||
| 609 | |||
| 610 | |||
| 611 | ASSUME DS:TRANGROUP | ||
| 612 | |||
| 613 | |||
| 614 | RESTUDIR1: | ||
| 615 | PUSH DS | ||
| 616 | MOV DS,[RESSEG] | ||
| 617 | ASSUME DS:RESGROUP | ||
| 618 | CMP [RESTDIR],0 | ||
| 619 | POP DS | ||
| 620 | ASSUME DS:TRANGROUP | ||
| 621 | retz | ||
| 622 | |||
| 623 | RESTUDIR: | ||
| 624 | MOV DX,OFFSET TRANGROUP:USERDIR1 | ||
| 625 | MOV AH,CHDIR | ||
| 626 | INT int_command ; Restore users DIR | ||
| 627 | XOR AL,AL | ||
| 628 | invoke SETREST | ||
| 629 | RET56: | ||
| 630 | return | ||
| 631 | |||
| 632 | trancode ends | ||
| 633 | end | ||
diff --git a/v4.0/src/CMD/COMMAND/TENV2.ASM b/v4.0/src/CMD/COMMAND/TENV2.ASM new file mode 100644 index 0000000..0c47958 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/TENV2.ASM | |||
| @@ -0,0 +1,663 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)tenv2.asm 1.1 85/05/14 | ||
| 3 | ; SCCSID = @(#)tenv2.asm 1.1 85/05/14 | ||
| 4 | TITLE Part6 COMMAND Transient routines. | ||
| 5 | |||
| 6 | ; Environment utilities and misc. routines | ||
| 7 | |||
| 8 | INCLUDE comsw.asm | ||
| 9 | |||
| 10 | .xlist | ||
| 11 | .xcref | ||
| 12 | INCLUDE DOSSYM.INC | ||
| 13 | INCLUDE comseg.asm | ||
| 14 | INCLUDE comequ.asm | ||
| 15 | .list | ||
| 16 | .cref | ||
| 17 | |||
| 18 | |||
| 19 | DATARES SEGMENT PUBLIC BYTE ;AC000; | ||
| 20 | EXTRN pipeflag:byte | ||
| 21 | DATARES ENDS | ||
| 22 | |||
| 23 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 24 | EXTRN ACRLF_PTR:WORD | ||
| 25 | EXTRN BadCD_Ptr:WORD | ||
| 26 | EXTRN Badmkd_ptr:word | ||
| 27 | EXTRN BADRMD_PTR:WORD | ||
| 28 | EXTRN Extend_buf_ptr:word ;AN000; | ||
| 29 | EXTRN Extend_buf_sub:byte ;AN022; | ||
| 30 | EXTRN MD_exists_ptr:word ;AN006; | ||
| 31 | EXTRN msg_disp_class:byte ;AC000; | ||
| 32 | EXTRN NOSPACE_PTR:WORD | ||
| 33 | EXTRN parse_chdir:byte ;AC000; | ||
| 34 | EXTRN parse_mrdir:byte ;AC000; | ||
| 35 | EXTRN PIPEEMES_PTR:WORD | ||
| 36 | EXTRN string_buf_ptr:word | ||
| 37 | TRANDATA ENDS | ||
| 38 | |||
| 39 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 40 | EXTRN CURDRV:BYTE | ||
| 41 | EXTRN DESTINFO:BYTE | ||
| 42 | EXTRN DESTTAIL:WORD | ||
| 43 | EXTRN DIRCHAR:BYTE | ||
| 44 | EXTRN dirflag:byte ;AN015; | ||
| 45 | EXTRN KPARSE:BYTE ;AC000; 3/3/KK | ||
| 46 | EXTRN msg_numb:word ;AN022; | ||
| 47 | EXTRN parse1_addr:dword ;AC000; | ||
| 48 | EXTRN parse1_type:byte ;AC000; | ||
| 49 | EXTRN PATHPOS:WORD | ||
| 50 | EXTRN RESSEG:WORD | ||
| 51 | EXTRN srcxname:byte ;AC000; | ||
| 52 | EXTRN string_ptr_2:word | ||
| 53 | EXTRN SWITCHAR:BYTE | ||
| 54 | EXTRN USERDIR1:BYTE | ||
| 55 | TRANSPACE ENDS | ||
| 56 | |||
| 57 | TRANCODE SEGMENT PUBLIC byte | ||
| 58 | |||
| 59 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 60 | |||
| 61 | EXTRN cerror:near | ||
| 62 | |||
| 63 | PUBLIC $chdir | ||
| 64 | PUBLIC $mkdir | ||
| 65 | PUBLIC $rmdir | ||
| 66 | PUBLIC crlf2 | ||
| 67 | PUBLIC crprint | ||
| 68 | PUBLIC delim | ||
| 69 | PUBLIC error_output | ||
| 70 | PUBLIC fcb_to_ascz | ||
| 71 | PUBLIC pathchrcmp | ||
| 72 | PUBLIC pathcrunch | ||
| 73 | PUBLIC savudir | ||
| 74 | PUBLIC savudir1 | ||
| 75 | PUBLIC scanoff | ||
| 76 | PUBLIC strcomp | ||
| 77 | |||
| 78 | break $Chdir | ||
| 79 | |||
| 80 | ; **************************************************************** | ||
| 81 | ; * | ||
| 82 | ; * ROUTINE: $CHDIR | ||
| 83 | ; * | ||
| 84 | ; * FUNCTION: Entry point for CHDIR command. Parse the command | ||
| 85 | ; * line. If path is found, CHDIR to path. If a drive | ||
| 86 | ; * letter is found, get and display the current dir | ||
| 87 | ; * of the specified drive. If nothing is found, get | ||
| 88 | ; * and display the current dir of the default drive. | ||
| 89 | ; * | ||
| 90 | ; * INPUT: command line at offset 81H | ||
| 91 | ; * | ||
| 92 | ; * OUTPUT: none | ||
| 93 | ; * | ||
| 94 | ; **************************************************************** | ||
| 95 | |||
| 96 | assume ds:trangroup,es:trangroup | ||
| 97 | |||
| 98 | $CHDIR: | ||
| 99 | |||
| 100 | mov si,81H | ||
| 101 | mov di,offset trangroup:parse_chdir ;AN000; Get adderss of PARSE_CHDIR | ||
| 102 | xor cx,cx ;AN000; clear cx,dx | ||
| 103 | xor dx,dx ;AN000; | ||
| 104 | invoke parse_with_msg ;AC018; call parser | ||
| 105 | |||
| 106 | cmp ax,end_of_line ;AC000; are we at end of line? | ||
| 107 | jz bwdJ ; No args | ||
| 108 | cmp ax,result_no_error ;AC000; did we have an error? | ||
| 109 | jnz ChDirErr ;AC018; yes - exit | ||
| 110 | |||
| 111 | cmp parse1_type,result_drive ;AC000; was a drive entered? | ||
| 112 | jnz REALCD ; no | ||
| 113 | ; | ||
| 114 | ; D: was found. See if there is anything more. | ||
| 115 | ; | ||
| 116 | mov di,offset trangroup:parse_chdir ;AC000; get address of parse_chdir | ||
| 117 | xor dx,dx ;AC000; | ||
| 118 | invoke parse_check_eol ;AC000; call parser | ||
| 119 | jnz ChDirErr ;AC000; | ||
| 120 | |||
| 121 | bwdJ: | ||
| 122 | invoke build_dir_for_chdir ; Drive only specified | ||
| 123 | call crlf2 | ||
| 124 | return | ||
| 125 | |||
| 126 | REALCD: | ||
| 127 | |||
| 128 | push si ;AN000; save position in line | ||
| 129 | lds si,parse1_addr ;AN000; get address of filespec | ||
| 130 | invoke move_to_srcbuf ;AN000; move to srcbuf | ||
| 131 | pop si ;AN000; restore position in line | ||
| 132 | mov di,offset trangroup:parse_chdir ;AC000; get address of parse_chdir | ||
| 133 | xor dx,dx ;AC000; | ||
| 134 | invoke parse_check_eol ;AC000; call parser | ||
| 135 | jnz ChDirErr ;AC000; | ||
| 136 | |||
| 137 | invoke SETPATH | ||
| 138 | TEST [DESTINFO],2 | ||
| 139 | JNZ BadChdir | ||
| 140 | MOV AH,CHDIR | ||
| 141 | INT int_command | ||
| 142 | retnc | ||
| 143 | |||
| 144 | invoke get_ext_error_number ;AN022; get the extended error | ||
| 145 | cmp ax,error_path_not_found ;AN022; see if path not found | ||
| 146 | jz BadChDir ;AN022; yes - issue old message | ||
| 147 | call Set_Ext_Error_Subst ;AN022; | ||
| 148 | jmp short chdirerr ;AN022; | ||
| 149 | |||
| 150 | BadChDir: | ||
| 151 | MOV DX,OFFSET TRANGROUP:BADCD_ptr | ||
| 152 | |||
| 153 | ChDirErr: | ||
| 154 | invoke Std_Eprintf | ||
| 155 | return | ||
| 156 | |||
| 157 | break $Mkdir | ||
| 158 | |||
| 159 | assume ds:trangroup,es:trangroup | ||
| 160 | |||
| 161 | $MKDIR: | ||
| 162 | CALL SETRMMK | ||
| 163 | JC MkDirErr | ||
| 164 | MOV AH,MKDIR | ||
| 165 | INT int_command | ||
| 166 | retnc | ||
| 167 | |||
| 168 | invoke get_ext_error_number ;AN022; get the extended error | ||
| 169 | cmp ax,error_path_not_found ;AN022; see if path not found | ||
| 170 | jz MD_other_err ;AN022; yes - issue old message | ||
| 171 | cmp ax,error_access_denied ;AN022; access denied? | ||
| 172 | jz badmderr ;AN022; yes - see if file exists | ||
| 173 | |||
| 174 | call Set_Ext_Error_Subst ;AN022; | ||
| 175 | jmp short MkDirerr ;AC022; yes - go print it | ||
| 176 | |||
| 177 | BADMDERR: | ||
| 178 | mov dx,offset trangroup:srcxname ;AN006; Set Disk transfer address | ||
| 179 | mov ah,Set_DMA ;AN006; | ||
| 180 | int int_command ;AN006; | ||
| 181 | MOV AH,Find_First ;AN006; see if file/dir exists | ||
| 182 | mov cx,attr_directory ;AN006; search for directory | ||
| 183 | INT int_command ;AN006; | ||
| 184 | jc MD_other_err ;AN006; doesn't exist - must be something else | ||
| 185 | mov dl,srcxname.find_buf_attr ;AN006; we found a file/dir | ||
| 186 | test dl,attr_directory ;AN006; was it a directory? | ||
| 187 | jz MD_other_err ;AN006; no - must have been a file | ||
| 188 | mov dx,offset trangroup:MD_exists_ptr ;AN006; set up already exists error | ||
| 189 | jmp short MkDirErr ;AN006; make sure we didn't have network error | ||
| 190 | MD_other_err: ;AN006; | ||
| 191 | MOV DX,OFFSET TRANGROUP:BADMKD_ptr | ||
| 192 | MkDirErr: | ||
| 193 | invoke Std_Eprintf | ||
| 194 | return | ||
| 195 | |||
| 196 | Break <Common MkDir/RmDir set up code> | ||
| 197 | |||
| 198 | ;**************************************************************** | ||
| 199 | ;* | ||
| 200 | ;* ROUTINE: SETRMMK | ||
| 201 | ;* | ||
| 202 | ;* FUNCTION: Parse routine for the internal MKDIR and RMDIR | ||
| 203 | ;* commands. Parses the command line for a required | ||
| 204 | ;* filespec. | ||
| 205 | ;* | ||
| 206 | ;* INPUT: command line at offset 81H | ||
| 207 | ;* | ||
| 208 | ;* OUTPUT: carry clear | ||
| 209 | ;* DS:DX points to ASCIIZ argument | ||
| 210 | ;* carry set | ||
| 211 | ;* DS:DX has error message pointer | ||
| 212 | ;* | ||
| 213 | ;**************************************************************** | ||
| 214 | |||
| 215 | SETRMMK: | ||
| 216 | mov si,81H | ||
| 217 | mov di,offset trangroup:parse_mrdir ;AN000; Get adderss of PARSE_MRDIR | ||
| 218 | xor cx,cx ;AN000; clear cx,dx | ||
| 219 | xor dx,dx ;AN000; | ||
| 220 | invoke parse_with_msg ;AC000; call parser | ||
| 221 | cmp ax,result_no_error ;AC000; did we have an error? | ||
| 222 | jnz NOARGERR ;AC000; yes - exit | ||
| 223 | |||
| 224 | mov di,offset trangroup:srcxname ;AN000; get address of srcxname | ||
| 225 | push di ;AN000; save address | ||
| 226 | push si ;AN000; save position in line | ||
| 227 | lds si,parse1_addr ;AN000; get address of path | ||
| 228 | |||
| 229 | mrdir_move_filename: ;AN000; put filespec in srcxname | ||
| 230 | lodsb ;get a char from buffer | ||
| 231 | stosb ;AN000; store in srcxname | ||
| 232 | cmp al,end_of_line_out ;AC000; it char a terminator? | ||
| 233 | jnz mrdir_move_filename ;AC000; no - keep moving | ||
| 234 | pop si ;AN000; get line position back | ||
| 235 | |||
| 236 | ; | ||
| 237 | ; we have scanned an argument. See if any args beyond. | ||
| 238 | ; | ||
| 239 | |||
| 240 | mov di,offset trangroup:parse_mrdir ;AC000; get address of parse_mrdir | ||
| 241 | invoke parse_check_eol ;AC000; are we at end of line? | ||
| 242 | pop dx ;AC000; get address of SRCXNAME | ||
| 243 | retz ;yes - return no error | ||
| 244 | NOARGERR: | ||
| 245 | mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer | ||
| 246 | XOR AX,AX | ||
| 247 | STC | ||
| 248 | return | ||
| 249 | |||
| 250 | break $Rmdir | ||
| 251 | |||
| 252 | assume ds:trangroup,es:trangroup | ||
| 253 | |||
| 254 | $RMDIR: | ||
| 255 | CALL SETRMMK | ||
| 256 | JC RmDirErr | ||
| 257 | JNZ BADRDERR | ||
| 258 | MOV AH,RMDIR | ||
| 259 | INT int_command | ||
| 260 | retnc | ||
| 261 | |||
| 262 | invoke get_ext_error_number ;AN022; get the extended error | ||
| 263 | cmp ax,error_path_not_found ;AN022; see if path not found | ||
| 264 | jz badrderr ;AN022; yes - issue old message | ||
| 265 | cmp ax,error_access_denied ;AN022; access denied? | ||
| 266 | jz badrderr ;AN022; yes - issue old message | ||
| 267 | |||
| 268 | call Set_Ext_Error_Subst ;AN022; | ||
| 269 | jmp short RmDirerr ;AC022; yes - go print it | ||
| 270 | |||
| 271 | BADRDERR: | ||
| 272 | MOV DX,OFFSET TRANGROUP:BADRMD_ptr | ||
| 273 | |||
| 274 | RmDirErr: | ||
| 275 | invoke STD_Eprintf | ||
| 276 | return | ||
| 277 | |||
| 278 | ;**************************************************************** | ||
| 279 | ;* | ||
| 280 | ;* ROUTINE: Set_ext_error_subst | ||
| 281 | ;* | ||
| 282 | ;* FUNCTION: Sets up substitution for extended error | ||
| 283 | ;* | ||
| 284 | ;* INPUT: AX - extended error number | ||
| 285 | ;* DX - offset of string | ||
| 286 | ;* | ||
| 287 | ;* OUTPUT: Extend_Buf_Ptr set up for STD_EPRINTF | ||
| 288 | ;* | ||
| 289 | ;**************************************************************** | ||
| 290 | |||
| 291 | Set_ext_error_subst proc near ;AN022; | ||
| 292 | |||
| 293 | mov msg_disp_class,ext_msg_class ;AN022; set up extended error msg class | ||
| 294 | mov string_ptr_2,dx ;AN022; get address of failed string | ||
| 295 | mov Extend_buf_sub,one_subst ;AN022; put number of subst in control block | ||
| 296 | mov dx,offset TranGroup:Extend_Buf_ptr ;AN022; get extended message pointer | ||
| 297 | mov Extend_Buf_ptr,ax ;AN022; get message number in control block | ||
| 298 | |||
| 299 | ret ;AN022; return | ||
| 300 | |||
| 301 | Set_ext_error_subst endp ;AN022; | ||
| 302 | |||
| 303 | |||
| 304 | |||
| 305 | |||
| 306 | |||
| 307 | Break <SavUDir - preserve the users current directory on a particular drive> | ||
| 308 | |||
| 309 | ; | ||
| 310 | ; SavUDir - move the user's current directory on a drive into UserDir1 | ||
| 311 | ; SavUDir1 - move the user's current directory on a drive into a specified | ||
| 312 | ; buffer | ||
| 313 | ; | ||
| 314 | ; Inputs: DL has 1-based drive number | ||
| 315 | ; ES:DI has destination buffer (SavUDir1 only) | ||
| 316 | ; Outputs: Carry Clear | ||
| 317 | ; DS = TranGroup | ||
| 318 | ; Carry Set | ||
| 319 | ; AX has error code | ||
| 320 | ; Registers Modified: AX, SI | ||
| 321 | ; | ||
| 322 | |||
| 323 | SAVUDIR: | ||
| 324 | MOV DI,OFFSET TRANGROUP:USERDIR1 | ||
| 325 | |||
| 326 | SAVUDIR1: | ||
| 327 | MOV AL,DL | ||
| 328 | ADD AL,'@' | ||
| 329 | CMP AL,'@' | ||
| 330 | JNZ GOTUDRV | ||
| 331 | ADD AL,[CURDRV] | ||
| 332 | INC AL ; A = 1 | ||
| 333 | |||
| 334 | GOTUDRV: | ||
| 335 | STOSB | ||
| 336 | MOV AH,[DIRCHAR] | ||
| 337 | MOV AL,':' | ||
| 338 | STOSW | ||
| 339 | PUSH ES | ||
| 340 | POP DS | ||
| 341 | ASSUME DS:NOTHING | ||
| 342 | |||
| 343 | MOV SI,DI | ||
| 344 | MOV AH,CURRENT_DIR ; Get the Directory Text | ||
| 345 | INT int_command | ||
| 346 | retc | ||
| 347 | PUSH CS | ||
| 348 | POP DS | ||
| 349 | ASSUME DS:TRANGROUP | ||
| 350 | |||
| 351 | return | ||
| 352 | |||
| 353 | |||
| 354 | CRLF2: | ||
| 355 | PUSH DX | ||
| 356 | MOV DX,OFFSET TRANGROUP:ACRLF_ptr | ||
| 357 | |||
| 358 | PR: | ||
| 359 | PUSH DS | ||
| 360 | PUSH CS | ||
| 361 | POP DS | ||
| 362 | invoke std_printf | ||
| 363 | POP DS | ||
| 364 | POP DX | ||
| 365 | |||
| 366 | return | ||
| 367 | |||
| 368 | ; | ||
| 369 | ; These routines (SCANOFF, DELIM) are called in batch processing when DS | ||
| 370 | ; may NOT be TRANGROUP | ||
| 371 | ; | ||
| 372 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 373 | |||
| 374 | SCANOFF: | ||
| 375 | LODSB | ||
| 376 | CALL DELIM | ||
| 377 | JZ SCANOFF | ||
| 378 | DEC SI ; Point to first non-delimiter | ||
| 379 | return | ||
| 380 | |||
| 381 | ; | ||
| 382 | ; Input: AL is character to classify | ||
| 383 | ; Output: Z set if delimiter | ||
| 384 | ; NZ set otherwise | ||
| 385 | ; Registers modified: none | ||
| 386 | ; | ||
| 387 | |||
| 388 | DELIM: | ||
| 389 | CMP AL,' ' | ||
| 390 | retz | ||
| 391 | CMP AL,'=' | ||
| 392 | retz | ||
| 393 | CMP AL,',' | ||
| 394 | retz | ||
| 395 | CMP AL,';' | ||
| 396 | retz | ||
| 397 | CMP AL,9 ; Check for TAB character | ||
| 398 | retz | ||
| 399 | CMP AL,0ah ; Check for line feed character - BAS | ||
| 400 | return | ||
| 401 | |||
| 402 | |||
| 403 | ASSUME DS:TRANGROUP,ES:TRANGROUP | ||
| 404 | |||
| 405 | |||
| 406 | FCB_TO_ASCZ: ; Convert DS:SI to ASCIZ ES:DI | ||
| 407 | MOV CX,8 | ||
| 408 | |||
| 409 | MAINNAME: | ||
| 410 | LODSB | ||
| 411 | CMP AL,' ' | ||
| 412 | JZ SKIPSPC | ||
| 413 | STOSB | ||
| 414 | |||
| 415 | SKIPSPC: | ||
| 416 | LOOP MAINNAME | ||
| 417 | LODSB | ||
| 418 | CMP AL,' ' | ||
| 419 | JZ GOTNAME | ||
| 420 | MOV AH,AL | ||
| 421 | MOV AL,dot_chr | ||
| 422 | STOSB | ||
| 423 | XCHG AL,AH | ||
| 424 | STOSB | ||
| 425 | MOV CL,2 | ||
| 426 | |||
| 427 | EXTNAME: | ||
| 428 | LODSB | ||
| 429 | CMP AL,' ' | ||
| 430 | JZ GOTNAME | ||
| 431 | STOSB | ||
| 432 | LOOP EXTNAME | ||
| 433 | |||
| 434 | GOTNAME: | ||
| 435 | XOR AL,AL | ||
| 436 | STOSB | ||
| 437 | return | ||
| 438 | |||
| 439 | STRCOMP: | ||
| 440 | ; | ||
| 441 | ; Compare ASCIZ DS:SI with ES:DI. | ||
| 442 | ; SI,DI destroyed. | ||
| 443 | ; | ||
| 444 | CMPSB | ||
| 445 | retnz ; Strings not equal | ||
| 446 | cmp byte ptr [SI-1],0 ; Hit NUL terminator? | ||
| 447 | retz ; Yes, strings equal | ||
| 448 | jmp short STRCOMP ; Equal so far, keep going | ||
| 449 | |||
| 450 | |||
| 451 | CRPRINT: | ||
| 452 | PUSH AX | ||
| 453 | MOV AL,13 | ||
| 454 | PUSH CX | ||
| 455 | PUSH DI | ||
| 456 | MOV DI,DX | ||
| 457 | MOV CX,-1 | ||
| 458 | PUSH ES | ||
| 459 | PUSH DS | ||
| 460 | POP ES | ||
| 461 | |||
| 462 | REPNZ SCASB ; LOOK FOR TERMINATOR | ||
| 463 | mov byte ptr [di-1],0 ; nul terminate the string | ||
| 464 | POP ES | ||
| 465 | mov string_ptr_2,dx | ||
| 466 | mov dx,offset trangroup:string_buf_ptr | ||
| 467 | invoke std_printf | ||
| 468 | mov ds:byte ptr [di-1],13 ; now put the CR back | ||
| 469 | JC ERROR_OUTPUT | ||
| 470 | |||
| 471 | POP DI | ||
| 472 | POP CX | ||
| 473 | POP AX | ||
| 474 | |||
| 475 | return | ||
| 476 | |||
| 477 | ERROR_OUTPUT: | ||
| 478 | PUSH CS | ||
| 479 | POP DS | ||
| 480 | ASSUME DS:TRANGROUP | ||
| 481 | MOV ES,[RESSEG] | ||
| 482 | ASSUME ES:RESGROUP | ||
| 483 | |||
| 484 | MOV DX,OFFSET TRANGROUP:NOSPACE_ptr | ||
| 485 | CMP [PIPEFLAG],0 | ||
| 486 | JZ GO_TO_ERROR | ||
| 487 | |||
| 488 | invoke PipeOff | ||
| 489 | MOV DX,OFFSET TRANGROUP:PIPEEMES_ptr | ||
| 490 | GO_TO_ERROR: | ||
| 491 | JMP CERROR | ||
| 492 | |||
| 493 | ASSUME DS:TRANGROUP,ES:TRANGROUP | ||
| 494 | |||
| 495 | PATHCHRCMP: | ||
| 496 | ;---- Mod for path invocation ---- | ||
| 497 | PUBLIC pathchrcmp | ||
| 498 | ;---- | ||
| 499 | |||
| 500 | push ax | ||
| 501 | mov ah,'/' | ||
| 502 | CMP [SWITCHAR],ah | ||
| 503 | JZ NOSLASHT | ||
| 504 | CMP AL,'/' | ||
| 505 | jz pccont | ||
| 506 | |||
| 507 | NOSLASHT: | ||
| 508 | CMP AL,'\' | ||
| 509 | pccont: | ||
| 510 | pop ax | ||
| 511 | |||
| 512 | return | ||
| 513 | |||
| 514 | ; Drive taken from FCB | ||
| 515 | ; User dir saved in userdir1 | ||
| 516 | ; | ||
| 517 | ; Zero set if path dir, CHDIR to this dir, FCB filled with ? | ||
| 518 | ; NZ set if path/file, CHDIR to file, FCB has file (parsed fill ' ') | ||
| 519 | ; [DESTTAIL] points to parse point | ||
| 520 | ; Carry set if no CHDIRs worked, FCB not altered. | ||
| 521 | ; DESTISDIR set non zero if PATHCHRs in path (via SETPATH) | ||
| 522 | ; | ||
| 523 | PATHCRUNCH: | ||
| 524 | mov [msg_numb],0 ;AN022; Set up message flag | ||
| 525 | MOV DL,DS:[FCB] | ||
| 526 | CALL SAVUDIR | ||
| 527 | jc pcrunch_cderrJ ;AN022; if error on current dir - report | ||
| 528 | |||
| 529 | invoke SETPATH | ||
| 530 | TEST [DESTINFO],2 | ||
| 531 | JNZ TRYPEEL ; If ? or * cannot be pure dir | ||
| 532 | |||
| 533 | MOV AH,CHDIR | ||
| 534 | INT int_command | ||
| 535 | jnc chdir_worked ;AN022; no error - continue | ||
| 536 | |||
| 537 | invoke get_ext_error_number ;AN022; get the extended error | ||
| 538 | cmp ax,error_path_not_found ;AN022; if path not found | ||
| 539 | jz trypeel ;AC022; keep trying | ||
| 540 | cmp ax,error_access_denied ;AN022; if access denied | ||
| 541 | jz trypeel ;AC022; keep trying | ||
| 542 | mov [msg_numb],ax ;AN022; set up message flag | ||
| 543 | jmp peelfail ;AN022; exit with other error | ||
| 544 | |||
| 545 | chdir_worked: | ||
| 546 | invoke SETREST1 | ||
| 547 | MOV AL,'?' ; *.* is default file spec if pure dir | ||
| 548 | MOV DI,5DH | ||
| 549 | MOV CX,11 | ||
| 550 | REP STOSB | ||
| 551 | XOR AL,AL ; Set zero | ||
| 552 | return | ||
| 553 | |||
| 554 | pcrunch_cderrj: ;AN022; need this for long jmp | ||
| 555 | jmp pcrunch_cderr ;AN022; | ||
| 556 | |||
| 557 | TRYPEEL: | ||
| 558 | MOV SI,[PATHPOS] | ||
| 559 | DEC SI ; Point at NUL | ||
| 560 | MOV AL,[SI-1] | ||
| 561 | |||
| 562 | CMP [KPARSE],0 | ||
| 563 | JNZ DELSTRT ; Last char is second KANJI byte, might be '\' | ||
| 564 | |||
| 565 | CALL PATHCHRCMP | ||
| 566 | JZ PEELFAIL ; Trailing '/' | ||
| 567 | |||
| 568 | DELSTRT: | ||
| 569 | MOV CX,SI | ||
| 570 | MOV SI,DX | ||
| 571 | PUSH DX | ||
| 572 | DELLOOP: | ||
| 573 | CMP SI,CX | ||
| 574 | JZ GOTDELE | ||
| 575 | LODSB | ||
| 576 | invoke TESTKANJ | ||
| 577 | JZ NOTKANJ8 | ||
| 578 | INC SI | ||
| 579 | JMP DELLOOP | ||
| 580 | |||
| 581 | NOTKANJ8: | ||
| 582 | CALL PATHCHRCMP | ||
| 583 | JNZ DELLOOP | ||
| 584 | MOV DX,SI | ||
| 585 | DEC DX | ||
| 586 | JMP DELLOOP | ||
| 587 | |||
| 588 | GOTDELE: | ||
| 589 | MOV SI,DX | ||
| 590 | POP DX | ||
| 591 | CMP SI,DX | ||
| 592 | JZ BADRET | ||
| 593 | MOV CX,SI | ||
| 594 | MOV SI,DX | ||
| 595 | DELLOOP2: ; Set value of KPARSE | ||
| 596 | CMP SI,CX | ||
| 597 | JZ TRYCD | ||
| 598 | MOV [KPARSE],0 | ||
| 599 | LODSB | ||
| 600 | INVOKE TESTKANJ | ||
| 601 | JZ DELLOOP2 | ||
| 602 | INC SI | ||
| 603 | INC [KPARSE] | ||
| 604 | JMP DELLOOP2 | ||
| 605 | |||
| 606 | TRYCD: | ||
| 607 | push ax | ||
| 608 | mov al,dot_chr | ||
| 609 | CMP BYTE PTR [SI+1],al | ||
| 610 | pop ax | ||
| 611 | JZ PEELFAIL ; If . or .., pure cd should have worked | ||
| 612 | mov al,[si-1] | ||
| 613 | CMP al,':' ; Special case d:\file | ||
| 614 | JZ BADRET | ||
| 615 | |||
| 616 | CMP [KPARSE],0 | ||
| 617 | JNZ NOTDOUBLESL ; Last char is second KANJI byte, might be '\' | ||
| 618 | |||
| 619 | CALL PATHCHRCMP | ||
| 620 | JNZ NOTDOUBLESL | ||
| 621 | PEELFAIL: | ||
| 622 | STC ; // | ||
| 623 | return | ||
| 624 | NOTDOUBLESL: | ||
| 625 | MOV BYTE PTR [SI],0 | ||
| 626 | MOV AH,CHDIR | ||
| 627 | INT int_command | ||
| 628 | JNC CDSUCC | ||
| 629 | pcrunch_cderr: | ||
| 630 | invoke get_ext_error_number ;AN022; get the extended error | ||
| 631 | mov [msg_numb],ax ;AN022; set up message flag | ||
| 632 | or si,si ;AN022; set up zero flag to not zero | ||
| 633 | stc ;AN022; set up carry flag | ||
| 634 | return | ||
| 635 | |||
| 636 | BADRET: | ||
| 637 | MOV AL,[SI] | ||
| 638 | CALL PATHCHRCMP ; Special case 'DIRCHAR'file | ||
| 639 | STC | ||
| 640 | retnz | ||
| 641 | XOR BL,BL | ||
| 642 | XCHG BL,[SI+1] | ||
| 643 | MOV AH,CHDIR | ||
| 644 | INT int_command | ||
| 645 | jc pcrunch_cderr ;AN022; go to error exit | ||
| 646 | MOV [SI+1],BL | ||
| 647 | CDSUCC: | ||
| 648 | invoke SETREST1 | ||
| 649 | INC SI ; Reset zero | ||
| 650 | MOV [DESTTAIL],SI | ||
| 651 | pushf ;AN015; save flags | ||
| 652 | cmp dirflag,-1 ;AN015; don't do parse if in DIR | ||
| 653 | jz pcrunch_end ;AN015; | ||
| 654 | MOV DI,FCB | ||
| 655 | MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 02H ; Parse with default drive | ||
| 656 | INT int_command | ||
| 657 | pcrunch_end: | ||
| 658 | popf ;AN015; get flags back | ||
| 659 | return | ||
| 660 | |||
| 661 | trancode ends | ||
| 662 | end | ||
| 663 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/COMMAND/TFOR.ASM b/v4.0/src/CMD/COMMAND/TFOR.ASM new file mode 100644 index 0000000..8454d5c --- /dev/null +++ b/v4.0/src/CMD/COMMAND/TFOR.ASM | |||
| @@ -0,0 +1,551 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)tfor.asm 4.1 85/09/17 | ||
| 3 | ; SCCSID = @(#)tfor.asm 4.1 85/09/17 | ||
| 4 | TITLE Part3 COMMAND Transient Routines | ||
| 5 | |||
| 6 | ; For loop processing routines | ||
| 7 | |||
| 8 | |||
| 9 | .xlist | ||
| 10 | .xcref | ||
| 11 | include comsw.asm | ||
| 12 | INCLUDE DOSSYM.INC | ||
| 13 | INCLUDE DEVSYM.INC | ||
| 14 | include comseg.asm | ||
| 15 | include comequ.asm | ||
| 16 | .list | ||
| 17 | .cref | ||
| 18 | |||
| 19 | |||
| 20 | DATARES SEGMENT PUBLIC BYTE ;AC000; | ||
| 21 | EXTRN BATCH:WORD | ||
| 22 | EXTRN ECHOFLAG:BYTE | ||
| 23 | EXTRN FORFLAG:BYTE | ||
| 24 | EXTRN FORPTR:WORD | ||
| 25 | EXTRN NEST:WORD | ||
| 26 | EXTRN NULLFLAG:BYTE | ||
| 27 | EXTRN PIPEFILES:BYTE | ||
| 28 | EXTRN SINGLECOM:WORD | ||
| 29 | DATARES ENDS | ||
| 30 | |||
| 31 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 32 | EXTRN Extend_buf_ptr:word ;AN000; | ||
| 33 | extrn fornestmes_ptr:word | ||
| 34 | EXTRN msg_disp_class:byte ;AN000; | ||
| 35 | extrn string_buf_ptr:word | ||
| 36 | TRANDATA ENDS | ||
| 37 | |||
| 38 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 39 | extrn arg:byte ; the arg structure! | ||
| 40 | EXTRN COMBUF:BYTE | ||
| 41 | EXTRN RESSEG:WORD | ||
| 42 | EXTRN string_ptr_2:word | ||
| 43 | TRANSPACE ENDS | ||
| 44 | |||
| 45 | TRANCODE SEGMENT PUBLIC BYTE | ||
| 46 | |||
| 47 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 48 | |||
| 49 | EXTRN cerror:near | ||
| 50 | EXTRN docom:near | ||
| 51 | EXTRN docom1:near | ||
| 52 | EXTRN forerror:near | ||
| 53 | EXTRN tcommand:near | ||
| 54 | |||
| 55 | PUBLIC $for | ||
| 56 | PUBLIC forproc | ||
| 57 | |||
| 58 | |||
| 59 | ; All batch proccessing has DS set to segment of resident portion | ||
| 60 | ASSUME DS:RESGROUP,ES:TRANGROUP | ||
| 61 | |||
| 62 | |||
| 63 | FORTERM: | ||
| 64 | push cs ;AN037; Get local segment into | ||
| 65 | pop ds ;AN037; DS, ES | ||
| 66 | push cs ;AN037; | ||
| 67 | pop es ;AN037; | ||
| 68 | call ForOff | ||
| 69 | mov ds,ResSeg | ||
| 70 | ASSUME DS:RESGROUP | ||
| 71 | CMP [SINGLECOM],0FF00H | ||
| 72 | JNZ BATCRLF | ||
| 73 | CMP NEST,0 ;G See if we have nested batch files | ||
| 74 | JNZ BATCRLF ;G Yes - don't exit just yet | ||
| 75 | MOV [SINGLECOM],-1 ; Cause a terminate | ||
| 76 | JMP SHORT NOFORP2 | ||
| 77 | |||
| 78 | BATCRLF: | ||
| 79 | test [ECHOFLAG],1 ;G Is echo on? | ||
| 80 | JZ NOFORP2 ;G no - exit | ||
| 81 | TEST [BATCH], -1 ;G print CRLF if in batch | ||
| 82 | JZ NOFORP2 ;G | ||
| 83 | invoke CRLF2 | ||
| 84 | |||
| 85 | NOFORP2: | ||
| 86 | JMP TCOMMAND | ||
| 87 | |||
| 88 | |||
| 89 | ;------ | ||
| 90 | ; For-loop processing. For loops are of the form: | ||
| 91 | ; for %<loop-variable> in (<list>) do <command> | ||
| 92 | ; where <command> may contain references of the form %<variable>, which are | ||
| 93 | ; later substituted with the items in <list>. The for-loop structure is | ||
| 94 | ; set-up by the procedure '$for'; successive calls to 'forproc' execute | ||
| 95 | ; <command> once for each item in <list>. All of the information needed for | ||
| 96 | ; loop processing is stored on a piece of memory gotten from 'alloc'. This | ||
| 97 | ; structure is actually fairly large, on the order of 700 bytes, and includes | ||
| 98 | ; a complete copy of the original command-line structure as parsed by | ||
| 99 | ; 'parseline', loop control variables, and a dma buffer for the | ||
| 100 | ; 'FindFirst/FindNext' expansion of wildcard filenames in <list>. When loop | ||
| 101 | ; processing has completed, this chunk of memory is returned to the system. | ||
| 102 | ; | ||
| 103 | ; All of the previously defined variables, in 'datares', used for loop | ||
| 104 | ; processing may be erased. Only one, (DW) ForPtr, need be allocated. | ||
| 105 | ; | ||
| 106 | ; The error message, 'for_alloc_mes', should be moved into the file | ||
| 107 | ; containing all of the other error messages. | ||
| 108 | ; | ||
| 109 | ; Referencing the allocated for-loop structure is a little tricky. | ||
| 110 | ; At the moment, a byte is defined as part of a new segment, 'for_segment'. | ||
| 111 | ; When 'forproc' actually runs, ES and DS are set to point to the base of the | ||
| 112 | ; new chunk of memory. References to this byte, 'f', thus assemble correctly | ||
| 113 | ; as offsets of ES or DS. 'f' would not be necessary, except that the | ||
| 114 | ; assembler translates an instruction such as 'mov AX, [for_minarg]' as an | ||
| 115 | ; immediate move of the offset of 'for_minarg' into AX. In other words, in | ||
| 116 | ; terms of PDP-11 mnemonics, the assembler ACTUALLY assembles | ||
| 117 | ; mov AX, #for_minarg ; AX := 02CA (for example) | ||
| 118 | ; instead of | ||
| 119 | ; mov AX, for_minarg ; AX := [02CA] (contents of 02CA) | ||
| 120 | ; By using 'f', we pretend that we are actually referencing an allocated | ||
| 121 | ; structure, and the assembler coughs up the code we want. Notice that it | ||
| 122 | ; doesn't matter whether we put brackets around the location or not -- the | ||
| 123 | ; assembler is "smart" enough to know that we want an address instead of the | ||
| 124 | ; contents of that location. | ||
| 125 | ; | ||
| 126 | ; Finally, there now exists the potential to easily implement nested loops. | ||
| 127 | ; One method would be to have a link field in each for-structure pointing to | ||
| 128 | ; its parent. Variable references that couldn't be resolved in the local | ||
| 129 | ; frame would cause a search of prior frames. For-structures would still be | ||
| 130 | ; allocated and released in exactly the same fashion. The only limit on the | ||
| 131 | ; number of nested loops would be memory size (although at 700 bytes a pop, | ||
| 132 | ; memory wouldn't last THAT long). Alternately, a small structure could be | ||
| 133 | ; maintained in the resident data area. This structure would be an array of | ||
| 134 | ; control-variable names and pointers to for-structure blocks. This would | ||
| 135 | ; greatly speed up the resolution of non-local variable references. However, | ||
| 136 | ; since space in the resident is precious, we would have to compromise on a | ||
| 137 | ; "reasonable" level of nesting -- 10, 16, 32 levels, whatever. For-structure | ||
| 138 | ; allocation and de-allocation would have to be modified slightly to take this | ||
| 139 | ; new structure into account. | ||
| 140 | ; | ||
| 141 | ; Oops, just one more thing. Forbuf need not be a part of the for-structure. | ||
| 142 | ; It could just as well be one structure allocated in 'transpace'. Actually, | ||
| 143 | ; it may be easier to allocate it as part of 'for_segment'. | ||
| 144 | ;------ | ||
| 145 | |||
| 146 | include fordata.asm | ||
| 147 | |||
| 148 | $for_exit: | ||
| 149 | jmp forterm ; exceeding maxarg means all done | ||
| 150 | |||
| 151 | forproc: | ||
| 152 | assume DS:resgroup | ||
| 153 | mov AX, [ForPtr] | ||
| 154 | mov DS, AX | ||
| 155 | mov ES, AX ; operate in for-info area | ||
| 156 | assume DS:for_segment, ES:for_segment | ||
| 157 | |||
| 158 | mov DX, OFFSET fordma | ||
| 159 | trap Set_Dma | ||
| 160 | for_begin: | ||
| 161 | cmp f.for_expand, 0 ; non-zero for_expand equals FALSE | ||
| 162 | je for_begin1 | ||
| 163 | inc f.for_minarg | ||
| 164 | for_begin1: | ||
| 165 | mov BX, f.for_minarg ; current item in <list> to examine | ||
| 166 | cmp BX, f.for_maxarg | ||
| 167 | jg $for_exit ; exceeding maxarg means all done | ||
| 168 | mov AX, OFFSET for_args.argv | ||
| 169 | invoke argv_calc ; compute argv[x] address | ||
| 170 | |||
| 171 | mov CX, [BX].argstartel | ||
| 172 | mov DX, [BX].argpointer | ||
| 173 | test [bx].argflags,00000100b ; Is there a path separator in this arg? | ||
| 174 | jnz forsub ; Yes, argstartel should be correct | ||
| 175 | mov si, [BX].argpointer | ||
| 176 | mov al,lparen | ||
| 177 | cmp byte ptr [si-1],al ; If the current token is the first | ||
| 178 | jnz forsub ; one in the list and originally had | ||
| 179 | inc cx ; the opening paren as its first char, | ||
| 180 | ; the argstartel ptr needs to be | ||
| 181 | ; advanced passed it before the prefix | ||
| 182 | ; length is computed. | ||
| 183 | mov al,':' | ||
| 184 | cmp byte ptr [si+1],al ; If the token begins with "(d:", | ||
| 185 | jnz forsub ; argstartel has to be moved over the | ||
| 186 | add cx,2 ; rest of the prefix as well. | ||
| 187 | |||
| 188 | forsub: | ||
| 189 | sub CX, DX ; compute length of pathname prefix | ||
| 190 | cmp f.for_expand, 0 ; are we still expanding a name? | ||
| 191 | je for_find_next ; if so, get next matching filename | ||
| 192 | |||
| 193 | test [BX].argflags, MASK wildcard | ||
| 194 | jnz for_find_first ; should we expand THIS (new) arg? | ||
| 195 | mov CX, [BX].arglen ; else, just copy all of it directly | ||
| 196 | jmp for_smoosh | ||
| 197 | |||
| 198 | for_find_first: | ||
| 199 | PUSH CX | ||
| 200 | XOR CX,CX | ||
| 201 | trap Find_First ; and search for first filename match | ||
| 202 | POP CX | ||
| 203 | jmp for_result | ||
| 204 | for_find_next: | ||
| 205 | trap Find_Next ; search for next filename match | ||
| 206 | |||
| 207 | for_result: | ||
| 208 | mov AX, -1 ; assume worst case | ||
| 209 | jc forCheck | ||
| 210 | mov ax,0 | ||
| 211 | forCheck: ; Find* returns 0 for SUCCESS | ||
| 212 | mov f.FOR_EXPAND, AX ; record success of findfirst/next | ||
| 213 | or AX, AX ; anything out there? | ||
| 214 | jnz for_begin ; if not, try next arg | ||
| 215 | |||
| 216 | for_smoosh: | ||
| 217 | mov SI, [BX].argpointer ; copy argv[arg][0,CX] into destbuf | ||
| 218 | mov DI, OFFSET forbuf ; some days this will be the entire | ||
| 219 | rep movsb ; arg, some days just the path prefix | ||
| 220 | |||
| 221 | cmp f.FOR_EXPAND, 0 ; if we're not expanding, we can | ||
| 222 | jnz for_make_com ; skip the following | ||
| 223 | |||
| 224 | mov SI, OFFSET fordma.find_buf_pname | ||
| 225 | for_more: ; tack on matching filename | ||
| 226 | cmp BYTE PTR [SI], 0 | ||
| 227 | je for_make_com | ||
| 228 | movsb | ||
| 229 | jnz for_more | ||
| 230 | |||
| 231 | for_make_com: | ||
| 232 | xor AL, AL ; tack a null byte onto the end | ||
| 233 | stosb ; of the substitute string | ||
| 234 | |||
| 235 | xor CX, CX ; character count for command line | ||
| 236 | not CX ; negate it -- take advantage of loopnz | ||
| 237 | xor BX, BX ; argpointer | ||
| 238 | mov DI, OFFSET TRANGROUP:COMBUF+2 | ||
| 239 | mov bl, f.FOR_COM_START ; argindex | ||
| 240 | mov DH, f.FOR_VAR ; %<for-var> is replaced by [forbuf] | ||
| 241 | ; time to form the <command> string | ||
| 242 | push CS | ||
| 243 | pop ES | ||
| 244 | assume ES:trangroup | ||
| 245 | |||
| 246 | mov AX, OFFSET for_args ; translate offset to pointer | ||
| 247 | invoke argv_calc | ||
| 248 | mov si,[bx].arg_ocomptr | ||
| 249 | inc si ; mov ptr passed beginning space | ||
| 250 | |||
| 251 | for_make_loop: | ||
| 252 | mov al,[si] ; the <command> arg, byte by byte | ||
| 253 | inc si | ||
| 254 | cmp AL,'%' ; looking for %<control-variable> | ||
| 255 | jne for_stosb ; no % ... add byte to string | ||
| 256 | cmp BYTE PTR [SI], DH ; got the right <variable>? | ||
| 257 | jne for_stosb ; got a %, but wrong <variable> | ||
| 258 | inc SI ; skip over <for-variable> | ||
| 259 | |||
| 260 | push SI | ||
| 261 | mov SI, OFFSET forbuf ; substitute the <item> for <variable> | ||
| 262 | ; to make a final <command> to execute | ||
| 263 | sloop: | ||
| 264 | lodsb ; grab all those <item> bytes, and | ||
| 265 | stosb ; add 'em to the <command> string, | ||
| 266 | or AL, AL ; until we run into a null | ||
| 267 | loopnz sloop | ||
| 268 | dec DI ; adjust length and <command> pointer | ||
| 269 | inc CX ; so we can overwrite the null | ||
| 270 | |||
| 271 | pop SI | ||
| 272 | jmp for_make_loop ; got back for more <command> bytes | ||
| 273 | for_stosb: | ||
| 274 | stosb ; take a byte from the <command> arg | ||
| 275 | dec CX ; and put it into the <command> to be | ||
| 276 | ; executed (and note length, too) | ||
| 277 | cmp al,0dh ; If not done, loop. | ||
| 278 | jne for_make_loop | ||
| 279 | |||
| 280 | for_made_com: ; finished all the <command> args | ||
| 281 | not CL ; compute and record command length | ||
| 282 | mov [COMBUF+1], CL | ||
| 283 | |||
| 284 | mov DS, [RESSEG] | ||
| 285 | assume DS:resgroup | ||
| 286 | |||
| 287 | test [ECHOFLAG],1 ; shall we echo this <command>, dearie? | ||
| 288 | jz noecho3 | ||
| 289 | cmp nullflag,nullcommand ;G was there a command last time? | ||
| 290 | jz No_crlf_pr ;G no - don't print crlf | ||
| 291 | invoke CRLF2 ;G Print out prompt | ||
| 292 | |||
| 293 | no_crlf_pr: | ||
| 294 | mov nullflag,0 ;G reset no command flag | ||
| 295 | push CS | ||
| 296 | pop DS | ||
| 297 | assume DS:trangroup | ||
| 298 | push di | ||
| 299 | invoke PRINT_PROMPT ;G Prompt the user | ||
| 300 | pop di | ||
| 301 | mov BYTE PTR ES:[DI-1],0 ; yeah, PRINT it out... | ||
| 302 | mov string_ptr_2,OFFSET TRANGROUP:COMBUF+2 | ||
| 303 | mov dx,offset trangroup:string_buf_ptr | ||
| 304 | invoke std_printf | ||
| 305 | mov BYTE PTR ES:[DI-1], 0DH | ||
| 306 | jmp DoCom | ||
| 307 | noecho3: ; run silent, run deep... | ||
| 308 | assume DS:resgroup | ||
| 309 | mov nullflag,0 ;G reset no command flag | ||
| 310 | push CS | ||
| 311 | pop DS | ||
| 312 | assume DS:trangroup | ||
| 313 | jmp docom1 | ||
| 314 | |||
| 315 | |||
| 316 | fornesterrj: ; no multi-loop processing... yet! | ||
| 317 | assume ES:resgroup | ||
| 318 | call ForOff | ||
| 319 | jmp fornesterr | ||
| 320 | |||
| 321 | forerrorj: | ||
| 322 | jmp forerror | ||
| 323 | |||
| 324 | break $For | ||
| 325 | assume ds:trangroup,es:trangroup | ||
| 326 | |||
| 327 | $for: | ||
| 328 | mov ES, [RESSEG] | ||
| 329 | assume ES:resgroup | ||
| 330 | |||
| 331 | cmp ForFlag,0 ; is another one already running? | ||
| 332 | jnz fornesterrj ; if flag is set.... boom! | ||
| 333 | |||
| 334 | ; | ||
| 335 | ; Turn off any pipes in progress. | ||
| 336 | ; | ||
| 337 | cmp [PIPEFILES],0 ; Only turn off if present. | ||
| 338 | jz NoPipe | ||
| 339 | invoke PipeDel | ||
| 340 | NoPipe: | ||
| 341 | xor DX, DX ; counter (0 <= DX < argvcnt) | ||
| 342 | call nextarg ; move to next argv[n] | ||
| 343 | jc forerrorj ; no more args -- bad forloop | ||
| 344 | cmp AL,'%' ; next arg MUST start with '%'... | ||
| 345 | jne forerrorj | ||
| 346 | mov BP, AX ; save forloop variable | ||
| 347 | lodsb | ||
| 348 | or AL, AL ; and MUST end immediately... | ||
| 349 | jne forerrorj | ||
| 350 | |||
| 351 | call nextarg ; let's make sure the next arg is 'in' | ||
| 352 | jc forerrorj | ||
| 353 | and AX, NOT 2020H ; uppercase the letters | ||
| 354 | cmp AX, in_word | ||
| 355 | jne forerrorj | ||
| 356 | lodsb | ||
| 357 | or AL, AL ; it, too, must end right away | ||
| 358 | je CheckLParen | ||
| 359 | ; | ||
| 360 | ; Not null. Perhaps there are no spaces between this and the (: | ||
| 361 | ; FOR %i in(foo bar... | ||
| 362 | ; Check for the Lparen here | ||
| 363 | ; | ||
| 364 | CMP AL,lparen | ||
| 365 | JNZ forerrorj | ||
| 366 | ; | ||
| 367 | ; The token was in(... We strip off the "in" part to simulate a separator | ||
| 368 | ; being there in the first place. | ||
| 369 | ; | ||
| 370 | ADD [BX].argpointer,2 ; advance source pointer | ||
| 371 | ADD [BX].arg_ocomptr,2 ; advance original string | ||
| 372 | SUB [BX].arglen,2 ; decrement the appropriate length | ||
| 373 | ; | ||
| 374 | ; SI now points past the in(. Simulate a nextarg call that results in the | ||
| 375 | ; current value. | ||
| 376 | ; | ||
| 377 | MOV ax,[si-1] ; get lparen and next char | ||
| 378 | jmp short lpcheck | ||
| 379 | |||
| 380 | CheckLParen: | ||
| 381 | call nextarg ; lparen delimits beginning of <list> | ||
| 382 | jc forerrorj | ||
| 383 | lpcheck: | ||
| 384 | cmp al, lparen | ||
| 385 | jne forerrorj | ||
| 386 | cmp ah,0 | ||
| 387 | je for_paren_token | ||
| 388 | |||
| 389 | cmp ah, rparen ; special case: null list | ||
| 390 | jne for_list_not_empty | ||
| 391 | jmp forterm | ||
| 392 | |||
| 393 | for_list_not_empty: | ||
| 394 | inc [bx].argpointer ; Advance ptr past "(" | ||
| 395 | ; Adjust the rest of this argv entry | ||
| 396 | dec [bx].arglen ; to agree. | ||
| 397 | inc si ; Inc si so check for ")" works | ||
| 398 | jmp for_list | ||
| 399 | |||
| 400 | for_paren_token: | ||
| 401 | call nextarg ; what have we in our <list>? | ||
| 402 | jc forerrorj | ||
| 403 | cmp ax, nullrparen ; special case: null list | ||
| 404 | jne for_list | ||
| 405 | jmp forterm | ||
| 406 | |||
| 407 | forerrorjj: | ||
| 408 | jmp forerror | ||
| 409 | |||
| 410 | for_list: ; skip over rest of <list> | ||
| 411 | mov CX, DX ; first arg of <list> | ||
| 412 | skip_list: | ||
| 413 | add si,[bx].arglen | ||
| 414 | sub si,3 ; si = ptr to last char of token | ||
| 415 | mov al,rparen | ||
| 416 | cmp byte ptr [si],al ; Is this the last element in <list> | ||
| 417 | je for_end_list ; Yes, exit loop. | ||
| 418 | call nextarg ; No, get next arg <list> | ||
| 419 | jc forerrorjj ; If no more and no rparen, error. | ||
| 420 | jmp skip_list | ||
| 421 | for_end_list: | ||
| 422 | mov DI, DX ; record position of last arg in <list> | ||
| 423 | mov byte ptr [si],0 ; Zap the rparen | ||
| 424 | cmp ax,nullrparen ; Was this token only a rparen | ||
| 425 | jz for_do ; Yes, continue | ||
| 426 | inc di ; No, inc position of last arg | ||
| 427 | |||
| 428 | for_do: | ||
| 429 | call nextarg ; now we had BETTER find a 'do'... | ||
| 430 | jc forerrorjj | ||
| 431 | and AX, NOT 2020H ; uppercase the letters | ||
| 432 | cmp AX, do_word | ||
| 433 | jne forerrorjj | ||
| 434 | lodsb | ||
| 435 | or AL, AL ; and it had BETTER be ONLY a 'do'... | ||
| 436 | jne forerrorjj | ||
| 437 | |||
| 438 | call nextarg ; on to the beginning of <command> | ||
| 439 | jc forerrorjj ; null <command> not legal | ||
| 440 | |||
| 441 | push AX | ||
| 442 | push BX | ||
| 443 | push CX | ||
| 444 | push DX ; preserve registers against disaster | ||
| 445 | push DI | ||
| 446 | push SI | ||
| 447 | push BP | ||
| 448 | invoke FREE_TPA ; need to make free memory, first | ||
| 449 | ASSUME ES:RESGROUP | ||
| 450 | call ForOff | ||
| 451 | mov BX, SIZE for_info - SIZE arg_unit | ||
| 452 | invoke Save_Args ; extra bytes needed for for-info | ||
| 453 | pushf | ||
| 454 | mov [ForPtr], AX | ||
| 455 | invoke ALLOC_TPA ; ALLOC_TPA clobbers registers... | ||
| 456 | popf | ||
| 457 | pop BP | ||
| 458 | pop SI | ||
| 459 | pop DI | ||
| 460 | pop DX | ||
| 461 | pop CX | ||
| 462 | pop BX | ||
| 463 | pop AX | ||
| 464 | jc for_alloc_err | ||
| 465 | |||
| 466 | push ES ; save resgroup seg... | ||
| 467 | push [ForPtr] | ||
| 468 | pop ES | ||
| 469 | assume ES:for_segment ; make references to for-info segment | ||
| 470 | |||
| 471 | dec CX ; forproc wants min pointing before | ||
| 472 | dec DI ; first arg, max right at last one | ||
| 473 | mov f.for_minarg, CX | ||
| 474 | mov f.for_maxarg, DI | ||
| 475 | mov f.for_com_start, DL | ||
| 476 | mov f.for_expand, -1 ; non-zero means FALSE | ||
| 477 | mov AX, BP | ||
| 478 | mov f.for_var, AH | ||
| 479 | pop ES | ||
| 480 | assume ES:resgroup | ||
| 481 | |||
| 482 | inc [FORFLAG] | ||
| 483 | cmp [SINGLECOM], -1 | ||
| 484 | jnz for_ret | ||
| 485 | mov [SINGLECOM], 0FF00H | ||
| 486 | for_ret: | ||
| 487 | ret | ||
| 488 | |||
| 489 | for_alloc_err: | ||
| 490 | mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class | ||
| 491 | mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer | ||
| 492 | mov Extend_Buf_ptr,error_not_enough_memory ;AN000; get message number in control block | ||
| 493 | jmp cerror | ||
| 494 | |||
| 495 | nextarg: | ||
| 496 | inc DX ; next argv[n] | ||
| 497 | cmp DX, arg.argvcnt ; make sure we don't run off end | ||
| 498 | jge nextarg_err ; of argv[]... | ||
| 499 | mov BX, DX | ||
| 500 | mov AX, OFFSET TRANGROUP:arg.argv | ||
| 501 | invoke argv_calc ; convert array index to pointer | ||
| 502 | mov SI, [BX].argpointer ; load pointer to argstring | ||
| 503 | lodsw ; and load first two chars | ||
| 504 | clc | ||
| 505 | ret | ||
| 506 | nextarg_err: | ||
| 507 | stc | ||
| 508 | ret | ||
| 509 | |||
| 510 | |||
| 511 | ASSUME DS:TRANGROUP,ES:TRANGROUP | ||
| 512 | |||
| 513 | FORNESTERR: | ||
| 514 | PUSH DS | ||
| 515 | MOV DS,[RESSEG] | ||
| 516 | ASSUME DS:RESGROUP | ||
| 517 | MOV DX,OFFSET TRANGROUP:FORNESTMES_ptr | ||
| 518 | CMP [SINGLECOM],0FF00H | ||
| 519 | JNZ NOFORP3 | ||
| 520 | MOV [SINGLECOM],-1 ; Cause termination | ||
| 521 | NOFORP3: | ||
| 522 | POP DS | ||
| 523 | ASSUME DS:TRANGROUP | ||
| 524 | JMP CERROR | ||
| 525 | ; | ||
| 526 | ; General routine called to free the for segment. We also clear the forflag | ||
| 527 | ; too. Change no registers. | ||
| 528 | ; | ||
| 529 | PUBLIC ForOff | ||
| 530 | ForOff: | ||
| 531 | assume DS:NOTHING,ES:NOTHING | ||
| 532 | SaveReg <AX,ES> | ||
| 533 | mov es,ResSeg | ||
| 534 | assume es:ResGroup | ||
| 535 | mov AX,ForPtr | ||
| 536 | or ax,ax | ||
| 537 | jz FreeDone | ||
| 538 | push es | ||
| 539 | mov es,ax | ||
| 540 | mov ah,dealloc | ||
| 541 | int 21h | ||
| 542 | pop es | ||
| 543 | FreeDone: | ||
| 544 | mov ForPtr,0 | ||
| 545 | mov ForFlag,0 | ||
| 546 | RestoreReg <ES,AX> | ||
| 547 | return | ||
| 548 | |||
| 549 | trancode ends | ||
| 550 | end | ||
| 551 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/COMMAND/TMISC1.ASM b/v4.0/src/CMD/COMMAND/TMISC1.ASM new file mode 100644 index 0000000..4b55aac --- /dev/null +++ b/v4.0/src/CMD/COMMAND/TMISC1.ASM | |||
| @@ -0,0 +1,655 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)tmisc1.asm 4.1 85/09/22 | ||
| 3 | ; SCCSID = @(#)tmisc1.asm 4.1 85/09/22 | ||
| 4 | TITLE Part7 COMMAND Transient Routines | ||
| 5 | |||
| 6 | ; More misc routines | ||
| 7 | |||
| 8 | .xlist | ||
| 9 | .xcref | ||
| 10 | INCLUDE comsw.asm | ||
| 11 | INCLUDE DOSSYM.INC | ||
| 12 | INCLUDE comseg.asm | ||
| 13 | INCLUDE comequ.asm | ||
| 14 | .list | ||
| 15 | .cref | ||
| 16 | |||
| 17 | |||
| 18 | |||
| 19 | CODERES SEGMENT PUBLIC BYTE ;AC000; | ||
| 20 | EXTRN RSTACK:BYTE | ||
| 21 | CodeRes ENDS | ||
| 22 | |||
| 23 | DATARES SEGMENT PUBLIC BYTE ;AC000; | ||
| 24 | EXTRN CALL_FLAG:BYTE | ||
| 25 | EXTRN EchoFlag:BYTE | ||
| 26 | EXTRN EXEC_BLOCK:BYTE | ||
| 27 | EXTRN EXTCOM:BYTE | ||
| 28 | EXTRN PIPEFLAG:BYTE | ||
| 29 | EXTRN PIPEPTR:WORD | ||
| 30 | EXTRN PIPESTR:BYTE | ||
| 31 | EXTRN RESTDIR:BYTE | ||
| 32 | EXTRN RE_OUT_APP:BYTE | ||
| 33 | EXTRN RE_OUTSTR:BYTE | ||
| 34 | DATARES ENDS | ||
| 35 | |||
| 36 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 37 | EXTRN BADDRV_PTR:WORD | ||
| 38 | EXTRN BADNAM_PTR:WORD | ||
| 39 | EXTRN COMTAB:BYTE ;AC000; | ||
| 40 | EXTRN extend_buf_ptr:word ;AN000; | ||
| 41 | EXTRN msg_disp_class:byte ;AN000; | ||
| 42 | TRANDATA ENDS | ||
| 43 | |||
| 44 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 45 | EXTRN arg:byte ; the arg structure! | ||
| 46 | EXTRN APPEND_EXEC:BYTE ;AN041; | ||
| 47 | EXTRN CHKDRV:BYTE | ||
| 48 | EXTRN COMBUF:BYTE | ||
| 49 | EXTRN EXECPATH:BYTE | ||
| 50 | EXTRN EXEC_ADDR:DWORD | ||
| 51 | EXTRN FILTYP:BYTE | ||
| 52 | EXTRN IDLEN:BYTE | ||
| 53 | EXTRN KPARSE:BYTE ;AC000; | ||
| 54 | EXTRN PARM1:BYTE | ||
| 55 | EXTRN PARM2:BYTE | ||
| 56 | EXTRN PathPos:word | ||
| 57 | EXTRN RESSEG:WORD | ||
| 58 | EXTRN RE_INSTR:BYTE | ||
| 59 | EXTRN SPECDRV:BYTE | ||
| 60 | EXTRN SWITCHAR:BYTE | ||
| 61 | EXTRN switch_list:byte | ||
| 62 | EXTRN TRAN_TPA:WORD | ||
| 63 | |||
| 64 | IF IBM | ||
| 65 | EXTRN ROM_CALL:BYTE | ||
| 66 | EXTRN ROM_CS:WORD | ||
| 67 | EXTRN ROM_IP:WORD | ||
| 68 | ENDIF | ||
| 69 | |||
| 70 | TRANSPACE ENDS | ||
| 71 | |||
| 72 | TRANCODE SEGMENT PUBLIC byte | ||
| 73 | |||
| 74 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 75 | |||
| 76 | EXTRN APPEND_PARSE:NEAR ;AN010; | ||
| 77 | EXTRN BATCOM:NEAR | ||
| 78 | EXTRN DOCOM1:NEAR | ||
| 79 | EXTRN PIPEERRSYN:NEAR | ||
| 80 | EXTRN TCOMMAND:NEAR | ||
| 81 | |||
| 82 | IF IBM | ||
| 83 | EXTRN ROM_EXEC:NEAR | ||
| 84 | EXTRN ROM_SCAN:NEAR | ||
| 85 | ENDIF | ||
| 86 | |||
| 87 | PUBLIC CERROR | ||
| 88 | PUBLIC DRVBAD | ||
| 89 | PUBLIC EXTERNAL | ||
| 90 | PUBLIC FNDCOM | ||
| 91 | PUBLIC PRESCAN | ||
| 92 | PUBLIC SWITCH | ||
| 93 | |||
| 94 | |||
| 95 | ASSUME DS:TRANGROUP | ||
| 96 | |||
| 97 | ;--------------------------- | ||
| 98 | ; We can get rid of this switch processing code if we can take | ||
| 99 | ; care of the remaining two calls to switch, later in the file. | ||
| 100 | ; However, I have not checked whether or not any other files use | ||
| 101 | ; switch -- after all, it IS public! | ||
| 102 | ;--------------------------- | ||
| 103 | RETSW: | ||
| 104 | XCHG AX,BX ; Put switches in AX | ||
| 105 | return | ||
| 106 | |||
| 107 | SWITCH: | ||
| 108 | XOR BX,BX ; Initialize - no switches set | ||
| 109 | SWLOOP: | ||
| 110 | INVOKE SCANOFF ; Skip any delimiters | ||
| 111 | CMP AL,[SWITCHAR] ; Is it a switch specifier? | ||
| 112 | JNZ RETSW ; No -- we're finished | ||
| 113 | OR BX,fSwitch ; Indicate there is a switch specified | ||
| 114 | INC SI ; Skip over the switch character | ||
| 115 | INVOKE SCANOFF | ||
| 116 | CMP AL,0DH | ||
| 117 | JZ RETSW ; Oops | ||
| 118 | INC SI | ||
| 119 | ; Convert lower case input to upper case | ||
| 120 | INVOKE UPCONV | ||
| 121 | MOV DI,OFFSET TRANGROUP:switch_list | ||
| 122 | MOV CX,SWCOUNT | ||
| 123 | REPNE SCASB ; Look for matching switch | ||
| 124 | JNZ BADSW | ||
| 125 | MOV AX,1 | ||
| 126 | SHL AX,CL ; Set a bit for the switch | ||
| 127 | OR BX,AX | ||
| 128 | JMP SHORT SWLOOP | ||
| 129 | |||
| 130 | BADSW: | ||
| 131 | JMP SHORT SWLOOP | ||
| 132 | |||
| 133 | SWCOUNT EQU 5 ; Length of switch_list | ||
| 134 | |||
| 135 | DRVBAD: | ||
| 136 | MOV DX,OFFSET TRANGROUP:BADDRV_ptr | ||
| 137 | JMP CERROR | ||
| 138 | |||
| 139 | externalj: | ||
| 140 | jmp EXTERNAL | ||
| 141 | |||
| 142 | fndcom: ; search the internal command table | ||
| 143 | OR AL,AL ; Get real length of first arg | ||
| 144 | jz externalj ; If 0, it must begin with "\" so has | ||
| 145 | ; to be external. | ||
| 146 | ; barryf code starts here | ||
| 147 | |||
| 148 | IF IBM | ||
| 149 | call test_append ; see if APPEND installed | ||
| 150 | je contcom ; not loaded | ||
| 151 | |||
| 152 | append_internal: | ||
| 153 | mov cl,TRANGROUP:IDLEN | ||
| 154 | mov ch,0 | ||
| 155 | mov pathpos,cx | ||
| 156 | inc append_exec ;AN041; set APPEND to ON | ||
| 157 | |||
| 158 | invoke ioset ; re-direct the o'l io | ||
| 159 | |||
| 160 | mov SI, offset TRANGROUP:IDLEN ; address command name, DS already set | ||
| 161 | mov DX,-1 ; set invoke function | ||
| 162 | mov di,offset TRANGROUP:APPEND_PARSE;AN010; Get the entry point for PARSE for APPEND | ||
| 163 | mov AX,0AE01H | ||
| 164 | int 2FH ; execute command | ||
| 165 | cmp TRANGROUP:IDLEN,0 ; execute requested | ||
| 166 | jne contcom | ||
| 167 | jmp Cmd_done | ||
| 168 | |||
| 169 | contcom: ; continue with internal scan | ||
| 170 | ENDIF | ||
| 171 | |||
| 172 | ; barryf code ends here | ||
| 173 | |||
| 174 | mov DI, OFFSET TRANGROUP:COMTAB | ||
| 175 | XOR CX,CX | ||
| 176 | |||
| 177 | findcom: | ||
| 178 | mov SI, offset TRANGROUP:IDLEN+1 ; pointer to command argument | ||
| 179 | mov CL, [DI] ; load length of internal command | ||
| 180 | inc di ; advance past length | ||
| 181 | jcxz externalj ; if it's zero, we're out of internals | ||
| 182 | cmp CL, IDLEN ; that of the command argument | ||
| 183 | jnz abcd ; lengths not equal ==> strings not eq | ||
| 184 | MOV PathPos,CX ; store length of command | ||
| 185 | repz cmpsb | ||
| 186 | |||
| 187 | abcd: | ||
| 188 | lahf ; save the good ol' flags | ||
| 189 | add DI, CX ; skip over remaining internal, if any | ||
| 190 | mov AL, BYTE PTR [DI] ; load drive-check indicator byte (DCIB) | ||
| 191 | mov [CHKDRV], AL ; save command flag byte in chkdrv | ||
| 192 | inc DI ; increment DI (OK, OK, I'll stop) | ||
| 193 | mov BX, WORD PTR [DI] ; load internal command address | ||
| 194 | inc DI ; skip over the puppy | ||
| 195 | inc DI | ||
| 196 | sahf ; remember those flags? | ||
| 197 | jnz findcom ; well, if all the cmps worked... | ||
| 198 | ; | ||
| 199 | ; All messages get redirected. | ||
| 200 | ; | ||
| 201 | cmp append_exec,0 ;AN041; APPEND just executed? | ||
| 202 | jnz dont_set_io ;AN041; Yes - this junk is already set | ||
| 203 | invoke ioset ; re-direct the ol' i/o | ||
| 204 | |||
| 205 | dont_set_io: ;AN041; | ||
| 206 | invoke SETSTDINON ;AN026; turn on critical error on STDIN | ||
| 207 | invoke SETSTDOUTOFF ;AN026; turn off critical error on STDOUT | ||
| 208 | test [CHKDRV], fCheckDrive ; did we wanna check those drives? | ||
| 209 | jz nocheck | ||
| 210 | mov AL, [PARM1] ; parse_file_descriptor results tell | ||
| 211 | or AL, [PARM2] ; us whether those drives were OK | ||
| 212 | cmp AL, -1 | ||
| 213 | jnz nocheck | ||
| 214 | jmp drvbad | ||
| 215 | |||
| 216 | |||
| 217 | ; | ||
| 218 | ; The user may have omitted the space between the command and its arguments. | ||
| 219 | ; We need to copy the remainder of the user's command line into the buffer. | ||
| 220 | ; Note that thisdoes not screw up the arg structure; it points into COMBUF not | ||
| 221 | ; into the command line at 80. | ||
| 222 | ; | ||
| 223 | nocheck: | ||
| 224 | call cmd_copy | ||
| 225 | |||
| 226 | switcheck: | ||
| 227 | test [CHKDRV], fSwitchAllowed ; Does the command take switches | ||
| 228 | jnz realwork ; Yes, process the command | ||
| 229 | call noswit ; No, check to see if any switches | ||
| 230 | jnz realwork ; None, process the command | ||
| 231 | mov msg_disp_class,parse_msg_class ;AN000; set up parse error msg class | ||
| 232 | MOV DX,OFFSET TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer | ||
| 233 | mov Extend_Buf_ptr,BadSwt_ptr ;AN000; get "Invalid switch" message number | ||
| 234 | jmp CERROR ; Print error and chill out... | ||
| 235 | realwork: | ||
| 236 | call BX ; do some real work, at last | ||
| 237 | |||
| 238 | ; See if we're in a batch CALL command. If we are, reprocess the command line, | ||
| 239 | ; otherwise, go get another command. | ||
| 240 | |||
| 241 | Cmd_done: | ||
| 242 | push cs ; g restore data segment | ||
| 243 | pop ds ; g | ||
| 244 | push ds ; g save data segment | ||
| 245 | mov ds,[resseg] ; g get segment containing call flag | ||
| 246 | ASSUME ds:resgroup | ||
| 247 | cmp call_flag, call_in_progress ; G Is a call in progress? | ||
| 248 | mov call_flag, 0 ; G Either way, reset flag | ||
| 249 | pop ds ; g get data segment back | ||
| 250 | jz incall ; G | ||
| 251 | jmp tcommand ; chill out... | ||
| 252 | |||
| 253 | incall: | ||
| 254 | JMP DOCOM1 | ||
| 255 | |||
| 256 | noswit: | ||
| 257 | push di ; Save di | ||
| 258 | mov di,81h ; di = ptr to command args | ||
| 259 | mov si,80h ; Get address of length of command args | ||
| 260 | lodsb ; Load length | ||
| 261 | mov cl,al ; Move length to cl | ||
| 262 | xor ch,ch ; Zero ch | ||
| 263 | mov al,[SWITCHAR] ; al = switch character | ||
| 264 | cmp al,0 ; Turn off ZF | ||
| 265 | repnz scasb ; Scan for a switch character and return | ||
| 266 | pop di ; with ZF set if one was found | ||
| 267 | ret | ||
| 268 | |||
| 269 | EXTERNAL: | ||
| 270 | |||
| 271 | IF IBM | ||
| 272 | call test_append ; check to see if append installed | ||
| 273 | je not_barryf ; no - truly external command | ||
| 274 | jmp append_internal ; yes - go to Barryf code | ||
| 275 | |||
| 276 | not_barryf: | ||
| 277 | |||
| 278 | ENDIF | ||
| 279 | |||
| 280 | MOV [FILTYP],0 | ||
| 281 | MOV DL,[SPECDRV] | ||
| 282 | MOV [IDLEN],DL | ||
| 283 | IF IBM | ||
| 284 | MOV [ROM_CALL],0 | ||
| 285 | PUSH DX | ||
| 286 | MOV DX,OFFSET TRANGROUP:IDLEN | ||
| 287 | CALL ROM_SCAN | ||
| 288 | POP DX | ||
| 289 | JNC DO_SCAN | ||
| 290 | INC [ROM_CALL] | ||
| 291 | JMP PostSave | ||
| 292 | DO_SCAN: | ||
| 293 | ENDIF | ||
| 294 | IF IBM | ||
| 295 | PostSave: | ||
| 296 | ENDIF | ||
| 297 | MOV DI,OFFSET TRANGROUP:EXECPATH | ||
| 298 | MOV BYTE PTR [DI],0 ; Initialize to current directory | ||
| 299 | IF IBM | ||
| 300 | CMP [ROM_CALL],0 | ||
| 301 | JZ Research | ||
| 302 | JMP NeoExecute | ||
| 303 | ENDIF | ||
| 304 | RESEARCH: | ||
| 305 | invoke path_search ; find the mother (result in execpath) | ||
| 306 | or AX, AX ; did we find anything? | ||
| 307 | je badcomj45 ; null means no (sob) | ||
| 308 | cmp AX, 04H ; 04H and 08H are .exe and .com | ||
| 309 | jl rsrch_br1 ; fuckin' sixteen-bit machine ought | ||
| 310 | jmp execute ; to be able to handle a SIXTEEN-BIT | ||
| 311 | rsrch_br1: ; DISPLACEMENT!! | ||
| 312 | jmp batcom ; 02H is .bat | ||
| 313 | BADCOMJ45: | ||
| 314 | JMP BADCOM | ||
| 315 | |||
| 316 | ASSUME DS:TRANGROUP,ES:TRANGROUP | ||
| 317 | |||
| 318 | EXECUTE: | ||
| 319 | NeoExecute: | ||
| 320 | invoke IOSET | ||
| 321 | invoke SETSTDINOFF ;AN026; turn off critical error on STDIN | ||
| 322 | invoke SETSTDOUTOFF ;AN026; turn off critical error on STDOUT | ||
| 323 | MOV ES,[TRAN_TPA] | ||
| 324 | MOV AH,DEALLOC | ||
| 325 | INT int_command ; Now running in "free" space | ||
| 326 | MOV ES,[RESSEG] | ||
| 327 | ASSUME ES:RESGROUP | ||
| 328 | INC [EXTCOM] ; Indicate external command | ||
| 329 | MOV [RESTDIR],0 ; Since USERDIR1 is in transient, insure | ||
| 330 | ; this flag value for re-entry to COMMAND | ||
| 331 | MOV DI,FCB | ||
| 332 | MOV SI,DI | ||
| 333 | MOV CX,052H ; moving (100h-5Ch)/2 = 80h-2Eh | ||
| 334 | REP MOVSW ; Transfer parameters to resident header | ||
| 335 | MOV DX,OFFSET TRANGROUP:EXECPATH | ||
| 336 | MOV BX,OFFSET RESGROUP:EXEC_BLOCK | ||
| 337 | MOV AX,EXEC SHL 8 | ||
| 338 | IF IBM | ||
| 339 | TEST [ROM_CALL],-1 | ||
| 340 | JZ OK_EXEC | ||
| 341 | JMP ROM_EXEC | ||
| 342 | OK_EXEC: | ||
| 343 | ENDIF | ||
| 344 | ; | ||
| 345 | ; we are now running in free space. anything we do from here on may get | ||
| 346 | ; trashed. Move the stack (also in free space) to allocated space because | ||
| 347 | ; since EXEC restores the stack, somebody may trash what is on the stack. | ||
| 348 | ; | ||
| 349 | MOV CX,ES | ||
| 350 | MOV SS,CX | ||
| 351 | MOV SP,OFFSET RESGROUP:RSTACK | ||
| 352 | JMP [EXEC_ADDR] ; Jmp to the EXEC in the resident | ||
| 353 | |||
| 354 | BADCOM: | ||
| 355 | PUSH CS | ||
| 356 | POP DS | ||
| 357 | MOV DX,OFFSET TRANGROUP:BADNAM_ptr | ||
| 358 | |||
| 359 | CERROR: | ||
| 360 | INVOKE std_eprintf | ||
| 361 | JMP TCOMMAND | ||
| 362 | |||
| 363 | ; | ||
| 364 | ; Prescan converts the input buffer into a canonicalized form. All | ||
| 365 | ; redirections and pipes are removed. | ||
| 366 | ; | ||
| 367 | PRESCAN: ; Cook the input buffer | ||
| 368 | |||
| 369 | ASSUME DS:TRANGROUP,ES:TRANGROUP | ||
| 370 | |||
| 371 | XOR CX,CX | ||
| 372 | MOV ES,[RESSEG] | ||
| 373 | ASSUME ES:RESGROUP | ||
| 374 | MOV SI,OFFSET TRANGROUP:COMBUF+2 | ||
| 375 | MOV DI,SI | ||
| 376 | |||
| 377 | CountQuotes: | ||
| 378 | LODSB ; get a byte | ||
| 379 | CMP AL,22h ; is it a quote? | ||
| 380 | JNZ CountEnd ; no, try for end of road | ||
| 381 | INC CH ; bump count | ||
| 382 | JMP CountQuotes ; go get next char | ||
| 383 | |||
| 384 | CountEnd: | ||
| 385 | CMP AL,13 ; end of road? | ||
| 386 | JNZ CountQuotes ; no, go back for next char | ||
| 387 | |||
| 388 | ;;;; IF KANJI 3/3/KK | ||
| 389 | PUSH CX ; save count | ||
| 390 | MOV SI,DI ; get back beginning of buffer | ||
| 391 | |||
| 392 | KanjiScan: | ||
| 393 | LODSB ; get a byte | ||
| 394 | INVOKE TestKanj ; is it a leadin byte | ||
| 395 | JZ KanjiQuote ; no, check for quotes | ||
| 396 | MOV AH,AL ; save leadin | ||
| 397 | LODSB ; get trailing byte | ||
| 398 | CMP AX,8140h ; is it Kanji space | ||
| 399 | JNZ KanjiScan ; no, go get next | ||
| 400 | MOV [SI-2],2020h ; replace with spaces | ||
| 401 | JMP KanjiScan ; go get next char | ||
| 402 | |||
| 403 | KanjiQuote: | ||
| 404 | CMP AL,22h ; beginning of quoted string | ||
| 405 | JNZ KanjiEnd ; no, check for end | ||
| 406 | DEC CH ; drop count | ||
| 407 | JZ KanjiScan ; if count is zero, no quoting | ||
| 408 | |||
| 409 | KanjiQuoteLoop: | ||
| 410 | LODSB ; get next byte | ||
| 411 | CMP AL,22h ; is it another quote | ||
| 412 | JNZ KanjiQuoteLoop ; no, get another | ||
| 413 | DEC CH ; yes, drop count | ||
| 414 | JMP KanjiScan ; go get next char | ||
| 415 | |||
| 416 | KanjiEnd: | ||
| 417 | CMP AL,13 ; end of line character? | ||
| 418 | JNZ KanjiScan ; go back to beginning | ||
| 419 | POP CX ; get back original count | ||
| 420 | ;;;; ENDIF 3/3/KK | ||
| 421 | |||
| 422 | MOV SI,DI ; restore pointer to begining | ||
| 423 | |||
| 424 | PRESCANLP: | ||
| 425 | LODSB | ||
| 426 | |||
| 427 | ;;;; IF KANJI 3/3/KK | ||
| 428 | INVOKE TESTKANJ | ||
| 429 | JZ NOTKANJ6 | ||
| 430 | MOV [DI],AL | ||
| 431 | INC DI ; fake STOSB into DS | ||
| 432 | LODSB ; grab second byte | ||
| 433 | MOV [DI],AL ; fake stosb into DS | ||
| 434 | INC DI | ||
| 435 | INC CL | ||
| 436 | INC CL | ||
| 437 | JMP PRESCANLP | ||
| 438 | |||
| 439 | NOTKANJ6: | ||
| 440 | ;;;; ENDIF 3/3/KK | ||
| 441 | |||
| 442 | CMP AL,'"' ; " character | ||
| 443 | JNZ TRYGREATER | ||
| 444 | DEC CH | ||
| 445 | JZ TRYGREATER | ||
| 446 | |||
| 447 | QLOOP: | ||
| 448 | MOV [DI],AL | ||
| 449 | INC DI | ||
| 450 | INC CL | ||
| 451 | LODSB | ||
| 452 | CMP AL,'"' ; " character | ||
| 453 | JNZ QLOOP | ||
| 454 | DEC CH | ||
| 455 | |||
| 456 | TRYGREATER: | ||
| 457 | CMP AL,rabracket | ||
| 458 | JNZ NOOUT | ||
| 459 | ; | ||
| 460 | ; We have found a ">" char. We need to see if there is another ">" | ||
| 461 | ; following it. | ||
| 462 | ; | ||
| 463 | CMP BYTE PTR [SI],al | ||
| 464 | JNZ NOAPPND | ||
| 465 | LODSB | ||
| 466 | INC [RE_OUT_APP] ; Flag >> | ||
| 467 | |||
| 468 | NOAPPND: | ||
| 469 | ; | ||
| 470 | ; Now we attempt to find the file name. First, scan off all whitespace | ||
| 471 | ; | ||
| 472 | INVOKE SCANOFF | ||
| 473 | CMP AL,labracket ;AN040; was there no filename? | ||
| 474 | JZ REOUT_ERRSET ;AN040; yes - set up error | ||
| 475 | CMP AL,0DH | ||
| 476 | JNZ GOTREOFIL | ||
| 477 | ; | ||
| 478 | ; There was no file present. Set us up at end-of-line. | ||
| 479 | ; | ||
| 480 | REOUT_ERRSET: ;AN040; set up for an error | ||
| 481 | mov byte ptr [di], 0dh ; Clobber first ">" | ||
| 482 | MOV WORD PTR [RE_OUTSTR],09H ; Cause an error later | ||
| 483 | JMP PRESCANEND | ||
| 484 | |||
| 485 | GOTREOFIL: | ||
| 486 | PUSH DI | ||
| 487 | MOV DI,OFFSET RESGROUP:RE_OUTSTR | ||
| 488 | MOV BX,DI | ||
| 489 | PUSH ES | ||
| 490 | |||
| 491 | SETREOUTSTR: ; Get the output redirection name | ||
| 492 | LODSB | ||
| 493 | CMP AL,0DH | ||
| 494 | JZ GOTRESTR | ||
| 495 | INVOKE DELIM | ||
| 496 | JZ GOTRESTR | ||
| 497 | CMP AL,[SWITCHAR] | ||
| 498 | JZ GOTRESTR | ||
| 499 | CMP AL,'"' ;AN033; Is the character a quote? | ||
| 500 | JZ PIPEERRSYNJ5 ;AN033; Yes - get out quick - or system crashes | ||
| 501 | CMP AL,labracket ;AN002; Is char for input redirection | ||
| 502 | JZ ABRACKET_TERM ;AN002; yes - end of string | ||
| 503 | CMP AL,rabracket ;AN002; Is char for output redirection | ||
| 504 | JNZ NO_ABRACKET ;AN002; no - not end of string | ||
| 505 | |||
| 506 | abracket_term: ;AN002; have end of string by < or > | ||
| 507 | DEC SI ;AN002; back up over symbol | ||
| 508 | MOV AL,BLANK ;AN002; show delimiter as char | ||
| 509 | JMP SHORT GOTRESTR ;AN002; go process it | ||
| 510 | |||
| 511 | no_abracket: ;AN002; not at end of string | ||
| 512 | STOSB ; store it into resgroup | ||
| 513 | JMP SHORT SETREOUTSTR | ||
| 514 | |||
| 515 | NOOUT: | ||
| 516 | CMP AL,labracket | ||
| 517 | JNZ CHKPIPE | ||
| 518 | mov bx,si ; Save loc of "<" | ||
| 519 | INVOKE SCANOFF | ||
| 520 | CMP AL,rabracket ;AN040; was there no filename? | ||
| 521 | JZ REIN_ERRSET ;AN040; yes - set up error | ||
| 522 | CMP AL,0DH | ||
| 523 | JNZ GOTREIFIL | ||
| 524 | |||
| 525 | REIN_ERRSET: ;AN040; set up for error | ||
| 526 | mov byte ptr [di],0dh ; Clobber "<" | ||
| 527 | MOV WORD PTR [RE_INSTR],09H ; Cause an error later | ||
| 528 | JMP SHORT PRESCANEND | ||
| 529 | |||
| 530 | GOTREIFIL: | ||
| 531 | PUSH DI | ||
| 532 | MOV DI,OFFSET TranGROUP:RE_INSTR | ||
| 533 | MOV BX,DI | ||
| 534 | PUSH ES | ||
| 535 | PUSH CS | ||
| 536 | POP ES ; store in TRANGROUP | ||
| 537 | JMP SHORT SETREOUTSTR ; Get the input redirection name | ||
| 538 | |||
| 539 | CHKPIPE: | ||
| 540 | MOV AH,AL | ||
| 541 | CMP AH,AltPipeChr | ||
| 542 | JZ IsPipe3 | ||
| 543 | CMP AH,vbar | ||
| 544 | JNZ CONTPRESCAN | ||
| 545 | |||
| 546 | IsPipe3: | ||
| 547 | ; | ||
| 548 | ; Only push the echo flag if we are entering the pipe for the first time. | ||
| 549 | ; | ||
| 550 | CMP PipeFlag,0 | ||
| 551 | JNZ NoEchoPush | ||
| 552 | SHL EchoFlag,1 ; push echo state and turn it off | ||
| 553 | NoEchoPush: | ||
| 554 | INC [PIPEFLAG] | ||
| 555 | INVOKE SCANOFF | ||
| 556 | CMP AL,0DH | ||
| 557 | JZ PIPEERRSYNJ5 | ||
| 558 | CMP AL,AltPipeChr | ||
| 559 | JZ PIPEERRSYNJ5 | ||
| 560 | CMP AL,vbar ; Double '|'? | ||
| 561 | JNZ CONTPRESCAN | ||
| 562 | |||
| 563 | PIPEERRSYNJ5: | ||
| 564 | PUSH ES | ||
| 565 | POP DS ; DS->RESGROUP | ||
| 566 | JMP PIPEERRSYN | ||
| 567 | |||
| 568 | ; | ||
| 569 | ; Trailing :s are allowed on devices. Check to be sure that there is more | ||
| 570 | ; than just a : in the redir string. | ||
| 571 | ; | ||
| 572 | GOTRESTR: | ||
| 573 | XCHG AH,AL | ||
| 574 | mov al,':' | ||
| 575 | SUB BX,DI ; compute negatinve of number of chars | ||
| 576 | CMP BX,-1 ; is there just a :? | ||
| 577 | JZ NotTrailCol ; yep, don't change | ||
| 578 | CMP BYTE PTR ES:[DI-1],al ; Trailing ':' OK on devices | ||
| 579 | JNZ NOTTRAILCOL | ||
| 580 | DEC DI ; Back up over trailing ':' | ||
| 581 | |||
| 582 | NOTTRAILCOL: | ||
| 583 | XOR AL,AL | ||
| 584 | STOSB ; NUL terminate the string | ||
| 585 | POP ES | ||
| 586 | POP DI ; Remember the start | ||
| 587 | |||
| 588 | CONTPRESCAN: | ||
| 589 | MOV [DI],AH ; "delete" the redirection string | ||
| 590 | INC DI | ||
| 591 | CMP AH,0DH | ||
| 592 | JZ PRESCANEND | ||
| 593 | INC CL | ||
| 594 | JMP PRESCANLP | ||
| 595 | |||
| 596 | PRESCANEND: | ||
| 597 | CMP [PIPEFLAG],0 | ||
| 598 | JZ ISNOPIPE | ||
| 599 | MOV DI,OFFSET RESGROUP:PIPESTR | ||
| 600 | MOV [PIPEPTR],DI | ||
| 601 | MOV SI,OFFSET TRANGROUP:COMBUF+2 | ||
| 602 | INVOKE SCANOFF | ||
| 603 | |||
| 604 | PIPESETLP: ; Transfer the pipe into the resident | ||
| 605 | LODSB ; pipe buffer | ||
| 606 | STOSB | ||
| 607 | CMP AL,0DH | ||
| 608 | JNZ PIPESETLP | ||
| 609 | |||
| 610 | ISNOPIPE: | ||
| 611 | MOV [COMBUF+1],CL | ||
| 612 | CMP [PIPEFLAG],0 | ||
| 613 | PUSH CS | ||
| 614 | POP ES | ||
| 615 | return | ||
| 616 | |||
| 617 | cmd_copy proc near | ||
| 618 | |||
| 619 | MOV SI,OFFSET TRANGROUP:COMBUF+2 | ||
| 620 | INVOKE Scanoff ; advance past separators... | ||
| 621 | add si,PathPos | ||
| 622 | mov di,81h | ||
| 623 | xor cx,cx | ||
| 624 | |||
| 625 | CmdCopy: | ||
| 626 | lodsb | ||
| 627 | stosb | ||
| 628 | cmp al,0dh | ||
| 629 | jz CopyDone | ||
| 630 | inc cx | ||
| 631 | jmp CmdCopy | ||
| 632 | |||
| 633 | CopyDone: | ||
| 634 | mov byte ptr ds:[80h],cl ; Store count | ||
| 635 | |||
| 636 | ret | ||
| 637 | cmd_copy endp | ||
| 638 | |||
| 639 | |||
| 640 | test_append proc near | ||
| 641 | |||
| 642 | mov BX,offset TRANGROUP:COMBUF ; barry can address | ||
| 643 | mov SI, offset TRANGROUP:IDLEN ; address command name, DS already set | ||
| 644 | mov DX,-1 ; set install check function | ||
| 645 | mov AX,0AE00H | ||
| 646 | int 2FH ; see if loaded | ||
| 647 | cmp AL,00H | ||
| 648 | |||
| 649 | ret | ||
| 650 | |||
| 651 | test_append endp | ||
| 652 | |||
| 653 | TRANCODE ENDS | ||
| 654 | END | ||
| 655 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/COMMAND/TMISC2.ASM b/v4.0/src/CMD/COMMAND/TMISC2.ASM new file mode 100644 index 0000000..cc30428 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/TMISC2.ASM | |||
| @@ -0,0 +1,487 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)tmisc2.asm 4.3 85/06/25 | ||
| 3 | ; SCCSID = @(#)tmisc2.asm 4.3 85/06/25 | ||
| 4 | TITLE Part7 COMMAND Transient Routines | ||
| 5 | |||
| 6 | ; More misc routines | ||
| 7 | |||
| 8 | |||
| 9 | .xlist | ||
| 10 | .xcref | ||
| 11 | INCLUDE comsw.asm | ||
| 12 | INCLUDE DOSSYM.INC | ||
| 13 | INCLUDE comseg.asm | ||
| 14 | INCLUDE comequ.asm | ||
| 15 | INCLUDE ioctl.inc | ||
| 16 | .list | ||
| 17 | .cref | ||
| 18 | |||
| 19 | |||
| 20 | CODERES SEGMENT PUBLIC BYTE ;AC000; | ||
| 21 | CodeRes ENDS | ||
| 22 | |||
| 23 | DATARES SEGMENT PUBLIC BYTE ;AC000; | ||
| 24 | EXTRN IFFlag:BYTE | ||
| 25 | EXTRN PIPEFLAG:BYTE | ||
| 26 | EXTRN RE_OUTSTR:BYTE | ||
| 27 | EXTRN RE_OUT_APP:BYTE | ||
| 28 | DATARES ENDS | ||
| 29 | |||
| 30 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 31 | EXTRN AccDen_PTR:WORD | ||
| 32 | EXTRN Extend_buf_ptr:word ;AN000; | ||
| 33 | EXTRN FULDIR_PTR:WORD | ||
| 34 | EXTRN msg_disp_class:byte ;AN000; | ||
| 35 | TRANDATA ENDS | ||
| 36 | |||
| 37 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 38 | EXTRN DESTINFO:BYTE | ||
| 39 | EXTRN DESTISDIR:BYTE | ||
| 40 | EXTRN KPARSE:BYTE ;AC000; | ||
| 41 | EXTRN ONE_CHAR_VAL:BYTE ;AN011; | ||
| 42 | EXTRN PATHCNT:WORD | ||
| 43 | EXTRN PATHPOS:WORD | ||
| 44 | EXTRN PATHSW:WORD | ||
| 45 | EXTRN RE_INSTR:BYTE | ||
| 46 | EXTRN RESSEG:WORD | ||
| 47 | EXTRN SRCBUF:BYTE | ||
| 48 | EXTRN SWITCHAR:BYTE | ||
| 49 | |||
| 50 | IF IBM | ||
| 51 | EXTRN ROM_CALL:BYTE | ||
| 52 | EXTRN ROM_CS:WORD | ||
| 53 | EXTRN ROM_IP:WORD | ||
| 54 | ENDIF | ||
| 55 | |||
| 56 | TRANSPACE ENDS | ||
| 57 | |||
| 58 | TRANCODE SEGMENT PUBLIC byte | ||
| 59 | |||
| 60 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 61 | |||
| 62 | EXTRN CERROR:NEAR | ||
| 63 | |||
| 64 | IF IBM | ||
| 65 | EXTRN ROM_EXEC:NEAR | ||
| 66 | EXTRN ROM_SCAN:NEAR | ||
| 67 | ENDIF | ||
| 68 | |||
| 69 | PUBLIC IOSET | ||
| 70 | PUBLIC MOVE_TO_SRCBUF ;AN000; | ||
| 71 | PUBLIC PGETARG | ||
| 72 | PUBLIC SETPATH | ||
| 73 | PUBLIC TESTDOREIN | ||
| 74 | PUBLIC TESTDOREOUT | ||
| 75 | |||
| 76 | |||
| 77 | ASSUME DS:TRANGROUP | ||
| 78 | |||
| 79 | SETPATH: | ||
| 80 | ; | ||
| 81 | ; Get an ASCIZ argument from the unformatted parms | ||
| 82 | ; DESTISDIR set if pathchars in string | ||
| 83 | ; DESTINFO set if ? or * in string | ||
| 84 | ; | ||
| 85 | MOV AX,[PATHCNT] ;AC000; get length of string | ||
| 86 | MOV SI,[PATHPOS] ;AC000; get start of source buffer | ||
| 87 | |||
| 88 | GETPATH: | ||
| 89 | MOV [DESTINFO],0 | ||
| 90 | MOV [DESTISDIR],0 | ||
| 91 | MOV SI,[PATHPOS] | ||
| 92 | MOV CX,[PATHCNT] | ||
| 93 | MOV DX,SI | ||
| 94 | JCXZ PATHDONE | ||
| 95 | PUSH CX | ||
| 96 | PUSH SI | ||
| 97 | INVOKE SWITCH | ||
| 98 | MOV [PATHSW],AX | ||
| 99 | POP BX | ||
| 100 | SUB BX,SI | ||
| 101 | POP CX | ||
| 102 | ADD CX,BX | ||
| 103 | MOV DX,SI | ||
| 104 | |||
| 105 | SKIPPATH: | ||
| 106 | |||
| 107 | ;;;; IF KANJI 3/3/KK | ||
| 108 | MOV [KPARSE],0 | ||
| 109 | |||
| 110 | SKIPPATH2: | ||
| 111 | ;;;; ENDIF 3/3/KK | ||
| 112 | |||
| 113 | JCXZ PATHDONE | ||
| 114 | DEC CX | ||
| 115 | LODSB | ||
| 116 | |||
| 117 | ;;;; IF KANJI 3/3/KK | ||
| 118 | INVOKE TESTKANJ | ||
| 119 | JZ TESTPPSEP | ||
| 120 | DEC CX | ||
| 121 | INC SI | ||
| 122 | INC [KPARSE] | ||
| 123 | JMP SKIPPATH2 | ||
| 124 | |||
| 125 | TESTPPSEP: | ||
| 126 | ;;;; ENDIF 3/3/KK | ||
| 127 | |||
| 128 | INVOKE PATHCHRCMP | ||
| 129 | JNZ TESTPMETA | ||
| 130 | INC [DESTISDIR] | ||
| 131 | |||
| 132 | TESTPMETA: | ||
| 133 | CMP AL,'?' | ||
| 134 | JNZ TESTPSTAR | ||
| 135 | OR [DESTINFO],2 | ||
| 136 | |||
| 137 | TESTPSTAR: | ||
| 138 | CMP AL,star | ||
| 139 | JNZ TESTPDELIM | ||
| 140 | OR [DESTINFO],2 | ||
| 141 | |||
| 142 | TESTPDELIM: | ||
| 143 | INVOKE DELIM | ||
| 144 | JZ PATHDONEDEC | ||
| 145 | CMP AL,[SWITCHAR] | ||
| 146 | JNZ SKIPPATH | ||
| 147 | |||
| 148 | PATHDONEDEC: | ||
| 149 | DEC SI | ||
| 150 | |||
| 151 | PATHDONE: | ||
| 152 | XOR AL,AL | ||
| 153 | XCHG AL,[SI] | ||
| 154 | INC SI | ||
| 155 | CMP AL,0DH | ||
| 156 | JNZ NOPSTORE | ||
| 157 | MOV [SI],AL ;Don't loose the CR | ||
| 158 | |||
| 159 | NOPSTORE: | ||
| 160 | MOV [PATHPOS],SI | ||
| 161 | MOV [PATHCNT],CX | ||
| 162 | return | ||
| 163 | |||
| 164 | PGETARG: | ||
| 165 | MOV SI,80H | ||
| 166 | LODSB | ||
| 167 | OR AL,AL | ||
| 168 | retz | ||
| 169 | CALL PSCANOFF | ||
| 170 | CMP AL,13 | ||
| 171 | return | ||
| 172 | |||
| 173 | PSCANOFF: | ||
| 174 | LODSB | ||
| 175 | INVOKE DELIM | ||
| 176 | JNZ PSCANOFFD | ||
| 177 | CMP AL,';' | ||
| 178 | JNZ PSCANOFF ; ';' is not a delimiter | ||
| 179 | |||
| 180 | PSCANOFFD: | ||
| 181 | DEC SI ; Point to first non-delimiter | ||
| 182 | return | ||
| 183 | |||
| 184 | IOSET: | ||
| 185 | ; | ||
| 186 | ; ALL REGISTERS PRESERVED | ||
| 187 | ; | ||
| 188 | ASSUME DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 189 | |||
| 190 | PUSH DS | ||
| 191 | PUSH DX | ||
| 192 | PUSH AX | ||
| 193 | PUSH BX | ||
| 194 | PUSH CX | ||
| 195 | MOV DS,[RESSEG] | ||
| 196 | ASSUME DS:RESGROUP | ||
| 197 | |||
| 198 | CMP [PIPEFLAG],0 | ||
| 199 | JNZ NOREDIR ; Don't muck up the pipe | ||
| 200 | TEST IFFlag,-1 | ||
| 201 | JNZ NoRedir | ||
| 202 | CALL TESTDOREIN | ||
| 203 | CALL TESTDOREOUT | ||
| 204 | |||
| 205 | NOREDIR: | ||
| 206 | POP CX | ||
| 207 | POP BX | ||
| 208 | POP AX | ||
| 209 | POP DX | ||
| 210 | POP DS | ||
| 211 | ASSUME DS:NOTHING | ||
| 212 | return | ||
| 213 | |||
| 214 | TESTDOREIN: | ||
| 215 | |||
| 216 | ASSUME DS:RESGROUP | ||
| 217 | |||
| 218 | CMP [RE_INSTR],0 | ||
| 219 | retz | ||
| 220 | PUSH DS | ||
| 221 | PUSH CS | ||
| 222 | POP DS | ||
| 223 | MOV DX,OFFSET tranGROUP:RE_INSTR | ||
| 224 | MOV AX,(OPEN SHL 8) | ||
| 225 | MOV BX,AX | ||
| 226 | INT int_command | ||
| 227 | POP DS | ||
| 228 | JC REDIRERR | ||
| 229 | MOV BX,AX | ||
| 230 | MOV AL,0FFH | ||
| 231 | ; | ||
| 232 | ; Mega sleaze!! We move the SFN from the new handle spot into the old stdin | ||
| 233 | ; spot. We invalidate the new JFN we got. | ||
| 234 | ; | ||
| 235 | XCHG AL,[BX.PDB_JFN_Table] | ||
| 236 | MOV DS:[PDB_JFN_Table],AL | ||
| 237 | |||
| 238 | return | ||
| 239 | ; | ||
| 240 | ; We had some kind of error on the redirection. Figure out what the | ||
| 241 | ; appropriate message should be; BX has the system call that failed | ||
| 242 | ; | ||
| 243 | REDIRERR: | ||
| 244 | PUSH CS | ||
| 245 | POP DS | ||
| 246 | Call TriageError | ||
| 247 | ; | ||
| 248 | ; At this point, we have recognized the network-generated access denied error. | ||
| 249 | ; The correct message is in DX | ||
| 250 | ; | ||
| 251 | CMP AX,65 | ||
| 252 | JZ CERRORJ ;AC000; just issue message returned | ||
| 253 | CMP BH,OPEN | ||
| 254 | JZ OpenError | ||
| 255 | ; | ||
| 256 | ; The error was for a create operation. Report the error as a creation error. | ||
| 257 | ; | ||
| 258 | MOV DX,OFFSET TranGroup:FULDIR_PTR | ||
| 259 | |||
| 260 | CERRORJ: | ||
| 261 | JMP CERROR | ||
| 262 | ; | ||
| 263 | ; The system call was an OPEN. Report either file not found or path not found. | ||
| 264 | ; | ||
| 265 | |||
| 266 | OpenError: | ||
| 267 | mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class | ||
| 268 | mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer | ||
| 269 | mov Extend_Buf_ptr,ax ;AN000; get message number in control block | ||
| 270 | JMP CERROR | ||
| 271 | |||
| 272 | TESTDOREOUT: | ||
| 273 | |||
| 274 | ASSUME DS:RESGROUP | ||
| 275 | |||
| 276 | CMP [RE_OUTSTR],0 | ||
| 277 | JNZ REOUTEXISTS ;AN017; need long jump | ||
| 278 | JMP NOREOUT ;AN017; | ||
| 279 | |||
| 280 | REOUTEXISTS: | ||
| 281 | CMP [RE_OUT_APP],0 | ||
| 282 | JZ REOUTCRT | ||
| 283 | ; | ||
| 284 | ; The output redirection was for append. We open for write and seek to the | ||
| 285 | ; end. | ||
| 286 | ; | ||
| 287 | MOV DX,OFFSET RESGROUP:RE_OUTSTR | ||
| 288 | MOV AX,(OPEN SHL 8) OR 2 ;AC011; Open for read/write | ||
| 289 | PUSH AX | ||
| 290 | INT int_command | ||
| 291 | POP BX | ||
| 292 | JC OpenWriteError | ||
| 293 | |||
| 294 | MOV BX,AX | ||
| 295 | MOV AX,IOCTL SHL 8 ;AN035; Get attributes of handle | ||
| 296 | INT int_command ;AN035; | ||
| 297 | TEST DL,devid_ISDEV ;AN035; Is it a device? | ||
| 298 | JNZ SET_REOUT ;AN035; Yes, don't read from it | ||
| 299 | |||
| 300 | MOV AX,(LSEEK SHL 8) OR 2 | ||
| 301 | MOV CX,-1 ;AC011; MOVE TO EOF -1 | ||
| 302 | MOV DX,CX ;AC011; | ||
| 303 | INT int_command | ||
| 304 | PUSH CS ;AN011; Get transient seg to DS | ||
| 305 | POP DS ;AN011; | ||
| 306 | assume DS:Trangroup ;AN011; | ||
| 307 | MOV AX,(READ SHL 8) ;AN011; Read one byte from the | ||
| 308 | MOV CX,1 ;AN011; file into one_char_val | ||
| 309 | MOV DX,OFFSET Trangroup:ONE_CHAR_VAL;AN011; | ||
| 310 | INT int_command ;AN011; | ||
| 311 | JC OpenWriteError ;AN011; If error, exit | ||
| 312 | cmp ax,cx ;AN017; Did we read 1 byte? | ||
| 313 | jnz reout_0_length ;AN017; No - file must be 0 length | ||
| 314 | |||
| 315 | cmp one_char_val,01ah ;AN011; Was char an eof mark? | ||
| 316 | mov DS,[resseg] ;AN011; Get resident segment back | ||
| 317 | assume DS:Resgroup ;AN011; | ||
| 318 | JNZ SET_REOUT ;AN011; No, just continue | ||
| 319 | MOV AX,(LSEEK SHL 8) OR 1 ;AN011; EOF mark found | ||
| 320 | MOV CX,-1 ;AN011; LSEEK back one byte | ||
| 321 | MOV DX,CX ;AN011; | ||
| 322 | INT int_command ;AN011; | ||
| 323 | JMP SHORT SET_REOUT | ||
| 324 | |||
| 325 | reout_0_length: ;AN017; We have a 0 length file | ||
| 326 | mov DS,[resseg] ;AN017; Get resident segment back | ||
| 327 | assume DS:Resgroup ;AN017; | ||
| 328 | MOV AX,(LSEEK SHL 8) ;AN017; Move to beginning of file | ||
| 329 | XOR CX,CX ;AN017; Offset is 0 | ||
| 330 | MOV DX,CX ;AN017; | ||
| 331 | INT int_command ;AN017; | ||
| 332 | JMP SHORT SET_REOUT ;AN017; now finish setting up redirection | ||
| 333 | |||
| 334 | OpenWriteError: | ||
| 335 | CMP AX,error_access_denied | ||
| 336 | STC ; preserve error | ||
| 337 | JNZ REOUTCRT ;AN017; need long jump | ||
| 338 | JMP REDIRERR ;AN017; | ||
| 339 | |||
| 340 | REOUTCRT: | ||
| 341 | MOV DX,OFFSET RESGROUP:RE_OUTSTR | ||
| 342 | XOR CX,CX | ||
| 343 | MOV AH,CREAT | ||
| 344 | PUSH AX | ||
| 345 | INT int_command | ||
| 346 | POP BX | ||
| 347 | JNC NOREDIRERR ;AC011; | ||
| 348 | JMP REDIRERR ;AC011; | ||
| 349 | |||
| 350 | NOREDIRERR: ;AN011; | ||
| 351 | MOV BX,AX | ||
| 352 | |||
| 353 | SET_REOUT: | ||
| 354 | ; | ||
| 355 | ; Mega sleaze!! We move the SFN from the new handle spot into the old stdout | ||
| 356 | ; spot. We invalidate the new JFN we got. | ||
| 357 | ; | ||
| 358 | MOV AL,0FFH | ||
| 359 | XCHG AL,[BX.PDB_JFN_Table] | ||
| 360 | MOV DS:[PDB_JFN_Table+1],AL | ||
| 361 | |||
| 362 | NOREOUT: | ||
| 363 | return | ||
| 364 | |||
| 365 | ; | ||
| 366 | ; Compute length of string (including NUL) in DS:SI into CX. Change no other | ||
| 367 | ; registers | ||
| 368 | ; | ||
| 369 | Procedure DSTRLEN,NEAR | ||
| 370 | |||
| 371 | SaveReg <AX> | ||
| 372 | XOR CX,CX | ||
| 373 | CLD | ||
| 374 | |||
| 375 | DLoop: LODSB | ||
| 376 | INC CX | ||
| 377 | OR AL,AL | ||
| 378 | JNZ DLoop | ||
| 379 | SUB SI,CX | ||
| 380 | RestoreReg <AX> | ||
| 381 | return | ||
| 382 | |||
| 383 | EndProc DSTRLEN | ||
| 384 | |||
| 385 | Break <Extended error support> | ||
| 386 | |||
| 387 | ; | ||
| 388 | ; TriageError will examine the return from a carry-set system call and | ||
| 389 | ; return the correct error if applicable. | ||
| 390 | ; | ||
| 391 | ; Inputs: outputs from a carry-settable system call | ||
| 392 | ; No system calls may be done in the interrim | ||
| 393 | ; Outputs: If carry was set on input | ||
| 394 | ; carry set on output | ||
| 395 | ; DX contains trangroup offset to printf message | ||
| 396 | ; else | ||
| 397 | ; No registers changed | ||
| 398 | ; | ||
| 399 | |||
| 400 | Procedure TriageError,NEAR | ||
| 401 | |||
| 402 | retnc ; no carry => do nothing... | ||
| 403 | PUSHF | ||
| 404 | SaveReg <BX,CX,SI,DI,BP,ES,DS,AX,DX> | ||
| 405 | MOV AH,GetExtendedError | ||
| 406 | INT 21h | ||
| 407 | RestoreReg <CX,BX> ; restore original AX | ||
| 408 | MOV DX,OFFSET TranGroup:AccDen_PTR | ||
| 409 | CMP AX,65 ; network access denied? | ||
| 410 | JZ NoMove ; Yes, return it. | ||
| 411 | MOV AX,BX | ||
| 412 | MOV DX,CX | ||
| 413 | |||
| 414 | NoMove: | ||
| 415 | RestoreReg <DS,ES,BP,DI,SI,CX,BX> | ||
| 416 | popf | ||
| 417 | return | ||
| 418 | |||
| 419 | EndProc TriageError | ||
| 420 | |||
| 421 | PUBLIC Triage_Init | ||
| 422 | Triage_Init proc FAR | ||
| 423 | call TriageError | ||
| 424 | ret | ||
| 425 | Triage_Init endp | ||
| 426 | |||
| 427 | |||
| 428 | ; **************************************************************** | ||
| 429 | ; * | ||
| 430 | ; * ROUTINE: MOVE_TO_SRCBUF | ||
| 431 | ; * | ||
| 432 | ; * FUNCTION: Move ASCIIZ string from DS:SI to SRCBUF. Change | ||
| 433 | ; * terminating 0 to 0dH. Set PATHCNT to length of | ||
| 434 | ; * string. Set PATHPOS to start of SRCBUF. | ||
| 435 | ; * | ||
| 436 | ; * INPUT: DS:SI points to ASCIIZ string | ||
| 437 | ; * ES points to TRANGROUP | ||
| 438 | ; * | ||
| 439 | ; * OUTPUT: SRCBUF filled in with string terminated by 0dH | ||
| 440 | ; * PATHCNT set to length of string | ||
| 441 | ; * PATHPOS set to start of SRCBUF | ||
| 442 | ; * CX,AX changed | ||
| 443 | ; * | ||
| 444 | ; **************************************************************** | ||
| 445 | |||
| 446 | assume es:trangroup,ds:nothing ;AN000; | ||
| 447 | |||
| 448 | MOVE_TO_SRCBUF PROC NEAR ;AN000; | ||
| 449 | |||
| 450 | push si ;AN000; save si,di | ||
| 451 | push di ;AN000; | ||
| 452 | push cx ;AN000; | ||
| 453 | mov di,offset TRANGROUP:srcbuf ;AN000; set ES:DI to srcbuf | ||
| 454 | xor cx,cx ;AN000; clear cx for counint | ||
| 455 | mov ax,cx ;AN000; clear ax | ||
| 456 | push di ;AN000; save start of srcbuf | ||
| 457 | lodsb ;AN000; get a character from DS:SI | ||
| 458 | |||
| 459 | mts_get_chars: ;AN000; | ||
| 460 | cmp al,0 ;AN000; was it a null char? | ||
| 461 | jz mts_end_string ;AN000; yes - exit | ||
| 462 | stosb ;AN000; no - store it in srcbuf | ||
| 463 | inc cx ;AN000; increment length count | ||
| 464 | lodsb ;AN000; get a character from DS:SI | ||
| 465 | jmp short mts_get_chars ;AN000; go check it | ||
| 466 | |||
| 467 | mts_end_string: ;AN000; we've reached the end of line | ||
| 468 | mov al,end_of_line_in ;AN000; store 0dH in srcbuf | ||
| 469 | stosb ;AN000; | ||
| 470 | pop di ;AN000; restore start of srcbuf | ||
| 471 | |||
| 472 | push cs ;AN000; set DS to local segment | ||
| 473 | pop ds ;AN000; | ||
| 474 | assume ds:trangroup ;AN000; | ||
| 475 | mov [pathcnt],cx ;AN000; set patchcnt to length count | ||
| 476 | mov [pathpos],di ;AN000; set pathpos to start of srcbuf | ||
| 477 | pop cx ;AN000; restore cx,di,si | ||
| 478 | pop di ;AN000; | ||
| 479 | pop si ;AN000; | ||
| 480 | |||
| 481 | RET ;AN000; exit | ||
| 482 | |||
| 483 | MOVE_TO_SRCBUF ENDP ;AN000; | ||
| 484 | |||
| 485 | TRANCODE ENDS | ||
| 486 | END | ||
| 487 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/COMMAND/TPARSE.ASM b/v4.0/src/CMD/COMMAND/TPARSE.ASM new file mode 100644 index 0000000..9268017 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/TPARSE.ASM | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)tparse.asm 4.1 87/04/28 | ||
| 3 | ; SCCSID = @(#)tparse.asm 4.1 87/04/28 | ||
| 4 | TITLE COMMAND interface to SYSPARSE | ||
| 5 | |||
| 6 | .xlist | ||
| 7 | .xcref | ||
| 8 | INCLUDE comseg.asm ;AN000; | ||
| 9 | .list | ||
| 10 | .cref | ||
| 11 | |||
| 12 | TRANSPACE SEGMENT PUBLIC BYTE ;AN000; | ||
| 13 | |||
| 14 | CmpxSW equ 0 ;AN000; do not check complex list | ||
| 15 | KeySW equ 0 ;AN000; do not support keywords | ||
| 16 | Val2SW equ 0 ;AN000; do not Support value definition 2 | ||
| 17 | IncSW equ 0 ;AN000; do not include psdata.inc | ||
| 18 | QusSW equ 0 ;AN025; do not include quoted string | ||
| 19 | LFEOLSW equ 0 ;AN044; do not use 0ah as line terminator | ||
| 20 | |||
| 21 | .xlist | ||
| 22 | .xcref | ||
| 23 | |||
| 24 | include psdata.inc ;AN000; | ||
| 25 | |||
| 26 | .list | ||
| 27 | .cref | ||
| 28 | |||
| 29 | TRANSPACE ENDS ;AN000; | ||
| 30 | |||
| 31 | TRANCODE SEGMENT PUBLIC BYTE ;AN000; | ||
| 32 | |||
| 33 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING ;AN054; | ||
| 34 | |||
| 35 | ; **************************************************************** | ||
| 36 | ; * | ||
| 37 | ; * ROUTINE: CMD_PARSE | ||
| 38 | ; * | ||
| 39 | ; * FUNCTION: Interface for transient COMMAND to invoke | ||
| 40 | ; * SYSPARSE. | ||
| 41 | ; * | ||
| 42 | ; * INPUT: inputs to SYSPARSE | ||
| 43 | ; * | ||
| 44 | ; * OUTPUT: outputs from SYSPARSE | ||
| 45 | ; * | ||
| 46 | ; **************************************************************** | ||
| 47 | |||
| 48 | public Cmd_parse ;AN000; | ||
| 49 | |||
| 50 | .xlist | ||
| 51 | .xcref | ||
| 52 | INCLUDE parse.asm ;AN000; | ||
| 53 | .list | ||
| 54 | .cref | ||
| 55 | |||
| 56 | Cmd_parse Proc near ;AN000; | ||
| 57 | |||
| 58 | call sysparse ;AN000; | ||
| 59 | |||
| 60 | ret ;AN000; | ||
| 61 | |||
| 62 | Cmd_parse endp ;AN000; | ||
| 63 | |||
| 64 | public Append_parse ;AN010; | ||
| 65 | |||
| 66 | Append_parse Proc Far ;AN010; | ||
| 67 | |||
| 68 | call sysparse ;AN010; | ||
| 69 | |||
| 70 | ret ;AN010; | ||
| 71 | |||
| 72 | Append_parse endp ;AN010; | ||
| 73 | |||
| 74 | trancode ends ;AN000; | ||
| 75 | end ;AN000; | ||
| 76 | \ No newline at end of file | ||
diff --git a/v4.0/src/CMD/COMMAND/TPIPE.ASM b/v4.0/src/CMD/COMMAND/TPIPE.ASM new file mode 100644 index 0000000..23f8417 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/TPIPE.ASM | |||
| @@ -0,0 +1,660 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)tpipe.asm 1.1 85/05/14 | ||
| 3 | ; SCCSID = @(#)tpipe.asm 1.1 85/05/14 | ||
| 4 | TITLE PART8 COMMAND Transient routines. | ||
| 5 | |||
| 6 | |||
| 7 | INCLUDE comsw.asm | ||
| 8 | .xlist | ||
| 9 | .xcref | ||
| 10 | INCLUDE DOSSYM.INC | ||
| 11 | INCLUDE comseg.asm | ||
| 12 | INCLUDE comequ.asm | ||
| 13 | .list | ||
| 14 | .cref | ||
| 15 | |||
| 16 | |||
| 17 | DATARES SEGMENT PUBLIC BYTE ;AC000; | ||
| 18 | EXTRN ECHOFLAG:BYTE | ||
| 19 | EXTRN InitFlag:byte | ||
| 20 | EXTRN INPIPEPTR:WORD | ||
| 21 | EXTRN OUTPIPEPTR:WORD | ||
| 22 | EXTRN PIPE1:BYTE | ||
| 23 | EXTRN PIPE1T:BYTE | ||
| 24 | EXTRN PIPE2:BYTE | ||
| 25 | EXTRN PIPE2T:BYTE | ||
| 26 | EXTRN PIPEFILES:BYTE | ||
| 27 | EXTRN PIPEFLAG:BYTE | ||
| 28 | EXTRN PIPEPTR:WORD | ||
| 29 | EXTRN RESTDIR:BYTE | ||
| 30 | EXTRN SINGLECOM:WORD | ||
| 31 | DATARES ENDS | ||
| 32 | |||
| 33 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 34 | EXTRN BADDAT_PTR:WORD | ||
| 35 | EXTRN BADTIM_PTR:WORD | ||
| 36 | EXTRN curdat_mo_day:word ;AN000; | ||
| 37 | EXTRN CURDAT_PTR:WORD | ||
| 38 | EXTRN curdat_yr:word ;AN000; | ||
| 39 | EXTRN curtim_hr_min:word ;AN000; | ||
| 40 | EXTRN CURTIM_PTR:WORD | ||
| 41 | EXTRN curtim_sec_hn:word ;AN000; | ||
| 42 | EXTRN eurdat_ptr:word | ||
| 43 | EXTRN japdat_ptr:word | ||
| 44 | EXTRN newdat_format:word ;AN000; | ||
| 45 | EXTRN NEWDAT_PTR:WORD | ||
| 46 | EXTRN NEWTIM_PTR:WORD | ||
| 47 | EXTRN parse_date:byte ;AN000; | ||
| 48 | EXTRN parse_time:byte ;AN000; | ||
| 49 | EXTRN PIPEEMES_PTR:WORD | ||
| 50 | EXTRN promtim_hr_min:word ;AN000; | ||
| 51 | EXTRN promtim_ptr:word ;AN000; | ||
| 52 | EXTRN promtim_sec_hn:word ;AN000; | ||
| 53 | EXTRN STRING_BUF_PTR:WORD ;AC000; | ||
| 54 | EXTRN SYNTMES_PTR:WORD | ||
| 55 | EXTRN usadat_ptr:word | ||
| 56 | |||
| 57 | TRANDATA ENDS | ||
| 58 | |||
| 59 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 60 | EXTRN COMBUF:BYTE | ||
| 61 | EXTRN date_day:byte ;AN000; | ||
| 62 | EXTRN date_month:byte ;AN000; | ||
| 63 | EXTRN date_year:word ;AN000; | ||
| 64 | EXTRN INTERNATVARS:BYTE | ||
| 65 | EXTRN RESSEG:WORD | ||
| 66 | EXTRN time_fraction:byte ;AN000; | ||
| 67 | EXTRN time_hour:byte ;AN000; | ||
| 68 | EXTRN time_minutes:byte ;AN000; | ||
| 69 | EXTRN time_seconds:byte ;AN000; | ||
| 70 | TRANSPACE ENDS | ||
| 71 | |||
| 72 | TRANCODE SEGMENT PUBLIC BYTE | ||
| 73 | ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING | ||
| 74 | |||
| 75 | EXTRN CERROR:NEAR | ||
| 76 | EXTRN NOPIPEPROC:NEAR | ||
| 77 | EXTRN STD_PRINTF:NEAR | ||
| 78 | EXTRN TCOMMAND:NEAR | ||
| 79 | EXTRN TESTDOREIN:NEAR | ||
| 80 | EXTRN TESTDOREOUT:NEAR | ||
| 81 | EXTRN TESTKANJ:NEAR ;AN000;3/3/KK | ||
| 82 | EXTRN TSYSGETMSG:NEAR ;AN000; | ||
| 83 | |||
| 84 | PUBLIC CTIME | ||
| 85 | PUBLIC DATE | ||
| 86 | PUBLIC DATINIT | ||
| 87 | PUBLIC PIPEDEL | ||
| 88 | PUBLIC PIPEERRSYN | ||
| 89 | PUBLIC PIPEPROC | ||
| 90 | PUBLIC PIPEPROCSTRT | ||
| 91 | PUBLIC PRINT_TIME | ||
| 92 | PUBLIC SETREST | ||
| 93 | PUBLIC SETREST1 | ||
| 94 | PUBLIC SINGLETEST | ||
| 95 | |||
| 96 | SINGLETEST: | ||
| 97 | ASSUME DS:NOTHING | ||
| 98 | push ds | ||
| 99 | MOV DS,ResSeg | ||
| 100 | ASSUME DS:ResGroup | ||
| 101 | CMP [SINGLECOM],0 | ||
| 102 | JZ TestDone | ||
| 103 | CMP [SINGLECOM],0EFFFH | ||
| 104 | TestDone: | ||
| 105 | pop ds | ||
| 106 | return | ||
| 107 | |||
| 108 | |||
| 109 | ASSUME DS:TRANGROUP | ||
| 110 | SETREST1: | ||
| 111 | MOV AL,1 | ||
| 112 | SETREST: | ||
| 113 | PUSH DS | ||
| 114 | MOV DS,[RESSEG] | ||
| 115 | ASSUME DS:RESGROUP | ||
| 116 | MOV [RESTDIR],AL | ||
| 117 | POP DS | ||
| 118 | ASSUME DS:TRANGROUP | ||
| 119 | return | ||
| 120 | |||
| 121 | ASSUME DS:RESGROUP | ||
| 122 | |||
| 123 | ; | ||
| 124 | ; Note that we need to handle the same thing that RestDir handles: the | ||
| 125 | ; requirement that we try only once to restore the user's environment after | ||
| 126 | ; and INT 24 or the like. If the condition that causes the INT 24 does not | ||
| 127 | ; disappear, we just give up. | ||
| 128 | ; | ||
| 129 | |||
| 130 | PIPEDEL: | ||
| 131 | assume ds:nothing | ||
| 132 | push ds | ||
| 133 | PUSH DX | ||
| 134 | mov ds,ResSeg | ||
| 135 | assume ds:ResGroup | ||
| 136 | mov DX,OFFSET RESGROUP:PIPE1 ; Clean up in case ^C | ||
| 137 | MOV AH,UNLINK | ||
| 138 | INT int_command | ||
| 139 | MOV DX,OFFSET RESGROUP:PIPE2 | ||
| 140 | MOV AH,UNLINK | ||
| 141 | INT int_command | ||
| 142 | POP DX | ||
| 143 | call PipeOff | ||
| 144 | mov PipeFiles,0 | ||
| 145 | pop ds | ||
| 146 | return | ||
| 147 | |||
| 148 | PIPEERRSYN: | ||
| 149 | MOV DX,OFFSET TRANGROUP:SYNTMES_ptr | ||
| 150 | CALL PIPEDEL | ||
| 151 | PUSH CS | ||
| 152 | POP DS | ||
| 153 | JMP CERROR | ||
| 154 | PIPEERR: | ||
| 155 | pushf | ||
| 156 | invoke triageError | ||
| 157 | SaveReg <AX,DX> ; Save results from TriageError | ||
| 158 | MOV DX,OFFSET TRANGROUP:PIPEEMES_ptr | ||
| 159 | CALL PIPEDEL | ||
| 160 | PUSH CS | ||
| 161 | POP DS | ||
| 162 | invoke std_eprintf | ||
| 163 | RestoreReg <DX,AX> ; Restore results from TriageError | ||
| 164 | popf | ||
| 165 | cmp ax, 65 | ||
| 166 | jnz tcommandj | ||
| 167 | JMP CERROR | ||
| 168 | tcommandj: | ||
| 169 | jmp tcommand | ||
| 170 | |||
| 171 | PIPEPROCSTRT: | ||
| 172 | ASSUME DS:TRANGROUP,ES:TRANGROUP | ||
| 173 | MOV DS,[RESSEG] | ||
| 174 | ASSUME DS:RESGROUP | ||
| 175 | INC [PIPEFILES] ; Flag that the pipe files exist | ||
| 176 | MOV AH,Get_Default_Drive ; Get current drive | ||
| 177 | INT int_command | ||
| 178 | ADD AL,capital_A | ||
| 179 | MOV [PIPE2],AL ; Make pipe files in root of def drv | ||
| 180 | MOV BX,OFFSET RESGROUP:PIPE1 | ||
| 181 | MOV [BX],AL | ||
| 182 | xor ah,ah ; nul terminate path names | ||
| 183 | mov [Pipe1T],ah | ||
| 184 | mov [Pipe2T],ah | ||
| 185 | MOV DX,BX | ||
| 186 | XOR CX,CX | ||
| 187 | mov ah,CreateTempFile ; the CreateTemp call | ||
| 188 | INT int_command | ||
| 189 | JC PIPEERR ; Couldn't create | ||
| 190 | MOV BX,AX | ||
| 191 | MOV AH,CLOSE ; Don't proliferate handles | ||
| 192 | INT int_command | ||
| 193 | |||
| 194 | MOV DX,OFFSET RESGROUP:PIPE2 | ||
| 195 | mov ah,createTempFile ; the CreateTemp call | ||
| 196 | INT int_command | ||
| 197 | JC PIPEERR | ||
| 198 | MOV BX,AX | ||
| 199 | MOV AH,CLOSE | ||
| 200 | INT int_command | ||
| 201 | |||
| 202 | CALL TESTDOREIN ; Set up a redirection if specified | ||
| 203 | MOV SI,[PIPEPTR] | ||
| 204 | CMP [SINGLECOM],-1 | ||
| 205 | JNZ NOSINGP | ||
| 206 | MOV [SINGLECOM],0F000H ; Flag single command pipe | ||
| 207 | NOSINGP: | ||
| 208 | JMP SHORT FIRSTPIPE | ||
| 209 | |||
| 210 | PIPEPROC: | ||
| 211 | ASSUME DS:RESGROUP | ||
| 212 | AND [ECHOFLAG],0FEh ; force current echo to be off | ||
| 213 | MOV SI,[PIPEPTR] | ||
| 214 | LODSB | ||
| 215 | CMP AL,AltPipeChr ; Alternate pipe char? | ||
| 216 | JZ IsPipe1 ; Yes | ||
| 217 | CMP AL,vbar | ||
| 218 | jz IsPipe1 | ||
| 219 | jmp PIPEEND ; Pipe done | ||
| 220 | IsPipe1: | ||
| 221 | MOV DX,[INPIPEPTR] ; Get the input file name | ||
| 222 | MOV AX,(OPEN SHL 8) | ||
| 223 | INT int_command | ||
| 224 | PIPEERRJ: | ||
| 225 | jnc no_pipeerr | ||
| 226 | JMP PIPEERR ; Lost the pipe file | ||
| 227 | no_pipeerr: | ||
| 228 | MOV BX,AX | ||
| 229 | MOV AL,0FFH | ||
| 230 | XCHG AL,[BX.PDB_JFN_Table] | ||
| 231 | MOV DS:[PDB_JFN_Table],AL ; Redirect | ||
| 232 | |||
| 233 | FIRSTPIPE: | ||
| 234 | MOV DI,OFFSET TRANGROUP:COMBUF + 2 | ||
| 235 | XOR CX,CX | ||
| 236 | CMP BYTE PTR [SI],0DH ; '|<CR>' | ||
| 237 | JNZ PIPEOK1 | ||
| 238 | PIPEERRSYNJ: | ||
| 239 | JMP PIPEERRSYN | ||
| 240 | PIPEOK1: | ||
| 241 | mov al,vbar | ||
| 242 | CMP BYTE PTR [SI],al ; '||' | ||
| 243 | JZ PIPEERRSYNJ | ||
| 244 | CMP BYTE PTR [SI],AltPipeChr ; '##' or '|#'? | ||
| 245 | JZ PipeErrSynJ ; Yes, Error | ||
| 246 | PIPECOMLP: | ||
| 247 | LODSB | ||
| 248 | STOSB | ||
| 249 | |||
| 250 | ;;;; IF KANJI 3/3/KK | ||
| 251 | CALL TESTKANJ | ||
| 252 | JZ NOTKANJ5 | ||
| 253 | MOVSB | ||
| 254 | ; | ||
| 255 | ; Added following 2 commands to the fix pipe bug. | ||
| 256 | ; | ||
| 257 | inc cx ;AN000; 3/3/KK | ||
| 258 | inc cx ;AN000; 3/3/KK | ||
| 259 | ; | ||
| 260 | JMP PIPECOMLP | ||
| 261 | |||
| 262 | NOTKANJ5: | ||
| 263 | ;;;; ENDIF ; 3/3/KK | ||
| 264 | |||
| 265 | CMP AL,0DH | ||
| 266 | JZ LASTPIPE | ||
| 267 | INC CX | ||
| 268 | CMP AL,AltPipeChr | ||
| 269 | JZ IsPipe2 | ||
| 270 | CMP AL,vbar | ||
| 271 | JNZ PIPECOMLP | ||
| 272 | IsPipe2: | ||
| 273 | MOV BYTE PTR ES:[DI-1],0DH | ||
| 274 | DEC CX | ||
| 275 | MOV [COMBUF+1],CL | ||
| 276 | DEC SI | ||
| 277 | MOV [PIPEPTR],SI ; On to next pipe element | ||
| 278 | MOV DX,[OUTPIPEPTR] | ||
| 279 | PUSH CX | ||
| 280 | XOR CX,CX | ||
| 281 | MOV AX,(CREAT SHL 8) | ||
| 282 | INT int_command | ||
| 283 | POP CX | ||
| 284 | JC PIPEERRJ ; Lost the file | ||
| 285 | MOV BX,AX | ||
| 286 | MOV AL,0FFH | ||
| 287 | XCHG AL,[BX.PDB_JFN_Table] | ||
| 288 | MOV DS:[PDB_JFN_Table+1],AL | ||
| 289 | XCHG DX,[INPIPEPTR] ; Swap for next element of pipe | ||
| 290 | MOV [OUTPIPEPTR],DX | ||
| 291 | JMP SHORT PIPECOM | ||
| 292 | |||
| 293 | LASTPIPE: | ||
| 294 | MOV [COMBUF+1],CL | ||
| 295 | DEC SI | ||
| 296 | MOV [PIPEPTR],SI ; Point at the CR (anything not '|' will do) | ||
| 297 | CALL TESTDOREOUT ; Set up the redirection if specified | ||
| 298 | PIPECOM: | ||
| 299 | PUSH CS | ||
| 300 | POP DS | ||
| 301 | JMP NOPIPEPROC ; Process the pipe element | ||
| 302 | |||
| 303 | PIPEEND: | ||
| 304 | CALL PIPEDEL | ||
| 305 | CMP [SINGLECOM],0F000H | ||
| 306 | JNZ NOSINGP2 | ||
| 307 | MOV [SINGLECOM],-1 ; Make it return | ||
| 308 | NOSINGP2: | ||
| 309 | JMP TCOMMAND | ||
| 310 | |||
| 311 | ASSUME DS:TRANGROUP,ES:TRANGROUP | ||
| 312 | |||
| 313 | ; Date and time are set during initialization and use | ||
| 314 | ; this routines since they need to do a long return | ||
| 315 | |||
| 316 | DATINIT PROC FAR | ||
| 317 | mov cs:[resseg],ds ; SetInitFlag needs resseg initialized | ||
| 318 | PUSH ES | ||
| 319 | PUSH DS ; Going to use the previous stack | ||
| 320 | MOV AX,CS ; Set up the appropriate segment registers | ||
| 321 | MOV ES,AX | ||
| 322 | MOV DS,AX | ||
| 323 | invoke TSYSLOADMSG ;AN000; preload messages | ||
| 324 | invoke SETSTDINON ;AN026; turn on critical error on STDIN | ||
| 325 | invoke SETSTDOUTOFF ;AN026; turn off critical error on STDOUT | ||
| 326 | MOV DX,OFFSET TRANGROUP:INTERNATVARS;Set up internat vars | ||
| 327 | MOV AX,INTERNATIONAL SHL 8 | ||
| 328 | INT 21H | ||
| 329 | MOV WORD PTR DS:[81H],13 ; Want to prompt for date during initialization | ||
| 330 | MOV [COMBUF],COMBUFLEN ; Init COMBUF | ||
| 331 | MOV WORD PTR [COMBUF+1],0D01H | ||
| 332 | CALL DATE | ||
| 333 | CALL CTIME | ||
| 334 | POP DS | ||
| 335 | POP ES | ||
| 336 | RET | ||
| 337 | DATINIT ENDP | ||
| 338 | |||
| 339 | ; DATE - Gets and sets the time | ||
| 340 | |||
| 341 | |||
| 342 | break Date | ||
| 343 | |||
| 344 | |||
| 345 | ; **************************************************************** | ||
| 346 | ; * | ||
| 347 | ; * ROUTINE: DATE - Set system date | ||
| 348 | ; * | ||
| 349 | ; * FUNCTION: If a date is specified, set the system date, | ||
| 350 | ; * otherwise display the current system date and | ||
| 351 | ; * prompt the user for a new date. If an invalid | ||
| 352 | ; * date is specified, issue an error message and | ||
| 353 | ; * prompt for a new date. If the user enters | ||
| 354 | ; * nothing when prompted for a date, terminate. | ||
| 355 | ; * | ||
| 356 | ; * INPUT: command line at offset 81H | ||
| 357 | ; * | ||
| 358 | ; * OUTPUT: none | ||
| 359 | ; * | ||
| 360 | ; **************************************************************** | ||
| 361 | |||
| 362 | assume ds:trangroup,es:trangroup | ||
| 363 | |||
| 364 | DATE: | ||
| 365 | MOV SI,81H ; Accepting argument for date inline | ||
| 366 | mov di,offset trangroup:parse_date ;AN000; Get adderss of PARSE_DATE | ||
| 367 | xor cx,cx ;AN000; clear counter for positionals | ||
| 368 | xor dx,dx ;AN000; | ||
| 369 | invoke cmd_parse ;AC000; call parser | ||
| 370 | cmp ax,end_of_line ;AC000; are we at end of line? | ||
| 371 | JZ PRMTDAT ;AC000; yes - go ask for date | ||
| 372 | cmp ax,result_no_error ;AN000; did we have an error? | ||
| 373 | jne daterr ;AN000; yes - go issue message | ||
| 374 | JMP COMDAT ;AC000; we have a date | ||
| 375 | |||
| 376 | PRMTDAT: | ||
| 377 | ; Print "Current date is | ||
| 378 | |||
| 379 | invoke GetDate ;AN000; get date for output | ||
| 380 | xchg dh,dl ;AN000; switch month & day | ||
| 381 | mov CurDat_yr,cx ;AC000; put year into message control block | ||
| 382 | mov CurDat_mo_day,dx ;AC000; put month and day into message control block | ||
| 383 | mov dx,offset trangroup:CurDat_ptr ;AC000; set up message for output | ||
| 384 | invoke std_printf | ||
| 385 | ;AD061; mov CurDat_yr,0 ;AC000; reset year, month and day | ||
| 386 | ;AD061; mov CurDat_mo_day,0 ;AC000; pointers in control block | ||
| 387 | |||
| 388 | GET_NEW_DATE: ;AN000; | ||
| 389 | call getdat ;AC000; prompt user for date | ||
| 390 | cmp ax,end_of_line ;AC000; are we at end of line? | ||
| 391 | jz date_end ;AC000; yes - exit | ||
| 392 | cmp ax,result_no_error ;AN000; did we have an error? | ||
| 393 | jne daterr ;AN000; yes - go issue message | ||
| 394 | COMDAT: | ||
| 395 | mov cx,date_year ;AC000; get parts of date in | ||
| 396 | mov dh,date_month ;AC000; cx and dx for set | ||
| 397 | mov dl,date_day ;AC000; date function call. | ||
| 398 | push cx ;AC000; save date | ||
| 399 | push dx ;AC000; | ||
| 400 | mov cx,1 ;AC000; set 1 positional entered | ||
| 401 | xor dx,dx ;AN029; | ||
| 402 | invoke cmd_parse ;AN029; call parser | ||
| 403 | cmp al,end_of_line ;AN029; Are we at end of line? | ||
| 404 | pop dx ;AC000; retrieve date | ||
| 405 | pop cx ;AC000; | ||
| 406 | jnz daterr ;AC000; extra stuff on line - try again | ||
| 407 | MOV AH,SET_DATE ;yes - set date | ||
| 408 | INT int_command | ||
| 409 | OR AL,AL | ||
| 410 | JNZ DATERR | ||
| 411 | date_end: | ||
| 412 | ret | ||
| 413 | |||
| 414 | DATERR: | ||
| 415 | invoke crlf2 ;AN028; print out a blank line | ||
| 416 | MOV DX,OFFSET TRANGROUP:BADDAT_ptr | ||
| 417 | invoke std_printf | ||
| 418 | JMP GET_NEW_DATE ;AC000; get date again | ||
| 419 | |||
| 420 | |||
| 421 | ; TIME gets and sets the time | ||
| 422 | |||
| 423 | break Time | ||
| 424 | |||
| 425 | ; **************************************************************** | ||
| 426 | ; * | ||
| 427 | ; * ROUTINE: TIME - Set system time | ||
| 428 | ; * | ||
| 429 | ; * FUNCTION: If a time is specified, set the system time, | ||
| 430 | ; * otherwise display the current system time and | ||
| 431 | ; * prompt the user for a new time. If an invalid | ||
| 432 | ; * time is specified, issue an error message and | ||
| 433 | ; * prompt for a new time. If the user enters | ||
| 434 | ; * nothing when prompted for a time, terminate. | ||
| 435 | ; * | ||
| 436 | ; * INPUT: command line at offset 81H | ||
| 437 | ; * | ||
| 438 | ; * OUTPUT: none | ||
| 439 | ; * | ||
| 440 | ; **************************************************************** | ||
| 441 | |||
| 442 | assume ds:trangroup,es:trangroup | ||
| 443 | |||
| 444 | CTIME: | ||
| 445 | MOV SI,81H ; Accepting argument for time inline | ||
| 446 | mov di,offset trangroup:parse_time ;AN000; Get adderss of PARSE_time | ||
| 447 | xor cx,cx ;AN000; clear counter for positionals | ||
| 448 | xor dx,dx ;AN000; | ||
| 449 | invoke cmd_parse ;AC000; call parser | ||
| 450 | cmp ax,end_of_line ;AC000; are we at end of line? | ||
| 451 | JZ PRMTTIM ;AC000; yes - prompt for time | ||
| 452 | cmp ax,result_no_error ;AN000; did we have an error? | ||
| 453 | jne timerr ;AN000; yes - go issue message | ||
| 454 | JMP COMTIM ;AC000; we have a time | ||
| 455 | |||
| 456 | PRMTTIM: | ||
| 457 | ;Printf "Current time is ... " | ||
| 458 | |||
| 459 | MOV AH,GET_TIME ;AC000; get the current time | ||
| 460 | INT int_command ;AC000; Get time in CX:DX | ||
| 461 | xchg ch,cl ;AN000; switch hours & minutes | ||
| 462 | xchg dh,dl ;AN000; switch seconds & hundredths | ||
| 463 | mov CurTim_hr_min,cx ;AC000; put hours and minutes into message subst block | ||
| 464 | mov CurTim_sec_hn,dx ;AC000; put seconds and hundredths into message subst block | ||
| 465 | mov dx,offset trangroup:CurTim_ptr ;AC000; set up message for output | ||
| 466 | invoke std_printf | ||
| 467 | ;AD061; mov CurTim_hr_min,0 ;AC000; reset hour, minutes, seconds, and hundredths | ||
| 468 | ;AD061; mov CurTim_sec_hn,0 ;AC000; pointers in control block | ||
| 469 | |||
| 470 | GET_NEW_TIME: | ||
| 471 | call gettim ;AC000; | ||
| 472 | cmp ax,end_of_line ;AC000; are we at end of line? | ||
| 473 | jz time_end ;AC000; | ||
| 474 | cmp ax,result_no_error ;AN000; did we have an error? | ||
| 475 | jne timerr ;AN000; yes - go issue message | ||
| 476 | |||
| 477 | COMTIM: | ||
| 478 | mov ch,time_hour ;AC000; get parts of time in | ||
| 479 | mov cl,time_minutes ;AC000; cx and dx for set | ||
| 480 | mov dh,time_seconds ;AC000; time function call | ||
| 481 | mov dl,time_fraction ;AC000; | ||
| 482 | push cx ;AC000; save time | ||
| 483 | push dx ;AC000; | ||
| 484 | mov cx,1 ;AC000; set 1 positional parm entered | ||
| 485 | xor dx,dx ;AN029; | ||
| 486 | invoke cmd_parse ;AN029; call parser | ||
| 487 | cmp al,end_of_line ;AN029; Are we at end of line? | ||
| 488 | pop dx ;AC000; retieve time | ||
| 489 | pop cx ;AC000; | ||
| 490 | jnz timerr ;AC000; extra stuff on line - try again | ||
| 491 | |||
| 492 | SAVTIM: | ||
| 493 | MOV AH,SET_TIME | ||
| 494 | INT int_command | ||
| 495 | OR AL,AL | ||
| 496 | JNZ TIMERR ;AC000; if an error occured, try again | ||
| 497 | |||
| 498 | TIME_END: | ||
| 499 | |||
| 500 | ret | ||
| 501 | |||
| 502 | TIMERR: | ||
| 503 | invoke crlf2 ;AN028; print out a blank line | ||
| 504 | MOV DX,OFFSET TRANGROUP:BADTIM_ptr | ||
| 505 | invoke std_printf ; Print error message | ||
| 506 | JMP GET_NEW_TIME ;AC000; Try again | ||
| 507 | |||
| 508 | |||
| 509 | ; | ||
| 510 | ; Set the special flag in the INIT flag to the value in CX. | ||
| 511 | ; | ||
| 512 | SetInitFlag: | ||
| 513 | mov ds,[RESSEG] | ||
| 514 | assume ds:resgroup | ||
| 515 | and InitFlag,NOT initSpecial | ||
| 516 | or InitFlag,cL | ||
| 517 | push cs | ||
| 518 | pop ds | ||
| 519 | return | ||
| 520 | |||
| 521 | Public PipeOff | ||
| 522 | PipeOff: | ||
| 523 | ASSUME DS:NOTHING,ES:NOTHING | ||
| 524 | SaveReg <DS,AX> | ||
| 525 | MOV DS,ResSeg | ||
| 526 | ASSUME DS:RESGroup | ||
| 527 | XOR AL,AL | ||
| 528 | XCHG PipeFlag,AL | ||
| 529 | OR AL,AL | ||
| 530 | JZ PipeOffDone | ||
| 531 | SHR EchoFlag,1 | ||
| 532 | PipeOffDone: | ||
| 533 | RestoreReg <AX,DS> | ||
| 534 | return | ||
| 535 | |||
| 536 | |||
| 537 | PRINT_TIME: | ||
| 538 | |||
| 539 | MOV AH,GET_TIME | ||
| 540 | INT int_command ; Get time in CX:DX | ||
| 541 | |||
| 542 | PUSH ES | ||
| 543 | PUSH CS | ||
| 544 | POP ES | ||
| 545 | xchg ch,cl ;AN000; switch hours & minutes | ||
| 546 | xchg dh,dl ;AN000; switch seconds & hundredths | ||
| 547 | mov promTim_hr_min,cx ;AC000; put hours and minutes into message subst block | ||
| 548 | mov promTim_sec_hn,dx ;AC000; put seconds and hundredths into message subst block | ||
| 549 | mov dx,offset trangroup:promTim_ptr ;AC000; set up message for output | ||
| 550 | invoke std_printf | ||
| 551 | ;AD061; mov promTim_hr_min,0 ;AC000; reset hour, minutes, seconds, and hundredths | ||
| 552 | ;AD061; mov promTim_sec_hn,0 ;AC000; pointers in control block | ||
| 553 | |||
| 554 | POP ES | ||
| 555 | return | ||
| 556 | |||
| 557 | |||
| 558 | ; **************************************************************** | ||
| 559 | ; * | ||
| 560 | ; * ROUTINE: GETDAT - Prompt user for date | ||
| 561 | ; * | ||
| 562 | ; * FUNCTION: Gets the date format from the COUNTRY DEPENDENT | ||
| 563 | ; * INFORMATION and issues the "Enter new date" | ||
| 564 | ; * message with the proper date format. COMBUF | ||
| 565 | ; * is reset to get a date from the command line. | ||
| 566 | ; * The PARSE_DATE blocks are then reset and the | ||
| 567 | ; * PARSE function call is issued. | ||
| 568 | ; * | ||
| 569 | ; * INPUT: NONE | ||
| 570 | ; * | ||
| 571 | ; * OUTPUT: COMBUF | ||
| 572 | ; * PARSER RETURN CODES | ||
| 573 | ; * | ||
| 574 | ; **************************************************************** | ||
| 575 | |||
| 576 | |||
| 577 | GETDAT proc near ;AC000; | ||
| 578 | |||
| 579 | mov ax,(International SHL 8) ; Determine what format the date | ||
| 580 | mov dx,5ch ; should be entered in and | ||
| 581 | int int_command ; print a message describing it | ||
| 582 | mov si,dx | ||
| 583 | lodsw | ||
| 584 | mov dx,usadat_ptr ;AC000; get mm-dd-yy | ||
| 585 | dec ax | ||
| 586 | js printformat | ||
| 587 | mov dx,eurdat_ptr ;AC000; get dd-mm-yy | ||
| 588 | jz printformat | ||
| 589 | mov dx,japdat_ptr ;AC000; get yy-mm-dd | ||
| 590 | printformat: | ||
| 591 | mov ax,dx ;AN000; get message number of format | ||
| 592 | mov dh,util_msg_class ;AN000; this is a utility message | ||
| 593 | call Tsysgetmsg ;AN000; get the address of the message | ||
| 594 | mov newdat_format,si ;AN000; put the address in subst block | ||
| 595 | MOV DX,OFFSET TRANGROUP:NEWDAT_ptr ;AC000; get address of message to print | ||
| 596 | invoke std_printf | ||
| 597 | mov newdat_format,no_subst ;AN000; reset subst block | ||
| 598 | |||
| 599 | MOV AH,STD_CON_STRING_INPUT | ||
| 600 | MOV DX,OFFSET TRANGROUP:COMBUF | ||
| 601 | mov cx,initSpecial ; Set bit in InitFlag that indicates | ||
| 602 | call SetInitFlag ; prompting for date. | ||
| 603 | INT int_command ; Get input line | ||
| 604 | xor cx,cx ; Reset bit in InitFlag that indicates | ||
| 605 | call SetInitFlag ; prompting for date. | ||
| 606 | invoke CRLF2 | ||
| 607 | MOV SI,OFFSET TRANGROUP:COMBUF+2 | ||
| 608 | mov di,offset trangroup:parse_date ;AN000; Get adderss of PARSE_DATE | ||
| 609 | xor cx,cx ;AN000; clear counter for positionals | ||
| 610 | xor dx,dx ;AN000; | ||
| 611 | invoke cmd_parse ;AC000; call parser | ||
| 612 | |||
| 613 | ret | ||
| 614 | |||
| 615 | GETDAT endp ;AC000; | ||
| 616 | |||
| 617 | |||
| 618 | ; **************************************************************** | ||
| 619 | ; * | ||
| 620 | ; * ROUTINE: GETTIME - Prompt user for time | ||
| 621 | ; * | ||
| 622 | ; * FUNCTION: Gets the time format from the COUNTRY DEPENDENT | ||
| 623 | ; * INFORMATION and issues the "Enter new time" | ||
| 624 | ; * message. COMBUF is reset to get a time from the | ||
| 625 | ; * command line. The PARSE_TIME blocks are then | ||
| 626 | ; * reset and the PARSE function call is issued. | ||
| 627 | ; * | ||
| 628 | ; * INPUT: NONE | ||
| 629 | ; * | ||
| 630 | ; * OUTPUT: COMBUF | ||
| 631 | ; * PARSER RETURN CODES | ||
| 632 | ; * | ||
| 633 | ; **************************************************************** | ||
| 634 | |||
| 635 | |||
| 636 | GETTIM proc near ;AC000; | ||
| 637 | |||
| 638 | XOR CX,CX ; Initialize hours and minutes to zero | ||
| 639 | MOV DX,OFFSET TRANGROUP:NEWTIM_ptr | ||
| 640 | invoke std_printf | ||
| 641 | MOV AH,STD_CON_STRING_INPUT | ||
| 642 | MOV DX,OFFSET TRANGROUP:COMBUF | ||
| 643 | mov cx,initSpecial ; Set bit in InitFlag that indicates | ||
| 644 | call SetInitFlag ; prompting for time. | ||
| 645 | INT int_command ; Get input line | ||
| 646 | xor cx,cx ; Reset bit in InitFlag that indicates | ||
| 647 | call SetInitFlag ; prompting for time. | ||
| 648 | invoke CRLF2 | ||
| 649 | MOV SI,OFFSET TRANGROUP:COMBUF+2 | ||
| 650 | mov di,offset trangroup:parse_time ;AN000; Get adderss of PARSE_TIME | ||
| 651 | xor cx,cx ;AN000; clear counter for positionals | ||
| 652 | xor dx,dx ;AN000; | ||
| 653 | invoke cmd_parse ;AC000; call parser | ||
| 654 | |||
| 655 | ret | ||
| 656 | |||
| 657 | GETTIM endp ;AC000; | ||
| 658 | |||
| 659 | TRANCODE ENDS | ||
| 660 | END | ||
diff --git a/v4.0/src/CMD/COMMAND/TPRINTF.ASM b/v4.0/src/CMD/COMMAND/TPRINTF.ASM new file mode 100644 index 0000000..c502f83 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/TPRINTF.ASM | |||
| @@ -0,0 +1,365 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)tprintf.asm 4.3 85/07/02 | ||
| 3 | ; SCCSID = @(#)tprintf.asm 4.3 85/07/02 | ||
| 4 | TITLE COMMAND Transient Printf routine | ||
| 5 | |||
| 6 | ;**************************************************************** | ||
| 7 | ;* | ||
| 8 | ;* ROUTINE: STD_PRINTF/STD_EPRINTF | ||
| 9 | ;* | ||
| 10 | ;* FUNCTION: Set up to print out a message using SYSDISPMSG. | ||
| 11 | ;* Set up substitutions if utility message. Make | ||
| 12 | ;* sure any changes to message variables in TDATA | ||
| 13 | ;* are reset to avoid reloading the transient. | ||
| 14 | ;* | ||
| 15 | ;* INPUT: Msg_Disp_Class - set to message class | ||
| 16 | ;* Msg_Cont_Flag - set to control flags | ||
| 17 | ;* DS points to transient segment | ||
| 18 | ;* | ||
| 19 | ;* if utility message: | ||
| 20 | ;* DX points to a block with message number | ||
| 21 | ;* (word), number of substitutions (byte), | ||
| 22 | ;* followed by substitution list if there | ||
| 23 | ;* are substitutions. If substitutions | ||
| 24 | ;* are not in transient segment they must | ||
| 25 | ;* be set. | ||
| 26 | ;* else | ||
| 27 | ;* AX set to message number | ||
| 28 | ;* | ||
| 29 | ;* OUTPUT: none | ||
| 30 | ;* | ||
| 31 | ;**************************************************************** | ||
| 32 | |||
| 33 | .xlist | ||
| 34 | .xcref | ||
| 35 | INCLUDE comsw.asm ;AC000; | ||
| 36 | INCLUDE DOSSYM.INC | ||
| 37 | INCLUDE comseg.asm | ||
| 38 | INCLUDE comequ.asm ;AN000; | ||
| 39 | INCLUDE SYSMSG.INC ;AN000; | ||
| 40 | .list | ||
| 41 | .cref | ||
| 42 | |||
| 43 | datares segment public | ||
| 44 | extrn pipeflag:byte | ||
| 45 | datares ends | ||
| 46 | |||
| 47 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 48 | EXTRN extend_buf_off:word ;AN000; | ||
| 49 | EXTRN Extend_Buf_ptr:word ;AN000; | ||
| 50 | EXTRN Extend_Buf_seg:word ;AN000; | ||
| 51 | EXTRN Msg_Cont_Flag:byte ;AN000; | ||
| 52 | EXTRN Msg_disp_Class:byte ;AN000; | ||
| 53 | EXTRN pipeemes_ptr:word | ||
| 54 | TRANDATA ENDS | ||
| 55 | |||
| 56 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 57 | EXTRN msg_flag:byte ;AN022; | ||
| 58 | EXTRN print_err_flag:word ;AN000; | ||
| 59 | EXTRN RESSEG:WORD | ||
| 60 | EXTRN String_ptr_2:word ;AC000; | ||
| 61 | EXTRN Subst_buffer:byte ;AN061; | ||
| 62 | ;AD061; EXTRN String_ptr_2_sb:word ;AN000; | ||
| 63 | |||
| 64 | ; include data area for message services | ||
| 65 | |||
| 66 | MSG_UTILNAME <COMMAND> ;AN000; define utility name | ||
| 67 | |||
| 68 | MSG_SERVICES <MSGDATA> ;AN000; | ||
| 69 | |||
| 70 | PRINTF_HANDLE DW ? ;AC000; | ||
| 71 | |||
| 72 | TRANSPACE ENDS ;AC000; | ||
| 73 | |||
| 74 | TRANCODE SEGMENT PUBLIC BYTE ;AC000; | ||
| 75 | |||
| 76 | EXTRN cerror:near | ||
| 77 | EXTRN crlf2:near | ||
| 78 | EXTRN tcommand:near ;AN026; | ||
| 79 | |||
| 80 | ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:NOTHING,SS:NOTHING ;AC000; | ||
| 81 | |||
| 82 | PUBLIC SETSTDINOFF ;AN026; | ||
| 83 | PUBLIC SETSTDINON ;AN026; | ||
| 84 | PUBLIC SETSTDOUTOFF ;AN026; | ||
| 85 | PUBLIC SETSTDOUTON ;AN026; | ||
| 86 | PUBLIC TSYSGETMSG ;AN000; | ||
| 87 | PUBLIC TSYSLOADMSG ;AN000; | ||
| 88 | |||
| 89 | PUBLIC Printf_Init | ||
| 90 | printf_init proc far | ||
| 91 | call std_printf | ||
| 92 | ret | ||
| 93 | printf_init endp | ||
| 94 | |||
| 95 | Public Printf_Crlf | ||
| 96 | PRINTF_CRLF: | ||
| 97 | CALL STD_PRINTF | ||
| 98 | CALL CRLF2 | ||
| 99 | RET | ||
| 100 | |||
| 101 | PUBLIC Std_EPrintf | ||
| 102 | STD_EPRINTF: | ||
| 103 | mov Printf_Handle,2 ;AC000;Print to STDERR | ||
| 104 | jmp short NEW_PRINTF ;AC000; | ||
| 105 | PUBLIC Std_Printf | ||
| 106 | STD_PRINTF: | ||
| 107 | mov Printf_Handle,1 ;AC000;Print to STDOUT | ||
| 108 | |||
| 109 | NEW_PRINTF: | ||
| 110 | push ax ;AN000;save registers | ||
| 111 | push bx ;AN000; | ||
| 112 | push cx ;AN000; | ||
| 113 | push es ;AN000;get local ES | ||
| 114 | push ds ;AN000; | ||
| 115 | pop es ;AN000; | ||
| 116 | push di ;AN000; | ||
| 117 | push si ;AN000; | ||
| 118 | push dx ;AN000; | ||
| 119 | assume es:trangroup ;AN000; | ||
| 120 | ;AD061; mov string_ptr_2_sb,0 ;AN000;initialize | ||
| 121 | mov print_err_flag,0 ;AN000; | ||
| 122 | |||
| 123 | UTILITY_SETUP: | ||
| 124 | mov si,dx ;AN000;Get offset of message number | ||
| 125 | lodsw ;AN000;load message number | ||
| 126 | push ax ;AN000;save it | ||
| 127 | lodsb ;AN000;get number of substitutions | ||
| 128 | mov cl,al ;AN000;set up CX as # of subst | ||
| 129 | xor ch,ch ;AN000; SI now points to subst list | ||
| 130 | pop ax ;AN000;get message number back | ||
| 131 | cmp cx,0 ;AN000;Any substitutions? | ||
| 132 | jz READY_TO_PRINT ;AN000;No - continue | ||
| 133 | |||
| 134 | ;AD061; add dx,Ptr_Seg_Pos ;AN000;Point to position of first segment | ||
| 135 | ;AD061; push cx ;AN000;save substitution count | ||
| 136 | |||
| 137 | ;AD061;SET_SUBST: | ||
| 138 | ;AD061; mov bx,dx ;AN000;get dx into base register | ||
| 139 | ;AD061; cmp word ptr [bx],0 ;AN000;has segment been set? | ||
| 140 | ;AD061; jnz SUBST_SEG_SET ;AN000;if not 0, don't replace it | ||
| 141 | ;AD061; test word ptr [bx+3],date_type ;AN000;if date or time - don't set segment | ||
| 142 | ;AD061; jnz subst_seg_set ;AN000;yes - skip it | ||
| 143 | ;AD061; mov word ptr [bx],cs ;AN000;put segment of subst parm in list | ||
| 144 | |||
| 145 | ;AD061;SUBST_SEG_SET: | ||
| 146 | ;AD061; add dx,Parm_Block_Size ;AN000;point to position of next segment | ||
| 147 | ;AD061; loop SET_SUBST ;AN000;keep replacing until complete | ||
| 148 | ;AD061; pop cx ;AN000; | ||
| 149 | |||
| 150 | ;AD061;NO_REPLACEMENT: | ||
| 151 | ;AD061; mov bx,parm_off_pos [si] ;AN000;get subst offset | ||
| 152 | ;AD061; cmp bx,offset trangroup:string_ptr_2 ;AN000;this is used for double indirection | ||
| 153 | ;AD061; jnz ready_to_print ;AN000;we already have address | ||
| 154 | ;AD061; mov dx,string_ptr_2 ;AN000;get address in string_ptr_2 | ||
| 155 | ;AD061; mov parm_off_pos [si],dx ;AN000;put proper address in table | ||
| 156 | ;AD061; mov string_ptr_2_sb,si ;AN000;save block changed | ||
| 157 | |||
| 158 | mov di,offset trangroup:subst_buffer;AN061; Get address of message subst buffer | ||
| 159 | push di ;AN061; save it | ||
| 160 | push cx ;AN061; save number of subst | ||
| 161 | |||
| 162 | MOVE_SUBST: | ||
| 163 | push cx ;AN061;save number of subst | ||
| 164 | mov bx,si ;AN061;save start of sublist | ||
| 165 | mov cx,parm_block_size ;AN061;get size of sublist | ||
| 166 | rep movsb ;AN061;move sublist | ||
| 167 | test byte ptr [bx.$M_S_FLAG],date_type ;AN061;are we doing date/time? | ||
| 168 | jz move_subst_cont ;AN061;no - no need to reset | ||
| 169 | mov word ptr [bx.$M_S_VALUE],0 ;AN061;reset original date or time to 0 | ||
| 170 | mov word ptr [bx.$M_S_VALUE+2],0 ;AN061; | ||
| 171 | |||
| 172 | MOVE_SUBST_CONT: ;AN061; | ||
| 173 | pop cx ;AN061;get number of subst back | ||
| 174 | loop move_subst ;AN061;move cx sublists | ||
| 175 | |||
| 176 | pop cx ;AN061;get number of subst | ||
| 177 | push ax ;AN061;save message number | ||
| 178 | cmp Msg_Disp_Class,Util_Msg_Class ;AN061;Is this a utility message | ||
| 179 | jz CHECK_FIX ;AN061;YES - go see if substitutions | ||
| 180 | mov msg_flag,ext_msg_class ;AN061;set message flag | ||
| 181 | mov di,offset trangroup:extend_buf_ptr ;AN061; Get address of extended message block | ||
| 182 | xor ax,ax ;AN061;clear ax register | ||
| 183 | stosw ;AN061;clear out message number | ||
| 184 | stosb ;AN061;clear out subst count | ||
| 185 | |||
| 186 | CHECK_FIX: ;AN061; | ||
| 187 | pop ax ;AN061;get message number back | ||
| 188 | pop di ;AN061;get start of sublists | ||
| 189 | mov si,di ;AN061;get into SI for msgserv | ||
| 190 | mov bx,si ;AN061;get into BX for addressing | ||
| 191 | push cx ;AN061;save number of subst | ||
| 192 | |||
| 193 | SET_SUBST: ;AN061;store the segment of the subst | ||
| 194 | cmp word ptr [bx.$M_S_VALUE+2],0 ;AN061;was it set already? | ||
| 195 | jnz subst_seg_set ;AN061;if not 0, don't replace it | ||
| 196 | test byte ptr [bx.$M_S_FLAG],date_type ;AN061;don't replace if date or time | ||
| 197 | jnz subst_seg_set ;AN061;yes - skip it | ||
| 198 | mov word ptr [bx.$M_S_VALUE+2],cs ;AN061;set segment value | ||
| 199 | |||
| 200 | SUBST_SEG_SET: ;AN061; | ||
| 201 | add bx,parm_block_size ;AN061;go to next sublist | ||
| 202 | loop set_subst ;AN061;loop CX times | ||
| 203 | pop cx ;AN061;get number of subst back | ||
| 204 | |||
| 205 | mov bx,si ;AN061;get start of sublist to BX | ||
| 206 | cmp word ptr [bx.$M_S_VALUE],offset trangroup:string_ptr_2 ;AN061;are we using double indirection? | ||
| 207 | jnz ready_to_print ;AN061;no - we already have address | ||
| 208 | mov dx,string_ptr_2 ;AN061;get address in string_ptr_2 | ||
| 209 | mov word ptr [bx.$M_S_VALUE],dx ;AN061;put it into the subst block | ||
| 210 | |||
| 211 | READY_TO_PRINT: | ||
| 212 | mov bx,Printf_Handle ;AN000;get print handle | ||
| 213 | mov dl,Msg_Cont_Flag ;AN000;set up control flag | ||
| 214 | mov dh,Msg_Disp_Class ;AN000;set up display class | ||
| 215 | mov Msg_Cont_Flag,No_Cont_Flag ;AN061;reset flags to avoid | ||
| 216 | mov Msg_Disp_Class,Util_Msg_Class ;AN061; transient reload | ||
| 217 | |||
| 218 | ;AD061; push bx ;AN026; save registers | ||
| 219 | ;AD061; push cx ;AN026; | ||
| 220 | ;AD061; push dx ;AN026; | ||
| 221 | ;AD061; push si ;AN026; | ||
| 222 | ;AD061; push di ;AN026; | ||
| 223 | push ds ;AN026; | ||
| 224 | push es ;AN026; | ||
| 225 | |||
| 226 | |||
| 227 | call SYSDISPMSG ;AN000;call Rod | ||
| 228 | |||
| 229 | pop es ;AN026; restore registers | ||
| 230 | pop ds ;AN026; | ||
| 231 | ;AD061; pop di ;AN026; | ||
| 232 | ;AD061; pop si ;AN026; | ||
| 233 | ;AD061; pop dx ;AN026; | ||
| 234 | ;AD061; pop cx ;AN026; | ||
| 235 | ;AD061; pop bx ;AN026; | ||
| 236 | |||
| 237 | jnc Print_success ;AN000; everything went okay | ||
| 238 | mov print_err_flag,ax ;AN000; | ||
| 239 | |||
| 240 | print_success: | ||
| 241 | ;AD061; cmp Msg_Disp_Class,Util_Msg_Class ;AN000;Is this a utility message | ||
| 242 | ;AD061; jz CHECK_FIX ;AN000;YES - go see if substitutions | ||
| 243 | ;AD061; mov msg_flag,ext_msg_class ;AN022;set message flag | ||
| 244 | ;AD061; mov di,offset trangroup:extend_buf_ptr ;AN000; Get address of extended message block | ||
| 245 | ;AD061; xor ax,ax ;AN000;clear ax register | ||
| 246 | ;AD061; stosw ;AN000;clear out message number | ||
| 247 | ;AD061; stosb ;AN000;clear out subst count | ||
| 248 | |||
| 249 | ;AD061; CHECK_FIX: | ||
| 250 | ;AD061; pop dx ;AN000;restore dx | ||
| 251 | ;AD061; cmp cx,0 ;AN000;Any substitutions? | ||
| 252 | ;AD061; jz NO_FIXUP ;AN000;No - leave | ||
| 253 | |||
| 254 | ;AD061; mov si,dx ;AN000;Reset changes so transient won't reload | ||
| 255 | ;AD061; add si,Ptr_Seg_Pos ;AN000;Point to position of first segment | ||
| 256 | |||
| 257 | ;AD061;FIX_SUBST: | ||
| 258 | ;AD061; mov word ptr [si],0 ;AN000;reset segment to 0 | ||
| 259 | ;AD061; add si,Parm_Block_Size ;AN000;point to position of next segment | ||
| 260 | ;AD061; loop FIX_SUBST ;AN000;keep replacing until complete | ||
| 261 | ;AD061; cmp string_ptr_2_sb,no_subst ;AN000;was double indirection used? | ||
| 262 | ;AD061; jz no_fixup ;AN000;no - we're finished | ||
| 263 | ;AD061; mov si,string_ptr_2_sb ;AN000;get offset changed | ||
| 264 | ;AD061; mov parm_off_pos [si],offset trangroup:string_ptr_2 ;AN000; set address back to string_ptr_2 | ||
| 265 | |||
| 266 | ;AD061;NO_FIXUP: | ||
| 267 | ;AD061; mov Msg_Cont_Flag,No_Cont_Flag ;AN000;reset flags to avoid | ||
| 268 | ;AD061; mov Msg_Disp_Class,Util_Msg_Class ;AN000; transient reload | ||
| 269 | pop dx ;AN061;restore dx | ||
| 270 | pop si ;AN000;restore registers | ||
| 271 | pop di ;AN000; | ||
| 272 | pop es ;AN000;restore registers | ||
| 273 | pop cx ;AN000; | ||
| 274 | pop bx ;AN000; | ||
| 275 | pop ax ;AN000; | ||
| 276 | cmp print_err_flag,0 ;AN000; if an error occurred - handle it | ||
| 277 | jnz print_err ;AN000; | ||
| 278 | |||
| 279 | ret ;AC000; | ||
| 280 | |||
| 281 | print_err: | ||
| 282 | push cs | ||
| 283 | pop es | ||
| 284 | cmp Printf_Handle,2 ;AN026;Print to STDERR? | ||
| 285 | jnz not_stderr ;AN026;no - continue | ||
| 286 | jmp tcommand ;AN026;Yes - hopless - just exit | ||
| 287 | |||
| 288 | not_stderr: | ||
| 289 | mov ax,print_err_flag ;AN026;get extended error number back | ||
| 290 | mov es,[resseg] ; No, set up for error, load the | ||
| 291 | assume es:resgroup ; right error msg, and jmp to cerror. | ||
| 292 | test PipeFlag,-1 | ||
| 293 | jz go_to_error | ||
| 294 | invoke PipeOff | ||
| 295 | mov dx,offset trangroup:pipeemes_ptr | ||
| 296 | jmp print_err_exit ;AC000; | ||
| 297 | |||
| 298 | go_to_error: | ||
| 299 | mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class | ||
| 300 | mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer | ||
| 301 | mov Extend_Buf_ptr,ax ;AN000; get message number in control block | ||
| 302 | |||
| 303 | PRINT_ERR_EXIT: ;AC000; | ||
| 304 | push cs | ||
| 305 | pop es | ||
| 306 | JMP CERROR | ||
| 307 | |||
| 308 | ;**************************************************************** | ||
| 309 | ;* | ||
| 310 | ;* ROUTINE: TSYSLOADMSG | ||
| 311 | ;* | ||
| 312 | ;* FUNCTION: Interface to call SYSLOADMSG to avoid duplicate | ||
| 313 | ;* names since these routines are also used in the | ||
| 314 | ;* resident. | ||
| 315 | ;* | ||
| 316 | ;* INPUT: Inputs to SYSLOADMSG | ||
| 317 | ;* | ||
| 318 | ;* OUTPUT: Outputs from SYSLOADMSG | ||
| 319 | ;* | ||
| 320 | ;**************************************************************** | ||
| 321 | |||
| 322 | |||
| 323 | TSYSLOADMSG PROC NEAR ;AN000; | ||
| 324 | |||
| 325 | push bx ;AN000; | ||
| 326 | call sysloadmsg ;AN000; call routine | ||
| 327 | pop bx ;AN000; | ||
| 328 | ret ;AN000; exit | ||
| 329 | |||
| 330 | TSYSLOADMSG ENDP ;AN000; | ||
| 331 | |||
| 332 | ;**************************************************************** | ||
| 333 | ;* | ||
| 334 | ;* ROUTINE: TSYSGETMSG | ||
| 335 | ;* | ||
| 336 | ;* FUNCTION: Interface to call SYSGETMSG to avoid duplicate | ||
| 337 | ;* names since these routines are also used in the | ||
| 338 | ;* resident. | ||
| 339 | ;* | ||
| 340 | ;* INPUT: Inputs to SYSGETMSG | ||
| 341 | ;* | ||
| 342 | ;* OUTPUT: Outputs from SYSGETMSG | ||
| 343 | ;* | ||
| 344 | ;**************************************************************** | ||
| 345 | |||
| 346 | |||
| 347 | TSYSGETMSG PROC NEAR ;AN000; | ||
| 348 | |||
| 349 | push cx ;AN000; | ||
| 350 | call sysgetmsg ;AN000; call routine | ||
| 351 | pop cx ;AN000; | ||
| 352 | ret ;AN000; exit | ||
| 353 | |||
| 354 | TSYSGETMSG ENDP ;AN000; | ||
| 355 | |||
| 356 | MSG_SERVICES <COMT,NOVERCHECKmsg,NEARmsg,LOADmsg,NOCHECKSTDIN,NOCHECKSTDOUT,GETmsg> ;AC026; The message services | ||
| 357 | MSG_SERVICES <COMT,NEARmsg,SETSTDIO,DISPLAYmsg,CHARmsg,NUMmsg,TIMEmsg,DATEmsg> ;AC026; The message services | ||
| 358 | |||
| 359 | PRINTF_LAST LABEL WORD | ||
| 360 | |||
| 361 | include msgdcl.inc | ||
| 362 | |||
| 363 | |||
| 364 | TRANCODE ENDS | ||
| 365 | END | ||
diff --git a/v4.0/src/CMD/COMMAND/TRANMSG.ASM b/v4.0/src/CMD/COMMAND/TRANMSG.ASM new file mode 100644 index 0000000..38b04ba --- /dev/null +++ b/v4.0/src/CMD/COMMAND/TRANMSG.ASM | |||
| @@ -0,0 +1,671 @@ | |||
| 1 | |||
| 2 | ;**************************************************** | ||
| 3 | ;* TRANSIENT MESSAGE POINTERS & SUBSTITUTION BLOCKS * | ||
| 4 | ;**************************************************** | ||
| 5 | |||
| 6 | msg_disp_class db Util_msg_class | ||
| 7 | msg_cont_flag db No_cont_flag | ||
| 8 | |||
| 9 | ; extended error string output | ||
| 10 | ; | ||
| 11 | Extend_Buf_ptr dw 0 ;AN000;set to no message | ||
| 12 | Extend_Buf_sub db 0 ;AN000;set to no substitutions | ||
| 13 | db parm_block_size ;AN000;size of sublist | ||
| 14 | db 0 ;AN000;reserved | ||
| 15 | Extend_Buf_off dw OFFSET TranGroup:String_ptr_2 ;AN000;offset of arg | ||
| 16 | Extend_Buf_seg dw 0 ;AN000;segment of arg | ||
| 17 | db 0 ;AN000;first subst | ||
| 18 | db Char_field_ASCIIZ ;AN000;character string | ||
| 19 | db 128 ;AN000;maximum width | ||
| 20 | db 0 ;AN000;minimum width | ||
| 21 | db blank ;AN000;pad character | ||
| 22 | |||
| 23 | ; "Duplicate file name or file not found" | ||
| 24 | ; | ||
| 25 | Renerr_Ptr dw 1002 ;AN000;message number | ||
| 26 | db no_subst ;AN000;number of subst | ||
| 27 | |||
| 28 | ; "Invalid path or file name" | ||
| 29 | ; | ||
| 30 | BadCPMes_Ptr dw 1003 ;AN000;message number | ||
| 31 | db no_subst ;AN000;number of subst | ||
| 32 | |||
| 33 | ; "Insufficient disk space" | ||
| 34 | ; | ||
| 35 | NoSpace_Ptr dw 1004 ;AN000;message number | ||
| 36 | db no_subst ;AN000;number of subst | ||
| 37 | |||
| 38 | ; "Out of environment space" | ||
| 39 | ; | ||
| 40 | EnvErr_Ptr dw 1007 ;AN000;message number | ||
| 41 | db no_subst ;AN000;number of subst | ||
| 42 | |||
| 43 | ; "File creation error" | ||
| 44 | ; | ||
| 45 | FulDir_Ptr dw 1008 ;AN000;message number | ||
| 46 | db no_subst ;AN000;number of subst | ||
| 47 | |||
| 48 | ; "Batch file missing",13,10 | ||
| 49 | ; | ||
| 50 | BadBat_Ptr dw 1009 ;AN000;message number | ||
| 51 | db no_subst ;AN000;number of subst | ||
| 52 | |||
| 53 | ; "Insert disk with batch file",13,10 | ||
| 54 | ; | ||
| 55 | NeedBat_Ptr dw 1010 ;AN000;message number | ||
| 56 | db no_subst ;AN000;number of subst | ||
| 57 | |||
| 58 | ; "Bad command or file name",13,10 | ||
| 59 | ; | ||
| 60 | BadNam_Ptr dw 1011 ;AN000;message number | ||
| 61 | db no_subst ;AN000;number of subst | ||
| 62 | |||
| 63 | |||
| 64 | ; "Access denied",13,10 | ||
| 65 | ; | ||
| 66 | AccDen_Ptr dw 1014 ;AN000;message number | ||
| 67 | db no_subst ;AN000;number of subst | ||
| 68 | |||
| 69 | ; "File cannot be copied onto itself",13,10 | ||
| 70 | ; | ||
| 71 | OverWr_Ptr dw 1015 ;AN000;message number | ||
| 72 | db no_subst ;AN000;number of subst | ||
| 73 | |||
| 74 | ; "Content of destination lost before copy",13,10 | ||
| 75 | ; | ||
| 76 | LostErr_Ptr dw 1016 ;AN000;message number | ||
| 77 | db no_subst ;AN000;number of subst | ||
| 78 | |||
| 79 | ; "Invalid filename or file not found",13,10 | ||
| 80 | ; | ||
| 81 | InOrNot_Ptr dw 1017 ;AN000;message number | ||
| 82 | db no_subst ;AN000;number of subst | ||
| 83 | |||
| 84 | ; "%1 File(s) copied",13,10 | ||
| 85 | ; | ||
| 86 | Copied_Ptr dw 1018 ;AN000;message number | ||
| 87 | db 1 ;AN000;number of subst | ||
| 88 | db parm_block_size ;AN000;size of sublist | ||
| 89 | db 0 ;AN000;reserved | ||
| 90 | dw OFFSET TranGroup:Copy_num ;AN000;offset of arg | ||
| 91 | dw 0 ;AN000;segment of arg | ||
| 92 | db 1 ;AN000;first subst | ||
| 93 | db Right_Align+Unsgn_Bin_Word ;AN000;binary to decimal | ||
| 94 | db 9 ;AN000;maximum width | ||
| 95 | db 9 ;AN000;minimum width | ||
| 96 | db blank ;AN000;pad character | ||
| 97 | |||
| 98 | ; "%1 File(s) " | ||
| 99 | ; | ||
| 100 | DirMes_Ptr dw 1019 ;AN000;message number | ||
| 101 | db 1 ;AN000;number of subst | ||
| 102 | db parm_block_size ;AN000;size of sublist | ||
| 103 | db 0 ;AN000;reserved | ||
| 104 | dw OFFSET TranGroup:Dir_num ;AN000;offset of arg | ||
| 105 | dw 0 ;AN000;segment of arg | ||
| 106 | db 1 ;AN000;first subst | ||
| 107 | db Right_Align+Unsgn_Bin_Word ;AN000;binary to decimal | ||
| 108 | db 9 ;AN000;maximum width | ||
| 109 | db 9 ;AN000;minimum width | ||
| 110 | db blank ;AN000;pad character | ||
| 111 | |||
| 112 | ; "%1 bytes free",13,10 | ||
| 113 | ; | ||
| 114 | BytMes_Ptr dw 1020 ;AN000;message number | ||
| 115 | db 1 ;AN000;number of subst | ||
| 116 | db parm_block_size ;AN000;size of sublist | ||
| 117 | db 0 ;AN000;reserved | ||
| 118 | dw OFFSET TranGroup:Bytes_Free ;AN000;offset of arg | ||
| 119 | dw 0 ;AN000;segment of arg | ||
| 120 | db 1 ;AN000;first subst | ||
| 121 | db Right_Align+Unsgn_Bin_DWord ;AN000;long binary to decimal | ||
| 122 | db 10 ;AN000;maximum width | ||
| 123 | db 10 ;AN000;minimum width | ||
| 124 | db blank ;AN000;pad character | ||
| 125 | |||
| 126 | ; "Invalid drive specification",13,10 | ||
| 127 | ; | ||
| 128 | BadDrv_Ptr dw 1021 ;AN000;message number | ||
| 129 | db no_subst ;AN000;number of subst | ||
| 130 | |||
| 131 | |||
| 132 | ; "Code page %1 not prepared for system",13,10 | ||
| 133 | ; | ||
| 134 | CP_not_set_Ptr dw 1022 ;AN000;message number | ||
| 135 | db 1 ;AN000;number of subst | ||
| 136 | db parm_block_size ;AN000;size of sublist | ||
| 137 | db 0 ;AN000;reserved | ||
| 138 | dw OFFSET TranGroup:System_cpage ;AN000;offset of arg | ||
| 139 | dw 0 ;AN000;segment of arg | ||
| 140 | db 1 ;AN000;first subst | ||
| 141 | db Right_Align+Unsgn_Bin_Word ;AN000;binary to decimal | ||
| 142 | db 5 ;AN000;maximum width | ||
| 143 | db 1 ;AN000;minimum width | ||
| 144 | db blank ;AN000;pad character | ||
| 145 | |||
| 146 | ; "Code page %1 not prepared for all devices",13,10 | ||
| 147 | ; | ||
| 148 | CP_not_all_Ptr dw 1023 ;AN000;message number | ||
| 149 | db 1 ;AN000;number of subst | ||
| 150 | db parm_block_size ;AN000;size of sublist | ||
| 151 | db 0 ;AN000;reserved | ||
| 152 | dw OFFSET TranGroup:System_cpage ;AN000;offset of arg | ||
| 153 | dw 0 ;AN000;segment of arg | ||
| 154 | db 1 ;AN000;first subst | ||
| 155 | db Right_Align+Unsgn_Bin_Word ;AN000;binary to decimal | ||
| 156 | db 5 ;AN000;maximum width | ||
| 157 | db 1 ;AN000;minimum width | ||
| 158 | db blank ;AN000;pad character | ||
| 159 | |||
| 160 | ; "Active code page: %1",13,10 | ||
| 161 | ; | ||
| 162 | CP_active_Ptr dw 1024 ;AN000;message number | ||
| 163 | db 1 ;AN000;number of subst | ||
| 164 | db parm_block_size ;AN000;size of sublist | ||
| 165 | db 0 ;AN000;reserved | ||
| 166 | dw OFFSET TranGroup:System_cpage ;AN000;offset of arg | ||
| 167 | dw 0 ;AN000;segment of arg | ||
| 168 | db 1 ;AN000;first subst | ||
| 169 | db Right_Align+Unsgn_Bin_Word ;AN000;binary to decimal | ||
| 170 | db 5 ;AN000;maximum width | ||
| 171 | db 1 ;AN000;minimum width | ||
| 172 | db blank ;AN000;pad character | ||
| 173 | |||
| 174 | ; "NLSFUNC not installed",13,10 | ||
| 175 | ; | ||
| 176 | NLSFUNC_Ptr dw 1025 ;AN000;message number | ||
| 177 | db no_subst ;AN000;number of subst | ||
| 178 | |||
| 179 | ; "Invalid code page",13,10 | ||
| 180 | ; | ||
| 181 | Inv_Code_Page dw 1026 ;AN000;message number | ||
| 182 | db no_subst ;AN000;number of subst | ||
| 183 | |||
| 184 | ; "Current drive is no longer valid" | ||
| 185 | ; | ||
| 186 | BadCurDrv dw 1027 ;AN000;message number | ||
| 187 | db no_subst ;AN000;number of subst | ||
| 188 | |||
| 189 | ; "Press any key to continue" | ||
| 190 | ; | ||
| 191 | PauseMes_Ptr dw 1028 ;AN000;message number | ||
| 192 | db no_subst ;AN000;number of subst | ||
| 193 | |||
| 194 | ; "Label not found",13,10 | ||
| 195 | ; | ||
| 196 | BadLab_Ptr dw 1029 ;AN000;message number | ||
| 197 | db no_subst ;AN000;number of subst | ||
| 198 | |||
| 199 | ; "Syntax error",13,10 | ||
| 200 | ; | ||
| 201 | SyntMes_Ptr dw 1030 ;AN000;message number | ||
| 202 | db no_subst ;AN000;number of subst | ||
| 203 | |||
| 204 | ; "Invalid date",13,10 | ||
| 205 | ; | ||
| 206 | BadDat_Ptr dw 1031 ;AN000;message number | ||
| 207 | db no_subst ;AN000;number of subst | ||
| 208 | |||
| 209 | ; "Current date is %1 %2",13,10 | ||
| 210 | ; | ||
| 211 | CurDat_Ptr dw 1032 ;AN000;message number | ||
| 212 | db 2 ;AN000;number of subst | ||
| 213 | db parm_block_size ;AN000;size of sublist | ||
| 214 | db 0 ;AN000;reserved | ||
| 215 | dw OFFSET TranGroup:Arg_Buf ;AN000;offset of arg | ||
| 216 | dw 0 ;AN000;segment of arg | ||
| 217 | db 1 ;AN000;first subst | ||
| 218 | db Char_field_ASCIIZ ;AN000;character string | ||
| 219 | db 3 ;AN000;maximum width | ||
| 220 | db 3 ;AN000;minimum width | ||
| 221 | db blank ;AN000;pad character | ||
| 222 | db parm_block_size ;AN000;size of sublist | ||
| 223 | db 0 ;AN000;reserved | ||
| 224 | CurDat_yr dw 0 ;AN000;year | ||
| 225 | CurDat_mo_day dw 0 ;AN000;month,day | ||
| 226 | db 2 ;AN000;second subst | ||
| 227 | db DATE_MDY_4 ;AN000;date | ||
| 228 | db 10 ;AN000;maximum width | ||
| 229 | db 10 ;AN000;minimum width | ||
| 230 | db blank ;AN000;pad character | ||
| 231 | |||
| 232 | |||
| 233 | ; "SunMonTueWedThuFriSat" | ||
| 234 | ; | ||
| 235 | WeekTab dw 1033 ;AN000;message number | ||
| 236 | db no_subst ;AN000;number of subst | ||
| 237 | |||
| 238 | ; "Enter new date (%1):" | ||
| 239 | ; | ||
| 240 | NewDat_Ptr dw 1034 ;AN000;message number | ||
| 241 | db 1 ;AN000;number of subst | ||
| 242 | db parm_block_size ;AN000;size of sublist | ||
| 243 | db 0 ;AN000;reserved | ||
| 244 | NewDat_Format dw 0 ;AN000;offset of replacement | ||
| 245 | dw 0 ;AN000;segment of arg | ||
| 246 | db 1 ;AN000;first subst | ||
| 247 | db Char_field_ASCIIZ ;AN000;character string | ||
| 248 | db 8 ;AN000;maximum width | ||
| 249 | db 8 ;AN000;minimum width | ||
| 250 | db blank ;AN000;pad character | ||
| 251 | |||
| 252 | ; "Invalid time",13,10 | ||
| 253 | ; | ||
| 254 | BadTim_Ptr dw 1035 ;AN000;message number | ||
| 255 | db no_subst ;AN000;number of subst | ||
| 256 | |||
| 257 | ; "Current time is %1",13,10 | ||
| 258 | ; | ||
| 259 | CurTim_Ptr dw 1036 ;AN000;message number | ||
| 260 | db 1 ;AN000;number of subst | ||
| 261 | db parm_block_size ;AN000;size of sublist | ||
| 262 | db 0 ;AN000;reserved | ||
| 263 | CurTim_hr_min dw 0 ;AN000;hours,minutes | ||
| 264 | CurTim_Sec_hn dw 0 ;AN000;seconds,hundredths | ||
| 265 | db 1 ;AN000;first subst | ||
| 266 | db Right_Align+TIME_HHMMSSHH_Cty ;AC059;time | ||
| 267 | db 12 ;AC059;maximum width | ||
| 268 | db 12 ;AC059;minimum width | ||
| 269 | db blank ;AN000;pad character | ||
| 270 | |||
| 271 | ; "Enter new time:" | ||
| 272 | ; | ||
| 273 | NewTim_Ptr dw 1037 ;AN000;message number | ||
| 274 | db no_subst ;AN000;number of subst | ||
| 275 | |||
| 276 | ; ", Delete (Y/N)?",13,10 | ||
| 277 | ; | ||
| 278 | Del_Y_N_Ptr dw 1038 ;AN000;message number | ||
| 279 | db no_subst ;AN000;number of subst | ||
| 280 | |||
| 281 | ; "All files in directory will be deleted!",13,10 | ||
| 282 | ; "Are you sure (Y/N)?",13,10 | ||
| 283 | ; | ||
| 284 | SureMes_Ptr dw 1039 ;AN000;message number | ||
| 285 | db no_subst ;AN000;number of subst | ||
| 286 | |||
| 287 | ; "Microsoft DOS Version %1.%2",13,10 | ||
| 288 | ; | ||
| 289 | VerMes_Ptr dw 1040 ;AN000;message number | ||
| 290 | db 2 ;AN000;number of subst | ||
| 291 | db parm_block_size ;AN000;size of sublist | ||
| 292 | db 0 ;AN000;reserved | ||
| 293 | dw OFFSET TranGroup:Major_Ver_Num ;AN000;offset of arg | ||
| 294 | dw 0 ;AN000;segment of arg | ||
| 295 | db 1 ;AN000;first subst | ||
| 296 | db Right_Align+Unsgn_Bin_Word ;AN000;binary to decimal | ||
| 297 | db 1 ;AN000;maximum width | ||
| 298 | db 1 ;AN000;minimum width | ||
| 299 | db blank ;AN000;pad character | ||
| 300 | db parm_block_size ;AN000;size of sublist | ||
| 301 | db 0 ;AN000;reserved | ||
| 302 | dw OFFSET TranGroup:Minor_Ver_Num ;AN000;offset of arg | ||
| 303 | dw 0 ;AN000;segment of arg | ||
| 304 | db 2 ;AN000;second subst | ||
| 305 | db Unsgn_Bin_Word ;AN000;binary to decimal | ||
| 306 | db 2 ;AN000;maximum width | ||
| 307 | db 2 ;AN000;minimum width | ||
| 308 | db "0" ;AN000;pad character | ||
| 309 | |||
| 310 | ; "Volume in drive %1 has no label",13,10 | ||
| 311 | ; | ||
| 312 | VolMes_Ptr_2 dw 1041 ;AN000;message number | ||
| 313 | db 1 ;AN000;number of subst | ||
| 314 | db parm_block_size ;AN000;size of sublist | ||
| 315 | db 0 ;AN000;reserved | ||
| 316 | dw OFFSET TranGroup:vol_drv ;AN000;offset of drive | ||
| 317 | dw 0 ;AN000;segment of arg | ||
| 318 | db 1 ;AN000;first subst | ||
| 319 | db Char_field_Char ;AN000;character | ||
| 320 | db 128 ;AN000;maximum width | ||
| 321 | db 1 ;AN000;minimum width | ||
| 322 | db blank ;AN000;pad character | ||
| 323 | |||
| 324 | ; "Volume in drive %1 is %2",13,10 | ||
| 325 | ; | ||
| 326 | VolMes_Ptr dw 1042 ;AN000;message number | ||
| 327 | db 2 ;AN000;number of subst | ||
| 328 | db parm_block_size ;AN000;size of sublist | ||
| 329 | db 0 ;AN000;reserved | ||
| 330 | dw OFFSET TranGroup:vol_drv ;AN000;offset of drive | ||
| 331 | dw 0 ;AN000;segment of arg | ||
| 332 | db 1 ;AN000;first subst | ||
| 333 | db 00000000b ;AN000;character | ||
| 334 | db 128 ;AN000;maximum width | ||
| 335 | db 1 ;AN000;minimum width | ||
| 336 | db blank ;AN000;pad character | ||
| 337 | db parm_block_size ;AN000;size of sublist | ||
| 338 | db 0 ;AN000;reserved | ||
| 339 | dw OFFSET TranGroup:CHARBUF ;AN000;offset of string | ||
| 340 | dw 0 ;AN000;segment of arg | ||
| 341 | db 2 ;AN000;second subst | ||
| 342 | db Char_field_ASCIIZ ;AN000;character string | ||
| 343 | db 128 ;AN000;maximum width | ||
| 344 | db 1 ;AN000;minimum width | ||
| 345 | db blank ;AN000;pad character | ||
| 346 | |||
| 347 | ; "Volume Serial Number is %1-%2",13,10 | ||
| 348 | ; | ||
| 349 | VolSerMes_Ptr dw 1043 ;AN000;message number | ||
| 350 | db 2 ;AN000;number of subst | ||
| 351 | db parm_block_size ;AN000;size of sublist | ||
| 352 | db 0 ;AN000;reserved | ||
| 353 | dw OFFSET TranGroup:vol_serial+2 ;AN000;offset of serial | ||
| 354 | dw 0 ;AN000;segment of arg | ||
| 355 | db 1 ;AN000;first subst | ||
| 356 | db Right_Align+Bin_Hex_Word ;AN000;binary to hex | ||
| 357 | db 4 ;AN000;maximum width | ||
| 358 | db 4 ;AN000;minimum width | ||
| 359 | db "0" ;AN000;pad character | ||
| 360 | db parm_block_size ;AN000;size of sublist | ||
| 361 | db 0 ;AN000;reserved | ||
| 362 | dw OFFSET TranGroup:vol_serial ;AN000;offset of serial | ||
| 363 | dw 0 ;AN000;segment of arg | ||
| 364 | db 2 ;AN000;second subst | ||
| 365 | db Right_Align+Bin_Hex_Word ;AN000;binary to hex | ||
| 366 | db 4 ;AN000;maximum width | ||
| 367 | db 4 ;AN000;minimum width | ||
| 368 | db "0" ;AN000;pad character | ||
| 369 | |||
| 370 | ; "Invalid directory",13,10 | ||
| 371 | ; | ||
| 372 | BadCD_Ptr dw 1044 ;AN000;message number | ||
| 373 | db no_subst ;AN000;number of subst | ||
| 374 | |||
| 375 | ; "Unable to create directory",13,10 | ||
| 376 | ; | ||
| 377 | BadMkD_Ptr dw 1045 ;AN000;message number | ||
| 378 | db no_subst ;AN000;number of subst | ||
| 379 | |||
| 380 | ; "Invalid path, not directory,",13,10 | ||
| 381 | ; "or directory not empty",13,10 | ||
| 382 | ; | ||
| 383 | BadRmD_Ptr dw 1046 ;AN000;message number | ||
| 384 | db no_subst ;AN000;number of subst | ||
| 385 | |||
| 386 | ; "Must specify ON or OFF",13,10 | ||
| 387 | ; | ||
| 388 | Bad_ON_OFF_Ptr dw 1047 ;AN000;message number | ||
| 389 | db no_subst ;AN000;number of subst | ||
| 390 | |||
| 391 | ; "Directory of %1",13,10 | ||
| 392 | ; | ||
| 393 | DirHead_Ptr dw 1048 ;AN000;message number | ||
| 394 | db 1 ;AN000;number of subst | ||
| 395 | db parm_block_size ;AN000;size of sublist | ||
| 396 | db 0 ;AN000;reserved | ||
| 397 | dw OFFSET TranGroup:BWDBUF ;AN000;offset of arg | ||
| 398 | dw 0 ;AN000;segment of arg | ||
| 399 | db 1 ;AN000;first subst | ||
| 400 | db Char_field_ASCIIZ ;AN000;character string | ||
| 401 | db 128 ;AN000;maximum width | ||
| 402 | db 0 ;AN000;minimum width | ||
| 403 | db blank ;AN000;pad character | ||
| 404 | |||
| 405 | ; "No Path",13,10 | ||
| 406 | ; | ||
| 407 | NulPath_Ptr dw 1049 ;AN000;message number | ||
| 408 | db no_subst ;AN000;number of subst | ||
| 409 | |||
| 410 | ; "Invalid drive in search path",13,10 | ||
| 411 | ; | ||
| 412 | BadPMes_Ptr dw 1050 ;AN000;message number | ||
| 413 | db no_subst ;AN000;number of subst | ||
| 414 | |||
| 415 | ; "Invalid device",13,10 | ||
| 416 | ; | ||
| 417 | BadDev_Ptr dw 1051 ;AN000;message number | ||
| 418 | db no_subst ;AN000;number of subst | ||
| 419 | |||
| 420 | ; "FOR cannot be nested",13,10 | ||
| 421 | ; | ||
| 422 | ForNestMes_Ptr dw 1052 ;AN000;message number | ||
| 423 | db no_subst ;AN000;number of subst | ||
| 424 | |||
| 425 | ; "Intermediate file error during pipe",13,10 | ||
| 426 | ; | ||
| 427 | PipeEMes_Ptr dw 1053 ;AN000;message number | ||
| 428 | db no_subst ;AN000;number of subst | ||
| 429 | |||
| 430 | ; "Cannot do binary reads from a device",13,10 | ||
| 431 | ; | ||
| 432 | InBDev_Ptr dw 1054 ;AN000;message number | ||
| 433 | db no_subst ;AN000;number of subst | ||
| 434 | |||
| 435 | ; "BREAK is %1",13,10 | ||
| 436 | ; | ||
| 437 | CtrlcMes_Ptr dw 1055 ;AN000;message number | ||
| 438 | db 1 ;AN000;number of subst | ||
| 439 | db parm_block_size ;AN000;size of sublist | ||
| 440 | db 0 ;AN000;reserved | ||
| 441 | dw 0 ;AN000;offset of on/off (new) | ||
| 442 | dw 0 ;AN000;segment of arg | ||
| 443 | db 1 ;AN000;first subst | ||
| 444 | db Char_field_ASCIIZ ;AN000;character string | ||
| 445 | db 128 ;AN000;maximum width | ||
| 446 | db 1 ;AN000;minimum width | ||
| 447 | db blank ;AN000;pad character | ||
| 448 | |||
| 449 | ; "VERIFY is %1",13,10 | ||
| 450 | ; | ||
| 451 | VeriMes_Ptr dw 1056 ;AN000;message number | ||
| 452 | db 1 ;AN000;number of subst | ||
| 453 | db parm_block_size ;AN000;size of sublist | ||
| 454 | db 0 ;AN000;reserved | ||
| 455 | dw 0 ;AN000;offset of on/off (new) | ||
| 456 | dw 0 ;AN000;segment of arg | ||
| 457 | db 1 ;AN000;first subst | ||
| 458 | db Char_field_ASCIIZ ;AN000;character string | ||
| 459 | db 128 ;AN000;maximum width | ||
| 460 | db 1 ;AN000;minimum width | ||
| 461 | db blank ;AN000;pad character | ||
| 462 | |||
| 463 | ; "ECHO is %1",13,10 | ||
| 464 | ; | ||
| 465 | EchoMes_Ptr dw 1057 ;AN000;message number | ||
| 466 | db 1 ;AN000;number of subst | ||
| 467 | db parm_block_size ;AN000;size of sublist | ||
| 468 | db 0 ;AN000;reserved | ||
| 469 | dw 0 ;AN000;offset of on/off (new) | ||
| 470 | dw 0 ;AN000;segment of arg | ||
| 471 | db 1 ;AN000;first subst | ||
| 472 | db Char_field_ASCIIZ ;AN000;character string | ||
| 473 | db 128 ;AN000;maximum width | ||
| 474 | db 1 ;AN000;minimum width | ||
| 475 | db blank ;AN000;pad character | ||
| 476 | |||
| 477 | ; "off" | ||
| 478 | ; | ||
| 479 | OffMes_Ptr dw 1059 ;AN000;message number | ||
| 480 | db no_subst ;AN000;number of subst | ||
| 481 | |||
| 482 | ; "on" | ||
| 483 | ; | ||
| 484 | OnMes_Ptr dw 1060 ;AN000;message number | ||
| 485 | db no_subst ;AN000;number of subst | ||
| 486 | |||
| 487 | ; "Error writing to device",13,10 | ||
| 488 | ; | ||
| 489 | DevWMes_Ptr dw 1061 ;AN000;message number | ||
| 490 | db no_subst ;AN000;number of subst | ||
| 491 | |||
| 492 | ; "Invalid path",13,10 | ||
| 493 | ; | ||
| 494 | Inval_Path_Ptr dw 1062 ;AN000;message number | ||
| 495 | db no_subst ;AN000;number of subst | ||
| 496 | |||
| 497 | ; unformatted string output | ||
| 498 | ; | ||
| 499 | arg_Buf_Ptr dw 1063 ;AN000;message number | ||
| 500 | db 1 ;AN000;number of subst | ||
| 501 | db parm_block_size ;AN000;size of sublist | ||
| 502 | db 0 ;AN000;reserved | ||
| 503 | dw OFFSET TranGroup:Arg_Buf ;AN000;offset of arg | ||
| 504 | dw 0 ;AN000;segment of arg | ||
| 505 | db 1 ;AN000;first subst | ||
| 506 | db Char_field_ASCIIZ ;AN000;character string | ||
| 507 | db 128 ;AN000;maximum width | ||
| 508 | db 0 ;AN000;minimum width | ||
| 509 | db blank ;AN000;pad character | ||
| 510 | |||
| 511 | ; file name output | ||
| 512 | ; | ||
| 513 | File_Name_Ptr dw 1064 ;AN000;message number | ||
| 514 | db 1 ;AN000;number of subst | ||
| 515 | db parm_block_size ;AN000;size of sublist | ||
| 516 | db 0 ;AN000;reserved | ||
| 517 | dw OFFSET TranGroup:SRCBUF ;AN000;offset of arg | ||
| 518 | dw 0 ;AN000;segment of arg | ||
| 519 | db 1 ;AN000;first subst | ||
| 520 | db Char_field_ASCIIZ ;AN000;character string | ||
| 521 | db 128 ;AN000;maximum width | ||
| 522 | db 0 ;AN000;minimum width | ||
| 523 | db blank ;AN000;pad character | ||
| 524 | |||
| 525 | ; file size output for dir | ||
| 526 | ; | ||
| 527 | Disp_File_Size_Ptr dw 1065 ;AN000;message number | ||
| 528 | db 1 ;AN000;number of subst | ||
| 529 | db parm_block_size ;AN000;size of sublist | ||
| 530 | db 0 ;AN000;reserved | ||
| 531 | dw OFFSET TranGroup:File_size_low ;AN000;offset of arg | ||
| 532 | dw 0 ;AN000;segment of arg | ||
| 533 | db 1 ;AN000;first subst | ||
| 534 | db Right_Align+Unsgn_Bin_DWord ;AN000;long binary to decimal | ||
| 535 | db 10 ;AN000;maximum width | ||
| 536 | db 10 ;AN000;minimum width | ||
| 537 | db blank ;AN000;pad character | ||
| 538 | |||
| 539 | ; unformatted string output | ||
| 540 | ; %s | ||
| 541 | String_Buf_Ptr dw 1066 ;AN000;message number | ||
| 542 | db 1 ;AN000;number of subst | ||
| 543 | db parm_block_size ;AN000;size of sublist | ||
| 544 | db 0 ;AN000;reserved | ||
| 545 | dw OFFSET TranGroup:String_ptr_2 ;AN000;offset of arg | ||
| 546 | dw 0 ;AN000;segment of arg | ||
| 547 | db 1 ;AN000;first subst | ||
| 548 | db Char_field_ASCIIZ ;AN000;character string | ||
| 549 | db 128 ;AN000;maximum width | ||
| 550 | db 0 ;AN000;minimum width | ||
| 551 | db blank ;AN000;pad character | ||
| 552 | db 0 ;AN000; | ||
| 553 | |||
| 554 | ; tab character | ||
| 555 | ; | ||
| 556 | Tab_ptr dw 1067 ;AN000;message number | ||
| 557 | db no_subst ;AN000;number of subst | ||
| 558 | |||
| 559 | ; " <DIR> " | ||
| 560 | ; | ||
| 561 | DMes_Ptr dw 1068 ;AN000;message number | ||
| 562 | db no_subst ;AN000;number of subst | ||
| 563 | |||
| 564 | ; destructive back space | ||
| 565 | ; | ||
| 566 | Dback_Ptr dw 1069 ;AN000;message number | ||
| 567 | db no_subst ;AN000;number of subst | ||
| 568 | |||
| 569 | ; carriage return / line feed | ||
| 570 | ; | ||
| 571 | ACRLF_Ptr dw 1070 ;AN000;message number | ||
| 572 | db no_subst ;AN000;number of subst | ||
| 573 | |||
| 574 | ; output a single character | ||
| 575 | ; | ||
| 576 | ;One_Char_Buf_Ptr dw 1071 ;AN000;message number | ||
| 577 | ; db 1 ;AN000;number of subst | ||
| 578 | ; db parm_block_size ;AN000;size of sublist | ||
| 579 | ; db 0 ;AN000;reserved | ||
| 580 | ; dw OFFSET TranGroup:One_Char_Val ;AN000;offset of charcacter | ||
| 581 | ; dw 0 ;AN000;segment of arg | ||
| 582 | ; db 1 ;AN000;first subst | ||
| 583 | ; db Char_field_Char ;AN000;character | ||
| 584 | ; db 1 ;AN000;maximum width | ||
| 585 | ; db 1 ;AN000;minimum width | ||
| 586 | ; db blank ;AN000;pad character | ||
| 587 | |||
| 588 | ; "mm-dd-yy" | ||
| 589 | ; | ||
| 590 | USADat_Ptr dw 1072 ;AN000;message number | ||
| 591 | db no_subst ;AN000;number of subst | ||
| 592 | |||
| 593 | ; "dd-mm-yy" | ||
| 594 | ; | ||
| 595 | EurDat_Ptr dw 1073 ;AN000;message number | ||
| 596 | db no_subst ;AN000;number of subst | ||
| 597 | |||
| 598 | ; "yy-mm-dd" | ||
| 599 | ; | ||
| 600 | JapDat_Ptr dw 1074 ;AN000;message number | ||
| 601 | db no_subst ;AN000;number of subst | ||
| 602 | |||
| 603 | ; date string for prompt | ||
| 604 | ; | ||
| 605 | promptDat_Ptr dw 1075 ;AN000;message number | ||
| 606 | db 2 ;AN000;number of subst | ||
| 607 | db parm_block_size ;AN000;size of sublist | ||
| 608 | db 0 ;AN000;reserved | ||
| 609 | dw OFFSET TranGroup:Arg_Buf ;AN000;offset of arg | ||
| 610 | dw 0 ;AN000;segment of arg | ||
| 611 | db 1 ;AN000;first subst | ||
| 612 | db Char_field_ASCIIZ ;AN000;character string | ||
| 613 | db 3 ;AN000;maximum width | ||
| 614 | db 3 ;AN000;minimum width | ||
| 615 | db blank ;AN000;pad character | ||
| 616 | db parm_block_size ;AN000;size of sublist | ||
| 617 | db 0 ;AN000;reserved | ||
| 618 | promptDat_yr dw 0 ;AN000;year | ||
| 619 | promptDat_moday dw 0 ;AN000;month,day | ||
| 620 | db 2 ;AN000;second subst | ||
| 621 | db DATE_MDY_4 ;AN000;date | ||
| 622 | db 10 ;AN000;maximum width | ||
| 623 | db 8 ;AN000;minimum width | ||
| 624 | db blank ;AN000;pad character | ||
| 625 | |||
| 626 | |||
| 627 | ; Time for prompt | ||
| 628 | ; | ||
| 629 | promTim_Ptr dw 1076 ;AN000;message number | ||
| 630 | db 1 ;AN000;number of subst | ||
| 631 | db parm_block_size ;AN000;size of sublist | ||
| 632 | db 0 ;AN000;reserved | ||
| 633 | PromTim_hr_min dw 0 ;AN000;hours,minutes | ||
| 634 | PromTim_Sec_hn dw 0 ;AN000;seconds,hundredths | ||
| 635 | db 1 ;AN000;first subst | ||
| 636 | db Right_Align+TIME_HHMMSSHH_24 ;AC013;time | ||
| 637 | db 11 ;AN000;maximum width | ||
| 638 | db 11 ;AC013;minimum width | ||
| 639 | db blank ;AN000;pad character | ||
| 640 | |||
| 641 | ; Date and time for DIR | ||
| 642 | ; | ||
| 643 | DirDatTim_Ptr dw 1077 ;AN000;message number | ||
| 644 | db 2 ;AN000;number of subst | ||
| 645 | db parm_block_size ;AN000;size of sublist | ||
| 646 | db 0 ;AN000;reserved | ||
| 647 | DirDat_yr dw 0 ;AN000;year | ||
| 648 | DirDat_mo_day dw 0 ;AN000;month,day | ||
| 649 | db 1 ;AN000;first subst | ||
| 650 | db Right_Align+DATE_MDY_2 ;AN000;date | ||
| 651 | db 10 ;AN000;maximum width | ||
| 652 | db 8 ;AN000;minimum width | ||
| 653 | db blank ;AN000;pad character | ||
| 654 | db parm_block_size ;AN000;size of sublist | ||
| 655 | db 0 ;AN000;reserved | ||
| 656 | DirTim_hr_min dw 0 ;AN000;hours,minutes | ||
| 657 | DirTim_Sec_hn dw 0 ;AN000;seconds,hundredths | ||
| 658 | db 2 ;AN000;second subst | ||
| 659 | db Right_align+TIME_HHMM_Cty ;AN000;time | ||
| 660 | db 6 ;AN000;maximum width | ||
| 661 | db 6 ;AN000;minimum width | ||
| 662 | db blank ;AN000;pad character | ||
| 663 | |||
| 664 | ; "Directory already exists" | ||
| 665 | ; | ||
| 666 | MD_exists_ptr dw 1078 ;AN000;message number | ||
| 667 | db no_subst ;AN000;number of subst | ||
| 668 | |||
| 669 | PATH_TEXT DB "PATH=" | ||
| 670 | PROMPT_TEXT DB "PROMPT=" | ||
| 671 | comspecstr db "COMSPEC=" | ||
diff --git a/v4.0/src/CMD/COMMAND/TSPC.ASM b/v4.0/src/CMD/COMMAND/TSPC.ASM new file mode 100644 index 0000000..10e5758 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/TSPC.ASM | |||
| @@ -0,0 +1,488 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)tspc.asm 4.1 85/09/22 | ||
| 3 | ; SCCSID = @(#)tspc.asm 4.1 85/09/22 | ||
| 4 | TITLE COMMAND Transient Uninitialized DATA | ||
| 5 | |||
| 6 | INCLUDE comsw.asm | ||
| 7 | .xlist | ||
| 8 | .xcref | ||
| 9 | INCLUDE DOSSYM.INC | ||
| 10 | INCLUDE comequ.asm | ||
| 11 | INCLUDE comseg.asm | ||
| 12 | INCLUDE EA.inc ;AN030; | ||
| 13 | .list | ||
| 14 | .cref | ||
| 15 | |||
| 16 | ; Uninitialized transient data | ||
| 17 | TRANSPACE SEGMENT PUBLIC BYTE | ||
| 18 | |||
| 19 | PUBLIC ALLSWITCH | ||
| 20 | PUBLIC append_exec ;AN041; | ||
| 21 | PUBLIC arg | ||
| 22 | PUBLIC argbufptr | ||
| 23 | PUBLIC ARGC | ||
| 24 | PUBLIC ARG1S | ||
| 25 | PUBLIC ARG2S | ||
| 26 | PUBLIC ARGTS | ||
| 27 | PUBLIC arg_buf | ||
| 28 | PUBLIC ASCII | ||
| 29 | PUBLIC BatBuf | ||
| 30 | PUBLIC BatBufEnd | ||
| 31 | PUBLIC BatBufPos | ||
| 32 | PUBLIC BATHAND | ||
| 33 | PUBLIC BINARY | ||
| 34 | PUBLIC BITS | ||
| 35 | PUBLIC BWDBUF | ||
| 36 | PUBLIC BYTCNT | ||
| 37 | PUBLIC bytes_free | ||
| 38 | PUBLIC CFLAG | ||
| 39 | PUBLIC CHARBUF | ||
| 40 | PUBLIC CHKDRV | ||
| 41 | PUBLIC COM | ||
| 42 | PUBLIC COMBUF | ||
| 43 | PUBLIC comma | ||
| 44 | PUBLIC comptr | ||
| 45 | PUBLIC comspec_flag | ||
| 46 | PUBLIC COMSW | ||
| 47 | PUBLIC CONCAT | ||
| 48 | PUBLIC concat_xa ;AN000; | ||
| 49 | PUBLIC copy_Num | ||
| 50 | PUBLIC CPDATE | ||
| 51 | PUBLIC CPTIME | ||
| 52 | PUBLIC cpyflag | ||
| 53 | PUBLIC CURDRV | ||
| 54 | PUBLIC DATE_DAY ;AN000; | ||
| 55 | PUBLIC DATE_MONTH ;AN000; | ||
| 56 | PUBLIC DATE_OUTPUT ;AN000; | ||
| 57 | PUBLIC DATE_TYPE ;AN000; | ||
| 58 | PUBLIC DATE_YEAR ;AN000; | ||
| 59 | PUBLIC DEST | ||
| 60 | PUBLIC DESTBUF | ||
| 61 | PUBLIC DestClosed | ||
| 62 | PUBLIC DESTDIR | ||
| 63 | PUBLIC DESTFCB | ||
| 64 | PUBLIC DESTFCB2 | ||
| 65 | PUBLIC DESTHAND | ||
| 66 | PUBLIC DESTINFO | ||
| 67 | PUBLIC DESTISDEV | ||
| 68 | PUBLIC DESTISDIR | ||
| 69 | PUBLIC DESTNAME | ||
| 70 | PUBLIC DESTSIZ | ||
| 71 | PUBLIC DESTSWITCH | ||
| 72 | PUBLIC DESTTAIL | ||
| 73 | PUBLIC DESTVARS | ||
| 74 | PUBLIC DIRBUF | ||
| 75 | PUBLIC DIRCHAR | ||
| 76 | PUBLIC dirflag ;AN015; | ||
| 77 | PUBLIC Dir_Num | ||
| 78 | PUBLIC display_ioctl ;AN000; | ||
| 79 | PUBLIC display_mode ;AN000; | ||
| 80 | PUBLIC display_width ;AN000; | ||
| 81 | PUBLIC DRIVE_NUMBER ;AN000; | ||
| 82 | PUBLIC DRIVE_OUTPUT ;AN000; | ||
| 83 | PUBLIC DRIVE_TYPE ;AN000; | ||
| 84 | PUBLIC DRIVE_VALUE ;AN000; | ||
| 85 | PUBLIC ELCNT | ||
| 86 | PUBLIC ELPOS | ||
| 87 | PUBLIC EXECPATH | ||
| 88 | PUBLIC EXEC_ADDR | ||
| 89 | PUBLIC EXEFCB | ||
| 90 | PUBLIC expand_star | ||
| 91 | PUBLIC ext_entered ;AN005; | ||
| 92 | PUBLIC ext_open_off ;AN000; | ||
| 93 | PUBLIC ext_open_parms ;AN000; | ||
| 94 | PUBLIC ext_open_seg ;AN000; | ||
| 95 | PUBLIC FBUF | ||
| 96 | PUBLIC FILECNT | ||
| 97 | PUBLIC file_size_high | ||
| 98 | PUBLIC file_size_low | ||
| 99 | PUBLIC FILTYP | ||
| 100 | PUBLIC FIRSTDEST | ||
| 101 | PUBLIC FRSTSRCH | ||
| 102 | PUBLIC FULLSCR | ||
| 103 | PUBLIC GOTOLEN | ||
| 104 | PUBLIC HEADCALL | ||
| 105 | PUBLIC ID | ||
| 106 | PUBLIC IDLEN | ||
| 107 | PUBLIC IFNOTFLAG | ||
| 108 | PUBLIC if_not_count | ||
| 109 | PUBLIC INEXACT | ||
| 110 | PUBLIC INTERNATVARS | ||
| 111 | PUBLIC KPARSE | ||
| 112 | PUBLIC last_arg | ||
| 113 | PUBLIC LINCNT | ||
| 114 | PUBLIC LINLEN | ||
| 115 | PUBLIC linperpag ;AN000; | ||
| 116 | PUBLIC major_ver_num | ||
| 117 | PUBLIC MELCOPY | ||
| 118 | PUBLIC MELSTART | ||
| 119 | PUBLIC minor_ver_num | ||
| 120 | PUBLIC msg_flag ;AN022; | ||
| 121 | PUBLIC msg_numb ;AN022; | ||
| 122 | PUBLIC NOWRITE | ||
| 123 | PUBLIC NXTADD | ||
| 124 | PUBLIC objcnt | ||
| 125 | PUBLIC one_char_val | ||
| 126 | PUBLIC PARM1 | ||
| 127 | PUBLIC PARM2 | ||
| 128 | PUBLIC parse_last ;AN018; | ||
| 129 | PUBLIC PARSE1_ADDR ;AN000; | ||
| 130 | PUBLIC PARSE1_CODE ;AN000; | ||
| 131 | PUBLIC PARSE1_OUTPUT ;AN000; | ||
| 132 | PUBLIC PARSE1_SYN ;AN000; | ||
| 133 | PUBLIC PARSE1_TYPE ;AN000; | ||
| 134 | PUBLIC PATHCNT | ||
| 135 | PUBLIC pathinfo | ||
| 136 | PUBLIC PATHPOS | ||
| 137 | PUBLIC PATHSW | ||
| 138 | PUBLIC PLUS | ||
| 139 | PUBLIC plus_comma | ||
| 140 | PUBLIC print_err_flag ;AN000; | ||
| 141 | PUBLIC psep_char | ||
| 142 | PUBLIC RCH_ADDR | ||
| 143 | PUBLIC RDEOF | ||
| 144 | PUBLIC RE_INSTR | ||
| 145 | PUBLIC RESSEG | ||
| 146 | PUBLIC SCANBUF | ||
| 147 | PUBLIC SDIRBUF | ||
| 148 | PUBLIC search_best | ||
| 149 | PUBLIC search_best_buf | ||
| 150 | PUBLIC search_curdir_buf | ||
| 151 | PUBLIC search_error | ||
| 152 | PUBLIC SKPDEL | ||
| 153 | PUBLIC SOURCE | ||
| 154 | PUBLIC SPECDRV | ||
| 155 | PUBLIC SRCBUF | ||
| 156 | PUBLIC SRCHAND | ||
| 157 | PUBLIC SRCINFO | ||
| 158 | PUBLIC SRCISDEV | ||
| 159 | PUBLIC SRCISDIR | ||
| 160 | PUBLIC SRCPT | ||
| 161 | PUBLIC SRCSIZ | ||
| 162 | PUBLIC SRCTAIL | ||
| 163 | PUBLIC SRCVARS | ||
| 164 | PUBLIC srcxname | ||
| 165 | PUBLIC src_xa_seg ;AN000; | ||
| 166 | PUBLIC src_xa_size ;AN000; | ||
| 167 | PUBLIC STACK | ||
| 168 | PUBLIC STARTEL | ||
| 169 | PUBLIC string_ptr_2 | ||
| 170 | ;AD061; PUBLIC string_ptr_2_sb ;AN000; | ||
| 171 | PUBLIC subst_buffer ;AN061; | ||
| 172 | PUBLIC SWITCHAR | ||
| 173 | PUBLIC system_cpage | ||
| 174 | PUBLIC TERMREAD | ||
| 175 | PUBLIC TIME_FRACTION ;AN000; | ||
| 176 | PUBLIC TIME_HOUR ;AN000; | ||
| 177 | PUBLIC TIME_MINUTES ;AN000; | ||
| 178 | PUBLIC TIME_OUTPUT ;AN000; | ||
| 179 | PUBLIC TIME_SECONDS ;AN000; | ||
| 180 | PUBLIC TIME_TYPE ;AN000; | ||
| 181 | PUBLIC TPA | ||
| 182 | PUBLIC tpbuf | ||
| 183 | PUBLIC TRANSPACEEND | ||
| 184 | PUBLIC TRAN_TPA | ||
| 185 | PUBLIC trgxname | ||
| 186 | PUBLIC UCOMBUF | ||
| 187 | PUBLIC USERDIR1 | ||
| 188 | PUBLIC vol_drv | ||
| 189 | PUBLIC vol_ioctl_buf ;AC030; | ||
| 190 | PUBLIC vol_serial ;AC030; | ||
| 191 | PUBLIC vol_label ;AC030; | ||
| 192 | PUBLIC WRITTEN | ||
| 193 | PUBLIC xa_cp_length ;AN030; | ||
| 194 | PUBLIC xa_cp_out ;AN030; | ||
| 195 | PUBLIC xa_list_attr ;AN030; | ||
| 196 | PUBLIC zflag | ||
| 197 | |||
| 198 | IF IBM | ||
| 199 | PUBLIC ROM_CALL | ||
| 200 | PUBLIC ROM_CS | ||
| 201 | PUBLIC ROM_IP | ||
| 202 | ENDIF | ||
| 203 | |||
| 204 | |||
| 205 | ORG 0 | ||
| 206 | ZERO = $ | ||
| 207 | SRCXNAME DB DIRSTRLEN + 20 DUP (?) ;g buffer for name translate | ||
| 208 | TRGXNAME DB DIRSTRLEN + 20 DUP (?) ;g buffer for name translate | ||
| 209 | UCOMBUF DB COMBUFLEN+3 DUP(?) ; Raw console buffer | ||
| 210 | COMBUF DB COMBUFLEN+3 DUP(?) ; Cooked console buffer | ||
| 211 | USERDIR1 DB DIRSTRLEN+3 DUP(?) ; Storage for users current directory | ||
| 212 | EXECPATH DB COMBUFLEN+3 DUP(?) ; Path for external command | ||
| 213 | RE_INSTR DB DIRSTRLEN+3+13 DUP (?) ; path for input to redirection | ||
| 214 | |||
| 215 | ; Variables passed up from resident | ||
| 216 | HEADCALL LABEL DWORD | ||
| 217 | DW ? | ||
| 218 | RESSEG DW ? | ||
| 219 | TPA DW ? | ||
| 220 | SWITCHAR DB ? | ||
| 221 | DIRCHAR DB ? | ||
| 222 | EXEC_ADDR DD ? | ||
| 223 | RCH_ADDR DD ? | ||
| 224 | fTest DW ? | ||
| 225 | TRAN_TPA DW ? | ||
| 226 | |||
| 227 | CHKDRV DB ? | ||
| 228 | RDEOF LABEL BYTE ; Misc flags | ||
| 229 | IFNOTFLAG LABEL BYTE | ||
| 230 | FILTYP DB ? | ||
| 231 | CURDRV DB ? | ||
| 232 | concat_xa db 0 ;AN000; flag for XA on file concatenations | ||
| 233 | CONCAT LABEL BYTE | ||
| 234 | PARM1 DB ? | ||
| 235 | ARGC LABEL BYTE | ||
| 236 | PARM2 DB ? | ||
| 237 | COMSW DW ? ; Switches between command and 1st arg | ||
| 238 | ARG1S DW ? ; Switches between 1st and 2nd arg | ||
| 239 | DESTSWITCH LABEL WORD | ||
| 240 | ARG2S DW ? ; Switches after 2nd arg | ||
| 241 | ALLSWITCH LABEL WORD | ||
| 242 | ARGTS DW ? ; ALL switches except for COMSW | ||
| 243 | CFLAG DB ? | ||
| 244 | DESTCLOSED LABEL BYTE | ||
| 245 | SPECDRV DB ? | ||
| 246 | BYTCNT DW ? ; Size of buffer between RES and TRANS | ||
| 247 | NXTADD DW ? | ||
| 248 | FRSTSRCH DB ? | ||
| 249 | LINCNT DB ? | ||
| 250 | LINLEN DB ? | ||
| 251 | FILECNT DW ? | ||
| 252 | CHARBUF DB 80 DUP (?) ;line byte character buffer for xenix write | ||
| 253 | DESTFCB2 LABEL BYTE | ||
| 254 | IDLEN DB ? | ||
| 255 | ID DB 8 DUP(?) | ||
| 256 | COM DB 3 DUP(?) | ||
| 257 | DEST DB 37 DUP(?) | ||
| 258 | DESTNAME DB 11 DUP(?) | ||
| 259 | DESTFCB LABEL BYTE | ||
| 260 | DESTDIR DB DIRSTRLEN DUP(?) ; Directory for PATH searches | ||
| 261 | GOTOLEN LABEL WORD | ||
| 262 | BWDBUF LABEL BYTE | ||
| 263 | EXEFCB LABEL WORD | ||
| 264 | DIRBUF DB DIRSTRLEN+3 DUP(?) | ||
| 265 | SDIRBUF DB 12 DUP(?) | ||
| 266 | BITS DW ? | ||
| 267 | PATHCNT DW ? | ||
| 268 | PATHPOS DW ? | ||
| 269 | PATHSW DW ? | ||
| 270 | FULLSCR DW ? | ||
| 271 | comma db 0 ;g flag set if +,, occurs | ||
| 272 | plus_comma db 0 ;g flag set if +,, occurs | ||
| 273 | dirflag db 0 ;AN015; set when pathcrunch called from DIR | ||
| 274 | parse_last dw 0 ;AN018; used to hold parsing position | ||
| 275 | |||
| 276 | system_cpage DW 0 ;AC001; used for CHCP variable | ||
| 277 | src_XA_size DW 0 ;AN000; size of extended attributes | ||
| 278 | src_XA_seg DW 0 ;AN000; segment of extended attributes | ||
| 279 | |||
| 280 | ext_open_parms label byte ;AN000; extended open parameter list | ||
| 281 | ;emg340 ext_open_off dw offset trangroup:srcbuf ;AN000; offset of file name | ||
| 282 | ext_open_off dw ? ;AN030; offset of extended attributes | ||
| 283 | ext_open_seg dw ? ;AN000; segment of extended attributes | ||
| 284 | dw 0 ;AN000; no additional parameters | ||
| 285 | |||
| 286 | XA_cp_out label byte ;AN030; list for one extended attribute | ||
| 287 | DW 1 ;AN030; count of entries | ||
| 288 | DB EAISBINARY ;AN030; ea_type | ||
| 289 | DW EASYSTEM ;AN030; ea_flags | ||
| 290 | DB ? ;AN030; ea_rc | ||
| 291 | DB 2 ;AN030; ea_namelen | ||
| 292 | DW 2 ;AN030; ea_valuelen | ||
| 293 | DB "CP" ;AN030; ea_name | ||
| 294 | xa_list_attr DW 0 ;AC030; code page | ||
| 295 | xa_cp_length DW $-XA_cp_out ;AN030; length of buffer | ||
| 296 | |||
| 297 | |||
| 298 | |||
| 299 | arg_buf db 128 dup (?) | ||
| 300 | file_size_low dw ? ;AC000; | ||
| 301 | file_size_high dw ? ;AC000; | ||
| 302 | string_ptr_2 dw ? | ||
| 303 | ;AD061;string_ptr_2_sb dw ? | ||
| 304 | copy_Num dw ? | ||
| 305 | cpyflag db ? | ||
| 306 | Dir_Num DW ? | ||
| 307 | bytes_free dw ? | ||
| 308 | dw ? | ||
| 309 | major_ver_num dw ? | ||
| 310 | minor_ver_num dw ? | ||
| 311 | one_char_val db ?,0 | ||
| 312 | vol_drv db ? | ||
| 313 | |||
| 314 | IF IBM | ||
| 315 | ROM_CALL DB ? ; flag for rom function | ||
| 316 | ROM_IP DW ? | ||
| 317 | ROM_CS DW ? | ||
| 318 | ENDIF | ||
| 319 | |||
| 320 | DESTVARS LABEL BYTE | ||
| 321 | DESTISDIR DB ? | ||
| 322 | DESTSIZ DB ? | ||
| 323 | DESTTAIL DW ? | ||
| 324 | DESTINFO DB ? | ||
| 325 | DESTBUF DB DIRSTRLEN + 20 DUP (?) | ||
| 326 | |||
| 327 | DESTHAND DW ? | ||
| 328 | DESTISDEV DB ? | ||
| 329 | FIRSTDEST DB ? | ||
| 330 | MELCOPY DB ? | ||
| 331 | MELSTART DW ? | ||
| 332 | |||
| 333 | SRCVARS LABEL BYTE | ||
| 334 | SRCISDIR DB ? | ||
| 335 | SRCSIZ DB ? | ||
| 336 | SRCTAIL DW ? | ||
| 337 | SRCINFO DB ? | ||
| 338 | SRCBUF DB DIRSTRLEN + 20 DUP (?) | ||
| 339 | |||
| 340 | SRCHAND DW ? | ||
| 341 | SRCISDEV DB ? | ||
| 342 | |||
| 343 | SCANBUF DB DIRSTRLEN + 20 DUP (?) | ||
| 344 | |||
| 345 | SRCPT DW ? | ||
| 346 | INEXACT DB ? | ||
| 347 | NOWRITE DB ? | ||
| 348 | BINARY DB ? | ||
| 349 | WRITTEN DW ? | ||
| 350 | TERMREAD DB ? | ||
| 351 | ASCII DB ? | ||
| 352 | PLUS DB ? | ||
| 353 | objcnt db ? ; Used in copy | ||
| 354 | CPDATE DW ? | ||
| 355 | CPTIME DW ? | ||
| 356 | BATHAND DW ? ; Batch handle | ||
| 357 | STARTEL DW ? | ||
| 358 | ELCNT DB ? | ||
| 359 | ELPOS DB ? | ||
| 360 | SKPDEL DB ? | ||
| 361 | SOURCE DB 11 DUP(?) | ||
| 362 | |||
| 363 | ext_entered db 0 ;AN005; | ||
| 364 | |||
| 365 | display_ioctl db 0 ;AN000; info level | ||
| 366 | db 0 ;AN000; reserved | ||
| 367 | dw crt_ioctl_ln ;AN000; length of data | ||
| 368 | dw ? ;AN000; control flags | ||
| 369 | display_mode db ? ;AN000; display mode, colors | ||
| 370 | db 0 ;AN000; reserved | ||
| 371 | dw ? ;AN023; colors | ||
| 372 | dw ? ;AN000; display width (PELS) | ||
| 373 | dw ? ;AN000; display length (PELS) | ||
| 374 | display_width dw ? ;AN000; display width | ||
| 375 | linperpag dw linesperpage ;AN000; display length (default to linesperpage) | ||
| 376 | |||
| 377 | vol_ioctl_buf label byte ;AN000; buffer for ioctl volume label/serial call | ||
| 378 | dw 0 ;AN000; info level | ||
| 379 | vol_serial dd 0 ;AN000; volume serial number | ||
| 380 | vol_label db 11 dup (" ") ;AN000; volume label - init to blanks | ||
| 381 | db 8 dup (" ") ;AN000; file system type | ||
| 382 | |||
| 383 | expand_star db ? | ||
| 384 | comspec_flag db ? | ||
| 385 | msg_flag db ? ;AN022; flag set if non-utility message issued | ||
| 386 | msg_numb dw 0 ;AN022; set with extended error message issued | ||
| 387 | append_exec db 0 ;AN041; set if internal append executed | ||
| 388 | print_err_flag dw 0 ;AN000; flag set if error during sysdispmsg | ||
| 389 | subst_buffer db parm_block_size*2 dup (0);AN061; | ||
| 390 | |||
| 391 | ;;;; IF KANJI 3/3/KK | ||
| 392 | KPARSE DB ? | ||
| 393 | ;;;; ENDIF 3/3/KK | ||
| 394 | |||
| 395 | ; Data declarations taken out of parse.asm | ||
| 396 | |||
| 397 | arg arg_unit <> ; pointers, arg count, string buffer | ||
| 398 | argbufptr DW ? ; index for argv[].argpointer | ||
| 399 | tpbuf DB 128 DUP (?) ; temporary buffer | ||
| 400 | LAST_ARG DW ? ; point at which to accumulate switch info | ||
| 401 | comptr dw ? ; ptr into combuf | ||
| 402 | |||
| 403 | ; Data declarations taken out of path.asm | ||
| 404 | fbuf find_buf <> ; dma buffer for findfirst/findnext | ||
| 405 | pathinfo DW 3 DUP (?) ; ES, SI(old), and SI(new) of user path | ||
| 406 | psep_char DB ? ; '/' or '\' | ||
| 407 | search_best DB (?) ; best code, best filename so far | ||
| 408 | fname_max_len equ 13 | ||
| 409 | search_best_buf DB fname_max_len DUP (?) | ||
| 410 | search_curdir_buf DB 64 DUP (?) ; a place for CurDir info, if successful | ||
| 411 | search_error DW (?) ; address of error message to be printed | ||
| 412 | |||
| 413 | ; Data declarations taken out of tbatch.asm | ||
| 414 | if_not_count DW ? | ||
| 415 | |||
| 416 | zflag db ? ; Used by typefil to indicate ^Z's | ||
| 417 | |||
| 418 | DW 80H DUP(0) ; Init to 0 to make sure the linker is not fooled | ||
| 419 | STACK LABEL WORD | ||
| 420 | |||
| 421 | INTERNATVARS internat_block <> | ||
| 422 | DB (internat_block_max - ($ - INTERNATVARS)) DUP (?) | ||
| 423 | |||
| 424 | BatBufPos DW ? ; integer position in buffer of next byte | ||
| 425 | BatBuf DB BatLen DUP (?) | ||
| 426 | BatBufEnd DW ? | ||
| 427 | |||
| 428 | ; ***************************************************** | ||
| 429 | ; EMG 4.00 | ||
| 430 | ; DATA STARTING HERE WAS ADDED BY EMG FOR 4.00 | ||
| 431 | ; FOR IMPLEMENTATION OF COMMON PARSE ROUTINE | ||
| 432 | ; ***************************************************** | ||
| 433 | ; | ||
| 434 | ; COMMON PARSE OUTPUT BLOCKS | ||
| 435 | ; | ||
| 436 | |||
| 437 | |||
| 438 | ; | ||
| 439 | ; Common output blocks for PARSE number, complex, or string values. | ||
| 440 | ; | ||
| 441 | |||
| 442 | PARSE1_OUTPUT LABEL BYTE ;AN000; | ||
| 443 | PARSE1_TYPE DB 0 ;AN000; type | ||
| 444 | PARSE1_CODE DB 0 ;AN000; return value | ||
| 445 | PARSE1_SYN DW 0 ;AN000; es offset of synonym | ||
| 446 | PARSE1_ADDR DD 0 ;AN000; numeric value / address | ||
| 447 | ; of string value | ||
| 448 | |||
| 449 | ; | ||
| 450 | ; Common output block for PARSE date strings. | ||
| 451 | ; | ||
| 452 | |||
| 453 | DATE_OUTPUT LABEL BYTE ;AN000; | ||
| 454 | DATE_TYPE DB 0 ;AN000; type | ||
| 455 | DB 0 ;AN000; return value | ||
| 456 | DW 0 ;AN000; es offset of synonym | ||
| 457 | DATE_YEAR DW 0 ;AN000; year | ||
| 458 | DATE_MONTH DB 0 ;AN000; month | ||
| 459 | DATE_DAY DB 0 ;AN000; day | ||
| 460 | |||
| 461 | ; | ||
| 462 | ; Common output block for PARSE time strings. | ||
| 463 | ; | ||
| 464 | |||
| 465 | TIME_OUTPUT LABEL BYTE ;AN000; | ||
| 466 | TIME_TYPE DB 0 ;AN000; type | ||
| 467 | DB 0 ;AN000; return value | ||
| 468 | DW 0 ;AN000; es offset of synonym | ||
| 469 | TIME_HOUR DB 0 ;AN000; hour | ||
| 470 | TIME_MINUTES DB 0 ;AN000; minutes | ||
| 471 | TIME_SECONDS DB 0 ;AN000; seconds | ||
| 472 | TIME_FRACTION DB 0 ;AN000; hundredths | ||
| 473 | |||
| 474 | ; | ||
| 475 | ; Common output block for PARSE drive specifier (one based drive number). | ||
| 476 | ; | ||
| 477 | |||
| 478 | DRIVE_OUTPUT LABEL BYTE ;AN000; | ||
| 479 | DRIVE_TYPE DB 0 ;AN000; type | ||
| 480 | DRIVE_VALUE DB 0 ;AN000; return value | ||
| 481 | DW 0 ;AN000; es offset of synonym | ||
| 482 | DRIVE_NUMBER DB 0 ;AN000; drive number | ||
| 483 | DB 0,0,0 ;AN000; reserved | ||
| 484 | |||
| 485 | TRANSPACEEND LABEL BYTE | ||
| 486 | |||
| 487 | TRANSPACE ENDS | ||
| 488 | END | ||
diff --git a/v4.0/src/CMD/COMMAND/TUCODE.ASM b/v4.0/src/CMD/COMMAND/TUCODE.ASM new file mode 100644 index 0000000..6531c44 --- /dev/null +++ b/v4.0/src/CMD/COMMAND/TUCODE.ASM | |||
| @@ -0,0 +1,520 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)tucode.asm 4.2 85/05/31 | ||
| 3 | ; SCCSID = @(#)tucode.asm 4.2 85/05/31 | ||
| 4 | Title COMMAND Language midifiable Code Transient | ||
| 5 | |||
| 6 | |||
| 7 | .xlist | ||
| 8 | .xcref | ||
| 9 | INCLUDE dossym.inc | ||
| 10 | INCLUDE comsw.asm | ||
| 11 | INCLUDE comseg.asm | ||
| 12 | INCLUDE comequ.asm | ||
| 13 | .list | ||
| 14 | .cref | ||
| 15 | |||
| 16 | |||
| 17 | DATARES SEGMENT PUBLIC BYTE ;AC000; | ||
| 18 | EXTRN ECHOFLAG:BYTE | ||
| 19 | DATARES ENDS | ||
| 20 | |||
| 21 | TRANDATA SEGMENT PUBLIC BYTE ;AC000; | ||
| 22 | EXTRN BAD_ON_OFF_ptr:word | ||
| 23 | EXTRN ctrlcmes_ptr:word | ||
| 24 | EXTRN DEL_Y_N_PTR:WORD | ||
| 25 | EXTRN ECHOMES_ptr:word | ||
| 26 | EXTRN extend_buf_ptr:word ;AC000; | ||
| 27 | EXTRN offmes_ptr:word | ||
| 28 | EXTRN onmes_ptr:word | ||
| 29 | EXTRN PARSE_BREAK:BYTE ;AN000; | ||
| 30 | EXTRN promptdat_moday:word ;AC000; | ||
| 31 | EXTRN promptdat_ptr:word ;AC000; | ||
| 32 | EXTRN promptdat_yr:word ;AC000; | ||
| 33 | EXTRN string_buf_ptr:word | ||
| 34 | EXTRN SUREMES_ptr:word | ||
| 35 | EXTRN VERIMES_ptr:BYTE | ||
| 36 | EXTRN WeekTab:word | ||
| 37 | TRANDATA ENDS | ||
| 38 | |||
| 39 | TRANSPACE SEGMENT PUBLIC BYTE ;AC000; | ||
| 40 | EXTRN arg_buf:byte | ||
| 41 | EXTRN BWDBUF:BYTE | ||
| 42 | EXTRN DEST:BYTE | ||
| 43 | EXTRN destdir:byte | ||
| 44 | EXTRN dirchar:byte | ||
| 45 | EXTRN PARSE1_CODE:BYTE ;AN000; | ||
| 46 | EXTRN RESSEG:WORD | ||
| 47 | EXTRN string_ptr_2:word | ||
| 48 | |||
| 49 | TRANSPACE ENDS | ||
| 50 | |||
| 51 | TRANCODE SEGMENT PUBLIC BYTE | ||
| 52 | |||
| 53 | EXTRN CERROR:NEAR | ||
| 54 | EXTRN CRLF2:NEAR | ||
| 55 | EXTRN extend_setup:near ;AN022; | ||
| 56 | |||
| 57 | PUBLIC CNTRLC | ||
| 58 | PUBLIC ECHO | ||
| 59 | PUBLIC GetDate | ||
| 60 | PUBLIC NOTEST2 | ||
| 61 | PUBLIC PRINT_DATE | ||
| 62 | PUBLIC SLASHP_ERASE ;AN000; | ||
| 63 | PUBLIC VERIFY | ||
| 64 | |||
| 65 | ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING | ||
| 66 | |||
| 67 | ; **************************************************************** | ||
| 68 | ; * | ||
| 69 | ; * ROUTINE: NOTEST2 - execution of DEL/ERASE command | ||
| 70 | ; * | ||
| 71 | ; * FUNCTION: Delete files based on user parsed input. Prompt | ||
| 72 | ; * user for Y/N if necessary. If an error occurs, | ||
| 73 | ; * set up an error message and go to CERROR. | ||
| 74 | ; * | ||
| 75 | ; * INPUT: FCB at 5ch set up with filename(s) entered | ||
| 76 | ; * Current directory set to entered directory | ||
| 77 | ; * | ||
| 78 | ; * OUTPUT: none | ||
| 79 | ; * | ||
| 80 | ; **************************************************************** | ||
| 81 | ; | ||
| 82 | ; ARE YOU SURE prompt when deleting *.* | ||
| 83 | |||
| 84 | NOTEST2: | ||
| 85 | MOV CX,11 | ||
| 86 | MOV SI,FCB+1 | ||
| 87 | |||
| 88 | AMBSPEC: | ||
| 89 | LODSB | ||
| 90 | CMP AL,'?' | ||
| 91 | JNZ ALLFIL | ||
| 92 | LOOP AMBSPEC | ||
| 93 | |||
| 94 | ALLFIL: | ||
| 95 | CMP CX,0 | ||
| 96 | JNZ NOPRMPT | ||
| 97 | |||
| 98 | ASKAGN: | ||
| 99 | MOV DX,OFFSET TRANGROUP:SUREMES_ptr ; "Are you sure (Y/N)?" | ||
| 100 | invoke std_printf | ||
| 101 | MOV SI,80H | ||
| 102 | MOV DX,SI | ||
| 103 | MOV WORD PTR [SI],120 ; zero length | ||
| 104 | MOV AX,(STD_CON_INPUT_FLUSH SHL 8) OR STD_CON_STRING_INPUT | ||
| 105 | INT 21H | ||
| 106 | LODSW | ||
| 107 | OR AH,AH | ||
| 108 | JZ ASKAGN | ||
| 109 | INVOKE SCANOFF | ||
| 110 | call char_in_xlat ;G Convert to upper case | ||
| 111 | retc ;AN000; return if function not supported | ||
| 112 | CMP AL,CAPITAL_N ;G | ||
| 113 | retz | ||
| 114 | CMP AL,CAPITAL_Y ;G | ||
| 115 | PUSHF | ||
| 116 | CALL CRLF2 | ||
| 117 | POPF | ||
| 118 | JNZ ASKAGN | ||
| 119 | |||
| 120 | NOPRMPT: | ||
| 121 | MOV AH,FCB_DELETE | ||
| 122 | MOV DX,FCB | ||
| 123 | INT 21H | ||
| 124 | INC AL | ||
| 125 | jz eraerr | ||
| 126 | invoke RESTUDIR | ||
| 127 | ret ; If no error, return | ||
| 128 | |||
| 129 | eraerr: | ||
| 130 | invoke set_ext_error_msg ;AN022; set up the extended error | ||
| 131 | push dx ;AN022; save message | ||
| 132 | invoke RESTUDIR | ||
| 133 | pop dx ;AN022; restore message | ||
| 134 | |||
| 135 | cmp word ptr extend_buf_ptr,error_no_more_files ;AN022; convert no more files to | ||
| 136 | jnz cerrorj2 ;AN022; file not found | ||
| 137 | mov Extend_Buf_ptr,error_file_not_found ;AN000; get message number in control block | ||
| 138 | |||
| 139 | cerrorj2: | ||
| 140 | jmp cerror | ||
| 141 | |||
| 142 | |||
| 143 | ; **************************************************************** | ||
| 144 | ; * | ||
| 145 | ; * ROUTINE: SLASHP_ERASE - execution of DEL/ERASE /P | ||
| 146 | ; * | ||
| 147 | ; * FUNCTION: Delete files based on user parsed input. Prompt | ||
| 148 | ; * user for Y/N where necessary. If an error occurs | ||
| 149 | ; * set up and error message and transfer control | ||
| 150 | ; * to CERROR. | ||
| 151 | ; * | ||
| 152 | ; * INPUT: FCB at 5ch set up with filename(s) entered | ||
| 153 | ; * Current directory set to entered directory | ||
| 154 | ; * | ||
| 155 | ; * OUTPUT: none | ||
| 156 | ; * | ||
| 157 | ; **************************************************************** | ||
| 158 | |||
| 159 | ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING | ||
| 160 | |||
| 161 | SLASHP_ERASE: ;AN000; entry point | ||
| 162 | invoke build_dir_string ;AN000; set up current directory string for output | ||
| 163 | mov ah,Set_DMA ;AN000; issue set dta int 21h | ||
| 164 | mov dx,offset trangroup:destdir ;AN000; use Destdir for target | ||
| 165 | int 21H ;AN000; | ||
| 166 | mov ah,Dir_Search_First ;AN000; do dir search first int 21h | ||
| 167 | mov dx,FCB ;AN000; use FCB at 5Ch for target | ||
| 168 | int 21H ;AN000; | ||
| 169 | inc al ;AN000; did an error occur | ||
| 170 | jz eraerr ;AN022; go to error exit | ||
| 171 | |||
| 172 | delete_prompt_loop: ;AN000; | ||
| 173 | mov si,offset trangroup:destdir+1 ;AN000; set up FCB as source | ||
| 174 | mov di,offset trangroup:dest ;AN000; set up dest as target | ||
| 175 | mov al,dirchar ;AN000; store a "\" in the first char | ||
| 176 | stosb ;AN000; of DEST | ||
| 177 | invoke fcb_to_ascz ;AN000; convert filename from FCB to ASCIIZ string | ||
| 178 | |||
| 179 | slashp_askagn: ;AN000; | ||
| 180 | call crlf2 ;AN000; print out carriage return, line feed | ||
| 181 | mov dx,offset trangroup:bwdbuf ;AN000; print out current directory string | ||
| 182 | mov bx,dx ;AN000; get string pointer in bx | ||
| 183 | cmp byte ptr [bx+3],end_of_line_out ;AN000; see if only D:\,0 | ||
| 184 | jnz not_del_root ;AN000; no continue | ||
| 185 | mov byte ptr [bx+2],end_of_line_out ;AN000; yes, get rid of \ | ||
| 186 | |||
| 187 | Not_del_root: ;AN000; | ||
| 188 | mov string_ptr_2,dx ;AN000; | ||
| 189 | mov dx,offset trangroup:string_buf_ptr ;AN000; | ||
| 190 | invoke std_printf ;AN000; | ||
| 191 | mov dx,offset trangroup:dest ;AN000; print out file name string | ||
| 192 | mov string_ptr_2,dx ;AN000; | ||
| 193 | mov dx,offset trangroup:string_buf_ptr ;AN000; | ||
| 194 | invoke std_printf ;AN000; | ||
| 195 | mov dx,offset trangroup:Del_Y_N_Ptr ;AN000; issue ", Delete (Y/N)?" message | ||
| 196 | invoke std_printf ;AN000; | ||
| 197 | mov si,80H ;AN000; set up buffer for input | ||
| 198 | mov dx,si ;AN000; | ||
| 199 | mov word ptr [si],combuflen ;AN000; | ||
| 200 | mov ax,(std_con_input_flush shl 8) or std_con_string_input ;AN000; | ||
| 201 | int int_command ;AN000; get input from the user | ||
| 202 | lodsw ;AN000; | ||
| 203 | or ah,ah ;AN000; was a character entered? | ||
| 204 | jz slashp_askagn ;AN000; no - ask again | ||
| 205 | invoke scanoff ;AN000; scan off leading delimiters | ||
| 206 | call char_in_xlat ;AN000; yes - upper case it | ||
| 207 | retc ;AN000; return if function not supported | ||
| 208 | cmp al,capital_n ;AN000; was it no? | ||
| 209 | jz next_del_file ;AN000; yes - don't delete file | ||
| 210 | cmp al,capital_y ;AN000; was it yes? | ||
| 211 | jz delete_this_file ;AN000; yes - delete the file | ||
| 212 | jmp short slashp_askagn ;AN000; it was neither - ask again | ||
| 213 | |||
| 214 | delete_this_file: ;AN000; | ||
| 215 | mov ah,fcb_delete ;AN000; delete the file | ||
| 216 | mov dx,offset trangroup:destdir ;AN000; use Destdir for target | ||
| 217 | int int_command ;AN000; | ||
| 218 | inc al ;AN000; did an error occur? | ||
| 219 | jnz next_del_file ;AN000; no - get next file | ||
| 220 | jmp eraerr ;AN022; go to error exit - need long jmp | ||
| 221 | |||
| 222 | next_del_file: ;AN000; | ||
| 223 | mov ah,dir_search_next ;AN000; search for another file | ||
| 224 | mov dx,FCB ;AN000; | ||
| 225 | int int_command ;AN000; | ||
| 226 | inc al ;AN000; was a file found? | ||
| 227 | jz slash_p_exit ;AN000; no - exit | ||
| 228 | jmp delete_prompt_loop ;AN000; yes - continue (need long jump) | ||
| 229 | |||
| 230 | slash_p_exit: | ||
| 231 | invoke get_ext_error_number ;AN022; get the extended error number | ||
| 232 | cmp ax,error_no_more_files ;AN022; was error file not found? | ||
| 233 | jz good_erase_exit ;AN022; yes - clean exit | ||
| 234 | jmp extend_setup ;AN022; go issue error message | ||
| 235 | |||
| 236 | good_erase_exit: | ||
| 237 | invoke restudir ;AN000; we're finished - restore user's dir | ||
| 238 | call crlf2 ;AN000; print out carriage return, line feed | ||
| 239 | ret ;AN000; exit | ||
| 240 | |||
| 241 | |||
| 242 | ;************************************************ | ||
| 243 | ; ECHO, BREAK, and VERIFY commands. Check for "ON" and "OFF" | ||
| 244 | |||
| 245 | break Echo | ||
| 246 | |||
| 247 | assume ds:trangroup,es:trangroup | ||
| 248 | |||
| 249 | ECHO: | ||
| 250 | CALL ON_OFF | ||
| 251 | JC DOEMES | ||
| 252 | MOV DS,[RESSEG] | ||
| 253 | ASSUME DS:RESGROUP | ||
| 254 | JNZ ECH_OFF | ||
| 255 | OR [ECHOFLAG],1 | ||
| 256 | RET | ||
| 257 | ECH_OFF: | ||
| 258 | AND [ECHOFLAG],NOT 1 | ||
| 259 | RET | ||
| 260 | |||
| 261 | |||
| 262 | CERRORJ: | ||
| 263 | JMP CERROR | ||
| 264 | |||
| 265 | ; | ||
| 266 | ; There was no discrenable ON or OFF after the ECHO. If there is nothing but | ||
| 267 | ; delimiters on the command line, we issue the ECHO is ON/OFF message. | ||
| 268 | ; | ||
| 269 | |||
| 270 | ASSUME DS:TRANGROUP | ||
| 271 | |||
| 272 | DOEMES: | ||
| 273 | cmp cl,0 ;AC000; was anything on the line? | ||
| 274 | jz PEcho ; just display current state. | ||
| 275 | MOV DX,82H ; Skip one char after "ECHO" | ||
| 276 | invoke CRPRINT | ||
| 277 | JMP CRLF2 | ||
| 278 | |||
| 279 | PECHO: | ||
| 280 | MOV DS,[RESSEG] | ||
| 281 | ASSUME DS:RESGROUP | ||
| 282 | MOV BL,[ECHOFLAG] | ||
| 283 | PUSH CS | ||
| 284 | POP DS | ||
| 285 | ASSUME DS:TRANGROUP | ||
| 286 | AND BL,1 | ||
| 287 | MOV DX,OFFSET TRANGROUP:ECHOMES_ptr | ||
| 288 | JMP SHORT PYN | ||
| 289 | |||
| 290 | break Break | ||
| 291 | assume ds:trangroup,es:trangroup | ||
| 292 | |||
| 293 | CNTRLC: | ||
| 294 | CALL ON_OFF | ||
| 295 | MOV AX,(SET_CTRL_C_TRAPPING SHL 8) OR 1 | ||
| 296 | JC PCNTRLC | ||
| 297 | JNZ CNTRLC_OFF | ||
| 298 | MOV DL,1 | ||
| 299 | INT 21H ; Set ^C | ||
| 300 | RET | ||
| 301 | |||
| 302 | CNTRLC_OFF: | ||
| 303 | XOR DL,DL | ||
| 304 | INT 21H ; Turn off ^C check | ||
| 305 | RET | ||
| 306 | |||
| 307 | PCNTRLC: | ||
| 308 | CMP CL,0 ;AC000; rest of line blank? | ||
| 309 | JNZ CERRORJ ; no, oops! | ||
| 310 | |||
| 311 | pccont: | ||
| 312 | XOR AL,AL | ||
| 313 | INT 21H | ||
| 314 | MOV BL,DL | ||
| 315 | MOV DX,OFFSET TRANGROUP:CTRLCMES_ptr | ||
| 316 | |||
| 317 | PYN: | ||
| 318 | mov si,offset trangroup:onmes_ptr ;AC000; get ON pointer | ||
| 319 | OR BL,BL | ||
| 320 | JNZ PRINTVAL | ||
| 321 | mov si,offset trangroup:offmes_ptr ;AC000; get OFF pointer | ||
| 322 | |||
| 323 | PRINTVAL: | ||
| 324 | push dx ;AN000; save offset of message block | ||
| 325 | mov bx,dx ;AN000; save offset value | ||
| 326 | lodsw ;AN000; get message number of on or off | ||
| 327 | mov dh,util_msg_class ;AN000; this is a utility message | ||
| 328 | invoke Tsysgetmsg ;AN000; get the address of the message | ||
| 329 | add bx,ptr_off_pos ;AN000; point to offset of ON/OFF | ||
| 330 | mov word ptr [bx],si ;AN000; put the offset in the message block | ||
| 331 | pop dx ;AN000; get message back | ||
| 332 | invoke std_printf ;AC000; go print message | ||
| 333 | mov word ptr [bx],0 ;AN000; zero out message pointer | ||
| 334 | |||
| 335 | ret ;AN000; exit | ||
| 336 | |||
| 337 | break Verify | ||
| 338 | assume ds:trangroup,es:trangroup | ||
| 339 | |||
| 340 | VERIFY: | ||
| 341 | CALL ON_OFF | ||
| 342 | MOV AX,(SET_VERIFY_ON_WRITE SHL 8) OR 1 | ||
| 343 | JC PVERIFY | ||
| 344 | JNZ VER_OFF | ||
| 345 | INT 21H ; Set verify | ||
| 346 | RET | ||
| 347 | |||
| 348 | VER_OFF: | ||
| 349 | DEC AL | ||
| 350 | INT 21H ; Turn off verify after write | ||
| 351 | RET | ||
| 352 | |||
| 353 | PVERIFY: | ||
| 354 | CMP CL,0 ;AC000; is rest of line blank? | ||
| 355 | JNZ CERRORJ ; nope... | ||
| 356 | MOV AH,GET_VERIFY_ON_WRITE | ||
| 357 | INT 21H | ||
| 358 | MOV BL,AL | ||
| 359 | MOV DX,OFFSET TRANGROUP:VERIMES_ptr | ||
| 360 | JMP PYN | ||
| 361 | |||
| 362 | ; **************************************************************** | ||
| 363 | ; * | ||
| 364 | ; * ROUTINE: ON_OFF | ||
| 365 | ; * | ||
| 366 | ; * FUNCTION: Parse the command line for an optional ON or | ||
| 367 | ; * OFF string for the BREAK, VERIFY, and ECHO | ||
| 368 | ; * routines. | ||
| 369 | ; * | ||
| 370 | ; * INPUT: command line at offset 81H | ||
| 371 | ; * PARSE_BREAK control block | ||
| 372 | ; * | ||
| 373 | ; * OUTPUT: If carry is clear | ||
| 374 | ; * If ON is found | ||
| 375 | ; * Zero flag set | ||
| 376 | ; * If OFF is found | ||
| 377 | ; * Zero flag clear | ||
| 378 | ; * If carry set | ||
| 379 | ; * If nothing on command line | ||
| 380 | ; * CL set to zero | ||
| 381 | ; * If error | ||
| 382 | ; * CL contains error value from parse | ||
| 383 | ; * | ||
| 384 | ; **************************************************************** | ||
| 385 | |||
| 386 | assume ds:trangroup,es:trangroup | ||
| 387 | |||
| 388 | ON_OFF: | ||
| 389 | MOV SI,81h | ||
| 390 | |||
| 391 | scan_on_off: ;AN032; scan off leading blanks & equal | ||
| 392 | lodsb ;AN032; get a char | ||
| 393 | cmp al,blank ;AN032; if whitespace | ||
| 394 | jz scan_on_off ;AN032; keep scanning | ||
| 395 | cmp al,tab_chr ;AN032; if tab | ||
| 396 | jz scan_on_off ;AN032; keep scanning | ||
| 397 | cmp al,equal_chr ;AN032; if equal char | ||
| 398 | jz parse_on_off ;AN032; start parsing | ||
| 399 | dec si ;AN032; if none of above - back up | ||
| 400 | |||
| 401 | parse_on_off: ;AN032; and start parsing | ||
| 402 | mov di,offset trangroup:parse_break ;AN000; Get adderss of PARSE_BREAK | ||
| 403 | xor cx,cx ;AN000; clear cx,dx | ||
| 404 | xor dx,dx ;AN000; | ||
| 405 | invoke cmd_parse ;AC000; call parser | ||
| 406 | cmp ax,end_of_line ;AC000; are we at end of line? | ||
| 407 | jz BADONF ;AC000; yes, return error | ||
| 408 | cmp ax,result_no_error ;AN000; did an error occur | ||
| 409 | jz on_off_there ;AN000; no - continue | ||
| 410 | mov cx,ax ;AN000; yes - set cl to error code | ||
| 411 | jmp short BADONF ;AN000; return error | ||
| 412 | |||
| 413 | on_off_there: | ||
| 414 | cmp parse1_code,-1 ;AN014; was a valid positional present? | ||
| 415 | jnz good_on_off ;AN014; yes - continue | ||
| 416 | mov cx,badparm_ptr ;AN014; something other than ON/OFF | ||
| 417 | jmp short BADONF ;AN014; return error | ||
| 418 | |||
| 419 | good_on_off: ;AN014; | ||
| 420 | xor ax,ax ;AC000; set up return code for | ||
| 421 | or al,parse1_code ;AC000; ON or OFF in AX | ||
| 422 | pushf ;AN000; save flags | ||
| 423 | mov di,offset trangroup:parse_break ;AN000; Get adderss of PARSE_BREAK | ||
| 424 | xor dx,dx ;AN000; | ||
| 425 | invoke cmd_parse ;AN000; call parser | ||
| 426 | cmp ax,end_of_line ;AN000; are we at end of line? | ||
| 427 | jnz BADONF_flags ;AN000; NO, return error | ||
| 428 | popf ;AN000; restore flags | ||
| 429 | clc ;AC000; no error | ||
| 430 | jmp short on_off_end ;AN000; return to caller | ||
| 431 | |||
| 432 | BADONF_flags: | ||
| 433 | mov cx,ax | ||
| 434 | popf | ||
| 435 | |||
| 436 | ; | ||
| 437 | ; No discernable ON or OFF has been found. Put an error message pointer in DX | ||
| 438 | ; and return the error | ||
| 439 | ; | ||
| 440 | BADONF: | ||
| 441 | MOV DX,OFFSET TRANGROUP:BAD_ON_OFF_ptr | ||
| 442 | STC | ||
| 443 | |||
| 444 | ON_OFF_END: | ||
| 445 | |||
| 446 | RET | ||
| 447 | |||
| 448 | |||
| 449 | |||
| 450 | ;************************************************************************* | ||
| 451 | ; print date | ||
| 452 | |||
| 453 | PRINT_DATE: | ||
| 454 | PUSH ES | ||
| 455 | PUSH DI | ||
| 456 | PUSH CS | ||
| 457 | POP ES | ||
| 458 | CALL GetDate ; get date | ||
| 459 | xchg dh,dl ;AN000; switch month & day | ||
| 460 | mov promptDat_yr,cx ;AC000; put year into message control block | ||
| 461 | mov promptDat_moday,dx ;AC000; put month and day into message control block | ||
| 462 | mov dx,offset trangroup:promptDat_ptr ;AC000; set up message for output | ||
| 463 | invoke std_printf | ||
| 464 | ;AD061; mov promptDat_yr,0 ;AC000; reset year, month and day | ||
| 465 | ;AD061; mov promptDat_moday,0 ;AC000; pointers in control block | ||
| 466 | POP DI ;AC000; restore di,es | ||
| 467 | POP ES ;AC000; | ||
| 468 | return | ||
| 469 | ; | ||
| 470 | ; Do GET DATE system call and set up 3 character day of week in ARG_BUF | ||
| 471 | ; for output. Date will be returned in CX,DX. | ||
| 472 | ; | ||
| 473 | |||
| 474 | GetDate: | ||
| 475 | mov di,offset trangroup:arg_buf ;AC000; target for day of week | ||
| 476 | MOV AH,GET_DATE ;AC000; get current date | ||
| 477 | INT int_command ;AC000; Get date in CX:DX | ||
| 478 | CBW ;AC000; | ||
| 479 | |||
| 480 | push cx ;AN000; save date returned in | ||
| 481 | push dx ;AN000; CX:DX | ||
| 482 | MOV SI,AX | ||
| 483 | SHL SI,1 | ||
| 484 | ADD SI,AX ; SI=AX*3 | ||
| 485 | mov cx,si ;AN000; save si | ||
| 486 | mov ax,weektab ;AN000; get message number of weektab | ||
| 487 | mov dh,util_msg_class ;AN000; this is a utility message | ||
| 488 | push di ;AN000; save argument buffer | ||
| 489 | invoke Tsysgetmsg ;AN000; get the address of the message | ||
| 490 | pop di ;AN000; retrieve argument buffer | ||
| 491 | add si,cx ;AC000; get day of week | ||
| 492 | MOV CX,3 | ||
| 493 | REP MOVSB | ||
| 494 | mov al,end_of_line_out ;AC000; terminate the string | ||
| 495 | stosb | ||
| 496 | pop dx ;AN000; get back date | ||
| 497 | pop cx ;AN000; | ||
| 498 | |||
| 499 | return | ||
| 500 | ;g | ||
| 501 | ;g This routine determines whether the character in AL is a | ||
| 502 | ;g Yes or No character. On return, if AL=0, the character is | ||
| 503 | ;g No, if AL=1, the character is Yes. | ||
| 504 | ;g | ||
| 505 | |||
| 506 | assume ds:trangroup | ||
| 507 | |||
| 508 | char_in_xlat proc near | ||
| 509 | |||
| 510 | mov dl,al ;AC000; get character into DX | ||
| 511 | xor dh,dh ;AC000; | ||
| 512 | mov ax,(getextcntry SHL 8) + 35 ;AC000; Yes/No char call | ||
| 513 | int int_command ;AC000; | ||
| 514 | |||
| 515 | ret | ||
| 516 | |||
| 517 | char_in_xlat endp | ||
| 518 | |||
| 519 | TRANCODE ENDS | ||
| 520 | END | ||
diff --git a/v4.0/src/CMD/COMMAND/UINIT.ASM b/v4.0/src/CMD/COMMAND/UINIT.ASM new file mode 100644 index 0000000..8f3498b --- /dev/null +++ b/v4.0/src/CMD/COMMAND/UINIT.ASM | |||
| @@ -0,0 +1,270 @@ | |||
| 1 | page 80,132 | ||
| 2 | ; SCCSID = @(#)uinit.asm 4.5 85/12/04 | ||
| 3 | ; SCCSID = @(#)uinit.asm 4.5 85/12/04 | ||
| 4 | TITLE COMMAND Initialization messages | ||
| 5 | |||
| 6 | .XCREF | ||
| 7 | .XLIST | ||
| 8 | include comsw.asm | ||
| 9 | include comseg.asm | ||
| 10 | include ifequ.asm | ||
| 11 | .LIST | ||
| 12 | .CREF | ||
| 13 | |||
| 14 | addr macro sym,name | ||
| 15 | public name | ||
| 16 | ifidn <name>,<> | ||
| 17 | |||
| 18 | dw offset resgroup:sym | ||
| 19 | else | ||
| 20 | |||
| 21 | name dw offset resgroup:sym | ||
| 22 | endif | ||
| 23 | endm | ||
| 24 | |||
| 25 | |||
| 26 | ENVIRONMENT SEGMENT PUBLIC PARA ;AC000; | ||
| 27 | EXTRN ECOMSPEC:BYTE | ||
| 28 | ENVIRONMENT ENDS | ||
| 29 | |||
| 30 | TRANCODE SEGMENT PUBLIC BYTE ;AC000; | ||
| 31 | extrn Printf_init:FAR | ||
| 32 | extrn Triage_Init:FAR | ||
| 33 | extrn append_parse:FAR ;AN054; | ||
| 34 | TranCode ENDS | ||
| 35 | |||
| 36 | INIT SEGMENT PUBLIC PARA ;AC000; | ||
| 37 | |||
| 38 | |||
| 39 | public icondev | ||
| 40 | public BADCSPFL | ||
| 41 | public COMSPECT | ||
| 42 | public AUTOBAT | ||
| 43 | public fslash | ||
| 44 | public bslash | ||
| 45 | public space | ||
| 46 | public PRDATTM | ||
| 47 | public INITADD | ||
| 48 | public print_add | ||
| 49 | public CHUCKENV | ||
| 50 | public scswitch | ||
| 51 | public ucasea | ||
| 52 | public ECOMLOC | ||
| 53 | public equalsign | ||
| 54 | public lcasea | ||
| 55 | public lcasez | ||
| 56 | public comspstring | ||
| 57 | public EnvSiz | ||
| 58 | public EnvMax | ||
| 59 | public initend | ||
| 60 | public trnsize | ||
| 61 | public resetenv ;AC000; | ||
| 62 | public ext_msg ;AC000; | ||
| 63 | public num_positionals | ||
| 64 | public internat_info | ||
| 65 | public parsemes_ptr | ||
| 66 | |||
| 67 | PUBLIC triage_add | ||
| 68 | PUBLIC oldenv | ||
| 69 | PUBLIC usedenv | ||
| 70 | PUBLIC KAUTOBAT ;AN000; 3/3/KK | ||
| 71 | public eswitch ;AN018; | ||
| 72 | public dswitch ;AN018; | ||
| 73 | public init_parse ;AN054; | ||
| 74 | public old_parse_ptr ;AN057; | ||
| 75 | PUBLIC pars_msg_off ;AN060; | ||
| 76 | PUBLIC pars_msg_seg ;AN060; | ||
| 77 | |||
| 78 | include resmsg.equ ;AC000; | ||
| 79 | |||
| 80 | |||
| 81 | ICONDEV LABEL BYTE | ||
| 82 | DB "/DEV/" | ||
| 83 | DB "CON",0,0,0,0,0,0 ; Room for 8 char device | ||
| 84 | BADCSPFL DB 0 | ||
| 85 | COMSPECT DB "/COMMAND.COM",0,0 | ||
| 86 | AUTOBAT DB 0,":\AUTOEXEC.BAT",0,0DH ;AC027; | ||
| 87 | KAUTOBAT DB 0,":\KAUTOEXE.BAT",0,0DH ;AC027; 3/3/KK | ||
| 88 | |||
| 89 | PRDATTM DB -1 ;Init not to prompt for date time | ||
| 90 | INITADD DD ? | ||
| 91 | print_add LABEL DWORD | ||
| 92 | DW OFFSET TranGroup:Printf_INIT | ||
| 93 | DW 0 | ||
| 94 | triage_add LABEL DWORD | ||
| 95 | DW OFFSET TranGroup:Triage_Init | ||
| 96 | DW 0 | ||
| 97 | CHUCKENV DB 0 | ||
| 98 | ;eg ECOMLOC DW OFFSET ENVIRONMENT:ECOMSPEC-10H | ||
| 99 | ECOMLOC DW OFFSET ENVIRONMENT:ECOMSPEC ;eg | ||
| 100 | |||
| 101 | COMSPSTRING DB "COMSPEC=" | ||
| 102 | equalsign db "=" | ||
| 103 | lcasea db "a" | ||
| 104 | lcasez db "z" | ||
| 105 | fslash db "/" | ||
| 106 | bslash db "\" | ||
| 107 | space db " " | ||
| 108 | scswitch db "C" ; Single command | ||
| 109 | ucasea db "A" | ||
| 110 | |||
| 111 | EnvSiz DW 0 ; size user wants to allocate | ||
| 112 | EnvMax DW 0 ; maximum size allowed. | ||
| 113 | oldenv DW 0 ; envirseg at initialization | ||
| 114 | usedenv DW 0 ; amount of envirseg used | ||
| 115 | PARS_MSG_OFF DW 0 ;AN060; SAVED PARSE ERROR MESSAGE OFFSET | ||
| 116 | PARS_MSG_SEG DW 0 ;AN060; SAVED PARSE ERROR MESSAGE SEGMENT | ||
| 117 | |||
| 118 | ;Do not separate the following two words. Used to call transient PARSE routine | ||
| 119 | |||
| 120 | init_parse label dword ;AN054; | ||
| 121 | init_p DW TRANGROUP:APPEND_PARSE ;AN054; | ||
| 122 | initend DW 0 ;eg segment address of end of init | ||
| 123 | |||
| 124 | ;End of data that shouldn't be separated. | ||
| 125 | |||
| 126 | trnsize DW 0 ;eg size of transient in paragraphs | ||
| 127 | resetenv DB 0 ;eg set if we need to setblck env at endinit | ||
| 128 | ext_msg DB 0 ;AN000; set if /MSG switch entered | ||
| 129 | eswitch db 0 ;AN018; set if /e was entered | ||
| 130 | dswitch db 0 ;AN018; set if /d was entered | ||
| 131 | parsemes_ptr dw 0 ;AN000; word to store parse error number | ||
| 132 | |||
| 133 | ; | ||
| 134 | ; PARSE BLOCK FOR COMMAND | ||
| 135 | ; | ||
| 136 | PUBLIC PARSE_COMMAND ;AN000; | ||
| 137 | PUBLIC COMND1_OUTPUT ;AN000; | ||
| 138 | PUBLIC COMND1_TYPE ;AN000; | ||
| 139 | PUBLIC COMND1_CODE ;AN000; | ||
| 140 | PUBLIC COMND1_SYN ;AN000; | ||
| 141 | PUBLIC COMND1_ADDR ;AN000; | ||
| 142 | PUBLIC COMMAND_F_SYN ;AN000; | ||
| 143 | PUBLIC COMMAND_P_SYN ;AN000; | ||
| 144 | PUBLIC COMMAND_C_SYN ;AN000; | ||
| 145 | PUBLIC COMMAND_D_SYN ;AN000; | ||
| 146 | PUBLIC COMMAND_E_SYN ;AN000; | ||
| 147 | PUBLIC COMMAND_M_SYN ;AN000; | ||
| 148 | |||
| 149 | ; | ||
| 150 | ; The following parse control block is used for COMMAND. This block is | ||
| 151 | ; used for parsing during initialization. The sytax for COMMAND is: | ||
| 152 | ; COMMAND [d:][path][/P][/F][/D][/E:xxxxx][/MSG][/C executable] | ||
| 153 | ; Anything on the command line after the /C switch will be passed to the | ||
| 154 | ; executable command, so if /C is used, it must be specified last. The | ||
| 155 | ; /MSG switch can only be specified if the /P switch is specified. | ||
| 156 | ; | ||
| 157 | |||
| 158 | ENVBIG EQU 32768 ;AN000; maximum environment size | ||
| 159 | ENVSML EQU 160 ;AN000; minimum environment size | ||
| 160 | |||
| 161 | INTERNAT_INFO LABEL BYTE ;AN000; used for country info after parsing is completed | ||
| 162 | PARSE_COMMAND LABEL BYTE ;AN000; | ||
| 163 | DW RESGROUP:COMMAND_PARMS ;AN000; | ||
| 164 | DB 0 ;AN000; no extra delimiter | ||
| 165 | |||
| 166 | COMMAND_PARMS LABEL BYTE ;AN000; | ||
| 167 | DB 0,1 ;AN000; 1 positional parm | ||
| 168 | DW RESGROUP:COMMAND_FILE ;AN000; | ||
| 169 | DB 6 ;AN000; 6 switches | ||
| 170 | DW RESGROUP:COMMAND_SWITCH1 ;AN000; | ||
| 171 | DW RESGROUP:COMMAND_SWITCH2 ;AN000; | ||
| 172 | DW RESGROUP:COMMAND_SWITCH3 ;AN000; | ||
| 173 | DW RESGROUP:COMMAND_SWITCH4 ;AN000; | ||
| 174 | DW RESGROUP:COMMAND_SWITCH5 ;AN000; | ||
| 175 | DW RESGROUP:COMMAND_SWITCH6 ;AN000; | ||
| 176 | DB 0 ;AN000; no keywords | ||
| 177 | |||
| 178 | COMMAND_FILE LABEL BYTE ;AN000; | ||
| 179 | DW 0201H ;AN000; filespec - optional | ||
| 180 | DW 1 ;AN000; capitalize - file table | ||
| 181 | DW RESGROUP:COMND1_OUTPUT ;AN000; result buffer | ||
| 182 | DW RESGROUP:NO_VAL ;AN000; | ||
| 183 | DB 0 ;AN000; no keywords | ||
| 184 | |||
| 185 | COMMAND_SWITCH1 LABEL BYTE ;AN000; | ||
| 186 | DW 0 ;AN000; no match flags | ||
| 187 | DW 2 ;AN000; capitalize by char table | ||
| 188 | DW RESGROUP:COMND1_OUTPUT ;AN000; result buffer | ||
| 189 | DW RESGROUP:NO_VAL ;AN000; | ||
| 190 | DB 1 ;AN000; 1 keyword | ||
| 191 | COMMAND_P_SYN DB "/P",0 ;AN000; /P switch | ||
| 192 | |||
| 193 | COMMAND_SWITCH2 LABEL BYTE ;AN000; | ||
| 194 | DW 0 ;AN000; no match flags | ||
| 195 | DW 2 ;AN000; capitalize by char table | ||
| 196 | DW RESGROUP:COMND1_OUTPUT ;AN000; result buffer | ||
| 197 | DW RESGROUP:NO_VAL ;AN000; | ||
| 198 | DB 1 ;AN000; 1 keyword | ||
| 199 | COMMAND_F_SYN DB "/F",0 ;AN000; /F switch | ||
| 200 | |||
| 201 | COMMAND_SWITCH3 LABEL BYTE ;AN000; | ||
| 202 | DW 0 ;AN000; no match flags | ||
| 203 | DW 2 ;AN000; capitalize by char table | ||
| 204 | DW RESGROUP:COMND1_OUTPUT ;AN000; result buffer | ||
| 205 | DW RESGROUP:NO_VAL ;AN000; | ||
| 206 | DB 1 ;AN000; 1 keyword | ||
| 207 | COMMAND_D_SYN DB "/D",0 ;AN000; /D switch | ||
| 208 | |||
| 209 | COMMAND_SWITCH4 LABEL BYTE ;AN000; | ||
| 210 | DW 8000H ;AN000; numeric value - required | ||
| 211 | DW 0 ;AN000; no function flags | ||
| 212 | DW RESGROUP:COMND1_OUTPUT ;AN000; result buffer | ||
| 213 | DW RESGROUP:COMMAND_E_VAL ;AN000; pointer to value list | ||
| 214 | DB 1 ;AN000; 1 keyword | ||
| 215 | COMMAND_E_SYN DB "/E",0 ;AN000; /E switch | ||
| 216 | |||
| 217 | COMMAND_E_VAL LABEL BYTE ;AN000; | ||
| 218 | DB 1 ;AN000; | ||
| 219 | DB 1 ;AN000; 1 range | ||
| 220 | DB 1 ;AN000; returned if result | ||
| 221 | DD ENVSML,ENVBIG ;AN000; minimum & maximum value | ||
| 222 | DB 0 ;AN000; no numeric values | ||
| 223 | DB 0 ;AN000; no string values | ||
| 224 | |||
| 225 | COMMAND_SWITCH5 LABEL BYTE ;AN000; | ||
| 226 | DW 0 ;AN000; no match flags | ||
| 227 | DW 2 ;AN000; capitalize by char table | ||
| 228 | DW RESGROUP:COMND1_OUTPUT ;AN000; result buffer | ||
| 229 | DW RESGROUP:NO_VAL ;AN000; | ||
| 230 | DB 1 ;AN000; 1 keyword | ||
| 231 | COMMAND_C_SYN DB "/C",0 ;AN000; /C switch | ||
| 232 | |||
| 233 | COMMAND_SWITCH6 LABEL BYTE ;AN000; | ||
| 234 | DW 0 ;AN000; no match flags | ||
| 235 | DW 2 ;AN000; capitalize by char table | ||
| 236 | DW RESGROUP:COMND1_OUTPUT ;AN000; result buffer | ||
| 237 | DW RESGROUP:NO_VAL ;AN000; | ||
| 238 | DB 1 ;AN000; 1 keyword | ||
| 239 | COMMAND_M_SYN DB "/MSG",0 ;AN000; /MSG switch | ||
| 240 | |||
| 241 | COMND1_OUTPUT LABEL BYTE ;AN000; | ||
| 242 | COMND1_TYPE DB 0 ;AN000; type | ||
| 243 | COMND1_CODE DB 0 ;AN000; return value | ||
| 244 | COMND1_SYN DW 0 ;AN000; synonym pointer | ||
| 245 | COMND1_ADDR DD 0 ;AN000; numeric value / address | ||
| 246 | ; of string value | ||
| 247 | |||
| 248 | NO_VAL DB 0 ;AN000; no values | ||
| 249 | num_positionals DW 0 ;AN000; counter for positionals | ||
| 250 | old_parse_ptr DW 0 ;AN057; SI position before calling parser | ||
| 251 | |||
| 252 | .xlist | ||
| 253 | .xcref | ||
| 254 | |||
| 255 | INCLUDE SYSMSG.INC ;AN000; get message services routine | ||
| 256 | |||
| 257 | .list | ||
| 258 | .cref | ||
| 259 | |||
| 260 | ASSUME DS:RESGROUP,ES:RESGROUP,CS:RESGROUP | ||
| 261 | |||
| 262 | MSG_UTILNAME <COMMAND> ;AN000; define utility name | ||
| 263 | |||
| 264 | MSG_SERVICES <COMR,COMMAND.CLB> ;AN000; include initialization messages | ||
| 265 | |||
| 266 | include msgdcl.inc | ||
| 267 | |||
| 268 | INIT ENDS | ||
| 269 | |||
| 270 | END | ||