'---------------------------------------------
'PUBLIC DOMAIN
'---------------------------------------------

'*******************************************************************
'********************* JIBBER JABBER *******************************
'*******************************************************************

'*****************************************************
' PSIM-1 (Programmable Synthesizer Interface Module)
'
' Module: PSIM-1 REV1b
' Revision Date:  2004/01/17  5:47 AM
' Processor Type: Basic Micro - Basic Atom Pro24M
'
'
' Basic Program Developed by Grant Richter
' Special thanks to Brice for his assistance.
'
' Description:
' Simple CV to MIDI converter, uses SCI3 for output
' 
' Inputs and Outputs:
' Start PB or Jack: Run light On Send MIDI Note On data
' Off = Send MIDI Note Off
' CV In 1 - Converted to Midi Note
' CV In 2 - Added with CV1 half scale
' CV In 3 - Converted to Velocity
' CV In 4 - Added with CV3 half scale
' Stop PB or Jack: Off = Diatonic Major, On = Chromatic
' CV Out 1 - CV version of MIDI note
' CV Out 2 - MIDI scaled version of Vel. input
' CV Out 3 - Raw Vel. Input x 3
' CV Out 4 - 2 volt tuning reference (middle C analog VCO)
'*****************************************************

' 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)
	
	SMR			CON	$FFA8-$F780
	BRR			CON	$FFA9-$F780
	SCR3		CON	$FFAA-$F780
	TDR			CON	$FFAB-$F780
	SSR			CON	$FFAC-$F780
	RDR			CON	$FFAD-$F780
	PMR1		CON	$FFE0-$F780
	
	NOTEOFF		CON	$80
	NOTEON		CON	$90
	CONTRL		CON	$B0
	MDELAY		CON	320
	MIDIOFFSET	CON	36
	
	MIDICHAN	VAR	NIB
	MIDINOTE	VAR BYTE
	MIDIVEL		VAR	BYTE
	NOTE		VAR	BYTE
	
	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
	
	SBUT		VAR	BIT
	
	NOTETABLE	BYTETABLE 36,38,40,41,43,45,47,48,50,52,53,55,57,59,60,62,64,65,67,69,71,72,74,76,77,79,81,83,84,86,88,89

	'*****************************************************
	'Initialize Module

	 DIRS = %0111110000000000 ' Configure Pins    1=output  0=input
	 OUTS = %0111111111111111 ' Configure State   1=high    0=low
	 POKE SCR3, %00000000
	 POKE SMR, %00000000
	 POKE BRR, 15
	 PAUSEUS 100
	 POKE SCR3, %00100000
	 POKE PMR1, %00001110
	'*****************************************************

	LOW STOPLED
	LOW RUNLED

'*******************************************************************
'*************** APPLICATION CODE START ****************************
'*******************************************************************

START:

	MIDICHAN = 0
	DAC4V=768 '2 VOLT TUNING REFERENCE
	
MAINLOOP:
	IF IN4 = 1 THEN GATEON ' is there a gate on the START button?
	' a pulse on the Start CV-IN also works the same as pressing the button.
	IF IN5 = 1 THEN
	HIGH STOPLED
	SBUT = 1
	ENDIF
	IF IN5 = 0 THEN
	LOW STOPLED
	SBUT = 0
	ENDIF
	GOTO MAINLOOP
	
	GATEON:
		
		HIGH RUNLED
		GOSUB SCANADC

		IF SBUT = 1 THEN 'CHROMATIC X 64
		MIDINOTE = (ADC1V/16)+(ADC2V/32)+31
		MIDIVEL = (ADC3V/16)+(ADC4V/32)+31
		ENDIF
		
		IF SBUT = 0 THEN 'DIATONIC X 32
		NOTE=(ADC1V/32)+(ADC2V/64)
		IF NOTE > 31 THEN
		NOTE = 31
		ENDIF
		MIDINOTE = NOTETABLE(NOTE)
		MIDIVEL = (ADC3V/16)+(ADC4V/32)+31
		ENDIF
		
		GOSUB NOTEONSUB
 		
 		DAC1V=(MIDINOTE-MIDIOFFSET)*32
 		DAC2V=MIDIVEL*32
 		DAC3V=ADC3V*3
 		GOSUB LOADALLDACS
	
SUSTAIN:' if no gate, then send noteoff
       	IF IN4 = 0 THEN GATEOFF
       	IF IN5 = 1 THEN
		HIGH STOPLED
		SBUT = 1
		ENDIF
		IF IN5 = 0 THEN
		LOW STOPLED
		SBUT = 0
		ENDIF
		GOTO SUSTAIN' keep staying
		
	GATEOFF:
		LOW RUNLED
		GOSUB NOTEOFFSUB
	
GOTO MAINLOOP
	
'*******************************************************************
'************************** SUBROUTINES ****************************
'*******************************************************************
LOADALLDACS:
	'HIGH RUNLED
	'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
 	'LOW RUNLED
 	RETURN

SCANADC:
	'load buffers with actual a/d values
	ADIN ADC1, ADC1V
	ADIN ADC2, ADC2V
	ADIN ADC3, ADC3V
	ADIN ADC4, ADC4V
	RETURN
	
NOTEONSUB:

	POKE TDR, NOTEON + MIDICHAN
	POKE SSR, %00000000
 	PAUSEUS MDELAY 
 	POKE TDR, MIDINOTE
 	POKE SSR, %00000000
 	PAUSEUS MDELAY
 	POKE TDR, MIDIVEL
 	POKE SSR, %00000000
 	PAUSEUS MDELAY
 	RETURN
 	
NOTEOFFSUB:
	
 	POKE TDR, NOTEOFF + MIDICHAN
 	POKE SSR, %00000000
 	PAUSEUS MDELAY
 	POKE TDR, MIDINOTE
 	POKE SSR, %00000000
 	PAUSEUS MDELAY
 	POKE TDR, MIDIVEL
 	POKE SSR, %00000000
 	PAUSEUS MDELAY
 	RETURN