badline 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (516) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/CLAUDE.md +59 -31
  4. data/README.md +1 -1
  5. data/doc/library.md +9 -9
  6. data/doc/pinned-behaviour.md +105 -105
  7. data/doc/snapshots.md +1 -4
  8. data/lib/badline/audio/bare_player.rb +4 -4
  9. data/lib/badline/audio/cli.rb +6 -6
  10. data/lib/badline/audio/jukebox.rb +2 -2
  11. data/lib/badline/audio/machine_player.rb +2 -2
  12. data/lib/badline/{media → audio}/queue.rb +1 -1
  13. data/lib/badline/audio/queued_tune.rb +6 -6
  14. data/lib/badline/audio/renderer.rb +5 -5
  15. data/lib/badline/audio/stereo.rb +1 -1
  16. data/lib/badline/c128/{bus_state.rb → bus/saved_state.rb} +6 -6
  17. data/lib/badline/c128/bus.rb +30 -51
  18. data/lib/badline/c128/color_lines.rb +2 -2
  19. data/lib/badline/c128/cpu.rb +1 -1
  20. data/lib/badline/c128/drives.rb +10 -11
  21. data/lib/badline/c128/fast_serial.rb +5 -5
  22. data/lib/badline/c128/mmu_pages.rb +1 -1
  23. data/lib/badline/c128/modes.rb +2 -2
  24. data/lib/badline/c128/saved_state.rb +21 -47
  25. data/lib/badline/c128/z80.rb +2 -2
  26. data/lib/badline/c128.rb +18 -72
  27. data/lib/badline/{computer → c64}/attachments.rb +16 -47
  28. data/lib/badline/c64/banked_ram/banking.rb +32 -0
  29. data/lib/badline/c64/banked_ram/plus256k.rb +56 -0
  30. data/lib/badline/c64/banked_ram/plus60k.rb +45 -0
  31. data/lib/badline/c64/banked_ram/unexpanded.rb +30 -0
  32. data/lib/badline/c64/banked_ram.rb +23 -0
  33. data/lib/badline/c64/bus/extra_sids.rb +32 -0
  34. data/lib/badline/c64/bus/fittings.rb +40 -0
  35. data/lib/badline/c64/bus/pla.rb +149 -0
  36. data/lib/badline/c64/bus/roms.rb +41 -0
  37. data/lib/badline/c64/bus/saved_state.rb +68 -0
  38. data/lib/badline/c64/bus/sid_slots.rb +44 -0
  39. data/lib/badline/c64/bus.rb +218 -0
  40. data/lib/badline/c64/cartridge/action_replay.rb +128 -0
  41. data/lib/badline/c64/cartridge/atomic_power.rb +26 -0
  42. data/lib/badline/c64/cartridge/bank.rb +83 -0
  43. data/lib/badline/c64/cartridge/comal80.rb +52 -0
  44. data/lib/badline/c64/cartridge/dinamic.rb +36 -0
  45. data/lib/badline/c64/cartridge/easy_flash.rb +147 -0
  46. data/lib/badline/c64/cartridge/epyx_fastload.rb +81 -0
  47. data/lib/badline/c64/cartridge/final_cartridge3.rb +91 -0
  48. data/lib/badline/c64/cartridge/flash/saved_state.rb +40 -0
  49. data/lib/badline/c64/cartridge/flash.rb +279 -0
  50. data/lib/badline/c64/cartridge/freezer.rb +35 -0
  51. data/lib/badline/c64/cartridge/fun_play.rb +40 -0
  52. data/lib/badline/c64/cartridge/g_mod2.rb +76 -0
  53. data/lib/badline/c64/cartridge/game_system.rb +42 -0
  54. data/lib/badline/c64/cartridge/geo_ram.rb +81 -0
  55. data/lib/badline/c64/cartridge/kcs_power.rb +77 -0
  56. data/lib/badline/c64/cartridge/mach5.rb +34 -0
  57. data/lib/badline/c64/cartridge/magic_desk.rb +32 -0
  58. data/lib/badline/c64/cartridge/ocean.rb +37 -0
  59. data/lib/badline/c64/cartridge/pagefox.rb +70 -0
  60. data/lib/badline/c64/cartridge/retro_replay/saved_state.rb +47 -0
  61. data/lib/badline/c64/cartridge/retro_replay.rb +286 -0
  62. data/lib/badline/c64/cartridge/rex_utility.rb +31 -0
  63. data/lib/badline/c64/cartridge/rgcd.rb +60 -0
  64. data/lib/badline/c64/cartridge/saved_state.rb +63 -0
  65. data/lib/badline/c64/cartridge/simons_basic.rb +37 -0
  66. data/lib/badline/c64/cartridge/standard.rb +17 -0
  67. data/lib/badline/c64/cartridge/super_games.rb +50 -0
  68. data/lib/badline/c64/cartridge/westermann.rb +32 -0
  69. data/lib/badline/c64/cartridge/zaxxon.rb +68 -0
  70. data/lib/badline/c64/cartridge.rb +258 -0
  71. data/lib/badline/c64/color_memory.rb +27 -0
  72. data/lib/badline/c64/common.rb +34 -0
  73. data/lib/badline/c64/kernal_traps.rb +89 -0
  74. data/lib/badline/c64/reu/dma/saved_state.rb +52 -0
  75. data/lib/badline/c64/reu/dma.rb +275 -0
  76. data/lib/badline/c64/reu/ram.rb +109 -0
  77. data/lib/badline/c64/reu/saved_state.rb +55 -0
  78. data/lib/badline/c64/reu/trigger.rb +34 -0
  79. data/lib/badline/c64/reu.rb +291 -0
  80. data/lib/badline/{computer → c64}/saved_state.rb +13 -18
  81. data/lib/badline/{computer → c64}/true_drives.rb +20 -31
  82. data/lib/badline/{computer.rb → c64.rb} +22 -80
  83. data/lib/badline/chips/cia/fast_forward.rb +62 -0
  84. data/lib/badline/chips/cia/interrupt_register.rb +145 -0
  85. data/lib/badline/chips/cia/saved_state.rb +49 -0
  86. data/lib/badline/chips/cia/serial/saved_state.rb +45 -0
  87. data/lib/badline/chips/cia/serial.rb +250 -0
  88. data/lib/badline/chips/cia/time_of_day.rb +232 -0
  89. data/lib/badline/chips/cia/timer.rb +208 -0
  90. data/lib/badline/chips/cia.rb +281 -0
  91. data/lib/badline/chips/cpu/addressing.rb +133 -0
  92. data/lib/badline/chips/cpu/boundary.rb +56 -0
  93. data/lib/badline/chips/cpu/core.rb +167 -0
  94. data/lib/badline/chips/cpu/instruction.rb +338 -0
  95. data/lib/badline/chips/cpu/instruction_set/arithmetic.rb +118 -0
  96. data/lib/badline/chips/cpu/instruction_set/bitwise.rb +130 -0
  97. data/lib/badline/chips/cpu/instruction_set/branch.rb +83 -0
  98. data/lib/badline/chips/cpu/instruction_set/flag.rb +67 -0
  99. data/lib/badline/chips/cpu/instruction_set/illegal.rb +274 -0
  100. data/lib/badline/chips/cpu/instruction_set/inc_dec.rb +73 -0
  101. data/lib/badline/chips/cpu/instruction_set/stack.rb +56 -0
  102. data/lib/badline/chips/cpu/instruction_set/transfer.rb +141 -0
  103. data/lib/badline/chips/cpu/instruction_set.rb +59 -0
  104. data/lib/badline/chips/cpu/interrupts.rb +108 -0
  105. data/lib/badline/chips/cpu/microcode.rb +179 -0
  106. data/lib/badline/chips/cpu/operations.rb +90 -0
  107. data/lib/badline/chips/cpu/port.rb +116 -0
  108. data/lib/badline/chips/cpu/saved_state.rb +117 -0
  109. data/lib/badline/chips/cpu/stack_operations.rb +84 -0
  110. data/lib/badline/chips/cpu/traps.rb +23 -0
  111. data/lib/badline/chips/cpu.rb +12 -0
  112. data/lib/badline/chips/sid/catch_up.rb +122 -0
  113. data/lib/badline/chips/sid/decimator.rb +66 -0
  114. data/lib/badline/chips/sid/envelope/saved_state.rb +70 -0
  115. data/lib/badline/chips/sid/envelope.rb +241 -0
  116. data/lib/badline/chips/sid/filter/saved_state.rb +42 -0
  117. data/lib/badline/chips/sid/filter.rb +241 -0
  118. data/lib/badline/chips/sid/saved_state.rb +52 -0
  119. data/lib/badline/chips/sid/voice.rb +79 -0
  120. data/lib/badline/chips/sid/waveform/combined.rb +128 -0
  121. data/lib/badline/chips/sid/waveform/fast_forward.rb +107 -0
  122. data/lib/badline/chips/sid/waveform/noise_writeback.rb +124 -0
  123. data/lib/badline/chips/sid/waveform/saved_state.rb +68 -0
  124. data/lib/badline/chips/sid/waveform.rb +307 -0
  125. data/lib/badline/chips/sid.rb +265 -0
  126. data/lib/badline/{c128 → chips}/vdc/memory.rb +1 -1
  127. data/lib/badline/{c128 → chips}/vdc/painter.rb +1 -1
  128. data/lib/badline/{c128 → chips}/vdc/raster.rb +1 -1
  129. data/lib/badline/chips/vdc/saved_state.rb +36 -0
  130. data/lib/badline/{c128 → chips}/vdc/window.rb +1 -1
  131. data/lib/badline/{c128 → chips}/vdc.rb +7 -31
  132. data/lib/badline/chips/via/control_lines.rb +124 -0
  133. data/lib/badline/chips/via/fast_forward.rb +55 -0
  134. data/lib/badline/chips/via/interrupt_register.rb +69 -0
  135. data/lib/badline/chips/via/saved_state.rb +44 -0
  136. data/lib/badline/chips/via/shift_register.rb +182 -0
  137. data/lib/badline/chips/via/timer1.rb +133 -0
  138. data/lib/badline/chips/via/timer2.rb +135 -0
  139. data/lib/badline/chips/via.rb +268 -0
  140. data/lib/badline/chips/vic/bank.rb +135 -0
  141. data/lib/badline/chips/vic/border_mask.rb +88 -0
  142. data/lib/badline/chips/vic/collisions.rb +117 -0
  143. data/lib/badline/chips/vic/color_patches.rb +49 -0
  144. data/lib/badline/chips/vic/display_state.rb +187 -0
  145. data/lib/badline/chips/vic/graphics_mode.rb +166 -0
  146. data/lib/badline/chips/vic/graphics_shifter/saved_state.rb +40 -0
  147. data/lib/badline/chips/vic/graphics_shifter.rb +187 -0
  148. data/lib/badline/chips/vic/register_log.rb +83 -0
  149. data/lib/badline/chips/vic/registers.rb +197 -0
  150. data/lib/badline/chips/vic/saved_state.rb +82 -0
  151. data/lib/badline/chips/vic/sequencer/saved_state.rb +91 -0
  152. data/lib/badline/chips/vic/sequencer.rb +277 -0
  153. data/lib/badline/chips/vic/sequencer_output.rb +118 -0
  154. data/lib/badline/chips/vic/sprite/internal_bus.rb +70 -0
  155. data/lib/badline/chips/vic/sprite/saved_state.rb +66 -0
  156. data/lib/badline/chips/vic/sprite/shifter.rb +148 -0
  157. data/lib/badline/chips/vic/sprite/timing.rb +58 -0
  158. data/lib/badline/chips/vic/sprite.rb +339 -0
  159. data/lib/badline/chips/vic/sprites/saved_state.rb +59 -0
  160. data/lib/badline/chips/vic/sprites.rb +284 -0
  161. data/lib/badline/chips/vic.rb +783 -0
  162. data/lib/badline/chips/vic_i/painter/saved_state.rb +40 -0
  163. data/lib/badline/{vic20/vic → chips/vic_i}/painter.rb +6 -30
  164. data/lib/badline/{vic20/vic → chips/vic_i}/saved_state.rb +2 -2
  165. data/lib/badline/chips/vic_i/sound/output.rb +85 -0
  166. data/lib/badline/chips/vic_i/sound.rb +235 -0
  167. data/lib/badline/{vic20/vic → chips/vic_i}/text_window.rb +2 -2
  168. data/lib/badline/{vic20/vic.rb → chips/vic_i.rb} +5 -5
  169. data/lib/badline/chips/z80/arithmetic.rb +119 -0
  170. data/lib/badline/chips/z80/bit_page.rb +57 -0
  171. data/lib/badline/chips/z80/block_io.rb +60 -0
  172. data/lib/badline/chips/z80/block_transfers.rb +61 -0
  173. data/lib/badline/chips/z80/bus_cycles.rb +113 -0
  174. data/lib/badline/chips/z80/core.rb +115 -0
  175. data/lib/badline/chips/z80/exchanges.rb +52 -0
  176. data/lib/badline/chips/z80/extended_page.rb +91 -0
  177. data/lib/badline/chips/z80/flags.rb +39 -0
  178. data/lib/badline/chips/z80/interrupt_acceptance.rb +48 -0
  179. data/lib/badline/chips/z80/jumps.rb +84 -0
  180. data/lib/badline/chips/z80/loads.rb +100 -0
  181. data/lib/badline/chips/z80/main_page.rb +136 -0
  182. data/lib/badline/chips/z80/registers.rb +122 -0
  183. data/lib/badline/chips/z80/saved_state.rb +71 -0
  184. data/lib/badline/chips/z80/shifts.rb +66 -0
  185. data/lib/badline/chips/z80.rb +13 -0
  186. data/lib/badline/core.rb +27 -29
  187. data/lib/badline/drives/datasette/saved_state.rb +37 -0
  188. data/lib/badline/drives/datasette.rb +140 -0
  189. data/lib/badline/drives/engine/core.rb +149 -0
  190. data/lib/badline/drives/engine/fast_serial.rb +75 -0
  191. data/lib/badline/drives/engine/idle.rb +127 -0
  192. data/lib/badline/drives/engine/idle_cpu.rb +30 -0
  193. data/lib/badline/drives/engine/orbit.rb +81 -0
  194. data/lib/badline/drives/engine/serial_lines.rb +75 -0
  195. data/lib/badline/drives/engine/sleep.rb +114 -0
  196. data/lib/badline/drives/engine/vias.rb +86 -0
  197. data/lib/badline/drives/engine/watch.rb +152 -0
  198. data/lib/badline/drives/engine.rb +11 -0
  199. data/lib/badline/drives/model1541/bus.rb +88 -0
  200. data/lib/badline/drives/model1541/byte_ready.rb +50 -0
  201. data/lib/badline/drives/model1541/cpu.rb +13 -0
  202. data/lib/badline/drives/model1541/disk/saved_state.rb +88 -0
  203. data/lib/badline/drives/model1541/disk.rb +317 -0
  204. data/lib/badline/drives/model1541/disk_via.rb +38 -0
  205. data/lib/badline/drives/model1541/gcr.rb +59 -0
  206. data/lib/badline/drives/model1541/mechanism/saved_state.rb +72 -0
  207. data/lib/badline/drives/model1541/mechanism.rb +315 -0
  208. data/lib/badline/drives/model1541/rotation.rb +123 -0
  209. data/lib/badline/drives/model1541/saved_state.rb +44 -0
  210. data/lib/badline/drives/model1541/sector_reader.rb +78 -0
  211. data/lib/badline/drives/model1541/serial_port.rb +20 -0
  212. data/lib/badline/drives/model1541/track.rb +100 -0
  213. data/lib/badline/drives/model1541.rb +81 -0
  214. data/lib/badline/drives/model1571/bus.rb +113 -0
  215. data/lib/badline/drives/model1571/cpu.rb +13 -0
  216. data/lib/badline/drives/model1571/saved_state.rb +47 -0
  217. data/lib/badline/drives/model1571/serial_port.rb +39 -0
  218. data/lib/badline/drives/model1571/serial_via.rb +27 -0
  219. data/lib/badline/drives/model1571/wd1770.rb +122 -0
  220. data/lib/badline/drives/model1571.rb +142 -0
  221. data/lib/badline/drives/model1581/bus.rb +139 -0
  222. data/lib/badline/drives/model1581/cpu.rb +13 -0
  223. data/lib/badline/drives/model1581/disk/saved_state.rb +89 -0
  224. data/lib/badline/drives/model1581/disk.rb +137 -0
  225. data/lib/badline/drives/model1581/mechanism.rb +119 -0
  226. data/lib/badline/drives/model1581/saved_state.rb +42 -0
  227. data/lib/badline/drives/model1581/serial_port.rb +54 -0
  228. data/lib/badline/drives/model1581/slot.rb +79 -0
  229. data/lib/badline/drives/model1581/track.rb +102 -0
  230. data/lib/badline/drives/model1581/track_bytes.rb +77 -0
  231. data/lib/badline/drives/model1581/wd1772/registers.rb +91 -0
  232. data/lib/badline/drives/model1581/wd1772/saved_state.rb +68 -0
  233. data/lib/badline/drives/model1581/wd1772/sector_writes.rb +75 -0
  234. data/lib/badline/drives/model1581/wd1772/sectors.rb +152 -0
  235. data/lib/badline/drives/model1581/wd1772/stepping.rb +111 -0
  236. data/lib/badline/drives/model1581/wd1772/tracks.rb +127 -0
  237. data/lib/badline/drives/model1581/wd1772/turn.rb +75 -0
  238. data/lib/badline/drives/model1581/wd1772.rb +218 -0
  239. data/lib/badline/drives/model1581.rb +206 -0
  240. data/lib/badline/drives/serial_bus.rb +161 -0
  241. data/lib/badline/frontend/boot.rb +10 -61
  242. data/lib/badline/frontend/machine_window.rb +3 -1
  243. data/lib/badline/frontend/player/filter_view.rb +1 -1
  244. data/lib/badline/frontend/player/player_controller.rb +2 -2
  245. data/lib/badline/frontend/player/player_screen.rb +1 -0
  246. data/lib/badline/frontend/player/theme.rb +7 -7
  247. data/lib/badline/frontend/timeline.rb +3 -3
  248. data/lib/badline/input/control_ports.rb +78 -0
  249. data/lib/badline/input/joystick.rb +27 -0
  250. data/lib/badline/input/keyboard.rb +114 -0
  251. data/lib/badline/input.rb +3 -0
  252. data/lib/badline/kernal_trap/{drive → dos}/block_commands.rb +1 -1
  253. data/lib/badline/kernal_trap/dos/channel.rb +183 -0
  254. data/lib/badline/kernal_trap/{drive → dos}/channels.rb +1 -1
  255. data/lib/badline/kernal_trap/{drive → dos}/memory.rb +1 -1
  256. data/lib/badline/kernal_trap/{drive → dos}/parameters.rb +1 -1
  257. data/lib/badline/kernal_trap/{drive → dos}/status.rb +1 -1
  258. data/lib/badline/kernal_trap/{drive → dos}/write_file.rb +1 -1
  259. data/lib/badline/kernal_trap/{drive → dos}/writes.rb +1 -1
  260. data/lib/badline/kernal_trap/{drive.rb → dos.rb} +11 -10
  261. data/lib/badline/kernal_trap/{file.rb → file_routine.rb} +1 -1
  262. data/lib/badline/kernal_trap/load.rb +6 -6
  263. data/lib/badline/kernal_trap/save.rb +5 -5
  264. data/lib/badline/kernal_trap/serial.rb +7 -7
  265. data/lib/badline/kernal_trap.rb +2 -3
  266. data/lib/badline/machine/clocking.rb +50 -0
  267. data/lib/badline/machine.rb +63 -7
  268. data/lib/badline/media/boot_disk.rb +2 -2
  269. data/lib/badline/media/disk_list.rb +3 -3
  270. data/lib/badline/media/disk_set.rb +1 -1
  271. data/lib/badline/media/extensions.rb +33 -0
  272. data/lib/badline/media/program.rb +28 -0
  273. data/lib/badline/media/true_drive.rb +4 -3
  274. data/lib/badline/media/tune.rb +35 -0
  275. data/lib/badline/media/vic20_cartridge.rb +1 -7
  276. data/lib/badline/media/vic20_media.rb +38 -80
  277. data/lib/badline/media.rb +84 -81
  278. data/lib/badline/model.rb +1 -1
  279. data/lib/badline/options/event.rb +3 -1
  280. data/lib/badline/roms/README +6 -6
  281. data/lib/badline/sdl.rb +1 -0
  282. data/lib/badline/{storage/sid_file.rb → sid_tune/file.rb} +3 -3
  283. data/lib/badline/{storage → sid_tune}/hvsc.rb +7 -7
  284. data/lib/badline/{storage → sid_tune}/song_lengths.rb +2 -2
  285. data/lib/badline/{storage → sid_tune}/stil/credit.rb +1 -1
  286. data/lib/badline/{storage → sid_tune}/stil.rb +3 -3
  287. data/lib/badline/sid_tune.rb +6 -0
  288. data/lib/badline/snapshot/c128_setup.rb +43 -0
  289. data/lib/badline/snapshot/c64_setup.rb +79 -0
  290. data/lib/badline/snapshot/image.rb +5 -25
  291. data/lib/badline/snapshot/machine_state.rb +10 -2
  292. data/lib/badline/snapshot/setup.rb +22 -66
  293. data/lib/badline/snapshot/state.rb +8 -17
  294. data/lib/badline/snapshot/storage_setup.rb +68 -0
  295. data/lib/badline/snapshot/vic20_setup.rb +37 -0
  296. data/lib/badline/snapshot/vice/c64_mem.rb +1 -1
  297. data/lib/badline/snapshot/vice/restore.rb +1 -1
  298. data/lib/badline/snapshot/vice/reu1764.rb +1 -1
  299. data/lib/badline/snapshot/vice/reu_fields.rb +40 -0
  300. data/lib/badline/snapshot/vice.rb +7 -5
  301. data/lib/badline/snapshot.rb +13 -12
  302. data/lib/badline/storage/d64_image.rb +15 -9
  303. data/lib/badline/storage/d71_image.rb +0 -2
  304. data/lib/badline/storage/d81_image.rb +0 -2
  305. data/lib/badline/storage/disk_image/writing.rb +2 -2
  306. data/lib/badline/storage/disk_image.rb +3 -6
  307. data/lib/badline/storage/g64_image.rb +2 -2
  308. data/lib/badline/storage/host_directory.rb +0 -5
  309. data/lib/badline/storage/t64.rb +2 -8
  310. data/lib/badline/storage/unavailable.rb +1 -1
  311. data/lib/badline/storage.rb +0 -37
  312. data/lib/badline/support/c128_checkpoint.rb +39 -0
  313. data/lib/badline/support/checkpoint.rb +108 -0
  314. data/lib/badline/support/vic20_checkpoint.rb +38 -0
  315. data/lib/badline/support.rb +5 -0
  316. data/lib/badline/version.rb +1 -1
  317. data/lib/badline/vic20/attachments.rb +11 -81
  318. data/lib/badline/vic20/bus/saved_state.rb +35 -0
  319. data/lib/badline/vic20/bus.rb +3 -25
  320. data/lib/badline/vic20/cpu.rb +1 -1
  321. data/lib/badline/vic20/port_wiring.rb +4 -4
  322. data/lib/badline/vic20/saved_state.rb +16 -60
  323. data/lib/badline/vic20/user_via_ports.rb +2 -2
  324. data/lib/badline/vic20.rb +20 -51
  325. metadata +250 -221
  326. data/lib/badline/address_bus/extra_sids.rb +0 -30
  327. data/lib/badline/address_bus/fittings.rb +0 -38
  328. data/lib/badline/address_bus/pla.rb +0 -147
  329. data/lib/badline/address_bus/roms.rb +0 -39
  330. data/lib/badline/address_bus/saved_state.rb +0 -72
  331. data/lib/badline/address_bus/sid_slots.rb +0 -42
  332. data/lib/badline/address_bus.rb +0 -235
  333. data/lib/badline/cartridge/action_replay.rb +0 -126
  334. data/lib/badline/cartridge/atomic_power.rb +0 -24
  335. data/lib/badline/cartridge/bank.rb +0 -81
  336. data/lib/badline/cartridge/comal80.rb +0 -50
  337. data/lib/badline/cartridge/dinamic.rb +0 -34
  338. data/lib/badline/cartridge/easy_flash.rb +0 -145
  339. data/lib/badline/cartridge/epyx_fastload.rb +0 -79
  340. data/lib/badline/cartridge/final_cartridge3.rb +0 -89
  341. data/lib/badline/cartridge/flash.rb +0 -306
  342. data/lib/badline/cartridge/freezer.rb +0 -33
  343. data/lib/badline/cartridge/fun_play.rb +0 -38
  344. data/lib/badline/cartridge/g_mod2.rb +0 -74
  345. data/lib/badline/cartridge/game_system.rb +0 -40
  346. data/lib/badline/cartridge/geo_ram.rb +0 -79
  347. data/lib/badline/cartridge/kcs_power.rb +0 -75
  348. data/lib/badline/cartridge/mach5.rb +0 -32
  349. data/lib/badline/cartridge/magic_desk.rb +0 -30
  350. data/lib/badline/cartridge/ocean.rb +0 -35
  351. data/lib/badline/cartridge/pagefox.rb +0 -68
  352. data/lib/badline/cartridge/retro_replay.rb +0 -320
  353. data/lib/badline/cartridge/rex_utility.rb +0 -29
  354. data/lib/badline/cartridge/rgcd.rb +0 -58
  355. data/lib/badline/cartridge/simons_basic.rb +0 -35
  356. data/lib/badline/cartridge/standard.rb +0 -15
  357. data/lib/badline/cartridge/super_games.rb +0 -48
  358. data/lib/badline/cartridge/westermann.rb +0 -30
  359. data/lib/badline/cartridge/zaxxon.rb +0 -66
  360. data/lib/badline/cartridge.rb +0 -303
  361. data/lib/badline/checkpoint.rb +0 -98
  362. data/lib/badline/cia/fast_forward.rb +0 -60
  363. data/lib/badline/cia/interrupt_register.rb +0 -143
  364. data/lib/badline/cia/serial.rb +0 -275
  365. data/lib/badline/cia/state.rb +0 -47
  366. data/lib/badline/cia/timer.rb +0 -206
  367. data/lib/badline/cia.rb +0 -279
  368. data/lib/badline/color_memory.rb +0 -25
  369. data/lib/badline/computer/kernal_traps.rb +0 -29
  370. data/lib/badline/control_ports.rb +0 -76
  371. data/lib/badline/cpu/addressing.rb +0 -131
  372. data/lib/badline/cpu/boundary.rb +0 -54
  373. data/lib/badline/cpu/core.rb +0 -165
  374. data/lib/badline/cpu/microcode.rb +0 -177
  375. data/lib/badline/cpu/operations.rb +0 -88
  376. data/lib/badline/cpu/saved_state.rb +0 -115
  377. data/lib/badline/cpu/stack_operations.rb +0 -82
  378. data/lib/badline/cpu.rb +0 -10
  379. data/lib/badline/cycleable.rb +0 -38
  380. data/lib/badline/datasette.rb +0 -161
  381. data/lib/badline/drive/core.rb +0 -147
  382. data/lib/badline/drive/fast_serial.rb +0 -73
  383. data/lib/badline/drive/idle.rb +0 -125
  384. data/lib/badline/drive/idle_cpu.rb +0 -28
  385. data/lib/badline/drive/orbit.rb +0 -79
  386. data/lib/badline/drive/serial_lines.rb +0 -73
  387. data/lib/badline/drive/sleep.rb +0 -112
  388. data/lib/badline/drive/vias.rb +0 -84
  389. data/lib/badline/drive/watch.rb +0 -150
  390. data/lib/badline/drive.rb +0 -11
  391. data/lib/badline/drive1541/bus.rb +0 -86
  392. data/lib/badline/drive1541/byte_ready.rb +0 -48
  393. data/lib/badline/drive1541/cpu.rb +0 -11
  394. data/lib/badline/drive1541/disk.rb +0 -318
  395. data/lib/badline/drive1541/disk_state.rb +0 -94
  396. data/lib/badline/drive1541/disk_via.rb +0 -36
  397. data/lib/badline/drive1541/gcr.rb +0 -57
  398. data/lib/badline/drive1541/mechanism.rb +0 -313
  399. data/lib/badline/drive1541/mechanism_state.rb +0 -68
  400. data/lib/badline/drive1541/rotation.rb +0 -121
  401. data/lib/badline/drive1541/sector_reader.rb +0 -76
  402. data/lib/badline/drive1541/serial_port.rb +0 -18
  403. data/lib/badline/drive1541/track.rb +0 -98
  404. data/lib/badline/drive1541.rb +0 -111
  405. data/lib/badline/drive1571/bus.rb +0 -111
  406. data/lib/badline/drive1571/cpu.rb +0 -11
  407. data/lib/badline/drive1571/serial_port.rb +0 -37
  408. data/lib/badline/drive1571/serial_via.rb +0 -25
  409. data/lib/badline/drive1571/wd1770.rb +0 -120
  410. data/lib/badline/drive1571.rb +0 -175
  411. data/lib/badline/drive1581/bus.rb +0 -137
  412. data/lib/badline/drive1581/cpu.rb +0 -11
  413. data/lib/badline/drive1581/disk.rb +0 -135
  414. data/lib/badline/drive1581/disk_state.rb +0 -87
  415. data/lib/badline/drive1581/mechanism.rb +0 -117
  416. data/lib/badline/drive1581/serial_port.rb +0 -52
  417. data/lib/badline/drive1581/slot.rb +0 -78
  418. data/lib/badline/drive1581/track.rb +0 -100
  419. data/lib/badline/drive1581/track_bytes.rb +0 -75
  420. data/lib/badline/drive1581/wd1772/registers.rb +0 -89
  421. data/lib/badline/drive1581/wd1772/sector_writes.rb +0 -73
  422. data/lib/badline/drive1581/wd1772/sectors.rb +0 -150
  423. data/lib/badline/drive1581/wd1772/state.rb +0 -66
  424. data/lib/badline/drive1581/wd1772/stepping.rb +0 -109
  425. data/lib/badline/drive1581/wd1772/tracks.rb +0 -125
  426. data/lib/badline/drive1581/wd1772/turn.rb +0 -73
  427. data/lib/badline/drive1581/wd1772.rb +0 -216
  428. data/lib/badline/drive1581.rb +0 -233
  429. data/lib/badline/iec_bus.rb +0 -159
  430. data/lib/badline/instruction.rb +0 -334
  431. data/lib/badline/instruction_set/arithmetic.rb +0 -114
  432. data/lib/badline/instruction_set/bitwise.rb +0 -126
  433. data/lib/badline/instruction_set/branch.rb +0 -79
  434. data/lib/badline/instruction_set/flag.rb +0 -63
  435. data/lib/badline/instruction_set/illegal.rb +0 -270
  436. data/lib/badline/instruction_set/inc_dec.rb +0 -69
  437. data/lib/badline/instruction_set/stack.rb +0 -52
  438. data/lib/badline/instruction_set/transfer.rb +0 -137
  439. data/lib/badline/instruction_set.rb +0 -55
  440. data/lib/badline/interrupts.rb +0 -104
  441. data/lib/badline/joystick.rb +0 -25
  442. data/lib/badline/kernal_trap/channel.rb +0 -181
  443. data/lib/badline/keyboard.rb +0 -112
  444. data/lib/badline/ram_expansion/banking.rb +0 -30
  445. data/lib/badline/ram_expansion/plus256k.rb +0 -54
  446. data/lib/badline/ram_expansion/plus60k.rb +0 -43
  447. data/lib/badline/ram_expansion/unexpanded.rb +0 -28
  448. data/lib/badline/ram_expansion.rb +0 -21
  449. data/lib/badline/reu/dma/saved_state.rb +0 -50
  450. data/lib/badline/reu/dma.rb +0 -273
  451. data/lib/badline/reu/ram.rb +0 -107
  452. data/lib/badline/reu/saved_state.rb +0 -80
  453. data/lib/badline/reu/trigger.rb +0 -32
  454. data/lib/badline/reu.rb +0 -289
  455. data/lib/badline/sid/catch_up.rb +0 -120
  456. data/lib/badline/sid/decimator.rb +0 -64
  457. data/lib/badline/sid/envelope/state.rb +0 -68
  458. data/lib/badline/sid/envelope.rb +0 -239
  459. data/lib/badline/sid/filter.rb +0 -263
  460. data/lib/badline/sid/voice.rb +0 -77
  461. data/lib/badline/sid/waveform/combined.rb +0 -126
  462. data/lib/badline/sid/waveform/fast_forward.rb +0 -105
  463. data/lib/badline/sid/waveform/noise_writeback.rb +0 -122
  464. data/lib/badline/sid/waveform/state.rb +0 -66
  465. data/lib/badline/sid/waveform.rb +0 -305
  466. data/lib/badline/sid.rb +0 -303
  467. data/lib/badline/time_of_day.rb +0 -228
  468. data/lib/badline/traps.rb +0 -19
  469. data/lib/badline/via/control_lines.rb +0 -122
  470. data/lib/badline/via/fast_forward.rb +0 -53
  471. data/lib/badline/via/interrupt_register.rb +0 -67
  472. data/lib/badline/via/shift_register.rb +0 -180
  473. data/lib/badline/via/state.rb +0 -42
  474. data/lib/badline/via/timer1.rb +0 -131
  475. data/lib/badline/via/timer2.rb +0 -133
  476. data/lib/badline/via.rb +0 -266
  477. data/lib/badline/vic/bank.rb +0 -133
  478. data/lib/badline/vic/border_mask.rb +0 -86
  479. data/lib/badline/vic/collisions.rb +0 -115
  480. data/lib/badline/vic/color_patches.rb +0 -47
  481. data/lib/badline/vic/display_state.rb +0 -185
  482. data/lib/badline/vic/graphics_mode.rb +0 -164
  483. data/lib/badline/vic/graphics_shifter.rb +0 -207
  484. data/lib/badline/vic/register_log.rb +0 -81
  485. data/lib/badline/vic/registers.rb +0 -195
  486. data/lib/badline/vic/sequencer.rb +0 -275
  487. data/lib/badline/vic/sequencer_output.rb +0 -116
  488. data/lib/badline/vic/sequencer_state.rb +0 -89
  489. data/lib/badline/vic/sprite/internal_bus.rb +0 -68
  490. data/lib/badline/vic/sprite/saved_state.rb +0 -64
  491. data/lib/badline/vic/sprite/shifter.rb +0 -146
  492. data/lib/badline/vic/sprite/timing.rb +0 -56
  493. data/lib/badline/vic/sprite.rb +0 -337
  494. data/lib/badline/vic/sprites.rb +0 -282
  495. data/lib/badline/vic/sprites_state.rb +0 -57
  496. data/lib/badline/vic.rb +0 -852
  497. data/lib/badline/vic20/sound/output.rb +0 -83
  498. data/lib/badline/vic20/sound.rb +0 -233
  499. data/lib/badline/z80/arithmetic.rb +0 -117
  500. data/lib/badline/z80/bit_page.rb +0 -55
  501. data/lib/badline/z80/block_io.rb +0 -58
  502. data/lib/badline/z80/block_transfers.rb +0 -59
  503. data/lib/badline/z80/bus_cycles.rb +0 -111
  504. data/lib/badline/z80/core.rb +0 -113
  505. data/lib/badline/z80/exchanges.rb +0 -50
  506. data/lib/badline/z80/extended_page.rb +0 -89
  507. data/lib/badline/z80/flags.rb +0 -37
  508. data/lib/badline/z80/interrupt_acceptance.rb +0 -46
  509. data/lib/badline/z80/jumps.rb +0 -82
  510. data/lib/badline/z80/loads.rb +0 -98
  511. data/lib/badline/z80/main_page.rb +0 -134
  512. data/lib/badline/z80/registers.rb +0 -120
  513. data/lib/badline/z80/saved_state.rb +0 -69
  514. data/lib/badline/z80/shifts.rb +0 -64
  515. data/lib/badline/z80.rb +0 -11
  516. /data/lib/badline/snapshot/{fields.rb → vice/fields.rb} +0 -0
@@ -1,195 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class VIC < Cycleable
5
- # = VIC-II Registers
6
- #
7
- # == Sprite positions
8
- #
9
- # $D000: Sprite 0 X
10
- # $D001: Sprite 0 Y
11
- # $D002: Sprite 1 X
12
- # $D003: Sprite 1 Y
13
- # $D004: Sprite 2 X
14
- # $D005: Sprite 2 Y
15
- # $D006: Sprite 3 X
16
- # $D007: Sprite 3 Y
17
- # $D008: Sprite 4 X
18
- # $D009: Sprite 4 Y
19
- # $D00A: Sprite 5 X
20
- # $D00B: Sprite 5 Y
21
- # $D00C: Sprite 6 X
22
- # $D00D: Sprite 6 Y
23
- # $D00E: Sprite 7 X
24
- # $D00F: Sprite 7 Y
25
- #
26
- # $D010: Most Significant Bits of Sprites 0-7 Horizontal Position
27
- # $D011: Vertical Fine Scrolling and Control Register
28
- # $D012: Rasterline
29
- # - Read: Current rasterline
30
- # - Write: Set rasterline interrupt
31
- #
32
- # == Light pen
33
- #
34
- # $D013: Light Pen Horizontal Position
35
- # $D014: Light Pen Vertical Position
36
- #
37
- # $D015: Sprite Enable Register
38
- # $D016: Horizontal Fine Scrolling and Control Register
39
- # $D017: Sprite Vertical Expansion Register
40
- # $D018: VIC-II Chip Memory Control Register
41
- # $D019: VIC Interrupt Flag Register
42
- # $D01A: IRQ Mask Register
43
- # $D01B: Sprite to Foreground Display Priority Register
44
- # $D01C: Sprite Multicolor Registers
45
- # $D01D: Sprite Horizontal Expansion Register
46
- #
47
- # == Sprite collision detection
48
- #
49
- # $D01E: Sprite to Sprite Collision Register
50
- # $D01F: Sprite to Foreground Collision Register
51
- #
52
- # == Color registers
53
- #
54
- # All color registers are 4bit, bits 4-7 always read 1.
55
- #
56
- # $D020: Border color
57
- # $D021: Background color 0
58
- # $D022: Background color 1
59
- # $D023: Background color 2
60
- # $D024: Background color 3
61
- # $D025: Sprite multicolor 0
62
- # $D026: Sprite multicolor 1
63
- # $D027: Sprite 0 color
64
- # $D028: Sprite 1 color
65
- # $D029: Sprite 2 color
66
- # $D02A: Sprite 3 color
67
- # $D02B: Sprite 4 color
68
- # $D02C: Sprite 5 color
69
- # $D02D: Sprite 6 color
70
- # $D02E: Sprite 7 color
71
- #
72
- # == VIC-IIe (8566 and 8564)
73
- #
74
- # $D02F: Extra keyboard lines K0-K2 in bits 0-2, bits 3-7 read 1
75
- # $D030: FAST (2 MHz) in bit 0 and TEST in bit 1, bits 2-7 read 1
76
- #
77
- # $D02F-$D03F: Not in use on the 6569 and 8565, always reads 0xff,
78
- # and $D031-$D03F on the VIC-IIe
79
- # $D040-$D3FF: Repeat $D0000 to $D03F every 64 bytes
80
- class Registers
81
- include IntegerHelper
82
-
83
- # The raw register bytes, for the per-column reads on the hot path.
84
- attr_reader :bytes
85
-
86
- # Every register powers on as zero, as in VICE. A VIC-IIe reads
87
- # $D02F and $D030 back as registers.
88
- def initialize(iie: false)
89
- @bytes = Array.new(2**6, 0)
90
- @irq_line = false
91
- @iie = iie
92
- end
93
-
94
- # True while any enabled latch bit is set in $D019/$D01A. Cached and
95
- # re-evaluated on writes, since it's checked every cycle.
96
- def irq_line? = @irq_line
97
-
98
- def [](reg) = @bytes[reg]
99
-
100
- def read(reg)
101
- case reg
102
- when 0x16 then @bytes[reg] | 0xc0 # bits 7-6 unused, read 1
103
- when 0x18 then @bytes[reg] | 0x01 # bit 0 unused, reads 1
104
- when 0x1a, 0x20..0x2e then @bytes[reg] | 0xf0
105
- when 0x1e, 0x1f then read_clear(reg) # collision registers clear on read
106
- when 0x2f then @iie ? @bytes[reg] | 0xf8 : 0xff
107
- when 0x30 then @iie ? @bytes[reg] | 0xfc : 0xff
108
- when 0x31..0x3f then 0xff
109
- else @bytes[reg]
110
- end
111
- end
112
-
113
- def write(reg, value)
114
- case reg
115
- when 0x19 # write 1 to clear
116
- @bytes[reg] &= ~value
117
- update_irq_line
118
- when 0x1a # only the four latch bits
119
- @bytes[reg] = value & 0x0f
120
- update_irq_line
121
- when 0x1e, 0x1f then nil # the collision registers are read-only
122
- else @bytes[reg] = value
123
- end
124
- end
125
-
126
- # Graphics modes
127
- def ecm = @bytes[0x11][6]
128
- def bmm = @bytes[0x11][5]
129
- def mcm = @bytes[0x16][4]
130
- # ECM/BMM from $D011 bits 6-5, MCM from $D016 bit 4.
131
- def mode = ((@bytes[0x11] >> 4) & 0b110) | ((@bytes[0x16] >> 4) & 0b001)
132
-
133
- def xscroll = @bytes[0x16] & 0b0111
134
- def yscroll = @bytes[0x11] & 0b0111
135
-
136
- def rsel? = @bytes[0x11].anybits?(0x08)
137
- def csel? = @bytes[0x16].anybits?(0x08)
138
- def display_enabled? = @bytes[0x11].anybits?(0x10)
139
-
140
- def char_base = (@bytes[0x18] & 0b1110) * 0x400
141
- def bitmap_base = (@bytes[0x18] & 0b1000) * 0x400
142
- def screen_base = (@bytes[0x18] >> 4) * 0x400
143
-
144
- def border = @bytes[0x20] & 0x0f
145
- def background(index = 0) = @bytes[0x21 + index] & 0x0f
146
-
147
- # The VIC-IIe's $D02F and $D030 bits. The 6569 and 8565 drive no
148
- # extra keyboard lines and run at 1 MHz.
149
- def extra_keyboard_lines = @iie ? @bytes[0x2f] & 0x07 : 0x07
150
- def fast? = @iie && @bytes[0x30].anybits?(0x01)
151
- def test? = @iie && @bytes[0x30].anybits?(0x02)
152
-
153
- # FAST and TEST as bits 0 and 1.
154
- def clock_bits = @iie ? @bytes[0x30] & 0x03 : 0
155
-
156
- def raster_target = uint16(@bytes[0x12], (@bytes[0x11] & 0x80) >> 7)
157
-
158
- def latch_irq!(bit)
159
- @bytes[0x19] |= bit
160
- update_irq_line
161
- end
162
-
163
- def latch_raster_irq! = latch_irq!(0x01)
164
-
165
- def save_state(out)
166
- out.blob(@bytes).boolean(@irq_line)
167
- end
168
-
169
- def load_state(input)
170
- input.blob_into(@bytes)
171
- @irq_line = input.boolean?
172
- end
173
-
174
- def collide!(reg, bits)
175
- return false if bits.zero?
176
-
177
- was_zero = @bytes[reg].zero?
178
- @bytes[reg] |= bits
179
- was_zero
180
- end
181
-
182
- # Works the IRQ line out from $D019 and $D01A again, after the bytes
183
- # were set directly.
184
- def update_irq_line
185
- @irq_line = (@bytes[0x19] & @bytes[0x1a]).anybits?(0x0f)
186
- end
187
-
188
- private
189
-
190
- def read_clear(reg)
191
- @bytes[reg].tap { @bytes[reg] = 0 }
192
- end
193
- end
194
- end
195
- end
@@ -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 < Cycleable
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 < Cycleable
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 < Cycleable
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