;AY_eeprom_midi_chords.bas, THeff 6-25-2012 ;Plays midi chords from eeprom lookup table, 61 notes C1 - C6 ;Address of AY LSB eeprom note data is MIDI decimal note value ;Address of AY MSB eeprom note data is MIDI decimal note value + 61 ;Tone A is the root note, Tone B is Tone A +4, Tone C is Tone B + 3 #Picaxe 28X2 ;#No_Data ;#No_Table ;#Terminal 76800 ;****************** Constant Definitions ****************** symbol control = outpinsA ;control lines to the AY chip symbol BC1 = A.0 ;A.0 is BC1 on the AY chip symbol BDIR = A.1 ;A.1 is BDIR on the AY chip symbol bus = outpinsB ;data/address bus to AY chip symbol AYpulse = 4 ;2.5 uSec for pulsout ;AY-8910 control codes and register addresses symbol inactive = %00000000 symbol latchAddr = %00000011 symbol Reg7 = %00000111 ;Register 7 - data direction symbol Reg14 = %00001110 ;Register 14 - Port IOB symbol IOAOut = %11111000 ;enable IOA and tone A ;MIDI message bytes symbol channel = 1 ' MIDI Channel = 1 To 16 symbol channel_minus_1 = channel - 1 symbol note_on = $390 + channel_minus_1 symbol note_off = $380 + channel_minus_1 ;****************** Variable Definitions ****************** symbol status = w0 ' b1:b0 symbol statusByte = b0 symbol statusCount = b1 symbol argW = w1 ' b3:b2 symbol arg2 = b2 symbol arg1 = b3 symbol char = b4 ;ASCII character to be displayed symbol cmd = b4 ;an alias for the char byte symbol i = b5 ;loop variable symbol msg = b6 ;offset into message table symbol index = b7 ;pointer to current character symbol temp = b8 ;temporary LCD data byte built here symbol row = b9 ;current LCD row symbol col = b10 ;current LCD column symbol eelsb = b11 ;LSB data read symbol eemsb = b12 ;MSB data read symbol midival = b13 ;MIDI note & LSBvalue symbol midimsb = b14 ;MIDI MSB value symbol value = b15 ;register number (0-15) symbol register = b16 ;value to store in register symbol ToneB = b17 ;Tone B LSB for chord symbol ToneC = b18 ;Tone B LSB for chord ;*********************** Note LSB Values ************************* eeprom 24, (238) ;C1 eeprom 25, (24) ;C#1 eeprom 26, (77); ;D1 eeprom 27, (142) ;D#1 eeprom 28, (218) ;E1 eeprom 29, (47) ;F1 eeprom 30, (143) ;F#1 eeprom 31, (247) ;G1 eeprom 32, (104) ;G#1 eeprom 33, (225) ;A1 eeprom 34, (97) ;A#1 eeprom 35, (233) ;B1 eeprom 36, (119) ;C2 eeprom 37, (12) ;C#2 eeprom 38, (167) ;D2 eeprom 39, (71) ;D#2 eeprom 40, (237) ;E2 eeprom 41, (152) ;F2 eeprom 42, (71) ;F#2 eeprom 43, (252) ;G2 eeprom 44, (180) ;G#2 eeprom 45, (112) ;A2 eeprom 46, (49) ;A#2 eeprom 47, (244) ;B2 eeprom 48, (188) ;C3 eeprom 49, (134) ;C#3 eeprom 50, (83); ;D3 eeprom 51, (36) ;D#3 eeprom 52, (246) ;E3 eeprom 53, (204) ;F3 eeprom 54, (164) ;F#3 eeprom 55, (126) ;G3 eeprom 56, (90) ;G#3 eeprom 57, (56) ;A3 eeprom 58, (24) ;A#3 eeprom 59, (250) ;B3 eeprom 60, (222) ;C4 *** Middle C eeprom 61, (195) ;C#4 eeprom 62, (170) ;D4 eeprom 63, (146) ;D#4 eeprom 64, (123) ;E4 eeprom 65, (102) ;F4 eeprom 66, (82) ;F#4 eeprom 67, (63) ;G4 eeprom 68, (45) ;G#4 eeprom 69, (28) ;A4 eeprom 70, (12) ;A#4 eeprom 71, (253) ;B4 eeprom 72, (239) ;C5 eeprom 73, (225) ;C#5 eeprom 74, (213) ;D5 eeprom 75, (201) ;D#5 eeprom 76, (190) ;E5 eeprom 77, (179) ;F5 eeprom 78, (169) ;F#5 eeprom 79, (159) ;G5 eeprom 80, (150) ;G#5 eeprom 81, (142) ;A5 eeprom 82, (134) ;A#5 eeprom 83, (127) ;B5 eeprom 84, (119) ;C6 ;*********************** Note MSB Values ************************* eeprom 85, (14) ;C1 eeprom 86, (14) ;C#1 eeprom 87, (13); ;D1 eeprom 88, (12) ;D#1 eeprom 89, (11) ;E1 eeprom 90, (11) ;F1 eeprom 91, (10) ;F#1 eeprom 92, (9) ;G1 eeprom 93, (9) ;G#1 eeprom 94, (8) ;A1 eeprom 95, (8) ;A#1 eeprom 96, (7) ;B1 eeprom 97, (7) ;C2 eeprom 98, (7) ;C#2 eeprom 99, (6) ;D2 eeprom 100, (6) ;D#2 eeprom 101, (5) ;E2 eeprom 102, (5) ;F2 eeprom 103, (5) ;F#2 eeprom 104, (4) ;G2 eeprom 105, (4) ;G#2 eeprom 106, (4) ;A2 eeprom 107, (4) ;A#2 eeprom 108, (3) ;B2 eeprom 109, (3) ;C3 eeprom 110, (3) ;C#3 eeprom 111, (3); ;D3 eeprom 112, (3) ;D#3 eeprom 113, (2) ;E3 eeprom 114, (2) ;F3 eeprom 115, (2) ;F#3 eeprom 116, (2) ;G3 eeprom 117, (2) ;G#3 eeprom 118, (2) ;A3 eeprom 119, (2) ;A#3 eeprom 120, (1) ;B3 eeprom 121, (1) ;C4 eeprom 122, (1) ;C#4 eeprom 123, (1) ;D4 eeprom 124, (1) ;D#4 eeprom 125, (1) ;E4 eeprom 126, (1) ;F4 eeprom 127, (1) ;F#4 eeprom 128, (1) ;G4 eeprom 129, (1) ;G#4 eeprom 130, (1) ;A4 eeprom 131, (1) ;A#4 eeprom 132, (0) ;B4 eeprom 133, (0) ;C5 eeprom 134, (0) ;C#5 eeprom 135, (0) ;D5 eeprom 136, (0) ;D#5 eeprom 137, (0) ;E5 eeprom 138, (0) ;F5 eeprom 139, (0) ;F#5 eeprom 140, (0) ;G5 eeprom 141, (0) ;G#5 eeprom 142, (0) ;A5 eeprom 143, (0) ;A#5 eeprom 144, (0) ;B5 eeprom 145, (0) ;C6 ;*********************** Messages ************************* eeprom 146, ("Note On ") ;0 eeprom 162, ("Note Off ") ;1 ;********************** Main Program ********************** pgm: SetFreq EM64 ;64 MHz external resonator dirsA = %00001111 ;A.0-A.3 are outputs dirsB = %11111111 ;B.0-B.7 are outputs dirsC = %00000010 ;C.2-C.6 are inputs pwmout C.1, 7, 16 ;start AY clock at 2 MHz HserSetup B31250_64, %001 ;turn on MIDI input gosub init ;initialize AY and LCD display MainLoop: Do Do : Loop While ptr = hSerPtr If @ptr >= $80 Then statusByte = @ptrInc Else arg1 = arg2 arg2 = @ptrInc statusCount = statusCount + 1 Select Case status Case NOTE_ON If arg2 <> 0 Then ;SerTxd( "Note On", 9, #arg1, 9, #arg2, CR, LF ) midimsb = arg1 + 61 ToneB = arg1 + 4 ToneC = ToneB + 3 read arg1,eelsb read midimsb,eemsb register = 0 ;frequency LSB value = eelsb gosub store register = 1 ;frequncy MSB value = eemsb gosub store register = 8 ;Tone A on max amp value = %00001111 gosub store midimsb = ToneB + 61 read ToneB,eelsb read midimsb,eemsb register = 2 ;frequency LSB value = eelsb gosub store register = 3 ;frequncy MSB value = eemsb gosub store register = 9 ;Tone B on max amp value = %00001111 gosub store midimsb = ToneC + 61 read ToneC,eelsb read midimsb,eemsb register = 4 ;frequency LSB value = eelsb gosub store register = 5 ;frequncy MSB value = eemsb gosub store register = 10 ;Tone C on max amp value = %00001111 gosub store Else ;SerTxd( "Note Off ( via Note On )", 9, #arg1, CR, LF ) register = 8 ;Tone A amp off value = %00000000 gosub store register = 9 ;Tone B amp off value = %00000000 gosub store register = 10 ;Tone C amp off value = %00000000 gosub store End If Else Goto MainLoop End Select End If statusCount = 1 Loop end ;************* Initialize AY on power-up ************* init: control = inactive ;clear BC1, BDIR ;set up the AY Port IOA for output control = latchAddr ;latch address to register 7 bus = Reg7 control = inactive bus = IOAOut ;enable IOA and Tone A pulsout BDIR,AYpulse control = latchAddr ;latch address to register 15 bus = Reg14 control = inactive bus = $FF ;turn all gates off pulsout BDIR,AYPulse return ;*************** Send Value to AY Register ************** ;Pass in register and value at entry store: control = inactive ;clear BC1, BDIR control = latchAddr ;latch address of register bus = register control = inactive bus = value ;get value and pulsout BDIR,AYPulse ;store it return