badline 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (516) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/CLAUDE.md +59 -31
  4. data/README.md +1 -1
  5. data/doc/library.md +9 -9
  6. data/doc/pinned-behaviour.md +105 -105
  7. data/doc/snapshots.md +1 -4
  8. data/lib/badline/audio/bare_player.rb +4 -4
  9. data/lib/badline/audio/cli.rb +6 -6
  10. data/lib/badline/audio/jukebox.rb +2 -2
  11. data/lib/badline/audio/machine_player.rb +2 -2
  12. data/lib/badline/{media → audio}/queue.rb +1 -1
  13. data/lib/badline/audio/queued_tune.rb +6 -6
  14. data/lib/badline/audio/renderer.rb +5 -5
  15. data/lib/badline/audio/stereo.rb +1 -1
  16. data/lib/badline/c128/{bus_state.rb → bus/saved_state.rb} +6 -6
  17. data/lib/badline/c128/bus.rb +30 -51
  18. data/lib/badline/c128/color_lines.rb +2 -2
  19. data/lib/badline/c128/cpu.rb +1 -1
  20. data/lib/badline/c128/drives.rb +10 -11
  21. data/lib/badline/c128/fast_serial.rb +5 -5
  22. data/lib/badline/c128/mmu_pages.rb +1 -1
  23. data/lib/badline/c128/modes.rb +2 -2
  24. data/lib/badline/c128/saved_state.rb +21 -47
  25. data/lib/badline/c128/z80.rb +2 -2
  26. data/lib/badline/c128.rb +18 -72
  27. data/lib/badline/{computer → c64}/attachments.rb +16 -47
  28. data/lib/badline/c64/banked_ram/banking.rb +32 -0
  29. data/lib/badline/c64/banked_ram/plus256k.rb +56 -0
  30. data/lib/badline/c64/banked_ram/plus60k.rb +45 -0
  31. data/lib/badline/c64/banked_ram/unexpanded.rb +30 -0
  32. data/lib/badline/c64/banked_ram.rb +23 -0
  33. data/lib/badline/c64/bus/extra_sids.rb +32 -0
  34. data/lib/badline/c64/bus/fittings.rb +40 -0
  35. data/lib/badline/c64/bus/pla.rb +149 -0
  36. data/lib/badline/c64/bus/roms.rb +41 -0
  37. data/lib/badline/c64/bus/saved_state.rb +68 -0
  38. data/lib/badline/c64/bus/sid_slots.rb +44 -0
  39. data/lib/badline/c64/bus.rb +218 -0
  40. data/lib/badline/c64/cartridge/action_replay.rb +128 -0
  41. data/lib/badline/c64/cartridge/atomic_power.rb +26 -0
  42. data/lib/badline/c64/cartridge/bank.rb +83 -0
  43. data/lib/badline/c64/cartridge/comal80.rb +52 -0
  44. data/lib/badline/c64/cartridge/dinamic.rb +36 -0
  45. data/lib/badline/c64/cartridge/easy_flash.rb +147 -0
  46. data/lib/badline/c64/cartridge/epyx_fastload.rb +81 -0
  47. data/lib/badline/c64/cartridge/final_cartridge3.rb +91 -0
  48. data/lib/badline/c64/cartridge/flash/saved_state.rb +40 -0
  49. data/lib/badline/c64/cartridge/flash.rb +279 -0
  50. data/lib/badline/c64/cartridge/freezer.rb +35 -0
  51. data/lib/badline/c64/cartridge/fun_play.rb +40 -0
  52. data/lib/badline/c64/cartridge/g_mod2.rb +76 -0
  53. data/lib/badline/c64/cartridge/game_system.rb +42 -0
  54. data/lib/badline/c64/cartridge/geo_ram.rb +81 -0
  55. data/lib/badline/c64/cartridge/kcs_power.rb +77 -0
  56. data/lib/badline/c64/cartridge/mach5.rb +34 -0
  57. data/lib/badline/c64/cartridge/magic_desk.rb +32 -0
  58. data/lib/badline/c64/cartridge/ocean.rb +37 -0
  59. data/lib/badline/c64/cartridge/pagefox.rb +70 -0
  60. data/lib/badline/c64/cartridge/retro_replay/saved_state.rb +47 -0
  61. data/lib/badline/c64/cartridge/retro_replay.rb +286 -0
  62. data/lib/badline/c64/cartridge/rex_utility.rb +31 -0
  63. data/lib/badline/c64/cartridge/rgcd.rb +60 -0
  64. data/lib/badline/c64/cartridge/saved_state.rb +63 -0
  65. data/lib/badline/c64/cartridge/simons_basic.rb +37 -0
  66. data/lib/badline/c64/cartridge/standard.rb +17 -0
  67. data/lib/badline/c64/cartridge/super_games.rb +50 -0
  68. data/lib/badline/c64/cartridge/westermann.rb +32 -0
  69. data/lib/badline/c64/cartridge/zaxxon.rb +68 -0
  70. data/lib/badline/c64/cartridge.rb +258 -0
  71. data/lib/badline/c64/color_memory.rb +27 -0
  72. data/lib/badline/c64/common.rb +34 -0
  73. data/lib/badline/c64/kernal_traps.rb +89 -0
  74. data/lib/badline/c64/reu/dma/saved_state.rb +52 -0
  75. data/lib/badline/c64/reu/dma.rb +275 -0
  76. data/lib/badline/c64/reu/ram.rb +109 -0
  77. data/lib/badline/c64/reu/saved_state.rb +55 -0
  78. data/lib/badline/c64/reu/trigger.rb +34 -0
  79. data/lib/badline/c64/reu.rb +291 -0
  80. data/lib/badline/{computer → c64}/saved_state.rb +13 -18
  81. data/lib/badline/{computer → c64}/true_drives.rb +20 -31
  82. data/lib/badline/{computer.rb → c64.rb} +22 -80
  83. data/lib/badline/chips/cia/fast_forward.rb +62 -0
  84. data/lib/badline/chips/cia/interrupt_register.rb +145 -0
  85. data/lib/badline/chips/cia/saved_state.rb +49 -0
  86. data/lib/badline/chips/cia/serial/saved_state.rb +45 -0
  87. data/lib/badline/chips/cia/serial.rb +250 -0
  88. data/lib/badline/chips/cia/time_of_day.rb +232 -0
  89. data/lib/badline/chips/cia/timer.rb +208 -0
  90. data/lib/badline/chips/cia.rb +281 -0
  91. data/lib/badline/chips/cpu/addressing.rb +133 -0
  92. data/lib/badline/chips/cpu/boundary.rb +56 -0
  93. data/lib/badline/chips/cpu/core.rb +167 -0
  94. data/lib/badline/chips/cpu/instruction.rb +338 -0
  95. data/lib/badline/chips/cpu/instruction_set/arithmetic.rb +118 -0
  96. data/lib/badline/chips/cpu/instruction_set/bitwise.rb +130 -0
  97. data/lib/badline/chips/cpu/instruction_set/branch.rb +83 -0
  98. data/lib/badline/chips/cpu/instruction_set/flag.rb +67 -0
  99. data/lib/badline/chips/cpu/instruction_set/illegal.rb +274 -0
  100. data/lib/badline/chips/cpu/instruction_set/inc_dec.rb +73 -0
  101. data/lib/badline/chips/cpu/instruction_set/stack.rb +56 -0
  102. data/lib/badline/chips/cpu/instruction_set/transfer.rb +141 -0
  103. data/lib/badline/chips/cpu/instruction_set.rb +59 -0
  104. data/lib/badline/chips/cpu/interrupts.rb +108 -0
  105. data/lib/badline/chips/cpu/microcode.rb +179 -0
  106. data/lib/badline/chips/cpu/operations.rb +90 -0
  107. data/lib/badline/chips/cpu/port.rb +116 -0
  108. data/lib/badline/chips/cpu/saved_state.rb +117 -0
  109. data/lib/badline/chips/cpu/stack_operations.rb +84 -0
  110. data/lib/badline/chips/cpu/traps.rb +23 -0
  111. data/lib/badline/chips/cpu.rb +12 -0
  112. data/lib/badline/chips/sid/catch_up.rb +122 -0
  113. data/lib/badline/chips/sid/decimator.rb +66 -0
  114. data/lib/badline/chips/sid/envelope/saved_state.rb +70 -0
  115. data/lib/badline/chips/sid/envelope.rb +241 -0
  116. data/lib/badline/chips/sid/filter/saved_state.rb +42 -0
  117. data/lib/badline/chips/sid/filter.rb +241 -0
  118. data/lib/badline/chips/sid/saved_state.rb +52 -0
  119. data/lib/badline/chips/sid/voice.rb +79 -0
  120. data/lib/badline/chips/sid/waveform/combined.rb +128 -0
  121. data/lib/badline/chips/sid/waveform/fast_forward.rb +107 -0
  122. data/lib/badline/chips/sid/waveform/noise_writeback.rb +124 -0
  123. data/lib/badline/chips/sid/waveform/saved_state.rb +68 -0
  124. data/lib/badline/chips/sid/waveform.rb +307 -0
  125. data/lib/badline/chips/sid.rb +265 -0
  126. data/lib/badline/{c128 → chips}/vdc/memory.rb +1 -1
  127. data/lib/badline/{c128 → chips}/vdc/painter.rb +1 -1
  128. data/lib/badline/{c128 → chips}/vdc/raster.rb +1 -1
  129. data/lib/badline/chips/vdc/saved_state.rb +36 -0
  130. data/lib/badline/{c128 → chips}/vdc/window.rb +1 -1
  131. data/lib/badline/{c128 → chips}/vdc.rb +7 -31
  132. data/lib/badline/chips/via/control_lines.rb +124 -0
  133. data/lib/badline/chips/via/fast_forward.rb +55 -0
  134. data/lib/badline/chips/via/interrupt_register.rb +69 -0
  135. data/lib/badline/chips/via/saved_state.rb +44 -0
  136. data/lib/badline/chips/via/shift_register.rb +182 -0
  137. data/lib/badline/chips/via/timer1.rb +133 -0
  138. data/lib/badline/chips/via/timer2.rb +135 -0
  139. data/lib/badline/chips/via.rb +268 -0
  140. data/lib/badline/chips/vic/bank.rb +135 -0
  141. data/lib/badline/chips/vic/border_mask.rb +88 -0
  142. data/lib/badline/chips/vic/collisions.rb +117 -0
  143. data/lib/badline/chips/vic/color_patches.rb +49 -0
  144. data/lib/badline/chips/vic/display_state.rb +187 -0
  145. data/lib/badline/chips/vic/graphics_mode.rb +166 -0
  146. data/lib/badline/chips/vic/graphics_shifter/saved_state.rb +40 -0
  147. data/lib/badline/chips/vic/graphics_shifter.rb +187 -0
  148. data/lib/badline/chips/vic/register_log.rb +83 -0
  149. data/lib/badline/chips/vic/registers.rb +197 -0
  150. data/lib/badline/chips/vic/saved_state.rb +82 -0
  151. data/lib/badline/chips/vic/sequencer/saved_state.rb +91 -0
  152. data/lib/badline/chips/vic/sequencer.rb +277 -0
  153. data/lib/badline/chips/vic/sequencer_output.rb +118 -0
  154. data/lib/badline/chips/vic/sprite/internal_bus.rb +70 -0
  155. data/lib/badline/chips/vic/sprite/saved_state.rb +66 -0
  156. data/lib/badline/chips/vic/sprite/shifter.rb +148 -0
  157. data/lib/badline/chips/vic/sprite/timing.rb +58 -0
  158. data/lib/badline/chips/vic/sprite.rb +339 -0
  159. data/lib/badline/chips/vic/sprites/saved_state.rb +59 -0
  160. data/lib/badline/chips/vic/sprites.rb +284 -0
  161. data/lib/badline/chips/vic.rb +783 -0
  162. data/lib/badline/chips/vic_i/painter/saved_state.rb +40 -0
  163. data/lib/badline/{vic20/vic → chips/vic_i}/painter.rb +6 -30
  164. data/lib/badline/{vic20/vic → chips/vic_i}/saved_state.rb +2 -2
  165. data/lib/badline/chips/vic_i/sound/output.rb +85 -0
  166. data/lib/badline/chips/vic_i/sound.rb +235 -0
  167. data/lib/badline/{vic20/vic → chips/vic_i}/text_window.rb +2 -2
  168. data/lib/badline/{vic20/vic.rb → chips/vic_i.rb} +5 -5
  169. data/lib/badline/chips/z80/arithmetic.rb +119 -0
  170. data/lib/badline/chips/z80/bit_page.rb +57 -0
  171. data/lib/badline/chips/z80/block_io.rb +60 -0
  172. data/lib/badline/chips/z80/block_transfers.rb +61 -0
  173. data/lib/badline/chips/z80/bus_cycles.rb +113 -0
  174. data/lib/badline/chips/z80/core.rb +115 -0
  175. data/lib/badline/chips/z80/exchanges.rb +52 -0
  176. data/lib/badline/chips/z80/extended_page.rb +91 -0
  177. data/lib/badline/chips/z80/flags.rb +39 -0
  178. data/lib/badline/chips/z80/interrupt_acceptance.rb +48 -0
  179. data/lib/badline/chips/z80/jumps.rb +84 -0
  180. data/lib/badline/chips/z80/loads.rb +100 -0
  181. data/lib/badline/chips/z80/main_page.rb +136 -0
  182. data/lib/badline/chips/z80/registers.rb +122 -0
  183. data/lib/badline/chips/z80/saved_state.rb +71 -0
  184. data/lib/badline/chips/z80/shifts.rb +66 -0
  185. data/lib/badline/chips/z80.rb +13 -0
  186. data/lib/badline/core.rb +27 -29
  187. data/lib/badline/drives/datasette/saved_state.rb +37 -0
  188. data/lib/badline/drives/datasette.rb +140 -0
  189. data/lib/badline/drives/engine/core.rb +149 -0
  190. data/lib/badline/drives/engine/fast_serial.rb +75 -0
  191. data/lib/badline/drives/engine/idle.rb +127 -0
  192. data/lib/badline/drives/engine/idle_cpu.rb +30 -0
  193. data/lib/badline/drives/engine/orbit.rb +81 -0
  194. data/lib/badline/drives/engine/serial_lines.rb +75 -0
  195. data/lib/badline/drives/engine/sleep.rb +114 -0
  196. data/lib/badline/drives/engine/vias.rb +86 -0
  197. data/lib/badline/drives/engine/watch.rb +152 -0
  198. data/lib/badline/drives/engine.rb +11 -0
  199. data/lib/badline/drives/model1541/bus.rb +88 -0
  200. data/lib/badline/drives/model1541/byte_ready.rb +50 -0
  201. data/lib/badline/drives/model1541/cpu.rb +13 -0
  202. data/lib/badline/drives/model1541/disk/saved_state.rb +88 -0
  203. data/lib/badline/drives/model1541/disk.rb +317 -0
  204. data/lib/badline/drives/model1541/disk_via.rb +38 -0
  205. data/lib/badline/drives/model1541/gcr.rb +59 -0
  206. data/lib/badline/drives/model1541/mechanism/saved_state.rb +72 -0
  207. data/lib/badline/drives/model1541/mechanism.rb +315 -0
  208. data/lib/badline/drives/model1541/rotation.rb +123 -0
  209. data/lib/badline/drives/model1541/saved_state.rb +44 -0
  210. data/lib/badline/drives/model1541/sector_reader.rb +78 -0
  211. data/lib/badline/drives/model1541/serial_port.rb +20 -0
  212. data/lib/badline/drives/model1541/track.rb +100 -0
  213. data/lib/badline/drives/model1541.rb +81 -0
  214. data/lib/badline/drives/model1571/bus.rb +113 -0
  215. data/lib/badline/drives/model1571/cpu.rb +13 -0
  216. data/lib/badline/drives/model1571/saved_state.rb +47 -0
  217. data/lib/badline/drives/model1571/serial_port.rb +39 -0
  218. data/lib/badline/drives/model1571/serial_via.rb +27 -0
  219. data/lib/badline/drives/model1571/wd1770.rb +122 -0
  220. data/lib/badline/drives/model1571.rb +142 -0
  221. data/lib/badline/drives/model1581/bus.rb +139 -0
  222. data/lib/badline/drives/model1581/cpu.rb +13 -0
  223. data/lib/badline/drives/model1581/disk/saved_state.rb +89 -0
  224. data/lib/badline/drives/model1581/disk.rb +137 -0
  225. data/lib/badline/drives/model1581/mechanism.rb +119 -0
  226. data/lib/badline/drives/model1581/saved_state.rb +42 -0
  227. data/lib/badline/drives/model1581/serial_port.rb +54 -0
  228. data/lib/badline/drives/model1581/slot.rb +79 -0
  229. data/lib/badline/drives/model1581/track.rb +102 -0
  230. data/lib/badline/drives/model1581/track_bytes.rb +77 -0
  231. data/lib/badline/drives/model1581/wd1772/registers.rb +91 -0
  232. data/lib/badline/drives/model1581/wd1772/saved_state.rb +68 -0
  233. data/lib/badline/drives/model1581/wd1772/sector_writes.rb +75 -0
  234. data/lib/badline/drives/model1581/wd1772/sectors.rb +152 -0
  235. data/lib/badline/drives/model1581/wd1772/stepping.rb +111 -0
  236. data/lib/badline/drives/model1581/wd1772/tracks.rb +127 -0
  237. data/lib/badline/drives/model1581/wd1772/turn.rb +75 -0
  238. data/lib/badline/drives/model1581/wd1772.rb +218 -0
  239. data/lib/badline/drives/model1581.rb +206 -0
  240. data/lib/badline/drives/serial_bus.rb +161 -0
  241. data/lib/badline/frontend/boot.rb +10 -61
  242. data/lib/badline/frontend/machine_window.rb +3 -1
  243. data/lib/badline/frontend/player/filter_view.rb +1 -1
  244. data/lib/badline/frontend/player/player_controller.rb +2 -2
  245. data/lib/badline/frontend/player/player_screen.rb +1 -0
  246. data/lib/badline/frontend/player/theme.rb +7 -7
  247. data/lib/badline/frontend/timeline.rb +3 -3
  248. data/lib/badline/input/control_ports.rb +78 -0
  249. data/lib/badline/input/joystick.rb +27 -0
  250. data/lib/badline/input/keyboard.rb +114 -0
  251. data/lib/badline/input.rb +3 -0
  252. data/lib/badline/kernal_trap/{drive → dos}/block_commands.rb +1 -1
  253. data/lib/badline/kernal_trap/dos/channel.rb +183 -0
  254. data/lib/badline/kernal_trap/{drive → dos}/channels.rb +1 -1
  255. data/lib/badline/kernal_trap/{drive → dos}/memory.rb +1 -1
  256. data/lib/badline/kernal_trap/{drive → dos}/parameters.rb +1 -1
  257. data/lib/badline/kernal_trap/{drive → dos}/status.rb +1 -1
  258. data/lib/badline/kernal_trap/{drive → dos}/write_file.rb +1 -1
  259. data/lib/badline/kernal_trap/{drive → dos}/writes.rb +1 -1
  260. data/lib/badline/kernal_trap/{drive.rb → dos.rb} +11 -10
  261. data/lib/badline/kernal_trap/{file.rb → file_routine.rb} +1 -1
  262. data/lib/badline/kernal_trap/load.rb +6 -6
  263. data/lib/badline/kernal_trap/save.rb +5 -5
  264. data/lib/badline/kernal_trap/serial.rb +7 -7
  265. data/lib/badline/kernal_trap.rb +2 -3
  266. data/lib/badline/machine/clocking.rb +50 -0
  267. data/lib/badline/machine.rb +63 -7
  268. data/lib/badline/media/boot_disk.rb +2 -2
  269. data/lib/badline/media/disk_list.rb +3 -3
  270. data/lib/badline/media/disk_set.rb +1 -1
  271. data/lib/badline/media/extensions.rb +33 -0
  272. data/lib/badline/media/program.rb +28 -0
  273. data/lib/badline/media/true_drive.rb +4 -3
  274. data/lib/badline/media/tune.rb +35 -0
  275. data/lib/badline/media/vic20_cartridge.rb +1 -7
  276. data/lib/badline/media/vic20_media.rb +38 -80
  277. data/lib/badline/media.rb +84 -81
  278. data/lib/badline/model.rb +1 -1
  279. data/lib/badline/options/event.rb +3 -1
  280. data/lib/badline/roms/README +6 -6
  281. data/lib/badline/sdl.rb +1 -0
  282. data/lib/badline/{storage/sid_file.rb → sid_tune/file.rb} +3 -3
  283. data/lib/badline/{storage → sid_tune}/hvsc.rb +7 -7
  284. data/lib/badline/{storage → sid_tune}/song_lengths.rb +2 -2
  285. data/lib/badline/{storage → sid_tune}/stil/credit.rb +1 -1
  286. data/lib/badline/{storage → sid_tune}/stil.rb +3 -3
  287. data/lib/badline/sid_tune.rb +6 -0
  288. data/lib/badline/snapshot/c128_setup.rb +43 -0
  289. data/lib/badline/snapshot/c64_setup.rb +79 -0
  290. data/lib/badline/snapshot/image.rb +5 -25
  291. data/lib/badline/snapshot/machine_state.rb +10 -2
  292. data/lib/badline/snapshot/setup.rb +22 -66
  293. data/lib/badline/snapshot/state.rb +8 -17
  294. data/lib/badline/snapshot/storage_setup.rb +68 -0
  295. data/lib/badline/snapshot/vic20_setup.rb +37 -0
  296. data/lib/badline/snapshot/vice/c64_mem.rb +1 -1
  297. data/lib/badline/snapshot/vice/restore.rb +1 -1
  298. data/lib/badline/snapshot/vice/reu1764.rb +1 -1
  299. data/lib/badline/snapshot/vice/reu_fields.rb +40 -0
  300. data/lib/badline/snapshot/vice.rb +7 -5
  301. data/lib/badline/snapshot.rb +13 -12
  302. data/lib/badline/storage/d64_image.rb +15 -9
  303. data/lib/badline/storage/d71_image.rb +0 -2
  304. data/lib/badline/storage/d81_image.rb +0 -2
  305. data/lib/badline/storage/disk_image/writing.rb +2 -2
  306. data/lib/badline/storage/disk_image.rb +3 -6
  307. data/lib/badline/storage/g64_image.rb +2 -2
  308. data/lib/badline/storage/host_directory.rb +0 -5
  309. data/lib/badline/storage/t64.rb +2 -8
  310. data/lib/badline/storage/unavailable.rb +1 -1
  311. data/lib/badline/storage.rb +0 -37
  312. data/lib/badline/support/c128_checkpoint.rb +39 -0
  313. data/lib/badline/support/checkpoint.rb +108 -0
  314. data/lib/badline/support/vic20_checkpoint.rb +38 -0
  315. data/lib/badline/support.rb +5 -0
  316. data/lib/badline/version.rb +1 -1
  317. data/lib/badline/vic20/attachments.rb +11 -81
  318. data/lib/badline/vic20/bus/saved_state.rb +35 -0
  319. data/lib/badline/vic20/bus.rb +3 -25
  320. data/lib/badline/vic20/cpu.rb +1 -1
  321. data/lib/badline/vic20/port_wiring.rb +4 -4
  322. data/lib/badline/vic20/saved_state.rb +16 -60
  323. data/lib/badline/vic20/user_via_ports.rb +2 -2
  324. data/lib/badline/vic20.rb +20 -51
  325. metadata +250 -221
  326. data/lib/badline/address_bus/extra_sids.rb +0 -30
  327. data/lib/badline/address_bus/fittings.rb +0 -38
  328. data/lib/badline/address_bus/pla.rb +0 -147
  329. data/lib/badline/address_bus/roms.rb +0 -39
  330. data/lib/badline/address_bus/saved_state.rb +0 -72
  331. data/lib/badline/address_bus/sid_slots.rb +0 -42
  332. data/lib/badline/address_bus.rb +0 -235
  333. data/lib/badline/cartridge/action_replay.rb +0 -126
  334. data/lib/badline/cartridge/atomic_power.rb +0 -24
  335. data/lib/badline/cartridge/bank.rb +0 -81
  336. data/lib/badline/cartridge/comal80.rb +0 -50
  337. data/lib/badline/cartridge/dinamic.rb +0 -34
  338. data/lib/badline/cartridge/easy_flash.rb +0 -145
  339. data/lib/badline/cartridge/epyx_fastload.rb +0 -79
  340. data/lib/badline/cartridge/final_cartridge3.rb +0 -89
  341. data/lib/badline/cartridge/flash.rb +0 -306
  342. data/lib/badline/cartridge/freezer.rb +0 -33
  343. data/lib/badline/cartridge/fun_play.rb +0 -38
  344. data/lib/badline/cartridge/g_mod2.rb +0 -74
  345. data/lib/badline/cartridge/game_system.rb +0 -40
  346. data/lib/badline/cartridge/geo_ram.rb +0 -79
  347. data/lib/badline/cartridge/kcs_power.rb +0 -75
  348. data/lib/badline/cartridge/mach5.rb +0 -32
  349. data/lib/badline/cartridge/magic_desk.rb +0 -30
  350. data/lib/badline/cartridge/ocean.rb +0 -35
  351. data/lib/badline/cartridge/pagefox.rb +0 -68
  352. data/lib/badline/cartridge/retro_replay.rb +0 -320
  353. data/lib/badline/cartridge/rex_utility.rb +0 -29
  354. data/lib/badline/cartridge/rgcd.rb +0 -58
  355. data/lib/badline/cartridge/simons_basic.rb +0 -35
  356. data/lib/badline/cartridge/standard.rb +0 -15
  357. data/lib/badline/cartridge/super_games.rb +0 -48
  358. data/lib/badline/cartridge/westermann.rb +0 -30
  359. data/lib/badline/cartridge/zaxxon.rb +0 -66
  360. data/lib/badline/cartridge.rb +0 -303
  361. data/lib/badline/checkpoint.rb +0 -98
  362. data/lib/badline/cia/fast_forward.rb +0 -60
  363. data/lib/badline/cia/interrupt_register.rb +0 -143
  364. data/lib/badline/cia/serial.rb +0 -275
  365. data/lib/badline/cia/state.rb +0 -47
  366. data/lib/badline/cia/timer.rb +0 -206
  367. data/lib/badline/cia.rb +0 -279
  368. data/lib/badline/color_memory.rb +0 -25
  369. data/lib/badline/computer/kernal_traps.rb +0 -29
  370. data/lib/badline/control_ports.rb +0 -76
  371. data/lib/badline/cpu/addressing.rb +0 -131
  372. data/lib/badline/cpu/boundary.rb +0 -54
  373. data/lib/badline/cpu/core.rb +0 -165
  374. data/lib/badline/cpu/microcode.rb +0 -177
  375. data/lib/badline/cpu/operations.rb +0 -88
  376. data/lib/badline/cpu/saved_state.rb +0 -115
  377. data/lib/badline/cpu/stack_operations.rb +0 -82
  378. data/lib/badline/cpu.rb +0 -10
  379. data/lib/badline/cycleable.rb +0 -38
  380. data/lib/badline/datasette.rb +0 -161
  381. data/lib/badline/drive/core.rb +0 -147
  382. data/lib/badline/drive/fast_serial.rb +0 -73
  383. data/lib/badline/drive/idle.rb +0 -125
  384. data/lib/badline/drive/idle_cpu.rb +0 -28
  385. data/lib/badline/drive/orbit.rb +0 -79
  386. data/lib/badline/drive/serial_lines.rb +0 -73
  387. data/lib/badline/drive/sleep.rb +0 -112
  388. data/lib/badline/drive/vias.rb +0 -84
  389. data/lib/badline/drive/watch.rb +0 -150
  390. data/lib/badline/drive.rb +0 -11
  391. data/lib/badline/drive1541/bus.rb +0 -86
  392. data/lib/badline/drive1541/byte_ready.rb +0 -48
  393. data/lib/badline/drive1541/cpu.rb +0 -11
  394. data/lib/badline/drive1541/disk.rb +0 -318
  395. data/lib/badline/drive1541/disk_state.rb +0 -94
  396. data/lib/badline/drive1541/disk_via.rb +0 -36
  397. data/lib/badline/drive1541/gcr.rb +0 -57
  398. data/lib/badline/drive1541/mechanism.rb +0 -313
  399. data/lib/badline/drive1541/mechanism_state.rb +0 -68
  400. data/lib/badline/drive1541/rotation.rb +0 -121
  401. data/lib/badline/drive1541/sector_reader.rb +0 -76
  402. data/lib/badline/drive1541/serial_port.rb +0 -18
  403. data/lib/badline/drive1541/track.rb +0 -98
  404. data/lib/badline/drive1541.rb +0 -111
  405. data/lib/badline/drive1571/bus.rb +0 -111
  406. data/lib/badline/drive1571/cpu.rb +0 -11
  407. data/lib/badline/drive1571/serial_port.rb +0 -37
  408. data/lib/badline/drive1571/serial_via.rb +0 -25
  409. data/lib/badline/drive1571/wd1770.rb +0 -120
  410. data/lib/badline/drive1571.rb +0 -175
  411. data/lib/badline/drive1581/bus.rb +0 -137
  412. data/lib/badline/drive1581/cpu.rb +0 -11
  413. data/lib/badline/drive1581/disk.rb +0 -135
  414. data/lib/badline/drive1581/disk_state.rb +0 -87
  415. data/lib/badline/drive1581/mechanism.rb +0 -117
  416. data/lib/badline/drive1581/serial_port.rb +0 -52
  417. data/lib/badline/drive1581/slot.rb +0 -78
  418. data/lib/badline/drive1581/track.rb +0 -100
  419. data/lib/badline/drive1581/track_bytes.rb +0 -75
  420. data/lib/badline/drive1581/wd1772/registers.rb +0 -89
  421. data/lib/badline/drive1581/wd1772/sector_writes.rb +0 -73
  422. data/lib/badline/drive1581/wd1772/sectors.rb +0 -150
  423. data/lib/badline/drive1581/wd1772/state.rb +0 -66
  424. data/lib/badline/drive1581/wd1772/stepping.rb +0 -109
  425. data/lib/badline/drive1581/wd1772/tracks.rb +0 -125
  426. data/lib/badline/drive1581/wd1772/turn.rb +0 -73
  427. data/lib/badline/drive1581/wd1772.rb +0 -216
  428. data/lib/badline/drive1581.rb +0 -233
  429. data/lib/badline/iec_bus.rb +0 -159
  430. data/lib/badline/instruction.rb +0 -334
  431. data/lib/badline/instruction_set/arithmetic.rb +0 -114
  432. data/lib/badline/instruction_set/bitwise.rb +0 -126
  433. data/lib/badline/instruction_set/branch.rb +0 -79
  434. data/lib/badline/instruction_set/flag.rb +0 -63
  435. data/lib/badline/instruction_set/illegal.rb +0 -270
  436. data/lib/badline/instruction_set/inc_dec.rb +0 -69
  437. data/lib/badline/instruction_set/stack.rb +0 -52
  438. data/lib/badline/instruction_set/transfer.rb +0 -137
  439. data/lib/badline/instruction_set.rb +0 -55
  440. data/lib/badline/interrupts.rb +0 -104
  441. data/lib/badline/joystick.rb +0 -25
  442. data/lib/badline/kernal_trap/channel.rb +0 -181
  443. data/lib/badline/keyboard.rb +0 -112
  444. data/lib/badline/ram_expansion/banking.rb +0 -30
  445. data/lib/badline/ram_expansion/plus256k.rb +0 -54
  446. data/lib/badline/ram_expansion/plus60k.rb +0 -43
  447. data/lib/badline/ram_expansion/unexpanded.rb +0 -28
  448. data/lib/badline/ram_expansion.rb +0 -21
  449. data/lib/badline/reu/dma/saved_state.rb +0 -50
  450. data/lib/badline/reu/dma.rb +0 -273
  451. data/lib/badline/reu/ram.rb +0 -107
  452. data/lib/badline/reu/saved_state.rb +0 -80
  453. data/lib/badline/reu/trigger.rb +0 -32
  454. data/lib/badline/reu.rb +0 -289
  455. data/lib/badline/sid/catch_up.rb +0 -120
  456. data/lib/badline/sid/decimator.rb +0 -64
  457. data/lib/badline/sid/envelope/state.rb +0 -68
  458. data/lib/badline/sid/envelope.rb +0 -239
  459. data/lib/badline/sid/filter.rb +0 -263
  460. data/lib/badline/sid/voice.rb +0 -77
  461. data/lib/badline/sid/waveform/combined.rb +0 -126
  462. data/lib/badline/sid/waveform/fast_forward.rb +0 -105
  463. data/lib/badline/sid/waveform/noise_writeback.rb +0 -122
  464. data/lib/badline/sid/waveform/state.rb +0 -66
  465. data/lib/badline/sid/waveform.rb +0 -305
  466. data/lib/badline/sid.rb +0 -303
  467. data/lib/badline/time_of_day.rb +0 -228
  468. data/lib/badline/traps.rb +0 -19
  469. data/lib/badline/via/control_lines.rb +0 -122
  470. data/lib/badline/via/fast_forward.rb +0 -53
  471. data/lib/badline/via/interrupt_register.rb +0 -67
  472. data/lib/badline/via/shift_register.rb +0 -180
  473. data/lib/badline/via/state.rb +0 -42
  474. data/lib/badline/via/timer1.rb +0 -131
  475. data/lib/badline/via/timer2.rb +0 -133
  476. data/lib/badline/via.rb +0 -266
  477. data/lib/badline/vic/bank.rb +0 -133
  478. data/lib/badline/vic/border_mask.rb +0 -86
  479. data/lib/badline/vic/collisions.rb +0 -115
  480. data/lib/badline/vic/color_patches.rb +0 -47
  481. data/lib/badline/vic/display_state.rb +0 -185
  482. data/lib/badline/vic/graphics_mode.rb +0 -164
  483. data/lib/badline/vic/graphics_shifter.rb +0 -207
  484. data/lib/badline/vic/register_log.rb +0 -81
  485. data/lib/badline/vic/registers.rb +0 -195
  486. data/lib/badline/vic/sequencer.rb +0 -275
  487. data/lib/badline/vic/sequencer_output.rb +0 -116
  488. data/lib/badline/vic/sequencer_state.rb +0 -89
  489. data/lib/badline/vic/sprite/internal_bus.rb +0 -68
  490. data/lib/badline/vic/sprite/saved_state.rb +0 -64
  491. data/lib/badline/vic/sprite/shifter.rb +0 -146
  492. data/lib/badline/vic/sprite/timing.rb +0 -56
  493. data/lib/badline/vic/sprite.rb +0 -337
  494. data/lib/badline/vic/sprites.rb +0 -282
  495. data/lib/badline/vic/sprites_state.rb +0 -57
  496. data/lib/badline/vic.rb +0 -852
  497. data/lib/badline/vic20/sound/output.rb +0 -83
  498. data/lib/badline/vic20/sound.rb +0 -233
  499. data/lib/badline/z80/arithmetic.rb +0 -117
  500. data/lib/badline/z80/bit_page.rb +0 -55
  501. data/lib/badline/z80/block_io.rb +0 -58
  502. data/lib/badline/z80/block_transfers.rb +0 -59
  503. data/lib/badline/z80/bus_cycles.rb +0 -111
  504. data/lib/badline/z80/core.rb +0 -113
  505. data/lib/badline/z80/exchanges.rb +0 -50
  506. data/lib/badline/z80/extended_page.rb +0 -89
  507. data/lib/badline/z80/flags.rb +0 -37
  508. data/lib/badline/z80/interrupt_acceptance.rb +0 -46
  509. data/lib/badline/z80/jumps.rb +0 -82
  510. data/lib/badline/z80/loads.rb +0 -98
  511. data/lib/badline/z80/main_page.rb +0 -134
  512. data/lib/badline/z80/registers.rb +0 -120
  513. data/lib/badline/z80/saved_state.rb +0 -69
  514. data/lib/badline/z80/shifts.rb +0 -64
  515. data/lib/badline/z80.rb +0 -11
  516. /data/lib/badline/snapshot/{fields.rb → vice/fields.rb} +0 -0
@@ -1,303 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "badline/cartridge/bank"
4
- require "badline/cartridge/flash"
5
- require "badline/cartridge/standard"
6
- require "badline/cartridge/simons_basic"
7
- require "badline/cartridge/ocean"
8
- require "badline/cartridge/fun_play"
9
- require "badline/cartridge/super_games"
10
- require "badline/cartridge/epyx_fastload"
11
- require "badline/cartridge/westermann"
12
- require "badline/cartridge/rex_utility"
13
- require "badline/cartridge/game_system"
14
- require "badline/cartridge/dinamic"
15
- require "badline/cartridge/zaxxon"
16
- require "badline/cartridge/magic_desk"
17
- require "badline/cartridge/comal80"
18
- require "badline/cartridge/easy_flash"
19
- require "badline/cartridge/mach5"
20
- require "badline/cartridge/pagefox"
21
- require "badline/cartridge/rgcd"
22
- require "badline/cartridge/g_mod2"
23
- require "badline/cartridge/freezer"
24
- require "badline/cartridge/action_replay"
25
- require "badline/cartridge/atomic_power"
26
- require "badline/cartridge/final_cartridge3"
27
- require "badline/cartridge/retro_replay"
28
- require "badline/cartridge/kcs_power"
29
- require "badline/cartridge/geo_ram"
30
-
31
- module Badline
32
- class Cartridge
33
- class UnsupportedTypeError < StandardError; end
34
-
35
- ROMH_START = 0xa000
36
- BANK_SIZE = 0x2000
37
-
38
- HARDWARE_TYPES = {
39
- 0 => Standard, 1 => ActionReplay, 2 => KCSPower, 3 => FinalCartridge3,
40
- 4 => SimonsBasic, 5 => Ocean, 7 => FunPlay, 8 => SuperGames,
41
- 9 => AtomicPower, 10 => EpyxFastload, 11 => Westermann,
42
- 12 => RexUtility, 15 => GameSystem, 17 => Dinamic, 18 => Zaxxon,
43
- 19 => MagicDesk, 21 => Comal80, 32 => EasyFlash, 36 => RetroReplay,
44
- 51 => Mach5, 53 => Pagefox, 57 => RGCD, 60 => GMod2
45
- }.freeze
46
-
47
- # The EXROM and GAME line levels of each memory configuration. The lines
48
- # are active low.
49
- MODES = {
50
- rom8k: [0, 1].freeze, rom16k: [0, 0].freeze,
51
- ultimax: [1, 0].freeze, off: [1, 1].freeze
52
- }.freeze
53
-
54
- attr_reader :name, :exrom, :game, :roml, :romh
55
-
56
- # A callable returning the current cycle, for mappers with timed state.
57
- attr_writer :clock
58
-
59
- class << self
60
- # Options set the cartridge's jumpers, for the mappers that have them.
61
- def from_file(path, **)
62
- from_crt(Storage::CRTFile.new(path), **)
63
- end
64
-
65
- def from_crt(crt, **)
66
- mapper_for(crt).new(crt, **)
67
- end
68
-
69
- # A cartridge built afresh from what save_setup wrote, before
70
- # load_state puts its state in.
71
- def from_setup(input)
72
- return GeoRAM.new(size: input.int) if input.int == GEO_RAM_SETUP
73
-
74
- crt = Storage::CRTFile.new(bytes: input.string)
75
- mapper_for(crt).from_jumpers(crt, input)
76
- end
77
-
78
- # A cartridge from its image and what save_jumpers wrote: whether
79
- # there are jumpers, then their settings on a mapper that has them.
80
- def from_jumpers(crt, input)
81
- input.boolean?
82
- new(crt)
83
- end
84
-
85
- def mapper_for(crt)
86
- HARDWARE_TYPES.fetch(crt.hardware_type) do
87
- raise UnsupportedTypeError,
88
- "Unsupported cartridge hardware type #{crt.hardware_type}"
89
- end
90
- end
91
- end
92
-
93
- # What save_setup writes first: a cartridge from a CRT image, or a
94
- # GEO-RAM.
95
- CRT_SETUP = 0
96
- GEO_RAM_SETUP = 1
97
-
98
- # Keeps the image it was built from, so a snapshot's machine can build
99
- # the same cartridge before the snapshot's state goes into it.
100
- def initialize(crt)
101
- @crt = crt
102
- @name = crt.name
103
- @exrom = crt.exrom
104
- @game = crt.game
105
- @roml = @romh = nil
106
- @banks = nil
107
- @on_change = nil
108
- @on_nmi_change = nil
109
- @nmi = false
110
- @open_bus = nil
111
- @clock = nil
112
- install_chips(crt.chips)
113
- end
114
-
115
- def on_change(&block)
116
- @on_change = block
117
- end
118
-
119
- # What builds the same cartridge afresh (Cartridge.from_setup): the CRT
120
- # image it was built from, and the jumpers of a mapper that has them.
121
- def save_setup(out)
122
- out.int(CRT_SETUP).string(Storage::CRTFile.encode(@crt))
123
- save_jumpers(out)
124
- end
125
-
126
- # The lines, the pull on NMI, the button and the mapper's own state.
127
- # Loading sets them without calling back into the machine, which maps
128
- # the cartridge again afterwards.
129
- def save_state(out)
130
- out.marker("CARTRIDGE")
131
- out.int(@exrom).int(@game).boolean(@nmi).boolean(@button == true)
132
- save_mapper(out)
133
- end
134
-
135
- def load_state(input)
136
- input.marker("CARTRIDGE")
137
- @exrom = input.int
138
- @game = input.int
139
- @nmi = input.boolean?
140
- @button = input.boolean?
141
- load_mapper(input)
142
- end
143
-
144
- # Called with the level of the cartridge's pull on the NMI line when it
145
- # changes. The line is wired-OR with CIA 2's.
146
- def on_nmi_change(&block)
147
- @on_nmi_change = block
148
- end
149
-
150
- def nmi?
151
- @nmi
152
- end
153
-
154
- # The address bus hands over the C64's RAM, for mappers that write
155
- # through to it, and the open bus, for I/O reads the cartridge doesn't
156
- # drive.
157
- def connect(ram:, open_bus:)
158
- @ram = ram
159
- @open_bus = open_bus
160
- end
161
-
162
- def ultimax?
163
- @game.zero? && @exrom == 1
164
- end
165
-
166
- # Whether the first half of the cycle, where the VIC does most of its
167
- # fetching, sees Ultimax mode. Some cartridges drive GAME and EXROM
168
- # differently in the two halves; #ultimax? is the second, the CPU's.
169
- def phi1_ultimax?
170
- ultimax?
171
- end
172
-
173
- # The I/O pages ($de, $df) whose reads the mapper drives. Reads of the
174
- # others are open bus.
175
- def readable_io_pages
176
- []
177
- end
178
-
179
- def poke(_addr, _value); end
180
-
181
- # A window taking writes to $E000-$FFFF while reads there see the C64's
182
- # memory, for a cartridge that asserts Ultimax on write cycles only.
183
- def romh_writes; end
184
-
185
- # A window at $A000-$BFFF in Ultimax mode, where the C64 maps nothing.
186
- def ultimax_a000; end
187
-
188
- # The RES line on the expansion port.
189
- def reset; end
190
-
191
- # Whether the cartridge has a freeze button.
192
- def freezer? = false
193
-
194
- # The freeze button, which cartridges without one ignore.
195
- def press_button; end
196
-
197
- def release_button; end
198
-
199
- private
200
-
201
- def save_jumpers(out)
202
- out.boolean(false)
203
- end
204
-
205
- # The mapper's own state: where its windows point, for a mapper that
206
- # moves them, and whatever a mapper adds after calling super.
207
- def save_mapper(out)
208
- save_windows(out, windows) if windows
209
- end
210
-
211
- def load_mapper(input)
212
- load_windows(input, windows) if windows
213
- end
214
-
215
- # The banks and views ROML and ROMH can point at, which a snapshot
216
- # names them by: the mapper's banks, or nothing for a mapper whose
217
- # windows stay where install_chips put them.
218
- def windows
219
- [*@banks, EMPTY_BANK] if @banks
220
- end
221
-
222
- # Where the ROML and ROMH windows point, as their places in `windows`,
223
- # the banks and views the mapper picks them from, or -1 for none.
224
- def save_windows(out, windows)
225
- out.int(window_index(@roml, windows)).int(window_index(@romh, windows))
226
- end
227
-
228
- def load_windows(input, windows)
229
- @roml = window_at(input.int, windows)
230
- @romh = window_at(input.int, windows)
231
- end
232
-
233
- def window_index(window, windows)
234
- return -1 if window.nil?
235
-
236
- windows.index { |candidate| candidate.equal?(window) } ||
237
- raise(ArgumentError, "#{self.class.name}: a window that isn't among its banks")
238
- end
239
-
240
- def window_at(index, windows) = index.negative? ? nil : windows.fetch(index)
241
-
242
- def nmi=(level)
243
- return if @nmi == level
244
-
245
- @nmi = level
246
- @on_nmi_change&.call(level)
247
- end
248
-
249
- def changed!
250
- @on_change&.call
251
- end
252
-
253
- def mode=(mode)
254
- @exrom, @game = MODES.fetch(mode)
255
- end
256
-
257
- # Sets the lines and tells the machine to map the cartridge again.
258
- def select_mode(mode)
259
- self.mode = mode
260
- changed!
261
- end
262
-
263
- def open_bus(addr)
264
- @open_bus ? @open_bus.peek(addr) : 0xff
265
- end
266
-
267
- def install_chips(_chips)
268
- raise NotImplementedError
269
- end
270
-
271
- def rom_bank(data)
272
- Bank.new(data)
273
- end
274
-
275
- # A bank the image leaves out reads as erased ROM.
276
- def bank(banks, number)
277
- banks[number] || EMPTY_BANK
278
- end
279
-
280
- # The bank register bits a ROM decodes. The ROM holds the highest bank
281
- # in the image, and has address lines for the power of two that covers
282
- # it; the register bits above those lines are ignored.
283
- def bank_mask(banks)
284
- (1 << (banks.length - 1).bit_length) - 1
285
- end
286
-
287
- # Sorts the CHIP packets into ROML and ROMH banks by load address. A 16K
288
- # chip at $8000 spans both.
289
- def banks_from(chips)
290
- roml = []
291
- romh = []
292
- chips.each do |chip|
293
- if chip.address >= ROMH_START
294
- romh[chip.bank] = rom_bank(chip.data)
295
- else
296
- roml[chip.bank] = rom_bank(chip.data[0, BANK_SIZE])
297
- romh[chip.bank] = rom_bank(chip.data[BANK_SIZE, BANK_SIZE]) if chip.data.length > BANK_SIZE
298
- end
299
- end
300
- [roml, romh]
301
- end
302
- end
303
- end
@@ -1,98 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- # A digest of the machine's state at one cycle, for comparing two runs of
5
- # the same scenario, on two builds or two revisions. Each component is
6
- # hashed on its own with 32-bit FNV-1a, so a mismatch names the part of the
7
- # machine that went its own way. Nothing is read through a chip's bus
8
- # interface, so taking a checkpoint leaves the machine as it was.
9
- #
10
- # Colour RAM is digested as the four bits each cell stores: the upper
11
- # nibble a CPU read sees comes off the open bus.
12
- class Checkpoint
13
- COMPONENTS = %w[cpu ram color_ram display vic cia1 cia2 sid].freeze
14
-
15
- FNV_OFFSET = 0x811c9dc5
16
- FNV_PRIME = 0x01000193
17
-
18
- attr_reader :cycle, :digests
19
-
20
- class << self
21
- def take(computer)
22
- new(computer.cycles, [
23
- fnv1a(cpu_state(computer.cpu)),
24
- fnv1a(ram(computer.ram)),
25
- fnv1a(color_ram(computer.address_bus.color_ram)),
26
- fnv1a(computer.vic.display),
27
- fnv1a(vic_state(computer.vic)),
28
- fnv1a(cia_state(computer.cia1)),
29
- fnv1a(cia_state(computer.cia2)),
30
- fnv1a(Array.new(0x20) { |reg| computer.sid.register(reg) })
31
- ])
32
- end
33
-
34
- # Reads a line written by #to_s.
35
- def parse(line)
36
- fields = line.split
37
- digests = COMPONENTS.map do |name|
38
- field = fields.find { |f| f.start_with?("#{name}=") }
39
- raise ArgumentError, "no #{name} digest in #{line.inspect}" unless field
40
-
41
- field.split("=").last.to_i(16)
42
- end
43
- new(fields.first.to_i, digests)
44
- end
45
-
46
- def fnv1a(values)
47
- hash = FNV_OFFSET
48
- values.each { |value| hash = ((hash ^ (value & 0xffffffff)) * FNV_PRIME) & 0xffffffff }
49
- hash
50
- end
51
-
52
- private
53
-
54
- def cpu_state(cpu)
55
- [cpu.program_counter, cpu.a, cpu.x, cpu.y, cpu.stack_pointer, cpu.p, cpu.cycles]
56
- end
57
-
58
- def ram(memory)
59
- Array.new(0x10000) { |addr| memory.peek(addr) }
60
- end
61
-
62
- def color_ram(memory)
63
- Array.new(0x400) { |offset| memory.nibble(0xd800 + offset) }
64
- end
65
-
66
- def vic_state(vic)
67
- vic.register_file + [vic.rasterline, vic.column]
68
- end
69
-
70
- def cia_state(cia)
71
- start = cia.start
72
- [cia.peek(start), cia.peek(start + 1), cia.peek(start + 2), cia.peek(start + 3),
73
- cia.timer_a, cia.timer_a_latch, cia.timer_b, cia.timer_b_latch, cia.serial.data,
74
- cia.control_a.value, cia.control_b.value, cia.interrupt_status.value,
75
- cia.interrupt_control.value] + cia.time_of_day.registers
76
- end
77
- end
78
-
79
- def initialize(cycle, digests)
80
- @cycle = cycle
81
- @digests = digests
82
- end
83
-
84
- # The components whose digests differ from `other`'s.
85
- def differences(other)
86
- COMPONENTS.each_index.reject { |i| digests[i] == other.digests[i] }.map { |i| COMPONENTS[i] }
87
- end
88
-
89
- def ==(other)
90
- other.is_a?(Checkpoint) && cycle == other.cycle && digests == other.digests
91
- end
92
-
93
- def to_s
94
- fields = COMPONENTS.each_index.map { |i| "#{COMPONENTS[i]}=#{digests[i].to_s(16).rjust(8, '0')}" }
95
- "#{cycle} #{fields.join(' ')}"
96
- end
97
- end
98
- end
@@ -1,60 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class CIA
5
- # Running a CIA a stretch of cycles at once, for Drive::Idle.
6
- module FastForward
7
- # quiet_cycles for a CIA whose counters will never set a flag.
8
- QUIET = 1 << 40
9
-
10
- # Whether fast_forward can run the CIA: timer B stopped with nothing
11
- # in its pipeline, no interrupt or acknowledge on its way, CNT where it
12
- # was, the TOD clock stopped, and timer A either stopped, or free
13
- # running (Timer#free_running?) with its interrupt masked and the
14
- # serial port an idle input. Drive::Idle sleeps the 1571's CIA through
15
- # such cycles, which its DOS leaves timer A running in.
16
- def quiet?
17
- return false unless @tb.idle? && @icr.quiet && @tod.quiet? && cnt_steady?
18
-
19
- @ta.idle? ? @serial.idle : timer_a_free_running?
20
- end
21
-
22
- # How many cycles the CIA can run with nothing but its counters
23
- # moving: as quiet? allows, but with timer B free running too, up to
24
- # the cycle before it underflows. The 1581's DOS leaves timer B
25
- # interrupting every 10 ms.
26
- def quiet_cycles
27
- return 0 unless @icr.quiet && @tod.quiet? && cnt_steady? && timer_a_quiet?
28
- return QUIET if @tb.idle?
29
- return 0 unless @tb.free_running? && @control_b.value.nobits?(0x60)
30
-
31
- @tb.counter - 1
32
- end
33
-
34
- # Runs +cycles+ cycles at once while quiet? or for quiet_cycles, as
35
- # cycle! would: timer A's underflows flag in the ICR, and reach the
36
- # serial port's underflow line.
37
- def fast_forward(cycles)
38
- @tod.fast_forward(cycles)
39
- @tb.fast_forward(cycles) unless @tb.idle?
40
- return if @ta.idle?
41
-
42
- @icr.flag(:timer_a) if @ta.fast_forward(cycles).positive?
43
- @serial.follow_underflow(@ta.underflowed)
44
- end
45
-
46
- private
47
-
48
- def timer_a_quiet? = @ta.idle? ? @serial.idle : timer_a_free_running?
49
-
50
- # Timer A free running with its interrupt masked, and the serial port
51
- # an idle input it only clocks.
52
- def timer_a_free_running?
53
- @ta.free_running? && !@control_a.serial_mode? && @icr.mask.value.nobits?(0x01) && @serial.drained?
54
- end
55
-
56
- # Whether CNT holds the level the last cycle sampled.
57
- def cnt_steady? = @serial.cnt == @cnt_high && !@cnt_rise
58
- end
59
- end
60
- end
@@ -1,143 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class CIA
5
- # The interrupt control register: the source flags, their mask and the
6
- # IR bit that drives the interrupt line, with the 6526's acknowledge
7
- # timing.
8
- class InterruptRegister
9
- attr_reader :status, :mask, :quiet
10
-
11
- # The 6526A is the faster of the two: see the rules below.
12
- def initialize(model = :mos6526)
13
- @fast = model == :mos6526a
14
- @mask = InterruptFlags.new([:timer_a, :timer_b, :alarm, :serial, :flag, 0, 0, 0])
15
- @status = InterruptFlags.new([:timer_a, :timer_b, :alarm, :serial, :flag, 0, 0, :interrupt])
16
- @pending = 0
17
- @read = @read_last_cycle = @read_two_cycles_ago = nil
18
- @timer_b_bug = false
19
- @quiet = true
20
- end
21
-
22
- # The CIA skips this while quiet: no read is recent enough to matter
23
- # and no assert is due.
24
- def cycle!
25
- @read_two_cycles_ago = @read_last_cycle
26
- @read_last_cycle = @read
27
- @read = nil
28
- if @pending.positive?
29
- @pending -= 1
30
- status.interrupt = true if @pending.zero?
31
- end
32
- @quiet = @pending.zero? && @read_last_cycle.nil? && @read_two_cycles_ago.nil?
33
- end
34
-
35
- def interrupted? = status.value >= 0x80
36
-
37
- def save_state(out)
38
- out.int(@mask.value).int(@status.value).int(@pending)
39
- [@read, @read_last_cycle, @read_two_cycles_ago].each { |read| out.optional_int(read) }
40
- out.boolean(@timer_b_bug).boolean(@quiet)
41
- end
42
-
43
- def load_state(input)
44
- @mask.value = input.int
45
- @status.value = input.int
46
- @pending = input.int
47
- @read = input.optional_int
48
- @read_last_cycle = input.optional_int
49
- @read_two_cycles_ago = input.optional_int
50
- @timer_b_bug = input.boolean?
51
- @quiet = input.boolean?
52
- end
53
-
54
- # Raises IR on this cycle.
55
- def assert_now
56
- status.interrupt = true
57
- @pending = 0
58
- end
59
-
60
- # Schedules IR to rise after delay cycles, keeping an earlier one.
61
- def assert!(delay = 1)
62
- @pending = @pending.positive? ? [@pending, delay].min : delay
63
- @quiet = false
64
- end
65
-
66
- # Latch a source, pulling the interrupt line if it is armed. The 6526
67
- # raises IR a cycle after the flag. The 6526A raises it on the flag's
68
- # own cycle, unless the ICR was read on the cycle before.
69
- def flag(source)
70
- bit = source_bit(source)
71
- @status.value |= bit
72
- return unless mask.value.anybits?(bit)
73
-
74
- @fast && @read_last_cycle.nil? ? assert_now : assert!
75
- end
76
-
77
- # The 6526 timer B bug: an underflow on the cycle after a read still
78
- # raises the flag, but the next read drops it unseen. The 6526A has
79
- # no such bug.
80
- def timer_b_underflow!
81
- @timer_b_bug = !@fast && !@read_last_cycle.nil?
82
- flag(:timer_b)
83
- end
84
-
85
- # A read releases the interrupt line at once, and cancels an assert
86
- # due on the next cycle, but its acknowledge lands a cycle late. On
87
- # the 6526 that holds only IR: the next cycle still reads IR set if it
88
- # was set, or about to be. The 6526A reads an IR about to rise as set
89
- # at once, and holds every bit it read: the next cycle reads them all
90
- # again, along with anything flagged since.
91
- def read
92
- status.timer_b = false if @timer_b_bug
93
- @timer_b_bug = false
94
- value = status.value
95
- value |= 0x80 if @fast && @pending == 1
96
- @read = @pending == 1 ? value | 0x80 : value
97
- @quiet = false
98
- value |= held(@read_last_cycle) if @read_last_cycle
99
- status.value = 0x0
100
- @pending = 0
101
- value
102
- end
103
-
104
- # Bit 7 picks between setting and clearing the mask bits given.
105
- def write(value)
106
- if value.nobits?(0x80)
107
- @mask.value &= ~(value & 0x1f)
108
- else
109
- @mask.value |= (value & 0x1f)
110
- end
111
- if mask.value.anybits?(status.value & 0x1f)
112
- assert!(arm_delay) unless interrupted?
113
- elsif @pending == 1 && @read_two_cycles_ago
114
- # On the 6526, masking the pending source cancels the assert due
115
- # on the next cycle only while a read two cycles back is
116
- # acknowledging.
117
- @pending = 0
118
- end
119
- end
120
-
121
- private
122
-
123
- # Arming a pending source raises IR two cycles later on the 6526,
124
- # and one cycle later on the 6526A.
125
- def arm_delay = @fast ? 1 : 2
126
-
127
- # What a read on the cycle before still holds: IR on the 6526, and
128
- # every bit it read on the 6526A.
129
- def held(last) = @fast ? last : last & 0x80
130
-
131
- def source_bit(source)
132
- case source
133
- when :timer_a then 0x01
134
- when :timer_b then 0x02
135
- when :alarm then 0x04
136
- when :serial then 0x08
137
- when :flag then 0x10
138
- else raise ArgumentError, "unknown interrupt source #{source}"
139
- end
140
- end
141
- end
142
- end
143
- end