badline 0.12.1 → 0.13.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 (505) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -0
  3. data/CLAUDE.md +59 -31
  4. data/README.md +1 -1
  5. data/doc/library.md +9 -9
  6. data/doc/pinned-behaviour.md +105 -105
  7. data/doc/snapshots.md +1 -4
  8. data/lib/badline/audio/bare_player.rb +3 -3
  9. data/lib/badline/audio/cli.rb +6 -6
  10. data/lib/badline/audio/jukebox.rb +2 -2
  11. data/lib/badline/audio/machine_player.rb +2 -2
  12. data/lib/badline/{media → audio}/queue.rb +1 -1
  13. data/lib/badline/audio/queued_tune.rb +6 -6
  14. data/lib/badline/audio/renderer.rb +5 -5
  15. data/lib/badline/audio/stereo.rb +1 -1
  16. data/lib/badline/c128/{bus_state.rb → bus/saved_state.rb} +1 -1
  17. data/lib/badline/c128/bus.rb +18 -17
  18. data/lib/badline/c128/color_lines.rb +2 -2
  19. data/lib/badline/c128/cpu.rb +1 -1
  20. data/lib/badline/c128/drives.rb +10 -11
  21. data/lib/badline/c128/fast_serial.rb +5 -5
  22. data/lib/badline/c128/mmu_pages.rb +1 -1
  23. data/lib/badline/c128/modes.rb +2 -2
  24. data/lib/badline/c128/saved_state.rb +21 -47
  25. data/lib/badline/c128/z80.rb +2 -2
  26. data/lib/badline/c128.rb +14 -9
  27. data/lib/badline/{computer → c64}/attachments.rb +4 -6
  28. data/lib/badline/c64/banked_ram/banking.rb +32 -0
  29. data/lib/badline/c64/banked_ram/plus256k.rb +56 -0
  30. data/lib/badline/c64/banked_ram/plus60k.rb +45 -0
  31. data/lib/badline/c64/banked_ram/unexpanded.rb +30 -0
  32. data/lib/badline/c64/banked_ram.rb +23 -0
  33. data/lib/badline/c64/bus/extra_sids.rb +32 -0
  34. data/lib/badline/c64/bus/fittings.rb +40 -0
  35. data/lib/badline/c64/bus/pla.rb +149 -0
  36. data/lib/badline/c64/bus/roms.rb +41 -0
  37. data/lib/badline/c64/bus/saved_state.rb +68 -0
  38. data/lib/badline/c64/bus/sid_slots.rb +44 -0
  39. data/lib/badline/c64/bus.rb +218 -0
  40. data/lib/badline/c64/cartridge/action_replay.rb +128 -0
  41. data/lib/badline/c64/cartridge/atomic_power.rb +26 -0
  42. data/lib/badline/c64/cartridge/bank.rb +83 -0
  43. data/lib/badline/c64/cartridge/comal80.rb +52 -0
  44. data/lib/badline/c64/cartridge/dinamic.rb +36 -0
  45. data/lib/badline/c64/cartridge/easy_flash.rb +147 -0
  46. data/lib/badline/c64/cartridge/epyx_fastload.rb +81 -0
  47. data/lib/badline/c64/cartridge/final_cartridge3.rb +91 -0
  48. data/lib/badline/c64/cartridge/flash/saved_state.rb +40 -0
  49. data/lib/badline/c64/cartridge/flash.rb +279 -0
  50. data/lib/badline/c64/cartridge/freezer.rb +35 -0
  51. data/lib/badline/c64/cartridge/fun_play.rb +40 -0
  52. data/lib/badline/c64/cartridge/g_mod2.rb +76 -0
  53. data/lib/badline/c64/cartridge/game_system.rb +42 -0
  54. data/lib/badline/c64/cartridge/geo_ram.rb +81 -0
  55. data/lib/badline/c64/cartridge/kcs_power.rb +77 -0
  56. data/lib/badline/c64/cartridge/mach5.rb +34 -0
  57. data/lib/badline/c64/cartridge/magic_desk.rb +32 -0
  58. data/lib/badline/c64/cartridge/ocean.rb +37 -0
  59. data/lib/badline/c64/cartridge/pagefox.rb +70 -0
  60. data/lib/badline/c64/cartridge/retro_replay/saved_state.rb +47 -0
  61. data/lib/badline/c64/cartridge/retro_replay.rb +286 -0
  62. data/lib/badline/c64/cartridge/rex_utility.rb +31 -0
  63. data/lib/badline/c64/cartridge/rgcd.rb +60 -0
  64. data/lib/badline/c64/cartridge/saved_state.rb +63 -0
  65. data/lib/badline/c64/cartridge/simons_basic.rb +37 -0
  66. data/lib/badline/c64/cartridge/standard.rb +17 -0
  67. data/lib/badline/c64/cartridge/super_games.rb +50 -0
  68. data/lib/badline/c64/cartridge/westermann.rb +32 -0
  69. data/lib/badline/c64/cartridge/zaxxon.rb +68 -0
  70. data/lib/badline/c64/cartridge.rb +258 -0
  71. data/lib/badline/c64/color_memory.rb +27 -0
  72. data/lib/badline/{computer → c64}/common.rb +2 -2
  73. data/lib/badline/{computer → c64}/kernal_traps.rb +18 -18
  74. data/lib/badline/c64/reu/dma/saved_state.rb +52 -0
  75. data/lib/badline/c64/reu/dma.rb +275 -0
  76. data/lib/badline/c64/reu/ram.rb +109 -0
  77. data/lib/badline/c64/reu/saved_state.rb +55 -0
  78. data/lib/badline/c64/reu/trigger.rb +34 -0
  79. data/lib/badline/c64/reu.rb +291 -0
  80. data/lib/badline/{computer → c64}/saved_state.rb +13 -18
  81. data/lib/badline/{computer → c64}/true_drives.rb +11 -11
  82. data/lib/badline/{computer.rb → c64.rb} +18 -13
  83. data/lib/badline/chips/cia/fast_forward.rb +62 -0
  84. data/lib/badline/chips/cia/interrupt_register.rb +145 -0
  85. data/lib/badline/chips/cia/saved_state.rb +49 -0
  86. data/lib/badline/chips/cia/serial/saved_state.rb +45 -0
  87. data/lib/badline/chips/cia/serial.rb +250 -0
  88. data/lib/badline/chips/cia/time_of_day.rb +232 -0
  89. data/lib/badline/chips/cia/timer.rb +208 -0
  90. data/lib/badline/chips/cia.rb +281 -0
  91. data/lib/badline/chips/cpu/addressing.rb +133 -0
  92. data/lib/badline/chips/cpu/boundary.rb +56 -0
  93. data/lib/badline/chips/cpu/core.rb +167 -0
  94. data/lib/badline/chips/cpu/instruction.rb +338 -0
  95. data/lib/badline/chips/cpu/instruction_set/arithmetic.rb +118 -0
  96. data/lib/badline/chips/cpu/instruction_set/bitwise.rb +130 -0
  97. data/lib/badline/chips/cpu/instruction_set/branch.rb +83 -0
  98. data/lib/badline/chips/cpu/instruction_set/flag.rb +67 -0
  99. data/lib/badline/chips/cpu/instruction_set/illegal.rb +274 -0
  100. data/lib/badline/chips/cpu/instruction_set/inc_dec.rb +73 -0
  101. data/lib/badline/chips/cpu/instruction_set/stack.rb +56 -0
  102. data/lib/badline/chips/cpu/instruction_set/transfer.rb +141 -0
  103. data/lib/badline/chips/cpu/instruction_set.rb +59 -0
  104. data/lib/badline/chips/cpu/interrupts.rb +108 -0
  105. data/lib/badline/chips/cpu/microcode.rb +179 -0
  106. data/lib/badline/chips/cpu/operations.rb +90 -0
  107. data/lib/badline/chips/cpu/port.rb +116 -0
  108. data/lib/badline/chips/cpu/saved_state.rb +117 -0
  109. data/lib/badline/chips/cpu/stack_operations.rb +84 -0
  110. data/lib/badline/chips/cpu/traps.rb +23 -0
  111. data/lib/badline/chips/cpu.rb +12 -0
  112. data/lib/badline/chips/sid/catch_up.rb +122 -0
  113. data/lib/badline/chips/sid/decimator.rb +66 -0
  114. data/lib/badline/chips/sid/envelope/saved_state.rb +70 -0
  115. data/lib/badline/chips/sid/envelope.rb +241 -0
  116. data/lib/badline/chips/sid/filter/saved_state.rb +42 -0
  117. data/lib/badline/chips/sid/filter.rb +241 -0
  118. data/lib/badline/chips/sid/saved_state.rb +52 -0
  119. data/lib/badline/chips/sid/voice.rb +79 -0
  120. data/lib/badline/chips/sid/waveform/combined.rb +128 -0
  121. data/lib/badline/chips/sid/waveform/fast_forward.rb +107 -0
  122. data/lib/badline/chips/sid/waveform/noise_writeback.rb +124 -0
  123. data/lib/badline/chips/sid/waveform/saved_state.rb +68 -0
  124. data/lib/badline/chips/sid/waveform.rb +307 -0
  125. data/lib/badline/chips/sid.rb +265 -0
  126. data/lib/badline/{c128 → chips}/vdc/memory.rb +1 -1
  127. data/lib/badline/{c128 → chips}/vdc/painter.rb +1 -1
  128. data/lib/badline/{c128 → chips}/vdc/raster.rb +1 -1
  129. data/lib/badline/chips/vdc/saved_state.rb +36 -0
  130. data/lib/badline/{c128 → chips}/vdc/window.rb +1 -1
  131. data/lib/badline/{c128 → chips}/vdc.rb +7 -31
  132. data/lib/badline/chips/via/control_lines.rb +124 -0
  133. data/lib/badline/chips/via/fast_forward.rb +55 -0
  134. data/lib/badline/chips/via/interrupt_register.rb +69 -0
  135. data/lib/badline/chips/via/saved_state.rb +44 -0
  136. data/lib/badline/chips/via/shift_register.rb +182 -0
  137. data/lib/badline/chips/via/timer1.rb +133 -0
  138. data/lib/badline/chips/via/timer2.rb +135 -0
  139. data/lib/badline/chips/via.rb +268 -0
  140. data/lib/badline/chips/vic/bank.rb +135 -0
  141. data/lib/badline/chips/vic/border_mask.rb +88 -0
  142. data/lib/badline/chips/vic/collisions.rb +117 -0
  143. data/lib/badline/chips/vic/color_patches.rb +49 -0
  144. data/lib/badline/chips/vic/display_state.rb +187 -0
  145. data/lib/badline/chips/vic/graphics_mode.rb +166 -0
  146. data/lib/badline/chips/vic/graphics_shifter/saved_state.rb +40 -0
  147. data/lib/badline/chips/vic/graphics_shifter.rb +187 -0
  148. data/lib/badline/chips/vic/register_log.rb +83 -0
  149. data/lib/badline/chips/vic/registers.rb +197 -0
  150. data/lib/badline/chips/vic/saved_state.rb +82 -0
  151. data/lib/badline/chips/vic/sequencer/saved_state.rb +91 -0
  152. data/lib/badline/chips/vic/sequencer.rb +277 -0
  153. data/lib/badline/chips/vic/sequencer_output.rb +118 -0
  154. data/lib/badline/chips/vic/sprite/internal_bus.rb +70 -0
  155. data/lib/badline/chips/vic/sprite/saved_state.rb +66 -0
  156. data/lib/badline/chips/vic/sprite/shifter.rb +148 -0
  157. data/lib/badline/chips/vic/sprite/timing.rb +58 -0
  158. data/lib/badline/chips/vic/sprite.rb +339 -0
  159. data/lib/badline/chips/vic/sprites/saved_state.rb +59 -0
  160. data/lib/badline/chips/vic/sprites.rb +284 -0
  161. data/lib/badline/chips/vic.rb +783 -0
  162. data/lib/badline/chips/vic_i/painter/saved_state.rb +40 -0
  163. data/lib/badline/{vic20/vic → chips/vic_i}/painter.rb +6 -30
  164. data/lib/badline/{vic20/vic → chips/vic_i}/saved_state.rb +2 -2
  165. data/lib/badline/chips/vic_i/sound/output.rb +85 -0
  166. data/lib/badline/chips/vic_i/sound.rb +235 -0
  167. data/lib/badline/{vic20/vic → chips/vic_i}/text_window.rb +2 -2
  168. data/lib/badline/{vic20/vic.rb → chips/vic_i.rb} +5 -5
  169. data/lib/badline/chips/z80/arithmetic.rb +119 -0
  170. data/lib/badline/chips/z80/bit_page.rb +57 -0
  171. data/lib/badline/chips/z80/block_io.rb +60 -0
  172. data/lib/badline/chips/z80/block_transfers.rb +61 -0
  173. data/lib/badline/chips/z80/bus_cycles.rb +113 -0
  174. data/lib/badline/chips/z80/core.rb +115 -0
  175. data/lib/badline/chips/z80/exchanges.rb +52 -0
  176. data/lib/badline/chips/z80/extended_page.rb +91 -0
  177. data/lib/badline/chips/z80/flags.rb +39 -0
  178. data/lib/badline/chips/z80/interrupt_acceptance.rb +48 -0
  179. data/lib/badline/chips/z80/jumps.rb +84 -0
  180. data/lib/badline/chips/z80/loads.rb +100 -0
  181. data/lib/badline/chips/z80/main_page.rb +136 -0
  182. data/lib/badline/chips/z80/registers.rb +122 -0
  183. data/lib/badline/chips/z80/saved_state.rb +71 -0
  184. data/lib/badline/chips/z80/shifts.rb +66 -0
  185. data/lib/badline/chips/z80.rb +13 -0
  186. data/lib/badline/core.rb +26 -28
  187. data/lib/badline/drives/datasette/saved_state.rb +37 -0
  188. data/lib/badline/drives/datasette.rb +140 -0
  189. data/lib/badline/drives/engine/core.rb +149 -0
  190. data/lib/badline/drives/engine/fast_serial.rb +75 -0
  191. data/lib/badline/drives/engine/idle.rb +127 -0
  192. data/lib/badline/drives/engine/idle_cpu.rb +30 -0
  193. data/lib/badline/drives/engine/orbit.rb +81 -0
  194. data/lib/badline/drives/engine/serial_lines.rb +75 -0
  195. data/lib/badline/drives/engine/sleep.rb +114 -0
  196. data/lib/badline/drives/engine/vias.rb +86 -0
  197. data/lib/badline/drives/engine/watch.rb +152 -0
  198. data/lib/badline/drives/engine.rb +11 -0
  199. data/lib/badline/drives/model1541/bus.rb +88 -0
  200. data/lib/badline/drives/model1541/byte_ready.rb +50 -0
  201. data/lib/badline/drives/model1541/cpu.rb +13 -0
  202. data/lib/badline/drives/model1541/disk/saved_state.rb +88 -0
  203. data/lib/badline/drives/model1541/disk.rb +317 -0
  204. data/lib/badline/drives/model1541/disk_via.rb +38 -0
  205. data/lib/badline/drives/model1541/gcr.rb +59 -0
  206. data/lib/badline/drives/model1541/mechanism/saved_state.rb +72 -0
  207. data/lib/badline/drives/model1541/mechanism.rb +315 -0
  208. data/lib/badline/drives/model1541/rotation.rb +123 -0
  209. data/lib/badline/drives/model1541/saved_state.rb +44 -0
  210. data/lib/badline/drives/model1541/sector_reader.rb +78 -0
  211. data/lib/badline/drives/model1541/serial_port.rb +20 -0
  212. data/lib/badline/drives/model1541/track.rb +100 -0
  213. data/lib/badline/drives/model1541.rb +81 -0
  214. data/lib/badline/drives/model1571/bus.rb +113 -0
  215. data/lib/badline/drives/model1571/cpu.rb +13 -0
  216. data/lib/badline/drives/model1571/saved_state.rb +47 -0
  217. data/lib/badline/drives/model1571/serial_port.rb +39 -0
  218. data/lib/badline/drives/model1571/serial_via.rb +27 -0
  219. data/lib/badline/drives/model1571/wd1770.rb +122 -0
  220. data/lib/badline/drives/model1571.rb +142 -0
  221. data/lib/badline/drives/model1581/bus.rb +139 -0
  222. data/lib/badline/drives/model1581/cpu.rb +13 -0
  223. data/lib/badline/drives/model1581/disk/saved_state.rb +89 -0
  224. data/lib/badline/drives/model1581/disk.rb +137 -0
  225. data/lib/badline/drives/model1581/mechanism.rb +119 -0
  226. data/lib/badline/drives/model1581/saved_state.rb +42 -0
  227. data/lib/badline/drives/model1581/serial_port.rb +54 -0
  228. data/lib/badline/drives/model1581/slot.rb +79 -0
  229. data/lib/badline/drives/model1581/track.rb +102 -0
  230. data/lib/badline/drives/model1581/track_bytes.rb +77 -0
  231. data/lib/badline/drives/model1581/wd1772/registers.rb +91 -0
  232. data/lib/badline/drives/model1581/wd1772/saved_state.rb +68 -0
  233. data/lib/badline/drives/model1581/wd1772/sector_writes.rb +75 -0
  234. data/lib/badline/drives/model1581/wd1772/sectors.rb +152 -0
  235. data/lib/badline/drives/model1581/wd1772/stepping.rb +111 -0
  236. data/lib/badline/drives/model1581/wd1772/tracks.rb +127 -0
  237. data/lib/badline/drives/model1581/wd1772/turn.rb +75 -0
  238. data/lib/badline/drives/model1581/wd1772.rb +218 -0
  239. data/lib/badline/drives/model1581.rb +206 -0
  240. data/lib/badline/drives/serial_bus.rb +161 -0
  241. data/lib/badline/frontend/boot.rb +3 -3
  242. data/lib/badline/frontend/machine_window.rb +3 -1
  243. data/lib/badline/frontend/player/filter_view.rb +1 -1
  244. data/lib/badline/frontend/player/player_controller.rb +2 -2
  245. data/lib/badline/frontend/player/player_screen.rb +1 -0
  246. data/lib/badline/frontend/player/theme.rb +7 -7
  247. data/lib/badline/frontend/timeline.rb +3 -3
  248. data/lib/badline/input/control_ports.rb +78 -0
  249. data/lib/badline/input/joystick.rb +27 -0
  250. data/lib/badline/input/keyboard.rb +114 -0
  251. data/lib/badline/input.rb +3 -0
  252. data/lib/badline/kernal_trap/{drive → dos}/block_commands.rb +1 -1
  253. data/lib/badline/kernal_trap/dos/channel.rb +183 -0
  254. data/lib/badline/kernal_trap/{drive → dos}/channels.rb +1 -1
  255. data/lib/badline/kernal_trap/{drive → dos}/memory.rb +1 -1
  256. data/lib/badline/kernal_trap/{drive → dos}/parameters.rb +1 -1
  257. data/lib/badline/kernal_trap/{drive → dos}/status.rb +1 -1
  258. data/lib/badline/kernal_trap/{drive → dos}/write_file.rb +1 -1
  259. data/lib/badline/kernal_trap/{drive → dos}/writes.rb +1 -1
  260. data/lib/badline/kernal_trap/{drive.rb → dos.rb} +11 -10
  261. data/lib/badline/kernal_trap/load.rb +5 -5
  262. data/lib/badline/kernal_trap/save.rb +4 -4
  263. data/lib/badline/kernal_trap/serial.rb +7 -7
  264. data/lib/badline/kernal_trap.rb +1 -2
  265. data/lib/badline/machine/clocking.rb +1 -1
  266. data/lib/badline/machine.rb +5 -5
  267. data/lib/badline/media/true_drive.rb +1 -1
  268. data/lib/badline/media/tune.rb +2 -2
  269. data/lib/badline/media.rb +3 -3
  270. data/lib/badline/model.rb +1 -1
  271. data/lib/badline/roms/README +6 -6
  272. data/lib/badline/sdl.rb +1 -0
  273. data/lib/badline/{storage/sid_file.rb → sid_tune/file.rb} +3 -3
  274. data/lib/badline/{storage → sid_tune}/hvsc.rb +7 -7
  275. data/lib/badline/{storage → sid_tune}/song_lengths.rb +2 -2
  276. data/lib/badline/{storage → sid_tune}/stil/credit.rb +1 -1
  277. data/lib/badline/{storage → sid_tune}/stil.rb +3 -3
  278. data/lib/badline/sid_tune.rb +6 -0
  279. data/lib/badline/snapshot/c128_setup.rb +43 -0
  280. data/lib/badline/snapshot/c64_setup.rb +79 -0
  281. data/lib/badline/snapshot/image.rb +5 -25
  282. data/lib/badline/snapshot/machine_state.rb +1 -1
  283. data/lib/badline/snapshot/setup.rb +22 -66
  284. data/lib/badline/snapshot/state.rb +8 -18
  285. data/lib/badline/snapshot/storage_setup.rb +68 -0
  286. data/lib/badline/snapshot/vic20_setup.rb +37 -0
  287. data/lib/badline/snapshot/vice/c64_mem.rb +1 -1
  288. data/lib/badline/snapshot/vice/restore.rb +1 -1
  289. data/lib/badline/snapshot/vice/reu1764.rb +1 -1
  290. data/lib/badline/snapshot/vice/reu_fields.rb +40 -0
  291. data/lib/badline/snapshot/vice.rb +7 -5
  292. data/lib/badline/snapshot.rb +3 -4
  293. data/lib/badline/storage/d64_image.rb +0 -2
  294. data/lib/badline/storage/d71_image.rb +0 -2
  295. data/lib/badline/storage/d81_image.rb +0 -2
  296. data/lib/badline/storage/disk_image.rb +3 -6
  297. data/lib/badline/storage/g64_image.rb +2 -2
  298. data/lib/badline/storage/host_directory.rb +0 -5
  299. data/lib/badline/storage/t64.rb +2 -8
  300. data/lib/badline/storage/unavailable.rb +1 -1
  301. data/lib/badline/storage.rb +0 -37
  302. data/lib/badline/support/c128_checkpoint.rb +39 -0
  303. data/lib/badline/support/checkpoint.rb +108 -0
  304. data/lib/badline/support/vic20_checkpoint.rb +38 -0
  305. data/lib/badline/support.rb +5 -0
  306. data/lib/badline/version.rb +1 -1
  307. data/lib/badline/vic20/attachments.rb +5 -5
  308. data/lib/badline/vic20/bus/saved_state.rb +35 -0
  309. data/lib/badline/vic20/bus.rb +3 -25
  310. data/lib/badline/vic20/cpu.rb +1 -1
  311. data/lib/badline/vic20/port_wiring.rb +4 -4
  312. data/lib/badline/vic20/saved_state.rb +16 -30
  313. data/lib/badline/vic20/user_via_ports.rb +2 -2
  314. data/lib/badline/vic20.rb +19 -14
  315. metadata +245 -221
  316. data/lib/badline/address_bus/extra_sids.rb +0 -30
  317. data/lib/badline/address_bus/fittings.rb +0 -38
  318. data/lib/badline/address_bus/pla.rb +0 -147
  319. data/lib/badline/address_bus/roms.rb +0 -39
  320. data/lib/badline/address_bus/saved_state.rb +0 -66
  321. data/lib/badline/address_bus/sid_slots.rb +0 -42
  322. data/lib/badline/address_bus.rb +0 -216
  323. data/lib/badline/cartridge/action_replay.rb +0 -126
  324. data/lib/badline/cartridge/atomic_power.rb +0 -24
  325. data/lib/badline/cartridge/bank.rb +0 -81
  326. data/lib/badline/cartridge/comal80.rb +0 -50
  327. data/lib/badline/cartridge/dinamic.rb +0 -34
  328. data/lib/badline/cartridge/easy_flash.rb +0 -145
  329. data/lib/badline/cartridge/epyx_fastload.rb +0 -79
  330. data/lib/badline/cartridge/final_cartridge3.rb +0 -89
  331. data/lib/badline/cartridge/flash.rb +0 -306
  332. data/lib/badline/cartridge/freezer.rb +0 -33
  333. data/lib/badline/cartridge/fun_play.rb +0 -38
  334. data/lib/badline/cartridge/g_mod2.rb +0 -74
  335. data/lib/badline/cartridge/game_system.rb +0 -40
  336. data/lib/badline/cartridge/geo_ram.rb +0 -79
  337. data/lib/badline/cartridge/kcs_power.rb +0 -75
  338. data/lib/badline/cartridge/mach5.rb +0 -32
  339. data/lib/badline/cartridge/magic_desk.rb +0 -30
  340. data/lib/badline/cartridge/ocean.rb +0 -35
  341. data/lib/badline/cartridge/pagefox.rb +0 -68
  342. data/lib/badline/cartridge/retro_replay.rb +0 -320
  343. data/lib/badline/cartridge/rex_utility.rb +0 -29
  344. data/lib/badline/cartridge/rgcd.rb +0 -58
  345. data/lib/badline/cartridge/simons_basic.rb +0 -35
  346. data/lib/badline/cartridge/standard.rb +0 -15
  347. data/lib/badline/cartridge/super_games.rb +0 -48
  348. data/lib/badline/cartridge/westermann.rb +0 -30
  349. data/lib/badline/cartridge/zaxxon.rb +0 -66
  350. data/lib/badline/cartridge.rb +0 -303
  351. data/lib/badline/checkpoint.rb +0 -98
  352. data/lib/badline/cia/fast_forward.rb +0 -60
  353. data/lib/badline/cia/interrupt_register.rb +0 -143
  354. data/lib/badline/cia/serial.rb +0 -275
  355. data/lib/badline/cia/state.rb +0 -47
  356. data/lib/badline/cia/timer.rb +0 -206
  357. data/lib/badline/cia.rb +0 -279
  358. data/lib/badline/color_memory.rb +0 -25
  359. data/lib/badline/control_ports.rb +0 -76
  360. data/lib/badline/cpu/addressing.rb +0 -131
  361. data/lib/badline/cpu/boundary.rb +0 -54
  362. data/lib/badline/cpu/core.rb +0 -165
  363. data/lib/badline/cpu/microcode.rb +0 -177
  364. data/lib/badline/cpu/operations.rb +0 -88
  365. data/lib/badline/cpu/saved_state.rb +0 -115
  366. data/lib/badline/cpu/stack_operations.rb +0 -82
  367. data/lib/badline/cpu.rb +0 -10
  368. data/lib/badline/cpu_port.rb +0 -112
  369. data/lib/badline/datasette.rb +0 -161
  370. data/lib/badline/drive/core.rb +0 -147
  371. data/lib/badline/drive/fast_serial.rb +0 -73
  372. data/lib/badline/drive/idle.rb +0 -125
  373. data/lib/badline/drive/idle_cpu.rb +0 -28
  374. data/lib/badline/drive/orbit.rb +0 -79
  375. data/lib/badline/drive/serial_lines.rb +0 -73
  376. data/lib/badline/drive/sleep.rb +0 -112
  377. data/lib/badline/drive/vias.rb +0 -84
  378. data/lib/badline/drive/watch.rb +0 -150
  379. data/lib/badline/drive.rb +0 -11
  380. data/lib/badline/drive1541/bus.rb +0 -86
  381. data/lib/badline/drive1541/byte_ready.rb +0 -48
  382. data/lib/badline/drive1541/cpu.rb +0 -11
  383. data/lib/badline/drive1541/disk.rb +0 -315
  384. data/lib/badline/drive1541/disk_state.rb +0 -86
  385. data/lib/badline/drive1541/disk_via.rb +0 -36
  386. data/lib/badline/drive1541/gcr.rb +0 -57
  387. data/lib/badline/drive1541/mechanism.rb +0 -313
  388. data/lib/badline/drive1541/mechanism_state.rb +0 -68
  389. data/lib/badline/drive1541/rotation.rb +0 -121
  390. data/lib/badline/drive1541/sector_reader.rb +0 -76
  391. data/lib/badline/drive1541/serial_port.rb +0 -18
  392. data/lib/badline/drive1541/track.rb +0 -98
  393. data/lib/badline/drive1541.rb +0 -111
  394. data/lib/badline/drive1571/bus.rb +0 -111
  395. data/lib/badline/drive1571/cpu.rb +0 -11
  396. data/lib/badline/drive1571/serial_port.rb +0 -37
  397. data/lib/badline/drive1571/serial_via.rb +0 -25
  398. data/lib/badline/drive1571/wd1770.rb +0 -120
  399. data/lib/badline/drive1571.rb +0 -175
  400. data/lib/badline/drive1581/bus.rb +0 -137
  401. data/lib/badline/drive1581/cpu.rb +0 -11
  402. data/lib/badline/drive1581/disk.rb +0 -135
  403. data/lib/badline/drive1581/disk_state.rb +0 -87
  404. data/lib/badline/drive1581/mechanism.rb +0 -117
  405. data/lib/badline/drive1581/serial_port.rb +0 -52
  406. data/lib/badline/drive1581/slot.rb +0 -78
  407. data/lib/badline/drive1581/track.rb +0 -100
  408. data/lib/badline/drive1581/track_bytes.rb +0 -75
  409. data/lib/badline/drive1581/wd1772/registers.rb +0 -89
  410. data/lib/badline/drive1581/wd1772/sector_writes.rb +0 -73
  411. data/lib/badline/drive1581/wd1772/sectors.rb +0 -150
  412. data/lib/badline/drive1581/wd1772/state.rb +0 -66
  413. data/lib/badline/drive1581/wd1772/stepping.rb +0 -109
  414. data/lib/badline/drive1581/wd1772/tracks.rb +0 -125
  415. data/lib/badline/drive1581/wd1772/turn.rb +0 -73
  416. data/lib/badline/drive1581/wd1772.rb +0 -216
  417. data/lib/badline/drive1581.rb +0 -233
  418. data/lib/badline/iec_bus.rb +0 -159
  419. data/lib/badline/instruction.rb +0 -334
  420. data/lib/badline/instruction_set/arithmetic.rb +0 -114
  421. data/lib/badline/instruction_set/bitwise.rb +0 -126
  422. data/lib/badline/instruction_set/branch.rb +0 -79
  423. data/lib/badline/instruction_set/flag.rb +0 -63
  424. data/lib/badline/instruction_set/illegal.rb +0 -270
  425. data/lib/badline/instruction_set/inc_dec.rb +0 -69
  426. data/lib/badline/instruction_set/stack.rb +0 -52
  427. data/lib/badline/instruction_set/transfer.rb +0 -137
  428. data/lib/badline/instruction_set.rb +0 -55
  429. data/lib/badline/interrupts.rb +0 -104
  430. data/lib/badline/joystick.rb +0 -25
  431. data/lib/badline/kernal_trap/channel.rb +0 -181
  432. data/lib/badline/keyboard.rb +0 -112
  433. data/lib/badline/ram_expansion/banking.rb +0 -30
  434. data/lib/badline/ram_expansion/plus256k.rb +0 -54
  435. data/lib/badline/ram_expansion/plus60k.rb +0 -43
  436. data/lib/badline/ram_expansion/unexpanded.rb +0 -28
  437. data/lib/badline/ram_expansion.rb +0 -21
  438. data/lib/badline/reu/dma/saved_state.rb +0 -50
  439. data/lib/badline/reu/dma.rb +0 -273
  440. data/lib/badline/reu/ram.rb +0 -107
  441. data/lib/badline/reu/saved_state.rb +0 -80
  442. data/lib/badline/reu/trigger.rb +0 -32
  443. data/lib/badline/reu.rb +0 -289
  444. data/lib/badline/sid/catch_up.rb +0 -120
  445. data/lib/badline/sid/decimator.rb +0 -64
  446. data/lib/badline/sid/envelope/state.rb +0 -68
  447. data/lib/badline/sid/envelope.rb +0 -239
  448. data/lib/badline/sid/filter.rb +0 -263
  449. data/lib/badline/sid/voice.rb +0 -77
  450. data/lib/badline/sid/waveform/combined.rb +0 -126
  451. data/lib/badline/sid/waveform/fast_forward.rb +0 -105
  452. data/lib/badline/sid/waveform/noise_writeback.rb +0 -122
  453. data/lib/badline/sid/waveform/state.rb +0 -66
  454. data/lib/badline/sid/waveform.rb +0 -305
  455. data/lib/badline/sid.rb +0 -303
  456. data/lib/badline/time_of_day.rb +0 -228
  457. data/lib/badline/traps.rb +0 -19
  458. data/lib/badline/via/control_lines.rb +0 -122
  459. data/lib/badline/via/fast_forward.rb +0 -53
  460. data/lib/badline/via/interrupt_register.rb +0 -67
  461. data/lib/badline/via/shift_register.rb +0 -180
  462. data/lib/badline/via/state.rb +0 -42
  463. data/lib/badline/via/timer1.rb +0 -131
  464. data/lib/badline/via/timer2.rb +0 -133
  465. data/lib/badline/via.rb +0 -266
  466. data/lib/badline/vic/bank.rb +0 -133
  467. data/lib/badline/vic/border_mask.rb +0 -86
  468. data/lib/badline/vic/collisions.rb +0 -115
  469. data/lib/badline/vic/color_patches.rb +0 -47
  470. data/lib/badline/vic/display_state.rb +0 -185
  471. data/lib/badline/vic/graphics_mode.rb +0 -164
  472. data/lib/badline/vic/graphics_shifter.rb +0 -207
  473. data/lib/badline/vic/register_log.rb +0 -81
  474. data/lib/badline/vic/registers.rb +0 -195
  475. data/lib/badline/vic/sequencer.rb +0 -275
  476. data/lib/badline/vic/sequencer_output.rb +0 -116
  477. data/lib/badline/vic/sequencer_state.rb +0 -89
  478. data/lib/badline/vic/sprite/internal_bus.rb +0 -68
  479. data/lib/badline/vic/sprite/saved_state.rb +0 -64
  480. data/lib/badline/vic/sprite/shifter.rb +0 -146
  481. data/lib/badline/vic/sprite/timing.rb +0 -56
  482. data/lib/badline/vic/sprite.rb +0 -337
  483. data/lib/badline/vic/sprites.rb +0 -282
  484. data/lib/badline/vic/sprites_state.rb +0 -57
  485. data/lib/badline/vic.rb +0 -853
  486. data/lib/badline/vic20/sound/output.rb +0 -83
  487. data/lib/badline/vic20/sound.rb +0 -233
  488. data/lib/badline/z80/arithmetic.rb +0 -117
  489. data/lib/badline/z80/bit_page.rb +0 -55
  490. data/lib/badline/z80/block_io.rb +0 -58
  491. data/lib/badline/z80/block_transfers.rb +0 -59
  492. data/lib/badline/z80/bus_cycles.rb +0 -111
  493. data/lib/badline/z80/core.rb +0 -113
  494. data/lib/badline/z80/exchanges.rb +0 -50
  495. data/lib/badline/z80/extended_page.rb +0 -89
  496. data/lib/badline/z80/flags.rb +0 -37
  497. data/lib/badline/z80/interrupt_acceptance.rb +0 -46
  498. data/lib/badline/z80/jumps.rb +0 -82
  499. data/lib/badline/z80/loads.rb +0 -98
  500. data/lib/badline/z80/main_page.rb +0 -134
  501. data/lib/badline/z80/registers.rb +0 -120
  502. data/lib/badline/z80/saved_state.rb +0 -69
  503. data/lib/badline/z80/shifts.rb +0 -64
  504. data/lib/badline/z80.rb +0 -11
  505. /data/lib/badline/snapshot/{fields.rb → vice/fields.rb} +0 -0
@@ -42,12 +42,9 @@ module Badline
42
42
  # Whether the image was opened write-protected.
43
43
  def read_only? = @read_only
44
44
 
45
- # What Storage.reopen needs to open the image again as it stands: its
46
- # path, whether it is write-protected, and its bytes with the error
47
- # table after them.
48
- def save_setup(out)
49
- out.int(storage_kind).string(File.expand_path(@path)).boolean(@read_only).blob(@bytes + @errors.to_a)
50
- end
45
+ # The image as its file holds it, with its error table after the
46
+ # blocks.
47
+ def contents = @bytes + @errors.to_a
51
48
 
52
49
  # A LOAD reads only PRG files. An OPEN names the type it wants, or
53
50
  # takes the first file of any type with a nil `type`.
@@ -5,7 +5,7 @@ module Badline
5
5
  # A .g64 image: a 1541 disk's flux as raw GCR, track by track, for the
6
6
  # true drive to read the way it reads a real disk, copy protection and
7
7
  # all. It has no file system of its own, so only the true drive
8
- # (Drive1541::Disk.from_g64) can use it. A .g71 holds a 1571 disk the
8
+ # (Drives::Model1541::Disk.from_g64) can use it. A .g71 holds a 1571 disk the
9
9
  # same way, with "GCR-1571" for its signature and 168 half tracks,
10
10
  # the first side's 84 and then the second's.
11
11
  #
@@ -21,7 +21,7 @@ module Badline
21
21
  # A larger one is the offset of a speed map, two bits a byte, four
22
22
  # track bytes to a map byte, the first byte's in the top two bits, for
23
23
  # a track whose zone changes along it. The drive passes each byte
24
- # under the head at its own zone's rate (Drive1541::Track).
24
+ # under the head at its own zone's rate (Drives::Model1541::Track).
25
25
  #
26
26
  # The drive writes a track at one zone, so a track written back takes
27
27
  # that zone as its speed entry. Writing it puts it in its own block,
@@ -17,11 +17,6 @@ module Badline
17
17
  @path = path
18
18
  end
19
19
 
20
- # What Storage.reopen needs to open the directory again.
21
- def save_setup(out)
22
- out.int(HOST_DIRECTORY).string(File.expand_path(@path))
23
- end
24
-
25
20
  def read_file(name, **)
26
21
  entry = find(name)
27
22
  return unless entry
@@ -20,14 +20,8 @@ module Badline
20
20
  raise FormatError, "Missing T64 signature" unless @bytes[0, 3] == SIGNATURE
21
21
  end
22
22
 
23
- # The host file's path, as it was opened.
24
- attr_reader :path
25
-
26
- # What Storage.reopen needs to open the archive again: its path and
27
- # its bytes.
28
- def save_setup(out)
29
- out.int(T64_ARCHIVE).string(File.expand_path(@path)).blob(@bytes)
30
- end
23
+ # The host file's path, as it was opened, and its bytes.
24
+ attr_reader :path, :bytes
31
25
 
32
26
  def read_file(name, **)
33
27
  pattern = Storage.matcher(name)
@@ -3,7 +3,7 @@
3
3
  module Badline
4
4
  module Storage
5
5
  # Stands in for a directory a detached restore leaves out
6
- # (Snapshot::StateReader): it finds no files and refuses every write
6
+ # (Snapshot::StorageSetup): it finds no files and refuses every write
7
7
  # as a write-protected disk does.
8
8
  class Unavailable
9
9
  def path = ""
@@ -11,10 +11,6 @@ require "badline/storage/g64_image"
11
11
  require "badline/storage/t64"
12
12
  require "badline/storage/tap"
13
13
  require "badline/storage/crt_file"
14
- require "badline/storage/sid_file"
15
- require "badline/storage/hvsc"
16
- require "badline/storage/song_lengths"
17
- require "badline/storage/stil"
18
14
  require "badline/storage/unavailable"
19
15
 
20
16
  module Badline
@@ -36,29 +32,7 @@ module Badline
36
32
  end
37
33
  end
38
34
 
39
- # The storage a snapshot's device 8 serves, by the number save_setup
40
- # writes first.
41
- HOST_DIRECTORY = 0
42
- D64 = 1
43
- D71 = 2
44
- D81 = 3
45
- T64_ARCHIVE = 4
46
-
47
35
  class << self
48
- # Opens the storage a save_setup wrote: the same directory by its
49
- # path, an archive with the bytes it held, or a disk image with the
50
- # bytes it held, writes and all. A detached reader gets the image
51
- # write-protected, and Unavailable for a directory.
52
- def reopen(input)
53
- kind = input.int
54
- path = input.string
55
- case kind
56
- when HOST_DIRECTORY then input.detached? ? Unavailable.new : HostDirectory.new(path)
57
- when T64_ARCHIVE then T64.new(path, bytes: input.blob)
58
- else reopen_image(kind, path, input)
59
- end
60
- end
61
-
62
36
  # Folds shifted PETSCII letters to their ASCII equivalents.
63
37
  def ascii(bytes)
64
38
  bytes.map { |b| b.between?(0xc1, 0xda) ? b - 0x80 : b }.pack("C*")
@@ -83,17 +57,6 @@ module Badline
83
57
  [base.to_s, FILE_TYPES[type.to_s.strip[0]&.upcase]]
84
58
  end
85
59
 
86
- def reopen_image(kind, path, input)
87
- read_only = input.boolean? || input.detached?
88
- bytes = input.blob
89
- case kind
90
- when D64 then D64Image.new(path, read_only:, bytes:)
91
- when D71 then D71Image.new(path, read_only:, bytes:)
92
- when D81 then D81Image.new(path, read_only:, bytes:)
93
- else raise Snapshot::FormatError, "unknown storage #{kind} in the state"
94
- end
95
- end
96
-
97
60
  # CBM-style filename pattern: "*" and "?" wildcards, case-insensitive.
98
61
  # The DOS stops comparing at the first "*", so whatever follows it
99
62
  # is ignored.
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Support
5
+ # A Checkpoint of a C128, in either mode: a C64's components, with the
6
+ # whole 128K of RAM in place of bank 0 and the colour RAM bank the 8502
7
+ # sees, and besides them the VDC's registers and beam, the VDC's RAM, the
8
+ # MMU's registers and the Z80.
9
+ module C128Checkpoint
10
+ COMPONENTS = %w[cpu ram color_ram display vic cia1 cia2 sid vdc vdc_ram mmu z80].freeze
11
+
12
+ def self.take(machine)
13
+ Checkpoint.new(machine.cycles, [
14
+ Checkpoint.fnv1a(Checkpoint.cpu_state(machine.cpu)),
15
+ Checkpoint.fnv1a(Checkpoint.ram(machine.ram, 0x20000)),
16
+ Checkpoint.fnv1a(Checkpoint.color_ram(machine.address_bus.color_ram, 0xd800)),
17
+ Checkpoint.fnv1a(machine.vic.display),
18
+ Checkpoint.fnv1a(Checkpoint.vic_state(machine.vic)),
19
+ Checkpoint.fnv1a(Checkpoint.cia_state(machine.cia1)),
20
+ Checkpoint.fnv1a(Checkpoint.cia_state(machine.cia2)),
21
+ Checkpoint.fnv1a(Array.new(0x20) { |reg| machine.sid.register(reg) }),
22
+ Checkpoint.fnv1a(machine.vdc.registers + [machine.vdc.frame]),
23
+ Checkpoint.fnv1a(machine.vdc.ram),
24
+ Checkpoint.fnv1a(machine.mmu.registers),
25
+ Checkpoint.fnv1a(z80_state(machine.z80))
26
+ ], COMPONENTS)
27
+ end
28
+
29
+ def self.parse(line) = Checkpoint.parse(line, COMPONENTS)
30
+
31
+ def self.z80_state(z80)
32
+ [z80.pc, z80.sp, z80.af, z80.bc, z80.de, z80.hl, z80.ix, z80.iy, z80.af_alt, z80.bc_alt, z80.de_alt,
33
+ z80.hl_alt, z80.i, z80.r, z80.im, flag(z80.iff1), flag(z80.iff2), flag(z80.halted), z80.cycles]
34
+ end
35
+
36
+ def self.flag(value) = value == true ? 1 : 0
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,108 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Support
5
+ # A digest of the machine's state at one cycle, for comparing two runs of
6
+ # the same scenario, on two builds or two revisions. Each component is
7
+ # hashed on its own with 32-bit FNV-1a, so a mismatch names the part of the
8
+ # machine that went its own way. Nothing is read through a chip's bus
9
+ # interface, so taking a checkpoint leaves the machine as it was.
10
+ #
11
+ # Checkpoint.take digests a C64's components, COMPONENTS.
12
+ # Vic20Checkpoint and C128Checkpoint digest the other families', each
13
+ # with a list of its own, which a checkpoint carries as +components+.
14
+ #
15
+ # Colour RAM is digested as the four bits each cell stores: the upper
16
+ # nibble a CPU read sees comes off the open bus.
17
+ class Checkpoint
18
+ COMPONENTS = %w[cpu ram color_ram display vic cia1 cia2 sid].freeze
19
+
20
+ FNV_OFFSET = 0x811c9dc5
21
+ FNV_PRIME = 0x01000193
22
+
23
+ attr_reader :cycle, :digests, :components
24
+
25
+ class << self
26
+ def take(computer)
27
+ new(computer.cycles, [
28
+ fnv1a(cpu_state(computer.cpu)),
29
+ fnv1a(ram(computer.ram, 0x10000)),
30
+ fnv1a(color_ram(computer.address_bus.color_ram, 0xd800)),
31
+ fnv1a(computer.vic.display),
32
+ fnv1a(vic_state(computer.vic)),
33
+ fnv1a(cia_state(computer.cia1)),
34
+ fnv1a(cia_state(computer.cia2)),
35
+ fnv1a(Array.new(0x20) { |reg| computer.sid.register(reg) })
36
+ ])
37
+ end
38
+
39
+ # Reads a line written by #to_s, with a digest for each of
40
+ # `components`.
41
+ def parse(line, components = COMPONENTS)
42
+ fields = line.split
43
+ digests = components.map do |name|
44
+ field = fields.find { |f| f.start_with?("#{name}=") }
45
+ raise ArgumentError, "no #{name} digest in #{line.inspect}" unless field
46
+
47
+ field.split("=").last.to_i(16)
48
+ end
49
+ new(fields.first.to_i, digests, components)
50
+ end
51
+
52
+ def fnv1a(values)
53
+ hash = FNV_OFFSET
54
+ values.each { |value| hash = ((hash ^ (value & 0xffffffff)) * FNV_PRIME) & 0xffffffff }
55
+ hash
56
+ end
57
+
58
+ # The registers and cycle count of a 6502 or an 8502.
59
+ def cpu_state(cpu)
60
+ [cpu.program_counter, cpu.a, cpu.x, cpu.y, cpu.stack_pointer, cpu.p, cpu.cycles]
61
+ end
62
+
63
+ # The first `length` bytes of `memory`.
64
+ def ram(memory, length)
65
+ Array.new(length) { |addr| memory.peek(addr) }
66
+ end
67
+
68
+ # The 1K of colour RAM at `start`.
69
+ def color_ram(memory, start)
70
+ Array.new(0x400) { |offset| memory.nibble(start + offset) }
71
+ end
72
+
73
+ # A VIC-II's or a VIC-I's registers and beam position.
74
+ def vic_state(vic)
75
+ vic.register_file + [vic.rasterline, vic.column]
76
+ end
77
+
78
+ def cia_state(cia)
79
+ start = cia.start
80
+ [cia.peek(start), cia.peek(start + 1), cia.peek(start + 2), cia.peek(start + 3),
81
+ cia.timer_a, cia.timer_a_latch, cia.timer_b, cia.timer_b_latch, cia.serial.data,
82
+ cia.control_a.value, cia.control_b.value, cia.interrupt_status.value,
83
+ cia.interrupt_control.value] + cia.time_of_day.registers
84
+ end
85
+ end
86
+
87
+ def initialize(cycle, digests, components = COMPONENTS)
88
+ @cycle = cycle
89
+ @digests = digests
90
+ @components = components
91
+ end
92
+
93
+ # The components whose digests differ from `other`'s.
94
+ def differences(other)
95
+ components.each_index.reject { |i| digests[i] == other.digests[i] }.map { |i| components[i] }
96
+ end
97
+
98
+ def ==(other)
99
+ other.is_a?(Checkpoint) && cycle == other.cycle && components == other.components && digests == other.digests
100
+ end
101
+
102
+ def to_s
103
+ fields = components.each_index.map { |i| "#{components[i]}=#{digests[i].to_s(16).rjust(8, '0')}" }
104
+ "#{cycle} #{fields.join(' ')}"
105
+ end
106
+ end
107
+ end
108
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Support
5
+ # A Checkpoint of a VIC-20: its CPU, the 48K of RAM the bus decodes, the
6
+ # colour RAM, the VIC-I's display and registers, both VIAs and the
7
+ # sound. The sound's shift registers and noise LFSR move only while it
8
+ # records, so a run that wants them digested records it.
9
+ module Vic20Checkpoint
10
+ COMPONENTS = %w[cpu ram color_ram display vic via1 via2 sound].freeze
11
+
12
+ def self.take(machine)
13
+ Checkpoint.new(machine.cycles, [
14
+ Checkpoint.fnv1a(Checkpoint.cpu_state(machine.cpu)),
15
+ Checkpoint.fnv1a(Checkpoint.ram(machine.ram, 0xc000)),
16
+ Checkpoint.fnv1a(Checkpoint.color_ram(machine.bus.color_ram, 0)),
17
+ Checkpoint.fnv1a(machine.vic.display),
18
+ Checkpoint.fnv1a(Checkpoint.vic_state(machine.vic)),
19
+ Checkpoint.fnv1a(via_state(machine.via1)),
20
+ Checkpoint.fnv1a(via_state(machine.via2)),
21
+ Checkpoint.fnv1a(sound_state(machine.sound))
22
+ ], COMPONENTS)
23
+ end
24
+
25
+ def self.parse(line) = Checkpoint.parse(line, COMPONENTS)
26
+
27
+ def self.via_state(via)
28
+ [via.port_a_output, via.port_b_output, via.timer1, via.timer1_latch, via.timer2,
29
+ via.shift_register.data, via.acr, via.pcr, via.interrupt_flags, via.interrupt_enable]
30
+ end
31
+
32
+ def self.sound_state(sound)
33
+ [sound.volume, sound.shift_register(0), sound.shift_register(1), sound.shift_register(2),
34
+ sound.shift_register(3), sound.lfsr]
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "badline/support/checkpoint"
4
+ require "badline/support/vic20_checkpoint"
5
+ require "badline/support/c128_checkpoint"
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Badline
4
- VERSION = "0.12.1"
4
+ VERSION = "0.13.0"
5
5
  end
@@ -4,11 +4,11 @@ module Badline
4
4
  class Vic20
5
5
  # What plugs into the VIC-20 besides its chips: cartridge ROM in the
6
6
  # expansion blocks, the disk device 8 serves through the KERNAL traps
7
- # (Computer::KernalTraps), and a true 1541 or 1581 on the serial bus
8
- # (Computer::TrueDrives).
7
+ # (C64::KernalTraps), and a true 1541 or 1581 on the serial bus
8
+ # (C64::TrueDrives).
9
9
  module Attachments
10
- include Computer::TrueDrives
11
- include Computer::KernalTraps
10
+ include C64::TrueDrives
11
+ include C64::KernalTraps
12
12
 
13
13
  # The cycle by which a 1541 switched on with the machine has run its
14
14
  # DOS's reset, the RAM test and the ROM checksum, and waits on the
@@ -46,7 +46,7 @@ module Badline
46
46
  # A 1581 plugged in, as a 1541 does, holds the machine's on_init
47
47
  # handlers back until its DOS has booted.
48
48
  def drive1581_attached
49
- @init_threshold = [@init_threshold, Drive1581::BOOT_CYCLES].max if @cycles < @init_threshold
49
+ @init_threshold = [@init_threshold, Drives::Model1581::BOOT_CYCLES].max if @cycles < @init_threshold
50
50
  end
51
51
  end
52
52
  end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class Vic20
5
+ class Bus
6
+ # The bus's state for a snapshot.
7
+ module SavedState
8
+ # The RAM, the colour RAM, the byte each side's data lines hold and the
9
+ # cartridge's ROM chips, for a snapshot. The expansion blocks are how
10
+ # the machine was built.
11
+ def save_state(out)
12
+ out.marker("VIC20 BUS")
13
+ @ram.save_state(out)
14
+ out.blob(@color_ram.cells).int(@data).int(@video_data).int(@roms.length)
15
+ @roms.each do |rom|
16
+ out.int(rom.start)
17
+ rom.save_state(out)
18
+ end
19
+ end
20
+
21
+ def load_state(input)
22
+ input.marker("VIC20 BUS")
23
+ @ram.load_state(input)
24
+ input.blob_into(@color_ram.cells)
25
+ @data = input.int
26
+ @video_data = input.int
27
+ chips = Array.new(input.int) { [input.int, input.blob] }
28
+ @roms = []
29
+ chips.each { |chip| @roms << ROM.new(chip[1], length: chip[1].length, start: chip[0]) }
30
+ map_pages
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "badline/vic20/bus/saved_state"
4
+
3
5
  module Badline
4
6
  class Vic20
5
7
  # The CPU's bus:
@@ -27,6 +29,7 @@ module Badline
27
29
  # Writes to ROM and to empty spots go nowhere.
28
30
  class Bus
29
31
  include Addressable
32
+ include SavedState
30
33
 
31
34
  # The pages each expansion block covers, as [first page, count].
32
35
  BLOCKS = {
@@ -215,31 +218,6 @@ module Badline
215
218
  @ram.clear!(RAM_POWER_ON)
216
219
  end
217
220
 
218
- # The RAM, the colour RAM, the byte each side's data lines hold and the
219
- # cartridge's ROM chips, for a snapshot. The expansion blocks are how
220
- # the machine was built.
221
- def save_state(out)
222
- out.marker("VIC20 BUS")
223
- @ram.save_state(out)
224
- out.blob(@color_ram.cells).int(@data).int(@video_data).int(@roms.length)
225
- @roms.each do |rom|
226
- out.int(rom.start)
227
- rom.save_state(out)
228
- end
229
- end
230
-
231
- def load_state(input)
232
- input.marker("VIC20 BUS")
233
- @ram.load_state(input)
234
- input.blob_into(@color_ram.cells)
235
- @data = input.int
236
- @video_data = input.int
237
- chips = Array.new(input.int) { [input.int, input.blob] }
238
- @roms = []
239
- chips.each { |chip| @roms << ROM.new(chip[1], length: chip[1].length, start: chip[0]) }
240
- map_pages
241
- end
242
-
243
221
  # Whether +block+ (BLOCKS) holds RAM.
244
222
  def ram?(block) = @blocks.include?(block)
245
223
 
@@ -4,7 +4,7 @@ module Badline
4
4
  class Vic20
5
5
  # The VIC-20's 6502, on the Vic20::Bus.
6
6
  class CPU
7
- include Badline::CPU::Core
7
+ include Badline::Chips::CPU::Core
8
8
  end
9
9
  end
10
10
  end
@@ -16,12 +16,12 @@ module Badline
16
16
  # on VIA 1's PA6, its motor runs while VIA 1's CA2 is low, and VIA 2's
17
17
  # PB3 drives its write line, the same pin as a keyboard column.
18
18
  module PortWiring
19
- # The lines the machine pulls, as IECBus host lines.
19
+ # The lines the machine pulls, as Drives::SerialBus host lines.
20
20
  def serial_lines
21
21
  lines = 0
22
- lines |= IECBus::HOST_ATN_OUT if @via1.port_a_output.anybits?(0x80)
23
- lines |= IECBus::HOST_CLK_OUT if @via2.ca2_output
24
- lines |= IECBus::HOST_DATA_OUT if @via2.cb2_output
22
+ lines |= Drives::SerialBus::HOST_ATN_OUT if @via1.port_a_output.anybits?(0x80)
23
+ lines |= Drives::SerialBus::HOST_CLK_OUT if @via2.ca2_output
24
+ lines |= Drives::SerialBus::HOST_DATA_OUT if @via2.cb2_output
25
25
  lines
26
26
  end
27
27
 
@@ -1,23 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "badline/snapshot/vic20_setup"
4
+
3
5
  module Badline
4
6
  class Vic20
5
- MARKER = "VIC20"
6
-
7
- # The RAM expansion of the machine a State from #snapshot was taken
8
- # of, a key of Bus::RAM_CONFIGURATIONS.
9
- def self.setup(state)
10
- input = Snapshot::StateReader.new(state)
11
- input.marker(MARKER)
12
- input.check_stamp
13
- SavedState.read_ram(input)
14
- end
7
+ # How the machine a State from #snapshot was taken of was built.
8
+ def self.setup(state) = Snapshot::Vic20Setup.from(state)
15
9
 
16
10
  # A new machine, built as the one a State from #snapshot was taken of,
17
11
  # at that state.
18
- def self.restored(state) = new(ram: setup(state)).apply_state(state)
12
+ def self.restored(state) = setup(state).build.apply_state(state)
19
13
 
20
- # The whole machine's state for a snapshot, as Computer's: the
14
+ # The whole machine's state for a snapshot, as C64's: the
21
15
  # machine's own latches, the bus with its RAM and cartridge ROM, the
22
16
  # VIC with its sound, both VIAs, the CPU, the datasette and its tape,
23
17
  # the disk device 8 serves through the traps, and a true 1541. The
@@ -26,14 +20,6 @@ module Badline
26
20
  # and callbacks, whether the display renders, whether the sound
27
21
  # records, and whether the datasette records.
28
22
  module SavedState
29
- RAM_CONFIGURATIONS = Bus::RAM_CONFIGURATIONS.keys.freeze
30
-
31
- def self.read_ram(input)
32
- RAM_CONFIGURATIONS.fetch(input.int)
33
- rescue IndexError
34
- raise Snapshot::FormatError, "the state names a VIC-20 RAM expansion badline doesn't know"
35
- end
36
-
37
23
  # How many more on_init handlers the machine a State was taken of had
38
24
  # yet to run than this one has. Nil until the machine is restored.
39
25
  attr_reader :init_handlers_lost
@@ -49,7 +35,7 @@ module Badline
49
35
  # Raises Snapshot::FormatError for a state of another machine or RAM
50
36
  # expansion.
51
37
  def restore(state)
52
- check_ram(Vic20.setup(state))
38
+ check_setup(Vic20.setup(state))
53
39
  Vic20.restored(state)
54
40
  apply_state(state)
55
41
  end
@@ -64,8 +50,8 @@ module Badline
64
50
  end
65
51
 
66
52
  def save_state(out)
67
- out.marker(MARKER).stamp
68
- out.int(RAM_CONFIGURATIONS.index(@ram_configuration))
53
+ out.marker(Snapshot::Vic20Setup::MARKER).stamp
54
+ Snapshot::Vic20Setup.new(ram: @ram_configuration).write(out)
69
55
  out.int(@cycles).boolean(@nmi_asserted).boolean(!@pending_keys.nil?)
70
56
  out.ints(@pending_keys) if @pending_keys
71
57
  out.int(@cycles <= @init_threshold ? @init_handlers.length : 0)
@@ -76,15 +62,15 @@ module Badline
76
62
  @via2.save_state(out)
77
63
  @cpu.save_state(out)
78
64
  @datasette.save_state(out)
79
- save_trap_drive(out)
65
+ save_trap_dos(out)
80
66
  save_drive1541(out)
81
67
  save_drive1581(out)
82
68
  end
83
69
 
84
70
  def load_state(input)
85
- input.marker(MARKER)
71
+ input.marker(Snapshot::Vic20Setup::MARKER)
86
72
  input.check_stamp
87
- check_ram(SavedState.read_ram(input))
73
+ check_setup(Snapshot::Vic20Setup.read(input))
88
74
  @cycles = input.int
89
75
  @nmi_asserted = input.boolean?
90
76
  @pending_keys = nil
@@ -98,7 +84,7 @@ module Badline
98
84
  @cpu.load_state(input)
99
85
  via_written
100
86
  @datasette.load_state(input)
101
- load_trap_drive(input)
87
+ load_trap_dos(input)
102
88
  load_drive1541(input)
103
89
  load_drive1581(input)
104
90
  end
@@ -114,10 +100,10 @@ module Badline
114
100
  @drive1541.save_state(out)
115
101
  end
116
102
 
117
- def check_ram(ram)
118
- return if ram == @ram_configuration
103
+ def check_setup(setup)
104
+ return if setup.ram == @ram_configuration
119
105
 
120
- raise Snapshot::FormatError, "the state is of a VIC-20 with #{ram} RAM, not #{@ram_configuration}"
106
+ raise Snapshot::FormatError, "the state is of a VIC-20 with #{setup.ram} RAM, not #{@ram_configuration}"
121
107
  end
122
108
  end
123
109
  end
@@ -38,8 +38,8 @@ module Badline
38
38
  def serial_inputs
39
39
  low = @serial_bus.low_lines
40
40
  value = 0x03
41
- value &= ~0x01 if low.anybits?(IECBus::CLK)
42
- value &= ~0x02 if low.anybits?(IECBus::DATA)
41
+ value &= ~0x01 if low.anybits?(Drives::SerialBus::CLK)
42
+ value &= ~0x02 if low.anybits?(Drives::SerialBus::DATA)
43
43
  value
44
44
  end
45
45
  end
data/lib/badline/vic20.rb CHANGED
@@ -6,8 +6,8 @@ require "badline/vic20/cpu"
6
6
  require "badline/vic20/keyboard_via_ports"
7
7
  require "badline/vic20/port_wiring"
8
8
  require "badline/vic20/user_via_ports"
9
- require "badline/vic20/vic"
10
- require "badline/vic20/sound"
9
+ require "badline/chips/vic_i"
10
+ require "badline/chips/vic_i/sound"
11
11
  require "badline/vic20/saved_state"
12
12
 
13
13
  module Badline
@@ -36,6 +36,11 @@ module Badline
36
36
 
37
37
  def ram = @bus.ram
38
38
 
39
+ # Reads and writes memory as the CPU sees it, through the bus.
40
+ def peek(addr) = @bus.peek(addr)
41
+
42
+ def poke(addr, value) = @bus.poke(addr, value)
43
+
39
44
  def family = :vic20
40
45
 
41
46
  # The one control port's joystick, which the front end's second
@@ -48,26 +53,26 @@ module Badline
48
53
  # +ram+ names the RAM expansion, one of Bus::RAM_CONFIGURATIONS.
49
54
  def initialize(ram: :unexpanded, debug: false)
50
55
  @ram_configuration = ram
51
- @vic = VIC.new
52
- @keyboard = Keyboard.new(matrix: KeyboardVIAPorts::MATRIX)
53
- @joystick1 = Joystick.new
54
- @iec_bus = IECBus.new
55
- @datasette = Datasette.new
56
- @via1 = VIA.new(start: 0x9000, peripheral: UserVIAPorts.new(joystick: @joystick1, serial_bus: @iec_bus,
57
- datasette: @datasette))
56
+ @vic = Chips::VICI.new
57
+ @keyboard = Input::Keyboard.new(matrix: KeyboardVIAPorts::MATRIX)
58
+ @joystick1 = Input::Joystick.new
59
+ @iec_bus = Drives::SerialBus.new
60
+ @datasette = Drives::Datasette.new
61
+ @via1 = Chips::VIA.new(start: 0x9000, peripheral: UserVIAPorts.new(joystick: @joystick1, serial_bus: @iec_bus,
62
+ datasette: @datasette))
58
63
  keyboard_ports = KeyboardVIAPorts.new(keyboard: @keyboard, joystick: @joystick1)
59
- @via2 = VIA.new(start: 0x9000, peripheral: keyboard_ports)
64
+ @via2 = Chips::VIA.new(start: 0x9000, peripheral: keyboard_ports)
60
65
  keyboard_ports.connect(@via2)
61
66
  @bus = Bus.new(vic: @vic, via1: @via1, via2: @via2, blocks: Bus::RAM_CONFIGURATIONS.fetch(ram))
62
67
  @vic.connect(@bus)
63
68
  @cpu = CPU.new(@bus, debug:)
64
69
  @cycles = 0
65
- @sound = Sound.new(self, @vic.profile.clock_hz)
70
+ @sound = Chips::VICI::Sound.new(self, @vic.profile.clock_hz)
66
71
  @vic.sound = @sound
67
72
  @nmi_asserted = false
68
73
  @init_handlers = []
69
74
  @pending_keys = nil
70
- @drive = nil
75
+ @dos = nil
71
76
  @serial_trap = nil
72
77
  @save_trap = nil
73
78
  @capture_output = nil
@@ -111,7 +116,7 @@ module Badline
111
116
  # xvic draws them.
112
117
  def timing
113
118
  profile = @vic.profile
114
- width = profile.cycles_per_line * VIC::PIXELS_PER_CYCLE
119
+ width = profile.cycles_per_line * Chips::VICI::PIXELS_PER_CYCLE
115
120
  blanked = profile.blanked_lines
116
121
  Timing.new(clock_hz: profile.clock_hz, cycles_per_line: profile.cycles_per_line,
117
122
  lines_per_frame: profile.lines_per_frame,
@@ -148,7 +153,7 @@ module Badline
148
153
  @via1.reset!
149
154
  @via2.reset!
150
155
  via_written
151
- @drive&.reset!
156
+ @dos&.reset!
152
157
  @drive1541&.reset!
153
158
  @drive1581&.reset!
154
159
  @nmi_asserted = false