blob: b40461408c53f4f8972e1c8a834ffd2bdf075858 [file] [log] [blame] [raw]
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001/* hp3000_mpx.c: HP 3000 30036B Multiplexer Channel simulator
2
3 Copyright (c) 2016, J. David Bryan
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
19 ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 Except as contained in this notice, the name of the author shall not be used
23 in advertising or otherwise to promote the sale, use or other dealings in
24 this Software without prior written authorization from the author.
25
26 MPX HP 3000 Series III Multiplexer Channel
27
Mark Pizzolatoe370b9e2016-09-20 20:34:22 -070028 12-Sep-16 JDB Changed DIB register macro usage from SRDATA to DIB_REG
29 15-Jul-16 JDB Fixed the word count display for DREADSTB trace
Mark Pizzolato07f99bb2016-07-05 22:09:21 -070030 08-Jun-16 JDB Corrected %d format to %u for unsigned values
31 07-Jun-16 JDB Corrected ACKSR assertion in State A for chained orders
32 16-May-16 JDB abort_channel parameter is now a pointer-to-constant
33 21-Mar-16 JDB Changed uint16 types to HP_WORD
Mark Pizzolato3a4e8792016-03-07 20:47:57 -080034 06-Oct-15 JDB First release version
35 11-Sep-14 JDB Passes the multiplexer channel diagnostic (D422A)
36 10-Feb-13 JDB Created
37
38 References:
39 - HP 3000 Series II/III System Reference Manual
40 (30000-90020, July 1978)
41 - HP 3000 Series III Reference/Training Manual
42 (30000-90143, February 1980)
43 - 30035A Multiplexer Channel Maintenance Manual
44 (30035-90001, September 1972)
45 - Stand-Alone HP 30036A/B Multiplexer Channel Diagnostic
46 (30036-90001, July 1978)
47 - HP 3000 Series III Engineering Diagrams Set
48 (30000-90141, Apr-1980)
49
50
51 The HP 30036B Multiplexer Channel provides high-speed data transfer between
52 from one to sixteen devices and main memory. Concurrent transfers for
53 multiple devices are multiplexed on a per-word basis, dependent on the
54 service request priorities assigned to the participating interfaces.
55 Interfaces must have additional hardware to be channel-capable, as the
56 channel uses separate control and data signals from those used for direct
57 I/O. In addition, the multiplexer and selector channels differ somewhat in
58 their use of the signals, so interfaces are generally designed for use with
59 one or the other (the Selector Channel Maintenance Board is a notable
60 exception that uses jumpers to indicate which channel to use).
61
62 The transfer rate of the Series III multiplexer channel is poorly documented.
63 Various rates are quoted in different publications: a uniform 990 KB/second
64 rate in one, a 1038 KB/second inbound rate and a 952 KB/second outbound rate
65 in another. Main memory access time is given as 300 nanoseconds, and the
66 cycle time is 700 nanoseconds. The multiplexer channel passes data to and
67 from main memory via the I/O Processor.
68
69 Once started by an SIO instruction, the channel executes I/O programs
70 independently of the CPU. Program words are read, and device status is
71 written back, by calls to the I/O Processor.
72
73 32-bit I/O program words are formed from a 16-bit I/O control word (IOCW) and
74 a 16-bit I/O address word (IOAW) in this general format:
75
76 0 | 1 2 3 | 4 5 6 | 7 8 9 |10 11 12 |13 14 15
77 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
78 | C | order | X | control word 1/word count | IOCW
79 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
80 | control word 2/status/address | IOAW
81 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
82
83 Most orders are fully decoded by bits 1-3, but a few use bit 4 to extend the
84 definition where bits 4-15 are not otherwise used. I/O programs always
85 reside in memory bank 0. The current I/O program pointer resides in word 0
86 of the Device Reference Table entry for the active interface.
87
88 The Jump and Jump Conditional orders use this format:
89
90 0 | 1 2 3 | 4 5 6 | 7 8 9 |10 11 12 |13 14 15
91 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
92 | - | 0 0 0 | C | - - - - - - - - - - - | IOCW
93 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
94 | jump target address | IOAW
95 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
96
97 ...where C is 0 for an unconditional jump and 1 for a conditional jump. An
98 unconditional jump is handled entirely within the channel. A conditional
99 jump asserts the SETJMP signal to the interface. If the interface returns
100 JMPMET, the jump will occur; otherwise, execution continues with the next
101 program word.
102
103 The Return Residue order uses this format:
104
105 0 | 1 2 3 | 4 5 6 | 7 8 9 |10 11 12 |13 14 15
106 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
107 | - | 0 0 1 0 | - - - - - - - - - - - | IOCW
108 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
109 | residue of word count | IOAW
110 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
111
112 The remaining word count from the last transfer will be returned in the IOAW
113 as a two's-complement value. If the transfer completed normally, the
114 returned value will be zero.
115
116 The Set Bank order uses this format:
117
118 0 | 1 2 3 | 4 5 6 | 7 8 9 |10 11 12 |13 14 15
119 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
120 | - | 0 0 1 1 | - - - - - - - - - - - | IOCW
121 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
122 | - - - - - - - - - - - - | bank | IOAW
123 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
124
125 This establishes the memory bank to be used for subsequent Write or Read
126 orders. Program addresses always use bank 0.
127
128 The Interrupt order uses this format:
129
130 0 | 1 2 3 | 4 5 6 | 7 8 9 |10 11 12 |13 14 15
131 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
132 | - | 0 1 0 | - - - - - - - - - - - - | IOCW
133 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
134 | - - - - - - - - - - - - - - - - | IOAW
135 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
136
137 The SETINT signal is asserted to the interface for this order.
138
139 The End and End with Interrupt orders use this format:
140
141 0 | 1 2 3 | 4 5 6 | 7 8 9 |10 11 12 |13 14 15
142 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
143 | - | 0 1 1 | I | - - - - - - - - - - - | IOCW
144 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
145 | device status | IOAW
146 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
147
148 ...where I is 0 for an End and 1 for an End with Interrupt. The PSTATSTB
149 signal is asserted to the interface to obtain the device status, which is
150 stored in the IOAW location. If the I bit is set, SETINT will also be
151 asserted,
152
153 The Control order uses this format:
154
155 0 | 1 2 3 | 4 5 6 | 7 8 9 |10 11 12 |13 14 15
156 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
157 | - | 1 0 0 | control word 1 | IOCW
158 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
159 | control word 2 | IOAW
160 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
161
162 Both control words are sent to the interface. The full IOCW containing
163 control word 1 is sent with the PCMD1 signal asserted. It is followed by the
164 IOAW with PCONTSTB asserted.
165
166 The Sense order uses this format:
167
168 0 | 1 2 3 | 4 5 6 | 7 8 9 |10 11 12 |13 14 15
169 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
170 | - | 1 0 1 | - - - - - - - - - - - - | IOCW
171 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
172 | device status | IOAW
173 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
174
175 The PSTATSTB signal is asserted to the interface to obtain the device status,
176 which is stored in the IOAW location.
177
178 The Write and Read orders use these formats:
179
180 0 | 1 2 3 | 4 5 6 | 7 8 9 |10 11 12 |13 14 15
181 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
182 | C | 1 1 0 | negative word count to write | IOCW
183 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
184 | C | 1 1 1 | negative word count to read | IOCW
185 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
186 | transfer address | IOAW
187 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
188
189 The C bit is the "data chain" flag. If it is set, then this transfer is a
190 continuation of a previous Write or Read transfer. This is used to
191 circumvent the transfer size limitation inherent in the 12-bit word count
192 allocated in the IOCW. For single transfers larger than 4K words, multiple
193 contiguous Write or Read orders are used, with all but the last order having
194 their data chain bits set.
195
196 In simulation, IOCW bits 1-4 are used to index into a 16-element lookup table
197 to produce the final I/O order (because some of the orders define IOCW bit 4
198 as "don't care", there are only thirteen distinct orders).
199
200 Channel-capable interfaces connect via the multiplexer channel bus and
201 request channel service by asserting one of the sixteen Service Request
202 signals (SR0 through SR15). Jumpers on the interface establish which SR
203 number to use. When multiple devices request service simultaneously, the
204 channel grants access to the lowest-numbered request.
205
206 In simulation, an interface is connected to the channel by setting the
207 "service_request" field in the DIB to a value between 0 and 15, representing
208 the SR number signal to assert. If the field is set to the SRNO_UNUSED
209 value, then it is not connected to the channel.
210
211
212 The channel contains a diagnostic interface that provides the capability to
213 check the operation independently of channel program execution. The
214 interface responds to direct I/O instructions, as follows:
215
216 Control Word Format (CIO):
217
218 0 | 1 2 3 | 4 5 6 | 7 8 9 |10 11 12 |13 14 15
219 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
220 | M | - | RAM address | A | O | S | L | I | - - - - - |
221 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
222
223 Where:
224
225 M = master reset
226 A = select the Address RAM and Register
227 O = select the Order RAM and Register
228 S = select the State RAM and Register
229 L = load the registers from the RAMs during the next read
230 I = increment the Address or Word Count Registers after the next read
231
232 The control word establishes the address and enable(s) to read or write from
233 a given RAM location. The RAM address is stored in the control word register
234 and is used in lieu of the service request encoding whenever an I/O order
235 references the multiplexer device number, effectively providing a
236 programmable service request number. The A/O/S/L/I bits enable the
237 corresponding actions for the next WIO or RIO instruction.
238
239
240 Status Word Format (TIO):
241
242 0 | 1 2 3 | 4 5 6 | 7 8 9 |10 11 12 |13 14 15
243 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
244 | S | D | - | E | RAM address | - - - - - - - - |
245 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
246
247 Key:
248
249 S = SIO OK (always 0)
250 D = direct read/write I/O OK (always 1)
251 E = a state parity error exists
252
253 A state parity error occurs when the state register contains a value other
254 than one of the four defined states. An error causes the RAM address and E
255 bit to be stored in the error register, which is then gated to form the
256 status return value. The error register is cleared by an IORESET or master
257 reset.
258
259
260 Write Word Format (WIO):
261
262 0 | 1 2 3 | 4 5 6 | 7 8 9 |10 11 12 |13 14 15
263 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
264 | address | Address RAM
265 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
266 | order | word count | Order RAM
267 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
268 | - - | A | B | C | D | - - - - - - | bank number | State RAM
269 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
270
271 Where:
272
273 A = set the state to State A
274 B = set the state to State B
275 C = set the state to State C
276 D = set the state to State D
277
278 The address, order, or state RAM value is written to the specified register
279 and RAM address set by the last control word. If multiple registers/RAMs
280 were selected, then the value is written to all of them.
281
282 Setting more than one state bit at a time will generate a state parity error.
283
284
285 Read Word Format (RIO):
286
287 0 | 1 2 3 | 4 5 6 | 7 8 9 |10 11 12 |13 14 15
288 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
289 | address | Address RAM
290 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
291 | order | word count | Order RAM
292 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
293 | - - - - | bank number | T | A | B | C | D | E | P | S | State RAM
294 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
295
296 Where:
297
298 T = the transfer complete flip-flop value
299 A = the state is State A
300 B = the state is State B
301 C = the state is State C
302 D = the state is State D
303 E = the end-of-transfer flip-flop value
304 P = address parity (odd parity for the address register)
305 S = a state parity error exists
306
307 The diagnostic tests address parity and state parity. State parity also
308 asserts the XFERERROR signal, which aborts a transfer in progress.
309
310
311 Implementation notes:
312
313 1. The multiplexer channel must execute more than one I/O order per CPU
314 instruction in order to meet the timing requirements of the diagnostic.
315 The timing is modeled by establishing a count of channel clock pulses at
316 poll entry and then executing orders until the count is exhausted. If
317 the clock count was exceeded, the excess count is saved and then
318 subtracted from the next entry's count, so that the typical execution
319 time is preserved over a number of entries.
320*/
321
322
323
324#include "hp3000_defs.h"
325#include "hp3000_cpu.h"
326#include "hp3000_cpu_ims.h"
327#include "hp3000_io.h"
328
329
330
331/* Program constants.
332
333 The multiplexer channel clock period is 175 nanoseconds. The channel runs
334 concurrently with the CPU, which executes instructions in an average of
335 2.57 microseconds, so multiple cycles are executed per CPU instruction.
336
337 In simulation, the channel is called from the instruction execution loop
338 after every instruction, and sometimes additionally within instructions that
339 have long execution times (e.g., MOVE). The number of event ticks that have
340 elapsed since the last call are passed to the channel; this determines the
341 number of channel cycles to execute.
342
343
344 Implementation notes:
345
346 1. The number of cycles consumed by the channel for various operations are
347 educated guesses. There is no documentation available that details the
348 cycle timing.
349
350 2. The MPX_STATE values match the values supplied in bits 2-5 of the "write
351 state RAM" command.
352
353 3. State "parity" is 1 for an illegal state and 0 for a valid state.
354
355*/
356
357#define INTRF_COUNT (SRNO_MAX + 1) /* count of interfaces handled by the multiplexer channel */
358
359#define NS_PER_CYCLE 175 /* each clock cycle is 175 nanoseconds */
360
361#define CYCLES_PER_STATE 2
362#define CYCLES_PER_READ 9
363#define CYCLES_PER_WRITE 9
364
365#define CYCLES_PER_EVENT (int32) (USEC_PER_EVENT * 1000 / NS_PER_CYCLE)
366
367
368typedef enum { /* multiplexer channel sequencer states */
369 State_Idle = 000,
370 State_D = 001,
371 State_C = 002,
372 State_B = 004,
373 State_A = 010
374 } MPX_STATE;
375
376static const char *const state_name [16] = { /* indexed by MPX_STATE */
377 "Idle State",
378 "State D",
379 "State C",
380 "invalid state 0011",
381 "State B",
382 "invalid state 0101",
383 "invalid state 0110",
384 "invalid state 0111",
385 "State A",
386 "invalid state 1001",
387 "invalid state 1010",
388 "invalid state 1011",
389 "invalid state 1100",
390 "invalid state 1101",
391 "invalid state 1110",
392 "invalid state 1111"
393 };
394
395static const uint8 state_parity [16] = { /* State RAM parity */
396 1, 0, 0, 1, /* 0000, 0001, 0010, 0011 */
397 0, 1, 1, 1, /* 0100, 0101, 0110, 0111 */
398 0, 1, 1, 1, /* 1000, 1001, 1010, 1011 */
399 1, 1, 1, 1 /* 1100, 1101, 1110, 1111 */
400 };
401
402
403/* Debug flags */
404
Mark Pizzolato07f99bb2016-07-05 22:09:21 -0700405#define DEB_CSRW (1u << 0) /* trace diagnostic and channel command initiations and completions */
406#define DEB_PIO (1u << 1) /* trace programmed I/O commands */
407#define DEB_IOB (1u << 2) /* trace I/O bus signals and data words */
408#define DEB_STATE (1u << 3) /* trace state changes */
409#define DEB_SR (1u << 4) /* trace service requests */
Mark Pizzolato3a4e8792016-03-07 20:47:57 -0800410
411
412/* Control word.
413
414 0 | 1 2 3 | 4 5 6 | 7 8 9 |10 11 12 |13 14 15
415 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
416 | M | - | RAM address | A | O | S | L | I | - - - - - |
417 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
418*/
419
Mark Pizzolato07f99bb2016-07-05 22:09:21 -0700420#define CN_MR 0100000u /* (M) master reset */
421#define CN_RAM_ADDR_MASK 0036000u /* RAM address mask */
422#define CN_ADDR_RAM 0001000u /* (A) select the address RAM and register */
423#define CN_ORDER_RAM 0000400u /* (O) select the order RAM and register */
424#define CN_STATE_RAM 0000200u /* (S) select the state RAM and register */
425#define CN_LOAD_REGS 0000100u /* (L) load registers from RAM */
426#define CN_INCR_REGS 0000040u /* (I) increment registers */
Mark Pizzolato3a4e8792016-03-07 20:47:57 -0800427
428#define CN_RAM_ADDR_SHIFT 10 /* RAM address alignment shift */
429
430#define CN_RAM_ADDR(c) (((c) & CN_RAM_ADDR_MASK) >> CN_RAM_ADDR_SHIFT)
431
432static const BITSET_NAME control_names [] = { /* Control word names */
433 "master reset", /* bit 0 */
434 NULL, /* bit 1 */
435 NULL, /* bit 2 */
436 NULL, /* bit 3 */
437 NULL, /* bit 4 */
438 NULL, /* bit 5 */
439 "address RAM", /* bit 6 */
440 "order RAM", /* bit 7 */
441 "state RAM", /* bit 9 */
442 "load registers", /* bit 9 */
443 "increment registers" /* bit 10 */
444 };
445
446static const BITSET_FORMAT control_format = /* names, offset, direction, alternates, bar */
447 { FMT_INIT (control_names, 5, msb_first, no_alt, append_bar) };
448
449
450/* Status word.
451
452 0 | 1 2 3 | 4 5 6 | 7 8 9 |10 11 12 |13 14 15
453 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
454 | - | D | - | E | RAM address | - - - - - - - - |
455 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
456*/
457
Mark Pizzolato07f99bb2016-07-05 22:09:21 -0700458#define ST_DIO_OK 0040000u /* (D) direct I/O OK (always set) */
459#define ST_STATE_PARITY 0010000u /* (E) a state error exists */
460#define ST_RAM_ADDR_MASK 0007400u /* RAM address mask */
Mark Pizzolato3a4e8792016-03-07 20:47:57 -0800461
462#define ST_RAM_ADDR_SHIFT 8 /* RAM address alignment shift */
463
464#define ST_RAM_ADDR(c) ((c) << ST_RAM_ADDR_SHIFT & ST_RAM_ADDR_MASK)
465
466#define ST_TO_RAM_ADDR(s) (((s) & ST_RAM_ADDR_MASK) >> ST_RAM_ADDR_SHIFT)
467
468static const BITSET_NAME status_names [] = { /* Status word names */
469 "DIO OK", /* bit 1 */
470 NULL, /* bit 2 */
471 "state error" /* bit 3 */
472 };
473
474static const BITSET_FORMAT status_format = /* names, offset, direction, alternates, bar */
475 { FMT_INIT (status_names, 12, msb_first, no_alt, append_bar) };
476
477
478/* Write word.
479
480 0 | 1 2 3 | 4 5 6 | 7 8 9 |10 11 12 |13 14 15
481 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
482 | address | Address RAM
483 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
484 | order | word count | Order RAM
485 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
486 | - - | A | B | C | D | - - - - - - | bank number | State RAM
487 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
488*/
489
Mark Pizzolato07f99bb2016-07-05 22:09:21 -0700490#define WR_ORDER_MASK 0170000u /* order mask */
491#define WR_COUNT_MASK 0007777u /* word count mask */
492#define WR_STATE_MASK 0036000u /* state mask */
493#define WR_BANK_MASK 0000017u /* bank number mask */
Mark Pizzolato3a4e8792016-03-07 20:47:57 -0800494
495#define WR_ORDER_SHIFT 12 /* order alignment shift */
496#define WR_COUNT_SHIFT 0 /* word count alignment shift */
497#define WR_STATE_SHIFT 10 /* state alignment shift */
498#define WR_BANK_SHIFT 0 /* bank number alignment shift */
499
500#define WR_ORDER(c) (((c) & WR_ORDER_MASK) >> WR_ORDER_SHIFT)
501#define WR_COUNT(c) (((c) & WR_COUNT_MASK) >> WR_COUNT_SHIFT)
502#define WR_STATE(c) (((c) & WR_STATE_MASK) >> WR_STATE_SHIFT)
503#define WR_BANK(c) (((c) & WR_BANK_MASK) >> WR_BANK_SHIFT)
504
505
506/* Read word.
507
508 0 | 1 2 3 | 4 5 6 | 7 8 9 |10 11 12 |13 14 15
509 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
510 | address | Address RAM
511 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
512 | order | word count | Order RAM
513 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
514 | - - - - | bank number | T | A | B | C | D | E | P | S | State RAM
515 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
516*/
517
Mark Pizzolato07f99bb2016-07-05 22:09:21 -0700518#define RD_ADDR_MASK 0177777u /* address mask */
519#define RD_ORDER_MASK 0170000u /* order mask */
520#define RD_COUNT_MASK 0007777u /* word count mask */
521#define RD_BANK_MASK 0007400u /* bank number mask */
522#define RD_XFER_COMPLETE 0000200u /* (T) transfer complete */
523#define RD_STATE_MASK 0000170u /* (A/B/C/D) state mask */
524#define RD_XFER_END 0000004u /* (E) end of transfer */
525#define RD_ADDR_PARITY 0000002u /* (P) address parity */
526#define RD_STATE_PARITY 0000001u /* (S) state parity */
Mark Pizzolato3a4e8792016-03-07 20:47:57 -0800527
528#define RD_ORDER_SHIFT 12 /* order alignment shift */
529#define RD_COUNT_SHIFT 0 /* word count alignment shift */
530#define RD_BANK_SHIFT 8 /* bank number alignment shift */
531#define RD_STATE_SHIFT 3 /* state alignment shift */
532
533#define RD_ORDER(c) ((c) << RD_ORDER_SHIFT & RD_ORDER_MASK)
534#define RD_COUNT(c) ((c) << RD_COUNT_SHIFT & RD_COUNT_MASK)
535#define RD_BANK(c) ((c) << RD_BANK_SHIFT & RD_BANK_MASK)
536#define RD_STATE(c) ((c) << RD_STATE_SHIFT & RD_STATE_MASK)
537
538#define RD_SIO_ORDER(o,c) IOCW_ORDER ((o) << RD_ORDER_SHIFT | (c) & RD_COUNT_MASK)
539
540static const BITSET_NAME read_names [] = { /* Read word names */
541 "terminal count", /* bit 8 */
542 "A", /* bit 9 */
543 "B", /* bit 10 */
544 "C", /* bit 11 */
545 "D", /* bit 12 */
546 "end of transfer", /* bit 13 */
547 "address parity", /* bit 14 */
548 "state parity" /* bit 15 */
549 };
550
551static const BITSET_FORMAT read_format = /* names, offset, direction, alternates, bar */
552 { FMT_INIT (read_names, 0, msb_first, no_alt, append_bar) };
553
554
555/* Channel RAMs.
556
557 In hardware, control information for a transfer-in-progress is stored in one
558 of sixteen RAM locations, corresponding the to assigned service request
559 number. The RAM is 42 bits wide, partitioned as follows:
560
561 - a 4-bit state RAM
562 - a 6-bit auxiliary RAM
563 - a 16-bit address RAM
564 - a 16-bit order RAM
565
566 In simulation, the 16-bit order RAM is split into a 5-bit order RAM and a
567 12-bit counter RAM. The order RAM stores the Data Chain bit and the four-bit
568 translated SIO order, rather than the DC and three-bit basic channel order.
569 This allows direct interpretation of the I/O order, rather than sometimes
570 depending on the leading bit of the counter RAM.
571
572 Values within the RAMs are formatted as follows:
573
574 0 1 | 2 3 4 | 5 6 7
575 +---+---+---+---+---+---+---+---+
576 | - - - - | state | State RAM
577 +---+---+---+---+---+---+---+---+
578 | - - | B | T | bank | Auxiliary RAM
579 +---+---+---+---+---+---+---+---+
580 | - - - | C | order | Order RAM
581 +---+---+---+---+---+---+---+---+
582
583 Where:
584
585 B = the transfer is within a block
586 T = the terminal word count has been reached
587 C = the I/O order specifies data chaining
588
589 0 | 1 2 3 | 4 5 6 | 7 8 9 |10 11 12 |13 14 15
590 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
591 | - - - - | word count | Counter RAM
592 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
593 | address | Address RAM
594 +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+
595*/
596
Mark Pizzolato07f99bb2016-07-05 22:09:21 -0700597#define AUX_IB 040u /* auxiliary RAM in-block flag */
598#define AUX_TC 020u /* auxiliary RAM terminal count flag */
599#define AUX_BANK_MASK 017u /* auxiliary RAM bank mask */
Mark Pizzolato3a4e8792016-03-07 20:47:57 -0800600
601#define AUX_BANK(r) ((r) & AUX_BANK_MASK)
602
Mark Pizzolato07f99bb2016-07-05 22:09:21 -0700603#define ORDER_DC 020u /* order RAM data chain flag */
604#define ORDER_MASK 017u /* order RAM current order mask */
Mark Pizzolato3a4e8792016-03-07 20:47:57 -0800605
Mark Pizzolato07f99bb2016-07-05 22:09:21 -0700606#define CNTR_MASK 0007777u /* counter RAM word count mask */
607#define CNTR_MAX 0007777u /* counter RAM word count maximum value */
Mark Pizzolato3a4e8792016-03-07 20:47:57 -0800608
609static const BITSET_NAME aux_names [] = { /* Auxiliary RAM word */
610 "in block", /* bit 2 */
611 "terminal count" /* bit 3 */
612 };
613
614static const BITSET_FORMAT aux_format = /* names, offset, direction, alternates, bar */
615 { FMT_INIT (aux_names, 4, msb_first, no_alt, append_bar) };
616
617
618/* Channel global state */
619
620t_bool mpx_is_idle = TRUE; /* TRUE if the multiplexer channel is idle */
621uint32 mpx_request_set = 0; /* set of service request bits */
622
623
624/* Channel local state */
625
626static DIB *srs [INTRF_COUNT]; /* indexed by service request number for channel requests */
627static uint32 active_count = 0; /* count of active transfers */
628static int32 excess_cycles = 0; /* count of cycles in excess of allocation */
629
630static HP_WORD control_word = 0; /* diagnostic control word */
631static HP_WORD status_word = 0; /* diagnostic status word */
632static FLIP_FLOP rollover = CLEAR; /* SET if the transfer word count rolls over */
633static FLIP_FLOP device_end = CLEAR; /* SET if DEVEND is asserted by the device */
634
635
636/* Channel per-interface state.
637
638 The per-interface state for a transfer-in-progress is stored in the RAM
639 location corresponding to the interface's assigned service request number.
640 The RAM values are loaded into registers at the start of a channel I/O cycle
641 and stored back into the RAM at the end of the cycle.
642
643
644 Implementation notes:
645
646 1. SCP requires that arrayed register elements be sized to match their width
647 in bits. We want to display multiplexer state RAM entries as four-bit
648 values, so state_ram must have 8-bit elements. However, because the
649 MPX_STATE enum size is implementation-dependent, state_ram cannot be of
650 type MPX_STATE.
651*/
652
653static uint8 state_ram [INTRF_COUNT]; /* state RAM */
654static uint8 aux_ram [INTRF_COUNT]; /* auxiliary RAM */
655static uint8 order_ram [INTRF_COUNT]; /* I/O order RAM */
656static HP_WORD cntr_ram [INTRF_COUNT]; /* counter RAM */
657static HP_WORD addr_ram [INTRF_COUNT]; /* I/O address RAM */
658
659static uint8 state_reg; /* state register */
660static uint8 aux_reg; /* auxiliary register */
661static uint8 order_reg; /* order register */
662static HP_WORD cntr_reg; /* word counter register */
663static HP_WORD addr_reg; /* address register */
664
665
666/* Channel local SCP support routines */
667
668static CNTLR_INTRF mpx_interface;
669static t_stat mpx_reset (DEVICE *dptr);
670
671
672/* Channel local utility routines */
673
674static uint8 next_state (uint8 current_state, SIO_ORDER order, t_bool abort);
675static void end_channel (DIB *dibptr);
Mark Pizzolato07f99bb2016-07-05 22:09:21 -0700676static SIGNALS_DATA abort_channel (DIB *dibptr, const char *reason);
Mark Pizzolato3a4e8792016-03-07 20:47:57 -0800677
678
679/* Channel SCP data structures */
680
681
682/* Device information block */
683
684static DIB mpx_dib = {
685 &mpx_interface, /* device interface */
686 127, /* device number */
687 SRNO_UNUSED, /* service request number */
688 INTPRI_UNUSED, /* interrupt priority */
689 INTMASK_UNUSED /* interrupt mask */
690 };
691
Mark Pizzolato07f99bb2016-07-05 22:09:21 -0700692
Mark Pizzolato3a4e8792016-03-07 20:47:57 -0800693/* Unit list */
694
695static UNIT mpx_unit [] = { /* a dummy unit to satisfy SCP requirements */
696 { UDATA (NULL, 0, 0) }
697 };
Mark Pizzolato07f99bb2016-07-05 22:09:21 -0700698
Mark Pizzolato3a4e8792016-03-07 20:47:57 -0800699
700/* Register list.
701
702
703 Implementation notes:
704
705 1. The "mpx_request_set" and "srs" variables need not be SAVEd or RESTOREd,
706 as they are rebuilt during the instruction execution prelude.
707
708 2. The state RAM register array cannot be named "STATE", because SCP uses
709 "STATE" to display all of the registers, and it checks the keyword before
710 checking for a register of the same name.
711*/
712
713static REG mpx_reg [] = {
Mark Pizzolato07f99bb2016-07-05 22:09:21 -0700714/* Macro Name Location Radix Width Depth Flags */
715/* ------ ------ ------------- ----- ----- ----------- ----------------- */
716 { FLDATA (IDLE, mpx_is_idle, 0) },
717 { DRDATA (COUNT, active_count, 32), PV_LEFT },
718 { DRDATA (EXCESS, excess_cycles, 32), PV_LEFT },
Mark Pizzolato3a4e8792016-03-07 20:47:57 -0800719
Mark Pizzolato07f99bb2016-07-05 22:09:21 -0700720 { ORDATA (CNTL, control_word, 16), REG_FIT },
721 { ORDATA (STAT, status_word, 16), REG_FIT },
722 { FLDATA (ROLOVR, rollover, 0) },
723 { FLDATA (DEVEND, device_end, 0) },
Mark Pizzolato3a4e8792016-03-07 20:47:57 -0800724
Mark Pizzolato07f99bb2016-07-05 22:09:21 -0700725 { BRDATA (STATR, state_ram, 2, 4, INTRF_COUNT) },
726 { BRDATA (AUX, aux_ram, 8, 6, INTRF_COUNT) },
727 { BRDATA (ORDER, order_ram, 8, 4, INTRF_COUNT) },
728 { BRDATA (CNTR, cntr_ram, 8, 12, INTRF_COUNT) },
729 { BRDATA (ADDR, addr_ram, 8, 16, INTRF_COUNT) },
Mark Pizzolato3a4e8792016-03-07 20:47:57 -0800730
Mark Pizzolato07f99bb2016-07-05 22:09:21 -0700731 { ORDATA (STAREG, state_reg, 8), REG_FIT | REG_HRO },
732 { ORDATA (AUXREG, aux_reg, 8), REG_FIT | REG_HRO },
733 { ORDATA (ORDREG, order_reg, 8), REG_FIT | REG_HRO },
734 { ORDATA (CTRREG, cntr_reg, 16), REG_FIT | REG_HRO },
735 { ORDATA (ADRREG, addr_reg, 16), REG_FIT | REG_HRO },
Mark Pizzolato3a4e8792016-03-07 20:47:57 -0800736
Mark Pizzolatoe370b9e2016-09-20 20:34:22 -0700737 DIB_REGS (mpx_dib),
Mark Pizzolato3a4e8792016-03-07 20:47:57 -0800738
739 { NULL }
740 };
Mark Pizzolato07f99bb2016-07-05 22:09:21 -0700741
Mark Pizzolato3a4e8792016-03-07 20:47:57 -0800742
743/* Modifier list */
744
745static MTAB mpx_mod [] = {
746/* Entry Flags Value Print String Match String Validation Display Descriptor */
747/* ----------- --------- ------------ ------------ ----------- ------------ ----------------- */
748 { MTAB_XDV, VAL_DEVNO, "DEVNO", "DEVNO", &hp_set_dib, &hp_show_dib, (void *) &mpx_dib },
749 { 0 }
750 };
Mark Pizzolato07f99bb2016-07-05 22:09:21 -0700751
Mark Pizzolato3a4e8792016-03-07 20:47:57 -0800752
753/* Debugging trace list */
754
755static DEBTAB mpx_deb [] = {
756 { "CSRW", DEB_CSRW }, /* channel control, status, read, and write actions */
757 { "PIO", DEB_PIO }, /* programmed I/O commands executed */
758 { "STATE", DEB_STATE }, /* channel state changes executed */
759 { "SR", DEB_SR }, /* service requests received */
760 { "IOBUS", DEB_IOB }, /* interface I/O bus signals and data words */
761 { NULL, 0 }
762 };
Mark Pizzolato07f99bb2016-07-05 22:09:21 -0700763
Mark Pizzolato3a4e8792016-03-07 20:47:57 -0800764
765/* Device descriptor */
766
767DEVICE mpx_dev = {
768 "MPX", /* device name */
769 mpx_unit, /* unit array */
770 mpx_reg, /* register array */
771 mpx_mod, /* modifier array */
772 1, /* number of units */
773 8, /* address radix */
774 PA_WIDTH, /* address width */
775 1, /* address increment */
776 8, /* data radix */
777 DV_WIDTH, /* data width */
778 NULL, /* examine routine */
779 NULL, /* deposit routine */
780 &mpx_reset, /* reset routine */
781 NULL, /* boot routine */
782 NULL, /* attach routine */
783 NULL, /* detach routine */
784 &mpx_dib, /* device information block pointer */
785 DEV_DEBUG, /* device flags */
786 0, /* debug control flags */
787 mpx_deb, /* debug flag name array */
788 NULL, /* memory size change routine */
789 NULL /* logical device name */
790 };
791
792
793
794/* Channel global routines */
795
796
797
798/* Initialize the channel.
799
800 This routine is called in the CPU instruction execution prelude to allow the
801 service request numbers of interfaces to be reassigned. It sets up the "srs"
802 DIB pointer array and the "mpx_request_set" bit vector from the service
803 request values in the device DIBs.
804
805 The "srs" dispatch table is used to send signals to the interfaces that
806 request service by asserting their SR numbers. The request set contains the
807 set of interfaces currently requesting channel service.
808*/
809
810void mpx_initialize (void)
811{
812uint32 idx;
813DIB *dibptr;
814const DEVICE *dptr;
815
816mpx_request_set = 0; /* set all requests inactive */
817
818memset (srs, 0, sizeof srs); /* clear the service requests table */
819
820for (idx = 0; sim_devices [idx] != NULL; idx++) { /* loop through the device table */
821 dptr = sim_devices [idx]; /* get the device pointer */
822 dibptr = (DIB *) dptr->ctxt; /* and the associated DIB pointer */
823
824 if (dibptr /* if an interface handler exists */
825 && !(dptr->flags & DEV_DIS) /* and the device is enabled */
826 && dibptr->service_request_number != SRNO_UNUSED) { /* and it is connected to the multiplexer channel */
827 srs [dibptr->service_request_number] = dibptr; /* then set the DIB pointer into the dispatch table */
828
829 if (dibptr->service_request) /* if the controller has asserted its service request line */
830 mpx_request_set |= /* then set the associated request bit */
831 1u << dibptr->service_request_number;
832 }
833 }
834
835return;
836}
837
838
839/* Start an I/O program.
840
841 This routine is called by a device interface in response to a Start I/O (SIO)
842 instruction to request that the multiplexer channel begin an I/O program. It
843 corresponds in hardware to asserting the REQ signal.
844
845 On entry, the service request number from the device's DIB is used as the RAM
846 index. The state RAM entry corresponding to the SR number is set to State C,
847 and the other RAM entries are cleared. The count of active I/O programs is
848 incremented.
849
850
851 Implementation notes:
852
853 1. Setting "excess_cycles" to the negative number of cycles per event
854 effectively doubles the available state execution time of the first
855 multiplexer poll. This is necessary to pass the Stand-Alone HP 30115A
856 (7970B/E) Magnetic Tape Diagnostic (D433) steps 252, 255, 260, and 263,
857 which check for command rejects. The diagnostic does an SIO / BNE / TIO
858 sequence and expects reject status to be set. However, the two available
859 multiplexer state execution opportunities (between the instructions) are
860 insufficient to execute the C, A, and B states that are necessary for the
861 tape controller to reject the command. We therefore lengthen the first
862 opportunity, so that all three states are completed before the TIO
863 instruction checks for command reject.
864*/
865
866void mpx_assert_REQ (DIB *dibptr)
867{
868const uint32 srn = dibptr->service_request_number; /* get the SR number for the RAM index */
869
Mark Pizzolato07f99bb2016-07-05 22:09:21 -0700870dprintf (mpx_dev, DEB_CSRW, "Device number %u asserted REQ for channel initialization\n",
Mark Pizzolato3a4e8792016-03-07 20:47:57 -0800871 dibptr->device_number);
872
873state_ram [srn] = State_C; /* set up the initial sequencer state */
874aux_ram [srn] = 0; /* clear */
875order_ram [srn] = sioEND; /* the rest */
876cntr_ram [srn] = 0; /* of the RAM */
877addr_ram [srn] = 0; /* entries */
878
879excess_cycles = - CYCLES_PER_EVENT; /* preset the excess cycle count */
880
881mpx_is_idle = FALSE; /* indicate that the channel is busy */
882active_count = active_count + 1; /* bump reference counter */
883
884return;
885}
886
887
888/* Request channel service.
889
890 This routine is called by a device interface to request service from the
891 channel. It is called either directly by the interface or indirectly by the
892 IOP in response to an SRn signal returned by the interface. A direct call is
893 needed for asynchronous assertion, e.g., in response to an event service
894 call. Synchronous assertion, i.e., in response to an interface call, is made
895 by returning the SRn signal to the IOP. The routine corresponds in hardware
896 to asserting the SRn signal associated with the interface to the multiplexer.
897
898 On entry, the service_request field in the device's DIB is set to TRUE, and
899 the request set bit corresponding the service_request_number field in the DIB
900 is set. This enables the channel to service the interface on the next
901 multiplexer poll call, assuming that the interface has priority.
902*/
903
904void mpx_assert_SRn (DIB *dibptr)
905{
906if (dibptr->service_request == FALSE)
Mark Pizzolato07f99bb2016-07-05 22:09:21 -0700907 dprintf (mpx_dev, DEB_SR, "Device number %u asserted SR%u\n",
Mark Pizzolato3a4e8792016-03-07 20:47:57 -0800908 dibptr->device_number, dibptr->service_request_number);
909
910dibptr->service_request = TRUE; /* set the service request flag */
911mpx_request_set |= 1 << dibptr->service_request_number; /* and the associated request bit */
912
913return;
914}
915
916
917/* Poll the interfaces on the multiplexer channel bus for service requests.
918
919 This routine is called in the CPU instruction execution loop to service a
920 request from the highest-priority device interface. It corresponds in
921 hardware to asserting HSREQ to the IOP, receiving the DATAPOLL IN signal from
922 the IOP, and then denying DATAPOLL OUT to the next multiplexer channel in the
923 chain. It executes one or more channel cycles for the associated device
924 interface and resets the service request flag in the DIB.
925
926 The multiplexer channel clock period is 175 nanoseconds. The channel runs
927 concurrently with the CPU, which executes instructions in an average of
928 2.57 microseconds, so multiple cycles are executed per CPU instruction.
929
930 This routine is called after every instruction, and sometimes additionally
931 within instructions that have long execution times (e.g., MOVE). The number
932 of event ticks that have elapsed since the last call are passed in; this
933 determines the number of channel cycles available to execute.
934
935 In hardware, the multiplexer priority-encodes the 16 service request lines,
936 selecting the highest-priority request for servicing. In simulation, a
937 service request sets the request set bit corresponding to the SR number.
938 When a poll is performed, the device corresponding to the highest-priority
939 (lowest-order) bit will be the recipient of the current multiplexer channel
940 cycles.
941
942 On entry, the routine determines the highest-priority interface that is
943 requesting service and then executes the next state in the transfer for that
944 interface, based on the values in the RAM. The number of multiplexer clock
945 counts consumed for the specified state execution is subtracted from the
946 number of clock counts available. If more time remains, and one or more
947 service requests are still active, another channel cycle is run for
948 the (possibly different) interface.
949
950 The multiplexer obtains the current state from the State RAM entry
951 corresponding to the service request number. If the current state is
952 invalid, i.e., not one of the four defined states, the channel aborts the
953 transfer by asserting XFERERROR to the interface. Otherwise, control
954 branches to one of the four state handlers before returning.
955
956 A transfer can be in one of four defined states:
957
958 - State A: fetch the first word (IOCW) of the I/O program word
959 - State B: fetch or store the second word (IOAW) of the I/O program word
960 - State C: fetch or store the I/O program pointer (IOPP)
961 - State D: transfer data to or from the interface
962
963 All I/O orders except Set Bank, Read, and Write execute states C, A, and B,
964 in that order. The Set Bank order executes state C, A, and D. The Read and
965 Write orders execute states C, A, B, and then one D state for each word
Mark Pizzolato07f99bb2016-07-05 22:09:21 -0700966 transferred. Some actions are dependent on external signals (JMPMET or
967 DEVEND) or internal conditions (terminal count reached [TC] or in a chained
968 block transfer [IB]).
969
Mark Pizzolato3a4e8792016-03-07 20:47:57 -0800970 The actions for the orders are:
971
972 Jump (sioJUMP)
973
974 State Condition Action Signals
975 ----- --------------- ---------- ------------------------------------------
976 C IOPP read DEVNODB
977 A IOCW read --
978 B IOAW read --
979 C IOPP write DEVNODB
980
981
Mark Pizzolato07f99bb2016-07-05 22:09:21 -0700982 Conditional Jump (sioJUMPC)
Mark Pizzolato3a4e8792016-03-07 20:47:57 -0800983
984 State Condition Action Signals
985 ----- --------------- ---------- ------------------------------------------
986 C IOPP read DEVNODB
987 A IOCW read --
988 B IOAW read SETJMP
989 / C ~ JMPMET IOPP read DEVNODB
990 \ C JMPMET IOPP write DEVNODB
991
992
993 Return Residue (sioRTRES)
994
995 State Condition Action Signals
996 ----- --------------- ---------- ------------------------------------------
997 C IOPP read DEVNODB
998 A IOCW read --
999 B IOAW write --
1000 C IOPP read DEVNODB
1001
1002
1003 Set Bank (sioSBANK)
1004
1005 State Condition Action Signals
1006 ----- --------------- ---------- ------------------------------------------
1007 C IOPP read DEVNODB
1008 A IOCW read --
1009 D IOAW read --
1010 C IOPP read DEVNODB
1011
1012
1013 Interrupt (sioINTRP)
1014
1015 State Condition Action Signals
1016 ----- --------------- ---------- ------------------------------------------
1017 C IOPP read DEVNODB
1018 A IOCW read --
1019 B IOAW read SETINT
1020 C IOPP read DEVNODB
1021
1022
1023 End (sioEND)
1024
1025 State Condition Action Signals
1026 ----- --------------- ---------- ------------------------------------------
1027 C IOPP read DEVNODB
1028 A IOCW read --
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001029 B IOAW write TOGGLESR | PSTATSTB | TOGGLESIOOK
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001030 idle
1031
1032
1033 End with Interrupt (sioENDIN)
1034
1035 State Condition Action Signals
1036 ----- --------------- ---------- ------------------------------------------
1037 C IOPP read DEVNODB
1038 A IOCW read --
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001039 B IOAW write TOGGLESR | SETINT | PSTATSTB | TOGGLESIOOK
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001040 idle
1041
1042
1043 Control (sioCNTL)
1044
1045 State Condition Action Signals
1046 ----- --------------- ---------- ------------------------------------------
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001047 C IOPP read DEVNODB
1048 A IOCW read TOGGLESR | PCMD1
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001049 B IOAW read ACKSR | PCONTSTB
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001050 C IOPP read ACKSR | TOGGLESR | DEVNODB
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001051
1052
1053 Sense (sioSENSE)
1054
1055 State Condition Action Signals
1056 ----- --------------- ---------- ------------------------------------------
1057 C IOPP read DEVNODB
1058 A IOCW read --
1059 B IOAW write PSTATSTB
1060 C IOPP read DEVNODB
1061
1062
1063 Write (sioWRITE)
1064
1065 State Condition Action Signals
1066 ----- --------------- ---------- ------------------------------------------
1067 C IOPP read DEVNODB
1068 A IOCW read ACKSR
1069 / B ~ IB IOAW read TOGGLESR | TOGGLEOUTXFER
1070 \ B IB IOAW read TOGGLESR
1071
1072 / D ~ TC data write ACKSR | PWRITESTB
1073 \ D TC data write ACKSR | PWRITESTB | EOT | TOGGLEOUTXFER
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001074 / D DEVEND * ~ TC IOPP read ACKSR | TOGGLESR | EOT | TOGGLEOUTXFER
1075 \ D DEVEND * TC IOPP read ACKSR | TOGGLESR
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001076
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001077 / C ~ DEVEND IOPP read ACKSR | TOGGLESR | DEVNODB
1078 / A ~ DEVEND IOCW read ACKSR
1079 \ A DEVEND IOCW read ACKSR
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001080
1081
1082 Write Chained (sioWRITEC)
1083
1084 State Condition Action Signals
1085 ----- --------------- ---------- ------------------------------------------
1086 C IOPP read DEVNODB
1087 A IOCW read --
1088 / B ~ IB IOAW read TOGGLESR | TOGGLEOUTXFER
1089 \ B IB IOAW read TOGGLESR
1090
1091 / D ~ TC data write ACKSR | PWRITESTB
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001092 \ D TC data write ACKSR | TOGGLESR | PWRITESTB | EOT
1093 / D DEVEND * ~ TC IOPP read ACKSR | EOT | TOGGLESR
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001094 \ D DEVEND * TC IOPP read --
1095
1096 / C ~ DEVEND IOPP read DEVNODB
1097 \ A DEVEND IOCW read --
1098
1099
1100 Read (sioREAD)
1101
1102 State Condition Action Signals
1103 ----- --------------- ---------- ------------------------------------------
1104 C IOPP read DEVNODB
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001105 A IOCW read --
1106 / B ~ IB IOAW read TOGGLESR | TOGGLEINXFER | READNEXTWD
1107 \ B IB IOAW read TOGGLESR | READNEXTWD
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001108
1109 / D ~ TC data write ACKSR | PREADSTB | READNEXTWD
1110 \ D TC data write ACKSR | PREADSTB | EOT | TOGGLEINXFER
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001111 / D DEVEND * ~ TC IOPP read ACKSR | TOGGLESR | EOT | TOGGLEINXFER
1112 \ D DEVEND * TC IOPP read ACKSR | TOGGLESR
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001113
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001114 / C ~ DEVEND IOPP read ACKSR | TOGGLESR | DEVNODB
1115 / A ~ DEVEND IOCW read ACKSR
1116 \ A DEVEND IOCW read ACKSR
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001117
1118
1119 Read Chained (sioREADC)
1120
1121 State Condition Action Signals
1122 ----- --------------- ---------- ------------------------------------------
1123 C IOPP read DEVNODB
1124 A IOCW read --
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001125 / B ~ IB IOAW read TOGGLESR | TOGGLEINXFER | READNEXTWD
1126 \ B IB IOAW read TOGGLESR | READNEXTWD
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001127
1128 / D ~ TC data write ACKSR | PREADSTB | READNEXTWD
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001129 \ D TC data write ACKSR | TOGGLESR | PREADSTB | EOT
1130 / D DEVEND * ~ TC IOPP read ACKSR | TOGGLESR | EOT
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001131 \ D DEVEND * TC IOPP read --
1132
1133 / C ~ DEVEND IOPP read DEVNODB
1134 \ A DEVEND IOCW read --
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001135
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001136
1137 Summarizing the State D signals sent to the interface:
1138
1139 Normal transfer
1140 ---------------
1141 - not the last word: ACKSR | PrwSTB { | READNEXTWD }
1142 - the last word and not chained: ACKSR | PrwSTB | EOT | TOGGLEioXFER
1143 - the last word and chained: ACKSR | PrwSTB | EOT | TOGGLESR
1144
1145 DEVEND asserted after a normal transfer
1146 ---------------------------------------
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001147 - not the last word and not chained: ACKSR | TOGGLESR | EOT | TOGGLEioXFER
1148 - not the last word and chained: ACKSR | TOGGLESR | EOT
1149 - the last word and not chained: ACKSR | TOGGLESR
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001150 - the last word and chained: (none)
1151
1152 In all cases where signals are generated, CHANSO is also included.
1153
1154
1155 Implementation notes:
1156
1157 1. In hardware, IOCW bits 1-3 specify the I/O order, except that the Jump,
1158 End, Return Residue, and Set Bank orders require an additional bit (IOCW
1159 bit 4) to define their orders fully. In simulation, the IOCW_ORDER macro
1160 uses IOCW bits 0-4 as an index into a 32-element lookup table to produce
1161 the final I/O order (because some of the orders define IOCW bit 4 as
1162 "don't care", there are only thirteen distinct orders).
1163
1164 2. In hardware, the Interrupt order loads the address register with the
1165 (unused) IOAW value. The simulator maintains this behavior.
1166
1167 3. The word count rollover flip-flop is preset asynchronously by the carry
1168 out signal from the word counter and is cleared synchronously by the
1169 trailing edge of the write-to-RAMs signal at the end of each state. It
1170 is used by the next-state logic to decide whether to remain in State D or
1171 exit to State C.
1172
1173 4. In hardware, the Device End flip-flop is clocked at the beginning and end
1174 of every I/O cycle and samples the DEVEND signal from the interface. The
1175 output controls the state sequencer. In simulation, the flip-flop is
1176 cleared at the end of every cycle, which ensures that it's clear for the
1177 next cycle entry.
1178
1179 5. The default label in the State B switch statement is necessary to quiet a
1180 warning that "inbound_signals" may be used uninitialized, even though all
1181 cases are covered. The initialization of "outbound" is also necessary,
1182 even though all paths through the while statement set its value.
1183*/
1184
1185void mpx_service (uint32 ticks_elapsed)
1186{
1187DIB *dibptr;
1188int32 cycles;
1189uint32 srn, mask, priority_mask;
1190HP_WORD inbound_data, outbound_data, iocw, ioaw;
1191t_bool store_ioaw;
1192SIO_ORDER sio_order;
1193INBOUND_SET inbound_signals;
1194SIGNALS_DATA outbound = IORETURN (NO_SIGNALS, 0); /* needed to quiet warning */
1195
1196cycles = CYCLES_PER_EVENT - excess_cycles; /* decrease the cycles available by any left over */
1197
1198priority_mask = 0; /* request a recalculation of the SR priority */
1199
1200while (cycles > 0) { /* execute as long as cycles remain */
1201 if (priority_mask == 0) { /* if priority must be recalculated */
1202 priority_mask = IOPRIORITY (mpx_request_set); /* then isolate the highest-priority bit from the set */
1203
1204 if (priority_mask == 0) /* if no request is pending */
1205 break; /* then we're done for now */
1206
1207 for (srn = 0, mask = priority_mask; !(mask & 1); srn++) /* determine the service request number */
1208 mask = mask >> 1; /* associated with the request bit */
1209
1210 dibptr = srs [srn]; /* get the DIB pointer for the request */
1211
1212 state_reg = state_ram [srn]; /* load the pipeline registers */
1213 aux_reg = aux_ram [srn]; /* from the selected RAM words */
1214 order_reg = order_ram [srn];
1215 cntr_reg = cntr_ram [srn];
1216 addr_reg = addr_ram [srn];
1217
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001218 sio_order = (SIO_ORDER) (order_reg & ORDER_MASK); /* map the order */
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001219 }
1220
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001221 dprintf (mpx_dev, DEB_STATE, "Channel SR %u entered %s with %d clock cycles remaining\n",
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001222 srn, state_name [state_reg], cycles);
1223
1224 switch (state_reg) { /* dispatch based on the multiplexer state */
1225
1226 case State_A:
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001227 if (sio_order == sioREAD /* if the previous order */
1228 || sio_order == sioWRITE) /* was an unchained Read or Write */
1229 inbound_signals = ACKSR | CHANSO; /* then acknowledge the final service request */
1230 else /* otherwise */
1231 inbound_signals = NO_SIGNALS; /* no acknowledgement is needed */
1232
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001233 cpu_read_memory (absolute_iop, addr_reg, &iocw); /* fetch the IOCW from memory */
1234 cycles = cycles - CYCLES_PER_READ; /* and count the memory access */
1235
1236 order_reg = IOCW_ORDER (iocw); /* get the translated order from the IOCW */
1237
1238 if (iocw & IOCW_DC) /* if the data chain bit is set */
1239 order_reg |= ORDER_DC; /* then set the data chain flag */
1240
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001241 sio_order = (SIO_ORDER) (order_reg & ORDER_MASK); /* isolate the I/O order */
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001242
1243 if (sio_order != sioRTRES) /* if this is not a Return Residue order */
1244 cntr_reg = IOCW_WCNT (iocw); /* then load the word count */
1245
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001246 dprintf (mpx_dev, DEB_PIO, "Channel SR %u loaded IOCW %06o (%s) from address %06o\n",
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001247 srn, iocw, sio_order_name [sio_order], addr_reg);
1248
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001249 if (sio_order == sioCNTL) /* if this a Control order */
1250 inbound_signals |= PCMD1 | TOGGLESR | CHANSO; /* then assert the first command strobe */
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001251
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001252 if (inbound_signals) /* call the interface if there are signals to assert */
1253 outbound = dibptr->io_interface (dibptr, inbound_signals, iocw);
1254 else /* otherwise the interface isn't involved */
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001255 outbound = IORETURN (SRn, 0); /* but assert a service request to continue the program */
1256
1257 addr_reg = addr_reg + 1 & R_MASK; /* point at the IOAW program word */
1258
1259 break;
1260
1261
1262 case State_B:
1263 store_ioaw = FALSE; /* assume that a fetch and not a store will be needed */
1264
1265 switch (sio_order) { /* dispatch based on the I/O order */
1266
1267 case sioJUMPC:
1268 inbound_signals = SETJMP | CHANSO;
1269 break;
1270
1271 case sioRTRES:
1272 inbound_signals = NO_SIGNALS; /* no interface call is needed */
1273
1274 if (aux_reg & AUX_TC) /* if the count has terminated */
1275 outbound = IORETURN (SRn, 0); /* then return a zero count and a service request */
1276 else /* otherwise return the two's-complement remainder */
1277 outbound = IORETURN (SRn, IOCW_COUNT (cntr_reg));
1278
1279 store_ioaw = TRUE; /* set to store the count */
1280 break;
1281
1282 case sioINTRP:
1283 inbound_signals = SETINT | CHANSO;
1284 break;
1285
1286 case sioEND:
1287 inbound_signals = TOGGLESIOOK | TOGGLESR | PSTATSTB | CHANSO;
1288 store_ioaw = TRUE; /* set to store the returned status */
1289 break;
1290
1291 case sioENDIN:
1292 inbound_signals = TOGGLESIOOK | TOGGLESR | PSTATSTB | SETINT | CHANSO;
1293 store_ioaw = TRUE; /* set to store the returned status */
1294 break;
1295
1296 case sioCNTL:
1297 inbound_signals = ACKSR | PCONTSTB | CHANSO;
1298 break;
1299
1300 case sioSENSE:
1301 inbound_signals = PSTATSTB | CHANSO;
1302 store_ioaw = TRUE; /* set to store the returned status */
1303 break;
1304
1305 case sioWRITE:
1306 case sioWRITEC:
1307 inbound_signals = TOGGLESR | CHANSO;
1308
1309 if ((aux_reg & AUX_IB) == 0) /* if we are not within a block transfer */
1310 inbound_signals |= TOGGLEOUTXFER; /* then add the signal to start the transfer */
1311 break;
1312
1313 case sioREAD:
1314 case sioREADC:
1315 inbound_signals = READNEXTWD | TOGGLESR | CHANSO;
1316
1317 if ((aux_reg & AUX_IB) == 0) /* if we are not within a block transfer */
1318 inbound_signals |= TOGGLEINXFER; /* then add the signal to start the transfer */
1319 break;
1320
1321 default: /* needed to quiet warning about inbound_signals */
1322 case sioJUMP: /* these orders do not need */
1323 case sioSBANK: /* to call the interface */
1324 inbound_signals = NO_SIGNALS; /* so assert a service request */
1325 outbound = IORETURN (SRn, 0); /* to continue the program */
1326 break;
1327 }
1328
1329 if (store_ioaw == FALSE) { /* if a fetch is needed */
1330 cpu_read_memory (absolute_iop, addr_reg, &ioaw); /* then load the IOAW from memory */
1331 cycles = cycles - CYCLES_PER_READ; /* and count the memory access */
1332
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001333 dprintf (mpx_dev, DEB_PIO, "Channel SR %u loaded IOAW %06o from address %06o\n",
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001334 srn, ioaw, addr_reg);
1335 }
1336
1337 else /* otherwise provide a dummy value */
1338 ioaw = 0; /* that will be overwritten */
1339
1340 if (inbound_signals) /* if there are signals to assert */
1341 outbound = dibptr->io_interface (dibptr, /* then pass them to the interface */
1342 inbound_signals, ioaw);
1343
1344 if (store_ioaw == TRUE) { /* if a store is needed */
1345 ioaw = IODATA (outbound); /* then set the IOAW from the returned value */
1346 cpu_write_memory (absolute_iop, addr_reg, ioaw); /* and store it in memory */
1347 cycles = cycles - CYCLES_PER_WRITE; /* count the memory access */
1348
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001349 dprintf (mpx_dev, DEB_PIO, "Channel SR %u stored IOAW %06o to address %06o\n",
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001350 srn, ioaw, addr_reg);
1351 }
1352
1353 switch (sio_order) { /* dispatch based on the I/O order */
1354 case sioREAD:
1355 case sioREADC:
1356 case sioWRITE:
1357 case sioWRITEC:
1358 aux_reg = aux_reg & ~AUX_TC | AUX_IB; /* clear the terminal count and set the in-block bit */
1359 addr_reg = ioaw; /* load the address register with the address word */
1360 break;
1361
1362 case sioJUMP:
1363 case sioJUMPC:
1364 case sioINTRP:
1365 addr_reg = ioaw; /* load the address register with the address word */
1366 break;
1367
1368 case sioEND:
1369 case sioENDIN:
1370 end_channel (dibptr); /* end the channel program */
1371
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001372 dprintf (mpx_dev, DEB_STATE, "Channel SR %u entered the %s\n",
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001373 srn, state_name [State_Idle]);
1374 break;
1375
1376 case sioCNTL: /* no additional */
1377 case sioSBANK: /* processing needed */
1378 case sioRTRES: /* for these orders */
1379 case sioSENSE:
1380 break;
1381 }
1382
1383 break;
1384
1385
1386 case State_C:
1387 inbound_signals = DEVNODB | CHANSO; /* assert DEVNODB to get the device number */
1388
1389 if (sio_order == sioREAD /* if we're completing */
1390 || sio_order == sioWRITE /* a Read, Write, */
1391 || sio_order == sioCNTL) /* or Control order */
1392 inbound_signals |= ACKSR | TOGGLESR; /* then clear the device and channel SR flip-flops */
1393
1394 outbound = dibptr->io_interface (dibptr, inbound_signals, 0);
1395
1396 if (sio_order != sioJUMP /* if we're not completing */
1397 && (sio_order != sioJUMPC || (outbound & JMPMET) == 0)) { /* a successful jump order */
1398 cpu_read_memory (absolute_iop, IODATA (outbound), &addr_reg); /* then get the I/O program pointer */
1399 cycles = cycles - CYCLES_PER_READ; /* and count the memory access */
1400 }
1401
1402 cpu_write_memory (absolute_iop, IODATA (outbound), /* write the updated program pointer */
1403 addr_reg + 2 & R_MASK); /* back to the DRT */
1404 cycles = cycles - CYCLES_PER_WRITE; /* and count the access */
1405
1406 break;
1407
1408
1409 case State_D:
1410 inbound_data = 0; /* assume there is no inbound data */
1411
1412 if (sio_order == sioSBANK) { /* if this is a Set Bank order */
1413 cpu_read_memory (absolute_iop, addr_reg, &ioaw); /* then read the IOAW */
1414 cycles = cycles - CYCLES_PER_READ; /* and count the memory access */
1415
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001416 dprintf (mpx_dev, DEB_PIO, "Channel SR %u loaded IOAW %06o from address %06o\n",
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001417 srn, ioaw, addr_reg);
1418
1419 addr_reg = ioaw; /* store the IOAW into the address register */
1420
1421 aux_reg = aux_reg & ~AUX_BANK_MASK /* merge the new bank number */
1422 | AUX_BANK (ioaw); /* into the auxiliary register */
1423
1424 outbound = IORETURN (SRn, 0); /* assert a service request to continue the program */
1425 break; /* no call to the interface is needed */
1426 }
1427
1428 else if (sio_order == sioREAD /* otherwise if this is a Read order */
1429 || sio_order == sioREADC) { /* or a Read Chained order */
1430 inbound_signals = ACKSR | PREADSTB | CHANSO; /* then assert the read strobe */
1431
1432 if (cntr_reg == CNTR_MAX) { /* if the word count is now exhausted */
1433 if (sio_order == sioREADC) /* then if the order is chained */
1434 inbound_signals |= EOT | TOGGLESR; /* then assert EOT and toggle the channel SR flip-flop */
1435 else /* otherwise */
1436 inbound_signals |= EOT | TOGGLEINXFER; /* assert EOT and end the transfer */
1437 }
1438
1439 else /* otherwise the transfer continues */
1440 inbound_signals |= READNEXTWD; /* so request the next word */
1441 }
1442
1443 else { /* otherwise this is a Write or Write Chained order */
1444 inbound_signals = ACKSR | PWRITESTB | CHANSO; /* so assert the write strobe */
1445
1446 if (cntr_reg == CNTR_MAX) /* if the word count is now exhausted */
1447 if (sio_order == sioWRITEC) /* then if the order is chained */
1448 inbound_signals |= EOT | TOGGLESR; /* then assert EOT and toggle the channel SR flip-flop */
1449 else /* otherwise */
1450 inbound_signals |= EOT | TOGGLEOUTXFER; /* assert EOT and end the transfer */
1451
1452 if (cpu_read_memory (dma_iop, /* read the word from memory */
1453 TO_PA (AUX_BANK (aux_reg), addr_reg), /* at the indicated bank and offset */
1454 &inbound_data)) /* if the read succeeds */
1455 cycles = cycles - CYCLES_PER_READ; /* then count the memory access */
1456
1457 else { /* otherwise the read failed */
1458 outbound = abort_channel (dibptr, "a memory read error"); /* so abort the transfer */
1459 break; /* and skip the interface call */
1460 }
1461 }
1462
1463 outbound = dibptr->io_interface (dibptr, inbound_signals, inbound_data); /* call the interface */
1464
1465 device_end = D_FF (outbound & DEVEND); /* set the flip-flop if the interface asserted DEVEND */
1466
1467 if (device_end == SET) { /* if the transfer was aborted by the interface */
1468 outbound_data = IODATA (outbound); /* then it returned the DRT program pointer address */
1469
1470 cpu_read_memory (absolute_iop, outbound_data, &addr_reg); /* do the I/O program pointer fetch here */
1471 cpu_write_memory (absolute_iop, outbound_data, /* so we don't have to do State C */
1472 addr_reg + 2 & R_MASK);
1473 cycles = cycles - CYCLES_PER_READ - CYCLES_PER_WRITE; /* count the two memory accesses */
1474
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001475 if (cntr_reg == CNTR_MAX) /* if the word count is now exhausted */
1476 if (order_reg & ORDER_DC) /* then if the order is chained */
1477 inbound_signals = NO_SIGNALS; /* then all required signals have been sent */
1478 else /* otherwise */
1479 inbound_signals = ACKSR | TOGGLESR | CHANSO; /* toggle the channel SR flip-flop */
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001480
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001481 else { /* otherwise the transfer is incomplete */
1482 inbound_signals = ACKSR | EOT | TOGGLESR | CHANSO; /* so assert EOT and toggle the channel SR FF */
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001483
1484 if (! (order_reg & ORDER_DC)) { /* if the order is not chained */
1485 aux_reg &= ~AUX_IB; /* then clear the in-block bit in RAM */
1486
1487 if (sio_order == sioREAD) /* if it's a Read order */
1488 inbound_signals |= TOGGLEINXFER; /* then terminate the inbound transfer */
1489 else /* otherwise it's a Write order */
1490 inbound_signals |= TOGGLEOUTXFER; /* so terminate the outbound transfer */
1491 }
1492 }
1493
1494 if (inbound_signals) /* if there are signals to assert */
1495 outbound = dibptr->io_interface (dibptr, /* then pass them to the interface */
1496 inbound_signals, 0);
1497 }
1498
1499 else { /* otherwise the transfer succeeded */
1500 if (sio_order == sioREAD || sio_order == sioREADC) /* if this is a Read or Read Chained order */
1501 if (cpu_write_memory (dma_iop, /* then write the word to memory */
1502 TO_PA (AUX_BANK (aux_reg), addr_reg), /* at the indicated bank and offset */
1503 IODATA (outbound))) /* if the write succeeds */
1504 cycles = cycles - CYCLES_PER_WRITE; /* then count the memory access */
1505
1506 else { /* otherwise the write failed */
1507 outbound = abort_channel (dibptr, "a memory write error"); /* so abort the transfer */
1508 break; /* and bail out now */
1509 }
1510
1511 addr_reg = addr_reg + 1 & R_MASK; /* point at the next word to transfer */
1512 cntr_reg = cntr_reg + 1 & CNTR_MASK; /* and count the word */
1513
1514 if (cntr_reg == 0) { /* if the count is exhausted */
1515 rollover = SET; /* then set the rollover flip-flop */
1516 aux_reg |= AUX_TC; /* and the terminal count flag */
1517
1518 if (! (order_reg & ORDER_DC)) /* if the order is not chained */
1519 aux_reg &= ~AUX_IB; /* then clear the in-block flag */
1520 }
1521 }
1522
1523 break;
1524
1525
1526 default: /* if the channel state is invalid */
1527 status_word = ST_STATE_PARITY | ST_RAM_ADDR (srn); /* then save the RAM address */
1528 outbound = abort_channel (dibptr, "an invalid state entry"); /* and abort the transfer */
1529 break;
1530 }
1531
1532 cycles = cycles - CYCLES_PER_STATE; /* count the state execution */
1533
1534 state_reg = next_state (state_reg, sio_order, device_end); /* get the next state */
1535
1536 rollover = CLEAR; /* the end of each state clears */
1537 device_end = CLEAR; /* the word count rollover and device end flip-flops */
1538
1539 if ((outbound & SRn) == NO_SIGNALS) { /* if the device is no longer requesting service */
1540 mpx_request_set &= ~priority_mask; /* then clear its request from the set */
1541 dibptr->service_request = FALSE; /* and clear its internal request flag */
1542
1543 priority_mask = 0; /* request SR priority recalculation */
1544
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001545 dprintf (mpx_dev, DEB_SR, "Device number %u denied SR%u\n",
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001546 dibptr->device_number, dibptr->service_request_number);
1547 }
1548
1549 if (outbound & INTREQ) /* if the interface asserted an interrupt request */
1550 iop_assert_INTREQ (dibptr); /* then set it up */
1551
1552 if (cycles <= 0 || priority_mask == 0) { /* if service for this device is ending */
1553 state_ram [srn] = state_reg; /* then write */
1554 aux_ram [srn] = aux_reg; /* the pipeline */
1555 order_ram [srn] = order_reg; /* registers back */
1556 cntr_ram [srn] = cntr_reg; /* to their */
1557 addr_ram [srn] = addr_reg; /* associated RAMS */
1558 }
1559 } /* end while */
1560
1561
1562if (cycles > 0) /* if we exited because there are no service requests */
1563 excess_cycles = 0; /* then do a full set of cycles next time */
1564else /* otherwise we ran over our allotment */
1565 excess_cycles = - cycles; /* so reduce the next poll by the overage */
1566
1567return;
1568}
1569
1570
1571
1572/* Channel local SCP support routines */
1573
1574
1575
1576/* Multiplexer channel diagnostic interface.
1577
1578 The channel diagnostic interface is installed on the IOP bus and receives
1579 direct I/O commands from the IOP. It does not respond to programmed I/O
1580 (SIO) commands, nor does it interrupt.
1581
1582 In simulation, the asserted signals on the bus are represented as bits in the
1583 inbound_signals set. Each signal is processed sequentially in numerical
1584 order, and a set of similar outbound_signals is assembled and returned to the
1585 caller, simulating assertion of the corresponding bus signals.
1586
1587 The interface allows a program to write to and read from any desired address
1588 in the address, order, state, or auxiliary RAMs. A CIO instruction specifies
1589 the RAM address and register to write or read with a subsequent WIO or RIO
1590 instruction. In addition, the address and word count registers may be
1591 incremented and the resulting values tested for correctness. After the RAMs
1592 are written, the next state is computed and written to the state RAM.
1593 Reading this value allows the next-state logic to be checked.
1594
1595
1596 Implementation notes:
1597
1598 1. In hardware, IOCW bits 1-3 specify the I/O order, except that the Jump,
1599 End, Return Residue, and Set Bank orders require an additional bit (IOCW
1600 bit 4) to define their orders fully. In simulation, the IOCW_ORDER macro
1601 uses IOCW bits 0-4 as an index into a 32-element lookup table to produce
1602 the final I/O order (because some of the orders define IOCW bit 4 as
1603 "don't care", there are only thirteen distinct orders).
1604
1605 2. In hardware, the "select the Address RAM and Register" bit (bit 6) of the
1606 control word is used only to enable reading and incrementing. The
1607 address RAM is written by a WIO instruction if the "select the Order RAM
1608 and Register" bit (bit 7) is not set. If bit 7 is set, then the Order
1609 RAM is written.
1610
1611 3. A WIO instruction writes all of the RAMs simultaneously. The control
1612 word select bits simply determine whether RAM data comes from the output
1613 word or the corresponding register.
1614
1615 4. A RIO instruction with the "load the registers from the RAMs during the
1616 next read" bit (bit 9) of the control word set loads all registers
1617 simultaneously. If the load bit and the "increment the Address or Word
1618 Count Registers after the next read" bit (bit 10) are both set, the load
1619 overrides the increment. An enabled increment occurs after the current
1620 value is returned.
1621
1622 5. If multiple registers are enabled in the control word, an RIO instruction
1623 will return the logical OR of the several values (in hardware, the
1624 selected registers are enabled to the active-low IOD bus).
1625*/
1626
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001627static SIGNALS_DATA mpx_interface (DIB *dibptr, INBOUND_SET inbound_signals, HP_WORD inbound_value)
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001628{
1629uint32 address;
1630SIO_ORDER sio_order;
1631INBOUND_SIGNAL signal;
1632INBOUND_SET working_set = inbound_signals;
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001633HP_WORD outbound_value = 0;
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001634OUTBOUND_SET outbound_signals = NO_SIGNALS;
1635
1636dprintf (mpx_dev, DEB_IOB, "Received data %06o with signals %s\n",
1637 inbound_value, fmt_bitset (inbound_signals, inbound_format));
1638
1639while (working_set) {
1640 signal = IONEXTSIG (working_set); /* isolate the next signal */
1641
1642 switch (signal) { /* dispatch an I/O signal */
1643
1644 case DWRITESTB:
1645 address = CN_RAM_ADDR (control_word); /* get the RAM location to address */
1646
1647 if (control_word & CN_ORDER_RAM) { /* if the order RAM is enabled */
1648 addr_ram [address] = addr_reg; /* then reload the address RAM from its register */
1649
1650 order_ram [address] = WR_ORDER (inbound_value); /* set the order RAM from the order field */
1651
1652 sio_order = IOCW_ORDER (inbound_value); /* get the translated order */
1653
1654 if (sio_order != sioRTRES) /* if it's not a Return Residue order */
1655 cntr_ram [address] = WR_COUNT (inbound_value); /* then set the counter RAM from the counter field */
1656 }
1657
1658 else { /* otherwise the order RAM is disabled */
1659 addr_ram [address] = inbound_value; /* so set the address RAM from the value */
1660
1661 sio_order = RD_SIO_ORDER (order_reg, cntr_reg); /* get the current SIO order */
1662
1663 order_ram [address] = order_reg; /* reload the order and counter RAMs */
1664 cntr_ram [address] = cntr_reg; /* from their respective registers */
1665 }
1666
1667 state_ram [address] = next_state (state_reg, sio_order, FALSE); /* store the next state into the state RAM */
1668
1669 if (control_word & CN_STATE_RAM) { /* if the state RAM is enabled */
1670 state_ram [address] |= WR_STATE (inbound_value); /* then merge the new state values */
1671
1672 aux_ram [address] = aux_reg & (AUX_IB | AUX_TC) /* set the new bank value */
1673 | WR_BANK (inbound_value); /* while preserving the flag bits */
1674 }
1675
1676 else /* otherwise the state RAM is disabled */
1677 aux_ram [address] = aux_reg; /* so reload the auxiliary RAM from its register */
1678
1679 if (state_reg == State_B) /* if the current state is State B */
1680 rollover = CLEAR; /* then clear the word count rollover flip-flop */
1681
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001682 dprintf (mpx_dev, DEB_CSRW, "RAM [%u] stored address %06o | %s | "
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001683 "counter %04o | %s | %sbank %02o\n",
1684 address, addr_ram [address], sio_order_name [sio_order],
1685 cntr_ram [address], state_name [state_ram [address]],
1686 fmt_bitset (aux_ram [address], aux_format),
1687 AUX_BANK (aux_ram [address]));
1688 break;
1689
1690
1691 case DREADSTB:
1692 address = CN_RAM_ADDR (control_word); /* get the RAM location to address */
1693
1694 if (control_word & CN_LOAD_REGS) { /* if the load enable bit is set */
1695 addr_reg = addr_ram [address]; /* then load all */
1696 order_reg = order_ram [address]; /* of the registers */
1697 cntr_reg = cntr_ram [address]; /* from their */
1698 state_reg = state_ram [address]; /* associated RAMs */
1699 aux_reg = aux_ram [address]; /* regardless of any RAM enables */
1700
1701 sio_order = RD_SIO_ORDER (order_reg, cntr_reg); /* get the current SIO order */
1702
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001703 dprintf (mpx_dev, DEB_CSRW, "RAM [%u] loaded address %06o | %s | "
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001704 "counter %04o | %s | %sbank %02o\n",
1705 address, addr_reg, sio_order_name [sio_order],
1706 cntr_reg, state_name [state_reg],
1707 fmt_bitset (aux_reg, aux_format),
1708 AUX_BANK (aux_reg));
1709 }
1710
1711 outbound_value = 0; /* start with an inactive IOD bus */
1712
1713 if (control_word & CN_STATE_RAM) { /* if the state register is selected */
1714 outbound_value = RD_STATE (state_reg) /* then merge the state register */
1715 | RD_BANK (aux_reg); /* and bank number to the bus */
1716
1717 if (aux_reg & AUX_TC) /* if the transfer-complete flag is set */
1718 outbound_value |= RD_XFER_COMPLETE; /* then reflect it in the status */
1719
1720 if (rollover == SET) /* if the word count rollover flip-flop is set */
1721 outbound_value |= RD_XFER_END; /* then indicate the end of the transfer */
1722
1723 if (odd_parity [UPPER_BYTE (addr_reg) /* if the address register value */
1724 ^ LOWER_BYTE (addr_reg)]) /* has odd parity */
1725 outbound_value |= RD_ADDR_PARITY; /* then set the parity status bit */
1726
1727 if (state_parity [state_reg]) /* if the state register does not have exactly one bit set */
1728 outbound_value |= RD_STATE_PARITY; /* then set the state parity status bit */
1729
1730 dprintf (mpx_dev, DEB_CSRW, "State register value %sbank %02o returned\n",
1731 fmt_bitset (outbound_value, read_format),
1732 AUX_BANK (aux_reg));
1733 }
1734
1735 if (control_word & CN_ORDER_RAM) { /* if the order register is selected */
1736 outbound_value = RD_ORDER (order_reg) /* then merge the order */
1737 | RD_COUNT (cntr_reg); /* and counter registers to the bus */
1738
1739 dprintf (mpx_dev, DEB_CSRW, "Order register value %02o (%s) "
1740 "and counter register value %d returned\n",
1741 order_reg & ORDER_MASK, sio_order_name [IOCW_ORDER (outbound_value)],
Mark Pizzolatoe370b9e2016-09-20 20:34:22 -07001742 SEXT (IOCW_COUNT (outbound_value)));
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001743 }
1744
1745 if (control_word & CN_ADDR_RAM) { /* if the address register is selected */
1746 outbound_value |= addr_reg; /* then enable it to drive the bus */
1747
1748 dprintf (mpx_dev, DEB_CSRW, "Address register value %06o returned\n",
1749 addr_reg);
1750 }
1751
1752 if (control_word & CN_INCR_REGS) { /* if incrementing is enabled */
1753 if (control_word & CN_ADDR_RAM){ /* then if the address register is selected */
1754 addr_reg = addr_reg + 1 & RD_ADDR_MASK; /* then increment it */
1755
1756 dprintf (mpx_dev, DEB_CSRW, "Address register incremented to %06o\n",
1757 addr_reg);
1758 }
1759
1760 if (control_word & CN_ORDER_RAM) { /* if the order register is selected */
1761 cntr_reg = cntr_reg + 1 & RD_COUNT_MASK; /* then increment the counter part of it */
1762
1763 dprintf (mpx_dev, DEB_CSRW, "Counter register incremented to %04o\n",
1764 cntr_reg);
1765
1766 if (cntr_reg == 0) { /* if the counter rolled over */
1767 rollover = SET; /* then set the rollover flip-flop */
1768 aux_reg |= AUX_TC; /* and the terminal count flag */
1769 }
1770 }
1771 }
1772 break;
1773
1774
1775 case DSTATSTB:
1776 outbound_value = ST_DIO_OK | status_word; /* get the last state parity error, if any */
1777
1778 dprintf (mpx_dev, DEB_CSRW, (status_word & ST_STATE_PARITY)
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001779 ? "Status is %sRAM address %u\n"
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001780 : "Status is DIO OK\n",
1781 fmt_bitset (outbound_value, status_format),
1782 ST_TO_RAM_ADDR (outbound_value));
1783 break;
1784
1785
1786 case DCONTSTB:
1787 control_word = inbound_value; /* save the new control word */
1788
1789 if (control_word & CN_MR) /* if a master reset is indicated */
1790 mpx_reset (&mpx_dev); /* then perform an IORESET */
1791
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001792 dprintf (mpx_dev, DEB_CSRW, "Control is %sRAM address %u\n",
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001793 fmt_bitset (inbound_value, control_format),
1794 CN_RAM_ADDR (control_word));
1795 break;
1796
1797
1798 case DSETINT: /* not used by this interface */
1799 case DRESETINT: /* not used by this interface */
1800 case DSTARTIO: /* not used by this interface */
1801 case DSETMASK: /* not used by this interface */
1802 case INTPOLLIN: /* not used by this interface */
1803 case XFERERROR: /* not used by this interface */
1804 case ACKSR: /* not used by this interface */
1805 case TOGGLESR: /* not used by this interface */
1806 case TOGGLESIOOK: /* not used by this interface */
1807 case TOGGLEINXFER: /* not used by this interface */
1808 case TOGGLEOUTXFER: /* not used by this interface */
1809 case READNEXTWD: /* not used by this interface */
1810 case PREADSTB: /* not used by this interface */
1811 case PWRITESTB: /* not used by this interface */
1812 case PCMD1: /* not used by this interface */
1813 case PCONTSTB: /* not used by this interface */
1814 case PSTATSTB: /* not used by this interface */
1815 case DEVNODB: /* not used by this interface */
1816 case SETINT: /* not used by this interface */
1817 case EOT: /* not used by this interface */
1818 case SETJMP: /* not used by this interface */
1819 case CHANSO: /* not used by this interface */
1820 case PFWARN: /* not used by this interface */
1821 break;
1822 }
1823
1824 IOCLEARSIG (working_set, signal); /* remove the current signal from the set */
1825 }
1826
1827dprintf (mpx_dev, DEB_IOB, "Returned data %06o with signals %s\n",
1828 outbound_value, fmt_bitset (outbound_signals, outbound_format));
1829
1830return IORETURN (outbound_signals, outbound_value); /* return the outbound signals and value */
1831}
1832
1833
1834/* Device reset.
1835
1836 This routine is called for a RESET or RESET MPX command. It is the
1837 simulation equivalent of the IORESET signal, which is asserted by the front
1838 panel LOAD and DUMP switches.
1839
1840 For this interface, IORESET is identical to a Programmed Master Reset.
1841
1842 A reset does not clear the order, counter, or address registers, nor any of
1843 the RAMs.
1844*/
1845
1846static t_stat mpx_reset (DEVICE *dptr)
1847{
1848state_reg = 0; /* clear the state */
1849aux_reg = 0; /* and auxiliary registers */
1850
1851control_word = 0; /* clear the control register */
1852status_word = 0; /* and state parity status register */
1853
1854rollover = CLEAR; /* clear the word count rollover */
1855device_end = CLEAR; /* and device end flip-flops */
1856
1857active_count = 0; /* idle the channel */
1858mpx_is_idle = TRUE;
1859
1860return SCPE_OK;
1861}
1862
1863
1864
1865/* Channel local utility routines */
1866
1867
1868
1869/* Determine the next state.
1870
1871 All I/O orders except Set Bank, Read, and Write execute states C, A, and B,
1872 in that order. The Set Bank order executes state C, A, and D. The Read and
1873 Write orders execute states C, A, B, and then one D state for each word
1874 transferred.
1875
1876 An abort in state D uses that cycle to perform the action of the next initial
1877 state C, which is skipped. Following the abort, the next state is state A.
1878*/
1879
1880static uint8 next_state (uint8 current_state, SIO_ORDER order, t_bool abort)
1881{
1882switch (current_state) {
1883
1884 case State_A: /* from state A */
1885 if (order == sioSBANK) /* the Set Bank order */
1886 return State_D; /* proceeds to state D */
1887 else /* while all other orders */
1888 return State_B; /* proceed to state B */
1889
1890
1891 case State_B: /* from state B */
1892 if (order == sioEND || order == sioENDIN) /* the End and End with Interrupt orders */
1893 return State_Idle; /* idle the channel */
1894
1895 else if (order >= sioWRITE) /* while the Write and Read orders */
1896 return State_D; /* proceed to state D */
1897
1898 else /* and all other orders */
1899 return State_C; /* proceed to state C */
1900
1901
1902 case State_C: /* from state C */
1903 return State_A; /* all orders proceed to state A */
1904
1905
1906 case State_D: /* from state D */
1907 if (order == sioSBANK || rollover == SET) /* the Set Bank order and the terminal count condition */
1908 return State_C; /* proceed to state C */
1909
1910 else if (abort) /* while the transfer abort condition */
1911 return State_A; /* proceeds to state A */
1912
1913 else /* and transfer continuation */
1914 return State_D; /* remains in state D */
1915
1916
1917 default: /* all invalid states */
1918 return State_Idle; /* return to the idle condition */
1919 }
1920}
1921
1922
1923/* End the channel I/O program.
1924
1925 The channel program ends, either normally via an sioEND or sioENDIN order, or
1926 abnormally via an XFERERROR abort. The reference count is decreased, and the
1927 idle flag set if no more transfers are active.
1928*/
1929
1930static void end_channel (DIB *dibptr)
1931{
1932active_count = active_count - 1; /* decrease the reference count */
1933mpx_is_idle = (active_count == 0); /* and idle the channel if no more work */
1934
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001935dprintf (mpx_dev, DEB_CSRW, "Channel SR %u program ended\n",
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001936 dibptr->service_request_number);
1937
1938return;
1939}
1940
1941
1942/* Abort the transfer in progress.
1943
1944 If an internal channel error occurs (e.g., a memory read or write failure,
1945 due to an invalid address), the channel asserts the XFERERROR signal to the
1946 device and then terminates the channel program. The device will clear its
1947 internal logic in response.
1948*/
1949
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001950static SIGNALS_DATA abort_channel (DIB *dibptr, const char *reason)
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001951{
1952SIGNALS_DATA outbound;
1953
Mark Pizzolato07f99bb2016-07-05 22:09:21 -07001954dprintf (mpx_dev, DEB_CSRW, "Channel SR %u asserted XFERERROR for %s\n",
Mark Pizzolato3a4e8792016-03-07 20:47:57 -08001955 dibptr->service_request_number, reason);
1956
1957outbound = dibptr->io_interface (dibptr, XFERERROR | CHANSO, 0); /* tell the device that the channel has aborted */
1958
1959end_channel (dibptr); /* end the channel program */
1960
1961return outbound;
1962}