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
data/lib/badline/via.rb DELETED
@@ -1,266 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "badline/via/control_lines"
4
- require "badline/via/fast_forward"
5
- require "badline/via/interrupt_register"
6
- require "badline/via/shift_register"
7
- require "badline/via/state"
8
- require "badline/via/timer1"
9
- require "badline/via/timer2"
10
-
11
- module Badline
12
- # VIA (Versatile Interface Adapter): the MOS 6522, two ports with
13
- # handshake lines, two timers and a shift register. The 1541 has two.
14
- #
15
- # Sixteen registers repeat across a 1 KB window. The control pins take
16
- # levels from outside through ca1= and friends, and PB6 takes its pulses
17
- # for timer 2 through pb6= alone: the peripheral's port B input doesn't
18
- # feed the counter.
19
- class VIA
20
- include Addressable
21
- include FastForward
22
- include State
23
-
24
- attr_reader :start, :peripheral, :shift_register, :acr, :pcr
25
-
26
- def timer1 = @t1.counter
27
-
28
- def timer1_latch = @t1.latch
29
-
30
- def timer2 = @t2.counter
31
-
32
- def interrupt_flags = @ifr.read
33
-
34
- def interrupt_enable = @ifr.read_enable
35
-
36
- def initialize(start: 0, peripheral: nil)
37
- addressable_at(start, length: 2**10)
38
-
39
- @peripheral = peripheral
40
- @t1 = Timer1.new
41
- @t2 = Timer2.new
42
- @shift_register = ShiftRegister.new
43
- @ifr = InterruptRegister.new
44
- @ca = ControlLines.new(@ifr, c1_flag: InterruptRegister::CA1, c2_flag: InterruptRegister::CA2,
45
- handshake_on_read: true)
46
- @cb = ControlLines.new(@ifr, c1_flag: InterruptRegister::CB1, c2_flag: InterruptRegister::CB2,
47
- handshake_on_read: false)
48
- @pb6_high = true
49
- @acr = 0x00
50
- reset!
51
- end
52
-
53
- # The RES line clears every register but the timers and the shift
54
- # register, which carry on counting, and so releases IRQ.
55
- def reset!
56
- @ora = @orb = @ddra = @ddrb = 0x00
57
- @latch_a = @latch_b = 0xff
58
- @ifr.reset!
59
- @ca.reset!
60
- @cb.reset!
61
- write_acr(0x00)
62
- @pcr = 0x00
63
- end
64
-
65
- def irq? = @ifr.irq?
66
-
67
- def cycle!
68
- @ca.cycle! if @ca.pulsing?
69
- @cb.cycle! if @cb.pulsing?
70
- @ifr.set(InterruptRegister::TIMER1) if @t1.cycle!(@acr.anybits?(0x40))
71
- @ifr.set(InterruptRegister::TIMER2) if @t2.cycle!(@sr_uses_t2)
72
- @ifr.set(InterruptRegister::SR) if @shift_register.cycle!(@t2.low_underflowed)
73
- end
74
-
75
- # Port A as driven by ORA and DDRA, input lines floating high.
76
- def port_a_output = driven_lines(@ora, @ddra)
77
-
78
- # Port B as driven by ORB and DDRB, with PB7 handed to timer 1 by ACR
79
- # bit 7.
80
- def port_b_output
81
- lines = driven_lines(@orb, @ddrb)
82
- return lines unless @acr.anybits?(0x80)
83
-
84
- @t1.pb7 ? lines | 0x80 : lines & 0x7f
85
- end
86
-
87
- # An active CA1 edge latches port A while ACR bit 0 is set.
88
- def ca1=(high)
89
- return if high == @ca.c1_high
90
-
91
- @latch_a = pins_a if @acr.anybits?(0x01) && @ca.active_c1_edge?(high)
92
- @ca.c1 = high
93
- end
94
-
95
- def ca2=(high)
96
- @ca.c2 = high
97
- end
98
-
99
- # An active CB1 edge latches port B while ACR bit 1 is set. CB1 also
100
- # clocks the shift register in its external clock modes.
101
- def cb1=(high)
102
- return if high == @cb.c1_high
103
-
104
- @ifr.set(InterruptRegister::SR) if @shift_register.cb1_edge!(high)
105
- @latch_b = pins_b if @acr.anybits?(0x02) && @cb.active_c1_edge?(high)
106
- @cb.c1 = high
107
- end
108
-
109
- def cb2=(high)
110
- @shift_register.cb2_input = high
111
- @cb.c2 = high
112
- end
113
-
114
- # A falling edge counts a pulse while timer 2 counts them.
115
- def pb6=(high)
116
- fell = @pb6_high && !high
117
- @pb6_high = high
118
- @ifr.set(InterruptRegister::TIMER2) if fell && @t2.pulse!
119
- end
120
-
121
- def ca2_output = @ca.c2_output
122
-
123
- # The shift register's clock on CB1, or nil when CB1 is an input.
124
- def cb1_output = @shift_register.cb1_output
125
-
126
- # The shift register takes CB2 over in its shift-out modes.
127
- def cb2_output
128
- level = @shift_register.cb2_output
129
- level.nil? ? @cb.c2_output : level
130
- end
131
-
132
- def peek(addr)
133
- case offset_of(addr) & 0x0f
134
- when 0x00 then read_port_b
135
- when 0x01 then read_port_a(handshake: true)
136
- when 0x02 then @ddrb
137
- when 0x03 then @ddra
138
- when 0x04 then read_timer_low(@t1.counter, InterruptRegister::TIMER1)
139
- when 0x05 then high_byte(@t1.counter)
140
- when 0x06 then low_byte(@t1.latch)
141
- when 0x07 then high_byte(@t1.latch)
142
- when 0x08 then read_timer_low(@t2.counter, InterruptRegister::TIMER2)
143
- when 0x09 then high_byte(@t2.counter)
144
- when 0x0a then read_shift_register
145
- when 0x0b then @acr
146
- when 0x0c then @pcr
147
- when 0x0d then @ifr.read
148
- when 0x0e then @ifr.read_enable
149
- else read_port_a(handshake: false)
150
- end
151
- end
152
-
153
- def poke(addr, value)
154
- case offset_of(addr) & 0x0f
155
- when 0x00 then write_port_b(value)
156
- when 0x01 then write_port_a(value, handshake: true)
157
- when 0x02 then @ddrb = value
158
- when 0x03 then @ddra = value
159
- when 0x04, 0x06 then @t1.write_latch_low(value)
160
- when 0x05 then write_timer1_high(value, start: true)
161
- when 0x07 then write_timer1_high(value, start: false)
162
- when 0x08 then @t2.latch_low = value
163
- when 0x09 then write_timer2_high(value)
164
- when 0x0a then write_shift_register(value)
165
- when 0x0b then write_acr(value)
166
- when 0x0c then write_pcr(value)
167
- when 0x0d then @ifr.write(value)
168
- when 0x0e then @ifr.write_enable(value)
169
- else write_port_a(value, handshake: false)
170
- end
171
- end
172
-
173
- private
174
-
175
- # Output bits are driven from the data register; input bits float high.
176
- # External peripherals can still pull any line low (wired-AND).
177
- def driven_lines(register, direction)
178
- (register & direction) | (~direction & 0xff)
179
- end
180
-
181
- def pins_a
182
- lines = port_a_output
183
- peripheral ? lines & peripheral.read_a(lines) : lines
184
- end
185
-
186
- def pins_b
187
- lines = port_b_output
188
- peripheral ? lines & peripheral.read_b(lines) : lines
189
- end
190
-
191
- # Port A reads the pins, or what CA1 latched off them.
192
- def read_port_a(handshake:)
193
- value = @acr.anybits?(0x01) ? @latch_a : pins_a
194
- @ca.access!(false) if handshake
195
- value
196
- end
197
-
198
- def write_port_a(value, handshake:)
199
- @ora = value
200
- @ca.access!(true) if handshake
201
- end
202
-
203
- # Port B reads its output bits from ORB, or from timer 1 for PB7, and
204
- # its input bits from the pins, or from what CB1 latched off them.
205
- def read_port_b
206
- outputs = @acr.anybits?(0x80) ? @ddrb | 0x80 : @ddrb
207
- inputs = @acr.anybits?(0x02) ? @latch_b : pins_b
208
- @cb.access!(false)
209
- (port_b_output & outputs) | (inputs & ~outputs & 0xff)
210
- end
211
-
212
- def write_port_b(value)
213
- @orb = value
214
- @cb.access!(true)
215
- end
216
-
217
- # A read of either timer's low counter byte acknowledges its interrupt.
218
- def read_timer_low(counter, flag)
219
- @ifr.clear(flag)
220
- low_byte(counter)
221
- end
222
-
223
- # $5 loads and starts the counter; $7 only writes the latch. Both
224
- # acknowledge the interrupt.
225
- def write_timer1_high(value, start:)
226
- @t1.write_latch_high(value)
227
- @t1.start! if start
228
- @ifr.clear(InterruptRegister::TIMER1)
229
- end
230
-
231
- def write_timer2_high(value)
232
- @t2.load(value)
233
- @ifr.clear(InterruptRegister::TIMER2)
234
- end
235
-
236
- def read_shift_register
237
- value = @shift_register.data
238
- @shift_register.access!
239
- @ifr.clear(InterruptRegister::SR)
240
- value
241
- end
242
-
243
- def write_shift_register(value)
244
- @shift_register.data = value
245
- @shift_register.access!
246
- @ifr.clear(InterruptRegister::SR)
247
- end
248
-
249
- # Bits 4-2 pick the shift register's mode. Modes 1, 4 and 5 clock off
250
- # timer 2's low byte. Bit 7 turning on hands PB7 to timer 1 high.
251
- def write_acr(value)
252
- @t1.pb7_enabled! if value.anybits?(0x80) && @acr.nobits?(0x80)
253
- @acr = value
254
- @t2.count_pulses = value.anybits?(0x20)
255
- mode = (value >> 2) & 0x07
256
- @shift_register.mode = mode
257
- @sr_uses_t2 = [1, 4, 5].include?(mode)
258
- end
259
-
260
- def write_pcr(value)
261
- @pcr = value
262
- @ca.control = value & 0x0f
263
- @cb.control = value >> 4
264
- end
265
- end
266
- end
@@ -1,133 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class VIC < Cycleable
5
- # The 16K window the VIC sees into RAM, selected by CIA2 $DD00, in the
6
- # bank a +256K picks for it. Character
7
- # ROM shadows $1000-$1FFF in banks 0 and 2.
8
- #
9
- # The machine's bus pushes in what the VIC sees through #connect,
10
- # #map_character_rom and #map whenever it changes. Until then the bank
11
- # has a CIA 2, RAM, colour RAM and character ROM of its own.
12
- class Bank
13
- include Addressable
14
-
15
- # The CIA2 port A bank bits are inverted: %11 selects bank 0.
16
- BANK_STARTS = [0xc000, 0x8000, 0x4000, 0x0000].freeze
17
-
18
- attr_reader :ram, :color_ram
19
-
20
- # The bank lines as #sample_lines last saw them.
21
- attr_accessor :lines
22
-
23
- def initialize(vic)
24
- addressable_at(0x0000, length: 2**14)
25
- connect(cia2: CIA.new(start: 0xdd00), color_ram: ColorMemory.new(vic))
26
- map_character_rom(ROM.load("character.rom", 0xd000))
27
- @base = 0
28
- @starts = BANK_STARTS
29
- map(Memory.new([], length: 2**16, start: 0))
30
- @lines = 0b11
31
- @swapped = false
32
- end
33
-
34
- # CIA 2, whose port A picks the bank, and the colour RAM, read from
35
- # the address +color_base+ gives offset 0.
36
- def connect(cia2:, color_ram:, color_base: 0xd800)
37
- @cia2 = cia2
38
- @color_ram = color_ram
39
- @color_base = color_base
40
- end
41
-
42
- # The character ROM, read from the address +base+ gives offset 0. It
43
- # shows in the banks whose low line is high, unless +shadow+ is false.
44
- def map_character_rom(rom, base: 0xc000, shadow: true)
45
- @character_rom = rom
46
- @character_base = base
47
- @shadow_mask = shadow ? 0b01 : 0b00
48
- end
49
-
50
- # The RAM the VIC's 64K starts at +base+ in, and the cartridge's
51
- # Ultimax lines in each half of the cycle with the ROMH bank they
52
- # show.
53
- def map(ram, base: 0, phi1_ultimax: false, ultimax: false, romh: nil)
54
- @ram = ram
55
- unless base == @base
56
- @base = base
57
- @starts = BANK_STARTS.map { |start| base + start }.freeze
58
- end
59
- @phi1_ultimax = phi1_ultimax
60
- @ultimax = ultimax
61
- @romh = romh
62
- end
63
-
64
- # On the 8565, a port A write that swaps the two bank lines, driving
65
- # one high as the other goes low, shows the VIC both lines low for the
66
- # cycle after it: every access in that cycle reads bank 3. A swap that
67
- # the DDR makes, releasing a line to float high, shows nothing.
68
- # Called once a cycle, ahead of the cycle's accesses.
69
- def sample_lines
70
- lines = @cia2.port_a_lines & 0b11
71
- @swapped = swap?(@lines, lines) && @cia2.port_registers[2].allbits?(0b11)
72
- @lines = lines
73
- end
74
-
75
- def peek(offset)
76
- return ultimax_peek(offset) if @phi1_ultimax
77
-
78
- bits = bank_switch_register
79
- if (bits & @shadow_mask) == 0b01 && (offset & 0xf000) == 0x1000
80
- @character_rom.peek(@character_base + offset)
81
- else
82
- @ram.peek(@starts[bits] + offset)
83
- end
84
- end
85
-
86
- # A fetch in the second half of the cycle, the c-access, sees the
87
- # memory configuration the CPU does in that half. No cartridge drives
88
- # Ultimax mode in the first half alone, so otherwise it reads as #peek.
89
- def peek_phi2(offset)
90
- @ultimax ? ultimax_peek(offset) : peek(offset)
91
- end
92
-
93
- def peek_color(offset)
94
- @color_ram.nibble(@color_base + offset)
95
- end
96
-
97
- def poke(_addr, _value)
98
- raise ReadOnlyMemoryError
99
- end
100
-
101
- # True if the VIC reads the character ROM at this offset.
102
- def character_rom?(offset)
103
- !@phi1_ultimax && (bank_switch_register & @shadow_mask) == 0b01 && (offset & 0xf000) == 0x1000
104
- end
105
-
106
- def start
107
- BANK_STARTS[bank_switch_register]
108
- end
109
-
110
- private
111
-
112
- # In Ultimax mode the cartridge ROMH replaces the character ROM
113
- # shadow, visible at $3000-$3FFF of the window. The MAX is in
114
- # Ultimax mode with no cartridge too.
115
- def ultimax_peek(offset)
116
- romh = @romh
117
- if romh && offset.allbits?(0x3000)
118
- romh.peek(0xe000 + (offset & 0x1fff))
119
- else
120
- @ram.peek(@starts[bank_switch_register] + offset)
121
- end
122
- end
123
-
124
- def swap?(from, to) = (from ^ to) == 0b11 && from.anybits?(0b11) && to.anybits?(0b11)
125
-
126
- def bank_switch_register
127
- return 0 if @swapped
128
-
129
- @cia2.port_a_lines & 0b11
130
- end
131
- end
132
- end
133
- end
@@ -1,86 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class VIC < Cycleable
5
- # Border coverage per 8-pixel group, tracked as the sequencer outputs
6
- # a line.
7
- #
8
- # The border is repainted over composited sprites from a snapshot of
9
- # the finished line, which keeps mid-line border color splits intact.
10
- class BorderMask
11
- FULL = 0
12
- NONE = 1
13
- MIXED = 2
14
-
15
- # The group table and per-pixel mask are exposed so the sequencer's
16
- # pixel loops can write them without a method call per column.
17
- attr_reader :groups, :mask
18
-
19
- def initialize(width)
20
- @width = width
21
- @groups = Array.new(width / 8, FULL)
22
- @mask = Array.new(width, true)
23
- @snapshot = Array.new(width, 0)
24
- end
25
-
26
- def reset
27
- @groups.fill(FULL)
28
- end
29
-
30
- def save_state(out)
31
- out.ints(@groups).booleans(@mask).blob(@snapshot)
32
- end
33
-
34
- def load_state(input)
35
- input.ints_into(@groups)
36
- input.booleans_into(@mask)
37
- input.blob_into(@snapshot)
38
- end
39
-
40
- def at?(pixel_x)
41
- case @groups[pixel_x >> 3]
42
- when FULL then true
43
- when MIXED then @mask[pixel_x]
44
- else false
45
- end
46
- end
47
-
48
- def snapshot(colors)
49
- @snapshot[0, @width] = colors
50
- end
51
-
52
- def restore(colors)
53
- group = 0
54
- while group < @groups.length
55
- case @groups[group]
56
- when FULL then group = restore_full(colors, group)
57
- when MIXED then restore_mixed(colors, group * 8)
58
- end
59
- group += 1
60
- end
61
- end
62
-
63
- private
64
-
65
- # Copies a run of full-border groups in one splice and returns its
66
- # last group.
67
- def restore_full(colors, first)
68
- last = first
69
- last += 1 while @groups[last + 1] == FULL
70
- x_pos = first * 8
71
- length = (last - first + 1) * 8
72
- colors[x_pos, length] = @snapshot[x_pos, length]
73
- last
74
- end
75
-
76
- def restore_mixed(colors, x_pos)
77
- i = 0
78
- while i < 8
79
- x = x_pos + i
80
- colors[x] = @snapshot[x] if @mask[x]
81
- i += 1
82
- end
83
- end
84
- end
85
- end
86
- end
@@ -1,115 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class VIC < Cycleable
5
- # = Sprite collisions
6
- #
7
- # The $D01E/$D01F latches and the per-pixel sprite coverage that feeds
8
- # them. Collisions latch as the beam passes each covered pixel, so a
9
- # read mid-line sees the pixels drawn before the reading cycle and none
10
- # of the ones after it.
11
- class Collisions
12
- # $D019 latch bits raised by the collision registers.
13
- SPRITE_COLLISION_IRQ = 0x04 # IMMC, mirrors $D01E
14
- DATA_COLLISION_IRQ = 0x02 # IMBC, mirrors $D01F
15
-
16
- # A read holds the register's reset asserted past the cycle that
17
- # issued it, so the pixels drawn under it never reach the register.
18
- # The read still reports only the pixels drawn before its own cycle,
19
- # which is why the two numbers do not cancel out.
20
- CLEAR_OVERRUN = 12
21
-
22
- # The pixel the last fold reached, so the sprites know whether a read
23
- # has anything left to latch.
24
- attr_reader :folded
25
-
26
- # One bitmask per pixel of the line, written straight by the sprite
27
- # merge and read back here and by the composite.
28
- attr_reader :hits
29
-
30
- def initialize(registers, width)
31
- @registers = registers
32
- @width = width
33
- @hits = Array.new(width, 0)
34
- @folded = 0
35
- @cleared_sprite = 0
36
- @cleared_data = 0
37
- end
38
-
39
- def save_state(out)
40
- out.blob(@hits).int(@folded).int(@cleared_sprite).int(@cleared_data)
41
- end
42
-
43
- def load_state(input)
44
- input.blob_into(@hits)
45
- @folded = input.int
46
- @cleared_sprite = input.int
47
- @cleared_data = input.int
48
- end
49
-
50
- def start_line
51
- @folded = 0
52
- @cleared_sprite = carry(@cleared_sprite)
53
- @cleared_data = carry(@cleared_data)
54
- end
55
-
56
- # Latch every covered pixel between the last fold and the beam. The
57
- # sprites' touched span bounds the scan; the coverage is zero outside
58
- # it either way.
59
- def fold(mask, upto, low, high)
60
- from = [@folded, low].max
61
- @folded = upto
62
- scan(mask, from, [upto, high].min)
63
- end
64
-
65
- # A read resets its register for the pixels that follow the reading
66
- # cycle as well as for everything before it.
67
- def clear(reg, beam_x)
68
- if reg == 0x1e
69
- @cleared_sprite = beam_x + CLEAR_OVERRUN
70
- else
71
- @cleared_data = beam_x + CLEAR_OVERRUN
72
- end
73
- end
74
-
75
- private
76
-
77
- # Two or more sprites on a pixel collide with each other; any sprite
78
- # over a foreground pixel collides with the graphics. Pixels still
79
- # under a read's reset are dropped rather than latched.
80
- def scan(mask, from, upto)
81
- sprite_clash = 0
82
- data_clash = 0
83
- pos = from
84
- while pos < upto
85
- bits = @hits[pos]
86
- unless bits.zero?
87
- sprite_clash |= bits if pos >= @cleared_sprite && bits.anybits?(bits - 1)
88
- data_clash |= bits if pos >= @cleared_data && mask[pos]
89
- end
90
- pos += 1
91
- end
92
- latch(sprite_clash, data_clash)
93
- end
94
-
95
- def latch(sprite_clash, data_clash)
96
- latch_one(0x1e, sprite_clash, SPRITE_COLLISION_IRQ)
97
- latch_one(0x1f, data_clash, DATA_COLLISION_IRQ)
98
- end
99
-
100
- # The IRQ is raised on the edge out of an empty register, so a
101
- # collision folded on top of an unread one raises nothing.
102
- def latch_one(reg, clash, irq)
103
- return if clash.zero?
104
- return unless @registers.collide!(reg, clash)
105
-
106
- @registers.latch_irq!(irq)
107
- end
108
-
109
- # A reset still asserted at the line wrap carries into the new line.
110
- def carry(cleared)
111
- cleared > @width ? cleared - @width : 0
112
- end
113
- end
114
- end
115
- end
@@ -1,47 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class VIC < Cycleable
5
- # A mid-line color register write becomes visible one pixel into the
6
- # column emitted the cycle after the write. That emit paints the whole
7
- # column with the new color, so the boundary pixel is patched back to
8
- # the old one before the line is finished. On the 8565 the boundary
9
- # pixel shows light grey instead, the grey dot, whatever the old and new
10
- # colors are.
11
- class ColorPatches
12
- def initialize(sequencer, grey_dots: false)
13
- @sequencer = sequencer
14
- @grey_dots = grey_dots
15
- @patches = []
16
- end
17
-
18
- def clear = @patches.clear
19
-
20
- # Each patch as its four numbers: the boundary pixel, the register,
21
- # the old colour and the new.
22
- def save_state(out)
23
- out.int(@patches.length)
24
- @patches.each { |patch| out.ints(patch) }
25
- end
26
-
27
- def load_state(input)
28
- @patches.replace(Array.new(input.int) { input.ints })
29
- end
30
-
31
- def log(reg, old, value, boundary_x)
32
- @patches << [boundary_x, reg, @grey_dots ? GREY_DOT : old & 0x0f, value & 0x0f]
33
- end
34
-
35
- def apply(colors, fg_mask)
36
- @patches.each do |(x, reg, old, value)|
37
- border = @sequencer.border_at?(x)
38
- if reg == 0x20
39
- colors[x] = old if border
40
- elsif !border && !fg_mask[x] && colors[x] == value
41
- colors[x] = old
42
- end
43
- end
44
- end
45
- end
46
- end
47
- end