GE-115 Emulator
An Emulator of the General Electrics GE-115 computer
cardreader.c
Go to the documentation of this file.
1/*
2 * cardreader.c - Connector-2 punch-card-reader peripheral for the GE-120 emulator.
3 *
4 * Feeds a .cap punch-card deck into the CPU via the existing integrated-reader
5 * handshake (reader_setup_to_send / reader_clear_sending), mirroring the
6 * manual cadence demonstrated in tests/initial-load.c.
7 *
8 * Handshake cadence (derived from initial-load.c):
9 *
10 * The machine enters the "input wait" loop (state b8 / b9). While
11 * waiting it polls LU081 (lu08). When lu08 == 0, the reader has no
12 * character ready, so the machine keeps looping.
13 *
14 * Our on_clock callback runs once per machine cycle, at TO00 (the first
15 * clock pulse of the new cycle, before MSL logic executes).
16 *
17 * Per-byte state machine:
18 * CR_IDLE: lu08 == 0 and RASI==1 → present byte → CR_PRESENTED
19 * CR_PRESENTED: (next clock) → clear byte, lu08 → 0 → CR_IDLE or CR_CARD_DONE
20 * CR_CARD_DONE: end-of-card consumed; wait for RASI==0 → CR_IDLE
21 * CR_DONE: deck exhausted; do nothing
22 *
23 * This reproduces the exact pattern:
24 * reader_setup_to_send(...) -- before b8/b9 cycle
25 * [ge_run_cycle b8/b9] -- machine reads nibble into mem[]
26 * reader_clear_sending(...) -- before b1 cycle
27 * [ge_run_cycle b1] -- machine packs nibble
28 *
29 * End-of-card / multi-card:
30 * The 'end' flag is set on the last column of the CURRENT card. This
31 * signals the machine to run the load-end sequence (ea → eb → e3).
32 * After the end byte is consumed, the cardreader enters CR_CARD_DONE and
33 * waits for RASI to drop (the machine clears RASI in state b8 TO70).
34 * Once RASI is 0, CR_CARD_DONE → CR_IDLE with the pointer already at
35 * card N+1, col 0. On the machine's next PER read (RASI=1 again), the
36 * cardreader presents the next card's bytes automatically.
37 */
38
39#include "cardreader.h"
40
41#include <stdlib.h>
42#include <stdio.h>
43
44#include "cap.h"
45#include "reader.h"
46#include "log.h"
47
48/* -------------------------------------------------------------------------
49 * Private state
50 * ------------------------------------------------------------------------- */
51
52/* Feeding state machine */
54 CR_IDLE, /* no character currently presented; ready to feed next */
55 CR_PRESENTED, /* character has been presented; waiting for machine to consume */
56 CR_CARD_DONE, /* end-of-card byte was consumed; wait for RASI to drop before
57 * starting the next card (avoids presenting card N+1 bytes
58 * during the ea/eb end-of-transfer cleanup sequence) */
59 CR_DONE, /* deck exhausted; nothing more to send */
60};
61
63 struct cap_deck *deck;
65
66 /* The loader card (the first card fed) is read in `mode` (TC_HEX for the
67 * "130 CPU FUNCTIONAL TEST" deck). After the loader sets "by-pass", the
68 * program cards are read in binary, so every card after the loader card
69 * is fed as TC_BINARY. */
71
72 int card_idx; /* index of the current card in the deck */
73 int col_idx; /* index of the current column within the current card */
74
75 /* pre-computed index of last non-empty card and its last column */
78
80
81 /* Set to 1 when the end-of-card byte was presented (end=1 flag).
82 * Used to transition to CR_CARD_DONE after CR_PRESENTED is cleared. */
84
85 /* Set to 1 when the last column of a card has been presented and the
86 * cross-to-next-card advance has been deferred until the CPU raises the
87 * TU03N end-of-card feed strobe (state ea). Honoured by the TU03 pulse
88 * handler at the top of on_clock. The per-column advance within a card is
89 * NOT gated by TU03 — that cadence stays on the lu08 read handshake. */
91
92 /* Packed / self-loading mode (cardreader_register_packed). The channel-1
93 * input-transfer microcode always packs TWO presented nibbles into one
94 * memory byte. A self-loading SMAC .cap holds the program as full COLBIN
95 * bytes (1 col -> 1 byte), so to land each byte intact we present it as a
96 * hi-then-lo nibble pair; the packer rebuilds the original byte. (This is
97 * also how the real machine reads: the IPL packs the hex loader card, and
98 * after "set by-pass" each binary column delivers a full byte — equivalent
99 * to two packed nibbles here.) `half` tracks which nibble is pending. */
100 int pack;
101 int half; /* 0 = high nibble pending, 1 = low nibble pending */
103
104 /* the ge_peri node we allocated (kept for potential future use) */
105 struct ge_peri peri;
106};
107
108/* Detect the functional-test Hollerith bootstrap loader among the early cards
109 * of a mixed deck. The matching card is punched as hex nibbles and is the one
110 * selected by a row-8 punch in column 3; after TC_HEX decode it begins with
111 * repeated `PER 0x80` orders (`9E 80 ... 9E 80 ...`). Returns the card index,
112 * or -1 if no such card is present. */
114{
115 int ncards = cap_num_cards(deck);
116
117 for (int i = 0; i < ncards && i < 16; i++) {
118 int ncols = cap_card_ncols(deck, i);
119 const uint16_t *cols;
120 uint8_t b[6];
121
122 if (ncols < 12)
123 continue;
124
125 cols = cap_card_columns(deck, i);
126 if (!cols)
127 continue;
128
129 /* The correct CR10/Hollerith loader is identified in the deck notes by
130 * a row-8 punch in column 3. */
131 if (cols[2] != 0x0100)
132 continue;
133
134 for (int j = 0; j < 12; j++) {
135 uint8_t nib = transcode_column(cols[j], TC_HEX) & 0x0f;
136 if ((j & 1) == 0)
137 b[j >> 1] = (uint8_t)(nib << 4);
138 else
139 b[j >> 1] |= nib;
140 }
141
142 if (b[0] == 0x9e && b[1] == 0x80 &&
143 b[2] == 0x00 && b[4] == 0x9e && b[5] == 0x80)
144 return i;
145 }
146
147 return -1;
148}
149
150/* -------------------------------------------------------------------------
151 * Helper: advance card/column, skipping empty cards.
152 * Returns 1 if there is more data, 0 if the deck is exhausted.
153 * ------------------------------------------------------------------------- */
154static int cr_advance(struct cardreader_ctx *ctx)
155{
156 ctx->col_idx++;
157
158 /* Move to next non-empty card if we finished this one */
159 while (ctx->card_idx < cap_num_cards(ctx->deck)) {
160 if (ctx->col_idx < cap_card_ncols(ctx->deck, ctx->card_idx))
161 return 1; /* still inside current card */
162 /* exhausted current card; try next */
163 ctx->card_idx++;
164 ctx->col_idx = 0;
165 /* skip empty cards */
166 while (ctx->card_idx < cap_num_cards(ctx->deck) &&
167 cap_card_ncols(ctx->deck, ctx->card_idx) == 0)
168 ctx->card_idx++;
169 }
170
171 return 0; /* deck exhausted */
172}
173
174/* -------------------------------------------------------------------------
175 * Peripheral callbacks
176 * ------------------------------------------------------------------------- */
177
178/*
179 * on_clock: called at TO00, the first clock of every new machine cycle.
180 *
181 * Feeding is gated on ge->RASI (channel 1 in transfer). RASI is set by
182 * the machine at state 0xab (TPER-CPER 5) just before it enters the
183 * input-wait loop (state 0xb8). Before that point, presenting bytes
184 * would be silently ignored by the machine but would consume our deck.
185 *
186 * State machine transitions (per-card):
187 *
188 * CR_IDLE: if RASI==1 and lu08==0
189 * → reader_setup_to_send(byte, end)
190 * → record end_of_card_presented
191 * → advance deck pointer to next column / next card
192 * → CR_PRESENTED
193 *
194 * CR_PRESENTED: (next clock after machine consumed the byte)
195 * → reader_clear_sending() (clears lu08 and fini)
196 * → if end_of_card_presented → CR_CARD_DONE
197 * → else → CR_IDLE (then retry)
198 *
199 * CR_CARD_DONE: end-of-card byte was consumed; do NOT yet present the next
200 * card because RASI may still be 1 from the just-finished
201 * transfer (it gets cleared by state_b8 TO70 / CI39).
202 * Wait for RASI to drop to 0, then transition to CR_IDLE.
203 * The existing RASI gate in CR_IDLE ensures no bytes are
204 * presented until the machine starts a new transfer (RASI=1).
205 *
206 * CR_DONE: deck exhausted; do nothing.
207 *
208 * Multi-card sequencing
209 * ---------------------
210 * The deck pointer (card_idx, col_idx) is advanced BEFORE transitioning to
211 * CR_PRESENTED. When cr_advance() returns 0 (whole deck exhausted), state
212 * goes to CR_DONE after the end byte is consumed. When cr_advance() returns
213 * 1 (more cards remain), state goes to CR_CARD_DONE; the pointer already
214 * sits at card N+1, col 0, ready for the next PER read.
215 */
216static int cardreader_on_clock(struct ge *ge, void *opaque)
217{
218 struct cardreader_ctx *ctx = (struct cardreader_ctx *)opaque;
219 int pack_now;
220
221 /* TU03N card-feed strobe (CE09), read as a one-cycle pulse: the CPU raises
222 * it at end-of-card (state ea). We latch and clear it here at TO00 so it
223 * reads as the previous cycle's pulse. A card-boundary advance deferred when
224 * the last column was presented is the reader physically feeding the card
225 * out and bringing the next under the read station — it happens in response
226 * to this strobe rather than autonomously. */
227 {
228 int feed = ge->integrated_reader.tu03;
230 if (feed && ctx->feed_pending) {
231 cr_advance(ctx);
232 ctx->feed_pending = 0;
233 }
234 }
235
236 /* LUSEN (out-of-service) / LUREN (error or card jam): the reader cannot
237 * deliver data — present nothing and report not-ready, so a read parks /
238 * completes as unit-not-ready or in error rather than getting data. (Both
239 * default 0: normal operation, no change.) */
242 return 0;
243 }
244
245 /* LUPOR (reader free / ready): asserted while the reader is not finished and
246 * not presenting a byte. Held 0 whenever a byte is on the data lines
247 * (lu08=1) so PELEA = !(LU08 . LUPO1) stays 1 (the read path is unchanged). */
249 (ctx->state != CR_DONE) && !ge->integrated_reader.lu08;
250
251 if (ctx->state == CR_DONE) {
252 ge->integrated_reader.fiden = 1; /* FIDEN: end-of-sequence (deck done) */
253 return 0;
254 }
255
256 if (ctx->state == CR_CARD_DONE) {
257 /* Wait for RASI to drop (end of the previous card's transfer).
258 * Once RASI is 0 we return to CR_IDLE. The RASI gate in CR_IDLE
259 * will prevent feeding until the machine starts a new transfer. */
260 if (!ge->RASI) {
261 ctx->state = CR_IDLE;
262 }
263 return 0;
264 }
265
266 if (ctx->state == CR_PRESENTED) {
267 /* The machine completed the input cycle; retire the previous char.
268 *
269 * Important: do NOT immediately present the next byte in the same
270 * on_clock call. The cadence from initial-load.c is:
271 * [b9 cycle with lu08=1] <- machine reads nibble
272 * on_clock: clear <- lu08 → 0 (this call, return now)
273 * [b1 cycle with lu08=0] <- machine packs nibble
274 * on_clock: present next byte <- lu08 → 1 (next call)
275 * [b9 cycle with lu08=1] <- machine reads next nibble
276 *
277 * Returning here ensures we wait one cycle (the b1 pack cycle) before
278 * presenting the next byte.
279 */
280 reader_clear_sending(ge); /* clears lu08, data, and fini */
281 if (ctx->end_of_card_presented) {
282 ctx->end_of_card_presented = 0;
283 ctx->state = CR_CARD_DONE;
284 } else {
285 ctx->state = CR_IDLE;
286 }
287 return 0; /* wait one more cycle before presenting the next byte */
288 }
289
290 if (ctx->state == CR_IDLE) {
291 /*
292 * Only feed when the machine has entered the channel-1 transfer phase
293 * (RASI==1). This prevents consuming deck bytes during the peri-init
294 * states (00, 80, c8 ... ab) where the machine is not yet waiting for
295 * card data.
296 */
297 if (!ge->RASI)
298 return 0; /* not in transfer phase yet */
299
300 /* Only present if the integrated reader is not already busy */
301 if (ge->integrated_reader.lu08 != 0)
302 return 0; /* still being consumed from a previous cycle */
303
304 if (ctx->card_idx >= cap_num_cards(ctx->deck)) {
305 ctx->state = CR_DONE;
306 return 0;
307 }
308
309 int ncols = cap_card_ncols(ctx->deck, ctx->card_idx);
310 if (ncols == 0 || ctx->col_idx >= ncols) {
311 /* Shouldn't happen if cr_advance is correct, but guard anyway */
312 ctx->state = CR_DONE;
313 return 0;
314 }
315
316 const uint16_t *cols = cap_card_columns(ctx->deck, ctx->card_idx);
317 /* Read mode. If the CPU has driven a mode-select read command (the
318 * loader's "set by-pass" — active_valid set by COCON; see reader.c) and
319 * this is not a packed self-loading deck, the reader transcodes in the
320 * CPU-selected active_mode. Otherwise the legacy harness selection holds:
321 * packed decks use the registered COLBIN mode; legacy decks read the
322 * loader card in the registered mode and the program cards in TC_BINARY
323 * ("by-pass"). */
324 enum transcode_mode m;
325 pack_now = ctx->pack || (ctx->post_loader_pack &&
326 ctx->card_idx != ctx->loader_card);
327 if (ctx->pack)
328 m = ctx->mode;
329 else if (ctx->card_idx == ctx->loader_card)
330 /* The loader card (first card) is read in the IPL's own loader mode
331 * = the registered mode (TC_HEX for the real "4 hex loader cards",
332 * which encode 0-F per column; the channel packs two columns into a
333 * byte). The CPU-driven mode-select (active_mode, from COCON) only
334 * offers NORMAL/BINARY and would corrupt an A-F hex nibble, so it
335 * must NOT override the loader card — it applies to the PROGRAM
336 * cards the loader's Set-by-Pass selects. */
337 m = ctx->mode;
338 else if (ctx->post_loader_pack)
339 /* The recovered loader program reads the following program cards in
340 * by-pass / column-binary form. The current signal-level model does
341 * not yet expose a distinct "non-packed by-pass" transfer state, so
342 * we feed each decoded COLBIN byte as a hi/lo nibble pair through
343 * the existing channel-1 packer. */
344 m = TC_COLBIN;
347 else
348 m = TC_BINARY;
349 uint8_t byte = transcode_column(cols[ctx->col_idx], m);
350
351 /* End-of-card: the GE reader raises FINI (the controller "end" RIG1)
352 * at every physical card boundary. Per CPU[4] §5.8.4.3 a transfer ends
353 * on (a) the instruction length L1+1 being exhausted, or (b) this
354 * peripheral "end". gemu now counts L1 down (the counting network honours
355 * the decrement), but the L1-exhausted -> RIVE path isn't fully wired for
356 * the integrated-reader handshake yet, so end-of-card (b) still bounds a
357 * read here. (Note: RAMO/RAMI is the CPU cycle-period counter, §6.7.5, not
358 * the read-length counter.) Signal end on the last column of the CURRENT
359 * card, not the whole deck. */
360 int is_last_col = (ctx->col_idx == ncols - 1);
361
362 /* The channel-1 input transfer packs TWO presented nibbles into one
363 * memory byte. In packed mode the .cap holds full COLBIN bytes, so we
364 * present each as a hi-then-lo nibble pair and the packer rebuilds the
365 * byte (1 col -> 1 byte). FINI rides the LOW nibble of the last column.
366 * In legacy mode one full value is presented per column. */
367 uint8_t present;
368 int is_last;
369 if (pack_now) {
370 present = (ctx->half == 0) ? (uint8_t)((byte >> 4) & 0x0f)
371 : (uint8_t)(byte & 0x0f);
372 is_last = (ctx->half == 1) && is_last_col;
373 } else {
374 present = byte;
375 is_last = is_last_col;
376 }
377
379 "cardreader: presenting card %d col %d half %d byte=0x%02x val=0x%02x end=%d\n",
380 ctx->card_idx, ctx->col_idx, ctx->half, byte, present, is_last);
381
382 /* Drive the reader's observable feed-state lines for this character:
383 * POM01 — binary-mode (by-pass) indicator: high for raw binary reads.
384 * PICON — first-column check: high on column 0 of a card.
385 * BI20 — binary 2nd-nibble clock: high while the low nibble of a
386 * packed binary column is on the lines (the second sub-read).
387 * Nothing in the CPU state logic consumes these yet; they make the read
388 * mode / framing visible at the pins. */
389 ge->integrated_reader.pom01 = (m == TC_BINARY || m == TC_COLBIN);
390 ge->integrated_reader.picon = (ctx->col_idx == 0);
391 ge->integrated_reader.bi20 = (pack_now && ctx->half == 1);
392
393 reader_setup_to_send(ge, present, is_last ? 1 : 0);
394 ctx->end_of_card_presented = is_last;
395 ctx->state = CR_PRESENTED;
396
397 /* Advance. In packed mode present the LOW nibble of the same column on
398 * the next call (do not move the pointer); only after the low nibble do
399 * we advance to the next column / card. For a multi-card deck cr_advance
400 * moves to (card+1, col 0), ready for the next PER read. */
401 if (pack_now && ctx->half == 0) {
402 ctx->half = 1;
403 } else {
404 ctx->half = 0;
405 if (is_last_col) {
406 /* Only the bootstrap loader card uses the explicit TU03 feed
407 * pulse (state ea). Once that loader has switched the reader to
408 * by-pass and is pulling binary program cards into its buffer,
409 * the next card becomes visible at the transfer boundary rather
410 * than waiting for the bootstrap-only TU03 path. */
411 if (ctx->card_idx == ctx->loader_card && !ctx->pack)
412 ctx->feed_pending = 1;
413 else
414 cr_advance(ctx);
415 } else {
416 cr_advance(ctx);
417 }
418 }
419 }
420
421 return 0;
422}
423
424static int cardreader_deinit(struct ge *ge, void *opaque)
425{
426 struct cardreader_ctx *ctx = (struct cardreader_ctx *)opaque;
427 (void)ge;
428 if (ctx) {
429 cap_free(ctx->deck);
430 free(ctx);
431 }
432 return 0;
433}
434
435/* -------------------------------------------------------------------------
436 * Public API
437 * ------------------------------------------------------------------------- */
438
439static int cr_register(struct ge *ge, const char *cap_path,
440 enum transcode_mode mode, int first_card, int pack);
441
442int cardreader_register(struct ge *ge, const char *cap_path,
443 enum transcode_mode mode)
444{
445 return cr_register(ge, cap_path, mode, 0, 0);
446}
447
448int cardreader_register_from(struct ge *ge, const char *cap_path,
449 enum transcode_mode mode, int first_card)
450{
451 return cr_register(ge, cap_path, mode, first_card, 0);
452}
453
454/* Self-loading SMAC deck: feed every card's COLBIN bytes as hi/lo nibble pairs
455 * so the channel-1 packing transfer reconstructs the full bytes (1 col -> 1
456 * byte), letting the deck's own loader chain (PER reads + MVC relocation)
457 * assemble the program in memory. */
458int cardreader_register_packed(struct ge *ge, const char *cap_path,
459 enum transcode_mode mode)
460{
461 return cr_register(ge, cap_path, mode, 0, 1);
462}
463
464static int cr_register(struct ge *ge, const char *cap_path,
465 enum transcode_mode mode, int first_card, int pack)
466{
467 struct cap_deck *deck = cap_load(cap_path);
468 int auto_loader = -1;
469 if (!deck) {
470 fprintf(stderr, "cardreader: failed to load deck '%s'\n", cap_path);
471 return -1;
472 }
473
474 struct cardreader_ctx *ctx = calloc(1, sizeof(*ctx));
475 if (!ctx) {
476 cap_free(deck);
477 return -1;
478 }
479
480 ctx->deck = deck;
481 ctx->mode = mode;
482 ctx->pack = pack;
483 ctx->half = 0;
484 ctx->state = CR_IDLE;
485
486 /* A plain `cardreader_register(..., TC_NORMAL)` on a real mixed deck should
487 * start from the Hollerith bootstrap loader, not from whichever control
488 * card happens to be first in the capture. Once identified, read that one
489 * card in TC_HEX; later cards still switch to binary via the normal
490 * active-mode/by-pass path. */
491 if (!pack && mode == TC_NORMAL && first_card == 0)
492 auto_loader = cr_find_hollerith_loader_card(deck);
493 if (auto_loader >= 0)
494 ctx->mode = TC_HEX;
495 ctx->post_loader_pack = !ctx->pack && ctx->mode == TC_HEX;
496
497 /* Find the first non-empty card at or after first_card */
498 ctx->card_idx = auto_loader >= 0 ? auto_loader : (first_card < 0 ? 0 : first_card);
499 ctx->col_idx = 0;
500 while (ctx->card_idx < cap_num_cards(deck) &&
501 cap_card_ncols(deck, ctx->card_idx) == 0)
502 ctx->card_idx++;
503
504 /* The first card we feed is the loader card (read in `mode`); later cards
505 * are program cards read in binary. */
506 ctx->loader_card = ctx->card_idx;
507
508 if (ctx->card_idx >= cap_num_cards(deck)) {
509 /* All cards are empty — nothing to send */
510 ctx->state = CR_DONE;
511 ctx->last_card = -1;
512 ctx->last_col = -1;
513 } else {
514 /* Pre-compute last non-empty card and its last column */
515 ctx->last_card = ctx->card_idx; /* start with first non-empty */
516 ctx->last_col = 0;
517 for (int i = ctx->card_idx; i < cap_num_cards(deck); i++) {
518 int nc = cap_card_ncols(deck, i);
519 if (nc > 0) {
520 ctx->last_card = i;
521 ctx->last_col = nc - 1;
522 }
523 }
524 }
525
527 "cardreader: loaded '%s', %d cards, last non-empty card=%d col=%d\n",
528 cap_path, cap_num_cards(deck), ctx->last_card, ctx->last_col);
529
530 /* Initialise the ge_peri node embedded in ctx */
531 ctx->peri.next = NULL;
532 ctx->peri.init = NULL;
533 ctx->peri.on_pulse = NULL;
536 ctx->peri.ctx = ctx;
537
538 return ge_register_peri(ge, &ctx->peri);
539}
const uint16_t * cap_card_columns(const struct cap_deck *d, int i)
Definition cap.c:214
int cap_card_ncols(const struct cap_deck *d, int i)
Definition cap.c:207
int cap_num_cards(const struct cap_deck *d)
Definition cap.c:200
void cap_free(struct cap_deck *d)
Definition cap.c:263
struct cap_deck * cap_load(const char *path)
Definition cap.c:124
int cardreader_register_packed(struct ge *ge, const char *cap_path, enum transcode_mode mode)
Definition cardreader.c:458
static int cr_advance(struct cardreader_ctx *ctx)
Definition cardreader.c:154
static int cardreader_deinit(struct ge *ge, void *opaque)
Definition cardreader.c:424
cr_state
Definition cardreader.c:53
@ CR_IDLE
Definition cardreader.c:54
@ CR_CARD_DONE
Definition cardreader.c:56
@ CR_PRESENTED
Definition cardreader.c:55
@ CR_DONE
Definition cardreader.c:59
static int cardreader_on_clock(struct ge *ge, void *opaque)
Definition cardreader.c:216
int cardreader_register(struct ge *ge, const char *cap_path, enum transcode_mode mode)
Definition cardreader.c:442
static int cr_find_hollerith_loader_card(struct cap_deck *deck)
Definition cardreader.c:113
int cardreader_register_from(struct ge *ge, const char *cap_path, enum transcode_mode mode, int first_card)
Definition cardreader.c:448
static int cr_register(struct ge *ge, const char *cap_path, enum transcode_mode mode, int first_card, int pack)
Definition cardreader.c:464
int ge_register_peri(struct ge *ge, struct ge_peri *p)
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:64
void reader_clear_sending(struct ge *ge)
Definition reader.c:98
Definition cap.c:35
enum transcode_mode mode
Definition cardreader.c:64
struct ge_peri peri
Definition cardreader.c:105
struct cap_deck * deck
Definition cardreader.c:63
int end_of_card_presented
Definition cardreader.c:83
enum cr_state state
Definition cardreader.c:79
enum transcode_mode active_mode
Definition reader.h:50
uint8_t active_valid
Definition reader.h:51
Definition ge.h:732
int(* on_pulse)(struct ge *, void *)
Definition ge.h:735
void * ctx
Definition ge.h:738
struct ge_peri * next
Definition ge.h:733
int(* init)(struct ge *, void *)
Definition ge.h:734
int(* deinit)(struct ge *, void *)
Definition ge.h:737
int(* on_clock)(struct ge *, void *)
Definition ge.h:736
The entire state of the emulated system, including registers, memory, peripherals and timings.
Definition ge.h:96
struct ge_integrated_reader integrated_reader
The I/O interface for the integrated reader (RI)
Definition ge.h:595
uint8_t RASI
Channel 1 in transfer.
Definition ge.h:404
uint8_t transcode_column(uint16_t column, enum transcode_mode mode)
Definition transcode.c:564
transcode_mode
Definition transcode.h:18
@ TC_NORMAL
Definition transcode.h:19
@ TC_BINARY
Definition transcode.h:20
@ TC_COLBIN
Definition transcode.h:22
@ TC_HEX
Definition transcode.h:21