|K1-Bus 68008 CPU board with SRAM – K1-Bus I/O Circuit|
Short summary of the K1-Bus
The ➧ K1-Bus is a 16 bit peripherals bus designed for simplicity. The basic unique concept of this bus is that the peripheral board accessed is not encoded in the address of each I/O opcode but the board to talk to must be selected. During selection the boards are addressed with a low level on their assigned data line.
Interrupts are signaled on the !K1_IRPT collector line and during interrupt processing the CPU queries the interrupt state of all devices. The CPU can enable and disable interrupts for each device individually by writing a mask work on the data bus. This way all devices may be assigned an individual interrupt priority if the programmer desires.
There are 5 control lines (strobe signals):
- !SELECT – The CPU writes a mask word on the bus to select a peripheral board for subsequent data transfer.
- !WR_IRPT – The CPU writes a mask word on the bus to enable or disable interrupts on the attached boards.
- !RD_IRPT – The CPU reads a mask word with the interrupt state of all attached boards.
- !WR_DATA – Send data to the selected device.
- !RD_DATA – Read data from the selected device.
The 74HCT138 3-to-8 line decoder generates the strobe signals for the bus when A19 is '1' during a bus cycle when !AS is low. A0, A5 and the !WR signal are used to determine which signal to activate. For the reason to chose A0 see below.
IC 74HC367 with the surrounding resistors and diode implement an i2c interface. Every K1-Bus extension board can provide an i2c EEprom with software driver for the board. Also, the i2c EEprom is used to detect the presence of the board. The funny circuit design is directly taken from my ➧ K1-Bus homepage. It was the simplest circuit i could come up with if no port pins are available to be used for the i2c bus.
The i2c bus is always accessed by reading from the K1-Bus and one of the select lines of the 74HCT138 3-to-8 line decoder is used to address the 74HC367. A6 and A7 are forwarded to the i2c data and clock line while the i2c data line is also read and returned in D7. When the i2c bus is selected, the upper 4 drivers of the 74HC367 are enabled. Then A6 and A7 are forwarded into the lower two drivers. When the upper drivers are disabled the resistors R1 and R2 feed back the output of the lower drivers to their inputs thus making them state keepers. So the low or high state of the i2c data and clock outputs are preserved until the next access is made to the 74HC367. The timing and protocol of the i2c bus must implemented in software. The i2c bus is optional but recommended unless you want to build a one-task computer which does not support to be extended later.
The two LEDs D4 and D5 may be attached here during debugging. As the 68008 CPU board does not have any I/O pins whatsoever, i have spent some time searching for a place to attach some status lights for initial testing. The LEDs should be removed when an I/O board is attached, because the LEDs may disturb operation of the i2c bus.
The two 74HCT574 data latches expand the 8-bit 68008 data bus to 16 bit for the K1-Bus. This is optional and only required if 16 bit extensions are actually attached. A serial card will probably be only 8 bit wide, but an IDE interface will most likely use the full bus width.
When 16 bit data is written to the bus this is done in two stages: First the upper byte is written into the 74HCT574 low-to-high data latch. One output of the 74HCT138 3-to-8 line decoder provides the !WR_HI strobe. Next the low byte is written to the !WR_DATA address as usual. While the CPU provides the low byte the latch outputs are enabled simultaneously and put their data on the upper half of the bus.
Note that only A0 discriminates between !WR_HI and !WR_DATA. This way the program can perform a 16 bit write opcode to the even base address: The high byte will be written first to the even address (A0=0) and the low byte thereafter to the odd address (A0=1). That's really sweet! :-)
When 16 bit data is read from the bus this is also done in two stages: First the low byte is read using !RD_DATA as usual. This will also load the high byte from the K1-Bus into the high-to-low data latch. Then the high byte can be read from the latch. For this the 74HCT138 3-to-8 line decoder provides the !RD_HI strobe.
Reading a 16 bit word is not as convenient as writing. Again !RD_DATA and !RD_HI are chosen to differ only in A0 and the word can be read with one 16 bit read opcode, but the result will be byte-swapped. This cannot be avoided except with some more latches and drivers. So the program has to swap them thereafter and as the 68000 does not provide a byte-swap opcode (though it provides one for word swapping) the best is probably to do an 8-fold rotate left or right on the word data which is a 24 clock cycles time consuming operation.
There are some pull-up resistors and networks related to the K1-Bus:
The !K1_IRPT collector line has a pull-up because it must be driven with open drain outputs.
!K1_RESET line has a pull-up for the same reason.
!K1_WAIT has a pull-up in case no peripheral board is selected. Whenever a board which uses the wait line is selected it must drive the wait line with a tri-state driver which actively pulls high and low. When a board is not selected it must not drive the wait line.
D0..D7 are pulled high with 3.3kΩ resistors. The data bus of the CPU is connected without bus drivers to the K1-Bus. This is possible for very small projects because the K1-Bus is defined to attach CMOS devices which draw only very little current, though switching the level on a line draws some current for the line capacitance which increases with line length and every device attached.
The 68008 CPU outputs TTL levels with very poor high-driving capability: 0.4mA only. The K1-Bus is defined for symmetrical signals as used by 74HC or 74AC types. This is in general no problem, only some timing parameters will shift a little. But as the 68008 can only drive 0.4mA high (and still guaranteeing only 2.4V, so effectively driving even less than 0.4mA) these resistors are there to help the CPU with the '1' bits. 3.3kΩ result in 1.5mA when the outputs are low which is approx. 1/2 of what the CPU can drive low. Peripheral drivers also must provide this additional current for low bits, but 1.5mA should be ok with almost any IC.
A0..A5 (on the K1 Bus) are pulled high for the same reason.
A6 and A7 are pulled high for the same reason because they are attached to the 74HC367 which is not a 74HCT367. I'm too lazy to modify the circuit for a 74HCT367 and i have HCs in stock, HCTs none.
More random notes:
The 74HCT574 high-to-low and low-to-high data latches were chosen to use HCT because when the CPU can operate the bus with TTL levels then the latches can do this as well. No need to read some data lines with HC circuits – keep it consistent.
This CPU board can attach 16 bit K1-Bus extension boards. This means, it can read and write 16 bit data. But it cannot use the upper byte of the data bus for board selection: !SELECT, !RD_IRPT and !WR_IRPT all do not trigger a read or write of the high-to-low / low-to-high data latches. Therefore peripheral cards are limited to D0..D7 for selection.