General Operation
-----------------
U1-U8 are Alliance SRAMs. They can be installed as a pair of AS6C62256 in bank 0 for a 64k 16 bit system, a pair of AS6C1008 in bank 0 for a 258k 18 bit system, or in 1-4 pairs of AS6C4008 for a 1, 2, 3, or 4mb 22 bit system. Jumper settings, provided on the schematic, serve to tie the unused address lines low and disconnect them from the bus (as the 11/2, 11/3 and maybe some others use these lines for other purposes), and to reconfigure pin 30 of bank 0 to provide CE2 or Vcc to the 32k and 128k chips, instead of A18.
/BINIT is asserted on system reset, and clears the latches.
FIXME: Do we also need to clear them on the falling edge of SYNC?
The QBUS signals are buffered through a pair of 74LS640 8-bit inverting bus transceivers, a 74LS240 8-bit inverter, and a 74LS14 hex inverter. LS14s could probably have been used in place of the LS240, but using the LS240 made drawing the schematic easier.
Address Latching Cycle:
-----------------------
The address is latched at the beginning of the bus cycle, regardless of whether it is a read or write cycle. The bus master drives an address on /BDAL0-/BDAL21. If this address is within the top 8k of the lower 64k address space (the peripheral IO segment), the bus master also asserts /BBS7.
On the rising edge of SYNC: A0-A21, /BS7, and the original inverted version of /A0 (this saves a gate later) are latched into a triplet of 74LS273 8-bit registers.
After at least 100ns, the bus master then clears the address from DAL0-DAL21, in preparation for the second half of the bus cycle. The second half of the bus cycle may be a read, a write, or a read-modify-right (a read followed immediately by a write to the same memory location, without releasing SYNC).
RAM chip enable is provided by a 74LS139 dual 2-to-4 decoder. A20 and A21 are decoded into a bank select, and the enable line is used to select between the low byte, the high byte, or both bytes (the whole 16-bit word). Details on the high/low bank selection can be found below.
Write Cycle:
-----------
The bus master places the data to be written on DA0-DA15. After 100ns, the DOUT and (if it is an 8-bit write) WTBT.
U16 handles the high- and low- byte enables. If /BS7 is low (an access to the peripheral IO segment), neither byte may be enabled. Otherwise, if WTBT is false (full 16-bit write) or A0 is high or low (depending on which half of the LS139 is being enabled), the 2-to-4 decoder is enabled and the a low signal is produced on the appropriate /CE (chip enable) line(s) for the RAM.
U17B generates a /WE (write enable) signal for the RAM, if /BS7 (IO segment) is not asserted.
With /CE and /WE both asserted on the appropriate banks of RAM, the memory latches the values presented on its data lines into the address pointed to by A1-A19.
The /WE signal passes through and is inverted by U17C. An RC circuit on the output of U17C causes a short delay as capacitor C0 charges until the voltage rises high enough to trigger the input of U15E. This delay gives the RAM time to store the data. When U15E triggers, it pulls /BRPLY low, signaling to the bus master that the data has been stored in the RAM.
In response to BRPLY, the bus master releases DOUT. BRPLY is released as a consequence, and then the bus master releases SYNC.
Read Cycle:
-----------
Read cycles are always a full word wide. WTBT is never asserted during a read cycle. As such, as long as /BS7 (IO segment access) is false, both 2-to-4 decoders are alwayys enabled. A20 and A21 are used to produce /CE (chip select) signals for the appropriate pair of RAMs.
The bus master asserts DIN, and as long as /BS7 (IO segment access) is false, an /OE signal is generated on the output of U17A.
With /CE and /OE both asserted on the appropriate banks of RAM, the memory presents the value stored in the address pointed to by A1-A19 to DA0-DA15 on the near-side of the bus transceivers.
The /OE signal passes through and is inverted by U17C, and a RPLY signal is generated in the same way as during a write cycle. Additionally, /BUS_OUT is asserted, which changes the direction of the LS640 pair, allowing the data from the RAMs to make its way onto the system bus.
The bus master consumes the data, and then releases DIN. BRPLY is released as a consequence, and then the bus master releases SYNC.
Potential Issues:
-----------------
This card does not make use of the +5B battery backup lines, nor does it disable chip selects in the event of power failure to preserve memory contents in the face of undefined bus signals. However, since most QBUS machines these days are only operated as a hobby, I don't think this is much of an issue.
The card decodes and drives the bus during reads throughout the entire memory map (excepting of course the BS7 segment). As such, it will conflict with any other memory cards installed in the system even if you don't install all eight AS6C4008s. If you are using a CPU with built-in RAM, that built-in RAM will have to be disabled. I do not have any such CPUs, and I have no idea if the built-in RAM on such CPU cards even *can* be disabled. So if this is a major issue then please let me know and we can figure out how to add some additional logic to mask off certain segments or something.
I wanted to do this with discrete logic and all through-hole ICs (because muh anachronism). I haven't even thought about laying out the board yet though. It may not all fit on a dual-height board. Our options in that case could be to make it a 2mb maximum card and add a jumper to select between the high or low 2mb (so you'd run two card in your system if you wanted 4mb). Or we could put all the decoding and latching on an ATF1502 or a couple 22V10s or something, although I'd hate to do that! Not everyone has the equipment to program that stuff.