;**********************************************************************
;               	 ALARM SYSTEM PROGRAM
;**********************************************************************
;
; Source		: Alarmsys.asm
; Date		: July 24, 2000
;----------------------------------------------------------------------
;
; Written By	: Mike Genovy
; Original Code   : May 19, 1983
; Last Modified	: August 17, 2000
;
;**********************************************************************
; Notes:
; ------
;
;	The original code was hand assembled, and tested on the Synertek
; SYM 6502 computer. Then the eprom for the single board computer was
; programmed after all addresses had been corrected to the S.B.C. 
; addresses. 
;	I have created this source code file from the original code written
; in 1983 and assembled it using the Cross 16 assembler from Universal
; Cross assemblers. This assembler produces an INTEL Hex format output 
; file. 
;-------------------------------------------------------------------------
; 
; Alarm Program Operation:
; ------------------------
;
; Power up or a Manual Reset:
;	- Read 8 switch inputs 
;	- If any are open at this time they will not be scanned during
;	  normal operation.
;
; Run Mode:
;	- Scan switch inputs ( the switches to be scanned are determined
;	  at pwer up, or after a manual reset ) 
;	- If any switch inputs go open the alarm will be turned on after
;	  a 15 second delay. The Alarm LED will also be turned on at this
;	  time.
;	- The Alarm relay will remain on for 15 minutes. After 15 minutes
;	  the alarm relay will be turned off, but the alarm LED will be
;	  left on.
;
;
;
; Disable Mode:
;
;
;
;
;
; Test Mode:
;
;
;
;
;
;
;
;
;
; 6522 Port Assignments
; ---------------------
;
; PA0 - Alarm switch input ( Low in normal position )
; PA1	- Alarm switch input
; PA2	- Alarm switch input
; PA3	- Alarm switch input
; PA4	- Alarm switch input
; PA5	- Alarm switch input
; PA6	- Disable switch input
; PA7	- Tamper switch input ( This bit is inverted in the code )
;
; CA1
; CA2	- Pulse Output 1
;
; PB0	- Alarm relay output
; PB1	- Alarm LED  output
; PB2	- Run LED output		- These LED's are on the front of
; PB3	- Disable LED output	- the alarm panel, and indicate
; PB4	- Test LED output		- the current mode of operation.
; PB5	- Run input		- These 3 inputs are from a 3 position 
; PB6	- Disable input	- rotary switch, referred to as the
; PB7	- Test input	- Control Switch in this code.
;
; CB1
; CB2	- Pulse output 2
;
;	This alarm program has 3 main time delay loops, and 2 delay loops
; associated with alarm switch debouncing. 
;
;	The Main program delay loops are:
;	---------------------------------
;
;	WAIT1 - Delay loop before starting to scan switches when put in Run 
;		  mode
;
;	WAIT2 - Delay loop before turning on the alarm relay and alarm led
;
;	WAIT3 - Delay loop before turning off the alarm relay
;
;	The Control Switch subroutine ( RDCSW: ) delay loop is:
;	-------------------------------------------------------
;
;	WAITA - This is a switch debounce delay loop
;
;	The Read Port A subroutine ( RDPTA ) delay loop is:
;	---------------------------------------------------
;
;	WAITB- This is a switch debounce delay loop
;
;	The present length of these delays is:
;	======================================
;
;	WAIT1	-	60 seconds ---> now 2 seconds
;	WAIT2	-	60 seconds ---> now 2 seconds
;	WAIT3	-	15 minutes
;	WAITA	- 	0.5 seconds
;	WAITB	-	0.5 seconds
;
;======================================================================
; Define the type of processor and the EPROM HEX file format
;======================================================================
;
		CPU  "6502.TBL"	; Processor table
		HOF  "INT8"		; HEX format
;
;======================================================================
; Define starting addresses of the 6502 S.B.C. EPROM program & tables
;======================================================================
;
MAIN:		EQU	0B800H	;Cartridge starts at B800 hex

INITVIA:	EQU	0BF00H	;array used to init 6522 via

INITPAGE0:	EQU	0BF30H	;array used to init Page 0 locations

VECTOR:	EQU	0BFFAH	;Vectors

VIABASE:	EQU	0A800H	;6522 base address

PAGE0:	EQU	0002H		;Page 0 storage
;
;======================================================================
; Define delay values of the 6502 S.B.C. 
;======================================================================
;
; WAIT1VAL - Delay before starting to scan switches when put in Run mode
; WAIT2VAL - Delay before turning on the alarm relay and alarm led
; WAIT3VAL - Delay before turning off the alarm relay
; WAITAVAL - Read Control Switch ( RDCSW ) switch debounce delay
; WAITBVAL - Read Port A ( RDPTA ) switch debounce delay

;	WAIT1VAL:	EQU	03CH	;60 second

;	WAIT2VAL:	EQU	03CH	;60 second

	WAIT1VAL:	EQU	02H	; 2 seconds

	WAIT2VAL:	EQU	02H	; 2 seconds

	WAIT3VAL:	EQU	00FH	;15 minutes

	WAITAVAL:	EQU	0AH	;10 x 50 msec
	
	WAITBVAL:	EQU	0AH	;10 x 50 msec
;
;======================================================================
; Define Page 0 memory allocation
;======================================================================
;
	ORG     PAGE0

ARYADR:	DFS	2 * 1	; 6522 VIA initialization array address pointer
PRTADR:	DFS	2 * 1	; 6522 port address pointer
RAMADR:	DFS	2 * 1	; Page 0 variable table address pointer
EPMADR:	DFS	2 * 1	; Eprom table address pointer
VIA:		DFS	2 * 1	; 6522 VIA chip base address
MASK:		DFS	1    	; Port A mask value
COUNT:	DFS	1    	; 50 msec counter for clock routine
SEC:		DFS	1    	; Seconds counter for wait loops
CSW:		DFS	1    	; Control switch value
ALMSW:	DFS	1    	; Port A alarm switch value
MIN:		DFS	1    	; Minutes counter for wait loops
SECONDS:	DFS	1    	; Seconds counter for clock routine
MINUTES:	DFS	1    	; Minutes counter fro clock routine
CNT:		DFS	1    	; 50 msec counter for RDCSW and RDPTA routine
HOURS:	DFS	1    	; Hours counter for clock routine
HR:		DFS	1    	; Hours counter for wait loops
TEMP:		DFS	1    	; Temporary storage of Port A input value
;
;======================================================================
; 6522 VIA Addresses
;======================================================================
;
;	A800H		ORB/IRB	Output / Input register B
;	A801H		ORA/IRA	Output / Input register A
;	A802H		DDR B		Data Direction Register A
;	A803H		DDR A		Data Direction Register B
;	A804H		T1C-L		Timer # 1 Low order latch/Low order counter
;	A805H		T1C-H		Timer # 1 High order counter
;	A806H		T1L-L		Timer # 1 Low order latches
;	A807H		T1L-H		Timer # 1 High order latches
;	A808H		T2C-L		Timer # 2 Low order latch/Low order counter
;	A809H		T2C-H		Timer # 2 High order counter
;	A80AH		SR		Shift register
;	A80BH		ACR		Auxillary Control Register
;	A80CH		PCR		Peripheral Control Register
;	A80DH		IFR		Interrupt Flag Register
;	A80EH		IER		Interrupt Enable Register
;	A80FH		ORA/IRA	Output Register A ( no effect on Handshaking )
;
;---------------------------------------------------------------------------
;
	ORG     VIABASE

ORB:	DFS	1		;Output Register B
IRB:	EQU	ORB   	;Input Register B
ORA:	DFS	1		;Output Register A
IRA:	EQU	ORA		;Input Register A
DDRB:	DFS	1		;Data Direction Register B
DDRA:	DFS	1		;Data Direction Register A
T1CL:	DFS	1		;read:  T1 counter, low-orde
				;write: T1 latches, low-order
T1CH:	DFS	1		;T1 counter, high-order
T1LL:	DFS	1		;T1 latches, low-order
T1LH:	DFS	1		;T1 latches, high-order
T2CL:	DFS	1		;read:  T2 counter, low-order
                		;write: T2 latches, low-order
T2CH:	DFS	1		;T2 counter, high-order
SR:	DFS	1		;Shift Register
ACR:	DFS	1		;Auxiliary Control Register
PCR:	DFS	1		;Peripheral Control Register
IFR:	DFS	1		;Interrupt Flag Register
IER:	DFS	1		;Interrupt Enable Register
;
;======================================================================
; 6522 VIA Initialization Array
;======================================================================
;
		ORG	INITVIA

ARYENT_AR:	DFB	008H		; # of entries in 6522 VIA initialization
					; array
DDRA_AR:	DWL	0A803H	; Data Direction Register A address
		DFB	000H		; Set Port A to all outputs
IORB_AR:	DWL	0A800H	; Input/Output Register B address
		DFB	000H		; Initial output to Port B is 00
DDRB_AR:	DWL	0A802H	; Data Direction Register B address
		DFB	01FH		; PB0 to PB4 = Outputs PB5 to PB7 = Inputs
PCR_AR:	DWL	0A80CH	; Peripheral Control Register address
		DFB	0AAH		; CA2/CB2 set for pulse output mode
ACR_AR:	DWL	0A80BH	; Auxillary Control Register address
		DFB	040H		; Timer # 1 set for Free Run Mode
IER_AR1:	DWL	0A80EH	; Interrupt Enable Register Address
		DFB	03FH		; Disable all other interrupts
IFR_AR:	DWL	0A80DH	; Interrupt Flag Register address
		DFB	0C0H		; Clear Timer # 1 Interrupt flag
IER_AR2:	DWL	0A80EH	; Interrupt Enable Register address
		DFB	0C0H		; Enable Timer # 1 interrupts
;
;======================================================================
; Page 0 Initial Values
;======================================================================
;
		ORG	INITPAGE0

RAMENT_AR:	DFB	00DH		; # of entries in RAM Initialization table
STADR_AR:	DWL	{VIA}		; Base address of RAM Variable Table
VIA_AR:	DWL	0A800H	; VIA Chip base address
MASK_AR:	DFB	0FFH		; Initial Port A mask value
					; ( All switches OK )
COUNT_AR:	DFB	014H		; Initial 50 msec count value for clock
					; routine
SEC_AR:	DFB	00H		; Initial seconds counter value for wait loops
CSW_AR:	DFB	0C0H		; Initial Control Switch value ( Run mode )
ALMSW_AR:	DFB	00H		; Initial Port A alarm data ( No alarms )
MIN_AR:	DFB	00H		; Initial minutes counter value for wait loops
SECONDS_AR:	DFB	00H		; Initial seconds for clock routine
MINUTES_AR:	DFB	00H		; Initial minutes for clock routine
CNT_AR:	DFB	00H		; Initial 50 msec counter value for RDCSW 
					; and RDPTA
HOURS_AR:	DFB	00H		; Initial hours for clock routine
HR_AR:	DFB	00H		; Initial hours counter value for wait loops
;
;======================================================================
; Define address in EPROM where INTERRUPT Vectors stored
;======================================================================
;
		ORG  VECTOR		;Must start at 0BFFAH for the Vectors 
					;to be equivalent to 0FFFAH !!!

NMI:		DWL	0B800H	; Non-Maskable Interrupt Vector
					; ( Same as a Reset )
RESETVEC:	DWL	0B800H	; Reset Vector
					; ( " Power on reset " vector )
BREAK:	DWL	{CLKINT}	; IRQ and Break Vector
					; ( Clock routine )
;
;======================================================================
; Define starting address EPROM HEX file
;======================================================================
;
		ORG  MAIN		;
;
;**********************************************************************
;                         MAIN ROUTINE
;**********************************************************************
;
;----------------------------------------------------------------------
; Stack Initialization
;----------------------------------------------------------------------
;
RESET:
	LDX	#0FFH		;
	TXS			; Initialize the stack pointer
;
;----------------------------------------------------------------------
; 6522 Initialization routine
;----------------------------------------------------------------------
;
; Set up the VIA array address pointer on Page 0 first
;
	LDA	#HIGH{INITVIA+1}	; Initialize starting address of VIA array
	STA	ARYADR+1		; located on Page 0 locations 0003/0002
	LDA	#LOW{INITVIA+1}	;
	STA	ARYADR		;

	LDA	ARYENT_AR 	; Get the number of entries in the VIA array
	TAX			; Set X register to number of VIA array entries
				; There are a total of 8 entries in the VIA array.
				; These 8 values are copied from EPROM to Page 0
;
; Now copy values from the VIA array in EPROM to Page 0 locations
;
LOOP:
	LDY	#00H		; Set up the VIA array index value
	LDA	(ARYADR),Y	; Get Low Byte of Port A DDR-A address and store in 
	STA	PRTADR	; PRTADR ( Location 0004 )
	INY			; Increment array index
	LDA	(ARYADR),Y	; Get High Byte of Port A DDR-A address and store in 
	STA	PRTADR+1	; PRTADR + 1 ( Location 0005 )
	INY			; Increment array index
	LDA	(ARYADR),Y	; Get Initial Port A value of 00H
	LDY	#00H		; Set array index to 0
	STA	(PRTADR),Y	; Output to Port A DDR-A. This sets all of Port A
				; to inputs
	LDA	ARYADR	; Bump up the VIA array address value pointer
	CLC			; Clear carry
	ADC	#03H		; Add 3 to Low Byte of Array address
	STA	ARYADR	;
	BCC	DECR		;
	INC	ARYADR+1	; Increment High Byte if a Carry exists
DECR:
	DEX			; Decrement # of VIA array entries - If 0 then we 
	BNE	LOOP		; are done setting up Page 0 VIA locations
;
;----------------------------------------------------------------------
; Initialize RAM Variable Table
;----------------------------------------------------------------------
;
	LDA	RAMENT_AR	; Get # of RAM table entries from Array in Eprom
	TAX			; Set X register to # of RAM table entries
				; There are a total of 0DH ( 13 decimal ) entries
				; These values are copied from EPROM to Page 0
	LDA	STADR_AR	; Initialize RAM variable table starting address
	STA	RAMADR	; located on Page 0 
	LDA	STADR_AR+1	;
	STA	RAMADR+1	;
;
; Set up the EPROM array address pointer on Page 0 first
;
	LDA	#LOW{VIA_AR}	;
	STA	EPMADR		; Initialize EPROM table starting address
	LDA	#HIGH{VIA_AR+1}	; located on Page 0 locations 0008/0009
	STA	EPMADR+1		;
	LDY	#00H			; Set index to 0
;
; Now copy values from the VIA array in EPROM to Page 0 locations
;
GETDTA:
	LDA	(EPMADR),Y	; Get EPROM data
	STA	(RAMADR),Y	; Store in RAM variable table
	INY			; Increment index pointer
	DEX			; Decrement # of array entries, If 0 then done
	BNE	GETDTA	;
;
; Some minor housekeeping
;
	CLD			; Clear Decimal mode flag
	CLI			; Clear Interrupt disable bit
;
;----------------------------------------------------------------------
; Start Timer # 1 in Free Run mode with 50 msec count. This will be used
; for the Real Time Clock routine to calculate various delays
;----------------------------------------------------------------------
;
	LDY	#04H		; Load Index
	LDA	#50H		; 
	STA	(VIA),Y	; Load Timer # 1 Low Latch with 50
	INY			;
	LDA	#0C3H		;
	STA	(VIA),Y	; Load Timer # 1 High Latch with 0C3H
				; ( Timer # 1 is now started )
;
;----------------------------------------------------------------------
; Initial PORT A read and Control Switch read
;----------------------------------------------------------------------
;
	JSR	INITRD	; Read Port A alarm switches. This is the Initial 
				; read of Port A alarm switches. The initial value
				; from Port A is used as a mask for normal scanning.
				; So....if a switch is open when Run is first 
				; entered then that switch will be ignored in any
				; further scanning of inputs.
LOOP1:
	JSR RDCSW		; Read the Control switch position 
	LDA	CSW		; Get Control switch position
	CMP	#0C0H		; and see if its RUN position ?
	BEQ	RUN		;
	CMP	#0A0H		; DISABLE position ?
	BEQ	DISABLE1	;
	CMP	#060H		;
	BEQ	TEST1		; TEST position ?
	LDY	#00H		; Load index to point to ORB ( Output Register B )
	LDA	#01CH		;
	STA	(VIA),Y	; Turn on RUN, DISABLE, and TEST Leds to indicate
				; no valid Control switch position read.
	JMP	LOOP1		; Continue scanning Control switch
DISABLE1:
	JMP	DISABLE	;
TEST1:
	JMP	TEST		;
;
;----------------------------------------------------------------------
; Control Switch in RUN Position
;----------------------------------------------------------------------
;
RUN:
	LDY	#00H		; Load index to point to DDR-A
	LDA	#04H		;
	STA	(VIA),Y	; Turn on the RUN Led
	LDA	#00H		; Set Seconds counter to 0
	STA	SEC		;
LOOP2:
	JSR	RDCSW		; Read the Control switch position 
	LDA	CSW		; Get Control switch position
	CMP	#0C0H		; and see if its RUN position ? 
	BEQ	WAIT1		;
	CMP	#0A0H		;
	BEQ	DISABLE2	; DISABLE position ?
	CMP	#060H		;
	BEQ	TEST2		; TEST position ?
	LDY	#00H		; Load index to point to ORB ( Output Register B )
	LDA	#01CH		;
	STA	(VIA),Y	; Turn on RUN, DISABLE, and TEST Leds to indicate
				; no valid Control switch position read.
	JMP	LOOP2		; Continue scanning Control switch
DISABLE2:
	JMP	DISABLE	;
TEST2:
	JMP	TEST		;
;
;----------------------------------------------------------------------
; This wait loop gives a 60 second delay prior to starting the normal
; scan. This is the EXIT delay, and allows one to turn the Alarm on,
; then exit the building without activating the alarm.
; To change this delay change the value of WAIT1VAL
;----------------------------------------------------------------------
;
WAIT1:
	LDA	#WAIT1VAL	;
	CMP	SEC		; See if 60 seconds has elapsed
	BEQ	SCAN		; Yes, so start normal scan
	JMP	LOOP2		; No, so continue scanning Control switch
;	JMP	DISABLE	;
;	JMP	TEST		;
;
;----------------------------------------------------------------------
; Normal Alarm Switch Scanning
;----------------------------------------------------------------------
;
SCAN:
	JSR	RDPTA		; Read Port A alarm switches. 
	LDA	ALMSW		; Get the alarm switch data
	AND	MASK		; and mask with the Initial Port A input data
	BNE	TAMPER	; If not 0 then check the TAMPER bit ( Bit 7 )
LOOP3:
	JSR	RDCSW		; Read the Control switch position 
	LDA	CSW		; Get Control switch position
	CMP	#0C0H		; and see if its RUN position ?
	BEQ	SCAN		;
	CMP	#0A0H		; DISABLE position ?
	BEQ	DISABLE3	;
	CMP	#060H		; TEST position ?
	BEQ	TEST3		;
	LDY	#00H		; Load index to point to ORB ( Output Register B )
	LDA	#01CH		; 
	STA	(VIA),Y	; Turn on RUN, DISABLE, and TEST Leds to indicate
				; no valid Control switch position read.
	JMP	LOOP3		; Continue scanning Control switch
DISABLE3:
	JMP	DISABLE	;
TEST3:
	JMP	TEST		;
;
;----------------------------------------------------------------------
; Check TAMPER switch input first !
;----------------------------------------------------------------------
;
TAMPER:
	CLC			; Clear carry flag	
	ROL	A		; Bit 7 is the Tamper input
	BCS	ALARM		; If Bit 7 = 1 the Tamper is active
	LDA	#00H		; 
	STA	SEC		; Set seconds counter to 0
LOOP4:
	JSR	RDCSW		; Read the Control switch position
	LDA	CSW		; Get Control switch position
	CMP	#0C0H		; and see if its RUN position ?
	BEQ	WAIT2		;
	CMP	#0A0H		;
	BEQ	DISABLE4	; DISABLE position ?
	CMP	#060H		;
	BEQ	TEST4		; TEST position ?
	LDY	#00H		; Load index to point to ORB ( Output Register B )
	LDA	#01CH		; 
	STA	(VIA),Y	; Turn on RUN, DISABLE, and TEST Leds to indicate
				; no valid Control switch position read.
	JMP	LOOP4		; Continue scanning Control switch
DISABLE4:
	JMP	DISABLE	;
TEST4:
	JMP	TEST		;
;
;----------------------------------------------------------------------
; This wait loop gives a 60 second delay prior to turning on the Alarm
; Led and Alarm relay. 
; To change this delay change the value of WAIT2VAL
;----------------------------------------------------------------------
;
WAIT2:
	LDA	#WAIT2VAL	;
	CMP	SEC		; See if 60 seconds has elapsed
	BEQ	ALARM		; Yes, so turn on Alarm relay
	JMP	LOOP4		; No, so continue scanning Control switch
;
;----------------------------------------------------------------------
; Alarm Led and Alarm Relay activated
;----------------------------------------------------------------------
;
ALARM:
	LDY	#00H		; Load index to point to ORB ( Output Register B )
	LDA	#07H		;
	STA	(VIA),Y	; Turn on Alarm Led and Alarm relay
	LDA	#00H		; 
	STA	MIN		; Set Minutes counter to 0
LOOP5:
	JSR	RDCSW		; Read the Control switch position
	LDA	CSW		; Get Control switch position
	CMP	#0C0H		; and see if its RUN position ?
	BEQ	WAIT3		;
	CMP	#0A0H		;
	BEQ	DISABLE5	; DISABLE position ?
	CMP	#060H		;
	BEQ	TEST5		; TEST position ?
	LDY	#00H		; Load index to point to ORB ( Output Register B )
	LDA	#01CH		;
	STA	(VIA),Y	; Turn on RUN, DISABLE, and TEST Leds to indicate
				; no valid Control switch position read.
	JMP	LOOP5		; Continue scanning Control switch
DISABLE5:
	JMP	DISABLE	;
TEST5:
	JMP	TEST		;
;
;----------------------------------------------------------------------
; This wait loop gives a 15 minute delay prior to turning off the Alarm
; Led and Alarm relay. 
; To change this delay change the value of WAIT3VAL
;----------------------------------------------------------------------
;
WAIT3:
	LDA	#WAIT3VAL	;
	CMP	MIN		; See if 15 minutes has elapsed
	BEQ	OFF		; Yes, so turn off Alarm relay
	JMP	LOOP5		; No, so continue scanning Control switch
;
;----------------------------------------------------------------------
; Alarm Led and Alarm Relay de-activated
;----------------------------------------------------------------------
;
OFF:
	LDY	#00H		; Load index to point to ORB ( Output Register B )
	LDA	#006H		;
	STA	(VIA),Y	; Turn off Alarm Led and Alarm relay
;
	JMP	SCAN		; Go back and start scan again
;
;----------------------------------------------------------------------
; Disable Routine
;----------------------------------------------------------------------
;
DISABLE:
	LDY	#00H		; Load index to point to ORB ( Output Register B )
	LDA	#08H		;
	STA	(VIA),Y	; Turn off Alarm Led, Alarm relay, and turn on 
				; Disable Led
LOOP6:
	JSR	RDCSW		; Read the Control switch position
	LDA	CSW		; Get Control switch position
	CMP	#0C0H		; and see if its RUN position ?
	BEQ	RESET1	;
	CMP	#0A0H		;
	BEQ	LOOP6		; DISABLE position ?
	CMP	#060H		;
	BEQ	TEST		; TEST position ?
	LDY	#00H		; Load index to point to ORB ( Output Register B )
	LDA	#01CH		;
	STA	(VIA),Y	; Turn on RUN, DISABLE, and TEST Leds to indicate
				; no valid Control switch position read.
	JMP	LOOP6		; Continue scanning Control switch
RESET1:
	JMP	RESET		;
	JMP	TEST		;
;
;----------------------------------------------------------------------
; Test Routine
;----------------------------------------------------------------------
;
TEST:
	LDY	#00H		; Load index to point to ORB ( Output Register B )
	LDA	#13H		;
	STA	(VIA),Y	; Turn on Alarm Led, Alarm relay, and turn on 
				; Test Led
LOOP7:
	JSR	RDCSW		; Read the Control switch position
	LDA	CSW		; Get Control switch position
	CMP	#0C0H		; and see if its RUN position ?
	BEQ	RESET2	;
	CMP	#0A0H		;
	BEQ	DISABLE	; DISABLE position ?
	CMP	#060H		;
	BEQ	LOOP7		; TEST position ?
	LDY	#00H		; Load index to point to ORB ( Output Register B )
	LDA	#01CH		;
	STA	(VIA),Y	; Turn on RUN, DISABLE, and TEST Leds to indicate
				; no valid Control switch position read.
	JMP	LOOP7		; Continue scanning Control switch
RESET2:
	JMP	RESET		;
	JMP	DISABLE	;
;
;======================================================================
; 			Read Control Switch Subroutine
;======================================================================
;
RDCSW:
	LDY	#00H		; Load index to point to ORB ( Output Register B )
	LDA	(VIA),Y	; Read Port B 
	AND	#0E0H		; Mask out bits 0 to 4
	STA	CSW		; Store the Control Switch value
	LDA	#00H		; 
	STA	CNT		; Set the 50 msec counter to zero
	LDA	#WAITAVAL	;
WAITA:
	CMP	CNT		; Wait for 0.5 seconds ( 10 x 50 msec )
	BEQ	READ		;
	JMP	WAITA		;
READ:
	LDY	#00H		; Load index to point to ORB ( Output Register B )
	LDA	(VIA),Y	; Read Port B again
	AND	#0E0H		; Mask out bits 0 to 4
	CMP	CSW		; Compare new value to old value
	BEQ	EXIT1		; If same continue, else read it again
	JMP	RDCSW		;
;
; Control Switch is the same position
;
EXIT1:
	LDA	CSW		; Get Control Switch value
	CMP	#0C0H		; and check if its Run position
	BEQ	RUNPOS	;
;
; Watchdog output - Pulse the CB2 line
;
EXIT:
	LDY	#00H		; Not in Run position
	LDA	(VIA),Y	; Read Port B
	STA	(VIA),Y	; Write to Port B
;
	RTS			; Return from subroutine
;
; Check Disable switch
;
RUNPOS:
	JSR	RDPTA		; Read Port A data inputs
	LDA	ALMSW		; Get Port A input value
	AND	#40H		; Only need Bit 6 ( Disable switch )
	BNE	END		;
	LDA	#0A0H		; Disable switch closed, so set Control switch
	STA	CSW		; value to Disable position
END:
	JMP	EXIT		;
;
;======================================================================
;			Initial Port A Read Subroutine
;======================================================================
;
INITRD:
	JSR	RDPTA		; Read Port A alarm switches
	LDA	ALMSW		; Get switch data
	EOR	#0FFH		; Complement the data
	AND	#0BFH		; Mask out Bit 6 which is the Disable switch
	STA	MASK		; Save this as Port A mask value
	RTS			;
;
;======================================================================
;			Read Port A Subroutine
;======================================================================
;
RDPTA:
	JSR	RDDTA		; Read Port A alarm switches 
	STA	ALMSW		; Save switch data
	LDA	#00H		;
	STA	CNT		; Set the 50 msec counter to zero
	LDA	#WAITBVAL	;
WAITB:
	CMP	CNT		; Wait for 0.5 seconds ( 10 x 50 msec )
	BEQ	READA		;
	JMP	WAITB		;
READA:
	JSR	RDDTA		; Read Port A alarm switches again
	CMP	ALMSW		; Compare new data to old data
	BEQ	EXITA		; If same exit, else
	JMP	RDPTA		; go back and read switches again
EXITA:
	RTS			; Return
;
;======================================================================
;			New Read Port A Subroutine
;======================================================================
;
RDDTA:
	LDY	#01H		;
	LDA	(VIA),Y	; Read Port A inputs
	STA	TEMP		; Save Port A value
	CLC			; Clear carry
	ROL	A		; Shift Bit 7 to carry
	BCS	OK		; Check if bit 7 = 1
	LDA	TEMP		; Get Port A value	Reverse Sense of Bit 7
	ORA	#80H		; and set Bit 7
	RTS			; Return
OK:
	LDA	TEMP		; Get Port A value
	AND	#7FH		; and clear Bit 7		Reverse Sense of Bit 7
	RTS			; Return
;
;======================================================================
;			Clock Interrupt Subroutine
;======================================================================
;
CLKINT:
	PHP			; Push processor status on stack
	PHA			; Push A on stack
	TXA			; Transfer X to A
	PHA			; Push X on stack
	TYA			; Transfer Y to A
	PHA			; Push Y on stack
	LDY	#04H		; Load index
	LDA	(VIA),Y	; Read Timer#1 low order counter to clear int flag
	INC	CNT		; Increment 50 msec counter
	DEC	COUNT		; Decrement 50 msec count value
	BNE	EXIT2		; If 0 then ( 20 x 50 msec ) = 1.0 sec has elapsed
	INC	SEC		; Increment seconds counter
	LDA	#14H		; 
	STA	COUNT		; Reset 50 msec count value
	LDA	#01H		; 
	CLC			;
	ADC	SECONDS	; Add 1 to seconds
	STA	SECONDS	;
	CMP	#3CH		; Has 60 seconds elapsed ?
	BNE	EXIT2		;
	INC	MIN		; Increment minutes counter
	LDA	#00H		;
	STA	SECONDS	; Reset seconds count to zero
	LDA	#01H		;
	CLC			;
	ADC	MINUTES	; Add 1 to minutes
	STA	MINUTES	;
	CMP	#3CH		; Has 60 minutes elapsed ?
	BNE	EXIT2		;
	INC	HR		; Increment hours counter
	LDA	#00H		;
	STA	MINUTES	; Reset minutes counter to zero
	INC	HOURS		; Increment hours
EXIT2:
	PLA			; Pull A from stack
	TAY			; Restore Y register
	PLA			;
	TAX			; Restore X register
	PLA			; Restore A register
	PLP			; Restore processor status
	RTI			; Return from Interrupt
;
;
;
	END