;Hypnolator - [Audiovisual overstimulation apparatus]

#include <P16F628A.INC>

;SET THE CONFIGURATION WORD
		__CONFIG	_BOREN_OFF & _CP_OFF & _DATA_CP_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _MCLRE_OFF & _INTOSC_OSC_NOCLKOUT

;RAM VARIABLE DEFINITIONS
MODE		EQU	H'0020'		;MODE STATUS
DEVSTAT		EQU	H'0021'		;DEVICE STATUS FLAGS
;7-MODE7 STATE, 6-MODE6 STATE2, 5-MODE6 STATE1, 4-MODE4 STATE, 3-MODE1 STATE, 2-MODE0 STATE, 1-MODE_SW BOUNCE GUARD, 0-MODE_SW ACTIVE
PORTA_AC	EQU	H'0030'		;PORTA ACTIVE BITS
PORTB_AC	EQU	H'0031'		;PORTB ACTIVE BITS
TONE		EQU	H'0032'		;SPEAKER TONE

;CONSTANT DEFINITIONS

;PORTA PINS
BLUE0		EQU	H'0000'		;BLUE LED 0 CONTROL (TOP RIGHT)
BLUE1		EQU	H'0001'		;BLUE LED 1 CONTROL (TOP MID-RIGHT)
BLUE2		EQU	H'0002'		;BLUE LED 2 CONTROL (TOP MID-LEFT)
BLUE3		EQU	H'0003'		;BLUE LED 3 CONTROL (TOP LEFT)
TILT_SW		EQU	H'0004'		;TILT SWITCH INPUT
VPP		EQU	H'0005'		;VPP INPUT, NOT USED
SPKR		EQU	H'0006'		;SPEAKER CONTROL
UV		EQU	H'0007'		;UV LED CONTROL

;PORTB PINS
BLUE4		EQU	H'0000'		;BLUE LED 4 CONTROL (BOTTOM)
BLUE5		EQU	H'0001'		;BLUE LED 5 CONTROL (BOTTOM RIGHT)
BLUE6		EQU	H'0002'		;BLUE LED 6 CONTROL (BOTTOM LEFT)
BLUE7		EQU	H'0003'		;BLUE LED 7 CONTROL (CENTER RIGHT)
BLUE8		EQU	H'0004'		;BLUE LED 8 CONTROL (CENTER)
BLUE9		EQU	H'0005'		;BLUE LED 9 CONTROL (CENTER LEFT)
TRIG_SW		EQU	H'0006'		;TRIGGER INPUT SWITCH
MODE_SW		EQU	H'0007'		;MODE INPUT SWITCH

;RESET VECTOR
		ORG	H'0000'
		GOTO	RESET

;INTERRUPT VECTOR
		ORG	H'0004'
		GOTO	RESET

;RESET INITIALISATION
RESET		MOVLW	B'00000111'
		MOVWF	CMCON		;DISABLE COMPARATORS
		CLRF	INTCON		;DISABLE INTERRUPTS
		MOVLW	B'00000111'
		MOVWF	T2CON		;ENABLE TIMER2, 1:1 POSTSCALER, 1:16 PRESCALER
		BSF	STATUS,RP0	;CHANGE TO REGISTER BANK 1
		MOVLW	B'01000111'
		MOVWF	OPTION_REG	;SET OPTION REGISTER
		MOVLW	B'00110000'
		MOVWF	TRISA		;PORTA 4-5 INPUT, ELSE OUTPUT
		MOVLW	B'11000000'
		MOVWF	TRISB		;PORTB 6-7 INPUT, ELSE OUTPUT
		BCF	STATUS,RP0	;CHANGE TO REGISTER BANK 0
		CLRF	PORTA		;SET DEFAULT REGISTER STATUS
		CLRF	PORTB
		CLRF	MODE
		CLRF	DEVSTAT
		CALL	TMR0INIT
		CALL	TMR2INIT
		GOTO	MAIN		;START MAIN LOOP

;TIMER0 INITIALISATION
TMR0INIT	CLRF	TMR0		;RESET TIMER0
		BCF	INTCON,T0IF	;RESET TIMER0 INTERRUPT FLAG
		RETURN

;TIMER2 INITIALISATION
TMR2INIT	CLRF	TMR2		;RESET TIMER2
		BCF	PIR1,TMR2IF	;RESET TIMER2 INTERRUPT FLAG
		RETURN

;CHECK IF MODE NEEDS UPDATING
MODE_CHK	BTFSS	PORTB,MODE_SW	;TEST IF MODE_SW ACTIVE
		GOTO	MODEACTV	;IF TRUE GOTO MODEACTV
		BTFSS	DEVSTAT,1	;TEST IF MODE_SW BOUNCE GUARD FLAG SET
		GOTO	$+3		;IF FALSE SKIP AHEAD
		BCF	DEVSTAT,1	;IF TRUE CLEAR MODE_SW BOUNCE GUARD FLAG
		RETURN
		BCF	DEVSTAT,0	;CLEAR MODE_SW ACTIVE FLAG
		RETURN
MODEACTV	BTFSC	DEVSTAT,0	;TEST IF MODE_SW ACTIVE FLAG SET
		RETURN			;IF TRUE RETURN
		BSF	DEVSTAT,0	;IF FALSE SET MODE_SW ACTIVE FLAG
		BSF	DEVSTAT,1	;SET MODE_SW BOUNCE GUARD FLAG
		RLF	MODE,F		;ROTATE MODE BITS LEFT
		BSF	MODE,0		;SET MODE BIT0
		BTFSS	MODE,7		;TEST IF MODE HAS REACHED BIT7
		RETURN			;IF FALSE RETURN
		CLRF	MODE		;IF TRUE RESET MODE
		RETURN

;SET CURRENT MODE ACTIVE BITS
MODE_SET	CALL	TMR0INIT
		BTFSS	MODE,0
		GOTO	MODE_0
		BTFSS	MODE,1
		GOTO	MODE_1
		BTFSS	MODE,2
		GOTO	MODE_2
		BTFSS	MODE,3
		GOTO	MODE_3
		BTFSS	MODE,4
		GOTO	MODE_4
		BTFSS	MODE,5
		GOTO	MODE_5
		BTFSS	MODE,6
		GOTO	MODE_6
		GOTO	MODE_7

;MODE 0
MODE_0		BTFSC	DEVSTAT,2
		GOTO	MODE_0B
		MOVLW	B'11000000'
		MOVWF	PORTA_AC
		MOVLW	B'00010000'
		MOVWF	PORTB_AC
		MOVLW	D'176'
		MOVWF	TONE
		BSF	DEVSTAT,2
		RETURN
MODE_0B		MOVLW	B'01001111'
		MOVWF	PORTA_AC
		MOVLW	B'00101111'
		MOVWF	PORTB_AC
		MOVLW	D'136'
		MOVWF	TONE
		BCF	DEVSTAT,2
		RETURN

;MODE 1
MODE_1		BTFSC	DEVSTAT,3
		GOTO	MODE_1B
		MOVLW	B'11001111'
		MOVWF	PORTA_AC
		MOVLW	B'00111111'
		MOVWF	PORTB_AC
		MOVLW	D'016'
		MOVWF	TONE
		BSF	DEVSTAT,3
		RETURN
MODE_1B		MOVLW	B'11000000'
		MOVWF	PORTA_AC
		MOVLW	B'00000000'
		MOVWF	PORTB_AC
		MOVLW	D'016'
		MOVWF	TONE
		BCF	DEVSTAT,3
		RETURN

;MODE 2
MODE_2		DECF	TONE,F
		DECF	TONE,F
		DECF	TONE,F
		DECFSZ	TONE,F
		GOTO	$+2
		GOTO	MODE_2B
		MOVLW	B'01000000'
		MOVWF	PORTA_AC
		MOVLW	B'00010000'
		MOVWF	PORTB_AC
		RETURN
MODE_2B		MOVLW	B'11001111'
		MOVWF	PORTA_AC
		MOVLW	B'00111111'
		MOVWF	PORTB_AC
		MOVLW	D'016'
		MOVWF	TONE
		RETURN

;MODE 3
MODE_3		INCF	TONE,F
		INCF	TONE,F
		INCF	TONE,F
		INCFSZ	TONE,F
		GOTO	$+2
		GOTO	MODE_3B
		MOVLW	B'01000000'
		MOVWF	PORTA_AC
		MOVLW	B'00010000'
		MOVWF	PORTB_AC
		RETURN
MODE_3B		MOVLW	B'11001111'
		MOVWF	PORTA_AC
		MOVLW	B'00111111'
		MOVWF	PORTB_AC
		MOVLW	D'064'
		MOVWF	TONE
		RETURN

;MODE 4
MODE_4		BTFSC	DEVSTAT,4
		GOTO	MODE_4B
		MOVLW	B'11001111'
		MOVWF	PORTA_AC
		MOVLW	B'00111111'
		MOVWF	PORTB_AC
		MOVLW	D'220'
		MOVWF	TONE
		BSF	DEVSTAT,4
		RETURN
MODE_4B		MOVLW	B'01000000'
		MOVWF	PORTA_AC
		MOVLW	B'00000000'
		MOVWF	PORTB_AC
		MOVLW	D'240'
		MOVWF	TONE
		BCF	DEVSTAT,4
		RETURN

;MODE 5
MODE_5		DECFSZ	TONE,F
		GOTO	$+2
		GOTO	MODE_5B
		MOVLW	B'01000000'
		MOVWF	PORTA_AC
		MOVLW	B'00010000'
		MOVWF	PORTB_AC
		RETURN
MODE_5B		MOVLW	B'11001111'
		MOVWF	PORTA_AC
		MOVLW	B'00111111'
		MOVWF	PORTB_AC
		MOVLW	D'192'
		MOVWF	TONE
		RETURN

;MODE 6
MODE_6		BTFSS	DEVSTAT,5
		GOTO	$+4
		BTFSS	DEVSTAT,6
		GOTO	MODE_6B
		GOTO	MODE_6C
		MOVLW	B'11000011'
		MOVWF	PORTA_AC
		MOVLW	B'00011000'
		MOVWF	PORTB_AC
		MOVLW	D'099'
		MOVWF	TONE
		BSF	DEVSTAT,5
		RETURN
MODE_6B		MOVLW	B'11001100'
		MOVWF	PORTA_AC
		MOVLW	B'00110000'
		MOVWF	PORTB_AC
		MOVLW	D'177'
		MOVWF	TONE
		BSF	DEVSTAT,6
		RETURN
MODE_6C		MOVLW	B'11000000'
		MOVWF	PORTA_AC
		MOVLW	B'00010111'
		MOVWF	PORTB_AC
		MOVLW	D'216'
		MOVWF	TONE
		BCF	DEVSTAT,5
		BCF	DEVSTAT,6
		RETURN

;MODE 7
MODE_7		BTFSC	DEVSTAT,7
		GOTO	MODE_7B
		MOVLW	B'11000000'
		MOVWF	PORTA_AC
		MOVLW	B'00010000'
		MOVWF	PORTB_AC
		MOVLW	D'000'
		MOVWF	TONE
		BSF	DEVSTAT,7
		RETURN
MODE_7B		MOVLW	B'11000000'
		MOVWF	PORTA_AC
		MOVLW	B'00000000'
		MOVWF	PORTB_AC
		MOVLW	D'008'
		MOVWF	TONE
		BCF	DEVSTAT,7
		RETURN

;MAIN PROGRAM LOOP
MAIN		CALL	TMR2INIT
		MOVF	TONE,W
		MOVWF	TMR2
		CLRF	PORTA
		CLRF	PORTB
		CALL	MODE_CHK
		BTFSC	INTCON,T0IF
		CALL	MODE_SET
		BTFSS	PIR1,TMR2IF
		GOTO	$-1
		BTFSC	PORTB,TRIG_SW
		GOTO	MAIN
		CALL	TMR2INIT
		MOVF	TONE,W
		MOVWF	TMR2
		MOVF	PORTA_AC,W
		MOVWF	PORTA
		BTFSS	PORTA,TILT_SW
		BCF	PORTA,SPKR
		MOVF	PORTB_AC,W
		MOVWF	PORTB
		BTFSS	PIR1,TMR2IF
		GOTO	$-1
		GOTO	MAIN		;RESTART MAIN LOOP

		END			;IF YOU GET TO HERE, SOMETHING HAS GONE WRONG -_-