From 80ab2fddfdf30f09f0a0a637654cbb3cd5c7baa6 Mon Sep 17 00:00:00 2001 From: Rich Turner Date: Fri, 12 Aug 1983 17:53:34 -0700 Subject: MS-DOS v2.0 Release --- v2.0/source/TCODE.ASM | 1088 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1088 insertions(+) create mode 100644 v2.0/source/TCODE.ASM (limited to 'v2.0/source/TCODE.ASM') diff --git a/v2.0/source/TCODE.ASM b/v2.0/source/TCODE.ASM new file mode 100644 index 0000000..dfe6ca5 --- /dev/null +++ b/v2.0/source/TCODE.ASM @@ -0,0 +1,1088 @@ +TITLE PART1 - COMMAND Transient routines. + + INCLUDE COMSW.ASM + +.xlist +.xcref + INCLUDE DOSSYM.ASM + INCLUDE DEVSYM.ASM + INCLUDE COMSEG.ASM +.list +.cref + + INCLUDE COMEQU.ASM + + +DATARES SEGMENT PUBLIC + EXTRN BATCH:WORD,BATLOC:DWORD,PARMBUF:BYTE + EXTRN RESTDIR:BYTE,EXTCOM:BYTE,ECHOFLAG:BYTE + EXTRN SINGLECOM:WORD,VERVAL:WORD,FORFLAG:BYTE + EXTRN RE_INSTR:BYTE,RE_OUT_APP:BYTE,PIPE1:BYTE,PIPE2:BYTE + EXTRN RE_OUTSTR:BYTE,PIPEFLAG:BYTE,PIPEFILES:BYTE,PIPEPTR:WORD + EXTRN INPIPEPTR:WORD,OUTPIPEPTR:WORD,EXEC_BLOCK:BYTE,ENVIRSEG:WORD +DATARES ENDS + +TRANDATA SEGMENT PUBLIC + EXTRN BADBAT:BYTE,NEEDBAT:BYTE,BADNAM:BYTE + EXTRN SYNTMES:BYTE,BADDRV:BYTE,BYTMES_POST:BYTE + EXTRN DIRMES_PRE:BYTE,DIRMES_POST:BYTE,BYTMES_PRE:BYTE + EXTRN NOTFND:BYTE,PIPEEMES:BYTE,BADPMES:BYTE,COMTAB:BYTE +TRANDATA ENDS + +TRANSPACE SEGMENT PUBLIC + EXTRN UCOMBUF:BYTE,COMBUF:BYTE,USERDIR1:BYTE,EXECPATH:BYTE + EXTRN DIRCHAR:BYTE,EXEC_ADDR:DWORD,RCH_ADDR:DWORD,CHKDRV:BYTE + EXTRN CURDRV:BYTE,PARM1:BYTE,PARM2:BYTE,COMSW:WORD,ARG1S:WORD + EXTRN ARG2S:WORD,ARGTS:WORD,SPECDRV:BYTE,BYTCNT:WORD,IDLEN:BYTE + EXTRN DIRBUF:BYTE,ID:BYTE,COM:BYTE,LINCNT:BYTE,INTERNATVARS:BYTE + EXTRN HEADCALL:DWORD,RESSEG:WORD,TPA:WORD,SWITCHAR:BYTE + EXTRN STACK:WORD,FILTYP:BYTE,FILECNT:WORD,LINLEN:BYTE + + + IF KANJI + EXTRN KPARSE:BYTE + ENDIF +TRANSPACE ENDS + +; ******************************************************************** +; START OF TRANSIENT PORTION +; This code is loaded at the end of memory and may be overwritten by +; memory-intensive user programs. + +TRANCODE SEGMENT PUBLIC PARA +ASSUME CS:TRANGROUP,DS:NOTHING,ES:NOTHING,SS:NOTHING + + + EXTRN SCANOFF:NEAR,DELIM:NEAR,SAVUDIR:NEAR,SAVUDIR1:NEAR + EXTRN PATHCHRCMP:NEAR,PRINT:NEAR,RESTUDIR:NEAR + EXTRN CRLF2:NEAR,PRINT_PROMPT:NEAR,GETBATBYT:NEAR,PRESCAN:NEAR + EXTRN CRPRINT:NEAR,DISP32BITS:NEAR,FCB_TO_ASCZ:NEAR + EXTRN ERROR_PRINT:NEAR,FREE_TPA:NEAR,ALLOC_TPA:NEAR + EXTRN $EXIT:NEAR,FORPROC:NEAR,FIND_NAME_IN_ENVIRONMENT:NEAR + EXTRN UPCONV:NEAR,BATOPEN:NEAR,BATCLOSE:NEAR,IOSET:NEAR,FIND_PATH:NEAR + EXTRN TESTDOREIN:NEAR,TESTDOREOUT:NEAR + + PUBLIC SWLIST,CERROR,SETREST1,DOCOM,DOCOM1,DRVBAD,NOTFNDERR + PUBLIC COMMAND,TCOMMAND,SWITCH,PIPEERRSYN,GETKEYSTROKE,SETREST + PUBLIC CHKCNT + + + IF KANJI + EXTRN TESTKANJ:NEAR + ENDIF + + ORG 0 +ZERO = $ + + ORG 100H ; Allow for 100H parameter area + +SETDRV: + MOV AH,SET_DEFAULT_DRIVE + INT int_command +TCOMMAND: + MOV DS,[RESSEG] +ASSUME DS:RESGROUP + MOV AX,-1 + XCHG AX,[VERVAL] + CMP AX,-1 + JZ NOSETVER2 + MOV AH,SET_VERIFY_ON_WRITE ; AL has correct value + INT int_command +NOSETVER2: + CALL [HEADCALL] ; Make sure header fixed + XOR BP,BP ; Flag transient not read + CMP [SINGLECOM],-1 + JNZ COMMAND +$EXITPREP: + PUSH CS + POP DS + JMP $EXIT ; Have finished the single command +ASSUME DS:NOTHING +COMMAND: + CLD + MOV AX,CS + MOV SS,AX +ASSUME SS:TRANGROUP + MOV SP,OFFSET TRANGROUP:STACK + MOV ES,AX +ASSUME ES:TRANGROUP + MOV DS,[RESSEG] +ASSUME DS:RESGROUP + STI + + MOV [UCOMBUF],COMBUFLEN ; Init UCOMBUF + MOV [COMBUF],COMBUFLEN ; Init COMBUF (Autoexec doing DATE) + OR BP,BP ; See if just read + JZ TESTRDIR ; Not read, check user directory + MOV WORD PTR [UCOMBUF+1],0D01H ; Reset buffer + JMP SHORT NOSETBUF +TESTRDIR: + CMP [RESTDIR],0 + JZ NOSETBUF ; User directory OK + PUSH DS + PUSH CS + POP DS +ASSUME DS:TRANGROUP + MOV DX,OFFSET TRANGROUP:USERDIR1 + MOV AH,CHDIR + INT int_command ; Restore users directory + POP DS +ASSUME DS:RESGROUP +NOSETBUF: + CMP [PIPEFILES],0 + JZ NOPCLOSE ; Don't bother if they don't exist + CMP [PIPEFLAG],0 + JNZ NOPCLOSE ; Don't del if still piping + CALL PIPEDEL +NOPCLOSE: + MOV [EXTCOM],0 ; Flag internal command + MOV [RESTDIR],0 ; Flag users dirs OK + MOV AX,CS ; Get segment we're in + MOV DS,AX +ASSUME DS:TRANGROUP + PUSH AX + MOV DX,OFFSET TRANGROUP:INTERNATVARS + MOV AX,INTERNATIONAL SHL 8 + INT 21H + POP AX + SUB AX,[TPA] ; AX=size of TPA in paragraphs + MOV DX,16 + MUL DX ; DX:AX=size of TPA in bytes + OR DX,DX ; See if over 64K + JZ SAVSIZ ; OK if not + MOV AX,-1 ; If so, limit to 65535 bytes +SAVSIZ: + MOV [BYTCNT],AX ; Max no. of bytes that can be buffered + MOV DS,[RESSEG] ; All batch work must use resident seg. +ASSUME DS:RESGROUP + TEST [ECHOFLAG],-1 + JZ GETCOM ; Don't do the CRLF + CALL SINGLETEST + JB GETCOM + CALL CRLF2 +GETCOM: + MOV AH,GET_DEFAULT_DRIVE + INT int_command + MOV [CURDRV],AL + TEST [ECHOFLAG],-1 + JZ NOPDRV ; No prompt if echo off + CALL SINGLETEST + JB NOPDRV + CALL PRINT_PROMPT ; Prompt the user +NOPDRV: + TEST [PIPEFLAG],-1 ; Pipe has highest presedence + JZ NOPIPE + JMP PIPEPROC ; Continue the pipeline +NOPIPE: + TEST [FORFLAG],-1 ; FOR has next highest precedence + JZ TESTFORBAT + JMP FORPROC ; Continue the FOR +TESTFORBAT: + MOV [RE_INSTR],0 ; Turn redirection back off + MOV [RE_OUTSTR],0 + MOV [RE_OUT_APP],0 + TEST [BATCH],-1 ; Batch has lowest precedence + JZ ISNOBAT + JMP READBAT ; Continue BATCH + +ISNOBAT: + CMP [SINGLECOM],0 + JZ REGCOM + MOV SI,-1 + XCHG SI,[SINGLECOM] + MOV DI,OFFSET TRANGROUP:COMBUF + 2 + XOR CX,CX +SINGLELOOP: + LODSB + STOSB + INC CX + CMP AL,0DH + JNZ SINGLELOOP + DEC CX + PUSH CS + POP DS +ASSUME DS:TRANGROUP + MOV [COMBUF + 1],CL + JMP DOCOM + +REGCOM: + PUSH CS + POP DS ; Need local segment to point to buffer + MOV DX,OFFSET TRANGROUP:UCOMBUF + MOV AH,STD_CON_STRING_INPUT + INT int_command ; Get a command + MOV CL,[UCOMBUF] + XOR CH,CH + ADD CX,3 + MOV SI,OFFSET TRANGROUP:UCOMBUF + MOV DI,OFFSET TRANGROUP:COMBUF + REP MOVSB ; Transfer it to the cooked buffer + JMP DOCOM + +; All batch proccessing has DS set to segment of resident portion +ASSUME DS:RESGROUP,ES:TRANGROUP + +NEEDENV: + PUSH DS + PUSH SI + PUSH DI + + MOV DI,OFFSET TRANGROUP:ID + ADD AL,"0" + STOSB +GETENV1: + CALL GETBATBYT + STOSB + CMP AL,13 + JZ GETENV2 + CMP AL,"%" + JNZ GETENV1 + MOV BYTE PTR ES:[DI-1],"=" +GETENV2: + MOV SI,OFFSET TRANGROUP:ID + PUSH CS + POP DS ; DS:SI POINTS TO NAME +ASSUME DS:TRANGROUP,ES:RESGROUP + CALL FIND_NAME_IN_environment + PUSH ES + POP DS + PUSH CS + POP ES +ASSUME DS:RESGROUP,ES:TRANGROUP + MOV SI,DI + POP DI ; get back pointer to command line + JNC GETENV4 + +GETENV3: ; Parameter not found + PUSH CS + POP DS + MOV SI,OFFSET TRANGROUP:ID + +GETENV4: + LODSB ; From resident segment + OR AL,AL ; Check for end of parameter + JZ GETENV6 + CMP AL,13 + JZ GETENV6 + CMP AL,"=" + JZ GETENVX + STOSB + JMP GETENV4 + +GETENVX: + MOV AL,"%" + STOSB +GETENV6: + POP SI + POP DS + CMP AL,13 + JZ SAVBATBYTJ + JMP RDBAT + +NEEDPARM: + CALL GETBATBYT + CMP AL,"%" ; Check for two consecutive % + JZ SAVBATBYTJ + CMP AL,13 ; Check for end-of-line + JNZ PAROK +SAVBATBYTJ: + JMP SAVBATBYT +PAROK: + SUB AL,"0" + JB NEEDENV ; look for parameter in the environment + CMP AL,9 + JA NEEDENV + + CBW + MOV SI,AX + SHL SI,1 ; Two bytes per entry + PUSH ES + PUSH DI + MOV ES,[BATCH] + XOR CX,CX + MOV AX,CX + MOV DI,CX + DEC CX + REPNZ SCASB + ADD DI,SI + MOV SI,ES:[DI] + POP DI + POP ES + CMP SI,-1 ; Check if parameter exists + JZ RDBAT ; Ignore if it doesn't +RDPARM: + LODSB ; From resident segment + CMP AL,0DH ; Check for end of parameter + JZ RDBAT + STOSB + JMP RDPARM + +PROMPTBAT: + MOV DX,OFFSET TRANGROUP:NEEDBAT + CALL [RCH_ADDR] + JZ AskForBat ; Media is removable +NoAskForBat: + MOV ES,[BATCH] ; Turn off batch + MOV AH,DEALLOC + INT int_command ; free up the batch piece + MOV [BATCH],0 ; AFTER DEALLOC in case of ^C + MOV [FORFLAG],0 ; Turn off for processing + MOV [PIPEFLAG],0 ; Turn off any pipe + PUSH CS + POP DS + MOV DX,OFFSET TRANGROUP:BADBAT + CALL ERROR_PRINT ; Tell user no batch file + JMP TCOMMAND + +ASKFORBAT: + PUSH CS + POP DS + CALL ERROR_PRINT ; Prompt for batch file + CALL GetKeystroke + JMP TCOMMAND +;************************************************************************** +; read the next keystroke + +GetKeystroke: + MOV AX,(STD_CON_INPUT_FLUSH SHL 8) OR STD_CON_INPUT_no_echo + INT int_command ; Get character with KB buffer flush + MOV AX,(STD_CON_INPUT_FLUSH SHL 8) + 0 + INT int_command + return + +READBAT: + CALL BATOPEN + JC PROMPTBAT + MOV DI,OFFSET TRANGROUP:COMBUF+2 +TESTNOP: + CALL GETBATBYT + CMP AL,':' ; Label/Comment? + JNZ NOTLABEL +NOPLINE: ; Consume the line + CALL GETBATBYT + CMP AL,0DH + JNZ NOPLINE + CALL GETBATBYT ; Eat Linefeed + TEST [BATCH],-1 + JNZ TESTNOP + JMP TCOMMAND ; Hit EOF + +RDBAT: + CALL GETBATBYT +NOTLABEL: + CMP AL,"%" ; Check for parameter + JNZ SAVBATBYT + JMP NEEDPARM +SAVBATBYT: + STOSB + CMP AL,0DH + JNZ RDBAT + SUB DI,OFFSET TRANGROUP:COMBUF+3 + MOV AX,DI + MOV ES:[COMBUF+1],AL ; Set length of line + CALL GETBATBYT ; Eat linefeed + CALL BATCLOSE + TEST [ECHOFLAG],-1 + PUSH CS + POP DS ; Go back to local segment + JZ NOECHO2 +ASSUME DS:TRANGROUP + MOV DX,OFFSET TRANGROUP:COMBUF+2 + CALL CRPRINT +DOCOM: +; All segments are local for command line processing + CALL CRLF2 +DOCOM1: + +NOECHO2: + CALL PRESCAN ; Cook the input buffer + JZ NOPIPEPROC + JMP PIPEPROCSTRT ; Fire up the pipe +NOPIPEPROC: + MOV SI,OFFSET TRANGROUP:COMBUF+2 + MOV DI,OFFSET TRANGROUP:IDLEN + MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H ; Make FCB with blank scan-off + INT int_command + CMP AL,1 ; Check for ambiguous command name + JZ BADCOMJ1 ; Ambiguous commands not allowed + CMP AL,-1 + JNZ DRVGD + JMP DRVBAD + +BADCOMJ1: + JMP BADCOM + +DRVGD: + MOV AL,[DI] + MOV [SPECDRV],AL + MOV AL," " + MOV CX,9 + INC DI + REPNE SCASB ; Count no. of letters in command name + MOV AL,9 + SUB AL,CL + MOV [IDLEN],AL + MOV DI,81H + XOR CX,CX + PUSH SI +COMTAIL: + LODSB + STOSB ; Move command tail to 80H + CMP AL,13 + LOOPNZ COMTAIL + NOT CL + MOV BYTE PTR DS:[80H],CL + POP SI +; If the command has 0 parameters must check here for +; any switches that might be present. +; SI -> first character after the command. + CALL SWITCH ; Is the next character a SWITCHAR + MOV [COMSW],AX + MOV DI,FCB + MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H + INT int_command + MOV [PARM1],AL ; Save result of parse + +PRBEG: + LODSB + CMP AL,[SWITCHAR] + JZ PRFIN + CMP AL,13 + JZ PRFIN + CALL DELIM + JNZ PRBEG +PRFIN: + DEC SI + CALL SWITCH + MOV [ARG1S],AX + MOV DI,FCB+10H + MOV AX,(PARSE_FILE_DESCRIPTOR SHL 8) OR 01H + INT int_command ; Parse file name + MOV [PARM2],AL ; Save result + CALL SWITCH + MOV [ARG2S],AX + OR AX,[ARG1S] + MOV [ARGTS],AX +SWTLP: ; Find any remaining switches + CMP BYTE PTR [SI],0DH + JZ GOTALLSW + INC SI + CALL SWITCH + OR [ARGTS],AX + JMP SHORT SWTLP + +GOTALLSW: + MOV AL,[IDLEN] + MOV DL,[SPECDRV] + OR DL,DL ; Check if drive was specified + JZ OK + JMP DRVCHK +OK: + DEC AL ; Check for null command + JNZ FNDCOM + MOV DS,[RESSEG] +ASSUME DS:RESGROUP + CMP [SINGLECOM],-1 + JZ EXITJ + JMP GETCOM + +EXITJ: + JMP $EXITPREP +ASSUME DS:TRANGROUP + +RETSW: + XCHG AX,BX ; Put switches in AX + return + +SWITCH: + XOR BX,BX ; Initialize - no switches set +SWLOOP: + CALL SCANOFF ; Skip any delimiters + CMP AL,[SWITCHAR] ; Is it a switch specifier? + JNZ RETSW ; No -- we're finished + OR BX,GOTSWITCH ; Indicate there is a switch specified + INC SI ; Skip over the switch character + CALL SCANOFF + CMP AL,0DH + JZ RETSW ; Oops + INC SI +; Convert lower case input to upper case + CALL UPCONV + MOV DI,OFFSET TRANGROUP:SWLIST + 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 + +SWLIST DB "VBAPW" +SWCOUNT EQU $-SWLIST + +DRVBAD: + MOV DX,OFFSET TRANGROUP:BADDRV + JMP CERROR + +FNDCOM: + MOV SI,OFFSET TRANGROUP:COMTAB ; Prepare to search command table + MOV CH,0 +FINDCOM: + MOV DI,OFFSET TRANGROUP:IDLEN + MOV CL,[SI] + JCXZ EXTERNAL + REPE CMPSB + LAHF + ADD SI,CX ; Bump to next position without affecting flags + SAHF + LODSB ; Get flag for drive check + MOV [CHKDRV],AL + LODSW ; Get address of command + JNZ FINDCOM + MOV DX,AX + CMP [CHKDRV],0 + JZ NOCHECK + MOV AL,[PARM1] + OR AL,[PARM2] ; Check if either parm. had invalid drive + CMP AL,-1 + JZ DRVBAD +NOCHECK: + CALL IOSET + CALL DX ; Call the internal +COMJMP: + JMP TCOMMAND + +SETDRV1: + JMP SETDRV + +DRVCHK: + DEC DL ; Adjust for correct drive number + DEC AL ; Check if anything else is on line + JZ SETDRV1 +EXTERNAL: + MOV [FILTYP],0 + MOV DL,[SPECDRV] + MOV [IDLEN],DL + CALL SAVUDIR ; Drive letter already checked + MOV AL,'?' + MOV DI,OFFSET TRANGROUP:COM + STOSB ; Look for any extension + STOSB + STOSB + MOV DX,OFFSET TRANGROUP:DIRBUF ; Command will end up here + MOV AH,SET_DMA + INT int_command + PUSH ES + CALL FIND_PATH + MOV SI,DI + POP ES + + MOV DI,OFFSET TRANGROUP:EXECPATH + MOV BYTE PTR [DI],0 ; Initialize to current directory +RESEARCH: + MOV AH,DIR_SEARCH_FIRST +COMSRCH: + PUSH CS + POP DS + MOV DX,OFFSET TRANGROUP:IDLEN + INT int_command + OR AL,AL + MOV AH,DIR_SEARCH_NEXT ; Do search-next next + JNZ PATHCHK + CMP WORD PTR [DIRBUF+9],4F00H + "C" + JNZ CHKEXE + CMP [DIRBUF+11],"M" + JNZ CHKEXE + OR [FILTYP],4 + JMP EXECUTE ; If we find a COM were done + +CHKEXE: + CMP WORD PTR [DIRBUF+9],5800H + "E" + JNZ CHKBAT + CMP [DIRBUF+11],"E" + JNZ CHKBAT + OR [FILTYP],1 ; Flag an EXE found + JMP COMSRCH ; Continue search + +CHKBAT: + CMP WORD PTR [DIRBUF+9],4100H + "B" + JNZ COMSRCH + CMP [DIRBUF+11],"T" + JNZ COMSRCH + OR [FILTYP],2 ; Flag BAT found + JMP COMSRCH ; Continue search + +PATHCHK: + TEST [FILTYP],1 + JZ TESTBAT + MOV WORD PTR [DIRBUF+9],5800H+"E" + MOV [DIRBUF+11],"E" + JMP EXECUTE ; Found EXE + +TESTBAT: + TEST [FILTYP],2 + JZ NEXTPATH ; Found nothing, try next path + MOV WORD PTR [DIRBUF+9],4100H+"B" + MOV [DIRBUF+11],"T" + MOV DX,OFFSET TRANGROUP:DIRBUF ; Found BAT + MOV AH,FCB_OPEN + INT int_command + OR AL,AL + JZ BATCOMJ ; Bat exists + CALL RESTUDIR + JMP BADCOM + +BATCOMJ: + JMP BATCOM + +NEXTPATH: + MOV DX,OFFSET TRANGROUP:USERDIR1 ; Restore users dir + MOV AH,CHDIR + INT int_command + MOV DS,[RESSEG] +ASSUME DS:RESGROUP + MOV [RESTDIR],0 +BADPATHEL: + MOV DI,OFFSET TRANGROUP:EXECPATH ; Build a full path here + MOV DX,SI + MOV DS,[ENVIRSEG] ; Point into environment +ASSUME DS:NOTHING + LODSB + + IF KANJI + MOV [KPARSE],0 + ENDIF + + OR AL,AL + JZ BADCOMJ ; NUL, command not found + XOR BL,BL ; Make BL a NUL +PSKIPLP: ; Get the path + STOSB + OR AL,AL + JZ LASTPATH + CMP AL,';' + JZ GOTNEXTPATH + CMP DI,15+DirStrLen+(OFFSET TRANGROUP:EXECPATH) + JB OKPath +SKIPPathElem: + LODSB ; scan to end of path element + OR AL,AL + JZ BadPathEl + CMP AL,';' + JZ BadPathEl + JMP SkipPathElem + +OKPath: + IF KANJI + MOV [KPARSE],0 + CALL TESTKANJ + JZ NXTPTCHR + INC [KPARSE] + MOVSB +NXTPTCHR: + ENDIF + + LODSB + JMP SHORT PSKIPLP + +BADCOMJ: + JMP BADCOM + +LASTPATH: + MOV BYTE PTR ES:[DI-1],';' ; Fix up the NUL in EXECPATH + DEC SI ; Point to the NUL in PATHSTRING + MOV BL,[SI-1] ; Change substi char to char before NUL + +GOTNEXTPATH: + DEC DI ; Point to the end of the dir + PUSH BX + PUSH SI + PUSH DX + MOV SI,DX + XOR DL,DL + CMP BYTE PTR [SI+1],DRVCHAR + JNZ DEFDRVPATH ; No drive spec + MOV DL,[SI] + SUB DL,'@' +DEFDRVPATH: + PUSH DS + PUSH CS + POP DS +ASSUME DS:TRANGROUP + MOV [IDLEN],DL ; New drive + PUSH DI + CALL SAVUDIR ; Save the users dir + POP DI + JNC PATHTRY + MOV DX,OFFSET TRANGROUP:BADPMES ; Tell the user bad stuff in path + CALL PRINT +PATHTRY: + POP DS +ASSUME DS:NOTHING + POP DX + POP SI + POP BX + XCHG BL,[SI-1] ; Stick in NUL, or same thing if LASTPATH +CDPATH: + MOV AH,CHDIR + INT int_command + MOV [SI-1],BL ; Fix the path string back up + MOV DS,[RESSEG] +ASSUME DS:RESGROUP + INC [RESTDIR] ; Say users dir needs restoring + JNC ResearchJ + JMP BADPATHEL ; Ignore a directory which doesn't exist +ResearchJ: + JMP RESEARCH ; Try looking in this one + +BATCOM: +ASSUME DS:TRANGROUP +; Batch parameters are read with ES set to segment of resident part + CALL IOSET ; Set up any redirection + MOV ES,[RESSEG] +ASSUME ES:RESGROUP +;Since BATCH has lower precedence than PIPE or FOR. If a new BATCH file +;is being started it MUST be true that no FOR or PIPE is currently in +;progress. + MOV [FORFLAG],0 ; Turn off for processing + MOV [PIPEFLAG],0 ; Turn off any pipe + TEST [BATCH],-1 + JNZ CHAINBAT ; Don't need allocation if chaining + CALL FREE_TPA +ASSUME ES:RESGROUP + MOV BX,6 ; 64 + 32 bytes + MOV AH,ALLOC + INT int_command ; Suck up a little piece for batch processing + MOV [BATCH],AX + CALL ALLOC_TPA +CHAINBAT: + PUSH ES + MOV ES,[BATCH] +ASSUME ES:NOTHING + MOV DL,[DIRBUF] + XOR DI,DI + CALL SAVUDIR1 ; ES:DI set up, get dir containing Batch file + XOR AX,AX + MOV CX,AX + DEC CX + REPNZ SCASB ; Find the NUL + DEC DI ; Point at the NUL + MOV AL,[DIRCHAR] + CMP AL,ES:[DI-1] + JZ NOPUTSLASH + STOSB +NOPUTSLASH: + MOV SI,OFFSET TRANGROUP:DIRBUF+1 + CALL FCB_TO_ASCZ ; Tack on batch file name + MOV AX,-1 + MOV BX,DI + MOV CX,10 + REP STOSW ; Init Parmtab to no parms + POP ES +ASSUME ES:RESGROUP + CALL RESTUDIR + MOV SI,OFFSET TRANGROUP:COMBUF+2 + MOV DI,OFFSET RESGROUP:PARMBUF + MOV CX,10 +EACHPARM: + CALL SCANOFF + CMP AL,0DH + JZ HAVPARM + JCXZ MOVPARM ; Only first 10 parms get pointers + PUSH ES + MOV ES,[BATCH] + MOV ES:[BX],DI ; Set pointer table to point to actual parameter + POP ES + INC BX + INC BX +MOVPARM: + LODSB + CALL DELIM + JZ ENDPARM ; Check for end of parameter + STOSB + CMP AL,0DH + JZ HAVPARM + JMP SHORT MOVPARM +ENDPARM: + MOV AL,0DH + STOSB ; End-of-parameter marker + JCXZ EACHPARM + DEC CX + JMP SHORT EACHPARM +HAVPARM: + XOR AL,AL + STOSB ; Nul terminate the parms + XOR AX,AX + PUSH ES + POP DS ; Simply batch FCB setup +ASSUME DS:RESGROUP + MOV WORD PTR [BATLOC],AX ; Start at beginning of file + MOV WORD PTR [BATLOC+2],AX + CMP [SINGLECOM],-1 + JNZ NOBATSING + MOV [SINGLECOM],0FFF0H ; Flag single command BATCH job +NOBATSING: + JMP TCOMMAND +ASSUME DS:TRANGROUP,ES:TRANGROUP + +EXECUTE: + CALL RESTUDIR +NeoExecute: + CMP BYTE PTR [DI],0 ; Command in current directory + JZ NNSLSH + MOV AL,[DI-1] + + IF KANJI + CMP [KPARSE],0 + JNZ StuffPath ; Last char is second KANJI byte, might be '\' + ENDIF + + CALL PATHCHRCMP + JZ HAVEXP ; Don't double slash +StuffPath: + MOV AL,[DIRCHAR] + STOSB + JMP SHORT HAVEXP + +NNSLSH: + MOV AL,[DIRBUF] ; Specify a drive + ADD AL,'@' + STOSB + MOV AL,DRVCHAR + STOSB +HAVEXP: + MOV SI,OFFSET TRANGROUP:DIRBUF+1 + CALL FCB_TO_ASCZ ; Tack on the filename + CALL IOSET + MOV ES,[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 + REP MOVSW ; Transfer parameters to resident header + MOV DX,OFFSET TRANGROUP:EXECPATH + MOV BX,OFFSET RESGROUP:EXEC_BLOCK + MOV AX,EXEC SHL 8 + JMP [EXEC_ADDR] ; Jmp to the EXEC in the resident + +BADCOM: + PUSH CS + POP DS + MOV DX,OFFSET TRANGROUP:BADNAM +CERROR: + CALL ERROR_PRINT + JMP TCOMMAND + +SINGLETEST: +ASSUME DS:RESGROUP + CMP [SINGLECOM],0 + JZ RET5 + CMP [SINGLECOM],0EFFFH + return + + +ASSUME DS:TRANGROUP +SETREST1: + MOV AL,1 +SETREST: + PUSH DS + MOV DS,[RESSEG] +ASSUME DS:RESGROUP + MOV [RESTDIR],AL + POP DS +ASSUME DS:TRANGROUP +RET5: + return + +CHKCNT: + TEST [FILECNT],-1 + JNZ ENDDIR +NOTFNDERR: + MOV DX,OFFSET TRANGROUP:NOTFND + JMP CERROR + +ENDDIR: +; Make sure last line ends with CR/LF + MOV AL,[LINLEN] + CMP AL,[LINCNT] ; Will be equal if just had CR/LF + JZ MESSAGE + CALL CRLF2 +MESSAGE: + MOV DX,OFFSET TRANGROUP:DIRMES_PRE + CALL PRINT + MOV SI,[FILECNT] + XOR DI,DI + CALL DISP32BITS + MOV DX,OFFSET TRANGROUP:DIRMES_POST + CALL PRINT + MOV AH,GET_DRIVE_FREESPACE + MOV DL,BYTE PTR DS:[FCB] + INT int_command + CMP AX,-1 + retz + MOV DX,OFFSET TRANGROUP:BYTMES_PRE + CALL PRINT + MUL CX ; AX is bytes per cluster + MUL BX + MOV DI,DX + MOV SI,AX + CALL DISP32BITS + MOV DX,OFFSET TRANGROUP:BYTMES_POST + JMP PRINT + +ASSUME DS:RESGROUP + +PIPEDEL: + PUSH DX + MOV DX,OFFSET RESGROUP:PIPE1 ; Clean up in case ^C + MOV AH,UNLINK + INT int_command + MOV DX,OFFSET RESGROUP:PIPE2 + MOV AH,UNLINK + INT int_command + XOR AX,AX + MOV WORD PTR [PIPEFLAG],AX ; Pipe files and pipe gone + MOV [ECHOFLAG],1 ; Make sure ^C to pipe doesn't leave ECHO OFF + POP DX + return + +PIPEERRSYN: + MOV DX,OFFSET TRANGROUP:SYNTMES + JMP SHORT PIPPERR +PIPEERR: + MOV DX,OFFSET TRANGROUP:PIPEEMES +PIPPERR: + CALL PIPEDEL + PUSH CS + POP DS + JMP CERROR + +PIPEPROCSTRT: +ASSUME DS:TRANGROUP,ES:TRANGROUP + MOV DS,[RESSEG] +ASSUME DS:RESGROUP + INC [PIPEFILES] ; Flag that the pipe files exist + MOV AH,19H ; Get current drive + INT int_command + ADD AL,'A' + MOV [PIPE2],AL ; Make pipe files in root of def drv + MOV BX,OFFSET RESGROUP:PIPE1 + MOV [BX],AL + MOV DX,BX + XOR CX,CX + MOV AH,CREAT + INT int_command + JC PIPEERR ; Couldn't create + MOV BX,AX + MOV AH,CLOSE ; Don't proliferate handles + INT int_command + MOV DX,OFFSET RESGROUP:PIPE2 + MOV AH,CREAT + INT int_command + JC PIPEERR + MOV BX,AX + MOV AH,CLOSE + INT int_command + CALL TESTDOREIN ; Set up a redirection if specified + MOV [ECHOFLAG],0 ; No echo on pipes + MOV SI,[PIPEPTR] + CMP [SINGLECOM],-1 + JNZ NOSINGP + MOV [SINGLECOM],0F000H ; Flag single command pipe +NOSINGP: + JMP SHORT FIRSTPIPE + +PIPEPROC: +ASSUME DS:RESGROUP + MOV [ECHOFLAG],0 ; No echo on pipes + MOV SI,[PIPEPTR] + LODSB + CMP AL,'|' + JNZ PIPEEND ; Pipe done + MOV DX,[INPIPEPTR] ; Get the input file name + MOV AX,(OPEN SHL 8) + INT int_command +PIPEERRJ: + JC PIPEERR ; Lost the pipe file + MOV BX,AX + MOV AL,0FFH + XCHG AL,[BX.PDB_JFN_Table] + MOV DS:[PDB_JFN_Table],AL ; Redirect +FIRSTPIPE: + MOV DI,OFFSET TRANGROUP:COMBUF + 2 + XOR CX,CX + CMP BYTE PTR [SI],0DH ; '|' + JNZ PIPEOK1 +PIPEERRSYNJ: + JMP PIPEERRSYN +PIPEOK1: + CMP BYTE PTR [SI],'|' ; '||' + JZ PIPEERRSYNJ +PIPECOMLP: + LODSB + STOSB + + IF KANJI + CALL TESTKANJ + JZ NOTKANJ5 + MOVSB + JMP PIPECOMLP + +NOTKANJ5: + ENDIF + + CMP AL,0DH + JZ LASTPIPE + INC CX + CMP AL,'|' + JNZ PIPECOMLP + MOV BYTE PTR ES:[DI-1],0DH + DEC CX + MOV [COMBUF+1],CL + DEC SI + MOV [PIPEPTR],SI ; On to next pipe element + MOV DX,[OUTPIPEPTR] + PUSH CX + XOR CX,CX + MOV AX,(CREAT SHL 8) + INT int_command + POP CX + JC PIPEERRJ ; Lost the file + MOV BX,AX + MOV AL,0FFH + XCHG AL,[BX.PDB_JFN_Table] + MOV DS:[PDB_JFN_Table+1],AL + XCHG DX,[INPIPEPTR] ; Swap for next element of pipe + MOV [OUTPIPEPTR],DX + JMP SHORT PIPECOM + +LASTPIPE: + MOV [COMBUF+1],CL + DEC SI + MOV [PIPEPTR],SI ; Point at the CR (anything not '|' will do) + CALL TESTDOREOUT ; Set up the redirection if specified +PIPECOM: + PUSH CS + POP DS + JMP NOPIPEPROC ; Process the pipe element + +PIPEEND: + CALL PIPEDEL + CMP [SINGLECOM],0F000H + JNZ NOSINGP2 + MOV [SINGLECOM],-1 ; Make it return +NOSINGP2: + JMP TCOMMAND + +TRANCODE ENDS + END + \ No newline at end of file -- cgit v1.2.3