Graphical LCD Text Display

Graphical LCD Text Display

The Graphical LCD Text Display is complete!   I've used the same Atmel ATMega8 controller that I used in the Composite Video Display.   The interface is the same as well; an 8 bit parallel port with a strobe input and a busy output.   It can be connected directly to a 65C22 8 bit port or any generic parallel port with ease.

The Display is an Optrex DMF50840A which supports 320x240 with a Cold Compact Flourescent Lamp as the backlight.

The power supply is an ASTEC AA9090A.   It has a 6-12vdc input and supplies 5vdc, 12vdc, -26vdc, and 350vac.   The -26v and 350v are used by the Display for contrast and the backlight.

Here is a sample of the display.   I use only 320x200 (40x25 characters) as that's all the character space the ATMega8 can support.

Here is a copy of the character sets that I chose.

You can enable one of the two sets at any time. The primary font provides all 256 standard DOS characters,   The alternate font provides 128 characters and the inverse of each.   These are accessed by using toggle commands as defined below:
Lower = the lower 128 characters with the supported control characters (see description below).
Upper = the upper 128 characters including the box drawing characters in Primary mode, inverse characters in Alternate mode.
Primary Font Select = Enable the 256 DOS character set.
Alternate Font Select = Enable a subset of 128 characters with Inverse video support.
See the Command Bytes below for the specific toggle commands.

The firmware is complete and the prototype assembled and tested!   The source code for the ATMega8 is now available in the Downloads section.   Here is a picture of the completed circuit. The board on the upper left is a modified Composite Text Display board.   The top center board is used to tie everything together and has the contrast control.   The upper right board is the power supply and the bottom board is the display:

Here's how the interface works:
The Host polls the Busy line and waits for it to go inactive (J2 selects active high or active low), then loads the data onto the data bus and clocks the strobe high.   The Busy line will go active and stay active until the data has been processed.   The time it takes to process a data byte depends upon several factors, including display refresh operations and display movements such as scrolling.

Here is a simple timing diagram:

Here's the schematic. As you can see, its a very simple circuit.

The 74HC573 Octal Latch is not necessary as long as you leave the data inputs stable until the Busy Flag is reset, but I decided to add it to make the circuit more versatile.   The 74HC74 D Flip-flop acts as the strobe latch and Busy Flag, which ensures the host's strobes are not missed by the ATMega8 during screen refresh.   All timing and control is provided by the ATMega8's program running at 16 MHz.   J2 selects the Busy Output logic level, short pins 1-2 for Active High or pins 2-3 for active low.

When interfacing to a 65C22, use active low and the 74HC573 is not needed if you use the program provided below to access the display.

Here is a list of the supported data/command bytes:
ASCII Code	Function
00 - 07		Null	
     08		backspace (destructive)
     09		TAB (stops are 0, 8, 16, 24, 32)
     0A		Line Feed
     0B		Null
     0C		Form Feed (Clear the screen and move cursor to top left)
     0D		Carrage Return (clears rest of line)
0E - 1F		Null
20 - 7E		Standard printable ASCII characters in 8x8 font
     7F		Delete (clear character @ cursor, does not shift rest of line left)
80 - 9F		print the 32 special purpose characters (from font positions 0-31)
A0 - B8		Move cursor directly to Row 0 - 24 respectively
     B9		Null
     BA		Cursor Home - move cursor to top left without clear
     BB		Turn Cursor off (hide it)
     BC		Turn on Block Cursor 
     BD		Turn on underscore Cursor
     BE		Set Cursor to Blink Mode (blink rate is approx .5 sec on, .5 sec off)
     BF		Set Cursor to Solid Mode (no blink)
C0 - E7		Move cursor directly to Column 0 - 39 respectively
     E8		Move Cursor up one row (no scrolling)
     E9		Move Cursor down one row (no scrolling)
     EA		Move Cursor left one column (no scrolling)
     EB		Move Cursor right one column (no scrolling)
     EC		scroll screen up one row (bottom is filled in with spaces)
     ED		scroll screen down one row (top is filled in with spaces)
     EE		scroll screen left one column (right column is filled in with spaces)
     EF		scroll screen right one column (left column is filled in with spaces)
     F0		Select the lower 128 characters (including supported control characters)
     F1         Select the upper 128 characters (including box drawing set or Inverse Video)
     F2		Set Font to Primary - 256 DOS character set
     F3 	Set Font to Alternate - 128 characters with Inverse Video Support
F4 - FF		Null (reserved for expansion)

Here is the SBC-2 driver used to reroute the Monitor's output to the Video Display.

;							  ;
;     SBC-2 v2.5 Video Display Driver (c)2003-2004	  ;
;                        v1.0  				  ;
;                  by Daryl Rictor   			  ;
; 		  ;
;							  ;
;							  ;

;  6522 Port Definitions
VIDEO	=  $7F51		; VIA1 Port A
Vidddr	=  $7F53		; Via1 Port A DDR
Vidpcr  =  $7F5C		; Via1 peripheral control register
Vidbsy  =  $7F5D		; Via1 IFR bit 1
VidIRQ	=  $7f5E		; Via1 IER
Out_Vec =  $03F1		; The SBC-2 Output port vector

	*= $1000		; can start anywhere

; Call this once to initialize the interface
; it sets up Port A as an output port and enables Handshaking	
	lda  #$ff		; Set Video Port as output
	sta  Vidddr		; 
	sei			; disable Interrupts until after we change things
	lda  VidIRQ		; get IER value
	and  #$FD		; disable CA1 IRQ	
	sta  VidIRQ		; save it
	lda  Vidpcr		; get current value
	and  #$F0		; mask out Port A bits
	ora  #$0B		; set output handshake mode on port A
	sta  Vidpcr		; to CA2=pulse mode, CA1=Positive Active Edge
	lda  #$0C		; CLS cmd
	sta  Video		; write it to the Display and init the CA1 flag in the IFR
	lda  #<Output		; get low address of the Output Routine
	sta  Out_vec		; set the SBC's output vector address (low byte)
	lda  #>Output		; get high address of the Output Routine
	sta  Out_vec+1		; set the SBC's output vector address (high byte)
	cli			; Enable Interrupts again
	rts			; done

; Call this to write the byte in the Accumulator to the display
	pha			; save data in A reg
Output1	lda  Vidbsy		; get status
	and  #$02		; mask bit 1
	beq  output1		; wait for CA1 Flag to go hi (Ready for next byte)
	pla			; restore data to A reg
	sta  video		; write the byte and clr CA1 flag in IFR
	rts			; done
; End of Program.

The support file that includes ExpressPCB schematic and firmware source and binary files can be downloaded here ->



All info provided "as-is" and is Copyright 2005.