badline 0.12.1 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (505) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -0
  3. data/CLAUDE.md +59 -31
  4. data/README.md +1 -1
  5. data/doc/library.md +9 -9
  6. data/doc/pinned-behaviour.md +105 -105
  7. data/doc/snapshots.md +1 -4
  8. data/lib/badline/audio/bare_player.rb +3 -3
  9. data/lib/badline/audio/cli.rb +6 -6
  10. data/lib/badline/audio/jukebox.rb +2 -2
  11. data/lib/badline/audio/machine_player.rb +2 -2
  12. data/lib/badline/{media → audio}/queue.rb +1 -1
  13. data/lib/badline/audio/queued_tune.rb +6 -6
  14. data/lib/badline/audio/renderer.rb +5 -5
  15. data/lib/badline/audio/stereo.rb +1 -1
  16. data/lib/badline/c128/{bus_state.rb → bus/saved_state.rb} +1 -1
  17. data/lib/badline/c128/bus.rb +18 -17
  18. data/lib/badline/c128/color_lines.rb +2 -2
  19. data/lib/badline/c128/cpu.rb +1 -1
  20. data/lib/badline/c128/drives.rb +10 -11
  21. data/lib/badline/c128/fast_serial.rb +5 -5
  22. data/lib/badline/c128/mmu_pages.rb +1 -1
  23. data/lib/badline/c128/modes.rb +2 -2
  24. data/lib/badline/c128/saved_state.rb +21 -47
  25. data/lib/badline/c128/z80.rb +2 -2
  26. data/lib/badline/c128.rb +14 -9
  27. data/lib/badline/{computer → c64}/attachments.rb +4 -6
  28. data/lib/badline/c64/banked_ram/banking.rb +32 -0
  29. data/lib/badline/c64/banked_ram/plus256k.rb +56 -0
  30. data/lib/badline/c64/banked_ram/plus60k.rb +45 -0
  31. data/lib/badline/c64/banked_ram/unexpanded.rb +30 -0
  32. data/lib/badline/c64/banked_ram.rb +23 -0
  33. data/lib/badline/c64/bus/extra_sids.rb +32 -0
  34. data/lib/badline/c64/bus/fittings.rb +40 -0
  35. data/lib/badline/c64/bus/pla.rb +149 -0
  36. data/lib/badline/c64/bus/roms.rb +41 -0
  37. data/lib/badline/c64/bus/saved_state.rb +68 -0
  38. data/lib/badline/c64/bus/sid_slots.rb +44 -0
  39. data/lib/badline/c64/bus.rb +218 -0
  40. data/lib/badline/c64/cartridge/action_replay.rb +128 -0
  41. data/lib/badline/c64/cartridge/atomic_power.rb +26 -0
  42. data/lib/badline/c64/cartridge/bank.rb +83 -0
  43. data/lib/badline/c64/cartridge/comal80.rb +52 -0
  44. data/lib/badline/c64/cartridge/dinamic.rb +36 -0
  45. data/lib/badline/c64/cartridge/easy_flash.rb +147 -0
  46. data/lib/badline/c64/cartridge/epyx_fastload.rb +81 -0
  47. data/lib/badline/c64/cartridge/final_cartridge3.rb +91 -0
  48. data/lib/badline/c64/cartridge/flash/saved_state.rb +40 -0
  49. data/lib/badline/c64/cartridge/flash.rb +279 -0
  50. data/lib/badline/c64/cartridge/freezer.rb +35 -0
  51. data/lib/badline/c64/cartridge/fun_play.rb +40 -0
  52. data/lib/badline/c64/cartridge/g_mod2.rb +76 -0
  53. data/lib/badline/c64/cartridge/game_system.rb +42 -0
  54. data/lib/badline/c64/cartridge/geo_ram.rb +81 -0
  55. data/lib/badline/c64/cartridge/kcs_power.rb +77 -0
  56. data/lib/badline/c64/cartridge/mach5.rb +34 -0
  57. data/lib/badline/c64/cartridge/magic_desk.rb +32 -0
  58. data/lib/badline/c64/cartridge/ocean.rb +37 -0
  59. data/lib/badline/c64/cartridge/pagefox.rb +70 -0
  60. data/lib/badline/c64/cartridge/retro_replay/saved_state.rb +47 -0
  61. data/lib/badline/c64/cartridge/retro_replay.rb +286 -0
  62. data/lib/badline/c64/cartridge/rex_utility.rb +31 -0
  63. data/lib/badline/c64/cartridge/rgcd.rb +60 -0
  64. data/lib/badline/c64/cartridge/saved_state.rb +63 -0
  65. data/lib/badline/c64/cartridge/simons_basic.rb +37 -0
  66. data/lib/badline/c64/cartridge/standard.rb +17 -0
  67. data/lib/badline/c64/cartridge/super_games.rb +50 -0
  68. data/lib/badline/c64/cartridge/westermann.rb +32 -0
  69. data/lib/badline/c64/cartridge/zaxxon.rb +68 -0
  70. data/lib/badline/c64/cartridge.rb +258 -0
  71. data/lib/badline/c64/color_memory.rb +27 -0
  72. data/lib/badline/{computer → c64}/common.rb +2 -2
  73. data/lib/badline/{computer → c64}/kernal_traps.rb +18 -18
  74. data/lib/badline/c64/reu/dma/saved_state.rb +52 -0
  75. data/lib/badline/c64/reu/dma.rb +275 -0
  76. data/lib/badline/c64/reu/ram.rb +109 -0
  77. data/lib/badline/c64/reu/saved_state.rb +55 -0
  78. data/lib/badline/c64/reu/trigger.rb +34 -0
  79. data/lib/badline/c64/reu.rb +291 -0
  80. data/lib/badline/{computer → c64}/saved_state.rb +13 -18
  81. data/lib/badline/{computer → c64}/true_drives.rb +11 -11
  82. data/lib/badline/{computer.rb → c64.rb} +18 -13
  83. data/lib/badline/chips/cia/fast_forward.rb +62 -0
  84. data/lib/badline/chips/cia/interrupt_register.rb +145 -0
  85. data/lib/badline/chips/cia/saved_state.rb +49 -0
  86. data/lib/badline/chips/cia/serial/saved_state.rb +45 -0
  87. data/lib/badline/chips/cia/serial.rb +250 -0
  88. data/lib/badline/chips/cia/time_of_day.rb +232 -0
  89. data/lib/badline/chips/cia/timer.rb +208 -0
  90. data/lib/badline/chips/cia.rb +281 -0
  91. data/lib/badline/chips/cpu/addressing.rb +133 -0
  92. data/lib/badline/chips/cpu/boundary.rb +56 -0
  93. data/lib/badline/chips/cpu/core.rb +167 -0
  94. data/lib/badline/chips/cpu/instruction.rb +338 -0
  95. data/lib/badline/chips/cpu/instruction_set/arithmetic.rb +118 -0
  96. data/lib/badline/chips/cpu/instruction_set/bitwise.rb +130 -0
  97. data/lib/badline/chips/cpu/instruction_set/branch.rb +83 -0
  98. data/lib/badline/chips/cpu/instruction_set/flag.rb +67 -0
  99. data/lib/badline/chips/cpu/instruction_set/illegal.rb +274 -0
  100. data/lib/badline/chips/cpu/instruction_set/inc_dec.rb +73 -0
  101. data/lib/badline/chips/cpu/instruction_set/stack.rb +56 -0
  102. data/lib/badline/chips/cpu/instruction_set/transfer.rb +141 -0
  103. data/lib/badline/chips/cpu/instruction_set.rb +59 -0
  104. data/lib/badline/chips/cpu/interrupts.rb +108 -0
  105. data/lib/badline/chips/cpu/microcode.rb +179 -0
  106. data/lib/badline/chips/cpu/operations.rb +90 -0
  107. data/lib/badline/chips/cpu/port.rb +116 -0
  108. data/lib/badline/chips/cpu/saved_state.rb +117 -0
  109. data/lib/badline/chips/cpu/stack_operations.rb +84 -0
  110. data/lib/badline/chips/cpu/traps.rb +23 -0
  111. data/lib/badline/chips/cpu.rb +12 -0
  112. data/lib/badline/chips/sid/catch_up.rb +122 -0
  113. data/lib/badline/chips/sid/decimator.rb +66 -0
  114. data/lib/badline/chips/sid/envelope/saved_state.rb +70 -0
  115. data/lib/badline/chips/sid/envelope.rb +241 -0
  116. data/lib/badline/chips/sid/filter/saved_state.rb +42 -0
  117. data/lib/badline/chips/sid/filter.rb +241 -0
  118. data/lib/badline/chips/sid/saved_state.rb +52 -0
  119. data/lib/badline/chips/sid/voice.rb +79 -0
  120. data/lib/badline/chips/sid/waveform/combined.rb +128 -0
  121. data/lib/badline/chips/sid/waveform/fast_forward.rb +107 -0
  122. data/lib/badline/chips/sid/waveform/noise_writeback.rb +124 -0
  123. data/lib/badline/chips/sid/waveform/saved_state.rb +68 -0
  124. data/lib/badline/chips/sid/waveform.rb +307 -0
  125. data/lib/badline/chips/sid.rb +265 -0
  126. data/lib/badline/{c128 → chips}/vdc/memory.rb +1 -1
  127. data/lib/badline/{c128 → chips}/vdc/painter.rb +1 -1
  128. data/lib/badline/{c128 → chips}/vdc/raster.rb +1 -1
  129. data/lib/badline/chips/vdc/saved_state.rb +36 -0
  130. data/lib/badline/{c128 → chips}/vdc/window.rb +1 -1
  131. data/lib/badline/{c128 → chips}/vdc.rb +7 -31
  132. data/lib/badline/chips/via/control_lines.rb +124 -0
  133. data/lib/badline/chips/via/fast_forward.rb +55 -0
  134. data/lib/badline/chips/via/interrupt_register.rb +69 -0
  135. data/lib/badline/chips/via/saved_state.rb +44 -0
  136. data/lib/badline/chips/via/shift_register.rb +182 -0
  137. data/lib/badline/chips/via/timer1.rb +133 -0
  138. data/lib/badline/chips/via/timer2.rb +135 -0
  139. data/lib/badline/chips/via.rb +268 -0
  140. data/lib/badline/chips/vic/bank.rb +135 -0
  141. data/lib/badline/chips/vic/border_mask.rb +88 -0
  142. data/lib/badline/chips/vic/collisions.rb +117 -0
  143. data/lib/badline/chips/vic/color_patches.rb +49 -0
  144. data/lib/badline/chips/vic/display_state.rb +187 -0
  145. data/lib/badline/chips/vic/graphics_mode.rb +166 -0
  146. data/lib/badline/chips/vic/graphics_shifter/saved_state.rb +40 -0
  147. data/lib/badline/chips/vic/graphics_shifter.rb +187 -0
  148. data/lib/badline/chips/vic/register_log.rb +83 -0
  149. data/lib/badline/chips/vic/registers.rb +197 -0
  150. data/lib/badline/chips/vic/saved_state.rb +82 -0
  151. data/lib/badline/chips/vic/sequencer/saved_state.rb +91 -0
  152. data/lib/badline/chips/vic/sequencer.rb +277 -0
  153. data/lib/badline/chips/vic/sequencer_output.rb +118 -0
  154. data/lib/badline/chips/vic/sprite/internal_bus.rb +70 -0
  155. data/lib/badline/chips/vic/sprite/saved_state.rb +66 -0
  156. data/lib/badline/chips/vic/sprite/shifter.rb +148 -0
  157. data/lib/badline/chips/vic/sprite/timing.rb +58 -0
  158. data/lib/badline/chips/vic/sprite.rb +339 -0
  159. data/lib/badline/chips/vic/sprites/saved_state.rb +59 -0
  160. data/lib/badline/chips/vic/sprites.rb +284 -0
  161. data/lib/badline/chips/vic.rb +783 -0
  162. data/lib/badline/chips/vic_i/painter/saved_state.rb +40 -0
  163. data/lib/badline/{vic20/vic → chips/vic_i}/painter.rb +6 -30
  164. data/lib/badline/{vic20/vic → chips/vic_i}/saved_state.rb +2 -2
  165. data/lib/badline/chips/vic_i/sound/output.rb +85 -0
  166. data/lib/badline/chips/vic_i/sound.rb +235 -0
  167. data/lib/badline/{vic20/vic → chips/vic_i}/text_window.rb +2 -2
  168. data/lib/badline/{vic20/vic.rb → chips/vic_i.rb} +5 -5
  169. data/lib/badline/chips/z80/arithmetic.rb +119 -0
  170. data/lib/badline/chips/z80/bit_page.rb +57 -0
  171. data/lib/badline/chips/z80/block_io.rb +60 -0
  172. data/lib/badline/chips/z80/block_transfers.rb +61 -0
  173. data/lib/badline/chips/z80/bus_cycles.rb +113 -0
  174. data/lib/badline/chips/z80/core.rb +115 -0
  175. data/lib/badline/chips/z80/exchanges.rb +52 -0
  176. data/lib/badline/chips/z80/extended_page.rb +91 -0
  177. data/lib/badline/chips/z80/flags.rb +39 -0
  178. data/lib/badline/chips/z80/interrupt_acceptance.rb +48 -0
  179. data/lib/badline/chips/z80/jumps.rb +84 -0
  180. data/lib/badline/chips/z80/loads.rb +100 -0
  181. data/lib/badline/chips/z80/main_page.rb +136 -0
  182. data/lib/badline/chips/z80/registers.rb +122 -0
  183. data/lib/badline/chips/z80/saved_state.rb +71 -0
  184. data/lib/badline/chips/z80/shifts.rb +66 -0
  185. data/lib/badline/chips/z80.rb +13 -0
  186. data/lib/badline/core.rb +26 -28
  187. data/lib/badline/drives/datasette/saved_state.rb +37 -0
  188. data/lib/badline/drives/datasette.rb +140 -0
  189. data/lib/badline/drives/engine/core.rb +149 -0
  190. data/lib/badline/drives/engine/fast_serial.rb +75 -0
  191. data/lib/badline/drives/engine/idle.rb +127 -0
  192. data/lib/badline/drives/engine/idle_cpu.rb +30 -0
  193. data/lib/badline/drives/engine/orbit.rb +81 -0
  194. data/lib/badline/drives/engine/serial_lines.rb +75 -0
  195. data/lib/badline/drives/engine/sleep.rb +114 -0
  196. data/lib/badline/drives/engine/vias.rb +86 -0
  197. data/lib/badline/drives/engine/watch.rb +152 -0
  198. data/lib/badline/drives/engine.rb +11 -0
  199. data/lib/badline/drives/model1541/bus.rb +88 -0
  200. data/lib/badline/drives/model1541/byte_ready.rb +50 -0
  201. data/lib/badline/drives/model1541/cpu.rb +13 -0
  202. data/lib/badline/drives/model1541/disk/saved_state.rb +88 -0
  203. data/lib/badline/drives/model1541/disk.rb +317 -0
  204. data/lib/badline/drives/model1541/disk_via.rb +38 -0
  205. data/lib/badline/drives/model1541/gcr.rb +59 -0
  206. data/lib/badline/drives/model1541/mechanism/saved_state.rb +72 -0
  207. data/lib/badline/drives/model1541/mechanism.rb +315 -0
  208. data/lib/badline/drives/model1541/rotation.rb +123 -0
  209. data/lib/badline/drives/model1541/saved_state.rb +44 -0
  210. data/lib/badline/drives/model1541/sector_reader.rb +78 -0
  211. data/lib/badline/drives/model1541/serial_port.rb +20 -0
  212. data/lib/badline/drives/model1541/track.rb +100 -0
  213. data/lib/badline/drives/model1541.rb +81 -0
  214. data/lib/badline/drives/model1571/bus.rb +113 -0
  215. data/lib/badline/drives/model1571/cpu.rb +13 -0
  216. data/lib/badline/drives/model1571/saved_state.rb +47 -0
  217. data/lib/badline/drives/model1571/serial_port.rb +39 -0
  218. data/lib/badline/drives/model1571/serial_via.rb +27 -0
  219. data/lib/badline/drives/model1571/wd1770.rb +122 -0
  220. data/lib/badline/drives/model1571.rb +142 -0
  221. data/lib/badline/drives/model1581/bus.rb +139 -0
  222. data/lib/badline/drives/model1581/cpu.rb +13 -0
  223. data/lib/badline/drives/model1581/disk/saved_state.rb +89 -0
  224. data/lib/badline/drives/model1581/disk.rb +137 -0
  225. data/lib/badline/drives/model1581/mechanism.rb +119 -0
  226. data/lib/badline/drives/model1581/saved_state.rb +42 -0
  227. data/lib/badline/drives/model1581/serial_port.rb +54 -0
  228. data/lib/badline/drives/model1581/slot.rb +79 -0
  229. data/lib/badline/drives/model1581/track.rb +102 -0
  230. data/lib/badline/drives/model1581/track_bytes.rb +77 -0
  231. data/lib/badline/drives/model1581/wd1772/registers.rb +91 -0
  232. data/lib/badline/drives/model1581/wd1772/saved_state.rb +68 -0
  233. data/lib/badline/drives/model1581/wd1772/sector_writes.rb +75 -0
  234. data/lib/badline/drives/model1581/wd1772/sectors.rb +152 -0
  235. data/lib/badline/drives/model1581/wd1772/stepping.rb +111 -0
  236. data/lib/badline/drives/model1581/wd1772/tracks.rb +127 -0
  237. data/lib/badline/drives/model1581/wd1772/turn.rb +75 -0
  238. data/lib/badline/drives/model1581/wd1772.rb +218 -0
  239. data/lib/badline/drives/model1581.rb +206 -0
  240. data/lib/badline/drives/serial_bus.rb +161 -0
  241. data/lib/badline/frontend/boot.rb +3 -3
  242. data/lib/badline/frontend/machine_window.rb +3 -1
  243. data/lib/badline/frontend/player/filter_view.rb +1 -1
  244. data/lib/badline/frontend/player/player_controller.rb +2 -2
  245. data/lib/badline/frontend/player/player_screen.rb +1 -0
  246. data/lib/badline/frontend/player/theme.rb +7 -7
  247. data/lib/badline/frontend/timeline.rb +3 -3
  248. data/lib/badline/input/control_ports.rb +78 -0
  249. data/lib/badline/input/joystick.rb +27 -0
  250. data/lib/badline/input/keyboard.rb +114 -0
  251. data/lib/badline/input.rb +3 -0
  252. data/lib/badline/kernal_trap/{drive → dos}/block_commands.rb +1 -1
  253. data/lib/badline/kernal_trap/dos/channel.rb +183 -0
  254. data/lib/badline/kernal_trap/{drive → dos}/channels.rb +1 -1
  255. data/lib/badline/kernal_trap/{drive → dos}/memory.rb +1 -1
  256. data/lib/badline/kernal_trap/{drive → dos}/parameters.rb +1 -1
  257. data/lib/badline/kernal_trap/{drive → dos}/status.rb +1 -1
  258. data/lib/badline/kernal_trap/{drive → dos}/write_file.rb +1 -1
  259. data/lib/badline/kernal_trap/{drive → dos}/writes.rb +1 -1
  260. data/lib/badline/kernal_trap/{drive.rb → dos.rb} +11 -10
  261. data/lib/badline/kernal_trap/load.rb +5 -5
  262. data/lib/badline/kernal_trap/save.rb +4 -4
  263. data/lib/badline/kernal_trap/serial.rb +7 -7
  264. data/lib/badline/kernal_trap.rb +1 -2
  265. data/lib/badline/machine/clocking.rb +1 -1
  266. data/lib/badline/machine.rb +5 -5
  267. data/lib/badline/media/true_drive.rb +1 -1
  268. data/lib/badline/media/tune.rb +2 -2
  269. data/lib/badline/media.rb +3 -3
  270. data/lib/badline/model.rb +1 -1
  271. data/lib/badline/roms/README +6 -6
  272. data/lib/badline/sdl.rb +1 -0
  273. data/lib/badline/{storage/sid_file.rb → sid_tune/file.rb} +3 -3
  274. data/lib/badline/{storage → sid_tune}/hvsc.rb +7 -7
  275. data/lib/badline/{storage → sid_tune}/song_lengths.rb +2 -2
  276. data/lib/badline/{storage → sid_tune}/stil/credit.rb +1 -1
  277. data/lib/badline/{storage → sid_tune}/stil.rb +3 -3
  278. data/lib/badline/sid_tune.rb +6 -0
  279. data/lib/badline/snapshot/c128_setup.rb +43 -0
  280. data/lib/badline/snapshot/c64_setup.rb +79 -0
  281. data/lib/badline/snapshot/image.rb +5 -25
  282. data/lib/badline/snapshot/machine_state.rb +1 -1
  283. data/lib/badline/snapshot/setup.rb +22 -66
  284. data/lib/badline/snapshot/state.rb +8 -18
  285. data/lib/badline/snapshot/storage_setup.rb +68 -0
  286. data/lib/badline/snapshot/vic20_setup.rb +37 -0
  287. data/lib/badline/snapshot/vice/c64_mem.rb +1 -1
  288. data/lib/badline/snapshot/vice/restore.rb +1 -1
  289. data/lib/badline/snapshot/vice/reu1764.rb +1 -1
  290. data/lib/badline/snapshot/vice/reu_fields.rb +40 -0
  291. data/lib/badline/snapshot/vice.rb +7 -5
  292. data/lib/badline/snapshot.rb +3 -4
  293. data/lib/badline/storage/d64_image.rb +0 -2
  294. data/lib/badline/storage/d71_image.rb +0 -2
  295. data/lib/badline/storage/d81_image.rb +0 -2
  296. data/lib/badline/storage/disk_image.rb +3 -6
  297. data/lib/badline/storage/g64_image.rb +2 -2
  298. data/lib/badline/storage/host_directory.rb +0 -5
  299. data/lib/badline/storage/t64.rb +2 -8
  300. data/lib/badline/storage/unavailable.rb +1 -1
  301. data/lib/badline/storage.rb +0 -37
  302. data/lib/badline/support/c128_checkpoint.rb +39 -0
  303. data/lib/badline/support/checkpoint.rb +108 -0
  304. data/lib/badline/support/vic20_checkpoint.rb +38 -0
  305. data/lib/badline/support.rb +5 -0
  306. data/lib/badline/version.rb +1 -1
  307. data/lib/badline/vic20/attachments.rb +5 -5
  308. data/lib/badline/vic20/bus/saved_state.rb +35 -0
  309. data/lib/badline/vic20/bus.rb +3 -25
  310. data/lib/badline/vic20/cpu.rb +1 -1
  311. data/lib/badline/vic20/port_wiring.rb +4 -4
  312. data/lib/badline/vic20/saved_state.rb +16 -30
  313. data/lib/badline/vic20/user_via_ports.rb +2 -2
  314. data/lib/badline/vic20.rb +19 -14
  315. metadata +245 -221
  316. data/lib/badline/address_bus/extra_sids.rb +0 -30
  317. data/lib/badline/address_bus/fittings.rb +0 -38
  318. data/lib/badline/address_bus/pla.rb +0 -147
  319. data/lib/badline/address_bus/roms.rb +0 -39
  320. data/lib/badline/address_bus/saved_state.rb +0 -66
  321. data/lib/badline/address_bus/sid_slots.rb +0 -42
  322. data/lib/badline/address_bus.rb +0 -216
  323. data/lib/badline/cartridge/action_replay.rb +0 -126
  324. data/lib/badline/cartridge/atomic_power.rb +0 -24
  325. data/lib/badline/cartridge/bank.rb +0 -81
  326. data/lib/badline/cartridge/comal80.rb +0 -50
  327. data/lib/badline/cartridge/dinamic.rb +0 -34
  328. data/lib/badline/cartridge/easy_flash.rb +0 -145
  329. data/lib/badline/cartridge/epyx_fastload.rb +0 -79
  330. data/lib/badline/cartridge/final_cartridge3.rb +0 -89
  331. data/lib/badline/cartridge/flash.rb +0 -306
  332. data/lib/badline/cartridge/freezer.rb +0 -33
  333. data/lib/badline/cartridge/fun_play.rb +0 -38
  334. data/lib/badline/cartridge/g_mod2.rb +0 -74
  335. data/lib/badline/cartridge/game_system.rb +0 -40
  336. data/lib/badline/cartridge/geo_ram.rb +0 -79
  337. data/lib/badline/cartridge/kcs_power.rb +0 -75
  338. data/lib/badline/cartridge/mach5.rb +0 -32
  339. data/lib/badline/cartridge/magic_desk.rb +0 -30
  340. data/lib/badline/cartridge/ocean.rb +0 -35
  341. data/lib/badline/cartridge/pagefox.rb +0 -68
  342. data/lib/badline/cartridge/retro_replay.rb +0 -320
  343. data/lib/badline/cartridge/rex_utility.rb +0 -29
  344. data/lib/badline/cartridge/rgcd.rb +0 -58
  345. data/lib/badline/cartridge/simons_basic.rb +0 -35
  346. data/lib/badline/cartridge/standard.rb +0 -15
  347. data/lib/badline/cartridge/super_games.rb +0 -48
  348. data/lib/badline/cartridge/westermann.rb +0 -30
  349. data/lib/badline/cartridge/zaxxon.rb +0 -66
  350. data/lib/badline/cartridge.rb +0 -303
  351. data/lib/badline/checkpoint.rb +0 -98
  352. data/lib/badline/cia/fast_forward.rb +0 -60
  353. data/lib/badline/cia/interrupt_register.rb +0 -143
  354. data/lib/badline/cia/serial.rb +0 -275
  355. data/lib/badline/cia/state.rb +0 -47
  356. data/lib/badline/cia/timer.rb +0 -206
  357. data/lib/badline/cia.rb +0 -279
  358. data/lib/badline/color_memory.rb +0 -25
  359. data/lib/badline/control_ports.rb +0 -76
  360. data/lib/badline/cpu/addressing.rb +0 -131
  361. data/lib/badline/cpu/boundary.rb +0 -54
  362. data/lib/badline/cpu/core.rb +0 -165
  363. data/lib/badline/cpu/microcode.rb +0 -177
  364. data/lib/badline/cpu/operations.rb +0 -88
  365. data/lib/badline/cpu/saved_state.rb +0 -115
  366. data/lib/badline/cpu/stack_operations.rb +0 -82
  367. data/lib/badline/cpu.rb +0 -10
  368. data/lib/badline/cpu_port.rb +0 -112
  369. data/lib/badline/datasette.rb +0 -161
  370. data/lib/badline/drive/core.rb +0 -147
  371. data/lib/badline/drive/fast_serial.rb +0 -73
  372. data/lib/badline/drive/idle.rb +0 -125
  373. data/lib/badline/drive/idle_cpu.rb +0 -28
  374. data/lib/badline/drive/orbit.rb +0 -79
  375. data/lib/badline/drive/serial_lines.rb +0 -73
  376. data/lib/badline/drive/sleep.rb +0 -112
  377. data/lib/badline/drive/vias.rb +0 -84
  378. data/lib/badline/drive/watch.rb +0 -150
  379. data/lib/badline/drive.rb +0 -11
  380. data/lib/badline/drive1541/bus.rb +0 -86
  381. data/lib/badline/drive1541/byte_ready.rb +0 -48
  382. data/lib/badline/drive1541/cpu.rb +0 -11
  383. data/lib/badline/drive1541/disk.rb +0 -315
  384. data/lib/badline/drive1541/disk_state.rb +0 -86
  385. data/lib/badline/drive1541/disk_via.rb +0 -36
  386. data/lib/badline/drive1541/gcr.rb +0 -57
  387. data/lib/badline/drive1541/mechanism.rb +0 -313
  388. data/lib/badline/drive1541/mechanism_state.rb +0 -68
  389. data/lib/badline/drive1541/rotation.rb +0 -121
  390. data/lib/badline/drive1541/sector_reader.rb +0 -76
  391. data/lib/badline/drive1541/serial_port.rb +0 -18
  392. data/lib/badline/drive1541/track.rb +0 -98
  393. data/lib/badline/drive1541.rb +0 -111
  394. data/lib/badline/drive1571/bus.rb +0 -111
  395. data/lib/badline/drive1571/cpu.rb +0 -11
  396. data/lib/badline/drive1571/serial_port.rb +0 -37
  397. data/lib/badline/drive1571/serial_via.rb +0 -25
  398. data/lib/badline/drive1571/wd1770.rb +0 -120
  399. data/lib/badline/drive1571.rb +0 -175
  400. data/lib/badline/drive1581/bus.rb +0 -137
  401. data/lib/badline/drive1581/cpu.rb +0 -11
  402. data/lib/badline/drive1581/disk.rb +0 -135
  403. data/lib/badline/drive1581/disk_state.rb +0 -87
  404. data/lib/badline/drive1581/mechanism.rb +0 -117
  405. data/lib/badline/drive1581/serial_port.rb +0 -52
  406. data/lib/badline/drive1581/slot.rb +0 -78
  407. data/lib/badline/drive1581/track.rb +0 -100
  408. data/lib/badline/drive1581/track_bytes.rb +0 -75
  409. data/lib/badline/drive1581/wd1772/registers.rb +0 -89
  410. data/lib/badline/drive1581/wd1772/sector_writes.rb +0 -73
  411. data/lib/badline/drive1581/wd1772/sectors.rb +0 -150
  412. data/lib/badline/drive1581/wd1772/state.rb +0 -66
  413. data/lib/badline/drive1581/wd1772/stepping.rb +0 -109
  414. data/lib/badline/drive1581/wd1772/tracks.rb +0 -125
  415. data/lib/badline/drive1581/wd1772/turn.rb +0 -73
  416. data/lib/badline/drive1581/wd1772.rb +0 -216
  417. data/lib/badline/drive1581.rb +0 -233
  418. data/lib/badline/iec_bus.rb +0 -159
  419. data/lib/badline/instruction.rb +0 -334
  420. data/lib/badline/instruction_set/arithmetic.rb +0 -114
  421. data/lib/badline/instruction_set/bitwise.rb +0 -126
  422. data/lib/badline/instruction_set/branch.rb +0 -79
  423. data/lib/badline/instruction_set/flag.rb +0 -63
  424. data/lib/badline/instruction_set/illegal.rb +0 -270
  425. data/lib/badline/instruction_set/inc_dec.rb +0 -69
  426. data/lib/badline/instruction_set/stack.rb +0 -52
  427. data/lib/badline/instruction_set/transfer.rb +0 -137
  428. data/lib/badline/instruction_set.rb +0 -55
  429. data/lib/badline/interrupts.rb +0 -104
  430. data/lib/badline/joystick.rb +0 -25
  431. data/lib/badline/kernal_trap/channel.rb +0 -181
  432. data/lib/badline/keyboard.rb +0 -112
  433. data/lib/badline/ram_expansion/banking.rb +0 -30
  434. data/lib/badline/ram_expansion/plus256k.rb +0 -54
  435. data/lib/badline/ram_expansion/plus60k.rb +0 -43
  436. data/lib/badline/ram_expansion/unexpanded.rb +0 -28
  437. data/lib/badline/ram_expansion.rb +0 -21
  438. data/lib/badline/reu/dma/saved_state.rb +0 -50
  439. data/lib/badline/reu/dma.rb +0 -273
  440. data/lib/badline/reu/ram.rb +0 -107
  441. data/lib/badline/reu/saved_state.rb +0 -80
  442. data/lib/badline/reu/trigger.rb +0 -32
  443. data/lib/badline/reu.rb +0 -289
  444. data/lib/badline/sid/catch_up.rb +0 -120
  445. data/lib/badline/sid/decimator.rb +0 -64
  446. data/lib/badline/sid/envelope/state.rb +0 -68
  447. data/lib/badline/sid/envelope.rb +0 -239
  448. data/lib/badline/sid/filter.rb +0 -263
  449. data/lib/badline/sid/voice.rb +0 -77
  450. data/lib/badline/sid/waveform/combined.rb +0 -126
  451. data/lib/badline/sid/waveform/fast_forward.rb +0 -105
  452. data/lib/badline/sid/waveform/noise_writeback.rb +0 -122
  453. data/lib/badline/sid/waveform/state.rb +0 -66
  454. data/lib/badline/sid/waveform.rb +0 -305
  455. data/lib/badline/sid.rb +0 -303
  456. data/lib/badline/time_of_day.rb +0 -228
  457. data/lib/badline/traps.rb +0 -19
  458. data/lib/badline/via/control_lines.rb +0 -122
  459. data/lib/badline/via/fast_forward.rb +0 -53
  460. data/lib/badline/via/interrupt_register.rb +0 -67
  461. data/lib/badline/via/shift_register.rb +0 -180
  462. data/lib/badline/via/state.rb +0 -42
  463. data/lib/badline/via/timer1.rb +0 -131
  464. data/lib/badline/via/timer2.rb +0 -133
  465. data/lib/badline/via.rb +0 -266
  466. data/lib/badline/vic/bank.rb +0 -133
  467. data/lib/badline/vic/border_mask.rb +0 -86
  468. data/lib/badline/vic/collisions.rb +0 -115
  469. data/lib/badline/vic/color_patches.rb +0 -47
  470. data/lib/badline/vic/display_state.rb +0 -185
  471. data/lib/badline/vic/graphics_mode.rb +0 -164
  472. data/lib/badline/vic/graphics_shifter.rb +0 -207
  473. data/lib/badline/vic/register_log.rb +0 -81
  474. data/lib/badline/vic/registers.rb +0 -195
  475. data/lib/badline/vic/sequencer.rb +0 -275
  476. data/lib/badline/vic/sequencer_output.rb +0 -116
  477. data/lib/badline/vic/sequencer_state.rb +0 -89
  478. data/lib/badline/vic/sprite/internal_bus.rb +0 -68
  479. data/lib/badline/vic/sprite/saved_state.rb +0 -64
  480. data/lib/badline/vic/sprite/shifter.rb +0 -146
  481. data/lib/badline/vic/sprite/timing.rb +0 -56
  482. data/lib/badline/vic/sprite.rb +0 -337
  483. data/lib/badline/vic/sprites.rb +0 -282
  484. data/lib/badline/vic/sprites_state.rb +0 -57
  485. data/lib/badline/vic.rb +0 -853
  486. data/lib/badline/vic20/sound/output.rb +0 -83
  487. data/lib/badline/vic20/sound.rb +0 -233
  488. data/lib/badline/z80/arithmetic.rb +0 -117
  489. data/lib/badline/z80/bit_page.rb +0 -55
  490. data/lib/badline/z80/block_io.rb +0 -58
  491. data/lib/badline/z80/block_transfers.rb +0 -59
  492. data/lib/badline/z80/bus_cycles.rb +0 -111
  493. data/lib/badline/z80/core.rb +0 -113
  494. data/lib/badline/z80/exchanges.rb +0 -50
  495. data/lib/badline/z80/extended_page.rb +0 -89
  496. data/lib/badline/z80/flags.rb +0 -37
  497. data/lib/badline/z80/interrupt_acceptance.rb +0 -46
  498. data/lib/badline/z80/jumps.rb +0 -82
  499. data/lib/badline/z80/loads.rb +0 -98
  500. data/lib/badline/z80/main_page.rb +0 -134
  501. data/lib/badline/z80/registers.rb +0 -120
  502. data/lib/badline/z80/saved_state.rb +0 -69
  503. data/lib/badline/z80/shifts.rb +0 -64
  504. data/lib/badline/z80.rb +0 -11
  505. /data/lib/badline/snapshot/{fields.rb → vice/fields.rb} +0 -0
@@ -0,0 +1,291 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "badline/c64/reu/ram"
4
+ require "badline/c64/reu/dma"
5
+ require "badline/c64/reu/trigger"
6
+ require "badline/c64/reu/saved_state"
7
+
8
+ module Badline
9
+ class C64
10
+ # A RAM Expansion Unit: the Commodore 1700 (128K), 1764 (256K) and 1750
11
+ # (512K), and the bigger units built around the same 8726 RAM Expansion
12
+ # Controller (REC), such as the CMD 1750XL, up to 16M.
13
+ #
14
+ # The REC's eleven registers sit in I/O 2 from $DF00, repeated every 32
15
+ # bytes up to $DFFF, as the 1764 and 1750 manuals map them. It moves
16
+ # bytes between the C64 and its RAM by DMA, one bus cycle each, with the
17
+ # CPU held off the bus. A command with the execute bit set starts a
18
+ # transfer, or with bit 4 clear arms the REC to start one on the next
19
+ # write to $FF00, so a program can bank the ROMs out first. A transfer
20
+ # waits for the CPU's next read cycle with BA high, and C64 then
21
+ # clocks it through #dma_cycle! until it hands the bus back.
22
+ class REU
23
+ include SavedState
24
+
25
+ SIZES_KB = [128, 256, 512, 1024, 2048, 4096, 8192, 16_384].freeze
26
+
27
+ # The registers, by offset.
28
+ STATUS = 0x00
29
+ COMMAND = 0x01
30
+ C64_LOW = 0x02
31
+ C64_HIGH = 0x03
32
+ EXPANSION_LOW = 0x04
33
+ EXPANSION_HIGH = 0x05
34
+ EXPANSION_BANK = 0x06
35
+ LENGTH_LOW = 0x07
36
+ LENGTH_HIGH = 0x08
37
+ INTERRUPT_MASK = 0x09
38
+ ADDRESS_CONTROL = 0x0a
39
+
40
+ # Status: an interrupt is pending, the block ended, a verify found a
41
+ # difference (the manual's fault bit), and the unit is built from 256K
42
+ # chips, which only the 1700 isn't. Reading the status clears the top
43
+ # three.
44
+ INTERRUPT_PENDING = 0x80
45
+ END_OF_BLOCK = 0x40
46
+ FAULT = 0x20
47
+ CHIPS_256K = 0x10
48
+
49
+ # Command: execute, reload the registers after the transfer, don't wait
50
+ # for $FF00, and the transfer type in the bottom two bits.
51
+ EXECUTE = 0x80
52
+ AUTOLOAD = 0x20
53
+ NO_FF00_TRIGGER = 0x10
54
+ TRANSFER_TYPE = 0x03
55
+
56
+ # Interrupt mask: interrupts on at all, then on the end of a block and
57
+ # on a fault. The low five bits aren't there and read as 1.
58
+ INTERRUPTS_ON = 0x80
59
+ INTERRUPT_ON_END = 0x40
60
+ INTERRUPT_ON_FAULT = 0x20
61
+
62
+ # Address control: hold the C64 address or the expansion address where
63
+ # it is. The low six bits aren't there and read as 1.
64
+ FIX_C64 = 0x80
65
+ FIX_EXPANSION = 0x40
66
+
67
+ # The REC's bank register has three bits, and the other five read as
68
+ # 1. A unit past 512K latches all eight onto its own address lines.
69
+ BANK_STUCK = 0xf8
70
+
71
+ attr_reader :trigger
72
+
73
+ # bus is the bus the REC reaches C64 memory through, and vic the VIC,
74
+ # whose phi1 fetch is what a register read finds on the bus during a
75
+ # transfer.
76
+ def initialize(size_kb, bus:, vic:)
77
+ raise ArgumentError, "No #{size_kb}K REU. Pick one of #{SIZES_KB.join(', ')}." unless SIZES_KB.include?(size_kb)
78
+
79
+ # The 1700's REC counts 17 address bits, the others' 19.
80
+ span = size_kb == 128 ? 0x20000 : 0x80000
81
+ @size_kb = size_kb
82
+ size = size_kb * 1024
83
+ @address_mask = [size, span].max - 1
84
+ @bank_bits = size > span ? 0xff : 0x07
85
+ @chips = size_kb == 128 ? 0 : CHIPS_256K
86
+ @ram = RAM.new(size, span)
87
+ @dma = DMA.new(@ram, span, bus)
88
+ @trigger = Trigger.new(self)
89
+ @vic = vic
90
+ @on_irq_change = nil
91
+ @on_dma = nil
92
+ @irq = false
93
+ reset!
94
+ end
95
+
96
+ def on_irq_change(&block)
97
+ @on_irq_change = block
98
+ end
99
+
100
+ # Called when the REC asks for the bus.
101
+ def on_dma(&block)
102
+ @on_dma = block
103
+ end
104
+
105
+ def irq? = @irq
106
+
107
+ # From the moment the REC asks for the bus until it hands it back.
108
+ def dma? = @requested || @running
109
+
110
+ # Whether the REC ran a transfer on the last cycle clocked, which it
111
+ # goes on doing until the cycle it lets go of the bus.
112
+ def holds_bus? = @running
113
+
114
+ def reset!
115
+ @status = @chips
116
+ @command = NO_FF00_TRIGGER
117
+ @c64 = @c64_start = 0
118
+ @expansion = @expansion_start = 0
119
+ @bank = @bank_start = 0
120
+ @length = @length_start = 0xffff
121
+ @interrupt_mask = 0x1f
122
+ @address_control = 0x3f
123
+ @armed = @requested = @running = @ba_was_low = false
124
+ interrupt(false)
125
+ end
126
+
127
+ def peek(addr)
128
+ return @vic.phi1_data if @running
129
+
130
+ register = addr & 0x1f
131
+ value = register_value(register)
132
+ read_status if register == STATUS
133
+ value
134
+ end
135
+
136
+ def poke(addr, value)
137
+ return if @running
138
+
139
+ register = addr & 0x1f
140
+ case register
141
+ when COMMAND then write_command(value)
142
+ when C64_LOW, C64_HIGH then @c64 = @c64_start = with_byte(@c64_start, value, register == C64_HIGH)
143
+ when EXPANSION_LOW, EXPANSION_HIGH
144
+ @expansion = @expansion_start = with_byte(@expansion_start, value, register == EXPANSION_HIGH)
145
+ when EXPANSION_BANK then @bank = @bank_start = value & @bank_bits
146
+ when LENGTH_LOW, LENGTH_HIGH
147
+ @length = @length_start = with_byte(@length_start, value, register == LENGTH_HIGH)
148
+ when INTERRUPT_MASK then write_interrupt_mask(value)
149
+ when ADDRESS_CONTROL then @address_control = value | 0x3f
150
+ end
151
+ end
152
+
153
+ # A write to $FF00 starts the transfer the command register armed.
154
+ def ff00_written
155
+ return unless @armed
156
+
157
+ @armed = false
158
+ request_bus
159
+ end
160
+
161
+ # Clocks the REC for a cycle, given the VIC's BA line. A requested
162
+ # transfer starts on the first cycle with BA high as the REC sees it,
163
+ # even one the CPU writes on. Pinned by REU/rmw-trigger. A fetch
164
+ # requested on the cycle before BA falls writes its first byte on the
165
+ # first BA-low cycle as well, and again when it starts. Pinned by
166
+ # REU/badoublewrite.
167
+ def dma_cycle!(ba_low)
168
+ late = ba_low && @vic.reu_ba_late?
169
+ if @requested
170
+ return hold_off if ba_low && !late
171
+
172
+ start_transfer
173
+ end
174
+ @dma.cycle!(ba_low, late, ba_low && @vic.reu_ba_handed_on?)
175
+ end_transfer unless @dma.holds_bus?
176
+ end
177
+
178
+ # The REU's RAM, at an address as the REC's registers give it.
179
+ def ram_peek(addr) = @ram.peek(addr)
180
+
181
+ def ram_poke(addr, value) = @ram.poke(addr, value)
182
+
183
+ private
184
+
185
+ def register_value(register)
186
+ case register
187
+ when STATUS then @status
188
+ when COMMAND then @command
189
+ when C64_LOW then @c64 & 0xff
190
+ when C64_HIGH then @c64 >> 8
191
+ when EXPANSION_LOW then @expansion & 0xff
192
+ when EXPANSION_HIGH then @expansion >> 8
193
+ when EXPANSION_BANK then @bank | BANK_STUCK
194
+ when LENGTH_LOW then @length & 0xff
195
+ when LENGTH_HIGH then @length >> 8
196
+ when INTERRUPT_MASK then @interrupt_mask
197
+ when ADDRESS_CONTROL then @address_control
198
+ else 0xff
199
+ end
200
+ end
201
+
202
+ def read_status
203
+ @status &= CHIPS_256K
204
+ interrupt(false)
205
+ end
206
+
207
+ # Writing either byte of an address or the length sets the value the
208
+ # transfer starts from, and puts the counter back to it.
209
+ def with_byte(word, value, high)
210
+ high ? (word & 0x00ff) | (value << 8) : (word & 0xff00) | value
211
+ end
212
+
213
+ def write_command(value)
214
+ @command = value
215
+ return if value.nobits?(EXECUTE)
216
+
217
+ @armed = value.nobits?(NO_FF00_TRIGGER)
218
+ request_bus unless @armed
219
+ end
220
+
221
+ # An interrupt enabled over a block that already ended, or a fault
222
+ # already found, fires at once.
223
+ def write_interrupt_mask(value)
224
+ @interrupt_mask = value | 0x1f
225
+ interrupt_on(@status)
226
+ end
227
+
228
+ def interrupt_on(events)
229
+ return unless @interrupt_mask.anybits?(INTERRUPTS_ON)
230
+ return unless (events.anybits?(END_OF_BLOCK) && @interrupt_mask.anybits?(INTERRUPT_ON_END)) ||
231
+ (events.anybits?(FAULT) && @interrupt_mask.anybits?(INTERRUPT_ON_FAULT))
232
+
233
+ @status |= INTERRUPT_PENDING
234
+ interrupt(true)
235
+ end
236
+
237
+ def interrupt(level)
238
+ return if @irq == level
239
+
240
+ @irq = level
241
+ @on_irq_change&.call(level)
242
+ end
243
+
244
+ def request_bus
245
+ @requested = true
246
+ @ba_was_low = @vic.ba_low?
247
+ @on_dma&.call
248
+ end
249
+
250
+ def hold_off
251
+ @dma.write_ahead(@command & TRANSFER_TYPE, @c64, @expansion | (@bank << 16)) unless @ba_was_low
252
+ @ba_was_low = true
253
+ end
254
+
255
+ def start_transfer
256
+ @requested = false
257
+ @running = true
258
+ @dma.start(@command & TRANSFER_TYPE, @c64, @expansion | (@bank << 16), @length, @address_control)
259
+ end
260
+
261
+ # The execute bit drops and the $FF00 trigger turns off. With autoload
262
+ # the addresses and the length go back to where the transfer started,
263
+ # and otherwise they stay where it stopped.
264
+ def end_transfer
265
+ @running = false
266
+ @command = (@command & ~EXECUTE & 0xff) | NO_FF00_TRIGGER
267
+ events = @dma.events
268
+ @status |= events
269
+ @command.anybits?(AUTOLOAD) ? reload : keep_counters
270
+ interrupt_on(events)
271
+ end
272
+
273
+ def reload
274
+ @c64 = @c64_start
275
+ @expansion = @expansion_start
276
+ @bank = @bank_start
277
+ @length = @length_start
278
+ end
279
+
280
+ def keep_counters
281
+ @c64 = @dma.c64 if @address_control.nobits?(FIX_C64)
282
+ @length = @dma.length & 0xffff
283
+ return if @address_control.anybits?(FIX_EXPANSION)
284
+
285
+ address = @dma.expansion & @address_mask
286
+ @expansion = address & 0xffff
287
+ @bank = (address >> 16) & 0xff
288
+ end
289
+ end
290
+ end
291
+ end
@@ -1,15 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Badline
4
- class Computer
5
- # The keyword arguments Computer.new takes to build the machine a
4
+ class C64
5
+ # The keyword arguments C64.new takes to build the machine a
6
6
  # State from #snapshot was taken of.
7
- def self.setup(state)
8
- input = Snapshot::StateReader.new(state)
9
- input.marker("COMPUTER")
10
- input.check_stamp
11
- Snapshot::Setup.read(input)
12
- end
7
+ def self.setup(state) = Snapshot::C64Setup.from(state)
13
8
 
14
9
  # A new machine, built as the one a State from #snapshot was taken of,
15
10
  # at that state. `detached` builds it without the host's files
@@ -44,13 +39,13 @@ module Badline
44
39
  # The state goes into a new machine first, so one that fails leaves
45
40
  # this machine as it was.
46
41
  def restore(state)
47
- check_setup(Computer.setup(state))
48
- Computer.restored(state)
42
+ check_setup(C64.setup(state))
43
+ C64.restored(state)
49
44
  apply_state(state)
50
45
  end
51
46
 
52
47
  # Puts a State into the machine without trying it on a new one
53
- # first, for a machine built for it (Computer.restored): a state that
48
+ # first, for a machine built for it (C64.restored): a state that
54
49
  # fails leaves the machine part restored. `detached` restores it
55
50
  # without the host's files (Snapshot::StateReader).
56
51
  def apply_state(state, detached: false)
@@ -68,8 +63,8 @@ module Badline
68
63
  end
69
64
 
70
65
  def save_state(out)
71
- out.marker("COMPUTER").stamp
72
- Snapshot::Setup.of(address_bus).write(out)
66
+ out.marker(Snapshot::C64Setup::MARKER).stamp
67
+ Snapshot::C64Setup.of(address_bus).write(out)
73
68
  out.int(@cycles).boolean(@nmi_asserted).boolean(@cartridge_nmi).boolean(@restore_pulse).boolean(@freezing)
74
69
  out.int(@freeze_writes).boolean(!@pending_keys.nil?)
75
70
  out.ints(@pending_keys) if @pending_keys
@@ -77,15 +72,15 @@ module Badline
77
72
  save_cartridge(out)
78
73
  address_bus.save_state(out)
79
74
  @cpu.save_state(out)
80
- save_trap_drive(out)
75
+ save_trap_dos(out)
81
76
  save_serial_bus(out)
82
77
  save_reu(out)
83
78
  end
84
79
 
85
80
  def load_state(input)
86
- input.marker("COMPUTER")
81
+ input.marker(Snapshot::C64Setup::MARKER)
87
82
  input.check_stamp
88
- check_setup(Snapshot::Setup.read(input))
83
+ check_setup(Snapshot::C64Setup.read(input))
89
84
  @cycles = input.int
90
85
  @nmi_asserted = input.boolean?
91
86
  @cartridge_nmi = input.boolean?
@@ -99,7 +94,7 @@ module Badline
99
94
  address_bus.load_state(input)
100
95
  push_serial_lines
101
96
  @cpu.load_state(input)
102
- load_trap_drive(input)
97
+ load_trap_dos(input)
103
98
  load_serial_bus(input)
104
99
  load_reu(input)
105
100
  end
@@ -107,7 +102,7 @@ module Badline
107
102
  private
108
103
 
109
104
  def check_setup(setup)
110
- ours = Snapshot::Setup.of(address_bus)
105
+ ours = Snapshot::C64Setup.of(address_bus)
111
106
  return if setup == ours
112
107
 
113
108
  raise Snapshot::FormatError, "the state is of a machine with #{setup}, not #{ours}"
@@ -1,14 +1,14 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Badline
4
- class Computer
5
- # The true drives on the machine's serial bus: a Drive1541, and a
6
- # Drive1581 (Drive1581::Slot), each in a field of its own. Computer,
4
+ class C64
5
+ # The true drives on the machine's serial bus: a Drives::Model1541, and a
6
+ # Drives::Model1581 (Drives::Model1581::Slot), each in a field of its own. C64,
7
7
  # Vic20 and C128 each include it.
8
8
  module TrueDrives
9
- include Drive1581::Slot
9
+ include Drives::Model1581::Slot
10
10
 
11
- # Plugs in a Drive1541, which then runs alongside the machine on its
11
+ # Plugs in a Drives::Model1541, which then runs alongside the machine on its
12
12
  # own clock and talks to it over the serial bus. The serial traps stop
13
13
  # answering the drive's device number, so the KERNAL's TALK, LISTEN and
14
14
  # byte transfers reach the drive. The LOAD and SAVE traps stay, and
@@ -22,18 +22,18 @@ module Badline
22
22
  drive1541_attached
23
23
  end
24
24
 
25
- # The true drive on the serial bus: the Drive1581 ahead of the
26
- # Drive1541, or nil.
25
+ # The true drive on the serial bus: the Drives::Model1581 ahead of the
26
+ # Drives::Model1541, or nil.
27
27
  def true_drive = @drive1581 || @drive1541
28
28
 
29
- # Plugs a Drive1541 in as device 8, in place of a 1581 there, and
29
+ # Plugs a Drives::Model1541 in as device 8, in place of a 1581 there, and
30
30
  # returns it.
31
31
  def plug_true_drive
32
32
  detach_drive1581 if drive1581_on_device8?
33
- Drive1541.new.tap { |drive| attach_drive1541(drive) }
33
+ Drives::Model1541.new.tap { |drive| attach_drive1541(drive) }
34
34
  end
35
35
 
36
- # Unplugs the Drive1541, leaving the serial bus with nothing on it.
36
+ # Unplugs the Drives::Model1541, leaving the serial bus with nothing on it.
37
37
  def detach_drive1541
38
38
  return unless @drive1541
39
39
 
@@ -61,7 +61,7 @@ module Badline
61
61
 
62
62
  device = input.int
63
63
  detach_drive1541 if @drive1541 && @drive1541.device != device
64
- attach_drive1541(Drive1541.new(device:)) unless @drive1541
64
+ attach_drive1541(Drives::Model1541.new(device:)) unless @drive1541
65
65
  @drive1541.load_state(input)
66
66
  end
67
67
  end
@@ -1,13 +1,13 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "badline/computer/common"
4
- require "badline/computer/true_drives"
5
- require "badline/computer/attachments"
6
- require "badline/computer/kernal_traps"
7
- require "badline/computer/saved_state"
3
+ require "badline/c64/common"
4
+ require "badline/c64/true_drives"
5
+ require "badline/c64/attachments"
6
+ require "badline/c64/kernal_traps"
7
+ require "badline/c64/saved_state"
8
8
 
9
9
  module Badline
10
- class Computer
10
+ class C64
11
11
  include IntegerHelper
12
12
  include KeyboardBuffer
13
13
  include Machine::Clocking
@@ -32,6 +32,11 @@ module Badline
32
32
 
33
33
  def ram = address_bus.ram
34
34
 
35
+ # Reads and writes memory as the CPU sees it, through the bus.
36
+ def peek(addr) = address_bus.peek(addr)
37
+
38
+ def poke(addr, value) = address_bus.poke(addr, value)
39
+
35
40
  def keyboard = address_bus.keyboard
36
41
 
37
42
  def joystick1 = address_bus.joystick1
@@ -45,18 +50,18 @@ module Badline
45
50
  def install_debug_register(&) = address_bus.install_debug_register(&)
46
51
 
47
52
  # The machine options (sid_model:, cia_model:, vic_model:, region: and
48
- # ram_expansion:) configure the AddressBus. The region sets the clock,
53
+ # ram_expansion:) configure the C64::Bus. The region sets the clock,
49
54
  # the VIC's raster and sprite timing, and the mains frequency the CIAs'
50
55
  # TOD clocks count. The KERNAL tells PAL from NTSC by the raster, so
51
56
  # every region boots the same ROMs. reu plugs an REU of that many K
52
57
  # into the expansion port, where it drives the IRQ line and takes the
53
58
  # bus for its transfers. kernal:, datasette: and board: fit the bus
54
- # afterwards (AddressBus::Fittings): the KERNAL ROM, the cassette port,
59
+ # afterwards (C64::Bus::Fittings): the KERNAL ROM, the cassette port,
55
60
  # which is empty on the SX-64, and the board and case.
56
61
  def initialize(debug: false, reu: nil, **machine)
57
- @address_bus = AddressBus.new(**machine.except(*AddressBus::Fittings::NAMES))
58
- @address_bus.fit(**machine.slice(*AddressBus::Fittings::NAMES))
59
- @cpu = CPU.new(@address_bus, debug:)
62
+ @address_bus = Bus.new(**machine.except(*Bus::Fittings::NAMES))
63
+ @address_bus.fit(**machine.slice(*Bus::Fittings::NAMES))
64
+ @cpu = Chips::CPU.new(@address_bus, debug:)
60
65
  @vic = @address_bus.vic
61
66
  @vic.open_bus = -> { @address_bus.ram.peek(@cpu.program_counter) }
62
67
  @cia1 = @address_bus.cia1
@@ -73,7 +78,7 @@ module Badline
73
78
  @freeze_writes = 0
74
79
  @init_handlers = []
75
80
  @pending_keys = nil
76
- @drive = nil
81
+ @dos = nil
77
82
  @serial_trap = nil
78
83
  @save_trap = nil
79
84
  @drive1541 = nil
@@ -145,7 +150,7 @@ module Badline
145
150
  address_bus.cartridge&.reset
146
151
  @reu&.reset!
147
152
  @dma = false
148
- @drive&.reset!
153
+ @dos&.reset!
149
154
  @drive1541&.reset!
150
155
  @drive1581&.reset!
151
156
  @freezing = false
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Chips
5
+ class CIA
6
+ # Running a CIA a stretch of cycles at once, for Drives::Engine::Idle.
7
+ module FastForward
8
+ # quiet_cycles for a CIA whose counters will never set a flag.
9
+ QUIET = 1 << 40
10
+
11
+ # Whether fast_forward can run the CIA: timer B stopped with nothing
12
+ # in its pipeline, no interrupt or acknowledge on its way, CNT where it
13
+ # was, the TOD clock stopped, and timer A either stopped, or free
14
+ # running (Timer#free_running?) with its interrupt masked and the
15
+ # serial port an idle input. Drives::Engine::Idle sleeps the 1571's CIA through
16
+ # such cycles, which its DOS leaves timer A running in.
17
+ def quiet?
18
+ return false unless @tb.idle? && @icr.quiet && @tod.quiet? && cnt_steady?
19
+
20
+ @ta.idle? ? @serial.idle : timer_a_free_running?
21
+ end
22
+
23
+ # How many cycles the CIA can run with nothing but its counters
24
+ # moving: as quiet? allows, but with timer B free running too, up to
25
+ # the cycle before it underflows. The 1581's DOS leaves timer B
26
+ # interrupting every 10 ms.
27
+ def quiet_cycles
28
+ return 0 unless @icr.quiet && @tod.quiet? && cnt_steady? && timer_a_quiet?
29
+ return QUIET if @tb.idle?
30
+ return 0 unless @tb.free_running? && @control_b.value.nobits?(0x60)
31
+
32
+ @tb.counter - 1
33
+ end
34
+
35
+ # Runs +cycles+ cycles at once while quiet? or for quiet_cycles, as
36
+ # cycle! would: timer A's underflows flag in the ICR, and reach the
37
+ # serial port's underflow line.
38
+ def fast_forward(cycles)
39
+ @tod.fast_forward(cycles)
40
+ @tb.fast_forward(cycles) unless @tb.idle?
41
+ return if @ta.idle?
42
+
43
+ @icr.flag(:timer_a) if @ta.fast_forward(cycles).positive?
44
+ @serial.follow_underflow(@ta.underflowed)
45
+ end
46
+
47
+ private
48
+
49
+ def timer_a_quiet? = @ta.idle? ? @serial.idle : timer_a_free_running?
50
+
51
+ # Timer A free running with its interrupt masked, and the serial port
52
+ # an idle input it only clocks.
53
+ def timer_a_free_running?
54
+ @ta.free_running? && !@control_a.serial_mode? && @icr.mask.value.nobits?(0x01) && @serial.drained?
55
+ end
56
+
57
+ # Whether CNT holds the level the last cycle sampled.
58
+ def cnt_steady? = @serial.cnt == @cnt_high && !@cnt_rise
59
+ end
60
+ end
61
+ end
62
+ end