home *** CD-ROM | disk | FTP | other *** search
/ kermit.columbia.edu / kermit.columbia.edu.tar / kermit.columbia.edu / test / pdp11 / krte80.mac < prev    next >
Text File  |  1996-10-17  |  67KB  |  2,420 lines

  1.     .title    krte80    kermit i/o for RSTS version 8
  2.  
  3.     .ident    /V04.64/
  4.  
  5. ; /E64/    05-May-96  John Santos
  6. ;
  7. ;    From K11E80.MAC.  Move messages to top.
  8. ;    Channel # in ttyini, xbinre, and pakwri is now a constant.
  9. ;    Add xbinr1 with channel # as argument.
  10. ;    Fake DTR and CD testing.
  11. ;    Make KBREAD return cmd$ex if ctrl/Z, cmd$ab if ctrl/C
  12. ;    Init clkflg, break in xinit
  13. ;    Add CANTIM (canonical time, not cancel timer for the VMS impaired)
  14. ;    Change delimiter mask for packet mode to be only packet characters
  15. ;    Change packet mode to be binary mode with xon (should be controlled
  16. ;    by whether XON flow control is enabled...)
  17. ;    l$ttyo, binmod are obsolete.
  18. ;    new wrtcnt routine, like wrtall, but gets passed the length of
  19. ;    the output string
  20. ;    wrtall, wrtcnt, writ1ch all call dowrite, write to channel 0 if
  21. ;    lun.tt is not open
  22.  
  23.     .psect    $code    ,ro,i,lcl,rel,con
  24.  
  25.  
  26. ;    define macros and things we want for KERMIT-11
  27.  
  28.     .include    /SY:[1,2]COMMON.MAC/
  29.     .iif ndf, xrb    , .error ; INCULDE for [1,2]COMMON.MAC failed
  30.  
  31.  
  32.  
  33.     .if ndf, KRTINC
  34.     .ift
  35.     .include    /IN:KRTMAC.MAC/
  36.     .endc
  37.  
  38.     .iif ndf, krtinc, .error ; INCLUDE for IN:KRTMAC.MAC failed
  39.  
  40.     .title    krte80        ; common.mac destroys our name
  41.  
  42.  
  43.  
  44. ;    Copyright (C) 1983,1984,1985 Change Software, Inc.
  45. ;    
  46. ;    
  47. ;    This software is furnished under a license and may
  48. ;    be  used  and  copied  only in accordance with the
  49. ;    terms of such license and with  the  inclusion  of
  50. ;    the  above copyright notice.  This software or any
  51. ;    other copies thereof may not be provided or other-
  52. ;    wise made available to any other person.  No title
  53. ;    to and ownership of the software is hereby  trans-
  54. ;    ferred.
  55. ;    
  56. ;    The information in this  software  is  subject  to
  57. ;    change  without notice and should not be construed
  58. ;    as a commitment by the author.
  59. ;
  60. ;
  61.  
  62.     .sbttl    the entry points
  63.  
  64. ;    In all cases, R0 will have the returned error code (zero for success)
  65. ;    For KBREAD and READ, R1 will have the size of the read
  66. ;    For BINREAD, R1 will have the character just read
  67. ;
  68. ;    The use of %LOC and %VAL are from VMS Pascal and Fortran.
  69. ;    %LOC means ADDRESS, whereas %VAL means literal. All call
  70. ;    formats assume the first argument is at 0(r5), the next
  71. ;    at 2(r5) and so on, as in:
  72. ;
  73. ;    clr    -(sp)            ; today's date by default
  74. ;    mov    #datebf    ,-(sp)        ; where to put the converted string
  75. ;    mov    sp    ,r5        ; call ASCDAT
  76. ;    call    ascdat            ; simple
  77. ;    cmp    (sp)+    ,(sp)+        ; all done
  78. ;
  79. ;    or by using the CALLS macro (defined in KRTMAC.MAC)
  80. ;
  81. ;    calls    ascdat    ,<#datebf,#0>
  82. ;
  83. ;
  84. ;    Any version of Kermit-11 which can not, due to the lack of
  85. ;    executive support, implement a function should return an
  86. ;    error of -1 in r0.  For instance, RT11 does not have any
  87. ;    executive primitives to do wildcarding directory lookup.
  88. ;
  89. ;
  90. ;
  91. ;
  92. ;    ASCDAT    ( %loc buffer, %val datevalue )
  93. ;    ASCTIM    ( %loc buffer, %val timevalue )
  94. ;    ASSDEV    ( %loc device_name )
  95. ;    BINREA    ( %val timeout )
  96. ;    BINWRI    ( %loc buffer, %val byte_count )
  97. ;    CANTIM    ( %loc buffer, %val datevalue, %val timevalue )
  98. ;    CANTYP    ( )
  99. ;    CHKABO    ( )
  100. ;    DCDTST    ( )
  101. ;    DODIR    ( %loc directory_string, %val lun )
  102. ;    DRPPRV    ( )
  103. ;    DSKUSE    ( %loc returned_string )
  104. ;    ECHO    ( %loc terminal_name )
  105. ;    EXIT    ( )
  106. ;    GETPRV    ( )
  107. ;    GETUIC    ( )
  108. ;    GTTNAM    ( %loc returned_ttname )
  109. ;    KBREAD    ( %loc buffer )
  110. ;    L$PCRL    ( )
  111. ;    L$TTYO    ( %loc buffer, %val bytecount )
  112. ;    LOGOUT    ( )
  113. ;    NAMCVT    ( %loc source_filename, %loc returned_normal_name )
  114. ;    NOECHO    ( %loc device_name )
  115. ;    QUOCHK    ( )
  116. ;    READ    ( %loc buffer, %val buffer_length, %val lun, %val block_number )
  117. ;    SETCC    ( )
  118. ;    SETSPD    ( %val speed )
  119. ;    SUSPEN    ( %val seconds, %val ticks )
  120. ;    SYSERR    ( %val error_number, %loc error_text_buffer )
  121. ;    TTRFIN    ( )
  122. ;    TTRINI    ( )
  123. ;    TTSPEE    ( )
  124. ;    TTYDTR    ( )
  125. ;    TTYFIN    ( )
  126. ;    TTYHAN    ( )
  127. ;    TTYINI    ( %val open_flags )
  128. ;    TTYPAR    ( %loc terminal_name, %val parity_code )
  129. ;    TTYRST    ( )
  130. ;    TTYSAV    ( %loc terminal_name )
  131. ;    TTYSET    ( %loc terminal_name )
  132. ;    WRITE    ( %loc buffer, %val buffer_length, %val lun, %val block_number )
  133. ;    XINIT    ( )
  134.  
  135.         .sbttl  Local data              ; /63/ consolidated here..
  136.  
  137.     lun.kb  ==    0        ; assume if channel 0 --> terminal
  138.     lun.in  ==    1        ; channel for input files
  139.     lun.ou  ==    2        ; channel for output files
  140.     lun.lo  ==    3        ; channel for packet and file logging
  141.     lun.tr  ==    3        ; same as lun.log
  142.     lun.ta  ==    4        ; for the TAKE command
  143.     lun.tt  ==    5        ; for RSX, the normal TI: channel
  144.     lun.sr  ==    6        ; channel for $search for RMSv2.0
  145.     lun.ti  ==    7        ; channel number for connected terminal
  146.     lun.xk  ==    7        ; Ditto, for clarity
  147.     lun.co  ==    10        ; used as is lin.ti for remote connect
  148.     lun.as  ==    11        ; used to attach to remote link device
  149.                     ; to fake a device assignment
  150.  
  151.     .psect    dirctx    ,rw,d,lcl,rel,con
  152. dirnam:    .blkb    120
  153. dirfir:    .blkb    42
  154. dirbuf:    .blkb    100
  155. diridx:    .word    0
  156. dirptr:    .word    dirbuf
  157. dcrlf:    .byte    15,12,0
  158.     .even
  159.  
  160.     .psect    buffer    ,rw,d,lcl,rel,con
  161. lunsize    =    17
  162. lokahd:    .word    0            ; /44/
  163. linit:    .blkw    20
  164. lpoint:    .blkw    20
  165. lsize:    .blkw    20
  166. lbuffer:.blkb    MAXLNG+<MAXLNG/10>    ; /42/ Bigger for LONG PACKETS
  167.     .even
  168. ttsave:    .blkb    40*15
  169. bufqsav:.blkb    15
  170.     .even
  171. ver9.x::.word    0
  172. $xon:    .byte    'Q&37
  173. $off:    .byte    'S&37
  174.  
  175. $albuf:    .blkb    ALSIZE
  176. $phnum:    .blkb    60
  177.  
  178.     .globl    albuff,phnum
  179.  
  180.     .psect    $pdata
  181.     .even
  182. splst:    .word    dlalst,dclst,dlclst,dlelst,pklst,djlst,dhlst,dzlst,dhvlst
  183.     .word    10$,10$,10$,10$,10$,10$
  184. 10$:    .word    0,0
  185. dlalst:    .word    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  186. dclst:    .word    -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1
  187. dlclst:    .word    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1
  188. dlelst:    .word    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1
  189. pklst:    .word    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1
  190. djlst:    .word    0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1
  191. dhlst:    .word    0., 50.,75.,110.,134.,150.,200.,300., 600.
  192.     .word    1200.,1800.,2400.,4800.,9600.,0.,0,-1
  193. dzlst:    .word    0., 50.,75.,110.,134.,150.,300.,600.,1200.
  194.     .word    1800.,2000.,2400.,3600.,4800.,7200.,9600.,-1
  195. dhvlst:    .word     0,  75.,110.,134.,150.,300.,600.,1200.
  196.     .word    1800.,2000.,2400.,4800.,0    ,9600.,19200.,-1
  197. sp.dev::.word    0
  198. sp.mod::.word    0            ; use 4!40 for delete and noheader
  199. fu$def::.word    177777            ; do we need a defdir for RMS11v2
  200.  
  201. ;/E64/
  202. ;    Useful delimiter masks
  203. ;    Let's only make protocol characters delimiters for transfers
  204. pakmsk:
  205.     .rept    2
  206.     .byte    ^B00101010
  207.     .byte    ^B00100100
  208.     .byte    0
  209.     .byte    ^B00000100
  210.     .rept    14
  211.     .byte    0
  212.     .endr
  213.     .endr
  214.  
  215. ;pakmsk:    .byte    ^B11110111
  216. ;    .byte    377
  217. ;    .byte    377
  218. ;    .byte    377
  219. ;    .rept    13
  220. ;    .byte    0
  221. ;    .endr
  222. ;    .rept    21
  223. ;    .byte    377
  224. ;    .endr
  225.  
  226. dlmmsk::.byte    ^B11110111        ; all chars except control C
  227.     .byte    ^B11111111
  228.     .rept    36
  229.     .byte    377
  230.     .endr
  231.     .even
  232.  
  233. dlmcc:    .rept    40
  234.     .byte    377
  235.     .endr
  236.     .even
  237.  
  238. ;xzmask:    .byte    ^B00100010        ; control E and A (/56/)
  239. ;    .byte    0
  240. ;    .byte    0
  241. ;    .byte    ^B00000101        ; control X and control Z please
  242. ;    .rept    34
  243. ;    .byte    0
  244. ;    .endr
  245.  
  246. hwcfg:    .asciz    "HWCFG"
  247. kp.res:    .byte    33 ,'> ,0        ; type this out to reset keypad
  248. kb:    .asciz    "_KB:"
  249. e80.01:    .asciz    "You lack the HWCFG privilege to assign a line"<cr><lf>
  250. e80.02:    .ascii    "? This copy of RSTS is missing the multiple private"<cr><lf>
  251.     .ascii    "delimiter SYSGEN option. Please include this option"<cr><lf>
  252.     .ascii    "in RSTS for KERMIT to function"
  253. crlf:    .byte    15 ,12 ,0
  254. crnolf:    .byte    15 ,0
  255. hndlst:    .byte    ttyhnd    ,pkbhnd    ,dmchnd    ,dmphnd    ,0
  256. wild:    .asciz    "*.*"
  257. trmtyp:    .byte    6.            ; /39/  vt100
  258.     .byte    13.            ; /39/  vt101
  259.     .byte    14.            ; /39/  vt102
  260.     .byte    15.            ; /39/  vt125
  261.     .byte    16.            ; /39/  vt131
  262.     .byte    17.            ; /39/  vt132
  263.     .byte    18.            ; /39/  vt220
  264.     .byte    19.            ; /39/  vt240
  265.     .byte    20.            ; /39/  vt241
  266.     .byte    21.            ; /39/  vt105
  267.     .byte    22.            ; /39/  vk100 (gigi)
  268.     .byte    23.            ; /39/  rt02
  269.     .byte    48.            ; /58/  VT330
  270.     .byte    49.            ; /58/  VT430
  271.     .byte    0            ; /39/  end
  272. ttdevl:    .asciz    "KLDCDLDEPKDJDHDZVH"
  273.     .even
  274.  
  275.     .sbttl    edits
  276.  
  277.  
  278. ;    05-Jan-84  14:34:01 BDN    Added  TT8BIT mode to line if no parity
  279. ;                since the terminal driver always strips
  280. ;                bit 7 even if the character is a delim.
  281.  
  282.  
  283.  
  284.  
  285.     .sbttl    macros
  286.  
  287.     .macro    clrfqb
  288.     call    $clrfq
  289.     .endm    clrfqb
  290.  
  291.     .macro    clrxrb
  292.     call    $clrxr
  293.     .endm    clrxrb
  294.  
  295.  
  296.     nodata    ==    13.        ; no data for terminal read
  297.     detkey    ==    27.        ; i/o to detached tt line
  298.  
  299.     .psect    USERMD    ,rw,d,gbl,rel,con
  300.     .psect    $code
  301.  
  302. xinit::    save    <r1>
  303.     call    seconds            ; /E64/ init clock
  304.     mov    #17.    ,break+2    ; /E64/ assume 60Hz for break length
  305.     cmp    #60.    ,clkflg        ; /E64/ 60Hz clock?
  306.     beq    5$            ; /E64/ yup..
  307.     mov    #14.    ,break+2    ; /E64/ fix break length for 50Hz
  308. 5$:    call    rmsini            ; /53/ Setup SST
  309.     mov    #$phnum    ,phnum        ; /51/
  310.     mov    #$albuf    ,albuff        ; /51/ Fill address in.
  311.     clrb    @phnum            ; /51/ Clear
  312.     clr    @albuff            ; /51/ Clear first word.
  313.     mov    #$cmdbuf,cmdbuf        ; /53/ $CMDBUF defined in KRTRMS
  314.     mov    #$argbuf,argbuf        ; /53/ $ARGBUF defined in KRTRMS
  315.     mov    sp    ,infomsg    ; /41/ msg displaying
  316.     clr    df$rat            ; stream ascii please for RSTS?
  317.     movb    #fb$stm    ,df$rfm        ; say so and exit
  318.     mov    #ttsave    ,r1        ; initialize the terminal char
  319.     mov    #15    ,r0        ; save area now.
  320. 10$:    movb    #377    ,(r1)+        ; the ttysave area is set up for
  321.     add    #40    ,r1        ; saving up to 15 (8) settings.
  322.     clrb    bufqsav(r0)        ; /40/ clear old buffer quotas
  323.     sob    r0    ,10$        ; makes it easy to save via LUN
  324.     calls    l$fss    ,<#kb>        ; open terminal on LUN.AS
  325.     movb    #opnfq    ,FIRQB+FQFUN    ; to fix things up if using
  326.     movb    #lun.tt    ,FIRQB+FQFIL    ; it's global please
  327.     aslb    FIRQB+FQFIL        ; times 2 please
  328.     CALFIP                ; simple
  329.     movb    FIRQB    ,r0        ; it can't fail !!
  330.     beq    20$            ; ok
  331.     direrr    r0            ; oops
  332. 20$:    call    inqv9            ; /40/ global flag for version 9.x
  333.     bcs    40$            ; /45/ Not version 9 or later
  334.     clrfqb                ; /45/ V9, get the JOB type
  335.     movb    #UU.SYS    ,FIRQB+FQFUN    ; /45/ Job stats, part 3
  336.     movb    #2    ,FIRQB+5    ; /45/ Subfunction code
  337.     .UUO                ; /45/ Do it please
  338.     mov    #proctype,r0        ; /45/ Address of process_type
  339.     clr    (r0)            ; /45/ Word sized
  340.     movb    FIRQB+20,(r0)        ; /45/ Save our process type now
  341.     clr    jobtype            ; /45/ Assume interactive
  342.     cmpb    (r0)    ,#PRO$NET    ; /45/ Is this a SET HOST job ?
  343.     beq    30$            ; /45/ Yes, let it be INTERACTIVE
  344.     cmpb    (r0)    ,#PRO$BAT    ; /45/ Is this a BATCH job ?
  345.     bne    30$            ; /45/ No, assume INTERACTIVE for now
  346.     mov    #JOB$BAT,jobtype    ; /45/ Set BATCH access
  347. 30$:                    ; /45/ Maybe more kinds in the future
  348. 40$:    call    inqter            ; /39/ get terminal type
  349.     movb    r0    ,vttype        ; /39/ same terminal type
  350.     cmp    jobtype    ,#JOB$BAT    ; /59/ Batch?
  351.     bne    50$            ; /59/ No
  352.     clr    vttype            ; /59/ Yes, dumb terminal
  353.     clr    blip            ; /59/ No packet count updates
  354. 50$:
  355.     clr    r0
  356.     unsave    <r1>
  357.     return
  358.  
  359.     .globl    lastli
  360.     .globl    df$rat,df$rfm,fb$stm,getuic,lun.tt,vttype
  361.     .globl    infomsg,inqter
  362.     .globl    jobtyp,procty        ; /E64/
  363.     .globl    ARGBUF,CMDBUF,$ARGBUF,$CMDBUF    ; /53/
  364.     .globl    RMSINI,BLIP        ; /53/
  365.     .globl    direr$            ; /E64/
  366.     .globl    seconds,clkflg,break    ; /E64/
  367.  
  368.  
  369.     .assume    JOB$INT eq 0        ; /45/
  370.  
  371.  
  372.     .sbttl    terminal initialization
  373.     .psect    $code
  374.  
  375.  
  376. ;    T T Y I N I
  377. ;
  378. ;    ttyini( %val ccflag )
  379. ;
  380. ;
  381. ;    input:    @r5    bitfield for ter$cc and ter$bi
  382. ;
  383. ;             if (r5) and ter$bi then use binary open
  384. ;                         else use multiple delimiters
  385. ;             if (r5) and ter$cc then set control c as delimiter
  386. ;             if (r5) and ter$xo then allow binary mode with XON
  387. ;
  388. ;    output:    r0    error codes
  389. ;
  390. ;
  391. ;     Ttyini sets the  appropiate terminal characteristics  for
  392. ;    the  device name  in #ttname and returns the  device open (or
  393. ;    attached) on logical unit lun.ti.  Errors are returned
  394. ;    in r0. For RSTS these could be the usual device not avail-
  395. ;    able or missing monitor feature.
  396. ;
  397. ;    useful things to add: device check for terminal
  398.  
  399. ttyini::save    <r2>
  400.     clr    lokahd            ; /44/ Clear lookahead
  401.     call    getprv            ; will need for binary open
  402.     mov    #lun.ti*2, r2        ; /E64/ set up channel #
  403.     clr    lpoint(r2)        ; clear offset into local buffer
  404.     clr    linit(r2)        ; we have not set fast packet mode
  405.     clr    lsize(r2)        ; we have not read anyting yet also
  406.     clrfqb                ; insure FIRQB and xrb are cleared
  407.     clrxrb                ; of undesirable defaults
  408.     mov    #ttname    ,r0        ; get address of device string
  409.     tstb    @r0            ; anything there ?
  410.     bne    10$            ; yes
  411.     calls    l$fss    ,<#kb>        ; no, use _KB:
  412.     br    20$
  413. 10$:    calls    l$fss    ,<r0>        ; do the usual .FSS to parse
  414. 20$:    tst    r0            ; the device name
  415.     bne    100$            ; oops
  416.     movb    #opnfq    ,FIRQB+FQFUN    ; open the device up now
  417.     movb    r2    ,FIRQB+FQFIL
  418.     bit    #ter$bi    ,(r5)        ; use straight binary mode today ?
  419.     beq    30$            ; no
  420.     mov    #100001    ,FIRQB+FQMODE    ; yes
  421.     bit    #ter$xo    ,(r5)        ; want xon/xoff to work normally ?
  422.     beq    30$            ; no
  423.     bis    #40    ,FIRQB+FQMODE    ; yes, add the mode in please
  424.  
  425. 30$:    bit    #ter$pa    ,(r5)        ; /E64/ use packet mode?
  426.     beq    35$            ; /E64/ no
  427.     mov    #100041    ,FIRQB+FQMODE    ; /E64/ yes
  428. 35$:    CALFIP                ; get fip to do it
  429.     movb    FIRQB    ,r0        ; fail ?
  430.     bne    100$            ; /E64/ yes
  431.     bit    #ter$bi    ,(r5)        ; use straight binary mode today ?
  432.     bne    50$            ; yes
  433.     clr    r0            ; assume control c's are ok
  434.     bit    #ter$cc    ,(r5)        ; did the caller want to allow ^C
  435.     beq    40$            ; yes
  436.     dec    r0            ; no, make control C a delimiter
  437.     br    45$
  438. 40$:    bit    #ter$pa    ,(r5)
  439.     beq    45$
  440.     inc    r0
  441.     mov    sp    ,linit(r2)
  442. 45$:    calls    setdlm    ,<#lun.ti,r0>    ; no, try to set up delimiter
  443. 50$:    tst    r0            ; did it work also
  444.     bne    80$            ; no
  445.     call    initer            ; yes, set the tty's characteristics
  446.     br    100$            ; and exit (with errors in r0)
  447. 80$:    cmpb    r0    ,#102        ; "missing special feature?"
  448.     bne    100$            ; no
  449.     wrtall    #e80.02            ; /E64/ yes, make it reasonable
  450. 100$:    call    drpprv            ; no longer want privs please
  451.     tst    r0            ; /E64/ any error?
  452.     beq    110$            ; /E64/ no
  453.     direrr    r0            ; /E64/ report it
  454. 110$:    unsave    <r2>
  455.     return
  456.  
  457.     .sbttl    close up a terminal line
  458.  
  459.  
  460. ttyfin::save    <r1,r2,r3>
  461.     calls    ttpars    ,<#ttname>    ; get unit number
  462.     mov    r0    ,r3        ; save it
  463.     movb    FIRQB    ,r0        ; check for any errors from parse
  464.     bne    100$            ; oops
  465.     calls    clrdlm    ,<#lun.ti>    ; clear private delimiters
  466.     mov    #lun.ti*2, r0        ; channel # times 2
  467.     clr    lsize(r0)        ; nothing in packet buffer
  468.     clr    linit(r0)        ; not using packet buffering now
  469.     clrfqb                ; close the terminal
  470.     movb    #clsfq    ,FIRQB+FQFUN    ; fip subfunction for closing lun
  471.     movb    #lun.ti*2,FIRQB+FQFIL    ; channel number
  472.     CALFIP                ; close it now
  473.     movb    FIRQB    ,r0        ; get any errors from close
  474.     bne    100$            ; oops, just exit then
  475.     mov    #lun.ti    ,r1        ; get the channel number
  476.     clrfqb                ; /40/ insure no unpleasant effects
  477.     movb    #UU.TRM    ,FIRQB+FQFUN    ; /40/ uuo code for terminals
  478.     incb    FIRQB+4            ; /40/ subfunction one
  479.     movb    r3    ,FIRQB+5    ; /40/ unit number or 377
  480.     movb    bufqsav(r1),FIRQB+27    ; /40/ restore old buffer quotas
  481.     .UUO                ; /40/ ignore errors
  482.     mul    #40    ,r1        ; offset into the TTSAVE area
  483.     add    #ttsave    ,r1        ; finally, the address of saved stuff
  484.     cmpb    @r1    ,#377        ; but is the saved stuff real ?
  485.     beq    100$            ; no
  486.     mov    r1    ,-(sp)        ; yes, try to set terminal chars
  487.     mov    #FIRQB    ,r2        ; where to put the parameters
  488.     mov    #40    ,r0        ; number of bytes to copy
  489. 10$:    movb    (r1)+    ,(r2)+        ; do a byte please
  490.     sob    r0    ,10$        ; next
  491.     clrb    FIRQB+4            ; Version 9 fix here
  492.     bisb    FIRQB+36,FIRQB+20    ; UU.TRM returns 8bit setting here
  493.     clr    FIRQB+36        ; insure unused for future rsts/e?
  494.     movb    #UU.TRM    ,FIRQB+FQFUN    ; uuo subfunction for terminals
  495.     movb    r3    ,FIRQB+5    ; stuff the unit number in
  496.     .UUO                ; try to do it
  497.     movb    FIRQB    ,r0        ; save any errors    
  498.     mov    (sp)+    ,r1        ; get the ttsave address back
  499.     movb    #377    ,@r1        ; mark as being invalid
  500. 100$:    unsave    <r3,r2,r1>        ; pop registers and exit
  501.     return
  502.  
  503.  
  504.     .sbttl    get terminal name
  505.  
  506. ;    G T T N A M
  507. ;
  508. ;    input:    @r5    address of 8 character buffer for terminal name
  509. ;    output:        .asciz name of terminal
  510.  
  511. gttnam::save    <r0,r1,r2>        ; may as well save it
  512.     mov    @r5    ,r2        ; now return the name
  513.     movb    #'_    ,(r2)+        ; return _KBnn:
  514.     movb    #'K    ,(r2)+        ; return _KBnn:
  515.     movb    #'B    ,(r2)+        ; return _KBnn:
  516.     clrfqb                ; assume defaults
  517.     movb    #UU.SYS    ,FIRQB+FQFUN    ; for a systat part one
  518.     .UUO                ; simple
  519.     movb    FIRQB+5    ,r1        ; get the name
  520.     bmi    90$            ; detached ?
  521.     clr    r0            ; now compute the ascii name
  522.     div    #100.    ,r0        ; /19/ lots of terminals on system?
  523.     tst    r0            ; /19/ ge kb100: ?
  524.     beq    10$            ; /19/ no
  525.     add    #'0    ,r0        ; /19/ convert the 100's part of unit
  526.     movb    r0    ,(r2)+        ; /19/ and copy it please
  527. 10$:    clr    r0            ; /19/ get the low two digits please
  528.     div    #10.    ,r0        ; simple
  529.     add    #'0    ,r0
  530.     add    #'0    ,r1
  531.     movb    r0    ,(r2)+
  532.     movb    r1    ,(r2)+
  533. 90$:    movb    #':    ,(r2)+
  534.     clrb    @r2
  535.     unsave    <r2,r1,r0>
  536.     return
  537.     
  538.  
  539.  
  540.     .sbttl    set delimiter bitmask up please
  541.  
  542.  
  543. ;    S E T D L M
  544. ;
  545. ;!    setdlm( %val channel_number, %val cc_flag )
  546. ;
  547. ;    input:    @r5    channel number to use
  548. ;        2(r5)    control/c flag
  549. ;
  550. ;    output:    r0    error code (would be missing sysgen feature)
  551.  
  552.  
  553. snoecho:mov    #xrb    ,r0        ; pointer to parameter block
  554.     mov    #3    ,(r0)+        ; function to disable echo
  555.     clr    (r0)+            ; unused
  556.     clr    (r0)+            ; unused
  557.     movb    2(sp)    ,@r0        ; channel number
  558.     aslb    (r0)+            ; times 2
  559.     movb    #ttyhnd    ,(r0)+        ; driver index (ttdvr)
  560.     clr    (r0)+            ; unused
  561.     clr    (r0)+            ; unused
  562.     clr    (r0)+            ; unused
  563.     .spec                ; now do it
  564.     movb    FIRQB    ,r0        ; return any errors
  565.     mov    (sp)+    ,(sp)        ; pop arg list and exit
  566.     return                ; exit
  567.  
  568.  
  569. setdlm::mov    @r5    ,-(sp)
  570.     call    snoecho
  571.     mov    #xrb    ,r0        ; setup to set a private delim
  572.     mov    #11    ,(r0)+        ; mask now. function code is 11
  573.     mov    #40    ,(r0)+        ; for .spec, 40 byte to copy
  574.     mov    #dlmmsk    ,(r0)+        ; address of delimiter mask
  575.     tst    2(r5)            ; allow control c's to come in
  576.     beq    10$
  577.     bmi    5$
  578.     mov    #pakmsk    ,-2(r0)
  579.     br    10$
  580. 5$:     mov    #dlmcc    ,-2(r0)
  581. 10$:    movb    @r5    ,@r0        ; channel number
  582.     aslb    (r0)+            ; times 2
  583.     movb    #ttyhnd    ,(r0)+        ; device driver index
  584.     clr    (r0)+            ; default to console device
  585.     clr    (r0)+            ; unused
  586.     mov    #1    ,(r0)+        ; subfunction SET DELIMITER
  587.     .spec                ; and do it please
  588.     movb    FIRQB    ,r0        ; did it work ?
  589.     return
  590.  
  591.  
  592.  
  593.  
  594. clrdlm::
  595.     mov    #xrb    ,r0        ; point to it please
  596.     mov    #11    ,(r0)+        ; subfunction 
  597.     clr    (r0)+            ; must be 0
  598.     clr    (r0)+            ; also 0
  599.     movb    @r5    ,@r0        ; channel number please
  600.     aslb    (r0)+
  601.     movb    #ttyhnd    ,(r0)+        ; device driver to call
  602.     clr    (r0)+            ; use channel number
  603.     clr    (r0)+            ; must be zero
  604.     clr    (r0)+            ; subfunction 0
  605.     .spec                ; and call ttdvr
  606. 100$:    return
  607.  
  608.  
  609.  
  610.     .sbttl    special init for receiving files
  611.  
  612. ;/E64/    Nothing seems to call this stuff anymore.
  613. ;    Due to what I would consider a RSTS terminal driver
  614. ;    bug ( .ttddt isn't cleared if you do a read without
  615. ;    wait and  there was  no data)  we have to call this
  616. ;    before we receive any files from a remote kermit.
  617.  
  618. ;ttrini::mov    #xrb    ,r0        ; setup to set a private delim
  619. ;    mov    #11    ,(r0)+        ; mask now. function code is 11
  620. ;    mov    #40    ,(r0)+        ; for .spec, 40 byte to copy
  621. ;    mov    #xzmask    ,(r0)+        ; address of delimiter mask
  622. ;    movb    #lun.tt    ,@r0        ; channel number
  623. ;    aslb    (r0)+            ; times 2
  624. ;    movb    #ttyhnd    ,(r0)+        ; device driver index
  625. ;    clr    (r0)+            ; default to console device
  626. ;    clr    (r0)+            ; unused
  627. ;    mov    #1    ,(r0)+        ; subfunction SET DELIMITER
  628. ;    .spec                ; and do it please
  629. ;    return
  630.  
  631.  
  632. ;ttrfin::calls    clrdlm    ,<#lun.tt>
  633. ;    return
  634.  
  635.  
  636.  
  637.  
  638.     .sbttl    other things like echo off and on
  639.  
  640.  
  641. ;    N O E C H O
  642. ;
  643. ;
  644. ;    input:    @r5    terminal name or null or 0 for current terminal
  645. ;    output:    r0    error code
  646.  
  647.  
  648. noecho::save    <r1>            ; save a temp register
  649.     clr    r0            ; assume our terminal
  650.     mov    @r5    ,r1        ; passed address of 0 or a null string?
  651.     beq    10$            ; no address, assume _KB:
  652.     tstb    @r1            ; null string passed ?
  653.     beq    10$            ; yes, assume the console terminal
  654.     call    ttpars            ; parse the terminal device name
  655.     bcs    90$            ; oops
  656.     cmpb    r0    ,#377        ; own terminal ?
  657.     bne    10$            ; no
  658.     call    myterm            ; yes, get correct unit number then
  659. 10$:    clrxrb                ; insure no defaults
  660.     mov    #xrb    ,r1        ; point to the xrb now
  661.     mov    #3    ,(r1)+        ; disable function for .SPEC
  662.     mov    r0    ,(r1)+        ; terminal number or zero for _KB:
  663.     movb    #ttyhnd    ,xrb+7        ; and the device driver index please
  664.     .spec                ; simple
  665.  
  666. 90$:    movb    FIRQB    ,r0        ; error, return it please
  667. 100$:    unsave    <r1>            ; pop the register we saved
  668.     return
  669.  
  670.  
  671. ;    E C H O
  672. ;
  673. ;    input:    @r5    terminal name or null or 0 for current terminal
  674. ;    output:    r0    error code
  675.  
  676.  
  677. echo::    save    <r1>            ; save a temp register
  678.     clr    r0            ; assume our terminal
  679.     mov    @r5    ,r1        ; passed address of 0 or a null string?
  680.     beq    10$            ; no address, assume _KB:
  681.     tstb    @r1            ; null string passed ?
  682.     beq    10$            ; yes, assume the console terminal
  683.     call    ttpars            ; parse the terminal device name
  684.     bcs    90$            ; oops
  685. 10$:    clrxrb                ; insure no defaults
  686.     mov    #xrb    ,r1        ; point to the xrb now
  687.     mov    #2    ,(r1)+        ; enable echo function for .SPEC
  688.     mov    r0    ,(r1)+        ; terminal number or zero for _KB:
  689.     movb    #ttyhnd    ,xrb+7        ; and the device driver index please
  690.     .spec                ; simple
  691.  
  692. 90$:    movb    FIRQB    ,r0        ; error, return it please
  693. 100$:    unsave    <r1>            ; pop the register we saved
  694.     return
  695.  
  696.  
  697.  
  698.  
  699.     .sbttl    write and read
  700.  
  701. ;    W R I T E
  702. ;
  703. ;!    write( %loc buffer, %val buffer_length, %val channel_number,
  704. ;!           %val block_number )
  705. ;
  706. ;
  707. ;    input:    @r5    buffer address
  708. ;        2(r5)    buffer length
  709. ;        4(r5)    channel number
  710. ;        6(r5)    block number
  711. ;
  712. ;    output:    r0    error code
  713.  
  714.  
  715. write::    mov    #xrb    ,r0        ; address of xrb parameter block
  716.     mov    2(r5)    ,(r0)+        ; buffer length
  717.     mov    2(r5)    ,(r0)+        ; byte count for the i/o
  718.     mov    @r5    ,(r0)+        ; address of the buffer
  719.     movb    4(r5)    ,@r0        ; channel number
  720.     aslb    (r0)+            ; times 2
  721.     clrb    (r0)+            ; unused
  722.     clr    (r0)+            ; unused
  723.     clr    (r0)+            ; unused
  724.     clr    (r0)+            ; unused
  725.     mov    6(r5)    ,xrb+xrblk    ; forgot to stuff this one in
  726.     .WRITE
  727.     movb    FIRQB    ,r0        ; return error code and exit
  728.     return
  729.  
  730.  
  731.  
  732. ;    R E A D
  733. ;
  734. ;!    read( %loc buffer, %val buffer_length, %val channel_number,
  735. ;!           %val block_number )
  736. ;
  737. ;    input:    @r5    buffer address
  738. ;        2(r5)    buffer length
  739. ;        4(r5)    channel number
  740. ;        6(r5)    block number
  741. ;
  742. ;    output:    r0    error code
  743. ;        r1    byte count for read
  744.  
  745.  
  746. read::    mov    #xrb    ,r0        ; address of xrb parameter block
  747.     mov    2(r5)    ,(r0)+        ; buffer length
  748.     clr    (r0)+            ; must be zero
  749.     mov    @r5    ,(r0)+        ; address of the buffer
  750.     movb    4(r5)    ,@r0        ; channel number
  751.     bne    10$            ; /52/ Not Chan zero
  752.     .TTECH                ; /52/ Chan zero, insure echo
  753. 10$:    aslb    (r0)+            ; times 2
  754.     clrb    (r0)+            ; unused
  755.     clr    (r0)+            ; unused
  756.     clr    (r0)+            ; unused
  757.     clr    (r0)+            ; unused
  758.     mov    6(r5)    ,xrb+xrblk    ; forgot to stuff this one in
  759.     .READ
  760.     clr    r1            ; /36/ assume error
  761.     movb    FIRQB    ,r0        ; return error code and exit
  762.     bne    100$            ; /36/ insure zero bytecount on error
  763.     mov    xrb+xrbc,r1
  764. 100$:    return
  765.  
  766. kbread::.TTECH
  767.     calls    read    ,<@r5,#80.,#0,#0> ; do the actual read now
  768.     cmpb    r0    ,#11.        ; /E64/ ctrl/Z?
  769.     bne    10$            ; /E64/ no
  770.     mov    #cmd$ex    ,r0        ; /E64/ yes, so tell caller
  771. 10$:    tst    cccnt            ; /E64/ ctrl/c typed?
  772.     beq    20$            ; /E64/ no
  773.     mov    #cmd$ab    ,r0        ; /E64/ yes, so tell caller
  774.     clr    r1            ; /E64/ and signal no input
  775. 20$:    mov    r1    ,-(sp)        ; /36/ save byte count
  776.     add    @r5    ,r1        ; /36/ point to end to make it .asciz
  777.     clrb    @r1            ; /36/ .asciz
  778.     mov    (sp)+    ,r1        ; /36/ restore length
  779.     return
  780.  
  781.     .globl    cmd$ex    ,cmd$ab    ,cccnt    ; /E64/
  782.  
  783.  
  784.     .sbttl    terminal read/write binary mode
  785.  
  786.  
  787. ;    B I N R E A
  788. ;
  789. ;!    binread( %val timeout )
  790. ;
  791. ;
  792. ;    input:    @r5    timeout    (if -1, then no wait)
  793. ;
  794. ;    output:    r0    error
  795. ;        r1    character read
  796. ;
  797. ;    assumptions:    the terminal has all characters set up
  798. ;            as private delimeters
  799. ;
  800. ;
  801. ;    BINREAD is called ONLY for packet reading.
  802. ;    XBINREA is called for general single character data reading
  803. ;
  804. ;
  805. ; /44/    If a packet reads gets ESC<letter>, where LETTER is in the
  806. ;    range 100-137,  then we can safely assume that the version
  807. ;    9 terminal driver did us the favor of converting a C1 char
  808. ;    into the equivalent (?) escape sequence. What a hack!
  809.  
  810.  
  811. pakrea::
  812. binrea::tstb    lokahd+1        ; /44/ Anything REALLY there?
  813.     bne    90$            ; /44/ Yes, use it
  814.     call    doread            ; /44/ Read next character
  815.     tst    r0            ; /44/ Success?
  816.     bne    100$            ; /44/ No, just exit with error
  817.     cmpb    r1    ,#33        ; /44/ Escape character?
  818.     bne    100$            ; /44/ No, use it as is
  819.     call    doread            ; /44/ Yes, look for char in 100..137
  820.     tst    r0            ; /44/ Should always work
  821.     bne    95$            ; /44/ But if not, return( '\033' )
  822.     cmpb    r1    ,#100        ; /44/ Is it in the range of \0100
  823.     blo    80$            ; /44/ to \0137 ?
  824.     cmpb    r1    ,#137        ; /44/ Well ?
  825.     bhi    80$            ; /44/ Yes, we can't control it then
  826.     bisb    #100    ,r1        ; /44/ In range, restore to CORRECT
  827.     br    100$            ; /44/ format of CTL+0100
  828.  
  829. 80$:    incb    lokahd+1        ; /44/ Invalid, set lookahead flag
  830.     movb    r1    ,lokahd+0    ; /44/ Save the data please
  831.     movb    #33    ,r1        ; /44/ Return( '\033' )
  832.     br    100$            ; /44/ for next read and exit
  833.  
  834. 90$:    clr    r1            ; /44/ Setup for lookahead data
  835.     bisb    lokahd    ,r1        ; /44/ Insert lookahead data
  836. 95$:    clr    lokahd            ; /44/ No more lookhahead data
  837.     clr    r0            ; /44/ No errors
  838. 100$:    return                ; /44/ Exit
  839.  
  840.  
  841.  
  842.     .sbttl    Really read next character in the buffer now
  843. doread:    save    <r2>            ; save temp register
  844. 5$:    mov    #lun.ti*2,r2        ; get the channel number * 2
  845.     tst    linit(r2)        ; has this lun ever been set
  846.     beq    20$            ; up for a partial delimiter mask?
  847.     tst    lsize(r2)        ; yes, is there any data waiting?
  848.     bgt    10$            ; yes, get whats already there
  849.     clr    lpoint(r2)        ; no, clear the pointer
  850.     clr    lsize(r2)        ; insure buffer size is zero
  851.     call    rget            ; and read a record if possible
  852.     tst    r0            ; if it fails, revert to 1 char
  853.     bne    100$            ; i/o
  854. 10$:    dec    lsize(r2)        ; one less character in buffer
  855.     bmi    5$            ; if < 0, nothig was read. do it again
  856.     mov    lpoint(r2),r0        ; get the offset into the buffer
  857.     inc    lpoint(r2)        ; and prime this for next time
  858.     clr    r1            ; avoid pdp-11 sign extension
  859.     bisb    lbuffer(r0),r1        ; get the character from the buffer
  860.     clr    r0            ; no errors
  861.     br    100$            ; and exit
  862. 20$:    call    xbinrea            ;
  863. 100$:    unsave    <r2>            ; pop temp register and exit
  864.     return                ;
  865.  
  866. rget:    mov    #xrb    ,r0        ; address of xrb parameter block
  867.     mov    #MAXLNG    ,(r0)+        ; /42/ buffer length
  868.     clr    (r0)+            ; must be zero
  869.     mov    #lbuffer,(r0)+
  870.     movb    r2    ,(r0)+        ; channel number
  871.     bne    5$            ; /52/ Not zero
  872.     .TTECH                ; /52/ Zero, insure echoing
  873. 5$:    clrb    (r0)+            ; unused
  874.     clr    (r0)+            ; unused
  875.     cmp    (r5)    ,#-1        ; no wait ?
  876.     bne    10$            ; no
  877.      clr    (r0)+            ; yes
  878.      mov    #8192.    ,(r0)+        ; stuff return without wait in
  879.      br    20$            ; and do it
  880. 10$:    mov    (r5)    ,(r0)+        ; timeout
  881.     clr    (r0)+            ; unused
  882. 20$:    .READ
  883.     movb    FIRQB    ,r0        ; return error code and exit
  884.     beq    30$            ; /45/ No errors
  885.     cmpb    r0    ,#DETKEY    ; /45/ I/O to detached Keyboard ?
  886.     bne    100$            ; /45/ No
  887.     mov    #1    ,XRB+0        ; /45/ Yes, sleep a moment
  888.     .SLEEP                ; /45/ ...
  889.     br    100$            ; /45/ Exit
  890. 30$:    mov    xrb+xrbc,lsize(r2)    ; Read size, save it
  891.     clr    lpoint(r2)
  892.     add    #1    ,rdrate+4    ; /56/ Stats
  893.     bcs    40$            ; /56/ Overflowed
  894.     add    lsize(r2),rdrate+2    ; /56/ Count the data
  895.     adc    rdrate+0        ; /56/ 32 bits worth
  896.     br    100$            ; /56/ And exit
  897. 40$:    clr    rdrate+0        ; /56/ Overflow, so reset
  898.     clr    rdrate+2        ; /56/ Overflow, so reset
  899.     clr    rdrate+4        ; /56/ Overflow, so reset    
  900. 100$:    return
  901.  
  902.     .globl    rdrate        ; /56/
  903.  
  904.     .enabl    lsb
  905. xbinr1::movb    2(r5)    ,r1        ; /E64/ get channel #
  906.     br    1$            ; /E64/ skip setup
  907.  
  908. xbinre::movb    #lun.ti    ,r1        ; /E64/ always this lun
  909. 1$:    mov    #xrb    ,r0        ; address of xrb parameter block
  910.     mov    #1    ,(r0)+        ; buffer length
  911.     clr    (r0)+            ; must be zero
  912.     clr    -(sp)            ; allocate buffer on the stack
  913.     mov    sp    ,(r0)+        ; address of the buffer
  914.     movb    r1    ,@r0        ; channel number
  915.     bne    5$            ; /52/ Not zero
  916.     .TTECH                ; /52/ Zero, insure echoing
  917. 5$:    aslb    (r0)+            ; times 2
  918.     clrb    (r0)+            ; unused
  919.     clr    (r0)+            ; unused
  920.     cmp    (r5)    ,#-1        ; no wait ?
  921.     bne    10$            ; no
  922.      clr    (r0)+            ; yes
  923.      mov    #8192.    ,(r0)+        ; stuff return without wait in
  924.      br    20$            ; and do it
  925. 10$:    mov    (r5)    ,(r0)+        ; timeout
  926.     clr    (r0)+            ; unused
  927. 20$:    .READ
  928.     movb    FIRQB    ,r0        ; return error code and exit
  929.     clr    r1
  930.     bisb    (sp)+    ,r1
  931.     return
  932.  
  933.     .dsabl    lsb
  934.  
  935.  
  936. ;    Check for pending input on terminal (like ^X and ^Z)
  937. ;    Note: .TTDDT should be cleared by TTDVR always. It's
  938. ;    not, so for the time being lets forget about it  and
  939. ;    instead setup ^X and ^Z as delimiters.  I would have
  940. ;    preferred to use odt mode for this routine.
  941.  
  942.  
  943. chkabo::tst    jobtyp            ; /45/ Can't do from batch
  944.     bne    110$            ; /45/ Exit then
  945.     calls    xbinr1    ,<#-1,#lun.tt>    ; simple read on console terminal
  946.     tst    r0            ; did it work ok ?
  947.     bne    100$            ; no
  948.     mov    r1    ,r0        ; yes, return ch in r0 please
  949.     return
  950. 100$:    cmpb    r0    ,#11.        ; error EOFEOF?
  951.     bne    110$            ; no
  952.     movb    #'Z&37    ,r0        ; yes, return ^Z as the character
  953.     return
  954. 110$:    clr    r0            ; it failed
  955.     return
  956.  
  957.     .assume    JOB$INT eq 0
  958.     .assume    JOB$BAT eq 1
  959.  
  960.  
  961. read1c::CLRXRB                ; Insure XRB is zapped
  962.     .TTNCH                ; No echo
  963.     .TTDDT                ; One shot ODT mode
  964.     CLRXRB                ; Insure XRB zapped
  965.     clr    -(sp)            ; Allocate a buffer
  966.     mov    sp    ,r1        ; A pointer
  967.     mov    r1    ,XRB+XRLOC    ; Buffer address
  968.     inc    XRB+XRLEN        ; One character size buffer
  969.     .READ                ; Simple
  970.     clr    r0            ; Return the character next
  971.     tstb    FIRQB            ; Errors?
  972.     bne    100$            ; Yes, return a NULL
  973.     tst    XRB+XRBC        ; No data?????
  974.     beq    100$            ; Should never happen.
  975.     bisb    @r1    ,r0        ; No, return the data then.
  976. 100$:    tst    (sp)+            ; Pop the buffer and exit
  977.     return                ; Bye
  978.  
  979. writ1ch::
  980.     SAVE    <r2,r1,r0>        ; /E64/ Save registers
  981.     mov    sp    ,r2        ; /E64/ point to character
  982.     mov    #1    ,r0        ; /E64/ buffer length
  983.     call    dowrite            ; /E64/ do it
  984.     UNSAVE    <r0,r1,r2>        ; /E64/ Pop registers
  985.     return                ; And exit
  986.  
  987. Wrtcnt::SAVE    <r0,r1,r2>        ; /E64/ Save registers
  988.     mov    2+6(sp)    ,r2        ; /E64/ String address
  989.     mov    4+6(sp)    ,r0        ; /E64/ get string length
  990.     call    dowrite            ; /E64/
  991.     UNSAVE    <r2,r1,r0>        ; /E64/ Pop registers
  992.     mov    (sp)+    ,(sp)        ; /E64/ Move return address up
  993.     mov    (sp)+    ,(sp)        ; /E64/ Move return address up
  994.     return                ; /E64/ And exit
  995.  
  996. Wrtall::SAVE    <r0,r1,r2>        ; Save registers
  997.     mov    2+6(sp)    ,r2        ; String address
  998.     STRLEN    r2            ; Get the length
  999.     call    dowrite            ; /E64/
  1000.     UNSAVE    <r2,r1,r0>        ; Pop registers
  1001.     mov    (sp)+    ,(sp)        ; Move return address up
  1002.     return                ; And exit
  1003.  
  1004. ; /E64/
  1005. ;
  1006. ;    In dowrite, R0 is length of buffer
  1007. ;        R2 is address of buffer
  1008. ;
  1009. dowrite:mov    #xrb    ,r1        ; address of xrb parameter block
  1010.     mov    r0    ,(r1)+        ; buffer length
  1011.     mov    r0    ,(r1)+        ; byte count for the i/o
  1012.     mov    r2    ,(r1)+        ; address of the buffer
  1013.     mov    #lun.tt*2,(r1)+        ; /E64/ always use non-zero chan to
  1014.                     ; /E64/ avoid tromping on binary mode
  1015.     clr    (r1)+            ; unused
  1016.     clr    (r1)+            ; unused
  1017.     mov    #4096.    ,(r1)+        ; /E64/ modifier (ie, binary output)
  1018.     .WRITE                ; Do the WRITE
  1019.     cmpb    FIRQB    ,#11        ; /E64/ i/o channel not open ?
  1020.     bne    10$            ; /E64/ no, exit please
  1021.                     ; /E64/ try again on channel 0
  1022.     mov    #xrb    ,r1        ; /E64/ address of xrb parameter block
  1023.     mov    r0    ,(r1)+        ; /E64/ buffer length
  1024.     mov    r0    ,(r1)+        ; /E64/ byte count for the i/o
  1025.     mov    r2    ,(r1)+        ; /E64/ address of the buffer
  1026.     clr    (r1)+            ; /E64/ channel 0
  1027.     clr    (r1)+            ; /E64/ unused
  1028.     clr    (r1)+            ; /E64/ unused
  1029.     mov    #40000    ,(r1)+        ; /E64/ xrmod (transparent controls)
  1030.     .WRITE                ; /E64/
  1031. 10$:    return                ; And exit
  1032.  
  1033.     .globl    l$len
  1034.  
  1035.  
  1036.     .sbttl    write everything to the communications line
  1037.  
  1038. ;    P A K W R I
  1039. ;
  1040. ;    input:    @r5    buffer address
  1041. ;        2(r5)    buffer size
  1042. ;    output:    r0    error code
  1043. ;
  1044. ;     Pakwrite(buffer,size) attempts  to  write out the specified
  1045. ;    number of bytes in pass all  mode  to  the  line.  Additionally,
  1046. ;    NOSTALL  is  specified  the first time to allow us to detect the
  1047. ;    line being XOFF'ed. The side effect is  that  we  may  also  get
  1048. ;    returned  on  a  lack  of  small  buffers,  so  thus  we must be
  1049. ;    prepared to try again if that was the case. If we  are  XOFF'ed,
  1050. ;    which  is indicated by the 'bytes not sent' value being equal to
  1051. ;    the requested write size, then we force  an  XON  to  the  line.
  1052. ;    We also can get an XOFF via line noise in the middle of a packet
  1053. ;    thus we should also force an XOFF even for a partial write.
  1054. ;     This  is messy, addtionally, it ALWAYS requires SYSIO priv even
  1055. ;    if you own the line. The code to do this always has  to  inquire
  1056. ;    about  the  unit number, which is currently only possible via an
  1057. ;    UU.FCB call. This is undesirable in the unlikely event that  the
  1058. ;    first  few  words of the terminal DDB get changed by DIGITAL. We
  1059. ;    could, of course, save the  unit  number  in  TTYINI  in  a  LUN
  1060. ;    indexed table, but that's conceptually unattractive.  Even if it
  1061. ;    does change,  the UU.FCB code is rarely called and not very dan-
  1062. ;    gerous if things change.
  1063. ;    
  1064. ;     Ideally, we  need  a  .SPEC call to return XOFF'ed status and a
  1065. ;    .SPEC call to clear XOFF'ed status. The method used in  the  RSX
  1066. ;    based  Kermit-11  uses  a QIOW$S with a marktime in front of it,
  1067. ;    this if the mark time goes off we can  issue  an  IO.KIL,  clear
  1068. ;    the  xoffed  state  with  SF.SMC+IO.CTS,  and  redo  the QIOW$S.
  1069. ;    Again, the usefulness of MARK TIME and the equiv of IO.KIL comes
  1070. ;    to mind for RSTS/E, as noted before in the case of having a CTRL
  1071. ;    C ast routine being able to kill io requests on lines other than
  1072. ;    one's console terminal, which a control C always does.
  1073. ;     Hopefully, a future  release of  RSTS/E  will  make  these task
  1074. ;    simpler.  At  such  time,  we would have to consider the case of
  1075. ;    older version of RSTS/E; I would simply  cut  the  current  code
  1076. ;    out  and let those user's not upgrading suffer; reverting to the
  1077. ;    old code in BINWRI (next page). 
  1078. ;     Lately,  I seem to be turning my comments into essays about the
  1079. ;    deficiences a given exec may have.  RSTS developers, take heart,
  1080. ;    using the RSTS/E terminal  driver is a LOT more predictable than 
  1081. ;    than what you find on the various flavors of RSX.  I simply have
  1082. ;    spent a lot of time in the last couple of years with RT11,  RSX, 
  1083. ;    P/OS, TSX+ and VMS; they all have strong points and weaknesses.
  1084. ;    What one likes in one is rarely found in the other.
  1085.  
  1086.  
  1087.     .sbttl    Now for the real packet writer (enough of the soapbox)
  1088.  
  1089. pakwri::save    <r1,r2,r3>        ; /45/ Save this please
  1090.     mov    @r5    ,r2        ; /45/ Address of the write
  1091.     mov    2(r5)    ,r3        ; /45/ Size of the write
  1092.     mov    #8192.!4096.,r1        ; /45/ First time modifier
  1093. 10$:    mov    #XRB    ,r0        ; /45/ Address of xrb parameter block
  1094.     mov    r3    ,(r0)+        ; /45/ Buffer length
  1095.     mov    r3    ,(r0)+        ; /45/ Byte count for the i/o
  1096.     mov    r2    ,(r0)+        ; /45/ Address of the buffer
  1097.     movb    #lun.ti*2,(r0)+        ; /E64/ hardwire channel #*2
  1098.     clrb    (r0)+            ; /45/ Unused
  1099.     clr    (r0)+            ; /45/ Unused
  1100.     clr    (r0)+            ; /45/ Unused
  1101.     mov    r1    ,(r0)+        ; /45/ Modifier (ie, io.wal+nostall)
  1102.     .WRITE                ; /45/ Really dump the data
  1103.     movb    FIRQB    ,r0        ; /45/ return error code and exit
  1104.     bne    100$            ; /45/ Error, exit NOW
  1105.     tst    XRB+XRBC        ; /45/ Did EVERTHING get dumped ?
  1106.     beq    100$            ; /45/ Yes, exit with SUCCESS
  1107.  
  1108.     bic    #8192.    ,r1        ; /45/ No more 'NO STALL' modes
  1109.     mov    r3    ,r0        ; /45/ Get the old write size
  1110.     sub    XRB+XRBC,r0        ; /45/ And compute a new buffer addr
  1111.     add    r0    ,r2        ; /45/ buffer = buffer + (size-left)
  1112.     mov    XRB+XRBC,r3        ; /45/ New write size
  1113.                     ; /45/ Now try to XON the line
  1114.     clrfqb                ; /45/ Try a UU.FCB to get the unit
  1115.     movb    #UU.FCB    ,FIRQB+FQFUN    ; /45/ number. While it's acknowledged
  1116.     movb    #lun.ti    ,FIRQB+FQFIL    ; /45/ that data strutures may change,
  1117.     .UUO                ; /45/ its unlikely that terminal DDB's
  1118.     movb    FIRQB    ,r0        ; /45/ will change in the first few
  1119.     bne    100$            ; /45/ words.
  1120.     mov    #XRB    ,r0        ; /45/ Point to the XRB now
  1121.     mov    #5    ,(r0)+        ; /45/ Xoffed, try to clear the line
  1122.     mov    #1    ,(r0)+        ; /45/ One byte, an XON, to force.
  1123.     mov    #$xon    ,(r0)+        ; /45/ XRLOC, address of the buffer.
  1124.     mov    #TTYHND*400,(r0)+    ; /45/ Low byte unused, high=driveridx
  1125.     movb    FIRQB+7    ,(r0)+        ; /45/ Unit number to force to
  1126.     clrb    (r0)+            ; /45/ Unused
  1127.     clr    (r0)+            ; /45/ Unused
  1128.     clr    (r0)+            ; /45/ Unused
  1129.     .SPEC                ; /45/ At last !
  1130.     mov    #4    ,XRB+0        ; /45/ Take a short nap and then retry
  1131.     .SLEEP                ; /45/ Wait a moment.
  1132.     br    10$            ; /45/ Go back, stalled write this time
  1133.  
  1134. 100$:    unsave    <r3,r2,r1>
  1135.     return
  1136.  
  1137.  
  1138.  
  1139.  
  1140.  
  1141. ;    B I N W R I
  1142. ;
  1143. ;    input:    @r5    buffer address
  1144. ;        2(r5)    buffer size
  1145. ;    output:    r0    error code
  1146.  
  1147.  
  1148. binwri::mov    #xrb    ,r0        ; address of xrb parameter block
  1149.     mov    2(r5)    ,(r0)+        ; buffer length
  1150.     mov    2(r5)    ,(r0)+        ; byte count for the i/o
  1151.     mov    @r5    ,(r0)+        ; address of the buffer
  1152.     movb    #lun.ti*2,(r0)+        ; channel number
  1153.     clrb    (r0)+            ; unused
  1154.     clr    (r0)+            ; unused
  1155.     clr    (r0)+            ; unused
  1156.     mov    #4096.    ,(r0)+        ; modifier (ie, io.wal+nostall)
  1157.     .WRITE
  1158.     movb    FIRQB    ,r0        ; return error code and exit
  1159.     return
  1160.  
  1161.  
  1162.  
  1163.  
  1164.     .sbttl    do a filename string scan
  1165.  
  1166. ;    L $ F S S
  1167. ;
  1168. ;    input:    @r5    .asciz string of the device or filename
  1169. ;    output:    FIRQB    the usual
  1170. ;        r0    error code if any
  1171.  
  1172.  
  1173. l$fss::    clrfqb
  1174. l$fssx::mov    @r5    ,r0        ; get the filename address
  1175. 10$:    tstb    (r0)+            ; and now get the length
  1176.     bne    10$            ; no null, keep going
  1177.     sub    @r5    ,r0        ; now get the length
  1178.     dec    r0            ; which is off by one of course
  1179.     mov    r0    ,xrb+xrlen    ; length of the string
  1180.     mov    r0    ,xrb+xrbc    ; once again
  1181.     mov    #xrb+xrloc,r0        ; finish clearing out
  1182.     mov    @r5    ,(r0)+        ; starting address of string
  1183.     clr    (r0)+            ; unused
  1184.     clr    (r0)+            ; unused
  1185.     clr    (r0)+            ; unused
  1186.     clr    (r0)+            ; unused
  1187.     .FSS                ; now do it please
  1188.     movb    FIRQB    ,r0        ; return error
  1189.     return
  1190.  
  1191.     .assume    <xrb+xrlen+2> eq <xrb+xrbc>
  1192.     .assume    <xrb+xrbc+2>  eq <xrb+xrloc>
  1193.  
  1194.  
  1195.     .sbttl    normal i/o to the terminal
  1196.  
  1197. l$nolf::
  1198.     tst    vttype            ; unless it's a hard copy term
  1199.     beq    l$pcrl            ; it is
  1200.     wrtall    #crnolf            ; it isn't, just a CR, no line feed..
  1201.     return
  1202.  
  1203. l$pcrl::wrtall    #crlf
  1204.     return
  1205.  
  1206.  
  1207.     .sbttl    other junk
  1208.  
  1209. $clrxr::save    <r0>
  1210.     mov    #xrb    ,r0
  1211. 10$:    clr    (r0)+
  1212.     cmp    r0    ,#xrb+14
  1213.     blos    10$
  1214.     unsave    <r0>
  1215.     return
  1216.  
  1217.  
  1218.  
  1219. $clrfq::save    <r0>
  1220.     mov    #FIRQB    ,r0
  1221. 10$:    clr    (r0)+
  1222.     cmp    r0    ,#FIRQB+36
  1223.     blos    10$
  1224.     unsave    <r0>
  1225.     return
  1226.  
  1227.  
  1228.  
  1229.     .sbttl    Reset the keypad    ; /BBS/ added
  1230.  
  1231. kp.clr::wrtall    #kp.res            ; dump reset string to terminal
  1232.     return
  1233.  
  1234.     .sbttl    exit kermit and logout
  1235.  
  1236.  
  1237. exit::    .newline
  1238.     clrxrb                ; /55/ ensure xrb is clear first
  1239.     .TTECH                ; /55/
  1240.     clrxrb                ; ensure xrb is clear first
  1241.     clrfqb                ; this must be cleared out
  1242.     .RTS                ; try to go to users KBM
  1243.     .EXIT                ; failed, go to the system's DEFKBM
  1244.  
  1245. ;    Logout moved to KRT80S /54/ 23-Aug-86  12:21:41
  1246.  
  1247.  
  1248.  
  1249.  
  1250.     .sbttl    cantyp    cancel typeahead
  1251.  
  1252.  
  1253. ;    C A N T Y P
  1254. ;
  1255. ;    cantyp( )
  1256. ;
  1257. ;
  1258. ;     Cantyp tries to dump all pending input on a given terminal
  1259. ;    line  by using  the normal  .spec call.
  1260.  
  1261.  
  1262. hose::
  1263. cantyp::save    <r1,r2>            ; use r0 to point into xrb
  1264.     mov    #xrb    ,r1        ; ok
  1265.     mov    #7    ,(r1)+        ; functioncode := cancel_typeahead
  1266.     clr    (r1)+            ; the kb number to use
  1267.     clr    (r1)+            ; not used
  1268.     mov    #lun.ti,r0        ; channel number
  1269.     asl    r0
  1270.     movb    r0,(r1)+        ; channel number
  1271.     movb    #TTYHND,(r1)+        ; driver index for terminals
  1272.     clr    (r1)+            ; not used
  1273.     clr    (r1)+            ; not used
  1274.     clr    (r1)+            ; not used
  1275.     .spec                ; do a driver special function now
  1276.     clr    lsize(r0)
  1277.     movb    FIRQB    ,r0        ; return any errors please
  1278. 100$:    unsave    <r2,r1>            ; all done
  1279.     return                ; bye
  1280.  
  1281. clrcns::CLRXRB                ; Insure XRB is cleared
  1282.     mov    #7    ,XRB+XRLEN    ; Cancel typeahead call
  1283.     movb    #TTYHND    ,XRB+XRBLKM    ; Driver index
  1284.     .SPEC                ; Should be it
  1285.     return                ; Exit
  1286.  
  1287.  
  1288.  
  1289.     .sbttl    get uic
  1290.  
  1291.  
  1292. ;    G E T U I C
  1293. ;
  1294. ;    input:    nothing
  1295. ;    output:    r0    current UIC/PPN of the user
  1296.  
  1297.  
  1298.  
  1299. getuic::mov    #xrb    ,r0        ; clear xrb out first
  1300. 10$:    clrb    (r0)+            ; simple
  1301.     cmp    r0    ,#xrb+15
  1302.     blos    10$
  1303.     .stat
  1304.     mov    xrb+10    ,r0        ; return uic (ppn) in r0
  1305.     return
  1306.  
  1307.  
  1308.  
  1309. drpprv::mov    #jfsys    ,xrb+0        ; drop temp privs
  1310.     .clear                ; simple
  1311.     return
  1312.  
  1313.  
  1314. getprv::mov    #jfsys    ,xrb+0        ; get temp privs back please
  1315.     .SET
  1316.     return
  1317.  
  1318.  
  1319.  
  1320.     .sbttl    suspend the job for a while
  1321.  
  1322. ;    S U S P E N
  1323. ;
  1324. ;    suspend(%val sleep_time)
  1325. ;
  1326. ;    input:    @r5    time to go away for
  1327.  
  1328.  
  1329. suspen::mov    @r5    ,xrb+0
  1330.     bne    10$
  1331.     inc    xrb+0
  1332. 10$:    .sleep
  1333.     return
  1334.  
  1335.  
  1336.     .sbttl    error text
  1337.  
  1338.  
  1339. syserp::save    <r0>
  1340.     mov    @r5    ,r0
  1341.     call    rmserp
  1342.     .newline
  1343.     unsave    <r0>
  1344.     return
  1345.  
  1346.  
  1347.  
  1348. syserr::save    <r1>            ; save a register
  1349.     clr    -(sp)            ; allocate variable for error #
  1350.     mov    sp    ,r1        ; and point to it
  1351.     mov    @r5    ,@r1        ; if errornumber > 0
  1352.     bmi    10$            ;  then
  1353.     calls    fiperr    ,<#2,r1,2(r5)>    ;   call fiperr(num,text)
  1354.     br    100$            ;  else
  1355. 10$:    calls    rmserr    ,<#2,r1,2(r5)>    ;   call rmserr(num,text)
  1356. 100$:    tst    (sp)+
  1357.     unsave    <r1>
  1358.     return
  1359.  
  1360.     .globl    fiperr    ,rmserp    ,rmserr
  1361.  
  1362.  
  1363.  
  1364.  
  1365.     .sbttl    ttypar    set parity stuff for kermit
  1366.  
  1367.  
  1368. ;    T T Y P A R
  1369. ;
  1370. ;    ttypar( %loc terminal name, %val paritycode )
  1371. ;
  1372. ;    input:    @r5    address of terminal name
  1373. ;        2(r5)    parity code
  1374. ;    output:    r0    error code
  1375.  
  1376.     .if ne    ,0            ; we don't need this anymore
  1377.     .ift
  1378.  
  1379. ttypar::call    ttpars            ; get the terminal unit number
  1380.     bcs    100$            ; oops
  1381.     clrfqb                ; clear FIRQB out for defaults
  1382.     inc    FIRQB+20        ; assume no parity
  1383.     cmpb    2(r5)    ,#par$no    ; really no parity ?
  1384.     beq    10$            ; yes
  1385.     inc    FIRQB+20        ; try next for even parity
  1386.     cmpb    2(r5)    ,#par$ev    ; well ?
  1387.     beq    10$            ; yes
  1388.     inc    FIRQB+20        ; not NONE or EVEN --> ODD
  1389.     cmpb    2(r5)    ,#par$od    ; must be
  1390.     beq    10$            ; yes
  1391.     movb    #18.    ,FIRQB        ; no, return illegal sys usage
  1392.     br    100$
  1393. 10$:    movb    r0    ,FIRQB+5    ; stuff the terminal unit number
  1394.     movb    #UU.TRM    ,FIRQB+FQFUN    ; terminal call today
  1395.     .UUO                ; simple
  1396. 100$:    movb    FIRQB    ,r0        ; get any errors
  1397.     return
  1398.  
  1399.     .endc                ; don't need hardware parity control
  1400.  
  1401. chkpar::clr    r0
  1402.     return
  1403.  
  1404.  
  1405.  
  1406.  
  1407.     .sbttl    hangup a terminal, set dtr on a terminal
  1408.  
  1409.  
  1410. ;    T T Y H A N
  1411. ;
  1412. ;    ttyhan( )
  1413. ;
  1414. ;    output:    r0    error code
  1415.  
  1416.  
  1417. ttyhan::calls    ttpars    ,<#ttname>    ; the usual, parse the device name
  1418.     bcs    100$            ; oops
  1419.     clrfqb                ; clear the FIRQB please
  1420.     movb    #UU.HNG    ,FIRQB+FQFUN    ; terminal call today
  1421.     movb    r0    ,FIRQB+4    ; unit number
  1422.     movb    #1    ,FIRQB+5    ; do it asap
  1423.     .UUO                ; simple
  1424. 100$:    movb    FIRQB    ,r0        ; return error code and exit
  1425.     return                ; bye
  1426.  
  1427.  
  1428.  
  1429. ;    raise DTR on a terminal line
  1430. ;
  1431. ;    T T Y D T R
  1432. ;
  1433. ;    ttydtr( )
  1434. ;
  1435. ;    output:    r0    error code
  1436.  
  1437.  
  1438. ttydtr::calls    ttpars    ,<#ttname>    ; the usual, parse the device name
  1439.     bcs    100$            ; oops
  1440.     clrfqb                ; clear the FIRQB please
  1441.     movb    #UU.HNG    ,FIRQB+FQFUN    ; terminal call today
  1442.     movb    r0    ,FIRQB+4    ; unit number
  1443.     movb    #377    ,FIRQB+5    ; set dtr function
  1444.     .UUO                ; simple
  1445. 100$:    movb    FIRQB    ,r0        ; return error code and exit
  1446.     return                ; bye
  1447.  
  1448.  
  1449.  
  1450.  
  1451.  
  1452.  
  1453.     .sbttl    inquire if DTR is up on a device
  1454.  
  1455. ;    INQDTR(ttname)
  1456. ;
  1457. ;    Find out if DTR is up.
  1458. ;
  1459. ;     On RSTS/E, DTR is up if (1) Carrier detect is up or (2) Ring is up
  1460. ;    Thus,  to connect to a dialout modem,  some means  must be provided
  1461. ;    for the terminal driver to 'See' CD. This can be done from internal
  1462. ;    modem options, or one can cut CD and loop DTR to CD on the cpu side
  1463. ;    and use the Kermit-11 command SET DTR to get CD up. This routine is
  1464. ;    to return the current DTR status.  For RSX, it would be more useful
  1465. ;    to return TRUE if TC.DLU==2 or TRUE if CD is up.
  1466. ;
  1467. ;    Returns:    1    DTR is present
  1468. ;            0    DTR is NOT present
  1469. ;            -1    Line is not modem controlled
  1470. ;
  1471. ;    18-Dec-85  09:16:08 BDN
  1472.  
  1473.     .iif ndf, UU.CFG, UU.CFG = 42    ; So this builds on version 8 systems
  1474.  
  1475.     .enabl    lsb
  1476. inqdtr::tst    ver9.x            ; /40/ only works on 9.0 or later
  1477.     beq    90$            ; /40/ if so, return(-1)
  1478.     call    ttpars            ; /40/ get device unit number
  1479.     tstb    FIRQB            ; /40/ Was parse successful?
  1480.     bne    90$            ; /40/ No, return(-1)
  1481.     clrfqb                ; /40/ clear firqb out please
  1482.     movb    #UU.CFG    ,FIRQB+FQFUN    ; /40/ Find out if line has Modem ctl
  1483.     mov    #"KB    ,FIRQB+FQDEV    ; /40/ Always a KB: device please
  1484.     movb    r0    ,FIRQB+FQDEVN    ; /40/ Unit number please
  1485.     movb    #377    ,FIRQB+FQDEVN+1    ; /40/ Unit number is 'real'
  1486.     .UUO                ; /40/ do it
  1487.     tstb    FIRQB            ; /40/ If failure, return(nomodem)
  1488.     bne    90$            ; /40/ Failed
  1489.     bitb    #4    ,FIRQB+7    ; /40/ If set, the line is modem ctl
  1490.     beq    90$            ; /40/ No modem control, return(-1)
  1491.     clrfqb                ; /40/ We have modem control, what
  1492.     movb    #UU.TRM    ,FIRQB+FQFUN    ; /40/ about DTR being around ?
  1493.     movb    r0    ,FIRQB+5    ; /40/ Unit number here this time
  1494.     .UUO                ; /40/ get tt characteristics, part 1
  1495.     tstb    FIRQB            ; /40/ Can't fail
  1496.     bne    90$            ; /40/ But it did ?
  1497.     bitb    #200    ,FIRQB+4    ; /40/ At last, is DTR up ?
  1498.     bne    80$            ; /40/ No, return(0)
  1499.     mov    #1    ,r0        ; /40/ Yes, return(1)
  1500.     br    100$            ; /40/ Exit
  1501.  
  1502. 80$:    clr    r0            ; /40/ Modem line and no DTR
  1503.     br    100$            ; /40/ exit
  1504. inqcd::                    ; /E64/
  1505. 90$:    mov    #-1    ,r0        ; /40/ Not modem or pre 9.x system
  1506. 100$:    return
  1507.     .dsabl    lsb
  1508.  
  1509.  
  1510. dcdtst::                ; /E64/
  1511.     clr    r0            ; not available
  1512.     return
  1513.  
  1514. inqbuf::mov    #maxpak    ,r0        ; /42/ Assume pre RSTS v9
  1515.     tst    ver9.x            ; /42/ 9.X with huge buffer quotas?
  1516.     beq    100$            ; /42/ No
  1517.     mov    #MAXLNG    ,r0        ; /42/ Yes, return the MAX size
  1518. 100$:    return                ; /42/ exit
  1519.  
  1520.  
  1521. inqpar::clr    r0
  1522.     return
  1523.  
  1524.  
  1525.  
  1526.     .sbttl    ttspeed    get speed for line
  1527.  
  1528.  
  1529. ;    T T S P E E D
  1530. ;
  1531. ;    output:    r0    current speed
  1532. ;
  1533.  
  1534. ttspee::save    <r1>
  1535.     calls    ttpars    ,<#ttname>    ; parse the device name
  1536.     bcs    90$            ; exit
  1537.     clrfqb                ; insure no changes to tty settings
  1538.     movb    #UU.TRM    ,FIRQB+FQFUN    ; uuo code to do it
  1539.     movb    r0    ,FIRQB+5    ; unit number
  1540.     .UUO                ; get terminal characteristics
  1541.     tstb    FIRQB            ; did it work ?
  1542.     bne    90$            ; no
  1543.     movb    FIRQB+24,r1        ; interface type
  1544.     mov    splst(r1),r0        ; /40/ is the speed settable?
  1545.     tst    2(r0)            ; /40/ second entry is always <> 0
  1546.     beq    90$            ; /40/ not settable
  1547.     movb    FIRQB+17,r0        ; get the speed of it
  1548.     dec    r0
  1549.     asl    r0            ; times 2
  1550.     add    splst(r1),r0        ; and the actual speed now
  1551.     mov    @r0    ,r0        ; got it
  1552.     br    100$            ; exit
  1553. 90$:    clr    r0
  1554. 100$:    unsave    <r1>
  1555.     return
  1556.  
  1557.  
  1558.  
  1559.  
  1560.  
  1561.  
  1562.     .sbttl    set the speed of a terminal line
  1563.  
  1564.  
  1565.  
  1566. ;    S E T S P D
  1567. ;
  1568. ;    setspd(%val speed)
  1569. ;
  1570. ;    input:    @r5    speed
  1571. ;    output:    r0    error code, 255 if invalid speed
  1572.  
  1573. setspd::save    <r1,r2>
  1574.     calls    ttpars    ,<#ttname>    ; parse the terminal name
  1575.     bcs    90$            ; oops
  1576.     clrfqb
  1577.     movb    #UU.TRM    ,FIRQB+FQFUN    ; uuo code to do it
  1578.     movb    r0    ,FIRQB+5    ; unit number
  1579.     .UUO                ; get terminal characteristics
  1580.     tstb    FIRQB            ; did it work ?
  1581.     bne    90$            ; no
  1582.     movb    FIRQB+24,r1        ; interface type
  1583.     mov    splst(r1),r1        ; point to the speed table for it
  1584.     clr    r2            ; current index
  1585. 10$:    cmp    @r1    ,#-1        ; reached the end of the table
  1586.     beq    80$            ; yes, can't set the speed
  1587.     inc    r2            ; speednum := succ( speednum )
  1588.     cmp    (r5)    ,(r1)+        ; speed match ?
  1589.     bne    10$            ; no
  1590.     clrfqb                ; clear FIRQB out please
  1591.     movb    #UU.TRM    ,FIRQB+FQFUN    ; uuo function for terminals
  1592.     movb    r0    ,FIRQB+5    ; unit number
  1593.     movb    r2    ,FIRQB+17    ; rec speed
  1594.     movb    r2    ,FIRQB+21    ; xmit speed
  1595.     .UUO                ; do it
  1596.     tstb    FIRQB            ; error ?
  1597.     bne    90$            ; yes
  1598.     clr    r0            ; no
  1599.     br    100$            ; exit
  1600.  
  1601. 80$:    mov    #377    ,r0        ; unknown speed or not settable
  1602.     br    100$            ; exit
  1603.  
  1604. 90$:    movb    FIRQB    ,r0        ; uuo error, return it please
  1605. 100$:    unsave    <r2,r1>            ; bye
  1606.     return
  1607.  
  1608.  
  1609.  
  1610.  
  1611.     .sbttl    INITER    save and set the terminal characteristics
  1612.  
  1613. ;    ttysav( %loc ttname)
  1614. ;    ttyrst()
  1615. ;
  1616. ;    output:    r0    error code
  1617.  
  1618. ttysav::
  1619. ttyrst::
  1620. ttyset::clr    r0
  1621.     return
  1622.  
  1623.  
  1624.  
  1625. ;    INITER
  1626. ;
  1627. ;    Passed:    0(r5)    Address of terminal name
  1628. ;    Return:    r0    error code
  1629. ;
  1630. ;    INITER is called ONLY internally from TTYINI()
  1631.  
  1632.  
  1633. initer:    save    <r1,r2,r3>
  1634.     calls    ttpars    ,<#ttname>    ; set terminal up for KERMIT
  1635.     bcs    90$            ; oops, bad device name
  1636.     mov    #lun.ti    ,r1        ; /40/ get the channel number please
  1637.     tst    ver9.x            ; /40/ version 9.x or later?
  1638.     beq    4$            ; /40/ no
  1639.  
  1640.     clrb    bufqsav(r1)        ; /40/ assume nothing saved for quota
  1641.     clrfqb                ; /40/ insure no unpleasant effects
  1642.     movb    #UU.TRM    ,FIRQB+FQFUN    ; /40/ uuo code for terminals
  1643.     incb    FIRQB+4            ; /40/ UU.TRM part two
  1644.     movb    r0    ,FIRQB+5    ; /40/ unit number or 377
  1645.     .UUO                ; /40/ get the current settings
  1646.     tstb    FIRQB            ; /40/ did the set list work ?
  1647.     bne    4$            ; /40/ should have
  1648.     movb    FIRQB+27,bufqsav(r1)    ; /40/ save old buffer quotas
  1649.     clrfqb                ; /40/ insure no unpleasant effects
  1650.     movb    #UU.TRM    ,FIRQB+FQFUN    ; /40/ uuo code for terminals
  1651.     incb    FIRQB+4            ; /40/ subfunction one
  1652.     movb    r0    ,FIRQB+5    ; /40/ unit number or 377
  1653. ..BUFQ    == . + 2            ; /46/ Patchable
  1654.     movb    #40.    ,FIRQB+27    ; /40/ raise buffer quotas now
  1655.     .UUO                ; /40/ ignore errors
  1656.  
  1657. 4$:    clrfqb                ; insure no unpleasant effects
  1658.     movb    #UU.TRM    ,FIRQB+FQFUN    ; uuo code for terminals
  1659.     movb    r0    ,FIRQB+5    ; unit number or 377
  1660.     .UUO                ; get the current settings
  1661.     tstb    FIRQB            ; did the set list work ?
  1662.     bne    90$            ; no, die
  1663.     mov    #lun.ti    ,r1        ; get the channel number please
  1664.     mul    #40    ,r1        ; get address of ttsave area for it
  1665.     add    #ttsave    ,r1        ; at last
  1666.     mov    #FIRQB    ,r2        ; get address of current settings
  1667.     mov    #40    ,r3        ; number of bytes to copy now
  1668. 5$:    movb    (r2)+    ,(r1)+        ; copy a byte
  1669.     sob    r3    ,5$        ; next please
  1670.     clr    r1            ; get the parity/8bit setting
  1671.     bisb    FIRQB+20,r1        ; and check for parity being set
  1672.     bic    #^C3    ,r1        ; leave only parity bits here
  1673.     cmpb    r1    ,#1        ; parity set ?
  1674.     bhi    7$            ; /36/ yes, can't set 8bit mode then
  1675.     tstb    parity            ; /36/ If software parity enabled
  1676.     beq    6$            ; /36/ then we must prevent TTDVR
  1677.     cmpb    parity    ,#PAR$NO    ; /36/ from changing characters in
  1678.     bne    7$            ; /36/ range 201-237 into esc seqs.
  1679. 6$:    movb    #30    ,r1        ; no parity so please set 8bit mode
  1680.     br    10$            ; /36/
  1681. 7$:    bisb    #20    ,r1        ; /36/ explicitly turn 8bit mode off
  1682. 10$:    clrfqb                ; now actually set it
  1683.     movb    #UU.TRM    ,FIRQB+FQFUN    ; uuo code for terminals
  1684.     movb    r0    ,FIRQB+5    ; unit number or 377
  1685.     movb    #377    ,FIRQB+12    ; SET XON
  1686.     movb    #377    ,FIRQB+35    ; SET GAG
  1687.     movb    r1    ,FIRQB+20    ; SET 8BIT
  1688.     movb    #200    ,FIRQB+11    ; SET LC OUTPUT
  1689.     movb    #377    ,FIRQB+15    ; SET LC INPUT
  1690.     movb    #200    ,FIRQB+30    ; insure no delimiters are set now
  1691.     cmpb    handch    ,#'Q&37        ; This is a pain. We have to use
  1692.     beq    15$            ; multiple delims cause bin mode
  1693.     cmpb    handch    ,#'S&37        ; perhaps XON also ?
  1694.     bne    20$            ; no
  1695. 15$:    movb    #200    ,FIRQB+22    ; timeouts don't work and xon's
  1696.                     ; don't get thru unless stall is off
  1697. 20$:    
  1698.     .UUO                ; go get RSTS's attention
  1699. 90$:    movb    FIRQB    ,r0        ; return possible errors
  1700.     unsave    <r3,r2,r1>
  1701.     return
  1702.  
  1703.     .globl    handch ,parity ,ttname
  1704.  
  1705.     .sbttl    ttpars    get unit number from ttname
  1706.  
  1707. ;    T T P A R S
  1708. ;
  1709. ;    ttpars( %loc ttname )
  1710. ;
  1711. ;    output:    r0    unit number or 377 for null string
  1712.  
  1713. ttpars::save    <r1>
  1714.     call    myterm            ; get attached console name
  1715.     movb    r0    ,r1        ; get the name
  1716.     clrfqb                ; no defaults
  1717.     clrxrb
  1718.     mov    #377    ,-(sp)        ; assume KB:
  1719.     mov    @r5    ,r0        ; address of terminal name
  1720. 10$:    tstb    (r0)+            ; get the length of the name
  1721.     bne    10$            ; until we find a NULL
  1722.     sub    @r5    ,r0        ; get the length
  1723.     dec    r0            ; if zero, then use 377 for unit
  1724.     beq    20$            ; use zero
  1725.     mov    r0    ,xrb+xrlen    ; length of string for .FSS
  1726.     mov    r0    ,xrb+xrbc    ; again
  1727.     mov    @r5    ,xrb+xrloc    ; address of the string to parse
  1728.     .FSS                ; and do it
  1729.     tstb    FIRQB            ; did it work ?
  1730.     bne    90$            ; no
  1731.     bit    #20000!40000,xrb+10    ; a device name was parsed ?
  1732.     beq    80$            ; no
  1733.     movb    xrb+14,    r0        ; get the driver index please
  1734.     scan    r0    ,#hndlst    ; a reasonable device name?
  1735.     tst    r0            ; well ?
  1736.     beq    80$            ; no
  1737.     cmpb    FIRQB+FQDEVN,r1        ; same device as controlling terminal?
  1738.     beq    20$            ; yes
  1739.     movb    FIRQB+FQDEVN,@sp    ; yes, save unit number
  1740.     bne    20$
  1741.     movb    #377    ,@sp        ; no unit, return 377 for self
  1742. 20$:    clc                ; flag success
  1743.     br    100$            ; and exit
  1744.  
  1745. 80$:    movb    #6    ,FIRQB        ; invlaid device name error
  1746. 90$:    sec                ; flag failure
  1747. 100$:    mov    (sp)+    ,r0
  1748.     unsave    <r1>
  1749.     return
  1750.  
  1751.     .globl    scanch
  1752.  
  1753.  
  1754. myterm:    clrfqb
  1755.     movb    #UU.SYS    ,FIRQB+FQFUN    ; for a systat part one
  1756.     .UUO                ; simple
  1757.     movb    FIRQB+5    ,r0        ; get the name
  1758.     return
  1759.  
  1760.  
  1761.  
  1762.     .sbttl    assign device
  1763.     .enabl    lsb
  1764.  
  1765. ;    Assign the device for SET LINE. Device characteristics are
  1766. ;    set in TTYINI and reset in TTYFIN. For edit /41/, check to
  1767. ;    be sure that the JOB privilege mask includes HWCFG,  which
  1768. ;    is needed to alter settings on other terminal lines (9.x).
  1769.  
  1770.     .iif ndf , PRVIOL,    PRVIOL = 12
  1771.  
  1772. assdev::mov    r1    ,-(sp)        ; /41/
  1773.     call    ttpars            ; parse the terminal name
  1774.     bcs    100$            ; oops
  1775.     cmpb    r0    ,#377        ; Return KB: ?
  1776.     bne    10$            ; no
  1777.     clr    r0            ; Yes, simply return
  1778.     br    110$            ; exit
  1779. 10$:    mov    r0    ,r1        ; /41/ save unit number
  1780.     tst    ver9.x            ; /45/ What if this is version 8?
  1781.     beq    20$            ; /45/ If so, don't try this out.
  1782.     mov    #HWCFG    ,-(sp)        ; /41/ See if we have JOB privs
  1783.     call    jobprv            ; /41/ Well?
  1784.     tst    r0            ; /41/ 1 == success
  1785.     beq    90$            ; /41/ No
  1786. 20$:    clrfqb                ; A Real LINE today
  1787.     movb    #UU.ASS    ,FIRQB+FQFUN    ; Assign the device please
  1788.     mov    #FIRQB+FQDEV,r0        ; Where to place the device name
  1789.     movb    #'K    ,(r0)+        ; name
  1790.     movb    #'B    ,(r0)+        ; ..name continued (Always KBnn:)
  1791.     movb    r1    ,(r0)+        ; unit
  1792.     movb    #377    ,@r0        ; Unit is 'real'
  1793.     .UUO                ; get RSTS/E to do the assignment
  1794.     br    100$            ; exit with error in FIRQB+0
  1795. 90$:    wrtall    #e80.01            ; /E64/
  1796.     mov    #PRVIOL    ,FIRQB        ; /41/
  1797. 100$:    movb    FIRQB    ,r0        ; Return the error code please
  1798. 110$:    mov    (sp)+    ,r1        ; /41/ Restore register please
  1799.     return                ; exit
  1800.  
  1801.     .dsabl    lsb
  1802.  
  1803.  
  1804.     .sbttl    ascdat    get the ascii string for the date
  1805.  
  1806. ;    A S C D A T
  1807. ;
  1808. ;    input:    @r5    buffer address
  1809. ;        2(r5)    date in system internal format
  1810.  
  1811.  
  1812. ascdat::save    <r0,r1>
  1813.     clrfqb                ; clear the FIRQB out first
  1814.     mov    2(r5)    ,FIRQB+4    ; where to pass the date
  1815.     movb    #UU.CNV    ,FIRQB+FQFUN    ; simple
  1816. ;/*60*/    inc    FIRQB+6            ; KERMIT uses ISO date formats
  1817.     .UUO                ; get RSTS to convert the date
  1818.     clrb    FIRQB+22        ; insure .asciz
  1819.     mov    #FIRQB+10,r0        ; where RSTS put the date
  1820.     mov    @r5    ,r1        ; where we want to put it
  1821. 10$:    movb    (r0)+    ,(r1)+        ; simple
  1822.     bne    10$            ; copy until a null byte is found
  1823.     unsave    <r1,r0>            ; pop temps and exit
  1824.     return
  1825.  
  1826.  
  1827.  
  1828.  
  1829.  
  1830.  
  1831. ;    A S C T I M
  1832. ;
  1833. ;    input:    @r5    buffer address
  1834. ;        2(r5)    time in system internal format
  1835.  
  1836.  
  1837. asctim::save    <r0,r1>
  1838.     clrfqb                ; clear the FIRQB out first
  1839.     mov    2(r5)    ,FIRQB+22    ; where to pass the time
  1840.     movb    #UU.CNV    ,FIRQB+FQFUN    ; simple
  1841. ;/*60*/    inc    FIRQB+24        ; KERMIT uses ISO time formats
  1842.     .UUO                ; get RSTS to convert the time
  1843.     clrb    FIRQB+36        ; insure .asciz
  1844.     mov    #FIRQB+26,r0        ; where RSTS put the time
  1845.     mov    @r5    ,r1        ; where we want to put it
  1846. 10$:    movb    (r0)+    ,(r1)+        ; simple
  1847.     bne    10$            ; copy until a null byte is found
  1848.     unsave    <r1,r0>            ; pop temps and exit
  1849.     return
  1850.  
  1851.     .sbttl    cantim    Convert date and time to canonical form
  1852.  
  1853. ;    C A N T I M
  1854. ;
  1855. ;    input:    @r5    buffer address
  1856. ;        2(r5)    date in system internal format
  1857. ;        4(r5)    time in system internal format
  1858. ; /E64/    new
  1859.  
  1860.  
  1861. cantim::save    <r0,r1,r2>
  1862.     clrfqb                ; clear the FIRQB out first
  1863.     mov    2(r5)    ,FIRQB+4    ; where to pass the date
  1864.     mov    4(r5)    ,FIRQB+22    ; where to pass the time
  1865.     movb    #UU.CNV    ,FIRQB+FQFUN    ; simple
  1866.     inc    FIRQB+6            ; KERMIT uses ISO date formats
  1867.     inc    FIRQB+24        ; KERMIT uses ISO time formats
  1868.     .UUO                ; get RSTS to convert the date
  1869.     mov    #FIRQB+10,r0        ; where RSTS put the date
  1870.     mov    @r5    ,r1        ; where we want to put it
  1871.     cmp    #30000.    ,2(r5)        ; after year 2000?
  1872.     blos    10$            ;   yes
  1873.     movb    #'1    ,(r1)+        ;   no, 19xx
  1874.     movb    #'9    ,(r1)+
  1875.     br    20$
  1876. 10$:    movb    #'2    ,(r1)+        ; year 20xx
  1877.     movb    #'0    ,(r1)+
  1878. 20$:    movb    (r0)+    ,(r1)+        ; YY
  1879.     movb    (r0)+    ,(r1)+        ;
  1880.     inc    r0            ; skip .
  1881.     movb    (r0)+    ,(r1)+        ; MM
  1882.     movb    (r0)+    ,(r1)+        ;
  1883.     inc    r0            ; skip .
  1884.     movb    (r0)+    ,(r1)+        ; DD
  1885.     movb    (r0)+    ,(r1)+        ;
  1886.     movb    #40    ,(r1)+        ; a space delimiter
  1887.  
  1888.                     ; the time's in the right format!
  1889.     clrb    FIRQB+36        ; insure .asciz
  1890.     mov    #FIRQB+26,r0        ; where RSTS put the time
  1891.     mov    #5    ,r2        ; 5 bytes of time
  1892. 30$:    movb    (r0)+    ,(r1)+        ; simple
  1893.     sob    r2    ,30$        ; copy the time
  1894.     movb    #':    ,(r1)+        ; seconds always 0
  1895.     movb    #'0    ,(r1)+        ;
  1896.     movb    #'0    ,(r1)+        ;
  1897.     clrb    (r1)            ; and delimit as .asciz
  1898.     unsave    <r2,r1,r0>        ; pop temps and exit
  1899.     return
  1900.  
  1901.     .sbttl    dodir    get a reasonable directory printed
  1902.  
  1903.  
  1904. ;    D O D I R
  1905. ;
  1906. ;    input:    @r5    wildcarded filespec
  1907. ;    output:    r0    error code
  1908. ;
  1909. ;    DODIR prints a directory listing at the local terminal.
  1910. ;
  1911. ;
  1912. ;    S D O D I R
  1913. ;
  1914. ;    Passed:    @r5    wildcarded name
  1915. ;    Return:    r0    error code, zero for no errors
  1916. ;        r1    next character in the directory listing
  1917. ;
  1918. ;    SDODIR is called by the server to respond to a remote directory
  1919. ;    command.  Instead of the pre 2.38 method of dumping output to a
  1920. ;    disk file and then sending the disk file in an extended replay,
  1921. ;    SDODIR  returns the next  character so that  BUFFIL can use it.
  1922. ;    The routine  GETCR0  is actually a dispatch routine to call the
  1923. ;    currently selected GET_NEXT_CHARACTER routine.
  1924.  
  1925.  
  1926. dodir::    save    <r1,r2,r3,r4>
  1927.     strcpy    #dirnam    ,@r5
  1928.     call    dirini            ; init things
  1929.     bcs    100$            ; error in the .FSS parse
  1930. 10$:    call    dirnex            ; get the next file
  1931.     bcs    100$            ; all done
  1932.     wrtall    #dirbuf
  1933.     br    10$
  1934. 100$:    unsave    <r4,r3,r2,r1>
  1935.     clr    diridx
  1936.     return
  1937.  
  1938.     .globl    strcpy
  1939.  
  1940.  
  1941. sdirin::strcpy    #dirnam    ,@r5        ; copy name over
  1942.     clr    diridx            ; ditto
  1943.     call    dirini            ; init for calls to sdodir
  1944.     bcs    100$
  1945.     mov    #dirbuf    ,dirptr        ; yes, init pointers please
  1946.     clrb    @dirptr            ; yes, zap the buffer
  1947.     call    dirnex            ; preload buffer
  1948. 100$:    return
  1949.  
  1950. sdodir::save    <r2,r3,r4>
  1951. 10$:    movb    @dirptr    ,r1        ; get the next character please
  1952.     bne    20$            ; something was there
  1953.     mov    #dirbuf    ,dirptr        ; reset the pointer
  1954.     clrb    @dirptr            ; yes, zap the buffer
  1955.     call    dirnex            ; empty buffer, load with next file
  1956.     bcs    90$            ; no more, return ER$EOF
  1957.     br    10$            ; and try again
  1958. 20$:    inc    dirptr            ; pointer++
  1959.     clr    r0            ; no errors
  1960.     br    100$            ; exit
  1961. 90$:    mov    #ER$EOF    ,r0        ; failure, return(EOF)
  1962. 95$:    clr    r1            ; return no data also
  1963.     clr    diridx            ; init for next time through
  1964. 100$:    unsave    <r4,r3,r2>
  1965.     return
  1966.     
  1967.     .globl    er$eof
  1968.  
  1969.     .sbttl    init for the directory
  1970.  
  1971.  
  1972. dirini:    clr    diridx            ; /38/
  1973.     mov    #dirnam    ,r2        ; string address
  1974.     tstb    @r2            ; a null string ?
  1975.     bne    10$            ; no
  1976. 5$:    mov    #wild    ,r2        ; yes, supply *.*
  1977. 10$:    calls    l$fss    ,<#defdir>    ; stuff FIRQB with defaults
  1978.     calls    l$fssx    ,<r2>        ; parse the string with defaults
  1979.     tst    r0            ; did it work ?
  1980.     bne    90$            ; no
  1981.     bit    #1    ,xrb+10        ; was some kind of filename passed?
  1982.     bne    20$            ; yes
  1983.     mov    #134745    ,FIRQB+FQNAM1+0    ; no, insert *
  1984.     mov    #134745    ,FIRQB+FQNAM1+2    ; no, insert *
  1985.  
  1986. 20$:    bit    #20    ,xrb+10        ; was a non-null extension passed ?
  1987.     bne    40$            ; yes
  1988.     bit    #10    ,xrb+10        ; no extension, was the extension an
  1989.     bne    40$            ; explicit null (ie, abcdef.) ?
  1990.     mov    #134745    ,FIRQB+FQNAM1+4    ; no, stuff .* into the filespec
  1991.  
  1992. 40$:    mov    #dirfir    ,r4        ; save the FIRQB save area pointer
  1993.     mov    #FIRQB    ,r3        ; and a pointer to the FIRQB itself
  1994.     mov    #40    ,r0        ; number of bytes to copy
  1995. 50$:    movb    (r3)+    ,(r4)+        ; simple
  1996.     sob    r0    ,50$        ; all done saving the FIRQB
  1997.     clc                ; success
  1998.     br    100$            ; bye
  1999.  
  2000. 90$:    sec                ; failure
  2001. 100$:    return                ; bye
  2002.  
  2003.     .globl    defdir
  2004.  
  2005.     .sbttl    more routines for dodir
  2006.  
  2007. .globl    rdtoa
  2008.  
  2009. dircvt:    save    <r0,r1,r2>
  2010.     mov    r3    ,-(sp)        ; save the pointer please
  2011.     mov    #FIRQB+FQNAM1,r2    ; first three characters of filename
  2012.     calls    rdtoa    ,<r3,(r2)+>    ; convert it
  2013.     add    #3    ,r3        ; and fix the pointer up
  2014.     calls    rdtoa    ,<r3,(r2)+>    ; convert it
  2015.     add    #3    ,r3        ; and fix the pointer up
  2016.     movb    #'.    ,(r3)+        ; stuff a dot in please
  2017.     calls    rdtoa    ,<r3,(r2)+>    ; convert it
  2018.     add    #3    ,r3        ; bump the pointer along please
  2019.     movb    #40    ,(r3)+        ; some spaces
  2020.     movb    #40    ,(r3)+        ; some spaces
  2021.     mov    FIRQB+16,r0        ; the file size
  2022.     deccvt    r0,r3,#6        ; convert it to ascii
  2023.     add    #6    ,r3        ; point past the number now
  2024.     movb    #40    ,(r3)+        ; some spaces
  2025.     movb    #40    ,(r3)+        ; some spaces
  2026.     movb    #'<    ,(r3)+        ;/*60*/ give 'em prot. code, too
  2027.     mov    FIRQB+20,r0        ;/*60*/
  2028.     bic    #177400    ,r0        ;/*60*/
  2029.     deccvt    r0,r3,#3        ;/*60*/
  2030.     add    #3    ,r3        ;/*60*/
  2031.     movb    #'>    ,(r3)+        ;/*60*/
  2032.     movb    #40    ,(r3)+        ;/*60*/
  2033.     movb    #40    ,(r3)+        ;/*60*/
  2034.     mov    FIRQB+26,r2        ; save the time of creation
  2035.     calls    ascdat    ,<r3,FIRQB+24>    ; convert the date
  2036.     mov    (sp)    ,r3
  2037.     strlen    r3            ; get the current length
  2038.     add    r0    ,r3        ; and point to the new end of it
  2039.     movb    #40    ,(r3)+        ;/*60*/
  2040.     movb    #40    ,(r3)+        ;/*60*/
  2041.     calls    asctim    ,<r3,r2>    ; and get the time
  2042.     strcat    r3    ,#dcrlf        ; append crlf
  2043.     mov    (sp)+    ,r3        ; point back to the string
  2044.     unsave    <r2,r1,r0>
  2045.     return
  2046.     
  2047.     .globl    l$cvtnum, strcat
  2048.  
  2049.  
  2050. dirnex:    mov    #dirfir    ,r4        ;
  2051.     mov    #FIRQB    ,r3        ; and a pointer to the FIRQB itself
  2052.     mov    #40    ,r0        ; number of bytes to copy
  2053. 20$:    movb    (r4)+    ,(r3)+        ; simple
  2054.     sob    r0    ,20$        ; all done loading the FIRQB
  2055.     mov    diridx    ,FIRQB+4    ; store the index for the file
  2056.     movb    #lokfq    ,FIRQB+3    ; directory lookup please
  2057.     CALFIP                ; get fip to do it please
  2058.     movb    FIRQB    ,r0        ; did it work ?
  2059.     bne    90$            ; no
  2060.     mov    #dirbuf    ,r3        ; point to the string buffer
  2061.     call    dircvt            ; yes, convert it please
  2062.     inc    diridx            ; setup for the next time
  2063.     clc                ; success
  2064.     return                ; failure
  2065.  
  2066. 90$:    tst    diridx            ; error, did we already find a file?
  2067.     beq    100$            ; no, retain error code
  2068.     clr    r0            ; yes, return zero and C set
  2069. 100$:    clr    diridx            ; clear for next time around
  2070.     sec
  2071.     return
  2072.  
  2073.     .sbttl    force a xon to the connect line
  2074.  
  2075. ;    T T X O N
  2076. ;
  2077. ;    output:    r0    error code
  2078.  
  2079.  
  2080. ttxon::    save    <r1>            ; save a temp register
  2081.     calls    ttpars    ,<#ttname>    ; parse the terminal device name
  2082.     bcs    90$            ; oops
  2083. 10$:    clrxrb                ; insure no defaults
  2084.     mov    #xrb    ,r1        ; point to the xrb now
  2085.     mov    #5    ,(r1)+        ; force to kb: function for .SPEC
  2086.     inc    (r1)+            ; one byte to force please
  2087.     mov    #$xon    ,(r1)+        ; address of the buffer for output
  2088.     mov    #ttyhnd*400,(r1)+    ; channel zero, device driver index
  2089.     mov    r0    ,(r1)+        ; terminal number
  2090.     .spec                ; simple
  2091.  
  2092. 90$:    movb    FIRQB    ,r0        ; error, return it please
  2093. 100$:    unsave    <r1>            ; pop the register we saved
  2094.     return
  2095.  
  2096.  
  2097.  
  2098.     .sbttl    printer spooling for RSTS
  2099.  
  2100.  
  2101.     .iif ndf, UU.SPL, UU.SPL = -28.
  2102.  
  2103.  
  2104. ;    Q S P O O L
  2105. ;
  2106. ;    calls QSPOOL    ,<address(filename)>
  2107. ;
  2108. ;    returns:    r0 := rsts error code (if any)
  2109.  
  2110. qspool::save    <r1>
  2111.     call    l$fss            ; do the .FSS now
  2112.     tst    r0            ; fail ?
  2113.     bne    100$            ; yes, exit
  2114.     mov    #FIRQB+16,r1        ; stuff the rest of the params
  2115.     mov    #"LP    ,(r1)+        ; LP of course
  2116.     movb    sp.dev    ,(r1)+        ; assume LP0 for a moment
  2117.     movb    #377    ,(r1)+        ; unit is real for sure
  2118.     clr    (r1)+            ; must be zero
  2119.     mov    sp.mod    ,(r1)+        ; /nodelete/header
  2120.     movb    #UU.SPL    ,FIRQB+FQFUN    ; uuo function code to do
  2121.     .UUO                ; simple to do
  2122.     movb    FIRQB    ,r0        ; return any error codes
  2123. 100$:    unsave    <r1>            ; pop temps and exit
  2124.     return
  2125.  
  2126.  
  2127.  
  2128.  
  2129.     .sbttl    inqterm    get terminal type (v9.x only)
  2130.  
  2131. ;    Assume:    Login.com did a $ SET TER/INQ
  2132.  
  2133. inqter:    call    inqv9            ; /39/ RSTS/E 9.x ?
  2134.     bcs    90$            ; /39/ no
  2135.     clrfqb                ; /39/ clear out again
  2136.     movb    #UU.TRM    ,FIRQB+FQFUN    ; /39/ terminal char function
  2137.     mov    #1+<400*377>,FIRQB+4    ; /39/ subfunction 1, KB:
  2138.     .UUO                ; /39/ read chars
  2139.     tstb    FIRQB            ; /39/ success?
  2140.     bne    90$            ; /39/ no
  2141.     mov    #trmtyp    ,r0        ; /39/ yes, look for VT type term
  2142. 10$:    tstb    @r0            ; /39/ end of list yet?
  2143.     beq    90$            ; /39/ yes, return( TTY )
  2144.     cmpb    (r0)+    ,FIRQB+6    ; /39/ no, check for a match
  2145.     bne    10$            ; /39/ not yet
  2146.     mov    #VT100    ,r0        ; /39/ yes, return(VT100)
  2147.     br    100$            ; /39/ exit
  2148.  
  2149. 90$:    mov    #TTY    ,r0        ; /39/ nothing
  2150. 100$:    return                ; /39/ exit
  2151.  
  2152.     .sbttl    login
  2153.  
  2154.  
  2155.     .iif ndf , UU.CHK,    UU.CHK = 40
  2156.     .iif ndf , UU.PRV,    UU.PRV = 34
  2157.     .iif ndf , NOSUCH,    NOSUCH = 5
  2158.     .iif ndf , NOTAVL,    NOTAVL = 10
  2159.     .iif ndf , PRVIOL,    PRVIOL = 12
  2160.     .iif ndf , QUOTA ,    QUOTA  = 105
  2161.  
  2162. ;    LOGIN    24-Sep-85  10:01:33  Brian Nelson (V9.x and later only)
  2163. ;        Added on Edit 2.36
  2164. ;        Moved to KRT80S 11-Apr-86  12:27:18
  2165.  
  2166.  
  2167.  
  2168.  
  2169.     .sbttl    Check for given privilege (V9.x and later)
  2170.  
  2171. ;     SETPRV is intended to reset the CURRENT privilege mask to the
  2172. ;    user's AUTHORIZED mask. They could be different as a result of
  2173. ;    the REMOTE LOGIN command, moving from a high access account to
  2174. ;    once with lesser access.
  2175.  
  2176. setprv::sub    #12    ,sp        ; a buffer
  2177.     mov    #JFSYS    ,XRB+0        ; drop all privs that are not mine
  2178.     .CLEAR                ; in case we inherited privilege
  2179.     clrfqb                ; now read the authorized priv mask
  2180.     movb    #UU.PRV    ,FIRQB+FQFUN    ; UUO function code
  2181.     .UUO                ; simple
  2182.     mov    #FIRQB+FQFIL,r0        ; and save them
  2183.     mov    sp    ,r2        ; copy them onto stack save area
  2184.     mov    (r0)+    ,(r2)+        ; copy
  2185.     mov    (r0)+    ,(r2)+        ; ..copy
  2186.     mov    (r0)+    ,(r2)+        ; ....copy
  2187.     mov    (r0)+    ,(r2)+        ; ......copy
  2188.     mov    #JFSYS    ,XRB+0        ; now get all we had back again
  2189.     .SET                ; simple
  2190.  
  2191.     clrfqb                ; 
  2192.     movb    #UU.PRV    ,FIRQB+FQFUN    ; read current privilege
  2193.     .UUO                ; call RSTS to do so
  2194.     mov    #FIRQB+FQFIL,r0        ; now setup to copy current over
  2195.     mov    #FIRQB+FQNAM2,r1    ; the current mask to the 'clear'
  2196.     mov    #4    ,r2        ; mask
  2197. 10$:    mov    @r0    ,(r1)+        ; copy the privilege mask
  2198.     clr    (r0)+            ; and clear this one out
  2199.     sob    r2    ,10$        ; next please
  2200.     movb    #UU.PRV    ,FIRQB+FQFUN    ; now drop ALL privileges we had
  2201.     .UUO                ; simple
  2202.     clrfqb                ; At last, make current privs the
  2203.     mov    sp    ,r2        ; ones that the user is authorized
  2204.     mov    #FIRQB+FQFIL,r1        ; to have
  2205.     mov    (r2)+    ,(r1)+        ; insert these privileges
  2206.     mov    (r2)+    ,(r1)+        ; ..insert these privileges
  2207.     mov    (r2)+    ,(r1)+        ; ....insert these privileges
  2208.     mov    (r2)+    ,(r1)+        ; ......insert these privileges
  2209.     movb    #UU.PRV    ,FIRQB+FQFUN    ; at last, set the correct mask
  2210.     .UUO                ; simple
  2211.     add    #12    ,sp        ; exit
  2212.     mov    #1    ,r0        ;
  2213.     return
  2214.  
  2215.  
  2216. chkprv::mov    2(sp)    ,r1        ; get address of priv to look for
  2217.     clrfqb                ; clear the FIRQB out
  2218.     mov    #FIRQB+FQFUN,r0        ; setup to get the bit value of WACNT
  2219.     movb    #UU.CHK    ,(r0)+        ; UUO subfunction
  2220.     inc    (r0)+            ; UU.CHK subfunction
  2221.     tst    (r0)+            ; not used
  2222. 10$:    movb    (r1)+    ,(r0)+        ; copy the desired priv to check
  2223.     bne    10$            ; next please
  2224.     .UUO                ; try it out
  2225.     movb    FIRQB    ,r0        ; if this fails its not verison 9.x
  2226.     bne    90$            ; or later
  2227.     movb    FIRQB+4    ,r0        ; success, check if priv is present
  2228.     bne    90$            ; no
  2229.     mov    #1    ,r0        ; yes, return(1)
  2230.     br    100$            ; exit
  2231. 90$:    clr    r0            ; no,  return(0)
  2232. 100$:    mov    (sp)+    ,(sp)        ; pop stack and exit
  2233.     return                ; bye
  2234.  
  2235.  
  2236. inqv9::    clrfqb                ; /39/ clear FIRQB out
  2237.     clr    ver9.x            ; /40/ assume old RSTS/E
  2238.     movb    #UU.PRV    ,FIRQB+FQFUN    ; /39/ see if version 9 or later
  2239.     .UUO                ; /39/ always works (read priv mask)
  2240.     tstb    FIRQB            ; /39/ success?
  2241.     bne    90$            ; /39/ no
  2242.     mov    sp    ,ver9.x        ; /40/ flag for v9.x and later
  2243.     clc                ; /39/ v.9x
  2244.     return                ; /39/ exit
  2245. 90$:    sec                ; /39/ not 9.x
  2246.     return                ; /39/ return
  2247.  
  2248.  
  2249.  
  2250.     .sbttl    check for current JOB priv , not PROGRAM priv.
  2251.  
  2252. ;     Added edit  2.41 to check if a user has HWCFG authorized to
  2253. ;    effect a SET LINE command. Note that this  will  not  affect
  2254. ;    the  current mask, it just checks to see if the JOB has this
  2255. ;    priv. This is different than UU.CHK in that here we look  at
  2256. ;    current  'JOB'  mask  where  the other (CHKPRV) looks at the
  2257. ;    CURRENT program priv mask. To find AUTHORIZED priv, you must
  2258. ;    call AUTHPR.
  2259. ;     Added cause the  M+  v3  Kermit will get and drop privs for
  2260. ;    SET LINE.
  2261. ;
  2262. ;    Passed:    2(sp)    Address of priv name to check
  2263. ;    Return:    r0    1 for success (or pre 9.x), zero for no priv
  2264. ;
  2265. ;    Example:
  2266. ;
  2267. ;    mov    #HWCFG    ,-(sp)
  2268. ;    call    JOBPRV
  2269. ;    tst    r0
  2270. ;    beq    error
  2271. ;
  2272. ;
  2273. ; hwcfg:.asciz    /HWCFG/
  2274. ;    .even
  2275.  
  2276.  
  2277.  
  2278. jobprv::mov    r1    ,-(sp)        ; /41/ Save a register
  2279.     mov    r2    ,-(sp)        ; /41/ ... save another one
  2280.     sub    #10    ,sp        ; /41/ temp save area
  2281.     mov    #1    ,r2        ; /41/ Assume success
  2282.     tst    ver9.x            ; /41/ version nine or later?
  2283.     beq    100$            ; /41/ no, return( success )
  2284.     clrfqb                ; /41/
  2285.     mov    #FIRQB+3,r1        ; /41/ point to FQFUN offset
  2286.     movb    #UU.PRV    ,(r1)+        ; /41/ read current priv mask.
  2287.     .UUO                ; /41/ Do it
  2288.     tstb    FIRQB            ; /41/ Check status (has to work)
  2289.     bne    90$            ; /41/ Return( failure )
  2290.     mov    sp    ,r0        ; /41/ a pointer to mask save area
  2291.     mov    (r1)+    ,(r0)+        ; /41/ save current priv mask
  2292.     mov    (r1)+    ,(r0)+        ; /41/ .save current priv mask
  2293.     mov    (r1)+    ,(r0)+        ; /41/ ..save current priv mask
  2294.     mov    (r1)+    ,(r0)+        ; /41/ ...save current priv mask
  2295.     mov    #JFSYS    ,XRB+0        ; /41/ what to do
  2296.     .CLEAR                ; /41/ Drop ALL privs now
  2297.     clrfqb                ; /41/ clear firqb out
  2298.     mov    #FIRQB+FQFUN,r0        ; /41
  2299.     movb    #UU.CHK    ,(r0)+        ; /41/ Convert priv name to bitmask
  2300.     inc    (r0)+            ; /41/ Subfunbction code = 1
  2301.     tst    (r0)+            ; /41/ skip this field
  2302.     mov    2+14(sp),r1        ; /41/ copy the priv over
  2303. 10$:    movb    (r1)+    ,(r0)+        ; /41/ copy the asciz name over
  2304.     bne    10$            ; /41/ simple
  2305.     .UUO                ; /41/ convert NAME to MASK
  2306.     mov    sp    ,r1        ; /41/ point back to save area
  2307.     mov    #FIRQB+FQNAM1,r0    ; /41/ Where the bit pattern is
  2308.     mov    #4    ,r2        ; /41/ Four words to check
  2309. 20$:    bit    (r0)+    ,(r1)+        ; /41/ Any bit(s) set here ?
  2310.     bne    30$            ; /41/ Yes, we have it
  2311.     sob    r2    ,20$        ; /41/ No, keep looking
  2312.     clr    r2            ; /41/ Flag not found
  2313.     br    40$            ; /41/ Restore old priv mask
  2314. 30$:    mov    #1    ,r2        ; /41/ Flag we have it
  2315. 40$:    clrfqb                ; /41/ Now restore JOB privs
  2316.     mov    #FIRQB+FQFUN,r0        ; /41/ point to FQFUN offset
  2317.     movb    #UU.PRV    ,(r0)+        ; /41/ read current priv mask.
  2318.     mov    sp    ,r1        ; /41/ Saved OLD priv mask
  2319.     mov    (r1)+    ,(r0)+        ; /41/ save current priv mask
  2320.     mov    (r1)+    ,(r0)+        ; /41/ .save current priv mask
  2321.     mov    (r1)+    ,(r0)+        ; /41/ ..save current priv mask
  2322.     mov    (r1)+    ,(r0)+        ; /41/ ...save current priv mask
  2323.     .UUO                ; /41/ Do it
  2324.     br    100$            ; /41/ exit
  2325.  
  2326. 90$:    clr    r2            ; /41/ failure
  2327. 100$:    mov    r2    ,r0        ; /41/ Return the status now
  2328.     add    #10    ,sp        ; /41/ Pop buffer
  2329.     mov    (sp)+    ,r2        ; /41/ ...Pop a register
  2330.     mov    (sp)+    ,r1        ; /41/ Pop a register
  2331.     mov    (sp)+    ,(sp)        ; /41/ pop parameter
  2332.     return                ; /41/ At last
  2333.  
  2334.  
  2335.  
  2336.  
  2337.  
  2338.  
  2339.     .sbttl    setcc    setup a control C trap
  2340.  
  2341.  
  2342. ;    SETCC    arm the control C trap
  2343. ;    TTAST    field the ast
  2344. ;
  2345. ;    It would be REALLY nice if we had the equivalent of an IO.KIL
  2346. ;    so we could cancel a pending terminal read as I do in the RSX
  2347. ;    based Kermits. While it is true that control C will terminate
  2348. ;    a read on your console terminal, we need to be able to cancel
  2349. ;    a read that's waiting on another terminal,  as is the case if
  2350. ;    Kermit is running LOCAL (set lin ttnn:).  Hopefully, some day
  2351. ;    DIGITAL will provide that.
  2352.  
  2353.  
  2354.  
  2355. setcc::    mov    #ttast    ,@#24
  2356.     .ttrst
  2357.     .ttech
  2358.     return
  2359.  
  2360. ttast:    save    <r0,r1>
  2361.     call    cctrap
  2362.     mov    #lunsize*2,r1
  2363. 10$:    tst    linit(r1)
  2364.     beq    20$
  2365.     mov    r1    ,-(sp)
  2366.     asr    (sp)
  2367.     call    snoecho
  2368. 20$:    sub    #2    ,r1
  2369.     bge    10$
  2370.     unsave    <r1,r0>
  2371.     rti
  2372.  
  2373.     .globl    cctrap
  2374.  
  2375.  
  2376. ;    dummy epts and symbols for rsx11m/m+ compatibility
  2377.  
  2378. tidias::
  2379. tidiar::return
  2380. tmsdia::
  2381. setsla::clr    r0
  2382.     return
  2383.  
  2384. wtmask    ==    0            ; dummy definitions for event flags
  2385. ef.co    ==    0            ; used under RSX
  2386. ef.ti    ==    0
  2387. bit.co    ==    0
  2388. bit.ti    ==    0
  2389. sf.gmc    ==    2560 
  2390. sf.smc    ==    2440 
  2391. tc.fdx    ==    64 
  2392. tf.ral    ==    10    
  2393. tc.tbf    ==    71    
  2394. tc.slv    ==    0
  2395. tc.abd    ==    0
  2396. tc.dlu    ==    0
  2397. tc.xsp    ==    0
  2398. tc.rsp    ==    0
  2399. tf.rne    ==    20
  2400. tf.wal    ==    10
  2401.  
  2402. xdorsx::call    doconn
  2403.     return
  2404.  
  2405.     .globl    doconn
  2406.  
  2407.  
  2408. rstsrv::clr    r0
  2409.     return
  2410.  
  2411. paksta::                    ; packet timing stats
  2412. ;    dummy for now
  2413.     return
  2414.  
  2415. ttrctl::
  2416.     .ttrst                ; cancel ctrl/o
  2417.     return
  2418.  
  2419.     .end
  2420.