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,137 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Drive1581
5
- # The drive CPU's bus, as the 74LS139 decodes A13-A15 (1581 Service
6
- # Manual, memory map and schematic sheet 1):
7
- #
8
- # $0000-$1FFF - 8 KB of RAM
9
- # $2000-$3FFF - nothing: open bus
10
- # $4000-$5FFF - the 8520, its sixteen registers mirrored
11
- # $6000-$7FFF - the WD1772, its four registers mirrored
12
- # $8000-$FFFF - the DOS ROM
13
- #
14
- # Writes to the ROM and to open bus go nowhere, and a read from open
15
- # bus finds the last byte on the data bus, as on the 1541. A write to
16
- # either of the 8520's ports or their direction registers moves the
17
- # drive's lines (Drive1581#ports_written).
18
- #
19
- # While Idle records a pass of the DOS's idle loop, the bus watches it
20
- # (watch!): the RAM it reads and writes, and whether it touched the
21
- # 8520 or the WD1772, either of which makes the pass volatile. While
22
- # Idle looks for an orbit, the bus guards the drive (guard!), and any
23
- # access to either chip taints it.
24
- class Bus
25
- include Addressable
26
-
27
- attr_reader :ram, :rom, :cia, :fdc, :data, :volatile, :touched, :tainted, :touched_timers
28
-
29
- def initialize(rom:, cia:, fdc:, drive:)
30
- addressable_at(0, length: 2**16)
31
- @ram = Memory.new([], length: 0x2000, start: 0)
32
- @rom = rom
33
- @cia = cia
34
- @fdc = fdc
35
- @drive = drive
36
- @data = 0
37
- @recording = @guarding = @watching = false
38
- @volatile = @tainted = false
39
- @touched = {}
40
- @touched_timers = 0
41
- end
42
-
43
- # The last byte on the data bus and the RAM. What a watched stretch
44
- # touched is Idle's, and a restored bus isn't watching.
45
- def save_state(out)
46
- out.int(@data)
47
- @ram.save_state(out)
48
- end
49
-
50
- def load_state(input)
51
- @data = input.int
52
- @ram.load_state(input)
53
- @watching = false
54
- end
55
-
56
- def peek(addr)
57
- return @data = @rom.peek(addr) if addr >= 0x8000
58
- return @data = chip_peek(addr) if addr >= 0x2000
59
-
60
- touch(addr) if @recording
61
- @data = @ram.peek(addr)
62
- end
63
-
64
- def poke(addr, value)
65
- @data = value
66
- return if addr >= 0x8000
67
- return chip_poke(addr, value) if addr >= 0x2000
68
-
69
- touch(addr) if @recording
70
- @ram.poke(addr, value)
71
- end
72
-
73
- # Starts watching: see volatile and touched.
74
- def watch!
75
- @recording = true
76
- @volatile = false
77
- @touched = {}
78
- watching!
79
- end
80
-
81
- def unwatch!
82
- @recording = false
83
- watching!
84
- end
85
-
86
- # Starts guarding: see tainted.
87
- def guard!
88
- @guarding = true
89
- @tainted = false
90
- watching!
91
- end
92
-
93
- private
94
-
95
- def chip_peek(addr)
96
- watch_chip if @watching
97
- if addr >= 0x6000
98
- @fdc.peek(addr & 0x03)
99
- elsif addr >= 0x4000
100
- @cia.peek(0x4000 | (addr & 0x0f))
101
- else
102
- @data
103
- end
104
- end
105
-
106
- def chip_poke(addr, value)
107
- watch_chip if @watching
108
- if addr >= 0x6000
109
- @fdc.poke(addr & 0x03, value)
110
- elsif addr >= 0x4000
111
- @cia.poke(0x4000 | (addr & 0x0f), value)
112
- @drive.ports_written if addr.nobits?(0x0c)
113
- end
114
- end
115
-
116
- def touch(addr)
117
- @touched[addr] = @ram.peek(addr) unless @touched.key?(addr)
118
- end
119
-
120
- def watching!
121
- @watching = @recording || @guarding
122
- end
123
-
124
- def watch_chip
125
- if @recording
126
- @volatile = true
127
- @recording = false
128
- end
129
- if @guarding
130
- @tainted = true
131
- @guarding = false
132
- end
133
- watching!
134
- end
135
- end
136
- end
137
- end
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Drive1581
5
- # The drive's 6502, on the drive's Bus.
6
- class CPU
7
- include Badline::CPU::Core
8
- include Drive::IdleCPU
9
- end
10
- end
11
- end
@@ -1,135 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "badline/drive1581/disk_state"
4
-
5
- module Badline
6
- class Drive1581
7
- # A 3.5" double-sided disk as the WD1772 sees it: a Track on each side
8
- # of 80 cylinders, or none where it was never formatted.
9
- #
10
- # A .d81 image holds the 1581 DOS's logical blocks in order, 40 of 256
11
- # bytes on each logical track 1 to 80 (1581 Service Manual, format
12
- # organization). Logical track t is cylinder t - 1, and the DOS puts
13
- # its sectors 0 to 19 on side 0 and 20 to 39 on side 1, two to each
14
- # 512-byte physical sector, numbered from 1. So physical sector s on
15
- # side h of cylinder c holds logical sectors 20h + 2(s - 1) and the one
16
- # after it, and every cylinder of the image is a standard Track
17
- # (Track.standard) on both sides. A block the image's error table
18
- # marks 20 or 21 loses its sector's ID field, 27 spoils the ID's CRC,
19
- # 22 loses the data field and 23 spoils its CRC.
20
- #
21
- # The WD1772 writes into the tracks, and flush stores the standard
22
- # sectors of each one written back in the image, which writes its host
23
- # file. A track formatted another way stays on the disk alone. The disk
24
- # is write-protected when the image won't take writes.
25
- class Disk
26
- include State
27
-
28
- CYLINDERS = 80
29
- SIDES = 2
30
-
31
- # Logical blocks a side of a cylinder holds.
32
- SIDE_BLOCKS = 20
33
-
34
- # A logical block's bytes, and how many a physical sector holds.
35
- BLOCK_SIZE = 256
36
- BLOCKS = Track::SECTOR_SIZE / BLOCK_SIZE
37
-
38
- # A disk from the .d81 image at +path+. `read_only` opens the image
39
- # write-protected.
40
- def self.open(path, read_only: false)
41
- new(Storage::D81Image.new(path, read_only:)).opened(path, read_only)
42
- end
43
-
44
- attr_reader :image
45
-
46
- def initialize(image = nil)
47
- @image = image
48
- @tracks = Array.new(CYLINDERS * SIDES)
49
- @written = {}
50
- @changed = {}
51
- @path = nil
52
- @read_only = false
53
- end
54
-
55
- # The Track on +side+ of +cylinder+, or nil where there is none: past
56
- # the image's cylinders, or on a disk without an image that the head
57
- # never formatted.
58
- def track(cylinder, side)
59
- index = (cylinder * SIDES) + side
60
- return @tracks[index] if @tracks[index] || !@image || cylinder >= CYLINDERS
61
-
62
- @tracks[index] = image_track(cylinder, side)
63
- end
64
-
65
- # A write track laid +track+ down on +side+ of +cylinder+, or a write
66
- # sector changed it.
67
- def write(cylinder, side, track)
68
- return if cylinder >= CYLINDERS
69
-
70
- index = (cylinder * SIDES) + side
71
- @tracks[index] = track
72
- @written[index] = true
73
- @changed[index] = true
74
- end
75
-
76
- # Whether the write-protect hole is open: the disk's image won't take
77
- # writes, or a disk without an image was opened read-only.
78
- def write_protected? = @image.nil? ? @read_only : !@image.writable?
79
-
80
- # Whether any track was written since the last flush.
81
- def written? = !@written.empty?
82
-
83
- # Stores the standard sectors of each track written since the last
84
- # flush in the image, all in one write to its host file.
85
- def flush
86
- written = @written.keys.sort
87
- @written.clear
88
- return if @image.nil? || written.empty?
89
-
90
- @image.store_blocks(written.flat_map { |index| track_blocks(index / SIDES, index % SIDES) })
91
- end
92
-
93
- private
94
-
95
- def image_track(cylinder, side)
96
- track = Track.standard(cylinder, side) { |sector| physical_block(cylinder, side, sector) }
97
- track.sectors.each { |sector| mark_errors(cylinder, side, sector) }
98
- track.sectors.reject! { |sector| sector.id.nil? }
99
- track
100
- end
101
-
102
- # The logical track and first sector physical sector +sector+ holds.
103
- def logical(cylinder, side, sector) = [cylinder + 1, (side * SIDE_BLOCKS) + ((sector - 1) * BLOCKS)]
104
-
105
- def physical_block(cylinder, side, sector)
106
- track, first = logical(cylinder, side, sector)
107
- Array.new(BLOCKS) { |i| @image.read_block(track, first + i) || [] }.flatten
108
- end
109
-
110
- def mark_errors(cylinder, side, sector)
111
- track, first = logical(cylinder, side, sector.id.bytes[2])
112
- errors = Array.new(BLOCKS) { |i| @image.block_error(track, first + i) }
113
- sector.id.good = false if errors.include?(27)
114
- sector.data.good = false if errors.include?(23)
115
- sector.data = nil if errors.include?(22)
116
- sector.id = nil if errors.include?(20) || errors.include?(21)
117
- end
118
-
119
- # [track, sector, data, nil] for DiskImage#store_blocks, for each
120
- # logical block a standard sector of the track holds.
121
- def track_blocks(cylinder, side)
122
- track = @tracks[(cylinder * SIDES) + side]
123
- Track::SECTORS.times.flat_map do |index|
124
- data = track.sector([cylinder, side, index + 1, Track::SIZE_CODE])&.data
125
- next [] unless data
126
-
127
- logical_track, first = logical(cylinder, side, index + 1)
128
- Array.new(BLOCKS) do |i|
129
- [logical_track, first + i, data.bytes[i * BLOCK_SIZE, BLOCK_SIZE], nil]
130
- end
131
- end
132
- end
133
- end
134
- end
135
- end
@@ -1,87 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Drive1581
5
- class Disk
6
- # Saving and restoring a Disk for a snapshot: the image by its path,
7
- # and every track the head wrote since the disk went in, with those
8
- # written since the last flush. The rest come from the image, read
9
- # again from its host file where there still is one.
10
- module State
11
- # The image's path, expanded, and whether it was opened read-only,
12
- # for a disk from Disk.open. Nil for a disk made another way.
13
- attr_reader :path, :read_only
14
-
15
- # The disk a state from save_state describes: +current+ when it was
16
- # opened from the same image the same way, and otherwise a disk for
17
- # the image at the path the state names. Where no file is at that
18
- # path, the disk has no image and is write-protected, and a
19
- # detached reader always gets one without an image.
20
- def self.load(input, current)
21
- path = input.optional_string
22
- read_only = input.boolean?
23
- disk = current if current && !path.nil? && current.path == path && current.read_only == read_only
24
- disk ||= fresh(path, read_only, input.detached?)
25
- disk.load_tracks(input)
26
- disk
27
- end
28
-
29
- def self.fresh(path, read_only, detached)
30
- return Disk.new if path.nil? || detached
31
- return Disk.new.opened(path, true) unless File.file?(path)
32
-
33
- Disk.open(path, read_only:)
34
- end
35
-
36
- # Notes the image's path and how it was opened.
37
- def opened(path, read_only)
38
- @path = File.expand_path(path)
39
- @read_only = read_only
40
- self
41
- end
42
-
43
- def save_state(out)
44
- out.optional_string(@path).boolean(@read_only)
45
- changed = @changed.keys.sort
46
- out.ints(changed)
47
- changed.each { |index| save_track(@tracks[index], out) }
48
- out.ints(@written.keys)
49
- end
50
-
51
- def load_tracks(input)
52
- @changed.clear
53
- input.ints.each do |index|
54
- @tracks[index] = load_track(input)
55
- @changed[index] = true
56
- end
57
- @written.clear
58
- input.ints.each { |index| @written[index] = true }
59
- end
60
-
61
- private
62
-
63
- def save_track(track, out)
64
- out.int(track.sectors.length)
65
- track.sectors.each do |sector|
66
- save_field(sector.id, out)
67
- out.boolean(!sector.data.nil?)
68
- save_field(sector.data, out) if sector.data
69
- end
70
- end
71
-
72
- def save_field(field, out)
73
- out.int(field.mark).ints(field.bytes).boolean(field.good).boolean(field.deleted)
74
- end
75
-
76
- def load_track(input)
77
- Track.new(Array.new(input.int) do
78
- id = load_field(input)
79
- Track::Sector.new(id, input.boolean? ? load_field(input) : nil)
80
- end)
81
- end
82
-
83
- def load_field(input) = Track::Field.new(input.int, input.ints, input.boolean?, input.boolean?)
84
- end
85
- end
86
- end
87
- end
@@ -1,117 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Drive1581
5
- # The 1581's 3.5" mechanism: the spindle motor, the head on one of
6
- # its cylinders and sides, the index sensor, and the lines it reports
7
- # on the drive connector (1581 Service Manual, schematic sheet 2).
8
- #
9
- # The motor runs while /MOTOR is low and turns a disk at 300 rpm, a
10
- # turn every REVOLUTION drive cycles at 2 MHz. The index sensor pulses
11
- # for INDEX_PULSE cycles at the start of each turn, which is where a
12
- # Track's bytes start. /RDY is low while the motor turns a disk. The
13
- # WD1772 steps the head, and /TR00 is low while it sits on cylinder 0.
14
- # /WPRT is low while the disk's write-protect hole is open, or without
15
- # a disk.
16
- #
17
- # /DISK CHNG goes low as a disk comes out, and at power-on, and goes
18
- # high again at a step pulse with a disk in, as on any Shugart-style
19
- # drive with a disk change line. The DOS steps in and out after
20
- # spinning the motor up to find out whether a disk is in.
21
- #
22
- # Times are the WD1772's cycle count (WD1772#now), which the drive
23
- # passes in: the angle under the head follows from how long the disk
24
- # has turned.
25
- class Mechanism
26
- REVOLUTION = 400_000
27
- INDEX_PULSE = 4_000
28
- LAST_CYLINDER = 83
29
-
30
- attr_reader :disk, :cylinder
31
- attr_accessor :side
32
-
33
- def initialize
34
- @disk = nil
35
- @cylinder = 0
36
- @side = 0
37
- @motor = false
38
- @changed = true
39
- @angle = 0
40
- @since = 0
41
- end
42
-
43
- # Puts a Disk in, or with nil takes it out. Whatever was in is
44
- # flushed first, and the disk change line goes low.
45
- def insert(disk, now)
46
- @angle = angle(now)
47
- @since = now
48
- flush
49
- @disk = disk
50
- @changed = true
51
- end
52
-
53
- def flush = @disk&.flush
54
-
55
- def motor_on? = @motor
56
-
57
- # Turns the motor on or off at +now+.
58
- def motor(on, now)
59
- @angle = angle(now)
60
- @since = now
61
- @motor = on
62
- end
63
-
64
- # Whether a disk turns.
65
- def spinning? = @motor && !@disk.nil?
66
-
67
- # How far into its turn the disk is at +now+, in cycles from the
68
- # index.
69
- def angle(now) = spinning? ? (@angle + now - @since) % REVOLUTION : @angle
70
-
71
- def index?(now) = spinning? && angle(now) < INDEX_PULSE
72
-
73
- def ready? = spinning?
74
-
75
- def track0? = @cylinder.zero?
76
-
77
- def disk_changed? = @changed
78
-
79
- def write_protected? = @disk.nil? || @disk.write_protected?
80
-
81
- # A step pulse, towards the hub with +inward+.
82
- def step(inward)
83
- @cylinder = (@cylinder + (inward ? 1 : -1)).clamp(0, LAST_CYLINDER)
84
- @changed = false if @disk
85
- end
86
-
87
- # The Track under the head, or nil.
88
- def track = @disk&.track(@cylinder, @side)
89
-
90
- # Stores a track the WD1772 laid down under the head.
91
- def write(track)
92
- @disk&.write(@cylinder, @side, track)
93
- end
94
-
95
- # The disk (Disk#save_state) and the motor, the head and the turn.
96
- def save_state(out)
97
- out.boolean(!@disk.nil?)
98
- @disk&.save_state(out)
99
- out.int(@cylinder).int(@side).int(@angle).int(@since).boolean(@motor).boolean(@changed)
100
- end
101
-
102
- # Puts the state back, reusing the disk in when it's the one the state
103
- # names (Disk::State.load). A disk taken out is flushed.
104
- def load_state(input)
105
- disk = input.boolean? ? Disk::State.load(input, @disk) : nil
106
- flush unless disk.equal?(@disk)
107
- @disk = disk
108
- @cylinder = input.int
109
- @side = input.int
110
- @angle = input.int
111
- @since = input.int
112
- @motor = input.boolean?
113
- @changed = input.boolean?
114
- end
115
- end
116
- end
117
- end
@@ -1,52 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Drive1581
5
- # What the 8520's ports read from outside the chip (1581 Service
6
- # Manual, schematic sheet 3; the DOS's I/O definitions):
7
- #
8
- # PA0 side select (out) PB0 DATA IN (in)
9
- # PA1 /RDY from the mechanism PB1 DATA OUT (out)
10
- # PA2 /MOTOR (out) PB2 CLK IN (in)
11
- # PA3 device number switch 1 PB3 CLK OUT (out)
12
- # PA4 device number switch 2 PB4 ATN ACK (out)
13
- # PA5 power LED (out) PB5 fast serial direction (out)
14
- # PA6 activity LED (out) PB6 /WPRT from the mechanism
15
- # PA7 /DISK CHNG from the mech. PB7 ATN IN (in)
16
- #
17
- # DATA IN, CLK IN and ATN IN come through inverters, so a pulled line
18
- # reads 1, as on the 1541 (Drive::SerialLines). A closed switch pulls
19
- # its line low, and both closed make device 8. The ports' outputs
20
- # read back as driven: the peripheral pulls only the inputs.
21
- class SerialPort
22
- include Drive::SerialLines
23
-
24
- READY = 0x02
25
- SWITCHES = 0x18
26
- DISK_CHANGE = 0x80
27
- PROTECT = 0x40
28
-
29
- def initialize(mechanism, device: 8, bus: IECBus.new)
30
- @mechanism = mechanism
31
- @switches = (0xff & ~SWITCHES) | (((device - 8) & 0x03) << 3)
32
- init_serial_lines(device, bus)
33
- end
34
-
35
- def read_a(_port_a, _port_b)
36
- value = @switches
37
- value &= ~READY if @mechanism.ready?
38
- value &= ~DISK_CHANGE if @mechanism.disk_changed?
39
- value
40
- end
41
-
42
- def read_b(_port_a, _port_b)
43
- low = @bus.low_lines(@host)
44
- value = 0xff & ~(SERIAL_INPUTS | PROTECT)
45
- value |= DATA_IN if low.anybits?(IECBus::DATA)
46
- value |= CLK_IN if low.anybits?(IECBus::CLK)
47
- value |= ATN_IN if low.anybits?(IECBus::ATN)
48
- @mechanism.write_protected? ? value : value | PROTECT
49
- end
50
- end
51
- end
52
- end
@@ -1,78 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Drive1581
5
- # A machine's place for a Drive1581 on its serial bus, in a field of
6
- # its own beside its other true drives, so none of them makes another's
7
- # per-cycle call a union. The C64, the VIC-20 and the C128 include it,
8
- # and run the drive from their cycle as they run a 1541.
9
- #
10
- # A 1581 reads only .d81 images and the others none, so a .d81 put in
11
- # device 8 swaps the true drive there for a 1581, and any other disk
12
- # swaps a 1581 back for the machine's own true drive
13
- # (Media::TrueDrive).
14
- module Slot
15
- attr_reader :drive1581
16
-
17
- # Plugs in a Drive1581, which then runs alongside the machine on its
18
- # own clock and talks to it over the serial bus, as a 1541 does.
19
- def attach_drive1581(drive)
20
- @iec_bus.detach(@drive1581) if @drive1581
21
- drive.host_clock_hz = timing.clock_hz
22
- @drive1581 = drive
23
- drive.connect(@iec_bus)
24
- @serial_trap&.device = serial_trap_device
25
- drive1581_attached
26
- end
27
-
28
- # Unplugs the Drive1581.
29
- def detach_drive1581
30
- return unless @drive1581
31
-
32
- @iec_bus.detach(@drive1581)
33
- @drive1581 = nil
34
- @serial_trap&.device = serial_trap_device
35
- end
36
-
37
- # Plugs in a 1581 as device 8, in place of the true drive there, and
38
- # returns it.
39
- def plug_drive1581
40
- unplug_device8
41
- Drive1581.new.tap { |drive| attach_drive1581(drive) }
42
- end
43
-
44
- private
45
-
46
- # Unplugs the 1541 if it is device 8, for a 1581 to take its place.
47
- def unplug_device8
48
- detach_drive1541 if @drive1541&.device == KernalTrap::Routine::DEVICE
49
- end
50
-
51
- # What the machine does as a 1581 goes on its bus. The VIC-20 waits
52
- # for its DOS to boot before typing.
53
- def drive1581_attached = nil
54
-
55
- # Whether the 1581 is device 8.
56
- def drive1581_on_device8? = @drive1581&.device == KernalTrap::Routine::DEVICE
57
-
58
- # The 1581 on the serial bus, with its device number.
59
- def save_drive1581(out)
60
- out.boolean(!@drive1581.nil?)
61
- return unless @drive1581
62
-
63
- out.int(@drive1581.device)
64
- @drive1581.save_state(out)
65
- end
66
-
67
- # Layouts before 8 have no 1581.
68
- def load_drive1581(input)
69
- return detach_drive1581 if input.schema < 8 || !input.boolean?
70
-
71
- device = input.int
72
- detach_drive1581 if @drive1581 && @drive1581.device != device
73
- attach_drive1581(Drive1581.new(device:)) unless @drive1581
74
- @drive1581.load_state(input)
75
- end
76
- end
77
- end
78
- end