1 | Name QBus14 ;
|
2 | PartNo 00 ;
|
3 | Date 03/28/2008;
|
4 | Revision 14 ;
|
5 | Designer CHD ;
|
6 | Company ;
|
7 | Assembly None ;
|
8 | Location ;
|
9 | Device f1508ispplcc84 ;
|
10 |
|
11 | /* revisions */
|
12 |
|
13 | /* 14 Name changed to prevent confusion with previous version 13 series. */
|
14 | /* Removed all logic support for DMA. */
|
15 | /* Changed interrupt logic to more closely follow DC003 logic */
|
16 |
|
17 | /* 13 Renewed development.
|
18 | /* The contents of the CPLD on the prototype board does not match the .jed file */
|
19 | /* generated when version 12 is compiled. The published version 12 has some */
|
20 | /* debugging changes that are not shown on a version 11 printout. Revision 13 is */
|
21 | /* an attempt to reconstruct the last reasonably functional version as a starting */
|
22 | /* point for further efforts. */
|
23 |
|
24 | /* pre 2002 */
|
25 | /* 12 Published version including some debug hooks. */
|
26 | /* 11 Buggy version used to write wd driver for 2.11BSD. */
|
27 |
|
28 |
|
29 |
|
30 | /* PIO Mode Only Adapter */
|
31 |
|
32 | /* $define JUMPERS */ /* include logic for address switches */
|
33 | /* if not defined, address is hardwired */
|
34 |
|
35 | /* editor font: Courier New, Regular, 10 */
|
36 |
|
37 | /*
|
38 |
|
39 | BB
|
40 | +--------------------------------+
|
41 | | |
|
42 | +-----+ | +----------+ +-----+
|
43 | QB | |<---+-+------| | CTL | |
|
44 | ----|TRANS| | | CPLD |---------| ATA |
|
45 | | | TSBUF | | | |
|
46 | +-----+ ^ | | +-----+
|
47 | | | +----------+
|
48 | +---------+ |
|
49 | BA |
|
50 | |
|
51 | +-----+ |
|
52 | QB | | |
|
53 | ----|TRANS|------------------+
|
54 | | |
|
55 | +-----+
|
56 |
|
57 |
|
58 | */
|
59 |
|
60 | /* Device Selection */
|
61 |
|
62 | /* Q22 addressing */
|
63 |
|
64 | /* 1 7 7 6 0 0 0 0 */
|
65 | /* 1 111 111 11A AAA AAA BBR RR0 */
|
66 | /* where A is the variable base CSR address */
|
67 | /* B is the register bank */
|
68 | /* R is the register select */
|
69 |
|
70 | /* 1 111 111 11A AAA AAA A00 000 CSR - base control register (including DMA address extension) */
|
71 | /* 1 111 111 11A AAA AAA A00 010 CNT - DMA count register - NOT IMPLEMENTED (reserved) */
|
72 | /* 1 111 111 11A AAA AAA A00 100 DMA - DMA address register - NOT IMPLEMENTED (reserved) */
|
73 | /* 1 111 111 11A AAA AAA A00 110 VECT - interupt vector number */
|
74 | /* 1 111 111 11A AAA AAA A01 000 (reserved) */
|
75 | /* 1 111 111 11A AAA AAA A01 010 (reserved) */
|
76 | /* 1 111 111 11A AAA AAA A01 100 CS1 disk controller register */
|
77 | /* 1 111 111 11A AAA AAA A01 110 (reserved) */
|
78 | /* 1 111 111 11A AAA AAA A1X XX0 CS0 disk controller registers */
|
79 |
|
80 | /* clock rate: 32MHz *
|
81 | /* state1 state2 state3 state4 state5 */
|
82 | /* minimum delay 1 2 3 4 5 */
|
83 | /* 31ns 63ns 94ns 125ns 156ns */
|
84 | /* maximum delay 2 3 4 5 6 */
|
85 | /* 63ns 94ns 125ns 156ns 188ns */
|
86 |
|
87 | $define TRUE 'b'1
|
88 | $define FALSE 'b'0
|
89 |
|
90 | /* DECLARATION */
|
91 |
|
92 | /* Adapter Tri-State Bus */
|
93 | pin [8, 9, 6, 5, 4, 37, 36, 35, 31, 30, 28, 29, 27, 11, 24, 10]
|
94 | = [DAB0..15];
|
95 |
|
96 | field DAB = [DAB0..15]; /* Full word width bus */
|
97 | field DAB_HIGH = [DAB8..DAB15]; /* Upper byte */
|
98 | field DAB_LOW = [DAB0..DAB7]; /* Lower byte */
|
99 |
|
100 | /* disk control signals */
|
101 | pin [49, 48, 61]
|
102 | = [DA0..2]; /* disk register address */
|
103 | pin 17 = !DCS1; /* disk chip select 0 - pin */
|
104 | node CS1; /* disk chip select 0 latch */
|
105 | pin 34 = !DCS0; /* disk chip select 1 - pin */
|
106 | node CS0; /* disk chip select 1 latch */
|
107 | pin 16 = !DIOR; /* disk controller read operation */
|
108 | pin 15 = !DIOW; /* disk controller write operation */
|
109 | pin 39 = DIORDY; /* disk controller ready for word transfer */
|
110 | pin 40 = DINTRQ; /* disk controller interrupt request */
|
111 | pin 50 = !DIOCS16; /* disk controller 16-bit transfer operation */
|
112 | pin 60 = !DRESET; /* disk controller hardware reset */
|
113 |
|
114 | /* QBUS control signals */
|
115 | pin 1 = INIT; /* bus reset */
|
116 | pin 58 = S7; /* device page select */
|
117 | pin 81 = SYNC; /* bus address sync */
|
118 | pin 2 = DIN; /* data read cycle */
|
119 | pin 45 = DOUT; /* data write cycle */
|
120 | pin 25 = RPLY; /* bus cycle handshake */
|
121 | pin 18 = IRQ4O; /* interrupt request - level 4 - QBus out*/
|
122 | pin 44 = IRQ5; /* interrupt request - level 5 */
|
123 | pin 46 = IRQ6; /* interrupt request - level 6 */
|
124 | pin 41 = IAKI; /* interrupt acknowledge daisy chain in */
|
125 | pin 12 = IAKO; /* interrupt acknowledge daisy chain out */
|
126 |
|
127 | pin 83 = CLOCK32; /* clock for delays */
|
128 | pin 20 = !QB_DREN; /* Qbus read - enable OC bus drivers */
|
129 | /* This signal drives the qbus BDAL with the tristate bus contents. */
|
130 | pin 21 = !QB_TSEN; /* Qbus write - enable TS buffers between bus A and bus B */
|
131 | /* This signal drives the tristate bus from the qbus. */
|
132 | pin = SEL; /* address match */
|
133 | node [RPLYD0..3]; /* state vector for RPLY delay */
|
134 | node [IOWD0..3]; /* state vector for IOW delay */
|
135 | node INT_ARB_WON; /* internal signal indicating that adapter gets interrupt */
|
136 | node ATA_IRQ; /* internal F/F to capture drive interrupt request */
|
137 |
|
138 | $ifdef JUMPERS
|
139 | /* Option Configuration */
|
140 | pin = [CSR_BASE0..7]; /* CSR base address jumpers */
|
141 | field CSR_BASE = [CSR_BASE0..7];
|
142 | field DAB_CSR = [DAB5..12];
|
143 | $endif
|
144 |
|
145 | /* TEST and misc signals */
|
146 | pin 22 = SYNC_LITE; /* light driver showing bus activity */
|
147 |
|
148 | /* CSR - Control and Status Register */
|
149 | pin = CS_COM; /* internal select */
|
150 |
|
151 | pin = INT_ENABLE; /* 6: interrupt enable from disk controller to QBus */
|
152 | node IORDY_ENABLE; /* 5: use IORDY signal from disk controller */
|
153 |
|
154 | /* VECTOR - Interrupt Vector Number Register */
|
155 | pin = CS_VECT; /* internal select */
|
156 |
|
157 | node [VECTOR0..6]; /* Interrupt vector number */
|
158 | field VECTOR = [VECTOR0..6];
|
159 | field DAB_VECT = [DAB2..8];
|
160 |
|
161 | /* reserved space */
|
162 | node RSRVD;
|
163 |
|
164 | field REG_ADDR = [DAB0..4];
|
165 |
|
166 | /* LOGIC */
|
167 |
|
168 | /* QBUS Reset */
|
169 | DRESET = INIT;
|
170 |
|
171 | /* QBUS Addressing */
|
172 |
|
173 | /* 1 111 111 11A AAA AAA BBR RR0 */
|
174 | /* 1 7 7 7 1 0 0 0 */
|
175 | $ifndef JUMPERS
|
176 | SEL = S7 & DAB:'b'xxxxxxxxx10010000xxxxx;
|
177 | $endif
|
178 |
|
179 | $ifdef JUMPERS
|
180 | field MATCH = [MATCH0..7];
|
181 | MATCH = !(CSR_BASE $ DAB_CSR);
|
182 | SEL = S7 & MATCH:&;
|
183 | $endif
|
184 |
|
185 | CS_COM.L = SEL & REG_ADDR:'b'00000; /* BASE + 0 */
|
186 | CS_COM.LE = !SYNC;
|
187 |
|
188 | CS_VECT.L = SEL & REG_ADDR:'b'00110; /* BASE + 6 */
|
189 | CS_VECT.LE = !SYNC;
|
190 |
|
191 | RSRVD.L = SEL & REG_ADDR:'b'00010 /* BASE + 2 */
|
192 | # SEL & REG_ADDR:'b'00100 /* BASE + 4 */
|
193 | # SEL & REG_ADDR:'b'01000 /* BASE + 8 */
|
194 | # SEL & REG_ADDR:'b'01010 /* BASE + 10 */
|
195 | # SEL & REG_ADDR:'b'01110; /* BASE + 14 */
|
196 | RSRVD.LE = !SYNC;
|
197 |
|
198 | CS1.L = SEL & REG_ADDR:'b'01100; /* BASE + 12 */
|
199 | CS1.LE = !SYNC;
|
200 | DCS1 = CS1 & SYNC;
|
201 |
|
202 | CS0.L = SEL & REG_ADDR:'b'1XXX0; /* BASE + 16 */
|
203 | CS0.LE = !SYNC;
|
204 | DCS0 = CS0 & SYNC;
|
205 |
|
206 | [DA0..2].L = [DAB1..3]; /* save for disk register select */
|
207 | [DA0..2].LE = !SYNC;
|
208 |
|
209 | DISK_SEL = CS0 # CS1;
|
210 | ADPTR_SEL = CS_COM # CS_VECT # RSRVD;
|
211 | FAST_CYCLE = CS0 & [DA0..2]:'b'000; /* data register */
|
212 | DIOCS16 = FAST_CYCLE;
|
213 |
|
214 | /* I/O Control - QBUS read */
|
215 | IOR = DISK_SEL & DIN; /* disk controller read */
|
216 | DIOR = IOR; /* pin */
|
217 | QBR = (DISK_SEL # ADPTR_SEL) & DIN; /* enable QBUS drivers */
|
218 | QB_DREN = QBR # IAKI & INT_ARB_WON;
|
219 |
|
220 | /* Reply */
|
221 | /* Reply from DIN = 91ns for byte transfers */
|
222 | /* = 30ns for word transfers */
|
223 | append RPLY = DIN & ADPTR_SEL
|
224 | # DIN & !FAST_CYCLE & RPLYD3 & (IORDY_ENABLE & DIORDY # !IORDY_ENABLE)
|
225 | # DIN & FAST_CYCLE & RPLYD1 & (IORDY_ENABLE & DIORDY # !IORDY_ENABLE);
|
226 |
|
227 | /* I/O Control - QBUS write */
|
228 | IOW = DISK_SEL & DOUT & SYNC & !IOWD3; /* disk controller write */
|
229 | DIOW = IOW; /* pin */
|
230 | QBW = (DISK_SEL # ADPTR_SEL) & DOUT; /* connect bus A to bus B */
|
231 | QB_TSEN = QBW # !SYNC & !(IAKI & INT_ARB_WON); /* let the Qbus address pass thru */
|
232 |
|
233 | /* Reply */
|
234 | /* Reply from DOUT = 91ns for byte transfers */
|
235 | /* = 30ns for word transfers */
|
236 | append RPLY = DOUT & ADPTR_SEL
|
237 | # DOUT & IOWD1;
|
238 |
|
239 | RPLYD0.D = DISK_SEL & (DIN # DOUT); /* synchronizer */
|
240 | RPLYD1.D = RPLYD0; /* 31ns */
|
241 | RPLYD2.D = RPLYD0 & RPLYD1; /* 62ns */
|
242 | RPLYD3.D = RPLYD0 & RPLYD2; /* 94ns */
|
243 | [RPLYD0..3].CK = CLOCK32;
|
244 |
|
245 | IOWD0.D = DOUT /* synchonizer */
|
246 | & (!FAST_CYCLE & RPLYD3 # FAST_CYCLE & RPLYD1)
|
247 | & (IORDY_ENABLE & DIORDY # !IORDY_ENABLE);
|
248 | IOWD1.D = IOWD0; /* 31ns 63ns 125ns */
|
249 | IOWD2.D = IOWD0 & IOWD1; /* 63ns 94ns 156ns */
|
250 | IOWD3.D = IOWD0 & IOWD2; /* 94ns 125ns 188ns */
|
251 | [IOWD0..3].CK = CLOCK32; /* word byte */
|
252 |
|
253 | append DAB = 'b'0000000000000000;
|
254 |
|
255 | append DAB.OE = ADPTR_SEL & DIN & SYNC;
|
256 |
|
257 | /* QBus Interrupt Cycle - Modeled after DC003 logic */
|
258 | ATA_IRQ.D = TRUE;
|
259 | ATA_IRQ.CK = INT_ENABLE & DINTRQ; /* interrupt is triggered on leading edge of DINTRQ */
|
260 | ATA_IRQ.AR = IAKI & INT_ARB_WON; /* clear interrupt on acknowledge or reset */
|
261 | ATA_IRQ.AP = INIT;
|
262 |
|
263 | IRQ4O = DINTRQ & INT_ENABLE & ATA_IRQ; /* QBus signal to processor */
|
264 |
|
265 | INT_ARB_WON.D = DINTRQ & INT_ENABLE & ATA_IRQ & !IRQ5 & !IRQ6; /* perform arbitration */
|
266 | INT_ARB_WON.CK = DIN;
|
267 | INT_ARB_WON.AR = INIT;
|
268 |
|
269 | IAKO = IAKI & !INT_ARB_WON; /* pass on if not for us */
|
270 |
|
271 | append DAB_VECT = IAKI & INT_ARB_WON & VECTOR; /* place vector on TS bus */
|
272 | append DAB.OE = IAKI & INT_ARB_WON;
|
273 | append RPLY = IAKI & INT_ARB_WON; /* reply to acknowledge */
|
274 | /* does RPLY need to be lengthened? Qbus docs say 125ns from RPLY to vector clocked */
|
275 |
|
276 | /* CSR - Control and Status Register */
|
277 | /* read cycle */
|
278 | append DAB7 = QBR & CS_COM & DINTRQ; /* disk interrupt request line */
|
279 | append DAB6 = QBR & CS_COM & INT_ENABLE; /* interrupt enable */
|
280 | append DAB5 = QBR & CS_COM & IORDY_ENABLE; /* disk IORDY control enable */
|
281 | append DAB4 = QBR & CS_COM & ATA_IRQ; /* disk interrupt pending */
|
282 | append DAB0 = QBR & CS_COM; /* LSB always reads as 1 */
|
283 |
|
284 | /* write cycle */
|
285 | INT_ENABLE.D = DAB6;
|
286 | INT_ENABLE.CK = !(CS_COM & DOUT);
|
287 | INT_ENABLE.AR = INIT;
|
288 | IORDY_ENABLE.D = DAB5;
|
289 | IORDY_ENABLE.CK = !(CS_COM & DOUT);
|
290 | IORDY_ENABLE.AR = INIT;
|
291 |
|
292 | /* Vector Register */
|
293 | /* read cycle */
|
294 | append DAB_VECT = QBR & CS_VECT & VECTOR;
|
295 |
|
296 | /* write cycle */
|
297 | VECTOR.D = DAB_VECT;
|
298 | VECTOR.CK = !(CS_VECT & DOUT);
|
299 |
|
300 | /* Miscellaneous logic */
|
301 | SYNC_LITE = !SYNC;
|