;
;***************************************
; written by: John Morton		
; for PIC12F675			
; clock frequency: Int. 4 MHz		
; ***************************************

; Program Description: Quiz controller for 3 players, including reset button 
;  for the quiz master

	list		P=12F675		
	include		inc:\pic\p12f675.inc

;==============
; Declarations:

temp	equ	20h
Post16	equ	21h

	org	0	; first instruction to be executed
	goto	Start	;
	
	org	4	; interrupt service routine
	goto	isr	;

;===========
; Subroutines: 

Init	bsf	STATUS, RP0	; go to Bank 1
	call	3FFh		; call calibration address
	movwf	OSCCAL		; move w. reg into OSCCAL

	movlw	b'011110'		; GP5: Buzzer, GP3: Reset button
	movwf	TRISIO		;  GP1,2,4: LEDs/Buttons (inputs
				;  to start with), GP0: LED enable
	movlw	b'010110'		; GP1,2,4 have weak pull-ups 
	movwf	WPU		;   enabled

	movlw	b'00000111'	; pull-ups enabled, TMR0 presc.	
	movwf	OPTION_REG	;  by maximum (256)
	clrf	PIE1		; turn off peripheral interrupts
	movlw	b'010110'		; enable GPIO change interrupt
	movwf	IOC		;  on GP1, GP2 and GP4 only
	clrf	VRCON		; turn off comparator V. ref.
	clrf	ANSEL		; make GP0:3 digital I/O pins
	
	bcf	STATUS, RP0	; back to Bank 0
	clrf	GPIO		; reset input/output port
	movlw	b'00001000'	; enable GPIO change interrupt
	movwf	INTCON		;  only
	movlw	b'00000111'	; turn off comparator
	movwf	CMCON		;
	clrf	T1CON		; turn off TMR1
	clrf	ADCON0		; turn off A to D converter

	movlw	d'16'		; set up postscaler
	movwf	Post16		;	
	retfie			; return, enabling interrupts

;====================
; Interrupt Service Routine
isr	btfss	INTCON, 0		; check GPIO change int. flag
	goto	Timer		; TMR0 interrupt occurred?
				; GPIO interrupt occurred?
	bcf	INTCON, 0		; reset interrupt flag	
	comf	GPIO, w		; store state of GPIO
	andlw	b'010110'		; mask all except buttons
	movwf	temp			;
	btfsc	STATUS, Z	; are any buttons actually pressed?
	retfie			; false alarm	
	bsf	STATUS, RP0	; to Bank 1
	movlw	b'001000'		; make GP1,2,4 outputs 
	movwf	TRISIO		; 
	bcf	STATUS, RP0	; move to Bank 0	
	movfw	temp		; move temp back into GPIO,
	addlw	b'100001'		;  set GP5 and GP0 (turns on 
	movwf	GPIO		;  buzzer and enables LEDs)
	movlw	b'00100000'	; enable TMR0 interrupt, disables 
	movwf	INTCON		;  the GPIO change interrupt
	retfie			; return, enabling GIE

Timer	bcf	INTCON, 2		; reset TMR0 interrupt flag
	decfsz	Post16, f		; is this the 16th TMR0 interrupt
	retfie			;
		
	bcf	GPIO, 5		; turn off buzzer
	clrf	INTCON		; turn off all interrupts 
	sleep			; go into low power mode

;============
; Program Start

Start	call	Init		; initialisation routine

Loop	goto	Loop		; keep looping

		END
