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
@@ -1,143 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class C128
5
- MARKER = "C128"
6
-
7
- # The model, the SID and the mode it resets into of the machine a State
8
- # from #snapshot was taken of, the arguments C128.new takes.
9
- def self.setup(state)
10
- input = Snapshot::StateReader.new(state)
11
- input.marker(MARKER)
12
- input.check_stamp
13
- SavedState.read_setup(input)
14
- end
15
-
16
- # A new machine, built as the one a State from #snapshot was taken of,
17
- # at that state.
18
- def self.restored(state)
19
- setup = setup(state)
20
- new(model: setup[0], sid_model: setup[1], mode: setup[2]).apply_state(state)
21
- end
22
-
23
- # The whole machine's state for a snapshot, as Computer's: the
24
- # machine's own latches, FAST and TEST as they last took hold, the bus with its RAM, the MMU, the chips and
25
- # the VDC, the CPU, the cartridge, the disk device 8 serves through the
26
- # traps and a true 1541. The serial lines go back into the bus from the
27
- # restored CIA 2. What the host holds stays out: the keyboard, the
28
- # joysticks, CAPS LOCK and 40/80 DISPLAY, the traps and callbacks, and
29
- # which chip renders.
30
- module SavedState
31
- SID_MODELS = %i[mos6581 mos8580].freeze
32
- MODES = %i[c64 c128].freeze
33
-
34
- # The model's name, the SID's model and the mode.
35
- def self.read_setup(input)
36
- name = input.string
37
- known = Model::ALL.any? { |model| model.name == name }
38
- raise Snapshot::FormatError, "the state names a C128 model badline doesn't know" unless known
39
-
40
- sid_model = SID_MODELS.fetch(input.int)
41
- [name, sid_model, MODES.fetch(input.int)]
42
- rescue IndexError
43
- raise Snapshot::FormatError, "the state names a SID or a mode badline doesn't know"
44
- end
45
-
46
- # How many more on_init handlers the machine a State was taken of had
47
- # yet to run than this one has. Nil until the machine is restored.
48
- attr_reader :init_handlers_lost
49
-
50
- def snapshot
51
- out = Snapshot::StateWriter.new
52
- save_state(out)
53
- out.state
54
- end
55
-
56
- # Takes the machine back to a State from #snapshot, trying it on a new
57
- # machine first, so one that fails leaves this machine as it was.
58
- # Raises Snapshot::FormatError for a state of another model or SID.
59
- def restore(state)
60
- check_setup(C128.setup(state))
61
- C128.restored(state)
62
- apply_state(state)
63
- end
64
-
65
- # Puts a State into the machine without trying it on a new one first.
66
- def apply_state(state)
67
- input = Snapshot::StateReader.new(state)
68
- load_state(input)
69
- raise Snapshot::FormatError, "the state goes on past the machine" unless input.finished?
70
-
71
- self
72
- end
73
-
74
- def save_state(out)
75
- out.marker(MARKER).stamp
76
- out.string(@model.name).int(SID_MODELS.index(@sid.model)).int(@c64_built ? 0 : 1)
77
- out.int(@cycles).int(@clock_bits).boolean(@nmi_asserted).boolean(@cartridge_nmi).boolean(@restore_pulse)
78
- out.boolean(!@pending_keys.nil?)
79
- out.ints(@pending_keys) if @pending_keys
80
- out.int(@cycles <= init_threshold ? @init_handlers.length : 0)
81
- save_cartridge(out)
82
- @bus.save_state(out)
83
- @cpu.save_state(out)
84
- @z80.save_state(out)
85
- out.int(@z80_due).int(@chips_ahead).boolean(@cpu_reset_pending)
86
- save_trap_drive(out)
87
- save_serial_bus(out)
88
- end
89
-
90
- def load_state(input)
91
- input.marker(MARKER)
92
- input.check_stamp
93
- check_setup(SavedState.read_setup(input))
94
- @cycles = input.int
95
- @clock_bits = input.int
96
- @nmi_asserted = input.boolean?
97
- @cartridge_nmi = input.boolean?
98
- @restore_pulse = input.boolean?
99
- @pending_keys = nil
100
- @pending_keys = input.ints if input.boolean?
101
- @init_handlers_lost = [input.int - @init_handlers.length, 0].max
102
- load_cartridge(input)
103
- @cpu_reset_pending = false
104
- @bus.load_state(input)
105
- push_serial_lines
106
- @cpu.load_state(input)
107
- load_z80(input)
108
- load_trap_drive(input)
109
- load_serial_bus(input)
110
- push_fast_serial
111
- end
112
-
113
- private
114
-
115
- # The Z80 and which CPU has the bus, which a state from before the
116
- # Z80 leaves to the 8502. The bus, restored before it, hands the bus
117
- # to its CPU without resetting the 8502.
118
- def load_z80(input)
119
- @z80_running = @bus.z80?
120
- @z80_turn = @z80_running
121
- @z80_due = @z80.cycles
122
- @chips_ahead = 0
123
- @cpu_reset_pending = false
124
- return unless input.schema > 6
125
-
126
- @z80.load_state(input)
127
- @z80_due = input.int
128
- @chips_ahead = input.int
129
- @cpu_reset_pending = input.boolean?
130
- @z80_turn = @z80_running || @chips_ahead.positive?
131
- end
132
-
133
- def check_setup(setup)
134
- ours = [@model.name, @sid.model, @c64_built ? :c64 : :c128]
135
- return if setup == ours
136
-
137
- raise Snapshot::FormatError, "the state is of a #{setup.join(' with a ')}, not a #{ours.join(' with a ')}"
138
- end
139
- end
140
-
141
- include SavedState
142
- end
143
- end
@@ -1,126 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Cartridge
5
- # Action Replay v4.2 to v6: four 8K ROM banks and 8K of RAM. A write to
6
- # I/O 1 sets the control register:
7
- #
8
- # bit 0 pulls GAME low
9
- # bit 1 releases EXROM
10
- # bit 2 switches the register off until the next freeze or reset
11
- # bits 3-4 ROM bank
12
- # bit 5 RAM instead of ROM at ROML and I/O 2
13
- # bit 6 acknowledges a freeze and lets go of NMI
14
- #
15
- # I/O 2 shows the last page of the RAM or of the ROM bank. The register
16
- # doesn't decode R/W, so a read of I/O 1 writes whatever is on the bus
17
- # into it. RAM with only EXROM released ($22) selects the cartridge RAM
18
- # and the C64's together at ROML. A freeze switches the cartridge back
19
- # on, in Ultimax mode with the RAM at ROML and the first bank at ROMH.
20
- class ActionReplay < Cartridge
21
- include Freezer
22
-
23
- CONTROL_MODES = %i[rom8k rom16k off ultimax].freeze
24
- IO2_PAGE = 0x1f00
25
-
26
- def connect(ram:, open_bus:)
27
- super
28
- @through.backing = ram
29
- @contended.backing = ram
30
- end
31
-
32
- def readable_io_pages
33
- [0xde, 0xdf]
34
- end
35
-
36
- def peek(addr)
37
- return open_bus(addr) unless @active
38
- return io2_peek(addr) if addr >= 0xdf00
39
-
40
- open_bus(addr).tap { |value| control(value) }
41
- end
42
-
43
- def poke(addr, value)
44
- return unless @active
45
-
46
- if addr < 0xdf00
47
- control(value)
48
- elsif @io2_ram
49
- @ram_data[IO2_PAGE | (addr & 0xff)] = value
50
- end
51
- end
52
-
53
- def reset
54
- @active = true
55
- self.nmi = false
56
- control(0)
57
- end
58
-
59
- def freeze!
60
- @active = true
61
- @rom = bank(@rom_banks, 0)
62
- select(:ultimax, @isolated, io2_ram: true)
63
- end
64
-
65
- private
66
-
67
- def save_mapper(out)
68
- super
69
- out.int(window_index(@rom, windows)).boolean(@active).boolean(@io2_ram).blob(@ram_data)
70
- end
71
-
72
- def load_mapper(input)
73
- super
74
- @rom = window_at(input.int, windows)
75
- @active = input.boolean?
76
- @io2_ram = input.boolean?
77
- input.blob_into(@ram_data)
78
- end
79
-
80
- def windows = [@through, @isolated, @contended, *@rom_banks, EMPTY_BANK]
81
-
82
- def io2_peek(addr)
83
- @io2_ram ? @ram_data[IO2_PAGE | (addr & 0xff)] : @rom.peek(addr)
84
- end
85
-
86
- def control(value)
87
- self.nmi = false if value.anybits?(0x40)
88
- @rom = bank(@rom_banks, (value >> 3) & 0x03)
89
- configure(value)
90
- @active = false if value.anybits?(0x04)
91
- end
92
-
93
- def configure(value)
94
- return select(:rom8k, @contended, io2_ram: true) if (value & 0x23) == 0x22
95
-
96
- configure_standard(value)
97
- end
98
-
99
- def configure_standard(value)
100
- mode = CONTROL_MODES[value & 0x03]
101
- if value.anybits?(0x20)
102
- select(mode, mode == :ultimax ? @isolated : @through, io2_ram: true)
103
- else
104
- select(mode, @rom, io2_ram: false)
105
- end
106
- end
107
-
108
- def select(mode, roml, io2_ram:, romh: @rom)
109
- self.mode = mode
110
- @roml = roml
111
- @romh = romh
112
- @io2_ram = io2_ram
113
- changed!
114
- end
115
-
116
- def install_chips(chips)
117
- @rom_banks = banks_from(chips).first
118
- @ram_data = Array.new(BANK_SIZE, 0)
119
- @through = RAMBank.new(@ram_data)
120
- @isolated = RAMBank.new(@ram_data)
121
- @contended = ContendedRAM.new(@ram_data)
122
- reset
123
- end
124
- end
125
- end
126
- end
@@ -1,24 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Cartridge
5
- # Atomic Power, sold as Nordic Power: an Action Replay 5 with one more
6
- # configuration. RAM with only EXROM released and bits 2, 6 and 7 clear
7
- # ($22) selects 16K mode with the ROM bank at ROML and the RAM at ROMH
8
- # and I/O 2. Writes to that RAM don't reach the C64's. The VIC never
9
- # sees Ultimax mode.
10
- class AtomicPower < ActionReplay
11
- def phi1_ultimax?
12
- false
13
- end
14
-
15
- private
16
-
17
- def configure(value)
18
- return select(:rom16k, @rom, romh: @isolated, io2_ram: true) if (value & 0xe7) == 0x22
19
-
20
- configure_standard(value)
21
- end
22
- end
23
- end
24
- end
@@ -1,81 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Cartridge
5
- # One 8K bank of cartridge ROM. The chip decodes only the low address
6
- # lines, so the same bank answers at $8000, $A000 or $E000, and a smaller
7
- # chip mirrors across the window.
8
- class Bank
9
- def initialize(data)
10
- size = [1 << (data.length - 1).bit_length, 1].max
11
- @mask = size - 1
12
- @data = (data + ([0xff] * (size - data.length))).freeze
13
- end
14
-
15
- def peek(addr)
16
- @data[addr & @mask]
17
- end
18
- alias [] peek
19
- end
20
-
21
- # Cartridge RAM mapped into the ROML or ROMH window. Writes land in the
22
- # C64's RAM underneath as well, when there is a backing. Banks built on
23
- # the same data are views of the same RAM.
24
- class RAMBank
25
- attr_reader :data
26
- attr_writer :backing
27
-
28
- def initialize(data = Array.new(BANK_SIZE, 0))
29
- @data = data
30
- @backing = nil
31
- end
32
-
33
- def peek(addr)
34
- @data[addr & 0x1fff]
35
- end
36
- alias [] peek
37
-
38
- def poke(addr, value)
39
- @data[addr & 0x1fff] = value
40
- @backing&.poke(addr, value)
41
- end
42
- alias []= poke
43
- end
44
-
45
- # Cartridge RAM the window reads, where the cartridge ignores writes.
46
- class RAMReader
47
- def initialize(data)
48
- @data = data
49
- end
50
-
51
- def peek(addr)
52
- @data[addr & 0x1fff]
53
- end
54
- alias [] peek
55
- end
56
-
57
- # Cartridge RAM that takes writes while the window reads something else.
58
- class WriteOnlyRAM < RAMBank
59
- def initialize(data, reader)
60
- super(data)
61
- @reader = reader
62
- end
63
-
64
- def peek(addr)
65
- @reader.peek(addr)
66
- end
67
- alias [] peek
68
- end
69
-
70
- # Cartridge RAM selected together with the C64's RAM, both driving the
71
- # bus on a read. The result is ORed, as VICE has it.
72
- class ContendedRAM < RAMBank
73
- def peek(addr)
74
- @data[addr & 0x1fff] | @backing.peek(addr)
75
- end
76
- alias [] peek
77
- end
78
-
79
- EMPTY_BANK = Bank.new([0xff])
80
- end
81
- end
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Cartridge
5
- # Comal-80: four 16K banks, or eight with the extra ROMs. A write to
6
- # I/O 1 selects the bank and the memory configuration. The black board
7
- # (subtype 0) takes the bank from bits 0-2 and switches the ROM out with
8
- # bit 6; the grey one (subtype 1) takes the bank from bits 0-1 and the
9
- # configuration from bits 5-6.
10
- class Comal80 < Cartridge
11
- GREY_MODES = %i[rom16k ultimax rom8k off].freeze
12
-
13
- def initialize(crt)
14
- @grey = crt.subtype == 1
15
- super
16
- end
17
-
18
- def poke(addr, value)
19
- return if addr > 0xdeff
20
-
21
- if @grey
22
- select(value & 0x03, GREY_MODES[(value >> 5) & 0x03])
23
- else
24
- select(value & 0x07, value.anybits?(0x40) ? :off : :rom16k)
25
- end
26
- changed!
27
- end
28
-
29
- def reset
30
- select(0, :rom16k)
31
- changed!
32
- end
33
-
34
- private
35
-
36
- def windows = [*@roml_banks, *@romh_banks, EMPTY_BANK]
37
-
38
- def select(number, mode)
39
- @roml = bank(@roml_banks, number)
40
- @romh = bank(@romh_banks, number)
41
- self.mode = mode
42
- end
43
-
44
- def install_chips(chips)
45
- @roml_banks, @romh_banks = banks_from(chips)
46
- reset
47
- end
48
- end
49
- end
50
- end
@@ -1,34 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Cartridge
5
- # Dinamic: up to 16 8K banks. Reading $DE00-$DE0F selects the bank from
6
- # the low address bits.
7
- class Dinamic < Cartridge
8
- def readable_io_pages
9
- [0xde]
10
- end
11
-
12
- def peek(addr)
13
- if addr < 0xde10
14
- @roml = bank(@banks, addr & 0x0f)
15
- changed!
16
- end
17
- open_bus(addr)
18
- end
19
-
20
- def reset
21
- @roml = bank(@banks, 0)
22
- changed!
23
- end
24
-
25
- private
26
-
27
- def install_chips(chips)
28
- @banks = banks_from(chips).first
29
- self.mode = :rom8k
30
- reset
31
- end
32
- end
33
- end
34
- end
@@ -1,145 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Cartridge
5
- # EasyFlash: two Am29F040B flash chips, one for ROML and one for ROMH,
6
- # each 64 banks of 8K, and 256 bytes of RAM at $DF00. $DE00 selects the
7
- # bank. $DE02 sets the memory configuration: bit 2 hands the GAME line
8
- # to bit 0 (otherwise the boot jumper holds it low), bit 1 pulls EXROM
9
- # low and bit 7 drives the LED.
10
- #
11
- # The flash takes writes in Ultimax mode, at $8000 for ROML and $E000
12
- # for ROMH, which is how EAPI programs and erases it. The writes stay in
13
- # memory; #save_crt writes the flash out as a new image.
14
- #
15
- # An image built for EasyFlash carries an EAPI, the flash driver, at $B800
16
- # in bank 0 of ROMH. On attach, as in VICE, the bundled Am29F040 EAPI
17
- # (roms/eapi) takes its place, so the image drives the flash emulated here.
18
- class EasyFlash < Cartridge
19
- BANKS = 64
20
- EAPI_OFFSET = 0x1800
21
-
22
- def self.eapi
23
- @eapi ||= ROM.read("eapi/eapi-am29f040-14").drop(2).freeze
24
- end
25
-
26
- attr_reader :low_flash, :high_flash
27
-
28
- def clock=(clock)
29
- super
30
- [@low_flash, @high_flash].each { |flash| flash.clock = clock }
31
- end
32
-
33
- def readable_io_pages
34
- [0xdf]
35
- end
36
-
37
- def peek(addr)
38
- @io_ram[addr & 0xff]
39
- end
40
-
41
- def poke(addr, value)
42
- if addr >= 0xdf00
43
- @io_ram[addr & 0xff] = value
44
- elsif addr.nobits?(0x02)
45
- @bank = value & 0x3f
46
- select_bank
47
- else
48
- @control = value & 0x87
49
- apply_control
50
- changed!
51
- end
52
- end
53
-
54
- def led?
55
- @control.anybits?(0x80)
56
- end
57
-
58
- # Reset clears both registers, and leaves the flash and the RAM.
59
- def reset
60
- @bank = 0
61
- @control = 0
62
- apply_control
63
- select_bank
64
- end
65
-
66
- # Writes every bank that isn't blank to a CRT image at path.
67
- def save_crt(path)
68
- chips = (0...BANKS).flat_map do |number|
69
- [[@low_flash, 0x8000], [@high_flash, 0xa000]].filter_map do |flash, address|
70
- data = flash.data[number * BANK_SIZE, BANK_SIZE]
71
- Storage::CRTFile::Chip.new(chip_type: 2, bank: number, address:, data:) if data.any?(0..0xfe)
72
- end
73
- end
74
- image = Storage::CRTFile::Image.new(hardware_type: 32, subtype: 0, exrom: 1, game: 0, name:, chips:)
75
- Storage::CRTFile.write(path, image)
76
- end
77
-
78
- private
79
-
80
- def select_bank
81
- map_bank
82
- changed!
83
- end
84
-
85
- def map_bank
86
- @roml = @low_flash.window(@bank * BANK_SIZE)
87
- @romh = @high_flash.window(@bank * BANK_SIZE)
88
- end
89
-
90
- def save_mapper(out)
91
- out.int(@bank).int(@control).blob(@io_ram)
92
- @low_flash.save_state(out)
93
- @high_flash.save_state(out)
94
- end
95
-
96
- def load_mapper(input)
97
- @bank = input.int
98
- @control = input.int
99
- input.blob_into(@io_ram)
100
- @low_flash.load_state(input)
101
- @high_flash.load_state(input)
102
- map_bank
103
- end
104
-
105
- def apply_control
106
- game = @control.nobits?(0x04) || @control.anybits?(0x01)
107
- exrom = @control.anybits?(0x02)
108
- @game = game ? 0 : 1
109
- @exrom = exrom ? 0 : 1
110
- end
111
-
112
- def install_chips(chips)
113
- low = Array.new(BANKS * BANK_SIZE, 0xff)
114
- high = Array.new(BANKS * BANK_SIZE, 0xff)
115
- chips.each do |chip|
116
- offset = (chip.bank & 0x3f) * BANK_SIZE
117
- if chip.address >= ROMH_START
118
- place(high, offset, chip.data)
119
- else
120
- place(low, offset, chip.data)
121
- place(high, offset, chip.data[BANK_SIZE..]) if chip.data.length > BANK_SIZE
122
- end
123
- end
124
- install_eapi(high)
125
- @low_flash = Flash.new(low)
126
- @high_flash = Flash.new(high)
127
- [@low_flash, @high_flash].each { |flash| flash.on_change { select_bank } }
128
- @io_ram = Array.new(0x100, 0xff)
129
- reset
130
- end
131
-
132
- def install_eapi(high)
133
- return unless high[EAPI_OFFSET, 4] == "eapi".bytes
134
-
135
- eapi = EasyFlash.eapi
136
- high[EAPI_OFFSET, eapi.length] = eapi
137
- end
138
-
139
- def place(flash_data, offset, bytes)
140
- bytes = bytes.first(BANK_SIZE)
141
- flash_data[offset, bytes.length] = bytes
142
- end
143
- end
144
- end
145
- end
@@ -1,79 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Cartridge
5
- # Epyx FastLoad: 8K. A capacitor holds the ROM in for 512 cycles after
6
- # it was last discharged, by reset, a read through ROML or a read of
7
- # I/O 1; once it charges, $8000-$9FFF reads RAM. I/O 2 reads the last
8
- # 256 bytes of the ROM.
9
- class EpyxFastload < Cartridge
10
- DISCHARGED_CYCLES = 512
11
-
12
- class Window
13
- def initialize(cartridge, rom)
14
- @cartridge = cartridge
15
- @rom = rom
16
- end
17
-
18
- def peek(addr)
19
- @cartridge.rom_visible? ? @rom.peek(addr) : @cartridge.ram_peek(addr)
20
- end
21
- end
22
-
23
- def clock=(clock)
24
- super
25
- discharge!
26
- end
27
-
28
- def readable_io_pages
29
- [0xde, 0xdf]
30
- end
31
-
32
- def peek(addr)
33
- return @rom.peek(addr) if addr >= 0xdf00
34
-
35
- discharge!
36
- open_bus(addr)
37
- end
38
-
39
- # True while the capacitor holds the ROM in, discharging it again.
40
- def rom_visible?
41
- return true unless @clock
42
- return false if @clock.call - @discharged_at >= DISCHARGED_CYCLES
43
-
44
- discharge!
45
- true
46
- end
47
-
48
- def ram_peek(addr)
49
- @ram.peek(addr)
50
- end
51
-
52
- # Reset discharges the capacitor, so the ROM shows.
53
- def reset
54
- discharge!
55
- end
56
-
57
- private
58
-
59
- def save_mapper(out)
60
- out.int(@discharged_at)
61
- end
62
-
63
- def load_mapper(input)
64
- @discharged_at = input.int
65
- end
66
-
67
- def discharge!
68
- @discharged_at = @clock ? @clock.call : 0
69
- end
70
-
71
- def install_chips(chips)
72
- @rom = banks_from(chips).first.compact.first || EMPTY_BANK
73
- @roml = Window.new(self, @rom)
74
- @discharged_at = 0
75
- self.mode = :rom8k
76
- end
77
- end
78
- end
79
- end