Google
 

Trailing-Edge - PDP-10 Archives - BB-F494Z-DD_1986 - 10,7/sed1fi.mac
There are 10 other files named sed1fi.mac in the archive. Click here to see a list.
TITLE	SED1FI - SED SET-FILE AND WINDOW COMMANDS
SUBTTL	A CHRISTOPHER HALL FECIT

;COPYRIGHT (C) DIGITAL EQUIPMENT CORPORATION 1979,1983.

	SEARCH	SEDSYM
	SALL

IFN TOPS10,<
	SEARCH	UUOSYM
	TWOSEG
	RELOC	400000
>
IFE TOPS10,<
	SEARCH	MONSYM
>

;**********************************************************************
;HERE TO SET UP A NEW FILE FOR EDITING

SETFIL::HRRZM	P,SAVEAC+11	;SET READ-WRITE FLAG POSITIVE (IE, NONE)
	MOVEM	F,SAVEAC	;SAVE THE FLAGS FOR LATER
	TRZE	F,RDO		;ASSUME WILL WRITE FILE - CAN WRITE NOW?
	TLZA	F,CHG		;NO - FORGET ANY CHANGES THAT WERE MADE; SKIP
SETFLS::MOVEM	F,SAVEAC	;SAVE THE FLAGS FOR LATER
	MOVE	T2,PARPTR	;END PARAMETER WITH A NULL
	SETZ	T1,		;GET A NULL
	IDPB	T1,T2
	MOVE	PT,[POINT 7,PARBUF]
	ILDB	T1,PT		;GET FIRST CHARACTER OF FILESPECS
	CAIE	T1,"/"		;GOT JUST A STRING OF SWITCHES?
	JRST	SETFL0		;NO - CONTINUE
	PUSHJ	P,RESTPM	;YES - CLEAR ENTER MODE
	PUSHJ	P,SWHMNY	;SET UP THE SWITCHES
	SKIPN	AGNFLG		;WANT TO SET TO THE SAME FILE AGAIN?
	JRST	SETNPM		;NO - GO SET UP THE ALTERNATE FILE

	SETZM	AGNFLG		;YES - CLEAR THE AGAIN FLAG
	MOVE	T3,[POINT 7,FILSPC]
	MOVE	T4,[POINT 7,PARBUF]
SETAG0:	ILDB	T1,T3		;MOVE CURRENT FILESPECS TO PARM BUFFER
	IDPB	T1,T4		;AS IF THE USER TYPED THEM IN
	JUMPN	T1,SETAG0
	MOVEM	T4,PARPTR	;SAVE POINTER TO END OF PARAMETER

SETFL0:	MOVE	T1,[OLDSPC,,SVASPC] ;COPY OLD SPECS TO SAVE AREA
	BLT	T1,SVASPC+SPCSIZ+3  ;  (COPY THE SAVED POINTERS, TOO)
	MOVE	T1,[FILSPC,,OLDSPC] ;AND CURRENT SPECS TO OLD AREA
	BLT	T1,OLDSPC+SPCSIZ-1
IFE TOPS10,<
	DMOVE	T1,EXTPTR	;SAVE EXTENSION AND ITS POINTER
	DMOVEM	T1,SAVEXP
>
	SKIPA	T1,SAVEAC	;SAVE THE ORIGINAL CURRENT FLAGS
SETFLC::MOVE	T1,F		;SAVE THE CURRENT FLAGS
	MOVEM	T1,SAVEFG
	MOVE	T1,DISPTR	;SAVE CURRENT DISPLAY POINTER
	MOVEM	T1,SAVEDP
	MOVEM	SL,SAVESL	;SAVE SLIDE
	MOVE	T3,[POINT 7,FILSPC]
	PUSHJ	P,PELS.F	;PICK UP USER'S FILESPEC, IF ANY
	MOVEM	RW,SAVERW	;SAVE POSITION AGAIN IN CASE OF CUR MVMT
	HRLM	CM,SAVERW
	PUSHJ	P,ERASPM	;ERASE PARAMETER
	SETZM	WINDIS		;IF WINDOWING BE SURE TO DISPLAY THE FILE
	SETZM	MFLPTR		;FORGET INDIRECT STUFF IF USER GIVES A FILE
	TRZE	F,IND		;WANT TO LOOK AT FILES INDIRECTLY?
	JRST	SETIND		;YES - HANDLE SEPARATELY
	PUSHJ	P,PNTSTT	;SET UP POINTERS TO START OF FILE
	PUSHJ	P,PARSEF	;PARSE FILESPEC AND (MAYBE) SWITCHES
	TLZ	F,PCM!FLG!FNC	;CLEAR MARK AND PARSE FLAGS

IFN TOPS10,<
SETFL1::TLZ	F,FLG		;CLEAR FLAG FROM PARSEF
IFN FTSFD,<
	MOVE	T1,[SFDLVL+4,,FILPTH]
	PATH.	T1,
	  JRST	SETERR
>
	OPEN	2,FILBLK	;OPEN FILE FOR EDITING
	  JRST	SETERR
	LOOKUP	2,FILFIL	;SET UP FILE FOR READING
	  JRST	SETERR

	SETOM	INJFN		;SAY FILE HAS BEEN SET UP
	MOVE	T1,FILFIL+5	;GET SIZE OF FILE (IN WORDS)
	CAILE	T1,MAXSIZ*200	;IS FILE TOO BIG?
	JRST	SSZERR		;YES - ERROR
	MOVEM	T1,FILSIZ	;NO - SAVE FILE SIZE
	HRRZ	T2,DISPTR	;GET DISPLAY POINTER ADDRESS
	SUBI	T2,BUFFER
	CAMGE	T1,T2		;IS IT POINTING BEYOND THE BUFFER?
	JRST	[MOVE  T2,[010700,,BUFFER-1]
		 MOVEM T2,DISPTR ;YES - POINT TO START OF BUFFER
		 JRST  .+1]
;	LSH	T1,-7		;GET SIZE IN BLOCKS
;	MOVEM	T1,FILBSZ	;SAVE IT, TOO
IFE FTSFD,<
	MOVE	T1,FILFIL+16	;GET ACTUAL DEVICE NAME
	MOVEM	T1,FILBLK+1	;SAVE IN OPEN BLOCK, AND GET WHAT'S THERE
>
	ENTER	2,FILFIL	;SEE IF FILE CAN BE WRITTEN
	  TRO	F,RDO		;IT CAN'T - SET READ ONLY FLAG
	HLLZS	FILFIL+3	;CLEAN UP FILESPEC BLOCK
	SETZ	T1,
	EXCH	T1,FILFIL+4
	MOVEM	T1,SAVEAC+10
IFN FTSFD,<
	SETZM	FILFIL+5
	MOVEI	T2,2		;SEE WHAT THE PDP-10 THINKS THE PATH IS
	MOVEM	T2,FILPTH
	MOVE	T1,[SFDLVL+4,,FILPTH]
	PATH.	T1,
	  JRST	SETERR		;(THIS SHOULD NEVER HAPPEN)
	MOVN	T2,T2		;SAVE SET-PATH ARGUMENT
	EXCH	T2,FILPTH	;  AND GET THE DEVICE NAME
	MOVEM	T2,FILBLK+1	;SAVE DEVICE IN OPEN BLOCK
	SETZM	FILPTH+1	;CLEAN UP THE PATH BLOCK
	SETZM	FILFIL+1	;  AND THE LOOKUP BLOCK
	MOVE	T1,FILPTH+2	;GET THE PPN
>
IFE FTSFD,<
	MOVE	T1,[FILFIL+4,,FILFIL+5]
	BLT	T1,FILFIL+LUKLEN ;ZERO REST OF FILE BLOCK
	MOVE	T1,FILFIL+1
>
	MOVEM	T1,FILPPN	;SAVE THE REAL FILE PPN

	JUMPLE	DO,SETF10	;UNPARSE NOT NEEDED IF NO PARAMETER WAS GIVEN
	PUSHJ	P,UNPARS	;NOW UNPARSE THE FILESPECS
	SKIPE	RSCANF		;GOT A FILE FROM RESCAN?
	JRST	SETF10		;YES - DON'T SAVE PREVIOUS FILE
	TLNN	DO,200000	;WORKING ON AN INDIRECT FILE,
	SKIPN	OLDSPC		;  OR IS THERE A PREVIOUS FILE?
	JRST	SETF10		;EITHER - DON'T SAVE OLD FILE
	PUSHJ	P,SAMFIL	;AND SEE FILE IS SAME AS PREVIOUS ONE
	TLNE	F,SMF		;ARE FILES THE SAME?
	JRST	[RELEAS 2,
		 JRST   SETWIN] ;YES - JUST SET THE THE NEW POSITION
	MOVEI	T4,OLDSPC	;NO - PREPARE TO SAVE FILE
	MOVEI	PT,OLDBLK
	MOVE	T1,SAVEDP
	MOVEM	T1,DISPTR
IFN FTSFD,<
	MOVE	T1,[SFDLVL+4,,OLDPTH]
	PATH.	T1,		;SET THE PATH TO THE OLD FILE
	  JRST	SETERR
>
	EXCH	F,SAVEFG	;GET OLD FILE FLAGS
	PUSHJ	P,SAVFIL	;SAVE THE OLD FILE
	EXCH	F,SAVEFG	;GET NEW FILE'S FLAGS BACK
	MOVE	T1,[010700,,BUFFER-1]
	EXCH	T1,DISPTR
	MOVEM	T1,SAVEDP

SETF10:	SETZM	RSCANF		;CLEAR FILE-FROM-RESCAN FLAG
IFN FTSFD,<
	MOVE	T1,[SFDLVL+4,,FILPTH]
	PATH.	T1,		;PATH BACK TO THE NEW FILE
	  JRST	SETERR
>
	MOVEI	T1,BUFFER-1	;SHRINK CORE TO GET RID OF OLD FILE
	CORE	T1,
	  HALT
	MOVE	T1,FILSIZ	;EXPAND CORE TO ACCOMMODATE NEW FILE
	ADDI	T1,BUFFER
	CAMGE	T1,.JBREL	;IS IT WITHIN PRESENT CORE?
	JRST	[SETZM BUFFER	;YES - CLEAR OUT ALL OF CORE
		 MOVE  T2,[BUFFER,,BUFFER+1]
		 MOVE  T3,.JBREL
		 BLT   T2,(T3)
		 JRST  .+1]
	ADDI	T1,2000
	CORE	T1,
	  JRST	SSZERR		;ERROR - FILE TOO BIG
	MOVN	T1,FILSIZ
	HRLM	T1,FILCCL	;READ ENTIRE FILE IN
	CAIE	T1,0		;UNLESS IT'S A ZERO-LENGTH FILE
	INPUT	2,FILCCL
	RELEAS	2,		;GET RID OF CHANNEL
	MOVE	T1,FILSIZ
>
IFE TOPS10,<
SETFL1::MOVE	T1,[GJ%OLD+GJ%SHT]
	HRROI	T2,FILSPC	;GET A JFN FOR THIS FILE
	GTJFN
	  JRST	SETERR
	JUMPLE	DO,SETF11	;UNPARSE NOT NEEDED IF NO PARAMETER WAS GIVEN
	HRRZM	T1,NEWJFN	;SAVE FILE'S JFN IN A SCRATCH AREA FOR NOW
	PUSHJ	P,UNPARS	;READ THE SPECS BACK FROM THE MONITOR

	SKIPE	RSCANF		;GOT A FILE FROM RESCAN?
	JRST	SETF10		;YES - DON'T SAVE PREVIOUS FILE
	TLNN	DO,200000	;WORKING ON AN INDIRECT FILE,
	SKIPN	OLDSPC		;  OR IS THERE A PREVIOUS FILE?
	JRST	SETF10		;EITHER - DON'T SAVE OLD FILE
	PUSHJ	P,SAMFIL	;SEE FILE IS SAME AS PREVIOUS ONE
	TLNE	F,SMF		;ARE FILES THE SAME?
	JRST	[MOVE  T1,NEWJFN ;YES - JUST SET THE THE NEW POSITION
		 CLOSF
		  JRST SETWIN
		 JRST  SETWIN]
	MOVEI	T4,OLDSPC	;NO - PREPARE TO SAVE FILE
	MOVE	T1,SAVEDP
	MOVEM	T1,DISPTR
	PUSHJ	P,SAVFIL	;SAVE THE OLD FILE
	MOVE	T1,[010700,,BUFFER-1]
	EXCH	T1,DISPTR
	MOVEM	T1,SAVEDP

SETF10:	SETZM	RSCANF		;CLEAR FILE-FROM-RESCAN FLAG
	MOVE	T1,NEWJFN	;MAKE THE NEW FILE'S JFN OFFICIAL
SETF11:	MOVEM	T1,INJFN	;  (AND GET JFN IN T1)
	MOVEI	T2,OF%THW+OF%RD+OF%WR+OF%DUD+OF%PDT
	OPENF
	  JRST	SETERC		;FAILED - TRY TO OPEN FROZEN
SETF12:	SETO	T1,		;UN-MAP THE PREVIOUS FILE
	MOVE	T2,[400000,,BUFBLK]
	MOVE	T3,[PM%CNT]
	HRR	T3,FILBSZ
	PMAP

	MOVE	T1,INJFN	;GET THE NEW FILE'S JFN
	MOVE	T2,[1,,.FBBYV]	;FIND BYTE SIZE OF THE FILE
	MOVEI	T3,T4		;  IN T4
	GTFDB
	HLRZ	T4,T4
	ANDI	T4,7700		;CLEAR OUT ALL FIELDS BUT BYTE SIZE
	MOVEI	PT,1		;ASSUME BYTE SIZE IS 7
	CAIN	T4,4400		;IS IT REALLY 36?
	MOVEI	PT,5		;YES - MAKE ADJUSTMENT

	SIZEF			;FIND THE SIZE OF THE FILE
	  JRST	SETERC		;FAILED - TRY TO OPEN FROZEN
	IMUL	T2,PT		;CONVERT BYTE COUNT INTO CHARACTER COUNT
	MOVEM	T2,FILSIZ	;AND SAVE IT
	MOVEM	T3,FILBSZ	;AND BLOCK COUNT

	CAIL	T3,777-BUFBLK	;IS FILE TOO BIG?
	JRST	SSZERR		;YES - TOUGH LUCK
	HRLZ	T1,INJFN	;NO - READ IN THE ENTIRE FILE
	MOVE	T2,[400000,,BUFBLK]
	MOVE	T4,T3		;SAVE NUMBER OF PAGES IN FILE
	ADD	T3,[PM%CNT+PM%RD+PM%CPY]
	PMAP

	SETO	T1,		;SNIFF ALL PAGES SO THEY'LL BE LOCALLY COPIED
	MOVEI	T2,BUFFER
SETF1A:	ANDM	T1,(T2)		;WRITE INTO A PAGE
	ADDI	T2,1000		;GO TO NEXT PAGE
	SOJG	T4,SETF1A	;LOOP THROUGH ALL PAGES
	MOVE	T1,INJFN	;DONE WITH THE INPUT FILE - GET RID OF IT
	HRLI	T1,(CO%NRJ)	;BUT KEEP THE JFN FOR THE BACKUP FILE
	CLOSF			;CLOSE THE FILE
	  JFCL
	MOVE	T1,FILSIZ	;GET BYTE SIZE
	IDIVI	T1,5		;CONVERT TO WORDS
>
	MOVE	EN,[010700,,BUFFER]
	ADD	EN,T1		;SET UP POINTER TO END OF FILE
	TRO	F,GFL		;NOTE THAT A FILE HAS BEEN SET UP
	TDZ	F,[FLG!PCM,,CRE] ;CLEAR EXTENSION, MARK, AND CREATE FLAGS
	SKIPN	DISPTR		;WANT TO USE PRE-SET POINTERS?
	PUSHJ	P,PRESET	;YES - SET THEM UP
	SETZM	EEEPTR		;CLEAR FREE-EXTENSION POINTER
IFN FTJOUR,<
	TLNE	TM,JRW		;WANT TO WRITE A JOURNAL?
	PUSHJ	P,JRNSTT	;YES - START IT UP
>
	SKIPN	(EN)		;GOT A WORD ENTIRELY OF NULLS?
	SOJA	EN,.-1		;YES - BACK UP OVER IT
	CAMN	EN,[010700,,BUFFER-1] ;IF THERE'S NOTHING IN THE BUFFER,
	AOJA	EN,SETCR2	      ;PUT IN A FREE CARRIAGE RETURN
	MOVE	T1,EN		;GET POINTER TO END OF FILE
	AOJA	EN,SETCR0	;MAKE SURE FILE ENDS WITH A CRLF

SETCR:	ADD	T1,[70000,,0]	;BACK UP END POINTER A NOTCH
	CAIGE	T1,0
	SUB	T1,[430000,,1]
SETCR0:	LDB	T2,T1		;GET CHARACTER
	JUMPE	T2,SETCR	;SKIP IF NULL
	CAIE	T2,12		;ELSE GOT A LINEFEED?
	JRST	SETCR2		;NO - GO ADD A CRLF
	ADD	T1,[70000,,0]	;YES - SEE IF IT'S PRECEDED BY A <CR>
	CAIGE	T1,0		;BACK UP A NOTCH
	SUB	T1,[430000,,1]
	LDB	T2,T1		;GET CHARACTER
	CAIN	T2,15		;GOT A <CR>
	JRST	SETRDO		;YES - O.K.
				;NO - FALL TO ADD A CRLF
SETCR2:	MOVE	T1,[BYTE (7) 15,12] ;GET A <CRLF>
	MOVEM	T1,1(EN)	;SAVE AS LAST WORD OF FILE
	AOJA	EN,SETRDO	;NOW GO CHECK FOR LINE NUMBERS

;NOW CHECK READ-WRITE STATUS. IF THE FILE ACCESS DOES NOT PERMIT WRITING,
;IT'S READ-ONLY. ELSE USE THE SWITCH THE USER GAVE IN THE SET-FILE COMMAND.
;ELSE IT'S READ-ONLY IF GREFLG IS SET. ELSE IT'S WRITEABLE.

;IF THE FILE IS WRITEABLE, SEE IF LOW ORDER BITS ARE ON IN FILE WORDS: IF
;SO, FILE HAS LINE NUMBERS OR IS NOT TEXT. IF THE USER WANTS TO STRIP LINE
;NUMBERS, DO SO AND CONTINUE. ELSE SET READ-ONLY FLAG AND WARN THE USER.

;(GOSH, YOU WONDER HOW ANY FILE ENDS UP WRITEABLE)

SETRDO:
IFE TOPS10,<
	TLNE	DO,100000	;IS THIS THE END OF A SAVE (COMMAND OR INC'L)?
	JRST	SETWIN		;YES - IT CAN'T BE READ-ONLY
>
	TRNE	F,RDO		;IS FILE ALREADY READ-ONLY?
	JRST	SETRD5		;YES - NO FURTHER CHECKING IS NECESSARY
	SKIPG	T1,SAVEAC+11	;DID USER GIVE A READ OR WRITE SWITCH?
	JRST	SETRD3		;YES - LET IT OVERRIDE ANYTHING ELSE
	SKIPE	GREFLG		;NO - SHOULD ALL FILES BE MARKED READ-ONLY?
	JRST	SETRD7		;YES - SET READ-ONLY; NO ERROR MESSAGE
;	JRST	SETRD5		;YES - SET READ-ONLY
	JRST	SETRD4		;NO - SKIP THIS

SETRD3:	JUMPL	T1,SETRD5	;IF USER GAVE READ, SET READ-ONLY
SETRD4:	MOVE	T2,BUFFER	;GET FIRST WORD OF BUFFER
	TRNN	T2,1		;IS THE LINE NUMBER FLAG ON?
	JRST	SETWIN		;NO - GO CHECK FOR A WINDOW
	SKIPE	STRFLG		;YES - WANT TO STRIP LINE NUMBERS?
	JRST	SETSTP		;YES - DO SO (RETURN TO SETWIN)
	SKIPA	T1,[[ASCIZ /######Line numbers - read only/]]
SETRD5:	MOVEI	T1,[ASCIZ /######File cannot be modified/]
SETRD6:	PUSHJ	P,ERRDSP	;DISPLAY THE MESSAGE
SETRD7:	TRO	F,RDO		;MARK FILE AS READ ONLY

;NOW SEE IF WINDOWING IS IN EFFECT. IF SO, CHANGE WINDOWS (MAYBE).

SETWIN:	TLNE	TM,WDW		;WANT WINDOWING,
	SKIPE	CRRFLG		;  AND WANT TO REPLACE THE ALTERNATE FILE?
	JRST	SETCUR		;NOT BOTH - JUST DISPLAY THE FILE
IFE TOPS10,<
	TLNE	DO,100000	;IS THIS THE END OF A SAVE (COMMAND OR INC'L)?
	JRST	SETCUR		;YES - DON'T CHANGE WINDOWS
>
	SKIPE	HOMPOS		;BOTH - IN TOP WINDOW?
	JRST	[SETZ  T3,	;NO - MOVE TO TOP
		 EXCH  T3,HOMPOS
		 MOVEI T1,"^"	;GET UPWARD-POINTING SEPARATOR
		 SETZM CPG(TM)	;MAKE CLEAR-TO-EOP NOT WORK
		 SETZM ILN(TM)	;AND INSERT-LINES
		 SETZM DLN(TM)	;AND DELETE-LINES
		 SOJA  T3,SETWN1]
	MOVE	T3,LPP(TM)	;YES - GET CURRENT SCREEN LENGTH
	MOVEM	T3,HOMPOS	;SAVE AS ROW POSITION OF HOME
	SETO	T3,		;PUT SEPARATOR ON LINE ABOVE HOME
	DMOVE	T1,SAVILN	;RESTORE INSERT- AND DELETE-LINE SEQUENCES
	MOVEM	T1,ILN(TM)
	MOVEM	T2,DLN(TM)
	MOVE	T1,SAVCPG	;RESTORE CLEAR-TO-EOP SEQUENCE
	MOVEM	T1,CPG(TM)
	MOVEI	T1,"v"		;GET DOWNWARD-POINTING SEPARATOR
SETWN1:	PUSHJ	P,WINSEP
	SKIPE	WINDIS		;IS THERE A DISPLAY IN BOTH WINDOWS?
	SETOM	DSPFLG		;YES - DON'T DISPLAY NOW
	SETOM	WINDIS		;EITHER WAY, DON'T DISPLAY NEXT TIME
SETCUR:	MOVS	T1,[OLDSPC,,SVASPC]
	SKIPE	CRRFLG		;WANT TO REPLACE THE CURRENT (NOT OLD) FILE?
	BLT	T1,OLDSPC+SPCSIZ+2 ;YES - COPY THE OLD STUFF BACK
	SETZM	CRRFLG		;CLEAR USE CURRENT FILE FLAG
	SETZM	CHGSPC		;NOTE THAT FILESPECS AREN'T CHANGED (YET)
	SKIPE	OUTFLG		;NEED TO FINISH UP AN /OUT: SWITCH?
	PUSHJ	P,OUTSET	;YES - CHANGE THE FILESPECS TO THOSE IN NEWFIL
	TRZ	F,200		;MAKE SURE CREATE-FILE FLAG IS OFF
	LDB	T1,DISPTR	;IS THE DISPLAY PTR AT THE START OF LINE?
	MOVEI	T4,1
	CAIE	T1,12
	PUSHJ	P,ADVDPT	;NO - MOVE TO THE START OF THE NEXT LINE
IFE TOPS10,<
	TLNE	DO,100000	;IS THIS THE END OF A SAVE (COMMAND OR INC'L)?
	JRST	SETREP		;YES - DON'T RE-DISPLAY IT
>
	SKIPN	CHGSPC		;HAVE FILESPECS CHANGED,
	TLNE	F,SMF		;  OR ARE THE TWO FILES THE SAME?
	JRST	NEWFIL+1	;EITHER - START EDITING THE SAME FILE
	JRST	NEWFIL		;NEITHER - SET UP NEW FILE

IFE TOPS10,<
;HERE WHEN A SAVE (INCREMENTAL OR THE SAVE COMMAND) WAS DONE. INCSAV WENT
;TO SET-FILE TO GET THE FILE BACK. THIS CODE REPAIRS THE SCREEN WITHOUT
;RE-DISPLAYING IT AND MAKES SURE THE FILE IS STILL MARKED "CHANGED".

SETREP:	TLO	F,CHG		;NOTE THAT THE FILE HAS BEEN CHANGED
	TRZ	F,RDO		;AND IT'S NOT READ-ONLY
	PUSHJ	P,FIXBLN	;REPAIR THE BOTTOM LINE OF THE SCREEN
	PUSHJ	P,POSCUR	;RE-POSITION THE CURSOR
	JRST	LOOP		;AND GO GET A NEW COMMAND
>
SSZERR:
IFE TOPS10,<
	MOVE	T1,INJFN	;CLOSE THE NEWLY-GTJFN-ED FILE
	CLOSF
	  JFCL
>
	MOVEI	T1,[ASCIZ /#####File is too large to edit/]
	JRST	STFERR

;HERE TO STRIP THE LINE NUMBERS FROM THE FILE (IF /STRIP SET)
;THE TAB AFTER THE LINE NUMBER HAS TO BE STRIPPED TOO

SETSTP:	MOVEI	PT,BUFFER	;POINT TO START OF BUFFER
	SETZ	T2,		;GET A ZERO TO SAVE
	MOVE	T3,[003777,,-1]	;AND THE ANTI-TAB MASK
SETST1:	MOVE	T1,(PT)		;GET A WORD FROM THE BUFFER
	TRNN	T1,1		;IS THE LINE NUMBER BIT ON?
	JRST	SETST2		;NO - LEAVE IT ALONE
	MOVEM	T2,(PT)		;YES - ZERO THE WORD IN THE BUFFER
	ANDM	T3,1(PT)	;ZERO THE FOLLOWING TAB, TOO
SETST2:	CAIG	PT,(EN)		;AT END OF BUFFER?
	AOJA	PT,SETST1	;NO - LOOP
	MOVEI	T1,[ASCIZ /#######Stripping line numbers/]
	PUSHJ	P,ERRDSP	;DISPLAY THE MESSAGE
	JRST	SETWIN		;YES - DONE

;HERE IF NO PARAMETER WAS TYPED - SET UP PREVIOUS FILE, AND SAVE PRESENT
;ONE AS NEW PREVIOUS ONE

SETNPM::SKIPN	OLDSPC		;ARE THERE OLD FILE SPECS?
	JRST	SETERX		;NO - ERROR
	TLO	DO,400000	;MAKE SETNPM LOOK DIFFERENT FROM SETFIL
IFN TOPS10,<
	MOVEI	PT,FILBLK	;POINT TO NAME OF CURRENT FILE
>
	SETZM	CRRFLG		;MAKE SURE USE-CURRENT-FILE FLAG IS CLEAR
	MOVEI	T4,FILSPC	;POINT TO SPECS (BOTH FOR SAVFIL)
	TLNE	F,SMF		;ARE FILE AND ALTERNATE FILE THE SAME?
	JRST	SETNP0		;YES - DON'T SAVE
	SKIPE	FILSPC		;IS THERE AN ACTIVE FILE?
	PUSHJ	P,SAVFIL	;YES - SAVE IT NOW
SETNP0:	SKIPE	PT,MFLPTR	;GOT MORE FILES IN nnnSED.TMP?
	PUSHJ	P,SETMFL	;YES - SET NEXT ONE UP AS ALTERNATE
	MOVEI	T1,SPCSIZ-1
SETNP1:	MOVE	T2,FILSPC(T1)
	EXCH	T2,OLDSPC(T1)
	MOVEM	T2,FILSPC(T1)
	SOJGE	T1,SETNP1
IFE TOPS10,<
	DMOVE	T1,SAVEXP	;GET SAVED EXTENSION AND ITS POINTER
	EXCH	T1,EXTPTR	;SWAP WITH THE CURRENT ONES
	EXCH	T2,EXTTBL
	DMOVEM	T1,SAVEXP
>
	HRL	RW,CM		;SWAP ROW AND COLUMN POSITIONS
	EXCH	RW,SAVERW
	HLRZ	CM,RW
	HRRZ	RW,RW
	MOVE	T1,DISPTR	;SWAP DISPLAY POINTER
	EXCH	T1,SAVEDP
	MOVEM	T1,DISPTR
	EXCH	SL,SAVESL	;SET UP SLIDE
	MOVE	T1,SAVEFG	;GET THE ALTERNATE FILE'S FLAGS
	MOVEM	F,SAVEFG	;SAVE CURRENT FILE'S FLAGS
	TRZ	F,RDO		;USE CURRENT FLAGS, BUT ALTERNATE'S READ-ONLY
	ANDI	T1,RDO
	OR	F,T1
	TRNN	F,RDO		;IS THE ALTERNATE FILE READ-ONLY?
	TDZA	T1,T1		;NO - SAY IT'S WRITEABLE
	SETO	T1,		;YES - MARK AS READ-ONLY
	MOVEM	T1,SAVEAC+11	;SAVE THE READ-WRITE FLAG
	SKIPN	DISPTR		;NEED TO PARSE SPECS (FROM .TMP)?
	PUSHJ	P,PARSFN	;YES - DO SO
IFN TOPS10,<
IFE FTSFD,<
	MOVE	T1,FILFIL+1	;SET UP THIS FILE'S PPN
	MOVEM	T1,FILPPN
>>
IFE TOPS10,<
	SETOM	SAVEAC+12	;FLAG FILES AS NOT SAME, IF THEY'RE NOT SAME
>
	TLO	F,XPC!XPL!XPB	;NO POINTERS ARE VALID
	TLZ	F,FNC!FLG	;CLEAR FLAG FROM PARSEF AND FENCE
	TLNN	F,SMF		;ARE FILE AND ALTERNATE FILE THE SAME?
	JRST	SETFL1		;NO - GO SET UP THAT FILE
	SKIPN	DISPTR		;NEED TO SET UP PRE-SET POINTERS?
	PUSHJ	P,PRESET	;YES - DO SO
	JRST	SETWIN		;DON'T LOOK FILE UP; JUST USE IT

;HERE TO CREATE FILE. WRITE FIRST LINE IN IT, CLOSE IT,
;AND PRETEND IT WAS THERE ALL THE TIME
;RETURNS +1 ON FAILURE, +2 ON SUCCESS

IFN TOPS10,<
SETCRE:	MOVE	T1,FILBLK+1	;MAKE SURE DEVICE IS RIGHT
	MOVEM	T1,GENBLK+1
	OPEN	5,GENBLK	;OPEN A DUMP MODE OUTPUT FILE ON CHANNEL 5
	  POPJ	P,		;OOPS - CAN'T
	MOVSI	T1,'DSK'	;RESTORE GENBLK'S GENERALITY
	MOVEM	T1,GENBLK+1
	ENTER	5,FILFIL
	  POPJ	P,
	HLLZS	FILFIL+3
	SETZM	FILFIL+4
	SETZM	FILFIL+5
IFN FTSFD,<
	SETZM	FILFIL+1
>
IFE FTSFD,<
	MOVE	T1,FILPPN	;PUT USER'S PPN BACK IN
	MOVEM	T1,FILFIL+1
>
	OUTPUT	5,NEWCCL	;OUTPUT CHEERY MESSAGE
	RELEAS	5,		;CLOSE THE FILE
>
IFE TOPS10,<
SETCRE:	HRROI	T2,FILSPC	;SET UP NEW FILE FOR OUTPUT
	PUSHJ	P,SETOUT
	JUMPE	T1,CPOPJ	;GIVE ERROR RETURN IF FILE CAN'T BE CREATED
	MOVE	T2,[POINT 7,NEWMSG]
	SETZ	T3,
	SOUT			;WRITE STARTING MESSAGE TO NEW FILE
	MOVEI	T2,15		;END IT ALL WITH A <CR>
	BOUT
	MOVEI	T2,12
	BOUT
	CLOSF			;COMPLETE THE FILE
	  POPJ	P,		;OOPS - GIVE ERROR RETURN
>
	SETZM	SAVEAC+11	;SUCCESS - MARK FILE IS ALWAYS WRITEABLE
	TRZ	F,RDO		;DITTO
	AOS	(P)		;RETURN SUCCESS
	POPJ	P,		;RETURN TO LOOK UP THE FILE FOR EDITING

;HERE ON A FILE-NOT-FOUND ERROR. MAY WANT TO LOOK FOR OTHER FILES

IFE TOPS10,<
SETERC:	MOVE	T1,INJFN	;TRY TO OPEN THE FILE FROZEN
	MOVEI	T2,OF%RD+OF%WR+OF%PDT
	OPENF
	  TROA	F,RDO		;NOPE - TRY TO GET THE FILE READ-ONLY
	JRST	SETF12		;YES - CONTINUE
	MOVE	T1,INJFN	;TRY TO OPEN THE FILE THAWED, READ-ONLY
	MOVEI	T2,OF%THW+OF%RD+OF%DUD
	OPENF
	  SKIPA	T1,INJFN	;NOPE - TRY FROZEN, READ-ONLY
	JRST	SETF12		;YES - CONTINUE
	MOVEI	T2,OF%RD
	OPENF
	  SKIPA	T1,INJFN	;NOPE - CLOSE THE NEWLY-GTJFN-ED FILE
	JRST	SETF12		;SUCCESS - CONTINUE SETTING UP THE FILE
	CLOSF			;CLOSE, AND FALL INTO ERROR CODE
	  JFCL
	TRZ	F,RDO		;CLEAR READ-ONLY FLAG
>
SETERR:	SKIPE	EEEPTR		;NO - WORKING ON A LIST OF EXT'S?
	JRST	SETER1		;YES - KEEP WORKING
IFN TOPS10,<
	SKIPE	FILFIL+3	;IS THERE A CURRENT EXTENSION?
	JRST	SETRRC		;YES - CREATE THE FILE OR GIVE AN ERROR
	TLO	F,FLG		;NO - TRY SOME USUAL EXTENSIONS
	MOVE	PT,[POINT 18,EXTTBL]
	HLLZ	T1,OLDFIL+3	;GET EXTENSION OF PREVIOUS FILE
	HLLM	T1,EXTTBL	;SAVE AS FIRST EXTENSION TO TRY
	CAIN	T1,0		;DID PREVIOUS FILE HAVE AN EXTENSION?
	IBP	PT		;NO - SKIP OVER IT
	MOVEM	PT,EEEPTR	;SAVE EXTENSION POINTER
	HLRZ	T1,FILBLK+1	;GET DEVICE NAME
	CAIE	T1,'DSK'	;IS IT DISK?
	JRST	SETR1A		;NO - TRY USING DEVICE AS EXT, TOO

SETER1:	ILDB	T1,EEEPTR	;SET UP ANOTHER EXTENSION
	JUMPE	T1,STRRC0	;UNLESS NONE LEFT, THEN ERROR OR CREATE
SETR1A:	HRLZM	T1,FILFIL+3
	JRST	SETFL1
>
IFE TOPS10,<
	SKIPN	T2,EXTPTR	;IS THERE A CURRENT EXTENSION?
	JRST	SETRRC		;YES - CREATE THE FILE OR GIVE AN ERROR
	SETOM	EEEPTR
	MOVEI	PT,EXTTBL
	SKIPN	T1,(PT)		;NO - IS FIRST EXT NULL?
	AOJA	PT,SETR1A	;YES - SKIP IT
	JRST	SETR1B		;NO - WORK WITH IT

SETER1:	MOVE	T2,EXTPTR	;GET POINTER TO WHERE TO STORE EXT
SETR1A:	SKIPN	T1,(PT)		;SET UP ANOTHER EXTENSION - ANY?
	JRST	STRRC0		;NO - ERROR OR CREATE
SETR1B:	MOVEI	T0,"."		;YES - PUT IN THE DOT
	DPB	T0,T2
	LSHC	T0,7		;GET AN EXTENSION CHARACTER
	IDPB	T0,T2		;SAVE IT
	JUMPN	T1,.-2		;LOOP THROUGH ALL CHARS
	IDPB	T1,T2		;SAVE A NULL AT THE END
	AOJA	PT,SETFL1	;TRY TO FIND THAT FILE
>
SETER3:	SKIPA	T1,[[ASCIZ /######Unable to create file/]]
SETER2:	MOVEI	T1,[ASCIZ /##########File not found/]
	SETZM	EEEPTR
	JRST	STFERR		;GO DISPLAY THE ERROR
SETERX:	MOVEI	T1,[ASCIZ /#########No alternate file/]
	JRST	ERROR

;HERE IF FILE IS NOT FOUND (PERHAPS EVEN AFTER TRYING THE EXTENSION LIST)
;IF /CREATE IS SET, CREATE THE FILE, ELSE IT'S AN ERROR

STRRC0:
IFN TOPS10,<
	SETZM	FILFIL+3	;MAKE THE FILESPEC BE EXTENSIONLESS AGAIN
>
IFE TOPS10,<
	SETZ	T1,
	MOVE	T2,EXTPTR
	IDPB	T1,T2
>
SETRRC:	TRZE	F,CRE		;WANT TO CREATE THIS FILE?
	JRST	STRRC1		;YES - GO CREATE IT
	SKIPN	CREFLG		;WANT TO CREATE EVERY FILE?
	JRST	SETER2		;NO - GIVE THE FILE-NOT-FOUND ERROR
STRRC1:	PUSHJ	P,SETCRE	;YES - CREATE THE FILE
	  JRST	SETER3		;CREATE FAILED - ERROR
	JRST	SETFL1		;O.K. - NOW LOOK IT UP

;SUBROUTINE TO READ NEXT LINE OF STAT.TMP FILE INTO (T4 - FRAGGED)
;ENTER ALSO WITH PT/MFLPTR

SETMFE::MOVE	T4,[POINT 7,OLDSPC] ;HERE AFTER SETERR - READ INTO ALT SPECS
	SETZM	SAVEDP		;CLEAR SAVED DISPLAY POINTER
	JRST	SETMF0		;CONTINUE

SETMFL:	SKIPE	MFLPT0		;GET HERE FROM SETMFB?
	JRST	SETMFC		;NO - CONTINUE
	MOVE	T1,SAVEAC	;YES - SET UP REAL MFLPT0
	MOVEM	T1,MFLPT0
	POPJ	P,		;AND DO NOTHING MORE

SETMFC:	SETZM	DISPTR		;CLEAR DISPLAY PTR SO SPECS WILL BE PARSED
	TLC	DO,600000	;CLEAR NPM AND SET INDIRECT FLAGS
	MOVE	T4,[POINT 7,FILSPC] ;POINT TO FILSPC BLOCK
SETMF0:	EXCH	PT,MFLPT0	;SAVE POINTER TO ALTERNATE SPECS
	MOVEM	PT,MFLPT1	;AND CURRENT SPECS
	MOVE	PT,MFLPT0	;GET CURRENT POINTER BACK
	PUSHJ	P,SETINF	;READ IN INDIRECT FILE
	TRZ	F,GFL		;CURRENT FILE IS NO LONGER AROUND
	PUSHJ	P,TMPGET	;READ NEW SPECS INTO CURRENT FILE AREA
	CAIGE	T1,"!"		;IS THERE AT LEAST A COMMENT ON THE NEXT LINE?
	SETZM	MFLPTR		;NO - FORGET THE POINTER
	POPJ	P,

;SUBROUTINE TO READ IN THE INDIRECT FILESPEC FILE

SETINF:	SETZ	T2,		;CLEAR T2 FOR TMPGET
	SKIPN	INDFLG		;IS FILE ALREADY HERE?
	POPJ	P,		;YES - NOTHING TO DO
	PUSHJ	P,SETIDI	;GO FIND THE TEMPORARY FILE
IFN TOPS10,<
	INPUT	5,SEDCCL	;READ STATUS INTO PICK BUFFER
	RELEAS	5,
>
IFE TOPS10,<
	MOVE	T2,[POINT 7,PIKBUF+PCBSIZ-400]
	SETZ	T3,		;READ THE FILE INTO THE PICK BUFFER
	SIN
	CLOSF			;CLOSE THE FILE
	  HALTF
>
	SETZM	INDFLG		;NOTE THAT FILE IS HERE
	POPJ	P,		;DONE

;HERE ON ENTER SET-FILE, TO SET TO THE PREVIOUS ONE ON THE LIST
;CONTROL GOT HERE FROM PEEL.F, WHICH WAS CALLED BY SETFIL
;CONTROL PASSES TO SETNPM, NOT BACK TO SETFIL. VERY UNSTRUCTURED.

SETMFB::MOVEI	T1,SETNPM	;FAKE RETURN TO SETNPM
	MOVEM	T1,(P)
	MOVE	PT,MFLPT1	;GET POINTER TO CURRENT FILE
	CAMN	PT,[POINT 7,PIKBUF+PCBSIZ-400]
	POPJ	P,		;IF AT START, JUST TOGGLE
	MOVEM	PT,SAVEAC	;SAVE TO PUT IN MFLPT0 LATER
	SETZ	T1,		;CLEAR ALTERNATE PTR AS A FLAG
	EXCH	T1,MFLPT0
	MOVEM	T1,SAVEAC+1
	PUSHJ	P,SETINF	;SET UP THE INDIRECT FILE
STMFB1:	ADD	PT,[70000,,0]	;BACK UP ONE CHARACTER
	CAIGE	PT,0
	SUB	PT,[430000,,1]
	LDB	T1,PT		;GET THE CHARACTER
	JUMPE	T1,STMFB2	;END OF LINE IF NULL
	CAIE	T1,12		;END OF PREVIOUS LINE?
	JRST	STMFB1		;NO - KEEP LOOPING
STMFB2:	MOVEM	PT,MFLPT1	;SAVE POINTER TO (MAYBE) CURRENT FILE
	ILDB	T1,PT		;GET THE FIRST CHARACTER OF THE LINE
	MOVE	PT,MFLPT1	;GET THE REAL POINTER BACK
	CAIE	T1,";"		;IS THE LINE A COMMENT?
	CAIN	T1,"!"
	JRST	STMFB1		;YES - BACK UP ONE MORE LINE

	MOVE	T4,[POINT 7,OLDSPC] ;NO - POINT TO OLD FILESPEC BLOCK
	SETZM	SAVEDP		;CLEAR DISPLAY PTR SO SPECS WILL BE PARSED
	PUSHJ	P,TMPGET	;READ NEW SPECS INTO ALTERNATE FILE AREA
	MOVE	T1,SAVEAC+1	;GET REAL POINTER TO NEXT FILE
	MOVEM	T1,MFLPTR	;SAVE IT
	POPJ	P,		;RETURN TO SET UP THE FILE

;HERE ON "@FILSPC" TO USE GIVEN FILE AS A LIST OF FILES TO EDIT

SETIND:	MOVE	T1,SEDFIL	;SAVE ORIGINAL .TMP FILE NAME
	SKIPN	SAVSED		;UNLESS IT'S SAVED ALREADY
	MOVEM	T1,SAVSED
	MOVE	PT,[POINT 7,FILSPC]
	MOVE	T3,[POINT 7,SEDFIL]
IFN TOPS10,<
	MOVEI	T4,'DIR'	;GET DEFAULT EXTENSION
>
IFE TOPS10,<
	MOVE	T4,[ASCII /DIR/]
>
	PUSHJ	P,PARSFX	;PARSE THESE FILE SPECS
	MOVEI	T4,OLDSPC	;PREPARE TO SAVE FILE
IFN TOPS10,<
	MOVEI	PT,OLDBLK
>
	TRNN	F,GFL		;HAS A FILE BEEN SET UP?
	JRST	SETID1		;NO - DON'T SAVE
	SKIPE	OLDSPC		;IS THERE AN ACTIVE FILE?
	PUSHJ	P,SAVFIL	;YES - SAVE IT
SETID1:	PUSHJ	P,SETIDI	;LOOK UP INDIRECT FILE
	PUSHJ	P,REDTM0	;TREAT @FILE JUST LIKE nnnSED.TMP
	TLZ	F,SMF		;FILES CAN'T BE THE SAME
	TLO	DO,200000	;NOTE THAT AN INDIRECT FILE IS BEING SET UP
	JRST	INDIRE

SETIDI:	HRROI	T2,SEDFIL
	PUSHJ	P,SETINP	;FIND THE FILE
	JUMPN	T1,PIKFRG	;IF O.K., CHECK PICK BUFFER AND RETURN
	MOVEI	T1,[ASCIZ /######Indirect file not found/]
	JRST	STFERR		;TREAT LIKE A NORMAL BAD FILE

;**********************************************************************
;HERE TO SET UP OR CANCEL WINDOWING

WINCLR::PUSHJ	P,RESTPM	;RESET PARAMETER
WINCL1:	PUSHJ	P,WNCLST	;CLEAR WINDOWING
	PUSHJ	P,DISPLL	;RE-DISPLAY THE SCREEN
	JRST	DISCUR		;POSITION THE CURSOR AND LOOP

WNCLST::TLZN	TM,WDW		;GET OUT OF WINDOWING - IN IT?
	POPJ	P,		;NO - DO NOTHING
	SETZM	HOMPOS		;PUT HOME BACK HOME
	DMOVE	T1,SAVRUP	;RESTORE SAVED ROLL UP AND DOWN
	DMOVEM	T1,RUP(TM)
	DMOVE	T1,SAVILN	;RESTORE SAVED INSERT AND DELETE LINE
	MOVEM	T1,ILN(TM)
	MOVEM	T2,DLN(TM)
	MOVE	T1,SAVCPG	;RESTORE CLEAR-TO-EOP, TOO
	MOVEM	T1,CPG(TM)
	MOVE	T3,SAVLPP	;SET UP FULL SCREEN LENGTH
	JRST	SWHLPP		;ALSO SET UP AS LINES PER PAGE, AND RETURN

WINSET::TLOE	TM,WDW		;ALREADY IN A WINDOW?
	JRST	WINCL1		;YES - CANCEL WINDOWING
	MOVE	T3,LPP(TM)	;GET THE SCREEN LENGTH
	MOVEM	T3,SAVLPP	;SAVE IT FOR AFTER WINDOWING
	LSH	T3,-1		;DIVIDE IN TWO, ONE FOR EACH WINDOW
	CAML	RW,T3		;IS CURSOR BELOW WINDOW?
	SETZB	RW,CM		;YES - MOVE IT HOME
	TLO	F,XPL!XPC!XPB	;CURSOR, LINE, BOTTOM POINTERS ARE BAD
	SETZB	T1,T2		;CLEAR AND GET
	EXCH	T1,RUP(TM)	;  ROLL UP AND ROLL DOWN SEQUENCES
	EXCH	T2,RLD(TM)	;  (SO ROLLS WON'T BE DONE)
	DMOVEM	T1,SAVRUP	;SAVE THEM
	SETZB	T1,T2		;SAME WITH INSERT AND DELETE LINE SEQUENCES
	EXCH	T1,ILN(TM)	;  (IN THE UPPER WINDOW ONLY)
	EXCH	T2,DLN(TM)
	DMOVEM	T1,SAVILN	;SAVE THEM
	PUSHJ	P,SWHLPP	;ALSO SET UP AS LINES PER PAGE
	MOVEI	T1,"^"		;GET UPWARD-POINTING SEPARATOR
	PUSHJ	P,WINSEP	;PUT WINDOW SEPARATOR UP
	SKIPE	CPG(TM)		;IS THERE A CLEAR-TO-EOP SEQUENCE?
	PUSHJ	P,CLEARP	;YES - DO IT
	SETZB	T1,WINDIS	;CLEAR AND SAVE
	EXCH	T1,CPG(TM)	;  SEQUENCE FOR CLEAR-TO-EOP
	MOVEM	T1,SAVCPG
	JRST	DISCUR		;RE-POSITION THE CURSOR; DONE

;SUBROUTINE TO OUTPUT WINDOW SEPARATOR ON LINE (T3)
;ENTER WITH SEPARATOR CHARACTER IN T1

WINSEP:	PUSH	P,T1		;SAVE SEPARATOR CHARACTER
	MOVE	T4,T3		;PUT POSITION IN THE RIGHT AC
	PUSHJ	P,POSLIN	;MOVE TO THE START OF LINE (T4)
	MOVE	T2,CPL.1
	SUBI	T2,5
	PUSHJ	P,PROTON	;OUTPUT A PROTECTED SEPARATOR
	POP	P,T1
	IDPB	T1,TY
	SOJG	T2,.-1
	PUSHJ	P,PROTOF
	JRST	PUTTYP		;OUTPUT AND RETURN

;************************************************************************
;SUBROUTINE TO SAVE THE CURRENT FILE
;TOPS10: ENTER WITH ADDRESS OF FILBLK OR OLDBLK SET UP IN AC PT
;BOTH:	 ENTER WITH ADDRESS OF FILSPC OR OLDSPC SET UP IN AC T4

SAVFIL::
IFE TOPS10,<
	TRZ	F,GFL		;SAY FILE IS NO LONGER AROUND
>
	TRNN	F,RDO		;IS FILE READ-ONLY?
	TLZN	F,CHG		;NO - HAS IT BEEN MODIFIED?
	JRST	SAVFNO		;READ-ONLY OR NOT MODIFIED - DON'T SAVE FILE
	PUSHJ	P,SAVMGS	;YES - OUTPUT FILE-MODIFIED MESSAGE
IFN TOPS10,<
	MOVEM	PT,SAVEAC+1	;SAVE POINTER TO TOPS10 FILE DATA
	SKIPE	TAGFLG		;WANT TO PUT A TAG LINE AT START OF FILE?
	PUSHJ	P,SAVTAG	;YES - DO SO
	PUSHJ	P,TRAILL	;CHOP OUT TRAILING SPACES AND NULLS
	MOVE	PT,SAVEAC+1	;RESTORE TOPS10 POINTER
SAVFLC::
>
IFE TOPS10,<
	SETZ	T1,		;MAKE SURE ENDING CHARACTERS ARE NULLS
	MOVE	T2,EN
	DPB	T1,T2
	IDPB	T1,T2
	PUSHJ	P,SVFSET	;GET THE OUTPUT JFN
	SKIPE	TAGFLG		;WANT TO PUT A TAG LINE AT START OF FILE?
	PUSHJ	P,SAVTAG	;YES - DO SO
	PUSHJ	P,TRAILL	;CHOP OUT TRAILING SPACES AND NULLS
>
SAVFL1:	SETZ	T1,		;MAKE SURE THE REST OF LAST WORD IS NULL
	MOVE	T2,EN
	IDPB	T1,T2
	IDPB	T1,T2
	IDPB	T1,T2
	IDPB	T1,T2
	IDPB	T1,T2
	SETZM	(T2)
	MOVEI	T1,1(T2)	;THEN NULL OUT FROM END OF FILE
	HRL	T1,T2		;(TO END OF CORE OR END OF PAGE)
IFN TOPS10,<
	MOVE	EN,T2
	HRRZ	T2,.JBREL	;TO END OF CORE
	BLT	T1,(T2)
	OPEN	3,(PT)		;SET UP CHANNEL FOR THE EXISTING FILE
	  HALT
	DMOVE	T0,5(PT)	;GET FILE NAME AND EXTENSION
	SETZ	T2,
	MOVE	T3,4(PT)	;GET FILE PPN
	SKIPN	CHGSPC		;ARE SPECS UNCHANGED,
	SKIPN	BAKFLG		;AND IS A BACKUP FILE WANTED?
	JRST	SAVFLB		;NOT BOTH - NO BACKUP
	MOVSI	T1,'BAK'	;YES - SET UP A BACKUP FLAVORED FILE
	DMOVEM	T0,BAKFIL	;SAVE BACKUP NAME AND EXT
	MOVEM	T3,BAKFIL+3	;SAVE BACKUP PPN
	OPEN	5,(PT)		;ELIMINATE CURRENT BACKUP FILE (IF ANY)
	  HALT
	LOOKUP	5,BAKFIL
	  CAIA			;(DON'T DO IT IF IT'S NOT THERE)
	RENAME	5,DELFIL
	  JFCL
	RELEAS	5,
	DMOVEM	T0,BAKFIL	;GET A CLEAN LOOKUP BLOCK
	DMOVEM	T2,BAKFIL+2
	LOOKUP	3,3(PT)		;RENAME THE OLD FILE TO *.BAK
	  JRST	SAVFLA+1	;IF NONE, DON'T WORRY ABOUT IT
	LDB	T1,[POINT 9,7(PT),8] ;ELSE GET THE FILE PROTECTION
	CAIGE	T1,300		;IS IT BETWEEN 200 AND 277?
	CAIGE	T1,200
	  JRST	SAVFLA		;NO - NO NEED TO LOWER THE PROTECTION
	DMOVE	T0,5(PT)	;YES - GET THE ORIGINAL FILENAME
	HLLZ	T1,T1		;ZERO THE UNWANTED PART
	DMOVEM	T0,PRTFIL	;AND SAVE IT
	DMOVEM	T2,PRTFIL+2	;SET UP THE REST OF THE BLOCK
	LDB	T1,[POINT 9,7(PT),8] ;GET THE PROTECTION
	XORI	T1,300		;MAKE IT IN THE 100'S
	DPB	T1,[POINT 9,PRTFIL+2,8]	;AND SAVE IT
	RENAME	3,PRTFIL	;LOWER THE PROTECTION
	  JFCL			;IGNORE THE ERROR
SAVFLA:	RENAME	3,BAKFIL
	  JFCL
	CLOSE	3,
	HLL	T1,6(PT)	;GET REAL FILE'S EXTENSION
	HLLZ	T2,7(PT)	;  AND ITS PROTECTION
	TLZ	T2,000777
	DMOVEM	T0,5(PT)	;SET UP EXT AND PROTECTION IN FILE BLOCK
	MOVEM	T2,7(PT)	;SAVE FILE PROTECTION
	MOVEM	T3,4(PT)	;  AND PPN

SAVFLB:
IFE FTSFD,<
	SETZM	3+11(PT)	;ALLOW FILE NOT TO BE CONTIGUOUS IF NECESSARY
>
	ENTER	3,3(PT)		;FIND THE FILE AGAIN (FOR OUTPUT)
	  JRST	SVEERR		;ERROR - OVER QUOTA OR DISK FULL
	DMOVEM	T0,5(PT)	;CLEAN UP FILE BLOCK
	MOVEM	T2,7(PT)
	MOVEM	T3,4(PT)
	MOVE	T1,EN
	SUBI	T1,BUFFER
	MOVN	T1,T1
	HRLM	T1,FILCCL	;SET UP FILE SIZE IN COMMAND
	OUTPUT	3,FILCCL	;OUTPUT THE ENTIRE FILE
	RELEAS	3,		;CLOSE THE FILE UP
>
IFE TOPS10,<
	HRRZ	T2,EN		;CLEAR TO END OF PAGE
	TRO	T2,777
	BLT	T1,(T2)

SAVFLB:	LDB	T1,EN		;BACK UP END PTR TO LAST REAL CHARACTER
	JUMPN	T1,SAVFB1	;DONE IF NON-NULL
	ADD	EN,[70000,,0]	;ELSE BACK UP A NOTCH
	CAIGE	EN,0
	SUB	EN,[430000,,1]
	JRST	SAVFLB		;AND TRY THE PREVIOUS CHARACTER

SAVFB1:	HRRZI	T1,1(EN)	;FIND FINAL FILE SIZE
	SUBI	T1,BUFFER
	MOVE	T3,T1		;FIND IT IN BYTES
	ADDI	T3,777		;ROUND TO NEXT HIGHER PAGE
	LSH	T3,-11
	MOVEM	T3,FILBSZ

	SOJ	T1,		;FIND IT IN CHARACTERS
	IMULI	T1,5
	HLRZ	T0,EN		;GET POINTER PART OF POINTER
	SETZ	T2,		;FIND NUMBER OF CHARACTERS IN FINAL WORD
	CAME	T0,PTRTBL(T2)
	AOJA	T2,.-1
	ADD	T1,T2
	MOVEM	T1,FILSIZ

	MOVE	T1,SAVCAP	;GET THE USER'S CAPABILITIES
	TRNE	T1,SC%WHL+SC%OPR ;IS HE WHEEL OR OPERATOR?
	JRST	SAVFB3		;YES - DON'T ENFORCE THE DIRECTORY QUOTA
	SETZM	SAVEAC		;CLEAR BEEN-HERE-ONCE FLAG
	MOVSI	T1,(RC%EMO)	;GET THE DIRECTORY NUMBER
	MOVE	T2,OUTJFN	;  OF THE OUTPUT FILESPEC
	RCDIR			;(MAKE IT AN EXACT MATCH)
	MOVE	T1,T3
	MOVE	T4,T3		;SAVE THE DIRECTORY NUMBER
SAVFB2:	GTDAL			;GET THE DISK ALLOCATION
	SUB	T1,T2		;FIND HOW MUCH WILL BE LEFT
	SUB	T1,FILBSZ	;  AFTER THIS FILE HAS BEEN SAVED
	JUMPG	T1,SAVFB3	;JUMP IS THERE IS ENOUGH ROOM
	EXCH	T4,SAVEAC	;SAVE DIRECTORY NUMBER AND GET WHAT'S THERE
	JUMPN	T4,SVERR0	;ERROR IF BEEN HERE ONCE & STILL NOT ENOUGH ROOM
	MOVEI	T1,[ASCIZ/Quota exceeded or disk full - Expunging directory/]
	PUSHJ	P,ERRDSP	;TELL THE USER WHAT'S GOING ON
	MOVE	T2,SAVEAC	;GET THE DIRECTORY NUMBER
	SETZ	T1,
	DELDF			;EXPUNGE THAT DIRECTORY
	MOVE	T1,SAVEAC	;GET THE DIRECTORY NUMBER
	JRST	SAVFB2		;SEE IF THERE'S ENOUGH ROOM NOW

SAVFB3:	MOVE	T1,OUTJFN	;GET THE OUTPUT JFN
	MOVEI	T2,OF%THW+OF%WR	;OPEN THE FILE FOR WRITING
	OPENF
	  ERJMP	SVEERR		;IF CAN'T, JUST FINISH OFF
	MOVE	T1,[400000,,BUFBLK]
	HRLZ	T2,OUTJFN	;WRITE ALL OF BUFFER INTO FILE
	MOVE	T3,[PM%CNT+PM%WR]
	ADD	T3,FILBSZ
	PMAP

	SKIPN	CHGSPC		;ARE SPECS UNCHANGED,
	SKIPN	BAKFLG		;AND IS A BACKUP FILE WANTED?
	JRST	NOBAK		;NOT BOTH - NO BACKUP
	HRROI	T1,BAKSPC	;YES - GET BACKUP SPECS
	MOVE	T2,INJFN	;  WITH INPUT FILE NAME
	MOVE	T3,[221000,,1]
	SETZ	T4,
	JFNS
	  ERJMP	NBKERR		;FAILED - NO BACKUP
	HRROI	T2,[ASCII /.BAK/] ;CHANGE EXTENSION TO .BAK
	MOVNI	T3,5
	SOUT			;MOVE THE STRING
	  ERJMP	NBKERR		;FAILED - NO BACKUP
	MOVSI	T1,(GJ%FOU+GJ%SHT) ;OPEN THE BACKUP FILE
	HRROI	T2,BAKSPC
	GTJFN
	  ERJMP	NBKERR		;FAILED - NO BACKUP
	MOVE	T2,T1
	MOVE	T3,T1
	MOVE	T1,INJFN	;SET TO RENAME THE ORIGINAL FILE
	RNAMF
	  ERJMP	NBKERR		;FAILED - NO BACKUP
	SKIPA	T1,T3		;SET TO RELEASE THE BACKUP JFN
NOBAK:	MOVE	T1,INJFN	;(OR RELEASE THE INPUT JFN)
	RLJFN
	  JFCL
	HRLI	T1,(CO%NRJ)	;CLOSE FILE; DON'T RELEASE JFN
	HRR	T1,OUTJFN
	CLOSF
	  JRST	SVEERR
	HRLI	T1,.FBSIZ	;CHANGE FILE SIZE IN DESCRIPTOR BLOCK
	OR	T1,[CF%NUD]
	SETO	T2,
	MOVE	T3,FILSIZ
	CHFDB
	HRLI	T1,.FBBYV	;TELL FILE ITS BYTE SIZE IS NOW 7
	MOVE	T2,[FB%BSZ]
	MOVSI	T3,700
	CHFDB
	MOVE	T1,OUTJFN	;NOW RELEASE THE JFN
	RLJFN
	  JRST	SVEERR
>
	POPJ	P,

IFE TOPS10,<
;ENTER AT SAVFLC FOR INCREMENTAL SAVES AND THE SAVE COMMAND

SAVFLC::PUSHJ	P,SVFST1	;GET OUTPUT JFN - DON'T BUMP VERSION
	JRST	SAVFL1		;JUMP INTO THE FLOW

SVFSET:	MOVE	T1,EXTTBL	;IS .TMP THE EXTENSION OF THIS FILE?
	CAMN	T1,[ASCII /TMP/]
SVFST1:	SKIPA	T1,[GJ%SHT]	;YES - DON'T BUMP VERSION NUMBER (ELSE DO)
	MOVE	T1,[GJ%FOU+GJ%SHT]
	HRRO	T2,T4		;GET A JFN FOR THE OUTPUT FILE
	GTJFN
	  ERJMP	SVEERR		;OOPS - FILE IS READ-ONLY - JUST FINISH OFF
	HRRZM	T1,OUTJFN	;SAVE THE OUTPUT JFN
	POPJ	P,		;DONE
>
SAVFNO:
IFE TOPS10,<
	MOVE	T1,INJFN	;RELEASE THE INPUT JFN
	RLJFN
	  JFCL
>
	PUSHJ	P,SAVMGN	;TELL USER THAT FILE IS NOT CHANGED
	SNOOZE	^D0700		;SLEEP A BIT
	POPJ	P,

IFE TOPS10,<
NBKERR:	MOVEI	T1,[ASCIZ / *Error - no backup file generated* /]
	PUSHJ	P,PUTSTG	;OUTPUT THE ERROR MESSAGE
	PUSHJ	P,PUTTYP
	JRST	NOBAK		;GO FINISH OFF

SVERR0:	TRO	F,GFL		;SAY FILE REALLY IS AROUND
>
SVEERR:	TLO	F,CHG		;REMEMBER THAT FILE WAS CHANGED
	IBP	EN		;POINT BEYOND THE LAST CHARACTER OF THE FILE
	MOVEI	T1,[ASCIZ /Can't save - quota exceeded or disk full/]
	HRRZ	T2,DO		;IS THIS PART OF A SET-FILE COMMAND?
	CAIN	T2,$SETFI
	JRST	STFERR		;YES - TREAT IT AS A SET-FILE ERROR
	PUSHJ	P,ERRDSP	;NO - OUTPUT THE MESSAGE
IFN TOPS10,<				;is this necessary?
	PUSHJ	P,INITTY	;RE-INIT THE TERMINAL
>
	PUSHJ	P,DISPLL	;RE-DISPLAY THE SCREEN
	MOVE	P,[IOWD STKSIZ,STACK]
	JRST	DISCUR		;WAIT FOR FURTHER INSTRUCTIONS

;SUBROUTINE TO PUT A TAG LINE AT THE START OF THE FILE BEFORE IT'S SAVED.
;THE TAG LOOKS LIKE: ";<CHALL>SED.MAC.1, 11-Mar-82 09:25:27, Edit by CHALL"

SAVTAG:	MOVEM	TY,SAVEAC	;SAVE THE TYPE-OUT BUFFER POINTER
	MOVEI	T1,^D100	;INSERT 100 NULLS
	MOVEM	T1,NUMCHR
	MOVE	TY,[010700,,BUFFER-1]
	MOVEM	TY,CHRPTR	;AT THE START OF THE FILE
	HRRZ	T1,DISPTR	;TELL MAKNUL TO ADJUST THE DISPLAY POINTER
	MOVEM	T1,ADJWRD
	TLO	F,XPB!XPL!XPC	;POINTERS ARE NO LONGER VALID
	PUSHJ	P,MAKNUL	;AND POINT TO START OF FILE
	SETZ	T1,		;CLEAR AND GET ADJUSTED DISPLAY ADDRESS
	EXCH	T1,ADJWRD
	MOVE	T2,DISPTR	;AT THE START OF THE FILE?
	CAMN	T2,[010700,,BUFFER-1]
	AOJA	RW,SAVTG0	;YES - LEAVE DISPTR ALONE; MOVE ONE ROW DOWN
	HRRM	T1,DISPTR	;SAVE IT WITH THE DISPLAY POINTER
SAVTG0:	MOVEI	T1,TAGFLG	;GET THE STARTING COMMENT CHARACTER(S)
	PUSHJ	P,PUTSTG	;OUTPUT IT (THEM)
IFN TOPS10,<
	MOVEI	T1,FILSPC	;OUTPUT THE CURRENT FILESPECS
	PUSHJ	P,PUTSTG
	MOVEI	T3,","		;DELIMIT WITH COMMA, SPACE
	IDPB	T3,TY
	MOVEI	T3," "
	IDPB	T3,TY

	MOVS	T4,[60,,11]	;SET UP INDEX FOR DATES IN CONFIG TABLE
	PUSHJ	P,SAVTAD	;READ DAY
	PUSHJ	P,SVTATN 	;OUTPUT IT AS TWO DIGITS
	PUSHJ	P,SAVTAD 	;READ MONTH
	MOVE	T1,MONTAB-1(T1)	;GET ITS NAME
	PUSHJ	P,PUTSQ1 	;OUTPUT IT
	PUSHJ	P,SAVTAD 	;READ YEAR
	PUSHJ	P,PUTNUM 	;OUTPUT IT
	IDPB	T3,TY		;SEPARATE DATE FROM TIME WITH A SPACE

	MOVS	T4,[61,,11]	;SET UP INDEX FOR TIMES IN CONFIG TABLE
	MOVEI	T3,":"		;GET A COLON FOR DELIMITING
	PUSHJ	P,SAVTAT 	;READ AND OUTPUT THE HOUR
	IDPB	T3,TY		;DELIMIT WITH A COLON
	PUSHJ	P,SAVTAT 	;READ AND OUTPUT THE MINUTE
	IDPB	T3,TY		;DELIMIT WITH A COLON
	PUSHJ	P,SAVTAT 	;READ AND OUTPUT THE SECOND
>
IFE TOPS10,<
	MOVE	T1,TY		;SET UP POINTER FOR JSYS'S
	MOVE	T2,OUTJFN	;GET THE JFN OF THE OUTPUT FILE
	MOVE	T3,[2B2+1B5+1B8+1B11+1B14+1B35]
	JFNS			;OUTPUT THE COMPLETE FILESPEC
	MOVEI	T2,","		;DELIMIT WITH COMMA, SPACE
	IDPB	T2,T1
	MOVEI	T2," "
	IDPB	T2,T1
	SETO	T2,		;OUTPUT THE CURRENT DATE AND TIME
	SETZ	T3,
	ODTIM
	MOVE	TY,T1		;UPDATE THE CHARACTER POINTER
>
	MOVEI	T1,[ASCIZ /, Edit by /]
	PUSHJ	P,PUTSTG
IFN TOPS10,<
	MOVE	PT,TY
	PJOB	T4,		;GET JOB NUMBER
	HRL	T2,T4
	HRRI	T2,31		;READ FIRST PART OF USER NAME
	GETTAB	T2,
	  SETZ	T2,		;(IT BETTER WORK)
	PUSHJ	P,PUTSIX	;OUTPUT THE SIXBIT FIRST PART
	HRL	T2,T4
	HRRI	T2,32		;READ SECOND PART OF USER NAME
	GETTAB	T2,
	  SETZ	T2,
	PUSHJ	P,PUTSIX	;OUTPUT THE SIXBIT SECOND PART
	MOVE	TY,PT		;PUT THE POINTER BACK IN AC TY
>
IFE TOPS10,<
	GJINF			;GET LOGGED-IN DIRECTORY NUMBER
	MOVE	T2,T1		;PUT IN THE RIGHT PLACE FOR DIRST
	MOVE	T1,TY
	DIRST			;WRITE USER NAME
	 PUSHJ	P,SAVTGN	;UNKNOWN - SAY SO
	MOVE	TY,T1		;PUT THE POINTER BACK IN AC TY
>
	SKIPE	T1,TAGFG1	;ARE THERE ANY ENDING COMMENT CHARACTER(S)?
	PUSHJ	P,PUTSQ1	;YES - CLOSE THE COMMENT
SAVTGE:	MOVEI	T1,15		;END WITH A CRLF
	IDPB	T1,TY
	MOVEI	T1,12
	IDPB	T1,TY
	MOVE	TY,SAVEAC	;GET THE READ TYPE-OUT BUFFER POINTER BACK
	POPJ	P,		;DONE

IFE TOPS10,<
SAVTGN:	MOVEI	T1,[ASCIZ /Unknown user
/]
	JRST	PUTSTG		;DIRST FAILED - SAY SOMETHING USEFUL & RETURN
>
IFN TOPS10,<
SAVTAD:	MOVS	T1,T4		;READ THE NEXT DATE TABLE ENTRY
	GETTAB	T1,
	  HALT			;(IT BETTER WORK)
	SOJA	T4,CPOPJ

SAVTAT:	MOVS	T1,T4		;READ THE NEXT TIME TABLE ENTRY
	AOJ	T4,
	GETTAB	T1,
	  HALT			;(IT BETTER WORK)
SVTATN:	IDIVI	T1,^D10		;SEPARATE INTO TWO DIGITS
	ADDI	T1,"0"		;MAKE THEM BOTH ASCII
	ADDI	T2,"0"
	IDPB	T1,TY		;SAVE THEM
	IDPB	T2,TY
	POPJ	P,

MONTAB:	ASCII	/-Jan-/		;TABLE OF NAMES OF MONTHS
	ASCII	/-Feb-/
	ASCII	/-Mar-/
	ASCII	/-Apr-/
	ASCII	/-May-/
	ASCII	/-Jun-/
	ASCII	/-Jul-/
	ASCII	/-Aug-/
	ASCII	/-Sep-/
	ASCII	/-Oct-/
	ASCII	/-Nov-/
	ASCII	/-Dec-/
>
;ROUTINES TO OUTPUT FILE SAVE MESSAGES
;ENTER WITH T4/ ADDR OF OLDSPC OR FILSPC (WHICHEVER IS CURRENT FILE)

SAVMGN::TLNE	TM,WDW		;IN A WINDOW?
	POPJ	P,		;YES - NO MESSAGE
	PUSHJ	P,CLRALL	;TELL USER THAT FILE IS NOT CHANGED
	MOVEI	T1,[ASCIZ /NOT MODIFIED: /]
	PUSHJ	P,PUTSTG
	MOVE	T1,T4		;OUTPUT FILESPECS
	PUSHJ	P,PUTSTG
	JRST	SAVMG1

SAVMGS:	TLNE	TM,WDW		;IN A WINDOW?
	POPJ	P,		;YES - NO MESSAGE
	PUSHJ	P,CLRALL
	MOVEI	T1,[ASCIZ /SAVING FILE: /]
	PUSHJ	P,PUTSTG
	MOVE	T1,T4		;OUTPUT FILESPECS
	PUSHJ	P,PUTSTG
	SKIPN	CHGSPC		;ARE SPECS UNCHANGED,
	SKIPN	BAKFLG		;AND IS A BACKUP FILE WANTED?
	SKIPA	T1,[[ASCIZ / (NO BACKUP)/]]
	MOVEI	T1,[ASCIZ / (WITH BACKUP)/]
	PUSHJ	P,PUTSTG

SAVMG1:	MOVEI	T1,15		;END WITH A CARRIAGE RETURN
	IDPB	T1,TY
	MOVEI	T1,12
	IDPB	T1,TY
	JRST	PUTTYP

;************************************************************************
;SUBROUTINE TO PARSE THE FILE SPECS IN FILSPC INTO THE OPEN AND LOOKUP BLOCKS
;ALSO HANDLES SWITCHES. IF TOPS20, PARSEF HANDLES ONLY SWITCHES

PARSFN:
IFN TOPS10,<
	MOVEI	T1,2		;SET UP CURRENT PATH AS DEFAULT
PARFN1:	MOVE	T2,OLDPTH(T1)	;(THIS IS USED ONLY IN SETNPM,
	MOVEM	T2,FILPTH(T1)	; FOR THE 2ND FILE IN .TMP OR
	JUMPE	T2,PARSEF	; AN INDIRECT FILE)
	AOJA	T1,PARFN1

PARSEF::MOVE	PT,[POINT 7,FILSPC]
	MOVEI	T1,16		;SET UP OPEN BLOCK
	MOVSI	T2,'DSK'	;  (MODE AND DEVICE)
	DMOVEM	T1,FILBLK
	SETZB	T1,T2		;ZERO OUT FILE SPEC AREA
	DMOVEM	T1,FILFIL+1	;(NOTE: PATH STAYS THE SAME AS LAST TIME
	DMOVEM	T1,FILFIL+3	; UNTIL USER GIVES A PPN)
	SETZM	FILFIL+5
IFE FTSFD,<
	SETZM	FILPPN
>

PARSF0:	MOVE	T4,[POINT 6,FILFIL+2]
	MOVEI	T0,^D9		;SAVE AT MOST 9 CHARACTERS
PARSF1:	ILDB	T1,PT		;GET A CHARACTER
	JUMPE	T1,CPOPJ	;DONE, IF NULL
	CAIN	T1,11		;(TREAT TAB LIKE A NULL)
	POPJ	P,
	CAIN	T1," "		;IGNORE SPACES
	JRST	PARSF1
	CAIN	T1,":"		;END OF DEVICE?
	JRST	PARSED		;YES - GO SET DEVICE UP
	CAIN	T1,"."		;START OF EXTENSION?
	JRST	PARSEE		;YES - GO PARSE IT
	CAIN	T1,"["		;START OF PPN?
	JRST	PARSEP		;YES - GO PARSE IT
	CAIN	T1,"/"		;START OF SWITCHES?
	JRST	PARSES		;YES - GO HANDLE THEM
	CAIL	T1,"a"		;LOWER CASE?
	TRZA	T1,100		;YES - CONVERT TO SIXBIT
	SUBI	T1,40		;NO - CONVERT TO SIXBIT
	JUMPL	T1,PRSERR	;ERROR IF CHARACTER IS NOT ALPHANUMERIC
	CAIGE	T1,'0'
	JRST	PRSERR
	CAIG	T1,'9'
	JRST	PARSF2
	CAIL	T1,'A'
	CAILE	T1,'Z'
	JRST	PRSERR

PARSF2:	SOJL	T0,PARSF1	;IGNORE, IF GOT TOO MANY CHARACTERS
	IDPB	T1,T4		;ELSE SAVE IT
	JRST	PARSF1		;AND GET ANOTHER

PARSED:	SKIPN	T1,FILFIL+2	;GET DEVICE NAME - ANY?
	JRST	PRSERR		;NO - JUST A COLON - ERROR
	MOVEM	T1,FILBLK+1	;SAVE AS DEVICE
	SETZM	FILFIL+2	;CLEAR FILE NAME
	JRST	PARSF0		;GO GET FILE NAME AGAIN

PARSEE:	MOVE	T4,[POINT 6,FILFIL+3]
	MOVEI	T0,3		;SAVE AT MOST 3 CHARACTERS
PRSEE1:	ILDB	T1,PT		;GET A CHARACTER
	JUMPE	T1,CPOPJ	;DONE, IF NULL
	CAIE	T1,11		;IGNORE TABS
	CAIN	T1," "		;  AND SPACES
	JRST	PRSEE1
	CAIN	T1,"["		;START OF PPN?
	JRST	PARSEP		;YES - GO PARSE IT
	CAIN	T1,"/"		;START OF SWITCHES?
	JRST	PARSES		;YES - GO HANDLE THEM
	CAIL	T1,"a"		;LOWER CASE?
	TRZA	T1,100		;YES - CONVERT TO SIXBIT
	SUBI	T1,40		;NO - CONVERT TO SIXBIT
	JUMPL	T1,PRSERR	;ERROR IF CHARACTER IS NOT ALPHANUMERIC
	CAIGE	T1,'0'
	JRST	PRSERR
	CAIG	T1,'9'
	JRST	PARSE2
	CAIL	T1,'A'
	CAILE	T1,'Z'
	JRST	PRSERR

PARSE2:	SOJL	T0,PRSEE1	;IGNORE, IF GOT TOO MANY CHARACTERS
	IDPB	T1,T4		;SAVE CHARACTER
	JRST	PRSEE1		;AND GET ANOTHER

PARSEP:	SETZ	T1,		;CLEAR TARGET
PARSP1:	ILDB	T2,PT		;GET CHARACTER OF PPN
	JUMPE	T2,PARSP3	;DONE IF NULL
	CAIN	T2,","		;END OF PROJECT NUMBER?
	JRST	PARSP2		;YES - SAVE IT AND GET PROG NUMBER
	CAIE	T2,"/"		;END OF PROGRAMMER NUMBER?
	CAIN	T2,"]"
	JRST	PARSP3		;YES - SAVE IT AND QUIT
	CAIL	T2,"0"		;ERROR IF NOT OCTAL
	CAILE	T2,"7"
	JRST	PRSERR
	ROT	T2,-3		;ELSE SHIFT IT INTO TARGET
	LSHC	T1,3
	JRST	PARSP1		;AND GET SOME MORE

IFN FTSFD,<
PARSP2:	TLOE	F,FLG		;IT THIS PROGRAMMER NUMBER?
	JRST	PARSSF		;YES - THERE'S AN SFD COMING
	JUMPE	T1,PARSEP	;NO - IF NOTHING THERE, DON'T SAVE
	HRLM	T1,FILPTH+2	;ELSE SAVE PROJECT NUMBER
	JRST	PARSEP		;AND GET PROGRAMMER NUMBER

PARSSF:	SETZ	T2,		;FINISH OFF PPN
	PUSHJ	P,PARSP3+1
	TLZ	F,FLG		;CLEAR PROJECT NUMBER FLAG
	SETZ	T1,		;CLEAR SFD LEVEL COUNTER
PARSS0:	MOVE	T4,[POINT 6,T3]
	MOVEI	T0,^D6		;SAVE AT MOST 6 CHARACTERS
	SETZ	T3,		;CLEAR TARGET OF SFD NAME
PARSS1:	ILDB	T2,PT		;GET CHARACTER OF SFD
	JUMPE	T2,PARSS3	;DONE IF NULL
	CAIN	T2,","		;START OF ANOTHER SFD LEVEL?
	AOJA	T1,PARSS2	;YES - SET UP FOR IT
	CAIE	T2,"/"		;END OF SFDS?
	CAIN	T2,"]"
	JRST	PARSS3		;YES - SAVE IT AND QUIT
	CAIL	T2,"a"		;LOWER CASE?
	TRZA	T2,100		;YES - CONVERT TO SIXBIT
	SUBI	T2,40		;NO - CONVERT TO SIXBIT
	JUMPL	T2,PRSERR	;ERROR IF ILLEGAL SIXBIT
	CAILE	T2,77
	JRST	PRSERR
	IDPB	T2,T4		;O.K. - ADD TO SFD NAME
	SOJGE	T0,PARSS1	;AND GET SOME MORE
	JRST	PRSERR		;UNLESS COUNTED OUT

PARSS2:	CAIE	T3,0		;USE OLD SFD NAME IF NONE GIVEN
	MOVEM	T3,FILPTH+2(T1)	;ELSE SAVE SFD NAME
	CAIGE	T1,SFDLVL	;DOWN TOO MANY SFD LEVELS?
	JRST	PARSS0		;NO - GO PARSE THE NEXT LEVEL
	JRST	PRFERR		;YES - ERROR

PARSP3:	SETZM	FILPTH+3	;PATH ENDS WITH PPN
	CAIE	T1,0		;IS PROGRAMMER NUMBER NON-0?
	HRRM	T1,FILPTH+2	;YES - SAVE IT
	JUMPE	T2,CPOPJ	;DONE IF LAST CHARACTER WAS NULL
	CAIN	T2,"/"		;ELSE GOT SOME SWITCHES?
	JRST	PARSES		;YES - READ THEM, TOO
	JRST	PARSF0		;NO - SEE WHAT ELSE THERE IS

PARSS3:	CAIE	T3,0		;WANT DEFAULT FOR THIS SFD?
	MOVEM	T3,FILPTH+3(T1)	;NO - SAVE WHAT THE USER TYPED
	SETZM	FILPTH+4(T1)	;CLEAR WORD AFTER LAST SFD NAME
	JUMPE	T2,CPOPJ	;DONE IF LAST CHARACTER WAS NULL
	CAIE	T2,"/"		;ELSE GOT SOME SWITCHES?
	JRST	PARSF0		;NO - SEE WHAT ELSE THERE IS
>
IFE FTSFD,<
PARSP2:	HRLM	T1,FILFIL+1	;SAVE PROJECT NUMBER
	JRST	PARSEP		;AND GET PROGRAMMER NUMBER

PARSP3:	HLL	T1,FILFIL+1	;GET ENTIRE PPN
	TLNN	T1,-1		;MISSING THE PROJECT?
	HLL	T1,USRPPN	;YES - USE THE USER'S OWN
	TRNN	T1,-1		;MISSING THE PROGRAMMER?
	HRR	T1,USRPPN	;YES - USE THE USER'S OWN
	MOVEM	T1,FILFIL+1	;STORE ENTIRE PPN
	MOVEM	T1,FILPPN	;HERE, TOO
PARSS3:	JUMPE	T2,CPOPJ	;DONE IF LAST CHARACTER WAS NULL
	CAIE	T2,"/"		;ELSE GOT SOME SWITCHES?
	JRST	PARSF0		;NO - SEE WHAT ELSE THERE IS
>
PARSES:	SETZ	T1,		;NULL OUT THE FIRST SLASH
	DPB	T1,PT
	JRST	SWHMNY		;HANDLE THE SWITCHES AND RETURN

IFN FTSFD,<
PRFERR:	SKIPA	T1,[[ASCIZ /#########SFD level too deep/]]
>
PRSERR:	MOVEI	T1,[ASCIZ /###########Bad file specs/]
	SKIPG	OUTFLG		;PARSING SPECS FROM AN /OUT: SWITCH?
	JRST	STFERR		;NO - OUTPUT THE ERROR AND CONTINUE
	MOVS	T2,[FILSPC,,SVASPC]
	BLT	T2,FILSPC+SPCSIZ-1 ;YES - RESTORE ORIGINAL FILESPECS
	SETZM	OUTFLG		;SAY NO LONGER PARSING /OUT: SPECS
	MOVEI	T1,[ASCIZ /######Bad file specs in switch/]
	JRST	ERROR		;AND GIVE THE RIGHT ERROR MESSAGE
>
IFE TOPS10,<
PARSEF::MOVE	PT,[POINT 7,FILSPC]
	SETZM	SAVEAC+12	;CLEAR VERSION-NUMBER-GIVEN FLAG
	SETZB	T3,EXTPTR	;CLEAR FOUND-EXTENSION FLAG
	SETZ	T4,		;CLEAR POINTER TO EXTENSION
PARSF1:	ILDB	T1,PT		;GET A CHARACTER
	JUMPE	T1,PARSF2	;DONE IF NULL
	CAIN	T1,"."		;START OF EXTENSION?
	JRST	PARSFE		;MAYBE - CHECK AND SEE
	CAIN	T1,74		;START OF USER I.D.?
	JRST	PARSFU		;YES - GO SKIP OVER IT
	CAIE	T1,"/"		;START OF SWITCHES?
	JRST	PARSF1		;NO - KEEP LOOKING

PARSFS:	SETZ	T1,		;NULL OUT THE FIRST SLASH
	DPB	T1,PT
	PUSHJ	P,PARSF2	;SEE IF EXTENSION FOUND
	JRST	SWHMNY		;HANDLE THE SWITCHES AND RETURN

PARSFE:	CAIE	T4,0		;GOT ONE DOT ALREADY?
	SETOM	SAVEAC+12	;YES - FLAG THE START OF THE VERSION NUMBER
	MOVE	T4,PT		;SAVE POINTER TO THE DOT
	ILDB	T1,PT		;IF EXT IS JUST A DOT IT'S NOT AN EXT
	JUMPE	T1,PARSF2	;LIKE DOT<NULL> - DONE
	CAIN	T1,"/"		;START OF SWITCHES?
	JRST	PARSFS		;YES - GO DO THEM
	JRST	PARSF1		;NO - CONTINUE

PARSFU:	ILDB	T1,PT		;SKIP OVER USER I.D. - READ CHARACTER
	JUMPE	T1,PARSF2	;DONE IF NULL
	CAIN	T1,76		;END OF USER I.D.?
	JRST	PARSF1		;YES - BACK TO THE FLOW
	JRST	PARSFU		;NO - KEEP LOOKING

PARSF2:	JUMPN	T4,CPOPJ	;IF SOME EXTENSION FOUND JUST RETURN
	MOVEM	PT,EXTPTR	;SAVE PTR TO END OF SPECS (IE, START OF EXT)
	POPJ	P,
>
;SUBROUTINE TO UNPARSE THE FILE SPEC BLOCKS INTO FILSPC

IFN TOPS10,<
UNPARS:	MOVE	PT,[POINT 7,FILSPC]
	MOVE	T2,FILBLK+1	;GET DEVICE
	PUSHJ	P,PUTSIX	;OUTPUT IT
	MOVEI	T1,":"
	IDPB	T1,PT

	MOVE	T2,FILFIL+2	;SET UP FILE NAME
	PUSHJ	P,PUTSIX
	MOVEI	T1,"."
	IDPB	T1,PT
	HLLZ	T2,FILFIL+3	;SET UP EXTENSION
	PUSHJ	P,PUTSIX
	SKIPN	FILPPN		;IS THERE A PPN?
	JRST	UNPRSX		;NO - DON'T OUTPUT IT
	MOVEI	T1,"["		;START THE PPN
	IDPB	T1,PT

	SETO	T3,
	HLRZ	T1,FILPPN	;GET THE PROJECT
	SKIPA	T4,[","]	;GET SEPARATOR CHARACTER
UNPRSP:	HRRZ	T1,FILPPN	;GET THE PROGRAMMER
	MOVSI	T2,700000
	LSHC	T1,-3
	JUMPN	T1,.-1		;PUT NUMBER ENTIRELY IN T2
UNPSP1:	SETZ	T1,
	LSHC	T1,3		;GET A DIGIT IN T1
	JUMPE	T2,UNPSP2	;DONE IF NOTHING LEFT
	ADDI	T1,"0"
	IDPB	T1,PT
	JRST	UNPSP1

UNPSP2:	IDPB	T4,PT		;SAVE SEPARATOR OR END BRACKET
	MOVEI	T4,"]"		;GET THE END BRACKET
	AOJE	T3,UNPRSP	;IF DID PROJ, GO DO PROG
IFN FTSFD,<
	SETZ	T3,		;CLEAR SFD INDEX
UNPSSF:	SKIPN	T2,FILPTH+3(T3)	;GOT AN(OTHER) SFD NAME?
	JRST	UNPRSX		;NO - FINISH OFF
	MOVEI	T1,","		;YES - CHANGE BRACKET TO A COMMA
	DPB	T1,PT
	PUSHJ	P,PUTSIX	;OUTPUT SIXBIT SFD NAME
	IDPB	T4,PT		;END WITH A RIGHT BRACKET
	AOJA	T3,UNPSSF	;GET NEXT LEVEL, IF ANY
>
UNPRSX:	SETZ	T2,
	IDPB	T2,PT		;END WITH A NULL
	POPJ	P,		;AND RETURN

PUTSIX::SETZ	T1,		;GET A SIXBIT CHARACTER
	LSHC	T1,6
	JUMPE	T1,PUTSX2	;IF NULL CHECK TO SEE IF DONE
PUTSX1:	ADDI	T1,40		;ELSE CONVERT TO ASCII
	IDPB	T1,PT		;STORE CHARACTER
	JRST	PUTSIX		;AND LOOP

PUTSX2:	JUMPN	T2,PUTSX1	;GOT NULL OR SPACE - IF THERE IS MORE FOLLOWING
	POPJ	P,		;  OUTPUT THE SPACE, ELSE RETURN
>
IFE TOPS10,<
;UNPARSE - READ SPECS BACK FROM MONITOR. FIND EXTENSION AND SAVE FOR
;DEFAULTING NEXT TIME. EXPECTS JFN IN T1

UNPARS:	MOVE	T2,T1		;READ FILESPECS BACK INTO FILSPC
	HRROI	T1,FILSPC
	MOVE	T3,[221100,,1]
	SETZ	T4,
	JFNS			;AND FALL INTO:

;SUBROUTINE TO FIND AN EXTENSION IN THE FILESPECS AT (T4) AND SAVE IT AT (PT)

UNPEX0::MOVE	T4,[POINT 7,FILSPC]
	MOVE	PT,[POINT 7,EXTTBL]
	MOVEI	T0,5		;SET MAXIMUM EXTENSION SIZE TO 5 CHARACTERS
UNPEXT::ILDB	T1,T4		;GET A CHARACTER
	JUMPE	T1,CPOPJ	;DONE IF NULL
	CAIN	T1,"."		;START OF EXTENSION?
	JRST	UNPEXE		;YES - GO SAVE
	CAIE	T1,74		;START OF USER I.D.?
	JRST	UNPEXT		;NO - GET MORE

UNPEXU:	ILDB	T1,T4		;GET A CHARACTER OF THE USER I.D.
	JUMPE	T1,CPOPJ	;DONE IF NULL
	CAIN	T1,76		;END OF I.D.?
	JRST	UNPEXT		;YES - BACK TO THE MAIN FLOW
	JRST	UNPEXU		;NO - KEEP SKIPPING

UNPEXE:	ILDB	T1,T4		;GET A CHARACTER OF THE EXTENSION
	JUMPE	T1,CPOPJ	;DONE IF NULL
	CAIE	T1,"."		;START OF VERSION NUMBER,
	CAIN	T1,"/"		;  OR START OF SWITCHES?
	POPJ	P,		;YES - DONE
	SOJL	T0,UNPEXE	;SAVED MORE THAN FOUR EXTENSION CHARACTERS?
	IDPB	T1,PT		;NO - SAVE THIS ONE, TOO
	JRST	UNPEXE		;AND KEEP LOOKING
>
;HERE TO READ FILE.EXT INTO A NORMAL LOOKUP BLOCK
;FILESPEC TO PARSE IS IN (PT); TARGET ADDRESS IS IN (T3)
;DEFAULT EXTENSION IS IN T4

IFN TOPS10,<
PARSFX::MOVEM	T4,SAVEAC	;SAVE DEFAULT EXTENSION
	SETZB	T1,T2		;ZERO OUT FILE SPEC AREA
	DMOVEM	T1,0(T3)	;(NOTE: PATH STAYS THE SAME AS LAST TIME
	DMOVEM	T1,2(T3)	; UNTIL USER GIVES A PPN)
PARSP0:	MOVEI	T0,^D9		;SAVE AT MOST 9 CHARACTERS
	MOVE	T4,[POINT 6,(T3)]
PARFP1:	ILDB	T1,PT		;GET A CHARACTER
	JUMPE	T1,PARSPX	;DONE, IF NULL
	CAIN	T1,15		;ALSO DONE IF CR
	JRST	PARSPX
	CAIN	T1," "		;IGNORE SPACES
	JRST	PARFP1
	CAIN	T1,"."		;START OF EXTENSION?
	JRST	PARSPE		;YES - GO PARSE IT
	CAIN	T1,"["		;START OF PPN?
	JRST	PARSPP		;YES - GO PARSE IT
	CAIL	T1,"a"		;LOWER CASE?
	TRZA	T1,100		;YES - CONVERT TO SIXBIT
	SUBI	T1,40		;NO - CONVERT TO SIXBIT
	JUMPL	T1,PRPERR	;ERROR IF CHARACTER IS NOT ALPHANUMERIC
	CAIGE	T1,'0'
	JRST	PRPERR
	CAIG	T1,'9'
	JRST	PARFP2
	CAIL	T1,'A'
	CAILE	T1,'Z'
	JRST	PRPERR

PARFP2:	SOJL	T0,PARFP1	;IGNORE IF GOT TOO MANY CHARACTERS
	IDPB	T1,T4		;ELSE SAVE IT
	JRST	PARFP1		;AND GET ANOTHER

PARSPE:	MOVE	T4,[POINT 6,1(T3)]
	MOVEI	T0,3		;SAVE AT MOST 3 CHARACTERS
PRSPE1:	ILDB	T1,PT		;GET A CHARACTER
	JUMPE	T1,PARSPX	;DONE, IF NULL
	CAIN	T1,"["		;START OF PPN?
	JRST	PARSPP		;YES - GO PARSE IT
	CAIL	T1,"a"		;LOWER CASE?
	TRZA	T1,100		;YES - CONVERT TO SIXBIT
	SUBI	T1,40		;NO - CONVERT TO SIXBIT
	JUMPL	T1,PRPERR	;ERROR IF CHARACTER IS NOT ALPHANUMERIC
	CAIGE	T1,'0'
	JRST	PRPERR
	CAIG	T1,'9'
	JRST	PAREP2
	CAIL	T1,'A'
	CAILE	T1,'Z'
	JRST	PRPERR

PAREP2:	SOJL	T0,PRSPE1	;IGNORE, IF GOT TOO MANY CHARACTERS
	IDPB	T1,T4		;SAVE CHARACTER
	JRST	PRSPE1		;AND GET ANOTHER

PARSPP:	SETZ	T1,		;CLEAR TARGET
PARPP1:	ILDB	T2,PT		;GET CHARACTER OF PPN
	JUMPE	T2,PARPP3	;DONE IF NULL
	CAIN	T2,","		;END OF PROJECT NUMBER?
	JRST	PARPP2		;YES - SAVE IT AND GET PROG NUMBER
	CAIN	T2,"]"		;END OF PROGRAMMER NUMBER?
	JRST	PARPP3		;YES - SAVE IT AND QUIT
	CAIL	T2,"0"		;ERROR IF NOT OCTAL
	CAILE	T2,"7"
	JRST	PRPERR
	ROT	T2,-3		;ELSE SHIFT IT INTO TARGET
	LSHC	T1,3
	JRST	PARPP1		;AND GET SOME MORE

PARPP2:	HRLM	T1,3(T3)	;SAVE PROJECT NUMBER
	JRST	PARSPP		;AND GET PROGRAMMER NUMBER

PARPP3:	HRRM	T1,3(T3)	;SAVE PROGRAMMER NUMBER
	JUMPN	T2,PARSP0	;IF NOT END, SEE WHAT ELSE AWAITS
PARSPX:	MOVE	T1,SAVEAC	;GET DEFAULT EXTENSION
	SKIPN	1(T3)		;GOT AN EXTENSION?
	HRLM	T1,1(T3)	;NO - SAVE DEFAULT
	MOVE	T1,USRPPN	;GET USER'S PPN
	SKIPN	3(T3)		;DID USER GIVE ONE HERE?
	MOVEM	T1,3(T3)	;NO - SAVE USER'S
	POPJ	P,		;THEN RETURN

PRPERR:	MOVEI	T1,[ASCIZ /###########Bad file specs/]
	JRST	ERROR
>
IFE TOPS10,<
;TOPS20 - JUST MOVE SPECS FROM (PT) TO (T3)
;APPEND DEFAULT EXTENSION (IN T4) IF NONE GIVEN
;FILESPEC TO PARSE IS IN (PT); TARGET ADDRESS IS IN (T3)

PARSFX::SETZ	T0,		;CLEAR EXTENSION FLAG
PRSFX1:	ILDB	T1,PT		;GET A CHARACTER
	IDPB	T1,T3		;ELSE SAVE CHARACTER
	CAIN	T1,74		;GOT AN OPEN-BRACKET?
	JRST	PRSFXD		;YES - SKIP THE DIRECTORY
	CAIN	T1,"."		;GOT AN EXTENSION?
	SETO	T0,		;YES - SET FLAG
	JUMPN	T1,PRSFX1	;LOOP IF NOT NULL
	JUMPN	T0,CPOPJ	;RETURN IF EXTENSION GIVEN
	MOVEI	T1,"."		;ELSE APPEND EXTENSION
	DPB	T1,T3
	MOVEI	T0,4
	ROT	T4,7
	IDPB	T4,T3
	SOJG	T0,.-2
	POPJ	P,		;DONE

PRSFXD:	ILDB	T1,PT		;SKIP OVER DIRECTORY - GET A CHARACTER
	JUMPE	T1,CPOPJ	;DONE IF NULL
	CAIN	T1,76		;ELSE GOT A CLOSE BRACKET?
	JRST	PRSFX1		;YES - CONTINUE NORMAL PROCESSING
	JRST	PRSFXD		;NO - KEEP SKIPPING
>
	END