badline 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (516) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/CLAUDE.md +59 -31
  4. data/README.md +1 -1
  5. data/doc/library.md +9 -9
  6. data/doc/pinned-behaviour.md +105 -105
  7. data/doc/snapshots.md +1 -4
  8. data/lib/badline/audio/bare_player.rb +4 -4
  9. data/lib/badline/audio/cli.rb +6 -6
  10. data/lib/badline/audio/jukebox.rb +2 -2
  11. data/lib/badline/audio/machine_player.rb +2 -2
  12. data/lib/badline/{media → audio}/queue.rb +1 -1
  13. data/lib/badline/audio/queued_tune.rb +6 -6
  14. data/lib/badline/audio/renderer.rb +5 -5
  15. data/lib/badline/audio/stereo.rb +1 -1
  16. data/lib/badline/c128/{bus_state.rb → bus/saved_state.rb} +6 -6
  17. data/lib/badline/c128/bus.rb +30 -51
  18. data/lib/badline/c128/color_lines.rb +2 -2
  19. data/lib/badline/c128/cpu.rb +1 -1
  20. data/lib/badline/c128/drives.rb +10 -11
  21. data/lib/badline/c128/fast_serial.rb +5 -5
  22. data/lib/badline/c128/mmu_pages.rb +1 -1
  23. data/lib/badline/c128/modes.rb +2 -2
  24. data/lib/badline/c128/saved_state.rb +21 -47
  25. data/lib/badline/c128/z80.rb +2 -2
  26. data/lib/badline/c128.rb +18 -72
  27. data/lib/badline/{computer → c64}/attachments.rb +16 -47
  28. data/lib/badline/c64/banked_ram/banking.rb +32 -0
  29. data/lib/badline/c64/banked_ram/plus256k.rb +56 -0
  30. data/lib/badline/c64/banked_ram/plus60k.rb +45 -0
  31. data/lib/badline/c64/banked_ram/unexpanded.rb +30 -0
  32. data/lib/badline/c64/banked_ram.rb +23 -0
  33. data/lib/badline/c64/bus/extra_sids.rb +32 -0
  34. data/lib/badline/c64/bus/fittings.rb +40 -0
  35. data/lib/badline/c64/bus/pla.rb +149 -0
  36. data/lib/badline/c64/bus/roms.rb +41 -0
  37. data/lib/badline/c64/bus/saved_state.rb +68 -0
  38. data/lib/badline/c64/bus/sid_slots.rb +44 -0
  39. data/lib/badline/c64/bus.rb +218 -0
  40. data/lib/badline/c64/cartridge/action_replay.rb +128 -0
  41. data/lib/badline/c64/cartridge/atomic_power.rb +26 -0
  42. data/lib/badline/c64/cartridge/bank.rb +83 -0
  43. data/lib/badline/c64/cartridge/comal80.rb +52 -0
  44. data/lib/badline/c64/cartridge/dinamic.rb +36 -0
  45. data/lib/badline/c64/cartridge/easy_flash.rb +147 -0
  46. data/lib/badline/c64/cartridge/epyx_fastload.rb +81 -0
  47. data/lib/badline/c64/cartridge/final_cartridge3.rb +91 -0
  48. data/lib/badline/c64/cartridge/flash/saved_state.rb +40 -0
  49. data/lib/badline/c64/cartridge/flash.rb +279 -0
  50. data/lib/badline/c64/cartridge/freezer.rb +35 -0
  51. data/lib/badline/c64/cartridge/fun_play.rb +40 -0
  52. data/lib/badline/c64/cartridge/g_mod2.rb +76 -0
  53. data/lib/badline/c64/cartridge/game_system.rb +42 -0
  54. data/lib/badline/c64/cartridge/geo_ram.rb +81 -0
  55. data/lib/badline/c64/cartridge/kcs_power.rb +77 -0
  56. data/lib/badline/c64/cartridge/mach5.rb +34 -0
  57. data/lib/badline/c64/cartridge/magic_desk.rb +32 -0
  58. data/lib/badline/c64/cartridge/ocean.rb +37 -0
  59. data/lib/badline/c64/cartridge/pagefox.rb +70 -0
  60. data/lib/badline/c64/cartridge/retro_replay/saved_state.rb +47 -0
  61. data/lib/badline/c64/cartridge/retro_replay.rb +286 -0
  62. data/lib/badline/c64/cartridge/rex_utility.rb +31 -0
  63. data/lib/badline/c64/cartridge/rgcd.rb +60 -0
  64. data/lib/badline/c64/cartridge/saved_state.rb +63 -0
  65. data/lib/badline/c64/cartridge/simons_basic.rb +37 -0
  66. data/lib/badline/c64/cartridge/standard.rb +17 -0
  67. data/lib/badline/c64/cartridge/super_games.rb +50 -0
  68. data/lib/badline/c64/cartridge/westermann.rb +32 -0
  69. data/lib/badline/c64/cartridge/zaxxon.rb +68 -0
  70. data/lib/badline/c64/cartridge.rb +258 -0
  71. data/lib/badline/c64/color_memory.rb +27 -0
  72. data/lib/badline/c64/common.rb +34 -0
  73. data/lib/badline/c64/kernal_traps.rb +89 -0
  74. data/lib/badline/c64/reu/dma/saved_state.rb +52 -0
  75. data/lib/badline/c64/reu/dma.rb +275 -0
  76. data/lib/badline/c64/reu/ram.rb +109 -0
  77. data/lib/badline/c64/reu/saved_state.rb +55 -0
  78. data/lib/badline/c64/reu/trigger.rb +34 -0
  79. data/lib/badline/c64/reu.rb +291 -0
  80. data/lib/badline/{computer → c64}/saved_state.rb +13 -18
  81. data/lib/badline/{computer → c64}/true_drives.rb +20 -31
  82. data/lib/badline/{computer.rb → c64.rb} +22 -80
  83. data/lib/badline/chips/cia/fast_forward.rb +62 -0
  84. data/lib/badline/chips/cia/interrupt_register.rb +145 -0
  85. data/lib/badline/chips/cia/saved_state.rb +49 -0
  86. data/lib/badline/chips/cia/serial/saved_state.rb +45 -0
  87. data/lib/badline/chips/cia/serial.rb +250 -0
  88. data/lib/badline/chips/cia/time_of_day.rb +232 -0
  89. data/lib/badline/chips/cia/timer.rb +208 -0
  90. data/lib/badline/chips/cia.rb +281 -0
  91. data/lib/badline/chips/cpu/addressing.rb +133 -0
  92. data/lib/badline/chips/cpu/boundary.rb +56 -0
  93. data/lib/badline/chips/cpu/core.rb +167 -0
  94. data/lib/badline/chips/cpu/instruction.rb +338 -0
  95. data/lib/badline/chips/cpu/instruction_set/arithmetic.rb +118 -0
  96. data/lib/badline/chips/cpu/instruction_set/bitwise.rb +130 -0
  97. data/lib/badline/chips/cpu/instruction_set/branch.rb +83 -0
  98. data/lib/badline/chips/cpu/instruction_set/flag.rb +67 -0
  99. data/lib/badline/chips/cpu/instruction_set/illegal.rb +274 -0
  100. data/lib/badline/chips/cpu/instruction_set/inc_dec.rb +73 -0
  101. data/lib/badline/chips/cpu/instruction_set/stack.rb +56 -0
  102. data/lib/badline/chips/cpu/instruction_set/transfer.rb +141 -0
  103. data/lib/badline/chips/cpu/instruction_set.rb +59 -0
  104. data/lib/badline/chips/cpu/interrupts.rb +108 -0
  105. data/lib/badline/chips/cpu/microcode.rb +179 -0
  106. data/lib/badline/chips/cpu/operations.rb +90 -0
  107. data/lib/badline/chips/cpu/port.rb +116 -0
  108. data/lib/badline/chips/cpu/saved_state.rb +117 -0
  109. data/lib/badline/chips/cpu/stack_operations.rb +84 -0
  110. data/lib/badline/chips/cpu/traps.rb +23 -0
  111. data/lib/badline/chips/cpu.rb +12 -0
  112. data/lib/badline/chips/sid/catch_up.rb +122 -0
  113. data/lib/badline/chips/sid/decimator.rb +66 -0
  114. data/lib/badline/chips/sid/envelope/saved_state.rb +70 -0
  115. data/lib/badline/chips/sid/envelope.rb +241 -0
  116. data/lib/badline/chips/sid/filter/saved_state.rb +42 -0
  117. data/lib/badline/chips/sid/filter.rb +241 -0
  118. data/lib/badline/chips/sid/saved_state.rb +52 -0
  119. data/lib/badline/chips/sid/voice.rb +79 -0
  120. data/lib/badline/chips/sid/waveform/combined.rb +128 -0
  121. data/lib/badline/chips/sid/waveform/fast_forward.rb +107 -0
  122. data/lib/badline/chips/sid/waveform/noise_writeback.rb +124 -0
  123. data/lib/badline/chips/sid/waveform/saved_state.rb +68 -0
  124. data/lib/badline/chips/sid/waveform.rb +307 -0
  125. data/lib/badline/chips/sid.rb +265 -0
  126. data/lib/badline/{c128 → chips}/vdc/memory.rb +1 -1
  127. data/lib/badline/{c128 → chips}/vdc/painter.rb +1 -1
  128. data/lib/badline/{c128 → chips}/vdc/raster.rb +1 -1
  129. data/lib/badline/chips/vdc/saved_state.rb +36 -0
  130. data/lib/badline/{c128 → chips}/vdc/window.rb +1 -1
  131. data/lib/badline/{c128 → chips}/vdc.rb +7 -31
  132. data/lib/badline/chips/via/control_lines.rb +124 -0
  133. data/lib/badline/chips/via/fast_forward.rb +55 -0
  134. data/lib/badline/chips/via/interrupt_register.rb +69 -0
  135. data/lib/badline/chips/via/saved_state.rb +44 -0
  136. data/lib/badline/chips/via/shift_register.rb +182 -0
  137. data/lib/badline/chips/via/timer1.rb +133 -0
  138. data/lib/badline/chips/via/timer2.rb +135 -0
  139. data/lib/badline/chips/via.rb +268 -0
  140. data/lib/badline/chips/vic/bank.rb +135 -0
  141. data/lib/badline/chips/vic/border_mask.rb +88 -0
  142. data/lib/badline/chips/vic/collisions.rb +117 -0
  143. data/lib/badline/chips/vic/color_patches.rb +49 -0
  144. data/lib/badline/chips/vic/display_state.rb +187 -0
  145. data/lib/badline/chips/vic/graphics_mode.rb +166 -0
  146. data/lib/badline/chips/vic/graphics_shifter/saved_state.rb +40 -0
  147. data/lib/badline/chips/vic/graphics_shifter.rb +187 -0
  148. data/lib/badline/chips/vic/register_log.rb +83 -0
  149. data/lib/badline/chips/vic/registers.rb +197 -0
  150. data/lib/badline/chips/vic/saved_state.rb +82 -0
  151. data/lib/badline/chips/vic/sequencer/saved_state.rb +91 -0
  152. data/lib/badline/chips/vic/sequencer.rb +277 -0
  153. data/lib/badline/chips/vic/sequencer_output.rb +118 -0
  154. data/lib/badline/chips/vic/sprite/internal_bus.rb +70 -0
  155. data/lib/badline/chips/vic/sprite/saved_state.rb +66 -0
  156. data/lib/badline/chips/vic/sprite/shifter.rb +148 -0
  157. data/lib/badline/chips/vic/sprite/timing.rb +58 -0
  158. data/lib/badline/chips/vic/sprite.rb +339 -0
  159. data/lib/badline/chips/vic/sprites/saved_state.rb +59 -0
  160. data/lib/badline/chips/vic/sprites.rb +284 -0
  161. data/lib/badline/chips/vic.rb +783 -0
  162. data/lib/badline/chips/vic_i/painter/saved_state.rb +40 -0
  163. data/lib/badline/{vic20/vic → chips/vic_i}/painter.rb +6 -30
  164. data/lib/badline/{vic20/vic → chips/vic_i}/saved_state.rb +2 -2
  165. data/lib/badline/chips/vic_i/sound/output.rb +85 -0
  166. data/lib/badline/chips/vic_i/sound.rb +235 -0
  167. data/lib/badline/{vic20/vic → chips/vic_i}/text_window.rb +2 -2
  168. data/lib/badline/{vic20/vic.rb → chips/vic_i.rb} +5 -5
  169. data/lib/badline/chips/z80/arithmetic.rb +119 -0
  170. data/lib/badline/chips/z80/bit_page.rb +57 -0
  171. data/lib/badline/chips/z80/block_io.rb +60 -0
  172. data/lib/badline/chips/z80/block_transfers.rb +61 -0
  173. data/lib/badline/chips/z80/bus_cycles.rb +113 -0
  174. data/lib/badline/chips/z80/core.rb +115 -0
  175. data/lib/badline/chips/z80/exchanges.rb +52 -0
  176. data/lib/badline/chips/z80/extended_page.rb +91 -0
  177. data/lib/badline/chips/z80/flags.rb +39 -0
  178. data/lib/badline/chips/z80/interrupt_acceptance.rb +48 -0
  179. data/lib/badline/chips/z80/jumps.rb +84 -0
  180. data/lib/badline/chips/z80/loads.rb +100 -0
  181. data/lib/badline/chips/z80/main_page.rb +136 -0
  182. data/lib/badline/chips/z80/registers.rb +122 -0
  183. data/lib/badline/chips/z80/saved_state.rb +71 -0
  184. data/lib/badline/chips/z80/shifts.rb +66 -0
  185. data/lib/badline/chips/z80.rb +13 -0
  186. data/lib/badline/core.rb +27 -29
  187. data/lib/badline/drives/datasette/saved_state.rb +37 -0
  188. data/lib/badline/drives/datasette.rb +140 -0
  189. data/lib/badline/drives/engine/core.rb +149 -0
  190. data/lib/badline/drives/engine/fast_serial.rb +75 -0
  191. data/lib/badline/drives/engine/idle.rb +127 -0
  192. data/lib/badline/drives/engine/idle_cpu.rb +30 -0
  193. data/lib/badline/drives/engine/orbit.rb +81 -0
  194. data/lib/badline/drives/engine/serial_lines.rb +75 -0
  195. data/lib/badline/drives/engine/sleep.rb +114 -0
  196. data/lib/badline/drives/engine/vias.rb +86 -0
  197. data/lib/badline/drives/engine/watch.rb +152 -0
  198. data/lib/badline/drives/engine.rb +11 -0
  199. data/lib/badline/drives/model1541/bus.rb +88 -0
  200. data/lib/badline/drives/model1541/byte_ready.rb +50 -0
  201. data/lib/badline/drives/model1541/cpu.rb +13 -0
  202. data/lib/badline/drives/model1541/disk/saved_state.rb +88 -0
  203. data/lib/badline/drives/model1541/disk.rb +317 -0
  204. data/lib/badline/drives/model1541/disk_via.rb +38 -0
  205. data/lib/badline/drives/model1541/gcr.rb +59 -0
  206. data/lib/badline/drives/model1541/mechanism/saved_state.rb +72 -0
  207. data/lib/badline/drives/model1541/mechanism.rb +315 -0
  208. data/lib/badline/drives/model1541/rotation.rb +123 -0
  209. data/lib/badline/drives/model1541/saved_state.rb +44 -0
  210. data/lib/badline/drives/model1541/sector_reader.rb +78 -0
  211. data/lib/badline/drives/model1541/serial_port.rb +20 -0
  212. data/lib/badline/drives/model1541/track.rb +100 -0
  213. data/lib/badline/drives/model1541.rb +81 -0
  214. data/lib/badline/drives/model1571/bus.rb +113 -0
  215. data/lib/badline/drives/model1571/cpu.rb +13 -0
  216. data/lib/badline/drives/model1571/saved_state.rb +47 -0
  217. data/lib/badline/drives/model1571/serial_port.rb +39 -0
  218. data/lib/badline/drives/model1571/serial_via.rb +27 -0
  219. data/lib/badline/drives/model1571/wd1770.rb +122 -0
  220. data/lib/badline/drives/model1571.rb +142 -0
  221. data/lib/badline/drives/model1581/bus.rb +139 -0
  222. data/lib/badline/drives/model1581/cpu.rb +13 -0
  223. data/lib/badline/drives/model1581/disk/saved_state.rb +89 -0
  224. data/lib/badline/drives/model1581/disk.rb +137 -0
  225. data/lib/badline/drives/model1581/mechanism.rb +119 -0
  226. data/lib/badline/drives/model1581/saved_state.rb +42 -0
  227. data/lib/badline/drives/model1581/serial_port.rb +54 -0
  228. data/lib/badline/drives/model1581/slot.rb +79 -0
  229. data/lib/badline/drives/model1581/track.rb +102 -0
  230. data/lib/badline/drives/model1581/track_bytes.rb +77 -0
  231. data/lib/badline/drives/model1581/wd1772/registers.rb +91 -0
  232. data/lib/badline/drives/model1581/wd1772/saved_state.rb +68 -0
  233. data/lib/badline/drives/model1581/wd1772/sector_writes.rb +75 -0
  234. data/lib/badline/drives/model1581/wd1772/sectors.rb +152 -0
  235. data/lib/badline/drives/model1581/wd1772/stepping.rb +111 -0
  236. data/lib/badline/drives/model1581/wd1772/tracks.rb +127 -0
  237. data/lib/badline/drives/model1581/wd1772/turn.rb +75 -0
  238. data/lib/badline/drives/model1581/wd1772.rb +218 -0
  239. data/lib/badline/drives/model1581.rb +206 -0
  240. data/lib/badline/drives/serial_bus.rb +161 -0
  241. data/lib/badline/frontend/boot.rb +10 -61
  242. data/lib/badline/frontend/machine_window.rb +3 -1
  243. data/lib/badline/frontend/player/filter_view.rb +1 -1
  244. data/lib/badline/frontend/player/player_controller.rb +2 -2
  245. data/lib/badline/frontend/player/player_screen.rb +1 -0
  246. data/lib/badline/frontend/player/theme.rb +7 -7
  247. data/lib/badline/frontend/timeline.rb +3 -3
  248. data/lib/badline/input/control_ports.rb +78 -0
  249. data/lib/badline/input/joystick.rb +27 -0
  250. data/lib/badline/input/keyboard.rb +114 -0
  251. data/lib/badline/input.rb +3 -0
  252. data/lib/badline/kernal_trap/{drive → dos}/block_commands.rb +1 -1
  253. data/lib/badline/kernal_trap/dos/channel.rb +183 -0
  254. data/lib/badline/kernal_trap/{drive → dos}/channels.rb +1 -1
  255. data/lib/badline/kernal_trap/{drive → dos}/memory.rb +1 -1
  256. data/lib/badline/kernal_trap/{drive → dos}/parameters.rb +1 -1
  257. data/lib/badline/kernal_trap/{drive → dos}/status.rb +1 -1
  258. data/lib/badline/kernal_trap/{drive → dos}/write_file.rb +1 -1
  259. data/lib/badline/kernal_trap/{drive → dos}/writes.rb +1 -1
  260. data/lib/badline/kernal_trap/{drive.rb → dos.rb} +11 -10
  261. data/lib/badline/kernal_trap/{file.rb → file_routine.rb} +1 -1
  262. data/lib/badline/kernal_trap/load.rb +6 -6
  263. data/lib/badline/kernal_trap/save.rb +5 -5
  264. data/lib/badline/kernal_trap/serial.rb +7 -7
  265. data/lib/badline/kernal_trap.rb +2 -3
  266. data/lib/badline/machine/clocking.rb +50 -0
  267. data/lib/badline/machine.rb +63 -7
  268. data/lib/badline/media/boot_disk.rb +2 -2
  269. data/lib/badline/media/disk_list.rb +3 -3
  270. data/lib/badline/media/disk_set.rb +1 -1
  271. data/lib/badline/media/extensions.rb +33 -0
  272. data/lib/badline/media/program.rb +28 -0
  273. data/lib/badline/media/true_drive.rb +4 -3
  274. data/lib/badline/media/tune.rb +35 -0
  275. data/lib/badline/media/vic20_cartridge.rb +1 -7
  276. data/lib/badline/media/vic20_media.rb +38 -80
  277. data/lib/badline/media.rb +84 -81
  278. data/lib/badline/model.rb +1 -1
  279. data/lib/badline/options/event.rb +3 -1
  280. data/lib/badline/roms/README +6 -6
  281. data/lib/badline/sdl.rb +1 -0
  282. data/lib/badline/{storage/sid_file.rb → sid_tune/file.rb} +3 -3
  283. data/lib/badline/{storage → sid_tune}/hvsc.rb +7 -7
  284. data/lib/badline/{storage → sid_tune}/song_lengths.rb +2 -2
  285. data/lib/badline/{storage → sid_tune}/stil/credit.rb +1 -1
  286. data/lib/badline/{storage → sid_tune}/stil.rb +3 -3
  287. data/lib/badline/sid_tune.rb +6 -0
  288. data/lib/badline/snapshot/c128_setup.rb +43 -0
  289. data/lib/badline/snapshot/c64_setup.rb +79 -0
  290. data/lib/badline/snapshot/image.rb +5 -25
  291. data/lib/badline/snapshot/machine_state.rb +10 -2
  292. data/lib/badline/snapshot/setup.rb +22 -66
  293. data/lib/badline/snapshot/state.rb +8 -17
  294. data/lib/badline/snapshot/storage_setup.rb +68 -0
  295. data/lib/badline/snapshot/vic20_setup.rb +37 -0
  296. data/lib/badline/snapshot/vice/c64_mem.rb +1 -1
  297. data/lib/badline/snapshot/vice/restore.rb +1 -1
  298. data/lib/badline/snapshot/vice/reu1764.rb +1 -1
  299. data/lib/badline/snapshot/vice/reu_fields.rb +40 -0
  300. data/lib/badline/snapshot/vice.rb +7 -5
  301. data/lib/badline/snapshot.rb +13 -12
  302. data/lib/badline/storage/d64_image.rb +15 -9
  303. data/lib/badline/storage/d71_image.rb +0 -2
  304. data/lib/badline/storage/d81_image.rb +0 -2
  305. data/lib/badline/storage/disk_image/writing.rb +2 -2
  306. data/lib/badline/storage/disk_image.rb +3 -6
  307. data/lib/badline/storage/g64_image.rb +2 -2
  308. data/lib/badline/storage/host_directory.rb +0 -5
  309. data/lib/badline/storage/t64.rb +2 -8
  310. data/lib/badline/storage/unavailable.rb +1 -1
  311. data/lib/badline/storage.rb +0 -37
  312. data/lib/badline/support/c128_checkpoint.rb +39 -0
  313. data/lib/badline/support/checkpoint.rb +108 -0
  314. data/lib/badline/support/vic20_checkpoint.rb +38 -0
  315. data/lib/badline/support.rb +5 -0
  316. data/lib/badline/version.rb +1 -1
  317. data/lib/badline/vic20/attachments.rb +11 -81
  318. data/lib/badline/vic20/bus/saved_state.rb +35 -0
  319. data/lib/badline/vic20/bus.rb +3 -25
  320. data/lib/badline/vic20/cpu.rb +1 -1
  321. data/lib/badline/vic20/port_wiring.rb +4 -4
  322. data/lib/badline/vic20/saved_state.rb +16 -60
  323. data/lib/badline/vic20/user_via_ports.rb +2 -2
  324. data/lib/badline/vic20.rb +20 -51
  325. metadata +250 -221
  326. data/lib/badline/address_bus/extra_sids.rb +0 -30
  327. data/lib/badline/address_bus/fittings.rb +0 -38
  328. data/lib/badline/address_bus/pla.rb +0 -147
  329. data/lib/badline/address_bus/roms.rb +0 -39
  330. data/lib/badline/address_bus/saved_state.rb +0 -72
  331. data/lib/badline/address_bus/sid_slots.rb +0 -42
  332. data/lib/badline/address_bus.rb +0 -235
  333. data/lib/badline/cartridge/action_replay.rb +0 -126
  334. data/lib/badline/cartridge/atomic_power.rb +0 -24
  335. data/lib/badline/cartridge/bank.rb +0 -81
  336. data/lib/badline/cartridge/comal80.rb +0 -50
  337. data/lib/badline/cartridge/dinamic.rb +0 -34
  338. data/lib/badline/cartridge/easy_flash.rb +0 -145
  339. data/lib/badline/cartridge/epyx_fastload.rb +0 -79
  340. data/lib/badline/cartridge/final_cartridge3.rb +0 -89
  341. data/lib/badline/cartridge/flash.rb +0 -306
  342. data/lib/badline/cartridge/freezer.rb +0 -33
  343. data/lib/badline/cartridge/fun_play.rb +0 -38
  344. data/lib/badline/cartridge/g_mod2.rb +0 -74
  345. data/lib/badline/cartridge/game_system.rb +0 -40
  346. data/lib/badline/cartridge/geo_ram.rb +0 -79
  347. data/lib/badline/cartridge/kcs_power.rb +0 -75
  348. data/lib/badline/cartridge/mach5.rb +0 -32
  349. data/lib/badline/cartridge/magic_desk.rb +0 -30
  350. data/lib/badline/cartridge/ocean.rb +0 -35
  351. data/lib/badline/cartridge/pagefox.rb +0 -68
  352. data/lib/badline/cartridge/retro_replay.rb +0 -320
  353. data/lib/badline/cartridge/rex_utility.rb +0 -29
  354. data/lib/badline/cartridge/rgcd.rb +0 -58
  355. data/lib/badline/cartridge/simons_basic.rb +0 -35
  356. data/lib/badline/cartridge/standard.rb +0 -15
  357. data/lib/badline/cartridge/super_games.rb +0 -48
  358. data/lib/badline/cartridge/westermann.rb +0 -30
  359. data/lib/badline/cartridge/zaxxon.rb +0 -66
  360. data/lib/badline/cartridge.rb +0 -303
  361. data/lib/badline/checkpoint.rb +0 -98
  362. data/lib/badline/cia/fast_forward.rb +0 -60
  363. data/lib/badline/cia/interrupt_register.rb +0 -143
  364. data/lib/badline/cia/serial.rb +0 -275
  365. data/lib/badline/cia/state.rb +0 -47
  366. data/lib/badline/cia/timer.rb +0 -206
  367. data/lib/badline/cia.rb +0 -279
  368. data/lib/badline/color_memory.rb +0 -25
  369. data/lib/badline/computer/kernal_traps.rb +0 -29
  370. data/lib/badline/control_ports.rb +0 -76
  371. data/lib/badline/cpu/addressing.rb +0 -131
  372. data/lib/badline/cpu/boundary.rb +0 -54
  373. data/lib/badline/cpu/core.rb +0 -165
  374. data/lib/badline/cpu/microcode.rb +0 -177
  375. data/lib/badline/cpu/operations.rb +0 -88
  376. data/lib/badline/cpu/saved_state.rb +0 -115
  377. data/lib/badline/cpu/stack_operations.rb +0 -82
  378. data/lib/badline/cpu.rb +0 -10
  379. data/lib/badline/cycleable.rb +0 -38
  380. data/lib/badline/datasette.rb +0 -161
  381. data/lib/badline/drive/core.rb +0 -147
  382. data/lib/badline/drive/fast_serial.rb +0 -73
  383. data/lib/badline/drive/idle.rb +0 -125
  384. data/lib/badline/drive/idle_cpu.rb +0 -28
  385. data/lib/badline/drive/orbit.rb +0 -79
  386. data/lib/badline/drive/serial_lines.rb +0 -73
  387. data/lib/badline/drive/sleep.rb +0 -112
  388. data/lib/badline/drive/vias.rb +0 -84
  389. data/lib/badline/drive/watch.rb +0 -150
  390. data/lib/badline/drive.rb +0 -11
  391. data/lib/badline/drive1541/bus.rb +0 -86
  392. data/lib/badline/drive1541/byte_ready.rb +0 -48
  393. data/lib/badline/drive1541/cpu.rb +0 -11
  394. data/lib/badline/drive1541/disk.rb +0 -318
  395. data/lib/badline/drive1541/disk_state.rb +0 -94
  396. data/lib/badline/drive1541/disk_via.rb +0 -36
  397. data/lib/badline/drive1541/gcr.rb +0 -57
  398. data/lib/badline/drive1541/mechanism.rb +0 -313
  399. data/lib/badline/drive1541/mechanism_state.rb +0 -68
  400. data/lib/badline/drive1541/rotation.rb +0 -121
  401. data/lib/badline/drive1541/sector_reader.rb +0 -76
  402. data/lib/badline/drive1541/serial_port.rb +0 -18
  403. data/lib/badline/drive1541/track.rb +0 -98
  404. data/lib/badline/drive1541.rb +0 -111
  405. data/lib/badline/drive1571/bus.rb +0 -111
  406. data/lib/badline/drive1571/cpu.rb +0 -11
  407. data/lib/badline/drive1571/serial_port.rb +0 -37
  408. data/lib/badline/drive1571/serial_via.rb +0 -25
  409. data/lib/badline/drive1571/wd1770.rb +0 -120
  410. data/lib/badline/drive1571.rb +0 -175
  411. data/lib/badline/drive1581/bus.rb +0 -137
  412. data/lib/badline/drive1581/cpu.rb +0 -11
  413. data/lib/badline/drive1581/disk.rb +0 -135
  414. data/lib/badline/drive1581/disk_state.rb +0 -87
  415. data/lib/badline/drive1581/mechanism.rb +0 -117
  416. data/lib/badline/drive1581/serial_port.rb +0 -52
  417. data/lib/badline/drive1581/slot.rb +0 -78
  418. data/lib/badline/drive1581/track.rb +0 -100
  419. data/lib/badline/drive1581/track_bytes.rb +0 -75
  420. data/lib/badline/drive1581/wd1772/registers.rb +0 -89
  421. data/lib/badline/drive1581/wd1772/sector_writes.rb +0 -73
  422. data/lib/badline/drive1581/wd1772/sectors.rb +0 -150
  423. data/lib/badline/drive1581/wd1772/state.rb +0 -66
  424. data/lib/badline/drive1581/wd1772/stepping.rb +0 -109
  425. data/lib/badline/drive1581/wd1772/tracks.rb +0 -125
  426. data/lib/badline/drive1581/wd1772/turn.rb +0 -73
  427. data/lib/badline/drive1581/wd1772.rb +0 -216
  428. data/lib/badline/drive1581.rb +0 -233
  429. data/lib/badline/iec_bus.rb +0 -159
  430. data/lib/badline/instruction.rb +0 -334
  431. data/lib/badline/instruction_set/arithmetic.rb +0 -114
  432. data/lib/badline/instruction_set/bitwise.rb +0 -126
  433. data/lib/badline/instruction_set/branch.rb +0 -79
  434. data/lib/badline/instruction_set/flag.rb +0 -63
  435. data/lib/badline/instruction_set/illegal.rb +0 -270
  436. data/lib/badline/instruction_set/inc_dec.rb +0 -69
  437. data/lib/badline/instruction_set/stack.rb +0 -52
  438. data/lib/badline/instruction_set/transfer.rb +0 -137
  439. data/lib/badline/instruction_set.rb +0 -55
  440. data/lib/badline/interrupts.rb +0 -104
  441. data/lib/badline/joystick.rb +0 -25
  442. data/lib/badline/kernal_trap/channel.rb +0 -181
  443. data/lib/badline/keyboard.rb +0 -112
  444. data/lib/badline/ram_expansion/banking.rb +0 -30
  445. data/lib/badline/ram_expansion/plus256k.rb +0 -54
  446. data/lib/badline/ram_expansion/plus60k.rb +0 -43
  447. data/lib/badline/ram_expansion/unexpanded.rb +0 -28
  448. data/lib/badline/ram_expansion.rb +0 -21
  449. data/lib/badline/reu/dma/saved_state.rb +0 -50
  450. data/lib/badline/reu/dma.rb +0 -273
  451. data/lib/badline/reu/ram.rb +0 -107
  452. data/lib/badline/reu/saved_state.rb +0 -80
  453. data/lib/badline/reu/trigger.rb +0 -32
  454. data/lib/badline/reu.rb +0 -289
  455. data/lib/badline/sid/catch_up.rb +0 -120
  456. data/lib/badline/sid/decimator.rb +0 -64
  457. data/lib/badline/sid/envelope/state.rb +0 -68
  458. data/lib/badline/sid/envelope.rb +0 -239
  459. data/lib/badline/sid/filter.rb +0 -263
  460. data/lib/badline/sid/voice.rb +0 -77
  461. data/lib/badline/sid/waveform/combined.rb +0 -126
  462. data/lib/badline/sid/waveform/fast_forward.rb +0 -105
  463. data/lib/badline/sid/waveform/noise_writeback.rb +0 -122
  464. data/lib/badline/sid/waveform/state.rb +0 -66
  465. data/lib/badline/sid/waveform.rb +0 -305
  466. data/lib/badline/sid.rb +0 -303
  467. data/lib/badline/time_of_day.rb +0 -228
  468. data/lib/badline/traps.rb +0 -19
  469. data/lib/badline/via/control_lines.rb +0 -122
  470. data/lib/badline/via/fast_forward.rb +0 -53
  471. data/lib/badline/via/interrupt_register.rb +0 -67
  472. data/lib/badline/via/shift_register.rb +0 -180
  473. data/lib/badline/via/state.rb +0 -42
  474. data/lib/badline/via/timer1.rb +0 -131
  475. data/lib/badline/via/timer2.rb +0 -133
  476. data/lib/badline/via.rb +0 -266
  477. data/lib/badline/vic/bank.rb +0 -133
  478. data/lib/badline/vic/border_mask.rb +0 -86
  479. data/lib/badline/vic/collisions.rb +0 -115
  480. data/lib/badline/vic/color_patches.rb +0 -47
  481. data/lib/badline/vic/display_state.rb +0 -185
  482. data/lib/badline/vic/graphics_mode.rb +0 -164
  483. data/lib/badline/vic/graphics_shifter.rb +0 -207
  484. data/lib/badline/vic/register_log.rb +0 -81
  485. data/lib/badline/vic/registers.rb +0 -195
  486. data/lib/badline/vic/sequencer.rb +0 -275
  487. data/lib/badline/vic/sequencer_output.rb +0 -116
  488. data/lib/badline/vic/sequencer_state.rb +0 -89
  489. data/lib/badline/vic/sprite/internal_bus.rb +0 -68
  490. data/lib/badline/vic/sprite/saved_state.rb +0 -64
  491. data/lib/badline/vic/sprite/shifter.rb +0 -146
  492. data/lib/badline/vic/sprite/timing.rb +0 -56
  493. data/lib/badline/vic/sprite.rb +0 -337
  494. data/lib/badline/vic/sprites.rb +0 -282
  495. data/lib/badline/vic/sprites_state.rb +0 -57
  496. data/lib/badline/vic.rb +0 -852
  497. data/lib/badline/vic20/sound/output.rb +0 -83
  498. data/lib/badline/vic20/sound.rb +0 -233
  499. data/lib/badline/z80/arithmetic.rb +0 -117
  500. data/lib/badline/z80/bit_page.rb +0 -55
  501. data/lib/badline/z80/block_io.rb +0 -58
  502. data/lib/badline/z80/block_transfers.rb +0 -59
  503. data/lib/badline/z80/bus_cycles.rb +0 -111
  504. data/lib/badline/z80/core.rb +0 -113
  505. data/lib/badline/z80/exchanges.rb +0 -50
  506. data/lib/badline/z80/extended_page.rb +0 -89
  507. data/lib/badline/z80/flags.rb +0 -37
  508. data/lib/badline/z80/interrupt_acceptance.rb +0 -46
  509. data/lib/badline/z80/jumps.rb +0 -82
  510. data/lib/badline/z80/loads.rb +0 -98
  511. data/lib/badline/z80/main_page.rb +0 -134
  512. data/lib/badline/z80/registers.rb +0 -120
  513. data/lib/badline/z80/saved_state.rb +0 -69
  514. data/lib/badline/z80/shifts.rb +0 -64
  515. data/lib/badline/z80.rb +0 -11
  516. /data/lib/badline/snapshot/{fields.rb → vice/fields.rb} +0 -0
@@ -1,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 << 62
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