'---------------------------------------------
'PUBLIC DOMAIN
'---------------------------------------------

'*******************************************************************
'********************* JIBBER JABBER *******************************
'*******************************************************************

'*****************************************************
' PSIM-1 (Programmable Synthesizer Interface Module)
'
' Module: PSIM-1 REV1b
' Revision Date:  2004/02/19  12:00 AM
' Processor Type: Basic Micro - Basic Atom Pro24M
'
'
' Basic Program Developed by Grant Richter
' Special thanks to Brice for his assistance.
'
' Description:
' Master Clock Interface  Uses a pulse on CV IN 4 to get 96 ppq
'  	clocks.   Sends divided down pulses to outs 1 to 4 
'   and midi clock out to midi out (fun for syncing drum machines
'   without having to use the pc to generate clock)
'   96 ppq is pretty fast so an oscillator pulse wave or a high freq
'   VC Clock is recommended.
'   
'   There is an inhibit which in on cv in 1 which inhibits clock on 
'   the 4 outs but not on the aux which continues with 16th notes
'   
'
' MIDI connector:
'
' Pin 4 throught 220 ohm to PSIM pin 37
' Pin 5 throught 220 ohm to PSIM pin 38 (+5V)
'
' DIN Synch:
'
' RUNLED pin 10 is DIN Synch Start/Stop Pin 1
' AUX pin 8 is DIN Synch Clock Pin 3
' GROUND is DIN Synch Pin 2
'
' Process Indicators:
'
' StopLED = Clock Stopped
' RunLED = Clock Running
' 
' Inputs and Outputs:
' Start PB or Jack: Run light On Start Master Clock
' Stop PB or Jack: Stop Light On Stop Master Clock
'
' CV In 1 - Clock off all inhibit all clocks but Aux out
' CV In 2 - 
' CV In 3 - 
' CV In 4 - Clock Rate 96ppq 
' use very fast gate or pulse wave off an osc for midi out clock

' CV Out 1 - Quarter Note Analog Clock (96/24)
' CV Out 2 - Eigth Note Analog Clock   (96/12)
' CV Out 3 - 12th Note Analog Clock (just for fun swing time 96/8)
' CV Out 4 - 16th Note Analog Clock 96/6
' Aux out  - 16th Note Analog Clock (no Inhibit)
'
'*****************************************************

' Basic Micro Atom Pro-24M Configuration
'
' (Note: P0 is I/O 0 and NOT pin 0 on the microprocessor.)
'
' P0 -  Analog IN-1 (0-5 VDC)
' P1 -  Analog IN-2 (0-5 VDC)
' P2 -  Analog IN-3 (0-5 VDC)
' P3 -  Analog IN-4 (0-5 VDC)
' P4 -  START Button (Momentary Normally Open Switch)
' P5 -  STOP  Button (Momentary Normally Open Switch)
' P6 -  I2C/SDA (Reserved) - J3 Pin 1
' P7 -  I2C/SDL (Reserved) -  J3 Pin 2
' P8 -  AUX (Digital I/O - NO BUFFERING)
' P9 -  STOP LED
' P10 - RUN LED
' P11 - DAC - LOADDACS
' P12 - DAC - SERDATA
' P13 - DAC - CLOCK
' P14 - RXD (Reserved) - J5 Pin 1 (Midi)
' P15 - TXD (Reserved) - J5 Pin 2 (Midi) Din Pin 4 > 220 ohm
'*****************************************************
	'Define Variables
	
	LOADDACS	CON 11  ' Pin OUT to DAC LOADDACS
	SERDATA		CON 12  ' Pin OUT Serial Data to DAC (16-bit)
	CLOCK		CON 13  ' Pin OUT to Clock DAC
	STOPLED		CON 9   ' Red LED
	RUNLED		CON 10  ' Green LED
	BSTART		CON 5   ' Start Button
	BSTOP		CON 4   ' Stop  Button
	AUX			CON 8	' AUX Jack (unbuffered)
	
	BPM			VAR	LONG
	MIDICLK		VAR	BYTE
	INH0		VAR	BIT
	INH1		VAR	BIT
	INH2		VAR	BIT
	HALFPAUSE	VAR	WORD
	
	RAWDAC1  	VAR WORD  ' RAW DAC DATA 1 
	RAWDAC2  	VAR WORD  ' RAW DAC DATA 2 
	RAWDAC3  	VAR WORD  ' RAW DAC DATA 3 
	RAWDAC4  	VAR WORD  ' RAW DAC DATA 4 

	DAC1V  		VAR WORD  ' DAC Value to be Sent to DAC Channel
	DAC2V  		VAR WORD  ' DAC Value to be Sent to DAC Channel
	DAC3V  		VAR WORD  ' DAC Value to be Sent to DAC Channel
	DAC4V  		VAR WORD  ' DAC Value to be Sent to DAC Channel
	
	ADC1		CON 0
	ADC2		CON	1
	ADC3		CON 2
	ADC4		CON 3

	ADC1V		VAR WORD	'INPUT A/D BUFFER CH. 1
	ADC2V		VAR WORD	'INPUT A/D BUFFER CH. 2
	ADC3V		VAR WORD	'INPUT A/D BUFFER CH. 3
	ADC4V		VAR WORD	'INPUT A/D BUFFER CH. 4

	'*****************************************************
	'Initialize Module

	 DIRS = %0111110010000000 ' Configure Pins    1=output  0=input
	 OUTS = %0111111111111111 ' Configure State   1=high    0=low
	 SCR3 = %00000000
	 SMR = %00000000
	 BRR = 15
	 PAUSEUS 100
	 SCR3 = %00100000
	 PMR1 = %00001110
	'*****************************************************

'*******************************************************************
'*************** APPLICATION CODE START ****************************
'*******************************************************************

START:

	HIGH STOPLED
	LOW RUNLED ' RUNLED pin is also DIN Synch Start/Stop Pin 1
	LOW AUX
	BPM = 0
	GOSUB CLEARDACS
	
MAINLOOP:

	IF IN4 = 1 THEN CLOCKON ' is there a high on the START button?
	' a pulse on the Start CV-IN also works the same as pressing the button.
	
	GOTO MAINLOOP

CLOCKON:

	LOW STOPLED
	HIGH RUNLED
	GOSUB STARTSUB
	
WAITFORHIGH:					' Wait for front of gate pulse
	GOSUB SCANADC
	
	IF ADC1V > 1000 THEN
		INH0 = 1
	ELSE
		INH0 = 0
	ENDIF
		
	IF ADC4V < 250 THEN WAITFORHIGH		' Keep looping while IN-1 is LOW
	GOSUB CLOCKSUB	
	IF BPM = 0 AND INH0 = 0 THEN 
	DAC1V = 2200
	DAC2V = 2200
	DAC4V = 2200
	DAC3V = 2200
	ENDIF
	
	IF BPM = 12  AND INH0 = 0 THEN
	DAC2V = 2200
	DAC4V = 2200
	ENDIF
	
	IF BPM = 6 OR BPM = 18  AND INH0 = 0 THEN
	DAC4V = 2200
	ENDIF
	
	IF BPM = 8 OR BPM = 16  AND INH0 = 0 THEN
	DAC3V = 2200
	ENDIF
	
	IF BPM = 0 OR BPM = 12 OR BPM = 6 OR BPM = 18 THEN
	HIGH AUX
	ENDIF
	
	GOSUB LOADALLDACS
	BPM = BPM + 1

WAITFORLOW:					' Wait for gate input to drop
	GOSUB SCANADC
	IF BPM = 24  THEN 
	BPM = 0
	ENDIF
	IF ADC4V > 250 THEN WAITFORLOW		' Keep looping while IN-1 is HIGH
  	GOSUB CLEARDACS
  	LOW AUX

CLOCKOFF:
	IF IN5 = 1 THEN 
	GOSUB STOPSUB 'is there a high on the STOP button?
	GOSUB CLEARDACS
	GOTO START
	ENDIF    'a pulse on the Stop CV-IN also works the same as pressing the button.
 
	GOTO WAITFORHIGH
	
'*******************************************************************
'************************** SUBROUTINES ****************************
'*******************************************************************

CLEARDACS:
	DAC1V = 0
	DAC2V = 0
	DAC3V = 0
	DAC4V = 0
 
SCANADC:
	'load buffers with actual a/d values
	ADIN ADC1, ADC1V
	ADIN ADC2, ADC2V
	ADIN ADC3, ADC3V
	ADIN ADC4, ADC4V
	RETURN

LOADALLDACS: ' by Grant Richter of Wiard Synthesizer Company as of 17 Jan 2004
	'Add addresses to VALues no speed improve with OR over +
	RAWDAC1=DAC1V+49152
	RAWDAC2=DAC2V+32768
	RAWDAC3=DAC3V+16384
	RAWDAC4=DAC4V
	'shift out 16 bits mode 4 gotta bang loaddacs pin for each channel
	'skew from ch. 1 to 4 = 400 usecs. Aprox 1 msec execution time for sub.
	SHIFTOUT SERDATA,CLOCK,4,[RAWDAC1\16]
	PULSOUT LOADDACS,1 
	SHIFTOUT SERDATA,CLOCK,4,[RAWDAC2\16]
	PULSOUT LOADDACS,1 
	SHIFTOUT SERDATA,CLOCK,4,[RAWDAC3\16]
	PULSOUT LOADDACS,1
	SHIFTOUT SERDATA,CLOCK,4,[RAWDAC4\16]
	PULSOUT LOADDACS,1
	RETURN
	
STARTSUB:

	TDR = $FA
	SSR = %00000000
 	RETURN
 	
STOPSUB:
	
	TDR = $FC
 	SSR = %00000000
 	RETURN
 	
CLOCKSUB:
	
 	TDR = $F8
 	SSR = %00000000
 	'PULSOUT AUX, 2000
   	RETURN