GE-115 Emulator
An Emulator of the General Electrics GE-115 computer
msl-commands.c
Go to the documentation of this file.
1#include "ge.h"
2#include "log.h"
3#include "bit.h"
4#include "signals.h"
5#include "alu_logic.h"
6#include "alu_bin.h"
7#include "alu_dec.h"
8#include "alu_reg.h"
9#include "alu_cc.h"
10
11#ifndef MSL_COMMANDS_INCLUDED_BY_MSL_STATES
12# error This file should be include by msl-states.c and not compiled directly
13#endif
14
15#define CC { ge_log(LOG_ERR, "implement command %s\n", __FUNCTION__); }
16
17/* Commands To Load The Registers */
18/* ------------------------------ */
19
20static void CO00(struct ge* ge) { ge->rPO = NI_knot(ge); }
21static void CO01(struct ge* ge) { ge->rV1 = NI_knot(ge); }
22static void CO02(struct ge* ge) { ge->rV2 = NI_knot(ge); }
23static void CO03(struct ge* ge) { ge->rV3 = NI_knot(ge); }
24static void CO04(struct ge* ge) { ge->rV4 = NI_knot(ge); }
25
26static void CI00(struct ge* ge) { CO00(ge); }
27static void CI01(struct ge* ge) { CO01(ge); }
28static void CI02(struct ge* ge) { CO02(ge); }
29static void CI03(struct ge* ge) { CO03(ge); }
30static void CI04(struct ge* ge) { CO04(ge); }
31static void CI05(struct ge* ge) { ge->rL1 = NI_knot(ge); }
32static void CI06(struct ge* ge) { ge->rL2 = NI_knot(ge) & 0x00ff; }
33static void CI07(struct ge* ge) { ge->rL3 = NI_knot(ge); }
34static void CI08(struct ge* ge) { ge->rFO = (NI_knot(ge) & 0x00ff); }
35static void CI09(struct ge* ge) { ge->rRI = (NI_knot(ge) & 0xff00) >> 8; }
36
37/* NO Knot Selection Commands */
38/* -------------------------- */
39
40static void CO10(struct ge* ge) { ge->kNO.cmd = KNOT_PO_IN_NO; }
41static void CO11(struct ge* ge) { ge->kNO.cmd = KNOT_V1_IN_NO; }
42static void CO12(struct ge* ge) { ge->kNO.cmd = KNOT_V2_IN_NO; }
43static void CO13(struct ge* ge) { ge->kNO.cmd = KNOT_V3_IN_NO; }
44static void CO14(struct ge* ge) { ge->kNO.cmd = KNOT_V4_IN_NO; }
45static void CO16(struct ge* ge) { ge->kNO.cmd = KNOT_L2_IN_NO; }
46static void CO18(struct ge *ge) { ge->kNO.forcings = KNOT_FORCING_NO_21; }
47
48static void CI11(struct ge* ge) { CO11(ge); }
49static void CI12(struct ge* ge) { CO12(ge); }
50static void CI15(struct ge* ge) { ge->kNO.cmd = KNOT_L1_IN_NO; }
51static void CI16(struct ge* ge) { CO16(ge); }
52static void CI17(struct ge* ge) { ge->kNO.cmd = KNOT_L3_IN_NO; }
53static void CI19(struct ge* ge) { ge->kNO.force_mode = KNOT_FORCING_NO_43; }
54static void CI20(struct ge* ge) { ge->kNO.cmd = KNOT_AM_IN_NO; }
55static void CI21(struct ge* ge) { ge->kNO.cmd = KNOT_RI_IN_NO_43; }
56
57
58/* VO, BO, RO Loading Commands */
59/* --------------------------- */
60
61static void CO30(struct ge* ge) { ge->memory_command = MC_READ; }
62static void CO31(struct ge* ge) { ge->memory_command = MC_WRITE; }
63static void CO35(struct ge* ge) { /* "reset int. error"? (cpu fo. 105) */ }
64
65static void CI32(struct ge* ge) {
66 ge->rRO = NO_knot(ge) >> 8;
68}
69
70static void CI33(struct ge* ge) {
71 ge->rRO = NO_knot(ge) & 0x00ff;
73}
74
75static void CI34(struct ge* ge) {
76 ge->rRO = NE_knot(ge);
77}
78
79static void CI38(struct ge *ge)
80{
81 /* Enable set of aver & alto (cpu fo. 105) */
82 ge->AVER = verified_condition(ge);
83
84 /* (One) possible (ALTO) set condition (is): the ACOV or ACON
85 * switches are insterted, an the related condition is verified
86 * (cpu fo. 98) */
88 ge->ALTO = 1;
89
90 if (!ge->AVER && ge->console_switches.ACON)
91 ge->ALTO = 1;
92}
93
94static void CI39(struct ge *ge)
95{
96 /* Reset AVER, it also resets the FF AINI and PUC1 (cpu fo. 105) */
97 ge->AVER = 0;
98 ge->AINI = 0;
99 ge->PIC1 = 0;
100
101 /* intermediate fo. 10 B6 */
102 ge->RASI = 0;
103
104 if (!PUC1(ge))
105 ge->RC00 = 1;
106}
107
108/* Count And Arithmetical Unit Commands */
109/* ------------------------------------ */
110
111static void CO40(struct ge* ge) { ge->counting_network.cmds.decresing = 1; };
112static void CO41(struct ge* ge) { ge->counting_network.cmds.from_zero = 1; };
113static void CO48(struct ge* ge)
114{
115 /* most probably incorrect, "set urpe/urpu" (cpu fo. 106) */
116 ge->URPE = 1;
117 ge->URPU = 1;
118}
119
120static void CO49(struct ge* ge) {
121 /* most probably incorrect, "reset urpe/urpu" (cpu fo. 106) */
122 ge->URPE = 0;
123 ge->URPU = 0;
124};
125
126/* Instruction execution commands (hybrid: invoke the pure ALU helpers once,
127 * in the beta phase, using operands already fetched into V1/L1).
128 * These cover the PM/SI immediate-format ops: opcode, immediate(->L1), addr(->V1). */
129static uint16_t eff_v1_l2(struct ge* ge);
130static void EXEC_MVI(struct ge* ge) { alu_mvi(ge, eff_v1_l2(ge), ge->rL1 & 0xff); }
131static void EXEC_NI (struct ge* ge) { alu_ni (ge, eff_v1_l2(ge), ge->rL1 & 0xff); }
132static void EXEC_CI (struct ge* ge) { alu_oi (ge, eff_v1_l2(ge), ge->rL1 & 0xff); } /* CI 0x96 = OR Immediate */
133static void EXEC_CMI(struct ge* ge) { alu_ci (ge, eff_v1_l2(ge), ge->rL1 & 0xff); } /* CMI 0x95 = Compare Immediate */
134static void EXEC_XI (struct ge* ge) { alu_xi (ge, eff_v1_l2(ge), ge->rL1 & 0xff); }
135static void EXEC_TM (struct ge* ge) { alu_tm (ge, eff_v1_l2(ge), ge->rL1 & 0xff); }
136
137/* Change registers are memory-mapped, 16-bit big-endian, at addresses
138 * 240 + N*2 (N = 0..7). The register-op aux char (in L1) carries the 4-bit
139 * register code 1000..1111; the register index N = code & 7.
140 * NOTE: the code is assumed to sit in the LOW nibble of the aux char —
141 * verify against the funktionalcpu oracle. V1 holds the I1 memory address. */
142/* Register-op aux char format is 1XXX0000: bit 7 = 1, the register number is
143 * bits 4-6, low nibble 0 (confirmed against the funktionalcpu deck, step 0x37
144 * LR with aux 0xE0 -> register 6). N = (aux >> 4) & 7. */
145static uint16_t reg_addr_of(struct ge* ge) { return (uint16_t)(240 + ((ge->rL1 >> 4) & 0x07) * 2); }
146static uint16_t cr_rd16(struct ge* ge, uint16_t a) {
147 return (uint16_t)((ge->mem[a] << 8) | ge->mem[(uint16_t)(a + 1)]);
148}
149static void cr_wr16(struct ge* ge, uint16_t a, uint16_t v) {
150 ge_mem_store8(ge, a, (uint8_t)(v >> 8));
151 ge_mem_store8(ge, (uint16_t)(a + 1), (uint8_t)(v & 0xff));
152 /* cr_wr16 is the register-instruction write path (LR/LA/AMR/SMR/JRT, always
153 * to a change-register slot 240+2N). Keep the addressing cache in sync here
154 * so a register instruction updates live addressing — but a GENERAL memory
155 * write to 0xF0-0xFF (e.g. a destructive memory test) does NOT, leaving
156 * addressing intact. See struct ge::cr_cache. */
157 if (a >= 240 && a <= 254 && !(a & 1))
158 ge->cr_cache[(a - 240) >> 1] = v;
159}
160
161/* Register-op MEMORY operand: the instruction address (V1) points to the
162 * RIGHTMOST (low) byte; the 16-bit value occupies [addr-1 .. addr] (the
163 * LR-AMR-SMR-CMR-STR microcode reads V2 DOWNWARD, V2-1->V2). Confirmed by
164 * funktionalcpu step 0x37: LR cr6 <- mem[0x0621..0x0622], verified by the
165 * CMC against the saved copy. (The change-register storage at 240+2N is the
166 * other way -- high byte first -- handled by cr_rd16/cr_wr16.) */
167static uint16_t mem_rd16_op(struct ge* ge, uint16_t a) {
168 return (uint16_t)((ge->mem[(uint16_t)(a - 1)] << 8) | ge->mem[a]);
169}
170static void mem_wr16_op(struct ge* ge, uint16_t a, uint16_t v) {
171 ge_mem_store8(ge, (uint16_t)(a - 1), (uint8_t)(v >> 8));
172 ge_mem_store8(ge, a, (uint8_t)(v & 0xff));
173}
174
175/* Address modification — bit 15 = absolute/modified flag (CPU[4] §2.5, FO.19-20;
176 * flow chart dwg 14023130, transcribed in reference_operand_fetch_flowchart).
177 *
178 * Every operand address field carries the modify flag in bit 15:
179 * bit 15 = 0 ABSOLUTE: bits 0-14 are the address directly (0..0x7FFF); the
180 * change registers are NOT consulted.
181 * bit 15 = 1 MODIFIED: bits 12-14 select one of the 8 change registers and
182 * EA = change_register[N] + (bits 0-11 displacement), 16-bit wrap.
183 *
184 * The GE-130 resolves this *during operand fetch*: an absolute field is left in
185 * V verbatim (bit 15 = 0, so V < 0x8000); a modified field is reduced to its
186 * 12-bit displacement (top quartet zeroed) in V and the change register is then
187 * added by the indexing micro-cycle ED|EC -> EF|EE (EXEC_INDEX below), which
188 * leaves the resolved EA in V2 and (for the first operand, SA00) copies it to V1.
189 * So after fetch the operand registers hold the RESOLVED effective address and
190 * execution uses them directly — eff_v1_l2 / CI00s / EXEC_SS just mask to the
191 * 15-bit address space. The change registers live at mem[240+2N] and default to
192 * base[N] = N<<12 at reset (ge_clear); programs reload a base via LR/LA/AMR. */
193
194/* Read change register N for modified-address resolution. Reads the hardware
195 * CACHE (cr_cache), not the mem[240+2N] shadow RAM, so a destructive memory test
196 * writing 0xF0-0xFF does not corrupt live addressing. The cache is kept in sync
197 * with register-instruction writes by cr_wr16 and seeded by ge_seed_segment_bases. */
198static uint16_t cr_base(struct ge* ge, int n) {
199 return ge->cr_cache[n & 7];
200}
201
202/* Effective V1 for single-address PM/SI ops: V1 already holds the resolved EA
203 * (absolute field, or change_register+displacement after the indexing cycle). */
204static uint16_t eff_v1_l2(struct ge* ge) { return ge->rV1 & 0x7FFFu; }
205
206/* Jump target: NI re-assembles the resolved target field at TI05 (for a modified
207 * jump it was resolved into V2 by the indexing cycle). Mask to the address space. */
208static void CI00s(struct ge* ge) {
209 ge->rPO = NI_knot(ge) & 0x7FFFu;
210}
211
212/* Modified-address indexing (flow chart ED|EC, the low-byte add, fused with the
213 * EF|EE high-byte/carry add into one hybrid step). The displacement sits in
214 * V2 bits 0-11 (top quartet was zeroed during the high-byte read for a modified
215 * address); the modifier N is L2 bits 4-6 (= address bits 12-14, since L2 holds
216 * the current operand's addr-hi byte). EA = change_register[N] + displacement,
217 * 16-bit wrap (carry beyond word 2 lost). The resolved EA is written to V2 and,
218 * for the first operand (SA00), copied to V1. */
219static void EXEC_INDEX(struct ge* ge) {
220 uint8_t n = (ge->rL2 >> 4) & 7;
221 uint16_t disp = ge->rV2 & 0x0FFFu;
222 uint16_t ea = (uint16_t)(cr_base(ge, n) + disp);
223 ge->rV2 = ea;
224 if (ge->SA00)
225 ge->rV1 = ea;
226}
227
228/* Index-cycle sequencing helpers (explicit future-state forcing, like
229 * SS_TO_ALPHA — see msl-states.c for the routing). */
230static void INDEX_OP1(struct ge* ge) { ge->SA00 = 1; ge->future_state = 0xec; }
231static void INDEX_OP2(struct ge* ge) { ge->SA00 = 0; ge->future_state = 0xec; }
232static void INDEX_NEXT(struct ge* ge) { ge->future_state = 0xee; }
233
234static void EXEC_LR (struct ge* ge) { cr_wr16(ge, reg_addr_of(ge), mem_rd16_op(ge, eff_v1_l2(ge))); }
235static void EXEC_STR(struct ge* ge) { mem_wr16_op(ge, eff_v1_l2(ge), cr_rd16(ge, reg_addr_of(ge))); }
236static void EXEC_LA (struct ge* ge) { cr_wr16(ge, reg_addr_of(ge), eff_v1_l2(ge)); }
237/* LPSR instruction (0x9d): load the PSR (status + PO) from its operand by
238 * entering the shared C-sequence (C2->C3->C0->C1), exactly like the interrupt
239 * restore but reading from the instruction's address operand (V1) instead of
240 * the interrupt-save area 0x0304. Per the LPSR flowchart: alpha -> 64|65 -> C2. */
241static void EXEC_LPSR(struct ge* ge) { ge->rV1 = eff_v1_l2(ge); ge->future_state = 0xc2; }
242/* JRT (Jump Return, op 0x41): deposits the address of the subsequent instruction
243 * (rPO before the jump rewrites it at TI05/CI00s) into index register 7
244 * (mem 254/255). Unconditional, per CPU[4] sec.5.5.6.2 / 5.6.5.1: the link is
245 * reserved even when the conditional form does not take the jump. */
246static void JRT_LINK(struct ge* ge) { cr_wr16(ge, 254, ge->rPO); }
248static void EXEC_AMR(struct ge* ge) { uint16_t r = cr_rd16(ge, reg_addr_of(ge)); alu_amr(ge, &r, mem_rd16_op(ge, eff_v1_l2(ge))); cr_wr16(ge, reg_addr_of(ge), r); }
249static void EXEC_SMR(struct ge* ge) { uint16_t r = cr_rd16(ge, reg_addr_of(ge)); alu_smr(ge, &r, mem_rd16_op(ge, eff_v1_l2(ge))); cr_wr16(ge, reg_addr_of(ge), r); }
250
251/* SS (Storage-to-Storage) data-op execution commands (Wave 5 / Mechanism B).
252 *
253 * EXEC_SS fires from state_E7 at TI06, after CI02 at TI05 has loaded V2
254 * (source address) and V1 (destination address) was already set by the
255 * preceding E5 pass. SS_TO_ALPHA then overrides the future state to
256 * 0xe2 (alpha), breaking out of the operand-fetch micro-loop.
257 *
258 * Operand layout at TI06 of state_E7:
259 * V1 = destination address
260 * V2 = source address
261 * L1 = length byte
262 *
263 * Single-length ops (MVC/NC/OC/XC/CMC/TL/UPK/PK/EDT):
264 * len = (rL1 & 0xff) + 1
265 *
266 * Two-length decimal ops (AP/SP/MP/DP/MVP/CMP/PKS/UPKS):
267 * alen = ((rL1 >> 4) & 0xf) + 1 (high nibble + 1)
268 * blen = (rL1 & 0xf) + 1 (low nibble + 1)
269 */
270static void EXEC_SS(struct ge *ge)
271{
272 uint16_t len = (uint16_t)((ge->rL1 & 0xff) + 1); /* up to 256 (LL=0xff); must not be uint8_t */
273 uint8_t alen = ((ge->rL1 >> 4) & 0xf) + 1;
274 uint8_t blen = (ge->rL1 & 0x0f) + 1;
275 /* SS effective addresses: V1 (dest) and V2 (src) already hold the resolved
276 * effective address after operand fetch (absolute field verbatim, or
277 * change_register+displacement via the indexing micro-cycle). Mask to the
278 * 15-bit address space. */
279 uint16_t dst = ge->rV1 & 0x7FFFu;
280 uint16_t src = ge->rV2 & 0x7FFFu;
281
282 switch (ge->rFO) {
283 case MVC_OPCODE:
284 alu_mvc(ge, dst, src, len);
285 break;
286 case NC_OPCODE:
287 alu_nc(ge, dst, src, len);
288 break;
289 case OC_OPCODE:
290 alu_oc(ge, dst, src, len);
291 break;
292 case XC_OPCODE:
293 alu_xc(ge, dst, src, len);
294 break;
295 case CMC_OPCODE:
296 alu_cmc(ge, dst, src, len);
297 break;
298 case TL_OPCODE:
299 alu_tl(ge, dst, len, src);
300 break;
301 case UPK_OPCODE:
302 alu_upk(ge, dst, len-1, src, len-1);
303 break;
304 case PK_OPCODE:
305 alu_pk(ge, dst, len-1, src, len-1);
306 break;
307 case EDT_OPCODE:
308 alu_edt(ge, dst, len, src);
309 break;
310 case MVP_OPCODE:
311 alu_mvp(ge, dst, alen-1, src, blen-1);
312 break;
313 case CMP_OPCODE:
314 alu_cmp(ge, dst, alen-1, src, blen-1);
315 break;
316 case AP_OPCODE:
317 alu_ap(ge, dst, alen-1, src, blen-1);
318 break;
319 case SP_OPCODE:
320 alu_sp(ge, dst, alen-1, src, blen-1);
321 break;
322 case MP_OPCODE:
323 alu_mp(ge, dst, alen-1, src, blen-1);
324 break;
325 case DP_OPCODE:
326 alu_dp(ge, dst, alen-1, src, blen-1);
327 break;
328 case PKS_OPCODE:
329 alu_pks(ge, dst, alen-1, src, blen-1);
330 break;
331 case UPKS_OPCODE:
332 alu_upks(ge, dst, alen-1, src, blen-1);
333 break;
334 case AB_OPCODE:
335 alu_ab(ge, dst, alen, src, blen);
336 break;
337 case SB_OPCODE:
338 alu_sb(ge, dst, alen, src, blen);
339 break;
340 case AD_OPCODE:
341 alu_ad(ge, dst, alen, src, blen);
342 break;
343 case SD_OPCODE:
344 alu_sd(ge, dst, alen, src, blen);
345 break;
346 /* MVQ/CMQ are part of the AB-SB-AD-SD-MVQ-CMQ microcode family, whose
347 * field length is governed by the L1.2 counter (= the high-nibble
348 * length, alen), not the full L1 byte. funktionalcpu step 0x1B
349 * (MVQ 2,0x0531,0x0533 with L1=0x01) moves only alen=1 byte. */
350 case MVQ_OPCODE:
351 alu_mvq(ge, dst, src, alen);
352 break;
353 case CMQ_OPCODE:
354 alu_cmq(ge, dst, src, alen);
355 break;
356 /* Search Right/Left (SR=0xD9, SL=0xDB), SS1 format "SR len, A1, A2":
357 * A1 (V1=dst) = leftmost byte of the search field
358 * A2 (V2=src) = address of the 1-byte model to search for
359 * result address -> change/segment register 7 (mem[0xFE..0xFF], BE)
360 * The result-register location is confirmed by the funktionalcpu deck
361 * (the instruction following SR at 0x03dc reads mem[0x00FE]); the
362 * model-byte source (mem[A2]) is the best-supported reading of the
363 * SS1 two-address form and remains MEDIUM confidence pending the
364 * search-instruction page image (docs/ISA.md §6.10). */
365 case SR_OPCODE: {
366 uint16_t r7 = (uint16_t)((ge->mem[0xFE] << 8) | ge->mem[0xFF]);
367 alu_sr(ge, &r7, dst, len, ge->mem[src]);
368 ge_mem_store8(ge, 0xFE, (uint8_t)(r7 >> 8));
369 ge_mem_store8(ge, 0xFF, (uint8_t)(r7 & 0xFF));
370 break;
371 }
372 case SL_OPCODE: {
373 uint16_t r7 = (uint16_t)((ge->mem[0xFE] << 8) | ge->mem[0xFF]);
374 alu_sl(ge, &r7, dst, len, ge->mem[src]);
375 ge_mem_store8(ge, 0xFE, (uint8_t)(r7 >> 8));
376 ge_mem_store8(ge, 0xFF, (uint8_t)(r7 & 0xFF));
377 break;
378 }
379 default:
380 ge_log(LOG_ERR, "EXEC_SS: unknown SS opcode 0x%02x\n", ge->rFO);
381 break;
382 }
383}
384
385/* Force future state to alpha (0xe2).
386 * Must be placed AFTER the regular CU commands in state_E7 so it wins. */
387static void SS_TO_ALPHA(struct ge *ge)
388{
389 ge->future_state = 0xe2;
390}
391
392/* EPER "examine abnormal conditions": load the channel-1 peripheral status
393 * into RO so the qualitative-result decode (DU95 = !RO1 && !RO2 && RO6 = "no
394 * error") reflects the real status. Our integrated-reader feed is always
395 * clean (no parity/format error; CE02 even ignores the parity check), so the
396 * status is no-error: RO6 set, error bits (RO1/RO2) clear. A real error would
397 * be reported here once error injection is modelled. */
398static void CE_chan1_status(struct ge *ge)
399{
400 /* Default: RO6=1 (operation OK), RO1=RO2=0 (no error) -> DU95=1 ("no
401 * error"). When inject_chan1_status is non-zero a test/harness is injecting
402 * an abnormal condition: report that status byte instead (e.g. 0x42 sets
403 * RO1, so DU95 reads "error" and the EPER examine branch fires). */
405}
406
407static void CI40(struct ge *ge) { CO40(ge); }
408static void CI41(struct ge *ge) { CO41(ge); }
409
410
411/* NI Knot Selection Commands */
412/* -------------------------- */
413
414static void CI60(struct ge *ge) { ge->kNI.ni4 = NS_RO2; }
415static void CI61(struct ge *ge) { ge->kNI.ni3 = NS_RO2; }
416static void CI62(struct ge *ge) { ge->kNI.ni2 = NS_RO2; }
417static void CI63(struct ge *ge) { ge->kNI.ni1 = NS_RO2; }
418static void CI64(struct ge *ge) { ge->kNI.ni4 = NS_RO1; }
419static void CI65(struct ge *ge) { ge->kNI.ni3 = NS_RO1; }
420static void CI66(struct ge *ge) { ge->kNI.ni2 = NS_RO1; }
421static void CI67(struct ge *ge) { ge->kNI.ni1 = NS_RO1; }
422static void CI68(struct ge *ge) { ge->kNI.ni4 = NS_UA2; ge->kNI.ni3 = NS_UA1; }
423static void CI69(struct ge *ge) { ge->kNI.ni2 = NS_UA2; ge->kNI.ni1 = NS_UA1; }
424
425/* Commands To Set And Reset FF Of Condition */
426/* ----------------------------------------- */
427
428static void CI70(struct ge* ge) { SET_BIT(ge->ffFI, 0); }
429static void CI71(struct ge* ge) { SET_BIT(ge->ffFI, 1); }
430static void CI72(struct ge* ge) { SET_BIT(ge->ffFI, 2); }
431static void CI73(struct ge* ge) { SET_BIT(ge->ffFI, 3); }
432static void CI74(struct ge* ge) { SET_BIT(ge->ffFI, 4); }
433static void CI75(struct ge* ge) { SET_BIT(ge->ffFI, 5); }
434static void CI76(struct ge* ge) { SET_BIT(ge->ffFI, 6); }
435static void CI77(struct ge* ge) { ge->ADIR = 1; }
436static void CI78(struct ge* ge) { ge->ADIR = 0; }
437static void CI80(struct ge* ge) { RESET_BIT(ge->ffFI, 0); }
438static void CI81(struct ge* ge) { RESET_BIT(ge->ffFI, 1); }
439static void CI82(struct ge* ge) { RESET_BIT(ge->ffFI, 2); }
440static void CI83(struct ge* ge) { RESET_BIT(ge->ffFI, 3); }
441static void CI84(struct ge* ge) { RESET_BIT(ge->ffFI, 4); }
442static void CI85(struct ge* ge) { RESET_BIT(ge->ffFI, 5); }
443static void CI86(struct ge* ge) { RESET_BIT(ge->ffFI, 6); }
444
445static void CI87(struct ge* ge) {
446 ge->ALAM = 1;
447 ge->PODI = 1; /* should PODI be set here? */
448}
449
450static void CI88(struct ge* ge) {
451 ge->ALAM = 0;
452 ge->PODI = 0; /* should PODI be set here? */
453}
454
455static void CI89(struct ge* ge) { ge->ALTO = 1; ge->halted = 1; }
456
457/* Commands To Force In NO Knot */
458/* ---------------------------- */
459
460static void CO90(struct ge *ge) { SET_BIT(ge->kNO.forcings, 0); }
461static void CO91(struct ge *ge) { SET_BIT(ge->kNO.forcings, 1); }
462static void CO92(struct ge *ge) { SET_BIT(ge->kNO.forcings, 2); }
463static void CO93(struct ge *ge) { SET_BIT(ge->kNO.forcings, 3); }
464static void CO94(struct ge *ge) { SET_BIT(ge->kNO.forcings, 4); }
465static void CO95(struct ge *ge) { SET_BIT(ge->kNO.forcings, 5); }
466static void CO96(struct ge *ge) { SET_BIT(ge->kNO.forcings, 6); }
467static void CO97(struct ge *ge) { SET_BIT(ge->kNO.forcings, 7); }
468
469/* Commands For External Operations */
470/* -------------------------------- */
471
472static void CE00(struct ge* ge) {
473 /* is PIPO needed?! (intermediate fo. 10 A1*/
474 ge_log(LOG_PERI, "RA <- %x\n", ge->rRO);
475 ge->rRA = ge->rRO;
476}
477
478static void CE01(struct ge* ge) {
479 /* is PIPO needed?! (intermediate fo. 10 A1*/
480 ge_log(LOG_PERI, "RE <- %x\n", ge->rRO);
481 ge->rRE = ge->rRO;
482}
483
484static void CE02(struct ge* ge) {
485 /* admits AEBE: */
486 /* UNIV 1.2µs --> RATE1 nand PC131 --> AEBE */
487 /* AEBE is a control signal sent to ST3 and ST4 */
488
489 /* Unconditionally set by command CE02 (cpu fo. 235) */
490 ge->PIC1 = 1;
491
492 /* Latch PB flip flops (intermediate diagram fo. 9 D 1,2,3) */
493 ge->PB06 = BIT(ge->rL1, 6);
494 ge->PB07 = BIT(ge->rL1, 7);
495
496 /* In case of initial load / TPER, L2 here should be the Z character of
497 * the instructions. It encodes the channel to be used for the transfer.
498 *
499 * If bit 0 of L2 is 0, channel is either 1 or 3,
500 * if bit 0 of L2 is 1, channel is 2.
501 *
502 * (cpu fo. 73)
503 */
504 if (BIT(ge->rL2, 0))
505 ge->PB26 = BIT(ge->rL1, 6);
506
507 if (PC031(ge)) {
508 ge->PB36 = BIT(ge->rL1, 6);
509 ge->PB37 = BIT(ge->rL1, 7);
510 }
511
512 /* parity check ignored */
513}
514
515static void CE03(struct ge *ge) {
516 /* reset IO */
517 uint8_t CE031 = 1;
518 uint8_t TO191 = ge->current_clock == TO19;
519 uint8_t TO651 = ge->current_clock == TO65;
520 uint8_t RECIA = !(CE031 && PC011(ge));
521 uint8_t RECI1 = !RECIA;
522
523 ge_log(LOG_PERI, "RESET I/U (CE03)\n");
524
525 if (TO651 && RECI1) {
526 ge->RIG1 = 0;
527 ge_log(LOG_PERI, "RESETTING RIG1 (CE03)\n", ge->RIG1);
528 } else {
529 ge_log(LOG_PERI, "NOT RESETTING RIG1 (CE03)\n");
530 }
531
532 if (TO191) {
533 ge->RACI = 0;
534 ge_log(LOG_PERI, "RESETTING RACI (CE03)\n");
535 } else {
536 ge_log(LOG_PERI, "NOT RESETTING RACI (CE03)\n");
537 }
538
539 /* maybe more? */
540}
541
542static void CE05(struct ge* ge) {
543 ge_log(LOG_PERI, "TODO: enable selection external error\n");
544}
545
546static void CE06(struct ge *ge) {
547 /* enable set error 1 */
548}
549
550static void CE07(struct ge *ge) {
551 /* set io for can 1, 2 or 3 */
552 uint8_t TO191 = ge->current_clock == TO19;
553
554 if (TO191 && PC011(ge)) {
555 ge->RASI = 1;
556 ge_log(LOG_PERI, "SET RASI (CE07)\n");
557 } else {
558 ge_log(LOG_PERI, "NOT SETTING RASI (CE07)\n");
559 }
560
561 if (TU00A(ge)) {
562 ge_log(LOG_PERI, "TU00A! %d\n", TU00A(ge));
563 }
564}
565
566static void CE08(struct ge *ge) {
567 /* Set VICU.
568 *
569 * The CPU docs tie CE08 to the VICU-support path: TO19 + RETO sets RAVI
570 * (indexed as RAV12), and the later RB111 timing edge stores RACI.
571 * gemu models that latch pair directly even though the wider VICU
572 * ecosystem is still only partially implemented. */
573 uint8_t TO191 = ge->current_clock == TO19;
574
575 ge_log(LOG_PERI, "SET VICU (CE08)\n");
576
577 if (TO191 && ge->RETO) {
578 ge->RAVI = 1;
579 ge_log(LOG_PERI, "SET RAVI (CE08)\n");
580 } else {
581 ge_log(LOG_PERI, "NOT SETTING RAVI (CE08)\n");
582 }
583
584 if (ge->RAVI && RB111(ge)) {
585 ge->RACI = 1;
586 ge_log(LOG_PERI, "SET RACI (CE08)\n");
587 } else {
588 ge_log(LOG_PERI, "NOT SETTING RACI (CE08)\n");
589 }
590}
591
592static void CE09(struct ge *ge) {
593 /* character request */
594
595 /* emits TU101: */
596 /* UNIV 1.2µs --> RT111 */
597
598 uint8_t RT111 = 1;
599
600 /* intermediate fo 14 D3 */
601 uint8_t TU03A = !(RT111 && PC121(ge));
602 uint8_t TU03 = !TU03A;
603
604 if (TU03)
606}
607
608/* CE16 — "Carica Buffer Stampante / Load Printer Buffer" (channel-2 OUTPUT, rSI
609 * transfer state 02/03; flow chart 14023130₁, CPU[7] render-pg 36). Hands the
610 * character just read from memory into RO to the integrated printer over the
611 * channel-2 output line. The printer sink renders it through the GE graphic set.
612 * No-op if no channel-2 sink is attached. */
613static void CE16(struct ge *ge) {
614 channel_accept_output(ge, &ge->channel2, (uint8_t)(ge->rRO & 0xff));
615}
616
617static void CE10(struct ge *ge) {
618 /* send command */
619
620 /* emits TU201: UNIV 1.2µs --> RT121 */
621 ge->RT121 = 1;
622
623 /* UNIV seems a delay line to synchronise the hardware, let's
624 * ignore the exact timings. */
626}
627
628static void CE11(struct ge* ge) {
629 ge->RT131 = 1;
630
631 /* UNIV seems a delay line to synchronise the hardware, let's
632 * ignore the exact timings. */
633
634 /* ad hoc logic, this should be conditioned by TU30C and TU30D
635 * (intermediate fo 14, B4 B5) to send the command only to the
636 * specified units, but the signals don't fully work here */
637
638 if (PC131(ge))
640
641 if (PC141(ge))
643}
644
645static void CE18(struct ge *ge) {
646 /* enable reset RIAP */
647 ge_log(LOG_PERI, "RESET RIAP\n");
648
649 uint8_t TO801 = ge->current_clock == TO80;
650
651 if (TO801 && RIUC(ge)) {
652 ge->RC00 = 0;
653 ge_log(LOG_PERI, "RESETING RC00 (CE18)\n");
654 } else {
655 ge_log(LOG_PERI, "NOT RESETING RC00 (CE18)\n");
656 }
657
658 if (TO801 && RESI(ge)) {
659 ge->RC01 = 0;
660 ge_log(LOG_PERI, "RESETING RC01 (CE18)\n");
661 } else {
662 ge_log(LOG_PERI, "NOT RESETING RC01 (CE18)\n");
663 }
664
665 if (TO801 && RES2(ge)) {
666 ge->RC02 = 0;
667 ge_log(LOG_PERI, "RESETING RC02 (CE18)\n");
668 } else {
669 ge_log(LOG_PERI, "NOT RESETING RC02 (CE18)\n");
670 }
671
672 if (TO801 && RES3(ge)) {
673 ge->RC03 = 0;
674 ge_log(LOG_PERI, "RESETING RC03 (CE18)\n");
675 } else {
676 ge_log(LOG_PERI, "NOT RESETING RC03 (CE18)\n");
677 }
678}
679
680static void CE19(struct ge *ge) {
681 /* reset selection can 3 */
682}
683
684
685/* Future States Commands */
686/* ---------------------- */
687
688/* Set S0 */
689static void CU00(struct ge* ge) { SET_BIT(ge->future_state, 0); }
690static void CU01(struct ge* ge) { SET_BIT(ge->future_state, 1); }
691static void CU02(struct ge* ge) { SET_BIT(ge->future_state, 2); }
692static void CU03(struct ge* ge) { SET_BIT(ge->future_state, 3); }
693static void CU04(struct ge* ge) { SET_BIT(ge->future_state, 4); }
694static void CU05(struct ge* ge) { SET_BIT(ge->future_state, 5); }
695static void CU06(struct ge* ge) { SET_BIT(ge->future_state, 6); }
696static void CU07(struct ge* ge) { SET_BIT(ge->future_state, 7); }
697
698/* Reset S0 */
699static void CU10(struct ge* ge) { RESET_BIT(ge->future_state, 0); }
700static void CU11(struct ge* ge) { RESET_BIT(ge->future_state, 1); }
701static void CU12(struct ge* ge) { RESET_BIT(ge->future_state, 2); }
702static void CU13(struct ge* ge) { RESET_BIT(ge->future_state, 3); }
703static void CU14(struct ge* ge) { RESET_BIT(ge->future_state, 4); }
704static void CU15(struct ge* ge) { RESET_BIT(ge->future_state, 5); }
705static void CU16(struct ge* ge) { RESET_BIT(ge->future_state, 6); }
706static void CU17(struct ge* ge) { RESET_BIT(ge->future_state, 7); }
707
708static void CU20(struct ge *ge) {
709 ge->rSO = ge->rSI = ge->future_state;
710 ge_log(LOG_FUTURE, "forcing state with CU20: %2x\n", ge->future_state);
711}
712
713/* Interruption routine (flow chart 14023130C, CPU[7] render-pg 26) + the LPSR
714 * load it chains into (14023130D, render-pg 27).
715 *
716 * Entered from alpha (e2/e3) when INTE = RINT & /MASC: the state graph is
717 * F0 -> D2 -> D3 -> D0 -> D1 -> C2 -> C3 -> C0 -> C1 -> alpha
718 * F0..D1 SAVE the current Program Status Register (PSR) to the fixed store at
719 * 0x0300; C2..C1 are the LPSR sequence that LOADS the new PSR from 0x0304 and
720 * resumes at its PO (the handler). The PSR is 4 bytes (CPU[4] PSR diagram):
721 * byte0 = status: bit5<-FI04, bit4<-FI05, bit0<-FI06 (FA = latched FI)
722 * byte1 = 0
723 * byte2 = PO high (bits 8-15)
724 * byte3 = PO low (bits 0-7)
725 * Implemented as hybrid one-shot commands at TI06 (the established gemu idiom;
726 * the per-clock datapath is not transcribed). V1 walks the store; the states
727 * are otherwise inert. See docs/flowchart-sheets.md. */
728static uint8_t int_parity(uint8_t b) { return (__builtin_popcount(b) & 1) ? 0 : 1; }
729static void int_store(struct ge *ge, uint16_t a, uint8_t b) {
730 ge->mem[a] = b;
731 ge->mem_parity[a] = int_parity(b);
732 ge->mem_written[a] = 1;
733}
734
735/* F0: build the save address (0x0300) into V1; acknowledge the request. */
736static void INT_F0(struct ge *ge) {
737 ge->rV1 = 0x0300; /* "Set N009-08 / 0i->NO2,1 / Res N010-15 / NO->V1" */
738 ge->RINT = 0; /* acknowledge: clear the request so we don't re-enter */
739 ge->future_state = 0xd2;
740}
741/* D2: store the status byte (FA04->b5, FA05->b4, FA06->b0). */
742static void INT_D2(struct ge *ge) {
743 uint8_t st = (uint8_t)((BIT(ge->ffFA, 4) << 5) |
744 (BIT(ge->ffFA, 5) << 4) |
745 (BIT(ge->ffFA, 6) << 0));
746 int_store(ge, ge->rV1, st);
747 ge->rV1++;
748 ge->future_state = 0xd3;
749}
750/* D3: store the zero byte. */
751static void INT_D3(struct ge *ge) {
752 int_store(ge, ge->rV1, 0x00);
753 ge->rV1++;
754 ge->future_state = 0xd0;
755}
756/* D0: store PO high byte (PO4,3). */
757static void INT_D0(struct ge *ge) {
758 int_store(ge, ge->rV1, (uint8_t)(ge->rPO >> 8));
759 ge->rV1++;
760 ge->future_state = 0xd1;
761}
762/* D1: store PO low byte (PO2,1) -> then to LPSR (C2). */
763static void INT_D1(struct ge *ge) {
764 int_store(ge, ge->rV1, (uint8_t)(ge->rPO & 0xff));
765 ge->rV1++;
766 ge->future_state = 0xc2;
767}
768/* C2 (LPSR): load the new status byte, restore FI04/05/06. */
769static void INT_C2(struct ge *ge) {
770 uint8_t st = ge->mem[ge->rV1];
771 if (BIT(st, 5)) SET_BIT(ge->ffFI, 4); else RESET_BIT(ge->ffFI, 4);
772 if (BIT(st, 4)) SET_BIT(ge->ffFI, 5); else RESET_BIT(ge->ffFI, 5);
773 if (BIT(st, 0)) SET_BIT(ge->ffFI, 6); else RESET_BIT(ge->ffFI, 6);
774 ge->rV1++;
775 ge->future_state = 0xc3;
776}
777/* C3 (LPSR): skip the zero byte. */
778static void INT_C3(struct ge *ge) {
779 ge->rV1++;
780 ge->future_state = 0xc0;
781}
782/* C0 (LPSR): load the new PO high byte. */
783static void INT_C0(struct ge *ge) {
784 ge->rPO = (uint16_t)((ge->mem[ge->rV1] << 8) | (ge->rPO & 0x00ff));
785 ge->rV1++;
786 ge->future_state = 0xc1;
787}
788/* C1 (LPSR): load the new PO low byte -> resume in alpha at the handler. */
789static void INT_C1(struct ge *ge) {
790 ge->rPO = (uint16_t)((ge->rPO & 0xff00) | ge->mem[ge->rV1]);
791 ge->future_state = 0xe2;
792}
void alu_ad(struct ge *ge, uint16_t a_addr, uint8_t a_len, uint16_t b_addr, uint8_t b_len)
AD – Add Decimal (opcode 0xFA).
Definition alu_bin.c:200
void alu_sb(struct ge *ge, uint16_t a_addr, uint8_t a_len, uint16_t b_addr, uint8_t b_len)
SB – Subtract Binary (opcode 0xFF).
Definition alu_bin.c:118
void alu_sd(struct ge *ge, uint16_t a_addr, uint8_t a_len, uint16_t b_addr, uint8_t b_len)
SD – Subtract Decimal (opcode 0xFB).
Definition alu_bin.c:249
void alu_ab(struct ge *ge, uint16_t a_addr, uint8_t a_len, uint16_t b_addr, uint8_t b_len)
AB – Add Binary (opcode 0xFE).
Definition alu_bin.c:68
Binary and decimal (unpacked) arithmetic helpers for the GE-120/130.
void alu_mvp(struct ge *ge, uint16_t a, uint8_t alen, uint16_t b, uint8_t blen)
MVP 0xE8 Move Packed: op1 = op2 (sign preserved from op2); CC set.
Definition alu_dec.c:614
void alu_sp(struct ge *ge, uint16_t a, uint8_t alen, uint16_t b, uint8_t blen)
SP 0xEB Subtract Packed: op1 = op1 - op2; CC set.
Definition alu_dec.c:324
void alu_upks(struct ge *ge, uint16_t dst, uint8_t dlen, uint16_t src, uint8_t slen)
UPKS 0xEF Unpack with Sign: packed op2 → zoned op1; zone always 0x4.
Definition alu_dec.c:804
void alu_upk(struct ge *ge, uint16_t dst, uint8_t dlen, uint16_t src, uint8_t slen)
UPK 0xD8 Unpack: packed op2 → zoned op1 (no sign processing; zone of each result byte is taken from t...
Definition alu_dec.c:728
void alu_pks(struct ge *ge, uint16_t dst, uint8_t dlen, uint16_t src, uint8_t slen)
PKS 0xEE Pack with Sign: zoned op2 → packed op1; sign from zone of rightmost source byte (zone 0xA → ...
Definition alu_dec.c:761
void alu_mp(struct ge *ge, uint16_t a, uint8_t alen, uint16_t b, uint8_t blen)
MP 0xEC Multiply Packed: op1 = op1 * op2; CC set.
Definition alu_dec.c:358
void alu_cmp(struct ge *ge, uint16_t a, uint8_t alen, uint16_t b, uint8_t blen)
CMP 0xE9 Compare Packed (algebraic, no operand change); CC set.
Definition alu_dec.c:559
void alu_pk(struct ge *ge, uint16_t dst, uint8_t dlen, uint16_t src, uint8_t slen)
PK 0xDA Pack: zoned op2 → packed op1 (no sign processing).
Definition alu_dec.c:682
void alu_edt(struct ge *ge, uint16_t pattern, uint8_t plen, uint16_t src)
EDT 0xDE Edit packed source into pattern at op1.
Definition alu_dec.c:868
void alu_ap(struct ge *ge, uint16_t a, uint8_t alen, uint16_t b, uint8_t blen)
AP 0xEA Add Packed: op1 = op1 + op2; CC set.
Definition alu_dec.c:253
void alu_dp(struct ge *ge, uint16_t a, uint8_t alen, uint16_t b, uint8_t blen)
DP 0xED Divide Packed: op1[left L1-L2 chars] = quotient, op1[right L2+1 chars] = remainder; CC set.
Definition alu_dec.c:459
GE-130 packed/signed decimal ALU helpers.
void alu_tl(struct ge *ge, uint16_t a, uint8_t len, uint16_t table)
alu_tl – Translate (TL, §5.5.3.3, "TR" in manual)
Definition alu_logic.c:203
void alu_ni(struct ge *ge, uint16_t addr, uint8_t imm)
alu_ni – AND Immediate (NI, §5.6.3.2)
Definition alu_logic.c:108
void alu_nc(struct ge *ge, uint16_t a, uint16_t b, uint8_t len)
alu_nc – AND Characters (NC, §5.5.3.9)
Definition alu_logic.c:61
void alu_oc(struct ge *ge, uint16_t a, uint16_t b, uint8_t len)
alu_oc – OR Characters (OC, §5.5.3.8)
Definition alu_logic.c:73
void alu_cmc(struct ge *ge, uint16_t a, uint16_t b, uint8_t len)
alu_cmc – Compare Characters (CMC, §5.5.3.2)
Definition alu_logic.c:153
void alu_ci(struct ge *ge, uint16_t addr, uint8_t imm)
alu_ci – Compare Immediate (CMI, §5.5.5.1)
Definition alu_logic.c:180
void alu_xc(struct ge *ge, uint16_t a, uint16_t b, uint8_t len)
alu_xc – Exclusive-OR Characters (XC, §5.5.3.7)
Definition alu_logic.c:85
void alu_oi(struct ge *ge, uint16_t addr, uint8_t imm)
Definition alu_logic.c:118
void alu_mvc(struct ge *ge, uint16_t dst, uint16_t src, uint16_t len)
alu_mvc – Move Characters (MVC, §5.5.3.1)
Definition alu_logic.c:31
void alu_xi(struct ge *ge, uint16_t addr, uint8_t imm)
alu_xi – Exclusive-OR Immediate (XI, §5.6.3.3)
Definition alu_logic.c:136
void alu_mvi(struct ge *ge, uint16_t addr, uint8_t imm)
alu_mvi – Move Immediate (MVI, §5.5.5.2)
Definition alu_logic.c:51
void alu_tm(struct ge *ge, uint16_t addr, uint8_t mask)
alu_tm – Test under Mask (TM, §5.6.3.4)
Definition alu_logic.c:226
GE-120/130 ALU logical and string-move primitives.
void alu_mvq(struct ge *ge, uint16_t dst, uint16_t src, uint8_t len)
alu_mvq - Move Quartets (MVQ, 0xF8)
Definition alu_reg.c:305
void alu_cmq(struct ge *ge, uint16_t a, uint16_t b, uint8_t len)
alu_cmq - Compare Quartets (CMQ, 0xF9)
Definition alu_reg.c:347
void alu_cmr(struct ge *ge, uint16_t reg_val, uint16_t value)
alu_cmr - Compare Memory to Register (CMR, 0xBD)
Definition alu_reg.c:77
void alu_sr(struct ge *ge, uint16_t *r7, uint16_t field, uint16_t len, uint8_t model)
alu_sr - Search Right (SR, 0xD9)
Definition alu_reg.c:228
void alu_smr(struct ge *ge, uint16_t *reg, uint16_t value)
alu_smr - Subtract Memory from Register (SMR, 0xBF)
Definition alu_reg.c:162
void alu_sl(struct ge *ge, uint16_t *r7, uint16_t field, uint16_t len, uint8_t model)
alu_sl - Search Left (SL, 0xDB)
Definition alu_reg.c:263
void alu_amr(struct ge *ge, uint16_t *reg, uint16_t value)
alu_amr - Add Memory to Register (AMR, 0xBE)
Definition alu_reg.c:110
ALU helpers for GE-120/GE-130 register and memory-field operations.
Bit manipulation helpers.
#define BIT(V, X)
Definition bit.h:9
#define SET_BIT(R, X)
Definition bit.h:10
#define RESET_BIT(R, X)
Definition bit.h:11
void channel_accept_output(struct ge *ge, struct ge_channel *ch, uint8_t c)
Definition channel.c:31
void ge_mem_store8(struct ge *ge, uint16_t addr, uint8_t val)
Store a byte with generated odd parity + mark-written (for the hybrid ALU/SS write paths that write g...
Definition ge.c:119
@ NS_RO1
Definition ge.h:79
@ NS_UA1
Definition ge.h:82
@ NS_UA2
Definition ge.h:81
@ NS_RO2
Definition ge.h:80
static uint16_t NI_knot(struct ge *ge)
NI Knot.
Definition signals.h:301
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 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_ERR
Emulator unrecoverable condition.
Definition log.h:18
@ LOG_FUTURE
Future state network debug.
Definition log.h:24
@ LOG_PERI
Peripherals IO.
Definition log.h:27
static void EXEC_NI(struct ge *ge)
static void INT_F0(struct ge *ge)
static void INT_C3(struct ge *ge)
static void CI73(struct ge *ge)
static void CE08(struct ge *ge)
static void CI02(struct ge *ge)
static uint16_t eff_v1_l2(struct ge *ge)
static void CI08(struct ge *ge)
static void EXEC_SMR(struct ge *ge)
static void CE01(struct ge *ge)
static void CU05(struct ge *ge)
static void CI63(struct ge *ge)
static void CI39(struct ge *ge)
static void INT_D3(struct ge *ge)
static void INT_C2(struct ge *ge)
static void CO49(struct ge *ge)
static void CO04(struct ge *ge)
static void CE11(struct ge *ge)
static void CO14(struct ge *ge)
static void CE18(struct ge *ge)
static void CI21(struct ge *ge)
static void CI20(struct ge *ge)
static void CO00(struct ge *ge)
static void CU12(struct ge *ge)
static void CI00s(struct ge *ge)
static void CI66(struct ge *ge)
static void CI19(struct ge *ge)
static void CE10(struct ge *ge)
static void CI74(struct ge *ge)
static void CI17(struct ge *ge)
static void CU00(struct ge *ge)
static void CO35(struct ge *ge)
static void CI15(struct ge *ge)
static void INT_D1(struct ge *ge)
static void EXEC_STR(struct ge *ge)
static void CU06(struct ge *ge)
static void CE03(struct ge *ge)
static void CI70(struct ge *ge)
static void CU07(struct ge *ge)
static void INT_C0(struct ge *ge)
static void INDEX_NEXT(struct ge *ge)
static void CE00(struct ge *ge)
static void CO01(struct ge *ge)
static void CI11(struct ge *ge)
static void INT_D2(struct ge *ge)
static void CU02(struct ge *ge)
static void CI06(struct ge *ge)
static void CI32(struct ge *ge)
static void CI65(struct ge *ge)
static void CO03(struct ge *ge)
static void CI75(struct ge *ge)
static void int_store(struct ge *ge, uint16_t a, uint8_t b)
static void EXEC_INDEX(struct ge *ge)
static void CU13(struct ge *ge)
static void CE07(struct ge *ge)
static void INT_D0(struct ge *ge)
static void CI80(struct ge *ge)
static void CI07(struct ge *ge)
static void EXEC_AMR(struct ge *ge)
static void CI81(struct ge *ge)
static void CU17(struct ge *ge)
static void CO96(struct ge *ge)
static void INDEX_OP2(struct ge *ge)
static void CI60(struct ge *ge)
static void EXEC_CMI(struct ge *ge)
static void EXEC_TM(struct ge *ge)
static void CI86(struct ge *ge)
static void CE06(struct ge *ge)
static void CO94(struct ge *ge)
static void CU20(struct ge *ge)
static void CO48(struct ge *ge)
static void CI64(struct ge *ge)
static void CI68(struct ge *ge)
static void CE16(struct ge *ge)
static void CO91(struct ge *ge)
static void EXEC_MVI(struct ge *ge)
static void CI05(struct ge *ge)
static void CI82(struct ge *ge)
static void CE09(struct ge *ge)
static void CI84(struct ge *ge)
static uint16_t reg_addr_of(struct ge *ge)
static void CI72(struct ge *ge)
static void CU01(struct ge *ge)
static uint16_t mem_rd16_op(struct ge *ge, uint16_t a)
static void CO90(struct ge *ge)
static void EXEC_CI(struct ge *ge)
static void SS_TO_ALPHA(struct ge *ge)
static void CE02(struct ge *ge)
static void EXEC_LR(struct ge *ge)
static void CI04(struct ge *ge)
static void CI88(struct ge *ge)
static void CI83(struct ge *ge)
static void CI41(struct ge *ge)
static void mem_wr16_op(struct ge *ge, uint16_t a, uint16_t v)
static void CO18(struct ge *ge)
static void CO40(struct ge *ge)
static void CI09(struct ge *ge)
static void CI89(struct ge *ge)
static void CU10(struct ge *ge)
static void CI62(struct ge *ge)
static void CI38(struct ge *ge)
static void CI69(struct ge *ge)
static void CI03(struct ge *ge)
static void CI77(struct ge *ge)
static void CU14(struct ge *ge)
static void CO11(struct ge *ge)
static void EXEC_LPSR(struct ge *ge)
static void CU16(struct ge *ge)
static void CO12(struct ge *ge)
static uint8_t int_parity(uint8_t b)
static void CI87(struct ge *ge)
static void CI85(struct ge *ge)
static void CO97(struct ge *ge)
static void CO30(struct ge *ge)
static void CI67(struct ge *ge)
static void CO16(struct ge *ge)
static void CI40(struct ge *ge)
static void CI00(struct ge *ge)
static void CI33(struct ge *ge)
static void CO41(struct ge *ge)
static void CO92(struct ge *ge)
static void EXEC_XI(struct ge *ge)
static void cr_wr16(struct ge *ge, uint16_t a, uint16_t v)
static void CO13(struct ge *ge)
static void EXEC_CMR(struct ge *ge)
static void CI61(struct ge *ge)
static void CO10(struct ge *ge)
static void CO31(struct ge *ge)
static uint16_t cr_base(struct ge *ge, int n)
static void CE05(struct ge *ge)
static uint16_t cr_rd16(struct ge *ge, uint16_t a)
static void CU11(struct ge *ge)
static void EXEC_SS(struct ge *ge)
static void INDEX_OP1(struct ge *ge)
static void CU03(struct ge *ge)
static void CE19(struct ge *ge)
static void CO93(struct ge *ge)
static void CI76(struct ge *ge)
static void EXEC_LA(struct ge *ge)
static void INT_C1(struct ge *ge)
static void CO95(struct ge *ge)
static void CE_chan1_status(struct ge *ge)
static void CI34(struct ge *ge)
static void CI16(struct ge *ge)
static void CI12(struct ge *ge)
static void CI78(struct ge *ge)
static void CI71(struct ge *ge)
static void CO02(struct ge *ge)
static void CU15(struct ge *ge)
static void CU04(struct ge *ge)
static void CI01(struct ge *ge)
static void JRT_LINK(struct ge *ge)
#define SP_OPCODE
Definition opcodes.h:75
#define AB_OPCODE
Definition opcodes.h:84
#define XC_OPCODE
Definition opcodes.h:65
#define NC_OPCODE
Definition opcodes.h:62
#define SD_OPCODE
Definition opcodes.h:83
#define SL_OPCODE
Definition opcodes.h:69
#define CMP_OPCODE
Definition opcodes.h:73
#define MP_OPCODE
Definition opcodes.h:76
#define CMC_OPCODE
Definition opcodes.h:63
#define UPK_OPCODE
Definition opcodes.h:66
#define PKS_OPCODE
Definition opcodes.h:78
#define AD_OPCODE
Definition opcodes.h:82
#define OC_OPCODE
Definition opcodes.h:64
#define DP_OPCODE
Definition opcodes.h:77
#define SB_OPCODE
Definition opcodes.h:85
#define MVC_OPCODE
Definition opcodes.h:61
#define AP_OPCODE
Definition opcodes.h:74
#define EDT_OPCODE
Definition opcodes.h:71
#define PK_OPCODE
Definition opcodes.h:68
#define SR_OPCODE
Definition opcodes.h:67
#define TL_OPCODE
Definition opcodes.h:70
#define MVQ_OPCODE
Definition opcodes.h:80
#define MVP_OPCODE
Definition opcodes.h:72
#define CMQ_OPCODE
Definition opcodes.h:81
#define UPKS_OPCODE
Definition opcodes.h:79
void reader_send_tu10(struct ge *ge)
Definition reader.c:109
void connector_send_tu00(struct ge *ge, struct ge_connector *conn)
Definition reader.c:216
void reader_send_tu00(struct ge *ge)
Definition reader.c:22
Signals.
uint16_t ACON
Stops on jump condition not verified.
Definition console.h:113
uint16_t ACOV
Stops on jump condition verified.
Definition console.h:105
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 ALAM
Operator Call.
Definition ge.h:332
uint8_t RINT
Definition ge.h:364
uint8_t RT121
Definition ge.h:537
uint8_t rRA
Definition ge.h:245
uint8_t PB37
Definition ge.h:377
uint8_t rRE
Definition ge.h:244
uint8_t AINI
Program Loading.
Definition ge.h:278
struct ge_connector ST4
The I/O interface for the ST4 connector.
Definition ge.h:636
uint8_t ALTO
Stops internal cycles.
Definition ge.h:293
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
uint8_t future_state
Future state.
Definition ge.h:546
uint8_t PODI
Slow delay line.
Definition ge.h:301
uint8_t mem_written[MEM_SIZE]
1 once a location has been written; prevents false MEM CHECK on cleared memory
Definition ge.h:572
uint8_t inject_chan1_status
Channel-1 peripheral status override for error injection.
Definition ge.h:588
uint16_t rV1
Addresser for the first operand.
Definition ge.h:123
uint8_t rSO
Main sequencer.
Definition ge.h:220
uint8_t halted
Definition ge.h:99
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 rL2
Auxiliary register.
Definition ge.h:155
uint8_t ffFI
Special conditions register 1.
Definition ge.h:253
uint8_t RC00
Asynchronous CPU Cycle Request.
Definition ge.h:445
uint8_t rRI
Photoprint register 8-bit register used to store the photodisc codes.
Definition ge.h:146
uint8_t PB06
Unconditionally stores L106.
Definition ge.h:373
uint8_t RC01
Asynchronous Channel 1 Cycle Request.
Definition ge.h:458
enum ge::@3 memory_command
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 mem[MEM_SIZE]
The memory of the emulated system.
Definition ge.h:566
uint8_t AVER
Jump Condition Verified.
Definition ge.h:343
struct ge_channel channel2
Integrated channel 2 (CAN2) line bundle — shared by the integrated reader (input),...
Definition ge.h:645
uint8_t RAVI
VICU Support.
Definition ge.h:535
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
uint16_t rV2
Addresser for the second operand.
Definition ge.h:124
uint8_t RC02
Asynchronous Channel 2 Cycle Request.
Definition ge.h:473
uint8_t ADIR
Disable Step By Step.
Definition ge.h:362
uint8_t RIG1
End from controller 1.
Definition ge.h:527
uint8_t rSI
Peripheral unit sequencer.
Definition ge.h:234
uint8_t URPU
Definition ge.h:426
uint8_t RC03
Asynchronous Channel 3 Cycle Request.
Definition ge.h:488
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 mem_parity[MEM_SIZE]
Stored odd-parity bit (1 bit per location) written alongside mem[].
Definition ge.h:569
uint8_t PB07
Unconditionally stores L106.
Definition ge.h:374
uint8_t RETO
Definition ge.h:269
uint8_t URPE
Definition ge.h:425
uint16_t rV3
Addresser for external instructions using channel 3.
Definition ge.h:125
uint8_t TO50_did_CI32_or_CI33
Workaround for pulse TO50.
Definition ge.h:667
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
uint16_t cr_cache[8]
Change/segment-register CACHE used for modified-address resolution.
Definition ge.h:140
uint8_t SA00
First-vs-second operand flag for address modification.
Definition ge.h:354