From 2d04cacc5322951f187bb17e017c12920ac8ebe2 Mon Sep 17 00:00:00 2001 From: Mark Zbikowski Date: Thu, 25 Apr 2024 21:24:10 +0100 Subject: MZ is back! --- v4.0/src/CMD/COMMAND/TMISC1.ASM | 655 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 655 insertions(+) create mode 100644 v4.0/src/CMD/COMMAND/TMISC1.ASM (limited to 'v4.0/src/CMD/COMMAND/TMISC1.ASM') 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 @@ + page 80,132 +; SCCSID = @(#)tmisc1.asm 4.1 85/09/22 +; SCCSID = @(#)tmisc1.asm 4.1 85/09/22 +TITLE Part7 COMMAND Transient Routines + +; More misc routines + +.xlist +.xcref + INCLUDE comsw.asm + INCLUDE DOSSYM.INC + INCLUDE comseg.asm + INCLUDE comequ.asm +.list +.cref + + + +CODERES SEGMENT PUBLIC BYTE ;AC000; + EXTRN RSTACK:BYTE +CodeRes ENDS + +DATARES SEGMENT PUBLIC BYTE ;AC000; + EXTRN CALL_FLAG:BYTE + EXTRN EchoFlag:BYTE + EXTRN EXEC_BLOCK:BYTE + EXTRN EXTCOM:BYTE + EXTRN PIPEFLAG:BYTE + EXTRN PIPEPTR:WORD + EXTRN PIPESTR:BYTE + EXTRN RESTDIR:BYTE + EXTRN RE_OUT_APP:BYTE + EXTRN RE_OUTSTR:BYTE +DATARES ENDS + +TRANDATA SEGMENT PUBLIC BYTE ;AC000; + EXTRN BADDRV_PTR:WORD + EXTRN BADNAM_PTR:WORD + EXTRN COMTAB:BYTE ;AC000; + EXTRN extend_buf_ptr:word ;AN000; + EXTRN msg_disp_class:byte ;AN000; +TRANDATA ENDS + +TRANSPACE SEGMENT PUBLIC BYTE ;AC000; + EXTRN arg:byte ; the arg structure! + EXTRN APPEND_EXEC:BYTE ;AN041; + EXTRN CHKDRV:BYTE + EXTRN COMBUF:BYTE + EXTRN EXECPATH:BYTE + EXTRN EXEC_ADDR:DWORD + EXTRN FILTYP:BYTE + EXTRN IDLEN:BYTE + EXTRN KPARSE:BYTE ;AC000; + EXTRN PARM1:BYTE + EXTRN PARM2:BYTE + EXTRN PathPos:word + EXTRN RESSEG:WORD + EXTRN RE_INSTR:BYTE + EXTRN SPECDRV:BYTE + EXTRN SWITCHAR:BYTE + EXTRN switch_list:byte + EXTRN TRAN_TPA:WORD + + IF IBM + EXTRN ROM_CALL:BYTE + EXTRN ROM_CS:WORD + EXTRN ROM_IP:WORD + ENDIF + +TRANSPACE ENDS + +TRANCODE SEGMENT PUBLIC byte + +ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING + + EXTRN APPEND_PARSE:NEAR ;AN010; + EXTRN BATCOM:NEAR + EXTRN DOCOM1:NEAR + EXTRN PIPEERRSYN:NEAR + EXTRN TCOMMAND:NEAR + + IF IBM + EXTRN ROM_EXEC:NEAR + EXTRN ROM_SCAN:NEAR + ENDIF + + PUBLIC CERROR + PUBLIC DRVBAD + PUBLIC EXTERNAL + PUBLIC FNDCOM + PUBLIC PRESCAN + PUBLIC SWITCH + + +ASSUME DS:TRANGROUP + +;--------------------------- +; We can get rid of this switch processing code if we can take +; care of the remaining two calls to switch, later in the file. +; However, I have not checked whether or not any other files use +; switch -- after all, it IS public! +;--------------------------- +RETSW: + XCHG AX,BX ; Put switches in AX + return + +SWITCH: + XOR BX,BX ; Initialize - no switches set +SWLOOP: + INVOKE SCANOFF ; Skip any delimiters + CMP AL,[SWITCHAR] ; Is it a switch specifier? + JNZ RETSW ; No -- we're finished + OR BX,fSwitch ; Indicate there is a switch specified + INC SI ; Skip over the switch character + INVOKE SCANOFF + CMP AL,0DH + JZ RETSW ; Oops + INC SI +; Convert lower case input to upper case + INVOKE UPCONV + MOV DI,OFFSET TRANGROUP:switch_list + MOV CX,SWCOUNT + REPNE SCASB ; Look for matching switch + JNZ BADSW + MOV AX,1 + SHL AX,CL ; Set a bit for the switch + OR BX,AX + JMP SHORT SWLOOP + +BADSW: + JMP SHORT SWLOOP + +SWCOUNT EQU 5 ; Length of switch_list + +DRVBAD: + MOV DX,OFFSET TRANGROUP:BADDRV_ptr + JMP CERROR + +externalj: + jmp EXTERNAL + +fndcom: ; search the internal command table + OR AL,AL ; Get real length of first arg + jz externalj ; If 0, it must begin with "\" so has + ; to be external. +; barryf code starts here + + IF IBM + call test_append ; see if APPEND installed + je contcom ; not loaded + +append_internal: + mov cl,TRANGROUP:IDLEN + mov ch,0 + mov pathpos,cx + inc append_exec ;AN041; set APPEND to ON + + invoke ioset ; re-direct the o'l io + + mov SI, offset TRANGROUP:IDLEN ; address command name, DS already set + mov DX,-1 ; set invoke function + mov di,offset TRANGROUP:APPEND_PARSE;AN010; Get the entry point for PARSE for APPEND + mov AX,0AE01H + int 2FH ; execute command + cmp TRANGROUP:IDLEN,0 ; execute requested + jne contcom + jmp Cmd_done + +contcom: ; continue with internal scan + ENDIF + +; barryf code ends here + + mov DI, OFFSET TRANGROUP:COMTAB + XOR CX,CX + +findcom: + mov SI, offset TRANGROUP:IDLEN+1 ; pointer to command argument + mov CL, [DI] ; load length of internal command + inc di ; advance past length + jcxz externalj ; if it's zero, we're out of internals + cmp CL, IDLEN ; that of the command argument + jnz abcd ; lengths not equal ==> strings not eq + MOV PathPos,CX ; store length of command + repz cmpsb + +abcd: + lahf ; save the good ol' flags + add DI, CX ; skip over remaining internal, if any + mov AL, BYTE PTR [DI] ; load drive-check indicator byte (DCIB) + mov [CHKDRV], AL ; save command flag byte in chkdrv + inc DI ; increment DI (OK, OK, I'll stop) + mov BX, WORD PTR [DI] ; load internal command address + inc DI ; skip over the puppy + inc DI + sahf ; remember those flags? + jnz findcom ; well, if all the cmps worked... +; +; All messages get redirected. +; + cmp append_exec,0 ;AN041; APPEND just executed? + jnz dont_set_io ;AN041; Yes - this junk is already set + invoke ioset ; re-direct the ol' i/o + +dont_set_io: ;AN041; + invoke SETSTDINON ;AN026; turn on critical error on STDIN + invoke SETSTDOUTOFF ;AN026; turn off critical error on STDOUT + test [CHKDRV], fCheckDrive ; did we wanna check those drives? + jz nocheck + mov AL, [PARM1] ; parse_file_descriptor results tell + or AL, [PARM2] ; us whether those drives were OK + cmp AL, -1 + jnz nocheck + jmp drvbad + + +; +; The user may have omitted the space between the command and its arguments. +; We need to copy the remainder of the user's command line into the buffer. +; Note that thisdoes not screw up the arg structure; it points into COMBUF not +; into the command line at 80. +; +nocheck: + call cmd_copy + +switcheck: + test [CHKDRV], fSwitchAllowed ; Does the command take switches + jnz realwork ; Yes, process the command + call noswit ; No, check to see if any switches + jnz realwork ; None, process the command + mov msg_disp_class,parse_msg_class ;AN000; set up parse error msg class + MOV DX,OFFSET TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer + mov Extend_Buf_ptr,BadSwt_ptr ;AN000; get "Invalid switch" message number + jmp CERROR ; Print error and chill out... +realwork: + call BX ; do some real work, at last + +; See if we're in a batch CALL command. If we are, reprocess the command line, +; otherwise, go get another command. + +Cmd_done: + push cs ; g restore data segment + pop ds ; g + push ds ; g save data segment + mov ds,[resseg] ; g get segment containing call flag + ASSUME ds:resgroup + cmp call_flag, call_in_progress ; G Is a call in progress? + mov call_flag, 0 ; G Either way, reset flag + pop ds ; g get data segment back + jz incall ; G + jmp tcommand ; chill out... + +incall: + JMP DOCOM1 + +noswit: + push di ; Save di + mov di,81h ; di = ptr to command args + mov si,80h ; Get address of length of command args + lodsb ; Load length + mov cl,al ; Move length to cl + xor ch,ch ; Zero ch + mov al,[SWITCHAR] ; al = switch character + cmp al,0 ; Turn off ZF + repnz scasb ; Scan for a switch character and return + pop di ; with ZF set if one was found + ret + +EXTERNAL: + +IF IBM + call test_append ; check to see if append installed + je not_barryf ; no - truly external command + jmp append_internal ; yes - go to Barryf code + +not_barryf: + +ENDIF + + MOV [FILTYP],0 + MOV DL,[SPECDRV] + MOV [IDLEN],DL +IF IBM + MOV [ROM_CALL],0 + PUSH DX + MOV DX,OFFSET TRANGROUP:IDLEN + CALL ROM_SCAN + POP DX + JNC DO_SCAN + INC [ROM_CALL] + JMP PostSave +DO_SCAN: +ENDIF +IF IBM +PostSave: +ENDIF + MOV DI,OFFSET TRANGROUP:EXECPATH + MOV BYTE PTR [DI],0 ; Initialize to current directory +IF IBM + CMP [ROM_CALL],0 + JZ Research + JMP NeoExecute +ENDIF +RESEARCH: + invoke path_search ; find the mother (result in execpath) + or AX, AX ; did we find anything? + je badcomj45 ; null means no (sob) + cmp AX, 04H ; 04H and 08H are .exe and .com + jl rsrch_br1 ; fuckin' sixteen-bit machine ought + jmp execute ; to be able to handle a SIXTEEN-BIT +rsrch_br1: ; DISPLACEMENT!! + jmp batcom ; 02H is .bat +BADCOMJ45: + JMP BADCOM + +ASSUME DS:TRANGROUP,ES:TRANGROUP + +EXECUTE: +NeoExecute: + invoke IOSET + invoke SETSTDINOFF ;AN026; turn off critical error on STDIN + invoke SETSTDOUTOFF ;AN026; turn off critical error on STDOUT + MOV ES,[TRAN_TPA] + MOV AH,DEALLOC + INT int_command ; Now running in "free" space + MOV ES,[RESSEG] +ASSUME ES:RESGROUP + INC [EXTCOM] ; Indicate external command + MOV [RESTDIR],0 ; Since USERDIR1 is in transient, insure + ; this flag value for re-entry to COMMAND + MOV DI,FCB + MOV SI,DI + MOV CX,052H ; moving (100h-5Ch)/2 = 80h-2Eh + REP MOVSW ; Transfer parameters to resident header + MOV DX,OFFSET TRANGROUP:EXECPATH + MOV BX,OFFSET RESGROUP:EXEC_BLOCK + MOV AX,EXEC SHL 8 +IF IBM + TEST [ROM_CALL],-1 + JZ OK_EXEC + JMP ROM_EXEC +OK_EXEC: +ENDIF +; +; we are now running in free space. anything we do from here on may get +; trashed. Move the stack (also in free space) to allocated space because +; since EXEC restores the stack, somebody may trash what is on the stack. +; + MOV CX,ES + MOV SS,CX + MOV SP,OFFSET RESGROUP:RSTACK + JMP [EXEC_ADDR] ; Jmp to the EXEC in the resident + +BADCOM: + PUSH CS + POP DS + MOV DX,OFFSET TRANGROUP:BADNAM_ptr + +CERROR: + INVOKE std_eprintf + JMP TCOMMAND + +; +; Prescan converts the input buffer into a canonicalized form. All +; redirections and pipes are removed. +; +PRESCAN: ; Cook the input buffer + +ASSUME DS:TRANGROUP,ES:TRANGROUP + + XOR CX,CX + MOV ES,[RESSEG] +ASSUME ES:RESGROUP + MOV SI,OFFSET TRANGROUP:COMBUF+2 + MOV DI,SI + +CountQuotes: + LODSB ; get a byte + CMP AL,22h ; is it a quote? + JNZ CountEnd ; no, try for end of road + INC CH ; bump count + JMP CountQuotes ; go get next char + +CountEnd: + CMP AL,13 ; end of road? + JNZ CountQuotes ; no, go back for next char + +;;;; IF KANJI 3/3/KK + PUSH CX ; save count + MOV SI,DI ; get back beginning of buffer + +KanjiScan: + LODSB ; get a byte + INVOKE TestKanj ; is it a leadin byte + JZ KanjiQuote ; no, check for quotes + MOV AH,AL ; save leadin + LODSB ; get trailing byte + CMP AX,8140h ; is it Kanji space + JNZ KanjiScan ; no, go get next + MOV [SI-2],2020h ; replace with spaces + JMP KanjiScan ; go get next char + +KanjiQuote: + CMP AL,22h ; beginning of quoted string + JNZ KanjiEnd ; no, check for end + DEC CH ; drop count + JZ KanjiScan ; if count is zero, no quoting + +KanjiQuoteLoop: + LODSB ; get next byte + CMP AL,22h ; is it another quote + JNZ KanjiQuoteLoop ; no, get another + DEC CH ; yes, drop count + JMP KanjiScan ; go get next char + +KanjiEnd: + CMP AL,13 ; end of line character? + JNZ KanjiScan ; go back to beginning + POP CX ; get back original count +;;;; ENDIF 3/3/KK + + MOV SI,DI ; restore pointer to begining + +PRESCANLP: + LODSB + +;;;; IF KANJI 3/3/KK + INVOKE TESTKANJ + JZ NOTKANJ6 + MOV [DI],AL + INC DI ; fake STOSB into DS + LODSB ; grab second byte + MOV [DI],AL ; fake stosb into DS + INC DI + INC CL + INC CL + JMP PRESCANLP + +NOTKANJ6: +;;;; ENDIF 3/3/KK + + CMP AL,'"' ; " character + JNZ TRYGREATER + DEC CH + JZ TRYGREATER + +QLOOP: + MOV [DI],AL + INC DI + INC CL + LODSB + CMP AL,'"' ; " character + JNZ QLOOP + DEC CH + +TRYGREATER: + CMP AL,rabracket + JNZ NOOUT +; +; We have found a ">" char. We need to see if there is another ">" +; following it. +; + CMP BYTE PTR [SI],al + JNZ NOAPPND + LODSB + INC [RE_OUT_APP] ; Flag >> + +NOAPPND: +; +; Now we attempt to find the file name. First, scan off all whitespace +; + INVOKE SCANOFF + CMP AL,labracket ;AN040; was there no filename? + JZ REOUT_ERRSET ;AN040; yes - set up error + CMP AL,0DH + JNZ GOTREOFIL +; +; There was no file present. Set us up at end-of-line. +; +REOUT_ERRSET: ;AN040; set up for an error + mov byte ptr [di], 0dh ; Clobber first ">" + MOV WORD PTR [RE_OUTSTR],09H ; Cause an error later + JMP PRESCANEND + +GOTREOFIL: + PUSH DI + MOV DI,OFFSET RESGROUP:RE_OUTSTR + MOV BX,DI + PUSH ES + +SETREOUTSTR: ; Get the output redirection name + LODSB + CMP AL,0DH + JZ GOTRESTR + INVOKE DELIM + JZ GOTRESTR + CMP AL,[SWITCHAR] + JZ GOTRESTR + CMP AL,'"' ;AN033; Is the character a quote? + JZ PIPEERRSYNJ5 ;AN033; Yes - get out quick - or system crashes + CMP AL,labracket ;AN002; Is char for input redirection + JZ ABRACKET_TERM ;AN002; yes - end of string + CMP AL,rabracket ;AN002; Is char for output redirection + JNZ NO_ABRACKET ;AN002; no - not end of string + +abracket_term: ;AN002; have end of string by < or > + DEC SI ;AN002; back up over symbol + MOV AL,BLANK ;AN002; show delimiter as char + JMP SHORT GOTRESTR ;AN002; go process it + +no_abracket: ;AN002; not at end of string + STOSB ; store it into resgroup + JMP SHORT SETREOUTSTR + +NOOUT: + CMP AL,labracket + JNZ CHKPIPE + mov bx,si ; Save loc of "<" + INVOKE SCANOFF + CMP AL,rabracket ;AN040; was there no filename? + JZ REIN_ERRSET ;AN040; yes - set up error + CMP AL,0DH + JNZ GOTREIFIL + +REIN_ERRSET: ;AN040; set up for error + mov byte ptr [di],0dh ; Clobber "<" + MOV WORD PTR [RE_INSTR],09H ; Cause an error later + JMP SHORT PRESCANEND + +GOTREIFIL: + PUSH DI + MOV DI,OFFSET TranGROUP:RE_INSTR + MOV BX,DI + PUSH ES + PUSH CS + POP ES ; store in TRANGROUP + JMP SHORT SETREOUTSTR ; Get the input redirection name + +CHKPIPE: + MOV AH,AL + CMP AH,AltPipeChr + JZ IsPipe3 + CMP AH,vbar + JNZ CONTPRESCAN + +IsPipe3: +; +; Only push the echo flag if we are entering the pipe for the first time. +; + CMP PipeFlag,0 + JNZ NoEchoPush + SHL EchoFlag,1 ; push echo state and turn it off +NoEchoPush: + INC [PIPEFLAG] + INVOKE SCANOFF + CMP AL,0DH + JZ PIPEERRSYNJ5 + CMP AL,AltPipeChr + JZ PIPEERRSYNJ5 + CMP AL,vbar ; Double '|'? + JNZ CONTPRESCAN + +PIPEERRSYNJ5: + PUSH ES + POP DS ; DS->RESGROUP + JMP PIPEERRSYN + +; +; Trailing :s are allowed on devices. Check to be sure that there is more +; than just a : in the redir string. +; +GOTRESTR: + XCHG AH,AL + mov al,':' + SUB BX,DI ; compute negatinve of number of chars + CMP BX,-1 ; is there just a :? + JZ NotTrailCol ; yep, don't change + CMP BYTE PTR ES:[DI-1],al ; Trailing ':' OK on devices + JNZ NOTTRAILCOL + DEC DI ; Back up over trailing ':' + +NOTTRAILCOL: + XOR AL,AL + STOSB ; NUL terminate the string + POP ES + POP DI ; Remember the start + +CONTPRESCAN: + MOV [DI],AH ; "delete" the redirection string + INC DI + CMP AH,0DH + JZ PRESCANEND + INC CL + JMP PRESCANLP + +PRESCANEND: + CMP [PIPEFLAG],0 + JZ ISNOPIPE + MOV DI,OFFSET RESGROUP:PIPESTR + MOV [PIPEPTR],DI + MOV SI,OFFSET TRANGROUP:COMBUF+2 + INVOKE SCANOFF + +PIPESETLP: ; Transfer the pipe into the resident + LODSB ; pipe buffer + STOSB + CMP AL,0DH + JNZ PIPESETLP + +ISNOPIPE: + MOV [COMBUF+1],CL + CMP [PIPEFLAG],0 + PUSH CS + POP ES + return + +cmd_copy proc near + + MOV SI,OFFSET TRANGROUP:COMBUF+2 + INVOKE Scanoff ; advance past separators... + add si,PathPos + mov di,81h + xor cx,cx + +CmdCopy: + lodsb + stosb + cmp al,0dh + jz CopyDone + inc cx + jmp CmdCopy + +CopyDone: + mov byte ptr ds:[80h],cl ; Store count + + ret +cmd_copy endp + + +test_append proc near + + mov BX,offset TRANGROUP:COMBUF ; barry can address + mov SI, offset TRANGROUP:IDLEN ; address command name, DS already set + mov DX,-1 ; set install check function + mov AX,0AE00H + int 2FH ; see if loaded + cmp AL,00H + + ret + +test_append endp + +TRANCODE ENDS + END + \ No newline at end of file -- cgit v1.2.3