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,112 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- # The I/O port of the 6510 and the 8502 at $00 (direction) and $01
5
- # (data). An input pin reads its pull-up, P4 reads the datasette's sense
6
- # line, and a pin without a pull-up holds the charge last driven onto
7
- # it. P5 drives the datasette motor through an inverter: low runs it.
8
- #
9
- # The 6510 has pull-ups on P0-P2 and P4 and leaves P3, P6 and P7
10
- # floating. The 8502 adds a CAPS LOCK pin on P6, high while the key is
11
- # up.
12
- class CPUPort
13
- TAPE_SENSE = 0b0001_0000
14
-
15
- # The direction and output registers, and the charge on the floating
16
- # pins.
17
- attr_reader :ddr, :data, :floating
18
-
19
- # The port as the banking logic reads it (PortStatus).
20
- attr_reader :status
21
-
22
- # Whether CAPS LOCK is down, holding its pin low.
23
- attr_reader :caps_lock
24
-
25
- # +pullups+ and +floating+ are the masks of the pins with a pull-up and
26
- # of the floating ones, and +caps_lock+ the CAPS LOCK pin's, 0 where
27
- # there is none.
28
- def initialize(datasette, pullups:, floating:, caps_lock: 0)
29
- @datasette = datasette
30
- @pullups = pullups
31
- @floating_mask = floating
32
- @caps_lock_pin = caps_lock
33
- @caps_lock = false
34
- @ddr = 0x00
35
- @data = 0x00
36
- @floating = 0x00
37
- @change_handler = nil
38
- @status = PortStatus.new(%i[basic kernal io tape_out tape_switch tape_motor], value: input_value)
39
- end
40
-
41
- # Calls the block after every write to the port, for the bus to remap
42
- # its banks.
43
- def on_change(&handler)
44
- @change_handler = handler
45
- end
46
-
47
- # What a read of $01 sees.
48
- def value = @status.value
49
-
50
- def write_ddr(value)
51
- @ddr = value
52
- update
53
- end
54
-
55
- def write_data(value)
56
- @data = value
57
- update
58
- end
59
-
60
- # The RES line clears the direction and output registers. The floating
61
- # pins keep their charge.
62
- def reset!
63
- @ddr = 0x00
64
- @data = 0x00
65
- update
66
- end
67
-
68
- # Sets the registers and the charge, as a snapshot restores them, and
69
- # drives the motor and calls the change handler as a write does.
70
- def restore(ddr, data, floating)
71
- load(ddr, data, floating)
72
- update
73
- end
74
-
75
- # Sets the registers and the charge, as a snapshot loads them, without
76
- # driving the motor or calling the change handler.
77
- def load(ddr, data, floating)
78
- @ddr = ddr
79
- @data = data
80
- @floating = floating
81
- refresh
82
- end
83
-
84
- # Holds CAPS LOCK down, or lets it up.
85
- def caps_lock=(down)
86
- @caps_lock = down
87
- refresh
88
- end
89
-
90
- # Reads the inputs again, after the datasette's sense line changes.
91
- def refresh
92
- @status.value = input_value
93
- end
94
-
95
- private
96
-
97
- def update
98
- driven = @ddr & @floating_mask
99
- @floating = (@floating & ~driven) | (@data & driven)
100
- refresh
101
- @datasette.motor = !@status.tape_motor?
102
- @change_handler&.call
103
- end
104
-
105
- def input_value
106
- input = @pullups | (@floating & @floating_mask)
107
- input |= @caps_lock_pin unless @caps_lock
108
- input &= ~TAPE_SENSE if @datasette.sense_low?
109
- (@data & @ddr) | (input & ~@ddr & 0xff)
110
- end
111
- end
112
- end
@@ -1,161 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- # The 1530 datasette. Plays a pulse stream into CIA 1's FLAG pin while the
5
- # motor runs with a key pressed, and reports the keys through the cassette
6
- # sense line on the $01 port. With RECORD down too, it records the
7
- # machine's write line onto the tape instead.
8
- class Datasette
9
- # What inserting a tape raises on a machine without a cassette port.
10
- class Missing < ArgumentError; end
11
-
12
- attr_reader :tape
13
- attr_writer :motor
14
-
15
- def initialize(tape = nil)
16
- @tape = tape
17
- @connected = true
18
- @playing = false
19
- @recording = false
20
- @write_high = true
21
- @since = 0
22
- @motor = false
23
- @countdown = 0
24
- @flag_handler = nil
25
- @sense_handler = nil
26
- end
27
-
28
- # Falling edges on the tape read line.
29
- def on_flag(&handler)
30
- @flag_handler = handler
31
- end
32
-
33
- # The cassette sense line, which the $01 port reads back.
34
- def on_sense_change(&handler)
35
- @sense_handler = handler
36
- end
37
-
38
- # Whether the machine has a datasette at its cassette port. The SX-64
39
- # has none: its keys stay up and it takes no tape.
40
- def connected? = @connected
41
-
42
- def disconnect!
43
- eject
44
- @connected = false
45
- end
46
-
47
- def insert(tape)
48
- raise Missing, "this machine has no datasette" unless @connected
49
-
50
- @tape = tape
51
- rewind
52
- end
53
-
54
- def eject
55
- stop!
56
- @tape = nil
57
- end
58
-
59
- def rewind
60
- @tape&.rewind
61
- @countdown = 0
62
- end
63
-
64
- def play! = press(true)
65
- def stop! = press(false)
66
-
67
- # Presses RECORD and PLAY together.
68
- def record!
69
- return if !@connected || @tape.nil?
70
-
71
- press(true)
72
- @recording = true
73
- @since = 0
74
- end
75
-
76
- def recording? = @recording
77
-
78
- # The machine's tape write line. While the deck records with its motor
79
- # running, each rising edge ends a pulse on the tape, as long as the
80
- # time since the edge before, and plays back as a falling edge on the
81
- # read line.
82
- def write_line=(high)
83
- rose = high && !@write_high
84
- @write_high = high
85
- return unless rose && @recording && running?
86
-
87
- @tape.record_pulse(@since)
88
- @since = 0
89
- end
90
-
91
- def playing? = @playing
92
-
93
- # Sense reads low while a key is down on the deck.
94
- def sense_low? = @playing
95
-
96
- def motor? = @motor
97
-
98
- def running? = @playing && @motor && !@tape.nil?
99
-
100
- # The keys, the motor, the countdown to the next pulse and the tape:
101
- # its path, its bytes and how far it has played.
102
- def save_state(out)
103
- out.marker("DATASETTE")
104
- out.boolean(@playing).boolean(@motor).int(@countdown).boolean(!@tape.nil?)
105
- return unless @tape
106
-
107
- out.string(@tape.path).blob(@tape.bytes).int(@tape.position)
108
- end
109
-
110
- # The tape goes back in from the bytes the state holds, without its
111
- # host file, unless the tape in is the same one. The sense and flag
112
- # handlers don't fire.
113
- def load_state(input)
114
- input.marker("DATASETTE")
115
- @playing = input.boolean?
116
- @motor = input.boolean?
117
- @countdown = input.int
118
- return @tape = nil unless input.boolean?
119
-
120
- path = input.string
121
- bytes = input.blob
122
- position = input.int
123
- @tape = Storage::TAP.new(path, bytes:) unless @tape&.path&.b == path && @tape.bytes == bytes
124
- @tape.position = position
125
- end
126
-
127
- def cycle!
128
- return unless running?
129
- return @since += 1 if @recording
130
-
131
- @countdown = @tape.next_pulse.to_i if @countdown.zero?
132
- return if @countdown.zero?
133
-
134
- @countdown -= 1
135
- @flag_handler&.call if @countdown.zero?
136
- end
137
-
138
- def inspect
139
- "#<#{self.class.name} tape=#{@tape ? @tape.class.name : 'none'} " \
140
- "playing=#{@playing} motor=#{@motor}>"
141
- end
142
-
143
- private
144
-
145
- def press(down)
146
- return if down == @playing || !@connected
147
-
148
- finish_recording unless down
149
- @playing = down
150
- @sense_handler&.call
151
- end
152
-
153
- # Releasing the keys ends a recording, and writes the tape out.
154
- def finish_recording
155
- return unless @recording
156
-
157
- @recording = false
158
- @tape.save
159
- end
160
- end
161
- end
@@ -1,147 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- module Drive
5
- # What every Commodore disk drive here shares: a 6502 running the DOS
6
- # ROM, with chips on its bus facing the serial bus and the disk
7
- # mechanism, on a clock of its own.
8
- #
9
- # The drive runs on its own crystal, so it clocks against the host's
10
- # clock through a fractional accumulator: each host cycle adds the
11
- # drive's clock rate worth of phase, and every whole host period in it
12
- # runs a drive cycle. Against the PAL C64's 985,248 Hz a drive at
13
- # 1 MHz runs one drive cycle per host cycle and a second one about
14
- # every 67. The host sets its clock on attaching the drive, and until
15
- # then a 1 MHz drive runs one cycle per host cycle.
16
- #
17
- # The Mechanism reads a Disk put in with insert.
18
- #
19
- # While the DOS idles, host_cycle! skips the drive's cycles and catches
20
- # up on them later, exactly (see Idle). The readers of the drive's parts
21
- # catch up first, so they find the drive as running every cycle would
22
- # have left it. Once the DOS's timer interrupts come round, the drive
23
- # sleeps through them too (see Orbit).
24
- #
25
- # A model includes Core and builds its parts, sets @clock_hz and
26
- # @idle_loop, and runs one drive cycle in step. It hears ATN on
27
- # connecting (hear_atn), drives the serial bus (serial_output), and
28
- # answers Idle's and Orbit's questions about its chips, as VIAs does
29
- # for the 1541 and the 1571.
30
- module Core
31
- include Sleep
32
- include Idle
33
- include Orbit
34
-
35
- attr_reader :device, :serial_bus
36
-
37
- def cpu
38
- settle!
39
- @cpu
40
- end
41
-
42
- def bus
43
- settle!
44
- @bus
45
- end
46
-
47
- def mechanism
48
- settle!
49
- @mechanism
50
- end
51
-
52
- def cycles
53
- settle!
54
- @cycles
55
- end
56
-
57
- def ram = bus.ram
58
-
59
- def host_clock_hz=(clock_hz)
60
- settle!
61
- @host_clock_hz = clock_hz
62
- end
63
-
64
- # Plugs the drive into a serial bus, leaving the one it was on. A drive
65
- # starts out on a bus of its own, with nothing else on it.
66
- def connect(serial_bus)
67
- settle!
68
- @serial_bus&.detach(self)
69
- @serial_bus = serial_bus
70
- @serial_port.bus = serial_bus
71
- serial_bus.attach(self)
72
- hear_atn
73
- end
74
-
75
- # Puts a Disk in the drive (Disk.from_d64 makes one from an image).
76
- # Nil takes the disk out.
77
- def insert(disk)
78
- settle!
79
- @mechanism.insert(disk)
80
- end
81
-
82
- def disk = mechanism.disk
83
-
84
- # Whether the LED is lit. Reading it leaves the drive asleep: the LED
85
- # is the same at the end of every pass the drive sleeps through.
86
- def led_on? = @mechanism.led_on?
87
-
88
- # Stores what the head wrote since the motor last stopped in the
89
- # disk's image, as the motor stopping does.
90
- def flush
91
- settle!
92
- @mechanism.flush
93
- end
94
-
95
- # Runs the drive cycles that fall in one host cycle: none, one or two.
96
- # The host has run this cycle already, and the drive sees what it did
97
- # from the next one on (see SerialPort). Asleep, the drive owes the
98
- # cycles instead, until ATN moves or its counters are due (see Idle).
99
- # It looks at ATN only after the machine pushed its lines into the bus
100
- # (see host_written!).
101
- def host_cycle!
102
- if @asleep
103
- return if (@slept += 1) != @wake_at && @host_still
104
-
105
- return doze
106
- end
107
-
108
- phase = @phase + @clock_hz
109
- while phase >= @host_clock_hz
110
- @asleep ? @owed += 1 : run_cycle
111
- phase -= @host_clock_hz
112
- end
113
- @phase = phase
114
- settle! if @serial_port.atn_moved?
115
- @serial_port.latch_host
116
- plan_wake if @asleep
117
- end
118
-
119
- # The machine pushed its lines into the bus, so ATN may have moved.
120
- def host_written!
121
- @host_still = false
122
- end
123
-
124
- # The host moved its fast serial pins, which a 1541 has none to hear.
125
- def fast_lines_moved = nil
126
-
127
- # Runs one drive cycle, catching up first on any the drive owes (see
128
- # step).
129
- def cycle!
130
- settle!
131
- step
132
- end
133
-
134
- def inspect
135
- "#<#{self.class.name} cycles=#{cycles} cpu=(#{cpu.inspect})>"
136
- end
137
-
138
- private
139
-
140
- # A drive cycle from host_cycle!, which may find the idle loop.
141
- def run_cycle
142
- step
143
- idle_loop_reached if @cpu.program_counter == @idle_loop && @idle_skip
144
- end
145
- end
146
- end
147
- end
@@ -1,73 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- module Drive
5
- # Fast serial on a drive with a CIA, the 1571's 6526 or the 1581's
6
- # 8520: through buffers a port line turns round, the CIA's CNT drives
7
- # SRQ and its SP drives DATA, or it hears them. The drive pushes its
8
- # pins into the bus as they move, and hears the host's as the host
9
- # pushes them, pin by pin, so each byte goes through both shift
10
- # registers bit by bit. The CIA takes no part in a pass of the idle
11
- # loop, and any access to it, or the host moving its fast serial pins,
12
- # wakes the drive.
13
- #
14
- # A model includes it beside Core, and calls turn_fast_serial when its
15
- # direction line moves and drive_fast_serial each cycle the buffers
16
- # face out. Its serial_output carries @fast_output above its port.
17
- module FastSerial
18
- # Whether the buffers face out, the drive's CIA driving DATA and SRQ.
19
- attr_reader :fast_serial_out
20
-
21
- # The host moved its fast serial pins: the CIA hears SRQ on CNT and
22
- # DATA on SP while the buffers face in.
23
- def fast_lines_moved
24
- settle!
25
- hear_fast_serial unless @fast_serial_out
26
- end
27
-
28
- private
29
-
30
- def init_fast_serial
31
- @fast_serial_out = false
32
- @fast_output = 0
33
- end
34
-
35
- # The buffers turned round: outwards the CIA's pins drive the lines,
36
- # and inwards they let go and hear them.
37
- def turn_fast_serial(out)
38
- @fast_serial_out = out
39
- return unless @serial_bus
40
-
41
- push_fast_output(out ? fast_pins : 0)
42
- hear_fast_serial unless out
43
- end
44
-
45
- def drive_fast_serial
46
- low = fast_pins
47
- push_fast_output(low) if low != @fast_output
48
- end
49
-
50
- # The lines the CIA's CNT and SP pull while its serial port drives
51
- # them.
52
- def fast_pins
53
- serial = @cia.serial
54
- return 0 unless serial.output?
55
-
56
- low = serial.cnt ? 0 : IECBus::DRIVE_FAST_SRQ
57
- serial.sp_out ? low : low | IECBus::DRIVE_FAST_DATA
58
- end
59
-
60
- def push_fast_output(low)
61
- @fast_output = low
62
- @serial_bus&.drives_fast_moved!
63
- end
64
-
65
- def hear_fast_serial
66
- low = @serial_bus.low_lines
67
- serial = @cia.serial
68
- serial.cnt_in = low.nobits?(IECBus::SRQ)
69
- serial.sp_in = low.nobits?(IECBus::DATA)
70
- end
71
- end
72
- end
73
- end
@@ -1,125 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- module Drive
5
- # Skipping the drive's cycles while the DOS idles, exactly.
6
- #
7
- # With nothing to do, the DOS goes round its idle loop from the
8
- # model's @idle_loop ($EBFF in the 1541, 446 cycles a pass), until VIA
9
- # 2's timer 1 interrupts it every 14,850 cycles for the job loop, or
10
- # ATN interrupts it through VIA 1's CA1. A pass writes RAM and VIA 2's
11
- # port B, but puts back what it found, so the drive comes round to the
12
- # loop's start as it left it. Only the timers' counters and the cycle
13
- # counts move.
14
- #
15
- # Each time the CPU comes to the loop's start, the drive records the
16
- # pass that follows. At the next it checks that the pass
17
- #
18
- # - left the CPU, both VIAs but for their counters, the bus's last
19
- # byte, the SO pin, the mechanism (Mechanism#idle_state) and what
20
- # the ports read from it, and every byte of RAM it read or wrote as
21
- # it found them (Bus#watch!)
22
- # - read nothing that changes from pass to pass: no counter, no shift
23
- # register, and not VIA 1's port B, which reads the serial bus
24
- # - wrote nothing that reaches outside the drive: not VIA 1, whose port
25
- # B drives the serial bus, and not the motor on
26
- # - ran while no counter could set a flag (VIA#quiet_cycles), with the
27
- # motor off, no interrupt pulled and no trap on the CPU.
28
- #
29
- # Such a pass runs the same way again from where it ended, for as
30
- # long as ATN holds still and no counter sets a flag, so the drive
31
- # sleeps: host_cycle! only counts the host cycles that go by (see
32
- # Sleep). It wakes
33
- # when ATN moves, when a counter is due to set a flag, or when something
34
- # outside reads or changes the drive (the readers in Core call
35
- # settle!). Waking counts off the whole passes it owes in bulk,
36
- # moving the counters on, and runs the rest cycle by cycle.
37
- #
38
- # The loop reads neither CLK nor DATA, so the drive sleeps through them
39
- # moving and takes the C64's lines as they stand once it wakes. Its
40
- # own lines hold still while it sleeps, so the C64 reads them without
41
- # waking it (serial_output).
42
- #
43
- # A pass starts at the loop's start, where the CPU always comes from
44
- # the loop's last instruction, a JMP, so what that leaves in the CPU's
45
- # working registers is the same each time round.
46
- #
47
- # The timer's interrupts come round too, and once they do, the drive
48
- # sleeps on through them (see Orbit).
49
- module Idle
50
- # Whether the drive may sleep through its idle loop. On by default,
51
- # but for a drive whose CPU logs each instruction.
52
- attr_reader :idle_skip
53
-
54
- def idle_skip=(on)
55
- settle!
56
- @idle_skip = on
57
- end
58
-
59
- private
60
-
61
- def init_idle(debug)
62
- @idle_skip = !debug
63
- @recording = false
64
- @pass_cycles = 0
65
- @pass_instructions = 0
66
- init_sleep
67
- init_orbits
68
- end
69
-
70
- # The CPU is at the loop's start. At an instruction boundary, the
71
- # drive sleeps if the pass it recorded can repeat, and otherwise
72
- # records the next.
73
- def idle_loop_reached
74
- return unless @cpu.boundary?
75
-
76
- if @recording
77
- stop_recording
78
- return fall_asleep if repeatable_pass? && room_for_pass?
79
- end
80
- start_recording
81
- end
82
-
83
- def start_recording
84
- return if busy_for_pass? || @cpu.trapped?
85
-
86
- @recording = true
87
- @record_state = idle_state
88
- @record_cycles = @cycles
89
- @record_instructions = @cpu.instructions
90
- @record_quiet = quiet_cycles
91
- @bus.watch!
92
- end
93
-
94
- def stop_recording
95
- @recording = false
96
- @bus.unwatch!
97
- end
98
-
99
- # Whether the pass just recorded can repeat.
100
- def repeatable_pass?
101
- !@bus.volatile && @cycles - @record_cycles <= @record_quiet && idle_state == @record_state &&
102
- ram_as_found?
103
- end
104
-
105
- # Whether the counters leave room for a whole pass.
106
- def room_for_pass? = quiet_cycles >= @cycles - @record_cycles
107
-
108
- # Sleeps through the pass just recorded, over and over.
109
- def fall_asleep
110
- @pass_cycles = @cycles - @record_cycles
111
- @pass_instructions = @cpu.instructions - @record_instructions
112
- @asleep = true
113
- @host_still = false
114
- @owed = 0
115
- @budget = quiet_cycles
116
- anchor
117
- end
118
-
119
- def ram_as_found?
120
- ram = @bus.ram
121
- @bus.touched.all? { |addr, value| ram.peek(addr) == value }
122
- end
123
- end
124
- end
125
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- module Drive
5
- # What Idle needs of a drive's 6502, which includes it beside
6
- # CPU::Core.
7
- module IdleCPU
8
- # Everything the CPU holds but its cycle and instruction counts: the
9
- # registers, the interrupt lines and pipeline, and what the last
10
- # instruction left in its working registers. Drive::Idle compares
11
- # it at two instruction boundaries.
12
- def idle_state
13
- [@program_counter, @stack_pointer, @a, @x, @y, @status.value,
14
- @irq, @nmi, @irq_sample, @irq_pending, @nmi_sample, @nmi_pending, @skip_poll,
15
- @boundary_irq, @boundary_nmi, @so_high, @interrupt, @brk, @pending_write, @stalled_at, @traps,
16
- @operation, @optional_dummy, @boundary_crossed, @branch_taken,
17
- @address, @pointer, @dummy_address, @value, @rmw_result]
18
- end
19
-
20
- # Counts +cycles+ cycles and +instructions+ instructions that ran
21
- # without changing anything idle_state holds.
22
- def fast_forward(cycles, instructions)
23
- @cycles += cycles
24
- @instructions += instructions
25
- end
26
- end
27
- end
28
- end