;Wavecrafter - [constructing audio waveforms seeded with ambient sensory data]

;WORKING REGISTERS
W			EQU     H'0000'
F			EQU     H'0001'

;BANK 0 SPECIAL FUNCTION REGISTERS
INDF			EQU     H'0000'
TMR0			EQU     H'0001'
PCL			EQU     H'0002'
STATUS			EQU     H'0003'
FSR			EQU     H'0004'
PORTA			EQU     H'0005'
PORTB			EQU     H'0006'
PCLATH			EQU     H'000A'
INTCON			EQU     H'000B'
PIR1			EQU     H'000C'
TMR1L			EQU     H'000E'
TMR1H			EQU     H'000F'
T1CON			EQU     H'0010'
TMR2			EQU     H'0011'
T2CON			EQU     H'0012'
CCPR1L			EQU     H'0015'
CCPR1H			EQU     H'0016'
CCP1CON			EQU     H'0017'
RCSTA			EQU     H'0018'
TXREG			EQU     H'0019'
RCREG			EQU     H'001A'
CMCON			EQU     H'001F'

;BANK 1 SPECIAL FUNCTION REGISTER
OPTION_REG		EQU     H'0081'
TRISA			EQU     H'0085'
TRISB			EQU     H'0086'
PIE1			EQU     H'008C'
PCON			EQU     H'008E'
PR2			EQU     H'0092'
TXSTA			EQU     H'0098'
SPBRG			EQU     H'0099'
EEDATA			EQU     H'009A'
EEADR			EQU     H'009B'
EECON1			EQU     H'009C'
EECON2			EQU     H'009D'
VRCON			EQU     H'009F'

;STATUS REGISTER BITS
IRP			EQU     H'0007'
RP1			EQU     H'0006'
RP0			EQU     H'0005'
NOT_TO			EQU     H'0004'
NOT_PD			EQU     H'0003'
Z			EQU     H'0002'
DC			EQU     H'0001'
C			EQU     H'0000'

;INTCON REGISTER BITS
GIE			EQU     H'0007'
PEIE			EQU     H'0006'
T0IE			EQU     H'0005'
INTE			EQU     H'0004'
RBIE			EQU     H'0003'
T0IF			EQU     H'0002'
INTF			EQU     H'0001'
RBIF			EQU     H'0000'

;PIR1 REGISTER BITS
EEIF			EQU     H'0007'
CMIF			EQU     H'0006'
RCIF			EQU     H'0005'
TXIF			EQU     H'0004'
CCP1IF			EQU     H'0002'
TMR2IF			EQU     H'0001'
TMR1IF			EQU     H'0000'

;T1CON REGISTER BITS
T1CKPS1			EQU     H'0005'
T1CKPS0			EQU     H'0004'
T1OSCEN			EQU     H'0003'
NOT_T1SYNC		EQU     H'0002'
TMR1CS			EQU     H'0001'
TMR1ON			EQU     H'0000'

;T2CON REGISTER BITS
TOUTPS3			EQU     H'0006'
TOUTPS2			EQU     H'0005'
TOUTPS1			EQU     H'0004'
TOUTPS0			EQU     H'0003'
TMR2ON			EQU     H'0002'
T2CKPS1			EQU     H'0001'
T2CKPS0			EQU     H'0000'

;CCP1CON REGISTER BITS
CCP1X			EQU     H'0005'
CCP1Y			EQU     H'0004'
CCP1M3			EQU     H'0003'
CCP1M2			EQU     H'0002'
CCP1M1			EQU     H'0001'
CCP1M0			EQU     H'0000'

;RCSTA REGISTER BITS
SPEN			EQU     H'0007'
RX9			EQU     H'0006'
SREN			EQU     H'0005'
CREN			EQU     H'0004'
ADEN			EQU     H'0003'
FERR			EQU     H'0002'
OERR			EQU     H'0001'
RX9D			EQU     H'0000'

;CMCON REGISTER BITS
C2OUT			EQU     H'0007'
C1OUT			EQU     H'0006'
C2INV			EQU     H'0005'
C1INV			EQU     H'0004'
CIS			EQU     H'0003'
CM2			EQU     H'0002'
CM1			EQU     H'0001'
CM0			EQU     H'0000'

;OPTION REGISTER BITS
NOT_RBPU		EQU     H'0007'
INTEDG			EQU     H'0006'
T0CS			EQU     H'0005'
T0SE			EQU     H'0004'
PSA			EQU     H'0003'
PS2			EQU     H'0002'
PS1			EQU     H'0001'
PS0			EQU     H'0000'

;PIE1 REGISTER BITS
EEIE			EQU     H'0007'
CMIE			EQU     H'0006'
RCIE			EQU     H'0005'
TXIE			EQU     H'0004'
CCP1IE			EQU     H'0002'
TMR2IE			EQU     H'0001'
TMR1IE			EQU     H'0000'

;PCON REGISTER BITS
OSCF			EQU     H'0003'
NOT_POR			EQU     H'0001'
NOT_BOR			EQU     H'0000'

;TXSTA REGISTER BITS
CSRC			EQU     H'0007'
TX9			EQU     H'0006'
TXEN			EQU     H'0005'
SYNC			EQU     H'0004'
BRGH			EQU     H'0002'
TRMT			EQU     H'0001'
TX9D			EQU     H'0000'

;EECON1 REGISTER BITS
WRERR			EQU     H'0003'
WREN			EQU     H'0002'
WR			EQU     H'0001'
RD			EQU     H'0000'

;VRCON REGISTER BITS
VREN			EQU	H'0007'
VROE			EQU     H'0006'
VRR			EQU     H'0005'
VR3			EQU     H'0003'
VR2			EQU     H'0002'
VR1			EQU     H'0001'
VR0			EQU     H'0000'

;CONFIGURATION WORD OPTIONS
_BOREN_ON		EQU     H'3FFF'
_BOREN_OFF		EQU     H'3FBF'
_CP_ON			EQU     H'1FFF'
_CP_OFF			EQU     H'3FFF'
_DATA_CP_ON		EQU     H'3EFF'
_DATA_CP_OFF		EQU     H'3FFF'
_PWRTE_OFF		EQU     H'3FFF'
_PWRTE_ON		EQU     H'3FF7'
_WDT_ON			EQU     H'3FFF'
_WDT_OFF		EQU     H'3FFB'
_LVP_ON			EQU     H'3FFF'
_LVP_OFF		EQU     H'3F7F'
_MCLRE_ON		EQU     H'3FFF'
_MCLRE_OFF		EQU     H'3FDF'
_RC_OSC_CLKOUT		EQU     H'3FFF'
_RC_OSC_NOCLKOUT	EQU     H'3FFE'
_INTOSC_OSC_CLKOUT	EQU     H'3FFD'
_INTOSC_OSC_NOCLKOUT	EQU     H'3FFC'    
_EXTCLK_OSC		EQU     H'3FEF'
_HS_OSC			EQU     H'3FEE'
_XT_OSC			EQU     H'3FED'
_LP_OSC			EQU	H'3FEC'

;SET THE CONFIGURATION WORD
		__CONFIG	_BOREN_OFF & _CP_OFF & _DATA_CP_OFF & _PWRTE_ON & _WDT_OFF & _LVP_OFF & _MCLRE_ON & _INTOSC_OSC_NOCLKOUT

;RAM VARIABLE DEFINITIONS
SENSTAT		EQU	H'0020'		;NEXT SENSOR TRISA STATUS
SENACTV		EQU	H'0021'		;SENSOR INPUT CURRENTLY ACTIVE
WAVEMNTR	EQU	H'0022'		;WAVE MONITOR REGISTER
;7-5 - UNUSED, 4 - UPDATE BEAT PERIOD, 3 - UPDATE WAVE3, 2 - UPDATE WAVE2, 1 - UPDATE WAVE1, 0 - UNUSED
WAVE		EQU	H'0023'		;WAVE DATA
WAVE1		EQU	H'0024'		;WAVE1 DATA
WAVE2		EQU	H'0025'		;WAVE2 DATA
WAVE3		EQU	H'0026'		;WAVE3 DATA
BEATPRD		EQU	H'0027'		;BEAT PERIOD
WAVE1TMR	EQU	H'0028'		;WAVE1 TIMER
WAVE2TMR	EQU	H'0029'		;WAVE2 TIMER
WAVE3TMR	EQU	H'0030'		;WAVE3 TIMER
BEATPRDT	EQU	H'0031'		;BEAT PERIOD TIMER
WAVEDRN		EQU	H'0032'		;WAVE DURATION TIMER
WAVEPRD		EQU	H'0033'		;WAVE PERIOD TIMER

;CONSTANT DEFINITIONS
SENDFLT		EQU	B'11101111'	;SENSOR TRISA DEFAULT
SENIR		EQU	B'00000001'	;SENSOR PORTA IR
SENLDRR		EQU	B'00000010'	;SENSOR PORTA RIGHT SIDE LDR
SENLDRL		EQU	B'00000100'	;SENSOR PORTA LEFT SIDE LDR
SENTHRM		EQU	B'00001000'	;SENSOR PORTA THERMAL SENSOR
WAVEMNW1	EQU	B'00000010'	;WAVE MONITOR WAVE1
WAVEMNW2	EQU	B'00000100'	;WAVE MONITOR WAVE2
WAVEMNW3	EQU	B'00001000'	;WAVE MONITOR WAVE3
WAVEMNBP	EQU	B'00010000'	;WAVE MONITOR BEAT PERIOD
WAVE1TMD	EQU	D'16'		;WAVE1 TIMER DEFAULT
WAVE2TMD	EQU	D'30'		;WAVE2 TIMER DEFAULT
WAVE3TMD	EQU	D'58'		;WAVE3 TIMER DEFAULT

;PORTA PINS
IR		EQU	H'0000'		;IR PHOTOTRANSISTOR CONTROL
LDRR		EQU	H'0001'		;RIGHT SIDE LDR CONTROL
LDRL		EQU	H'0002'		;LEFT SIDE LDR CONTROL
THRM		EQU	H'0003'		;THERMAL SENSOR CONTROL
SENAN		EQU	H'0004'		;SENSOR ANALYSER
;PIN 5 - NOT_MCLR
PVMNTR		EQU	H'0006'		;PHOTOVOLTAIC CELL MONITOR
ANT		EQU	H'0007'		;ANTENNA SENSOR

;PORTB PINS
PZO0		EQU	H'0000'		;PIEZO 0
PZO1		EQU	H'0001'		;PIEZO 1
PZO2		EQU	H'0002'		;PIEZO 2
PZO3		EQU	H'0003'		;PIEZO 3
RED		EQU	H'0004'		;RED LED
;UNUSED		EQU	H'0005'		;UNUSED
;PIN 6 - ICSPCLK
;PIN 7 - ICSPDAT

;RESET VECTOR
		ORG	H'0000'
		GOTO	RESET

;RESET INITIALISATION
RESET		MOVLW	B'00000111'
		MOVWF	CMCON		;DISABLE COMPARATORS
		BSF	STATUS,RP0	;CHANGE TO REGISTER BANK 1
		MOVLW	B'11000011'
		MOVWF	OPTION_REG	;SET OPTION REGISTER
		CLRF	INTCON		;DISABLE INTERRUPTS
		MOVLW	B'11111111'
		MOVWF	TRISA		;PORTA ALL INPUT
		MOVLW	B'11100000'
		MOVWF	TRISB		;PORTB 5-7 INPUT, ELSE OUTPUT
		BCF	STATUS,RP0	;CHANGE TO REGISTER BANK 0
		CLRF	PORTA		;CLEAR ALL PORTS
		CLRF	PORTB
		MOVLW	WAVEMNW1	;SET DEFAULT WAVE MONITOR REGISTER
		MOVWF	WAVEMNTR
		MOVLW	WAVE1TMD	;SET DEFAULT WAVE TIMER 1
		MOVWF	WAVE1TMR
		MOVLW	WAVE2TMD	;SET DEFAULT WAVE TIMER 2
		MOVWF	WAVE2TMR
		MOVLW	WAVE3TMD	;SET DEFAULT WAVE TIMER 3
		MOVWF	WAVE3TMR
		GOTO	MAIN		;START MAIN LOOP

;TIMER0 INITIALISATION
TMR0INIT	CLRF	TMR0		;RESET TIMER0
		BCF	INTCON,T0IF	;RESTART TIMER0
		RETURN

;SENSOR ANALYSER
SENANLY		MOVLW	SENDFLT		;LOAD DEFAULT SENSOR TRISA
		MOVWF	SENSTAT		;SET SENSOR STATUS TO DEFAULT
		BSF	STATUS,RP0	;CHANGE TO REGISTER BANK 1
		MOVWF	TRISA		;LOAD NEW SENSOR STATUS INTO TRISA
		BCF	STATUS,RP0	;CHANGE TO REGISTER BANK 0
		CLRF	PORTA		;CLEAR PORTA
		BSF	SENSTAT,4	;SET SENAN SENSOR STATUS TO INPUT
		MOVF	SENSTAT,W	;LOAD SENSOR STATUS
		BSF	STATUS,RP0	;CHANGE TO REGISTER BANK 1
		MOVWF	TRISA		;LOAD NEW SENSOR STATUS INTO TRISA
		BCF	STATUS,RP0	;CHANGE TO REGISTER BANK 0
		BTFSC	PORTA,SENAN	;TEST IF SENAN IS LOW
		GOTO	SENANLY		;IF FALSE REPEAT SENANLY
		COMF	SENACTV,W	;LOAD INVERTED ACTIVE SENSOR BITS
		ANDWF	SENSTAT,W	;COMBINE ACTIVE SENSOR WITH DEFAULT
		BSF	STATUS,RP0	;CHANGE TO REGISTER BANK 1
		MOVWF	TRISA		;LOAD NEW SENSOR STATUS INTO TRISA
		BCF	STATUS,RP0	;CHANGE TO REGISTER BANK 0
		MOVF	SENACTV,W	;LOAD ACTIVE SENSOR BITS
		MOVWF	PORTA		;SET ACTIVE SENSOR BITS
		CALL	TMR0INIT	;INITIALISE TIMER0
SENLOOP		MOVF	TMR0,W		;LOAD TIMER0 VALUE
		BTFSC	PORTA,SENAN	;TEST IF SENAN HIGH
		GOTO	SENFULL		;IF TRUE GOTO SENFULL
		BTFSS	INTCON,T0IF	;TEST IF TIMER0 IS FULL
		GOTO	SENLOOP		;IF FALSE REPEAT SENLOOP
		MOVLW	B'11111111'	;LOAD MAX TIMER0 VALUE IF FULL
SENFULL		IORLW	B'00000001'	;SET BIT 0 TO ENSURE WAVE>0
		MOVWF	WAVE		;STORE TIMER0 VALUE IN WAVE
		RETURN

;WAVE SET UPDATER
WAVEUPDT	BTFSS	INTCON,T0IF	;TEST IF TIMER0 FULL
		RETURN			;IF FALSE, RETURN TO MAIN LOOP
		BTFSC	WAVEMNTR,4	;TEST IF BEAT PERIOD TO BE UPDATED
		GOTO	WAVEUPBP	;IF TRUE, SKIP AHEAD
		BTFSC	WAVEMNTR,3	;TEST IF WAVE3 TO BE UPDATED
		GOTO	WAVEUPW3	;IF TRUE, SKIP AHEAD
		BTFSC	WAVEMNTR,2	;TEST IF WAVE2 TO BE UPDATED
		GOTO	WAVEUPW2	;IF TRUE, SKIP AHEAD
WAVEUPW1	MOVLW	SENIR		;LOAD SENSOR PORTA IR
		MOVWF	SENACTV		;SET ACTIVE SENSOR STATUS
		CALL	SENANLY		;CALL SENSOR ANALYSER
		MOVF	WAVE,W		;LOAD NEW WAVE VALUE
		MOVWF	WAVE1		;STORE IN WAVE1
		MOVLW	WAVEMNW2	;SIGNAL WAVE2 TO BE UPDATED NEXT
		GOTO	WAVEUPFN
WAVEUPW2	MOVLW	SENLDRR		;LOAD SENSOR PORTA LDR RIGHT
		MOVWF	SENACTV		;SET ACTIVE SENSOR STATUS
		CALL	SENANLY		;CALL SENSOR ANALYSER
		MOVF	WAVE,W		;LOAD NEW WAVE VALUE
		MOVWF	WAVE2		;STORE IN WAVE2
		MOVLW	WAVEMNW3	;SIGNAL WAVE3 TO BE UPDATED NEXT
		GOTO	WAVEUPFN
WAVEUPW3	MOVLW	SENLDRL		;LOAD SENSOR PORTA LDR LEFT
		MOVWF	SENACTV		;SET ACTIVE SENSOR STATUS
		CALL	SENANLY		;CALL SENSOR ANALYSER
		MOVF	WAVE,W		;LOAD NEW WAVE VALUE
		MOVWF	WAVE3		;STORE IN WAVE3
		MOVLW	WAVEMNBP	;SIGNAL BEAT PERIOD TO BE UPDATED NEXT
		GOTO	WAVEUPFN
WAVEUPBP	MOVLW	SENTHRM		;LOAD SENSOR PORTA LDR LEFT
		MOVWF	SENACTV		;SET ACTIVE SENSOR STATUS
		CALL	SENANLY		;CALL SENSOR ANALYSER
		MOVF	WAVE,W		;LOAD NEW WAVE VALUE
		MOVWF	BEATPRD		;STORE IN BEAT PERIOD
		MOVLW	WAVEMNW1	;SIGNAL WAVE1 TO BE UPDATED NEXT
WAVEUPFN	MOVWF	WAVEMNTR	;STORE NEXT UPDATE IN WAVE MONITOR
		GOTO	TMR0INIT	;INITIALISE TIMER0

;WAVE CRAFTER
WAVECRFT	DECFSZ	WAVE1TMR,F	;DECREMENT WAVE1 TIMER
		GOTO	WAVE2TMT	;IF WAVE1 TIMER>0, SKIP AHEAD
		GOTO	WAVE1OUT	;IF ELSE, OUTPUT WAVE1
WAVE2TMT	DECFSZ	WAVE2TMR,F	;DECREMENT WAVE2 TIMER
		GOTO	WAVE3TMT	;IF WAVE2 TIMER>0, SKIP AHEAD
		GOTO	WAVE2OUT	;IF ELSE, OUTPUT WAVE2
WAVE3TMT	DECFSZ	WAVE3TMR,F	;DECREMENT WAVE3 TIMER
		RETURN			;IF WAVE2 TIMER>0, RETURN TO MAIN LOOP

;WAVE 3 OUTPUT
WAVE3OUT	MOVLW	WAVE3TMD	;LOAD WAVE3 TIMER DEFAULT
		MOVWF	WAVE3TMR	;STORE IN WAVE3 TIMER
		MOVF	WAVE3,W		;LOAD WAVE3
		GOTO	WAVEOUT

;WAVE 2 OUTPUT
WAVE2OUT	MOVLW	WAVE2TMD	;LOAD WAVE2 TIMER DEFAULT
		MOVWF	WAVE2TMR	;STORE IN WAVE2 TIMER
		MOVF	WAVE2,W		;LOAD WAVE2
		GOTO	WAVEOUT

;WAVE 1 OUTPUT
WAVE1OUT	MOVLW	WAVE1TMD	;LOAD WAVE1 TIMER DEFAULT
		MOVWF	WAVE1TMR	;STORE IN WAVE1 TIMER
		MOVF	WAVE1,W		;LOAD WAVE1

;WAVE OUTPUT
WAVEOUT		MOVWF	WAVEDRN		;STORE CURRENT WAVE IN WAVE DURATION
		MOVWF	WAVEPRD		;STORE CURRENT WAVE IN WAVE PERIOD
		COMF	WAVEDRN,F	;INVERT WAVE DURATION
		MOVWF	PORTB		;STORE CURRENT WAVE IN PORTB
WAVELOOP	COMF	WAVEPRD,W	;LOAD INVERTED WAVE PERIOD
		MOVWF	WAVE		;STORE IN WAVE
WAVELOOP2	DECFSZ	WAVE,F		;DECREMENT WAVE
		GOTO	WAVELOOP2	;IF WAVE>0, REPEAT WAVELOOP2
		DECF	WAVEPRD,F	;DECREMENT WAVE PERIOD
		COMF	PORTB,F		;LOAD INVERTED PORTB
		BTFSS	PORTA,PVMNTR	;TEST IF PHOTOVOLTAIC CELL IS POWERING THE CIRCUIT
		BCF	PORTB,RED	;IF FALSE, DISABLE RED LED
		DECFSZ	WAVEDRN,F	;DECREMENT WAVE DURATION
		GOTO	WAVELOOP	;IF WAVE DURATION>0, REPEAT WAVELOOP
		RETURN			;IF ELSE, RETURN TO MAIN LOOP

;BEAT PERIOD DELAY
BEATPRDD	MOVF	BEATPRD,W	;LOAD BEAT PERIOD
		MOVWF	BEATPRDT	;STORE IN BEAT PERIOD TIMER
BEATLOOP	CALL	TMR0INIT	;INITIALISE TIMER0
		MOVLW	D'252'		;SET TIMER0 TO 252
		MOVWF	TMR0
BEATLOOP2	BTFSS	INTCON,T0IF	;TEST IF TIMER0 FULL
		GOTO	BEATLOOP2	;IF FALSE, REPEAT BEATLOOP2
		DECFSZ	BEATPRDT,F	;DECREMENT BEAT PERIOD TIMER
		GOTO	BEATLOOP	;IF BEAT PERIOD TIMER>0, REPEAT BEATLOOP
		RETURN			;IF ELSE, RETURN TO MAIN LOOP

;MAIN PROGRAM LOOP
MAIN		CALL	WAVEUPDT	;UPDATE WAVE DATA
		CALL	BEATPRDD	;DELAY FOR BEAT PERIOD
		CALL	WAVECRFT	;CRAFT AND OUTPUT WAVES
		GOTO	MAIN		;RESTART MAIN LOOP

		END			;IF YOU GET TO HERE, SOMETHING HAS GONE WRONG -_-