badline 0.12.1 → 0.14.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 (565) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -1
  3. data/CLAUDE.md +86 -38
  4. data/CONTRIBUTING.md +4 -3
  5. data/README.md +9 -6
  6. data/doc/library.md +9 -9
  7. data/doc/media.md +2 -1
  8. data/doc/pinned-behaviour.md +134 -105
  9. data/doc/snapshot-format.md +1047 -0
  10. data/doc/snapshots.md +73 -43
  11. data/lib/badline/audio/bare_player.rb +53 -20
  12. data/lib/badline/audio/cli.rb +6 -6
  13. data/lib/badline/audio/jukebox.rb +2 -2
  14. data/lib/badline/audio/machine_player.rb +16 -10
  15. data/lib/badline/{media → audio}/queue.rb +1 -1
  16. data/lib/badline/audio/queued_tune.rb +6 -6
  17. data/lib/badline/audio/renderer.rb +33 -22
  18. data/lib/badline/audio/stereo.rb +1 -1
  19. data/lib/badline/c128/banks.rb +6 -3
  20. data/lib/badline/c128/bus/keyed_state.rb +45 -0
  21. data/lib/badline/c128/bus.rb +35 -20
  22. data/lib/badline/c128/color_lines.rb +2 -2
  23. data/lib/badline/c128/cpu.rb +1 -1
  24. data/lib/badline/c128/drives.rb +14 -34
  25. data/lib/badline/c128/fast_serial.rb +5 -5
  26. data/lib/badline/c128/keyed_modules.rb +117 -0
  27. data/lib/badline/c128/keyed_state.rb +91 -0
  28. data/lib/badline/c128/keys.rb +9 -0
  29. data/lib/badline/c128/mmu.rb +9 -8
  30. data/lib/badline/c128/mmu_pages.rb +21 -1
  31. data/lib/badline/c128/modes.rb +21 -11
  32. data/lib/badline/c128/z80.rb +2 -2
  33. data/lib/badline/c128/z80_turns.rb +1 -1
  34. data/lib/badline/c128.rb +21 -16
  35. data/lib/badline/c64/attachments.rb +42 -0
  36. data/lib/badline/c64/banked_ram/banking.rb +32 -0
  37. data/lib/badline/c64/banked_ram/plus256k.rb +64 -0
  38. data/lib/badline/c64/banked_ram/plus60k.rb +47 -0
  39. data/lib/badline/c64/banked_ram/unexpanded.rb +30 -0
  40. data/lib/badline/c64/banked_ram.rb +23 -0
  41. data/lib/badline/c64/bus/debug_register.rb +32 -0
  42. data/lib/badline/c64/bus/extra_sids.rb +32 -0
  43. data/lib/badline/c64/bus/fittings.rb +40 -0
  44. data/lib/badline/c64/bus/keyed_state.rb +41 -0
  45. data/lib/badline/c64/bus/pla.rb +149 -0
  46. data/lib/badline/c64/bus/roms.rb +41 -0
  47. data/lib/badline/c64/bus/sid_slots.rb +44 -0
  48. data/lib/badline/c64/bus.rb +219 -0
  49. data/lib/badline/c64/cartridge/action_replay.rb +115 -0
  50. data/lib/badline/c64/cartridge/atomic_power.rb +26 -0
  51. data/lib/badline/c64/cartridge/bank.rb +83 -0
  52. data/lib/badline/c64/cartridge/comal80.rb +52 -0
  53. data/lib/badline/c64/cartridge/dinamic.rb +36 -0
  54. data/lib/badline/c64/cartridge/easy_flash.rb +132 -0
  55. data/lib/badline/c64/cartridge/epyx_fastload.rb +73 -0
  56. data/lib/badline/c64/cartridge/final_cartridge3.rb +79 -0
  57. data/lib/badline/c64/cartridge/flash.rb +279 -0
  58. data/lib/badline/c64/cartridge/freezer.rb +35 -0
  59. data/lib/badline/c64/cartridge/fun_play.rb +40 -0
  60. data/lib/badline/c64/cartridge/g_mod2.rb +64 -0
  61. data/lib/badline/c64/cartridge/game_system.rb +42 -0
  62. data/lib/badline/c64/cartridge/geo_ram.rb +65 -0
  63. data/lib/badline/c64/cartridge/kcs_power.rb +69 -0
  64. data/lib/badline/c64/cartridge/keyed_state.rb +393 -0
  65. data/lib/badline/c64/cartridge/mach5.rb +34 -0
  66. data/lib/badline/c64/cartridge/magic_desk.rb +32 -0
  67. data/lib/badline/c64/cartridge/ocean.rb +37 -0
  68. data/lib/badline/c64/cartridge/pagefox.rb +60 -0
  69. data/lib/badline/c64/cartridge/retro_replay.rb +278 -0
  70. data/lib/badline/c64/cartridge/rex_utility.rb +31 -0
  71. data/lib/badline/c64/cartridge/rgcd.rb +50 -0
  72. data/lib/badline/c64/cartridge/simons_basic.rb +37 -0
  73. data/lib/badline/c64/cartridge/standard.rb +17 -0
  74. data/lib/badline/c64/cartridge/super_games.rb +40 -0
  75. data/lib/badline/c64/cartridge/westermann.rb +32 -0
  76. data/lib/badline/c64/cartridge/zaxxon.rb +52 -0
  77. data/lib/badline/c64/cartridge.rb +232 -0
  78. data/lib/badline/c64/color_memory.rb +27 -0
  79. data/lib/badline/{computer → c64}/common.rb +2 -2
  80. data/lib/badline/{computer → c64}/kernal_traps.rb +39 -36
  81. data/lib/badline/c64/keyed_modules.rb +111 -0
  82. data/lib/badline/c64/keyed_state.rb +68 -0
  83. data/lib/badline/c64/reu/dma.rb +271 -0
  84. data/lib/badline/c64/reu/keyed_state.rb +140 -0
  85. data/lib/badline/c64/reu/ram.rb +94 -0
  86. data/lib/badline/c64/reu/trigger.rb +34 -0
  87. data/lib/badline/c64/reu.rb +289 -0
  88. data/lib/badline/c64/true_drives.rb +120 -0
  89. data/lib/badline/{computer.rb → c64.rb} +24 -15
  90. data/lib/badline/chips/cia/fast_forward.rb +62 -0
  91. data/lib/badline/chips/cia/interrupt_register.rb +128 -0
  92. data/lib/badline/chips/cia/keyed_parts.rb +213 -0
  93. data/lib/badline/chips/cia/serial.rb +246 -0
  94. data/lib/badline/chips/cia/time_of_day.rb +210 -0
  95. data/lib/badline/chips/cia/timer.rb +188 -0
  96. data/lib/badline/chips/cia.rb +281 -0
  97. data/lib/badline/chips/cpu/addressing.rb +133 -0
  98. data/lib/badline/chips/cpu/boundary.rb +56 -0
  99. data/lib/badline/chips/cpu/core.rb +183 -0
  100. data/lib/badline/chips/cpu/instruction.rb +338 -0
  101. data/lib/badline/chips/cpu/instruction_set/arithmetic.rb +118 -0
  102. data/lib/badline/chips/cpu/instruction_set/bitwise.rb +130 -0
  103. data/lib/badline/chips/cpu/instruction_set/branch.rb +83 -0
  104. data/lib/badline/chips/cpu/instruction_set/flag.rb +67 -0
  105. data/lib/badline/chips/cpu/instruction_set/illegal.rb +274 -0
  106. data/lib/badline/chips/cpu/instruction_set/inc_dec.rb +73 -0
  107. data/lib/badline/chips/cpu/instruction_set/stack.rb +56 -0
  108. data/lib/badline/chips/cpu/instruction_set/transfer.rb +141 -0
  109. data/lib/badline/chips/cpu/instruction_set.rb +59 -0
  110. data/lib/badline/chips/cpu/interrupts.rb +108 -0
  111. data/lib/badline/chips/cpu/keyed_state.rb +177 -0
  112. data/lib/badline/chips/cpu/microcode.rb +195 -0
  113. data/lib/badline/chips/cpu/operations.rb +90 -0
  114. data/lib/badline/chips/cpu/port.rb +133 -0
  115. data/lib/badline/chips/cpu/stack_operations.rb +84 -0
  116. data/lib/badline/chips/cpu/traps.rb +23 -0
  117. data/lib/badline/chips/cpu.rb +17 -0
  118. data/lib/badline/chips/sid/catch_up.rb +122 -0
  119. data/lib/badline/chips/sid/decimator.rb +68 -0
  120. data/lib/badline/chips/sid/envelope.rb +236 -0
  121. data/lib/badline/chips/sid/filter.rb +227 -0
  122. data/lib/badline/chips/sid/keyed_parts.rb +286 -0
  123. data/lib/badline/chips/sid/voice.rb +69 -0
  124. data/lib/badline/chips/sid/waveform/combined.rb +128 -0
  125. data/lib/badline/chips/sid/waveform/fast_forward.rb +107 -0
  126. data/lib/badline/chips/sid/waveform/noise_writeback.rb +124 -0
  127. data/lib/badline/chips/sid/waveform.rb +305 -0
  128. data/lib/badline/chips/sid.rb +264 -0
  129. data/lib/badline/chips/ted/beam.rb +119 -0
  130. data/lib/badline/chips/ted/timers.rb +66 -0
  131. data/lib/badline/chips/ted.rb +143 -0
  132. data/lib/badline/chips/tia.rb +49 -0
  133. data/lib/badline/chips/vdc/keyed_parts.rb +105 -0
  134. data/lib/badline/{c128 → chips}/vdc/memory.rb +1 -1
  135. data/lib/badline/{c128 → chips}/vdc/painter.rb +1 -13
  136. data/lib/badline/{c128 → chips}/vdc/raster.rb +1 -17
  137. data/lib/badline/{c128 → chips}/vdc/window.rb +1 -10
  138. data/lib/badline/{c128 → chips}/vdc.rb +6 -31
  139. data/lib/badline/chips/via/control_lines.rb +109 -0
  140. data/lib/badline/chips/via/fast_forward.rb +55 -0
  141. data/lib/badline/chips/via/interrupt_register.rb +60 -0
  142. data/lib/badline/chips/via/keyed_parts.rb +163 -0
  143. data/lib/badline/chips/via/shift_register.rb +168 -0
  144. data/lib/badline/chips/via/timer1.rb +120 -0
  145. data/lib/badline/chips/via/timer2.rb +117 -0
  146. data/lib/badline/chips/via.rb +267 -0
  147. data/lib/badline/chips/vic/bank.rb +135 -0
  148. data/lib/badline/chips/vic/border_mask.rb +78 -0
  149. data/lib/badline/chips/vic/collisions.rb +106 -0
  150. data/lib/badline/chips/vic/color_patches.rb +38 -0
  151. data/lib/badline/chips/vic/display_state.rb +168 -0
  152. data/lib/badline/chips/vic/graphics_mode.rb +166 -0
  153. data/lib/badline/chips/vic/graphics_shifter.rb +183 -0
  154. data/lib/badline/chips/vic/keyed_parts.rb +228 -0
  155. data/lib/badline/chips/vic/keyed_sprites.rb +225 -0
  156. data/lib/badline/chips/vic/keyed_state.rb +102 -0
  157. data/lib/badline/chips/vic/register_log.rb +65 -0
  158. data/lib/badline/chips/vic/registers.rb +188 -0
  159. data/lib/badline/chips/vic/sequencer.rb +275 -0
  160. data/lib/badline/chips/vic/sequencer_output.rb +118 -0
  161. data/lib/badline/chips/vic/sprite/internal_bus.rb +59 -0
  162. data/lib/badline/chips/vic/sprite/shifter.rb +148 -0
  163. data/lib/badline/chips/vic/sprite/timing.rb +58 -0
  164. data/lib/badline/chips/vic/sprite.rb +337 -0
  165. data/lib/badline/chips/vic/sprites.rb +281 -0
  166. data/lib/badline/chips/vic.rb +787 -0
  167. data/lib/badline/chips/vic_i/keyed_parts.rb +142 -0
  168. data/lib/badline/{vic20/vic → chips/vic_i}/painter.rb +2 -30
  169. data/lib/badline/chips/vic_i/sound/output.rb +85 -0
  170. data/lib/badline/chips/vic_i/sound.rb +227 -0
  171. data/lib/badline/{vic20/vic → chips/vic_i}/text_window.rb +2 -2
  172. data/lib/badline/{vic20/vic.rb → chips/vic_i.rb} +6 -6
  173. data/lib/badline/chips/z80/arithmetic.rb +119 -0
  174. data/lib/badline/chips/z80/bit_page.rb +57 -0
  175. data/lib/badline/chips/z80/block_io.rb +60 -0
  176. data/lib/badline/chips/z80/block_transfers.rb +61 -0
  177. data/lib/badline/chips/z80/bus_cycles.rb +113 -0
  178. data/lib/badline/chips/z80/core.rb +115 -0
  179. data/lib/badline/chips/z80/exchanges.rb +52 -0
  180. data/lib/badline/chips/z80/extended_page.rb +91 -0
  181. data/lib/badline/chips/z80/flags.rb +39 -0
  182. data/lib/badline/chips/z80/interrupt_acceptance.rb +48 -0
  183. data/lib/badline/chips/z80/jumps.rb +84 -0
  184. data/lib/badline/chips/z80/keyed_state.rb +73 -0
  185. data/lib/badline/chips/z80/loads.rb +100 -0
  186. data/lib/badline/chips/z80/main_page.rb +136 -0
  187. data/lib/badline/chips/z80/registers.rb +122 -0
  188. data/lib/badline/chips/z80/shifts.rb +66 -0
  189. data/lib/badline/chips/z80.rb +13 -0
  190. data/lib/badline/chips.rb +10 -0
  191. data/lib/badline/core.rb +13 -32
  192. data/lib/badline/drives/datasette/keyed_state.rb +38 -0
  193. data/lib/badline/drives/datasette.rb +173 -0
  194. data/lib/badline/drives/engine/core.rb +152 -0
  195. data/lib/badline/drives/engine/fast_serial.rb +75 -0
  196. data/lib/badline/drives/engine/idle.rb +127 -0
  197. data/lib/badline/drives/engine/idle_cpu.rb +30 -0
  198. data/lib/badline/drives/engine/orbit.rb +81 -0
  199. data/lib/badline/drives/engine/serial_lines.rb +72 -0
  200. data/lib/badline/drives/engine/sleep.rb +114 -0
  201. data/lib/badline/drives/engine/vias.rb +86 -0
  202. data/lib/badline/drives/engine/watch.rb +152 -0
  203. data/lib/badline/drives/engine.rb +11 -0
  204. data/lib/badline/drives/model1541/bus.rb +75 -0
  205. data/lib/badline/drives/model1541/byte_ready.rb +50 -0
  206. data/lib/badline/drives/model1541/cpu.rb +13 -0
  207. data/lib/badline/drives/model1541/disk.rb +318 -0
  208. data/lib/badline/drives/model1541/disk_via.rb +38 -0
  209. data/lib/badline/drives/model1541/gcr.rb +59 -0
  210. data/lib/badline/drives/model1541/keyed_state.rb +251 -0
  211. data/lib/badline/drives/model1541/mechanism.rb +313 -0
  212. data/lib/badline/drives/model1541/rotation.rb +123 -0
  213. data/lib/badline/drives/model1541/sector_reader.rb +78 -0
  214. data/lib/badline/drives/model1541/serial_port.rb +20 -0
  215. data/lib/badline/drives/model1541/track.rb +100 -0
  216. data/lib/badline/drives/model1541.rb +80 -0
  217. data/lib/badline/drives/model1571/bus.rb +100 -0
  218. data/lib/badline/drives/model1571/cpu.rb +13 -0
  219. data/lib/badline/drives/model1571/keyed_state.rb +108 -0
  220. data/lib/badline/drives/model1571/serial_port.rb +39 -0
  221. data/lib/badline/drives/model1571/serial_via.rb +27 -0
  222. data/lib/badline/drives/model1571/wd1770.rb +108 -0
  223. data/lib/badline/drives/model1571.rb +141 -0
  224. data/lib/badline/drives/model1581/bus.rb +126 -0
  225. data/lib/badline/drives/model1581/cpu.rb +13 -0
  226. data/lib/badline/drives/model1581/disk.rb +133 -0
  227. data/lib/badline/drives/model1581/keyed_state.rb +280 -0
  228. data/lib/badline/drives/model1581/mechanism.rb +98 -0
  229. data/lib/badline/drives/model1581/serial_port.rb +54 -0
  230. data/lib/badline/drives/model1581/slot.rb +61 -0
  231. data/lib/badline/drives/model1581/track.rb +102 -0
  232. data/lib/badline/drives/model1581/track_bytes.rb +77 -0
  233. data/lib/badline/drives/model1581/wd1772/registers.rb +91 -0
  234. data/lib/badline/drives/model1581/wd1772/sector_writes.rb +75 -0
  235. data/lib/badline/drives/model1581/wd1772/sectors.rb +152 -0
  236. data/lib/badline/drives/model1581/wd1772/stepping.rb +111 -0
  237. data/lib/badline/drives/model1581/wd1772/tracks.rb +127 -0
  238. data/lib/badline/drives/model1581/wd1772/turn.rb +75 -0
  239. data/lib/badline/drives/model1581/wd1772.rb +216 -0
  240. data/lib/badline/drives/model1581.rb +206 -0
  241. data/lib/badline/drives/serial_bus.rb +161 -0
  242. data/lib/badline/drives.rb +8 -0
  243. data/lib/badline/frontend/app.rb +3 -3
  244. data/lib/badline/frontend/boot.rb +4 -4
  245. data/lib/badline/frontend/controls.rb +19 -3
  246. data/lib/badline/frontend/drive_led.rb +44 -21
  247. data/lib/badline/frontend/machine_window.rb +3 -1
  248. data/lib/badline/frontend/menu/menu_dialogs.rb +2 -2
  249. data/lib/badline/frontend/player/filter_view.rb +1 -1
  250. data/lib/badline/frontend/player/player_controller.rb +2 -2
  251. data/lib/badline/frontend/player/player_screen.rb +1 -0
  252. data/lib/badline/frontend/player/theme.rb +7 -7
  253. data/lib/badline/frontend/snapshots.rb +12 -1
  254. data/lib/badline/frontend/timeline.rb +30 -12
  255. data/lib/badline/input/control_ports.rb +78 -0
  256. data/lib/badline/input/joystick.rb +27 -0
  257. data/lib/badline/input/keyboard.rb +114 -0
  258. data/lib/badline/input/matrix_typist.rb +98 -0
  259. data/lib/badline/input.rb +4 -0
  260. data/lib/badline/kernal_trap/chrout.rb +45 -0
  261. data/lib/badline/kernal_trap/{drive → dos}/block_commands.rb +1 -1
  262. data/lib/badline/kernal_trap/dos/channel.rb +156 -0
  263. data/lib/badline/kernal_trap/{drive → dos}/channels.rb +1 -26
  264. data/lib/badline/kernal_trap/{drive → dos}/memory.rb +1 -10
  265. data/lib/badline/kernal_trap/{drive → dos}/parameters.rb +1 -1
  266. data/lib/badline/kernal_trap/{drive → dos}/status.rb +1 -9
  267. data/lib/badline/kernal_trap/{drive → dos}/write_file.rb +1 -19
  268. data/lib/badline/kernal_trap/{drive → dos}/writes.rb +1 -1
  269. data/lib/badline/kernal_trap/{drive.rb → dos.rb} +9 -27
  270. data/lib/badline/kernal_trap/file_routine.rb +4 -4
  271. data/lib/badline/kernal_trap/keyed_state.rb +150 -0
  272. data/lib/badline/kernal_trap/layout.rb +75 -11
  273. data/lib/badline/kernal_trap/load.rb +19 -21
  274. data/lib/badline/kernal_trap/routine.rb +12 -0
  275. data/lib/badline/kernal_trap/save.rb +12 -22
  276. data/lib/badline/kernal_trap/serial.rb +8 -24
  277. data/lib/badline/kernal_trap.rb +3 -2
  278. data/lib/badline/machine/clocking.rb +1 -1
  279. data/lib/badline/machine/keyboard_buffer.rb +49 -0
  280. data/lib/badline/machine/settling.rb +29 -0
  281. data/lib/badline/machine.rb +10 -7
  282. data/lib/badline/media/boot_disk.rb +14 -2
  283. data/lib/badline/media/extensions.rb +10 -0
  284. data/lib/badline/media/true_drive.rb +1 -1
  285. data/lib/badline/media/tune.rb +2 -2
  286. data/lib/badline/media.rb +3 -3
  287. data/lib/badline/memory.rb +3 -6
  288. data/lib/badline/model.rb +1 -1
  289. data/lib/badline/options/family.rb +5 -2
  290. data/lib/badline/options/help.rb +42 -16
  291. data/lib/badline/options/table.rb +2 -0
  292. data/lib/badline/options/validation.rb +2 -0
  293. data/lib/badline/options.rb +6 -1
  294. data/lib/badline/plus4/acia.rb +45 -0
  295. data/lib/badline/plus4/bus.rb +312 -0
  296. data/lib/badline/plus4/cpu.rb +10 -0
  297. data/lib/badline/plus4/cpu_port.rb +93 -0
  298. data/lib/badline/plus4/keyboard_port.rb +51 -0
  299. data/lib/badline/plus4/model.rb +38 -0
  300. data/lib/badline/plus4/user_port.rb +31 -0
  301. data/lib/badline/plus4.rb +164 -0
  302. data/lib/badline/roms/README +44 -6
  303. data/lib/badline/roms/plus4/basic.rom +0 -0
  304. data/lib/badline/roms/plus4/function-high.rom +0 -0
  305. data/lib/badline/roms/plus4/function-low.rom +0 -0
  306. data/lib/badline/roms/plus4/kernal-ntsc.rom +0 -0
  307. data/lib/badline/roms/plus4/kernal-pal.rom +0 -0
  308. data/lib/badline/sdl.rb +1 -0
  309. data/lib/badline/{storage/sid_file.rb → sid_tune/file.rb} +3 -3
  310. data/lib/badline/{storage → sid_tune}/hvsc.rb +7 -7
  311. data/lib/badline/{storage → sid_tune}/song_lengths.rb +2 -2
  312. data/lib/badline/{storage → sid_tune}/stil/credit.rb +1 -1
  313. data/lib/badline/{storage → sid_tune}/stil.rb +3 -3
  314. data/lib/badline/sid_tune.rb +6 -0
  315. data/lib/badline/snapshot/c128_setup.rb +32 -0
  316. data/lib/badline/snapshot/c64_setup.rb +83 -0
  317. data/lib/badline/snapshot/container.rb +4 -0
  318. data/lib/badline/snapshot/field_doc/markdown.rb +112 -0
  319. data/lib/badline/snapshot/field_doc.rb +109 -0
  320. data/lib/badline/snapshot/image.rb +132 -46
  321. data/lib/badline/snapshot/keyed/cursor.rb +40 -0
  322. data/lib/badline/snapshot/keyed/modules.rb +66 -0
  323. data/lib/badline/snapshot/keyed/reader.rb +188 -0
  324. data/lib/badline/snapshot/keyed/recorder.rb +88 -0
  325. data/lib/badline/snapshot/keyed/report.rb +26 -0
  326. data/lib/badline/snapshot/keyed/writer.rb +55 -0
  327. data/lib/badline/snapshot/keyed.rb +64 -0
  328. data/lib/badline/snapshot/machine_state.rb +17 -64
  329. data/lib/badline/snapshot/storage_setup.rb +63 -0
  330. data/lib/badline/snapshot/vic20_setup.rb +28 -0
  331. data/lib/badline/snapshot/vice/c64_mem.rb +1 -1
  332. data/lib/badline/snapshot/vice/restore.rb +1 -1
  333. data/lib/badline/snapshot/vice/reu1764.rb +3 -3
  334. data/lib/badline/snapshot/vice/reu_fields.rb +40 -0
  335. data/lib/badline/snapshot/vice.rb +13 -35
  336. data/lib/badline/snapshot.rb +44 -22
  337. data/lib/badline/storage/crt_file.rb +3 -1
  338. data/lib/badline/storage/d64_image.rb +0 -2
  339. data/lib/badline/storage/d71_image.rb +0 -2
  340. data/lib/badline/storage/d81_image.rb +0 -2
  341. data/lib/badline/storage/disk_image.rb +3 -6
  342. data/lib/badline/storage/g64_image.rb +10 -5
  343. data/lib/badline/storage/host_directory.rb +0 -5
  344. data/lib/badline/storage/t64.rb +2 -8
  345. data/lib/badline/storage/tap.rb +43 -15
  346. data/lib/badline/storage/unavailable.rb +1 -1
  347. data/lib/badline/storage.rb +0 -37
  348. data/lib/badline/support/c128_checkpoint.rb +39 -0
  349. data/lib/badline/support/checkpoint.rb +108 -0
  350. data/lib/badline/support/vic20_checkpoint.rb +38 -0
  351. data/lib/badline/support.rb +5 -0
  352. data/lib/badline/version.rb +1 -1
  353. data/lib/badline/vic20/attachments.rb +8 -5
  354. data/lib/badline/vic20/bus/keyed_state.rb +52 -0
  355. data/lib/badline/vic20/bus.rb +2 -25
  356. data/lib/badline/vic20/cpu.rb +1 -1
  357. data/lib/badline/vic20/keyed_modules.rb +73 -0
  358. data/lib/badline/vic20/keyed_state.rb +45 -0
  359. data/lib/badline/vic20/port_wiring.rb +4 -4
  360. data/lib/badline/vic20/user_via_ports.rb +2 -2
  361. data/lib/badline/vic20.rb +22 -17
  362. data/lib/badline.rb +1 -0
  363. metadata +271 -228
  364. data/lib/badline/address_bus/extra_sids.rb +0 -30
  365. data/lib/badline/address_bus/fittings.rb +0 -38
  366. data/lib/badline/address_bus/pla.rb +0 -147
  367. data/lib/badline/address_bus/roms.rb +0 -39
  368. data/lib/badline/address_bus/saved_state.rb +0 -66
  369. data/lib/badline/address_bus/sid_slots.rb +0 -42
  370. data/lib/badline/address_bus.rb +0 -216
  371. data/lib/badline/c128/bus_state.rb +0 -53
  372. data/lib/badline/c128/saved_state.rb +0 -143
  373. data/lib/badline/cartridge/action_replay.rb +0 -126
  374. data/lib/badline/cartridge/atomic_power.rb +0 -24
  375. data/lib/badline/cartridge/bank.rb +0 -81
  376. data/lib/badline/cartridge/comal80.rb +0 -50
  377. data/lib/badline/cartridge/dinamic.rb +0 -34
  378. data/lib/badline/cartridge/easy_flash.rb +0 -145
  379. data/lib/badline/cartridge/epyx_fastload.rb +0 -79
  380. data/lib/badline/cartridge/final_cartridge3.rb +0 -89
  381. data/lib/badline/cartridge/flash.rb +0 -306
  382. data/lib/badline/cartridge/freezer.rb +0 -33
  383. data/lib/badline/cartridge/fun_play.rb +0 -38
  384. data/lib/badline/cartridge/g_mod2.rb +0 -74
  385. data/lib/badline/cartridge/game_system.rb +0 -40
  386. data/lib/badline/cartridge/geo_ram.rb +0 -79
  387. data/lib/badline/cartridge/kcs_power.rb +0 -75
  388. data/lib/badline/cartridge/mach5.rb +0 -32
  389. data/lib/badline/cartridge/magic_desk.rb +0 -30
  390. data/lib/badline/cartridge/ocean.rb +0 -35
  391. data/lib/badline/cartridge/pagefox.rb +0 -68
  392. data/lib/badline/cartridge/retro_replay.rb +0 -320
  393. data/lib/badline/cartridge/rex_utility.rb +0 -29
  394. data/lib/badline/cartridge/rgcd.rb +0 -58
  395. data/lib/badline/cartridge/simons_basic.rb +0 -35
  396. data/lib/badline/cartridge/standard.rb +0 -15
  397. data/lib/badline/cartridge/super_games.rb +0 -48
  398. data/lib/badline/cartridge/westermann.rb +0 -30
  399. data/lib/badline/cartridge/zaxxon.rb +0 -66
  400. data/lib/badline/cartridge.rb +0 -303
  401. data/lib/badline/checkpoint.rb +0 -98
  402. data/lib/badline/chrout_trap.rb +0 -43
  403. data/lib/badline/cia/fast_forward.rb +0 -60
  404. data/lib/badline/cia/interrupt_register.rb +0 -143
  405. data/lib/badline/cia/serial.rb +0 -275
  406. data/lib/badline/cia/state.rb +0 -47
  407. data/lib/badline/cia/timer.rb +0 -206
  408. data/lib/badline/cia.rb +0 -279
  409. data/lib/badline/color_memory.rb +0 -25
  410. data/lib/badline/computer/attachments.rb +0 -88
  411. data/lib/badline/computer/saved_state.rb +0 -117
  412. data/lib/badline/computer/true_drives.rb +0 -69
  413. data/lib/badline/control_ports.rb +0 -76
  414. data/lib/badline/cpu/addressing.rb +0 -131
  415. data/lib/badline/cpu/boundary.rb +0 -54
  416. data/lib/badline/cpu/core.rb +0 -165
  417. data/lib/badline/cpu/microcode.rb +0 -177
  418. data/lib/badline/cpu/operations.rb +0 -88
  419. data/lib/badline/cpu/saved_state.rb +0 -115
  420. data/lib/badline/cpu/stack_operations.rb +0 -82
  421. data/lib/badline/cpu.rb +0 -10
  422. data/lib/badline/cpu_port.rb +0 -112
  423. data/lib/badline/datasette.rb +0 -161
  424. data/lib/badline/debug_register.rb +0 -28
  425. data/lib/badline/drive/core.rb +0 -147
  426. data/lib/badline/drive/fast_serial.rb +0 -73
  427. data/lib/badline/drive/idle.rb +0 -125
  428. data/lib/badline/drive/idle_cpu.rb +0 -28
  429. data/lib/badline/drive/orbit.rb +0 -79
  430. data/lib/badline/drive/serial_lines.rb +0 -73
  431. data/lib/badline/drive/sleep.rb +0 -112
  432. data/lib/badline/drive/vias.rb +0 -84
  433. data/lib/badline/drive/watch.rb +0 -150
  434. data/lib/badline/drive.rb +0 -11
  435. data/lib/badline/drive1541/bus.rb +0 -86
  436. data/lib/badline/drive1541/byte_ready.rb +0 -48
  437. data/lib/badline/drive1541/cpu.rb +0 -11
  438. data/lib/badline/drive1541/disk.rb +0 -315
  439. data/lib/badline/drive1541/disk_state.rb +0 -86
  440. data/lib/badline/drive1541/disk_via.rb +0 -36
  441. data/lib/badline/drive1541/gcr.rb +0 -57
  442. data/lib/badline/drive1541/mechanism.rb +0 -313
  443. data/lib/badline/drive1541/mechanism_state.rb +0 -68
  444. data/lib/badline/drive1541/rotation.rb +0 -121
  445. data/lib/badline/drive1541/sector_reader.rb +0 -76
  446. data/lib/badline/drive1541/serial_port.rb +0 -18
  447. data/lib/badline/drive1541/track.rb +0 -98
  448. data/lib/badline/drive1541.rb +0 -111
  449. data/lib/badline/drive1571/bus.rb +0 -111
  450. data/lib/badline/drive1571/cpu.rb +0 -11
  451. data/lib/badline/drive1571/serial_port.rb +0 -37
  452. data/lib/badline/drive1571/serial_via.rb +0 -25
  453. data/lib/badline/drive1571/wd1770.rb +0 -120
  454. data/lib/badline/drive1571.rb +0 -175
  455. data/lib/badline/drive1581/bus.rb +0 -137
  456. data/lib/badline/drive1581/cpu.rb +0 -11
  457. data/lib/badline/drive1581/disk.rb +0 -135
  458. data/lib/badline/drive1581/disk_state.rb +0 -87
  459. data/lib/badline/drive1581/mechanism.rb +0 -117
  460. data/lib/badline/drive1581/serial_port.rb +0 -52
  461. data/lib/badline/drive1581/slot.rb +0 -78
  462. data/lib/badline/drive1581/track.rb +0 -100
  463. data/lib/badline/drive1581/track_bytes.rb +0 -75
  464. data/lib/badline/drive1581/wd1772/registers.rb +0 -89
  465. data/lib/badline/drive1581/wd1772/sector_writes.rb +0 -73
  466. data/lib/badline/drive1581/wd1772/sectors.rb +0 -150
  467. data/lib/badline/drive1581/wd1772/state.rb +0 -66
  468. data/lib/badline/drive1581/wd1772/stepping.rb +0 -109
  469. data/lib/badline/drive1581/wd1772/tracks.rb +0 -125
  470. data/lib/badline/drive1581/wd1772/turn.rb +0 -73
  471. data/lib/badline/drive1581/wd1772.rb +0 -216
  472. data/lib/badline/drive1581.rb +0 -233
  473. data/lib/badline/iec_bus.rb +0 -159
  474. data/lib/badline/instruction.rb +0 -334
  475. data/lib/badline/instruction_set/arithmetic.rb +0 -114
  476. data/lib/badline/instruction_set/bitwise.rb +0 -126
  477. data/lib/badline/instruction_set/branch.rb +0 -79
  478. data/lib/badline/instruction_set/flag.rb +0 -63
  479. data/lib/badline/instruction_set/illegal.rb +0 -270
  480. data/lib/badline/instruction_set/inc_dec.rb +0 -69
  481. data/lib/badline/instruction_set/stack.rb +0 -52
  482. data/lib/badline/instruction_set/transfer.rb +0 -137
  483. data/lib/badline/instruction_set.rb +0 -55
  484. data/lib/badline/interrupts.rb +0 -104
  485. data/lib/badline/joystick.rb +0 -25
  486. data/lib/badline/kernal_trap/channel.rb +0 -181
  487. data/lib/badline/keyboard.rb +0 -112
  488. data/lib/badline/keyboard_buffer.rb +0 -33
  489. data/lib/badline/ram_expansion/banking.rb +0 -30
  490. data/lib/badline/ram_expansion/plus256k.rb +0 -54
  491. data/lib/badline/ram_expansion/plus60k.rb +0 -43
  492. data/lib/badline/ram_expansion/unexpanded.rb +0 -28
  493. data/lib/badline/ram_expansion.rb +0 -21
  494. data/lib/badline/reu/dma/saved_state.rb +0 -50
  495. data/lib/badline/reu/dma.rb +0 -273
  496. data/lib/badline/reu/ram.rb +0 -107
  497. data/lib/badline/reu/saved_state.rb +0 -80
  498. data/lib/badline/reu/trigger.rb +0 -32
  499. data/lib/badline/reu.rb +0 -289
  500. data/lib/badline/sid/catch_up.rb +0 -120
  501. data/lib/badline/sid/decimator.rb +0 -64
  502. data/lib/badline/sid/envelope/state.rb +0 -68
  503. data/lib/badline/sid/envelope.rb +0 -239
  504. data/lib/badline/sid/filter.rb +0 -263
  505. data/lib/badline/sid/voice.rb +0 -77
  506. data/lib/badline/sid/waveform/combined.rb +0 -126
  507. data/lib/badline/sid/waveform/fast_forward.rb +0 -105
  508. data/lib/badline/sid/waveform/noise_writeback.rb +0 -122
  509. data/lib/badline/sid/waveform/state.rb +0 -66
  510. data/lib/badline/sid/waveform.rb +0 -305
  511. data/lib/badline/sid.rb +0 -303
  512. data/lib/badline/snapshot/setup.rb +0 -75
  513. data/lib/badline/snapshot/state.rb +0 -189
  514. data/lib/badline/time_of_day.rb +0 -228
  515. data/lib/badline/traps.rb +0 -19
  516. data/lib/badline/via/control_lines.rb +0 -122
  517. data/lib/badline/via/fast_forward.rb +0 -53
  518. data/lib/badline/via/interrupt_register.rb +0 -67
  519. data/lib/badline/via/shift_register.rb +0 -180
  520. data/lib/badline/via/state.rb +0 -42
  521. data/lib/badline/via/timer1.rb +0 -131
  522. data/lib/badline/via/timer2.rb +0 -133
  523. data/lib/badline/via.rb +0 -266
  524. data/lib/badline/vic/bank.rb +0 -133
  525. data/lib/badline/vic/border_mask.rb +0 -86
  526. data/lib/badline/vic/collisions.rb +0 -115
  527. data/lib/badline/vic/color_patches.rb +0 -47
  528. data/lib/badline/vic/display_state.rb +0 -185
  529. data/lib/badline/vic/graphics_mode.rb +0 -164
  530. data/lib/badline/vic/graphics_shifter.rb +0 -207
  531. data/lib/badline/vic/register_log.rb +0 -81
  532. data/lib/badline/vic/registers.rb +0 -195
  533. data/lib/badline/vic/sequencer.rb +0 -275
  534. data/lib/badline/vic/sequencer_output.rb +0 -116
  535. data/lib/badline/vic/sequencer_state.rb +0 -89
  536. data/lib/badline/vic/sprite/internal_bus.rb +0 -68
  537. data/lib/badline/vic/sprite/saved_state.rb +0 -64
  538. data/lib/badline/vic/sprite/shifter.rb +0 -146
  539. data/lib/badline/vic/sprite/timing.rb +0 -56
  540. data/lib/badline/vic/sprite.rb +0 -337
  541. data/lib/badline/vic/sprites.rb +0 -282
  542. data/lib/badline/vic/sprites_state.rb +0 -57
  543. data/lib/badline/vic.rb +0 -853
  544. data/lib/badline/vic20/saved_state.rb +0 -124
  545. data/lib/badline/vic20/sound/output.rb +0 -83
  546. data/lib/badline/vic20/sound.rb +0 -233
  547. data/lib/badline/vic20/vic/saved_state.rb +0 -55
  548. data/lib/badline/z80/arithmetic.rb +0 -117
  549. data/lib/badline/z80/bit_page.rb +0 -55
  550. data/lib/badline/z80/block_io.rb +0 -58
  551. data/lib/badline/z80/block_transfers.rb +0 -59
  552. data/lib/badline/z80/bus_cycles.rb +0 -111
  553. data/lib/badline/z80/core.rb +0 -113
  554. data/lib/badline/z80/exchanges.rb +0 -50
  555. data/lib/badline/z80/extended_page.rb +0 -89
  556. data/lib/badline/z80/flags.rb +0 -37
  557. data/lib/badline/z80/interrupt_acceptance.rb +0 -46
  558. data/lib/badline/z80/jumps.rb +0 -82
  559. data/lib/badline/z80/loads.rb +0 -98
  560. data/lib/badline/z80/main_page.rb +0 -134
  561. data/lib/badline/z80/registers.rb +0 -120
  562. data/lib/badline/z80/saved_state.rb +0 -69
  563. data/lib/badline/z80/shifts.rb +0 -64
  564. data/lib/badline/z80.rb +0 -11
  565. /data/lib/badline/snapshot/{fields.rb → vice/fields.rb} +0 -0
@@ -1,275 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "badline/vic/border_mask"
4
- require "badline/vic/color_patches"
5
- require "badline/vic/graphics_mode"
6
- require "badline/vic/graphics_shifter"
7
- require "badline/vic/sequencer_output"
8
- require "badline/vic/sequencer_state"
9
-
10
- module Badline
11
- class VIC
12
- # = VIC-II Sequencer
13
- #
14
- # Turns fetched graphics data into output pixels.
15
- class Sequencer
16
- include Output
17
- include SavedState
18
-
19
- BORDER_Y_BOUNDS = [
20
- [55, 247].freeze,
21
- [51, 251].freeze
22
- ].freeze
23
-
24
- MODES = GraphicsMode::MODES
25
-
26
- attr_reader :colors, :fg, :registers, :bank, :cur_colors,
27
- :color_patches
28
- # The fg masks are shared frozen patterns assigned by reference, never
29
- # mutated in place.
30
- attr_accessor :cur_fg
31
- # False leaves the line's colours unpainted and keeps only the
32
- # foreground mask the sprite collisions read.
33
- attr_writer :render
34
-
35
- def initialize(width, registers, bank, model: :mos6569, region: Region::PAL)
36
- @width = width
37
- window_bounds(region.display_x_bounds)
38
- @registers = registers
39
- @bank = bank
40
- @colors = Array.new(width, 0)
41
- @fg = Array.new(width, false)
42
- @border_mask = BorderMask.new(width)
43
- # Hot-path aliases: the pixel loops write coverage straight into the
44
- # mask's arrays.
45
- @border = @border_mask.mask
46
- @border_groups = @border_mask.groups
47
- @cur_colors = Array.new(8, 0)
48
- @cur_fg = GraphicsMode::NO_FG
49
- @prev_colors = Array.new(8, 0)
50
- @prev_fg = GraphicsMode::NO_FG
51
- @vertical_border = true
52
- @vertical_armed = true
53
- @main_border = true
54
- @color_patches = ColorPatches.new(self, grey_dots: model == :mos8565)
55
- @shifter = GraphicsShifter.new(registers, model:)
56
- @xscroll = 0
57
- @last_shift = 0
58
- @last_mode = 0
59
- @settling = false
60
- @ring_data = Array.new(4, 0)
61
- @ring_char = Array.new(4, 0)
62
- @ring_color = Array.new(4, 1)
63
- @prev_fresh = false
64
- @check = true
65
- @render = true
66
- new_line(0)
67
- end
68
-
69
- # Reset the line buffers at the start of a rasterline.
70
- def new_line(line)
71
- @line = line
72
- @left_vertical_border = nil
73
- @first_csel = @registers.csel?
74
- @colors.fill(@registers.border)
75
- @fg.fill(false)
76
- @border_mask.reset
77
- @prev_colors.fill(@registers.background)
78
- @prev_fg = GraphicsMode::NO_FG
79
- @prev_fresh = false
80
- @check = true
81
- @color_patches.clear
82
- end
83
-
84
- # The load point for the next group's byte: XSCROLL as a g-access
85
- # column with the border open sees it, a column before the group that
86
- # uses it (VICE x64sc `xscroll_pipe`).
87
- def latch_xscroll(xscroll = @registers.xscroll)
88
- return if xscroll == @xscroll
89
-
90
- @xscroll = xscroll
91
- @check = true
92
- end
93
-
94
- # A write to a register the painted colours depend on: the byte kept
95
- # from the previous group is painted again before its pixels are shown.
96
- def colors_changed!
97
- @prev_fresh = false
98
- @check = true
99
- end
100
-
101
- def apply_color_patches
102
- @color_patches.apply(@colors, @fg)
103
- end
104
-
105
- # The vertical border compares run in every cycle of their line (VICE
106
- # x64sc). The top one resets the flip-flop at once when DEN is set. The
107
- # bottom one only arms it, and the armed state takes hold at the line's
108
- # first cycle and at the left window edge (Bauer §3.9 rules 2-5). The
109
- # VIC calls this after each $d011 write.
110
- def compare_vertical_border(line)
111
- top, bottom = BORDER_Y_BOUNDS[@registers.rsel? ? 1 : 0]
112
- @vertical_armed = true if line == bottom
113
- @vertical_armed = @vertical_border = false if line == top && @registers.display_enabled?
114
- end
115
-
116
- # The line's first cycle, Bauer's cycle 1, which is the last column of
117
- # the line before it.
118
- def start_vertical_border(line)
119
- compare_vertical_border(line)
120
- @vertical_border = @vertical_armed
121
- end
122
-
123
- # The 40-column left compare, a column before the column that draws its
124
- # pixel. The 38-column one runs in the drawing column.
125
- def left_compare_vertical_border
126
- @left_vertical_border = start_vertical_border(@line) if @registers.csel?
127
- end
128
-
129
- def border_at?(pixel_x) = @border_mask.at?(pixel_x)
130
-
131
- # True while the vertical border flip-flop is set and stays set for the
132
- # rest of the line: it can only clear mid-line on a top compare line
133
- # with DEN set.
134
- def vertical_closed?
135
- return false unless @vertical_border
136
- return true unless @line == 51 || @line == 55
137
-
138
- top, = BORDER_Y_BOUNDS[@registers.rsel? ? 1 : 0]
139
- !(@line == top && @registers.display_enabled?)
140
- end
141
-
142
- # Snapshot the finished line so apply_border can restore the border
143
- # pixels sprites were composited over, keeping mid-line border splits.
144
- def snapshot_line = @border_mask.snapshot(@colors)
145
-
146
- # Repaint the border over the composited line, hiding the sprites.
147
- def apply_border = @border_mask.restore(@colors)
148
-
149
- # The g-accesses the VIC hands over, as a ring the column's slot
150
- # indexes: the byte read, the screen byte and the colour nibble. The
151
- # slot before is the byte the previous group loaded.
152
- attr_reader :ring_data, :ring_char, :ring_color
153
-
154
- # The border flip-flops: vertical, the vertical one armed to set, and
155
- # the main one.
156
- def borders = [@vertical_border, @vertical_armed, @main_border]
157
-
158
- def restore_borders(vertical, armed, main)
159
- @vertical_border = vertical
160
- @vertical_armed = armed
161
- @main_border = main
162
- end
163
-
164
- # Paints the byte in the slot through the current mode. An idle access
165
- # latches 0/0 and one that made no access passes on zero data with the
166
- # kept values; under a closed border neither has foreground. A group
167
- # where the mode or the load point changes, and the one after it, run
168
- # the shift register pixel by pixel.
169
- def emit(slot, col, display)
170
- mode = @registers.mode
171
- return emit_checked(slot, col, display, mode) if @check || mode != @last_mode
172
-
173
- paint_slot(slot, mode, display)
174
- output(col, @last_shift)
175
- roll
176
- end
177
-
178
- private
179
-
180
- # The display window's edges per CSEL state, as the region gives them.
181
- # The graphics window always spans the full 40 columns, ignoring CSEL,
182
- # and the border flip-flop takes [left compare, right compare] per
183
- # CSEL state.
184
- def window_bounds(bounds)
185
- narrow, wide = bounds
186
- @gfx_x_start = wide[0]
187
- @gfx_x_end = wide[1] + 1
188
- @window_compares = [
189
- [narrow[0], narrow[1] + 1].freeze,
190
- [@gfx_x_start, @gfx_x_end].freeze
191
- ].freeze
192
- end
193
-
194
- # After a mode, XSCROLL or colour change: groups paint whole bytes
195
- # again once the change has settled, and run pixel by pixel until then.
196
- def emit_checked(slot, col, display, mode)
197
- shift = @xscroll
198
- if mode == @last_mode && shift == @last_shift && !@settling
199
- emit_settled(slot, col, display, mode, shift)
200
- else
201
- emit_pixels(slot, col, mode, shift, !display && border_hidden?)
202
- @settling = mode != @last_mode || shift != @last_shift
203
- @last_mode = mode
204
- @last_shift = shift
205
- end
206
- end
207
-
208
- def emit_settled(slot, col, display, mode, shift)
209
- repaint_previous(mode, (slot - 1) & 3) unless @prev_fresh || shift.zero?
210
- paint_slot(slot, mode, display)
211
- output(col, shift)
212
- roll
213
- @prev_fresh = true
214
- @check = false
215
- end
216
-
217
- def paint_slot(slot, mode, display)
218
- if !display && border_hidden?
219
- @cur_fg = GraphicsMode::NO_FG
220
- else
221
- paint(slot, mode)
222
- end
223
- end
224
-
225
- def repaint_previous(mode, slot)
226
- roll
227
- paint(slot, mode)
228
- roll
229
- end
230
-
231
- def paint(slot, mode)
232
- if @render
233
- MODES[mode].paint(@ring_data[slot], @ring_char[slot], @ring_color[slot], self)
234
- else
235
- @cur_fg = MODES[mode].fg(@ring_data[slot], @ring_char[slot], @ring_color[slot])
236
- end
237
- end
238
-
239
- def emit_pixels(slot, col, mode, shift, hidden)
240
- prime_shifter((slot - 1) & 3) unless @settling
241
- @shifter.draw(hidden ? 0 : @ring_data[slot], @ring_char[slot], @ring_color[slot], shift, mode)
242
- @cur_colors[0, 8] = @shifter.colors
243
- @cur_fg = @shifter.fg
244
- output(col, 0)
245
- @prev_fresh = false
246
- @check = true
247
- end
248
-
249
- # Picks up from a group that painted whole bytes.
250
- def prime_shifter(slot)
251
- @shifter.prime(@ring_data[slot], @ring_char[slot], @ring_color[slot], @last_shift, @last_mode)
252
- end
253
-
254
- # The group is border throughout when the main flip-flop is set and the
255
- # vertical one keeps it from clearing.
256
- def border_hidden? = @main_border && vertical_closed?
257
-
258
- def pixel_shown?(pixel_x, left_compare, right_compare)
259
- @main_border = true if pixel_x == right_compare
260
- @main_border = false if pixel_x == left_compare && !left_vertical_border
261
- !@main_border
262
- end
263
-
264
- def left_vertical_border
265
- @left_vertical_border.nil? ? start_vertical_border(@line) : @left_vertical_border
266
- end
267
-
268
- def roll
269
- @prev_colors, @cur_colors = @cur_colors, @prev_colors
270
- @prev_fg, @cur_fg = @cur_fg, @prev_fg
271
- nil
272
- end
273
- end
274
- end
275
- end
@@ -1,116 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class VIC
5
- class Sequencer
6
- # Writes a column's 8-pixel group into the line buffers, through the
7
- # main border flip-flop and XSCROLL.
8
- module Output
9
- private
10
-
11
- # Write the 8-pixel group for a column into the line buffers. The main
12
- # border flip-flop only changes state in the groups containing the
13
- # window edge compares, so all other groups take a branch-free bulk
14
- # path: fully border or fully window. A group's first pixel, where the
15
- # 40-column compares fall, still sees CSEL as the column before had it.
16
- def output(col, shift)
17
- x_pos = (col + 16) * 8
18
- csel = @registers.csel?
19
- first = @window_compares[@first_csel ? 1 : 0]
20
- @first_csel = csel
21
- compares = @window_compares[csel ? 1 : 0]
22
- win_lo, right_compare = compares
23
-
24
- if !first.equal?(compares) || boundary_group?(x_pos, win_lo, right_compare)
25
- output_boundary(x_pos, first, compares, shift)
26
- elsif @main_border
27
- output_border(x_pos)
28
- else
29
- output_window(x_pos, shift)
30
- end
31
- end
32
-
33
- # True if the group contains a window edge, where the main border
34
- # flip-flop can change state.
35
- def boundary_group?(x_pos, win_lo, right_compare)
36
- lo_delta = win_lo - x_pos
37
- hi_delta = right_compare - x_pos
38
- (lo_delta >= 0 && lo_delta < 8) || (hi_delta >= 0 && hi_delta < 8)
39
- end
40
-
41
- def output_border(x_pos)
42
- @colors.fill(@registers.border, x_pos, 8) if @render
43
- @border_groups[x_pos >> 3] = BorderMask::FULL
44
- @fg.fill(false, x_pos, 8)
45
- end
46
-
47
- def output_window(x_pos, shift)
48
- in_gfx = x_pos >= @gfx_x_start && x_pos < @gfx_x_end
49
- @border_groups[x_pos >> 3] = BorderMask::NONE
50
-
51
- if shift.zero?
52
- @colors[x_pos, 8] = @cur_colors if @render
53
- if in_gfx
54
- @fg[x_pos, 8] = @cur_fg
55
- else
56
- @fg.fill(false, x_pos, 8)
57
- end
58
- else
59
- output_window_shifted(x_pos, in_gfx, shift)
60
- end
61
- end
62
-
63
- def output_window_shifted(x_pos, in_gfx, shift)
64
- keep = 8 - shift
65
-
66
- if @render
67
- copy(@cur_colors, 0, @colors, x_pos + shift, keep)
68
- copy(@prev_colors, keep, @colors, x_pos, shift)
69
- end
70
- output_shifted_fg(x_pos, in_gfx, shift, keep)
71
- end
72
-
73
- def output_shifted_fg(x_pos, in_gfx, shift, keep)
74
- return @fg.fill(false, x_pos, 8) unless in_gfx
75
-
76
- copy(@cur_fg, 0, @fg, x_pos + shift, keep)
77
- copy(@prev_fg, keep, @fg, x_pos, shift)
78
- end
79
-
80
- def copy(src, from, dest, to, count)
81
- i = 0
82
- while i < count
83
- dest[to + i] = src[from + i]
84
- i += 1
85
- end
86
- end
87
-
88
- # Slow path for the groups where the border flip-flop can change state.
89
- def output_boundary(x_pos, first, compares, shift)
90
- border = @registers.border
91
- win_lo, right_compare = first
92
- @border_groups[x_pos >> 3] = BorderMask::MIXED
93
-
94
- i = 0
95
- while i < 8
96
- src = i - shift
97
- if src >= 0
98
- pixel = @cur_colors[src]
99
- mask = @cur_fg[src]
100
- else
101
- pixel = @prev_colors[8 + src]
102
- mask = @prev_fg[8 + src]
103
- end
104
- x = x_pos + i
105
- shown = pixel_shown?(x, win_lo, right_compare)
106
- @colors[x] = shown ? pixel : border
107
- @border[x] = !shown
108
- @fg[x] = x >= @gfx_x_start && x < @gfx_x_end ? mask : false
109
- win_lo, right_compare = compares if i.zero?
110
- i += 1
111
- end
112
- end
113
- end
114
- end
115
- end
116
- end
@@ -1,89 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class VIC
5
- class Sequencer
6
- # The sequencer's save_state and load_state.
7
- module SavedState
8
- FG_SHIFTER = -1
9
- PAIR_CODES = 256
10
-
11
- # The line buffers, the border flip-flops, the g-access ring and the
12
- # pixel pipeline. The foreground masks the groups point at go as
13
- # FG_SHIFTER for the shift register's, or their data byte in
14
- # GraphicsMode's HIRES_FG, or that plus 256 in its PAIR_FG. The left
15
- # vertical border compare goes as -1 before it has run.
16
- def save_state(out)
17
- out.int(@line).boolean(@first_csel).int(@left_vertical_border.nil? ? -1 : bit(@left_vertical_border))
18
- out.blob(@colors).booleans(@fg)
19
- @border_mask.save_state(out)
20
- out.ints(@cur_colors).int(fg_code(@cur_fg)).ints(@prev_colors).int(fg_code(@prev_fg))
21
- out.boolean(@vertical_border).boolean(@vertical_armed).boolean(@main_border)
22
- @color_patches.save_state(out)
23
- @shifter.save_state(out)
24
- out.int(@xscroll).int(@last_shift).int(@last_mode).boolean(@settling).boolean(@prev_fresh).boolean(@check)
25
- out.ints(@ring_data).ints(@ring_char).ints(@ring_color)
26
- end
27
-
28
- def load_state(input)
29
- load_line(input)
30
- @border_mask.load_state(input)
31
- input.ints_into(@cur_colors)
32
- @cur_fg = fg_pattern(input.int)
33
- input.ints_into(@prev_colors)
34
- @prev_fg = fg_pattern(input.int)
35
- @vertical_border = input.boolean?
36
- @vertical_armed = input.boolean?
37
- @main_border = input.boolean?
38
- @color_patches.load_state(input)
39
- @shifter.load_state(input)
40
- load_pipeline(input)
41
- end
42
-
43
- private
44
-
45
- def bit(flag) = flag ? 1 : 0
46
-
47
- def load_line(input)
48
- @line = input.int
49
- @first_csel = input.boolean?
50
- left = input.int
51
- @left_vertical_border = left.negative? ? nil : left == 1
52
- input.blob_into(@colors)
53
- input.booleans_into(@fg)
54
- end
55
-
56
- def load_pipeline(input)
57
- @xscroll = input.int
58
- @last_shift = input.int
59
- @last_mode = input.int
60
- @settling = input.boolean?
61
- @prev_fresh = input.boolean?
62
- @check = input.boolean?
63
- input.ints_into(@ring_data)
64
- input.ints_into(@ring_char)
65
- input.ints_into(@ring_color)
66
- end
67
-
68
- def fg_code(pattern)
69
- return FG_SHIFTER if pattern.equal?(@shifter.fg)
70
-
71
- hires = GraphicsMode::HIRES_FG.index { |fg| fg.equal?(pattern) }
72
- return hires if hires
73
-
74
- pair = GraphicsMode::PAIR_FG.index { |fg| fg.equal?(pattern) }
75
- raise ArgumentError, "a foreground mask the sequencer doesn't know" unless pair
76
-
77
- PAIR_CODES + pair
78
- end
79
-
80
- def fg_pattern(code)
81
- return @shifter.fg if code == FG_SHIFTER
82
- return GraphicsMode::HIRES_FG.fetch(code) if code < PAIR_CODES
83
-
84
- GraphicsMode::PAIR_FG.fetch(code - PAIR_CODES)
85
- end
86
- end
87
- end
88
- end
89
- end
@@ -1,68 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class VIC
5
- class Sprite
6
- # = InternalBus
7
- #
8
- # What a sprite's s-accesses read while its DMA is off. The first and
9
- # third fall in phi2, where the VIC's internal bus floats to $ff unless
10
- # the CPU reads or writes a VIC register in that cycle, and the middle
11
- # one is the idle fetch at $3fff (sbsprf24's readme).
12
- class InternalBus
13
- # The columns of a raster line, and where the region puts the
14
- # sprites in it.
15
- attr_reader :columns, :timing
16
-
17
- def initialize(bank, timing)
18
- @bank = bank
19
- @timing = timing
20
- @columns = timing.columns
21
- @sprite_cycle = timing.sprite_cycle
22
- @lines = 0
23
- @ghost = 0xff
24
- @value = Array.new(columns, 0xff)
25
- @line = Array.new(columns, -1)
26
- end
27
-
28
- def save_state(out)
29
- out.int(@lines).int(@ghost).ints(@value).ints(@line)
30
- end
31
-
32
- def load_state(input)
33
- @lines = input.int
34
- @ghost = input.int
35
- input.ints_into(@value)
36
- input.ints_into(@line)
37
- end
38
-
39
- # Sprites 3-7 fetch in Bauer cycles 1-10, so the idle byte is taken
40
- # as the line starts.
41
- def start_line(sprites_enabled)
42
- @lines += 1
43
- @ghost = @bank.peek(0x3fff) if sprites_enabled
44
- end
45
-
46
- # The VIC has advanced to `column`, so the access runs in Bauer cycle
47
- # `column + 1`, and column 0 is the first cycle of the line about to
48
- # start.
49
- def access(column, value)
50
- @value[column] = value
51
- @line[column] = column.zero? ? @lines + 1 : @lines
52
- end
53
-
54
- # The row sprite `index` (3-7) fetched this line, in the phi2 halves
55
- # of the two cycles from its p-access: Bauer cycles 2n-5 and 2n-4 on
56
- # the 6569.
57
- def row(index)
58
- column = (@sprite_cycle + (2 * index) - 1) % @columns
59
- (phi2(column) << 16) | (@ghost << 8) | phi2(column + 1)
60
- end
61
-
62
- private
63
-
64
- def phi2(column) = @line[column] == @lines ? @value[column] : 0xff
65
- end
66
- end
67
- end
68
- end
@@ -1,64 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class VIC
5
- class Sprite
6
- # The sprite's save_state and load_state.
7
- module SavedState
8
- # The shift register, MC, MCBASE, the expansion flip-flop and whether
9
- # the sprite shows, for a VICE snapshot.
10
- attr_reader :sr, :mc, :mcbase, :exp_ff, :display_on
11
-
12
- # Sets MC, MCBASE, the expansion flip-flop, whether the sprite's DMA
13
- # runs and whether it shows, as a VICE snapshot gives them.
14
- def restore_counters(counter, base, expanded, dma, shows)
15
- @mc = counter
16
- @mcbase = base
17
- @exp_ff = expanded
18
- @dma = dma
19
- @display_on = shows
20
- end
21
-
22
- def save_state(out)
23
- out.boolean(@dma).boolean(@display_on).int(@mcbase).int(@mc).boolean(@exp_ff).optional_int(@crunched_mc)
24
- out.int(@bits).boolean(@row_ready).optional_int(@prev_bits).boolean(@first_byte_lost).boolean(@blind)
25
- out.int(@show_from).optional_int(@stop_x)
26
- out.ints(@codes).int(@leftmost).int(@span).ints(@reload_codes).int(@reload_leftmost).int(@reload_span)
27
- out.int(@sr).int(@latch).boolean(@mc_flop).boolean(@xe_flop)
28
- end
29
-
30
- def load_state(input)
31
- load_counters(input)
32
- @show_from = input.int
33
- @stop_x = input.optional_int
34
- input.ints_into(@codes)
35
- @leftmost = input.int
36
- @span = input.int
37
- input.ints_into(@reload_codes)
38
- @reload_leftmost = input.int
39
- @reload_span = input.int
40
- @sr = input.int
41
- @latch = input.int
42
- @mc_flop = input.boolean?
43
- @xe_flop = input.boolean?
44
- end
45
-
46
- private
47
-
48
- def load_counters(input)
49
- @dma = input.boolean?
50
- @display_on = input.boolean?
51
- @mcbase = input.int
52
- @mc = input.int
53
- @exp_ff = input.boolean?
54
- @crunched_mc = input.optional_int
55
- @bits = input.int
56
- @row_ready = input.boolean?
57
- @prev_bits = input.optional_int
58
- @first_byte_lost = input.boolean?
59
- @blind = input.boolean?
60
- end
61
- end
62
- end
63
- end
64
- end