;******************************************************************************
;******************************************************************************
;
;File Name:	Thumb_Stadium_setup_files_v1.asm
;Author:	ThumbStadium.com	
;Date:  	March 22, 2009
;Version:	1
;Description:	Thumb Stadium open source setup files - for use with Thumb Stadium  
;
;******************************************************************************
;******************************************************************************
;Modified:	
;******************************************************************************
; Notes:	This is the version for the 12F629 8-pin chip
; 
; This gets the pins set up and the lights flashing, the rest is up to you!
;
; Be sure to read the 12F629 datasheet thoroughly
;
;******************************************************************************
;******************************************************************************

	list      p=12F629			; list directive to define processor
	#include <p12f629.inc>		; includes the right linker file right into this code file

	__CONFIG   _CP_OFF & _CPD_OFF & _BODEN_OFF & _MCLRE_OFF & _WDT_OFF & _PWRTE_ON & _INTRC_OSC_NOCLKOUT

								; '__CONFIG' directive is used to embed configuration word within .asm file.
								; The labels following the directive are located in the respective .inc file.
								; See data sheet for additional information on configuration word settings.


;******************************************************************************
; register address names assigned to their respective register so you can use the label instead:

;	code						; this command is mandatory when using the assembler commands and shortcuts
								; not necessary when you stick to the fundamental commands [PIC instruction set]
;******************************************************************************
; NEED TO ASSIGN ALL THE VARIABLES HERE FIRST
;******************************************************************************

;***** VARIABLE DEFINITIONS *****

INT_VAR		UDATA_SHR	0x20   
w_temp		RES     1		; variable used for context saving 
status_temp	RES     1		; variable used for context saving

bigdelay res 1					; placeholder for 255 count
maindly res 1					; placeholder for 255 count
superdly res 1					; this sets the overall delay
duperdly res 1					; holds the superdly value

temp res 1

;******************************************************************************
; RESET VECTOR - tells the assembler - "use this as the beginning of the program"
;******************************************************************************

RESET_VECTOR	CODE	0x000		; processor reset vector
		goto    main              ; go to beginning of program

;******************************************************************************
; INTERRUPT VECTOR - this is where you put the subroutine call for the interrupt routine
;******************************************************************************


INT_VECTOR	CODE	0x004		; interrupt vector location
		movwf   w_temp            ; save off current W register contents
		movf	STATUS,w          ; move status register into W register
		movwf	status_temp       ; save off contents of STATUS register


; isr code can go here or be located as a call subroutine elsewhere

;	banksel INTCON					; re-enables the interrupt on GP2
;	bcf INTCON,1

		movf    status_temp,w     ; retrieve copy of STATUS register
		movwf	STATUS            ; restore pre-isr STATUS register contents
		swapf   w_temp,f
		swapf   w_temp,w          ; restore pre-isr W register contents
		retfie                    ; return from interrupt



; =====================================================
; HERE IS THE MAIN PROGRAM
; =====================================================

main

; CALIBRATE THE INTERNAL OSCILLATOR

		bsf     STATUS,RP0        ; set file register bank to 1 
		call    3FFh             ; retrieve factory calibration value
		movwf   OSCCAL            ; update register with factory cal value 
		bcf     STATUS,RP0        ; set file register bank to 0


; ======================================================================================
; CHIP SPECIFIC SETUP STUFF - ASSIGN PINS ETC.
; ======================================================================================

	movlw b'001010'
	banksel TRISIO
	movwf TRISIO			; sets pins 4 and 6 as inputs (GP1, GP3), pins 2, 3, 5, 7 as outputs (GP0, GP2, GP4, GP5)
							; Note that GP3 is always an input on the 12F629 chip



; ****************************************
; IMPORTANT NOTE!
; ****************************************
; 
; Thumb Stadium does not use resistors on the LEDs
; Because of this, when any activity related to GPIO occurs (bit test, read, write, etc.)
; GPIO,2 (pin 5) will turn off
; as such, avoid turning individual LEDs off
; instead, write the entire regsiter all at once, like this:

; tworeds
;	movlw b'00100100'		; turn on the two reds
;	banksel GPIO
;	movwf GPIO
;	return

; Do this rather than changing individual bits using bsf or bcf
; so you reset GPIO,2 each time

; another approach is to track the status of GPIO,2 with another variable
; and re-load its status after any GPIO activity

; ****************************************




	banksel WPU				; disable all the weak pullups on GPIO inputs
	clrf WPU				; because the Thumb Stadium inputs are read when high, not low

	banksel OPTION_REG
	bsf OPTION_REG,6		; makes it a rising edge triggered interrupt

	banksel INTCON
;	bsf INTCON,7			; seting the Global Inerrupt Enable bit allows interrupts
;	bcf INTCON,6			; clearing this disables all peripheral interrupts
;	bcf INTCON,5			; clearing this disables the TMR0 interrupt
;	bsf INTCON,4			; setting this enables the RA2/INT interrupt (pin 5)
;	bcf INTCON,3			; clearing this disables the GPIO interrupt on change
;	bcf INTCON,2			; clears the TMR0 interrupt flag bit just to be safe
;	bcf INTCON,1			; clears the RA2/INT inerrupt flag just to be safe - will need to do this at end of interrupt routine
;	bcf INTCON,0			; clears the PORTA change interrupt flag bit just to be safe
	clrf INTCON				; this command disables all the interrupts

	banksel CMCON
	movlw 0x07				; disables comparators - might cause problems if you don't do this
	movwf CMCON	


; ======================================================================================
; START OF ACTUAL PROGRAM
; ======================================================================================

	movlw .3
	banksel superdly
	movwf superdly			; sets the initial value for superdly


startup						; this is the looping section for the initial light show
	call twogreens			; that let's people know it is operational

	call delay1

	call tworeds

	call delay1

	goto startup


; ============================================================================

delay1
	call movesuperdly

loop1
	movlw .100
	banksel bigdelay
	movwf bigdelay	

loop2
	call maindly255

loop3
	banksel GPIO				; PRESSING THE GREEN PLAYER BUTTON ADVANCES IT TO THE NEXT ROUTINE
	btfsc GPIO,1				; check the input on Pin 6 -     
	goto modetest				; if high, goto modetest, if low skip this instruction - normally low on Thumb Stadium

	banksel maindly					
	decfsz maindly,1
	goto loop3

	banksel bigdelay
	decfsz bigdelay,1			; decreases maindly by 1 and when it hits 0 then skips next line
	goto loop2					; by skipping next instruction ~ 'goto loop1'

	banksel duperdly
	decfsz duperdly,1
	goto loop1

	return


; ============================================================================

modetest
	call debouncer1				; don't do anything until the switch is stable

	banksel GPIO
	clrf GPIO					; turn off all the LEDs to confirm button press


	; branch to the next routine here



	goto modetest					; set to perpetually loop







; ==============================================
; THIS IS THE COMMON LOOP SECTION TO SAVE SPACE
; ==============================================

movesuperdly
	banksel superdly			
	movf superdly,0				; moves the intended value to the W register
	banksel duperdly
	movwf duperdly				; places the value from superdly to duperdly via W register
	return

maindly255
	movlw .180					; sets the value for maindly
	banksel maindly				; changes to the bank for maindly
	movwf maindly				; moves the W register value to maindly
	return

twogreens
	movlw b'00010001'		; turn on the two green LEDs
	banksel GPIO
	movwf GPIO
	return

tworeds
	movlw b'00100100'		; turn on the two red LEDs
	banksel GPIO
	movwf GPIO
	return

debouncer1						; this subroutine pauses the program until the player 1 switch is low again before continuing
	banksel GPIO				; THIS IS FOR PLAYER 1 BUTTON ONLY - GREEN
	btfsc GPIO,1				; checks the input on Pin 6    
	goto debouncer1				; if low, then finish up, otherwise goto debouncer1 and try again

	return


debouncer2						; this subroutine pauses the program until the player 2 switch is low again before continuing
	banksel GPIO				; THIS IS FOR PLAYER 2 BUTTON ONLY - RED
	btfsc GPIO,3				; checks the input on Pin 4 
	goto debouncer2				; if low, then finish up, otherwise goto debouncer2 and try again

	return


	end						; needed by some compilers - good pratice to include this
