badline 0.12.1 → 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 (505) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -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 +3 -3
  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} +1 -1
  17. data/lib/badline/c128/bus.rb +18 -17
  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 +14 -9
  27. data/lib/badline/{computer → c64}/attachments.rb +4 -6
  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/{computer → c64}/common.rb +2 -2
  73. data/lib/badline/{computer → c64}/kernal_traps.rb +18 -18
  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 +11 -11
  82. data/lib/badline/{computer.rb → c64.rb} +18 -13
  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 +26 -28
  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 +3 -3
  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/load.rb +5 -5
  262. data/lib/badline/kernal_trap/save.rb +4 -4
  263. data/lib/badline/kernal_trap/serial.rb +7 -7
  264. data/lib/badline/kernal_trap.rb +1 -2
  265. data/lib/badline/machine/clocking.rb +1 -1
  266. data/lib/badline/machine.rb +5 -5
  267. data/lib/badline/media/true_drive.rb +1 -1
  268. data/lib/badline/media/tune.rb +2 -2
  269. data/lib/badline/media.rb +3 -3
  270. data/lib/badline/model.rb +1 -1
  271. data/lib/badline/roms/README +6 -6
  272. data/lib/badline/sdl.rb +1 -0
  273. data/lib/badline/{storage/sid_file.rb → sid_tune/file.rb} +3 -3
  274. data/lib/badline/{storage → sid_tune}/hvsc.rb +7 -7
  275. data/lib/badline/{storage → sid_tune}/song_lengths.rb +2 -2
  276. data/lib/badline/{storage → sid_tune}/stil/credit.rb +1 -1
  277. data/lib/badline/{storage → sid_tune}/stil.rb +3 -3
  278. data/lib/badline/sid_tune.rb +6 -0
  279. data/lib/badline/snapshot/c128_setup.rb +43 -0
  280. data/lib/badline/snapshot/c64_setup.rb +79 -0
  281. data/lib/badline/snapshot/image.rb +5 -25
  282. data/lib/badline/snapshot/machine_state.rb +1 -1
  283. data/lib/badline/snapshot/setup.rb +22 -66
  284. data/lib/badline/snapshot/state.rb +8 -18
  285. data/lib/badline/snapshot/storage_setup.rb +68 -0
  286. data/lib/badline/snapshot/vic20_setup.rb +37 -0
  287. data/lib/badline/snapshot/vice/c64_mem.rb +1 -1
  288. data/lib/badline/snapshot/vice/restore.rb +1 -1
  289. data/lib/badline/snapshot/vice/reu1764.rb +1 -1
  290. data/lib/badline/snapshot/vice/reu_fields.rb +40 -0
  291. data/lib/badline/snapshot/vice.rb +7 -5
  292. data/lib/badline/snapshot.rb +3 -4
  293. data/lib/badline/storage/d64_image.rb +0 -2
  294. data/lib/badline/storage/d71_image.rb +0 -2
  295. data/lib/badline/storage/d81_image.rb +0 -2
  296. data/lib/badline/storage/disk_image.rb +3 -6
  297. data/lib/badline/storage/g64_image.rb +2 -2
  298. data/lib/badline/storage/host_directory.rb +0 -5
  299. data/lib/badline/storage/t64.rb +2 -8
  300. data/lib/badline/storage/unavailable.rb +1 -1
  301. data/lib/badline/storage.rb +0 -37
  302. data/lib/badline/support/c128_checkpoint.rb +39 -0
  303. data/lib/badline/support/checkpoint.rb +108 -0
  304. data/lib/badline/support/vic20_checkpoint.rb +38 -0
  305. data/lib/badline/support.rb +5 -0
  306. data/lib/badline/version.rb +1 -1
  307. data/lib/badline/vic20/attachments.rb +5 -5
  308. data/lib/badline/vic20/bus/saved_state.rb +35 -0
  309. data/lib/badline/vic20/bus.rb +3 -25
  310. data/lib/badline/vic20/cpu.rb +1 -1
  311. data/lib/badline/vic20/port_wiring.rb +4 -4
  312. data/lib/badline/vic20/saved_state.rb +16 -30
  313. data/lib/badline/vic20/user_via_ports.rb +2 -2
  314. data/lib/badline/vic20.rb +19 -14
  315. metadata +245 -221
  316. data/lib/badline/address_bus/extra_sids.rb +0 -30
  317. data/lib/badline/address_bus/fittings.rb +0 -38
  318. data/lib/badline/address_bus/pla.rb +0 -147
  319. data/lib/badline/address_bus/roms.rb +0 -39
  320. data/lib/badline/address_bus/saved_state.rb +0 -66
  321. data/lib/badline/address_bus/sid_slots.rb +0 -42
  322. data/lib/badline/address_bus.rb +0 -216
  323. data/lib/badline/cartridge/action_replay.rb +0 -126
  324. data/lib/badline/cartridge/atomic_power.rb +0 -24
  325. data/lib/badline/cartridge/bank.rb +0 -81
  326. data/lib/badline/cartridge/comal80.rb +0 -50
  327. data/lib/badline/cartridge/dinamic.rb +0 -34
  328. data/lib/badline/cartridge/easy_flash.rb +0 -145
  329. data/lib/badline/cartridge/epyx_fastload.rb +0 -79
  330. data/lib/badline/cartridge/final_cartridge3.rb +0 -89
  331. data/lib/badline/cartridge/flash.rb +0 -306
  332. data/lib/badline/cartridge/freezer.rb +0 -33
  333. data/lib/badline/cartridge/fun_play.rb +0 -38
  334. data/lib/badline/cartridge/g_mod2.rb +0 -74
  335. data/lib/badline/cartridge/game_system.rb +0 -40
  336. data/lib/badline/cartridge/geo_ram.rb +0 -79
  337. data/lib/badline/cartridge/kcs_power.rb +0 -75
  338. data/lib/badline/cartridge/mach5.rb +0 -32
  339. data/lib/badline/cartridge/magic_desk.rb +0 -30
  340. data/lib/badline/cartridge/ocean.rb +0 -35
  341. data/lib/badline/cartridge/pagefox.rb +0 -68
  342. data/lib/badline/cartridge/retro_replay.rb +0 -320
  343. data/lib/badline/cartridge/rex_utility.rb +0 -29
  344. data/lib/badline/cartridge/rgcd.rb +0 -58
  345. data/lib/badline/cartridge/simons_basic.rb +0 -35
  346. data/lib/badline/cartridge/standard.rb +0 -15
  347. data/lib/badline/cartridge/super_games.rb +0 -48
  348. data/lib/badline/cartridge/westermann.rb +0 -30
  349. data/lib/badline/cartridge/zaxxon.rb +0 -66
  350. data/lib/badline/cartridge.rb +0 -303
  351. data/lib/badline/checkpoint.rb +0 -98
  352. data/lib/badline/cia/fast_forward.rb +0 -60
  353. data/lib/badline/cia/interrupt_register.rb +0 -143
  354. data/lib/badline/cia/serial.rb +0 -275
  355. data/lib/badline/cia/state.rb +0 -47
  356. data/lib/badline/cia/timer.rb +0 -206
  357. data/lib/badline/cia.rb +0 -279
  358. data/lib/badline/color_memory.rb +0 -25
  359. data/lib/badline/control_ports.rb +0 -76
  360. data/lib/badline/cpu/addressing.rb +0 -131
  361. data/lib/badline/cpu/boundary.rb +0 -54
  362. data/lib/badline/cpu/core.rb +0 -165
  363. data/lib/badline/cpu/microcode.rb +0 -177
  364. data/lib/badline/cpu/operations.rb +0 -88
  365. data/lib/badline/cpu/saved_state.rb +0 -115
  366. data/lib/badline/cpu/stack_operations.rb +0 -82
  367. data/lib/badline/cpu.rb +0 -10
  368. data/lib/badline/cpu_port.rb +0 -112
  369. data/lib/badline/datasette.rb +0 -161
  370. data/lib/badline/drive/core.rb +0 -147
  371. data/lib/badline/drive/fast_serial.rb +0 -73
  372. data/lib/badline/drive/idle.rb +0 -125
  373. data/lib/badline/drive/idle_cpu.rb +0 -28
  374. data/lib/badline/drive/orbit.rb +0 -79
  375. data/lib/badline/drive/serial_lines.rb +0 -73
  376. data/lib/badline/drive/sleep.rb +0 -112
  377. data/lib/badline/drive/vias.rb +0 -84
  378. data/lib/badline/drive/watch.rb +0 -150
  379. data/lib/badline/drive.rb +0 -11
  380. data/lib/badline/drive1541/bus.rb +0 -86
  381. data/lib/badline/drive1541/byte_ready.rb +0 -48
  382. data/lib/badline/drive1541/cpu.rb +0 -11
  383. data/lib/badline/drive1541/disk.rb +0 -315
  384. data/lib/badline/drive1541/disk_state.rb +0 -86
  385. data/lib/badline/drive1541/disk_via.rb +0 -36
  386. data/lib/badline/drive1541/gcr.rb +0 -57
  387. data/lib/badline/drive1541/mechanism.rb +0 -313
  388. data/lib/badline/drive1541/mechanism_state.rb +0 -68
  389. data/lib/badline/drive1541/rotation.rb +0 -121
  390. data/lib/badline/drive1541/sector_reader.rb +0 -76
  391. data/lib/badline/drive1541/serial_port.rb +0 -18
  392. data/lib/badline/drive1541/track.rb +0 -98
  393. data/lib/badline/drive1541.rb +0 -111
  394. data/lib/badline/drive1571/bus.rb +0 -111
  395. data/lib/badline/drive1571/cpu.rb +0 -11
  396. data/lib/badline/drive1571/serial_port.rb +0 -37
  397. data/lib/badline/drive1571/serial_via.rb +0 -25
  398. data/lib/badline/drive1571/wd1770.rb +0 -120
  399. data/lib/badline/drive1571.rb +0 -175
  400. data/lib/badline/drive1581/bus.rb +0 -137
  401. data/lib/badline/drive1581/cpu.rb +0 -11
  402. data/lib/badline/drive1581/disk.rb +0 -135
  403. data/lib/badline/drive1581/disk_state.rb +0 -87
  404. data/lib/badline/drive1581/mechanism.rb +0 -117
  405. data/lib/badline/drive1581/serial_port.rb +0 -52
  406. data/lib/badline/drive1581/slot.rb +0 -78
  407. data/lib/badline/drive1581/track.rb +0 -100
  408. data/lib/badline/drive1581/track_bytes.rb +0 -75
  409. data/lib/badline/drive1581/wd1772/registers.rb +0 -89
  410. data/lib/badline/drive1581/wd1772/sector_writes.rb +0 -73
  411. data/lib/badline/drive1581/wd1772/sectors.rb +0 -150
  412. data/lib/badline/drive1581/wd1772/state.rb +0 -66
  413. data/lib/badline/drive1581/wd1772/stepping.rb +0 -109
  414. data/lib/badline/drive1581/wd1772/tracks.rb +0 -125
  415. data/lib/badline/drive1581/wd1772/turn.rb +0 -73
  416. data/lib/badline/drive1581/wd1772.rb +0 -216
  417. data/lib/badline/drive1581.rb +0 -233
  418. data/lib/badline/iec_bus.rb +0 -159
  419. data/lib/badline/instruction.rb +0 -334
  420. data/lib/badline/instruction_set/arithmetic.rb +0 -114
  421. data/lib/badline/instruction_set/bitwise.rb +0 -126
  422. data/lib/badline/instruction_set/branch.rb +0 -79
  423. data/lib/badline/instruction_set/flag.rb +0 -63
  424. data/lib/badline/instruction_set/illegal.rb +0 -270
  425. data/lib/badline/instruction_set/inc_dec.rb +0 -69
  426. data/lib/badline/instruction_set/stack.rb +0 -52
  427. data/lib/badline/instruction_set/transfer.rb +0 -137
  428. data/lib/badline/instruction_set.rb +0 -55
  429. data/lib/badline/interrupts.rb +0 -104
  430. data/lib/badline/joystick.rb +0 -25
  431. data/lib/badline/kernal_trap/channel.rb +0 -181
  432. data/lib/badline/keyboard.rb +0 -112
  433. data/lib/badline/ram_expansion/banking.rb +0 -30
  434. data/lib/badline/ram_expansion/plus256k.rb +0 -54
  435. data/lib/badline/ram_expansion/plus60k.rb +0 -43
  436. data/lib/badline/ram_expansion/unexpanded.rb +0 -28
  437. data/lib/badline/ram_expansion.rb +0 -21
  438. data/lib/badline/reu/dma/saved_state.rb +0 -50
  439. data/lib/badline/reu/dma.rb +0 -273
  440. data/lib/badline/reu/ram.rb +0 -107
  441. data/lib/badline/reu/saved_state.rb +0 -80
  442. data/lib/badline/reu/trigger.rb +0 -32
  443. data/lib/badline/reu.rb +0 -289
  444. data/lib/badline/sid/catch_up.rb +0 -120
  445. data/lib/badline/sid/decimator.rb +0 -64
  446. data/lib/badline/sid/envelope/state.rb +0 -68
  447. data/lib/badline/sid/envelope.rb +0 -239
  448. data/lib/badline/sid/filter.rb +0 -263
  449. data/lib/badline/sid/voice.rb +0 -77
  450. data/lib/badline/sid/waveform/combined.rb +0 -126
  451. data/lib/badline/sid/waveform/fast_forward.rb +0 -105
  452. data/lib/badline/sid/waveform/noise_writeback.rb +0 -122
  453. data/lib/badline/sid/waveform/state.rb +0 -66
  454. data/lib/badline/sid/waveform.rb +0 -305
  455. data/lib/badline/sid.rb +0 -303
  456. data/lib/badline/time_of_day.rb +0 -228
  457. data/lib/badline/traps.rb +0 -19
  458. data/lib/badline/via/control_lines.rb +0 -122
  459. data/lib/badline/via/fast_forward.rb +0 -53
  460. data/lib/badline/via/interrupt_register.rb +0 -67
  461. data/lib/badline/via/shift_register.rb +0 -180
  462. data/lib/badline/via/state.rb +0 -42
  463. data/lib/badline/via/timer1.rb +0 -131
  464. data/lib/badline/via/timer2.rb +0 -133
  465. data/lib/badline/via.rb +0 -266
  466. data/lib/badline/vic/bank.rb +0 -133
  467. data/lib/badline/vic/border_mask.rb +0 -86
  468. data/lib/badline/vic/collisions.rb +0 -115
  469. data/lib/badline/vic/color_patches.rb +0 -47
  470. data/lib/badline/vic/display_state.rb +0 -185
  471. data/lib/badline/vic/graphics_mode.rb +0 -164
  472. data/lib/badline/vic/graphics_shifter.rb +0 -207
  473. data/lib/badline/vic/register_log.rb +0 -81
  474. data/lib/badline/vic/registers.rb +0 -195
  475. data/lib/badline/vic/sequencer.rb +0 -275
  476. data/lib/badline/vic/sequencer_output.rb +0 -116
  477. data/lib/badline/vic/sequencer_state.rb +0 -89
  478. data/lib/badline/vic/sprite/internal_bus.rb +0 -68
  479. data/lib/badline/vic/sprite/saved_state.rb +0 -64
  480. data/lib/badline/vic/sprite/shifter.rb +0 -146
  481. data/lib/badline/vic/sprite/timing.rb +0 -56
  482. data/lib/badline/vic/sprite.rb +0 -337
  483. data/lib/badline/vic/sprites.rb +0 -282
  484. data/lib/badline/vic/sprites_state.rb +0 -57
  485. data/lib/badline/vic.rb +0 -853
  486. data/lib/badline/vic20/sound/output.rb +0 -83
  487. data/lib/badline/vic20/sound.rb +0 -233
  488. data/lib/badline/z80/arithmetic.rb +0 -117
  489. data/lib/badline/z80/bit_page.rb +0 -55
  490. data/lib/badline/z80/block_io.rb +0 -58
  491. data/lib/badline/z80/block_transfers.rb +0 -59
  492. data/lib/badline/z80/bus_cycles.rb +0 -111
  493. data/lib/badline/z80/core.rb +0 -113
  494. data/lib/badline/z80/exchanges.rb +0 -50
  495. data/lib/badline/z80/extended_page.rb +0 -89
  496. data/lib/badline/z80/flags.rb +0 -37
  497. data/lib/badline/z80/interrupt_acceptance.rb +0 -46
  498. data/lib/badline/z80/jumps.rb +0 -82
  499. data/lib/badline/z80/loads.rb +0 -98
  500. data/lib/badline/z80/main_page.rb +0 -134
  501. data/lib/badline/z80/registers.rb +0 -120
  502. data/lib/badline/z80/saved_state.rb +0 -69
  503. data/lib/badline/z80/shifts.rb +0 -64
  504. data/lib/badline/z80.rb +0 -11
  505. /data/lib/badline/snapshot/{fields.rb → vice/fields.rb} +0 -0
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ class Cartridge
6
+ # RGCD: up to eight 8K banks. A write to I/O 1 selects the bank from the
7
+ # low bits, and bit 3 switches the ROM out until reset. The Hucky board
8
+ # (subtype 1) inverts the bank bits and decodes only as many as it has
9
+ # banks.
10
+ class RGCD < Cartridge
11
+ def initialize(crt)
12
+ @hucky = crt.subtype == 1
13
+ super
14
+ end
15
+
16
+ def poke(addr, value)
17
+ return if addr > 0xdeff || @disabled
18
+
19
+ select(value)
20
+ changed!
21
+ end
22
+
23
+ def reset
24
+ @disabled = false
25
+ self.mode = :rom8k
26
+ select(0)
27
+ changed!
28
+ end
29
+
30
+ private
31
+
32
+ def save_mapper(out)
33
+ super
34
+ out.boolean(@disabled)
35
+ end
36
+
37
+ def load_mapper(input)
38
+ super
39
+ @disabled = input.boolean?
40
+ end
41
+
42
+ def select(value)
43
+ value ^= 0x07 if @hucky
44
+ if value.anybits?(0x08)
45
+ @disabled = true
46
+ self.mode = :off
47
+ else
48
+ @roml = bank(@banks, value & @bank_mask)
49
+ end
50
+ end
51
+
52
+ def install_chips(chips)
53
+ @banks = banks_from(chips).first
54
+ @bank_mask = @hucky ? bank_mask(@banks) : 0x07
55
+ reset
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ class Cartridge
6
+ # A cartridge's state for a snapshot: the setup that builds it again and
7
+ # the state that goes into it.
8
+ module SavedState
9
+ # What builds the same cartridge afresh (Cartridge.from_setup): the CRT
10
+ # image it was built from, and the jumpers of a mapper that has them.
11
+ def save_setup(out)
12
+ out.int(CRT_SETUP).string(Storage::CRTFile.encode(@crt))
13
+ save_jumpers(out)
14
+ end
15
+
16
+ # The lines, the pull on NMI, the button and the mapper's own state.
17
+ # Loading sets them without calling back into the machine, which maps
18
+ # the cartridge again afterwards.
19
+ def save_state(out)
20
+ out.marker("CARTRIDGE")
21
+ out.int(@exrom).int(@game).boolean(@nmi).boolean(@button == true)
22
+ save_mapper(out)
23
+ end
24
+
25
+ def load_state(input)
26
+ input.marker("CARTRIDGE")
27
+ @exrom = input.int
28
+ @game = input.int
29
+ @nmi = input.boolean?
30
+ @button = input.boolean?
31
+ load_mapper(input)
32
+ end
33
+
34
+ private
35
+
36
+ def save_jumpers(out)
37
+ out.boolean(false)
38
+ end
39
+
40
+ # The mapper's own state: where its windows point, for a mapper that
41
+ # moves them, and whatever a mapper adds after calling super.
42
+ def save_mapper(out)
43
+ save_windows(out, windows) if windows
44
+ end
45
+
46
+ def load_mapper(input)
47
+ load_windows(input, windows) if windows
48
+ end
49
+
50
+ # Where the ROML and ROMH windows point, as their places in `windows`,
51
+ # the banks and views the mapper picks them from, or -1 for none.
52
+ def save_windows(out, windows)
53
+ out.int(window_index(@roml, windows)).int(window_index(@romh, windows))
54
+ end
55
+
56
+ def load_windows(input, windows)
57
+ @roml = window_at(input.int, windows)
58
+ @romh = window_at(input.int, windows)
59
+ end
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ class Cartridge
6
+ # 16K. Reading I/O 1 switches ROMH out (8K mode), writing it switches
7
+ # ROMH back in.
8
+ class SimonsBasic < Cartridge
9
+ def readable_io_pages
10
+ [0xde]
11
+ end
12
+
13
+ def peek(addr)
14
+ select_mode(:rom8k) if addr < 0xdf00
15
+ open_bus(addr)
16
+ end
17
+
18
+ def poke(addr, _value)
19
+ select_mode(:rom16k) if addr < 0xdf00
20
+ end
21
+
22
+ def reset
23
+ select_mode(:rom16k)
24
+ end
25
+
26
+ private
27
+
28
+ def install_chips(chips)
29
+ roml, romh = banks_from(chips)
30
+ @roml = bank(roml, 0)
31
+ @romh = bank(romh, 0)
32
+ reset
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ class Cartridge
6
+ class Standard < Cartridge
7
+ private
8
+
9
+ def install_chips(chips)
10
+ roml, romh = banks_from(chips)
11
+ @roml = roml.compact.first
12
+ @romh = romh.compact.first
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ class Cartridge
6
+ # Super Games: four 16K banks. A write to I/O 2 selects the bank from bits
7
+ # 0-1, switches the ROM out with bit 2, and with bit 3 locks the register
8
+ # until reset.
9
+ class SuperGames < Cartridge
10
+ def poke(addr, value)
11
+ return if addr < 0xdf00 || @locked
12
+
13
+ select(value)
14
+ changed!
15
+ end
16
+
17
+ def reset
18
+ select(0)
19
+ changed!
20
+ end
21
+
22
+ private
23
+
24
+ def save_mapper(out)
25
+ super
26
+ out.boolean(@locked)
27
+ end
28
+
29
+ def load_mapper(input)
30
+ super
31
+ @locked = input.boolean?
32
+ end
33
+
34
+ def windows = [*@roml_banks, *@romh_banks, EMPTY_BANK]
35
+
36
+ def select(value)
37
+ @roml = bank(@roml_banks, value & 0x03)
38
+ @romh = bank(@romh_banks, value & 0x03)
39
+ self.mode = value.anybits?(0x04) ? :off : :rom16k
40
+ @locked = value.anybits?(0x08)
41
+ end
42
+
43
+ def install_chips(chips)
44
+ @roml_banks, @romh_banks = banks_from(chips)
45
+ reset
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ class Cartridge
6
+ # 16K. Reading I/O 2 switches ROMH out (8K mode) until reset.
7
+ class Westermann < Cartridge
8
+ def readable_io_pages
9
+ [0xdf]
10
+ end
11
+
12
+ def peek(addr)
13
+ select_mode(:rom8k) if addr >= 0xdf00
14
+ open_bus(addr)
15
+ end
16
+
17
+ def reset
18
+ select_mode(:rom16k)
19
+ end
20
+
21
+ private
22
+
23
+ def install_chips(chips)
24
+ roml, romh = banks_from(chips)
25
+ @roml = bank(roml, 0)
26
+ @romh = bank(romh, 0)
27
+ reset
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ class Cartridge
6
+ # Zaxxon / Super Zaxxon: 16K mode with a 4K ROML mirrored across
7
+ # $8000-$9FFF and two 8K ROMH banks. A read through ROML selects the
8
+ # ROMH bank: $8000-$8FFF the first, $9000-$9FFF the second.
9
+ class Zaxxon < Cartridge
10
+ class Low
11
+ def initialize(rom, high)
12
+ @rom = rom
13
+ @high = high
14
+ end
15
+
16
+ def peek(addr)
17
+ @high.select(addr[12])
18
+ @rom.peek(addr)
19
+ end
20
+ end
21
+
22
+ class High
23
+ def initialize(banks)
24
+ @banks = banks
25
+ select(0)
26
+ end
27
+
28
+ def select(number)
29
+ @bank = @banks[number] || EMPTY_BANK
30
+ end
31
+
32
+ def peek(addr)
33
+ @bank.peek(addr)
34
+ end
35
+
36
+ def save_state(out)
37
+ out.int([*@banks, EMPTY_BANK].index { |bank| bank.equal?(@bank) })
38
+ end
39
+
40
+ def load_state(input)
41
+ @bank = [*@banks, EMPTY_BANK].fetch(input.int)
42
+ end
43
+ end
44
+
45
+ def reset
46
+ @romh.select(0)
47
+ end
48
+
49
+ private
50
+
51
+ def save_mapper(out)
52
+ @romh.save_state(out)
53
+ end
54
+
55
+ def load_mapper(input)
56
+ @romh.load_state(input)
57
+ end
58
+
59
+ def install_chips(chips)
60
+ roml, romh = banks_from(chips)
61
+ @romh = High.new(romh)
62
+ @roml = Low.new(roml.first || EMPTY_BANK, @romh)
63
+ self.mode = :rom16k
64
+ end
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,258 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "badline/c64/cartridge/bank"
4
+ require "badline/c64/cartridge/flash"
5
+ require "badline/c64/cartridge/standard"
6
+ require "badline/c64/cartridge/simons_basic"
7
+ require "badline/c64/cartridge/ocean"
8
+ require "badline/c64/cartridge/fun_play"
9
+ require "badline/c64/cartridge/super_games"
10
+ require "badline/c64/cartridge/epyx_fastload"
11
+ require "badline/c64/cartridge/westermann"
12
+ require "badline/c64/cartridge/rex_utility"
13
+ require "badline/c64/cartridge/game_system"
14
+ require "badline/c64/cartridge/dinamic"
15
+ require "badline/c64/cartridge/zaxxon"
16
+ require "badline/c64/cartridge/magic_desk"
17
+ require "badline/c64/cartridge/comal80"
18
+ require "badline/c64/cartridge/easy_flash"
19
+ require "badline/c64/cartridge/mach5"
20
+ require "badline/c64/cartridge/pagefox"
21
+ require "badline/c64/cartridge/rgcd"
22
+ require "badline/c64/cartridge/g_mod2"
23
+ require "badline/c64/cartridge/freezer"
24
+ require "badline/c64/cartridge/action_replay"
25
+ require "badline/c64/cartridge/atomic_power"
26
+ require "badline/c64/cartridge/final_cartridge3"
27
+ require "badline/c64/cartridge/retro_replay"
28
+ require "badline/c64/cartridge/kcs_power"
29
+ require "badline/c64/cartridge/geo_ram"
30
+ require "badline/c64/cartridge/saved_state"
31
+
32
+ module Badline
33
+ class C64
34
+ class Cartridge
35
+ include SavedState
36
+
37
+ class UnsupportedTypeError < StandardError; end
38
+
39
+ ROMH_START = 0xa000
40
+ BANK_SIZE = 0x2000
41
+
42
+ HARDWARE_TYPES = {
43
+ 0 => Standard, 1 => ActionReplay, 2 => KCSPower, 3 => FinalCartridge3,
44
+ 4 => SimonsBasic, 5 => Ocean, 7 => FunPlay, 8 => SuperGames,
45
+ 9 => AtomicPower, 10 => EpyxFastload, 11 => Westermann,
46
+ 12 => RexUtility, 15 => GameSystem, 17 => Dinamic, 18 => Zaxxon,
47
+ 19 => MagicDesk, 21 => Comal80, 32 => EasyFlash, 36 => RetroReplay,
48
+ 51 => Mach5, 53 => Pagefox, 57 => RGCD, 60 => GMod2
49
+ }.freeze
50
+
51
+ # The EXROM and GAME line levels of each memory configuration. The lines
52
+ # are active low.
53
+ MODES = {
54
+ rom8k: [0, 1].freeze, rom16k: [0, 0].freeze,
55
+ ultimax: [1, 0].freeze, off: [1, 1].freeze
56
+ }.freeze
57
+
58
+ attr_reader :name, :exrom, :game, :roml, :romh
59
+
60
+ # A callable returning the current cycle, for mappers with timed state.
61
+ attr_writer :clock
62
+
63
+ class << self
64
+ # Options set the cartridge's jumpers, for the mappers that have them.
65
+ def from_file(path, **)
66
+ from_crt(Storage::CRTFile.new(path), **)
67
+ end
68
+
69
+ def from_crt(crt, **)
70
+ mapper_for(crt).new(crt, **)
71
+ end
72
+
73
+ # A cartridge built afresh from what save_setup wrote, before
74
+ # load_state puts its state in.
75
+ def from_setup(input)
76
+ return GeoRAM.new(size: input.int) if input.int == GEO_RAM_SETUP
77
+
78
+ crt = Storage::CRTFile.new(bytes: input.string)
79
+ mapper_for(crt).from_jumpers(crt, input)
80
+ end
81
+
82
+ # A cartridge from its image and what save_jumpers wrote: whether
83
+ # there are jumpers, then their settings on a mapper that has them.
84
+ def from_jumpers(crt, input)
85
+ input.boolean?
86
+ new(crt)
87
+ end
88
+
89
+ def mapper_for(crt)
90
+ HARDWARE_TYPES.fetch(crt.hardware_type) do
91
+ raise UnsupportedTypeError,
92
+ "Unsupported cartridge hardware type #{crt.hardware_type}"
93
+ end
94
+ end
95
+ end
96
+
97
+ # What save_setup writes first: a cartridge from a CRT image, or a
98
+ # GEO-RAM.
99
+ CRT_SETUP = 0
100
+ GEO_RAM_SETUP = 1
101
+
102
+ # Keeps the image it was built from, so a snapshot's machine can build
103
+ # the same cartridge before the snapshot's state goes into it.
104
+ def initialize(crt)
105
+ @crt = crt
106
+ @name = crt.name
107
+ @exrom = crt.exrom
108
+ @game = crt.game
109
+ @roml = @romh = nil
110
+ @banks = nil
111
+ @on_change = nil
112
+ @on_nmi_change = nil
113
+ @nmi = false
114
+ @open_bus = nil
115
+ @clock = nil
116
+ install_chips(crt.chips)
117
+ end
118
+
119
+ def on_change(&block)
120
+ @on_change = block
121
+ end
122
+
123
+ # Called with the level of the cartridge's pull on the NMI line when it
124
+ # changes. The line is wired-OR with CIA 2's.
125
+ def on_nmi_change(&block)
126
+ @on_nmi_change = block
127
+ end
128
+
129
+ def nmi?
130
+ @nmi
131
+ end
132
+
133
+ # The address bus hands over the C64's RAM, for mappers that write
134
+ # through to it, and the open bus, for I/O reads the cartridge doesn't
135
+ # drive.
136
+ def connect(ram:, open_bus:)
137
+ @ram = ram
138
+ @open_bus = open_bus
139
+ end
140
+
141
+ def ultimax?
142
+ @game.zero? && @exrom == 1
143
+ end
144
+
145
+ # Whether the first half of the cycle, where the VIC does most of its
146
+ # fetching, sees Ultimax mode. Some cartridges drive GAME and EXROM
147
+ # differently in the two halves; #ultimax? is the second, the CPU's.
148
+ def phi1_ultimax?
149
+ ultimax?
150
+ end
151
+
152
+ # The I/O pages ($de, $df) whose reads the mapper drives. Reads of the
153
+ # others are open bus.
154
+ def readable_io_pages
155
+ []
156
+ end
157
+
158
+ def poke(_addr, _value); end
159
+
160
+ # A window taking writes to $E000-$FFFF while reads there see the C64's
161
+ # memory, for a cartridge that asserts Ultimax on write cycles only.
162
+ def romh_writes; end
163
+
164
+ # A window at $A000-$BFFF in Ultimax mode, where the C64 maps nothing.
165
+ def ultimax_a000; end
166
+
167
+ # The RES line on the expansion port.
168
+ def reset; end
169
+
170
+ # Whether the cartridge has a freeze button.
171
+ def freezer? = false
172
+
173
+ # The freeze button, which cartridges without one ignore.
174
+ def press_button; end
175
+
176
+ def release_button; end
177
+
178
+ private
179
+
180
+ # The banks and views ROML and ROMH can point at, which a snapshot
181
+ # names them by: the mapper's banks, or nothing for a mapper whose
182
+ # windows stay where install_chips put them.
183
+ def windows
184
+ [*@banks, EMPTY_BANK] if @banks
185
+ end
186
+
187
+ def window_index(window, windows)
188
+ return -1 if window.nil?
189
+
190
+ windows.index { |candidate| candidate.equal?(window) } ||
191
+ raise(ArgumentError, "#{self.class.name}: a window that isn't among its banks")
192
+ end
193
+
194
+ def window_at(index, windows) = index.negative? ? nil : windows.fetch(index)
195
+
196
+ def nmi=(level)
197
+ return if @nmi == level
198
+
199
+ @nmi = level
200
+ @on_nmi_change&.call(level)
201
+ end
202
+
203
+ def changed!
204
+ @on_change&.call
205
+ end
206
+
207
+ def mode=(mode)
208
+ @exrom, @game = MODES.fetch(mode)
209
+ end
210
+
211
+ # Sets the lines and tells the machine to map the cartridge again.
212
+ def select_mode(mode)
213
+ self.mode = mode
214
+ changed!
215
+ end
216
+
217
+ def open_bus(addr)
218
+ @open_bus ? @open_bus.peek(addr) : 0xff
219
+ end
220
+
221
+ def install_chips(_chips)
222
+ raise NotImplementedError
223
+ end
224
+
225
+ def rom_bank(data)
226
+ Bank.new(data)
227
+ end
228
+
229
+ # A bank the image leaves out reads as erased ROM.
230
+ def bank(banks, number)
231
+ banks[number] || EMPTY_BANK
232
+ end
233
+
234
+ # The bank register bits a ROM decodes. The ROM holds the highest bank
235
+ # in the image, and has address lines for the power of two that covers
236
+ # it; the register bits above those lines are ignored.
237
+ def bank_mask(banks)
238
+ (1 << (banks.length - 1).bit_length) - 1
239
+ end
240
+
241
+ # Sorts the CHIP packets into ROML and ROMH banks by load address. A 16K
242
+ # chip at $8000 spans both.
243
+ def banks_from(chips)
244
+ roml = []
245
+ romh = []
246
+ chips.each do |chip|
247
+ if chip.address >= ROMH_START
248
+ romh[chip.bank] = rom_bank(chip.data)
249
+ else
250
+ roml[chip.bank] = rom_bank(chip.data[0, BANK_SIZE])
251
+ romh[chip.bank] = rom_bank(chip.data[BANK_SIZE, BANK_SIZE]) if chip.data.length > BANK_SIZE
252
+ end
253
+ end
254
+ [roml, romh]
255
+ end
256
+ end
257
+ end
258
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ # Colour RAM is four bits wide. A CPU read takes the upper nibble off the
6
+ # open data bus, which still holds the byte the VIC fetched in phi1.
7
+ class ColorMemory < Memory
8
+ def initialize(vic, start: 0xd800, length: 2**10)
9
+ super(start:, length:)
10
+ @vic = vic
11
+ end
12
+
13
+ def peek(addr)
14
+ (@vic.phi1_data & 0xf0) | @storage[offset_of(addr)]
15
+ end
16
+
17
+ def poke(addr, value)
18
+ super(addr, value & 0x0f)
19
+ end
20
+
21
+ # The four bits the cell stores, as the VIC's c-access sees them.
22
+ def nibble(addr)
23
+ @storage[offset_of(addr)]
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,9 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Badline
4
- class Computer
4
+ class C64
5
5
  # What the C128 does as the C64 does: the NMI line, a PRG put into RAM
6
- # and the region's timing. Computer and C128 each include it.
6
+ # and the region's timing. C64 and C128 each include it.
7
7
  module Common
8
8
  # The clock, the raster and the crop of the machine's region, a pixel
9
9
  # to a window pixel.