badline 0.12.1 → 0.14.0

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