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,100 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Drive1581
5
- # One side of a cylinder as the WD1772 finds it: its sectors, each an
6
- # ID field and a data field at a place round the turn, counted in
7
- # bytes from the index pulse. The disk turns at 300 rpm and the bits
8
- # pass at 250 kbit/s, so a turn is LENGTH bytes of 32 µs. The bytes
9
- # between the fields, the gaps and the sync marks, are not kept: a
10
- # read track lays them out again (raw).
11
- #
12
- # A standard track is the one the 1581 DOS formats (its format routine,
13
- # and the 1581 Service Manual's per-sector organization): 32 bytes of
14
- # $4E after the index, then ten 512-byte sectors numbered from 1, each
15
- #
16
- # 12 x $00, 3 x $A1, $FE, track, side, sector, size code, CRC,
17
- # 22 x $4E, 12 x $00, 3 x $A1, $FB, 512 data bytes, CRC,
18
- # 35 x $4E
19
- #
20
- # and $4E to the index. A write track lays down whatever the CPU sends,
21
- # and parse finds its fields again.
22
- class Track
23
- LENGTH = 6250
24
- GAP = 0x4e
25
- SYNC = 0xa1
26
- ID_MARK = 0xfe
27
- DATA_MARK = 0xfb
28
- DELETED_MARK = 0xf8
29
-
30
- SECTORS = 10
31
- SECTOR_SIZE = 512
32
- SIZE_CODE = 2
33
-
34
- # Where the first sector's ID mark lies, and how far apart the
35
- # sectors are.
36
- FIRST_ID = 32 + 15
37
- SECTOR_SPACING = 574 + 35
38
-
39
- # From an ID mark to its data mark.
40
- DATA_OFFSET = 44
41
-
42
- # How far after an ID field's CRC a data mark still belongs to it
43
- # (WD177x data sheet).
44
- DATA_MARK_WINDOW = 43
45
-
46
- # An ID or data field: its mark's place, its bytes, whether its CRC
47
- # reads back, and for a data field whether its mark is the deleted
48
- # one.
49
- Field = Struct.new(:mark, :bytes, :good, :deleted)
50
-
51
- # A sector: its ID field and its data field, or nil where none
52
- # follows the ID.
53
- Sector = Struct.new(:id, :data)
54
-
55
- # The CRC-CCITT the WD1772 writes after each field, over the field
56
- # from its first $A1: x^16 + x^12 + x^5 + 1 from $FFFF.
57
- def self.crc(bytes, crc = 0xffff)
58
- bytes.each do |byte|
59
- crc ^= byte << 8
60
- 8.times { crc = crc.anybits?(0x8000) ? ((crc << 1) ^ 0x1021) & 0xffff : (crc << 1) & 0xffff }
61
- end
62
- crc
63
- end
64
-
65
- # A field's CRC as the two bytes written after it: the mark and
66
- # +bytes+, behind three $A1s.
67
- def self.field_crc(mark, bytes)
68
- crc = crc([SYNC, SYNC, SYNC, mark] + bytes)
69
- [crc >> 8, crc & 0xff]
70
- end
71
-
72
- # A standard track for +cylinder+ and +side+, each sector's data the
73
- # block yields for its number, 1 to 10.
74
- def self.standard(cylinder, side)
75
- sectors = Array.new(SECTORS) do |index|
76
- mark = FIRST_ID + (index * SECTOR_SPACING)
77
- id = Field.new(mark, [cylinder, side, index + 1, SIZE_CODE], true, false)
78
- Sector.new(id, Field.new(mark + DATA_OFFSET, yield(index + 1), true, false))
79
- end
80
- new(sectors)
81
- end
82
-
83
- attr_reader :sectors
84
-
85
- def initialize(sectors)
86
- @sectors = sectors
87
- end
88
-
89
- # The first sector whose ID mark lies at or after +position+, round
90
- # from the index if none does, or nil on a track without IDs.
91
- def next_id(position)
92
- @sectors.find { |sector| sector.id.mark >= position } || @sectors.first
93
- end
94
-
95
- # The sector with the ID field +id+, track, side, sector and size
96
- # code, or nil.
97
- def sector(id) = @sectors.find { |sector| sector.id.bytes == id }
98
- end
99
- end
100
- end
@@ -1,75 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Drive1581
5
- class Track
6
- # A Track as the bytes going round under the head, for the WD1772's
7
- # read track: its fields with their gaps and sync marks.
8
- module Bytes
9
- # The track's LENGTH bytes from the index: $4E gaps, and before each
10
- # field 12 x $00 and three $A1 sync marks, its mark, its bytes and
11
- # its CRC, spoiled where the field's CRC doesn't read back.
12
- def raw
13
- bytes = Array.new(LENGTH, GAP)
14
- @sectors.each do |sector|
15
- lay(bytes, sector.id, ID_MARK)
16
- data = sector.data
17
- lay(bytes, data, data.deleted ? DELETED_MARK : DATA_MARK) if data
18
- end
19
- bytes
20
- end
21
-
22
- private
23
-
24
- def lay(bytes, field, mark)
25
- start = field.mark - 15
26
- crc = Track.field_crc(mark, field.bytes)
27
- crc[1] ^= 0xff unless field.good
28
- [*Array.new(12, 0), SYNC, SYNC, SYNC, mark, *field.bytes, *crc].each_with_index do |byte, i|
29
- bytes[start + i] = byte if start + i < LENGTH
30
- end
31
- end
32
- end
33
-
34
- # Finding the fields in the bytes a write track laid down.
35
- module Parse
36
- # Every sector in +bytes+, a turn as a write track laid it down,
37
- # where +syncs+ marks the $A1s written as sync marks: an ID mark
38
- # behind three of them, its four bytes and CRC, and the data field
39
- # that follows it within DATA_MARK_WINDOW bytes, its length from
40
- # the ID's size code.
41
- def parse(bytes, syncs)
42
- sectors = []
43
- position = 0
44
- while (mark = find_mark(bytes, syncs, position...bytes.length, ID_MARK..ID_MARK))
45
- id = read_field(bytes, mark, 4)
46
- position = mark + 7
47
- data_mark = find_mark(bytes, syncs, position...(position + DATA_MARK_WINDOW), DELETED_MARK..DATA_MARK)
48
- sectors << Sector.new(id, data_mark && read_field(bytes, data_mark, 128 << (id.bytes[3] & 3)))
49
- end
50
- new(sectors)
51
- end
52
-
53
- private
54
-
55
- # The first place in +range+ that holds one of +marks+ behind three
56
- # sync marks.
57
- def find_mark(bytes, syncs, range, marks)
58
- ([range.first, 3].max...[range.end, bytes.length].min).find do |at|
59
- marks.cover?(bytes[at]) && syncs[at - 1] && syncs[at - 2] && syncs[at - 3]
60
- end
61
- end
62
-
63
- def read_field(bytes, mark, length)
64
- field = bytes[mark + 1, length] || []
65
- field += Array.new(length - field.length, 0)
66
- crc = bytes[mark + 1 + length, 2] || []
67
- Field.new(mark, field, crc == Track.field_crc(bytes[mark], field), bytes[mark] < 0xfa)
68
- end
69
- end
70
-
71
- include Bytes
72
- extend Parse
73
- end
74
- end
75
- end
@@ -1,89 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Drive1581
5
- class WD1772
6
- # The four registers as the CPU reaches them, and a command written
7
- # to the command register.
8
- module Registers
9
- # Register +offset+, 0 to 3.
10
- def peek(offset)
11
- case offset
12
- when 0 then status
13
- when 1 then @track
14
- when 2 then @sector
15
- else read_data
16
- end
17
- end
18
-
19
- def poke(offset, value)
20
- case offset
21
- when 0 then write_command(value)
22
- when 1 then @track = value unless busy?
23
- when 2 then @sector = value unless busy?
24
- else write_data(value)
25
- end
26
- end
27
-
28
- # The status register, which clears INTRQ: after a type I command
29
- # bits 1, 2, 5 and 6 follow the index sensor, the track 0 sensor, the
30
- # spin-up and the write-protect line as they are now.
31
- def status
32
- @intrq = false
33
- value = @status | (@motor_on ? MOTOR_ON : 0) | (busy? ? BUSY : 0)
34
- return value | (@drq ? DATA_REQUEST : 0) unless @type1
35
-
36
- value |= PROTECTED if @mechanism.write_protected?
37
- value |= TRACK0 if @mechanism.track0?
38
- value | (@mechanism.index?(@now) ? INDEX : 0)
39
- end
40
-
41
- private
42
-
43
- def read_data
44
- @drq = false
45
- @data
46
- end
47
-
48
- def write_data(value)
49
- @drq = false
50
- @data = value
51
- end
52
-
53
- # A command while busy goes nowhere, but for a force interrupt.
54
- def write_command(value)
55
- @intrq = false
56
- return force_interrupt(value) if value & 0xf0 == 0xd0
57
- return if busy?
58
-
59
- @command = value
60
- @phase = STARTING
61
- @due = @now + START
62
- end
63
-
64
- def start_command
65
- if @command < 0x80 then start_type1
66
- elsif @command < 0xc0 then start_type2
67
- elsif @command & 0xf0 == 0xc0 then start_read_address
68
- else start_type3
69
- end
70
- end
71
-
72
- # Stops a command where it is, leaving its status but for BUSY, or
73
- # with none running switches the status to type I. I3 interrupts at
74
- # once and I2 at the next index pulse.
75
- def force_interrupt(value)
76
- @type1 = true unless busy?
77
- @drq = false
78
- idle
79
- @intrq = true if value.anybits?(0x08)
80
- return unless value.anybits?(0x04)
81
-
82
- @phase = INDEX_INTERRUPT
83
- @count = 1
84
- count_index
85
- end
86
- end
87
- end
88
- end
89
- end
@@ -1,73 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Drive1581
5
- class WD1772
6
- # Write sector, once Sectors has found the ID: it asks for the first
7
- # byte 2 bytes after the ID's CRC and gives up at 22 with LOST_DATA,
8
- # then writes the data field where a format puts it, behind 12 x $00
9
- # and three $A1s, its mark deleted with a, a byte of 0 for each one
10
- # the CPU missed, and the CRC and a $FF after the last.
11
- module SectorWrites
12
- WRITE_REQUEST = 2
13
- WRITE_DEADLINE = 22
14
-
15
- private
16
-
17
- def write_sector(sector)
18
- @write_id = sector.id.mark
19
- @size = 128 << (sector.id.bytes[3] & 0x03)
20
- @gate_open = false
21
- @phase = WRITE_GATE
22
- @due = byte_end(@write_id + 6 + WRITE_REQUEST)
23
- end
24
-
25
- # Two bytes after the ID's CRC, DRQ asks for the first byte, and
26
- # twenty bytes on it has to be there.
27
- def write_gate
28
- unless @gate_open
29
- @gate_open = true
30
- @drq = true
31
- return @due += (WRITE_DEADLINE - WRITE_REQUEST) * BYTE
32
- end
33
- return lost if @drq
34
-
35
- @bytes = []
36
- @phase = WRITE_DATA
37
- @due = byte_end(@write_id + Track::DATA_OFFSET)
38
- end
39
-
40
- # The next byte goes under the head from the data register, a 0
41
- # where DRQ went unanswered, and DRQ asks for the one after it.
42
- # After the last come the CRC and a $FF.
43
- def byte_written
44
- return sector_written if @bytes.length == @size
45
-
46
- @status |= LOST_DATA if @drq && !@bytes.empty?
47
- @bytes << (@drq && !@bytes.empty? ? 0 : @data)
48
- @drq = @bytes.length < @size
49
- @due += @bytes.length == @size ? 3 * BYTE : BYTE
50
- end
51
-
52
- def sector_written
53
- sector = found
54
- if sector
55
- sector.data = Track::Field.new(@write_id + Track::DATA_OFFSET, @bytes, true,
56
- @command.anybits?(DELETED_MARK))
57
- @mechanism.write(@mechanism.track)
58
- end
59
- return finish if @command.nobits?(MULTIPLE)
60
-
61
- @sector = (@sector + 1) & 0xff
62
- begin_search
63
- end
64
-
65
- def lost
66
- @status |= LOST_DATA
67
- @drq = false
68
- finish
69
- end
70
- end
71
- end
72
- end
73
- end
@@ -1,150 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Drive1581
5
- class WD1772
6
- # The type II commands and read address, which find an ID field on
7
- # the track under the head:
8
- #
9
- # 100mhE00 read sector the data field after the ID that carries
10
- # the track and sector registers
11
- # 101mhEPa write sector a data field after that ID, deleted with a
12
- # 11000hE00 read address the next ID field's six bytes, the track
13
- # going into the sector register
14
- #
15
- # The search reads each ID field as it passes. One that matches but
16
- # whose CRC doesn't read back sets CRC_ERROR and the search goes on;
17
- # after five index pulses it gives up with NOT_FOUND. Each byte of a
18
- # field passes in BYTE cycles and sets DRQ as it lands in the data
19
- # register, and LOST_DATA where the last one was still unread. With m
20
- # the command goes on to the next sector until one isn't found. E
21
- # lets the head settle first. SectorWrites writes the data field.
22
- module Sectors
23
- private
24
-
25
- def start_type2
26
- start_search(@command < 0xa0 ? READ : WRITE)
27
- end
28
-
29
- def start_read_address
30
- start_search(ADDRESS)
31
- end
32
-
33
- def start_search(mode)
34
- @type1 = false
35
- @status = 0
36
- @drq = false
37
- @mode = mode
38
- resume_type2 unless spinning_up?(SEARCH)
39
- end
40
-
41
- def resume_type2
42
- if @mode == WRITE && @mechanism.write_protected?
43
- @status |= PROTECTED
44
- return finish
45
- end
46
- return begin_search if @command.nobits?(SETTLE_DELAY)
47
-
48
- @phase = SETTLE_SEARCH
49
- @due = @now + SETTLE
50
- end
51
-
52
- # Searches for five index pulses from now.
53
- def begin_search
54
- index = next_index
55
- @deadline = index == NEVER ? NEVER : index + (4 * Mechanism::REVOLUTION)
56
- search
57
- end
58
-
59
- # Waits for the next ID field to pass under the head.
60
- def search
61
- @phase = SEARCH
62
- track = @mechanism.track
63
- sector = track&.next_id((@mechanism.angle(@now) / BYTE) + 1)
64
- @found = sector ? track.sectors.index(sector) : -1
65
- @id_at = sector ? byte_end(sector.id.mark) : NEVER
66
- @due = [@id_at, @deadline].min
67
- end
68
-
69
- def found = @mechanism.track&.sectors&.[](@found)
70
-
71
- def id_passed
72
- return not_found unless @now == @id_at
73
-
74
- sector = found
75
- return search if sector.nil?
76
-
77
- id = sector.id
78
- return id_read(id) if @mode == ADDRESS
79
- return search unless matches?(id.bytes)
80
- return crc_mismatch unless id.good
81
-
82
- @status &= ~CRC_ERROR
83
- @mode == VERIFY_TRACK ? finish : sector_found(sector)
84
- end
85
-
86
- def matches?(id)
87
- id[0] == @track && (@mode == VERIFY_TRACK || id[2] == @sector)
88
- end
89
-
90
- def crc_mismatch
91
- @status |= CRC_ERROR
92
- search
93
- end
94
-
95
- def not_found
96
- @status |= NOT_FOUND
97
- finish
98
- end
99
-
100
- def sector_found(sector)
101
- return write_sector(sector) if @mode == WRITE
102
-
103
- data = sector.data
104
- return search if data.nil? || data.mark > sector.id.mark + 7 + Track::DATA_MARK_WINDOW
105
-
106
- @status |= DELETED if data.deleted
107
- transfer(data.bytes, data.mark, READ_DATA)
108
- @crc_good = data.good
109
- end
110
-
111
- # Read address: the ID's bytes and its CRC.
112
- def id_read(id)
113
- @status |= CRC_ERROR unless id.good
114
- transfer(id.bytes + Track.field_crc(Track::ID_MARK, id.bytes), id.mark, READ_ADDRESS)
115
- end
116
-
117
- def transfer(bytes, mark, phase)
118
- @bytes = bytes
119
- @index = 0
120
- @phase = phase
121
- @due = byte_end(mark + 1)
122
- end
123
-
124
- # A byte of the field lands in the data register. After the last,
125
- # the CRC passes.
126
- def byte_read
127
- return field_read if @index == @bytes.length
128
-
129
- @status |= LOST_DATA if @drq
130
- @data = @bytes[@index]
131
- @drq = true
132
- @index += 1
133
- @due += @index == @bytes.length && @phase == READ_DATA ? 2 * BYTE : BYTE
134
- end
135
-
136
- def field_read
137
- if @phase == READ_ADDRESS
138
- @sector = @bytes[0]
139
- elsif !@crc_good
140
- @status |= CRC_ERROR
141
- elsif @command.anybits?(MULTIPLE)
142
- @sector = (@sector + 1) & 0xff
143
- return begin_search
144
- end
145
- finish
146
- end
147
- end
148
- end
149
- end
150
- end
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Drive1581
5
- class WD1772
6
- # Saving and restoring the WD1772 for a snapshot: its registers and
7
- # lines, and the command running, down to the byte it is at.
8
- module State
9
- def save_state(out)
10
- [@now, @due, @phase, @command, @track, @sector, @data, @status, @steps, @count, @after_spin_up, @mode,
11
- @deadline, @id_at, @found, @index, @crc, @write_id, @size].each { |value| out.int(value) }
12
- [@type1, @drq, @intrq, @motor_on, @inward, @crc_good, @gate_open, @late,
13
- @settling].each { |flag| out.boolean(flag) }
14
- out.ints(@bytes).ints(@syncs.map { |sync| sync ? 1 : 0 })
15
- end
16
-
17
- def load_state(input)
18
- load_registers(input)
19
- load_command(input)
20
- load_flags(input)
21
- @bytes = input.ints
22
- @syncs = input.ints.map { |sync| sync == 1 }
23
- end
24
-
25
- private
26
-
27
- def load_registers(input)
28
- @now = input.int
29
- @due = input.int
30
- @phase = input.int
31
- @command = input.int
32
- @track = input.int
33
- @sector = input.int
34
- @data = input.int
35
- @status = input.int
36
- end
37
-
38
- def load_command(input)
39
- @steps = input.int
40
- @count = input.int
41
- @after_spin_up = input.int
42
- @mode = input.int
43
- @deadline = input.int
44
- @id_at = input.int
45
- @found = input.int
46
- @index = input.int
47
- @crc = input.int
48
- @write_id = input.int
49
- @size = input.int
50
- end
51
-
52
- def load_flags(input)
53
- @type1 = input.boolean?
54
- @drq = input.boolean?
55
- @intrq = input.boolean?
56
- @motor_on = input.boolean?
57
- @inward = input.boolean?
58
- @crc_good = input.boolean?
59
- @gate_open = input.boolean?
60
- @late = input.boolean?
61
- @settling = input.boolean?
62
- end
63
- end
64
- end
65
- end
66
- end
@@ -1,109 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Drive1581
5
- class WD1772
6
- # The type I commands, which move the head:
7
- #
8
- # 0000hVrr restore step out to track 0, the track register to 0
9
- # 0001hVrr seek step until the track register holds the data
10
- # register's track
11
- # 001uhVrr step one step the way the last one went
12
- # 010uhVrr step in one step towards the hub
13
- # 011uhVrr step out one step towards the rim
14
- #
15
- # Each step waits out the step rate rr picks (STEP_RATES), and u has
16
- # a step update the track register, as restore and seek always do.
17
- # With V the head settles and the command reads IDs until one carries
18
- # the track register's track, or sets NOT_FOUND after five turns.
19
- module Stepping
20
- private
21
-
22
- def start_type1
23
- @type1 = true
24
- @status = 0
25
- @drq = false
26
- @phase = STEPPED
27
- @steps = 0
28
- if @command < 0x10
29
- @track = 0xff
30
- @data = 0
31
- elsif @command >= 0x40
32
- @inward = @command < 0x60
33
- end
34
- step_done unless spinning_up?(STEPPED)
35
- end
36
-
37
- def spun_up
38
- @status |= SPUN_UP
39
- @phase = @after_spin_up
40
- case @after_spin_up
41
- when STEPPED then step_done
42
- when SEARCH then resume_type2
43
- else resume_track
44
- end
45
- end
46
-
47
- # The step rate has passed: the next step, or the end of the moves.
48
- def step_done
49
- return next_step if @steps.zero? || @command < 0x20
50
-
51
- moved
52
- end
53
-
54
- # Restore and seek step until the track register matches, restore
55
- # also stopping at track 0. The others step once.
56
- def next_step
57
- return single_step if @command >= 0x20
58
- return seek_restore if @command < 0x10 && restored?
59
-
60
- if @track == @data
61
- moved
62
- else
63
- @inward = @data > @track
64
- @track = (@track + (@inward ? 1 : -1)) & 0xff
65
- pulse
66
- end
67
- end
68
-
69
- def restored?
70
- return false unless @mechanism.track0? || @steps >= 255
71
-
72
- @status |= NOT_FOUND if !@mechanism.track0? && @command.anybits?(VERIFY)
73
- true
74
- end
75
-
76
- def seek_restore
77
- @track = 0 if @mechanism.track0?
78
- moved
79
- end
80
-
81
- def single_step
82
- @track = (@track + (@inward ? 1 : -1)) & 0xff if @command.anybits?(UPDATE)
83
- pulse
84
- end
85
-
86
- def pulse
87
- @steps += 1
88
- @mechanism.step(@inward)
89
- @phase = STEPPED
90
- @due = @now + STEP_RATES[@command & 0x03]
91
- end
92
-
93
- # The head is there: with V it settles, and the command ends
94
- # otherwise.
95
- def moved
96
- return finish unless @command.anybits?(VERIFY) && @status.nobits?(NOT_FOUND)
97
-
98
- @phase = SETTLED
99
- @due = @now + SETTLE
100
- end
101
-
102
- def verify_track
103
- @mode = VERIFY_TRACK
104
- begin_search
105
- end
106
- end
107
- end
108
- end
109
- end