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
@@ -1,275 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class CIA
5
- # The serial shift register and the CNT line that clocks it.
6
- #
7
- # With CRA bit 6 clear the port is an input: SP is sampled on every
8
- # rising CNT edge, and the byte reaches the data register after eight of
9
- # them. With the bit set the CIA drives CNT itself, toggling it on every
10
- # timer A underflow, so a byte takes sixteen underflows to go out. CNT falls
11
- # as each bit is put on SP, and rises again to clock it in.
12
- #
13
- # The register counts itself empty as soon as the eighth bit is on SP,
14
- # fifteen underflows in: the serial flag follows a few cycles later
15
- # rather than waiting for the sixteenth underflow, and a byte written
16
- # from that point on goes out on the next one.
17
- class Serial
18
- BITS = 8
19
-
20
- # A byte written to the data register reaches the shift register one
21
- # cycle later. The empty countdown starts on the underflow that puts
22
- # the eighth bit on SP and is decremented on that same cycle, so the
23
- # flag lands four cycles after it.
24
- LOAD_DELAY = 1
25
- EMPTY_DELAY = 5
26
- BUSY_DELAY = 5
27
-
28
- # The logic watching the shift register runs a few cycles behind it,
29
- # so the level saying a bit is still on its way out is scheduled
30
- # through a delay line: a bit set at position 7 - n takes effect n
31
- # cycles later. Putting a bit on SP raises the level after one cycle
32
- # and drops it again after two before raising it for good after
33
- # three; the eighth bit skips straight to the last of those. CNT
34
- # rising over a bit lowers the level four cycles later.
35
- IN_FLIGHT = 0x50
36
- LAST_IN_FLIGHT = 0x10
37
- BOUNCE = 0x20
38
- SETTLED = 0x08
39
-
40
- attr_reader :data, :sp_out, :cnt, :cnt_in, :idle
41
- attr_accessor :sp_in
42
-
43
- def initialize(control)
44
- @control = control
45
- @data = 0x0
46
- @shift = 0x0
47
- @steps = 0
48
- @empty_in = nil
49
- @busy_in = nil
50
- @busy = false
51
- @abandoned = false
52
- @pending = nil
53
- @underflow_high = false
54
- @in_flight = false
55
- @flight_up = 0x0
56
- @flight_down = 0x0
57
- @idle = true
58
- # Nothing drives the user port, so both lines float high.
59
- @cnt = true
60
- @cnt_in = true
61
- @sp_in = true
62
- @sp_out = true
63
- end
64
-
65
- # The bits shifted so far, and the byte waiting to go out after the
66
- # one shifting.
67
- attr_reader :steps, :pending
68
-
69
- def shift_register = @shift
70
-
71
- # Sets the data register and the shift register, as a VICE snapshot
72
- # gives them.
73
- def restore_shift(data, shift)
74
- @data = data
75
- @shift = shift
76
- end
77
-
78
- def output?
79
- @control.serial_mode?
80
- end
81
-
82
- # Whether nothing is counting down or in the delay lines, so only
83
- # timer A's underflows reach the register.
84
- def drained? = idle?
85
-
86
- # Takes timer A's underflow line as cycle! would have left it, with
87
- # +underflowed+ its level on the last cycle, for a CIA run without
88
- # the register in use (CIA#fast_forward).
89
- def follow_underflow(underflowed)
90
- @underflow_high = underflowed
91
- @idle = !underflowed
92
- end
93
-
94
- def cnt_in=(level)
95
- @cnt_in = level
96
- @cnt = level unless output?
97
- end
98
-
99
- def save_state(out)
100
- out.int(@data).int(@shift).int(@steps).optional_int(@empty_in).optional_int(@busy_in)
101
- out.boolean(@busy).boolean(@abandoned).optional_int(@pending).boolean(@underflow_high).boolean(@in_flight)
102
- out.int(@flight_up).int(@flight_down).boolean(@idle)
103
- [@cnt, @cnt_in, @sp_in, @sp_out].each { |level| out.boolean(level) }
104
- end
105
-
106
- def load_state(input)
107
- @data = input.int
108
- @shift = input.int
109
- @steps = input.int
110
- @empty_in = input.optional_int
111
- @busy_in = input.optional_int
112
- @busy = input.boolean?
113
- @abandoned = input.boolean?
114
- @pending = input.optional_int
115
- load_lines(input)
116
- end
117
-
118
- def write(value)
119
- @data = value
120
- @pending = LOAD_DELAY
121
- @idle = false
122
- end
123
-
124
- # Clocked every cycle with timer A's underflow line. Yields once the
125
- # shift register reports itself empty, which it does without waiting
126
- # for the underflow that raises CNT over the eighth bit.
127
- def cycle!(underflowed)
128
- return if @idle && !underflowed
129
-
130
- shift(underflowed)
131
- @pending -= 1 if @pending&.positive?
132
- drain_flight
133
- count_busy
134
- @idle = !underflowed && idle?
135
- return if @empty_in.nil?
136
-
137
- @empty_in -= 1
138
- return unless @empty_in.zero?
139
-
140
- @empty_in = nil
141
- @busy = false
142
- yield
143
- end
144
-
145
- # Clocked by rising CNT edges while receiving. Yields once a whole
146
- # byte has arrived.
147
- def rising_edge!
148
- return if output?
149
-
150
- @shift = ((@shift << 1) | (@sp_in ? 1 : 0)) & 0xff
151
- @steps += 1
152
- return unless @steps == BITS
153
-
154
- @steps = 0
155
- @data = @shift
156
- yield if block_given?
157
- end
158
-
159
- # A mode change drops the byte in flight and hands CNT back to
160
- # whichever side drives it now, and yields: that byte counts as gone.
161
- # Handing the port over as an input tears a transmission down, so a
162
- # busy register reports it; the same change latches how far the bit
163
- # in flight had got, and taking the port back reports that.
164
- def reset!
165
- abandoned = output? ? @abandoned : @busy
166
- @abandoned = output? ? false : @in_flight
167
- @in_flight = false
168
- @steps = 0
169
- @empty_in = nil
170
- @busy_in = nil
171
- @busy = false
172
- @pending = nil
173
- @cnt = output? || @cnt_in
174
- yield if abandoned
175
- end
176
-
177
- private
178
-
179
- def load_lines(input)
180
- @underflow_high = input.boolean?
181
- @in_flight = input.boolean?
182
- @flight_up = input.int
183
- @flight_down = input.int
184
- @idle = input.boolean?
185
- @cnt = input.boolean?
186
- @cnt_in = input.boolean?
187
- @sp_in = input.boolean?
188
- @sp_out = input.boolean?
189
- end
190
-
191
- # Without an underflow, a register with nothing counting down and
192
- # nothing in the delay lines has nothing to do on a cycle.
193
- def idle?
194
- !@pending&.positive? && (@flight_up | @flight_down).zero? &&
195
- @busy_in.nil? && @empty_in.nil?
196
- end
197
-
198
- # The shift register picks up a waiting byte whenever the underflow
199
- # line is asserted, but every half-step after that needs a fresh edge
200
- # on it. A zero latch holds the line down for good rather than
201
- # pulsing it, so such a byte stops after its first bit and never
202
- # reaches the data register.
203
- def shift(underflowed)
204
- edge = underflowed && !@underflow_high
205
- @underflow_high = underflowed
206
- clock(edge) if underflowed && output?
207
- end
208
-
209
- def clock(edge)
210
- start if @steps <= 1
211
- if @steps.zero?
212
- @flight_down |= SETTLED
213
- elsif edge || @steps == BITS * 2
214
- half_step
215
- end
216
- end
217
-
218
- def half_step
219
- @steps -= 1
220
- @cnt = @steps.even?
221
- if @cnt
222
- @flight_down |= SETTLED
223
- else
224
- shift_out
225
- end
226
- end
227
-
228
- # The register reads as busy from a few cycles after the first bit
229
- # reaches SP until it reports itself empty over the eighth.
230
- def mark_busy
231
- case @steps
232
- when (BITS * 2) - 1 then @busy_in = BUSY_DELAY
233
- when 1
234
- @empty_in = EMPTY_DELAY
235
- @busy_in = nil
236
- end
237
- end
238
-
239
- def count_busy
240
- return if @busy_in.nil?
241
-
242
- @busy_in -= 1
243
- return unless @busy_in.zero?
244
-
245
- @busy_in = nil
246
- @busy = true
247
- end
248
-
249
- def drain_flight
250
- @in_flight = false if @flight_down.anybits?(0x80)
251
- @flight_down = (@flight_down << 1) & 0xff
252
- @in_flight = true if @flight_up.anybits?(0x80)
253
- @flight_up = (@flight_up << 1) & 0xff
254
- end
255
-
256
- # A byte only moves out of the data register once the one before it
257
- # has put its last bit on SP.
258
- def start
259
- return unless @pending&.zero?
260
-
261
- @pending = nil
262
- @shift = @data
263
- @steps = BITS * 2
264
- end
265
-
266
- def shift_out
267
- @sp_out = @shift.anybits?(0x80)
268
- @shift = (@shift << 1) & 0xff
269
- mark_busy
270
- @flight_up |= @steps == 1 ? LAST_IN_FLIGHT : IN_FLIGHT
271
- @flight_down |= BOUNCE
272
- end
273
- end
274
- end
275
- end
@@ -1,47 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class CIA
5
- # A snapshot of the chip: everything it holds but its wiring, the ports,
6
- # the PB4 and CNT levels, the timers, the interrupt register, the serial
7
- # port and the TOD clock.
8
- module State
9
- def save_state(out)
10
- out.marker("CIA")
11
- out.int(@data_port_a).int(@data_port_b).int(@data_dir_a).int(@data_dir_b)
12
- out.boolean(@port_b4_high).boolean(@port_b4_driven_high).boolean(@cnt_high).boolean(@cnt_rise)
13
- out.int(@control_a.value).int(@control_b.value)
14
- @ta.save_state(out)
15
- @tb.save_state(out)
16
- @icr.save_state(out)
17
- @serial.save_state(out)
18
- @tod.save_state(out)
19
- end
20
-
21
- def load_state(input)
22
- input.marker("CIA")
23
- @data_port_a = input.int
24
- @data_port_b = input.int
25
- @data_dir_a = input.int
26
- @data_dir_b = input.int
27
- @port_b4_high = input.boolean?
28
- @port_b4_driven_high = input.boolean?
29
- @cnt_high = input.boolean?
30
- @cnt_rise = input.boolean?
31
- @control_a.value = input.int
32
- @control_b.value = input.int
33
- load_parts(input)
34
- end
35
-
36
- private
37
-
38
- def load_parts(input)
39
- @ta.load_state(input)
40
- @tb.load_state(input)
41
- @icr.load_state(input)
42
- @serial.load_state(input)
43
- @tod.load_state(input)
44
- end
45
- end
46
- end
47
- end
@@ -1,206 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class CIA
5
- class Timer
6
- attr_accessor :counter, :latch
7
- attr_reader :control, :underflowed
8
-
9
- def initialize(control)
10
- @control = control
11
- @counter = @latch = 0xffff
12
- @pipe = 0
13
- @load_delay = 0
14
- @reload = false
15
- @underflowed = false
16
- @oneshot_linger = 0
17
- @toggle = true
18
- settle
19
- end
20
-
21
- # The level this timer drives on its port B pin: a square wave that
22
- # flips on each underflow, or a single high tick when one happens.
23
- def output?
24
- control.out_mode? ? @toggle : @underflowed
25
- end
26
-
27
- # Whether the timer is stopped with nothing in its pipeline, so a
28
- # cycle changes nothing.
29
- def idle? = @empty && !started?
30
-
31
- # Whether the timer counts ø2 in continuous mode with nothing pending
32
- # but the reload after an underflow, so fast_forward can run it. A
33
- # latch below 2 is left out.
34
- def free_running?
35
- started? && !@control.run_mode? && @control.value.nobits?(0x20) && @latch >= 2 && @pipe == 0b11 &&
36
- (@load_delay | @oneshot_linger).zero? && (@settled || @reload)
37
- end
38
-
39
- # Runs a free-running timer +cycles+ cycles at once, as cycle! would:
40
- # an underflow every latch + 1 cycles, each one followed by the
41
- # reload. Returns the underflows.
42
- def fast_forward(cycles)
43
- return 0 if cycles.zero?
44
- return after_underflow(cycles, 0) unless @settled
45
-
46
- if cycles < @counter
47
- @counter -= cycles
48
- return 0
49
- end
50
- after_underflow(cycles - @counter, 1)
51
- end
52
-
53
- def cycle!(feed)
54
- feed &&= @control.value & 0x01 != 0
55
- if @settled
56
- return @counter -= 1 if feed && @counter > 1
57
- elsif @empty
58
- enter if feed
59
- return
60
- end
61
- run_tick(feed)
62
- end
63
-
64
- def run_tick(feed)
65
- @underflowed = false
66
- @oneshot_linger -= 1 if @oneshot_linger.positive?
67
- tick(feed)
68
- settle
69
- end
70
-
71
- # The counter, the latch and the pipeline between them. The control
72
- # register is the CIA's to save.
73
- def save_state(out)
74
- out.int(@counter).int(@latch).int(@pipe).int(@load_delay).boolean(@reload).boolean(@underflowed)
75
- out.int(@oneshot_linger).boolean(@toggle).boolean(@settled).boolean(@empty)
76
- end
77
-
78
- def load_state(input)
79
- @counter = input.int
80
- @latch = input.int
81
- @pipe = input.int
82
- @load_delay = input.int
83
- @reload = input.boolean?
84
- @underflowed = input.boolean?
85
- @oneshot_linger = input.int
86
- @toggle = input.boolean?
87
- @settled = input.boolean?
88
- @empty = input.boolean?
89
- end
90
-
91
- def write_control(value)
92
- @toggle = true if value.anybits?(0x01) && !started?
93
- @oneshot_linger = 2 if control.run_mode? && value.nobits?(0x08)
94
- control.value = value & ~0x10
95
- @load_delay = 3 if value.anybits?(0x10)
96
- settle
97
- end
98
-
99
- def write_latch_low(value)
100
- @latch = (@latch & 0xff00) | value
101
- end
102
-
103
- def write_latch_high(value)
104
- @latch = (value << 8) | (@latch & 0xff)
105
- @counter = @latch unless started?
106
- end
107
-
108
- # Whether the timer's PB output toggle is high, and its count pipeline
109
- # as two bits, the newer stage high.
110
- attr_reader :toggle, :pipe
111
-
112
- # Sets the control register without its load strobe, the toggle and
113
- # the count pipeline, as a VICE snapshot gives them.
114
- def restore_pipeline(control, toggle, pipe)
115
- @control.value = control & ~0x10
116
- @toggle = toggle
117
- @pipe = pipe
118
- settle
119
- end
120
-
121
- private
122
-
123
- def started?
124
- @control.value & 0x01 != 0
125
- end
126
-
127
- # Where fast_forward lands +cycles+ after an underflow, with
128
- # +underflows+ underflows counted so far.
129
- def after_underflow(cycles, underflows)
130
- periods, rest = cycles.divmod(@latch + 1)
131
- underflows += periods
132
- @toggle = !@toggle if underflows.odd?
133
- @underflowed = rest.zero?
134
- @reload = rest.zero?
135
- @counter = @latch - (rest.zero? ? 0 : rest - 1)
136
- settle
137
- underflows
138
- end
139
-
140
- def enter
141
- @pipe = 0b10
142
- @empty = false
143
- end
144
-
145
- # With no load, reload or one-shot linger pending, a full pipe only
146
- # counts and an empty one only waits to be fed.
147
- def settle
148
- quiet = (@load_delay | @oneshot_linger).zero? && !@reload
149
- @settled = quiet && @pipe == 0b11
150
- @empty = quiet && @pipe.zero?
151
- end
152
-
153
- def tick(feed)
154
- counting = @pipe.anybits?(0b01)
155
- @pipe = (@pipe >> 1) | (feed ? 0b10 : 0)
156
- loading = @reload || @load_delay == 1
157
- @reload = false
158
-
159
- if loading
160
- reload
161
- elsif premature_underflow?
162
- underflow
163
- elsif counting
164
- count
165
- end
166
-
167
- forced_load
168
- end
169
-
170
- def forced_load
171
- return unless @load_delay.positive?
172
-
173
- @load_delay -= 1
174
- @counter = @latch if @load_delay == 1
175
- end
176
-
177
- # the final pipeline stage, before any pending load lands
178
- def premature_underflow?
179
- @counter.zero? && @pipe.anybits?(0b01) && started?
180
- end
181
-
182
- # A load consumes its tick, so the counter never decrements on it
183
- def reload
184
- @counter = @latch
185
- # A zero latch underflows again on the reload tick while running
186
- underflow if @counter.zero? && started? && @pipe.anybits?(0b01)
187
- end
188
-
189
- def count
190
- @counter -= 1 if @counter.positive?
191
- underflow if @counter.zero? && @pipe.anybits?(0b01)
192
- end
193
-
194
- def underflow
195
- @underflowed = true
196
- @reload = true
197
- @counter = @latch
198
- @toggle = !@toggle
199
- return unless control.run_mode? || @oneshot_linger.positive?
200
-
201
- control.start = false
202
- @pipe = 0
203
- end
204
- end
205
- end
206
- end