home *** CD-ROM | disk | FTP | other *** search
/ Columbia Kermit / kermit.zip / pdp11 / k11rt4.mac < prev    next >
Text File  |  2020-01-01  |  28KB  |  1,117 lines

  1.     .title    k11rt4    i/o for rt11 version 4 or 5 for Kermit-11
  2.     .ident    /1.0.01/
  3.  
  4.  
  5. ;    08-Mar-84  09:18:25  Brian Nelson
  6. ;
  7. ;    6-May-85             Added a little more to the TSX message to 
  8. ;                            indicate that the TSX version comes up in
  9. ;                            the remote mode.  If a set line 0 is performed
  10. ;                            you are changed to a local kermit and send
  11. ;                            receive do not work.  Going to server mode
  12. ;                            works fine.  Purpose of the message is to alert
  13. ;                            user that the default is remote mode and no
  14. ;                            setting of the line is required.
  15. ;
  16. ;    20-May-86  09:03:30  Mods for .SETTOP in XM, also .SERR mods
  17. ;
  18. ;    Copyright (C) 1984 1986 Change Software, Inc.
  19. ;
  20. ;     This is the RT11 version of K11RMS.MAC.  It simply tries
  21. ;    to emulate,  as much as is  reasonable,  what the RMS i/o
  22. ;    routines do for  RSX and RSTS.  This strains a few things
  23. ;    in as  much that RT11  does not provide  much of anything
  24. ;    in the  sense of file services as compared to that  which
  25. ;    RMS11 v2 provides.  Since the whole of Kermit-11 is built
  26. ;    around RMS11  for i/o we will even  take the step  to map
  27. ;    RT11 error codes  into RMS11 error  codes,  thus allowing
  28. ;    the use  of the RMS error  routines and removing any need
  29. ;    to modify Kermit-11 elsewhere.  
  30. ;    We won't really use the RMS error routines since they are
  31. ;    much to comprehensive for the errors that RT can have.
  32. ;
  33. ;    This routine MUST be in the root segment.
  34. ;    The RT11 executive must have multiple terminal support.
  35. ;
  36. ;
  37. ;    Disk i/o epts
  38. ;
  39. ;    open  ( %loc filename, %val channel_number ,%val type )
  40. ;    create( %loc filename, %val channel_number ,%val type )
  41. ;    getrec( %loc buffer  , %val channel_number ) { returns RSZ in R1}
  42. ;    putrec( %loc buffer  , %val record_size    ,%val channel_number )
  43. ;    close ( %val channel_number )
  44. ;    putc  ( %val char    , %val channel_number )
  45. ;    getc  ( %val channel_number )
  46.  
  47.  
  48.  
  49.     .sbttl    non disk i/o entry points
  50.  
  51. ;    In all cases, R0 will have the returned error code (zero for success)
  52. ;    For KBREAD and READ, R1 will have the size of the read
  53. ;    For BINREAD,  R1 will have the character just read
  54. ;
  55. ;    The use of %LOC and %VAL are from VMS Pascal and Fortran.
  56. ;    %LOC means ADDRESS, whereas %VAL means literal. All call
  57. ;    formats assume the first argument is at 0(r5), the next
  58. ;    at 2(r5) and so on, as in:
  59. ;
  60. ;    clr    -(sp)            ; today's date by default
  61. ;    mov    #datebf    ,-(sp)        ; where to put the converted string
  62. ;    mov    sp    ,r5        ; call ASCDAT
  63. ;    call    ascdat            ; simple
  64. ;    cmp    (sp)+    ,(sp)+        ; all done
  65. ;
  66. ;    or by using the CALLS macro (defined in K11MAC.MAC)
  67. ;
  68. ;    calls    ascdat    ,<#datebf,#0>
  69. ;
  70. ;
  71. ;    Any version of Kermit-11 which can not, due to the lack of
  72. ;    executive  support,  implement a function should return an
  73. ;    error of -1 in r0.  For instance,  RT11 does not have  any
  74. ;    executive primitives to do wildcarding directory lookup.
  75. ;
  76. ;
  77. ;
  78. ;
  79. ;    ASCDAT    ( %loc buffer, %val datevalue )
  80. ;    ASCTIM    ( %loc buffer, %val timevalue )
  81. ;    ASSDEV    ( %loc device_name )
  82. ;    BINREA    ( %val lun, %val timeout )
  83. ;    BINWRI    ( %loc buffer, %val byte_count, %val lun )
  84. ;    CANTYP    ( %loc device_name, %val lun )
  85. ;    CHKABO    ( )
  86. ;    DODIR    ( %loc directory_string, %val lun )
  87. ;    DRPPRV    ( )
  88. ;    DSKUSE    ( %loc returned_string )
  89. ;    ECHO    ( %loc terminal_name )
  90. ;    EXIT    ( )
  91. ;    GETPRV    ( )
  92. ;    GETUIC    ( )
  93. ;    GTTNAM    ( %loc returned_ttname )
  94. ;    KBREAD    ( %loc buffer )
  95. ;    L$PCRL    ( )
  96. ;    L$TTYO    ( %loc buffer, %val bytecount )
  97. ;    LOGOUT    ( )
  98. ;    NAMCVT    ( %loc source_filename, %loc returned_normal_name )
  99. ;    NOECHO    ( %loc device_name, %val lun )
  100. ;    QUOCHK    ( )
  101. ;    READ    ( %loc buffer, %val buffer_length, %val lun, %val block_number )
  102. ;    SETCC    ( %loc control_c_ast_handler )
  103. ;    SETSPD    ( %loc device_name, %val speed )
  104. ;    SUSPEN    ( %val seconds, %val ticks )
  105. ;    SYSERR    ( %val error_number, %loc error_text_buffer )
  106. ;    TTRFIN    ( )
  107. ;    TTRINI    ( )
  108. ;    TTSPEE    ( %loc terminal_name )
  109. ;    TTYDTR    ( %loc terminal_name )
  110. ;    TTYFIN    ( %loc terminal_name, %val lun )
  111. ;    TTYHAN    ( %loc terminal_name )
  112. ;    TTYINI    ( %loc terminal_name, %val lun, %val open_flags )
  113. ;    TTYPAR    ( %loc terminal_name, %val parity_code )
  114. ;    TTYRST    ( %loc terminal_name )
  115. ;    TTYSAV    ( %loc terminal_name )
  116. ;    TTYSET    ( %loc terminal_name )
  117. ;    WRITE    ( %loc buffer, %val buffer_length, %val lun, %val block_number )
  118. ;    XINIT    ( )
  119.  
  120.  
  121.  
  122.     .sbttl    define macros and local i/o database
  123.  
  124.  
  125.  
  126.  
  127.     .if ndf, K11INC
  128.     .ift
  129.     .include    /IN:K11MAC.MAC/
  130.     .endc
  131.  
  132.     .iif ndf,k11inc    ,.error    ; missing INCLUDE for K11MAC.MAC
  133.  
  134.     cr    =    15
  135.     lf    =    12
  136.     ff    =    14
  137.     soh    =    1
  138.     maxsiz    =    1000
  139.     errbyt    ==    52
  140.     topmem    =    50
  141.     JSW    =    44
  142.  
  143.     .enabl    gbl
  144.  
  145.     .psect    $code    ,ro,i,lcl,rel,con
  146.     .psect    rtdir1    ,rw,d,gbl,rel,con
  147.     .psect    rtioda    ,rw,d,lcl,rel,con
  148.  
  149. ;    Note that for RT11,  of course, all files are considered
  150. ;    to be image files. If there was a RMS11/RT we would have
  151. ;    had  transportability from RSX and  RSTS version of disk
  152. ;    i/o.
  153.  
  154. buflst::.word    ttbuf    ,0    ,0    ,0    ,0
  155. bufdef::.word    ttbuf    ,0    ,0    ,0    ,0
  156. bufsiz::.word    ttbsiz    ,maxsiz    ,maxsiz    ,maxsiz    ,maxsiz
  157. filtyp:    .word    terminal,text    ,text    ,text    ,text
  158. bufp:    .word    0    ,0    ,0    ,0    ,0
  159. bufs:    .word    0    ,0    ,0    ,0    ,0
  160. mode:    .word    1    ,0    ,0    ,0    ,0
  161. blknum:    .word    0    ,0    ,0    ,0    ,0
  162. sizof:    .word    0    ,0    ,0    ,0    ,0
  163.  
  164.     filsiz    ==    100
  165.  
  166. defdir::.blkb    filsiz+2        ; default directory for send and rec
  167. srcnam::.blkb    filsiz+2        ; original send filespec
  168. filnam::.blkb    filsiz+2        ; output from directory lookup routine
  169. asname::.blkb    filsiz+2        ; for SEND file [as] file
  170. bintyp::.word    0
  171. totp.s::.word    0,0
  172. totp.r::.word    0,0
  173. dkdev:    .rad50    /DK /
  174.  
  175.     $hbufs    ==    1
  176.  
  177.     ie.its    ==    0
  178.     fb$stm    ==    0
  179.     fb$var    ==    0
  180.     fb$cr    ==    0
  181.     xdorsx    ==    0
  182.  
  183. df$rfm::.word    0
  184. df$rat::.word    0
  185.  
  186.  
  187. ; /51/    The following buffers are allocated after the initial .SETTOP
  188. ;    They can swap with the USR if need be.
  189.  
  190.     ALSIZE    ==    600
  191.     SDBSIZ    ==    600
  192.     $$LBUF    ==    < <MAXLNG/10>+MAXLNG > & 177776
  193.     $$BUFP    ==    <<MAXSIZ+2>*4> + $$LBUF + ALSIZE
  194.  
  195.  
  196.  
  197.     ttbsiz    =    40
  198. ttbuf:    .blkb    ttbsiz+2
  199. $prtbu::.word    ttbuf            ; /51/ Altered at startup
  200.  
  201. tsxsav::.word    0
  202. devidx::.word    0            ; /45/ From .dstat, device type
  203. wtime:    .word    0,60.
  204. cancel:
  205. mtsts:    .word    0,0,0,0,0
  206. timbuf:    .word    0,0
  207. timbf1:    .word    0,0
  208. clkflg::.word    0
  209. tenth:    .word    0,6
  210. wasxc::    .word    0
  211. jobsts::.blkw    10            ; /51/ From .GTJB
  212. freept::.word    0            ; /51/ For the next general allocation
  213. fetpt::    .word    0            ; /51/ For the next .FETCH
  214. fetptm::.word    0            ; /51/ Max address for fetching
  215. xmfetp::.word    0            ; /51/ Base of area for fetching, XM
  216. maxtop::.word    0            ; /51/ Size after .settop
  217. xklgbu::.word    0            ; /51/ Pointer to special XL buffer
  218. montyp::.word    0            ; /51/ < 0 -> SJ, = 0 -> FB, > 0 -> XM
  219. hilimi::.word    50            ; /51/ It's 50 for FB, $limit+2 for XM
  220. $ttyou::.word    0            ; /51/ Filled in at startup
  221. $$cbta::.word    0            ; /53/ 
  222. $limit::.limit                ; /51/ Enable XM .SETTOP .limit
  223. lun1    =    1
  224. lun2    =    2
  225. lun3    =    3
  226. lun4    =    4
  227. maxlun    =    lun4
  228.  
  229.     
  230.  
  231.     .sbttl    error mapping, error codes defined in overlay K11RTE
  232.     
  233.     .psect    $pdata
  234.  
  235. cloerr::.word    er$sy1    ,er$sy1    ,er$sys    ,er$prv
  236. csierr::.word    er$fnm    ,er$dev    ,er$sy2
  237. dsterr::.word    er$dev
  238. enterr::.word    er$lby    ,er$ful    ,er$sy3    ,er$prv    ,er$sy3
  239. feterr::.word    er$dev    ,er$sy4
  240. lokerr::.word    er$lby    ,er$fnf    ,er$sys
  241. reaerr::.word    er$eof    ,er$rer    ,er$nop    ,er$sys
  242. wrierr::.word    er$eof    ,er$wer    ,er$nop    ,er$sys
  243. twaerr::.word    er$que
  244. mrkerr::.word    er$que
  245. renerr::.word    er$lby    ,er$fnf    ,er$iop    ,er$prv
  246. xcierr::.word    er$lby    ,er$xco
  247. xcspfu::.word    er$fun    ,er$hrd    ,er$nop    ,er$sys
  248.     .word    er$sup
  249. faterr::.word    fa$imp    ,fa$nhd    ,fa$dio    ,fa$fet    ,fa$ovr    ,fa$dfl    ,fa$adr
  250.     .word    fa$lun    ,fa$imp    ,fa$imp    ,fa$imp    ,fa$idr    ,fa$imp    ,fa$imp
  251.     .word    fa$imp    ,fa$imp    ,fa$imp    ,fa$imp
  252.  
  253. mterr::    .word    er$nin    ,er$nat    ,er$lun    ,er$iop    ,er$bsy    ,er$buf    ,er$sys
  254.     .word    er$sup
  255.  
  256.     .psect    $rtque
  257. nrtque    ==    20
  258. rtque::    .blkw    10.*nrtque
  259.     .psect    $code
  260.     
  261.  
  262.     .sbttl    one shot init code for Kermit-11 RT11
  263.  
  264.     CONFIG    =    300
  265.     CONFG2    =    370
  266.     SYSGEN    =    372
  267.     $USRLC    =    266
  268.     SYSVER    =    276
  269.  
  270.     PRO350    =    20000
  271.     TSXPLU    =    100000
  272.  
  273.     SJSYS    =    1
  274.     XMSYS    =    10000
  275.                     
  276.     .MCALL    .QSET,.TWAIT,.FETCH,.GVAL,.SETTOP,.SERR,.HERR,.GTIM
  277.     .MCALL    .DSTAT,.MTSTAT,.EXIT
  278.  
  279.  
  280.  
  281. ;    23-May-86  18:21:33 XINIT moved to K11RTI.MAC
  282.  
  283.  
  284.     GLOBAL    <lun.in,lun.ou,proflg,rtvol,rtque,tsxflg>
  285.     GLOBAL    <defdir,infomsg>
  286.  
  287.  
  288.  
  289.     .sbttl    open a file for rt11
  290.  
  291.     .MCALL    .CSISPC,.DSTATUS,.LOOKUP,.FETCH,.ENTER,.CLOSE
  292.     .MCALL    .SERR    ,.HERR    ,.PURGE
  293.     .psect    $code
  294.  
  295. ;    OPEN( &filename,channel,type )
  296. ;
  297. ;    CREATE( &filename,channel,type )
  298.  
  299.  
  300.  
  301.     .psect    $pdata
  302. defext:    .word    0
  303.     .word    0
  304.     .word    0
  305.     .word    0
  306. en$siz::.word    0            ; 1/2 largest free or 2nd largest
  307.     .psect    $code
  308.  
  309.  
  310.     .enabl    lsb
  311.  
  312. fcreat::                ; Create a file
  313. append::                ; Alternate EP's
  314. create::mov    #1    ,r0        ; Say we want to create
  315.     br    10$            ; And off to common code
  316.  
  317. fopen::                    ; Open a file for reading
  318. open::    clr    r0            ; .LOOKUP please
  319. 10$:    Save    <r1,r2,r3>        ; Save these
  320.     mov    r0    ,r2        ; .ENTER/.LOOKUP ?
  321.     mov    (r5)    ,r1        ; Filespec address, .Asciz
  322.     mov    2(r5)    ,r0        ; LUN
  323.     mov    4(r5)    ,r3        ; Binary/text
  324.     call    mtb$op            ; Call file opener
  325.     Unsave    <r3,r2,r1>        ; Pop em
  326.     return                ; And exit
  327.                     ;
  328.     .dsabl    lsb            ;
  329.  
  330.  
  331. ;    MTB$OP    20-Nov-86  14:56:59  BDN
  332. ;
  333. ;    Input:    R0    Lun
  334. ;        R1    Filename, .asciz
  335. ;        R2    Direction, zero --> read (.LOOKUP), else write (.ENTER)
  336. ;        R3    Binary flag <> 0 --> binary
  337. ;    Return:    R0    Mapped error code
  338. ;
  339. ;     This is the old open/create code from Kermit-11/RT rewritten for
  340. ;    inclusion in another application. I have replaced the old code as
  341. ;    this version is cleaner and 100 words shorter.
  342.  
  343.     .iif ndf, BINARY, BINARY = 1
  344.     .iif ndf, RD$ONL, RD$ONL = 0
  345.     .iif ndf, RD$WRI, RD$WRI = 1
  346.     .ASSUME    RD$ONL EQ 0
  347.     .ASSUME    BINARY EQ 1
  348.  
  349.  
  350. Mtb$op::Save    <r4,r5>            ; Save regs (r1,r2,r3 saved above)
  351.     sub    #40.*2    ,sp        ; Allocate a buffer for .CSISPC
  352.     mov    r0    ,r4        ; Copy the LUN to use
  353.     .SERR                ; Inhibit fatal aborts by RT
  354.     asl    r4            ; Zero?
  355.     bne    10$            ; Non-zero
  356.     mov    sp    ,mode+0        ; Zero, implies terminal always
  357.     clr    bufp+0            ; Clear this out also
  358.     clr    r0            ; No errors
  359.     br    100$            ; Exit
  360. 10$:    clr    sizof(r4)        ; Clear I/O subsystem tables
  361.     clr    bufp(r4)        ; Clear buffer pointer out
  362.     clr    bufs(r4)        ; Clear buffer size out
  363.     clr    mode(r4)        ; Assume reading
  364.     clr    blknum(r4)        ; To keep track of current VBN
  365.     mov    r3    ,filtyp(r4)    ; Text or binary?
  366.     mov    bufdef(r4),r0        ; Insert default buffer addresses
  367.     mov    r0    ,buflst(r4)    ; Copy it
  368.     mov    #MAXSIZ    ,r5        ; Insert the buffer size
  369.     mov    r5    ,bufsiz(r4)    ; Do it
  370. 20$:    clrb    (r0)+            ; Clear it out
  371.     sob    r5    ,20$        ; Next please    
  372.     mov    sp    ,r5        ; Point to save area
  373. 30$:    movb    (r1)+    ,(r5)+        ; Copy the filename over now
  374.     bne    30$            ; Next please
  375.     dec    r5            ; Back up to the null.
  376.     movb    #'=    ,(r5)+        ; Setup
  377.     clrb    @r5            ; .Asciz
  378.     mov    sp    ,r5        ; Point back to save area
  379.     mov    #csierr    ,r1        ; Assume .CSI error mapping
  380.     .CSISPC    r5,#defext,r5        ; Do it
  381.     mov    r5    ,sp        ; Restore the stack pointer
  382.     bcs    80$            ; Filename parse error
  383.     tst    @r5            ; Device name present?
  384.     bne    40$            ; Yes
  385.     mov    #^RDK     ,@r5        ; No, insert one then
  386. 40$:    CALL    fetch            ; Insure that handlers are loaded
  387.     tst    r0            ; Well?
  388.     bne    100$            ; No, error codes already mapped.
  389.     mov    r4    ,r3        ; Get channel number back
  390.     asr    r3            ; Get correct channel number
  391.     tst    r2            ; And check for .ENTER
  392.     bne    50$            ; .ENTER
  393.                     ;
  394.     mov    #lokerr    ,r1        ; Set up error mapping for .LOOKUP
  395.     .LOOKUP    #rtwork,r3,r5        ; Do it
  396.     bcs    80$            ; It failed
  397.     mov    r0    ,sizof(r4)    ; Success, return the created size
  398.     mov    #-1    ,bufp(r4)    ; Force a disk read on first call.
  399.     clr    r0            ; Success
  400.     br    100$            ; Exit
  401.                     ;
  402. 50$:    tst    2(r5)            ; Never allow NFS writes to a disk
  403.     bne    60$            ; Its ok
  404.     mov    #^RNON    ,2(r5)        ; No name, stuff one in then
  405.     mov    #^RNAM    ,4(r5)        ; ....
  406.     mov    #^RTMP    ,6(r5)        ; ......
  407. 60$:    mov    #enterr    ,r1        ; Assume .ENTER error code mapping
  408.     mov    at$len    ,r2        ; Is there a protocol passed size?
  409.     bne    70$            ; Yes
  410.     mov    en$siz    ,r2        ; No, use SET value or default.
  411. 70$:    .ENTER    #rtwork,r3,r5,r2    ; Try hard to create the file
  412.     bcs    80$            ; No way
  413.     mov    sp    ,mode(r4)    ; Writing today
  414.     clr    r0            ; Success
  415.     br    100$            ; Time to go now
  416.                     ;
  417. 80$:    movb    @#errbyt,r0        ; Get the error code
  418.     bpl    90$            ; Normal error
  419.     com    r0            ; Hard error code
  420.     mov    #faterr    ,r1        ; Map into the hard errors
  421. 90$:    asl    r0            ; Word addressing
  422.     add    r0    ,r1        ; Get the mapped (fake RMS) error
  423.     asr    r4            ; Channel number
  424.     .PURGE    r4            ; Insure the channel in cleared
  425.     mov    (r1)    ,r0        ; Copy and exit
  426. 100$:    mov    r0    ,-(sp)        ; Save errors
  427.     .HERR                ; Restore normal error handling
  428.     mov    (sp)+    ,r0        ; Pop
  429.     add    #40.*2    ,sp        ; Pop stack
  430.     Unsave    <r5,r4>            ; Pop registers and exit
  431.     return
  432.  
  433.  
  434.  
  435.  
  436.  
  437. getsiz::mov    @r5    ,r1        ; get opened filesize
  438.     asl    r1            ; get the lun times 2
  439.     mov    sizof(r1),r1        ; return the size
  440.     clr    r0            ; no errors
  441.     return                ; bye
  442.  
  443.     
  444.  
  445.     .sbttl    close a file
  446.     .MCALL    .CLOSE
  447.  
  448.  
  449. ;    C L O S E
  450. ;
  451. ;    close (%val lun)
  452. ;
  453. ;    input:    @r5    channel number to close
  454. ;    output:    r0    mapped error code
  455. ;
  456. ;    calls:    flush(lun)
  457.  
  458.  
  459. close::    save    <r1>            ; save registers we may have
  460.     call    flush            ; dump out any remaining buffer
  461.     mov    @r5    ,r1        ; then disconnect the access stream
  462.     beq    10$            ; terminal
  463.     .CLOSE    r1            ; do the rt close
  464.     bcc    10$            ; it worked
  465.     movb    @#errbyt,r0        ; it failed, map the rt11 error
  466.     asl    r0            ; to something more descriptive
  467.     mov    cloerr(r0),r0        ; simple
  468.     br    20$            ; map the error please
  469. 10$:    clr    r0            ; no errors
  470. 20$:    asl    r1            ; channel number times 2
  471.     clr    bufp(r1)        ; buffer_pointer[lun] := 0
  472.     clr    sizof(r1)        ; no size please
  473.     unsave    <r1>            ; pop the saved r1
  474.     return                ; and exit with error in r0
  475.  
  476.  
  477. rewind::mov    @r5    ,r0        ; get the channel number
  478.     beq    100$            ; for the terminal, a no-op
  479.     asl    r0            ; times two please
  480.     mov    #-1    ,bufp(r0)    ; flag a buffer reload is needed
  481.     clr    bufs(r0)        ; nothing is in the buffer
  482.     clr    blknum(r0)        ; first block of the disk file
  483. 100$:    clr    r0            ; no errors are possible
  484.     return                ; bye
  485.  
  486.  
  487.  
  488.  
  489.  
  490.  
  491.     .sbttl    put a record to an rt11 sequential file
  492.  
  493.  
  494. ;    P U T R E C
  495. ;
  496. ;    putrec( %loc buffer, %val record_size, %val channel_number )
  497. ;
  498. ;    input:    @r5    address of user buffer
  499. ;        2(r5)    record size
  500. ;        4(r5)    channel number
  501. ;
  502. ;    output:    r0    rms sts
  503. ;
  504. ;    Write the next record to  a disk file.
  505. ;
  506. ;    Assumption: The record to be written will have a cr/lf
  507. ;            appended  to it unless the filetype is not
  508. ;            text.  In other words, PUTREC provides the
  509. ;            carriage control unless the file is a ter-
  510. ;            minal.
  511.  
  512.  
  513. putrec::save    <r1,r2,r3>        ; save registers we may need
  514.     mov    2(r5)    ,r2        ; the size of the i/o
  515.     mov    @r5    ,r3        ; the buffer address
  516.     mov    4(r5)    ,r1        ; the channel number please
  517.     bne    10$            ; a real disk file
  518.  
  519.     tst    r2            ; faking output to a terminal
  520.     beq    100$            ; nothing at all to do ?
  521.     print    r3    ,r2        ; do the terminal i/o
  522.     br    100$            ; bye
  523.     
  524.  
  525. 10$:    tst    r2            ; the size of the i/o to do
  526.     beq    30$            ; nothing to do, add carriage control
  527.  
  528. 20$:    clr    r0
  529.     bisb    (r3)+    ,r0        ; the character to write out
  530.     call    putcr0            ; channel is passed in r1
  531.     tst    r0            ; did the write fail ?
  532.     bne    100$            ; yes, exit asap
  533.     sob    r2    ,20$        ; next ch please
  534.  
  535. 30$:    asl    r1            ; get the channel number times 2
  536.     cmp    filtyp(r1),#text    ; is this a text file
  537.     bne    100$            ; no, don't add carriage control in
  538.     asr    r1            ; get the channel number back
  539.     movb    #cr    ,r0        ; and add in a cr/lf
  540.     call    putcr0            ; simple
  541.     movb    #lf    ,r0        ; and at last the line feed
  542.     call    putcr0            ; do the line feed at the end
  543.  
  544. 100$:    unsave    <r3,r2,r1>        ; pop registers we saved
  545.     return                ; bye
  546.  
  547.  
  548.  
  549.     .sbttl    getc    get one character from an input file
  550.     .MCALL    .READW
  551.  
  552.  
  553. ;    G E T C
  554. ;
  555. ;    getc(%val channel_number)
  556. ;
  557. ;    input:    @r5    channel_number
  558. ;    output:    r0    rms error status
  559. ;        r1    the character just read
  560.  
  561. getc::    mov    @r5    ,r0
  562.     call    getcr0
  563.     return
  564.  
  565. fgetcr::save    <r3>            ; use for saving the channel#
  566. 10$:    mov    r0    ,r3        ; save the channel number please
  567.     call    .getc            ; get the next ch please
  568.     tst    r0            ; did the read work ok ?
  569.     bne    100$            ; no, exit
  570.     asl    r3            ; get the channel number times 2
  571.     cmp    filtyp(r3),#text    ; if filetype[lun] = text
  572.     bne    100$            ;  then
  573.     tstb    r1            ;   if ch = NULL
  574.     bne    100$            ;    then try-again
  575.     asr    r3            ; get origional channel back
  576.     mov    r3    ,r0        ; setup the correct call format
  577.     br    10$
  578. 100$:    unsave    <r3>
  579.     return
  580.  
  581.  
  582. .getc:    save    <r2,r3>            ; save temps
  583.     mov    r0    ,r2        ; channel number please
  584.     mov    r0    ,r1        ; for the .READW please
  585.     asl    r2            ; times 2
  586.     tst    bufs(r2)        ; anything in the buffer ?
  587.     beq    10$            ; no, please load it
  588.     cmp    bufp(r2),#-1        ; need to initialize the buffer?
  589.     bne    20$            ; no
  590. 10$:    mov    bufsiz(r2),r3        ; we need buffer size in words
  591.     asr    r3            ; convert bytes to words
  592.     .READW    #rtwork,r1,buflst(r2),r3,blknum(r2)
  593.     bcs    90$            ; it failed, bye
  594.     inc    blknum(r2)        ; next time read the next block
  595.     clr    bufp(r2)        ; it worked. clear current pointer
  596.     asl    r0            ; convert words read to bytes
  597.     mov    r0    ,bufs(r2)    ; and save the record size
  598. 20$:    mov    buflst(r2),r3        ; get the address of the buffer
  599.     add    bufp(r2),r3        ; and point to the next character
  600.     clr    r1            ; to be returned in r1
  601.     bisb    @r3    ,r1        ; simple
  602.     inc    bufp(r2)        ; buffer.pointer := succ(buffer.pointer)
  603.     dec    bufs(r2)        ; amountleft := pred( amountleft )
  604.     clr    r0            ; no errors please
  605.     br    100$
  606.  
  607. 90$:    movb    @#errbyt,r0        ; get the error code
  608.     asl    r0            ; times two
  609.     mov    reaerr(r0),r0        ; map it into a unique global error
  610.  
  611. 100$:    unsave    <r3,r2>
  612.     return
  613.  
  614.  
  615.  
  616.     .sbttl    putc    put a single character to an rms file
  617.     .MCALL    .WRITW
  618.  
  619. ;    P U T C
  620. ;
  621. ;    input:    @r5    the character to put
  622. ;        2(r5)    the channel number to use
  623. ;
  624. ;    Buffer single character i/o to internal disk buffer.
  625. ;    Buffer is dumped if internal buffer is  full.
  626. ;    The local buffers are allocated in CREATE and OPEN.
  627.  
  628.  
  629. putc::    save    <r1>            ; simply save r1 and call putcr0
  630.     mov    2(r5)    ,r1        ; to do it. putcr0 will be somewhat
  631.     clr    r0            ; faster to call directly due to the
  632.     bisb    @r5    ,r0        ; overhead involved in setting up an
  633.     call    putcr0            ; argument list.
  634.     unsave    <r1>            ; pop saved r1 and exit
  635.     return                ; bye
  636.  
  637.  
  638. putcr0::save    <r1,r2,r3,r4>        ; save registers we use
  639.     mov    r1    ,r2        ; channel number
  640.     asl    r2            ; times 2 of course
  641.     cmp    bufp(r2),bufsiz(r2)    ; is the buffer full ?
  642.     blo    20$            ; no, store some more characters in it
  643.     movb    r0    ,r3        ; yes, save the input character r0
  644.     mov    bufsiz(r2),r4        ; and setup for a .WRITW
  645.     asr    r4            ; rt11 needs word count not byte count
  646.     tst    r1            ; channel zero is always terminal
  647.     beq    3$            ; simple
  648.     cmp    filtyp(r2),#terminal    ; check for being a terminal today?
  649.     bne    4$            ; not a terminal
  650. 3$:    print    buflst(r2),bufsiz(r2)    ; a terminal, force it out please
  651.     br    5$            ; and reinit the buffer now
  652. 4$:    .WRITW    #rtwork,r1,buflst(r2),r4,blknum(r2); dump this block to disk
  653.     bcs    90$            ; it failed for some reason
  654. 5$:    inc    blknum(r2)
  655.     clr    bufp(r2)        ; pointer := 0
  656.     mov    buflst(r2),r4        ; it worked. zero the buffer now
  657.     mov    bufsiz(r2),r0        ; get the buffer address and size
  658. 10$:    clrb    (r4)+            ; for i := 1 to bufsiz
  659.     sob    r0    ,10$        ;   do buffer[i] := chr(0)
  660.     movb    r3    ,r0        ; ok, restore the old character
  661. 20$:    mov    bufp(r2),r1        ; get the current buffer pointer
  662.     add    buflst(r2),r1        ; and point to a new home for the
  663.     movb    r0    ,@r1        ; the input character in r0
  664.     inc    bufp(r2)        ; pointer := succ( pointer )
  665.     clr    r0            ; success
  666.     br    100$
  667.  
  668. 90$:    movb    @#errbyt,r0        ; get the rt11 error code
  669.     asl    r0            ; times two
  670.     mov    wrierr(r0),r0        ; map it into a global error code
  671.  
  672. 100$:    unsave    <r4,r3,r2,r1>
  673.     return
  674.  
  675.  
  676.     .sbttl    flush
  677.     .MCALL    .WRITW
  678.  
  679. flush:    save    <r1,r2>
  680.     mov    @r5    ,r1        ; get the internal channel number
  681.     asl    r1            ; times 2 for indexing
  682.     tst    bufp(r1)        ; anything in the buffer
  683.     beq    100$            ; no
  684.     tst    mode(r1)        ; writing today ?
  685.     beq    100$            ; no
  686.     tst    r1            ; terminal today ?
  687.     beq    20$            ; yes
  688.     mov    bufsiz(r1),r2        ; rt11 likes to have word counts
  689.     asr    r2            ; simple
  690.     .WRITW    #rtwork,@r5,buflst(r1),r2,blknum(r1)
  691.     br    100$
  692.  
  693. 20$:    print    buflst(r1),bufp(r1)
  694.     br    100$
  695.  
  696. 100$:    unsave    <r2,r1>
  697.     clr    r0
  698.     return
  699.  
  700.  
  701.  
  702.  
  703.  
  704.     .sbttl    fparse    parse filename and fill in with defaults
  705.  
  706.  
  707. ;    F P A R S E
  708. ;
  709. ;    input:    @r5    input filename,     .asciz
  710. ;        defdir    the default directory name string to use
  711. ;
  712. ;    output:    2(r5)    expanded filename, .asciz, maximum length 63 bytes
  713. ;        r0    error codes
  714. ;
  715. ;    For RT11, simply return the passed string. Perhaps later do
  716. ;    something real.
  717.  
  718.  
  719. fparse::save    <r1>
  720.     mov    #defdir    ,r0
  721.     mov    2(r5)    ,r1
  722. 10$:    movb    (r0)+    ,(r1)+
  723.     bne    10$
  724.     dec    r1
  725.     copyz    @r5    ,r1        ; simple
  726.     clr    r0            ; no errors are possible today
  727.     unsave    <r1>
  728.     return                ; bye
  729.  
  730.     global    <defdir>
  731.  
  732.  
  733.  
  734.  
  735.  
  736.  
  737.     .sbttl    l$ttyout
  738.  
  739. ;    Print a string to the console terminal
  740. ;
  741. ;    Input:    @r5    buffer address
  742. ;        2(r5)    string length
  743. ;
  744. ;    If 2(r5) is zero, then assume .asciz
  745.  
  746.     .if eq    ,0
  747.     .ift
  748.  
  749. l$ttyo::call    @$ttyou
  750.     return
  751.  
  752.     .iff
  753.  
  754. l$ttyo::save    <r0,r1,r2,r3>        ; save registers we may need
  755.     mov    @r5    ,r1        ; get the string address
  756.     mov    2(r5)    ,r2        ; get the string length
  757.     bne    20$            ; non-zero then
  758.     mov    r1    ,r2        ; count until a null now
  759. 10$:    tstb    (r2)+            ; well ?
  760.     bne    10$            ; not yet, keep looking
  761.     sub    r1    ,r2        ; get the length now
  762.     dec    r2            ; all done
  763.     beq    100$            ; nothing to print at all?
  764.  
  765. 20$:    mov    $prtbuf    ,r0        ; now buffer the i/o to avoid
  766.     mov    #36    ,r3        ; the printing of cr/lf at the
  767. 30$:    tstb    (r1)+            ; don't copy nulls please
  768.     beq    35$            ; ignore if null
  769.     movb    -1(r1)    ,(r0)+        ; copy a byte please
  770. 35$:    dec    r2            ; done yet ?
  771.     beq    40$            ; yes
  772.     sob    r3    ,30$        ; no, next please
  773. 40$:    movb    #200    ,(r0)+        ; insure no carraige control !
  774.     clrb    @r0            ; must be passed .asciz
  775.     mov    $prtbuf    ,r0        ; point back to the start of buffer
  776.     emt    351            ; do the .print kmon request
  777.     tst    r2            ; any more data to buffer ?
  778.     bne    20$            ; yes, try again
  779.  
  780. 100$:    unsave    <r3,r2,r1,r0>
  781.     return
  782.  
  783.     .endc
  784.  
  785. l$pcrl::print    #100$
  786.     return
  787.  
  788. 100$:    .byte    cr,lf,0,0
  789.  
  790.  
  791. ;    G E T S Y S
  792. ;
  793. ;    output:    r0    operating system
  794. ;
  795. ;    sy$11m    (1)    for rsx11m
  796. ;    sy$ias    (3)    for ias
  797. ;    sy$rsts    (4)    for rsts
  798. ;    sy$mpl    (6)    for m+
  799. ;    sy$rt    (7)    for rt11 ????
  800.  
  801.  
  802. getsys::mov    #7    ,r0        ; this is rt11 folks
  803.     return                ; bye
  804.  
  805.  
  806.     .sbttl    misc routines
  807.  
  808. iswild::mov    @r5    ,r0
  809. 10$:    tstb    @r0
  810.     beq    100$
  811.     cmpb    @r0    ,#'%
  812.     beq    90$
  813.     cmpb    (r0)+    ,#'*
  814.     bne    10$
  815. 90$:    mov    #1    ,r0
  816.     return
  817. 100$:    clr    r0
  818.     return
  819.  
  820.  
  821. ;    E X I T
  822. ;
  823. ;    exit to kmon
  824.  
  825.     .MCALL    .EXIT    ,.HRESET,.CMKT    ,.TWAIT
  826.  
  827. exit::    .CMKT    #cancel,#0        ; /51/ Stop watchdogs please
  828.     call    finrt            ; /37/ clear lines out
  829.     clr    r0
  830.     .EXIT                ; should always work ok
  831.     halt                ; huh ?
  832.  
  833.  
  834.     .MCALL    .TWAIT            ; mark time request
  835.  
  836.  
  837. suspen::save    <r1>            ; save temps
  838.     mov    @r5    ,r1        ; sleep time in seconds
  839.     beq    10$            ; nothing, must be fractional
  840.     mul    #60.    ,r1        ; sixty clock ticks in a second
  841.     clr    r0            ; low order part
  842.     br    20$            ; ignore the fractional part
  843. 10$:    mov    2(r5)    ,r0        ; sleep < 1 second
  844. 20$:    add    r1    ,r0        ; total time to sleep
  845.     mov    r0    ,-(sp)        ; setup the timeout block
  846.     clr    -(sp)            ; two words please
  847.     mov    sp    ,r1        ; point to it
  848.     .TWAIT    #rtwork,r1        ; suspend ourself for a while
  849.     bcs    30$            ; it worked ok
  850.     clr    r0            ; return success
  851.     br    100$            ; bye
  852. 30$:    movb    @#errbyt,r0        ; it failed, map the error into
  853.     asl    r0            ; a global error number
  854.     mov    twaerr(r0),r0        ; simple
  855. 100$:    cmp    (sp)+    ,(sp)+        ; pop time buffer and exit
  856.     unsave    <r1>            ; pop registers
  857.     return                ; bye
  858.  
  859.  
  860.  
  861.  
  862.     .sbttl    Log out and Set control C
  863.  
  864.  
  865. logout::tst    tsxsav            ; /45/ Does this make sense?
  866.     beq    100$            ; /45/ Not really
  867.     mov    #510    ,r0        ; /45/ Address of chain command
  868.     mov    #4    ,(r0)+        ; /45/ Setup to log out on TSX+
  869.     movb    #'B&137    ,(r0)+        ; /45/ And insert BYE
  870.     movb    #'Y&137    ,(r0)+        ; /45/  ...
  871.     movb    #'E&137    ,(r0)+        ; /45/   ...
  872.     clrb    (r0)+            ; /45/ Make it .asciz please
  873.     bis    #4000    ,@#JSW        ; /45/ Pass to KMON
  874.     clr    r0            ; /45/ Must be zero
  875.     .EXIT                ; /45/ Try to logout on TSX+
  876. 100$:    clr    r0            ; /45/ Exit
  877.     return
  878.  
  879.  
  880.     .MCALL    .SCCA    ,.MRKT    ,.EXIT    ,.CMKT    ,.RCTRLO,.SPCPS    ,.TTINR
  881.  
  882.     .save                ; /51/ Save current PSECT
  883.     .psect    sccada    ,rw,d,lcl,rel,con;/51/ Get out of APR1 mapping?
  884. sccwork:.word    0,0,0,0            ; /51/ A work area for .SCCA
  885. ccflag:    .word    0            ; /51/ RT11's way of flagging ^C
  886. mkw:    .word    0,0,0,0            ; /51/ A Mark Time work area
  887. mktime:    .word    0,15.            ; /51/ Check for ^C every 15 ticks
  888. spcwork:.word    0,0            ; /51/ For the .SPCPS directive
  889. spcarg:    .word    ccexit,0,0        ; /51/ Where to alter flow to.
  890.     .restore            ; /51/ Pop old psect now.
  891.     .save                ; /51/ Save current PSECT
  892.     .psect    sccain    ,ro,i,lcl,rel,con;/51/ Perhaps get this out of APR1
  893.     .enabl    lsb            ; /51/ mapping for XM?
  894.  
  895.  
  896. setcc::    clr    ccflag            ; /51/ No control C's as of yet
  897.     .CMKT    #mkw,#40        ; /51/ Clear previous Mark Time.
  898.     .SCCA    #sccwork,#ccflag    ; /51/ Set the address for flag word
  899.     .MRKT    #mkw,#mktime,#ccast,#40 ; /51/ Schedule a checkup for ^C
  900.     return                ; /51/ Exit
  901.  
  902. ccast:    tst    ccflag            ; /51/ Was there a Control C typed?
  903.     beq    100$            ; /51/ No, just reschedule
  904.     clr    ccflag            ; /51/ Clear the flag
  905.     .TTINR                ; /51/ In case control C's sitting
  906.     .TTINR                ; /51/ around in the input buffer.
  907.     .RCTRLO                ; /51/ Insure output enabled
  908.     inc    cccnt            ; /51/ Bump the global ^C count
  909.     cmp    cccnt    ,#CC$MAX    ; /51/ Exit?
  910.     blos    100$            ; /51/ No
  911.     call    finrt            ; /51/ Yes, get set to exit
  912.     .SPCPS    #spcwork,#spcarg    ; /51/ Get RT11 to jump to .EXIT
  913.     bcc    110$            ; /51/ Success
  914. 10$:    clr    r0            ; /51/ Normal .EXIT
  915.     .EXIT                ; /51/ Bye
  916. 100$:    .MRKT    #mkw,#mktime,#ccast,#40 ; /51/ Start a timer to watch
  917. 110$:    return                ; /51/ And exit
  918.  
  919. ccexit:    .EXIT                ; /51/ Bye
  920.  
  921.     .dsabl    lsb            ; /51/
  922.     .restore
  923.  
  924.  
  925.     .sbttl    Dummy EPTS for RSTS/RSX compatibility
  926.  
  927.  
  928. putcdt::
  929. getcdt::
  930. tlog::
  931. tmsdia::
  932. getuic::
  933. quochk::
  934. qspool::
  935. noecho::
  936. echo::
  937. chkpar::
  938. fixwil::
  939. putatr::
  940. runjob::clr    r0
  941. getprv::
  942. drpprv::
  943. throtl::return
  944.  
  945.  
  946.  
  947.  
  948. binfil::clr    r0
  949.     calls    chkext    ,<@r5>
  950.     return
  951.  
  952.  
  953. getatr::
  954. detach::
  955. systat::
  956. login::
  957. sercmd::mov    #er$iop    ,r0
  958.     return
  959.  
  960. okuser::mov    (sp)+    ,@sp
  961.     return
  962.  
  963.  
  964. dskuse::mov    @r5    ,r0
  965.     clrb    @r0
  966.     return
  967.  
  968. second::clr    r0
  969.     clr    r1
  970.     return
  971.  
  972. getpro::clr    r0
  973.     return
  974.  
  975. getmcr::mov    @r5    ,r0
  976.     clrb    @r0
  977.     clr    r0
  978.     return
  979.  
  980.  
  981.  
  982.  
  983.     .sbttl    FETCH    Load a handler if not already resident (BG only)
  984.  
  985.  
  986.  
  987. ;    FETCH( rad50(devicename) )
  988. ;
  989. ;    Mostly rewritten Edit /51/
  990. ;
  991. ;    /51/ Hard error recovery
  992. ;    /51/ New buffer allocation scheme
  993. ;    /51/ Checks on .FETCH when running in Foreground
  994. ;
  995. ;    Example call:    CALLS FETCH,<#^RDZ0>
  996. ;            TST R0
  997. ;            BNE ERROR
  998.  
  999.  
  1000. fetch::    .SERR                ; Trap all errors please
  1001.     .DSTAT    #rtwork,r5        ; Get handler status
  1002.     bcs    70$            ; No such handler present
  1003.     movb    rtwork    ,devidx        ; Save device index
  1004.     tst    rtwork+4        ; Is this handler resident ?
  1005.     bne    50$            ; Yes
  1006.     tst    jobsts            ; No, we MUST be job zero to be in
  1007.     bne    55$            ; the background, else ERROR return.
  1008.     mov    fetptmax,-(sp)        ; Check for space to load it
  1009.     sub    @fetpt    ,@sp        ; Simple to do
  1010.     cmp    rtwork+2,(sp)+        ; Is there sufficient space ?
  1011.     bhi    60$            ; No, error and exit
  1012.     .FETCH    @fetpt    ,r5        ; Try hard to load the thing
  1013.     bcs    80$            ; No way, map the error code please
  1014.     mov    r0    ,@fetpt        ; update the free pointer and exit
  1015. 50$:    clr    r0            ; No errors
  1016.     br    100$            ; Exit
  1017.                     ;
  1018. 55$:    mov    #ER$FGF    ,r0        ; Can't fetch if running in FG
  1019.     br    100$            ; Exit
  1020. 60$:    mov    #ER$FET    ,r0        ; Return NO ROOM for the handler
  1021.     br    100$            ; and exit with error in R0.
  1022.                     ;
  1023. 70$:    mov    #DSTERR    ,-(sp)        ; Map a .dstat error
  1024.     br    90$            ; And do it
  1025. 80$:    mov    #FETERR    ,-(sp)        ; Map a .FETCH error
  1026. 90$:    movb    @#ERRBYT,r0        ; Get the error code
  1027.     bpl    95$            ; Normal error code here
  1028.     com    r0            ; Fatal error from .SERR
  1029.     mov    #FATERR    ,(sp)        ; Thus map to RT11 messages
  1030. 95$:    asl    r0            ; Word offsets
  1031.     add    (sp)+    ,r0        ; The actual address
  1032.     mov    @r0    ,r0        ; Get it and exit
  1033. 100$:    mov    r0    ,-(sp)        ; Save this
  1034.     .HERR                ; Reset executive error trapping
  1035.     mov    (sp)+    ,r0        ; Restore error codes
  1036.     return                ; Bye
  1037.  
  1038.  
  1039.  
  1040.  
  1041.     .sbttl    things to do eis instructions
  1042.  
  1043.  
  1044. $cbta::    jsr    pc    ,@$$cbta
  1045.     return
  1046.  
  1047.     .if ne    ,0
  1048.     .ift
  1049.  
  1050.     .psect
  1051.  
  1052. $mul::    mov    r0    ,-(sp)
  1053.     mov    r1    ,-(sp)
  1054.     mov    6(sp)    ,r0
  1055.     mov    10(sp)    ,r1
  1056.     mov    r0,-(sp)
  1057.     mov    #21,-(sp)
  1058.     clr    r0
  1059. 10$:    ror    r0
  1060.     ror    r1
  1061.     bcc    20$
  1062.     add    2(sp),r0
  1063. 20$:    dec    (sp)
  1064.     bgt    10$
  1065.     cmp    (sp)+    ,(sp)+
  1066.     mov    r1    ,10(sp)
  1067.     mov    (sp)+    ,r1
  1068.     mov    (sp)+    ,r0
  1069.     mov    (sp)    ,2(sp)
  1070.     tst    (sp)+
  1071.     return
  1072.     
  1073. $div::    mov    r0    ,-(sp)
  1074.     mov    r1    ,-(sp)
  1075.     mov    6(sp)    ,r0
  1076.     mov    10(sp)    ,r1
  1077.     mov    #20,-(sp)
  1078.     mov    r1,-(sp)
  1079.     clr    r1
  1080. e00040:    asl    r0
  1081.     rol    r1
  1082.     cmp    r1,(sp)
  1083.     bcs    e00054
  1084.     sub    (sp),r1
  1085.     inc    r0
  1086. e00054:    dec    2(sp)
  1087.     bgt    e00040
  1088.     cmp    (sp)+    ,(sp)+
  1089.     mov    r1    ,6(sp)
  1090.     mov    r0    ,10(sp)
  1091.     mov    (sp)+    ,r1
  1092.     mov    (sp)+    ,r0
  1093.     return
  1094.  
  1095.     .endc
  1096.  
  1097.     .sbttl    $CBTA    Conversion called by $CDDMG from RSX SYSLIB
  1098.  
  1099. ;    09-Jun-86  10:14:54 $CBTA moved to K11DSP.MAC for XM root cuts
  1100.  
  1101.     .GLOBL    $SAVRG        ;Global reference
  1102.     .GLOBL    $CBTA
  1103.  
  1104.  
  1105.     .GLOBL    $SAVRG
  1106. $SAVRG:    MOV    R4,-(SP)
  1107.     MOV    R3,-(SP)
  1108.     MOV    R5,-(SP)
  1109.     MOV    6(SP),R5
  1110.     CALL    @(SP)+
  1111.     MOV    (SP)+,R3
  1112.     MOV    (SP)+,R4
  1113.     MOV    (SP)+,R5
  1114.     RETURN
  1115.  
  1116.     .end
  1117.