Google
 

Trailing-Edge - PDP-10 Archives - tops10_tools_bb-fp64b-sb - 10,7/dskdmp/dskdmp.mac
There are 4 other files named dskdmp.mac in the archive. Click here to see a list.
	TITLE	DSKDMP--DUMP THE DISK DATA BASE FROM A CRASH FILE
	SUBTTL	DEFINITIONS

	SEARCH	Q,MACTEN,UUOSYM
	SALL

;ACCUMULATORS
	F=0			;FLAGS
	T1=1			;TEMPORARIES
	T2=2
	T3=3
	T4=4
	T5=5
	T6=6
	J=T6
	P1=10			;PRESERVED
	P2=11
	P3=12
	P4=13
	P5=14
	CNT=15			;COUNTER (TEMPORARY AC)
	LVL=16			;SFD LEVEL
	P=17			;STACK POINTER

;I/O CHANNELS
	DSK==1			;FOR READING EXE FILE
	LPT==2			;FOR DUMPING DATA BASE

;FLAGS IN THE LEFT HALF OF AC F
	L.BHED==1B0		;SET IF HEADER TYPED FOR BIT TABLE CHECK
	L.MLST==1B3		;SET IF USER WANTS TO SPY ON MONITOR
	L.ACHK==1B4		;SET IF ONLY WANT TO ADDRESS CHECK
	L.NAME==1B7		;HAVE NAME
	L.PROJ==1B8		;HAVE PROJECT NUMBER
	L.ANY==1B9		;SAW ANYTHING
	L.NOPP==1B10		;DON'T TYPE DATA FOR THIS PPN
	L.NONM==1B11		;DON'T TYPE THIS NMB/AT
	L.OTTY==1B12		;OUTPUT TO TTY
	L.RDSK==1B13		;READING A CRASH FROM DISK

;MACROS

	DEFINE	MONWRD(INST)<
	JRST	[PUSHJ P,DOINST
		JRST .+1
		JRST .+2
		INST]
>
	DEFINE ERROR(TEXT)
<	JRST [	OUTSTR	[ASCIZ	/?TEXT
/]
		JRST	BEGIN]>

;CONDITIONAL ASSEMBLY:
	ND	CSL,0		;NON-0 FOR CSL FEATURES
	SUBTTL	MONITOR-DEPENDENT DEFINITIONS
UNINAM=0			;DEVICE NAME
UNILOG=1			;PACK NAME
UNISYS=3			;PNTR TO NEXT UNIT
UNIHCT=10			;HARD ERR COUNT
UNISCT=11			;SORT ERR COUNT
UNIECT=34			;ERROR-RETRY COUNT
UNIHNG=35			;HUNG COUNT
UNISTS=36			;STATUS
UNIBPU=43			;BLOCKS PER UNIT (NON-0 IF UNIT EXISTS)
UNIRCV=63			;RETRIES ON HUNG DEV
UNI2ND=72			;POINTER TO 2ND PORT
UNITIM==73			;TIMER

IFNDEF LN.BUF,<LN.BUF==200>	;LENGTH OF DISK BUFFER
IFNDEF NBCSHE,<NBCSHE==^D25>	;NUMBER OF PAGES TO KEEP IN CORE
	SUBTTL	VARIABLES

	BEGLOW==.
TTCLST:	BLOCK	1		;# CHUNKS,,POINTER TO 1ST CHUNK
TTFREE:	BLOCK	1		;POINTER TO FREE CHUNKS
TTFREN:	BLOCK	1		;NUMBER OF FREE CHUNKS
LINPTR:	BLOCK	1		;-#LINES,,ADR OF LINTAB
CKADR:	BLOCK	1		;.TTCLST<0,18>
LWRDCN:	BLOCK	1		;.TTCLST<18,18>*4
LTBSIZ:	BLOCK	1		;SIZE OF BIT TABLE IN WORDS
CORNUM:	BLOCK	1		;NUMBER OF BLOCKS
SYSPPB:	BLOCK	1		;START OF CORE
SPPB:	BLOCK	1		;HAS LH(SYSPPB) IN ITS RH
SYSCOR:	BLOCK	1		;START OF FREE LIST
SYSDOR:	BLOCK	1		;DORMANT ACCESS TABLES
WRDCNT:	BLOCK	1		;.CORNUM*8
TABSIZ:	BLOCK	1		;SIZE OF BIT TABLE IN WORDS
CORPNT:	BLOCK	1		;POINTER TO AREA IN CORE WHERE INFO IS
BITTAB:	BLOCK	1		;POINTER TO BIT TABLE OF 8 WORD BLOCKS
DIRPNT:	BLOCK	1		;POINTER TO IN-CORE COPY OF FILE DIRECTORY
COROFF:	BLOCK	1		;OFFSET BETWEEN FILE ADDRESSES AND CORE ADDRESSES
LCRPNT:	BLOCK	1		;POINTER TO LINE DATA
LINTAB:	BLOCK	1		;POINTER TO TABLE OF LINE ADDRESSES
LBITTB:	BLOCK	1		;POINTER TO BIT TABLE FOR CHUNKS
LCOROF:	BLOCK	1		;TTY OFFSET BETWEEN FILE AND CORE
;WORK AREA
DBLOCK:	BLOCK	200		;WHERE DISK BLOCKS ARE READ INTO
TEMP:	BLOCK	1		;TEMPORARY VARIABLE
LPTOUT:	BLOCK	3		;LPT OUTPUT BUFFER HEADER
FRECNT:	BLOCK	1		;COUNT OF FREE BLOCKS
DORCNT:	BLOCK	1		;COUNT OF DORMANT ACCESS TABLES
TEMP1:	BLOCK	1		;ANOTHER TEMPORARY
LSTBLK:	BLOCK	1		;DISK BLOCK CURRENTLY IN DBLOCK
ONELIN:	BLOCK	1		;SINGLE LINE TO REPORT ON
NAME:	BLOCK	1		;PARTICULAR NAME (DSK DATA)
EXT:	BLOCK	1		;EXT WE'RE LOOKING FOR
PROJ:	BLOCK	1		;THE PROJECT NUMBER
PROG:	BLOCK	1		;PROGRAMMER NUMBER
;***DO NOT SEPERATE THE FOLLOWING LABELS!
IDEV:	BLOCK	3		;INPUT DEVICE OPEN BLOCK
IFILE:	BLOCK	4		;INPUT LOOKUP BLOCK
ODEV:	BLOCK	3		;OUTPUT DEVICE OPEN BLOCK
OFILE:	BLOCK	4		;OUTPUT DEVICE ENTER BLOCK
;***END OF DO NOT SEPARATE
PLIST:	BLOCK	60		;STACK
SAVET1:	BLOCK	2
SAVET3:	BLOCK	2
INST:	0
DATA:	0
.CPTOS:	BLOCK	1
.CPMAP:	BLOCK	1
EXEDIR:	BLOCK	LN.BUF		;SPACE FOR EXE DIRECTORY
DCACHE:	BLOCK	NBCSHE		;INCORE CACHE FOR CRASH FILE
DSKFLG:	BLOCK	1		;FLAG (AND MAX SIZE) OF DISK INPUT FILE
	ENDLOW==.-1		;END OF NORMAL VARIABLES
PNTR:	0,,DATA
DSKIOW:	IOWD	LN.BUF,0	;IOWD FOR READING CRASH FILE, ADDR FILLED IN
	0			;END OF LIST
	SUBTTL	INITIALIZATION

BEGIN:	JFCL			;NO CCL
	START	60,PLIST	;SET UP STACK
	SETZB	F,BEGLOW	;CLEAR FLAGS AND START OF CORE AREA
	MOVE	T1,[BEGLOW,,BEGLOW+1]	;BLT POINTER
	BLT	T1,ENDLOW	;TO END OF LOW SEG
	MOVX	T1,%CNSIZ	;SIZE OF THE MONITOR
	GETTAB	T1,		;GET IT
	  MOVEI	T1,-1		;MAKE SURE SPY FAILS
	SPY	T1,		;MAP MONITOR
	  ERROR	<Spy failed>	;IF DON'T HAVE SPY PRIV'S, CANT PEEK EITHER
	HLRZ	T1,.JBSA##	;GET INITIAL .JBFF
	MOVEM	T1,.JBFF##	;AND RESET IT
	SETZM	IFILE		;SET UP DEFAULTS
	MOVSI	T1,'EXE'
	MOVEM	T1,IFILE+1
	SETZM	IFILE+2
	MOVE	T1,[10,,1]
	MOVEM	T1,IFILE+3
	MOVEI	T1,17
	MOVEM	T1,IDEV
	MOVSI	T1,'ALL'
	MOVEM	T1,IDEV+1
	SETZM	ODEV
	MOVSI	T1,'TTY'
	MOVEM	T1,ODEV+1
	MOVSI	T1,LPTOUT
	MOVEM	T1,ODEV+2
	PUSHJ	P,SCAN		;GET COMMAND LINE
	OPEN	LPT,ODEV	;GET THE OUTPUT DEVICE
	  ERROR	<Cannot OPEN output device>
	MOVS	T1,ODEV+1
	CAIN	T1,'TTY'	;IF OUTPUT IS TO TTY
	TXOA	F,L.OTTY	; LIGHT A BIT IN F
	TXZ	F,L.OTTY
	SKIPN	IFILE		;NAME TYPED?
	TXOA	F,L.MLST	;NO, PEEK AT RUNNING MONITOR
	TXOA	F,L.RDSK	;READ FROM DISK
	TXZ	F,L.RDSK
	TXNE	F,L.MLST	;DID HE SAY /M?
	JRST	DODUMP		;YES--DON'T OPEN INPUT DEVICE.
	OPEN	DSK,IDEV	;OPEN THE INPUT DEVICE!
	  ERROR	<Can't open input device>
	LOOKUP	DSK,IFILE	;FIND THE FILE!
	  ERROR	<Can't lookup input file>
	PUSHJ	P,CPYEXE	;READ DIRECTORY
DODUMP:	PUSHJ	P,DUMP		;DUMP DATA BASE
	JRST	BEGIN		;NO

DOINST:	DMOVEM	T1,SAVET1
	DMOVEM	T3,SAVET3
	MOVE	T2,(P)
	MOVE	T2,2(T2)
	MOVEM	T2,INST
	SETZ	T3,
	LDB	T1,[POINT 9,T2,8]	;OP CODE
	CAIE	T1,(LDB_-11)
	CAIN	T1,(ILDB_-11)
	SKIPA	T2,(T2)
	JRST	NOTBYT
	CAIN	T1,(ILDB_-11)
	IBP	T2
	TLZ	T2,77
	HLLM	T2,PNTR
	MOVSI	T1,000740
	AND	T1,INST
	IOR	T1,[LDB PNTR]
	EXCH	T1,INST
	SETO	T3,
	LDB	T1,[POINT 4,(T1),17]
	CAIA

NOTBYT:	LDB	T1,[POINT 4,INST,17]	;INDEX
	CAIL	T1,T1
	CAILE	T1,T4
	CAIA
	ADDI	T1,SAVET1-T1
	MOVE	T1,(T1)
	ADDI	T1,(T2)
	PUSHJ	P,PEEKA		;T1=LOC TO READ, ANSWER IN T1
	MOVE	T2,INST
	TLNE	T2,20
	PUSHJ	P,PEEKA		;INDIRECT, ONE MORE TIME (BUT NO RECURSION)
	MOVEM	T1,DATA
	JUMPL	T3,DOIT
	MOVEI	T1,DATA
	DPB	T1,[POINT 23,INST,35]
DOIT:	DMOVE	T1,SAVET1
	DMOVE	T3,SAVET3
	XCT	INST
	POPJ	P,
	AOS	(P)
	POPJ	P,
PEEKA:	TXNE	F,L.RDSK	;SEE IF DISK MODE
	PJRST	DSKA		;YES--PEEK AT THE DISK
	TLZ	T1,-1		;CLEAR JUNK
	CAIGE	T1,400000	;MONITOR HIGH SEG ADDRESS?
	SKIPA	T1,400000(T1)	;YES--GET FROM CORE
PEEKA1:	PEEK	T1,		;NO--GET FROM MONITOR
	POPJ	P,

DSKA:	TLZ	T1,-1		;CLEAR JUNK
	CAIGE	T1,340000	;ADDRESS IN MONITOR LOW SEG
	JRST	DSKA8		;YES, JUST GET MONITOR LOW SEG VALUE
	PUSH	P,T4		;GET A WORKING AC
	MOVE	T4,T1		;SAVE ADDRESS IN T4
	ANDI	T1,777		;ISOLATE OFFSET IN PAGE
	PUSH	P,T1		;SAVE THIS
	LSH	T4,-^D9		;CONVERT TO PAGE NUMBER
	MOVE	T1,.CPTOS	;THIS IS KIND OF A KLUDGE BUT THERE ARE NO
	CAME	T1,.CPMAP	; CONVIENENT BITS TO REMEMBER TYPE OF PAGING
	TLO	T4,600000	;KL PAGING
	TRNN	T4,400000_-^D9	;ADDRESS IN MONITOR HIGH SEG?
	JRST	DSKA2		;NO, PER-PROCESS MAPPING
	TLNN	T4,200000	;KL PAGING?
	ROT	T4,-1		;NO, KI PAGING - MAP SLOTS ARE HALF WORDS
	HRRZ	T1,T4		;WORD WITHIN THE MAP
	ADD	T1,.CPMAP	;ADDRESS OF MAP SLOT ENTRY
	JRST	DSKA7		;GO GET MAP SLOT ENTRY
DSKA2:	MOVSI	T1,(J)		;JOB NUMBER TO LH
	HRRI	T1,.GTUPM	;NEED JBTUPM FOR THIS JOB
	GETTAB	T1,		;GET VALUE
	  JRST	DSKA3		;FAILED, RETURN ZERO
	HRRZS	T1		;KEEP JUST PAGE NUMBER
	JUMPN	T1,DSKA5	;IF THERE, CONTINUE
DSKA3:	POP	P,(P)		;FLUSH JUNK
	POP	P,T4		;RESTORE T4
DSKA4:	MOVEI	T1,0		;RETURN ZERO TO CALLER
	POPJ	P,		;  AND RETURN
DSKA5:	LSH	T1,^D9		;MAKE PAGE NUMBER AN ADDRESS
	TLNE	T4,200000	;KL PAGING?
	JRST	DSKA6		;YES, PAGE NUMBER IS OFFSET INTO THE MAP
	ROT	T4,-1		;DIVIDE BY 2 PUTTING REMAINDER IN THE SIGN BIT
	ADDI	T4,220		;PP STUFF STARTS AT 400 IN THE MAP
DSKA6:	ADDI	T1,(T4)		;POINT TO PER-PROCESS STUFF IN THE UPMP
DSKA7:	PUSHJ	P,DSKA8		;GET THE MAP SLOT FOR THIS ADDRESS
	SKIPL	T4		;SKIP IF MAPPING THROUGH RH
	MOVSS	T1		;MAPPING THROUGH LH, REVERSE
	TLNE	T4,200000	;KL PAGING?
	TLNN	T1,700000	;YES, ACCESS ALLOWED?
	CAIA			;KI PAGING OR ACCESS NOT ALLOWED
	TRO	T1,400000	;INDICATE ACCESS ALLOWED
	TRNN	T1,400000	;PAGE HAVE ACCESS ALLOWED ON?
	JRST	DSKA3		;NO, RETURN ZERO
	ANDI	T1,17777	;KEEP JUST 13 BIT PAGE NUMBER
	LSH	T1,^D9		;MAKE IT AN ADDRESS
	ADD	T1,0(P)		;ADD IN OFFSET IN PAGE
	POP	P,(P)		;FLUSH JUNK
	POP	P,T4		;RESTORE T4
DSKA8:	PUSH	P,T2		;SAVE T2
	CAML	T1,DSKFLG	;COMPARE TO AMOUNT IN FILE
	JRST	[POP	P,T2	;RESTORE T2
		 JRST	DSKA4]	;RETURN ZERO
	PUSH	P,T3		;SAVE T1 WORK REGISTER
	JUMPE	T1,DSKA9	;DON'T RELOCATE 0 (NEED TO READ EXE DIRECTORY)
	PUSHJ	P,RELEXE	;RELOCATE ADDRESS TO DISK PAGE ADDRESS
	  JRST	[POP P,T3	;ADDRESS NOT IN FILE, RESTORE ACS
		POP P,T2
		JRST DSKA4]	;AND RETURN 0
DSKA9:	IDIVI	T1,LN.BUF	;SPLIT INTO BLOCK AND WORD
	PUSH	P,T2		;OFFSET FOR WORD IN BUFFER
	MOVSI	T2,-NBCSHE	;SEARCH THE CACHE FOR THIS DISK BLOCK
	HLRZ	T3,DCACHE(T2)	;FETCH BLOCK DESCRIBED
	CAIE	T3,(T1)		;IS THIS IT
	AOBJN	T2,.-2		;NO, KEEP LOOKING
	JUMPL	T2,DSKARD	;FOUND ONE, UPDATE LEAST RECENTLY USED
	HRLM	T1,DCACHE+NBCSHE-1 ;STORE BLOCK NUMBER IN LAST (OLDEST)
	HRRZ	T2,DCACHE+NBCSHE-1 ;WHERE DATA IS TO BE READ
	SOS	T2		;-1 FOR THE IOWD
	HRRM	T2,DSKIOW	;STORE ADDR
	MOVEI	T2,NBCSHE-1	;INDEX WHERE READ (FOUND)
IFN LN.BUF-200,<IMULI T1,LN.BUF/200>
IFN LN.BUF-<LN.BUF/200>*200,<PRINTX LN.BUF MUST BE MULT OF 200>
	USETI	DSK,1(T1)	;NO--POSITION FILE
	IN	DSK,DSKIOW
	JRST	DSKARD		;READ OK
	PUTSTR	LPT,<
% Disk read error >
	GETSTS	DSK,T1
	PUTOCT	LPT,T1
DSKARD:	HRRZS	T2		;ISOLATE POSITION IN TABLE
	CAIG	T2,NBCSHE/3	;DON'T RIPPLE TABLE IF CLOSE TO FRONT ALREADY
	JRST	DSKAR1		;THIS MIGHT NOT BE TOO GOOD WITH SMALL "NBCSHE"
	PUSH	P,DCACHE(T2)	;SAVE DESIRED ENTRY
	MOVE	T3,DCACHE-1(T2)	;COMPRESS TABLE SO LEAST USED IS LAST
	MOVEM	T3,DCACHE(T2)	;MOVE UP ENTRIES BELOW ONE FOUND
	SOJG	T2,.-2		;SO NEW ONE CAN BE FOUND QUICKLY LATER
	POP	P,DCACHE(T2)	;PUT SAVED ENTRY AT THE FRONT
DSKAR1:	POP	P,T3		;GET WORD OFFSET FOR DATA ITEM
	ADD	T3,DCACHE(T2)	;FIND WORD IN BUFFER
	MOVE	T1,(T3)		;FETCH IT
	POP	P,T3		;RESTORE WORK AC
	POP	P,T2		;RESTORE CALLERS AC
	POPJ	P,		;RETURN WITH DATA ITEM IN T1
;SUBROUTINES TO INITIALIZE AND DEAL WITH EXE DIRECTORY

CPYEXE:	HLRE	T1,IFILE+3	;LENGTH OF THE FILE
	SKIPL	T1		;IF POSTIVE, MEANS NUMBER OF BLOCKS
	LSH	T1,7		;CONVERT TO WORDS
	MOVMS	T1		;LENGTH OF THE FILE IN WORDS
	MOVEM	T1,DSKFLG	;SAVE FOR SANITY CHECKING
	MOVSI	T1,-NBCSHE	;PRIME THE INCORE CACHE POINTERS
	MOVE	T2,.JBREL	;FIRST AVAILABLE LOC
	HRROM	T2,DCACHE(T1)	;STORE -1,,BUFFER ADDRESS
	ADDI	T2,LN.BUF	;STEP TO NEXT DISK BUFFER
	AOBJN	T1,.-2		;STORE ALL ENTRIES
	CAMG	T2,.JBREL	;NEED TO EXPAND
	JRST	.+3		;NO
	CORE	T2,		;GET THE EXTRA CORE
	  ERROR	<Not enough CORE>
	MOVEI	T1,0		;CAUSE THE EXE DIRECTORY TO BE READ
	PUSHJ	P,DSKA		;GET FIRST WORD OF DIRECTORY
	HLRZS	T1
	CAIE	T1,1776		;AN EXE FILE?
	ERROR	<Not an EXE file>
	HRLZ	T1,DCACHE	;*** "KNOW" WHERE DSKA READ IT
	HRRI	T1,EXEDIR	;PLACE TO SAVE IT
	BLT	T1,EXEDIR+LN.BUF-1 ;MOVE AS MUCH AS WAS READ
	HRRZ	T1,EXEDIR	;FETCH DIRECTORY SIZE
	CAIL	T1,LN.BUF	;DID WE GET ALL OF IT
	ERROR	(EXE Directory too complex, try making LN.BUF larger)
	MOVE	T1,EXEDIR-1(T1)	;FETCH LAST DESCRIPTOR WORD
	LDB	T2,[POINT 9,T1,8] ;GET REPEATER COUNT
	ADDI	T2,1(T1)	;FIRST PAGE NOT IN FILE
	LSH	T2,^D9		;FIRST ADDRESS NOT IN FILE
	MOVEM	T2,DSKFLG	;RESET MAXIMUM ADDRESS
	MONWRD	<MOVE T2,410>
	MONWRD	<MOVE T1,<777777>&<%CNBCP>(T2)>
	MONWRD	<MOVE T1,<(<-1,,0>&<%CNBCP>)>(T1)>
	LSH	T1,1		;*2 FOR GETTAB
	MONWRD	<MOVE T1,<777777>&<%CCTOS>(T2)>
	MONWRD	<MOVE T1,<(<-1,,0>&<%CCTOS>)>(T1)> ;GET ADDRESS OF EPT FOR BOOT CPU
	MOVEM	T1,.CPTOS	;SAVE FOR LATER
	MONWRD	<MOVE T1,<%FTERR>&<777777>(T2)>
	MONWRD	<MOVE T1,<(<-1,,0>&<%FTERR>)>(T1)>
	TRNN	T1,<F%KLP&777777> ;KI OR KL PAGING?
	TDZA	T1,T1		;KI PAGING, EPT AND MAP ARE THE SAME PAGE
	MOVEI	T1,1000		;KL PAGING, MAP IS THE NEXT PAGE AFTER THE EPT
	ADD	T1,.CPTOS	;ADDRESS OF THE MAP
	MOVEM	T1,.CPMAP	;SAVE THAT FOR DSKA
	POPJ	P,		;AND RETURN
RELEXE:	PUSH	P,T4		;SAVE A WORKING AC
	IDIVI	T1,1000		;SPLIT INTO PAGE AND OFFSET
	PUSH	P,T2		;SAVE OFFSET
	HRRZ	T2,EXEDIR	;FETCH NUMBER OF WORDS IN DIRECTORY
	MOVNI	T2,-1(T2)	;DON'T COUNT HEADER WORD
	HRLZS	T2		; = AOBJN
RELEX1:	HRRZ	T3,EXEDIR+2(T2)	;GET CORE ADDRESS FROM DESCRIPTOR
	CAILE	T3,(T1)		;PASS THE ONE WE WANT
	JRST	RELEX3		;YES, WORD NOT IN FILE
	LDB	T4,[POINT 9,EXEDIR+2(T2),8] ;GET REPEATER
	ADDI	T4,1(T3)	;FIRST PAGE NOT IN POINTER
	CAIL	T1,(T4)		;PAGE IN THIS POINTER AT ALL
	JRST	RELEX2		;NO, GET ANOTHER POINTER
	SUBI	T1,(T3)		;HOW FAR INTO THE POINTER
	ADD	T1,EXEDIR+1(T2)	;HOW FAR INTO THE FILE PROPER
	TLZ	T1,-1		;KEEP IT REASONABLE ( FLAGS BITS )
	LSH	T1,^D9		;TO A PAGE ADDRESS IN THE FILE
	ADDM	T1,(P)		;INCLUDE THE OFFSET WANTED
	AOS	-2(P)		;GIVE GOOD RETURN
	JRST	RELEX3		;AND RETURN
RELEX2:	AOBJN	T2,.+1		;ADJUST FOR DOUBLE WORD ENTRIES
	AOBJN	T2,RELEX1	;LOOK AT NEXT POINTER
RELEX3:	POP	P,T1		;RETURN VALUE
	POP	P,T4		;RESTORE WORKING AC
	POPJ	P,		;RETURN
	SUBTTL	SCAN SUBROUTINES

SCAN:	OUTCHR	["*"]		;PROMPT
	MOVEI	P1,IDEV		;POINT TO INPUT DEVICE
	CALL	ASKFIL		;GET SPEC FROM USER
	TXO	F,L.ANY		;CANT USE SHORT FORM
	CLEAR			;CLEAR TO EOL
	POPJ	P,		;RETURN
ASKFIL:	ASKSXB			;GET A SIXBIT WORD
	CAIN	T2,32
	EXIT			;EXIT IF ^Z TYPED
	JUMPE	T3,NOTEXT	;IF NO CHARS READ, NOT A FILE NAME
	CAIE	T2,":"		;DELIMITER A COLON?
	JRST	NOTDEV		;NO--NOT A DEVICE
	MOVEM	T1,1(P1)	;YES--STORE DEVICE
	JRST	ASKFIL		;LOOP BACK
NOTDEV:	MOVEM	T1,3(P1)	;MUST BE A FILE NAME
	CAIE	T2,"."		;DELIMITER A .?
	JRST	NOTEXT		;NO
	ASKSXB			;YES--GET IT
	HLLZM	T1,4(P1)	;AND STORE IT
NOTEXT:	CAIE	T2,"["		;PPN FOLLOW?
	POPJ	P,		;NO
	ASKOCT			;YES--GET PROJECT
	HRLZ	P2,T1		;STORE PROJECT
	CAIE	T2,","		;DELIMITER A COMMA?
	POPJ	P,		;NO
	ASKOCT			;YES--GET PROGRAMMER
	HRR	P2,T1		;AND STORE IT
	CAIE	T2,"]"		;DELIMITER A ]?
	POPJ	P,		;NO
	MOVEM	P2,6(P1)	;STORE PPN
	POPJ	P,		;AND RETURN
	SUBTTL	ROUTINE TO DUMP DATA BASE FROM CORE

DUMP:	PUSH	P,.JBFF##	;SAVE .JBFF SO CAN RECLAIM BUFFERS
	SETOVR	(\LPT,LPTOUT)	;TELL MACROS WHERE BUFFER HEADER IS
	PUSHJ	P,PUTHDR	;PUT FILE HEADER
	PUSHJ	P,PUTDSK	;PUT DISK STUFF
	CLOSE	LPT,		;CLOSE THE FILE
	POP	P,.JBFF##	;RESET FIRST FREE
	POPJ	P,		;AND RETURN
	SUBTTL	FILE HEADER

PUTHDR:	PUTSTR	LPT,<input file=>
	TXNE	F,L.MLST	;WANT TO SPY?
	PUTSTR	LPT,<running monitor>
	TXNE	F,L.MLST	;SAME QUESTION
	JRST	TYPPHD		;YES
	PUTSXB	LPT,IFILE
	PUTCHR	LPT,["."]
	HLLZ	T1,IFILE+1	;GET EXTENSION
	PUTSXB	LPT,T1
TYPPHD:	PUTSTR	LPT,< on >
	DATE	T1,		;GET TODAY'S DATE
	CALL	PUTDAT		;STICK IT IN OUTPUT BUFFER
	PUTSTR	LPT,< at >
	MSTIME	T1,		;GET TIME IN MILLISECONDS
	IDIVI	T1,^D60000	;CONVERT TO MINUTES
	CALL	PUTTIM		;STICK THAT IN BUFFER TOO
	PUTLF	LPT,
	POPJ	P,		;RETURN
	SUBTTL	DISK REPORTING

PUTDSK:	PUTSTR	LPT,<
UNIT	PACK	UNISTS	HNG/TIM/RCV	UNISCT	UNIHCT	UNIECT	ADDRESS
>
	MONWRD	<MOVE P4,410>	;ADDRESS OF NUMTAB
	MONWRD	<MOVE P4,16(P4)> ;ADDRESS OF LEVELD TAB
	MONWRD	<HLRZ P4,7(P4)>	;SYSUNI
UNILOP:	PUSHJ	P,PUTUNI	;TELL ALL ABOUT THIS UNIT
	MONWRD	<SKIPN UNI2ND(P4)>
	JRST	UNILP1		;NOT DUAL-PORTED
	PUSH	P,P4		;DUAL-PORTED - PRINT 2ND PATH
	MONWRD	<SKIPE UNILOG(P4)>
	TLO	P4,-1		;PRINT NAME OF 2ND PORT AS "......"
	MONWRD	<HRR P4,UNI2ND(P4)>
	PUSHJ	P,PUTUNI
	POP	P,P4
UNILP1:	MONWRD	<HLRZ P4,UNISYS(P4)>	;NEXT UNIT
	JUMPN	P4,UNILOP	;DO IT
	PUTLF	LPT,
	POPJ	P,

PUTUNI:	MONWRD	<SKIPN UNIBPU(P4)>	;DOES UNIT EXIST?
	POPJ	P,		;NO, DONT TYPE IT
	MONWRD	<MOVE T1,UNISTS(P4)>
	CAIN	T1,13		;IF THE UDB IS UNINTERESTING
	MONWRD	<SKIPE UNILOG(P4)>	; DONT TYPE IT
	JRST	PUTUNX
	MONWRD	<SKIPN UNIHCT(P4)>
	MONWRD	<SKIPE UNISCT(P4)>
	JRST	PUTUNX
	POPJ	P,
PUTUNX:	MONWRD	<MOVE T1,UNINAM(P4)>
	PUTSXB	LPT,T1
	PUTSTR	LPT,<	>
	JUMPL	P4,[MOVE T1,[SIXBIT /....../]
		    JRST .+2]
	MONWRD	<MOVE T1,UNILOG(P4)>
	PUTSXB	LPT,T1
	PUTSTR	LPT,<	>
	MONWRD	<MOVE T1,UNISTS(P4)>
	PUTOCT	LPT,T1
	PUTSTR	LPT,<	>
	MONWRD	<MOVE T1,UNIHNG(P4)>
	PUSHJ	P,PUTHWD
	PUTSTR	LPT,</>
	MONWRD	<MOVE T1,UNITIM(P4)>
	SKIPGE	T1
	MOVNI	T1,1
	PUTDEC	LPT,T1
	PUTSTR	LPT,</>
	MONWRD	<MOVE T1,UNIRCV(P4)>
	PUTDEC	LPT,T1
	PUTSTR	LPT,<	>
	MONWRD	<MOVE T1,UNISCT(P4)>
	PUSHJ	P,PUTHWD
	PUTSTR	LPT,<	>
	MONWRD	<MOVE T1,UNIHCT(P4)>
	PUSHJ	P,PUTHWD
	PUTSTR	LPT,<	>
	MONWRD	<SKIPLE UNIECT(P4)>
	PUTSTR	LPT,<P>
	MONWRD	<MOVE T1,UNIECT(P4)>
	TLZ	T1,400000
	PUTOCT	LPT,T1
	PUTSTR	LPT,<	>
	MOVE	T1,P4
	SUB	T1,COROFF
	HRRZS	T1
	PUTOCT	LPT,T1
	PUTSTR	LPT,<
>
	POPJ	P,
	SUBTTL	DUMP SUBROUTINES

PUTKYS:	PUTSTR	LPT,< KNO=>
	PUSHJ	P,REPKNO	;REPORT THE KNO WORD
	PUTSTR	LPT,< YES=>
	MOVE	T4,0(T1)	;GET KNO WORD
	MOVE	T2,1(T1)	;GET YES WORD
	MOVEI	CNT,^D36	;HOW MANY BITS
KYSLOP:	SETZB	T1,T3		;CLEAR SOME WORDS
	LSHC	T1,1		;MOVE A BIT OF YES WORD INTO T1
	LSHC	T3,1		;AND THE CORRESPONDING BIT OF KNOW WORD INTO T3
	JUMPE	T3,DNTKNO	;IF KNO BIT IS 0, DON'T KNOW
	MOVEI	T5,"N"		;ASSUME NO.
	JUMPE	T1,DPCHAR	;IF YES BIT IS 0, GOOD
	MOVEI	T5,"Y"		;WRONG. USE A Y
	JRST	DPCHAR		;PUT IT IN THE BUFFER
DNTKNO:	MOVEI	T5,"0"		;ASSUME IS 0
	JUMPE	T1,DPCHAR	;GOOD GUESS?
	MOVEI	T5,"1"		;NO.
DPCHAR:	PUTCHR	LPT,T5
	CALL	PTSPC		;TYPE A SPACE AFTER EACH NINE
	SOJG	CNT,KYSLOP	;REPEAT FOR 36 BITS
	POPJ	P,		;RETURN NOW

REPADR:	SUB	T1,COROFF
	PUTSTR	LPT,< ADDRESS=>
	PUTOCT	LPT,T1
	POPJ	P,

REPKNO:	MOVE	T3,0(T1)	;GET KNO BITS IN T3
	MOVEI	CNT,^D36	;36 BITS
KNOLOP:	LSHC	T2,1		;GET A BIT IN T2
	MOVEI	T4,"N"		;ASSUME NO
	TRNE	T2,1		;RIGHT?
	MOVEI	T4,"Y"		;WRONG
	PUTCHR	LPT,T4
	CALL	PTSPC		;TYPE A SPACE AFTER EACH NINE
	SOJG	CNT,KNOLOP	;REPEAT
	POPJ	P,		;RETURN

PUTPRV:	LSHC	T1,-^D9		;LEFT JUSTIFY IN T2
	MOVEI	CNT,3		;3 DIGITS
PRVLOP:	SETZ	T1,		;CLEAR DIGIT
	LSHC	T1,3		;PICK UP AN OCTAL DIGIT
	ADDI	T1,"0"		;CONVERT TO ASCII
	PUTCHR	LPT,T1		;PRINT IT
	SOJG	CNT,PRVLOP	;REPEAT TWICE MORE
	POPJ	P,		;RETURN

PTSPC:	CAIE	CNT,^D10	;TYPED 9?
	CAIN	CNT,^D19	;OR 18?
	JRST	PSPC		;YES
	CAIE	CNT,^D28	;OR 27?
	POPJ	P,		;NO
PSPC:	PUTCHR	LPT,[" "]
	POPJ	P,

PUTPTR:
PUTHWD:	HLRZ	T2,T1		;GET LH(T1)
	PUTOCT	LPT,T2
	PUTSTR	LPT,<,,>
	HRRZ	T2,T1		;AND RH(T1)
	PUTOCT	LPT,T2
	POPJ	P,

PUTTSP:	JUMPE	LVL,PUTTL1	;NOTHING EXTRA AT LEVEL 0
	MOVE	T4,[ASCII /    /]
	MOVE	T1,LVL
PUTTLP:	PUTSTR	LPT,,T4
	SOJGE	T1,PUTTLP	;REPEAT FOR EACH LEVEL
PUTTL1:	POPJ	P,		;RETURN


PUTTIM:	IDIVI	T1,^D60		;GET HOURS AND MINUTES
	PUTDEC	LPT,T1		;HOURS FIRST
	PUTCHR	LPT,[":"]
	IDIVI	T2,^D10		;SPLIT MINUTES INTO 2 DIGITS
	PUTDEC	LPT,T2
	PUTDEC	LPT,T3
	POPJ	P,		;RETURN

	DEFINE	LISTL(ARG),<
	IRP	ARG,<ASCII	/ARG/>>

MONTAB:	LISTL	<Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec>

PUTDAT:	IDIVI	T1,^D31		;GET DAY NUMBER-1
	AOS	T2		;GET DAY NUMBER
	PUTDEC	LPT,T2		;TYPE IT
	PUTCHR	LPT,["-"]
	IDIVI	T1,^D12
	PUTSTR	LPT,,MONTAB(T2)
	PUTCHR	LPT,["-"]
	ADDI	T1,^D1964
	PUTDEC	LPT,T1
	POPJ	P,
SPYDSK:	MOVE	P4,400410	;GET ADDRESS OF .GTSLF
	MOVE	P3,400000+.GTLVD(P4)	;GET ADDRESS OF LEVEL-D TABLE
	MOVE	T1,400000+11(P3)	;GET NUMBER OF BLOCKS
	MOVEM	T1,CORNUM	;STORE FOR LATER
	LSH	T1,3		;CONVERT TO WORDS
	MOVEM	T1,WRDCNT	;STORE FOR LATER
	MOVE	T2,.JBFF##	;GET CURRENT FIRST FREE
	MOVEM	T2,CORPNT	;STORE.
	ADDB	T1,.JBFF##	;UPDATE FIRST FREE
	SOS	T1		;POINT TO LAST WORD
	CAMG	T1,.JBREL##	;HAVE THE CORE?
	JRST	HCORE7		;YES
	CORE	T1,		;NO--GET IT
	  ERROR	<No core to copy monitor's data base>
HCORE7:	HLRZ	T1,400000+7(P3)	;GET START OF DATA BASE
HCORE8:	HLRZ	T2,400000+3(T1)	;POINT TO NEXT UDB
	CAIG	T1,(T2)		;IF NEXT IS A LOWER ADDRESS,
	JRST	HCORE9		; THE 1ST UDB WAS CREATED AFTER SYSTEM STARTED
	MOVE	T1,T2		;SO START AT LOWER UDB
	JRST	HCORE8
HCORE9:	MOVEM	T1,SPPB		;STORE FOR LATER
	HRLI	T1,400000(T1)	;PUT IN LH(T1)
	HRR	T1,CORPNT	;MAKE INTO A BLT POINTER
	HRRZ	T2,CORPNT	;GET THAT START ADR AGAIN
	ADD	T2,WRDCNT	;POINT 1 PAST END OF DATA
	BLT	T1,-1(T2)	;AND COPY THE DATA BASE!
	MOVE	T1,400000+5(P3)	;GET SYSPPB AGAIN
	MOVEM	T1,SYSPPB	;AND STORE IT
	MOVE	T1,400000+76(P3);GET SYSCOR
	MOVEM	T1,SYSCOR	;STORE
	MOVE	T1,400000+75(P3);GET SYSDOR
	MOVEM	T1,SYSDOR	;AND STORE FOR LATER
	POPJ	P,



	UTIL
	END	BEGIN