Skip to content

RunCPM: RSX-style bar-command gate for the CCP - #1404

Open
peterkaczorowski wants to merge 5 commits into
FujiNetWIFI:masterfrom
peterkaczorowski:runcpm-bar-on-cpmbase
Open

RunCPM: RSX-style bar-command gate for the CCP#1404
peterkaczorowski wants to merge 5 commits into
FujiNetWIFI:masterfrom
peterkaczorowski:runcpm-bar-on-cpmbase

Conversation

@peterkaczorowski

Copy link
Copy Markdown
Contributor

Summary

Routes any CCP line whose first non-space character is | to a host-side gate
(vm_bar.cpp) instead of treating it as a CP/M command — RSX-style host
commands from the CP/M prompt. Rebased onto the cpmDevice + 6.9 + telnet stack;
the tip of the consolidation series.

Stacks on #1403 (TELNET console) → #1402 (engine 6.9 on cpmDevice) → #1401
(cpmDevice consolidation). Merge in order #1401#1402#1403 → this.

What changed

  • lib/device/sio/vm_bar.{cpp,h} — the bar-command gate, decoupled from
    RunCPM internals via a small vm_bar_io callback struct so the single shared
    core can drive it from every transport (SIO G/R:, N:CPM://, telnet).
  • lib/runcpm/ccp.h (+57) — the CCP hook that diverts a leading-| line to
    the gate. Applies on top of the verbatim 6.9 ccp.h from RunCPM: upgrade engine to 6.9 on the shared cpmDevice base #1402.
  • Verbs shipped: |wget, |ftp, |fn, |apt, |help, and |say (SAM
    text-to-speech out the SIO AUDIO line).

Build / test

  • Desktop ATARI links clean.
  • ESP32 fujinet-atari-v1: builds clean, RAM 36.6%, Flash 24.3%.
  • Verified on real FujiNet ESP32 (Atari): |help lists the verbs; |say,
    |ftp, |fn, |wget, |apt run from the CP/M prompt across SIO and telnet
    transports.

All lib/device/*/cpm devices were near-identical and each embedded its own
copy of the RunCPM engine. Introduce a single lib/device/cpm base class
(cpmDevice, plus cpmQueueDevice for buses whose engine runs on its own task)
and a single shared engine TU (runcpm_core.cpp via runcpm_session.h). Per-bus
devices now override only four console-endpoint primitives.

Buses without a working CP/M console (rc2014, rs232) inherit a default
clean-exit endpoint instead of returning hardcoded values, so CP/M cold-boots
and exits cleanly everywhere. Fold N:CPM:// onto the same shared engine.

Built against the current RunCPM 5.8 (no engine version change).
Bumps the vendored RunCPM engine from 5.8 to 6.9 while keeping the
cpmDevice base-class architecture introduced in the previous commit.

The engine-side files are a matched set taken from upstream RunCPM 6.9:
ccp.h, cpm.h, cpu.h (+cpu_mhz.h, +debug.h), disk.h, console.h, host.h,
ram.h, resource.h and globals.h, plus the 6.9 single-core glue
(runcpm_core.cpp, runcpm_session.h, abstraction_fujinet_core.h, which
replaces abstraction_fujinet.h).

6.9's console interface adds a getche primitive (blocking read + echo)
and widens getch/getche/kbhit to int.  Rather than add a per-bus
override, cpmDevice synthesises getche generically (read endpoint byte,
mask to 7 bits, echo via putch) so no transport had to change: the SIO,
IWM, DriveWire, RS232 and RC2014 devices keep their existing ep_*
overrides untouched.  The N:CPM:// adapter (network-protocol/CPM.cpp),
which is not a cpmDevice, gets the same small getche shim.

Builds clean on desktop ATARI and APPLE (cpmQueueDevice path) and on the
ESP32 fujinet-atari-v1 target (RAM 36.6%, Flash 24.2%).
Add a second access path to the shared RunCPM core: a TELNET console
that the Atari reaches via the FujiNet N:TELNET://127.0.0.1:8677 device.
The acceptor binds to loopback only and is started from fn_service_loop()
after fnWiFi.start() has brought up the lwIP stack (starting it earlier
panicked in tcpip_send_msg_wait_sem() with an uninitialised mbox), and is
torn down in main() before static destruction so detached worker threads
do not race the queue mutexes at exit.  Also lets the reset button preempt
an active session and yields core 1 in the idle kbhit poll to avoid an
ESP32 watchdog hang.
peterkaczorowski and others added 2 commits July 1, 2026 22:59
Route any CCP line whose first non-space character is '|' to a host-side
gate (vm_bar.cpp) instead of treating it as a CP/M command.  The gate is
decoupled from RunCPM internals via a small vm_bar_io callback struct, so
the single shared core can drive it from every transport (SIO 'G' / R:,
N:CPM://, telnet).  Ships the verbs |wget, |ftp, |fn, |apt, |help and
|say (SAM text-to-speech out the SIO AUDIO line).
_perform() spawns _perform_subtask on a 4 KB stack that must come from
INTERNAL RAM.  When internal RAM is exhausted xTaskCreate() fails silently:
the subtask never runs, the following ulTaskNotifyTake() blocks for its full
20 s timeout, and the call finally returns a misleading -1 after a long hang.

Check the xTaskCreate() result and, on failure, log the free internal heap
and return -1 immediately instead of hanging.  Also drop a stale commented-out
debug line in _perform_subtask.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@peterkaczorowski
peterkaczorowski force-pushed the runcpm-bar-on-cpmbase branch from 6c0359c to 9716e3d Compare July 1, 2026 21:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant