badline 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (516) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/CLAUDE.md +59 -31
  4. data/README.md +1 -1
  5. data/doc/library.md +9 -9
  6. data/doc/pinned-behaviour.md +105 -105
  7. data/doc/snapshots.md +1 -4
  8. data/lib/badline/audio/bare_player.rb +4 -4
  9. data/lib/badline/audio/cli.rb +6 -6
  10. data/lib/badline/audio/jukebox.rb +2 -2
  11. data/lib/badline/audio/machine_player.rb +2 -2
  12. data/lib/badline/{media → audio}/queue.rb +1 -1
  13. data/lib/badline/audio/queued_tune.rb +6 -6
  14. data/lib/badline/audio/renderer.rb +5 -5
  15. data/lib/badline/audio/stereo.rb +1 -1
  16. data/lib/badline/c128/{bus_state.rb → bus/saved_state.rb} +6 -6
  17. data/lib/badline/c128/bus.rb +30 -51
  18. data/lib/badline/c128/color_lines.rb +2 -2
  19. data/lib/badline/c128/cpu.rb +1 -1
  20. data/lib/badline/c128/drives.rb +10 -11
  21. data/lib/badline/c128/fast_serial.rb +5 -5
  22. data/lib/badline/c128/mmu_pages.rb +1 -1
  23. data/lib/badline/c128/modes.rb +2 -2
  24. data/lib/badline/c128/saved_state.rb +21 -47
  25. data/lib/badline/c128/z80.rb +2 -2
  26. data/lib/badline/c128.rb +18 -72
  27. data/lib/badline/{computer → c64}/attachments.rb +16 -47
  28. data/lib/badline/c64/banked_ram/banking.rb +32 -0
  29. data/lib/badline/c64/banked_ram/plus256k.rb +56 -0
  30. data/lib/badline/c64/banked_ram/plus60k.rb +45 -0
  31. data/lib/badline/c64/banked_ram/unexpanded.rb +30 -0
  32. data/lib/badline/c64/banked_ram.rb +23 -0
  33. data/lib/badline/c64/bus/extra_sids.rb +32 -0
  34. data/lib/badline/c64/bus/fittings.rb +40 -0
  35. data/lib/badline/c64/bus/pla.rb +149 -0
  36. data/lib/badline/c64/bus/roms.rb +41 -0
  37. data/lib/badline/c64/bus/saved_state.rb +68 -0
  38. data/lib/badline/c64/bus/sid_slots.rb +44 -0
  39. data/lib/badline/c64/bus.rb +218 -0
  40. data/lib/badline/c64/cartridge/action_replay.rb +128 -0
  41. data/lib/badline/c64/cartridge/atomic_power.rb +26 -0
  42. data/lib/badline/c64/cartridge/bank.rb +83 -0
  43. data/lib/badline/c64/cartridge/comal80.rb +52 -0
  44. data/lib/badline/c64/cartridge/dinamic.rb +36 -0
  45. data/lib/badline/c64/cartridge/easy_flash.rb +147 -0
  46. data/lib/badline/c64/cartridge/epyx_fastload.rb +81 -0
  47. data/lib/badline/c64/cartridge/final_cartridge3.rb +91 -0
  48. data/lib/badline/c64/cartridge/flash/saved_state.rb +40 -0
  49. data/lib/badline/c64/cartridge/flash.rb +279 -0
  50. data/lib/badline/c64/cartridge/freezer.rb +35 -0
  51. data/lib/badline/c64/cartridge/fun_play.rb +40 -0
  52. data/lib/badline/c64/cartridge/g_mod2.rb +76 -0
  53. data/lib/badline/c64/cartridge/game_system.rb +42 -0
  54. data/lib/badline/c64/cartridge/geo_ram.rb +81 -0
  55. data/lib/badline/c64/cartridge/kcs_power.rb +77 -0
  56. data/lib/badline/c64/cartridge/mach5.rb +34 -0
  57. data/lib/badline/c64/cartridge/magic_desk.rb +32 -0
  58. data/lib/badline/c64/cartridge/ocean.rb +37 -0
  59. data/lib/badline/c64/cartridge/pagefox.rb +70 -0
  60. data/lib/badline/c64/cartridge/retro_replay/saved_state.rb +47 -0
  61. data/lib/badline/c64/cartridge/retro_replay.rb +286 -0
  62. data/lib/badline/c64/cartridge/rex_utility.rb +31 -0
  63. data/lib/badline/c64/cartridge/rgcd.rb +60 -0
  64. data/lib/badline/c64/cartridge/saved_state.rb +63 -0
  65. data/lib/badline/c64/cartridge/simons_basic.rb +37 -0
  66. data/lib/badline/c64/cartridge/standard.rb +17 -0
  67. data/lib/badline/c64/cartridge/super_games.rb +50 -0
  68. data/lib/badline/c64/cartridge/westermann.rb +32 -0
  69. data/lib/badline/c64/cartridge/zaxxon.rb +68 -0
  70. data/lib/badline/c64/cartridge.rb +258 -0
  71. data/lib/badline/c64/color_memory.rb +27 -0
  72. data/lib/badline/c64/common.rb +34 -0
  73. data/lib/badline/c64/kernal_traps.rb +89 -0
  74. data/lib/badline/c64/reu/dma/saved_state.rb +52 -0
  75. data/lib/badline/c64/reu/dma.rb +275 -0
  76. data/lib/badline/c64/reu/ram.rb +109 -0
  77. data/lib/badline/c64/reu/saved_state.rb +55 -0
  78. data/lib/badline/c64/reu/trigger.rb +34 -0
  79. data/lib/badline/c64/reu.rb +291 -0
  80. data/lib/badline/{computer → c64}/saved_state.rb +13 -18
  81. data/lib/badline/{computer → c64}/true_drives.rb +20 -31
  82. data/lib/badline/{computer.rb → c64.rb} +22 -80
  83. data/lib/badline/chips/cia/fast_forward.rb +62 -0
  84. data/lib/badline/chips/cia/interrupt_register.rb +145 -0
  85. data/lib/badline/chips/cia/saved_state.rb +49 -0
  86. data/lib/badline/chips/cia/serial/saved_state.rb +45 -0
  87. data/lib/badline/chips/cia/serial.rb +250 -0
  88. data/lib/badline/chips/cia/time_of_day.rb +232 -0
  89. data/lib/badline/chips/cia/timer.rb +208 -0
  90. data/lib/badline/chips/cia.rb +281 -0
  91. data/lib/badline/chips/cpu/addressing.rb +133 -0
  92. data/lib/badline/chips/cpu/boundary.rb +56 -0
  93. data/lib/badline/chips/cpu/core.rb +167 -0
  94. data/lib/badline/chips/cpu/instruction.rb +338 -0
  95. data/lib/badline/chips/cpu/instruction_set/arithmetic.rb +118 -0
  96. data/lib/badline/chips/cpu/instruction_set/bitwise.rb +130 -0
  97. data/lib/badline/chips/cpu/instruction_set/branch.rb +83 -0
  98. data/lib/badline/chips/cpu/instruction_set/flag.rb +67 -0
  99. data/lib/badline/chips/cpu/instruction_set/illegal.rb +274 -0
  100. data/lib/badline/chips/cpu/instruction_set/inc_dec.rb +73 -0
  101. data/lib/badline/chips/cpu/instruction_set/stack.rb +56 -0
  102. data/lib/badline/chips/cpu/instruction_set/transfer.rb +141 -0
  103. data/lib/badline/chips/cpu/instruction_set.rb +59 -0
  104. data/lib/badline/chips/cpu/interrupts.rb +108 -0
  105. data/lib/badline/chips/cpu/microcode.rb +179 -0
  106. data/lib/badline/chips/cpu/operations.rb +90 -0
  107. data/lib/badline/chips/cpu/port.rb +116 -0
  108. data/lib/badline/chips/cpu/saved_state.rb +117 -0
  109. data/lib/badline/chips/cpu/stack_operations.rb +84 -0
  110. data/lib/badline/chips/cpu/traps.rb +23 -0
  111. data/lib/badline/chips/cpu.rb +12 -0
  112. data/lib/badline/chips/sid/catch_up.rb +122 -0
  113. data/lib/badline/chips/sid/decimator.rb +66 -0
  114. data/lib/badline/chips/sid/envelope/saved_state.rb +70 -0
  115. data/lib/badline/chips/sid/envelope.rb +241 -0
  116. data/lib/badline/chips/sid/filter/saved_state.rb +42 -0
  117. data/lib/badline/chips/sid/filter.rb +241 -0
  118. data/lib/badline/chips/sid/saved_state.rb +52 -0
  119. data/lib/badline/chips/sid/voice.rb +79 -0
  120. data/lib/badline/chips/sid/waveform/combined.rb +128 -0
  121. data/lib/badline/chips/sid/waveform/fast_forward.rb +107 -0
  122. data/lib/badline/chips/sid/waveform/noise_writeback.rb +124 -0
  123. data/lib/badline/chips/sid/waveform/saved_state.rb +68 -0
  124. data/lib/badline/chips/sid/waveform.rb +307 -0
  125. data/lib/badline/chips/sid.rb +265 -0
  126. data/lib/badline/{c128 → chips}/vdc/memory.rb +1 -1
  127. data/lib/badline/{c128 → chips}/vdc/painter.rb +1 -1
  128. data/lib/badline/{c128 → chips}/vdc/raster.rb +1 -1
  129. data/lib/badline/chips/vdc/saved_state.rb +36 -0
  130. data/lib/badline/{c128 → chips}/vdc/window.rb +1 -1
  131. data/lib/badline/{c128 → chips}/vdc.rb +7 -31
  132. data/lib/badline/chips/via/control_lines.rb +124 -0
  133. data/lib/badline/chips/via/fast_forward.rb +55 -0
  134. data/lib/badline/chips/via/interrupt_register.rb +69 -0
  135. data/lib/badline/chips/via/saved_state.rb +44 -0
  136. data/lib/badline/chips/via/shift_register.rb +182 -0
  137. data/lib/badline/chips/via/timer1.rb +133 -0
  138. data/lib/badline/chips/via/timer2.rb +135 -0
  139. data/lib/badline/chips/via.rb +268 -0
  140. data/lib/badline/chips/vic/bank.rb +135 -0
  141. data/lib/badline/chips/vic/border_mask.rb +88 -0
  142. data/lib/badline/chips/vic/collisions.rb +117 -0
  143. data/lib/badline/chips/vic/color_patches.rb +49 -0
  144. data/lib/badline/chips/vic/display_state.rb +187 -0
  145. data/lib/badline/chips/vic/graphics_mode.rb +166 -0
  146. data/lib/badline/chips/vic/graphics_shifter/saved_state.rb +40 -0
  147. data/lib/badline/chips/vic/graphics_shifter.rb +187 -0
  148. data/lib/badline/chips/vic/register_log.rb +83 -0
  149. data/lib/badline/chips/vic/registers.rb +197 -0
  150. data/lib/badline/chips/vic/saved_state.rb +82 -0
  151. data/lib/badline/chips/vic/sequencer/saved_state.rb +91 -0
  152. data/lib/badline/chips/vic/sequencer.rb +277 -0
  153. data/lib/badline/chips/vic/sequencer_output.rb +118 -0
  154. data/lib/badline/chips/vic/sprite/internal_bus.rb +70 -0
  155. data/lib/badline/chips/vic/sprite/saved_state.rb +66 -0
  156. data/lib/badline/chips/vic/sprite/shifter.rb +148 -0
  157. data/lib/badline/chips/vic/sprite/timing.rb +58 -0
  158. data/lib/badline/chips/vic/sprite.rb +339 -0
  159. data/lib/badline/chips/vic/sprites/saved_state.rb +59 -0
  160. data/lib/badline/chips/vic/sprites.rb +284 -0
  161. data/lib/badline/chips/vic.rb +783 -0
  162. data/lib/badline/chips/vic_i/painter/saved_state.rb +40 -0
  163. data/lib/badline/{vic20/vic → chips/vic_i}/painter.rb +6 -30
  164. data/lib/badline/{vic20/vic → chips/vic_i}/saved_state.rb +2 -2
  165. data/lib/badline/chips/vic_i/sound/output.rb +85 -0
  166. data/lib/badline/chips/vic_i/sound.rb +235 -0
  167. data/lib/badline/{vic20/vic → chips/vic_i}/text_window.rb +2 -2
  168. data/lib/badline/{vic20/vic.rb → chips/vic_i.rb} +5 -5
  169. data/lib/badline/chips/z80/arithmetic.rb +119 -0
  170. data/lib/badline/chips/z80/bit_page.rb +57 -0
  171. data/lib/badline/chips/z80/block_io.rb +60 -0
  172. data/lib/badline/chips/z80/block_transfers.rb +61 -0
  173. data/lib/badline/chips/z80/bus_cycles.rb +113 -0
  174. data/lib/badline/chips/z80/core.rb +115 -0
  175. data/lib/badline/chips/z80/exchanges.rb +52 -0
  176. data/lib/badline/chips/z80/extended_page.rb +91 -0
  177. data/lib/badline/chips/z80/flags.rb +39 -0
  178. data/lib/badline/chips/z80/interrupt_acceptance.rb +48 -0
  179. data/lib/badline/chips/z80/jumps.rb +84 -0
  180. data/lib/badline/chips/z80/loads.rb +100 -0
  181. data/lib/badline/chips/z80/main_page.rb +136 -0
  182. data/lib/badline/chips/z80/registers.rb +122 -0
  183. data/lib/badline/chips/z80/saved_state.rb +71 -0
  184. data/lib/badline/chips/z80/shifts.rb +66 -0
  185. data/lib/badline/chips/z80.rb +13 -0
  186. data/lib/badline/core.rb +27 -29
  187. data/lib/badline/drives/datasette/saved_state.rb +37 -0
  188. data/lib/badline/drives/datasette.rb +140 -0
  189. data/lib/badline/drives/engine/core.rb +149 -0
  190. data/lib/badline/drives/engine/fast_serial.rb +75 -0
  191. data/lib/badline/drives/engine/idle.rb +127 -0
  192. data/lib/badline/drives/engine/idle_cpu.rb +30 -0
  193. data/lib/badline/drives/engine/orbit.rb +81 -0
  194. data/lib/badline/drives/engine/serial_lines.rb +75 -0
  195. data/lib/badline/drives/engine/sleep.rb +114 -0
  196. data/lib/badline/drives/engine/vias.rb +86 -0
  197. data/lib/badline/drives/engine/watch.rb +152 -0
  198. data/lib/badline/drives/engine.rb +11 -0
  199. data/lib/badline/drives/model1541/bus.rb +88 -0
  200. data/lib/badline/drives/model1541/byte_ready.rb +50 -0
  201. data/lib/badline/drives/model1541/cpu.rb +13 -0
  202. data/lib/badline/drives/model1541/disk/saved_state.rb +88 -0
  203. data/lib/badline/drives/model1541/disk.rb +317 -0
  204. data/lib/badline/drives/model1541/disk_via.rb +38 -0
  205. data/lib/badline/drives/model1541/gcr.rb +59 -0
  206. data/lib/badline/drives/model1541/mechanism/saved_state.rb +72 -0
  207. data/lib/badline/drives/model1541/mechanism.rb +315 -0
  208. data/lib/badline/drives/model1541/rotation.rb +123 -0
  209. data/lib/badline/drives/model1541/saved_state.rb +44 -0
  210. data/lib/badline/drives/model1541/sector_reader.rb +78 -0
  211. data/lib/badline/drives/model1541/serial_port.rb +20 -0
  212. data/lib/badline/drives/model1541/track.rb +100 -0
  213. data/lib/badline/drives/model1541.rb +81 -0
  214. data/lib/badline/drives/model1571/bus.rb +113 -0
  215. data/lib/badline/drives/model1571/cpu.rb +13 -0
  216. data/lib/badline/drives/model1571/saved_state.rb +47 -0
  217. data/lib/badline/drives/model1571/serial_port.rb +39 -0
  218. data/lib/badline/drives/model1571/serial_via.rb +27 -0
  219. data/lib/badline/drives/model1571/wd1770.rb +122 -0
  220. data/lib/badline/drives/model1571.rb +142 -0
  221. data/lib/badline/drives/model1581/bus.rb +139 -0
  222. data/lib/badline/drives/model1581/cpu.rb +13 -0
  223. data/lib/badline/drives/model1581/disk/saved_state.rb +89 -0
  224. data/lib/badline/drives/model1581/disk.rb +137 -0
  225. data/lib/badline/drives/model1581/mechanism.rb +119 -0
  226. data/lib/badline/drives/model1581/saved_state.rb +42 -0
  227. data/lib/badline/drives/model1581/serial_port.rb +54 -0
  228. data/lib/badline/drives/model1581/slot.rb +79 -0
  229. data/lib/badline/drives/model1581/track.rb +102 -0
  230. data/lib/badline/drives/model1581/track_bytes.rb +77 -0
  231. data/lib/badline/drives/model1581/wd1772/registers.rb +91 -0
  232. data/lib/badline/drives/model1581/wd1772/saved_state.rb +68 -0
  233. data/lib/badline/drives/model1581/wd1772/sector_writes.rb +75 -0
  234. data/lib/badline/drives/model1581/wd1772/sectors.rb +152 -0
  235. data/lib/badline/drives/model1581/wd1772/stepping.rb +111 -0
  236. data/lib/badline/drives/model1581/wd1772/tracks.rb +127 -0
  237. data/lib/badline/drives/model1581/wd1772/turn.rb +75 -0
  238. data/lib/badline/drives/model1581/wd1772.rb +218 -0
  239. data/lib/badline/drives/model1581.rb +206 -0
  240. data/lib/badline/drives/serial_bus.rb +161 -0
  241. data/lib/badline/frontend/boot.rb +10 -61
  242. data/lib/badline/frontend/machine_window.rb +3 -1
  243. data/lib/badline/frontend/player/filter_view.rb +1 -1
  244. data/lib/badline/frontend/player/player_controller.rb +2 -2
  245. data/lib/badline/frontend/player/player_screen.rb +1 -0
  246. data/lib/badline/frontend/player/theme.rb +7 -7
  247. data/lib/badline/frontend/timeline.rb +3 -3
  248. data/lib/badline/input/control_ports.rb +78 -0
  249. data/lib/badline/input/joystick.rb +27 -0
  250. data/lib/badline/input/keyboard.rb +114 -0
  251. data/lib/badline/input.rb +3 -0
  252. data/lib/badline/kernal_trap/{drive → dos}/block_commands.rb +1 -1
  253. data/lib/badline/kernal_trap/dos/channel.rb +183 -0
  254. data/lib/badline/kernal_trap/{drive → dos}/channels.rb +1 -1
  255. data/lib/badline/kernal_trap/{drive → dos}/memory.rb +1 -1
  256. data/lib/badline/kernal_trap/{drive → dos}/parameters.rb +1 -1
  257. data/lib/badline/kernal_trap/{drive → dos}/status.rb +1 -1
  258. data/lib/badline/kernal_trap/{drive → dos}/write_file.rb +1 -1
  259. data/lib/badline/kernal_trap/{drive → dos}/writes.rb +1 -1
  260. data/lib/badline/kernal_trap/{drive.rb → dos.rb} +11 -10
  261. data/lib/badline/kernal_trap/{file.rb → file_routine.rb} +1 -1
  262. data/lib/badline/kernal_trap/load.rb +6 -6
  263. data/lib/badline/kernal_trap/save.rb +5 -5
  264. data/lib/badline/kernal_trap/serial.rb +7 -7
  265. data/lib/badline/kernal_trap.rb +2 -3
  266. data/lib/badline/machine/clocking.rb +50 -0
  267. data/lib/badline/machine.rb +63 -7
  268. data/lib/badline/media/boot_disk.rb +2 -2
  269. data/lib/badline/media/disk_list.rb +3 -3
  270. data/lib/badline/media/disk_set.rb +1 -1
  271. data/lib/badline/media/extensions.rb +33 -0
  272. data/lib/badline/media/program.rb +28 -0
  273. data/lib/badline/media/true_drive.rb +4 -3
  274. data/lib/badline/media/tune.rb +35 -0
  275. data/lib/badline/media/vic20_cartridge.rb +1 -7
  276. data/lib/badline/media/vic20_media.rb +38 -80
  277. data/lib/badline/media.rb +84 -81
  278. data/lib/badline/model.rb +1 -1
  279. data/lib/badline/options/event.rb +3 -1
  280. data/lib/badline/roms/README +6 -6
  281. data/lib/badline/sdl.rb +1 -0
  282. data/lib/badline/{storage/sid_file.rb → sid_tune/file.rb} +3 -3
  283. data/lib/badline/{storage → sid_tune}/hvsc.rb +7 -7
  284. data/lib/badline/{storage → sid_tune}/song_lengths.rb +2 -2
  285. data/lib/badline/{storage → sid_tune}/stil/credit.rb +1 -1
  286. data/lib/badline/{storage → sid_tune}/stil.rb +3 -3
  287. data/lib/badline/sid_tune.rb +6 -0
  288. data/lib/badline/snapshot/c128_setup.rb +43 -0
  289. data/lib/badline/snapshot/c64_setup.rb +79 -0
  290. data/lib/badline/snapshot/image.rb +5 -25
  291. data/lib/badline/snapshot/machine_state.rb +10 -2
  292. data/lib/badline/snapshot/setup.rb +22 -66
  293. data/lib/badline/snapshot/state.rb +8 -17
  294. data/lib/badline/snapshot/storage_setup.rb +68 -0
  295. data/lib/badline/snapshot/vic20_setup.rb +37 -0
  296. data/lib/badline/snapshot/vice/c64_mem.rb +1 -1
  297. data/lib/badline/snapshot/vice/restore.rb +1 -1
  298. data/lib/badline/snapshot/vice/reu1764.rb +1 -1
  299. data/lib/badline/snapshot/vice/reu_fields.rb +40 -0
  300. data/lib/badline/snapshot/vice.rb +7 -5
  301. data/lib/badline/snapshot.rb +13 -12
  302. data/lib/badline/storage/d64_image.rb +15 -9
  303. data/lib/badline/storage/d71_image.rb +0 -2
  304. data/lib/badline/storage/d81_image.rb +0 -2
  305. data/lib/badline/storage/disk_image/writing.rb +2 -2
  306. data/lib/badline/storage/disk_image.rb +3 -6
  307. data/lib/badline/storage/g64_image.rb +2 -2
  308. data/lib/badline/storage/host_directory.rb +0 -5
  309. data/lib/badline/storage/t64.rb +2 -8
  310. data/lib/badline/storage/unavailable.rb +1 -1
  311. data/lib/badline/storage.rb +0 -37
  312. data/lib/badline/support/c128_checkpoint.rb +39 -0
  313. data/lib/badline/support/checkpoint.rb +108 -0
  314. data/lib/badline/support/vic20_checkpoint.rb +38 -0
  315. data/lib/badline/support.rb +5 -0
  316. data/lib/badline/version.rb +1 -1
  317. data/lib/badline/vic20/attachments.rb +11 -81
  318. data/lib/badline/vic20/bus/saved_state.rb +35 -0
  319. data/lib/badline/vic20/bus.rb +3 -25
  320. data/lib/badline/vic20/cpu.rb +1 -1
  321. data/lib/badline/vic20/port_wiring.rb +4 -4
  322. data/lib/badline/vic20/saved_state.rb +16 -60
  323. data/lib/badline/vic20/user_via_ports.rb +2 -2
  324. data/lib/badline/vic20.rb +20 -51
  325. metadata +250 -221
  326. data/lib/badline/address_bus/extra_sids.rb +0 -30
  327. data/lib/badline/address_bus/fittings.rb +0 -38
  328. data/lib/badline/address_bus/pla.rb +0 -147
  329. data/lib/badline/address_bus/roms.rb +0 -39
  330. data/lib/badline/address_bus/saved_state.rb +0 -72
  331. data/lib/badline/address_bus/sid_slots.rb +0 -42
  332. data/lib/badline/address_bus.rb +0 -235
  333. data/lib/badline/cartridge/action_replay.rb +0 -126
  334. data/lib/badline/cartridge/atomic_power.rb +0 -24
  335. data/lib/badline/cartridge/bank.rb +0 -81
  336. data/lib/badline/cartridge/comal80.rb +0 -50
  337. data/lib/badline/cartridge/dinamic.rb +0 -34
  338. data/lib/badline/cartridge/easy_flash.rb +0 -145
  339. data/lib/badline/cartridge/epyx_fastload.rb +0 -79
  340. data/lib/badline/cartridge/final_cartridge3.rb +0 -89
  341. data/lib/badline/cartridge/flash.rb +0 -306
  342. data/lib/badline/cartridge/freezer.rb +0 -33
  343. data/lib/badline/cartridge/fun_play.rb +0 -38
  344. data/lib/badline/cartridge/g_mod2.rb +0 -74
  345. data/lib/badline/cartridge/game_system.rb +0 -40
  346. data/lib/badline/cartridge/geo_ram.rb +0 -79
  347. data/lib/badline/cartridge/kcs_power.rb +0 -75
  348. data/lib/badline/cartridge/mach5.rb +0 -32
  349. data/lib/badline/cartridge/magic_desk.rb +0 -30
  350. data/lib/badline/cartridge/ocean.rb +0 -35
  351. data/lib/badline/cartridge/pagefox.rb +0 -68
  352. data/lib/badline/cartridge/retro_replay.rb +0 -320
  353. data/lib/badline/cartridge/rex_utility.rb +0 -29
  354. data/lib/badline/cartridge/rgcd.rb +0 -58
  355. data/lib/badline/cartridge/simons_basic.rb +0 -35
  356. data/lib/badline/cartridge/standard.rb +0 -15
  357. data/lib/badline/cartridge/super_games.rb +0 -48
  358. data/lib/badline/cartridge/westermann.rb +0 -30
  359. data/lib/badline/cartridge/zaxxon.rb +0 -66
  360. data/lib/badline/cartridge.rb +0 -303
  361. data/lib/badline/checkpoint.rb +0 -98
  362. data/lib/badline/cia/fast_forward.rb +0 -60
  363. data/lib/badline/cia/interrupt_register.rb +0 -143
  364. data/lib/badline/cia/serial.rb +0 -275
  365. data/lib/badline/cia/state.rb +0 -47
  366. data/lib/badline/cia/timer.rb +0 -206
  367. data/lib/badline/cia.rb +0 -279
  368. data/lib/badline/color_memory.rb +0 -25
  369. data/lib/badline/computer/kernal_traps.rb +0 -29
  370. data/lib/badline/control_ports.rb +0 -76
  371. data/lib/badline/cpu/addressing.rb +0 -131
  372. data/lib/badline/cpu/boundary.rb +0 -54
  373. data/lib/badline/cpu/core.rb +0 -165
  374. data/lib/badline/cpu/microcode.rb +0 -177
  375. data/lib/badline/cpu/operations.rb +0 -88
  376. data/lib/badline/cpu/saved_state.rb +0 -115
  377. data/lib/badline/cpu/stack_operations.rb +0 -82
  378. data/lib/badline/cpu.rb +0 -10
  379. data/lib/badline/cycleable.rb +0 -38
  380. data/lib/badline/datasette.rb +0 -161
  381. data/lib/badline/drive/core.rb +0 -147
  382. data/lib/badline/drive/fast_serial.rb +0 -73
  383. data/lib/badline/drive/idle.rb +0 -125
  384. data/lib/badline/drive/idle_cpu.rb +0 -28
  385. data/lib/badline/drive/orbit.rb +0 -79
  386. data/lib/badline/drive/serial_lines.rb +0 -73
  387. data/lib/badline/drive/sleep.rb +0 -112
  388. data/lib/badline/drive/vias.rb +0 -84
  389. data/lib/badline/drive/watch.rb +0 -150
  390. data/lib/badline/drive.rb +0 -11
  391. data/lib/badline/drive1541/bus.rb +0 -86
  392. data/lib/badline/drive1541/byte_ready.rb +0 -48
  393. data/lib/badline/drive1541/cpu.rb +0 -11
  394. data/lib/badline/drive1541/disk.rb +0 -318
  395. data/lib/badline/drive1541/disk_state.rb +0 -94
  396. data/lib/badline/drive1541/disk_via.rb +0 -36
  397. data/lib/badline/drive1541/gcr.rb +0 -57
  398. data/lib/badline/drive1541/mechanism.rb +0 -313
  399. data/lib/badline/drive1541/mechanism_state.rb +0 -68
  400. data/lib/badline/drive1541/rotation.rb +0 -121
  401. data/lib/badline/drive1541/sector_reader.rb +0 -76
  402. data/lib/badline/drive1541/serial_port.rb +0 -18
  403. data/lib/badline/drive1541/track.rb +0 -98
  404. data/lib/badline/drive1541.rb +0 -111
  405. data/lib/badline/drive1571/bus.rb +0 -111
  406. data/lib/badline/drive1571/cpu.rb +0 -11
  407. data/lib/badline/drive1571/serial_port.rb +0 -37
  408. data/lib/badline/drive1571/serial_via.rb +0 -25
  409. data/lib/badline/drive1571/wd1770.rb +0 -120
  410. data/lib/badline/drive1571.rb +0 -175
  411. data/lib/badline/drive1581/bus.rb +0 -137
  412. data/lib/badline/drive1581/cpu.rb +0 -11
  413. data/lib/badline/drive1581/disk.rb +0 -135
  414. data/lib/badline/drive1581/disk_state.rb +0 -87
  415. data/lib/badline/drive1581/mechanism.rb +0 -117
  416. data/lib/badline/drive1581/serial_port.rb +0 -52
  417. data/lib/badline/drive1581/slot.rb +0 -78
  418. data/lib/badline/drive1581/track.rb +0 -100
  419. data/lib/badline/drive1581/track_bytes.rb +0 -75
  420. data/lib/badline/drive1581/wd1772/registers.rb +0 -89
  421. data/lib/badline/drive1581/wd1772/sector_writes.rb +0 -73
  422. data/lib/badline/drive1581/wd1772/sectors.rb +0 -150
  423. data/lib/badline/drive1581/wd1772/state.rb +0 -66
  424. data/lib/badline/drive1581/wd1772/stepping.rb +0 -109
  425. data/lib/badline/drive1581/wd1772/tracks.rb +0 -125
  426. data/lib/badline/drive1581/wd1772/turn.rb +0 -73
  427. data/lib/badline/drive1581/wd1772.rb +0 -216
  428. data/lib/badline/drive1581.rb +0 -233
  429. data/lib/badline/iec_bus.rb +0 -159
  430. data/lib/badline/instruction.rb +0 -334
  431. data/lib/badline/instruction_set/arithmetic.rb +0 -114
  432. data/lib/badline/instruction_set/bitwise.rb +0 -126
  433. data/lib/badline/instruction_set/branch.rb +0 -79
  434. data/lib/badline/instruction_set/flag.rb +0 -63
  435. data/lib/badline/instruction_set/illegal.rb +0 -270
  436. data/lib/badline/instruction_set/inc_dec.rb +0 -69
  437. data/lib/badline/instruction_set/stack.rb +0 -52
  438. data/lib/badline/instruction_set/transfer.rb +0 -137
  439. data/lib/badline/instruction_set.rb +0 -55
  440. data/lib/badline/interrupts.rb +0 -104
  441. data/lib/badline/joystick.rb +0 -25
  442. data/lib/badline/kernal_trap/channel.rb +0 -181
  443. data/lib/badline/keyboard.rb +0 -112
  444. data/lib/badline/ram_expansion/banking.rb +0 -30
  445. data/lib/badline/ram_expansion/plus256k.rb +0 -54
  446. data/lib/badline/ram_expansion/plus60k.rb +0 -43
  447. data/lib/badline/ram_expansion/unexpanded.rb +0 -28
  448. data/lib/badline/ram_expansion.rb +0 -21
  449. data/lib/badline/reu/dma/saved_state.rb +0 -50
  450. data/lib/badline/reu/dma.rb +0 -273
  451. data/lib/badline/reu/ram.rb +0 -107
  452. data/lib/badline/reu/saved_state.rb +0 -80
  453. data/lib/badline/reu/trigger.rb +0 -32
  454. data/lib/badline/reu.rb +0 -289
  455. data/lib/badline/sid/catch_up.rb +0 -120
  456. data/lib/badline/sid/decimator.rb +0 -64
  457. data/lib/badline/sid/envelope/state.rb +0 -68
  458. data/lib/badline/sid/envelope.rb +0 -239
  459. data/lib/badline/sid/filter.rb +0 -263
  460. data/lib/badline/sid/voice.rb +0 -77
  461. data/lib/badline/sid/waveform/combined.rb +0 -126
  462. data/lib/badline/sid/waveform/fast_forward.rb +0 -105
  463. data/lib/badline/sid/waveform/noise_writeback.rb +0 -122
  464. data/lib/badline/sid/waveform/state.rb +0 -66
  465. data/lib/badline/sid/waveform.rb +0 -305
  466. data/lib/badline/sid.rb +0 -303
  467. data/lib/badline/time_of_day.rb +0 -228
  468. data/lib/badline/traps.rb +0 -19
  469. data/lib/badline/via/control_lines.rb +0 -122
  470. data/lib/badline/via/fast_forward.rb +0 -53
  471. data/lib/badline/via/interrupt_register.rb +0 -67
  472. data/lib/badline/via/shift_register.rb +0 -180
  473. data/lib/badline/via/state.rb +0 -42
  474. data/lib/badline/via/timer1.rb +0 -131
  475. data/lib/badline/via/timer2.rb +0 -133
  476. data/lib/badline/via.rb +0 -266
  477. data/lib/badline/vic/bank.rb +0 -133
  478. data/lib/badline/vic/border_mask.rb +0 -86
  479. data/lib/badline/vic/collisions.rb +0 -115
  480. data/lib/badline/vic/color_patches.rb +0 -47
  481. data/lib/badline/vic/display_state.rb +0 -185
  482. data/lib/badline/vic/graphics_mode.rb +0 -164
  483. data/lib/badline/vic/graphics_shifter.rb +0 -207
  484. data/lib/badline/vic/register_log.rb +0 -81
  485. data/lib/badline/vic/registers.rb +0 -195
  486. data/lib/badline/vic/sequencer.rb +0 -275
  487. data/lib/badline/vic/sequencer_output.rb +0 -116
  488. data/lib/badline/vic/sequencer_state.rb +0 -89
  489. data/lib/badline/vic/sprite/internal_bus.rb +0 -68
  490. data/lib/badline/vic/sprite/saved_state.rb +0 -64
  491. data/lib/badline/vic/sprite/shifter.rb +0 -146
  492. data/lib/badline/vic/sprite/timing.rb +0 -56
  493. data/lib/badline/vic/sprite.rb +0 -337
  494. data/lib/badline/vic/sprites.rb +0 -282
  495. data/lib/badline/vic/sprites_state.rb +0 -57
  496. data/lib/badline/vic.rb +0 -852
  497. data/lib/badline/vic20/sound/output.rb +0 -83
  498. data/lib/badline/vic20/sound.rb +0 -233
  499. data/lib/badline/z80/arithmetic.rb +0 -117
  500. data/lib/badline/z80/bit_page.rb +0 -55
  501. data/lib/badline/z80/block_io.rb +0 -58
  502. data/lib/badline/z80/block_transfers.rb +0 -59
  503. data/lib/badline/z80/bus_cycles.rb +0 -111
  504. data/lib/badline/z80/core.rb +0 -113
  505. data/lib/badline/z80/exchanges.rb +0 -50
  506. data/lib/badline/z80/extended_page.rb +0 -89
  507. data/lib/badline/z80/flags.rb +0 -37
  508. data/lib/badline/z80/interrupt_acceptance.rb +0 -46
  509. data/lib/badline/z80/jumps.rb +0 -82
  510. data/lib/badline/z80/loads.rb +0 -98
  511. data/lib/badline/z80/main_page.rb +0 -134
  512. data/lib/badline/z80/registers.rb +0 -120
  513. data/lib/badline/z80/saved_state.rb +0 -69
  514. data/lib/badline/z80/shifts.rb +0 -64
  515. data/lib/badline/z80.rb +0 -11
  516. /data/lib/badline/snapshot/{fields.rb → vice/fields.rb} +0 -0
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ class Cartridge
6
+ # Ocean: up to 64 8K banks. A write to I/O 1 selects the bank from bits
7
+ # 0-5, masked to the size of the ROM.
8
+ class Ocean < Cartridge
9
+ def poke(addr, value)
10
+ return if addr > 0xdeff
11
+
12
+ select_bank(value & @bank_mask)
13
+ changed!
14
+ end
15
+
16
+ def reset
17
+ select_bank(0)
18
+ changed!
19
+ end
20
+
21
+ private
22
+
23
+ # In 16K mode the selected bank shows through ROMH as well.
24
+ def select_bank(number)
25
+ @roml = bank(@banks, number)
26
+ @romh = @roml if game.zero?
27
+ end
28
+
29
+ def install_chips(chips)
30
+ @banks = banks_from(chips).first
31
+ @bank_mask = bank_mask(@banks) & 0x3f
32
+ reset
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,70 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ class Cartridge
6
+ # Pagefox: two 32K EPROMs and 32K of RAM, seen 16K at a time. A write to
7
+ # $DE80-$DEFF selects the half with bit 1 and the chip with bits 2-3
8
+ # (EPROM, EPROM, RAM, nothing), and switches the cartridge out with
9
+ # bit 4. Writes to the RAM land in the C64's RAM as well.
10
+ class Pagefox < Cartridge
11
+ RAM_CHIP = 2
12
+ EMPTY_CHIP = 3
13
+
14
+ def connect(ram:, open_bus:)
15
+ super
16
+ @ram_banks.each { |b| b.backing = ram }
17
+ end
18
+
19
+ def poke(addr, value)
20
+ return if addr < 0xde80 || addr > 0xdeff
21
+
22
+ select(value)
23
+ changed!
24
+ end
25
+
26
+ def reset
27
+ select(0)
28
+ changed!
29
+ end
30
+
31
+ private
32
+
33
+ def save_mapper(out)
34
+ super
35
+ @ram_banks.each { |ram| out.blob(ram.data) }
36
+ end
37
+
38
+ def load_mapper(input)
39
+ super
40
+ @ram_banks.each { |ram| input.blob_into(ram.data) }
41
+ end
42
+
43
+ def windows = [*@roml_banks, *@romh_banks, *@ram_banks, @open_bus || EMPTY_BANK, EMPTY_BANK]
44
+
45
+ def select(value)
46
+ half = (value >> 1) & 0x01
47
+ chip = (value >> 2) & 0x03
48
+ @roml, @romh = window(chip, half)
49
+ self.mode = value.anybits?(0x10) ? :off : :rom16k
50
+ end
51
+
52
+ def window(chip, half)
53
+ case chip
54
+ when RAM_CHIP then @ram_banks[half * 2, 2]
55
+ when EMPTY_CHIP then [@open_bus || EMPTY_BANK] * 2
56
+ else
57
+ number = (chip << 1) | half
58
+ [bank(@roml_banks, number), bank(@romh_banks, number)]
59
+ end
60
+ end
61
+
62
+ def install_chips(chips)
63
+ @roml_banks, @romh_banks = banks_from(chips)
64
+ @ram_banks = Array.new(4) { RAMBank.new }
65
+ reset
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ class Cartridge
6
+ class RetroReplay < Cartridge
7
+ # A Retro Replay's registers, RAM and flash, for a snapshot.
8
+ module SavedState
9
+ private
10
+
11
+ def save_jumpers(out)
12
+ out.boolean(true).boolean(@flash_jumper).boolean(@bank_jumper)
13
+ end
14
+
15
+ def save_mapper(out)
16
+ [@active, @frozen, @phi1_ultimax, @ram_enabled, @ram_at_a000, @allow_bank, @no_freeze, @reu_mapping,
17
+ @write_once].each { |flag| out.boolean(flag) }
18
+ out.int(@bank).int(RetroReplay::CONTROL_MODES.index(@config))
19
+ @ram_data.each { |data| out.blob(data) }
20
+ @flash.save_state(out)
21
+ end
22
+
23
+ def load_mapper(input)
24
+ load_flags(input)
25
+ @bank = input.int
26
+ @config = RetroReplay::CONTROL_MODES.fetch(input.int)
27
+ @ram_data.each { |data| input.blob_into(data) }
28
+ @flash.load_state(input)
29
+ map_windows
30
+ end
31
+
32
+ def load_flags(input)
33
+ @active = input.boolean?
34
+ @frozen = input.boolean?
35
+ @phi1_ultimax = input.boolean?
36
+ @ram_enabled = input.boolean?
37
+ @ram_at_a000 = input.boolean?
38
+ @allow_bank = input.boolean?
39
+ @no_freeze = input.boolean?
40
+ @reu_mapping = input.boolean?
41
+ @write_once = input.boolean?
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,286 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "badline/c64/cartridge/retro_replay/saved_state"
4
+
5
+ module Badline
6
+ class C64
7
+ class Cartridge
8
+ # Retro Replay: an Am29F010 flash chip of two 64K halves, each eight 8K
9
+ # ROM banks, and four 8K RAM banks, with the Action Replay's register at
10
+ # $DE00 and an extended one at $DE01. The Nordic Replay (subtype 1) adds
11
+ # the Nordic Power configuration. The clock port isn't there.
12
+ #
13
+ # CRT banks 0-7 are the chip's upper half and banks 8-15 its lower half.
14
+ # The cartridge runs from the upper half, or from the lower one with the
15
+ # bank jumper set.
16
+ #
17
+ # $DE00 writes:
18
+ # bit 0 pulls GAME low
19
+ # bit 1 releases EXROM
20
+ # bit 2 switches the registers off until the next freeze or reset
21
+ # bits 3-4,7 bank
22
+ # bit 5 RAM instead of ROM
23
+ # bit 6 acknowledges a freeze: until then the cartridge stays in
24
+ # Ultimax mode with nothing at ROML
25
+ #
26
+ # $DE01 writes the bank again, and once only AllowBank (bit 1), which
27
+ # banks the RAM in I/O as well, NoFreeze (bit 2) and the REU-compatible
28
+ # map (bit 6), which moves the I/O RAM from I/O 2 to I/O 1 above $DE01.
29
+ # $DE00 and $DE01 read back the bank, the write-once bits and the freeze
30
+ # button.
31
+ #
32
+ # The VIC sees Ultimax mode only from a freeze to the next $DE00 write.
33
+ #
34
+ # The RAM at ROML takes writes only in Ultimax mode, except on the Nordic
35
+ # Replay. With RAM and only EXROM released ($22) the Retro Replay maps
36
+ # nothing at ROML and keeps the RAM in I/O, and the Nordic Replay maps
37
+ # the ROM at ROML and the RAM at ROMH, as the Nordic Power does. Frozen
38
+ # in that configuration, the Nordic Replay maps the RAM at $A000.
39
+ #
40
+ # The flash jumper puts the cartridge in flash mode, which starts with
41
+ # the cartridge switched off ($02) and has no freeze. $DE00 selects 8K
42
+ # mode unless it switches the cartridge off, and writes to ROML reach
43
+ # the flash, and the C64's RAM underneath, or the RAM when selected.
44
+ # $DE01 isn't write-once and has no REU-compatible map, and with the
45
+ # bank jumper set its bit 5 clear selects the other half of the flash,
46
+ # until the next $DE00 write. $DE00 reads the flash jumper in bit 0 and
47
+ # the half in bit 5.
48
+ class RetroReplay < Cartridge
49
+ include Freezer
50
+ include SavedState
51
+
52
+ CONTROL_MODES = %i[rom8k rom16k off ultimax].freeze
53
+ IO1_PAGE = 0x1e00
54
+ IO2_PAGE = 0x1f00
55
+
56
+ attr_reader :flash
57
+
58
+ def self.from_jumpers(crt, input)
59
+ input.boolean?
60
+ new(crt, flash_jumper: input.boolean?, bank_jumper: input.boolean?)
61
+ end
62
+
63
+ def initialize(crt, flash_jumper: false, bank_jumper: false)
64
+ @nordic = crt.subtype == 1
65
+ @flash_jumper = flash_jumper
66
+ @bank_jumper = bank_jumper
67
+ super(crt)
68
+ end
69
+
70
+ def clock=(clock)
71
+ super
72
+ @flash.clock = clock
73
+ end
74
+
75
+ def connect(ram:, open_bus:)
76
+ super
77
+ @through.each { |b| b.backing = ram }
78
+ configure
79
+ end
80
+
81
+ def readable_io_pages
82
+ [0xde, 0xdf]
83
+ end
84
+
85
+ def peek(addr)
86
+ return open_bus(addr) unless @active
87
+
88
+ addr < 0xdf00 ? io1_peek(addr) : io2_peek(addr)
89
+ end
90
+
91
+ def poke(addr, value)
92
+ return unless @active
93
+
94
+ low = addr & 0xff
95
+ if addr >= 0xdf00
96
+ io_ram[IO2_PAGE | low] = value if io_ram_writable?(!@reu_mapping)
97
+ elsif low > 1
98
+ io_ram[IO1_PAGE | low] = value if io_ram_writable?(@reu_mapping)
99
+ else
100
+ low.zero? ? control(value) : extended_control(value)
101
+ end
102
+ end
103
+
104
+ def phi1_ultimax? = @phi1_ultimax
105
+
106
+ def ultimax_a000
107
+ @isolated[ram_view_bank] if @nordic && @ram_at_a000 && @frozen
108
+ end
109
+
110
+ # Reset leaves the write-once bits of $DE01 as they are.
111
+ def reset
112
+ @active = true
113
+ @frozen = false
114
+ self.nmi = false
115
+ control(@flash_jumper ? 0x02 : 0x00)
116
+ end
117
+
118
+ def freeze!
119
+ @active = @frozen = @phi1_ultimax = true
120
+ @ram_enabled = false
121
+ @bank = 0
122
+ @config = :ultimax
123
+ configure
124
+ end
125
+
126
+ private
127
+
128
+ def freeze_allowed? = !@no_freeze && !@flash_jumper
129
+
130
+ def status
131
+ ((@bank & 0x03) << 3) | ((@bank & 0x04) << 5) | ((@bank & 0x08) << 2) | (@flash_jumper ? 0x01 : 0) |
132
+ (@allow_bank ? 0x02 : 0) | (button_pressed? ? 0x04 : 0) | (@reu_mapping ? 0x40 : 0)
133
+ end
134
+
135
+ def io1_peek(addr)
136
+ return status if (addr & 0xff) < 2
137
+ return open_bus(addr) unless @reu_mapping && !@frozen
138
+
139
+ io_window(addr, IO1_PAGE)
140
+ end
141
+
142
+ def io2_peek(addr)
143
+ return open_bus(addr) if @reu_mapping || @frozen
144
+
145
+ io_window(addr, IO2_PAGE)
146
+ end
147
+
148
+ # The I/O RAM when selected, otherwise the ROM, which 16K and Ultimax
149
+ # mode leave out.
150
+ def io_window(addr, page)
151
+ if @ram_enabled || @ram_at_a000
152
+ io_ram[page | (addr & 0xff)]
153
+ elsif @config == :rom8k || @config == :off
154
+ @rom.peek(addr)
155
+ else
156
+ open_bus(addr)
157
+ end
158
+ end
159
+
160
+ def io_ram
161
+ @ram_data[ram_view_bank]
162
+ end
163
+
164
+ def io_ram_writable?(window)
165
+ window && !@frozen && (@ram_enabled || (@nordic && @ram_at_a000))
166
+ end
167
+
168
+ def ram_view_bank
169
+ @allow_bank ? @bank & 0x03 : 0
170
+ end
171
+
172
+ def control(value)
173
+ value = flash_mode_control(value)
174
+ @bank = bank_bits(value)
175
+ @phi1_ultimax = false
176
+ @config = CONTROL_MODES[value & 0x03]
177
+ @ram_at_a000 = (value & 0x67) == 0x22
178
+ if @nordic && @ram_at_a000
179
+ @config = :rom16k
180
+ @ram_enabled = false
181
+ else
182
+ acknowledge_freeze if value.anybits?(0x40)
183
+ @ram_enabled = value.anybits?(0x20)
184
+ @config = :off if @ram_at_a000
185
+ end
186
+ @config = :ultimax if @frozen
187
+ configure
188
+ @active = false if value.anybits?(0x04)
189
+ end
190
+
191
+ # Flash mode leaves 8K mode only to switch the cartridge off.
192
+ def flash_mode_control(value)
193
+ return value unless @flash_jumper && (value & 0x03) != 0x02
194
+
195
+ value & ~0x03
196
+ end
197
+
198
+ def acknowledge_freeze
199
+ @frozen = false
200
+ self.nmi = false
201
+ end
202
+
203
+ def extended_control(value)
204
+ unless @write_once
205
+ @allow_bank = value.anybits?(0x02)
206
+ @no_freeze = value.anybits?(0x04)
207
+ @reu_mapping = value.anybits?(0x40) && !@flash_jumper
208
+ @write_once = !@flash_jumper
209
+ end
210
+ @bank = bank_bits(value)
211
+ @bank |= 0x08 if @flash_jumper && @bank_jumper && value.nobits?(0x20)
212
+ configure
213
+ end
214
+
215
+ def bank_bits(value)
216
+ ((value >> 3) & 0x03) | ((value >> 5) & 0x04)
217
+ end
218
+
219
+ def configure
220
+ map_windows
221
+ changed!
222
+ end
223
+
224
+ def map_windows
225
+ self.mode = @config
226
+ @rom = flash_window(@bank)
227
+ @roml = roml_window
228
+ @romh = romh_window
229
+ end
230
+
231
+ def roml_window
232
+ nothing = @open_bus || EMPTY_BANK
233
+ return @ram_enabled ? WriteOnlyRAM.new(@ram_data[@bank & 0x03], nothing) : nothing if @frozen
234
+ return ram_window(@bank & 0x03) if @ram_enabled
235
+ return flash_writes if (@nordic && @ram_at_a000) || @config != :rom16k
236
+
237
+ nothing
238
+ end
239
+
240
+ # A RAM bank over the flash window takes writes for the chip and the
241
+ # C64's RAM alike.
242
+ def flash_writes
243
+ return @rom unless @flash_jumper
244
+
245
+ RAMBank.new(@rom).tap { |window| window.backing = @ram }
246
+ end
247
+
248
+ def ram_window(number)
249
+ if @config == :ultimax || @flash_jumper
250
+ @isolated[number]
251
+ else
252
+ (@nordic ? @through : @readers)[number]
253
+ end
254
+ end
255
+
256
+ def romh_window
257
+ nordic_ram = @nordic && @ram_at_a000
258
+ return @isolated[ram_view_bank] if nordic_ram && !@frozen
259
+ return @rom if @allow_bank || !(@ram_enabled || nordic_ram)
260
+
261
+ flash_window(@bank & ~0x03)
262
+ end
263
+
264
+ def flash_window(number)
265
+ @flash.window((@bank_jumper ? 0 : 0x10000) + (number * BANK_SIZE))
266
+ end
267
+
268
+ def install_chips(chips)
269
+ data = Array.new(0x20000, 0xff)
270
+ chips.each do |chip|
271
+ bytes = chip.data.first(BANK_SIZE)
272
+ data[((chip.bank & 0x0f) ^ 0x08) * BANK_SIZE, bytes.length] = bytes
273
+ end
274
+ @flash = Flash.new(data, model: Flash::AM29F010)
275
+ @flash.on_change { configure }
276
+ @ram_data = Array.new(4) { Array.new(BANK_SIZE, 0) }
277
+ @through = @ram_data.map { |data| RAMBank.new(data) }
278
+ @isolated = @ram_data.map { |data| RAMBank.new(data) }
279
+ @readers = @ram_data.map { |data| RAMReader.new(data) }
280
+ @allow_bank = @no_freeze = @reu_mapping = @write_once = false
281
+ reset
282
+ end
283
+ end
284
+ end
285
+ end
286
+ end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ class Cartridge
6
+ # 8K. Reading $DF00-$DFBF switches the ROM out, reading $DFC0-$DFFF
7
+ # switches it back in.
8
+ class RexUtility < Cartridge
9
+ def readable_io_pages
10
+ [0xdf]
11
+ end
12
+
13
+ def peek(addr)
14
+ select_mode((addr & 0xff) < 0xc0 ? :off : :rom8k) if addr >= 0xdf00
15
+ open_bus(addr)
16
+ end
17
+
18
+ def reset
19
+ select_mode(:rom8k)
20
+ end
21
+
22
+ private
23
+
24
+ def install_chips(chips)
25
+ @roml = banks_from(chips).first.compact.first || EMPTY_BANK
26
+ reset
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -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