diff --git a/README.md b/README.md index 236f65a7..e46fd220 100644 --- a/README.md +++ b/README.md @@ -74,6 +74,7 @@ from scratch. - TCTYP and CRTSTY, terminal handling. - PEEK, system monitoring. - ARCDEV, transparent file system access to archive files. + - DIRDEV, list directories, sorted or subsetted. - ATSIGN TARAKA, starts dragons. - Dragons: DMPCPY, MODEMS, NETIME, PFTHMG. - MTBOOT, make bootable tapes. diff --git a/build/build.tcl b/build/build.tcl index baac2081..788d52ee 100644 --- a/build/build.tcl +++ b/build/build.tcl @@ -412,6 +412,9 @@ expect ":KILL" respond "*" ":link device;tcp syn123,device;atsign mlslv\r" +respond "*" ":midas device;atsign dirdev_syseng;dirdev\r" +expect ":KILL" + respond "*" ":midas sys1;ts cftp_sysen2; cftp\r" respond "KLp==" "0\r" expect ":KILL" diff --git a/doc/README.md b/doc/README.md index 6649a2f7..393b383e 100644 --- a/doc/README.md +++ b/doc/README.md @@ -14,3 +14,4 @@ - TCTYP: [manual](_info_/tctyp.order) - DSKDUMP: [commands](sysdoc/dskdmp.order) - FIND: [manual](init/find.13) +- DIRDEV: [manual](_init_/dir.order) diff --git a/doc/_info_/dir.order b/doc/_info_/dir.order new file mode 100755 index 00000000..8480a205 --- /dev/null +++ b/doc/_info_/dir.order @@ -0,0 +1,160 @@ +The DIR device + +A new device has been defined (it will work only on ITS with version +number greater than 886). This device allows users and programs to +see sorted directories or subsets of directories. The DIR device +supports both image and ascii mode directories which means that it can +be PRINTed or used in programs like DIRED and FIND. + +The DIR device requires a file name much like a disk path name. +It takes a device name (DIR), a user's directory name, and two file +names. The directory name identifies the disk directory to be sorted +or subsetted, while the two file names indicate what to do with the +directory. The device name may also be DIRxxx, which will cause +device xxx: to be used instead of DSK. For example, DIRML: will go +over the net to the ML machine, and DIRAR3: will look at the +specified user's AR3 archive. + +There are currently two types of operations - sorting and subsetting. + +If you wish to sort, the first file name you supply will identify the +sort key and the second file name will determine whether an ascending +or descending sort is used (DOWN => descending, UP implies ascending). +The following table gives the currently recognized first file names +for sorting: + + file name => sort key + + NAME1 sort on first file name + NAME2 sort on second file name + LENGTH or SIZE sort on file length + (links have len = 0) + CDATE sort on creation date + RDATE sort on reference date + +Note that numeric names are sorted specially: The numeric names come +before any non-numeric names, and the numeric names are ordered by +number, not by name (so for example, 10 comes after 9, instead of +before it.) + +For subsetting, the directory subset will be sorted like NAME1 UP. + +If the first file name you supply is NOT or ONLY, it indicates whether +only those things with the named attribute (if ONLY) or only those +things without the named attribute (if NOT) are retained. The second +file name indicates the attribute upon which the decision should be +made: + + file name ==> attribute + + LINKS or LINK whether file is a link + DUMPED whether file is backed up + PACKnm whether file is on disk pack nm + +If the first file name is one of: CDATE> CDATE= CDATE< RDATE> RDATE= RDATE< +then the second file name must be a date in YYMMDD format. + +The directory subset returned consists of only those files which pass +the test, such as: + all files created since new years: CDATE> 750000 + all file created on last July 4: CDATE= 740704 +and similarly for reference date. Note that you can use 00's even +though those are normally not legal dates. Additionally, these work +on links just like CDATE UP and CDATE DOWN, even though you usually +don't see creation dates for them. + +If the first file name is FIRST, FIRST#, or SECOND, the second file +name specifies a pattern in DIRED-style "* format". Examples: + all files named NBIN: SECOND NBIN + all files with 1st name starting with BAR: FIRST BAR*** + +FIRST# is like FIRST, except that it will only consider files with a +numeric fn2. Thus FIRST# ****** will give you all the files with +purely numeric second names (and any first name). Also, FIRST# cause +the numeric fn2's to be right-justified in the listing. + +If the file names given are not one of the valid forms listed above, +you will get a "mode not available" error. If the file names are +valid but the directory can not be opened, you will get whatever that +open error is. For example: DIR:BLECH;NAME1 UP will cause a +"non-existent user name" error. + +Examples: + + DIR:.INFO.;CDATE DOWN + will give a directory of all the .INFO. files with the + most recently created ones listed first. + + + DIR:SYS;ONLY LINKS + will give a directory with those files in SYS + that are links + + +The DIR device handler can also be used to intercept DSK (or AI, DM, +ARC, etc.) device requests by means of translation entries. Saying +the following to DDT (eg. in your .DDT. (INIT) file) +  *: *; .FILE. *, JOB:DEVICE;JOBDEV DIR +  *: *; ****** *, JOB:DEVICE;JOBDEV DIR +  *: *; * ******, JOB:DEVICE;JOBDEV DIR +  *: *; * ######, JOB:DEVICE;JOBDEV DIR +will allow you to use the following features of the DIR handler: + + .FILE. (DIR) acts like DIR: NAME1 UP, +which will give you a DIR-style directory listing +(with tenths-of-blocks and reference dates) instead of the normal +system listing. (Note that .FILE. (DIR) is what TECO reads to do the +EY command, so EY will give you the new format. + + .FILE. + acts like DIR: ONLY + .FILE. - acts like DIR: NOT + .FILE. / acts like DIR: UP + .FILE. \ acts like DIR: DOWN + ****** acts like DIR: SECOND + ****** acts like DIR: FIRST + ###### acts like DIR: FIRST# + +Note the fact that all .FILE. (DIR) requests must go through the DIR +handler will significantly slow down the FIND program. Thus the +translation entry should be removed (via  .FILE.) before running FIND. + + +Using the DIR device: + +There are basically four ways to use the DIR right now: + +(1) Print it using DDT, etc. + For example, try typing :PRINT DIR:SYS;ONLY LINKS to DDT. + This will get you a ":LISTF" of the links in the SYS directory. + +(2) Use it in TECO macros for getting at various directory subsets. + For example, DIR: FIRST or ****** (with the + appropriate DDT translation entry) can be used in the M..G + directory display macro to only display the appropriate files. + Also, DIR: FIRST# (or DSK: ######) can be + used in the "erase all but the last few numerically-named copies + of " macro. Doing these kinds of subsetting via the DIR + device is usually faster than reading in the whole directory + (which the system must convert to acsii) and then subsetting it + using TECO commands. The file AI:GROSS;^TECO^ > contains some + examples (see the macros .F, F, Z, and D) + +(3) Use it in DIRED. NDIRED now knows about the DIR device. + For example, try typing ACT DIR:SYS;ONLY LINKS to NDIRED. + This will activate a directory consisting of only the links in the + SYS directory. NDIRED will do all copies, deletes, etc. via the + DSK for efficiency. + +(4) Use it with DFIND. This is a special version of FIND for use with the + DIR device. You may NOT do file name pattern matching since the file + names you specify will be interpreted as names for the DIR device. + You can, however, use it for other purposes. For example try typing + the following to DDT: :DFIND ONLY PACK20 + This will cause every directory on the system to be searched for + files that are on pack 20. + +Report problems to BUG-ITS@MIT-MC. +Reasonable suggestions for modifications will be considered. +(Formerly maintained by GROSS@AI or PDL@DM.) + + diff --git a/doc/_info_/dir.recent b/doc/_info_/dir.recent new file mode 100755 index 00000000..1c2aed89 --- /dev/null +++ b/doc/_info_/dir.recent @@ -0,0 +1,111 @@ +CHANGES TO DIR DEVICE BY VERSION NUMBER, SOURCE FILE IS DM:DEVICE;DIRDEV > + +80 (6/11/78 MOON) Fixed to work with SIOT (e.g. LISP I/O) and with + new-type archives. + +79 (7/29/77 JMB) .FILE. (DIR) is translated to NAME1 UP. + +52 (5/23/76 JMB) New DDT mode (for DDT) just like FIRST mode. + NAME1 & NAME2 , where is not UP or DOWN, + first gives files whose specified name matches , then + ones after it (in ASCENDING order), and then ones before it, with + each group preceded by a line of dashes. + +51 (5/15/76 JMB) Print file size like FIND (NNN+NNN). + Changed format of links. + +50 (5/8/76 JMB) Added display of REAP bit. + Changed AR* handling to read directly from archive file. + Gets headers from device handler, if possible. + Prints author for DSK or DM files when running on DM only. + +49 (5/7/76 JMB) Changed format of ascii directory output. + +48 (5/5/76 JMB) Add -FIRST mode, opposite of FIRST mode. + +47 (11/7/75 GROSS) Clean up a little. + +46 (11/6/75 GROSS) Hack files bigger than 256 blocks. + +45 (11/6/75 GROSS) Fix bug in FLEN. + +44 (9/6/75 GROSS) Fix bug in RJNUM - non-final "9"s lost. + Have CNAMES not do RJNUM stuff if doing FIRST#. + +43 (8/19/75 GROSS) Put lots of code in the output buffer. + Flush some spurious SETZM's. + +42 (8/17/75 GROSS) Don't do (41) if fname is .FILE. (DIR) + Put most of the OPEN code into the directory buffer. + +41 (8/16/75 GROSS) Hack image-mode dirs for NDIRED, etc. + +40 (8/16/75 GROSS) Add hacks for .FILE. /. + +39 (8/15/75 GROSS) Add stuff for 2nd output line. + Use 0 as the file-length for links. + +38 (8/14/75 GROSS) Add hacks for .FILE. +. + +37 (8/13/75 GROSS) Add FIRST# mode and ###### + for getting files with numeric 2nd fname. + Do syntax check before opening directory. + Use right-justified numbers for comparison. + +36 (7/26/75 GROSS) Use 777777 for link's flen, + and change MAXCHS to reflect the fact that if you have + the max # of files, each will have at most a 3 char + length (being n.m). + Add decoding for DIRxxx devices. + Separate pure & impure stuff. + +35 Clean up a lot: + Flush GCDIR in favor of faster SUBSET. + Flush DIRSRT in favor of faster SORT. + Make the open filename decoding simpler. + Have LISTF do it all at once (not 1 line at a time). + +34 Use JOBCAL instead of JOBGET in interrupt handler. + +33 (7/23/75 GROSS) If null cdate, don't print time. + +32 (7/22/75 GROSS) Pass back the real error code + when the directory open fails. + +31 (7/22/75 GROSS) Do ascii open so TTY will work. + +30 (7/21/75 GROSS) Flush lots of extraneous krud. + Have file-length give 1 decimal place. + Put referenced-date in the output. + Add "SIZE" as an alias for "LENGTH". + Add device hackery: + DIR: Works normally. +(36) DIR: Like DIR:, but uses device : +(36) For example, DIRML:LUSER;RDATE DOWN + JOB: Loses. + Anything else is treated like DSK: + .FILE. (DIR) ACTS LIKE NAME1 UP + .FILE. + ACTS LIKE ONLY + .FILE. - ACTS LIKE NOT +(40) .FILE. / ACTS LIKE UP +(40) .FILE. \ ACTS LIKE DOWN + ****** ACTS LIKE FIRST +(37) ###### ACTS LIKE FIRST# + ****** ACTS LIKE SECOND + To use these features, tell DDT + AI *: *; .FILE. *, DIR: + AI *: *; ****** *, DIR: + AI *: *; * ******, DIR: +(37) AI *: *; * ######, DIR: + +29 (3/30/75 PDL) Put insert files into this file. + Added new modes: CDATE>, CDATE=, CDATE<, same for RDATE, + and NAME1, NAME2. + Date hackers take 741231 style dates, + name hackers take * format names. + +28 (3/25/75 PDL) Changed to give MODE NOT AVAILABLE if files + not from legal list instead of just giving directory + untouched. + +------- DIR ORDER updated to this point. ------- diff --git a/src/syseng/dirdev.86 b/src/syseng/dirdev.86 new file mode 100755 index 00000000..8c1bb900 --- /dev/null +++ b/src/syseng/dirdev.86 @@ -0,0 +1,1596 @@ +;-*-MIDAS-*- + +TITLE DIRDEV -- DIRECTORY JOB DEVICE + + ;Details of updates moved to .INFO.;DIR RECENT + + +IMAGE==1 ;1 => Do hair also for image mode open. + +.XCREF A B P + +;AC DEFS + +R0==0 +A=1 +B=2 ;MUST = A+1 +C=3 ;MUST = B+1 +D=4 +E=5 ;RELATIVELY PERMANENT. +F=6 ;RELATIVELY PERMANENT. +I=7 +Q=11 ;RELATIVELY PERMANENT. +LFBPTR=13 ;BYTE POINTER FOR GENERATING ASCII DIR. +H=14 +P=15 ;PDL POINTER +AUTHFL=16 ;-1 IF DEVICE HAS AUTHORS + +BLANK=40 ;BLANK ASCII CHAR. + +BOJC==1 ;BOJ OUTPUT CHANNEL. +IFILE==2 ;INPUT FILE DIRECTORY CHANNEL. + + +SUBTTL File directory symbol definitions. + +.INSRT SYSTEM;FSDEFS > + +MFDPGE==20 ;WHERE TO PUT MFD +MFDBFR=MFDPGE*2000 + +UFDLEN=2000 ;LENGTH OF THE DIRECTORY. + +UN==1,,525252 ;FOR DDT'S BIT-TYPEOUT MODE. + + +SUBTTL Impure stuff + + LOC 77 + + SIXBIT /DIRDEV/ ;IDENTIFICATION INFO FOR PEEK +DIRDEV: 0 +F1: 0 +F2: 0 +DIRECT: 0 + 0 + 0 +CRUNAM: 0 +CRJNAM: 0 + 0 +DEVICE: 0 + +.M"HERE==. + +LOC 42 + JSR TSINT + +LOC .M"HERE + +LPDLL==40 +PDL: BLOCK LPDLL + + +IWD1: 0 ;JOBCAL AREA FOR INTERRUPT LEVEL. + +;JOBCAL AREA FOR MAIN PROGRAM LEVEL + +WD1: 0 +WD2: 0 +OPNFN1: 0 +OPNFN2: 0 +WD5: 0 +WD6: 0 + + +ERRCOD: 0 ;ERROR CODE. + + +OPMODE: 0 ;Open mode on JOB device. + +IMGHAK: 0 ;-1 => we are DSK: .FILE. (DIR) + +SORTER: NAME1 ;SORT's comparator predicate. +SELECT: SUBALL ;SUBSET's selector predicate. + +NOTSW: 0 ;Set if subsetting, eg, NOT DUMPED. +PACKNO: 0 ;Disk pack # if subsetting PACKxx +DATE: 0 ;Date or name for subsetting. +MASK: 0 ;Mask for name (where asterisks are). + +ASCEND: 0 ;For SORT: 0 => ASCENDING ORDER. +NMCOMP: 0 ;For 3-WAY SORT holds name to compare with. +FNCOMP: 0 ;For 3-WAY SORT holds address of comparison routine used. +PRNFLG: 0 ;For 3-WAY SORT: 1 => already printed first separator line. + +INITED: 0 ;Set to -1 after we do a successful JOBRET. +HNGFLG: 0 ;Set 0 if hung, -1 if not. +IFOPEN: 0 ;Set -1 if IFILE is open. + +ILFBPT: 0 ;Holds LFBPTR at beginning of each line. + +TSINT: 0 ;Interrupt JSR area. + 0 + JRST INTGO + + +BFR: BLOCK UFDLEN ;Directory buffer. +TBFR: BLOCK 50 + +TOPNO: SETZ + SIXBIT /OPEN/ + [.BAI,,IFILE] + DEVICE + [SIXBIT /.FILE./] + [SIXBIT /(DIR)/] + SETZ DIRECT + +MFDOPN: SETZ + SIXBIT /OPEN/ + [.BII,,IFILE] + DEVICE + [SIXBIT /M.F.D./] + SETZ [SIXBIT /(FILE)/] + +MFDBLK: SETZ ;CALL BLOCK TO GET MFD PAGE + SIXBIT /CORBLK/ + [100,,0] + [-1] + 1000,,MFDPGE + SETZI -5 + +;MAXIMUM POSSIBLE NUMBER OF FILES IN 1 DIRECTORY, +;= TOTAL AVAIL BYTES DIVIDED BY MINIMUM BYTES PER FILE -- +MAXFIL==*UFDBPW/+1 + +NAPTR: 0 ;AOBJN PTR DESCRIBING -- +NAVECT: BLOCK MAXFIL ;Vector of size.ptr,,name.block.ptr +SZVECT: BLOCK MAXFIL ;Vector of file.size (in words). + +MAXCHS==66. ;MAX # CHARS LISTF WILL DO FOR 1 FILE, + ;ASSUMING THERE ARE MAXFIL FILES. + +OUTPTR: 0 ;NEXT WORD/BYTE IN OUTBUF. +OUTFIN: 0 ;LAST WORD +1. +OUTBUF: BLOCK <100.+*MAXCHS+4>/5 ;OUTPUT FOR LISTF. + ;The 100. is for the header lines. + ;The 2 is for the separator lines. + +IFN IMAGE,[ +IMGBUF==OUTBUF +OUTPAD==-<.-OUTBUF> ;MORE WORDS NEEDED FOR IMAGE. + BLOCK IFG OUTPAD,OUTPAD .ELSE 0 +] + +BUFEND: + +IFN 0,[LOC <.*2000+1777>/2000 ;Pad the last impure page.] + +SUBTTL Various .CALL blocks & other constants + +RET=2000,,0 ;VALUE RETURNED. +ERR=3000,,0 ;ERROR CODE RETURNED. +IMM=1000,,0 ;IMMEDIATE ARGUMENT. + +IJGET: SETZ ;JOBCAL for interrupt level. + SIXBIT /JOBCAL/ + IMM BOJC + SETZ IWD1 + +JGET: SETZ ;JOBCAL for main program level. + SIXBIT /JOBCAL/ + IMM BOJC + RET WD1 + SETZ [-5,,WD2] + +JRET: SETZ + SIXBIT /JOBRET/ + IMM BOJC + H ;io.err.code,,number.to.skip + SETZ I ;AOBJN pointer for ret values. + +JIOC: SETZ + SIXBIT /SETIOC/ + IMM BOJC + SETZ I ;IOCERR code. + + +QBTBLI: 440600,, ;Byte ptrs for directory descr. + 360600,, + 300600,, + 220600,, + 140600,, + 060600,, + 000600,, + + CONSTA + +SUBTTL Dispatching loop + +START: JFCL ;LEAVE ROOM FOR .VALUE + MOVE P,[-LPDLL-1,,PDL-1] ;SET UP PDL + .SUSET [.SMASK,,[1_10]] ;ENABLE IOCERR INTRPT. + .SUSET [.SMSK2,,[1_BOJC]] ;ENABLE CHANNEL INTRPT. + .OPEN BOJC,[SIXBIT/ 'BOJ/] ;OPEN CHANNEL + JRST CLOSE ;CAN'T + .CALL [SETZ ;GET GARBAGE TO MAKE PEEK HAPPY + SIXBIT /RFNAME/ + 1000,,BOJC + 2000,,. + 2000,,CRUNAM + SETZM CRJNAM] + JFCL + SETZM INITED + SETOM HNGFLG ;SET NOT HUNG + +LOOP: SKIPN HNGFLG ;SEE IF HUNG + .HANG ;YES - WAIT UNTIL NOT + SETZM HNGFLG + .CALL JGET ;GET INFO FOR CALL + JRST CHKOPN ;FAILED - IGNORE + MOVE A,OPNFN1 + MOVEM A,F1 + MOVE A,OPNFN2 + MOVEM A,F2 + LDB A,[370200,,WD1] ;SEE IF CLOSE BITS SET + JUMPN A,CLOSE ;YES - GO CLOSE + LDB A,[000400,,WD1] ;GET OP CODE + CAIN A,1 ;IOT? + JRST IOT + JUMPE A,OPEN +;ANY OPERATION OTHER THAN OPEN IS NOT ALLOWED AT THE BEGINNING. + SKIPE INITED + JRST RNDMOP + .CALL [ SETZ ? SIXBIT /JOBRET/ + IMM BOJC ? SETZ [%EBDDV,,]] + JFCL + JRST CLOSE + +;RANDOM OPERATION DONE ON US AFTER WE ARE OPEN. +RNDMOP: CAIE A,10 ;Some UUO? + JRST SUCCED ; Yeah. Most things "succeed". + MOVE A,WD2 ;Get call name. + CAMN A,['LNKEDP] ;LNKEDP fails. + JRST SUCLOS + CAME A,['FILLEN] ;FILLEN is wrong type device. + JRST SUCCED + .CALL [ SETZ ? SIXBIT /JOBRET/ ? IMM BOJC ? SETZ [(%EBDDV)]] + JFCL + JRST LOOP + +OPNRET: .CALL [ SETZ ? SIXBIT /JOBRET/ + IMM BOJC ? SETZI 1] + JRST CLOSE + SETOM INITED ;HERE WHEN INITIAL OPEN SUCCEEDS. SAY WE ARE OPEN. + JRST LOOP + +SUCCED: MOVEI H,1 ;Skip once. + SETZM I + .CALL JRET + JFCL + JRST LOOP + +SUCLOS: MOVEI H,0 ;Skip sero times. + SETZM I + .CALL JRET + JFCL + JRST LOOP + + +SUBTTL OPEN handler. + +OPEN:.BEGIN + LDB A,[410300,,WD1] ;GET MODE + TRNE A,1 ;MUST BE READ + JRST BADOP ;NOPE + MOVEM A,OPMODE + TRO A,1 ;NOW MAKE THE BOJ MATCH + HRLZS A + HRRI A,(SIXBIT/BOJ/) + .OPEN BOJC,A + .LOSE %LSSYS +;Decode the file names to see what to do. + MOVEI A,12 ;"MODE NOT AVAILABLE". + MOVEM A,ERRCOD ;IN CASE SYNTAX ERR. + MOVE A,WD5 + MOVEM A,DIRECT + MOVE A,WD6 + MOVEM A,DEVICE + CAMN A,[SIXBIT /JOB/] + JRST BADOP + HLRZ R0,A ;Look at top 3 chars + CAIE R0,(SIXBIT /DIR/) + JRST DEV10 + HRLZ R0,A ;Get bottom 3 chars. + MOVE A,[SIXBIT /DSK/];Change DIR to DSK. + JUMPE R0,DEV06 + MOVE A,R0 ;Change DIRxxx to xxx. +DEV06: MOVEM A,DEVICE + MOVE A,[SIXBIT /.FILE./] + MOVE B,[SIXBIT /(DIR)/] + CAMN A,OPNFN1 + CAME B,OPNFN2 + JRST DEVEND + JRST NMTRAN + +DEV10: MOVE A,OPNFN1 ;Assume DSK-like dev -- + MOVE B,OPNFN2 + CAME A,[SIXBIT /.FILE./] + JRST DEV20 + CAME B,[SIXBIT /(DIR)/] + JRST DEV11 + SETOM IMGHAK ;Set switch. +NMTRAN: MOVE A,XNAME1 ;Map .FILE. (DIR) to NAME1 UP + MOVE B,[SIXBIT /UP/] + JRST DEVSET +DEV11: MOVE R0,B + LSH R0,-30. ;Isolate first char. + LSH B,6 ;Flush 1st char. + MOVE A,[SIXBIT /ONLY/] ;Try for +. + CAIN R0,'+ + JRST DEVSET ;Is +. + MOVE A,[SIXBIT /NOT/] + CAIN R0,'- + JRST DEVSET ;Is - + MOVE A,B + MOVE B,[SIXBIT 'UP'] + CAIN R0,'/ + JRST DEVSET ;Is / + MOVE B,[SIXBIT 'DOWN'] + CAIN R0,'\ + JRST DEVSET ;Is \ + JRST BADOP + +DEV20: CAME B,[SIXBIT /******/] + JRST DEV40 + MOVE B,A ;MAP X ****** TO FIRST X + MOVE A,XFIRST + JRST DEVSET +DEV40: CAME B,[SIXBIT /######/] + JRST DEV50 + MOVE B,A ;MAP X ###### TO FIRST# X + MOVE A,XFIRSN + JRST DEVSET +DEV50: CAME A,[SIXBIT /******/] + JRST BADOP + MOVE A,XSECON ;MAP ****** X TO SECOND X +DEVSET: MOVEM A,OPNFN1 + MOVEM B,OPNFN2 +DEVEND: MOVE A,DEVICE ;FOR PEEK WINNAGE + HLR A,A + HRLI A,'DIR + MOVEM A,DIRDEV + +;;;;; DETERMINE MODE FROM FN1 & FN2. + + MOVE A,OPNFN1 +;is it a comparative subset? + HRLZI B,-SB1CNT + CAMN A,SB1NAM(B) + JRST ISCOMP + AOBJN B,.-2 +;is it a special sort? + TRZ A,77 + HRLZI B,-SRTCNT + CAMN A,SRTNAM(B) + JRST ISSORT + AOBJN B,.-2 +;is it a NOT/ONLY SUBSET? + CAMN A,[SIXBIT /ONLY/] + JRST TRYSB2 ;OK -- CHECK 2ND NAME. + SETOM NOTSW ;MUST BE /NOT/. + CAME A,[SIXBIT /NOT/] + JRST BADOP +TRYSB2: MOVE A,OPNFN2 + TRZ A,77 ;Zero last char. + HRLZI B,-SB2CNT + CAMN A,SB2NAM(B) + JRST ISSB2 + AOBJN B,.-2 +;is it NOT/ONLY PACKxx? + TRZ A,7777 + CAME A,[SIXBIT/PACK/] + JRST BADOP + LDB A,[060600,,OPNFN2] ;GET PACK NUMBER + SUBI A,'0 + IMULI A,10. + MOVEM A,PACKNO + LDB A,[000600,,OPNFN2] + SUBI A,'0 + ADDM A,PACKNO + MOVEI A,IFPACK ;SET PROPER SELECTOR. + MOVEM A,SELECT + JRST SETUP + +ISCOMP: MOVE A,SB1TAB(B) ;GET INFO FROM TABLE. + HLRZM A,SELECT ;SET SELECTOR. + PUSHJ P,(A) ;PARSE FN2. + JRST BADOP ;IF DOESN'T PARSE. + JRST SETUP + +ISSORT: MOVE A,SRTTAB(B) + MOVEM A,SORTER + MOVE A,OPNFN2 + CAMN A,[SIXBIT /UP/] + JRST SETUP + SETOM ASCEND ;DESCENDING ORDER + CAMN A,[SIXBIT /DOWN/] + JRST SETUP + MOVE A,XNAME1(B) + CAME A,[SIXBIT /NAME1/] + CAMN A,[SIXBIT /NAME2/] + SKIPA + JRST BADOP + SETZM ASCEND + CAME A,[SIXBIT /NAME1/] + JRST .+3 + MOVEI A,NAME1+1 + SKIPA + MOVEI A,NAME2+1 + MOVEM A,FNCOMP + MOVE A,OPNFN2 ;GET NAME FOR 3-WAY SORT + TLC A,400000 ;TO MAKE COMPARISON WORK + MOVEM A,NMCOMP + JRST SETUP + +ISSB2: MOVE A,SB2TAB(B) + MOVEM A,SELECT + +SETUP: ;Open the directory. + MOVE A,DEVICE + AND A,[777700,,0] + CAME A,[SIXBIT /AR/] + JRST DBGTST + MOVE A,DEVICE + MOVEM A,DNAME1 + MOVE A,[SIXBIT />/] + MOVEM A,DNAME2 + MOVE A,[SIXBIT /DSK/] + MOVEM A,DEVICE +DBGTST: MOVE A,[SIXBIT /DEBUG/] + CAMN A,DIRECT + .HANG ;STOP HERE IF BEING DEBUGGED + .CALL OPNO + JRST BADOP + MOVE C,DNAME1 + CAME C,[SIXBIT /.FILE./] + MOVEM C,DEVICE +SETUP1: SETOM IFOPEN + MOVE A,[-UFDLEN,,BFR] + JRST OPEN10 + +;;;;;; Constants for OPEN + +OPNO: SETZ + SIXBIT/OPEN/ + ERR ERRCOD + [.BII,,IFILE] + DEVICE + DNAME1 + DNAME2 + SETZ DIRECT + +DNAME1: SIXBIT /.FILE./ +DNAME2: SIXBIT /(DIR)/ + + +SB1NAM: SIXBIT /CDATE>/ + SIXBIT /CDATE=/ + SIXBIT /CDATE/ + SIXBIT /RDATE=/ + SIXBIT /RDATE DIRECTORY. + MOVE B,[-MAXFIL,,NAVECT] ;AOBJN PTR FOR VECTOR. + MOVE C,SELECT ;SELECTOR PREDICATE. + PUSHJ P,SUBSET + MOVEM A,NAPTR ;SAVE RETURNED AOBJN PTR. +;SORT NAVECT. + MOVE B,SORTER + PUSHJ P,SORT +;INITIALIZE FOR SUBSEQUENT .IOT'S +IFN IMAGE,[ + MOVE A,OPMODE + TRNE A,4 + JRST OPNIMG ;IMAGE MODE. +] + MOVE LFBPTR,[440700,,OUTBUF] + MOVEM LFBPTR,OUTPTR ;BEGINNING OF OUTPUT AREA. + +;Attempt to get header from device handler + MOVE A,[440700,,TBFR] + ILDB B,A + JUMPE B,HE1 ;NO HEADER, MAKE OUR OWN + SETZ C, +HDL1: IDPB B,LFBPTR + CAIE B,^J + JRST HDL2 + SKIPE C ;FINISHED AFTER SECOND LINE-FEED + JRST FLISTF + SETO C, +HDL2: ILDB B,A + JUMPN B,HDL1 + MOVE LFBPTR,[440700,,OUTBUF] + +;1st header line. +HE1: MOVE A,DEVICE + PUSHJ P,LF6BIT ;PUT SIXBIT DEV NAME IN OUTPUT. + MOVEI A,BLANK + IDPB A,LFBPTR + MOVE A,DIRECT + PUSHJ P,LF6BIT + MOVEI A,^M + IDPB A,LFBPTR + MOVEI B,^J + IDPB B,LFBPTR +;2nd header line. + IDPB A,LFBPTR + IDPB B,LFBPTR +;;;Now listf the files. +FLISTF: MOVE A,NAPTR ;VECTOR OF FILE ENTRIES. + PUSHJ P,LISTF ;DO THEM. + AOJ LFBPTR, ;RH = LAST WORD +1. + HRRZM LFBPTR,OUTFIN ;SET IT. + JRST OPNRET + +;SET UP FOR IMAGE-MODE .IOT'S. +IFN IMAGE,[ +OPNIMG: ;;;;;; USE SORTED NAVECT TO RE-ARRANGE THE DIR. +;First, copy & reorder the name blocks into IMGBUF. + MOVE B,NAPTR ;AOBJN for name-block pointers. + MOVEI A,IMGBUF ;BLT destination. + JUMPGE B,OIMG20 ;Weird -- no files. +OIMG10: MOVEI C,(A) + HRL C,(B) ;Now = name.block,,next.imgbuf + BLT C,LUNBLK-1(C) + ADDI A,LUNBLK + AOBJN B,OIMG10 +OIMG20: +;Second, copy the reordered stuff back into the dir bfr. + MOVEI B,IMGBUF + SUBI B,(A) ;= -<# words in IMGBUF>. + ADDI B,UFDLEN ;offset to start of name area. + MOVEM B,BFR+UDNAMP ;Set it in the image dir. + ADDI B,BFR ;-> start of name area. + HRLI B,IMGBUF + BLT B,BFR+UFDLEN-1 ;Copy the stuff back. +] +OPNIMX: MOVEI A,BFR ;THE DIR ITSELF WILL BE OUTPUT. + HRLI A,444400 ;FULL-WORD BYTE PTR. + MOVEM A,OUTPTR + MOVEI B,UFDLEN(A) + MOVEM B,OUTFIN + JRST OPNRET + +.END OPEN + +SUBTTL IOT handler. + +IOT:.BEGIN + ;IOT HACKER FOR WHEN STUFF IS ALL IN CORE. + ;OUTPTR/ POINTS TO NEXT BYTE/WORD TO DO; + ;OUTFIN/ POINTS TO LAST WORD +1. + MOVE A,OPMODE + TRNE A,2 + JRST IOT1BL ;GO IF BLOCK INPUT. +;HERE FOR UNIT-MODE OR SIOT + MOVE A,WD2 ;NUMBER OF CHARACTERS WANTED + MOVE D,OUTFIN + SUBI D,@OUTPTR ;D GETS NUMBER OF WORDS AVAILABLE + IMULI D,5 ;NUMBER OF CHARACTERS + LDB B,[360600,,OUTPTR] ;OFFSET FOR CHARS ALREADY TAKEN IN 1ST WD + SUBI B,44 ;-# BITS TAKEN + IDIVI B,7 ;B GETS -# CHARACTERS ALREADY TAKEN + ADD D,B ;D GETS NUMBER OF CHARACTERS AVAILABLE + CAMLE A,D + MOVE A,D ;A GETS MIN(AMOUNT WANTED, AMOUNT AVAILABLE) + MOVE B,A + .CALL [ SETZ ? SIXBIT/SIOT/ + MOVEI BOJC ? OUTPTR ? SETZ A ] + .LOSE + CAMN B,WD2 ;DID WE GIVE ALL THAT WAS WANTED? + JRST LOOP + JRST IOTUNH ;NO, EOF, UNHANG CALLER + +IOT1BL: HLRE A,WD2 ;CALLER'S AOBJN. + JUMPGE A,LOOP + MOVNS A ;NOW = LEN WANTED. + HRRZ D,OUTPTR ;FIRST WORD AVAILABLE. + ADDI A,(D) ;LAST WORD +1. + MOVEI C,(A) + CAMLE A,OUTFIN + MOVE A,OUTFIN ;GIVE NO MORE THAN WE HAVE! + MOVEI B,(A) ;LAST WORD +1. + SUBI D,(A) ;NOW = -LEN WE WILL GIVE. + HRLZI A,(D) + HRR A,OUTPTR ;AOBJN PTR. + HRRM B,OUTPTR ;UPDATE. + .IOT BOJC,A + CAMN B,C + JRST LOOP +IOTUNH: SETZM H ;LUSER WANTED MORE THAN WE HAD. + SETZM I + .CALL JRET + JFCL + JRST LOOP + +.END IOT + +SUBTTL Exit and interrupt code. + + +CHKOPN: SKIPE INITED ;JOBCAL failed. In the initial OPEN? + JRST LOOP ; no, so we are still open. + JRST CLOSE ;yes, so creator is ignoring us. Lets log out. + + +BADOP: HRLZ H,ERRCOD ;SET ERROR CODE. + SETZM I + .CALL JRET + JFCL + JRST CLOSE ;WE MADE THE INITIAL OPEN FAIL, SO DIE. + +LOST: +LOSE: +CLOSE: .CLOSE BOJC, ;CLOSE THE CHANNEL + .CLOSE IFILE, + .LOGOUT + .VALUE + +INTGO: SKIPL TSINT ;IOC INTERRUPT + JRST INTIOE ;NO - IOERR INTERRUPT + .CALL IJGET ;GET COMMAND INFO + .DISMISS TSINT+1 ;NONE - DISMISS WITHOUT WAKEUP + PUSH P,A ;SAVE A + LDB A,[370200,,IWD1];GET CLOSE BITS + JUMPN A,CLOSE ;IF CLOSE GO QUIT. + POP P,A ;OTHERWISE - RESTORE A + SETOM HNGFLG ;WAKEUP MAIN PROGRAM LEVEL + .DISMIS TSINT+1 ;AND DISMISS INTERRUPT + +INTIOE: MOVEI I,3 + .CALL JIOC ;SIGNAL IOC ERROR TO USER + JFCL + MOVEI A,300 ;SLEEP AWHILE TO TRY AVOID + .SLEEP A, ;STATUS TIMING ERROR. + JRST CLOSE ;DIE + + +SUBTTL Directory subsetting routine. + +SUBSET:.BEGIN ;BUILD VECTOR OF FILE POINTERS. + ;EACH ENTRY IS FILE.LEN.PTR,,NAME.BLK.PTR + ;B/ AOBJN TO VECTOR + ;A/ -> DIRECTORY + ;C/ -> SELECTOR CODE (SKIPS TO USE FILE). + ; CALLED WITH A/ -> NAME BLOCK. + ;WE RETURN A/ AOBJN TO FILLED PART OF VECTOR. + MOVE E,[-MAXFIL-1,,SZVECT-1] ;Size-vector ptr. + PUSH P,B ;SAVE. + SUB B,[1,,1] + PUSH P,A ;Save dir pointer. + MOVEI D,UFDLEN(A) ;END OF DIR +1. + ADD A,UDNAMP(A) ;-> 1ST NAME ENTRY. + JRST SUBTST ;ENTER LOOP. +SUBLUP: ADDI A,LUNBLK ;-> NEXT NAME ENTRY. +SUBTST: CAML A,D + JRST SUBEND + SKIPN UNFN1(A) ;SKIP THOSE WITH FN1 = 0. + JRST SUBLUP + PUSHJ P,(C) ;CALL THE PREDICATE. + JRST SUBLUP ;NO SKIP => DON'T USE. + PUSH B,A ;ADD ENTRY TO VECTOR. + PUSH P,A ;SAVE + PUSH P,B + MOVE B,-2(P) ;-> dir for FLEN. + PUSHJ P,FLEN ;RETURN A/ FILE LEN. + PUSH E,A ;Save this file len. + POP P,B + HRLM E,(B) ;Put ptr to len in LH. + POP P,A + JRST SUBLUP + +SUBEND: POP P,A ;Flush dir ptr from stack. + POP P,A ;AOBJN TO BEGINNING OF VECTOR. + AOBJN B,.+1 ;CONVERT PDL PTR TO VECTOR PTR. + HLLZS B ;= -UNUSED.IN.VECT,,0 + SUB A,B ;NOW IS AOBJN TO USED VECTOR. + POPJ P, + +.END SUBSET + + +SUBTTL Subsetting predicates. + + +;This page contains routines that are used for directory subset +;selection. They are not allowed to clobber any regs. + + +;KEEP ON CREATION DATE + +IFCDG: PUSH P,A + HLLZ A,UNDATE(A) + CAMG A,DATE + JRST FLSHIT + JRST KEEPIT + +IFCDE: PUSH P,A + HLLZ A,UNDATE(A) + CAME A,DATE + JRST FLSHIT + JRST KEEPIT + +IFCDL: PUSH P,A + HLLZ A,UNDATE(A) + CAML A,DATE + JRST FLSHIT + JRST KEEPIT + +;KEEP ON REFERENCE DATE + +IFRDG: PUSH P,A + HLLZ A,UNREF(A) + CAMG A,DATE + JRST FLSHIT + JRST KEEPIT + +IFRDE: PUSH P,A + HLLZ A,UNREF(A) + CAME A,DATE + JRST FLSHIT + JRST KEEPIT + +IFRDL: PUSH P,A + HLLZ A,UNREF(A) + CAML A,DATE + JRST FLSHIT + JRST KEEPIT + +;KEEP IF NAME1 SAME + +IFNM1: PUSH P,A + MOVE A,UNFN1(A) + AND A,MASK + CAME A,DATE ;does double duty + JRST FLSHIT + JRST KEEPIT + +;KEEP IF NAME1 SAME & FN2 IS NUMERIC + +IFNM1N: PUSH P,A + MOVE A,UNFN1(A) + AND A,MASK + CAME A,DATE + JRST FLSHIT + MOVE A,(P) + MOVE A,UNFN2(A) + PUSHJ P,RJNUM ;RIGHT-JUSTIFY THE NUMBER. + JRST FLSHIT ;IT ISN'T A NUMBER. + PUSH P,B + MOVE B,-1(P) + MOVEM A,UNFN2(B) ;USE RIGHT-JUSTIFIED NUMBER. + POP P,B + JRST KEEPIT + +;KEEP IF NAME1 NOT SAME + +IFNM1M: PUSH P,A + MOVE A,UNFN1(A) + AND A,MASK + CAMN A,DATE + JRST FLSHIT + JRST KEEPIT + +RJNUM: ;;;;;; RETURN RIGHT-JUSTIFIED NUMBER IN A, + ;;;;;; IF NOT NUMERIC, DON'T SKIP. + JUMPE A,RJNUMX ;Just in case ALL BLANK. + MOVE R0,A ;(KEEP VALUE IN A). +RJNUM1: JUMPE R0,RJNUM2 ;ALL THE REST IS BLANK. + CAML R0,[SIXBIT /0/] + CAMLE R0,[SIXBIT /999999/] + JRST RJNUMX + LSH R0,6 + JRST RJNUM1 +RJNUM2: TRNE A,77 + JRST RJNUM3 + LSH A,-6 ;RIGHT JUSTIFY. + JRST RJNUM2 +RJNUM3: AOS (P) +RJNUMX: POPJ P, + + +;KEEP IF NAME2 SAME + +IFNM2: PUSH P,A + MOVE A,UNFN2(A) + AND A,MASK + CAME A,DATE + JRST FLSHIT + JRST KEEPIT + +;KEEP IF DUMPED + +IFDUMP: PUSH P,A + MOVE A,UNRNDM(A) + TLNE A,UNLINK + JRST NEVER + TLNN A,UNDUMP + JRST FLSHIT + JRST KEEPIT + +;KEEP IF PACK NUMBER MATCHES THAT IT PACKNO + +IFPACK: PUSH P,A + MOVE A,UNRNDM(A) + TLNE A,UNLINK + JRST NEVER + LDB A,[UNPKN+A] + CAME A,PACKNO + JRST FLSHIT + JRST KEEPIT + +;KEEP IF A LINK + +IFLINK: PUSH P,A + MOVE A,UNRNDM(A) + TLNN A,UNLINK + JRST FLSHIT + JRST KEEPIT + +FLSHIT: POP P,A + SKIPE NOTSW +POPJ1: AOS (P) ;HE SAID NOT - KEEP IT + POPJ P, + +KEEPIT: POP P,A + SKIPN NOTSW +SUBALL: AOS (P) ;HE SAID ONLY - KEEP IT + POPJ P, + +NEVER: POP P,A + POPJ P, + + +SUBTTL File-length calculator + +;FLEN - GET FILE LENGTH +; INPUT A/ -> NAME BLOCK;B/ -> DIRECTORY. +; OUTPUT A/ FILE LENGTH (= 0 for a link) + +;DESCRIPTOR BYTE MEANINGS + ;0 => FREE 1-UDTKMX => TAKE NEXT N + ;UDTKMX+1 THRU UDWPH-1 => SKIP N-UDTKMX AND TAKE ONE + ;40 BIT SET => LOAD ADDRESS -- + ;LOWER 5 BITS PLUS NEXT TWO CHARS (17 BITS IN ALL) + +FLEN:.BEGIN + PUSH P,C + PUSH P,D + PUSH P,A + MOVEI D,(B) ;-> DIRECTORY. + MOVE B,UNRNDM(A) + TLNE B,UNLINK + JRST FLENLK + LDB A,[UNDSCP UNRNDM(A)] + IDIVI A,UFDBPW + ADDI D,UDDESC(A) ;D/ -> 1ST DESC WORD. + HLL D,QBTBLI(B) ;NOW A/ BYTE POINTER. + SETZ B, ;ZERO THE BLOCK COUNTER. + +BLKLUP: ILDB R0,D + JUMPE R0,LSTBYT + CAILE R0,UDTKMX + JRST ADDTHE + ADD B,R0 + JRST BLKLUP + +ADDTHE: CAIN R0,UDWPH + JRST BLKLUP ;DON'T COUNT IT IF DUMMY. + AOS B + CAIG R0,UDWPH + JRST BLKLUP + IBP D ;IF FULL ADDR, SKIP IT. + IBP D + JRST BLKLUP + +LSTBYT: POP P,A ;-> NAME BLOCK. + IMULI B,2000 + LDB A,[UNWRDC UNRNDM(A)] + ADD B,A + SKIPE A + SUBI B,2000 +FLENXT: MOVE A,B + POP P,D + POP P,C + POPJ P, + +FLENLK: MOVEI B,0 + POP P,A + JRST FLENXT + +.END FLEN + +SUBTTL Sort routine (for vectors) + +;SORT ROUTINE + +;A/ AOBJN FOR VECTOR TO SORT +;B/ -> COMPARATOR TO USE (SKIPS IF ORDER OK). +; IT MAY USE REGS C,D WITHOUT RESTORING THEM. + +;WE CLOBBER A B E F Q + +SORT:.BEGIN + PUSH P,A ;SAVE. + MOVEI Q,(B) ;SAVE. + MOVE E,A ;AOBJN FOR VECTOR. + AOBJN E,SRTL1 ;BUMP E & GO IF >1. + JRST SRTEND +SRTL1: MOVE A,-1(E) ;1ST ITEM + MOVE B,0(E) ;2ND ITEM + PUSHJ P,(Q) ;COMPARE. + JRST SRTSW ;IF NO SKIP, NEED TO SWITCH. +SRTL1T: AOBJN E,SRTL1 +SRTEND: POP P,A + POPJ P, + +SRTSW: HLLZ F,0(P) ;-LEN,,0 OF WHOLE VECTOR. + MOVNS F ;LEN,,0 OF WHOLE. + ADD F,E ;LEN.1ST.PART,,END.FIRST.PART. +SRTL2: MOVEM B,-1(F) ;SWAP OUT-OF-ORDER ENTRY. + MOVEM A,0(F) + SUB F,[1,,1] + TLNN F,777777 + JRST SRTL1T ;WE ARE AT BEGINNING. + MOVE A,-1(F) ;NOW A,B ARE PREV PAIR OF ITEMS + PUSHJ P,(Q) + JRST SRTL2 ;ORDER STILL NOT OK. + JRST SRTL1T ;ORDER OK - RETURN TO MAIN LOOP + +.END SORT + + +SUBTTL Sort predicates + +;This page contains comparators for various sort conditions. + +;CNAME1 and CNAME2 are comparators used by the comparators. +;Return if equal, go to AFIRST or BFIRST otherwise. + +CNAME1: MOVE C,UNFN1(A) ;SET UP COMPARISON OF NAME1'S + MOVE D,UNFN1(B) + +CNAMES: PUSH P,A + MOVE A,C + MOVEI R0,IFNM1N ;IF DOING FIRST#, THEN + CAMN R0,SELECT + JRST CN.COM ;DON'T RE-JUSTIFY. + PUSHJ P,RJNUM ;RIGHT-JUSTIFY. + JRST CN10 ;1ST IS NOT NUMERIC. + MOVE C,A + MOVE A,D + PUSHJ P,RJNUM + JRST CN.A ;1ST IS NUMERIC, 2ND ISN'T. + MOVE D,A + JRST CN.COM ;GO DO COMPARISON. +CN10: MOVE A,D + PUSHJ P,RJNUM + JRST CN.COM ;NEITHER ARE NUMERIC. + POP P,A + POP P,R0 ;(SINCE WE JRST) + SKIPN NMCOMP + JRST BFRST1 ;2ND NUMERIC, 1ST NOT. + TLC C,400000 + HRLI R0, + CAMN R0,FNCOMP ;MAKE SURE CHECKING RIGHT FILE NAME + CAMGE C,NMCOMP + JRST BFRST1 + JRST AFRST1 +CN.A: POP P,A + POP P,R0 + SKIPN NMCOMP + JRST AFRST1 ;1ST NUMERIC, 2ND NOT. + TLC D,400000 + HRLI R0, + CAMN R0,FNCOMP ;MAKE SURE CHECKING RIGHT FILE NAME + CAMGE D,NMCOMP + JRST AFRST1 + JRST BFRST1 +CN.COM: POP P,A + TLC C,400000 + TLC D,400000 + CAMN C,D ;THE SAME? + POPJ P, ;YES - RETURN + POP P,R0 ;NO -- POP 1 SINCE WE JRST. + CAML C,D ;WHICH IS FIRST + JRST BFIRST + JRST AFIRST + +CNAME2: MOVE C,UNFN2(A) ;SET UP COMPARISON OF NAME2'S + MOVE D,UNFN2(B) + JRST CNAMES + +NAME1: PUSHJ P,CNAME1 ;COMPARE ON NAME1 + PUSHJ P,CNAME2 ;FIRST NAMES EQUAL, TRY 2ND. + JRST A.EQ.B + +NAME2: PUSHJ P,CNAME2 ;COMPARE ON NAME2. + PUSHJ P,CNAME1 + JRST A.EQ.B + +;COMPARE BASED ON FILE LENGTH + +LENGTH: HLRZ C,A + HLRZ D,B + MOVE C,0(C) ;Pick up len from SZVECT. + MOVE D,0(D) + JRST COMPAR ;GO DO COMPARISON + + +;COMPARE BASED ON CREATION DATES + +CDATE: MOVE C,UNDATE(A) ;COMPARE CREATION DATES + MOVE D,UNDATE(B) + JRST COMPAR + +;COMPARE BASED ON REFERENCE DATES + +RDATE: HLRZ C,UNREF(A) + HLRZ D,UNREF(B) + +COMPAR: SUB C,D + JUMPE C,NAME1 ;IF THE SAME - SORT ON NAME + JUMPG C,BFIRST + +AFIRST: SKIPN NMCOMP ;3-WAY SORT? + JRST AFRST1 ;NO - ACT NORMALLY + HRLI R0, + CAME R0,FNCOMP ;MAKE SURE CHECKING RIGHT FILE NAME + JRST AFRST1 + CAML C,NMCOMP + JRST AFRST1+1 + CAML D,NMCOMP + POPJ P, + SKIPA +AFRST1: SKIPN ASCEND ;ASCENDING ORDER? + AOS (P) ;YES - NO SWITCH NEEDED + POPJ P, + +BFIRST: SKIPN NMCOMP ;3-WAY SORT? + JRST BFRST1 ;NO - ACT NORMALLY + HRLI R0, + CAME R0,FNCOMP ;MAKE SURE CHECKING RIGHT FILE NAME + JRST BFRST1 + CAML D,NMCOMP + POPJ P, + CAMGE C,NMCOMP + POPJ P, + SKIPA +BFRST1: SKIPE ASCEND ;DESCENDING ORDER? +A.EQ.B: AOS (P) ;YES - NO SWITCH NEEDED + POPJ P, + + +SUBTTL Name and Date parser. + +;This page contains routines to parse dates into directory +;format and names into * format. + +DPARSE: PUSH P,A + LDB A,[301400,,OPNFN2] + PUSHJ P,SIXNUM + DPB A,[UNYRB DATE] + LDB A,[141400,,OPNFN2] + PUSHJ P,SIXNUM + DPB A,[UNMON DATE] + LDB A,[001400,,OPNFN2] + PUSHJ P,SIXNUM + DPB A,[UNDAY DATE] + AOSA -1(P) +DPLOSE: POP P,A + POP P,A + POPJ P, + +SIXNUM: CAIL A,(SIXBIT / 00/) + CAILE A,(SIXBIT / 99/) + JRST DPLOSE + PUSH P,B + MOVE B,A + LSH A,-6 + ANDI A,17 + IMULI A,10. + ANDI B,17 + ADD A,B + POP P,B + POPJ P, + +;A/ name to parse +NMPARS: PUSH P,A + PUSH P,B + PUSH P,C + MOVE A,OPNFN2 + SETZ C, + CAMN A,[SIXBIT /*/] + JRST NMDONE + MOVE B,[440600,,A] + SETO C, +NMPAR1: CAMN B,[000600,,A] + JRST NMDONE + ILDB 0,B + CAIE 0,'* + JRST NMPAR1 + HRRI B,C + SETZ + DPB 0,B + HRRI B,A + JRST NMPAR1 +NMDONE: MOVEM C,MASK + AND A,MASK + MOVEM A,DATE + POP P,C + POP P,B + POP P,A + AOS (P) + POPJ P, + +;PUT FN2 INTO DATE AND SET MASK TO ALL ONES +;FOR EXACT COMPARISON WITH SUPPLIED NAME (NO STAR-MATCHING). +NMPXACT: + PUSH P,OPNFN2 + POP P,DATE + SETOM MASK + JRST POPJ1 + +SUBTTL LISTF routine. + +;LISTF -- CREATE ASCII VERSION OF AN IMAGE DIRECTORY. +; A/ AOBJN FOR VECTOR OF FILE.LEN,,NAME.PTR. +; LFBPTR/ BYTE POINTER FOR WHERE TO PUT THE STUFF. +; BFR==IMAGE DIRECTORY BUFFER, + + +LISTF:.BEGIN + MOVE D,A ;LOOP COUNTER. + JUMPGE A,LFDONE +LFNEXT: MOVE C,0(D) ;THIS LEN,,NAME.PTR + SKIPN NMCOMP ;WAS THIS A 3-WAY SORT? + JRST LFNXT1 ;NO -- SKIP SEPARATOR LINE CHECKING + MOVE A,UNFN1(C) + MOVE B,FNCOMP + CAIE B,NAME1+1 + MOVE A,UNFN2(C) + TLC A,400000 + CAMN A,NMCOMP + JRST LFNXT1 + CAML A,NMCOMP + JRST .+3 + SETZM NMCOMP + JRST LFSEP + SKIPE PRNFLG + JRST LFNXT1 + AOS PRNFLG +LFSEP: MOVEI A,100 ;OUTPUT SEPARATOR LINE + MOVEI B,"- +LFSEP1: IDPB B,LFBPTR + SOJG A,LFSEP1 + MOVEI B,^M + IDPB B,LFBPTR + MOVEI B,^J + IDPB B,LFBPTR + SKIPN PRNFLG + JRST [AOS PRNFLG + JRST LFSEP] +LFNXT1: MOVEM LFBPTR,ILFBPT ;SAVE INITIAL BYTE-POINTER FOR THIS LINE + MOVE A,UNRNDM(C) ;GET FLAG BITS + TLNN A,UNLINK ;LINK? + JRST LFFILE ;NOT A LINK +LFLINK: MOVEI A,[ASCIZ " L "] + PUSHJ P,LFASCZ + MOVE A,UNFN1(C) ;OUTPUT FNAME1 + PUSHJ P,LF6BIT + MOVEI B,BLANK + IDPB B,LFBPTR + MOVE A,UNFN2(C) ;OUTPUT FNAME2 + PUSHJ P,LF6BIT +;OUTPUT THE LINKED-TO NAMES. + IDPB B,LFBPTR + IDPB B,LFBPTR + IDPB B,LFBPTR + MOVEI B,"= + IDPB B,LFBPTR + IDPB B,LFBPTR + MOVEI B,"> + IDPB B,LFBPTR + MOVEI B,BLANK + IDPB B,LFBPTR + LDB A,[UNDSCP UNRNDM(C)] ;GET BYTE INDEX + IDIVI A,UFDBPW ;CONVERT TO BYTE POINTER + ADDI A,UDDESC+BFR + HLL A,QBTBLI(B) + PUSH P,C + PUSH P,D + MOVEI C,20. + MOVEI D,"; +LFCH00: MOVEI E,6 +LFCHR1: ILDB B,A ;GET NEXT CHAR + JUMPE B,LFCHR4 ;THE END. + CAIN B,'; ;SEMI-COLON IS SEPARATOR + JRST LFCHR3 + CAIN B,': ;COLON IS QUOTE + ILDB B,A + ADDI B,40 ;CONVERT TO ASCII + IDPB B,LFBPTR + SOJ C, + SOJG E,LFCHR1 +LFCHR3: IDPB D,LFBPTR + MOVEI D,BLANK + SOJ C, + JRST LFCH00 +LFCHR4: JUMPLE C,.+3 + IDPB D,LFBPTR + SOJG C,.-1 + POP P,D + POP P,C + JRST LFCHR9 + +LFFILE: ;OUTPUT INFORMATION FOR A REAL FILE. +;OUTPUT STAR IF OPEN FOR WRITING, DELETED, ETC. + MOVEI B,BLANK + MOVE A,UNRNDM(C) + TLNE A,UNIGFL + MOVEI B,"* + IDPB B,LFBPTR +;OUTPUT PACK NUMBER. + MOVEI B,BLANK + IDPB B,LFBPTR + LDB A,[UNPKN A] ;GET PACK NUMBER + IDIVI A,10. + ADDI A,"0 + ADDI B,"0 + CAIE A,"0 + JRST LFPAK1 + MOVEI A,(B) ;USE "3 " INSTEAD OF "03". + MOVEI B,BLANK +LFPAK1: IDPB A,LFBPTR + IDPB B,LFBPTR + MOVEI B,BLANK + IDPB B,LFBPTR + IDPB B,LFBPTR +;OUTPUT FILE NAMES + MOVE A,UNFN1(C) + PUSHJ P,LF6BIT + IDPB B,LFBPTR + MOVE A,UNFN2(C) + PUSHJ P,LF6BIT +;OUTPUT FILE LENGTH AS NNN+NNN + MOVEI A,BLANK + IDPB A,LFBPTR + HLRZ A,C ;GET FILE LENGTH + MOVE A,0(A) + IDIVI A,2000 + PUSH P,C + MOVEI C,3 + PUSHJ P,LFJUST + POP P,C + PUSHJ P,LFDEC + JUMPE B,LFLENX + PUSH P,C + MOVE A,B + MOVEI C,4 + PUSHJ P,LFJUST + MOVEI B,"+ + IDPB B,LFBPTR + POP P,C + PUSHJ P,LFDEC +LFLENX: +;OUTPUT REAP AND DUMP BITS + MOVEI A,29. + PUSHJ P,LFHPOS + MOVEI A,BLANK + MOVE B,UNRNDM(C) + TLNN B,UNDUMP + MOVEI A,"! + IDPB A,LFBPTR + MOVEI A,BLANK + TLNE B,UNREAP + MOVEI A,"$ + IDPB A,LFBPTR +;OUTPUT CREATION DATE + MOVE A,UNDATE(C) + PUSHJ P,LFDATE ;CREATION DATE + JRST LFCHR9 ;NO CREATION TIME. +;OUTPUT CREATION TIME. + MOVEI A,BLANK + IDPB A,LFBPTR + HRRZ B,UNDATE(C) + PUSH P,C + LSH B,-1 + IDIVI B,10. + PUSH P,C + IDIVI B,6 + PUSH P,C + IDIVI B,10. + PUSH P,C + IDIVI B,6 + PUSH P,C + IDIVI B,10. + PUSH P,C + PUSH P,B + MOVEI B,2 +LFF1: POP P,A + ADDI A,"0 + IDPB A,LFBPTR + POP P,A + ADDI A,"0 + IDPB A,LFBPTR + MOVEI A,": + SKIPE B + IDPB A,LFBPTR + SOJGE B,LFF1 + POP P,C + +LFCHR9: MOVEI A,49. + PUSHJ P,LFHPOS + MOVEI A,BLANK ;REFERENCE DATE. + IDPB A,LFBPTR + PUSH P,LFBPTR + MOVE A,UNREF(C) + PUSHJ P,LFDATE + JFCL + MOVEI A,"( + MOVE B,(P) + ILDB B,B + CAIN B,BLANK + IBP (P) + DPB A,(P) + POP P,B + MOVEI A,") + IDPB A,LFBPTR +;OUTPUT AUTHOR + JUMPE AUTHFL,LFEND ;UNLESS NO AUTHORS ON THIS DEVICE + LDB B,[UNAUTH+UNREF(C)] + JUMPE B,LFEND + MOVEI A,BLANK + IDPB A,LFBPTR + CAIN B,777 ;RANDOM AUTHOR + JRST AUTRAN + LSH B,1 + ADDI B,MFDBFR+2000 + SUB B,MDNUDS+MFDBFR + SUB B,MDNUDS+MFDBFR + MOVE A,(B) + CAMN A,DIRECT ;DON'T PRINT IF AUTHOR IS DIR NAME + JRST LFEND + PUSHJ P,LF6BIT + JRST LFEND +AUTRAN: MOVEI A,[ASCIZ /???/] + PUSHJ P,LFASCZ + +LFEND: MOVEI A,15 + IDPB A,LFBPTR + MOVEI A,12 + IDPB A,LFBPTR + AOBJN D,LFNEXT ;LOOP. +LFDONE: MOVEI A,3 ;EOF CHAR. +LFDON1: IDPB A,LFBPTR + TLNE LFBPTR,760000 + JRST LFDON1 ;FILL OUT LAST WORD. + POPJ P, + + +LFDATE: CAMN A,[-1] + JRST LFNDAT + PUSH P,C + MOVEI C,BLANK + PUSH P,B + MOVE B,A + LDB A,[UNMON B] + CAIG A,9 + IDPB C,LFBPTR + PUSHJ P,LFDEC + MOVEI A,"/ + MOVEI C,"0 + IDPB A,LFBPTR + LDB A,[UNDAY B] + CAIG A,9 + IDPB C,LFBPTR + PUSHJ P,LFDEC + MOVEI A,"/ + IDPB A,LFBPTR + LDB A,[UNYRB B] + CAIG A,9 + IDPB C,LFBPTR + PUSHJ P,LFDEC + POP P,B + POP P,C + AOS (P) + POPJ P, +LFNDAT: MOVEI A,"- + IDPB A,LFBPTR + POPJ P, + +.END LISTF + +LFDEC: PUSH P,B ;OUTPUTS NUMBER + PUSH P,[-1] + IDIVI A,10. + PUSH P,B + JUMPN A,.-2 +LFDEC1: POP P,A + JUMPL A,LFDEC2 + ADDI A,"0 + IDPB A,LFBPTR + JRST LFDEC1 +LFDEC2: POP P,B + POPJ P, + +LF6BIT: PUSH P,B ;MAY NOT CLOBBER ANYTHING. + PUSH P,C + MOVEI C,6 +LF6BL: SETZM B + ROTC A,6 + ADDI B,40 + IDPB B,LFBPTR + SOJG C,LF6BL + POP P,C + POP P,B +POPJ.P: POPJ P, + +LFASCZ: ;Output an asciz string. + HRLI A,440700 ;Make input byte pointer. + ILDB R0,A + JUMPE R0,POPJ.P + IDPB R0,LFBPTR + JRST .-3 + +LFJUST: PUSH P,B ;OUTPUT C-(NUMBER OF CHARS NEEDED TO PRINT A) SPACES + PUSH P,A + IDIVI A,10. + SOJ C, + JUMPN A,.-2 + JUMPLE C,LFJST1 + MOVEI A,BLANK + IDPB A,LFBPTR + SOJG C,.-1 +LFJST1: POP P,A + POP P,B + POPJ P, + +LFHPOS: ;Move to specified character position. + PUSH P,B + IDIVI A,5 + ADD A,ILFBPT + JUMPE B,.+3 + IBP A + SOJN B,.-1 + MOVEI B,BLANK + CAMN A,LFBPTR + JRST LFHP0 + IDPB B,LFBPTR + CAME A,LFBPTR + JRST .-2 +LFHP0: POP P,B + POPJ P, + + +CONST: CONSTA +PAT: PATCH: BLOCK 100 +PATCHE: -1 + +END START