;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;Automatic light show controller program for 16f84 from Microchip
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;
;Copyright (c) 2000 by Elektuur BV, All rights reserved.
;
;File name:	light.asm
;
;Author:	Ron Wouters
;
;Date:		19-3-2000
;
;Revision:	1.73
;
;Description:	Assembly code for the PIC16f84 microcontroller from microchip 
;		for automatic lightshow.
;
;Inputs: 	PORTA,0		;Audio Very LF synchro input
;		PORTA,1		;Audio LF input
; 		PORTA,2		;Audio MF input
;		PORTA,3		;Audio HF input
;		PORTA,4		;Input switch light organ/automatic mode
;
;Outputs:	PORTB,0		;Lamp 1 low
;		PORTB,1		;Lamp 2	low
;		PORTB,2		;Lamp 3 mid
;		PORTB,3		;Lamp 4	high
;		PORTB,4		;Lamp 5 high
;		PORTB,5		;Not used
;		PORTB,6		;Not used
;		PORTB,7		;Not used
;
;Oscillator:	Crystal 4.096 MHz
;
;Prescaler:	Set to 128 on TMR0
;
;Postscaler:	Timer every 1 mS overfloats, Timer0 preloaded with 31 mS, 
;		(this is F8h) so every 1 mSec the program LOOP is executed
;
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
	list               p=16f84
	#include           <p16f84.INC>

	__Config  _XT_OSC & _WDT_OFF & _PWRTE_OFF

MEMO1	EQU	0Ch		;Status inputs
MEMO2	EQU	0Dh		;Bit check register
MEMO2A	EQU	0Eh		;Rotate left register
MEMO2B	EQU	0Fh		;Rotate left/right register
MEMO3	EQU	10h		;Bit check register
MEMO4	EQU	11h		;Random light register
MEMO5	EQU	12h		;Random light register
MEMO6	EQU	13h		;Random light register
MEMO7	EQU	14h		;Random light which lamp is set
MEMO8	EQU	15h		;Rotate right register
LAMP0	EQU	16h		;Lamp 0 bit is 1
LAMP1	EQU	17h		;Lamp 1 bit is 1
LAMP2	EQU	18h		;Lamp 2 bit is 1
LAMP3	EQU	19h		;Lamp 3 bit is 1
LAMP4	EQU	20h		;Lamp 4 bit is 1
CNT1	EQU	21h		;Timer of 250 mS 
CNT2	EQU	22h		;Timer of 4 S 
CNT3	EQU	23h		;Timer of 250 mS
CNT4	EQU	24h		;Timer of 100 mS
CNT5	EQU	25h		;Timer of 250 mS
CNT6	EQU	26h		;Timer of 30 S
CNT7	EQU	27h		;Timer of 50 mS 
CNT8	EQU	28h		;Timer of 250 mS
CNT9	EQU	29h		;Timer of 6 S
MODE	EQU	30h		;Mode register
OLDINP	EQU	31h		;Old input status register
	ORG   	0x000
	GOTO START
;*******************************************************************
;Initialise the necessary registers
;*******************************************************************
START	CLRF	PORTA
	CLRF	PORTB
	BSF   	STATUS,RP0	;Bank 1
	MOVLW 	0x00
	MOVWF	TRISB		;Set PORTB as outputs
	MOVLW 	0x1F
	MOVWF	TRISA		;Set PORTA,0,1,2,3,4 as input
	BCF	OPTION_REG,0	;Prescaler set to 128
	BCF	OPTION_REG,3	;Prescaler assigned to TMR0
	BCF	OPTION_REG,5	;Internal instruction cycle clock
	BCF   	STATUS,RP0	;Bank 0
	CLRF	MEMO1		;Clear register MEMO1
	CLRF	MEMO2		;Clear register MEMO2
	CLRF	MEMO2A		;Clear register MEMO2A
	CLRF	MEMO3		;Clear register MEMO3
	CLRF	MEMO4		;Clear register MEMO4
	CLRF	MEMO5		;Clear register MEMO5
	CLRF	MEMO6		;Clear register MEMO6
	CLRF	MEMO7		;Clear register MEMO7
	CLRF	CNT1		;Clear register CNT1
	CLRF	CNT2		;Clear register CNT2
	CLRF	CNT3		;Clear register CNT3
	CLRF	MODE		;Clear register MODE
	CLRF	OLDINP		;Clear register OLDINP
	MOVLW	001h		
	MOVWF	LAMP0		;Lamp 0 on
	MOVLW	002h		
	MOVWF	LAMP1		;Lamp 1 on
	MOVLW	004h		
	MOVWF	LAMP2		;Lamp 2 on
	MOVLW	008h		
	MOVWF	LAMP3		;Lamp 3 on
	MOVLW	010h		
	MOVWF	LAMP4		;Lamp 4 on
	MOVLW	020h		
	MOVWF	MEMO2B		;Load rotate register with 20h
	MOVLW	0FAh		
	MOVWF	CNT1		;Timer of 250 mS 
	MOVLW	010h		
	MOVWF	CNT2		;Timer 16 x 250 mS= 4 S
	MOVLW	0FAh		
	MOVWF	CNT3		;Timer of 250 mS 
	MOVLW	064h		
	MOVWF	CNT4		;Timer 100 mS
	MOVLW	0FAh		
	MOVWF	CNT5		;Timer 250 mS
	MOVLW	078h		
	MOVWF	CNT6		;Timer 120 x 250 mS= 30 S
	MOVLW	032h		
	MOVWF	CNT7		;Timer 50 mS
	MOVLW	0FAh		
	MOVWF	CNT8		;Timer 250 mS
	MOVLW	018h		
	MOVWF	CNT9		;Timer 24 x 250 mS= 6 S
	MOVLW	0E0h		;Preload register with 224h
	MOVF	MEMO8		;Rotate right register
	MOVF	PORTA,0
	MOVWF	OLDINP		;Load inputs in OLDINP
	MOVLW	00Ah		
	MOVWF	MODE		;Load Mode register with 10
;*******************************************************************
;*******************************************************************
;Program loop
;*******************************************************************
	MOVLW	0F8h		;Preload counter with 256-8
	MOVWF	TMR0
LOOP	BTFSS	INTCON,2	;Everey 1 mSec timer overflows
	GOTO 	LOOP
	BCF	INTCON,2	;Every 1 mSec program runs from here
	MOVLW	0F8h		;Preload counter again with 256-8
	MOVWF	TMR0
;********************************************************************
;********************************************************************
;Read inputs
;********************************************************************
	MOVF	PORTA,0
	MOVWF	MEMO1
	BTFSS	MEMO1,1		;Chech if nothing happens on llf
	GOTO	NEXTC
	BTFSS	MEMO1,2		;Chech if nothing happens on mlf
	GOTO	NEXTC	
	BTFSS	MEMO1,3		;Chech if nothing happens on hlf
	GOTO	NEXTC
	BTFSC	MEMO3,2		;Is random mode on
	GOTO	MODE8
	BSF 	MEMO2,4		;Set bit no sound detected
	DECFSZ	CNT5,1		;30 sec timer
	GOTO	NEXTC
	MOVLW	0FAh
	MOVWF	CNT5
	DECFSZ	CNT6,1		;30 sec timer
	GOTO	NEXTC
	MOVLW	078h
	MOVWF	CNT6	
	BSF	MEMO3,2		;Set random mode on bit
	GOTO 	MODE8
NEXTC	BCF	MEMO3,2		;Sound detected clear random mode bit
	BTFSC	MEMO2,4		;Is sound detected
	GOTO	NEXTD	
	BCF	MEMO2,4		;Sound detected clear bit
	MOVLW	0FAh		;Load 30s timer again
	MOVWF	CNT5
	MOVLW	078h		;Load 30s timer again
	MOVWF	CNT6
NEXTD	BCF	MEMO2,4		;Check no sound detected bit
	BTFSS	MEMO1,0		;Check if nothing happens on vlf input
	GOTO 	NEXTA
	BTFSC	MEMO3,4		;Is 6 sec timer done
	GOTO	MODE0
	DECFSZ	CNT8,1		;Nothing happens for 6 sec timer
	GOTO	NEXTB
	MOVLW	0FAh		;Load cnt 5 again
	MOVWF	CNT8
	DECFSZ	CNT9,1		;Nothing happens for 6 sec timer		
	GOTO 	NEXTB
	MOVLW	018h		;Load cnt 6 again
	MOVWF	CNT9
	BSF	MEMO3,4		;Nothing has happened on vlf for 6 sec
	GOTO	MODE0
NEXTA	BCF	MEMO3,4		;Clear 6 sec timer done
	MOVLW	0FAh		;Load cnt8 again
	MOVWF	CNT8	
	MOVLW	018h		;Load cnt9 again
	MOVWF	CNT9
NEXTB	BTFSS	MEMO1,4		;Light organ or automatic mode
	GOTO	MODE0		;Light organ mode
	DECFSZ	CNT1,1		;Timer of 250 mS 
	GOTO 	MODEX
	MOVLW	0FAh		;Load timer again with 250 mS 
	MOVWF	CNT1		
	DECFSZ	CNT2,1		;Timer 16 x 250 mS= 4 S
	GOTO	MODEX
	MOVLW	010h		;Load timer again with 4 S
	MOVWF	CNT2		
	BCF	PORTB,0		;Clear lamp output
	BCF	PORTB,1		;Clear lamp output
	BCF	PORTB,2		;Clear lamp output
	BCF	PORTB,3		;Clear lamp output
	BCF	PORTB,4		;Clear lamp output
	DECFSZ	MODE,1		;Decrement mode register
	GOTO 	MODEX
	MOVLW	00Ah		;Mode reg is 0, load again with 10
	MOVWF	MODE
;********************************************************************
;********************************************************************
;Determine mode setting
;********************************************************************
MODEX	BTFSS	MODE,3		;Check bit 3 of mode register
	GOTO	CHK2
	BTFSS	MODE,1		;Check bit 1 of mode register
	GOTO	CHK1
	GOTO	MODE5		;Transition 1
CHK1	BTFSS	MODE,0		;Check bit 0 of mode register
	GOTO	MODE4		;Transition 3
	GOTO	MODE0		;Transition 2
CHK2	BTFSS	MODE,2		;Check bit 2 of mode register
	GOTO	CHK3
	BTFSS	MODE,1		;Check bit 1 of mode register
	GOTO	CHK4
	BTFSS	MODE,0		;Check bit 0 of mode register
	GOTO	MODE3		;Transition 5
	GOTO	MODE0		;Transition 4
CHK4	BTFSS	MODE,0		;Check bit 0 of mode register
	GOTO	MODE2		;Transition 7
	GOTO	MODE0		;Transition 6
CHK3	BTFSS	MODE,1		;Check bit 1 of mode register
	GOTO	MODE0		;Transition 8	
	BTFSS	MODE,0		;Check bit 0 of mode register
	GOTO	MODE1		;Transition 9
	GOTO	MODE0		;Transition 10
;********************************************************************
;********************************************************************
;MODE0 light organ low mid high lamps
;********************************************************************
MODE0	MOVF 	MEMO1,0		;Store old input setting
	MOVWF	OLDINP
	BCF	PORTB,0		;Clear lamp output
	BCF	PORTB,1		;Clear lamp output
	BCF	PORTB,2		;Clear lamp output
	BCF	PORTB,3		;Clear lamp output
	BCF	PORTB,4		;Clear lamp output
	BTFSC 	MEMO1,1		;Is signal on low input
	GOTO 	LO
	BSF	PORTB,0
	BSF	PORTB,1
LO	BTFSC 	MEMO1,2		;Is signal on mid input
	GOTO	LO1
	BSF	PORTB,2
LO1	BTFSC 	MEMO1,3		;Is signal on high input
	GOTO	LOOP
	BSF	PORTB,3
	BSF	PORTB,4
	GOTO 	LOOP
;********************************************************************
;********************************************************************
;MODE1 walking light down
;********************************************************************
MODE1	BTFSC	MEMO3,6		;Is mode active
	GOTO	ON
	BTFSC	MEMO1,0		;Is input low
	GOTO 	ALEND
	BTFSS	OLDINP,0	;Is oldinp high	
	GOTO 	ALEND
ON	BSF	MEMO3,6
	DECFSZ	CNT7,1		;Timer of 50 mS 
	GOTO 	ALEND
	MOVLW	032h		;Load timer again with 50 mS	
	MOVWF	CNT7		
	BSF	STATUS,0
	RRF	MEMO8,1
	BTFSC	MEMO8,4
	BSF	PORTB,4
	BTFSC	MEMO8,3
	BSF	PORTB,3
	BTFSC	MEMO8,2
	BSF	PORTB,2
	BTFSC	MEMO8,1
	BSF	PORTB,1
	BTFSC	MEMO8,0
	BSF	PORTB,0
	BTFSS	MEMO8,0
	GOTO	ALEND
	BTFSC	MEMO2,3
	GOTO    CLRLMPS	
	BSF	MEMO2,3
	GOTO    ALEND
CLRLMPS	BCF	PORTB,0
	BCF	PORTB,1
	BCF	PORTB,2
	BCF	PORTB,3
	BCF	PORTB,4
	MOVLW	0E0h
	MOVWF	MEMO8
	BCF	MEMO2,3	
	BCF	MEMO3,6
ALEND	MOVF 	MEMO1,0
	MOVWF	OLDINP
	GOTO 	LOOP
;********************************************************************
;********************************************************************
;MODE2 walking light on beat
;********************************************************************
MODE2	BTFSC	MEMO1,0		;Is input low
	GOTO 	WLKEND
	BTFSS	OLDINP,0	;Is oldinp high	
	GOTO 	WLKEND	
	BTFSC	MEMO3,7		;Which direction
	GOTO 	WLL
	BCF	STATUS,0	;Clear carry bit
	RRF	MEMO2B,1	;Rotate memo2a right
	MOVF	MEMO2B,0
	MOVWF	PORTB
	BTFSS	MEMO2B,0	;Is bit 0 set
	GOTO 	WLKEND
	BSF	MEMO3,7
	GOTO 	WLKEND
WLL	BCF	STATUS,0	;Clear carry bit
	RLF	MEMO2B,1
	MOVF	MEMO2B,0
	MOVWF	PORTB
	BTFSS	MEMO2B,4	;Is bit 4 set
	GOTO 	WLKEND	
	BCF	MEMO3,7		
WLKEND	MOVF 	MEMO1,0
	MOVWF	OLDINP
	GOTO 	LOOP
;********************************************************************
;********************************************************************
;MODE3 walking lights up on beat
;********************************************************************
MODE3	BTFSC	MEMO3,3
	GOTO	ARRWLK
	BTFSC	MEMO1,0		;Is input low
	GOTO 	ARREND
	BTFSS	OLDINP,0	;Is oldinp high
	GOTO 	ARREND
	BSF	MEMO3,3		;Slope 1 to 0
	MOVLW	001h		;Load MEMO2A with 001h
	MOVWF	MEMO2A		;Rotate left register
	MOVF	MEMO2A,0
	MOVWF	PORTB
ARRWLK	DECFSZ	CNT7,1		;Timer of 50 mS 
	GOTO 	ARREND
	MOVLW	032h		;Load timer again with 50 mS	
	MOVWF	CNT7		
	BCF	STATUS,0	;Clear carry bit
	RLF	MEMO2A,1	;Rotate MEMO2A left
	MOVF	MEMO2A,0
	MOVWF	PORTB		;Write MEMO2A to PORTB
	BTFSS	MEMO2A,4	;Is lamp 4 ON
	GOTO	ARREND
	BCF	MEMO3,3		;Sequence done
ARREND	MOVF 	MEMO1,0
	MOVWF	OLDINP	
	GOTO 	LOOP
;********************************************************************
;********************************************************************
;MODE4 walking light out of middle
;********************************************************************
MODE4	BTFSC	MEMO3,1		;Is mode active
	GOTO	WLM3
	BTFSC	MEMO1,0		;Is input low
	GOTO 	WLEND
	BTFSS	OLDINP,0	;Is oldinp high	
	GOTO 	WLEND	
	BSF	MEMO3,1
WLM3	DECFSZ	CNT7,1		;Timer of 50 mS 
	GOTO 	WLEND
	MOVLW	032h		;Load timer again with 50 mS	
	MOVWF	CNT7		
	BTFSC	MEMO2,0		;Is middle led on
	GOTO	WLM1	
	BCF	PORTB,0
	BCF	PORTB,4
	BSF	PORTB,2
	BSF 	MEMO2,0
	GOTO	WLEND
WLM1	BTFSC	MEMO2,1		;Is led 1 and 3 on
	GOTO	WLM2
	BCF	PORTB,2
	BSF	PORTB,1
	BSF	PORTB,3
	BSF	MEMO2,1
	GOTO	WLEND
WLM2	BCF	PORTB,1		;Set led 0 and 4
	BCF	PORTB,3
	BSF	PORTB,0
	BSF	PORTB,4
	BCF	MEMO2,0
	BCF	MEMO2,1
	BCF	MEMO2,2
	BCF	MEMO3,1
WLEND	MOVF 	MEMO1,0
	MOVWF	OLDINP
	GOTO 	LOOP
;********************************************************************
;********************************************************************
;MODE5 2 or 3 lamps on bass
;********************************************************************
MODE5	BTFSC	MEMO1,0		;Is input low
	GOTO 	ALLMP
	BTFSS	OLDINP,0	;Is oldinp high
	GOTO 	ALLMP
	BTFSC	MEMO3,0
	GOTO	ALLMP1
	BSF	PORTB,0		;Set lamp 0
	BCF	PORTB,1		;Clear lamp 1
	BSF	PORTB,2		;Set lamp 2
	BCF	PORTB,3		;Clear lamp 3
	BSF	PORTB,4		;Set lamp 4		
	BSF	MEMO3,0
	GOTO 	ALLMP
ALLMP1	BCF	PORTB,0		;Clear lamp 0
	BSF	PORTB,1		;Set lamp 1
	BCF	PORTB,2		;Clear lamp 2
	BSF	PORTB,3		;Set lamp 3
	BCF	PORTB,4		;Clear lamp 4
	BCF	MEMO3,0
ALLMP	MOVF 	MEMO1,0
	MOVWF	OLDINP
	GOTO 	LOOP
;********************************************************************
;********************************************************************
;MODE8 random lights
;********************************************************************
MODE8	BTFSC	MEMO3,5
	GOTO	RAND	
	BTFSC	MEMO4,0
	GOTO	R1
	MOVF	LAMP2,0
	MOVWF	MEMO7
	BSF	MEMO4,0
	GOTO	NEXT
R1	BTFSC	MEMO4,1
	GOTO	R2
	MOVF	LAMP3,0
	MOVWF	MEMO7
	BSF	MEMO4,1
	GOTO	NEXT
R2	BTFSC	MEMO4,2
	GOTO	R3
	MOVF	LAMP1,0
	MOVWF	MEMO7
	BSF	MEMO4,2
	GOTO	NEXT
R3	BTFSC	MEMO4,3
	GOTO	R4
	MOVF	LAMP0,0
	MOVWF	MEMO7
	BSF	MEMO4,3
	GOTO	NEXT
R4	BTFSC	MEMO4,4
	GOTO	R5
	MOVF	LAMP4,0
	MOVWF	MEMO7
	BSF	MEMO4,4
	GOTO	NEXT
R5	BTFSC	MEMO4,5
	GOTO	R6
	MOVF	LAMP2,0
	MOVWF	MEMO7
	BSF	MEMO4,5
	GOTO	NEXT
R6	BTFSC	MEMO4,6
	GOTO	R7
	MOVF	LAMP0,0
	MOVWF	MEMO7
	BSF	MEMO4,6
	GOTO	NEXT
R7	BTFSC	MEMO4,7
	GOTO	R8
	MOVF	LAMP3,0
	MOVWF	MEMO7
	BSF	MEMO4,7
	GOTO	NEXT
R8	BTFSC	MEMO5,0
	GOTO	R9
	MOVF	LAMP2,0
	MOVWF	MEMO7
	BSF	MEMO5,0
	GOTO	NEXT
R9	BTFSC	MEMO5,1
	GOTO	R10
	MOVF	LAMP4,0
	MOVWF	MEMO7
	BSF	MEMO5,1
	GOTO	NEXT
R10	BTFSC	MEMO5,2
	GOTO	R11
	MOVF	LAMP3,0
	MOVWF	MEMO7
	BSF	MEMO5,2
	GOTO	NEXT
R11	BTFSC	MEMO5,3
	GOTO	R12
	MOVF	LAMP1,0
	MOVWF	MEMO7
	BSF	MEMO5,3
	GOTO	NEXT
R12	BTFSC	MEMO5,4
	GOTO	R13
	MOVF	LAMP4,0
	MOVWF	MEMO7
	BSF	MEMO5,4
	GOTO	NEXT
R13	BTFSC	MEMO5,5
	GOTO	R14
	MOVF	LAMP2,0
	MOVWF	MEMO7
	BSF	MEMO5,5
	GOTO	NEXT
R14	BTFSC	MEMO5,6
	GOTO	R15
	MOVF	LAMP0,0
	MOVWF	MEMO7
	BSF	MEMO5,6
	GOTO	NEXT
R15	BTFSC	MEMO5,7
	GOTO	R16
	MOVF	LAMP1,0
	MOVWF	MEMO7
	BSF	MEMO5,7
	GOTO	NEXT
R16	BTFSC	MEMO6,0
	GOTO	R17
	MOVF	LAMP3,0
	MOVWF	MEMO7
	BSF	MEMO6,0
	GOTO	NEXT
R17	BTFSC	MEMO6,1
	GOTO	R18
	MOVF	LAMP1,0
	MOVWF	MEMO7
	BSF	MEMO6,1
	GOTO	NEXT
R18	BTFSC	MEMO6,2
	GOTO	R19
	MOVF	LAMP4,0
	MOVWF	MEMO7
	BSF	MEMO6,2
	GOTO	NEXT
R19	BTFSC	MEMO6,3
	GOTO	R20
	MOVF	LAMP3,0
	MOVWF	MEMO7
	BSF	MEMO6,3
	GOTO	NEXT
R20	BTFSC	MEMO6,4
	GOTO	R21
	MOVF	LAMP0,0
	MOVWF	MEMO7
	BSF	MEMO6,4
	GOTO	NEXT
R21	BTFSC	MEMO6,5
	GOTO	R22
	MOVF	LAMP2,0
	MOVWF	MEMO7
	BSF	MEMO6,5
	GOTO	NEXT
R22	BTFSC	MEMO6,6
	GOTO	R23
	MOVF	LAMP1,0
	MOVWF	MEMO7
	BSF	MEMO6,6
	GOTO	NEXT
R23	BTFSC	MEMO6,7
	GOTO	R24
	MOVF	LAMP0,0
	MOVWF	MEMO7
	BSF	MEMO6,7
	GOTO	NEXT
R24	MOVF	LAMP4,0
	MOVWF	MEMO7
	CLRF	MEMO4
	CLRF	MEMO5
	CLRF	MEMO6
NEXT	BCF	PORTB,0
	BCF	PORTB,1
	BCF	PORTB,2
	BCF	PORTB,3
	BCF	PORTB,4
	BTFSC	MEMO7,0
	BSF	PORTB,0
	BTFSC	MEMO7,1
	BSF	PORTB,1
	BTFSC	MEMO7,2
	BSF	PORTB,2
	BTFSC	MEMO7,3
	BSF	PORTB,3
	BTFSC	MEMO7,4
	BSF	PORTB,4	
	BSF	MEMO3,5
RAND	DECFSZ	CNT4,1		;Timer of 100 mS 
	GOTO 	LOOP
	MOVLW	064h		;Load timer again with 100 mS
	MOVWF	CNT4		
	BCF	MEMO3,5
	GOTO 	LOOP
;********************************************************************

	END

