badline 0.3.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.claude/hooks/session-start.sh +57 -0
- data/.claude/settings.json +14 -0
- data/CHANGELOG.md +65 -0
- data/CLAUDE.md +45 -16
- data/CONTRIBUTING.md +95 -3
- data/README.md +111 -61
- data/SECURITY.md +9 -0
- data/doc/pinned-behaviour.md +275 -33
- data/exe/badline-ruby +59 -0
- data/lib/badline/address_bus.rb +22 -10
- data/lib/badline/audio/aiff.rb +8 -3
- data/lib/badline/audio/cli.rb +17 -12
- data/lib/badline/audio/console.rb +12 -58
- data/lib/badline/audio/playback.rb +3 -0
- data/lib/badline/audio/sdl_sink.rb +20 -52
- data/lib/badline/audio/terminal.rb +90 -0
- data/lib/badline/audio.rb +2 -2
- data/lib/badline/cartridge/geo_ram.rb +63 -0
- data/lib/badline/cartridge.rb +1 -0
- data/lib/badline/cia/interrupt_register.rb +34 -10
- data/lib/badline/cia.rb +15 -8
- data/lib/badline/computer.rb +28 -13
- data/lib/badline/gui/application.rb +33 -21
- data/lib/badline/gui/gamepads.rb +22 -22
- data/lib/badline/gui/joy_map.rb +1 -1
- data/lib/badline/gui/key_map.rb +6 -1
- data/lib/badline/gui/pane.rb +7 -6
- data/lib/badline/gui/screen_pane.rb +9 -13
- data/lib/badline/gui/window.rb +35 -20
- data/lib/badline/gui.rb +1 -1
- data/lib/badline/input/mouse1351.rb +21 -6
- data/lib/badline/input/paddles.rb +11 -6
- data/lib/badline/kernal_trap/channel.rb +3 -0
- data/lib/badline/kernal_trap/drive/block_commands.rb +33 -4
- data/lib/badline/kernal_trap/drive/status.rb +3 -0
- data/lib/badline/kernal_trap/drive/write_file.rb +41 -0
- data/lib/badline/kernal_trap/drive/writes.rb +92 -0
- data/lib/badline/kernal_trap/drive.rb +51 -51
- data/lib/badline/kernal_trap/file.rb +6 -9
- data/lib/badline/kernal_trap/save.rb +9 -4
- data/lib/badline/keyboard.rb +19 -3
- data/lib/badline/media.rb +42 -11
- data/lib/badline/options.rb +209 -0
- data/lib/badline/ram_expansion/banking.rb +30 -0
- data/lib/badline/ram_expansion/plus256k.rb +38 -0
- data/lib/badline/ram_expansion/plus60k.rb +31 -0
- data/lib/badline/ram_expansion/unexpanded.rb +22 -0
- data/lib/badline/ram_expansion.rb +21 -0
- data/lib/badline/region.rb +51 -0
- data/lib/badline/sdl/events.rb +47 -0
- data/lib/badline/sdl/functions.rb +73 -0
- data/lib/badline/sdl.rb +67 -0
- data/lib/badline/sid/waveform/noise_writeback.rb +32 -14
- data/lib/badline/sid/waveform.rb +1 -1
- data/lib/badline/sid.rb +3 -1
- data/lib/badline/storage/d64_image.rb +10 -0
- data/lib/badline/storage/d71_image.rb +12 -0
- data/lib/badline/storage/d81_image.rb +9 -0
- data/lib/badline/storage/disk_image/bam.rb +111 -0
- data/lib/badline/storage/disk_image/directory.rb +79 -0
- data/lib/badline/storage/disk_image/writing.rb +110 -0
- data/lib/badline/storage/disk_image.rb +27 -4
- data/lib/badline/storage/host_directory.rb +2 -1
- data/lib/badline/storage.rb +15 -0
- data/lib/badline/time_of_day.rb +4 -2
- data/lib/badline/version.rb +1 -1
- data/lib/badline/via/control_lines.rb +104 -0
- data/lib/badline/via/interrupt_register.rb +58 -0
- data/lib/badline/via/shift_register.rb +135 -0
- data/lib/badline/via/timer1.rb +82 -0
- data/lib/badline/via/timer2.rb +84 -0
- data/lib/badline/via.rb +262 -0
- data/lib/badline/vic/bank.rb +4 -3
- data/lib/badline/vic/color_patches.rb +6 -3
- data/lib/badline/vic/display_state.rb +4 -0
- data/lib/badline/vic/graphics_shifter.rb +42 -7
- data/lib/badline/vic/registers.rb +3 -0
- data/lib/badline/vic/sequencer.rb +18 -18
- data/lib/badline/vic/sequencer_output.rb +4 -4
- data/lib/badline/vic/sprite/internal_bus.rb +4 -0
- data/lib/badline/vic/sprite/shifter.rb +25 -3
- data/lib/badline/vic/sprite.rb +5 -4
- data/lib/badline/vic/sprites.rb +8 -3
- data/lib/badline/vic.rb +93 -44
- data/lib/badline.rb +4 -0
- data/packaging/homebrew/badline.rb +34 -0
- metadata +30 -20
- data/exe/badline +0 -78
- data/exe/badline-sid +0 -34
- data/lib/badline/audio/options.rb +0 -137
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b8f0c7ca349b7139fbb2c891e8a134bec1d4653ee4ff93edd9ec4088bf5c1809
|
|
4
|
+
data.tar.gz: 245b97ff97f8b442b3ad389198560b096b704805f5e6925601b44c45255fc299
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: eba9f947b6a929f46eccf02146a13778e68b7e24e2a731f31722aba4e18d49c6f89b60e8eccaace777e1d258a09b71f08d86ae51749c8bb2e4ebcd830677d57d
|
|
7
|
+
data.tar.gz: 391cd6122a22940dab59dc5d32fb1b4918eb6ba444cc4113ced0003ae865fe31fadfbfbd9515063bb466f8c473d02422e7a03bb06fbbf6ef2f049ca2261851d5
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Prepares a Claude Code on the web container to run `bundle exec rubocop`
|
|
3
|
+
# and `bundle exec rspec`. The regression suites need vendor/ and aren't set
|
|
4
|
+
# up here.
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
if [ "${CLAUDE_CODE_REMOTE:-}" != "true" ]; then
|
|
8
|
+
exit 0
|
|
9
|
+
fi
|
|
10
|
+
|
|
11
|
+
cd "${CLAUDE_PROJECT_DIR:-$(dirname "$0")/../..}"
|
|
12
|
+
|
|
13
|
+
# The SDL specs open libSDL2 through Fiddle, so only the runtime library is
|
|
14
|
+
# needed, as in CI.
|
|
15
|
+
if ! ldconfig -p | grep 'libSDL2-2\.0\.so\.0' >/dev/null; then
|
|
16
|
+
export DEBIAN_FRONTEND=noninteractive
|
|
17
|
+
apt-get update -qq
|
|
18
|
+
apt-get install -y -qq libsdl2-2.0-0 >/dev/null
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
# The image ships Ruby 3.3 and an rbenv. Install the newest Ruby 4.0.x, as
|
|
22
|
+
# CI's ruby-version "4.0" picks, from the prebuilt binaries setup-ruby uses,
|
|
23
|
+
# unless a 4.0 is installed already.
|
|
24
|
+
export RBENV_ROOT=/opt/rbenv
|
|
25
|
+
export PATH="$RBENV_ROOT/bin:$RBENV_ROOT/shims:$PATH"
|
|
26
|
+
ruby_version=$(rbenv versions --bare | grep -E '^4\.0\.[0-9]+$' | sort -V | tail -1 || true)
|
|
27
|
+
if [ -z "$ruby_version" ]; then
|
|
28
|
+
ruby_version=$(curl -fsSL https://raw.githubusercontent.com/ruby/setup-ruby/master/ruby-builder-versions.json |
|
|
29
|
+
ruby -rjson -e 'puts JSON.parse($stdin.read)["ruby"].grep(/\A4\.0\.\d+\z/).max_by { Gem::Version.new(_1) }')
|
|
30
|
+
# The binaries only run from the prefix they were built with, so unpack
|
|
31
|
+
# there and link it into rbenv.
|
|
32
|
+
. /etc/os-release
|
|
33
|
+
prefix="/opt/hostedtoolcache/Ruby/$ruby_version/x64"
|
|
34
|
+
mkdir -p "$prefix"
|
|
35
|
+
if curl -fsSL "https://github.com/ruby/ruby-builder/releases/download/ruby-$ruby_version/ruby-$ruby_version-ubuntu-$VERSION_ID-x64.tar.gz" |
|
|
36
|
+
tar -xz -C "$prefix" --strip-components=1; then
|
|
37
|
+
ln -sfn "$prefix" "$RBENV_ROOT/versions/$ruby_version"
|
|
38
|
+
else
|
|
39
|
+
# No binary for this Ubuntu release: build from source, which takes minutes.
|
|
40
|
+
rm -rf "$prefix"
|
|
41
|
+
git -C "$RBENV_ROOT/plugins/ruby-build" pull --ff-only -q || true
|
|
42
|
+
MAKE_OPTS="-j$(nproc)" rbenv install --skip-existing "$ruby_version"
|
|
43
|
+
fi
|
|
44
|
+
fi
|
|
45
|
+
rbenv global "$ruby_version"
|
|
46
|
+
rbenv rehash
|
|
47
|
+
|
|
48
|
+
# Put rbenv's shims ahead of /usr/local/bin/ruby for the session.
|
|
49
|
+
if [ -n "${CLAUDE_ENV_FILE:-}" ]; then
|
|
50
|
+
{
|
|
51
|
+
echo "export RBENV_ROOT=$RBENV_ROOT"
|
|
52
|
+
echo "export PATH=\"$RBENV_ROOT/bin:$RBENV_ROOT/shims:\$PATH\""
|
|
53
|
+
} >> "$CLAUDE_ENV_FILE"
|
|
54
|
+
fi
|
|
55
|
+
|
|
56
|
+
# Bundler switches to the version Gemfile.lock was bundled with.
|
|
57
|
+
bundle install --jobs "$(nproc)"
|
data/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,70 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.4.1](https://github.com/elektronaut/badline/compare/v0.4.0...v0.4.1) (2026-09-28)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Bug Fixes
|
|
7
|
+
|
|
8
|
+
* build the Homebrew pack with Spinel d3182102 ([42b42d5](https://github.com/elektronaut/badline/commit/42b42d506270f16cfb033c7d538e75131f7c74c2))
|
|
9
|
+
|
|
10
|
+
## [0.4.0](https://github.com/elektronaut/badline/compare/v0.3.0...v0.4.0) (2026-09-28)
|
|
11
|
+
|
|
12
|
+
### Upgrading
|
|
13
|
+
|
|
14
|
+
* The gem's executable is now `badline-ruby`. The name `badline` now belongs to the native build, which installs with `brew install elektronaut/tap/badline` on macOS.
|
|
15
|
+
* `badline-sid` is gone. Play a tune with `badline-ruby --headless tune.sid` (or `badline --headless tune.sid`), and render one with `--audio-out out.wav`.
|
|
16
|
+
|
|
17
|
+
### ⚠ BREAKING CHANGES
|
|
18
|
+
|
|
19
|
+
* the `badline-sid` executable is gone. Use `badline-ruby --headless tune.sid` to play a tune and `badline-ruby tune.sid --audio-out out.wav` to render one. badline-sid's `-o`/`--output` option and positional output file became `--audio-out`, which has no short form. Badline::Audio::Options is now Badline::Options.
|
|
20
|
+
* the gem's `badline` executable is now `badline-ruby`. There is no `badline` shim.
|
|
21
|
+
|
|
22
|
+
### Features
|
|
23
|
+
|
|
24
|
+
* add a Homebrew formula for the native badline ([33c2e98](https://github.com/elektronaut/badline/commit/33c2e983a12275195383e33230137d461b1a9fd0))
|
|
25
|
+
* add mouse and paddle input to the native window ([f468c21](https://github.com/elektronaut/badline/commit/f468c2189b3b213561516a39ec0ffcedcb8c5b89))
|
|
26
|
+
* emulate GEO-RAM and run the testbench geo512k rows ([9a5395f](https://github.com/elektronaut/badline/commit/9a5395fd34ad42d21e08a3b498038850d790f253)), closes [#239](https://github.com/elektronaut/badline/issues/239)
|
|
27
|
+
* emulate the +60K and +256K RAM expansions ([9d60488](https://github.com/elektronaut/badline/commit/9d60488d01bd33c9d090f75f4765931f21911247)), closes [#240](https://github.com/elektronaut/badline/issues/240)
|
|
28
|
+
* fold badline-sid into badline-ruby ([443d155](https://github.com/elektronaut/badline/commit/443d1559bb5253d58f5378e7e212beda5b734bda))
|
|
29
|
+
* give the native badline badline-ruby's command-line options ([bd2ec0d](https://github.com/elektronaut/badline/commit/bd2ec0da269a95eccb37198dd3e03faf84651396))
|
|
30
|
+
* headless .sid options for the native badline ([4354e80](https://github.com/elektronaut/badline/commit/4354e80e5b61da9148a2077d1e0557ea23a833df))
|
|
31
|
+
* make the Spinel window the native badline executable ([54e8e71](https://github.com/elektronaut/badline/commit/54e8e7151e5ced11e536da6baaf779af7f4eae16))
|
|
32
|
+
* model the 6526A CIA ([18a2012](https://github.com/elektronaut/badline/commit/18a201253c4612bb2ae821e544c9e6f3a6e1fb8c))
|
|
33
|
+
* model the 8565 VIC-II ([e81b7fb](https://github.com/elektronaut/badline/commit/e81b7fb7053c8cca1b94dda66cda3357d2984aa1))
|
|
34
|
+
* mount disk images read-only ([c35b808](https://github.com/elektronaut/badline/commit/c35b80852da7ebcf92cbf7de9478d62ba9197602))
|
|
35
|
+
* pace the native window by vsync ([1fa4661](https://github.com/elektronaut/badline/commit/1fa4661b480cba2a79772096ee32327098719f1b))
|
|
36
|
+
* pack the native badline with spin pack (rake native:pack) ([1d2288b](https://github.com/elektronaut/badline/commit/1d2288bd4f9c6589a35a0f99f8f1b0baeaa8e69a))
|
|
37
|
+
* read SDL game controllers in the native window ([a80403c](https://github.com/elektronaut/badline/commit/a80403cefa5b75f4edbf9157631ff5eac9c234f9))
|
|
38
|
+
* rename the executable to badline-ruby ([6050d9d](https://github.com/elektronaut/badline/commit/6050d9db2376ada76af5068b1e9703162adb90b3))
|
|
39
|
+
* replace ruby-sdl2 with a Fiddle binding to libSDL2 ([f3a4b84](https://github.com/elektronaut/badline/commit/f3a4b8429330efaf2abfe2592e1df2fd0791a9ee)), closes [#253](https://github.com/elektronaut/badline/issues/253)
|
|
40
|
+
* run the C64/ and general/ testbench rows as testbench-general ([53316c0](https://github.com/elektronaut/badline/commit/53316c03cd87e9e72d92ff8a6a9e13b6d0eae807))
|
|
41
|
+
* run the Lorenz chain on a Spinel build with rake spinel:lorenz ([955d722](https://github.com/elektronaut/badline/commit/955d722a06865f6a704f14570d7b246963317551))
|
|
42
|
+
* run the SID testprogs on a Spinel build with rake spinel:sidtests ([ecff9ba](https://github.com/elektronaut/badline/commit/ecff9bafa8b3621454e540d92707c0c139c7f7fd))
|
|
43
|
+
* run the testbench suites on a Spinel build with rake spinel:testbench ([083911a](https://github.com/elektronaut/badline/commit/083911af7194c56992f529f67c4bf101a44fb450))
|
|
44
|
+
* turn sound on by default in the native badline ([c4f65cf](https://github.com/elektronaut/badline/commit/c4f65cfa73fcad49399226f238b8b5b46799ed30))
|
|
45
|
+
* type RESTORE, ↑, ← and cursor up/left from the host keyboard ([74623e3](https://github.com/elektronaut/badline/commit/74623e346d4ccad26f779d3f0c9f0c11426b96c3)), closes [#234](https://github.com/elektronaut/badline/issues/234)
|
|
46
|
+
* write to disk images and swap them at runtime ([a6eebf5](https://github.com/elektronaut/badline/commit/a6eebf5e304186c8512e5cda4f6514a92ac64395)), closes [#233](https://github.com/elektronaut/badline/issues/233)
|
|
47
|
+
|
|
48
|
+
### Bug Fixes
|
|
49
|
+
|
|
50
|
+
* end a testbench run on the cycle the test writes its exit code ([58aa8c5](https://github.com/elektronaut/badline/commit/58aa8c52e639945a78cac40330e15a686081d8ec))
|
|
51
|
+
* keep pixel 0 black out of an invalid mode into hi-res text on the 8565 ([5a6ff96](https://github.com/elektronaut/badline/commit/5a6ff96192455b9f3ca9fd8904aa9bb4760e99cc))
|
|
52
|
+
* leave a PRG's end address in $AE/$AF on autostart ([d76ed18](https://github.com/elektronaut/badline/commit/d76ed1840850045ac7a1c1d3dc5c6d5d99685fdd))
|
|
53
|
+
* leave the VIC's phi1 byte in the RAM under the CPU port ([55fc2f5](https://github.com/elektronaut/badline/commit/55fc2f52cd0d0a0edeb56cde140e67fb1ab50077))
|
|
54
|
+
* make the mouse speed independent of the window size ([5cbabbf](https://github.com/elektronaut/badline/commit/5cbabbfade4e53c8aae265f2493466419ef67958)), closes [#280](https://github.com/elektronaut/badline/issues/280)
|
|
55
|
+
* make the VIC's collision registers read-only ([141526c](https://github.com/elektronaut/badline/commit/141526ce755bf47582a25e2c209cdc950ff81f0b))
|
|
56
|
+
* name the release tag in the native --version ([5654433](https://github.com/elektronaut/badline/commit/56544334b43ed992d0d54215a99a7be50fa74240))
|
|
57
|
+
* read unused bits of $D016 and $D018 as 1 ([00a816b](https://github.com/elektronaut/badline/commit/00a816b9bdbe88c7f838f941b2ef2dc5cd7db075)), closes [#237](https://github.com/elektronaut/badline/issues/237)
|
|
58
|
+
* say SDL2 is missing instead of raising from badline-ruby ([0f5ec9c](https://github.com/elektronaut/badline/commit/0f5ec9c7fabfa922ecb4c87339ba3ccc0f09bca0))
|
|
59
|
+
* SID test bit writeback for noiselfsrinit, F->8 and the 8580's C->F ([bdb063f](https://github.com/elektronaut/badline/commit/bdb063f1aba3f1714e26bc3e8301adf9bc33fb3e)), closes [#238](https://github.com/elektronaut/badline/issues/238)
|
|
60
|
+
* suggest the SDL2 runtime package when badline-ruby can't find it ([44a3375](https://github.com/elektronaut/badline/commit/44a3375973aafc0ec7aba672609517dd6571f85c))
|
|
61
|
+
* **vic:** read the idle byte at $38ff where a DMA delay starts ([f3892aa](https://github.com/elektronaut/badline/commit/f3892aa0ac45fbc493bccd0f5980dfe7fc659848)), closes [#235](https://github.com/elektronaut/badline/issues/235)
|
|
62
|
+
|
|
63
|
+
### Performance Improvements
|
|
64
|
+
|
|
65
|
+
* **vic:** check the DMA-delay idle byte only when display state opens ([8d9b777](https://github.com/elektronaut/badline/commit/8d9b777b3554ed4d6bef67ac41c0a344c3b0a35b))
|
|
66
|
+
|
|
67
|
+
|
|
3
68
|
## [0.3.0](https://github.com/elektronaut/badline/compare/v0.2.1...v0.3.0) (2026-09-24)
|
|
4
69
|
|
|
5
70
|
Sound is the headline: `badline --sound` plays the SID in the emulator window and paces emulation to the audio device. It is off by default, because the emulator still runs below real time on CRuby and the sound stutters there. This release also brings the virtual drive closer to a real 1541 (buffer channels in drive RAM, DOS command parsing, the BAM in buffer 4, `LOAD"*"`), cartridge banking fixes, and `Badline::Checkpoint` with `bin/machine_diff` for checking that a change leaves emulation alone.
|
data/CLAUDE.md
CHANGED
|
@@ -18,18 +18,22 @@ live in subdirectories:
|
|
|
18
18
|
modes, border and register timing
|
|
19
19
|
- **CIA**: `cia.rb` and `cia/` (timers, serial), plus `time_of_day.rb`
|
|
20
20
|
- **SID**: `sid.rb` and `sid/`. `audio/` plays and renders tunes for
|
|
21
|
-
`
|
|
21
|
+
`badline-ruby --headless` and `--audio-out`
|
|
22
22
|
- **Media and host I/O**: `storage/` (disk, tape and cartridge image
|
|
23
23
|
formats), `cartridge/` (mappers), `kernal_trap/` (the LOAD/SAVE and IEC
|
|
24
24
|
traps that stand in for a drive), `media.rb` (attach and autostart),
|
|
25
25
|
`datasette.rb`, and `gui/` and `input/` (SDL front end, controllers)
|
|
26
|
+
- **Native**: `native/` holds the native `badline`, the core compiled with
|
|
27
|
+
Spinel in an SDL2 window (`rake native:build`, `native/README.md`).
|
|
28
|
+
`spinel/` holds the Spinel test harnesses
|
|
26
29
|
|
|
27
30
|
Timing-critical code lives in `cpu`, `interrupts`, `vic`, `cia` and `sid` and
|
|
28
31
|
in the order `Computer#cycle!` clocks them. Changes there move the test
|
|
29
32
|
suites below. `gui/` changes move none of them.
|
|
30
33
|
|
|
31
34
|
Namespaced groups live in `lib/badline/<namespace>/`, with a sibling
|
|
32
|
-
`lib/badline/<namespace>.rb` that requires the members
|
|
35
|
+
`lib/badline/<namespace>.rb` that requires the members, directly or through
|
|
36
|
+
other members. `lib/badline.rb`
|
|
33
37
|
requires only the namespace file.
|
|
34
38
|
|
|
35
39
|
### Oracles
|
|
@@ -60,7 +64,7 @@ and speed work.
|
|
|
60
64
|
|
|
61
65
|
## Driving the emulator headlessly
|
|
62
66
|
|
|
63
|
-
`exe/badline <media>` opens the SDL window, which is no use for checking
|
|
67
|
+
`exe/badline-ruby <media>` opens the SDL window, which is no use for checking
|
|
64
68
|
work. Drive a `Badline::Computer` from Ruby instead, as the `bin/` runners do:
|
|
65
69
|
|
|
66
70
|
```ruby
|
|
@@ -119,11 +123,12 @@ worktree and owns a different set of files.
|
|
|
119
123
|
|
|
120
124
|
- `rake vendor:checkout` fetches SingleStepTests and VICE-testprogs into
|
|
121
125
|
`vendor/`
|
|
122
|
-
- `bundle exec rspec`: line coverage is about
|
|
126
|
+
- `bundle exec rspec`: line coverage is about 97%. `spec/spec_helper.rb`
|
|
123
127
|
fails a whole-suite run (every spec file, no filters) below 90%, while
|
|
124
128
|
single-file and filtered runs skip the floor. `:slow` specs are excluded
|
|
125
129
|
by default: run them with `bundle exec rspec --tag slow`
|
|
126
|
-
- `rake test`: SingleStepTests
|
|
130
|
+
- `rake test`: SingleStepTests, plus the Minitest tests for the regression
|
|
131
|
+
runners in `test/`. Run it for any CPU change
|
|
127
132
|
|
|
128
133
|
The headless suites are expensive. `bin/testbench` forks over 4 shards by
|
|
129
134
|
default. `SHARDS=N rake regression:<suite>` or `bin/testbench --shards N`
|
|
@@ -131,7 +136,7 @@ overrides that, capped by the core count, but keep the default, because
|
|
|
131
136
|
other worktrees share the machine. Whole runs at 4 shards on an M-series
|
|
132
137
|
laptop take 15 min for `testbench` (`VICII/`), 11 for `testbench-cia`, 1 for
|
|
133
138
|
`testbench-interrupts`, 37 for `testbench-irqdma`, 11 for
|
|
134
|
-
`testbench-cpu` and
|
|
139
|
+
`testbench-cpu`, 2 for `testbench-carts` and 10 for `testbench-expansions`. `sid` takes about 12 min. `lorenz` chains itself and takes
|
|
135
140
|
about 2.5 h on CI whole. `rake regression:lorenz-1` to `lorenz-4` run it as
|
|
136
141
|
four stretches of about 40 min each, and they can run side by side.
|
|
137
142
|
`test/baselines/README.md` has the full table. A killed `bin/testbench` run
|
|
@@ -164,17 +169,23 @@ the rows your change can't reach tell you nothing about it.
|
|
|
164
169
|
nightly run. It also runs from the Actions tab on demand. It never runs
|
|
165
170
|
on push or on pull requests, so one verdict can cover a day's merges.
|
|
166
171
|
The `testbench-*` and `sid-8580` suites run from the Actions tab on
|
|
167
|
-
demand
|
|
172
|
+
demand. The Spinel workflow runs the Spinel suites on pull requests
|
|
173
|
+
that touch emulation, harness or build paths. Its jobs aren't required
|
|
174
|
+
checks yet, and the CRuby Regression nightly runs as before
|
|
168
175
|
- The one exception is a change whose reach you can't bound to a set of
|
|
169
176
|
filters, such as reordering `Computer#cycle!` or changing the LOAD trap
|
|
170
177
|
every suite loads through. Ask before running a full suite for it, and
|
|
171
178
|
don't start one on your own judgement
|
|
172
179
|
|
|
173
|
-
Pick the filters from the suites your change can move: VIC → `testbench
|
|
180
|
+
Pick the filters from the suites your change can move: VIC → `testbench`,
|
|
181
|
+
plus `testbench-vicii-new` (`bin/testbench --vicii-new`, the 8565) for
|
|
182
|
+
anything the VIC model reaches;
|
|
174
183
|
CPU, interrupts or timing → the matching `testbench-*` suite, plus
|
|
175
184
|
`rake test` for CPU; CIA → the slow CIA specs first, then the matching
|
|
176
|
-
`testbench-cia` rows
|
|
177
|
-
|
|
185
|
+
`testbench-cia` rows, plus `testbench-cia-new` (`bin/testbench --cia-new`,
|
|
186
|
+
the 6526A) for anything the interrupt register or the CIA model reaches; cartridge mappers, banking or power-on state →
|
|
187
|
+
`testbench-carts`, plus `testbench-expansions` for banking; GEO-RAM, +60K
|
|
188
|
+
or +256K → `testbench-expansions`; SID → `sid`, plus `sid-8580` for anything the 8580
|
|
178
189
|
model reaches (`bin/sidtests --sid 8580`). Lorenz isn't a per-change check:
|
|
179
190
|
its full chain runs nightly, and the planner assigns any row it moves. The
|
|
180
191
|
exception is code whose rule in `doc/pinned-behaviour.md` names Lorenz
|
|
@@ -207,17 +218,35 @@ you change code a pinned rule governs, re-derive the rule against its test
|
|
|
207
218
|
and update the doc if the rule moves. A green suite alone isn't enough,
|
|
208
219
|
because the suite can stay green while the rule breaks.
|
|
209
220
|
|
|
221
|
+
## Issues and pull requests
|
|
222
|
+
|
|
223
|
+
Before filing an issue or opening a pull request, read CONTRIBUTING.md and follow it. Use the exact headings from its skeletons. Report only what you observed or verified, and don't include hypotheses about causes. Open an issue before writing non-trivial code; only changes with one obvious fix (typos, broken links, clear-cut fixes) go straight to a pull request.
|
|
224
|
+
|
|
225
|
+
### Working from issues
|
|
226
|
+
|
|
227
|
+
Open issues are agreed work. An agent told to pick issues works this way:
|
|
228
|
+
|
|
229
|
+
- Pick an open issue without the `in-progress` label whose dependencies
|
|
230
|
+
(named in its body) have merged. Add the label and a comment saying you've
|
|
231
|
+
taken it before you start
|
|
232
|
+
- Work in a worktree from `origin/main` as described under *Working in
|
|
233
|
+
parallel*. The issue's text is your brief. If it turns out wrong or
|
|
234
|
+
blocked, comment on the issue and stop rather than widening the scope
|
|
235
|
+
- Open one pull request per issue with `Closes #N` in its body, and run
|
|
236
|
+
only the rows your change can reach. Picking an issue is permission to
|
|
237
|
+
commit, push and open that pull request
|
|
238
|
+
- Never merge, and never enable auto-merge. The planner session reviews
|
|
239
|
+
every pull request, answers through PR reviews, and merges
|
|
240
|
+
- Fix review findings on the same branch. If you drop an issue, remove
|
|
241
|
+
the label and say why in a comment
|
|
242
|
+
|
|
210
243
|
## Git
|
|
211
244
|
|
|
212
|
-
- **Don't stage, commit, push or open a PR** unless your task says so in
|
|
213
|
-
those words. Wanting a PR, a finished feature or green CI doesn't count
|
|
214
|
-
as permission. Finish the work, report what changed, and stop. A dirty
|
|
215
|
-
tree is the expected end state
|
|
216
245
|
- Hunks are staged by hand during review, so a partially staged file is
|
|
217
246
|
deliberate. Use `git diff HEAD` to see everything
|
|
218
247
|
- Commit messages use Conventional Commits (`feat:`, `fix:`, `chore:`, …).
|
|
219
248
|
release-please derives version bumps and the changelog from the prefixes
|
|
220
249
|
- No `Co-Authored-By` or `Claude-Session` trailers, even where `git log`
|
|
221
250
|
shows them
|
|
222
|
-
-
|
|
223
|
-
|
|
251
|
+
- Open pull requests against `main`, from a branch cut from `origin/main`
|
|
252
|
+
(see above): `gh pr create --base main`
|
data/CONTRIBUTING.md
CHANGED
|
@@ -1,16 +1,58 @@
|
|
|
1
1
|
# Contributing
|
|
2
2
|
|
|
3
|
+
This guide covers bug reports, feature requests, and pull requests. It applies to everyone, including AI agents filing on someone's behalf.
|
|
4
|
+
|
|
5
|
+
In the GitHub web interface, issue forms guide you through the structure. If you file through the API or the `gh` CLI, the forms are bypassed: copy the matching skeleton from [Skeletons](#skeletons) and keep the headings exactly as written.
|
|
6
|
+
|
|
3
7
|
Bug reports and pull requests are welcome on
|
|
4
8
|
[GitHub](https://github.com/elektronaut/badline). Everyone participating
|
|
5
9
|
is expected to follow the [code of conduct](CODE_OF_CONDUCT.md).
|
|
6
10
|
|
|
11
|
+
## Principles
|
|
12
|
+
|
|
13
|
+
### For all issues and pull requests
|
|
14
|
+
|
|
15
|
+
**Report only what you observed or verified.** Whoever investigates, human or agent, anchors on the claims in a report. Unverified claims cost more time than they save.
|
|
16
|
+
|
|
17
|
+
**No hypotheses about causes.** Diagnosis is the maintainers' job. They add theories as comments, where the author shows how much weight to give them. Speculation in a report misleads everyone who reads it.
|
|
18
|
+
|
|
19
|
+
**Keep it short.** Length hides the useful information. A long report usually means two reports, or padding.
|
|
20
|
+
|
|
21
|
+
**One concern per issue or pull request.** Mixed concerns can't be tracked, reviewed, or reverted independently.
|
|
22
|
+
|
|
23
|
+
**Use the exact headings.** Maintainers and their tools rely on them to process reports.
|
|
24
|
+
|
|
25
|
+
### Bug reports
|
|
26
|
+
|
|
27
|
+
**Minimal, numbered steps you actually ran.** A reproduction nobody has run is speculation too.
|
|
28
|
+
|
|
29
|
+
**Raw output, not a paraphrase.** The details that matter are the ones a summary drops.
|
|
30
|
+
|
|
31
|
+
**Ruled out: negative results only.** "Still happens with caching disabled" narrows the search without steering it.
|
|
32
|
+
|
|
33
|
+
### Feature requests
|
|
34
|
+
|
|
35
|
+
**Problem before solution.** A proposed solution constrains the design before anyone familiar with the code has weighed in.
|
|
36
|
+
|
|
37
|
+
### Pull requests
|
|
38
|
+
|
|
39
|
+
**Open an issue before writing non-trivial code.** Code is cheap to write; choosing the right change is the expensive part. An issue lets maintainers weigh in on the approach before anything is built, while an unsolicited implementation anchors the discussion on one solution. Open a pull request directly only when there's one obvious way to make the change: typos, broken links, or a clear-cut fix. Reporting those costs more than fixing them. They don't need the template; a one-line description is ideal.
|
|
40
|
+
|
|
41
|
+
**Describe what changed, not what it might fix.** The diff shows how. Broad claims steer reviewers the same way hypotheses steer investigators.
|
|
42
|
+
|
|
43
|
+
### Security
|
|
44
|
+
|
|
45
|
+
**Never report vulnerabilities publicly.** Report them privately as described in [SECURITY.md](SECURITY.md).
|
|
46
|
+
|
|
7
47
|
## Getting started
|
|
8
48
|
|
|
9
|
-
Badline needs SDL2, which is available from most package
|
|
49
|
+
Badline needs the SDL2 library, which is available from most package
|
|
50
|
+
managers. Building the native `badline` also needs the SDL2 headers
|
|
51
|
+
(`libsdl2-dev` on Debian/Ubuntu); see [native/README.md](native/README.md).
|
|
10
52
|
|
|
11
53
|
```sh
|
|
12
54
|
brew install sdl2 # macOS
|
|
13
|
-
apt install libsdl2-
|
|
55
|
+
apt install libsdl2-2.0-0 # Debian/Ubuntu
|
|
14
56
|
```
|
|
15
57
|
|
|
16
58
|
Install the dependencies and run the specs:
|
|
@@ -40,7 +82,7 @@ Check style before pushing:
|
|
|
40
82
|
bundle exec rubocop
|
|
41
83
|
```
|
|
42
84
|
|
|
43
|
-
##
|
|
85
|
+
## Tests and commits
|
|
44
86
|
|
|
45
87
|
- Add tests for any behavior you change.
|
|
46
88
|
- Write commit messages using
|
|
@@ -49,3 +91,53 @@ bundle exec rubocop
|
|
|
49
91
|
`fix:` prefixes decide what ends up in the next release.
|
|
50
92
|
- Leave the version and `CHANGELOG.md` alone. Both are updated
|
|
51
93
|
automatically when a release is cut.
|
|
94
|
+
|
|
95
|
+
## Skeletons
|
|
96
|
+
|
|
97
|
+
Leave out optional sections you have nothing for.
|
|
98
|
+
|
|
99
|
+
### Bug report
|
|
100
|
+
|
|
101
|
+
```markdown
|
|
102
|
+
### Expected behavior
|
|
103
|
+
|
|
104
|
+
<!-- What should happen. -->
|
|
105
|
+
|
|
106
|
+
### Actual behavior
|
|
107
|
+
|
|
108
|
+
<!-- What happened instead, as observed. Include the error message, if any. -->
|
|
109
|
+
|
|
110
|
+
### Steps to reproduce
|
|
111
|
+
|
|
112
|
+
1.
|
|
113
|
+
2.
|
|
114
|
+
3.
|
|
115
|
+
|
|
116
|
+
### Error output
|
|
117
|
+
|
|
118
|
+
<!-- Optional. Raw stack trace or log lines in a code block. -->
|
|
119
|
+
|
|
120
|
+
### Ruled out
|
|
121
|
+
|
|
122
|
+
<!-- Optional. Negative results only, e.g. "Still happens with caching disabled." -->
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Feature request
|
|
126
|
+
|
|
127
|
+
```markdown
|
|
128
|
+
### Problem
|
|
129
|
+
|
|
130
|
+
<!-- What you're trying to do, and what's blocking you. -->
|
|
131
|
+
|
|
132
|
+
### Current workaround
|
|
133
|
+
|
|
134
|
+
<!-- Optional. How you get around it today, if at all. -->
|
|
135
|
+
|
|
136
|
+
### Proposed solution
|
|
137
|
+
|
|
138
|
+
<!-- Optional, and brief. -->
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Pull request
|
|
142
|
+
|
|
143
|
+
See [.github/pull_request_template.md](.github/pull_request_template.md).
|