/CLOCK HANDLER FOR RTS8 V2			8/30/74
/
/
/
/
/
/
/
/
/
/COPYRIGHT  (C)  1974,1975 BY DIGITAL EQUIPMENT CORPORATION
/
/
/
/
/
/
/
/
/
/
/THE INFORMATION IN THIS DOCUMENT IS SUBJECT TO CHANGE WITHOUT NOTICE
/AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
/CORPORATION.  DIGITAL EQUIPMENT CORPORATION ASSUMES NO RESPONSIBILITY
/FOR ANY ERRORS THAT MAY APPEAR IN THIS DOCUMENT.
/
/THE SOFTWARE DESCRIBED IN THIS DOCUMENT IS FURNISHED TO THE PURCHASER
/UNDER A LICENSE FOR USE ON A SINGLE COMPUTER SYSTEM AND CAN BE COPIED
/(WITH INCLUSION OF DIGITAL'S COPYRIGHT NOTICE) ONLY FOR USE IN SUCH
/SYSTEM, EXCEPT AS MAY OTHERWISE BE PROVIDED IN WRITING BY DIGITAL.
/
/DIGITAL EQUIPMENT CORPORATION ASSUMES NO RESPONSIBILITY FOR THE USE
/OR RELIABILITY OF ITS SOFTWARE ON EQUIPMENT THAT IS NOT SUPPLIED BY
/DIGITAL.
/
/
/
/
/
/
/
/
/
/

/THE RTS-8 CLOCK HANDLER ACCEPTS MESSAGES FROM THE USER AND INSERTS
/ENTRIES INTO A CLOCK QUEUE.  AS ENTRIES IN THE CLOCK QUEUE BECOME
/DUE, THEY ARE REMOVED FROM THE QUEUE AND THE REQUEST ISS DECODED
/AND EXECUTED.

/THE CLOCK HANDLER MUST RUN IN FIELD 0 AS IT IS TREATED SPECIALLY
/BY THE INTERRUPT CODE IN RTS-8

/THE FORMAT OF CLOCK MESSAGES ARE:

/WORD 1		USED AS EVENT FLAG FOR MESSAGE
/WORDS 2-3	USED BY RTS-8
/WORD 4		COMMAND WORD - BITS ARE:
/    BITS 0-2	FUNCTION:
/		   0 -	SET EVENT FLAG AFTER TIMED INTERVAL
/		   1 -	RUN SPECIFIED TASK AFTER INTERVAL
/		   2 -	DERAIL SPECIIFIED TASK AFTER INTERVAL
/		   3 -	RUN SPEC. TASK PERIODICALLY AFTER INTERVAL
/	   5,6, OR 7 -	CANCEL ALL TIMED REQUESTS FOR SPECIFIED TASK
/
/    BITS 5-11  SPECIFY TASK - 0 MEANS TASK IS SENDING TASK
/WORD 5		HIGH ORDER OF TIME (IN TICKS)
/WORD 6		LOW ORDER OF TIME
/WORDS 7-8(OPT)	DERAIL ADDRESS OR RESCHEDULE PERIOD

/FORMAT OF CLOCK QUEUE ENTRY:

/WORD 1		POINTER TO NEXT ENTRY (0 IF LAST)
/WORD 2 AND 3	NUMBER OF TICKS FROM PREV ENTRY UNTIL THIS ONE -
/		NUMBER IS NEGATIVE, LOW ORDER IN WORD 2
/WORD 4		COMMAND WORD (FROM MESSAGE)
/WORD 5 AND 6	WORDS 7 AND 8 OF MESSAGE (ADDR OF MESSAGE IF FN=0)
/THIS CLOCK HANDLER WILL RUN ON MANY HARDWARE CONFIGURATIONS
/THE PARAMETER "CLKTYP" CONTROLS THE CONFIGURATION
/LEGAL VALUES OF CLKTYP ARE:

/	0	DK8EA LINE CLOCK, DK8EC CRYSTAL CLOCK
/	1	KW12A PROGRAMMABLE CLOCK
/	2	PDP 8/A CLOCK (INCLUDED ON OPTION BOARD 1 OF PDP8A)
/	3	DK8EP PROGRAMMABLE CLOCK
/  4,6,10,ETC	USER-DEFINED CLOCK TYPES

/VARIOUS CLOCK IOT DEFINITIONS:

	IFZERO	CLKTYP	<
CLSK=	6133
CLEI=	6131
CLDI=	6132
	>
	IFNZRO	CLKTYP&1	<	/KW12 AND DK8EP IOT'S
CLZE=	6130	/DK8EP ONLY!
CLSK=	6131
CLLR=	6132	/CALLED CLDE ON DK8EP
CLAB=	6133
CLEN=	6134
CLSA=	6135
	>
	IFZERO	CLKTYP-2	<
CLEN=	6135	/PDP 8/A CLOCK INTERRUPT ENABLE
CLCL=	6136	/PDP 8/A CLOCK FLAG CLEAR
CLSK=	6137	/PDP 8/A CLOCK SKIP
	>

	IFNZRO	CLKTYP&1 <HERTZ= 1750>	/FORCE DK8EP,KW12 TO 1 KHZ

TICKS=	HERTZ%SHERTZ

	IFNZRO	TICKS^SHERTZ-HERTZ	<RATERR,_ERROR_>
	IFZERO	SHERTZ-300&4000		<TODERR,_ERROR_>

/CLOCK TASK PAAMETERS:

TASK=	CLOCK
INIWT=	0
CUR=	0		/** MUST RUN IN FIELD 0! **

	FIELD 0
	*10		/AUTO XR - NO-ONE ELSE SHOULD USE!
CLKXR,	0		/MARK XR USED ON BITMAP
/THIS IS THE CLOCK QUEUE CREATOR - IT IS INVOKED WHEN THE CODE
/AT "CLKLP" NOTICES THAT THE INPUT MESSAGE QUEUE IS NON-EMPTY.

	IFNDEF	SWAPPER	<
	ENDEXC=	NTASKS+1^7+1200		/ORIGIN JUST ABOVE SWAPPER, IF ANY
	>
	IFDEF	SWAPPER	<
	ENDEXC=	PARTNS^4+PARTBL+577&7600	/ELSE JUST ABOVE EXEC TABLES
	>
	*ENDEXC
	PAGE		/START LOADING IN FIRST PG AFTER TABLES OR SWAPPER

GETMSG,	CAL
	RECEIV		/GET MESSAGE ADDRESS
MADDR,	0
	DCA	MSGCDF	/CDF IS IN AC ON RETURN
XTRA1,			/INITIALIZED IN CASE FUNCT IS "SET E.F."
MSGCDF,	HLT		/SET TO DF OF MESSAGE
	AC7775		/SABVE ADDRESS OF MESSAGE EVENT FLAG
	TAD	MADDR	/IN XTRA2 - XTRA1&2 ARE NOW SET UP
	DCA	XTRA2	/IN CASE COMMAND WAS "SET EVENT FLAG"
	TAD I	MADDR	/GET COMMAND
	AND	(177
	SNA CLA		/CHECK FOR EXPLICIT TASK ARGUMENT
	TAD I	XTRA2	/NONE - USE SENDING TASK
	AND	(177	/(MESSAGE E.F. MAY HAVE 4000 BIT ON)
	TAD I	MADDR
	DCA	CLKCMD	/SAVE CLOCK COMMAND
	TAD	MSGCDF
	DCA	CT	/SET UP CDF OF EVENT FLAG IN "POST" CALL
	TAD	MADDR
	DCA	CLKXR	/SET UP AUTO-XR FOR FETCHING ARGS
	TAD I	CLKXR	/GET HIGH ORDER INTERVAL
	DCA	TH	/SAVE IT
	TAD I	CLKXR	/GET LOW ORDER INTERVAL
	SNA		/IF ZERO, MAKE IT 1 - THIS INTRODUCES A SMALL
	IAC		/(LT .025%) ERROR IN SOME INTERVALS, BUT
	DCA	TL	/ELIMINATES THE KILLER 0 INTERVAL
	TAD	CLKCMD	/GET COMMAND
	RTL
	SNL SMA CLA	/CHECK FOR "SET EVENT FLAG" COMMAND
	JMP	NOIMEF	/YES - SO DON'T SET EVENT FLAG NOW
	TAD I	CLKXR	/GET TWO MORE ARGUMENTS EVEN THOUGH WE
	DCA	XTRA1	/ONLY NEED THEM FOR COMMANDS 2 AND 3.
	TAD I	CLKXR
	DCA	XTRA2
	AC7775		/WE MUST FIGURE OUT WHERE THE
	TAD	MADDR	/MESSAGE STARTED SINCE WE DESTROYED XTRA2
	CAL
	POST
CT,	0

NOIMEF,	JMS	CLQINS	/NOW INSERT THE MESSAGE INTO THE CLOCK QUEUE
	JMP I	(CLKLP
/SEARCH THE CLOCK QUEUE TO FIND WHERE TO PUT THIS REQUEST

/THE REQUEST TO BE QUEUED SHOULD BE IN THE WORDS:
/CLKCMD, TH, TL, XTRA1, XTRA2

CLQINS,	0
	CDF CUR
	TAD	(CLQ
QSRCLP,	DCA	CQ
	TAD I	CQ	/GET NEXT QUEUE ENTRY
	DCA	CT
	TAD	CT
	DCA	CLKXR	/ACCESS BODY OF QUEUE ENTRY WITH AUTO-XR
	TAD I	CT
	CLL		/INHIBIT INTS WHILE LOOKING AT Q ENTRY
	IOF		/TO KEEP IT FROM CHANGING ON US.
	SNA CLA		/IS IT THE TERMINAL ONE?
	JMP	INHERE	/YES - INSERT HERE
	TAD I	CLKXR
	TAD	TL
	DCA	TTL	/SUBTRACT INTERVAL TO THIS QUEUED EVENT
	TAD	CLKCMD	/IF COMMAND IS NEGATIVE,
	SPA CLA		/THIS IS NOT A REGULAR COMMAND BUT A CANCEL -
	JMP	KILLQE	/CHECK WHETHER WE SHOULD CANCEL THIS Q ENTRY
	TAD I	CLKXR	/FROM INTERVAL TO THE CURRENT REQUEST
	SNA		/WATCH FOR 0 INTERVAL - SCREWS UP LINK
	JMP	NULADD	/NULL INTERVALS DON'T AFFECT SEARCH
	SZL
	CLL IAC		/ADD IN CARRY AFTER ZERO TEST!
	TAD	TH
	SNL		/IF THE REQUEST OCCURS BEFORE THE CURRENT
	JMP	INHERE	/QUEUE ENTRY, BREAK THE QUEUE HERE
	DCA	TH
	TAD	TTL	/SINCE QUEUED INTERVALS ARE CUMULATIVE,
	DCA	TL	/USE THE UPDATED INTERVAL FROM NOW ON
NULADD,	ION		/ALLOW INTERRUPTS BETWEEN ENTRIES
	TAD	CT
	JMP	QSRCLP	/GO TO NEXT QUEUE ENTRY

KILLQE,	AC0002
	TAD	CLKXR
	DCA	MADDR	/POINT AT COMMAND WORD OF QUEUE REQUEST
	TAD I	MADDR
	CIA		/COMPARE TASK NUMBER IN QUEUE ENTRY COMMAND
	TAD	CLKCMD	/TO SPECIFIED TASK
	AND	(177	/(ONLY 7 BITS TO COMPARE
	SNA CLA		/WELL?
	DCA I	MADDR	/MATCH - ZERO COMMAND WD (0 COMMAND IS NOP)
	JMP	NULADD
/FOUND WHERE IT GOES - NOW PUT IT THERE

INHERE,	DCA	MADDR	/SAVE HIGH ORDER OF DIFFERENCE
	TAD	CLKCMD
	SPA CLA		/IF THIS WAS A CANCEL COMMAND,
	JMP I	(CLKLP	/WE ARE DONE - DON'T INSERT ANYTHING.
	TAD	CLF
	DCA I	CQ	/LINK THE FIRST ENTRY ON THE FREE LIST
	STA		/INTO THE QUEUE AT THIS POINT
	TAD	CLF	/USE XR TO SET UP NEW ENTRY
	DCA	CLKXR
	TAD I	CLF	/REMOVE FREE LIST ENTRY
	DCA	CLF	/FROM FREE LIST
	TAD	CT	/COMPLETE THE INSERTION BY SETTING UP
	DCA I	CLKXR	/THE POINTER TO THE NEXT QUEUE ENTRY
	TAD	TL	/PUT THE NEGATIVE OF THE INTERVAL
	CIA CLL		/UNTIL THIS ENTRY IS EXECUTABLE INTO
	DCA I	CLKXR	/THE NEW QUEUE ENTRY, LOW ORDER
	CML RAL		/WORD FIRST (FOR EASY INCREMENTING)
	ION		/FINISHED DBL-PREC ARITHMETIC - ALLOW INTS
	TAD	TH
	CIA
	DCA I	CLKXR
	TAD	CLKCMD
	DCA I	CLKXR	/PUT COMMAND WORD IN QUEUE ENTRY
	TAD	XTRA1
	DCA I	CLKXR	/AND EXTRA WORDS FOR COMMAND
	TAD	XTRA2
	DCA I	CLKXR
	ISZ	CT	/NOW UPDATE THE FOLLOWING ENTRY
	TAD	TTL	/TO REFLECT THE REDUCED NUMBER
	DCA I	CT	/OF TICKS BETWEEN ENTRIES
	ISZ	CT
	TAD	MADDR	/** WE MAY BE "UPDATING" ZROENT **
	DCA I	CT	/** WE NEED TWO SCRATCH LOCS AFTER ZROENT **
	JMP I	CLQINS	/RETURN

ZROENT,	0		/PERMANENT FINAL ENTRY IN CLOCK QUEUE
TH,	0		/TH AND TL ALSO SERVE AS THE FIRST TWO
TL,	0		/WORDS OF "ZROENT"
CQ,	0
XTRA2,	0
CLKCMD,	0
CLF,	BEGFRE		/INITIALIZED TO BEGINNING OF FREE LIST
TTL,	0
	PAGE
/MAIN CLOCK HANDLER LOOP - SEE IF ANYTHING TO DO

CLKEF,	4000+TASK	/SIGNIFICANT TICK EVENT FLAG

CLKWT,	WAITM		/SPECIAL MONITOR ENTRY TO WAIT
	EORMWT		/FOR EVENT FLAG OR MESSAGE.
CLKLP,	IOF		/INTERRUPTS OFF FOR DELICATE CODE!
	TAD	CLKEF
	SNA CLA		/SIGNIFICANT TICK?
	JMP	GETICK	/YES - PROCESS IT
	TAD I	(CLF
	SZA CLA		/ANY ROOM IN CLOCK QUEUE?
	TAD I	(TASK^2+MSGTBL	/YES - CONSIDER MESSAGES
	SNA CLA		/CAN WE TAKE A MESSAGE?
	JMP	CLKWT	/NO - GO INTO EORMWT
	ION		/YES - RESTORE INTERRUPTS
	JMP I	(GETMSG	/AND GO RECEIVE MESSAGE

GETICK,	TAD	(4000+TASK	/RESET EVENT FLAG
	DCA	CLKEF		/TO "WAITING" STATE
	ION		/TURN INTERRUPTS BACK ON
	TAD	CLIPTR	/** GET POINTER FROM INTERRUPT ROUTINE **
	DCA	CLKXR	/USE AUTO-XR TO ACCESS HIGH-ORDER WORD
	DCA I	CLIPTR	/**FIXES QUEUE CREATOR BUG**
	ISZ I	CLKXR	/OK, WE GOT A NIBBLE - BUMP HIGH-ORDER WORD
	JMP	CLKLP	/FALSE ALARM (SIGH)
/	BBBB    OOO   N   N  GGGGG
/	B   B  O   O  NN  N  G
/	BBBB   O   O  N N N  G  GG  -  THE CLOCK HAS STRUCK!
/	B   B  O   O  N  NN  G   G
/	BBBB    OOO   N   N  GGGGG

CLKOV,	TAD I	CLQ	/REMOVE THE FIRST ENTRY FROM THE CLOCK QUEUE
	DCA	CLKTMP	/AND PLACE IT ON THE FREE LIST.
	TAD I	(CLF	/THIS ALLOWS US TO PLAY WITH IT TO OUR
	DCA I	CLQ	/HEARTS CONTENT WITHOUT MISSING ANY TICKS
	TAD	CLQ
	DCA I	(CLF
	TAD	CLKTMP
	DCA	CLQ
	TAD I	CLKXR
	SNA		/CHECK FOR CANCELLED REQUEST
	JMP	FIXQ	/YES - JUST DELETE FROM QUEUE
	DCA I	(CLKCMD
	TAD I	(CLKCMD
	RTL		/SET UP TO TEST BITS 1 AND 2 OF CMD WD
	SMA CLA		/CHECK FOR COMMAND 1 OR 3
	JMP	NOTRUN	/NO - 0 OR 2.
	SNL		/WHICH ONE?
	JMP	NORSCD	/1 - STRAIGHT RUN COMMAND
	TAD I	CLKXR
	DCA I	(TH	/GET RESCHEDULE INTERVAL
	TAD I	CLKXR
	DCA I	(TL
	TAD I	(TH
	DCA I	(XTRA1	/USE RESCHED INTERVAL AS NEW SCHEDULE
	TAD I	(TL	/AND RESCHEDULE INTERVAL
	DCA I	(XTRA2
	JMS I	(CLQINS	/INSERT THE NEW REQUEST IN THE CLOCK QUEUE
NORSCD,	TAD I	(CLKCMD	/GET TASK NUMBER
	AND	(177	/OUT OF COMMAND WORD
	CAL
	RUN		/AND RUN THE JOB NOW.
	JMP	FIXQ	/CLEAN UP THE QUEUE ENTRY
/TEST FOR DERAIL REQUEST

NOTRUN,	TAD I	CLKXR	/LOAD ARGUMENT INTO AC
	SNL		/DERAIL OR EVENT-FLAG REQUEST?
	JMP	SETEF	/EVENT FLAG
	DCA	DRLADR	/SAVE DERAIL SUBROUTINE ADDRESS
	TAD I	(CLKCMD
	AND	(177	/GET TASK NUMBER FROM COMMAND WORD
	CAL
	DERAIL		/DERAIL THE TASK
CLKTMP,
DRLADR,	0
	JMP	FIXQ

SETEF,	DCA	EFCDF	/SAVE DATA FIELD OF EVENT FLAG
	TAD I	CLKXR	/GET ADDRESS OF EVENT FLAG
	CAL
	POST		/POST THE EVENT FLAG ASSOCIATED
EFCDF,	0		/WITH THIS TIMER REQUEST

FIXQ,	CLA IAC
	TAD	CLQ
	DCA	CLKXR	/IT IS POSSIBLE FOR THE INTERVAL
	TAD I	CLKXR	/BETWEEN EVENTS ON THE QUEUE TO BE 0 -
	SNA CLA		/THIS MEANS THE EVENTS COME UP SIMULTANEOUSLY.
	TAD I	CLQ	/WE MUST CHECK FOR SIMULTANEITY HERE
	SNA CLA		/(WATCHING OUT FOR THE END OF THE QUEUE!)
	JMP	CLKLP	/IF NONE, GO WAIT FOR THE NEXT TICK
	JMP	CLKOV	/SIMULTANEOUS REQUEST - GO PROCESS IT
/CLOCK INTERRUPT ROUTINE
/INSERT CONDITIONALIZED FLAG CLEARS FOR USER-DEFINED CLOCK HERE.

CLKINT,	IFNZRO	CLKTYP&1	<CLSA>	/CLEAR KW12/DK8EP FLAG
	IFZERO	CLKTYP&1	<
	IFZERO	CLKTYP-2	<
	CLCL		/CLEAR PDP 8/A CLOCK FLAG
	CLA		/JUST IN CASE??
	>
	IFNZRO	TICKS-1	<
	ISZ	CLKCNT	/COUNT CLOCK TICKS PER SOFTWARE TICK
	POSTDS		/UNLESS COUNT=1 - THEN WHY BOTHER?
	TAD	(-TICKS	/RESTORE FULL COUNT
	DCA	CLKCNT
	>
	>

	CLA IAC		/** AC MAY NOT BE 0 HERE IF KW12 OR DK8EP **
	TAD	CLQ	/SAVE POINTER TO LOW-ORDER TICK COUNT
	DCA	CLIPTR	/OF FIRST QUEUE ENTRY
	ISZ	TODL
	JMP	CLKQT	/BUMP TIME-OF-DAY
	ISZ	TODH
	JMP	CLKQT
	TAD	MIDNTH	/T.O.D. CLOCK OVERFLOWS AT MIDNIGHT -
	DCA	TODH	/WE MUST RESET TO A SPECIAL FUDGE TO
	TAD	MIDNTL	/ASSURE THAT IT WILL HAPPEN AGAIN
	DCA	TODL	/NEXT MIDNIGHT.
	TAD	DATE
	TAD	(10
	DCA	DATE	/BUMP DATE 1 DAY, THE CRUDE WAY
CLKQT,	TAD I	CLQ
	SZA CLA		/IF QUEUE IS NOT EMPTY,
	ISZ I	CLIPTR	/BUMP LOW-ORDER COUNT
	POSTDS		/NOTHING DOING
	STA		/**FIXES QUEUE CREATOR BUG**
	DCA I	CLIPTR	/PUT -1 BACK...END OF FIX
	TAD	(CLKEF	/SET EVENT FLAG TO START DEQUEUER RUNNING
	POSTDS		/AS WE MAY HAVE REACHED A SIGNIFICANT TIME

CLIPTR,	0		/INTERRUPT-LEVEL POINTER
CLQ,	ZROENT		/QUEUE INITIALLY EMPTY
	IFNZRO	TICKS-1	<
CLKCNT,	-TICKS
	>

DAYL=	600^SHERTZ	/THESE STATEMENTS COMPUTE THE NUMBER OF TICKS
DAYH=	6^SHERTZ%100	/IN A DAY AS A DOUBLE WORD QUANTITY
DAYH=	25^SHERTZ+DAYH	/ = 250600*SHERTZ
	IFNZRO	DAYL	<DAYH=DAYH+1>	/JUST FOR BORROW ON NEGATE
MIDNTH,	-DAYH
MIDNTL,	-DAYL
	PAGE
/CLOCK QUEUE FREE LIST - ALSO INITIALIZATION CODE

EXROOM=	ENDEXC+177&7600-ENDEXC	/CALCULATE ROOM IN PAGE WITH EXEC TABLES
	IFNZRO	CLKQLN^6-EXROOM&4000	<	/IF QUEUE WILL FIT THERE,
	IFNZRO	100-EXROOM&4000	<	/AS WELL AS INITIALIZATION CODE,
	*ENDEXC			/THEN SAVE SOME SPACE
	>	>

BEGFRE,
START,	IOF		/IOF WHEN MESSING WITH SKIP CHAIN!!
	ISZ	DATE	/DATE CONTAINS POINTER TO CLOCK SKIP LOC -1
	TAD	(CLSK
	DCA I	DATE
	TAD	DATE
	TAD	(4
	DCA	DATE
	TAD	(CLKINT
	DCA I	DATE
	CDF	10
	TAD I	(7666	/GET OS/8 DATE WORD
	DCA	DATE	/SET RTS DATE FROM IT
	CDF CUR
	TAD I	(MIDNTH
	DCA	TODH	/SET TIME TO MIDNIGHT (AS GOOD AS ANY TIME)
	TAD I	(MIDNTL
	DCA	TODL
/INSERT CONDITIONALIZED INITIALIZATION CODE FOR USER-DEFINED
/CLOCK HERE - MUST ENABLE INTERRUPTS AND SET RATE.

	IFZERO	CLKTYP	<
	CLEI		/ENABLE CLOCK INTERRUPTS FOR DK8EA,C
	>
	IFZERO	CLKTYP-3	<	/SPECIFIC DK8EP INIT CODE
	STA
	CLZE		/ZERO COMMAND REGISTER ON DK8EP
	TAD	(5311-4100	/5310 = ENABLE INTS, 1 KHZ, MODE 1
	>
	IFNZRO	CLKTYP&1	<	/COMMON DK8EP, KW12 INIT CODE
	TAD	(4100	/4100 = 1 KHZ, MODE 1
	CLLR		/LOAD COMMAND REGISTER
	CLA		/CLLR DOESN'T CLEAR AC
	TAD	(-TICKS
	CLAB		/SCALE DOWN CLOCK TO SOFTWARE RATE
	CLA		/DOES NOT CLEAR AC
	>
	IFZERO	CLKTYP-1	<	/SPECIFIC KW12 INIT CODE
	TAD	(300	/FORCE CLOCK BUFFER INTO COUNTER AND
	CLEN		/ENABLE KW12 INTERRUPTS
	CLA		/THIS DOESN'T CLEAR AC EITHER
	>
	IFZERO	CLKTYP-2	<	/PDP8/A CLOCK INIT CODE
	CLA IAC
	CLEN		/ENABLE CLOCK INTERRUPTS
	CLA		/(JUST IN CASE)
	>
	JMP	FREELP
/CLOCK QUEUE INITIALIZATION -
/THIS CODE IS WRITTEN TO SKIP EVERY SIXTH WORD SINCE IT IS
/SETTING THESE WORDS TO QUEUE POINTERS.
/** NO LITERALS IN THIS CODE! **

	ZBLOCK	.-BEGFRE%6^6+BEGFRE+7-.	/MOVE US TO THE 2ND WORD OF A 6 WD BLOCK

FREELP,	TAD	FREPTR
	TAD	F6
	DCA I	FREPTR	/CHAIN EACH QUEUE ENTRY TO THE NEXT ONE
	TAD	FREPTR
	SKP
	0		/THIS LOC GETS DESTROYED BY OUR LOOP!
	TAD	FRELIM
	SMA CLA
	JMP	INIXIT	/DONE - END INITIALIZATION CODE
	TAD I	FREPTR	/GET NEW QUEUE ENTRY ADDRESS
	SKP
	0
	DCA	FREPTR
	JMP	FREELP
INIXIT,	DCA I	FREPTR	/ZERO LAST POINTER
	ION
	JMP I	PCLKLP	/START WAITING FOR CLOCK TICKS
	0
FREPTR,	BEGFRE
F6,	6
FRELIM,	13-ENDFRE	/SO WE NEVER GO PAST "ENDFRE"
PCLKLP,	CLKLP
	PAGE
	IFZERO	CLKQLN^6+BEGFRE-.&4000	<
	ZBLOCK	CLKQLN^6+BEGFRE-.+5	/+5 FOR SAFETY
	>	/MAKE SPACE FOR ENTRIES IF MORE THAN 21 DESIRED

ENDFRE=	.
	$$$
