home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / pdp11 / k11rtt.mac < prev    next >
Text File  |  2020-01-01  |  16KB  |  611 lines

  1.     .title    k11rtt    mt terminal service for Kermit-11/RT
  2.     .ident    /1.0.01/
  3.  
  4. ;    28-May-84  09:06:31  Brian Nelson
  5. ;
  6. ;    Copyright (C) 1984 Change Software, Inc.
  7.  
  8.  
  9.  
  10.  
  11.  
  12.     .if ndf, K11INC
  13.     .ift
  14.     .include    /IN:K11MAC.MAC/
  15.     .endc
  16.  
  17.     .psect
  18.     .sbttl    definitions for multiple terminal support
  19.  
  20.     .mcall    .mtstat    ,.mtatch,.mtdtch,.mtget    ,.mtin
  21.     .mcall    .mtout    ,.mtprnt,.mtrcto,.mtset
  22.     .mcall    .mrkt    ,.cmkt    ,.twait    ,.ttinr
  23.     .enabl    gbl
  24.  
  25.     m.tsts    =    0        ; terminal status word
  26.     m.tst2    =    2        ; terminal status word number 2
  27.     m.tfil    =    4        ; character requiring fill
  28.     m.fcnt    =    5        ; number of fillers
  29.     m.twid    =    6        ; width
  30.     m.tstw    =    7        ; terminal status byte
  31.     m.nlun    =    4        ; number of terminals for .mtstat
  32.  
  33.  
  34.     .macro    $mterr            ; map multiple terminal service
  35.     movb    @#errbyt,r0        ; into a global error code
  36.     asl    r0            ; simple to do
  37.     mov    mterr(r0),r0        ; thats all there is to it
  38.     .endm    $mterr
  39.  
  40.  
  41.     .save
  42.     .psect    mtmap    ,rw,d,lcl,rel,con
  43.  
  44. lunmap:    .blkw    12            ; map LUNS to RT units
  45. mtsts:    .blkw    10            ; from the .mtstat call
  46. ttsts:    .blkw    10            ; for ttyini
  47. tmowrk:    .blkw    10            ; for mark time while reading
  48. ttsave:    .blkw    4
  49. ttctlc:    .blkw    1            ; for control C things in connect mode
  50. ttime:    .word    0,1            ; a tick sleep for .twait
  51.     .restore
  52.  
  53.  
  54.  
  55.  
  56.  
  57.     .sbttl    assign the terminal unit
  58.  
  59.  
  60.  
  61. m.assdev::
  62.     save    <r1>            ; we may want to use these
  63.     .mtstat    #rtwork    ,#mtsts        ; get terminal driver status
  64.     bcs    90$            ; oops
  65.     tst    mtsts+m.nlun        ; any multi tty support in exec?
  66.     beq    80$            ; no, thats fatal
  67.     call    ttpars            ; parse the device unit number
  68.     bcs    70$            ; bad device name
  69.     mov    r0    ,r1        ; save the unit number now
  70.     .mtatch    #rtwork,#kbiost,r1    ; try to attach the terminal now
  71.     bcs    90$            ; fatal error, exit
  72.     clr    r0            ; ok, exit with success
  73.     br    100$            ; bye
  74.  
  75. 70$:    mov    #er$dev    ,r0        ; return bad device name error
  76.     br    100$            ; bye
  77. 80$:    mov    #er$sup    ,r0        ; return missing support error
  78.     br    100$            ; bye
  79. 90$:    $mterr                ; map local error into global error
  80. 100$:    unsave    <r1>            ; pop local registers and exit
  81.     return
  82.  
  83.  
  84. m.deadev::
  85.     save    <r1>            ; save this one, folks
  86.     call    ttpars            ; parse the device name
  87.     bcs    70$            ; oops
  88.     mov    r0    ,r1        ; save the unit number now
  89.     .mtdtch    #rtwork,r1        ; do it
  90.     clr    r0            ; success
  91.     br    100$            ; bye
  92.  
  93. 70$:    mov    #er$dev    ,r0        ; bad device name error
  94.     br    100$            ; bye
  95. 100$:    unsave    <r1>            ; exit
  96.     return                ; dh
  97.  
  98.     .sbttl    initialize the terminal
  99.  
  100.  
  101. ;    T T Y I N I
  102. ;
  103. ;    input:    @r5    device name
  104. ;        2(r5)    LUN
  105. ;        4(r5)    modifiers
  106. ;
  107. ;    output:    r0    error code
  108.     ttmode    =    100 ! 10000 ! 40000
  109.  
  110. m.ttyini::
  111.     save    <r1,r2>            ; we will need this one
  112.     call    ttpars            ; get the unit number
  113.     bcs    70$            ; oops, return ER$DEV error
  114.     mov    2(r5)    ,r1        ; get the internal LUN to use
  115.     asl    r1            ; into a word offset
  116.     mov    r0    ,lunmap(r1)    ; so we can map lun into a unit
  117.     movb    #377    ,lunmap+1(r1)    ; say we have done this already
  118.     mov    r0    ,r1        ; save the unit number please
  119.     .mtatch    #rtwork,#kbiost,r1    ; ensure it's attached
  120.     mov    #ttsts    ,r2        ; point to the status area
  121.     .mtget    #rtwork,r2,r1        ; get the current terminal setting
  122.     bcs    90$            ; oops
  123.     bic    #2    ,m.tsts(r2)    ; no automatic cr/lf's please
  124.     bis    #ttmode    ,m.tsts(r2)    ; no lower case convert, no echo
  125.     bis    #200!100000,m.tst2(r2)    ; read and write pass all please
  126.     .mtset    #rtwork,r2,r1        ; set these please
  127.     bcs    90$            ; oops
  128.     mov    #1000    ,r2
  129. 10$:    calls    binrea    ,<2(r5),#-1>    ; eat anything that's pending please
  130.     dec    r2            ; don't loop forever please
  131.     beq    20$            ; exit the loop
  132.     tst    r0            ; did we get anything at all ?
  133.     beq    10$            ; yes, eat some more input
  134. 20$:    clr    r0            ; all done
  135.     br    100$            ; bye
  136.  
  137. 70$:    mov    #er$dev    ,r0        ; device name parse failed
  138.     br    100$            ; bye
  139.  
  140. 90$:    $mterr                ; map local error into a global one
  141. 100$:    unsave    <r2,r1>            ; pop and exit
  142.     return
  143.  
  144.  
  145.  
  146.  
  147.     .sbttl    save/restore terminal settings
  148.  
  149.  
  150. m.ttysav::
  151.     save    <r1>            ; we will use this one
  152.     call    ttpars            ; parse the unit number please
  153.     bcs    80$            ; oops
  154.     mov    r0    ,r1        ; copy the parsed unit number
  155.     .mtget    #rtwork,#ttparm,r1    ; get the current settings
  156.     bcs    90$            ; error
  157.     clr    r0            ; success
  158.     br    100$            ; bye
  159.  
  160. 80$:    mov    #er$dev    ,r0        ; bad device name
  161.     br    100$            ; bye
  162. 90$:    $mterr                ; error, map into global and exit
  163. 100$:    unsave    <r1>            ; pop this and exit
  164.     return
  165.  
  166.  
  167.  
  168. m.ttyrst::
  169.     save    <r1,r2>            ; we will use this one
  170.     clr    r2            ; was already attached
  171.     call    ttpars            ; parse the unit number please
  172.     bcs    80$            ; oops
  173.     mov    r0    ,r1        ; copy the parsed unit number
  174.     .mtset    #rtwork,#ttparm,r1    ; get the current settings
  175.     bcc    20$            ; it worked
  176.     cmpb    @#errbyt,#1        ; not attached?
  177.     bne    90$            ; no
  178.     .mtatch    #rtwork,#0,r1        ; yes, attach it
  179.     bcs    90$            ; oops
  180.     mov    sp    ,r2        ; flag we just attached it
  181.     .mtset    #rtwork,#ttparm,r1    ; get the current settings
  182.     bcs    90$            ; error
  183. 20$:    clr    r0            ; success
  184.     br    100$            ; bye
  185.  
  186. 80$:    mov    #er$dev    ,r0        ; bad device name
  187.     br    100$            ; bye
  188. 90$:    $mterr                ; error, map into global and exit
  189. 100$:    tst    r2            ; need to detach it again
  190.     beq    110$            ; no
  191.     .mtdtch    #rtwork,r1        ; yes, do it please
  192. 110$:    unsave    <r2,r1>            ; pop this and exit
  193.     return
  194.  
  195.  
  196.  
  197.  
  198.     .sbttl    binrea    read binary
  199.  
  200.  
  201. ;    B I N R E A
  202. ;
  203. ;    input:    @r5    LUN
  204. ;        2(r5)    timeout
  205. ;    output:    r0    error code
  206. ;        r1    character just read
  207.  
  208.  
  209. m.xbinre::
  210. m.binrea::
  211.     save    <r2,r3,r4>        ; we may want to use these here
  212.     clr    -(sp)            ; allocate a single character buffer
  213.     mov    sp    ,r4        ; and a pointer to it also
  214.     clr    -(sp)            ; allocate a mark time tim buffer
  215.     clr    -(sp)            ; simple
  216.     mov    sp    ,r2        ; and point to it
  217.     mov    @r5    ,r3        ; get the LUN
  218.     asl    r3            ; and map it into the unit number
  219.     movb    lunmap(r3),r3        ; simple
  220. ;-    .mtget    #rtwork,#ttsts,r3    ; get current terminal setting
  221. ;-    bcs    90$            ; oops
  222. ;-    bis    #ttmode    ,ttsts+m.tsts    ; set so we don't wait for anything
  223. ;-    .mtset    #rtwork,#ttsts,r3    ; set this please
  224. ;-    bcs    90$            ; can't set it for some reason
  225.     cmp    2(r5)    ,#-1        ; read without any wait ?
  226.     bne    40$            ; no
  227.  
  228.     .mtin    #rtwork,r4,r3,#1    ; read a single character now
  229.     bcs    80$            ; it worked
  230.     clr    r1            ; get the character into r1 now
  231.     bisb    @r4    ,r1        ; and exit with success
  232.     clr    r0            ; bye
  233.     br    100$            ; exit at last
  234.  
  235.  
  236. 40$:    mov    2(r5)    ,r1        ; get the timeout in seconds
  237.     mul    #60.    ,r1        ; into ticks now
  238. 50$:    .mtin    #rtwork,r4,r3,#1    ; do it please
  239.     bcc    60$            ; it worked, get the ch into r1
  240.     dec    r1            ; been here too long ?
  241.     beq    80$            ; yes, exit with error
  242.     tst    clkflg            ; /37/ is there a clock on system?
  243.     bne    55$            ; /37/ yes
  244.     cpuwait    #1            ; /37/ no, try loop for one tick
  245.     br    56$            ; /37/ very cpu speed dependent.
  246. 55$:    .twait    #rtwork,#ttime        ; sleep a moment please
  247. 56$:    br    50$            ; and try again please
  248.  
  249. 60$:    clr    r1            ; it worked, get the character and exit
  250.     bisb    @r4    ,r1        ; simple
  251.     clr    r0            ; success
  252.     br    100$
  253.  
  254. 80$:    mov    #er$nin    ,r0        ; no data today
  255.     br    100$            ; bye
  256.  
  257. 90$:    $mterr                ; map the error code into a global one
  258.  
  259. 100$:    add    #6    ,sp        ; pop local buffers
  260.     unsave    <r4,r3,r2>        ; pop registers and exit
  261.     return
  262.  
  263.  
  264. 200$:    mov    #1    ,r1        ; flag a timeout
  265.     return
  266.  
  267.  
  268.  
  269.  
  270.  
  271.     .sbttl    binary write
  272.  
  273.  
  274.  
  275. ;    B I N W R I
  276. ;
  277. ;    binwri( %loc buffer, %val buffer_size, %val lun )
  278. ;
  279. ;    output:    r0    error code
  280. ;
  281. ;    Assumption:    TTYINI has been called to map the Kermit LUN
  282. ;            into the RT11 unit number for the terminal.
  283.  
  284.  
  285.  
  286.  
  287. m.binwri::
  288.     save    <r1,r2,r3,r4,r5>    ; save registers we may need
  289.     sub    #20    ,sp        ; a save area for tt settings
  290.     clr    r0            ; preset no errors as of yet
  291.     mov    @r5    ,r1        ; get the string address
  292.     mov    2(r5)    ,r2        ; get the string length
  293.     beq    100$            ; nothing to do
  294.     mov    #ttsts    ,r3        ; for getting tt settings
  295.     mov    4(r5)    ,r4        ; the internal LUN
  296.     bne    10$            ; map LUN 0 to console
  297.     print    r1,r2            ; simple
  298.     clr    r0            ; no errors
  299.     br    100$            ; exit
  300.  
  301. 10$:    mov    sp    ,r5        ; point to the stack work area
  302.     asl    r4            ; times two    
  303.     tstb    lunmap+1(r4)        ; have we mapped the lun into unit?
  304.     beq    80$            ; no, fatal error
  305.     movb    lunmap(r4),r4        ; map into the rt11 unit number
  306.     .mtget    #rtwork,r3,r4        ; get current settings, set to wait
  307.     bcs    90$            ; oops, exit with the error code in r0
  308.     mov    (r3)+    ,(r5)+        ; copy the four words now
  309.     mov    (r3)+    ,(r5)+        ; copy the four words now
  310.     mov    (r3)+    ,(r5)+        ; copy the four words now
  311.     mov    (r3)+    ,(r5)+        ; copy the four words now
  312.     bit    #100    ,ttsts+m.tsts    ; is the wait bit set already ?
  313.     beq    20$            ; no, don't bother to clear it
  314.     bic    #100    ,ttsts+m.tsts    ; set so we will wait for buffer space
  315.     .mtset    #rtwork,#ttsts,r4    ; simple to set
  316. 20$:    .mtout    #rtwork,r1,r4,r2    ; do the output now
  317.     bcs    90$            ; oops, it failed for whatever reason
  318.     mov    -(r5)    ,-(r3)        ; restore the terminal settings
  319.     mov    -(r5)    ,-(r3)        ; restore the terminal settings
  320.     mov    -(r5)    ,-(r3)        ; restore the terminal settings
  321.     mov    -(r5)    ,-(r3)        ; restore the terminal settings
  322.     .mtset    #rtwork,r3,r4        ; simple
  323.     clr    r0            ; say it worked and exit
  324.     br    100$            ; bye
  325.  
  326. 80$:    mov    #er$map    ,r0        ; rt11 unit not mapped to internal LUN
  327.     br    100$            ; bye
  328. 90$:    $mterr                ; map mt error into global error code
  329.  
  330. 100$:    add    #20    ,sp        ; pop local work buffer
  331.     unsave    <r5,r4,r3,r2,r1>    ; pop the saved registers
  332.     return                ; and exit
  333.  
  334.  
  335.  
  336.  
  337.     .sbttl    parse terminal unit
  338.  
  339.  
  340. ;    T T P A R S
  341. ;
  342. ;    input:    @r5    address of RT11 Multiple terminal service unit string
  343. ;    output:    r0    unit in binary
  344.  
  345.  
  346. m.ttpars::
  347.     mov    r1    ,-(sp)        ; save scratch register please
  348.     mov    @r5    ,r0        ; get the address of the string
  349.     call    200$            ; check for legit character
  350.     bcs    110$            ; oops
  351.     movb    (r0)+    ,r1        ; get the first byte please
  352.     sub    #'0    ,r1        ; convert to binary
  353.     call    200$            ; check for legit character
  354.     bcs    110$            ; oops
  355.     movb    @r0    ,r0        ; get the next digit
  356.     beq    100$            ; nothing there then we are done
  357.     mul    #12    ,r1        ; something there, shift over by 10
  358.     sub    #'0    ,r0        ; and convert low digit to binary
  359.     add    r0    ,r1        ; add into the accumulator
  360. 100$:    mov    r1    ,r0        ; and return the result
  361.     clc                ; return success
  362. 110$:    mov    (sp)+    ,r1
  363.     return
  364.  
  365.  
  366. 200$:    tstb    @r0            ; null ?
  367.     beq    210$            ; yes, it's ok
  368.     cmpb    @r0    ,#'0        ; must only be digits today
  369.     blo    220$            ; oops
  370.     cmpb    @r0    ,#'9        ; 0..9
  371.     bhi    220$            ; bad device name
  372. 210$:    clc                ; device name ok so far
  373.     return                ; bye
  374. 220$:    sec                ; bad, set and exit
  375.     return
  376.  
  377.  
  378.     .sbttl    GTTNAM    get MT unit of current console (set tt:consol=nn)
  379.  
  380. ;    G T T N A M
  381. ;
  382. ;    input:    @r5    address of console name to be written
  383. ;    output:    @r5    current console name
  384. ;        consave    same thing
  385.  
  386.     .mcall    .mtstat
  387.  
  388. ;    data returned by .mtstat
  389. ;
  390. ;    offset    0    offset from RMON base to first TCB
  391. ;        2    offset from RMON base to the current console TCB
  392. ;        4    numer of luns generated into the exec
  393. ;        6    size of the TCB in bytes
  394. ;
  395. ;    Since the TCB does NOT contain a copy of the LUN in it, we have
  396. ;    to start with TCB number 0 and add in the TCB size until we get
  397. ;    the value of the offset to the current console's TCB.  Counting
  398. ;    this will give us the LUN for that TCB.
  399.  
  400. m.gttnam::
  401.     save    <r1,r2,r3>        ; save registers please
  402.     .mtstat    #rtwork,#mtsts        ; get info on mt service
  403.     clr    r3            ; current lun number, starts with zero
  404.     tst    mtsts+4            ; see if mt service is present?
  405.     beq    30$            ; no, ignore it for now
  406.     mov    mtsts+0    ,r1        ; offset to tcb for console interface
  407.     mov    mtsts+4    ,r2        ; number of tcb's generated in exec
  408. 10$:    cmp    r1    ,mtsts+2    ; find our tcb yet?
  409.     beq    20$            ; yes, exit
  410.     inc    r3            ; no, then lun := succ(lun)
  411.     add    mtsts+6    ,r1        ; add the tcb size in and compage offset
  412.     dec    r2            ; if more tcbs to do, then try again
  413.     bne    10$            ; next please
  414. 20$:
  415. 30$:    asl    r3            ; get word indexing please to map the
  416.     add    #200$    ,r3        ; value into a ascii string.
  417.     mov    @r5    ,r1        ; where to put it please
  418.     movb    (r3)+    ,@r1        ; copy a byte
  419.     cmpb    @r1    ,#40        ; but if it's a blank, then skip it
  420.     beq    40$            ; a space
  421.     inc    r1            ; not a space, bump the dest pointer
  422. 40$:    movb    (r3)+    ,(r1)+        ; copy the next character now
  423.     clrb    @r1            ; always make it .asciz
  424.     mov    @r5    ,r1        ; copy to consave:
  425.     mov    #consave,r2        ;
  426. 50$:    movb    (r1)+    ,(r2)+        ; simple to copy .asciz string
  427.     bne    50$            ; next please
  428. 100$:    clr    r0
  429.     unsave    <r3,r2,r1>
  430.     return
  431.  
  432.  
  433. ;    This is a rather dumb way to convert to ascii, but there are only
  434. ;    a few values,  and it is easier to test via downloading to my PDT
  435. ;    with Kermit since the PDT150 lacks DIV.
  436.  
  437. 200$:    .asciz    / 0 1 2 3 4 5 6 7 8 9/
  438.     .asciz    /101112131415161718/
  439.     .even
  440.  
  441.     global    <consave>
  442.  
  443.  
  444.  
  445. m.ttyfin::
  446.     call    ttpars            ; finish up mt service
  447.     mov    r0    ,r1        ; parse the device name
  448.     .mtdtch    #rtwork,r1        ; and detach the device now
  449.     clr    r0            ; return 'success'
  450.     return                ; and exit
  451.  
  452.  
  453.  
  454.     .sbttl    speed read and change
  455.  
  456. m.setspd::
  457.     save    <r1,r2,r3>        ; save temps that we will use
  458.     clr    r0            ; find the speed map now
  459. 10$:    tst    spdlst(r0)        ; reach the end of the table?
  460.     beq    80$            ; yes, return unknown speed
  461.     cmp    2(r5)    ,spdlst(r0)    ; table entry match the passed speed
  462.     beq    20$            ; yes
  463.     add    #2    ,r0        ; no, try the next one please
  464.     br    10$            ; next please
  465. 20$:    mov    spdmap(r0),r3        ; and get the speed setting bits
  466.     call    ttpars            ; parse the mt unit number
  467.     bcs    70$            ; oops
  468.     mov    r0    ,r1        ; save the unit number
  469.     .mtatch    #rtwork,#kbiost,r1    ; insure unit is attached
  470.     mov    #ttsts    ,r2        ; point to the status area
  471.     .mtget    #rtwork,r2,r1        ; get the current terminal setting
  472.     bcs    90$            ; oops
  473.     bic    #7400    ,m.tsts(r2)    ; clear out old speed bits
  474.     bis    r3    ,m.tsts(r2)    ; stuff the dz11 speed bits in
  475.     .mtset    #rtwork,r2,r1        ; set these please
  476.     bcs    90$            ; oops
  477.     clr    r0            ; all done
  478.     br    100$            ; bye
  479.  
  480. 70$:    mov    #er$dev    ,r0        ; device name parse failed
  481.     br    100$            ; bye
  482.  
  483. 80$:    mov    #er$spe    ,r0        ; unknown speed ?
  484.     br    100$
  485.  
  486. 90$:    $mterr                ; map local error into a global one
  487. 100$:    unsave    <r3,r2,r1>        ; pop and exit
  488.     return
  489.  
  490.  
  491. m.ttspee::
  492.     save    <r1,r2,r3>        ; save these please
  493.     call    ttpars            ; parse the mt unit number
  494.     bcs    70$            ; oops
  495.     mov    r0    ,r1        ; save the unit number
  496.     .mtatch    #rtwork,#kbiost,r1    ; insure unit is attached
  497.     mov    #ttsts    ,r2        ; point to the status area
  498.     .mtget    #rtwork,r2,r1        ; get the current terminal setting
  499.     bcs    90$            ; oops
  500.     mov    m.tsts(r2),r3        ; get the speed mask out now
  501.     bic    #^C7400    ,r3        ; drop all bits but the speed
  502.     clr    r0            ; now look for the correct speed map
  503. 10$:    tst    spdmap(r0)        ; reach the end of the list ?
  504.     bmi    80$            ; yes, return a speed of zero
  505.     cmp    r3    ,spdmap(r0)    ; setting match up now ?
  506.     beq    20$            ; yes
  507.     add    #2    ,r0        ; no, try again please
  508.     br    10$            ; next
  509. 20$:    mov    spdlst(r0),r0        ; a match, return the speed setting
  510.     br    100$            ; bye
  511.  
  512. 70$:    mov    #er$dev    ,r0        ; device name parse failed
  513.     br    100$            ; bye
  514.  
  515. 80$:    clr    r0            ; failure
  516.     br    100$            ; return a speed of zero then
  517.  
  518. 90$:    $mterr                ; map local error into a global one
  519. 100$:    unsave    <r3,r2,r1>        ; pop and exit
  520.     return
  521.  
  522.  
  523.     .save
  524.     .psect    $pdata
  525.  
  526. spdlst:    .word    50.    ,75.    ,110.    ,134.    ,150.    ,300.    ,600.
  527.     .word    1200.    ,1800.    ,2000.    ,2400.    ,3600.    ,4800.    ,7200.
  528.     .word    9600.    ,0    ,0
  529.  
  530. spdmap:    .word    0    ,400    ,1000    ,1400    ,2000    ,2400    ,3000
  531.     .word    3400    ,4000    ,4400    ,5000    ,5400    ,6000    ,6400
  532.     .word    7000    ,7400    ,-1
  533.  
  534.     .restore
  535.  
  536.  
  537.  
  538.     .sbttl    terminal i/o things we don't need, can't do or haven't done yet
  539.  
  540. m.ttxon::
  541. m.cantyp::
  542. m.ttset::
  543. m.ttydtr::
  544. m.ttrfin::
  545. m.ttrini::
  546.     clr    r0
  547.     return
  548.  
  549. m.ttyhan::
  550.     mov    #er$iop    ,r0
  551.     return
  552.  
  553.  
  554.     .mcall    .ttyin
  555.     jsw    =    44
  556.  
  557. m.kbread::
  558.     mov    r2    ,-(sp)
  559.     mov    r3    ,-(sp)
  560.     bis    #40000    ,@#jsw        ; enable lower case tt: input
  561.     bic    #10000    ,@#jsw        ; ditch single ch input please
  562.     mov    @r5    ,r1        ; a buffer to put the chars
  563.     mov    #80.    ,r3        ; size of the buffer here
  564. ;10$:    .scca    #area    ,#kmonbf    ; so we can catch control Z
  565. 10$:    .ttyin                ; read a character please
  566.     tstb    r0
  567.     beq    15$            ; a null
  568.     cmpb    r0    ,#'Z&37        ; control Z ?
  569.     beq    20$            ; yes
  570.     cmpb    r0    ,#'C&37        ; control C ?
  571.     beq    20$            ; yep
  572.     cmpb    r0    ,#15        ; carriage return ?
  573.     beq    30$            ; yep
  574.     movb    r0    ,(r1)+        ; return what we just got
  575.     cmpb    r0    ,#14        ; form feed ?
  576.     beq    40$            ; yep
  577. 15$:    sob    r3    ,10$        ; next please
  578. 20$:    mov    #er$eof    ,r0        ; say read error and exit
  579.     br    100$            ; bye
  580. 30$:    movb    #cr    ,(r1)+        ; return all terminators please
  581.     movb    #lf    ,(r1)+        ; simple
  582.     .ttyin                ; eat the line feed now
  583. 40$:    clrb    @r1
  584.     sub    @r5    ,r1        ; the length
  585.     clr    r0
  586. 100$:    mov    (sp)+    ,r3
  587.     mov    (sp)+    ,r2
  588.     return
  589.  
  590.  
  591.  
  592.  
  593. m.finrt::                ; /37/
  594.     clr    r0            ; /37/
  595.     return                ; /37/
  596.  
  597. m.senbrk::
  598.     calls    ttspee    ,<@r5>        ; get the remotes terminal speed
  599.     mov    r0    ,r2        ; save the old speed
  600.     calls    setspd    ,<@r5,#50.,2(r5)>;try to set it down to 50 baud
  601.     tst    r0            ; did it work ?
  602.     bne    100$            ; no, forget it
  603.     calls    binwri    ,<#200$,#2,2(r5)>;yes, send a null over
  604.     calls    setspd    ,<@r5,r2,2(r5)>    ; restore the terminal's speed
  605. 100$:    clr    r0
  606.     return
  607.  
  608. 200$:    .byte    0,0
  609.  
  610.     .end
  611.