LCD Output

Posted on Sun 20 October 2024 in MUPS16

Following on from the CPUs first successful run a couple of weeks ago, I decided that patterns in registers are all well and good, but what it really needed was an LCD display. Since I had one in a drawer that seemed to use a Hitachi HD44780 controller, it was a fairly simple matter to build a trivial memory-mapped interface that just exposed raw register reads/writes at a fixed address. It took a couple of evenings to get right, but hey presto:

It's a trivial design: it has a single word mapped at 0x80F0. Writing to that address sends a command or data to the LCD, reading from it reads whatever value the LCD is outputting. The writes are split into two parts: the low byte is the actual data byte presented to the LCDs data pins. The upper bytes contains the value of the three control lines for the LCD: E (the enable line), RW (the read/write selector, with 0 meaning write), and RS (the register select line, controlling whether we're reading/writing registers or data):

This trivial interface means that it's up to the software driving it to bit-bang the enable line to clock data in and out of the LCD. For example, to print a character that's in R1:

liw     r2, LCD_ADDR
lui     r1, LCD_BIT_RS | LCD_BIT_EN     ; rs = 1, en = 1
sw      r2, r1
lui     r1, LCD_BIT_RS                  ; rs = 1, en = 0
sw      r2, r1

It's a bit cumbersome, but easy enough to wrap in functions, and keeps the hardware very simple. It'll do for now, and I'm very pleased I finally have some real output.