home *** CD-ROM | disk | FTP | other *** search
- public comnd, cmcfrm, prserr, repars, cmgtch, drives, comand, fcbcpy
- include msdefs.h
-
- datas segment public 'datas'
- extrn flags:byte, trans:byte, fcb:byte, buff:byte
- extrn taklev:byte, takadr:word, dosnum:byte
-
- comand cmdinfo <>
- cmer00 db cr,lf,'?Program error Invalid COMND call$'
- cmer01 db cr,lf,'?Ambiguous$'
- cmer02 db cr,lf,'?Illegal input file spec$'
- cmer03 db cr,lf,'?Invalid command$' ; [19e]
- cmer04 db cr,lf,'?Invalid command or operand$' ; [1]
- cmer06 db cr,lf,'?Wildcard not allowed$' ; [21a]
- cmer07 db cr,lf,'?Invalid drive specificaton$' ; [21a]
- cmin00 db ' Confirm with carriage return$'
- cmin01 db ' One of the following:',cr,lf,'$'
-
- cmthlp dw 0 ; Text of help message for random input.
- drives db 0 ; How many drives we have. [21a]
- crlf db cr,lf,'$'
- ctcmsg db '^C$'
- prsp db ' $' ; Print a space.
- hlpmsg dw 0 ; Address of help message.
- spchar db 24H,26H,23H,40H,21H,25H,27H,28H,29H,2DH
- db 3CH,3EH,7BH,7DH,5FH,5CH,5EH,7EH,7CH,60H
- spclen equ $-spchar
- spchar2 db 24H,26H,23H,40H,21H,25H,27H,28H,29H,2DH
- db 7BH,7DH,5FH,5EH,7EH,60H
- spc2len equ $-spchar2
- escspc db 10O,' ',10O,'$' ; Clear escape.
- clrspc db ' ',10O,'$' ; Clear space.
- filbuf db 60H DUP(?) ; Character buffer.
- tbuff db 80 DUP(?)
- cmdstk dw ?
- datas ends
-
- code segment public
- extrn dodel:near, ctlu:near, cmblnk:near, locate:near, takrd:near
- extrn clearl:near
- assume cs:code,ds:datas,es:datas
-
- ; This routine parses the specified function in AH. Any additional
- ; information is in DX and BX.
- ; Returns +1 on success
- ; +4 on failure (assumes a JMP follows the call)
-
- CMND PROC NEAR
- comnd: mov comand.cmstat,ah ; Save what we are presently parsing.
- mov cmdstk,sp ; save stack ptr locally.
- call cminbf ; Get chars until an action or a erase char.
- mov ah,comand.cmstat ; Restore 'ah' for upcoming checks.
- cmp ah,cmcfm ; Parse a confirm?
- jz cmcfrm ; Go get one.
- cmp ah,cmkey ; Parse a keyword?
- jnz cm1
- jmp cmkeyw ; Try and get one.
- cm1: cmp ah,cmifi ; Parse an input file spec?
- jnz cm2
- jmp cmifil ; Go get one.
- cm2: cmp ah,cmofi ; Output file spec?
- jnz cm3
- jmp cmofil ; Go get one.
- cm3: cmp ah,cmtxt ; Parse arbitrary text. [8]
- jnz cm4
- jmp cmtext
- cm4: mov ah,prstr ; Else give error.
- mov dx,offset cmer00 ; "?Unrecognized COMND call"
- int dos
- ret
-
- ; This routine gets a confirm.
-
- cmcfrm: call cmgtch ; Get a char.
- cmp ah,0 ; Is it negative (a terminator; a space or
- ; a tab will not be returned here as they
- ; will be seen as leading white space.)
- js cmcfr0
- ret ; If not, return failure.
- cmcfr0: and ah,7FH ; Turn off the minus bit.
- cmp ah,esc ; Is it an escape?
- jne cmcfr2
- mov ah,conout
- mov dl,bell ; Get a bell.
- int dos
- mov ah,0
- mov comand.cmaflg,ah ; Turn off the action flag.
- mov bx,comand.cmcptr ; Move the pointer to before thee scape.
- dec bx
- mov comand.cmcptr,bx
- mov comand.cmdptr,bx
- dec comand.cmccnt ; Decremrnt the char count.
- jmp cmcfrm ; Try again.
- cmcfr2: cmp ah,'?' ; Curious?
- jne cmcfr3
- mov ah,prstr ; Print something useful.
- mov dx,offset cmin00
- int dos
- mov ah,prstr
- mov dx,offset crlf ; Print a crlf.
- int dos
- mov ah,prstr
- mov dx,comand.cmprmp ; Reprint the prompt.
- int dos
- mov bx,comand.cmdptr ; Get the pointer into the buffer.
- mov ah,'$' ; Put a $ there for printing.
- mov [bx],ah
- mov bx,comand.cmcptr
- dec bx ; Decrement & save the buffer pointer.
- mov comand.cmcptr,bx
- mov ah,prstr
- mov dx,offset comand.cmdbuf
- int dos
- mov ah,0 ; Turn off the action flag.
- mov comand.cmaflg,ah
- jmp repars ; Reparse everything.
-
- cmcfr3: cmp ah,ff ; Is it a form feed?
- jne cmcfr4
- call cmblnk ; If so blank the screen.
- cmcfr4: jmp rskp
-
- ; This routine parses a keyword from the table pointed
- ; to in DX. The format of the table is as follows:
- ;
- ; addr: db n ; Where n is the # of entries in the table.
- ; db m ; M is the size of the keyword.
- ; db 'string$' ; Where string is the keyword.
- ; dw ab ; Where ab is data to be returned.
- ;
- ; The keywords must be in alphabetical order.
-
-
- cmkeyw: mov comand.cmhlp,bx ; Save the help.
- mov comand.cmptab,dx ; Save the beginning of keyword table.
- mov bx,dx
- mov ch,[bx] ; Get number of entries in table.
- inc bx
- mov dx,comand.cmdptr ; Save command pointer.
- mov comand.cmsptr,dx ; Save pointer's here.
- cmky1: cmp ch,0 ; Any commands left to check?
- jne cmky2
- jmp cmky41 ; no, go complain
- cmky2: dec ch
- mov cl,0 ; Keep track of how many chars read in so far.
- call cmgtch ; Get a char.
- cmp ah,0 ; Do we have a terminator?
- jns cmky2x
- jmp cmky4 ; Negative number means we do.
- cmky2x: inc bx ; Point to first letter of keyword.
- inc cl ; Read in another char.
- mov al,[bx]
- cmp ah,'a' ; Less than a?
- jl cmky21 ; If so, don't capitalize.
- cmp ah,'z'+1 ; More than z?
- jns cmky21
- and ah,137O ; Capitalize the letter.
- cmky21: cmp ah,al
- je cmky3
- jg cmky2y
- jmp cmky41 ; Fail if ah preceeds al alphabetically.
- cmky2y: jmp cmky6 ; Not this keyword - try the next.
- cmky3: inc bx ; We match here, how 'bout next char?
- mov al,[bx]
- cmp al,'$' ; End of keyword?
- jne cmky3x
- jmp cmky7 ; Succeed.
- cmky3x: mov dl,al ; Save al's char here.
- call cmgtch
- inc cl ; Read in another char.
- mov al,dl
- cmp ah,'a'
- jl cmky31
- cmp ah,'z'+1
- jns cmky31
- and ah,137O
- cmky31: cmp ah,esc+80H ; Escape Recognition (escape w/minus bit on)?
- je cmky3y
- cmp ah,'?'+80H ; A question mark? [3]
- je cmky3y
- cmp ah,' '+80H ; A space?
- je cmky3y
- cmp ah,cr+80H ; Carriage return?
- je cmky3y
- jmp cmky38
- cmky3y: mov comand.cmkptr,bx ; Save bx here.
- mov comand.cmsiz,cx ; Save size info.
- mov comand.cmchr,ah ; Save char for latter.
- call cmambg ; See if input is ambiguous or not.
- jmp cmky32 ; Succeeded (not ambiguous).
- mov ah,comand.cmchr
- cmp ah,esc+80H ; Escape?
- je cmky3z
- cmp ah,'?'+80H ; maybe question mark?
- je cmkyj1 ; yes, go handle
- jmp cmky41 ; Else fail.
- cmky3z: mov ah,conout ; Ring a bell.
- mov dl,bell
- int dos
- mov bx,comand.cmcptr ; Move pointer to before the escape.
- dec bx
- mov comand.cmcptr,bx
- mov comand.cmdptr,bx
- dec comand.cmccnt ; Decrement char count.
- mov bx,comand.cmkptr ; Failed - pretend user never typed ....
- mov cx,comand.cmsiz ; ... in a char.
- dec cl ; Don't count the escape.
- dec bx
- mov comand.cmaflg,0 ; Reset the action flag.
- jmp cmky3 ; Keep checking.
- ; ambiguous. Print out all the keywords that match
- cmkyj1: mov dx,offset cmin01
- mov ah,prstr
- int dos
- mov bx,comand.cmkptr ; this is current keyword
- mov cx,comand.cmsiz ; we are cl chars into it
- mov ch,0
- sub bx,cx ; back up to beginning
- inc bx ; not counting ?
- mov comand.cmkptr,bx ; save beginning of kw
- cmkyj2: mov dl,tab ; put a tab before each keyword
- mov ah,conout
- int dos
- mov dx,comand.cmkptr ; get current keyword
- mov ah,prstr
- int dos ; print it
- mov bx,comand.cmkptr ; get keyword back
- dec bx
- mov al,[bx] ; get length
- mov ah,0
- add ax,5 ; skip length, $, value, next length
- add bx,ax ; this is next keyword
- mov si,bx
- mov di,comand.cmkptr ; compare with last keyword
- mov comand.cmkptr,bx ; update this
- mov cx,comand.cmsiz
- dec ch ; are we at end of table?
- jl cmkyj3 ; yes, don't go on
- mov comand.cmsiz,cx ; else update count
- mov ch,0
- dec cl ; this includes ?
- jcxz cmkyj2 ; empty, just print it
- repe cmpsb ; compare to previous string
- je cmkyj2 ; same, go print this one
- cmkyj3: jmp cmky50 ; else go finish up
-
- cmky32: mov cx,comand.cmsiz ; Restore info.
- mov bx,comand.cmkptr ; Our place in the keyword table.
- cmp comand.cmchr,0A0H ; Space?
- je cmky35
- cmp comand.cmchr,0BFH ; Question mark? [3]
- je cmky35
- cmp comand.cmchr,8DH ; Carriage return?
- je cmky35
- dec comand.cmcptr ; Pointer into buffer of input.
- mov dx,comand.cmcptr
- cmky33: mov ah,[bx] ; Get next char in keyword.
- cmp ah,'$' ; Are we done yet?
- jz cmky34
- mov di,dx
- mov [di],ah
- inc bx
- inc dx
- inc comand.cmccnt
- jmp cmky33
- cmky34: mov ah,' '
- mov di,dx
- mov [di],ah ; Put a blank in the buffer.
- inc dx
- mov cx,comand.cmcptr ; Remember where we were.
- mov comand.cmcptr,dx ; Update our pointers.
- mov comand.cmdptr,dx
- mov ah,'$'
- mov di,dx
- mov [di],ah ; Add '$' for printing.
- mov ah,prstr
- mov dx,cx ; Point to beginning of filled in data.
- int dos
- inc bx ; Point to address we'll need.
- mov bx,[bx]
- mov comand.cmaflg,0 ; Turn off action flag.
- jmp rskp
-
- cmky35: inc bx
- mov ah,[bx] ; Find end of keyword.
- cmp ah,'$'
- jne cmky35
- inc bx
- mov bx,[bx] ; Address of next routine to call.
- ; mov comand.cmaflg,0 ; Zero the action flag.
- jmp rskp
-
- cmky38: cmp ah,al
- je cmky39
- jmp cmky6 ; Go to end of keyword and try next.
- cmky39: jmp cmky3 ; Check next letter.
-
- cmky4: and ah,7FH ; Turn off minus bit.
- cmp ah,'?' ; Need help?
- je cmky5
- cmp ah,' ' ; Just a space - no error.
- je cmky51
- cmp ah,cr
- je cmky51
- cmp ah,tab
- je cmky51
- cmp ah,esc ; Ignore escape?
- je cmky43
- cmky41: mov ah,prstr
- mov dx,offset cmer03
- int dos
- jmp prserr ; Parse error - give up.
-
- cmky43: mov ah,conout ; Ring a bell.
- mov dl,bell
- int dos
- dec comand.cmcptr ;[ESC] don't trash BX here.
- dec comand.cmdptr ;[ESC] ditto
- dec comand.cmccnt ; Don't count the escape.
- mov comand.cmaflg,0 ; Reset action flag.
- inc ch ; Account for a previous 'dec'.
- jmp cmky1 ; Start over.
-
- cmky5: inc bx ; point to actual keyword
- mov comand.cmkptr,bx ; remember current kw
- mov cl,1 ; code above expects to count ?
- mov comand.cmsiz,cx ; and size
- mov dx,comand.cmhlp
- or dx,dx ; was any help given?
- jnz cmky5a ; yes, use it
- jmp cmkyj1 ; else make our own message
- cmky5a: mov ah,prstr
- int dos
- cmky50: mov ah,prstr
- mov dx,offset crlf
- int dos
- mov dx,comand.cmprmp ; Address of prompt.
- int dos
- mov bx,comand.cmdptr ; Get pointer into buffer.
- mov al,'$'
- mov [bx],al ; Add dollar sign for printing.
- mov dx,offset comand.cmdbuf
- int dos
- dec comand.cmcptr ; Don't keep it in the buffer.
- dec comand.cmccnt ; Don't conut it.
- mov comand.cmaflg,0 ; Turn off the action flag.
- jmp repars
-
- cmky51: cmp comand.cmcr,1 ; Are bare CR's allowed?
- je cmky52 ; Yes.
- mov ah,prstr
- mov dx,offset cmer04 ; Complain.
- int dos
- cmky52: jmp prserr
-
- cmky6: inc bx ; Find end of keyword.
- mov al,[bx]
- cmp al,'$'
- jne cmky6
- inc bx ; Beginning of next command.
- inc bx
- inc bx
- mov dx,comand.cmsptr ; Get old cmdptr.
- mov comand.cmdptr,dx ; Restore.
- mov comand.cmsflg,0FFH
- jmp cmky1 ; Keep trying.
-
- cmky7: call cmgtch ; Get char.
- cmp ah,0
- js cmky71 ; Ok if a terminator.
- dec bx
- jmp cmky6 ; No match - try next keyword.
- cmky71: inc bx ; Get necessary data.
- mov bx,[bx]
- cmp ah,9BH ; An escape?
- jne cmky72
- mov ah,prstr
- mov dx,offset prsp ; Print a space.
- int dos
- mov di,comand.cmcptr
- dec di
- mov ah,20H
- mov [di],ah ; Replace escape char with space.
- mov comand.cmaflg,0
- mov comand.cmsflg,0FFH ; Pretend they typed a space.
- cmky72: jmp rskp
-
- ; See if keyword is unambiguous or not from what the user has typed in.
-
- cmambg: cmp ch,0 ; Any keywords left to check?
- jne cmamb0
- ret ; If not then not ambiguous.
- cmamb0: inc bx ; Go to end of keyword ...
- mov al,[bx] ; So we can check the next one.
- cmp al,'$'
- jne cmamb0
- add bx,4 ; Point to start of next keyword.
- dec cl ; Don't count escape.
- mov dx,comand.cmsptr ; Buffer with input typed by user.
- cmamb1: mov ah,[bx] ; Keyword char.
- mov di,dx
- mov al,[di] ; Input char.
- cmp al,'a' ; Do capitalizing.
- jl cmam11
- cmp al,'z'+1
- jns cmam11
- and al,137O
- cmam11: cmp ah,al ; Keyword bigger than input (alphabetically)?
- jle cmamb2 ; No - keep checking.
- ret ; Yes - not ambiguous.
- cmamb2: inc bx ; Advance one char.
- inc dx
- dec cl
- jnz cmamb1
- jmp rskp ; Fail - it's ambiguous.
-
- cmifil: mov hlpmsg,bx ; Address of help message.
- mov bx,dx ; Get the fcb address in bx.
- mov comand.cmfcb,bx ; Save it.
- mov ch,0 ; Initialize char count.
- mov ah,0
- mov [bx],ah ; Set the drive to default to current.
- inc bx
- mov comand.cmfcb2,bx
- mov cl,' '
- cmifi0: mov [bx],cl ; Blank the FCB.
- inc bx
- inc ah
- cmp ah,0BH ; Twelve?
- jl cmifi0
- cmifi1: call cmgtch ; Get another char.
- cmp ah,0 ; Is it an action character.
- js cmif1x ; Jump out of range. [21a]
- jmp cmifi2 ; Ditto. [21a]
- cmif1x: and ah,7FH ; Turn off the action bit. [21a]
- cmp ah,'?' ; A question mark?
- jne cmif12
- mov al,0
- mov comand.cmaflg,al ; Blank the action flag.
- dec comand.cmcptr ; Decrement the buffer pointer.
- dec comand.cmccnt ; Decrement count.
- mov ah,prstr
- mov dx,hlpmsg ; Help message.
- int dos
- mov dx,offset crlf
- int dos
- mov dx,comand.cmprmp
- int dos
- mov bx,comand.cmdptr
- mov al,'$'
- mov [bx],al ; Put in dollar sign for printing.
- mov dx,offset comand.cmdbuf
- int dos
- jmp repars
- cmif12: cmp ah,esc ; An escape?
- je cm12x
- jmp cmif13
- cm12x: mov comand.cmaflg,0 ; Turn off the action flag.
- dec comand.cmcptr ; Move pointers to before the escape.
- dec comand.cmdptr
- dec comand.cmccnt ; Decrement char count.
- mov comand.cmchr,ch ; Save current character count.
- cmp ch,9 ; Past '.'?
- jl cmf120 ; No.
- dec ch ; Yes, don't count point.
- cmf120: mov di,comand.cmfcb2 ; Fill the rest with CP/M wildcards.
- mov ah,'?'
-
- cmf121: cmp ch,11 ; Done?
- jge cmf122 ; Yes.
- mov [di],ah
- inc di
- inc ch
- jmp cmf121
-
- cmf122: mov ah,sfirst ; Find first matching file?
- mov dx,comand.cmfcb ;[jd] use pointer to PASSED fcb
- int dos
- cmp al,0FFH ; Any found?
- jne cmf123 ; Yes.
- jmp cmf12b ; No, lose.
- cmf123: mov di,offset filbuf ; Copy first file spec from DTA to buffer.
- mov bx,offset buff+1
- mov cl,11
- call fcbcpy
- mov di,offset filbuf+10H ; Get another copy (if not ambiguous).
- mov bx,offset buff+1
- mov cl,11
- call fcbcpy
- mov ah,snext ; More matching specs?
- mov dx,comand.cmfcb ;[jd] use PASSED fcb...
- int dos
- cmp al,0FFH
- je cmf124 ; Only one.
- mov di,offset filbuf+10H ; Copy second file spec.
- mov bx,offset buff+1
- mov cl,11
- call fcbcpy
-
- cmf124: mov si,offset filbuf ; Start comparing file names.
- mov bx,offset filbuf+10H
- mov di,comand.cmcptr ; Command buffer pointer
- mov cl,comand.cmchr ; Bypass characters typed.
- cmp cl,9 ; Past '.'?
- jl cmf125 ; No.
- dec cl ; Yes, don't count point.
- cmf125: mov ch,0 ; Adjust pointers.
- add si,cx
- add bx,cx
- mov ch,cl ; Update character count
-
- cmf126: cmp ch,11 ; All done?
- jne cmf127 ; No.
- jmp cmf12a ; Yes.
- cmf127: cmp ch,8 ; End of file name?
- jne cmf128 ; No.
- cmp comand.cmchr,9 ; Exactly at point?
- je cmf128 ; Yes, don't output a second point.
- mov ah,'.' ; Output separator.
- mov [di],ah
- inc di
- inc comand.cmccnt
- cmf128: mov ah,[si] ; Get a character from first file spec.
- inc si
- mov al,[bx] ; Get another from second spec.
- inc bx
- cmp ah,al ; Compare.
- jne cmf12a ; Ambiguous.
- inc ch ; Same, count.
- cmp ah,' ' ; Blank?
- je cmf129 ; Yes, don't output.
- mov [di],ah
- inc di
- inc comand.cmccnt
- cmf129: jmp cmf126 ; Repeat.
-
- cmf12a: mov comand.cmchr,ch ; Save count of characters processed.
- mov ah,'$' ; Put terminator into buffer.
- mov [di],ah
- mov comand.cmcptr,di ; Save pointer for recognized characters.
- mov ah,prstr
- mov dx,comand.cmdptr
- int dos
- mov ch,comand.cmchr ; Characters processed.
- cmp ch,11 ; Complete file name.
- je cmf12c ; Yes, don't beep.
-
- cmf12b: mov ah,conout ; Beep, if not recognized.
- mov dl,bell
- int dos ; Ring the bell.
- cmf12c: jmp repars
-
- cmif13: mov ah,ch ; It must be a terminator.
- cmp ah,0 ; Test the length of the file name.
- jnz cmf3x
- cmp comand.cmcr,1 ; Is zero length OK? [21a]
- je cmf3z ; Return successfully. [21a]
- jmp cmifi9 ; If zero complain.
- cmf3x: cmp ah,0DH
- js cmf3y
- jmp cmifi9 ; If too long complain.
- cmf3y: jmp rskp ; Otherwise we have succeeded.
- cmf3z: push es
- mov ax,ds
- mov es,ax
- mov di,comand.cmfcb
- inc di
- mov cx,11
- mov al,'?'
- repne stosb
- pop es
- mov flags.wldflg,0FFH ; Remember we had a wildcard.
- jmp rskp
- cmifi2: cmp ah,'.'
- jne cmifi3
- inc ch
- mov ah,ch
- cmp ah,1H ; Any chars yet?
- jnz cmf2x
- jmp cmifi9 ; No, give error.
- cmf2x: cmp ah,0AH ; Tenth char?
- js cmf2y
- jmp cmifi9 ; Past it, give an error.
- cmf2y: mov dl,9H
- mov dh,0
- mov bx,comand.cmfcb
- add bx,dx ; Point to file type field.
- mov comand.cmfcb2,bx
- mov ch,9H ; Say we've gotten nine.
- jmp cmifi1 ; Get the next char.
- cmifi3: cmp ah,':'
- jne cmifi4
- inc ch
- cmp ch,2H ; Is it in right place for a drive?
- je cmif3x
- jmp cmifi9 ; If not, complain.
- cmif3x: mov ch,0 ; Reset char count.
- mov flags.droflg,1 ; Override default drive. [21a]
- mov flags.nmoflg,0 ; Not so fast. [21a]
- mov bx,comand.cmfcb2
- mov al,':' ; Use for parsing drive name.
- mov [bx],al
- dec bx ; Point to drive spec.
- mov si,bx
- push es
- mov ax,ds
- mov es,ax
- mov di,offset tbuff ; Borrow this buffer.
- mov ah,prsfcb
- int dos
- pop es
- cmp al,0 ; OK return code?
- je cmif3y ; Yes, keep going.
- ; mov ah,[bx] ; Get the drive name.
- ; sub ah,'@' ; Get the drive number.
- ; cmp ah,drives ; Did user specify a non-existant drive? [21a]
- ; jle cmif3y ; Nope, so continue. [21a]
- mov dx,offset cmer07 ; Fail with this error message. [21a]
- jmp cmif9x ; [21a]
- cmif3y: mov comand.cmfcb2,bx ; Put rest of filename starting here. [21a]
- mov ah,[bx] ; Pick up drive specified.
- sub ah,'@' ; Get real value.
- mov bx,comand.cmfcb
- mov [bx],ah ; Put it in the fcb.
- push bx
- mov al,' ' ; Overwrite the drive and ":".
- inc bx
- mov [bx],al
- inc bx
- mov [bx],al
- pop bx
- jmp cmifi1
- cmifi4: cmp ah,'*'
- jne cmifi7
- cmp comand.cmrflg,1 ; In receive mode? [21a]
- jne cmif4x ; Jump out of range. [21a]
- mov dx,offset cmer06 ; Set the error message. [21a]
- jmp cmif9x ; Fail - no wildcard allowed. [21a]
- cmif4x: mov ah,ch ; [21a]
- cmp ah,8H ; Is this in the name or type field?
- jns cmifi5 ; Type.
- mov cl,8H ; Say we have eight chars.
- js cmifi6 ; Name field.
- jmp cmifi9 ; If its where the dot should be give up.
- cmifi5: mov cl,0CH ; Three chars.
- cmifi6: mov flags.wldflg,0FFH ; Remember we had a wildcard.
- mov bx,comand.cmfcb2 ; Get a pointer into the FCB.
- mov ah,'?'
- mov [bx],ah ; Put a question mark in.
- inc bx
- mov comand.cmfcb2,bx
- inc ch
- mov ah,ch
- cmp ah,cl
- jl cmifi6 ; Go fill in another.
- jmp cmifi1 ; Get the next char.
- cmifi7: cmp ah,03DH ; Equals sign (wildcard)?
- jne cmif7x
- cmp comand.cmrflg,1 ; In receive mode? [21a]
- jne cmif7y ; No, so it's ok. [21a]
- mov dx,offset cmer06 ; Set the error message. [21a]
- jmp cmif9x ; Fail - no wildcard allowed. [21a]
- cmif7y: mov ah,'?' ; New label. [21a]
- mov flags.wldflg,0FFH ; Say we have a wildcard.
- jmp cmifi8 ; Put into FCB.
- cmif7x: cmp ah,'0'
- jl cmif8x
- cmp ah,'z'+1
- jns cmif8x
- cmp ah,'A' ; Don't capitalize non-alphabetics.
- jl cmifi8
- and ah,137O ; Capitalize.
- cmifi8: mov bx,comand.cmfcb2 ; Get the pointer into the FCB.
- mov [bx],ah ; Put the char there.
- inc bx
- mov comand.cmfcb2,bx
- mov flags.nmoflg,1 ; Overriding name from host. [21a]
- inc ch
- jmp cmifi1
-
- cmif8x: push es
- mov cx,ds
- mov es,cx ; Scan uses ES register.
- mov di,offset spchar ; Special chars.
- mov cx,spclen ; How many of them.
- cmp dosnum,0 ; Under version 2.0
- je cmif8y
- mov di,offset spchar2
- mov cx,spc2len
- cmif8y: mov al,ah ; Char is in al.
- repnz scasb ; Search string for input char.
- cmp cx,0 ; Was it there?
- pop es
- jnz cmifi8
-
- cmifi9: mov dx,offset cmer02
- cmif9x: mov ah,prstr
- int dos
- mov flags.droflg,0 ; Not overriding drive. [21a]
- mov flags.nmoflg,0 ; Or name to save file under. [21a]
- mov comand.cmrflg,0 ; Reset this flag too. [21a]
- ret
-
- cmofil: jmp cmifil ; For now, the same as CMIFI.
-
- ; Parse arbitrary text up to a CR. Put chars into data buffer sent to
- ; the host (pointed to by BX). Called with text of help message in DX.
- ; Return updated pointer in BX and input size in AH.
-
- cmtext: mov comand.cmptab,bx ; Save pointer to data buffer. [8 start]
- mov cmthlp,dx ; Save the help message.
- mov cl,0 ; Init the char count.
- cmtxt1: mov comand.cmsflg,0 ; Get all spaces. [25]
- call cmgtch ; Get a char.
- test ah,80H ; is high-order bit on?
- jz cmtxt5 ; Nope, put into the buffer.
- and ah,07FH
- cmp ah,' '
- je cmtxt5
- cmp ah,esc ; An escape?
- jne cmtxt2
- mov ah,conout
- mov dl,bell ; Ring a bell.
- int dos
- mov comand.cmaflg,0 ; Reset action flag.
- dec comand.cmcptr ; Move pointer to before the escape.
- dec comand.cmdptr
- dec comand.cmccnt ; Decrement count.
- jmp cmtxt1 ; Try again.
- cmtxt2: cmp ah,'?' ; Asking a question?
- jz cmtx30
- cmp ah,ff ; Formfeed?
- jne cmtx2x
- call cmblnk
- cmtx2x: mov ah,cl ; Return count in AH.
- mov bx,comand.cmptab ; Return updated pointer.
- jmp rskp
- cmtx30: mov comand.cmaflg,0 ; Reset action flag to zero.
- inc comand.cmdptr ; count the ?
- cmp cl,0 ; Is "?" first char?
- jne cmtxt5 ; No, just add to buffer.
- dec comand.cmcptr ;[ESC] (moved 3 lines) Don't keep in buffer.
- dec comand.cmccnt ;[ESC] Don't conut it.
- dec comand.cmdptr ;[ESC] don't count if printing help.
- mov ah,prstr ; Else, give some help.
- mov dx,cmthlp ; Address of help message.
- int dos
- mov ah,prstr
- mov dx,offset crlf ; Print a crlf.
- int dos
- mov ah,prstr
- mov dx,comand.cmprmp ; Reprint the prompt.
- int dos
- mov bx,comand.cmdptr ; Get the pointer into the buffer.
- mov byte ptr [bx],'$'
- mov ah,prstr
- mov dx,offset comand.cmdbuf
- int dos
- jmp cmtxt1 ; And keep going.
- cmtxt5: inc cl ; Increment the count.
- mov bx,comand.cmptab ; Pointer into destination array.
- mov [bx],ah ; Put char into the buffer.
- inc bx
- mov comand.cmptab,bx
- jmp cmtxt1 ; [8 end]
-
- cmgetc: cmp taklev,0
- jne cmget1
- jmp cmge10 ; no take file, get from keyboard
- cmget1: push bx
- push si
- mov bx,takadr
- mov ax,[bx].takcnt
- or ax,[bx].takcnt+2
- jnz cmget5
- cmget2: mov al,byte ptr [bx].takfcb ; get first byte of fcb
- cmp al,0ffh ; is it really a macro?
- je cmget4 ; yes, better not try to close it
- cmp al,0feh ; or maybe a file handle?
- je cmget3 ; yes, close w/2.0 call
- mov ah,closf
- lea dx,[bx].takfcb
- int dos
- jmp short cmget4 ; skip over alternate close
- cmget3: mov bx,word ptr [bx].takfcb+1 ; this is where file handle is stored
- mov ah,close2 ; use 2.0 close
- int dos
- cmget4: dec taklev
- sub takadr,size takinfo
- pop si
- pop bx
- mov al,cr ; end with carriage return...
- ret
-
- cmget5: cmp [bx].takchl,0 ; Any chars left in buffer?
- jne cmget6
- call takrd
- cmget6: dec [bx].takchl
- sub [bx].takcnt,1 ; DEC doesn't set carry!!
- sbb [bx].takcnt+2,0
- mov si,[bx].takptr
- lodsb
- mov [bx].takptr,si
- cmp al,ctlz ; maybe control-z?
- je cmget2 ; yes, close take file (has to be before pops)
- pop si
- pop bx
- cmp al,lf ; linefeed?
- jne cmget7
- cmp flags.takflg,0
- je cmgetc ; yes, ignore it
- cmget7: cmp al,';' ; maybe a semicolon?
- je cmget9
- cmp flags.takflg,0 ; Echo contents of take file?
- je cmget8
- push dx
- mov dl,al
- mov ah,conout
- int dos
- pop dx
- cmget8: ret ; else just return...
- ; semicolon seen, ignore chars until cr
- cmget9: call cmgetc ; get a character?
- cmp al,cr ; carriage return?
- jne cmget9 ; no, keep reading
- ret ; else return it
-
- cmge10: mov ah,coninq ; Get a char.
- cmp flags.debug,0 ; in debug mode?
- je cmge11 ; yes, go on
- mov ah,8 ; else use read that recognizes ^C
- cmge11: int dos
- push ax ; save the char
- cmp al,bs ; backspace?
- je cmge13 ; yes, skip echo
- cmp al,' ' ; printable?
- jae cmge12 ; yes, no translation needed
- cmp al,cr ; this is printable
- je cmge12
- cmp al,lf
- je cmge12
- cmp al,tab
- je cmge12
- mov al,' ' ; else echo a space
- cmge12: mov dl,al ; put char here
- mov ah,conout
- int dos ; echo it ourselves...
- cmge13: pop ax ; and return it
- cmp al,'C'-40H ; control-C?
- je cmge15 ; yes, go handle
- cmp al,';' ; semicolon?
- je cmget9 ; yes, ignore rest of line...
- cmp al,tab
- jne cmge14
- mov al,' '
- cmge14: ret
- cmge15: mov dx,offset ctcmsg
- mov ah,prstr
- int dos
- mov flags.cxzflg,'C' ; remember ^C'd
- mov sp,cmdstk ; restore command stack ptr
- ret ; and fail
-
- ; Come here is user types ^W when during input.
- cntrlw: mov ah,prstr
- mov dx,offset escspc
- int dos
- dec comand.cmccnt ; Don't include it in the count.
- dec comand.cmcptr ; Back up past the ^W.
- mov cl,comand.cmccnt
- mov ch,0
- jcxz ctlw2
- pushf
- push es
- std ; Scan backwards.
- mov ax,ds
- mov es,ax ; Point to the data area.
- mov di,comand.cmcptr ; Looking from here.
- dec di
- mov al,' '
- repe scasb ; Look for non-space.
- je ctlw1 ; All spaces, nothing else to do
- inc di ; move back to non-space
- inc cx
- repne scasb ; look for a space
- jne ctlw1 ; no space, leave ptrs alone
- inc di
- inc cx ; skip back over space
- ctlw1: inc di
- mov comand.cmccnt,cl ; update count
- mov cx,comand.cmcptr ; remember old ptr
- mov comand.cmcptr,di ; update pointer
- sub cx,di ; this is characters moved
- mov al,bs ; backspace
- cld
- mov di,offset tbuff ; temporary buffer
- rep stosb ; put enough spaces in
- mov byte ptr [di],'$' ; end buffer
- mov dx,offset tbuff
- mov ah,prstr
- int dos ; back up cursor
- call clearl ; clear line
- pop es
- popf
- ret ; and return
- ctlw2: mov ah,conout
- mov dl,bell
- int dos
- ret
-
- cminbf: push dx
- push bx
- mov cx,dx ; Save value here too.
- mov ah,comand.cmaflg ; Is the action char flag set?
- cmp ah,0
- je cminb1
- jmp cminb9 ; If so get no more chars.
- cminb1: inc comand.cmccnt ; Increment the char count.
- call cmgetc
- mov ah,al ; Keep char in 'ah'.
- mov bx,comand.cmcptr ; Get the pointer into the buffer.
- mov [bx],ah ; Put it in the buffer.
- inc bx
- mov comand.cmcptr,bx
- cmp ah,'W'-64 ; Is it a ^W?
- jne cmnb11
- call cntrlw ; Kill the previous word.
- jmp repars
- cmnb11: cmp ah,25O ; Is it a ^U?
- jne cminb2
- cmnb12: call ctlu ; Clear out the line.
- mov ah,prstr
- mov dx,comand.cmprmp ; Print the prompt.
- int dos
- mov bx,offset comand.cmdbuf
- mov comand.cmcptr,bx ; Reset the point to the start.
- mov comand.cmccnt,0 ; Zero the count.
- mov dx,cx ; Preserve original value of dx.
- jmp repars ; Go start over.
- cminb2: cmp ah,bs ; Or backspace?
- jz cminb3
- cmp ah,del ; Delete?
- jne cminb4
- cminb3: call dodel ; Delete a character.
- mov ah,comand.cmccnt ; Decrement the char count by two.
- dec ah
- dec ah
- cmp ah,0 ; Have we gone too far?
- jns cmnb32 ; If not proceed.
- mov ah,conout ; Ring the bell.
- mov dl,bell
- int dos
- jmp cmnb12 ; Go reprint prompt and reparse.
- cmnb32: mov comand.cmccnt,ah ; Save the new char count.
- mov ah,prstr ; Erase the character.
- mov dx,offset clrspc
- int dos
- mov bx,comand.cmcptr ; Get the pointer into the buffer.
- dec bx ; Back up in the buffer.
- dec bx
- mov comand.cmcptr,bx
- jmp repars ; Go reparse everything.
- cminb4: cmp ah,'?' ; Is it a question mark.
- jz cminb6
- cmp ah,esc ; Is it an escape?
- jz cminb8
- cmp ah,cr ; Is it a carriage return?
- jz cminb5
- cmp ah,lf ; Is it a line feed?
- jz cminb5
- cmp ah,ff ; Is it a formfeed?
- jne cminb7
- call cmblnk
- call locate
- cminb5: mov ah,comand.cmccnt ; Have we parsed any chars yet?
- cmp ah,1
- jnz cminb6
- jmp prserr ; If not, just start over.
- cminb6: mov ah,0FFH ; Set the action flag.
- mov comand.cmaflg,ah
- jmp cminb9
- cminb7: jmp cminb1 ; Get another char.
-
- cminb8: mov ah,prstr ; Don't print the escape char.
- mov dx,offset escspc
- int dos
- jmp cminb6
-
- cminb9: pop bx
- pop dx
- ret
-
- cmgtch: push cx
- push bx
- push dx
- cmgtc1: mov ah,comand.cmaflg
- cmp ah,0 ; Is it set.
- jne cmgt10
- call cminbf ; If the action char flag is not set get more.
- cmgt10: mov bx,comand.cmdptr ; Get a pointer into the buffer.
- mov ah,[bx] ; Get the next char.
- inc bx
- mov comand.cmdptr,bx
- cmp ah,' ' ; Is it a space?
- jz cmgtc2
- cmp ah,tab ; Or a tab?
- jne cmgtc3
- cmgtc2: mov ah,comand.cmsflg ; Get the space flag.
- cmp ah,0 ; Was the last char a space?
- jne cmgtc1 ; Yes, get another char.
- mov ah,0FFH ; Set the space flag.
- mov comand.cmsflg,ah
- mov ah,' '
- pop dx
- pop bx
- jmp cmgtc5
- cmgtc3: mov al,0
- mov comand.cmsflg,al ; Zero the space flag.
- pop dx
- pop bx
- cmp ah,esc
- jz cmgtc5
- cmp ah,'?' ; Is the user curious?
- jz cmgtc4
- cmp ah,cr
- jz cmgtc4
- cmp ah,lf
- jz cmgtc4
- cmp ah,ff
- je cmgtc4
- pop cx
- ret ; Not an action char, just return.
- cmgtc4: dec comand.cmdptr
- cmgtc5: or ah,80H ; Make the char negative to indicate
- pop cx
- ret ; it is a terminator.
- CMND ENDP
-
- ; This address is jumped to on reparse.
-
- PARSE PROC NEAR
- repars: mov sp,comand.cmostp ; new sp <-- old sp
- mov bx,offset comand.cmdbuf
- mov comand.cmdptr,bx
- mov ah,0FFH
- mov comand.cmsflg,ah
- jmp comand.cmrprs ; go back to reparse address
-
- ; This address can be jumped to on a parsing error.
-
- prserr: mov sp,comand.cmostp ; Set new sp to old one.
- mov bx,offset comand.cmdbuf
- mov comand.cmcptr,bx ; Initialize the command pointer.
- mov comand.cmdptr,bx
- mov ah,0
- mov comand.cmaflg,ah ; Zero the flags.
- mov comand.cmccnt,ah
- mov comand.cmsflg,0FFH
- cmp taklev,0 ; in take cmd?
- jne prser1 ; yes, don't print prompt
- mov ah,prstr
- mov dx,offset crlf
- int dos
- mov ah,prstr ; Print the prompt.
- mov dx,comand.cmprmp ; Get the prompt.
- int dos
- ; Instead return to before the prompt call.
- prser1: jmp comand.cmrprs
- PARSE ENDP
-
- ; FCB must be remembered if found "*" in filename. [7 start]
- ; Copy from place addressed by BX to place addressed by DI.
- ; Also use to get the filename to the FCB from the DTA.
-
- FCBCPY PROC NEAR
- push es
- push si
- mov ax,ds
- mov es,ax ; make sure destination segment is correct
- mov ch,0 ; high-order part of length
- jcxz fcbcp1 ; zero argument (is this necessary???)
- mov si,bx ; this is source
- rep movsb ; copy the whole thing
- fcbcp1: pop si
- pop es
- ret ; and return
- FCBCPY ENDP
-
- ; Jumping to this location is like retskp. It assumes the instruction
- ; after the call is a jmp addr.
-
- RSKP PROC NEAR
- pop bp
- add bp,3
- push bp
- ret
- RSKP ENDP
-
- ; Jumping here is the same as a ret.
-
- R PROC NEAR
- ret
- R ENDP
-
- code ends
- end