; Note: a 2 by 16 LCD is assumed ;****************** 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 buttons = pinsC ;switches on C.2-C.6 ;These are time constants based on a 64 MHz clock. The numbers ;may seem inconsistent since they refer to the pause, pauseus ;or pulsout commands which all use different base units. symbol AYpulse = 4 ;2.5 uSec for pulsout symbol LCDpulse = 8 ;10 uSec for pauseus symbol uSec50 = 40 ;50 uSec for pauseus symbol mSec50 = 400 ;50 mSec for pause symbol mSec = 8 ;1 mSec for pause symbol mSec2 = 16 ;2 mSec for pause ;AY-8910 control codes and register addresses symbol inactive = %00000000 symbol latchAddr = %00000011 symbol Reg7 = %00000111 ;Register 7 - data direction symbol Reg15 = %00001111 ;Register 15 - Port IOB symbol IOBOut = %11111111 ;IOB data direction-out ;Here are various LCD commands which can be used. symbol clrHome = 1 ;clear the display, home the cursor symbol LtoR = 6 ;print characters left to right symbol lcdOn = 12 ;LCD screen on, no cursor symbol curOff = 12 ;an alias for the above symbol mode2 = 40 ;two-line mode (4-bit data) symbol bus4 = 32 ;4-bit data bus mode symbol bus8 = 48 ;8-bit data bus mode symbol line1 = 128 ;go to start of line 1 ;MIDI message bytes symbol midi_start = $FA ;MIDI status byte: Start symbol midi_cont = $FB ;MIDI status byte: Continue symbol midi_stop = $FC ;MIDI status byte: Stop ;****************** Variable Definitions ****************** symbol char = b0 ;ASCII character to be displayed symbol cmd = b0 ;an alias for the char byte symbol i = b1 ;loop variable symbol msg = b2 ;offset into message table symbol index = b3 ;pointer to current character symbol temp = b4 ;temporary LCD data byte built here symbol midi = b5 ;message byte to be processed symbol head = w3 ;head of queue ;*********************** Messages ************************* eeprom 0, ("Start ") ;0 eeprom 16, ("Stop ") ;1 eeprom 32, ("Continue ") ;2 ;********************** 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 head = 0 ;initialize queue hsersetup B31250_64,%00001001 ;turn on MIDI input gosub init ;initialize AY and LCD display gosub init2 ;repeat LCD for security main: if head != hserptr then ;anything in queue? ptr = head ;yes midi = @ptrinc ;get the byte head = ptr ;move head one byte along if head = 1024 then ;but don't go beyond end head = 0 ;wrap around endif select case midi case midi_start ;MIDI Start received msg = 0 ;print results gosub print case midi_stop ;MIDI Stop received msg = 1 gosub print case midi_cont ;MIDI Continue received msg = 2 gosub print end select ;all other bytes ignored endif goto main ;repeat forever end ;************* Initialize AY and LCD on power-up ************* init: pause mSec50 ;let LCD settle for 50 mS at power-up control = inactive ;clear BC1, BDIR ;set up the AY Port IOB for output control = latchAddr ;latch address to register 7 bus = Reg7 control = inactive bus = IOBOut ;make Port IOB all outputs pulsout BDIR,AYpulse init2: control = latchAddr ;latch address to register 15 bus = Reg15 control = inactive bus = %00100011 ;set to 8-bit mode pulsout BDIR,AYPulse bus = %00000011 pulsout BDIR,AYPulse pauseus uSec50 cmd = bus4 ;switch to 4-bit mode now gosub sendCmd pauseus uSec50 cmd = bus4 ;manufacturer recommends redundancy gosub sendCmd pauseus uSec50 cmd = lcdOn ;display on, no cursor gosub sendCmd pauseus uSec50 cmd = clrHome ;clear display gosub sendCmd pause mSec2 char = LtoR ;print left to right by default gosub sendCmd pauseus uSec50 char = mode2 ;use two-line format gosub sendCmd pause uSec50 return ;*************** Send a Character to the LCD ************** ;To transmit a character, RS must be high. sendChr: control = latchAddr ;latch address mode bus = Reg15 ;access Port IOB control = inactive ;address now latched temp = char >> 4 ;shift high nibble right bus = temp | %00110000 ;Enable high (and RS) pulsout BDIR,AYpulse ;latch data pause LCDpulse ;keep high for 200 uS bus = temp | %00010000 ;Enable low, RS still high pulsout BDIR,AYpulse ;latch data temp = char & %00001111 ;grab low nibble bus = temp | %00110000 ;Enable high,RS high pulsout BDIR,AYPulse ;latch data pause LCDpulse bus = temp | %00010000 ;Enable low pulsout BDIR,AYPulse ;latch data return ;**************** Send a Command to the LCD *************** ;To transmit a command, RS must be low sendCmd: control = latchAddr ;latch address mode bus = Reg15 ;access Port IOB control = inactive ;address now latched temp = char >> 4 ;shift high nibble right bus = temp | %00100000 ;Enable high,RS low pulsout BDIR,AYpulse ;latch data pause LCDpulse bus = temp ;Enable low, RS still low pulsout BDIR,AYpulse ;latch data temp = char & %00001111 ;grab low nibble bus = temp | %00100000 ;Enable high,RS low pulsout BDIR,AYPulse ;latch data pause LCDpulse bus = temp ;Enable low, RS still low pulsout BDIR,AYPulse ;latch data pause mSec ;commands take longer return ;**************** Clear LCD and home cursor *************** clearLCD: cmd = clrHome ;clear display gosub sendCmd pause mSec2 return ;*************** Print first row to the LCD *************** ;The variable 'row' points to the start of the string. print: cmd = line1 ;print on first line gosub sendCmd for i = 0 to 15 index = msg*16+i read index, char ;fetch next character and gosub sendChr ;transmit to the LCD next i return