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) {
147 /* The flow charts spell an increment as CO41 (from_zero) alone and a
148 * decrement as CO40+CO41 (decreasing+from_zero): V1+1->V1 is "...41...",
149 * V1-1->V1 and L1-1->L1 are "...40-41...". So `decreasing` selects -1;
150 * without it, +1. (CPU[7] p33 external-sequence charts.) */
152 return ge->rBO - 1;
153 return ge->rBO + 1;
154 }
155 return ge->rBO;
156}
157
170static inline uint16_t NO_knot(struct ge *ge)
171{
172 uint16_t no = 0;
173
174 switch (ge->kNO.cmd) {
175 case KNOT_PO_IN_NO:
176 no = ge->rPO;
177 break;
178 case KNOT_V1_IN_NO:
179 no = ge->rV1;
180 break;
181 case KNOT_V2_IN_NO:
182 no = ge->rV2;
183 break;
184 case KNOT_V3_IN_NO:
185 no = ge->rV3;
186 break;
187 case KNOT_V4_IN_NO:
188 no = ge->rV4;
189 break;
190 case KNOT_L1_IN_NO:
191 no = ge->rL1;
192 break;
193 case KNOT_L2_IN_NO:
194 no = ge->rL2;
195 break;
196 case KNOT_L3_IN_NO:
197 no = ge->rL3;
198 break;
199 case KNOT_AM_IN_NO:
200 no = ge->console_switches.AM;
201 break;
202 case KNOT_RI_IN_NO_43:
203 no = ge->rRI << 8;
204 break;
205 }
206
207 switch (ge->kNO.force_mode) {
208 case KNOT_FORCING_NONE:
209 break;
210 case KNOT_FORCING_NO_21:
211 no = (no & 0x00ff) | (ge->kNO.forcings << 0);
212 break;
213 case KNOT_FORCING_NO_43:
214 no = (no & 0xff00) | (ge->kNO.forcings << 8);
215 break;
216 }
217
218 return no;
219}
220
239static inline uint8_t NA_knot(struct ge *ge) {
240 uint8_t na = 0;
241
242 if (RES0(ge) || (RIUC(ge) && AF32(ge)))
243 na = ge->rSO;
244
245 if (RES2(ge))
246 na = ge->rSI & 0x0f;
247
248 if (RES0(ge) || RES3(ge))
249 na = na | 0x01;
250
251 if (RIUC(ge) && !AF32(ge))
252 na = na | 0x08;
253
254 return na;
255}
256
257static inline uint8_t NI_source(struct ge *ge, enum knot_ni_source source) {
258 uint16_t cn = ge_counting_network_output(ge);
259
260 switch (source) {
261 case NS_CN1:
262 return (cn & 0x000f) >> 0;
263 case NS_CN2:
264 return (cn & 0x00f0) >> 4;
265 case NS_CN3:
266 return (cn & 0x0f00) >> 8;
267 case NS_CN4:
268 return (cn & 0xf000) >> 12;
269 case NS_RO1:
270 return (ge->rRO & 0x0f) >> 0;
271 case NS_RO2:
272 return (ge->rRO & 0xf0) >> 4;
273 case NS_UA2:
274 return 0;
275 case NS_UA1:
276 return 0;
277 }
278}
279
301static inline uint16_t NI_knot(struct ge *ge) {
302 uint16_t ni1 = NI_source(ge, ge->kNI.ni1);
303 uint16_t ni2 = NI_source(ge, ge->kNI.ni2);
304 uint16_t ni3 = NI_source(ge, ge->kNI.ni3);
305 uint16_t ni4 = NI_source(ge, ge->kNI.ni4);
306
307 return ((ni4 << 12) |
308 (ni3 << 8) |
309 (ni2 << 4) |
310 (ni1 << 0));
311}
312
320SIG(DI01A) { return !(BIT(ge->rSA, 0) && !BIT(ge->rSA, 1)); }
321SIG(DI011) { return !DI01A(ge); }
322SIG(DI02A) { return !(BIT(ge->rSA, 0) && BIT(ge->rSA, 1)); }
323SIG(DI021) { return !DI02A(ge); }
324SIG(DI03A) { return !(BIT(ge->rSA, 0) && BIT(ge->rSA, 1)); }
325SIG(DI031) { return !DI03A(ge); }
326SIG(DI06A) { return !(!BIT(ge->rSA, 7) && BIT(ge->rSA, 6) && BIT(ge->rSA, 2)); }
327SIG(DI062) { return !DI06A(ge); }
328SIG(DI10A) { return !(BIT(ge->rSA, 7) && BIT(ge->rSA, 6) && BIT(ge->rSA, 5) && !BIT(ge->rSA, 4)); }
329SIG(DI101) { return !DI10A(ge); }
330SIG(DI11A) { return !(BIT(ge->rSA, 3) && DI101(ge) && !BIT(ge->rSA, 2)); }
331SIG(DI111) { return !DI11A(ge); }
332SIG(DI12A) { return !(!BIT(ge->rSA, 3) && DI101(ge)); }
333SIG(DI121) { return !DI12A(ge); }
334SIG(DI14A) { return !(BIT(ge->rSA, 7) && !BIT(ge->rSA, 5) && BIT(ge->rSA, 6)); }
335SIG(DI141) { return !DI14A(ge); }
336SIG(DI15A) { return !(DI141(ge) && !BIT(ge->rSA, 3)); }
337SIG(DI151) { return !DI15A(ge); }
338SIG(DI17A) { return !(!BIT(ge->rSA, 1) && DI121(ge) && !BIT(ge->rSA, 2)); }
339SIG(DI18A) { return !(!BIT(ge->rSA, 2) && DI121(ge) && BIT(ge->rSA, 1)); }
340SIG(DI181) { return !DI18A(ge); }
341SIG(DI18B) { return !DI181(ge); }
342SIG(DI19A) { return !(!BIT(ge->rSA, 1) && DI121(ge) && BIT(ge->rSA, 2)); }
343SIG(DI20A) { return !(BIT(ge->rSA, 1) && BIT(ge->rSA, 2) && DI121(ge)); }
344SIG(DI201) { return DI20A(ge); }
345SIG(DI21A) { return !( DI141(ge) && BIT(ge->rSA, 4) && BIT(ge->rSA, 3) && !BIT(ge->rSA, 2)); }
346SIG(DI211) { return !DI21A(ge); }
347SIG(DI22A) { return !(DI141(ge) && BIT(ge->rSA, 4) && BIT(ge->rSA, 3) && BIT(ge->rSA, 2)); }
348SIG(DI23A) { return !(DI141(ge) && BIT(ge->rSA, 3) && !BIT(ge->rSA, 4)); }
349SIG(DI231) { return !DI23A(ge); }
350SIG(DI24A) { return !(DI231(ge) && BIT(ge->rSA, 2)); };
351SIG(DI25A) { return !( DI231(ge) && !BIT(ge->rSA, 1) && !BIT(ge->rSA, 2)); };
352SIG(DI27A) { return !(!BIT(ge->rSA, 4) && !BIT(ge->rSA, 6) && BIT(ge->rSA, 7)); }
353SIG(DI271) { return !DI27A(ge); }
354SIG(DI28A) { return !(DI271(ge) && !BIT(ge->rSA, 5)); }
355SIG(DI281) { return !DI28A(ge); }
356SIG(DI28B) { return !DI281(ge); }
357SIG(DI29A) { return !(DI271(ge) && BIT(ge->rSA, 5) && BIT(ge->rSA, 3)); };
358SIG(DI291) { return !DI29A(ge); }
359SIG(DI48A) { return !(!BIT(ge->rSA, 4) && !BIT(ge->rSA, 5) && !BIT(ge->rSA, 6) && !BIT(ge->rSA, 7)); }
360SIG(DI481) { return !DI48A(ge); }
361SIG(DI58A) { return !(BIT(ge->rSA, 3) && !BIT(ge->rSA, 6)); }
362SIG(DI581) { return !DI58A(ge); }
363SIG(DI69A) { return !(DI481(ge) && !BIT(ge->rSA, 2)); }
364SIG(DI691) { return !DI69A(ge); }
365SIG(DI57A) { return !(!BIT(ge->rSA, 1) && DI581(ge) && DI691(ge)); }
366SIG(DI572) { return !DI57A(ge); }
367SIG(DI57B) { return DI57A(ge) ; }
368SIG(DI79A) { return !(DI151(ge) && DI021(ge)); }
369SIG(DI82A) { return 0; } // TODO: MISSING MANUAL PAGE!!
370SIG(DI83A) { return 1; } // TODO: MISSING MANUAL PAGE!!
371SIG(DI84A) { return !(DI011(ge) && DI291(ge)); }
372SIG(DI85A) { return !(DI291(ge) && DI031(ge)); }
373SIG(DI86A) { return !(!BIT(ge->rSA, 0) && DI291(ge)); }
374SIG(DI87A) { return !(!BIT(ge->rSA, 1) && DI291(ge)); }
375SIG(DI91A) { return !(DI031(ge) && DI211(ge)); }
376SIG(DI931) { return !(DI21A(ge) && DI29A(ge) && DI21A(ge) && DI15A(ge)); }
377SIG(DI93A) { return !DI931(ge); }
378SIG(DI94A) { return !(BIT(ge->rSA, 0) && DI931(ge)); }
379SIG(DI95A) { return !(DI931(ge) && DI031(ge)); }
380SIG(DI971) { return !(DI29A(ge) && DI25A(ge) && DI24A(ge) && DI29A(ge)); }
381SIG(DI97A) { return !DI971(ge); }
382
383SIG(DO01A) { return !(BIT(ge->rFO, 6) && !BIT(ge->rFO, 3) && !BIT(ge->rFO, 7)); }
384SIG(DO011) { return !DO01A(ge); }
385SIG(DO02A) { return !(BIT(ge->rFO, 3) && !BIT(ge->rFO, 7) && BIT(ge->rFO, 6)); }
386SIG(DO021) { return !(DO02A(ge) && DO02A(ge)); }
387SIG(DO04A) { return !(!BIT(ge->rFO, 5) && BIT(ge->rFO, 7)); }
388SIG(DO041) { return !DO04A(ge); }
389SIG(DO07A) { return !(!BIT(ge->rFO, 0) && !BIT(ge->rFO, 6) && DO041(ge)); }
390SIG(DO071) { return !DO07A(ge); }
391
392// TODO: doesn't work for nop/lon/loff ecc
393SIG(DE00A) { return 0; !(DO011(ge) && DI062(ge)); }
394SIG(DE001) { return !DE00A(ge); }
395SIG(DE07A) { return !(DO071(ge) && DI062(ge)); }
396SIG(DE23A) { return !(DE001(ge) && BIT(ge->rFO, 4) && BIT(ge->rL1, 5)); }
397SIG(DE231) { return !(DE23A(ge) && DE23A(ge)); }
398
399SIG(DA25A) { return !(DI111(ge) && DO021(ge)); }
400
401SIG(PC011); SIG(PC111); SIG(PC211);
402SIG(DU161) { return !(BIT(ge->rSA, 1) && PC111(ge) && PC211(ge) && PC111(ge)); }
403SIG(DU18A) { return !(ge->RIG3 && BIT(ge->rL2, 7)); }
404SIG(DU19A) { return !(ge->RIG1 && PC011(ge) && !ge->RACI); }
405SIG(DU201) { return !(DU18A(ge) && DU19A(ge)); }
406SIG(EC56A) { return !(DI201(ge) && BIT(ge->rL2, 7)); }
407SIG(EC69A) { return !(AF41(ge) && DI572(ge));}
408SIG(EC70A) { return !(AF51(ge) && DI572(ge)); }
409SIG(ED70A) { return !(!ge->AINI && DI971(ge)); }
410SIG(ED75A) { return !(ge->AINI && DI011(ge) && DI291(ge)); }
411SIG(ED79A) { return !(DI291(ge) && DU161(ge) && BIT(ge->rSA, 0)); }
412SIG(ED91A) { return !(DE231(ge) && DU201(ge)); }
413
414SIG(DE00A0) { return !DE00A(ge); }
415SIG(DE07A0) { return !DE07A(ge); }
416SIG(DE08A0) { return !(!BIT(ge->rFO, 1) && DI062(ge) && DO071(ge)); }
417
418SIG(DA25A0) { return !DA25A(ge); }
419SIG(DI11A0) { return !DI11A(ge); }
420SIG(DI12A0) { return !DI12A(ge); }
421SIG(DI17A0) { return !DI17A(ge); }
422SIG(DI18A0) { return !DI18A(ge); }
423SIG(DI18B0) { return !DI18B(ge); }
424SIG(DI19A0) { return !DI19A(ge); }
425SIG(DI20A0) { return !DI20A(ge); }
426SIG(DI21A0) { return !DI21A(ge); }
427SIG(DI22A0) { return !DI22A(ge); }
428SIG(DI24A0) { return !DI24A(ge); }
429SIG(DI25A0) { return !DI25A(ge); }
430SIG(DI28A0) { return !DI28A(ge); }
431SIG(DI28B0) { return !DI28B(ge); }
432SIG(DI29A0) { return !DI29A(ge); }
433SIG(DI57A0) { return !DI57A(ge); }
434SIG(DI57B0) { return !DI57B(ge); }
435SIG(DI60A0) { return 1; } // TODO: Missing page in manual (!)
436SIG(DI79A0) { return !DI79A(ge); }
437SIG(DI82A0) { return !DI82A(ge); }
438SIG(DI83A0) { return !DI83A(ge); }
439SIG(DI84A0) { return !DI84A(ge); }
440SIG(DI85A0) { return !DI85A(ge); }
441SIG(DI86A0) { return !DI86A(ge); }
442SIG(DI87A0) { return !DI87A(ge); }
443SIG(DI91A0) { return !DI91A(ge); }
444SIG(DI93A0) { return !DI93A(ge); }
445SIG(DI94A0) { return !DI94A(ge); }
446SIG(DI95A0) { return !DI95A(ge); }
447SIG(DI97A0) { return !DI97A(ge); }
448
449SIG(EC56A0) { return !EC56A(ge); }
450SIG(EC69A0) { return !EC69A(ge); }
451SIG(EC70A0) { return !EC70A(ge); }
452SIG(ED70A0) { return !ED70A(ge); }
453SIG(ED75A0) { return !ED75A(ge); }
454SIG(ED79A0) { return !ED79A(ge); }
455SIG(ED91A0) { return !ED91A(ge); }
456
464/* MC */
465SIG(AITE) { return ge->console_switches.SITE; }
466SIG(AITEA) { return !AITE(ge); }
467
468/* RI — integrated card reader on channel 1 (COCA pins; see docs/signals.md §1). */
469SIG(LU081) { return reader_get_LU08(ge); } /* LU08N : char-ready strobe */
470SIG(LUPO1) { return reader_get_LUPO1(ge); } /* LUPOR : reader free / ready */
471SIG(FINI1) { return reader_get_FINI1(ge); } /* FININ : end-of-read */
472SIG(FIDE1) { return ge->integrated_reader.fiden; } /* FIDEN: end-of-sequence */
473SIG(LURE1) { return ge->integrated_reader.luren; } /* LUREN: error / jam */
474SIG(LUSE1) { return ge->integrated_reader.lusen; } /* LUSEN: out-of-service */
475SIG(LENO1) { return ge->integrated_reader.lenon; } /* LENON: not operable */
476SIG(BI201) { return ge->integrated_reader.bi20; } /* BI20 : binary 2nd-nibble */
477SIG(POM01) { return ge->integrated_reader.pom01; } /* POM01: binary-mode indic */
478SIG(PICO1) { return ge->integrated_reader.picon; } /* PICON: first-column */
479
480/* RL1U1: channel-1 read-length L1 "all ones" (terminal-count) decode (CPU
481 * signal index ch.128). A length-counted channel-1 transfer ends at L1+1
482 * characters; counting L1 down per character, the terminal is reached when L1
483 * underflows to all ones. Pure decode of rL1, so it is exposed here and reused
484 * by the RENIA end-of-transfer equation in msl-states.c. */
485SIG(RL1U1) { return (ge->rL1 & 0xff) == 0xff; }
486
487/* PI */
488SIG(FUSE1) { return 0; }
489SIG(FINA1) { return 0; }
490
491/* ST3 */
492SIG(MARE3) { return connector_get_MARE(&ge->ST3); }
493SIG(TE103) { return connector_get_TE10(&ge->ST3); }
494SIG(TE203) { return connector_get_TE20(&ge->ST3); }
495SIG(TE303) { return connector_get_TE30(&ge->ST3); }
496SIG(FINE3) { return connector_get_FINE(&ge->ST3); }
497
498/* ST4 */
499SIG(MARE4) { return connector_get_MARE(&ge->ST4); }
500SIG(TE104) { return connector_get_TE10(&ge->ST4); }
501SIG(TE204) { return connector_get_TE20(&ge->ST4); }
502SIG(TE304) { return connector_get_TE30(&ge->ST4); }
503SIG(FINE4) { return connector_get_FINE(&ge->ST4); }
504
507SIG(PC111); SIG(PC131); SIG(PC141); SIG(PC121);
508
509SIG(PB11A) { return !(FINA1(ge) && PC111(ge)); }
510SIG(PB13A) { return !(TE303(ge) && PC131(ge)); }
511SIG(PB14A) { return !(TE304(ge) && PC141(ge)); }
512
513SIG(RT121) { /* UNIV 1.2µs */ return ge->RT121; }
514SIG(RT131) { /* UNIV 1.2µs */ return ge->RT131; }
515
516SIG(RB101) { return !(AITEA(ge) && PB11A(ge) && PB13A(ge) && PB14A(ge)); }
517SIG(RB121) { /* UNIV 1.2µs */ return RB101(ge); }
518SIG(RB12A) { return !RB121(ge); }
519SIG(RB01A) { return !(RT121(ge) && RB101(ge)); }
520SIG(RB111) { return !(RB12A(ge) && RB01A(ge)); }
521
522SIG(PF12A) { return !(FINI1(ge) && PC121(ge)); }
523SIG(PF13A) { return !(FINE3(ge) && PC131(ge)); }
524SIG(PF14A) { return !(FINE4(ge) && PC141(ge)); }
525SIG(RF101) { return !(PF12A(ge) && PF13A(ge) && PF14A(ge)); }
526
535SIG(PC11A); SIG(PC12A); SIG(PC13A); SIG(PC14A);
536
537SIG(PC111) { return !PC11A(ge); };
539SIG(PC121) { return !PC12A(ge); };
540SIG(PC131) { return !PC13A(ge); };
541SIG(PC141) { return !PC14A(ge); };
542
543SIG(RUF11) { return ge->RUF1; }
544SIG(RUF1A) { return !ge->RUF1; }
545SIG(RASI1) { return ge->RASI; }
546SIG(TO501) { return ge->current_clock == TO50; }
547
548SIG(PELEA) { return !(LU081(ge) && LUPO1(ge)); }
549SIG(RELO1) { return !(PELEA(ge) && RUF1A(ge)); }
550SIG(PAM4A) { return !(RELO1(ge) && RASI1(ge) && PC121(ge)); }
551SIG(PM11A) { return !(FUSE1(ge) && PC111(ge)); }
552SIG(PM13A) { return !(MARE3(ge) && PC131(ge)); }
553SIG(PM14A) { return !(MARE4(ge) && PC141(ge)); }
554SIG(RM101) { return !(PM11A(ge) && PM13A(ge) && PM14A(ge)); }
555SIG(PAM1A) { return !(RASI1(ge) && RM101(ge)); }
556SIG(RS011) { return !(PAM4A(ge) && PAM1A(ge)); }
557SIG(PIM1A) { return !(TO501(ge) || RS011(ge) || RB111(ge) || RUF11(ge)); }
558SIG(PIM11) { return !PIM1A(ge); }
559SIG(PIC1A) { return !ge->PIC1; }
560SIG(PUC11) { return !(PIC1A(ge) && PIM1A(ge)); }
561SIG(PUC1) { return PUC11(ge); }
562
563/* !(channel 2 non overlap) */
564SIG(PC01A) { return !(!BIT(ge->rL2, 3) && !BIT(ge->rL2, 0)); }
566SIG(PC011) { return !PC01A(ge); }
567
568/* !(channel2 overlapped) */
569SIG(PC03A) { return !(!BIT(ge->rL2, 0) && BIT(ge->rL2, 3)); }
571SIG(PC031) { return !PC03A(ge); }
572
575SIG(PUC26) { return ge->PUC2; }
576SIG(PUC36) { return ge->PUC3; }
577
586SIG(PB061) { return ge->PB06; }
587SIG(PB06A) { return !ge->PB06; }
588SIG(PB071) { return ge->PB07; }
589SIG(PB07A) { return !ge->PB07; }
590SIG(PB261) { return ge->PB26; }
591SIG(PB26A) { return !ge->PB26; }
592SIG(PB361) { return ge->PB36; }
593SIG(PB36A) { return !ge->PB36; }
594SIG(PB371) { return ge->PB37; }
595SIG(PB37A) { return !ge->PB37; }
596SIG(PUC21) { return ge->PUC2; }
597SIG(PUC2A) { return !ge->PUC2; }
598SIG(PUC31) { return ge->PUC3; }
599SIG(PUC3A) { return !ge->PUC3; }
600
601SIG(PC11A) { return !(PUC11(ge) && PB071(ge) && PB061(ge)); }
602SIG(PC12A) { return !(PUC11(ge) && PB071(ge) && PB06A(ge)); }
603SIG(PC13A) { return !(PUC11(ge) && PB07A(ge) && PB06A(ge)); }
604SIG(PC14A) { return !(PUC11(ge) && PB07A(ge) && PB061(ge)); }
605SIG(PC21A) { return !(PUC21(ge) && PB261(ge)); }
606SIG(PC22A) { return !(PUC21(ge) && PB26A(ge)); }
607SIG(PC31A) { return !(PUC31(ge) && PB371(ge) && PB361(ge)); }
608SIG(PC32A) { return !(PUC31(ge) && PB371(ge) && PB36A(ge)); }
609SIG(PC33A) { return !(PUC31(ge) && PB37A(ge) && PB36A(ge)); }
610SIG(PC34A) { return !(PUC31(ge) && PB37A(ge) && PB361(ge)); }
611
612SIG(SEPEI) { return !(PC11A(ge) && PC21A(ge) && PC31A(ge)); }
613SIG(PU002) { return !(PC12A(ge) && PC22A(ge) && PC32A(ge)); }
614SIG(PU003) { return !(PC13A(ge) && PC33A(ge)); }
615SIG(PU004) { return !(PC14A(ge) && PC34A(ge)); }
616
617SIG(PUB01_d1) { return !(SEPEI(ge) && BIT(ge->rL1, 7) && BIT(ge->rL1, 6)); }
618SIG(PUB01_d2) { return !(PU002(ge) && BIT(ge->rL1, 7) && BIT(ge->rL1, 6)); }
619SIG(PUB01_d3) { return !(PU003(ge) && BIT(ge->rL1, 7) && BIT(ge->rL1, 6)); }
620SIG(PUB01_d4) { return !(PU004(ge) && BIT(ge->rL1, 7) && BIT(ge->rL1, 6)); }
621
623SIG(PUB01) { return !(PUB01_d1(ge) && PUB01_d2(ge) && PUB01_d3(ge) && PUB01_d4(ge)); }
624
626SIG(PC211) { return !PC21A(ge); }
627
628SIG(PC321) { return !PC32A(ge); }
629SIG(PC331) { return !PC33A(ge); }
630SIG(PC341) { return !PC34A(ge); }
631
634/* !(!rejected && in transfer) => rejected || !in_transfer */
635SIG(DU871) { return !(!ge->RACI && ge->RASI); }
636/* for state b8, FA is set if L200 && L203, which is channel 2 in overlap */
637/* !(channel2 in overlap && channel2 in transfer */
638SIG(DU881) { return !(BIT(ge->ffFA, 2) && ge->PUC2); }
639
640SIG(DU89A) { return !(DU871(ge) && DU881(ge) && PC011(ge) && DU881(ge)); }
641
642SIG(DU90A) { return !(PUC26(ge) && !BIT(ge->rRO, 0)); }
643SIG(DU91A) { return !(BIT(ge->rRO, 0) && !BIT(ge->rRO, 3) && PUC36(ge)); }
644
646SIG(DU92) { return !(DU90A(ge) && DU91A(ge)); }
647
648SIG(DU93A) { return !(BIT(ge->rL2, 7) && BIT(ge->rL2, 5)); }
649
651SIG(DU93) { return !DU93A(ge); }
652
653SIG(DU95A) { return !(!BIT(ge->rRO, 1) && !BIT(ge->rRO, 2) && BIT(ge->rRO, 6)); }
654SIG(DU95) { return !DU95A(ge); }
655
656SIG(DU96A) { return !(BIT(ge->rL2, 7) && BIT(ge->rL2, 7)); }
657SIG(DU96) { return !DU96A(ge); }
658
659SIG(DU97A) { return !(ge->PUC2 ^
660 BIT(ge->rL2, 0) ^
661 BIT(ge->rL2, 0) ^
662 BIT(ge->rL2, 3)); }
663
664SIG(DU97) { return !DU97A(ge); }
665
666SIG(DU98) { return !(DU89A(ge) && PC03A(ge)); }
667
668/* RI outgoing */
669SIG(TU00A) { return !(RT121(ge) && RUF1A(ge) && PC121(ge));}
670
679SIG(FU091) { return 0; } /* todo: printer */
680
681SIG(PTA3A) { return !(TE103(ge) && TE203(ge)); }
682SIG(PTA31) { return !PTA3A(ge); }
683
684SIG(PTA4A) { return !(TE104(ge) && TE204(ge)); }
685SIG(PTA41) { return !PTA4A(ge); }
686
687SIG(PA11A) { return !(FU091(ge) && PC111(ge)); }
688SIG(PA12A) { return !(LU081(ge) && PC121(ge)); }
689SIG(PA13A) { return !(PTA31(ge) && PC131(ge)); }
690SIG(PA14A) { return !(PTA41(ge) && PC141(ge)); }
691SIG(RA101) { return !(PA11A(ge) && PA12A(ge) && PA13A(ge) && PA13A(ge) && PA14A(ge)); }
692
693/* } */
694
695/* Channel-2 reader-input selection (Phase 4). These gate PIB21 = enable NE input
696 * from connector 2 on a channel-2 cycle, mirroring the channel-1 path
697 * PB12A = !(RESI1 . PC121):
698 * PB22A = !(RET21 . PC221), so the channel-2 reader read latches NE->RO when
699 * the channel-2 cycle is active (RET21) AND connector 2 is selected on channel
700 * 2 (PC221). RET21 is the channel-2 sync request RIA2 (mirror of RESI1 for ch-1).
701 * PC221 = !PC22A = PUC21 . ~PB26 (channel-2 unit selected, connector selector
702 * PB26=0 => connector 2). Both were stubbed to 0, which left the integrated
703 * reader selectable only on channel 1 (via PB12A); these light the channel-2
704 * path. Off for channel-1 ops (RIA2=0 / PUC2=0), so the channel-1 bootstrap is
705 * unaffected. */
706SIG(RET21) { return ge->RIA2; }
707SIG(PC221) { return !PC22A(ge); }
708
717SIG(PIB1A) { return !(RET21(ge) && PC211(ge)); }
718SIG(PIB11) { return !PIB1A(ge); }
719
720SIG(PB12A) { return !(RESI1(ge) && PC121(ge)); }
721SIG(PB22A) { return !(RET21(ge) && PC221(ge)); }
722SIG(PB32A) { return !(RES31(ge) && PC321(ge)); }
723SIG(PIB21) { return !(PB12A(ge) && PB22A(ge) && PB32A(ge)); }
724
725SIG(RB13A) { return !(RESI1(ge) && PC131(ge)); }
726SIG(RB33A) { return !(RES31(ge) && PC331(ge)); }
727SIG(PIB31) { return !(RB13A(ge) && RB33A(ge)); }
728
729SIG(RB14A) { return !(RESI1(ge) && PC141(ge)); }
730SIG(RB34A) { return !(RES31(ge) && PC341(ge)); }
731SIG(PIB41) { return !(RB14A(ge) && RB34A(ge)); }
732
741static inline uint16_t NE_knot(struct ge *ge) {
742 uint16_t ret = 0;
743 const char *where = "";
744
745 uint8_t count = PIB11(ge) + PIB21(ge) + PIB31(ge) + PIB41(ge);
746
747 if (count > 1) {
748 ge_log(LOG_PERI, "multiple input signals for NE knot (?!)\n");
749 }
750
751 if (PIB11(ge)) {
752 where = "PI";
753 ge_log(LOG_PERI, "TODO -- printer\n");
754 }
755
756 if (PIB21(ge)) {
757 where = "RI";
759 }
760
761 if (PIB31(ge)) {
762 where = "ST3";
763 ret = ge->ST3.data;
764 }
765
766 if (PIB41(ge)) {
767 where = "ST4";
768 ret = ge->ST4.data;
769 }
770
771 ge_log(LOG_PERI, "READING FROM NE KNOT %s --> %03x\n", where, ret);
772 return ret;
773}
774
775/* } */
776
785#define NAOR(a, b, c, d) !(a || b || c || d)
786
787SIG(RT111) { return 0; }
788
789SIG(RT311) { return 0; }
790SIG(RT321) { return 0; }
791SIG(RT331) { return 0; }
792
793SIG(RATE1) { return 0; }
794SIG(PUOO3) { return 0; }
795SIG(RUF31) { return 0; }
796SIG(RAVI1) { return 0; }
797
798SIG(TU10C) { return NAOR(RT111(ge), PC131(ge), RT311(ge), PC331(ge)); }
799SIG(TU20C) { return NAOR(RT121(ge), PC131(ge), RT321(ge), PC331(ge)); }
800SIG(TU30C) { return NAOR(RT131(ge), PC131(ge), RT331(ge), PC331(ge)); }
801SIG(AEBEC) { return !(RATE1(ge) && PC131(ge)); }
802SIG(AECO3) { return !PUOO3(ge); }
803SIG(FINUC) { return NAOR(RUF11(ge), PC131(ge), RUF31(ge), PC331(ge)); }
804SIG(PV13A) { return !(RAVI1(ge) && PC131(ge)); }
805SIG(VICU3) { return !(FINUC(ge) && PV13A(ge)); }
806/* } */
807
808#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:74
@ NS_RO1
Definition ge.h:79
@ NS_UA1
Definition ge.h:82
@ NS_UA2
Definition ge.h:81
@ NS_CN1
Definition ge.h:75
@ NS_CN2
Definition ge.h:76
@ NS_CN4
Definition ge.h:78
@ NS_CN3
Definition ge.h:77
@ NS_RO2
Definition ge.h:80
#define NAOR(a, b, c, d)
Definition signals.h:785
static uint16_t NI_knot(struct ge *ge)
NI Knot.
Definition signals.h:301
static uint8_t NI_source(struct ge *ge, enum knot_ni_source source)
Definition signals.h:257
static uint16_t NO_knot(struct ge *ge)
Knot driven by P0, V1, V2, V4, L1, R1, V3 and L3.
Definition signals.h:170
static uint8_t NA_knot(struct ge *ge)
Knot driven by SO or SI.
Definition signals.h:239
static uint16_t NE_knot(struct ge *ge)
NE Knot.
Definition signals.h:741
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:140
uint8_t connector_get_TE30(struct ge_connector *conn)
Definition reader.c:171
uint8_t reader_get_LU08(struct ge *ge)
Definition reader.c:127
uint8_t connector_get_MARE(struct ge_connector *conn)
Definition reader.c:153
uint8_t reader_get_FINI1(struct ge *ge)
Definition reader.c:147
uint8_t connector_get_TE10(struct ge_connector *conn)
Definition reader.c:159
uint8_t connector_get_TE20(struct ge_connector *conn)
Definition reader.c:165
uint8_t connector_get_FINE(struct ge_connector *conn)
Definition reader.c:177
#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:67
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:89
enum knot_ni_source ni2
Definition ge.h:87
enum knot_ni_source ni1
Definition ge.h:86
enum knot_ni_source ni3
Definition ge.h:88
uint8_t forcings
Definition ge.h:52
enum ge_knot_no::@1 force_mode
enum ge_knot_no::@2 cmd
The entire state of the emulated system, including registers, memory, peripherals and timings.
Definition ge.h:96
uint8_t RT121
Definition ge.h:537
uint8_t PB37
Definition ge.h:377
uint8_t AINI
Program Loading.
Definition ge.h:278
struct ge_integrated_reader integrated_reader
The I/O interface for the integrated reader (RI)
Definition ge.h:595
uint8_t JS2
Console jump condition 2.
Definition ge.h:367
struct ge_connector ST4
The I/O interface for the ST4 connector.
Definition ge.h:636
uint8_t ffFA
Special conditions register 2.
Definition ge.h:263
uint16_t rPO
Program addresser.
Definition ge.h:113
uint8_t PIC1
Selection Channel 1.
Definition ge.h:397
enum ge_console_rotary register_selector
The current state of the console register rotary switch.
Definition ge.h:551
uint8_t RIA0
Synchronous CPU Cycle Request.
Definition ge.h:500
uint8_t RIA2
Synchronous Channel 2 Cycle Request.
Definition ge.h:514
uint16_t rV1
Addresser for the first operand.
Definition ge.h:123
uint8_t rSO
Main sequencer.
Definition ge.h:220
uint16_t rRO
Multipurpose 8+1 bit register.
Definition ge.h:171
struct ge_counting_network counting_network
Definition ge.h:590
struct ge_console_switches console_switches
The current state of the console switches.
Definition ge.h:556
struct ge_connector ST3
The I/O interface for the ST3 connector.
Definition ge.h:631
uint8_t RIA3
Synchronous Channel 3 Cycle Request.
Definition ge.h:521
uint8_t PUC3
Channel 3 in transfer.
Definition ge.h:418
uint8_t rL2
Auxiliary register.
Definition ge.h:155
uint8_t PUC2
Channel 2 in transfer.
Definition ge.h:411
uint8_t rRI
Photoprint register 8-bit register used to store the photodisc codes.
Definition ge.h:146
uint16_t rBO
Default operator.
Definition ge.h:188
uint8_t PB06
Unconditionally stores L106.
Definition ge.h:373
struct ge_knot_ni kNI
Knot driven by counting network, or by the UA to store the result of the operation.
Definition ge.h:164
uint8_t RACI
Rejected Command.
Definition ge.h:532
uint8_t RT131
Definition ge.h:538
uint16_t rV4
Addresser for external instructions using channel 2.
Definition ge.h:126
uint8_t RASI
Channel 1 in transfer.
Definition ge.h:404
uint16_t rL1
Length of the operand.
Definition ge.h:154
uint8_t RUF1
Definition ge.h:423
uint8_t rSA
Future state configuration.
Definition ge.h:242
uint16_t rV2
Addresser for the second operand.
Definition ge.h:124
uint8_t RESI
Synchronous Channel 1 Cycle Request.
Definition ge.h:507
uint8_t RIG1
End from controller 1.
Definition ge.h:527
uint8_t rSI
Peripheral unit sequencer.
Definition ge.h:234
enum clock current_clock
Definition ge.h:98
uint8_t PB26
Stores L106 if channel 2 is selected.
Definition ge.h:375
uint16_t rL3
Length of operands involving channel 3.
Definition ge.h:156
uint8_t PB07
Unconditionally stores L106.
Definition ge.h:374
uint8_t RIG3
Definition ge.h:529
uint16_t rV3
Addresser for external instructions using channel 3.
Definition ge.h:125
uint8_t PB36
Definition ge.h:376
struct ge_knot_no kNO
Definition ge.h:158
uint8_t rFO
Current function code.
Definition ge.h:195
uint8_t JS1
Console jump condition 1.
Definition ge.h:366