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,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class AddressBus
5
- # What a model fits around the chips: its KERNAL, a datasette or none,
6
- # and the board and case they sit in.
7
- module Fittings
8
- # The keywords #fit takes.
9
- NAMES = %i[kernal datasette board].freeze
10
-
11
- # The C64's board and case, the PET 64's, whose built-in monitor
12
- # shows the VIC's output in shades of green, the C64GS's, which has
13
- # no keyboard, or the MAX Machine's (:max): 2K of RAM, no ROMs, CIA 1
14
- # alone at $DC00-$DFFF and the cartridge port in Ultimax mode.
15
- BOARDS = %i[c64 pet64 gs max].freeze
16
-
17
- attr_reader :board
18
-
19
- # Fits the KERNAL ROM ROMs::KERNALS names, leaves the cassette port
20
- # empty unless `datasette`, and puts the chips in the board BOARDS
21
- # names.
22
- def fit(kernal: :c64, datasette: true, board: :c64)
23
- self.kernal = kernal unless kernal == :c64
24
- @datasette.disconnect! unless datasette
25
- self.board = board unless board == :c64
26
- end
27
-
28
- def board=(name)
29
- raise ArgumentError, "no board named #{name}" unless BOARDS.include?(name)
30
-
31
- @board = name
32
- vic.palette = name == :pet64 ? VIC::GREEN_PALETTE : VIC::PALETTE
33
- keyboard.connected = name != :gs
34
- update_overlays!
35
- end
36
- end
37
- end
38
- end
@@ -1,147 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class AddressBus
5
- # The C64's PLA: what each page of the CPU's view maps to, from the
6
- # CPU port's LORAM, HIRAM and CHAREN lines and the cartridge's EXROM
7
- # and GAME. The bus that includes it supplies the page tables, the
8
- # ROMs, the chips, #map_ram_pages, which lays out the RAM that the
9
- # ROMs, the cartridge and I/O map over, and #map_io_pages, which lays
10
- # out the chips at $D000-$DFFF, with #map_cartridge_io for I/O 1 and 2.
11
- module PLA
12
- # A chip's registers seen at another page, which reads and writes
13
- # them as at the page the chip starts at.
14
- class Mirror
15
- def initialize(chip, start)
16
- @chip = chip
17
- @start = start
18
- end
19
-
20
- def peek(addr) = @chip.peek(@start | (addr & 0xff))
21
- def poke(addr, value) = @chip.poke(@start | (addr & 0xff), value)
22
- end
23
-
24
- private
25
-
26
- def map_pla_pages
27
- map_ram_pages
28
- @ultimax ? map_ultimax_pages : map_banked_pages
29
- end
30
-
31
- def map_banked_pages
32
- map_rom_overlays
33
- map_cartridge_ram
34
- @write_pages.fill(@cartridge.romh_writes, 0xe0, 0x20) if @cartridge&.romh_writes
35
-
36
- if io?
37
- map_io_pages
38
- elsif character?
39
- @read_pages.fill(character_rom, 0xd0, 0x10)
40
- end
41
- end
42
-
43
- # Ultimax mode ignores the $01 lines: 4K of RAM, ROML/ROMH windows,
44
- # I/O always visible and open address space everywhere else. The ROML
45
- # and ROMH selects fire on writes as well, so cartridge RAM or flash in
46
- # either window takes the writes there. The MAX has 2K of RAM, and is
47
- # in Ultimax mode with no cartridge too.
48
- def map_ultimax_pages
49
- first = @board == :max ? 0x08 : 0x10
50
- @read_pages.fill(@open_bus, first, 0x100 - first)
51
- @write_pages.fill(@open_bus, first, 0x100 - first)
52
- map_ultimax_cartridge if @cartridge
53
- map_io_pages
54
- map_max_io if @board == :max
55
- end
56
-
57
- def map_ultimax_cartridge
58
- @read_pages.fill(@cartridge.roml, 0x80, 0x20) if @cartridge.roml
59
- map_ultimax_writes(@cartridge.roml, 0x80)
60
- @read_pages.fill(@cartridge.romh, 0xe0, 0x20) if @cartridge.romh
61
- map_ultimax_writes(@cartridge.romh, 0xe0)
62
- map_ultimax_a000
63
- end
64
-
65
- def map_ultimax_writes(bank, first_page)
66
- @write_pages.fill(bank, first_page, 0x20) if bank.respond_to?(:poke)
67
- end
68
-
69
- def map_ultimax_a000
70
- return unless (window = @cartridge.ultimax_a000)
71
-
72
- @read_pages.fill(window, 0xa0, 0x20)
73
- @write_pages.fill(window, 0xa0, 0x20)
74
- end
75
-
76
- # The MAX has no CIA 2 and no I/O 2: CIA 1 answers all through
77
- # $DC00-$DFFF, but for the I/O 1 page a cartridge takes.
78
- def map_max_io
79
- @cia1_mirror ||= Mirror.new(cia1, 0xdc00)
80
- (0xdd..0xdf).each { |page| @read_pages[page] = @write_pages[page] = @cia1_mirror }
81
- return unless @cartridge
82
-
83
- @write_pages[0xde] = @cartridge
84
- @read_pages[0xde] = @cartridge if @cartridge.readable_io_pages.include?(0xde)
85
- end
86
-
87
- # EXROM and GAME select the cartridge whether or not it has a chip
88
- # there, and an empty socket leaves the bus floating.
89
- def map_rom_overlays
90
- @read_pages.fill(@cartridge.roml || @open_bus, 0x80, 0x20) if roml?
91
- if romh?
92
- @read_pages.fill(@cartridge.romh || @open_bus, 0xa0, 0x20)
93
- elsif basic?
94
- @read_pages.fill(basic_rom, 0xa0, 0x20)
95
- end
96
- @read_pages.fill(kernal_rom, 0xe0, 0x20) if kernal?
97
- end
98
-
99
- # Cartridge RAM in the ROML or ROMH window decodes writes itself,
100
- # whatever the $01 lines say.
101
- def map_cartridge_ram
102
- return unless @cartridge&.exrom&.zero?
103
-
104
- map_cartridge_ram_bank(@cartridge.roml, 0x80)
105
- map_cartridge_ram_bank(@cartridge.romh, 0xa0) if @cartridge.game.zero?
106
- end
107
-
108
- def map_cartridge_ram_bank(bank, first_page)
109
- @write_pages.fill(bank, first_page, 0x20) if bank.is_a?(Cartridge::RAMBank)
110
- end
111
-
112
- def map_cartridge_io
113
- @write_pages.fill(@cartridge, 0xde, 2)
114
- @cartridge.readable_io_pages.each { |p| @read_pages[p] = @cartridge }
115
- end
116
-
117
- def basic?
118
- io_port.kernal? && io_port.basic? && game_high?
119
- end
120
-
121
- def game_high?
122
- @cartridge.nil? || @cartridge.game == 1
123
- end
124
-
125
- def roml?
126
- @cartridge&.exrom&.zero? && io_port.kernal? && io_port.basic?
127
- end
128
-
129
- def romh?
130
- @cartridge&.exrom&.zero? && @cartridge.game.zero? && io_port.kernal?
131
- end
132
-
133
- # In 16K mode LORAM alone leaves $d000 as RAM, where it still maps I/O.
134
- def character?
135
- (io_port.kernal? || (io_port.basic? && game_high?)) && !io_port.io?
136
- end
137
-
138
- def io?
139
- (io_port.basic? || io_port.kernal?) && io_port.io?
140
- end
141
-
142
- def kernal?
143
- io_port.kernal?
144
- end
145
- end
146
- end
147
- end
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class AddressBus
5
- # The BASIC, character and KERNAL ROMs, and which KERNAL is fitted.
6
- module ROMs
7
- # The KERNAL ROMs a machine can be fitted with, by name: the C64's,
8
- # the SX-64's, the PET 64's and the C64GS's. The C64GS's is a 16K
9
- # image of its BASIC and its KERNAL, and fits both.
10
- KERNALS = {
11
- c64: "kernal.rom", sx64: "kernal-sx64.rom", pet64: "kernal-pet64.rom", gs: "c64gs.rom"
12
- }.freeze
13
-
14
- attr_reader :basic_rom, :character_rom, :kernal_rom, :kernal
15
-
16
- # Fits the KERNAL ROM KERNALS names `name`, in place of the one before,
17
- # with the BASIC of a 16K image or else the C64's.
18
- def kernal=(name)
19
- raise ArgumentError, "no KERNAL named #{name}" unless KERNALS.key?(name)
20
-
21
- @kernal = name
22
- data = ROM.read(KERNALS[name])
23
- basic = data.length == 0x4000 ? data[0, 0x2000] : ROM.read("basic.rom")
24
- @basic_rom = ROM.new(basic, length: 0x2000, start: 0xa000)
25
- @kernal_rom = ROM.new(data[-0x2000, 0x2000], length: 0x2000, start: 0xe000)
26
- update_overlays!
27
- end
28
-
29
- private
30
-
31
- def load_roms
32
- @basic_rom = ROM.load("basic.rom", 0xa000)
33
- @character_rom = ROM.load("character.rom", 0xd000)
34
- @kernal = :c64
35
- @kernal_rom = ROM.load(KERNALS[:c64], 0xe000)
36
- end
37
- end
38
- end
39
- end
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class AddressBus
5
- # The bus's state for a snapshot: the CPU port, the RAM, colour RAM and
6
- # a RAM expansion, the cartridge, the datasette and the chips.
7
- module SavedState
8
- # The RAM expansion fitted, or an Unexpanded stand-in.
9
- attr_reader :ram_expansion
10
-
11
- # Takes the cartridge out of the expansion port, as a restore does for
12
- # a state without one.
13
- def detach_cartridge
14
- @cartridge = nil
15
- update_overlays!
16
- end
17
-
18
- # The 6510 port's direction and output registers, and the charge left
19
- # on its floating bits.
20
- def port_state = [@cpu_port.ddr, @cpu_port.data, @cpu_port.floating]
21
-
22
- # Sets the port as port_state reads it, as a snapshot restores it,
23
- # leaving the RAM under $00 and $01 alone.
24
- def restore_port(ddr, out, floating)
25
- @cpu_port.restore(ddr, out, floating)
26
- end
27
-
28
- # The machine's memory and everything on the bus but the keyboard, the
29
- # joysticks and the pot devices, which the host holds. A cartridge is
30
- # already in the port, built from its setup (Computer#load_state).
31
- def save_state(out)
32
- out.marker("BUS")
33
- out.int(@cpu_port.ddr).int(@cpu_port.data).int(@cpu_port.floating)
34
- @ram.save_state(out)
35
- @color_ram.save_state(out)
36
- @ram_expansion.save_state(out)
37
- @cartridge&.save_state(out)
38
- @datasette.save_state(out)
39
- @vic.save_state(out)
40
- @cia1.save_state(out)
41
- @cia2.save_state(out)
42
- @sid.save_state(out)
43
- end
44
-
45
- def load_state(input)
46
- input.marker("BUS")
47
- ddr = input.int
48
- port_out = input.int
49
- floating = input.int
50
- @ram.load_state(input)
51
- @color_ram.load_state(input)
52
- @ram_expansion.load_state(input)
53
- @cartridge&.load_state(input)
54
- @datasette.load_state(input)
55
- @cpu_port.load(ddr, port_out, floating)
56
- update_overlays!
57
- @vic.load_state(input)
58
- @cia1.load_state(input)
59
- @cia2.load_state(input)
60
- @sid.load_state(input)
61
- end
62
- end
63
-
64
- include SavedState
65
- end
66
- end
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class AddressBus
5
- # Stands in for a page of I/O that a second or third SID shares: each 32
6
- # bytes of it go to the SID placed there, or else to the first SID's
7
- # mirrors in `$d400-$d7ff`, and to the open bus in I/O 1 and 2.
8
- class SIDSlots
9
- attr_reader :page
10
-
11
- def initialize(page, first, open_bus)
12
- @page = page
13
- @io = page >= 0xde
14
- @first = first
15
- @open_bus = open_bus
16
- @sids = []
17
- @slots = Array.new(8, -1)
18
- end
19
-
20
- def place(sid)
21
- @slots[(sid.start >> 5) & 7] = @sids.size
22
- @sids << sid
23
- end
24
-
25
- def peek(addr)
26
- index = @slots[(addr >> 5) & 7]
27
- return @sids[index].peek(addr) unless index.negative?
28
-
29
- @io ? @open_bus.peek(addr) : @first.peek(addr)
30
- end
31
-
32
- def poke(addr, value)
33
- index = @slots[(addr >> 5) & 7]
34
- if !index.negative?
35
- @sids[index].poke(addr, value)
36
- elsif !@io
37
- @first.poke(addr, value)
38
- end
39
- end
40
- end
41
- end
42
- end
@@ -1,216 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "badline/address_bus/saved_state"
4
- require "badline/address_bus/sid_slots"
5
- require "badline/address_bus/extra_sids"
6
- require "badline/address_bus/pla"
7
- require "badline/address_bus/roms"
8
- require "badline/address_bus/fittings"
9
-
10
- module Badline
11
- # Memory layout:
12
- #
13
- # 0x0000-0x00FF - Page 0 - Zeropage
14
- # 0x0100-0x01FF - Page 1 - Stack
15
- # 0x0200-0x02FF - Page 2 - OS/BASIC pointers
16
- # 0x0300-0x03FF - Page 3 - OS/BASIC pointers
17
- # 0x0400-0x07FF - Page 4-7 - Screen memory
18
- # 0x0800-0x9FFF - Page 8-159 - BASIC program storage area
19
- # 0xA000-0xBFFF - Page 160-191 - Machine code program storage (ROM overlay)
20
- # 0xC000-0xCFFF - Page 192-207 - Machine code program storage
21
- # 0xD000-0xD3FF - Page 208-211 - VIC II registers
22
- # 0xD400-0xD7FF - Page 212-215 - SID registers
23
- # 0xD800-0xDBFF - Page 216-219 - Color memory
24
- # 0xDC00-0xDCFF - Page 220 - CIA 1
25
- # 0xDD00-0xDDFF - Page 221 - CIA 2
26
- # 0xDE00-0xDEFF - Page 222 - I/O 1
27
- # 0xDF00-0xDFFF - Page 223 - I/O 2
28
- # 0xE000-0xFFFF - Page 224-255 - Machine code program storage (ROM overlay)
29
-
30
- # Overlays:
31
- #
32
- # 0x8000-0x9FFF - Cartridge ROM (low) - 8kb
33
- # 0xA000-0xBFFF - BASIC ROM / Cartridge ROM (high) - 8kb
34
- # 0xD000-0xDFFF - Character ROM / I/O - 4kb
35
- # 0xE000-0xFFFF - KERNAL ROM / Cartridge ROM (high) - 8kb
36
- class AddressBus
37
- include Addressable
38
- include PLA
39
- include ExtraSIDs
40
- include ROMs
41
- include Fittings
42
-
43
- # I/O 1 and 2, and the Ultimax holes, with nothing on the bus. A read
44
- # picks up the byte the VIC fetched in the preceding phi1 half-cycle,
45
- # and a write goes nowhere.
46
- class OpenBus
47
- def initialize(vic)
48
- @vic = vic
49
- end
50
-
51
- def peek(_addr) = @vic.phi1_data
52
- def poke(_addr, _value); end
53
- end
54
-
55
- # The 6510's port pins with pull-ups, and the floating ones (CPUPort).
56
- PORT_PULLUPS = 0b0001_0111
57
- PORT_FLOATING = 0b1100_1000
58
-
59
- # RAM powers on in runs of $00 $00 $FF $FF $FF $FF $00 $00, inverted in
60
- # the second and fourth 16K: a C64C (ASSY 250469 R4) from
61
- # C64/raminitpattern/readme.txt, without its occasional random bytes.
62
- # See doc/pinned-behaviour.md.
63
- RAM_POWER_ON = Array.new(2**16) { |addr| (((addr + 2) / 4) ^ (addr / 0x4000)).odd? ? 0xff : 0x00 }.freeze
64
-
65
- attr_reader :io_port, :ram,
66
- :vic, :sid, :color_ram, :cia1, :cia2, :keyboard, :joystick1, :joystick2,
67
- :control_ports, :cartridge, :ultimax, :phi1_ultimax, :datasette, :region, :video_ram, :reu
68
-
69
- # ram_expansion fits a +60K (:plus60k) or +256K (:plus256k).
70
- def initialize(sid_model: :mos6581, cia_model: :mos6526, vic_model: :mos6569, region: Region::PAL,
71
- ram_expansion: nil)
72
- @region = region
73
- @board = :c64
74
- @ram = Memory.new(RAM_POWER_ON, length: 2**16, start: 0)
75
- @ram_expansion = RAMExpansion.build(ram_expansion, @ram) { update_overlays! }
76
- @cartridge = @reu = nil
77
- @debug_register = nil
78
-
79
- load_roms
80
-
81
- @keyboard = Keyboard.new
82
- @joystick1 = Joystick.new
83
- @joystick2 = Joystick.new
84
- @control_ports = ControlPorts.new(keyboard: @keyboard, joystick1: @joystick1, joystick2: @joystick2)
85
- @vic = VIC.new(model: vic_model, region:)
86
- @cia1 = CIA.new(start: 0xdc00, peripheral: @control_ports, model: cia_model, region:)
87
- @cia2 = CIA.new(start: 0xdd00, model: cia_model, region:)
88
- @control_ports.port_a_source = @cia1
89
- @cia1.on_port_b4_change { |high| @vic.lightpen_level(high) }
90
- @sid = SID.new(model: sid_model, pots: @control_ports)
91
- @sid_slots = []
92
-
93
- @datasette = Datasette.new
94
- @datasette.on_flag { @cia1.flag! }
95
- @datasette.on_sense_change { @cpu_port.refresh }
96
-
97
- @color_ram = ColorMemory.new(@vic)
98
- @vic.vic_bank.connect(cia2: @cia2, color_ram: @color_ram)
99
- @vic.vic_bank.map_character_rom(character_rom)
100
- @open_bus = OpenBus.new(@vic)
101
- @cpu_off_bus = false
102
-
103
- @cpu_port = CPUPort.new(@datasette, pullups: PORT_PULLUPS, floating: PORT_FLOATING)
104
- @cpu_port.on_change { update_overlays! }
105
- @io_port = @cpu_port.status
106
-
107
- @read_pages = Array.new(256)
108
- @write_pages = Array.new(256)
109
- update_overlays!
110
- end
111
-
112
- def attach_cartridge(cartridge)
113
- @cartridge = cartridge
114
- cartridge.connect(ram: @ram, open_bus: @open_bus)
115
- cartridge.on_change { update_overlays! }
116
- update_overlays!
117
- end
118
-
119
- # An REU takes I/O 2 unless a cartridge claims it, and watches writes
120
- # to $FF00 for the one that starts an armed transfer.
121
- def attach_reu(reu)
122
- @reu = reu
123
- update_overlays!
124
- end
125
-
126
- def power_on!
127
- @ram.clear!(RAM_POWER_ON)
128
- @ram_expansion.power_on!
129
- end
130
-
131
- # The RES line clears the 6510 port's direction and output registers,
132
- # and a RAM expansion's bank register. The port's floating bits keep
133
- # their charge.
134
- def reset!
135
- @ram_expansion.reset!
136
- @cpu_port.reset!
137
- end
138
-
139
- def disable_overlays!
140
- poke(0, 0x2f)
141
- poke(1, 0)
142
- end
143
-
144
- def install_debug_register(&)
145
- @debug_register = DebugRegister.new(@sid, &)
146
- update_overlays!
147
- end
148
-
149
- def peek(addr)
150
- return @cpu_port.ddr if addr.zero?
151
- return @io_port.value if addr == 0x01
152
-
153
- @read_pages[addr >> 8].peek(addr)
154
- end
155
-
156
- # A write to $00 or $01 goes to the port, but the RAM below is still
157
- # write-enabled, and takes whatever is left on the bus: the byte the VIC
158
- # fetched in the phi1 half of the cycle.
159
- def poke(addr, value)
160
- if addr < 0x02
161
- @ram.poke(addr, @vic.phi1_data)
162
- addr.zero? ? @cpu_port.write_ddr(value) : @cpu_port.write_data(value)
163
- elsif !@cpu_off_bus
164
- @write_pages[addr >> 8].poke(addr, value)
165
- end
166
- end
167
-
168
- # Runs a CPU cycle with the CPU off the bus, as an REU's /DMA line
169
- # holds it: a write it makes reaches nothing but its own port.
170
- def cycle_cpu_off_bus(cpu)
171
- @cpu_off_bus = true
172
- cpu.cycle!
173
- @cpu_off_bus = false
174
- end
175
-
176
- def inspect
177
- "#<#{self.class.name} port=#{format('0x%02x', @io_port.value)} " \
178
- "cartridge=#{@cartridge ? @cartridge.class.name : 'none'} " \
179
- "ultimax=#{@ultimax}>"
180
- end
181
-
182
- private
183
-
184
- # Banking changes only on $01 writes and cartridge line/bank changes,
185
- # so reads and writes dispatch through per-page handler tables instead
186
- # of range checks.
187
- def update_overlays!
188
- max = @board == :max
189
- @ultimax = max || (@cartridge ? @cartridge.ultimax? : false)
190
- @phi1_ultimax = max || (@cartridge ? @cartridge.phi1_ultimax? : false)
191
- @video_ram = @ram_expansion.video_ram
192
- @vic.vic_bank.map(@video_ram, phi1_ultimax: @phi1_ultimax, ultimax: @ultimax, romh: @cartridge&.romh)
193
-
194
- map_pla_pages
195
- @write_pages[0xff] = @reu.trigger.wrap(@write_pages[0xff]) if @reu
196
- end
197
-
198
- def map_ram_pages
199
- @ram_expansion.map(@read_pages, @write_pages)
200
- end
201
-
202
- def map_io_pages
203
- {
204
- vic => 0xd0..0xd3, sid => 0xd4..0xd7, color_ram => 0xd8..0xdb,
205
- cia1 => 0xdc..0xdc, cia2 => 0xdd..0xdd, @open_bus => 0xde..0xdf
206
- }.each do |chip, pages|
207
- pages.each { |p| @read_pages[p] = @write_pages[p] = chip }
208
- end
209
- @ram_expansion.map_io(@read_pages, @write_pages)
210
- @read_pages[0xd7] = @write_pages[0xd7] = @debug_register if @debug_register
211
- @read_pages[0xdf] = @write_pages[0xdf] = @reu if @reu
212
- map_cartridge_io if @cartridge
213
- map_extra_sids unless @sid_slots.empty?
214
- end
215
- end
216
- end
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class C128
5
- class Bus
6
- # The bus's state for a snapshot, as AddressBus::SavedState is the
7
- # C64's.
8
- module SavedState
9
- # The machine's memory, the last access and everything on the bus but
10
- # the keyboard, the joysticks, the pot devices and CAPS LOCK, which the
11
- # host holds. A cartridge is already in the port, built from its setup.
12
- def save_state(out)
13
- out.marker("C128 BUS")
14
- out.int(@cpu_port.ddr).int(@cpu_port.data).int(@cpu_port.floating).int(@address).int(@data)
15
- @mmu.save_state(out)
16
- @ram.save_state(out)
17
- @color_lines.color_ram(0).save_state(out)
18
- @color_lines.color_ram(1).save_state(out)
19
- @cartridge&.save_state(out)
20
- @datasette.save_state(out)
21
- @vic.save_state(out)
22
- @cia1.save_state(out)
23
- @cia2.save_state(out)
24
- @sid.save_state(out)
25
- @vdc.save_state(out)
26
- end
27
-
28
- def load_state(input)
29
- input.marker("C128 BUS")
30
- ddr = input.int
31
- data = input.int
32
- floating = input.int
33
- @address = input.int
34
- @data = input.int
35
- @mmu.load_state(input)
36
- @ram.load_state(input)
37
- @color_lines.color_ram(0).load_state(input)
38
- @color_lines.color_ram(1).load_state(input)
39
- @cartridge&.load_state(input)
40
- @datasette.load_state(input)
41
- @cpu_port.load(ddr, data, floating)
42
- update_overlays!
43
- @vic.load_state(input)
44
- @control_ports.extra_rows = 0xf8 | @vic.extra_keyboard_lines
45
- @cia1.load_state(input)
46
- @cia2.load_state(input)
47
- @sid.load_state(input)
48
- @vdc.load_state(input)
49
- end
50
- end
51
- end
52
- end
53
- end