badline 0.12.1 → 0.14.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 (565) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -1
  3. data/CLAUDE.md +86 -38
  4. data/CONTRIBUTING.md +4 -3
  5. data/README.md +9 -6
  6. data/doc/library.md +9 -9
  7. data/doc/media.md +2 -1
  8. data/doc/pinned-behaviour.md +134 -105
  9. data/doc/snapshot-format.md +1047 -0
  10. data/doc/snapshots.md +73 -43
  11. data/lib/badline/audio/bare_player.rb +53 -20
  12. data/lib/badline/audio/cli.rb +6 -6
  13. data/lib/badline/audio/jukebox.rb +2 -2
  14. data/lib/badline/audio/machine_player.rb +16 -10
  15. data/lib/badline/{media → audio}/queue.rb +1 -1
  16. data/lib/badline/audio/queued_tune.rb +6 -6
  17. data/lib/badline/audio/renderer.rb +33 -22
  18. data/lib/badline/audio/stereo.rb +1 -1
  19. data/lib/badline/c128/banks.rb +6 -3
  20. data/lib/badline/c128/bus/keyed_state.rb +45 -0
  21. data/lib/badline/c128/bus.rb +35 -20
  22. data/lib/badline/c128/color_lines.rb +2 -2
  23. data/lib/badline/c128/cpu.rb +1 -1
  24. data/lib/badline/c128/drives.rb +14 -34
  25. data/lib/badline/c128/fast_serial.rb +5 -5
  26. data/lib/badline/c128/keyed_modules.rb +117 -0
  27. data/lib/badline/c128/keyed_state.rb +91 -0
  28. data/lib/badline/c128/keys.rb +9 -0
  29. data/lib/badline/c128/mmu.rb +9 -8
  30. data/lib/badline/c128/mmu_pages.rb +21 -1
  31. data/lib/badline/c128/modes.rb +21 -11
  32. data/lib/badline/c128/z80.rb +2 -2
  33. data/lib/badline/c128/z80_turns.rb +1 -1
  34. data/lib/badline/c128.rb +21 -16
  35. data/lib/badline/c64/attachments.rb +42 -0
  36. data/lib/badline/c64/banked_ram/banking.rb +32 -0
  37. data/lib/badline/c64/banked_ram/plus256k.rb +64 -0
  38. data/lib/badline/c64/banked_ram/plus60k.rb +47 -0
  39. data/lib/badline/c64/banked_ram/unexpanded.rb +30 -0
  40. data/lib/badline/c64/banked_ram.rb +23 -0
  41. data/lib/badline/c64/bus/debug_register.rb +32 -0
  42. data/lib/badline/c64/bus/extra_sids.rb +32 -0
  43. data/lib/badline/c64/bus/fittings.rb +40 -0
  44. data/lib/badline/c64/bus/keyed_state.rb +41 -0
  45. data/lib/badline/c64/bus/pla.rb +149 -0
  46. data/lib/badline/c64/bus/roms.rb +41 -0
  47. data/lib/badline/c64/bus/sid_slots.rb +44 -0
  48. data/lib/badline/c64/bus.rb +219 -0
  49. data/lib/badline/c64/cartridge/action_replay.rb +115 -0
  50. data/lib/badline/c64/cartridge/atomic_power.rb +26 -0
  51. data/lib/badline/c64/cartridge/bank.rb +83 -0
  52. data/lib/badline/c64/cartridge/comal80.rb +52 -0
  53. data/lib/badline/c64/cartridge/dinamic.rb +36 -0
  54. data/lib/badline/c64/cartridge/easy_flash.rb +132 -0
  55. data/lib/badline/c64/cartridge/epyx_fastload.rb +73 -0
  56. data/lib/badline/c64/cartridge/final_cartridge3.rb +79 -0
  57. data/lib/badline/c64/cartridge/flash.rb +279 -0
  58. data/lib/badline/c64/cartridge/freezer.rb +35 -0
  59. data/lib/badline/c64/cartridge/fun_play.rb +40 -0
  60. data/lib/badline/c64/cartridge/g_mod2.rb +64 -0
  61. data/lib/badline/c64/cartridge/game_system.rb +42 -0
  62. data/lib/badline/c64/cartridge/geo_ram.rb +65 -0
  63. data/lib/badline/c64/cartridge/kcs_power.rb +69 -0
  64. data/lib/badline/c64/cartridge/keyed_state.rb +393 -0
  65. data/lib/badline/c64/cartridge/mach5.rb +34 -0
  66. data/lib/badline/c64/cartridge/magic_desk.rb +32 -0
  67. data/lib/badline/c64/cartridge/ocean.rb +37 -0
  68. data/lib/badline/c64/cartridge/pagefox.rb +60 -0
  69. data/lib/badline/c64/cartridge/retro_replay.rb +278 -0
  70. data/lib/badline/c64/cartridge/rex_utility.rb +31 -0
  71. data/lib/badline/c64/cartridge/rgcd.rb +50 -0
  72. data/lib/badline/c64/cartridge/simons_basic.rb +37 -0
  73. data/lib/badline/c64/cartridge/standard.rb +17 -0
  74. data/lib/badline/c64/cartridge/super_games.rb +40 -0
  75. data/lib/badline/c64/cartridge/westermann.rb +32 -0
  76. data/lib/badline/c64/cartridge/zaxxon.rb +52 -0
  77. data/lib/badline/c64/cartridge.rb +232 -0
  78. data/lib/badline/c64/color_memory.rb +27 -0
  79. data/lib/badline/{computer → c64}/common.rb +2 -2
  80. data/lib/badline/{computer → c64}/kernal_traps.rb +39 -36
  81. data/lib/badline/c64/keyed_modules.rb +111 -0
  82. data/lib/badline/c64/keyed_state.rb +68 -0
  83. data/lib/badline/c64/reu/dma.rb +271 -0
  84. data/lib/badline/c64/reu/keyed_state.rb +140 -0
  85. data/lib/badline/c64/reu/ram.rb +94 -0
  86. data/lib/badline/c64/reu/trigger.rb +34 -0
  87. data/lib/badline/c64/reu.rb +289 -0
  88. data/lib/badline/c64/true_drives.rb +120 -0
  89. data/lib/badline/{computer.rb → c64.rb} +24 -15
  90. data/lib/badline/chips/cia/fast_forward.rb +62 -0
  91. data/lib/badline/chips/cia/interrupt_register.rb +128 -0
  92. data/lib/badline/chips/cia/keyed_parts.rb +213 -0
  93. data/lib/badline/chips/cia/serial.rb +246 -0
  94. data/lib/badline/chips/cia/time_of_day.rb +210 -0
  95. data/lib/badline/chips/cia/timer.rb +188 -0
  96. data/lib/badline/chips/cia.rb +281 -0
  97. data/lib/badline/chips/cpu/addressing.rb +133 -0
  98. data/lib/badline/chips/cpu/boundary.rb +56 -0
  99. data/lib/badline/chips/cpu/core.rb +183 -0
  100. data/lib/badline/chips/cpu/instruction.rb +338 -0
  101. data/lib/badline/chips/cpu/instruction_set/arithmetic.rb +118 -0
  102. data/lib/badline/chips/cpu/instruction_set/bitwise.rb +130 -0
  103. data/lib/badline/chips/cpu/instruction_set/branch.rb +83 -0
  104. data/lib/badline/chips/cpu/instruction_set/flag.rb +67 -0
  105. data/lib/badline/chips/cpu/instruction_set/illegal.rb +274 -0
  106. data/lib/badline/chips/cpu/instruction_set/inc_dec.rb +73 -0
  107. data/lib/badline/chips/cpu/instruction_set/stack.rb +56 -0
  108. data/lib/badline/chips/cpu/instruction_set/transfer.rb +141 -0
  109. data/lib/badline/chips/cpu/instruction_set.rb +59 -0
  110. data/lib/badline/chips/cpu/interrupts.rb +108 -0
  111. data/lib/badline/chips/cpu/keyed_state.rb +177 -0
  112. data/lib/badline/chips/cpu/microcode.rb +195 -0
  113. data/lib/badline/chips/cpu/operations.rb +90 -0
  114. data/lib/badline/chips/cpu/port.rb +133 -0
  115. data/lib/badline/chips/cpu/stack_operations.rb +84 -0
  116. data/lib/badline/chips/cpu/traps.rb +23 -0
  117. data/lib/badline/chips/cpu.rb +17 -0
  118. data/lib/badline/chips/sid/catch_up.rb +122 -0
  119. data/lib/badline/chips/sid/decimator.rb +68 -0
  120. data/lib/badline/chips/sid/envelope.rb +236 -0
  121. data/lib/badline/chips/sid/filter.rb +227 -0
  122. data/lib/badline/chips/sid/keyed_parts.rb +286 -0
  123. data/lib/badline/chips/sid/voice.rb +69 -0
  124. data/lib/badline/chips/sid/waveform/combined.rb +128 -0
  125. data/lib/badline/chips/sid/waveform/fast_forward.rb +107 -0
  126. data/lib/badline/chips/sid/waveform/noise_writeback.rb +124 -0
  127. data/lib/badline/chips/sid/waveform.rb +305 -0
  128. data/lib/badline/chips/sid.rb +264 -0
  129. data/lib/badline/chips/ted/beam.rb +119 -0
  130. data/lib/badline/chips/ted/timers.rb +66 -0
  131. data/lib/badline/chips/ted.rb +143 -0
  132. data/lib/badline/chips/tia.rb +49 -0
  133. data/lib/badline/chips/vdc/keyed_parts.rb +105 -0
  134. data/lib/badline/{c128 → chips}/vdc/memory.rb +1 -1
  135. data/lib/badline/{c128 → chips}/vdc/painter.rb +1 -13
  136. data/lib/badline/{c128 → chips}/vdc/raster.rb +1 -17
  137. data/lib/badline/{c128 → chips}/vdc/window.rb +1 -10
  138. data/lib/badline/{c128 → chips}/vdc.rb +6 -31
  139. data/lib/badline/chips/via/control_lines.rb +109 -0
  140. data/lib/badline/chips/via/fast_forward.rb +55 -0
  141. data/lib/badline/chips/via/interrupt_register.rb +60 -0
  142. data/lib/badline/chips/via/keyed_parts.rb +163 -0
  143. data/lib/badline/chips/via/shift_register.rb +168 -0
  144. data/lib/badline/chips/via/timer1.rb +120 -0
  145. data/lib/badline/chips/via/timer2.rb +117 -0
  146. data/lib/badline/chips/via.rb +267 -0
  147. data/lib/badline/chips/vic/bank.rb +135 -0
  148. data/lib/badline/chips/vic/border_mask.rb +78 -0
  149. data/lib/badline/chips/vic/collisions.rb +106 -0
  150. data/lib/badline/chips/vic/color_patches.rb +38 -0
  151. data/lib/badline/chips/vic/display_state.rb +168 -0
  152. data/lib/badline/chips/vic/graphics_mode.rb +166 -0
  153. data/lib/badline/chips/vic/graphics_shifter.rb +183 -0
  154. data/lib/badline/chips/vic/keyed_parts.rb +228 -0
  155. data/lib/badline/chips/vic/keyed_sprites.rb +225 -0
  156. data/lib/badline/chips/vic/keyed_state.rb +102 -0
  157. data/lib/badline/chips/vic/register_log.rb +65 -0
  158. data/lib/badline/chips/vic/registers.rb +188 -0
  159. data/lib/badline/chips/vic/sequencer.rb +275 -0
  160. data/lib/badline/chips/vic/sequencer_output.rb +118 -0
  161. data/lib/badline/chips/vic/sprite/internal_bus.rb +59 -0
  162. data/lib/badline/chips/vic/sprite/shifter.rb +148 -0
  163. data/lib/badline/chips/vic/sprite/timing.rb +58 -0
  164. data/lib/badline/chips/vic/sprite.rb +337 -0
  165. data/lib/badline/chips/vic/sprites.rb +281 -0
  166. data/lib/badline/chips/vic.rb +787 -0
  167. data/lib/badline/chips/vic_i/keyed_parts.rb +142 -0
  168. data/lib/badline/{vic20/vic → chips/vic_i}/painter.rb +2 -30
  169. data/lib/badline/chips/vic_i/sound/output.rb +85 -0
  170. data/lib/badline/chips/vic_i/sound.rb +227 -0
  171. data/lib/badline/{vic20/vic → chips/vic_i}/text_window.rb +2 -2
  172. data/lib/badline/{vic20/vic.rb → chips/vic_i.rb} +6 -6
  173. data/lib/badline/chips/z80/arithmetic.rb +119 -0
  174. data/lib/badline/chips/z80/bit_page.rb +57 -0
  175. data/lib/badline/chips/z80/block_io.rb +60 -0
  176. data/lib/badline/chips/z80/block_transfers.rb +61 -0
  177. data/lib/badline/chips/z80/bus_cycles.rb +113 -0
  178. data/lib/badline/chips/z80/core.rb +115 -0
  179. data/lib/badline/chips/z80/exchanges.rb +52 -0
  180. data/lib/badline/chips/z80/extended_page.rb +91 -0
  181. data/lib/badline/chips/z80/flags.rb +39 -0
  182. data/lib/badline/chips/z80/interrupt_acceptance.rb +48 -0
  183. data/lib/badline/chips/z80/jumps.rb +84 -0
  184. data/lib/badline/chips/z80/keyed_state.rb +73 -0
  185. data/lib/badline/chips/z80/loads.rb +100 -0
  186. data/lib/badline/chips/z80/main_page.rb +136 -0
  187. data/lib/badline/chips/z80/registers.rb +122 -0
  188. data/lib/badline/chips/z80/shifts.rb +66 -0
  189. data/lib/badline/chips/z80.rb +13 -0
  190. data/lib/badline/chips.rb +10 -0
  191. data/lib/badline/core.rb +13 -32
  192. data/lib/badline/drives/datasette/keyed_state.rb +38 -0
  193. data/lib/badline/drives/datasette.rb +173 -0
  194. data/lib/badline/drives/engine/core.rb +152 -0
  195. data/lib/badline/drives/engine/fast_serial.rb +75 -0
  196. data/lib/badline/drives/engine/idle.rb +127 -0
  197. data/lib/badline/drives/engine/idle_cpu.rb +30 -0
  198. data/lib/badline/drives/engine/orbit.rb +81 -0
  199. data/lib/badline/drives/engine/serial_lines.rb +72 -0
  200. data/lib/badline/drives/engine/sleep.rb +114 -0
  201. data/lib/badline/drives/engine/vias.rb +86 -0
  202. data/lib/badline/drives/engine/watch.rb +152 -0
  203. data/lib/badline/drives/engine.rb +11 -0
  204. data/lib/badline/drives/model1541/bus.rb +75 -0
  205. data/lib/badline/drives/model1541/byte_ready.rb +50 -0
  206. data/lib/badline/drives/model1541/cpu.rb +13 -0
  207. data/lib/badline/drives/model1541/disk.rb +318 -0
  208. data/lib/badline/drives/model1541/disk_via.rb +38 -0
  209. data/lib/badline/drives/model1541/gcr.rb +59 -0
  210. data/lib/badline/drives/model1541/keyed_state.rb +251 -0
  211. data/lib/badline/drives/model1541/mechanism.rb +313 -0
  212. data/lib/badline/drives/model1541/rotation.rb +123 -0
  213. data/lib/badline/drives/model1541/sector_reader.rb +78 -0
  214. data/lib/badline/drives/model1541/serial_port.rb +20 -0
  215. data/lib/badline/drives/model1541/track.rb +100 -0
  216. data/lib/badline/drives/model1541.rb +80 -0
  217. data/lib/badline/drives/model1571/bus.rb +100 -0
  218. data/lib/badline/drives/model1571/cpu.rb +13 -0
  219. data/lib/badline/drives/model1571/keyed_state.rb +108 -0
  220. data/lib/badline/drives/model1571/serial_port.rb +39 -0
  221. data/lib/badline/drives/model1571/serial_via.rb +27 -0
  222. data/lib/badline/drives/model1571/wd1770.rb +108 -0
  223. data/lib/badline/drives/model1571.rb +141 -0
  224. data/lib/badline/drives/model1581/bus.rb +126 -0
  225. data/lib/badline/drives/model1581/cpu.rb +13 -0
  226. data/lib/badline/drives/model1581/disk.rb +133 -0
  227. data/lib/badline/drives/model1581/keyed_state.rb +280 -0
  228. data/lib/badline/drives/model1581/mechanism.rb +98 -0
  229. data/lib/badline/drives/model1581/serial_port.rb +54 -0
  230. data/lib/badline/drives/model1581/slot.rb +61 -0
  231. data/lib/badline/drives/model1581/track.rb +102 -0
  232. data/lib/badline/drives/model1581/track_bytes.rb +77 -0
  233. data/lib/badline/drives/model1581/wd1772/registers.rb +91 -0
  234. data/lib/badline/drives/model1581/wd1772/sector_writes.rb +75 -0
  235. data/lib/badline/drives/model1581/wd1772/sectors.rb +152 -0
  236. data/lib/badline/drives/model1581/wd1772/stepping.rb +111 -0
  237. data/lib/badline/drives/model1581/wd1772/tracks.rb +127 -0
  238. data/lib/badline/drives/model1581/wd1772/turn.rb +75 -0
  239. data/lib/badline/drives/model1581/wd1772.rb +216 -0
  240. data/lib/badline/drives/model1581.rb +206 -0
  241. data/lib/badline/drives/serial_bus.rb +161 -0
  242. data/lib/badline/drives.rb +8 -0
  243. data/lib/badline/frontend/app.rb +3 -3
  244. data/lib/badline/frontend/boot.rb +4 -4
  245. data/lib/badline/frontend/controls.rb +19 -3
  246. data/lib/badline/frontend/drive_led.rb +44 -21
  247. data/lib/badline/frontend/machine_window.rb +3 -1
  248. data/lib/badline/frontend/menu/menu_dialogs.rb +2 -2
  249. data/lib/badline/frontend/player/filter_view.rb +1 -1
  250. data/lib/badline/frontend/player/player_controller.rb +2 -2
  251. data/lib/badline/frontend/player/player_screen.rb +1 -0
  252. data/lib/badline/frontend/player/theme.rb +7 -7
  253. data/lib/badline/frontend/snapshots.rb +12 -1
  254. data/lib/badline/frontend/timeline.rb +30 -12
  255. data/lib/badline/input/control_ports.rb +78 -0
  256. data/lib/badline/input/joystick.rb +27 -0
  257. data/lib/badline/input/keyboard.rb +114 -0
  258. data/lib/badline/input/matrix_typist.rb +98 -0
  259. data/lib/badline/input.rb +4 -0
  260. data/lib/badline/kernal_trap/chrout.rb +45 -0
  261. data/lib/badline/kernal_trap/{drive → dos}/block_commands.rb +1 -1
  262. data/lib/badline/kernal_trap/dos/channel.rb +156 -0
  263. data/lib/badline/kernal_trap/{drive → dos}/channels.rb +1 -26
  264. data/lib/badline/kernal_trap/{drive → dos}/memory.rb +1 -10
  265. data/lib/badline/kernal_trap/{drive → dos}/parameters.rb +1 -1
  266. data/lib/badline/kernal_trap/{drive → dos}/status.rb +1 -9
  267. data/lib/badline/kernal_trap/{drive → dos}/write_file.rb +1 -19
  268. data/lib/badline/kernal_trap/{drive → dos}/writes.rb +1 -1
  269. data/lib/badline/kernal_trap/{drive.rb → dos.rb} +9 -27
  270. data/lib/badline/kernal_trap/file_routine.rb +4 -4
  271. data/lib/badline/kernal_trap/keyed_state.rb +150 -0
  272. data/lib/badline/kernal_trap/layout.rb +75 -11
  273. data/lib/badline/kernal_trap/load.rb +19 -21
  274. data/lib/badline/kernal_trap/routine.rb +12 -0
  275. data/lib/badline/kernal_trap/save.rb +12 -22
  276. data/lib/badline/kernal_trap/serial.rb +8 -24
  277. data/lib/badline/kernal_trap.rb +3 -2
  278. data/lib/badline/machine/clocking.rb +1 -1
  279. data/lib/badline/machine/keyboard_buffer.rb +49 -0
  280. data/lib/badline/machine/settling.rb +29 -0
  281. data/lib/badline/machine.rb +10 -7
  282. data/lib/badline/media/boot_disk.rb +14 -2
  283. data/lib/badline/media/extensions.rb +10 -0
  284. data/lib/badline/media/true_drive.rb +1 -1
  285. data/lib/badline/media/tune.rb +2 -2
  286. data/lib/badline/media.rb +3 -3
  287. data/lib/badline/memory.rb +3 -6
  288. data/lib/badline/model.rb +1 -1
  289. data/lib/badline/options/family.rb +5 -2
  290. data/lib/badline/options/help.rb +42 -16
  291. data/lib/badline/options/table.rb +2 -0
  292. data/lib/badline/options/validation.rb +2 -0
  293. data/lib/badline/options.rb +6 -1
  294. data/lib/badline/plus4/acia.rb +45 -0
  295. data/lib/badline/plus4/bus.rb +312 -0
  296. data/lib/badline/plus4/cpu.rb +10 -0
  297. data/lib/badline/plus4/cpu_port.rb +93 -0
  298. data/lib/badline/plus4/keyboard_port.rb +51 -0
  299. data/lib/badline/plus4/model.rb +38 -0
  300. data/lib/badline/plus4/user_port.rb +31 -0
  301. data/lib/badline/plus4.rb +164 -0
  302. data/lib/badline/roms/README +44 -6
  303. data/lib/badline/roms/plus4/basic.rom +0 -0
  304. data/lib/badline/roms/plus4/function-high.rom +0 -0
  305. data/lib/badline/roms/plus4/function-low.rom +0 -0
  306. data/lib/badline/roms/plus4/kernal-ntsc.rom +0 -0
  307. data/lib/badline/roms/plus4/kernal-pal.rom +0 -0
  308. data/lib/badline/sdl.rb +1 -0
  309. data/lib/badline/{storage/sid_file.rb → sid_tune/file.rb} +3 -3
  310. data/lib/badline/{storage → sid_tune}/hvsc.rb +7 -7
  311. data/lib/badline/{storage → sid_tune}/song_lengths.rb +2 -2
  312. data/lib/badline/{storage → sid_tune}/stil/credit.rb +1 -1
  313. data/lib/badline/{storage → sid_tune}/stil.rb +3 -3
  314. data/lib/badline/sid_tune.rb +6 -0
  315. data/lib/badline/snapshot/c128_setup.rb +32 -0
  316. data/lib/badline/snapshot/c64_setup.rb +83 -0
  317. data/lib/badline/snapshot/container.rb +4 -0
  318. data/lib/badline/snapshot/field_doc/markdown.rb +112 -0
  319. data/lib/badline/snapshot/field_doc.rb +109 -0
  320. data/lib/badline/snapshot/image.rb +132 -46
  321. data/lib/badline/snapshot/keyed/cursor.rb +40 -0
  322. data/lib/badline/snapshot/keyed/modules.rb +66 -0
  323. data/lib/badline/snapshot/keyed/reader.rb +188 -0
  324. data/lib/badline/snapshot/keyed/recorder.rb +88 -0
  325. data/lib/badline/snapshot/keyed/report.rb +26 -0
  326. data/lib/badline/snapshot/keyed/writer.rb +55 -0
  327. data/lib/badline/snapshot/keyed.rb +64 -0
  328. data/lib/badline/snapshot/machine_state.rb +17 -64
  329. data/lib/badline/snapshot/storage_setup.rb +63 -0
  330. data/lib/badline/snapshot/vic20_setup.rb +28 -0
  331. data/lib/badline/snapshot/vice/c64_mem.rb +1 -1
  332. data/lib/badline/snapshot/vice/restore.rb +1 -1
  333. data/lib/badline/snapshot/vice/reu1764.rb +3 -3
  334. data/lib/badline/snapshot/vice/reu_fields.rb +40 -0
  335. data/lib/badline/snapshot/vice.rb +13 -35
  336. data/lib/badline/snapshot.rb +44 -22
  337. data/lib/badline/storage/crt_file.rb +3 -1
  338. data/lib/badline/storage/d64_image.rb +0 -2
  339. data/lib/badline/storage/d71_image.rb +0 -2
  340. data/lib/badline/storage/d81_image.rb +0 -2
  341. data/lib/badline/storage/disk_image.rb +3 -6
  342. data/lib/badline/storage/g64_image.rb +10 -5
  343. data/lib/badline/storage/host_directory.rb +0 -5
  344. data/lib/badline/storage/t64.rb +2 -8
  345. data/lib/badline/storage/tap.rb +43 -15
  346. data/lib/badline/storage/unavailable.rb +1 -1
  347. data/lib/badline/storage.rb +0 -37
  348. data/lib/badline/support/c128_checkpoint.rb +39 -0
  349. data/lib/badline/support/checkpoint.rb +108 -0
  350. data/lib/badline/support/vic20_checkpoint.rb +38 -0
  351. data/lib/badline/support.rb +5 -0
  352. data/lib/badline/version.rb +1 -1
  353. data/lib/badline/vic20/attachments.rb +8 -5
  354. data/lib/badline/vic20/bus/keyed_state.rb +52 -0
  355. data/lib/badline/vic20/bus.rb +2 -25
  356. data/lib/badline/vic20/cpu.rb +1 -1
  357. data/lib/badline/vic20/keyed_modules.rb +73 -0
  358. data/lib/badline/vic20/keyed_state.rb +45 -0
  359. data/lib/badline/vic20/port_wiring.rb +4 -4
  360. data/lib/badline/vic20/user_via_ports.rb +2 -2
  361. data/lib/badline/vic20.rb +22 -17
  362. data/lib/badline.rb +1 -0
  363. metadata +271 -228
  364. data/lib/badline/address_bus/extra_sids.rb +0 -30
  365. data/lib/badline/address_bus/fittings.rb +0 -38
  366. data/lib/badline/address_bus/pla.rb +0 -147
  367. data/lib/badline/address_bus/roms.rb +0 -39
  368. data/lib/badline/address_bus/saved_state.rb +0 -66
  369. data/lib/badline/address_bus/sid_slots.rb +0 -42
  370. data/lib/badline/address_bus.rb +0 -216
  371. data/lib/badline/c128/bus_state.rb +0 -53
  372. data/lib/badline/c128/saved_state.rb +0 -143
  373. data/lib/badline/cartridge/action_replay.rb +0 -126
  374. data/lib/badline/cartridge/atomic_power.rb +0 -24
  375. data/lib/badline/cartridge/bank.rb +0 -81
  376. data/lib/badline/cartridge/comal80.rb +0 -50
  377. data/lib/badline/cartridge/dinamic.rb +0 -34
  378. data/lib/badline/cartridge/easy_flash.rb +0 -145
  379. data/lib/badline/cartridge/epyx_fastload.rb +0 -79
  380. data/lib/badline/cartridge/final_cartridge3.rb +0 -89
  381. data/lib/badline/cartridge/flash.rb +0 -306
  382. data/lib/badline/cartridge/freezer.rb +0 -33
  383. data/lib/badline/cartridge/fun_play.rb +0 -38
  384. data/lib/badline/cartridge/g_mod2.rb +0 -74
  385. data/lib/badline/cartridge/game_system.rb +0 -40
  386. data/lib/badline/cartridge/geo_ram.rb +0 -79
  387. data/lib/badline/cartridge/kcs_power.rb +0 -75
  388. data/lib/badline/cartridge/mach5.rb +0 -32
  389. data/lib/badline/cartridge/magic_desk.rb +0 -30
  390. data/lib/badline/cartridge/ocean.rb +0 -35
  391. data/lib/badline/cartridge/pagefox.rb +0 -68
  392. data/lib/badline/cartridge/retro_replay.rb +0 -320
  393. data/lib/badline/cartridge/rex_utility.rb +0 -29
  394. data/lib/badline/cartridge/rgcd.rb +0 -58
  395. data/lib/badline/cartridge/simons_basic.rb +0 -35
  396. data/lib/badline/cartridge/standard.rb +0 -15
  397. data/lib/badline/cartridge/super_games.rb +0 -48
  398. data/lib/badline/cartridge/westermann.rb +0 -30
  399. data/lib/badline/cartridge/zaxxon.rb +0 -66
  400. data/lib/badline/cartridge.rb +0 -303
  401. data/lib/badline/checkpoint.rb +0 -98
  402. data/lib/badline/chrout_trap.rb +0 -43
  403. data/lib/badline/cia/fast_forward.rb +0 -60
  404. data/lib/badline/cia/interrupt_register.rb +0 -143
  405. data/lib/badline/cia/serial.rb +0 -275
  406. data/lib/badline/cia/state.rb +0 -47
  407. data/lib/badline/cia/timer.rb +0 -206
  408. data/lib/badline/cia.rb +0 -279
  409. data/lib/badline/color_memory.rb +0 -25
  410. data/lib/badline/computer/attachments.rb +0 -88
  411. data/lib/badline/computer/saved_state.rb +0 -117
  412. data/lib/badline/computer/true_drives.rb +0 -69
  413. data/lib/badline/control_ports.rb +0 -76
  414. data/lib/badline/cpu/addressing.rb +0 -131
  415. data/lib/badline/cpu/boundary.rb +0 -54
  416. data/lib/badline/cpu/core.rb +0 -165
  417. data/lib/badline/cpu/microcode.rb +0 -177
  418. data/lib/badline/cpu/operations.rb +0 -88
  419. data/lib/badline/cpu/saved_state.rb +0 -115
  420. data/lib/badline/cpu/stack_operations.rb +0 -82
  421. data/lib/badline/cpu.rb +0 -10
  422. data/lib/badline/cpu_port.rb +0 -112
  423. data/lib/badline/datasette.rb +0 -161
  424. data/lib/badline/debug_register.rb +0 -28
  425. data/lib/badline/drive/core.rb +0 -147
  426. data/lib/badline/drive/fast_serial.rb +0 -73
  427. data/lib/badline/drive/idle.rb +0 -125
  428. data/lib/badline/drive/idle_cpu.rb +0 -28
  429. data/lib/badline/drive/orbit.rb +0 -79
  430. data/lib/badline/drive/serial_lines.rb +0 -73
  431. data/lib/badline/drive/sleep.rb +0 -112
  432. data/lib/badline/drive/vias.rb +0 -84
  433. data/lib/badline/drive/watch.rb +0 -150
  434. data/lib/badline/drive.rb +0 -11
  435. data/lib/badline/drive1541/bus.rb +0 -86
  436. data/lib/badline/drive1541/byte_ready.rb +0 -48
  437. data/lib/badline/drive1541/cpu.rb +0 -11
  438. data/lib/badline/drive1541/disk.rb +0 -315
  439. data/lib/badline/drive1541/disk_state.rb +0 -86
  440. data/lib/badline/drive1541/disk_via.rb +0 -36
  441. data/lib/badline/drive1541/gcr.rb +0 -57
  442. data/lib/badline/drive1541/mechanism.rb +0 -313
  443. data/lib/badline/drive1541/mechanism_state.rb +0 -68
  444. data/lib/badline/drive1541/rotation.rb +0 -121
  445. data/lib/badline/drive1541/sector_reader.rb +0 -76
  446. data/lib/badline/drive1541/serial_port.rb +0 -18
  447. data/lib/badline/drive1541/track.rb +0 -98
  448. data/lib/badline/drive1541.rb +0 -111
  449. data/lib/badline/drive1571/bus.rb +0 -111
  450. data/lib/badline/drive1571/cpu.rb +0 -11
  451. data/lib/badline/drive1571/serial_port.rb +0 -37
  452. data/lib/badline/drive1571/serial_via.rb +0 -25
  453. data/lib/badline/drive1571/wd1770.rb +0 -120
  454. data/lib/badline/drive1571.rb +0 -175
  455. data/lib/badline/drive1581/bus.rb +0 -137
  456. data/lib/badline/drive1581/cpu.rb +0 -11
  457. data/lib/badline/drive1581/disk.rb +0 -135
  458. data/lib/badline/drive1581/disk_state.rb +0 -87
  459. data/lib/badline/drive1581/mechanism.rb +0 -117
  460. data/lib/badline/drive1581/serial_port.rb +0 -52
  461. data/lib/badline/drive1581/slot.rb +0 -78
  462. data/lib/badline/drive1581/track.rb +0 -100
  463. data/lib/badline/drive1581/track_bytes.rb +0 -75
  464. data/lib/badline/drive1581/wd1772/registers.rb +0 -89
  465. data/lib/badline/drive1581/wd1772/sector_writes.rb +0 -73
  466. data/lib/badline/drive1581/wd1772/sectors.rb +0 -150
  467. data/lib/badline/drive1581/wd1772/state.rb +0 -66
  468. data/lib/badline/drive1581/wd1772/stepping.rb +0 -109
  469. data/lib/badline/drive1581/wd1772/tracks.rb +0 -125
  470. data/lib/badline/drive1581/wd1772/turn.rb +0 -73
  471. data/lib/badline/drive1581/wd1772.rb +0 -216
  472. data/lib/badline/drive1581.rb +0 -233
  473. data/lib/badline/iec_bus.rb +0 -159
  474. data/lib/badline/instruction.rb +0 -334
  475. data/lib/badline/instruction_set/arithmetic.rb +0 -114
  476. data/lib/badline/instruction_set/bitwise.rb +0 -126
  477. data/lib/badline/instruction_set/branch.rb +0 -79
  478. data/lib/badline/instruction_set/flag.rb +0 -63
  479. data/lib/badline/instruction_set/illegal.rb +0 -270
  480. data/lib/badline/instruction_set/inc_dec.rb +0 -69
  481. data/lib/badline/instruction_set/stack.rb +0 -52
  482. data/lib/badline/instruction_set/transfer.rb +0 -137
  483. data/lib/badline/instruction_set.rb +0 -55
  484. data/lib/badline/interrupts.rb +0 -104
  485. data/lib/badline/joystick.rb +0 -25
  486. data/lib/badline/kernal_trap/channel.rb +0 -181
  487. data/lib/badline/keyboard.rb +0 -112
  488. data/lib/badline/keyboard_buffer.rb +0 -33
  489. data/lib/badline/ram_expansion/banking.rb +0 -30
  490. data/lib/badline/ram_expansion/plus256k.rb +0 -54
  491. data/lib/badline/ram_expansion/plus60k.rb +0 -43
  492. data/lib/badline/ram_expansion/unexpanded.rb +0 -28
  493. data/lib/badline/ram_expansion.rb +0 -21
  494. data/lib/badline/reu/dma/saved_state.rb +0 -50
  495. data/lib/badline/reu/dma.rb +0 -273
  496. data/lib/badline/reu/ram.rb +0 -107
  497. data/lib/badline/reu/saved_state.rb +0 -80
  498. data/lib/badline/reu/trigger.rb +0 -32
  499. data/lib/badline/reu.rb +0 -289
  500. data/lib/badline/sid/catch_up.rb +0 -120
  501. data/lib/badline/sid/decimator.rb +0 -64
  502. data/lib/badline/sid/envelope/state.rb +0 -68
  503. data/lib/badline/sid/envelope.rb +0 -239
  504. data/lib/badline/sid/filter.rb +0 -263
  505. data/lib/badline/sid/voice.rb +0 -77
  506. data/lib/badline/sid/waveform/combined.rb +0 -126
  507. data/lib/badline/sid/waveform/fast_forward.rb +0 -105
  508. data/lib/badline/sid/waveform/noise_writeback.rb +0 -122
  509. data/lib/badline/sid/waveform/state.rb +0 -66
  510. data/lib/badline/sid/waveform.rb +0 -305
  511. data/lib/badline/sid.rb +0 -303
  512. data/lib/badline/snapshot/setup.rb +0 -75
  513. data/lib/badline/snapshot/state.rb +0 -189
  514. data/lib/badline/time_of_day.rb +0 -228
  515. data/lib/badline/traps.rb +0 -19
  516. data/lib/badline/via/control_lines.rb +0 -122
  517. data/lib/badline/via/fast_forward.rb +0 -53
  518. data/lib/badline/via/interrupt_register.rb +0 -67
  519. data/lib/badline/via/shift_register.rb +0 -180
  520. data/lib/badline/via/state.rb +0 -42
  521. data/lib/badline/via/timer1.rb +0 -131
  522. data/lib/badline/via/timer2.rb +0 -133
  523. data/lib/badline/via.rb +0 -266
  524. data/lib/badline/vic/bank.rb +0 -133
  525. data/lib/badline/vic/border_mask.rb +0 -86
  526. data/lib/badline/vic/collisions.rb +0 -115
  527. data/lib/badline/vic/color_patches.rb +0 -47
  528. data/lib/badline/vic/display_state.rb +0 -185
  529. data/lib/badline/vic/graphics_mode.rb +0 -164
  530. data/lib/badline/vic/graphics_shifter.rb +0 -207
  531. data/lib/badline/vic/register_log.rb +0 -81
  532. data/lib/badline/vic/registers.rb +0 -195
  533. data/lib/badline/vic/sequencer.rb +0 -275
  534. data/lib/badline/vic/sequencer_output.rb +0 -116
  535. data/lib/badline/vic/sequencer_state.rb +0 -89
  536. data/lib/badline/vic/sprite/internal_bus.rb +0 -68
  537. data/lib/badline/vic/sprite/saved_state.rb +0 -64
  538. data/lib/badline/vic/sprite/shifter.rb +0 -146
  539. data/lib/badline/vic/sprite/timing.rb +0 -56
  540. data/lib/badline/vic/sprite.rb +0 -337
  541. data/lib/badline/vic/sprites.rb +0 -282
  542. data/lib/badline/vic/sprites_state.rb +0 -57
  543. data/lib/badline/vic.rb +0 -853
  544. data/lib/badline/vic20/saved_state.rb +0 -124
  545. data/lib/badline/vic20/sound/output.rb +0 -83
  546. data/lib/badline/vic20/sound.rb +0 -233
  547. data/lib/badline/vic20/vic/saved_state.rb +0 -55
  548. data/lib/badline/z80/arithmetic.rb +0 -117
  549. data/lib/badline/z80/bit_page.rb +0 -55
  550. data/lib/badline/z80/block_io.rb +0 -58
  551. data/lib/badline/z80/block_transfers.rb +0 -59
  552. data/lib/badline/z80/bus_cycles.rb +0 -111
  553. data/lib/badline/z80/core.rb +0 -113
  554. data/lib/badline/z80/exchanges.rb +0 -50
  555. data/lib/badline/z80/extended_page.rb +0 -89
  556. data/lib/badline/z80/flags.rb +0 -37
  557. data/lib/badline/z80/interrupt_acceptance.rb +0 -46
  558. data/lib/badline/z80/jumps.rb +0 -82
  559. data/lib/badline/z80/loads.rb +0 -98
  560. data/lib/badline/z80/main_page.rb +0 -134
  561. data/lib/badline/z80/registers.rb +0 -120
  562. data/lib/badline/z80/saved_state.rb +0 -69
  563. data/lib/badline/z80/shifts.rb +0 -64
  564. data/lib/badline/z80.rb +0 -11
  565. /data/lib/badline/snapshot/{fields.rb → vice/fields.rb} +0 -0
data/lib/badline/sid.rb DELETED
@@ -1,303 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "badline/sid/waveform"
4
- require "badline/sid/envelope"
5
- require "badline/sid/voice"
6
- require "badline/sid/filter"
7
- require "badline/sid/decimator"
8
- require "badline/sid/catch_up"
9
-
10
- module Badline
11
- # SID (Sound Interface Device) chip, in either the 6581 or the 8580
12
- # revision.
13
- #
14
- # $D400-$D418 - Voices, filter and volume - write only
15
- # $D419-$D41A - POTX/POTY paddle inputs - read only
16
- # $D41B-$D41C - Voice 3 oscillator/envelope - read only
17
- # $D41D-$D41F - Unconnected
18
- #
19
- # The register file mirrors every 32 bytes up to $D7FF. A second or
20
- # third SID, which only the SID player fits, is built `at` another
21
- # address and decodes just the 32 bytes there.
22
- #
23
- # Reading a write-only or unconnected register returns the last byte the
24
- # SID saw on the data bus. That value fades to $00 as the capacitance
25
- # holding it drains. Paddles and the 1351 mouse attach as a pots source
26
- # responding to #pot_x and #pot_y; with none attached the lines read $FF.
27
- #
28
- # Three voices feed the filter and the master volume; #output and #sample
29
- # read out the mixed result, and #record collects it at an audio rate for
30
- # #drain_samples. The DSP is clocked lazily and catches up when something
31
- # asks for its state.
32
- #
33
- # The 6581 drives its voices well above ground, so the mix carries a large
34
- # DC offset that the RC network on the C64 board filters out.
35
- class SID
36
- include Addressable
37
- include CatchUp
38
-
39
- VOICES = 3
40
-
41
- # Cycles the data bus holds a value, measured through SID/bitfade.
42
- BUS_TTL = { mos6581: 0x1d00, mos8580: 0xa2000 }.freeze
43
-
44
- # Scales the filter's 20-bit mix down to a signed 16-bit sample, as
45
- # reSID 0.16 does: three voices at full swing and volume 15 span the
46
- # whole range, on either chip.
47
- SAMPLE_DIVISOR = ((0xfff * 0xff) >> 7) * 3 * 15 * 2 / (2**16)
48
-
49
- # Writes the DSP queues between catch-ups. A full queue catches up
50
- # there and then, so no write loses its timing.
51
- DEFERRED_WRITES = 0x400
52
-
53
- # Cycles the filter integrates in one step while synthesizing, after
54
- # reSID's delta_t_flt. 1 makes the audio exact, at a per-cycle cost.
55
- FILTER_CHUNK = 4
56
-
57
- attr_accessor :pots
58
- attr_reader :model
59
-
60
- def initialize(model: :mos6581, pots: nil, filter_chunk: FILTER_CHUNK, at: 0xd400)
61
- addressable_at(at, length: at == 0xd400 ? 2**10 : 2**5)
62
- @model = model
63
- @pots = pots
64
- @bus_ttl_reset = BUS_TTL.fetch(model)
65
- @filter = Filter.new(model:)
66
- @synthesizing = false
67
- @stepped = @synced = false
68
- @pending_cycles = 0
69
- @deferred_writes = []
70
- @decimator = nil
71
- @samples = []
72
- @voice_samples = nil
73
- @filter_chunk = filter_chunk
74
- @voices = Voice.linked(VOICES, model:)
75
- @voice1, @voice2, @voice3 = @voices
76
- @waveform1, @waveform2, @waveform3 = @voices.map(&:waveform)
77
- reset!
78
- end
79
-
80
- # Switches the chip, its filter and its voices to the other model's
81
- # values. The cycles already passed run on the old model first, and the
82
- # running state carries over.
83
- def model=(model)
84
- catch_up
85
- @model = model
86
- @bus_ttl_reset = BUS_TTL.fetch(model)
87
- @filter.model = model
88
- @voices.each { |voice| voice.model = model }
89
- update_span_rules
90
- end
91
-
92
- # The RES line clears the registers, the data bus, the filter and the
93
- # voices, all but their accumulators. Recording carries on across it.
94
- def reset!
95
- catch_up
96
- @registers = Memory.new(length: 2**5)
97
- @bus_value = 0x00
98
- @bus_ttl = 0
99
- @voices.each(&:reset!)
100
- @filter.reset
101
- update_span_rules
102
- end
103
-
104
- # The DSP only counts cycles as they pass. Whatever asks for its state
105
- # catches it up, a span at a time: each span fast-forwards the voices
106
- # and ends on one whole cycle, so everything the CPU can read stays
107
- # exact. The filter only runs once something wants audio.
108
- def synthesizing? = @synthesizing
109
-
110
- def synthesize!
111
- return if @synthesizing
112
-
113
- @synthesizing = true
114
- update_span_rules
115
- catch_up
116
- end
117
-
118
- # Starts collecting the output, averaged down to `rate` samples a
119
- # second, for #drain_samples. `filter_chunk` overrides the one the SID
120
- # was built with, for a machine that built its own. `clock_hz` is the
121
- # rate the SID's cycles are taken to run at.
122
- def record(rate:, filter_chunk: @filter_chunk, clock_hz: Region::PAL.clock_hz)
123
- synthesize!
124
- catch_up
125
- @filter_chunk = filter_chunk
126
- @decimator = Decimator.new(clock_hz:, rate:)
127
- @samples = []
128
- end
129
-
130
- # How far the recording has got into the sample it is averaging, for
131
- # a host that carries on recording from a saved state: it calls
132
- # #record, then #load_recording.
133
- def save_recording(out)
134
- decimator = @decimator
135
- raise ArgumentError, "the SID isn't recording" if decimator.nil?
136
-
137
- out.marker("RECORDING")
138
- decimator.save_state(out)
139
- end
140
-
141
- def load_recording(input)
142
- decimator = @decimator
143
- raise ArgumentError, "the SID isn't recording" if decimator.nil?
144
-
145
- input.marker("RECORDING")
146
- decimator.load_state(input)
147
- end
148
-
149
- # Also keeps each voice's own output, before the filter and the volume,
150
- # as each recorded sample closes, for #drain_voice_samples.
151
- def record_voices!
152
- @voice_samples = [] if @voice_samples.nil?
153
- end
154
-
155
- # The voices' outputs since the last drain, three to a sample, in voice
156
- # order, or nothing unless #record_voices! asked for them.
157
- def drain_voice_samples
158
- return [] if @voice_samples.nil?
159
-
160
- catch_up
161
- samples = @voice_samples
162
- @voice_samples = []
163
- samples
164
- end
165
-
166
- # The samples recorded since the last drain.
167
- def drain_samples
168
- catch_up
169
- samples = @samples
170
- @samples = []
171
- samples
172
- end
173
-
174
- def voices
175
- catch_up
176
- @voices
177
- end
178
-
179
- # Runs the DSP up to the current cycle.
180
- def catch_up! = catch_up
181
-
182
- # The byte the data bus holds and the cycles until it fades.
183
- def bus_state = [@bus_value, @bus_ttl]
184
-
185
- def restore_bus(value, ttl)
186
- @bus_value = value
187
- @bus_ttl = ttl
188
- end
189
-
190
- def filter
191
- catch_up
192
- @filter
193
- end
194
-
195
- # Voice 3's oscillator and envelope, the only synthesis state the CPU
196
- # can see. Programs poll OSC3 with the noise waveform selected for
197
- # random numbers, and ENV3 to time hard restarts.
198
- def osc3
199
- catch_up
200
- @waveform3.osc3 >> 4
201
- end
202
-
203
- def env3
204
- catch_up
205
- @voice3.envelope.env3
206
- end
207
-
208
- def output
209
- synthesize!
210
- catch_up
211
- @filter.output
212
- end
213
-
214
- def sample
215
- output
216
- current_sample
217
- end
218
-
219
- def cycle!
220
- age_bus if @bus_ttl != 0
221
- @pending_cycles += 1
222
- end
223
-
224
- def peek(addr)
225
- case offset_of(addr) % (2**5)
226
- when 0x19 then latch(pots ? pots.pot_x : 0xff)
227
- when 0x1a then latch(pots ? pots.pot_y : 0xff)
228
- when 0x1b then latch(osc3)
229
- when 0x1c then latch(env3)
230
- else @bus_value
231
- end
232
- end
233
-
234
- def poke(addr, value)
235
- reg = offset_of(addr) % (2**5)
236
- write_register(reg, value) if reg <= 0x18
237
- latch(value)
238
- end
239
-
240
- # Register contents as written, for save states and debugging.
241
- def register(reg) = @registers.peek(reg)
242
-
243
- # The registers, the data bus, the voices and the filter, and the span
244
- # the DSP has yet to catch up on, as it stands: saving leaves the SID
245
- # as it was. Whether it synthesizes or records is the host's.
246
- def save_state(out)
247
- out.marker("SID")
248
- @registers.save_state(out)
249
- out.int(@bus_value).int(@bus_ttl).int(@pending_cycles).ints(@deferred_writes)
250
- @voices.each { |voice| voice.save_state(out) }
251
- @filter.save_state(out)
252
- end
253
-
254
- def load_state(input)
255
- input.marker("SID")
256
- @registers.load_state(input)
257
- @bus_value = input.int
258
- @bus_ttl = input.int
259
- @pending_cycles = input.int
260
- input.ints_into(@deferred_writes)
261
- @voices.each { |voice| voice.load_state(input) }
262
- @filter.load_state(input)
263
- update_span_rules
264
- end
265
-
266
- private
267
-
268
- def latch(value)
269
- @bus_ttl = @bus_ttl_reset
270
- @bus_value = value
271
- end
272
-
273
- def age_bus
274
- @bus_ttl -= 1
275
- @bus_value = 0x00 if @bus_ttl.zero?
276
- end
277
-
278
- def write_register(reg, value)
279
- @registers.poke(reg, value)
280
- catch_up if @deferred_writes.length == DEFERRED_WRITES * 3
281
- @deferred_writes.push(@pending_cycles, reg, value)
282
- end
283
-
284
- def apply_write(reg, value)
285
- reg < 0x15 ? write_voice(reg, value) : @filter.write(reg, value)
286
- end
287
-
288
- def write_voice(reg, value)
289
- voice = @voices[reg / 7]
290
- case reg % 7
291
- when 0 then voice.waveform.frequency_low = value
292
- when 1 then voice.waveform.frequency_high = value
293
- when 2 then voice.waveform.pulse_width_low = value
294
- when 3 then voice.waveform.pulse_width_high = value
295
- when 4
296
- voice.control = value
297
- update_span_rules
298
- when 5 then voice.envelope.attack_decay = value
299
- when 6 then voice.envelope.sustain_release = value
300
- end
301
- end
302
- end
303
- end
@@ -1,75 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- 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))
53
- end
54
-
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
73
- end
74
- end
75
- end
@@ -1,189 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- module Snapshot
5
- # A file that isn't a snapshot badline reads, is cut short, or holds a
6
- # state that doesn't line up with the machine reading it.
7
- class FormatError < StandardError; end
8
-
9
- # A machine's state, held in memory: the Integers each chip writes in
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.
13
- class State
14
- # The layout the chips write their fields in. It goes up whenever a
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, layout 7, without a 1581 on the
20
- # serial bus, and layout 8, with the VIC's unused cycle count and
21
- # pending-write flag, still read.
22
- SCHEMA = 9
23
- READABLE = [3, 4, 5, 6, 7, 8, SCHEMA].freeze
24
-
25
- attr_reader :values, :strings
26
-
27
- def initialize(values, strings)
28
- @values = values
29
- @strings = strings
30
- end
31
-
32
- def ==(other)
33
- other.is_a?(State) && values == other.values && strings == other.strings
34
- end
35
- end
36
-
37
- # Writes a State. Each chip's save_state writes its fields through one
38
- # of these, and its load_state reads them back from a StateReader in
39
- # the same order.
40
- class StateWriter
41
- attr_reader :state
42
-
43
- def initialize
44
- @values = []
45
- @strings = []
46
- @state = State.new(@values, @strings)
47
- end
48
-
49
- def int(value)
50
- raise TypeError, "not an Integer: #{value.inspect}" unless value.is_a?(Integer)
51
-
52
- @values << value.to_i
53
- self
54
- end
55
-
56
- def boolean(value)
57
- @values << (value ? 1 : 0)
58
- self
59
- end
60
-
61
- def optional_int(value)
62
- return boolean(false) if value.nil?
63
-
64
- boolean(true).int(value)
65
- end
66
-
67
- def ints(values)
68
- int(values.length)
69
- values.each { |value| int(value) }
70
- self
71
- end
72
-
73
- def booleans(values)
74
- int(values.length)
75
- values.each { |value| boolean(value) }
76
- self
77
- end
78
-
79
- # Bytes, 0 to 255 each, kept as one string.
80
- def blob(values)
81
- @strings << values.pack("C*")
82
- self
83
- end
84
-
85
- def string(value)
86
- @strings << value.to_s.b
87
- self
88
- end
89
-
90
- def optional_string(value)
91
- return boolean(false) if value.nil?
92
-
93
- boolean(true).string(value)
94
- end
95
-
96
- # A name a reader checks for, so a state that has gone out of step
97
- # fails there instead of loading the wrong fields.
98
- def marker(name) = string(name)
99
-
100
- # The State's layout and the badline version writing it, which a
101
- # reader checks first (StateReader#check_stamp).
102
- def stamp = int(State::SCHEMA).string(VERSION)
103
- end
104
-
105
- # Reads a State back in the order a StateWriter wrote it.
106
- #
107
- # A detached reader restores a machine that opens no host file and
108
- # writes none, for a copy the machine runs on its own: a disk image
109
- # comes from the bytes the state holds, write-protected, a directory
110
- # device 8 serves is left out, and a true drive's disk keeps the
111
- # state's tracks without its image file.
112
- class StateReader
113
- # The layout check_stamp found.
114
- attr_reader :schema
115
-
116
- def initialize(state, detached: false)
117
- @values = state.values
118
- @strings = state.strings
119
- @value = 0
120
- @string = 0
121
- @detached = detached
122
- @schema = State::SCHEMA
123
- end
124
-
125
- def detached? = @detached
126
-
127
- def int
128
- raise FormatError, "the state ends early, at value #{@value}" if @value >= @values.length
129
-
130
- value = @values[@value]
131
- @value += 1
132
- value
133
- end
134
-
135
- def boolean?
136
- value = int
137
- raise FormatError, "expected a boolean in the state, found #{value}" unless value.between?(0, 1)
138
-
139
- value == 1
140
- end
141
-
142
- def optional_int = boolean? ? int : nil
143
-
144
- def ints = Array.new(int) { int }
145
-
146
- def booleans = Array.new(int) { boolean? }
147
-
148
- # Reads into an existing array, in place, so whatever else holds it
149
- # sees the values.
150
- def ints_into(array) = array.replace(ints)
151
-
152
- def booleans_into(array) = array.replace(booleans)
153
-
154
- def blob = string.bytes
155
-
156
- def blob_into(array) = array.replace(blob)
157
-
158
- def string
159
- raise FormatError, "the state ends early, at string #{@string}" if @string >= @strings.length
160
-
161
- value = @strings[@string]
162
- @string += 1
163
- value
164
- end
165
-
166
- def optional_string = boolean? ? string : nil
167
-
168
- def marker(name)
169
- found = string
170
- raise FormatError, "expected #{name} in the state, found #{found[0, 20].inspect}" unless found == name
171
- end
172
-
173
- # Fails unless the State was written in a layout this badline reads
174
- # (State::READABLE) by this badline version.
175
- def check_stamp
176
- schema = int
177
- version = string
178
- @schema = schema
179
- return if State::READABLE.include?(schema) && version == VERSION
180
-
181
- raise FormatError, "the state was written by badline #{version.inspect} in layout #{schema}, " \
182
- "and this is badline #{VERSION}, layout #{State::SCHEMA}"
183
- end
184
-
185
- # Whether every value and string has been read.
186
- def finished? = @value == @values.length && @string == @strings.length
187
- end
188
- end
189
- end