*********************************************************************************************
*       Switch-Debouncer IC Creates A Long-Period Timer                      					                                                 *
*	Phill Leyva, Maxim Integrated Products, Sunnyvale, CA                					                                                       *
*                                                                            								                                                                           *
* ==> Project Description <==                                          							                                                                  *
* Switch debouncer used as a long period external timer, allowing the microcontroller to reduce power       *                                                                                                                                 	*                                                                                                                                                               *
* consumption by entering a sleep mode.							                                                                                            	*		                     
*                                                                                                                               							                    			 		*
*           		Total Elapsed Time = Count_T x Timer_period  where                                                                			*
*                		Count_T = Number of external Timer periods                                                                       			*
*                		Timer_period (s) = (63k x C1 x (-ln(1 - VT/VCC)) + 0.1s)                                                     			*
*                        		VT = MAX6817 threshold voltage                      				                                                         	*
*                        		VCC = MAX6817 VCC voltage                                                                                     					*
*       										                                                                                                                                             		*
*	    ICs utilized in project:                                             				                                                                        		*
*              	 Motorola MC68HC705J1A Microcontroller                                                                               				*
*              	 MAXIM MAX6817 ESD Protected CMOS Switch Debouncer                                                         			*
*               	Fairchild FDV303N N-Channel Digital FET                      		                                                          			*
*									                                                                                                                                                     			*
*	==> Program Description								                                                                                                                  *
* The Start section initializes the registers and I/O. The remaining code consists of the Main Program, the 	*
*   subroutines Input, Control, and Output, and interrupt subroutine IRQ_ISR.			                      	                      *			                     
*								                                                                                                                                                     				*
* After power up, subroutine Input obtains current data from input Port A and stores it in the Input Data   	*
* Table (IN_Port). Subroutine Control transfers this IN_Port data to the Output Data Table (OUT_Port),     	*
* and accepts the user's control logic algorithm. Subroutine Output transfers the new output data 		           *
* (OUT_Port) to Output Port B.                                          			                                                         	          		*
*							                                                                                                                                                    	 				*
* Finally, the Main Program calls the Interrupt subroutine (IRQ_ISR) when U1 has timed out for 1 period,     	*
*  and adds 1 to the counter. Count T specifies the number of timer periods before waking up the             		*
*   microcontroller. The Main program controls the flow of the program, and enters a low-power wait state 	*
*  when the input and output have been updated.			                                                                                  			 	*
*												                                                                                                                                                     *
***********************************************************************************
*                            Register Equates                                                                                 							*
***********************************************************************************
PORTA   	equ     	$00     	; Port A byte address
PORTB   	equ     	$01     	; Port B byte address
DDRA    	equ     	$04     	; Port A Data Direction Register
DDRB    	equ     	$05     	; Port B Data Direction Register
TSCR    	equ     	$08     	; Timer Status and Control Register
TCR     	equ     	$09     	; Timer-Counter Register
ISCR    	equ     	$0A     	; Interrupt Status and Control Register
PDRA    	equ     	$10     	; Pull-Down Register Port A
PDRB    	equ     	$11     	; Pull-Down Register Port B
EPROG   	equ     	$18     	; EPROM Programming Control Register
COPR    	equ     	$7F0    	; COP Reset Register
MOR     	equ     	$7F1    	; Mask Option Register

***********************************************************************************
*               I/O Port Register Equates                                                                                  						*
***********************************************************************************
* Port A Data Register (PORTA Address = $00)
PA0     		equ     	0       	; Port A bit 0, Input Bit
PA1     		equ     	1       	; Port A bit 1, Input Bit
PA2     		equ     	2       	; Port A bit 2, Input Bit
PA3     		equ     	3       	; Port A bit 3, Input Bit
PA4     		equ     	4       	; Port A bit 4, Input Bit
PA5     		equ     	5       	; Port A bit 5, Input Bit
PA6     		equ     	6       	; Port A bit 6, Input Bit
PA7     		equ     	7       	; Port A bit 7, Input Bit

* Port B Data Register (PORTB Address = $01)
PB0     		equ     	0      	; Port B bit 0, Output Bit
PB1     		equ     	1       	; Port B bit 1, Output Bit
PB2     		equ    	2       	; Port B bit 2, Output Bit
PB3     		equ     	3       	; Port B bit 3, Output Bit
PB4     		equ     	4       	; Port B bit 4, Output Bit
PB5     		equ     	5       	; Port B bit 5, Output Bit

* Timer Status and Control Register (TSCR Address = $08)
RT0       	equ     	0       	; Real-Time Interrupt Rate Select bit 0
RT1       	equ     	1       	; Real-Time Interrupt Rate Select bit 1
RTIFR   	equ     	2       	; Real-Time Interrupt Flag Reset
TOFR   	equ     	3       	; Timer Overflow Flag Reset
RTIE     	equ     	4       	; Real-Time Interrupt Enable
TOIE    	equ     	5       	; Timer Overflow Interrupt Enable
RTIF     	equ    	6       	; Real-Time Interrupt Flag
TOF     	equ     	7       	; Timer Overflow Flag

***********************************************************************************
*                       Memory Equates                                                                                       							*
***********************************************************************************
RAM             	equ     	$00C0   		; Start of on Chip Static RAM
EPROM           	equ     	$0300   		; Start of on Chip ROM/EPROM
Vectors        	equ     	$07F8   		; Start of Reset/Interrupt Vectors
Timer_INT       	equ     	$07F8   		; Timer Vector
IRQ_INT         	equ     	$07FA   		; External Hardware Interrupt Vector
SWI_INT         	equ     	$07FC   		; Software Interrupt Vector
RESET           	equ     	$07FE   		; Reset Vector

***********************************************************************************
*                       Program Equates                                                                                      							*
***********************************************************************************
Count_T         	equ     	$04       		; Number of external Timer periods desired
                                  			; Total elapsed time=Count_T x Timer_period

***********************************************************************************
*                       RAM Variables                                       			                                                   				*
***********************************************************************************
                	org     	RAM     		; Start of Static RAM address
IN_Port        	 rmb     	1       		; Byte Wide, Input Data Table
OUT_Port       	 rmb     	1       		; Byte Wide, Output Data Table
Count           	rmb     	1       		; External Timer pulse counter

***********************************************************************************
*                   Program I/O Initialization                             	                                                   				*
*      Default for PORTA is as INPUT Port                                                                             					*
*       PortA Pins   7     6     5      4     3     2     1       0                                                        					*
*          Function  In    In    In    In    In   In   In      In                                                               					*
*      Default for PORTB is as OUTPUT Port                                                                         					*
*        PortB Pins    5          4           3         2          1           0                                            						*
*          Function  Out     Out     Out     Out     Out     Out           				                                           		*
***********************************************************************************
                org     EPROM
Start:          	sei             		; Mask OFF Hardware Interrupt
                	clra            		; Clear Accumulator
                	sta    	 PORTA   	; Blank data for registers
                	sta     	DDRA    		; Set Port A Byte Wide Inputs
                	sta     	IN_Port		; Clear Input Data Table
                	sta    	 OUT_Port 	; Clear Output Data Table
                	sta     	Count   		; Clear external timer counter
                	sta    	 PORTB  	 	; Initialize Port B MCU-Latches
                	lda     	#$FF    		;
                	sta     	DDRB    		; Set Port B as Output Port
                	lda     	#$0F    		;
                	sta     	TSCR    		; Disable Timer Interrupts
                	clrx            		; Clear Index Registor
                	clra            		; Clear Accumulator
                	sta     	COPR    		; Reset Watchdog timer
                	jsr     	Input   		; Get initial Input Port A data
                	jsr     	Control 		; Manipulate Data Tables
                	jsr     	Output  		; Send out initial Output Port B data
                	cli             		; Mask ON Hardware Interrupts, enable
                                			; external timer interrupts

***********************************************************************************
*                       Main Program                                                                                           							*
***********************************************************************************
Main:          	wait             		; Enter power saving mode until awaken by
                               			; by timer (IRQ\) or system reset (RESET\)
                     	lda     	#Count_T 	; Number of external Timer periods desired
                     	sbc     	Count    		; Subtract (Count_T - Count)
                     	bls     	Next     		; Test if accumulator is zero or negative
                     	jmp     	Main     		; Counter not done
Next:           	jsr     	Input    		; Counter done, get new Input Port A data
                     	jsr     	Control  		; Transfer data tables and other user tasks
                    	jsr     	Output   		; Send out new Output Port B data
                     	jmp     	Main     		; Do another loop through Main

***********************************************************************************
*                       Input Port A Update Subroutine                      				                                           		*
***********************************************************************************
Input:          	lda     	PORTA  		; Read new Input Port A data
                	sta     	IN_Port 		; Update Input Data Table
                	rts            			; Return from Subroutine

***********************************************************************************
*                       Control Logic Update Subroutine                     				                                           		*
***********************************************************************************
Control:        	nop            		; USER to remove "nop"s and insert CONTROL<<*
                	nop            		; LOGIC routine here <<**********************
                	lda     	IN_Port		 ; Read new Input table data
                	sta     	OUT_Port 	; Update Output table
                	rts             		; Return from Subroutine

***********************************************************************************
*                       Output Port B Update Subroutine                     	                                          					*
***********************************************************************************
Output:         	lda     	OUT_Port 	;
                	sta     	PORTB    	; Send new data to Output Port B
                	rts              		; Return from Subroutine

***********************************************************************************
*                       Interrupt Service Routine                      						                                                   	*  
*	            External Timer (MAX6817) has pulsed once                                                           					*
***********************************************************************************
IRQ_ISR:        	inc     	Count   		; Add 1 to counter
                	rti             			; Done with Interrupt Routine
*****************************************************************************
*                       Timer Interrupt Service Routine                                                            *
*****************************************************************************
TIMER_ISR:      nop             ; Future User Timer Routine
                rti             ; Done with Interrupt Routine

*****************************************************************************
*                       Software Interrupt Service Routine                                                       *
*****************************************************************************
SWI_ISR:        nop             ; Future User Sofware Routine
                rti             ; Done with Interrupt Routine

*****************************************************************************
*                      RESET and Interrupt Vectors                                                                 *
*****************************************************************************
                 org     Vectors

                 org    Timer_INT
                 fdb    TIMER_ISR

                 org    IRQ_INT
                 fdb    IRQ_ISR

                 org    SWI_INT
                 fdb    SWI_ISR

                 org    RESET
                 fdb    Start

*****************************************************************************
*                      MOR Vectors                                                                                          *
*****************************************************************************
                 org     MOR
                 db      $20       ; Set MOR Register Options, no Watchdog




                rti             ; Done with Interrupt Routine

*****************************************************************************
*                       Timer Interrupt Service Routine                                                            *
*****************************************************************************
TIMER_ISR:      nop             ; Future User Timer Routine
                rti             ; Done with Interrupt Routine

*****************************************************************************
*                       Software Interrupt Service Routine                                                       *
*****************************************************************************
SWI_ISR:        nop             ; Future User Sofware Routine
                rti             ; Done with Interrupt Routine

*****************************************************************************
*                      RESET and Interrupt Vectors                                                                 *
*****************************************************************************
                 org     Vectors

                 org    Timer_INT
                 fdb    TIMER_ISR

                 org    IRQ_INT
                 fdb    IRQ_ISR

                 org    SWI_INT
                 fdb    SWI_ISR

                 org    RESET
                 fdb    Start

*****************************************************************************
*                      MOR Vectors                                                                                         *
*****************************************************************************
                 org     MOR
                 db      $20       ; Set MOR Register Options, no Watchdog