GE-115 Emulator
An Emulator of the General Electrics GE-115 computer
console.c
Go to the documentation of this file.
1#include "console.h"
2
3#include <string.h>
4#include "ge.h"
5#include "bit.h"
6#include "log.h"
7#include "signals.h"
8
9void ge_fill_console_data(struct ge* ge, struct ge_console *console)
10{
11 /* maintenance panel lamps (cpu fo. 34) */
12
13 console->lamps.RO = ge->rRO;
14 console->lamps.SO = ge->rSO;
15 console->lamps.FA = ge->ffFA & 0x0f;
16 console->lamps.UR = ge->URPE;
17 console->lamps.SA = ge->rSA;
18
19 /* TODO: "selection of the four connectors"? */
20 console->lamps.B = 0;
21
22 /* operator panel lamps (cpu fo. 33) */
23
24 console->lamps.HALT = ge->ALTO;
25 console->lamps.OPERATOR_CALL = ge->ALAM;
26
27 /* MAINT ON: the maintenance panel has the machine.
28 *
29 * The lamp answers one question -- is the field engineer in control, or the
30 * program? It lights when the panel has been touched AND the machine is
31 * stopped: any maintenance switch inserted, or the register selector turned
32 * off NORM, with the CPU held by ALTO. A machine that is running, or one
33 * whose panel is untouched and rotary at NORM, is the operator's and the
34 * lamp stays dark.
35 *
36 * Behaviour as observed on the restored machine, 2026-07-29. Note the
37 * rotary alone is enough: turning the selector off NORM arms the forcing
38 * cycle that START would perform (see the rotary table in docs/console.md
39 * §4.2), which is precisely when an operator needs telling. */
40 {
41 const struct ge_console_switches *sw = &ge->console_switches;
42 int inserted = sw->PAPA || sw->PATE || sw->RICI || sw->ACOV ||
43 sw->ACON || sw->INAR || sw->STOC || sw->INCE || sw->SITE;
44
45 /* The sixteen AM forcing toggles are switches on that panel too, and
46 * count: setting one up is the engineer preparing a value to force. */
47 console->lamps.MAINTENANCE_ON =
48 (inserted || sw->AM != 0 ||
50 }
51
52 /* SWITCH 1 / SWITCH 2 lamps show the positions of the two program-readable
53 * switches: lit when the switch reads logic 1 (the value that makes JS1 /
54 * JS2 jump). (CPU[4] §3.3, fo.33) */
55 console->lamps.SWITCH_1 = ge->JS1;
56 console->lamps.SWITCH_2 = ge->JS2;
57
58 /* LOAD1/LOAD2 selector lamps: the load-unit selector picks one of the two
59 * install-time load connectors (ALOI=1 -> connector 2 = LOAD1, ALOI=0 ->
60 * LOAD2). Exactly one is lit. (CPU[4] §3.3, fo.43) */
61 console->lamps.LOAD_1 = ge->ALOI;
62 console->lamps.LOAD_2 = !ge->ALOI;
63
64 /* performance conditions (cpu fo. 31, 32) */
65
66 console->lamps.ADD_reg = ge->rBO;
67
68 console->lamps.OF = BIT(ge->ffFA, 4);
69 console->lamps.NZ = BIT(ge->ffFA, 5);
70 console->lamps.IM = BIT(ge->ffFA, 6);
71 console->lamps.JE = ge->JE;
72
73 console->lamps.I = ge->INTE;
74 console->lamps.C1 = PUC1(ge);
75 console->lamps.C2 = ge->PUC2;
76 console->lamps.C3 = ge->PUC3;
77
78 console->lamps.MEM_CHECK = ge->mem_check;
79 console->lamps.INV_ADD = ge->inv_add;
80
81 /* STEP BY STEP is the operator panel's own switch (ASIN) and has the only
82 * lamp of the two step circuits. The maintenance PAPA switch steps the
83 * microsequences with no lamp of its own -- they are independent, and
84 * inserting PAPA must not light this. (CPU[4] fo.115; see ge.h ASIN.) */
85 console->lamps.STEP_BY_STEP = ge->ASIN;
86
87 console->lamps.OP_reg = ge->rFO;
88
89 console->rotary = ge->register_selector;
90 console->switches = ge->console_switches;
91
92 /* LAMPS CHECK, held: every lamp on the console lights, whatever the machine
93 * is doing. A bulb test, so it is the last word here -- it overwrites the
94 * states computed above rather than mixing with them. (CPU[4] §3.2) */
95 if (ge->lamps_test)
96 memset(&console->lamps, 0xff, sizeof(console->lamps));
97}
98
99void ge_set_console_switches(struct ge *ge, struct ge_console_switches *switches)
100{
102 "AM: %04x - switches: "
103 "SITE: %d INCE: %d INAR: %d STOC: %d "
104 "ACON: %d ACOV: %d RICI: %d PATE: %d PAPA: %d\n",
105 switches->AM,
106 switches->SITE, switches->INCE, switches->INAR, switches->STOC,
107 switches->ACON, switches->ACOV, switches->RICI, switches->PATE, switches->PAPA);
108 ge->console_switches = *switches;
109}
110
111
113{
114 ge_log(LOG_CONSOLE, "setting rotary %d\n", rs);
115 ge->register_selector = rs;
116}
117
118/*
119 * START, as a console presses it. See console.h.
120 *
121 * It releases the machine, and what stops it again is the machine's business,
122 * not the console's:
123 *
124 * - at NORM the program runs until a HLT, a step switch, or a fault;
125 * - off NORM the end-of-cycle stop (fo.98) fires after ONE maintenance cycle,
126 * so a register forcing is a single cycle and the machine parks again;
127 * - EXCEPT at position 8, the storage key-in, which fo.98 exempts along with
128 * NORM. There the machine goes on storing the AM switches at V1 and
129 * advancing V1 through the whole of core -- that is what the real machine
130 * does -- until PAPA stops it at the next microsequence, or the address
131 * walks off the installed memory and the INV ADD error stop ends it
132 * (pulse.c mem_fault). Inserting PAPA is what makes it one byte per press.
133 *
134 * The return value tells a front end whether this was a program run (1) or a
135 * maintenance operation (0); both need the caller to keep turning the machine,
136 * because a powered GE-120's delay line does not stop.
137 */
139{
140 ge->ALTO = 0;
141 ge_start(ge);
142 return ge->register_selector == RS_NORM;
143}
Bit manipulation helpers.
#define BIT(V, X)
Definition bit.h:9
void ge_fill_console_data(struct ge *ge, struct ge_console *console)
Definition console.c:9
void ge_set_console_switches(struct ge *ge, struct ge_console_switches *switches)
Definition console.c:99
int ge_console_start(struct ge *ge)
Definition console.c:138
void ge_set_console_rotary(struct ge *ge, enum ge_console_rotary rs)
Definition console.c:112
ge_console_rotary
Definition console.h:8
@ RS_NORM
Definition console.h:18
void ge_start(struct ge *ge)
Emulate the press of the "start" button in the console.
Definition ge.c:394
static uint8_t ge_halted(const struct ge *ge)
Is the CPU stopped?
Definition ge.h:929
void ge_log(ge_log_type type, const char *format,...)
Log message.
Definition log.c:122
@ LOG_CONSOLE
Console interactions.
Definition log.h:26
Signals.
uint16_t C1
Definition console.h:43
uint16_t SA
Definition console.h:35
uint16_t I
Definition console.h:44
uint16_t INV_ADD
Definition console.h:56
uint16_t SWITCH_2
Definition console.h:58
uint16_t UR
Definition console.h:28
uint16_t LOAD_1
Definition console.h:61
uint16_t C2
Definition console.h:42
uint16_t JE
Definition console.h:45
uint16_t FA
Definition console.h:33
uint16_t SO
Definition console.h:31
uint16_t LOAD_2
Definition console.h:62
uint16_t HALT
Definition console.h:60
uint16_t MEM_CHECK
Definition console.h:55
uint16_t STEP_BY_STEP
Definition console.h:59
uint16_t RO
Definition console.h:26
uint16_t OF
Definition console.h:48
uint16_t MAINTENANCE_ON
Definition console.h:54
uint16_t IM
Definition console.h:46
uint16_t OP_reg
Definition console.h:40
uint16_t C3
Definition console.h:41
uint16_t B
Definition console.h:37
uint16_t OPERATOR_CALL
Definition console.h:63
uint16_t NZ
Definition console.h:47
uint16_t ADD_reg
Definition console.h:39
uint16_t SWITCH_1
Definition console.h:57
Console switches.
Definition console.h:71
uint16_t SITE
Don't wait for external unit availability.
Definition console.h:145
uint16_t INCE
Do not error-correct external units input.
Definition console.h:136
uint16_t PATE
Stop after a cycle.
Definition console.h:89
uint16_t ACON
Stops on jump condition not verified.
Definition console.h:113
uint16_t RICI
Disables next status.
Definition console.h:97
uint16_t AM
Forcing bits.
Definition console.h:155
uint16_t INAR
Do not stop on memory error.
Definition console.h:121
uint16_t ACOV
Stops on jump condition verified.
Definition console.h:105
uint16_t PAPA
Step By Step execution.
Definition console.h:81
enum ge_console_rotary rotary
Definition console.h:182
struct ge_console_switches switches
Definition console.h:180
struct ge_console_lamps lamps
Definition console.h:179
The entire state of the emulated system, including registers, memory, peripherals and timings.
Definition ge.h:172
uint8_t ALAM
Operator Call.
Definition ge.h:431
uint8_t INTE
Interruption present.
Definition ge.h:498
uint8_t ALOI
Load connector selection.
Definition ge.h:384
uint8_t JS2
Console jump condition 2.
Definition ge.h:496
uint8_t ALTO
Stops internal cycles.
Definition ge.h:392
uint8_t ffFA
Special conditions register 2.
Definition ge.h:352
uint8_t lamps_test
LAMPS CHECK held (CPU[4] §3.2).
Definition ge.h:491
uint8_t inv_add
Invalid-address fault flag: set when rVO >= installed memory size.
Definition ge.h:729
enum ge_console_rotary register_selector
The current state of the console register rotary switch.
Definition ge.h:680
uint8_t mem_check
Parity fault flag: set when a READ finds a parity mismatch on a previously-written location.
Definition ge.h:726
uint8_t rSO
Main sequencer.
Definition ge.h:309
uint16_t rRO
Multipurpose 8+1 bit register.
Definition ge.h:248
struct ge_console_switches console_switches
The current state of the console switches.
Definition ge.h:685
uint8_t PUC3
Channel 3 in transfer.
Definition ge.h:547
uint8_t PUC2
Channel 2 in transfer.
Definition ge.h:540
uint8_t ASIN
STEP-BY-STEP, the OPERATOR panel switch (signal ASIN).
Definition ge.h:477
uint16_t rBO
Default operator.
Definition ge.h:277
uint8_t rSA
Future state configuration.
Definition ge.h:331
uint8_t JE
JE/AVER jump instruction exectuted.
Definition ge.h:497
uint8_t URPE
Definition ge.h:554
uint8_t rFO
Current function code.
Definition ge.h:284
uint8_t JS1
Console jump condition 1.
Definition ge.h:495