; 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 ;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 mSec = 8 ;1 mSec for pause symbol mSec2 = 16 ;2 mSec for pause symbol mSec50 = 400 ;50 mSec for pause symbol mSec200 = 1600 ;200 mSec for pause symbol mSec500 = 4000 ;500 mSec for pause symbol secOne = 8000 ;one second symbol sec3 = 24000 ;3 seconds ;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 home = 2 ;home the cursor only symbol RtoL = 4 ;print characters right to left symbol insR = 5 ;insert characters to right symbol LtoR = 6 ;print characters left to right symbol insL = 7 ;insert characters to left symbol lcdOff = 8 ;LCD screen off symbol lcdOn = 12 ;LCD screen on, no cursor symbol curOff = 12 ;an alias for the above symbol block = 13 ;LCD screen on, block cursor symbol under = 14 ;LCD screen on, underline cursor symbol undblk = 15 ;LCD screen on, blinking and underline cursor symbol left = 16 ;cursor left symbol right = 20 ;cursor right symbol panR = 24 ;pan viewing window right symbol panL = 28 ;pan viewing window left symbol mode1 = 32 ;one-line mode (4-bit data) 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 symbol line2 = 192 ;go to start of line 2 ;****************** 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 j = b2 ;and another one symbol row = b3 ;offset into message table symbol index = b4 ;pointer to current character symbol temp = b5 ;temporary LCD data byte built here ;*********************** Messages ************************* eeprom 0, ("First we'll show") ;0 eeprom 16, ("this message. ") eeprom 32, ("Then we'll blink") ;2 eeprom 48, ("five times. ") eeprom 64, ("Now let's pan ") ;4 eeprom 80, ("left and right. ") eeprom 96, ("Watch the line ") ;6 eeprom 112,("cursor move. ") eeprom 128,("A block cursor ") ;8 eeprom 144,("is available. ") eeprom 160,("Next we'll scroll this long message as a continuous ") eeprom ("marquee in one line mode. ") eeprom 238,("Characters: ") eeprom 250,("Bye!") ;********************** 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 gosub init ;initialize AY and LCD display gosub init2 ;repeat LCD for security main: row = 0 ;print first message gosub print pause sec3 ;pause 3 seconds row = 2 ;print next message gosub print pause sec3 ;pause 3 seconds for i = 1 to 5 ;blink it five times cmd = lcdOff gosub sendCmd pause mSec500 ;half-second off cmd = lcdOn gosub sendCmd pause mSec500 ;then half-second on next i pause sec3 ;demonstrate panning row = 4 ;print next message gosub print pause sec3 ;pause 3 seconds for i = 1 to 16 ;pan left a step at a time cmd = panL gosub sendCmd pause mSec200 next i for i = 1 to 16 ;then pan right cmd = panR gosub sendCmd pause mSec200 next i pause sec3 ;demonstrate moving the cursor row = 6 ;print next message gosub print pause sec3 ;pause 3 seconds gosub homeLCD ;home the cursor cmd = under ;choose underline cursor gosub sendCmd for i = 0 to 15 ;move cursor across first line cmd = line1+i gosub sendCmd pause mSec200 next i for i = 0 to 15 ;move cursor across second line cmd = line2+i gosub sendCmd pause mSec200 next i for i = 15 to 0 step -1 ;move cursor back over second line cmd = line2+i gosub sendCmd pause mSec200 next i for i = 15 to 0 step -1 ;move cursor back over first line cmd = line1+i gosub sendCmd pause mSec200 next i pause sec3 ;demonstrate blinking block cursor row = 8 ;print next message gosub print gosub homeLCD ;home the cursor cmd = block ;choose blinking block cursor gosub sendCmd pause sec3 ;pause 3 seconds ;demonstrate scrolling a lengthy one-line marquee cmd = mode1 ;change to one long line mode gosub sendCmd gosub clearLCD cmd = curOff ;and disable it gosub sendCmd for i = 160 to 237 ;print next message read i, char gosub sendChr next i pause secOne gosub homeLCD ;home cursor once more for i = 0 to 60 ;scroll message cmd = panR gosub sendCmd pause mSec500 next i pause sec3 gosub clearLCD cmd = mode2 ;change back to two line mode gosub sendCmd ;demonstrate all of the characters cmd = curOff ;disable cursor gosub sendCmd for i = 238 to 250 ;print next message read i, char gosub sendChr next i for i = 33 to 127 ;print first batch of ASCII characters cmd = line1 + 12 ;overwrite each character displayed gosub sendCmd char = i gosub sendChr pause mSec500 next i for i = 161 to 253 ;print next batch of ASCII characters cmd = line1 + 12 gosub sendCmd char = i gosub sendChr pause mSec500 next i pause sec3 ;say good-bye cmd = line2 ;go to start of line 2 gosub sendCmd for i = 250 to 253 ;print last message read i, char gosub sendChr next i pause sec3 goto main ;repeat in perpetuity 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 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 ;**************** Print a message to the LCD ************** ;The variable 'row' points to the start of the string. print: cmd = mode2 ;two line mode gosub sendCmd gosub clearLCD cmd = line1 ;get set for first line gosub sendCmd for i = 0 to 15 ;16 characters per line index = row*16+i read index, char ;fetch next character and gosub sendChr ;transmit to the LCD next i cmd = line2 ;get set for second line gosub sendCmd for i = 0 to 15 index = row+1*16+i read index, char ;fetch next character and gosub sendChr ;transmit to the LCD next i return ;**************** Clear LCD and home cursor *************** clearLCD: cmd = clrHome ;clear display gosub sendCmd ;clear and home pause mSec2 ;take longer to execute return ;******************* Home cursor only ********************* homeLCD: cmd = home ;home the cursor gosub sendCmd pause mSec2 return