GE-115 Emulator
An Emulator of the General Electrics GE-115 computer
reader.c
Go to the documentation of this file.
1#include "ge.h"
2#include "log.h"
3#include "signals.h"
4#include "connector34.h"
5
6#define ENUMERATE_READER_COMMANDS \
7 X(0x40, read, "Read unchanged") \
8 X(0x21, read_normal_1, "Read normal i" ) \
9 X(0x01, read_normal_2, "Read normal ii") \
10 X(0x24, read_mixed_1, "Read mixed i" ) \
11 X(0x04, read_mixed_2, "Read mixed ii" ) \
12 X(0x20, read_binary, "Read binary" ) \
13 X(0xa1, put_normal_1, "Put normal i" ) \
14 X(0x81, put_normal_2, "Put normal ii" ) \
15 X(0xa4, put_mixed_1, "Put mixed i" ) \
16 X(0x84, put_mixed_2, "Put mixed ii" ) \
17 X(0xa0, put_binary, "Put binary" ) \
18 X(0xac, put_manual, "Put manual" ) \
19 X(0x44, exam_cond, "Exam of conditions") \
20 X(0x47, reset_error, "Reset error" ) \
21 X(0x48, card_reject, "Card_reject" ) \
22 X(0x0c, no_function, "No function" )
23
24/*
25 * TU00N, the command strobe. The CPU has put an order byte on RE00-07; this is
26 * the edge that hands it to the reader.
27 *
28 * The command matrix is the one the Pico firmware implements (src/feeder.c
29 * feeder_on_re_cmd), so a deck that drives one reader drives the other:
30 *
31 * 0x40 read unchanged -- the IPL's own order, and the loader's
32 * 0x21 0x01 read normal i/ii -- latch the Hollerith transcoder
33 * 0x24 0x04 read mixed i/ii -- likewise
34 * 0x20 read binary -- latch by-pass (column binary)
35 * 0xa0 put binary -- latch by-pass, but never a transfer
36 * 0x44 exam conditions -- nothing to do: the status lines are
37 * always valid, the CPU just samples them
38 * 0x47 reset error -- drop LUREN
39 * 0x48 card reject -- eject this card without reading it
40 * 0x0c no function -- nothing
41 * anything else -- counted as an anomaly, feed undisturbed
42 */
43void reader_send_tu00(struct ge *ge)
44{
46 uint8_t command = ge->rRE;
47 int known = 0;
48 int latch = 1;
49 int is_read = 0;
50
51 ge_log(LOG_READER, "EMIT TU201 (CE10)\n");
52
53 /* TU00N read-strobe line: the CPU clocks the command byte (rRE) toward the
54 * reader. Active for this one strobe. */
55 r->tu00 = 1;
56
57 switch (command) {
58#define X(cmd, name, desc) \
59 case cmd: \
60 ge_log(LOG_READER, " Command: %02x - %s\n", cmd, desc ); \
61 known = 1; \
62 break;
64#undef X
65 }
66 if (!known) {
67 r->anomalies++;
68 ge_log(LOG_READER, " Command: %02x - UNKNOWN (anomaly %u)\n",
69 command, (unsigned)r->anomalies);
70 }
71
72 /* COCON — mode-select clock. An explicit mode-select READ command drives the
73 * N001/N002/DEBI/MI01/MI02 decode and latches the CPU-selected read mode
74 * (active_mode/active_valid). The plain "read unchanged" (0x40) and the
75 * put/reject/manual commands leave the mode as-is, so the bootstrap (which
76 * issues 0x40) never engages the CPU mode and the cardreader keeps its
77 * harness/default mode. This is the loader's "set by-pass" actually
78 * switching normal<->binary. */
79 r->mode_n001 = r->mode_n002 = r->mode_debi = r->mode_mi01 = r->mode_mi02 = 0;
80 switch (command) {
81 case 0x21: r->mode_n001 = 1; r->active_mode = TC_NORMAL; break; /* read normal i */
82 case 0x01: r->mode_n002 = 1; r->active_mode = TC_NORMAL; break; /* read normal ii */
83 case 0x24: r->mode_mi01 = 1; r->active_mode = TC_NORMAL; break; /* read mixed i */
84 case 0x04: r->mode_mi02 = 1; r->active_mode = TC_NORMAL; break; /* read mixed ii */
85 case 0x20: r->mode_debi = 1; r->active_mode = TC_COLBIN; break; /* read by-pass / column-binary */
86 case 0xa0: r->mode_debi = 1; r->active_mode = TC_COLBIN; break; /* channel code card: with by-pass */
87 default: latch = 0; break; /* 0x40 etc.: keep mode */
88 }
89 if (latch) { r->cocon = 1; r->active_valid = 1; }
90
91 switch (command) {
92 case 0x40: case 0x21: case 0x01: case 0x24: case 0x04: case 0x20:
93 is_read = 1;
94 break;
95 case 0x47:
96 /* Reset error: clear the error line and let the feed resume. */
97 r->luren = 0;
98 break;
99 case 0x48:
100 /* Card reject: this card leaves the station unread. */
101 r->cmd_reject = 1;
102 break;
103 default:
104 break;
105 }
106
107 /* A read command latches and waits for the feed. Releasing a standing FININ
108 * happens HERE, on the command -- before any ready/busy update -- which is
109 * why the steady loader loop shows no LUPOB ready front between cards. */
110 if (is_read) {
111 r->fini = 0;
112 r->cmd_pending = 1;
113 }
114}
115
116void reader_setup_to_send(struct ge *ge, uint8_t data, uint8_t end)
117{
121
122 /* A byte is now on the data lines: the reader is busy, not free. Holding
123 * LUPOR (reader free) at 0 whenever LU08=1 keeps PELEA = !(LU08 . LUPO1) at
124 * 1, so the read data path is unchanged by the ready line. */
126
127 /* When end=1, set the end-of-transfer flip-flops.
128 *
129 * In the hardware, FINI1 contributes to RF101 through PF12A when the
130 * integrated reader is selected on channel 1 (PC121=1). RF101 is then
131 * stored into RIG1 on the channel timing edge. Here we short-cut that
132 * path and set RIG1 directly because this helper is only used by the
133 * integrated-reader path.
134 *
135 * PEC1 is a second shortcut, but one stage later. The manual routes
136 * peripheral-end completion through the TO50/PIM11 reset chain; gemu now
137 * records that a PEC1 set is pending here and commits it from pulse.c at
138 * TO50, instead of raising PEC1 immediately in the peripheral helper.
139 */
140 if (end) {
141 ge->RIG1 = 1;
142 ge->PEC1_pending = 1;
143 }
144
145 if (RB111(ge)) {
146 ge_log(LOG_READER, "XXX\n");
147 }
148}
149
150/*
151 * Retire the character strobe.
152 *
153 * LU08N comes down and that is all. FININ does NOT: on the wire the end-of-card
154 * word is still standing on the pins after its strobe has gone, because the
155 * presenter has stalled with nothing left to shift out. It stays there until
156 * the next read command (reader_send_tu00), a TU03N, or the reader's own
157 * timeout takes it down -- see cardreader.c cr_finin_release.
158 *
159 * The data lines are left alone for the same reason: what the GE sees between
160 * cards is the last nibble of the last card, not zeroes.
161 */
163{
165}
166
167void reader_send_tu10(struct ge *ge)
168{
169 ge_log(LOG_READER, "EMIT TU101 (CE09)\n");
170
171 /* LENON ("not operable") inhibits the card-feed: a non-operable reader
172 * does not advance under the CPU's feed strobe. */
174 ge_log(LOG_READER, " Card feed INHIBITED (LENON / not operable)\n");
175 return;
176 }
177
178 ge_log(LOG_READER, " Card feed\n");
179
180 /* TU03N card-feed/advance line. Modelled as an explicit pin (Phase 4
181 * switches the cardreader's deck-advance onto this line). */
183}
184
185uint8_t reader_get_LU08(struct ge *ge)
186{
187 ge_log(LOG_READER, "reading LU081 -- character strobe\n");
188
191 " wanting to send char: %02x\n",
193 }
194
195 return ge->integrated_reader.lu08;
196}
197
198uint8_t reader_get_LUPO1(struct ge *ge)
199{
200 /* LUPOR: reader free / ready. Defaults 0 (== the previous hardcoded stub),
201 * so this is inert until Phase 3 drives `lupor`. */
202 return ge->integrated_reader.lupor;
203}
204
205uint8_t reader_get_FINI1(struct ge *ge)
206{
207 ge_log(LOG_READER, "**** reading FINI1 %d\n", ge->integrated_reader.fini);
208 return ge->integrated_reader.fini;
209}
210
211uint8_t connector_get_MARE(struct ge_connector *conn)
212{
213 ge_log(LOG_READER, "%s -- connector_get_MARE\n", conn->name);
214 return conn->mare;
215}
216
217uint8_t connector_get_TE10(struct ge_connector *conn)
218{
219 ge_log(LOG_READER, "%s -- connector_get_TE10\n", conn->name);
220 return conn->te10;
221}
222
223uint8_t connector_get_TE20(struct ge_connector *conn)
224{
225 ge_log(LOG_READER, "%s -- connector_get_TE20\n", conn->name);
226 return conn->te20;
227}
228
229uint8_t connector_get_TE30(struct ge_connector *conn)
230{
231 ge_log(LOG_READER, "%s -- connector_get_TE30\n", conn->name);
232 return conn->te30;
233}
234
235uint8_t connector_get_FINE(struct ge_connector *conn)
236{
237 ge_log(LOG_READER, "%s -- connector_get_FINE\n", conn->name);
238 return conn->fine;
239}
240
241void connector_setup_to_send(struct ge *ge, struct ge_connector *conn, uint8_t data, uint8_t end)
242{
243 /* equivalent of lu08, but not sure if it's TE10 or TE20, seems or-red together
244 * (intermediate fo. 11, D1, D2) */
245
246 conn->te10 = 1;
247 conn->te20 = 1;
248 conn->data = data;
249 conn->fine = end;
250
251 /* Mirror the same end-of-transfer signalling as reader_setup_to_send.
252 * The connector FINE inputs feed RF101 through PF13A/PF14A when the
253 * external unit is selected; gemu still short-circuits the subsequent
254 * RIG1 timing path here, but now defers PEC1 to the TO50 latch point. */
255 if (end) {
256 ge->RIG1 = 1;
257 ge->PEC1_pending = 1;
258 }
259
260 if (RB111(ge)) {
261 ge_log(LOG_READER, "XXX\n");
262 }
263}
264
266{
267 conn->te10 = 0;
268 conn->te20 = 0;
269 conn->data = 0;
270 /* Clear end-of-card strobe to deassert FINE/RF10x for next card. */
271 conn->fine = 0;
272}
273
274void connector_send_tu00(struct ge *ge, struct ge_connector *conn)
275{
276 uint8_t command = ge->rRE;
277
278 switch (command) {
279#define X(cmd, namex, desc) \
280 case cmd: \
281 ge_log(LOG_READER, " connector %s got: %02x - %s\n", conn->name, cmd, desc ); \
282 break;
284#undef X
285 }
286
287 /* Hand the order byte to a Standard-GE-100 controller (disk/tape) on this
288 * connector, if one is attached. Inert when no connector-3/4 core exists. */
289 if (ge->std_core)
291}
void connector34_deliver_order(struct ge *ge, struct ge_connector *conn)
void ge_log(ge_log_type type, const char *format,...)
Log message.
Definition log.c:122
@ LOG_READER
Integrated Reader.
Definition log.h:28
void reader_setup_to_send(struct ge *ge, uint8_t data, uint8_t end)
Definition reader.c:116
uint8_t reader_get_LUPO1(struct ge *ge)
Definition reader.c:198
uint8_t connector_get_TE30(struct ge_connector *conn)
Definition reader.c:229
uint8_t reader_get_LU08(struct ge *ge)
Definition reader.c:185
uint8_t connector_get_MARE(struct ge_connector *conn)
Definition reader.c:211
void connector_clear_sending(struct ge_connector *conn)
Definition reader.c:265
void reader_clear_sending(struct ge *ge)
Definition reader.c:162
void reader_send_tu10(struct ge *ge)
Definition reader.c:167
uint8_t reader_get_FINI1(struct ge *ge)
Definition reader.c:205
void connector_send_tu00(struct ge *ge, struct ge_connector *conn)
Definition reader.c:274
void connector_setup_to_send(struct ge *ge, struct ge_connector *conn, uint8_t data, uint8_t end)
Definition reader.c:241
uint8_t connector_get_TE10(struct ge_connector *conn)
Definition reader.c:217
uint8_t connector_get_TE20(struct ge_connector *conn)
Definition reader.c:223
void reader_send_tu00(struct ge *ge)
Definition reader.c:43
#define ENUMERATE_READER_COMMANDS
Definition reader.c:6
uint8_t connector_get_FINE(struct ge_connector *conn)
Definition reader.c:235
Signals.
uint8_t te20
Definition reader.h:93
uint8_t mare
Definition reader.h:91
uint8_t data
Definition reader.h:89
uint8_t te30
Definition reader.h:94
uint8_t fine
Definition reader.h:95
const char * name
Definition reader.h:87
uint8_t te10
Definition reader.h:92
uint8_t mode_debi
Definition reader.h:50
enum transcode_mode active_mode
Definition reader.h:58
uint8_t cmd_pending
Definition reader.h:68
uint8_t mode_mi01
Definition reader.h:51
uint16_t anomalies
Definition reader.h:73
uint8_t mode_n001
Definition reader.h:48
uint8_t cmd_reject
Definition reader.h:69
uint8_t active_valid
Definition reader.h:59
uint8_t mode_n002
Definition reader.h:49
uint8_t mode_mi02
Definition reader.h:52
The entire state of the emulated system, including registers, memory, peripherals and timings.
Definition ge.h:172
void * std_core
Shared core for Standard-GE-100 controllers on connectors 3/4 (disk/tape).
Definition ge.h:803
uint8_t rRE
Definition ge.h:333
struct ge_integrated_reader integrated_reader
The I/O interface for the integrated reader (RI)
Definition ge.h:744
uint8_t PEC1_pending
Definition ge.h:550
uint8_t RIG1
End from controller 1.
Definition ge.h:656
@ TC_NORMAL
Definition transcode.h:19
@ TC_COLBIN
Definition transcode.h:22