Monitor and keyboard controller
Appendix A : ATmega32 display processor option
(keyboard/serial interface optional)

Work on here, unless credited otherwise, is copyright Grant Searle. You are not allowed to publish this elsewhere without my permission. You may use any of this for your personal use, but commercial use is prohibited.

by Grant Searle

Last update: 27th September 2013

Major changes log:
* 21st August 2013 - Original (ATmega32) keyboard/display interface back online.


This page contains the schematic and code for the version that uses an Atmel ATmega32 processor for the display part of the circuitry.
PLEASE REGARD THIS VERSION AS BEING OBSOLETE: A newer version using a smaller and cheaper ATmega328 is shown here, and that is the recommended version to use. Functionality and of the new version is greatly enhanced. Although it can be done, I do not have sufficient time to keep this version up to date with the ATmega328 version so this version is frozen at the moment.


VERSION 1.1 - This is for the older ATmega32. Go here for the newer ATmega328 version.

This is a generic 80 column x 25 line ANSI terminal using a TTL compatible serial interface running at 115200 baud (can be changed in software) so can be used for any computer project that has a serial I/O and needs a keyboard and display.

This uses an ATmega88 for the keyboard and serial buffer and an ATmega32 for the display processor.

The circuit is in two distinct parts, as shown below. If only a display is needed then only the circuit to the left side of the line is needed.

Not all power supply pins are not shown. These must be connected to the appropriate power rail.

PAL timings - leave pin 35 disconnected. NTSC timings - connect pin 35 to ground, as shown on the schematic.

The code for the ATmega88 was written in C, and the code for the ATmega32 is assembler, modified from Daryl Rictor's original (full credit to Daryl for the original!)

I use the free Atmel AVR studio 6.0 to compile/assemble the two sets of code.


The two parts of the above schematic are constructed as shown here. A resistor links each reset to the power because I program the chips in-circuit.

The system that required the interface (my CP/M design) is shown to the right. The TX, RX, /RTS and power connections are made between the interface and the host computer.
The data bus wiring between the display and the interface parts of the circuit can be seen in blue, handshake between them in orange.

To interface the display to a microcontroller without the keyboard or serial interface requires only the left hand part. The controller needs an 8 output pins for the data, one output pin for the "data available signal" and one input pin for the "acknowledge" pin.


Same as the 8-bit interface on the ATmega328 version. Please refer to the main page for details.

The pin assignment differences between the two versions are shown here:

ATmega328 Pin description ATmega32
PORTD Data to 74HCT166 PORTB
PC5 /LOAD output PD0
PB0 /SYNC output PD1
PB1..5,PC0..2 Data in PORTC
PC3 AVAIL input PA7
PC4 ACK output PA6
PC5 /NTSC selection PA5

Port pins chosen for each version to simplify PCB layout as much as possible.
The code for the two processors is therefore slightly different due to the different ports being used.
Due to fewer pins on the ATmega328, the /NTSC selection is on the same pin as the /LOAD output (briefly becomes an input during startup to see if it is pulled low). The ATmega32 however, has this on a separate pin.


Commented source code and HEX files for the ATmega88 and ATmega32 (or ATmega328) processors are HERE.

When programming the ATMEL processors, ensure the appropriate fuse bits are set (see documentation/programmer details) as these need to use the following settings:
A crystal (XT) clock (must be rail to rail for the ATmega32)
No watchdog timer
No clock divider
JTAG disabled
OCD disabled

Must use XT rail-to-rail clock for the video processor because this also clocks the 74HCT166 (as permitted in the ATMEL datasheet).


Standard ASCII is implemented for the main character set. Extended ASCII codes are implemented the same as for DOS. Control codes are standard ASCII where applicable - other codes added to allow control of the screen. The full implementation is shown below:

Video display control codes:
Hex (Decimal) and meaning
01 (01) - Cursor home
02 (02) - Cursor off
03 (03) - Cursor block
04 (04) - Cursor underscore
05 (05) - Cursor blinking
06 (06) - Cursor solid
08 (08) - Backspace
09 (09) - Tab
0A (11) - Linefeed
0C (12) - Clear screen
0D (13) - Carriage return
0E (14) - Set column 0 to 79 (2nd byte is the column number)
0F (16) - Set row 0 to 24 (2nd byte is the row number)
10 (16) - Delete start of line
11 (17) - Delete to end of line
12 (18) - Delete to start of screen
13 (19) - Delete to end of screen
14 (20) - Scroll up
15 (21) - Scroll down
16 (22) - Scroll left
17 (23) - Scroll right
1A (26) - Treat next byte as a character (to allow PC DOS char codes 1 to 31 to be displayed on screen)
1B (27) - ESC - reserved for ANSI sequences
1C (28) - Cursor right
1D (29) - Cursor Left
1E (30) - Cursor up
1F (31) - Cursor down
20 (32) to 7E (126) - Standard ASCII codes
7F (127) - Delete
80 (128) to FF (255) - PC (DOS) extended characters


So, to print "Hello" at column 18, row 10 on the monitor in BASIC would be as follows:
PRINT CHR$(14) ; CHR$(17) ; CHR$(15) ; CHR$(9) ; "HELLO"

Some ANSI/VT100 escape sequences have been implemented to allow programs such as Wordstar etc. to run on the CPM machine. The ones implemented are shown below (Esc = character 1B Hex, 27 decimal):
Esc[Line;ColumnH or Esc[Line;Columnf moves cursor to that coordinate
Esc[J=clear from cursor down
Esc[1J=clear from cursor up
Esc[2J=clear complete screen
Esc[K = erase to end of line
= erase to start of line
Esc[L = scroll down
Esc[M = scroll up

The above example can also be implemented using escape sequences instead...
PRINT CHR$(27) ; "[18;10H" ; "HELLO"

The character font is not the same as supplied by Daryl. I recreated the complete font from a bitmap of 8x8 characters for a CGA PC display (using a small VB program). Most appear identical, so I assume we used a similar source. However, I have included all characters, including those normally reserved for control codes.

ASCII codes 00 to 1F (and 7F) are reserved for control. However, the character map also has display characters with these values. These characters can be displayed by sending code 1A (26 decimal) before sending the code for the character. This prefix tells the display processor to store the actual character into the display and not treat it as a control code.
eg. in BASIC, to display the heart symbol (at 03) you can use the following...
PRINT CHR$(26) ; CHR$(3)




I hope this page has been useful.


To contact me, my current eMail address can be found here. Please note that this address may change to avoid spam.

Note: All information shown here is supplied "as is" with no warranty whatsoever, however, please let me know if there are any errors. All copyrights recognised.