Paganini wrote:
Another reason for using my existing LCD routines is that it gives me the chance to talk about how I modified them to work with the 4 x 20 LCD. Internally, the 4 x 20 LCD is a little bit strange. A single HD44780U can only display one or two 8-character lines. That means to get an 80 character display the manufacturers of 4 x 20 LCDs had to combine at least 5 of them. The way this works out in practice is that display line 3 is actually the second half of display line 1, and display line 4 is actually the second half of display line 2. This means that the display lines are interlaced. If you write off the end of line 1 you will appear not on line 2, but on line 3. Going off the end of line 3 brings you back to line 2, and from line 2 you go to line 4. Yikes!
It's not so strange if you understand the original design. I've not read the HD44780U data sheet in detail, but I did go through the
ST7066 data sheet the other day (the HD44780U is a clone of the ST7066) and discovered some interesting things.
While the ST7066 itself has the hardware to support only one or two lines of 8 characters, the "firmware" supports two lines of 40 characters using an 80-byte frame buffer. While in standard form only characters 0-7 of each line are displayed, there's an "extension module" that adds the ability to support an additional display of two lines of 8 characters; this is simply extra I/O lines and driver hardware that displays characters 8-15 from the frame buffer.
What's going on here becomes apparent when you look at the commands; the %0001.sdxx command, with s=1 lets you shift the "head" of the frame buffer left and right. So each line in the display is actually an 8- or 16-character window into a virtual 40-character line in the frame buffer.
As a side note, 80 bytes is obviously far more memory than you need if you're not using this "virtual 40-character line" feature; even a two-line by 16-character display uses only 32 bytes of the frame buffer memory, leaving 48 bytes free. The data sheet itself also suggests what Michael suggested in an earlier post: that you can use this extra memory for whatever other purposes you like. It's not so useful on systems with a large amount of RAM, such as 16K or more, but if you're using something like a 6802 without external RAM, and thus have only 128 bytes of RAM available, I can see this being quite handy. (The presumption here is that you do have lots of ROM for the extra code to handle writing and reading that memory through the display's chip's interface.)
When manufacturers started cloning the chip, and especially when packaging such as PLCC with many more pins than DIP became available, they would usually include not just the extension module but another half extension module, allowing the ability to drive a two line by 20 character display. This still fit easily within the two-line by 40 character frame buffer concept, and so involved no changes to the interface at all.
Moving up to support a four-line by 20 character display was the obvious next step, but of course the manufacturers of the clone chips also wanted to maintain compatibility with the original chip, which meant that the virtual two-line 40-character display with a scrolling window had to be maintained for those that were using that with two-line displays. Unfortunately, expanding the frame buffer to four lines of 40 characters wasn't an option, because the %1aaa.aaaa "set DDRAM address" command has only 7 bits of address, so you can't address a 160 byte frame buffer. So instead they stuck with 80 bytes of frame buffer, and, when used for a four line display, made line three extend the "window" displayed by line one, and line four extend the "window" displayed by line two. This makes everything fit nicely in the existing 80-byte frame buffer interface, but of course introduces the "jumps" in addressing that you discovered.