home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / ccpm86 / cn8icm.a86 < prev    next >
Text File  |  2020-01-01  |  24KB  |  863 lines

  1. ; CN8ICM.A86
  2. ; * * * * * * * * * * * * * * *  version 2.8  * * * * * * * * * * * * * * *
  3. ; [32c] remove check for 0-length filename
  4. ; [32b] fix minor bugs
  5. ; [32a] fix prompt to show default drive and user
  6. ; RonB, 09/13/84
  7. ; * * * * * * * * * * * * * * *  version 2.7  * * * * * * * * * * * * * * *
  8. ; [fdc] Fix small glitch w/CMLEVL that issued msg spuriously sometimes.
  9. ; [] Introduced CMLEVL flag to intercept "empty" command-options
  10. ; Reset by PRSERR, SET in 86KERMIT KERMIT:
  11. ;  B.E.; EIBEN at DEC-MARLBORO 2-May-84
  12. ; [30c] Isolate ANSI escape sequences for machine independence.
  13. ; [30b] Make DEL work like BS and ^X like ^U in command input.
  14. ; RonB, 04/18/84
  15. ; * * * * * * * * * * * * * * *  version 2.6  * * * * * * * * * * * * * * *
  16. ; [28d] Improve filename special character processing
  17. ; RonB, 03/27/84
  18. ; [25] Move logic for "seteol" and "escape" (from KERSYS) into here so those
  19. ; routines need not use internal CMD routines and variables.  For this
  20. ; purpose add 2 parse routines and codes: "cmcha" and "cmnum".  The point
  21. ; of this is to keep calls to CMD modular since I want to eventually
  22. ; replace the whole thing.
  23. ; R. Garland 9-Mar-1984
  24. ; * * * * * * * * * * * * * * *  version 2.1  * * * * * * * * * * * * * * *
  25. ;  [9] Fix filename parsing, and add wildcard ability.
  26. ; RonB,12/26/83
  27. ;  [8] Show choices for ambiguous keywords, finish keyword on '?'
  28. ; RonB,12/26/83
  29. ; * * * * * * * * * * * * * * *  version 2.0  * * * * * * * * * * * * * * *
  30. ; This module contains all the routines and storage necessary for the
  31. ; command parser.  The command parser approximates that of the Tops-20
  32. ; COMND% JSYS.  This code is adapted from the IBM PC Kermit code which
  33. ; was adapted from the CP/M-80 Kermit code.
  34. ; COMND definitions.
  35.  
  36. cmcfm equ 01H
  37. cmkey equ 02H
  38. cmifi equ 03H
  39. cmofi equ 04H
  40. cmtxt equ 05H
  41. cmcha equ 06H
  42. cmnum equ 07H
  43.  
  44.  DSEG $   ; Resume the data segment.
  45.  
  46. ; COMND storage.
  47.  
  48. cmer00 db bell,'?Program error -- Invalid COMND call$'
  49. cmer01 db bell,'?Ambiguous command$'
  50. cmer02 db bell,'?Illegal input file spec$'
  51. cmer03 db bell,'?Unrecognized instruction$'
  52. cmer04 db bell,'?Invalid command or operand$'
  53. cmer05 db bell,'?Missing command-option$'
  54. cmin00 db ' Confirm with carriage return$'
  55. cmin01  db      ' Input file spec (possibly wild) $'
  56. cmin02 db ' One of the following:$'   ;[8]
  57.  
  58. cmlevl db 0  ;0 at main-level, 1 otherwise
  59. cmstat db 0  ;What is presently being parsed.
  60. cmaflg db 0  ;Non-zero when an action char has been found.
  61. cmccnt db 0  ;Non-zero if a significant char is found.
  62. cmsflg db 0  ;Non-zero when the last char was a space.
  63. cmostp dw 0  ;Old stack pointer for reparse.
  64. cmrprs dw 0  ;Address to go to on reparse.
  65. cmprmp dw 0  ;Address of prompt.
  66. cmptab dw 0  ;Address of present keyword table.
  67. cmhlp dw 0  ;Address of present help.
  68. cmdbuf rb 80H  ;Buffer for command parsing.
  69. cmfcb dw 0  ;Pointer to FCB.
  70. cmfcb2 dw 0  ;Pointer to position in FCB.
  71. cmcptr dw 0  ;Pointer for next char input.
  72. cmdptr dw 0  ;Pointer into the command buffer.
  73. cmsiz dw 0  ;Size info of user input.
  74. cmkptr dw 0  ;Pointer to keyword.
  75. cmsptr dw 0  ;Place to save a pointer.
  76. cmchr db 0  ;Save char when checking ambiguity.
  77. cmten dw 10  ;the number "10"
  78.  
  79. spchar db '!#$%&()+-/@\^`|~0000' ;Valid special characters ;[8][28d]
  80.  
  81. ; This set of routines provides a user oriented way of parsing
  82. ; commands.  It is similar to that of the COMND JSYS in TOPS-20.
  83.  
  84.  CSEG $   ;Resume coding.
  85.  
  86. ; This routine prints the prompt in DX and specifies the reparse
  87. ; address.
  88.  
  89. prompt: pop bx  ;Get the return address.
  90.  push bx  ;Put it on the stack again.
  91.  mov cmrprs, bx ;Save as addr to go to on reparse.
  92.  mov bx, 0  ;Clear out register.
  93.  add bx, sp  ;Get the present stack pointer.
  94.  mov cmostp, bx ;Save for later restoral.
  95.  mov cmprmp, dx ;Save pointer to the prompt.
  96.  mov bx, offset cmdbuf
  97.  mov cmcptr, bx ;Initialize the command pointer.
  98.  mov cmdptr, bx
  99.  mov cmaflg, 0 ;Zero the flags.
  100.  mov cmlevl, 0 ;[fdc]Including the level-flag
  101.  mov cmccnt, 0
  102.  mov cmsflg, 0FFH
  103. reprompt:       ;[32a] begin
  104.  call tcrlf
  105. repmt2: mov dx, cmprmp ;Print the prompt.
  106.  call tmsg
  107.  mov dl,defdrv ;Print the default drive and user
  108.  add dl,'A'
  109.  call bout
  110.  mov al,defusr
  111.  cbw
  112.  or ax,ax  ;Only print the user number if nonzero
  113.  jz repmt3
  114.  call nout
  115. repmt3: mov dl,'>'
  116.  call bout      ;[32a] end
  117.  ret
  118.  
  119.  
  120. ; This address is jumped to on reparse.
  121.  
  122. repars: mov sp, cmostp ;new sp <-- old sp
  123.  mov bx, offset cmdbuf
  124.  mov cmdptr, bx
  125.  mov cmsflg, 0FFH
  126.  mov bx, cmrprs ;Get the reparse address.
  127.  jmp bx  ;Go there.
  128.  
  129. ; This address can be jumped to on a parsing error.
  130.  
  131. prserr: mov ah, cmlevl ;What level are we in?
  132.  cmp ah, 0  ;
  133.  jz prser1  ;skip error-message
  134.  mov dx, offset cmer05 ;we're out of main-commands
  135.  call tcrmsg  ;and got an empty option
  136.  mov cmlevl, 0 ;reset level-flag
  137. prser1: mov sp, cmostp ;Set new sp to old one.
  138.  mov bx, offset cmdbuf
  139.  mov cmcptr, bx ;Initialize the command pointer.
  140.  mov cmdptr, bx
  141.  mov cmaflg, 0 ;Zero the flags.
  142.  mov cmccnt, 0
  143.  mov cmsflg, 0FFH
  144.  call reprompt     ;[32a]
  145.  mov bx, cmrprs
  146.  jmp bx
  147.  
  148.  
  149. ; This routine parses the specified function in AH. Any additional
  150. ; information is in DX and BX.
  151. ; Returns +1 on success
  152. ;  +4 on failure (assumes a JMP follows the call)
  153.  
  154. comnd: mov cmstat, ah ;Save what we are presently parsing.
  155.  call cminbf  ;Get chars until an action or a erase char.
  156.  mov ah, cmstat ;Restore 'ah' for upcoming checks.
  157.  cmp ah, cmcfm ;Parse a confirm?
  158.  jz cmcfrm  ;Go get one.
  159.  cmp ah, cmkey ;Parse a keyword?
  160.  jnz cm1
  161.  jmp cmkeyw  ;Try and get one.
  162. cm1: cmp ah, cmifi ;Parse an input file spec?
  163.  jnz cm2
  164.  jmp cmifil  ;Go get one.
  165. cm2: cmp ah, cmofi ;Output file spec?
  166.  jnz cm3
  167.  jmp cmofil  ;Go get one.
  168. cm3: cmp ah, cmtxt ;Parse arbitrary text.
  169.  jnz cm4
  170.  jmp cmtext
  171. cm4: cmp ah, cmcha ;[25] parse a single character?
  172.  jnz cm5  ;[25]
  173.  jmp cmchar  ;[25] go do it.
  174. cm5: cmp ah, cmnum ;[25] parse a (decimal) number?
  175.  jnz cm99  ;[25]
  176.  jmp cmnumr  ;[25] go do it.
  177. cm99: mov dx, offset cmer00 ;"?Unrecognized COMND call" [25]
  178.  call tcrmsg
  179.  ret
  180.  
  181. ; This routine gets a confirm.
  182.  
  183. cmcfrm: call cmgtch  ;Get a char.
  184.  cmp ah, 0  ;Is it negative (a terminator;a space or
  185.     ;a tab will not be returned here as they
  186.     ;will be seen as leading white space)?
  187.  js cmcfr0
  188.  ret   ;If not, return failure.
  189. cmcfr0: and ah, 7FH  ;Turn off the minus bit.
  190.  cmp ah, esc  ;Is it an escape?
  191.  jne cmcfr2
  192.  mov dl, bell ;Get a bell.
  193.  call bout  ;Output the char.
  194.  mov cmaflg, 0 ;Turn off the action flag.
  195.  mov bx, cmcptr ;Move the pointer to before the escape.
  196.  dec bx
  197.  mov cmcptr, bx
  198.  mov cmdptr, bx
  199.  dec cmccnt  ;Decrement the char count.
  200.  jmp cmcfrm  ;Try again.
  201. cmcfr2: cmp ah, '?'  ;Curious?
  202.  jne cmcfr3
  203.  mov dx, offset cmin00 ;Print something useful.
  204.  call tmsg
  205.  call reprompt ;Reprint the prompt  ;[32a]
  206.  mov bx, cmdptr ;Get the pointer into the buffer.
  207.  mov ah, '$'  ;Put a $ there for printing.
  208.  mov [bx], ah
  209.  mov bx, cmcptr
  210.  dec bx  ;Decrement & save the buffer pointer.
  211.  mov cmcptr, bx
  212.  mov dx, offset cmdbuf
  213.  call tmsg
  214.  mov cmaflg, 0 ;Turn off the action flag.
  215.  jmp repars  ;Reparse everything.
  216.  
  217. cmcfr3:        ;[8] begin
  218. cmcfr4: jmp rskp
  219.  
  220.  
  221. ; This routine parses a keyword from the table pointed
  222. ; to in DX.  The format of the table is as follows:
  223. ;
  224. ; addr: db n ;Where n is the # of entries in the table.
  225. ;  db m ;M is the size of the keyword.
  226. ;  db 'string$' ;Where string is the keyword.
  227. ;  dw ab ;Where ab is data to be returned.
  228. ;
  229. ; The keywords must be in alphabetical order.
  230.  
  231. cmkeyw: mov cmhlp, bx ;Save the help string.
  232.  mov cmptab, dx ;Save the beginning of keyword table.
  233.  mov bx, dx
  234.  mov ch, [bx] ;Get number of entries in table.
  235.  inc bx
  236.  mov dx, cmdptr ;Save command pointer.
  237.  mov cmsptr, dx ;Save pointer's here.
  238. cmky1: cmp ch, 0  ;Any commands left to check?
  239.  jne cmky2
  240.  ret
  241. cmky2: dec ch
  242.  mov cl, 0  ;Keep track of how many chars read in so far.
  243.  call cmgtch  ;Get a char.
  244.  cmp ah, 0  ;Do we have a terminator?
  245.  jns cmky2x
  246.  jmp cmky4  ;Negative number means we do.
  247. cmky2x: inc bx  ;Point to first letter of keyword.
  248.  inc cl  ;Read in another char.
  249.  mov al, [bx]
  250.  cmp ah, 'a'  ;Less than a?
  251.  jl cmky21  ;If so, don't capitalize.
  252.  cmp ah, 'z'+1 ;More than z?
  253.  jns cmky21
  254.  and ah, 137O ;Capitalize the letter.
  255. cmky21: cmp ah, al
  256.  je cmky3
  257.  jg cmky2y
  258.  jmp cmky41  ;Fail if ah preceeds al alphabetically.
  259. cmky2y: jmp cmky6  ;Not this keyword - try the next.
  260. cmky3: inc bx  ;We match here, how 'bout next char?
  261.  mov al, [bx]
  262.  cmp al, '$'  ;End of keyword?
  263.  jne cmky3x
  264.  jmp cmky7  ;Succeed.
  265. cmky3x: mov dl, al  ;Save al's char here.
  266.  call cmgtch
  267.  inc cl  ;Read in another char.
  268.  mov al, dl
  269.  cmp ah, 'a'
  270.  jl cmky31
  271.  cmp ah, 'z'+1
  272.  jns cmky31
  273.  and ah, 137O
  274. cmky31: cmp ah, esc+80H ;Escape Recognition (escape w/minus bit on)?
  275.  je cmky3y
  276.  cmp ah, '?'+80H ;A question mark?
  277.  je cmky3y
  278.  cmp ah, ' '+80H ;A space?
  279.  je cmky3y
  280.  cmp ah, cr+80H ;Carriage return?
  281.  je cmky3y
  282.  jmp cmky38
  283. cmky3y: mov cmkptr, bx ;Save bx here.
  284.  mov cmsiz, cx ;Save size info.
  285.  mov cmchr, ah ;Save char for latter.
  286.  call cmambg  ;See if input is ambiguous or not.
  287.   jmp cmky32 ;Succeeded (not ambiguous).
  288.  mov ah, cmchr
  289.  cmp ah, esc+80H ;Escape?
  290.  
  291. ; Display keyword choices and reparse if ambiguous  ;[8] begin
  292.  je cmky3a
  293.  cmp ah, ' '+80H ;Space?
  294.  jne cmky3b
  295. cmky3a: dec cmdptr  ;If so, back up over it.
  296. cmky3b: mov dx, offset cmin02 ;'One of the following:'
  297.  call tcmsgc
  298.  mov bx, cmkptr ;Find beginning of current keyword
  299.  mov cx, cmsiz
  300. cmky3c: dec bx  ;We are 'cl' characters into it
  301.  dec cl
  302.  jnz cmky3c
  303.  inc bx
  304.  mov cmkptr, bx ;Save beginning of keyword
  305. cmky3d: mov dl, tab  ;Precede each keyword with a tab
  306.  call bout
  307.  mov dx,cmkptr ;and display the keyword
  308.  call tmsg
  309.  mov bx, cmkptr ;Move to the next keyword
  310. cmky3e: inc bx
  311.  cmp byte ptr [bx], '$'
  312.  jnz cmky3e
  313.  add bx,4  ;Bypass '$', 2-byte return value, next length
  314.  mov di, cmkptr ;Get previous keyword for comparison
  315.  mov cmkptr, bx ;and save beginning of this keyword
  316.  mov cx, cmsiz ;Get number of characters to match
  317.  dec ch  ;Are we at end of table?
  318.  js cmky3g  ;  Yes, quit displaying
  319.  mov cmsiz, cx
  320. cmky3f: dec cl
  321.  jz cmky3d  ;This keyword also matches to 'cl' places
  322.  mov ah,[bx]  ;Compare this keyword to last
  323.  cmp ah,[di]
  324.  jne cmky3g
  325.  inc di
  326.  inc bx
  327.  jmps cmky3f
  328. cmky3g: jmp cmky50  ;Not equal or end of table, redisplay prompt
  329.         ;[8] end
  330.  
  331. cmky32: mov cx, cmsiz ;Restore info.
  332.  mov bx, cmkptr ;Our place in the keyword table.
  333. cmk32a: cmp cmchr, ' '+80H ;Space?   ;[8]
  334.  je cmky35
  335.  cmp cmchr, cr+80H ;Carriage return?
  336.  je cmky35
  337.  dec cmcptr  ;Pointer into buffer of input.
  338.  mov dx, cmcptr
  339. cmky33: mov ah, [bx] ;Get next char in keyword.
  340.  cmp ah, '$'  ;Are we done yet?
  341.  jz cmky34
  342.  mov di,dx
  343.  mov [di], ah
  344.  inc bx
  345.  inc dx
  346.  inc cmccnt
  347.  jmp cmky33
  348. cmky34: push bx  ;Save pointer to return value ;[8]
  349.  mov ah, ' '
  350.  mov di, dx
  351.  mov [di], ah ;Put a blank in the buffer.
  352.  inc dx
  353.  mov cmdptr, dx      ;[8] begin
  354.  cmp cmchr, '?'+80H ;Question mark?
  355.  jne cmk34a
  356.  mov ah, '?'
  357.  mov di,dx
  358.  mov [di], ah
  359.  inc dx
  360.  inc cmccnt
  361.  push dx
  362.  mov dl, 08H  ;Erase question mark from display
  363.  call bout
  364.  pop dx
  365. cmk34a: mov cx, cmcptr ;Remember where we were (for printing below).
  366.  mov cmcptr, dx ;Update our pointers.  ;[8] end
  367.  mov ah, '$'
  368.  mov di, dx
  369.  mov [di], ah ;Add '$' for printing.
  370.  mov dx, cx  ;Point to beginning of filled in data.
  371.  call tmsg
  372.  pop bx  ;Recover pointer to return value ;[8]
  373.  inc bx  ;Point to address we'll need.
  374.  mov bx, [bx]
  375.  cmp cmchr, 0BFH ;Question mark?  ;[8] begin
  376.  je cmk34b
  377.  mov cmaflg, 0  ;If esc, turn off action flag
  378.  mov cmsflg, 0FFH ;   and pretend they typed a space
  379. cmk34b: jmp rskp      ;[8] end
  380.  
  381. cmky35: mov ah, [bx] ;Find end of keyword.
  382.  inc bx
  383.  cmp ah, '$'
  384.  jne cmky35
  385.  mov bx, [bx] ;Address of next routine to call.
  386.  jmp rskp
  387.  
  388. cmky38: cmp ah, al
  389.  jne cmky6  ;Go to end of keyword and try next.
  390.  jmp cmky3
  391.  
  392. cmky4: and ah, 7FH  ;Turn off minus bit.
  393.  cmp ah, '?'  ;Need help?
  394.  je cmky5
  395.  cmp ah, ' '  ;Just a space - no error.
  396.  je cmky51
  397.  cmp ah, cr
  398.  je cmky51
  399.  cmp ah, esc  ;Ignore escape?
  400.  je cmky43
  401. cmky41: mov dx, offset cmer03
  402.  call tcrmsg
  403.  jmp prserr  ;Parse error - give up.
  404.  
  405. cmky43: mov dl, bell ;Ring a bell.
  406.  call bout
  407.  mov bx, cmcptr
  408.  dec bx
  409.  mov cmcptr, bx
  410.  mov cmdptr, bx
  411.  dec cmccnt  ;Don't count the escape.
  412.  mov cmaflg, 0 ;Reset action flag.
  413.  inc ch  ;Account for a previous 'dec'.
  414.  jmp cmky1  ;Start over.
  415.  
  416. cmky5: mov dx,cmhlp ;Print the help text.
  417.  call tcmsgc
  418. cmky50: call reprompt ;Reprint the prompt  ;[32a]
  419.  mov bx,cmdptr ;Get pointer into buffer.
  420.  mov al, '$'
  421.  mov [bx], al ;Add dollar sign for printing.
  422.  mov dx, offset cmdbuf
  423.  call tmsg
  424.  mov bx, cmdptr ;[8] begin
  425.  mov cmcptr, bx
  426.  mov dx, offset cmdbuf
  427.  sub bx, dx
  428.  mov cmccnt, bl
  429.  mov cmaflg, 0 ;Turn off the action flag.
  430.  jmp repars
  431.  
  432. cmky51: jmp prserr
  433.  
  434. cmky6: inc bx  ;Find end of keyword.
  435.  mov al, [bx]
  436.  cmp al, '$'
  437.  jne cmky6
  438.  add bx, 3  ;Beginning of next command.
  439.  mov dx, cmsptr ;Get old cmdptr.
  440.  mov cmdptr, dx ;Restore.
  441.  mov cmsflg, 0FFH
  442.  jmp cmky1  ;Keep trying.
  443.  
  444. cmky7: call cmgtch  ;Get char.
  445.  cmp ah, 0
  446.  js cmky71  ;Ok if a terminator.
  447.  dec bx
  448.  jmp cmky6  ;No match - try next keyword.
  449. cmky71: mov cmchr, ah      ;[8] begin
  450.  jmp cmk32a
  451.  
  452.  
  453. ; See if keyword is ambiguous from what the user has typed in.
  454.  
  455. cmambg: cmp ch, 0  ;Any keywords left to check?
  456.  jne cmamb0
  457.  ret   ;If not then not ambiguous.
  458. cmamb0: inc bx  ;Go to end of keyword ...
  459.  mov al, [bx] ;So we can check the next one.
  460.  cmp al, '$'
  461.  jne cmamb0
  462.  add bx, 4  ;Point to start of next keyword.
  463.  dec cl  ;Don't count escape.
  464.  mov dx, cmsptr ;Buffer with input typed by user.
  465. cmamb1: mov ah, [bx] ;Keyword char.
  466.  mov di, dx
  467.  mov al, [di] ;Input char.
  468.  cmp al, 'a'  ;Do capitalizing.
  469.  jl cmam11
  470.  cmp al, 'z'+1
  471.  jns cmam11
  472.  and al, 137O
  473. cmam11: cmp ah, al  ;Keyword bigger than input (alphabetically)?
  474.  jle cmamb2  ;No - keep checking.
  475.  ret   ;Yes - not ambiguous.
  476. cmamb2: inc bx  ;Advance one char.
  477.  inc dx
  478.  dec cl
  479.  jnz cmamb1
  480.  jmp rskp  ;Fail - it's ambiguous.
  481.  
  482. ; Parse an input file spec.
  483.  
  484. cmifil: mov wldflg, 0 ;Set to no wildcards.  ;[9]
  485.  mov bx, dx  ;Get the fcb address in bx.
  486.  mov cmfcb, bx ;Save it.
  487.  mov ch, 0  ;Initialize char count.
  488.  mov ah, 0
  489.  mov [bx], ah ;Set the drive to default to current.
  490.  inc bx
  491.  mov cmfcb2, bx
  492.  mov cl, ' '
  493. cmifi0: mov [bx], cl ;Blank the FCB.
  494.  inc bx
  495.  inc ah
  496.  cmp ah, 0BH  ;Twelve?
  497.  jl cmifi0
  498. cmifi1: call cmgtch  ;Get another char.
  499.  cmp ah, 0  ;Is it an action character.
  500.  jns cmifi2
  501.  and ah, 7FH  ;Turn off the action bit.
  502.  cmp ah, '?'  ;A question mark?
  503.  jne cmif12
  504.  mov cmaflg, 0 ;Blank the action flag.
  505. ; '?' is a legal character in wildcard filenames.  ;[9] begin
  506. ; Make ESC take its place by giving info instead of beeping. ;[32b]
  507.  mov wldflg, 0FFH ;Say we have a wildcard.
  508.  inc cmdptr
  509.  jmp cmifi8  ;Accept a '?'
  510. cmif12: cmp ah, esc  ;An escape?
  511.  jne cmif13
  512.  dec cmdptr
  513. cmf12a: mov cmaflg, 0 ;Turn off the action flag ;[9] end
  514.  dec cmcptr  ;Decrement the buffer pointer.
  515.  dec cmccnt  ;Decrement count.
  516.  mov dx, offset cmin01 ;Help message.
  517.  call tmsg
  518.  call reprompt ;Reprint the prompt  ;[32a]
  519.  mov bx, cmdptr
  520.  mov al, '$'
  521.  mov [bx], al ;Put in dollar sign for printing.
  522.  mov dx, offset cmdbuf
  523.  call tmsg
  524.  jmp repars
  525.  
  526. cmif13: mov ah, ch  ;It must be a terminator.
  527. ; The check for 0-length filenames will be performed by the ;[32c]
  528. ; caller so as to allow the file specification to be optional.
  529.  cmp ah, 0DH
  530.  js cmf3y
  531.  jmp cmifi9  ;If too long complain.
  532. cmf3y: jmp rskp  ;Otherwise we have succeeded.
  533. cmifi2: cmp ah, '.'
  534.  jne cmifi3
  535.  inc ch
  536.  mov ah, ch
  537.  cmp ah, 1H  ;Any chars yet?
  538.        jnz cmf2x
  539.  jmp cmifi9  ;No, give error.
  540. cmf2x: cmp ah, 0AH  ;Tenth char?
  541.        js cmf2y
  542.  jmp cmifi9  ;Past it, give an error.
  543. cmf2y: mov dl, 9H
  544.  mov dh, 0
  545.  mov bx, cmfcb
  546.  add bx, dx  ;Point to file type field.
  547.  mov cmfcb2, bx
  548.  mov ch, 9H  ;Say we've gotten nine.
  549.  jmp cmifi1  ;Get the next char.
  550. cmifi3: cmp ah, ':'
  551.  jne cmifi4
  552.  inc ch
  553.  cmp ch, 2H  ;Is it in right place for a drive?
  554.  je cmif3x
  555.  jmp cmifi9  ;If not, complain.
  556. cmif3x: mov ch, 0  ;Reset char count.
  557.  mov bx, cmfcb2
  558.  dec bx
  559.  mov ah, [bx] ;Get the drive name.
  560.  cmp ah,'A'  ;Make sure it's in range A-P ;[9] begin
  561.  jb cmif3y
  562.  cmp ah,'P'
  563.  jbe cmif3z
  564. cmif3y: jmp cmifi9
  565. cmif3z: sub ah,'@'  ;Get the drive number.  ;[9] end
  566.  mov cmfcb2, bx
  567.   mov bx, cmfcb
  568.  mov [bx], ah ;Put it in the fcb.
  569.  jmp cmifi1
  570. cmifi4: cmp ah, '*'
  571.  jne cmifi7
  572.  mov ah, ch
  573.  cmp ah, 8H  ;Is this in the name or type field?
  574.  jz cmifi9  ;If its where the dot should be give up.
  575.  jns cmifi5  ;Type.
  576.  mov cl, 8H  ;Eight chars.
  577.  jmp cmifi6
  578. cmifi5: mov cl, 0CH  ;Three chars.
  579. cmifi6: mov wldflg, 0FFH ;Remember we had a wildcard.
  580.  mov bx, cmfcb2 ;Get a pointer into the FCB.
  581.  mov ah, '?'
  582.  mov [bx], ah ;Put a question mark in.
  583.  inc bx
  584.  mov cmfcb2, bx
  585.  inc ch
  586.  mov ah, ch
  587.  cmp ah, cl
  588.  jl cmifi6  ;Go fill in another.
  589.  jmp cmifi1  ;Get the next char.
  590. cmifi7:
  591.  
  592. cmif7x: cmp ah,'0'
  593.  jb cmif8x
  594.  cmp ah,'9'
  595.  jbe cmifi8
  596.  cmp ah,'A'
  597.  jb cmif8x
  598.  cmp ah,'Z'
  599.  jbe cmifi8
  600.  cmp ah,'a'
  601.  jb cmif8x
  602.  cmp ah,'z'
  603.  ja cmif8x      ;[9] end
  604.  and ah, 137O ;Capitalize.
  605. cmifi8: mov bx, cmfcb2 ;Get the pointer into the FCB.
  606.  mov [bx], ah ;Put the char there.
  607.  inc bx
  608.  mov cmfcb2, bx
  609.  inc ch
  610.  jmp cmifi1
  611.  
  612. cmif8x: push es  ;Check list of special characters
  613.  mov cx, ds  ;   which are legal in filenames
  614.  mov es, cx  ;Scan uses ES register.
  615.  mov di, offset spchar ;Special chars.
  616.  mov cx, 20  ;Twenty of them.
  617.  mov al, ah  ;Char is in al.
  618.  repnz scasb  ;Search string for input char.
  619.  cmp cx, 0  ;Was it there?
  620.  pop es
  621.  jnz cmifi8
  622.  
  623. cmifi9: mov dx, offset cmer02
  624.  call tcrmsg
  625.  ret
  626.  
  627. cmofil: jmp cmifil  ;For now, the same as CMIFI.
  628.  
  629. ; Parse arbitrary text up to a CR.  Put chars into data buffer sent to
  630. ; the host (pointed to by BX).  Return updated pointer in BX and
  631. ; input size in AH.
  632.  
  633. cmtext: mov cmptab, bx ;Save pointer to data buffer.
  634.  mov cl, 0  ;Init the char count.
  635. cmtxt1: call cmgtch  ;Get a char.
  636.  cmp ah, 0  ;Terminator?
  637.  jns cmtxt5  ;Nope, put into the buffer.
  638.  and ah, 07FH
  639.  cmp ah, esc  ;An escape?
  640.  jne cmtxt2
  641.  mov dl, bell ;Ring a bell.
  642.  call bout
  643.  mov cmaflg, 0 ;Reset action flag.
  644.  dec cmcptr  ;Move pointer to before the escape.
  645.  dec cmdptr
  646.  dec cmccnt  ;Decrement count.
  647.  jmp cmtxt1  ;Try again.
  648. cmtxt2: cmp ah, '?'  ;Asking a question?
  649.  jz cmtx2y      ;[32b]
  650.  cmp ah, ' '  ;Space?    ;[32b]
  651.  jz cmtxt3
  652.  cmp ah, ff  ;Formfeed?
  653.  jne cmtx2x
  654.  call clrscr
  655. cmtx2x: mov ah, cl  ;Return count in AH.
  656.  mov bx, cmptab ;Return updated pointer.
  657.  jmp rskp
  658. cmtx2y: inc cmdptr      ;[32b]
  659. cmtxt3: mov cmaflg, 0 ;Reset action flag to zero.
  660. cmtxt5: inc cl  ;Increment the count.
  661.  mov bx, cmptab ;Pointer into destination array.
  662.  mov [bx], ah ;Put char into the buffer.
  663.  inc bx
  664.  mov cmptab, bx
  665.  jmp cmtxt1
  666.  
  667.  
  668. cminbf: push dx
  669.  push bx
  670.  mov cx, dx  ;Save value here too.
  671.  mov ah, cmaflg ;Is the action char flag set?
  672.  cmp ah, 0
  673.  je cminb1
  674.  jmp cminb9  ;If so get no more chars.
  675. cminb1: inc cmccnt  ;Increment the char count.
  676.  call bin
  677.  mov ah, al  ;Keep char in 'ah'.
  678.  mov bx, cmcptr ;Get the pointer into the buffer.
  679.  mov [bx], ah ;Put it in the buffer.
  680.  inc bx
  681.  mov cmcptr, bx
  682.  cmp ah, 15h  ;Is it a ^U?
  683.  je cmnb12      ;[30b]
  684.  cmp ah, 18h  ;     or ^X?   ;[30b]
  685.  jne cminb2
  686. cmnb12: call clrlin      ;[30c]
  687.  call repmt2  ;Reprint the prompt (no crlf) ;[32a]
  688.  mov bx, offset cmdbuf
  689.  mov cmcptr, bx ;Reset the point to the start.
  690.  mov cmccnt, 0 ;Zero the count.
  691.  mov dx, cx  ;Preserve original value of dx.
  692.  jmp repars  ;Go start over.
  693. cminb2: cmp ah, 08h  ;Is it a backspace?  ;[30b]
  694.  jz cminb3
  695.  cmp ah, 7fh  ;     or delete?  ;[30b]
  696.  jne cminb4
  697.  mov dx, offset delstr
  698.  call tmsg
  699. cminb3: mov ah, cmccnt ;Decrement the char count by two.
  700.  dec ah
  701.  dec ah
  702.  cmp ah, 0  ;Have we gone too far?
  703.  jns cmnb32  ;If not proceed.
  704.  mov dl, bell ;Ring the bell.
  705.  call bout
  706.  jmp cmnb12  ;Go reprint prompt and reparse.
  707. cmnb32: mov cmccnt, ah ;Save the new char count.
  708.  mov dx, offset clrspc ;Erase the character.
  709.  call tmsg
  710.  mov bx, cmcptr ;Get the pointer into the buffer.
  711.  dec bx  ;Back up in the buffer.
  712.  dec bx
  713.  mov cmcptr, bx
  714.  jmp repars  ;Go reparse everything.
  715. cminb4: cmp ah, '?'  ;Is it a question mark.
  716.  jz cminb6
  717.  cmp ah, esc  ;Is it an escape?
  718.  jz cminb6
  719.  cmp ah, cr  ;Is it a carriage return?
  720.  jz cminb5
  721.  cmp ah, lf  ;Is it a line feed?
  722.  jz cminb5
  723.  cmp ah, ff  ;Is it a formfeed?
  724.  jne cminb7
  725.  call clrscr
  726. cminb5: mov ah, cmccnt ;Have we parsed any chars yet?
  727.  cmp ah, 1
  728.  jnz cminb6
  729.  jmp prserr  ;If not, just start over.
  730. cminb6: mov cmaflg, 0FFH ;Set the action flag.
  731.  jmp cminb9
  732. cminb7: jmp cminb1  ;Get another char.
  733.  
  734. cminb9: pop bx
  735.  pop dx
  736.  ret
  737.  
  738. cmgtch: push cx
  739.  push bx
  740.  push dx
  741. cmgtc1: mov ah, cmaflg
  742.  cmp ah, 0  ;Is it set.
  743.  jne cmgt10
  744.  call cminbf  ;If the action char flag is not set get more.
  745. cmgt10: mov bx, cmdptr ;Get a pointer into the buffer.
  746.  mov ah, [bx] ;Get the next char.
  747.  inc bx
  748.  mov cmdptr, bx
  749.  cmp ah, ' '  ;Is it a space?
  750.  jz cmgtc2
  751.  cmp ah, tab  ;Or a tab?
  752.  jne cmgtc3
  753. cmgtc2: mov ah, cmsflg ;Get the space flag.
  754.  cmp ah, 0  ;Was the last char a space?
  755.  jne cmgtc1  ;Yes, get another char.
  756.  mov cmsflg, 0FFH ;Set the space flag.
  757.  mov ah, ' '
  758.  pop dx
  759.  pop bx
  760.  jmp cmgtc5
  761. cmgtc3: mov cmsflg, 0 ;Zero the space flag.
  762.  pop dx
  763.  pop bx
  764.  cmp ah, esc
  765.  jz cmgtc5
  766.  cmp ah, '?'  ;Is the user curious?
  767.  jz cmgtc4
  768.  cmp ah, cr
  769.  jz cmgtc4
  770.  cmp ah, lf
  771.  jz cmgtc6      ;[8]
  772.  cmp ah, ff
  773.  je cmgtc6      ;[8]
  774.  pop cx
  775.  ret   ;Not an action char, just return.
  776. cmgtc6: mov ah, cr  ;Convert lf & ff to cr  ;[8]
  777. cmgtc4: dec cmdptr
  778. cmgtc5: or ah, 80H  ;Make the char negative to indicate
  779.  pop cx  ;it is a terminator.
  780.  ret
  781.  
  782. ; Parse a single character ;[25] start
  783. ; this is for setting the escape character
  784.  
  785. cmchar:
  786.  call cmgtch  ;get a char
  787.  cmp ah, 0
  788.  jns cmchr1  ;go if not negative
  789.  and ah, 7FH  ;turn off sign bit
  790.  cmp ah, '?'  ;user curious?
  791.  jne cmchr0  ;no - an error
  792.  mov dx, bx  ;help string pointer was in bx
  793.  call tmsg  ;print help stuff  ;[32a]
  794.  call reprompt ;Reprint the prompt  ;[32a]
  795.  mov bx, cmdptr
  796.  mov al, '$'
  797.  mov [bx], al ;add a "$" to what was typed
  798.  mov dx, offset cmdbuf
  799.  call tmsg  ;type it again
  800.  dec cmcptr  ;but don't leave "$" ..
  801.  dec cmccnt  ;in buffer
  802.  mov cmaflg, 0 ;turn off action flag
  803.  jmp repars  ;try again
  804. cmchr0: mov dx, offset erms20
  805.  call tcrmsg  ;"illegal value" error
  806.  ret
  807. cmchr1: mov temp, ax
  808.  call cmcfrm  ;get a confirm
  809.   jmp cmchr0  ;or else complain
  810.  mov ax, temp
  811.  mov bl, ah  ;return the character
  812.  jmp rskp
  813.  
  814. ; parse a (decimal) number.  Maximum allowed value in dx
  815. cmnumr:
  816.  mov temp1, 001H ;initial multiplier of 1
  817.  mov temp2, dx ;storage for maximum
  818.  mov temp, 0  ;zero running sum
  819.  call cmgtch  ;get a char
  820.  cmp ah, 0
  821.  jns cmnum1  ;go if not negative
  822.  and ah, 7FH  ;turn off sign bit
  823.  cmp ah, '?'  ;user curious?
  824.  jne cmnum0  ;no - an error
  825.  mov dx, bx  ;help string pointer was in bx
  826.  call tmsg  ;print help stuff  ;[32a]
  827.  call reprompt ;Reprint the prompt  ;[32a]
  828.  mov bx, cmdptr
  829.  mov al, '$'
  830.  mov [bx], al ;add a "$" to what was typed
  831.  mov dx, offset cmdbuf
  832.  call tmsg  ;type it again
  833.  dec cmcptr  ;but don't leave "$" ..
  834.  dec cmccnt  ;in buffer
  835.  mov cmaflg, 0 ;turn off action flag
  836.  jmp repars  ;try again
  837.  call cmcfrm  ;get character (or confirm)
  838.   jmp cmnum1  ;got a character
  839.     ;fall through - too early for confirm
  840. cmnum0: mov dx, offset erms20
  841.  call tcrmsg  ;"illegal value" message
  842.  ret
  843. cmnum1: sub ah, 030H ;ASCII -> binary
  844.  jl cmnum0  ;too small
  845.  cmp ah, 09H
  846.  jg cmnum0  ;too big
  847.  mov bl, ah
  848.  mov bh, 0  ;get number in low part of bx
  849.  mov ax, temp ;get running sum
  850.  mul temp1  ;multiply by decimal place value
  851.  add ax, bx  ;add in this digit
  852.  cmp ax, temp2 ;over the maximum
  853.  jg cmnum0  ;yes - error
  854.  mov temp, ax ;save running sum
  855.  mov ax, temp1 ;get multiplier
  856.  mul cmten  ;multiply multiplier by 10
  857.  mov temp1, ax ;save it
  858.  call cmcfrm  ;get another character
  859.   jmp cmnum1  ;not terminator - process it
  860.  mov bx, temp ;get value of number
  861.  jmp rskp  ;return success
  862.       ;[25] end
  863.