Commit Graph
146 Commits
Author SHA1 Message Date
Stefan ArentzandClaude Fable 5 db070e561c Phase 4: Apple 1 SDL frontend
ewm one now runs windowed:

- ewm-core/src/chr.rs: the bitmap half of chr.c — the 2716 character
  ROM (3410036.bin, embedded) decodes to 7x8 glyphs indexed by Apple ][
  screen code, with the same table layout as ewm_chr_init (normal
  $A0-$DF, inverse $00-$3F, flashing-as-inverse $40-$7F). Unit
  tests pin the 'A' glyph, inverse glyphs, and unmapped slots.
- ewm/src/tty.rs: tty.c — 24x40 screen buffer, scrolling, blinking
  cursor, rendered into a 280x192 pixel buffer.
- ewm/src/sdl.rs: sdl.c — pixel-format pick and green phosphor color.
- ewm/src/one.rs: the SDL loop of one.c — 40 fps cycle bursts
  (1023000/40), the same key mapping (including one.c's TAB
  fallthrough that also sends DEL, and ctrl-a mapping to 0x00),
  Cmd-Esc reset, Cmd-Return fullscreen, and --model/--memory/
  --trace/--strict flags. Extra --memory regions are supported by
  new One::add_ram/add_rom (dispatched LIFO like the C mem list).
- ewm/src/main.rs: subcommand dispatch; two/boo report not ported.

The sdl2 crate now uses the use-pkgconfig feature: linking the real
SDL symbols needs the Homebrew/pkg-config library path.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 09:41:48 -04:00
Stefan ArentzandClaude Fable 5 7ed9c6c6ae Phase 3: headless Apple 1 / Replica 1 (#193)
* Phase 3: headless Apple 1 / Replica 1

Ports the machine layer for the One:

- pia.rs: the 6820 PIA from pia.c. The C output callback becomes a
  return value — Pia::write yields (ddr, byte) when an output register
  is written — and reads keep the IRQA1-clear side effect.
- one.rs: One implements Bus with the C memory map (Apple 1: 8K RAM +
  Woz monitor ROM at $FF00 on a 6502; Replica 1: 32K RAM + Krusader
  ROM at $E000 on a 65C02; PIA at $D010). ROMs are embedded with
  include_bytes! so nothing needs to run from src/. Display bytes are
  collected in a drainable buffer, with the Apple 1's 7-bit masking
  applied exactly where ewm_one_pia_callback did. One::key latches
  key | 0x80 into the PIA and raises IRQA1, per ewm_one_keydown.
- tests/one_boot.rs: both machines boot to the Woz monitor prompt;
  FF00.FF0F (Apple 1) and E000.E00F (Replica 1) dumps are verified
  against the actual ROM bytes; typed characters echo back.

utl.c is not ported: ewm_utl_endswith is str::ends_with, and the
clock_gettime shim is obsolete.

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

* Add an interactive console example for the headless One

cargo run -p ewm-core --example one -- [apple1|replica1] gives a
line-based Woz monitor console, so the machine can be tried by hand
before the SDL frontend lands in Phase 4.

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

* Make the example's demo program print HI!

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

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 09:32:31 -04:00
Stefan ArentzandClaude Fable 5 8c158618d5 Phase 2: 65C02, disassembler, and golden-trace harness (#192)
Completes the CPU core port:

- ins.rs: the 65C02 override handlers ((zp) modes, BRA, STZ, PHX/PHY/
  PLX/PLY, TRB/TSB, RMB/SMB, BBR/BBS, INC/DEC A, BIT imm/zpgx/absx,
  JMP (abs,X)) and the override table transcribed verbatim from
  instructions_65C02 — including its 1-cycle NOPs and the stray 0x03
  opcode fields. The table is overlaid onto the 6502 table once, the
  Rust version of cpu_initialize()'s back-fill. C's arity-cast NOPs
  become explicit nop_byte/nop_word wrappers.
- fmt.rs: cpu_format_state, cpu_format_stack, and the disassembler
  from fmt.c, bugs preserved (0x9c prints JMP; BBR/BBS targets are
  computed from pc+2).
- tests/dormann.rs: dormann_65c02 passes at $24a8 after 65,094,140
  cycles — exactly the C emulator's count.
- Golden-trace harness: scripts/gen-golden-trace.{c,sh} builds a
  capture program against the unmodified C sources and records the
  first 100k instructions of the functional test as normalized
  'PC A X Y SP P' lines; checked in gzipped. trace_compare.rs replays
  it on the Rust core and reports the first divergent instruction
  (currently: zero divergence). flate2 is a dev-dependency only.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 09:16:20 -04:00
Stefan ArentzandClaude Fable 5 880100ac90 Phase 1: 6502 core, passing the Dormann functional test (#191)
Ports cpu.c, mem.c, and the 6502 half of ins.c to rust/ewm-core:

- bus.rs: the Bus trait (replacing the mem_t linked list) and a flat
  64K TestBus for the CPU test harness
- cpu.rs: registers, separate raw-valued flag fields packed/unpacked
  only in status()/set_status(), stack ops with u8 sp wraparound,
  reset/irq/nmi (keeping the pc+1 interrupt push quirk the Dormann
  tests depend on), strict-mode stack overflow checks, and step()
  with pc advanced before handler dispatch
- ins.rs: the 3-variant Handler arity enum, addressing-mode and RMW
  helpers ported expression-for-expression from mem.c (including the
  indx zero-page wrap and the indy non-wrap), ~200 handlers in ins.c
  source order, and the 256-entry table transcribed verbatim
- tests/dormann.rs: the cpu_test.c harness (success PC $3399,
  branch-to-self deadlock detection) plus unit tests for status
  round-trip, stack wraparound, and the indexed-indirect quirks

The Rust core executes 88,957,316 cycles for the functional test —
exactly the C emulator's count.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 09:02:50 -04:00
Stefan ArentzandClaude Fable 5 fbad7d01de Phase 0: Rust workspace scaffolding + CI (#190)
* Phase 0: Rust workspace scaffolding + CI

Adds the parallel Rust workspace under rust/ per REWRITE.md:
- ewm-core (headless lib, zero dependencies) and ewm (binary,
  declares sdl2 now so CI installs SDL2 headers from day one;
  prints the same usage line as the C binary)
- rust-toolchain.toml pinning 1.91.1 with rustfmt + clippy
- GitHub Actions CI: C build job (ubuntu + libsdl2-dev) and Rust
  job (fmt --check, clippy -D warnings, test)
- Anchor the 'ewm' gitignore pattern to src/ so rust/ewm is tracked;
  ignore rust/target/
- README note pointing at REWRITE.md

The C tree in src/ is untouched.

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

* CI: build the C tree on macOS

gcc on ubuntu fails -Werror with -Wimplicit-fallthrough in two.c;
src/ is frozen until Phase 9, so build C where it has always built
(macOS, as Travis did).

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

* CI: point clang at the Homebrew prefix via CPATH/LIBRARY_PATH

The committed Makefile does not search /opt/homebrew, so SDL2
headers are not found on the arm64 macOS runner. src/ is frozen,
so pass the paths through the environment instead.

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

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-05 08:42:08 -04:00
Stefan Arentz 7befac8e6d Add phased plan for rewriting EWM in Rust (#189) 2026-07-05 00:51:33 -04:00
Stefan ArentzandClaude Opus 4.5 1c00e6f271 Implement speaker sound support (#188)
Add sound subsystem that emulates the Apple II speaker by:
- Tracking speaker state toggles when $C030 is accessed
- Generating audio samples based on CPU cycle timing
- Outputting 44.1 kHz audio via SDL

New files: snd.h, snd.c

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 13:07:28 -05:00
Stefan ArentzandClaude Opus 4.5 4ad5d458f9 Fix HGR color fringing artifacts (#187)
Replace the 2-bit pairing approach with per-pixel rendering to eliminate
color artifacts at edges. The new implementation processes each pixel
individually, uses each byte's own high bit for palette selection, and
properly detects adjacent pixels for white rendering.

Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-11 12:56:34 -05:00
Joe Hildebrand f797e02836 Add small doc improvements for first time users (#182) 2018-01-25 16:38:53 -05:00
Stefan Arentz 71bbe91ac3 Fixes #84 - Unexpected write at $C000 2017-10-15 22:21:56 -04:00
Stefan Arentz ccfa250823 Fixes #154 - Unexpected read at $C020 2017-10-15 22:18:20 -04:00
Stefan Arentz 3168e11814 Fixes #181 - In color mode, text should be white 2017-10-15 21:30:15 -04:00
Stefan Arentz 31ecfb98f5 Fixes #180 - Implement flashing text 2017-10-15 20:01:08 -04:00
Stefan Arentz 6e32724ffa Fixes #179 - Blinking in tty is irregular 2017-10-15 17:02:22 -04:00
Stefan Arentz d2a8386f72 Fixes #178 - Allow the emulator to be paused 2017-10-15 16:40:30 -04:00
Stefan Arentz 7a68e0909b Fixes #175 - Support software rendering in scr (#176) 2017-10-15 15:45:53 -04:00
Stefan Arentz 8a8438d0c2 Fix for link issue 2017-10-03 20:39:37 -04:00
Stefan Arentz cb783a3957 Fixes #174 - Support CMake (Debug vs Release) 2017-10-03 01:28:22 +00:00
Stefan Arentz 95dcce4bba Fixes #174 - Support CMake (Lower CMake version) 2017-10-03 01:19:28 +00:00
Stefan Arentz 3f1d258646 Fixes #174 - Support CMake 2017-10-02 21:12:21 -04:00
Stefan Arentz a28b9180ff Fixes #173 - Crash in scr_test 2017-10-02 20:36:15 -04:00
Stefan Arentz 839ce07e9c Fixes #164 - Make Lua Optional (#165) 2017-10-02 20:32:43 -04:00
Stefan Arentz 9a517223e2 Fixes #171 - Support software rendering in tty (#172) 2017-10-02 20:20:53 -04:00
Stefan Arentz 699072aa86 Fixes #170 - Create a benchmark for tty.c 2017-10-01 11:08:23 -04:00
Stefan Arentz a38375554d Fixes #162 - Introduce a DEBUG compilation mode 2017-09-23 11:57:40 +00:00
Stefan Arentz fd6818e2ab Performance Improvements Part II (#161) 2017-09-23 07:45:36 -04:00
Stefan Arentz ab4c8e025e Update cpu_test.lua 2017-09-22 11:41:51 +00:00
Stefan Arentz a4324737d5 Performance improvements (#160) 2017-09-21 22:18:53 -04:00
Stefan Arentz 58bb3d7739 Fixes #158 - Make the project compile on Raspbian 9.1 (Stretch) (#159) 2017-09-21 21:39:31 -04:00
Stefan Arentz de9212a47f Script for Burger Time cheat 2017-09-20 18:06:30 -04:00
Stefan Arentz 1cd98d8e71 Fixes #157 - Add Lua API for Keyboard Events 2017-09-20 18:06:09 -04:00
Stefan Arentz 97d415a501 Fixes #155 - Add a Lua API to access memory 2017-09-20 17:44:57 -04:00
Stefan Arentz a88c4a7562 Introduce Lua 5.2 support (#148) 2017-09-18 21:21:57 -04:00
Stefan Arentz c68fc356c6 Adding cpu_bench to gitignore 2017-03-14 09:49:12 -04:00
Stefan Arentz da40ac82bb Fixes #145 - Print Usage and Command Line Options (#146) 2017-03-14 09:46:57 -04:00
Stefan Arentz 47ca22fb42 Update .travis.yml 2017-03-14 09:46:33 -04:00
Stefan Arentz 05bef561ad Update .travis.yml 2017-03-13 22:47:05 -04:00
Stefan Arentz be01db6393 Fixes #143 Implement a clock_gettime replacement (#144) 2017-03-13 15:01:06 -04:00
Stefan Arentz e0943d051a Fixes #86 Create a Boot Loader (#134) 2017-01-22 20:02:26 -05:00
Stefan Arentz 9a94156a5b Fix for GCC compilation issue 2017-01-17 03:18:32 +00:00
Stefan Arentz 8800bf2b9f Fixes #139 Optimize zero page and stack access (#140) 2017-01-15 20:48:16 -05:00
Stefan Arentz f3781e2d69 Fixes #135 Benchmark Memory Routines (#136) 2017-01-15 16:49:06 -05:00
Stefan Arentz 349ebc0bad Fixes #137 Benchmark CPU Module (#138) 2017-01-15 16:28:32 -05:00
Stefan Arentz 83157ffe2a Removed the Apple IIe from the README 2017-01-14 20:33:45 -05:00
Stefan Arentz af139f2e2c Fixes #129 Find Volume from disk image (#132) 2017-01-13 21:41:44 -05:00
Stefan Arentz 7acae93861 Fixes #104 Control keys don't work correctly (#130) 2017-01-13 21:29:25 -05:00
Stefan Arentz a1536aa351 Add chr_test to .gitignore 2017-01-13 21:12:31 -05:00
Stefan Arentz 9df5355e31 Fixes #82 Support nib files 2017-01-09 21:39:55 -05:00
Stefan Arentz 70aef81778 Fixes #125 Remove all public _init() functions 2017-01-09 21:09:20 -05:00
Stefan Arentz 37d508c367 Fixes #126 Implement the same cpu throttling/screen update loop as we have on the two 2017-01-08 22:18:38 -05:00