home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / b / krtcon.mac < prev    next >
Text File  |  2020-01-01  |  17KB  |  535 lines

  1.     .title    KRTCON    Terminal emulator
  2.     .ident    "V03.63"
  3.  
  4. ; /63/    27-Sep-97  Billy Youdelman  V03.63
  5. ;
  6. ;    marktime (scheduler) completion routines are now more efficient
  7. ;    fix SET CON 8 test for emulator command chars
  8.  
  9. ; /62/    27-Jul-93  Billy Youdelman  V03.62
  10. ;
  11. ;    correct comments to indicate r3 is not preserved between tasks
  12. ;    fixed error handling for suspend/resume CONSOLE logging
  13. ;    added handling for logfile errors
  14. ;    move senbrk here
  15. ;    speed up keyboard input processing at high data rates
  16.  
  17. ; /BBS/     1-Dec-91  Billy Youdelman  V03.61
  18. ;
  19. ;    this module has been extensively modified and will now run fine
  20. ;    under any monitor including SJ if it's built with timer support
  21. ;
  22. ;    pulled RT-11 multi-terminal and sj monitor w/o twait stuff..
  23. ;
  24. ;    set/reset a list of "activation" chars under TSX which
  25. ;    allows non-printing chars input at the terminal, such as ^O,
  26. ;    to be passed to the remote system during the connect mode
  27. ;
  28. ;    display handler speed (fixed for 19.2k too) when connecting
  29. ;    display escape sequence when entering CONNECT
  30. ;    disallow typing TSX lead-in char to TT when running under TSX
  31. ;    allow suppression of sign-on text, for use with krttra
  32. ;    skip TT input routine once done flag is set
  33. ;    tt input now uses con8bit ala TT output
  34. ;    added MILNET option to wakeup (XON) MILNET TACs
  35. ;    added send a control char via esc_char "^x" ala VTCOM
  36. ;    added esc_char "Z" command to hose/refresh handler
  37.  
  38. ;    Copyright 1986 Change Software, Inc
  39. ;
  40. ;    07-MAY-1986 10:55  Brian Nelson
  41.  
  42.  
  43.     .include "IN:KRTMAC.MAC"
  44.     .iif ndf  KRTINC  .error    <; .include for IN:KRTMAC.MAC failed>
  45.  
  46.     .mcall    .CMKT    ,.MRKT    ,.RSUM    ,.SCCA    ,.SPFUN
  47.     .mcall    .SPND    ,.TTINR    ,.TTOUTR,.TWAIT    ,.WRITC
  48.  
  49.  
  50.     BRKDRV    =    202        ; /62/ wc=0 ends break, else begin it
  51.     STSDRV    =    204        ; low byte status, high byte version
  52.     $XLV51    =    16.        ; RT-11 V5.1 XL/XC version number
  53.  
  54.     .macro    beep
  55.     mov    #bell    ,r0        ; load a bell
  56.     .ttoutr                ; try to beep, but don't wait for it..
  57.     .endm    beep
  58.  
  59.     .macro    schedule  taskheader
  60.     mov    r0    ,-(sp)        ; this is a completion routine
  61.     mov    taskheader,r0        ; top of task's entry in scheduler
  62.     mov    sp    ,state(r0)    ; flag task is now ready to run
  63.     mov    (sp)+    ,r0
  64.     .endm    schedule
  65.  
  66.  
  67.     .sbttl    Local buffers
  68.  
  69.     .psect    condat    ,rw,d,lcl,rel,con
  70. brkwrk:    .word    0 ,0 ,0 ,0        ; /62/ break mark time work area
  71. cancel:    .word    0 ,0 ,0 ,0        ; .cmkt work area
  72. crflag:    .word    0            ; if <> last char was a CR
  73. done:    .word    0            ; set this <> to exit scheduler
  74. iopend:    .word    0            ; if <> XL write completion is pending
  75. rmbuff:    .word    0            ; one word buffer for writes to XL
  76. rt.v51:    .word    0            ; if <> XL is from RT-11 V5.1
  77. scca:    .word    0 ,0 ,0            ; trap ^C here
  78. short:    .word    0 ,1            ; wait one tick
  79. stsmark:.word    0 ,0 ,0 ,0        ; status watcher mark time work area
  80. ttmark:    .word    0 ,0 ,0 ,0        ; ttdone mark time work area
  81. twait:    .word    0 ,0            ; .twait work area
  82. xkmark:    .word    0 ,0 ,0 ,0        ; xktime mark time work area
  83. xkwork:    .word    0 ,0 ,0 ,0 ,0 ,0    ; writes to handler work area
  84.  
  85.  
  86.     .sbttl    Task scheduler data table
  87.  
  88. ; these are NOT saved and may be used only within the then active task
  89. ;    r0    = scratch
  90. ;    r1    = scratch
  91. ;    r2    = scratch
  92. ;    r3    = not currently in use    ; /62/
  93.  
  94. ; this register is preserved between tasks
  95. ;    r4    = one word TT input buffer
  96.  
  97. ;    r5    = pointer to CURRENT task's entry in table
  98.  
  99.     TASKADDR = 0            ; task's starting address
  100.     STATE     = 2            ; if <> run this task next time thru
  101.  
  102. ;           taskaddr    ,state        ; /62/ rmhead MUST follow tthead in
  103. tlist:                    ; /62/ this table, see note in rmproc
  104. xkhead::.word    xkproc    ,0        ; XL data out to TT
  105. tthead:    .word    ttproc    ,0        ; get TT input
  106. rmhead:    .word    rmproc    ,0        ; send it to XL
  107. sthead:    .word    stproc    ,0        ; check XL status
  108.     .word    0            ; terminate table
  109. hdsize    =    tthead - xkhead        ; each entry is this long
  110.  
  111.     .psect    $pdata            ; /63/ consolidate local data here..
  112. ;        marktime intervals
  113. ststime:.word    0 ,0            ; /62/ init puts 0.5 sec in ticks here
  114. ttwait:    .word    0 ,3            ; poll TT for input every 3 ticks
  115. xktime:    .word    0 ,2            ; wait to clear stuffed output buffer
  116.  
  117. con.01:    .asciz    "Connecting to "
  118. con.02:    .asciz    "  DTE speed: "        ; "DTE" as path speed may be different
  119. con.03:    .asciz    "N/A"
  120. con.04:    .asciz    <cr><lf>"Type ^"
  121. con.05:    .asciz    "C to return to your local machine"<cr><lf>
  122. con.06:    .asciz    "%KRTCON-W-Carrier "
  123. con.07:    .asciz    "lost"<cr><lf>
  124. con.08:    .asciz    "detected"<cr><lf>
  125. con.09:    .asciz    "Logfile is "
  126. con.10:    .asciz    ", cur/max blk: "
  127. con.11:    .asciz    "/"
  128. con.12:    .asciz    "No LOGFILE is open"
  129. hlptxt:    .ascii    <cr><lf>
  130.     .ascii    "B    Send a break"<cr><lf>
  131.     .ascii    "C    Connect back to the local Kermit-11"<cr><lf>
  132.     .ascii    "I    Drop DTR for 0.5sec (hang up) then restore it"<cr><lf>
  133.     .ascii    "Q    Suspend CONSOLE logging"<cr><lf>
  134.     .ascii    "R    Resume CONSOLE logging"<cr><lf>
  135.     .ascii    "S    CONSOLE logging status"<cr><lf>
  136.     .ascii    "X    Flow control reset"<cr><lf>
  137.     .ascii    "Z    Zap (100% hose & try to unhang) the handler"<cr><lf>
  138.     .ascii    '^x    Send control char "x" using A..Z[\]~? '
  139.     .ascii    "prefixed with a carat"<cr><lf>    ; /63/ added for clarity
  140.     .asciz    "RUBOUT    Send a break"<cr><lf><cr><lf>
  141. lis.ct:    .asciz    "ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]~?"
  142.     .even
  143.  
  144.  
  145.     .psect    $code
  146.     .sbttl    Initialization
  147.  
  148. doconn::call    opentt            ; /63/ open the link device
  149.     tst    r0            ; ok?
  150.     beq    10$            ; ya
  151.     return                ; nope, bail out
  152.  
  153. 10$:    .scca    #scca    ,#scca+4    ; kill ^C, this is reset by setcc
  154.     .cmkt    #cancel    ,#40        ; then dump setcc's mark timer
  155.     calls    t.ttyini,<#-1>        ; init terminal (w/flag for ^W)
  156.  
  157.     tst    conmsg            ; display sign-on text?
  158.     bne    40$            ; nope..
  159.     wrtall    #con.01            ; /63/ "Connecting to "
  160.     wrtall    #ttname            ; spell out the device name
  161.     wrtall    #con.02            ; /63/ "  DTE speed: "
  162.     call    ttspeed            ; get speed
  163.     tst    r0            ; wuz it gettable?
  164.     bne    20$            ; /62/ yup..
  165.     wrtall    #con.03            ; /63/ "N/A"
  166.     br    30$            ; continue
  167. 20$:    call    L10266            ; write speed in r0 as dec num to TT
  168. 30$:    wrtall    #con.04            ; /63/ <cr><lf>"Type ^"
  169.     mov    conesc    ,r0        ; get esc char
  170.     dec    r0            ; lis.ct here has no null entry
  171.     movb    lis.ct(r0),r0        ; make it printable
  172.     call    writ1ch            ; write it to TT
  173.     wrtall    #con.05            ; /63/ "C to return .."<cr><lf>
  174. 40$:    clr    conmsg            ; reset sign-on bypass flag
  175.     mov    sp    ,logini        ; /62/ force logerr msg into the clear
  176.  
  177.     clr    r4            ; init TT input buffer
  178.     tst    milnet            ; MILNET mode on?
  179.     beq    50$            ; no
  180.     mov    #xon+<xon*400>,r4    ; ya, stuff a couple XONs for remote
  181.  
  182. 50$:    .spfun    #rtwork,#xc.control,#stsdrv,#xcsts,#0,#1 ; /62/ get status
  183.  
  184.     clr    rt.v51            ; init version flag
  185.     tst    tsxcl            ; CL?
  186.     bne    70$            ; ya, skip this
  187.     tst    km.lock            ; /62/ if it's KM do it here which
  188.     bne    60$            ; /62/ keeps handler smaller..
  189.     cmpb    xcsts+1    ,#$xlv51    ; does this ver of XL eat LF after CR?
  190.     bgt    70$            ; ya
  191. 60$:    inc    rt.v51            ; no, flag it has to be done here
  192.  
  193. 70$:    mov    clkflg    ,r0        ; /62/ get number of ticks/second
  194.     asr    r0            ; /62/ number of ticks in 1/2 second
  195.     mov    r0    ,ststime+2    ; /62/ stuff into status check timer
  196.     mov    #tlist    ,r0        ; init flags for each task
  197. 80$:    tst    (r0)            ; end of the list?
  198.     beq    90$            ; ya
  199.     mov    sp    ,state(r0)    ; no, run each task to init itself
  200.     add    #hdsize    ,r0        ; bump to head of next task
  201.     br    80$            ; and loop back for it
  202.  
  203. 90$:    clr    crflag            ; no CR received from TT yet
  204.     clr    done            ; definitely not done
  205.     mov    #1    ,suspnd        ; don't miss a .rsum in the init pass
  206.  
  207.     mov    sp    ,xk.con        ; direct data read from handler here
  208.     tstb    @xkpoint        ; anything unused in buffer?
  209.     bne    100$            ; ya
  210.     call    readxk            ; get data or set completion routine
  211.     .br    100$            ; /63/
  212.  
  213.  
  214.     .sbttl    CONNECT main_loop
  215.  
  216. 100$:    mov    #tlist    ,r5        ; get top of the task list
  217. 110$:    tst    (r5)            ; end of the table now?
  218.     beq    130$            ; ya, go away until something happens
  219.     tst    state(r5)        ; runnable task?
  220.     beq    120$            ; no
  221.     jsr    pc    ,@(r5)        ; ya, do it
  222. 120$:    add    #hdsize    ,r5        ; next task control block please
  223.     br    110$            ; loop back for it
  224. 130$:    inc    suspnd            ; flag a .rsum is needed
  225.     .spnd                ; suspend ourself
  226.     tst    done            ; time to go now?
  227.     beq    100$            ; no, loop again
  228.  
  229.  
  230.     .sbttl    Shut_down and exit
  231.  
  232.     clr    xk.con            ; send completed reads data to binread
  233.     .cmkt    #cancel    ,#0        ; kill all marktime requests
  234.     call    clostt            ; /63/ close the link device
  235.     .newline            ; ensure exit is to a clean line
  236.     clr    logini            ; /62/ indicate cursor on a clean line
  237.     return
  238.  
  239.  
  240.     .sbttl    Scheduler's mark time completion routines
  241.  
  242. stsdone:mov    sp    ,sthead+state    ; /63/ make the status test runnable
  243.     br    rerun            ; /63/
  244.  
  245. xkredo:    mov    sp    ,xkhead+state    ; /63/ retry TT output, buff was full
  246.     br    rerun            ; /63/
  247.  
  248. ttdone:    tst    done            ; finished?
  249.     bne    S10$            ; ya, skip all this..
  250.     mov    sp    ,tthead+state    ; /63/ no, poll TT for possible input
  251.     .br    rerun            ; /63/
  252.  
  253. rerun:    tst    suspnd            ; need to resume?  /62/ add rerun ept
  254.     beq    S10$            ; nope..
  255.     dec    suspnd            ; ya, make sure no one else does it
  256.     .rsum                ; get scheduler going
  257. S10$:    return
  258.  
  259.  
  260.     .sbttl    Process TT input
  261.  
  262. ttproc:    tst    done            ; finished?
  263.     bne    140$            ; ya, don't eat possible type ahead..
  264.     tst    r4            ; previous input queued to send yet?
  265.     bne    140$            ; no, loop until it has been
  266.  
  267. 10$:    .ttinr                ; check for input waiting for term
  268.     bcs    130$            ; nothing to do
  269.  
  270.     tst    con8bit            ; SET CON 8?
  271.     bne    20$            ; ya
  272.     bic    #^c<177>,r0        ; no, strip any parity present
  273. 20$:    cmpb    r0    ,conesc        ; escape sequence?
  274.     bne    60$            ; no, dump character as is
  275.     mov    #5    ,r1        ; ya, wait up to five seconds
  276.     mul    clkflg    ,r1        ; for the next char
  277.  
  278. 30$:    .ttinr                ; try to get the next char
  279.     bcc    40$            ; got something valid
  280.     .twait    #twait    ,#short        ; nothing, wait one tick
  281.     sob    r1    ,30$        ; and try again
  282.     br    130$            ; exit as we did not get anything
  283. 40$:    tst    con8bit            ; SET CON 8?
  284.     bne    50$            ; ya
  285.     bic    #^c<177>,r0        ; strip junk from the character
  286. 50$:    cmpb    r0    ,conesc        ; another escape character?
  287.     beq    60$            ; yes, dump that character as is
  288.     call    concmd            ; console command processor
  289.     br    130$            ; if n.g. concmd will beep
  290.  
  291. 60$:    bit    #2    ,xcsts        ; /62/ remote asserted flow control?
  292.     beq    70$            ; no
  293.     save    <r0>            ; /62/ ya, save the input byte
  294.     beep                ; beep & continue, _OVERWRITING_ data
  295.     unsave    <r0>            ; /62/ by restoring input byte and
  296.     clr    r4            ; /62/ ensuring it's bit settable here
  297. 70$:    tst    tsxsav            ; running under TSX?
  298.     bne    90$            ; ya, skip LF processing..
  299.     tst    rt.v51            ; is this OLD XL/XC from RT-11 V5.1?
  300.     beq    90$            ; no
  301.     asr    crflag            ; ya, see if a CR precedes a LF
  302.     bcc    80$            ; last char was not a CR
  303.     cmpb    r0    ,#lf        ; ignore LINE FEEDs please, but only
  304.     beq    10$            ; when they follow a CR, that is..
  305. 80$:    cmpb    r0    ,#cr        ; is this a CR?
  306.     bne    90$            ; no
  307.     inc    crflag            ; yes, flag for next pass
  308.  
  309. 90$:    tst    duplex            ; need local echoing?
  310.     beq    110$            ; no
  311.     tst    tsxsav            ; TSX?
  312.     beq    100$            ; no
  313.     cmpb    r0    ,m.tsxr        ; is it TSX lead-in char?
  314.     beq    110$            ; ya, don't type this to TT
  315. 100$:    .ttoutr                ; echo the character
  316.  
  317. 110$:    setpar    r0    ,r0        ; set parity if enabled
  318.     tstb    r4            ; is this byte free?
  319.     bne    120$            ; no, use the hi byte for this char
  320.     bisb    r0    ,r4        ; ya, stuff the char in
  321.     schedule #rmhead        ; enable the send char via XL task
  322.     br    10$            ; and try for one more input byte
  323.  
  324. 120$:    swab    r4            ; swap bytes to
  325.     bisb    r0    ,r4        ; stuff second char into the hi one
  326.     swab    r4            ; bytes back into proper positions
  327.     return                ; waste no time, every inst counts..
  328.  
  329. 130$:    clr    state(r5)        ; don't come back right away
  330.     .mrkt    #ttmark,#ttwait,#ttdone,#3 ; sched another try for TT input
  331. 140$:    return
  332.  
  333.  
  334.     .sbttl    Send data from XL to TT
  335.  
  336. xkproc:    clr    r0            ; avoid sign extension
  337.     bisb    @xkpoint,r0        ; get next char
  338.     beq    60$            ; nothing left..
  339.     tst    con8bit            ; SET CON 7 or 8?
  340.     bne    10$            ; 8
  341.     bicb    #200    ,r0        ; 7, strip high bit
  342. 10$:    tst    tsxsav            ; TSX?
  343.     beq    20$            ; no
  344.     cmpb    r0    ,m.tsxr        ; lead-in char?
  345.     beq    30$            ; ya, don't type this to TT
  346. 20$:    .ttoutr                ; dump the char
  347.     bcs    50$            ; buffer full, go wait a bit
  348. 30$:    bit    #<log$co!log$on>,trace    ; /63/ logging enabled?
  349.     beq    40$            ; no
  350.     mov    #lun.lo    ,r1        ; log file chan, char is still in r0
  351.     call    putcr0            ; that's it folks
  352.     tst    r0            ; /62/ did it work?
  353.     beq    40$            ; /62/ ya
  354.     save    <r0>            ; /62/ no, save error code
  355.     beep                ; /62/ call attention to this!
  356.     unsave    <r0>            ; /62/ recover error code
  357.     call    logerr            ; /62/ handle the error
  358. 40$:    inc    xkpoint            ; bump to next byte
  359.     br    xkproc            ; loop for it
  360.  
  361. 50$:    .mrkt    #xkmark,#xktime,#xkredo,#13 ; output ring buffer is FULL
  362.     clr    state(r5)        ; wait for mark time to expire
  363.     return
  364.  
  365. 60$:    clr    state(r5)        ; no longer runnable
  366.     jmp    readxk            ; /63/ get more data from XL
  367.  
  368.  
  369.     .sbttl    Write one word from TT input to XL
  370.  
  371. rmproc:    tst    iopending        ; we still waiting for XL?
  372.     bne    10$            ; /62/ ya, don't wait too long..
  373.     mov    r4    ,rmbuff        ; copy the data
  374.     beq    20$            ; nothing to do
  375.     clr    r4            ; make TT input buffer available again
  376.     mov    sp    ,iopending    ; flag I/O is not yet completed
  377.     .writc    #xkwork,#lun.xk,#rmbuff,#1,#30$,#1 ; queue the write
  378. 10$:    jmp    rerun            ; /62/ check for more, rerun ttproc
  379.  
  380. 20$:    clr    state(r5)        ; done, no longer runnable
  381.     return
  382.  
  383.  
  384.     .sbttl    XL write completion routine
  385.  
  386. 30$:    clr    iopending        ; I/O no longer pending
  387.     return
  388.  
  389.  
  390.     .sbttl    Status_watcher
  391.  
  392. stproc:    mov    xcsts    ,r2        ; /62/ save prior status
  393.     .spfun    #rtwork,#xc.control,#stsdrv,#xcsts,#0,#1 ; /62/ present status
  394.     bcs    30$            ; failed
  395.     mov    xcsts    ,r1        ; /62/ copy of current status
  396.     tst    tsxcl            ; which handler is it?
  397.     bne    10$            ; CL uses bit 2
  398.     asr    r1            ; KM, XC and XL use bit 3
  399.     asr    r2            ; make it 2 here
  400. 10$:    bic    #^c<4>    ,r2        ; recover the carrier
  401.     bic    #^c<4>    ,r1        ; detect bits
  402.     cmp    r1    ,r2        ; any change?
  403.     beq    30$            ; no
  404.     beep                ; ya, make a small noise
  405.     wrtall    #con.06            ; /63/ "%KRTCON-W-Carrier "
  406.     tst    r1            ; did we loose it?
  407.     bne    20$            ; no, must have just gotten it
  408.     wrtall    #con.07            ; /63/ "lost"
  409.     call    ttxon            ; clear the driver just in case
  410.     br    30$
  411. 20$:    wrtall    #con.08            ; /63/ "detected"
  412. 30$:    clr    state(r5)            ; no longer runnable
  413.     .mrkt    #stsmark,#ststime,#stsdone,#7    ; reschedule us
  414.     return
  415.  
  416.  
  417.     .sbttl    Internal command processor
  418.  
  419. concmd:    call    strip0            ; /62/ strip parity, upcase if alpha
  420.     scan    r0    ,#C10$        ; look for a match
  421.     asl    r0            ; word offsets
  422.     jmp    @C20$(r0)        ; /62/ dispatch to the correct routine
  423.  
  424.     .save
  425.     .psect    $pdata            ; /62/ pull lower case stuff..
  426. C10$:    .byte    '/    ,'?    ,'B&137    ,'C&137    ,'H&137    ,'I&137
  427.     .byte    'Q&137    ,'R&137    ,'S&137    ,'X&137    ,'Z&137    ,'^    ,177
  428.     .byte    0
  429.     .even
  430.  
  431. C20$:    .word    con.$
  432.     .word    con.hl    ,con.hl    ,con.br    ,con.c    ,con.hl    ,con.i
  433.     .word    con.q    ,con.r    ,con.s    ,con.x    ,con.z    ,con.ctr,con.br
  434.     .restore
  435.  
  436.  
  437.     .sbttl    CONCMD sub-routines
  438.  
  439. con.$:    beep                ; bad command, ring the bell
  440.     return
  441.  
  442. con.c:    mov    sp    ,done        ; set flag to exit the emulator
  443.     return
  444.  
  445. con.i:    jmp    ttyhang            ; /62/ go toggle DTR
  446.  
  447. con.q:    bit    #log$op    ,trace        ; /62/ file open?
  448.     beq    con.$            ; /62/ no, go make a beep
  449.     bic    #log$co    ,trace        ; turn off console logging
  450.     return
  451.  
  452. con.r:    bit    #log$op    ,trace        ; file open?
  453.     beq    con.$            ; /62/ no, go make a beep
  454.     bis    #log$co    ,trace        ; yes, resume console logging
  455.     return
  456.  
  457. con.s:    .newline            ; /63/ added debug status
  458. con.s0:    bit    #log$op    ,trace        ; is a file open?
  459.     beq    10$            ; no
  460.     wrtall    #con.09            ; "Logfile is "
  461.     wrtall    #logfil            ; include file name
  462.     wrtall    #con.10            ; ", cur/max blk: "
  463.     mov    #lun.lo    ,r1        ; logfile lun
  464.     asl    r1            ; word indexing
  465.     mov    blknum(r1),r0        ; recover current block number
  466.     call    L10266            ; dump it to TT
  467.     wrtall    #con.11            ; "/"
  468.     mov    sizof(r1),r0        ; recover file size
  469.     call    L10266            ; dump that to TT too
  470.     bit    #log$co    ,trace        ; yes, resume console logging
  471.     br    20$
  472. 10$:    wrtall    #con.12            ; "No LOGFILE is open"
  473. 20$:    .newline
  474.     .newline
  475.     return
  476.  
  477. con.z:    call    hose            ; zap handler, then
  478. con.x:    jmp    ttxon            ; /62/ reset XOFF and send an XON
  479.  
  480. con.br:    .spfun    #rtwork,#xc.control,#brkdrv,#0,#1,#1 ; /62/ turn break on
  481.     .mrkt    #brkwrk,#break,#20$,#20    ; /62/ queue this to turn it off
  482.     return
  483.  
  484. 20$:    save    <r0>            ; /62/ this is a completion routine
  485.     .spfun    #rtwork,#xc.control,#brkdrv,#0,#0,#1 ; /62/ turn break off
  486.     unsave    <r0>
  487.     return
  488.  
  489. con.hl:    wrtall    #hlptxt            ; dump help text to terminal
  490.     jmp    con.s0            ; /63/ sho debug status
  491.  
  492.  
  493.     .sbttl    Send a control char ala VTCOM's ^x command
  494.  
  495. con.ctrl:mov    #5    ,r1        ; wait five seconds
  496.     mul    clkflg    ,r1        ; for the next char
  497.  
  498. 10$:    .ttinr                ; get possible ctrl character
  499.     bcc    20$            ; got something valid
  500.     .twait    #twait    ,#short        ; nothing, wait one tick
  501.     sob    r1    ,10$        ; next please
  502.     br    60$            ; exit as we did not get any data
  503. 20$:    call    strip0            ; /62/ strip parity, upcase if alpha
  504.     scan    r0    ,#lis.ctrl    ; a control char symbol?
  505.     tst    r0
  506.     bne    30$            ; ya
  507.     beep                ; no, beep for a n.g. char
  508.     br    60$
  509.  
  510. 30$:    setpar    r0    ,r0        ; set parity if enabled
  511.     tstb    r4            ; is this byte free?
  512.     bne    40$            ; no
  513.     bisb    r0    ,r4        ; ya, stuff the char in
  514.     br    50$            ; and try for another one
  515.  
  516. 40$:    swab    r4            ; swap bytes to
  517.     bisb    r0    ,r4        ; stuff second char into the hi one
  518.     swab    r4            ; bytes back into proper positions
  519.  
  520. 50$:    schedule #rmhead        ; dump the data down the line
  521. 60$:    return
  522.  
  523.  
  524.     .sbttl    Strip parity and upcase    ; /62/ moved this here, now shared..
  525.  
  526. strip0:    bic    #^c<177>,r0        ; strip parity
  527.     cmp    r0    ,#'a!40        ; convert
  528.     blo    10$            ; char
  529.     cmp    r0    ,#'z!40        ; to
  530.     bhi    10$            ; upper
  531.     bic    #40    ,r0        ; case
  532. 10$:    return
  533.  
  534.     .end
  535.