	.TITLE %CLOCK
	.GLOBL %CLOCK,%START,%STOP,%ENTER,%DLETE
/REAL-TIME CLOCK HANDLER---ALL CLOCK FUNCTIONS
/C. L. CROSS, DECEMBER, 1968
/CARNEGIE-MELLON UNIVERSITY HYBRID LAB
/
/FUNCTION #1 - START THE CLOCK
/EXECUTION TIME (AFTER FIRST CALL):  4 (CLOCK WAS ALREADY ON) OR
/                                   12 (CLOCK WAS OFF) MICROSECONDS
/CALLING SEQUENCE:  JMS* %START
/RESULT:  .SETUP TO KM9 EXECUTED ON FIRST CALL TO SET-UP INTERRUPT FIELDING
/         ALL QUEUE LOCATIONS ARE CLEARED AND
/            THE REAL-TIME CLOCK IS ENABLED IF IT IS OFF
/         A DEPTH-COUNTER IS INCREMENTED IF THE REAL-TIME CLOCK IS ALREADY ON
%START	0
/ONCE-ONLY .SETUP CODE
FIXLOC	CAL 51	/API TRAP REGISTER
TEMP	16	/.SETUP
SUB1	CLSF	/CLOCK INTERRUPTS
SUB2	%CLOCK	/INTERRUPT HANDLER
SUB3	LAC (JMP .+2
SUB4	DAC FIXLOC	/SET-UP ONCE-ONLY CODE BYPASS
/END OF ONCE-ONLY CODE
	ISZ DEPTH
	JMP* %START	/CLOCK IS ALREADY ON
	DZM TIME	/ZERO ELAPSED TIME
	DZM TIME1	/FREE
	DZM TIME2	/   ALL
	DZM TIME3	/      QUEUE
	DZM TIME4	/         LOCATIONS
	LAW 17777
	DAC* (7	/INITIALIZE LOCATION 7
	CLON	/ENABLE THE CLOCK
	JMP* %START
CLON=700044
CLSF=700001
/
/FUNCTION #2 - STOP THE CLOCK
/EXECUTION TIME:  8 (CLOCK IS LEFT ON) OR
/                12 (CLOCK IS TURNED OFF) MICROSECONDS
/CALLING SEQUENCE:  JMS* %STOP
/RESULT:  THE REAL-TIME CLOCK IS DISABLED IF THE DEPTH-COUNTER IS ZERO
/         THE DEPTH-COUNTER IS DECREMENTED IF IT IS POSITIVE
%STOP	0
	LAW 17777
	TAD DEPTH
/(AN INTERRUPT HERE WHICH FINDS ITS WAY TO %START WILL RUIN EVERYTHING)
	DAC DEPTH	/DECREMENT THE DEPTH-COUNTER
	SPA
	CLOF	/DISABLE THE CLOCK
	JMP* %STOP
CLOF=700004
DEPTH	777777
/
/FUNCTION #3 - CLOCK INTERVAL REQUEST PROCESSING
/EXECUTION TIME:  27 (QUEUE 1), 29 (QUEUE 2), 31 (QUEUE 3),
/                 OR 32 (QUEUE 4) MICROSECONDS
/CALLING SEQUENCE:  SET (AC)=LENGTH OF INTERVAL DESIRED
/                             (IN UNITS OF 16 2/3 MILLISECONDS)
/                    JMS* %ENTER
/                    ADDRESS OF SUBROUTINE TO PROCESS END-OF-INTERVAL NOTIFICATION
/                    RETURN (AC)=QUEUE NUMBER GRANTED
/RESULT:  A REQUEST FOR NOTIFICATION AT COMPLETION OF THE SPECIFIED
/            INTERVAL IS ENTERED INTO THE FIRST FREE QUEUE LOCATION
%ENTER	0
	SNA!SPA
	JMP ER77	/NONPOSITIVE INTERVAL REQUESTED
	TAD TIME
	DAC TEMP	/SAVE ELAPSED TIME AT END OF INTERVAL
	LAC DEPTH
	SPA!CLA
	JMP ER76	/CLOCK IS OFF
	SAD TIME1
	JMP ONE	/QUEUE 1 IS FREE
	SAD TIME2
	JMP TWO	/QUEUE 2 IS FREE
	SAD TIME3
	JMP THREE	/QUEUE 3 IS FREE
	SAD TIME4
	JMP FOUR	/QUEUE 4 IS FREE
/NO FREE QUEUE LOCATIONS AVAILABLE
/IOPS ERROR MESSAGE SECTION
	LAC %ENTER
	DAC* (.MED	/STORE ENTRY POINT
	LAW 74	/IOPS 74
	JMP* (.MED+1	/CLOCK QUEUE OVERFLOW
ER75	LAC %ENTER
	DAC* (.MED	/STORE ENTRY POINT
	LAW 75	/IOPS 75
	JMP* (.MED+1	/USER SUBROUTINES TOOK TOO LONG
ER76	LAC %ENTER
	DAC* (.MED	/STORE ENTRY POINT
	LAW 76	/IOPS 76
	JMP* (.MED+1	/INTERVAL REQUESTED WHEN THE CLOCK WAS OFF
ER77	LAC %ENTER
	DAC* (.MED	/STORE ENTRY POINT
	LAW 77	/IOPS 77
	JMP* (.MED+1	/NO POSITIVE INTERVAL REQUESTED
/END OF ERROR MESSAGE SECTION
ONE	LAC* %ENTER
	DAC SUB1	/STORE NOTIFICATION ADDRESS
	LAC TEMP
	DAC TIME1	/STORE ELAPSED TIME
	LAC (1	/QUEUE 1 GRANTED
	JMP OUT
TWO	LAC* %ENTER
	DAC SUB2	/STORE NOTIFICATION ADDRESS
	LAC TEMP
	DAC TIME2	/STORE ELAPSED TIME
	LAC (2	/QUEUE 2 GRANTED
	JMP OUT
THREE	LAC* %ENTER
	DAC SUB3	/STORE NOTIFICATION ADDRESS
	LAC TEMP
	DAC TIME3	/STORE ELAPSED TIME
	LAC (3	/QUEUE 3 GRANTED
	JMP OUT
FOUR	LAC* %ENTER
	DAC SUB4	/STORE NOTIFICATION ADDRESS
	LAC TEMP
	DAC TIME4	/STORE ELAPSED TIME
	LAC (4	/QUEUE 4 GRANTED
OUT	ISZ %ENTER	/BUMP TO EXIT
	JMP* %ENTER
TIME
TIME1
TIME2
TIME3
TIME4
.MED=3
/
/FUNCTION #4 - CLOCK INTERVAL REQUEST DELETION
/EXECUTION TIME:  15 MICROSECONDS
/CALLING SEQUENCE:  SET (AC)=QUEUE NUMBER OF REQUEST TO BE DELETED
/                   JMS* %DLETE
/RESULT:  THE CLOCK INTERVAL NOTIFICATION REQUEST PREVIOUSLY GRANTED
/            IN THE SPECIFIED QUEUE NUMBER IS DELETED
%DLETE	0
	TAD (-5
	SMA
	JMP* %DLETE	/AC>4
	TAD (4
	SPA
	JMP* %DLETE	/AC<0
	TAD (TIME1
	DAC LOC
	DZM* LOC	/FREE THE SPECIFIED QUEUE LOCATION
	JMP* %DLETE
LOC
/FUNCTION #5 - CLOCK INTERRUPT HANDLER
/EXECUTION TIMING:  CONSTANT OVERHEAD-57 (PI) MICROSECONDS
/                                   OR 48 (API) MICROSECONDS
/                   PER NOTIFICATION REQUIRED-9 MICROSECONDS
/                                           + USER SUBROUTINE EXECUTION TIME
/CALLING SEQUENCE:  INTERRUPT DRIVEN
%CLOCK	JMP PI	/PIC ENTRY
	DAC AC	/API ENTRY---SAVE AC
	LAC %CLOCK
	DAC EXIT	/SAVE L,EM,MP,PC
	LAC (JMP PI
	DAC %CLOCK	/RESTORE PIC ENTRY
	EEM	/ENABLE EXTEND MODE
	LAW 17777
	DAC* (7	/RESET LOCATION 7
	CLON	/CLEAR THE CLOCK FLAG
	JMS CLOCK	/CHECK THE CLOCK QUEUE
	LAC AC	/RESTORE AC
	JMP DONE
PI	DAC AC	/SAVE AC
	LAC* (0
	DAC EXIT	/SAVE L,EM,MP,PC
	ISZ SAFE
	JMP ER75	/NOT FINISHED WITH THE LAST CLOCK INTERRUPT
	LAW 17777
	DAC* (7	/RESET LOCATION 7
	CLON	/CLEAR THE CLOCK FLAG
	ION	/ALLOW OTHER PI INTERRUPTS
	JMS CLOCK	/CHECK THE CLOCK QUEUE
	IOF	/SHUT OUT (CLOCK) INTERRUPTS TEMPORARILY
	LAW 17777
	DAC SAFE	/RESET PROTECTION SWITCH
	LAC AC	/RESTORE AC
	ION	/CLOCK INTERRUPTS OK NOW
DONE	DBR	/RELEASE LEVEL 1
	JMP* EXIT	/RESTORE L,EX,MP,PC
AC
EXIT
SAFE
/
/FUNCTION #6 - QUEUE-VERSUS-ELAPSED-TIME CHECKER
/INTERNAL SUBROUTINE
/EXECUTION TIME:  CONSTANT OVERHEAD-14 MICROSECONDS
/                 PER NOTIFICATION REQUIRED-9 MICROSECONDS
/                                         + USER SUBROUTINE EXECUTION TIME
/CALLING SEQUENCE:  JMS CLOCK
CLOCK	0
	ISZ TIME	/INCREMENT ELAPSED TIME
	LAC TIME
	SAD TIME1
	JMP FIRST	/QUEUE 1 IS READY
BACK2	SAD TIME2
	JMP SECOND	/QUEUE 2 IS READY
BACK3	SAD TIME3
	JMP THIRD	/QUEUE 3 IS READY
BACK4	SAD TIME4
	JMP FOURTH	/QUEUE 4 IS READY
	JMP* CLOCK
FIRST	DZM TIME1	/FREE QUEUE 1
	JMS* SUB1	/NOTIFY USER
	LAC TIME	/RESTORE AC=TIME
	JMP BACK2	/CHECK QUEUE 2, 3, AND 4
SECOND	DZM TIME2	/FREE QUEUE 2
	JMS* SUB2	/NOTIFY USER
	LAC TIME	/RESTORE AC=TIME
	JMP BACK3	/CHECK QUEUE 3 AND 4
THIRD	DZM TIME3	/FREE QUEUE 3
	JMS* SUB3	/NOTIFY USER
	LAC TIME	/RESTORE AC=TIME
	JMP BACK4	/CHECK QUEUE 4
FOURTH	DZM TIME4	/FREE QUEUE 4
	JMS* SUB4	/NOTIFY USER
	JMP* CLOCK
/THAT IS ALL
	.END
