Google
 

Trailing-Edge - PDP-10 Archives - decuslib10-03 - 43,50311/lost.mac
There are no other files named lost.mac in the archive.
	TITLE	LOST BLOCKS PROGRAM


LPTC==0
RIBPTR==1
F==2
BLK==3
FBN==4
CH==5
U==6
BUF==7
T1==10
T2==11
T3==12
T4==13
P1==14
P2==15
P3==16
P==17


VWHO==4
VMAJOR==2
VMINOR==0
VEDIT==0

LOC 137
BYTE	(3)VWHO(9)VMAJOR(6)VMINOR(18)VEDIT
RELOC


;VERSION 1-2	12 NOV 73
;RE-ADDED INSTRUCTION THAT HAD "DISAPPEARED"
;AND INSERTED CODE TO SET UNIT BITS IN LAST SAT OF EACH UNIT
;PARAMETERS FROM COMMOD.MAC

HOMNAM==0	;"HOM" IN SIXBIT
HOMSNM==4	;STR TO WHICH THIS UNIT BELONGS
HOMNXT==5	;ID OF NEXT UNIT IN FILE STRUCTURE
HOMLUN==10	;LOGICAL UNIT IN STR
HOMBSC==14	;BLOCKS PER SUPERCLUSTER
HOMSCU==15	;SUPER CLUSTERS/UNIT
HOMCNP==16	;CLUSTER COUNT BYTE PTR FOR RETRIEVAL PTRS
HOMCKP==17	;CHECKSUM BYTE PTR
HOMCLP==20	;CLUSTER ADDR BYTE PTR
HOMBPC==21	;BLOCKS PER CLUSTER
HOMSPU==31	;SATS ON THIS UNIT
HOMSAT==34	;LOGICAL BLOCK WITHIN STR OF 1ST RIB FOR SAT.SYS
HOMMFD==46	;LOGICAL BLOCK WITHIN STR OF 1ST MFD RIB
HOMCOD==176	;CONAINS UNLIKELY CODE
HOMSLF==177	;THIS BLOCK WITHIN UNIT

CODHOM==707070	;UNLIKELY CODE FOR HOME BLOCK

RIBFIR==0	;RELATIVE POINTER TO RETRIEVAL PTRS IN RIB
RIBPPN==1
RIBNAM==2
RIBEXT==3
RIBSIZ==5
RIBSTS==17
RBXXX==22	;BASE FOR RIB
RIBFLR==33
RIBXRA==34	;EXTENDED RIB ADD
RIBCOD==176
RIBSLF==177

RIPABC==20000
RIPNUB==400000

CODRIB==777777
BLKSIZ==200

SFDLVL==5	;MAXIMUM NUMBER OF NESTED SFD'S

;END PARAMETERS FROM COMMOD.MAC



OPDEF	PJRST	[JRST]
OPDEF	HALT	[HALT]	;MAKE IT COME OUT IN CREF
	EXTERN	.JBFF,.JBREL,.JBINT
ST:	JFCL			;DEFEND AGAINST CCL
	RESET
	SETZM	.JBINT		;ENABLE ^C INTERUPT
	MOVE	P,[IOWD 200,PDLBLK]

	GETPPN	T1,
	HLRZ	T2,T1		;PROJECT #
	CAIE	T2,1
	JRST	NOTP1		;NOT PROJECT 1

	MOVE	T1,[ASTRST,,ASTRST+1]
	SETZM	ASTRST
	BLT	T1,LAB-1	;ZERO OUT CORE

	MOVE	T1,[XWD 0,16]
	GETTAB	T1,		;GET MFD PPN
	MOVE	T1,[1000001]	;ASSUME 1,1 IF GETTAB FAILED
	MOVEM	T1,MFDPPN	;SAVE
	JUMPE	T1,ZERPPN	;IF 0
	INIT	LPTC,0
	SIXBIT/LPT/
	XWD	OUTBUF,0
	JRST	LPTERR		;ERROR RETURN
	OUTBUF	LPTC,		;SET UP
GETSTR:	MOVE	T2,[POINT 6,STRNAM]
	OUTSTR	[ASCIZ/
WHICH STRUCTURE?/]
	MOVEI	T3,6		;MAX. COUNT
MORSTR:	TTCALL	4,T1
	CAIN	T1,15		;END I/P?
	JRST	ENDSTR
	SUBI	T1,40		;CONVERT TO SIXBIT
	IDPB	T1,T2
	SOJG	T3,MORSTR	;NEXT CHAR
ENDSTR:	PUSHJ	P,CLEAR		;CLEAR REMAINING I/P
GETDRV:	OUTSTR	[ASCIZ/
WHICH DRIVES? (IN FORMAT DRIVE1,DRIVE2,..FOLLOWED
BY A CR.):/]
	MOVEI	P1,0		;INDEX FOR UN%NAM TABLE
NXTDRV:	SETZ	T3,
	MOVE	T2,[POINT 6,T3]
	MOVEI	T4,6		;MAX. COUNT
MORUN:	TTCALL	4,T1
	CAIN	T1,","		;END OF DRIVE?
	JRST	ENDRV
	CAIN	T1,15		;END OF I/P?
	JRST	ENDALL
	SUBI	T1,40		;CONVERT TO SIXBIT
	IDPB	T1,T2
	SOJG	T4,MORUN	;STILL THIS DRIVE?
	TTCALL	4,T1
	CAIE	T1,","		;CORRECT DELIM.?
	JRST	SYNTER		;SYNTAX ERROR
ENDRV:	MOVEM	T3,UN%NAM(P1)
	ADDI	P1,1
	CAILE	P1,^D8
	JRST	TOMANY		;TOO MANY DRIVES
	JRST	NXTDRV		;GET NEXT DRIVE
ENDALL:	MOVEM	T3,UN%NAM(P1)
	ADDI	P1,1
	MOVEM	P1,DRVCNT	;SAVE #DRIVES
	SETZM	UN%NAM(P1)
	PUSHJ	P,CLEAR		;CLEAR REMAINING I/P
	MOVEI	CH,10		;CHBASE=10
	MOVEM	CH,CHBASE
	MOVEI	F,0		;INDEX
MORINT:	MOVE	T3,UN%NAM(F)
	JUMPE	T3,LOOPY	;END OF UN%NAM TABLE
	PUSHJ	P,INITAL	;INIT. CH=CHAN,T3=DRIVE
	ADDI	F,1		;NEXT NAME
	AOJA	CH,MORINT	;NEXT ONE
LOOPY:	SETZM	FLAG
	OUTSTR	[ASCIZ/
DO YOU WANT TO INCLUDE LOOP TEST FOR DISK? Y OR C.R.:/]
	TTCALL	4,T1
	CAIE	T1,"Y"
	JRST	DATIM		;NO SO DONT SET FLAG
	MOVEI	T1,1
	MOVEM	T1,FLAG	;SET FLAG
	PUSHJ	P,CLEAR		;CLEAR L.F.
;O/P DATE AND TIME

DATIM:	OUTSTR	[ASCIZ/
/]
	MOVE	T1,STRNAM
	PUSHJ	P,SIXASC	;O/P STR NAME IN ASCIZ
	PUSHJ	P,STRING
	ASCIZ/	ANALYSIS BEGUN AT /
	MSTIME	P1,		;GET TIME
	IDIVI	P1,^D1000	;IN SECONDS
	IDIVI	P1,^D60		;MINS
	PUSH	P,P2		;STACK SECS
	IDIVI	P1,^D60		;HRS REM MINS
	MOVE	F,P1
	PUSHJ	P,DECOUT	;O/P HRS IN DECIMAL
	PUSHJ	P,STRING
	ASCIZ/:/
	MOVE	F,P2
	PUSHJ	P,DECOUT	;O/P MINS
	PUSHJ	P,STRING
	ASCIZ/:/
	POP	P,F
	PUSHJ	P,DECOUT	;O/P SECS
	PUSHJ	P,STRING
	ASCIZ/	/

	DATE	P1,		;GET DATE
	IDIVI	P1,^D372	;YEARS + REMAINDER IN P2
	IDIVI	P2,^D31		;MONTHS-1 REM DAYS-1
	AOS	F,P3		;DAYS
	PUSHJ	P,DECOUT
	PUSHJ	P,STRING
	ASCIZ/-/
	AOS	F,P2		;MONTHS
	PUSHJ	P,DECOUT
	PUSHJ	P,STRING
	ASCIZ/-/
	MOVE	F,P1		;YEARS
	ADDI	F,^D1964	;BASE YEAR
	PUSHJ	P,DECOUT
	PUSHJ	P,STRING
	ASCIZ/
/
INTDUN:	MOVE	T1,DRVCNT	;# OF DRIVES
	MOVEI	CH,10		;1ST. CHAN
NXT1:	PUSH	P,T1		;SAVE COUNT
	PUSHJ	P,GETHOM	;GET HOME BLOCK FOR THIS DRIVE
				;INTO BUFHOM & TEST IT
	PUSHJ	P,UNITST	;THIS UNIT IN STR?
				;LOGICAL UNIT# IN U
	CAMLE	U,HGHUNI
	MOVEM	U,HGHUNI	;UPDATE HIGHEST UNIT
	MOVEM	CH,UN%CHN(U)	;MAKE ENTRY IN UN%CHN TABLE
	PUSHJ	P,GETWPS	;WRDS/SAT FOR UNIT IN T1
	MOVEM	T1,UN%WPS(U)	;ENTRY IN TABLE
	MOVEI	BUF,BUFHOM
	MOVE	T2,HOMSPU(BUF)	;SATS ON THIS UNIT
	MOVEM	T2,SATNUM(U)	;# SATS ON THIS UNIT
	PUSHJ	P,GETCLS	;GET CLS/UNIT TO T1
	MOVEM	T1,ST%ON(U)	;SAVE IN TABLE
	IDIV	T1,HOMSPU(BUF)	;GET CLUSTERS/SAT
	SKIPE	T2
	ADDI	T1,1		;ROUND UP
	MOVEM	T1,UN%CPS(U)	;CLUSTERS/SAT
	ADDI	CH,1		;NEXT CHAN
	POP	P,T1		;GET COUNT BACK
	SOJG	T1,NXT1		;GET NEXT
	PUSHJ	P,GAPTST	;ANY GAPS IN UN%CHN?
	SETZM	SATBAS
	MOVEI	U,0
NXT2:	MOVE	T1,UN%WPS(U)
	MOVE	T2,SATNUM(U)
	IMUL	T1,T2
	ADD	T1,SATBAS(U)
	MOVEM	T1,SATBAS+1(U)
	ADDI	U,1
	CAMGE	U,DRVCNT
	JRST	NXT2
	PUSHJ	P,CUMCLS	;CUMULATIVE COUNT OF "CLUSTERS
				;BELOW THIS UNIT" TABLE
	MOVEI	BUF,BUFHOM
	MOVE	T1,HOMBPC(BUF)
	MOVEM	T1,BLKCLS	;BLOCKS/CLUSTER
	MOVE	T1,HOMCNP(BUF)
	MOVEM	T1,BPCLCT	;BYTE PTR. FOR CLUST. CNT.
	MOVE	T1,HOMCLP(BUF)
	MOVEM	T1,BPCLAD	;BYTE PTR. FOR CLUST. ADD.


	PUSHJ	P,STRING
	ASCIZ/BLOCKS PER CLUSTER=/
	MOVE	F,BLKCLS
	PUSHJ	P,PRNOCT
	PUSHJ	P,STRING
	ASCIZ/
/
;TEST TO SEE IF PACKS ARE MOUNTED
TESTM:	MOVEI	T1,0		;INDEX TO UN%NAM
TESTM0:	MOVE	P1,UN%NAM(T1)	;GET NAME
	JUMPE	P1,OK		;FINISHED TEST
	MOVEM	P1,MNTST	;FOR DSKCHR
	MOVE	T2,[XWD 4,MNTST]
	DSKCHR	T2,
	JRST	[OUTSTR	[ASCIZ/
?DSKCHR UUO FAILED
/]
		JRST	QUIT]	;GIVE UP

	LDB	T3,[POINT 1,T2,1]
	CAIE	T3,0		;IF BIT 1=1 THEN PACK OFF LINE
	JRST	OFFLIN		;PACK OFF LINE
	LDB	T3,[POINT 2,T2,8]
	CAIN	T3,2		;IF BITS 7&8=10 THEN PACK NOT MOUNTED
	JRST	NXTPAK		;OK SO TEST NEXT PACK
	OUTSTR	[ASCIZ/
PACK MOUNTED. NOT USUALLY DONE. ARE YOU SURE?
Y OR CAR RET.:/]
	TTCALL	4,T3
	CAIN	T3,"Y"
	JRST	NXTPK0		;YES BUT TEST FURTHER PACKS ANYWAY
	PUSHJ	P,CLEAR		;GET RID OF REMAINING I/P
	JRST	TESTM		;START AGAIN

NXTPK0:	OUTSTR	[ASCIZ/
/]
NXTPAK:	ADDI	T1,1		;INCREMENT INDEX
	JRST	TESTM0		;TEST NEXT ONE

OFFLIN:	OUTSTR	[ASCIZ/
?PACK OFF LINE. FIX AND START AGAIN
/]
	JRST	QUIT
;STILL HAVE A HOME BLOCK IN CORE IN BUFHOM
;GET RIB OF SAT.SYS


OK:	MOVEI	BUF,BUFHOM
	MOVE	T1,HOMSAT(BUF)	;LOG. BLK# OF RIB FOR SAT.SYS
				;(WITHIN STR)
	PUSHJ	P,STRUNI	;LOG BLK# WITHIN UNIT IN BLK
				;UNIT# IN U
	MOVEI	BUF,SATRIB
	PUSHJ	P,RUB200	;GET SAT.SYS RIB
	 JRST	STRBER		;I/P ERROR
	PUSHJ	P,RIBTST	;IS IT A RIB?
	 JRST	RIBERR		;RIB ERROR
	MOVEI	BUF,SATRIB
	MOVE	T1,[SIXBIT/SAT/]
	CAME	T1,RIBNAM(BUF)	;NAME=SAT?
	JRST	NOTSAT
	MOVE	T1,[SIXBIT/SYS/]
	HLLZ	T1,RIBEXT(BUF)	;EXT ONLY
	CAME	T1,[SIXBIT/SYS/]
	JRST	NOTSAT
;WANT TO BUILD ST%ADD TABLE (SAT# TO DISC ADDRESS)

	MOVEI	U,0		;1ST. UNIT
	MOVEI	P2,-1
	MOVEI	P1,SATRIB
	ADD	P1,(P1)		;AOBJN TO POINTERS
NXTPTR:	MOVE	T1,(P1)		;GET POINTER IN T1
	JUMPE	T1,SATRD	;EOF
	PUSH	P,P1		;SAVE AOBJN POINTER TO POINTERS
	TLNN	T1,777777	;UNIT CHANGE BITS SET?
	JRST	NXTUNI
	MOVE	P3,BPCLAD
	HRRI	P3,T1
	LDB	T2,P3		;T2=CLUST. ADD REL TO UNIT
	MOVEM	T2,ST%ADD(P2)	;CLUSTER ADD
	MOVE	P1,[POINT 3,U,35]
	MOVE	P3,[POINT 3,ST%ADD(P2),2]
	LDB	T1,P1		;UNIT
	DPB	T1,P3		;IN TABLE
CNTDWN:	ADDI	P2,1		;UPDATE SAT#
CNTDW1:	POP	P,P1
	AOBJN	P1,NXTPTR	;NEXT POINTER
	HALT	.		;SHOULD NEVER HAPPEN (NO EOF PTR)
NXTUNI:	TRZN	T1,400000	;UNIT CHANGE?
	JRST	CMPLAN		;WHY NOT?
	MOVE	U,T1		;UPDATE UNIT
	JRST	CNTDW1		;GO ON FOR NEXT SAT
;READ IN SAT BLOCKS

SATRD:	CAIGE	P2,1		;TOP SAT #
	HALT	.		;NO SATS
	SETZM	ST%ADD-1(P2)	;CLEAR LAST ADD+1
	MOVEI	P1,0		;INDEX TO ST%ADD
	MOVE	P2,.JBFF	;START OF FREE CORE
	MOVEM	P2,ASTRST	;START ADD OF STRSAT
NXTSAT:	LDB	U,[POINT 3,ST%ADD(P1),2]
	LDB	BLK,[POINT 33,ST%ADD(P1),35]
	SKIPN	BLK		;IF NOT BLK 0
	JUMPE	U,DONE		;IF BLK=U=0 THEN DONE
	IMUL	BLK,BLKCLS		;BLK ADD
	ADD	P2,UN%WPS(U)
	CAMLE	P2,.JBREL
	PUSHJ	P,GETCOR	;GET ENOUGH CORE
	MOVEM	P2,.JBFF	;UPDATE
	SUB	P2,UN%WPS(U)	;RESET P2
	MOVEI	BUF,(P2)	;ADD OF BUFFER
	MOVN	T1,UN%WPS(U)	;COUNT
	PUSHJ	P,RUBT1		;I/P T1 WRDS TO BUF
	 JRST	SATERR		;I/P ERROR
	ADD	P2,UN%WPS(U)	;NEXT SAT
	AOJA	P1,NXTSAT	;NEXT SAT BLOCK
DONE:	SUB	P2,ASTRST
	MOVEM	P2,LSTRST	;LENGTH OF SAT TABLE
;MAKE OUR SAT TABLE


;GET ENOUGH CORE TO MAKE OURSAT

	MOVE	P2,.JBFF
	MOVEM	P2,STAOUR	;START ADD OF OURSAT
	ADD	P2,LSTRST	;LENGTH OF STRSAT
	PUSHJ	P,GETCOR	;GET ENOUGH CORE
	MOVEM	P2,.JBFF	;UPDATE
;CLEAR OUR SAT AREA

	MOVE	T2,STAOUR	;START ADDRESS
	SETZM	(T2)		;SET TO ZEROS
	HRR	T1,STAOUR	;ADD
	ADDI	T1,1
	HRL	T1,STAOUR
	ADD	T2,LSTRST
	SUBI	T2,1		;LAST ADD TO CLEAR
	BLT	T1,(T2)
;SET UNUSED BITS IN LAST WORD OF EACH SAT
SETWRD:	MOVEI	U,0		;START WITH UNIT 0
	MOVE	P2,DRVCNT	;# OF DRIVES
UNINXT:	MOVE	P1,SATNUM(U)	;# OF SATS ON THIS UNIT
	MOVE	T1,SATBAS(U)	;BASE OF 1ST SAT FOR UNIT
	ADD	T1,STAOUR	;ADD OF 1ST SAT ON UNIT
	MOVE	T2,UN%WPS(U)	;WRDS/SAT
	IMULI	T2,^D36		;CLUSTERS REP BY EACH SAT
	SUB	T2,UN%CPS(U)	;T2=BITS TO SET AT END OF EACH SAT
	SETOM	T4		;BITS TO STORE (ALL ONES)

SATNXT:	ADD	T1,UN%WPS(U)	;ADD OF NEXT SAT
	SUBI	T1,1		;ADD OF LAST WORD IN SAT
	MOVSI	T3,T1		;SET INDEX IN BYTE PTR ACC
	DPB	T2,[POINT 6,T3,11];SIZE
	DPB	T4,T3		;SET BITS
	ADDI	T1,1		;RESET T1
	SOJLE	P1,ALLSAT	;NONE LEFT
	CAIE	P1,1		;IF LAST SAT
	JRST	SATNXT		;NEXT ONE

	PUSH	P,T1		;SAVE T1
	MOVE	T3,SATNUM(U)	;# SATS ON UNIT
	SUBI	T3,1		;# SATS SO FAR
	IMUL	T3,UN%CPS(U)	;CLUSTERS SO FAR
	PUSHJ	P,GETCLS	;CLUSTERS ON UNIT IN T1
	SUB	T1,T3		;CLUSTERS IN LAST SAT
	MOVE	T3,UN%CPS(U)	;C/SAT
	SUB	T3,T1		;EXTRA BITS FOR LAST SAT
	ADD	T2,T3		;TOTAL BITS FOR LAST SAT
	PUSHJ	P,LSTCLS	;IF LAST CLUSTER IS NOT WHOLE
				;THEN INCREMENT T2
	POP	P,T1		;RESTORE T1
	JRST	SATNXT

ALLSAT:	ADDI	U,1		;NEXT UNIT
	SOJG	P2,UNINXT
;GET MFD RIB

	MOVEI	BUF,BUFHOM
	MOVE	T1,HOMMFD(BUF)	;LOG BLK# OF MFD RIB (WITHIN STR)
	PUSHJ	P,STRUNI	;U=UNIT,BLK=LOG BLK# OF MFD RIB
				; (WITHIN UNIT)
	MOVE	P1,P		;CURRENT P
	MOVEI	P,@.JBFF
	PUSHJ	P,ADVSTK
	JFCL
	PUSH	P,P1		;SAVE OLD P

	JSP	T1,SETSTP	;SET UP STACK FOR MFD
	 JRST	RIBERR		;ERROR IN RIB
	MOVE	P3,[IOWD 50,PDLBK2]	;STACK FOR RECURSION ROUTINE
	PUSHJ	P3,SETSAT	;MAKE OURSAT
	SUBI	P,405		;WIND BACK STACK
	POP	P,P		;GET OLD P BACK


	PUSHJ	P,STRING
ASCIZ/
TOTAL NO OF MULTIPLY DEFINED CLUSTERS= /
	MOVE	F,MULCNT
	PUSHJ	P,DECOUT	;O/P IN DECIMAL
	PUSHJ	P,STRING
	ASCIZ/
/
OUTHED:	PUSHJ	P,STRING
	ASCIZ/	LOST CLUSTERS/
	PUSHJ	P,STRING
	ASCIZ/
/
;COMPARE OUR SAT WITH THEIRS

COMPAR:	MOVEI	U,0
	SETZM	CLSBEF		;CLUSTERS BEFORE START OF THIS SAT
	SETZM	SATCNT		;#SATS SO FAR
	SETZM	LSTCNT		;#LOST BLOCKS SO FAR
	SETZM	FRECNT		;# NF FREE BLOCKS
	SETZM	LINCNT		;# OF NOS. O/P ON LINE SO FAR
	MOVEI	P1,0		;START INDEX AT 0
	MOVEI	F,0		;CLUSTER # OF 1ST CLUSTER IN WRD

NXTENT:	MOVE	P2,ASTRST	;START ADD OF THEIR SAT
	MOVE	P3,STAOUR	;START ADD OF OUR SAT
	ADD	P2,P1
	ADD	P3,P1
	MOVE	T1,(P2)		;THEIR ENTRY
	MOVE	T2,(P3)		;OUR ENTRY
	XOR	T1,T2		;SET BITS THAT ARE DIFFERENT
	JUMPE	T1,NODIF	;SAME
	PUSH	P,F		;SAVE CLUST# OF 1ST CLUST IN WRD

;BITS SET IN T1 ARE EITHER LOST OR FREE BLOCKS
;T2=OUR ENTRY
	MOVEI	T4,^D36		;COUNT
	MOVE	P2,[POINT 1,T1]
	MOVE	P3,[POINT 1,T2]
GETMOR:	PUSH	P,T4		;SAVE COUNT
	ILDB	T4,P2
	JUMPE	T4,[ILDB T4,P3
		JRST	NOTONE]
	PUSH	P,T1
	PUSH	P,T2
	PUSHJ	P,SPACNG	;GET SPACING RIGHT
	PUSHJ	P,PRNOCT	;CLUST# IN F.CONVERT TO OCTAL & O/P
	POP	P,T2
	POP	P,T1
	ILDB	T4,P3
	JUMPE	T4,LSTONE	;LOST
	PUSHJ	P,FREE		;O/P AN F AND UPDATE # OF FREE
	JRST	NOTONE

LSTONE:	AOS	LSTCNT
NOTONE:	ADDI	F,1		;ADD OF NEXT CLUSTER
	POP	P,T4		;GET COUNT BACK
	SOJG	T4,GETMOR	;NEXT BIT
	POP	P,F		;RESTORE CLUST # OF 1ST CLUST IN WRD
NODIF:	ADDI	P1,1		;INCREMENT INDEX
	ADDI	F,^D36		;AND CLUST#
	MOVE	T1,UN%CPS(U)	;CLUST/SAT FOR UNIT
	ADD	T1,CLSBEF	;CLUSTS BEFORE START OF THIS SAT
	CAMG	F,T1
	JRST	NXTENT		;STILL IN SAME SAT
	MOVE	F,T1
	MOVE	T1,UN%CPS(U)
	ADDM	T1,CLSBEF	;UPDATE CLUSTS BEFORE THIS SAT
	AOS	T1,SATCNT	;UPDATE
	CAMGE	T1,SATNUM(U)	;TOTAL # OF SATS ON UNIT
	JRST	NXTENT		;STILL THIS UNIT
	ADDI	U,1		;NEXT UNIT
	CAML	U,DRVCNT	;FINISHED?
	JRST	TOTOUT		;YES GO TO NEXT PART
	SETZM	SATNUM		;RESET
	JRST	NXTENT		;NEXT ENTRY


FREE:	PUSH	P,T1
	MOVEI	T1,"F"
	PUSHJ	P,WRITEC	;O/P AN F TO SHOW CLUSTER FREE (T2 PRESERVED)
	AOS	FRECNT		;UPDATE FREE COUNT
	POP	P,T1
	POPJ	P,
;	O/P TOTAL # OF LOST BLOCKS

TOTOUT:	PUSHJ	P,STRING
	ASCIZ/

	TOTAL NO. OF LOST CLUSTERS = /
	MOVE	F,LSTCNT
	PUSHJ	P,DECOUT	;CONVERT & O/P
	PUSHJ	P,STRING
	ASCIZ/
/
	OUT	LPTC,		;GET IT ON PAPER


	PUSHJ	P,STRING
	ASCIZ/
TOTAL NO OF FREE CLUSTERS=/
	MOVE	F,FRECNT
	PUSHJ	P,DECOUT	;CONVERT AND O/P
	PUSHJ	P,STRING
	ASCIZ/
/
	OUT	LPTC,		;GET IT ON PAPER
;IF NO LOST OR FREE CLUSTERS THEN FINISHED
	MOVE	T1,LSTCNT
	MOVE	T2,FRECNT	;FREE
	MOVE	T2,FRECNT	;FREE
	CAIN	T1,0		;NO LOST?
	CAIE	T2,0		;NO FREE
	JRST	SATWIT		;YES SO WRITE OUR SATS
	JRST	QUIT		;NO LOST OR FREE SO ALL DONE
SATWIT:	CLRBFI			;MAKE SURE GET AN "HONEST" REPLY
	OUTSTR	[ASCIZ/
DO YOU WANT THESE SATS WRITTEN ONTO DSK?Y OR N:/]

	TTCALL	4,T1		;GET ANSWRE
	CAIE	T1,"Y"
	JRST	QUIT		;NO SO DONE
	PUSHJ	P,CLEAR		;CLEAR REMAINING I/P & CONTINUE


	MOVEI	T1,INTRBK
	MOVEM	T1,.JBINT	;DISABLE ^C INTERRUPT
;WRITE OUR SATS ONTO DSK
;ST%ADD=TABLE OF POINTERS TO SATS; 1ST 4 BITS=UNIT
;RH=BLOCK ADD REL TO UNIT

	MOVEI	P1,0		;INDEX TO ST%ADD TABLE
	MOVE	P2,STAOUR	;START ADD OF OUR SAT

NXTCOP:	PUSHJ	P,SETTMP	;SET TRANSFER BUFFER TO ALL ONES
	HRLZ	P3,P2		;CURRENT POS IN OUR SAT
	HRRI	P3,TMPBUF	;ADD OF TRANSFER BUFFER

	MOVE	T1,ST%ADD(P1)	;THIS ENTRY
	JUMPE	T1,QUIT		;END OF PTRS IF U=ADD=0
	LDB	U,[POINT 4,T1,3]

	MOVE	T1,UN%WPS(U)	;# OF WRDS TO TRANSFER
	ADDI	T1,TMPBUF-1	;ADD OF LAST WORD TO TRANSFER
	BLT	P3,(T1)		;TRANSFER THIS MANY

	MOVE	T2,ST%ADD(P1)	;THIS ENTRY
	LDB	FBN,[POINT 32,T2,35]
	IMUL	FBN,BLKCLS	;BLOCK ADDRESS
	MOVE	CH,UN%CHN(U)	;CHAN THIS UNIT IS ON
;WRITE OUT 1 DISK BLOCK FROM TMPBUF TO UNIT ON CHAN,CH
;STARTING AT BLK ADD FBN

	DPB	CH,[POINT 4,SET1,12]	;FOR USETO
	DPB	CH,[POINT 4,SET2,12]	;FOR O/P
	DPB	CH,[POINT 4,SET3,12]	;FOR STATUS
	DPB	CH,[POINT 4,SET0,12]	;FOR GETSTS
	SETZM	LABO+1

SET0:	GETSTS	0,T1
SET1:	USETO	0,FBN
SET2:	OUTPUT	0,LABO
SET3:	STATZ	0,740000		;ANY ERROR?
	JRST	OUTERR			;YES

	ADD	P2,UN%WPS(U)		;UPDATE IT
	AOJA	P1,NXTCOP		;INCREMENT INDEX & LOOP

;ROUTINES


;I/P ROUTINE
;-----------

;T1=COUNT
RUBT1:	MOVE	CH,UN%CHN(U)	;GET CHANNEL
	JRST	RUB200+2

RCB200:	SKIPA			;GOT CHAN ALREADY

;U=UNIT,BLK=BLOCK#,BUF=BUFFER
RUB200:	MOVE	CH,UN%CHN(U)	;GET CHANNEL
	MOVEI	T1,-200		;COUNT
	HRLM	T1,LAB
	HRRM	BUF,LAB		;BUFFER ADD
	SOS	LAB		;MAKE LAB A PROPER I/O WRD
	PUSHJ	P,INP		;I/P THIS BLK
	 POPJ	P,
	JRST	CPOPJ1		;GIVE SKIP RETURN
INP:	DPB	CH,[POINT 4,SET,12]
	DPB	CH,[POINT 4,INCHAN,12]
	DPB	CH,[POINT 4,INCHAN+1,12]

SET:	USETI	0,BLK
INCHAN:	INPUT	0,LAB
	STATZ	0,740000	;ERROR?
	SOS	(P)		;COUNTERACT SKIP RETURN
CPOPJ1:	AOS	(P)
CPOPJ:	POPJ	P,
;LINE PRINTER O/P ROUTINES
WRITC0:	OUT	LPTC,
	JRST	WRITEC		;OK
	STATZ	LPTC,740000	;ANY ERROR?
	JRST	LPTOER		;YES
	JRST	HELP		;ASSUME EOF & SCREAM!!
WRITEC:	SOSG	OUTBUF+2	;DECREMENT COUNT
	JRST	WRITC0		;O/P
	IDPB	T1,OUTBUF+1
	POPJ	P,		;RETURN
;CONVERT C(F) TO OCTAL & O/P
PRNOCT:	PUSH	P,F
	MOVEI	T2,6		;COUNT
	HRLZ	F,F
	MOVE	T3,[POINT 3,F]
NXTNO:	ILDB	T1,T3
	ADDI	T1,60		;CONVERT TO NO.
	PUSHJ	P,WRITEC	;O/P
	SOJG	T2,NXTNO
	POP	P,F
	POPJ	P,
;O/P A STRING OF ASCIZ CHARACTERS
STRING:	MOVSI	T2,440700	;MAGIC #
	HRR	T2,(P)		;T2=BYTE PTR TO STRING
	ILDB	T1,T2
	JUMPE	T1,.+3		;END OF STRING
	PUSHJ	P,WRITEC	;O/P
	JRST	.-3		;NEXT BYTE

	ADDI	T2,1
	HRRM	T2,(P)		;UPDATE P
	POPJ	P,		;AND RETURN
;CONVERT C(T1) FROM SIXBIT TO ASCIZ & RETURN RESULT IN T1
SIXASC:	MOVEI	T4,5		;COUNT
	MOVE	T2,T1
MORCNV:	ILDB	T1,[POINT 6,T2]
	ADDI	T1,40
	PUSHJ	P,WRITEC
	SOJG	T4,MORCNV	;STILL MORE
	POPJ	P,
DECOUT:	PUSH	P,F+1		;MAKE SURE NO DISASTER HAPPENS
	PUSHJ	P,DECOU0	;CONVERT & PRINT
	POP	P,F+1		;RESTORE F+1
	POPJ	P,
DECOU0:	MOVEI	T2,^D10
RADOUT:	IDIVI	F,(T2)		;USES RADIX T2
	HRLM	F+1,(P)		;STACK REMAINDER
	SKIPE	F		;WHEN DONE
	PUSHJ	P,RADOUT	;NEXT DIGIT
	HLRZ	T1,(P)
	MOVEI	T1,"0"(T1)
	PJRST	WRITEC		;OUT CHAR AND RETURN
;CH=CHAN,T3=DRIVE IN SIXBIT
INITAL:	DPB	CH,[POINT 4,INTBLK,12]
	MOVEM	T3,INTBLK+1	;DRIVE
INTBLK:	INIT	0,17		;DUMP MODE
	0			;DEVICE
	0
	JRST	INTERR
	POPJ	P,
CLEAR:	TTCALL	4,T1
	CAIE	T1,12		;L.F.?
	JRST	CLEAR		;CONT UNTIL U GET ONE
	POPJ	P,
GETCLS:	PUSH	P,T2
	MOVEI	BUF,BUFHOM
	MOVE	T1,HOMSCU(BUF)	;SUPER CLUST./UNIT
	IMUL	T1,HOMBSC(BUF)
	IDIV	T1,HOMBPC(BUF)
	SKIPE	T2
	ADDI	T1,1		;ROUND UP
T2POPJ:	POP	P,T2		;RESTORE T2
	POPJ	P,
GETHOM:	MOVEI	BUF,BUFHOM	;BUFFER
	MOVEI	BLK,1		;1ST HOME BLK
	PUSHJ	P,RCB200
	 JRST	HOM2		;TRY 2ND HOME BLOCK
	PUSHJ	P,HOMTST	;IS IT A HOME BLOCK?
	 SKIPA			;TRY OTHER ONE
	JRST	CPOPJ		;NO GOT ONE
HOM2:	MOVEI	BUF,BUFHOM
	MOVEI	BLK,10		;2ND HOME BLK
	PUSHJ	P,RCB200
	 JRST	HOMERD

	PUSHJ	P,HOMTST	;IS IT A HOME BLOCK?
	 JRST	HOMERR
	POPJ	P,
HOMTST:	MOVEI	BUF,BUFHOM
	MOVE	T1,[SIXBIT/HOM/]
	CAME	T1,HOMNAM(BUF)
	JRST	CPOPJ
	MOVEI	T1,CODHOM
	CAME	T1,HOMCOD(BUF)
	JRST	CPOPJ
	JRST	CPOPJ1		;GIVE SKIP RETURN. (HAVE HOME BLK)
RIBTST:	SKIPL	RIBFIR(BUF)
	JRST	RBTST0		;NO AOBJN WRD
	MOVE	T1,RIBCOD(BUF)
	CAME	T1,[CODRIB]
	JRST	RBTST0		;NO CODE
	CAME	BLK,RIBSLF(BUF)	;THIS BLOCK
	JRST	RBTST0		;RIBERR
	AOS	(P)		;SKIP RETURN IF OK
	POPJ	P,
RBTST0:	OUTSTR	[ASCIZ/
?RIB ERROR
/]
	POPJ	P,		;NON SKIP RETURN IF ERROR
;P2 SET UP

;ROUTINE TO SEE IF LAST CLUSTER ON UNIT IS WHOLE
;IF NOT WHOLE THEN INCREMENT T2 (BITS TO SET AT END OF LAST SAT)

LSTCLS:	PUSH	P,T1		;SAVE ACCS
	PUSH	P,T2

	MOVE	T1,UN%NAM(U)	;UNIT NAME
	MOVEM	T1,NAMLOC	;STORE
	MOVE	T1,[XWD 1,NAMLOC]
	DSKCHR	T1,
	JRST	[OUTSTR	[ASCIZ/
?DSKCHR UUO FAILED FOR UNIT
/]
		JRST	QUIT]

	LDB	T2,[POINT 6,T1,26];CONTROLLER TYPE
	CAIN	T2,1
	JRST	FIXED		;FIXED HEAD
	CAIE	T2,2
	JRST	[OUTSTR	[ASCIZ/
?CONTROLLER IS NEITHER FH OR DP
/]
		JRST	QUIT]

;MOVEABLE HEAD
	LDB	T2,[POINT 3,T1,32];UNIT TYPE
	CAIN	T2,1		;RPO2?
	JRST	[MOVE	T1,[^D40000]
		JRST	GOTBLK]
	CAIN	T2,2		;RPO3?
	JRST	[MOVE	T1,[^D80000]
		JRST	GOTBLK]

	OUTSTR	[ASCIZ/
MOVEABLE HEAD IS NEITHER RPO2 OR RPO3
/]
	JRST	QUIT
FIXED:	LDB	T2,[POINT 3,T1,32];UNIT TYPE
	CAIN	T2,0		;BURROUGHS DISK?
	JRST	[MOVE	T1,[^D4000]
		JRST	GOTBLK]
	CAIN	T2,1		;BRYANT DRUM?
	JRST	[MOVE	T1,[^D2700]
		JRST	GOTBLK]

	OUTSTR	[ASCIZ/
FIXED HEAD IS NEITHER BURROUGHS DISK OR BRYANT DRUM
/]
	JRST	QUIT
;T1=BLOCKS ON UNIT
GOTBLK:	IDIV	T1,BLKCLS
	SKIPE	T2
	AOS	(P)		;INCREMENT T2 (IE. ROUND UP)
	POP	P,T2		;RESTORE T2
	POP	P,T1		;& T1
	POPJ	P,
GETCOR:	PUSH	P,T1
	MOVE	T1,P2
	CORE	T1,
	JRST	NOCORE		;NO MORE CORE
TPOPJ:	POP	P,T1		;RESTORE T1
	POPJ	P,		;AND RETURN
CUMCLS:	SETZ	P3,		;COUNT TO ADD
	MOVE	T4,DRVCNT	;# OF DRIVES
	SETZM	ST%BEL		;1ST ENTRY 0
	MOVEI	T1,0		;INDEX TO ST%ON
	MOVEI	T2,1		;INDEX TO ST%BEL

NXTCUM:	MOVE	T3,ST%ON(T1)	;CLUSTERS ON UNIT
	ADD	T3,P3		;ADD COUNT SO FAR
	MOVEM	T3,ST%BEL(T2)	;CLUSTERS BELOW UNIT
	ADD	P3,T3		;UPDATE COUNT TO ADD
	ADDI	T1,1
	ADDI	T2,1		;AND INDEXES
	SOJG	T4,NXTCUM	;NEXT ENTRY
	POPJ	P,
UNITST:	MOVEI	BUF,BUFHOM
	MOVE	T1,HOMSNM(BUF)	;STR THIS UNIT BELONGS TO
	CAME	T1,STRNAM	;SAME?
	JRST	WRNSTR		;WRONG STR
	MOVE	U,HOMLUN(BUF)	;LOGICAL UNIT# OF THIS UNIT
	POPJ	P,		;WITHIN THIS FILE STR
GAPTST:	MOVEI	T1,0
	MOVE	T4,DRVCNT	;# OF DRIVES
	JUMPE	T4,AYAY		;0 DRIVES?
NXTCHN:	MOVE	T3,UN%CHN(T1)	;CHAN
	JUMPE	T3,GAP
	ADDI	T1,1		;NEXT INDEX
	SOJG	T4,NXTCHN	;NEXT
	POPJ	P,


GAP:	OUTSTR	[ASCIZ/
?GAP FOUND IN CHANNEL TABLE.HAVE YOU GIVEN ALL THE DRIVES?/]
	JRST	GETDRV		;TRY AGAIN
GETWPS:	MOVEI	BUF,BUFHOM
	MOVE	T1,HOMBSC(BUF)
	IMUL	T1,HOMSCU(BUF)
	IDIV	T1,HOMBPC(BUF)	;T1=#CLUSTERS/UNIT
	SKIPE	T2		;IF REMAINDER=0
	ADDI	T1,1		;ROUND UP
	IDIV	T1,HOMSPU(BUF)	;WRDS/SAT
	CAIE	T2,0
	ADDI	T1,1		;ROUND UP
	IDIVI	T1,^D36		;WORDS NEEDED
	SKIPE	T2		;IF REMAINDER=0
	ADDI	T1,1		;ROUND UP
	POPJ	P,

;U=UNIT,T1=CLUSTER ADD REL TO UNIT
UNISTR:	ADD	T1,ST%BEL(U)
	POPJ	P,
;T1=LOGICAL BLOCK# WITHIN STR
STRUNI:	MOVEI	U,0		;START WITH UNIT 0
	MOVE	T2,ST%ON(U)	;CLUSTERS
	IMUL	T2,BLKCLS	;T2=BLOCKS ON UNIT
	CAMLE	T1,T2		;ON THIS UNIT?
	AOJA	U,STRUNI+1	;NEXT
	MOVE	T2,ST%BEL(U)	;CLS BELOW THIS UNIT
	IMUL	T2,BLKCLS	;BLKS BELOW THIS UNIT
	SUB	T1,T2		;T1=LOG BLK# WITHIN UNIT
	MOVE	BLK,T1
	POPJ	P,
;T1=WRDS,T2=BITS
TABMAK:	PUSH	P,P1		;SAVE P1
	MOVE	T3,STAOUR	;START ADD OF OURSAT
	MOVEI	T4,^D35
	SUB	T4,T2		;BITS TO RIGHT
	ADD	T3,T1		;WORD IN TABLE
	MOVE	P1,[POINT 1,(T3),0]
	DPB	T4,[POINT 6,P1,5]	;CHECK ON 5
	SETO	T2,
	LDB	T4,P1
	JUMPN	T4,MULTI	;BIT ALREADY SET SO COMPLAIN
	DPB	T2,P1		;SET BIT
TABMK1:	POP	P,P1		;RESTORE P1
	POPJ	P,
MULTI:	PUSHJ	P,SPACNG
	MOVE	F,CDUMP		;CLUSTER # WRT UNIT
	ADD	F,CLSBEF(U)	;CLUSTER # WRT STR
	PUSHJ	P,PRNOCT	;O/P
	AOS	MULCNT
	JRST	TABMK1
;RDBLK:	READ BLOCK FBN,RELATIVE TO FILE WHOSE RIB ADD IS
;IN RIBPTR. BUFFER GIVEN IN BUF

RDBLK:	PUSHJ	P,GENBLK	;RETURN WITH U=UNIT
				;T2=CLUSTER ADD &
				;T3=BLOCKS ON IN FRAGMENT
	 JRST	RDBLK0
	IMUL	T2,BLKCLS	;BLOCK ADD OF 1ST. CLUSTER
	ADD	T2,T3		;THIS BLOCK
	MOVE	BLK,T2		;BLOCK# FOR I/P
	PUSHJ	P,RUB200	;I/P
	 JRST	INPERR
	AOS	(P)		;GOOD RETURN
RDBLK0:	POPJ	P,
;RIBPTR=ADD OF RIB. MARK ALL BLOCKS OF FILE

MRKBLK:	MOVEI	FBN,0
NXTBLK:	PUSHJ	P,GENBLK
	 POPJ	P,		;RETURN IF EOF
	MOVE	T1,T2
	IMUL	T1,BLKCLS	;BLK ADD
	ADD	T1,T3		;THIS BLK
	IDIV	T1,BLKCLS	;THIS CLUSTER # WRT UNIT
	MOVEM	T1,CDUMP	;SAVE CLUSTER # FOR PRINTING IF MULTIPLE
	JUMPN	T2,COUNTY	;IF REMAINDER NOT 0 THEN CLUSTER
				;IS ALREADY MARKED
	IDIV	T1,UN%CPS(U)	;T1=SAT#
				;T2=CLUSTER # WRT THIS SAT
	IDIVI	T2,^D36		;T2=WRDS ON IN THIS SAT
				;T3=BITS ON IN THIS WRD
	IMUL	T1,UN%WPS(U)
	ADD	T1,SATBAS(U)	;BASE FOR THIS SAT
	ADD	T1,T2		;THIS WRD
	MOVE	T2,T3		;FOR TABMAK
	PUSHJ	P,TABMAK	;SET THIS BLOCK "IN USE"
COUNTY:	ADDI	FBN,1		;NEXT BLOCK
	JRST	NXTBLK		;MARK NEXT BLOCK

;CALLED WITH RIBPTR=ADD OF RIB & FBN=BLOCK # OF FILE

GENBLK:	PUSH	P,FBN
	PUSH	P,P1
	SUB	FBN,RBXXX(RIBPTR);SUBTRACT BASE
	JUMPL	FBN,OHDEAR	;-VE FBN NOT ALLOWED!!
	MOVE	P1,RIBPTR	;ADD OF RIB
	ADD	P1,(P1)		;AOBJN TO POINTERS
NXTGRP:	MOVE	T1,(P1)		;T1=POINTER
	JUMPN	T1,NXTGR1	;NOT EOF
NXTGR0:	POP	P,P1
	POP	P,FBN
	POPJ	P,
NXTGR1:	TLNE	T1,777777	;UNIT CHANGE BITS SET?
	JRST	GRPTR		;NO SO GROUP POINTER
	TRZN	T1,400000	;UNIT CHANGE?
	JRST	[OUTSTR	[ASCIZ/
?BAD UNIT CHANGE IN RIB - TREATED AS EOF
/]
		JRST	NXTGR0]	;GIVE NON SKIP RETURN
	MOVE	U,T1		;UPDATE UNIT
	JRST	COUNT+1		;COUNTDOWN


GRPTR:	PUSHJ	P,GETINF	;T2=CLS ADD,T3=FRGCNT IN BLKS


;IS FBN IN THIS GROUP?
TSTGRP:	CAML	FBN,T3
	JRST	COUNT
	MOVE	T3,FBN
	AOS	-2(P)		;FOUND GROUP SKIP RETURN
	JRST	NXTGR0		;QUIT
COUNT:	SUB	FBN,T3		;# BLKS AFTER THIS GRP
	AOBJN	P1,NXTGRP	;TRY NEXT GROUP


	MOVE	T1,RIBXRA(RIBPTR);GET EXTENDED RIB ADD
	JUMPE	T1,NOPTRS	;NOT AN EXTENDED RIB

	LDB	U,[POINT 4,T1,12];UNIT
	LDB	BLK,[POINT 23,T1,35];ADD
	MOVE	BUF,RIBPTR	;BUFFER
	PUSHJ	P,RUB200	;READ IN EXTENDED RIB
	 JRST	EXTERR		;YES
	PUSHJ	P,RIBTST	;IS IT A RIB?
	 JRST	NOGO		;ERROR RETURN
	POP	P,P1		;KEEP STACK RIGHT
	POP	P,FBN
	MOVEM	FBN,RBXXX(RIBPTR);SET OFFSET
	JRST	GENBLK		;CONTINUE WITH NEXT RIB

NOPTRS:	OUTSTR	[ASCIZ/
?RUN OUT OF POINTERS BEFORE
REACHING END OF FILE
/]
	JRST	NXTGR0		;SIMULATE EOF WHEN CANT READ
				;EXTENDED RIB OR GET RIB ERROR
NOGO:	OUTSTR	[ASCIZ/
?ERROR IN EXTENDED RIB. CONTINUING
/]
	JRST	NXTGR0		;RIB ERROR - SIMULATE EOF
;POINTER IN T1
;GET	1) CLUSTER ADD IN T2
;	2) FRGCNT IN BLOCKS IN T3

GETINF:	PUSH	P,P1		;RESPECT P1
	MOVE	P1,BPCLCT	;BYTE PTR FOR CLUST CNT
	HRRI	P1,T1
	LDB	T3,P1		;CLUSTER CNT
	IMUL	T3,BLKCLS	;BLOCK COUNT

	MOVE	P1,BPCLAD	;BYTE PTR FOR CLUST ADD
	HRRI	P1,T1
	LDB	T2,P1		;CLUST ADD (REL TO UNIT)
	POP	P,P1		;RESPECT P1
	POPJ	P,
;BUFFER IN BUF
GETSIZ:	MOVE	T1,RIBSIZ(BUF)
	IDIV	T1,200		;SIZE IN BLOCKS OF FILE
	POPJ	P,

;RECURSIVE ROUTINE TO MAKE OURSAT

SETSAT:	MOVE	P1,(P)	;INITIALISE P1
SETST0:	SKIPN	(P1)		;FILE NAME =0?
	JRST	SETST4		;WAS 0 SO GET NEXT
	HLRZ	T2,1(P1)	;EXT
	CAIE	T2,'UFD'	;.UFD
	JRST	SETST1		;CANT BE MFD
	MOVE	T2,(P1)
	CAMN	T2,MFDPPN	;WAS MFD IE <MFDPPN>.UFD
	JRST	SETST4		;IGNORE IT (SO DONT LOOP)

SETST1:	SKIPE	FLAG		;IF FLAG NOT SET
	PUSHJ	P,LOPTST	;TEST FOR LOOP ON DISK
	HRRZ	T1,1(P1)	;GET CFP
	MOVEM	P1,-1(P)	;SAVE CURRENT POSITION
	PUSHJ	P,CFPCNV	;U=UNIT,BLK=BLOCK#
	 JRST	SETST4		;FORGET IT!
	JSP	T1,SETSTP	;SET UP STACK
	 JRST	SETST7		;GOT A RIB ERROR
	PUSHJ	P3,SETSAT	;RECURSE
SETST3:	SUBI	P,405		;WIND BACK STACK
SETST8:	MOVE	P1,-1(P)	;GET POINTER TO POSITION
SETST4:	AOBJN	P1,.+1		;ADVANCE
	AOBJN	P1,SETST0	;JUMP IF MORE
	AOS	FBN,-3(P)	;INCREM. & LOAD FBN
	CAMLE	FBN,-2(P)	;EOF?
	JRST	SETST5		;EOF
	MOVE	P1,(P)	;INITIALISE P1 AGAIN
	MOVEM	P1,-1(P)	;SAVE CURRENT POS
	MOVEI	BUF,(P1)
	MOVEI	RIBPTR,-200(BUF)
	PUSHJ	P,RDBLK		;READ BLOCK IN
	 JRST	SETST3		;ERROR RETURN SO MISS THIS STEP OUT
	JRST	SETSAT		;LOOP
SETST6:	MOVEI	RIBPTR,-404(P)		;PTR TO RIB
	SETZM	RBXXX(RIBPTR);ZERO OUT BASE FOR RIB
	PUSHJ	P,MRKBLK
	JRST	SETST3

SETST5:	MOVEI	RIBPTR,-404(P)	;PTR TO RIB (ITSELF)
	PUSHJ	P,MRKBLK	;MARK IT
	POPJ	P3,


SETST7:	SUBI	P,401		;WIND BACK STACK IF BAD RIB
	JRST	SETST8		;CONT AS IF NOT THERE
;SET UP STACK

SETSTP:	MOVEM	T1,LNKSAV	;SAVE LINK ADD
	PUSHJ	P,ADVSTK	;ADVANCE STACK
	ADDI	P,401		;PARAMETER
	MOVEI	BUF,-400(P)	;SET UP BUFFER
	PUSHJ	P,RUB200	;READ BLOCK
	JRST	TEMP		;I/P ERROR
	PUSHJ	P,RIBTST	;IS IT A RIB?
	 JRST	SETSP0		;ERROR RETURN

	MOVEI	FBN,1		;START AT 1ST. BLOCK
	PUSH	P,FBN		;STACK BLK#
	MOVE	T1,RIBSIZ(BUF)
	JUMPL	T1,NEGSIZ	;-VE RIBSIZ
	LSH	T1,-7		;GET LAST BLK#
	PUSH	P,T1		;STACK BLK# LIMIT
	MOVSI	P1,-200
	HRRI	P1,-202(P)	;AOBJN PTR TO DATA
	PUSH	P,P1		;REMEMBER ORIGINAL POS
	PUSH	P,P1		;AND CURRENT POS

	MOVEI	T1,1B18		;DIRECTORY BIT
	TDNE	T1,RIBSTS(BUF)	;SKIP IF SET
	SKIPN	-2(P)		;CATCH 0 LENGTH FILES
	JRST	SETST6		;WAS 0
	MOVE	BUF,-1(P)	;SET UP BUFFER ADD
				;FROM ORIGINAL PTR
	MOVEI	RIBPTR,-200(BUF);PTR TO RIB
	SETZM	RBXXX(RIBPTR)	;INITIALISE OFFSET
	SKIPN	FLAG
	JRST	NOTEST
	PUSHJ	P,INCONS	;SEE IF INCONSISTENCEY
	JRST	SETST3		;YES. IGNORE THIS LEVEL
NOTEST:	PUSHJ	P,RDBLK		;READ A DATA BLOCK
	 JRST	SETST3		;ERROR RETURN SO MISS THIS STEP OUT
	AOS	T1,LNKSAV	;GET LINK ADD BACK AND GIVE SKIP RET.
	JRST	@T1		;& RETURN TO CALL OF SETSTP


SETSP0:	MOVE	T1,LNKSAV
	JRST	@T1
TEMP:	OUTSTR	[ASCIZ/
?INPUT ERROR
/]
	JRST	QUIT
;TEST FOR LOOP ON DISC

LOPTST:	POP	P,T1	;LINK
	MOVEM	T1,LNKSAV	;SAVE
	MOVEM	P1,SAVE1	;SAVE P1 & DONT CHANGE STACK
	MOVEM	P2,SAVE2	;& P2
	MOVEM	P3,SAVE3	;& P3
	MOVE	T1,(P1)		;NAME
	MOVEM	T1,NAME		;SAVE NAME
	HLRZ	T2,1(P1)	;EXT
	MOVEM	T2,EXT		;SAVE EXT
	MOVE	T2,1(P1)	;EXT & CFP
	MOVEI	T3,-406		;PTR TO POSITION IN PREVIOUS LEVEL
LPTST0:	HRRZ	P2,P		;CURRENT POS IN STACK
	ADD	P2,T3		;ADD OF PTR TO DATA
	MOVEM	P2,SAVE		;SAVE P2
	HRRZ	P1,(P2)		;PTR IN P1
	MOVE	P2,(P1)		;NAME
	CAME	P2,T1		;SAME AS CURRENT NAME?
	JRST	ENDTST		;NO 
	MOVE	P3,1(P1)	;EXT & CFP
	CAME	P3,T2		;SAME?
	JRST	ENDTST		;NO

	MOVE	P1,SAVE1
	MOVE	P2,SAVE2
	MOVE	P3,SAVE3
	OUTSTR	[ASCIZ/
?FOUND A LOOP ON THE DISC BUT CONTINUING
/]
	JRST	SETST3		;LOOP SO IGNORE THIS LEVEL


ENDTST:	MOVE	P2,SAVE		;GET P2 BACK
	ADDI	P2,4		;TO NAME IN RIB
	MOVE	P1,(P2)		;NAME
	HLRZ	P3,1(P2)	;EXT
	CAIN	P3,'UFD'	;UFD?
	CAME	P1,MFDPPN	;IS IT MFD?
	JRST	NOTSAM		;REACHED LOWEST LEVEL
	JRST	NOTDUN		;STILL MORE LEVELS TO TEST

NOTSAM:	SUBI	T3,405		;NEXT LEVEL UP
	JRST	LPTST0		;TEST IT

NOTDUN:	MOVE	P1,SAVE1
	MOVE	P2,SAVE2
	MOVE	P3,SAVE3
	JRST	@LNKSAV		;RETURN NO LOOP FOUND
;INCONSISTENCY TEST

INCONS:	MOVE	T1,2(RIBPTR)	;NAME IN RIB
	CAMN	T1,MFDPPN
	JRST	EXTST		;DONT WANT TO FOR MFD
	CAME	T1,NAME
	JRST	INCON0		;INCONSISTENCY ERROR
EXTST:	HLRZ	T1,3(RIBPTR)	;EXT
	CAIN	T1,'UFD'
	JRST	RET		;MFD SO RETURN
	CAME	T1,EXT
	JRST	INCON0		;INCONSISTENCY
RET:	AOS	(P)		;SKIP RETURN IS GOOD
	POPJ	P,


INCON0:	OUTSTR	[ASCIZ/
?INCONSISTENCY ERROR. CONTINUING
/]
	POPJ	P,		;ERROR RETURN
;ADVANCE STACK
ADVSTK:	HRRZ	T1,@(P)
	ADD	T1,P
	ADDI	T1,100		;EXTRA
	TLZ	T1,-1
	CORE	T1,
	JRST	NOCORE		;NO MORE CORE
	POPJ	P,
;T1=CFP..CONVERT TO U=UNIT,BLK=BLOCK#
CFPCNV:	MOVEI	U,1		;INDEX=UNIT+1
CFPCN0:	MOVE	T3,ST%BEL(U)	;CLUSTS BELOW THIS UNIT
	CAMG	T1,T3		;FOUND UNIT?
	JRST	GOTUNI		;FOUND UNIT
	ADDI	U,1		;NEXT UNIT
	CAMLE	U,DRVCNT	;WITHIN BOUNDS?
	JRST	BADUN		;NO
	JRST	CFPCN0		;TRY NEXT UNIT

GOTUNI:	SUBI	U,1		;U=UNIT
	MOVE	T3,ST%BEL(U)	;CLUSTERS BELOW THIS UNIT
	SUB	T1,T3		;CLUST# ON UNIT
	CAMLE	T1,ST%ON(U)	;WITHIN BOUNDS?
	JRST	BADUN		;NO
	IMUL	T1,BLKCLS	;BLK# ON UNIT
	MOVE	BLK,T1
	AOS	(P)		;GIVE GOOD RETURN
BADUN:	POPJ	P,
;SET TMPBUF TO ALL ONES

SETTMP:	SETOM	TMPBUF
	MOVE	T1,[XWD TMPBUF,TMPBUF+1]
	BLT	T1,TMPBUF+177
	POPJ	P,
SPACNG:	PUSH	P,T2
	MOVE	T2,LINCNT	;# OF NOS ON LINE SO FAR
	JUMPE	T2,UPDCNT	;DONT WANT TAB 1ST TIME THRU
	CAIL	T2,^D15
	JRST	EOL
	PUSH	P,T2		;SAVE COUNT
	PUSHJ	P,STRING
	ASCIZ/	/		;O/P A TAB
	POP	P,T2
UPDCNT:	ADDI	T2,1		;INCREMENT COUNT
	MOVEM	T2,LINCNT	;UPDATE COUNT
	POP	P,T2
	POPJ	P,
EOL:	PUSHJ	P,STRING
	ASCIZ/
/
	SETZ	T2,		;RESET LINE COUNT TO 0
	JRST	UPDCNT		;UPDATE TO 1 AND RETURN
;INTERRUPT ROUTINE

INTRTN:	PUSH	P,T1		;SAVE T1
	LDB	T1,[POINT 1,INTRBK+3,34];GET REASON FOR INTERRUPT
	SKIPN	T1
	EXIT	1,		;NOT ^C SO EXIT, NOT CLEARING JOB
	OUTSTR	[ASCIZ/
?CANT ^C WHILE SATS ARE BEING WRITTEN
/]
	MOVE	T1,INTRBK+2	;GET PC OF TRAP
	MOVEM	T1,INTPC	;SAVE
	SETZM	INTRBK+2	;CLEAR TRAP PC
	SETZM	INTRBK+3	;CLEAR CLASS & WHY BITS
	POP	P,T1		;RESTORE T1
	JRSTF	INTPC		;RETURN
;ERROR MESSAGES

HELP:	OUTSTR	[ASCIZ/
?GOT EOF ON LPT
/]
	JRST	QUIT
SYNTERR:	OUTSTR	[ASCIZ/
?SYNTAX ERROR. TRY AGAIN
/]
	JRST	GETDRV

TOMANY:	OUTSTR	[ASCIZ/
?CANT HAVE MORE THAN 8 DRIVES IN ONE STRUCTURE
/]
	JRST	GETDRV

STRBER:	OUTSTR	[ASCIZ/
?ERROR READING SAT.SYS RIB
/]
	JRST	QUIT

CMPLAN:	OUTSTR	[ASCIZ/
?BAD FORMAT UNIT CHANGE POINTER IN RIB OF SAT.SYS
-REBUILD 'STR' !!!!
/]
	JRST	QUIT

SATERR:	OUTSTR	[ASCIZ/
?INPUT ERROR READING SAT.SYS
/]


LPTERR:	OUTSTR	[ASCIZ/
?CANT INIT LPT
/]
	JRST	QUIT

LPTOER:	OUTSTR	[ASCIZ/
?ERROR ON OUTPUT TO LPT
/]
	JRST	QUIT

OUTERR:	OUTSTR	[ASCIZ/
?ERROR RE-WRITING SATS ONTO DSK - THE 'STR' SHOULD BE REBUILT!!!
/]
	JRST	QUIT

NOCORE:	OUTSTR	[ASCIZ/
?NO MORE CORE
/]
	JRST	QUIT

NOTSAT:	OUTSTR	[ASCIZ/
?HOME BLOCK POINTER TO SAT.SYS RIB WRONG - REBUILD 'STR'
/]
	JRST	QUIT

AYAY:	OUTSTR	[ASCIZ/
?NO DRIVES!
/]
	JRST	GETDRV

WRNSTR:	OUTSTR	[ASCIZ/
?DRIVE NOT IN GIVEN STR
/]
	JRST	GETSTR

HOMERD:	OUTSTR	[ASCIZ/
?INPUT ERROR READING 2ND. HOME BLOCK - REBUILD 'STR'!!!

/]
	JRST	QUIT

HOMERR:	OUTSTR	[ASCIZ/
?NOT A HOME BLOCK WHEN EXPECTED - CALL SYSTEMS GROUP
/]
	JRST	QUIT


OHDEAR:	OUTSTR	[ASCIZ/
?NOW HAVE A -VE FBN!! - CALL THE SYSTEMS GROUP & DO A DCORE
/]
	JRST	QUIT

NOTP1:	OUTSTR	[ASCIZ/
CANNOT RUN UNLESS PROJECT 1

/]
INPERR:	OUTSTR	[ASCIZ/
?ERROR READING A SPECIFIED BLOCK OF A FILE
/]
	JRST	QUIT

RIBERR:	OUTSTR	[ASCIZ/
?RIB ERROR FOR RIB OF SAT.SYS OR MFD - REBUILD 'STR'!!!
/]
	JRST	QUIT


ERROR:	OUTSTR	[ASCIZ/
?EOF AND BLOCK FBN OF FILE NOT FOUND
/]
	JRST	QUIT

INTERR:	OUTSTR	[ASCIZ/
?CANT INIT DRIVE
/]
	JRST	QUIT

ZERPPN:	OUTSTR	[ASCIZ/
?MFDPPN IS ZERO
/]
	JRST	QUIT


EXTERR:	OUTSTR	[ASCIZ/
?ERROR READING EXTENDED RIB
/]
	JRST	QUIT

NEGSIZ:	OUTSTR	[ASCIZ/
?RIBSIZ IS -VE
/]
	JRST	QUIT
ASTRST:	BLOCK 1
BLKCLS:	BLOCK 1
BPCLAD:	BLOCK 1
BPCLCT:	BLOCK 1
CDUMP:	BLOCK 1
CHBASE:	BLOCK 1
CLSBEF:	BLOCK 1
DRVCNT:	BLOCK 1
FLAG:	BLOCK 1
FRECNT:	BLOCK 1
HGHUNI:	BLOCK 1
INTPC:	BLOCK 1
LINCNT:	BLOCK 1
LNKSAV:	BLOCK 1
LSTCNT:	BLOCK 1
LSTRST:	BLOCK 1
MAXSIZ:	BLOCK 1
MFDPPN:	BLOCK 1
MULCNT:	BLOCK 1
NAME:	BLOCK 1
NAMLOC:	BLOCK	1
EXT:	BLOCK 1
SATCNT:	BLOCK 1
SAVE:	BLOCK 1
SAVE1:	BLOCK 1
SAVE2:	BLOCK 1
SAVE3:	BLOCK 1
STAOUR:	BLOCK 1
STRNAM:	BLOCK 1

PDLBLK:	BLOCK 200
PDLBK2:	BLOCK 50

BUFHOM:	BLOCK 200
ST%ADD:	BLOCK 200
SATRIB:	BLOCK 200
UN%CHN:	BLOCK 10
UN%NAM:	BLOCK 10
UN%WPS:	BLOCK 10
ST%BEL:	BLOCK 10
ST%ON:	BLOCK 10
SATBAS:	BLOCK 10
SATNUM:	BLOCK 10
UN%CPS:	BLOCK 10


TMPBUF:	BLOCK 200

OUTBUF:	BLOCK 3
LAB:	0
	0

LABO:	-200,,TMPBUF-1
	0
MNTST:	0
	0
	0
	0

INTRBK:	4,,INTRTN		;# OF ARGS & ADD OF INT ROUTINE
	0,,2			;BIT 34 FOR ^C
	0			;PC OF TRAP
	0			;CLASS,,WHY
QUIT:	SETZM	.JBINT		;ENABLE ^C INTERRUPT AGAIN
	CALLI	12
	END	ST