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
@@ -1,73 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- module Drive
5
- # Fast serial on a drive with a CIA, the 1571's 6526 or the 1581's
6
- # 8520: through buffers a port line turns round, the CIA's CNT drives
7
- # SRQ and its SP drives DATA, or it hears them. The drive pushes its
8
- # pins into the bus as they move, and hears the host's as the host
9
- # pushes them, pin by pin, so each byte goes through both shift
10
- # registers bit by bit. The CIA takes no part in a pass of the idle
11
- # loop, and any access to it, or the host moving its fast serial pins,
12
- # wakes the drive.
13
- #
14
- # A model includes it beside Core, and calls turn_fast_serial when its
15
- # direction line moves and drive_fast_serial each cycle the buffers
16
- # face out. Its serial_output carries @fast_output above its port.
17
- module FastSerial
18
- # Whether the buffers face out, the drive's CIA driving DATA and SRQ.
19
- attr_reader :fast_serial_out
20
-
21
- # The host moved its fast serial pins: the CIA hears SRQ on CNT and
22
- # DATA on SP while the buffers face in.
23
- def fast_lines_moved
24
- settle!
25
- hear_fast_serial unless @fast_serial_out
26
- end
27
-
28
- private
29
-
30
- def init_fast_serial
31
- @fast_serial_out = false
32
- @fast_output = 0
33
- end
34
-
35
- # The buffers turned round: outwards the CIA's pins drive the lines,
36
- # and inwards they let go and hear them.
37
- def turn_fast_serial(out)
38
- @fast_serial_out = out
39
- return unless @serial_bus
40
-
41
- push_fast_output(out ? fast_pins : 0)
42
- hear_fast_serial unless out
43
- end
44
-
45
- def drive_fast_serial
46
- low = fast_pins
47
- push_fast_output(low) if low != @fast_output
48
- end
49
-
50
- # The lines the CIA's CNT and SP pull while its serial port drives
51
- # them.
52
- def fast_pins
53
- serial = @cia.serial
54
- return 0 unless serial.output?
55
-
56
- low = serial.cnt ? 0 : IECBus::DRIVE_FAST_SRQ
57
- serial.sp_out ? low : low | IECBus::DRIVE_FAST_DATA
58
- end
59
-
60
- def push_fast_output(low)
61
- @fast_output = low
62
- @serial_bus&.drives_fast_moved!
63
- end
64
-
65
- def hear_fast_serial
66
- low = @serial_bus.low_lines
67
- serial = @cia.serial
68
- serial.cnt_in = low.nobits?(IECBus::SRQ)
69
- serial.sp_in = low.nobits?(IECBus::DATA)
70
- end
71
- end
72
- end
73
- end
@@ -1,125 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- module Drive
5
- # Skipping the drive's cycles while the DOS idles, exactly.
6
- #
7
- # With nothing to do, the DOS goes round its idle loop from the
8
- # model's @idle_loop ($EBFF in the 1541, 446 cycles a pass), until VIA
9
- # 2's timer 1 interrupts it every 14,850 cycles for the job loop, or
10
- # ATN interrupts it through VIA 1's CA1. A pass writes RAM and VIA 2's
11
- # port B, but puts back what it found, so the drive comes round to the
12
- # loop's start as it left it. Only the timers' counters and the cycle
13
- # counts move.
14
- #
15
- # Each time the CPU comes to the loop's start, the drive records the
16
- # pass that follows. At the next it checks that the pass
17
- #
18
- # - left the CPU, both VIAs but for their counters, the bus's last
19
- # byte, the SO pin, the mechanism (Mechanism#idle_state) and what
20
- # the ports read from it, and every byte of RAM it read or wrote as
21
- # it found them (Bus#watch!)
22
- # - read nothing that changes from pass to pass: no counter, no shift
23
- # register, and not VIA 1's port B, which reads the serial bus
24
- # - wrote nothing that reaches outside the drive: not VIA 1, whose port
25
- # B drives the serial bus, and not the motor on
26
- # - ran while no counter could set a flag (VIA#quiet_cycles), with the
27
- # motor off, no interrupt pulled and no trap on the CPU.
28
- #
29
- # Such a pass runs the same way again from where it ended, for as
30
- # long as ATN holds still and no counter sets a flag, so the drive
31
- # sleeps: host_cycle! only counts the host cycles that go by (see
32
- # Sleep). It wakes
33
- # when ATN moves, when a counter is due to set a flag, or when something
34
- # outside reads or changes the drive (the readers in Core call
35
- # settle!). Waking counts off the whole passes it owes in bulk,
36
- # moving the counters on, and runs the rest cycle by cycle.
37
- #
38
- # The loop reads neither CLK nor DATA, so the drive sleeps through them
39
- # moving and takes the C64's lines as they stand once it wakes. Its
40
- # own lines hold still while it sleeps, so the C64 reads them without
41
- # waking it (serial_output).
42
- #
43
- # A pass starts at the loop's start, where the CPU always comes from
44
- # the loop's last instruction, a JMP, so what that leaves in the CPU's
45
- # working registers is the same each time round.
46
- #
47
- # The timer's interrupts come round too, and once they do, the drive
48
- # sleeps on through them (see Orbit).
49
- module Idle
50
- # Whether the drive may sleep through its idle loop. On by default,
51
- # but for a drive whose CPU logs each instruction.
52
- attr_reader :idle_skip
53
-
54
- def idle_skip=(on)
55
- settle!
56
- @idle_skip = on
57
- end
58
-
59
- private
60
-
61
- def init_idle(debug)
62
- @idle_skip = !debug
63
- @recording = false
64
- @pass_cycles = 0
65
- @pass_instructions = 0
66
- init_sleep
67
- init_orbits
68
- end
69
-
70
- # The CPU is at the loop's start. At an instruction boundary, the
71
- # drive sleeps if the pass it recorded can repeat, and otherwise
72
- # records the next.
73
- def idle_loop_reached
74
- return unless @cpu.boundary?
75
-
76
- if @recording
77
- stop_recording
78
- return fall_asleep if repeatable_pass? && room_for_pass?
79
- end
80
- start_recording
81
- end
82
-
83
- def start_recording
84
- return if busy_for_pass? || @cpu.trapped?
85
-
86
- @recording = true
87
- @record_state = idle_state
88
- @record_cycles = @cycles
89
- @record_instructions = @cpu.instructions
90
- @record_quiet = quiet_cycles
91
- @bus.watch!
92
- end
93
-
94
- def stop_recording
95
- @recording = false
96
- @bus.unwatch!
97
- end
98
-
99
- # Whether the pass just recorded can repeat.
100
- def repeatable_pass?
101
- !@bus.volatile && @cycles - @record_cycles <= @record_quiet && idle_state == @record_state &&
102
- ram_as_found?
103
- end
104
-
105
- # Whether the counters leave room for a whole pass.
106
- def room_for_pass? = quiet_cycles >= @cycles - @record_cycles
107
-
108
- # Sleeps through the pass just recorded, over and over.
109
- def fall_asleep
110
- @pass_cycles = @cycles - @record_cycles
111
- @pass_instructions = @cpu.instructions - @record_instructions
112
- @asleep = true
113
- @host_still = false
114
- @owed = 0
115
- @budget = quiet_cycles
116
- anchor
117
- end
118
-
119
- def ram_as_found?
120
- ram = @bus.ram
121
- @bus.touched.all? { |addr, value| ram.peek(addr) == value }
122
- end
123
- end
124
- end
125
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- module Drive
5
- # What Idle needs of a drive's 6502, which includes it beside
6
- # CPU::Core.
7
- module IdleCPU
8
- # Everything the CPU holds but its cycle and instruction counts: the
9
- # registers, the interrupt lines and pipeline, and what the last
10
- # instruction left in its working registers. Drive::Idle compares
11
- # it at two instruction boundaries.
12
- def idle_state
13
- [@program_counter, @stack_pointer, @a, @x, @y, @status.value,
14
- @irq, @nmi, @irq_sample, @irq_pending, @nmi_sample, @nmi_pending, @skip_poll,
15
- @boundary_irq, @boundary_nmi, @so_high, @interrupt, @brk, @pending_write, @stalled_at, @traps,
16
- @operation, @optional_dummy, @boundary_crossed, @branch_taken,
17
- @address, @pointer, @dummy_address, @value, @rmw_result]
18
- end
19
-
20
- # Counts +cycles+ cycles and +instructions+ instructions that ran
21
- # without changing anything idle_state holds.
22
- def fast_forward(cycles, instructions)
23
- @cycles += cycles
24
- @instructions += instructions
25
- end
26
- end
27
- end
28
- end
@@ -1,79 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- module Drive
5
- # Sleeping through the DOS's timer interrupts, exactly, once they come
6
- # round.
7
- #
8
- # VIA 2's timer 1 interrupts the idle loop for the job loop, which
9
- # finds no job, restarts the timer and returns into the pass it cut
10
- # into, 14,998 cycles and more apart. The interrupts land at a
11
- # different point in the pass each time, until, six of them on, the
12
- # whole drive is back where it was: an orbit of 90,044 cycles.
13
- #
14
- # Each place the drive falls asleep (see Idle) is an anchor, and the
15
- # drive keeps everything it holds at each one: RAM, the counters of
16
- # the timers that are armed or that it read or wrote since, and the
17
- # rest as Idle compares a pass. It keeps them only while it keeps to
18
- # itself, with Bus#guard! checking that it doesn't read the serial
19
- # bus, write VIA 1, turn the motor on or change the LED. ATN moving,
20
- # or a reader settling the drive, forgets them.
21
- #
22
- # Coming to an anchor it kept before closes an orbit, which runs the
23
- # same way again from here for as long as ATN holds still, so the
24
- # drive sleeps on without waking for its counters. Waking counts off
25
- # the whole orbits it owes in bulk, moving on only the counters it
26
- # never touched, and runs the rest as Idle does.
27
- module Orbit
28
- # How many anchors the drive keeps while it looks for an orbit.
29
- ANCHORS = 32
30
-
31
- private
32
-
33
- def init_orbits
34
- @anchors = {}
35
- @orbit_cycles = nil
36
- @orbit_instructions = 0
37
- @bus.guard!
38
- end
39
-
40
- # The drive falls asleep at an anchor. One it came to before closes
41
- # an orbit: everything from there to here runs the same way again.
42
- def anchor
43
- forget_orbits if @bus.tainted || @anchors.size >= ANCHORS
44
- key = anchor_state
45
- if (seen = @anchors[key])
46
- @orbit_cycles = @cycles - seen[0]
47
- @orbit_instructions = @cpu.instructions - seen[1]
48
- else
49
- @anchors[key] = [@cycles, @cpu.instructions]
50
- end
51
- end
52
-
53
- def forget_orbits
54
- @anchors.clear
55
- @orbit_cycles = nil
56
- @bus.guard!
57
- end
58
-
59
- # Runs whole orbits, which bring the drive back to the anchor it
60
- # sleeps at but for the counters it never touched. Returns the
61
- # cycles.
62
- def skip_orbits(orbits)
63
- cycles = orbits * @orbit_cycles
64
- touched = @bus.touched_timers
65
- @cpu.fast_forward(cycles, orbits * @orbit_instructions)
66
- skip_chip_orbits(cycles, touched)
67
- @cycles += cycles
68
- cycles
69
- end
70
-
71
- # Everything the drive holds at an anchor, but for the counters of
72
- # the unarmed timers it hasn't touched since it was last tainted.
73
- def anchor_state
74
- touched = @bus.touched_timers
75
- [*idle_state, *counter_state(touched), @bus.ram.snapshot]
76
- end
77
- end
78
- end
79
- end
@@ -1,73 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- module Drive
5
- # What VIA 1's port B reads from the serial bus. DATA IN (PB0), CLK IN
6
- # (PB2) and ATN IN (PB7) come through inverters, so a released line
7
- # reads 0 and a pulled one 1. The jumpers on PB5 and PB6 pull a line
8
- # low when closed, and both closed make device 8.
9
- #
10
- # The drive sees the host's side of the bus a host cycle late. The
11
- # host's CIA changes its pins at the end of the cycle that writes them,
12
- # and the drive's VIA samples its own late in each of its cycles, so a
13
- # drive cycle that runs alongside the write reads the lines from
14
- # before it. The drive runs after the host in each host cycle (see
15
- # Computer#cycle!), so the port reads the host's lines as latch_host
16
- # took them at the end of the last one. Fast loaders that time their
17
- # transfer from an ATN edge, as VICE's drive tests do, depend on it.
18
- #
19
- # A model's serial port includes it, with its own port A.
20
- module SerialLines
21
- DATA_IN = 0x01
22
- CLK_IN = 0x04
23
- ATN_IN = 0x80
24
- SERIAL_INPUTS = DATA_IN | CLK_IN | ATN_IN
25
- JUMPERS = 0b0110_0000
26
-
27
- attr_reader :bus
28
-
29
- def bus=(bus)
30
- @bus = bus
31
- latch_host
32
- end
33
-
34
- # Takes the host's lines as the machine last pushed them into the bus,
35
- # for the drive cycles of the next host cycle.
36
- def latch_host
37
- @host = @bus.host_lines
38
- end
39
-
40
- # The host's lines as last latched. The jumpers and the bus are the
41
- # drive's wiring.
42
- def save_state(out)
43
- out.int(@host)
44
- end
45
-
46
- def load_state(input)
47
- @host = input.int
48
- end
49
-
50
- # Whether the host has moved ATN since the last latch_host.
51
- def atn_moved? = (@bus.host_lines ^ @host).anybits?(IECBus::HOST_ATN_OUT)
52
-
53
- def atn_low? = @bus.atn_low?(@host)
54
-
55
- def read_b(_lines)
56
- low = @bus.low_lines(@host)
57
- value = @port_b
58
- value |= DATA_IN if low.anybits?(IECBus::DATA)
59
- value |= CLK_IN if low.anybits?(IECBus::CLK)
60
- value |= ATN_IN if low.anybits?(IECBus::ATN)
61
- value
62
- end
63
-
64
- private
65
-
66
- def init_serial_lines(device, bus)
67
- @port_b = (0xff & ~(SERIAL_INPUTS | JUMPERS)) | (((device - 8) & 0x03) << 5)
68
- @host = 0
69
- self.bus = bus
70
- end
71
- end
72
- end
73
- end
@@ -1,112 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- module Drive
5
- # The drive asleep, as Idle and Orbit let it: host_cycle! counts the
6
- # host cycles that go by, and waking turns them into drive cycles
7
- # through the phase accumulator and runs them. Whole orbits and whole
8
- # passes go in bulk, and the rest cycle by cycle, which may find the
9
- # idle loop and put the drive back to sleep.
10
- #
11
- # The drive looks at ATN only when the machine may have moved it, as
12
- # it pushes its lines into the bus (IECBus#host_lines=).
13
- module Sleep
14
- # Whether the drive is skipping its idle loop right now.
15
- def asleep? = @asleep
16
-
17
- # Brings the drive up to the present, cycle for cycle, and drops the
18
- # pass it was recording and the orbits it found, since whoever called
19
- # may change it. Every reader of the drive's parts calls this.
20
- def settle!
21
- if @asleep
22
- wake!
23
- @serial_port.latch_host
24
- @asleep = false
25
- @orbit_cycles = nil
26
- end
27
- stop_recording if @recording
28
- forget_orbits
29
- end
30
-
31
- private
32
-
33
- def init_sleep
34
- @asleep = false
35
- @host_still = false
36
- @owed = 0
37
- @budget = 0
38
- @slept = 0
39
- @wake_at = 0
40
- end
41
-
42
- # A host cycle asleep that may wake the drive. The next ones need no
43
- # look at ATN until the machine pushes its lines again.
44
- def doze
45
- @host_still = true
46
- if @serial_port.atn_moved?
47
- settle!
48
- elsif @slept == @wake_at
49
- wake!
50
- @serial_port.latch_host
51
- plan_wake if @asleep
52
- end
53
- end
54
-
55
- # Asleep, host_cycle! counts host cycles, and leaves it to wake! to
56
- # turn them into drive cycles through the phase accumulator. This sets
57
- # the host cycle that brings the drive cycles owed up to the budget.
58
- # On an orbit the drive sleeps until something outside wakes it:
59
- # @slept counts from 1, so it never comes to 0.
60
- def plan_wake
61
- @slept = 0
62
- return @wake_at = 0 if @orbit_cycles
63
-
64
- needed = ((@budget - @owed) * @host_clock_hz) - @phase
65
- @wake_at = needed.positive? ? (needed + @clock_hz - 1) / @clock_hz : 1
66
- end
67
-
68
- # Runs the cycles owed.
69
- def wake!
70
- phase = @phase + (@slept * @clock_hz)
71
- @phase = phase % @host_clock_hz
72
- owed = @owed + (phase / @host_clock_hz)
73
- @owed = 0
74
- @slept = 0
75
- catch_up(owed)
76
- end
77
-
78
- # Runs +owed+ drive cycles: whole orbits and whole passes in bulk,
79
- # passes only up to the budget, and the rest cycle by cycle, which
80
- # may put the drive back to sleep.
81
- def catch_up(owed)
82
- while owed.positive?
83
- if @asleep
84
- if @orbit_cycles && owed >= @orbit_cycles
85
- owed -= skip_orbits(owed / @orbit_cycles)
86
- next
87
- end
88
- @orbit_cycles = nil
89
- passes = [owed, @budget].min / @pass_cycles
90
- if passes.positive?
91
- owed -= skip_passes(passes)
92
- next
93
- end
94
- @asleep = false
95
- end
96
- run_cycle
97
- owed -= 1
98
- end
99
- end
100
-
101
- # Runs whole passes, moving the counters on. Returns the cycles.
102
- def skip_passes(passes)
103
- cycles = passes * @pass_cycles
104
- @cpu.fast_forward(cycles, passes * @pass_instructions)
105
- fast_forward_chips(cycles)
106
- @cycles += cycles
107
- @budget -= cycles
108
- cycles
109
- end
110
- end
111
- end
112
- end
@@ -1,84 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- module Drive
5
- # The two VIAs the 1541 and the 1571 share: VIA 1 facing the serial
6
- # bus, its CA1 on ATN, and VIA 2 running the GCR Mechanism. A model
7
- # includes it beside Core, and it answers Core's, Idle's and Orbit's
8
- # questions about the chips: what they hold, how long their counters
9
- # leave them quiet, and how to run them a stretch at once. A model with
10
- # more chips on its bus runs them in fast_forward_more.
11
- module VIAs
12
- def via1
13
- settle!
14
- @via1
15
- end
16
-
17
- def via2
18
- settle!
19
- @via2
20
- end
21
-
22
- # Puts in a Disk from the .d64, .g64, .d71 or .g71 image at +path+
23
- # (Drive1541::Disk.open), write-protected with `read_only`.
24
- def insert_image(path, read_only: false)
25
- insert(Drive1541::Disk.open(path, read_only:))
26
- end
27
-
28
- # VIA 1's port B as it drives the serial bus. It holds still while the
29
- # drive sleeps, so reading it leaves the drive asleep.
30
- def serial_output = @via1.port_b_output
31
-
32
- # The serial bus's RESET line reaches the CPU and both VIAs. RAM keeps
33
- # its contents.
34
- def reset!
35
- settle!
36
- @via1.reset!
37
- @via2.reset!
38
- @cpu.reset!
39
- end
40
-
41
- private
42
-
43
- # ATN reaches VIA 1's CA1 as the serial port latched it.
44
- def hear_atn
45
- @via1.ca1 = @serial_port.atn_low?
46
- end
47
-
48
- # Whether the drive is doing anything a pass of the idle loop can't
49
- # repeat: the motor on, or a VIA pulling IRQ.
50
- def busy_for_pass? = @mechanism.motor_on? || @via1.irq? || @via2.irq?
51
-
52
- def quiet_cycles
53
- [@via1.quiet_cycles, @via2.quiet_cycles].min
54
- end
55
-
56
- def idle_state
57
- mechanism = @mechanism
58
- [*@cpu.idle_state, *@via1.idle_state, *@via2.idle_state, @bus.data, mechanism.so_pending,
59
- *mechanism.idle_state, mechanism.read_a(0xff), mechanism.read_b(0xff)]
60
- end
61
-
62
- # The counters an orbit has to bring back (VIA#counter_state).
63
- def counter_state(touched)
64
- [*@via1.counter_state(touched & 0x03), *@via2.counter_state(touched >> 2)]
65
- end
66
-
67
- def fast_forward_chips(cycles)
68
- @via1.fast_forward(cycles)
69
- @via2.fast_forward(cycles)
70
- fast_forward_more(cycles)
71
- end
72
-
73
- def skip_chip_orbits(cycles, touched)
74
- @via1.skip_orbits(cycles, touched & 0x03)
75
- @via2.skip_orbits(cycles, touched >> 2)
76
- fast_forward_more(cycles)
77
- end
78
-
79
- # Runs the model's chips beyond the VIAs +cycles+ quiet cycles at once
80
- # (see quiet_cycles). The 1541 has none.
81
- def fast_forward_more(_cycles) = nil
82
- end
83
- end
84
- end