badline 0.12.1 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (505) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +17 -0
  3. data/CLAUDE.md +59 -31
  4. data/README.md +1 -1
  5. data/doc/library.md +9 -9
  6. data/doc/pinned-behaviour.md +105 -105
  7. data/doc/snapshots.md +1 -4
  8. data/lib/badline/audio/bare_player.rb +3 -3
  9. data/lib/badline/audio/cli.rb +6 -6
  10. data/lib/badline/audio/jukebox.rb +2 -2
  11. data/lib/badline/audio/machine_player.rb +2 -2
  12. data/lib/badline/{media → audio}/queue.rb +1 -1
  13. data/lib/badline/audio/queued_tune.rb +6 -6
  14. data/lib/badline/audio/renderer.rb +5 -5
  15. data/lib/badline/audio/stereo.rb +1 -1
  16. data/lib/badline/c128/{bus_state.rb → bus/saved_state.rb} +1 -1
  17. data/lib/badline/c128/bus.rb +18 -17
  18. data/lib/badline/c128/color_lines.rb +2 -2
  19. data/lib/badline/c128/cpu.rb +1 -1
  20. data/lib/badline/c128/drives.rb +10 -11
  21. data/lib/badline/c128/fast_serial.rb +5 -5
  22. data/lib/badline/c128/mmu_pages.rb +1 -1
  23. data/lib/badline/c128/modes.rb +2 -2
  24. data/lib/badline/c128/saved_state.rb +21 -47
  25. data/lib/badline/c128/z80.rb +2 -2
  26. data/lib/badline/c128.rb +14 -9
  27. data/lib/badline/{computer → c64}/attachments.rb +4 -6
  28. data/lib/badline/c64/banked_ram/banking.rb +32 -0
  29. data/lib/badline/c64/banked_ram/plus256k.rb +56 -0
  30. data/lib/badline/c64/banked_ram/plus60k.rb +45 -0
  31. data/lib/badline/c64/banked_ram/unexpanded.rb +30 -0
  32. data/lib/badline/c64/banked_ram.rb +23 -0
  33. data/lib/badline/c64/bus/extra_sids.rb +32 -0
  34. data/lib/badline/c64/bus/fittings.rb +40 -0
  35. data/lib/badline/c64/bus/pla.rb +149 -0
  36. data/lib/badline/c64/bus/roms.rb +41 -0
  37. data/lib/badline/c64/bus/saved_state.rb +68 -0
  38. data/lib/badline/c64/bus/sid_slots.rb +44 -0
  39. data/lib/badline/c64/bus.rb +218 -0
  40. data/lib/badline/c64/cartridge/action_replay.rb +128 -0
  41. data/lib/badline/c64/cartridge/atomic_power.rb +26 -0
  42. data/lib/badline/c64/cartridge/bank.rb +83 -0
  43. data/lib/badline/c64/cartridge/comal80.rb +52 -0
  44. data/lib/badline/c64/cartridge/dinamic.rb +36 -0
  45. data/lib/badline/c64/cartridge/easy_flash.rb +147 -0
  46. data/lib/badline/c64/cartridge/epyx_fastload.rb +81 -0
  47. data/lib/badline/c64/cartridge/final_cartridge3.rb +91 -0
  48. data/lib/badline/c64/cartridge/flash/saved_state.rb +40 -0
  49. data/lib/badline/c64/cartridge/flash.rb +279 -0
  50. data/lib/badline/c64/cartridge/freezer.rb +35 -0
  51. data/lib/badline/c64/cartridge/fun_play.rb +40 -0
  52. data/lib/badline/c64/cartridge/g_mod2.rb +76 -0
  53. data/lib/badline/c64/cartridge/game_system.rb +42 -0
  54. data/lib/badline/c64/cartridge/geo_ram.rb +81 -0
  55. data/lib/badline/c64/cartridge/kcs_power.rb +77 -0
  56. data/lib/badline/c64/cartridge/mach5.rb +34 -0
  57. data/lib/badline/c64/cartridge/magic_desk.rb +32 -0
  58. data/lib/badline/c64/cartridge/ocean.rb +37 -0
  59. data/lib/badline/c64/cartridge/pagefox.rb +70 -0
  60. data/lib/badline/c64/cartridge/retro_replay/saved_state.rb +47 -0
  61. data/lib/badline/c64/cartridge/retro_replay.rb +286 -0
  62. data/lib/badline/c64/cartridge/rex_utility.rb +31 -0
  63. data/lib/badline/c64/cartridge/rgcd.rb +60 -0
  64. data/lib/badline/c64/cartridge/saved_state.rb +63 -0
  65. data/lib/badline/c64/cartridge/simons_basic.rb +37 -0
  66. data/lib/badline/c64/cartridge/standard.rb +17 -0
  67. data/lib/badline/c64/cartridge/super_games.rb +50 -0
  68. data/lib/badline/c64/cartridge/westermann.rb +32 -0
  69. data/lib/badline/c64/cartridge/zaxxon.rb +68 -0
  70. data/lib/badline/c64/cartridge.rb +258 -0
  71. data/lib/badline/c64/color_memory.rb +27 -0
  72. data/lib/badline/{computer → c64}/common.rb +2 -2
  73. data/lib/badline/{computer → c64}/kernal_traps.rb +18 -18
  74. data/lib/badline/c64/reu/dma/saved_state.rb +52 -0
  75. data/lib/badline/c64/reu/dma.rb +275 -0
  76. data/lib/badline/c64/reu/ram.rb +109 -0
  77. data/lib/badline/c64/reu/saved_state.rb +55 -0
  78. data/lib/badline/c64/reu/trigger.rb +34 -0
  79. data/lib/badline/c64/reu.rb +291 -0
  80. data/lib/badline/{computer → c64}/saved_state.rb +13 -18
  81. data/lib/badline/{computer → c64}/true_drives.rb +11 -11
  82. data/lib/badline/{computer.rb → c64.rb} +18 -13
  83. data/lib/badline/chips/cia/fast_forward.rb +62 -0
  84. data/lib/badline/chips/cia/interrupt_register.rb +145 -0
  85. data/lib/badline/chips/cia/saved_state.rb +49 -0
  86. data/lib/badline/chips/cia/serial/saved_state.rb +45 -0
  87. data/lib/badline/chips/cia/serial.rb +250 -0
  88. data/lib/badline/chips/cia/time_of_day.rb +232 -0
  89. data/lib/badline/chips/cia/timer.rb +208 -0
  90. data/lib/badline/chips/cia.rb +281 -0
  91. data/lib/badline/chips/cpu/addressing.rb +133 -0
  92. data/lib/badline/chips/cpu/boundary.rb +56 -0
  93. data/lib/badline/chips/cpu/core.rb +167 -0
  94. data/lib/badline/chips/cpu/instruction.rb +338 -0
  95. data/lib/badline/chips/cpu/instruction_set/arithmetic.rb +118 -0
  96. data/lib/badline/chips/cpu/instruction_set/bitwise.rb +130 -0
  97. data/lib/badline/chips/cpu/instruction_set/branch.rb +83 -0
  98. data/lib/badline/chips/cpu/instruction_set/flag.rb +67 -0
  99. data/lib/badline/chips/cpu/instruction_set/illegal.rb +274 -0
  100. data/lib/badline/chips/cpu/instruction_set/inc_dec.rb +73 -0
  101. data/lib/badline/chips/cpu/instruction_set/stack.rb +56 -0
  102. data/lib/badline/chips/cpu/instruction_set/transfer.rb +141 -0
  103. data/lib/badline/chips/cpu/instruction_set.rb +59 -0
  104. data/lib/badline/chips/cpu/interrupts.rb +108 -0
  105. data/lib/badline/chips/cpu/microcode.rb +179 -0
  106. data/lib/badline/chips/cpu/operations.rb +90 -0
  107. data/lib/badline/chips/cpu/port.rb +116 -0
  108. data/lib/badline/chips/cpu/saved_state.rb +117 -0
  109. data/lib/badline/chips/cpu/stack_operations.rb +84 -0
  110. data/lib/badline/chips/cpu/traps.rb +23 -0
  111. data/lib/badline/chips/cpu.rb +12 -0
  112. data/lib/badline/chips/sid/catch_up.rb +122 -0
  113. data/lib/badline/chips/sid/decimator.rb +66 -0
  114. data/lib/badline/chips/sid/envelope/saved_state.rb +70 -0
  115. data/lib/badline/chips/sid/envelope.rb +241 -0
  116. data/lib/badline/chips/sid/filter/saved_state.rb +42 -0
  117. data/lib/badline/chips/sid/filter.rb +241 -0
  118. data/lib/badline/chips/sid/saved_state.rb +52 -0
  119. data/lib/badline/chips/sid/voice.rb +79 -0
  120. data/lib/badline/chips/sid/waveform/combined.rb +128 -0
  121. data/lib/badline/chips/sid/waveform/fast_forward.rb +107 -0
  122. data/lib/badline/chips/sid/waveform/noise_writeback.rb +124 -0
  123. data/lib/badline/chips/sid/waveform/saved_state.rb +68 -0
  124. data/lib/badline/chips/sid/waveform.rb +307 -0
  125. data/lib/badline/chips/sid.rb +265 -0
  126. data/lib/badline/{c128 → chips}/vdc/memory.rb +1 -1
  127. data/lib/badline/{c128 → chips}/vdc/painter.rb +1 -1
  128. data/lib/badline/{c128 → chips}/vdc/raster.rb +1 -1
  129. data/lib/badline/chips/vdc/saved_state.rb +36 -0
  130. data/lib/badline/{c128 → chips}/vdc/window.rb +1 -1
  131. data/lib/badline/{c128 → chips}/vdc.rb +7 -31
  132. data/lib/badline/chips/via/control_lines.rb +124 -0
  133. data/lib/badline/chips/via/fast_forward.rb +55 -0
  134. data/lib/badline/chips/via/interrupt_register.rb +69 -0
  135. data/lib/badline/chips/via/saved_state.rb +44 -0
  136. data/lib/badline/chips/via/shift_register.rb +182 -0
  137. data/lib/badline/chips/via/timer1.rb +133 -0
  138. data/lib/badline/chips/via/timer2.rb +135 -0
  139. data/lib/badline/chips/via.rb +268 -0
  140. data/lib/badline/chips/vic/bank.rb +135 -0
  141. data/lib/badline/chips/vic/border_mask.rb +88 -0
  142. data/lib/badline/chips/vic/collisions.rb +117 -0
  143. data/lib/badline/chips/vic/color_patches.rb +49 -0
  144. data/lib/badline/chips/vic/display_state.rb +187 -0
  145. data/lib/badline/chips/vic/graphics_mode.rb +166 -0
  146. data/lib/badline/chips/vic/graphics_shifter/saved_state.rb +40 -0
  147. data/lib/badline/chips/vic/graphics_shifter.rb +187 -0
  148. data/lib/badline/chips/vic/register_log.rb +83 -0
  149. data/lib/badline/chips/vic/registers.rb +197 -0
  150. data/lib/badline/chips/vic/saved_state.rb +82 -0
  151. data/lib/badline/chips/vic/sequencer/saved_state.rb +91 -0
  152. data/lib/badline/chips/vic/sequencer.rb +277 -0
  153. data/lib/badline/chips/vic/sequencer_output.rb +118 -0
  154. data/lib/badline/chips/vic/sprite/internal_bus.rb +70 -0
  155. data/lib/badline/chips/vic/sprite/saved_state.rb +66 -0
  156. data/lib/badline/chips/vic/sprite/shifter.rb +148 -0
  157. data/lib/badline/chips/vic/sprite/timing.rb +58 -0
  158. data/lib/badline/chips/vic/sprite.rb +339 -0
  159. data/lib/badline/chips/vic/sprites/saved_state.rb +59 -0
  160. data/lib/badline/chips/vic/sprites.rb +284 -0
  161. data/lib/badline/chips/vic.rb +783 -0
  162. data/lib/badline/chips/vic_i/painter/saved_state.rb +40 -0
  163. data/lib/badline/{vic20/vic → chips/vic_i}/painter.rb +6 -30
  164. data/lib/badline/{vic20/vic → chips/vic_i}/saved_state.rb +2 -2
  165. data/lib/badline/chips/vic_i/sound/output.rb +85 -0
  166. data/lib/badline/chips/vic_i/sound.rb +235 -0
  167. data/lib/badline/{vic20/vic → chips/vic_i}/text_window.rb +2 -2
  168. data/lib/badline/{vic20/vic.rb → chips/vic_i.rb} +5 -5
  169. data/lib/badline/chips/z80/arithmetic.rb +119 -0
  170. data/lib/badline/chips/z80/bit_page.rb +57 -0
  171. data/lib/badline/chips/z80/block_io.rb +60 -0
  172. data/lib/badline/chips/z80/block_transfers.rb +61 -0
  173. data/lib/badline/chips/z80/bus_cycles.rb +113 -0
  174. data/lib/badline/chips/z80/core.rb +115 -0
  175. data/lib/badline/chips/z80/exchanges.rb +52 -0
  176. data/lib/badline/chips/z80/extended_page.rb +91 -0
  177. data/lib/badline/chips/z80/flags.rb +39 -0
  178. data/lib/badline/chips/z80/interrupt_acceptance.rb +48 -0
  179. data/lib/badline/chips/z80/jumps.rb +84 -0
  180. data/lib/badline/chips/z80/loads.rb +100 -0
  181. data/lib/badline/chips/z80/main_page.rb +136 -0
  182. data/lib/badline/chips/z80/registers.rb +122 -0
  183. data/lib/badline/chips/z80/saved_state.rb +71 -0
  184. data/lib/badline/chips/z80/shifts.rb +66 -0
  185. data/lib/badline/chips/z80.rb +13 -0
  186. data/lib/badline/core.rb +26 -28
  187. data/lib/badline/drives/datasette/saved_state.rb +37 -0
  188. data/lib/badline/drives/datasette.rb +140 -0
  189. data/lib/badline/drives/engine/core.rb +149 -0
  190. data/lib/badline/drives/engine/fast_serial.rb +75 -0
  191. data/lib/badline/drives/engine/idle.rb +127 -0
  192. data/lib/badline/drives/engine/idle_cpu.rb +30 -0
  193. data/lib/badline/drives/engine/orbit.rb +81 -0
  194. data/lib/badline/drives/engine/serial_lines.rb +75 -0
  195. data/lib/badline/drives/engine/sleep.rb +114 -0
  196. data/lib/badline/drives/engine/vias.rb +86 -0
  197. data/lib/badline/drives/engine/watch.rb +152 -0
  198. data/lib/badline/drives/engine.rb +11 -0
  199. data/lib/badline/drives/model1541/bus.rb +88 -0
  200. data/lib/badline/drives/model1541/byte_ready.rb +50 -0
  201. data/lib/badline/drives/model1541/cpu.rb +13 -0
  202. data/lib/badline/drives/model1541/disk/saved_state.rb +88 -0
  203. data/lib/badline/drives/model1541/disk.rb +317 -0
  204. data/lib/badline/drives/model1541/disk_via.rb +38 -0
  205. data/lib/badline/drives/model1541/gcr.rb +59 -0
  206. data/lib/badline/drives/model1541/mechanism/saved_state.rb +72 -0
  207. data/lib/badline/drives/model1541/mechanism.rb +315 -0
  208. data/lib/badline/drives/model1541/rotation.rb +123 -0
  209. data/lib/badline/drives/model1541/saved_state.rb +44 -0
  210. data/lib/badline/drives/model1541/sector_reader.rb +78 -0
  211. data/lib/badline/drives/model1541/serial_port.rb +20 -0
  212. data/lib/badline/drives/model1541/track.rb +100 -0
  213. data/lib/badline/drives/model1541.rb +81 -0
  214. data/lib/badline/drives/model1571/bus.rb +113 -0
  215. data/lib/badline/drives/model1571/cpu.rb +13 -0
  216. data/lib/badline/drives/model1571/saved_state.rb +47 -0
  217. data/lib/badline/drives/model1571/serial_port.rb +39 -0
  218. data/lib/badline/drives/model1571/serial_via.rb +27 -0
  219. data/lib/badline/drives/model1571/wd1770.rb +122 -0
  220. data/lib/badline/drives/model1571.rb +142 -0
  221. data/lib/badline/drives/model1581/bus.rb +139 -0
  222. data/lib/badline/drives/model1581/cpu.rb +13 -0
  223. data/lib/badline/drives/model1581/disk/saved_state.rb +89 -0
  224. data/lib/badline/drives/model1581/disk.rb +137 -0
  225. data/lib/badline/drives/model1581/mechanism.rb +119 -0
  226. data/lib/badline/drives/model1581/saved_state.rb +42 -0
  227. data/lib/badline/drives/model1581/serial_port.rb +54 -0
  228. data/lib/badline/drives/model1581/slot.rb +79 -0
  229. data/lib/badline/drives/model1581/track.rb +102 -0
  230. data/lib/badline/drives/model1581/track_bytes.rb +77 -0
  231. data/lib/badline/drives/model1581/wd1772/registers.rb +91 -0
  232. data/lib/badline/drives/model1581/wd1772/saved_state.rb +68 -0
  233. data/lib/badline/drives/model1581/wd1772/sector_writes.rb +75 -0
  234. data/lib/badline/drives/model1581/wd1772/sectors.rb +152 -0
  235. data/lib/badline/drives/model1581/wd1772/stepping.rb +111 -0
  236. data/lib/badline/drives/model1581/wd1772/tracks.rb +127 -0
  237. data/lib/badline/drives/model1581/wd1772/turn.rb +75 -0
  238. data/lib/badline/drives/model1581/wd1772.rb +218 -0
  239. data/lib/badline/drives/model1581.rb +206 -0
  240. data/lib/badline/drives/serial_bus.rb +161 -0
  241. data/lib/badline/frontend/boot.rb +3 -3
  242. data/lib/badline/frontend/machine_window.rb +3 -1
  243. data/lib/badline/frontend/player/filter_view.rb +1 -1
  244. data/lib/badline/frontend/player/player_controller.rb +2 -2
  245. data/lib/badline/frontend/player/player_screen.rb +1 -0
  246. data/lib/badline/frontend/player/theme.rb +7 -7
  247. data/lib/badline/frontend/timeline.rb +3 -3
  248. data/lib/badline/input/control_ports.rb +78 -0
  249. data/lib/badline/input/joystick.rb +27 -0
  250. data/lib/badline/input/keyboard.rb +114 -0
  251. data/lib/badline/input.rb +3 -0
  252. data/lib/badline/kernal_trap/{drive → dos}/block_commands.rb +1 -1
  253. data/lib/badline/kernal_trap/dos/channel.rb +183 -0
  254. data/lib/badline/kernal_trap/{drive → dos}/channels.rb +1 -1
  255. data/lib/badline/kernal_trap/{drive → dos}/memory.rb +1 -1
  256. data/lib/badline/kernal_trap/{drive → dos}/parameters.rb +1 -1
  257. data/lib/badline/kernal_trap/{drive → dos}/status.rb +1 -1
  258. data/lib/badline/kernal_trap/{drive → dos}/write_file.rb +1 -1
  259. data/lib/badline/kernal_trap/{drive → dos}/writes.rb +1 -1
  260. data/lib/badline/kernal_trap/{drive.rb → dos.rb} +11 -10
  261. data/lib/badline/kernal_trap/load.rb +5 -5
  262. data/lib/badline/kernal_trap/save.rb +4 -4
  263. data/lib/badline/kernal_trap/serial.rb +7 -7
  264. data/lib/badline/kernal_trap.rb +1 -2
  265. data/lib/badline/machine/clocking.rb +1 -1
  266. data/lib/badline/machine.rb +5 -5
  267. data/lib/badline/media/true_drive.rb +1 -1
  268. data/lib/badline/media/tune.rb +2 -2
  269. data/lib/badline/media.rb +3 -3
  270. data/lib/badline/model.rb +1 -1
  271. data/lib/badline/roms/README +6 -6
  272. data/lib/badline/sdl.rb +1 -0
  273. data/lib/badline/{storage/sid_file.rb → sid_tune/file.rb} +3 -3
  274. data/lib/badline/{storage → sid_tune}/hvsc.rb +7 -7
  275. data/lib/badline/{storage → sid_tune}/song_lengths.rb +2 -2
  276. data/lib/badline/{storage → sid_tune}/stil/credit.rb +1 -1
  277. data/lib/badline/{storage → sid_tune}/stil.rb +3 -3
  278. data/lib/badline/sid_tune.rb +6 -0
  279. data/lib/badline/snapshot/c128_setup.rb +43 -0
  280. data/lib/badline/snapshot/c64_setup.rb +79 -0
  281. data/lib/badline/snapshot/image.rb +5 -25
  282. data/lib/badline/snapshot/machine_state.rb +1 -1
  283. data/lib/badline/snapshot/setup.rb +22 -66
  284. data/lib/badline/snapshot/state.rb +8 -18
  285. data/lib/badline/snapshot/storage_setup.rb +68 -0
  286. data/lib/badline/snapshot/vic20_setup.rb +37 -0
  287. data/lib/badline/snapshot/vice/c64_mem.rb +1 -1
  288. data/lib/badline/snapshot/vice/restore.rb +1 -1
  289. data/lib/badline/snapshot/vice/reu1764.rb +1 -1
  290. data/lib/badline/snapshot/vice/reu_fields.rb +40 -0
  291. data/lib/badline/snapshot/vice.rb +7 -5
  292. data/lib/badline/snapshot.rb +3 -4
  293. data/lib/badline/storage/d64_image.rb +0 -2
  294. data/lib/badline/storage/d71_image.rb +0 -2
  295. data/lib/badline/storage/d81_image.rb +0 -2
  296. data/lib/badline/storage/disk_image.rb +3 -6
  297. data/lib/badline/storage/g64_image.rb +2 -2
  298. data/lib/badline/storage/host_directory.rb +0 -5
  299. data/lib/badline/storage/t64.rb +2 -8
  300. data/lib/badline/storage/unavailable.rb +1 -1
  301. data/lib/badline/storage.rb +0 -37
  302. data/lib/badline/support/c128_checkpoint.rb +39 -0
  303. data/lib/badline/support/checkpoint.rb +108 -0
  304. data/lib/badline/support/vic20_checkpoint.rb +38 -0
  305. data/lib/badline/support.rb +5 -0
  306. data/lib/badline/version.rb +1 -1
  307. data/lib/badline/vic20/attachments.rb +5 -5
  308. data/lib/badline/vic20/bus/saved_state.rb +35 -0
  309. data/lib/badline/vic20/bus.rb +3 -25
  310. data/lib/badline/vic20/cpu.rb +1 -1
  311. data/lib/badline/vic20/port_wiring.rb +4 -4
  312. data/lib/badline/vic20/saved_state.rb +16 -30
  313. data/lib/badline/vic20/user_via_ports.rb +2 -2
  314. data/lib/badline/vic20.rb +19 -14
  315. metadata +245 -221
  316. data/lib/badline/address_bus/extra_sids.rb +0 -30
  317. data/lib/badline/address_bus/fittings.rb +0 -38
  318. data/lib/badline/address_bus/pla.rb +0 -147
  319. data/lib/badline/address_bus/roms.rb +0 -39
  320. data/lib/badline/address_bus/saved_state.rb +0 -66
  321. data/lib/badline/address_bus/sid_slots.rb +0 -42
  322. data/lib/badline/address_bus.rb +0 -216
  323. data/lib/badline/cartridge/action_replay.rb +0 -126
  324. data/lib/badline/cartridge/atomic_power.rb +0 -24
  325. data/lib/badline/cartridge/bank.rb +0 -81
  326. data/lib/badline/cartridge/comal80.rb +0 -50
  327. data/lib/badline/cartridge/dinamic.rb +0 -34
  328. data/lib/badline/cartridge/easy_flash.rb +0 -145
  329. data/lib/badline/cartridge/epyx_fastload.rb +0 -79
  330. data/lib/badline/cartridge/final_cartridge3.rb +0 -89
  331. data/lib/badline/cartridge/flash.rb +0 -306
  332. data/lib/badline/cartridge/freezer.rb +0 -33
  333. data/lib/badline/cartridge/fun_play.rb +0 -38
  334. data/lib/badline/cartridge/g_mod2.rb +0 -74
  335. data/lib/badline/cartridge/game_system.rb +0 -40
  336. data/lib/badline/cartridge/geo_ram.rb +0 -79
  337. data/lib/badline/cartridge/kcs_power.rb +0 -75
  338. data/lib/badline/cartridge/mach5.rb +0 -32
  339. data/lib/badline/cartridge/magic_desk.rb +0 -30
  340. data/lib/badline/cartridge/ocean.rb +0 -35
  341. data/lib/badline/cartridge/pagefox.rb +0 -68
  342. data/lib/badline/cartridge/retro_replay.rb +0 -320
  343. data/lib/badline/cartridge/rex_utility.rb +0 -29
  344. data/lib/badline/cartridge/rgcd.rb +0 -58
  345. data/lib/badline/cartridge/simons_basic.rb +0 -35
  346. data/lib/badline/cartridge/standard.rb +0 -15
  347. data/lib/badline/cartridge/super_games.rb +0 -48
  348. data/lib/badline/cartridge/westermann.rb +0 -30
  349. data/lib/badline/cartridge/zaxxon.rb +0 -66
  350. data/lib/badline/cartridge.rb +0 -303
  351. data/lib/badline/checkpoint.rb +0 -98
  352. data/lib/badline/cia/fast_forward.rb +0 -60
  353. data/lib/badline/cia/interrupt_register.rb +0 -143
  354. data/lib/badline/cia/serial.rb +0 -275
  355. data/lib/badline/cia/state.rb +0 -47
  356. data/lib/badline/cia/timer.rb +0 -206
  357. data/lib/badline/cia.rb +0 -279
  358. data/lib/badline/color_memory.rb +0 -25
  359. data/lib/badline/control_ports.rb +0 -76
  360. data/lib/badline/cpu/addressing.rb +0 -131
  361. data/lib/badline/cpu/boundary.rb +0 -54
  362. data/lib/badline/cpu/core.rb +0 -165
  363. data/lib/badline/cpu/microcode.rb +0 -177
  364. data/lib/badline/cpu/operations.rb +0 -88
  365. data/lib/badline/cpu/saved_state.rb +0 -115
  366. data/lib/badline/cpu/stack_operations.rb +0 -82
  367. data/lib/badline/cpu.rb +0 -10
  368. data/lib/badline/cpu_port.rb +0 -112
  369. data/lib/badline/datasette.rb +0 -161
  370. data/lib/badline/drive/core.rb +0 -147
  371. data/lib/badline/drive/fast_serial.rb +0 -73
  372. data/lib/badline/drive/idle.rb +0 -125
  373. data/lib/badline/drive/idle_cpu.rb +0 -28
  374. data/lib/badline/drive/orbit.rb +0 -79
  375. data/lib/badline/drive/serial_lines.rb +0 -73
  376. data/lib/badline/drive/sleep.rb +0 -112
  377. data/lib/badline/drive/vias.rb +0 -84
  378. data/lib/badline/drive/watch.rb +0 -150
  379. data/lib/badline/drive.rb +0 -11
  380. data/lib/badline/drive1541/bus.rb +0 -86
  381. data/lib/badline/drive1541/byte_ready.rb +0 -48
  382. data/lib/badline/drive1541/cpu.rb +0 -11
  383. data/lib/badline/drive1541/disk.rb +0 -315
  384. data/lib/badline/drive1541/disk_state.rb +0 -86
  385. data/lib/badline/drive1541/disk_via.rb +0 -36
  386. data/lib/badline/drive1541/gcr.rb +0 -57
  387. data/lib/badline/drive1541/mechanism.rb +0 -313
  388. data/lib/badline/drive1541/mechanism_state.rb +0 -68
  389. data/lib/badline/drive1541/rotation.rb +0 -121
  390. data/lib/badline/drive1541/sector_reader.rb +0 -76
  391. data/lib/badline/drive1541/serial_port.rb +0 -18
  392. data/lib/badline/drive1541/track.rb +0 -98
  393. data/lib/badline/drive1541.rb +0 -111
  394. data/lib/badline/drive1571/bus.rb +0 -111
  395. data/lib/badline/drive1571/cpu.rb +0 -11
  396. data/lib/badline/drive1571/serial_port.rb +0 -37
  397. data/lib/badline/drive1571/serial_via.rb +0 -25
  398. data/lib/badline/drive1571/wd1770.rb +0 -120
  399. data/lib/badline/drive1571.rb +0 -175
  400. data/lib/badline/drive1581/bus.rb +0 -137
  401. data/lib/badline/drive1581/cpu.rb +0 -11
  402. data/lib/badline/drive1581/disk.rb +0 -135
  403. data/lib/badline/drive1581/disk_state.rb +0 -87
  404. data/lib/badline/drive1581/mechanism.rb +0 -117
  405. data/lib/badline/drive1581/serial_port.rb +0 -52
  406. data/lib/badline/drive1581/slot.rb +0 -78
  407. data/lib/badline/drive1581/track.rb +0 -100
  408. data/lib/badline/drive1581/track_bytes.rb +0 -75
  409. data/lib/badline/drive1581/wd1772/registers.rb +0 -89
  410. data/lib/badline/drive1581/wd1772/sector_writes.rb +0 -73
  411. data/lib/badline/drive1581/wd1772/sectors.rb +0 -150
  412. data/lib/badline/drive1581/wd1772/state.rb +0 -66
  413. data/lib/badline/drive1581/wd1772/stepping.rb +0 -109
  414. data/lib/badline/drive1581/wd1772/tracks.rb +0 -125
  415. data/lib/badline/drive1581/wd1772/turn.rb +0 -73
  416. data/lib/badline/drive1581/wd1772.rb +0 -216
  417. data/lib/badline/drive1581.rb +0 -233
  418. data/lib/badline/iec_bus.rb +0 -159
  419. data/lib/badline/instruction.rb +0 -334
  420. data/lib/badline/instruction_set/arithmetic.rb +0 -114
  421. data/lib/badline/instruction_set/bitwise.rb +0 -126
  422. data/lib/badline/instruction_set/branch.rb +0 -79
  423. data/lib/badline/instruction_set/flag.rb +0 -63
  424. data/lib/badline/instruction_set/illegal.rb +0 -270
  425. data/lib/badline/instruction_set/inc_dec.rb +0 -69
  426. data/lib/badline/instruction_set/stack.rb +0 -52
  427. data/lib/badline/instruction_set/transfer.rb +0 -137
  428. data/lib/badline/instruction_set.rb +0 -55
  429. data/lib/badline/interrupts.rb +0 -104
  430. data/lib/badline/joystick.rb +0 -25
  431. data/lib/badline/kernal_trap/channel.rb +0 -181
  432. data/lib/badline/keyboard.rb +0 -112
  433. data/lib/badline/ram_expansion/banking.rb +0 -30
  434. data/lib/badline/ram_expansion/plus256k.rb +0 -54
  435. data/lib/badline/ram_expansion/plus60k.rb +0 -43
  436. data/lib/badline/ram_expansion/unexpanded.rb +0 -28
  437. data/lib/badline/ram_expansion.rb +0 -21
  438. data/lib/badline/reu/dma/saved_state.rb +0 -50
  439. data/lib/badline/reu/dma.rb +0 -273
  440. data/lib/badline/reu/ram.rb +0 -107
  441. data/lib/badline/reu/saved_state.rb +0 -80
  442. data/lib/badline/reu/trigger.rb +0 -32
  443. data/lib/badline/reu.rb +0 -289
  444. data/lib/badline/sid/catch_up.rb +0 -120
  445. data/lib/badline/sid/decimator.rb +0 -64
  446. data/lib/badline/sid/envelope/state.rb +0 -68
  447. data/lib/badline/sid/envelope.rb +0 -239
  448. data/lib/badline/sid/filter.rb +0 -263
  449. data/lib/badline/sid/voice.rb +0 -77
  450. data/lib/badline/sid/waveform/combined.rb +0 -126
  451. data/lib/badline/sid/waveform/fast_forward.rb +0 -105
  452. data/lib/badline/sid/waveform/noise_writeback.rb +0 -122
  453. data/lib/badline/sid/waveform/state.rb +0 -66
  454. data/lib/badline/sid/waveform.rb +0 -305
  455. data/lib/badline/sid.rb +0 -303
  456. data/lib/badline/time_of_day.rb +0 -228
  457. data/lib/badline/traps.rb +0 -19
  458. data/lib/badline/via/control_lines.rb +0 -122
  459. data/lib/badline/via/fast_forward.rb +0 -53
  460. data/lib/badline/via/interrupt_register.rb +0 -67
  461. data/lib/badline/via/shift_register.rb +0 -180
  462. data/lib/badline/via/state.rb +0 -42
  463. data/lib/badline/via/timer1.rb +0 -131
  464. data/lib/badline/via/timer2.rb +0 -133
  465. data/lib/badline/via.rb +0 -266
  466. data/lib/badline/vic/bank.rb +0 -133
  467. data/lib/badline/vic/border_mask.rb +0 -86
  468. data/lib/badline/vic/collisions.rb +0 -115
  469. data/lib/badline/vic/color_patches.rb +0 -47
  470. data/lib/badline/vic/display_state.rb +0 -185
  471. data/lib/badline/vic/graphics_mode.rb +0 -164
  472. data/lib/badline/vic/graphics_shifter.rb +0 -207
  473. data/lib/badline/vic/register_log.rb +0 -81
  474. data/lib/badline/vic/registers.rb +0 -195
  475. data/lib/badline/vic/sequencer.rb +0 -275
  476. data/lib/badline/vic/sequencer_output.rb +0 -116
  477. data/lib/badline/vic/sequencer_state.rb +0 -89
  478. data/lib/badline/vic/sprite/internal_bus.rb +0 -68
  479. data/lib/badline/vic/sprite/saved_state.rb +0 -64
  480. data/lib/badline/vic/sprite/shifter.rb +0 -146
  481. data/lib/badline/vic/sprite/timing.rb +0 -56
  482. data/lib/badline/vic/sprite.rb +0 -337
  483. data/lib/badline/vic/sprites.rb +0 -282
  484. data/lib/badline/vic/sprites_state.rb +0 -57
  485. data/lib/badline/vic.rb +0 -853
  486. data/lib/badline/vic20/sound/output.rb +0 -83
  487. data/lib/badline/vic20/sound.rb +0 -233
  488. data/lib/badline/z80/arithmetic.rb +0 -117
  489. data/lib/badline/z80/bit_page.rb +0 -55
  490. data/lib/badline/z80/block_io.rb +0 -58
  491. data/lib/badline/z80/block_transfers.rb +0 -59
  492. data/lib/badline/z80/bus_cycles.rb +0 -111
  493. data/lib/badline/z80/core.rb +0 -113
  494. data/lib/badline/z80/exchanges.rb +0 -50
  495. data/lib/badline/z80/extended_page.rb +0 -89
  496. data/lib/badline/z80/flags.rb +0 -37
  497. data/lib/badline/z80/interrupt_acceptance.rb +0 -46
  498. data/lib/badline/z80/jumps.rb +0 -82
  499. data/lib/badline/z80/loads.rb +0 -98
  500. data/lib/badline/z80/main_page.rb +0 -134
  501. data/lib/badline/z80/registers.rb +0 -120
  502. data/lib/badline/z80/saved_state.rb +0 -69
  503. data/lib/badline/z80/shifts.rb +0 -64
  504. data/lib/badline/z80.rb +0 -11
  505. /data/lib/badline/snapshot/{fields.rb → vice/fields.rb} +0 -0
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,
@@ -45,9 +45,9 @@ module Badline
45
45
  include IntegerHelper
46
46
  include KeyboardBuffer
47
47
  include Machine::Clocking
48
- include Computer::Common
49
- include Computer::Attachments
50
- include Computer::KernalTraps
48
+ include C64::Common
49
+ include C64::Attachments
50
+ include C64::KernalTraps
51
51
  include Keys
52
52
  include Modes
53
53
  include Drives
@@ -56,7 +56,7 @@ module Badline
56
56
 
57
57
  # The C64's 8x8 matrix and the three rows K0-K2 select, in port B
58
58
  # column order.
59
- KEYBOARD_MATRIX = (Keyboard::C64_MATRIX + [
59
+ KEYBOARD_MATRIX = (Input::Keyboard::C64_MATRIX + [
60
60
  %i[help keypad8 keypad5 tab keypad2 keypad4 keypad7 keypad1],
61
61
  %i[esc keypad_plus keypad_minus line_feed keypad_enter keypad6 keypad9 keypad3],
62
62
  %i[alt keypad0 keypad_period crsr_up crsr_down crsr_left crsr_right no_scroll]
@@ -93,6 +93,11 @@ module Badline
93
93
 
94
94
  def ram = @bus.ram
95
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
+
96
101
  def keyboard = @bus.keyboard
97
102
 
98
103
  def joystick1 = @bus.joystick1
@@ -116,7 +121,7 @@ module Badline
116
121
 
117
122
  @model = Model.named(model)
118
123
  @c64_built = mode == :c64
119
- @init_threshold = @c64_built ? Computer::INIT_THRESHOLD : C128_INIT_THRESHOLD
124
+ @init_threshold = @c64_built ? C64::INIT_THRESHOLD : C128_INIT_THRESHOLD
120
125
  @holding_commodore = false
121
126
  @bus = Bus.new(@model, sid_model: sid_model || @model.sid_model, mode:)
122
127
  @cpu = CPU.new(@bus, debug:)
@@ -209,7 +214,7 @@ module Badline
209
214
  @cia2.reset!
210
215
  @sid.reset!
211
216
  @bus.cartridge&.reset
212
- @drive&.reset!
217
+ @dos&.reset!
213
218
  @drive1541&.reset!
214
219
  @drive1571&.reset!
215
220
  @drive1581&.reset!
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Badline
4
- class Computer
4
+ class C64
5
5
  # What plugs into the machine besides its chips, the cartridge, its
6
6
  # true drives (TrueDrives) and an REU, and their state for a snapshot.
7
7
  # The disk device 8 serves through the traps is KernalTraps'.
@@ -27,7 +27,7 @@ module Badline
27
27
  # CIA 2's port A drives the serial bus, which reads CLK and DATA back
28
28
  # into it.
29
29
  def plug_serial_bus
30
- @iec_bus = IECBus.new
30
+ @iec_bus = Drives::SerialBus.new
31
31
  @cia2.peripheral = @iec_bus
32
32
  @cia2.on_port_a_write { push_serial_lines }
33
33
  push_serial_lines
@@ -54,10 +54,9 @@ module Badline
54
54
  end
55
55
  end
56
56
 
57
- # A true 1541 on the serial bus, then a 1581. The leading flag is the
58
- # bus itself, which every machine now has.
57
+ # A true 1541 on the serial bus, then a 1581.
59
58
  def save_serial_bus(out)
60
- out.boolean(true).boolean(!@drive1541.nil?)
59
+ out.boolean(!@drive1541.nil?)
61
60
  if @drive1541
62
61
  out.int(@drive1541.device)
63
62
  @drive1541.save_state(out)
@@ -66,7 +65,6 @@ module Badline
66
65
  end
67
66
 
68
67
  def load_serial_bus(input)
69
- input.boolean?
70
68
  load_drive1541(input)
71
69
  load_drive1581(input)
72
70
  end
@@ -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
@@ -0,0 +1,149 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ class Bus
6
+ # The C64's PLA: what each page of the CPU's view maps to, from the
7
+ # CPU port's LORAM, HIRAM and CHAREN lines and the cartridge's EXROM
8
+ # and GAME. The bus that includes it supplies the page tables, the
9
+ # ROMs, the chips, #map_ram_pages, which lays out the RAM that the
10
+ # ROMs, the cartridge and I/O map over, and #map_io_pages, which lays
11
+ # out the chips at $D000-$DFFF, with #map_cartridge_io for I/O 1 and 2.
12
+ module PLA
13
+ # A chip's registers seen at another page, which reads and writes
14
+ # them as at the page the chip starts at.
15
+ class Mirror
16
+ def initialize(chip, start)
17
+ @chip = chip
18
+ @start = start
19
+ end
20
+
21
+ def peek(addr) = @chip.peek(@start | (addr & 0xff))
22
+ def poke(addr, value) = @chip.poke(@start | (addr & 0xff), value)
23
+ end
24
+
25
+ private
26
+
27
+ def map_pla_pages
28
+ map_ram_pages
29
+ @ultimax ? map_ultimax_pages : map_banked_pages
30
+ end
31
+
32
+ def map_banked_pages
33
+ map_rom_overlays
34
+ map_cartridge_ram
35
+ @write_pages.fill(@cartridge.romh_writes, 0xe0, 0x20) if @cartridge&.romh_writes
36
+
37
+ if io?
38
+ map_io_pages
39
+ elsif character?
40
+ @read_pages.fill(character_rom, 0xd0, 0x10)
41
+ end
42
+ end
43
+
44
+ # Ultimax mode ignores the $01 lines: 4K of RAM, ROML/ROMH windows,
45
+ # I/O always visible and open address space everywhere else. The ROML
46
+ # and ROMH selects fire on writes as well, so cartridge RAM or flash in
47
+ # either window takes the writes there. The MAX has 2K of RAM, and is
48
+ # in Ultimax mode with no cartridge too.
49
+ def map_ultimax_pages
50
+ first = @board == :max ? 0x08 : 0x10
51
+ @read_pages.fill(@open_bus, first, 0x100 - first)
52
+ @write_pages.fill(@open_bus, first, 0x100 - first)
53
+ map_ultimax_cartridge if @cartridge
54
+ map_io_pages
55
+ map_max_io if @board == :max
56
+ end
57
+
58
+ def map_ultimax_cartridge
59
+ @read_pages.fill(@cartridge.roml, 0x80, 0x20) if @cartridge.roml
60
+ map_ultimax_writes(@cartridge.roml, 0x80)
61
+ @read_pages.fill(@cartridge.romh, 0xe0, 0x20) if @cartridge.romh
62
+ map_ultimax_writes(@cartridge.romh, 0xe0)
63
+ map_ultimax_a000
64
+ end
65
+
66
+ def map_ultimax_writes(bank, first_page)
67
+ @write_pages.fill(bank, first_page, 0x20) if bank.respond_to?(:poke)
68
+ end
69
+
70
+ def map_ultimax_a000
71
+ return unless (window = @cartridge.ultimax_a000)
72
+
73
+ @read_pages.fill(window, 0xa0, 0x20)
74
+ @write_pages.fill(window, 0xa0, 0x20)
75
+ end
76
+
77
+ # The MAX has no CIA 2 and no I/O 2: CIA 1 answers all through
78
+ # $DC00-$DFFF, but for the I/O 1 page a cartridge takes.
79
+ def map_max_io
80
+ @cia1_mirror ||= Mirror.new(cia1, 0xdc00)
81
+ (0xdd..0xdf).each { |page| @read_pages[page] = @write_pages[page] = @cia1_mirror }
82
+ return unless @cartridge
83
+
84
+ @write_pages[0xde] = @cartridge
85
+ @read_pages[0xde] = @cartridge if @cartridge.readable_io_pages.include?(0xde)
86
+ end
87
+
88
+ # EXROM and GAME select the cartridge whether or not it has a chip
89
+ # there, and an empty socket leaves the bus floating.
90
+ def map_rom_overlays
91
+ @read_pages.fill(@cartridge.roml || @open_bus, 0x80, 0x20) if roml?
92
+ if romh?
93
+ @read_pages.fill(@cartridge.romh || @open_bus, 0xa0, 0x20)
94
+ elsif basic?
95
+ @read_pages.fill(basic_rom, 0xa0, 0x20)
96
+ end
97
+ @read_pages.fill(kernal_rom, 0xe0, 0x20) if kernal?
98
+ end
99
+
100
+ # Cartridge RAM in the ROML or ROMH window decodes writes itself,
101
+ # whatever the $01 lines say.
102
+ def map_cartridge_ram
103
+ return unless @cartridge&.exrom&.zero?
104
+
105
+ map_cartridge_ram_bank(@cartridge.roml, 0x80)
106
+ map_cartridge_ram_bank(@cartridge.romh, 0xa0) if @cartridge.game.zero?
107
+ end
108
+
109
+ def map_cartridge_ram_bank(bank, first_page)
110
+ @write_pages.fill(bank, first_page, 0x20) if bank.is_a?(Cartridge::RAMBank)
111
+ end
112
+
113
+ def map_cartridge_io
114
+ @write_pages.fill(@cartridge, 0xde, 2)
115
+ @cartridge.readable_io_pages.each { |p| @read_pages[p] = @cartridge }
116
+ end
117
+
118
+ def basic?
119
+ io_port.kernal? && io_port.basic? && game_high?
120
+ end
121
+
122
+ def game_high?
123
+ @cartridge.nil? || @cartridge.game == 1
124
+ end
125
+
126
+ def roml?
127
+ @cartridge&.exrom&.zero? && io_port.kernal? && io_port.basic?
128
+ end
129
+
130
+ def romh?
131
+ @cartridge&.exrom&.zero? && @cartridge.game.zero? && io_port.kernal?
132
+ end
133
+
134
+ # In 16K mode LORAM alone leaves $d000 as RAM, where it still maps I/O.
135
+ def character?
136
+ (io_port.kernal? || (io_port.basic? && game_high?)) && !io_port.io?
137
+ end
138
+
139
+ def io?
140
+ (io_port.basic? || io_port.kernal?) && io_port.io?
141
+ end
142
+
143
+ def kernal?
144
+ io_port.kernal?
145
+ end
146
+ end
147
+ end
148
+ end
149
+ end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ class Bus
6
+ # The BASIC, character and KERNAL ROMs, and which KERNAL is fitted.
7
+ module ROMs
8
+ # The KERNAL ROMs a machine can be fitted with, by name: the C64's,
9
+ # the SX-64's, the PET 64's and the C64GS's. The C64GS's is a 16K
10
+ # image of its BASIC and its KERNAL, and fits both.
11
+ KERNALS = {
12
+ c64: "kernal.rom", sx64: "kernal-sx64.rom", pet64: "kernal-pet64.rom", gs: "c64gs.rom"
13
+ }.freeze
14
+
15
+ attr_reader :basic_rom, :character_rom, :kernal_rom, :kernal
16
+
17
+ # Fits the KERNAL ROM KERNALS names `name`, in place of the one before,
18
+ # with the BASIC of a 16K image or else the C64's.
19
+ def kernal=(name)
20
+ raise ArgumentError, "no KERNAL named #{name}" unless KERNALS.key?(name)
21
+
22
+ @kernal = name
23
+ data = ROM.read(KERNALS[name])
24
+ basic = data.length == 0x4000 ? data[0, 0x2000] : ROM.read("basic.rom")
25
+ @basic_rom = ROM.new(basic, length: 0x2000, start: 0xa000)
26
+ @kernal_rom = ROM.new(data[-0x2000, 0x2000], length: 0x2000, start: 0xe000)
27
+ update_overlays!
28
+ end
29
+
30
+ private
31
+
32
+ def load_roms
33
+ @basic_rom = ROM.load("basic.rom", 0xa000)
34
+ @character_rom = ROM.load("character.rom", 0xd000)
35
+ @kernal = :c64
36
+ @kernal_rom = ROM.load(KERNALS[:c64], 0xe000)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,68 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ class Bus
6
+ # The bus's state for a snapshot: the CPU port, the RAM, colour RAM and
7
+ # a RAM expansion, the cartridge, the datasette and the chips.
8
+ module SavedState
9
+ # The RAM expansion fitted, or an Unexpanded stand-in.
10
+ attr_reader :ram_expansion
11
+
12
+ # Takes the cartridge out of the expansion port, as a restore does for
13
+ # a state without one.
14
+ def detach_cartridge
15
+ @cartridge = nil
16
+ update_overlays!
17
+ end
18
+
19
+ # The 6510 port's direction and output registers, and the charge left
20
+ # on its floating bits.
21
+ def port_state = [@cpu_port.ddr, @cpu_port.data, @cpu_port.floating]
22
+
23
+ # Sets the port as port_state reads it, as a snapshot restores it,
24
+ # leaving the RAM under $00 and $01 alone.
25
+ def restore_port(ddr, out, floating)
26
+ @cpu_port.restore(ddr, out, floating)
27
+ end
28
+
29
+ # The machine's memory and everything on the bus but the keyboard, the
30
+ # joysticks and the pot devices, which the host holds. A cartridge is
31
+ # already in the port, built from its setup (C64#load_state).
32
+ def save_state(out)
33
+ out.marker("BUS")
34
+ out.int(@cpu_port.ddr).int(@cpu_port.data).int(@cpu_port.floating)
35
+ @ram.save_state(out)
36
+ @color_ram.save_state(out)
37
+ @ram_expansion.save_state(out)
38
+ @cartridge&.save_state(out)
39
+ @datasette.save_state(out)
40
+ @vic.save_state(out)
41
+ @cia1.save_state(out)
42
+ @cia2.save_state(out)
43
+ @sid.save_state(out)
44
+ end
45
+
46
+ def load_state(input)
47
+ input.marker("BUS")
48
+ ddr = input.int
49
+ port_out = input.int
50
+ floating = input.int
51
+ @ram.load_state(input)
52
+ @color_ram.load_state(input)
53
+ @ram_expansion.load_state(input)
54
+ @cartridge&.load_state(input)
55
+ @datasette.load_state(input)
56
+ @cpu_port.load(ddr, port_out, floating)
57
+ update_overlays!
58
+ @vic.load_state(input)
59
+ @cia1.load_state(input)
60
+ @cia2.load_state(input)
61
+ @sid.load_state(input)
62
+ end
63
+ end
64
+
65
+ include SavedState
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class C64
5
+ class Bus
6
+ # Stands in for a page of I/O that a second or third SID shares: each 32
7
+ # bytes of it go to the SID placed there, or else to the first SID's
8
+ # mirrors in `$d400-$d7ff`, and to the open bus in I/O 1 and 2.
9
+ class SIDSlots
10
+ attr_reader :page
11
+
12
+ def initialize(page, first, open_bus)
13
+ @page = page
14
+ @io = page >= 0xde
15
+ @first = first
16
+ @open_bus = open_bus
17
+ @sids = []
18
+ @slots = Array.new(8, -1)
19
+ end
20
+
21
+ def place(sid)
22
+ @slots[(sid.start >> 5) & 7] = @sids.size
23
+ @sids << sid
24
+ end
25
+
26
+ def peek(addr)
27
+ index = @slots[(addr >> 5) & 7]
28
+ return @sids[index].peek(addr) unless index.negative?
29
+
30
+ @io ? @open_bus.peek(addr) : @first.peek(addr)
31
+ end
32
+
33
+ def poke(addr, value)
34
+ index = @slots[(addr >> 5) & 7]
35
+ if !index.negative?
36
+ @sids[index].poke(addr, value)
37
+ elsif !@io
38
+ @first.poke(addr, value)
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end