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

  1.     .title    KRTDIR    RT-11 directory services
  2.     .ident    "V03.63"
  3.  
  4. ; /63/    27-Sep-97  Billy Youdelman  V03.63
  5. ;
  6. ;    buffil back to root (KRTPAK), for speed and room now available
  7. ;    add support for SET WILDCARDS
  8.  
  9. ; /62/    27-Jul-93  Billy Youdelman  V03.62
  10. ;
  11. ;    reorganized and substantially sped up
  12. ;    added .csispc comma delimiter parsing
  13. ;    fixed wildcard "%" match to no longer match on blanks
  14. ;    add version testing to support RT-11 V4
  15. ;    moved buffil here, has to be if not in root for getcr0 @sdodir..
  16. ;    make hd$fir=:6 so badly initted disks don't crash DIR
  17.  
  18. ; /BBS/     1-Dec-91  Billy Youdelman  V03.61
  19. ;
  20. ;    this module has been extensively modified, please refer to it..
  21. ;    add TSX+ create time, date slug, prot status, summary lines, etc
  22. ;    corrected bugs in error handling
  23. ;    added d$cvtnum for file sizes/sums larger than 32767.
  24. ;    "DK" now uses defdir, not op system DK, needs fparse in krtrms
  25. ;    ascdat patched for RT-11 V5.5, now also used for cvtdat
  26. ;    add dirflg to control embedded blanks in file name
  27. ;    getnth used to reread until context=diridx, now context saves it
  28. ;    added summary only flag, for use with SPACE and REM SPACE
  29. ;    force USR to re-read dir segment, allowing one to swap floppies..
  30.  
  31. ;    17-Sep-86  13:23:00  Handle Labels stuffed in by VMS Exchange
  32. ;    18-Jun-84  16:33:01  Brian Nelson
  33. ;
  34. ;    Copyright 1984 Change Software, Inc
  35.  
  36.  
  37.     .include "IN:KRTMAC.MAC"
  38.     .iif ndf  KRTINC  .error    <; .include for IN:KRTMAC.MAC failed>
  39.  
  40. ; /62/    .PVAL bypassed for V4, also expanded to allow assembly under same
  41.  
  42.     .mcall    .CSISPC ,.DATE    ,.GTIM    ,.LOCK    ,.LOOKUP
  43.     .mcall    .READW    ,.PURGE    ,.RCTRLO,.UNLOCK
  44.  
  45.  
  46.     .macro    R0toR2    ptr        ; /62/ added..
  47.     .if nb ptr
  48.     mov    ptr    ,r0        ; load r0 if an arg is supplied
  49.     .endc
  50.     call    R0toR2            ; copy string in (r0) to (r2)
  51.     .endm    R0toR2
  52.  
  53.  
  54.     .sbttl    Data offsets
  55.  
  56.     SYSPTR    =    54        ; /62/ pointer to RMON base
  57.         BLKEY    =    256    ; /BBS/ RMON dir seg number in memory
  58.  
  59.     ; directory home block
  60.     HD$BLK    =    1        ; vbn of the home block
  61.     HD$FIR    =    6        ; /62/ first dir segment block number
  62.     HD$SYS    =    760        ; volume id (DECRT11, DECVMSEX)
  63.  
  64.     ; directory segment header
  65.     H$NEXT    =    2        ; next logical dir segment
  66.     H$EXT    =    6        ; number of extra bytes per entry
  67.  
  68.     ; current directory entry
  69.     F.STAT    =    0        ; status word
  70.     F.NAM1    =    2        ; first three rad50 chars of name
  71.     F.NAM2    =    4        ; last three rad50 chars of name
  72.     F.TYPE    =    6        ; all three rad50 chars of type
  73.     F.LEN    =    10        ; file size
  74.     F.TIME    =    12        ; /BBS/ TSX+ file creation time
  75.     F.DATE    =    14        ; creation date
  76.  
  77.     ; entry status word bits
  78.     PERM    =    2000        ; permanent file
  79.     ENDSEG    =    4000        ; end of a segment
  80.     PROT    =    100000        ; /BBS/ protected entry
  81.  
  82.  
  83.     .sbttl    Data definitions
  84.  
  85. ;    STAR    =    134745        ; RTEM (RSTS) .csispc for a "*"
  86.     STAR    =    132500        ; real RT-11 .csispc for a "*"
  87.  
  88.     .psect    rtdir    ,rw,d,gbl,rel,con
  89. csidev:    .word    0 ,0 ,0 ,0        ; /62/ rad50 dev name + 3 null words..
  90. dirsiz: .word    0            ; length of a file's dir entry
  91. dirbuf:    .blkw    1000            ; 2 block buffer for one dir segment
  92. dbsize    = .-dirbuf            ; /62/ need this to prevent overruns..
  93. dirptr: .word    0            ; server dirbfr read pointer
  94. endflg:    .word    0            ; /BBS/ end of server dir listing flag
  95. h.next: .word    0            ; link to next directory segment
  96. name1:    .blkb    56.            ; /62/ ascii'd csinam(s), null, .even
  97. name2:    .blkb    12            ; /62/ disk file name, for matching
  98. numblks:.word    0            ; /BBS/ total blocks of listed files
  99. numfree:.word    0            ; /BBS/ total blocks empty+tent files
  100.  
  101.     .psect    $rwdata    ,rw,d,lcl,rel,con
  102. L310$:    .word    0            ; /58/ searched string base address
  103. L311$:    .word    0            ; /58/ string width
  104. sluggy:    .blkw    41.            ; /62/ slug buffer, .csispc, etc, etc.
  105.  
  106.     .psect    $pdata            ; /BBS/ all new..
  107. defext:    .word    star ,0 ,0 ,0        ; /62/ input default extent is wild
  108. months:    .ascii "-ERR-Jan-Feb-Mar-Apr-May-Jun-Jul-Aug-Sep-Oct-Nov-Dec-" ; /BBS/
  109. nodate:    .asciz " No Date "        ; /BBS/
  110. blocks:    .asciz    " Block"        ; /62/ # of blocks for summary
  111. dcrlf:    .asciz    <cr><lf>        ; a new line
  112. files:    .asciz    " File"            ; /62/ tag line at end of dir list
  113. free:    .asciz    " Free block"        ; /62/ free space..
  114. plural:    .asciz    "s"            ; /63/ this allow easier translation..
  115. protspc:.asciz    "P  "            ; where the P in protect lives
  116. rt:    .asciz    "DECRT11"        ; /54/ home block disk id
  117. unpspc:    .ascii    " "            ; come here for three blanks
  118.  prospc:.asciz    "  "            ; or, come here for just two
  119. vms:    .asciz    "DECVMSEX"        ; /54/ from EXCHANGE under VMS4.x
  120.     .even
  121.  
  122.  
  123.     .psect    $code
  124.     .sbttl    Wildcarded lookup
  125.  
  126. ;    L O O K U P            ; /62/ merged getnth into this..
  127. ;
  128. ;     (r5)    = possibly wildcarded input file specification
  129. ;    2(r5)    = output file spec, name of file matching input spec
  130. ;    index    = count of files found, init to 0 before first call
  131. ;      r0    = if <>, error code
  132.  
  133. lookup::save    <r1,r2,r3>
  134.     tst    index            ; /62/ new call sequence today?
  135.     bgt    10$            ; /62/ no, already found a file
  136.     call    opndev            ; ya, get the disk opened up please
  137.     tst    r0            ; any errors?
  138.     bne    120$            ; /62/ yes, we will have to die then
  139. 10$:    mov    context    ,r3        ; /BBS/ recover where we were
  140.     bne    30$            ; /BBS/ dir is already in progress
  141.     call    gethom            ; read in the home block
  142.     tst    r0            ; did it work?
  143.     bne    120$            ; /62/ no, exit with the error please
  144.  
  145.     mov    #hd$fir    ,r1        ; /62/ the first directory segment
  146. 20$:    call    gethdr            ; read in a dir segment
  147.     tst    r0            ; did this work?
  148.     bne    120$            ; /62/ no, return mapped error code
  149.     mov    #dirbuf ,r3        ; point to the directory buffer
  150.     add    #5*2    ,r3        ; skip past the header information
  151.  
  152. 30$:    mov    #dirbuf    ,r0        ; /62/ top of the dir buffer
  153.     add    #dbsize    ,r0        ; /62/ end of the buffer
  154.     cmp    r3    ,r0        ; /62/ room for one more?
  155.     bhis    110$            ; /62/ no, so avoid a trap to 4 here!
  156.     bit    #endseg ,f.stat(r3)    ; end of this segment?
  157.     bne    100$            ; yes, try the next one please
  158.     bit    #perm    ,f.stat(r3)    ; /62/ is this a real file?
  159.     bne    40$            ; /62/ ya
  160.     add    f.len(r3),numfree    ; /62/ no, add to total free blocks
  161.     br    90$            ; /62/ next..
  162. 40$:    call    match            ; see if the file matches up
  163.     tst    r0            ; well?
  164.     beq    90$            ; no, try again please
  165.     inc    index            ; /62/ ya, bump caller's match count
  166.     add    f.len(r3) ,numblks    ; /62/ add size to total blocks
  167.     tst    summary            ; /62/ need to do any file data?
  168.     bne    90$            ; /62/ no
  169.     mov    2(r5)    ,r2        ; /62/ ya, pass buffer location
  170.     call    convert            ; and convert name to asciz
  171.     mov    r2    ,r0        ; copy to process embedded spaces
  172. 50$:    tstb    (r0)            ; end of the string yet?
  173.     beq    80$            ; yes
  174.     tst    dirflg            ; /BBS/ retain embedded blanks?
  175.     bne    60$            ; /BBS/ ya, this is for a dir display
  176.     cmpb    (r0)    ,#space        ; no, if it's a space
  177.     beq    70$            ; then ignore it
  178. 60$:    movb    (r0)    ,(r2)+        ; copy one byte
  179. 70$:    inc    r0            ; then point to the next char
  180.     br    50$            ; and go check it
  181. 80$:    clrb    (r2)            ; ensure returned string is .asciz
  182.     mov    f.date(r3),lokdate    ; /38/ save create date
  183.     mov    f.len(r3) ,loklen    ; /38/ save file size
  184.     mov    f.stat(r3),lokstat    ; /BBS/ file status word
  185.     mov    f.time(r3),loktime    ; /BBS/ TSX+ file create time
  186.     add    dirsiz    ,r3        ; /BBS/ next time, try next one
  187.     mov    r3    ,context    ; /BBS/ save where next one is..
  188.     clr    r0            ; success
  189.     br    130$
  190.  
  191. 90$:    add    dirsiz    ,r3        ; skip to the next entry please
  192.     br    30$            ; and check it
  193. 100$:    mov    h.next    ,r1        ; end of segment, check the next one
  194.     bne    20$            ; /62/ if one is there
  195. 110$:    mov    #er$nmf ,r0        ; /BBS/ no more files..
  196.  
  197. 120$:    save    <r0>            ; /63/ save the incoming error
  198.     .purge    #lun.sr            ; /62/ dump the device on any error
  199.     clr    lokdate            ; /62/ clear
  200.     clr    lokstat            ; /62/ these
  201.     clr    loktime            ; /62/ on
  202.     clr    loklen            ; /62/ failure..
  203.     clr    dirflg            ; /62/ done with this now
  204.     strcpy    2(r5)    ,(r5)        ; /62/ return input name causing error
  205.     unsave    <r0>            ; /63/ restore the error code now
  206. 130$:    unsave    <r3,r2,r1>
  207.     return
  208.  
  209.  
  210.     .sbttl    Replace "?" with "%" for RSTS/E users ; /BBS/ from K11RMS.MAC
  211.  
  212. ;    input:    (r5)    = address of string to process
  213.  
  214. fixwil::save    <r2>
  215.     mov    @r5    ,r2        ; get the string address
  216. 10$:    tstb    @r2            ; done with the file name yet?
  217.     beq    30$            ; yes, exit
  218.     cmpb    @r2    ,#'?        ; check for a "?" character
  219.     bne    20$            ; no
  220.     movb    #'%    ,@r2        ; yes, replace with a percent sign
  221. 20$:    inc    r2            ; next please
  222.     br    10$            ; back again
  223. 30$:    unsave    <r2>
  224.     clr    r0            ; no error
  225.     return
  226.  
  227.  
  228.     .sbttl    Display directory listing on terminal
  229.  
  230. ;     D O D I R            ; /62/ major rewrite using server code
  231. ;
  232. ;     (r5)    = wildcarded filespec
  233. ;      r0    = if <>, error code
  234.  
  235. dodir::    call    sdirini            ; init directory lookup and
  236.     tst    r0            ; pre-load output buffer
  237.     bne    40$            ; an error occurred
  238.     br    20$            ; enter loop writing..
  239.  
  240. 10$:    call    dirnex            ; look for a matching file
  241.     bcs    30$            ; done..
  242.     tst    endflg            ; about to type the summary lines?
  243.     beq    20$            ; no
  244.     .rctrlo                ; ya, ensure totals are visible
  245. 20$:    wrtall    dirbfr            ; dump matching file spec to terminal
  246.     br    10$            ; try for another match
  247.  
  248. 30$:    clr    r0            ; no error
  249. 40$:    return
  250.  
  251.  
  252.     .sbttl    Server directory    ; /62/ condensed a bit..
  253.  
  254. ;    S D I R I N I  -  Initialization
  255. ;    S D O D I R    -  Get next char
  256. ;
  257. ;    input:   (r5)    = wildcarded name
  258. ;    output:   r1    = next character in the directory listing
  259. ;          r0    = if <>, error code
  260. ;
  261. ;    SDODIR is called by the server to respond to a remote directory
  262. ;    command, returning one char at a time so BUFFIL can use it, via
  263. ;    the GETCR0 routine.  SDIRINI must be called first, to check for
  264. ;    a valid device and file spec, and to pre-load the date slug.
  265.  
  266. sdirini::copyz    (r5)    ,dirnam    ,#80.    ; /62/ copy name over, don't overwrite
  267.     clr    index            ; /62/ init to
  268.     calls    lookup    ,<dirnam,@r5>    ; /62/ open device and check file spec
  269.     tst    r0            ; /62/ well?
  270.     beq    10$            ; /62/ no error
  271.     cmp    r0    ,#er$nmf    ; /62/ no good, but
  272.     bne    40$            ; /62/ ignore no more files error
  273. 10$:    clr    index            ; /62/ reset match counter
  274.     mov    sp    ,dirflg        ; /62/ keep blanks in name
  275.     clr    endflg            ; clear all done looking flag
  276.     mov    dirbfr    ,r2        ; the output buffer
  277.     mov    r2    ,dirptr        ; reset its pointer
  278.     mov    #sluggy    ,r0        ; /62/ scratch buff
  279.     calls    ascdat    ,<r0,#-1>    ; /62/ get date into a buffer
  280.     cmpb    #space    ,(r0)        ; leading space in date?
  281.     beq    20$            ; ya, so skip adding one
  282.     movb    #space    ,(r2)+        ; no, so blank col. 1 ala RT-11
  283. 20$:    R0toR2                ; /62/ copy the date
  284.     tst    summary            ; doing a summary only?
  285.     beq    30$            ; /62/ nope
  286.     R0toR2    #dcrlf            ; /62/ ya, prefix with <cr><lf>
  287.     R0toR2    dirnam            ; /62/ display file spec for SPACE cmd
  288. 30$:    clr    r0            ; /62/ no error
  289. 40$:    return
  290.  
  291. sdodir::save    <r2,r3>
  292. 10$:    movb    @dirptr ,r1        ; get the next char please
  293.     beq    20$            ; /63/ nothing left, reload buffer
  294.     inc    dirptr            ; pointer++, something was there
  295.     clr    r0            ; no errors
  296.     br    40$
  297. 20$:    mov    dirbfr    ,dirptr        ; /63/ reset the pointer
  298.     clrb    @dirptr            ; init the buffer
  299.     call    dirnex            ; load next file's data into buffer
  300.     bcc    10$            ; /63/ back to get next char loop
  301. 30$:    mov    #er$eof ,r0        ; failure, return(EOF)
  302.     clr    r1            ; return no data also
  303. 40$:    unsave    <r3,r2>
  304.     return
  305.  
  306. dirnex:    mov    dirbfr    ,r2        ; pointer to buffer
  307.     mov    #sluggy    ,r3        ; /62/ local scratch buffer
  308.     tst    endflg            ; /BBS/ done the tally lines yet?
  309.     bne    50$            ; /BBS/ ya, time to bail out
  310.     calls    lookup    ,<dirnam,r3>    ; /62/ try to find a matching file
  311.     tst    r0            ; successful?
  312.     bne    30$            ; no
  313.     R0toR2    #dcrlf            ; /62/ ya, prefix with <cr><lf>
  314.     R0toR2    r3            ; /62/ copy file spec into buff
  315.     calls    d$cvtnum,<r3,loklen,#0>    ; /BBS/ file size
  316.     R0toR2    r3            ; /62/ append it please
  317.     bit    #prot    ,lokstat    ; /BBS/ protected file?
  318.     beq    10$            ; /BBS/ nope..
  319.     R0toR2    #protspc        ; /62/ ya, so flag it accordingly
  320.     br    20$            ; /BBS/ and continue
  321. 10$:    R0toR2    #unpspc            ; /62/ three spaces..
  322. 20$:    calls    ascdat    ,<r3,lokdate>    ; /62/ convert date to asciz
  323.     R0toR2    r3            ; /62/ append the date please
  324.     tst    tsxsav            ; /BBS/ if not TSX
  325.     beq    40$            ; /63/ skip the file time
  326.     R0toR2    #prospc            ; /62/ two blanks
  327.     calls    filtim    ,<r3,loktime>    ; /BBS/ make it displayable
  328.     R0toR2    r3            ; /62/ copy that into dir string
  329.     br    40$
  330.  
  331. 30$:    cmp    r0    ,#er$nmf    ; no more files error?
  332.     bne    60$            ; no
  333.     call    dirsum            ; /63/ ya, do summary lines now
  334. 40$:    clr    r0            ; success
  335.     br    70$
  336. 50$:    mov    #er$eof ,r0        ; failure, return(EOF)
  337. 60$:    sec                ; indicate there was some error
  338. 70$:    return
  339.  
  340. dirsum:    mov    sp    ,endflg        ; /63/ flag it's all over
  341.     R0toR2    #dcrlf            ; /62/ prefix with <cr><lf>
  342.     tst    summary            ; doing a SPACE summary only?
  343.     bne    10$            ; ya, skip the newline here
  344.     tst    index            ; anything listed?
  345.     bgt    10$            ; ya
  346.     R0toR2    #dcrlf            ; no, so blank a line ala RT-11
  347. 10$:    calls    d$cvtnum,<r3,index,#-1>    ; number of files listed
  348.     R0toR2    r3            ; copy to buffer
  349.     R0toR2    #files            ; " File"
  350.     dec    index            ; singular or plural?
  351.     beq    20$            ; singular
  352.     R0toR2    #plural            ; /63/ not 1, so make it plural
  353. 20$:    movb    #comma    ,(r2)+        ; ","
  354.     calls    d$cvtnum,<r3,numblks,#-1> ; total blocks
  355.     R0toR2    r3            ; append it please
  356.     R0toR2    #blocks            ; " Block"
  357.     dec    numblks            ; singular or plural?
  358.     beq    30$            ; just one
  359.     R0toR2    #plural            ; /63/ not 1, so make it plural
  360. 30$:    R0toR2    #dcrlf            ; <cr><lf>
  361.     calls    d$cvtnum,<r3,numfree,#-1> ; free blocks
  362.     R0toR2    r3            ; put ascii number in buffer
  363.     R0toR2    #free            ; " Free Block"
  364.     dec    numfree            ; singular or plural?
  365.     beq    40$            ; singular
  366.     R0toR2    #plural            ; /63/ not 1, so make it plural
  367. 40$:    R0toR2    #dcrlf            ; <cr><lf>
  368.     return
  369.  
  370.  
  371.     .sbttl    Copy (r0) to (r2)    ; /62/ replaces strcat here
  372.  
  373. R0toR2:    movb    (r0)+    ,(r2)+        ; copy a byte
  374.     bne    R0toR2            ; until hitting a null
  375.     dec    r2            ; leave r2 on the null
  376.     return
  377.  
  378.  
  379.     .sbttl    Open device, build name list to search directory
  380.  
  381. ;    O P N D E V
  382. ;
  383. ;    input:      (r5)    = file spec string
  384. ;    output:       r0    = if <>, error code
  385.  
  386. opndev:    calls    fparse    ,<(r5),#sluggy>    ; /62/ check for valid device
  387.     tst    r0            ; /BBS/ is it?
  388.     beq    10$            ; /BBS/ ya
  389.     return                ; /BBS/ no
  390.  
  391. 10$:    .purge    #lun.sr            ; /62/ dump possible old device
  392.     mov    #sluggy    ,r0        ; /62/ input string address
  393.     copyz    r0    ,dirnam        ; /62/ return cleaned up file spec
  394.     clr    context            ; /62/ init curr dir seg offset reg
  395.     clr    numblks            ; /62/ clear total blocks of above
  396.     clr    numfree            ; /62/ clear free space reg
  397.  
  398.     sub    #ln$max+2.,sp        ; /63/ .csispc input data buffer
  399.     mov    sp    ,r1        ; pointer to it
  400.     movb    #'=    ,(r1)+        ; /62/ fake an output file spec
  401. 20$:    movb    (r0)+    ,(r1)+        ; copy input string to the CSI buffer
  402.     bne    20$            ; until a null byte is found
  403.     mov    sp    ,r1        ; reset pointer (also saving sp)
  404.     .csispc #sluggy    ,#defext ,r1    ; /62/ try to parse the file spec(s)
  405.     mov    r1    ,sp        ; hose any switches, unsupported here
  406.     bcs    110$            ; oops
  407.     mov    sluggy+36,csidev    ; /62/ save a copy of device name only
  408.     calls    fetch    ,<csidev>    ; /62/ try to get the thing loaded
  409.     tst    r0            ; well?
  410.     bne    150$            ; exit with mapped error
  411.  
  412.     mov    #6    ,r1        ; /62/ do implicit "*." wildcarding
  413.     mov    #sluggy+40,r0        ; /62/ first input file name is here
  414. 30$:    tst    (r0)            ; /62/ does an input file name exist?
  415.     bne    40$            ; /62/ something was indeed there
  416. ; /63/    Following two lines are here if needed, but probably will never be..
  417. ;    tst    dowild            ; /63/ implicit wildcarding enabled?
  418. ;    beq    40$            ; /63/ not this time..
  419.     mov    #star    ,(r0)        ; /62/ nothing, convert to wildcard
  420. 40$:    add    #10    ,r0        ; /62/ bump pointer to next descriptor
  421.     sob    r1    ,30$        ; /62/ do six input file descriptors
  422.     clr    -(r0)            ; /62/ null terminate rad50 names
  423.  
  424.     mov    #name1    ,r0        ; /62/ init this buffer with nulls
  425.     mov    #56./2    ,r1        ; /62/ clearing 2 bytes at a time
  426. 50$:    clr    (r0)+            ; /62/ is somewhat faster than one
  427.     sob    r1    ,50$        ; /62/ by one..
  428.  
  429.     save    <r2>            ; /63/
  430.     mov    #name1    ,r1        ; /62/ top of ascii'd names buffer
  431.     mov    #sluggy+36,r2        ; /62/ offset to first input file spec
  432. 60$:    tst    (r2)+            ; /62/ ignore device name
  433.     beq    80$            ; /62/ nothing left, done
  434.     mov    #3    ,r0        ; /62/ loop 3 times
  435. 70$:    calls    rdtoa    ,<r1,(r2)+>    ; /62/ convert file name to ascii
  436.     add    #3    ,r1        ; /62/ increment pointer by 3 chars
  437.     sob    r0    ,70$        ; /62/ next please
  438.     br    60$            ; /62/ then try next file name
  439. 80$:    unsave    <r2>            ; /63/
  440.  
  441.     .lock                ; /BBS/ lock the USR in memory
  442.     cmp    rt11ver    ,#5        ; /62/ is the RT-11 V5 or above?
  443.     bge    90$            ; /62/ ya, .pval will work
  444.     tst    montyp            ; /62/ if XM and V4..
  445.     bgt    100$            ; /62/ ..tough luck
  446.     mov    @#sysptr,r0        ; /62/ otherwise, get RMON base and
  447.     clr    blkey(r0)        ; /63/ force USR to re-read the dir
  448.     br    100$
  449. 90$:
  450. ; /62/    .pval    #rtwork    ,#blkey    ,#0    ; /BBS/ force USR to re-read the dir
  451.     MOV    #rtwork    ,R0        ; /62/ expanded to assemble under V4
  452.     MOV    #28.*^o400+2,@R0    ; /62/ even though V4 can't run it
  453.     MOV    #blkey    ,2.(R0)        ; /62/
  454.     CLR    4.(R0)            ; /62/
  455.     EMT    ^o375            ; /62/
  456. 100$:    .lookup #rtwork    ,#lun.sr,#csidev ; /62/ open the DEVICE for input
  457.     bcs    120$            ; can not find it
  458.     clr    r0            ; no errors
  459.     br    150$
  460.  
  461. 110$:    mov    #csierr ,r1        ; .csispc error mapping
  462.     br    130$
  463. 120$:    mov    #lokerr ,r1        ; .lookup error mapping
  464. 130$:    movb    @#errbyt,r0        ; get the error code now
  465.     bpl    140$            ; /51/ normal (non-fatal) RT-11 error
  466.     com    r0            ; /51/ fatal error, flip it to map
  467.     mov    #faterr ,r1        ; /BBS/ to a fatal error message
  468. 140$:    asl    r0            ; word indexing
  469.     add    r0    ,r1        ; now map the RT-11 error into
  470.     mov    @r1    ,r0        ; a fake RMS-11 error
  471.  
  472. 150$:    add    #ln$max+2,sp        ; /63/ pop the .csispc input buffer
  473.     save    <r0>            ; /63/ did an error occur?
  474.     beq    160$            ; /51/ no
  475.     .purge    #lun.sr            ; /51/ ya, purge the channel
  476. 160$:    .unlock                ; /BBS/ now release the USR..
  477.     unsave    <r0>            ; /63/ restore possible error code
  478.     return
  479.  
  480.  
  481.     .sbttl    Read in the home block
  482.  
  483. ;    G E T H O M E
  484. ;
  485. ;    output:       r0    = if <>, error code
  486.  
  487. gethom: save    <r1,r2>            ; /54/
  488.     .readw    #rtwork,#lun.sr,#dirbuf,#400,#hd$blk
  489.     bcs    50$            ; it failed, bye
  490.     tst    rtvol            ; really verify volume?
  491.     beq    30$            ; no
  492.     mov    #dirbuf ,r2        ; ya, get top of the buffer
  493.     add    #hd$sys ,r2        ; now point to the volume ident
  494.     mov    r2    ,r1        ; /54/ copy of dirbuf pointer
  495.     mov    #rt    ,r0        ; /54/ check for DECRT11 id
  496. 10$:    tstb    @r0            ; /54/ done?
  497.     beq    30$            ; /54/ yes, exit
  498.     cmpb    (r0)+    ,(r1)+        ; /54/ same?
  499.     beq    10$            ; /54/ yes, keep looking
  500.     mov    #vms    ,r0        ; /54/ check for VMSEXCH id
  501. 20$:    tstb    @r0            ; /54/ done?
  502.     beq    30$            ; /54/ yes, exit
  503.     cmpb    (r0)+    ,(r2)+        ; /62/ same?
  504.     beq    20$            ; /54/ yes, keep looking
  505.     br    40$            ; /54/ not valid
  506. 30$:    clr    r0            ; no error
  507.     br    60$
  508.  
  509. 40$:    mov    #er$vol ,r0        ; return an error code
  510.     br    60$
  511. 50$:    movb    @#errbyt,r0        ; get the error code
  512.     asl    r0            ; word indexing
  513.     mov    drderr(r0),r0        ; /BBS/ disk read error mapping
  514. 60$:    unsave    <r2,r1>            ; /54/
  515.     return
  516.  
  517.  
  518.     .sbttl    Read in a segment, get header data
  519.  
  520. ;    G E T H D R
  521. ;
  522. ;    input:    r1    = desired segment begins at this block
  523. ;    output:    dirbuf    = dir segment just read
  524. ;        dirsiz    = size of each file's dir entry
  525. ;        h.next    = link to next segment
  526.  
  527. gethdr: .readw    #rtwork,#lun.sr,#dirbuf,#1000,r1
  528.     bcs    20$            ; it failed, bye
  529.     mov    #dirbuf    ,r0        ; point to the buffer now
  530.     asl    h$next(r0)        ; segments are two blocks in length
  531.     beq    10$            ; no more segments if zero
  532.     add    #4      ,h$next(r0)    ; and at last, the offset
  533. 10$:    mov    h$next(r0),h.next    ; get the link to the next one
  534.     mov    #7*2     ,dirsiz    ; the default entry size
  535.     add    h$ext(r0),dirsiz    ; plus extra bytes per entry
  536.     clr    r0            ; no error
  537.     br    30$
  538.  
  539. 20$:    movb    @#errbyt,r0        ; get the error code
  540.     asl    r0            ; word indexing
  541.     mov    drderr(r0),r0        ; /BBS/ disk read error mapping
  542. 30$:    return
  543.  
  544.  
  545.     .sbttl    Convert a directory entry to .asciz
  546.  
  547. ;    C O N V E R T
  548. ;
  549. ;    input:       r2    = buffer for the result
  550. ;           r3    = current directory entry pointer
  551.  
  552. convert:save    <r2>
  553.     calls    rdtoa    ,<r2,csidev>    ; /62/ convert the device name please
  554.     add    #2    ,r2        ; skip past it and insert a ":"
  555.     cmpb    @r2    ,#space        ; a space (no unit number?)
  556.     beq    10$            ; no
  557.     tstb    (r2)+            ; a real unit, skip over number
  558. 10$:    movb    #':    ,(r2)+        ; get DDn: format of device name
  559.     calls    rdtoa    ,<r2,f.nam1(r3)> ; convert first 3 file name to ascii
  560.     add    #3    ,r2        ; and skip over those three characters
  561.     calls    rdtoa    ,<r2,f.nam2(r3)> ; now get the rest of the file name
  562.     add    #3    ,r2        ; point to place a dot into the name
  563.     movb    #'.    ,(r2)+        ; a dot
  564.     calls    rdtoa    ,<r2,f.type(r3)> ; get the file type at last
  565.     clrb    3(r2)            ; ensure .asciz
  566.     unsave    <r2>
  567.     return
  568.  
  569.  
  570.     .sbttl    Wildcarded file name match test
  571.  
  572. ;    M A T C H
  573. ;
  574. ;    r3 = passed pointer to current entry in directory segment buffer
  575. ;    r4 = internal pointer to current entry in file names data buffer
  576.  
  577.     PERCENT = '.            ; /58/ percent in a file spec string
  578.     WILDC    = '?            ; /58/ wildcard flag in same
  579.  
  580. match:    save    <r1,r2,r4>        ; /62/
  581.     mov    #name2    ,r1        ; /62/ ascii name of file on disk
  582.     mov    r3    ,r2        ; /62/ address of its entry
  583.     add    #f.nam1 ,r2        ; /62/ bump to start of file name
  584.     mov    #3    ,r0        ; /62/ loop 3 times
  585. 10$:    calls    rdtoa    ,<r1,(r2)+>    ; /62/ convert to ascii
  586.     add    #3    ,r1        ; /62/ next please
  587.     sob    r0    ,10$        ; /62/
  588.  
  589.     mov    #name1    ,r4        ; /62/ top of input file names buffer
  590. 20$:    tstb    (r4)            ; /62/ is there an entry here?
  591.     beq    50$            ; /62/ nothing left, bail out..
  592.     mov    r4    ,r1        ; /62/ the file name pattern
  593.     mov    #name2    ,r2        ; the current file name on disk
  594.     mov    #6.    ,r0        ; the loop count for scanning
  595.     add    r0    ,r4        ; /62/ preset to file type location
  596.     call    m.char            ; /58/ compare file name
  597.     bcs    30$            ; /58/ match failure
  598.     mov    r4    ,r1        ; /62/ the file type pattern
  599.     mov    #name2+6,r2        ; the current file type on disk
  600.     mov    #3.    ,r0        ; the loop count for scanning
  601.     add    r0    ,r4        ; /62/ preset to next file name
  602.     call    m.char            ; /58/ compare file type
  603.     bcs    40$            ; /62/ match failure
  604.     mov    sp    ,r0        ; flag success and exit
  605.     br    60$
  606. 30$:    add    #3    ,r4        ; /62/ bump to next file name
  607. 40$:    br    20$            ; /62/ go try possible next file spec
  608. 50$:    clr    r0            ; /62/ failure, exit
  609. 60$:    unsave    <r4,r2,r1>        ; /62/
  610.     return
  611.  
  612. m.char:    mov    r0    ,L311$        ; /63/ save for
  613.     mov    r1    ,L310$        ; /58/ later re-use
  614. 10$:    cmpb    @r1    ,@r2        ; /58/ if they match, no problem
  615.     beq    20$            ; /58/ simply check the next character
  616.     cmpb    @r1    ,#wildc        ; /58/ a translated * wildcard?
  617.     beq    30$            ; /58/ yes - alternative check
  618.     cmpb    @r1    ,#percent    ; /58/ a translated % wildcard?
  619.     bne    80$            ; /58/ no  - match failure..
  620.     cmpb    (r2)    ,#space        ; /62/ ya, but must be something here
  621.     ble    80$            ; /62/ nothing there, match failure
  622. 20$:    inc    r1            ; /58/ match so far,
  623.     inc    r2            ; /58/ update pointers
  624.     sob    r0    ,10$        ; /58/ and check the next ones
  625.     call    m.len            ; /58/ are we at end of string?
  626.     bcs    70$            ; /58/ yes - success
  627.     cmpb    @r1    ,#space        ; /58/ no - see if wildcarded
  628.     beq    70$            ; /58/ if so, success
  629.     br    80$            ; /58/ else failure..
  630.  
  631. 30$:    inc    r1            ; /58/ point to char after wildcard
  632.     call    m.len            ; /58/ are we at end of string?
  633.     bcs    70$            ; /58/ if so, success..
  634. 40$:    cmpb    @r1    ,#space        ; /58/ a space?
  635.     beq    70$            ; /58/ end of matching check
  636.     cmpb    @r1    ,#percent    ; /58/ a translated % wildcard?
  637.     bne    50$            ; /58/ no - compare strings
  638.     cmpb    (r2)    ,#space        ; /62/ ya, but must be something here
  639.     ble    80$            ; /62/ nothing there, match failure
  640.     inc    r1            ; /58/ point to char after wildc
  641.     sob    r0    ,40$        ; /58/ otherwise loop to find a char
  642.     br    70$            ; /58/ all %s, assume success
  643.  
  644. 50$:    cmpb    @r1    ,@r2        ; /58/ find a matching character?
  645.     bne    60$            ; /58/ not yet, see next..
  646.     cmpb    1(r2)    ,@r2        ; /58/ next = same?
  647.     bne    20$            ; /58/ no - verify remainder
  648. 60$:    inc    r2            ; /58/ else point to next
  649.     sob    r0    ,50$        ; /58/ and loop until done
  650.     br    80$            ; /58/ match failure
  651. 70$:    tst    (pc)+            ; /58/ skip next instr and clr carry
  652. 80$:    sec                ; /58/ or, flag failure by seting it
  653.     return
  654.  
  655. m.len:    save    <r0>            ; /63/
  656.     mov    r1    ,r0        ; /58/ copy searched string pointer
  657.     sub    L310$    ,r0        ; /62/ get number of chars checked
  658.     cmp    L311$    ,r0        ; /62/ compare with total char count
  659.     beq    10$            ; /58/ a match - go flag it
  660.     tst    (pc)+            ; /58/ else skip next instr, clr carry
  661. 10$:    sec                ; /58/ flag end of string
  662.     unsave    <r0>            ; /63/
  663.     return
  664.  
  665.  
  666.     .sbttl    Convert date to .asciz
  667.  
  668. ;    A S C D A T E
  669. ;
  670. ;    input:   (r5)    = output buffer address
  671. ;        2(r5)    = value of date, -1 for today's
  672.  
  673. ; /BBS/    modified for RT-11 V5.5 extension of max year to 2099
  674.  
  675.     DOFOUR    = 1    ; /62/ zero to display just last two digits of year
  676.  
  677. ascdat::save    <r0,r1,r2,r3>
  678.     mov    @r5    ,r1        ; the result address
  679.     mov    2(r5)    ,r0        ; /62/ get the date desired please
  680.     bne    10$            ; /62/ something is there
  681.     strcpy    r1    ,#nodate    ; /62/ else return " No Date "
  682.     br    60$            ; bye
  683.  
  684. 10$:    cmp    r0    ,#-1        ; /62/ if -1, then return today's date
  685.     bne    20$            ; it's something else..
  686.     cmp    -(sp)    ,-(sp)        ; /BBS/ a two word buffer
  687.     mov    sp    ,r3        ; /BBS/ point to it
  688.     .gtim    #rtwork    ,r3        ; /BBS/ roll over clock so date is ok
  689.     cmp    (sp)+    ,(sp)+        ; /BBS/ dump the time buffer
  690.     .date                ; /BBS/ get today's date
  691.  
  692. 20$:    mov    r0    ,r3        ; copy the date to get day of month
  693.     ash    #3    ,r3        ; /62/ shift left 3 places
  694.     swab    r3            ; then swap bytes to get
  695.     bic    #^c<37>    ,r3        ; the date, at last
  696.     call    i2toa            ; /BBS/ write ascii to out buff
  697.  
  698.     mov    r0    ,r3        ; get the date once again please
  699.     swab    r3            ; get the month to bits 5..2
  700.     bic    #^c<74>    ,r3        ; /62/ hose yrs/days, leave at *4
  701.     cmp    r3    ,#12.*4        ; /62/ a legal month?
  702.     ble    30$            ; /62/ most likely..
  703.     clr    r3            ; /62/ no, force "-ERR-"
  704. 30$:    add    #months    ,r3        ; /BBS/ the easy way to point to month
  705.     mov    #5    ,r2        ; /BBS/ prep to copy 5 chars "-Mon-"
  706. 40$:    movb    (r3)+    ,(r1)+        ; /BBS/ copy to out buff
  707.     dec    r2            ; /BBS/ one byte
  708.     bne    40$            ; /BBS/ at a time
  709.  
  710.     mov    r0    ,r3        ; copy the date
  711.     bic    #^c<37>    ,r3        ; hose all but the year
  712.  
  713.     .if ne dofour            ; /62/ display all four years digits
  714.     add    #1972.    ,r3        ; plus the bias please
  715.     .iff                ; /62/ just last two digits of year
  716.     add    #72.    ,r3        ; plus the bias please
  717.     .iftf                ; /63/ common code ahead..
  718.  
  719.     bic    #^c<140000>,r0        ; /BBS/ extend max year w/two hi bits
  720.     swab    r0            ; /BBS/ two hi bits now are bits 7,6
  721.     asr    r0            ; /BBS/ shift to bits 6,5 (true value)
  722.     add    r0    ,r3        ; /BBS/ add to total years
  723.  
  724.     .ift                ; /63/
  725.     call    i4toa            ; /BBS/ write all 4 digits of year
  726.     .iff                ; /62/ just last two digits of year
  727.     cmp    #100.    ,r3        ; /BBS/ is it 2000 (next century) yet?
  728.     bgt    50$            ; /BBS/ no
  729.     sub    #100.    ,r3        ; /BBS/ ya, extract last 2 digits
  730. 50$:    call    i2toa            ; /BBS/ write ascii to out buff
  731.     .endc    ; ne dofour
  732.  
  733.     clrb    @r1            ; .asciz
  734.     cmpb    #'0    ,@(r5)        ; /BBS/ leading zero to blank?
  735.     bne    60$            ; /BBS/ not zero
  736.     movb    #space    ,@(r5)        ; /BBS/ ya
  737. 60$:    unsave    <r3,r2,r1,r0>
  738.     return
  739.  
  740.  
  741.     .sbttl    Display TSX+ file creation time    ; /BBS/ all new
  742.  
  743. ;    F I L T I M E
  744. ;
  745. ;    input:      (r5)    = output buffer address
  746. ;         2(r5)    = input filtim in TSX+ "3 sec" format
  747.  
  748. filtim:    save    <r0,r1,r2,r3>
  749.     mov    2(r5)    ,r1        ; get filtim (low) word
  750.     clr    r0            ; clear hi word for divide
  751.     div    #20.    ,r0        ; get # of 3-secs since midnite
  752.     mov    r1    ,-(sp)        ; put on stack
  753.     asl    r1            ; multiply by two
  754.     add    r1    ,(sp)        ; *3 = secs component of time value
  755.     mov    r0    ,r1        ; prep for divide to..
  756.     clr    r0            ; ..get mins + hrs
  757.     div    #60.    ,r0        ; get minutes component of time value
  758.     mov    r1    ,-(sp)        ; save minutes
  759.     mov    r0    ,r3        ; put hrs where i2toa expects them
  760.     mov    @r5    ,r1        ; the result address
  761.     call    i2toa            ; write hours to outbuff
  762.     movb    #':    ,(r1)+        ; format display
  763.     mov    (sp)+    ,r3        ; put mins where i2toa expects them
  764.     call    i2toa            ; write mins to outbuf
  765.     movb    #':    ,(r1)+        ; format display
  766.     mov    (sp)+    ,r3        ; put secs where i2toa expects them
  767.     call    i2toa            ; write secs to outbuf
  768.     clrb    @r1            ; null terminate the whole thingie
  769.     unsave    <r3,r2,r1,r0>
  770.     return
  771.  
  772.  
  773.     .sbttl    Unsigned 16-bit integer conversion  ; /BBS/ all new
  774.  
  775. ;    D $ C V T N U M        accommodates sizes > 32767.
  776. ;
  777. ;    input:      (r5)    = output buffer address
  778. ;         2(r5)    = unsigned 16-bit value to write into buffer
  779. ;         4(r5)    = display formatting:
  780. ;              0  = field set to 6 and right justified
  781. ;              <> = space at left, number from left, .asciz
  782.  
  783. d$cvtnum:save    <r0,r1,r2,r3>        ; /62/ cleaned up this code..
  784.     mov    (r5)    ,r2        ; write the number here
  785.     mov    #6    ,r3        ; make its width 6
  786.     mov    r3    ,r1        ; copy to clear buffer
  787.  
  788. 10$:    movb    #space    ,(r2)+        ; fill the buffer with blanks
  789.     sob    r1    ,10$
  790.     clrb    @r2            ; null terminate end of buffer
  791.     mov    2(r5)    ,r1        ; get the value to print out
  792.  
  793. 20$:    clr    r0            ; set up for the divide by 10.
  794.     div    #10.    ,r0        ; remainder in r1, quotient r0
  795.     add    #'0    ,r1        ; convert remainder to character
  796.     movb    r1    ,-(r2)        ; and stuff that into output buffer
  797.     mov    r0    ,r1        ; copy for next iteration
  798.     beq    30$            ; done
  799.     sob    r3    ,20$        ; next..
  800.  
  801. 30$:    tst    4(r5)            ; field flag flyin?
  802.     beq    50$            ; no, exit
  803.      mov    @r5    ,r1        ; start of the buffer here
  804.      inc    r1            ; keep the leading blank in..
  805. 40$:     movb    (r2)+    ,(r1)+        ; move chars to front of buffer
  806.      bne    40$            ; copy to and including the null
  807.  
  808. 50$:    unsave    <r3,r2,r1,r0>
  809.     return
  810.  
  811.     .end
  812.