GE-115 Emulator
An Emulator of the General Electrics GE-115 computer
ge.h
Go to the documentation of this file.
1#ifndef GE_H
2#define GE_H
3
4#include <stdint.h>
5#include <stddef.h>
6#include "opcodes.h"
7#include "console.h"
8#include "reader.h"
9#include "channel.h"
10
11#define CLOCK_PERIOD 14000 /* in usec, interval between pulse lines */
12#define MEM_SIZE 65536
13
14#define ENUMERATE_CLOCKS \
15 X(TO00) \
16 X(TO10) \
17 X(TO11) \
18 X(TO15) \
19 X(TO19) \
20 X(TO20) \
21 X(TO25) \
22 X(TO30) \
23 X(TO40) \
24 X(TO50) \
25 X(TO50_1) \
26 X(TO60) \
27 X(TO64) \
28 X(TO65) \
29 X(TO70) \
30 X(TO80) \
31 X(TO89) \
32 X(TO90) \
33 X(TI05) \
34 X(TI06) \
35 X(TI10) \
36 X(END_OF_STATUS)
37
38enum clock {
39 #define X(name) name ,
41 #undef X
42};
43
45 struct cmds {
46 uint8_t from_zero:1;
47 uint8_t decresing:1;
48 uint8_t from_04:1; /* count injected at bit 04 (CI42) */
49 uint8_t stop_07:1; /* carry/borrow blocked past bit 07 (CI44) */
50 } cmds;
51
52 /* Second-phase (CI-side) counting selection: CI40/41/42/44 stage their
53 * configuration here; it becomes active when TO65 "enables the second
54 * phase commands for count selection" (cpu fo. 142) — i.e. the CO-phase
55 * flags are replaced by these for the TI05 loads (CI05 NI->L1 etc.).
56 * This is what makes the b9/b1 per-character L1 decrement effective. */
57 struct cmds ci_cmds;
58};
59
60/* Arithmetic-unit mode lines selected by CI45/CI46/CI47 for the duration of
61 * one sequencer state. Their combinations are decoded by CI68/CI69 when the
62 * UA result is admitted to the NI knot. */
64 uint8_t logic:1; /* CI45: logical-operation group */
65 uint8_t decimal_and:1; /* CI46: decimal / AND group */
66 uint8_t subtract_xor:1; /* CI47: subtract / XOR group */
67
68 /* CI50, "OPERA SOLO UA1 / WORK ONLY UA1" (cp07 fo.142). Not a function
69 * select: cp06 ch.094 shows CI50B = /CI501 feeding the UZE71 and UZE81
70 * NANDs, so asserting CI50 INHIBITS the inter-zone enables and leaves
71 * only the low unit participating. It gates the arithmetic unit's
72 * WIDTH, which is what a digit-at-a-time decimal operation needs. */
73 uint8_t low_zone_only:1; /* CI50: inhibit UZE71/UZE81 */
74};
75
76struct ge_knot_no {
77 uint8_t forcings;
78
79 enum {
84
85 enum {
96 /* Explicit "no selection drives the knot": hardware selections are
97 * pulses, so a knot with no active selection reads 0 at latch time.
98 * gemu's cmd persists across pulses; NO_UNDRIVEN models the decay
99 * where a sheet's data path depends on it (interruption D3). */
102};
103
105 NS_ZERO, /* quartet driven by nothing: non-storing knot reads 0 */
114};
115
122
134/* Strap-card types actually printed in the ch.001/ch.002 tables: only PONT2N
135 * and PONT2P exist. "PONT2H" was a misread of PONT2N in the 1968 typeface,
136 * caught when the physical machine's cards were identified (2026-07-21):
137 * 0618034Z reads PONT2N on the board, and 0618035V is electrically a PONT2N
138 * too, under a different part code. */
140
144
147
150
153
158
165 uint8_t S42_diag;
166};
167
172struct ge {
173 /* Main clock */
175 uint8_t powered;
176
179
180 /* Lists of events and operations for all
181 * pulses
182 */
183 struct pulse_event *on_pulse[END_OF_STATUS];
184
191 uint16_t rPO;
192
199 uint16_t instr_pc;
200
201 uint16_t rV1;
202 uint16_t rV2;
203 uint16_t rV3;
204 uint16_t rV4;
205
217 uint16_t cr_cache[8];
218
223 uint8_t rRI;
224
231 uint16_t rL1;
232 uint8_t rL2;
233 uint16_t rL3;
234
236
242
248 uint16_t rRO;
249
260 uint8_t rUA;
261
268 uint16_t rVO;
269
277 uint16_t rBO;
278
284 uint8_t rFO;
285
309 uint8_t rSO;
310
323 uint8_t rSI;
324
331 uint8_t rSA;
332
333 uint8_t rRE;
334 uint8_t rRA;
335
342 uint8_t ffFI;
343
352 uint8_t ffFA;
353
354 /* Those two store which work channel the present cycle as been attributed to
355 * (cpu fo. 130).
356 * When setting RETO, if PAPA switch is set, rotary is neither in normal, nor
357 * in position 8 to store in memory, should set ALTO */
358 uint8_t RETO:1;
359
369 uint8_t RET2:1;
370
377 uint8_t AINI:1;
378
384 uint8_t ALOI:1;
385
392 uint8_t ALTO:1;
393
400 uint8_t PODI:1;
401
421 uint8_t ACIC:1;
422
431 uint8_t ALAM:1;
432
442 uint8_t AVER:1;
443
444 /* The flow chart's <SA00> first-vs-second operand diamond (dwg 14023130)
445 * is bit 0 of the SA state code itself: E6 routes operand 1 to ED (bit 0
446 * set, via its unconditional CU00) and E7 routes operand 2 to EC (bit 0
447 * cleared by CU10 = DI64A0) — see the indexing states in msl-states.c.
448 * No separate flag is needed. */
449
456 uint8_t ADIR:1;
457
477 uint8_t ASIN:1;
478
491 uint8_t lamps_test:1;
492
493 uint8_t RINT:1;
494
495 uint8_t JS1:1;
496 uint8_t JS2:1;
497 uint8_t JE:1;
498 uint8_t INTE:1;
499
500 /* Busy Connector Logic */
501
502 uint8_t PB06:1;
503 uint8_t PB07:1;
504 uint8_t PB26:1;
505 uint8_t PB36:1;
506 uint8_t PB37:1;
507
526 uint8_t PIC1:1;
527
533 uint8_t RASI:1;
534
540 uint8_t PUC2:1;
541
547 uint8_t PUC3:1;
548
549 uint8_t PEC1:1;
550 uint8_t PEC1_pending:1;
551
552 uint8_t RUF1:1;
553
554 uint8_t URPE:1;
555 uint8_t URPU:1;
556
557 /* Cycle Attribution Logic */
558 /* ----------------------- */
559
560 /* Asyncronous flip flops */
561
574 uint8_t RC00:1;
575
587 uint8_t RC01:1;
588
602 uint8_t RC02:1;
603
617 uint8_t RC03:1;
618
629 uint8_t RIA0:1;
630
636 uint8_t RESI:1;
637
643 uint8_t RIA2:1;
644
650 uint8_t RIA3:1;
651
653 uint8_t RECE:1;
654
656 uint8_t RIG1:1;
657
658 uint8_t RIG3:1;
659
661 uint8_t RACI:1;
662
664 uint8_t RAVI:1;
665
666 uint8_t RT121:1;
667 uint8_t RT131:1;
668
676
681
686
687 uint8_t step_by_step:1;
688
689 enum {
694
695 uint8_t mem[MEM_SIZE];
696
699
702
721
723 uint32_t mem_size;
724
726 uint8_t mem_check;
727
729 uint8_t inv_add;
730
737
740
745
756 char out[65536]; /* captured printed chars; per-frame staging only
757 * (the wasm console drains+clears each frame, the
758 * CLI reads it at end). Sized for a catch-up
759 * frame's burst so fast/backgrounded printing
760 * doesn't overflow before the drain. */
762 uint8_t kbd[256]; /* operator keyboard input queue */
764 /* Channel-2 OUTPUT transfer engine (printer.c): while out_active, the
765 * printer requests a channel-2 cycle (RC02) per character so the rSI
766 * output state (0x02) drains out_remaining bytes from V4, then ends.
767 * out_saved_so preserves the CPU sequencer across the (overlapped)
768 * transfer — fsn advances SO on RIA0, which the stolen channel-2 cycles
769 * would otherwise clobber; we restore it when the transfer ends. */
776
781
786
795
796 struct ge_peri *peri;
797
803 void *std_core;
804
817};
818
820void ge_init(struct ge *ge);
821
823int ge_deinit(struct ge *ge);
824
829int ge_load_image(struct ge *ge, const uint8_t *image, size_t size,
830 uint16_t origin);
831
835void ge_enter(struct ge *ge, uint16_t entry);
836
840void ge_mem_store8(struct ge *ge, uint16_t addr, uint8_t val);
841
846void ge_seed_segment_bases(struct ge *ge);
847
849int ge_run(struct ge *ge);
850
852int ge_run_pulse(struct ge *ge);
853
855int ge_run_cycle(struct ge *ge);
856
858void ge_clear(struct ge * ge);
859
861void ge_load(struct ge * ge);
862
864void ge_load_1(struct ge * ge);
865
867void ge_load_2(struct ge * ge);
868
870void ge_start(struct ge * ge);
871
872typedef void (*on_pulse_cb)(struct ge *);
873
878
879/* Defined in pulse.c: execute pulse events */
880void pulse(struct ge *ge);
881
882struct ge_peri {
883 struct ge_peri *next;
884 int (*init)(struct ge*, void*);
885 int (*on_pulse)(struct ge*, void*);
886 int (*on_clock)(struct ge*, void*);
887 int (*deinit)(struct ge*, void*);
888 void *ctx;
889};
890
891int ge_register_peri(struct ge *ge, struct ge_peri *p);
892
900void fsn_last_clock(struct ge *ge);
901
902void connectors_first_clock(struct ge *ge);
903
909const char *ge_clock_name(enum clock c);
910
911void ge_print_registers_verbose(struct ge *ge);
912
929static inline uint8_t ge_halted(const struct ge *ge) { return ge->ALTO; }
930
932void ge_log_options(struct ge *ge);
933
934#endif /* GE_H */
ge_console_rotary
Definition console.h:8
int ge_deinit(struct ge *ge)
Deinitialize the emulator.
Definition ge.c:560
void ge_seed_segment_bases(struct ge *ge)
Seed the eight change/segment-base registers (mem[240+2N]) to identity bases N<<12.
Definition ge.c:294
void ge_load_1(struct ge *ge)
Emulate the press of the "load 1" button in the console.
Definition ge.c:372
void ge_clear(struct ge *ge)
Emulate the press of the "clear" button in the console.
Definition ge.c:137
#define MEM_SIZE
Definition ge.h:12
#define ENUMERATE_CLOCKS
Definition ge.h:14
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
int ge_run(struct ge *ge)
Run the emulator.
int ge_run_cycle(struct ge *ge)
Run all GE "mastri" clock periods until next clock cycle.
Definition ge.c:549
static uint8_t ge_halted(const struct ge *ge)
Is the CPU stopped?
Definition ge.h:929
ge_pont
Backplane option connectors and the maintenance LAMPS switch.
Definition ge.h:139
@ PONT_NONE
Definition ge.h:139
@ PONT_2N
Definition ge.h:139
@ PONT_2P
Definition ge.h:139
const char * ge_clock_name(enum clock c)
The clock period name name.
Definition ge.c:433
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:317
void ge_load_2(struct ge *ge)
Emulate the press of the "load 2" button in the console.
Definition ge.c:389
void(* on_pulse_cb)(struct ge *)
Definition ge.h:872
void ge_enter(struct ge *ge, uint16_t entry)
Force the sequencer into the alpha (fetch) phase at entry.
Definition ge.c:355
void ge_init(struct ge *ge)
Initialize the emulator.
Definition ge.c:14
int ge_run_pulse(struct ge *ge)
Run a single pulse (i.e. a single GE "mastri" clock periods)
Definition ge.c:493
void fsn_last_clock(struct ge *ge)
Commit the future state.
Definition ge.c:574
int ge_register_peri(struct ge *ge, struct ge_peri *p)
void ge_print_registers_verbose(struct ge *ge)
Definition ge.c:459
void pulse(struct ge *ge)
Definition pulse.c:328
void ge_load(struct ge *ge)
Emulate the press of the "load" button in the console.
Definition ge.c:362
void ge_log_options(struct ge *ge)
Report the strapped configuration and every level it produces (LOG_DEBUG).
Definition ge.c:93
int ge_load_image(struct ge *ge, const uint8_t *image, size_t size, uint16_t origin)
Write a flat image into core at origin, priming the parity store.
Definition ge.c:330
void connectors_first_clock(struct ge *ge)
Definition ge.c:566
clock
Definition ge.h:38
void ge_start(struct ge *ge)
Emulate the press of the "start" button in the console.
Definition ge.c:394
Integrated printer / console typewriter (channel 2) — pragmatic model.
Definition ge.h:754
uint8_t kbd[256]
Definition ge.h:762
char out[65536]
Definition ge.h:756
Console switches.
Definition console.h:71
struct cmds ci_cmds
Definition ge.h:57
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
@ KNOT_PO_IN_NO
Definition ge.h:86
@ KNOT_V3_IN_NO
Definition ge.h:89
@ KNOT_AM_IN_NO
Definition ge.h:94
@ KNOT_V4_IN_NO
Definition ge.h:90
@ KNOT_V1_IN_NO
Definition ge.h:87
@ KNOT_L3_IN_NO
Definition ge.h:93
@ KNOT_NONE_IN_NO
Definition ge.h:100
@ KNOT_L2_IN_NO
Definition ge.h:92
@ KNOT_V2_IN_NO
Definition ge.h:88
@ KNOT_RI_IN_NO_43
Definition ge.h:95
@ KNOT_L1_IN_NO
Definition ge.h:91
enum ge_knot_no::@1 force_mode
enum ge_knot_no::@2 cmd
@ KNOT_FORCING_NO_43
Definition ge.h:82
@ KNOT_FORCING_NONE
Definition ge.h:80
@ KNOT_FORCING_NO_21
Definition ge.h:81
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
Definition ge.h:882
int(* on_pulse)(struct ge *, void *)
Definition ge.h:885
void * ctx
Definition ge.h:888
struct ge_peri * next
Definition ge.h:883
int(* init)(struct ge *, void *)
Definition ge.h:884
int(* deinit)(struct ge *, void *)
Definition ge.h:887
int(* on_clock)(struct ge *, void *)
Definition ge.h:886
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 ALAM
Operator Call.
Definition ge.h:431
uint8_t RET2
Channel-2 cycle-assignment memory.
Definition ge.h:369
uint8_t RINT
Definition ge.h:493
uint8_t INTE
Interruption present.
Definition ge.h:498
uint16_t instr_pc
Instruction-start PC (display aid, not a real register).
Definition ge.h:199
uint8_t ALOI
Load connector selection.
Definition ge.h:384
uint8_t RT121
Definition ge.h:666
void * std_core
Shared core for Standard-GE-100 controllers on connectors 3/4 (disk/tape).
Definition ge.h:803
uint8_t rRA
Definition ge.h:334
uint8_t PB37
Definition ge.h:506
uint8_t rRE
Definition ge.h:333
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 ALTO
Stops internal cycles.
Definition ge.h:392
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
uint8_t lamps_test
LAMPS CHECK held (CPU[4] §3.2).
Definition ge.h:491
uint8_t future_state
Future state.
Definition ge.h:675
uint8_t inv_add
Invalid-address fault flag: set when rVO >= installed memory size.
Definition ge.h:729
uint8_t PODI
Slow delay line.
Definition ge.h:400
uint8_t mem_written[MEM_SIZE]
1 once a location has been written; prevents false MEM CHECK on cleared memory
Definition ge.h:701
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
uint32_t mem_size
Installed memory size; 0 is treated as MEM_SIZE (full address space)
Definition ge.h:723
uint8_t inject_chan1_status
Channel-1 peripheral status override for error injection.
Definition ge.h:736
uint8_t RIA2
Synchronous Channel 2 Cycle Request.
Definition ge.h:643
uint8_t PEC1
Definition ge.h:549
uint16_t rV1
Addresser for the first operand.
Definition ge.h:201
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
uint8_t mem_check_blank
Read never-written core as a parity error (default 0).
Definition ge.h:720
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 powered
Definition ge.h:175
struct pulse_event * on_pulse[END_OF_STATUS]
Definition ge.h:183
uint8_t PUC2
Channel 2 in transfer.
Definition ge.h:540
uint8_t ffFI
Special conditions register 1.
Definition ge.h:342
uint8_t RC00
Asynchronous CPU Cycle Request.
Definition ge.h:574
uint8_t ASIN
STEP-BY-STEP, the OPERATOR panel switch (signal ASIN).
Definition ge.h:477
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
uint8_t RC01
Asynchronous Channel 1 Cycle Request.
Definition ge.h:587
enum ge::@3 memory_command
uint8_t RECE
Selection Check Byte.
Definition ge.h:653
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 mem[MEM_SIZE]
The memory of the emulated system.
Definition ge.h:695
uint8_t AVER
Jump Condition Verified.
Definition ge.h:442
struct ge_channel channel2
Integrated channel 2 (CAN2) line bundle — shared by the integrated reader (input),...
Definition ge.h:794
uint8_t RAVI
VICU Support.
Definition ge.h:664
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
uint8_t PEC1_pending
Definition ge.h:550
uint16_t rV2
Addresser for the second operand.
Definition ge.h:202
uint8_t RC02
Asynchronous Channel 2 Cycle Request.
Definition ge.h:602
uint8_t ADIR
Disable Step By Step.
Definition ge.h:456
struct ge_peri * peri
Definition ge.h:796
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
uint16_t rVO
Default memory addresser.
Definition ge.h:268
uint8_t URPU
Definition ge.h:555
uint8_t RC03
Asynchronous Channel 3 Cycle Request.
Definition ge.h:617
uint8_t JE
JE/AVER jump instruction exectuted.
Definition ge.h:497
uint8_t step_by_step
Step by step execution.
Definition ge.h:687
@ MC_READ
Definition ge.h:691
@ MC_NONE
Definition ge.h:690
@ MC_WRITE
Definition ge.h:692
uint8_t ACIC
Recycle delay line.
Definition ge.h:421
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 mem_parity[MEM_SIZE]
Stored odd-parity bit (1 bit per location) written alongside mem[].
Definition ge.h:698
uint8_t PB07
Unconditionally stores L106.
Definition ge.h:503
uint8_t RETO
Definition ge.h:358
uint8_t RIG3
Definition ge.h:658
uint8_t URPE
Definition ge.h:554
uint16_t rV3
Addresser for external instructions using channel 3.
Definition ge.h:203
uint8_t TO50_did_CI32_or_CI33
Workaround for pulse TO50.
Definition ge.h:816
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
uint16_t cr_cache[8]
Change/segment-register cache (kept in sync by the register instructions via cr_wr16 and by ge_seed_s...
Definition ge.h:217
struct ge::ge_integrated_printer integrated_printer
uint8_t JS1
Console jump condition 1.
Definition ge.h:495
on_pulse_cb cb
Definition ge.h:875
struct pulse_event * next
Definition ge.h:876