badline 0.12.1 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (505) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -0
  3. data/CLAUDE.md +59 -31
  4. data/README.md +1 -1
  5. data/doc/library.md +9 -9
  6. data/doc/pinned-behaviour.md +105 -105
  7. data/doc/snapshots.md +1 -4
  8. data/lib/badline/audio/bare_player.rb +3 -3
  9. data/lib/badline/audio/cli.rb +6 -6
  10. data/lib/badline/audio/jukebox.rb +2 -2
  11. data/lib/badline/audio/machine_player.rb +2 -2
  12. data/lib/badline/{media → audio}/queue.rb +1 -1
  13. data/lib/badline/audio/queued_tune.rb +6 -6
  14. data/lib/badline/audio/renderer.rb +5 -5
  15. data/lib/badline/audio/stereo.rb +1 -1
  16. data/lib/badline/c128/{bus_state.rb → bus/saved_state.rb} +1 -1
  17. data/lib/badline/c128/bus.rb +18 -17
  18. data/lib/badline/c128/color_lines.rb +2 -2
  19. data/lib/badline/c128/cpu.rb +1 -1
  20. data/lib/badline/c128/drives.rb +10 -11
  21. data/lib/badline/c128/fast_serial.rb +5 -5
  22. data/lib/badline/c128/mmu_pages.rb +1 -1
  23. data/lib/badline/c128/modes.rb +2 -2
  24. data/lib/badline/c128/saved_state.rb +21 -47
  25. data/lib/badline/c128/z80.rb +2 -2
  26. data/lib/badline/c128.rb +14 -9
  27. data/lib/badline/{computer → c64}/attachments.rb +4 -6
  28. data/lib/badline/c64/banked_ram/banking.rb +32 -0
  29. data/lib/badline/c64/banked_ram/plus256k.rb +56 -0
  30. data/lib/badline/c64/banked_ram/plus60k.rb +45 -0
  31. data/lib/badline/c64/banked_ram/unexpanded.rb +30 -0
  32. data/lib/badline/c64/banked_ram.rb +23 -0
  33. data/lib/badline/c64/bus/extra_sids.rb +32 -0
  34. data/lib/badline/c64/bus/fittings.rb +40 -0
  35. data/lib/badline/c64/bus/pla.rb +149 -0
  36. data/lib/badline/c64/bus/roms.rb +41 -0
  37. data/lib/badline/c64/bus/saved_state.rb +68 -0
  38. data/lib/badline/c64/bus/sid_slots.rb +44 -0
  39. data/lib/badline/c64/bus.rb +218 -0
  40. data/lib/badline/c64/cartridge/action_replay.rb +128 -0
  41. data/lib/badline/c64/cartridge/atomic_power.rb +26 -0
  42. data/lib/badline/c64/cartridge/bank.rb +83 -0
  43. data/lib/badline/c64/cartridge/comal80.rb +52 -0
  44. data/lib/badline/c64/cartridge/dinamic.rb +36 -0
  45. data/lib/badline/c64/cartridge/easy_flash.rb +147 -0
  46. data/lib/badline/c64/cartridge/epyx_fastload.rb +81 -0
  47. data/lib/badline/c64/cartridge/final_cartridge3.rb +91 -0
  48. data/lib/badline/c64/cartridge/flash/saved_state.rb +40 -0
  49. data/lib/badline/c64/cartridge/flash.rb +279 -0
  50. data/lib/badline/c64/cartridge/freezer.rb +35 -0
  51. data/lib/badline/c64/cartridge/fun_play.rb +40 -0
  52. data/lib/badline/c64/cartridge/g_mod2.rb +76 -0
  53. data/lib/badline/c64/cartridge/game_system.rb +42 -0
  54. data/lib/badline/c64/cartridge/geo_ram.rb +81 -0
  55. data/lib/badline/c64/cartridge/kcs_power.rb +77 -0
  56. data/lib/badline/c64/cartridge/mach5.rb +34 -0
  57. data/lib/badline/c64/cartridge/magic_desk.rb +32 -0
  58. data/lib/badline/c64/cartridge/ocean.rb +37 -0
  59. data/lib/badline/c64/cartridge/pagefox.rb +70 -0
  60. data/lib/badline/c64/cartridge/retro_replay/saved_state.rb +47 -0
  61. data/lib/badline/c64/cartridge/retro_replay.rb +286 -0
  62. data/lib/badline/c64/cartridge/rex_utility.rb +31 -0
  63. data/lib/badline/c64/cartridge/rgcd.rb +60 -0
  64. data/lib/badline/c64/cartridge/saved_state.rb +63 -0
  65. data/lib/badline/c64/cartridge/simons_basic.rb +37 -0
  66. data/lib/badline/c64/cartridge/standard.rb +17 -0
  67. data/lib/badline/c64/cartridge/super_games.rb +50 -0
  68. data/lib/badline/c64/cartridge/westermann.rb +32 -0
  69. data/lib/badline/c64/cartridge/zaxxon.rb +68 -0
  70. data/lib/badline/c64/cartridge.rb +258 -0
  71. data/lib/badline/c64/color_memory.rb +27 -0
  72. data/lib/badline/{computer → c64}/common.rb +2 -2
  73. data/lib/badline/{computer → c64}/kernal_traps.rb +18 -18
  74. data/lib/badline/c64/reu/dma/saved_state.rb +52 -0
  75. data/lib/badline/c64/reu/dma.rb +275 -0
  76. data/lib/badline/c64/reu/ram.rb +109 -0
  77. data/lib/badline/c64/reu/saved_state.rb +55 -0
  78. data/lib/badline/c64/reu/trigger.rb +34 -0
  79. data/lib/badline/c64/reu.rb +291 -0
  80. data/lib/badline/{computer → c64}/saved_state.rb +13 -18
  81. data/lib/badline/{computer → c64}/true_drives.rb +11 -11
  82. data/lib/badline/{computer.rb → c64.rb} +18 -13
  83. data/lib/badline/chips/cia/fast_forward.rb +62 -0
  84. data/lib/badline/chips/cia/interrupt_register.rb +145 -0
  85. data/lib/badline/chips/cia/saved_state.rb +49 -0
  86. data/lib/badline/chips/cia/serial/saved_state.rb +45 -0
  87. data/lib/badline/chips/cia/serial.rb +250 -0
  88. data/lib/badline/chips/cia/time_of_day.rb +232 -0
  89. data/lib/badline/chips/cia/timer.rb +208 -0
  90. data/lib/badline/chips/cia.rb +281 -0
  91. data/lib/badline/chips/cpu/addressing.rb +133 -0
  92. data/lib/badline/chips/cpu/boundary.rb +56 -0
  93. data/lib/badline/chips/cpu/core.rb +167 -0
  94. data/lib/badline/chips/cpu/instruction.rb +338 -0
  95. data/lib/badline/chips/cpu/instruction_set/arithmetic.rb +118 -0
  96. data/lib/badline/chips/cpu/instruction_set/bitwise.rb +130 -0
  97. data/lib/badline/chips/cpu/instruction_set/branch.rb +83 -0
  98. data/lib/badline/chips/cpu/instruction_set/flag.rb +67 -0
  99. data/lib/badline/chips/cpu/instruction_set/illegal.rb +274 -0
  100. data/lib/badline/chips/cpu/instruction_set/inc_dec.rb +73 -0
  101. data/lib/badline/chips/cpu/instruction_set/stack.rb +56 -0
  102. data/lib/badline/chips/cpu/instruction_set/transfer.rb +141 -0
  103. data/lib/badline/chips/cpu/instruction_set.rb +59 -0
  104. data/lib/badline/chips/cpu/interrupts.rb +108 -0
  105. data/lib/badline/chips/cpu/microcode.rb +179 -0
  106. data/lib/badline/chips/cpu/operations.rb +90 -0
  107. data/lib/badline/chips/cpu/port.rb +116 -0
  108. data/lib/badline/chips/cpu/saved_state.rb +117 -0
  109. data/lib/badline/chips/cpu/stack_operations.rb +84 -0
  110. data/lib/badline/chips/cpu/traps.rb +23 -0
  111. data/lib/badline/chips/cpu.rb +12 -0
  112. data/lib/badline/chips/sid/catch_up.rb +122 -0
  113. data/lib/badline/chips/sid/decimator.rb +66 -0
  114. data/lib/badline/chips/sid/envelope/saved_state.rb +70 -0
  115. data/lib/badline/chips/sid/envelope.rb +241 -0
  116. data/lib/badline/chips/sid/filter/saved_state.rb +42 -0
  117. data/lib/badline/chips/sid/filter.rb +241 -0
  118. data/lib/badline/chips/sid/saved_state.rb +52 -0
  119. data/lib/badline/chips/sid/voice.rb +79 -0
  120. data/lib/badline/chips/sid/waveform/combined.rb +128 -0
  121. data/lib/badline/chips/sid/waveform/fast_forward.rb +107 -0
  122. data/lib/badline/chips/sid/waveform/noise_writeback.rb +124 -0
  123. data/lib/badline/chips/sid/waveform/saved_state.rb +68 -0
  124. data/lib/badline/chips/sid/waveform.rb +307 -0
  125. data/lib/badline/chips/sid.rb +265 -0
  126. data/lib/badline/{c128 → chips}/vdc/memory.rb +1 -1
  127. data/lib/badline/{c128 → chips}/vdc/painter.rb +1 -1
  128. data/lib/badline/{c128 → chips}/vdc/raster.rb +1 -1
  129. data/lib/badline/chips/vdc/saved_state.rb +36 -0
  130. data/lib/badline/{c128 → chips}/vdc/window.rb +1 -1
  131. data/lib/badline/{c128 → chips}/vdc.rb +7 -31
  132. data/lib/badline/chips/via/control_lines.rb +124 -0
  133. data/lib/badline/chips/via/fast_forward.rb +55 -0
  134. data/lib/badline/chips/via/interrupt_register.rb +69 -0
  135. data/lib/badline/chips/via/saved_state.rb +44 -0
  136. data/lib/badline/chips/via/shift_register.rb +182 -0
  137. data/lib/badline/chips/via/timer1.rb +133 -0
  138. data/lib/badline/chips/via/timer2.rb +135 -0
  139. data/lib/badline/chips/via.rb +268 -0
  140. data/lib/badline/chips/vic/bank.rb +135 -0
  141. data/lib/badline/chips/vic/border_mask.rb +88 -0
  142. data/lib/badline/chips/vic/collisions.rb +117 -0
  143. data/lib/badline/chips/vic/color_patches.rb +49 -0
  144. data/lib/badline/chips/vic/display_state.rb +187 -0
  145. data/lib/badline/chips/vic/graphics_mode.rb +166 -0
  146. data/lib/badline/chips/vic/graphics_shifter/saved_state.rb +40 -0
  147. data/lib/badline/chips/vic/graphics_shifter.rb +187 -0
  148. data/lib/badline/chips/vic/register_log.rb +83 -0
  149. data/lib/badline/chips/vic/registers.rb +197 -0
  150. data/lib/badline/chips/vic/saved_state.rb +82 -0
  151. data/lib/badline/chips/vic/sequencer/saved_state.rb +91 -0
  152. data/lib/badline/chips/vic/sequencer.rb +277 -0
  153. data/lib/badline/chips/vic/sequencer_output.rb +118 -0
  154. data/lib/badline/chips/vic/sprite/internal_bus.rb +70 -0
  155. data/lib/badline/chips/vic/sprite/saved_state.rb +66 -0
  156. data/lib/badline/chips/vic/sprite/shifter.rb +148 -0
  157. data/lib/badline/chips/vic/sprite/timing.rb +58 -0
  158. data/lib/badline/chips/vic/sprite.rb +339 -0
  159. data/lib/badline/chips/vic/sprites/saved_state.rb +59 -0
  160. data/lib/badline/chips/vic/sprites.rb +284 -0
  161. data/lib/badline/chips/vic.rb +783 -0
  162. data/lib/badline/chips/vic_i/painter/saved_state.rb +40 -0
  163. data/lib/badline/{vic20/vic → chips/vic_i}/painter.rb +6 -30
  164. data/lib/badline/{vic20/vic → chips/vic_i}/saved_state.rb +2 -2
  165. data/lib/badline/chips/vic_i/sound/output.rb +85 -0
  166. data/lib/badline/chips/vic_i/sound.rb +235 -0
  167. data/lib/badline/{vic20/vic → chips/vic_i}/text_window.rb +2 -2
  168. data/lib/badline/{vic20/vic.rb → chips/vic_i.rb} +5 -5
  169. data/lib/badline/chips/z80/arithmetic.rb +119 -0
  170. data/lib/badline/chips/z80/bit_page.rb +57 -0
  171. data/lib/badline/chips/z80/block_io.rb +60 -0
  172. data/lib/badline/chips/z80/block_transfers.rb +61 -0
  173. data/lib/badline/chips/z80/bus_cycles.rb +113 -0
  174. data/lib/badline/chips/z80/core.rb +115 -0
  175. data/lib/badline/chips/z80/exchanges.rb +52 -0
  176. data/lib/badline/chips/z80/extended_page.rb +91 -0
  177. data/lib/badline/chips/z80/flags.rb +39 -0
  178. data/lib/badline/chips/z80/interrupt_acceptance.rb +48 -0
  179. data/lib/badline/chips/z80/jumps.rb +84 -0
  180. data/lib/badline/chips/z80/loads.rb +100 -0
  181. data/lib/badline/chips/z80/main_page.rb +136 -0
  182. data/lib/badline/chips/z80/registers.rb +122 -0
  183. data/lib/badline/chips/z80/saved_state.rb +71 -0
  184. data/lib/badline/chips/z80/shifts.rb +66 -0
  185. data/lib/badline/chips/z80.rb +13 -0
  186. data/lib/badline/core.rb +26 -28
  187. data/lib/badline/drives/datasette/saved_state.rb +37 -0
  188. data/lib/badline/drives/datasette.rb +140 -0
  189. data/lib/badline/drives/engine/core.rb +149 -0
  190. data/lib/badline/drives/engine/fast_serial.rb +75 -0
  191. data/lib/badline/drives/engine/idle.rb +127 -0
  192. data/lib/badline/drives/engine/idle_cpu.rb +30 -0
  193. data/lib/badline/drives/engine/orbit.rb +81 -0
  194. data/lib/badline/drives/engine/serial_lines.rb +75 -0
  195. data/lib/badline/drives/engine/sleep.rb +114 -0
  196. data/lib/badline/drives/engine/vias.rb +86 -0
  197. data/lib/badline/drives/engine/watch.rb +152 -0
  198. data/lib/badline/drives/engine.rb +11 -0
  199. data/lib/badline/drives/model1541/bus.rb +88 -0
  200. data/lib/badline/drives/model1541/byte_ready.rb +50 -0
  201. data/lib/badline/drives/model1541/cpu.rb +13 -0
  202. data/lib/badline/drives/model1541/disk/saved_state.rb +88 -0
  203. data/lib/badline/drives/model1541/disk.rb +317 -0
  204. data/lib/badline/drives/model1541/disk_via.rb +38 -0
  205. data/lib/badline/drives/model1541/gcr.rb +59 -0
  206. data/lib/badline/drives/model1541/mechanism/saved_state.rb +72 -0
  207. data/lib/badline/drives/model1541/mechanism.rb +315 -0
  208. data/lib/badline/drives/model1541/rotation.rb +123 -0
  209. data/lib/badline/drives/model1541/saved_state.rb +44 -0
  210. data/lib/badline/drives/model1541/sector_reader.rb +78 -0
  211. data/lib/badline/drives/model1541/serial_port.rb +20 -0
  212. data/lib/badline/drives/model1541/track.rb +100 -0
  213. data/lib/badline/drives/model1541.rb +81 -0
  214. data/lib/badline/drives/model1571/bus.rb +113 -0
  215. data/lib/badline/drives/model1571/cpu.rb +13 -0
  216. data/lib/badline/drives/model1571/saved_state.rb +47 -0
  217. data/lib/badline/drives/model1571/serial_port.rb +39 -0
  218. data/lib/badline/drives/model1571/serial_via.rb +27 -0
  219. data/lib/badline/drives/model1571/wd1770.rb +122 -0
  220. data/lib/badline/drives/model1571.rb +142 -0
  221. data/lib/badline/drives/model1581/bus.rb +139 -0
  222. data/lib/badline/drives/model1581/cpu.rb +13 -0
  223. data/lib/badline/drives/model1581/disk/saved_state.rb +89 -0
  224. data/lib/badline/drives/model1581/disk.rb +137 -0
  225. data/lib/badline/drives/model1581/mechanism.rb +119 -0
  226. data/lib/badline/drives/model1581/saved_state.rb +42 -0
  227. data/lib/badline/drives/model1581/serial_port.rb +54 -0
  228. data/lib/badline/drives/model1581/slot.rb +79 -0
  229. data/lib/badline/drives/model1581/track.rb +102 -0
  230. data/lib/badline/drives/model1581/track_bytes.rb +77 -0
  231. data/lib/badline/drives/model1581/wd1772/registers.rb +91 -0
  232. data/lib/badline/drives/model1581/wd1772/saved_state.rb +68 -0
  233. data/lib/badline/drives/model1581/wd1772/sector_writes.rb +75 -0
  234. data/lib/badline/drives/model1581/wd1772/sectors.rb +152 -0
  235. data/lib/badline/drives/model1581/wd1772/stepping.rb +111 -0
  236. data/lib/badline/drives/model1581/wd1772/tracks.rb +127 -0
  237. data/lib/badline/drives/model1581/wd1772/turn.rb +75 -0
  238. data/lib/badline/drives/model1581/wd1772.rb +218 -0
  239. data/lib/badline/drives/model1581.rb +206 -0
  240. data/lib/badline/drives/serial_bus.rb +161 -0
  241. data/lib/badline/frontend/boot.rb +3 -3
  242. data/lib/badline/frontend/machine_window.rb +3 -1
  243. data/lib/badline/frontend/player/filter_view.rb +1 -1
  244. data/lib/badline/frontend/player/player_controller.rb +2 -2
  245. data/lib/badline/frontend/player/player_screen.rb +1 -0
  246. data/lib/badline/frontend/player/theme.rb +7 -7
  247. data/lib/badline/frontend/timeline.rb +3 -3
  248. data/lib/badline/input/control_ports.rb +78 -0
  249. data/lib/badline/input/joystick.rb +27 -0
  250. data/lib/badline/input/keyboard.rb +114 -0
  251. data/lib/badline/input.rb +3 -0
  252. data/lib/badline/kernal_trap/{drive → dos}/block_commands.rb +1 -1
  253. data/lib/badline/kernal_trap/dos/channel.rb +183 -0
  254. data/lib/badline/kernal_trap/{drive → dos}/channels.rb +1 -1
  255. data/lib/badline/kernal_trap/{drive → dos}/memory.rb +1 -1
  256. data/lib/badline/kernal_trap/{drive → dos}/parameters.rb +1 -1
  257. data/lib/badline/kernal_trap/{drive → dos}/status.rb +1 -1
  258. data/lib/badline/kernal_trap/{drive → dos}/write_file.rb +1 -1
  259. data/lib/badline/kernal_trap/{drive → dos}/writes.rb +1 -1
  260. data/lib/badline/kernal_trap/{drive.rb → dos.rb} +11 -10
  261. data/lib/badline/kernal_trap/load.rb +5 -5
  262. data/lib/badline/kernal_trap/save.rb +4 -4
  263. data/lib/badline/kernal_trap/serial.rb +7 -7
  264. data/lib/badline/kernal_trap.rb +1 -2
  265. data/lib/badline/machine/clocking.rb +1 -1
  266. data/lib/badline/machine.rb +5 -5
  267. data/lib/badline/media/true_drive.rb +1 -1
  268. data/lib/badline/media/tune.rb +2 -2
  269. data/lib/badline/media.rb +3 -3
  270. data/lib/badline/model.rb +1 -1
  271. data/lib/badline/roms/README +6 -6
  272. data/lib/badline/sdl.rb +1 -0
  273. data/lib/badline/{storage/sid_file.rb → sid_tune/file.rb} +3 -3
  274. data/lib/badline/{storage → sid_tune}/hvsc.rb +7 -7
  275. data/lib/badline/{storage → sid_tune}/song_lengths.rb +2 -2
  276. data/lib/badline/{storage → sid_tune}/stil/credit.rb +1 -1
  277. data/lib/badline/{storage → sid_tune}/stil.rb +3 -3
  278. data/lib/badline/sid_tune.rb +6 -0
  279. data/lib/badline/snapshot/c128_setup.rb +43 -0
  280. data/lib/badline/snapshot/c64_setup.rb +79 -0
  281. data/lib/badline/snapshot/image.rb +5 -25
  282. data/lib/badline/snapshot/machine_state.rb +1 -1
  283. data/lib/badline/snapshot/setup.rb +22 -66
  284. data/lib/badline/snapshot/state.rb +8 -18
  285. data/lib/badline/snapshot/storage_setup.rb +68 -0
  286. data/lib/badline/snapshot/vic20_setup.rb +37 -0
  287. data/lib/badline/snapshot/vice/c64_mem.rb +1 -1
  288. data/lib/badline/snapshot/vice/restore.rb +1 -1
  289. data/lib/badline/snapshot/vice/reu1764.rb +1 -1
  290. data/lib/badline/snapshot/vice/reu_fields.rb +40 -0
  291. data/lib/badline/snapshot/vice.rb +7 -5
  292. data/lib/badline/snapshot.rb +3 -4
  293. data/lib/badline/storage/d64_image.rb +0 -2
  294. data/lib/badline/storage/d71_image.rb +0 -2
  295. data/lib/badline/storage/d81_image.rb +0 -2
  296. data/lib/badline/storage/disk_image.rb +3 -6
  297. data/lib/badline/storage/g64_image.rb +2 -2
  298. data/lib/badline/storage/host_directory.rb +0 -5
  299. data/lib/badline/storage/t64.rb +2 -8
  300. data/lib/badline/storage/unavailable.rb +1 -1
  301. data/lib/badline/storage.rb +0 -37
  302. data/lib/badline/support/c128_checkpoint.rb +39 -0
  303. data/lib/badline/support/checkpoint.rb +108 -0
  304. data/lib/badline/support/vic20_checkpoint.rb +38 -0
  305. data/lib/badline/support.rb +5 -0
  306. data/lib/badline/version.rb +1 -1
  307. data/lib/badline/vic20/attachments.rb +5 -5
  308. data/lib/badline/vic20/bus/saved_state.rb +35 -0
  309. data/lib/badline/vic20/bus.rb +3 -25
  310. data/lib/badline/vic20/cpu.rb +1 -1
  311. data/lib/badline/vic20/port_wiring.rb +4 -4
  312. data/lib/badline/vic20/saved_state.rb +16 -30
  313. data/lib/badline/vic20/user_via_ports.rb +2 -2
  314. data/lib/badline/vic20.rb +19 -14
  315. metadata +245 -221
  316. data/lib/badline/address_bus/extra_sids.rb +0 -30
  317. data/lib/badline/address_bus/fittings.rb +0 -38
  318. data/lib/badline/address_bus/pla.rb +0 -147
  319. data/lib/badline/address_bus/roms.rb +0 -39
  320. data/lib/badline/address_bus/saved_state.rb +0 -66
  321. data/lib/badline/address_bus/sid_slots.rb +0 -42
  322. data/lib/badline/address_bus.rb +0 -216
  323. data/lib/badline/cartridge/action_replay.rb +0 -126
  324. data/lib/badline/cartridge/atomic_power.rb +0 -24
  325. data/lib/badline/cartridge/bank.rb +0 -81
  326. data/lib/badline/cartridge/comal80.rb +0 -50
  327. data/lib/badline/cartridge/dinamic.rb +0 -34
  328. data/lib/badline/cartridge/easy_flash.rb +0 -145
  329. data/lib/badline/cartridge/epyx_fastload.rb +0 -79
  330. data/lib/badline/cartridge/final_cartridge3.rb +0 -89
  331. data/lib/badline/cartridge/flash.rb +0 -306
  332. data/lib/badline/cartridge/freezer.rb +0 -33
  333. data/lib/badline/cartridge/fun_play.rb +0 -38
  334. data/lib/badline/cartridge/g_mod2.rb +0 -74
  335. data/lib/badline/cartridge/game_system.rb +0 -40
  336. data/lib/badline/cartridge/geo_ram.rb +0 -79
  337. data/lib/badline/cartridge/kcs_power.rb +0 -75
  338. data/lib/badline/cartridge/mach5.rb +0 -32
  339. data/lib/badline/cartridge/magic_desk.rb +0 -30
  340. data/lib/badline/cartridge/ocean.rb +0 -35
  341. data/lib/badline/cartridge/pagefox.rb +0 -68
  342. data/lib/badline/cartridge/retro_replay.rb +0 -320
  343. data/lib/badline/cartridge/rex_utility.rb +0 -29
  344. data/lib/badline/cartridge/rgcd.rb +0 -58
  345. data/lib/badline/cartridge/simons_basic.rb +0 -35
  346. data/lib/badline/cartridge/standard.rb +0 -15
  347. data/lib/badline/cartridge/super_games.rb +0 -48
  348. data/lib/badline/cartridge/westermann.rb +0 -30
  349. data/lib/badline/cartridge/zaxxon.rb +0 -66
  350. data/lib/badline/cartridge.rb +0 -303
  351. data/lib/badline/checkpoint.rb +0 -98
  352. data/lib/badline/cia/fast_forward.rb +0 -60
  353. data/lib/badline/cia/interrupt_register.rb +0 -143
  354. data/lib/badline/cia/serial.rb +0 -275
  355. data/lib/badline/cia/state.rb +0 -47
  356. data/lib/badline/cia/timer.rb +0 -206
  357. data/lib/badline/cia.rb +0 -279
  358. data/lib/badline/color_memory.rb +0 -25
  359. data/lib/badline/control_ports.rb +0 -76
  360. data/lib/badline/cpu/addressing.rb +0 -131
  361. data/lib/badline/cpu/boundary.rb +0 -54
  362. data/lib/badline/cpu/core.rb +0 -165
  363. data/lib/badline/cpu/microcode.rb +0 -177
  364. data/lib/badline/cpu/operations.rb +0 -88
  365. data/lib/badline/cpu/saved_state.rb +0 -115
  366. data/lib/badline/cpu/stack_operations.rb +0 -82
  367. data/lib/badline/cpu.rb +0 -10
  368. data/lib/badline/cpu_port.rb +0 -112
  369. data/lib/badline/datasette.rb +0 -161
  370. data/lib/badline/drive/core.rb +0 -147
  371. data/lib/badline/drive/fast_serial.rb +0 -73
  372. data/lib/badline/drive/idle.rb +0 -125
  373. data/lib/badline/drive/idle_cpu.rb +0 -28
  374. data/lib/badline/drive/orbit.rb +0 -79
  375. data/lib/badline/drive/serial_lines.rb +0 -73
  376. data/lib/badline/drive/sleep.rb +0 -112
  377. data/lib/badline/drive/vias.rb +0 -84
  378. data/lib/badline/drive/watch.rb +0 -150
  379. data/lib/badline/drive.rb +0 -11
  380. data/lib/badline/drive1541/bus.rb +0 -86
  381. data/lib/badline/drive1541/byte_ready.rb +0 -48
  382. data/lib/badline/drive1541/cpu.rb +0 -11
  383. data/lib/badline/drive1541/disk.rb +0 -315
  384. data/lib/badline/drive1541/disk_state.rb +0 -86
  385. data/lib/badline/drive1541/disk_via.rb +0 -36
  386. data/lib/badline/drive1541/gcr.rb +0 -57
  387. data/lib/badline/drive1541/mechanism.rb +0 -313
  388. data/lib/badline/drive1541/mechanism_state.rb +0 -68
  389. data/lib/badline/drive1541/rotation.rb +0 -121
  390. data/lib/badline/drive1541/sector_reader.rb +0 -76
  391. data/lib/badline/drive1541/serial_port.rb +0 -18
  392. data/lib/badline/drive1541/track.rb +0 -98
  393. data/lib/badline/drive1541.rb +0 -111
  394. data/lib/badline/drive1571/bus.rb +0 -111
  395. data/lib/badline/drive1571/cpu.rb +0 -11
  396. data/lib/badline/drive1571/serial_port.rb +0 -37
  397. data/lib/badline/drive1571/serial_via.rb +0 -25
  398. data/lib/badline/drive1571/wd1770.rb +0 -120
  399. data/lib/badline/drive1571.rb +0 -175
  400. data/lib/badline/drive1581/bus.rb +0 -137
  401. data/lib/badline/drive1581/cpu.rb +0 -11
  402. data/lib/badline/drive1581/disk.rb +0 -135
  403. data/lib/badline/drive1581/disk_state.rb +0 -87
  404. data/lib/badline/drive1581/mechanism.rb +0 -117
  405. data/lib/badline/drive1581/serial_port.rb +0 -52
  406. data/lib/badline/drive1581/slot.rb +0 -78
  407. data/lib/badline/drive1581/track.rb +0 -100
  408. data/lib/badline/drive1581/track_bytes.rb +0 -75
  409. data/lib/badline/drive1581/wd1772/registers.rb +0 -89
  410. data/lib/badline/drive1581/wd1772/sector_writes.rb +0 -73
  411. data/lib/badline/drive1581/wd1772/sectors.rb +0 -150
  412. data/lib/badline/drive1581/wd1772/state.rb +0 -66
  413. data/lib/badline/drive1581/wd1772/stepping.rb +0 -109
  414. data/lib/badline/drive1581/wd1772/tracks.rb +0 -125
  415. data/lib/badline/drive1581/wd1772/turn.rb +0 -73
  416. data/lib/badline/drive1581/wd1772.rb +0 -216
  417. data/lib/badline/drive1581.rb +0 -233
  418. data/lib/badline/iec_bus.rb +0 -159
  419. data/lib/badline/instruction.rb +0 -334
  420. data/lib/badline/instruction_set/arithmetic.rb +0 -114
  421. data/lib/badline/instruction_set/bitwise.rb +0 -126
  422. data/lib/badline/instruction_set/branch.rb +0 -79
  423. data/lib/badline/instruction_set/flag.rb +0 -63
  424. data/lib/badline/instruction_set/illegal.rb +0 -270
  425. data/lib/badline/instruction_set/inc_dec.rb +0 -69
  426. data/lib/badline/instruction_set/stack.rb +0 -52
  427. data/lib/badline/instruction_set/transfer.rb +0 -137
  428. data/lib/badline/instruction_set.rb +0 -55
  429. data/lib/badline/interrupts.rb +0 -104
  430. data/lib/badline/joystick.rb +0 -25
  431. data/lib/badline/kernal_trap/channel.rb +0 -181
  432. data/lib/badline/keyboard.rb +0 -112
  433. data/lib/badline/ram_expansion/banking.rb +0 -30
  434. data/lib/badline/ram_expansion/plus256k.rb +0 -54
  435. data/lib/badline/ram_expansion/plus60k.rb +0 -43
  436. data/lib/badline/ram_expansion/unexpanded.rb +0 -28
  437. data/lib/badline/ram_expansion.rb +0 -21
  438. data/lib/badline/reu/dma/saved_state.rb +0 -50
  439. data/lib/badline/reu/dma.rb +0 -273
  440. data/lib/badline/reu/ram.rb +0 -107
  441. data/lib/badline/reu/saved_state.rb +0 -80
  442. data/lib/badline/reu/trigger.rb +0 -32
  443. data/lib/badline/reu.rb +0 -289
  444. data/lib/badline/sid/catch_up.rb +0 -120
  445. data/lib/badline/sid/decimator.rb +0 -64
  446. data/lib/badline/sid/envelope/state.rb +0 -68
  447. data/lib/badline/sid/envelope.rb +0 -239
  448. data/lib/badline/sid/filter.rb +0 -263
  449. data/lib/badline/sid/voice.rb +0 -77
  450. data/lib/badline/sid/waveform/combined.rb +0 -126
  451. data/lib/badline/sid/waveform/fast_forward.rb +0 -105
  452. data/lib/badline/sid/waveform/noise_writeback.rb +0 -122
  453. data/lib/badline/sid/waveform/state.rb +0 -66
  454. data/lib/badline/sid/waveform.rb +0 -305
  455. data/lib/badline/sid.rb +0 -303
  456. data/lib/badline/time_of_day.rb +0 -228
  457. data/lib/badline/traps.rb +0 -19
  458. data/lib/badline/via/control_lines.rb +0 -122
  459. data/lib/badline/via/fast_forward.rb +0 -53
  460. data/lib/badline/via/interrupt_register.rb +0 -67
  461. data/lib/badline/via/shift_register.rb +0 -180
  462. data/lib/badline/via/state.rb +0 -42
  463. data/lib/badline/via/timer1.rb +0 -131
  464. data/lib/badline/via/timer2.rb +0 -133
  465. data/lib/badline/via.rb +0 -266
  466. data/lib/badline/vic/bank.rb +0 -133
  467. data/lib/badline/vic/border_mask.rb +0 -86
  468. data/lib/badline/vic/collisions.rb +0 -115
  469. data/lib/badline/vic/color_patches.rb +0 -47
  470. data/lib/badline/vic/display_state.rb +0 -185
  471. data/lib/badline/vic/graphics_mode.rb +0 -164
  472. data/lib/badline/vic/graphics_shifter.rb +0 -207
  473. data/lib/badline/vic/register_log.rb +0 -81
  474. data/lib/badline/vic/registers.rb +0 -195
  475. data/lib/badline/vic/sequencer.rb +0 -275
  476. data/lib/badline/vic/sequencer_output.rb +0 -116
  477. data/lib/badline/vic/sequencer_state.rb +0 -89
  478. data/lib/badline/vic/sprite/internal_bus.rb +0 -68
  479. data/lib/badline/vic/sprite/saved_state.rb +0 -64
  480. data/lib/badline/vic/sprite/shifter.rb +0 -146
  481. data/lib/badline/vic/sprite/timing.rb +0 -56
  482. data/lib/badline/vic/sprite.rb +0 -337
  483. data/lib/badline/vic/sprites.rb +0 -282
  484. data/lib/badline/vic/sprites_state.rb +0 -57
  485. data/lib/badline/vic.rb +0 -853
  486. data/lib/badline/vic20/sound/output.rb +0 -83
  487. data/lib/badline/vic20/sound.rb +0 -233
  488. data/lib/badline/z80/arithmetic.rb +0 -117
  489. data/lib/badline/z80/bit_page.rb +0 -55
  490. data/lib/badline/z80/block_io.rb +0 -58
  491. data/lib/badline/z80/block_transfers.rb +0 -59
  492. data/lib/badline/z80/bus_cycles.rb +0 -111
  493. data/lib/badline/z80/core.rb +0 -113
  494. data/lib/badline/z80/exchanges.rb +0 -50
  495. data/lib/badline/z80/extended_page.rb +0 -89
  496. data/lib/badline/z80/flags.rb +0 -37
  497. data/lib/badline/z80/interrupt_acceptance.rb +0 -46
  498. data/lib/badline/z80/jumps.rb +0 -82
  499. data/lib/badline/z80/loads.rb +0 -98
  500. data/lib/badline/z80/main_page.rb +0 -134
  501. data/lib/badline/z80/registers.rb +0 -120
  502. data/lib/badline/z80/saved_state.rb +0 -69
  503. data/lib/badline/z80/shifts.rb +0 -64
  504. data/lib/badline/z80.rb +0 -11
  505. /data/lib/badline/snapshot/{fields.rb → vice/fields.rb} +0 -0
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ class Cartridge
6
+ # GEO-RAM: a RAM expansion on the expansion port, seen through a 256-byte
7
+ # window at $DE00-$DEFF. Two write-only registers pick the page the
8
+ # window shows: $DFFE selects one of the 64 pages of a 16K block, and
9
+ # $DFFF selects the block. As in VICE, the registers answer at every
10
+ # address from $DF80 up, even for $DFFE and odd for $DFFF, and the block
11
+ # number wraps at the number of blocks the RAM holds. Reads of I/O 2 are
12
+ # open bus. It leaves EXROM and GAME high, and RES clears both
13
+ # registers.
14
+ class GeoRAM < Cartridge
15
+ SIZES = [64, 128, 256, 512, 1024, 2048, 4096].freeze
16
+ BLOCK_SIZE = 0x4000
17
+ PAGE_MASK = 0x3f
18
+
19
+ attr_reader :size
20
+
21
+ # size is the RAM in kilobytes.
22
+ def initialize(size: 512)
23
+ raise ArgumentError, "Unsupported GEO-RAM size #{size}K" unless SIZES.include?(size)
24
+
25
+ @size = size
26
+ @block_mask = ((size * 1024) / BLOCK_SIZE) - 1
27
+ super(Storage::CRTFile::Image.new(hardware_type: nil, subtype: 0, exrom: 1, game: 1,
28
+ name: "GEO-RAM", chips: []))
29
+ end
30
+
31
+ def readable_io_pages
32
+ [0xde]
33
+ end
34
+
35
+ def peek(addr)
36
+ @ram_data[@window + (addr & 0xff)]
37
+ end
38
+
39
+ def poke(addr, value)
40
+ if addr <= 0xdeff
41
+ @ram_data[@window + (addr & 0xff)] = value
42
+ elsif addr >= 0xdf80
43
+ if addr.odd?
44
+ @block = value & @block_mask
45
+ else
46
+ @page = value & PAGE_MASK
47
+ end
48
+ @window = (@block * BLOCK_SIZE) + (@page * 0x100)
49
+ end
50
+ end
51
+
52
+ def reset
53
+ @block = @page = @window = 0
54
+ end
55
+
56
+ # A GEO-RAM is built from its size alone.
57
+ def save_setup(out)
58
+ out.int(GEO_RAM_SETUP).int(@size)
59
+ end
60
+
61
+ private
62
+
63
+ def save_mapper(out)
64
+ out.blob(@ram_data).int(@block).int(@page).int(@window)
65
+ end
66
+
67
+ def load_mapper(input)
68
+ input.blob_into(@ram_data)
69
+ @block = input.int
70
+ @page = input.int
71
+ @window = input.int
72
+ end
73
+
74
+ def install_chips(_chips)
75
+ @ram_data = Array.new(@size * 1024, 0)
76
+ reset
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ class Cartridge
6
+ # The KCS Power Cartridge: 16K of ROM, 128 bytes of RAM and a freeze
7
+ # button. It boots in 16K mode, and any access to I/O 1 sets the lines
8
+ # from address bit 1 and the direction:
9
+ #
10
+ # read, bit 1 clear 8K
11
+ # read, bit 1 set off
12
+ # write, bit 1 clear 16K
13
+ # write, bit 1 set Ultimax
14
+ #
15
+ # A read of I/O 1 returns the second last page of ROML. I/O 2 holds the
16
+ # RAM in its lower half, and the upper half reads the EXROM line in bit 7
17
+ # and GAME in bit 6, which the freezer checks to find the mode it
18
+ # interrupted. A freeze switches to Ultimax and lets go of NMI.
19
+ class KCSPower < Cartridge
20
+ include Freezer
21
+
22
+ IO1_ROM_PAGE = 0x1e00
23
+
24
+ def readable_io_pages
25
+ [0xde, 0xdf]
26
+ end
27
+
28
+ def peek(addr)
29
+ if addr < 0xdf00
30
+ select_mode(addr.anybits?(0x02) ? :off : :rom8k)
31
+ @roml.peek(IO1_ROM_PAGE | (addr & 0xff))
32
+ elsif addr.anybits?(0x80)
33
+ (@exrom << 7) | (@game << 6) | (open_bus(addr) & 0x3f)
34
+ else
35
+ @io_ram[addr & 0x7f]
36
+ end
37
+ end
38
+
39
+ def poke(addr, value)
40
+ if addr < 0xdf00
41
+ select_mode(addr.anybits?(0x02) ? :ultimax : :rom16k)
42
+ elsif addr.nobits?(0x80)
43
+ @io_ram[addr & 0x7f] = value
44
+ end
45
+ end
46
+
47
+ def reset
48
+ self.nmi = false
49
+ select_mode(:rom16k)
50
+ end
51
+
52
+ def freeze!
53
+ self.nmi = false
54
+ select_mode(:ultimax)
55
+ end
56
+
57
+ private
58
+
59
+ def save_mapper(out)
60
+ out.blob(@io_ram)
61
+ end
62
+
63
+ def load_mapper(input)
64
+ input.blob_into(@io_ram)
65
+ end
66
+
67
+ def install_chips(chips)
68
+ roml, romh = banks_from(chips)
69
+ @roml = roml.first || EMPTY_BANK
70
+ @romh = romh.first || EMPTY_BANK
71
+ @io_ram = Array.new(0x80, 0xff)
72
+ reset
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ class Cartridge
6
+ # 8K. Writing I/O 1 switches the ROM in, writing I/O 2 switches it out.
7
+ # Both I/O pages read the last 512 bytes of the ROM.
8
+ class Mach5 < Cartridge
9
+ def readable_io_pages
10
+ [0xde, 0xdf]
11
+ end
12
+
13
+ def peek(addr)
14
+ @roml.peek(addr)
15
+ end
16
+
17
+ def poke(addr, _value)
18
+ select_mode(addr < 0xdf00 ? :rom8k : :off)
19
+ end
20
+
21
+ def reset
22
+ select_mode(:rom8k)
23
+ end
24
+
25
+ private
26
+
27
+ def install_chips(chips)
28
+ @roml = banks_from(chips).first.compact.first || EMPTY_BANK
29
+ reset
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ class Cartridge
6
+ # Magic Desk: up to 128 8K banks. A write to I/O 1 selects the bank from
7
+ # bits 0-6, masked to the size of the ROM and at least four banks, and
8
+ # switches the ROM out with bit 7.
9
+ class MagicDesk < Cartridge
10
+ def poke(addr, value)
11
+ return if addr > 0xdeff
12
+
13
+ @exrom = value.anybits?(0x80) ? 1 : 0
14
+ @roml = bank(@banks, value & @bank_mask)
15
+ changed!
16
+ end
17
+
18
+ def reset
19
+ poke(0xde00, 0)
20
+ end
21
+
22
+ private
23
+
24
+ def install_chips(chips)
25
+ @banks = banks_from(chips).first
26
+ @bank_mask = (bank_mask(@banks) | 0x03) & 0x7f
27
+ reset
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -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