GE-115 Emulator
An Emulator of the General Electrics GE-115 computer
signals.h
Go to the documentation of this file.
1
9#ifndef SIGNALS_H
10#define SIGNALS_H
11
12#include <stdint.h>
13#include "bit.h"
14#include "ge.h"
15#include "log.h"
16
17#define SIG( name ) static inline uint8_t name (struct ge *ge)
18
24SIG(RESI) { return ge->RESI; }
25SIG(RESI1) { return RESI(ge); }
26SIG(RESIA) { return !RESI1(ge); }
27SIG(RIA01) { return ge->RIA0; }
28SIG(RIA2A) { return !ge->RIA2; }
29SIG(RIA3A) { return !ge->RIA3; }
30
31SIG(RIUCA) { return !(RIA01(ge) && RESIA(ge) && RIA2A(ge) && RIA3A(ge)); }
32
33/* adding RIUCA here breaks machine startup */
34SIG(RES01) { return !(RESIA(ge) /* && RIUCA(ge) */); }
35
37SIG(RES0) { return RES01(ge); }
38
42SIG(RES2) {
43 /* cpu fo. 116 */
44 /* maybe this equation is incorrect in manual? it's
45 * documented as `!RIA2`, but it seems it should not
46 * be negated. */
47 return !ge->RIA3 & !ge->RESI & ge->RIA2;
48}
49
53SIG(RES3) {
54 /* cpu fo. 115 */
55 return ge->RIA3 & !ge->RESI;
56}
57
61SIG(RIUC) {
62 return ge->RIA0 & !ge->RESI & !ge->RIA3 & !ge->RIA2;
63}
64
65SIG(RES31) { return RES3(ge); };
66
75SIG(verified_condition) {
76 /* cpu fo 56, 57 */
77 uint8_t M = ge->rL1;
78 uint8_t M7 = BIT(M, 7);
79 uint8_t M6 = BIT(M, 6);
80 uint8_t M5 = BIT(M, 5);
81 uint8_t M4 = BIT(M, 4);
82
83 uint8_t FA5 = BIT(ge->ffFA, 5);
84 uint8_t FA4 = BIT(ge->ffFA, 4);
85
86 return (((ge->rFO == JC_OPCODE || ge->rFO == JU_OPCODE || ge->rFO == JCC_OPCODE ||
87 ge->rFO == JRT_OPCODE) &&
88 ((M7 && !FA4 && !FA5) ||
89 (M6 && !FA4 && FA5) ||
90 (M5 && FA4 && !FA5) ||
91 (M4 && FA4 && FA5))) ||
92 (ge->rFO == JS1_OPCODE && (ge->rL1 & 0xFF) ==JS1_2NDCHAR && ge->JS1) ||
93 (ge->rFO == JS2_OPCODE && (ge->rL1 & 0xFF) ==JS2_2NDCHAR && ge->JS2) ||
94 0);
95}
96
103SIG(AF10) { return ge->register_selector == RS_V4; }
104
106SIG(AF20) { return ge->register_selector == RS_L3; }
107
109SIG(AF21) { return ge->register_selector == RS_L1; }
110
112SIG(AF30) { return ge->register_selector == RS_V3; }
113
115SIG(AF31) { return ge->register_selector == RS_V1; }
116
118SIG(AF32) { return ge->register_selector == RS_NORM; }
119
121SIG(AF40) { return ge->register_selector == RS_R1_L2; }
122
124SIG(AF41) { return ge->register_selector == RS_V1_SCR; }
125
127SIG(AF42) { return ge->register_selector == RS_PO; }
128
130SIG(AF43) { return ge->register_selector == RS_SO; }
131
133SIG(AF50) { return ge->register_selector == RS_V2; }
134
136SIG(AF51) { return ge->register_selector == RS_V1_LETT; }
137
139SIG(AF52) { return ge->register_selector == RS_FI_UR; }
140
142SIG(AF53) { return ge->register_selector == RS_FO; }
145static inline uint16_t ge_counting_network_output(struct ge *ge) {
146 /* The flow charts spell an increment as CO41 (from_zero) alone and a
147 * decrement as CO40+CO41 (decreasing+from_zero): V1+1->V1 is "...41...",
148 * V1-1->V1 and L1-1->L1 are "...40-41...". CI42 injects the count at bit
149 * 04 instead, and CI44 blocks the carry/borrow past bit 07 (byte-local
150 * count). The active flags are the CO-phase ones until TO65 swaps in the
151 * CI-phase staging (pulse.c). (CPU[7] p33 external charts; fo.38/62 CI
152 * rows.)
153 *
154 * from_zero AND from_04 together are TWO INDEPENDENT QUARTET COUNTERS,
155 * not one subtraction of 0x11. cp06 ch.097 gate 24 (U13) builds BUD01 --
156 * the term that drives quartet 2's carry chain over on ch.096 -- from
157 * CA41A, CA42B and CA431 alone, all command lines, with no carry term
158 * from the bits 00-03 chain in it. So quartet 2 counts because it was
159 * TOLD to, not because quartet 1 borrowed into it, and a borrow out of
160 * bit 03 must not disturb it.
161 *
162 * That is what the decimal families need: cp07 fo.141 raises CI41 and
163 * CI42 from one gate, and fo.143 reads the two quartets separately --
164 * {L1_1 = 1i} switches the loop into its X variant (60 -> 62) while only
165 * {L1_2 = 1i} leaves for E2/E3. L1's low byte carries one length per SS
166 * operand, and the shorter one running out must not shorten the other. */
167 struct cmds *c = &ge->counting_network.cmds;
168 uint16_t delta = 0;
169
170 if (c->from_zero && c->from_04) {
171 uint8_t lo = ge->rBO & 0x0f;
172 uint8_t hi = (ge->rBO >> 4) & 0x0f;
173
174 if (c->decresing) {
175 lo = (lo - 1) & 0x0f;
176 hi = (hi - 1) & 0x0f;
177 } else {
178 lo = (lo + 1) & 0x0f;
179 hi = (hi + 1) & 0x0f;
180 }
181 return (ge->rBO & 0xff00) | (uint16_t)(hi << 4) | lo;
182 }
183
184 if (c->from_zero)
185 delta += 1;
186 if (c->from_04)
187 delta += 0x10;
188 if (!delta)
189 return ge->rBO;
190 if (c->decresing) {
191 if (c->stop_07)
192 return (ge->rBO & 0xff00) | ((ge->rBO - delta) & 0x00ff);
193 return ge->rBO - delta;
194 }
195 if (c->stop_07)
196 return (ge->rBO & 0xff00) | ((ge->rBO + delta) & 0x00ff);
197 return ge->rBO + delta;
198}
199
212static inline uint16_t NO_knot(struct ge *ge)
213{
214 uint16_t no = 0;
215
216 switch (ge->kNO.cmd) {
217 case KNOT_PO_IN_NO:
218 no = ge->rPO;
219 break;
220 case KNOT_V1_IN_NO:
221 no = ge->rV1;
222 break;
223 case KNOT_V2_IN_NO:
224 no = ge->rV2;
225 break;
226 case KNOT_V3_IN_NO:
227 no = ge->rV3;
228 break;
229 case KNOT_V4_IN_NO:
230 no = ge->rV4;
231 break;
232 case KNOT_L1_IN_NO:
233 no = ge->rL1;
234 break;
235 case KNOT_L2_IN_NO:
236 no = ge->rL2;
237 break;
238 case KNOT_L3_IN_NO:
239 no = ge->rL3;
240 break;
241 case KNOT_AM_IN_NO:
242 no = ge->console_switches.AM;
243 break;
244 case KNOT_RI_IN_NO_43:
245 no = ge->rRI << 8;
246 break;
247 case KNOT_NONE_IN_NO:
248 no = 0;
249 break;
250 }
251
252 switch (ge->kNO.force_mode) {
253 case KNOT_FORCING_NONE:
254 break;
255 case KNOT_FORCING_NO_21:
256 /* "Forcing in NO21" (CO18): the forcings drive quartets 2,1.
257 * In every state that raises CO18 with an address build (the
258 * indexing micro-cycle ED|EC / EF|EE, CPU[7] p64), no register
259 * selection is active while BO/VO latch the knot at TO20 — the
260 * selection commands are pulsed later in the cycle — so the knot
261 * carries the forced byte alone (quartets 4,3 read 0). gemu's
262 * kNO.cmd persists across cycles, so the previous state's
263 * selection must not leak into the forced address here. */
264 no = ge->kNO.forcings;
265 break;
266 case KNOT_FORCING_NO_43:
267 /* "Forcing in NO43" (CI19): forcings drive quartets 4,3 on top
268 * of whatever selection still drives them, and the low quartets
269 * are blanked (the TPER-CPER a8/a9 flow depends on both). Where
270 * a sheet's data path instead needs the PURE forced byte because
271 * the selection pulse has decayed (interruption F0/D2), the
272 * state issues NO_UNDRIVEN first — see KNOT_NONE_IN_NO. */
273 no = (no & 0xff00) | (ge->kNO.forcings << 8);
274 break;
275 }
276
277 return no;
278}
279
298static inline uint8_t NA_knot(struct ge *ge) {
299 uint8_t na = 0;
300
301 if (RES0(ge) || (RIUC(ge) && AF32(ge)))
302 na = ge->rSO;
303
304 if (RES2(ge))
305 na = ge->rSI & 0x0f;
306
307 if (RES0(ge) || RES3(ge))
308 na = na | 0x01;
309
310 if (RIUC(ge) && !AF32(ge))
311 na = na | 0x08;
312
313 return na;
314}
315
316static inline uint8_t NI_source(struct ge *ge, enum knot_ni_source source) {
317 uint16_t cn = ge_counting_network_output(ge);
318
319 switch (source) {
320 case NS_ZERO:
321 return 0;
322 case NS_CN1:
323 return (cn & 0x000f) >> 0;
324 case NS_CN2:
325 return (cn & 0x00f0) >> 4;
326 case NS_CN3:
327 return (cn & 0x0f00) >> 8;
328 case NS_CN4:
329 return (cn & 0xf000) >> 12;
330 case NS_RO1:
331 return (ge->rRO & 0x0f) >> 0;
332 case NS_RO2:
333 return (ge->rRO & 0xf0) >> 4;
334 case NS_UA2:
335 return (ge->rUA & 0xf0) >> 4;
336 case NS_UA1:
337 return (ge->rUA & 0x0f) >> 0;
338 }
339}
340
362static inline uint16_t NI_knot(struct ge *ge) {
363 uint16_t ni1 = NI_source(ge, ge->kNI.ni1);
364 uint16_t ni2 = NI_source(ge, ge->kNI.ni2);
365 uint16_t ni3 = NI_source(ge, ge->kNI.ni3);
366 uint16_t ni4 = NI_source(ge, ge->kNI.ni4);
367
368 return ((ni4 << 12) |
369 (ni3 << 8) |
370 (ni2 << 4) |
371 (ni1 << 0));
372}
373
381SIG(DI01A) { return !(BIT(ge->rSA, 0) && !BIT(ge->rSA, 1)); }
382SIG(DI011) { return !DI01A(ge); }
383SIG(DI02A) { return !(BIT(ge->rSA, 0) && BIT(ge->rSA, 1)); }
384SIG(DI021) { return !DI02A(ge); }
385SIG(DI03A) { return !(BIT(ge->rSA, 0) && BIT(ge->rSA, 1)); }
386SIG(DI031) { return !DI03A(ge); }
387SIG(DI06A) { return !(!BIT(ge->rSA, 7) && BIT(ge->rSA, 6) && BIT(ge->rSA, 2)); }
388SIG(DI062) { return !DI06A(ge); }
389/* cp06 ch.241-11: a second inverter off the same DI06A net, carrying the
390 * identical value to DI062. The two exist only to split fan-out -- the
391 * function/status AND sheets draw some of their beta-band terms from one and
392 * some from the other. Kept distinct so each gate reads like its sheet. */
393SIG(DI061) { return !DI06A(ge); }
394SIG(DI10A) { return !(BIT(ge->rSA, 7) && BIT(ge->rSA, 6) && BIT(ge->rSA, 5) && !BIT(ge->rSA, 4)); }
395SIG(DI101) { return !DI10A(ge); }
396SIG(DI11A) { return !(BIT(ge->rSA, 3) && DI101(ge) && !BIT(ge->rSA, 2)); }
397SIG(DI111) { return !DI11A(ge); }
398SIG(DI12A) { return !(!BIT(ge->rSA, 3) && DI101(ge)); }
399SIG(DI121) { return !DI12A(ge); }
400SIG(DI14A) { return !(BIT(ge->rSA, 7) && !BIT(ge->rSA, 5) && BIT(ge->rSA, 6)); }
401SIG(DI141) { return !DI14A(ge); }
402SIG(DI15A) { return !(DI141(ge) && !BIT(ge->rSA, 3)); }
403SIG(DI151) { return !DI15A(ge); }
404SIG(DI17A) { return !(!BIT(ge->rSA, 1) && DI121(ge) && !BIT(ge->rSA, 2)); }
405SIG(DI18A) { return !(!BIT(ge->rSA, 2) && DI121(ge) && BIT(ge->rSA, 1)); }
406SIG(DI181) { return !DI18A(ge); }
407SIG(DI18B) { return !DI181(ge); }
408SIG(DI19A) { return !(!BIT(ge->rSA, 1) && DI121(ge) && BIT(ge->rSA, 2)); }
409SIG(DI20A) { return !(BIT(ge->rSA, 1) && BIT(ge->rSA, 2) && DI121(ge)); }
410/* DI201 = /DI20A (the E6|E7 state decode, active-high). Was transcribed as
411 * DI201 = DI20A, which made EC56A0 (the modified-address CU03 gate in E6/E7,
412 * timing tables CPU[7] p63) a constant 0 — the reason the indexing micro-cycle
413 * previously needed future-state forcing instead of its documented CU rows. */
414SIG(DI201) { return !DI20A(ge); }
415/* State decodes for the modified-address indexing micro-cycle (timing tables
416 * CPU[7] p64, "FASE ALFA ED-EC / EF-EE"). The xxA equations are derived from
417 * the state codes; audit round-2 evidence from the cp06 sheets:
418 * - DI13A = NAND(DI101, SA03, SA02) READ on ch.225-18 — matches exactly.
419 * - DI65A reconstructed from fan-out callouts as NAND(DI131, SA01M)
420 * == this derivation (the generating ch.239 sheet is missing from the
421 * scan — see DI60A below).
422 * - DI67A partially reconstructed as NAND(DI031, ...): DI031 = SA00·SA01,
423 * functionally identical to this derivation (DI13·SA1·SA0 = EF).
424 * - DI66A partially reconstructed (SA016 confirmed as one input).
425 * - DI64A EXISTS at ch.232-19 (p292, read at 600dpi; missing from the
426 * parsed signal index — DI181-style parser gap); it is an inverter there,
427 * upstream AND-decode not yet located. Derived E7-only equation kept. */
428SIG(DI13A) { return !(DI101(ge) && BIT(ge->rSA, 3) && BIT(ge->rSA, 2)); } /* ED|EC + EF|EE */
429SIG(DI64A) { return !(DI121(ge) && BIT(ge->rSA, 2) &&
430 BIT(ge->rSA, 1) && BIT(ge->rSA, 0)); } /* E7 only */
431SIG(DI65A) { return !(!DI13A(ge) && !BIT(ge->rSA, 1)); } /* ED|EC only */
432SIG(DI66A) { return !(!DI13A(ge) && BIT(ge->rSA, 1)); } /* EF|EE only */
433SIG(DI67A) { return !(!DI66A(ge) && BIT(ge->rSA, 0)); } /* EF|EE, 1st operand {SA00} */
434SIG(DI21A) { return !( DI141(ge) && BIT(ge->rSA, 4) && BIT(ge->rSA, 3) && !BIT(ge->rSA, 2)); }
435SIG(DI211) { return !DI21A(ge); }
436SIG(DI22A) { return !(DI141(ge) && BIT(ge->rSA, 4) && BIT(ge->rSA, 3) && BIT(ge->rSA, 2)); }
437SIG(DI23A) { return !(DI141(ge) && BIT(ge->rSA, 3) && !BIT(ge->rSA, 4)); }
438SIG(DI231) { return !DI23A(ge); }
439SIG(DI24A) { return !(DI231(ge) && BIT(ge->rSA, 2)); };
440SIG(DI25A) { return !( DI231(ge) && !BIT(ge->rSA, 1) && !BIT(ge->rSA, 2)); };
441SIG(DI27A) { return !(!BIT(ge->rSA, 4) && !BIT(ge->rSA, 6) && BIT(ge->rSA, 7)); }
442SIG(DI271) { return !DI27A(ge); }
443SIG(DI28A) { return !(DI271(ge) && !BIT(ge->rSA, 5)); }
444SIG(DI281) { return !DI28A(ge); }
445SIG(DI28B) { return !DI281(ge); }
446SIG(DI29A) { return !(DI271(ge) && BIT(ge->rSA, 5) && BIT(ge->rSA, 3)); };
447SIG(DI291) { return !DI29A(ge); }
448SIG(DI48A) { return !(!BIT(ge->rSA, 4) && !BIT(ge->rSA, 5) && !BIT(ge->rSA, 6) && !BIT(ge->rSA, 7)); }
449SIG(DI481) { return !DI48A(ge); }
450SIG(DI58A) { return !(BIT(ge->rSA, 3) && !BIT(ge->rSA, 6)); }
451SIG(DI581) { return !DI58A(ge); }
452SIG(DI69A) { return !(DI481(ge) && !BIT(ge->rSA, 2)); }
453SIG(DI691) { return !DI69A(ge); }
454SIG(DI57A) { return !(!BIT(ge->rSA, 1) && DI581(ge) && DI691(ge)); }
455SIG(DI572) { return !DI57A(ge); }
456SIG(DI57B) { return DI57A(ge) ; }
457SIG(DI79A) { return !(DI151(ge) && DI021(ge)); }
458/* DI82A/DI83A live on the same missing ch.239 sheet as DI60A (see above).
459 * DI82A = NAND(DI111 [274-11], SA006 [110-2]) reconstructed from fan-out
460 * callouts (medium confidence): the E9|EB decode. Currently unused by any
461 * state table. */
462SIG(DI82A) { return !(DI111(ge) && BIT(ge->rSA, 0)); }
463/* DI83A: only one input recovered from callouts (SA00F = /SA00); the second
464 * input is unrecoverable without the missing sheet. Kept as the historical
465 * stub (DI83A0 = 0, so state_ea's CI33 row stays inert) rather than guessing
466 * an equation that could change state_ea behavior. */
467SIG(DI83A) { return 1; } // ch.239 sheet missing from scan; eq. partially known
468SIG(DI84A) { return !(DI011(ge) && DI291(ge)); }
469SIG(DI85A) { return !(DI291(ge) && DI031(ge)); }
470SIG(DI86A) { return !(!BIT(ge->rSA, 0) && DI291(ge)); }
471SIG(DI87A) { return !(!BIT(ge->rSA, 1) && DI291(ge)); }
472SIG(DI91A) { return !(DI031(ge) && DI211(ge)); }
473SIG(DI931) { return !(DI21A(ge) && DI29A(ge) && DI21A(ge) && DI15A(ge)); }
474SIG(DI93A) { return !DI931(ge); }
475SIG(DI94A) { return !(BIT(ge->rSA, 0) && DI931(ge)); }
476SIG(DI95A) { return !(DI931(ge) && DI031(ge)); }
477SIG(DI971) { return !(DI29A(ge) && DI25A(ge) && DI24A(ge) && DI29A(ge)); }
478SIG(DI97A) { return !DI971(ge); }
479
480SIG(DO01A) { return !(BIT(ge->rFO, 6) && !BIT(ge->rFO, 3) && !BIT(ge->rFO, 7)); }
481SIG(DO011) { return !DO01A(ge); }
482SIG(DO02A) { return !(BIT(ge->rFO, 3) && !BIT(ge->rFO, 7) && BIT(ge->rFO, 6)); }
483SIG(DO021) { return !(DO02A(ge) && DO02A(ge)); }
484SIG(DO04A) { return !(!BIT(ge->rFO, 5) && BIT(ge->rFO, 7)); }
485SIG(DO041) { return !DO04A(ge); }
486/* Backplane option connectors, cp06 ch.002 "VARIANTI E OPZIONI".
487 *
488 * TAB.3 -- E04 selects which two connectors are enabled for the initial LOAD:
489 *
490 * E04 || FUL26 | FUL36 || connectors enabled for loading
491 * ---------++-------+-------++--------------------------------
492 * (empty) || 1 | 1 || 2 and 3
493 * PONT2N || 1 | 0 || 2 and 4
494 * PONT2P || 0 | 1 || 4 and 3
495 *
496 * gemu defaults to empty, which is what the initial-load tests assume. */
497SIG(FUL26) { return ge->options.E04 != PONT_2P; }
498SIG(FUL36) { return ge->options.E04 != PONT_2N; }
499
500/* TAB.1 selection signals for the processor version. FEL06 is high only on
501 * the 6 usec UCE 466; FEL16 separates the 4 usec 467 from the 2 usec 468. */
502SIG(FEL06) { return ge->options.E03 == PONT_NONE; }
503SIG(FEL16) { return ge->options.E03 != PONT_2N; }
504
505/* TAB.1 + TAB.2 -- which connectors may raise an interruption. A strapped
506 * F04 is one of the "interruptions NO" versions and holds both low; only an
507 * empty F04 lets F03 choose, per TAB.2: empty enables both connectors,
508 * PONT2N enables 3 alone, PONT2P enables 4 alone. */
509SIG(INES3) {
510 return ge->options.F04 == PONT_NONE && ge->options.F03 != PONT_2P;
511}
512SIG(INES4) {
513 return ge->options.F04 == PONT_NONE && ge->options.F03 != PONT_2N;
514}
515
522static inline uint16_t ge_cpu_version_uce(const struct ge *ge)
523{
524 if (ge->options.E03 == PONT_NONE) return 466; /* 6 usec, MIN */
525 if (ge->options.E03 == PONT_2P) return 467; /* 4 usec, MAX */
526 return 468; /* 2 usec, MAX */
527}
528
530static inline uint16_t ge_cycle_period_ns(const struct ge *ge)
531{
532 switch (ge_cpu_version_uce(ge)) {
533 case 466: return 6000;
534 case 467: return 4000;
535 default: return 2000;
536 }
537}
538
539/* Memory capacity, cp06 ch.001 "SELEZIONE CAPACITA' MEMORIA / MEMORY
540 * CAPABILITY SELECTION" (dwg 14013 065 6). E05 and F05 between them pick one
541 * of five sizes, and the three selection signals fall out as:
542 *
543 * version | memory | E05 | F05 || VAMA2 | VEMB6 | VAMC2
544 * ---------+--------+--------+--------++-------+-------+-------
545 * UCE 460 | 8K | / | / || 1 | 1 | 1
546 * UCE 461 | 12K | PONT2N | / || 1 | 1 | 0
547 * UCE 462 | 16K | / | PONT2N || 1 | 0 | 1
548 * UCE 463 | 24K | PONT2P | PONT2N || 0 | 0 | 1
549 * UCE 464 | 32K | PONT2N | PONT2P || 0 | 0 | 0
550 *
551 * Note the UCE numbering runs on two independent axes: 460-464 is the memory
552 * capacity, 466-468 the processor version on ch.002. A machine is one of
553 * each, which is why every title block reads "UCE 460" -- that is the drawing
554 * set, not the machine.
555 *
556 * HOW THE CARDS WORK (derived 2026-07-21, over-determined by the ch.001 +
557 * ch.002 tables jointly and corroborated by the photographed boards): the
558 * PONT2 is a generic strap card and the type is which pins its staples
559 * short to the common --
560 *
561 * PONT2N shorts pins {1, 4} PONT2P shorts pins {1, 3}
562 *
563 * One assignment reproduces every printed row of TAB.1/TAB.2/TAB.3 and the
564 * ch.001 capacity table simultaneously (FEL06=1/FEL16=4 on E03, INES3=3/
565 * INES4=4 on F03, FUL26=3/FUL36=4 on E04, VAMC2=4/VAMA2=3 on E05,
566 * VEMB6=1/VAMA2=3 on F05, and on F04 it places FUL4G on pin 4 with the
567 * interrupt inhibit on pin 1 -- explaining why BOTH card types disable
568 * interrupts there). The signal equations below are written from that
569 * mechanism, not fitted to the table rows: the difference shows only for
570 * strap combinations the tables never print, e.g. E05=N,F05=N, where the
571 * old fitted VAMA2 wrongly read 0. */
572SIG(VAMC2) { return ge->options.E05 != PONT_2N; }
573SIG(VEMB6) { return ge->options.F05 == PONT_NONE; }
574SIG(VAMA2) {
575 /* pin 3 is grounded only by a PONT2P, in either position */
576 return !(ge->options.E05 == PONT_2P || ge->options.F05 == PONT_2P);
577}
578
579/* The S42 "LAMPS" override again, exactly as on ch.002: VAMA1/VAMB1/VAMC1
580 * follow VAMA2/VEMB6/VAMC2 unless the switch is in DIAG, when they become
581 * 1 / 0 / 1 regardless of the straps. */
582SIG(VAMA1) { return ge->options.S42_diag ? 1 : VAMA2(ge); }
583SIG(VAMB1) { return ge->options.S42_diag ? 0 : VEMB6(ge); }
584SIG(VAMC1) { return ge->options.S42_diag ? 1 : VAMC2(ge); }
585
616static inline uint8_t ge_mem_in_bounds(struct ge *ge, uint16_t addr)
617{
618 uint8_t b12 = !!(addr & 0x1000), b13 = !!(addr & 0x2000),
619 b14 = !!(addr & 0x4000);
620 uint8_t A = VAMA1(ge), B = VAMB1(ge), C = VAMC1(ge);
621
622 if (b13 && A && B && C) return 0; /* VAM11: past 8K */
623 if (b14 && A) return 0; /* VAM21: past 16K */
624 if (b13 && b12 && B) return 0; /* VAM31: past 12K */
625 if (b14 && b13 && C) return 0; /* VAM41: past 24K */
626 return 1;
627}
628
629static inline uint16_t ge_memory_capacity_k(struct ge *ge)
630{
631 /* The effective bound the ch.080 gates enforce: the first 4K frame
632 * whose start address the memory refuses to cycle for. For the five
633 * printed ch.001 rows this lands on the table's own 8/12/16/24/32K;
634 * for off-table strap combinations (e.g. the N+N found at Electric
635 * Dreams, which reads (1,0,0) -> 16K) it is the machine's real,
636 * gate-derived behaviour rather than a guess. */
637 for (uint32_t a = 0x1000; a < 0x8000; a += 0x1000)
638 if (!ge_mem_in_bounds(ge, (uint16_t)a))
639 return (uint16_t)(a >> 10);
640 return 32;
641}
642
643/* TAB.1 -- E03 and F04 strap the machine version, and FUL4G distinguishes the
644 * slow minimum-performance model from the two faster ones:
645 *
646 * version | cycle | perf | interrupts | E03 | F04 || FUL4G
647 * ---------+--------+------+------------+--------+--------++-------
648 * UCE 466 | 6 usec | MIN | no | / | PONT2N || 0
649 * UCE 467 | 4 usec | MAX | no | PONT2P | PONT2P || 1
650 * UCE 467 | 4 usec | MAX | YES | PONT2P | / || 1
651 * UCE 468 | 2 usec | MAX | no | PONT2N | PONT2P || 1
652 * UCE 468 | 2 usec | MAX | YES | PONT2N | / || 1
653 *
654 * FUL4G reads "this machine has the MAX instruction set", and it is low for
655 * exactly ONE strap: F04 = PONT2N, the 6 usec UCE 466. An EMPTY F04 is the
656 * interrupts-enabled variant of the two fast models, so it gives FUL4G = 1 --
657 * which is why this tests for PONT2N rather than for PONT2P. (It did test
658 * for PONT2P, which read the table off the "no interrupts" rows only and got
659 * an empty F04 backwards.) */
660SIG(FUL4G) { return ge->options.F04 != PONT_2N; }
661
662/* The note on ch.002: FUL01/FUL11/FUL4F follow FEL06/FEL16/FUL4G unless the
663 * maintenance panel's S42 "LAMPS" switch is in position DIAG, in which case
664 * they become 0 / 0 / 1 regardless of the straps. FUL4F is the form the
665 * timing charts cite as {FUL4}. */
666SIG(FUL4F) { return ge->options.S42_diag ? 1 : FUL4G(ge); }
667
668/* Names the charts and the older transcriptions use. */
669SIG(FUL2) { return FUL26(ge); }
670SIG(FUL3) { return FUL36(ge); }
671SIG(FUL4) { return FUL4F(ge); }
672
693/* Entry inverters, gates 22/26/31. Each is a NAND with both inputs tied to
694 * one net, which is how this drawing draws an inverter. */
695SIG(CI451) { return ge->ua_controls.logic; }
696SIG(CI461) { return ge->ua_controls.decimal_and; }
697SIG(CI471) { return ge->ua_controls.subtract_xor; }
698SIG(CI45D) { return !CI451(ge); }
699SIG(CI46B) { return !CI461(ge); }
700SIG(CI47B) { return !CI471(ge); }
701
702SIG(UCOA1) { return !(CI46B(ge) && CI47B(ge)); } /* gate 32 */
703SIG(UCO21) { return !(CI45D(ge) && UCOA1(ge)); } /* gate 33 */
704SIG(UCO2A) { return !UCO21(ge); } /* gate 34 */
705SIG(UCO4A) { return !(CI451(ge) && CI471(ge)); } /* gate 23 */
706SIG(UCO41) { return !UCO4A(ge); } /* gate 24 */
707SIG(UCO0A) { return !(CI45D(ge) && CI461(ge) && CI47B(ge)); } /* gate 27 */
708SIG(UCO01) { return !UCO0A(ge); } /* gates 25 + 28 */
709SIG(UCO1A) { return !(CI45D(ge) && CI471(ge)); } /* gate 29 */
710SIG(UCO11) { return !UCO1A(ge); } /* gate 30 */
711
712/* CI50's effect, cp06 ch.094 gates 8/9/12: CI50B = /CI501 is an input of the
713 * UZE71 and UZE81 NANDs, so raising CI50 forces both zone enables inactive. */
714SIG(CI50B) { return !ge->ua_controls.low_zone_only; }
715SIG(UZE71_enabled) { return CI50B(ge); }
716SIG(UZE81_enabled) { return CI50B(ge); }
717
720SIG(DO07A) { return !(!BIT(ge->rFO, 0) && !BIT(ge->rFO, 6) && DO041(ge)); }
721SIG(DO071) { return !DO07A(ge); }
722
723/* Function classes DO00 and DO06, cp06 ch.229 "FUNCTION DECODING" (dwg
724 * 14013 0650). Both gates take their inputs on unlabelled bus lines, read
725 * off the sheet rather than inferred: gate 10 pin 1 and gate 4 pin 1 both
726 * come from margin stub (105-8) C38-12 = FO06F, gate 4 pin 4 from (104-16)
727 * D38-03 = FO036, and gate 4 pin 5 from U07 pin 6 = DO041.
728 *
729 * Together with DO01 (jumps) and DO02 (LA) these are the four classes whose
730 * beta-band ANDs feed CU01 -- see docs/transcriptions/cu01-partial-command.md.
731 * The partition they produce is exact over the whole ISA: DO00 takes the
732 * console/control codes at 0x02/0x07/0x0A, DO06 takes LPSR alone, and every
733 * family that continues into the executive band falls outside all four. */
734SIG(DO00A) { return !(!BIT(ge->rFO, 7) && !BIT(ge->rFO, 6)); }
735SIG(DO001) { return !DO00A(ge); }
736SIG(DO06A) {
737 return !(!BIT(ge->rFO, 6) && BIT(ge->rFO, 3) && BIT(ge->rFO, 0) &&
738 DO041(ge));
739}
740SIG(DO061) { return !DO06A(ge); }
741
742/* Function-class AND beta-band terms, cp06 ch.248 "FUNCTION AND STATUS CODES
743 * ANDS" (gates 9, 8, 4) and ch.243 gate 5. All four have the same shape --
744 * one function class ANDed with the beta-state decode -- and all four are
745 * leaves of the CU01 partial command, CM011 below.
746 *
747 * DE00A used to be stubbed to a constant with the note "doesn't work for
748 * nop/lon/loff ecc". It was transcribed correctly all along; what was
749 * missing were its three siblings, so the one leaf was being asked to carry
750 * the whole condition and could only do it by being forced true. */
751SIG(DE00A) { return !(DO011(ge) && DI062(ge)); } /* jumps + JRT ch.248-9 */
752SIG(DE06A) { return !(DO021(ge) && DI062(ge)); } /* LA ch.248-8 */
753SIG(DE11A) { return !(DI061(ge) && DO001(ge)); } /* console group ch.248-4 */
754SIG(DE13A) { return !(DO061(ge) && DI061(ge)); } /* LPSR ch.243-5 */
755SIG(DE001) { return !DE00A(ge); }
756
757/* CU01's partial command, cp06 ch.252-7 "PARTIAL COMMANDS GENERATION": a
758 * four-input NAND over the active-low leaves above, i.e. the command asserts
759 * when ANY class claims the opcode. CM01A (ch.252-10) is its inverse; the
760 * timing charts cite the active-high call CM01A0. */
761SIG(CM011) {
762 return !(DE00A(ge) && DE06A(ge) && DE11A(ge) && DE13A(ge));
763}
764SIG(CM01A) { return !CM011(ge); }
765SIG(CM01A0) { return !CM01A(ge); }
766
767SIG(DE07A) { return !(DO071(ge) && DI062(ge)); }
768SIG(DE23A) { return !(DE001(ge) && BIT(ge->rFO, 4) && BIT(ge->rL1, 5)); }
769SIG(DE231) { return !(DE23A(ge) && DE23A(ge)); }
770
771SIG(DA25A) { return !(DI111(ge) && DO021(ge)); }
772
773SIG(PC011); SIG(PC111); SIG(PC211);
774SIG(DU161) { return !(BIT(ge->rSA, 1) && PC111(ge) && PC211(ge) && PC111(ge)); }
775SIG(DU18A) { return !(ge->RIG3 && BIT(ge->rL2, 7)); }
776SIG(DU19A) { return !(ge->RIG1 && PC011(ge) && !ge->RACI); }
777SIG(DU201) { return !(DU18A(ge) && DU19A(ge)); }
778SIG(EC56A) { return !(DI201(ge) && BIT(ge->rL2, 7)); }
779SIG(EC69A) { return !(AF41(ge) && DI572(ge));}
780SIG(EC70A) { return !(AF51(ge) && DI572(ge)); }
781SIG(ED70A) { return !(!ge->AINI && DI971(ge)); }
782SIG(ED75A) { return !(ge->AINI && DI011(ge) && DI291(ge)); }
783SIG(ED79A) { return !(DI291(ge) && DU161(ge) && BIT(ge->rSA, 0)); }
784SIG(ED91A) { return !(DE231(ge) && DU201(ge)); }
785
786SIG(DE00A0) { return !DE00A(ge); }
787SIG(DE07A0) { return !DE07A(ge); }
788SIG(DE08A0) { return !(!BIT(ge->rFO, 1) && DI062(ge) && DO071(ge)); }
789
790SIG(DA25A0) { return !DA25A(ge); }
791SIG(DI11A0) { return !DI11A(ge); }
792SIG(DI12A0) { return !DI12A(ge); }
793SIG(DI13A0) { return !DI13A(ge); }
794SIG(DI17A0) { return !DI17A(ge); }
795SIG(DI18A0) { return !DI18A(ge); }
796SIG(DI18B0) { return !DI18B(ge); }
797SIG(DI19A0) { return !DI19A(ge); }
798SIG(DI20A0) { return !DI20A(ge); }
799SIG(DI21A0) { return !DI21A(ge); }
800SIG(DI22A0) { return !DI22A(ge); }
801SIG(DI24A0) { return !DI24A(ge); }
802SIG(DI25A0) { return !DI25A(ge); }
803SIG(DI28A0) { return !DI28A(ge); }
804SIG(DI28B0) { return !DI28B(ge); }
805SIG(DI29A0) { return !DI29A(ge); }
806SIG(DI57A0) { return !DI57A(ge); }
807SIG(DI57B0) { return !DI57B(ge); }
808/* DI60A: the ch.239 sheet (foglio 217) is PHYSICALLY MISSING from the cp06
809 * scan (audit round-2: p298=ch238 -> p299=ch240, and ch256 is bound twice at
810 * p315/316). Equation reconstructed from fan-out callouts on surviving
811 * sheets: DI60A = NAND(DI121 [252-11], SA028 [256-4]) — i.e. the E4|E5|E6|E7
812 * band decode. Within the only states that use DI60A0 (E4/E5/E6/E7) it is
813 * identically 1, matching the previous stub. Medium confidence (callout
814 * reconstruction; the generating sheet itself is unscanned). */
815SIG(DI60A) { return !(DI121(ge) && BIT(ge->rSA, 2)); }
816SIG(DI60A0) { return !DI60A(ge); }
817SIG(DI64A0) { return !DI64A(ge); }
818SIG(DI65A0) { return !DI65A(ge); }
819SIG(DI66A0) { return !DI66A(ge); }
820SIG(DI67A0) { return !DI67A(ge); }
821SIG(DI79A0) { return !DI79A(ge); }
822SIG(DI82A0) { return !DI82A(ge); }
823SIG(DI83A0) { return !DI83A(ge); }
824SIG(DI84A0) { return !DI84A(ge); }
825SIG(DI85A0) { return !DI85A(ge); }
826SIG(DI86A0) { return !DI86A(ge); }
827SIG(DI87A0) { return !DI87A(ge); }
828SIG(DI91A0) { return !DI91A(ge); }
829SIG(DI93A0) { return !DI93A(ge); }
830SIG(DI94A0) { return !DI94A(ge); }
831SIG(DI95A0) { return !DI95A(ge); }
832SIG(DI97A0) { return !DI97A(ge); }
833
834SIG(EC56A0) { return !EC56A(ge); }
835SIG(EC69A0) { return !EC69A(ge); }
836SIG(EC70A0) { return !EC70A(ge); }
837SIG(ED70A0) { return !ED70A(ge); }
838SIG(ED75A0) { return !ED75A(ge); }
839SIG(ED79A0) { return !ED79A(ge); }
840SIG(ED91A0) { return !ED91A(ge); }
841
849/* MC */
850SIG(AITE) { return ge->console_switches.SITE; }
851SIG(AITEA) { return !AITE(ge); }
852
853/* RI — integrated card reader on channel 1 (COCA pins; see docs/signals/01-coca-connector.md). */
854SIG(LU081) { return reader_get_LU08(ge); } /* LU08N : char-ready strobe */
855SIG(LUPO1) { return reader_get_LUPO1(ge); } /* LUPOR : reader free / ready */
856SIG(FINI1) { return reader_get_FINI1(ge); } /* FININ : end-of-read */
857SIG(FIDE1) { return ge->integrated_reader.fiden; } /* FIDEN: end-of-sequence */
858SIG(LURE1) { return ge->integrated_reader.luren; } /* LUREN: error / jam */
859SIG(LUSE1) { return ge->integrated_reader.lusen; } /* LUSEN: out-of-service */
860SIG(LENO1) { return ge->integrated_reader.lenon; } /* LENON: not operable */
861SIG(BI201) { return ge->integrated_reader.bi20; } /* BI20 : binary 2nd-nibble */
862SIG(POM01) { return ge->integrated_reader.pom01; } /* POM01: binary-mode indic */
863SIG(PICO1) { return ge->integrated_reader.picon; } /* PICON: first-column */
864
865/* RL1U1: channel-1 read-length L1 "all ones" (terminal-count) decode (CPU
866 * signal index ch.128). A length-counted channel-1 transfer ends at L1+1
867 * characters; counting L1 down per character, the terminal is reached when L1
868 * underflows to all ones. Pure decode of rL1, so it is exposed here and reused
869 * by the RENIA end-of-transfer equation in msl-states.c. */
870SIG(RL1U1) { return (ge->rL1 & 0xff) == 0xff; }
871
872/* PI */
873SIG(FUSE1) { return 0; }
874SIG(FINA1) { return 0; }
875
876/* ST3 */
877SIG(MARE3) { return connector_get_MARE(&ge->ST3); }
878SIG(TE103) { return connector_get_TE10(&ge->ST3); }
879SIG(TE203) { return connector_get_TE20(&ge->ST3); }
880SIG(TE303) { return connector_get_TE30(&ge->ST3); }
881SIG(FINE3) { return connector_get_FINE(&ge->ST3); }
882
883/* ST4 */
884SIG(MARE4) { return connector_get_MARE(&ge->ST4); }
885SIG(TE104) { return connector_get_TE10(&ge->ST4); }
886SIG(TE204) { return connector_get_TE20(&ge->ST4); }
887SIG(TE304) { return connector_get_TE30(&ge->ST4); }
888SIG(FINE4) { return connector_get_FINE(&ge->ST4); }
889
892SIG(PC111); SIG(PC131); SIG(PC141); SIG(PC121);
893
894SIG(PB11A) { return !(FINA1(ge) && PC111(ge)); }
895SIG(PB13A) { return !(TE303(ge) && PC131(ge)); }
896SIG(PB14A) { return !(TE304(ge) && PC141(ge)); }
897
898SIG(RT121) { /* UNIV 1.2µs */ return ge->RT121; }
899SIG(RT131) { /* UNIV 1.2µs */ return ge->RT131; }
900
901SIG(RB101) { return !(AITEA(ge) && PB11A(ge) && PB13A(ge) && PB14A(ge)); }
902SIG(RB121) { /* UNIV 1.2µs */ return RB101(ge); }
903SIG(RB12A) { return !RB121(ge); }
904SIG(RB01A) { return !(RT121(ge) && RB101(ge)); }
905SIG(RB111) { return !(RB12A(ge) && RB01A(ge)); }
906
907SIG(PF12A) { return !(FINI1(ge) && PC121(ge)); }
908SIG(PF13A) { return !(FINE3(ge) && PC131(ge)); }
909SIG(PF14A) { return !(FINE4(ge) && PC141(ge)); }
910SIG(RF101) { return !(PF12A(ge) && PF13A(ge) && PF14A(ge)); }
911
920SIG(PC11A); SIG(PC12A); SIG(PC13A); SIG(PC14A);
921
922SIG(PC111) { return !PC11A(ge); };
924SIG(PC121) { return !PC12A(ge); };
925SIG(PC131) { return !PC13A(ge); };
926SIG(PC141) { return !PC14A(ge); };
927
928SIG(RUF11) { return ge->RUF1; }
929SIG(RUF1A) { return !ge->RUF1; }
930SIG(RASI1) { return ge->RASI; }
931SIG(TO501) { return ge->current_clock == TO50; }
932
933SIG(PELEA) { return !(LU081(ge) && LUPO1(ge)); }
934SIG(RELO1) { return !(PELEA(ge) && RUF1A(ge)); }
935SIG(PAM4A) { return !(RELO1(ge) && RASI1(ge) && PC121(ge)); }
936SIG(PM11A) { return !(FUSE1(ge) && PC111(ge)); }
937SIG(PM13A) { return !(MARE3(ge) && PC131(ge)); }
938SIG(PM14A) { return !(MARE4(ge) && PC141(ge)); }
939SIG(RM101) { return !(PM11A(ge) && PM13A(ge) && PM14A(ge)); }
940SIG(PAM1A) { return !(RASI1(ge) && RM101(ge)); }
941SIG(RS011) { return !(PAM4A(ge) && PAM1A(ge)); }
942SIG(PIM1A) { return !(TO501(ge) || RS011(ge) || RB111(ge) || RUF11(ge)); }
943SIG(PIM11) { return !PIM1A(ge); }
944SIG(PIC1A) { return !ge->PIC1; }
945SIG(PUC11) { return !(PIC1A(ge) && PIM1A(ge)); }
946SIG(PUC1) { return PUC11(ge); }
947
948/* !(channel 2 non overlap) */
949SIG(PC01A) { return !(!BIT(ge->rL2, 3) && !BIT(ge->rL2, 0)); }
951SIG(PC011) { return !PC01A(ge); }
952
953/* !(channel2 overlapped) */
954SIG(PC03A) { return !(!BIT(ge->rL2, 0) && BIT(ge->rL2, 3)); }
956SIG(PC031) { return !PC03A(ge); }
957
960SIG(PUC26) { return ge->PUC2; }
961SIG(PUC36) { return ge->PUC3; }
962
971SIG(PB061) { return ge->PB06; }
972SIG(PB06A) { return !ge->PB06; }
973SIG(PB071) { return ge->PB07; }
974SIG(PB07A) { return !ge->PB07; }
975SIG(PB261) { return ge->PB26; }
976SIG(PB26A) { return !ge->PB26; }
977SIG(PB361) { return ge->PB36; }
978SIG(PB36A) { return !ge->PB36; }
979SIG(PB371) { return ge->PB37; }
980SIG(PB37A) { return !ge->PB37; }
981SIG(PUC21) { return ge->PUC2; }
982SIG(PUC2A) { return !ge->PUC2; }
983SIG(PUC31) { return ge->PUC3; }
984SIG(PUC3A) { return !ge->PUC3; }
985
986SIG(PC11A) { return !(PUC11(ge) && PB071(ge) && PB061(ge)); }
987SIG(PC12A) { return !(PUC11(ge) && PB071(ge) && PB06A(ge)); }
988SIG(PC13A) { return !(PUC11(ge) && PB07A(ge) && PB06A(ge)); }
989SIG(PC14A) { return !(PUC11(ge) && PB07A(ge) && PB061(ge)); }
990SIG(PC21A) { return !(PUC21(ge) && PB261(ge)); }
991SIG(PC22A) { return !(PUC21(ge) && PB26A(ge)); }
992SIG(PC31A) { return !(PUC31(ge) && PB371(ge) && PB361(ge)); }
993SIG(PC32A) { return !(PUC31(ge) && PB371(ge) && PB36A(ge)); }
994SIG(PC33A) { return !(PUC31(ge) && PB37A(ge) && PB36A(ge)); }
995SIG(PC34A) { return !(PUC31(ge) && PB37A(ge) && PB361(ge)); }
996
997SIG(SEPEI) { return !(PC11A(ge) && PC21A(ge) && PC31A(ge)); }
998SIG(PU002) { return !(PC12A(ge) && PC22A(ge) && PC32A(ge)); }
999SIG(PU003) { return !(PC13A(ge) && PC33A(ge)); }
1000SIG(PU004) { return !(PC14A(ge) && PC34A(ge)); }
1001
1002SIG(PUB01_d1) { return !(SEPEI(ge) && BIT(ge->rL1, 7) && BIT(ge->rL1, 6)); }
1003SIG(PUB01_d2) { return !(PU002(ge) && BIT(ge->rL1, 7) && BIT(ge->rL1, 6)); }
1004SIG(PUB01_d3) { return !(PU003(ge) && BIT(ge->rL1, 7) && BIT(ge->rL1, 6)); }
1005SIG(PUB01_d4) { return !(PU004(ge) && BIT(ge->rL1, 7) && BIT(ge->rL1, 6)); }
1006
1008SIG(PUB01) { return !(PUB01_d1(ge) && PUB01_d2(ge) && PUB01_d3(ge) && PUB01_d4(ge)); }
1009
1011SIG(PC211) { return !PC21A(ge); }
1012
1013SIG(PC321) { return !PC32A(ge); }
1014SIG(PC331) { return !PC33A(ge); }
1015SIG(PC341) { return !PC34A(ge); }
1016
1019/* !(!rejected && in transfer) => rejected || !in_transfer */
1020SIG(DU871) { return !(!ge->RACI && ge->RASI); }
1021/* for state b8, FA is set if L200 && L203, which is channel 2 in overlap */
1022/* !(channel2 in overlap && channel2 in transfer */
1023SIG(DU881) { return !(BIT(ge->ffFA, 2) && ge->PUC2); }
1024
1025SIG(DU89A) { return !(DU871(ge) && DU881(ge) && PC011(ge) && DU881(ge)); }
1026
1027SIG(DU90A) { return !(PUC26(ge) && !BIT(ge->rRO, 0)); }
1028SIG(DU91A) { return !(BIT(ge->rRO, 0) && !BIT(ge->rRO, 3) && PUC36(ge)); }
1029
1031SIG(DU92) { return !(DU90A(ge) && DU91A(ge)); }
1032
1033SIG(DU93A) { return !(BIT(ge->rL2, 7) && BIT(ge->rL2, 5)); }
1034
1036SIG(DU93) { return !DU93A(ge); }
1037
1038SIG(DU95A) { return !(!BIT(ge->rRO, 1) && !BIT(ge->rRO, 2) && BIT(ge->rRO, 6)); }
1039SIG(DU95) { return !DU95A(ge); }
1040
1041SIG(DU96A) { return !(BIT(ge->rL2, 7) && BIT(ge->rL2, 7)); }
1042SIG(DU96) { return !DU96A(ge); }
1043
1044SIG(DU97A) { return !(ge->PUC2 ^
1045 BIT(ge->rL2, 0) ^
1046 BIT(ge->rL2, 0) ^
1047 BIT(ge->rL2, 3)); }
1048
1049SIG(DU97) { return !DU97A(ge); }
1050
1051SIG(DU98) { return !(DU89A(ge) && PC03A(ge)); }
1052
1053/* RI outgoing */
1054SIG(TU00A) { return !(RT121(ge) && RUF1A(ge) && PC121(ge));}
1055
1064SIG(FU091) { return 0; } /* todo: printer */
1065
1066SIG(PTA3A) { return !(TE103(ge) && TE203(ge)); }
1067SIG(PTA31) { return !PTA3A(ge); }
1068
1069SIG(PTA4A) { return !(TE104(ge) && TE204(ge)); }
1070SIG(PTA41) { return !PTA4A(ge); }
1071
1072SIG(PA11A) { return !(FU091(ge) && PC111(ge)); }
1073SIG(PA12A) { return !(LU081(ge) && PC121(ge)); }
1074SIG(PA13A) { return !(PTA31(ge) && PC131(ge)); }
1075SIG(PA14A) { return !(PTA41(ge) && PC141(ge)); }
1076SIG(RA101) { return !(PA11A(ge) && PA12A(ge) && PA13A(ge) && PA13A(ge) && PA14A(ge)); }
1077
1078/* } */
1079
1080/* Channel-2 reader-input selection (Phase 4). These gate PIB21 = enable NE input
1081 * from connector 2 on a channel-2 cycle, mirroring the channel-1 path
1082 * PB12A = !(RESI1 . PC121):
1083 * PB22A = !(RET21 . PC221), so the channel-2 reader read latches NE->RO when
1084 * the channel-2 cycle is active (RET21) AND connector 2 is selected on channel
1085 * 2 (PC221). RET21 is the channel-2 sync request RIA2 (mirror of RESI1 for ch-1).
1086 * PC221 = !PC22A = PUC21 . ~PB26 (channel-2 unit selected, connector selector
1087 * PB26=0 => connector 2). Both were stubbed to 0, which left the integrated
1088 * reader selectable only on channel 1 (via PB12A); these light the channel-2
1089 * path. Off for channel-1 ops (RIA2=0 / PUC2=0), so the channel-1 bootstrap is
1090 * unaffected. */
1091/* RET21: channel-2 cycle-assignment memory, the T010-clocked latch of RES2
1092 * (cp06 ch.132-6, verified on the sheet: RET21 = /((RES2A·T0107)+(T010C·RET2A))).
1093 * Was approximated as raw RIA2, which ignored the priority masking in RES2
1094 * (ch.1/ch.3 contention) and the latching. */
1095SIG(RET21) { return ge->RET2; }
1096SIG(PC221) { return !PC22A(ge); }
1097
1106SIG(PIB1A) { return !(RET21(ge) && PC211(ge)); }
1107SIG(PIB11) { return !PIB1A(ge); }
1108
1109SIG(PB12A) { return !(RESI1(ge) && PC121(ge)); }
1110SIG(PB22A) { return !(RET21(ge) && PC221(ge)); }
1111SIG(PB32A) { return !(RES31(ge) && PC321(ge)); }
1112SIG(PIB21) { return !(PB12A(ge) && PB22A(ge) && PB32A(ge)); }
1113
1114SIG(RB13A) { return !(RESI1(ge) && PC131(ge)); }
1115SIG(RB33A) { return !(RES31(ge) && PC331(ge)); }
1116SIG(PIB31) { return !(RB13A(ge) && RB33A(ge)); }
1117
1118SIG(RB14A) { return !(RESI1(ge) && PC141(ge)); }
1119SIG(RB34A) { return !(RES31(ge) && PC341(ge)); }
1120SIG(PIB41) { return !(RB14A(ge) && RB34A(ge)); }
1121
1130static inline uint16_t NE_knot(struct ge *ge) {
1131 uint16_t ret = 0;
1132 const char *where = "";
1133
1134 uint8_t count = PIB11(ge) + PIB21(ge) + PIB31(ge) + PIB41(ge);
1135
1136 if (count > 1) {
1137 ge_log(LOG_PERI, "multiple input signals for NE knot (?!)\n");
1138 }
1139
1140 if (PIB11(ge)) {
1141 where = "PI";
1142 ge_log(LOG_PERI, "TODO -- printer\n");
1143 }
1144
1145 if (PIB21(ge)) {
1146 where = "RI";
1147 ret = ge->integrated_reader.data;
1148 }
1149
1150 if (PIB31(ge)) {
1151 where = "ST3";
1152 ret = ge->ST3.data;
1153 }
1154
1155 if (PIB41(ge)) {
1156 where = "ST4";
1157 ret = ge->ST4.data;
1158 }
1159
1160 ge_log(LOG_PERI, "READING FROM NE KNOT %s --> %03x\n", where, ret);
1161 return ret;
1162}
1163
1164/* } */
1165
1174#define NAOR(a, b, c, d) !(a || b || c || d)
1175
1176SIG(RT111) { return 0; }
1177
1178SIG(RT311) { return 0; }
1179SIG(RT321) { return 0; }
1180SIG(RT331) { return 0; }
1181
1182SIG(RATE1) { return 0; }
1183SIG(PUOO3) { return 0; }
1184SIG(RUF31) { return 0; }
1185SIG(RAVI1) { return 0; }
1186
1187SIG(TU10C) { return NAOR(RT111(ge), PC131(ge), RT311(ge), PC331(ge)); }
1188SIG(TU20C) { return NAOR(RT121(ge), PC131(ge), RT321(ge), PC331(ge)); }
1189SIG(TU30C) { return NAOR(RT131(ge), PC131(ge), RT331(ge), PC331(ge)); }
1190SIG(AEBEC) { return !(RATE1(ge) && PC131(ge)); }
1191SIG(AECO3) { return !PUOO3(ge); }
1192SIG(FINUC) { return NAOR(RUF11(ge), PC131(ge), RUF31(ge), PC331(ge)); }
1193SIG(PV13A) { return !(RAVI1(ge) && PC131(ge)); }
1194SIG(VICU3) { return !(FINUC(ge) && PV13A(ge)); }
1195/* } */
1196
1197#endif
Bit manipulation helpers.
#define BIT(V, X)
Definition bit.h:9
@ RS_FI_UR
Definition console.h:20
@ RS_V1_SCR
Definition console.h:16
@ RS_SO
Definition console.h:21
@ RS_R1_L2
Definition console.h:12
@ RS_PO
Definition console.h:19
@ RS_V1_LETT
Definition console.h:17
@ RS_V1
Definition console.h:15
@ RS_L1
Definition console.h:14
@ RS_V3
Definition console.h:11
@ RS_NORM
Definition console.h:18
@ RS_L3
Definition console.h:10
@ RS_FO
Definition console.h:22
@ RS_V4
Definition console.h:9
@ RS_V2
Definition console.h:13
knot_ni_source
Definition ge.h:104
@ NS_ZERO
Definition ge.h:105
@ NS_RO1
Definition ge.h:110
@ NS_UA1
Definition ge.h:113
@ NS_UA2
Definition ge.h:112
@ NS_CN1
Definition ge.h:106
@ NS_CN2
Definition ge.h:107
@ NS_CN4
Definition ge.h:109
@ NS_CN3
Definition ge.h:108
@ NS_RO2
Definition ge.h:111
@ PONT_NONE
Definition ge.h:139
@ PONT_2N
Definition ge.h:139
@ PONT_2P
Definition ge.h:139
#define NAOR(a, b, c, d)
Definition signals.h:1174
static uint16_t NI_knot(struct ge *ge)
NI Knot.
Definition signals.h:362
static uint8_t NI_source(struct ge *ge, enum knot_ni_source source)
Definition signals.h:316
static uint16_t NO_knot(struct ge *ge)
Knot driven by P0, V1, V2, V4, L1, R1, V3 and L3.
Definition signals.h:212
static uint8_t NA_knot(struct ge *ge)
Knot driven by SO or SI.
Definition signals.h:298
static uint16_t ge_memory_capacity_k(struct ge *ge)
Definition signals.h:629
static uint16_t ge_cycle_period_ns(const struct ge *ge)
Cycle period in nanoseconds for the strapped version.
Definition signals.h:530
static uint8_t ge_mem_in_bounds(struct ge *ge, uint16_t addr)
Installed memory, in K.
Definition signals.h:616
static uint16_t ge_cpu_version_uce(const struct ge *ge)
Processor version: 466, 467 or 468 (cp06 ch.002 TAB.1).
Definition signals.h:522
static uint16_t NE_knot(struct ge *ge)
NE Knot.
Definition signals.h:1130
void ge_log(ge_log_type type, const char *format,...)
Log message.
Definition log.c:122
@ LOG_PERI
Peripherals IO.
Definition log.h:27
#define JCC_OPCODE
Definition opcodes.h:41
#define JS1_2NDCHAR
Definition opcodes.h:36
#define JRT_OPCODE
Definition opcodes.h:38
#define JC_OPCODE
Definition opcodes.h:39
#define JS2_OPCODE
Definition opcodes.h:32
#define JU_OPCODE
Definition opcodes.h:40
#define JS1_OPCODE
Definition opcodes.h:35
#define JS2_2NDCHAR
Definition opcodes.h:33
uint8_t reader_get_LUPO1(struct ge *ge)
Definition reader.c:198
uint8_t connector_get_TE30(struct ge_connector *conn)
Definition reader.c:229
uint8_t reader_get_LU08(struct ge *ge)
Definition reader.c:185
uint8_t connector_get_MARE(struct ge_connector *conn)
Definition reader.c:211
uint8_t reader_get_FINI1(struct ge *ge)
Definition reader.c:205
uint8_t connector_get_TE10(struct ge_connector *conn)
Definition reader.c:217
uint8_t connector_get_TE20(struct ge_connector *conn)
Definition reader.c:223
uint8_t connector_get_FINE(struct ge_connector *conn)
Definition reader.c:235
#define SIG(name)
Definition signals.h:17
static uint16_t ge_counting_network_output(struct ge *ge)
Definition signals.h:145
uint8_t data
Definition reader.h:89
uint16_t SITE
Don't wait for external unit availability.
Definition console.h:145
uint16_t AM
Forcing bits.
Definition console.h:155
struct ge_counting_network::cmds cmds
enum knot_ni_source ni4
Definition ge.h:120
enum knot_ni_source ni2
Definition ge.h:118
enum knot_ni_source ni1
Definition ge.h:117
enum knot_ni_source ni3
Definition ge.h:119
uint8_t forcings
Definition ge.h:77
enum ge_knot_no::@1 force_mode
enum ge_knot_no::@2 cmd
enum ge_pont E03
E03: machine version, paired with F04 (TAB.1) – FEL06 / FEL16.
Definition ge.h:143
enum ge_pont F05
Definition ge.h:157
enum ge_pont F03
F03: which connectors may raise an interruption (TAB.2).
Definition ge.h:149
enum ge_pont E04
E04: which two connectors are enabled for the initial LOAD (TAB.3).
Definition ge.h:146
uint8_t S42_diag
S42 "LAMPS" on the maintenance panel, in position DIAG.
Definition ge.h:165
enum ge_pont E05
E05 / F05: memory capacity (cp06 ch.001, "SELEZIONE CAPACITA MEMORIA") – 8K through 32K.
Definition ge.h:156
enum ge_pont F04
F04: machine version straps – cycle period and performance (TAB.1).
Definition ge.h:152
uint8_t subtract_xor
Definition ge.h:66
uint8_t decimal_and
Definition ge.h:65
uint8_t logic
Definition ge.h:64
uint8_t low_zone_only
Definition ge.h:73
The entire state of the emulated system, including registers, memory, peripherals and timings.
Definition ge.h:172
uint8_t RET2
Channel-2 cycle-assignment memory.
Definition ge.h:369
uint8_t RT121
Definition ge.h:666
uint8_t PB37
Definition ge.h:506
uint8_t AINI
Program Loading.
Definition ge.h:377
struct ge_integrated_reader integrated_reader
The I/O interface for the integrated reader (RI)
Definition ge.h:744
uint8_t JS2
Console jump condition 2.
Definition ge.h:496
struct ge_connector ST4
The I/O interface for the ST4 connector.
Definition ge.h:785
uint8_t ffFA
Special conditions register 2.
Definition ge.h:352
uint16_t rPO
Program addresser.
Definition ge.h:191
uint8_t PIC1
Selection Channel 1.
Definition ge.h:526
enum ge_console_rotary register_selector
The current state of the console register rotary switch.
Definition ge.h:680
uint8_t RIA0
Synchronous CPU Cycle Request.
Definition ge.h:629
uint8_t RIA2
Synchronous Channel 2 Cycle Request.
Definition ge.h:643
uint16_t rV1
Addresser for the first operand.
Definition ge.h:201
uint8_t rSO
Main sequencer.
Definition ge.h:309
uint16_t rRO
Multipurpose 8+1 bit register.
Definition ge.h:248
struct ge_counting_network counting_network
Definition ge.h:738
struct ge_console_switches console_switches
The current state of the console switches.
Definition ge.h:685
struct ge_connector ST3
The I/O interface for the ST3 connector.
Definition ge.h:780
uint8_t RIA3
Synchronous Channel 3 Cycle Request.
Definition ge.h:650
uint8_t PUC3
Channel 3 in transfer.
Definition ge.h:547
uint8_t rL2
Auxiliary register.
Definition ge.h:232
uint8_t PUC2
Channel 2 in transfer.
Definition ge.h:540
uint8_t rRI
Photoprint register 8-bit register used to store the photodisc codes.
Definition ge.h:223
uint16_t rBO
Default operator.
Definition ge.h:277
uint8_t PB06
Unconditionally stores L106.
Definition ge.h:502
struct ge_ua_controls ua_controls
Definition ge.h:739
struct ge_knot_ni kNI
Knot driven by counting network, or by the UA to store the result of the operation.
Definition ge.h:241
uint8_t RACI
Rejected Command.
Definition ge.h:661
uint8_t RT131
Definition ge.h:667
uint16_t rV4
Addresser for external instructions using channel 2.
Definition ge.h:204
uint8_t RASI
Channel 1 in transfer.
Definition ge.h:533
uint16_t rL1
Length of the operand.
Definition ge.h:231
uint8_t RUF1
Definition ge.h:552
uint8_t rSA
Future state configuration.
Definition ge.h:331
uint16_t rV2
Addresser for the second operand.
Definition ge.h:202
uint8_t RESI
Synchronous Channel 1 Cycle Request.
Definition ge.h:636
struct ge_options options
Backplane straps and maintenance-panel options (cp06 ch.002).
Definition ge.h:178
uint8_t RIG1
End from controller 1.
Definition ge.h:656
uint8_t rSI
Peripheral unit sequencer.
Definition ge.h:323
enum clock current_clock
Definition ge.h:174
uint8_t PB26
Stores L106 if channel 2 is selected.
Definition ge.h:504
uint16_t rL3
Length of operands involving channel 3.
Definition ge.h:233
uint8_t rUA
UA (arithmetic unit) output latch.
Definition ge.h:260
uint8_t PB07
Unconditionally stores L106.
Definition ge.h:503
uint8_t RIG3
Definition ge.h:658
uint16_t rV3
Addresser for external instructions using channel 3.
Definition ge.h:203
uint8_t PB36
Definition ge.h:505
struct ge_knot_no kNO
Definition ge.h:235
uint8_t rFO
Current function code.
Definition ge.h:284
uint8_t JS1
Console jump condition 1.
Definition ge.h:495