Port 4, LCD config

A project log for Vintage Z80 palmtop compy hackery

It even has a keyboard!

esot.ericesot.eric 08/02/2021 at 19:070 Comments


Looking at 84-port4.txt again, again...

LCD/Timer correlation:

Thinking, very differently from before, the LCD driver is actually the source for Timer Ints. 

Port4 bits 4,3 set the number of columns: 80, 96, 128, or 160. Lacking software-control of LCD-data-sending (which seems the case), this must be controlled by a (tiny) circuit in the VLSI... at the very least, for this discussion, a byte-counter that pulses the row-shift clock after so many pixels.

Bits 2,1 supposedly seem to set the timer interrupt rate, like a prescaler... 4x, 2x, 4/3x, or 1x (~200Hz). 

Previously, I presumed, this was a separate device, a timer... but, it would make a heck of a lot more sense "Port 4 is the LCD controller port"

So, instead of configuring a separate timer peripheral, these bits may set the number of LCD columns in the LCD driver circuit in the VLSI... Then, the row-counter can be configured to count to:

 4xTimer=64rows/4=16rows=2linesOfText which is pretty common on, say, data/contact/calendar organizers, which this chip T6A43 was used in (albeit with a much larger screen)

2x=32 rows... 4 lines of text

1x of course being our 64 rows

4/3x? Math... 85 rows? Well, maybe not /exactly/ 4/3, being that the description sounds like it was determined by how many times the screen was repeated... but, say it's 88 rows, that'd be 11 lines of text, or 80 is 10, which might seem a bit unusual, but the data-organizer had several rows of text /and/ numerous custom icons... so, even 85 "rows" could make sense in a case like that.

PS-6600, 6 lines, 32chars each, + icons... and note that its display has a pixel-wide space between characters, like a typical text-display... so while a dot-matrix graphics display uses 6x8 pixels per each 5x7 character, this one uses 5x7 (maybe 5x8 if they want a fancier font for lowercase gyqj, etc...) 5*32=160... perfect. 6*8=48, and... heh, well, nowhere near 85 rows... but 6*7 is 42, double that is 84, and a handful of icons... it's not at all uncommon for LCDs of these sorts to be spilt into halves, either vertically or horizontally... Though, usually it has some correlation with the row-driver and col-driver chips' number of outputs... /our/ row driver has 68 outputs, col-driver 160... PS-6600: "Display: Toshiba T7900, 2*T7778A"



Not really feeling like going so far down this rabbit hole, but 2x one chip... /could/ indicate screen-splitting either horizontally or vertically... (though, they could just as well be daisychained). It was also common to have 4bit parallel input on col drivers (as opposed to ours' 8), so it might be loading the left half and right half simultaneously, though that'd be one gnarly framebuffer.

Anyhow, it /might/ be configured as 64x85, displaying two "rows" of 16 5x7 characters per visible line, 6 lines, 84 "rows", plus icons on the 85th.

Why would they /design/ a VLSI with such a weird setting? Hah! ... plausibly the VLSI was designed /for/ this organizer, with future-use in mind...? I dunno...

Anyhow, it seems to work out, math-wise.


OK, then the thing actually has a full-on two-dimensional LCD controller, capable of counting not only the bytes per row, but also the rows.. which, in a previous rambling, I determined wasn't necessary if they /planned/ to have screen-refresh restarted in software by a timer interrupt, and would save several presettable counters. BUT, it probably would be wiser (certainly more "de-facto") to actually count the rows, thus keeping the refresh-rate perfectly constant, thus alleviating the dreaded DC-offset fears of liquid-crystal-driving (which /never/ made sense to me, being that to truly remove DC offset, one would have to drive pixels /exactly/ some integer multiple of the number of DC voltages used to simulate an AC waveform, meaning, e.g. an "on" pixel would have to remain on for exactly four refreshes... and / countless/ other concerns, like those DC voltages' being /exactly/ evenly-spaced, and so-forth... and, frankly, I've done some allegedly horribly abusive things to liquid crystals and never seen any damage... but, maybe it has more to do with, e.g. response-time?)

Ok... rambling...

So, the lcd controller actually has a row counter, and its overflow value is set by bits 1 and 2 in port4... Port4, which I've now determined to be designed exclusively for LCD-controller-configuration (as opposed to multipurpose, "bit-packed"/shared between the LCD controller and a timer peripheral). 

THEN, the alleged "Timer" and its alleged interrupt are /really/ essentially a V-sync interrupt. And that just happens to be quite a useful doodad to use for interrupts, and timing, in many cases, but also, especially, for fast-changing graphics, ala games, which, of course, TI-Calculator assembly-programmers seem to be drawn to.


PORT 4 is for configuring the display controller inside the T6A43. Any other [mis]use is a "hack" of the inspir[ed/ing] sort.

... bit6, ROM-Enable? Note if that is the pin wired to ROM's /OE that A) it happens to be right near the LCD signals, so may've been originally intended for LCD control that this particular display doesn't need (e.g. an enable/sleep input) and B) this pin is an N/C on the TI-85, and appears to be a bit of a hack on the 86 as /OE is generally a shared bus signal amongst all memories and I/O devices on most systems (including z80), but really isn't necessary for most memories since /OE's functionality can usually be implied by tying it low, and using /CS and /WR... as seems to have been done in both the '85 and '86, /except/ for the rare case when developers used a FLASH in place of the OTP-ROM on the '86, and that flash just happens to be weird amongst memory-like-devices in that /OE is /not/ overridden by /WR, so the T6A43's apparently lacking a "real" /OE, TI had to find a GP[I]O to do the job this one time... and, lo, the display controller just happened to have one to spare.


PORT 4 is for display controller configuration, any other use is a hack.


Which, is fine... but shuts down some of my other hack-ideas... e.g. using the display itself for output pins, mainly, which is too complicated anyhow; there are plenty better options.


OK, Smarty, explain bit0 "Disable RAM".

I can't... Frankly, I can't explain how that function would work /at all/ unless *internal to the VLSI* it intercepts the /CS1 signal before the pin.

And that, combined with ROM Enable, and the two unknown bits in port4, would /almost/ make sense that each /CS output has a disable feature (for standby, I guess), except that A) you'd get the same functionality by just not accessing them, and B) the bits are way out of order, and 3) they've different active-levels, and D) they have nothing to do with the LCD controller, right? And port 4 is for configuring the lcd controller, only, wherein every other use is a hack... right?

More reading to be done.


Theory: the LCD controller /has/ to access the RAM for fefreshing... it does so, as far as we can tell, so far, in memory page 0... now, does it do-so before or after the remapping logic that places RAM page 0 permanently at 0xC00? Yes, I'm almost certain there is internal remapper that does that. Could be as simple as an 8-bit buffer (ala 74244) with its inputs directly wired to 0x40, as would be written to port5 or 6 to do the same, and an output-enable wired to the presumably 2-in-4-out demux wired to z80's A15-14. that is already half-implemented for port5/6.

SO: now... the lcd controller *could* have a similarly simple remapper for its own addresses, as selected by port 0... those addresses, the framebuffer, might be remappable from /any/ ram page, via e.g. the unknown bits in port4... and, since they're never set, and 0xc000 is always mapped to the same ram page, we assume there is no such 5th (or 3rd, if you still believe the RAM is really at 0xc000 without a mapper) page-mapper... maybe call it a post-it mapper, instead.

OK, then what...? Then, such could allow for a full 32k of RAM (or even 64k) sans framebuffer, making the T6A43 look just like any ol' Z80 at the address pins... (maybe even default on power-up, in port5/6) and yet a separate VRAM /just/ for the framebuffer... which would be accessible by software by mapping it in, briefly, somewhere in 0xc000-0x7fff (e.g. over the stack, allowing the z80 to basically function as normal, all (other) RAM/ROM addresses accessible normally, for the few instructions necessary to read/write some pixels). And this would be quite nice for a simple z80 design e.g. for a data organizer, because text is updated /very/ rarely compared to cursors on a graph (or games)... now... the actual brief-framebuffer-over-mapping could be done by, e.g. writing bit 0 in the LCD-controller port. And another bit in there, maybe, tells the controller where to look for both that overmapping /and/ its refreshing... e.g. maybe /CS2, or maybe the pin now used for the ROM's /OE...

Essentially, a /CS4 provided by the video controller, which can be enabled to override /CS0-3 during z80 memory accesses, but /isn't/ usually, because it's not wired-up that way, here... why...? 

Well, maybe because RAM/ROM were slow back in the day, so a VRAM of only 1024bytes might need to be faster than affordable at 64k... because, my theory still goes, the vram is output to the display during the z80 DRAM refresh cycle... and... slower memories can add wait states for regular z80 accesses.


The z80 refresh cycle might actually still not only be available for actual DRAM refreshes simultaneously with LCD loads, but could even be one of those outputs, enabled/disabled/repurposed by one of the bits in PORT4. Huh! Anyhow, it's a vagueish theory.

BTW refresh-cycles-for-vid-data-loading would gnarl-up the theory of DC-bias concerns, one frame might take longer to load than another depending on the instructions executed during each. But, i am still not convinced they would've sacrificed calculating speed on a calculator for adding 1024bytes of instruction-execution-delays (essentially DMA) every 200th of a second... 


There was a reason this came up...

Unknown bits, repurposing unused vid-controller signals... i dunno.

... oh, right, but it kinda fits within 86port4.txt and tiports.txt about port4 bit 0... "lcd can access ram, cpu can't"... why would such be wanted...? Unless that's not the purpose at all, the purpose being the opposite, to allow cpu access to (to map in) the separate vram, if it were separate. Essentially bypassing the regular mappers and outputting a chip-select of its own, to its own chip.

Only thing... why would it do-so with RAM, specifically, and not ROM...? How would it know /which/ remapper to bypass? Oh yeah, back to the original theory that  0xc000-0xffff is /always/ mapped to 0x0000-0x3ffff on /CS1... so... /not/ typical z80, on power-up, but very close... and that the VRAM is, then, only mappable into somewhere in 0xc000-0xffff...

Then the various theories from those txt files? 

Tiports.txt: "Bit0=1 freeze. Bit0=0 function"

86port4.txt: "Bit0=1 LCD can access RAM, CPU can't. Read results in floating bus value"... 

Hmmm... OK.... guess it depends on where those reads were performed: z80 page 2, 3? Within the framebuffer or outside it? (TODOS for if I ever get my FLASH backup running... I'm still hesitant of Mem Clears, despite its not being nearly as long as I thought to backup to compy... maybe I'll get over that).

I can't quite see why it'd remap the /entire/ page if that's what it does... then why even have it? And can't see why "disabling RAM" makes sense, except for power-saving, which again is equally-accomplished by just not accessing it (ahhhhh DRAM...? Maybe during "sleep", for a DRAM design, the VRAM would be used for Nonvolatile storage... hmmmm...)... Either way, now I'm sorta leaning to the idea that this was intended to have a separate VRAM, and that using shared-RAM might've been a "hack"... 

E.g. if bit5 is active /CS4-VRAM is always output active. An internal /OE prevents it from outputting to the bus except during dram-refreshes/LCD-data-loads... it probably has to bypass all other /CS3-0 signals, since there is no /OE, it'd cause contention. BUT 

... err..

but doesn't go anywhere... /CS1 would've been rerouted to /CS4 when bit1 is set...


Holy crud, it took me this much thumb-yammering to grab a pen and paper. Sheesh.