i worked on the main circuit and removed 2 (two!) of the four glue logic ICs. Wow! This is near-Sinclair. I could remove one more IC and become equal-Sinclair. Or remove both remaining glue ICs and become super-Sinclair.
What does this
You know i come from the Sinclair ZX Spectrum side of the universe (as opposed to the C64) and i have certain ideas about how Sir Sinclair worked. What he did was like this:
- Use the cheapest components,
- reduce the design to the absolute minimum
- and then take away one more part.
Hint: right-click on the image and open it in another window if you want to keep it visible while you read on!
As you can see there are only two glue ICs: one Quad NAND 74HCT00 and a Dual 2-to-4 line decoder 74HCT139 with only one decoder actually used.
The 2nd NAND IC7C is used as an inverter and constructs a !RD signal from the CPU's !WR signal, required by the RAM and the ROM.
The next two NANDs construct a flip flop, which is set by !RESET to indicate the initialization phase after system reset. The INIT signal from this flip flop is used to pull A18 high at the input of the 2-to-4 decoder IC2A. (The resistor R5 and the diode D2 actually construct an OR gate without wasting 3 unused gates in a 74HCT32.)
This is used to circumvent a design flaw in the 68000 microprocessor series: After reset the supervisor stack pointer and the program counter are read from addresses 0x00000.l and 0x00004.l respectively so there must be ROM mapped in. But then the whole vector table of the cpu is located here; actually roughly the first 1 kByte of memory is used for vectors. It is very desirable to have these in RAM because otherwise you cannot change them without a secondary vector table in RAM which is jumped to by the vectors in ROM. So you need ROM after reset but you prefer RAM here at any other time. The normal memory layout is RAM at address 0x00000 as you can see from the 2-to-4 decoder outputs, but during initialization A18 is pulled high so that the processor, when trying to read from address 0x00000 and 0x00004 reads from the ROM instead. After that the first memory access to the slow I/O address range will also reset the NAND flip flop and A18 is no longer forced high and the RAM can be accessed.
After we know where the !SLOW_IO signal comes from we can understand what the first NAND gate IC7D does: If !WAIT is high and !SLOW_IO is high then the !DTACK signal to the CPU is low (asserted). The !DTACK signal is used to terminate a normal bus cycle of the CPU, either memory or other bus access. !DTACK will not be asserted when !WAIT from the K1 bus is active, thus implementing the wait processing for the K1 bus, or when !SLOW_IO is low which means a memory access to an address with A18=1 and A19=1. This memory range is used for slow I/O (sic!) and shall use the 6800 peripherals slow addressing mode, which is signaled to the CPU by pulling it's !VPA entry low instead of activating !DTACK. You can see that !SLOW_IO is directly connected to !VPA of the CPU. So either !DTACK is asserted (for the first 3 memory ranges, eventually suppressed by !WAIT) or !VPA.
Trick: Connecting !SLOW_IO to !VPA has a second effect: This also requests the CPU to use an auto-vector from it's vector table for interrupts. When an interrupt is acknowledged and the CPU reads the vector number for this interrupt, most address lines are pulled high, most notably A18 and A19, which will activate !SLOW_IO which activates !VPA which requests an auto-vector if it is pulled low during an interrupt acknowledge cycle. We only have to take precautions that this not also performs spurious I/O on the K1 bus; but that's on the other sheet. :-)
That's all about the glue logics. Not supported are:
- Bus arbitration for multiple bus masters
- Bus error or any other exception signaling
How to become Equal-Sinclair
Let's remove the Quad NAND IC. Will it still work?
If we remove the first NAND IC7D then we'll lose wait handling for the K1 bus. Ok, well, that may be acceptable. But we'll still need an inverter here to invert !SLOW_IO to !DTACK.
To solve this, we could connect A19 directly to !DTACK, so whenever the CPU accesses RAM or ROM !DTACK will be asserted. But then we'll lose !FAST_IO because whenever !DTACK is not asserted !VPA must be asserted instead to finish the bus cycle. So !VPA must be connected to !A19. How can we invert A19? We can use the unused gate from the Dual 2-to-4 decoder. If we have no fast I/O we also need no wait cycle handling. :-) Check.✓
If we remove the second NAND IC7C then we'll lose the !RD signal. This is acceptable: !OE of the ROM can be tied high so whenever the ROM is enabled it puts it's data on the bus. Disadvantage: If the CPU writes to the ROM then there'll be a collision on the data bus. We'll have to be cautious.
!OE of the RAM can also tied high. When !WR is enabled this will supersede the !OE signal. (eventually this is not true for all RAMs, but RAMs exist which can be operated in this way). Check.✓
If we remove the NAND flip flop, we'll no longer have the INIT signal. Ok, let's remove the resistor-diode OR gate as well and let's swap !ROM_CE and !RAM_CE. ROM has to be at address 0x00000 and we can't modify the vector table in ROM. Check.✓
Summary: Yes, we can become Equal-Sinclair! We just have no fast I/O and we'll have to live with the vector table in ROM. That's easy.✓✓✓
How to become Super-Sinclair
Obviously we must remove the Quad 2-to-4 line decoder as well. Will it still work? Ok, that's real hard, but Super-Sinclair IS real hard. You get a "Sir" for Equal-Sinclair, right?
First let's remove the gate used to construct the inverter for address line A19 which we just have added to become Equal-Sinclair. Now we have the choice: We could build an inverter from two resistors and one transistor or we could ... leave it out. Yes, that's what Sir Sinclair had done. :-)
We either need !VPA to be asserted during interrupt acknowledge or we must to supply a vector address. Both is possible:
Supply !VPA: Tie !VPA fixed low and !DTACK fixed high and the CPU will do all bus cycles in 6800 mode. Will be a little slow though. We'll have slow memory access and only slow I/O.
Supply !DTACK: Tie !VPA fixed high and !DTACK fixed low and the CPU will do all bus cycles in standard mode. We'll have fast I/O (with no wait cycles) but no slow I/O. During an interrupt acknowledge cycle we'll have to provide a vector number on the data bus. We can use a resistor network to pull up all data lines if no one else drives the bus, then the vector number will be 0xFF (255). Check.✓
Now – shiver! – let's remove the address range decoder. Can we provide !RAM_CE, !ROM_CE and !FAST_IO (no need for !SLOW_IO) somehow else?
Yes, we can! We can use 3 address lines directly to do that:
• Use A17 for !RAM_CE,
• A18 for !ROM_CE and
• A19 for !FAST_IO.
Each range is limited to 128 kByte. (A0..A16) Accepted.
There will be be bus collisions if the program accesses addresses with more than one of A17 .. A19 low. Accepted.
There may be short bus collisions when the address lines toggle between bus cycles. Accepted.
After reset the CPU will read from address 0x00000.l and 0x00004.l Uh uh... This will read from RAM, ROM and IO simultaneously. And any other vector will be read from this page with triple-collision as well. That's bad.
I'm a programmer and i'm here to find solutions: We have to disable RAM and IO when the ROM is selected. This will also reduce the forbidden address ranges with bus collisions.
We can get the RAM out of the way by its positive CE input. Yeah, it has one. Look at the circuit diagram. Just connect RAM.CE to A18 (!ROM_CE). When the CPU reads any vector from the first kByte of memory then A18 will be low and the RAM is not enabled. Check.✓
Next we can suppress the K1 bus control signals in a similar way: As you not yet know they are generated with a 3-to-8 line decoder 74HC138 which has two negative and one positive enable input. We can connect A19 (!FAST_IO) and !AS to the negative enables, and A18 (!ROM_CE) to the positive enable. Check.✓
Summary: Yes, we can become Super-Sinclair! We just have only fast I/O with no wait cycles, we'll have the vector table in ROM and we are limited to 128k ROM and 128k RAM and there is a risk of bus collisions if the program accesses forbidden address ranges and there may be regular very short bus collisions between each bus cycle.
Accepted. Design finished, let's ship it. ;-) Check✓ Check✓ Check.✓