home *** CD-ROM | disk | FTP | other *** search
/ Phoenix CD 2.0 / Phoenix_CD.cdr / 01e / msk230s1.zip / MSSCMD.ASM < prev    next >
Assembly Source File  |  1988-02-12  |  43KB  |  942 lines

  1.         NAME    msscmd
  2. ; File MSSCMD.ASM
  3. ; Edit history:
  4. ; Last edit 1 Jan 1988
  5. ; 1 Jan 1988 version 2.30
  6. ; 8 Oct 1987 Add syntax of "\;" is a literal semicolon and not a comment
  7. ;  introducer (; prints as space, \; prints as ;) but only when doing a
  8. ;  TAKE file or macro. [jrd]
  9. ; 28 Aug 1987 Show Kermit prompt when in Take file and echoing Take cmd. [jrd]
  10. ; 18 Aug 1987 Change ESC to escape, for MASM 4.5+ [jrd]
  11. ; 27 June 1987 Add allowance for bare c/r's (comand.cmcr != 0) in cminbf.
  12. ;  Add global byte "intake" to say if reading from Take file (non-zero). [jrd]
  13. ; 1 Oct 1986 Version 2.29a
  14. ; 20 August 1986 Protect against buffer overflow and stop deleting of prompt
  15. ; 16 August 1986 Remove unneeded buffer tbuff. [jrd]
  16. ; 22 May 1986 Echo tabs as just a space, avoids corrupted cmd line. [jrd]
  17. ; [2.29] code frozen on 6 May 1986 [jrd]
  18.  
  19.         public comnd, cmcfrm, prserr, repars, cmgtch, comand
  20.         public cmgetc, intake
  21.         include mssdef.h
  22.  
  23. datas   segment public 'datas'
  24.         extrn   flags:byte, trans:byte
  25.         extrn   taklev:byte, takadr:word, dosnum:byte
  26.  
  27. comand  cmdinfo <>
  28. cmer00  db      cr,lf,'?Program error   Invalid COMND call$'
  29. cmer03  db      cr,lf,'?Invalid command$'
  30. cmer04  db      cr,lf,'?Invalid command or operand$'
  31. cmin00  db      ' Confirm with carriage return$'
  32. cmin01  db      ' One of the following:',cr,lf,'$'
  33.  
  34. cmthlp  dw      0                       ; Text ptr to help message for cmds
  35. crlf    db      cr,lf,'$'
  36. ctcmsg  db      '^C$'
  37. prsp    db      ' $'                    ; Print a space.
  38. hlpmsg  dw      0                       ; Address of help message.
  39. escspc  db      BS,' ',BS,'$'           ; Clear escape.
  40. clrspc  db      ' ',BS,'$'              ; Clear space.
  41. temp    db      ?                       ; temp (counts char/line so far)
  42. cmdstk  dw      ?
  43. intake  db      ?                       ; last command line was from Take
  44. prevch  db      0                       ; previous char read by cmgetc
  45. noparse db      0                       ; semicolons not special, if non-zero
  46. datas   ends
  47.  
  48. code    segment public 'code'
  49.         extrn   dodel:near, ctlu:near, cmblnk:near, locate:near, takrd:near
  50.         extrn   clearl:near
  51.         assume  cs:code, ds:datas, es:datas
  52.  
  53. ;       This routine parses the specified function in AH. Any additional
  54. ;       information is in DX and BX.
  55. ;       Returns +1 on success
  56. ;               +4 on failure (assumes a JMP follows the call)
  57.  
  58. CMND    PROC NEAR
  59. comnd:  mov     comand.cmstat,ah        ; Save what we are presently parsing.
  60.         mov     cmdstk,sp               ; save stack ptr locally.
  61.         mov     prevch,0                ; clear old previous char
  62.         mov     noparse,0         ; say recognize semicolons in Take files
  63.         call    cminbf            ; Get chars until an action or a erase char
  64.         mov     ah,comand.cmstat        ; Restore 'ah' for upcoming checks.
  65.         cmp     ah,cmcfm                ; Parse a confirm?
  66.         jz      cmcfrm                  ; Go get one.
  67.         cmp     ah,cmkey                ; Parse a keyword?
  68.         jnz     cm3
  69.         jmp     cmkeyw                  ; Try and get one.
  70. cm3:    cmp     ah,cmtxt                ; Parse arbitrary text.
  71.         jnz     cm4
  72.         jmp     cmtext
  73. cm4:    cmp     ah,cmfile               ; parse text surrounded by whitespace
  74.         jnz     cm5
  75.         jmp     cmfil0
  76. cm5:    mov     ah,prstr                ; Else give error
  77.         mov     dx,offset cmer00        ; "?Unrecognized COMND call"
  78.         int     dos
  79.         ret
  80.  
  81. ; This  routine gets a confirm.
  82.  
  83. cmcfrm: call    cmgtch                  ; Get a char.
  84.         cmp     ah,0            ; Is it negative? (a terminator; a space or
  85.                                 ; a tab will not be returned here as they
  86.                                 ; will be seen as leading white space.)
  87.         js      cmcfr0
  88.         mov     comand.cmstat,cmcfm-1   ; make sure status isn't = cmcfm
  89.         ret                             ; If not, return failure.
  90. cmcfr0: and     ah,7FH                  ; Turn off the minus bit.
  91.         cmp     ah,escape               ; Is it an escape?
  92.         jne     cmcfr2
  93.         mov     ah,conout
  94.         mov     dl,bell                 ; Get a bell.
  95.         int     dos
  96.         mov     comand.cmaflg,0         ; Turn off the action flag.
  97.         mov     bx,comand.cmcptr        ; Move pointer to before the escape.
  98.         dec     bx
  99.         mov     comand.cmcptr,bx
  100.         mov     comand.cmdptr,bx
  101.         dec     comand.cmccnt           ; Decrement the char count.
  102.         jmp     cmcfrm                  ; Try again.
  103. cmcfr2: cmp     ah,'?'                  ; Curious?
  104.         jne     cmcfr3
  105.         mov     ah,prstr                ; Print something useful.
  106.         mov     dx,offset cmin00
  107.         int     dos
  108.         mov     dx,offset crlf          ; Print a crlf.
  109.         int     dos
  110.         mov     dx,comand.cmprmp        ; Reprint the prompt.
  111.         int     dos
  112.         mov     bx,comand.cmdptr        ; Get the pointer into the buffer.
  113.         mov     byte ptr[bx],'$'        ; Put a $ there for printing.
  114.         dec     comand.cmcptr           ; Decrement & save the buffer pointer
  115.         mov     dx,offset comand.cmdbuf
  116.         int     dos
  117.         mov     comand.cmaflg,0         ; Turn off the action flag.
  118.         jmp     repars                  ; Reparse everything.
  119.  
  120. cmcfr3: cmp     ah,ff                   ; Is it a form feed?
  121.         jne     cmcfr4
  122.         call    cmblnk                  ; If so blank the screen.
  123. cmcfr4: jmp     rskp
  124.  
  125. ;       This routine parses a keyword from the table pointed
  126. ;       to in DX.  The format of the table is as follows:
  127. ;
  128. ;       addr:   db      n         ; Where n is the # of entries in the table.
  129. ;               db      m         ; M is the size of the keyword.
  130. ;               db      'string$' ; Where string is the keyword.
  131. ;               dw      ab        ; Where ab is data to be returned.
  132. ;
  133. ;       The keywords must be in alphabetical order,
  134. ;       but they may be of mixed case. [jrd]
  135.  
  136. cmkeyw: mov     comand.cmhlp,bx         ; Save the help.
  137.         mov     comand.cmptab,dx        ; Save the beginning of keyword table
  138.         mov     bx,dx
  139.         mov     ch,[bx]                 ; Get number of entries in table.
  140.         inc     bx
  141.         mov     dx,comand.cmdptr        ; Save command pointer.
  142.         mov     comand.cmsptr,dx        ; Save pointer's here.
  143. cmky1:  cmp     ch,0                    ; Any commands left to check?
  144.         jne     cmky2
  145.         jmp     cmky41                  ; no, go complain
  146. cmky2:  dec     ch
  147.         mov     cl,0            ; Keep track of how many chars read in so far
  148.         call    cmgtch                  ; Get a char from the user
  149.         cmp     ah,0                    ; Do we have a terminator?
  150.         jns     cmky2x                  ; ns = no
  151.         jmp     cmky4                   ; Negative number means we do.
  152. cmky2x: inc     bx                      ; Point to first letter of keyword.
  153.         inc     cl                      ; count the user's char
  154.         mov     al,[bx]
  155.         call    tolowr                  ; convert al (key) and ah (user)
  156.         cmp     ah,al                   ; do they match?
  157.         je      cmky3                   ; e = yes
  158.         jg      cmky2y                  ; g = keychar < user's (keep looking)
  159.         jmp     cmky41                ; Fail if ah preceeds al alphabetically
  160. cmky2y: jmp     cmky6                   ; Not this keyword - try the next.
  161. cmky3:  inc     bx                      ; We match here, how 'bout next char?
  162.         mov     al,[bx]
  163.         call    tolowr                  ; lower case the key word char
  164.         cmp     al,'$'                  ; End of keyword?
  165.         jne     cmky3x                  ; ne = not yet
  166.         jmp     cmky7                   ; Succeed.
  167. cmky3x: mov     dl,al                   ; Save al's char here.
  168.         call    cmgtch
  169.         inc     cl                      ; Read in another char.
  170.         mov     al,dl
  171.         call    tolowr                  ; lower case
  172.         cmp     ah,escape+80H   ; Escape Recognition (escape w/minus bit on)?
  173.         je      cmky3y
  174.         cmp     ah,' '+80H              ; A space?
  175.         je      cmky3y
  176.         cmp     ah,cr+80H               ; Carriage return?
  177.         je      cmky3y
  178.         cmp     ah,'?'+80H              ; A question mark?
  179.         je      cmky3y
  180.         cmp     ah,al                   ; user = keyword char?
  181.         je      cmky3                   ; e = yes. Check next letter
  182.         jmp     cmky6           ; no. Go to end of keyword and try next
  183.  
  184. cmky3y: mov     comand.cmkptr,bx        ; Save bx here.
  185.         mov     comand.cmsiz,cx         ; Save size info.
  186.         mov     comand.cmchr,ah         ; Save char for latter.
  187.         cmp     ah,'?'+80h              ; question mark?
  188.         je      cmkyj1                  ; yes, always print possibilities
  189.         call    cmambg                  ; See if input is ambiguous or not.
  190.          jmp    cmky32                  ; Succeeded (not ambiguous).
  191.         mov     ah,comand.cmchr
  192.         cmp     ah,escape+80H           ; Escape?
  193.         je      cmky3z
  194.         jmp     cmky41                  ; Else fail.
  195. cmky3z: mov     ah,conout               ; Ring a bell.
  196.         mov     dl,bell
  197.         int     dos
  198.         mov     bx,comand.cmcptr        ; Move pointer to before the escape.
  199.         dec     bx
  200.         mov     comand.cmcptr,bx
  201.         mov     comand.cmdptr,bx
  202.         dec     comand.cmccnt           ; Decrement char count.
  203.         mov     bx,comand.cmkptr        ; Failed - pretend user never typed
  204.         mov     cx,comand.cmsiz         ; ... in a char.
  205.         dec     cl                      ; Don't count the escape.
  206.         dec     bx
  207.         mov     comand.cmaflg,0         ; Reset the action flag.
  208.         jmp     cmky3                   ; Keep checking.
  209.  
  210. ; Question mark entered by user.  Print out all the keywords that match
  211. cmkyj1: mov     dx,offset cmin01
  212.         mov     ah,prstr
  213.         int     dos
  214.         mov     temp,0                  ; count # chars printed on this line
  215.         mov     bx,comand.cmkptr        ; this is current keyword
  216.         mov     cx,comand.cmsiz         ; we are cl chars into it
  217.         mov     ch,0
  218.         sub     bx,cx                   ; back up to beginning
  219.         inc     bx                      ; not counting ?
  220.         mov     comand.cmkptr,bx        ; save beginning of kw
  221. cmkyj2: mov     bx,comand.cmkptr        ; start of keyword
  222.         dec     bx
  223.         mov     al,[bx]                 ; its length
  224.         add     temp,al                 ; count chars printed so far
  225.         cmp     temp,76                 ; will this take us beyond column 78?
  226.         jle     cmkyj3                  ; le = ok so far
  227.         mov     ah,prstr                ; print string
  228.         mov     dx,offset crlf          ; break the line
  229.         int     dos
  230.         mov     temp,0                  ; and reset the count
  231. cmkyj3: mov     dl,spc                  ; put two spaces before each keyword
  232.         mov     ah,conout
  233.         int     dos
  234.         inc     temp                    ; count output chars
  235.         int     dos
  236.         inc     temp
  237.         mov     dx,comand.cmkptr        ; get current keyword
  238.         mov     ah,prstr
  239.         int     dos                     ; print it
  240.         mov     bx,comand.cmkptr        ; get keyword back
  241.         dec     bx
  242.         mov     al,[bx]                 ; get length
  243.         mov     ah,0
  244.         add     ax,5                    ; skip length, $, value, next length
  245.         add     bx,ax                   ; this is next keyword
  246.         mov     si,bx
  247.         mov     di,comand.cmkptr        ; compare with last keyword
  248.         mov     comand.cmkptr,bx        ; update this
  249.         mov     cx,comand.cmsiz
  250.         dec     ch                      ; are we at end of table?
  251.         jl      cmkyj4                  ; l = yes, don't go on
  252.         mov     comand.cmsiz,cx         ; else update count
  253.         mov     ch,0
  254.         dec     cl                      ; this includes ?
  255.         jcxz    cmkyj2                  ; empty, just print it
  256.         repe    cmpsb                   ; compare to previous string
  257.         je      cmkyj2                  ; same, go print this one
  258. cmkyj4: jmp     cmky50                  ; else go finish up
  259.  
  260. cmky32: mov     cx,comand.cmsiz         ; Restore info.
  261.         mov     bx,comand.cmkptr        ; Our place in the keyword table.
  262.         cmp     comand.cmchr,' '+80H    ; Space?
  263.         je      cmky35
  264.         cmp     comand.cmchr,'?'+80H    ; Question mark?
  265.         je      cmky35
  266.         cmp     comand.cmchr,cr+80H     ; Carriage return?
  267.         je      cmky35
  268.         dec     comand.cmcptr           ; Pointer into buffer of input.
  269.         mov     dx,comand.cmcptr
  270. cmky33: mov     ah,[bx]                 ; Get next char in keyword.
  271.         call    tolowr                  ; convert it to lower case
  272.         cmp     ah,'$'                  ; Are we done yet?
  273.         jz      cmky34
  274.         mov     di,dx
  275.         mov     [di],ah
  276.         inc     bx
  277.         inc     dx
  278.         inc     comand.cmccnt
  279.         jmp     cmky33
  280. cmky34: mov     ah,' '
  281.         mov     di,dx
  282.         mov     [di],ah                 ; Put a blank in the buffer.
  283.         inc     dx
  284.         mov     cx,comand.cmcptr        ; Remember where we were.
  285.         mov     comand.cmcptr,dx        ; Update our pointers.
  286.         mov     comand.cmdptr,dx
  287.         mov     ah,'$'
  288.         mov     di,dx
  289.         mov     [di],ah                 ; Add '$' for printing.
  290.         mov     ah,prstr
  291.         mov     dx,cx                   ; Point to beginning of filled in data
  292.         int     dos
  293.         inc     bx                      ; Point to address we'll need.
  294.         mov     bx,[bx]
  295.         mov     comand.cmaflg,0         ; Turn off action flag.
  296.         jmp     rskp
  297.  
  298. cmky35: inc     bx
  299.         mov     ah,[bx]                 ; Find end of keyword.
  300.         cmp     ah,'$'
  301.         jne     cmky35
  302.         inc     bx
  303.         mov     bx,[bx]                 ; Address of next routine to call.
  304.         jmp     rskp
  305.  
  306. cmky4:  and     ah,7FH                  ; Turn off minus bit.
  307.         cmp     ah,'?'                  ; Need help?
  308.         je      cmky5
  309.         cmp     ah,' '                  ; Just a space - no error.
  310.         je      cmky51
  311.         cmp     ah,cr
  312.         je      cmky51
  313.         cmp     ah,tab
  314.         je      cmky51
  315.         cmp     ah,escape               ; Ignore escape?
  316.         je      cmky43
  317. cmky41: mov     ah,prstr
  318.         mov     dx,offset cmer03
  319.         int     dos
  320.         jmp     prserr                  ; Parse error - give up.
  321.  
  322. cmky43: mov     ah,conout               ; Ring a bell.
  323.         mov     dl,bell
  324.         int     dos
  325.         dec     comand.cmcptr           ;[ESC] don't trash BX here.
  326.         dec     comand.cmdptr           ;[ESC] ditto
  327.         dec     comand.cmccnt           ; Don't count the escape.
  328.         mov     comand.cmaflg,0         ; Reset action flag.
  329.         inc     ch                      ; Account for a previous 'dec'.
  330.         jmp     cmky1                   ; Start over.
  331.  
  332. cmky5:  inc     bx                      ; point to actual keyword
  333.         mov     comand.cmkptr,bx        ; remember current kw
  334.         mov     cl,1                    ; code above expects to count '?'
  335.         mov     comand.cmsiz,cx         ; and size
  336.         mov     dx,comand.cmhlp
  337.         or      dx,dx                   ; was any help given?
  338.         jnz     cmky5a                  ; yes, use it
  339.         jmp     cmkyj1                  ; else make our own message
  340. cmky5a: mov     ah,prstr
  341.         int     dos
  342. cmky50: mov     ah,prstr
  343.         mov     dx,offset crlf
  344.         int     dos
  345.         mov     dx,comand.cmprmp        ; Address of prompt.
  346.         int     dos
  347.         mov     bx,comand.cmdptr        ; Get pointer into buffer.
  348.         mov     al,'$'
  349.         mov     [bx],al                 ; Add dollar sign for printing.
  350.         mov     dx,offset comand.cmdbuf
  351.         int     dos
  352.         dec     comand.cmcptr           ; Don't keep it in the buffer.
  353.         dec     comand.cmccnt           ; Don't count it.
  354.         mov     comand.cmaflg,0         ; Turn off the action flag.
  355.         jmp     repars
  356.  
  357. cmky51: cmp     comand.cmcr,1           ; Are bare CR's allowed?
  358.         je      cmky52                  ; Yes.
  359.         mov     ah,prstr
  360.         mov     dx,offset cmer04        ; Complain.
  361.         int     dos
  362. cmky52: jmp     prserr
  363.  
  364. cmky6:  inc     bx                      ; Find end of keyword.
  365.         cmp     byte ptr [bx],'$'
  366.         jne     cmky6
  367.         add     bx,3                    ; Beginning of next command.
  368.         mov     dx,comand.cmsptr        ; Get old cmdptr.
  369.         mov     comand.cmdptr,dx        ; Restore.
  370.         mov     comand.cmsflg,0FFH
  371.         jmp     cmky1                   ; Keep trying.
  372.  
  373. cmky7:  call    cmgtch                  ; Get char.
  374.         cmp     ah,0
  375.         js      cmky71                  ; Ok if a terminator.
  376.         dec     bx
  377.         jmp     cmky6                   ; No match - try next keyword.
  378. cmky71: cmp     ah,'?'+80h              ; question mark?
  379.         jne     cmky72                  ; yes, don't return yet
  380.         inc     cl              ; count the '?' Fix single char keywords
  381.         jmp     cmky3y                  ; and process ? correctly
  382. cmky72: inc     bx                      ; Get necessary data.
  383.         mov     bx,[bx]
  384.         cmp     ah,escape+80h           ; An escape?
  385.         jne     cmky73
  386.         mov     ah,prstr
  387.         mov     dx,offset prsp          ; Print a space.
  388.         int     dos
  389.         mov     di,comand.cmcptr
  390.         dec     di
  391.         mov     ah,20H
  392.         mov     [di],ah                 ; Replace escape char with space.
  393.         mov     comand.cmaflg,0
  394.         mov     comand.cmsflg,0FFH      ; Pretend they typed a space.
  395. cmky73: jmp     rskp
  396.  
  397. ; See if keyword is unambiguous or not from what the user has typed in.
  398.  
  399. cmambg: cmp     ch,0                    ; Any keywords left to check?
  400.         jne     cmamb0
  401.         ret                             ; If not then not ambiguous.
  402. cmamb0: inc     bx                      ; Go to end of keyword ...
  403.         mov     al,[bx]                 ; So we can check the next one.
  404.         cmp     al,'$'
  405.         jne     cmamb0
  406.         add     bx,4                    ; Point to start of next keyword.
  407.         dec     cl                      ; Don't count escape.
  408.         mov     dx,comand.cmsptr        ; Buffer with input typed by user.
  409. cmamb1: mov     ah,[bx]                 ; Keyword char.
  410.         mov     di,dx
  411.         mov     al,[di]                 ; Input char.
  412.         call    tolowr                  ; convert to lower case
  413.         cmp     ah,al           ; Keyword bigger than input (alphabetically)?
  414.         jle     cmamb2                  ; No - keep checking.
  415.         ret                             ; Yes   - not ambiguous.
  416. cmamb2: inc     bx                      ; Advance one char.
  417.         inc     dx
  418.         dec     cl
  419.         jnz     cmamb1
  420.         jmp     rskp                    ; Fail - it's ambiguous.
  421.  
  422.  
  423.  
  424. ; Parse arbitrary text up to a CR.  Put chars into data buffer sent to
  425. ; the host (pointed to by BX).   Called with text of help message in DX.
  426. ; Produces asciiz string. Return updated pointer in BX and input size in AH.
  427.  
  428. cmtext: mov     comand.cmptab,bx        ; Save pointer to data buffer.
  429.         mov     cmthlp,dx               ; Save the help message.
  430.         mov     cl,0                    ; Init the char count.
  431. cmtxt1: mov     comand.cmsflg,0         ; Get all spaces.
  432.         call    cmgtch                  ; Get a char.
  433.         test    ah,80H                  ; is high-order bit on?
  434.         jz      cmtxt5                  ; Nope, put into the buffer.
  435.         and     ah,07FH
  436.         cmp     ah,' '
  437.         je      cmtxt5
  438.         cmp     ah,escape               ; An escape?
  439.         jne     cmtxt2
  440.         mov     ah,conout
  441.         mov     dl,bell                 ; Ring a bell.
  442.         int     dos
  443.         mov     comand.cmaflg,0         ; Reset action flag.
  444.         dec     comand.cmcptr           ; Move pointer to before the escape.
  445.         dec     comand.cmdptr
  446.         dec     comand.cmccnt           ; Decrement count.
  447.         jmp     cmtxt1                  ; Try again.
  448. cmtxt2: cmp     ah,'?'                  ; Asking a question?
  449.         jz      cmtx30
  450.         cmp     ah,FF                   ; Formfeed?
  451.         jne     cmtx2x
  452.         call    cmblnk
  453. cmtx2x: mov     ah,cl                   ; Return count in AH.
  454.         mov     bx,comand.cmptab        ; Return updated pointer.
  455.         jmp     rskp
  456. cmtxt5: inc     cl                      ; Increment the count.
  457.         mov     bx,comand.cmptab        ; Pointer into destination array.
  458.         mov     [bx],ah                 ; Put char into the buffer.
  459.         inc     bx
  460.         mov     al,0
  461.         mov     [bx],al                 ; insert null terminator
  462.         mov     comand.cmptab,bx
  463.         jmp     cmtxt1
  464. cmtx30: mov     comand.cmaflg,0         ; Reset action flag to zero.
  465.         inc     comand.cmdptr           ; count the ?
  466.         cmp     cl,0                    ; Is "?" first char?
  467.         jne     cmtxt5                  ; No, just add to buffer.
  468.         dec     comand.cmcptr   ;[ESC] (moved 3 lines) Don't keep in buffer.
  469.         dec     comand.cmccnt           ;[ESC] Don't count it.
  470.         dec     comand.cmdptr           ;[ESC] don't count if printing help.
  471.         mov     ah,prstr                ; Else, give some help.
  472.         mov     dx,cmthlp               ; Address of help message.
  473.         int     dos
  474.         mov     ah,prstr
  475.         mov     dx,offset crlf          ; Print a crlf.
  476.         int     dos
  477.         mov     ah,prstr
  478.         mov     dx,comand.cmprmp        ; Reprint the prompt.
  479.         int     dos
  480.         mov     bx,comand.cmdptr        ; Get the pointer into the buffer.
  481.         mov     byte ptr [bx],'$'
  482.         mov     ah,prstr
  483.         mov     dx,offset comand.cmdbuf
  484.         int     dos
  485.         jmp     cmtxt1                  ; And keep going.
  486.  
  487. ;       [jrd]
  488. ; Parse arbitrary text up to whitespace.  Put chars into data buffer sent to
  489. ; the host (pointed to by DX).   Called with text of help message in BX.
  490. ; Produces asciiz string. Return updated pointer in DX and input size in AH.
  491. ; Skips leading whitespace.
  492. ; Does a return skip exit. Replaces old cmifi routine.
  493.  
  494. cmfil0: push    dx
  495.         mov     dx,bx                   ; interchange bx and bx internally
  496.         pop     bx
  497.         mov     comand.cmptab,bx        ; Save pointer to data buffer.
  498.         mov     cmthlp,dx               ; Save the help message.
  499.         mov     cl,0                    ; Init the char count.
  500.         mov     comand.cmsflg,0ffH      ; skip over leading spaces and tabs.
  501. cmfil1: call    cmgtch                  ; Get a char.
  502.         test    ah,80H          ; is high-order bit on (i.e. terminator seen)?
  503.         jnz     cmfi1a                  ; nz = yes
  504.         jmp     cmfil5                  ; z = no, put char into the buffer.
  505. cmfi1a: and     ah,07FH                 ; clear high order bit
  506.         cmp     ah,escape               ; An escape?
  507.         je      cmfi1b                  ; e = yes.
  508.         cmp     ah,' '                  ; is it a space or control char?
  509.         jg      cmfil2                  ; g = no. keep it
  510.         jmp     cmfi2x          ; else, a space or control char; end here.
  511.  
  512. cmfi1b: mov     ah,conout               ; handle escape char; ie, complain
  513.         mov     dl,bell                 ; Ring a bell.
  514.         int     dos
  515.         mov     comand.cmaflg,0         ; Reset action flag.
  516.         dec     comand.cmcptr           ; Move pointer to before the escape.
  517.         dec     comand.cmdptr
  518.         dec     comand.cmccnt           ; Decrement count.
  519.         jmp     cmfil1                  ; Try again.
  520. cmfil2: cmp     ah,'?'                  ; Asking a question?
  521.         jz      cmfil3                  ; z = yes
  522.         cmp     ah,ff                   ; Formfeed?
  523.         jne     cmfi2x                  ; ne = no
  524.         call    cmblnk                  ; a FF. clear the command line and end
  525.  
  526. cmfi2x: mov     bx,comand.cmptab        ; Pointer into destination array.
  527.         mov     byte ptr[bx],0          ; Put null terminator into the buffer
  528.         inc     bx
  529.         mov     ah,cl                   ; Return count in AH.
  530.         mov     dx,comand.cmptab        ; Return updated pointer.
  531.         xchg    dx,bx                   ; re-interchange bx and dx
  532.         jmp     rskp
  533.  
  534. cmfil3: mov     comand.cmaflg,0         ; Reset action flag to zero.
  535.         inc     comand.cmdptr           ; count the ?
  536.         cmp     cl,0                    ; Is "?" first char?
  537.         jne     cmfil5                  ; No, just add to buffer.
  538.         dec     comand.cmcptr   ;[ESC] (moved 3 lines) Don't keep in buffer.
  539.         dec     comand.cmccnt           ;[ESC] Don't count it.
  540.         dec     comand.cmdptr           ;[ESC] don't count if displaying help.
  541.         mov     ah,prstr                ; Else, give some help.
  542.         mov     dx,cmthlp               ; Address of help message.
  543.         int     dos
  544.         mov     dx,offset crlf          ; Print a crlf.
  545.         int     dos
  546.         mov     dx,comand.cmprmp        ; Reprint the prompt.
  547.         int     dos
  548.         mov     bx,comand.cmdptr        ; Get the pointer into the buffer.
  549.         mov     byte ptr [bx],'$'
  550.         mov     dx,offset comand.cmdbuf
  551.         int     dos
  552.         jmp     cmfil1                  ; And keep going.
  553. cmfil5: inc     cl                      ; Increment the count.
  554.         mov     bx,comand.cmptab        ; Pointer into destination array.
  555.         mov     [bx],ah                 ; Put char into the buffer.
  556.         inc     bx
  557.         mov     comand.cmptab,bx
  558.         jmp     cmfil1                  ; the end of cmfil0.
  559.  
  560.  
  561. cmgetc: mov     ah,taklev               ; get current Take level
  562.         mov     intake,ah               ; remember here for later callers
  563.         cmp     ah,0                    ; in a Take file?
  564.         jne     cmget1                  ; ne = yes
  565.         jmp     cmge10                  ; no take file, get from keyboard
  566. cmget1: push    bx
  567.         push    si
  568.         mov     bx,takadr
  569.         mov     ax,[bx].takcnt          ; size of item
  570.         or      ax,[bx].takcnt+2        ; empty?
  571.         jnz     cmget5                  ; nz = no
  572. cmget2: mov     al,byte ptr [bx].taktyp ; get type of take
  573.         cmp     al,0ffh                 ; is it really a macro?
  574.         je      cmget4                  ; yes, better not try to close it
  575.         mov     bx,word ptr [bx].takhnd ; get file handle
  576.         mov     ah,close2               ; use 2.0 close
  577.         int     dos
  578. cmget4: dec     taklev
  579.         sub     takadr,size takinfo
  580.         pop     si
  581.         pop     bx
  582.         mov     al,cr                   ; end with carriage return...
  583.         mov     prevch,al               ; remember last read character
  584.         mov     noparse,0
  585.         ret
  586.  
  587. cmget5: cmp     [bx].takchl,0           ; Any chars left in buffer?
  588.         jne     cmget6                  ; ne = yes
  589.         call    takrd                   ; else read another buffer
  590.         cmp     [bx].takchl,0           ; anything in the file?
  591.         je      cmget2                  ; e = no, quit
  592. cmget6: dec     [bx].takchl
  593.         sub     [bx].takcnt,1           ; DEC doesn't set carry!!
  594.         sbb     [bx].takcnt+2,0
  595.         mov     si,[bx].takptr
  596.         lodsb
  597.         mov     [bx].takptr,si
  598.         cmp     al,ctlz                 ; maybe control-z?
  599.         je      cmget2          ; yes, close take file (has to be before pops)
  600.         pop     si
  601.         pop     bx
  602.         cmp     al,lf                   ; linefeed?
  603.         jne     cmget7
  604.         mov     prevch,al               ; remember last read character
  605.         jmp     cmgetc                  ; yes, ignore it.
  606. cmget7: cmp     al,';'                  ; maybe a semicolon?
  607.         jne     cmget7c                 ; ne = no, accept as-is
  608.         cmp     prevch,5ch              ; was previous char backslash escape?
  609.         jne     cmget9                  ; ne = no, semicolon starts a comment
  610.         cmp     noparse,0               ; parsing this part of the command?
  611.         jne     cmget7a                 ; ne = no, observe but do not store
  612.         pop     bx
  613.         mov     bx,comand.cmcptr        ; Get the pointer into the cmd buffer.
  614.         mov     byte ptr[bx-1],al       ; stuff in the literal semicolon
  615.         pop     bx
  616. cmget7a:mov     prevch,al               ; remember last read character
  617.         cmp     flags.takflg,0          ; echoing take files?
  618.         je      cmget7b                 ; e = no
  619.         push    dx                      ; backspace cursor over backslash
  620.         push    ax                      ; and print the semicolon
  621.         mov     ah,conout
  622.         mov     dl,BS
  623.         int     dos
  624.         mov     dl,al
  625.         int     dos
  626.         pop     ax
  627. cmget7b:pop     dx
  628.         jmp     cmgetc                  ; get next char
  629.  
  630. cmget7c:mov     prevch,al               ; normal character acceptance pathway
  631.         cmp     flags.takflg,0          ; Echo contents of take file?
  632.         je      cmget8                  ; e = no
  633.         push    dx
  634.         mov     dl,al
  635.         mov     ah,conout
  636.         int     dos
  637.         pop     dx
  638. cmget8: ret                             ; else just return...
  639.  
  640. ; semicolon seen, echo and ignore chars until cr
  641. cmget9: push    ax
  642.         mov     al,spc                  ; replace semicolon with a space
  643.         call    cmget7c                 ; echo the char
  644.         pop     ax
  645. cmget9a:mov     prevch,al               ; remember last read character
  646.         mov     noparse,1               ; defeat semicolon parsing
  647.         call    cmgetc                  ; get a character
  648.         cmp     al,cr                   ; carriage return?
  649.         jne     cmget9a                 ; no, keep reading
  650.         mov     prevch,al               ; remember last read character
  651.         mov     noparse,0               ; done with escaped semicolon actions
  652.         ret                             ; else return it
  653.  
  654. cmge10: mov     ah,coninq               ; Get a char.
  655.         int     dos
  656.         or      al,al
  657.         jnz     cmge11                  ; ignore null bytes of special keys
  658.         int     dos                     ; read and discard scan code byte
  659.         jmp     cmge10                  ; try again
  660. cmge11: and     al,7fh                  ; only allow 7-bit characters.
  661.         push    ax                      ; save the char
  662.         cmp     al,del
  663.         je      cmgex
  664.         cmp     al,' '                  ; printable?
  665.         jae     cmge12                  ; yes, no translation needed
  666.         cmp     al,cr                   ; this is printable
  667.         je      cmge12
  668.         cmp     al,lf
  669.         je      cmge12
  670. cmgex:  mov     al,' '                  ; else echo a space
  671. cmge12: mov     dl,al                   ; put char here
  672.         cmp     comand.cmquiet,0        ; quiet mode?
  673.         jnz     cmge13                  ; yes, skip echoing...
  674.         mov     ah,conout
  675.         int     dos                     ; echo it ourselves...
  676. cmge13: pop     ax                      ; and return it
  677.         cmp     al,'C'-40H              ; control-C?
  678.         je      cmge15                  ; yes, go handle
  679.         cmp     al,tab
  680.         jne     cmge14
  681.         mov     al,' '
  682. cmge14: ret
  683. cmge15: mov     dx,offset ctcmsg
  684.         mov     ah,prstr
  685.         int     dos
  686.         mov     flags.cxzflg,'C'        ; remember ^C'd
  687.         mov     sp,cmdstk               ; restore command stack ptr
  688.         ret                             ; and fail
  689.  
  690. ; Come here is user types ^W when during input.
  691. cntrlw: mov     ah,prstr
  692.         mov     dx,offset escspc
  693.         int     dos
  694.         dec     comand.cmccnt           ; Don't include it in the count.
  695.         dec     comand.cmcptr           ; Back up past the ^W.
  696.         mov     cl,comand.cmccnt
  697.         mov     ch,0
  698.         jcxz    ctlw2
  699.         pushf
  700.         push    es
  701.         std                             ; Scan  backward
  702.         mov     ax,ds
  703.         mov     es,ax                   ; Point to the data area.
  704.         mov     di,comand.cmcptr        ; Looking from here.
  705.         dec     di
  706.         mov     al,' '
  707.         repe    scasb                   ; Look for non-space.
  708.         je      ctlw1                   ; All spaces, nothing else to do
  709.         inc     di                      ; move back to non-space
  710.         inc     cx
  711.         repne   scasb                   ; look for a space
  712.         jne     ctlw1                   ; no space, leave ptrs alone
  713.         inc     di
  714.         inc     cx                      ; skip back over space
  715. ctlw1:  inc     di
  716.         cld                             ; reset direction flag
  717.         mov     comand.cmccnt,cl        ; update count
  718.         mov     cx,comand.cmcptr        ; remember old ptr
  719.         mov     comand.cmcptr,di        ; update pointer
  720.         sub     cx,di                   ; this is characters moved
  721.         mov     dl,BS                   ; output backspaces
  722.         mov     ah,conout
  723. ctlw3:  int     dos                     ; backup cursor
  724.         loop    ctlw3
  725.         call    clearl                  ; clear line
  726.         pop     es
  727.         popf
  728.         ret                             ; and return
  729. ctlw2:  mov     ah,conout
  730.         mov     dl,bell
  731.         int     dos
  732.         ret
  733.  
  734. cminbf: push    dx
  735.         push    bx
  736.         mov     cx,dx                   ; Save value here too.
  737.         cmp     comand.cmaflg,0         ; Is the action char flag set?
  738.         je      cminb1
  739.         jmp     cminb9                  ; If so get no more chars.
  740. cminb1: cmp     comand.cmccnt,size cmdbuf       ; max buffer size
  741.         jb      cminb1a                 ; b = not full
  742.         push    ax                      ; full.
  743.         push    dx
  744.         mov     ah,conout               ; complain
  745.         mov     dl,bell
  746.         int     dos
  747.         pop     dx
  748.         pop     ax
  749.         jmp     cminb6                  ; set action flag
  750. cminb1a:inc     comand.cmccnt           ; Increment the char count.
  751.         call    cmgetc
  752.         mov     ah,al                   ; Keep char in 'ah'.
  753.         mov     bx,comand.cmcptr        ; Get the pointer into the buffer.
  754.         mov     [bx],ah                 ; Put it in the buffer.
  755.         inc     bx
  756.         mov     comand.cmcptr,bx
  757.         cmp     ah,'W'-64               ; Is it a ^W?
  758.         jne     cmnb11
  759.         call    cntrlw                  ; Kill the previous word.
  760.         jmp     repars
  761. cmnb11: cmp     ah,25O                  ; Is it a ^U?
  762.         jne     cminb2
  763. cmnb12: call    ctlu                    ; Clear out the line.
  764.         mov     ah,prstr
  765.         mov     dx,comand.cmprmp        ; Print the prompt.
  766.         int     dos
  767.         mov     bx,offset comand.cmdbuf
  768.         mov     comand.cmcptr,bx        ; Reset the point to the start.
  769.         mov     comand.cmccnt,0         ; Zero the count.
  770.         mov     dx,cx                   ; Preserve original value of dx.
  771.         jmp     repars                  ; Go start over.
  772. cminb2: cmp     ah,bs                   ; Or backspace?
  773.         jz      cminb3
  774.         cmp     ah,del                  ; Delete?
  775.         jne     cminb4
  776. cminb3: mov     ah,comand.cmccnt ; Decrement the char count by two (char + BS)
  777.         dec     ah
  778.         dec     ah
  779.         cmp     ah,0                    ; Have we gone too far?
  780.         jns     cmnb32                  ; If not proceed.
  781.         mov     ah,conout               ; Ring the bell.
  782.         mov     dl,bell
  783.         int     dos
  784.         jmp     cmnb12                  ; Go reprint prompt and reparse.
  785. cmnb32: mov     comand.cmccnt,ah        ; Save the new char count.
  786.         call    dodel                   ; Delete a character.
  787.         mov     ah,prstr                ; Erase the character.
  788.         mov     dx,offset clrspc
  789.         int     dos
  790.         dec     comand.cmcptr           ; Get the pointer into the buffer.
  791.         dec     comand.cmcptr           ; Back up in the buffer.
  792. cmnb34: jmp     repars                  ; Go reparse everything.
  793. cminb4: cmp     ah,'?'                  ; Is it a question mark.
  794.         jz      cminb6
  795.         cmp     ah,escape               ; Is it an escape?
  796.         jz      cminb8
  797.         cmp     ah,cr                   ; Is it a carriage return?
  798.         jz      cminb5
  799.         cmp     ah,lf                   ; Is it a line feed?
  800.         jz      cminb5
  801.         cmp     ah,ff                   ; Is it a formfeed?
  802.         jne     cminb7
  803.         call    cmblnk                  ; FF: clear the screen and
  804.         call    locate                  ; Home the cursor.
  805.         push    bx                      ; make the FF parse like a cr
  806.         mov     bx,comand.cmcptr        ; permanent storage of next char
  807.         mov     byte ptr [bx-1],cr      ; pretend a carriage return were typed
  808.         pop     bx
  809. cminb5: cmp     comand.cmccnt,1         ; Have we parsed any chars yet?
  810.         jnz     cminb6
  811.         cmp     comand.cmcr,0           ; bare cr's allowed?
  812.         jne     cminb6                  ; ne = yes
  813.         jmp     prserr                  ; If not, just start over.
  814. cminb6: mov     comand.cmaflg,0FFH      ; Set the action flag.
  815.         jmp     cminb9
  816. cminb7: jmp     cminb1                  ; Get another char.
  817.  
  818. cminb8: mov     ah,prstr                ; Don't print the escape char.
  819.         mov     dx,offset escspc
  820.         int     dos
  821.         jmp     cminb6
  822.  
  823. cminb9: pop     bx
  824.         pop     dx
  825.         ret
  826.  
  827. cmgtch: push    cx
  828.         push    bx
  829.         push    dx
  830. cmgtc1: cmp     comand.cmaflg,0         ; is action flag set?
  831.         jne     cmgt10
  832.         call    cminbf          ; If the action char flag is not set get more.
  833. cmgt10: mov     bx,comand.cmdptr        ; Get a pointer into the buffer.
  834.         mov     ah,[bx]                 ; Get the next char.
  835.         inc     bx
  836.         mov     comand.cmdptr,bx
  837.         cmp     ah,' '                  ; Is it a space?
  838.         jz      cmgtc2
  839.         cmp     ah,tab                  ; Or a tab?
  840.         jne     cmgtc3
  841. cmgtc2: cmp     comand.cmsflg,0         ; space flag, was last char a space?
  842.         jne     cmgtc1                  ; Yes, get another char.
  843.         mov     comand.cmsflg,0FFH      ; Set the space flag.
  844.         mov     ah,' '
  845.         pop     dx
  846.         pop     bx
  847.         jmp     cmgtc5
  848. cmgtc3: mov     al,0
  849.         mov     comand.cmsflg,al        ; Zero the space flag.
  850.         pop     dx
  851.         pop     bx
  852.         cmp     ah,escape
  853.         jz      cmgtc5
  854.         cmp     ah,'?'                  ; Is the user curious?
  855.         jz      cmgtc4
  856.         cmp     ah,cr
  857.         jz      cmgtc4
  858.         cmp     ah,lf
  859.         jz      cmgtc4
  860.         cmp     ah,ff
  861.         je      cmgtc4
  862.         pop     cx
  863.         ret                             ; Not an action char, just return.
  864. cmgtc4: dec     comand.cmdptr
  865. cmgtc5: or      ah,80H                  ; Make the char negative to indicate
  866.         pop     cx
  867.         ret                             ; it is a terminator.
  868. CMND    ENDP
  869.  
  870. ;       This address is jumped to on reparse.
  871.  
  872. PARSE   PROC NEAR
  873. repars: mov     sp,comand.cmostp        ; new sp <-- old sp
  874.         mov     bx,offset comand.cmdbuf
  875.         mov     comand.cmdptr,bx
  876.         mov     comand.cmsflg,0ffh
  877.         jmp     comand.cmrprs           ; go back to reparse address
  878.  
  879. ;       This address can be jumped to on a parsing error.
  880.  
  881. prserr: mov     sp,comand.cmostp        ; Set new sp to old one.
  882.         mov     bx,offset comand.cmdbuf
  883.         mov     comand.cmcptr,bx        ; Initialize the command pointer.
  884.         mov     comand.cmdptr,bx
  885.         mov     ah,0
  886.         mov     comand.cmaflg,ah        ; Zero the flags.
  887.         mov     comand.cmccnt,ah
  888.         mov     comand.cmsflg,0FFH
  889.         cmp     taklev,0                ; in take cmd?
  890.         je      prser2                  ; e = no
  891.         cmp     flags.takflg,0          ; echo contents of take file?
  892.         je      prser1                  ; e = no
  893. prser2: mov     ah,prstr
  894.         mov     dx,offset crlf
  895.         int     dos
  896.         mov     ah,prstr                ; Print the prompt.
  897.         mov     dx,comand.cmprmp        ; Get the prompt.
  898.         int     dos
  899.                                 ; Instead return to before the prompt call.
  900. prser1: jmp     comand.cmrprs
  901. PARSE   ENDP
  902.  
  903. ; Convert ascii characters in al and ah to lowercase. [jrd]
  904. ; All registers are preserved except AX, of course.
  905.  
  906. TOLOWR PROC NEAR
  907.         test    ah,80H                  ; sign  bit set?
  908.         jnz     tolow1                  ; nz = yes
  909.         cmp     ah,'A'                  ; less that cap A?
  910.         jl      tolow1                  ; l = yes. leave untouched
  911.         cmp     ah,'Z'+1                ; more than cap Z?
  912.         jns     tolow1                  ; ns = yes.
  913.         or      ah,20H                  ; convert to lowercase
  914. tolow1: test    al,80H                  ; sign bit set?
  915.         jnz     tolow2                  ; nz = yes
  916.         cmp     al,'A'                  ; less that cap A?
  917.         jl      tolow2                  ; l = yes. leave untouched
  918.         cmp     al,'Z'+1                ; more than cap Z?
  919.         jns     tolow2                  ; ns = yes.
  920.         or      al,20H                  ; convert to lowercase
  921. tolow2: ret
  922. TOLOWR  endp
  923.  
  924. ; Jumping to this location is like retskp.  It assumes the instruction
  925. ;   after the call is a jmp addr.
  926.  
  927. RSKP    PROC    NEAR
  928.         pop     bp
  929.         add     bp,3
  930.         push    bp
  931.         ret
  932. RSKP    ENDP
  933.  
  934. ; Jumping here is the same as a ret.
  935.  
  936. R       PROC    NEAR
  937.         ret
  938. R       ENDP
  939.  
  940. code    ends
  941.         end
  942.