TITLE New Archive Salvager -- MARC (8/18/76) A=1 B=2 C=3 D=4 E=5 F=6 G=7 H=10 I=11 J=12 K=13 Q=15 R=16 P=17 ARCIN==0 ARCOUT==1 TTYO==3 TTYI==4 LPDL==100 DIRLEN=2000+6+199. ;TTYCOM HACKS %TOERS==40000 ; system symbol for erasable display %TOSAI==4000 ; " " " sail character set %TIDIS==4000 ; display mode ;UFD INFO ;USER DIR IN TRACK NUMBERED SAME AS INDEX IN MFD (SEE QFL2) NUDSL==200. ;# UFDS SPACE RESERVED UFDBYT==6 ;SIZE OF BYTES UFDBPW==36./UFDBYT ;NUMBER OF BYTES PER WORD ;RANDOM INFO ARCTYP==0 ;-1=>NEW ARCHIVE, OTHERWISE OLD FORMAT UDESCP==1 ;FS PNTR TO DESC AREA UDNAMP==2 ;PNTR TO ORG OF NAME AREA GCTAG==3 ;DATE/TIME OF LAST GARBAGE COLLECT UDDESC==11. ;FIRST LOC AVAIL FOR DESC ;UFD DESCRIPTORS ;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) ;IF LINK DESCR ;6 CHAR OR UNTIL ; = SYS NAME. MUST HAVE NO CHAR = 0 IN THIS OR NEXT 2 NAMES ;NEXT CHAR QUOTED BY : (FOR NAMES WITH : OR ;) ;NEXT CHAR N1 ;NEXT CHAR N2 ;END BY 0 UDTKMX==12. ;HIGHEST "TAKE N" CODE UDWPH==31. ;PLACE HOLDER ON WRITE (OR NULL FILE) ; NXLBYT==2 ;# ADDITIONAL BYTES FOR LOAD ADDR ;ACTUAL PARAMETER ASSIGN MUST BE AT FRONT OF FILE ;NAME AREA DATA LUNBLK==5 ;WDS/NAME BLK UNFN1==0 ;FIRST FN UNFN2==1 ;SECOND FN UNRNDM==2 ;ALL KINDS OF RANDOM INFO UNDSCP==1500,, ;PNTR TO DESC UNPKN==150500,, ;PACK # UNBOJN==150500,, ;BOJ # ON LAST WRITE UNLINK==1 ;LINK BIT UNLNKB==220100,, UNWRIT==4 ;OPEN FOR WRITING UNMARK==10 ;GC MARK BIT UNCDEL==20 ;DEL WHEN CLOSED UNPDEL==40 ;DEL FROM UNMOUNTED PACK UNDS1==100000 ;HAS BEEN HALF DELETED AND HAS 1 STRIKE UNHD==200000 ;HAS BEEN HALF DELETED DELBTS==UNCDEL+UNPDEL+UNHD ;DELETED -- IGNORE UNIGFL==DELBTS+UNWRIT ;BITS TO IGNORE FILE UNWRDC==301200,, ; WORD COUNT OF LAST BLOCK MOD 2000 UNDUMP==400000 ;HAS BEEN DUMPED UNDATE==3 ;DATE ETC. UNTIM==2200,, ;COMPACTED TIME OF CREATION UNYMD==222000,, ;Y,M,D OF CREATION UNMON==270400,, ;MONTH UNDAY==220500,, ;DAY UNYRB==330700,, UNREF==4 ; REFERENCE DATE SAME AS LEFT HALF OF UNDATE ; ARCHIVE FORMAT ; FIRST BLOCK LOOKS ALMOST EXACTLY LIKE A DISK DIRECTORY EXCEPT FOR ; THE FIRST FOUR WORDS: ; WORD 0 - ALWAYS -1 TO DISTINGUISH FROM OLD ARCHIVES ; WORD 1 - "UDNAMP" RELATIVE POINTER WITHIN DIRECTORY TO ; START OF FIRST NAME AREA BLOCK ; WORD 2 - "UDESCP" BYTE NUMBER OF NEXT AVAILABLE BYTE IN ; DESCRIPTOR AREA ; WORD 3 - GC TAG - SYSTEM PACKED DATE/TIME OF LAST REARRANGEMENT ; OF DIRECTORY (E.G. DELETION, INSERTION, GARBAGE COLLECTION) ; ONLY OTHER DIFFERENCE FROM STANDARD DISK DIRECTORY IS IN 5TH WORD ; OF EACH NAME BLOCK. DISK USES LEFT HALF FOR REFERENCE DATE, DOESN'T ; USE RIGHT HALF. ARC USES LEFT HALF FOR REFERENCE DATE, USES RIGHT HALF ; FOR COUNT OF NUMBER OF OPENS FOR READING. ; SECOND BLOCK: ; WORD 2000 - ACCESS POINTER TO FIRST BLOCK IN FREE BLOCK CHAIN ; (0=>CHAIN IS EMPTY) ; WORD 2001 - NUMBER OF FREE WORDS IN ENTIRE ARCHIVE ; WORD 2002 - NUMBER OF FREE BLOCKS IN ENTIRE ARCHIVE ; WORD 2003 - NUMBER OF WORDS IN USE IN ENTIRE ARCHIVE ; WORD 2004 - NUMBER OF BLOCKS IN USE IN ENTIRE ARCHIVE ; WORD 2005 - RELATIVE POINTER (RELATIVE TO 2005) TO NEXT AVAILABLE ; FBAT ENTRY (0=>FBAT IS FULL) ; WORDS 2006-<2005+200.> - THE FBAT - EACH ENTRY POINTS TO ; THE FIRST DATA BLOCK IN A FILE. ; WORDS <2005+200.>-EOF - DATA BLOCKS ; A DATA BLOCK: ; HEADER - 4.9 BIT - 1=>BLOCK IS FREE ; 4.8 BIT - 1=>LAST BLOCK IN FILE CHAIN ; 4.9,4.8 BITS BOTH 1 => SINGLE WORD OF GARBAGE ; 4.7 BIT - UNUSED ; 4.6-3.6 - LENGTH-1 OF DATA AREA (NOT INCLUDING HEADER AND TRAILER) ; 3.4-1.1 - DISK ADDRESS OF NEXT DATA BLOCK IN THE CHAIN ; TRAILER - IDENTICAL TO HEADER EXCEPT ; 3.4-1.1 - DISK ADDRESS OF PREVIOUS DATA BLOCK IN THE CHAIN LOC 42 JSR TSINT LOC 100 START: MOVE P,[-LPDL,,PDL] PUSHJ P,TTYOPN .BREAK 12,[5,,COMMND] OASCR [ASCIZ /Archive Salvager/] SKIPE COMMND JRST ARCLP1 ARCLP: MOVE P,[-LPDL,,PDL] OASC [ASCIZ /*/] MOVEI D,ARCIN PUSHJ P,GETLIN JRST .+2 ARCLP1: SETOM JCLHAK PUSHJ P,NMFLS MOVE E,[440700,,COMMND] PUSHJ P,FPARSS MOVEI D,ARCOUT PUSHJ P,FPARSS SKIPN DIRECT(D) JRST [MOVE A,DIRECT MOVEM A,DIRECT(D) JRST .+1] SKIPN FNAME1(D) JRST [MOVE A,FNAME1 MOVEM A,FNAME1(D) SETZ D, JRST .+1] MOVE A,[SIXBIT /QUIT/] CAMN A,FNAME1(D) .BREAK 16,40000 .CALL ARCOPN JRST ARCNFN .CALL FILLEN .VALUE TRC D,1 .CALL DSKOPN JRST OPNFAL PUSHJ P,ARCSAL .CLOSE ARCIN, .CLOSE ARCOUT, SKIPE JCLHAK FINIS: .BREAK 16,40000 JRST ARCLP ARCNFN: OASCR [ASCIZ /Archive not found?/] JRST ARCLP BLKTBG: OASCR [ASCIZ /Block too big?/] .VALUE OPNFAL: OASCR [ASCIZ /Output open failed?/] JRST ARCLP ARCSAL: MOVE A,[-DIRLEN,,ODIR] ;READ OLD DIRECT .IOT ARCIN,A SETZM NDIR ;ZERO OUT OLD MOVE A,[NDIR,,NDIR+1] BLT A,NDIR+DIRLEN-1 SETOM NDIR AOS NDIR+UDESCP MOVEI A,2000 MOVEM A,NDIR+UDNAMP SETOM NDIR+GCTAG MOVE A,[-198.,,2] ;SET UP FBAT HRRM A,NDIR+2004(A) AOBJN A,.-1 AOS NDIR+2005 MOVE A,[-2000,,NDIR] ;OUTPUT FIRST PART OF DIRECTORY .IOT ARCOUT,A ;OUTPUT DIRECT MOVEI A,DIRLEN MOVEM A,NHDPNT ANDI A,1777 AOS A MOVEM A,NRLPNT ;RELATIVE POINTER MOVEI A,2000 MOVEM A,BLKPOS MOVEI A,DIRLEN+1 MOVEM A,NACPNT MOVEI A,4000-DIRLEN-2 MOVEM A,NLEN SETZM CURLEN MOVEI Q,2000-5 ARCSA1: CAMGE Q,ODIR+UDNAMP JRST SALDON SKIPN UNFN1+ODIR(Q) SKIPE UNFN2+ODIR(Q) SKIPA JRST NEXFIL MOVE A,UNRNDM+ODIR(Q) TLNE A,64 JRST NEXFIL LDB A,[UNDSCP+ODIR+UNRNDM(Q)] PUSHJ P,GDESBT ADDI A,ODIR MOVEM A,OLDDBP MOVE B,A ILDB A,B SKIPN A JRST NEXFIL ;SKIP ZERO LENGTH FILES MOVE R,NDIR+UDNAMP SUBI R,5 MOVEM R,NDIR+UDNAMP HRLI A,ODIR(Q) HRRI A,NDIR(R) BLT A,NDIR+4(R) HLLZS NDIR+4(R) MOVE A,NDIR+UDESCP DPB A,[UNDSCP+NDIR+UNRNDM(R)] PUSHJ P,GDESBT ADDI A,NDIR MOVEM A,NEWDBP SETZM A ILDB B,OLDDBP DPB B,[140600,,A] ILDB B,OLDDBP DPB B,[060600,,A] ILDB B,OLDDBP DPB B,[000600,,A] TRZ A,400000 MOVE A,ODIR+2005(A) MOVEM A,OACPNT ;BEGINNING OF FIRST BLOCK CAML A,LENGTH JRST ARCSA3 MOVE A,NDIR+2005 ;GET NEXT FBAT ENTRY MOVEM A,CURFBT MOVE A,NDIR+2005(A) MOVEM A,NDIR+2005 MOVE A,CURFBT ADDI A,400000 ;FOR PROPPER DESC LDB B,[140600,,A] IDPB B,NEWDBP AOS NDIR+UDESCP LDB B,[060600,,A] IDPB B,NEWDBP AOS NDIR+UDESCP LDB B,[000600,,A] IDPB B,NEWDBP AOS NDIR+UDESCP ARCSA2: ILDB A,OLDDBP IDPB A,NEWDBP AOS NDIR+UDESCP SKIPE A JRST ARCSA2 PUSHJ P,FILCPY NEXFIL: SUBI Q,5 JRST ARCSA1 ARCSA3: PUSHJ P,FILLGP SETZM A DPB A,[UNDSCP+NDIR+UNRNDM(R)] JRST NEXFIL FILLGP: OASC [ASCIZ /î*** /] OSIX NDIR(R) MOVEI A,40 .IOT TTYO,A OSIX NDIR+1(R) MOVEI A,40 .IOT TTYO,A OASCR [ASCIZ /POINTS OUTSIDE OF ARCHIVE, FILE BEING TRUNCATED ***/] CPOPJ: POPJ P, SALDON: PUSHJ P,MAKFRE ;MAKE FREE CHAIN PUSHJ P,BLKFLS ;FLUSH OUT BLOCK .ACCESS ARCOUT,[0] MOVE A,[-DIRLEN,,NDIR] .IOT ARCOUT,A .CLOSE ARCOUT, POPJ P, MAKFRE: MOVE A,NLEN CAIN A,2000-2 POPJ P, ;NOTHING IN BLOCK. NO FREE CHAIN NEEDED ADDM A,NDIR+2001 AOS NDIR+2002 ;ONE MORE FREE BLOCK SOS B,A LSH B,27 TLO B,400000 ;MAKE IT A FREE BLOCK MOVE A,NHDPNT MOVEM A,NDIR+2000 ANDI A,1777 MOVEM B,NDATA(A) MOVEM B,NDATA+1777 AOS A,NLEN ADDM A,NRLPNT ADDM A,NACPNT POPJ P, BLKFLS: MOVE A,NRLPNT CAIN A,1 POPJ P, ;NOTHING WRITTEN MOVE A,[-2000,,NDATA] .IOT ARCOUT,A MOVE A,NACPNT MOVEM A,NHDPNT MOVEM A,BLKPOS SETZM NRLPNT AOS NRLPNT AOS NACPNT MOVEI A,2000-2 MOVEM A,NLEN SETZM CURLEN POPJ P, BLKGET: MOVE A,OACPNT TRZ A,1777 .ACCESS ARCIN,A MOVE A,[-2000,,ODATA] .IOT ARCIN,A MOVE A,OACPNT MOVEM A,OHDPNT ANDI A,1777 MOVEM A,ORLPNT MOVE A,ODATA(A) MOVEM A,OHEAD LDB B,[271200,,OHEAD] AOS B ;LENGTH OF BLOCK CAILE B,2000-2 JRST BLKTBG ;BLOCK TOO BIG MOVEM B,OLEN AOS ORLPNT AOS OACPNT POPJ P, FILCPY: SETZM LHDPNT MOVE A,NHDPNT MOVE B,CURFBT MOVEM A,NDIR+2005(B) ;SET STARTING LOCATION PUSHJ P,BLKGET FILCP1: SKIPN A,OLEN JRST FILCP2 CAMLE A,NLEN JRST FILCP3 MOVE B,ORLPNT MOVE C,NRLPNT HRLI D,ODATA(B) HRRI D,NDATA(C) ADDI C,-1(A) BLT D,NDATA(C) SETZM OLEN ADDM A,NRLPNT ADDM A,ORLPNT ADDM A,NACPNT ADDM A,OACPNT ADDM A,CURLEN MOVE B,NLEN SUB B,A MOVEM B,NLEN CAILE B,1 JRST FILCP1 PUSHJ P,MAKHED JRST FILCP1 FILCP2: MOVE A,OHDPNT ANDI A,1777 MOVE B,ODATA(A) TLNE B,200000 JRST FILCP4 ;END LDB B,[2700,,ODATA(A)] SKIPN B JRST FILCP4 ;POINTS TO 0 CAML B,LENGTH ;FILE TOO LONG JRST FILCP5 MOVEM B,OACPNT PUSHJ P,BLKGET JRST FILCP1 FILCP4: SKIPE CURLEN PUSHJ P,MAKHED POPJ P, FILCP5: PUSHJ P,FILLGP ;PRINT NAME OF TRUNCATED FILE JRST FILCP4 ;CONTINUE, SIMULATE EOF FILCP3: MOVE A,NLEN MOVE B,ORLPNT MOVE C,NRLPNT HRLI D,ODATA(B) HRRI D,NDATA(C) ADDI C,-1(A) BLT D,NDATA(C) SETZM NLEN ADDM A,NRLPNT ADDM A,ORLPNT ADDM A,NACPNT ADDM A,OACPNT ADDM A,CURLEN MOVE B,OLEN SUB B,A MOVEM B,OLEN PUSHJ P,MAKHED JRST FILCP1 MAKHED: MOVE A,CURLEN ADDM A,NDIR+2003 AOS NDIR+2004 ;ONE MORE DATA BLOCK SOS A LSH A,27 TLO A,200000 MOVE B,NHDPNT ANDI B,1777 MOVEM A,NDATA(B) MOVE C,LHDPNT DPB C,[2700,,A] MOVE C,NRLPNT MOVEM A,NDATA(C) MOVE B,LHEAD MOVE A,NHDPNT DPB A,[2700,,B] SKIPN A,LHDPNT JRST MAKHE1 PUSHJ P,HEDPUT MOVE B,LHEAD LDB A,[271200,,B] ADDI A,2 ADD A,LHDPNT PUSHJ P,HEDPUT MAKHE1: MOVE A,NHDPNT MOVEM A,LHDPNT MOVE A,NRLPNT MOVE A,NDATA(A) TLZ A,200000 MOVEM A,LHEAD AOS NACPNT AOS A,NRLPNT CAIN A,1777 PUSHJ P,ONEGAR SETZM CURLEN CAIN A,2000 JRST BLKFLS MOVE A,NACPNT MOVEM A,NHDPNT AOS NACPNT AOS NRLPNT SOS NLEN SOS NLEN POPJ P, ONEGAR: HRLZI B,600000 ;SINGLE QORD OF GARBAGE MOVEM B,NDATA+1777 AOS A,NRLPNT AOS NACPNT POPJ P, HEDPUT: CAMGE A,BLKPOS JRST HEDPU1 ANDI A,1777 MOVEM B,NDATA(A) POPJ P, HEDPU1: .ACCESS ARCOUT,A MOVE A,[-1,,B] .IOT ARCOUT,A .ACCESS ARCOUT,BLKPOS POPJ P, GDESBT: PUSH P,B IDIVI A,6 HLL A,IBTBL(B) ADDI A,UDDESC POP P,B POPJ P, IBTBL: 440600,,0 BTBL: 360600,,0 300600,,0 220600,,0 140600,,0 060600,,0 000600,,0 ODIR: BLOCK DIRLEN NDIR: BLOCK DIRLEN ODATA: BLOCK 2000 ;ONE BLOCKS WORTH NDATA: BLOCK 2000 ;ONE BLOCKS WORTH OF DATA SNAM: 0 JCLHAK: 0 CURFBT: 0 ;CURRENT FBAT POINTER NLEN: 0 ;NUMBER OF DATA WORDS THAT CAN BE STORED IN CURRENT BLOCK OLEN: 0 ;NUMBER OF DATA WORDS IN CURRENT BLOCK CURLEN: 0 ;NUMBER OF WORDS WRITTEN IN CURRENT BLOCK LENGTH: 0 ;LENGTH OF OLD ARCHIVE FILE OACPNT: 0 ;READ POINTER NACPNT: 0 ;NEW ACCESS POINTER OHEAD: 0 ;OLD HEADER NHEAD: 0 ;NEW HEADER LHEAD: 0 ;LAST HEADER OHDPNT: 0 ;OLD HEADER POINTER NHDPNT: 0 ;NEW HEADER POINTER LHDPNT: 0 ;LAST HEADER LOCATION BLKPOS: 0 ;ADDRESS OF BEGINNING OF BLOCK NRLPNT: 0 ;RELATIVE POINTER WITHIN CURRENT BLOCK ORLPNT: 0 ;SAME BUT FOR READING OLDDBP: 0 ;OLD DESC BYTE PNTR NEWDBP: 0 TTYIN: SIXBIT / TTY/ 0 0 TTYOUT: SIXBIT / !TTY/ 0 0 PDL: BLOCK LPDL COMMND: BLOCK 20 COMPTR: 0 GETLIN: SETZM COMMND MOVE [COMMND,,COMMND+1] BLT 0,COMMND+17 RCMD: MOVE B,[440700,,COMMND] MOVEM B,COMPTR MOVEI C,0 RCMD1: .IOT TTYI,A CAIN A,177 JRST RUB CAIN A,^D JRST RREPEA CAIN A,^L JRST RCLEAR CAIN A,^J JRST RCMD1 CAIN A,^M JRST RCMDX RCMDL: IDPB A,B CAMGE B,[350700,,COMMND+17] AOJA C,RCMD1 RCFUL: IDPB A,B MOVEI A,15 IDPB A,B RCMDX: IDPB A,B MOVEI A,0 IDPB A,B POPJ P, RREPEA: OASCR [0] JRST REPPER RCLEAR: OCTLP "C JUMPGE DIR,REPPER REPPER: OASCI "* OASC COMMND JRST RCMD1 RUB: PUSHJ P,RUBBER JRST RCMD JRST RCMD1 RUBBER: SOJL C,[POPJ P,] LDB D,B ; pick up dead character MOVEI A,0 DPB A,B ; smash it in buffer XCT XCTRUB ADD B,[070000,,] TLNE B,400000 ADD B,[347777,,-1] AOS (P) POPJ P, RUBECH: CAIN D,177 JRST [OASC [ASCIZ /^?/] POPJ P,] OASCI (D) POPJ P, RUBFLS: MOVE TTYOPT TLNE %TOSAI JRST RUBONE CAIN D,177 JRST RUBTWO CAIL D,40 JRST RUBONE CAIE D,33 CAIN D,10 JRST RUBONE CAIE D,^I CAIN D,^L JRST RUBONE RUBTWO: OCTLP "X ; controls that echo as ^x RUBONE: OCTLP "X POPJ P, ; TYPEOUT UUOS ZZZ==. LOC 40 0 JSR UUOH LOC ZZZ UUOCT==0 UUOTAB: JRST ILUUO IRPS X,,[ODEC OBPTR OOCT OCTLP OASCC OSIX OASC OASCI OASCR OSIXS] UUOCT==UUOCT+1 X=UUOCT_33 JRST U!X TERMIN UUOMAX==.-UUOTAB UUOH: 0 PUSH P,A PUSH P,B PUSH P,C MOVEI @40 ; get eff addr. of uuo MOVEM UUOE' MOVE @0 MOVEM UUOD' ; contents of eff adr MOVE B,UUOE ; eff adr LDB A,[270400,,40] ; get uuo ac, LDB C,[330600,,40] ; op code CAIL C,UUOMAX MOVEI C,0 ; grt=>illegal JRST @UUOTAB(C) ; go to proper rout UUORET: POP P,C POP P,B POP P,A ; restore ac's JRST 2,@UUOH ILUUO: .VALUE [ASCIZ /:ILLEGAL UUO/] UOBPTR: MOVEI C,0 MOVE B,@40 JRST UOASC1 UOASCR: SKIPA C,[^M] ; cr for end of type UOASC: MOVEI C,0 ; no cr HRLI B,440700 ; make ascii pointer UOASC1: ILDB A,B ; get char JUMPE A,.+3 ; finish? PUSHJ P,IOTA JRST .-3 ; and get another SKIPE A,C ; get saved cr? PUSHJ P,IOTA JRST UUORET UOASCC: HRLI B,440700 ; make ascii pointer UOAS1C: ILDB A,B ; get char CAIN A,^C JRST UUORET PUSHJ P,IOTA JRST UOAS1C ; and get another UOCTLP: MOVEI A,^P PUSHJ P,IOTA1 UOASCI: MOVE A,B ; prt ascii immediate PUSHJ P,IOTA JRST UUORET UOSIX: MOVE B,UUOD USXOOP: JUMPE B,UUORET LDB A,[360600,,B] ADDI A,40 PUSHJ P,IOTA LSH B,6 JRST USXOOP UOSIXS: MOVE A,[440600,,UUOD] USLOOP: ILDB C,A ADDI C,40 PUSHJ P,IOTC TLNE A,770000 JRST USLOOP JRST UUORET UODEC: SKIPA C,[10.] ; get base for decimal UOOCT: MOVEI C,8. ; octal base MOVE B,UUOD ; get actual word to prt JRST .+3 ; join code UODECI: SKIPA C,[10.] ; decimal UOOCTI: MOVEI C,8. MOVEM C,BASE' SKIPN A HRREI A,-1 ; a=digit count PUSHJ P,UONUM ; print numbr JRST UUORET UONUM: IDIV B,BASE HRLM C,(P) ; save digit SOJE A,UONUM1 ; done if 0 SKIPG A ; + => more SKIPE B ; - => b=0 => done PUSHJ P,UONUM ; else more UONUM1: HLRZ C,(P) ; retreive digits ADDI C,"0 ; make to ascii CAILE C,"9 ; is it good dig ADDI C,"A-"9-1 ; make hex digit PUSHJ P,IOTC POPJ P, ; ret IOTC: PUSH P,A MOVE A,C PUSHJ P,IOTA JRST POPAJ IOTA: CAIN A,^P JRST IOTAP IOTA1: CAIN A,^J JRST .+3 .IOT TTYO,A CAIE A,^M POPJ P, POPJ P, IOTAP: .IOT TTYO,["^] ADDI A,100 JRST IOTA1 POPAJ: POP P,A POPJ P, ;ROUTINE TO PARSE FILE NAMES (FROM SHARER) NAME: 0 ENDSW: 0 DEVICE: SIXBIT /DSK/ SIXBIT /DSK/ FNAME1: 0 0 FNAME2: SOJ SOJ DIRECT: 0 0 NMFLS: MOVE A,[SIXBIT /DSK/] MOVEM A,DEVICE MOVEM A,DEVICE+1 SETZM ENDSW SETZM FNAME1 SETZM FNAME1+1 SETZM DIRECT+1 .SUSET [.RSNAM,,DIRECT] MOVE A,[SIXBIT />/] MOVEM A,FNAME2 MOVEM A,FNAME2+1 POPJ P, FPARSS: SETZM ENDSW FPARSE: SETZM NAME ;CLEAR NAME SLOT SKIPE ENDSW POPJ P, MOVE F,[440600,,NAME] GETCHR: ILDB B,E ;FIND NEXT NON-EMPTY CHARACTER JUMPE B,CPOPJ CAIE B,40 CAIN B,^I JRST GETCHR FIELD: CAIE B,40 ;HERE TO GET A NAME CAIN B,^I JRST FNAM ;SPACE AND TAB MAKE FNAME1 AND 2 CAIE B,0 CAIN B,^M JRST FNAM ;SO DOES 0 AND CAIE B,", CAIN B,"_ JRST [SETOM ENDSW JRST FNAM] CAIN B,": JRST DEV ;DEVICE NAME CAIN B,"; JRST DIR ;SNAME CAIN B,^Q ;HANDLE QUOTING ILDB B,E CAIGE B,40 ;SUBI B,40 < 0 (BAD CHARACTER) JRST ILLCHR SUBI B,40 CAIL B,100 SUBI B,40 ;CASE CONVERSION TLNE F,770000 ;IGNORE MORE THAN 6 CHARACTERS IDPB B,F FPARS2: ILDB B,E JRST FIELD DEV: MOVE A,NAME ;SAVE DEVICE MOVEM A,DEVICE(D) JRST FPARSE DIR: MOVE A,NAME ;SAVE SNAME MOVEM A,DIRECT(D) JRST FPARSE FNAM: MOVE A,NAME JUMPE A,FPARSE SKIPE FNAME1(D) ;DOES HE HAVE AN FNAME1 ALREAD? JRST FNAM1 ;YES - OOPS. HE IS GIVING TWO NAMES MOVEM A,FNAME1(D) ;NO - TRY IT AS FNAME1 JRST FPARSE FNAM1: MOVEM A,FNAME2(D) ;PUT NEW NAME INTO FNAME2 JRST FPARSE ILLCHR: OASC [ASCIZ /Illegal character in file name /] OASCI (B) OASCR [ASCIZ / /] POP P, JRST ARCLP ARCOPN: SETZ SIXBIT /OPEN/ MOVSI 6 MOVEI ARCIN DEVICE(D) FNAME1(D) FNAME2(D) SETZ DIRECT(D) DSKOPN: SETZ SIXBIT /OPEN/ MOVSI 7 MOVEI ARCOUT DEVICE(D) FNAME1(D) FNAME2(D) SETZ DIRECT(D) RCHST: SETZ SIXBIT /RCHST/ D MOVEM DEVICE(D) MOVEM FNAME1(D) MOVEM FNAME2(D) SETZM DIRECT(D) FILLEN: SETZ SIXBIT /FILLEN/ MOVEI ARCIN SETZM LENGTH TTYSET: SETZ ;BLOCK FOR CALL TO TTYSET SIXBIT /TTYSET/ 1000,,TTYI [222222,,222222] [232222,,220222] SETZ [0] TSINT: 0 ;HERE TO CATCH INT. CHARS 0 MOVEI 0,TTYI .ITYIC 0, .VALUE CAIN 0," JRST FINIS .DISMIS TSINT+1 TTYOPN: .CALL [SETZ SIXBIT "OPEN" [TTYI] [SIXBIT "TTY"] [SIXBIT "DIRED"] [SIXBIT "INTTY"] SETZB LSTERR] .VALUE [ASCIZ /:CAN'T OPEN IN TTY/] .CALL [SETZ SIXBIT "OPEN" [4001,,TTYO] ; display mode == %TIDIS [SIXBIT "TTY"] [SIXBIT "DIRED"] [SIXBIT "OUTTTY"] SETZB LSTERR] .VALUE [ASCIZ /:CAN'T OPEN OUT TTY/] .CALL [SETZ 'CNSGET [TTYO] MOVEM ; vsize MOVEM ; hsize MOVEM ; tctyp MOVEM ; ttycom MOVEM TTYOPT' SETZB LSTERR'] .VALUE [ASCIZ /:CANT GET CONSOLE TYPE/] .SUSET [.SIMSK2,,[20]] .CALL TTYSET ;SET UP TTY TO TAKE CONTROL-S AND G .VALUE MOVE A,TTYOPT ; setup rubout hackery MOVE [PUSHJ P,RUBECH] TLNE A,%TOERS MOVE [PUSHJ P,RUBFLS] MOVEM XCTRUB' POPJ P, END START