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

  1. ;    M4LOG/ASM
  2. ;    LOGON SCRIPT INTERPRETER
  3. ;
  4. ;    OUTPUT STRING TO PORT
  5. ;
  6. ;    This code performs the OUTPUT function.  Control characters
  7. ;    are ignored in the output string as far as matching is concerned,
  8. ;    and they are also ignored in the input port.  This allows more
  9. ;    flexability as far as text recognition is concerned.
  10. ;
  11. ;    e.g.  The string XYZPDQ<CR><ESC><CR> will be output exactly as
  12. ;    specified, but only the characters "XYZPDQ" will be matched if
  13. ;    SET OUTPUT HOST-ECHO is ON.  Any control characters will be
  14. ;    ignored.
  15. ;
  16. OUTPUT    EQU    $
  17.     LD    A,CMTXT        ;GET SOME TEXT TO SEND
  18.     LD    DE,DATA        ;WHERE TO PUT THE STRING
  19.     LD    (SOUPTR),DE    ;SET THE ORIGINAL DATA ADDRESS
  20.     CALL    COMND        ;GET IT
  21.     JP    KERMT3        ;SAY NOT CONFIRMED ON ERROR
  22.     LD    A,1
  23.     LD    (SNDFLG),A
  24. OUTPUT1    CALL    GETFCH        ;GET A CHARACTER
  25.     JR    NZ,OUTPUT5
  26.     CALL    GTREAL        ;GET THE ACTUAL IF IT IS SPECIAL
  27.     JP    NZ,SOU400    ;QUIT ON AN ERROR
  28.     LD    E,A        ;PUT IT IN E FOR OUTCHR
  29.     LD    A,(DLYFLG)    ;WAS IT A DELAY
  30.     IFZ    OUTPUT2        ;Jump is no delay
  31.     XOR    A
  32.     LD    (DLYFLG),A    ;RESET THE FLAG
  33.     JR    OUTPUT1        ;GET A NEW CHARACTER
  34. OUTPUT2    CALL    OUTCHR        ;OUT THE PORT WITH IT
  35.     LD    A,(LOGFLG)    ;DO WE NEED TO LOGIT TO THE FILE
  36.     OR    A
  37.     LD    A,E        ;RESTORE THE CHARACTER IN A
  38.     CALL    NZ,LOGIT    ;LOG IT IF LOGFLG IS SET
  39.     IFALT    32,OUTPUT1
  40.     LD    A,(ECHFLG)    ;IS ECHO ON?
  41.     IFZ    OUTPUT1        ;If not than get the next to send
  42.     LD    A,E        ;GET THE CHARACTER BACK IN A
  43.     PUSH    AF        ;SAVE IT FOR A SEC
  44. OUTPUT3    CALL    INPORT        ;GET ONE CHARACTER FROM THE PORT
  45.     JR    Z,OUTPUT4    ;Got a character so check it
  46.     CALL    CONIN        ;IS THERE A KEY PRESSED?
  47.     IFZ    OUTPUT3        ;Go if there isn't
  48.     CP    128        ;IS IT BREAK
  49.     JP    Z,SBORT        ;QUIT IF IT IS
  50.     CP    27        ;IS IT ESCAPE
  51.     JP    Z,QUTOUT    ;Skip this command
  52.     CP    129        ;CHECK FOR F1 PRESSED
  53.     JP    Z,QUTOUT    ;Skip this command
  54.     JR    OUTPUT3        ;TRY AGAIN TO GET THE ECHO
  55. OUTPUT4    LD    E,A
  56.     LD    A,(OTDSP)    ;LOCAL ECHO ON?
  57.     OR    A
  58.     LD    A,E        ;RESTORE A FOR THE CALL TO TRMOUT
  59.     CALL    NZ,TRMOUT    ;DISPLAY THE CHARACTER
  60.     LD    A,(LOGFLG)    ;IS LOGGING SET?
  61.     OR    A
  62.     LD    A,E
  63.     CALL    NZ,LOGIT    ;LOG WHAT WE RECEIVED
  64.     CALL    SETCSE        ;SET THE CASE
  65.     LD    E,A        ;PUT IT IN E
  66.     POP    AF        ;GET THE CHARACTER WE SENT
  67.     CALL    SETCSE        ;SET THE CASE
  68.     IFA    E,OUTPUT1
  69.     LD    A,E
  70.     IFALT    32,OUTPUT1    ;Ignore CNTL that doesn't match
  71.     LD    DE,NOECHO    ;LOAD NO REMOTE-HOST ECHO ERROR
  72.     JP    SBORT2        ;QUIT, NO MATCH
  73. OUTPUT5    XOR    A        ;RESET STATE FLAG
  74.     LD    (SNDFLG),A
  75.     JP    KERMIT        ;GET A NEW COMMAND
  76. ;
  77. ;    Do receive character matching.
  78. ;
  79. ;    The KMP pattern matching algorithm is used here for the fun of
  80. ;    it.  In reality, we probably don't need this much power, but
  81. ;    it is rather elegant!!!
  82. ;
  83. INPUT    EQU    $
  84.     LD    A,CMTXT        ;GET SOMETHING TO SEND
  85.     LD    DE,DATA        ;WHERE TO PUT THE TEXT
  86.     LD    (SOUPTR),DE    ;SAVE THE ADDRESS FOR GETFCH
  87.     CALL    COMND        ;GET SOME TEXT, OR FAIL
  88.     JP    KERMT3        ;SAY NOT CONFIRMED ON FAILURE
  89.     LD    A,1
  90.     LD    (RECFLG),A
  91.     LD    HL,STRING    ;GET ADDRESS OF THE BUFFER
  92.     LD    B,0        ;B IS THE LENGTH COUNTER
  93. ;
  94. ;    Gather the string to receive
  95. ;
  96. INPUT1    CALL    GETFCH        ;GET A CHARACTER
  97.     JP    NZ,INPUT3    ;QUIT ON AN ERROR
  98.     CALL    GTREAL        ;CONVERT ESCAPES, ETC...
  99.     JP    NZ,SOU400    ;QUIT ON AN ERROR
  100.     LD    E,A        ;SAVE THE CHARACTER FOR A SEC
  101.     LD    A,(DLYFLG)    ;WAS IT A DELAY?
  102.     IFZ    INPUT2        ;Jump if not
  103.     XOR    A        ;CLEAR A
  104.     LD    (DLYFLG),A    ;RESET THE FLAG
  105.     JR    INPUT1
  106. INPUT2    LD    (HL),E        ;STORE WHAT WE GOT
  107.     INC    HL        ;POINT TO THE NEXT
  108.     INC    B        ;ONE MORE TO LENGTH
  109.     JR    NZ,INPUT1    ;JUMP IF NOT BUFFER OVERFLOW
  110.     LD    DE,STOBIG    ;LOAD error MESSAGE STRING
  111.     CALL    PRTSTR        ;PRINT IT ON THE SCREEN.
  112.     JP    SOU540        ;Jump to end
  113. INPUT3    LD    (HL),0        ;END IT WITH A NULL
  114. ;
  115. ;    KMP really begins here.  The basic C code is in the comments!
  116. ;    Build the failure link table...
  117. ;        
  118.     LD    A,B        ;B IS THE LENGTH
  119.     LD    (LENGTH),A    ;SAVE THE LENGTH M=STRLEN(STR)
  120.     XOR    A        ;ZERO a FOR FLINK[1]=0
  121.     LD    C,1        ;SUBSCRIPT 1
  122.     CALL    SETLNK        ;FLINK[1]=0;
  123.     LD    D,2        ;I=2;
  124. INPUT4    LD    C,D        ;GET I
  125.     LD    A,(LENGTH)    ;GET THE LENGTH OF THE STRING
  126.     CP    C        ;IF (I <= M) {
  127.     JP    M,INPUT7    ;Jump if I > M
  128.     LD    C,D        ;c = I
  129.     DEC    C        ;c = I-1
  130.     CALL    GETLNK        ;a = FLINK[c]
  131.     LD    E,A        ;J = FLINK[I-1]
  132. INPUT5    INC    E        ;IF (I != 0
  133.     DEC    E
  134.     JR    Z,INPUT6    ;JUMP IF I = 0
  135.     LD    C,E        ;c = J
  136.     CALL    GETSTG        ;a = STRING[J]
  137.     LD    B,A        ;b = a
  138.     LD    C,D        ;c = I
  139.     DEC    C        ;c = I - 1
  140.     CALL    GETSTG        ;a = STRING[I-1]
  141.     IFA    B,INPUT6
  142.     LD    C,E        ;c = J
  143.     CALL    GETLNK        ;a = FLINK[J]
  144.     LD    E,A        ;J = FLINK[J]
  145.     JR    INPUT5
  146. INPUT6    LD    A,E        ;A = J
  147.     INC    A        ;A = J+1
  148.     LD    C,D        ;C = I
  149.     CALL    SETLNK        ;FLINK[I] = J+1
  150.     INC    D        ;I++
  151.     JR    INPUT4
  152. INPUT7    LD    E,0        ;J = 0
  153.     LD    A,(HSTCHR)    ;GET ANY LEFT OVER CHARACTERS
  154.     IFZ    INPUT12
  155.     LD    C,A        ;SAVE A FOR A SEC
  156.     XOR    A        ;CLEAR IT OUT
  157.     LD    (HSTCHR),A    ;SAY NO REMAINING HOST CHARACTER
  158.     LD    A,C        ;RESTORE A
  159. INPUT8    LD    (CHRGOT),A
  160.     LD    C,A        ;SAVE THE CHARACTER
  161.     LD    A,(INDSP)    ;CHECK IF WE SHOULD DISPLAY
  162.     IFZ    INPUT9
  163.     LD    A,C        ;GET THE CHARACTER BACK
  164.     CALL    TRMOUT        ;PRINT IT
  165. INPUT9    LD    A,(LOGFLG)    ;IS LOGGING ON
  166.     OR    A        ;SET THE FLAGS
  167.     LD    A,C        ;RESTORE THE CHARACTER INTO A
  168.     CALL    NZ,LOGIT    ;LOG THE CHARACTER TO THE FILE
  169.     INC    E        ;++J
  170. INPUT10    INC    E        ;IS E == 0
  171.     DEC    E
  172.     JR    Z,INPUT11
  173.     LD    C,E        ;C = J
  174.     DEC    C        ;C = J-1
  175.     CALL    GETSTG        ;A = STRING[J-1]
  176.     CALL    SETCSE        ;ADJUST THE CASE
  177.     LD    C,A        ;C = A
  178.     LD    A,(CHRGOT)
  179.     CALL    SETCSE        ;ADJUST THE CASE
  180.     IFA    C,INPUT11
  181.     LD    C,E        ;C = J
  182.     CALL    GETLNK        ;A = FLINK[J]
  183.     LD    E,A        ;J = FLINK[J]
  184.     JR    INPUT10
  185. INPUT11    LD    A,(LENGTH)    ;ARE WE AT THE END
  186.     IFA    E,INPUT13
  187. INPUT12    CALL    INPORT        ;GET A CHARACTER IF THERE
  188.     JR    Z,INPUT8    ;GO IF WE GOT ONE
  189.     CALL    CONIN        ;IS THERE A KEY PRESSED
  190.     IFZ    INPUT12
  191.     CP    128        ;IS BREAK PRESSED
  192.     JP    Z,SBORT        ;SBORT IF IT IS
  193.     CP    ESC        ;IS IT ESCAPE
  194.     JP    Z,QUTOUT    ;Skip this command
  195.     CP    129        ;CHECK IF F1 IS PRESSED AS ESCAPE
  196.     JP    Z,QUTOUT    ;Skip this command
  197.     PUSH    DE        ;SAVE E
  198.     LD    E,A        ;OUTCHR NEEDS CHAR IN E
  199.     CALL    OUTCHR        ;SEND IT OUT THE PORT
  200.     POP    DE        ;RESTORE E
  201.     JR    INPUT12        ;CHECK AGAIN
  202. INPUT13    XOR    A        ;RESET RECEIVE STATE FLAG
  203.     LD    (RECFLG),A
  204.     JP    KERMIT        ;GET A NEW COMMAND
  205. ;
  206. ;    DO MULTIPLE/REPEATING TRANSMITTION UNTIL A CHARACTER IS RECEIVED
  207. ;
  208. PULSE    EQU    $
  209.     LD    A,CMTXT        ;GET SOME TEXT
  210.     LD    DE,DATA        ;WHERE TO PUT IT
  211.     LD    (SOUPTR),DE    ;SAVE THE ADDRESS OF THE BUFFER
  212.     CALL    COMND        ;GET SOME TEXT
  213.     JP    KERMT3        ;SAY NOT CONFIRMED ON FAILURE
  214.     LD    A,1
  215.     LD    (MULFLG),A
  216.     LD    HL,MULBUF    ;GET THE BUFFER
  217.     LD    (BUFPTR),HL    ;SAVE THE START
  218. PULSE1    CALL    GETFCH        ;GET A CHARACTER
  219.     JP    NZ,PULSE3    ;QUIT ON AN ERROR
  220.     CALL    GTREAL        ;GET THE ACTUAL CHARACTER
  221.     JP    NZ,SOU400
  222.     LD    E,A
  223.     LD    A,(DLYFLG)    ;WAS IT A DELAY?
  224.     IFZ    PULSE2
  225.     XOR    A        ;CLEAR A
  226.     LD    (DLYFLG),A    ;RESET THE FLAG
  227.     JR    PULSE1        ;GET A NEW CHARACTER
  228. PULSE2    LD    (HL),E        ;SAVE THE CHARACTER
  229.     INC    HL        ;POINT TO THE NEXT
  230.     JR    PULSE1        ;DO IT AGAIN
  231. PULSE3    PUTHL    A        ;Save the CR just found
  232.     LD    (HL),0        ;Terminate with a NULL
  233. PULSE4    LD    BC,3000        ;DELAY COUNTER, MAGICAL NUMBER?!?
  234. PULSE5    CALL    INPORT        ;CHECK FOR A CHARACTER FIRST.
  235.     JR    Z,PULSE9    ;GO IF WE GOT ONE
  236.     PUSH    BC        ;SAVE BC
  237.     CALL    CONIN        ;CHECK THE KEYBOARD
  238.     IFZ    PULSE6
  239.     CP    128        ;IS IT BREAK?
  240.     POP    BC
  241.     JP    Z,SBORT        ;SBORT IF IT IS
  242.     CP    ESC        ;IS IT ESCAPE?
  243.     JP    Z,QUTOUT    ;Skip this command
  244.     CP    129        ;IS F1 PRESSED FOR ESCAPE?
  245.     JP    Z,QUTOUT    ;Skip this command
  246.     PUSH    BC
  247.     LD    E,A        ;PUT CHAR IN E FOR OUTCHR
  248.     CALL    OUTCHR        ;OUTPUT THE SUCKER!
  249.     LD    A,(LOGFLG)    ;CHECK FOR LOGGING TO FILE
  250.     OR    A
  251.     LD    A,E        ;GET THE CHARACTER BACK
  252.     CALL    NZ,LOGIT    ;GO LOG IT TO THE FILE IF FLAG
  253. PULSE6    POP    BC
  254.     DEC    BC        ;DECREMENT OUR COUNTER
  255.     LD    A,B        ;CHECK IT FOR ZERO
  256.     OR    C
  257.     JR    NZ,PULSE5    ;LOOP UNTIL IT IS
  258.     LD    HL,MULBUF    ;GET THE STRING ADDRESS
  259. PULSE7    LD    A,(HL)        ;GET A CHARACTER TO SEND
  260.     CP    CR        ;IS IT THE END OF THE STRING?
  261.     JR    NZ,PULSE8    ;If not CR than jump
  262.     INC    HL        ;CHECK FOR NULL TERMINATOR
  263.     LD    A,(HL)        ;GET THE CHARACTER AFTER CR
  264.     DEC    HL        ;POINT BACK ONE FOR FAIL
  265.     IFZ    PULSE4
  266. PULSE8    INC    HL        ;POINT TO NEXT CHAR
  267.     PUSH    HL        ;SAVE THE ADDRESS
  268.     LD    E,A        ;SEND IT TO THE PORT
  269.     CALL    OUTCHR
  270.     LD    A,(LOGFLG)    ;CHECK FOR LOGGING
  271.     OR    A
  272.     LD    A,E        ;GET THE CHARACTER BACK
  273.     CALL    NZ,LOGIT    ;GO LOG IT TO THE FILE
  274.     POP    HL        ;GET THE ADDRESS BACK
  275.     JR    PULSE7        ;TO OF THE LOOP
  276. PULSE9    LD    (HSTCHR),A    ;SAVE THE SENT CHARACTER
  277.     XOR    A        ;RESET THE STATE FLAG
  278.     LD    (MULFLG),A
  279.     JP    KERMIT        ;GET A NEW COMMAND
  280. ;
  281. ;    PAUSE FOR A CERTAIN NUMBER OF SECONDS
  282. ;
  283. PAUSE    EQU    $
  284.     LD    A,CMNUM        ;GET A WHILE TO PAUSE
  285.     CALL    COMND        ;GET A NUMBER
  286.     JP    KERMT3        ;SAY NOT CONFIRMED ON AN ERROR
  287.     IFNZ    PAUSE1        ;Jump if at least one digit given
  288.     LD    DE,1        ;Use one second for the default
  289. PAUSE1    LD    L,E        ;SAVE IT
  290.     LD    H,D        ;HL IN THE COUNT
  291.     LD    C,30        ;Count * 30 * HL = seconds delay
  292.     CALL    XMUL16        ;Multiply 16 bit HL by 8 bit C
  293.     LD    H,L        ;Put the lower 16 bit of the 24
  294.     LD    L,A        ;bit result into HL
  295.     LD    (TIMER),HL    ;STORE THE NUMBER
  296.     LD    C,8        ;TASK SLOT # 8
  297. PAUSE2    CALL    XCKTSK        ;Is the task available?
  298.     JR    NZ,PAUSE3
  299.     LD    IY,(FLAGS)    ;Reset the special key bits in kflag$
  300.     LD    A,(IY+10)    ;Get it
  301.     AND    0F8H        ;Throw out <ENTER>, <BREAK>, and <PAUSE>
  302.     LD    (IY+10),A    ;Put it back
  303.     LD    DE,ALRMAD    ;ADDRESS OF THE ALARM
  304.     CALL    XADTSK        ;Add the task
  305.     JR    PAUSE5        ;Go wait for completion
  306. PAUSE3    INC    C        ;Get the next slot
  307.     CP    11
  308.     JR    NZ,PAUSE2
  309.     STROUT    NODELAY        ;Issue errormessage
  310.     LD    BC,0FFFFH    ;Get a big value
  311.     CALL    XPAUSE        ;Use @PAUSE to sleep for awhile
  312.     JP    KERMIT
  313. PAUSE5    LD    HL,(TIMER)    ;CHECK FOR ZERO YET
  314.     LD    A,H
  315.     OR    L
  316.     JR    NZ,PAUSE5    ;LOOP UNTIL EXPIRES
  317.     JP    KERMIT        ;QUIT WHEN FLAG IS ZERO
  318. ;
  319. ;    Set or ignore case based on "CSEFLG"
  320. ;
  321. SETCSE    PUSH    AF        ;SAVE THE CHARACTER
  322.     LD    A,(CSEFLG)    ;IS THE OPTION ON?
  323.     IFZ    CPS10
  324.     POP    AF        ;GET THE CHARACTER BACK
  325. CPTAL    CP    'a'        ;CHECK FOR LOWER CASE
  326.     RET    M
  327.     CP    'z'+1
  328.     RET    P
  329.     AND    5FH        ;MAKE IT UPPER IF IT IS LOWER
  330.     JR    CAPS20
  331. CPS10    POP    AF        ;RESTORE AF
  332. CAPS20    RET            ;RETURN TO THE CALLER
  333. ;
  334. ;    INDEX STRING BY "C" ELEMENTS, AND PUT THE VALUE THERE IN A
  335. ;
  336. GETSTG    LD    HL,STRING    ;GET STRING AS THE BASE
  337.     JR    GET100        ;JOIN THE CODE
  338. GETLNK    LD    HL,FLINK    ;GET FLINK AS THE BASE
  339. GET100    PUSH    BC        ;SAVE BC FOR THE ADD
  340.     LD    B,0        ;MAKE BC A BYTE COUNT
  341.     ADD    HL,BC        ;HL NOW POINTS TO IT
  342.     LD    A,(HL)        ;A = HL[c]
  343.     POP    BC        ;RESTORE BC
  344.     RET
  345. ;
  346. ;    ASSIGN THE C'th ELEMENT OF A STRING THE VALUE IN A
  347. ;
  348. SETSTG    LD    HL,STRING    ;GET STRING AS THE BASE
  349.     JR    SET100        ;JOIN THE CODE
  350. SETLNK    LD    HL,FLINK    ;GET FLINK AS THE BASE
  351. SET100    PUSH    BC        ;SAVE BC FOR THE ADD
  352.     LD    B,0        ;MAKE BC A BYTE OFFSET
  353.     ADD    HL,BC        ;HL POINT TO IT NOW
  354.     LD    (HL),A        ;HL[c] = A
  355.     POP    BC        ;RESTORE BC
  356.     RET
  357. ;
  358. ;    PRINT THE MESSAGE IN DE AND QUIT WITH AN ERROR
  359. ;
  360. SBORT2    CALL    PRTSTR        ;DISPLAY THE MESSAGE
  361.     JR    SBORT        ;CLOSE THE FILE AND EXIT
  362. ;
  363. ;    ISSUE A SYSTEM ERROR MESSAGE FIRST AND SBORT
  364. ;
  365. SBORT1    CALL    XERROR0        ;PRINT A SYSTEM MESSAGE
  366. SBORT    STROUT    LGFAIL        ;Operation aborted message
  367.     JP    SOU540
  368. ;
  369. ;    SURRENDER THE TERMINAL TO THE USER
  370. ;
  371. QUTOUT    STROUT    QUTMES        ;TELL THEM WHAT WE ARE DOING
  372.     LD    HL,(CMCPTR)
  373.     LD    (HL),EOS
  374.     STROUT    CMDBUF
  375.     JP    KERMIT        ;GET A NEW COMMAND
  376. ;
  377. ;    CONTROL COMES HERE AT EOF
  378. ;
  379. SOU400    LD    A,(ESFLG)    ;DID WE DIE IN AN ESC SEQ
  380.     IFZ    SOU420
  381.     STROUT    PREESC        ;Print the message
  382.     JR    SOU540        ;CHECK STATE FLAGS
  383. SOU420    LD    A,(CTLFLG)    ;DID WE DIE IN A CTL SEQ
  384.     IFZ    SOU430
  385.     STROUT    PRECTL        ;Print the message
  386.     JR    SOU540        ;CHECK STATE FLAGS
  387. SOU430    LD    A,(OPTFLG)    ;CHECK FOR <CR> TYPE EOF
  388.     OR    A
  389.     JP    Z,KERMIT    ;ON THIS ONE, GOTO KERMIT
  390.     STROUT    PREOPT        ;Print the message
  391.     JR    SOU540
  392. SOU540    LD    A,(EXTFLG)    ;CHECK FOR EXIT AT EOF
  393.     OR    A        ;IS IT SET
  394.     JP    Z,KERMIT    ;GOTO GET MORE COMMANDS IF NOT
  395.     LD    A,(TAKFLG)    ;CHECK IF TAKE ACTIVE
  396.     OR    A
  397.     JP    Z,KERMIT    ;GOTO KERMIT IF NOT
  398.     LD    DE,TFCB
  399.     CALL    XCLOSE        ;CLOSE THE TAKE FILE
  400.     XOR    A        ;TURN TAKE OFF
  401.     LD    (TAKFLG),A
  402.     JP    KERMIT        ;GET A NEW COMMAND
  403. ;
  404. ;    GET \ ESCAPED OR CONTROL'D CHARACTER IF CONTENTS OF "A" SAY SO.
  405. ;    ALSO <CR>, <LF>, <FF>, ARE RECOGNIZED HERE FOR SEND AND RECEIVE.
  406. ;    HL MUST CONTAIN ADDRESS OF ROUTINE TO CALL FOR NEXT CHARACTER.
  407. ;    RETURNS NZ STATUS IF SECOND GET FAILED, OTHERWIZE RETURNS Z.
  408. ;
  409. GTREAL    PUSH    HL        ;SAVE THE REGS!
  410.     PUSH    BC
  411.     PUSH    DE
  412.     IFANOT    '\',GT010
  413.     XOR    A
  414.     LD    B,A
  415.     INC    A
  416.     LD    (ESFLG),A
  417.     CALL    GETFCH        ;CALL THE SPECIAL ROUTINE
  418.     JP    NZ,GT060    ;QUIT IF END IS FOUND
  419.     CP    '0'
  420.     JP    M,GT005
  421.     CP    '9'+1
  422.     JP    P,GT005
  423. GT002    CP    '0'
  424.     JP    M,GT003
  425.     CP    '9'+1
  426.     JP    P,GT003
  427.     SUB    '0'
  428.     SLA    B
  429.     SLA    B
  430.     SLA    B
  431.     ADD    A,B
  432.     LD    B,A
  433.     CALL    GETFCH        ;CALL THE SPECIAL ROUTINE
  434.     JR    Z,GT002        ;Go on success
  435. GT003    LD    HL,(SOUPTR)    ;Unput the character
  436.     DEC    HL
  437.     LD    (SOUPTR),HL
  438.     LD    (HL),A
  439. GT004    LD    A,B
  440. GT005    PUSH    AF
  441.     XOR    A
  442.     LD    (ESFLG),A
  443.     POP    AF
  444.     JP    GT050
  445. GT010    IFANOT    '^',GT020    ;Jump if not a control sequence
  446.     LD    A,1        ;SET THE FLAG FOR A GET ERROR
  447.     LD    (CTLFLG),A
  448.     CALL    GETFCH        ;CALL THE SPECIAL ROUTINE
  449.     JP    NZ,GT060
  450.     SUB    40H        ;CONTROLIFY IT BY SUBTRACTING "@"
  451.     PUSH    AF
  452.     XOR    A
  453.     LD    (CTLFLG),A
  454.     POP    AF
  455.     JP    GT050
  456. GT020    CP    '<'        ;Is it an ANSI sequence
  457.     JP    NZ,GT050    ;RETURN Z STATUS IF NOT
  458.     LD    A,1        ;SET THE STATE FLAG
  459.     LD    (OPTFLG),A
  460.     LD    HL,GTSTRG    ;WHERE TO STORE THE STRING
  461. GT023    CALL    GETFCH        ;GET A CHARACTER
  462.     JP    NZ,GT060    ;QUIT ON AN ERROR
  463.     IFA    '>',GT026
  464.     CALL    CPTAL        ;MAKE IT A CAPITAL
  465.     PUTHL    A        ;Save the character
  466.     JR    GT023        ;GET SOME MORE
  467. GT026    LD    (HL),0FFH    ;IMPOSSIBLE CHARACTER AS EOL
  468.     LD    HL,CTLTBL    ;TOP OF THE TABLE
  469.     LD    B,(HL)        ;GET THE NUMBER OF ENTRIES
  470.     INC    HL        ;POINT AT THE FIRST CHAR
  471. GT028    LD    DE,GTSTRG    ;Get the buffer we stored into
  472. GT030    LD    A,(DE)        ;Get a character
  473.     IFANOT    (HL),GT040    ;Does it match
  474. GT035    GETHL    A        ;Get the next character
  475.     INC    DE        ;Point to next
  476.     IFALT    '0',GT037    ;Check valid range of characters
  477.     IFAGE    'Z'+1,GT037    ;Jump if we are at the end marker
  478.     JR    GT030        ;Go get the rest of the string
  479. GT037    LD    C,A        ;Save the character
  480.     LD    A,(DE)        ;Get the next
  481.     IFANOT    0FFH,GT040    ;Error if not terminator
  482.     LD    A,C        ;RESTORE THE CHARACTER
  483.     CP    DLY        ;Is it a delay string?
  484.     JP    Z,DELAY        ;Go do it if it is
  485.     PUSH    AF
  486.     XOR    A        ;Reset the state flag for EOF
  487.     LD    (OPTFLG),A
  488.     POP    AF
  489.     JP    GT050        ;RETURN Z STATUS
  490. GT040    LD    C,A        ;SAVE THE CHARACTER
  491.     LD    A,(HL)        ;WILD CARD?
  492.     IFANOT    '*',GT042    ;Jump if not wild
  493.     LD    A,C        ;Get the delay character
  494.     LD    (WLDBUF),A    ;SAVE IT IN THE BUFFER
  495.     JR    GT035        ;Join the code for end check
  496. GT042    LD    A,0FEH        ;WHAT TO LOOK FOR
  497.     PUSH    BC        ;DON'T KILL B
  498.     LD    BC,0        ;Set max count
  499.     CPIR            ;LOOK AHEAD FOR THE NEXT
  500.     POP    BC        ;RESTORE B
  501.     DJNZ    GT028        ;GO LOOK SOMEMORE
  502.     JP    NOCODE        ;PRINT A MESSAGE
  503. DELAY    LD    A,(WLDBUF)    ;GET THE CHARACTER
  504.     SUB    48        ;MAKE IT BINARY
  505.     LD    L,A        ;SAVE IT
  506.     LD    H,0        ;HL IN THE COUNT
  507.     LD    C,30        ;33.33 MILLISECS * 30 * HL = SECS
  508.     CALL    XMUL16
  509.     LD    H,L        ;SHIFT IT ALL INTO HL
  510.     LD    L,A        ;HL = HL * 120
  511.     LD    (TIMER),HL
  512.     LD    IY,(FLAGS)    ;Reset the special key bits in kflag$
  513.     LD    A,(IY+10)
  514.     AND    0F8H
  515.     LD    (IY+10),A
  516.     LD    C,8        ;TASK SLOT # 8
  517.     LD    DE,ALRMAD    ;ADDRESS OF THE ALARM
  518.     CALL    XADTSK
  519. GT034    LD    HL,(TIMER)    ;CHECK FOR ZERO YET
  520.     LD    A,H
  521.     OR    L
  522.     JR    NZ,GT034    ;LOOP UNTIL EXPIRES
  523.     LD    A,1
  524.     LD    (DLYFLG),A    ;SET THE DELAY FLAG
  525. GT050    CP    A        ;SET Z STATUS
  526. GT060    POP    DE        ;RESTORE REGS
  527.     POP    BC
  528.     POP    HL
  529.     RET            ;RETURN TO THE CALLER
  530. ;
  531. ;    Print an error message about a bad string inside <...>'s
  532. ;
  533. NOCODE    STROUT    BADCD        ;PRINT A MESSAGE
  534.     XOR    A
  535.     INC    A        ;SET NZ STATUS
  536.     JR    GT060
  537. ;
  538. ;    ALARM COUNTER
  539. ;
  540. ALARM    PUSH    HL        ;Save the registers
  541.     PUSH    AF
  542.     PUSH    IY
  543.     LD    IY,(FLAGS)    ;Get the system flags
  544.     LD    HL,(TIMER)    ;PREVIOUS TIMER VALUE
  545.     DEC    HL        ;DECREMENT IT
  546.     LD    (TIMER),HL    ;SAVE THE NEW VALUE
  547.     LD    A,H        ;IS IT ZERO YET
  548.     OR    L
  549.     JR    NZ,ALARM2
  550. ALARM1    EQU    $
  551.     RES    0,(IY+10)    ;Reset the break bit
  552.     POP    IY
  553.     POP    AF
  554.     POP    HL
  555.     CALL    XKLTSK        ;Remove the alarm task, doesn't return
  556.     RET            ;Just in case
  557. ALARM2    EQU    $
  558.     BIT    0,(IY+10)    ;Check the break bit
  559.     JR    Z,ALARM5
  560.     LD    HL,0
  561.     LD    (TIMER),HL
  562.     LD    H,50
  563. ALARM3    DEC    HL
  564.     LD    A,H
  565.     OR    L
  566.     JR    NZ,ALARM3
  567.     JR    ALARM1
  568. ALARM5    EQU    $
  569.     POP    IY
  570.     POP    AF
  571.     POP    HL
  572.     RET
  573. ;
  574. ;    GET THE NEXT CHARACTER FROM THE BUFFER
  575. ;
  576. GETFCH    PUSH    HL
  577.     LD    HL,(SOUPTR)
  578.     LD    A,(HL)
  579.     INC    HL
  580.     LD    (SOUPTR),HL
  581.     IFA    CR,GTF010
  582.     CP    A
  583.     POP    HL
  584.     RET
  585. GTF010    CP    CR+1        ;Force NZ to be set
  586.     POP    HL
  587.     RET
  588.     END
  589. ;end of file
  590.