Skip to content

Es40 port from gdwnldsksc (using claude) - #129

Merged
RaymiiOrg merged 41 commits into
lenticularis39:mainfrom
RaymiiOrg:es40-ports-from-gdwnldsKSC
Jul 11, 2026
Merged

RaymiiOrg merged 41 commits into
lenticularis39:mainfrom
RaymiiOrg:es40-ports-from-gdwnldsKSC

Conversation

@RaymiiOrg

@RaymiiOrg RaymiiOrg commented Jul 10, 2026

Copy link
Copy Markdown
Collaborator

This is a port of most changes from https://github.com/ES40-Emu/es40 via Claude, as we have earlier discussed by email. I haven't been able to test the Windows build. The Linux build (via WSL) is able to boot Windows 2000. This should fix #95

RaymiiOrg added 30 commits July 10, 2026 21:31
Stage 1 of the ES40-Emu revival port: bump CMAKE_CXX_STANDARD from 11 to
17. Required by the MAME-derived VGA code and the asmjit-based JIT that
later stages bring in.

Verified: clean Release build, SRM boots to P00>>> (test/rom/test.sh).

Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stage 2: support files the later S3Trio64/VGA/JIT ports depend on:
mame_shims.hpp (bitmap/rectangle/device stubs), emu/emu.hpp,
address_map.hpp, coretmpl.hpp, attotime.hpp, xtal.hpp, logmacro.hpp,
diag_rpcc.hpp (RPCC wall-clock backdoor) and the i2c_spd memory SPD
EEPROM device used by ARC memory detection. Only i2c_spd.cpp is
compiled so far; nothing references the new code yet.

Verified: clean build, SRM boots to P00>>>.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stage 3 of the ES40-Emu port:
- System gains the Tsunami CCHIP MPD register (0x0C0) wired to an I2C
  bus with SPD EEPROMs generated from the configured memory size (ARC
  memory detection), plus the firmware-triggered reset request API
  (RequestSystemReset/IsSystemResetRequested; processing arrives with
  the CPU-core stage).
- PCIDevice ported wholesale from ES40-Emu HEAD: diag_printf with RPCC
  stall exclusion (g_diag_excluded_ns), IO/ROM/MEM BAR sizing and
  alignment fixes, and the page-split DMA loops (superset of the
  existing AXPbox implementation, adds end-of-chunk validation).

Verified: clean build, SRM boots to P00>>>.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
…RCR reset

Stage 4 of the ES40-Emu port:
- Flash ported wholesale: AMD flash aliasing fixes (ignore address bit 2,
  out-of-bounds reads return 0xFF), HasBootFirmware() CPQ-signature
  detection, GetFlashBytes(), FlushIfDirty() and quiesce-flush in
  check_state(). This is what lets the LFU on the firmware update CD
  program AlphaBIOS/ARC into flash.
- DPR ported wholesale (UTC-correct faketime handling, supersedes the
  previous implementation).
- System.LoadROM() boots the SRM console from a flashed firmware image
  when one is present (self-decompressor run from flash contents),
  falling back to the existing cl67srmrom.exe / decompressed.rom path.
- TIG SRCR0/1 writes (LFU exit) flush dirty flash and request a system
  reset; TIG mod_info now stored (new ModInfo state field).

Verified: clean build, SRM boots to P00>>>, log diff clean.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ard, FDC, IDE, DMA

Stage 5 of the ES40-Emu port, all converted to std::thread/std::mutex/
std::shared_mutex (no Poco-style wrappers):
- AliM1543C: 8259 PIC rework (IRR/ISR/IMR model with pic_set_line),
  rudimentary SuperIO with PnP, TOY clock offset model with
  arc_year_compat (20-year ARC offset, default off) and faketime,
  get_interval_period_ns() for the CPU timer poll. The AXPbox-only
  'timezone' option is re-implemented as an initial TOY offset seed
  (guest clock shows host local time by default).
- Serial: disabled/raw_mode/null_attach options, telnet subnegotiation
  handling, baud-rate staged delivery, IIR-driven pic_set_line. AXPbox
  bind 'address' option, accept-guard on join and 5 ms poll re-applied.
- Keyboard: Win2K/2210 keyboard+mouse fixes, kbd IRQ rework, mouse
  capture plumbing, input hardening (kbdLock as std::mutex).
- FloppyController: near-rewrite; FDC works on AlphaBIOS/Windows NT
  (interrupt handling, no-drive abort, DMA transfers).
- AliM1543C_ide: ES40-Emu HEAD (NT/Win2K boot blockers fixed, live
  alt-status reads, shared_mutex register locks, run(index) threads).
  The AXPbox fresh-value-read and sector-calculation fixes were already
  transplanted upstream.
- DMA: send/recv_data with length, needed by the new FDC.
- CSemaphore::set() now saturates at max instead of throwing, matching
  the ES40-Emu semaphore semantics the ported devices rely on.
- test/rom/axp_correct.log refreshed: the new Serial emits one extra
  telnet negotiation triplet in the connection preamble (only change).

Verified: clean build, SRM boots to P00>>>, log diff clean.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stage 6 of the ES40-Emu port. Wholesale port of the CPU family:
AlphaCPU, AlphaCPU_{ieeefloat,vaxfloat,vmspal}, all cpu_*.hpp dispatch
headers, datatypes and config_debug. Brings the revival's interpreter
correctness work: LDBU/LDWU zero-extension per HRM, HW_LD sign
extension, EV68 GH translation-buffer masks (fixes ARC screen
corruption and memory test), IEEE S-float rpack canonicalization,
STS/STF/FTOIS conversions, FPCR/inf/zero handling, ITB_IAP/IA/IS,
CAS-backed LL/SC model (cpu_lock/cpu_take_lock/cpu_clear_lock on
CSystem, EV6 64-byte lock ranges), data page cache, native VMS PALcode
improvements, and the wall-clock-pinned RPCC/interval-timer model
(guest clocks track real time). The old host-FP path (es40_float.hpp)
is removed; the softfloat path is always used.

Converted to AXPbox conventions: std::thread run loop with
myThreadDead, runtime skip_memtest_hack option (replaces the
compile-time SKIP_SRM_MEMTEST default), icache config default remains
off, checked fread in RestoreState.

System side: ProcessPendingReset/ResetChipsetState (firmware-triggered
reset), drir_lock serialization for interrupt delivery, clear_ipi.

Two fixes for bugs inherited from ES40-Emu HEAD, found while debugging
SRM boot on the icache-off configuration:
- execute() must advance the PC through next_pc(): the icache-disabled
  fetch path depends on next_pc() keeping pc_phys/rem_ins_in_page in
  sync. Upstream's bare pc += 4 leaves pc_phys frozen, so fetches
  re-read one stale physical word and SRM runs away into pattern-filled
  memory during the console banner (upstream defaults icache on and
  never hits this).
- vmspal_int_initiate_exception() now tracks nesting depth; virt2phys
  diverts to the real PALcode vectors when the native VMS fast path is
  already delivering an exception. Asynchronous (wall-clock) interrupts
  could otherwise land before the guest interrupt context exists and
  recurse the host stack to a segfault.

test/rom/test.sh now ignores the 'CPU n speed is' line: SRM measures
speed from the wall-clock RPCC, so the value is host-dependent.

Verified: clean build; SRM boots to P00>>> (9/10 consecutive runs
clean, one inconclusive early cut; no crashes).

Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stage 7 of the ES40-Emu port. Adds src/jit/jitengine.{hpp,cpp}: a
block-compiling JIT over asmjit with direct-mapped block cache, block
chaining with lazy flush revalidation, inline data-page-cache loads,
SSE floating point, and interpreter bail-out for uncompilable or
faulting operations. Runtime field offsets into CAlphaCPU are computed
at init, so no fixed layout is assumed. JIT_VERIFY (differential
check against the interpreter) and JIT_STATS remain available through
config_debug.hpp.

Build: -DES40_DISABLE_ASMJIT=OFF enables the JIT (off by default).
asmjit is a plain pinned clone in third_party/asmjit (gitignored);
CMake errors with clone instructions when it is missing.

One fix over upstream: break_seq_icache() now also clears
rem_ins_in_page. Compiled blocks write state.pc natively, so the
icache-disabled fetch cursor (pc_phys/rem_ins_in_page) is stale when
interpretation resumes; upstream's Linux JIT loops on 'halt code = 5'
with icache=false and hangs at the SRM idle loop with icache=true.
With this fix the JIT lane boots SRM to P00>>> in ~18s under both
icache settings (verified against upstream es40 as a control, which
does neither on this host).

Verified: default lane (JIT off) builds and passes test/rom/test.sh;
JIT lane builds and boots SRM to P00>>> with icache on and off;
JIT_VERIFY run: 429M compiled-block executions, 0 mismatches.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stage 8 of the ES40-Emu port:
- Sym53C810 wholesale: ARC boot blockers fixed (missing register
  reads, STO handling, SSTAT1 real-phase update, SIDL update), NT 4.0
  register readbacks, GP/Gen timer and DFE stack-drain fixes,
  instruction runaway guard. The residual-state short-move fix and MA
  raise that AXPbox carried for Tru64 were already transplanted
  upstream. Threading converted to std::thread.
- Disk wholesale: mode_sense_page rework, do_scsi_error with info
  byte, media_changed reporting, CD-R/RW command handling. The AXPbox
  START STOP UNIT workaround is preserved: opcode 0x1b answers
  SCSI_OK instead of illegal-command (upstream routed it to the
  CD-R/RW reject group).
- DiskFile: reload_file with autocreate_size support, CD diskfile
  registry for runtime ISO swapping (the SDL3 file dialog activates
  with the graphics stage), flush(). The AXPbox default-filename
  fallback is preserved.
- DiskController/DiskDevice/SCSIBus/SCSIDevice refreshed to ES40-Emu
  HEAD. fopen_large added to StdAfx.hpp.

Verified: clean build, SRM boots to P00>>> with clean log diff, and
'show device' lists an attached IDE ATAPI CD (OpenVMS ISO) and the
floppy correctly.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stage 9 of the ES40-Emu port:
- DEC21143 wholesale: SROM v3 with corrected ID-block CRC and no
  phantom MII PHY, link-up status and transmit-descriptor fixes (ARC
  DHCP/self-test work), RX/TX buffer-2 descriptor handling for the NT
  driver, RX/TX wake semaphores, MBO bit, LFU reset fix, optional
  packet debug. Windows dynamic wpcap loading retained under _WIN32.
  Threading converted to std::thread.
- Ethernet base class refreshed; lockstep updated to ES40-Emu HEAD.
- New devices: ES1370 sound, MPU401 MIDI, AliM1543C PMU (power
  management shell).
- gui_win32.cpp restored from ES40-Emu (fully _WIN32-guarded; empty
  translation unit elsewhere).

Verified: clean build, SRM test passes 3/3 with clean log diff (one
earlier run showed the known rare mid-boot console restart transient,
still reaching P00>>>).

Authored-By: Claude Fable 5 <noreply@anthropic.com>
…64, SDL3 GUI

Stage 10 of the ES40-Emu port:
- VGA base class becomes the MAME-derived VGA core (register dispatch,
  sequencer/CRTC/GC/attribute state, pel/DAC, screen_update render
  path); Cirrus is excluded from the build (not ported to the new
  core, disabled upstream too) and its config entry reports a clear
  error suggesting s3.
- New ibm8514a device: MAME IBM 8514/A accelerator used by the S3.
- S3Trio64 wholesale: full rewrite around the MAME core. Boots the
  real S3 Trio64 VGA BIOS (86c764x1.bin via the s3 'rom' config key),
  linear framebuffer with dynamic BAR handling, 2D acceleration via
  the 8514/A, hardware cursor, 4MB interlaced modes, text rendering,
  Windows NT high/true-color background fix, pause-instead-of-destroy
  window handling across firmware resets. Threading converted to
  std::thread.
- GUI layer moves to SDL3 (upstream is SDL3 too): dynamic resolution
  and DPI scaling, linear filtering, mouse capture (Ctrl+F10),
  Ctrl+Alt+End sends Ctrl+Alt+Del for NT, Ctrl+F11 opens the CD-swap
  file dialog (DiskFile SDL3 dialog now active), runtime scale
  hotkeys. gui.cpp/gui.hpp gain a base graphics_frame_update so the
  X11 backend keeps working. SDL 1.2 is fully removed from the build
  (find_package(SDL3 CONFIG), no SDL/SDL.h includes remain).

Verified: clean build linking SDL3; headless SRM test passes with
clean log diff; DISABLE_SDL=yes build compiles; manual boot with
pci0.2=s3 + gui=sdl + the 86Box Trio64 BIOS reaches P00>>> with the
SDL window on WSLg.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stage 11 of the ES40-Emu port:
- Configurator refreshed to ES40-Emu HEAD: s3, es1370, mpu401 and
  ali_pmu device registration, PCI slot validation for the extra
  reserved slot 17 and the PMU. The cirrus entry stays registered but
  reports a clear configuration error pointing at s3 (device not
  ported to the MAME VGA core, disabled upstream too).
- es40-cfg configuration wizard refreshed: VGA card question with S3
  VGA BIOS path, in-memory CD option, serial disabled/none ports,
  display scaling questions, fixed date/time question. The AXPbox
  icache and skip_memtest_hack questions are preserved (upstream had
  commented icache out and hardcoded true). Entry point remains
  main_cfg for the 'axpbox configure' subcommand.
- Sample es40.cfg: arc_year_compat and extended time documentation,
  S3 + 86c764x1.bin example replaces the cirrus example, SDL video
  scaling options and runtime hotkeys documented, timezone docs kept.
- VERSION is now a quoted string in config.hpp (banner printf pastes
  it).
- AlphaCPU: the first Cchip interval-timer tick now fires one second
  after CPU start instead of immediately. An immediate tick could
  land inside the SRM console's earliest initialization and make it
  dump registers and restart (intermittent boot-log transient seen
  roughly one run in five).

Verified: clean build; SRM test passes 6/6 consecutive runs with
clean log diff.
Authored-By: Claude Fable 5 <noreply@anthropic.com>
Stage 12 of the ES40-Emu port: run clang-format (LLVM style, repo
.clang-format) over all files touched by the port so the tree is
uniformly formatted again; make Ethernet.hpp self-contained (include
sorting exposed its reliance on the includer providing StdAfx types).
README documents the C++17/SDL3 requirements, the optional asmjit JIT
build, and the S3/ARC/Windows NT setup; the ARC and OpenVMS-VGA
entries leave the 'not working' list.

Verified after formatting: fresh configure + build of both lanes;
default lane passes test/rom/test.sh 3/3 with clean diff; JIT lane
boots SRM to P00>>> in 18s.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
Token-stream comparison of every shared source file against ES40-Emu
HEAD confirmed the port is complete (all remaining deltas are the
intentional AXPbox keep-list additions) except for five small items,
now applied:
- Sym53C895: don't delete the shared SCSI bus in the destructor
  (double free; the 810 already had the fix)
- TraceEngine (IDB builds): trace-map init used CPU 0's slot for every
  CPU, and the branch-target address was computed from the branch
  source
- StdAfx: PRINTF_BYTE_TO_BINARY debug macros (referenced by S3 debug
  paths) and <cerrno>
- telnet.hpp: TELOPT_BINARY fallback define for platforms without
  arpa/telnet.h

Verified: clean build.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
Captures the verification work done after the ES40-Emu port as
reusable pieces:

- .claude/skills/: srm-boot-test (the P00>>> regression test and its
  pitfalls), boot-openvms (full-guest boot from the provided 8.4
  image), test-arc (AlphaBIOS from the pre-programmed flash, S3 BIOS
  sources, timing caveats), verify-vga-sdl (framebuffer dumps,
  SRM-on-VGA text check, WSLg display notes), build-lanes (default /
  JIT / headless builds and pre-commit gates).
- test/vms/: config + telnet drivers that boot OpenVMS end-to-end
  (SRM boot dqa0, date prompt answer, startup markers). Verified:
  OpenVMS 8.4-2L1 boots from the provided image through full system
  startup with correct 2026 timestamps.
- test/arc/: config + serial watcher for the AlphaBIOS flash boot.
  Verified: SRM boots from flash on the graphics console (S3 text
  rendering pixel-verified), nvram script loads ARC firmware; ARC
  waits on its first-boot blue screen for an interactive keypress.
- src/gui/sdl.cpp: two env-gated debug hooks used by the skills:
  AXPBOX_DUMP_FB=<prefix> (periodic PPM dump of the rendered frame)
  and AXPBOX_AUTOKEY_ENTER=<seconds> (periodic Enter through the
  emulated keyboard for headless firmware prompts).

Media and ROMs (6 GB disk copy, firmware, VGA BIOS, dumps) are
gitignored; scripts fetch what they need.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
JIT (upstream 7d94c9e..7140555 series): block cache 64K->256K slots,
poly-link direct chaining (2 cached successors, round-robin backpatch),
register allocation with global pins (R26/R16/R27; +3 on Win64, +1 SysV),
standalone emit_op shared by block and trace compilers, value caching,
smaller ALU codegen, HW_LD 0xa (virtual+WrChk), JIT_VERIFY fixes, and the
dormant trace tier (JIT_TRACES, off by default: measured net perf loss,
kept as correctness infrastructure).

Timing (upstream d12d4e8): state.cc is wall-clock in both engines (DO_RPCC
unified; odd deltas capped at 1s instead of dropped - the 357 MHz
boot-calibration bug), Cchip interval timer driven by CPU0 at dispatch-batch
boundaries with count-preserving paced catch-up (repay lost ticks at <= 2x
nominal, drop >1s backlog), 8254/PIT advanced by elapsed host time at
1.193182 MHz with analytic pit_out() for jitter-free port-61h polling, and
RTC register A preset to 0x26 at reset (battery-backed semantics: SRM's
boot-CPU speed calibration sees 1024Hz ticks from power-on).

The first interval tick now fires immediately like upstream; the 1-second
grace is dropped (the RTC boot tick and vmspal_exc_depth guard cover the
early-boot transient it worked around - verified over repeated SRM boots
in both lanes).

Per upstream ed9bf49, the icache and mouse.enabled options are gone:
icache is always on, PS/2 mouse always present/captured (superio LDN8
reports 0x01 unconditionally).

Kept axpbox-specific fixes: next_pc() in execute(), rem_ins_in_page clear
in break_seq_icache(), vmspal exception-nesting guard, skip_memtest_hack,
fread return checks, AXPBOX_PC_SAMPLE sampler, std::thread threading.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ings

Port upstream BIN/CUE support (ES40-Emu PR lenticularis39#121 plus follow-ups): a cdrom
file ending in .cue is parsed as a cue sheet (single- or multi-file BIN,
MODE1/2048, MODE1/2352, MODE2/2336, MODE2/2352, AUDIO), with graceful
fallback to a raw image on parse failure. New DiskFileBinCue.hpp defines
CueTrack/CueTrackMode; CDiskFile gains the track query API and LBA-to-file
mapping; Disk READ_TOC and track reporting use real track data when a
BIN/CUE image is mounted.

Disk identity values now accept both spellings: serial_number/serial_num
and rev_number/rev_num (upstream 11666e8) - previously the documented long
forms were silently ignored.

Kept axpbox-specific behavior: default image filename fallback when a disk
has no file attached, and START_STOP_UNIT accepted with SCSI_OK.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
…DISCONNECT fix

Serialize CPU-thread CSR/rx_queue access against the NIC worker thread
(upstream 4bb0161): the worker holds the register lock for its whole batch
(receive_process, TX drain, interrupt summary), and ReadMem_Bar /
WriteMem_Bar / SaveState / RestoreState take the same lock. Written with
std::recursive_mutex + std::lock_guard rather than upstream's CMutex
wrapper, preserving the recursive semantics.

Raise the default rx packet queue from 100 to 1024 (upstream d8a8d4e).

Sym53C810 WAIT DISCONNECT (upstream 14d613e): instead of unconditionally
freeing the bus, check the current SCSI phase - free only from arbitration;
if the bus is still connected, release it on the passive target's behalf
via free_bus(GET_DEST()) with a diagnostic, since emulated targets never
drop BSY on their own.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
…attach serials

Port upstream 11666e8 / 43469dc / ed9bf49 configuration hardening:

- Each device class now carries an allow-list of the configuration values
  it actually reads; anything else in that section gets a one-line
  %SYS-W-UNKNOWNCFG warning at startup instead of being silently ignored.
  The lists are extended for axpbox-specific options: skip_memtest_hack
  (ev68cb), timezone (ali), rom.decompressed (tsunami), address (serial).
- ';' at the start of a line now works as a line comment.
- Serial ports that are not configured are synthesized as null_attach
  with a %SYS-W-NOSERIAL notice (the ES40 always has two UARTs).
- The kept axpbox cirrus class row still resolves, and still fails with
  the pointer to use an s3 section instead.

Configuration wizard (axpbox configure): the sym53c895 wide-SCSI option,
the mouse question/mouse.enabled output, and the icache question are gone,
matching the removal of those options from the emulator. Shipped configs
drop their icache = false and mouse.enabled lines so they start warning-free.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
Port upstream 074b5e0 / b26fc37: new sdl-section options mouse.speed
(0.0 < speed <= 10.0, default 1.0, warns and falls back to 1.0 on invalid
values) and mouse.invert_x / mouse.invert_y. Scaled motion is accumulated
fractionally across events so sub-1.0 multipliers don't drop slow movement.
The allow-list entries landed with the Configurator port.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
… documentation refresh

New src/banner.hpp (ported from upstream banner.h): a shared startup banner
with runtime-computed padding, printed by both the run and configure
subcommands. It credits the emulator's major authors by era: Camiel
Vanderhoeven and the ES40 Emulator Project (2007-2010), Tim Stark / fsword7
(2018), Tomas Glozar (2020-2023), Remy van Elst (2020-2026), and Gary /
gdwnldsKSC of the ES40-Emu revival (2023-2026). Shows axpbox's own version.

All user-facing "ES40" text now says AXPbox: SDL/X11/Win32 window titles,
the configurator banner, the serial-port telnet greeting (expected SRM test
log updated to match), the interactive-debugger greeting, the memory-map
header, and the MIPS statistics line. Guest-visible identity strings
(ES40EM00000 disk serial, ES40RAMDISK model, the ES40-derived MAC seed) and
the es40.cfg file name are intentionally unchanged.

The sample es40.cfg is refreshed with the upstream 0.75.1 documentation
(comment forms, unknown-value warning, mouse.speed/invert, DEC21143 queue,
serial null_attach/disabled/raw_mode, disk identity values, no icache or
mouse.enabled) merged with the axpbox-specific docs (rom.decompressed,
skip_memtest_hack, timezone, S3 Trio64 with the 86Box BIOS). The old sample's
stack of five active timezone lines (last-one-wins, leaving utc+2y in
effect) is now a commented example block. README points at the sample file.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
Step-by-step recipe for porting ES40-Emu commits into axpbox: range
survey, file mapping (.h->.hpp, main_cfg, config locations), per-file
strategy (manual vs wholesale-replace with axpbox-delta reapplication),
the axpbox invariants (std:: threading, preserved bug fixes, settled
icache/timer/mouse decisions, configurator allow-lists), rebranding
rules (host-side AXPbox text vs guest-visible ES40 identifiers), the
full verification gate sequence (build lanes, SRM diff, JIT_VERIFY,
config-warning sweep, OpenVMS boot, ARC smoke), and the port history
with the next range's base commit.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
Add debug hooks to investigate the reported Linux SDL mouse-input
problem and to drive headless firmware/guest runs:

- AXPBOX_MOUSE_DEBUG=1 traces every host SDL mouse-motion event
  (xrel/yrel/grab) and every grab transition to stderr, and logs if
  SDL_SetWindowRelativeMouseMode fails. This localizes a dead mouse to
  host-side (no motion events delivered) vs guest-side (events arrive
  but the guest pointer doesn't move).
- AXPBOX_AUTOMOUSE=<sec> injects synthetic motion straight into the
  guest PS/2 path (a square pattern + periodic click), exercising KBC
  aux / IRQ12 / guest driver with no host input.
- AXPBOX_KEYPIPE=<file> injects named keys appended to a file while the
  emulator runs, for interactive headless menu navigation; the
  AXPBOX_KEYSCRIPT key table is factored into a shared lookup and
  extended with the full letter/digit set and ins/home/end/f4/f5 etc.

Also finish the rebrand: the GUI-install banner now says "AXPbox GUI".

No change to the normal input path. Offscreen headless rendering
(SDL_VIDEO_DRIVER=offscreen) with AXPBOX_DUMP_FB confirmed working.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
Describe the AXPBOX_* debug environment variables (framebuffer dumps,
scripted and interactive key injection, synthetic mouse motion, mouse
event tracing, PC sampling), the key-name list, an example fully
headless firmware run with the offscreen SDL driver, and the
serial-port-waits-for-telnet startup gotcha.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
On WSLg (and some Wayland compositors) engaging the mouse grab bounces
window focus; the FOCUS_LOST handler released the grab immediately after
the user's click, so motion events kept arriving but were discarded and
the guest mouse appeared dead (traced with AXPBOX_MOUSE_DEBUG: grab -> 1
followed instantly by grab -> 0, all motion at grab=0).

Remember that the guest owned the mouse when focus loss forces an
ungrab, and re-grab on FOCUS_GAINED. Bounded to 8 bounces per user
action so a compositor that always rejects the grab cannot ping-pong;
a deliberate Ctrl+F10 release or a fresh click resets the budget.

Note: WSLg's Wayland backend additionally delivers no relative motion
at all while relative mouse mode is active (SDL reports success, zero
motion events arrive). On such hosts run the emulator under XWayland:
SDL_VIDEO_DRIVER=x11 DISPLAY=:0 SDL_RENDER_DRIVER=software.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
AXPBOX_MOUSE_DEBUG=1 now also traces every command the guest sends to
the PS/2 aux device (Keyboard.cpp ctrl_to_mouse) - shows whether a
guest driver ever detects and enables the mouse (f4 = enable stream).

README gains the "Mouse on WSLg / Wayland" section: the default
Wayland backend on WSLg delivers no relative motion while grabbed; run
via SDL_VIDEO_DRIVER=x11 DISPLAY=:0 SDL_RENDER_DRIVER=software
(verified working). The verify-vga-sdl skill is updated with the
corrected WSLg facts (x11 backend IS available), the offscreen-driver
headless recipe, the serial-port startup gotcha, and the mouse
diagnosis procedure; port-from-es40 lists the new hooks among the
axpbox-only code to preserve across future ports.

Known-open: AlphaBIOS moves the pointer with both axes inverted
(mouse.invert_x/y compensate); Windows 2000 shows no pointer movement
once booted - under investigation with the new aux trace.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
…E feature docs

The sample es40.cfg now starts without any telnet interaction: both
UARTs are null_attach (console on the VGA window), with the port/action
telnet variants kept as commented alternatives and a note that a
configured port waits for a client at startup.

The DEC 21143 NIC section is active with adapter = "eth0" and documents
the one-time Linux capture-permission grant (setcap cap_net_raw,
cap_net_admin+eip) plus the Windows npcap adapter syntax; leaving
adapter unset triggers an interactive chooser, so unattended runs must
set it. The ES1370 sound card is enabled (NT4 guest drivers; other
guests ignore it).

README gains a "Serial consoles, networking, and sound" section
covering these plus the mouse tuning options, window scaling hotkeys,
and BIN/CUE cdrom support.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
Repository guidance for Claude Code: the three build lanes and JIT debug
flags, the SRM regression test and its pitfalls, pointers to the deeper
verification skills, a big-picture map of the architecture (CSystem device
graph, CPU interpreter + VMS PAL fast path, wall-clock timing, JIT block
cache, configurator allow-lists, threading idioms), and the settled project
rules (std:: over the base/ wrappers, .hpp headers, icache/mouse/timer
decisions, rebrand boundaries, own versioning).

Authored-By: Claude Fable 5 <noreply@anthropic.com>
RaymiiOrg added 10 commits July 11, 2026 18:35
gui_win32.cpp is pure GDI code and DiskFile.cpp includes commdlg.h,
both of which fail to compile when NOGDI strips wingdi.h out of
windows.h. Drop the unused Poco-style scoped lock macros from
RWLock.hpp; AliM1543C_ide.hpp defines the std::shared_mutex versions.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
Adopt the CNetworkBackend abstraction (pcap + Linux TAP) from upstream
while preserving the local networking features on top of it:

- trace_packets tracing re-added in the DEC21143 RX/TX paths
- NetworkFilter struct extends set_filter() with the full CSR6
  semantics (PR/RA/PM/IF + broadcast + own-MAC fallback); the BPF
  builder moved from DEC21143::SetupFilter into CNetworkPcap
- Windows run-time wpcap.dll loading (from System32\Npcap) moved into
  NetworkPcap and shared with the es40-cfg wizard, replacing the two
  duplicated copies; the exe no longer needs Npcap in WinPcap-compat
  mode
- robust fgets-based adapter picker kept, now in CNetworkPcap::init
- adapter descriptions kept in the configure wizard device list
- new TAP config keys (type, host_ip, bridge, uplink, tap_create)
  added to the dec21143 config allow-list

Authored-By: Claude Fable 5 <noreply@anthropic.com>
- third_party/SDL submodule pinned at release-3.4.12 (shallow); CMake
  falls back to a static build of it when no system SDL3 is found, so
  Windows needs no SDL install and the exe is self-contained
- CI: check out submodules on the Linux and Windows jobs; Linux jobs
  drop the obsolete SDL1 packages in favor of X11/Wayland headers for
  the bundled SDL3
- README: Building-from-source section (Linux + Windows incl. npcap
  SDK and VS 2022 steps) and pcap/TAP backend documentation
- banner credits: gdwnldsKSC listed by GitHub handle

Authored-By: Claude Fable 5 <noreply@anthropic.com>
Guests that legitimately hit integer overflow traps (e.g. Tru64) no
longer spam the console; define DEBUG_ARITH_TRAP in config_debug.hpp to
get the old logging. DEBUG_LOCKS comment style aligned with upstream.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
EV68 HRM 4.6: an external (DMA) writer must invalidate a CPU's locked
cache line. Adds a reader/writer gate (cpu_llsc_dma_gate) that makes
the DMA invalidating probe + RAM write atomic against the LDx_L
load/publish and STx_C test/store windows:

- System: CLLSCDRAMGuard (reader) / CPCIDMAWriteGuard (writer) RAII
  classes, gate enter/leave, cpu_clear_external_locks()
- PCIDevice::do_pci_write takes the writer guard and probes every
  reservation line the DMA touches
- interpreter LDx_L/STx_C (cpu_defs.hpp READ_VIRT_LOCK[_F],
  WRITE_VIRT_COND) and vmspal HW_LD/HW_ST locked/conditional cases
  (cpu_pal.hpp) take the reader guard
- JIT jit_read_locked/jit_stc take the reader guard

Also ports the DEBUG_INSTALL_PAL_TRAP hook in GO_PAL from upstream
c2bd1fb (compiles out unless DEBUG_INSTALL_VMFAULT is defined).

Authored-By: Claude Fable 5 <noreply@anthropic.com>
ufdiv64 cannot represent asig*2^64 / (zsig*2^32): with zsig >= 2^31 the
divisor has bit 63 set and the shifted dividend wraps, producing a
garbage estimate that the correction loop walks back ~2^60 ULPs. Use
SoftFloat's estimateDiv128To64 (udiv128to64) instead. Fixes SQRT
results that broke network dialogs on Tru64 (upstream #136).

Authored-By: Claude Fable 5 <noreply@anthropic.com>
Upstream reverted the CSR lock (originally 4bb01619 / our
std::recursive_mutex myRegLock) in v0.75.4 after it caused regressions;
follow suit: the NIC thread batch, ReadMem_Bar, WriteMem_Bar and
Save/RestoreState run lock-free again, matching the pre-0.75.1 model.
The axpbox instant-IRQ recompute (update_irq) is unaffected.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
Authored-By: Claude Fable 5 <noreply@anthropic.com>
The blessed log predated the AXPbox startup banner, the blank-flash
auto-create (%FLS-I-CREATE), the %SYS-W-NOSERIAL warning and the new
DiskFile failure text, so the comparison always failed. Also:

- drop the removed 'icache' option from the test config (it now
  triggers %SYS-W-UNKNOWNCFG)
- normalize the banner version line in test.sh (Version X.Y.Z) so
  version bumps don't break the comparison

Authored-By: Claude Fable 5 <noreply@anthropic.com>
A config file with e.g. two serial0 sections silently created two
devices; the later one wins the address range, so a stray telnet
serial0 section makes startup block waiting for a connection even
though an earlier serial0 says null_attach. Warn at parse time.

Authored-By: Claude Fable 5 <noreply@anthropic.com>
@RaymiiOrg
RaymiiOrg force-pushed the es40-ports-from-gdwnldsKSC branch from 9d09861 to 89000e3 Compare July 11, 2026 17:05
The runner label was literally 'macos-15"' so no runner ever picked
the job up ('Requested labels: macos-15"' → waits forever). While in
there:

- macos-15 runners are arm64: drop the x86 -std=c++11/-stdlib=libc++
  and /usr/local pcap paths; point PCAP at $(brew --prefix libpcap);
  rename the job/artifact osx-x86 → osx/macos-arm64
- check out submodules so the bundled SDL3 builds in statically
  (the old 'sdl doesnt work' comment predates SDL3)
- replace the disabled ::set-output syntax and the broken
  'name=date::...' GITHUB_OUTPUT variant (which left BUILD_DATE empty
  in artifact names) with the proper 'date=...' form in all jobs

Workflow validated with actionlint (no errors).

Authored-By: Claude Fable 5 <noreply@anthropic.com>
@RaymiiOrg
RaymiiOrg merged commit 6c67d5b into lenticularis39:main Jul 11, 2026
5 checks passed
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.

AlphaBIOS / ARC doesn't boot

1 participant