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,111 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "badline/drive"
4
- require "badline/drive1541/bus"
5
- require "badline/drive1541/cpu"
6
- require "badline/drive1541/serial_port"
7
- require "badline/drive1541/gcr"
8
- require "badline/drive1541/track"
9
- require "badline/drive1541/disk"
10
- require "badline/drive1541/mechanism"
11
- require "badline/drive1541/disk_via"
12
-
13
- module Badline
14
- # The 1541 disk drive as a machine of its own: a 6502 running the DOS
15
- # ROM at 1 MHz, with 2 KB of RAM and two VIAs on its bus. Drive::Core
16
- # clocks it against the host and sleeps through the DOS's idle loop.
17
- class Drive1541
18
- include Drive::Core
19
- include Drive::VIAs
20
-
21
- CLOCK_HZ = 1_000_000
22
-
23
- # Where the DOS 2.6 idle loop starts over (see Drive::Idle).
24
- IDLE_LOOP = 0xebff
25
-
26
- def model_name = "1541"
27
-
28
- # +rom+ covers $C000-$FFFF, and defaults to the DOS image in the ROM
29
- # path. +device+ is the number the jumpers on VIA 1's PB5 and PB6 set,
30
- # 8 to 11.
31
- def initialize(rom: nil, host_clock_hz: CLOCK_HZ, device: 8, debug: false)
32
- @device = device
33
- @serial_port = SerialPort.new(device:)
34
- @via1 = VIA.new(start: 0x1800, peripheral: @serial_port)
35
- @mechanism = Mechanism.new
36
- @via2 = DiskVIA.new(start: 0x1c00, mechanism: @mechanism)
37
- @bus = Bus.new(rom: rom || ROM.load("dos1541.rom", 0xc000), via1: @via1, via2: @via2)
38
- @cpu = CPU.new(@bus, debug:)
39
- @clock_hz = CLOCK_HZ
40
- @idle_loop = IDLE_LOOP
41
- @host_clock_hz = host_clock_hz
42
- @phase = 0
43
- @cycles = 0
44
- @serial_bus = nil
45
- init_idle(debug)
46
- # CA1 powers up at the level of a released ATN, without an edge.
47
- @via1.ca1 = false
48
- @via1.reset!
49
- connect(IECBus.new)
50
- end
51
-
52
- # The drive's whole state: its clock phase, the CPU, RAM, both VIAs,
53
- # the serial port's latch of the C64's lines and the mechanism with its
54
- # disk. The drive settles first, so it is awake and not recording a
55
- # pass, and a restored drive starts the same way, its orbits forgotten
56
- # from the state it takes: Idle's and Orbit's bookkeeping
57
- # isn't stored. The device number, the host's clock rate and whether
58
- # the drive may sleep are the machine's wiring.
59
- def save_state(out)
60
- settle!
61
- out.marker("DRIVE1541")
62
- out.int(@phase).int(@cycles).boolean(@mechanism.so_pending)
63
- @serial_port.save_state(out)
64
- @via1.save_state(out)
65
- @via2.save_state(out)
66
- @bus.save_state(out)
67
- @cpu.save_state(out)
68
- @mechanism.save_state(out)
69
- end
70
-
71
- def load_state(input)
72
- settle!
73
- input.marker("DRIVE1541")
74
- @phase = input.int
75
- @cycles = input.int
76
- @mechanism.so_pending = input.boolean?
77
- @serial_port.load_state(input)
78
- @via1.load_state(input)
79
- @via2.load_state(input)
80
- @bus.load_state(input)
81
- @cpu.load_state(input)
82
- @mechanism.load_state(input)
83
- forget_orbits
84
- end
85
-
86
- private
87
-
88
- # One drive cycle. The VIAs clock ahead of the CPU, as the C64's chips
89
- # do, and either one pulls IRQ. Nothing drives NMI on the 1541. The CPU
90
- # runs whether or not the motor turns, since it answers ATN.
91
- #
92
- # The disk mechanism runs first, so BYTE READY lands on the VIA ahead
93
- # of the CPU's cycle. The CPU samples SO a cycle late: BYTE READY sets
94
- # V for the next cycle's instruction step.
95
- #
96
- # ATN reaches VIA 1's CA1 through the same inverter as PB7, so CA1 goes
97
- # high as the C64 asserts ATN, as the serial port sees it: from the
98
- # host cycle after the one that asserts it.
99
- def step
100
- so = @mechanism.take_so
101
- @mechanism.cycle!
102
- @via1.ca1 = @serial_port.atn_low?
103
- @via1.cycle!
104
- @via2.cycle!
105
- @cpu.irq = @via1.irq? || @via2.irq?
106
- @cpu.so! if so
107
- @cpu.cycle!
108
- @cycles += 1
109
- end
110
- end
111
- end
@@ -1,111 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Drive1571
5
- # The drive CPU's bus:
6
- #
7
- # $0000-$07FF - 2 KB of RAM
8
- # $0800-$17FF - nothing: open bus
9
- # $1800-$1BFF - VIA 1, its sixteen registers mirrored
10
- # $1C00-$1FFF - VIA 2, its sixteen registers mirrored
11
- # $2000-$3FFF - the WD1770, its four registers mirrored
12
- # $4000-$7FFF - the CIA, its sixteen registers mirrored
13
- # $8000-$FFFF - the DOS ROM
14
- #
15
- # Writes to the ROM and to open bus go nowhere, and a read from open
16
- # bus finds the last byte on the data bus, as on the 1541. Any access
17
- # to VIA 2 clears the BYTE READY latch VIA 1's PA7 reads (SerialPort).
18
- #
19
- # While Idle records a pass of the DOS's idle loop, the bus watches it,
20
- # and while Idle looks for an orbit, it guards the drive (see
21
- # Drive::Watch). Any access to the CIA or the WD1770 makes the pass
22
- # volatile and taints the drive.
23
- class Bus
24
- include Addressable
25
- include Drive::Watch
26
-
27
- attr_reader :ram, :rom, :via1, :via2, :cia, :fdc, :data
28
-
29
- def initialize(rom:, via1:, via2:, cia:, fdc:)
30
- addressable_at(0, length: 2**16)
31
- @ram = Memory.new([], length: 0x0800, start: 0)
32
- @rom = rom
33
- @via1 = via1
34
- @via2 = via2
35
- @cia = cia
36
- @fdc = fdc
37
- @mechanism = via2.mechanism
38
- @data = 0
39
- init_watch
40
- end
41
-
42
- # The last byte on the data bus and the RAM. What a watched stretch
43
- # touched is Idle's, and a restored bus isn't watching.
44
- def save_state(out)
45
- out.int(@data)
46
- @ram.save_state(out)
47
- end
48
-
49
- def load_state(input)
50
- @data = input.int
51
- @ram.load_state(input)
52
- @watching = false
53
- end
54
-
55
- def peek(addr)
56
- return @data = @rom.peek(addr) if addr >= 0x8000
57
- return @data = chip_peek(addr) if addr >= 0x2000
58
-
59
- watch_read(addr) if @watching
60
- @data = if addr < 0x0800
61
- @ram.peek(addr)
62
- elsif addr < 0x1800
63
- @data
64
- elsif addr < 0x1c00
65
- @via1.peek(addr)
66
- else
67
- @mechanism.release_byte_latch
68
- @via2.peek(addr)
69
- end
70
- end
71
-
72
- def poke(addr, value)
73
- @data = value
74
- return if addr >= 0x8000
75
- return chip_poke(addr, value) if addr >= 0x2000
76
-
77
- low_poke(addr, value)
78
- end
79
-
80
- private
81
-
82
- # A write below $2000: RAM or a VIA.
83
- def low_poke(addr, value)
84
- if addr < 0x0800
85
- touch(addr) if @recording
86
- @ram.poke(addr, value)
87
- elsif addr >= 0x1c00
88
- @mechanism.release_byte_latch
89
- @via2.poke(addr, value)
90
- elsif addr >= 0x1800
91
- @via1.poke(addr, value)
92
- end
93
- watch_write(addr) if @watching
94
- end
95
-
96
- def chip_peek(addr)
97
- watch_chip if @watching
98
- addr >= 0x4000 ? @cia.peek(0x4000 | (addr & 0x0f)) : @fdc.peek(addr & 0x03)
99
- end
100
-
101
- def chip_poke(addr, value)
102
- if addr >= 0x4000
103
- @cia.poke(0x4000 | (addr & 0x0f), value)
104
- else
105
- @fdc.poke(addr & 0x03, value)
106
- end
107
- watch_chip if @watching
108
- end
109
- end
110
- end
111
- end
@@ -1,11 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Drive1571
5
- # The drive's 6502, on the drive's Bus.
6
- class CPU
7
- include Badline::CPU::Core
8
- include Drive::IdleCPU
9
- end
10
- end
11
- end
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Drive1571
5
- # What VIA 1's ports read from outside the chip. Port B carries the
6
- # serial bus inputs and the device number jumpers, as on the 1541
7
- # (Drive::SerialLines). Port A reads the mechanism on two inputs:
8
- #
9
- # PA0 track 0 sensor, low while the head sits on track 1
10
- # PA7 BYTE READY, latched low from a whole byte until the CPU next
11
- # reads or writes VIA 2
12
- #
13
- # The DOS steps the head out until PA0 reads low with the stepper on
14
- # phase 0, and polls PA7 for each byte at 2 MHz, taking the byte from
15
- # VIA 2's port A or putting the next one there after each. PA1 (fast serial
16
- # direction), PA2 (side) and PA5 (1 or 2 MHz) are outputs, which
17
- # Drive1571 follows (SerialVIA).
18
- class SerialPort
19
- include Drive::SerialLines
20
-
21
- TRACK0 = 0x01
22
- BYTE_READY = 0x80
23
-
24
- def initialize(mechanism, device: 8, bus: IECBus.new)
25
- @mechanism = mechanism
26
- init_serial_lines(device, bus)
27
- end
28
-
29
- def read_a(_lines)
30
- value = 0xff
31
- value &= ~TRACK0 if @mechanism.half_track == Drive1541::Mechanism::MIN_HALF_TRACK
32
- value &= ~BYTE_READY if @mechanism.byte_latched?
33
- value
34
- end
35
- end
36
- end
37
- end
@@ -1,25 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Drive1571
5
- # VIA 1, the one facing the serial bus. Its port A also selects the
6
- # side, the clock rate and the fast serial direction, so the drive
7
- # hears port A after every write and reset (Drive1571#port_a_written).
8
- class SerialVIA < VIA
9
- def initialize(start:, peripheral:, drive:)
10
- @drive = drive
11
- super(start:, peripheral:)
12
- end
13
-
14
- def reset!
15
- super
16
- @drive.port_a_written(port_a_output)
17
- end
18
-
19
- def poke(addr, value)
20
- super
21
- @drive.port_a_written(port_a_output)
22
- end
23
- end
24
- end
25
- end
@@ -1,120 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Drive1571
5
- # The WD1770 floppy controller at $2000, which DOS 3.0 drives for MFM
6
- # disks. The 1571 here only ever holds GCR disks, so the controller
7
- # never finds an MFM sector: it runs each command for its time and ends
8
- # it as the WD177x data sheet does on a disk without one.
9
- #
10
- # $2000 status (read), command (write)
11
- # $2001 track
12
- # $2002 sector
13
- # $2003 data
14
- #
15
- # BUSY sets as a command is written. A restore, seek or step (type I)
16
- # moves the track register and ends a few milliseconds later, with
17
- # TRACK 0 reported at track 0. A sector read or write, a read address
18
- # or a read track ends with RECORD NOT FOUND after five turns of the
19
- # disk, and a write track after one, with nothing written. A force
20
- # interrupt ends the command at once. Time is the drive CPU's cycles.
21
- class WD1770
22
- BUSY = 0x01
23
- TRACK0 = 0x04
24
- NOT_FOUND = 0x10
25
- MOTOR_ON = 0x80
26
-
27
- # Cycles at 2 MHz, the 1571's clock in 1571 mode: a turn of the disk
28
- # at 300 rpm, and a step with the head settling.
29
- TURN = 400_000
30
- STEP = 12_000
31
-
32
- # The CPU whose cycles time the commands.
33
- attr_writer :cpu
34
-
35
- def initialize
36
- @registers = [0, 0, 0, 0]
37
- @status = 0
38
- @due = 0
39
- @result = 0
40
- @cpu = nil
41
- end
42
-
43
- # Register +offset+, 0 to 3: the status, settled to the command's end
44
- # once its time has run out.
45
- def peek(offset)
46
- return @registers[offset] unless offset.zero?
47
-
48
- finish if @status.anybits?(BUSY) && @cpu.cycles >= @due
49
- @status
50
- end
51
-
52
- def poke(offset, value)
53
- offset.zero? ? command(value) : @registers[offset] = value
54
- end
55
-
56
- def save_state(out)
57
- out.ints([*@registers, @status, @due, @result])
58
- end
59
-
60
- # A state from before the controller ran commands holds the four
61
- # registers alone.
62
- def load_state(input)
63
- values = input.ints
64
- @registers = values[0, 4]
65
- @status = values[4] || 0
66
- @due = values[5] || 0
67
- @result = values[6] || 0
68
- end
69
-
70
- private
71
-
72
- def command(value)
73
- return interrupt if (value & 0xf0) == 0xd0
74
-
75
- @registers[0] = value
76
- value < 0x80 ? step(value) : search(value)
77
- end
78
-
79
- # A restore ($0x), seek ($1x) or step ($2x to $7x), its track register
80
- # moved at once.
81
- def step(value)
82
- track = @registers[1]
83
- target = case value >> 4
84
- when 0 then 0
85
- when 1 then @registers[3]
86
- else track + step_direction(value)
87
- end
88
- @registers[1] = target.clamp(0, 255) if value < 0x20 || value.anybits?(0x10)
89
- start(STEP * [(target - track).abs, 1].max, @registers[1].zero? ? TRACK0 : 0)
90
- end
91
-
92
- # Step in ($4x) moves toward higher tracks, step out ($6x) toward
93
- # track 0, and step ($2x) the way the last one went.
94
- def step_direction(value)
95
- @direction = 1 if (value >> 5) == 2
96
- @direction = -1 if (value >> 5) == 3
97
- @direction || 1
98
- end
99
-
100
- # A sector or track command that finds no MFM sector.
101
- def search(value)
102
- value >= 0xf0 ? start(TURN, 0) : start(TURN * 5, NOT_FOUND)
103
- end
104
-
105
- def start(cycles, result)
106
- @status = BUSY | MOTOR_ON
107
- @due = @cpu.cycles + cycles
108
- @result = result
109
- end
110
-
111
- def finish
112
- @status = @result
113
- end
114
-
115
- def interrupt
116
- @status &= ~BUSY & 0xff
117
- end
118
- end
119
- end
120
- end
@@ -1,175 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "badline/drive1571/cpu"
4
- require "badline/drive1571/wd1770"
5
- require "badline/drive1571/serial_port"
6
- require "badline/drive1571/serial_via"
7
- require "badline/drive1571/bus"
8
-
9
- module Badline
10
- # The 1571 disk drive, the C128D's built-in one: the 1541's 6502, two
11
- # VIAs and GCR mechanism, with a second head, a 6526 CIA for fast
12
- # serial, a WD1770 for MFM disks and DOS 3.0 in 32 KB of ROM. Drive::Core
13
- # clocks it against the host and sleeps through the DOS's idle loop.
14
- #
15
- # VIA 1's port A picks the clock, 1 or 2 MHz on PA5, and the head on
16
- # PA2, and reads the track 0 sensor and BYTE READY (SerialPort). The
17
- # DOS resets at 2 MHz and drops to 1 MHz as a 1541 would run, which is
18
- # how it stays until a C128 asks for fast serial. The disk turns at the
19
- # same speed either way (Drive1541::Mechanism#clock_hz=).
20
- #
21
- # The CIA sits at $4000, on the IRQ line with both VIAs. Only its serial
22
- # port is wired, for fast serial through buffers PA1 turns round
23
- # (Drive::FastSerial). The drive sleeps only while the CIA is quiet
24
- # (CIA#quiet?).
25
- class Drive1571
26
- include Drive::Core
27
- include Drive::VIAs
28
- include Drive::FastSerial
29
-
30
- CLOCK_HZ = 1_000_000
31
- FAST_CLOCK_HZ = 2_000_000
32
-
33
- # Where the DOS 3.0 idle loop starts over, as DOS 2.6's does.
34
- IDLE_LOOP = 0xebff
35
-
36
- # VIA 1's port A outputs.
37
- FAST_SERIAL_OUT = 0x02
38
- SIDE = 0x04
39
- FAST = 0x20
40
-
41
- def cia
42
- settle!
43
- @cia
44
- end
45
-
46
- def fdc
47
- settle!
48
- @fdc
49
- end
50
-
51
- def model_name = "1571"
52
-
53
- # +rom+ covers $8000-$FFFF, and defaults to the DOS image in the ROM
54
- # path. +device+ is the number the jumpers on VIA 1's PB5 and PB6 set,
55
- # 8 to 11.
56
- def initialize(rom: nil, host_clock_hz: CLOCK_HZ, device: 8, debug: false)
57
- @device = device
58
- @clock_hz = CLOCK_HZ
59
- init_fast_serial
60
- @mechanism = Drive1541::Mechanism.new(slip: 2)
61
- @serial_port = SerialPort.new(@mechanism, device:)
62
- @via1 = SerialVIA.new(start: 0x1800, peripheral: @serial_port, drive: self)
63
- @via2 = Drive1541::DiskVIA.new(start: 0x1c00, mechanism: @mechanism)
64
- @cia = CIA.new(start: 0x4000)
65
- @fdc = WD1770.new
66
- @bus = Bus.new(rom: rom || ROM.load("dos1571.rom", 0x8000), via1: @via1, via2: @via2, cia: @cia, fdc: @fdc)
67
- @cpu = CPU.new(@bus, debug:)
68
- @fdc.cpu = @cpu
69
- @idle_loop = IDLE_LOOP
70
- @host_clock_hz = host_clock_hz
71
- @phase = 0
72
- @cycles = 0
73
- @serial_bus = nil
74
- init_idle(debug)
75
- # CA1 powers up at the level of a released ATN, without an edge.
76
- @via1.ca1 = false
77
- @via1.reset!
78
- connect(IECBus.new)
79
- end
80
-
81
- # The serial bus's RESET line reaches the CPU, both VIAs and the CIA.
82
- # RAM keeps its contents.
83
- def reset!
84
- settle!
85
- @via1.reset!
86
- @via2.reset!
87
- @cia.reset!
88
- @cpu.reset!
89
- end
90
-
91
- # VIA 1 drives port A to +lines+: the side, the clock rate and the fast
92
- # serial direction follow it.
93
- def port_a_written(lines)
94
- @mechanism.side = lines.anybits?(SIDE) ? 1 : 0
95
- fast_serial_out = lines.anybits?(FAST_SERIAL_OUT)
96
- turn_fast_serial(fast_serial_out) if fast_serial_out != @fast_serial_out
97
- clock_hz = lines.anybits?(FAST) ? FAST_CLOCK_HZ : CLOCK_HZ
98
- return if clock_hz == @clock_hz
99
-
100
- @clock_hz = clock_hz
101
- @mechanism.clock_hz = clock_hz
102
- end
103
-
104
- # Whether the drive runs at 2 MHz.
105
- def fast? = @clock_hz == FAST_CLOCK_HZ
106
-
107
- # VIA 1's port B, with the fast serial pins pulling DATA and SRQ
108
- # (IECBus::DRIVE_FAST_DATA and DRIVE_FAST_SRQ) above it.
109
- def serial_output = @via1.port_b_output | @fast_output
110
-
111
- # The drive's whole state, as the 1541's (Drive1541#save_state), with
112
- # the CIA and the WD1770's registers. The clock rate, the side and the
113
- # fast serial direction follow from VIA 1's port A.
114
- def save_state(out)
115
- settle!
116
- out.marker("DRIVE1571")
117
- out.int(@phase).int(@cycles).boolean(@mechanism.so_pending)
118
- @serial_port.save_state(out)
119
- @via1.save_state(out)
120
- @via2.save_state(out)
121
- @cia.save_state(out)
122
- @fdc.save_state(out)
123
- @bus.save_state(out)
124
- @cpu.save_state(out)
125
- @mechanism.save_state(out)
126
- end
127
-
128
- def load_state(input)
129
- settle!
130
- input.marker("DRIVE1571")
131
- @phase = input.int
132
- @cycles = input.int
133
- @mechanism.so_pending = input.boolean?
134
- @serial_port.load_state(input)
135
- @via1.load_state(input)
136
- @via2.load_state(input)
137
- @cia.load_state(input)
138
- @fdc.load_state(input)
139
- @bus.load_state(input)
140
- @cpu.load_state(input)
141
- @mechanism.load_state(input)
142
- @fast_serial_out = @via1.port_a_output.anybits?(FAST_SERIAL_OUT)
143
- port_a_written(@via1.port_a_output)
144
- push_fast_output(@fast_serial_out ? fast_pins : 0)
145
- forget_orbits
146
- end
147
-
148
- private
149
-
150
- # One drive cycle, as the 1541's (Drive1541#step), with the CIA
151
- # clocked beside the VIAs and pulling IRQ with them.
152
- def step
153
- so = @mechanism.take_so
154
- @mechanism.cycle!
155
- @via1.ca1 = @serial_port.atn_low?
156
- @via1.cycle!
157
- @via2.cycle!
158
- @cia.cycle!
159
- drive_fast_serial if @fast_serial_out
160
- @cpu.irq = @via1.irq? || @via2.irq? || @cia.interrupted?
161
- @cpu.so! if so
162
- @cpu.cycle!
163
- @cycles += 1
164
- end
165
-
166
- # The VIAs' quiet cycles while the CIA is quiet, and none otherwise.
167
- def quiet_cycles
168
- @cia.quiet? ? [@via1.quiet_cycles, @via2.quiet_cycles].min : 0
169
- end
170
-
171
- def fast_forward_more(cycles)
172
- @cia.fast_forward(cycles)
173
- end
174
- end
175
- end