badline 0.12.0 → 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 (516) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -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 +4 -4
  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} +6 -6
  17. data/lib/badline/c128/bus.rb +30 -51
  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 +18 -72
  27. data/lib/badline/{computer → c64}/attachments.rb +16 -47
  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/c64/common.rb +34 -0
  73. data/lib/badline/c64/kernal_traps.rb +89 -0
  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 +20 -31
  82. data/lib/badline/{computer.rb → c64.rb} +22 -80
  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 +27 -29
  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 +10 -61
  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/{file.rb → file_routine.rb} +1 -1
  262. data/lib/badline/kernal_trap/load.rb +6 -6
  263. data/lib/badline/kernal_trap/save.rb +5 -5
  264. data/lib/badline/kernal_trap/serial.rb +7 -7
  265. data/lib/badline/kernal_trap.rb +2 -3
  266. data/lib/badline/machine/clocking.rb +50 -0
  267. data/lib/badline/machine.rb +63 -7
  268. data/lib/badline/media/boot_disk.rb +2 -2
  269. data/lib/badline/media/disk_list.rb +3 -3
  270. data/lib/badline/media/disk_set.rb +1 -1
  271. data/lib/badline/media/extensions.rb +33 -0
  272. data/lib/badline/media/program.rb +28 -0
  273. data/lib/badline/media/true_drive.rb +4 -3
  274. data/lib/badline/media/tune.rb +35 -0
  275. data/lib/badline/media/vic20_cartridge.rb +1 -7
  276. data/lib/badline/media/vic20_media.rb +38 -80
  277. data/lib/badline/media.rb +84 -81
  278. data/lib/badline/model.rb +1 -1
  279. data/lib/badline/options/event.rb +3 -1
  280. data/lib/badline/roms/README +6 -6
  281. data/lib/badline/sdl.rb +1 -0
  282. data/lib/badline/{storage/sid_file.rb → sid_tune/file.rb} +3 -3
  283. data/lib/badline/{storage → sid_tune}/hvsc.rb +7 -7
  284. data/lib/badline/{storage → sid_tune}/song_lengths.rb +2 -2
  285. data/lib/badline/{storage → sid_tune}/stil/credit.rb +1 -1
  286. data/lib/badline/{storage → sid_tune}/stil.rb +3 -3
  287. data/lib/badline/sid_tune.rb +6 -0
  288. data/lib/badline/snapshot/c128_setup.rb +43 -0
  289. data/lib/badline/snapshot/c64_setup.rb +79 -0
  290. data/lib/badline/snapshot/image.rb +5 -25
  291. data/lib/badline/snapshot/machine_state.rb +10 -2
  292. data/lib/badline/snapshot/setup.rb +22 -66
  293. data/lib/badline/snapshot/state.rb +8 -17
  294. data/lib/badline/snapshot/storage_setup.rb +68 -0
  295. data/lib/badline/snapshot/vic20_setup.rb +37 -0
  296. data/lib/badline/snapshot/vice/c64_mem.rb +1 -1
  297. data/lib/badline/snapshot/vice/restore.rb +1 -1
  298. data/lib/badline/snapshot/vice/reu1764.rb +1 -1
  299. data/lib/badline/snapshot/vice/reu_fields.rb +40 -0
  300. data/lib/badline/snapshot/vice.rb +7 -5
  301. data/lib/badline/snapshot.rb +13 -12
  302. data/lib/badline/storage/d64_image.rb +15 -9
  303. data/lib/badline/storage/d71_image.rb +0 -2
  304. data/lib/badline/storage/d81_image.rb +0 -2
  305. data/lib/badline/storage/disk_image/writing.rb +2 -2
  306. data/lib/badline/storage/disk_image.rb +3 -6
  307. data/lib/badline/storage/g64_image.rb +2 -2
  308. data/lib/badline/storage/host_directory.rb +0 -5
  309. data/lib/badline/storage/t64.rb +2 -8
  310. data/lib/badline/storage/unavailable.rb +1 -1
  311. data/lib/badline/storage.rb +0 -37
  312. data/lib/badline/support/c128_checkpoint.rb +39 -0
  313. data/lib/badline/support/checkpoint.rb +108 -0
  314. data/lib/badline/support/vic20_checkpoint.rb +38 -0
  315. data/lib/badline/support.rb +5 -0
  316. data/lib/badline/version.rb +1 -1
  317. data/lib/badline/vic20/attachments.rb +11 -81
  318. data/lib/badline/vic20/bus/saved_state.rb +35 -0
  319. data/lib/badline/vic20/bus.rb +3 -25
  320. data/lib/badline/vic20/cpu.rb +1 -1
  321. data/lib/badline/vic20/port_wiring.rb +4 -4
  322. data/lib/badline/vic20/saved_state.rb +16 -60
  323. data/lib/badline/vic20/user_via_ports.rb +2 -2
  324. data/lib/badline/vic20.rb +20 -51
  325. metadata +250 -221
  326. data/lib/badline/address_bus/extra_sids.rb +0 -30
  327. data/lib/badline/address_bus/fittings.rb +0 -38
  328. data/lib/badline/address_bus/pla.rb +0 -147
  329. data/lib/badline/address_bus/roms.rb +0 -39
  330. data/lib/badline/address_bus/saved_state.rb +0 -72
  331. data/lib/badline/address_bus/sid_slots.rb +0 -42
  332. data/lib/badline/address_bus.rb +0 -235
  333. data/lib/badline/cartridge/action_replay.rb +0 -126
  334. data/lib/badline/cartridge/atomic_power.rb +0 -24
  335. data/lib/badline/cartridge/bank.rb +0 -81
  336. data/lib/badline/cartridge/comal80.rb +0 -50
  337. data/lib/badline/cartridge/dinamic.rb +0 -34
  338. data/lib/badline/cartridge/easy_flash.rb +0 -145
  339. data/lib/badline/cartridge/epyx_fastload.rb +0 -79
  340. data/lib/badline/cartridge/final_cartridge3.rb +0 -89
  341. data/lib/badline/cartridge/flash.rb +0 -306
  342. data/lib/badline/cartridge/freezer.rb +0 -33
  343. data/lib/badline/cartridge/fun_play.rb +0 -38
  344. data/lib/badline/cartridge/g_mod2.rb +0 -74
  345. data/lib/badline/cartridge/game_system.rb +0 -40
  346. data/lib/badline/cartridge/geo_ram.rb +0 -79
  347. data/lib/badline/cartridge/kcs_power.rb +0 -75
  348. data/lib/badline/cartridge/mach5.rb +0 -32
  349. data/lib/badline/cartridge/magic_desk.rb +0 -30
  350. data/lib/badline/cartridge/ocean.rb +0 -35
  351. data/lib/badline/cartridge/pagefox.rb +0 -68
  352. data/lib/badline/cartridge/retro_replay.rb +0 -320
  353. data/lib/badline/cartridge/rex_utility.rb +0 -29
  354. data/lib/badline/cartridge/rgcd.rb +0 -58
  355. data/lib/badline/cartridge/simons_basic.rb +0 -35
  356. data/lib/badline/cartridge/standard.rb +0 -15
  357. data/lib/badline/cartridge/super_games.rb +0 -48
  358. data/lib/badline/cartridge/westermann.rb +0 -30
  359. data/lib/badline/cartridge/zaxxon.rb +0 -66
  360. data/lib/badline/cartridge.rb +0 -303
  361. data/lib/badline/checkpoint.rb +0 -98
  362. data/lib/badline/cia/fast_forward.rb +0 -60
  363. data/lib/badline/cia/interrupt_register.rb +0 -143
  364. data/lib/badline/cia/serial.rb +0 -275
  365. data/lib/badline/cia/state.rb +0 -47
  366. data/lib/badline/cia/timer.rb +0 -206
  367. data/lib/badline/cia.rb +0 -279
  368. data/lib/badline/color_memory.rb +0 -25
  369. data/lib/badline/computer/kernal_traps.rb +0 -29
  370. data/lib/badline/control_ports.rb +0 -76
  371. data/lib/badline/cpu/addressing.rb +0 -131
  372. data/lib/badline/cpu/boundary.rb +0 -54
  373. data/lib/badline/cpu/core.rb +0 -165
  374. data/lib/badline/cpu/microcode.rb +0 -177
  375. data/lib/badline/cpu/operations.rb +0 -88
  376. data/lib/badline/cpu/saved_state.rb +0 -115
  377. data/lib/badline/cpu/stack_operations.rb +0 -82
  378. data/lib/badline/cpu.rb +0 -10
  379. data/lib/badline/cycleable.rb +0 -38
  380. data/lib/badline/datasette.rb +0 -161
  381. data/lib/badline/drive/core.rb +0 -147
  382. data/lib/badline/drive/fast_serial.rb +0 -73
  383. data/lib/badline/drive/idle.rb +0 -125
  384. data/lib/badline/drive/idle_cpu.rb +0 -28
  385. data/lib/badline/drive/orbit.rb +0 -79
  386. data/lib/badline/drive/serial_lines.rb +0 -73
  387. data/lib/badline/drive/sleep.rb +0 -112
  388. data/lib/badline/drive/vias.rb +0 -84
  389. data/lib/badline/drive/watch.rb +0 -150
  390. data/lib/badline/drive.rb +0 -11
  391. data/lib/badline/drive1541/bus.rb +0 -86
  392. data/lib/badline/drive1541/byte_ready.rb +0 -48
  393. data/lib/badline/drive1541/cpu.rb +0 -11
  394. data/lib/badline/drive1541/disk.rb +0 -318
  395. data/lib/badline/drive1541/disk_state.rb +0 -94
  396. data/lib/badline/drive1541/disk_via.rb +0 -36
  397. data/lib/badline/drive1541/gcr.rb +0 -57
  398. data/lib/badline/drive1541/mechanism.rb +0 -313
  399. data/lib/badline/drive1541/mechanism_state.rb +0 -68
  400. data/lib/badline/drive1541/rotation.rb +0 -121
  401. data/lib/badline/drive1541/sector_reader.rb +0 -76
  402. data/lib/badline/drive1541/serial_port.rb +0 -18
  403. data/lib/badline/drive1541/track.rb +0 -98
  404. data/lib/badline/drive1541.rb +0 -111
  405. data/lib/badline/drive1571/bus.rb +0 -111
  406. data/lib/badline/drive1571/cpu.rb +0 -11
  407. data/lib/badline/drive1571/serial_port.rb +0 -37
  408. data/lib/badline/drive1571/serial_via.rb +0 -25
  409. data/lib/badline/drive1571/wd1770.rb +0 -120
  410. data/lib/badline/drive1571.rb +0 -175
  411. data/lib/badline/drive1581/bus.rb +0 -137
  412. data/lib/badline/drive1581/cpu.rb +0 -11
  413. data/lib/badline/drive1581/disk.rb +0 -135
  414. data/lib/badline/drive1581/disk_state.rb +0 -87
  415. data/lib/badline/drive1581/mechanism.rb +0 -117
  416. data/lib/badline/drive1581/serial_port.rb +0 -52
  417. data/lib/badline/drive1581/slot.rb +0 -78
  418. data/lib/badline/drive1581/track.rb +0 -100
  419. data/lib/badline/drive1581/track_bytes.rb +0 -75
  420. data/lib/badline/drive1581/wd1772/registers.rb +0 -89
  421. data/lib/badline/drive1581/wd1772/sector_writes.rb +0 -73
  422. data/lib/badline/drive1581/wd1772/sectors.rb +0 -150
  423. data/lib/badline/drive1581/wd1772/state.rb +0 -66
  424. data/lib/badline/drive1581/wd1772/stepping.rb +0 -109
  425. data/lib/badline/drive1581/wd1772/tracks.rb +0 -125
  426. data/lib/badline/drive1581/wd1772/turn.rb +0 -73
  427. data/lib/badline/drive1581/wd1772.rb +0 -216
  428. data/lib/badline/drive1581.rb +0 -233
  429. data/lib/badline/iec_bus.rb +0 -159
  430. data/lib/badline/instruction.rb +0 -334
  431. data/lib/badline/instruction_set/arithmetic.rb +0 -114
  432. data/lib/badline/instruction_set/bitwise.rb +0 -126
  433. data/lib/badline/instruction_set/branch.rb +0 -79
  434. data/lib/badline/instruction_set/flag.rb +0 -63
  435. data/lib/badline/instruction_set/illegal.rb +0 -270
  436. data/lib/badline/instruction_set/inc_dec.rb +0 -69
  437. data/lib/badline/instruction_set/stack.rb +0 -52
  438. data/lib/badline/instruction_set/transfer.rb +0 -137
  439. data/lib/badline/instruction_set.rb +0 -55
  440. data/lib/badline/interrupts.rb +0 -104
  441. data/lib/badline/joystick.rb +0 -25
  442. data/lib/badline/kernal_trap/channel.rb +0 -181
  443. data/lib/badline/keyboard.rb +0 -112
  444. data/lib/badline/ram_expansion/banking.rb +0 -30
  445. data/lib/badline/ram_expansion/plus256k.rb +0 -54
  446. data/lib/badline/ram_expansion/plus60k.rb +0 -43
  447. data/lib/badline/ram_expansion/unexpanded.rb +0 -28
  448. data/lib/badline/ram_expansion.rb +0 -21
  449. data/lib/badline/reu/dma/saved_state.rb +0 -50
  450. data/lib/badline/reu/dma.rb +0 -273
  451. data/lib/badline/reu/ram.rb +0 -107
  452. data/lib/badline/reu/saved_state.rb +0 -80
  453. data/lib/badline/reu/trigger.rb +0 -32
  454. data/lib/badline/reu.rb +0 -289
  455. data/lib/badline/sid/catch_up.rb +0 -120
  456. data/lib/badline/sid/decimator.rb +0 -64
  457. data/lib/badline/sid/envelope/state.rb +0 -68
  458. data/lib/badline/sid/envelope.rb +0 -239
  459. data/lib/badline/sid/filter.rb +0 -263
  460. data/lib/badline/sid/voice.rb +0 -77
  461. data/lib/badline/sid/waveform/combined.rb +0 -126
  462. data/lib/badline/sid/waveform/fast_forward.rb +0 -105
  463. data/lib/badline/sid/waveform/noise_writeback.rb +0 -122
  464. data/lib/badline/sid/waveform/state.rb +0 -66
  465. data/lib/badline/sid/waveform.rb +0 -305
  466. data/lib/badline/sid.rb +0 -303
  467. data/lib/badline/time_of_day.rb +0 -228
  468. data/lib/badline/traps.rb +0 -19
  469. data/lib/badline/via/control_lines.rb +0 -122
  470. data/lib/badline/via/fast_forward.rb +0 -53
  471. data/lib/badline/via/interrupt_register.rb +0 -67
  472. data/lib/badline/via/shift_register.rb +0 -180
  473. data/lib/badline/via/state.rb +0 -42
  474. data/lib/badline/via/timer1.rb +0 -131
  475. data/lib/badline/via/timer2.rb +0 -133
  476. data/lib/badline/via.rb +0 -266
  477. data/lib/badline/vic/bank.rb +0 -133
  478. data/lib/badline/vic/border_mask.rb +0 -86
  479. data/lib/badline/vic/collisions.rb +0 -115
  480. data/lib/badline/vic/color_patches.rb +0 -47
  481. data/lib/badline/vic/display_state.rb +0 -185
  482. data/lib/badline/vic/graphics_mode.rb +0 -164
  483. data/lib/badline/vic/graphics_shifter.rb +0 -207
  484. data/lib/badline/vic/register_log.rb +0 -81
  485. data/lib/badline/vic/registers.rb +0 -195
  486. data/lib/badline/vic/sequencer.rb +0 -275
  487. data/lib/badline/vic/sequencer_output.rb +0 -116
  488. data/lib/badline/vic/sequencer_state.rb +0 -89
  489. data/lib/badline/vic/sprite/internal_bus.rb +0 -68
  490. data/lib/badline/vic/sprite/saved_state.rb +0 -64
  491. data/lib/badline/vic/sprite/shifter.rb +0 -146
  492. data/lib/badline/vic/sprite/timing.rb +0 -56
  493. data/lib/badline/vic/sprite.rb +0 -337
  494. data/lib/badline/vic/sprites.rb +0 -282
  495. data/lib/badline/vic/sprites_state.rb +0 -57
  496. data/lib/badline/vic.rb +0 -852
  497. data/lib/badline/vic20/sound/output.rb +0 -83
  498. data/lib/badline/vic20/sound.rb +0 -233
  499. data/lib/badline/z80/arithmetic.rb +0 -117
  500. data/lib/badline/z80/bit_page.rb +0 -55
  501. data/lib/badline/z80/block_io.rb +0 -58
  502. data/lib/badline/z80/block_transfers.rb +0 -59
  503. data/lib/badline/z80/bus_cycles.rb +0 -111
  504. data/lib/badline/z80/core.rb +0 -113
  505. data/lib/badline/z80/exchanges.rb +0 -50
  506. data/lib/badline/z80/extended_page.rb +0 -89
  507. data/lib/badline/z80/flags.rb +0 -37
  508. data/lib/badline/z80/interrupt_acceptance.rb +0 -46
  509. data/lib/badline/z80/jumps.rb +0 -82
  510. data/lib/badline/z80/loads.rb +0 -98
  511. data/lib/badline/z80/main_page.rb +0 -134
  512. data/lib/badline/z80/registers.rb +0 -120
  513. data/lib/badline/z80/saved_state.rb +0 -69
  514. data/lib/badline/z80/shifts.rb +0 -64
  515. data/lib/badline/z80.rb +0 -11
  516. /data/lib/badline/snapshot/{fields.rb → vice/fields.rb} +0 -0
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Badline
4
- module Storage
4
+ module SIDTune
5
5
  # HVSC's subtune length database. Each tune gets a comment naming its path
6
6
  # and a line keyed by the MD5 of the whole `.sid` file, holding one
7
7
  # `m:ss` time per subtune, optionally down to milliseconds:
@@ -23,7 +23,7 @@ module Badline
23
23
  # The tune's per-subtune lengths in seconds, or nil when it isn't listed.
24
24
  def lengths(md5)
25
25
  prefix = "#{md5.downcase}="
26
- File.foreach(@path) do |line|
26
+ ::File.foreach(@path) do |line|
27
27
  next unless line.start_with?(prefix)
28
28
 
29
29
  return line[prefix.length..].split.map { |time| seconds(time) }
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Badline
4
- module Storage
4
+ module SIDTune
5
5
  class STIL
6
6
  # A TITLE in a STIL entry, the tune a subtune covers, with the ARTIST
7
7
  # after it, and the stretch of the subtune it covers when the title
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "badline/storage/stil/credit"
3
+ require "badline/sid_tune/stil/credit"
4
4
 
5
5
  module Badline
6
- module Storage
6
+ module SIDTune
7
7
  # HVSC's SID Tune Information List, `DOCUMENTS/STIL.txt`: covers,
8
8
  # subtune names and composers' comments, keyed by each tune's HVSC path.
9
9
  # An entry holds fields for the whole file, then a block per subtune
@@ -89,7 +89,7 @@ module Badline
89
89
  def entry(hvsc_path) = entries[hvsc_path]
90
90
 
91
91
  def entries
92
- @entries ||= parse(Storage.latin1(File.binread(@path).bytes))
92
+ @entries ||= parse(Storage.latin1(::File.binread(@path).bytes))
93
93
  end
94
94
 
95
95
  private
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "badline/sid_tune/file"
4
+ require "badline/sid_tune/hvsc"
5
+ require "badline/sid_tune/song_lengths"
6
+ require "badline/sid_tune/stil"
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Snapshot
5
+ # How a C128 was built: its model's name, its SID's model and the
6
+ # mode it resets into, the arguments C128.new takes.
7
+ C128Setup = Data.define(:model, :sid_model, :mode)
8
+
9
+ class C128Setup
10
+ MARKER = "C128"
11
+ SID_MODELS = %i[mos6581 mos8580].freeze
12
+ MODES = %i[c64 c128].freeze
13
+
14
+ # The setup a C128's State starts with.
15
+ def self.from(state)
16
+ input = StateReader.new(state)
17
+ input.marker(MARKER)
18
+ input.check_stamp
19
+ read(input)
20
+ end
21
+
22
+ def self.read(input)
23
+ model = input.string
24
+ known = C128::Model::ALL.any? { |candidate| candidate.name == model }
25
+ raise FormatError, "the state names a C128 model badline doesn't know" unless known
26
+
27
+ sid_model = SID_MODELS.fetch(input.int)
28
+ new(model:, sid_model:, mode: MODES.fetch(input.int))
29
+ rescue IndexError
30
+ raise FormatError, "the state names a SID or a mode badline doesn't know"
31
+ end
32
+
33
+ def write(out)
34
+ out.string(model).int(SID_MODELS.index(sid_model)).int(MODES.index(mode))
35
+ end
36
+
37
+ # A machine built this way, at power-on.
38
+ def build = C128.new(model:, sid_model:, mode:)
39
+
40
+ def to_s = [model, sid_model, mode].join(" with a ")
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,79 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Snapshot
5
+ # How a C64 was built: its VIC, CIA and SID models, its region, its
6
+ # RAM expansion, the size of its REU, its KERNAL, whether it has a
7
+ # datasette and its board, the arguments C64.new takes.
8
+ C64Setup = Data.define(:vic_model, :cia_model, :sid_model, :region, :ram_expansion, :reu, :kernal, :datasette,
9
+ :board)
10
+
11
+ class C64Setup
12
+ MARKER = "COMPUTER"
13
+ SID_MODELS = %i[mos6581 mos8580].freeze
14
+ REGIONS = [Region::PAL, Region::NTSC, Region::NTSC_OLD, Region::DREAN].freeze
15
+ RAM_EXPANSIONS = [:none, *C64::BankedRAM::TYPES.keys].freeze
16
+ KERNALS = C64::Bus::ROMs::KERNALS.keys.freeze
17
+ BOARDS = C64::Bus::Fittings::BOARDS
18
+
19
+ def self.of(address_bus)
20
+ new(vic_model: address_bus.vic.model, cia_model: address_bus.cia1.model, sid_model: address_bus.sid.model,
21
+ region: address_bus.region, ram_expansion: address_bus.ram_expansion.type, reu: address_bus.reu&.size_kb,
22
+ kernal: address_bus.kernal, datasette: address_bus.datasette.connected?, board: address_bus.board)
23
+ end
24
+
25
+ # The setup a C64's State starts with.
26
+ def self.from(state)
27
+ input = StateReader.new(state)
28
+ input.marker(MARKER)
29
+ input.check_stamp
30
+ read(input)
31
+ end
32
+
33
+ def self.read(input)
34
+ new(vic_model: Chips::VIC::MODELS.fetch(input.int), cia_model: Chips::CIA::MODELS.fetch(input.int),
35
+ sid_model: SID_MODELS.fetch(input.int), region: REGIONS.fetch(input.int),
36
+ ram_expansion: ram_expansion(RAM_EXPANSIONS.fetch(input.int)), reu: reu(input.int),
37
+ kernal: KERNALS.fetch(input.int), datasette: input.boolean?, board: BOARDS.fetch(input.int))
38
+ rescue IndexError
39
+ raise FormatError, "the state names a chip model, region, RAM expansion, KERNAL or board badline doesn't know"
40
+ end
41
+
42
+ def self.ram_expansion(name) = name == :none ? nil : name
43
+
44
+ # An REU's size in K, written as 0 for none.
45
+ def self.reu(size_kb)
46
+ return nil if size_kb.zero?
47
+ return size_kb if C64::REU::SIZES_KB.include?(size_kb)
48
+
49
+ raise FormatError, "the state names a #{size_kb}K REU, which badline doesn't build"
50
+ end
51
+
52
+ def write(out)
53
+ out.int(Chips::VIC::MODELS.index(vic_model)).int(Chips::CIA::MODELS.index(cia_model))
54
+ out.int(SID_MODELS.index(sid_model)).int(REGIONS.index(region))
55
+ out.int(RAM_EXPANSIONS.index(ram_expansion || :none)).int(reu || 0)
56
+ out.int(KERNALS.index(kernal)).boolean(datasette).int(BOARDS.index(board))
57
+ end
58
+
59
+ # A machine built this way, at power-on.
60
+ def build
61
+ C64.new(vic_model:, cia_model:, sid_model:, region:, ram_expansion:, reu:, kernal:, datasette:, board:)
62
+ end
63
+
64
+ # The chips, led by the model's name when they make one of
65
+ # Badline::Model's.
66
+ def to_s
67
+ model = Model.of(self)
68
+ parts = [vic_model, cia_model, sid_model, region.name]
69
+ parts.unshift(model.name) if model
70
+ parts << ram_expansion if ram_expansion
71
+ parts << "a #{reu}K REU" if reu
72
+ parts << "the #{kernal} KERNAL" unless kernal == :c64
73
+ parts << "no datasette" unless datasette
74
+ parts << "the #{board} board" unless board == :c64
75
+ parts.join(", ")
76
+ end
77
+ end
78
+ end
79
+ end
@@ -25,13 +25,13 @@ module Badline
25
25
  # A new machine, built as the snapshot's was and restored from it. A
26
26
  # badline snapshot restores from its BADLINE module alone, which
27
27
  # carries everything its VICE modules do, and a VICE one through the
28
- # modules badline reads. Yields a line for each thing left out, or
29
- # warns it without a block.
28
+ # modules badline reads. xvic's and x128's own modules aren't read.
29
+ # Yields a line for each thing left out, or warns it without a block.
30
30
  def load(&)
31
- return load_vic20(&) if vic20?
32
- return load_c128(&) if c128?
31
+ raise FormatError, "badline reads only its own VIC-20 snapshots, not xvic's" if vic20? && !badline?
32
+ raise FormatError, "badline reads only its own C128 snapshots, not x128's" if c128? && !badline?
33
33
 
34
- computer = badline? ? opening { Computer.restored(state) } : Vice.setup(@container).build
34
+ computer = badline? ? opening { Setup.restored(state) } : Vice.setup(@container).build
35
35
  tell(badline? ? state_report(computer) : Vice::Restore.apply(@container, computer), &)
36
36
  computer
37
37
  end
@@ -54,26 +54,6 @@ module Badline
54
54
 
55
55
  def section = @container[MachineState::NAME]
56
56
 
57
- # A VIC-20 restores from its BADLINE module alone. xvic's own modules
58
- # aren't read.
59
- def load_vic20(&)
60
- raise FormatError, "badline reads only its own VIC-20 snapshots, not xvic's" unless badline?
61
-
62
- machine = Vic20.restored(state)
63
- tell(state_report(machine), &)
64
- machine
65
- end
66
-
67
- # A C128 restores from its BADLINE module alone. x128's own modules
68
- # aren't read.
69
- def load_c128(&)
70
- raise FormatError, "badline reads only its own C128 snapshots, not x128's" unless badline?
71
-
72
- machine = C128.restored(state)
73
- tell(state_report(machine), &)
74
- machine
75
- end
76
-
77
57
  def tell(report)
78
58
  report.ignored.each { |line| block_given? ? yield(line) : warn("badline: #{line}") }
79
59
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Badline
4
4
  module Snapshot
5
- # The BADLINE module: a State from Computer#snapshot, which restores the
5
+ # The BADLINE module: a State from C64#snapshot, which restores the
6
6
  # machine exactly where it was saved. VICE skips a module it doesn't
7
7
  # know.
8
8
  #
@@ -19,6 +19,10 @@ module Badline
19
19
  MAJOR = 2
20
20
  MINOR = 0
21
21
 
22
+ # The values a 64-bit integer holds once encode doubles them, which a
23
+ # native build's integers can't exceed.
24
+ VALUES = (-(1 << 62))..((1 << 62) - 1)
25
+
22
26
  module_function
23
27
 
24
28
  def section(state)
@@ -41,7 +45,11 @@ module Badline
41
45
  strings = state.strings
42
46
  numbers = [values.length, strings.length]
43
47
  strings.each { |string| numbers << string.bytesize }
44
- values.each { |value| numbers << (value.negative? ? (-2 * value) - 1 : 2 * value) }
48
+ values.each do |value|
49
+ raise RangeError, "#{value} is too large for a snapshot" unless VALUES.cover?(value)
50
+
51
+ numbers << (value.negative? ? (-2 * value) - 1 : 2 * value)
52
+ end
45
53
  index = numbers.pack("w*")
46
54
  [index.bytesize].pack("V") + index + strings.join
47
55
  end
@@ -1,75 +1,31 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "badline/snapshot/c64_setup"
4
+ require "badline/snapshot/vic20_setup"
5
+ require "badline/snapshot/c128_setup"
6
+
3
7
  module Badline
4
8
  module Snapshot
5
- # How a machine was built: its VIC, CIA and SID models, its region, its
6
- # RAM expansion, the size of its REU, its KERNAL, whether it has a
7
- # datasette and its board, the arguments Computer.new takes. A State
8
- # starts with them, so a machine to restore it into can be built first.
9
- Setup = Data.define(:vic_model, :cia_model, :sid_model, :region, :ram_expansion, :reu, :kernal, :datasette,
10
- :board)
11
-
12
- class Setup
13
- SID_MODELS = %i[mos6581 mos8580].freeze
14
- REGIONS = [Region::PAL, Region::NTSC, Region::NTSC_OLD, Region::DREAN].freeze
15
- RAM_EXPANSIONS = [:none, *RAMExpansion::TYPES.keys].freeze
16
- KERNALS = AddressBus::ROMs::KERNALS.keys.freeze
17
- BOARDS = AddressBus::Fittings::BOARDS
18
-
19
- def self.of(address_bus)
20
- new(vic_model: address_bus.vic.model, cia_model: address_bus.cia1.model, sid_model: address_bus.sid.model,
21
- region: address_bus.region, ram_expansion: address_bus.ram_expansion.type, reu: address_bus.reu&.size_kb,
22
- kernal: address_bus.kernal, datasette: address_bus.datasette.connected?, board: address_bus.board)
23
- end
24
-
25
- # Layout 3 has no KERNAL or datasette, and stands for the C64's, and
26
- # layouts before 6 have no board, and stand for the C64's.
27
- def self.read(input)
28
- new(vic_model: VIC::MODELS.fetch(input.int), cia_model: CIA::MODELS.fetch(input.int),
29
- sid_model: SID_MODELS.fetch(input.int), region: REGIONS.fetch(input.int),
30
- ram_expansion: ram_expansion(RAM_EXPANSIONS.fetch(input.int)), reu: reu(input.int),
31
- kernal: input.schema > 3 ? KERNALS.fetch(input.int) : :c64,
32
- datasette: input.schema > 3 ? input.boolean? : true,
33
- board: input.schema > 5 ? BOARDS.fetch(input.int) : :c64)
34
- rescue IndexError
35
- raise FormatError, "the state names a chip model, region, RAM expansion, KERNAL or board badline doesn't know"
36
- end
37
-
38
- def self.ram_expansion(name) = name == :none ? nil : name
39
-
40
- # An REU's size in K, written as 0 for none.
41
- def self.reu(size_kb)
42
- return nil if size_kb.zero?
43
- return size_kb if REU::SIZES_KB.include?(size_kb)
44
-
45
- raise FormatError, "the state names a #{size_kb}K REU, which badline doesn't build"
46
- end
47
-
48
- def write(out)
49
- out.int(VIC::MODELS.index(vic_model)).int(CIA::MODELS.index(cia_model))
50
- out.int(SID_MODELS.index(sid_model)).int(REGIONS.index(region))
51
- out.int(RAM_EXPANSIONS.index(ram_expansion || :none)).int(reu || 0)
52
- out.int(KERNALS.index(kernal)).boolean(datasette).int(BOARDS.index(board))
9
+ # How the machine a State was taken of was built, so a machine to
10
+ # restore it into can be built first. A State starts with its family's
11
+ # marker, the stamp (StateWriter#stamp) and the family's setup:
12
+ # C64Setup, Vic20Setup or C128Setup. Each reads its setup from a State
13
+ # (.from) or from the fields after the stamp (.read), writes it
14
+ # (#write), builds a machine that way at power-on (#build) and names it
15
+ # (#to_s).
16
+ module Setup
17
+ # The setup of the family whose marker the State starts with.
18
+ def self.read(state)
19
+ family = StateReader.new(state).string
20
+ return Vic20Setup.from(state) if family == Vic20Setup::MARKER
21
+ return C128Setup.from(state) if family == C128Setup::MARKER
22
+
23
+ C64Setup.from(state)
53
24
  end
54
25
 
55
- # A machine built this way, at power-on.
56
- def build
57
- Computer.new(vic_model:, cia_model:, sid_model:, region:, ram_expansion:, reu:, kernal:, datasette:, board:)
58
- end
59
-
60
- # The chips, led by the model's name when they make one of
61
- # Badline::Model's.
62
- def to_s
63
- model = Model.of(self)
64
- parts = [vic_model, cia_model, sid_model, region.name]
65
- parts.unshift(model.name) if model
66
- parts << ram_expansion if ram_expansion
67
- parts << "a #{reu}K REU" if reu
68
- parts << "the #{kernal} KERNAL" unless kernal == :c64
69
- parts << "no datasette" unless datasette
70
- parts << "the #{board} board" unless board == :c64
71
- parts.join(", ")
72
- end
26
+ # A new machine, built as the one a State was taken of, at that
27
+ # state.
28
+ def self.restored(state) = read(state).build.apply_state(state)
73
29
  end
74
30
  end
75
31
  end
@@ -8,18 +8,14 @@ module Badline
8
8
 
9
9
  # A machine's state, held in memory: the Integers each chip writes in
10
10
  # turn, and the byte strings for memories, names and paths. Booleans
11
- # are written as 0 and 1. Computer#snapshot takes one and
12
- # Computer#restore puts it back.
11
+ # are written as 0 and 1. C64#snapshot takes one and
12
+ # C64#restore puts it back.
13
13
  class State
14
14
  # The layout the chips write their fields in. It goes up whenever a
15
15
  # save_state writes something else, so a State in another layout
16
- # fails before anything is read into a machine. Layout 3, without the
17
- # KERNAL and datasette in the setup, layout 4, without the VIA shift
18
- # register's clock delay, layout 5, without the board in the setup,
19
- # layout 6, without the C128's Z80, and layout 7, without a 1581 on the
20
- # serial bus, still read.
21
- SCHEMA = 8
22
- READABLE = [3, 4, 5, 6, 7, SCHEMA].freeze
16
+ # fails before anything is read into a machine. A State only reads in
17
+ # the layout and the badline version that wrote it.
18
+ SCHEMA = 10
23
19
 
24
20
  attr_reader :values, :strings
25
21
 
@@ -109,16 +105,12 @@ module Badline
109
105
  # device 8 serves is left out, and a true drive's disk keeps the
110
106
  # state's tracks without its image file.
111
107
  class StateReader
112
- # The layout check_stamp found.
113
- attr_reader :schema
114
-
115
108
  def initialize(state, detached: false)
116
109
  @values = state.values
117
110
  @strings = state.strings
118
111
  @value = 0
119
112
  @string = 0
120
113
  @detached = detached
121
- @schema = State::SCHEMA
122
114
  end
123
115
 
124
116
  def detached? = @detached
@@ -169,13 +161,12 @@ module Badline
169
161
  raise FormatError, "expected #{name} in the state, found #{found[0, 20].inspect}" unless found == name
170
162
  end
171
163
 
172
- # Fails unless the State was written in a layout this badline reads
173
- # (State::READABLE) by this badline version.
164
+ # Fails unless the State was written in this layout by this badline
165
+ # version.
174
166
  def check_stamp
175
167
  schema = int
176
168
  version = string
177
- @schema = schema
178
- return if State::READABLE.include?(schema) && version == VERSION
169
+ return if schema == State::SCHEMA && version == VERSION
179
170
 
180
171
  raise FormatError, "the state was written by badline #{version.inspect} in layout #{schema}, " \
181
172
  "and this is badline #{VERSION}, layout #{State::SCHEMA}"
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Snapshot
5
+ # The storage device 8 serves through the traps, as a State holds it:
6
+ # its kind, its path and, for an archive or a disk image, its bytes, so
7
+ # it opens again without the host file.
8
+ module StorageSetup
9
+ HOST_DIRECTORY = 0
10
+ D64 = 1
11
+ D71 = 2
12
+ D81 = 3
13
+ T64_ARCHIVE = 4
14
+
15
+ module_function
16
+
17
+ # The same directory by its path, an archive with the bytes it held,
18
+ # or a disk image with its path, whether it is write-protected, and
19
+ # its bytes with the error table after them.
20
+ def write(storage, out)
21
+ if storage.is_a?(Storage::HostDirectory)
22
+ out.int(HOST_DIRECTORY).string(File.expand_path(storage.path))
23
+ elsif storage.is_a?(Storage::T64)
24
+ out.int(T64_ARCHIVE).string(File.expand_path(storage.path)).blob(storage.bytes)
25
+ else
26
+ write_image(storage, out)
27
+ end
28
+ end
29
+
30
+ def write_image(image, out)
31
+ out.int(image_kind(image)).string(File.expand_path(image.path)).boolean(image.read_only?).blob(image.contents)
32
+ end
33
+
34
+ def image_kind(image)
35
+ return D71 if image.is_a?(Storage::D71Image)
36
+ return D64 if image.is_a?(Storage::D64Image)
37
+ return D81 if image.is_a?(Storage::D81Image)
38
+
39
+ raise ArgumentError, "#{image.class} can't go in a snapshot"
40
+ end
41
+
42
+ # Opens the storage `write` wrote: the same directory by its path, an
43
+ # archive with the bytes it held, or a disk image with the bytes it
44
+ # held, writes and all. A detached reader gets the image
45
+ # write-protected, and Storage::Unavailable for a directory.
46
+ def read(input)
47
+ kind = input.int
48
+ path = input.string
49
+ case kind
50
+ when HOST_DIRECTORY then input.detached? ? Storage::Unavailable.new : Storage::HostDirectory.new(path)
51
+ when T64_ARCHIVE then Storage::T64.new(path, bytes: input.blob)
52
+ else read_image(kind, path, input)
53
+ end
54
+ end
55
+
56
+ def read_image(kind, path, input)
57
+ read_only = input.boolean? || input.detached?
58
+ bytes = input.blob
59
+ case kind
60
+ when D64 then Storage::D64Image.new(path, read_only:, bytes:)
61
+ when D71 then Storage::D71Image.new(path, read_only:, bytes:)
62
+ when D81 then Storage::D81Image.new(path, read_only:, bytes:)
63
+ else raise FormatError, "unknown storage #{kind} in the state"
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Snapshot
5
+ # How a VIC-20 was built: its RAM expansion, a key of
6
+ # Vic20::Bus::RAM_CONFIGURATIONS, the argument Vic20.new takes.
7
+ Vic20Setup = Data.define(:ram)
8
+
9
+ class Vic20Setup
10
+ MARKER = "VIC20"
11
+ RAM_CONFIGURATIONS = Vic20::Bus::RAM_CONFIGURATIONS.keys.freeze
12
+
13
+ # The setup a VIC-20's State starts with.
14
+ def self.from(state)
15
+ input = StateReader.new(state)
16
+ input.marker(MARKER)
17
+ input.check_stamp
18
+ read(input)
19
+ end
20
+
21
+ def self.read(input)
22
+ new(ram: RAM_CONFIGURATIONS.fetch(input.int))
23
+ rescue IndexError
24
+ raise FormatError, "the state names a VIC-20 RAM expansion badline doesn't know"
25
+ end
26
+
27
+ def write(out)
28
+ out.int(RAM_CONFIGURATIONS.index(ram))
29
+ end
30
+
31
+ # A machine built this way, at power-on.
32
+ def build = Vic20.new(ram:)
33
+
34
+ def to_s = ram.to_s
35
+ end
36
+ end
37
+ end
@@ -44,7 +44,7 @@ module Badline
44
44
  computer.ram.write(0, fields.bytes(0x10000))
45
45
  fields.skip(3 + 8)
46
46
  charge = FLOATING.sum { |bit| fields.flag? ? bit : 0 }
47
- driven = ddr & AddressBus::PORT_FLOATING
47
+ driven = ddr & C64::Bus::PORT_FLOATING
48
48
  computer.address_bus.restore_port(ddr, data, (data & driven) | (charge & ~driven & 0xff))
49
49
  end
50
50
  end
@@ -25,7 +25,7 @@ module Badline
25
25
  # so nothing it was doing carries into the snapshot's machine.
26
26
  def import(container, computer)
27
27
  setup = Vice.setup(container)
28
- ours = Setup.of(computer.address_bus)
28
+ ours = C64Setup.of(computer.address_bus)
29
29
  raise FormatError, "the snapshot is of a machine with #{setup}, not #{ours}" unless setup == ours
30
30
 
31
31
  apply(container, setup.build)
@@ -36,7 +36,7 @@ module Badline
36
36
  # The REU's size in K, which builds the machine.
37
37
  def size_kb(section)
38
38
  size = FieldReader.new(section).dword
39
- return size if REU::SIZES_KB.include?(size)
39
+ return size if C64::REU::SIZES_KB.include?(size)
40
40
 
41
41
  raise FormatError, "#{section}: a #{size}K REU, which badline doesn't build"
42
42
  end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ class REU
6
+ # The REU as VICE's REU1764 module holds it (Snapshot::Vice::REU1764):
7
+ # the registers as they read from $DF00, and the RAM.
8
+ module ViceFields
9
+ # The sixteen bytes the REC's registers read from $DF00, without
10
+ # what reading the status does, as VICE's REU1764 module holds them.
11
+ def register_file = Array.new(16) { |register| register_value(register) }
12
+
13
+ # Sets the registers from a register file, as writing them would but
14
+ # without starting a transfer: each address and the length set both
15
+ # the counter and the value it starts from. A command with the
16
+ # execute bit set and the $FF00 trigger on arms the REC.
17
+ def restore_registers(values)
18
+ @status = (values[STATUS] & (INTERRUPT_PENDING | END_OF_BLOCK | FAULT)) | @chips
19
+ @command = values[COMMAND]
20
+ @c64 = @c64_start = values[C64_LOW] | (values[C64_HIGH] << 8)
21
+ @expansion = @expansion_start = values[EXPANSION_LOW] | (values[EXPANSION_HIGH] << 8)
22
+ @bank = @bank_start = values[EXPANSION_BANK] & @bank_bits
23
+ @length = @length_start = values[LENGTH_LOW] | (values[LENGTH_HIGH] << 8)
24
+ @interrupt_mask = values[INTERRUPT_MASK] | 0x1f
25
+ @address_control = values[ADDRESS_CONTROL] | 0x3f
26
+ @armed = @command.anybits?(EXECUTE) && @command.nobits?(NO_FF00_TRIGGER)
27
+ @requested = @running = @ba_was_low = false
28
+ interrupt(@status.anybits?(INTERRUPT_PENDING))
29
+ end
30
+
31
+ # The RAM, every byte of it, as one string.
32
+ def ram_contents = @ram.contents
33
+
34
+ def restore_ram(bytes) = @ram.restore(bytes)
35
+ end
36
+
37
+ include ViceFields
38
+ end
39
+ end
40
+ end
@@ -1,11 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "badline/snapshot/vice/fields"
3
4
  require "badline/snapshot/vice/main_cpu"
4
5
  require "badline/snapshot/vice/c64_mem"
5
6
  require "badline/snapshot/vice/cias"
6
7
  require "badline/snapshot/vice/cias_import"
7
8
  require "badline/snapshot/vice/sid_registers"
8
9
  require "badline/snapshot/vice/sid_extended"
10
+ require "badline/snapshot/vice/reu_fields"
9
11
  require "badline/snapshot/vice/reu1764"
10
12
  require "badline/snapshot/vice/peripherals"
11
13
  require "badline/snapshot/vice/vicii"
@@ -47,7 +49,7 @@ module Badline
47
49
  # The copy is detached from the host's files (Snapshot::StateReader),
48
50
  # so it reads none and its traps write none.
49
51
  def self.settled(state)
50
- copy = Computer.restored(state, detached: true)
52
+ copy = C64.restored(state, detached: true)
51
53
  (BOUNDARY_CYCLES + TRANSFER_CYCLES).times do
52
54
  break if copy.cpu.boundary? && !copy.reu&.dma?
53
55
 
@@ -67,10 +69,10 @@ module Badline
67
69
  sid = container[SIDRegisters::NAME] ? SIDRegisters.model(container[SIDRegisters::NAME]) : :mos6581
68
70
  reu = container[REU1764::NAME]
69
71
  reu = nil unless reu && REU1764.reads?(reu)
70
- Setup.new(vic_model: model, cia_model: model == :mos8565 ? :mos6526a : :mos6526, sid_model: sid,
71
- region: vic ? VICII.region(vic) : Region::PAL, ram_expansion: nil,
72
- reu: reu ? REU1764.size_kb(reu) : nil, kernal: :c64, datasette: true,
73
- board: :c64)
72
+ C64Setup.new(vic_model: model, cia_model: model == :mos8565 ? :mos6526a : :mos6526, sid_model: sid,
73
+ region: vic ? VICII.region(vic) : Region::PAL, ram_expansion: nil,
74
+ reu: reu ? REU1764.size_kb(reu) : nil, kernal: :c64, datasette: true,
75
+ board: :c64)
74
76
  end
75
77
  end
76
78
  end