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
@@ -11,7 +11,7 @@ module Badline
11
11
  # $FF00-$FF04.
12
12
  #
13
13
  # In C64 mode the 8721 PLA decodes $01's LORAM, HIRAM and CHAREN and the
14
- # cartridge's EXROM and GAME as a C64's does (AddressBus::PLA), and the
14
+ # cartridge's EXROM and GAME as a C64's does (C64::Bus::PLA), and the
15
15
  # MMU answers nowhere.
16
16
  #
17
17
  # In both modes the RAM is the bank CR picks, with common RAM in bank 0,
@@ -34,12 +34,11 @@ module Badline
34
34
  # Colour RAM has two 1K banks (ColorLines).
35
35
  class Bus
36
36
  include Addressable
37
- include AddressBus::PLA
38
- include AddressBus::ROMs
37
+ include C64::Bus::PLA
38
+ include C64::Bus::ROMs
39
39
  include MMUPages
40
40
  include IOPages
41
41
  include Z80Pages
42
- include SavedState
43
42
 
44
43
  # The 8502's port has seven pins. P0-P5 are the 6510's, and P6 senses
45
44
  # the CAPS LOCK key, high while it is up. Bit 7 has no pin, and holds
@@ -48,9 +47,9 @@ module Badline
48
47
  PORT_FLOATING = 0b1000_1000
49
48
  CAPS_LOCK = 0b0100_0000
50
49
 
51
- # The C64's power-on pattern (AddressBus::RAM_POWER_ON) in both 64K
50
+ # The C64's power-on pattern (C64::Bus::RAM_POWER_ON) in both 64K
52
51
  # banks. The C128's own DRAMs' pattern is unmeasured.
53
- RAM_POWER_ON = Array.new(2**17) { |addr| AddressBus::RAM_POWER_ON[addr & 0xffff] }.freeze
52
+ RAM_POWER_ON = Array.new(2**17) { |addr| C64::Bus::RAM_POWER_ON[addr & 0xffff] }.freeze
54
53
 
55
54
  # The VIC's write side: a write to $D02F also drives the extra
56
55
  # keyboard lines K0-K2 onto the keyboard's rows 8-10.
@@ -143,7 +142,7 @@ module Badline
143
142
  @on_mode_change = nil
144
143
  plug_chips(model, sid_model)
145
144
 
146
- @datasette = Datasette.new
145
+ @datasette = Badline::Drives::Datasette.new
147
146
  @datasette.on_flag { @cia1.flag! }
148
147
  @datasette.on_sense_change { @cpu_port.refresh }
149
148
 
@@ -151,15 +150,18 @@ module Badline
151
150
  @color_ram = @color_lines.color_ram(1)
152
151
  build_z80_pages
153
152
  @vic_writes = VICWrites.new(@vic, @control_ports)
154
- @open_bus = AddressBus::OpenBus.new(@vic)
153
+ @open_bus = C64::Bus::OpenBus.new(@vic)
155
154
  @configuration_reads = ConfigurationPage.new(@mmu, @open_bus)
156
155
  @configuration_writes = ConfigurationPage.new(@mmu, @open_bus)
157
156
 
158
- @cpu_port = CPUPort.new(@datasette, pullups: PORT_PULLUPS, floating: PORT_FLOATING, caps_lock: CAPS_LOCK)
157
+ @cpu_port = Chips::CPU::Port.new(@datasette, pullups: PORT_PULLUPS, floating: PORT_FLOATING,
158
+ caps_lock: CAPS_LOCK)
159
159
  @io_port = @cpu_port.status
160
160
 
161
161
  @read_pages = Array.new(256)
162
162
  @write_pages = Array.new(256)
163
+ @bank_io_reads = Array.new(256)
164
+ @bank_io_writes = Array.new(256)
163
165
  @address = 0
164
166
  @data = 0
165
167
  @io_mapped = false
@@ -210,8 +212,21 @@ module Badline
210
212
  # ROM at $C000-$FFFF.
211
213
  def system_rom_mapped? = !@mmu.c64_mode? && @mmu.cr.nobits?(0x30)
212
214
 
213
- # The RAM the C128 KERNAL's bank number +bank+ reaches (Banks).
214
- def peek_bank(bank, addr) = @banks.peek(bank, addr)
215
+ # The byte the C128 KERNAL's bank number +bank+ reads at +addr+, as
216
+ # its INDFET does: the ROMs and I/O the bank's CR value maps, over the
217
+ # RAM it reaches (Banks).
218
+ def peek_bank(bank, addr)
219
+ cr = @banks.configuration(bank)
220
+ return @mmu.peek_configuration(addr) if addr.between?(0xff00, 0xff04)
221
+ return bank_io_peek(addr) if cr.nobits?(0x01) && (addr & 0xf000) == 0xd000
222
+ return @basic_low_rom.peek(addr) if cr.nobits?(0x02) && addr.between?(0x4000, 0x7fff)
223
+
224
+ select = addr < 0xc000 ? (cr >> 2) & 0x03 : (cr >> 4) & 0x03
225
+ return @banks.peek(bank, addr) if addr < 0x8000 || select == 3
226
+ return @open_bus.peek(addr) unless select.zero?
227
+
228
+ system_rom_peek(addr)
229
+ end
215
230
 
216
231
  def write_bank(bank, addr, bytes) = @banks.write(bank, addr, bytes)
217
232
 
@@ -274,17 +289,17 @@ module Badline
274
289
  end
275
290
 
276
291
  def plug_chips(model, sid_model)
277
- @keyboard = Keyboard.new(matrix: KEYBOARD_MATRIX)
278
- @joystick1 = Joystick.new
279
- @joystick2 = Joystick.new
280
- @control_ports = ControlPorts.new(keyboard: @keyboard, joystick1: @joystick1, joystick2: @joystick2)
281
- @vic = VIC.new(model: model.vic_model, region: @region)
282
- @cia1 = CIA.new(start: 0xdc00, peripheral: @control_ports, model: model.cia_model, region: @region)
283
- @cia2 = CIA.new(start: 0xdd00, model: model.cia_model, region: @region)
292
+ @keyboard = Input::Keyboard.new(matrix: KEYBOARD_MATRIX)
293
+ @joystick1 = Input::Joystick.new
294
+ @joystick2 = Input::Joystick.new
295
+ @control_ports = Input::ControlPorts.new(keyboard: @keyboard, joystick1: @joystick1, joystick2: @joystick2)
296
+ @vic = Chips::VIC.new(model: model.vic_model, region: @region)
297
+ @cia1 = Chips::CIA.new(start: 0xdc00, peripheral: @control_ports, model: model.cia_model, region: @region)
298
+ @cia2 = Chips::CIA.new(start: 0xdd00, model: model.cia_model, region: @region)
284
299
  @control_ports.port_a_source = @cia1
285
300
  @cia1.on_port_b4_change { |high| @vic.lightpen_level(high) }
286
- @sid = SID.new(model: sid_model, pots: @control_ports)
287
- @vdc = VDC.new(model: model.vdc_model, ram_kb: model.vdc_ram_kb, clock_hz: @region.clock_hz)
301
+ @sid = Chips::SID.new(model: sid_model, pots: @control_ports)
302
+ @vdc = Chips::VDC.new(model: model.vdc_model, ram_kb: model.vdc_ram_kb, clock_hz: @region.clock_hz)
288
303
  end
289
304
 
290
305
  def update_overlays!
@@ -13,8 +13,8 @@ module Badline
13
13
  @cia2 = cia2
14
14
  @c64_characters = c64_characters
15
15
  @c128_characters = c128_characters
16
- @bank0 = ColorMemory.new(vic)
17
- @bank1 = ColorMemory.new(vic)
16
+ @bank0 = C64::ColorMemory.new(vic)
17
+ @bank1 = C64::ColorMemory.new(vic)
18
18
  end
19
19
 
20
20
  # Colour RAM bank +number+, 0 or 1.
@@ -4,7 +4,7 @@ module Badline
4
4
  class C128
5
5
  # The C128's 8502, on the C128::Bus, which holds its I/O port.
6
6
  class CPU
7
- include Badline::CPU::Core
7
+ include Badline::Chips::CPU::Core
8
8
  end
9
9
  end
10
10
  end
@@ -2,13 +2,13 @@
2
2
 
3
3
  module Badline
4
4
  class C128
5
- # The true drives on the C128's serial bus: a Drive1541, the C128D's
6
- # built-in 1571 (Drive1571) or a 1581 (Drive1581::Slot), each in a
5
+ # The true drives on the C128's serial bus: a Drives::Model1541, the C128D's
6
+ # built-in 1571 (Drives::Model1571) or a 1581 (Drives::Model1581::Slot), each in a
7
7
  # field of its own, so none makes another's per-cycle call a union.
8
8
  module Drives
9
9
  attr_reader :drive1571
10
10
 
11
- # Plugs in a Drive1571, which then runs alongside the C128 on its own
11
+ # Plugs in a Drives::Model1571, which then runs alongside the C128 on its own
12
12
  # clock and talks to it over the serial bus, as attach_drive1541 does
13
13
  # for a 1541.
14
14
  def attach_drive1571(drive)
@@ -19,7 +19,7 @@ module Badline
19
19
  @serial_trap&.device = serial_trap_device
20
20
  end
21
21
 
22
- # Unplugs the Drive1571.
22
+ # Unplugs the Drives::Model1571.
23
23
  def detach_drive1571
24
24
  return unless @drive1571
25
25
 
@@ -35,14 +35,14 @@ module Badline
35
35
  # returns it.
36
36
  def plug_true_drive
37
37
  detach_drive1581 if drive1581_on_device8?
38
- Drive1571.new.tap { |drive| attach_drive1571(drive) }
38
+ Badline::Drives::Model1571.new.tap { |drive| attach_drive1571(drive) }
39
39
  end
40
40
 
41
41
  private
42
42
 
43
43
  # The serial bus, with no disk in device 8's traps and no true drive.
44
44
  def init_drives
45
- @drive = nil
45
+ @dos = nil
46
46
  @serial_trap = nil
47
47
  @save_trap = nil
48
48
  @drive1541 = nil
@@ -61,7 +61,7 @@ module Badline
61
61
  # A 1581 plugged in holds the machine's on_init handlers back until
62
62
  # its DOS has booted, which takes longer than the C128 KERNAL's.
63
63
  def drive1581_attached
64
- @init_threshold = [@init_threshold, Drive1581::BOOT_CYCLES].max if @cycles < @init_threshold
64
+ @init_threshold = [@init_threshold, Badline::Drives::Model1581::BOOT_CYCLES].max if @cycles < @init_threshold
65
65
  end
66
66
 
67
67
  # Unplugs the 1541 and the 1571 if either is device 8, for a 1581 to
@@ -72,36 +72,16 @@ module Badline
72
72
  detach_drive1571 if @drive1571&.device == device
73
73
  end
74
74
 
75
- # A true 1541 (Computer::Attachments#save_serial_bus), then a 1571 and
76
- # a 1581.
77
- def save_serial_bus(out)
78
- out.boolean(true).boolean(!@drive1541.nil?)
79
- if @drive1541
80
- out.int(@drive1541.device)
81
- @drive1541.save_state(out)
82
- end
83
- out.boolean(!@drive1571.nil?)
84
- if @drive1571
85
- out.int(@drive1571.device)
86
- @drive1571.save_state(out)
87
- end
88
- save_drive1581(out)
75
+ def save_drive1571_modules(sections)
76
+ drive1571 = @drive1571
77
+ drive1571&.save_modules(sections, "BL-D#{drive1571.device}")
78
+ sections
89
79
  end
90
80
 
91
- def load_serial_bus(input)
92
- input.boolean?
93
- load_drive1541(input)
94
- load_drive1571(input)
95
- load_drive1581(input)
96
- end
97
-
98
- def load_drive1571(input)
99
- return detach_drive1571 unless input.boolean?
100
-
101
- device = input.int
81
+ def load_drive1571_modules(modules, input, device)
102
82
  detach_drive1571 if @drive1571 && @drive1571.device != device
103
- attach_drive1571(Drive1571.new(device:)) unless @drive1571
104
- @drive1571.load_state(input)
83
+ attach_drive1571(Badline::Drives::Model1571.new(device:)) unless @drive1571
84
+ @drive1571.load_modules(modules, input, "BL-D#{device}")
105
85
  end
106
86
  end
107
87
  end
@@ -6,7 +6,7 @@ module Badline
6
6
  # through buffers MCR's FSDIR turns round. Outwards, the machine pushes
7
7
  # the lines the pins pull into the bus as they move. Inwards, CIA 1
8
8
  # hears the lines whenever a drive moves its own fast serial pins
9
- # (IECBus#on_fast_change).
9
+ # (Drives::SerialBus#on_fast_change).
10
10
  module FastSerial
11
11
  private
12
12
 
@@ -48,15 +48,15 @@ module Badline
48
48
  serial = @cia1.serial
49
49
  return 0 unless serial.output?
50
50
 
51
- low = serial.cnt ? 0 : IECBus::SRQ
52
- serial.sp_out ? low : low | IECBus::DATA
51
+ low = serial.cnt ? 0 : Badline::Drives::SerialBus::SRQ
52
+ serial.sp_out ? low : low | Badline::Drives::SerialBus::DATA
53
53
  end
54
54
 
55
55
  def hear_fast_serial
56
56
  low = @iec_bus.low_lines
57
57
  serial = @cia1.serial
58
- serial.cnt_in = low.nobits?(IECBus::SRQ)
59
- serial.sp_in = low.nobits?(IECBus::DATA)
58
+ serial.cnt_in = low.nobits?(Badline::Drives::SerialBus::SRQ)
59
+ serial.sp_in = low.nobits?(Badline::Drives::SerialBus::DATA)
60
60
  end
61
61
  end
62
62
  end
@@ -0,0 +1,117 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C128
5
+ # The whole machine as keyed snapshot modules (Snapshot::Keyed), in the
6
+ # order a load applies them, as C64::KeyedModules: BL-MACHINE with the
7
+ # last bus access under bus.*, the RAM, both banks of colour RAM, the
8
+ # MMU, the cartridge, the 8502 with its port, the Z80, the chips, the
9
+ # datasette, device 8 through the traps and the true drives. The
10
+ # machine's own fields load after the Z80's, which z80_ahead counts
11
+ # from.
12
+ module KeyedModules
13
+ def save_modules
14
+ bus = @bus
15
+ sections = [Snapshot::Keyed.section("BL-MACHINE") do |out|
16
+ save_machine_fields(out)
17
+ bus.save_fields(out, "bus.")
18
+ end]
19
+ sections << Snapshot::Keyed.section("BL-RAM") { |out| bus.ram.save_fields(out, "ram") }
20
+ sections << Snapshot::Keyed.section("BL-COLORRAM") { |out| bus.save_color_fields(out) }
21
+ sections << Snapshot::Keyed.section("BL-MMU") { |out| bus.mmu.save_fields(out) }
22
+ cartridge = bus.cartridge
23
+ sections << Snapshot::Keyed.section("BL-CART") { |out| cartridge.save_fields(out) } if cartridge
24
+ save_chip_modules(sections, bus)
25
+ sections << Snapshot::Keyed.section("BL-TAPE") { |out| bus.datasette.save_fields(out) }
26
+ sections << Snapshot::Keyed.section("BL-TRAPDOS") { |out| save_trap_dos_fields(out) } if mounted?
27
+ save_drive_modules(sections)
28
+ end
29
+
30
+ # Raises Snapshot::FormatError for the modules of another model, SID
31
+ # or mode.
32
+ def load_modules(modules)
33
+ machine = modules.machine
34
+ check_snapshot_setup(Snapshot::C128Setup.read_fields(machine))
35
+ bus = @bus
36
+ bus.ram.load_fields(modules.required("BL-RAM"), "ram")
37
+ bus.load_color_fields(modules.required("BL-COLORRAM"))
38
+ bus.mmu.load_fields(modules.required("BL-MMU"))
39
+ load_cartridge_module(modules.optional("BL-CART"))
40
+ load_chip_modules(modules)
41
+ bus.load_fields(machine, "bus.")
42
+ load_machine_fields(machine)
43
+ bus.datasette.load_fields(modules.required("BL-TAPE"))
44
+ trap_dos = modules.optional("BL-TRAPDOS")
45
+ trap_dos ? load_trap_dos_fields(trap_dos, detached: modules.detached?) : unmount
46
+ load_drive_modules(modules)
47
+ modules_restored!
48
+ self
49
+ end
50
+
51
+ private
52
+
53
+ def save_chip_modules(sections, bus)
54
+ sections << Snapshot::Keyed.section("BL-CPU") do |out|
55
+ @cpu.save_fields(out)
56
+ bus.save_port_fields(out)
57
+ end
58
+ sections << Snapshot::Keyed.section("BL-Z80") { |out| @z80.save_fields(out) }
59
+ sections << Snapshot::Keyed.section("BL-VIC") { |out| @vic.save_fields(out) }
60
+ sections << Snapshot::Keyed.section("BL-VDC") { |out| @vdc.save_fields(out) }
61
+ sections << Snapshot::Keyed.section("BL-CIA1") { |out| @cia1.save_fields(out) }
62
+ sections << Snapshot::Keyed.section("BL-CIA2") { |out| @cia2.save_fields(out) }
63
+ sections << Snapshot::Keyed.section("BL-SID") { |out| @sid.save_fields(out) }
64
+ end
65
+
66
+ # The port goes in ahead of the chips, as the C64's does, and the bus
67
+ # maps its banks and the keyboard's extra rows once they are in. That
68
+ # hands the bus to the CPU the MMU names, which resets the Z80's
69
+ # schedule and can reset the 8502, so the CPUs, the last bus access
70
+ # and the machine's own fields load after it.
71
+ def load_chip_modules(modules)
72
+ cpu = modules.required("BL-CPU")
73
+ @bus.load_port_fields(cpu)
74
+ @vic.load_fields(modules.required("BL-VIC"))
75
+ @vdc.load_fields(modules.required("BL-VDC"))
76
+ @cia1.load_fields(modules.required("BL-CIA1"))
77
+ @cia2.load_fields(modules.required("BL-CIA2"))
78
+ @sid.load_fields(modules.required("BL-SID"))
79
+ @bus.restored!
80
+ @cpu.load_fields(cpu)
81
+ @z80.load_fields(modules.required("BL-Z80"))
82
+ end
83
+
84
+ # The cartridge comes back built afresh from the CRT image the module
85
+ # holds, before its state goes in. No module means no cartridge.
86
+ def load_cartridge_module(input)
87
+ if input
88
+ cartridge = C64::Cartridge.from_fields(input)
89
+ connect_cartridge(cartridge)
90
+ cartridge.load_fields(input)
91
+ elsif @bus.cartridge
92
+ @bus.detach_cartridge
93
+ end
94
+ end
95
+
96
+ def modules_restored!
97
+ @cpu.restored!
98
+ @z80.restored!
99
+ @vic.restored!
100
+ @vdc.restored!
101
+ @cia1.restored!
102
+ @cia2.restored!
103
+ @sid.restored!
104
+ machine_restored!
105
+ end
106
+
107
+ def check_snapshot_setup(setup)
108
+ ours = snapshot_setup
109
+ return if setup == ours
110
+
111
+ raise Snapshot::FormatError, "the snapshot is of a #{setup}, not a #{ours}"
112
+ end
113
+ end
114
+
115
+ include KeyedModules
116
+ end
117
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C128
5
+ # The machine's own fields in a keyed snapshot module (Snapshot::Keyed,
6
+ # BL-MACHINE): the family, its model, SID and mode by name, the cycle
7
+ # count, $D030's clock bits on their way, the NMI glue, the two
8
+ # schedulers' offsets (z80_ahead, the Z80's T-states past when it was
9
+ # due, and chips_ahead), an 8502 reset waiting for the bus, and under
10
+ # host.* the host's typing (the codes still to type, whether it is
11
+ # typing, and where Input::MatrixTypist is in a code on the key
12
+ # matrix), C= held from power-on and the on_init handlers still to run.
13
+ # They load after the Z80's own fields, which z80_ahead counts from.
14
+ module KeyedState
15
+ # How many more on_init handlers the machine a snapshot was taken of had
16
+ # yet to run than this one has. Nil until the machine is restored.
17
+ attr_reader :init_handlers_lost
18
+
19
+ # Whether a snapshot saves now (Machine::Settling): the 8502 between
20
+ # instructions or jammed. While the Z80 runs, the 8502 waits at the
21
+ # boundary it handed the bus over at, and the Z80 runs whole
22
+ # instructions.
23
+ def settled_for_snapshot? = @cpu.boundary? || @cpu.jammed?
24
+
25
+ # The SID's deferred cycles and writes, run up to this cycle, and the
26
+ # VIC's sprite collisions latched up to the beam.
27
+ def settle_chips_for_snapshot
28
+ sid.catch_up!
29
+ @vic.fold_collisions!
30
+ end
31
+
32
+ def save_machine_fields(out)
33
+ out.text("family", "c128").text("written_by", VERSION)
34
+ snapshot_setup.write_fields(out)
35
+ out.int("cycles", @cycles).int("clock_bits", @clock_bits).bool("nmi_asserted", @nmi_asserted)
36
+ out.bool("cartridge_nmi", @cartridge_nmi).bool("restore_pulse", @restore_pulse)
37
+ out.int("z80_ahead", @z80.cycles - @z80_due).int("chips_ahead", @chips_ahead)
38
+ out.bool("cpu_reset_pending", @cpu_reset_pending)
39
+ pending = @pending_keys
40
+ out.ints("host.pending_keys", pending) if pending
41
+ out.bool("host.typing", !pending.nil?)
42
+ out.int("host.init_pending", @cycles <= init_threshold ? @init_handlers.length : 0)
43
+ out.bool("host.holding_commodore", @holding_commodore)
44
+ @typist.save_fields(out, "host.typist.")
45
+ end
46
+
47
+ def load_machine_fields(input)
48
+ @cycles = input.int("cycles", @cycles)
49
+ @clock_bits = input.int("clock_bits", @clock_bits)
50
+ @nmi_asserted = input.bool("nmi_asserted", @nmi_asserted)
51
+ @cartridge_nmi = input.bool("cartridge_nmi", @cartridge_nmi)
52
+ @restore_pulse = input.bool("restore_pulse", @restore_pulse)
53
+ @z80_due = @z80.cycles - input.int("z80_ahead", @z80.cycles - @z80_due)
54
+ @chips_ahead = input.int("chips_ahead", @chips_ahead)
55
+ @cpu_reset_pending = input.bool("cpu_reset_pending", @cpu_reset_pending)
56
+ pending = input.ints("host.pending_keys", [])
57
+ @pending_keys = input.bool("host.typing", !pending.empty?) ? pending.dup : nil
58
+ @init_handlers_lost = [input.int("host.init_pending", 0) - @init_handlers.length, 0].max
59
+ load_holding_fields(input)
60
+ @typist.load_fields(input, "host.typist.")
61
+ end
62
+
63
+ # Which CPU has the bus and whose turn it is, from the MMU and the
64
+ # schedulers' offsets, and the serial bus's lines.
65
+ def machine_restored!
66
+ @z80_running = @bus.z80?
67
+ @z80_turn = @z80_running || @chips_ahead.positive?
68
+ push_serial_lines
69
+ push_fast_serial
70
+ end
71
+
72
+ private
73
+
74
+ # C= held from power-on until the machine reaches C64 mode
75
+ # (Modes#hold_commodore_key).
76
+ def load_holding_fields(input)
77
+ holding = input.bool("host.holding_commodore", @holding_commodore)
78
+ keyboard.release(:cbm) if @holding_commodore && !holding
79
+ keyboard.press(:cbm) if holding && !@holding_commodore
80
+ @holding_commodore = holding
81
+ end
82
+
83
+ # How this machine was built.
84
+ def snapshot_setup
85
+ Snapshot::C128Setup.new(model: @model.name, sid_model: @sid.model, mode: @c64_built ? :c64 : :c128)
86
+ end
87
+ end
88
+
89
+ include KeyedState
90
+ end
91
+ end
@@ -21,6 +21,11 @@ module Badline
21
21
  @bus.caps_lock = false
22
22
  end
23
23
 
24
+ # Pushes CAPS LOCK, down if it was up and up if it was down.
25
+ def push_caps_lock
26
+ @bus.caps_lock = !@bus.caps_lock
27
+ end
28
+
24
29
  # The 40/80 DISPLAY key locks down and up. The KERNAL reads it at reset
25
30
  # and starts the screen editor on the VDC's 80 columns while it is down.
26
31
  def press_display_key
@@ -30,6 +35,10 @@ module Badline
30
35
  def release_display_key
31
36
  @bus.mmu.display_key = false
32
37
  end
38
+
39
+ def push_display_key
40
+ @bus.mmu.display_key = !@bus.mmu.display_key
41
+ end
33
42
  end
34
43
  end
35
44
  end
@@ -151,16 +151,17 @@ module Badline
151
151
  end
152
152
  end
153
153
 
154
- # The registers and the P0H and P1H writes waiting for P0L and P1L.
155
- # The bus maps the restored registers once its own state is back.
156
- def save_state(out)
157
- out.ints(@registers).int(@p0h_latch).int(@p1h_latch)
154
+ # The registers and the page pointers' high bytes waiting for their
155
+ # low bytes, in a keyed snapshot module (Snapshot::Keyed). The bus
156
+ # maps its banks from them afterwards.
157
+ def save_fields(out)
158
+ out.bytes("registers", @registers).int("p0h_latch", @p0h_latch).int("p1h_latch", @p1h_latch)
158
159
  end
159
160
 
160
- def load_state(input)
161
- input.ints_into(@registers)
162
- @p0h_latch = input.int
163
- @p1h_latch = input.int
161
+ def load_fields(input)
162
+ input.bytes_into("registers", @registers)
163
+ @p0h_latch = input.masked("p0h_latch", @p0h_latch, 0x0f)
164
+ @p1h_latch = input.masked("p1h_latch", @p1h_latch, 0x0f)
164
165
  end
165
166
 
166
167
  # CR and the LCRs at $FF00-$FF04: an LCR reads its PCR.
@@ -6,7 +6,7 @@ module Badline
6
6
  # What the MMU maps. For the CPU: the RAM bank, common RAM and the
7
7
  # pages page 0 and page 1 move to in both modes, and CR's ROMs and I/O
8
8
  # in C128 mode. C64 mode lays the PLA's ROMs and I/O over the same RAM
9
- # (AddressBus::PLA).
9
+ # (C64::Bus::PLA).
10
10
  module MMUPages
11
11
  private
12
12
 
@@ -46,6 +46,26 @@ module Badline
46
46
  end
47
47
  end
48
48
 
49
+ # The system ROM's byte at +addr+, $8000 or above, as CR value 0 maps it.
50
+ def system_rom_peek(addr)
51
+ if addr < 0xc000
52
+ @basic_high_rom.peek(addr)
53
+ elsif addr < 0xd000
54
+ @editor_rom.peek(addr)
55
+ elsif addr < 0xe000
56
+ @c128_character_rom.peek(addr)
57
+ else
58
+ @c128_kernal_rom.peek(addr)
59
+ end
60
+ end
61
+
62
+ # The chip's byte at +addr+, in $D000-$DFFF, as C128 mode's I/O maps it.
63
+ def bank_io_peek(addr)
64
+ lay_out_io(@bank_io_reads, @bank_io_writes)
65
+ @bank_io_reads[0xd5] = @mmu
66
+ @bank_io_reads[addr >> 8].peek(addr)
67
+ end
68
+
49
69
  # The bank CR picks, with common RAM in bank 0, then the pages page 0
50
70
  # and page 1 move to.
51
71
  def map_ram_pages
@@ -33,7 +33,7 @@ module Badline
33
33
  def mode_changed
34
34
  layout = trap_layout
35
35
  @capture_output&.layout = layout
36
- if @drive
36
+ if @dos
37
37
  remove_kernal_traps
38
38
  install_kernal_traps(layout)
39
39
  end
@@ -41,20 +41,30 @@ module Badline
41
41
 
42
42
  keyboard.release(:cbm)
43
43
  @holding_commodore = false
44
- @init_threshold = @cycles + Computer::INIT_THRESHOLD if @cycles < @init_threshold
44
+ @init_threshold = @cycles + C64::INIT_THRESHOLD if @cycles < @init_threshold
45
45
  end
46
46
 
47
47
  # The keyboard buffer of the KERNAL the machine runs: the C64's, or in
48
48
  # C128 mode BASIC 7.0's.
49
- def feed_keyboard
50
- c64 = mode == :c64
51
- count = c64 ? KeyboardBuffer::COUNT : C128_KEYBOARD_COUNT
52
- return unless ram.peek(count).zero?
53
-
54
- chunk = @pending_keys.shift(KeyboardBuffer::CAPACITY)
55
- ram.write(c64 ? KeyboardBuffer::ADDRESS : C128_KEYBOARD_BUFFER, chunk)
56
- ram.poke(count, chunk.length)
57
- @pending_keys = nil if @pending_keys.empty?
49
+ def keyboard_buffer
50
+ mode == :c64 ? Machine::KeyboardBuffer::C64_LAYOUT : Machine::KeyboardBuffer::C128_LAYOUT
51
+ end
52
+
53
+ # Types the text type_text left: into the keyboard buffer, or while
54
+ # the Z80 runs, as under CP/M, where no KERNAL reads the buffer, on
55
+ # the key matrix, all of it once begun there.
56
+ def type_pending
57
+ if @z80_running || @typist.typing?
58
+ type_on_matrix
59
+ else
60
+ feed_keyboard
61
+ end
62
+ end
63
+
64
+ def type_on_matrix
65
+ pending = @pending_keys
66
+ @typist.cycle!(pending)
67
+ @pending_keys = nil if pending.empty? && !@typist.typing?
58
68
  end
59
69
  end
60
70
  end
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "badline/z80/core"
3
+ require "badline/chips/z80/core"
4
4
 
5
5
  module Badline
6
6
  class C128
7
7
  # The C128's Z80A, on the Z80's side of the C128::Bus.
8
8
  class Z80
9
- include Badline::Z80::Core
9
+ include Badline::Chips::Z80::Core
10
10
  end
11
11
 
12
12
  # The Z80's accesses, through the pages C128::Bus lays out for it
@@ -58,7 +58,7 @@ module Badline
58
58
  # interrupt lines going to the Z80.
59
59
  def clock_chips
60
60
  handle_init if @cycles == @init_threshold
61
- feed_keyboard if @pending_keys
61
+ type_pending if @pending_keys
62
62
 
63
63
  clock_bits = @clock_bits
64
64
  @clock_bits = @vic.clock_bits