diff --git a/build/misc.tcl b/build/misc.tcl index 91ed65a7..c4f46fe5 100644 --- a/build/misc.tcl +++ b/build/misc.tcl @@ -1654,6 +1654,10 @@ expect ":KILL" respond "*" ":palx inquir\r" expect ":KILL" +# DIRED for SITS. +respond "*" ":palx dired\r" +expect ":KILL" + # SLOGO, 11LOGO for SITS. respond "*" ":cwd nlogo\r" respond "*" ":palx slogo_@slogo\r" diff --git a/build/timestamps.txt b/build/timestamps.txt index 81ac766f..cc80b180 100644 --- a/build/timestamps.txt +++ b/build/timestamps.txt @@ -1923,6 +1923,7 @@ sits/bigf.7 197703090139.50 sits/bigf.ast 197507300444.54 sits/conven.3 197503051957.44 sits/ddt.73 197706301928.57 +sits/dired.2 197806041838.00 sits/docum.66 197607010317.17 sits/fnt.8 197705191238.47 sits/inquir.30 197603212234.51 diff --git a/src/sits/dired.2 b/src/sits/dired.2 new file mode 100755 index 00000000..3c655ed8 --- /dev/null +++ b/src/sits/dired.2 @@ -0,0 +1,2027 @@ +.TITLE DIRED +VERN==%FNAM2 ;DIRED VERSION NO. + +.MACRO DCS NAME,VAL +NAME==VAL +.ENDM + +.INSRT SITS;SITSS SYMS +.INSRT SITS;SITMAC > + + +.DLPAG==-3 ;DELETE PAGE, FOR $MAP SYSTEM CALL +BLKLN==2000 ;1 BLOCK = 2000 BYTES (OCTAL) +LINBFL==100. ;LINBUF LENGTH +NAMELN==52. ;NAME LENGTH IN CHAR'S + +;SET UP P-PDL +PPDLL==400 ;LENGTH OF PDL + .=.+PPDLL +IP=. + +;SET UP PATCH AREA +PATCH:PAT: .=.+200 + +;MEMORY PAGING PARAMETERS +DIRPG==5 ;PAGE TO MAP DIR. INTO +DIRPAD==DIRPG*20000 ;DIRPG ADDR + + +;DISK PARAMETERS +NDISKS==4 ;MAX NUMBER OF DISKS +MXNAME==10. ;MAX LENGTH OF NAME IN WORDS +DNAME: .BLKW 5 ;BITS, LENGTH, DATE, TIME +DNAM: .BLKW MXNAME ;ACTUAL NAME +DNAMEP: .REPT NDISKS ;NDISKS IS MAX NUBMER OF DISKS + DNAMES+<.RPCNT*MXNAME*2> + .ENDR + 0 ;ARRAY TERMINATES WITH A 0 POINTER +DNAMES: .BLKW MXNAME*NDISKS +DISKS: 0 ;NUMBER OF DISKS + +;CAPABILITIES +TTYCAP: 0 ;TTY +FRMCAP: 0 ;SOURCE DIRECTORY +TOCAP: 0 ;DESTINATION DIRECTORY +TMPCAP: 4 ;TEMPORARY +SRCCAP: 0 ;SOURCE FILE +DSTCAP: 0 ;DESTINATION FILE +CRTCAP: 0 ;CURRENT ROOT + +;PARAMETERS RELATED TO DIRECTORY ENTRIES +VERNO: 0 ;VERSION NUMBER +ENTTYP: -1 ;ENTRY TYPE +ENTLN: 0 ;ENTRY LENGTH +ABSEOF: 0 ;ABSOLUTE ADDR OF END OF COMPLETE DIR. + +;MISC. STORAGE +TMPWRD: 0 ;TEMPORARY STORAGE +RCURDP: 0 ;RECURSION DEPTH COUNTER (FOR TREES) +RESTRT: 0 ;RESTART PROGRAM SWITCH +TREE: 0 ;TREE STRUCTURE INDICATOR +DATE: 0 +TIME: 0 + +;ADDRESS CALCULATION PARAMETERS +OFFSET: 0 ;OFFSET INTO DISPATCH TABLE +DRDONE: 0 ;FOR ADDR. OF ROUTINE TO EXEC. WHEN DONE WITH INFERIOR DIR. +RTINE: 0 ;FOR ADDR. OF ALTERNATIVE ROUTINE TO EXECUTE +CROUT: 0 ;FOR ADDR. OF NCVT OUTPUT ROUTINE +XROUT: 0 ;FOR ADDR. OF CREATE FUNCTION + + +;MISC. BUFFERS +FILBLK: .BLKW 20 ;PLACE TO PUT FILE BLOCK FOR .FARI +IOBUF: .BLKB BLKLN ;I/O BUFFER +LINBUF: .BLKB LINBFL ;BUFFER TO CONTAIN CHAR'S FROM TTY +NAMBUF: .BLKB NAMELN ;NAME BUFFER + + +.STITLE COMMAND TABLE + + +;USED TO EXPAND COMMAND TABLE +.MACRO CMD CMD,ADDR + .ASCIZ ÃMDŠ .EVEN + .IF B ADDR + .IF DF CMD + CMD + .IFF + NOCMD + .ENDC + .IFF + .IF DF ADDR + ADDR + .IFF + NOCMD + .ENDC + .ENDC +NCMDS==NCMDS+1 +.ENDM +NCMDS==0 + + +CMDTAB: CMD ?,HELP + CMD HELP + CMD INFORMATION,INFO + CMD INFO + CMD INFO1 + CMD INFO2 + CMD INFO3 + CMD QUIT + CMD Q,QUIT + CMD GOODBYE,QUIT + CMD ATTACH + CMD AT,ATTACH + CMD A,ATTACH + CMD COPYFILE + CMD CF,COPYFI + CMD COPYTREE + CMD CT,COPYTREE + CMD MERGE,COPYTREE + CMD POFILE + CMD POF,POFILE + CMD POINDEX,POI + CMD POI + CMD POTREE + CMD POT,POTREE + CMD CRTDIR,CRD + CMD CRD + CMD CRTFILE,CRF + CMD CRF + CMD DLTFILE + CMD DF,DLTFILE + CMD DLTREE + CMD DT,DLTREE + CMD DLTDIR,DLTREE + CMD DD,DLTREE + CMD SUPRDL + + + +.STITLE DISPATCH TABLE + +;DEPENDS ON ENTRY TYPE + ;TYPES ARE AS GIVEN IN THE FIRST GROUP OF ROUTINES; I.E, 0-16 +;COMMENTS GIVE DISPLACEMENT FROM BEGINNING OF TABLE + +;PRINT OUT DIRECTORY ROUTINES +DISPCH: +POROUT: PODIRP ;0: PARENT + PODIRD ;2: DIRECTORY + PODIRF ;4: FILE + PODIRL ;6: NOT IMPLEMENTED (N.I.) + PODIRS ;10; SELF + PODIRL ;12; N.I. + PODIRL ;14; N.I. + PODIRL ;16; N.I. + +;DELETE TREE ROUTINES +DTROUT: DELDRP ;20: PARENT + DELDRD ;22: DIRECTORY + DELDRF ;24: FILE + PODIRL ;26: N.I. + DELDRS ;30: SELF + PODIRL ;32: N.I. + PODIRL ;34: N.I. + PODIRL ;36: N.I. + +;COPY TREE ROUTINES +CTROUT: COPTRP ;40: PARENT + COPTRD ;42: DIRECTORY + COPTRF ;44: FILE + PODIRL ;46: N.I. + COPTRS ;50: SELF + PODIRL ;52: N.I. + PODIRL ;54: N.I. + PODIRL ;56: N.I. + + + + + + +.STITLE MACROS + + +;FOR BOTH ERROR AND NON-ERROR CONDITIONS +.MACRO ERRORF TEXT,DELCPS,ROUTIN + ERR FERROT,,,ROUTIN +.ENDM + + +;FOR ERROR CONDITIONS +.MACRO ERROR TEXT,DELCPS,ROUTIN + ERR ERRROT,,,ROUTIN +.ENDM + + +;USED BY BOTH OF THE ABOVE +;E MAY CONTAIN ROUTIN ARG +.MACRO ERR ROT,TEXT,DELCPS,ROUTIN + JSR F,ROT + .ASCIZ ÔEXTŠ .EVEN + .IRP CAP, + CAP + .ENDM + .WORD 0 + .IIF NB ROUTIN, .WORD ROUTIN + .IIF B ROUTIN, .WORD 0 +.ENDM + + +;USED TO TYPE TEXT SPECIFIED IN PROGRAM +.MACRO TYPE TEXT + JSR E,TYPES + .ASCIZ ÔEXTŠ .EVEN +.ENDM + + + + +;TYPE TEXT SPECIFIED IN PROGRAM, EACH LINE FOLL. BY C.R. +.MACRO T TEXT + JSR E,TYPES + .ASCIZ ÔEXT‰;NOTE: "¢ IS "META&RUBOUT" ON KBD + .EVEN + JSR PC,CRLF +.ENDM + + + + + .STITLE INITIALIZATION ROUTINES + +;GET INITIAL CRTCAP (& TMPCAP) +INITCP: SAVE <#0,TMPCAP,#<.SPRCP*400>+1> + $INVOK ;READ THE C-LIST AT 4 (DEFAULT DIR) + TST (P)+ ;IS ANYTHING THERE? + BNE HAVDEF ;YES, WE HAVE A DEFAULT DIR. + SAVE <#-1,#0,#.CPYCP+10> ;NO DEFAULT DIRECTORY, + $INVOK ;SO USE ROOT CAP FOR DISK 0 + REST TMPCAP +HAVDEF: SAVE <,,TMPCAP> + BIS #.FADI,(P) ;WANT TO GET DISK NUMBER + $INVOK + REST ;DISK NUMBER IS SECOND ON STACK + ADD #10,A ;CONVERT TO ROOT CAP NUMBER + MOV A,CRTCAP ;THIS IS THE DEFAULT ROOT + RTS PC + +;READ ALL DISK ROOT DIR. NAMES INTO DNAMES BUFFER +DSKNAM: MOV #10,C ;FIRST DISK CAP + CLR A +DSKNM1: SAVE <#DNAME,#<5+MXNAME>*2,C> + BIS #.FARI,(P) ;WANT TO GET DISK NAME + .INVOK ;.FARI PUTS 0 BYTE AT END OF NAME + BEQ OPNDON ;IF IT FAILS WE MUST BE DONE + INC DISKS ;ONE MORE DISK + MOV DNAMEP(A),E ;POINTER TO NAME BLOCK + MOV #DNAM,F ;POINTER TO NAME READ IN +1$: MOVB (F)+,(E)+ + BNE 1$ + TST (A)+ ;INCREMENT NAME POINTER + INC C ;POINT TO THE NEXT CAPABILITY + BR DSKNM1 +OPNDON: CLR (A) ;TERMINATE DISKS + ADD #6,P ;FIX PDL + RTS PC + + + .STITLE PROGRAM ENTRY POINT + +START: MOV #IP,P ;INIT. PDL +;IF ALREADY STARTED ONCE, SKIP INITIALIZATION + TST RESTRT + BNE 1$ ;POSITIVE IF PROG. HAS BEEN STARTED + + MOV PC,RESTRT ;MAKE POSITIVE +;INITIALIZATION + MOV #3,TTYCAP ;PRIMARY I/O CAPABILITY + SAVE <,#.TIMGI!.TICVM!.TICTM,TTYCAP> ;SET TTY MODE TO: + MOVB #.TTMOV,1(P) ;IMAGE MODE, CVT TO UPPER CASE, CONTROL MODE (CTL Z) + $INVOK + +;TMPCAP ALREADY SET UP + JSR PC,INITCP ;GET INITIAL ROOT DIR. CAP + MOV TMPCAP,FRMCAP ;DEFAULT SOURCE CAP + MOV TMPCAP,A ;SET UP FOR SUBROUT. + JSR PC,COPCP1 ;COPY CAP WITHOUT DELETING TMPCAP + MOV TMPCAP,TOCAP ;DEFAULT DESTINATION CAP + CLR TMPCAP ;PREVENT CAP FROM BEING DELETED BY CLOOP + + JSR PC,DSKNAM ;READ IN ALL DISK ROOT DIR NAMES + JSR PC,CRLF ;START NEW LINE + TYPE ;PRINT PROG. NAME & VERSION NO. + MOV #VERN,A + JSR PC,PRDN ;PRINT AS DECIMAL NO. + JSR PC,CRLF +1$: JMP CLOOP ;PROCESS ALL COMMANDS + + + +.STITLE MAIN COMMAND LOOP + + +;GET A LINE OF INPUT FROM TTY, STRIP OFF COMMAND & BRANCH TO EXECUTE IT +;ON EXIT, E POINTS TO FIRST NON-BLANK CHAR AFTER COMMAND + + +CLOOP: JSR PC,FSHTMP ;FLUSH (DELETE & CLEAR) TMPCAP + MOV #DSTCAP,A ;FORCE WRITE OF LAST BLK AFTER COPY A FILE (FREAD) + JSR PC,FSHCAP ;FLUSH DSTCAP + CLR RCURDP ;RE-INITIALIZE RECURDION DEPTH + CLR VERNO ;RE-INIT. VERSION NO. + CLR ABSEOF ;RE-INIT. END-OF-FILE ADDR + MOV #-1,ENTTYP ;RE-INIT. ENTRY TYPE + + MOV #'>,A ;PROMPT CHAR IS ">" + JSR PC,TYO + JSR PC,GETLIN ;PTR TO BEG OF LINE RET. IN E; PTR TO END IN D + JSR PC,NULSTR ;ELIM. LEADING BLANKS (PASS E & D) + BEQ CLOOP ;Z SET IF NULL STRING + +;DETERMINE WHICH COMMAND USER HAS TYPED + MOV #NCMDS,A ;NUMBER OF COMMANDS + MOV #CMDTAB,B ;B <- PTR TO COMMAND TABLE +;COMMANDS TERM. BY: GETLIN- BLANK; CMDTAB- 0 +CMDLOP: MOV E,C ;C <- PTR INTO GETLIN +CMDLO3: CMPB (B)+,(C)+ ;CMDTAB CHAR:GETLIN CHAR + BNE CMDLO1 ;BRANCH IF MISMATCH + TSTB (B) ;END OF CMD NAME? (CHECK FOR 0) + BNE CMDLO2 ;NO, MAYBE THIS CMD + CMPB #40,(C) ;IS THE CHAR A SEPARATOR? SEE IF GETLIN CMD ALSO ENDED + BLT CMDLO1 ;NOPE, NOT THIS CMD + +;FOUND A MATCH + MOV C,E ;E POINTS TO CMD SEPARATOR (D PTS TO GETLIN END) + JSR PC,NULSTR ;MAKE E POINT TO 1ST NON-BLANK CHAR + ADD #2,B ;POINT TO NEXT CHAR AFTER DELIM., THEN ALIGN TO .EVEN + BIC #1,B + JSR PC,@(B) ;GO EXECUTE CMD + BR CLOOP ;CMDS MAY ALSO RET. DIRECTLY TO CLOOP + +CMDLO1: TSTB (B)+ ;SKIP TO END OF CMD + BNE CMDLO1 +;JUMP TO NEXT COMMAND + INC B ;ALIGN TO .EVEN + BIC #1,B + TST (B)+ ;SKIP DISPATCH ADDR + SOB A,CMDLOP ;CHECK NEXT CMD, IF ANY + ERROR <; NO SUCH COMMAND> + +;SEE IF GETLIN CMD ENDED BEFORE CMDTAB CMD +CMDLO2: CMPB #40,(C) ;HAVE WE HIT A SEPARATOR? + BGE CMDLO1 ;YES, NOT THIS CMD + BR CMDLO3 ;NO, MAYBE THIS CMD + + + .STITLE HELP COMMAND + +;PRINT LIST OF ALL COMMANDS +HELP: MOV #CMDTAB,D ;POINT AT COMMANDS + MOV #NCMDS,E ;NUMBER OF COMMANDS +HELP1: MOVB (D)+,A ;GET CHAR + BEQ HELP2 ;END OF CMD? + JSR PC,TYO + BR HELP1 +HELP2: ADD #3,D ;GET PAST DISPATCH ADDRESS + BIC #1,D ;AND ON EVEN LOC + JSR PC,CRLF + SOB E,HELP1 ;DO FOR ALL CMDS + RTS PC + + +NOCMD: ERROR <; COMMAND NOT IMPLEMENTED YET> + + + .STITLE INFORMATION COMMAND + +;INFORMATION COMMAND +;PRINTS INFORMATION ABOUT EACH FUNCTION +;NOTE: THIS COMMAND BROKEN INTO PIECES BECAUSE SITS PRINTS OUT ALL DATA WITHOUT + ;STOPPING AFTER TRANSFERING A SCREENFUL +INFO: T + T + T + T + T < AND/OR DELIMITER, AS FOLLOWS:> + T < ROOT DIR. NAME IMMEDIATELY FOLLOWED BY ";"> + T < MULTIPLE ARGUMENTS SEPARATED BY ALTMODE CHARACTER ("$")> + JSR PC,CRLF + + T + T + T + T + JSR PC,CRLF + + T + T + T + T < 2 DIFFERENT DIRECTORIES MAY BE POINTED TO AT ONCE> + T < THEY CAN BE USED, FOR EXAMPLE, BY "COPYFILE" TO REACH SOURCE AND> + T < DESTINATION FILES FOR THE COPY> + T < POINTERS MAY ALSO POINT TO SAME DIRECTORY> + T + T <1) AT 0;MAIL $ 1;USERS> + T < POINTERS CONSTRUCTED TO 2 DIFFERENT FILES> + T <2) ATTACH MAIL> + T < ASSUMES SOURCE AND DEST. POINTERS ALREADY POINTING TO DIRECTORY> + T < CONTAINING THIS NAME; BOTH PTRS RESET TO POINT TO DIR. NAMED "MAIL"> + T <3) AT 1;USERS $> + T <4) AT $ 1;USERS> + T < IN 3), JUST SOURCE POINTER RESET WHILE DEST. POINTER UNALTERED> + T < IN 4), SOURCE POINTER UNALTERED WHILE DEST. POINTER CHANGED> + JSR PC,CRLF + + T + T < "INFO2"-- PRINT COMMANDS, "INFO3"-- CREATION, DELETION COMMANDS> + JMP CLOOP + + +INFO1: T + T + T + T < FOR DESTINATION NAME, ONLY THE FILE CAN BE CREATED: DIRECTORY> + T < MUST ALREADY EXIST> + T + T <1) CF 0;MAIL SOMEFIL $ 1;USERS ANOTHFIL> + T <2) CF $ 0;MYDIR THIRDFIL> + T < IF 2) IMMEDIATELY FOLLOWS 1), CONTENTS OF "SOMEFIL" ALSO> + T < FOUND IN "ANOTHFIL" AND IN "THIRDFIL"> + T <3) COPYFILE SOMEFIL $ ANOTHFIL> + T < ASSUMES DIRECTORIES CONTAINING THESE FILES ARE CURRENTLY ATTACHED> + T <4) CF SOMEFIL> + T < LIKE 3), EXCEPT SOURCE AND DESTINATION FILE HAVE SAME NAME> + T < ARGUMENT MUST BE A SIMPLE FILE NAME> + JSR PC,CRLF + + T + T + T + T + T <1) CT 0;MAIL $ 1;USERS> + T <2) CT $ 2;ANOTHDIR> + T < SOURCE DIR. IS THE ONE POINTED TO BY ATTACH COMMAND (SOURCE) POINTER> + T <3) COPYTREE MAIL $ USERS> + T < ASSUMES DIRECTORIES CONTAINING THESE DIR.'S ARE CURRENTLY ATTACHED> + JSR PC,CRLF + JMP CLOOP + +INFO2: T + T + T + T <1) POF 1;USERS MYFILE> + T < COMPLETE PATH NAME SPECIFIED> + T <2) POFILE> + T < DEFAULT IS LAST (SOURCE) FILE REFERENCED> + T <3) POF MYDIR MYFILE> + T < ASSUMES DIR. CONTAINING "MYDIR" IS CURRENTLY ATTACHED (SOURCE) DIR.> + JSR PC,CRLF + + T + T < IN A DIRECTORY> + T + T + T <1) POI 1;USERS> + T < COMPLETE PATH NAME SPECIFIED> + T <2) POINDEX USERS> + T < ASSUMES DIR. CONTAINING THIS ONE IS THE CURRENTLY ATTACHED SOURCE DIR.> + T <3) POI> + T < PRINTS OUT INDEX OF CURRENTLY ATTACHED SOURCE DIRECTORY> + JSR PC,CRLF + + T + T < INFERIOR DIRECTORIES TOO> + JSR PC,CRLF + JMP CLOOP + +INFO3: T + T + T + T <1) CRTDIR 1;USERS MYDIR> + T < "MYDIR" CREATED IN "USERS" DIRECTORY ON DISK AI01> + T <2) CRD MYDIR> + T < CREATED AS SUB- OR INFERIOR DIR. IN CURRENTLY ATTACHED (SOURCE) DIR.> + JSR PC,CRLF + + T + T + T + T <1) CRF 1;USERS MYFILE> + T <2) CRTFILE MYFILE> + T < "MYFILE" CREATED IN CURRENTLY ATTACHED (SOURCE) DIRECTORY> + JSR PC,CRLF + + T + T + T + T <1) DF 1;USERS MYFILE> + T <2) DLTFILE MYFILE> + T < "MYFILE" DELETED FROM CURRENTLY ATTACHED (SOURCE) DIRECTORY> + JSR PC,CRLF + + T + T + T + T < ANY INFERIOR DIRECTORIES> + T + T <1) DD 0;MAIL MYDIR> + T <2) DLTREE MAIL MYDIR> + T < ASSUMES DIR. CONTAINING "MAIL" IS CURRENTLY ATTACHED (SOURCE) DIRECTORY> + JSR PC,CRLF + + T + T + T + T + T <1) SUPRDL MAIL MYDIR> + T < ASSUMES DIRECTORY CONTAINING "MAIL" IS ATTACHED (SOURCE) DIRECTORY> + + JMP CLOOP + + + .STITLE ATTACH COMMAND +;ATTACH TAKES AN ASCIZ STRING (PART OF A GETLIN STRING) +;GETS CAPABILITIES TO SOURCE & DEST. DIRECTORIES AND PUTS THEM + ;IN FRMCAP & TOCAP, RESPECTIVELY + +;SYNTAX: 1) 2 DIR. PATH NAMES SEPARATED BY THE DELIMITER CHAR "ALTMODE" + ;IF EITHER NAME IS NULL, EXISTING FRMCAP OR TOCAP IS UNALTERED + ;2) 1 DIR. PATH NAME, IN WHICH CASE FRMCAP & TOCAP POINT TO SAME DIR. + +ATTACH: JSR PC,ATCH1 ;"ATTACH" FIRST NAME- MAY RET. TMPCAP + BEQ 1$ ;BRANCH IF NO NEW TMPCAP + MOV #FRMCAP,A ;MAKE TMPCAP INTO NEW FRMCAP + JSR PC,NEWCAP +1$: MOV #MUTDIR,RTINE ;2ND NAME MUST EXIST + JSR PC,ATCH2 ;"ATTACH" SECOND NAME; ARG IN RTINE + BEQ 2$ + MOV #TOCAP,A ;MAKE TMPCAP INTO NEW TOCAP + JSR PC,NEWCAP +2$: JMP CLOOP + + +;ON ENTRY, E POINTS TO BEG OF DIRECTORY STRING, + ;AND D POINTS TO THE ENDING 0 +;FOR BOTH ATCH1 & 2: +;ON EXIT, Z SET IF ARG IS NULL; Z CLEAR IF NOT- I.E., NEW DIR. MUTATED TO (TMPCAP) + +;"ATTACH" FIRST NAME +ATCH1: TSTB (E) ;MAKE SURE SOMETHING TYPED + BNE 1$ + JMP CLOOP ;NO CHAR'S, SO NOTHING TO DO +1$: MOVB #33,A ;SEARCH FOR ALTMODE CHAR + JSR PC,SCHAR ;RETURNS WITH D POINTING TO IT, OR THE ENDING 0 IF NOT FOUND + + MOVB (D),-(P) ;SAVE THIS CHAR + CLRB 1(P) ;CLEAR HIGH ORDER BYTE + CLRB (D) ;TURN DELIMITER INTO A "0" BYTE + SAVE ;SAVE POINTER TO IT + SAVE ;SAVE PTR TO BEG. OF STRING + + JSR PC,NULSTR ;SEE IF NULL STRING; TAKES PTRS IN E & D + BEQ 2$ ;Z SET IF NULL, SO SKIP THIS PART + MOV FRMCAP,A ;SUPPLY A CAP TO COPY + JSR PC,COPYCP ;GET A TMPCAP + MOV #MUTDIR,RTINE ;ROUTINE USED BY DIRGET + JSR PC,DIRGET ;GET TMPCAP TO A DIRECTORY + MOV PC,TMPWRD ;MAKE NON-0: INDICATE RETURNING TMPCAP + BR 3$ +2$: CLR TMPWRD ;MAKE 0: INDICATE NO NEW TMPCAP + +;DETERMINE WHERE TO PUT E PTR TO DEST. CAP NAME +;IF 2 NAMES SPECIFIED, PARSE 2ND HALF OF STRING; +;IF 1 NAME, RE-PARSE SAME CHARS +3$: REST ;RESTORE ORIGINAL PTR TO BEG. OF STRING + REST ;RESTORE PTR TO DELIM. CHAR (ALTMODE OR 0) + REST ;RESTORE THE CHAR ITSELF + BEQ 4$ ;IF "0" DON'T CHANGE E + INC D + MOV D,E ;E PTS TO NEXT CHAR AFTER THE DELIMITER +4$: TST TMPWRD ;SET COND CODE + RTS PC + +;"ATTACH" 2ND NAME +;ASSUMES ADDR OF WHICH MUTATE ROUTINE IN RTINE (FOR DIRGET) + ;E CONTAINS POINTER TO NAME +ATCH2: CLR A ;CHAR TO SEARCH FOR, I.E. "0" + JSR PC,SCHAR ;GET POINTER TO END OF STRING IN D + ERRORF <; GETLIN TERMINATING 0 DESTROYED> + JSR PC,NULSTR ;SEE IF NULL STRING-- SETS Z + BEQ 2$ ;IF SO, SKIP THIS PART + MOV TOCAP,A ;SUPPLY A CAP TO COPY + JSR PC,COPYCP ;GET A TMPCAP + JSR PC,DIRGET ;GET TMPCAP TO A DIRECTORY, USING ARG IN RTINE + MOV PC,TMPWRD ;MAKE NON-0: INDICATE RETURNING TMPCAP + BR 3$ +2$: CLR TMPWRD ;MAKE 0: INDICATE NO NEW TMPCAP +3$: TST TMPWRD ;SET COND CODE + RTS PC + +;SEARCH FOR THE CHAR IN A +;ASSUMES POINTER TO BEG. OF ASCIZ STRING IN E +;EXIT COND.'S: + ;IF CHAR FOUND: Z CLEAR; D POINTS TO THE CHAR + ;IF CHAR NOT FOUND: Z SET; D POINTS TO TERMINATING 0 +SCHAR: MOV E,D ;INITIALIZE +1$: CMPB (D),A ;IS THIS THE CHAR BEING SEARCHED FOR? + BEQ 2$ ;YES + TSTB (D) ;NO. END OF STRING? + BEQ 3$ ;BRANCH IF SO; Z SET + INC D ;TRY NEXT CHAR + BR 1$ +2$: CLZ ;CLEAR Z +3$: RTS PC + + + +;FOR ASCIZ STRING, ELIMINATE LEADING BLANKS AND RETURN WITH: + ;Z SET IF NULL STRING; Z CLEAR IF NON-NULL +;ENTRY COND.'S: E & D POINT TO BEG. AND ENDING CHARS, RESPECTIVELY +;EXIT COND.'S: E POINTS TO FIRST NON-BLANK CHAR; D UNCHANGED + +NULSTR: CMPB #40,(E) ;IS THIS CHAR A BLANK? + BNE 1$ ;IF NOT, GO ON + INC E ;YES, ELIMINATE IT + BR NULSTR ;AND TRY NEXT ONE +1$: CMP E,D ;ANY CHARS BETWEEN BEG. AND END OF STRING? + BLO 2$ + SEZ ;NO. SET Z + RTS PC +2$: CLZ ;YES. CLEAR Z + RTS PC + + + + + +;GET TMPCAP TO DIR., WHETHER ROOT DIR. OR ANY OTHER +;ON ENTRY, E POINTS TO FIRST CHAR OF PATH NAME + ;RTINE CONTAINS ADDR OF WHICH MUTATE ROUTINE TO USE +;ROUTINE MAY MODIFY E +DIRGET: SAVE + MOV E,D ;D POINTS TO NAME +;SEE IF 1ST WORD IS ROOT DIR. NAME +1$: CMPB #';,(D) ;DOES IT CONTAIN ";"? + BEQ 2$ ;IF SO, IT'S ROOT NAME + CMPB #40,(D) ;END OF WORD OR GETLIN STRING? + BGE 3$ ;YES. NOT ROOT + INC D ;POINT TO NEXT CHAR + BR 1$ ;NO, CHAR WAS NOT SEPARATOR + +2$: JSR PC,ROOTCP ;GET CAP TO ROOT DIR; COPIED FROM CRTCAP TO TMPCAP + INC D ;MAKE E POINT TO + MOV D,E ;NEXT CHAR AFTER THE ";" + TSTB (D) ;IS DELIMITER A 0? + BNE 3$ ;NO, MUTATE DOWN THE LINE (PROCESSES TRAILING BLANKS) + BR 4$ ;YES, DONE + +3$: MOV TMPCAP,A ;ALL ROUT.'S REQUIRE CAP IN A + JSR PC,@RTINE ;MUTATE TO NON-ROOT DIR USING APPROPRIATE ROUTINE +4$: REST + RTS PC + + +;GET CAP TO ROOT DIR. ACCORDING TO GETLIN NAME +;ON ENTRY, D POINTS TO DELIMITER CHAR; E POINTS TO FIRST CHAR OF NAME + +;SEE IF NAME IS A VALID ROOT DIR. +ROOTCP: DEC D ;POINT TO CHAR BEFORE THE ";" + CMP E,D ;ANY CHARS TYPED BEFORE THE ";" ? + BHI DIRGT2 ;NO, USE CURRENT ROOT CAP + BLO DIRGT8 ;YES, MORE THAN 1: A DIR. NAME + +;YES, BUT JUST 1: MUST BE A DISK NUMBER + MOVB (D),A ;PICK UP THE CHAR + SUB #60,A ;MAKE SURE IT'S A NUMBER + BLT DIRGT8 ;IT'S NOT + CMP DISKS,A ;NO. DISKS ON SYSTEM + BLE DIRGT8 ;NOPE, CHAR CODE TOO HIGH + +;IT IS A VALID DISK NUMBER, SO GET CORRES. ROOT CAP +DIRGT9: ADD #10,A ;GET PROPER ROOT CAP + MOV A,CRTCAP +DIRGT2: MOV CRTCAP,A + JSR PC,COPYCP ;GET NEW CAP BASED ON IT + INC D ;RESTORE D + RTS PC + + +;HAVE NAME OF A ROOT DIR.: SEE IF IT MATCHES A DNAMES NAME +DIRGT8: MOV #DNAMEP,A ;POINTER TO TABLE OF NAME POINTERS +2$: MOV (A)+,B ;POINTER TO A NAME + BNE 1$ ;TABLE ENDS WITH A 0 POINTER + ERROR <; INVALID ROOT DIRECTORY NAME> +1$: MOV E,C ;POINT TO BEG. OF NAME +3$: CMPB (C)+,(B)+ ;COMPARE CHAR BY CHAR + BEQ 3$ + TSTB -(B) ;EACH DNAMES NAME TERM. BY 0 --END OF AN ENTRY? + BNE 2$ ;NO, TRY ANOTHER OF DNAMES + CMPB -(C),#'; ;GETLIN NAME TERM. BY ; --END OF NAME? + BNE 2$ ;NO, TRY ANOTHER + SUB #DNAMEP+2,A ;OFFSET CORRES. TO CAP + ASR A ;CAP INDEX + BR DIRGT9 ;GET ROOT CAP & COPY CURCAP + + .STITLE COPY FILE COMMAND + +;COPY EXISTING FILE TO ANOTHER ONE +;GETS CAP'S TO SOURCE & DEST. FILES AND PUTS THEM IN SRCCAP + ;AND DSTCAP, RESPECTIVELY +;FORMAT: 1) 2 FILE PATH NAMES SEPARATED BY THE DELIMITER CHAR "ALTMODE" + ;IF SRCCAP IS NULL, THE EXISTING SRCCAP IS UNALTERED + ;ALTMODE CHAR MUST APPEAR TO SEPARATE FILE NAMES + ;2) 1 FILE PATH NAME; IN THIS CASE SOURCE & DEST. FILE NAMES ARE THE SAME + +COPYFI: TSTB (E) ;MAKE SURE SOMETHING TYPED + BNE 3$ + JMP CLOOP ;IF NOT, NOTHING TO DO +3$: MOVB #33,A ;SEARCH FOR ALTMODE CHAR + JSR PC,SCHAR ;RETURNS WITH D POINTING TO IT, OR THE ENDING 0 IF NOT FOUND + + MOVB (D),-(P) ;SAVE THIS CHAR + CLRB 1(P) ;CLEAR HIGH ORDER BYTE + CLRB (D) ;TURN DELIMITER INTO A "0" BYTE + SAVE ;SAVE PTR TO IT + + JSR PC,NULSTR ;SEE IF NULL STRING + BNE 1$ ;BRANCH IF SOMETHING THERE + TST SRCCAP ;DEFAULT MUST EXIST + BNE COPFI1 + ERROR <; DEFAULT SOURCE CAPABILITY DOES NOT EXIST> + + ;NAME SPECIFIED +1$: MOV FRMCAP,A ;COPY SOURCE DIR. CAP INTO TMPCAP + JSR PC,DIRARG ;GET A TMPCAP TO EITHER NEW DIR. OR CURRENT ONE; + ;PTR TO 1ST CHAR OF FILE NAME IN E + JSR PC,MUTFIL ;MUTATE TMPCAP TO FILE WHOSE NAME POINTED TO BY E + ERRORF <; SOURCE FILE MUTATE FAILED> + MOV #SRCCAP,A ;MAKE TMPCAP INTO NEW SRCCAP + JSR PC,NEWCAP + +;DETERMINE WHERE TO PUT E PTR TO DEST. CAP NAME +COPFI1: REST ;RESTORE POINTER + REST ;RESTORE CHAR ITSELF + BEQ 3$ ;IF "0" DON'T CHANGE E + INC D + MOV D,E ;E POINTS TO NEXT CHAR AFTER THE DELIMITER + +3$: CLR A ;SEARCH FOR "0" DELIM. CHAR + JSR PC,SCHAR ;GET POINTER TO IT IN D + ERRORF <; GETLIN TERMINATING 0 DESTROYED> + JSR PC,NULSTR ;SEE IF NULL STRING-- SETS Z + ERRORF <; DESTINATION FILE MUST BE SPECIFIED> ;(DSTCAP WAS DELETED) + + ;NAME SPECIFIED + MOV TOCAP,A ;CAP TO BEGIN MUTATE FROM + JSR PC,DIRARG ;GET TMPCAP TO EITHER NEW DIR. OR CURRENT ONE + JSR PC,MUTFCR ;MUTATE TMPCAP TO NEW FILE- CREATE IF NOT EXIST + MOV #DSTCAP,A ;MAKE TMPCAP INTO NEW DSTCAP + JSR PC,NEWCAP + JSR PC,FREAD ;PERFORM THE COPY + JMP CLOOP + + + +;RETURNS TMPCAP CONTAINING: 1) CAP TO THE DIR. SPECIFIED IN PATH NAME, OR + ;2) COPY OF CAP TO ORIG. DIR., IF NEW DIR. NOT SPECIFIED +;(TMPCAP MAY THEN BE MUTATED TO THE FILE) + +;ENTRY COND'S: POINTER TO BEG. OF FILE PATH NAME IN E. . . .REPEAT: FILE PATH NAME + ;DIR. CAP TO BEGIN THE MUTATE FROM IN A +;EXIT COND: POINTER TO BEG. OF FILE NAME IN E + +DIRARG: JSR PC,COPYCP ;USES CAP IN A + JSR PC,BUTLST ;SPLIT STRING INTO DIR. + FILE; RET'S WITH D POINTING + ;TO DELIMITER OR ENDING 0 + BEQ 2$ ;Z SET IF JUST FILE NAME + MOV #MUTDIR,RTINE ;INDICATE USE MUTDIR ROUTINE + JSR PC,DIRGET ;MUTATE TMPCAP TO DIR. + INC D ;MAKE E POINT TO 1ST CHAR OF FILE NAME + MOV D,E +2$: RTS PC + + + +;READ SOURCE FILE & WRITE DEST. FILE BLOCK BY BLOCK +;READS & WRITES USING SRCCAP AND DSTCAP +FREAD: SAVE <#0,#0,SRCCAP> ;RESET FILE PTR TO BEG OF FILE, + BIS #.FASP,(P) ;IN CASE REREADING SAME SOURCE FILE + $INVOK + +FRD1: SAVE <#IOBUF,#-BLKLN,SRCCAP> + .BLKI ;READ IN SOURCE BLK + BEQ 4$ ;Z SET ON EOF + SAVE <#IOBUF,#-BLKLN,DSTCAP> + .BLKO ;WRITE BLK + BNE 3$ ;Z CLEAR IF SUCCEED + BR DSKFUL ;CALL FAILED: DISK FULL? +3$: BR FRD1 ;GET NEXT ONE + +;HAVE HIT END OF FILE: MAY NEED TO OUTPUT CHARS IN LAST BLOCK +4$: MOV DSTCAP,(P) ;REPLACE .BLKI ARG'S LEFT ON STACK WITH .BLKO ONES + ADD #BLKLN,2(P) + NEG 2(P) ;NO. BYTES TO TRANSFER + MOV #IOBUF,4(P) + .BLKO ;WRITE OUT BLK + BNE 2$ ;Z CLEAR IF SUCCEED + BR DSKFUL ;SEE IF DISK FULL +2$: MOV #DSTCAP,A ;FLUSH DSTCAP TO CAUSE MFI TO BE COPIED TO DIR. + JSR PC,FSHCAP + RTS PC + + + + +;SEE IF WRITE FAILED BECAUSE DISK FULL +DSKFUL: $GERRW ;GET ERROR WORD + TST (P)+ + CMP (P)+,#.EDFL + BNE 5$ + ERROR <; INCOMPLETE FILE WRITE-- DISK FULL> +5$: ERROR <; UNDETERMINED WRITE ERROR> ;SOME OTHER ERROR + + + +;SPLITS ASCIZ STRING INTO ALL-BUT-LAST AND LAST WORD +;ASSUMES E POINTS TO 1ST NON-BLANK CHAR +;ON EXIT, D POINTS TO DELIMITER CHAR (A BLANK TURNED INTO A "0"), + ;OR ENDING 0, IF JUST 1 WORD (NO BLANKS) +;RETURNS WITH Z SET IF JUST 1 WORD; Z CLEAR IF MORE THAN 1 + +BUTLST: CLR A ;SEARCH FOR END OF STRING + JSR PC,SCHAR ;D POINTS TO IT +1$: CMPB #40,-(D) ;CONTINUE UNTIL FIND 1ST NON-BLANK CHAR + BEQ 1$ ;D POINTS TO IT + BR 3$ ;FOUND IT +2$: CMPB #40,-(D) ;IS THIS CHAR A BLANK? + BEQ 4$ ;IF SO, BRANCH +3$: CMP E,D ;AT BEG. OF STRING? + BLT 2$ ;IF NOT, KEEP LOOKING + +;REACHED BEG. WITHOUT FINDING A BLANK: Z SET + CLR A ;MAKE D POINT TO ENDING 0 + JSR PC,SCHAR + SEZ ;SET Z + RTS PC ;JUST 1 WORD + +;FOUND A BLANK; MORE THAN 1 WORD +4$: CLRB (D) ;TURN IT INTO A 0 (SPLIT STRING) + CLZ ;CLEAR Z +5$: RTS PC + + + .STITLE PRINT OUT TREE, PRINT OUT INDEX COMMANDS + +;PRINT OUT DIRECTORY ROUTINES +;NOTE: LONG DIRECTORIES LOSE BECAUSE SITS CONTINUES PRINTING UNTIL ALL DATA + ;IS EXHAUSTED +;FORMAT: NULL ARGUMENT- USE CURRECT DIR. CAP (FRMCAP) + ;NON-NULL ARGUMENT- MUTATE TO DIR. WHOSE NAME GIVEN + +;ON ENTRY, E POINTS TO COMMAND ARGUMENT, AND + ;RECURSION DEPTH SET TO 0 BY CLOOP +;ASSUMES D CONTAINS THE NO. OF THE ENTRY BEING PROCESSED + + +;ENTER HERE FOR PRINT OUT TREE +POTREE: MOV PC,TREE ;MAKE NON-ZERO FOR TREE + BR POI.1 + +;ENTER HERE FOR PRINT OUT INDEX +POI: CLR TREE ;0 INDICATES NOT TREE +POI.1: MOV #,OFFSET ;FOR PRINT OUT (DIR.) ROUTINES + JSR PC,UTIL ;EXECUTE PRINT ROUTINES + + SAVE <,,TMPCAP> ;GET NO. FREE BLKS ON DISK & DISK NO. + BIS #.FADI,(P) + $INVOK + REST ;RETRIEVE NO. FREE BLKS + JSR PC,PRDN ;PRINT AS DEC. NO. (ARG IN A) + TYPE < FREE BLOCKS ON DISK #> + REST ;RETRIEVE DISK NO. + JSR PC,PRDN ;PRINT IT + JSR PC,CRLF ;NEW LINE ON TTY + JMP CLOOP + + +;ASSUMES OFFSET INTO DISPATCH TABLE SET UP +UTIL: MOV FRMCAP,A ;COPY FRMCAP TO TMPCAP + JSR PC,COPYCP + TSTB (E) ;ANY ARGUMENT GIVEN? + BEQ 1$ ;BRANCH IF NOT + MOV #MUTDIR,RTINE ;INDICATE USE MUTDIR ROUTINE + JSR PC,DIRGET ;MUTATE TO GIVEN DIR.; CAP IN TMPCAP +1$: MOV TMPCAP,A ;PASS CAP IN A + JSR PC,PODIR ;PRINT OUT DIR. ROUTINE + RTS PC + + +;ASSUMES CAP TO A DIR. IN A +PODIR: MOV #-1,D ;INITIALIZE TO SELF ENTRY + JSR PC,MAP ;MAP IN DIR; USES THE CAP IN A; + ;ADDR OF BEG. OF DIR. RET. IN C + +;PROCESS NEXT ENTRY +NXENT: INC D ;ENTRY NO. + JSR PC,SKPENT ;GET ADDR (IN DIR) OF NEXT ENTRY; ADDR RET. IN C + CMP C,ABSEOF ;GONE BEYOND EOF? + BHIS 1$ ;IF SO, DONE + +;DISPATCH TO ROUTINE + MOVB 1(C),A ;GET TYPE OF ENTRY + BIC #177761,A ;TYPE LOCATED IN TOP BYTE OF HEADER WORD + MOV A,ENTTYP ;STORE IT + ADD OFFSET,A ;CHOOSE APPROPRIATE GROUP + JSR PC,@DISPCH(A) ;GO EXECUTE ROUTINE + BR NXENT + +;FINISHED ALL ENTRIES +1$: MOV #.DLPAG,A ;DELETE PAGE BEFORE RE-MAPPING + JSR PC,MAP ;USES ARG. IN A + RTS PC + + +;ROUTINES THAT ASSUME C POINTS TO BEG. OF THE DIR. ENTRY: PODIRD, PODIRS, + ;PODIRP, PODIRL, PODIRF + +;DIRECTORY TYPE ENTRY OTHER THAN SELF OR PARENT +PODIRD: TST TREE ;SEE IF DOING TREE + BNE 1$ ;IF SO, BRANCH +;NON-TREE + MOV #2,RCURDP ;PRINT "I" BEFORE SUB-DIR.'S + JSR PC,PODIRS ;NO, SO CONTINUE + CLR RCURDP ;RESTORE LEVEL + RTS PC +;TREE +1$: MOV #FSHTMP,DRDONE ;INDICATE FLUSH CAP TO DIR. WHEN DONE + JSR PC,DOTREE ;PROCESS INFERIOR DIR. + MOV TMPCAP,A ;AGAIN, CAP TO PARENT DIR. + JSR PC,MAP ;RESTORE PAGE IN CORE TO SEE IF END OF DIR. + RTS PC ;GO ON LISTING THIS DIRECTORY + +;PRINT OUT SELF ENTRY +PODIRS: JSR PC,INDENT ;PRINT BLANKS FOLL. BY "I" FOR ALL BUT TOP LEVEL +PODRS2: JSR PC,SKPENT ;GET PTR TO BEG. OF ENTRY; PTR RET. IN C + JSR PC,NMVRSZ ;PRINT OUT NAME, VERSION NO., AND SIZE + +;ENTER HERE FOR PARENT ENTRY- SKIP IT +PODIRP: RTS PC + +;ENTER HERE FOR NON-IMPLEMENTED ENTRY TYPE +PODIRL: ERROR <; ENTRY TYPE NOT IMPLEMENTED> + +;PRINT OUT FILE ENTRIES +PODIRF: MOV RCURDP,E ;PRINT RECUR. LEV.+2 BLANKS (NO "I" BEFORE FILE NAMES) + ADD #2,E ;NO. TO PRINT + JSR PC,NBLNKS + BR PODRS2 + + + +;GET CAP TO INFERIOR DIRECTORY +;ASSUMES PODIR OFFSET ALREADY SET UP + ;AND DRDONE CONTAINS ADDR. OF ROUT.TO EXEC. WHEN PROCESSING DONE + ;(EITHER FLUSH CAP TO THE DIR., OR FLUSH DIR. ITSELF) +;RECURSION LEVEL JUMPS BY 2 AS CROCK USED FOR PRINTING BLANKS + +DOTREE: SAVE ;NO. OF THE ENTRY WORKING ON & CAP TO THIS DIR. + ADD #2,RCURDP ;INCREMENT RECUR. LEV. + MOV TMPCAP,A ;GET A TMPCAP TO MUTATE + JSR PC,COPCP1 ;COPY TMPCAP WITHOUT DELETING OLD ONE + + JSR PC,NAMENT ;RET'S PTR TO NAME IN E + JSR PC,MUTDIR ;MUTATE TMPCAP TO NEW DIR. + + MOV TMPCAP,A ;PASS CAP TO USE + JSR PC,PODIR ;PROCESS INFERIOR DIR. + JSR PC,@DRDONE ;ROUT. TO EXECUTE WHEN DONE (SEE ABOVE) + + SUB #2,RCURDP ;RESTORE THIS RECUR. LEV. + REST ;CAP TO THIS DIR, & NO. OF THE ENTRY WORKING ON + RTS PC + + +;SET C TO FIRST BYTE OF NEXT ENTRY (HEADER WORD) +;CALC. BASED ON THE NO. OF THE ENTRY BEING PROCESSED +;INPUT COND: D = ENTRY NO. + +SKPENT: SAVE + MOV #DIRPAD,C ;ADDR OF BEG OF PAGE + MOV D,E ;ENTRY NO. + BEQ 2$ ;EXIT IF SELF ENTRY +;CALC WHERE IN PAGE THE ENTRY STARTS +1$: MOV (C),F ;PICK UP HEADER WORD + INC F ;GET LENGTH TO NEAREST WORD + BIC #177401,F + ADD F,C ;ADD ON LEN OF THIS ENTRY + SOB E,1$ ;REPEAT UNTIL GET TO THE ENTRY WE WANT +2$: REST + RTS PC + + +;SKIP TO NAME +;ASSUMES C POINTS TO HEADER WORD OF AN ENTRY +;RETURNS WITH C POINTING TO NAME +;MOVES VERSION NO.INTO BUFFERS +;SETS UP DATE, TIME, & ENTRY LEN., IF ANY + +SKPTNM: MOV (C)+,E ;E <- HEADER WORD + MOV (C)+,VERNO ;STORE VERSION NO. + CLR DATE ;INDICATES: IF 0, DON'T PRINT + ROL E ;PUT EOF BIT IN CARRY + BCC 1$ ;IF CLEAR, MEANS NO EOF'S, DATE, OR TIME + + ADD #2,C ;SKIP 1ST EOF WORD- WILL COME BACK TO IT +;GET LENGTH IN BLOCKS FOR A FILE ENTRY + SAVE + MOV (C)+,F ;2ND EOF: BYTE POINTER + ADD #1777,F ;ROUND UP TO BLOCK BOUNDARY + CLR E ;CLEAR HIGH PART + ASHC #3,E ;ONLY 13 BITS USED + ADD -4(C),E ;ADD IN NO. OF PAGES (1ST EOF) + ASHC #3,E ;GET LEN. IN BLKS + MOV E,ENTLN ;STORE ENTRY LEN + REST + + ;E CONTAINS HEADER WORD ROTATED + MOV (C)+,DATE + MOV (C)+,TIME +1$: ROL E ;PUT ACC BIT IN CARRY + BCC 3$ ;CLEAR IF NO ACCESS CODES + +2$: ADD #2,C ;SKIP ACCESS CODES + TSTB (C)+ ;MORE CODES? + BLT 2$ ;LAST GROUP HAS SIGN BIT ON +3$: RTS PC + + + + +;PRINT NAME, VERSION NO., SIZE, DATE, AND TIME +;ON ENTRY, C POINTS TO FIRST BYTE OF ENTRY + +NMVRSZ: JSR PC,SKPTNM ;SKIP TO NAME; PTR TO NAME RET. IN C + +;PRINT NAME +1$: MOVB (C),A ;PUT CHAR IN A + BIC #177600,A ;CLEAR ALL BUT THE CHAR CODE + JSR PC,SPLCHR ;IS CHAR SPECIAL (#, ", >, <)? + BNE 3$ ;BRANCH IF NOT + +;CHAR WAS SPECIAL: PRINT " BEFORE IT + SAVE + MOVB #'",A + JSR PC,TYO ;PRINT " + REST + +3$: JSR PC,TYO ;PRINT THE CHAR IN A + TSTB (C)+ + BPL 1$ ;LAST CHAR HAS 200 BIT SET + +;PRINT VERSION NUMBER + TST VERNO ;DON'T PRINT IF NEG. + BLT 4$ + MOV #'#,A ;PRINT # BEFORE IT + JSR PC,TYO + MOV VERNO,A ;PICK UP VERSION NO. + JSR PC,PRDN ;PRINT IT AS DECIMAL NO. + +;IF FILE ENTRY, PRINT LENGTH IN BLOCKS +4$: CMP #4,ENTTYP ;IS TYPE FILE? + BNE 5$ ;IF NOT, BRANCH + MOV #2,E ;PRINT 2 BLANKS + JSR PC,NBLNKS + MOV ENTLN,A ;PICK UP ENTRY LEN. + JSR PC,PRDN ;PRINT IT AS DECIMAL NO. + +;PRINT DATE AND TIME OF CREATION +5$: JSR PC,PRDAT ;PRINT DATE & TIME, IF ANY + JSR PC,CRLF ;END OF THIS LINE OF INFO + RTS PC + + + +;FOR A DIRECTORY, INDENTS ACCORDING TO RECURSION DEPTH, AND +;PRINTS "I" (FOR "INDEX") BEFORE ALL BUT RECUR. DEPTH 0 + +INDENT: TST RCURDP ;DON'T DO ANYTHING AT TOP LEVEL + BEQ 2$ +;PRINT RECUR. LEV.-2 BLANKS + MOV RCURDP,E + SUB #2,E ;ANY BLANKS TO PRINT? + BEQ 1$ ;BRANCH IF NOT + JSR PC,NBLNKS ;YES: NO. TO PRINT IN E +1$: MOV #'I,A ;PRINT "I," + JSR PC,TYO + INC E ;(WAS 0 FROM LAST NBLNKS CALL) + JSR PC,NBLNKS ;FOLLOWED BY A BLANK +2$: RTS PC + + + +;TAKE NAME OUT OF DIR. TYPE ENTRY & PUT IT IN NAMBUF +;ON ENTRY, C POINTS TO BEG. OF THIS ENTRY +;ON EXIT, E POINTS TO THE NAME (TURNED INTO ASCIZ) +NAMENT: SAVE + JSR PC,SKPTNM ;RETURNS PTR TO NAME IN C; GETS VERNO + MOV #NAMBUF,E ;GET POINTER TO ASCIZ NAME + +;COPY NAME TO NAMBUF +1$: MOVB (C),A ;PICK UP A CHAR + JSR PC,SPLCHR ;SEE IF IT'S SPECIAL + BNE 2$ ;BRANCH IF NOT + MOVB #'",(E)+ ;INSERT " BEFORE IT +2$: MOVB (C)+,(E)+ ;TRANSFER CHAR + BPL 1$ ;LAST BYTE HAS 200 BIT SET, + BICB #200,-1(E) ;SO ZAP IT + + MOV VERNO,A ;SEE IF VERSION NO. USED + BLT 3$ ;NO, IF NEG. + MOVB #'#,(E)+ ;INSERT # BEFORE IT + JSR PC,CVDN ;CONVERT & INSERT NO. ITSELF- IN A + +3$: CLRB (E) ;TERMINATE WITH 0 BYTE + MOV #NAMBUF,E ;POINTER TO NAME IN E + REST + RTS PC + + + +;MOVE CHARACTERS TO NAMBUF-- USED BY CVDN +;MOVE CHAR IN A TO DEST. ADDR IN E +;LEAVES E POINTING TO NEXT BYTE +MVNBUF: MOVB A,(E)+ + RTS PC + + + +;SEE IF CHAR IN A IS SPECIAL, I.E., #, ", >, <, OR 0 +;RETURNS WITH Z SET IF SO +SPLCHR: CMPB #'#,A + BEQ 2$ + CMPB #'",A + BEQ 2$ + CMPB #'>,A + BEQ 2$ + CMPB #'<,A + BEQ 2$ + TST A ;IS IT 0? +2$: RTS PC + + + + +;PRDAT PRINTS DATE & TIME, IF ANY +PRDAT: SAVE + MOV DATE,A ;PUT DATE IN A + BEQ 5$ ;IF NO DATE & TIME, RETURN + CMP #-1,A ;SEE IF INITIALIZED + BNE PRDAT1 ;GO ON IF INITIALIZED + TYPE < -> ;PRINT "-" IF NOT +5$: BR PRDAT2 ;EXIT + +PRDAT1: TYPE < > ;PRINT 2 BLANKS + ASH #-5,A ;SHIFT MONTH TO LOW BYTE + BIC #177760,A ;ZAP ALL ELSE + JSR PC,PRDN ;PRINT MONTH + TYPE + MOV DATE,A ;RESET A + BIC #177740,A ;ZAP ALL ELSE + JSR PC,ZPRDN ;PRINT DAY + TYPE + MOV DATE,A ;RESET A + ASH #-9.,A ;SHIFT YEAR TO LOW BYTE + BIC #177600,A ;ZAP ALL ELSE + JSR PC,ZPRDN ;PRINT YEAR + + TYPE < > ;PRINT 2 BLANKS + MOV TIME,A ;MOVE TIME INTO A + ASH #-13,A ;SHIFT HOUR TO LOW BYTE + BIC #177740,A ;ZAP ALL ELSE + JSR PC,PRDN ;PRINT HOUR + TYPE <:> + MOV TIME,A ;RESET A + ASH #-5,A ;SHIFT MINUTE TO LOW BYTE + BIC #177700,A ;ZAP ALL ELSE + JSR PC,ZPRDN ;PRINT MINUTE + TYPE <:> + MOV TIME,A ;RESET A + BIC #177740,A ;ZAP ALL BUT SECONDS/2 + ASL A ;MULTIPLY BY 2 + JSR PC,ZPRDN ;PRINT SECONDS +PRDAT2: REST + RTS PC + + .STITLE CREATE DIRECTORY, CREATE FILE, QUIT COMMANDS + +;CREATE DIRECTORY COMMAND +;ASSUMES POINTER TO DIRECTORY PATH NAME IN E +CRD: TSTB (E) ;SEE IF ANY ARG. GIVEN + ERRORF <; ARGUMENT MUST BE SPECIFIED> + MOV FRMCAP,A ;GET CAP TO COPY + JSR PC,COPYCP + MOV #MUTDCM,RTINE ;INDICATE MUTDCM ROUTINE, + JSR PC,DIRGET ;WHICH PRINTS MESS. IF DIR. EXISTS + JMP CLOOP + + + +;CREATE FILE COMMAND +;ASSUMES POINTER TO FILE PATH NAME IN E +CRF: TSTB (E) + ERRORF <; ARGUMENT MUST BE SPECIFIED> + MOV FRMCAP,A ;GET CAP TO COPY + JSR PC,COPYCP + MOV #MUTFCM,RTINE ;INDICATE MUTFCM ROUTINE, + JSR PC,DIRGET ;WHICH PRINTS MESS. IF FILE EXISTS + JMP CLOOP + + + +;QUIT COMMAND +QUIT: T ;JUMPS TO NEXT LINE + BPT + JMP CLOOP + .STITLE COPY TREE COMMAND +;COPY CONTENTS OF DIR. TO NEW OR EXISTING DIR. +;COPY PERFORMED FROM SRCCAP DIR. INTO DSTCAP DIR. + +;SYNTAX: + ;1) 2 DIR. PATH NAMES SEPARATED BY THE DELIMITER CHAR "ALTMODE" ("$") + ;FRMCAP MUTATED TO SRCCAP; TOCAP MUTATED TO DSTCAP + ;FIRST NAME MAY BE NULL: EXISTING FRMCAP (SET BY ATTACH) USED AS SRCCAP + ;2) 1 DIR. PATH NAME + ;DIRECTORY COPIED TO ITSELF + +;NOTE: DIRECTORY CREATION INCOMPLETE: SITS SYSTEM ERROR? + ;COPYING INTO A DIR. CREATED BY THIS COMMAND FAILS, + ;BUT COPYING INTO EXISTING DIRECTORIES SEEMS TO WORK +COPYTR: JSR PC,ATCH1 ;"ATTACH" FIRST NAME- MAY RET. TMPCAP + BNE 1$ ;BRANCH IF NEW TMPCAP + MOV FRMCAP,A ;DEFAULT: USE CURRENT FRMCAP + JSR PC,COPYCP ;COPY FRMCAP TO TMPCAP +1$: MOV #SRCCAP,A ;MAKE TMPCAP INTO NEW SRCCAP + JSR PC,NEWCAP + MOV #MUTDCR,RTINE ;2ND NAME MUST BE SPECIFIED + JSR PC,ATCH2 ;"ATTACH" SECOND NAME; ARG IN RTINE + ERRORF <; DESTINATION DIRECTORY NAME MUST BE SPECIFIED> + MOV #DSTCAP,A ;MAKE TMPCAP INTO NEW DSTCAP + JSR PC,NEWCAP +;NOW HAVE SRCCAP AND DSTCAP + + MOV #,OFFSET ;COPYTREE ROUTINES + MOV SRCCAP,A ;PASS CAP + JSR PC,PODIR ;DO ROUT. CORRES. TO EACH ENTRY TYPE + JMP CLOOP + + +;FOUND A DIR. ENTRY POINTED TO BY C +;MUTATE SRCCAP & DSTCAP TO INFERIOR DIR.'S +COPTRD: SAVE ;D CONTAINS NO. OF THE ENTRY WORKING ON + ADD #2,RCURDP ;INCREMENT RECURSION DEPTH + JSR PC,NAMENT ;GET POINTER TO NAME IN E + + MOV SRCCAP,A ;MUTATE SRCCAP TO INFER. DIR. + JSR PC,COPYCP ;GET A TMPCAP + JSR PC,MUTDIR ;USES TMPCAP, E + MOV TMPCAP,SRCCAP ;NEW SRCCAP + CLR TMPCAP + + MOV DSTCAP,A ;MUTATE DSTCAP TO INFER. DIR. + JSR PC,COPYCP ;GET A TMPCAP + JSR PC,MUTDCN ;USES TMPCAP, E; CREATE IF NOT EXIST + MOV TMPCAP,DSTCAP ;NEW DSTCAP + CLR TMPCAP + + MOV SRCCAP,A ;PROCESS INFERIOR SOURCE DIR. + JSR PC,PODIR + MOV #SRCCAP,A ;FLUSH ITS CAP + JSR PC,FSHCAP + + MOV #DSTCAP,A ;FLUSH CAP TO INFER. DEST. DIR. + JSR PC,FSHCAP + + SUB #2,RCURDP ;COME BACK TO THIS LEVEL + REST + MOV SRCCAP,A ;GO ON COPYING THIS DIR. + JSR PC,MAP ;RE-MAP IN PAGE + RTS PC + + +;FOUND A FILE ENTRY WHOSE ENTRY NO. GIVEN BY D +;MUTATE SRCCAP & DSTCAP TO SOURCE & DEST. FILES +COPTRF: SAVE ;SAVE CAPS TO THE DIR.'S + JSR PC,NAMENT ;GET POINTER TO ITS NAME IN E + MOV SRCCAP,A ;GET A TMPCAP TO MUTATE + JSR PC,COPYCP + JSR PC,MUTFIL ;USES TMPCAP, E + ERRORF <; SOURCE FILE MUTATE FAILED: >,,TYPEIT + MOV TMPCAP,SRCCAP ;MAKE TMPCAP INTO NEW SRCCAP + CLR TMPCAP + + ;GET CAP TO DEST. FILE + MOV DSTCAP,A ;GET A TMPCAP TO MUTATE + JSR PC,COPYCP + JSR PC,MUTFCN ;MUTATE TMPCAP TO FILE- CREATE IF NOT EXIST + MOV TMPCAP,DSTCAP ;MAKE TMPCAP INTO NEW DSTCAP + CLR TMPCAP + JSR PC,FREAD ;PERFORM THE COPY FROM SRCCAP; DELETES DSTCAP WHEN DONE + + MOV SRCCAP,A ;DELETE CAP TO SOURCE FILE + JSR PC,DELCAP + REST + +;FOR SELF AND PARENT ENTRIES, JUST RETURN +COPTRS: +COPTRP: RTS PC + + + .STITLE DELETE FILE, PRINT OUT FILE COMMANDS + +;DELETE FILE +;SINGLE ARG. MUST BE A FILE PATH NAME +DLTFIL: JSR PC,NULSTR ;ELIMINATE LEADING BLANKS + TSTB (E) ;NULL ARG. NOT PERMITTED + ERRORF <; FILE NAME MUST BE SPECIFIED> + + MOV FRMCAP,A ;GET A TMPCAP TO EITHER NEW DIR. OR CURRENT ONE + JSR PC,DIRARG ;PTR TO NAME RET. IN E + JSR PC,MUTFIL ;MUT. THE TMPCAP TO THE FILE + ERRORF <; FILE DOES NOT EXIST> + + JSR PC,FSHTFI ;DELETE FILE & FLUSH CAP TO IT + JMP CLOOP + + + +;PRINT OUT CONTENTS OF FILE +;SINGLE ARG. MAY BE COMPLETE PATH NAME OR NULL +POFILE: JSR PC,NULSTR ;ELIM. LEADING BLANKS + TSTB (E) ;SEE IF ANY ARG. GIVEN + BNE 1$ ;BRANCH IF SO + +;NO ARG. GIVEN, SO USE CURRENT SRCCAP + TST SRCCAP ;DEFAULT MUST EXIST + ERRORF <; NO DEFAULT SOURCE FILE CAPABILITY> + BR 3$ + +;ARG. GIVEN +1$: MOV FRMCAP,A ;COPY SOURCE DIR. CAP INTO TMPCAP + JSR PC,DIRARG ;GET A TMPCAP TO EITHER NEW DIR. OR CURRENT ONE + ;PTR TO FILE NAME IN E + +2$: JSR PC,MUTFIL ;MUTATE TMPCAP TO FILE WHOSE NAME POINTED TO BY E + ERRORF <; CANNOT MUTATE TO SOURCE FILE> + MOV #SRCCAP,A ;MAKE TMPCAP INTO NEW SRCCAP + JSR PC,NEWCAP + +3$: MOV TTYCAP,A ;USE TTYCAP AS DSTCAP + JSR PC,COPYCP ;RETURNS TMPCAP + MOV TMPCAP,DSTCAP ;OLD DSTCAP DELETED BY CLOOP + CLR TMPCAP + + JSR PC,FREAD ;READ AND PRINT FILE + JMP CLOOP + + + .STITLE DELETE TREE, SUPER DELETE COMMANDS + +;DELETE DIRECTORY AND ALL ITS FILES AND INFERIOR DIRECTORIES AND THEIR FILES +;SINGLE ARG. MUST BE A DIR. PATH NAME +DLTREE: JSR PC,NULSTR ;ELIM. ANY LEADING BLANKS + TSTB (E) ;REQUIRE ARG. SPECIFIED + ERRORF <; DIRECTORY NAME MUST BE SPECIFIED> + MOV #,OFFSET ;DELETE TREE ROUTINES + JSR PC,UTIL + JSR PC,FSHTFI ;FLUSH EMPTTY DIR. + JMP CLOOP + +;ASSUMES TMPCAP POINTING TO THE DIR. TO DELETE +DELDRD: MOV #FSHTFI,DRDONE ;INDICATE FLUSH INFER. DIR. WHEN DONE + JSR PC,DOTREE ;PROCESS INFERIOR DIR. + DEC D ;1 LESS ENTRY IN PARENT DIR. + MOV TMPCAP,A ;AGAIN, CAP TO PARENT DIR. + JSR PC,MAP ;RE-MAP IN PAGE + RTS PC ;CONTINUE PROCESSING THIS DIR. + + +;DELETE FILE. ASSUMES POINTER TO BEG. OF ENTRY IN C +DELDRF: SAVE + JSR PC,NAMENT ;GET POINTER TO NAME IN E + MOV TMPCAP,A ;GET ANOTHER COPY TO MUTATE + JSR PC,COPCP1 + JSR PC,MUTFIL ;MUTATE IT TO THE FILE WHOSE NAME POINTED TO BY E + JSR PC,FSHTFI ;DELETE THE FILE & ITS CAP + DEC D ;1 LESS ENTRY IN PARENT DIR. + JSR PC,MAPEOF ;RE-CALC. DIR. LENGTH + REST ;GET BACK CAP TO PARENT DIR. + +;FOR SELF AND PARENT ENTRIES, JUST RETURN +DELDRS: +DELDRP: RTS PC + + + +;SUPER DELETE COMMAND +;MUST GIVE ARG., I.E., DIR. IS MUTATED TO FROM THE CURRENT FRMCAP +;THIS PREVENTS ACCIDENTAL DELETION OF ROOT DIRECTORY +;THIS IS MESSY WAY: LEAVES AROUND UNUSED FILE BLOCKS. DLTREE COMMAND PREFERRED +SUPRDL: JSR PC,NULSTR ;ELIM. LEADING BLANKS + TSTB (E) ;SEE IF ANY ARG. GIVEN + BEQ SPDERR ;IF NOT, CANNOT MUTATE + MOV FRMCAP,A ;GET A TMPCAP + JSR PC,COPYCP + + JSR PC,MUTDIR ;PROTECT ROOT DIR. BY NOT ALLOWING AS PART OF PATH NAME + JSR PC,PLVRIZ ;USES .FASDL TO DELETE DIR. + JSR PC,FSHTMP ;FLUSH ITS CAP + JMP CLOOP + +SPDERR: ERROR <; DIRECTORY MUST BE MUTATED TO BY THIS COMMAND> + + + .STITLE UTILITY ROUTINES USING SITS FUNCTIONS + +;COPY CAPABILITY IN A INTO TMPCAP +COPYCP: JSR PC,FSHTMP ;FLUSH OLD TMPCAP +COPCP1: SAVE <#-1,#0,A> ;COPY CAPABILITY + BIS #.CPYCP,(P) + .INVOK + ERRORF <; CAPABILITY COULDN'T BE COPIED> + REST TMPCAP ;NEW TEMP. CAP + RTS PC + + +;DELETE CAPABILITY IN A +DELCAP: TST A + BEQ DELCP1 ;DON'T DELETE NON-EXISTING CAP + SAVE <,,A> + BIS #.DELCP,(P) + $INVOK +DELCP1: RTS PC + + +;FLUSH (DELETE & CLEAR) TMPCAP +FSHTMP: SAVE + MOV TMPCAP,A + JSR PC,DELCAP + CLR TMPCAP + REST + RTS PC + + +;FLUSH (DELETE & CLEAR) CAP WHOSE LOCATION IN A +FSHCAP: TST (A) ;DON'T DELETE NON-EXISTING CAP + BEQ 1$ + SAVE <,,(A)> + BIS #.DELCP,(P) + $INVOK + CLR (A) ;CLEAR LOC. +1$: RTS PC + + +;DELETE FILE WHOSE CAP IN A +DELFI: TST A ;DON'T DELETE IF NON-EXISTENT CAP + BEQ 1$ + SAVE <,,A> + BIS #.FADL,(P) ;FILE DELETE FUNCTION + $INVOK +1$: RTS PC + + +;FLUSH FILE WHOSE CAP IN TMPCAP +FSHTFI: MOV TMPCAP,A + JSR PC,DELFI ;DELETE THE FILE + JMP FSHTMP ;FLUSH ITS CAP + + +;DELETE DIR WHOSE CAP IN TMPCAP +PLVRIZ: SAVE <,,TMPCAP> + BIS #.FASDL,(P) ;DIR. DELETE FUNCTION + .INVOK ;SHOULD FAIL IF PROTECTED DIR. + BNE 2$ ;Z SET IF FAIL + $GERRW + TST (P)+ + CMP (P)+,#.ECDD ;SEE IF MORE THAN 1 CAP TO THIS DIR. + BNE 1$ ;IF THAT'S NOT THE PROBLEM, BRANCH + ERROR <; MORE THAN 1 CAPABILITY TO THIS DIRECTORY> + +;SHOULD MODIFY SITS TO INCLUDE PROTECTION +1$: ERROR <; PROTECTED DIRECTORY, CANNOT BE DELETED> +2$: RTS PC + + + +;MUTATE TMPCAP TO A DIRECTORY +;ASSUMES E POINTS TO ASCIZ NAME +;USES A .INVOK. CALLING PROG. MUST DECIDE WHAT TO DO IF CALL FAILS. +MUTDR1: SAVE <#0,E,TMPCAP> + BIS #.FAMU,(P) ;MUTATE CURRENT CAP + .INVOK ;CLEARS Z IF SUCCESSFUL + BNE 1$ ;Z SET IF CALL FAILS + ADD #6,P ;RESTORE PDL + SEZ ;INDICATE FAILURE +1$: RTS PC + + + + +;MAKE SURE THAT THE TMPCAP ACQUIRED IS TO A DIRECTORY +;COMMAND ABORTED IF NOT +DIRCHK: SAVE <#FILBLK,#10,TMPCAP> ;GET 8. BYTES OF FILE INFORMATION + BIS #.FARI,(P) + $INVOK + BIT #.FADIR,FILBLK+2 ;CHECK THAT IT IS A DIR. + BNE 2$ ;Z CLEAR IF BIT ON + ERROR <; ARGUMENT NOT A DIRECTORY: >,,TYPEIT +2$: RTS PC + + + + +;MUTATE TMPCAP TO DIRECTORY +;ASSUMES NON-ROOT ASCIZ DIR. NAME POINTED TO BY E +;RETURNS TO CLOOP IF FAILS +MUTDIR: JSR PC,MUTDR1 ;ALREADY HAVE TMPCAP TO MUTATE + ERRORF <; DIRECTORY MUTATE FAILED: >,,TYPEIT ;Z SET IF FAILED + JMP DIRCHK ;CHECK THAT IT IS A DIR. + + + +;MUTATE TMPCAP TO FILE +;IF FILE ALREADY EXISTS, DELETES & THEN RECREATES +;IF DOES NOT EXIST, CREATES FILE +;ENTRY COND'S: E POINTS TO ASCIZ FILE PATH NAME + ;TMPCAP CONTAINS DIR. CAP TO BEGIN THE MUTATE FROM + +;MUTATE, NO MESSAGE +MUTFCN: CLR B ;INDICATE NO MESS. BEFORE ZAPPING FILE + BR MUT.1 + +;MUTATE, MESSAGE +MUTFCR: MOV PC,B ;MAKE NON-0: INDICATE REQUIRE YES ANSWER BEFORE ZAPPING FILE + +MUT.1: SAVE ;CAP TO THE DIR. + MOV TMPCAP,A ;MAKE ANOTHER COPY TO MUTATE + JSR PC,COPCP1 + JSR PC,MUTFIL ;TRY TO MUTATE TO THIS FILE- RET'S A TMPCAP + BEQ 2$ ;BRANCH IF FAIL + TST B ;SEE IF REQUIRE ANSWER + BEQ 1$ ;BRANCH IF NOT + TYPE + JSR PC,GETANS ;GET ANSWER; MUST BE "Y" TO CONTINUE +1$: JSR PC,FSHTFI ;FLUSH FILE WHOSE CAP IN TMPCAP +2$: JSR PC,FSHTMP ;FOR CASE WHEN FILE DID NOT EXIST + REST ;GET BACK CAP TO THE DIR. + JSR PC,CRETFL ;CREATE FILE USING TMPCAP + RTS PC + + + + +;MUTATE TMPCAP TO DIRECTORY +;ASSUMES NON-ROOT ASCIZ DIR. PATH NAME POINTED TO BY E +;CREATES NEW DIR. IF MUTATE FAILS +;REQUIRES "Y"ES ANSWER FOR ALR. EXISTING DIR. TO BE REWRITTEN +MUTDCR: MOV #CRETDR,XROUT ;INDICATE CRETDR ROUTINE + JSR PC,MUTWRD ;MUTATE WORD BY WORD, THEN CREATE + BEQ 1$ ;BRANCH IF DIR. WAS CREATED + TYPE + JSR PC,GETANS ;GET ANSWER +1$: RTS PC + + + +;MUTATE TMPCAP TO DIRECTORY +;NO MESSAGE PRINTED IF DIR. ALREADY EXISTS +;ASSUMES NON-ROOT ASCIZ DIR. PATH NAME POINTED TO BY E +;CREATES NEW DIR. IF MUTATE FAILS +MUTDCN: MOV #CRETDR,XROUT ;INDICATE CRETDR ROUTINE + JSR PC,MUTWRD ;MUTATE WORD BY WORD, THEN CREATE + RTS PC + + + +;MUTATE TMPCAP TO DIRECTORY +;MESS. PRINTED IF DIR. ALREADY EXISTS +;ASSUMES NON-ROOT ASCIZ DIR. PATH NAME POINTED TO BY E +;CREATES NEW DIR. IF MUTATE FAILS +MUTDCM: MOV #CRETDR,XROUT + JSR PC,MUTWRD + BEQ 1$ ;Z SET IF DIR. WAS CREATED + T +1$: RTS PC + + + +;MUTATE TMPCAP TO FILE +;MESSAGE PRINTED IF FILE ALREADY EXISTS +;ASSUMES NON-ROOT ASCIZ FILE PATH NAME POINTED TO BY E +;CREATES NEW FILE IF MUTATE FAILS +MUTFCM: MOV #CRETFL,XROUT + JSR PC,MUTWRD + BEQ 1$ + T +1$: RTS PC + + + + + + + + + + +;GET A TMPCAP TO FILE OR DIR. WITH INTENTION OF REWRITING IT +;CREATE NEW FILE OR DIR. IF MUTATE FAILS +;RETURNS WITH Z SET IF FAIL; Z CLEAR IF SUCCEED + +;ASSUMES NON-ROOT ASCIZ PATH NAME POINTED TO BY E + ;XROUT CONTAINS ADDR OF WHICH CREATE ROUTINE TO USE (FOR FILE OR DIR.) + +MUTWRD: CLR A ;FIND END OF STRING + JSR PC,SCHAR ;PTR RET. IN D + MOV D,TMPWRD ;SAVE PTR TO END OF NAME +1$: JSR PC,BUTLST ;SPLIT STRING INTO ALL-BUT-LAST & LAST WORDS + BNE 1$ ;CONTINUE UNTIL ALL WORDS SEPARATED BY 0'S + +;D LEFT POINTING TO END OF 1ST WORD +;MUTATE DOWN PATH NAME WORD BY WORD +MUTWD1: SAVE ;LAST GOOD TMPCAP + MOV TMPCAP,A + JSR PC,COPCP1 ;GET ANOTHER COPY TO MUTATE + JSR PC,MUTDR1 ;TRY TO MUTATE- NAME POINTED TO BY E + BEQ MUTWD2 ;BRANCH IF MUTATE FAILED + +;NOW HAVE NEW TMPCAP FROM THE MUTATE + REST ;DELETE PREV. GOOD TMPCAP + JSR PC,DELCAP + INC D ;POINT TO NEXT CHAR AFTER THE 0 + CMP D,TMPWRD ;IS THIS LAST WORD? + BLT 3$ ;IF NOT, REQUIRE MUTATE TO A DIR.(NOT FILE) +;LAST WORD: HAVE CAP TO FILE OR DIR. + CMP #CRETFL,XROUT ;SHOULD CAP BE TO FILE? + BNE 1$ ;BRANCH IF NOT + JSR PC,FILCHK ;MAKE SURE TMPCAP IS TO FILE + BR 2$ ;DONE +1$: JSR PC,DIRCHK ;MAKE SURE TMPCAP IS TO DIR. +;REACHED END OF STRING WITH ALL MUTATES SUCCEEDING +2$: CLZ ;INDICATE F. OR D. EXISTED + RTS PC + +;NOT LAST WORD +3$: JSR PC,DIRCHK ;MUST BE DIR. + MOV D,E ;RESET NAME POINTER AND + CLR A ;POINT TO NEXT DELIMITER 0 + JSR PC,SCHAR ;PTR RET. IN D + BR MUTWD1 ;MUTATE TO NEXT LEVEL + +;MUTATE FAILED, SO CREATE NEW FILE OR DIR. AT NEXT LEVEL +MUTWD2: JSR PC,FSHTMP ;FLUSH BAD TMPCAP + REST ;LAST GOOD TMPCAP + CLR A ;FIND END OF WORD (TERM. BY "0") + JSR PC,SCHAR ;PTR RET. IN D + JSR PC,@XROUT ;DO APPROPRIATE CREATE ROUTINE + SEZ ;INDICATE F. OR D. WAS CREATED + RTS PC + + +;MAP PAGE IN OR OUT +;ASSUMES A CONTAINS CAP TO A DIR. OR FILE OR THE DELETE PAGE ARG. (.DLPAG) +MAP: SAVE <#0,#0,A,#.CRRD!1> ;CAP, TYPE OF PAGE & SPHERE CAP TO SELF + MOVB #DIRPG+20,3(P) ;PAGE IN BOTH I- AND D-SPACE + $MAP + CMP A,#.DLPAG ;SEE IF PAGE WAS DELETED + BEQ MAP1 ;IF SO, DON'T COMPUTE EOF + +;ENTRY TO RE-CALCULATE DIR. LENGTH +MAPEOF: MOV #DIRPAD,C ;GET ABSOLUTE EOF FOR A DIR. + MOV 6(C),ABSEOF ;2ND EOF (BYTE POINTER) + ADD C,ABSEOF +MAP1: RTS PC + + +;MAKE TMPCAP INTO NEW CAP WHOSE LOCATION IN A +;DELETES OLD CAP IN THAT LOCATION +NEWCAP: SAVE ;SAVE LOC. + MOV (A),A ;PUT THE CAP IN A + JSR PC,DELCAP ;DELETE IT + REST ;GET BACK ITS LOCATION + MOV TMPCAP,(A) ;PUT TMPCAP INTO THE LOC. + CLR TMPCAP + RTS PC + + +;MUTATE TO THE FILE WHOSE ASCIZ NAME STRING POINTED TO BY E +;DIRECTORY CAPABILITY IN TMPCAP +;IF FAIL, Z SET & STACK RESET +;IF SUCCEED, Z CLEAR + +MUTFIL: SAVE <#0,E,TMPCAP> + BIS #.FAMU,(P) ;FILE MUTATE FUNCTION + .INVOK + BNE FILCHK ;CALL SUCCEEDED + ADD #6,P ;CALL FAILED: RESET STACK + SEZ + RTS PC + + + +;CHECK THAT GIVEN TMPCAP IS TO A FILE +FILCHK: SAVE <#FILBLK,#10,TMPCAP> + BIS #.FARI,(P) + $INVOK + BIT #.FADIR,FILBLK+2 + BEQ 2$ ;FADIR SHOULD NOT BE SET + ERROR <; ARGUMENT NOT A FILE: >,,TYPEIT +2$: CLZ + RTS PC + + + +;CREATE FILE WHOSE CAPABILITY RETURNED IN TMPCAP +;FILE NAME IS ASCIZ STRING POINTED TO BY E +CRETFL: SAVE <#0,E,TMPCAP> + BIS #.FAAD,(P) ;FILE ADD FUNCTION + .INVOK + BNE 2$ ;EXIT IF SUCCEED + BR DIRFUL ;SEE IF DIR. FULL- IT RETURNS TO CLOOP OR BPT'S +2$: RTS PC + + + +;CREATE DIR. WHOSE CAP RETURNED IN TMPCAP +;ASSUMES DIR. NAME IS ASCIZ STRING POINTED TO BY E +CRETDR: JSR PC,CRETFL ;CREATE AS A FILE FIRST + SAVE <#0,TMPCAP> ;MAKE IT 1 BLOCK LONG + .WRDO + ERRORF <; DIRECTORY CREATION ERROR> + SAVE <,,TMPCAP> ;TURN IT INTO A DIR. + BIS #.FAMD,(P) + $INVOK + RTS PC + + +;ASSUMES .INVOK FAILED +;SEE IF FAILED BECAUSE DIRECTORY FULL +;ON EXIT, RETURNS TO CLOOP + ;I.E., FUNCTION CANNOT BE CONTINUED SINCE CALL FAILED +DIRFUL: $GERRW ;GET ERROR WORD + TST (P)+ + CMP (P)+,#.EDRF + BNE 1$ + ERROR <; CAN'T ADD FILE-- DIRECTORY FULL> +1$: ERROR <; UNDETERMINED FILE ADD ERROR: >,,TYPEIT ;SOME OTHER ERROR + + + + +.STITLE ERROR ROUTINES + +;ENTRY ASSUMES Z SET FOR FAILURE; Z CLEAR FOR SUCCESS +FERROT: BEQ ERRROT + ;THIS CODING EXECUTED IF NO ERROR + ;DOES NOTHING BUT SKIP OVER THE GENERATED MACRO CODING + TSTB (F)+ ;SKIP TEXT + BNE .-2 + INC F ;ALIGN TO .EVEN + BIC #1,F + TST (F)+ ;SKIP CAPABILITIES + BNE .-2 + TST (F)+ ;SKIP ROUTINE & FALL THROUGH + RTS F + +ERRROT: MOV F,A ;F CONTAINS RET. ADDR, OF WHERE ERROR OCCURRED + JSR PC, PRON ;PRINT ADDR IN OCTAL +1$: MOVB (F)+,A + BEQ ERRRO1 ;SKIP NULL TEXT + JSR PC,TYO ;PRINT TEXT CHAR BY CHAR + BR 1$ +ERRRO1: INC F ;ALIGN TO .EVEN + BIC #1,F + JSR PC,CRLF ;PRINT CRLF +ERRRO3: MOV (F)+,B ;PICK UP CAPABILITY TO FLUSH + BEQ ERRRO2 + MOV (B),A ;THE CAP + JSR PC,DELCAP ;DELETE CAP + CLR (B) ;CLEAR IT + BR ERRRO3 +ERRRO2: MOV (F)+,A ;THE ROUTINE TO CALL + BEQ .+4 ;BRANCH IF ADDR IS 0 + JSR PC,(A) ;CALL IT + MOV #IP,P ;RESET THE PDL + JMP CLOOP + + + .STITLE I/O ROUTINES + +;READ A LINE FROM TTY INTO THE LINBUF BUFFER +;RETURN WITH Z CLEAR IF ANYTHING TYPED BEFORE +;REPLACES CRLF WITH A "0" BYTE +;ON EXIT, E POINTS TO LINBUF; D LEFT POINTING TO THE 0 + +GETLIN: MOV #LINBUF,E ;E <- PTR TO LINE BUFFER + MOV E,D ;SAVE IT IN D + MOV #LINBFL-1,C ;HIGHEST LINBUF ADDR +GETLI3: JSR PC,GETLI1 ;GET A NON-RUBOUT + CMP #15,A ;IS IT A ? + BEQ GETLI2 ;IF SO, END + JSR PC,TYO ;NO, SO ECHO IT + MOVB A,(D)+ ;SAVE IT + SOB C,GETLI3 ;99 CHARS/LINE, NOT INCL. + +;PERMIT RUBOUT AS 100TH CHAR; ALSO, +;IGNORE ALL CHARS AFTER 100, UNTIL GET A +GETLI4: JSR PC,GETLI1 ;GET A NON-RUBOUT + CMP #15,A + BEQ GETLI2 + TST C ;ANY SPACE IN BUFFER? + BNE GETLI3 + BR GETLI4 +GETLI2: JSR PC,CRLF + CLRB (D) ;PUT A "0" AT END OF STRING + CMP D,E ;WAS ANYTHING TYPED? (SETS Z IF NOT=) + RTS PC + + +GETLI1: JSR PC,TYI ;GET A CHAR + CMPB #177,A ;IS IT A RUBOUT? + BEQ GETL10 + RTS PC ;NO, RETURN WITH IT +GETL10: CMP E,D ;ANYTHING TO RUB? + BEQ GETLI1 ;NOPE + JSR PC,SLTYPE ;TYPE THE OPEN SLASH +GETLI5: MOVB -(D),A + JSR PC,TYO ;ECHO RUBBED OUT CHAR + INC C ;ONE MORE SPACE IN BUFFER + CMP E,D ;ALL RUBBED OUT? + BEQ GETLI6 ;YES + JSR PC,TYI ;GET NEXT CHAR + CMP #177,A ;IS IT ANOTHER RUBOUT? + BEQ GETLI5 + JMP SLTYPE +GETLI6: JSR PC,SLTYPE ;END SLASH + JSR PC,CRLF + BR GETLI1 + + + +;GET YES OR NO ANSWER FROM USER +;IF ANSWER NOT "Y" COMMAND TERMINATES +GETANS: JSR PC,TYI ;GET ANSWER + JSR PC,TYO ;ECHO ON TTY + JSR PC,CRLF ;JUMP TO NEXT LINE + CMPB #'Y,A + BEQ 4$ ;ABORT CMD IF NOT A "Y" + ERROR <; COMMAND CANNOT BE COMPLETED> +4$: RTS PC + + + +;PRINT THE CHAR IN A +TYO: SAVE + CMPB #33,A ;IF CHAR IS "ALTMODE," TURN IT INTO A "$" + BNE 1$ + MOV #44,A +1$: SAVE + $BYTO ;TYPE THE CHARACTER + REST + RTS PC + + +;INPUT A CHAR INTO A +TYI: SAVE + $BYTI ;GET AN INPUT CHARACTER + REST ;PUT IT IN A + CMPB #'Z-100,A ;CHECK FOR ^Z + BNE TYI1 + BPT ;IF SO, JUMP TO HIGHER LEVEL + BR TYI +TYI1: RTS PC + + +;PRINT A CAR. RET./LINE FEED +CRLF: SAVE + MOV #15,A + JSR PC,TYO + REST + RTS PC + + +;PRINT A "/" +SLTYPE: SAVE + MOVB #'\,A + JSR PC,TYO ;USED TO BOUND RUBBED OUT CHARS + REST + RTS PC + + +;PRINT ASCIZ STRING POINTED TO BY E +;SKIP TO NEXT LINE ON TTY +TYPEIT: SAVE +TYPEI2: MOVB (E)+,A ;PUT CHAR IN A + BEQ TYPEI1 ;IS IT 0? + JSR PC,TYO ;IF NOT, PRINT IT + BR TYPEI2 ;GET NEXT CHAR +TYPEI1: REST ;REACHED END OF STRING + JSR PC,CRLF ;SKIP A LINE ON TTY + RTS PC + + + +;PRINT ASCIZ STRING POINTED TO BY E +;E CONTAINS PROGRAM COUNTER (PC) +;ON EXIT, E PTS TO NEXT .EVEN BYTE AFTER THE STRING +TYPES: SAVE +TYPES1: MOVB (E)+,A + BEQ TYPES2 + JSR PC,TYO + BR TYPES1 +TYPES2: INC E ;ALIGN TO .EVEN + BIC #1,E + REST + RTS E + + + +;PRINTS BLANKS: E CONTAINS NO. TO PRINT +NBLNKS: TST E ;SEE IF ANY TO PRINT + BEQ 2$ + SAVE + MOVB #40,A +1$: JSR PC,TYO + SOB E,1$ + REST +2$: RTS PC + + .STITLE NUMBER CONVERSION ROUTINES + + +;PRINT OCTAL INTEGER AS A DECIMAL NUMBER +;ASSUMES NUMBER TO PRINT IN A +PRDN: SAVE + MOV #10.,D ;DECIMAL BASE + MOV #TYO,CROUT ;INDICATE PRINT NO. AFTER CONVERSION + JSR PC,NCVT ;GO PRINT IT OUT + REST + RTS PC + + +;PRINT OCTAL INTEGER AS AN OCTAL NUMBER +;ASSUMES NUMBER TO PRINT IN A +PRON: SAVE + MOV #8.,D ;OCTAL BASE + MOV #TYO,CROUT ;INDICATE PRINT NO. AFTER CONVERSION + JSR PC,NCVT ;GO PRINT IT OUT + REST + RTS PC + + + +;CONVERT OCTAL INTEGER INTO CHAR CODES IN GIVEN BASE, + ;AND OUTPUT IT (EITHER PRINT ON TTY OR TRANSFER TO BUFFER) +;ASSUMES NUMBER TO PRINT IN A, + ;BASE IN D, + ;CROUT CONTAINS ADDR OF OUTPUT ROUTINE +NCVT: SAVE + CLR C ;DIGIT COUNTER + MOV A,B ;NUMBER IN B + BGE 2$ ;POSITIVE + BEQ 1$ ;ZERO + + NEG B ;NEGATIVE + MOV #'-,A ;PRINT "-" + JSR PC,TYO + BR 2$ + +1$: INC C ;PRINT 1 CHAR, THE "0" + BR 4$ + +2$: INC C ;COUNT A SAVED DIGIT + CLR A + DIV D,A ;QUOTIENT IN A + SAVE ;SAVE REMAINDER IN B (A NEW DIGIT) + MOV A,B ;IS QUOTIENT 0? + BNE 2$ ;IF NOT, GET MORE DIGITS + +;HAVE REACHED END +3$: REST ;POP A DIGIT +4$: ADD #60,A ;CONVERT TO CHAR + JSR PC,@CROUT ;OUTPUT IT + SOB C,3$ + REST + RTS PC + + +;PRINT OCTAL INTEGER < 10 AS DECIMAL NO. WITH LEADING 0 +;ASSUMES NUMBER IN A +ZPRDN: CMP #10.,A ;IS NO. < 10? + BLE 1$ ;IF NOT, USE NORMAL PRINT ROUTINE + SAVE + MOV #'0,A ;PRINT A "0" + JSR PC,TYO + REST +1$: JMP PRDN + + +;CONVERT OCTAL INTEGER TO DECIMAL (CHAR CODES) +;INSERT AT DESTINATION POINTED TO BY E +CVDN: SAVE + MOV #10.,D ;BASE + MOV #MVNBUF,CROUT ;ROUT.TO MOVE CHAR TO LOC. IN NAMBUF + JSR PC,NCVT + REST + RTS PC + + + + + + + + + .END START