https://gitlab.synchro.net/main/sbbs/-/commit/7460ccb38cc178d2e99bc252
Added Files:
src/conio/cterm_atascii.c cterm_atascii.h cterm_cterm.c cterm_cterm.h cterm_dec.c cterm_dec.h cterm_ecma48.c cterm_ecma48.h cterm_internal.h cterm_petscii.c cterm_petscii.h cterm_prestel.c cterm_prestel.h cterm_vt52.c cterm_vt52.h
Modified Files:
src/conio/CMakeLists.txt cterm.c cterm.h cterm_test.c objects.mk
Log Message:
cterm: refactor to table-driven dispatch
Step one in properly modular emulation.
Replace the 2565-line do_ansi() switch with bsearch-based dispatch
tables keyed by a 21-bit (intro | final | priv | interm) sequence
key, and split the 7988-line cterm.c across per-standard files:
cterm_ecma48.c ECMA-48 CSI/C1 handlers
cterm_dec.c DEC private extensions (DECSM, DECRQM, DECCARA, ...)
cterm_cterm.c SyncTERM/CTerm/XTerm extensions (incl. SCOSC/DECSLRM
dispatcher, ANSI-music vs DL, CTerm RGB palette)
cterm_vt52.c VT52 / Atari ST VT52
cterm_atascii.c Atari 8-bit ATASCII
cterm_petscii.c Commodore C64/C128 PETSCII
cterm_prestel.c Prestel / BEEB serial attrs, VDU 23/28, prog memory
The parser is now an incremental seq_feed() state machine that drops
the legacy three-pass legal_sequence / parse_sequence / parse_parameters pipeline and the heap-allocated struct esc_seq it populated. SGR and
DECCARA read cterm->seq_param_int[] / seq_param_strs[] directly.
cterm_write's byte loop is reduced to the canonical two-check form (pick_accumulator -> dispatch); every emulation installs its own cterm->dispatch pointer at cterm_init time.
Per-emulation dispatch wiring:
* ANSI-BBS and Atari ST VT52 share cterm_accumulate_ecma_seq and
seq_feed, each installing its own sorted dispatch table
(cterm_ansi_dispatch[], cterm_st_vt52_dispatch[]) for bsearch.
VT52 has its own single-byte dispatcher (cterm_dispatch_vt52)
for VT52-specific C0 semantics (VT/FF as LF, bytes 1-6/14-31
silently dropped) while sharing the sequence-parsing path.
* PETSCII and ATASCII use a shared cterm_dispatch_byte with a
256-bit per-emulation ctrl_bitmap[32] marking control bytes and
a byte_handlers[256] table of per-byte handlers. Printable
bytes go through cterm_c64_get_attr. ATASCII's one-shot ESC
inverse installs cterm->accumulator (file-local
atascii_literal_byte) which takes priority in
cterm_pick_accumulator.
* Prestel keeps its custom programmable-memory state machine
(cterm_accumulate_prestel_seq) because the ESC 1 / ESC 2
grammar does not benefit from a bsearch table.
* BEEB has no sequence accumulator; VDU 23 (9 trailing bytes) and
VDU 28 (2 trailing bytes) install the generic
cterm_accumulate_trailing via cterm->seq_trailing_handler.
Supporting machinery:
* Cascade consumption tracking (seq_consumed[] bitmap + seq_consumed_any
latch) so handlers like SGR/DECSM can split across standards without
the "empty list -> apply default" path clobbering already-consumed
parameters.
* Accumulators for multi-byte state: ecma_seq, prestel_seq,
command_string, sos, music, font, doorway, trailing (+ ATASCII's
one-shot atascii_literal_byte installed directly on cterm).
* Dispatch entries carry a `trailing` count; when set, the matching
handler is deferred until cterm_accumulate_trailing collects N
raw bytes into seq_param_int[] (VT52 ESC Y / ESC b / ESC c).
* Handlers in new files follow a cterm_handle_<name> convention;
promoted statics uniformly gain the cterm_ prefix. The static
library exports no unprefixed symbols.
283/283 cterm_test + 67/67 termtest cases pass.
Co-Authored-By: Claude Opus 4.7 (1M context) <
noreply@anthropic.com>
---
■ Synchronet ■ Vertrauen ■ Home of Synchronet ■ [vert/cvs/bbs].synchro.net