Implement virtual serial channels and a TCP listen mode for emulator guests#6
Implement virtual serial channels and a TCP listen mode for emulator guests#6peacedudes wants to merge 10 commits into
Conversation
To try itxcodebuild -project swift/DriveWire.xcodeproj -scheme drivewire-cli -configuration Debug build
drivewire-cli --becker-port 65504 --drive0 <your disk> --verboseThen point an emulator's becker port at it — XRoar's default target is already xroar -m coco3 -cart becker ...Boot a DW4-capable NitrOS-9 (the EOU and on the host, channel 1 is TCP port 6811: nc localhost 6811One gotcha before you judge it broken: raw The harness we drive it with — tmux session wrapping drivewire-cli + XRoar + |
…ds, documented buffering semantics, edge tests
|
Updated: the branch now merges your current main (the new host with the dw command API is taken as-is) and re-attaches just the TCP transport on top: |
This implements the virtual serial channel side of the DriveWire protocol
in the Swift host, and adds a TCP listening driver so emulators like
XRoar and MAME (whose "becker port" connects out to a DriveWire server)
can use it. Everything follows
DriveWire Specification.mdin this repo.What's included
VirtualChannel+ all nine serial opcodes inDriveWireHost(
OP_SERINIT/SERTERM/SERSETSTAT/SERGETSTAT/SERREAD/SERREADM/SERWRITE/ SERWRITEM/FASTWRITE), replacing the previous stubs. Each processorconsumes the exact operand length from the spec so the byte stream can't
desync (the stubs returned 1 unconditionally, which desynced on any real
guest traffic). The SERREAD poll response implements the full response
table: single interactive byte, bulk count for SERREADM, channel-closed
status, with round-robin fairness between channels.
channelDataAvailable(host:channel:data:)with a protocol-extension default, so existing conformers compile
unchanged.
DriveWireTCPServerDriver(Network.framework): listens for theemulator on a becker port (default 65504) and bridges each virtual
channel N to its own TCP port (
channelPortBase + N) — connect withnc/telnet and you're talking to
/N1on the guest. Output while noclient is attached is buffered (bounded) and replayed on connect.
drivewire-cli --becker-portlisten mode alongside the existingserial mode (
--channel-port-base,--channels;validate()requiresexactly one of
--port/--becker-port).split across reads), poll/read cycles, over-request handling, and a
real-socket loopback test of the TCP driver.
Scope note
The per-channel TCP bridges are part of the new TCP server driver, so the
full experience (connect to a port, get a
/N1session) is available in--becker-portmode today. In serial mode (--port, real hardware) thehost now parses and tracks all virtual-channel traffic correctly, but no
consumer is wired to the channels yet —
DriveWireDelegate. channelDataAvailableandDriveWireHost.writeToChannel(_:channel:)arethe seam; attaching the same TCP bridges to the serial driver would be a
natural follow-up.
Two guest-compatibility fixes found by live NitrOS-9 testing
Tested end-to-end against NitrOS-9 EOU (dw_becker) under XRoar:
zero response as a DW3 server and disables its DW4 extensions —
including the virtual channel poller, so SERREAD polling never starts.
The host now answers
0xFF.$64 $00pairs (OP_SERWRITEM naming anever-opened channel, with no count byte). Parsing a count there
swallows the following ~100 bytes (including the guest's SERINIT).
The host now consumes exactly two bytes for a SERWRITEM addressed to an
unopened channel, matching how existing servers behave.
Also fixed en route
DriveWireTeststarget deployment 13.0 → 14.1 (@ObservableinDriveWireHostrequires 14+; the test target didn't build).testInsertreferenced a nonexistentDriveWireErrorenum(→
DriveWireHostError).Verification
xcodebuild -scheme DriveWire test— all new tests pass (twopre-existing tests reference a local disk image path and are untouched).
-cart-becker; a shell on/N1is fully usable overnc localhost 6811—mdir,dir,dateall round-trip.
🤖 Generated with Claude Code