;DSK:<PEFMON>DRMDMY.MAC;3 28-Apr-80 22:07:21, Edit by FRENCH
;MAKE DRMBND INTERNAL
;DSK:<PEFMON>DRMDMY.MAC;2 23-Apr-80 01:01:23, Edit by FRENCH
;COMMENT HORRIBLE CROCKERY AT ASDRMS
;<134-TENEX>DRMDMY.MAC;2    10-Sep-78 17:58:40    EDIT BY PETERS
;<134-TENEX>DRMDMY.MAC;1    10-Sep-78 15:41:35    EDIT BY PETERS
	SEARCH	PROLOG
	TITLE	DRM

;DRUM DRIVER - DUMMY DRUM, USES DSK

	INTERN DRMSEC,DRMBBT,DRMBST,DRMBND
	INTERN DRMIO,DRMINI
	EXTERN SWPDON,DRUMP
	EXTERN BUGHLT,BUGCHK,DSKIO,BITS,BHC

;DRUM IO DRIVER

; AC1/ 18-35 CORE PAGE NUMBER (CST INDEX) OF PAGE
;      DWRBIT WRITE OPERATION IF 1, READ IF 0

DRMIO:	JRST DSKIO		;USE DISK

;THIS ALLOCATOR HANDLES A DEVICE OF SOME NUMBER (DRMSEC) OF SECTORS,
;AND SOME NUMBER (DRMBND) OF BANDS. IT HAS A RESIDENT BIT TABLE,
;AND IS USED TO ALLOCATE SWAPPING STORAGE, EVEN IF THE PHYSICAL
;SWAPPING DEVICE IS THE SAME AS THE PHYSICAL FILE DEVICE

;THE FOLLOWING ROUTINES ARE IN THIS PACKAGE & CALLED FROM OUTSIDE.

INTERN ASDRMS		;ASSIGN SPECIFIC DRUM ADDRESSES
INTERN DRMASF		;ASSIGN A DRUM PAGE, EMPTIEST SECTOR.
INTERN ASDRM		;ASSIGN DRUM PAGE NEAR A SPECIFIC SECTOR
INTERN DEDRM		;DEASSIGN A DRUM PAGE
INTERN BNDLK,BNDULK	;ROUTINES TO PREVENT/ENABLE ASSIGNMENT OF
			;DRUM ADDRESSES AT PARTICULAR BANDS.

DRMSEC==^D36		;NO. OF DRUM SECTORS
DRMBND==NDST/DRMSEC	;NO OF BANDS
DRMBSZ==<DRMBND+^D35>/^D36	;SIZE OF BIT TABLE CHUNK FOR 1 SECTOR

LS DRMBLK		;LOCKOUT WORD FOR DRUM BIT TABLE
LS DRMSC,DRMSEC		;FREE PAGE COUNT TABLE (ONE WORD/SECTOR)
LS DRMFRE		;TOTAL FREE PAGE COUNT FOR DRUM
LS BNDLO,DRMBSZ		;BAND MASK OUT TABLE
GS DRMBIT,DRMSEC*DRMBSZ	;DRUM BIT TABLE

LS MAXBND,1		;[ISI] <Maximum band in use plus 1> * 100
LS DRMLSA,1		;LAST SECTOR ASSIGNED

;ASSIGN PAGE, EMPTIEST SECTOR

;"DRMASF" RETURNS CALLER+1 IF THE DRUM IS FULL OR UNAVAILABLE, ELSE
;CALLER+2 WITH THE DRUM ADDRESS ASSIGNED IN A.  THE SECTOR CHOSEN FOR
;THE ASSIGNMENT HAS THE MOST FREE PAGES.  "ASDRM" TRIES TO ASSIGN
;A PAGE AT SECTOR (A)+1 OR AS SOON AFTER AS POSSIBLE.  IT RETURNS CALLER+1
;IF NO FREE PAGES ARE LEFT OR CALLER+2 WITH THE DRUM ADDRESS IN A.

	INTERN DRMASN

DRMASF:	SKIPG DRMFRE		;ROOM AVAILABLE?
	JRST DRMSA3		;NO, RETURN BAD
	HRLZI C,-DRMSEC		;CHOOSE EMPTIEST SECTOR FOR PAGE ASSIGNMENT
	MOVE B,DRMSC(C)		;GET FREE PAGE COUNT FOR THIS SECTOR
	HRRZ A,C		;BEST SECTOR SO FAR IN 1.
	CAMG B,DRMSC+1(C)
	AOBJN C,.-3
	AOBJN C,.-2
	JUMPG B,DRMASL
	JRST DRMSA3		;RETURN CALLER+1 IF DRUM FULL

;ASSIGN PAGE NEAR GIVEN SECTOR

DRMASN:	JUMPL A,[AOS A,DRMLSA	;FREE CHOICE MEANS NEXT SECTOR
		CAIL A,DRMSEC
		SETZB A,DRMLSA	;WRAPAROUND
		JRST DRMASS]
ASDRM:	ANDI A,77
	CAIL A,DRMSEC		;CHECK FOR LEGAL ARGUMENT
	JRST DRMASF
DRMASS:	SKIPG DRMFRE
	JRST DRMSA3		;GO MAKE NO FREE PAGES RETURN
DRMAS1:	CAIGE A,DRMSEC-1
	AOJA A,.+2
	SETZ A,
	SKIPG DRMSC(A)
	JRST DRMAS1		;LOOP IF NO FREE PAGES HERE
DRMASL:	SOS DRMSC(A)		;DECREMENT NO. FREE PAGES ON THIS SECTOR
	MOVE B,A
	IMULI B,DRMBSZ
	HRLI B,-DRMBSZ
	SKIPE C,DRMBIT(B)
	JFFO C,SECFND
	AOBJN B,.-2
DBTFU:	BUG(HLT,<DRUM BIT TABLE FOULED, COUNT AND BITS DISAGREE>)

;CONVERT DRUM ADDRESS INTO INDEX INTO DST

	INTERN GDSTX

GDSTX:	TLNN 2,14		;INSIST ON REGULAR DRUM ADDRESS
	TLNN 2,2
	BUG(HLT,<GDSTX - BAD ADDRESS>)
	HRRZS 3,2		;SPLIT BAND AND SECTOR
	ANDI 3,77		;SECTOR
	LSH 2,-6		;BAND
	IMULI 2,DRMSEC
	ADDI 2,0(3)
	CAIL 2,NDST
	BUG(HLT,<GDSTX - BAD ADDRESS>)
	RET

	INTERN DASDRM

DASDRM:	CALL DEDRM
	JFCL
	BUG(HLT,<ATTEMPT TO DEASSIGN BAD OR UNASSIGNED DRUM ADDRESS>)
	RET

SECFND:	HLRO C,B
	MOVEI C,@BANDT(C)		;GET THE BAND NUMBER & 1 IN BIT 23
	LSH C,6			;POSITIONS THE BAND FIELD & 1 IN BIT 17
	IOR A,C			;DRUM ADDRESS NOW IN A
	MOVE C,BITS(D)		;GET BIT FOR BAND WORD
	ANDCAM C,DRMBIT(B)	;CLEAR THE BIT FROM THE BIT TABLE.
DRMSA1:	SOS DRMFRE		;DECREMENT TOTAL FREE PAGES ON DRUM
DRMSA2:	AOS (P)			;MAKE SKIP RETURN
DRMSA3:
DRMAS2:
RETN:	RET

	FOO==0
	REPEAT DRMBSZ,<XWD D,FOO+1B22
	FOO==FOO+44>
BANDT:
;ROUTINES TO ATTEMPT ASSIGNMENT OF A SPECIFIC DRUM ADDRESS

;NO SKIP IF BAD ADR
;SKIP IF OK ADR BUT NOT AVAILABLE
;DOUBLE SKIP IF AVAILABLE AND ASSIGN SUCCESS

ASDRMS:	JSP UNIT,DRMBS		;WILL AOS (P) IF GOOD ADR
	TDNN D,DRMBIT(B)	;SKIP IF PAGE IS AVAILABLE
	JRST DRMSA3		;NOT-TAKE +2 RETURN
	ANDCAM D,DRMBIT(B)	;OK-ASSIGN IT
	SOS DRMSC(C)		;REDUCE FREE PAGE COUNT FOR THIS SECTOR
	JRST DRMSA1		;TAKE +3 RETURN

;ROUTINE TO RELEASE A DRUM PAGE

DEDRM:	JSP UNIT,DRMBS
	TDNE D,BNDLO(A)		;CHECK IF BAND LOCKED OUT
	TDNE D,DRMBIT(B)	;CHECK IF NOT YET ASSIGNED
	RET			;SKIP RETURN 
	IORM D,DRMBIT(B)
	AOS DRMSC(C)		;INCREMENT FREE PAGE COUNT FOR THIS SECTOR
	AOS DRMFRE
	AOS (P)
	RET			;MAKE DOUBLE SKIP RETURN

;CHECKS FOR LEGAL DRUM ADDRESS & GETS WORD & BIT INDICES TO BIT TABLE
;RETURNS BIT CHUNK WORD INDEX IN A, BIT TABLE WORD INDEX IN B,
;SECTOR NO. IN C, AND BIT POSITION MASK IN D

DRMBS:	ANDI A,-1
	MOVE C,A
	ANDI C,77
	CAMGE A,MAXBND		;[ISI] Legal band?
	CAIL C,DRMSEC		;LEGAL SECTOR?
	RET 
	AOS (P)
DRMSA0:	LSH A,-6		;GET BAND NO.
	IDIVI A,44		;WORD IN CHUNK & BIT IN WORD
	MOVE D,BITS(B)		;POSITION THE BIT
	MOVE B,C
	IMULI B,DRMBSZ		;1ST WORD OF BIT CHUNK
	ADD B,A
	JRST (UNIT)

;LOCK BAND
;ACCEPTS IN A BAND TO LOCK.
; RETURN 1 => ILLEGAL ADDRESS
; RETURN 2 => BAND LOCKED, NOT ALL PAGES WERE FREE
; RETURN 3 => BAND LOCKED, ALL PAGES WERE FREE

BNDLK:	JSP UNIT,BNDLUE
	SETZ D,
	TDNN C,BNDLO(A)
	JRST DRMSA3
	ANDCAM C,BNDLO(A)	;CLEAR BIT IN LOCKOUT TABLE
BNDLP:	TDNN C,DRMBIT(A)
	JRST BNDCON
	SUBI D,1
	ANDCAM C,DRMBIT(A)	;CLEAR BIT IN EACH OF SECTOR BIT TABLES
	SOS DRMSC(B)		;& ADJUST FREE PAGE COUNT
BNDCON:	ADDI A,DRMBSZ
	AOBJN B,BNDLP
	ADDM D,DRMFRE
	CAIG D,-DRMSEC
	JRST DRMSA3
	JRST DRMSA2

;UNLOCK BAND
;ACCEPTS IN A BAND TO LOCK.
; RETURN 1 => ILLEGAL ADDRESS
; RETURN 2 => BAND NOT PREVIOUSLY LOCKED
; RETURN 3 => UNLOCKED SUCCESSFULLY

BNDULK:	JSP UNIT,BNDLUE
	TDNE C,BNDLO(A)
	JRST DRMAS2		;NOT PREVIOUSLY LOCKED--MAKE ERROR RETURN
	IORM C,BNDLO(A)
BNDU1:	TDNE C,DRMBIT(A)
	JRST DBTFU
	IORM C,DRMBIT(A)
	AOS DRMSC(B)
	AOS DRMFRE
	ADDI A,DRMBSZ
	AOBJN B,BNDU1
	JRST DRMSA2

BNDLUE:	JUMPL A,RETN
	CAIL A,DRMBND
	RET	 		;ILLEGAL ARGUMENT RETURN
	AOS (P)
	IDIVI A,44
	MOVN B,B
	MOVEI C,1
	LSH C,43(B)
	HRLZI B,-DRMSEC
	JRST (UNIT)

;INITIALIZE DRUM BIT TABLES

DRMINI:	MOVEI B,NDST		;[ISI]  table space available for DST
	IDIVI B,DRMSEC		;[ISI] Number of swapping bands
	PUSH P,B		;[ISI]
	IDIVI B,44		;[ISI] Set up bit table for 1st sector..
	MOVEI A,0		;[ISI]  Every one bit indicates free sector,
	SOJL B,.+3		;[ISI]  B/ number of words to init to -1
	SETOM DRMBIT(A)		;[ISI]
	AOJA A,.-2		;[ISI]
	SKIPE C			;[ISI]  C/ number of bits to set in partial word
	MOVN C,BITS-1(C)	;[ISI]
	MOVEM C,DRMBIT(A)	;[ISI]
	POP P,B			;[ISI]
	MOVE A,[XWD DRMBIT,DRMBIT+DRMBSZ]
	BLT A,DRMBIT+DRMSEC*DRMBSZ-1
	MOVE A,[XWD DRMBIT,BNDLO]
	BLT A,BNDLO+DRMBSZ-1	;INIT. BAND LOCKOUT TABLE TO ALL ONES
	MOVEI A,DRMSEC		;[ISI] Number of pages on drum
	IMULI A,0(B)		;[ISI]
	MOVEM A,DRMFRE
	MOVSI C,-DRMSEC		;[ISI]
	MOVEM B,DRMSC(C)	;[ISI] INITIALIZE FREE PAGE COUNT FOR EACH SECTOR
	AOBJN C,.-1		;[ISI]
	ASH B,6			;[ISI] No bands in use at or above this
	MOVEM B,MAXBND		;[ISI]

;INITIALIZE BAND LOCK OUT TABLE

	MOVE IOS,[POINT 18,DRMBBT]
DRMIN1:	ILDB A,IOS
	TRNE A,400000		;DONE ON -1 BYTE
	 JRST DRMIN2
	CALL BNDLK
	JFCL 0
	JFCL 0
	JRST DRMIN1		;[ISI]

DRMIN2:	MOVEI IOS,0
DRMIN4:	MOVE A,DRMBST(IOS)
	JUMPL A,RETN		;DONE ON -1
	CALL ASDRMS		;ASSIGN ALL THE BAD AREAS
	JFCL 0
	JFCL 0
	AOJA IOS,DRMIN4

DRMBBT:	-1
	BLOCK 6			;FOR OTHER BAD BANDS

DRMBST:	-1
	BLOCK 10

	END

