home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / trs80model4 / m4cmd.asm < prev    next >
Assembly Source File  |  1986-10-21  |  17KB  |  610 lines

  1. ;    M4CMD/ASM
  2. ;
  3. ;    Jumping to this location will cause the return address on the
  4. ;    stack to be incremented by 3, and then jumped to.  This is used
  5. ;    in several places to make error handling easier.  Code using
  6. ;    this mechanism might look like.
  7. ;
  8. ;    ROUTINE:    EQU    $
  9. ;            ...
  10. ;            CALL    SPACK
  11. ;            JP    ABORT    ;Die on an error
  12. ;            ...        ;Continue normally
  13. ;
  14. ;            RET
  15. ;    SPACK:        EQU    $
  16. ;            ...
  17. ;            LD    A,B    ;Check result
  18. ;            CP    C    ;Must be equal
  19. ;            RET    NZ    ;Error if not equal
  20. ;            LD    A,(LEN)    ;Get the length for return
  21. ;            JP    RSKP    ;Normal return
  22. ;
  23. RSKP    POP    HL        ;GET THE RETURN ADDRESS.
  24.     INC    HL        ;INCREMENT BY THREE.
  25.     INC    HL
  26.     INC    HL
  27.     JP    (HL)        ;Return to return+3 bytes
  28. ;
  29. ;    Output the value in HL as an ASCII decimal string
  30. ;
  31. NOUT    EQU    $
  32.     PUSH    HL        ;Save the registers
  33.     PUSH    BC
  34.     PUSH    DE
  35.     LD    DE,NBUFF    ;Get the string buffer
  36.     PUSH    DE        ;Save the address
  37.     CALL    XHEXDEC        ;Convert from binary to ASCII
  38.     EX    DE,HL        ;HL = end of buffer + 1
  39.     LD    (HL),EOS    ;Add EOS for printing
  40.     POP    HL        ;Restore the starting address
  41.     LD    A,' '        ;Remove leading spaces
  42. NOUT1    IFANOT    (HL),NOUT2    ;Go if not blank
  43.     INC    HL        ;Point to next character
  44.     JR    NOUT1        ;Back to top of loop
  45. NOUT2    EX    DE,HL        ;DE is now start of string to print
  46.     CALL    PRTSTR        ;Print the number
  47.     POP    DE        ;Restore the registers
  48.     POP    BC
  49.     POP    HL
  50.     RET
  51. ;
  52. ;
  53. ;    Command parsing routines
  54. ;
  55. ;    This routine prints the prompt pointed to by DE, and then
  56. ;    sets up the appropriate values to allow a reparse at any point
  57. ;
  58. PROMPT    POP    HL        ;Get the return address
  59.     PUSH    HL        ;Put it back
  60.     LD    (CMRPRS),HL    ;Save it as the reparse address
  61.     LD    (CMOSTP),SP    ;Save the stack pointer as well
  62.     LD    (CMPRMP),DE    ;Save the prompt to print
  63.     LD    HL,CMDBUF    ;Get the start of the command buffer
  64.     LD    (CMCPTR),HL    ;Initialize the pointer into it
  65.     LD    (CMDPTR),HL    ;Save 2 copies
  66.     XOR    A
  67.     LD    (CMAFLG),A    ;Zero the flags
  68.     LD    (CMCCNT),A    ;No characters
  69.     CPL            ;Make it non zero
  70.     LD    (CMSFLG),A    ;Set these flags
  71.     LD    A,(TAKFLG)    ;Check if take is active
  72.     IFZ    PRMT10        ;Jump if not
  73.     LD    A,(TAKLOG)    ;Is the take-file display flag set?
  74.     IFZ    PRMT20        ;Jump if not
  75. PRMT10    CALL    NEWLIN        ;Get a newline
  76.     LD    DE,(CMPRMP)    ;Print the prompt
  77.     CALL    PRTSTR
  78. PRMT20    RET            ;Return to the caller
  79. ;
  80. ;    Come to here to initiate a reparse
  81. ;
  82. REPARS    LD    SP,(CMOSTP)    ;GET THE OLD STACK POINTER.
  83.     LD    HL,CMDBUF
  84.     LD    (CMDPTR),HL
  85.     LD    A,0FFH        ;TRY IT THIS WAY (DAPHNE.)
  86.     LD    (CMSFLG),A
  87.     LD    HL,(CMRPRS)    ;GET THE REPARSE ADDRESS.
  88.     JP    (HL)        ;GO THERE.
  89. ;
  90. ;THIS ADDRESS CAN BE JUMPED TO ON A PARSING ERROR.
  91. ;
  92. PRSERR    LD    SP,(CMOSTP)    ;GET THE OLD STACK POINTER.
  93.     LD    HL,CMDBUF
  94.     LD    (CMCPTR),HL    ;INITIALIZE THE COMMAND POINTER.
  95.     LD    (CMDPTR),HL
  96.     CALL    NEWLIN
  97.     XOR    A
  98.     LD    (CMAFLG),A    ;ZERO THE FLAGS.
  99.     LD    (CMCCNT),A
  100.     LD    A,0FFH        ;TRY IT THIS WAY (DAPHNE.)
  101.     LD    (CMSFLG),A
  102.     LD    DE,(CMPRMP)    ;GET THE PROMPT.
  103.     CALL    PRTSTR
  104.     LD    HL,(CMRPRS)
  105.     JP    (HL)
  106. ;
  107. ;This routine parses the specified function in A.  Any additional
  108. ;information is in DE and HL.
  109. ;    Returns to RETURN+3 on success
  110. ;    Returns to RETURN on failure.  (Assumes that a JP follows CALL)
  111. ;
  112. COMND    LD    (CMSTAT),A    ;Save what we are presently parsing.
  113.     CALL    CMINBF        ;Get chars until action or erase char.
  114.     CP    CMNUM        ;Is the function "PARSE a number"?
  115.     JP    Z,CMDNUM    ;Jump if so
  116.     CP    CMCFM        ;Parse a confirm?
  117.     JP    Z,CMCFRM    ;Jump if so
  118.     CP    CMKEY        ;Parse a keyword from a table?
  119.     JP    Z,CMKEYW    ;Jump if so
  120.     CP    CMIFI        ;Parse a file spec?
  121.     JP    Z,CMIFIL    ;If so jump
  122.     CP    CMIFIN        ;Other file type?
  123.     JP    Z,CMIFIL    ;If so use same routine
  124.     CP    CMOFI        ;ditto
  125.     JP    Z,CMIFIL
  126.     CP    CMTXT        ;Parse a text string?
  127.     JP    Z,CMTEXT    ;If so jump
  128.     LD    DE,CMER00    ;Otherwise parser calling error
  129.     CALL    PRTSTR        ;So print a message
  130.     RET            ;And return error
  131. ;
  132. ;This routine parses arbitrary text up to a <ENTER>
  133. ;
  134. ;    DE=address of text buffer
  135. ;
  136. ;    A=number of characters typed (zero or more) on return
  137. ;
  138. CMTEXT    EX    DE,HL          ;Put the pointer to the buffer in HL
  139.     LD    (CMPTAB),HL    ;Save the pointer
  140.     LD    B,0        ;Initialize the count to zero
  141. CMTXT1    CALL    CMGTCH        ;Get a character
  142.     OR    A        ;Test the high bit for some terminator
  143.     JP    P,CMTXT5    ;If not then jump
  144.     AND    7FH        ;Turn off the high bit
  145.     CP    ESC        ;Is it escape
  146.     RET    Z        ;Return failure if so
  147. CMTXT2    IFA    '?',CMTXT7    ;Jump if the user needs help
  148.     IFA    ' ',CMTXT5    ;If blank, add it to text
  149.     LD    A,B        ;Get the counter
  150.     LD    HL,(CMPTAB)    ;Get the updated pointer
  151.     LD    (HL),CR        ;Put the terminator in
  152.     EX    DE,HL        ;Move ending pointer to DE
  153.     JP    RSKP        ;Return success
  154. ;
  155. CMTXT3    LD    HL,CMAFLG    ;Point to the action flag
  156.     LD    (HL),0        ;Reset it
  157. CMTXT5    INC    B        ;Add one to the count of characters
  158. CMTXT6    LD    HL,(CMPTAB)    ;Get the pointer
  159.     PUTHL    A        ;Add the character and increment
  160.     LD    (CMPTAB),HL    ;Save the update pointer
  161.     JR    CMTXT1        ;Go get another character
  162. ;
  163. CMTXT7    LD    DE,TXTHLP    ;Get the help message
  164.     CALL    REPRNT        ;Print the message
  165.     JP    REPARS        ;Jump to the reparse
  166. ;
  167. ;This routine parses an input number in ASCII decimal
  168. ;
  169. CMDNUM    LD    B,0        ;Reset the character count
  170.     LD    HL,0        ;Initialize the value to zero
  171.     LD    (THEVAL),HL
  172. CMNM10    CALL    CMGTCH        ;Get a character
  173.     OR    A        ;Check for high bit set terminator
  174.     JP    P,CMNM50    ;Jump if not
  175.     AND    7FH        ;Trim the high bit
  176.     CP    ESC        ;Is it ESCAPE (abort)
  177.     RET    Z        ;Return error if so
  178. CMNM20    IFA    '?',CMNM70    ;Go if the user needs help
  179.     LD    A,B        ;Get the count
  180.     LD    DE,(THEVAL)    ;Get the number found
  181.     JP    RSKP        ;Return success
  182. ;
  183. CMNM50    INC    B        ;Add one to count of characters
  184.     PUSH    HL        ;Save the values
  185.     PUSH    DE
  186.     PUSH    BC
  187.     LD    HL,(THEVAL)    ;Get the current number
  188.     LD    C,10        ;Multiply by 10
  189.     PUSH    AF        ;Save AF too
  190.     CALL    XMUL16        ;Multiply 8 bit by 16 bit
  191.     LD    H,L        ;Move the 24 bit result into HL as 16
  192.     LD    L,A
  193.     POP    AF        ;Get the character to add
  194.     SUB    48        ;Convert to a binary number
  195.     JP    P,CMNM60    ;Jump if no underflow
  196. CMNM55    POP    BC        ;Restore the regs
  197.     POP    DE
  198.     POP    HL
  199.     LD    DE,ERMES2    ;Print error message
  200.     CALL    PRTSTR
  201.     JP    KERMIT        ;GET A NEW COMMAND
  202. ;
  203. CMNM60    IFAGE    10,CMNM55    ;Jump if too big
  204.     LD    C,A        ;Get it into BC for 16 bit MATH
  205.     LD    B,0        ;Zero the MSB
  206.     ADD    HL,BC        ;Compute the new number
  207.     LD    (THEVAL),HL    ;Save the result
  208.     POP    BC        ;Restore the registers
  209.     POP    DE
  210.     POP    HL
  211.     JR    CMNM10        ;Loop on
  212. ;
  213. CMNM70    LD    DE,NUMHLP    ;Get the HELP message
  214.     CALL    REPRNT        ;Print the message, and reprint prompt
  215.     JP    REPARS        ;Plus the rest of the text, and restart
  216. ;
  217. ;    Get a confirmation of the command by accepting only <ENTER>
  218. ;
  219. CMCFRM    CALL    CMGTCH        ;GET A CHARACTER FROM THE BUFFER
  220.     OR    A        ;WHAT WAS IT, CONTROL?
  221.     RET    P        ;NOPE, SO EXIT VIA ERROR RETURN
  222.     AND    7FH        ;STRIP THE SIGN BIT FLAG
  223.     IFANOT    '?',CMCFR3    ;Go if not help request
  224.     LD    DE,CMIN00    ;TELL THEM NO MORE HELP
  225.     CALL    REPRNT        ;PRINT THE MESSAGE
  226.     JP    REPARS        ;PRINT THE MESSAGE AND THE PROMPT AGAIN
  227. CMCFR3    CP    ESC        ;IS IT ABORT?
  228.     RET    Z        ;TAKE ERROR EXIT IF SO
  229.     JP    RSKP        ;TAKE NORMAL RETURN
  230. ;THIS ROUTINE PRINTS THE MESSAGE IN DE AND SETS UP FOR A REPARSE
  231. REPRNT    CALL    PRTSTR
  232.     XOR    A
  233.     LD    (CMAFLG),A
  234.     CALL    NEWLIN
  235.     LD    DE,(CMPRMP)
  236.     CALL    PRTSTR
  237.     LD    HL,(CMCPTR)
  238.     DEC    HL
  239.     LD    (HL),EOS
  240.     LD    (CMCPTR),HL
  241.     LD    DE,CMDBUF
  242.     CALL    PRTSTR
  243.     RET
  244. ;THIS ROUTINE PARSES A KEYWORD FROM THE TABLE POINTED
  245. ;TO IN DE.  THE FORMAT OF THE TABLE IS AS FOLLOWS
  246. ;
  247. ;ADDR    DB    N    Where N is the number of entries in the table
  248. ;    DB    K    Where K is 2+length of longest keyword.
  249. ;    Repeated for each entry in the table...
  250. ;    DB    M        Where M is the length of the keyword
  251. ;    DB    'STRING',EOS    Where string is the KEYWORD.
  252. ;    DB    A,B           Where A & B are pieces of DATA
  253. ;                to be returned, (Must be two bytes worth)
  254. ;
  255. ;THE KEYWORDS MUST BE IN ALPHABETICAL ORDER.
  256. ;**** NOTE  THE DATA VALUE A IS RETURNED IN REGISTERS A AND E.  THE
  257. ;****    DATA VALUE B IS RETURNED IN REGISTER D.  THIS ALLOWS THE TWO DATA
  258. ;BYTES TO BE STORED AS
  259. ;DW    XXX
  260. ;AND RESULT IN A CORRECTLY FORMATTED 16-BIT VALUE IN REGISTER PAIR
  261. ;DE.
  262. CMKEYW    LD    (CMPTAB),DE    ;SAVE THE BEGINNING OF KEYWORD for ?
  263.     LD    A,(DE)        ;GET THE NUMBER OF ENTRIES IN THE TABLE.
  264.     LD    B,A        ;SAVE IN B
  265.     INC    DE        ;Point past the keyword count
  266.     INC    DE        ;POINT PAST THE MAX LENGTH NUMBER
  267.     LD    (CMKPTR),DE    ;Save it for later
  268.     LD    HL,(CMDPTR)    ;Save the command buffer pointer
  269.     LD    (CMSPTR),HL
  270. CMKEY2    LD    A,B        ;Get the keyword counter
  271.     OR    A        ;ANY LEFT?
  272.     RET    Z        ;IF NOT WE FAILED.
  273.     LD    HL,(CMKPTR)    ;Get the current keyword pointer
  274.     INC    HL        ;Skip the visibility
  275.     LD    E,(HL)        ;Get the length of the keyword
  276.     INC    HL        ;Skip the length
  277. CMKEY3    DEC    E        ;DECREMENT THE NUMBER OF CHARS LEFT.
  278.     LD    A,E
  279.     CP    -1
  280.     JP    M,CMKEY5    ;IF SO GO TO THE NEXT.
  281.     CALL    CMGTCH        ;GET A CHAR.
  282.     OR    A        ;IS IT A TERMINATER?
  283.     JP    P,CMKEY4    ;IF POSITIVE, IT IS NOT.
  284.     AND    7FH        ;TURN OFF THE MINUS BIT.
  285.     CP    '?'        ;Is this help?
  286.     JP    NZ,CMKY35
  287.     PUSH    HL        ;SAVE HL FOR A SEC
  288.     PUSH    DE
  289.     XOR    A
  290.     LD    (CMAFLG),A    ;TURN OFF THE ACTION FLAG.
  291.     LD    DE,HLPMES    ;PRINT ONE OF THE FOLLOWING...
  292.     CALL    PRTSTR
  293.     LD    HL,CMCCNT    ;DECREMENT THE CHAR COUNT.
  294.     DEC    (HL)
  295.     POP    DE
  296.     POP    HL
  297.     LD    HL,(CMPTAB)    ;GET THE START OF THE KEYWORD TABLE
  298.     LD    B,(HL)        ;B IS HOW MANY IN THE TABLE
  299.     INC    HL        ;Point at the column spacing value
  300.     LD    A,(HL)        ;Get the length
  301.     LD    (MAXLEN),A    ;Save it for later
  302.     XOR    A
  303.     LD    (CURCOL),A    ;Set column to starting column
  304.     INC    HL        ;Point at the visible attribute
  305. CM1010    LD    A,(HL)        ;Get the visibility
  306.     LD    (VISIBLE),A
  307.     INC    HL        ;POINT AT THE FIRST ENTRY
  308.     LD    C,(HL)        ;C IS HOW MANY CHARACTERS IN NAME
  309.     LD    A,C        ;SAVE THE LENGTH FOR LATER
  310.     LD    (CURLEN),A
  311.     INC    HL        ;POINT AT THE TEXT FOLLOWING
  312.     LD    (CMKPTR),HL    ;SAVE THE ADDRESS TO PRINT FROM ON MATCH
  313.     LD    DE,(CMSPTR)    ;GET THE ADDRESS OF THE TYPED KEYWORD
  314. CM1020    LD    A,(DE)        ;GET A CHARACTER
  315.     IFA    '?',CM1040    ;Go if request for help
  316.     CALL    CAPTAL        ;MAKE SURE LETTERS ARE UPPER CASE
  317.     INC    DE        ;POINT TO THE NEXT.
  318.     CP    (HL)        ;SAME AS IN KEYWORD TABLE?
  319.     INC    HL        ;POINT TO THE NEXT
  320.     JR    NZ,CM1050    ;JUMP IF NO MATCH
  321.     DEC    C        ;ONE LESS CHARACTER IN THE KEYWORD
  322.     JP    P,CM1020
  323.     LD    A,(DE)
  324.     IFA    '?',CM1040    ;Jump if help request
  325.     CP    0        ;Set flags to P,NZ
  326.     JP    CM1050        ;Join other code
  327. CM1040    EQU    $
  328.     LD    A,(VISIBLE)    ;Is this a visible command?
  329.     IFZ    CM1045        ;Jump if it is not
  330.     PUSH    DE        ;SAVE THE REGS
  331.     PUSH    HL
  332.     PUSH    BC
  333.     LD    DE,(CMKPTR)    ;Get the string
  334.     CALL    STRLEN        ;Get length into BC
  335.     LD    A,(MAXLEN)    ;Get the padded length
  336.     LD    B,A        ;Save it for now
  337.     LD    A,(CURCOL)    ;Get current screen column
  338.     ADD    A,B        ;Compute new column
  339.     LD    B,A        ;Save it
  340.     LD    A,(MAXCOL)    ;Get right margin
  341.     IFALT    B,CM1042    ;Are we passed the edge? Jump if so
  342.     LD    A,B        ;Get new column
  343.     LD    (CURCOL),A    ;Save it
  344.     LD    A,(MAXLEN)
  345.     JR    CM1043        ;Join code
  346. CM1042    CALL    NEWLIN        ;Print a newline
  347.     LD    A,(MAXLEN)    ;Get the padded length
  348.     LD    (CURCOL),A    ;Set new position
  349. CM1043    SUB    C        ;Compute blanks to print
  350.     LD    C,A        ;Put it into C
  351.     PUSH    BC        ;Save count for now
  352.     LD    DE,(CMKPTR)    ;Get the string to print
  353.     CALL    PRTSTR        ;Print the keyword
  354.     POP    BC        ;Restore count
  355. CM1044    LD    A,' '        ;Get a blank
  356.     CALL    CONOUT        ;Display it
  357.     DEC    C        ;Decrement counter
  358.     JR    NZ,CM1044    ;Jump if not there
  359.     POP    BC        ;RESTORE THE REGS
  360.     POP    HL
  361.     POP    DE
  362. CM1045    LD    A,3        ;SKIP OVER THE EOS AND THE DISCRIPTOR
  363.     ADD    A,C        ;PLUS THE CHARACTERS LEFT IN THE STRING
  364.     LD    E,A        ;PUT IT IN DE TO ADD
  365.     LD    D,0        ;MAKE IT A BYTE VALUE IN 16 BITS
  366.     ADD    HL,DE        ;GOT THE NEW ADDRESS
  367.     DJNZ    CM1010        ;GET THE NEXT
  368.     JR    CM1190        ;END OF THE TABLE
  369. CM1050    DEC    HL        ;CORRECT HL FROM LAST INCREMENT
  370.     JP    P,CM1045    ;IF (TABLE) > (COMMAND) KEEP LOOKING
  371.     JR    Z,CM1045
  372.     XOR    A        ;RESET THE ACTION FLAG
  373.     LD    (CMAFLG),A
  374. CM1190    CALL    NEWLIN        ;PRINT A NEW LINE
  375. CM1200    CALL    NEWLIN        ;PRINT A NEW LINE
  376.     LD    DE,(CMPRMP)    ;GET THE PROMPT TO REPRINT
  377.     CALL    PRTSTR        ;PRINT IT
  378.     LD    HL,(CMDPTR)    ;GET THE END OF THE COMMAND LINE
  379.     LD    (HL),EOS    ;TERMINATOR FOR PRINTING
  380.     LD    HL,(CMCPTR)    ;GET THE LAST CHARACTER
  381.     DEC    HL
  382.     LD    (CMCPTR),HL    ;IGNORE THE '?' AT THE END
  383.     LD    DE,CMDBUF    ;GET THE START OF THE BUFFER
  384.     CALL    PRTSTR        ;PRINT THE COMMAND LINE
  385.     JP    REPARS        ;REPARSE THE ENTIRE LINE
  386. CMKY35    CP    ESC
  387.     RET    Z
  388.     PUSH    HL
  389.     PUSH    DE
  390.     CALL    CMAMBG
  391.     JP    CMKY36
  392.     LD    HL,(CMCPTR)    ;GET THE END OF THE COMMAND
  393.     LD    BC,CMDBUF    ;GET THE START OF THE BUFFER
  394.     OR    A        ;RESET THE CARRY
  395.     SBC    HL,BC        ;COMPUTE THE OFFSET
  396.     LD    DE,CMER01
  397.     CALL    PRTSTR        ;SAY ITS AMBIGUOUS.
  398.     JP    PRSERR        ;GIVE UP.
  399. CMKY36    POP    DE
  400.     POP    HL
  401. CMKY37    INC    E        ;ADD ONE IN CASE IT IS NEGATIVE.
  402.     LD    D,0
  403.     ADD    HL,DE        ;INCREMENT PAST THE KEYWORD.
  404.     INC    HL        ;PAST THE EOS.
  405.     LD    E,(HL)        ;GET THE DATA.
  406.     INC    HL
  407.     LD    D,(HL)
  408.     LD    A,E
  409.     JP    RSKP
  410. CMKEY4    CALL    CAPTAL        ;MAKE IT UPPER CASE IF LOWER    
  411. CMKY41    CP    (HL)        ;Check the next character
  412.     JR    NZ,CMKEY5
  413.     INC    HL
  414.     JP    CMKEY3
  415. CMKEY5    LD    D,0
  416.     LD    A,E        ;GET THE NUMBER OF CHARS LEFT.
  417.     OR    A        ;IS IT NEGATIVE?
  418.     JP    P,CMKY51
  419.     LD    D,0FFH
  420. CMKY51    EQU    $
  421.     ADD    HL,DE        ;INCREMENT PAST THE KEYWORD.
  422.     INC    HL        ;PLUS 4
  423.     INC    HL
  424.     INC    HL
  425.     INC    HL
  426.     LD    (CMKPTR),HL
  427.     DEC    B        ;DECREMENT THE NUMBER OF ENTRIES LEFT.
  428.     LD    HL,(CMSPTR)    ;GET THE OLD CMDPTR.
  429.     LD    (CMDPTR),HL    ;RESTORE IT.
  430.     JP    CMKEY2        ;GO CHECK THE NEXT KEYWORD.
  431. ;CONVERT CONTENTS OF A TO UPPER CASE IF IT IS LOWER
  432. CAPTAL    IFALT    'a',CAPS10
  433.     IFAGE    'z'+1,CAPS10
  434.     AND    137O        ;MAKE IT UPPER CASE
  435. CAPS10    RET            ;RETURN TO THE CALLER
  436. ;CHECK AMBIGUITY OF A COMMAND
  437. CMAMBG    DEC    B        ;DECREMENT THE NUMBER OF ENTRIES LEFT.
  438.     RET    M        ;IF NONE LEFT THEN IT IS NOT AMBIGUOUS.
  439.     INC    E        ;THIS IS OFF BY ONE;ADJUST.
  440.     LD    C,E        ;SAVE THE CHAR COUNT.
  441.     LD    A,E
  442.     OR    A        ;ANY CHARS LEFT?
  443.     RET    Z        ;NO, IT CAN'T BE AMBIGUOUS.
  444.     LD    D,0
  445.     ADD    HL,DE        ;INCREMENT PAST THE KEYWORD.
  446.     LD    E,4        ;PLUS THE EOS AND DATA.
  447.     ADD    HL,DE
  448.     LD    B,(HL)        ;GET THE LENGTH OF THE KEYWORD.
  449.     INC    HL
  450.     EX    DE,HL    
  451.     LD    HL,(CMKPTR)    ;GET POINTER TO KEYWORD ENTRY.
  452.     INC    HL
  453.     LD    A,(HL)        ;GET THE LENGTH OF THE KEYWORD.
  454.     SUB    C        ;SUBTRACT HOW MANY LEFT.
  455.     LD    C,A        ;SAVE THE COUNT.
  456.     IFA    B,CMAMB0
  457.     RET    P        ;IF LARGER THAN THE NEW WORD THEN NOT AMB
  458. CMAMB0    LD    HL,(CMSPTR)    ;GET THE POINTER TO WHAT PARSED.
  459. CMAMB1    DEC    C        ;DECREMENT THE COUNT.
  460.     JP    M,RSKP        ;IF WE ARE DONE THEN IT IS AMBIGUOUS.
  461.     EX    DE,HL        ;EXCHANGE THE POINTERS.
  462.     LD    B,(HL)        ;GET THE NEXT CHAR OF THE KEYWORD
  463.     INC    HL
  464.     EX    DE,HL        ;EXCHANGE THE POINTERS.
  465.     LD    A,(HL)        ;GET THE NEXT PARSED CHAR.
  466.     INC    HL
  467.     CALL    CAPTAL        ;MAKE IT UPPER IF LOWER
  468. CMAMB2    CP    B        ;ARE THEY EQUAL?
  469.     RET    NZ        ;IF NOT THEN ITS NOT AMBIGUOUS.
  470.     JP    CMAMB1        ;CHECK THE NEXT CHAR.
  471. ;
  472. ;    Parse a file specification.  This includes a call to @FSPEC to
  473. ;    do case conversion, and any other necessary stuff to make a
  474. ;    legal file spec.  On normal return, A has the count of characters
  475. ;    that are in the passed buffer
  476. ;
  477. CMIFIL    LD    (CMFCB),DE    ;SAVE WHERE TO PUT THE CHARACTERS
  478.     LD    DE,CLBUF
  479.     LD    B,0        ;Set the count to zero
  480. CMIFI1    CALL    CMGTCH        ;GET A CHARACTER
  481.     OR    A        ;CHECK FOR A CONTROL CHARACTER ?,CR,ESC
  482.     JP    P,CMIFI3    ;GO IF NOT CONTROL
  483.     AND    7FH        ;STRIP THE HIGH BIT
  484.     CP    ESC        ;WAS IT ABORT?    
  485.     RET    Z        ;TAKE THE ERROR EXIT
  486.     IFANOT    '?',CMIFI4    ;Go if not help request
  487.     LD    DE,FILHLP    ;PRINT A MESSAGE
  488.     CALL    REPRNT        ;SET UP FOR REPARSE
  489.     JP    REPARS        ;GET A NEW CHARACTER
  490. CMIFI3    LD    (DE),A        ;STORE THE CHARACTER
  491.     INC    DE        ;POINT TO NEXT POS
  492.     INC    B        ;INCREMENT CHARACTER COUNT
  493.     JR    CMIFI1        ;GET ANOTHER ONE
  494. CMIFI4    LD    A,CR        ;Get the end of name marker
  495.     LD    (DE),A        ;Put in a terminator
  496.     LD    A,B        ;Get the count
  497.     IFZ    CMIFI5        ;Skip fspec if no characters given
  498.     PUSH    HL        ;Save the pointer
  499.     LD    HL,CLBUF    ;GET THE TEXT TO FSPEC
  500.     LD    DE,(CMFCB)    ;WHERE TO PUT THE RESULT
  501.     CALL    XFSPEC        ;MAKE IT A FILE SPEC
  502.     JP    NZ,CMIFI6    ;Oops, bad fspec
  503.     EX    DE,HL        ;Move start to HL
  504.     LD    A,3        ;Get the character to find
  505.     LD    BC,40        ;Get the maximum distance to look
  506.     CPIR            ;Find it
  507.     LD    HL,39        ;Find out how far we looked
  508.     OR    A        ;Reset the carry
  509.     SBC    HL,BC        ;Compute the distance
  510.     LD    B,L        ;Get the length
  511.     POP    HL        ;Restore pointer which is...
  512. CMIFI5    LD    (CMDPTR),HL    ;Next place to put characters at
  513.     LD    A,B        ;Copy the length to A
  514.     JP    RSKP        ;Return normal
  515. ;
  516. CMIFI6    POP    HL        ;Restore the stack
  517.     JP    XERROR0        ;Print a system message and return
  518. ;
  519. ;    Get input characters from the keyboard, up to an action character
  520. ;    The actual character input is retrieved via GETSTR().
  521. ;
  522. CMINBF    PUSH    AF
  523.     PUSH    DE
  524.     PUSH    HL
  525.     LD    A,(CMAFLG)    ;IS THE ACTION CHAR FLAG SET?
  526.     IFNZ    CMINB9        ;Go if it is
  527.     LD    HL,(CMCPTR)    ;Get the position
  528.     PUSH    HL        ;Save it for later
  529.     LD    DE,CMDBUF    ;Get EOB
  530.     OR    A        ;Reset carry
  531.     SBC    HL,DE        ;Compute number of characters typed in
  532.     LD    B,L        ;Get number of characters
  533.     POP    HL        ;Get the value back
  534.     CALL    GETSTR        ;Input up to an action character
  535.     JP    C,PRSERR    ;Jump if user pressed break
  536.     LD    A,B        ;SAVE THE COUNT
  537.     LD    (CMCCNT),A
  538.     LD    C,B        ;GET THE NUMBER OF CHARACTERS IN BUFFER
  539.     LD    B,0
  540.     LD    HL,CMDBUF    ;Get the start
  541.     PUSH    HL        ;Save it
  542.     ADD    HL,BC        ;Add the count
  543.     LD    (CMCPTR),HL    ;Save next input position
  544.     POP    BC        ;Get the start
  545.     OR    A        ;Reset the carry
  546.     SBC    HL,BC        ;Are there any characters in the buffer?
  547.     JP    Z,PRSERR    ;IF NO CHARACTERS START OVER
  548. CMINB6    LD    A,0FFH        ;SET THE ACTION FLAG.
  549.     LD    (CMAFLG),A
  550. CMINB9    POP    HL        ;Restore the registers
  551.     POP    DE
  552.     POP    AF
  553.     RET            ;Return
  554. ;
  555. ;    Get a character from the command input buffer.  If an action
  556. ;    character is found, then the MSB of the character will be set
  557. ;
  558. CMGTCH    PUSH    HL
  559.     PUSH    BC
  560. CMGTC1    LD    A,(CMAFLG)
  561.     OR    A        ;IS IT SET.
  562.     CALL    Z,CMINBF    ;IS THE ACTION CHAR FLAG SET?
  563.     LD    HL,(CMDPTR)    ;GET A POINTER INTO THE BUFFER.
  564.     LD    A,(HL)        ;GET THE NEXT CHAR.
  565.     INC    HL
  566.     LD    (CMDPTR),HL
  567.     IFA    ' ',CMGTC2
  568.     IFANOT    TAB,CMGTC3
  569. CMGTC2    LD    A,(CMSFLG)    ;GET THE SPACE FLAG.
  570.     IFNZ    CMGTC1        ;Was last char a space?
  571.     LD    A,0FFH        ;SET THE SPACE FLAG.
  572.     LD    (CMSFLG),A
  573.     LD    A,' '
  574.     POP    BC
  575.     POP    HL
  576.     JR    CMGTC5
  577. CMGTC3    PUSH    AF
  578.     XOR    A
  579.     LD    (CMSFLG),A        ;ZERO THE SPACE FLAG.
  580.     POP    AF
  581.     POP    BC
  582.     POP    HL
  583.     IFA    ESC,CMGTC5    ;Go if escape abort
  584.     IFA    '?',CMGTC4    ;Go answer a help request
  585.     IFA    CR,CMGTC4
  586.     CP    LF
  587.     RET    NZ        ;NOT AN ACTION CHAR, JUST RETURN.
  588. CMGTC4    PUSH    HL
  589.     LD    HL,(CMDPTR)
  590.     DEC    HL
  591.     LD    (CMDPTR),HL
  592.     POP    HL
  593. CMGTC5    OR    80H        ;MAKE THE CHAR NEGATIVE TO INDICATE IT IS
  594.     RET                ;A TERMINATOR.
  595. STRLEN    EQU    $
  596.     PUSH    AF
  597.     PUSH    DE
  598.     LD    BC,0
  599. STRLEN_1    EQU    $
  600.     LD    A,(DE)
  601.     IFA    EOS,STRLEN_2
  602.     INC    DE
  603.     INC    BC
  604.     JR    STRLEN_1
  605. STRLEN_2    EQU    $
  606.     POP    DE
  607.     POP    AF
  608.     RET
  609. ;end of file
  610.