The display unit comprises three controllers, with an HD44350 being the main controller and two HD44351 as segment drivers. Looking into the user and service manuals reveals the following:
- 96*64 pixels arranged into 8 lines per 16 chars (i.e., 8*6 char matrix)
- Controller-wise, it's treated as two (16+80)*32 displays
- The HD44350 delivers the row signals X1-X32 and two sets of segment driver signals W1-W16 and Z1-Z16.
- The two HD44351 are "extending" the HD44350, each providing a set of 80 segment driver signals Y1-Y80.
- The whole mess is controlled by two clock signals (Phi1/2), chip select (CS#), and the OP# signal.
- The entire setup looks awfully similar to that of Casio's line of 1980s graphics calculators. Luckily, in the FX8000G service manual, some more information is given:
- CS#/CE# is the enable signal. Low indicates a valid data transfer.
- OP# is the "data operation" signal. It seemingly differentiates data transfer from command codes (presumably like RS with HD44780 display). but unfortunately no further information is given.
- Data needs to be stable during Phi1=1 or is sampled at the 0->1 transition. Unfortunately, the datasheet is not clear here (whatever "signals vary by pulse" means).
- Control signals need to be stable during Phi2=1 or are sampled at the 0->1 transition -- same problem as with Phi1 applies.
The display circuitry is complemented by "GAL" (65012C046) which, according to the service manual, "converts the CPU data language into LCD driver's data word". Actually, it does a little bit more:
- Generating the two LCD timing signals (Phi1/2) from a 2MHz input signal. Phi1/2 presumably are 125kHz (which would match the 100kHz given in the HD61603 datasheet), but not more than 250kHz (2MHz/8) given the waveform plots depicted in the FX8000G service manual.
- Mingling a 6-bit input (D7/D4:0) into an LCD control word plus according OP and CS# signals.
- Generating the READY signal to indicate whether or not the GAL is still busy shifting out the data.
From the FZ-1 OS perspective, the display protocol itself is stream-oriented -- a stream of 32 nibbles is fed into the GAL which then translates it into corresponding display controller messages. (Presumably, the HD44350 would slow down the FZ-1's CPU if interfaced directly.). So how does such a message look like?
||display data block #1
||display data block #n
So which commands are there? Browsing through the OS reveals the following:
- A display message is always 32 bytes (well, nibbles) long. Shorter messages are padded with data marks (0x10).
- Message end is signaled with the end marker, i.e. 0x80|data mark or 0x80|data nibble.
- The command block encodes the command itself followed by the command flags . We'll have a look into that later.
- The optional parameter block is used for commands print, plot, and set contrast. It encodes either the display memory address to render to (print, plot) or the contrast value.
- Print and plot have an extra data block which either encodes the character (lsn/msn) or bit pattern (msn/lsn) to render. Multiple characters and patterns may be output sequentially without an extra command/parameter block, as long as the total message length is 32 bytes max.
As for encoding, it seems to work like this:
- Plot: 0x02 0x0* plus parameter block and at least one data block
- Print: 0x03 0x0* plus parameter block and at least one data block
- 0x04 0x0* (presumably "init")
- 0x08 0x0* (presumably graphics subsystem config)
- 0x09 0x0* (presumably text subsystem config)
- 0x0a 0x0* (presumably graphics rendering config)
- Contrast setting: 0x0c 0x0* plus parameter block
- 0x0d 0x0* (presumably "display on")
|| char-height (1) or line-height (0)
|| upper (0) or lower (1) display half
The command type is encoded as follows:
- Contrast setting uses flags 0x09 (0b1001) for initial setting, but 0x0f (0b1111) for manual setting. Obviously, the contrast affects the entire display, so u/d doesn't apply. Bit 3 might indicate a syste-wide message.
- Message 0x04 uses flags 0x00 (very first command sent) and 0x01 (after the intro screen), so I assume it's "display reset" and "display clear".
- Message 0x08 has flags 0x02 (0b0010).
- Message 0x09 and 0x0a only use flags 0x00.
- Message 0x0d is sent only once (with flags 0x00) after configuring but before the initial display animation, so presumably it's "display on".
- Plotting is usually only using the u/l display flag, however, rendering the level meter also sets bit 3 (0x08). Since the level meter does not iterate over y coordinates, presumably this means "char height" here.
The subsystem is either system control (0) or display rendering (1) whereas the operation depends on the command type:
- 00: display data
- 01: init
- 10: config
- 11: display control
- 00: plot (0) or print (1)
- 01: reset (0) or cls (1) (presumed)
- 10: graphics (0) or text (1) config (presumed)
- 11: set contrast (0) or enable display (1) (enable display: presumed)