badline 0.17.0 → 0.18.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 (166) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +153 -0
  3. data/CLAUDE.md +11 -7
  4. data/CONTRIBUTING.md +7 -1
  5. data/README.md +169 -20
  6. data/doc/pinned-behaviour.md +128 -0
  7. data/doc/snapshot-format.md +253 -18
  8. data/doc/snapshots.md +57 -23
  9. data/exe/badline-ruby +5 -0
  10. data/lib/badline/audio/terminal.rb +34 -2
  11. data/lib/badline/c128/keyed_state.rb +2 -0
  12. data/lib/badline/c128.rb +1 -0
  13. data/lib/badline/c64/keyed_state.rb +2 -0
  14. data/lib/badline/c64.rb +1 -0
  15. data/lib/badline/cbm2/keyed_state.rb +4 -0
  16. data/lib/badline/cbm2/p500.rb +5 -3
  17. data/lib/badline/cbm2.rb +6 -3
  18. data/lib/badline/chips/cia/timer.rb +2 -2
  19. data/lib/badline/chips/cpu/instruction_set.rb +1 -1
  20. data/lib/badline/chips/m6809/arithmetic.rb +140 -0
  21. data/lib/badline/chips/m6809/bus_steps.rb +223 -0
  22. data/lib/badline/chips/m6809/core.rb +149 -0
  23. data/lib/badline/chips/m6809/indexed.rb +82 -0
  24. data/lib/badline/chips/m6809/interrupts.rb +159 -0
  25. data/lib/badline/chips/m6809/keyed_state.rb +147 -0
  26. data/lib/badline/chips/m6809/opcodes.rb +159 -0
  27. data/lib/badline/chips/m6809/operations.rb +258 -0
  28. data/lib/badline/chips/m6809/plans.rb +143 -0
  29. data/lib/badline/chips/m6809/registers.rb +82 -0
  30. data/lib/badline/chips/m6809/stack.rb +140 -0
  31. data/lib/badline/chips/m6809.rb +13 -0
  32. data/lib/badline/chips/riot/timer.rb +14 -3
  33. data/lib/badline/chips/rriot.rb +4 -2
  34. data/lib/badline/chips/sid/filter.rb +4 -4
  35. data/lib/badline/chips/sid/waveform.rb +6 -6
  36. data/lib/badline/chips/vic_i/keyed_parts.rb +7 -2
  37. data/lib/badline/chips/vic_i.rb +84 -21
  38. data/lib/badline/data_path.rb +3 -3
  39. data/lib/badline/drives/ieee_models.rb +54 -0
  40. data/lib/badline/drives/model1001.rb +37 -0
  41. data/lib/badline/drives/model2031.rb +6 -0
  42. data/lib/badline/drives/model4040/disk.rb +62 -0
  43. data/lib/badline/drives/model4040/ip_bus.rb +46 -0
  44. data/lib/badline/drives/model4040/keyed_state.rb +57 -0
  45. data/lib/badline/drives/model4040/mechanism.rb +192 -0
  46. data/lib/badline/drives/model4040/parts.rb +20 -0
  47. data/lib/badline/drives/model4040.rb +179 -0
  48. data/lib/badline/drives/model8050/board.rb +77 -0
  49. data/lib/badline/drives/model8050/dos_board.rb +91 -0
  50. data/lib/badline/drives/model8050/idle.rb +11 -7
  51. data/lib/badline/drives/model8050/keyed_state.rb +5 -2
  52. data/lib/badline/drives/model8050.rb +18 -130
  53. data/lib/badline/drives/model9060/idle.rb +149 -0
  54. data/lib/badline/drives/model9060/keyed_state.rb +123 -0
  55. data/lib/badline/drives/model9060/parts.rb +98 -0
  56. data/lib/badline/drives/model9060/sasi_bus.rb +88 -0
  57. data/lib/badline/drives/model9060/sasi_commands.rb +168 -0
  58. data/lib/badline/drives/model9060/sasi_target.rb +161 -0
  59. data/lib/badline/drives/model9060.rb +195 -0
  60. data/lib/badline/frontend/app.rb +8 -0
  61. data/lib/badline/frontend/boot.rb +3 -2
  62. data/lib/badline/frontend/controls.rb +62 -6
  63. data/lib/badline/frontend/keys.rb +36 -0
  64. data/lib/badline/frontend/kim1_panel.rb +208 -0
  65. data/lib/badline/frontend/media_slots.rb +8 -1
  66. data/lib/badline/frontend/menu/drive_types.rb +56 -0
  67. data/lib/badline/frontend/menu/menu_dialogs.rb +61 -14
  68. data/lib/badline/frontend/menu/menu_media.rb +42 -12
  69. data/lib/badline/frontend/menu/menu_pages.rb +97 -2
  70. data/lib/badline/frontend/menu/menu_ports.rb +38 -1
  71. data/lib/badline/frontend/menu/pause_menu.rb +5 -1
  72. data/lib/badline/frontend/pet_keyboard.rb +23 -1
  73. data/lib/badline/frontend/screen.rb +1 -1
  74. data/lib/badline/frontend/screens.rb +40 -2
  75. data/lib/badline/frontend/teletype_pane.rb +152 -0
  76. data/lib/badline/frontend/timeline.rb +31 -2
  77. data/lib/badline/frontend.rb +3 -0
  78. data/lib/badline/kim1/bus.rb +117 -0
  79. data/lib/badline/kim1/cpu.rb +25 -0
  80. data/lib/badline/kim1/host_terminal.rb +74 -0
  81. data/lib/badline/kim1/key_entry.rb +74 -0
  82. data/lib/badline/kim1/keyed_modules.rb +53 -0
  83. data/lib/badline/kim1/keyed_state.rb +133 -0
  84. data/lib/badline/kim1/panel.rb +176 -0
  85. data/lib/badline/kim1/rriots.rb +28 -0
  86. data/lib/badline/kim1/sound.rb +29 -0
  87. data/lib/badline/kim1/tape.rb +116 -0
  88. data/lib/badline/kim1/teletype.rb +193 -0
  89. data/lib/badline/kim1.rb +190 -0
  90. data/lib/badline/machine/ieee_drives.rb +94 -117
  91. data/lib/badline/machine/keyboard_buffer.rb +20 -3
  92. data/lib/badline/machine/line_sound.rb +122 -0
  93. data/lib/badline/machine.rb +46 -15
  94. data/lib/badline/media/extensions.rb +8 -4
  95. data/lib/badline/media/kim1_media.rb +150 -0
  96. data/lib/badline/media/pet_media.rb +3 -1
  97. data/lib/badline/media/true_drive.rb +42 -45
  98. data/lib/badline/media.rb +12 -6
  99. data/lib/badline/options/family.rb +98 -8
  100. data/lib/badline/options/help.rb +44 -12
  101. data/lib/badline/options/table.rb +43 -11
  102. data/lib/badline/options/validation.rb +44 -8
  103. data/lib/badline/options.rb +27 -8
  104. data/lib/badline/pet/bus.rb +16 -2
  105. data/lib/badline/pet/keyboard_ports.rb +9 -2
  106. data/lib/badline/pet/keyed_state.rb +4 -0
  107. data/lib/badline/pet/model.rb +11 -2
  108. data/lib/badline/pet/rom_sets.rb +1 -0
  109. data/lib/badline/pet/sound.rb +5 -105
  110. data/lib/badline/pet/superpet/acia.rb +12 -0
  111. data/lib/badline/pet/superpet/board.rb +221 -0
  112. data/lib/badline/pet/superpet/dongle.rb +81 -0
  113. data/lib/badline/pet/superpet/keyed_modules.rb +63 -0
  114. data/lib/badline/pet/superpet/keyed_parts.rb +76 -0
  115. data/lib/badline/pet/superpet/m6809.rb +32 -0
  116. data/lib/badline/pet/superpet/waterloo_traps.rb +199 -0
  117. data/lib/badline/pet/superpet.rb +216 -0
  118. data/lib/badline/pet.rb +19 -3
  119. data/lib/badline/plus4/keyed_state.rb +2 -0
  120. data/lib/badline/plus4.rb +1 -0
  121. data/lib/badline/roms/1001/fdc-251257-02a.rom +0 -0
  122. data/lib/badline/roms/4040/dos-1.2.rom +0 -0
  123. data/lib/badline/roms/4040/dos-2.1-rev.rom +0 -0
  124. data/lib/badline/roms/4040/dos-2.1.rom +0 -0
  125. data/lib/badline/roms/4040/fdc-901466-02.rom +0 -0
  126. data/lib/badline/roms/4040/fdc-901466-04.rom +0 -0
  127. data/lib/badline/roms/9060/dos-3.0.rom +0 -0
  128. data/lib/badline/roms/9060/sasi-300515-revb.rom +0 -0
  129. data/lib/badline/roms/README +166 -0
  130. data/lib/badline/roms/kim1/6530-002.rom +0 -0
  131. data/lib/badline/roms/kim1/6530-003.rom +0 -0
  132. data/lib/badline/roms/pet/characters-superpet.rom +0 -0
  133. data/lib/badline/roms/pet/superpet-a000.rom +0 -0
  134. data/lib/badline/roms/pet/superpet-c000.rom +0 -0
  135. data/lib/badline/roms/pet/superpet-e000-50hz.rom +0 -0
  136. data/lib/badline/roms/pet/superpet-e000.rom +0 -0
  137. data/lib/badline/snapshot/container.rb +2 -0
  138. data/lib/badline/snapshot/field_doc/markdown.rb +1 -1
  139. data/lib/badline/snapshot/field_doc.rb +27 -6
  140. data/lib/badline/snapshot/image.rb +4 -1
  141. data/lib/badline/snapshot/kim1_setup.rb +28 -0
  142. data/lib/badline/snapshot/pet_setup.rb +27 -11
  143. data/lib/badline/snapshot/storage_setup.rb +4 -1
  144. data/lib/badline/snapshot/vic20_setup.rb +11 -7
  145. data/lib/badline/snapshot/vice/pet.rb +13 -7
  146. data/lib/badline/snapshot/vice/pet_cpu.rb +39 -5
  147. data/lib/badline/snapshot/vice/pet_crtc.rb +15 -2
  148. data/lib/badline/snapshot/vice/pet_drive8050.rb +188 -68
  149. data/lib/badline/snapshot/vice/pet_mem.rb +49 -5
  150. data/lib/badline/snapshot/vice/pet_restore.rb +40 -11
  151. data/lib/badline/snapshot.rb +4 -0
  152. data/lib/badline/status.rb +30 -30
  153. data/lib/badline/storage/d67_image.rb +55 -0
  154. data/lib/badline/storage/d90_image.rb +180 -0
  155. data/lib/badline/storage/disk_image/writing.rb +2 -2
  156. data/lib/badline/storage/kim_tape.rb +254 -0
  157. data/lib/badline/storage/papertape.rb +90 -0
  158. data/lib/badline/storage.rb +4 -0
  159. data/lib/badline/support/kim1_checkpoint.rb +41 -0
  160. data/lib/badline/support/superpet_checkpoint.rb +35 -0
  161. data/lib/badline/version.rb +1 -1
  162. data/lib/badline/vic20/keyed_modules.rb +6 -3
  163. data/lib/badline/vic20/keyed_state.rb +6 -4
  164. data/lib/badline/vic20.rb +26 -12
  165. data/lib/badline.rb +1 -0
  166. metadata +77 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0da2c8736f994b6f50c665b7bd8fdd6a1e311df953b16b0d7a09eb833771f96a
4
- data.tar.gz: a9922d7605a40eb98862e08c724ff7552a8e56d26662b95eb49b0fa954a9a9f5
3
+ metadata.gz: 1a3848536bdfa64fefb71cdb9347928e1ce8494c7b13594c07df72abc60f5ca0
4
+ data.tar.gz: 56c2eb4db9e9cc1953a4255c4d05d46ac01049c143d72a79f972bafefab2a919
5
5
  SHA512:
6
- metadata.gz: 7cb8eb2574f2816cd5eba6ac3077819583869dd5c60badec24cd3ef2e0d145ae0729c51268cbe47fd3b7781be1a0700415b26309c9eb3eb175e51bd8c799b858
7
- data.tar.gz: fd843b8b309c535c679c074801be2240e6e13c3ff65b671635c3a4d138808d048e73ce7802eabec3746d4e7154391757537e17e6ae30d91113c5df585a9c603a
6
+ metadata.gz: bc38c1d29d366004792db0dd24928c238f6396ce99a24491cb74fa1eb6d95e4f02e843d09da7f179f0a1b33f5e7ceae2e1ed73dfad2abd852802c714ccdb91b3
7
+ data.tar.gz: f81c7525afd46d0325feecce49bd2f9abda8c3410fc5854b0dea1166703f3c8bdb775bfd84d6c83e161dd3fd586cd0b23c286e564d5559c5d2d006427fedea6f
data/CHANGELOG.md CHANGED
@@ -1,7 +1,63 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.18.0](https://github.com/elektronaut/badline/compare/v0.17.0...v0.18.0) (2026-10-20)
4
+
5
+ ### Highlights
6
+
7
+ - **SuperPET**: `badline pet --model superpet` runs the SuperPET with both its CPUs. The 6502 side is an 8032 with 64K of bank RAM, the 6551 ACIA and the 6702 dongle. `--cpu 6809` boots the Waterloo menu on its 6809, and microBASIC, microAPL, Pascal, FORTRAN, COBOL and the editor load from disk and run unpatched. The pause menu sets the CPU and RAM switches, and APL types by key position.
8
+ - **KIM-1**: `badline kim1` runs the MOS KIM-1 with its six-digit display, keypad and single step, or with `--tty` on a teletype in the window or the terminal. Papertapes (`.ptp`, `.pap`) and binaries load straight into RAM or through the monitor's `L`, and cassettes play and record as `.wav`, including real recordings.
9
+ - **VIC-20 NTSC**: `badline vic20 --ntsc` runs the NTSC VIC-20 on its 6560, with its interlace.
10
+ - **Older PET drives**: `--drive-type` puts a 2040, 3040, 4040, SFD-1001, D9060 or D9090 on the PET's or the CBM-II's IEEE-488 bus, and the pause menu's drive page picks one. They read `.d64`, `.d67`, `.d82` and `.d90` images, a hard disk's `N` formats at once, and they save in xpet's `.vsf` snapshots.
11
+
12
+ ### Features
13
+
14
+ * add a cycle-by-cycle Motorola 6809E core ([5443d24](https://github.com/elektronaut/badline/commit/5443d24b5ce494c6ae15911b823944e3df620430))
15
+ * add the 2040 with DOS 1.2, and .d67 disks through it and the traps ([4e8a324](https://github.com/elektronaut/badline/commit/4e8a324d4db251785d4495db9d6c648897a4ad69))
16
+ * add the 4040 and 3040 as true drives on the PET's and CBM-II's IEEE-488 bus ([d9ce670](https://github.com/elektronaut/badline/commit/d9ce6709131e6a5b37b7650c9c3f85028df55a31))
17
+ * add the SFD-1001 as a true drive on the PET's and CBM-II's IEEE-488 bus ([eda00bf](https://github.com/elektronaut/badline/commit/eda00bf89c2b5fa14459b62c1b97262444ed2139))
18
+ * boot the SuperPET's 6809 to the Waterloo menu, with --cpu ([8e145d6](https://github.com/elektronaut/badline/commit/8e145d65237bcce25775cc1dfcc38723a1d45e8a))
19
+ * bundle the SuperPET's Waterloo 6809 ROMs and character generator ([0dce200](https://github.com/elektronaut/badline/commit/0dce200feb2b7a9356d781d906d57b951ba274a0))
20
+ * follow Banks' silicon notes for the 6809's undocumented opcodes ([cc7e842](https://github.com/elektronaut/badline/commit/cc7e842148c5c285161e7b6ac66abcb739469d86))
21
+ * interlace the 6560 with $9000 bit 7 ([7286f96](https://github.com/elektronaut/badline/commit/7286f96e50752416a6b1b06e64a4455e11cba50e))
22
+ * load KIM-1 papertapes and binaries, with 5K or expanded RAM ([0e48f42](https://github.com/elektronaut/badline/commit/0e48f42acf71a27a0b4092e952ad14cb5c0630a3))
23
+ * load the Waterloo languages in the SuperPET's 6809 mode, through traps on its IEEE-488 routines ([59abf2e](https://github.com/elektronaut/badline/commit/59abf2e95a144d31b7f30396111cff35323bfc5f))
24
+ * pick the PET's and the CBM-II's drive type on the pause menu's drive page ([bc3bb16](https://github.com/elektronaut/badline/commit/bc3bb16be4fe260bbf2828e513fa139e2b3b19e4))
25
+ * play, record and stop the KIM-1's cassette on the pause menu's tape page ([048d1c4](https://github.com/elektronaut/badline/commit/048d1c487042b4df7c9fdcd50154c4faa4bb8ca9))
26
+ * plug the PET's and CBM-II's IEEE-488 drives in by model, with --drive-type ([a3992be](https://github.com/elektronaut/badline/commit/a3992be4839eaef5f03dbef30b60cdd12c49d8cb))
27
+ * put a SuperPET's true-drive disk in drive 1, where the Waterloo menu loads from ([9ff4ea5](https://github.com/elektronaut/badline/commit/9ff4ea55a80cc59db23b9e075a85ac11326dc349))
28
+ * read and format D9060 and D9090 hard disk images ([59479ac](https://github.com/elektronaut/badline/commit/59479ac5a4302cb11c2189b553aa4a323227f711))
29
+ * read and write KIM-1 cassettes as .wav, and play and record them on U2's PB7 ([8041b2c](https://github.com/elektronaut/badline/commit/8041b2cf8a971bec4a7a365134cc92a7f05fc840))
30
+ * run an NTSC VIC-20 with the 6560 as badline vic20 --ntsc ([181b047](https://github.com/elektronaut/badline/commit/181b0477a75e7da359741340bdc71d08576e2176))
31
+ * run the D9060 and D9090 hard disks as true drives on the IEEE-488 bus ([291775a](https://github.com/elektronaut/badline/commit/291775aaf3ce09e8dc0031a13d3503af603818a4))
32
+ * run the KIM-1 headless, with its keypad, display and single step ([0a01647](https://github.com/elektronaut/badline/commit/0a0164719e672e7f42cac842557baf2aafc2ffd3))
33
+ * run the KIM-1 in the window, with its LEDs, keypad, panel page and sound ([df84ba3](https://github.com/elektronaut/badline/commit/df84ba3a6befdfd6e71cb326da74c55aa85b7303))
34
+ * run the KIM-1's monitor on a teletype, in the window or the terminal ([2dd101d](https://github.com/elektronaut/badline/commit/2dd101d329d034c80167154ccc55a27894536ac9))
35
+ * run the SuperPET's board in 6502 mode, with its bank RAM, latches, ACIA and 6702 ([ac0c02f](https://github.com/elektronaut/badline/commit/ac0c02f9853a9cf8807357180f0e45da3454c5e9))
36
+ * save and load the 4040, 3040, 2040, D9060 and D9090 in xpet's snapshot modules ([a5655e4](https://github.com/elektronaut/badline/commit/a5655e4c63e4e3b1952f6fcddf45b1969783aff1))
37
+ * save and load the SuperPET in snapshots, and in xpet's modules ([0dd847e](https://github.com/elektronaut/badline/commit/0dd847e781b94e8ad17b1279d1b763fcdd4152a3))
38
+ * save and restore KIM-1 snapshots ([b30d8bc](https://github.com/elektronaut/badline/commit/b30d8bc864e8529f384e43b06b2d9a5d64b1a106))
39
+ * save the KIM-1's tape deck in its snapshots ([013670c](https://github.com/elektronaut/badline/commit/013670cdfd6ff7910aa1d46fcafc3839bd2ae1b7))
40
+ * set the SuperPET's switches in the window and with --bank-ram, and type APL by key position ([19013b8](https://github.com/elektronaut/badline/commit/19013b827076fabaf72ff8df6fadd2252ce926bd))
41
+
42
+
43
+ ### Bug Fixes
44
+
45
+ * keep text typed before the boot in a snapshot ([b648c62](https://github.com/elektronaut/badline/commit/b648c62236c107f57475b6a0feb0688c3bb85daf))
46
+
47
+
48
+ ### Performance Improvements
49
+
50
+ * write a disk image's sectors byte by byte ([b2aa0be](https://github.com/elektronaut/badline/commit/b2aa0beae003b42c36ff4853fccb85facad44311))
51
+
3
52
  ## [0.17.0](https://github.com/elektronaut/badline/compare/v0.16.1...v0.17.0) (2026-10-19)
4
53
 
54
+ ### Highlights
55
+
56
+ - **CBM-II**: `badline cbm2` runs the B series' 610, 620, 710 and 720, with the 6509 and its segment bus, BASIC 128 or 256, the 6845 CRTC on 80 columns, the SID, both 6525 TPIs and cartridges. `--kernal 04a` or `03b` picks the KERNAL, and `--60hz` runs it on 60 Hz mains.
57
+ - **P500**: `badline cbm2 --model 510`, or `510ntsc`, runs the CBM 510, with a VIC-II for 40 columns in colour, two joysticks, and a 1351 mouse or paddles on either port.
58
+ - **8050 and 8250**: the dual drives run DOS 2.7 on both their processors and read and write `.d80` and `.d82` images. `--true-drive` puts one on the PET's or the CBM-II's IEEE-488 bus for a `.d80` or `.d82`, and the CBM-II takes a true 2031 too.
59
+ - **VICE snapshots**: badline reads and writes xcbm2's and xcbm5x0's `.vsf` files, and a PET's 8050 or 8250 in xpet's. `--vice` adds VICE's modules to a CBM-II snapshot, so xcbm2 or xcbm5x0 opens it.
60
+
5
61
 
6
62
  ### Features
7
63
 
@@ -78,6 +134,13 @@
78
134
 
79
135
  ## [0.16.0](https://github.com/elektronaut/badline/compare/v0.15.1...v0.16.0) (2026-10-17)
80
136
 
137
+ ### Highlights
138
+
139
+ - **PET and CBM**: `badline pet` runs the 2001, 3032, 3032b, 4032, 8032 and 8096, with the discrete 40-column video or the 6545 CRTC on 40 and 80 columns, the CRTC counted to the cycle, the graphics and business keyboards, and the sound on the VIA's CB2. The 8032 is the default.
140
+ - **Upgrade ROMs**: `--basic` fits BASIC 1, 2 or 4 and `--editor` an editor the board takes, `--60hz` runs a CRTC PET's 60 Hz editor, and `--ram` fits 4K to 32K.
141
+ - **Media**: programs and disks go on device 8 through traps on the IEEE-488 bus, with the 8050's and 8250's `.d80` and `.d82` images read and written, and tapes play and record on both cassette ports.
142
+ - **Snapshots**: `F11` and the Snapshots page save and restore the PET in keyed snapshots.
143
+
81
144
 
82
145
  ### Features
83
146
 
@@ -180,6 +243,12 @@
180
243
 
181
244
  ## [0.15.0](https://github.com/elektronaut/badline/compare/v0.14.0...v0.15.0) (2026-10-12)
182
245
 
246
+ ### Highlights
247
+
248
+ - **Plus/4, C16 and C116**: `badline plus4` runs them in the window, with the TED's picture and sound, BASIC 3.5, the Plus/4's 3-plus-1 function ROMs and both joysticks. `--model` picks `plus4`, `c16`, `c116`, `plus4ntsc` or `c16ntsc`, and `--ram` fits 16K, 32K or 64K.
249
+ - **Media**: programs load and run, tapes play and record on the datasette, disks go through the KERNAL traps or a true 1541 or 1581 on the serial bus, and cartridges go in both slots, from a `.crt` or a raw `.bin` (`--c1lo`, `--c1hi`, `--c2lo` and `--c2hi`).
250
+ - **Snapshots**: `F11` and the Snapshots page save the Plus/4 and the C16, and snapshots now hold the cartridge mappers' registers and the extra SIDs.
251
+
183
252
 
184
253
  ### Features
185
254
 
@@ -203,6 +272,12 @@
203
272
 
204
273
  ## [0.14.0](https://github.com/elektronaut/badline/compare/v0.13.0...v0.14.0) (2026-10-11)
205
274
 
275
+ ### Highlights
276
+
277
+ - **Snapshots that keep loading**: snapshots hold the machine as keyed `BL-*` modules, so one saved by 0.14.0 loads in every later version. Snapshots from earlier versions are refused with a message.
278
+ - **VICE export**: VICE's own modules go in only on export, with `--save-snapshot FILE --vice`, so x64sc opens the file too.
279
+ - **Plus/4 and C16, headless**: the 264 series boots to READY headless with its ROMs bundled, reads Plus/4 `.crt` images and version 2 C16 tapes, and runs VICE's 264 testbench rows (`testbench-plus4`, `testbench-c16`) and the Lorenz suite's plus4 build (`lorenz-plus4`).
280
+
206
281
 
207
282
  ### Features
208
283
 
@@ -252,6 +327,11 @@
252
327
 
253
328
  ## [0.13.0](https://github.com/elektronaut/badline/compare/v0.12.1...v0.13.0) (2026-10-11)
254
329
 
330
+ ### Highlights
331
+
332
+ - **Library layout**: `lib/badline/` is regrouped by namespace, and each constant follows its directory. `Badline::Computer` is now `Badline::C64`, and the chips, drives and input devices sit under `Badline::Chips`, `Badline::Drives` and `Badline::Input`. The move leaves emulation as it was.
333
+ - **`peek` and `poke`**: each machine reads and writes memory as its CPU sees it.
334
+
255
335
 
256
336
  ### Features
257
337
 
@@ -277,6 +357,12 @@
277
357
 
278
358
  ## [0.12.0](https://github.com/elektronaut/badline/compare/v0.11.1...v0.12.0) (2026-10-10)
279
359
 
360
+ ### Highlights
361
+
362
+ - **CP/M**: the C128's Z80 sits on its bus and starts the machine, as on a real C128. `badline c128 cpm3.d81` boots CP/M Plus to `A>`, and ZEXDOC and ZEXALL pass every test under it.
363
+ - **Boot disks**: a C128 boot disk, such as CP/M's system disks or a boot game, boots in C128 mode at power-on.
364
+ - **1581**: the 3.5" drive runs its own DOS on its WD1772 and reads and writes `.d81` images, on the C64, the VIC-20 and the C128 (`--true-drive` with a `.d81`).
365
+
280
366
 
281
367
  ### Features
282
368
 
@@ -303,6 +389,12 @@
303
389
 
304
390
  ## [0.11.0](https://github.com/elektronaut/badline/compare/v0.10.1...v0.11.0) (2026-10-09)
305
391
 
392
+ ### Highlights
393
+
394
+ - **C128**: `badline c128` runs a C128 in C128 mode with BASIC 7.0, through its own 8722 MMU and KERNAL, on the 8502 with its 2 MHz FAST mode and 128K of RAM, in both builds. `--model` picks `c128`, `c128dcr`, `c128ntsc` or `c128dcrntsc`. Device 8 goes through the KERNAL traps, and `F11` and `F12` save and load it in badline's own snapshots.
395
+ - **80 columns**: the VDC draws its 80-column display, and the window follows the C128 between its 40 and 80 column screens. `F6` is the 40/80 DISPLAY key, and `F8` switches the window to the other screen.
396
+ - **C64 mode**: `--c64` holds `C=` through the reset to start C64 mode, as a program that loads at `$0801`, a `.sid` tune or a C64 cartridge does, and `GO64` gets there from BASIC 7.0.
397
+
306
398
 
307
399
  ### Features
308
400
 
@@ -336,6 +428,13 @@
336
428
 
337
429
  ## [0.10.0](https://github.com/elektronaut/badline/compare/v0.9.0...v0.10.0) (2026-10-08)
338
430
 
431
+ ### Highlights
432
+
433
+ - **VIC-20**: `badline vic20` runs a PAL VIC-20 in the window, in both builds, with the 6561 VIC-I's picture and sound, both VIAs, the keyboard, the joystick and RESTORE. All 72 rows of `testbench-vic20` pass.
434
+ - **Media**: programs, disks, tapes and cartridges load as on the C64, with device 8 through the KERNAL traps or a true 1541 (`--true-drive`). Without `--ram`, the VIC-20 gets the RAM expansion its media needs, up to 35K.
435
+ - **Snapshots**: `F11`, `F12` and the pause menu save and load the VIC-20 in badline's own snapshots.
436
+ - **Machine families**: the first argument can name the machine, as in `badline c64 game.prg` or `badline vic20 game.prg`.
437
+
339
438
 
340
439
  ### Features
341
440
 
@@ -365,6 +464,13 @@
365
464
 
366
465
  ## [0.9.0](https://github.com/elektronaut/badline/compare/v0.8.0...v0.9.0) (2026-10-05)
367
466
 
467
+ ### Highlights
468
+
469
+ - **Quicksaves and autosave**: `F11` quicksaves to the next of five slots in badline's data folder, and `F12` restores the newest, even after badline has quit and started again. badline autosaves every two minutes of play, and the pause menu's Snapshots page saves under a name and loads any save.
470
+ - **Self-contained snapshots**: a snapshot restores without its tape, `.t64` or true drive disk files, and NTSC, Drean and REU machines save as `.vsf` too.
471
+ - **`--model`**: picks the C64 to run, named as in VICE: `c64`, `c64c`, `ntsc`, `newntsc` and `oldntsc`, and the new `drean`, the Drean C64, PAL-N with the 6572, and `sx64`, the SX-64.
472
+ - **Disk lists**: `.m3u` playlists and VICE `.vfl` flip lists give a disk set for the pause menu.
473
+
368
474
 
369
475
  ### Features
370
476
 
@@ -394,6 +500,13 @@
394
500
 
395
501
  ## [0.8.0](https://github.com/elektronaut/badline/compare/v0.7.0...v0.8.0) (2026-10-03)
396
502
 
503
+ ### Highlights
504
+
505
+ - **Pause menu**: `F9` pauses the machine and opens a menu with a page for each part of the hardware: Drive 8, Datasette, Expansion port, with the cartridge's freeze button, Ports, Sound and Power. INSERT opens a file browser, and Quick open starts a file in a new machine as the command line does.
506
+ - **Disk sets**: the Drive 8 page steps to the previous or next disk of a set, found by the names in the disk's folder, such as `Disk 1`, `Side B` or TOSEC's `(Disk 1 of 2)`.
507
+ - **Drag and drop**: a disk or tape dropped on the window goes into its drive, and a dropped cartridge, program or `.sid` asks first.
508
+ - **Write-protected by default**: disks go in write-protected, and `--writable`, or WRITABLE on the Drive 8 page, lets the machine write to the image.
509
+
397
510
 
398
511
  ### ⚠ BREAKING CHANGES
399
512
 
@@ -413,6 +526,13 @@
413
526
 
414
527
  ## [0.7.0](https://github.com/elektronaut/badline/compare/v0.6.1...v0.7.0) (2026-10-02)
415
528
 
529
+ ### Highlights
530
+
531
+ - **SID player**: `badline sid FILE|DIR...` plays a queue of tunes in a window worked with the mouse, and `badline tune.sid` opens it too. Its visualizer shows each voice's note and output, its SID view the registers, envelopes and filter, and its INFO view the tune's entry in HVSC's STIL.
532
+ - **Queue and subtunes**: shuffle, looping and playing all subtunes, seeking within a subtune from the bar or with `,` and `.`, and `.sid` files and folders dropped on the window join the queue. A subtune with no known length ends when it falls silent.
533
+ - **2SID and 3SID**: a tune written for two or three SIDs plays on as many, in stereo.
534
+ - **Chip swap**: the 6581 and the 8580 swap while a tune plays.
535
+
416
536
 
417
537
  ### ⚠ BREAKING CHANGES
418
538
 
@@ -490,6 +610,11 @@
490
610
 
491
611
  ## [0.6.0](https://github.com/elektronaut/badline/compare/v0.5.1...v0.6.0) (2026-09-29)
492
612
 
613
+ ### Highlights
614
+
615
+ - **Snapshots**: `F11` saves the whole machine to a `.vsf` snapshot in the working directory, and `F12` goes back to the one last saved or opened, in both executables. A snapshot holds the machine as it was on the cycle it was saved, with its RAM, expansions, cartridge, a true 1541 and the tape.
616
+ - **VICE's format**: badline opens snapshots VICE's x64sc saved, as in `badline game.vsf`, and x64sc 3.10 opens badline's.
617
+
493
618
 
494
619
  ### Features
495
620
 
@@ -514,6 +639,13 @@
514
639
 
515
640
  ## [0.5.0](https://github.com/elektronaut/badline/compare/v0.4.2...v0.5.0) (2026-09-29)
516
641
 
642
+ ### Highlights
643
+
644
+ - **True 1541**: `--true-drive` puts an emulated 1541 on device 8, running its own DOS ROM on its own 6502 and talking to the C64 over the serial bus. It reads `.d64` disks through its GCR mechanism, writes and formats them, and skips its cycles while it idles.
645
+ - **`.g64` images**: a `.g64` holds a disk's raw GCR, so copy protection and fast loaders that read it work. It goes in a true 1541.
646
+ - **REU**: `--reu SIZE` plugs in a 1700, 1764 or 1750, or a bigger unit up to 16M, with DMA timed against the VIC's bad lines and sprites.
647
+ - **NTSC**: `--ntsc` runs an NTSC C64, with the 6567R8 VIC-II.
648
+
517
649
 
518
650
  ### Features
519
651
 
@@ -556,6 +688,13 @@
556
688
 
557
689
  ## [0.4.0](https://github.com/elektronaut/badline/compare/v0.3.0...v0.4.0) (2026-09-28)
558
690
 
691
+ ### Highlights
692
+
693
+ - **Native `badline`**: compiled ahead of time with Spinel, it installs with `brew install elektronaut/tap/badline` on macOS, takes `badline-ruby`'s options and plays sound by default. Its window reads game controllers, the mouse and paddles, and paces itself by vsync.
694
+ - **`badline-ruby`**: the gem's executable is renamed, and takes over from `badline-sid`: `--headless tune.sid` plays a tune and `--audio-out out.wav` renders one.
695
+ - **Writable disks**: the virtual drive writes `SAVE`s, files and blocks back to the disk image, `--read-only` mounts one write-protected, and `Badline::Media.insert_disk` swaps the disk while the machine runs.
696
+ - **More hardware**: GEO-RAM, the +60K and +256K RAM expansions, and the C64C's 8565 VIC-II and 6526A CIA, chosen from Ruby.
697
+
559
698
  ### Upgrading
560
699
 
561
700
  * 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.
@@ -614,6 +753,12 @@
614
753
 
615
754
  ## [0.3.0](https://github.com/elektronaut/badline/compare/v0.2.1...v0.3.0) (2026-09-24)
616
755
 
756
+ ### Highlights
757
+
758
+ - **Sound in the window**: `badline --sound` plays the SID in the emulator window and paces emulation to the audio device. It is off by default.
759
+ - **A virtual drive closer to the 1541**: buffer channels live in the drive's RAM, DOS command parameters are read as the 1541 reads them, the BAM goes in buffer 4 when a disk initializes, `LOAD"*"` reopens the last file loaded, and host SAVE and read failures show on the error channel.
760
+ - **Other ROMs**: `BADLINE_ROM_PATH`, or `Badline.rom_path` from Ruby, loads the KERNAL, BASIC and character ROMs from a directory.
761
+
617
762
  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.
618
763
 
619
764
 
@@ -681,6 +826,14 @@ Sound is the headline: `badline --sound` plays the SID in the emulator window an
681
826
 
682
827
  ## [0.2.0](https://github.com/elektronaut/badline/compare/v0.1.0...v0.2.0) (2026-09-23)
683
828
 
829
+ ### Highlights
830
+
831
+ - **VIC-II**: the border, the bad-line DMA delay, idle graphics, the light pen and sprites run cycle by cycle, with the sprite registers replayed through a per-pixel sequencer.
832
+ - **CPU and CIAs**: the 6510 polls interrupts every cycle and makes the dummy reads of its internal cycles, and the CIAs model the CNT pin, the serial port and the TOD clock. Wolfgang Lorenz's test suite passes from start to finish.
833
+ - **SID**: the 6581 and the 8580, with the board's RC filter and combined waveforms fitted against real-chip dumps. `badline-sid` plays `.sid` tunes live and renders them to WAV or AIFF, taking the length from HVSC's song lengths.
834
+ - **Cartridges**: EasyFlash, Epyx FastLoad, Pagefox, Simons' BASIC, the Action Replay, Retro Replay and Final Cartridge III freezers, the KCS Power Cartridge and more bank-switching mappers.
835
+ - **Media and input**: `.tap` tapes play through the datasette, `.t64` archives load by name, and device 8 is served by trapping the KERNAL's serial bus primitives. Paddles and a 1351 mouse plug into either control port, and host gamepads drive the joysticks.
836
+
684
837
 
685
838
  ### Features
686
839
 
data/CLAUDE.md CHANGED
@@ -70,10 +70,13 @@ file: `core.rb` requires their members one by one.
70
70
  | rspec (`spec/`) | `bundle exec rspec` | Unit behaviour, all of `lib/` |
71
71
  | SingleStepTests 65x02 | `rake test` (100 sampled cases per opcode) | CPU, per-cycle bus traces |
72
72
  | SingleStepTests z80 | `rake test` (the first 100 cases per opcode, `Z80_SAMPLE=all` for all 1,604,000) | `Z80`: registers, flags, ports and the bus pins on every T-state |
73
+ | neetandev/m6809 vectors | `rake test` (the first 100 cases per opcode, `M6809_SAMPLE=all` for all 315,000) | `M6809`: registers, RAM and the bus on every cycle, with the dead cycles and undocumented opcodes `test/support/m6809_divergences.rb` moves to the MC6809E datasheet and Banks' notes |
74
+ | 6809 code tester | `rake test` | `M6809`: reyco2000's functional, interrupt (IRQ, FIRQ, NMI, SYNC, CWAI) and cycle-count programs on a bare 6809 |
73
75
  | Wolfgang Lorenz suite | `bin/lorenz` | CPU, CIA, interrupts; its plus4 build with `--plus4`: the CPU on the 264's bus, the TED's clock, DMA, timers and interrupt |
74
- | VICE testbench | `bin/testbench <subtree>` | `VICII/`, `CIA/`, `interrupts/`, `CPU/`, cartridges with `--carts`, the true 1541 drive with `--drive`, the VIC-20 with `--vic20`, the C128 in C64 mode with `--c128c64`, in C128 mode with `--c128`, and its Z80 with `--c128-z80`, the Plus/4 with `--plus4`, the C16 with `--c16`, and the PET with `--pet` (8096) and `--pet-discrete` (2001, 3032) |
76
+ | VICE testbench | `bin/testbench <subtree>` | `VICII/`, `CIA/`, `interrupts/`, `CPU/`, cartridges with `--carts`, the true 1541 drive with `--drive`, the VIC-20 with `--vic20` (NTSC with `--ntsc`), the C128 in C64 mode with `--c128c64`, in C128 mode with `--c128`, and its Z80 with `--c128-z80`, the Plus/4 with `--plus4`, the C16 with `--c16`, and the PET with `--pet` (8096) and `--pet-discrete` (2001, 3032) |
75
77
  | VICE SID testprogs | `bin/sidtests` | SID |
76
78
  | Drive scenarios | `bin/drive_scenarios` | The true 1541 running the DOS ROM: save, format, the error channel, idle, write protect and autostart; the `plus4-*` rows on the Plus/4 and C16, with the 1541 and 1581 on their serial bus and a tape saved and loaded back on the datasette |
79
+ | KIM-1 scenarios | `bin/drive_scenarios kim1` | The KIM-1's monitor: keys and the display, SST, ST, the teletype at 9600 and 110 baud, a papertape through `L`, a program loaded and started, and U3's timer interrupting through IRQ |
77
80
  | CIA offline grids | `bundle exec rspec --tag slow spec/badline/chips/cia` | CIA timers and shift register, against a bare CIA in about 2 min |
78
81
 
79
82
  The CIA offline grids replay Lorenz's `cia1ta` and `cia1tb` sweeps (about
@@ -133,7 +136,7 @@ worktree and owns a different set of files.
133
136
  - The external suites under `vendor/` are gitignored, so a new worktree has
134
137
  only `vendor/.gitkeep`. From the worktree root, symlink the main
135
138
  checkout's suites into it:
136
- `for d in 65x02 z80-sample VICE-testprogs; do ln -sfn ../../../../vendor/$d vendor/$d; done`.
139
+ `for d in 65x02 z80-sample m6809 m6809-code-tester VICE-testprogs; do ln -sfn ../../../../vendor/$d vendor/$d; done`.
137
140
  The main checkout also has `vendor/OneLoad64-Games-Collection-v5`, which
138
141
  `rake vendor:checkout` doesn't fetch. Link it the same way only for
139
142
  `.sid` or media work. Don't re-run `rake vendor:checkout` there, and
@@ -159,8 +162,8 @@ worktree and owns a different set of files.
159
162
 
160
163
  ## Testing and baselines
161
164
 
162
- - `rake vendor:checkout` fetches SingleStepTests 65x02, the Z80 sample
163
- and VICE-testprogs into `vendor/`
165
+ - `rake vendor:checkout` fetches SingleStepTests 65x02, the Z80 sample,
166
+ the 6809 vectors and test programs, and VICE-testprogs into `vendor/`
164
167
  - `bundle exec rspec`: line coverage is about 95%. `spec/spec_helper.rb`
165
168
  fails a whole-suite run (every spec file, no filters) below 90%, while
166
169
  single-file and filtered runs skip the floor. `:slow` specs are excluded
@@ -191,7 +194,7 @@ overrides that, capped by the core count, but keep the default, because
191
194
  other worktrees share the machine. Whole runs at 4 shards on an M-series
192
195
  laptop take 15 min for `testbench` (`VICII/`), 11 for `testbench-cia`, 1 for
193
196
  `testbench-interrupts`, 37 for `testbench-irqdma`, 11 for
194
- `testbench-cpu`, 2 for `testbench-carts`, about 25 for `testbench-expansions`, under 1 for `testbench-vic20`, `testbench-plus4`, `testbench-c16` and `testbench-plus4-ntsc`, and about 30 for `testbench-c128c64`. `lorenz-plus4` takes about 21 min whole on the Spinel build. `rake regression:lorenz-plus4-1` to `lorenz-plus4-4` run it as four stretches, cut where `lorenz` is, and the last, through the trap tests the chain resumes past, is about half of it. `sid` takes about 12 min. `lorenz` chains itself and takes
197
+ `testbench-cpu`, 2 for `testbench-carts`, about 25 for `testbench-expansions`, under 1 for `testbench-vic20`, `testbench-vic20-ntsc`, `testbench-plus4`, `testbench-c16` and `testbench-plus4-ntsc`, and about 30 for `testbench-c128c64`. `lorenz-plus4` takes about 21 min whole on the Spinel build. `rake regression:lorenz-plus4-1` to `lorenz-plus4-4` run it as four stretches, cut where `lorenz` is, and the last, through the trap tests the chain resumes past, is about half of it. `sid` takes about 12 min. `lorenz` chains itself and takes
195
198
  about 2.5 h on CI whole. `rake regression:lorenz-1` to `lorenz-4` run it as
196
199
  four stretches of about 40 min each, and they can run side by side.
197
200
  `test/baselines/README.md` has the full table. A killed `bin/testbench` run
@@ -263,7 +266,8 @@ the 6526A) for anything the interrupt register or the CIA model reaches; cartrid
263
266
  `testbench-carts`, plus `testbench-expansions` for banking; GEO-RAM, +60K,
264
267
  +256K, the REU or the VIC's BA line the REU follows → `testbench-expansions`; the 1541 drive, VIA or IEC bus →
265
268
  `testbench-drive` (`bin/testbench --drive`) and `drive-scenarios` (`bin/drive_scenarios <filter>`), plus `testbench-vic20` for the VIA; the VIC-20 (`vic20/`) →
266
- `testbench-vic20` (`bin/testbench --vic20`); the 264 series (`plus4.rb`,
269
+ `testbench-vic20` (`bin/testbench --vic20`) and `testbench-vic20-ntsc`
270
+ (`bin/testbench --vic20 --ntsc`); the 264 series (`plus4.rb`,
267
271
  `plus4/`), the TED (`chips/ted.rb`, `chips/ted/`) or the TIA (`chips/tia.rb`)
268
272
  → `testbench-plus4` (`bin/testbench --plus4`) and `testbench-c16`
269
273
  (`bin/testbench --c16`), plus `testbench-plus4-ntsc`
@@ -275,7 +279,7 @@ serial bus, its media, the CPU port or the datasette.
275
279
  Its tests run one at a time as the C64's do, with
276
280
  `ruby --yjit bin/lorenz --plus4 --resume <test> --stop-after <test>`; the C128 (`c128.rb`, `c128/`), or
277
281
  the VIC-IIe, CPU or PLA code it shares with the C64 → `testbench-c128c64`
278
- (`bin/testbench --c128c64`); the PET (`pet.rb`, `pet/`), its 6520 PIA (`chips/pia.rb`) or its CRTC (`chips/crtc.rb`) → `testbench-pet` (`bin/testbench --pet`) and `testbench-pet-discrete` (`bin/testbench --pet-discrete`), plus `testbench-cbm2` for the CRTC; the CBM-II (`cbm2.rb`, `cbm2/`), its 6525 TPI (`chips/tpi.rb`) or the CIA, SID and ACIA it shares → `testbench-cbm2` (`bin/testbench --cbm2`), plus `testbench-cbm5x0` (`bin/testbench --cbm5x0`); the P500 (`cbm2/p500.rb`, `cbm2/p500/`) → `testbench-cbm5x0`, which the VIC (`chips/vic*`) reaches too; the C128's Z80, MMU or hand-over → `testbench-c128-z80` (`bin/testbench --c128-z80`) and `testbench-c128`; SID → `sid`, plus `sid-8580` for anything the 8580
282
+ (`bin/testbench --c128c64`); the PET (`pet.rb`, `pet/`), its 6520 PIA (`chips/pia.rb`) or its CRTC (`chips/crtc.rb`) → `testbench-pet` (`bin/testbench --pet`) and `testbench-pet-discrete` (`bin/testbench --pet-discrete`), plus `testbench-cbm2` for the CRTC; the CBM-II (`cbm2.rb`, `cbm2/`), its 6525 TPI (`chips/tpi.rb`) or the CIA, SID and ACIA it shares → `testbench-cbm2` (`bin/testbench --cbm2`), plus `testbench-cbm5x0` (`bin/testbench --cbm5x0`); the P500 (`cbm2/p500.rb`, `cbm2/p500/`) → `testbench-cbm5x0`, which the VIC (`chips/vic*`) reaches too; the C128's Z80, MMU or hand-over → `testbench-c128-z80` (`bin/testbench --c128-z80`) and `testbench-c128`; the KIM-1 (`kim1.rb`, `kim1/`), its media or the 6530 (`chips/rriot.rb`) → `kim1-scenarios` (`bin/drive_scenarios kim1`); SID → `sid`, plus `sid-8580` for anything the 8580
279
283
  model reaches (`bin/sidtests --sid 8580`). Leave the Lorenz chain to CI,
280
284
  unless your code has a rule in `doc/pinned-behaviour.md` that names Lorenz
281
285
  tests: the interrupt polling, CPU port and CIA timer rules. Run just the
data/CONTRIBUTING.md CHANGED
@@ -75,11 +75,17 @@ the Z80 against the [Z80 ones](https://github.com/SingleStepTests/z80).
75
75
  which takes a moment the first time. For the Z80 it fetches only the
76
76
  first 100 cases of each opcode's file into `vendor/z80-sample`.
77
77
  `Z80_SAMPLE=all` checks the whole Z80 suite out into `vendor/z80`
78
- (about 1.5 GB) and runs every case:
78
+ (about 1.5 GB) and runs every case. The 6809 is verified against
79
+ [neetandev/m6809](https://github.com/neetandev/m6809)'s vectors, which
80
+ `rake test` fetches into `vendor/m6809` (24 MB). It runs the first 100
81
+ cases of each opcode's file, or every case with `M6809_SAMPLE=all`, and
82
+ also runs [reyco2000's 6809 test programs](https://github.com/reyco2000/6809_6309_code_tester),
83
+ fetched into `vendor/m6809-code-tester`:
79
84
 
80
85
  ```sh
81
86
  bundle exec rake test
82
87
  Z80_SAMPLE=all bundle exec rake test
88
+ M6809_SAMPLE=all bundle exec rake test
83
89
  ```
84
90
 
85
91
  Check style before pushing: