badline 0.18.0 → 0.19.0

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.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +40 -0
  3. data/CLAUDE.md +8 -0
  4. data/CONTRIBUTING.md +4 -0
  5. data/README.md +10 -7
  6. data/doc/library.md +5 -1
  7. data/doc/media.md +3 -2
  8. data/doc/pinned-behaviour.md +41 -1
  9. data/doc/snapshot-format.md +56 -24
  10. data/doc/snapshots.md +45 -8
  11. data/doc/vice.md +344 -0
  12. data/lib/badline/audio/renderer.rb +4 -8
  13. data/lib/badline/c128.rb +4 -0
  14. data/lib/badline/c64/bus/fittings.rb +6 -0
  15. data/lib/badline/c64.rb +6 -0
  16. data/lib/badline/cbm2/p500.rb +4 -0
  17. data/lib/badline/cbm2.rb +4 -0
  18. data/lib/badline/chips/cpu/core.rb +29 -4
  19. data/lib/badline/chips/cpu/interrupts.rb +9 -0
  20. data/lib/badline/chips/cpu/keyed_state.rb +15 -9
  21. data/lib/badline/chips/cpu/microcode.rb +10 -0
  22. data/lib/badline/chips/rriot.rb +4 -1
  23. data/lib/badline/chips/sid/decimator.rb +1 -1
  24. data/lib/badline/chips/sid/keyed_parts.rb +51 -18
  25. data/lib/badline/chips/sid.rb +6 -2
  26. data/lib/badline/chips/vic_i/keyed_parts.rb +6 -1
  27. data/lib/badline/chips/vic_i/light_pen.rb +89 -0
  28. data/lib/badline/chips/vic_i.rb +12 -7
  29. data/lib/badline/drives/model1541/sector_reader.rb +20 -3
  30. data/lib/badline/drives/model1541.rb +1 -0
  31. data/lib/badline/drives/model1551.rb +1 -0
  32. data/lib/badline/drives/model1571.rb +1 -0
  33. data/lib/badline/drives/model1581.rb +1 -0
  34. data/lib/badline/drives/model2031.rb +1 -0
  35. data/lib/badline/drives/model4040/mechanism.rb +6 -3
  36. data/lib/badline/drives/model4040.rb +17 -1
  37. data/lib/badline/drives/model8050/board.rb +2 -0
  38. data/lib/badline/drives/model8050/dos_board.rb +49 -6
  39. data/lib/badline/drives/model8050/fdc_bus.rb +7 -0
  40. data/lib/badline/drives/model8050/idle.rb +137 -24
  41. data/lib/badline/drives/model8050.rb +14 -0
  42. data/lib/badline/drives/model9060/idle.rb +30 -10
  43. data/lib/badline/drives/model9060.rb +2 -0
  44. data/lib/badline/input/joystick.rb +15 -2
  45. data/lib/badline/kim1/tape.rb +3 -1
  46. data/lib/badline/kim1.rb +4 -0
  47. data/lib/badline/machine.rb +3 -0
  48. data/lib/badline/media/true_drive.rb +10 -0
  49. data/lib/badline/media/vic20_media.rb +4 -2
  50. data/lib/badline/media.rb +5 -1
  51. data/lib/badline/memory.rb +2 -4
  52. data/lib/badline/options/table.rb +1 -1
  53. data/lib/badline/pet/superpet/dongle.rb +13 -2
  54. data/lib/badline/pet/superpet.rb +5 -0
  55. data/lib/badline/pet.rb +4 -0
  56. data/lib/badline/plus4.rb +4 -0
  57. data/lib/badline/roms/README +11 -1
  58. data/lib/badline/snapshot/container.rb +6 -4
  59. data/lib/badline/snapshot/field_doc.rb +8 -4
  60. data/lib/badline/snapshot/image.rb +15 -6
  61. data/lib/badline/snapshot/vice/pet.rb +1 -0
  62. data/lib/badline/snapshot/vice/pet_dongle.rb +72 -0
  63. data/lib/badline/snapshot/vice/pet_mem.rb +11 -5
  64. data/lib/badline/snapshot/vice/vic20.rb +70 -0
  65. data/lib/badline/snapshot/vice/vic20_cpu.rb +61 -0
  66. data/lib/badline/snapshot/vice/vic20_mem.rb +85 -0
  67. data/lib/badline/snapshot/vice/vic20_restore.rb +124 -0
  68. data/lib/badline/snapshot/vice/vic20_vici.rb +200 -0
  69. data/lib/badline/snapshot/vice.rb +1 -0
  70. data/lib/badline/snapshot.rb +4 -4
  71. data/lib/badline/storage/disk_image/writing.rb +2 -2
  72. data/lib/badline/version.rb +1 -1
  73. data/lib/badline/vic20/port_wiring.rb +11 -0
  74. data/lib/badline/vic20.rb +4 -0
  75. metadata +9 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1a3848536bdfa64fefb71cdb9347928e1ce8494c7b13594c07df72abc60f5ca0
4
- data.tar.gz: 56c2eb4db9e9cc1953a4255c4d05d46ac01049c143d72a79f972bafefab2a919
3
+ metadata.gz: 45be9424707255afd6c8c04be00d7bde36cca422c188b66229fb6fab9355bd3b
4
+ data.tar.gz: 7571cfbef8994cc7aeb82bcc619548abd88762f0b7f43807b18a5a6a6e50ff7a
5
5
  SHA512:
6
- metadata.gz: bc38c1d29d366004792db0dd24928c238f6396ce99a24491cb74fa1eb6d95e4f02e843d09da7f179f0a1b33f5e7ceae2e1ed73dfad2abd852802c714ccdb91b3
7
- data.tar.gz: f81c7525afd46d0325feecce49bd2f9abda8c3410fc5854b0dea1166703f3c8bdb775bfd84d6c83e161dd3fd586cd0b23c286e564d5559c5d2d006427fedea6f
6
+ metadata.gz: 33fc10445d3bb1971c698c4adcfbfa8fae3de078a62f808f3e62f06b31f9bd1728653c34f6e5a2f7944187d063377a81f8bd6d6f475d76cbab121f481948386c
7
+ data.tar.gz: 90b6dbdf27f29321a191ee63bcb8f96faafb02ce768d8ffc332d5a49cabc40326062824eb04552fb790f0575ad79849e69c1904b8c8005878a4f6a20337b3d0d
data/CHANGELOG.md CHANGED
@@ -1,5 +1,45 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.19.0](https://github.com/elektronaut/badline/compare/v0.18.0...v0.19.0) (2026-10-27)
4
+
5
+ ### Highlights
6
+
7
+ - **VIC-20 snapshots in VICE's format**: badline reads and writes xvic's `.vsf` snapshots of the PAL and NTSC VIC-20, so a machine saved in one emulator carries on in the other.
8
+ - **SuperPET snapshots**: xpet's `.vsf` now carries the SuperPET's 6702 dongle in both directions.
9
+ - **6502 reset**: the CPU runs its seven-cycle reset sequence through the bus, as the chip does, so a machine starts its first instruction on the same cycle as x64sc.
10
+ - **C64GS and MAX Machine**: neither has a serial port, so disks and true drives are refused on them rather than attached to a bus that isn't there.
11
+ - **Homebrew bottles**: `brew install elektronaut/tap/badline` pours a prebuilt binary on Apple Silicon (Sequoia) and x86_64 Linux instead of compiling it.
12
+
13
+ ### Features
14
+
15
+ * read and write the SuperPET's 6702 in xpet's .vsf ([75beb83](https://github.com/elektronaut/badline/commit/75beb8365760b19561e7178df5ddfe20e983ba87))
16
+ * read and write xvic's snapshots of the VIC-20, PAL and NTSC ([7e039a7](https://github.com/elektronaut/badline/commit/7e039a7deffc6e1283d5bc7e00182ae5350235e6))
17
+ * refuse disks and true drives on the C64GS and the MAX Machine, which have no serial port ([a4ba76d](https://github.com/elektronaut/badline/commit/a4ba76d0d40180fc3e6113fbb35306114e940bc5))
18
+ * run the VIC-20 testbench's screenshot rows and its NTSC raster and light pen programs ([1f54561](https://github.com/elektronaut/badline/commit/1f54561f2d8ba3bc511bf5d80d3b5f0365cc3a5b))
19
+
20
+
21
+ ### Bug Fixes
22
+
23
+ * autostart the first program off a disk image on BASIC 1, not the image itself ([3f31daa](https://github.com/elektronaut/badline/commit/3f31daa044497d2524b7906691cf9f4e8881eb6b))
24
+ * carry a recording SID's sample window across snapshots ([c4472c1](https://github.com/elektronaut/badline/commit/c4472c1d1a5027171527bdc9b1d82614aefe94d2))
25
+ * latch the VIC-20's light pen as the fire button moves ([37ab4b9](https://github.com/elektronaut/badline/commit/37ab4b945a036ade5ea5f9064f91c6267777a912))
26
+ * read a 1541 data block back as far as its checksum ([bcb167e](https://github.com/elektronaut/badline/commit/bcb167e263504610129d43bc26c9c87b16388b68))
27
+ * run the 6502's reset sequence through the bus ([a32f25c](https://github.com/elektronaut/badline/commit/a32f25cd04d4df9cd2e7aa8a63393a9661452aad))
28
+
29
+
30
+ ### Performance Improvements
31
+
32
+ * build Memory's storage as an Integer array and seed the VIC's geometry for Spinel ([b84353d](https://github.com/elektronaut/badline/commit/b84353d792f20fbfe5421fda534946b4f3e2cd19))
33
+ * seed CPU::Core's fields for every 6502 and qualify the drive and PET memory seeds ([6bf511c](https://github.com/elektronaut/badline/commit/6bf511c040105d7e8403593501fc9d8fb2a785fe))
34
+ * seed Snapshot::Keyed::Reader#int and #bool for Spinel ([8e1692b](https://github.com/elektronaut/badline/commit/8e1692bae61c76bc69869a094a7eb4fd748ddd95))
35
+ * seed the CIA's interrupt register, timers, shift register and TOD types for Spinel ([bc1e468](https://github.com/elektronaut/badline/commit/bc1e4686314f90a66be038d78f92a0b297538989))
36
+ * seed the KIM-1's CPU, 6530s, timer and bus types for Spinel ([0e42b9d](https://github.com/elektronaut/badline/commit/0e42b9d888e7ff1c4e871b49d32fe593c3e33a76))
37
+ * seed the Plus/4's CPU, TED and bus types for Spinel ([50d0c1f](https://github.com/elektronaut/badline/commit/50d0c1f63c2401158a77342fc8a37f4bb2031e95))
38
+ * sleep a 4040 whose motors turn with no disk in either drive ([2203749](https://github.com/elektronaut/badline/commit/22037497b80b04d26e947fb999f517422b59a18b))
39
+ * sleep an idle D9060 through planned host cycles and wake it as the controller moves a line ([5823192](https://github.com/elektronaut/badline/commit/582319299c75b9c1f39b22d2879b4ac06c8cf3c3))
40
+ * splice a disk image's sectors back in ([1f7242d](https://github.com/elektronaut/badline/commit/1f7242de9bd6e7c3001a96143efc171995e54ed2))
41
+ * wake only an idle 8050's controller for its 5 ms timer ([d733081](https://github.com/elektronaut/badline/commit/d7330814ca73b84c5537e8ca8d4e65121742b9b6))
42
+
3
43
  ## [0.18.0](https://github.com/elektronaut/badline/compare/v0.17.0...v0.18.0) (2026-10-20)
4
44
 
5
45
  ### Highlights
data/CLAUDE.md CHANGED
@@ -250,6 +250,14 @@ the rows your change can't reach tell you nothing about it.
250
250
  builds the native binary locally (`rake native:build`; on macOS with
251
251
  `SPINEL_CC="cc -Wno-nullability-completeness"`) before it's pushed, or
252
252
  types its arguments in `spinel/sig`
253
+ - Anywhere in `lib/`, don't name a method after one that Array, String,
254
+ Hash, Integer or IO define (`length`, `size`, `fill`, `step`, `sample`,
255
+ `write`, `truncate`) unless it returns the same type. Spinel can't tell
256
+ which classes a dynamic `new` builds, such as `BankedRAM.build`'s
257
+ `TYPES.fetch(type).new`, so it counts every class as constructible, and
258
+ the new method widens every untyped call of that name in the emulator.
259
+ In 0.18.0, a KIM-1 tape's `length` broke `D90Image`'s `Array#fill` in
260
+ a harness that never builds a KIM-1
253
261
  - The Regression workflow runs the suites on CRuby, started by hand from
254
262
  the Actions tab, for a person checking that CRuby and Spinel agree.
255
263
  Agents don't start it
data/CONTRIBUTING.md CHANGED
@@ -103,6 +103,10 @@ bundle exec rubocop
103
103
  `main` every two hours. When a change moves rows on purpose, re-record just
104
104
  those rows as [test/baselines/README.md](test/baselines/README.md)
105
105
  describes, and say why in the pull request.
106
+ - Timing rules derived against a test are in
107
+ [doc/pinned-behaviour.md](doc/pinned-behaviour.md). What VICE's
108
+ emulators check, how they're driven, their known quirks and where
109
+ badline differs from them are in [doc/vice.md](doc/vice.md).
106
110
  - Write commit messages using
107
111
  [Conventional Commits](https://www.conventionalcommits.org). The
108
112
  changelog and releases are generated from them, so the `feat:` and
data/README.md CHANGED
@@ -33,8 +33,10 @@ The native `badline`, with Homebrew:
33
33
  brew install elektronaut/tap/badline
34
34
  ```
35
35
 
36
- The formula builds it from the release's generated C, so it needs no
37
- Spinel or Ruby. To build it from a checkout instead, see
36
+ It installs a prebuilt bottle on macOS 15 or newer on Apple Silicon and
37
+ on x86_64 Linux. Elsewhere the formula builds it from the release's
38
+ generated C, so it needs no Spinel or Ruby. To build it from a checkout
39
+ instead, see
38
40
  [native/README.md](native/README.md).
39
41
 
40
42
  The gem needs Ruby 4.0 or newer and the SDL2 library:
@@ -96,7 +98,7 @@ differences noted in the table. `--help` lists the options for either.
96
98
  | `--sid-card-address fd40`, `--sid-card-address fe80` | Put the SID card at `$FD40` (the default) or at `$FE80` |
97
99
  | `--ram-expansion NAME` | Fit a Plus/4 or C16 with a RAM expansion: `hannes256`, `hannes1m` or `csory256`. See [The Plus/4](#the-plus4) |
98
100
  | `--reu SIZE` | Plug in a RAM Expansion Unit of `SIZE` K: 128, 256, 512 (a 1750) or up to 16384 |
99
- | `--model NAME` | Run another model of the machine, named as in VICE. For the C64: `c64` (the default, a PAL C64 with the 6569 VIC-II, 6526 CIAs and the 6581 SID), `c64c` (the PAL C64C, with the 8565, 6526As and the 8580), `ntsc` (the 6567R8), `newntsc` (the NTSC C64C, with the 8562, 6526As and the 8580), `oldntsc` (the first NTSC C64s' 6567R56A), `drean` (the Drean C64 of Argentina, PAL-N with the 6572), `sx64` (the portable SX-64, with its own KERNAL and no datasette), `pet64` (the PET 64 or Educator 64, a PAL C64 in a PET's case with its own KERNAL and a green monochrome monitor) `c64gs` (the C64GS games console, a PAL C64C with its own BASIC and KERNAL, and no keyboard or datasette) or `ultimax` (the MAX Machine of Japan, NTSC with 2K of RAM, one CIA and no ROMs, which runs only a cartridge). `--sid` or a `.sid` tune's own SID takes the model's place. The VIC-20, the C128, the Plus/4, the PET and the CBM-II have models of their own: see their sections |
101
+ | `--model NAME` | Run another model of the machine, named as in VICE. For the C64: `c64` (the default, a PAL C64 with the 6569 VIC-II, 6526 CIAs and the 6581 SID), `c64c` (the PAL C64C, with the 8565, 6526As and the 8580), `ntsc` (the 6567R8), `newntsc` (the NTSC C64C, with the 8562, 6526As and the 8580), `oldntsc` (the first NTSC C64s' 6567R56A), `drean` (the Drean C64 of Argentina, PAL-N with the 6572), `sx64` (the portable SX-64, with its own KERNAL and no datasette), `pet64` (the PET 64 or Educator 64, a PAL C64 in a PET's case with its own KERNAL and a green monochrome monitor) `c64gs` (the C64GS games console, a PAL C64C with its own BASIC and KERNAL, and no keyboard, datasette or disk drive) or `ultimax` (the MAX Machine of Japan, NTSC with 2K of RAM, one CIA, no ROMs and no disk drive, which runs only a cartridge). `--sid` or a `.sid` tune's own SID takes the model's place. The VIC-20, the C128, the Plus/4, the PET and the CBM-II have models of their own: see their sections |
100
102
  | `--ntsc` | Run an NTSC C64 or VIC-20, as `--model ntsc` does |
101
103
  | `--tty` | Fit the KIM-1's TTY/KB jumper, so its monitor talks to a teletype: a page in the window, or the terminal with `--headless`. See [The KIM-1](#the-kim-1) |
102
104
  | `--baud N` | Run the KIM-1's teletype at `110`, `300`, `1200`, `2400`, `4800` or `9600` baud (the default) |
@@ -122,7 +124,7 @@ differences noted in the table. `--help` lists the options for either.
122
124
  | `--script FILE` | Run the events in `FILE`, one `FRAME:EVENT` a line |
123
125
  | `--screenshot FILE` | Save the last frame as a `.bmp` |
124
126
  | `--save-snapshot FILE` | Save the machine as a `.vsf` snapshot after the last frame |
125
- | `--vice` | Add VICE's modules to `--save-snapshot`'s C64, PET or CBM-II snapshot, so x64sc, xpet, xcbm2 or xcbm5x0 opens it too |
127
+ | `--vice` | Add VICE's modules to `--save-snapshot`'s C64, VIC-20, PET or CBM-II snapshot, so x64sc, xvic, xpet, xcbm2 or xcbm5x0 opens it too |
126
128
 
127
129
  ```sh
128
130
  badline --unpaced --frames 12000 --true-drive disk1.d64 \
@@ -185,8 +187,8 @@ its start of BASIC comes with, and more of BLK1 to BLK3 when it runs
185
187
  past `$3FFF`. A program that loads at `$A000` is a cartridge's ROM, and
186
188
  goes in as a `.crt` does. Disks go through the KERNAL traps or, with
187
189
  `--true-drive`, a 1541, as on the C64. `F11`, `F12` and the pause menu
188
- save and load the VIC-20 too, in badline's own snapshots: xvic's `.vsf`
189
- files don't load.
190
+ save and load the VIC-20 too, and xvic's `.vsf` files load, as
191
+ [doc/snapshots.md](doc/snapshots.md#xvic) describes.
190
192
 
191
193
  ## The C128
192
194
 
@@ -756,7 +758,8 @@ in cartridge 1 as it does from the command line.
756
758
  (`--reu`), with DMA timed against the VIC's bad lines and sprites.
757
759
  - **Datasette**: `.tap` playback.
758
760
  - **VIC-20**: the 6502, the PAL 6561 and NTSC 6560 VIC-I with its
759
- picture and sound and the 6560's interlaced fields' timing, both 6522
761
+ picture, sound and light pen latch and the 6560's interlaced fields'
762
+ timing, both 6522
760
763
  VIAs, the keyboard, the joystick and RESTORE, RAM
761
764
  expansions up to 35K (`--ram`), cartridges, the datasette and the
762
765
  serial bus to device 8 (`badline vic20`).
data/doc/library.md CHANGED
@@ -49,12 +49,16 @@ model (`Badline::Model::ALL`):
49
49
  - `kernal: :gs` fits the C64GS's BASIC and KERNAL, and `board: :gs` its
50
50
  case, which has no keyboard: `computer.keyboard` takes no keys. The
51
51
  C64GS has both, and no datasette.
52
+ - `board: :gs` and `board: :max` have no serial port, so
53
+ `Badline::Media.attach` and `Media.insert_disk` raise
54
+ `Badline::Machine::Unsupported` for a disk image, a `.t64` or a host
55
+ directory, and `Media::TrueDrive.plug` for a true drive.
52
56
  - `board: :max` builds the MAX Machine's board: 2K of RAM at
53
57
  `$0000-$07FF`, no ROMs mapped, CIA 1 alone, answering all through
54
58
  `$DC00-$DFFF` but for the I/O 1 page a cartridge takes, and Ultimax
55
59
  mode with or without a cartridge. CIA 2 is never on the bus, so the
56
60
  VIC stays in bank 0. `Badline::Model::ULTIMAX` runs it on
57
- `Badline::Region::NTSC_OLD`.
61
+ `Badline::Region::NTSC_OLD`, with a datasette at its cassette port.
58
62
 
59
63
  ## Cartridges
60
64
 
data/doc/media.md CHANGED
@@ -127,11 +127,12 @@ of half waves.
127
127
 
128
128
  A program SAVEd that way on the C64 loads and runs in VICE's x64sc, on
129
129
  the VIC-20 in xvic, and on the Plus/4 or the C16 in xplus4 as a Plus/4.
130
- Neither the Plus/4's tape nor the C16's ran on xplus4's C16 model.
130
+ xplus4's C16 model loads no tape, its own included (#704).
131
131
  Checked with VICE 3.10.
132
132
 
133
133
  ## The light pen
134
134
 
135
135
  Control port 1's fire line is also the VIC-II's light pen input, so
136
136
  joystick 1's fire button and the 1351's left button in port 1 latch the
137
- light pen registers.
137
+ light pen registers. On the VIC-20 the joystick's fire line is the
138
+ VIC-I's light pen input, and the fire button latches `$9006` and `$9007`.
@@ -37,6 +37,7 @@ only catches the rows that happen to move.
37
37
  - [RAM power-on pattern](#ram-power-on-pattern)
38
38
  - [VIC-20 RAM power-on pattern](#vic-20-ram-power-on-pattern)
39
39
  - [VIC-I fetches and the V-bus](#vic-i-fetches-and-the-v-bus)
40
+ - [VIC-I light pen](#vic-i-light-pen)
40
41
  - [VIC-I sound](#vic-i-sound)
41
42
  - [TED beam and the 7501 port](#ted-beam-and-the-7501-port)
42
43
  - [TED sound](#ted-sound)
@@ -1424,11 +1425,24 @@ and each was knocked out: removing it fails the rows named.
1424
1425
  - Pinned by `VIC20/split-tests/timing`: all 1,024 bytes of its readings
1425
1426
  of `$9003`, `$9004`, `$9100` and `$9200` over 256 cycles match
1426
1427
  `dumps/dump6561e.prg`, a real 6561E. The later 6561-101's dump reads
1427
- `$20` in the idle cycles instead; badline follows the 6561E.
1428
+ `$20` in the idle cycles instead; badline follows the 6561E. On the
1429
+ 6560, `timing_ntsc` matches `dumps/dump6560-101.prg` byte for byte
1430
+ from `$17E0`, and `dumps/dump6560.prg`, from another NTSC machine,
1431
+ reads `$20` in the idle cycles as the 6561-101 does.
1428
1432
  - Spec guard:
1429
1433
  [`chips/vic_i_split_tests_timing_spec.rb`](../spec/badline/chips/vic_i_split_tests_timing_spec.rb)
1430
1434
  (`:slow`), and *the fetches* in
1431
1435
  [`chips/vic_i_video_spec.rb`](../spec/badline/chips/vic_i_video_spec.rb).
1436
+ - The 6560's raster count, which `$9003` bit 7 and `$9004` read, moves
1437
+ on to the next line 28 cycles into a line, and on the last line wraps
1438
+ to 0 at column 61 (`Chips::VICI::NTSC`), measured on xvic as a black
1439
+ box.
1440
+ - Pinned by `VIC20/split-tests/timing`'s `timing_ntsc`, whose `$9003`
1441
+ and `$9004` readings match `dumps/dump6560-101.prg`, and by
1442
+ `VIC20/vic_line0/raster-ntsc`, whose effect starts 33 cycles later
1443
+ for `$9004` at 0 than for 1, as its readme reports from a real
1444
+ machine, and in one field 33 later and in the other on time with
1445
+ interlace (`testbench-vic20-ntsc`).
1432
1446
  - A write to `$900F` or `$900E` takes hold from the second of the four
1433
1447
  pixels of the cycle it lands in, the reverse bit two pixels later, and
1434
1448
  a character's pixels come out in the two cycles after its pattern
@@ -1437,6 +1451,32 @@ and each was knocked out: removing it fails the rows named.
1437
1451
  - Spec guard: *a colour write* in
1438
1452
  [`chips/vic_i_video_spec.rb`](../spec/badline/chips/vic_i_video_spec.rb).
1439
1453
 
1454
+ ## VIC-I light pen
1455
+
1456
+ - A falling edge on the light pen line, VIA 1's PA5 on the VIC-20,
1457
+ latches `$9006` = 2h + 1, where h is the edge's column plus two,
1458
+ wrapping at the line's end, and `$9007` = the raster count of the next
1459
+ cycle, bits 8-1, the 6560's early count included
1460
+ (`Chips::VICI::LightPen`). The column is badline's, the VIC's at the
1461
+ cycle of the VIA write.
1462
+ - Around the cycle where the count turns to 0 (the 6561's frame start,
1463
+ the 6560's column 61 of its last line): an edge from 8 cycles before it
1464
+ to 1 after it latches as an edge in the cycle after it would, with
1465
+ `$9007` at 0, but an edge 2 cycles before it latches an even `$9006`,
1466
+ one less. Earlier, an edge latches nothing while the count read its
1467
+ last value of the frame in the cycle before the edge: 311 on the 6561,
1468
+ 261 on the 6560.
1469
+ - A second edge in a frame latches again. The test drives one edge a
1470
+ measurement, so no dump checks it.
1471
+ - Pinned by `VIC20/split-tests/lightpen`: `lightpen.prg`'s 1,024
1472
+ readings of `$9003`, `$9004`, `$9006` and `$9007` match
1473
+ `dumps/dump6561e.prg`, and `lightpen_ntsc.prg`'s match
1474
+ `dumps/dump6560.prg`, both from `$17E0` (`testbench-vic20` and
1475
+ `testbench-vic20-ntsc`). The even `$9006` shows in both dumps; the
1476
+ readme says the 6561E's was verified with 3 more dumps.
1477
+ - Spec guard:
1478
+ [`chips/vic_i_light_pen_spec.rb`](../spec/badline/chips/vic_i_light_pen_spec.rb).
1479
+
1440
1480
  ## VIC-I sound
1441
1481
 
1442
1482
  No testprog checks the VIC-I's sound, so these rules are pinned by xvic
@@ -129,12 +129,12 @@ Written by the C64, C128, Plus/4, VIC-20, PET, CBM-II, KIM-1.
129
129
  | `port.ddr` | byte | C64: 0; C128: 0; Plus/4: 0 |
130
130
  | `port.data` | byte | C64: 0; C128: 0; Plus/4: 0 |
131
131
  | `port.floating` | byte | C64: 0; C128: 0 |
132
- | `pc` | word | C64: 64738; VIC-20: 64802; C128: 65341; Plus/4: 65526; PET: 64790 or 64824; CBM-II: 63895 or 63902; KIM-1: 7202 |
133
- | `sp` | byte | 255 |
132
+ | `pc` | word | C64: 0; VIC-20: 0; C128: 65341; Plus/4: 0; PET: 0; CBM-II: 0; KIM-1: 0 |
133
+ | `sp` | byte | C64: 0; VIC-20: 0; C128: 255; Plus/4: 0; PET: 0; CBM-II: 0; KIM-1: 0 |
134
134
  | `a` | byte | 0 |
135
135
  | `x` | byte | 0 |
136
136
  | `y` | byte | 0 |
137
- | `p` | byte | 32 |
137
+ | `p` | byte | C64: 36; VIC-20: 36; C128: 32; Plus/4: 36; PET: 36; CBM-II: 36; KIM-1: 36 |
138
138
  | `nmi` | bool | false |
139
139
  | `so_high` | bool | true |
140
140
  | `irq.sample` | bool | false |
@@ -147,7 +147,17 @@ Written by the C64, C128, Plus/4, VIC-20, PET, CBM-II, KIM-1.
147
147
  | `cycles` | int | 0 |
148
148
  | `instructions` | int | 0 |
149
149
  | `stalled` | int, optional | absent |
150
- | `pos.seq` | text: boundary op interrupt jam | "boundary" |
150
+ | `pos.seq` | text: boundary op interrupt jam reset | "boundary" |
151
+ | `pos.crossed` | bool | PET: false |
152
+ | `pos.t` | int | PET: 0 |
153
+ | `pos.branch_taken` | bool | PET: false |
154
+ | `pos.brk` | bool | PET: false |
155
+ | `pos.vector` | int, optional | PET: absent |
156
+ | `pos.address` | int, optional | PET: absent |
157
+ | `pos.dummy_address` | int, optional | PET: absent |
158
+ | `pos.value` | int, optional | PET: absent |
159
+ | `pos.rmw` | int, optional | PET: absent |
160
+ | `pos.pointer` | int, optional | PET: absent |
151
161
 
152
162
  ## BL-VIC
153
163
 
@@ -449,6 +459,13 @@ Written by the C64, C128, Plus/4, CBM-II.
449
459
  | `ext.lowpass` | int | 0 |
450
460
  | `ext.highpass` | int | 0 |
451
461
  | `ext.output` | int | 0 |
462
+ | `rec.rate` | int | 0 |
463
+ | `rec.clock_hz` | int | C64: 985248 |
464
+ | `rec.phase` | int | C64: 0 |
465
+ | `rec.sum` | int | C64: 0 |
466
+ | `rec.count` | int | C64: 0 |
467
+ | `rec.cycles_to_close` | int | C64: 23 |
468
+ | `rec.filter_chunk` | int | C64: 4 |
452
469
 
453
470
  ## BL-TAPE
454
471
 
@@ -747,12 +764,12 @@ Written by the C64, C128, Plus/4, PET.
747
764
 
748
765
  | Key | Type | Default |
749
766
  | --- | --- | --- |
750
- | `pc` | word | C64: 60064 or 44836; C128: 60064; Plus/4: 60064 or 59829; PET: 60101 |
751
- | `sp` | byte | 255 |
767
+ | `pc` | word | 0 |
768
+ | `sp` | byte | 0 |
752
769
  | `a` | byte | 0 |
753
770
  | `x` | byte | 0 |
754
771
  | `y` | byte | 0 |
755
- | `p` | byte | 32 |
772
+ | `p` | byte | 36 |
756
773
  | `nmi` | bool | false |
757
774
  | `so_high` | bool | true |
758
775
  | `irq.sample` | bool | false |
@@ -765,7 +782,18 @@ Written by the C64, C128, Plus/4, PET.
765
782
  | `cycles` | int | 0 |
766
783
  | `instructions` | int | 0 |
767
784
  | `stalled` | int, optional | absent |
768
- | `pos.seq` | text: boundary op interrupt jam | "boundary" |
785
+ | `pos.seq` | text: boundary op interrupt jam reset | "boundary" |
786
+ | `pos.op` | byte | C64: 234; Plus/4: 234 |
787
+ | `pos.crossed` | bool | C64: false; C128: false; Plus/4: false |
788
+ | `pos.t` | int | C64: 1; C128: 0; Plus/4: 1 |
789
+ | `pos.branch_taken` | bool | C64: false; C128: false; Plus/4: false |
790
+ | `pos.brk` | bool | C64: false; C128: false; Plus/4: false |
791
+ | `pos.vector` | int, optional | C64: absent; C128: absent; Plus/4: absent |
792
+ | `pos.address` | int, optional | C64: absent; C128: absent; Plus/4: absent |
793
+ | `pos.dummy_address` | int, optional | C64: absent; C128: absent; Plus/4: absent |
794
+ | `pos.value` | int, optional | C64: absent; C128: absent; Plus/4: absent |
795
+ | `pos.rmw` | int, optional | C64: absent; C128: absent; Plus/4: absent |
796
+ | `pos.pointer` | int, optional | C64: absent; C128: absent; Plus/4: absent |
769
797
 
770
798
  ## BL-D8-DISK
771
799
 
@@ -795,7 +823,7 @@ Written by the C64, C128, Plus/4, PET.
795
823
  | `side` | int | C64: 0 or 1; C128: 85; Plus/4: 0; PET: 0 |
796
824
  | `zone` | int & 0x3 | C64: 3; C128: 3; Plus/4: 3 or 0; PET: 3 |
797
825
  | `time` | int | 0 |
798
- | `read_clock_in` | int | 2097152 |
826
+ | `read_clock_in` | int | C64: -3145728; C128: 2097152; Plus/4: -4194304 or 2097152; PET: -3145728 |
799
827
  | `clocks` | int | 0 |
800
828
  | `shift` | int | 0 |
801
829
  | `ones` | int | 0 |
@@ -976,6 +1004,7 @@ Written by the C64.
976
1004
  | `ext.lowpass` | int | 0 |
977
1005
  | `ext.highpass` | int | 0 |
978
1006
  | `ext.output` | int | 0 |
1007
+ | `rec.rate` | int | 0 |
979
1008
 
980
1009
  ## BL-VICI
981
1010
 
@@ -997,6 +1026,9 @@ Written by the VIC-20.
997
1026
  | `fetch_from` | int | 0 |
998
1027
  | `fetched` | int | 0 |
999
1028
  | `code` | byte | 0 |
1029
+ | `pen.x` | byte | 0 |
1030
+ | `pen.y` | byte | 0 |
1031
+ | `pen.low` | bool | false |
1000
1032
  | `line.layout` | int | 0 |
1001
1033
  | `display` | bytes | 88608 × 0 |
1002
1034
  | `line.row` | int | 311 |
@@ -1009,8 +1041,8 @@ Written by the VIC-20.
1009
1041
  | `sound.shift_registers` | ints | [0, 0, 0, 255] |
1010
1042
  | `sound.lfsr` | int & 0xffff | 65535 |
1011
1043
  | `sound.level` | int | 0 |
1012
- | `sound.ran_ago` | int | 0 |
1013
- | `sound.next_shifts` | ints | [2048, 1024, 512, 256] |
1044
+ | `sound.ran_ago` | int | 5 |
1045
+ | `sound.next_shifts` | ints | [2043, 1019, 507, 251] |
1014
1046
 
1015
1047
  ## BL-VIA1
1016
1048
 
@@ -1225,7 +1257,7 @@ Written by the Plus/4.
1225
1257
  | `voice<N>.phase` | int & 0x1 | 1 |
1226
1258
  | `voice<N>.toggle_in` | int, optional | absent |
1227
1259
  | `noise` | byte | 255 |
1228
- | `ran_ago` | int | 0 |
1260
+ | `ran_ago` | int | 6 |
1229
1261
 
1230
1262
  ## BL-KEYPORT
1231
1263
 
@@ -1552,12 +1584,12 @@ Written by the PET.
1552
1584
 
1553
1585
  | Key | Type | Default |
1554
1586
  | --- | --- | --- |
1555
- | `pc` | word | 62135 or 54059 or 61972 |
1556
- | `sp` | byte | 255 |
1587
+ | `pc` | word | 0 |
1588
+ | `sp` | byte | 0 |
1557
1589
  | `a` | byte | 0 |
1558
1590
  | `x` | byte | 0 |
1559
1591
  | `y` | byte | 0 |
1560
- | `p` | byte | 32 |
1592
+ | `p` | byte | 36 |
1561
1593
  | `nmi` | bool | false |
1562
1594
  | `so_high` | bool | true |
1563
1595
  | `irq.sample` | bool | false |
@@ -1570,7 +1602,7 @@ Written by the PET.
1570
1602
  | `cycles` | int | 0 |
1571
1603
  | `instructions` | int | 0 |
1572
1604
  | `stalled` | int, optional | absent |
1573
- | `pos.seq` | text: boundary op interrupt jam | "boundary" |
1605
+ | `pos.seq` | text: boundary op interrupt jam reset | "boundary" |
1574
1606
 
1575
1607
  ## BL-D8-FDCCPU
1576
1608
 
@@ -1578,12 +1610,12 @@ Written by the PET.
1578
1610
 
1579
1611
  | Key | Type | Default |
1580
1612
  | --- | --- | --- |
1581
- | `pc` | word | 64516 or 64521 |
1582
- | `sp` | byte | 255 |
1613
+ | `pc` | word | 0 |
1614
+ | `sp` | byte | 0 |
1583
1615
  | `a` | byte | 0 |
1584
1616
  | `x` | byte | 0 |
1585
1617
  | `y` | byte | 0 |
1586
- | `p` | byte | 32 |
1618
+ | `p` | byte | 36 |
1587
1619
  | `nmi` | bool | false |
1588
1620
  | `so_high` | bool | true |
1589
1621
  | `irq.sample` | bool | false |
@@ -1596,7 +1628,7 @@ Written by the PET.
1596
1628
  | `cycles` | int | 0 |
1597
1629
  | `instructions` | int | 0 |
1598
1630
  | `stalled` | int, optional | absent |
1599
- | `pos.seq` | text: boundary op interrupt jam | "boundary" |
1631
+ | `pos.seq` | text: boundary op interrupt jam reset | "boundary" |
1600
1632
 
1601
1633
  ## BL-D8-VIA
1602
1634
 
@@ -1671,12 +1703,12 @@ Written by the PET.
1671
1703
 
1672
1704
  | Key | Type | Default |
1673
1705
  | --- | --- | --- |
1674
- | `pc` | word | 63489 |
1675
- | `sp` | byte | 255 |
1706
+ | `pc` | word | 0 |
1707
+ | `sp` | byte | 0 |
1676
1708
  | `a` | byte | 0 |
1677
1709
  | `x` | byte | 0 |
1678
1710
  | `y` | byte | 0 |
1679
- | `p` | byte | 32 |
1711
+ | `p` | byte | 36 |
1680
1712
  | `nmi` | bool | false |
1681
1713
  | `so_high` | bool | true |
1682
1714
  | `irq.sample` | bool | false |
@@ -1689,7 +1721,7 @@ Written by the PET.
1689
1721
  | `cycles` | int | 0 |
1690
1722
  | `instructions` | int | 0 |
1691
1723
  | `stalled` | int, optional | absent |
1692
- | `pos.seq` | text: boundary op interrupt jam | "boundary" |
1724
+ | `pos.seq` | text: boundary op interrupt jam reset | "boundary" |
1693
1725
 
1694
1726
  ## BL-D8-SASIRAM
1695
1727
 
data/doc/snapshots.md CHANGED
@@ -83,6 +83,9 @@ disk comes back write-protected. A directory mounted as device 8 opens
83
83
  again from its path. What the host holds stays the
84
84
  host's: the keyboard, the joysticks, the mouse and paddles, sound, and
85
85
  blocks given to `on_init` that hadn't run yet, which a restore reports.
86
+ A SID that was recording saves how far into its current sample it had
87
+ got, and a restored one that records again at the same rate carries on
88
+ from there, so its output runs on as the saved one's would have.
86
89
 
87
90
  Every model saves this way, PAL, NTSC, old NTSC and Drean alike, and so
88
91
  does a machine with an REU, with its RAM and its registers. A snapshot
@@ -105,11 +108,42 @@ RAM, a cartridge's ROM, the VIC with its picture and sound, both VIAs,
105
108
  the CPU, the tape with its place on it, the disk or directory device 8
106
109
  serves through the traps and a true 1541 or 1581, and restores into a
107
110
  VIC-20 with the same RAM expansion. Its file names its machine `VIC20`,
108
- as xvic's do, and holds only badline's modules, so xvic doesn't open it,
109
- and badline doesn't open xvic's. Restoring a
111
+ as xvic's do, and holds only badline's modules, so xvic doesn't open it
112
+ unless it is saved with `--vice` (see [xvic](#xvic)). Restoring a
110
113
  VIC-20 snapshot while a C64 runs, or a C64 one while a VIC-20 runs,
111
114
  swaps the machine in the window.
112
115
 
116
+ ### xvic
117
+
118
+ A VIC-20 snapshot saved with `--vice`, or `computer.export_snapshot(path)`,
119
+ also holds xvic's modules for the CPU, the RAM, the VIC-I with the colour
120
+ RAM and both VIAs, and the ones xvic 3.10 needs to open the file, with no
121
+ cartridge, nothing open on the file system drive, the joystick released
122
+ and nothing on the user port. The file says it is in VICE's snapshot
123
+ format 3.1, the only one xvic reads.
124
+
125
+ xvic 3.10 opens those snapshots as long as its model matches:
126
+ `-model vic20` or `vic20ntsc`. It takes the RAM expansion from the
127
+ snapshot, whatever its `-memory` says, keeps its own drives and leaves
128
+ out badline's cartridge, tapes and disks. A program it runs on from badline's
129
+ snapshot runs as it does in badline, cycle for cycle, with the raster,
130
+ the VIAs' timers and RAM alike, but for a snapshot taken in an
131
+ interlaced frame, whose field xvic ends early (see
132
+ [VICE](vice.md#xvic)).
133
+
134
+ Snapshots xvic saves open in badline through the same modules: the CPU
135
+ at its instruction boundary, the RAM and the data lines' last bytes, the
136
+ VIC-I's registers, beam, frame, interlaced field, text window and
137
+ fetches, its light pen and the colour RAM, and both VIAs' registers,
138
+ timers and shift registers. The picture starts again with the next
139
+ frame, and the sound as at power-on. VIC20MEM's blocks and the VIC-I's
140
+ picture size build the machine: its RAM expansion and model. It reports
141
+ the modules it leaves out, such as the drives, the cartridge, the
142
+ datasette and the keyboard, and carries on without them. Restored into a
143
+ running VIC-20, an xvic snapshot fails for a VIC-20 built another way,
144
+ and otherwise switches the machine off and on, keeping its cartridge,
145
+ tapes and the disk device 8 serves.
146
+
113
147
  ## The C128
114
148
 
115
149
  `badline c128` saves and restores the same way too. A C128 snapshot
@@ -180,8 +214,8 @@ xpet 3.10 opens those snapshots as long as its model and editor match:
180
214
  `-model 2001`, `3032`, `3032B`, `4032`, `8032`, `8096`, `8296` or
181
215
  `SuperPET`, and for a badline editor other than xpet's own, `-editor`
182
216
  naming badline's ROM. xpet runs a SuperPET's 6809 when the snapshot
183
- says it has the bus, whatever its own CPU switch, and has no system
184
- latch, write protect or 6702 to take from it. xpet's 8296 runs the 8032's editor, 901474-04 dated 0283, so an
217
+ says it has the bus, whatever its own CPU switch, takes its 6702, and
218
+ has no system latch or write protect to take from it. xpet's 8296 runs the 8032's editor, 901474-04 dated 0283, so an
185
219
  8296 saved for it has to run that editor (`--editor 4-80-b-50hz-0283`),
186
220
  and xpet takes the 8296's jumpers from its own settings. It keeps its
187
221
  own datasettes and leaves out badline's tapes and disks. A true drive
@@ -227,9 +261,9 @@ fitted, or a SuperPET, at 50 or 60 Hz, and an 8032, 8096 or 8296 whose
227
261
  CRTC lines are 64 cycles long runs xpet's own 50 Hz editor, 901474-04
228
262
  dated 0283. A SuperPET comes with its bank RAM, its bank, its `$EFFE`
229
263
  bit and its ACIA, its CPU switch at the CPU that had the bus, and while
230
- that is the 6809, the 6809's registers. Its RAM switch is at R/W, the
231
- only position xpet has, its system latch is clear and its 6702 is as the
232
- RES line leaves it, since xpet saves none of them, and in 6809 mode its
264
+ that is the 6809, the 6809's registers, and its 6702. Its RAM switch is
265
+ at R/W, the only position xpet has, and its system latch is clear, since
266
+ xpet saves neither, and in 6809 mode its
233
267
  frame rate is the one the Waterloo ROM's CRTC table sets. It reports the modules it leaves out, such
234
268
  as the drives past device 8, the datasettes and the keyboard, and
235
269
  carries on without them, and a snapshot without a true drive takes
@@ -379,7 +413,10 @@ snapshot from its own modules, and leaves VICE's alone.
379
413
  x64sc 3.10 opens those snapshots, which are saved between
380
414
  instructions with no REU transfer under way, as long as its VIC-II
381
415
  model matches: `-model c64`, `c64c`, `ntsc`, `newntsc`,
382
- `oldntsc` or `drean`, as `--model` names the machine. It takes the REU
416
+ `oldntsc`, `drean`, `pet64` or `c64gs`, as `--model` names the machine.
417
+ The MAX Machine's needs `-model ultimax -VICIImodel 5`, since x64sc's
418
+ `ultimax` has the 6567R8 and badline's the 6567R56A. The snapshot names
419
+ the discrete glue logic, which x64sc's `c64c` and `c64gs` switch to. It takes the REU
383
420
  from the snapshot, keeps its own drives and leaves out the cartridge,
384
421
  the other expansions and the tape. A program x64sc runs on from badline's
385
422
  snapshot reads the raster as badline does, cycle for cycle.