; Note: a 2 by 16 LCD is assumed ;****************** Constant Definitions ****************** symbol control = outpinsA ;control to AY and LCD (A.0-A.3) 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 RS = A.0 ;A.2 is the LCD RS line (Reg Sel) symbol Enable = A.1 ;A.3 is the LCD E line (Enable) symbol bus = outpinsB ;main data bus to the AY chip (DA) ;time constants based on a 40 MHz clock symbol AYpulse = 1 ;AY write pulse width is 1uS symbol LCDpulse = 10 ;LCD enable pulse width is 10uS symbol mSec = 5 ;one millisecond symbol secFifth = 1000 ;fifth of a second symbol secHalf = 2500 ;half of a second symbol secOne = 5000 ;one second symbol sec3 = 15000 ;3 seconds ;AY-8910 control codes and register addresses symbol inactive = %00000000 symbol latchData = %00000010 symbol latchAddr = %00000011 symbol Reg7 = %00000111 ;Register 7 - data direction symbol Reg15 = %00001111 ;Register 15 - Port IOB symbol IOBOut = %10111111 ;IOB data direction code ;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 ;*********************** 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 em40 ;40 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 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 secHalf ;half-sec off cmd = lcdOn gosub sendCmd pause secHalf ;then half-sec on next i pause secOne ;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 secHalf next i for i = 1 to 16 ;then pan right cmd = panR gosub sendCmd pause secHalf next i pause secOne ;demonstrate moving the cursor row = 6 ;print next message gosub print pause sec3 ;pause 3 seconds cmd = home ;home the cursor gosub sendCmd cmd = under ;choose underline cursor gosub sendCmd for i = 0 to 15 ;move cursor across first line cmd = line1+i gosub sendCmd pause secFifth next i for i = 0 to 15 ;move cursor across second line cmd = line2+i gosub sendCmd pause secFifth next i for i = 15 to 0 step -1 ;move cursor back over second line cmd = line2+i gosub sendCmd pause secFifth next i for i = 15 to 0 step -1 ;move cursor back over first line cmd = line1+i gosub sendCmd pause secFifth next i pause sec3 ;demonstrate blinking block cursor row = 8 ;print next message gosub print cmd = home ;home the cursor gosub sendCmd 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 cmd = clrHome ;clear screen, home cursor gosub sendCmd cmd = curOff ;and disable it gosub sendCmd for i = 160 to 237 ;print next message read i, char gosub sendChr next i pause secOne cmd = home ;home cursor once more gosub sendCmd for i = 0 to 141 ;scroll message twice cmd = panR gosub sendCmd pause secHalf next i pause sec3 cmd = clrHome ;clear the screen gosub sendCmd cmd = mode2 ;change back to two line mode gosub sendCmd ;demonstrate all of the characters 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 secHalf next i for i = 161 to 253 ;print next batch of ASCII characters cmd = line1 + 12 gosub sendCmd char = i gosub sendChr pause secHalf next i ;say good-bye cmd = line2 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: control = inactive ;clear BC1, BDIR, RS and Enable ;set up the AY Port IOB for output control = latchAddr ;latch address command bus = Reg7 ;set address to register 7 control = inactive bus = IOBOut ;make Port IOB output pulsout BDIR,AYpulse ;latch data control = latchAddr bus = Reg15 ;address Port IOB control = inactive bus = 0 ;clear Port IOB pulsout BDIR,AYPulse pause secFifth ;let the LCD settle for 200 mSec cmd = bus8 ;command for 8-bit operation gosub sendCmd pause 50 ;pause 10 mS gosub sendCmd ;manufacturer recommends resends gosub sendCmd ;to allow for settling time cmd = bus4 ;now make 4-bit mode gosub sendCmd gosub sendCmd ;again, redundancy here on purpose cmd = 0 ;clear LCD inputs gosub sendCmd cmd = mode2 ;two-line mode gosub sendCmd char = clrHome ;clear display, home the cursor gosub sendCmd char = curOff ;turn cursor off gosub sendCmd char = LtoR ;print left to right by default gosub sendCmd return ;*************** Send a Character to the LCD ************** ;To transmit a character, RS must be high. sendChr: control = latchAddr ;latch the address bus = Reg15 ;access Port IOB control = inactive bus = char >> 4 ;shift high nibble right pulsout BDIR,AYpulse ;latch data high rs pulsout enable,LCDpulse ;send it control = latchAddr ;latch the address bus = Reg15 ;access Port IOB control = inactive bus = char & %00001111 ;grab low nibble pulsout BDIR,AYPulse ;latch data high rs pulsout enable,LCDpulse ;send it return ;**************** Send a Command to the LCD *************** ;To transmit a command, RS must be low. It is by default.. sendCmd: control = latchAddr ;latch the address bus = Reg15 ;access Port IOB control = inactive bus = cmd >> 4 ;shift high nibble right pulsout BDIR,AYpulse ;latch data pulsout enable,LCDpulse ;send it control = latchAddr ;latch the address bus = Reg15 ;access Port IOB control = inactive bus = cmd & %00001111 ;grab low nibble pulsout BDIR,AYpulse ;latch data pulsout enable,LCDpulse ;send it return ;**************** Print a message to the LCD ************** ;The variable 'row' points to the start of the string. print: cmd = clrHome gosub sendCmd cmd = mode2 gosub sendCmd cmd = line1 ;get set for first line gosub sendCmd for i = 0 to 15 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