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

  1.     .title    k11rms    rms i/o for KERMIT-11
  2.     .ident    /3.56.0/
  3.     .library    /LB:[1,1]RMSMAC.MLB/
  4.  
  5.  
  6. ;    Brian Nelson  30-Nov-83  09:53:49
  7. ;
  8. ;    Copyright (C) 1983   Change Software, Inc.
  9. ;
  10. ; Edited by:
  11. ; RBD01 - Bob Denny 03-Mar-84    See K11CMD for edit trails
  12. ;
  13. ;
  14. ;    *******************************************************
  15. ;    *  NOTES REGARDING DECnet (DAP) REMOTE FILE SUPPORT)  *
  16. ;    *******************************************************
  17. ;
  18. ; The code here contains some magic for DECnet (DAP) remote file
  19. ; access.  I have not been able to find documentation on the DAP
  20. ; support that is present in RMS-11 (V2).  My current understanding
  21. ; of this, through experimentation, is as follows:
  22. ;
  23. ;    1. $PARSE fails with RMS status ER$UIN when given a file
  24. ;       specification containing a node name, but seems to
  25. ;       merge the input string and defaults into the expanded
  26. ;       string buffer anyway.  It also sets the file specification
  27. ;       mask.  I have assumed that the ER$UIN error is encountered
  28. ;       in $PARSE after the merging of the default and input
  29. ;       filespec information, and reflects the "fact" that RMS-11
  30. ;       (V2) DOES NOT SUPPORT WILDCARDING ON REMOTE FILE ACCESS.
  31. ;
  32. ;    2. Therefore, lookup() has been modified to return the
  33. ;       expanded string if its second calling parameter (index)
  34. ;       is zero (1st call) and there is either a node name or a
  35. ;       quoted literal in the spec, no wildcards and the error
  36. ;       is ER$UIN.
  37. ;
  38. ;    3. fparse() has been modified to accept if the error is ER$UIN,
  39. ;       and if there are no wildcards and there is a node name present.
  40. ;       The FB$FID bit is cleared, however, so that the original
  41. ;       file spec string and the defaults will be used by $OPEN.
  42. ;
  43. ;    4. The "SY:" defaulting is not necessary, and in fact causes
  44. ;       remote accesses to fail on VMS systems, where "SY:" has
  45. ;       no conventional meaning.
  46. ;
  47. ;    5. The other routines which use $parse have been similarly
  48. ;       modified to use the expanded string once only.
  49. ;
  50. ;    6. Finally, the NAMCVT routine in K11M41 was changed to handle
  51. ;       quoted sections in strings and node names.  This was the
  52. ;       hardest part of the DAP adaptation.
  53. ;
  54. ; I have to believe that $parse and friends act this way because remote
  55. ; wildcarding got "left out" at the last minute because of scheduling
  56. ; problems in the RMS group.  The code I have added here should permit
  57. ; remote wildcarding when it is turned on by the RMS folks.
  58. ;
  59. ; Bob Denny    03-Mar-84
  60. ;
  61. ;
  62. ;
  63. ; Please note that RSTS rms11 requires a real default device. I thus
  64. ; have to put my origional default for SY: back in for RSTS only. We
  65. ; will determine this at tkb time by defining a global called FU$DEF
  66. ; to be <> 0 in K11E80.MAC  and = 0 in K11M41.MAC.
  67. ;
  68. ;
  69. ; Brian Nelson  16-Mar-84  17:34:19
  70. ;
  71. ; BDN 17-Feb-87  08:57:48  Re-do the allocation of record buffers so
  72. ;               can GBLDEF the size during TKB. This will
  73. ;               allow the I/D space Kermit to handle much
  74. ;               larger ascii records.
  75.  
  76.  
  77. ;    define macros and things we want for KERMIT-11
  78.  
  79.     .if ndf, k11inc
  80.     .ift
  81.  
  82.  
  83.     .if ndf, K11INC
  84.     .ift
  85.     .include    /IN:K11MAC.MAC/
  86.     .endc
  87.  
  88.     .endc
  89.     .iif ndf, k11inc, .error ; INCLUDE for IN:K11MAC.MAC failed
  90.  
  91.  
  92. ;    This is K11RMS.MAC,  the RMS11 version 2 i/o interface for
  93. ;    Kermit on RSTS version 8, RSX11M+ v2.1 and RSX11M v4.1. It
  94. ;    is,  without a doubt,  the worst part of Kermit due RMS11,
  95. ;    but it's strong points are  future uses and the RSX / RSTS
  96. ;    transportability.  An example of "future uses" is DECnet
  97. ;    remote file access (DAP) support now present.
  98. ;
  99. ;
  100. ;    open  ( %loc filename, %val channel_number ,%val type )
  101. ;    create( %loc filename, %val channel_number ,%val type )
  102. ;    getrec( %loc buffer  , %val channel_number ) { returns RSZ in R1}
  103. ;    putrec( %loc buffer  , %val record_size    ,%val channel_number )
  104. ;    close ( %val channel_number )
  105. ;    putc  ( %val char    , %val channel_number )
  106. ;    getc  ( %val channel_number )
  107.  
  108.  
  109.     cr    =    15
  110.     lf    =    12
  111.     ff    =    14
  112.     soh    =    1
  113. ;
  114. ; This isn't defined globally. (??)
  115. ;
  116.     nb$nod    =    400    ; Node in file or default string (FNB in NAM)
  117.  
  118.     .enabl    gbl
  119.  
  120.     .psect    $code    ,ro,i,lcl,rel,con
  121.     .psect    rmssup    ,rw,d,lcl,rel,con
  122.  
  123.  
  124.     .mcall    fabof$
  125.     .mcall    rabof$
  126.     .mcall    xabof$
  127.     .mcall    ifaof$
  128.  
  129.     fabof$    RMS$L
  130.     rabof$    RMS$L
  131.     xabof$    RMS$L
  132.     ifaof$    RMS$L
  133.  
  134.  
  135.     .mcall    fab$b    ,fab$e    ,rab$b    ,rab$e
  136.     .mcall    xab$b    ,xab$e
  137.     .mcall    nam$b    ,nam$e
  138.     .mcall    $initif    ,org$
  139.     .mcall    pool$b    ,pool$e    ,p$bdb    ,p$fab
  140.     .mcall    p$rabx    ,p$idx    ,p$buf
  141.  
  142.     .mcall    $compar    ,$fetch    ,$store    ,$rewin
  143.     .mcall    $close    ,$creat    ,$erase    ,$open
  144.     .mcall    $connec    ,$delet    ,$discon,$find
  145.     .mcall    $get    ,$put    ,$updat    ,$flush
  146.     .mcall    $read    ,$write    ,$off    ,$set
  147.     .mcall    $testbits
  148.  
  149.  
  150.     org$    SEQ,<CRE,DEL,GET,PUT>
  151.  
  152.     .psect    rmssup    ,rw,d,lcl,rel,con ; ORG$ macro needs .save/.restore
  153.  
  154.  
  155.     .if ne    ,0            ; Decide whether or not to use
  156.     .ift                ; dynamic space allocation by
  157.                     ; task extension or to use
  158. rmsbuf:    pool$b                ; static pools
  159.     p$rab    6            ; plenty of record streams
  160.     p$bdb    6            ; same goes for block buffers
  161.     p$fab    4            ; up to 3 fabs (needed for search)
  162.     p$buf    3072.            ; for 2 files and directory i/o
  163.     pool$e                ; end of static pool
  164.  
  165.     .iff                ; use task extension for space
  166.                     ; routine modifed from GSA example
  167.     .mcall    gsa$            ; from RMS v2.0 distribution.
  168.     gsa$    gsa            ; set our GSA address
  169.     .globl    gsa            ; it may be global
  170.  
  171.     .endc                ; to decide on pool allocation
  172.  
  173.     .psect    rmssup    ,rw,d,lcl,rel,con ; GSA$ macro needs .save/.restore
  174.  
  175.  
  176.  
  177.     .sbttl    rms file access blocks
  178.  
  179.     facc    =    fb$get ! fb$put
  180.  
  181. fab1:    fab$b
  182.     f$alq    0            ; initial allocation of 10 blocks
  183.     f$fac    facc            ; allowed i/o operations
  184.     f$fna    nam1            ; name of the file
  185.     f$fns    0            ; length of the filename
  186.     f$fop    fb$sup            ; supercede old versions
  187.     f$lch    lun1            ; channel number to use
  188.     f$org    fb$seq            ; seq
  189.     f$rat    fb$cr            ; implied carriage control
  190.     f$rfm    fb$var            ; variable length records
  191.     f$xab    datxb1            ; Date info
  192.     fab$e
  193. fab1en:
  194.  
  195. fab2:    fab$b
  196.     f$alq    0            ; initial allocation of 10 blocks
  197.     f$fac    facc            ; allowed i/o operations
  198.     f$fna    nam2            ; name of the file
  199.     f$fns    0            ; length of the filename
  200.     f$fop    fb$sup            ; supercede old versions
  201.     f$lch    lun2            ; channel number to use
  202.     f$org    fb$seq            ; seq
  203.     f$rat    fb$cr            ; implied carriage control
  204.     f$rfm    fb$var            ; variable length records
  205.     f$xab    datxb2            ; Date info
  206.     fab$e
  207. fab2en:
  208.  
  209.  
  210. fab3:    fab$b
  211.     f$alq    0            ; initial allocation of 10 blocks
  212.     f$fac    facc            ; allowed i/o operations
  213.     f$fna    nam3            ; name of the file
  214.     f$fns    0            ; length of the filename
  215.     f$fop    fb$sup            ; supercede old versions
  216.     f$lch    lun3            ; channel number to use
  217.     f$org    fb$seq            ; seq
  218.     f$rat    fb$cr            ; implied carriage control
  219.     f$rfm    fb$var            ; variable length records
  220.     f$xab    datxb3            ; Date info
  221.     fab$e
  222. fab3en:
  223.  
  224.  
  225. fab4:    fab$b
  226.     f$alq    0            ; initial allocation of 10 blocks
  227.     f$fac    facc            ; allowed i/o operations
  228.     f$fna    nam4            ; name of the file
  229.     f$fns    0            ; length of the filename
  230.     f$fop    fb$sup            ; supercede old versions
  231.     f$lch    lun4            ; channel number to use
  232.     f$org    fb$seq            ; seq
  233.     f$rat    fb$cr            ; implied carriage control
  234.     f$rfm    fb$var            ; variable length records
  235.     f$xab    datxb4            ; Date info
  236.     fab$e
  237.  
  238.     GLOBAL    <MAXSIZ>
  239.  
  240.  
  241.     .psect    rmssup    ,rw,d,lcl,rel,con
  242.  
  243. sydisk::.ascii    /SY:/
  244. sylen    ==    . - sydisk
  245.     .even
  246. sydska    ==    sydisk
  247. sydskl    ==    sylen
  248.  
  249. ;                                ;RBD01--
  250. ;    pointers to buffer and fabs
  251. ;
  252. ;    While none of this is really needed since all this info is
  253. ;    available in  the FAB and RAB,  I find it cleaner to do it
  254. ;    this way and thus avoid having to look at the  RMS control
  255. ;    structures.
  256.  
  257. fablst::.word    0    ,fab1    ,fab2    ,fab3    ,fab4
  258. namlst::.word    0    ,nam1    ,nam2    ,nam3    ,nam4
  259. namlen::.word    0    ,0    ,0    ,0    ,0
  260. rablst::.word    0    ,rab1    ,rab2    ,rab3    ,rab4
  261. buflst:    .word    ttbuf    ,buf1    ,buf2    ,buf3    ,buf4
  262. bufdef:    .word    ttbuf    ,buf1    ,buf2    ,buf3    ,buf4
  263. bufsiz:    .word    TTBSIZ    ,MAXSIZ    ,MAXSIZ    ,MAXSIZ    ,MAXSIZ
  264. bigbuf:    .word    bufx    ,bufx    ,bufx    ,bufx    ,bufx
  265. filtyp:    .word    TERMINAL,TEXT    ,TEXT    ,TEXT    ,TEXT
  266. bufp:    .word    0    ,0    ,0    ,0    ,0
  267. bufs:    .word    0    ,0    ,0    ,0    ,0
  268. mode:    .word    1    ,0    ,0    ,0    ,0
  269. blknum:    .word    0    ,0    ,0    ,0    ,0
  270. itsopen:.word    0    ,0    ,0    ,0    ,0
  271.  
  272.     FILSIZ    ==    110.
  273.     BINLSIZ    ==    30*4
  274.  
  275. defdir::.blkb    FILSIZ+2        ; default directory for send and rec
  276. srcnam::.blkb    FILSIZ+2        ; original send filespec
  277. filnam::.blkb    FILSIZ+2        ; output from directory lookup routine
  278. asname::.blkb    FILSIZ+2        ; for SEND file [as] file
  279. $cmdbu::.blkb    120
  280. $argbu::.blkb    120
  281. bintyp::.word    10$
  282. 10$:    .rept    BINLSIZE
  283.     .byte    0
  284.     .endr
  285. totp.r::.word    10$
  286. 10$:    .rept    34
  287.     .word    0,0
  288.     .endr
  289. totp.s::.word    10$
  290. 10$:    .rept    34
  291.     .word    0,0
  292.     .endr
  293.  
  294. ;    this sets the default for creating text files
  295.  
  296. df$rat::.word    fb$cr
  297. df$rfm::.word    fb$var
  298. en$siz::.word    0            ; for RT11 compatibilty
  299.  
  300. namln1    =    namlen+2
  301. namln2    =    namlen+4
  302. namln3    =    namlen+6
  303. namln4    =    namlen+10
  304.  
  305. nam1:    .rept    100
  306.     .byte    0
  307.     .endr
  308.  
  309. nam2:    .rept    100
  310.     .byte    0
  311.     .endr
  312.  
  313. nam3:    .rept    100
  314.     .byte    0
  315.     .endr
  316.  
  317. nam4:    .rept    100
  318.     .byte    0
  319.     .endr
  320.     .even
  321.  
  322.  
  323. packet::.blkb    MAXLNG+100        ; /51/ Moved.
  324.     .even
  325.  
  326. top:    .LIMIT
  327.  
  328.     TTBSIZ    =    40
  329. ttbuf:    .blkb    TTBSIZ+2
  330.  
  331. buf1:    .iif df, MAXSIZ, .blkb MAXSIZ+2    ; /56/ Dynamic or static setup?
  332. buf2:    .iif df, MAXSIZ, .blkb MAXSIZ+2    ; /56/ ...
  333. buf3:    .iif df, MAXSIZ, .blkb MAXSIZ+2    ; /56/ ....
  334. buf4:    .iif df, MAXSIZ, .blkb MAXSIZ+2    ; /56/ .....
  335.  
  336. bufx:    .blkb    1002            ; one large buffer to share
  337.  
  338.  
  339. lun1    =    1
  340. lun2    =    2
  341. lun3    =    3
  342. lun4    =    4
  343. maxlun    =    lun4
  344.  
  345.  
  346.  
  347.     .sbttl    rms record access blocks
  348.  
  349. rab1:    rab$b                ; define record access block
  350.     r$fab    fab1            ; associate a fab with this rab
  351.     r$rac    rb$seq            ; access by keys
  352.     r$rbf    buf1            ; where to return the data
  353.     r$ubf    buf1            ; where to return the data
  354.     rab$e                ; end of record access block
  355.  
  356. rab2:    rab$b                ; define record access block
  357.     r$fab    fab2            ; associate a fab with this rab
  358.     r$rac    rb$seq            ; access by keys
  359.     r$rbf    buf2            ; where to return the data
  360.     r$ubf    buf2            ; where to return the data
  361.     rab$e                ; end of record access block
  362.  
  363. rab3:    rab$b                ; define record access block
  364.     r$fab    fab3            ; associate a fab with this rab
  365.     r$rac    rb$seq            ; access by keys
  366.     r$rbf    buf3            ; where to return the data
  367.     r$ubf    buf3            ; where to return the data
  368.     rab$e                ; end of record access block
  369.  
  370. rab4:    rab$b                ; define record access block
  371.     r$fab    fab4            ; associate a fab with this rab
  372.     r$rac    rb$seq            ; access by keys
  373.     r$rbf    buf4            ; where to return the data
  374.     r$ubf    buf4            ; where to return the data
  375.     rab$e                ; end of record access block
  376.  
  377.  
  378.  
  379. proxab:    xab$b    XB$PRO            ; file protection xab
  380.     x$nxt    0            ; no more links
  381.     x$pro    60.            ; normal protection of <60>
  382.     xab$e                ; end of file protection xab
  383.  
  384. datxb1:    xab$b    XB$DAT
  385.     x$nxt    0
  386.     xab$e
  387. datxb2:    xab$b    XB$DAT
  388.     x$nxt    0
  389.     xab$e
  390. datxb3:    xab$b    XB$DAT
  391.     x$nxt    0
  392.     xab$e
  393. datxb4:    xab$b    XB$DAT
  394.     x$nxt    0
  395.     xab$e
  396.  
  397.     .psect    $code
  398.  
  399.  
  400.     .sbttl    Set up SST table to catch RMSRES missing
  401.  
  402.     .mcall    SVTK$S,EXST$S,EXTK$S    ; This code added /53/
  403.     .mcall    GTSK$S
  404.  
  405. ;    Dynamic record buffer allocation and dynamic recall buffer
  406. ;    allocation added /56/
  407.  
  408.  
  409.     .save                ; Save current PSECT
  410.     .psect    RMSSUP    ,D        ; Switch to a data psect
  411.     .even                ; Insure this
  412. tbl:    .word    0,0,norms        ; Missing RMS gives a BPT trap
  413. nolib:    .byte    CR,LF
  414.     .ascii    /Probable cause: Either RMSRES or an RMS satellite/<CR><LF>
  415.     .asciz    /resident library is not installed on this system./<CR><LF>
  416.     .even
  417.     .restore            ; Pop old psect
  418.     .enabl    lsb
  419.  
  420.  
  421. Rmsini::mov    #MAXSIZ    ,r3        ; Allocate record buffers
  422.     mov    r3    ,O$MRS+fab1    ; Since we are allocating
  423.     mov    r3    ,O$MRS+fab2    ; the RMS record buffers at
  424.     mov    r3    ,O$MRS+fab3    ; run time we will can't
  425.     mov    r3    ,O$MRS+fab4    ; fill these fields in with
  426.     mov    r3    ,O$USZ+rab1    ; ...MAC
  427.     mov    r3    ,O$USZ+rab2    ; .... and so on
  428.     mov    r3    ,O$USZ+rab3    ; ....
  429.     mov    r3    ,O$USZ+rab4    ; ....
  430.                     ;
  431.     .If df    ,MAXSIZ            ; Dynamic or static today?
  432.     .Ift                ; Static
  433.                     ;
  434.     mov    #buf1    ,r2        ; So get the preallocated buffers
  435.     mov    top+2    ,r4        ;
  436.     .Iff                ; Dynamic allocation
  437.                     ;
  438.     ash    #-<6-2>    ,r3        ; We need 4 buffers, in 64 byte
  439.     add    #2    ,r3        ; chuncks. Add a safety margin
  440.     EXTK$S    r3            ; Ask for the memory
  441.     bcs    110$            ; Oops, we will have to die.
  442.     mov    top+2    ,r2        ; The higest virtual address+2
  443.     add    #2    ,r2        ; filled in by TKB via .LIMIT
  444.     bic    #1    ,r2        ; Insure even
  445.                     ;
  446.     .Endc                ; .If DF, Maxsiz
  447.                     ;
  448.     mov    #4    ,r0        ; Number of fields to update
  449.     clr    r3            ; Offset into BUFDEF and BUFLST
  450. 10$:    mov    r2    ,bufdef+2(r3)    ; Insert a record buffer address
  451.     mov    r2    ,buflst+2(r3)    ; Ditto for here also
  452.     add    #2    ,r3        ; Next please
  453.     add    #MAXSIZ+2,r2        ; Point to the next buffer
  454.     sob    r0    ,10$        ; And go do another
  455.     .If ndf    ,MAXSIZ            ; Setup pointer for command line
  456.     mov    r2    ,r4        ; recall buffers if dynamic RMS
  457.     .Endc                ; buffer allocation was used
  458.                     ; Now for command line recall
  459.     mov    #LNCNT$    ,r1        ; buffers. The count is defined
  460.     cmp    r1    ,#LN$ALL    ; via a GBLDEF=LNCNT$:n by TKB.
  461.     bgt    120$            ; Ensure enough vector space. No, die
  462.     mov    #<LN$MAX+2>*LNCNT$,r3    ; Total byte count for recall buffers
  463.     ash    #-6    ,r3        ; In 64 byte chunks
  464.     add    #<LN$MAX+2>/100,r3    ; Fix for truncation
  465.     EXTK$S    r3            ; Ask for it
  466.     bcs    130$            ; No room, die (should never happen)
  467.     mov    r1    ,lastcnt    ; Save the number of recall buffers
  468.     mov    #lastli    ,r2        ; The pointer array
  469. 40$:    mov    r4    ,(r2)+        ; Insert the buffer address
  470.     clrb    @r4            ; Insure the buffer is zapped
  471.     add    #LN$MAX+2,r4        ; Get to the next one
  472.     sob    r1    ,40$        ; And loop
  473.                     ;
  474.                     ; Finally, our original purpose.
  475.     SVTK$S    #tbl,#3            ; Only want TBIT traps
  476.     return                ; Exit
  477.  
  478.  
  479. 110$:    Message    <Failure to allocate record buffers>,CR
  480.     br    200$
  481. 120$:    Message    <LN$ALL is less than LNCNT$>,CR
  482.     br    200$
  483. 130$:    Message    <Failure to allocate command recall buffers>,CR
  484.  
  485. 200$:    EXST$S    #EX$SEV            ; Die...
  486.  
  487.     .dsabl    lsb
  488.  
  489.  
  490.  
  491. Norms:    MESSAGE    <Breakpoint trap, >    ; A message
  492.     mov    (sp)    ,r1        ; Dump PC and PS
  493.     MESSAGE    < PC: >            ; A header
  494.     OCTOUT    R1            ; ...
  495.     mov    2(sp)    ,r1        ; PS
  496.     MESSAGE    <  PSW: >        ; ...
  497.     OCTOUT    r1            ; ...
  498.     cmp    (sp)    ,#140000    ; Perhaps RMSRES missing?
  499.     blo    100$            ; No
  500.     PRINT    #nolib            ; Dump the cause
  501. 100$:    EXST$S    #EX$SEV            ; Die
  502.  
  503.     Global    <LNCNT$>
  504.  
  505.  
  506.  
  507.  
  508.     .sbttl    create sequential file
  509.     .psect    $code
  510.     .even
  511.  
  512. ;    F C R E A T E    and   FOPEN
  513. ;
  514. ;    fcreate( %loc filename; %val channel_number, %val type ,%val mb_count)
  515. ;    fopen  ( %loc filename; %val channel_number, %val type ,%val mb_count)
  516. ;
  517. ;    input:    @r5    filename address
  518. ;        2(r5)    channel number
  519. ;        4(r5)    val 'binary' or 'text' or 0
  520. ;        6(r5)    RMS multiblock count for the stream
  521. ;
  522. ;    output:    r0    rms error code
  523. ;
  524. ;     Create a variable length sequential implied carriage control
  525. ;    disk file.  If 'type' is 'binary'  then use read/write access
  526. ;    to write  a fixed  512 byte image file. If  channel number is
  527. ;    zero (0),  then initialize  buffer single character  terminal
  528. ;    output.  It is always assumed that channel '0' implies writes
  529. ;    to the attached console terminal.
  530.  
  531.     .enabl    lsb
  532. open::    calls    fopen    ,<@r5,2(r5),4(r5),#0>
  533.     return
  534.  
  535. create::calls    fcreate    ,<@r5,2(r5),4(r5),#0>
  536.     return
  537.  
  538. append::calls    fapnd    ,<@r5,2(r5),4(r5),#0>
  539.     return
  540.  
  541.  
  542. fopen::    save    <r1,r2,r3>        ; save registers
  543.     call    drpprv            ; insure no privs are up now    +MJG
  544.     clr    -(sp)            ; flag for open not create
  545.     br    5$            ; and try to do it
  546.  
  547.  
  548. fapnd::    save    <r1,r2,r3>        ; save registers        +SSH
  549.     call    drpprv            ; insure no privs        +SSH
  550.     mov    #1,-(sp)        ; flag for open / append    +SSH
  551.     br    5$            ; and try to do it        +SSH
  552.  
  553.  
  554. fcreat::save    <r1,r2,r3>        ; save registers
  555.     call    drpprv            ; insure no privs are up now    +MJG
  556. tcreat:    mov    #-1    ,-(sp)        ; flag for create
  557.  
  558. 5$:    $initif                ; initialize rms i/o system if needed
  559.     mov    2(r5)    ,r0        ; get channel number please
  560.     bne    10$            ; not channel zero, do it normally
  561.  
  562.     mov    sp    ,itsopen+0    ; flag it as having been initted
  563.     mov    sp    ,mode+0        ; psuedo writing to the terminal
  564.     clr    bufp+0            ; initialize the terminal's buffer
  565.     br    120$            ; pointer and exit
  566.  
  567. 10$:    asl    r0            ; times 2
  568.     mov    r0    ,r2        ; save it please
  569.     mov    namlst(r2),r1        ; get address of name block
  570.     calls    fparse    ,<@r5,r1>    ; parse and fill in defaults
  571.     tst    r0            ; did the parse succeed ?
  572.     bne    120$            ; no, exit with RMS error in r0
  573.     strlen    r1            ; get the expanded filename length
  574.     mov    r0    ,namlen(r2)    ; and save the length
  575.     mov    r2    ,r0        ; get r0 back again please
  576.     mov    fablst(r0),r1        ; get the file access block
  577.     mov    @sp    ,r2        ; pass create/open/append flag       /SSH
  578.     call    settyp            ; setup the FAB now
  579.     mov    r0    ,r2        ; save the channel number*2
  580.     tst    @sp            ; create or open or append       /SSH
  581.     bmi    30$            ; if negative then create       /SSH
  582.  
  583.     $open    r1            ; try to open existing file       /SSH
  584.     tst    @sp            ; opening for append ?           +SSH
  585.     beq    28$            ; no, go setup for read           +SSH
  586.     mov    sp    ,mode(r2)    ; indicate open for writing       +SSH
  587.     clr    bufp(r2)        ; clear single char i/o pointer    +SSH
  588.     br    40$            ; continue with status check       +SSH
  589. 28$:                    ;                   +SSH
  590.     mov    #-1    ,bufp(r2)    ; init for buffer needing a read
  591.     clr    mode(r2)        ; no writing please
  592.     br    40$            ; check RMS status out now
  593.  
  594. 30$:    $creat    r1            ; try hard to create the file
  595.     mov    sp    ,mode(r2)    ; open for writing
  596.     clr    bufp(r2)        ; clear single character i/o pointer
  597.  
  598. 40$:    $fetch    r0,sts,r1        ; get status back out please
  599.     tst    r0            ; if status > 0 then status = 0
  600.     bmi    130$            ; error if less than zero       /SSH
  601.     mov    2(r5)    ,r0        ; connect access up now
  602.     asl    r0            ; flag also that we are open
  603.     mov    sp    ,itsopen(r0)    ; simple
  604.     asr    r0            ; restore r0 now
  605.     mov    6(r5)    ,r1        ; and the multiblock count also
  606.     mov    (sp)    ,r2        ; and the create/open/append opt   +SSH
  607.     call    rmscon            ; connect record stream up
  608.     tst    r0            ; if error > 0 then error = 0
  609.     bmi    120$            ; yep
  610.     clr    r0            ; error = 0
  611.  
  612. 120$:    tst    (sp)+            ; pop open/create flag
  613. 125$:    unsave    <r3,r2,r1>        ; pop registers we saved
  614.     return                ; and exit
  615.  
  616. 130$:    tst    (sp)+            ; if error on open for append       +SSH
  617.     ble    125$            ; no, return with error           +SSH
  618.     br    tcreat            ; yes, try creating the file       +SSH
  619.  
  620.     global    <drpprv>        ;                +MJG
  621.  
  622.     .dsabl    lsb
  623.  
  624.     .sbttl    setup things for open/create in the FAB
  625.  
  626.  
  627. ;    S E T T Y P
  628. ;
  629. ;    input:    r0    channel number times 2
  630. ;        r2    <> 0 implies create
  631. ;        r5    --> open/create parameter list
  632. ;
  633.     fbrw    =    fb$rea ! fb$wri
  634.  
  635. settyp::mov    fablst(r0),r1
  636.     clr    blknum(r0)        ; in case of read/write mode
  637.     mov    #MAXSIZ    ,bufsiz(r0)    ; default for the buffer size
  638.     mov    #text    ,filtyp(r0)    ; assume ascii text files for now
  639.     mov    bufdef(r0),buflst(r0)    ; set a default record buffer also
  640.     clr    bufs(r0)        ; clear single character i/o recsiz
  641.     $store    #proxab,XAB,r1        ; /59/ Get the protection out.
  642.     $store    namlen(r0),FNS,r1
  643.     $store    #fb$seq,ORG,r1        ; insure sequential by default
  644.     $store    df$rat ,RAT,r1        ; implied carriage control
  645.     $store    df$rfm ,RFM,r1        ; and also variable length records
  646.     $store    #fb$get,FAC,r1        ; insure readonly please
  647.     tst    fu$def            ; do we require a default device
  648.     beq    1$            ; no
  649.     $store    #sydisk,DNA,r1        ; yes, stuff the correct def dev in
  650.     $store    #sylen ,DNS,r1        ; and the length of it also please
  651. 1$:    tst    r2            ; if creating or appending the file /SSH
  652.     beq    10$            ; no                    /SSH
  653.     $store    #<fb$put>,FAC,r1     ; yes, get put access           /SSH
  654.     mov    at$pr0    ,proxab+O$PRO    ; /59/ Protection explicity set?
  655.     bne    10$            ; /59/ Yes
  656.     $store    #0,XAB,r1        ; /59/ No, remove the protection XAB
  657. 10$:    cmp    4(r5)    ,#binary    ; is this a binary file ?
  658.     bne    100$            ; no, just exit
  659.  
  660.     mov    #1000    ,bufsiz(r0)    ; yes, fix it up for that
  661.     mov    bigbuf(r0),buflst(r0)    ; setup a large i/o buffer please
  662.     mov    #binary    ,filtyp(r0)    ; please
  663.     $store    #0    ,RAT,r1        ; no cr/lf implied please
  664.     $store    #fb$fix    ,RFM,r1        ; fixed length also
  665.     $store    #fb$rea    ,FAC,r1        ; assume read only please
  666.     tst    r2            ; readonly ?
  667.     beq    30$            ; yes
  668.     $store    #fbrw    ,FAC,r1        ; read/write mode needed ?
  669. 30$:    save    <r2,r3>            ; zero out the big buffer
  670.     mov    buflst(r0),r2        ; get the buffer address
  671.     mov    #1000    ,r3        ; 1000 (8) bytes please
  672. 40$:    clrb    (r2)+            ; simple
  673.     sob    r3    ,40$        ; next please
  674.     unsave    <r3,r2>            ; pop registers we just used
  675.  
  676. 100$:    $store    bufsiz(r0),MRS,r1    ; stuff max recordsize in please
  677.     return
  678.  
  679.     global    <fu$def>
  680.     GLOBAL    <AT$PR0>        ; /59/ Protection mask
  681.  
  682.  
  683.  
  684.     .sbttl    close a file
  685.  
  686.  
  687. close::    save    <r1,r2,r3>        ; save registers we may have
  688.     mov    @r5    ,r0        ; get the lun
  689.     asl    r0            ; times 2
  690.     tst    itsopen(r0)        ; check for lun being open
  691.     beq    90$            ; no, skip all this then
  692.     clr    itsopen(r0)        ; not anymore please
  693.     call    flush            ; dump out any remaining buffer
  694.     mov    @r5    ,r0        ; then disconnect the access stream
  695.     beq    100$            ; terminal
  696.  
  697.     asl    r0            ; channel number times 2
  698.     tst    mode(r0)        ; writing to it today?
  699.     beq    10$            ; no
  700.     calls    atrfin    ,<@r5>        ; yes, perhaps do attribute things
  701. 10$:    mov    @r5    ,r0        ; then disconnect the access stream
  702.     call    rmsdis            ; by doing a $disconnect
  703.     mov    @r5    ,r1        ; get the FAB for the file open on
  704.     asl    r1            ; the passed channel
  705.     mov    fablst(r1),r1        ;
  706.     $close    r1            ; try hard to close the file
  707.     $fetch    r0,sts,r1        ; get status back out please
  708.     tst    r0            ; if status > 0 then status = 0
  709.     blt    100$            ; error if less than zero
  710. 90$:    clr    r0            ; make > 0 status eq 0
  711. 100$:    unsave    <r3,r2,r1>
  712.     return
  713.  
  714.  
  715. rewind::mov    @r5    ,r0
  716.     beq    100$
  717.     asl    r0
  718.     mov    rablst(r0),r0
  719.     $rewind    r0
  720. 100$:    clr    r0
  721.     return
  722.  
  723.  
  724.  
  725.     .sbttl    try to determine if a file needs binary xfer mode
  726.  
  727. ;    B I N F I L
  728. ;
  729. ;    input:    @r5    address of the filename
  730. ;        2(r5)    lun
  731. ;    output:    r0    < 0 then RMS error
  732. ;        r0    > 0 then the file is most likely binary
  733.  
  734.  
  735. binfil::save    <r1,r2,r3,r4>        ; save registers we may use
  736.     clr    r4            ; nothing is open as of yet
  737.     calls    chkext    ,<@r5>        ; check file based on filetype
  738.     tst    r0            ; assume a binary file ?
  739.     bne    100$            ; yep
  740.     mov    2(r5)    ,r2        ; get the lun
  741.     asl    r2            ; times 2
  742.     mov    fablst(r2),r2        ; get the fab address now
  743.     $fetch    r3,XAB,r2        ; save the xab link address
  744.     call    getuic            ; for RSTS, skip the protection XAB
  745.     swab    r0            ; if the user is not privledged
  746.     cmpb    r0    ,#1        ; since RMS uses the UU.LOK directive
  747.     bne    5$            ; which may be patched to fail.
  748.     $store    #proxab,XAB,r2        ; and stuff our own into it
  749. 5$:    calls    open    ,<@r5,2(r5),#binary>
  750.     tst    r0            ; did the open work
  751.     bmi    90$            ; no
  752.     mov    sp    ,r4        ; flag that it's open
  753.  
  754.     call    getsys            ; if this is RSTS then a protection
  755.     cmpb    r0    ,#sy$rsts    ; bit of 100 being set indicates an
  756.     bne    10$            ; executable file
  757.     mov    #proxab    ,r1        ; get the xab for the protection code
  758.     $testbit #100,PRO,r1        ; if set, then it's executable
  759.     bne    40$            ; assume it's binary
  760.  
  761. 10$:    $testbit #<fb$rel!fb$idx>,ORG,r2; indexed or relative file ?
  762.     bne    40$            ; yes, it must be sent as a binary file
  763.     $compare #fb$stm,RFM,r2        ; stream ascii file ?
  764.     beq    30$            ; yes, assume not binary then
  765.     $testbit #FB$FTN,RAT,r2        ; /47/ Please not for Fortran files
  766.     bne    30$            ; /47/ Ok
  767.     $testbit #fb$cr,RAT,r2        ; implied carriage control ?
  768.     bne    30$            ; yes, assume not 8 bit then
  769.     br    40$            ; anything else is binary please
  770.     
  771.  
  772. 30$:    clr    -(sp)            ; flag as most likely being ascii
  773.     br    50$            ; bye
  774. 40$:    mov    #1    ,-(sp)        ; flag as being binary and exit
  775. 50$:    tst    r4            ; ever opened up ?
  776.     beq    60$            ; no
  777.     calls    close    ,<2(r5)>    ; close up
  778. 60$:    mov    (sp)+    ,r0
  779. 90$:    $store    r3,XAB,r2        ; restore old xab links, if any
  780.  
  781. 100$:    unsave    <r4,r3,r2,r1>        ; bye
  782.     return
  783.  
  784.  
  785.     .sbttl    getatr    return attributes for a file already open
  786.  
  787.     .mcall    ifaof$            ; access the ifab for the fab
  788.     ifaof$    rms$l            ; get the ifab symbols defined
  789.  
  790.  
  791. getsiz::mov    @r5    ,r1        ; return error in r0, size in r1
  792.     asl    r1            ; lun times 2
  793.     mov    fablst(r1),r1        ; fab for this file
  794.     mov    <o$alq+0>(r1),r1    ; get the size please
  795.     clr    r0            ; no errors 
  796.     return                ; exit
  797.  
  798. getpro::mov    @r5    ,r0        ; size in r0
  799.     asl    r0            ; lun times 2
  800.     mov    fablst(r0),r0        ; fab for this file
  801.     mov    O$XAB(r0),r0        ; get the protection please
  802.     mov    O$PRO(r0),r0        ; ...
  803.     return                ; exit
  804.  
  805.  
  806.  
  807. ;    Getcdt    Return time/date of creation, system (ie, RMS vs RT) dep.
  808. ;
  809. ;    Passed:    2(r5)    Channel number file is open on
  810. ;    Return:    R0    Zero if failure (internal error) else address of
  811. ;            64 byte Smithsonian date format
  812.  
  813.  
  814. Getcdt::mov    @r5    ,r0        ; Channel
  815.     beq    100$            ; Oops
  816.     asl    r0            ; Word offsets
  817.     mov    FABLST(r0),r0        ; Get the fab
  818.     beq    100$            ; Impossible
  819.     mov    O$XAB(r0),r0        ; XAB address
  820.     beq    100$            ; Nothing
  821.     add    #O$CDT    ,r0        ; Point to 4word creation dat/tim
  822. 100$:    return                ; Exit
  823.  
  824. Putcdt::mov    @r5    ,r0        ; Channel
  825.     beq    100$            ; Oops
  826.     asl    r0            ; Word offsets
  827.     mov    FABLST(r0),r0        ; Get the fab
  828.     beq    100$            ; Impossible
  829.     mov    O$XAB(r0),r0        ; XAB address
  830.     beq    100$            ; Nothing
  831.     add    #O$CDT    ,r0        ; Point to 4word creation dat/tim
  832.     mov    2(r5)    ,r1        ; Data
  833.     mov    (r1)+    ,(r0)+        ; Copy it
  834.     mov    (r1)+    ,(r0)+        ; .Copy it
  835.     mov    (r1)+    ,(r0)+        ; ..Copy it
  836.     mov    (r1)+    ,(r0)+        ; ...Copy it
  837. 100$:    return                ; Exit
  838.  
  839.  
  840. getatr::save    <r1,r2>            ; save these please
  841.     mov    @r5    ,r1        ; the channel number please
  842.     asl    r1            ; times two please
  843.     mov    fablst(r1),r1        ; simple
  844.     mov    o$ifi(r1),r1        ; and now we are at the ifab
  845.     mov    2(r5)    ,r2        ; where to copy the attributes to
  846.     movb    f$ratt(r1),(r2)+    ; stuff the input record attributes
  847.     movb    f$forg(r1),(r2)+    ; also stuff the input file org in
  848.     mov    f$rsiz(r1),(r2)+    ; and the input record size please
  849.     mov    f$hvbn(r1),(r2)+    ; and the input eof markers
  850.     mov    f$lvbn(r1),(r2)+    ; like hi and low virtual block
  851.     mov    f$heof(r1),(r2)+    ; and the high and low eof block
  852.     mov    f$leof(r1),(r2)+    ; numbers also
  853.     mov    f$ffby(r1),(r2)+    ; and, at last, the first free byte
  854.     movb    f$hdsz(r1),(r2)+    ; VFC header size next
  855.     movb    f$bksz(r1),(r2)+    ; and largest bucket size
  856.     mov    f$mrs(r1) ,(r2)+    ; the maximum record size
  857.     mov    f$deq(r1) ,(r2)+    ; and the default extenstion size
  858.     mov    f$rtde(r1),(r2)+    ; and the run time extentsion size
  859. 100$:    unsave    <r2,r1>            ; all done
  860.     clr    r0            ; say it worked ok
  861.     return
  862.  
  863.  
  864.  
  865. putatr::save    <r1,r2>            ; save these please
  866.     mov    @r5    ,r1        ; the channel number please
  867.     asl    r1            ; times two please
  868.     mov    fablst(r1),r1        ; simple
  869.     mov    o$ifi(r1),r1        ; and now we are at the ifab
  870.     mov    2(r5)    ,r2        ; where to get the attributes from
  871.     movb    (r2)+    ,f$ratt(r1)    ; stuff the input record attributes
  872.     movb    (r2)+    ,f$forg(r1)    ; also stuff the input file org in
  873.     mov    (r2)+    ,f$rsiz(r1)    ; and the input record size please
  874.     mov    (r2)+    ,f$hvbn(r1)    ; and the input eof markers
  875.     mov    (r2)+    ,f$lvbn(r1)    ; like hi and low virtual block
  876.     mov    (r2)+    ,f$heof(r1)    ; and the high and low eof block
  877.     mov    (r2)+    ,f$leof(r1)    ; numbers also
  878.     mov    (r2)+    ,f$ffby(r1)    ; and, at last, the first free byte
  879.     movb    (r2)+    ,f$hdsz(r1)    ; VFC header size next
  880.     movb    (r2)+    ,f$bksz(r1)    ; and largest bucket size
  881.     mov    (r2)+    ,f$mrs(r1)     ; the maximum record size
  882.     mov    (r2)+    ,f$deq(r1)     ; and the default extenstion size
  883.     mov    (r2)+    ,f$rtde(r1)    ; and the run time extentsion size
  884. 100$:    unsave    <r2,r1>            ; all done
  885.     clr    r0            ; say it worked ok
  886.     return
  887.  
  888.  
  889.  
  890.  
  891.  
  892.     .sbttl    connect record access block to file access block
  893.  
  894.  
  895. ;    C O N N E C T
  896. ;
  897. ;    connect( %val channel_number )
  898. ;
  899. ;    input:    r0    channel number
  900. ;        r1    multiblock count
  901. ;        r2    create/open/append option flag            +SSH
  902. ;    output:    r0    rms sts
  903. ;
  904. ;    Connect a record access block to a file access block.
  905. ;    Called only from OPEN and CREATE
  906.  
  907.  
  908. rmscon:    mov    r1    ,-(sp)        ; the block count size
  909.     mov    r0    ,r1        ; get address of record access block
  910.     asl    r1            ; channel number times 2
  911.     mov    rablst(r1),r1        ; address of a rab to use
  912.     $store    (sp)+,MBC,r1        ; the block buffer count
  913.     $store    #0,ROP,r1        ; assume no processing options       +SSH
  914.     tst    r2            ; if appending to existing file       +SSH
  915.     ble    7$            ; no, leave options alone       +SSH
  916.     $store    #rb$eof,ROP,r1        ; yes, set position to EOF option  +SSH
  917. 7$:                    ;                   +SSH
  918.     $conne    r1            ; try hard to connect access up
  919.     $fetch    r0,sts,r1        ; get status back out please
  920.     tst    r0            ; if status > 0 then status = 0
  921.     blt    10$            ; error if less than zero
  922.     clr    r0            ; make > 0 status eq 0
  923. 10$:    return
  924.  
  925.  
  926.  
  927.  
  928.     .sbttl    disconnect record access block from file access block
  929.  
  930.  
  931. ;    R M S D I S
  932. ;
  933. ;    input:    r0    channel number
  934. ;        r0    error sts
  935. ;
  936.  
  937. rmsdis:    mov    r0    ,r1
  938.     asl    r1
  939.     mov    rablst(r1),r1
  940.     $discon    r1            ; disconnect access stream from file
  941.     $fetch    r0,sts,r1        ; get status back out please
  942.     tst    r0            ; if status > 0 then status = 0
  943.     blt    10$            ; error if less than zero
  944.     clr    r0            ; make > 0 status eq 0
  945. 10$:    return
  946.  
  947.  
  948.  
  949.     .sbttl    read a record from a sequential file
  950.  
  951.  
  952. ;    G E T R E C
  953. ;
  954. ;    getrec( %loc buffer, %val channel_number )
  955. ;
  956. ;    input:    @r5    address of user buffer, at least 80 bytes
  957. ;        2(r5)    channel number
  958. ;
  959. ;    output:    r0    rms sts
  960. ;        r1    record size
  961. ;
  962. ;    Read the next record from a disk file. Assumes that the
  963. ;    user  has supplied a buffer of 80 characters to  return
  964. ;    the record to.
  965.  
  966.  
  967. getrec::mov    2(r5)    ,r0        ; get the channel number
  968.     asl    r0            ; times 2 to index into table
  969.     mov    rablst(r0),r1        ; get the record access buffer
  970.     $store    #0  ,RSZ,r1
  971.     $store    @r5 ,UBF,r1        ; stuff a record buffer in
  972.     $store    bufsiz(r0),USZ,r1    ; and a maximum record size
  973.     cmp    filtyp(r0),#binary    ; a binary file today ?
  974.     bne    10$            ; no, use normal get$
  975.     clr    o$bkt+0(r1)        ; use sequential mode please
  976.     clr    o$bkt+2(r1)        ; both words are to have zero
  977.     $read    r1            ; get next virtual block please
  978.     br    20$            ; get error code out now
  979. 10$:    $get    r1            ; read a record now
  980. 20$:    $fetch    r0,STS,r1        ; get the return STATUS field
  981.     tst    r0            ; did it work ?
  982.     blt    100$            ; no
  983.     clr    r0            ; say no errors
  984.     $fetch    r1,RSZ,r1        ; get the record size now
  985. 100$:    return
  986.  
  987.     global    <o$bkt>
  988.  
  989.  
  990.     .sbttl    put a record to an rms sequential file
  991.  
  992.  
  993. ;    P U T R E C
  994. ;
  995. ;    putrec( %loc buffer, %val record_size, %val channel_number )
  996. ;
  997. ;    input:    @r5    address of user buffer
  998. ;        2(r5)    record size
  999. ;        4(r5)    channel number
  1000. ;
  1001. ;    output:    r0    rms sts
  1002. ;
  1003. ;    Write the next record to  a disk file.
  1004.  
  1005.  
  1006. putrec::mov    r1    ,-(sp)
  1007.     mov    4(r5)    ,r0        ; get the channel number
  1008.     bne    5$            ; if zero then assume TI:
  1009.     print    @r5    ,2(r5)        ; dump the buffer to ti: then
  1010.     br    100$            ; and exit
  1011. 5$:    asl    r0            ; times 2 to index into table
  1012.     mov    rablst(r0),r1        ; get the record access buffer
  1013.     $store    @r5  ,RBF,r1        ; stuff a record buffer in
  1014.     $store    2(r5),RSZ,r1        ; and a current record size
  1015.     cmp    filtyp(r0),#binary    ; image mode today ?
  1016.     bne    10$            ; no
  1017.     $store    #1000,RSZ,r1        ; yes, insure block write
  1018.     clr    o$bkt+0(r1)        ; yes, clear the VBN fields
  1019.     clr    o$bkt+2(r1)        ; yes, clear the VBN fields
  1020.     $write    r1            ; simple
  1021.     br    20$            ; get the status and exit
  1022. 10$:    $put    r1            ; write a record now           /SSH
  1023. 20$:    $fetch    r0,STS,r1        ; get the return STATUS field
  1024.     tst    r0            ; did it work ?
  1025.     blt    99$            ; no
  1026.     clr    r0            ; say no errors
  1027.     br    100$
  1028. 99$:    mov    r0,tmperr        ; store error code for debugging
  1029. 100$:    mov    (sp)+    ,r1
  1030.     return
  1031.  
  1032.  
  1033.     .sbttl    getc    get one character from an input file
  1034.  
  1035.  
  1036. ;    G E T C
  1037. ;
  1038. ;    getc(%val channel_number)
  1039. ;
  1040. ;    input:    @r5    channel_number
  1041. ;    output:    r0    rms error status
  1042. ;        r1    the character just read
  1043.  
  1044. getc::    mov    @r5    ,r0
  1045.     call    getcr0
  1046.     return
  1047.  
  1048.  
  1049. fgetcr::save    <r2,r3>            ; save temps
  1050.     mov    r0    ,r2        ; channel number please
  1051.     asl    r2            ; times 2
  1052.     cmp    bufp(r2),#-1        ; need to initialize the buffer?
  1053.     bne    10$            ; no
  1054.     calls    getrec    ,<buflst(r2),r0>; yes, load it please
  1055.     tst    r0            ; did the read work ?
  1056.     bne    100$            ; no, return rms error code
  1057.     clr    bufp(r2)        ; it worked. clear current pointer
  1058.     mov    r1    ,bufs(r2)    ; and save the record size
  1059.     br    30$            ; and goto common code
  1060.  
  1061. 10$:    cmp    bufp(r2),#-2        ; flag to return <cr> ?
  1062.     bne    20$            ; no
  1063.     movb    #cr    ,r1        ; yes, return it in r1
  1064.     mov    #-3    ,bufp(r2)    ; and setup for a <lf> nexttime
  1065.     clr    r0            ; no error
  1066.     br    100$            ; bye
  1067.  
  1068. 20$:    cmp    bufp(r2),#-3        ; flag to return a <lf> ?
  1069.     bne    30$            ; no
  1070.     movb    #lf    ,r1        ; yes, return <lf> in r1
  1071.     mov    #-1    ,bufp(r2)    ; flag buffer reload next time
  1072.     clr    r0            ; no error
  1073.     br    100$
  1074.  
  1075.  
  1076. 30$:    tst    bufs(r2)        ; anything left to get in record?
  1077.     bne    40$            ; yes
  1078.     mov    #-2    ,bufp(r2)    ; no, flag for a <cr> next
  1079.     cmp    filtyp(r2),#binary    ; a binary file today ?
  1080.     bne    35$            ; yes, need data as is please
  1081.     mov    #-1    ,bufp(r2)    ; yes, flag for a read next
  1082. 35$:    mov    r2    ,r0        ; channel number please
  1083.     asr    r0            ; NOT times two
  1084.     call    getcr0            ; call ourselves to do it
  1085.     br    100$            ; and exit
  1086.  
  1087. 40$:    mov    buflst(r2),r3        ; get the address of the buffer
  1088.     add    bufp(r2),r3        ; and point to the next character
  1089.     clr    r1            ; to be returned in r1
  1090.     bisb    @r3    ,r1        ; simple
  1091.     inc    bufp(r2)        ; buffer.pointer := succ(buffer.pointer)
  1092.     dec    bufs(r2)        ; amountleft := pred( amountleft )
  1093.     clr    r0            ; no errors please
  1094.  
  1095. 100$:    unsave    <r3,r2>
  1096.     return
  1097.  
  1098.  
  1099.  
  1100.     .sbttl    putc    put a single character to an rms file
  1101.  
  1102. ;    P U T C
  1103. ;
  1104. ;    input:    @r5    the character to put
  1105. ;        2(r5)    the channel number to use
  1106. ;
  1107. ;    Buffer single character i/o to internal disk buffer.
  1108. ;    Buffer is dumped if internal buffer is  full or, for
  1109. ;    FB$VAR records (default for TEXT), a carraige return
  1110. ;    is found. For FB$VAR with FB$CR format, all carraige
  1111. ;    returns  and line feeds are  flushed as  this record
  1112. ;    format will have them put back later.
  1113. ;    The local buffers are allocated in CREATE and OPEN.
  1114.  
  1115.  
  1116. putc::    save    <r1>            ; simply save r1 and call putcr0
  1117.     mov    2(r5)    ,r1        ; to do it. putcr0 will be somewhat
  1118.     clr    r0            ; faster to call directly due to the
  1119.     bisb    @r5    ,r0        ; overhead involved in setting up an
  1120.     call    putcr0            ; argument list.
  1121.     unsave    <r1>            ; pop saved r1 and exit
  1122.     return                ; bye
  1123.  
  1124.  
  1125. putcr0::save    <r1,r2,r3,r4>        ; save registers we use
  1126.     mov    r1    ,r2        ; channel number
  1127.     asl    r2            ; times 2 of course
  1128.     cmp    filtyp(r2),#binary    ; is this a binary file today ?
  1129.     beq    5$            ; yes, don't dump buffer on <cr>
  1130.     cmpb    r0    ,recdlm        ; /56/ end of line time today ?
  1131.     beq    10$            ; yes, dump the record out
  1132. 5$:    cmp    bufp(r2),bufsiz(r2)    ; is the buffer full ?
  1133.     blo    20$            ; no, store some more characters in it
  1134. 10$:    movb    r0    ,r3        ; yes, save the input character r0
  1135.     calls    putrec    ,<buflst(r2),bufp(r2),r1> ; yes, dump the buffer please
  1136.     clr    bufp(r2)        ; pointer := 0
  1137.     tst    r0            ; did it work ?
  1138.     bne    100$            ; no, die
  1139.     mov    buflst(r2),r4        ; it worked. zero the buffer now
  1140.     mov    bufsiz(r2),r0        ; get the buffer address and size
  1141. 15$:    clrb    (r4)+            ; for i := 1 to bufsiz
  1142.     sob    r0    ,15$        ;   do buffer[i] := chr(0)
  1143.     movb    r3    ,r0        ; ok, restore the old character
  1144.  
  1145. 20$:    cmp    filtyp(r2),#binary    ; once again, is this a binary file ?
  1146.     beq    30$            ; yes, ignore checks for <LF> and ^Z.
  1147.     cmp    filtyp(r2),#terminal    ; terminal file today ?
  1148.     beq    30$            ; yes, we want cr's and lf's
  1149.     cmpb    r0    ,#lf        ; we simply like to ignore line feeds
  1150.     beq    90$            ; bye
  1151.     cmpb    r0    ,#'Z&37        ; control Z ?
  1152.     beq    90$            ; yes, ignore the control Z's please
  1153.     cmpb    r0    ,#cr        ; carraige return today ?
  1154.     beq    90$            ; yes, ignore it
  1155. 30$:    mov    bufp(r2),r1        ; get the current buffer pointer
  1156.     add    buflst(r2),r1        ; and point to a new home for the
  1157.     movb    r0    ,@r1        ; the input character in r0
  1158.     inc    bufp(r2)        ; pointer := succ( pointer )
  1159.  
  1160. 90$:    clr    r0            ; no errors
  1161. 100$:    unsave    <r4,r3,r2,r1>
  1162.     return
  1163.  
  1164.     GLOBAL    <recdlm>        ; /56/
  1165.  
  1166.  
  1167.     .sbttl    flush
  1168.  
  1169.  
  1170. flush:    mov    @r5    ,r0        ; get the internal channel number
  1171.     asl    r0            ; times 2 for indexing
  1172.     tst    bufp(r0)        ; anything in the buffer
  1173.     beq    100$            ; no
  1174.     tst    mode(r0)        ; writing today ?
  1175.     beq    100$            ; no
  1176.     calls    putrec    ,<buflst(r0),bufp(r0),@r5> ; yes, dump it
  1177.     return
  1178. 100$:    clr    r0
  1179.     return
  1180.  
  1181.  
  1182.  
  1183.  
  1184.  
  1185.     .sbttl    lookup    do a filename lookup, wildcarding supported
  1186.     .enabl    gbl
  1187.  
  1188.  
  1189. ;    L O O K U P
  1190. ;
  1191. ;    input:    @r5    arg count    (DEC standard Fortran convention)
  1192. ;        2(r5)    address of input string
  1193. ;        @4(r5)    flag word for initializing with a $PARSE
  1194. ;        6(r5)    address of output string
  1195. ;
  1196. ;    output:    r0    RMS error code
  1197. ;
  1198. ;
  1199. ;    clr    index
  1200. ;10$:    calls    lookup    ,<#3,#inbuf,#index,#outbuf>
  1201. ;    tst    r0
  1202. ;    bne    100$
  1203. ;    do something
  1204. ;    br    10$
  1205.  
  1206.  
  1207.  
  1208.  
  1209.     .mcall    $parse    ,$search,$store    ,$fetch    ,$compare
  1210.     .mcall    fab$b    ,fab$e    ,nam$b    ,nam$e
  1211.     .mcall    $off    $testbits                ;RBD01
  1212.  
  1213.     .save
  1214.     .psect    rmssup    ,d
  1215.  
  1216.  
  1217.  
  1218. fab:    fab$b                ; argument fab
  1219.      f$nam    nam            ; link to nam        ;RBD01--
  1220.      f$lch    1            ; a dummy channel for the i/o op
  1221.     fab$e
  1222.  
  1223. nam:    nam$b                ; nam definition
  1224.      n$esa    expstr            ; exp str address
  1225.      n$ess    64.            ; exp str length
  1226.      n$rsa    resstr            ; res str address
  1227.      n$rss    64.            ; res str length
  1228.     nam$e
  1229.  
  1230. expstr:    .blkb    64.            ; context must be preserved here
  1231. resstr:    .blkb    64.            ; a temp place for the result
  1232.  
  1233.     .restore
  1234.  
  1235.  
  1236.     .sbttl    the real work of lookup
  1237.  
  1238.     .psect    $pdata
  1239.                     ; Make this <> 0 if you can't do CALFIP
  1240. fu$dir::.word    0            ; style wildcarding on your non-standard
  1241.                     ; RSTS system.  Could cause side effects
  1242.                     ; with remote decnet nodes.
  1243.     .psect    $code
  1244.  
  1245. lookup::tst    rsx32            ; /56/ Ancient RSX today?
  1246.     beq    4$            ; /56/ No
  1247.     mov    #ER$NMF    ,r0        ; /56/ Yes, preset No More Files
  1248.     tst    @4(r5)            ; /56/ Second call?
  1249.     bne    3$            ; /56/ Yes, die
  1250.     STRCPY    6(r5)    ,2(r5)        ; /56/ No just return the passed string
  1251.     inc    @4(r5)            ; /56/ Note that we have been here
  1252.     clr    r0            ; /56/ No errors
  1253. 3$:    return                ; /56/ Exit
  1254.                     ;
  1255. 4$:    save    <r1,r2,r3,r4,r5>    ; Save these please
  1256.     mov    #fab    ,r1        ; map the target fab    ;RBD01--
  1257.     tst    fu$def            ; do we really need a default device?
  1258.     beq    5$            ; no
  1259.     $store    #sydisk,DNA,r1        ; yes, please stuff the def device name
  1260.     $store    #sylen ,DNS,r1        ; and the length of it also please
  1261. 5$:    strlen    #defdir            ; anything in the Kermit default dir?
  1262.     tst    r0            ; if <> then use it
  1263.     beq    10$            ; nothing there to use. Let system do it
  1264.     $store    #defdir    ,DNA,r1        ; something was there, stuff it in
  1265.     $store    r0    ,DNS,r1        ; and the length of the default
  1266. 10$:    mov    r1    ,r0        ; save it for later
  1267.     mov    #nam    ,r3        ; map the target nam
  1268.     tst    @4(r5)            ; first time thru needs a parse
  1269.     bne    40$            ; not the first time
  1270.  
  1271.     clrb    expstr            ; clear the expanded name and
  1272.     clrb    resstr            ; the resultant string
  1273.     mov    2(r5)    ,r4        ; point to the filename passed
  1274.     mov    r4    ,r1        ; and save the pointer
  1275. 20$:    tstb    (r1)+            ; and get the length of the name
  1276.     bne    20$            ; for an .asciz string
  1277.     sub    r4    ,r1        ; compute the length of the string
  1278.     dec    r1            ; which is off by one
  1279.     $store    #lun.sr,lch,r0        ; channel number please
  1280.     $store    r1,fns,r0        ; stuff the filename length
  1281.     $store    r4,fna,r0        ; and the filename address
  1282.     $parse    r0            ; parse the strings
  1283.     $fetch    r4,sts,r0        ; get error codes
  1284.  
  1285.     cmp    #ER$UIN,r4        ; Maybe a remote file spec?    ;RBD01+
  1286.     bne    30$            ; (no)
  1287.     $testbits  #<nb$wve!nb$wty!nb$wna!nb$wdi>,fnb,r3    ; Anything wild?
  1288.     bne    90$            ; (wild remote files no good)
  1289.     $testbits  #nb$nod,fnb,r3    ; Remote file?
  1290.     beq    90$            ; (ER$UIN with no node???)
  1291.     $off    #nb$wch,fnb,r3        ; Make succeeding $search's act nice
  1292.     $fetch    r0,esl,r3        ; Pass back expanded string
  1293.     $fetch    r2,esa,r3        ;  and skip the $search.
  1294.     br    70$                               ;RBD01-
  1295.  
  1296. 30$:    tst    r4            ; < 0 ?
  1297.     bmi    90$            ; yes, error
  1298.  
  1299. ;    This added edit 2.12 by BDN for those RSTS systems that totally
  1300. ;    disallow directory lookups by modify the executive for non-priv
  1301. ;    users.
  1302.  
  1303. 40$:    tst    fu$dir            ; in case george w. @ purdue
  1304.     beq    50$            ; needs this due to a hacked up exec
  1305.     $testbits  #<nb$wve!nb$wty!nb$wna!nb$wdi>,fnb,r3    ; Anything wild?
  1306.     bne    50$            ; yes, let the $search go on
  1307.     tst    @4(r5)            ; if no wildcarding and we have
  1308.     beq    45$            ; already been here then return
  1309.     mov    #ER$NMF    ,r4        ; no more files and exit
  1310.     br    90$            ; bye
  1311. 45$:    $fetch    r0,esl,r3        ; no, skip the $search and get the
  1312.     $fetch    r2,esa,r3        ; expanded string from $parse
  1313.     br    70$            ; and copy it over now
  1314.  
  1315. ;    End of option tp skip lookups for non-wildcarded filenames.
  1316.  
  1317.  
  1318. 50$:    $search    r0            ; get a matching file
  1319.     $fetch    r4,sts,r0        ; get error codes
  1320.     ;                                   ;RBD01+
  1321.     ; The following shouldn't have been necessary, as I
  1322.     ; banged off the NB$WCH bit above. But ...
  1323.     ;
  1324.     cmp    r4,#ER$UIN        ; Remote file hacking?
  1325.     bne    60$            ; (no)
  1326.     mov    #ER$FNF,r4        ; Yes, no "more" files
  1327.     br    90$            ; and exit
  1328.  
  1329. 60$:    tst    r4            ; < 0 ?                   ;RBD01-
  1330.     bmi    90$            ; yes, error
  1331.     $fetch    r0,rsl,r3        ; get the string length
  1332.     $fetch    r2,rsa,r3        ; get the string address
  1333.  
  1334. 70$:    mov    6(r5)    ,r1        ; where to return the string
  1335. 80$:    movb    (r2)+    ,(r1)+        ; copy it over
  1336.     sob    r0    ,80$        ; for however the long it is
  1337.     clrb    @r1            ; insure .asciz please
  1338.     clr    r0            ; no errors
  1339.     inc    @4(r5)            ; say we have at least one file
  1340.     br    100$            ; and exit
  1341.  
  1342. 90$:    mov    r4    ,r0        ; error, return it please
  1343.     br    100$            ; exit
  1344.  
  1345. 100$:    unsave    <r5,r4,r3,r2,r1>
  1346.     return
  1347.  
  1348.  
  1349.  
  1350.     .save
  1351.     .psect    rendat    ,rw,d,lcl,con,lcl
  1352.  
  1353.     .mcall    $compare,$fetch    ,$parse    ,$search,$set    ,$store
  1354.     .mcall    fab$b    ,nam$b    ,$rename
  1355.  
  1356. ;    24-Jan-86  14:01:48 Rename, Delete and GMCR code moved to overlay
  1357.  
  1358.  
  1359. RNFAB1::FAB$B                ; Old file name
  1360.      F$NAM    RNNAM1            ; Link to RNNAM1           ;RBD01--
  1361.      F$LCH    1            ; Channel 1 (a dummy, filled in later)
  1362.     FAB$E
  1363.  
  1364. RNNAM1::NAM$B                ; NAM definition
  1365.     NAM$E
  1366.  
  1367.  
  1368. RNFAB2::FAB$B                ; New file name
  1369.      F$NAM    RNNAM2            ; Link to RNNAM2           ;RBD01--
  1370.      F$LCH    1            ; a dummy channel
  1371.     FAB$E
  1372.  
  1373. RNNAM2::NAM$B                ; NAM definition
  1374.     NAM$E
  1375.  
  1376.  
  1377.     .restore
  1378.  
  1379.  
  1380.  
  1381.     .sbttl    fparse    parse filename and fill in with defaults
  1382.  
  1383.     .mcall    $compar    ,$fetch    ,$off    ,$parse    ,$store
  1384.     .mcall    tlog$s
  1385.  
  1386. parfab    =    rnfab1
  1387. parnam    =    rnnam1
  1388.  
  1389.  
  1390. ;    F P A R S E
  1391. ;
  1392. ;    input:    @r5    input filename,     .asciz
  1393. ;        defdir    the default directory name string to use
  1394. ;
  1395. ;    output:    2(r5)    expanded filename, .asciz, maximum length 63 bytes
  1396. ;        r0    error codes
  1397.  
  1398.  
  1399. tlog::    save    <r1,r2,r3>        ; /46/ Save registers
  1400.     sub    #200    ,sp        ; /46/ Allocate a buffer
  1401.     mov    sp    ,r3        ; /46/ And a pointer to it please
  1402.     call    getsys            ; /46/ Is this RSTS/E ?
  1403.     cmpb    r0    ,#SY$RSTS    ; /46/ If so, don't try TLOG$S out
  1404.     beq    100$            ; /46/ Skip, must be RSTS/E
  1405.     strlen    (r5)            ; /46/ Get length of input string
  1406.     TLOG$S    #0,ln$mk1,#0,(r5),r0,r3,#77,#tlogda,#tlogda+2
  1407.     cmpb    @#$DSW,#IS.SUC        ; /46/ Did we get a translation?
  1408.     bne    100$            ; /46/ No, exit this
  1409.     mov    r3    ,r2        ; /46/ Setup to make it asciz
  1410.     add    tlogda    ,r3        ; /46/ Add the translated string length
  1411.     clrb    (r3)            ; /46/ in and insure it's .asciz
  1412.     strcpy    (r5)    ,r2        ; /46/ Copy new name over and exit
  1413. 100$:    add    #200    ,sp        ; /46/ Pop local buffer
  1414.     unsave    <r3,r2,r1>        ; /46/ Exit
  1415.     clr    r0            ; /46/ No errors
  1416.     return                ; /46/ Exit
  1417.  
  1418.     .save
  1419.     .psect    $PDATA
  1420. tlogda:    .word    0,0            ; /46/ Returned data
  1421. ln$mk1::.word    0
  1422.     .restore
  1423.  
  1424.  
  1425. Fparse::tst    rsx32            ; /56/ Old, old RSX?
  1426.     beq    1$            ; /56/ No
  1427.     STRCPY    2(r5)    ,@r5        ; /56/ Yes, just copy the thing over
  1428.     clr    r0            ; /56/ Success
  1429.     return                ; /56/ Quick exit
  1430. 1$:    save    <r1,r2,r3,r4>        ; /46/ save registers we may overwrite
  1431.     mov    @r5    ,r4        ; /46/ Assume input from source
  1432.     call    getsys            ; /46/ Is this RSTS/E ?
  1433.     cmpb    r0    ,#SY$RSTS    ; /46/ If so, don't try TLOG$S out
  1434.     beq    2$            ; /46/ Skip, must be RSTS/E
  1435.     mov    2(r5)    ,r3        ; /46/ Address of a buffer to use
  1436.     strlen    r4            ; /46/ Get length of input string
  1437.     TLOG$S    #0,ln$mk1,#0,r4,r0,r3,#77,#tlogda,#tlogda+2
  1438.     cmpb    @#$DSW,#IS.SUC        ; /46/ Did we get a translation?
  1439.     bne    2$            ; /46/ No, exit this
  1440.     mov    r3    ,r4        ; /46/ We did, set a new source address
  1441.     add    tlogda    ,r3        ; /46/ Add the translated string length
  1442.     clrb    (r3)            ; /46/ in and insure it's .asciz
  1443. 2$:    mov    #parfab    ,r1        ; point to the fab we use       ;RBD01--
  1444.     $store    #0,DNS,r1        ; /42/ PLEASE clear this OUT!
  1445.     tst    fu$def            ; do we need a defualt device string?
  1446.     beq    3$            ; no
  1447.     $store    #sydisk,DNA,r1        ; yes, please put it where we need it
  1448.     $store    #sylen ,DNS,r1        ;      also, the length also
  1449. 3$:    strlen    #defdir            ; get the default directory spec
  1450.     tst    r0            ; was anything there ?
  1451.     beq    4$            ; no
  1452.     $store    #defdir,DNA,r1        ; yes, stuff that in for the default
  1453.     $store    r0     ,DNS,r1        ; name string, and stuff the length.
  1454. 4$:    $store    #lun.sr,LCH,r1        ; a channel number to use for $PARSE
  1455.     $off    #fb$fid,FOP,r1        ; we want an implicit $SEARCH
  1456.     mov    #parnam    ,r2        ; also point to the NAME block
  1457.     sub    #100    ,sp        ; allocate result name string
  1458.     $store    sp  ,RSA,r2        ; set up the pointer to name string
  1459.     $store    #100,RSS,r2        ; and set the size of the string
  1460.     sub    #100    ,sp        ; allocate result expanded name string
  1461.     $store    sp  ,ESA,r2        ; set up the pointer to expanded name
  1462.     $store    #100,ESS,r2        ; and set the size of the string
  1463.     $store    #ER$FNM ,STS,r1        ; preset a bad filename error
  1464.     strlen    r4            ; /46/ get the length of the filename
  1465.     tst    r0            ; anything left at all ?
  1466.     beq    90$            ; no, fake a bad filename please
  1467.     $store    r0,FNS,r1        ; stuff the filename size in please
  1468.     $store    r4,FNA,r1        ; /46/ stuff the filename address
  1469.     $parse    r1            ; try to parse the filename now
  1470.  
  1471.     $compar    #ER$UIN,sts,r1        ; Maybe a remote file spec?    ;RBD01+
  1472.     bne    5$            ; (no)
  1473.     $testb    #<nb$wve!nb$wty!nb$wna!nb$wdi>,fnb,r2    ; Anything wild?
  1474.     bne    90$            ; (wild remote files no good)
  1475.     $testb    #nb$nod,fnb,r2    ; Remote file?
  1476.     beq    90$            ; (ER$UIN with no node???)
  1477.     $off    #nb$wch,fnb,r2        ; Make succeeding $search's act nice
  1478.     br    7$            ; Go ahead with it           ;RBD01-
  1479.  
  1480. 5$:    $compar    #0  ,STS,r1        ; did the parse of the name work ?
  1481.     blt    90$            ; no, exit and return STS in r0
  1482.  
  1483. 7$:    mov    2(r5)    ,r1        ; where we will copy the name to
  1484.     movb    o$esl(r2),r0        ; the length of the new name
  1485.     beq    30$            ; can't happen unless you fubar
  1486.     cmp    r0    ,#77        ; truncate names that are too long
  1487.     blos    10$            ; it's ok
  1488.     mov    #77    ,r0        ; too long, please set it to 63 (10)
  1489. 10$:    mov    o$esa(r2),r2        ; where the name is coming from
  1490. 20$:    movb    (r2)+    ,(r1)+        ; copy a byte at a time please
  1491.     sob    r0    ,20$        ; next please
  1492. 30$:    clrb    @r1            ; insure .asciz please
  1493.     clr    r0            ; no errors please
  1494.     br    100$            ; bye
  1495.  
  1496. 90$:    $fetch    r0,STS,r1        ; error from parse, return in r0
  1497. 100$:    add    #200    ,sp        ; pop local nameblock buffers
  1498. 110$:    unsave    <r4,r3,r2,r1>        ; /46/ pop registers
  1499.     return                ; bye
  1500.  
  1501.  
  1502.     global    <defdir>
  1503.     GLOBAL    <RSX32>            ; /56/
  1504.  
  1505.  
  1506. ;    F I X W I L D
  1507. ;
  1508. ;    FIXWILD will replace % with ? for RSTS/E
  1509. ;
  1510. ;    input:    @r5    Address of string to process
  1511.  
  1512.  
  1513. fixwil::nop                ; in case we want to patch to 207
  1514.     save    <r2>            ; save a register we use here
  1515.     calls    getsys            ; is this RSTS ?
  1516.     cmpb    r0    ,#sy$rsts    ;
  1517.     bne    100$            ; no
  1518.     mov    @r5    ,r2        ; get the string address
  1519. 10$:    tstb    @r2            ; done with the filename yet ?
  1520.     beq    100$            ; yes, exit
  1521.     cmpb    @r2    ,#'%        ; check for a % character
  1522.     bne    20$            ; no
  1523.     movb    #'?    ,@r2        ; yes, replace with question mark
  1524. 20$:    inc    r2            ; next please
  1525.     br    10$            ; back again
  1526. 100$:    unsave    <r2>            ; pop r2
  1527.     clr    r0            ; no errors
  1528.     return                ; bye
  1529.     
  1530.  
  1531.  
  1532. iswild::save    <r1,r2>            ; save a register we may use
  1533.     mov    #parfab,r2        ; get a fab to use for this
  1534.     tst    fu$def            ; do we need a defualt device string?
  1535.     beq    5$            ; no
  1536.     $store    #sydisk,DNA,r2        ; yes, please put it where we need it
  1537.     $store    #sylen ,DNS,r2        ;      also, the length also
  1538. 5$:    strlen    #defdir            ; get the default directory spec
  1539.     tst    r0            ; was anything there ?
  1540.     beq    10$            ; no
  1541.     $store    #defdir,DNA,r2        ; yes, stuff that in for the default
  1542.     $store    r0     ,DNS,r2        ; name string, and stuff the length.
  1543. 10$:    $store    @r5,FNA,r2        ; filename address
  1544.     strlen    @r5            ; length
  1545.     $store    r0,FNS,r2        ; into the FAB please
  1546.     $fetch    r1,NAM,r2        ; get NAM block address
  1547.     clr    O$ESA(r1)        ; no expanded string address
  1548.     clr    O$RSA(r1)        ; no resultant string address
  1549.     clrb    O$ESS(r1)        ; no length fields either
  1550.     clrb    O$RSS(r1)        ; no length fields either
  1551.     $parse    r2            ; parse the filename
  1552.     $fetch    r0,STS,r2        ; get the status
  1553.     bmi    90$            ; exit on error please
  1554.     $testbi #NB$WVE!NB$WTY!NB$WNA!NB$WDI,FNB,r1 ; any wildcarding today ?
  1555.     beq    90$            ; no
  1556.     mov    #1    ,r0        ; yes, return(true)
  1557.     br    100$            ; exit
  1558. 90$:    clr    r0
  1559. 100$:    unsave    <r2,r1>            ; pop reg and exit
  1560.     return                ; exit
  1561.  
  1562.  
  1563.  
  1564.  
  1565.  
  1566.  
  1567.  
  1568.  
  1569.     .sbttl    return current task size and return exec
  1570.  
  1571.     .mcall    gtsk$s    ,gtim$s
  1572.  
  1573.  
  1574.  
  1575. second::save    <r2,r3>            ; /43/ Get seconds past midnight
  1576.     sub    #40    ,sp        ; /43/ Used for reporting transfer
  1577.     mov    sp    ,r2        ; /43/ statistics
  1578.     gtim$s    r2            ; /43/ One should really get the time
  1579.     mov    g.timi(r2),r3        ; /43/ in the 64 bit klunk format to
  1580.     mul    #60.    ,r3        ; /43/ avoid 24 hour rollover, but
  1581.     add    g.tisc(r2),r3        ; /43/ I really think this is
  1582.     mov    g.tihr(r2),r0        ; /43/ sufficient
  1583.     clr    r1            ; /43/ multiply hour of day by 3600
  1584.     mul    #60.*60.,r0        ; /43/ which has to be 32 bits in
  1585.     add    r3    ,r1        ; /43/ size, then add in minutes*60
  1586.     adc    r0            ; /43/ + seconds.
  1587.     add    #40    ,sp        ; /43/ Pop buffer and exit
  1588.     unsave    <r3,r2>            ; /43/ Pop registers
  1589.     return                ; /43/ Bye
  1590.  
  1591. ;    G E T S Y S
  1592. ;
  1593. ;    output:    r0    operating system
  1594. ;
  1595. ;    sy$11m    (1)    for rsx11m
  1596. ;    sy$ias    (3)    for ias
  1597. ;    sy$rsts    (4)    for rsts
  1598. ;    sy$mpl    (6)    for m+
  1599. ;    sy$rt    (7)    for rt11 ????
  1600.  
  1601.  
  1602. getsys::sub    #40    ,sp        ; use the stack for a buffer
  1603.     mov    sp    ,r0        ; and point to it please
  1604.     gtsk$s    r0            ; simple
  1605.     mov    g.tssy(r0),r0        ; return exec
  1606.     add    #40    ,sp        ; pop buffer and exit
  1607.     return                ; bye
  1608.  
  1609.  
  1610.  
  1611.     .sbttl    gsa    get space for i/o buffers
  1612.  
  1613.  
  1614. ;    Modified from sample GSA from RMS v2 distribution
  1615. ;    by Brian Nelson  05-Jan-84  10:22:06
  1616. ;
  1617. ;
  1618. ;  Interface:
  1619. ;    Request space:
  1620. ;      R0 ->  RMS/user Pool list head (maintained by RL/CQB)
  1621. ;      R1 :=  Amount of space requested (bytes)
  1622. ;      R2 :=  0 (differentiates between request and release)
  1623. ;
  1624. ;    Release space:
  1625. ;      R0 ->  RMS Pool list head (maintained by RL/CQB)
  1626. ;      R1 :=  Amount of space to be released (bytes)
  1627. ;      R2 ->  Base address (for release)
  1628. ;
  1629. ;
  1630. ;  Returns:
  1631. ;    C-Bit "set"   if an error has occurred (failure)
  1632. ;    C-Bit "clear" if no error has occurred (success)
  1633. ;
  1634.  
  1635.  
  1636.     .Mcall    Extk$S
  1637.  
  1638.  
  1639.     .Sbttl    Control block definitions
  1640.  
  1641.     .Psect    GSA$$D,RW,D
  1642.  
  1643. ;
  1644. ; GSA internal data:
  1645. ;
  1646. ;   GSABAS - Base address for the next memory allocation.
  1647. ;            Initially set to zero, it will be assigned
  1648. ;            the first address outside of the task's
  1649. ;            current address limits.
  1650. ;   GSAMIN - Decimal value reflecting the minimum size
  1651. ;            (in bytes) to extend the task in order to
  1652. ;            provide space to the pool.
  1653. ;   GSAREQ - Requested pool block number.  If a request
  1654. ;            for the 'GSAMIN' fails, then the original
  1655. ;            allocation size will be attempted.  If that
  1656. ;            fails, then there is no more memory left.
  1657. ;
  1658.  
  1659. GSABAS::            ; GSA base address
  1660.     .Word    000000        ; (for next allocation)
  1661. GSAMIN::            ; Minimum allocation
  1662.     .Word    512./64.    ; (in 32-word blocks)
  1663. GSAREQ::            ; Size of this request
  1664.     .Word    000000        ; (if 'GSAMIN' extends fail)
  1665.  
  1666.  
  1667.  
  1668.     .Sbttl    GSA Initialization code
  1669.  
  1670.     .Psect    GSA$$I,RO,I
  1671.  
  1672.  
  1673.     .mcall    extk$s    ,gtsk$s
  1674.  
  1675. GSAINI:
  1676.     Mov    R0,-(SP)    ; R0-2 will be used to
  1677.     Mov    R1,-(SP)    ; communicate with $INIDM
  1678.     Mov    R2,-(SP)    ; NOTE: $INIDM uses EXTSK.
  1679.     mov    r0    ,-(sp)    ; save r0
  1680.     sub    #40    ,sp    ; check for 512 boundary
  1681.     mov    sp    ,r0    ; get the current task size and see
  1682.     gtsk$s    r0        ; if we are at a boundary. if so, then
  1683.     mov    g.tsts(r0),r0    ; extend a little bit to get INIDM to
  1684.     add    #40    ,sp    ; behave itself
  1685.     bic    #^c777    ,r0    ; strip all the high crap
  1686.     cmp    r0    ,#776    ; should we extend a little bit?
  1687.     blo    10$        ; no
  1688.     extk$s    #1        ; yes, get 64 more bytes please
  1689. 10$:    mov    (sp)+    ,r0    ; restore r0
  1690.  
  1691.     Call    $INIDM        ; Initialize dynamic memory
  1692.     Mov    R1,GSABAS    ; Setup the "free" address
  1693.     Mov    (SP)+,R2    ; Restore the registers
  1694.     Mov    (SP)+,R1    ;
  1695.     Mov    (SP)+,R0    ;
  1696.     Return            ; And return to GSA
  1697.  
  1698.  
  1699.  
  1700.     .Sbttl    GSA Mainline code
  1701.  
  1702.     .Psect    GSA$$M,RO,I
  1703.  
  1704. ;
  1705. ; GSA Mainline
  1706. ;
  1707. ;   Entry point is "GSA", with registers 0-2 loaded as
  1708. ;   described above.
  1709. ;
  1710.  
  1711. GSA::
  1712. gsax:
  1713.  
  1714. ;
  1715. ; First, determine if dynamic memory has been initialized.
  1716. ; GSABAS (initially set to zero) will be non-zero if $INIDM
  1717. ; has been called and the memory list initialized.  On RSX
  1718. ; based systems it is possible to install tasks with an
  1719. ; extension (/INCREMENT).  $INIDM will detect this and setup
  1720. ; the first memory entry in the pool list.
  1721. ;
  1722. ; A point to note: If the RSX task has been installed with
  1723. ; the non-checkpointable (/-CP) flag, then EXTKs will not
  1724. ; return success.  If it is necessary to install the task
  1725. ; non-checkpointable, then the task should be installed with
  1726. ; and increment value.
  1727. ;
  1728.  
  1729.     Tst    GSABAS        ; Dynamic memory initialized?
  1730.     Bne    10$        ; Yes if NE, proceed
  1731.     Call    GSAINI        ; Otherwise, initialize pool
  1732. 10$:    Tst    R1        ; Real memory?
  1733.     Bne    20$        ; Yes if NE, then process it
  1734.     Return            ; Otherwise return with success
  1735.  
  1736.  
  1737. 20$:    Tst    R2        ; Address specified? (release)
  1738.     Beq    30$        ; No if EQ, then it's a request
  1739.     Jmp    $RLCB        ; Otherwise it's a release; do it
  1740. 30$:    Mov    R0,-(SP)    ; save pool list head
  1741.     Mov    R1,-(SP)    ; save size of request
  1742.     Mov    R2,-(SP)    ; save entry flag
  1743.     Call    $RQCB        ; Try the allocation
  1744.     Bcc    70$        ; CC signifies success
  1745.     Mov    2(SP),R1    ; Obtain the request size
  1746.     Add    #63.,R1        ; Round the request
  1747.     Asr    R1        ; to a 32-word boundary
  1748.     Asr    R1        ; Then convert the value
  1749.     Asr    R1        ; to the number of
  1750.     Asr    R1        ; 32-word blocks.
  1751.     Asr    R1
  1752.     Asr    R1
  1753.     Mov    R1,GSAREQ    ; Save the real size
  1754.     Cmp    R1,GSAMIN    ; Smaller than minimum?
  1755.     Bhi    40$        ; No if HI, use it as is
  1756.     Mov    GSAMIN,R1    ; Otherwise use GSAMIN
  1757. 40$:    Extk$S    R1        ; Extend the task
  1758.     Bcc    60$        ; CC if successful
  1759.     Cmp    R1,GSAREQ    ; Is this request?
  1760.     Blos    50$        ; Yes if LOS, the end
  1761.     Mov    GSAREQ,R1    ; Otherwise try to use
  1762.     Br    40$        ; the actual request
  1763. 50$:    Sec            ; Mark failure
  1764.     Br    70$        ; And exit
  1765.  
  1766. 60$:    Mov    4(SP),R0    ; Setup the PLH
  1767.     Asl    R1        ; Convert the real
  1768.     Asl    R1        ; size to the actual
  1769.     Asl    R1        ; 16-bit size that
  1770.     Asl    R1        ; was allocated.
  1771.     Asl    R1        ; The virtual address
  1772.     Asl    R1        ; should be after the
  1773.     Mov    GSABAS,R2    ; task (which is now
  1774.     Add    R1,GSABAS    ; part of the task)
  1775.     Call    GSAX        ; Call ourself to release
  1776.     Mov    (SP)+,R2    ; Restore our registers
  1777.     Mov    (SP)+,R1    ; to the initial state
  1778.     Mov    (SP)+,R0    ; upon entry, and reenter
  1779.     Br    GSAX        ; as if it's a new request
  1780.  
  1781. 70$:    Inc    (SP)+        ; These won't alter the
  1782.     Bit    (SP)+,(SP)+    ; C-bit, so status remains
  1783.     Return            ; unchanged upon return
  1784.  
  1785.  
  1786.  
  1787.     .sbttl    Corrected version of $INIDM
  1788.  
  1789. ;     Re-do $INIDM to use the  actual task top address,  not
  1790. ;    that which was stored by TKB from the .LIMIT directive.
  1791. ;    This is required because we have already done a EXTK$S.
  1792. ;
  1793. ;    17-Feb-87  07:11:21  BDN edit 3.56
  1794.  
  1795.     .mcall    GPRT$    ,GTSK$    ,DIR$    ,GTSK$S
  1796.     .Save
  1797.     .psect    IMPURE    ,d
  1798.  
  1799. Limit:    .Limit
  1800. pdpb:    GPRT$    tbuf
  1801. tdpb:    GTSK$    tbuf
  1802.  
  1803. tbuf:    .blkw    20
  1804.  
  1805.     .Restore
  1806.  
  1807.     .Psect    PURE$I    ,RO,I,LCL,REL,CON
  1808.  
  1809. ;    Inidm
  1810. ;
  1811. ;    Input:    r0    Address of free code pool listhead
  1812. ;    Output:    r0    First address in task
  1813. ;        r1    Address following task
  1814. ;        r2    Size of core pool
  1815.  
  1816. $Inidm::DIR$    #tdpb            ; We already did an EXTK$S so
  1817.     mov    tbuf+G.TSTS,r2        ; want to use the CURRENT topmem
  1818.     add    #3    ,r2        ; Round up to next 4 byte boundary
  1819.     bic    #3    ,r2        ; ...
  1820.     mov    r2    ,@r0        ; Set base address of pool
  1821.     EXTK$S    #1            ; Ask for just a little bit more
  1822.     DIR$    #pdpb            ; Get partition parameters
  1823.     mov    $DSW    ,r0        ; Save starting address of partition
  1824.     DIR$    #tdpb            ; Get task parameters
  1825.     mov    r2    ,-(sp)        ; Save starting address
  1826.     clr    (r2)+            ; Clear out first word
  1827.     mov    tbuf+G.TSTS,(r2)    ; Set physical size of task
  1828.     sub    r0    ,(sp)        ; Compute apparent size of task
  1829.     mov    r0    ,r1        ; Copy base address
  1830.     add    (r2)    ,r1        ; Next address after task
  1831.     sub    (sp)+    ,(r2)        ; Set size of free pool
  1832.     mov    (r2)    ,r2        ; Get size
  1833.     return                ; And exit
  1834.  
  1835.     .end
  1836.