
	NAM	CLOCK
 IFP1
	USE	/D0/DEFS/OS9DEFS
	USE	/D0/DEFS/SCFDEFS
 ENDC

* REVISION HISTORY:
* 18 JAN, 82: MTN COMPUTER'S CPS CARD CLOCK
* 23 JAN, 82: WESTSIDE'S SUPERCLOCK II

* ABSTRACT:
* THE VARIOUS CLOCK TYPES ARE DEFINED IN THIS CODE
* VIA CONDITIONAL ASSEMBLY. THE CONFIGURED SOURCE
* IS THEN ASSEMBLED WITH THE OBJECT IN A DISK FILE
* WHOSE NAME DEPICTS THE CARD TYPE AND SLOT NUMBER.
*  EXAMPLE:
* CPSCLK7  IS THE MTN COMPUTER CPS CARD IN SLOT 7.
* WESCLK5  IS THE WESTSIDE ELECTRONICS IN SLOT 5.
* LINECLK   IS THE CASSETTE AUDIO "LINE" CLOCK.
* NONE     MEANS NONE OF THE ABOVE.. USES APPROXIMATION.
*
* WHEN LOADED INTO THE MODULE DIRECTORY, THE NAME
* CODE PRODUCES PERIODIC INTERRUPTS IN ALL CASES,
* HOWEVER THE TIME OF DAY COMES FROM A CLOCK CARD
* IF PRESENT, OR IF NO CARD, FROM OS9'S COUNTERS.

*  THE "CHEAP" CLOCK SHOULD BE CONNECTED IN ORDER
* TO USE THE MULTI-TASKING FEATURES OF OS9.
* THE CHEAP CLOCK IS A 60 HZ SIGNAL AT THE CASSETTE
* AUDIO INPUT JACK.  THIS MAY BE OBTAINED AT PIN
* ?? OF I.C. "C13", A 74LS51.
* THE "CHEAP" CLOCK MAY ALSO BE ENHANCED BY THE
* USE OF A TIME-OF-DAY HARDWARE CARD WHICH ENABLES
* MORE ACCURATE TIME KEEPING AND ELIMINATES THE
* NEED TO ENTER THE DATE/TIME ON EVERY SYSTEM BOOT.
*
* THE CLOCK CONTROL/STATUS REGISTER IS AT LOCATION
* "PARCLK" (SEE OS9DEFS). THIS REGISTER HAS THE
* FOLLOWING LAYOUT:
* B7: SET BY 6502 CODE EVERY 6 "TICS" OF THE CHEAP CLOCK.
* (OR APPROX 100 MSEC IF NO CHEAP (LINE) CLOCK.)
*     WHEN THE 6502 SETS THIS BIT, IT ALSO INTERRUPTS
*     OS9 WHICH PERFORMS A TASK SWITCH IF DESIRED.
*       THE CLOCK INTERRUPT SERVICE MUST CLEAR THIS BIT
*     BUT MUST PRESERVE BITS 6-0.
* B6: SET BY 6809 TO ENABLE  CLOCK INTERRUPTS
* B5-B3: CLOCK  TYPE:
*        000 NO LINE CLK, USE RAM COUNTER
*        001 LINE CLOCK CONNECTED (CASSETTE AUDIO)
* B2-B0  CARD SLOT IN WHICH CLOCK CARD IS LOCATED
*        XXX 1-7 (0 IS ILLEGAL)
*
* THE CLOCK IS STARTED BY "LOAD"ING ONE OF SEVERAL
* UNIQUE DISK FILES INTO RAM.  WHEN LOADED, THE
* INITIALIZATION CODE RUNS WHICH SETS THE ABOVE
* CARD TYPE/SLOT CODE.  THERE ARE SEVERAL VERSIONS
* OF THIS PROGRAM, ACCORDING TO THE VARIETY OF CLOCK
* CARDS AND DESIRED SLOT NUMBER.
*  THE "SETIME" UTILITY CALLS "CLKENT", BELOW.
*   IF THE WRONG CLOCK MODULE (DISK FILE) IS LOADED,
* THE 6502 IS LIKELY TO CRASH OS9.
*
* THE CASSETTE AUDIO "CHEAP" CLOCK SHOULD ALWAYS
* BE PRESENT. IT IS USED FOR THE PERIODIC INTERRUPT.
* IN ITS ABSENCE, THE 6502 INTERRUPTS USING A COUNTER.

 PAG
*******************************************************
*
*
*
* CHANGE THE BELOW TO ADD A NEW CLOCK TYPE:

	ORG	0 SET DATA COUNTER
NONE	RMB	1 NO CLOCK CARD
CPSCLK	RMB	1 MOUNTAIN COMPUTER CPS
WESCLK	RMB	1 WESTSIDE ELECTRONICS
* THE ABOVE CONTROL THE CONDITIONAL ASSEMBLY
*  OF THIS CODE.

******************************************************
*
* CHANGE THE BELOW TO DEFINE CLOCK TYPE AND CARD SLOT

CLKTYP	SET	NONE CLOCK TYPE
SLOT	SET	0 SLOT NUMBER FOR CLOCK BOARD

 IFEQ CLKTYP-NONE
	TTL	NO CLOCK CARD
 ENDC
 IFEQ CLKTYP-CPSCLK
	TTL	CPS CARD CLOCK
 ENDC
 IFEQ CLKTYP-WESCLK
	TTL	WESTSIDE ELECTRONICS
 ENDC
	PAG
TYPE	SET	SYSTM+OBJCT
REVS	SET	REENT+1

	MOD	CLKEND,CLKNAM,TYPE,REVS,CLKENT,PARCLK
SLOTNO	FCB	SLOT PATCHABLE
CLKNAM	FCS	"CLOCK"
	FCB	2
CLKPRT	EQU	M$STAK STACK HAS CLOCK PORT ADDR

* PARAMS FOR F$SSVC CALL IN INITIALIZATION CODE
TIMSVC	FCB	F$TIME
	FDB	TIME-*-2
	FCB	$80




***** CLOCK INTERRUPT SERVICE *******


NOTCLK	JMP	[D.ISVC] WAS NOT CLOCK

CLKSRV	LDB	PARCLK CLOCK INTERRUPT?
	BPL	NOTCLK IF NO
TICK	CLRA GET REAL BASE PAGE
	TFR	A,DP


* UPDATE TIC COUNTER:
	DEC	D.TIC
	LBNE	TICK50 IF NOT RUNDOWN
** THIS CODE RUNS ONCE PER SECOND **
 IFEQ CLKTYP-NONE
*** NO TIME-OF-DAY BOARD INSTALLED ***
	LDD	D.MIN GET MIN/SEC
	INCB
	CMPB	#60
	BCS	TICK35
	INCA
	CMPA	#60
	BCS	TICK30
	LDD	D.DAY
	INCB
	CMPB	#24 END OF DAY?
	BCS	TICK25
	INCA COUNT DAY
	LEAX	MONTHS,PCR END OF MONTH?
*
	LDB	D.MNTH
	CMPB	#2
	BNE	TICK10
	LDB	D.YEAR
	BEQ	TICK10
	ANDB	#3 LEAY?
	BNE	TICK10
	DECA  FEB 29
TICK10	LDB	D.MNTH
	CMPA	B,X
	BLS	TICK20
	LDD	D.YEAR
	INCB
	CMPB	#13
	BCS	TICK15 END OF YEAR
	INCA
	LDB	#1
TICK15	STD	D.YEAR
	LDA	#1 NEW DAY
TICK20	CLRB NEW HR
TICK25	STD	D.DAY
	CLRA NEW MIN
TICK30	CLRB NEW SECOND
TICK35	STD	D.MIN
 ENDC (END IF NO CLOCK BOARD)
**** RESET TIC COUNTER ****
	LDA	D.TSEC TICS/SECOND
	STA	D.TIC RESET COUNTER
 IFEQ CLKTYP-CPSCLK IF CPS CLOCK
*** SEE CPS MANUAL, PG B-9 FOR CLK CHIP I'FACE ***
*** REFER TO OKI DATA SHEET ON MSM5832  ***
	LDA	SLOTNO,PCR GET SLOT*256
	CLRB
	ADDD	#REMAPC+$00F0 =$BNF0
	TFR	D,X POINTS TO THE CARD
	LDB	#$40 HOLD=1=TRUE
	STB	$E,X SEND HOLD
	LDA	#160/5 HOLD SETUP
CPSG	DECA 2 USEC (@1 MHZ)
	BNE	CPSG 3 USEC, TOTAL 5 USEC
	LDY	#D.SEC+1 SYSTEM DATE GLOBAL
	ORB	#$10 SET READ=TRUE
	LEAS	-2,S WORKING RAM
CPSGET	CMPB	#$56 "WEEK" REGISTER?
	BNE	CPSG0 IF NO
	INCB
CPSG0	STB	$E,X ADDRESS CLOCK REGISTERS
	EXG	A,A READ ACCESS TIME DELAY
	TFR	A,A
	LDA	9,X GET A 10^0 DIGIT
	ANDA	#$F KILL OTHER BITS
	STA	,S SAVE IT
	INCB NEXT HIGHER
CPSG2	STB	$E,X SEND ADDR
	EXG	A,A DELAY
	TFR	A,A
	LDA	9,X GET 10^1 DIGIT
	ANDA	#$F KILL OTHER BITS
	CMPB	#$55 HOURS 10^1?
	BNE	CPSG4 IF NO
	ANDA	#3 KILL AM/PM AND 24HR FLAGS
CPSG4	STB	1,S  SAVE
	LDB	#10
	MUL	SCALE 10^1 DATA
	ADDB	,S SUM 10^0 DATA
	STB	,-Y PUT IN GLOBAL
	LDB	1,S INDEX
	INCB NEXT VARIABLE
	CMPB	#$50+13 READ REGISTERS 0..12
	BLO	CPSGET LOOP
	CLRB
	STB	$E,X RELEASE HOLD
	LEAS	2,S RELEASE STACK
 ENDC (CPS CLOCK)


 IFEQ CLKTYP-WESCLK IF WESTSIDE CLOCK
*** WESTSIDE USES MOTORALA PIA AND OKI CLOCK CHIP ***
*** REFER TO OKI DATA SHEET ON MSM5832  ***
	LDX	PIALOC,PCR GET ADDR OF PIA
	LDB	#$10 HOLD=1=TRUE
	STB	2,X SEND HOLD
	LDA	#160/5 HOLD SETUP
CPSG	DECA	2 USEC (@1 MHZ)
	BNE	CPSG 3 USEC, TOTAL 5 USEC
	LDY	#D.SEC+1 SYSTEM DATE GLOBAL
	ORB	#$20 SET READ=TRUE
	LEAS	-2,S WORKING RAM
CPSGET	CMPB	#$36 "WEEK" REGISTER?
	BNE	CPSG0 IF NO
	INCB
CPSG0	STB	2,X ADDRESS CLOCK REGISTERS
	EXG	A,A READ ACCESS TIME DELAY
	TFR	A,A
	LDA	,X GET A 10^0 DIGIT
	ANDA	#$F KILL OTHER BITS
	STA	,S SAVE IT
	INCB NEXT HIGHER
CPSG2	STB	2,X SEND ADDR
	EXG	A,A DELAY
	TFR	A,A
	LDA	,X GET 10^1 DIGIT
	ANDA	#$F KILL OTHER BITS
	CMPB	#$35 HOURS 10^1?
	BNE	CPSG4 IF NO
	ANDA	#3 KILL AM/PM AND 24HR FLAGS
CPSG4	STB	1,S  SAVE
	LDB	#10
	MUL	SCALE 10^1 DATA
	ADDB	,S SUM 10^0 DATA
	STB	,-Y PUT IN GLOBAL
	LDB	1,S INDEX
	INCB NEXT VARIABLE
	CMPB	#$30+13 READ REGISTERS 0..12
	BLO	CPSGET LOOP
	CLRB
	STB	2,X RELEASE HOLD
	LEAS	2,S RELEASE STACK
 ENDC (CPS CLOCK)


* ACKNOWLEDGE INTERRUPT & RELEASE 6502
TICK50	LDB	PARCLK GET STATUS
	ANDB	#$7F KILL IRQ BIT
	STB	PARCLK ACK IT
	LDX	>D.MILL MILL'S SLOT NO.
	LDA	#$80
	STA	5,X DROP IRQ
	JMP	[CLOCK] GO TO SYSTEM CLOCK CODE




 IFEQ CLKTYP-NONE
MONTHS	FCB	0,31,28,31,30,31,30,31,31,30,31,30,31
 ENDC


**** INITIALIZATION ******
* THIS CODE IS CALLED BY "SETIME".
CLKENT	PSHS	DP SAVE DP
	CLRA
	TFR	A,DP GET REAL ONE
	PSHS	CC SAVE MASK
****** CHANGE HERE FOR CLOCK FREQ *******
	LDA	#10 TICS PER SECOND
	STA	D.TSEC
	STA	D.TIC COUNTER
	LDA	#1 TICS PER TIME SLICE
	STA	D.TSLC
	STA	D.SLIC
	ORCC	#$50 BLOCK INTERRUPTS
	LEAX	CLKSRV,PCR GET ADR OF SERVICE
	STX	D.IRQ SET VECTOR
	PULS	CC REENABLE 
 IFEQ CLKTYP-WESCLK IF WESTSIDE CLOCK
*** INITIALIZE PIA FOR WESTSIDE I'FACE ***
	CLRA
	LDB	SLOTNO,PCR GET SLOT NO.
	LSLB TIMES 16
	LSLB
	LSLB
	LSLB
	ADDD	#REMAPC+$80 HAVE EQUIV OF C0N0
	TFR	D,X POINTS TO THE PIA
	LDA	#4 DATA DIRECTION FLAG BIT
	CLRB
	STB	1,X PIA'S A SIDE CONTROL REG
	BSR	RTSWES TNX MOTOROLA
	STB	,X SET A SIDE FOR ALL LINES AS INPUT
	BSR	RTSWES
	STA	1,X DESELECT DATA DIRECTION REG
	BSR	RTSWES
	STB	3,X B SIDE CONTROL REG
	BSR	RTSWES
	COMB =$FF
	STB	2,X B SIDE- ALL OUTPUT
	STX	<PIALOC,PCR SAVE PIA'S ADDR (IMPURE)
	STA	3,X DESELECT DATA DIR REGIS
 ENDC (WESTSIDE CLOCK)
	LDA	#$40   CLOCK ENABLE
	ORA	SLOTNO,PCR MERGE SLOT NO.
	STA	PARCLK STORE IN COMMON
	LEAY	TIMSVC,PCR INTERRUPT SERVICE ADDR
	OS9	F$SSVC SET TIME SERVICE
	PULS	DP,PC RETURN

 IFEQ CLKTYP-WESCLK
RTSWES	RTS TIME DELAY
*** NOT ROM-ABLE!!! ***
PIALOC	FDB	0 IMPURE.. SAVE PIA ADDR TO SPEED ISR
 ENDC
*
**** SUBROUTINE SUPPORTING OS9 GET TIME FUNCTION ****
* RETURNS TIME OF DAY
TIME	LDX	R$X,U GET LOCATION
	LDD	D.YEAR YEAR MONTH
	STD	,X
	LDD	D.DAY DAY HR
	STD	2,X
	LDD	D.MIN
	STD	4,X
	CLRB
	RTS

 IFNE 0 >>> FUTURE FAST IRQ SERVICE <<<
*******************************************
*
*  FAST IRQ SERVICE
FIRQSV	PSHS	X SAVE
	LDX	>D.MILL ADDR OF MILL
	CLR	1,X HALT MYSELF
	PULS	X RESTORE
	RTI	EXIT
 ENDC

 EMOD
CLKEND	EQU	*
 END
