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
@@ -0,0 +1,161 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Drives
5
+ # The serial bus between the C64 and its drives: ATN, CLK and DATA, each
6
+ # an open-collector line with a pull-up. A line is low while any device
7
+ # pulls it (wired-AND), and high otherwise. Every read works the levels
8
+ # out from what each side drives now.
9
+ #
10
+ # The C64 drives the lines from CIA 2's port A through 7406 inverters, so
11
+ # an output bit of 1 pulls its line low: PA3 ATN, PA4 CLK and PA5 DATA.
12
+ # The machine pushes those bits into the bus (host_lines=), which holds
13
+ # them. PA6 and PA7 read CLK and DATA directly, 1 for a released line.
14
+ # The bus stands in as CIA 2's peripheral for those two inputs.
15
+ #
16
+ # A drive drives CLK and DATA from VIA 1's PB3 and PB1, the same way. It
17
+ # also pulls DATA while ATN IN differs from its ATN acknowledge on PB4
18
+ # (an XOR gate), which answers ATN in hardware before the DOS gets to it.
19
+ # SerialPort reads the lines back into VIA 1. A drive whose
20
+ # serial_output sets DRIVE_ATN_GATED pulls DATA that way only while
21
+ # ATN is low, as the 1581's NAND does.
22
+ #
23
+ # Fast serial adds SRQ, which the C64 leaves alone. A C128 and a 1571
24
+ # clock bytes over it from a CIA's CNT, with the bits on DATA from its
25
+ # SP, through buffers each side turns towards the bus to send. A pin low
26
+ # pulls its line low. Each side pushes the lines it pulls when they
27
+ # move: the host through host_fast_lines=, which tells the drives
28
+ # (fast_lines_moved), and a drive through drives_fast_moved!, which
29
+ # tells the host (on_fast_change).
30
+ class SerialBus
31
+ # CIA 2 port A
32
+ HOST_ATN_OUT = 0x08
33
+ HOST_CLK_OUT = 0x10
34
+ HOST_DATA_OUT = 0x20
35
+ HOST_CLK_IN = 0x40
36
+ HOST_DATA_IN = 0x80
37
+
38
+ # VIA 1 port B
39
+ DRIVE_DATA_OUT = 0x02
40
+ DRIVE_CLK_OUT = 0x08
41
+ DRIVE_ATNA = 0x10
42
+
43
+ # The lines pulled low, as ATN, CLK, DATA and SRQ bits
44
+ ATN = 0x01
45
+ CLK = 0x02
46
+ DATA = 0x04
47
+ SRQ = 0x08
48
+
49
+ # A drive's serial_output bits above VIA 1's port B: its fast serial
50
+ # pins pulling DATA and SRQ.
51
+ DRIVE_FAST_DATA = 0x100
52
+ DRIVE_FAST_SRQ = 0x200
53
+
54
+ # A drive's serial_output bit whose ATN acknowledge pulls DATA only
55
+ # while ATN is low.
56
+ DRIVE_ATN_GATED = 0x400
57
+
58
+ attr_reader :drives, :host_lines
59
+
60
+ # The lines the host's fast serial pins pull, as DATA and SRQ bits.
61
+ attr_reader :host_fast_lines
62
+
63
+ def initialize
64
+ @drives = []
65
+ @host_lines = 0
66
+ @host_fast_lines = 0
67
+ @drive_fast_lines = 0
68
+ @on_fast_change = nil
69
+ end
70
+
71
+ # The host's fast serial pins moved: +low+ is the lines they pull, as
72
+ # DATA and SRQ bits.
73
+ def host_fast_lines=(low)
74
+ return if low == @host_fast_lines
75
+
76
+ @host_fast_lines = low
77
+ @drives.each(&:fast_lines_moved)
78
+ end
79
+
80
+ # A drive's fast serial pins moved (serial_output's fast bits).
81
+ def drives_fast_moved!
82
+ low = 0
83
+ @drives.each do |drive|
84
+ output = drive.serial_output
85
+ low |= DATA if output.anybits?(DRIVE_FAST_DATA)
86
+ low |= SRQ if output.anybits?(DRIVE_FAST_SRQ)
87
+ end
88
+ return if low == @drive_fast_lines
89
+
90
+ @drive_fast_lines = low
91
+ @on_fast_change&.call
92
+ end
93
+
94
+ # Calls the block whenever the drives move their fast serial pins.
95
+ def on_fast_change(&block)
96
+ @on_fast_change = block
97
+ end
98
+
99
+ # The machine pushes the lines it pulls, as port A bits, whenever they
100
+ # may have moved: its output bits, with input bits floating high as the
101
+ # 7406 inputs see them. A bus with only drives on it keeps 0.
102
+ def host_lines=(lines)
103
+ @host_lines = lines
104
+ @drives.each(&:host_written!)
105
+ end
106
+
107
+ def attach(drive)
108
+ @drives << drive unless @drives.include?(drive)
109
+ end
110
+
111
+ def detach(drive)
112
+ @drives.delete(drive)
113
+ end
114
+
115
+ # One pass over everything on the bus, for a reader that wants more
116
+ # than one line, SRQ included. +host+ is the C64's port A lines as the
117
+ # reader sees them, which a drive takes a cycle late (see
118
+ # Drives::Engine::SerialLines).
119
+ def low_lines(host = @host_lines)
120
+ atn = host.anybits?(HOST_ATN_OUT)
121
+ low = @host_fast_lines | @drive_fast_lines
122
+ low |= ATN if atn
123
+ low |= CLK if host.anybits?(HOST_CLK_OUT)
124
+ low |= DATA if host.anybits?(HOST_DATA_OUT)
125
+ i = 0
126
+ while i < @drives.length
127
+ drive = @drives[i].serial_output
128
+ low |= CLK if drive.anybits?(DRIVE_CLK_OUT)
129
+ low |= DATA if drive.anybits?(DRIVE_DATA_OUT) || acknowledging?(drive, atn)
130
+ i += 1
131
+ end
132
+ low
133
+ end
134
+
135
+ def atn_low?(host = @host_lines) = host.anybits?(HOST_ATN_OUT)
136
+
137
+ # Whether a drive's ATN acknowledge pulls DATA, with its serial_output
138
+ # +drive+, while ATN is +atn+.
139
+ def acknowledging?(drive, atn)
140
+ atn != drive.anybits?(DRIVE_ATNA) && (atn || drive.nobits?(DRIVE_ATN_GATED))
141
+ end
142
+
143
+ def clk_low? = low_lines.anybits?(CLK)
144
+
145
+ def data_low? = low_lines.anybits?(DATA)
146
+
147
+ # CIA 2's port A pins as the bus leaves them: CLK IN and DATA IN low
148
+ # while their lines are.
149
+ def read_a(_port_a, _port_b)
150
+ low = low_lines
151
+ value = 0xff
152
+ value &= ~HOST_CLK_IN if low.anybits?(CLK)
153
+ value &= ~HOST_DATA_IN if low.anybits?(DATA)
154
+ value
155
+ end
156
+
157
+ # Port B goes to the user port, not the serial bus.
158
+ def read_b(_port_a, _port_b) = 0xff
159
+ end
160
+ end
161
+ end
@@ -33,9 +33,9 @@ module Badline
33
33
  def self.media_problem
34
34
  yield
35
35
  ""
36
- rescue Unsupported, Media::TrueDrive::Error, Media::DiskList::Error, Media::NotDisk, Datasette::Missing,
37
- SystemCallError, Storage::SIDFile::FormatError, Storage::T64::FormatError, Storage::TAP::FormatError,
38
- Storage::CRTFile::FormatError, Storage::G64Image::FormatError, Cartridge::UnsupportedTypeError,
36
+ rescue Machine::Unsupported, Media::TrueDrive::Error, Media::DiskList::Error, Media::NotDisk, Drives::Datasette::Missing,
37
+ SystemCallError, SIDTune::File::FormatError, Storage::T64::FormatError, Storage::TAP::FormatError,
38
+ Storage::CRTFile::FormatError, Storage::G64Image::FormatError, C64::Cartridge::UnsupportedTypeError,
39
39
  Snapshot::FormatError => e
40
40
  e.message
41
41
  end
@@ -53,11 +53,10 @@ module Badline
53
53
  start(options, media, options.writable?)
54
54
  end
55
55
 
56
- # A new machine built from the options, with `media`, if not nil,
57
- # attached and started as the command line does, its disk writable if
58
- # `writable`. The family and model give the machine, and a .sid tune
59
- # or --sid the SID. The VIC-20 raises Unsupported for a .sid
60
- # tune.
56
+ # A new machine built from the options (Machine.for_options), with
57
+ # `media`, if not nil, attached and started as the command line does,
58
+ # its disk writable if `writable`. The VIC-20 raises
59
+ # Machine::Unsupported for a .sid tune.
61
60
  def self.start(options, media, writable)
62
61
  computer = build(options, media)
63
62
  Media::TrueDrive.plug(computer) if options.true_drive?
@@ -68,60 +67,10 @@ module Badline
68
67
  computer
69
68
  end
70
69
 
70
+ # The machine the options name, built for `media`, which says the RAM
71
+ # expansion a VIC-20 gets for it.
71
72
  def self.build(options, media)
72
- case options.family
73
- when :vic20 then vic20(options, media)
74
- when :c128 then c128(options, media)
75
- else c64(options, media)
76
- end
77
- end
78
-
79
- def self.c64(options, media)
80
- sid_model = options.sid_model || Media.sid_model(media, otherwise: nil)
81
- Machine.build(:c64, model: options.model, sid_model:, reu: options.reu)
82
- end
83
-
84
- # A C128 in C128 mode. With --c64, or media only C64 mode runs, a .sid
85
- # tune or a program that loads at the C64's BASIC start, C= is held
86
- # through the reset, so the C128 KERNAL starts C64 mode.
87
- def self.c128(options, media)
88
- sid_model = options.sid_model || Media.sid_model(media, otherwise: nil)
89
- machine = C128.new(model: options.model, sid_model:, mode: :c128)
90
- machine.hold_commodore_key if options.c64_mode? || c64_media?(media)
91
- machine
92
- end
93
-
94
- def self.c64_media?(media)
95
- return false if media.nil? || !File.file?(media)
96
-
97
- extension = File.extname(media).downcase
98
- return true if extension == ".sid"
99
- return false unless %w[.prg .p00].include?(extension)
100
-
101
- [Media::BASIC_START, Media::BASIC_START - 1].include?(Storage::P00.load_address(media))
73
+ Machine.for_options(options, media) { |line| puts line }
102
74
  end
103
-
104
- # A VIC-20 with the RAM --ram names, or else the RAM `media` needs
105
- # (Media::Vic20Media.ram_for), which it says. Raises Unsupported for
106
- # media a VIC-20 doesn't take.
107
- def self.vic20(options, media)
108
- ram = options.ram
109
- unless media.nil?
110
- unsupported = Media::Vic20Media::UNSUPPORTED.include?(File.extname(media).downcase)
111
- raise Unsupported, "doesn't go in a VIC-20" if unsupported
112
-
113
- ram ||= vic20_ram(media)
114
- end
115
- Machine.build(:vic20, model: options.model, ram:)
116
- end
117
-
118
- def self.vic20_ram(media)
119
- ram = Media::Vic20Media.ram_for(media)
120
- puts "RAM expansion: #{ram}"
121
- ram
122
- end
123
-
124
- # Media the machine the options name doesn't take.
125
- class Unsupported < ArgumentError; end
126
75
  end
127
76
  end
@@ -17,7 +17,8 @@ module Badline
17
17
  attr_reader :renderer, :texture
18
18
 
19
19
  # Opens the window for `screen`, presenting in step with the display
20
- # when `vsync`.
20
+ # when `vsync`. Text input stays off, so a dead key such as ´ on a Mac
21
+ # arrives as a key press, as every other key does.
21
22
  def initialize(screen, vsync:)
22
23
  abort "SDL_Init: #{SDL.SDL_GetError}" unless SDL.SDL_Init(SDL::INIT_VIDEO | SDL::INIT_EVENTS).zero?
23
24
 
@@ -28,6 +29,7 @@ module Badline
28
29
  TITLE, SDL::WINDOWPOS_CENTERED, SDL::WINDOWPOS_CENTERED, @width * SCALE, @height * SCALE,
29
30
  SDL::WINDOW_RESIZABLE
30
31
  )
32
+ SDL.SDL_StopTextInput
31
33
  flags = SDL::RENDERER_ACCELERATED
32
34
  flags |= SDL::RENDERER_PRESENTVSYNC if vsync
33
35
  @renderer = SDL.SDL_CreateRenderer(@window, -1, flags)
@@ -31,7 +31,7 @@ module Badline
31
31
  cutoff = (history.register(frame, 0x15) & 0x07) | (history.register(frame, 0x16) << 3)
32
32
  resonance = history.register(frame, 0x17) >> 4
33
33
  mode_volume = history.register(frame, 0x18)
34
- hertz = SID::Filter::W0.fetch(model)[cutoff] / (2 * Math::PI * SID::Filter::SCALE)
34
+ hertz = Chips::SID::Filter::W0.fetch(model)[cutoff] / (2 * Math::PI * Chips::SID::Filter::SCALE)
35
35
  paint = @painter
36
36
  paint.text(LEFT, top, "FILTER", BRIGHT)
37
37
  x = LEFT + 64
@@ -106,7 +106,7 @@ module Badline
106
106
  # Keeps the subtune's STIL credits for the header and the whole entry
107
107
  # for the INFO view.
108
108
  def stil(fields, subtune, subtune_fields)
109
- @credits = Storage::STIL::Credit.list(subtune_fields.empty? ? fields : subtune_fields)
109
+ @credits = SIDTune::STIL::Credit.list(subtune_fields.empty? ? fields : subtune_fields)
110
110
  @stil = fields
111
111
  @stil_subtune = subtune
112
112
  @subtune_stil = subtune_fields
@@ -211,7 +211,7 @@ module Badline
211
211
 
212
212
  def draw
213
213
  @next_draw = now + FRAME
214
- @screen.draw(@state, @player, @history, @tune_file, Storage::STIL::Credit.at(@credits, @state.played))
214
+ @screen.draw(@state, @player, @history, @tune_file, SIDTune::STIL::Credit.at(@credits, @state.played))
215
215
  end
216
216
 
217
217
  def now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
@@ -31,6 +31,7 @@ module Badline
31
31
  SDL.SDL_SetHint("SDL_RENDER_SCALE_QUALITY", "0")
32
32
  @window = SDL.SDL_CreateWindow(TITLE, SDL::WINDOWPOS_CENTERED, SDL::WINDOWPOS_CENTERED,
33
33
  WIDTH * SCALE, height(view) * SCALE, SDL::WINDOW_RESIZABLE)
34
+ SDL.SDL_StopTextInput
34
35
  @renderer = SDL.SDL_CreateRenderer(@window, -1, SDL::RENDERER_ACCELERATED)
35
36
  SDL.SDL_RenderSetLogicalSize(@renderer, WIDTH, height(view))
36
37
  build
@@ -6,13 +6,13 @@ module Badline
6
6
  # C64's palette: one for each voice, and light blue on blue as on the
7
7
  # machine's screen.
8
8
  module PlayerTheme
9
- TEXT = VIC::PALETTE[14]
10
- BRIGHT = VIC::PALETTE[1]
11
- DIM = VIC::PALETTE[11]
12
- BOX = VIC::PALETTE[0]
13
- BACKGROUND = VIC::PALETTE[6]
14
- WARNING = VIC::PALETTE[10]
15
- VOICE_COLORS = [VIC::PALETTE[7], VIC::PALETTE[13], VIC::PALETTE[3]].freeze
9
+ TEXT = Chips::VIC::PALETTE[14]
10
+ BRIGHT = Chips::VIC::PALETTE[1]
11
+ DIM = Chips::VIC::PALETTE[11]
12
+ BOX = Chips::VIC::PALETTE[0]
13
+ BACKGROUND = Chips::VIC::PALETTE[6]
14
+ WARNING = Chips::VIC::PALETTE[10]
15
+ VOICE_COLORS = [Chips::VIC::PALETTE[7], Chips::VIC::PALETTE[13], Chips::VIC::PALETTE[3]].freeze
16
16
  end
17
17
  end
18
18
  end
@@ -39,15 +39,15 @@ module Badline
39
39
 
40
40
  # The Keyboard's key for a name such as space, return or a.
41
41
  def self.keyboard_key(name)
42
- key = Keyboard.new.matrix.flatten.find { |candidate| candidate.to_s == name }
43
- key.nil? ? Keyboard::COMBINATIONS.keys.find { |candidate| candidate.to_s == name } : key
42
+ key = Input::Keyboard.new.matrix.flatten.find { |candidate| candidate.to_s == name }
43
+ key.nil? ? Input::Keyboard::COMBINATIONS.keys.find { |candidate| candidate.to_s == name } : key
44
44
  end
45
45
 
46
46
  # The direction of joy1-NAME or joy2-NAME, such as up or fire.
47
47
  def self.joystick_direction(name)
48
48
  return nil unless name.start_with?("joy1-") || name.start_with?("joy2-")
49
49
 
50
- Joystick::DIRECTIONS.keys.find { |direction| direction.to_s == name[5, name.size - 5] }
50
+ Input::Joystick::DIRECTIONS.keys.find { |direction| direction.to_s == name[5, name.size - 5] }
51
51
  end
52
52
 
53
53
  # The screenshot's file name, with the frame's number in place of %d,
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Input
5
+ # CIA 1's control ports and the keyboard matrix that spans them.
6
+ #
7
+ # Port A carries the matrix rows together with joystick 2, port B the matrix
8
+ # columns together with joystick 1. Every switch is active low, so the
9
+ # joysticks are wired-AND onto the lines *before* the matrix settles: a stick
10
+ # held in a direction selects rows and columns of its own, which is where
11
+ # hardware's phantom keypresses come from. Paddles and a 1351 mouse have
12
+ # buttons on those same lines.
13
+ #
14
+ # The ports also carry SID's POTX/POTY lines, which reach them through analog
15
+ # switches closed by CIA 1 PA6 (port 1) and PA7 (port 2). Close both and the
16
+ # pots sit in parallel, so SID charges through the lower of the two
17
+ # resistances; close neither and the lines float high. Reading a pot asks the
18
+ # CIA for the current select lines, since a program sets them and then goes
19
+ # straight to SID without touching the ports again.
20
+ #
21
+ # A matrix may have rows beyond port A's eight. Their select lines come from
22
+ # outside the CIA and are pushed into +extra_rows+, bit 0 for the ninth row
23
+ # upwards, active low like port A; idle, every line is high and none of
24
+ # those rows is selected. They settle with port A's lines as rows 8 and up,
25
+ # so their keys reach port B, but port A reads only its own eight.
26
+ class ControlPorts
27
+ PORT1_POTS = 0x40
28
+ PORT2_POTS = 0x80
29
+ FIRE = 0x10
30
+
31
+ attr_reader :keyboard, :joystick1, :joystick2
32
+ attr_accessor :device1, :device2, :port_a_source, :extra_rows
33
+
34
+ def initialize(keyboard:, joystick1:, joystick2:)
35
+ @keyboard = keyboard
36
+ @joystick1 = joystick1
37
+ @joystick2 = joystick2
38
+ @device1 = nil
39
+ @device2 = nil
40
+ @port_a_source = nil
41
+ @extra_rows = 0xff
42
+ end
43
+
44
+ def read_a(port_a, port_b) = scan(port_a, port_b).first & 0xff
45
+
46
+ def read_b(port_a, port_b) = scan(port_a, port_b).last
47
+
48
+ # Control port 1 pin 6 is both the port B fire line and the VIC's light
49
+ # pen input, so joystick 1's button and a 1351's left button latch
50
+ # $D013/$D014. The CIA samples this every cycle, so it skips the matrix and
51
+ # asks only what the port's own devices drive.
52
+ def port_b4_high? = port_bits(@joystick1, @device1).anybits?(FIRE)
53
+
54
+ def pot_x = selected_devices.map(&:pot_x).min || 0xff
55
+
56
+ def pot_y = selected_devices.map(&:pot_y).min || 0xff
57
+
58
+ private
59
+
60
+ def selected_devices
61
+ lines = @port_a_source&.port_a_lines || 0x00
62
+ devices = []
63
+ devices << @device1 if @device1 && lines.anybits?(PORT1_POTS)
64
+ devices << @device2 if @device2 && lines.anybits?(PORT2_POTS)
65
+ devices
66
+ end
67
+
68
+ def scan(port_a, port_b)
69
+ keyboard.scan((port_a & port_bits(@joystick2, @device2)) | (@extra_rows << 8),
70
+ port_b & port_bits(@joystick1, @device1))
71
+ end
72
+
73
+ def port_bits(joystick, device)
74
+ device ? joystick.port_bits & device.port_bits : joystick.port_bits
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Input
5
+ class Joystick
6
+ DIRECTIONS = { up: 0, down: 1, left: 2, right: 3, fire: 4 }.freeze
7
+
8
+ # Kept up to date as switches move, since the CIA samples the fire line
9
+ # every cycle to drive the light pen input.
10
+ attr_reader :port_bits
11
+
12
+ def initialize
13
+ @port_bits = 0xff
14
+ end
15
+
16
+ def press(direction)
17
+ bit = DIRECTIONS[direction]
18
+ @port_bits &= ~(1 << bit) if bit
19
+ end
20
+
21
+ def release(direction)
22
+ bit = DIRECTIONS[direction]
23
+ @port_bits |= 1 << bit if bit
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Input
5
+ # The key matrix spanning CIA 1's two ports: rows on port A, columns on
6
+ # port B. Row lines beyond the eighth sit above port A's bits in +rows+.
7
+ #
8
+ # A pressed key shorts its row line to its column line, so whichever side is
9
+ # pulled low drags the other down with it. Scanning works in either
10
+ # direction, and chains of keys sharing a line propagate the pulldown -- the
11
+ # ghost keys real hardware reports.
12
+ class Keyboard
13
+ include IntegerHelper
14
+
15
+ # Keys the C64 types as a combination: cursor up and cursor left are the
16
+ # shifted cursor keys. Pressing one holds both of its matrix keys, while
17
+ # a shift key held on its own stays down when it is released.
18
+ COMBINATIONS = {
19
+ cursor_up: %i[lshift cursor_v],
20
+ cursor_left: %i[lshift cursor_h]
21
+ }.freeze
22
+
23
+ # The C64's wiring: one row of keys per port A line, in port B column
24
+ # order.
25
+ C64_MATRIX = [
26
+ %i[delete return cursor_h f7 f1 f3 f5 cursor_v],
27
+ %i[3 w a 4 z s e lshift],
28
+ %i[5 r d 6 c f t x],
29
+ %i[7 y g 8 b h u v],
30
+ %i[9 i j 0 m k o n],
31
+ %i[+ p l - . : @ ,],
32
+ %i[£ * ; clr_home rshift = up /],
33
+ %i[1 left control 2 space cbm q run_stop]
34
+ ].freeze
35
+
36
+ attr_reader :keys, :matrix
37
+
38
+ def initialize(matrix: C64_MATRIX)
39
+ @keys = []
40
+ @row_masks = nil
41
+ @matrix = matrix
42
+ @connected = true
43
+ end
44
+
45
+ # Whether the machine has a keyboard. The C64GS has none: no key goes
46
+ # down on it.
47
+ def connected? = @connected
48
+
49
+ def connected=(connected)
50
+ @connected = connected
51
+ @keys.clear unless connected
52
+ @row_masks = nil
53
+ end
54
+
55
+ def press(key)
56
+ return unless @connected && valid_key?(key)
57
+
58
+ @keys << key
59
+ @row_masks = nil
60
+ end
61
+
62
+ def release(key)
63
+ @keys.reject! { |k| k == key }
64
+ @row_masks = nil
65
+ end
66
+
67
+ # Settles the row (port A) and column (port B) lines against each other
68
+ # until no key contact pulls a line low any more, and returns both.
69
+ def scan(rows, cols)
70
+ return [rows, cols] if keys.empty?
71
+
72
+ loop do
73
+ settled_rows = rows
74
+ settled_cols = cols
75
+
76
+ row_masks.each_with_index do |mask, row|
77
+ bit = 1 << row
78
+ next if mask.zero? || (rows.allbits?(bit) && cols.allbits?(mask))
79
+
80
+ rows &= ~bit
81
+ cols &= ~mask
82
+ end
83
+
84
+ return [rows, cols] if rows == settled_rows && cols == settled_cols
85
+ end
86
+ end
87
+
88
+ def read_a(port_a, port_b) = scan(port_a, port_b).first
89
+
90
+ def read_b(port_a, port_b) = scan(port_a, port_b).last
91
+
92
+ private
93
+
94
+ # Columns held down per row, as a bit mask of port B lines.
95
+ def row_masks
96
+ @row_masks ||= begin
97
+ pressed = held
98
+ matrix.map do |row|
99
+ row.each_with_index.sum { |key, column| pressed.include?(key) ? 1 << column : 0 }
100
+ end
101
+ end
102
+ end
103
+
104
+ # The matrix keys held down, with each combination expanded.
105
+ def held
106
+ keys.flat_map { |key| COMBINATIONS[key] || [key] }
107
+ end
108
+
109
+ def valid_key?(key)
110
+ COMBINATIONS.key?(key) || matrix.flatten.include?(key)
111
+ end
112
+ end
113
+ end
114
+ end
data/lib/badline/input.rb CHANGED
@@ -1,4 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "badline/input/keyboard"
4
+ require "badline/input/joystick"
5
+ require "badline/input/control_ports"
3
6
  require "badline/input/mouse1351"
4
7
  require "badline/input/paddles"
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Badline
4
4
  module KernalTrap
5
- class Drive
5
+ class DOS
6
6
  # The commands that read and write a block through a buffer channel,
7
7
  # and B-P, which moves its pointer.
8
8
  module BlockCommands