The WPC Dot Matrix Display Controller

Originally published January 10th, 2001 in the Usenet newsgroup: Rec.Games.Pinball



Introduction

I was going to write this up as a technical article. (To be honest, I can't remember the last time I wrote one for the group.) It's very technical, and will probably bore most of you to tears. I make no apology for it's complexity -- it's a very technical subject.

If you want to follow along, I suggest reading this along with the dot controller schematics.

This is not intended to be a troubleshooting guide -- only a logic level description. I've omitted the parallel to serial conversion and blanking logic description because I never got 'round to writing it. For those who are interested in this kind of stuff, maybe for custom projects or just to get a better understanding of the way the controller works...enjoy.

I've reverse engineered from the schematics, and like most humans, I'm prone to making mistakes. Please highlight any errors or omissions to me by e-mail.


Understanding the Role of the Clock

It's been mentioned before (more than once) that the WPC 6809 accesses the 8kb dot controller static RAM during the negative phase of the 'E' clock ('E' low) - this is not so. A single clock cycle is broken down into 4 quarter-clock cycle events for internal processing by the 6809. The 6809 does not allow for
valid data on the bus during 'E' low. A memory cycle comprises of 'E' going low on the first quarter cycle with 'Q' also low. The next quarter cycle sees 'Q' rise to high during the latter half of 'E's second quarter cycle low - the address on the address bus now becomes valid. 'E' then remains high for two further quarter cycles and during *this* period the address bus and data bus both hold valid data. The bus cycle is then terminated when 'E' goes low - ready for the next cycle. That was a 6809 clock-cycle. :-)

What the DMD controller does is this: It takes both 'Q' and 'E' clocks and generates a third clock strobe by inverting 'E' - 'IE' (Inverted 'E'). 'E' is feed into an inverting bus driver (HCT240) at U7A to generate an inverse clock strobe then 'E' is feed back through U7B (the same inverter) to correct itself. A tap off is made here and inverted at U7A to generate the 'IE' clock.

The DMD controller runs in two modes - a 'free-running' mode where data previously written to the onboard controller RAM is clocked out to the display using the 'Q' and 'E' clocks as a timing reference (without 6809 intervention), and '6809 access' when the processor needs to gain access to the RAM to update display data. I don't know what WMS called the two modes of operation, I've just named them for the purpose of describing the functionality. During a normal bus cycle, a read, write or read-modify-write
cycle causes IE to become low and switch control of the dot controller RAM to the 6809 - releasing it to the processor busses. During 'E' low (data is not valid on the 6809 busses), IE goes high and the dot controller takes over to clock data out of the RAM, into a serial stream and then into the DMD.


Dot Controller Logic

(Address' with respect to 'I/O' being $0000. Offset given address' by adding the chip-select 'I/O' address when mapping.)

'PORT' ($1800, active low) releases the RAM from the dot controller to the 6809 processor for writing new display data. The page to be written too appears to be set up in advance - HIGHPAGEWR for odd address' and LOWPAGEWR for even address' each on a 512 byte-boundary. Both registers are write-only.

Address line A9 selects the low page when low and the high page when high. The high order address bits for page selection are latched by either HIGHPAGEWR, LOWPAGEWR or both and held stable at the RAM address pins (obviously, not both at the same time). These high-order address bits are actually generated by the data bus (low-nybble in both instances) by setting up the address in advance.
Since A9 will automatically select the next page address when it changes state by crossing 512-byte boundaries, it's possible to write 2 pages (1kb of display data) at once (providing both HIGH and LOWPAGEWR hold valid, non-conflicting RAM address'). The lower 9 address lines (A0-8, 512 bytes) are used to address each RAM byte location per page.

The DISPAGEWR register hold the next address of the page to be displayed. This is clocked into the latch at U32 when row 32 is over (NEXTPAGE). This appears to be an automated sequential/clocked function. DISPAGEWR could either contain the same page address for looping or a new page address to be displayed.

The HIGHPAGERD (read only) register compliments the lower nybble of the HIGHPAGEWR register and is used to determine if page 15 is being displayed (if a read of this register results in zero, page 15 is being displayed).


Interrupt Generation

The controller can generate a maximum row status interrupt when row 'n' is over. Writing the maximum row number allowable to the ROW_IRQ (write-only) register causes the controller to compare that binary data with the current binary row number. The register supports 8-bits but the row counter is only
5-bits, this is useful in that setting a count higher than 32 will never assert an interrupt. When they are equal (32 or less) the flip-flop at U5A asserts itself upon the FIRQ (Fast Interrupt ReQuest) line, grounding it. A read of the FIRQRD (read-only) register determines the interrupt source. If
the MSB of the FIRQRD register (D7) is set to 1, the interrupt is valid.


Address decoder U2

Cycle A0 A1  r/w  O/P    Signal    address
----- ------ ---  ---    ------    -------
write  0  0   0    Y0  HIGHPAGEWR   $1FBC
read   0  0   1    Y1   Not used      --
write  0  1   0    Y2    ROW_IRQ    $1FBE
read   0  1   1    Y3    FIRQRD     $1FBF
write  1  0   0    Y4   LOWPAGEWR   $1FC0
read   1  0   1    Y5   Not used      --
write  1  1   0    Y6   DISPAGEWR   $1FC2
read   1  1   1    Y7   DISPAGERD   $1FC3



Paging via DISPAGEWR ($1FC2), HIGHPAGEWR ($1FBC) and LOWPAGEWR ($1FC0)
(data presented over data bus bits D0-D3)


D3 D2 D1 D0
-- -- -- --
0  0  0  0  page 0 $0000
0  0  0  1  page 1 $0200
0  0  1  0  page 2 $0400
0  0  1  1  page 3 $0600
0  1  0  0  page 4 $0800
0  1  0  1  page 5 $0a00
0  1  1  0  page 6 $0c00
0  1  1  1  page 7 $0e00
1  0  0  0  page 8 $1000
1  0  0  1  page 9 $1200
1  0  1  0  page 10 $1400
1  0  1  1  page 11 $1600
1  1  0  0  page 12 $1800
1  1  0  1  page 13 $1a00
1  1  1  0  page 14 $1c00
1  1  1  1  page 15 $1e00

-- End