I think I may have solved the mystery of the missing bottom line. The font data is stored as 8 bits, with the bottom line saved as 3 bytes. These bytes go into a shift register when written to c001,c002 and c003 and they get shifted out at c000.
So now you can see the bottom of the character [:
so at 2708 DE gets loaded with C001 and C gets 2 so we transfer 3 bytes to c001,c002,c003 with the BLOCK instruction.
then at 2714 we read the value at C000 for our 9th pin, the other 8 bits coming from LDAX (HL+).
It seems to work for the self test, anyway.
void e05a30_device::write(offs_t offset, uint8_t data)
{
LOG("%s: e05a30_w([0xC0%02x]): %02x\n", machine().describe_context(), offset, data);
switch (offset) {
case 0x0:
case 0x1:
case 0x2:
case 0x3:
c000_shift_register &= ~(0xff << ((3-offset)*8));
c000_shift_register |= (data << ((3-offset)*8));
break;
...
uint8_t e05a30_device::read(offs_t offset)
{
uint8_t result = 0;
LOG("%s: e05a30_r([0xC0%02x]): ", machine().describe_context(), offset);
switch (offset) {
case 0x0:
c000_shift_register <<= 1; // put shift before the capture
result = (c000_shift_register & 0x1000000) ? 0x80 : 0x0;
break;