;-*-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,51. 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] ADDI A,1900. 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