badline 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (516) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/CLAUDE.md +59 -31
  4. data/README.md +1 -1
  5. data/doc/library.md +9 -9
  6. data/doc/pinned-behaviour.md +105 -105
  7. data/doc/snapshots.md +1 -4
  8. data/lib/badline/audio/bare_player.rb +4 -4
  9. data/lib/badline/audio/cli.rb +6 -6
  10. data/lib/badline/audio/jukebox.rb +2 -2
  11. data/lib/badline/audio/machine_player.rb +2 -2
  12. data/lib/badline/{media → audio}/queue.rb +1 -1
  13. data/lib/badline/audio/queued_tune.rb +6 -6
  14. data/lib/badline/audio/renderer.rb +5 -5
  15. data/lib/badline/audio/stereo.rb +1 -1
  16. data/lib/badline/c128/{bus_state.rb → bus/saved_state.rb} +6 -6
  17. data/lib/badline/c128/bus.rb +30 -51
  18. data/lib/badline/c128/color_lines.rb +2 -2
  19. data/lib/badline/c128/cpu.rb +1 -1
  20. data/lib/badline/c128/drives.rb +10 -11
  21. data/lib/badline/c128/fast_serial.rb +5 -5
  22. data/lib/badline/c128/mmu_pages.rb +1 -1
  23. data/lib/badline/c128/modes.rb +2 -2
  24. data/lib/badline/c128/saved_state.rb +21 -47
  25. data/lib/badline/c128/z80.rb +2 -2
  26. data/lib/badline/c128.rb +18 -72
  27. data/lib/badline/{computer → c64}/attachments.rb +16 -47
  28. data/lib/badline/c64/banked_ram/banking.rb +32 -0
  29. data/lib/badline/c64/banked_ram/plus256k.rb +56 -0
  30. data/lib/badline/c64/banked_ram/plus60k.rb +45 -0
  31. data/lib/badline/c64/banked_ram/unexpanded.rb +30 -0
  32. data/lib/badline/c64/banked_ram.rb +23 -0
  33. data/lib/badline/c64/bus/extra_sids.rb +32 -0
  34. data/lib/badline/c64/bus/fittings.rb +40 -0
  35. data/lib/badline/c64/bus/pla.rb +149 -0
  36. data/lib/badline/c64/bus/roms.rb +41 -0
  37. data/lib/badline/c64/bus/saved_state.rb +68 -0
  38. data/lib/badline/c64/bus/sid_slots.rb +44 -0
  39. data/lib/badline/c64/bus.rb +218 -0
  40. data/lib/badline/c64/cartridge/action_replay.rb +128 -0
  41. data/lib/badline/c64/cartridge/atomic_power.rb +26 -0
  42. data/lib/badline/c64/cartridge/bank.rb +83 -0
  43. data/lib/badline/c64/cartridge/comal80.rb +52 -0
  44. data/lib/badline/c64/cartridge/dinamic.rb +36 -0
  45. data/lib/badline/c64/cartridge/easy_flash.rb +147 -0
  46. data/lib/badline/c64/cartridge/epyx_fastload.rb +81 -0
  47. data/lib/badline/c64/cartridge/final_cartridge3.rb +91 -0
  48. data/lib/badline/c64/cartridge/flash/saved_state.rb +40 -0
  49. data/lib/badline/c64/cartridge/flash.rb +279 -0
  50. data/lib/badline/c64/cartridge/freezer.rb +35 -0
  51. data/lib/badline/c64/cartridge/fun_play.rb +40 -0
  52. data/lib/badline/c64/cartridge/g_mod2.rb +76 -0
  53. data/lib/badline/c64/cartridge/game_system.rb +42 -0
  54. data/lib/badline/c64/cartridge/geo_ram.rb +81 -0
  55. data/lib/badline/c64/cartridge/kcs_power.rb +77 -0
  56. data/lib/badline/c64/cartridge/mach5.rb +34 -0
  57. data/lib/badline/c64/cartridge/magic_desk.rb +32 -0
  58. data/lib/badline/c64/cartridge/ocean.rb +37 -0
  59. data/lib/badline/c64/cartridge/pagefox.rb +70 -0
  60. data/lib/badline/c64/cartridge/retro_replay/saved_state.rb +47 -0
  61. data/lib/badline/c64/cartridge/retro_replay.rb +286 -0
  62. data/lib/badline/c64/cartridge/rex_utility.rb +31 -0
  63. data/lib/badline/c64/cartridge/rgcd.rb +60 -0
  64. data/lib/badline/c64/cartridge/saved_state.rb +63 -0
  65. data/lib/badline/c64/cartridge/simons_basic.rb +37 -0
  66. data/lib/badline/c64/cartridge/standard.rb +17 -0
  67. data/lib/badline/c64/cartridge/super_games.rb +50 -0
  68. data/lib/badline/c64/cartridge/westermann.rb +32 -0
  69. data/lib/badline/c64/cartridge/zaxxon.rb +68 -0
  70. data/lib/badline/c64/cartridge.rb +258 -0
  71. data/lib/badline/c64/color_memory.rb +27 -0
  72. data/lib/badline/c64/common.rb +34 -0
  73. data/lib/badline/c64/kernal_traps.rb +89 -0
  74. data/lib/badline/c64/reu/dma/saved_state.rb +52 -0
  75. data/lib/badline/c64/reu/dma.rb +275 -0
  76. data/lib/badline/c64/reu/ram.rb +109 -0
  77. data/lib/badline/c64/reu/saved_state.rb +55 -0
  78. data/lib/badline/c64/reu/trigger.rb +34 -0
  79. data/lib/badline/c64/reu.rb +291 -0
  80. data/lib/badline/{computer → c64}/saved_state.rb +13 -18
  81. data/lib/badline/{computer → c64}/true_drives.rb +20 -31
  82. data/lib/badline/{computer.rb → c64.rb} +22 -80
  83. data/lib/badline/chips/cia/fast_forward.rb +62 -0
  84. data/lib/badline/chips/cia/interrupt_register.rb +145 -0
  85. data/lib/badline/chips/cia/saved_state.rb +49 -0
  86. data/lib/badline/chips/cia/serial/saved_state.rb +45 -0
  87. data/lib/badline/chips/cia/serial.rb +250 -0
  88. data/lib/badline/chips/cia/time_of_day.rb +232 -0
  89. data/lib/badline/chips/cia/timer.rb +208 -0
  90. data/lib/badline/chips/cia.rb +281 -0
  91. data/lib/badline/chips/cpu/addressing.rb +133 -0
  92. data/lib/badline/chips/cpu/boundary.rb +56 -0
  93. data/lib/badline/chips/cpu/core.rb +167 -0
  94. data/lib/badline/chips/cpu/instruction.rb +338 -0
  95. data/lib/badline/chips/cpu/instruction_set/arithmetic.rb +118 -0
  96. data/lib/badline/chips/cpu/instruction_set/bitwise.rb +130 -0
  97. data/lib/badline/chips/cpu/instruction_set/branch.rb +83 -0
  98. data/lib/badline/chips/cpu/instruction_set/flag.rb +67 -0
  99. data/lib/badline/chips/cpu/instruction_set/illegal.rb +274 -0
  100. data/lib/badline/chips/cpu/instruction_set/inc_dec.rb +73 -0
  101. data/lib/badline/chips/cpu/instruction_set/stack.rb +56 -0
  102. data/lib/badline/chips/cpu/instruction_set/transfer.rb +141 -0
  103. data/lib/badline/chips/cpu/instruction_set.rb +59 -0
  104. data/lib/badline/chips/cpu/interrupts.rb +108 -0
  105. data/lib/badline/chips/cpu/microcode.rb +179 -0
  106. data/lib/badline/chips/cpu/operations.rb +90 -0
  107. data/lib/badline/chips/cpu/port.rb +116 -0
  108. data/lib/badline/chips/cpu/saved_state.rb +117 -0
  109. data/lib/badline/chips/cpu/stack_operations.rb +84 -0
  110. data/lib/badline/chips/cpu/traps.rb +23 -0
  111. data/lib/badline/chips/cpu.rb +12 -0
  112. data/lib/badline/chips/sid/catch_up.rb +122 -0
  113. data/lib/badline/chips/sid/decimator.rb +66 -0
  114. data/lib/badline/chips/sid/envelope/saved_state.rb +70 -0
  115. data/lib/badline/chips/sid/envelope.rb +241 -0
  116. data/lib/badline/chips/sid/filter/saved_state.rb +42 -0
  117. data/lib/badline/chips/sid/filter.rb +241 -0
  118. data/lib/badline/chips/sid/saved_state.rb +52 -0
  119. data/lib/badline/chips/sid/voice.rb +79 -0
  120. data/lib/badline/chips/sid/waveform/combined.rb +128 -0
  121. data/lib/badline/chips/sid/waveform/fast_forward.rb +107 -0
  122. data/lib/badline/chips/sid/waveform/noise_writeback.rb +124 -0
  123. data/lib/badline/chips/sid/waveform/saved_state.rb +68 -0
  124. data/lib/badline/chips/sid/waveform.rb +307 -0
  125. data/lib/badline/chips/sid.rb +265 -0
  126. data/lib/badline/{c128 → chips}/vdc/memory.rb +1 -1
  127. data/lib/badline/{c128 → chips}/vdc/painter.rb +1 -1
  128. data/lib/badline/{c128 → chips}/vdc/raster.rb +1 -1
  129. data/lib/badline/chips/vdc/saved_state.rb +36 -0
  130. data/lib/badline/{c128 → chips}/vdc/window.rb +1 -1
  131. data/lib/badline/{c128 → chips}/vdc.rb +7 -31
  132. data/lib/badline/chips/via/control_lines.rb +124 -0
  133. data/lib/badline/chips/via/fast_forward.rb +55 -0
  134. data/lib/badline/chips/via/interrupt_register.rb +69 -0
  135. data/lib/badline/chips/via/saved_state.rb +44 -0
  136. data/lib/badline/chips/via/shift_register.rb +182 -0
  137. data/lib/badline/chips/via/timer1.rb +133 -0
  138. data/lib/badline/chips/via/timer2.rb +135 -0
  139. data/lib/badline/chips/via.rb +268 -0
  140. data/lib/badline/chips/vic/bank.rb +135 -0
  141. data/lib/badline/chips/vic/border_mask.rb +88 -0
  142. data/lib/badline/chips/vic/collisions.rb +117 -0
  143. data/lib/badline/chips/vic/color_patches.rb +49 -0
  144. data/lib/badline/chips/vic/display_state.rb +187 -0
  145. data/lib/badline/chips/vic/graphics_mode.rb +166 -0
  146. data/lib/badline/chips/vic/graphics_shifter/saved_state.rb +40 -0
  147. data/lib/badline/chips/vic/graphics_shifter.rb +187 -0
  148. data/lib/badline/chips/vic/register_log.rb +83 -0
  149. data/lib/badline/chips/vic/registers.rb +197 -0
  150. data/lib/badline/chips/vic/saved_state.rb +82 -0
  151. data/lib/badline/chips/vic/sequencer/saved_state.rb +91 -0
  152. data/lib/badline/chips/vic/sequencer.rb +277 -0
  153. data/lib/badline/chips/vic/sequencer_output.rb +118 -0
  154. data/lib/badline/chips/vic/sprite/internal_bus.rb +70 -0
  155. data/lib/badline/chips/vic/sprite/saved_state.rb +66 -0
  156. data/lib/badline/chips/vic/sprite/shifter.rb +148 -0
  157. data/lib/badline/chips/vic/sprite/timing.rb +58 -0
  158. data/lib/badline/chips/vic/sprite.rb +339 -0
  159. data/lib/badline/chips/vic/sprites/saved_state.rb +59 -0
  160. data/lib/badline/chips/vic/sprites.rb +284 -0
  161. data/lib/badline/chips/vic.rb +783 -0
  162. data/lib/badline/chips/vic_i/painter/saved_state.rb +40 -0
  163. data/lib/badline/{vic20/vic → chips/vic_i}/painter.rb +6 -30
  164. data/lib/badline/{vic20/vic → chips/vic_i}/saved_state.rb +2 -2
  165. data/lib/badline/chips/vic_i/sound/output.rb +85 -0
  166. data/lib/badline/chips/vic_i/sound.rb +235 -0
  167. data/lib/badline/{vic20/vic → chips/vic_i}/text_window.rb +2 -2
  168. data/lib/badline/{vic20/vic.rb → chips/vic_i.rb} +5 -5
  169. data/lib/badline/chips/z80/arithmetic.rb +119 -0
  170. data/lib/badline/chips/z80/bit_page.rb +57 -0
  171. data/lib/badline/chips/z80/block_io.rb +60 -0
  172. data/lib/badline/chips/z80/block_transfers.rb +61 -0
  173. data/lib/badline/chips/z80/bus_cycles.rb +113 -0
  174. data/lib/badline/chips/z80/core.rb +115 -0
  175. data/lib/badline/chips/z80/exchanges.rb +52 -0
  176. data/lib/badline/chips/z80/extended_page.rb +91 -0
  177. data/lib/badline/chips/z80/flags.rb +39 -0
  178. data/lib/badline/chips/z80/interrupt_acceptance.rb +48 -0
  179. data/lib/badline/chips/z80/jumps.rb +84 -0
  180. data/lib/badline/chips/z80/loads.rb +100 -0
  181. data/lib/badline/chips/z80/main_page.rb +136 -0
  182. data/lib/badline/chips/z80/registers.rb +122 -0
  183. data/lib/badline/chips/z80/saved_state.rb +71 -0
  184. data/lib/badline/chips/z80/shifts.rb +66 -0
  185. data/lib/badline/chips/z80.rb +13 -0
  186. data/lib/badline/core.rb +27 -29
  187. data/lib/badline/drives/datasette/saved_state.rb +37 -0
  188. data/lib/badline/drives/datasette.rb +140 -0
  189. data/lib/badline/drives/engine/core.rb +149 -0
  190. data/lib/badline/drives/engine/fast_serial.rb +75 -0
  191. data/lib/badline/drives/engine/idle.rb +127 -0
  192. data/lib/badline/drives/engine/idle_cpu.rb +30 -0
  193. data/lib/badline/drives/engine/orbit.rb +81 -0
  194. data/lib/badline/drives/engine/serial_lines.rb +75 -0
  195. data/lib/badline/drives/engine/sleep.rb +114 -0
  196. data/lib/badline/drives/engine/vias.rb +86 -0
  197. data/lib/badline/drives/engine/watch.rb +152 -0
  198. data/lib/badline/drives/engine.rb +11 -0
  199. data/lib/badline/drives/model1541/bus.rb +88 -0
  200. data/lib/badline/drives/model1541/byte_ready.rb +50 -0
  201. data/lib/badline/drives/model1541/cpu.rb +13 -0
  202. data/lib/badline/drives/model1541/disk/saved_state.rb +88 -0
  203. data/lib/badline/drives/model1541/disk.rb +317 -0
  204. data/lib/badline/drives/model1541/disk_via.rb +38 -0
  205. data/lib/badline/drives/model1541/gcr.rb +59 -0
  206. data/lib/badline/drives/model1541/mechanism/saved_state.rb +72 -0
  207. data/lib/badline/drives/model1541/mechanism.rb +315 -0
  208. data/lib/badline/drives/model1541/rotation.rb +123 -0
  209. data/lib/badline/drives/model1541/saved_state.rb +44 -0
  210. data/lib/badline/drives/model1541/sector_reader.rb +78 -0
  211. data/lib/badline/drives/model1541/serial_port.rb +20 -0
  212. data/lib/badline/drives/model1541/track.rb +100 -0
  213. data/lib/badline/drives/model1541.rb +81 -0
  214. data/lib/badline/drives/model1571/bus.rb +113 -0
  215. data/lib/badline/drives/model1571/cpu.rb +13 -0
  216. data/lib/badline/drives/model1571/saved_state.rb +47 -0
  217. data/lib/badline/drives/model1571/serial_port.rb +39 -0
  218. data/lib/badline/drives/model1571/serial_via.rb +27 -0
  219. data/lib/badline/drives/model1571/wd1770.rb +122 -0
  220. data/lib/badline/drives/model1571.rb +142 -0
  221. data/lib/badline/drives/model1581/bus.rb +139 -0
  222. data/lib/badline/drives/model1581/cpu.rb +13 -0
  223. data/lib/badline/drives/model1581/disk/saved_state.rb +89 -0
  224. data/lib/badline/drives/model1581/disk.rb +137 -0
  225. data/lib/badline/drives/model1581/mechanism.rb +119 -0
  226. data/lib/badline/drives/model1581/saved_state.rb +42 -0
  227. data/lib/badline/drives/model1581/serial_port.rb +54 -0
  228. data/lib/badline/drives/model1581/slot.rb +79 -0
  229. data/lib/badline/drives/model1581/track.rb +102 -0
  230. data/lib/badline/drives/model1581/track_bytes.rb +77 -0
  231. data/lib/badline/drives/model1581/wd1772/registers.rb +91 -0
  232. data/lib/badline/drives/model1581/wd1772/saved_state.rb +68 -0
  233. data/lib/badline/drives/model1581/wd1772/sector_writes.rb +75 -0
  234. data/lib/badline/drives/model1581/wd1772/sectors.rb +152 -0
  235. data/lib/badline/drives/model1581/wd1772/stepping.rb +111 -0
  236. data/lib/badline/drives/model1581/wd1772/tracks.rb +127 -0
  237. data/lib/badline/drives/model1581/wd1772/turn.rb +75 -0
  238. data/lib/badline/drives/model1581/wd1772.rb +218 -0
  239. data/lib/badline/drives/model1581.rb +206 -0
  240. data/lib/badline/drives/serial_bus.rb +161 -0
  241. data/lib/badline/frontend/boot.rb +10 -61
  242. data/lib/badline/frontend/machine_window.rb +3 -1
  243. data/lib/badline/frontend/player/filter_view.rb +1 -1
  244. data/lib/badline/frontend/player/player_controller.rb +2 -2
  245. data/lib/badline/frontend/player/player_screen.rb +1 -0
  246. data/lib/badline/frontend/player/theme.rb +7 -7
  247. data/lib/badline/frontend/timeline.rb +3 -3
  248. data/lib/badline/input/control_ports.rb +78 -0
  249. data/lib/badline/input/joystick.rb +27 -0
  250. data/lib/badline/input/keyboard.rb +114 -0
  251. data/lib/badline/input.rb +3 -0
  252. data/lib/badline/kernal_trap/{drive → dos}/block_commands.rb +1 -1
  253. data/lib/badline/kernal_trap/dos/channel.rb +183 -0
  254. data/lib/badline/kernal_trap/{drive → dos}/channels.rb +1 -1
  255. data/lib/badline/kernal_trap/{drive → dos}/memory.rb +1 -1
  256. data/lib/badline/kernal_trap/{drive → dos}/parameters.rb +1 -1
  257. data/lib/badline/kernal_trap/{drive → dos}/status.rb +1 -1
  258. data/lib/badline/kernal_trap/{drive → dos}/write_file.rb +1 -1
  259. data/lib/badline/kernal_trap/{drive → dos}/writes.rb +1 -1
  260. data/lib/badline/kernal_trap/{drive.rb → dos.rb} +11 -10
  261. data/lib/badline/kernal_trap/{file.rb → file_routine.rb} +1 -1
  262. data/lib/badline/kernal_trap/load.rb +6 -6
  263. data/lib/badline/kernal_trap/save.rb +5 -5
  264. data/lib/badline/kernal_trap/serial.rb +7 -7
  265. data/lib/badline/kernal_trap.rb +2 -3
  266. data/lib/badline/machine/clocking.rb +50 -0
  267. data/lib/badline/machine.rb +63 -7
  268. data/lib/badline/media/boot_disk.rb +2 -2
  269. data/lib/badline/media/disk_list.rb +3 -3
  270. data/lib/badline/media/disk_set.rb +1 -1
  271. data/lib/badline/media/extensions.rb +33 -0
  272. data/lib/badline/media/program.rb +28 -0
  273. data/lib/badline/media/true_drive.rb +4 -3
  274. data/lib/badline/media/tune.rb +35 -0
  275. data/lib/badline/media/vic20_cartridge.rb +1 -7
  276. data/lib/badline/media/vic20_media.rb +38 -80
  277. data/lib/badline/media.rb +84 -81
  278. data/lib/badline/model.rb +1 -1
  279. data/lib/badline/options/event.rb +3 -1
  280. data/lib/badline/roms/README +6 -6
  281. data/lib/badline/sdl.rb +1 -0
  282. data/lib/badline/{storage/sid_file.rb → sid_tune/file.rb} +3 -3
  283. data/lib/badline/{storage → sid_tune}/hvsc.rb +7 -7
  284. data/lib/badline/{storage → sid_tune}/song_lengths.rb +2 -2
  285. data/lib/badline/{storage → sid_tune}/stil/credit.rb +1 -1
  286. data/lib/badline/{storage → sid_tune}/stil.rb +3 -3
  287. data/lib/badline/sid_tune.rb +6 -0
  288. data/lib/badline/snapshot/c128_setup.rb +43 -0
  289. data/lib/badline/snapshot/c64_setup.rb +79 -0
  290. data/lib/badline/snapshot/image.rb +5 -25
  291. data/lib/badline/snapshot/machine_state.rb +10 -2
  292. data/lib/badline/snapshot/setup.rb +22 -66
  293. data/lib/badline/snapshot/state.rb +8 -17
  294. data/lib/badline/snapshot/storage_setup.rb +68 -0
  295. data/lib/badline/snapshot/vic20_setup.rb +37 -0
  296. data/lib/badline/snapshot/vice/c64_mem.rb +1 -1
  297. data/lib/badline/snapshot/vice/restore.rb +1 -1
  298. data/lib/badline/snapshot/vice/reu1764.rb +1 -1
  299. data/lib/badline/snapshot/vice/reu_fields.rb +40 -0
  300. data/lib/badline/snapshot/vice.rb +7 -5
  301. data/lib/badline/snapshot.rb +13 -12
  302. data/lib/badline/storage/d64_image.rb +15 -9
  303. data/lib/badline/storage/d71_image.rb +0 -2
  304. data/lib/badline/storage/d81_image.rb +0 -2
  305. data/lib/badline/storage/disk_image/writing.rb +2 -2
  306. data/lib/badline/storage/disk_image.rb +3 -6
  307. data/lib/badline/storage/g64_image.rb +2 -2
  308. data/lib/badline/storage/host_directory.rb +0 -5
  309. data/lib/badline/storage/t64.rb +2 -8
  310. data/lib/badline/storage/unavailable.rb +1 -1
  311. data/lib/badline/storage.rb +0 -37
  312. data/lib/badline/support/c128_checkpoint.rb +39 -0
  313. data/lib/badline/support/checkpoint.rb +108 -0
  314. data/lib/badline/support/vic20_checkpoint.rb +38 -0
  315. data/lib/badline/support.rb +5 -0
  316. data/lib/badline/version.rb +1 -1
  317. data/lib/badline/vic20/attachments.rb +11 -81
  318. data/lib/badline/vic20/bus/saved_state.rb +35 -0
  319. data/lib/badline/vic20/bus.rb +3 -25
  320. data/lib/badline/vic20/cpu.rb +1 -1
  321. data/lib/badline/vic20/port_wiring.rb +4 -4
  322. data/lib/badline/vic20/saved_state.rb +16 -60
  323. data/lib/badline/vic20/user_via_ports.rb +2 -2
  324. data/lib/badline/vic20.rb +20 -51
  325. metadata +250 -221
  326. data/lib/badline/address_bus/extra_sids.rb +0 -30
  327. data/lib/badline/address_bus/fittings.rb +0 -38
  328. data/lib/badline/address_bus/pla.rb +0 -147
  329. data/lib/badline/address_bus/roms.rb +0 -39
  330. data/lib/badline/address_bus/saved_state.rb +0 -72
  331. data/lib/badline/address_bus/sid_slots.rb +0 -42
  332. data/lib/badline/address_bus.rb +0 -235
  333. data/lib/badline/cartridge/action_replay.rb +0 -126
  334. data/lib/badline/cartridge/atomic_power.rb +0 -24
  335. data/lib/badline/cartridge/bank.rb +0 -81
  336. data/lib/badline/cartridge/comal80.rb +0 -50
  337. data/lib/badline/cartridge/dinamic.rb +0 -34
  338. data/lib/badline/cartridge/easy_flash.rb +0 -145
  339. data/lib/badline/cartridge/epyx_fastload.rb +0 -79
  340. data/lib/badline/cartridge/final_cartridge3.rb +0 -89
  341. data/lib/badline/cartridge/flash.rb +0 -306
  342. data/lib/badline/cartridge/freezer.rb +0 -33
  343. data/lib/badline/cartridge/fun_play.rb +0 -38
  344. data/lib/badline/cartridge/g_mod2.rb +0 -74
  345. data/lib/badline/cartridge/game_system.rb +0 -40
  346. data/lib/badline/cartridge/geo_ram.rb +0 -79
  347. data/lib/badline/cartridge/kcs_power.rb +0 -75
  348. data/lib/badline/cartridge/mach5.rb +0 -32
  349. data/lib/badline/cartridge/magic_desk.rb +0 -30
  350. data/lib/badline/cartridge/ocean.rb +0 -35
  351. data/lib/badline/cartridge/pagefox.rb +0 -68
  352. data/lib/badline/cartridge/retro_replay.rb +0 -320
  353. data/lib/badline/cartridge/rex_utility.rb +0 -29
  354. data/lib/badline/cartridge/rgcd.rb +0 -58
  355. data/lib/badline/cartridge/simons_basic.rb +0 -35
  356. data/lib/badline/cartridge/standard.rb +0 -15
  357. data/lib/badline/cartridge/super_games.rb +0 -48
  358. data/lib/badline/cartridge/westermann.rb +0 -30
  359. data/lib/badline/cartridge/zaxxon.rb +0 -66
  360. data/lib/badline/cartridge.rb +0 -303
  361. data/lib/badline/checkpoint.rb +0 -98
  362. data/lib/badline/cia/fast_forward.rb +0 -60
  363. data/lib/badline/cia/interrupt_register.rb +0 -143
  364. data/lib/badline/cia/serial.rb +0 -275
  365. data/lib/badline/cia/state.rb +0 -47
  366. data/lib/badline/cia/timer.rb +0 -206
  367. data/lib/badline/cia.rb +0 -279
  368. data/lib/badline/color_memory.rb +0 -25
  369. data/lib/badline/computer/kernal_traps.rb +0 -29
  370. data/lib/badline/control_ports.rb +0 -76
  371. data/lib/badline/cpu/addressing.rb +0 -131
  372. data/lib/badline/cpu/boundary.rb +0 -54
  373. data/lib/badline/cpu/core.rb +0 -165
  374. data/lib/badline/cpu/microcode.rb +0 -177
  375. data/lib/badline/cpu/operations.rb +0 -88
  376. data/lib/badline/cpu/saved_state.rb +0 -115
  377. data/lib/badline/cpu/stack_operations.rb +0 -82
  378. data/lib/badline/cpu.rb +0 -10
  379. data/lib/badline/cycleable.rb +0 -38
  380. data/lib/badline/datasette.rb +0 -161
  381. data/lib/badline/drive/core.rb +0 -147
  382. data/lib/badline/drive/fast_serial.rb +0 -73
  383. data/lib/badline/drive/idle.rb +0 -125
  384. data/lib/badline/drive/idle_cpu.rb +0 -28
  385. data/lib/badline/drive/orbit.rb +0 -79
  386. data/lib/badline/drive/serial_lines.rb +0 -73
  387. data/lib/badline/drive/sleep.rb +0 -112
  388. data/lib/badline/drive/vias.rb +0 -84
  389. data/lib/badline/drive/watch.rb +0 -150
  390. data/lib/badline/drive.rb +0 -11
  391. data/lib/badline/drive1541/bus.rb +0 -86
  392. data/lib/badline/drive1541/byte_ready.rb +0 -48
  393. data/lib/badline/drive1541/cpu.rb +0 -11
  394. data/lib/badline/drive1541/disk.rb +0 -318
  395. data/lib/badline/drive1541/disk_state.rb +0 -94
  396. data/lib/badline/drive1541/disk_via.rb +0 -36
  397. data/lib/badline/drive1541/gcr.rb +0 -57
  398. data/lib/badline/drive1541/mechanism.rb +0 -313
  399. data/lib/badline/drive1541/mechanism_state.rb +0 -68
  400. data/lib/badline/drive1541/rotation.rb +0 -121
  401. data/lib/badline/drive1541/sector_reader.rb +0 -76
  402. data/lib/badline/drive1541/serial_port.rb +0 -18
  403. data/lib/badline/drive1541/track.rb +0 -98
  404. data/lib/badline/drive1541.rb +0 -111
  405. data/lib/badline/drive1571/bus.rb +0 -111
  406. data/lib/badline/drive1571/cpu.rb +0 -11
  407. data/lib/badline/drive1571/serial_port.rb +0 -37
  408. data/lib/badline/drive1571/serial_via.rb +0 -25
  409. data/lib/badline/drive1571/wd1770.rb +0 -120
  410. data/lib/badline/drive1571.rb +0 -175
  411. data/lib/badline/drive1581/bus.rb +0 -137
  412. data/lib/badline/drive1581/cpu.rb +0 -11
  413. data/lib/badline/drive1581/disk.rb +0 -135
  414. data/lib/badline/drive1581/disk_state.rb +0 -87
  415. data/lib/badline/drive1581/mechanism.rb +0 -117
  416. data/lib/badline/drive1581/serial_port.rb +0 -52
  417. data/lib/badline/drive1581/slot.rb +0 -78
  418. data/lib/badline/drive1581/track.rb +0 -100
  419. data/lib/badline/drive1581/track_bytes.rb +0 -75
  420. data/lib/badline/drive1581/wd1772/registers.rb +0 -89
  421. data/lib/badline/drive1581/wd1772/sector_writes.rb +0 -73
  422. data/lib/badline/drive1581/wd1772/sectors.rb +0 -150
  423. data/lib/badline/drive1581/wd1772/state.rb +0 -66
  424. data/lib/badline/drive1581/wd1772/stepping.rb +0 -109
  425. data/lib/badline/drive1581/wd1772/tracks.rb +0 -125
  426. data/lib/badline/drive1581/wd1772/turn.rb +0 -73
  427. data/lib/badline/drive1581/wd1772.rb +0 -216
  428. data/lib/badline/drive1581.rb +0 -233
  429. data/lib/badline/iec_bus.rb +0 -159
  430. data/lib/badline/instruction.rb +0 -334
  431. data/lib/badline/instruction_set/arithmetic.rb +0 -114
  432. data/lib/badline/instruction_set/bitwise.rb +0 -126
  433. data/lib/badline/instruction_set/branch.rb +0 -79
  434. data/lib/badline/instruction_set/flag.rb +0 -63
  435. data/lib/badline/instruction_set/illegal.rb +0 -270
  436. data/lib/badline/instruction_set/inc_dec.rb +0 -69
  437. data/lib/badline/instruction_set/stack.rb +0 -52
  438. data/lib/badline/instruction_set/transfer.rb +0 -137
  439. data/lib/badline/instruction_set.rb +0 -55
  440. data/lib/badline/interrupts.rb +0 -104
  441. data/lib/badline/joystick.rb +0 -25
  442. data/lib/badline/kernal_trap/channel.rb +0 -181
  443. data/lib/badline/keyboard.rb +0 -112
  444. data/lib/badline/ram_expansion/banking.rb +0 -30
  445. data/lib/badline/ram_expansion/plus256k.rb +0 -54
  446. data/lib/badline/ram_expansion/plus60k.rb +0 -43
  447. data/lib/badline/ram_expansion/unexpanded.rb +0 -28
  448. data/lib/badline/ram_expansion.rb +0 -21
  449. data/lib/badline/reu/dma/saved_state.rb +0 -50
  450. data/lib/badline/reu/dma.rb +0 -273
  451. data/lib/badline/reu/ram.rb +0 -107
  452. data/lib/badline/reu/saved_state.rb +0 -80
  453. data/lib/badline/reu/trigger.rb +0 -32
  454. data/lib/badline/reu.rb +0 -289
  455. data/lib/badline/sid/catch_up.rb +0 -120
  456. data/lib/badline/sid/decimator.rb +0 -64
  457. data/lib/badline/sid/envelope/state.rb +0 -68
  458. data/lib/badline/sid/envelope.rb +0 -239
  459. data/lib/badline/sid/filter.rb +0 -263
  460. data/lib/badline/sid/voice.rb +0 -77
  461. data/lib/badline/sid/waveform/combined.rb +0 -126
  462. data/lib/badline/sid/waveform/fast_forward.rb +0 -105
  463. data/lib/badline/sid/waveform/noise_writeback.rb +0 -122
  464. data/lib/badline/sid/waveform/state.rb +0 -66
  465. data/lib/badline/sid/waveform.rb +0 -305
  466. data/lib/badline/sid.rb +0 -303
  467. data/lib/badline/time_of_day.rb +0 -228
  468. data/lib/badline/traps.rb +0 -19
  469. data/lib/badline/via/control_lines.rb +0 -122
  470. data/lib/badline/via/fast_forward.rb +0 -53
  471. data/lib/badline/via/interrupt_register.rb +0 -67
  472. data/lib/badline/via/shift_register.rb +0 -180
  473. data/lib/badline/via/state.rb +0 -42
  474. data/lib/badline/via/timer1.rb +0 -131
  475. data/lib/badline/via/timer2.rb +0 -133
  476. data/lib/badline/via.rb +0 -266
  477. data/lib/badline/vic/bank.rb +0 -133
  478. data/lib/badline/vic/border_mask.rb +0 -86
  479. data/lib/badline/vic/collisions.rb +0 -115
  480. data/lib/badline/vic/color_patches.rb +0 -47
  481. data/lib/badline/vic/display_state.rb +0 -185
  482. data/lib/badline/vic/graphics_mode.rb +0 -164
  483. data/lib/badline/vic/graphics_shifter.rb +0 -207
  484. data/lib/badline/vic/register_log.rb +0 -81
  485. data/lib/badline/vic/registers.rb +0 -195
  486. data/lib/badline/vic/sequencer.rb +0 -275
  487. data/lib/badline/vic/sequencer_output.rb +0 -116
  488. data/lib/badline/vic/sequencer_state.rb +0 -89
  489. data/lib/badline/vic/sprite/internal_bus.rb +0 -68
  490. data/lib/badline/vic/sprite/saved_state.rb +0 -64
  491. data/lib/badline/vic/sprite/shifter.rb +0 -146
  492. data/lib/badline/vic/sprite/timing.rb +0 -56
  493. data/lib/badline/vic/sprite.rb +0 -337
  494. data/lib/badline/vic/sprites.rb +0 -282
  495. data/lib/badline/vic/sprites_state.rb +0 -57
  496. data/lib/badline/vic.rb +0 -852
  497. data/lib/badline/vic20/sound/output.rb +0 -83
  498. data/lib/badline/vic20/sound.rb +0 -233
  499. data/lib/badline/z80/arithmetic.rb +0 -117
  500. data/lib/badline/z80/bit_page.rb +0 -55
  501. data/lib/badline/z80/block_io.rb +0 -58
  502. data/lib/badline/z80/block_transfers.rb +0 -59
  503. data/lib/badline/z80/bus_cycles.rb +0 -111
  504. data/lib/badline/z80/core.rb +0 -113
  505. data/lib/badline/z80/exchanges.rb +0 -50
  506. data/lib/badline/z80/extended_page.rb +0 -89
  507. data/lib/badline/z80/flags.rb +0 -37
  508. data/lib/badline/z80/interrupt_acceptance.rb +0 -46
  509. data/lib/badline/z80/jumps.rb +0 -82
  510. data/lib/badline/z80/loads.rb +0 -98
  511. data/lib/badline/z80/main_page.rb +0 -134
  512. data/lib/badline/z80/registers.rb +0 -120
  513. data/lib/badline/z80/saved_state.rb +0 -69
  514. data/lib/badline/z80/shifts.rb +0 -64
  515. data/lib/badline/z80.rb +0 -11
  516. /data/lib/badline/snapshot/{fields.rb → vice/fields.rb} +0 -0
@@ -1,26 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "badline/snapshot/c128_setup"
4
+
3
5
  module Badline
4
6
  class C128
5
- MARKER = "C128"
6
-
7
- # The model, the SID and the mode it resets into of the machine a State
8
- # from #snapshot was taken of, the arguments C128.new takes.
9
- def self.setup(state)
10
- input = Snapshot::StateReader.new(state)
11
- input.marker(MARKER)
12
- input.check_stamp
13
- SavedState.read_setup(input)
14
- end
7
+ # How the machine a State from #snapshot was taken of was built.
8
+ def self.setup(state) = Snapshot::C128Setup.from(state)
15
9
 
16
10
  # A new machine, built as the one a State from #snapshot was taken of,
17
11
  # at that state.
18
- def self.restored(state)
19
- setup = setup(state)
20
- new(model: setup[0], sid_model: setup[1], mode: setup[2]).apply_state(state)
21
- end
12
+ def self.restored(state) = setup(state).build.apply_state(state)
22
13
 
23
- # The whole machine's state for a snapshot, as Computer's: the
14
+ # The whole machine's state for a snapshot, as C64's: the
24
15
  # machine's own latches, FAST and TEST as they last took hold, the bus with its RAM, the MMU, the chips and
25
16
  # the VDC, the CPU, the cartridge, the disk device 8 serves through the
26
17
  # traps and a true 1541. The serial lines go back into the bus from the
@@ -28,21 +19,6 @@ module Badline
28
19
  # joysticks, CAPS LOCK and 40/80 DISPLAY, the traps and callbacks, and
29
20
  # which chip renders.
30
21
  module SavedState
31
- SID_MODELS = %i[mos6581 mos8580].freeze
32
- MODES = %i[c64 c128].freeze
33
-
34
- # The model's name, the SID's model and the mode.
35
- def self.read_setup(input)
36
- name = input.string
37
- known = Model::ALL.any? { |model| model.name == name }
38
- raise Snapshot::FormatError, "the state names a C128 model badline doesn't know" unless known
39
-
40
- sid_model = SID_MODELS.fetch(input.int)
41
- [name, sid_model, MODES.fetch(input.int)]
42
- rescue IndexError
43
- raise Snapshot::FormatError, "the state names a SID or a mode badline doesn't know"
44
- end
45
-
46
22
  # How many more on_init handlers the machine a State was taken of had
47
23
  # yet to run than this one has. Nil until the machine is restored.
48
24
  attr_reader :init_handlers_lost
@@ -72,8 +48,8 @@ module Badline
72
48
  end
73
49
 
74
50
  def save_state(out)
75
- out.marker(MARKER).stamp
76
- out.string(@model.name).int(SID_MODELS.index(@sid.model)).int(@c64_built ? 0 : 1)
51
+ out.marker(Snapshot::C128Setup::MARKER).stamp
52
+ snapshot_setup.write(out)
77
53
  out.int(@cycles).int(@clock_bits).boolean(@nmi_asserted).boolean(@cartridge_nmi).boolean(@restore_pulse)
78
54
  out.boolean(!@pending_keys.nil?)
79
55
  out.ints(@pending_keys) if @pending_keys
@@ -83,14 +59,14 @@ module Badline
83
59
  @cpu.save_state(out)
84
60
  @z80.save_state(out)
85
61
  out.int(@z80_due).int(@chips_ahead).boolean(@cpu_reset_pending)
86
- save_trap_drive(out)
62
+ save_trap_dos(out)
87
63
  save_serial_bus(out)
88
64
  end
89
65
 
90
66
  def load_state(input)
91
- input.marker(MARKER)
67
+ input.marker(Snapshot::C128Setup::MARKER)
92
68
  input.check_stamp
93
- check_setup(SavedState.read_setup(input))
69
+ check_setup(Snapshot::C128Setup.read(input))
94
70
  @cycles = input.int
95
71
  @clock_bits = input.int
96
72
  @nmi_asserted = input.boolean?
@@ -105,24 +81,17 @@ module Badline
105
81
  push_serial_lines
106
82
  @cpu.load_state(input)
107
83
  load_z80(input)
108
- load_trap_drive(input)
84
+ load_trap_dos(input)
109
85
  load_serial_bus(input)
110
86
  push_fast_serial
111
87
  end
112
88
 
113
89
  private
114
90
 
115
- # The Z80 and which CPU has the bus, which a state from before the
116
- # Z80 leaves to the 8502. The bus, restored before it, hands the bus
117
- # to its CPU without resetting the 8502.
91
+ # The Z80 and which CPU has the bus. The bus, restored before it,
92
+ # hands the bus to its CPU without resetting the 8502.
118
93
  def load_z80(input)
119
94
  @z80_running = @bus.z80?
120
- @z80_turn = @z80_running
121
- @z80_due = @z80.cycles
122
- @chips_ahead = 0
123
- @cpu_reset_pending = false
124
- return unless input.schema > 6
125
-
126
95
  @z80.load_state(input)
127
96
  @z80_due = input.int
128
97
  @chips_ahead = input.int
@@ -130,11 +99,16 @@ module Badline
130
99
  @z80_turn = @z80_running || @chips_ahead.positive?
131
100
  end
132
101
 
102
+ # How this machine was built.
103
+ def snapshot_setup
104
+ Snapshot::C128Setup.new(model: @model.name, sid_model: @sid.model, mode: @c64_built ? :c64 : :c128)
105
+ end
106
+
133
107
  def check_setup(setup)
134
- ours = [@model.name, @sid.model, @c64_built ? :c64 : :c128]
108
+ ours = snapshot_setup
135
109
  return if setup == ours
136
110
 
137
- raise Snapshot::FormatError, "the state is of a #{setup.join(' with a ')}, not a #{ours.join(' with a ')}"
111
+ raise Snapshot::FormatError, "the state is of a #{setup}, not a #{ours}"
138
112
  end
139
113
  end
140
114
 
@@ -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
data/lib/badline/c128.rb CHANGED
@@ -2,13 +2,13 @@
2
2
 
3
3
  require "badline/c128/model"
4
4
  require "badline/c128/mmu"
5
- require "badline/c128/vdc"
5
+ require "badline/chips/vdc"
6
6
  require "badline/c128/mmu_pages"
7
7
  require "badline/c128/io_pages"
8
8
  require "badline/c128/z80_pages"
9
9
  require "badline/c128/color_lines"
10
10
  require "badline/c128/banks"
11
- require "badline/c128/bus_state"
11
+ require "badline/c128/bus/saved_state"
12
12
  require "badline/c128/bus"
13
13
  require "badline/c128/cpu"
14
14
  require "badline/c128/z80"
@@ -18,7 +18,7 @@ require "badline/c128/keys"
18
18
  require "badline/c128/modes"
19
19
  require "badline/c128/drives"
20
20
  require "badline/c128/fast_serial"
21
- require "badline/drive1571"
21
+ require "badline/drives/model1571"
22
22
 
23
23
  module Badline
24
24
  # The Commodore 128: the 8502 on the VIC-IIe's clock, two CIAs, the SID,
@@ -44,8 +44,10 @@ module Badline
44
44
  class C128
45
45
  include IntegerHelper
46
46
  include KeyboardBuffer
47
- include Computer::Attachments
48
- include Computer::KernalTraps
47
+ include Machine::Clocking
48
+ include C64::Common
49
+ include C64::Attachments
50
+ include C64::KernalTraps
49
51
  include Keys
50
52
  include Modes
51
53
  include Drives
@@ -54,7 +56,7 @@ module Badline
54
56
 
55
57
  # The C64's 8x8 matrix and the three rows K0-K2 select, in port B
56
58
  # column order.
57
- KEYBOARD_MATRIX = (Keyboard::C64_MATRIX + [
59
+ KEYBOARD_MATRIX = (Input::Keyboard::C64_MATRIX + [
58
60
  %i[help keypad8 keypad5 tab keypad2 keypad4 keypad7 keypad1],
59
61
  %i[esc keypad_plus keypad_minus line_feed keypad_enter keypad6 keypad9 keypad3],
60
62
  %i[alt keypad0 keypad_period crsr_up crsr_down crsr_left crsr_right no_scroll]
@@ -71,10 +73,6 @@ module Badline
71
73
 
72
74
  attr_reader :cpu, :cycles, :drive1541, :model, :init_threshold
73
75
 
74
- # The path of the disk or directory device 8 serves through the traps
75
- # (Computer::Attachments), or an empty one.
76
- def mounted_path = @drive.nil? ? "" : @drive.path
77
-
78
76
  def family = :c128
79
77
 
80
78
  def address_bus = @bus
@@ -95,6 +93,11 @@ module Badline
95
93
 
96
94
  def ram = @bus.ram
97
95
 
96
+ # Reads and writes memory as the CPU sees it, through the bus.
97
+ def peek(addr) = @bus.peek(addr)
98
+
99
+ def poke(addr, value) = @bus.poke(addr, value)
100
+
98
101
  def keyboard = @bus.keyboard
99
102
 
100
103
  def joystick1 = @bus.joystick1
@@ -118,7 +121,7 @@ module Badline
118
121
 
119
122
  @model = Model.named(model)
120
123
  @c64_built = mode == :c64
121
- @init_threshold = @c64_built ? Computer::INIT_THRESHOLD : C128_INIT_THRESHOLD
124
+ @init_threshold = @c64_built ? C64::INIT_THRESHOLD : C128_INIT_THRESHOLD
122
125
  @holding_commodore = false
123
126
  @bus = Bus.new(@model, sid_model: sid_model || @model.sid_model, mode:)
124
127
  @cpu = CPU.new(@bus, debug:)
@@ -173,36 +176,6 @@ module Badline
173
176
  @cycles += 1
174
177
  end
175
178
 
176
- # Runs `count` cycles, one #cycle! after another.
177
- def run_cycles(count)
178
- i = 0
179
- while i < count
180
- cycle!
181
- i += 1
182
- end
183
- end
184
-
185
- # Runs cycles until the block returns true or the cycle count passes
186
- # `limit`, checking before each cycle.
187
- def run_until(limit)
188
- cycle! until yield || @cycles > limit
189
- end
190
-
191
- def on_init(&block)
192
- if @cycles < init_threshold
193
- @init_handlers << block
194
- else
195
- block.call
196
- end
197
- end
198
-
199
- # The clock, the raster and the crop of the VIC-IIe's region.
200
- def timing
201
- region = @bus.region
202
- Timing.new(clock_hz: region.clock_hz, cycles_per_line: region.cycles_per_line,
203
- lines_per_frame: region.lines_per_frame, crop: region.crop, pixel_width: 1)
204
- end
205
-
206
179
  # The chip whose #display a front end shows: the VIC-IIe, or with
207
180
  # :vdc the VDC, whose display paints only while its #render is on.
208
181
  def video(chip = :vic) = chip == :vdc ? @vdc : @vic
@@ -217,12 +190,6 @@ module Badline
217
190
  # The chip a front end records the machine's sound from.
218
191
  def sound_source = @sid
219
192
 
220
- def load_prg(data)
221
- uint16(data[0], data[1]).tap do |load_addr|
222
- ram.write(load_addr, data[2..])
223
- end
224
- end
225
-
226
193
  # A cartridge goes in with the power off.
227
194
  def attach_cartridge(cartridge)
228
195
  connect_cartridge(cartridge)
@@ -247,7 +214,7 @@ module Badline
247
214
  @cia2.reset!
248
215
  @sid.reset!
249
216
  @bus.cartridge&.reset
250
- @drive&.reset!
217
+ @dos&.reset!
251
218
  @drive1541&.reset!
252
219
  @drive1571&.reset!
253
220
  @drive1581&.reset!
@@ -255,19 +222,11 @@ module Badline
255
222
  reset_z80
256
223
  end
257
224
 
258
- # CHROUT is at $FFD2 in both KERNALs, and the trap follows the mode.
259
- def capture_output
260
- @capture_output ||= ChroutTrap.new(cpu:, bus: @bus, layout: trap_layout).tap do |trap|
261
- cpu.install_trap(ChroutTrap::ADDRESS) { trap.call }
262
- end
263
- end
264
-
265
- def inspect
266
- "#<#{self.class.name} cycles=#{@cycles} cpu=(#{@cpu.inspect})>"
267
- end
268
-
269
225
  private
270
226
 
227
+ # The bus the KERNAL traps read and write through.
228
+ def trap_bus = @bus
229
+
271
230
  # The C128 KERNAL leaves $D02F at $FF, every extra keyboard row
272
231
  # deselected, before it jumps to the C64's reset.
273
232
  def enter_c64_mode
@@ -275,15 +234,6 @@ module Badline
275
234
  @bus.control_ports.extra_rows = 0xff
276
235
  end
277
236
 
278
- # The NMI line is wired-OR between CIA 2, the cartridge and RESTORE,
279
- # and the CPU takes an interrupt on its falling edge.
280
- def drive_nmi
281
- nmi = @cia2.interrupted? || @cartridge_nmi || @restore_pulse
282
- @restore_pulse = false
283
- @cpu.nmi = true if nmi && !@nmi_asserted
284
- @nmi_asserted = nmi
285
- end
286
-
287
237
  # BA halts the CPU on a read cycle.
288
238
  def clock_cpu
289
239
  @cpu.pending_write? || !@vic.ba_low? ? @cpu.cycle! : @cpu.stall!
@@ -311,9 +261,5 @@ module Badline
311
261
  @cpu.cycle!
312
262
  @vic.take_cpu_bus(phi1, @bus.data, @bus.vic_access?)
313
263
  end
314
-
315
- def handle_init
316
- @init_handlers.each(&:call)
317
- end
318
264
  end
319
265
  end
@@ -1,10 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Badline
4
- class Computer
5
- # What plugs into the machine besides its chips, the cartridge, the
6
- # disk device 8 serves through the traps, its true drives (TrueDrives)
7
- # and an REU, and their state for a snapshot.
4
+ class C64
5
+ # What plugs into the machine besides its chips, the cartridge, its
6
+ # true drives (TrueDrives) and an REU, and their state for a snapshot.
7
+ # The disk device 8 serves through the traps is KernalTraps'.
8
8
  module Attachments
9
9
  include TrueDrives
10
10
 
@@ -17,30 +17,6 @@ module Badline
17
17
  address_bus.attach_cartridge(cartridge)
18
18
  end
19
19
 
20
- # Puts the storage in device 8. Mounting again swaps the disk at any
21
- # point while the machine runs: the drive keeps its RAM, which only a
22
- # drive reset clears, and its status. The traps go on the KERNAL the
23
- # machine runs (#trap_layout).
24
- def mount(storage)
25
- return @drive.insert(storage) if @drive
26
-
27
- @drive = KernalTrap::Drive.new(storage)
28
- install_kernal_traps(trap_layout)
29
- end
30
-
31
- # Takes device 8's mounted storage out, and with it the LOAD, SAVE and
32
- # serial traps, so the KERNAL's routines go out over the serial bus.
33
- # Mounting again starts a new drive, with its RAM cleared.
34
- def unmount
35
- return unless @drive
36
-
37
- remove_kernal_traps
38
- @drive = nil
39
- end
40
-
41
- # Whether device 8 serves a disk or directory through the traps.
42
- def mounted? = !@drive.nil?
43
-
44
20
  # The serial bus, which CIA 2's port A drives through the C64's own
45
21
  # inverters and reads back on PA6 and PA7, with or without a drive on
46
22
  # it.
@@ -51,7 +27,7 @@ module Badline
51
27
  # CIA 2's port A drives the serial bus, which reads CLK and DATA back
52
28
  # into it.
53
29
  def plug_serial_bus
54
- @iec_bus = IECBus.new
30
+ @iec_bus = Drives::SerialBus.new
55
31
  @cia2.peripheral = @iec_bus
56
32
  @cia2.on_port_a_write { push_serial_lines }
57
33
  push_serial_lines
@@ -78,26 +54,19 @@ module Badline
78
54
  end
79
55
  end
80
56
 
81
- # The disk device 8 serves through the traps, with the traps' own
82
- # state: open channels, the drive's status and RAM, a SAVE under way.
83
- def save_trap_drive(out)
84
- out.boolean(!@drive.nil?)
85
- return unless @drive
86
-
87
- @drive.save_state(out)
88
- @serial_trap.save_state(out)
89
- @save_trap.save_state(out)
57
+ # A true 1541 on the serial bus, then a 1581.
58
+ def save_serial_bus(out)
59
+ out.boolean(!@drive1541.nil?)
60
+ if @drive1541
61
+ out.int(@drive1541.device)
62
+ @drive1541.save_state(out)
63
+ end
64
+ save_drive1581(out)
90
65
  end
91
66
 
92
- def load_trap_drive(input)
93
- return unmount unless input.boolean?
94
-
95
- storage = Storage.reopen(input)
96
- unmount
97
- mount(storage)
98
- @drive.load_state(input)
99
- @serial_trap.load_state(input)
100
- @save_trap.load_state(input)
67
+ def load_serial_bus(input)
68
+ load_drive1541(input)
69
+ load_drive1581(input)
101
70
  end
102
71
 
103
72
  # The REU, which the setup says the machine has, and whether it has
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ module BankedRAM
6
+ # The register and page mapping the expansions share. #map lays the
7
+ # selected banks out in the address bus's page tables, and #map_io puts
8
+ # the register over the VIC's I/O page at $D100.
9
+ module Banking
10
+ attr_reader :low_ram, :high_ram, :video_ram
11
+
12
+ # The block runs whenever the register moves a bank.
13
+ def on_change(&block)
14
+ @on_change = block
15
+ end
16
+
17
+ def peek(_addr) = 0xff
18
+
19
+ def map(read_pages, write_pages)
20
+ [read_pages, write_pages].each do |pages|
21
+ pages.fill(@low_ram, 0x00, 0x10)
22
+ pages.fill(@high_ram, 0x10, 0xf0)
23
+ end
24
+ end
25
+
26
+ def map_io(read_pages, write_pages)
27
+ read_pages[0xd1] = write_pages[0xd1] = self
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ module BankedRAM
6
+ # The +256K: four 64K banks, the first of them the machine's own RAM.
7
+ # $D100 picks one for $0000-$0FFF (bits 0-1), one for the VIC (bits 2-3)
8
+ # and one for $1000-$FFFF (bits 6-7). Setting bit 4 locks the register
9
+ # until the next reset.
10
+ class Plus256k
11
+ include Banking
12
+
13
+ def initialize(ram)
14
+ @banks = [ram, Memory.new, Memory.new, Memory.new]
15
+ @on_change = nil
16
+ reset!
17
+ end
18
+
19
+ def poke(_addr, value)
20
+ return if @locked
21
+
22
+ @low_ram = @banks[value & 0b11]
23
+ @video_ram = @banks[(value >> 2) & 0b11]
24
+ @high_ram = @banks[value >> 6]
25
+ @locked = value.anybits?(0x10)
26
+ @on_change&.call
27
+ end
28
+
29
+ def reset!
30
+ @low_ram = @video_ram = @high_ram = @banks[0]
31
+ @locked = false
32
+ end
33
+
34
+ def type = :plus256k
35
+
36
+ def save_state(out)
37
+ [@low_ram, @video_ram, @high_ram].each { |bank| out.int(@banks.index(bank)) }
38
+ out.boolean(@locked)
39
+ @banks.drop(1).each { |bank| bank.save_state(out) }
40
+ end
41
+
42
+ def load_state(input)
43
+ @low_ram = @banks.fetch(input.int)
44
+ @video_ram = @banks.fetch(input.int)
45
+ @high_ram = @banks.fetch(input.int)
46
+ @locked = input.boolean?
47
+ @banks.drop(1).each { |bank| bank.load_state(input) }
48
+ end
49
+
50
+ def power_on!
51
+ @banks.drop(1).each(&:clear!)
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ module BankedRAM
6
+ # The +60K: a second bank of RAM behind $1000-$FFFF, selected by bit 7
7
+ # of $D100. $0000-$0FFF stays the machine's own RAM, and so does all of
8
+ # what the VIC sees.
9
+ class Plus60k
10
+ include Banking
11
+
12
+ def initialize(ram)
13
+ @low_ram = @video_ram = @high_ram = ram
14
+ @banks = [ram, Memory.new]
15
+ @on_change = nil
16
+ end
17
+
18
+ def poke(_addr, value)
19
+ @high_ram = @banks[value >> 7]
20
+ @on_change&.call
21
+ end
22
+
23
+ def reset!
24
+ @high_ram = @banks[0]
25
+ end
26
+
27
+ def type = :plus60k
28
+
29
+ def save_state(out)
30
+ out.int(@banks.index(@high_ram))
31
+ @banks[1].save_state(out)
32
+ end
33
+
34
+ def load_state(input)
35
+ @high_ram = @banks.fetch(input.int)
36
+ @banks[1].load_state(input)
37
+ end
38
+
39
+ def power_on!
40
+ @banks[1].clear!
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ module BankedRAM
6
+ # The machine with no expansion fitted: its own RAM everywhere, and
7
+ # $D100 left to the VIC.
8
+ class Unexpanded
9
+ include Banking
10
+
11
+ def initialize(ram)
12
+ @low_ram = @video_ram = @high_ram = ram
13
+ @on_change = nil
14
+ end
15
+
16
+ def type = nil
17
+
18
+ def map_io(_read_pages, _write_pages); end
19
+
20
+ def save_state(_out); end
21
+
22
+ def load_state(_input); end
23
+
24
+ def reset!; end
25
+
26
+ def power_on!; end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "badline/c64/banked_ram/banking"
4
+ require "badline/c64/banked_ram/unexpanded"
5
+ require "badline/c64/banked_ram/plus60k"
6
+ require "badline/c64/banked_ram/plus256k"
7
+
8
+ module Badline
9
+ class C64
10
+ # RAM expansions that bank extra memory in under the CPU through a
11
+ # register at $D100, in the VIC's I/O page. Any write to $D100-$D1FF
12
+ # sets the register, which reads back as $FF.
13
+ module BankedRAM
14
+ TYPES = { plus60k: Plus60k, plus256k: Plus256k }.freeze
15
+
16
+ def self.build(type, ram, &)
17
+ expansion = type ? TYPES.fetch(type).new(ram) : Unexpanded.new(ram)
18
+ expansion.on_change(&)
19
+ expansion
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,32 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ class Bus
6
+ # The second and third SIDs the SID player fits for a tune written for
7
+ # them, each over its 32 bytes of the I/O area (SIDSlots). The SID
8
+ # player's machine has nothing else in I/O 1 and 2, so the rest of a
9
+ # page there reads the open bus.
10
+ module ExtraSIDs
11
+ # Fits a SID at the address it was built at, where it takes its 32
12
+ # bytes over from whatever maps there.
13
+ def add_sid(sid)
14
+ page = sid.start >> 8
15
+ slots = @sid_slots.find { |candidate| candidate.page == page }
16
+ if slots.nil?
17
+ slots = SIDSlots.new(page, @sid, @open_bus)
18
+ @sid_slots << slots
19
+ end
20
+ slots.place(sid)
21
+ update_overlays!
22
+ end
23
+
24
+ private
25
+
26
+ def map_extra_sids
27
+ @sid_slots.each { |slots| @read_pages[slots.page] = @write_pages[slots.page] = slots }
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,40 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ class Bus
6
+ # What a model fits around the chips: its KERNAL, a datasette or none,
7
+ # and the board and case they sit in.
8
+ module Fittings
9
+ # The keywords #fit takes.
10
+ NAMES = %i[kernal datasette board].freeze
11
+
12
+ # The C64's board and case, the PET 64's, whose built-in monitor
13
+ # shows the VIC's output in shades of green, the C64GS's, which has
14
+ # no keyboard, or the MAX Machine's (:max): 2K of RAM, no ROMs, CIA 1
15
+ # alone at $DC00-$DFFF and the cartridge port in Ultimax mode.
16
+ BOARDS = %i[c64 pet64 gs max].freeze
17
+
18
+ attr_reader :board
19
+
20
+ # Fits the KERNAL ROM ROMs::KERNALS names, leaves the cassette port
21
+ # empty unless `datasette`, and puts the chips in the board BOARDS
22
+ # names.
23
+ def fit(kernal: :c64, datasette: true, board: :c64)
24
+ self.kernal = kernal unless kernal == :c64
25
+ @datasette.disconnect! unless datasette
26
+ self.board = board unless board == :c64
27
+ end
28
+
29
+ def board=(name)
30
+ raise ArgumentError, "no board named #{name}" unless BOARDS.include?(name)
31
+
32
+ @board = name
33
+ vic.palette = name == :pet64 ? Chips::VIC::GREEN_PALETTE : Chips::VIC::PALETTE
34
+ keyboard.connected = name != :gs
35
+ update_overlays!
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end