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,125 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Drive1581
5
- class WD1772
6
- # The type III commands that take a whole turn, from one index pulse
7
- # to the next:
8
- #
9
- # 11100hE00 read track every byte under the head (Track#raw)
10
- # 11110hEP0 write track every byte the CPU sends, for a format
11
- #
12
- # Write track asks for its first byte at once and starts at the index
13
- # pulse, giving up with LOST_DATA if the byte hasn't come three bytes
14
- # later. $F5 writes a sync mark, an $A1, and the first of a run starts
15
- # the CRC over; $F6 writes $C2; $F7 writes the CRC's two bytes. At
16
- # the next index pulse the track under the head becomes the fields
17
- # found in what went down (Track.parse).
18
- module Tracks
19
- LATE = 3
20
-
21
- private
22
-
23
- def start_type3
24
- @type1 = false
25
- @status = 0
26
- @drq = false
27
- @mode = @command.anybits?(0x10) ? WRITE : READ
28
- resume_track unless spinning_up?(TRACK_INDEX)
29
- end
30
-
31
- def resume_track
32
- if @mode == WRITE
33
- if @mechanism.write_protected?
34
- @status |= PROTECTED
35
- return finish
36
- end
37
- @drq = true
38
- end
39
- @phase = @mode == WRITE ? WRITE_TRACK_START : TRACK_INDEX
40
- return wait_index(@phase) if @command.nobits?(SETTLE_DELAY)
41
-
42
- @due = @now + SETTLE
43
- @settling = true
44
- end
45
-
46
- def wait_index(phase)
47
- @settling = false
48
- @phase = phase
49
- @due = next_index
50
- end
51
-
52
- def track_index
53
- return wait_index(TRACK_INDEX) if @settling
54
-
55
- @bytes = (@mechanism.track || Track.new([])).raw
56
- @index = 0
57
- @phase = READ_TRACK
58
- @due = @now + BYTE
59
- end
60
-
61
- def track_byte_read
62
- @status |= LOST_DATA if @drq
63
- @data = @bytes[@index]
64
- @drq = true
65
- @index += 1
66
- @index == Track::LENGTH ? finish : @due += BYTE
67
- end
68
-
69
- def write_track_start
70
- return wait_index(WRITE_TRACK_START) if @settling
71
-
72
- @bytes = []
73
- @syncs = []
74
- @crc = 0xffff
75
- @phase = WRITE_TRACK
76
- return track_byte_written unless @drq
77
-
78
- @late = true
79
- @due = @now + (LATE * BYTE)
80
- end
81
-
82
- # The next byte from the data register goes under the head, a 0
83
- # where DRQ went unanswered.
84
- def track_byte_written
85
- return lost if @late && @drq
86
- return track_written if @bytes.length >= Track::LENGTH
87
-
88
- @late = false
89
- value = @drq ? 0 : @data
90
- @status |= LOST_DATA if @drq
91
- @drq = true
92
- before = @bytes.length
93
- lay_byte(value)
94
- @due = @now + ((@bytes.length - before) * BYTE)
95
- end
96
-
97
- def lay_byte(value)
98
- case value
99
- when 0xf5
100
- @crc = 0xffff unless @syncs.last
101
- push_byte(Track::SYNC, true)
102
- when 0xf6 then push_byte(0xc2, false)
103
- when 0xf7
104
- crc = @crc
105
- push_byte(crc >> 8, false)
106
- push_byte(crc & 0xff, false)
107
- else push_byte(value, false)
108
- end
109
- end
110
-
111
- def push_byte(value, sync)
112
- @bytes << value
113
- @syncs << sync
114
- @crc = Track.crc([value], @crc)
115
- end
116
-
117
- def track_written
118
- @drq = false
119
- @mechanism.write(Track.parse(@bytes.first(Track::LENGTH), @syncs))
120
- finish
121
- end
122
- end
123
- end
124
- end
125
- end
@@ -1,73 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Drive1581
5
- class WD1772
6
- # The disk turning under the head: the index pulses a phase waits
7
- # for or counts, and the cycle the head comes to a place round the
8
- # track.
9
- module Turn
10
- # The disk began or stopped turning: a phase waiting on the turn
11
- # starts its wait again.
12
- def spin_changed
13
- case @phase
14
- when SPIN_UP, MOTOR_IDLE, INDEX_INTERRUPT then count_index
15
- when SEARCH then begin_search
16
- when TRACK_INDEX, WRITE_TRACK_START then wait_index(@phase)
17
- end
18
- end
19
-
20
- private
21
-
22
- # The motor starts: with h clear and the motor off, the command waits
23
- # out six index pulses first, and the phase comes after them.
24
- def spinning_up?(phase)
25
- spin_up = !@motor_on && @command.nobits?(NO_SPIN_UP)
26
- @motor_on = true
27
- return false unless spin_up
28
-
29
- @after_spin_up = phase
30
- @phase = SPIN_UP
31
- @count = 6
32
- count_index
33
- true
34
- end
35
-
36
- # Waits for @count index pulses, or for the disk to turn.
37
- def count_index
38
- @due = next_index
39
- end
40
-
41
- def index_counted
42
- @count -= 1
43
- return @due += Mechanism::REVOLUTION if @count.positive?
44
-
45
- case @phase
46
- when SPIN_UP then spun_up
47
- when MOTOR_IDLE
48
- @motor_on = false
49
- idle
50
- else
51
- @intrq = true
52
- idle
53
- end
54
- end
55
-
56
- # The cycle the next index pulse starts, or NEVER while no disk turns.
57
- def next_index = at_angle(0)
58
-
59
- # The cycle the head next comes to +angle+, from the index.
60
- def at_angle(angle)
61
- return NEVER unless @mechanism.spinning?
62
-
63
- delta = (angle - @mechanism.angle(@now)) % Mechanism::REVOLUTION
64
- @now + (delta.zero? ? Mechanism::REVOLUTION : delta)
65
- end
66
-
67
- # The cycle the byte at +position+ round the track has passed under
68
- # the head.
69
- def byte_end(position) = at_angle(((position + 1) % Track::LENGTH) * BYTE)
70
- end
71
- end
72
- end
73
- end
@@ -1,216 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "badline/drive1581/wd1772/registers"
4
- require "badline/drive1581/wd1772/turn"
5
- require "badline/drive1581/wd1772/stepping"
6
- require "badline/drive1581/wd1772/sectors"
7
- require "badline/drive1581/wd1772/sector_writes"
8
- require "badline/drive1581/wd1772/tracks"
9
- require "badline/drive1581/wd1772/state"
10
-
11
- module Badline
12
- class Drive1581
13
- # The WD1772 floppy disk controller at $6000, as the WD177x data sheet
14
- # describes it, working on the Mechanism's Track at sector level: it
15
- # finds ID and data fields where they lie round the turn and moves
16
- # their bytes at the MFM double-density rate, a byte every 32 µs, but
17
- # keeps no flux or bitstream.
18
- #
19
- # $6000 status (read), command (write)
20
- # $6001 track
21
- # $6002 sector
22
- # $6003 data
23
- #
24
- # It runs on the drive's clock, 2 MHz here, so the data sheet's times,
25
- # given for 8 MHz on the chip's clock pin, come out as BYTE cycles a
26
- # byte, STEP_RATES between steps and SETTLE for the head to settle.
27
- #
28
- # A command runs as a chain of phases, each due at a cycle (@due): a
29
- # step, an index pulse, the end of a byte under the head. Between them
30
- # nothing happens, so cycle! only counts. BUSY sets as the command is
31
- # written, and the chip takes it up START cycles later, 16 µs, so a
32
- # command with nothing to do, such as a seek to the track the head is
33
- # on, still shows BUSY to the DOS, which polls for it before waiting
34
- # for it to clear.
35
- #
36
- # The 1581 leaves INTRQ and DRQ unconnected and polls the status
37
- # register instead (schematic sheet 2), but both are here (intrq?,
38
- # drq?). Its DOS sets h in every command, so the motor spin-up wait
39
- # never runs; the spindle follows the 8520's /MOTOR line instead.
40
- class WD1772
41
- include Registers
42
- include Turn
43
- include Stepping
44
- include Sectors
45
- include SectorWrites
46
- include Tracks
47
- include State
48
-
49
- BYTE = 64
50
- START = 32
51
- STEP_RATES = [12_000, 24_000, 4_000, 6_000].freeze
52
- SETTLE = 30_000
53
-
54
- NEVER = 1 << 60
55
-
56
- # Status bits. Bits 1 and 2 report the index pulse and track 0 after
57
- # a type I command, and DRQ and lost data after the others; bit 5
58
- # reports spin-up after a type I command and a deleted data mark
59
- # after a read.
60
- BUSY = 0x01
61
- INDEX = 0x02
62
- DATA_REQUEST = 0x02
63
- TRACK0 = 0x04
64
- LOST_DATA = 0x04
65
- CRC_ERROR = 0x08
66
- NOT_FOUND = 0x10
67
- SPUN_UP = 0x20
68
- DELETED = 0x20
69
- PROTECTED = 0x40
70
- MOTOR_ON = 0x80
71
-
72
- # Command flags.
73
- NO_SPIN_UP = 0x08
74
- VERIFY = 0x04
75
- SETTLE_DELAY = 0x04
76
- MULTIPLE = 0x10
77
- UPDATE = 0x10
78
- DELETED_MARK = 0x01
79
-
80
- # Phases.
81
- IDLE = 0
82
- SPIN_UP = 1
83
- STEPPED = 2
84
- SETTLED = 3
85
- SEARCH = 4
86
- READ_DATA = 5
87
- WRITE_GATE = 6
88
- WRITE_DATA = 7
89
- READ_TRACK = 8
90
- TRACK_INDEX = 9
91
- WRITE_TRACK = 10
92
- MOTOR_IDLE = 11
93
- INDEX_INTERRUPT = 12
94
- SETTLE_SEARCH = 13
95
- READ_ADDRESS = 14
96
- WRITE_TRACK_START = 15
97
- STARTING = 16
98
-
99
- # What a search for an ID field is for.
100
- READ = 0
101
- WRITE = 1
102
- ADDRESS = 2
103
- VERIFY_TRACK = 3
104
-
105
- attr_reader :now, :track, :sector, :data, :command
106
-
107
- def initialize(mechanism)
108
- @mechanism = mechanism
109
- @now = 0
110
- @due = NEVER
111
- @phase = IDLE
112
- reset!
113
- end
114
-
115
- # The MR line: the registers as the data sheet leaves them, $03 in
116
- # the command register and 1 in the sector register, and no command
117
- # running.
118
- def reset!
119
- @command = 0x03
120
- @track = 0
121
- @sector = 1
122
- @data = 0
123
- @status = 0
124
- @type1 = true
125
- @drq = false
126
- @intrq = false
127
- @motor_on = false
128
- @inward = true
129
- clear_command
130
- idle
131
- end
132
-
133
- def cycle!
134
- @now += 1
135
- advance if @now == @due
136
- end
137
-
138
- # How many cycles can go by before the next phase is due.
139
- def quiet_cycles = @due - @now - 1
140
-
141
- # Runs +cycles+ cycles at once, as many as quiet_cycles allows.
142
- def fast_forward(cycles)
143
- @now += cycles
144
- end
145
-
146
- def busy? = @phase != IDLE && @phase != MOTOR_IDLE && @phase != INDEX_INTERRUPT
147
-
148
- def drq? = @drq
149
-
150
- def intrq? = @intrq
151
-
152
- def motor_on? = @motor_on
153
-
154
- private
155
-
156
- # A command ends: INTRQ, and the motor turns off after nine more
157
- # index pulses unless a command comes first.
158
- def finish
159
- @intrq = true
160
- @phase = MOTOR_IDLE
161
- @count = 9
162
- count_index
163
- end
164
-
165
- # What a command keeps between its phases.
166
- def clear_command
167
- @steps = 0
168
- @count = 0
169
- @after_spin_up = IDLE
170
- @mode = 0
171
- @deadline = NEVER
172
- @id_at = NEVER
173
- @found = -1
174
- @bytes = []
175
- @syncs = []
176
- @index = 0
177
- @crc = 0xffff
178
- @crc_good = true
179
- @write_id = 0
180
- @size = 0
181
- @gate_open = false
182
- @late = false
183
- @settling = false
184
- end
185
-
186
- def idle
187
- @phase = IDLE
188
- @due = NEVER
189
- end
190
-
191
- def advance
192
- case @phase
193
- when STARTING then start_command
194
- when SPIN_UP, MOTOR_IDLE, INDEX_INTERRUPT then index_counted
195
- when STEPPED then step_done
196
- when SETTLED then verify_track
197
- when SETTLE_SEARCH then begin_search
198
- when SEARCH then id_passed
199
- when READ_DATA, READ_ADDRESS then byte_read
200
- else advance_write
201
- end
202
- end
203
-
204
- def advance_write
205
- case @phase
206
- when WRITE_GATE then write_gate
207
- when WRITE_DATA then byte_written
208
- when READ_TRACK then track_byte_read
209
- when TRACK_INDEX then track_index
210
- when WRITE_TRACK_START then write_track_start
211
- when WRITE_TRACK then track_byte_written
212
- end
213
- end
214
- end
215
- end
216
- end
@@ -1,233 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "badline/drive"
4
- require "badline/drive1581/track"
5
- require "badline/drive1581/track_bytes"
6
- require "badline/drive1581/disk"
7
- require "badline/drive1581/mechanism"
8
- require "badline/drive1581/wd1772"
9
- require "badline/drive1581/cpu"
10
- require "badline/drive1581/serial_port"
11
- require "badline/drive1581/bus"
12
-
13
- module Badline
14
- # The 1581 3.5" disk drive: a 6502 at 2 MHz with 8 KB of RAM, an 8520
15
- # for the serial bus and the mechanism's lines, a WD1772 for the MFM
16
- # disk, and the DOS in 32 KB of ROM (1581 Service Manual). Drive::Core
17
- # clocks it against the host.
18
- #
19
- # The 8520's port B faces the serial bus as VIA 1's does on the 1541,
20
- # with the same bits, and ATN reaches its FLAG pin, so ATN going low
21
- # interrupts the DOS. Its SP and CNT carry fast serial on DATA and SRQ,
22
- # through buffers PB5 turns round (Drive::FastSerial), as the 1571's
23
- # 6526 does. The ATN acknowledge differs: a NAND of ATN IN and
24
- # ATN ACK pulls DATA, so DATA follows ATN only while ATN is asserted
25
- # and PB4 is high, where the 1541's XOR pulls it whenever the two
26
- # differ (IECBus::DRIVE_ATN_GATED). Port A drives the motor, the side
27
- # and the two LEDs, and reads the switches and the mechanism's /RDY and
28
- # /DISK CHNG (SerialPort). Timer B interrupts every 10 ms for the
29
- # controller code that runs the WD1772.
30
- #
31
- # The 8520 differs from the 6526 in its TOD, a 24-bit binary event
32
- # counter where the 6526 keeps a BCD clock. The 1581 holds the TOD pin
33
- # high when it carries a WD1772 (jumper J1 out), so the counter never
34
- # counts, and the DOS's one use of it, writing $00 to the low byte and
35
- # reading it back 20 µs later to tell a WD1770 from a WD1772, reads $00
36
- # on either chip: the drive's CIA gets no TOD pulses (CIA's tod_hz).
37
- class Drive1581
38
- include Drive::Core
39
- include Drive::FastSerial
40
-
41
- CLOCK_HZ = 2_000_000
42
-
43
- # Where the DOS's idle loop starts over (see Drive::Idle).
44
- IDLE_LOOP = 0xb105
45
-
46
- # The host cycles, at about 1 MHz, by which a 1581 switched on with the
47
- # machine has run its DOS's reset, the RAM test, the ROM checksum and
48
- # the controller's half-second wait, and waits on the bus: 2.32 s,
49
- # with a margin.
50
- BOOT_CYCLES = 2_700_000
51
-
52
- # The 8520's port A outputs.
53
- SIDE = 0x01
54
- MOTOR = 0x04
55
- POWER_LED = 0x20
56
- ACTIVITY_LED = 0x40
57
-
58
- # Port B's ATN acknowledge, and the fast serial direction.
59
- ATN_ACK = 0x10
60
- FAST_SERIAL_OUT = 0x20
61
-
62
- def cia
63
- settle!
64
- @cia
65
- end
66
-
67
- def fdc
68
- settle!
69
- @fdc
70
- end
71
-
72
- def model_name = "1581"
73
-
74
- # +rom+ covers $8000-$FFFF, and defaults to the DOS image in the ROM
75
- # path. +device+ is the number the switches on port A's PA3 and PA4
76
- # set, 8 to 11.
77
- def initialize(rom: nil, host_clock_hz: Drive1541::CLOCK_HZ, device: 8, debug: false)
78
- @device = device
79
- @clock_hz = CLOCK_HZ
80
- @mechanism = Mechanism.new
81
- @fdc = WD1772.new(@mechanism)
82
- @serial_port = SerialPort.new(@mechanism, device:)
83
- @cia = CIA.new(start: 0x4000, peripheral: @serial_port, tod_hz: 0)
84
- @bus = Bus.new(rom: rom || ROM.load("dos1581.rom", 0x8000), cia: @cia, fdc: @fdc, drive: self)
85
- @cpu = CPU.new(@bus, debug:)
86
- @idle_loop = IDLE_LOOP
87
- @host_clock_hz = host_clock_hz
88
- @phase = 0
89
- @cycles = 0
90
- @serial_bus = nil
91
- @atn = false
92
- @activity = false
93
- @power = false
94
- init_fast_serial
95
- init_idle(debug)
96
- ports_written
97
- connect(IECBus.new)
98
- end
99
-
100
- # The serial bus's RESET line reaches the CPU, the 8520 and the
101
- # WD1772. RAM keeps its contents.
102
- def reset!
103
- settle!
104
- @cia.reset!
105
- @fdc.reset!
106
- ports_written
107
- @cpu.reset!
108
- end
109
-
110
- def insert(disk)
111
- settle!
112
- @mechanism.insert(disk, @fdc.now)
113
- @fdc.spin_changed
114
- end
115
-
116
- # Puts in a Disk from the .d81 image at +path+, write-protected with
117
- # `read_only`.
118
- def insert_image(path, read_only: false)
119
- insert(Disk.open(path, read_only:))
120
- end
121
-
122
- # Whether the activity LED is lit. The power LED stays lit, and
123
- # flashes on an error.
124
- def led_on? = @activity
125
-
126
- def power_led_on? = @power
127
-
128
- # The 8520's port B as it drives the serial bus, in VIA 1's bits, the
129
- # ATN acknowledge turned round for the NAND that gates it, with the
130
- # fast serial pins above it. It holds still while the drive sleeps, so
131
- # reading it leaves the drive asleep.
132
- def serial_output
133
- lines = @cia.port_b_lines
134
- output = (lines & (IECBus::DRIVE_DATA_OUT | IECBus::DRIVE_CLK_OUT)) | IECBus::DRIVE_ATN_GATED | @fast_output
135
- lines.anybits?(ATN_ACK) ? output : output | IECBus::DRIVE_ATNA
136
- end
137
-
138
- # The 8520's ports drive the motor, the side, the LEDs and the fast
139
- # serial buffers: the drive follows them after every write to a port
140
- # or direction register.
141
- def ports_written
142
- fast_serial_out = @cia.port_b_lines.anybits?(FAST_SERIAL_OUT)
143
- turn_fast_serial(fast_serial_out) if fast_serial_out != @fast_serial_out
144
- lines = @cia.port_a_lines
145
- @mechanism.side = lines.anybits?(SIDE) ? 1 : 0
146
- @activity = lines.anybits?(ACTIVITY_LED)
147
- @power = lines.anybits?(POWER_LED)
148
- motor = lines.nobits?(MOTOR)
149
- return if motor == @mechanism.motor_on?
150
-
151
- @mechanism.motor(motor, @fdc.now)
152
- @fdc.spin_changed
153
- end
154
-
155
- # The drive's whole state, as the 1541's (Drive1541#save_state), with
156
- # the 8520 and the WD1772 in place of the VIAs.
157
- def save_state(out)
158
- settle!
159
- out.marker("DRIVE1581")
160
- out.int(@phase).int(@cycles).boolean(@atn)
161
- @serial_port.save_state(out)
162
- @cia.save_state(out)
163
- @fdc.save_state(out)
164
- @bus.save_state(out)
165
- @cpu.save_state(out)
166
- @mechanism.save_state(out)
167
- end
168
-
169
- def load_state(input)
170
- settle!
171
- input.marker("DRIVE1581")
172
- @phase = input.int
173
- @cycles = input.int
174
- @atn = input.boolean?
175
- @serial_port.load_state(input)
176
- @cia.load_state(input)
177
- @fdc.load_state(input)
178
- @bus.load_state(input)
179
- @cpu.load_state(input)
180
- @mechanism.load_state(input)
181
- @fast_serial_out = @cia.port_b_lines.anybits?(FAST_SERIAL_OUT)
182
- ports_written
183
- push_fast_output(@fast_serial_out ? fast_pins : 0)
184
- forget_orbits
185
- end
186
-
187
- private
188
-
189
- # One drive cycle: ATN going low pulls FLAG, the WD1772 and the 8520
190
- # clock ahead of the CPU, and the 8520 alone pulls IRQ.
191
- def step
192
- atn = @serial_port.atn_low?
193
- if atn != @atn
194
- @atn = atn
195
- @cia.flag! if atn
196
- end
197
- @fdc.cycle!
198
- @cia.cycle!
199
- drive_fast_serial if @fast_serial_out
200
- @cpu.irq = @cia.interrupted?
201
- @cpu.cycle!
202
- @cycles += 1
203
- end
204
-
205
- def hear_atn
206
- @atn = @serial_port.atn_low?
207
- end
208
-
209
- # A pass of the idle loop reads and writes RAM alone, so it repeats
210
- # while the 8520 pulls no IRQ, for as long as the 8520's counters and
211
- # the WD1772's next phase leave room: until timer B's next interrupt
212
- # for the controller code. Neither chip changes but by the clock, so
213
- # only the CPU is compared.
214
- def busy_for_pass? = @cia.interrupted?
215
-
216
- def quiet_cycles = [@cia.quiet_cycles, @fdc.quiet_cycles].min
217
-
218
- def idle_state = [*@cpu.idle_state, @bus.data, @atn]
219
-
220
- def fast_forward_chips(cycles)
221
- @cia.fast_forward(cycles)
222
- @fdc.fast_forward(cycles)
223
- end
224
-
225
- # Every timer B interrupt reads the 8520, so no orbit (Drive::Orbit)
226
- # comes round, and the drive keeps no anchors.
227
- def anchor = nil
228
-
229
- def counter_state(_touched) = []
230
-
231
- def skip_chip_orbits(_cycles, _touched) = nil
232
- end
233
- end