Google
 

Trailing-Edge - PDP-10 Archives - scratch - 10,7/unscsp/lodtst/lodunv.mac
There are 5 other files named lodunv.mac in the archive. Click here to see a list.
	UNIVERSAL LODUNV - MONITOR TEST UNIVERSAL FILE


; AC DEFINITIONS

T0=0		;T0 - T5, TEMPORARY REGISTERS
T1=1
T2=2
T3=3
T4=4
T5=5
		;6-16 ARE UNUSED
P=17		;PUSH DOWN POINTER
PTY=2		;PSEUDO TTYP 
DSK=0		;DISK CHANNEL
XIT=1		;CHANNEL FOR KJOB CCL FILE

; OPDEFS

OPDEF	PJRST	[JRST]

; MACRO DEFINITIONS

	DEFINE	DEFINT,<
; DEFINT - PROGRAM INITIALIZATION ROUTINE

	JFCL			;ENTRY POINT
	RESET
	MOVE	P,PDP		;SET UP PDL POINTER
	PUSHJ	P,RANDOM	;INIT RANDOM NUMBER GENERATOR
	HLRZ	T0,.JBSA##	;INITIAL JOB SIZE
	IORI	T0,777		;ROUND UP TO PAGE BOUNDARY
	MOVEM	T0,MINSIZ	;SAVE JBSA
	PJOB	T0,		;GET JOB NUMBER THIS JOB
	MOVEM	T0,THSJOB	;SAVE JOB NUMBER
	GETPPN	T0,		;GET PPN FOR MY JOB
	JFCL			;BE CAUTIOUS
	MOVEM	T0,MYPPN	;SAVE MY PPN
	MOVE	T0,[20,,12]	;GET HIGHJB
	GETTAB	T0,		;FROM MONITOR
	MOVEI	T0,^D511	;ASSUME BIG JOBMAX IF GETTAB FAILS
	MOVN	T0,T0		;NEGATIVE JOB COUNT
	HRLZ	T0,T0		;SET UP AOBJN POINTER
	HRRI	T0,1		;START AT JOB 1
	MOVEM	T0,HIAOB	;AOBJN WORD FOR HIGHJB
	CTLJOB	T0,		;GET CONTROLLING JOB
	MOVEI	T0,0		;NOT ON A PTY
	JUMPG	T0,JOBOK	;FOUND CONTROLLING JOB
	MOVE	T0,HIAOB	;GET AOBJN WORD
JOBLUP:	MOVEI	T1,3		;GETTAB PROGRAM NAME
	HRL	T1,T0		;JOB NUMBER
	GETTAB	T1,		;FIND PROG NAME
	SETZ	T1,		;NOT LOGGED IN
	MOVEI	T2,2		;GETTAB PPN
	HRL	T2,T0		;JOB NUMBER
	GETTAB	T2,		;GET PPN
	SETZ	T2,		;FAILED
	CAME	T2,[1,,2]	;IS IT OPR?
	SETZ	T1,		;NO
	CAMN	T1,['LODTST']	;IS THIS THE LODTST JOB?
	JRST	JOBOK		;FOUND LODTST JOB
	AOBJN	T0,JOBLUP	;TRY NEXT JOB
	SETZ	T0,		;GIVE UP
JOBOK:	HRRZM	T0,LODJOB	;STORE LODTST JOB NUMBER
	MOVE	T0,THSJOB	;SET UP TO WAKE YOURSELF
	WAKE	T0,		;MAKE SURE YOU RETURN RIGHT AWAY
	JFCL			;IGNORE ERROR
	SETZ	T0,		;CLEAR T0
	HIBER	T0,		;DO DUMMY HIBER TO RETURN IMMEDIATELY
	JFCL			;IGNORE ERROR
	SETZ	T0,		;NOW DO THE REAL HIBER
	HIBER	T0,		;WAIT FOR LODTST TO WAKE US
	JFCL			;START IMMED IF NO HIBER
	SETOB	T2,T1		;FIND OUT WHAT PROCESSOR WE'RE ON
	AOBJN	T2,.+1		;TRY AOB INSTR
	JUMPN	T2,KA10		;KA10 ADDS 1000001
	BLT	T2,0		;TRY BLT INSTR
	JUMPE	T2,KI10		;KI10 DOESN'T MODIFY UNLESS INTERRUPTED
KL10:	SOJA	T1,KI10		;CODE OF 2 FOR KL
KA10:	SETZ	T1,		;CODE OF ZERO FOR KA
KI10:	MOVNM	T1,CPUMOD	;STORE CPU MODEL

>
	DEFINE	DEFALL<
; DEFALL - COMMON ROUTINES FOR ALL LODTST PROGRAMS

PDL:	BLOCK	20		;PUSHDOWN LIST
PDP:	IOWD	20,PDL		;PUSHDOWN POINTER
THSJOB:	0			;THIS JOB NUMBER
LODJOB:	0			;LODTST JOB NUMBER
MYPPN:	0			;PPN FOR THIS JOB
HIAOB:	0			;AOBJN WORD FOR HIGHEST JOB
MINSIZ:	0			;MINIMUM JOB SIZE
CPUMOD:	0			;CPU MODEL
FACTOR:	EXP	2.3E-6		;KA10
	EXP	1.6E-6		;KI10
	EXP	0.6E-6		;KL10


; RANDOM NUMBER GENERATOR (COURTESY FORLIB)

RANDOM:	PUSH	P,T1		;SAVE T1
	MOVE	T1,RANZER	;TO CLEAR DATA BASE
	SETZM	RAND		;SET RAND TO ZERO
	BLT	T1,RANTOP-1
	MSTIME	T0,		;GET TIME
	MOVE	T1,T0		;COPY
	ANDI	T0,77777	;JUST 15 BITS
	IMUL	T0,T0		;SQUARE
	XOR	T0,T1		;MIX BITS
	MOVEI	T1,3		;TO DO 4 RANDOM NUMBERS
RANDLP:	TLZ	T0,760000	;CLEAR 5 BITS FOR SAFETY
	SKIPN	T0
	MOVE	T0,[1777777]	;A STANDARD SEED
	MOVEM	T0,XN(T1)
	AOJ	T0,
	SOJGE	T1,RANDLP	;DO FOR 4 NUMBERS
	JRST	TPOPJ

RAN0:	PUSH	P,T2		;ENTRY FOR FIRST RANDOM NUMBER
	MOVEI	T2,0		;SET UP INDEX TO STORE RAND NUM
	PJRST	RAN		;GO MAKE RANDOM NUMBER
RAN1:	PUSH	P,T2		;ENTRY FOR SECOND RAN NUM
	MOVEI	T2,1
	PJRST	RAN
RAN2:	PUSH	P,T2		;ENTRY FOR THIRD RAN NUM
	MOVEI	T2,2
	PJRST	RAN
RAN3:	PUSH	P,T2		;ENTRY FOR FOURTH RAN NUM
	MOVEI	T2,3

RAN:	SETCMM	TIMES(T2)	;SWITCH FLAG
	SKIPN	TIMES(T2)	;WANT NEW RANDOM NUMBER?
	 JRST	NOTRAN		;NO
	PUSH	P,T1
	MOVE	T0,[^D630360016];14**29(MOD 2**31-1)
	MUL	T0,XN(T2)	;MULTIPLY WITH LAST RANDOM NUMBER
	ASHC	T0,4		;SEPARATE RESULT IN TWO 31 BIT WORDS
	LSH	T1,-4
	ADD	T0,T1		;ADD THEM TOGETHER
	TLZE	T0,760000	;SKIP IF RESULT .LT. 31 BITS
	ADDI	T0,1
	MOVEM	T0,XN(T2)	;STORE NEW RN IN INTEGER MODE
	HLRZ	T1,T0		;CONVERT TO FP IN TWO STEPS IN
	FSC	T1,216		;ORDER TO LOSE NO LOW ORDER
	HRRZ	T0,T0		;BITS
	FSC	T0,174
	FAD	T0,T1
	MOVEM	T0,RAND(T2)	;STORE IT FOR LATER
T2POPJ:	POP	P,T1		;RESTORE T1
	POP	P,T2		;RESTORE T2
	POPJ	P,		;RETURN

NOTRAN:	MOVSI	T0,(1.0)	;TAKE ONE MINUS LAST RANDOM
	FSBR	T0,RAND(T2)
	MOVEM	T0,RAND(T2)
	POP	P,T2
	POPJ	P,

FIX:	PUSH	P,T1		;SAVE T1
	SETZ	T1,
	ROTC	T0,^D9
	LSH	T0,-244(T1)
TPOPJ:	POP	P,T1		;RESTORE T1
	POPJ	P,

RANZER:	RAND,,RAND+1		;TO CLEAR AREA
RAND:	BLOCK	4		;CURRENT RANDOM NUMBER
XN:	BLOCK	4		;INTERNAL LAST RANDOM NUMBER
TIMES:	BLOCK	4		;FLAG FOR ODD OR EVEN CALL TO RAN
RANTOP:	BLOCK	0		; EVERY EVEN CALL RETURNS 1.0-RAND
				; INSTEAD OF A REAL RANDOM NUMBER


; ROUTINE TO PUT CONTENTS OF T2 INTO LEFT HALF OF JOB NAME

PUTNAM:	HRLZ	T0,THSJOB	;JOB NUMBER
	HRRI	T0,3		;SET UP FOR GETTAB
	GETTAB	T0,		;GET JOB NAME
	SETZ	T0,		;ERROR, ZERO NAME
	HRL	T0,T2		;PUT CODE IN FIRST THREE CHARS
	SETNAM	T0,		;OF JOB NAME
	POPJ	P,		;RETURN
; COMMON ERROR ROUTINE

ERROR:	MOVE	T2,T4		;GET ERROR NUMBER
	IDIVI	T2,^D10		;T2 CONTAINS TENS
	LSH	T2,6		;LINE UP WITH TENS IN SIXBIT
	ADDI	T2,452020(T3)	;ADD IN "E", TENS, UNITS
	PUSHJ	P,PUTNAM	;CHANGE LEFT HALF OF JOB NAME
	PUSHJ	P,PTYOPN	;GO INIT PTY
	JRST	ERRXIT		;CANT GET PTY
	MOVEI	T1,[ASCIZ/SEND OPR: ? /]
	PUSHJ	P,ASCIIP	;PRINT IT
	PUSHJ	P,OUTIME	;PRINT DAYTIME
	MOVEI	T1,[ASCIZ/ JOB /]
	PUSHJ	P,ASCIIP	;DO OUTPUT
	MOVE	T1,THSJOB	;GET JOB NUMBER
	PUSHJ	P,DECP3		;PRINT IT
	HRRZ	T1,ERRTAB-1(T4)	;GET MESSAGE
	PUSHJ	P,ASCIIP	;PRINT IT
	MOVEI	T1,[BYTE(7)15,12] ;CR, LF
	PUSHJ	P,ASCIIP	;PRINT IT
	MSTIME	T1,		;GET TIME
	ADDI	T1,^D3000	;CURRENT TIME PLUS 3 SECONDS
	MOVEM	T1,TIMLIM	;TIME LIMIT FOR PTY TO RETURN A DOT
	PUSHJ	P,PTYPRI	;SHORT SLEEP
ERRXIT:	HRRZ	T1,ERRSLP	;ON ERROR
	SLEEP	T1,		;DO SLEEP
	POPJ	P,		;RETURN

; ROUTINE TO OPEN PTY

PTYOPN:	OPEN	PTY,PTYDEV	;INIT PTY
	POPJ	P,		;CANT GET PTY
	PUSH	P,.JBFF##	;SAVE .JBFF
	OUTBUF	PTY,1		;SET UP OUTPUT BUFFER
	INBUF	PTY,1		;SET UP INPUT BUFFER
	EXCH	T1,-1(P)	;SAVE RETURN
	PUSHJ	P,1(T1)		;FOR LATER
	POP	P,.JBFF##	;SO CAN RESTORE .JBFF
	POP	P,T1
	RELEAS	PTY,		;GIVE UP PTY
	POPJ	P,		;RETURN

; ROUTINE TO CLEAN UP AFTER PTY OUTPUT

PTYPRI:	OUTPUT	PTY,		;FORCE AN OUTPUT
PTYTRY:	MOVEI	T1,PTY		;PTY CHANNEL NUMBER
	JOBSTS	T1,		;GET JOB STATUS
	JRST	PTYINP		;SHOULD NEVER HAPPEN
	TLC	T1,160000	;OUTPUT AVAIL, AT MON COMM LEVEL
	TLCN	T1,160000	;READY FOR NEXT SEND
	JRST	PTYINP		;YES
	MSTIME	T1,		;GET CURRENT TIME
	SUB	T1,TIMLIM	;MINUS TIME LIMIT
	JUMPGE	T1,PTYINP	;GIVE UP IF TIME LIMIT EXCEEDED
	MOVNS	T1		;NUMBER OF MS TO SLEEP
	HRLI	T1,(1B12)	;WAKE ON PTY ACTIVITY
	HIBER	T1,		;GO TO SLEEP
	SKIPA			;HIBER NOT IMPLEMENTED
	JRST	PTYTRY		;TRY AGAIN
	MOVEI	T1,1		;SLEEP A SECOND
	SLEEP	T1,
	JRST	PTYTRY		;NOW TRY
PTYINP:	INPUT	PTY,		;INPUT ANYTHING THATS THERE
	RELEAS	PTY,		;GET RID OF PTY
	POPJ	P,		;RETURN

; ROUTINE TO PRINT ASCII CHARACTERS

ASCIIP:	TLO	T1,(POINT 7,0)	;MAKE BYTE POINTER
NXCHAR:	ILDB	T2,T1		;GET NEXT CHAR
	JUMPE	T2,CPOPJ	;RETURN WHEN DONE
	PUSHJ	P,PTYP		;PRINT CHAR
	JRST	NXCHAR		;GET NEXT CHAR

; ROUTINES TO TYPE A DECIMAL NUMBER WITH LEADING SPACES OR ZEROS

DEC2P:	MOVEI	T2,"0"		;ZERO
	JRST	DEC2

DECP3:	MOVEI	T2," "		;SPACE
	CAIG	T1,^D99		;SKIP IF HAVE 3 DIGITS
	PUSHJ	P,PTYP		;1 SPACE IF 2 DIGIT OR LESS
DECP2:	MOVEI	T2," "		;SPACE
DEC2:	CAIG	T1,^D9		;SKIP IF HAVE 2  OR 3 DIGITS
	PUSHJ	P,PTYP		;2 SPACES IF HAVE 1 DIGIT
DECP:	IDIVI	T1,^D10		;ROUTINE TO
	HRLM	T2,(P)		;PRINT DECIMAL
	SKIPE	T1		;NUMBER
	PUSHJ	P,DECP
	HLRZ	T2,(P)
	ADDI	T2,"0"
	;PJRST	PTYP

; ROUTINE TO OUTPUT CHAR ON PTY

PTYP:	SOSG	PTYOUT+2	;ANY ROOM LEFT
	OUTPUT	PTY,		;NO, DUMP BUFFERS
	IDPB	T2,PTYOUT+1	;STORE BYTE IN BUFFER
CPOPJ:	POPJ	P,

; ROUTINE TO TYPE TIME OF DAY ON PTY

OUTIME:	MOVEI	T2,"["		;LEADING BRACKET
	PUSHJ	P,PTYP		;PRINT IT
	MSTIME	T1,		;GET TIME OF DAY
	IDIVI	T1,^D1000	;IN SECONDS
	IDIVI	T1,^D3600	;GET HOURS
	IDIVI	T2,^D60		;GET MIN'S AND SEC'S
	PUSH	P,T2		;SAVE MIN
	PUSHJ	P,DECP2		;PRINT HOURS
	MOVEI	T2,":"		;SEPARATE HR'S AND MIN'S
	PUSHJ	P,PTYP		;PRINT IT
	POP	P,T1		;GET BACK REMAINDER
	PUSHJ	P,DEC2P		;PRINT MINUTES
	MOVEI	T2,":"		;SEPARATOR
	PUSHJ	P,PTYP		;PRINT IT
	MOVE	T1,T3		;GET SECONDS
	PUSHJ	P,DEC2P		;TYPE IT
	MOVEI	T2,"]"		;CLOSING BRACKET
	PJRST	PTYP		;PRINT IT AND LEAVE


TIMLIM:	BLOCK	1		;TIME LIMIT TO WAIT FOR DOT
PTYIN:	BLOCK	3
PTYOUT:	BLOCK	3
PTYDEV:	0
	'PTY   '
	PTYOUT,,PTYIN
ERRTAB:	EXP	E01		;ERROR  1
	EXP	E02		;	2
	EXP	E03		;	3
	EXP	E04		;	4
	EXP	E05		;	5
	EXP	E06		;	6
	EXP	E07		;	7
	EXP	E08		;	8
	EXP	E09		;	9
E01:	ASCIZ	/ CORE UUO FAILED. /
E02:	ASCIZ	/ DISK INIT FAILURE./
E03:	ASCIZ	/ DISK ENTER FAILURE./
E04:	ASCIZ	/ DISK OUTPUT FAILURE./
E05:	ASCIZ	/ DISK CLOSE FAILURE./
E06:	ASCIZ	/ DISK LOOKUP FAILURE./
E07:	ASCIZ	/ DISK WRITE AND READ COMPARE FAILURE./
E08:	ASCIZ	/ DISK INPUT FAILURE./
E09:	ASCIZ	/ DISK RENAME FAILURE./
; ROUTINE TO CHECK FOR END OF TEST

TESTEX:	SKIPG	LODJOB		;DO WE KNOW THE JOB NUMBER OF LODTST?
	POPJ	P,		;NO
	MOVS	T0,LODJOB	;JOB NUMBER OF LODTST
	HRRI	T0,3		;GET PROGRAM NAME
	GETTAB	T0,		;DO THE GETTAB
	  POPJ	P,		;NO LODTST JOB - JUST RETURN
	CAMN	T0,['KILTST']	;IS LODTST TELLING US TO KJOB?
	JRST	KILJOB		;YES
	CAME	T0,['ENDTST']	;IS HE TELLING US TO EXIT?
	POPJ	P,		;NO - NEITHER
	MOVEI	T2,'END'	;YES - CHANGE PROGRAM NAME
	PUSHJ	P,PUTNAM	;TO START WITH END
KILXIT:	EXIT	1,		;EXIT TO MONITOR
	EXIT
KILJOB:	MOVEI	T2,'KIL'	;CHANGE PROGRAM NAME
	PUSHJ	P,PUTNAM	;TO START WITH KIL
	MOVE	T1,[106,,11]	;%CNST2 WORD
	GETTAB	T1,		;CHECK FOR MPB OR GALAXY
	  JRST	KILMPB		;ASSUME MPB
	TRNN	T1,1B26		;IS THIS A GALAXY SYSTEM?
	JRST	KILMPB		;NO, IT MUST BE MPB
	MOVE	T1,[1,,[EXP 'SYS   ','LOGOUT',0,0,0,0]]
	RUN	T1,
	JRST	KILXIT		;IF RUN UUO FAILS
	EXIT			;SHOULD NEVER GET HERE

KILMPB:	INIT	XIT,17		;OPEN CCL FILE
	'DSK   '
	0
	JRST	KILXIT		;GIVE UP IF NO DSK
	MOVE	T1,THSJOB	;GET MY JOB
	IDIVI	T1,^D100	;GET FIRST DIGIT
	IDIVI	T2,^D10		;GET SECOND DIGIT
	MOVE	T4,XITPNT	;POINTER TO KJOB MESSAGE
	MOVEI	T0,"0"(T1)	;FIRST DIGIT
	DPB	T0,T4		;STASH IN FILE NAME
	MOVEI	T0,"0"(T2)	;2ND DIGIT
	IDPB	T0,T4		;STORE IT
	MOVEI	T0,"0"(T3)	;LAST DIGIT
	IDPB	T0,T4		;STORE IT ALSO
	LSH	T1,^D12		;SHIFT 2 SIXBIT CHARS WORTH
	LSH	T2,6		;SHIFT 1 CHAR
	ADDI	T1,(T2)		;ADD IN FIRST 2 DIGITS
	ADDI	T1,202020(T3)	;ADD IN 3RD DIGIT
	HRLI	T1,'KJO'	;KJOB CCL FILE
	MOVSS	T1		;SWAP HALVES
	MOVSI	T2,'TMP'	;.TMP
	SETZB	T3,T4		;ZERO PPN
	ENTER	XIT,T1		;ENTER THE CCL FILE
	JRST	KILXIT		;OOPS
	OUTPUT	XIT,XOUT	;WRITE KJOB COMMAND INTO FILE
	CLOSE	XIT,		;CLOSE THE FILE
	RELEAS	XIT,		;CLOSE THE CHANNEL

	MOVE	T1,[1,,XITRUN]	;START UP KJOB AT THE CCL ENTRY POINT
	RUN	T1,		;RUN KJOB
	JRST	KILXIT		;ERROR RETURN
	JRST	KILXIT		;SHOULD NEVER GET HERE

XITPNT:	POINT	7,XITMES+2,20
XITMES:	ASCIZ *KJOB DSK:DUMMYX.LOG=/K/Z:0/VD:D
*
XITLEN==.-XITMES
XOUT:	IOWD	XITLEN,XITMES	;POINTER TO TEXT
	0
XITRUN:	SIXBIT/SYS/
	SIXBIT/KJOB/
	BLOCK	5

>
	DEFINE	DEFDSK,<
; DEFDSK - ROUTINES FOR DISK I/O


; PCKSTR - ROUTINE TO SELECT BEST DISK STRUCTURE

PCKSTR:	SETZB	T0,UNITS	;START WITH FIRST UNIT, NO UNITS
NXTPHY:	SYSPHY	T0,200000	;GET A PHYSICALUNIT
	 JRST	USEDSK		;CAN'T. USE JUST DSK
	JUMPE	T0,LSTPHY	;QUIT IF DONE
	MOVEM	T0,TBLLOC	;CHECK UNIT FOR USEABLITY
	MOVE	T1,[XWD 15,TBLLOC] ;ARGS FOR DSKCHR
	DSKCHR	T1,200000	;GET CHARACTERISTICS OF UNIT
	 JRST	NXTPHY		;TRY NEXT UNIT ON ERROR
	TLNE	T1,363300	;IS UNIT WRITEABLE, ON-LINE,MULTI-ACCESS,ETC.?
	 JRST	NXTPHY		;NO. TRY NEXT UNIT
	SKIPE	T2,TBLLOC+4	;GET STR NAME
	SKIPN	TBLLOC+14	;AND UNIT NAME IN STR
	 JRST	NXTPHY		;NOT BOTH DEFINED. TRY NEXT UNIT
	MOVE	T1,[XWD 400000,16] ;OPEN UNIT
	SETZ	T3,		;IN DUMP MODE
	OPEN	DSK,T1		;TO BE SURE WE CAN
	 JRST	NXTPHY		;CAN'T. TRY NEXT UNIT
	MOVE	T1,TBLLOC+14	;SAVE UNIT NAME
	MOVEM	T1,UNIT
	MOVE	T1,TBLLOC+1	;AND FCFS QUOTA REMAINING
	MOVEM	T1,FCFS
	MOVEI	T1,25		;SET FOR EXTENDED LOOKUP
	MOVEM	T1,TBLLOC	;THROUGH .RBUSD
	MOVE	T1,[0,,16]	;GET MFD PPN
	GETTAB	T1,		;FROM MONITOR
	 MOVE	T1,[1,,1]	;ASSUME [1,1]
	MOVEM	T1,TBLLOC+1	;WHERE TO FIND UFD
	GETPPN	T1,		;GET OUR PPN
	 JFCL
	MOVEM	T1,TBLLOC+2	;UFD TO LOOK UP
	MOVSI	T1,'UFD'	;EXTENSION IS UFD
	MOVEM	T1,TBLLOC+3
	LOOKUP	DSK,TBLLOC	;LOOK FOR UFD
	 JRST	NXTPHY		;NOT THERE. TRY NEXT UNIT
	RELEAS	DSK,		;GIVE THE DISK BACK
	SKIPG	TBLLOC+22	;ANY FCFS QUOTA?
	 JRST	NXTPHY		;NO. TRY NEXT UNIT
	MOVE	T1,FCFS		;FIND REMAINING FCFS
	MOVE	T2,TBLLOC+22	;MAY BE FCFS
	SUB	T2,TBLLOC+25	;MINUS USED
	CAMN	T1,[XWD 400000,0] ;DOES MONITOR KNOW?
	MOVE	T1,T2		;NO. USE FIGURE FROM UFD
	JUMPLE	T1,NXTPHY	;NO SPACE. TRY NEXT UNIT
	AOS	T1,UNITS	;INCREMENT UNIT COUNT
	MOVE	T2,UNIT		;GET UNIT NAME
	MOVEM	T2,TBLBLK-1(T1)	;STORE IN UNIT TABLE
	CAIGE	T1,^D20		;ROOM FOR MORE UNITS IN TABLE?
	JRST	NXTPHY		;YES. TRY FOR MORE UNITS

LSTPHY:	SETOM	PASS		;START WITH PASS ZERO
	RELEAS	DSK,		;RELEAS DSK JUST IN CASE
	SKIPLE	UNITS		;ANY UNITS AT ALL?
	 POPJ	P,		;YES. OK
USEDSK:	RELEAS	DSK,		;RELEAS DSK JUST IN CASE
	MOVEI	T1,1		;ONE UNIT
	MOVEM	T1,UNITS
	MOVSI	T1,'DSK'	;CALLED DSK
	MOVEM	T1,TBLBLK
	POPJ	P,

PCKDEV:	MOVE	T0,THSJOB	;GET JOB NUMBER
	ADD	T0,PASS		;PLUS PASS NUMBER
	IDIV	T0,UNITS	;MOD UNITS
	MOVE	T0,TBLBLK(T1)	;GET UNIT NAME FROM TABLE
	MOVEM	T0,DEVICE	;STORE FOR OPEN
	POPJ	P,		;RETURN
; ROUTINE TO DO DISK IO

RANDSK:	PUSHJ	P,PCKDEV	;PICK DEVICE
	SKIPE	TIMES+1		;AFTER EVERY 2ND CALL, CHANGE UNITS
	AOS	PASS		;BY INCREMENTING PASS
INTDSK:	SETZM	IBUF		;SET UP
	MOVE	T0,[IBUF,,IBUF+1] ;DISK IO
	BLT	T0,BUFTOP-1	;BUFFERS
	INIT	DSK,14		;INIT DISK
DEVICE:	'DSK   '		;SET UP BY PCKDEV AT INIT
	OBUF,,IBUF
	JRST	ERR2		;INIT FAILURE
	PUSHJ	P,RAN1		;GET RANDOM NUMBER
	FMPR	T0,[10.0]	;MAKE RANGE 0 TO 9
	PUSHJ	P,FIX		;CONVERT TO INTEGER
	MOVE	T1,T0		;COPY OF RANDOM NUMBER
	MOVE	T0,.JBFF##	;GET JOBFF
	MOVEM	T0,SAVEFF	;SAVE IT FOR FUTURE RESTORE
	OUTBUF	DSK,1(T1)	;1 TO 10 OUTPUT BUFFERS
	INBUF	DSK,1(T1)	;1 TO 10 INPUT BUFFERS
	MOVE	T0,RAND+1	;GET RANDOM NUMBER
	TRZ	T0,777		;MASK FOR JOB NUMBER
	IOR	T0,THSJOB	;MAKE JOB NUMBER PART OF FILE NAME
	MOVEM 	T0,SAVNAM	;SAVE FILE NAME
ENTDSK:	MOVE	T0,SAVNAM	;RESTORE FILE NAME
	SETZB	T1,T2		;MAKE UP 4
	SETZ	T3,		;WORD ENTER BLOCK
	ENTER	DSK,T0		;ENTER FILE
	JRST	ERR3		;ENTER FAILURE
	MOVE	T0,RAND+1	;GET RANDOM NUMBER
	FMPR	T0,BLKRNG	;4096 WORDS = 32 BLOCKS
	FADR	T0,BLKBAS	;PLUS MINIMUM
	PUSHJ	P,FIX		;CONVERT TO INTEGER
	MOVE 	T1,T0		;NUMBER OF WORDS TO WRITE
	MOVE	T0,RAND+1	;GET RANDOM NUMBER
PUTC:	SOSGE	OBUF+2		;NUMBER OF WORDS REMAINING
	JRST	WRIT		;GO WRITE DISK RECORD
	IDPB	T0,OBUF+1	;STORE THIS WORD
	ROT	T0,1		;TO WRITE ROTATING BIT PATTERN
	SOJG	T1,PUTC		;GO WRITE NEXT RECORD
	JRST	CLOSF		;DONE, GO CLOSE FILE
WRIT:	OUT	DSK,		;WRITE DISK RECORD
	JRST	PUTC		;GO WRITE NEXT RECORD
	JRST	ERR4		;DISK WRITE FAILURE
CLOSF:	CLOSE	DSK,		;CLOSE DISK FILE
	STATZ	DSK,740000	;CHECK FOR ERRORS
	JRST	ERR5		;DISK CLOSE ERROR
LOKDSK:	MOVE	T0,SAVNAM	;RESTORE FILE NAME
	SETZB	T1,T2		;CLEAR REST OF
	SETZ	T3,		;LOOKUP BLOCK
	LOOKUP	DSK,T0		;LOOKUP DISK FILE
	JRST	ERR6		;DISK LOOKUP FAILURE
	MOVE	T0,RAND+1	;GET RANDOM NUMBER
GETC:	SOSGE	IBUF +2		;WORDS REMAINING IN RECORD
	JRST	READF		;READ NEXT RECORD
	ILDB	T1,IBUF +1	;GET NEXT WORD
	CAME	T0,T1		;COMPARE TO KNOWN OUTPUT
	JRST	ERR7		;DISK READ AND WRITE FAILED
	ROT	T0,1		;ROTATING BIT PATTERN
	JRST	GETC		;GO GET NEXT WORD
READF:	IN	DSK,		;READ NEXT DISK RECORD
	JRST	GETC		;GO PROCESS WORDS
	STATO	DSK,20000	;CHECK EOF
	JRST	ERR8		;DISK INPUT ERR0R
RENDSK:	CLOSE	DSK,		;CLOSE THE FILE
	MOVE	T0,SAVEFF	;RESTORE JOBFF TO WHAT IT WAS BEFORE
	MOVEM	T0,.JBFF##	;TO RETURN CORE AND PREVENT ADDRESS CHECK
	SETZB	T0,T1		;CLEAR 4 WORD BLOCK
	SETZB	T2,T3		;FOR RENAME
	RENAME	DSK,T0		;DELETE DISK FILE
	JRST	ERR9		;DISK RENAME FAILURE
	POPJ	P,		;RETURN

ERR2:	MOVEI	T4,2		;DISK INIT FAILURE
	PUSHJ	P,ERROR		;PRINT ERROR MESSAGE
	JRST	INTDSK		;TRY INIT AGAIN
ERR3:	MOVEI	T4,3		;DISK ENTER FAILURE
	PUSHJ	P,ERROR		;PRINT MSG
	JRST	ENTDSK		;TRY TO ENTER AGAIN
ERR4:	MOVEI	T4,4		;DISK OUTPUT FAILURE
	PUSHJ	P,ERROR		;PRINT MSG
	JRST	RENDSK		;DELET FILE AND EXIT
ERR5:	MOVEI	T4,5		;DISK CLOSE FAILURE
	PUSHJ	P,ERROR		;PRINT MSG
	JRST	RENDSK		;DELETE FILE AND EXIT
ERR6:	MOVEI	T4,6		;DISK LOOKUP FAILURE
	PUSHJ	P,ERROR		;PRINT MSG
	JRST	LOKDSK		;TRY LOOKUP AGAIN
ERR7:	MOVEI	T4,7		;READ AND WRITE COMPARE FAILED
	PUSHJ	P,ERROR		;PRINT MSG
	JRST	RENDSK		;DELETE FILE AND EXIT
ERR8:	MOVEI	T4,^D8		;DISK INPUT ERROR
	PUSHJ	P,ERROR		;PRINT MSG
	JRST	RENDSK		;DELET FILE AND EXIT
ERR9:	MOVEI	T4,^D9 		;DISK RENAME FAILURE
	PUSHJ	P,ERROR		;PRINT MSG
	POPJ	P,		;START DISK IO AGAIN

IBUF:	BLOCK	3
OBUF:	BLOCK	3
BUFTOP:	BLOCK	0
SAVEFF:	BLOCK	1
SAVNAM:	BLOCK	1
UNIT:	BLOCK	1		;TEMP FOR UNIT NAME
FCFS:	BLOCK	1		;TEMP FOR FCFS QUOTA
UNITS:	BLOCK	1		;NUMBER OF UNITS IN STR
PASS:	BLOCK	1		;COUNT OF PASSES THRU PCKDEV
TBLBLK:	BLOCK	^D20		;MAXIMUM NUMBER OF UNITS TO READ/WRITE
TBLLOC:	BLOCK	30		;ARG SPACE FOR DSKCHR, LOOKUP, ETC.

>
	DEFINE	DEFOPN,<
; ROUTINE TO OPEN DEVICE CHANNELS

RANOPN:	PUSHJ	P,RAN1		;GET RANDOM #1
	MOVEI	T1,DEVNUM	;NUMBER OF DEVICES
	FSC	T1,233		;FLOAT T1
	FMPR	T0,T1		;SCALE TO RANGE
	PUSHJ	P,FIX		;CONVERT TO INTEGER
	MOVE	T1,T0		;SAVE DEVICE INDEX
	SETZ	T0,		;MODE 0
	MOVE	T1,DEVLST(T1)	;GET DEVICE NAME FROM TABLE
	MOVE	T2,[OPNB,,IPNB]	;BUFFER HEADERS
	MOVE	T3,[OPNB,,OPNB+1]
	SETZM	OPNB		;SET BUFFER HEADERS TO ZERO
	BLT	T3,OPNX-1
	MOVE	T3,[OPEN T0]	;SET UP OPEN UUO
	DPB	T4,[POINT 4,T3,12] ;DEPOSIT CHANNEL NUMBER
	XCT	T3		;EXECUTE THE OPEN
	JFCL			;IGNORE ERRORS
	POPJ	P,		;RETURN

OPNB:	BLOCK	3		;OUTPUT BUFFER
IPNB:	BLOCK	3		;INPUT BUFFER
OPNX:	BLOCK	0		;END FOR BLT

>

	DEFINE	DEFSLP,<
; ROUTINE TO DO RANDOM SLEEP LOOP

RANSLP:	PUSHJ	P,RAN2		;GET A RANDOM NUMBER
	FMPR	T0,SLPRNG	;MULT BY RANGE
	FADR	T0,SLPBAS	;ADD BASE SLEEP TIME
	PUSHJ	P,FIX		;CONVERT TO INTEGER
	SLEEP	T0,		;DO SLEEP
	POPJ	P,		;RETURN

>

	DEFINE	DEFCPU,<
; ROUTINE TO DO RANDOM CPU LOOP

RANCPU:	PUSHJ	P,RAN3		;GET RANDOM NUMBER
	FMPR	T0,CPURNG	;MULT BY RANGE
	FADR	T0,CPUBAS	;ADD MINIMUM
	MOVE	T1,CPUMOD	;GET CPU MODEL TO INDEX TABLE
	FDVR	T0,FACTOR(T1)	;DIVIDE BY APPROPRIATE FACTOR
	PUSHJ	P,FIX		;CONVERT TO INTEGER
	SOJG	T0,.		;CPU LOOP
	POPJ	P,		;RETURN

>
	DEFINE	DEFHGH,<
; ROUTINE TO CHANGE HIGH AND LOW CORE SIZE

RANHGH:	PUSHJ	P,RAN0		;GET RANDOM NUMBER
	FMPR	T0,HGHRNG	;SCALE TO RANGE
	FADR	T0,HGHBAS	;ADD BASE CORE
	FSC	T0,^D9		;TIMES PAGE SIZE
	PUSHJ	P,FIX		;CONVERT TO INTEGER
	SUBI	T0,1		;HIGHEST ADDRESS
	HRRZ	T1,T0		;SAVE HIGH SEG SIZE
	PUSHJ	P,RAN1		;GET DIFF RANDOM NUMBER
	FMPR	T0,LOWRNG	;SCALE TO RANGE
	FADR	T0,LOWBAS	;ADD BASE LOW SEG SIZE
	FSC	T0,^D9		;TIMES 512 FOR WORDS
	PUSHJ	P,FIX		;CONVERT TO INTEGER
	ADD	T0,MINSIZ	;PLUS MINIMUM
	HRLI	T0,400000(T1)	;COMBIN HIGH AND LOW
	CORE	T0,		;DO CORE UUO
	JRST	ERRA		;CORE UUO ERROR
	POPJ	P,		;RETURN

ERRA:	MOVEI	T4,1		;CORE UUO FAILURE
	PJRST	ERROR		;PRINT ERROR MSG

>

	DEFINE	DEFCOR,<
; ROUTINE TO CHANGE LOW SEG CORE SIZE

RANCOR:	SOSLE	CORNUM		;COUNT DOWN TO ZERO
	POPJ	P,		;NOT YET TIME TO CHANGE CORE
	MOVE	T0,CORCNT	;CHANGE CORE EVERY CORCNT TIME
	SKIPE	CORNUM		;FIRST TIME THRU?
	PUSHJ	P,CORSEL	;YES, SET COUNTER TO RANDOM NUMBER
	MOVEM	T0,CORNUM	;STORE NEW COUNTER
DOCORE:	PUSHJ	P,RAN0		;GET RANDOM NUMBER
	FMPR	T0,CORRNG	;SCALE TO RANGE
	FADR	T0,CORBAS	;PLUS BASE SIZE
	FSC	T0,^D9		;CHANGE TO WORDS
	PUSHJ	P,FIX		;CONVERT TO INTEGER
	ADD	T0,MINSIZ	;PLUS MINSIZE
	CORE	T0,		;GET NEW CORE SIZE
	JRST	ERR1		;CORE UUO FAILED
	POPJ	P,		;RETURN

CORSEL:	PUSHJ	P,RAN0		;GET RANDOM NUMBER
	MOVE	T1,CORCNT	;HOW OFTEN TO CHANGE CORE
	FSC	T1,233		;CHANGE TO DECIMAL
	FMPR	T0,T1		;PICK A STARTING VALUE
	PUSHJ	P,FIX		;CONVERT TO INTEGER IN RANGE
	ADDI	T0,1		;1 TO CORCNT
	POPJ	P,		;RETURN WITH INITIAL COUNT

ERR1:	MOVEI	T4,1		;CORE UUO FAILED
	PUSHJ	P,ERROR		;PRINT MSG
	JRST	DOCORE		;TRY AGAIN

CORNUM:	0			;COUNTER OF TIMES THRU RANCOR

>
	DEFINE	DEXSLP,<
; ROUTINE TO DO SLEEP WITH EXPONENTIAL DISTRIBUTION

EXPSLP:	PUSHJ	P,EXRAN2	;GET NEGATIVE EXPONENTIAL RANDOM NUMBER
	FMPR	T0,SLPRNX	;TIMES EXPONENTIAL SLEEP MEAN
	CAMLE	T0,SLPMAX	;IS IT LESS THAN THE MAXIMUM?
	MOVE	T0,SLPMAX	;IF NOT USE THE MAX
	PUSHJ	P,FIX		;CONVERT TO INTEGER
	SLEEP	T0,		;DO THE SLEEP
	POPJ	P,		;RETURN

>

	DEFINE	DEXCPU,<
; ROUTINE TO DO EXPONENTIAL CPU LOOP

EXPCPU:	PUSHJ	P,EXRAN3	;GET EXPONENTIAL RANDOM NUMBER
	FMPR	T0,CPURNX	;TIMES MEAN CPU TIME
	CAMLE	T0,CPUMAX	;COMPARE WITH MAX
	MOVE	T0,CPUMAX	;BE SURE ITS LESS OR EQUAL TO MAX
	MOVE	T1,CPUMOD	;CPU MODEL NUMBER
	FDVR	T0,FACTOR(T1)	;CONVERT TO NUMBER OF SOJGS
	PUSHJ	P,FIX		;IN INTEGER
	SOJG	T0,.		;DO THE CPU LOOP
	POPJ	P,		;RETURN

>

	DEFINE	DEXRAN,<

; ROUTINES TO CALCULATE RANDOM NUMBERS ACCORDING TO EXPONENTIAL DENSITY FUNCTION

EXRAN3:	PUSHJ	P,RAN3		;USE THIRD SEED
	JRST	EXRAN
EXRAN2:	PUSHJ	P,RAN2		;USE SECOND SEED
	JRST	EXRAN
EXRAN1:	PUSHJ	P,RAN1		;USE FIRST SEED
	JRST	EXRAN
EXRAN0:	PUSHJ	P,RAN0		;USE ZEROTH SEED
EXRAN:	PUSH	P,T1		;SAVE T1
	SKIPG	T1,T0		;IS RANDOM NUMBER GREATER THAN 0
	MOVSI	T1,146400	;NO USE VERY SMALL NUMBER
	MOVEM	T1,LOGARG	;STORE AS ARGUMENT TO ALOG
	PUSHJ	P,ALOG		;COMPUTE LOG OF NUMBER IN RANGE 0 TO 1
	MOVM	T0,T0		;MAKE RESULT POSITIVE
	JRST	TPOPJ		;RETURN
; ROUTINE TO COMPUTE NATURAL LOG

ALOG:	MOVM	T0,LOGARG	;GET ABSF(X)
	JUMPE	T0,ALOGFI	;CHECK FOR ZERO ARGUMENT
	CAMN	T0,ONE		;CHECK FOR 1.0 ARGUMENT
	JRST	ALOG0		;IT IS 1.0 RETURN ZERO ANS.
	ASHC	T0,-33		;SEPARATE FRACTION FROM EXPONENT
	ADDI	T0,211000	;FLOAT THE EXPONENT AND MULT. BY 2
	MOVSM	T0,LOGS		;NUMBER NOW IN CORRECT FL. FORMAT
	MOVSI	T0,567377	;SET UP -401.0 IN A
	FADM	T0,LOGS		;SUBTRACT 401 FROM EXP.*2
	ASH	T1,-10		;SHIFT FRACTION FOR FLOATING
	TLC	T1,200000	;FLOAT THE FRACTION PART
	FAD	T1,LOG1		;B = B-SQRT(2.0)/2.0
	MOVE	T0,T1		;PUT RESULTS IN A
	FAD	T0,LOG2		;A = A+SQRT(2.0)
	FDV	T1,T0		;B = B/A
	MOVEM	T1,LOGZ		;STORE NEW VARIABLE IN LZ
	FMP	T1,T1		;CALCULATE Z^2
	MOVE	T0,LOG3		;PICK UP FIRST CONSTANT
	FMP	T0,T1		;MULTIPLY BY Z^2
	FAD	T0,LOG4		;ADD IN NEXT CONSTANT
	FMP	T0,T1		;MULTIPLY BY Z^2
	FAD	T0,LOG5		;ADD IN NEXT CONSTANT
	FMP	T0,LOGZ		;MULTIPLY BY Z
	FAD	T0,LOGS		;ADD IN EXPONENT TO FORM LOG2(X)
	FMP	T0,LOG7		;MULTIPLY TO FORM LOGE(X)
	POPJ	P,
ALOG0:	TDZA	T0,T0		;MAKE ANSWER ZERO
ALOGFI:	MOVE	T0,MIFI		;PICK UP MINUS INFINITY
	POPJ	P,

;CONSTANTS

ONE:	201400000000
LOG1:	577225754146		;-0.707106781187
LOG2:	201552023632		;1.414213562374
LOG3:	200462532521		;0.5989786496
LOG4:	200754213604		;0.9614706323
LOG5:	202561251002		;2.8853912903
LOG7:	200542710300		;0.69314718056
MIFI:	400000000001		;LARGEST NEGATIVE FLOATING NUMBER

LOGS:	0
LOGZ:	0
LOGARG:	0

>

	END