The problem of the externel devices consists in the possibly very long disable time of the data acknowledge signal (DSACK) and the data bus for read accesses. Furthermore, the DUART has a very long hold time for the data in a write access.
To overcome this, we insert a bidirectional driver with internal registers into the data bus. Each port of the driver is controlled by 3 signals:
The CPU side port is activated for read accesses by /RDOE. Basically, it runs with the according chip select.
A direct write after an read access to some external bus master would due to the large disable time conflict with the still driving master and cause bus contention. But luckily there has to be a fetch after the access and in the meantime the external bus has disabled its data bus interface. Even for fast loops, where there is no fetching, the next cycle is completely internal (update and test internal counter).
In write cycles the chip select is enabled as early as the data strobe (/DS). Since the computation of the /WROE takes some time and the external bus controller expects valid data with the chip select going low, we enable the data bus driver with the write signal (/RW), that is valid after the first half clock cycle of the access. Consequently, in every write cycle the data bus driver is enabled. To ensure the large hold time specification of the DUART the /WROE signal is registered. Since the RW signal changes its state as early as in the first clock cycle of the next bus cycle, the data port is still active one clock cycle after the write access. To deliver valid data as long as possible, the port's source is switched to the internal register with the negated /AS signal. Thus, data is valid early in the beginning of the write cycle and gets invalid when the next read cycle starts.
The data acknowledge signal is handled in the same way as the data bus is. Since it is unidirectional, the driver is implemented in the GAL. The computattion of the enable signal needs to cover several cases and thus, the logic equation contains some 'or'. But the GAL offers only one term. Consequently, a seperate output is used for its computation.
A second issue is the interupt acknowledge cycle. It is basically a read cycle, but there is no chip select set. Hence, the cycle has to be decoded by the GAL. Such a cycle is recognized by the two low order function code bits (FC1, FC0) beeing 1 and address bit A0 beeing 1 as well. Address bits A1,...,A3 give the interupt level. This is sufficient because the lowest address bit distinguishes between other CPU space cycles. Due to lack of input pins A0 is not decoded. In selecting only unequal interupt levels, i.e. A1 is always 1 in this case, this distinguishes the interupt acknowledge cycles for these devices from other CPU cycles.
Finally, the resulting equations for the GAL.
GAL22V10 CK EQ RW /AS FC1 FC0 A3 A2 A1 /CS5 /CS2 GND /CS1 /DACKI DACKOE /IACK1 /IACK3 /IACK5 RDOE /WROE WRCK /REGCE /DACKO VCC RDOE = (/CS1 + /CS2 + /CS5)*RW + /IACK1 + /IACK3 + IACK5; /IACK1 = /AS*RW*FC1*FC0*/A3*/A2*A1; //IRQ1 --> I2CB /IACK3 = /AS*RW*FC1*FC0*/A3*A2*A1; //IRQ3 --> I2CA /IACK5 = /AS*RW*FC1*FC0*A3*/A2*A1; //IRQ5 --> DUART /WROE := /RW; WRCK = (CS1 + CS2 + CS5)*/RW; DACKOE = /CS1 + /CS2 + /CS5 + /IACK1 + /IACK3 + /IACK5; /DACKO.OE = DACKOE; /DACKO = /DACKI; //---------------------------------------------------------- /REGCE := /AS*/RW*/FC1*FC0*EQ*REGCE //on with adr valid and /AS + /RW*/FC1*FC0*EQ*/REGCE; //off with read or adr invalid
In the lower part of the definition of the GAL-equations the clock enable for the binary output is given. The register is clocked with the /DS signal. The clock is enabled after recognition of a valid address and an active address strobe (/AS). It is disabled again when the address gets invalid or the next read cycle starts. This is certainly before the next clock.
The GAL registers are automatically reset after during power up. Thus, the write enable of the data bus driver and the clock enable of the binary output register are both invalid.