	.TITLE	DSPLAY
/
/   3 FEB 77 (015; PDH) USE THE 'WAIT' DIRECTIVE AFTER 'RAISEB'
/  18 JAN 77 (011; PDH) CONVERT TO XVM/RSX, INCLUDING BANK BOUNDARIES.
/  20 MAY 76 (010: PDH) CONVERT FOR USE WITH VT15.  THIS REVISION
/			DOES NOT HANDLE BANK BOUNDARY CROSSINGS.
/  26 MAR 76 (PDH) TURN ON ZERO TAGGED FILES CORRECTLY
/  12 JAN 76 (PDH) FIX UP 'RESERVE' CALL; TAGS ALWAYS .LE. 32767
/   7 JAN 76 (PDH) ENSURE THAT THERE IS FREE CORE FOR DISPLAY
/  18 DEC 75 (PDH) IRON OUT THE BUGS
/   1 OCT 75 (PDH) FINISH ENTERING CODE
/  26 SEP 75 (PDH) TYPE SOME MORE CODE IN
/  19 SEP 75 - PAUL HENDERSON
/
/  COMPLETE RE-WRITE OF SIMILAR ROUTINE ORIGINALLY DEVELOPED BY
/  KEN COOK IN 1971, AND MODIFIED BY JOHN WILSON
/
/  DEFAULT ASSEMBLY PRODUCES A WATRAN COMPATIBLE SUBROUTINE.
/  TO GENERATE A SUBROUTINE COMPATIBLE WITH DEC FORTRAN, THE SYMBOL
/
/F4=1		/MUST BE DEFINED.
/
/  GENERAL CALLING SEQUENCE:
/
/	CALL DSPLAY (FCN,TAG,ERROR,IVECT,FIRST,LAST)
/
/  RETURNED VALUES FOR 'ERROR'
/
/	ERROR = 0 - REQUESTED ACTION COMPLETE
/		1 - FILE NOT FOUND, FCN .EQ. 3
/		2 - NOT ENOUGH CORE - FILE TOO LARGE
/				    - FCN = 0, REQUEST MORE THAN AVAILABLE
/		3 - FILE NOT FOUND, FCN .NE. 3
/		4 - TAG USED
/		5 - ILLEGAL FUNCTION, OR FCN = 0 NOT FIRST CALL
/
	.EJECT
/  ************   DISPLAY FILE MANAGEMENT PHILOSOPHY   *****************
/
/
/
/       THE CONSTRUCTION OF THE BASIC DISPLAY FILE IN THE FORM  REQUIRED
/  BY  THE  340C  DISPLAY IS CARRIED OUT BY EITHER AN EXTERNAL PROCESSOR
/  SUCH AS 'VECTOR', 'MENUX', OR 'TEXT'.
/       THE TOTAL DISPLAY FILE AREA IS MANAGED IN BLOCKS  WHICH  CONSIST
/  OF A SEQUENCE  OF ADDRESS LOCATIONS,  EACH CONTAINING THE SIZE OF THE
/  BLOCK.  THE ADDRESS OF THE FIRST  LOCATION IS ALWAYS  FOUND IN GLOBAL
/  'BEGIN' SO THAT OTHER HANDLERS SUCH AS 'SETPEN' AND 'TEXT' MAY ACCESS
/  THESE DISPLAY FILES.
/
/       EACH  DISPLAY  FILE  IS CONTAINED IN A BLOCK WHICH CONSISTS OF A
/  SIZE WORD, A TAG WORD, AND A 'DRAW'  ADDRESS  WORD,  FOLLOWED  BY THE
/  ACTUAL  DISPLAY  FILE  AND TERMINATED BY A SUBROUTINE MODE WORD AND A
/  'DJP' INSTRUCTION  WHICH  POINTS TO THE  START  OF  THE  NEXT  ACTIVE
/  DISPLAY  FILE,  OR BACK TO THE BASIC  DISPLAY  FILE IF IT IS THE LAST
/  ACTIVE FILE.
/
/       THE SIZE WORD  CONTAINS THE TOTAL BLOCK SIZE UP TO THE NEXT SIZE
/  WORD,  OR UP TO THE END OF THE  TOTAL  AREA  IF IT IS THE LAST BLOCK.
/  THE SIZE WORD  ADDRESS  PLUS THE SIZE WILL ALWAYS GIVE THE ADDRESS OF
/  THE NEXT SIZE WORD.   IN ADDITION,  BIT  0  IS  SET  TO  INDICATE  AN
/  OCCUPIED BLOCK AND BIT 1 IS SET TO INDICATE THE LAST BLOCK.
/
/       THE TAG WORD CONTAINS THE TAG NUMBER ASSIGNED BY THE USER.  SUCH
/  TAGS MUST  BE UNIQUE (IF NON-ZERO),  POSITIVE,  AND NO  GREATER  THAN
/  32767,  OR DIAGNOSTICS WILL OCCUR.   A ZERO TAG IS PERMITTED, AND ANY
/  NUMBER OF THESE MAY BE  DUPLICATED.   BIT 0 OF THE TAG WORD IS SET TO
/  INDICATE A FILE WHICH IS ACTIVE, OR TO BE TURNED ON FOR DISPLAY.
/
/       THE  MANIPULATION  OF THE DISPLAY FILES IS BASED ENTIRELY ON THE
/  INFORMATION CONTAINED IN THE SIZE AND TAG WORDS.   THE ACTUAL TURNING
/  ON  AND  TURNING  OFF  OF  SPECIFIC  FILES  IS  ACCOMPLISHED  THROUGH
/  SUBROUTINE 'DRAW'.
/
/           *      *      *      *      *      *      *      *
/
/
/
/
/
	.EJECT
/  NOW COMES THE ACTUAL PROGRAM
/
IDX=ISZ		/ INDEX POINTER (SKIP NOT EXPECTED)
.SCOM=100
/
	.GLOBL	DSPLAY,BEGIN,CLEAR,CLOUDY,FILER,D.FIND,P.BASE
	.IFUND	F4
	.GLOBL	.ARG,DRAWS
	.ENDC
	.IFDEF	F4
	.GLOBL	.DA,DRAW
.ARG=.DA
DRAWS=DRAW
	.ENDC
/
DSPLAY	XX
	JMS*	.ARG
	JMP	SETUP
FCN
TAG
ERROR
IVECT
FIRST
LAST
SETUP	JMP	RESERVE+1	/ CHANGED TO 'DZM* ERROR' AFTER 1ST TIME
	LAW	-12
	TAD*	FCN		/ VALIDATE FUNCTION
	SMA!SZA
	JMP	ERR5		/ FCN > 8
	LAC*	FCN
	SPA!SNA
	JMP	ERR5		/ FCN < 1 (HAVE ALREADY CHECKED FCN=0)
	TAD	(JMP DSPCH1
	DAC	DSPCH1
DSPCH1	XX			/ DISPATCH TO CORRECT FUNCTION
	JMP	SAVE	/ 1
	JMP	PUTBCK	/ 2
	JMP	DELETE	/ 3
	JMP	TURNON	/ 4
	JMP	TURNOFF	/ 5
	JMP	SAVE	/ 6: FIRST 'SAVE', THEN 'TURNON'
	JMP	GARBAGE	/ 7
	JMP	CLEAN	/ 8
/
	.EJECT
/  THIS SECTION IS INVOKED ONLY ON THE VERY FIRST CALL TO 'DSPLAY'.
/  AFTER USE, IT IS CONVERTED TO VARIABLE WORKING STORAGE.
/
BEGIN	(200000		/ POINT TO EMPTY BLOCK IF NO ROOM FOR FILES
END	0		/ END OF DISPLAY AREA
SIZE	0		/ DEFAULT SIZE WHEN NO FREE CORE & FCN = 0
R.GET	SIZE		/ POINTER IN CASE 1ST CALL NOT FCN 0.
/
RESERVE	SETUP			/ RETURN POINTER IF FCN .NE. 0
DZMERR	DZM*	ERROR		/ INITIALLY SET ERROR = 0
FTAG	LAC	DZMERR		/ CHANGE 'JMS  RESERVE'
GTAG	DAC	SETUP		/   TO   'DZM* ERROR'
	LAC*	FCN
DLAST	SZA			/ DO WE HAVE FCN = 0 ?
MSIZE	JMP	NOTF0
/
/  SOME PRELIMINARY SETUP REQUIRED WHEN FCN = 0.
/
PSIZE	LAC	DSPLAY		/ RETURN TO CALLING PROGRAM WHEN
FILEPT	DAC	RESERVE		/ FINISHED WITH RESERVATION
TAGPNT	LAC	IVECT
P.FP	DAC	R.GET		/ FETCH ACTUAL ADDRESS OF 'GET'
/
	.EJECT
NOTF0	LAC	(250		/ PBDL LISTHEAD
LOOK	JMS	LOOKUP		/ GET ADDRESS OF UNKNOWN PBDL
	DAC	P.FP		/ SAVE FORWARD POINTER
NEWPT	AAC	4
NEWBLK	JMS	LOOKUP		/ GET BASE ADDRESS OF UNKNOWN PBDL AND
BLKTYPE	SAD*	P.BASE		/ COMPARE IT WITH 'OUR' PARTITION
GBSIZE	JMP	FOUND
	LAC	P.FP		/ NOT CORRECT ONE YET.
	JMP	LOOK		/ TRY THE NEXT ONE
/
FOUND	LAC	P.FP
	AAC	6		/ GET TASK SIZE WHICH IS ALSO
BPSIZE	JMS	LOOKUP		/ THE FIRST FREE ADDRESS IN THIS PARTITION
BMSIZE	CAL	RAISEB		/ GET ALL THE FREE SPACE
BGNBIT	CAL	(5		/ WAIT FOR NEXT SIGNIFICANT EVENT
ENDBIT	LAW	-1
	TAD	SPYCON		/ CALCULATE SIZE OF DISPLAY AREA
	TCA
	TAD	END
	SMA
	JMP	SVSIZE		/ SIZE OK
	DZM*	R.GET		/ RETURN ZERO IF NO FREE CORE
	JMP	ERR2		/ ALSO RETURN ERROR CODE
/
SVSIZE	DAC	SIZE		/ SAVE SIZE
	DAC*	R.GET		/ ALSO RETURN IT TO USER
	LAC	SPYCON
	DAC	BEGIN		/ SAVE START ADDRESS OF DISPLAY FILE AREA
	LAC	SIZE		/ BUILD FIRST DISPLAY BLOCK
	XOR	(200000		/ INDICATE UNOCCUPIED, LAST
	DAC*	BEGIN
	LAC	BEGIN
	JMS	BANKS		/ DIVIDE AREA AT BANK BOUNDARIES
	LAC*	TAG		/ COMPARE REQUESTED SIZE
	TCA
	TAD	SIZE		/ WITH ACTUAL SIZE
	SMA
	JMP*	RESERVE
	LAC	(2		/ SET ERROR = 2 IF ASK .LT. GET
	DAC*	ERROR		/ IF FCN .NE. 0, ERROR WILL BE RESET
	JMP*	RESERVE		/ 'RETURN' OR CONTINUE
/
/  END OF 1ST TIME ONLY CODE
/
	.EJECT
/  FCN = 1  OR  FCN = 6: TRANSFER USER FILE TO DISPLAY AREA
/
SAVE	LAC*	TAG		/ GET TAG NUMBER
	AND	(77777		/ MAXIMUM LEGAL TAG VALUE IS 32767
	SZA			/ ZERO TAGS ARE NOT CHECKED
	JMS	D.FIND		/ DOES THIS NON-ZERO TAG ALREADY EXIST?
	SKP
	JMP	ERR4		/ YES.  RETURN ERROR CODE AND EXIT
	LAW	-3
	TAD*	FIRST		/ WE REQUIRE A BLOCK OF MEMORY TO
	TCA			/ INCLUDE THE SIZE AND TAG WORDS.
	TAD*	LAST		/ REQUIRED SIZE IS (LAST-FIRST+3)
	DAC	PSIZE
	TCA
	DAC	MSIZE		/ ALSO SAVE NEGATIVE OF REQUIRED SIZE
RESAVE	LAC	BEGIN		/ BEGINNING ADDRESS OF DISPLAY AREA
/
/  IN THIS SECTION WE SEARCH FOR A FREE BLOCK WITH
/  SUFFICIENT ROOM FOR THE DISPLAY FILE.
/
SAVE2	DAC	FILEPT
	LAC*	FILEPT
	AND	(200000
	DAC	BLKTYPE		/ SAVE BLOCK TYPE (LAST OR NOT-LAST)
	LAC*	FILEPT
	SPA
	JMP	S.OCC		/ BLOCK IS OCCUPIED.  TRY FOR NEXT ONE
	AND	(77777		/ GET RID OF BITS NOT IN SIZE
	TAD	MSIZE		/ COMPARE WITH REQUIRED SIZE
	SMA
	JMP	SIZEOK		/ SIZE ADEQUATE
/
S.OCC	LAC*	FILEPT		/ CHECK FOR LAST BLOCK
	RAL
	SPA!RAR
	JMP	S.GBG		/ LAST BLOCK.  PERFORM FINAL CHECK
	TAD	FILEPT		/ NOT LAST BLOCK.  UPDATE FILE POINTER
	JMP	SAVE2		/ AND CHECK NEXT BLOCK
/
/  WE HAVE REACHED THE END OF THE DISPLAY AREA WITHOUT FINDING A
/  LARGE ENOUGH BLOCK.  PERFORM A GARBAGE COLLECTION TO SEE IF THIS
/  WILL FREE UP ENOUGH SPACE FOR THE FILE.
/
S.GBG	JMS	GRBG		/ RETURNS WITH AVAILABLE SIZE IN AC
	TAD	MSIZE
	SMA
	JMP	RESAVE		/ ENOUGH SPACE NOW AVAILABLE.  GO FIND IT.
	JMP	ERR2
/
	.EJECT
/  WE HAVE FOUND A SPACE BIG ENOUGH FOR THE NEW FILE.  MUST CHECK FOR
/  SPECIAL CASE OF EXACT FIT.  AC CONTAINS SPACE REMAINING IN
/  CURRENT UNOCCUPIED BLOCK.
/
SIZEOK	SNA
	JMP	S.MOVE		/ BLOCK ALREADY DESCRIBED.  MOVE THE DATA
	XOR	BLKTYPE		/ GENERATE COMPLETE DESCRIPTOR FOR
	DAC	NEWBLK		/ NEW FREE BLOCK
	LAC	PSIZE
	DAC*	FILEPT		/ STORE SIZE FOR NEW OCCUPIED BLOCK
	TAD	FILEPT
	DAC	NEWPT		/ POINTER TO NEW FREE BLOCK
	LAC	NEWBLK
	DAC*	NEWPT		/ STORE FREE BLOCK DESCRIPTOR
/
/  DISPLAY BLOCKS ARE NOW UPDATED.  INDICATE AS OCCUPIED, AND
/  MOVE IN DISPLAY FILE.
/
S.MOVE	LAC*	FILEPT		/ GET SELECTED BLOCK DESCRIPTOR.
	XOR	(400000		/ SET 'OCCUPIED' BIT
	DAC*	FILEPT
	IDX	FILEPT		/ POINT TO TAG LOCATION
	ISZ	MSIZE		/ COUNT BLOCK DESCRIPTOR WORD
	LAC*	TAG		/ GET TAG FROM USER
	DAC*	FILEPT
	IDX	FILEPT
	ISZ	MSIZE		/ COUNT TAG DESCRIPTOR WORD
	LAW	-1
	TAD*	FIRST		/ CALCULATE ADDRESS OF
	TAD	IVECT		/ USER DATA ARRAY
	DAC	IVECT		/ POINTER TO DATA
S.LOOP	LAC*	IVECT		/ MOVE USER DATA
	DAC*	FILEPT		/ TO DISPLAY AREA
	IDX	IVECT
	IDX	FILEPT
	ISZ	MSIZE
	JMP	S.LOOP
/
/  THE FILE HAS BEEN MOVED IN.  CHECK TO SEE IF IT SHOULD BE TURNED ON.
/
	LAC*	FCN
	SAD	(6
	JMS	TRNON		/ TURN ON FILE IF FCN=6
	JMP	RETURN
	.EJECT
/  FCN = 2:  COPY DISPLAY FILE TO USER ARRAY
/
PUTBCK	LAC*	TAG
	JMS	D.FIND		/ SEARCH FOR SPECIFIED FILE
	JMP	ERR3		/ ERROR IF NOT FOUND
	AAC	2
	DAC	DIVECT		/ ADDRESS OF ACTUAL DISPLAY FILE
	LAW	-1
	TAD*	FIRST
	TAD	IVECT		/ CALCULATE USER ARRAY ADDRESS
	DAC	IVECT
	LAW	-3
	TAD*	FILEPT		/ TOTAL STORAGE USED WAS (LAST-FIRST+3)
	TAD*	FIRST
	AND	(77777
	DAC*	LAST		/ RETURN 'LAST' TO USER
	LAW	-3
	TAD*	FILEPT
	AND	(77777
	CMA
	DAC	MSIZE		/ SIZE OF DISPLAY FILE TO BE RETURNED
P.LOOP	LAC*	DIVECT
	DAC*	IVECT		/ COPY DISPLAY FILE
	IDX	DIVECT
	IDX	IVECT
	ISZ	MSIZE		/ WHEN FINISHED WITH LOOP,
	JMP	P.LOOP		/ FALL INTO 'DELETE'
/
/  FCN = 3:  DELETE SPECIFIED FILE
/
DELETE	JMS	TRNOFF		/ TURN OFF FILE FIRST
	JMP	ERR1		/ NOT FOUND (MAY BE END OF ZERO TAGS)
	LAC*	FILEPT
	AND	(377777
	DAC*	FILEPT		/ MARK BLOCK AS UNOCCUPIED
	JMS	DWAIT		/ WAIT UNTIL TRULY DISCONNECTED
	LAC*	TAG
	SNA
	JMP	DELETE		/ DELETE ALL ZERO TAGGED FILES
	JMP	RETURN
/
	.EJECT
/  FCN = 4:  TURN ON SPECIFIED FILE
/
TURNON	JMS	TRNON
	JMP	RETURN
/
/  FCN = 5:  TURN OFF SPECIFIED FILE
/
TURNOFF	JMS	TRNOFF		/ TURN OFF FILE
	JMP	ERR3		/ ERROR IF FILE NOT FOUND
	JMP	RETURN
/
/  FCN = 7:  PERFORM GARBAGE COLLECTION
/
GARBAGE	JMS	GRBG		/ DO IT
	DAC*	TAG		/ RETURN SIZE TO CALLING PROGRAM
	JMP	RETURN
/
/  FCN = 8:  WIPE OUT COMPLETE DISPLAY AREA, AND CALL CLEAR
/
CLEAN	JMS*	CLEAR
	LAC	SIZE
	DAC*	TAG		/ RETURN SIZE TO CALLER
	XOR	(200000		/ SET ENTIRE AREA TO FREE, LAST BLOCK
	DAC*	BEGIN
	LAC	BEGIN
	JMS	BANKS		/ DIVIDE AT BANK BOUNDARIES
	JMP	RETURN
/
/  ALL TERMINAL ERRORS COME THROUGH HERE
/
ERR5	LAC	(5
	SKP
ERR4	LAC	(4
	SKP
ERR3	LAC	(3
	SKP
ERR2	LAC	(2
	SKP
ERR1	LAC	(1
	DAC*	ERROR		/ RETURN ERROR NUMBER TO CALLER
RETURN	JMP*	DSPLAY		/ RETURN TO CALLING PROGRAM
/
	.EJECT
/  THIS IS A SUBROUTINE TO IMPOSE BLOCKS ON THE FREE DISPLAY AREA SO
/  THAT NO FREE BLOCK STRADDLES A BANK BOUNDARY, THUS ENSURING
/  THAT WE DO NOT HAVE A 'BAD' DISPLAY FILE.  IT IS CALLED AFTER THE
/  INITIALIZATION, AFTER FCN=8, AND AFTER A GARBAGE COLLECTION.
/
/  CALLING SEQUENCE:
/
/	LAC	START ADDRESS	/ ADDRESS TO BEGIN IMPOSING BANK STRUCTURE
/	JMS	BANKS
/	(RETURN)
/
BANKS	XX
	DAC	FILEPT		/ SAVE BEGINNING ADDRESS
	LAC*	FILEPT
	AND	(177777		/ GET SIZE OF FREE AREA
	DAC	BPSIZE
/
BANKS2	LAC	FILEPT
	AND	(160000
	DAC	BGNBIT		/ BANK BITS FOR BEGINNING OF DISPLAY AREA
	LAC	END
	AND	(160000
	DAC	ENDBIT		/ BANK BITS FOR END OF AREA
	SAD	BGNBIT		/ DO THEY MATCH?
	JMP*	BANKS		/ ALL IS OK WHEN THEY MATCH
/
	LAC	BGNBIT
	TAD	(20000		/ ADDRESS OF NEXT HIGHER BANK BOUNDARY
	TCA
	TAD	FILEPT		/ NEGATIVE OF FREE SPACE THIS BANK
	DAC	BMSIZE
	TCA
	DAC*	FILEPT		/ USE POSITIVE SIZE AS BLOCK DESCRIPTOR
	TAD	FILEPT
	DAC	FILEPT		/ UPDATE FILE POINTER
	LAC	BPSIZE		/ SIZE OF FREE AREA BEFORE BANK DIVISION
	TAD	BMSIZE		/ LESS SIZE OF BLOCK BELOW DIVISION
	DAC	BPSIZE		/ GIVES SIZE REMAINING ABOVE DIVISION
	XOR	(200000
	DAC*	FILEPT		/ INDICATE AS LAST BLOCK
	JMP	BANKS2		/ NOW SEE IF WE HAVE TO ADJUST AGAIN
/
	.EJECT
/  SUBROUTINE TO TURN OFF DISPLAY FILE AND CLEAR 'TURNED ON' BIT
/
/  CALLING SEQUENCE:
/
/	JMS	TRNOFF
/	(RETURN IF FILE FOUND)
/	(RETURN IF FILE NOT FOUND)
/
TRNOFF	XX
	LAC*	TAG
	JMS	D.FIND		/ SEARCH FOR SPECIFIED FILE
	JMP*	TRNOFF		/ EXIT IF FILE NOT FOUND
	JMS	DDRAW
	DZM	DLAST		/ TURN OFF FILE
	NOP
	IDX	TRNOFF		/ INDEX TO 'FOUND' EXIT
	JMP*	TRNOFF
/
/  SUBROUTINE TO TURN ON A DISPLAY FILE AND SET 'TURNED ON' BIT
/
/  CALLING SEQUENCE:
/
/	JMS	TRNON
/	(RETURN)
/
TRNON	XX
	LAC*	TAG
	JMS	D.FIND		/ SEARCH FOR SPECIFIED FILE
TRNON0	JMP	ERT3		/ ERROR IF FILE NOT FOUND
	JMS	DDRAW
	DAC	DLAST		/ TURN FILE ON
	XOR	(400000		/ SET 'TURNED ON' BIT
	LAC*	TAG
	SZA			/ WAS THIS A ZERO TAG?
	JMP*	TRNON		/ NO.  RETURN NORMALLY.
/
	LAC	(TRNON0
	DAC	D.FIND		/ PREPARATION REQUIRED BEFORE WE
	JMP	CKLAST		/ JUMP BACK INTO INTERRUPTED 'D.FIND'
/
ERT3	LAC*	TAG		/ COME HERE WHEN FILE NOT FOUND
	SNA
	JMP*	TRNON		/ NO ERROR WHEN FILE NOT FOUND IF TAG = 0
	JMP	ERR3		/ TAG .NE. 0; FILE NOT FOUND
/
	.EJECT
/  SUBROUTINE TO CONNECT OR DISCONNECT DISPLAY FILES VIA 'DRAW'.
/  ENTER WITH ADDRESS OF DISPLAY AREA DESCRIPTOR BLOCK IN AC AND
/  IN 'FILEPT' (AS GENERATED BY 'D.FIND').  CALCULATE VALUE OF
/  'LAST', THEN EXECUTE INTRUCTION TO SET OR CLEAR 'DLAST'.  BIT
/  TO INDICATE 'TURNED ON' IS ALSO SET OR CLEARED BY EXECUTING AN
/  INSTRUCTION.  THIS INSTRUCTION IS ALSO EXECUTED ON EXIT TO REDUCE
/  MEMORY REQUIREMENTS.
/
/  CALLING SEQUENCE:
/
/	LAC	(DESCRIPTOR BLOCK ADDRESS
/	JMS	DDRAW
/	INSTR1			/ 'DAC DLAST' OR 'DZM DLAST'
/	INSTR2			/ 'NOP' OR 'XOR (400000'
/				/ 'DDRAW' RETURNS TO INSTR2
DDRAW	XX
	AAC	2
	AND	(77777		/ REMOVE STATUS BITS
	DAC	DIVECT		/ ADDRESS OF ACTUAL DISPLAY FILE
	LAW	-2
	TAD*	FILEPT		/ CALCLUATE VALUE FOR 'DLAST'
	AND	(77777		/ REMOVE POSSIBLE STATUS BITS FROM SIZE
	XCT*	DDRAW		/ 'DAC DLAST' OR 'DZM DLAST'
	IDX	DDRAW		/ INDEX TO SECOND ARGUMENT
	JMS*	DRAWS		/ CALL 'DRAW' APPROPRIATELY
	JMP	.+4
DIVECT	XX
	(1
	DLAST
	LAC*	TAGPNT
	AND	(377777		/ CLEAR 'TURNED ON' BIT
	XCT*	DDRAW		/ SET BIT AGAIN IF REQUESTED
	DAC*	TAGPNT
	JMP*	DDRAW
/
	.EJECT
/  SUBROUTINE TO LOCATE TAGGED FILE.  ON EXIT, ADDRESS OF BLOCK
/  DESCRIPTOR IS IN AC AND IN 'FILEPT', AND ADDRESS OF TAG DESCRIPTOR
/  IS IN 'TAGPNT'.
/
/  CALLING SEQUENCE:
/
/	LAC	TAG
/	JMS	D.FIND
/	(RETURN IF NOT FOUND)
/	(RETURN IF TAG FOUND)
/
D.FIND	XX
	DAC	FTAG
	LAC	BEGIN		/ GET START ADDRESS OF DISPLAY AREA
FIND2	DAC	FILEPT
	DAC	TAGPNT
	IDX	TAGPNT		/ POINT TO TAG WORD LOCATION
	LAC*	FILEPT
	SMA			/ IS IT AN OCCUPIED BLOCK?
	JMP	CKLAST		/ NO.  BYPASS TAG CHECK
	LAC*	TAGPNT
	AND	(77777		/ IS IT CORRECT TAG?
	SAD	FTAG
	SKP
	JMP	CKLAST		/ NOT SPECIFIED TAG.
	LAC	FILEPT		/ TAG FOUND.  GET ADDRESS
	IDX	D.FIND		/ INDEX TO 'FOUND' EXIT
	JMP*	D.FIND
/
CKLAST	LAC*	FILEPT
	RAL
	SPA!RAR			/ IS IT LAST BLOCK?
	JMP*	D.FIND		/ YES.  TAKE 'NOT FOUND' EXIT
	TAD	FILEPT
	JMP	FIND2		/ NOT YET.  LOOK AT NEXT BLOCK
/
	.EJECT
/  THIS SUBROUTINE PERFORMS THE ACTUAL GARBAGE COLLECTION.  METHOD IS
/  TO TURN ALL FILES OFF, MOVE FILES DOWN IN MEMORY TO FILL UP ANY 
/  HOLES CAUSED BY DELETIONS, THEN TURN BACK ON THE FILES WHICH WERE
/  PREVIOUSLY TURNED ON.
/
GRBG	XX
	JMS	G.ONOFF		/ TURN OFF ALL DISPLAY FILES
	DZM	DLAST		/ EXECUTED FROM 'DDRAW'
/
/  WE HAVE NOW TURNED OFF ALL DISPLAY FILES.  WAIT UNTIL DISCONNECT
/  IS COMPLETE, THEN SHUFFLE THE FILES.
/
GWAIT	JMS	DWAIT
	LAC	BEGIN
	DAC	NEWPT		/ RUNNING POINTER TO NEW STRUCTURE
GRBG2	DAC	FILEPT		/ RUNNING POINTER TO OLD STRUCTURE
GRBG3	LAC*	FILEPT
	SPA			/ IS BLOCK EMPTY OR OCCUPIED?
	JMP	G.OCC
	RAL
	SPA!RAR			/ BLOCK IS EMPTY.  IS IT ALSO LAST BLOCK?
	JMP	GSIZE
	TAD	FILEPT		/ NOT LAST BLOCK.  STEP PAST EMPTY BLOCK
	JMP	GRBG2		/ AND CONTINUE SEARCH
/
G.OCC	AND	(77777		/ BLOCK IS OCCUPIED
	TCA
	DAC	GBSIZE
	CMA			/ 'TCA' -1
	TAD	NEWPT
	AND	(160000		/ BANK BITS FOR END OF MOVED DISPLAY FILE
	DAC	ENDBIT
	LAC	NEWPT
	DAC	DLAST		/ POINTER TO LAST BLOCK MOVED
	AND	(160000		/ BANK BITS FOR BEGINNING OF
	DAC	BGNBIT		/ MOVED DISPLAY FILE
	SAD	ENDBIT
	JMP	GMOVE		/ BITS MATCH.  OK TO MOVE FILE
	TAD	(20000		/ BANK BITS FOR NEW DISPLAY BLOCK WHICH
	DAC	NEWPT		/ BEGINS ON NEXT BANK BOUNDARY
	TCA
	TAD	DLAST		/ NEGATIVE OF SIZE OF UNUSEABLE BLOCK
	TCA
	DAC*	DLAST		/ EMPTY BLOCK UP TO END OF BANK
	LAC	NEWPT
	DAC	DLAST
/
	.EJECT
GMOVE	LAC*	FILEPT
	DAC*	NEWPT		/ MOVE BLOCK
	IDX	FILEPT
	IDX	NEWPT
	ISZ	GBSIZE
	JMP	GMOVE
/
/  WE HAVE NOW MOVED THE BLOCK.  CHECK TO SEE IF IT WAS THE LAST BLOCK
/
	LAC*	DLAST
	RAL
	SMA
	JMP	GRBG3		/ NOT LAST BLOCK.  CONTINUE PROCESS.
/
/  WE HAVE REACHED THE END OF THE DISPLAY AREA.  CALCULATE SIZE OF
/  REMAINING FREE AREA, AND ALSO UPDATE THE LAST BLOCK INDICATOR.
/
GSIZE	LAW	-1
	TAD	NEWPT
	TCA
	TAD	END		/ END-NEWPT+1
	DAC	GBSIZE
	SNA!SPA
	JMP	GB.ON		/ NO FREE CORE REMAINING.
	XOR	(200000		/ INDICATE AS LAST BLOCK
	DAC*	NEWPT		/ UPDATE LAST BLOCK
	LAC*	DLAST
	AND	(577777		/ PREVIOUS LAST BLOCK NO LONGER SO.
	DAC*	DLAST		/ REMOVE INCRIMINATING EVIDENCE.
	LAC	NEWPT		/ SLICE UP REMAINING FREE AREA
	JMS	BANKS		/ AT BANK BOUNDARIES
/
GB.ON	JMS	G.ONOFF		/ TURN ON APPROPRIATE FILES
	DAC	DLAST
	LAC	GBSIZE		/ RETRIEVE FREE SPACE LEFT
	JMP*	GRBG
/
	.EJECT
/  SUBROUTINE ACCESSED BY THE GARBAGE COLLECTION SUBROUTINE.
/  IT TURNS OF OR ON ALL THE DISPLAY FILES TAGGED AS BEING ON.
/
/  CALLING SEQUENCE:
/
/	JMS	G.ONOFF
/	INSTR			/ DZM DLAST TO TURN FILES OFF
/				/ DAC DLAST TO TURN FILES ON
/				/ 'INSTR' IS ALSO EXECUTED ON EXITT.
/
G.ONOFF	XX
	LAC*	G.ONOFF		/ CANNOT PERFORM XCT OF XCT
	DAC	G.XCT		/ FROM USER MODE TASK
	LAC	BEGIN
GB2	DAC	FILEPT
	DAC	TAGPNT
	IDX	TAGPNT		/ INDEX TO TAG WORD
	LAC*	TAGPNT
	SMA			/ DETERMINE IF FILE WAS ON
	JMP	GLAST
	DAC	GTAG		/ SAVE TAG WORD ENTRY INTACT
	LAC*	FILEPT
	SMA			/ NOW DECIDE IF BLOCK IS OCCUPIED.
	JMP	GLAST
	LAC	FILEPT		/ GET ACTUAL FILE POINTER
	JMS	DDRAW		/ BLOCK OCCUPIED AND FILE TURNED ON
G.XCT	XCT*	G.ONOFF		/ TURN FILE ON OR OFF, AS APPROPRIATE
	LAC	GTAG		/ RESTORE TAG WORD ENTRY (FROM 'DDRAW')
/
GLAST	LAC*	FILEPT		/ CHECK FOR LAST BLOCK
	RAL
	SPA!RAR
	JMP*	G.ONOFF		/ RETURN AFTER PROCESSING LAST BLOCK
	TAD	FILEPT
	JMP	GB2		/ POINT TO NEXT BLOCK IN STRING.
/
	.EJECT
/  SUBROUTINE TO WAIT FOR DISPLAY TO CYCLE.  THIS IS NEEDED AFTER A
/  DELETION TO ENSURE THAT WE NEVER OVER-WRITE A NEWLY DELETED DISPLAY
/  WHILE IT IS STILL BEING DISPLAYED FOR THE LAST TIME.  ON THE PDP-15,
/  CLOUDY IMMEDIATELY STOPS THE DISPLAY AND INVOKES THE SPECIFIED
/  SUBROUTINE, IN THIS CASE, 'DFLAG'.
/
DWAIT	XX
	JMS*	CLOUDY
	JMP*	DWAIT
	DFLAG
/
DFLAG	XX			/ SUBROUTINE CALLED WHEN DISPLAY STOPS.
	JMP*	DFLAG
/
/  SUBROUTINE 'LOOKUP' DOES A SPY AT THE ADDRESS SPECIFIED
/  IN THE ACCUMULATOR AT ENTRY.  THE CONTENTS OF THE ADDRESS ARE
/  IN THE AC ON EXIT.
/
LOOKUP	XX
	DAC	SPYADR
	CAL	SPY
	LAC	SPYCON
	JMP*	LOOKUP
/
SPY	31;	0;SPYADR;SPYCON
RAISEB	27;	END
	.END
