Google
 

Trailing-Edge - PDP-10 Archives - AP-4178E-RM - swskit-sources/filadr.mac
There are 2 other files named filadr.mac in the archive. Click here to see a list.
	TITLE	FILADR	TYPES OUT ADDRESSES A FILE IS USING


;WRITTEN BY DAVID I. BELL AT DIGITAL IN MARLBORO.
;THIS PROGRAM WILL TYPE OUT THE ADDRESSES OF EACH PAGE OF A FILE
;WHICH IS IN USE, AND ALSO THE PAGES USED BY THE INDEX BLOCKS.
;THE PROGRAM CAN ALSO CORRELATE THE ADDRESSES WITH THE ONES
;RECORDED IN THE BAT BLOCKS.  IT ALSO CAN LIST THE ADDRESSES IN
;THE BAT BLOCKS ALONE.


	SEARCH	MACSYM,MONSYM	;GET SYMBOLS
	SALL			;NICE LOOKING MACROS



;ACCUMULATORS:

	F=0			;FLAGS
	T1=1			;TEMPORARY AC'S
	T2=2
	T3=3
	T4=4
	I=5			;AOBJN POINTER FOR SUPER INDEX BLOCK
	A=6			;ADDRESS OF AN INDEX BLOCK IN CORE
	U=7			;LOGICAL UNIT NUMBER IN A STRUCTURE
	X=10			;ONLY FOR LUUO'S USE
	P=17			;STACK




;DEFAULT PARAMETERS:


	TXTLEN==^D100		;SIZE OF COMMAND BUFFERS
	PDLSIZ==30		;SIZE OF PUSHDOWN STACK
	MXUNIT==^D20		;NUMBER OF UNITS WE CAN HANDLE
	STGADR==77,,-1		;MASK FOR DISK ADDRESS IN A WORD
	DSKBIT==10,,0		;BIT SOMETIMES INCLUDED IN DISK ADDRESSES
	PAGI=10000		;ADDRESS OF INDEX BLOCK
	PAGSI=11000		;ADDRESS OF SUPER INDEX BLOCK
	BAT==12000		;ADDRESS TO READ IN FIRST BAT BLOCK
	BAT2==12200		;ADDRESS TO READ IN SECOND BAT BLOCK
	DATA=12400		;FIRST FREE LOCATION
;FLAGS:


	FR.BB1==1		;PRIMARY BAT BLOCK IS BAD
	FR.BB2==2		;SECONDARY BAT BLOCK IS BAD
	FR.BBI==4		;BAT BLOCKS DO NOT AGREE WITH EACH OTHER
	FR.ADR==10		;ADDRESSES ARE TO BE TYPED FOR FILES



;MACROS AND OPDEFS:



	OPDEF	PJRST	[JRST]		;PUSHJ/POPJ
	OPDEF	TYPE	[1B8]		;LUUO TO DO A SOUT
	OPDEF	OCTOUT	[2B8]		;LUUO FOR OCTAL OUTPUT
	OPDEF	DECOUT	[4B8]		;LUUO FOR DECIMAL OUTPUT



	DEFINE	AA(NAME,DATA),<		;;MACRO FOR COMMAND TABLES
	XWD	[ASCIZ/NAME/],DATA
>



	DEFINE	TEXT(STRING),<		;;MACRO FOR ASCIZ TEXT
	XLIST
	ASCIZ	@STRING@
	LIST
>



	DEFINE	ERROR(TEXT),<		;;MACRO FOR ERRORS
	JRST	[MOVEI	T1,[ASCIZ/
? TEXT/]
		PSOUT
		JRST	LOSFIN]
>
;DEFINITIONS ASSOCIATED WITH BAT BLOCKS:



;BLOCK NUMBERS:

	BATAD1==^D2		;UNIT ADDRESS OF PRIMARY BAT BLOCK
	BATAD2==^D11		;UNIT ADDRESS OF SECONDARY BAT BLOCK


;OFFSETS IN A BLOCK:

	BT.NAM==0		;NAME OF BLOCK - SIXBIT /BAT/
	BT.ADR==1		;<- FREE WORDS>,,ADDRESS OF FIRST PAIR
	BT.MAP==2		;DATA RECORDED BY MAPPING PROGRAMS
	BT.CNT==3		;NUMBER OF PAIRS ADDED BY MONITOR
	BT.FRE==4		;FIRST PAIR OF WORDS
	BT.COD==176		;SPECIAL CODE - 606060
	BT.BLK==177		;THIS BLOCK NUMBER - 2 OR 11


;FIELDS IN THE WORD BT.MAP:

	BT%NBB==777000,,0	;NUMBER OF BAD BLOCKS FOUND BY MAP PROGRAM
	BT%NBR==777,,0		;NUMBER OF BAD REGIONS FOUND BY PROGRAM


;FIELDS IN FIRST WORD OF EACH PAIR OF ERROR WORDS:

	BT%NEW==40000		;THIS IS A NEW FORMAT PAIR OF WORDS
	BT%CNT==777000,,0	;ONE LESS THAN THE NUMBER OF CONSEQUTIVE
				;BAD BLOCKS IN THIS REGION


;FIELDS IN SECOND WORD OF EACH PAIR OF ERROR WORDS:

	BT%VER==700000,,0	;VERSION NUMBER IF BT%NEW IS SET
	BT%ADR==777,,-1		;UNIT ADDRESS OF FIRST BAD BLOCK
				;IN THIS REGION
	BT%AD2==777777		;UNIT ADDRESS IF BT%NEW IS OFF


;OTHER DEFINITIONS:

	BT$HDR==6		;NUMBER OF WORDS USED IN HEADERS
	BT$COD==606060		;SPECIAL CODE IN WORD 176
	SUBTTL	COMMAND SCANNER AND INITIALIZATION




START:	MOVEI	F,FR.ADR	;SET TO TYPE ADDRESSES BY DEFAULT
	MOVE	T1,[PUSHJ P,LUUO]	;GET INSTRUCTION
	MOVEM	T1,.JB41##	;AND SET UP FOR LUUOS
	SETZM	WIDTH		;CLEAR WIDTH ARGUMENT
	MOVEI	T1,.FHSLF	;GET READY
	RPCAP			;READ MY CAPABILITIES
	TXNN	T3,SC%WHL+SC%OPR	;CAN I RUN THIS PROGRAM?
	JRST	NOPOWR		;NO, GO COMPLAIN


REEN:	RESET			;CLEAR EVERYTHING
	MOVE	P,[IOWD PDLSIZ,PDL]	;SET UP A STACK
	SETZM	JFN		;CLEAR INPUT JFN
	SETZM	JFNOUT		;CLEAR OUTPUT JFN ALSO


NEWCMD:	MOVEI	T1,CMDBLK	;POINT TO COMMAND BLOCK
	MOVEI	T2,[FLDDB. .CMINI]	;INITIALIZATION FUNCTION
	PUSHJ	P,COMMND	;GO DO IT
	MOVEM	P,SAVEP		;SAVE STACK FOR REPARSING


NEWPAR:	MOVE	P,SAVEP		;RESTORE THE STACK
	MOVEI	T1,CMDBLK	;POINT TO THE COMMAND BLOCK
	MOVEI	T2,[FLDDB. (.CMKEY,,CMDTAB)]	;POINT TO COMMAND TABLE
	PUSHJ	P,COMMND	;READ IT
	MOVE	T2,(T2)		;GET ADDRESS OF ROUTINE
	PUSHJ	P,(T2)		;CALL IT
	SKIPE	T1,JFN		;INPUT FILES STILL OPEN?
	RLJFN			;YES, CLOSE THEM
	SETZM	JFN		;AND CLEAR WORD
	JRST	NEWCMD		;AND GET A NEW COMMAND
;TABLE OF COMMANDS:



CMDTAB:	CMDLEN,,CMDLEN			;HEADER
	AA	ADDRESS,CMDADR		;ADDRESS COMMAND
	AA	BAT-BLOCKS,CMDBAT	;TYPE OUT THE BAT BLOCKS
	AA	EXIT,CMDXIT		;EXIT COMMAND
	AA	FILE,CMDFIL		;GIVE ADDRESSES OF FILE
	AA	HELP,CMDHLP		;TYPE HELP MESSAGE
	AA	WIDTH,CMDWID		;SET WIDTH OF OUTPUT

	CMDLEN==.-CMDTAB-1		;NUMBER OF COMMANDS
	SUBTTL	THE SIMPLE COMMANDS



;EXIT FROM PROGRAM.  "EXIT" COMMAND.


CMDXIT:	MOVEI	T2,[ASCIZ/FROM PROGRAM/]	;GET NOISE
	PUSHJ	P,NOISE		;EAT NOISE WORDS
	PUSHJ	P,CONFRM	;THEN CONFIRM THE COMMAND
	HALTF			;QUIT FOR NOW
	POPJ	P,		;RETURN FOR A NEW COMMAND




;SET THE WIDTH OF THE OUTPUT.  THE "WIDTH" COMMAND.



CMDWID:	MOVEI	T2,[ASCIZ/OF OUTPUT IS/]	;GET NOISE
	PUSHJ	P,NOISE		;DO NOISE
	MOVEI	T2,[FLDDB. (.CMKEY,,WIDTAB,,<DEFAULT>)]	;GET READY
	PUSHJ	P,COMMND	;READ KEYWORD
	MOVE	T4,(T2)		;GET VALUE
	PUSHJ	P,CONFRM	;CONFIRM THE LINE
	HRRZM	T4,WIDTH	;SAVE VALUE
	POPJ	P,		;AND RETURN



WIDTAB:	WIDLEN,,WIDLEN		;NUMBER OF ENTRIES
	AA	DEFAULT,0	;DEFAULT
	AA	NARROW,3	;NARROW
	AA	WIDE,7		;WIDE

	WIDLEN==.-WIDTAB-1	;NUMBER OF ENTRIES
;SET MODE OF OUTPUT, WITH OR WITHOUT THE ADDRESSES BEING TYPED.
;THE "ADDRESS" COMMAND.


CMDADR:	MOVEI	T2,[ASCIZ/LISTING MODE IS/]	;GET NOISE
	PUSHJ	P,NOISE		;PARSE IT
	MOVEI	T2,[FLDDB. (.CMKEY,,ADRTAB,,<ON>)]	;GET READY
	PUSHJ	P,COMMND	;READ KEYWORD
	MOVE	T4,(T2)		;SAVE ADDRESS OF INSTRUCTION
	PUSHJ	P,CONFRM	;COMFIRM THE LINE
	XCT	(T4)		;TURN FLAG ON OR OFF
	POPJ	P,		;AND RETURN



ADRTAB:	ADRLEN,,ADRLEN		;NUMBER OF ENTRIES
	AA	OFF,[ANDCMI F,FR.ADR]	;ADDRESS LISTING IS OFF
	AA	ON,[IORI F,FR.ADR]	;ADDRESS LISTING IS ON

	ADRLEN==.-ADRTAB-1	;NUMBER OF KEYWORDS





;THE "HELP" COMMAND.



CMDHLP:	PUSHJ	P,CONFRM	;CONFIRM THE LINE
	HRROI	T1,HLPTXT	;POINT TO HELP MESSAGE
	PSOUT			;TYPE IT
	POPJ	P,		;AND RETURN
HLPTXT:	TEXT	<
This program can either dump out the addresses of the disk which a
file is using, or dump out the addresses which are marked in the BAT
blocks of a structure.  Commands are:

  ADDRESS arg	Set whether or not to type the addresses of the used
		pages, or just plus signs.  The arg is one of ON or
		OFF.  The default is ON.

  BAT-BLOCKS str	Type out information about the BAT blocks on
		the indicated structure.  The disk addresses pointed
		to by the BAT blocks is also listed.

  EXIT		Leave the program

  FILE spec	Process the given file spec, making a list of the
		addresses the file is using.

  HELP		Type this message.

  WIDTH arg	Set how many addresses to print on a line.  The
		argument is one of WIDE, NARROW, or DEFAULT.


Notes:

1.	WHEEL or OPERATOR capability is required to run this program
	as it does DSKOPs to read the index blocks.

2.	All disk addresses will seem to be at least as large as the
	value 10,,000000.  This bit can be ignored, it is simply a
	flag meaning that the address is a disk address.

3.	Numbers in the output followed by a period are decimal numbers,
	all other numbers are octal.

4.	Any gaps in the output (such as non-printed sections or page
	numbers) indicate that an area exists which has no pages in use.

5.	Any asterisks indicate that the indicated page is recorded
	in the BAT blocks for that structure.

6.	Addresses in the BAT blocks are listed as A,B where A is the
	address of the start of a bad region, and B is the number
	of consequtive bad blocks.

7.	The headers for the BAT block typeout mean the following:
	UNIT	  The logical unit within the structure
	BLOCKS	  The number of blocks found to be bad on the unit
	REGIONS	  The number of regions which are bad.  This number is
		  how many entries are made in the BAT block
	COUNT	  The number of regions which were found bad by the
		  monitor.  This will not include regions originally
		  found by the mapping program

>
	SUBTTL	COMMAND TO PRINT OUT ADDRESSES A FILE USES



;THIS COMMAND DOES THE MAIN ACTION.  WE READ ALL OF THE
;INDEX BLOCKS OF THE FILE, AND OUTPUT THE DISK ADDRESSES OF
;EACH PAGE OF THE FILE, AND ALSO OF THE INDEX BLOCK.


CMDFIL:	MOVEI	T2,[ASCIZ/TO PROCESS IS/]	;GET NOISE
	PUSHJ	P,NOISE		;PARSE IT
	MOVX	T2,GJ%IFG+GJ%OLD	;GET FLAGS
	MOVEM	T2,JFNBLK	;AND SAVE THEM IN GTJFN BLOCK
	MOVEI	T2,[FLDDB. (.CMFIL)]	;SET UP
	PUSHJ	P,COMMND	;READ FILE SPEC
	MOVEM	T2,JFN		;SAVE THE JFN
	MOVEI	T2,[ASCIZ/OUTPUT TO/]	;GET NOISE
	PUSHJ	P,NOISE		;PARSE IT
	MOVEI	T2,[FLDDB. (.CMOFI,,,,<TTY:>)]	;GET READY
	PUSHJ	P,COMMND	;READ OUTPUT SPEC
	MOVEM	T2,JFNOUT	;AND SAVE OUTPUT JFN
	PUSHJ	P,CONFRM	;CONFIRM THE LINE
	PUSHJ	P,SETOUT	;SET UP THE OUTPUT JFN FOR WRITING
	SETOM	JFNBTS		;INITIALIZE GNJFN BITS


FILLOP:	PUSHJ	P,DOFILE	;GO PROCESS THIS FILE
	MOVE	T1,JFN		;GET JFN AND FLAG BITS
	GNJFN			;ADVANCE TO NEXT FILE
	  ERJMP	FILDON		;ERROR, GO SEE IF DONE
	MOVEM	T1,JFNBTS	;SAVE THE GNJFN FLAGS
	MOVE	T1,JFNOUT	;GET OUTPUT JFN
	MOVEI	T2,14		;GET A CONTROL-L
	BOUT			;AND OUTPUT IT
	JRST	FILLOP		;AND GO DO IT


FILDON:	CAIE	T1,GNJFX1	;ALL DONE?
	  JRST	LOSE		;NO, HE LOSES
	SETZM	JFN		;GNJFN CLEARED THE JFN
FILCLS:	MOVE	T1,JFNOUT	;GET OUTPUT JFN
	CLOSF			;CLOSE THE FILE
	  ERJMP	LOSE		;FAILED
	SETZM	JFNOUT		;CLEAR OUTPUT JFN
	HRROI	T1,CRLF		;GET READY
	PSOUT			;TYPE A CRLF TO SAY WE'RE DONE
	POPJ	P,		;AND RETURN
	SUBTTL	ROUTINE TO PROCESS A FILE




;HERE TO PROCESS A PARTICULAR FILE.



DOFILE:	PUSHJ	P,SETIN		;SET UP TO HANDLE THIS FILE
	MOVE	T1,JFNBTS	;GET BITS FROM GNJFN
	TLNE	T1,(GN%STR)	;DID STRUCTURE CHANGE?
	PUSHJ	P,DOBAT		;YES, INITIALIZE BATS FOR THIS STRUCTURE
	TYPE	[ASCIZ/
	Disk addresses for file /]	;OUTPUT STRING
	HRRZ	T2,JFN		;GET INPUT JFN
	MOVE	T3,[1B2+1B5+1B8+1B11+1B14+JS%PAF]	;GET FLAGS
	JFNS			;TYPE STRING
	TYPE	CRLF		;THEN TYPE A CRLF
	MOVE	T1,FDB+.FBCTL	;GET FLAG BITS FOR THIS FILE
	TXNE	T1,FB%LNG	;IS IT A LONG FILE?
	JRST	DOLONG		;YES, GO HANDLE IT
	MOVE	T1,FDB+.FBADR	;NO, GET INDEX BLOCK ADDRESS
	MOVEM	T1,PAGSI	;SAVE IN A FAKE SUPER INDEX BLOCK
	MOVSI	I,-1		;SET UP AOBJN WORD OF 1
	JRST	SECLOP		;AND JOIN LOOP FOR LONG FILE


DOLONG:	MOVE	T1,FDB+.FBADR	;GET ADDRESS OF SUPER INDEX BLOCK
	MOVEI	A,PAGSI		;AND ADDRESS WHERE IT IS READ TO
	PUSHJ	P,READ		;READ IT IN
	PUSHJ	P,SCAN		;GET INFORMATION ABOUT IT
	PUSHJ	P,CHKSUM	;AND ITS CHECKSUM
	MOVE	T1,JFNOUT	;GET OUTPUT JFN READY
	TYPE	[ASCIZ/
Super Index Block address: /]	;TYPE TEXT
	OCTOUT	FDB+.FBADR	;TYPE ADDRESS
	MOVE	T1,FDB+.FBADR	;GET ADDRESS AGAIN
	SETZ	T2,		;WANT NO TYPEOUT UNLESS IN BAT BLOCK
	PUSHJ	P,BADSRC	;LOOK FOR IT
	TYPE	[ASCIZ/    Sections used: /]	;TYPE MORE
	DECOUT	PAGTOT		;OUTPUT TOTAL NUMBER OF SECTIONS
	TYPE	CRLF		;AND THEN A CRLF
	AOSE	PAGCHK		;SEE IF HAS A CHECKSUM ERROR
	TYPE	[ASCIZ/Index block has a checksum error
/]				;YES, SAY SO
	AOS	ALLPAG		;ADD TO NUMBER OF PAGES TOTAL
	MOVSI	I,-1000		;SET UP AOBJN POINTER FOR WHOLE PAGE
;HERE TO LOOP OVER ALL WORDS IN A SUPER INDEX BLOCK, TO READ IN
;AND PROCESS EACH REGULAR INDEX BLOCK.


SECLOP:	MOVE	T1,PAGSI(I)	;GET NEXT POSSIBLE INDEX BLOCK ADDRESS
	AND	T1,[STGADR]	;IGNORE CHECKSUM PARTS
	JUMPE	T1,SECNXT	;IF NONE, JUST GO TO NEXT ONE
	MOVEM	T1,PAGIDX	;SAVE ADDRESS OF INDEX BLOCK
	AOS	ALLPAG		;ADD TO TOTAL NUMBER OF PAGES FOR FILE
	MOVEI	A,PAGI		;POINT TO AREA TO READ IT INTO
	PUSHJ	P,READ		;READ IT IN
	PUSHJ	P,SCAN		;GET INFORMATION
	PUSHJ	P,CHKSUM	;AND CHECKSUM
	PUSHJ	P,LIST		;THEN OUTPUT INFORMATION ON IT
	MOVE	T1,PAGTOT	;GET TOTAL PAGES DESCRIBED
	ADDM	T1,ALLPAG	;ADD TO GRAND TOTAL
	ADDM	T1,ALLDAT	;AND TO DATA PAGE TOTAL
SECNXT:	AOBJN	I,SECLOP	;LOOP OVER ALL SECTIONS



;HERE WHEN ALL DONE, TO OUTPUT TOTALS AND CLOSE FILES.


	MOVE	T1,JFNOUT	;GET READY FOR LAST BIT OF OUTPUT
	TYPE	[ASCIZ/
Total pages used: /]		;MORE TEXT
	DECOUT	ALLPAG		;OUTPUT NUMBER OF DATA PAGES
	TYPE	[ASCIZ/    Data pages: /]	;MORE
	DECOUT	ALLDAT		;OUTPUT NUMBER OF DATA PAGES
	TYPE	CRLF		;THEN TYPE A CRLF
	SKIPN	ALLBAD		;ANY BAD BLOCKS?
	POPJ	P,		;NO, RETURN
	TYPE	[ASCIZ/Pages listed in the BAT blocks (marked with "*"): /]
	DECOUT	ALLBAD		;OUTPUT NUMBER
	TYPE	CRLF		;ANOTHER CRLF
	POPJ	P,		;THEN RETURN
	SUBTTL	ROUTINE TO PRINT OUT THE ADDRESSES OF A PAGE TABLE




;CALLED TO PRINT THE ADDRESSES POINTED TO BY THE INDEX BLOCK WHOSE
;ADDRESS IS IN AC A.  ALSO PRINTED IS SOME HEADER INFORMATION OF USE.




LIST:	TYPE	[ASCIZ/
Section: /]			;TYPE SOME TEXT
	MOVEI	T3,(I)		;GET SECTION NUMBER READY
	OCTOUT	T3		;OUTPUT IT
	TYPE	[ASCIZ/     Index block address: /]	;MORE TEXT
	OCTOUT	PAGIDX		;OUTPUT PAGE NUMBER
	MOVE	T1,PAGIDX	;GET ADDRESS AGAIN
	SETZ	T2,		;NO OUTPUT IF NOT BAD
	PUSHJ	P,BADSRC	;LOOK FOR IT IN BAD BLOCKS
	TYPE	[ASCIZ/     Pages in use: /]	;TYPE MORE
	DECOUT	PAGTOT		;OUTPUT TOTAL NUMBER OF PAGES
	TYPE	CRLF		;OUTPUT A CRLF
	AOSE	PAGCHK		;SEE IF CHECKSUM WAS -1
	TYPE	[ASCIZ/Index block has a checksum error
/]				;IF NOT, TELL HIM
	SKIPGE	T2,PAGMIN	;ANY PAGES TO BE TYPED?
	POPJ	P,		;NO, THEN ARE ALL DONE
;HERE TO ACTUALLY LOOP OVER EACH WORD IN THE INDEX BLOCK:


LISTLP:	TDNE	T2,PAGMSK	;TIME FOR A NEW LINE?
	JRST	LISTPG		;NO, JUST GO TYPE THE PAGE NUMBER
	TYPE	CRLF		;START WITH A CRLF
	OCTOUT	3,PAGMIN	;PRINT THE PAGE NUMBER
	MOVEI	T2,"/"		;GET A SLASH
	BOUT			;PRINT THAT
	TRNN	F,FR.ADR	;TYPING ADDRESSES?
	TYPE	[ASCIZ/   /]	;NO, THEN SPACE OVER SOME
	MOVE	T2,PAGMIN	;GET PAGE NUMBER AGAIN

LISTPG:	ADDI	T2,(A)		;POINT INTO INDEX BLOCK
	MOVE	T4,(T2)		;GET WORD FROM INDEX BLOCK
	AND	T4,[STGADR]	;KEEP ONLY THE DISK ADDRESS
	JUMPE	T4,LISTNO	;JUMP IF THERE IS NO ADDRESS
	TRNN	F,FR.ADR	;TYPING ADDRESSES?
	JRST	LISTPL		;NO, GO DO OTHER WAY
	OCTOUT	^D11,T4		;YES, DO SO
	MOVE	T1,T4		;GET ADDRESS AGAIN
	MOVEI	T2," "		;GET A SPACE IN CASE IT ISN'T BAD
	PUSHJ	P,BADSRC	;LOOK FOR ADDRESS IN BAD BLOCK
	JRST	LISTDN		;AND CONTINUE

LISTPL:	MOVE	T1,T4		;GET ADDRESS OF PAGE
	MOVEI	T2,"+"		;GET A PLUS IN CASE IT IS GOOD PAGE
	PUSHJ	P,BADSRC	;LOOK FOR THE PAGE
	JRST	LISTDN		;AND CONTINUE

LISTNO:	TRNE	F,FR.ADR	;ARE WE TYPING ADDRESSES?
	TYPE	[ASCIZ/      --    /]	;YES, TYPE SOME DASHES
	MOVEI	T2,"-"		;GET A DASH READY
	TRNN	F,FR.ADR	;NOT GIVING THE ADDRESSES?
	BOUT			;YES, THEN OUTPUT IT


LISTDN:	AOS	T2,PAGMIN	;INCREMENT TO NEXT PAGE
	CAMG	T2,PAGMAX	;DID ALL WE SHOULD YET?
	JRST	LISTLP		;NO, GO DO MORE
	TYPE	CRLF		;FINISH WITH A CRLF
	POPJ	P,		;RETURN
	SUBTTL	COMMAND TO PRINT THE BAT BLOCKS




;THIS IS THE COMMAND TO LIST THE BAT BLOCKS.  THE ADDRESSES OF EACH
;REGION IS TYPED, ALONG WITH USEFUL STATISTICS.



CMDBAT:	MOVEI	T2,[ASCIZ/OF STRUCTURE/]	;GET READY
	PUSHJ	P,NOISE		;READ NOISE
	MOVEI	T2,[FLDDB. (.CMDEV,,,,<PS>)]	;WANT TO INPUT DEVICE
	PUSHJ	P,COMMND	;DO IT
	MOVEM	T2,DEVICE	;SAVE THE DEVICE DESIGNATOR
	MOVEI	T2,[ASCIZ/LISTED TO FILE/]	;GET READY
	PUSHJ	P,NOISE		;PARSE IT MORE
	MOVEI	T2,[FLDDB. (.CMOFI,,,,<TTY:>)]	;GET READY
	PUSHJ	P,COMMND	;READ OUTPUT SPEC
	MOVEM	T2,JFNOUT	;SAVE THE OUTPUT JFN
	PUSHJ	P,CONFRM	;THEN CONFIRM THE LINE
	MOVE	T1,DEVICE	;GET DEVICE DESIGNATOR
	DVCHR			;GET INFORMATION ABOUT IT
	  ERJMP	LOSE		;CAN'T
	LDB	T1,[POINTR T2,DV%TYP]	;GET DEVICE TYPE
	CAIE	T1,.DVDSK	;IS IT A DISK?
	  JRST	NOTDSK		;NO, COMPLAIN
	HRROI	T1,STR		;POINT TO STORAGE
	MOVE	T2,DEVICE	;GET DEVICE DESIGNATOR
	DEVST			;CONVERT IT TO A STRING
	  ERJMP	LOSE		;FAILED
	PUSHJ	P,SETOUT	;GET OUTPUT FILE READY TO WRITE
	PUSHJ	P,DOBAT		;READ IN ALL BAT BLOCK INFO
	TYPE	[ASCIZ/
BAT blocks for structure /]	;TYPE SOME TEXT
	TYPE	STR		;THEN THE STRUCTURE NAME
	TYPE	[ASCIZ/:
Units in structure: /]		;MORE
	DECOUT	PACKS		;OUTPUT IT
	TYPE	[ASCIZ/

Unit   Blocks   Regions   Count           Status

/]
	SETZ	U,		;GET SET FOR LOOP OVER ALL UNITS
;HERE FOR LOOP OVER ALL UNITS IN A STRUCTURE, LISTING THE INFORMATION
;WE KNOW FOR EACH UNIT.


UNITLP:	OCTOUT	2,U		;PRINT THE UNIT NUMBER
	DECOUT	^D9,UNITBB(U)	;TYPE THE NUMBER OF BAD BLOCKS
	DECOUT	^D8,UNITBR(U)	;AND THE NUMBER OF BAD REGIONS
	DECOUT	^D8,UNITCT(U)	;AND NUMBER OF MONITOR ADDED REGIONS
	TYPE	[ASCIZ/      /]	;THEN SPACE OVER
	MOVE	T1,UNITFL(U)	;GET THE FLAGS FOR THIS STRUCTURE
	PUSHJ	P,BATSTS	;TYPE THE STATUS
	TYPE	CRLF		;THEN A CRLF
	ADDI	U,1		;MOVE TO NEXT UNIT
	CAMGE	U,PACKS		;DONE WITH ALL UNITS YET?
	JRST	UNITLP		;NO, GO DO NEXT ONE
	MOVEI	I,DATA		;POINT TO FIRST PAIR OF WORDS
	CAML	I,BADPTR	;ANY ADDRESSES TO TYPE?
	  JRST	FILCLS		;NO, GO CLOSE FILE AND RETURN
	TYPE	[ASCIZ/
Addresses marked in the BAT blocks:
/]				;TYPE MORE TEXT
	SETOM	PAGMIN		;AND INITIALIZE A COUNTER
	MOVEI	T1,3		;GET MASK TO BE USED
	MOVEM	T1,PAGMSK	;SET FOR 4 COLUMNS OF OUTPUT


PARLOP:	AOS	T1,PAGMIN	;INCREMENT COUNTER
	TDNN	T1,PAGMSK	;IS IT TIME FOR A NEW LINE?
	TYPE	CRLF		;YES, DO A CRLF FIRST
	MOVX	T2,DSKBIT	;GET THE BIT READY
	IOR	T2,0(I)		;ADD IN THE DISK ADDRESS
	OCTOUT	^D12,T2		;THEN TYPE IT
	MOVEI	T2,","		;GET A COMMA
	BOUT			;TYPE IT
	MOVE	T2,1(I)		;GET SECOND ADDRESS
	SUB	T2,0(I)		;SUBTRACT FIRST ADDRESS
	ADDI	T2,1		;ADD ONE TO GET SIZE
	MOVE	T3,[3,,^D8]	;GET READY FOR OUTPUT IN COLUMN OF 3
	NOUT			;DO IT
	JFCL			;STUPID ERROR
	ADDI	I,2		;MOVE POINTER TO NEXT PAIR
	CAMGE	I,BADPTR	;STILL MORE TO TYPE?
	JRST	PARLOP		;YES, LOOP MORE
	TYPE	CRLF		;FINISH WITH A CRLF
	JRST	FILCLS		;THEN GO CLOSE FILE AND RETURN
	SUBTTL	ROUTINE TO SET UP INPUT FILE




;CALLED TO MAKE SURE THAT THE INPUT FILE IS A DISK FILE, AND
;TO OBTAIN THE INFORMATION THAT WE WILL NEED LATER.





SETIN:	HRRZ	T1,JFN		;GET JFN
	DVCHR			;READ STATUS BITS
	LDB	T1,[POINTR T2,DV%TYP]	;GET DEVICE TYPE
	CAIE	T1,.DVDSK	;MAKE SURE THIS IS A DISK
	  JRST	NOTDSK		;IF NOT, ERROR
	HRRZ	T1,JFN		;GET JFN
	MOVSI	T2,.FBLWR+1	;GET NUMBER OF FDB WORDS
	MOVEI	T3,FDB		;POINT TO STORAGE
	GTFDB			;READ THE FILE'S FDB
	  ERJMP	LOSE		;CAN'T, THEN BOMB
	HRROI	T1,STR		;POINT TO STORAGE
	HRRZ	T2,JFN		;GET JFN OF FILE
	MOVE	T3,[FLD (.JSAOF,JS%DEV)]	;AND FLAGS
	JFNS			;STORE DEVICE NAME
	SETZ	T2,		;GET READY
	IDPB	T2,T1		;MAKE SURE IS ASCIZ
	HRROI	T1,STR		;POINT TO IT AGAIN
	STDEV			;GET THE DEVICE DESIGNATOR
	  ERJMP	LOSE		;FAILED
	MOVEM	T2,DEVICE	;SAVE IT
	SETZM	ALLPAG		;CLEAR TOTAL NUMBER OF PAGES
	SETZM	ALLDAT		;AND TOTAL NUMBER OF DATA PAGES
	SETZM	ALLBAD		;AND NUMBER OF BAD PAGES
	POPJ	P,		;THEN RETURN
	SUBTTL	ROUTINE TO SET UP OUTPUT FILE



;CALLED TO OPEN THE OUTPUT FILE FOR WRITING, AND TO DECIDE ON THE
;NUMBER OF COLUMNS IN THE OUTPUT.  IF THERE IS NO JFN YET IN USE,
;THEN WE WILL USE THE DEVICE OF TTY:.




SETOUT:	MOVE	T1,JFNOUT	;GET OUTPUT JFN READY
	MOVX	T2,OF%WR+7B5	;SET UP BYTE SIZE AND WRITE ACCESS
	OPENF			;OPEN IT
	  ERJMP	LOSE		;FAILED
	MOVEI	T1,77		;GET VALUE READY IN CASE NO ADDRESS MODE
	TRNE	F,FR.ADR	;WANTS NO ADDRESSES?
	SKIPE	T1,WIDTH	;OR HE SPECIFIED A WIDTH?
	JRST	SETWID		;YES, GO STORE IT
	MOVE	T1,JFNOUT	;GET JFN AGAIN
	DVCHR			;READ STATUS OF DEVICE
	LDB	T1,[POINTR T2,DV%TYP]	;GET DEVICE TYPE
	CAIE	T1,.DVTTY	;IS IT A TTY?
	JRST	SETBIG		;NO, THEN USE WIDE FORMAT
	MOVE	T1,JFNOUT	;GET READY
	MOVEI	T2,.MORLW	;GET READY TO READ WIDTH
	MTOPR			;DO IT
	CAIGE	T3,^D100	;IS TERMINAL WIDE ENOUGH?
	SKIPA	T1,[3]		;NO, THEN USE NARROW FORMAT
SETBIG:	MOVEI	T1,7		;OTHERWISE USE WIDE FORMAT
SETWID:	MOVEM	T1,PAGMSK	;SAVE AS MASK TO USE IN OUTPUT ROUTINE
	POPJ	P,		;RETURN
	SUBTTL	LUUO HANDLER




;HERE ON AN LUUO, TO TYPE OUT EITHER A STRING OR A DECIMAL OR OCTAL
;NUMBER.  EACH OF THESE FUNCTIONS IS A DIFFERENT LUUO.  ALL OUTPUT
;GOES TO THE JFN JFNOUT.  ERRORS IN THE NUMBER OUTPUT ARE IGNORED.





LUUO:	MOVE	X,.JBUUO##	;GET THE UUO
	TLNN	X,(TYPE)	;IS IT THE TYPE LUUO?
	JRST	LUUO1		;NO, GO ON
	MOVE	T1,JFNOUT	;SET UP OUTPUT JFN
	HRROI	T2,(X)		;POINT TO THE TEXT
	SETZ	T3,		;WANT TO OUTPUT ALL OF IT
	SOUT			;DO SO
	POPJ	P,		;THEN RETURN


LUUO1:	TLNN	X,(OCTOUT)	;WANT TO OUTPUT OCTAL NUMBER?
	JRST	LUUO2		;NO, WANTS DECIMAL
	MOVE	T2,(X)		;GET NUMBER TO TYPE
	MOVE	T1,JFNOUT	;SET UP OUTPUT JFN
	LDB	T3,[POINT 4,X,12]	;GET COLUMN WIDTH
	MOVSI	T3,<(NO%LFL)>(T3)	;PUT IN PROPER PLACE
	IORI	T3,^D8		;AND INSERT RADIX
	NOUT			;TYPE IT
	JFCL			;STUPID ERROR
	POPJ	P,		;THEN RETURN


LUUO2:	MOVE	T2,(X)		;GET NUMBER TO TYPE
	MOVE	T1,JFNOUT	;GET OUTPUT JFN READY
	LDB	T3,[POINT 4,X,12]	;GET COLUMN WIDTH
	MOVSI	T3,<(NO%LFL)>(T3)	;PUT IN PROPER PLACE
	IORI	T3,^D10		;AND INSERT RADIX
	NOUT			;OUTPUT IT
	JFCL			;STUPID ERROR
	MOVEI	T2,"."		;GET A PERIOD
	BOUT			;OUTPUT IT TO INDICATE DECIMAL NUMBER
CPOPJ:	POPJ	P,		;THEN RETURN


CRLF:	BYTE 	(7)15,12	;CRLF TEXT
	SUBTTL	ROUTINE TO READ IN AN INDEX BLOCK




;SIMPLE SUBROUTINE TO READ AN INDEX BLOCK INTO THE GIVEN ADDRESS.
;THE DISK ADDRESS OF THE INDEX BLOCK IS IN AC T1, AND THE ADDRESS
;TO WRITE THE DATA IS IN AC A.  NO RETURN IF AN ERROR ENCOUNTERED.



READ:	AND	T1,[DOP%RA]	;CLEAR NON-ADDRESS PART
	IOR	T1,[<FLD (.DOPSR,DOP%AT)>!DOP%SN]	;SET UP REST
	MOVEI	T3,(A)		;MOVE ADDRESS TO RIGHT AC
	MOVEI	T2,1000		;READ IN A WHOLE PAGE, NO FLAGS SET
	MOVE	T4,DEVICE	;GET DEVICE DESIGNATOR
	DSKOP			;READ THE PAGE
	  ERJMP	LOSE		;CAN'T DO IT
	POPJ	P,		;ALL DONE
	SUBTTL	ROUTINE TO SCAN INDEX BLOCK TO FIND OUT INFORMATION



;THIS ROUTINE IS CALLED TO OBTAIN THE FIRST AND LAST PAGE NUMBER
;TO BE PRINTED FOR THIS INDEX BLOCK.  ALSO OBTAINED IS THE NUMBER
;OF PAGES WHICH ARE USED ACCORDING TO THE INDEX BLOCK.  ADDRESS
;OF THE INDEX BLOCK IS IN AC A.





SCAN:	SETZM	PAGTOT		;CLEAR NUMBER OF PAGES USED
	SETOM	PAGMIN		;AND INITIALIZE MINIMUM PAGE NUMBER
	MOVSI	T1,-1000	;WANT TO SCAN WHOLE PAGE
	HRLI	A,T1		;SET UP FOR INDIRECT ADDRESS
	MOVE	T2,[STGADR]	;GET MASK READY

SCANLP:	TDNN	T2,@A		;IS THIS PAGE USED?
	JRST	SCANNX		;NO, GO ON
	HRRZM	T1,PAGMAX	;YES, SAVE AS HIGHEST PAGE SO FAR
	SKIPGE	PAGMIN		;ALREADY FOUND LOWEST PAGE?
	HRRZM	T1,PAGMIN	;NO, THEN SAVE IT
	AOS	PAGTOT		;BUMP NUMBER OF PAGES TOTAL
SCANNX:	AOBJN	T1,SCANLP	;LOOP OVER ALL PAGES
	MOVE	T1,PAGMSK	;GET MASK USED FOR THIS WIDTH
	ANDCAM	T1,PAGMIN	;ROUND FIRST PAGE DOWN TO NICE VALUE
	IORM	T1,PAGMAX	;ROUND LAST PAGE UP TO NICE VALUE TOO
	POPJ	P,		;THEN RETURN
	SUBTTL	ROUTINE TO CHECKSUM AN INDEX BLOCK



;ROUTINE TO COMPUTE THE CHECKSUM OF AN INDEX BLOCK.  THE ADDRESS IN
;OUR CORE OF THE INDEX BLOCK IS SUPPLIED IN AC A.  AN INDEX BLOCK
;CONTAINS THE CHECKSUM IN THE FIRST 9 BITS OF THE FIRST 4 WORDS.
;THE RIGHT 24 BITS OF EACH WORD IS THE DISK ADDRESS FOR THAT PAGE.
;ANY REMAINING BITS ARE NOT USED, AND DO NOT TAKE PART IN THE CHECKSUM.
;A GOOD CHECKSUM HAS THE VALUE OF -1.  THE COMPUTED CHECKSUM IS
;SAVED IN LOCATION PAGCHK.





CHKSUM:	MOVSI	T2,-4		;GET READY FOR A LOOP
	HRRI	T2,(A)		;OVER THE FIRST FOUR WORDS
	MOVE	T3,[POINT 9,T1]	;POINT TO PLACE CHECKSUM WILL GO

CHKGET:	LDB	T4,[POINT 9,(T2),8]	;GET A BYTE OF THE CHECKSUM
	IDPB	T4,T3		;STORE IT
	AOBJN	T2,CHKGET	;DO FOR ALL FOUR WORDS
	SETCA	T1,		;COMPLEMENT THE CHECKSUM
	JCRY0	.+1		;CLEAR CARRY FLAG
	MOVSI	T2,-1000	;GET READY TO LOOP OVER WHOLE PAGE
	HRLI	A,T2		;SETUP INDEX FIELD

CHKWRD:	MOVE	T3,@A		;GET NEXT WORD OF PAGE
	AND	T3,[EXP STGADR]	;KEEP ONLY THE DISK ADDRESS PART
	SKIPN	T3		;IS THERE ANY ADDRESS?
	MOVEI	T3,(T2)		;NO, THEN USE THE OFFSET INTO THE PAGE
	ADD	T1,T3		;ADD RESULT INTO CHECKSUM
	JCRY0	[AOJA T1,.+1]	;IF OVERFLOW, WRAP AROUND
	AOBJN	T2,CHKWRD	;LOOP OVER ALL WORDS IN THE PAGE
	MOVEM	T1,PAGCHK	;SAVE THE CHECKSUM FOR LATER
	POPJ	P,		;RETURN
	SUBTTL	ROUTINE TO COLLECT ALL DATA ON BAD BLOCKS




;THIS ROUTINE DOES ALL GOOD THINGS TO COLLECT A LIST OF THE BAD
;BLOCKS OF A STRUCTURE.  IT ALSO COLLECTS THE INFORMATION FOR
;EACH UNIT IN A STRUCTURE.  BEFORE CALLING, PUT THE ASCIZ STRUCTURE
;NAME IN LOCATION STR.  RETURNS WILL ALL DATA GOTTEN, READY TO
;SEARCH FOR BAD BLOCKS.




DOBAT:	PUSHJ	P,STRFND	;LOOK FOR ALL UNITS IN STRUCTURE
	MOVEI	T1,DATA		;POINT TO STORAGE
	MOVEM	T1,BADPTR	;AND INITIALIZE POINTER
	SETZ	U,		;GET SET FOR LOOP THROUGH ALL UNITS


DOBATL:	PUSHJ	P,GETBAT	;READ IN BOTH BATS FOR UNIT
	  SKIPA			;BOTH WERE BAD, SKIP NEXT STEP
	PUSHJ	P,SAVBAD	;GET BAD BLOCKS SAVED IN CORE
	MOVE	T1,BAT+BT.CNT	;GET COUND OF REGIONS MONITOR FOUND
	MOVEM	T1,UNITCT(U)	;SAVE FOR LATER
	MOVEM	F,UNITFL(U)	;SAVE FLAGS FOR LATER TOO
	MOVE	T1,UNITSZ(U)	;GET SIZE OF THIS UNIT
	ADDM	T1,UNITOF	;ADD TO OFFSET IN ADDRESSES
	ADDI	U,1		;MOVE UP A UNIT
	CAMGE	U,PACKS		;LOOKED AT ALL UNITS YET?
	JRST	DOBATL		;NO, KEEP LOOPING
	POPJ	P,		;ALL DONE, RETURN
	SUBTTL	ROUTINE TO SEARCH FOR A BAD BLOCK



;THIS ROUTINE IS CALLED WITH THE ADDRESS OF A BLOCK IN T1, AND
;A CHARACTER TO BE OUTPUT (NULL IF NONE)