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,306 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Cartridge
5
- # A Flash chip's state, for a snapshot.
6
- module FlashState
7
- STATES = %i[read program_setup autoselect programming erase_window erasing suspended chip_erase
8
- program_error].freeze
9
-
10
- # The array, the command state, a timed operation's end on the
11
- # machine's clock, and the windows handed out so far, which load_state
12
- # builds anew.
13
- def save_state(out)
14
- out.blob(@data).int(STATES.index(@state)).int(STATES.index(@base_state)).int(@cycle).int(@toggle)
15
- out.optional_int(@done_at).optional_int(@programmed).optional_int(@remaining)
16
- out.boolean(!@erasing_sectors.nil?)
17
- out.ints(@erasing_sectors) if @erasing_sectors
18
- out.ints(@windows.keys).ints(@status_windows.keys)
19
- end
20
-
21
- def load_state(input)
22
- input.blob_into(@data)
23
- @state = STATES.fetch(input.int).to_sym
24
- @base_state = STATES.fetch(input.int).to_sym
25
- @cycle = input.int
26
- @toggle = input.int
27
- @done_at = input.optional_int
28
- @programmed = input.optional_int
29
- @remaining = input.optional_int
30
- @erasing_sectors = nil
31
- @erasing_sectors = input.ints if input.boolean?
32
- rebuild_windows(input.ints, input.ints)
33
- end
34
- end
35
-
36
- # An AMD 29F0x0 flash chip, driven through the JEDEC command set in the
37
- # AMD datasheets. Each command opens with two unlock cycles, $AA to the
38
- # first unlock address and $55 to the second, and a third write picks
39
- # the command:
40
- #
41
- # $90 autoselect: offset 0 reads the manufacturer, 1 the device and 2
42
- # the sector protection, until a reset
43
- # $F0 reset to reading the array, which a lone $F0 also does
44
- # $A0 byte program: the next write clears bits of the array, which
45
- # only an erase sets again
46
- # $80 erase, after two more unlock cycles: $10 to the first unlock
47
- # address erases the chip, and $30 to a sector erases the sector.
48
- # Further sectors can follow within the 50 us window.
49
- #
50
- # While a program or erase runs, a read returns status: DQ7 the
51
- # complement of the programmed bit (0 while erasing), DQ6 toggling on
52
- # every read, DQ5 set when a program failed and DQ3 set once an erase
53
- # has left its window. $B0 suspends a sector erase and $30 resumes it.
54
- #
55
- # The cartridge reads the array through windows, and the chip swaps
56
- # them for status windows while it is busy or in autoselect.
57
- class Flash
58
- Model = Data.define(:size, :sector_size, :unlock1, :unlock2, :unlock_mask, :manufacturer, :device)
59
-
60
- AM29F040 = Model.new(size: 0x80000, sector_size: 0x10000, unlock1: 0x5555, unlock2: 0x2aaa,
61
- unlock_mask: 0x7fff, manufacturer: 0x01, device: 0xa4)
62
- AM29F040B = Model.new(size: 0x80000, sector_size: 0x10000, unlock1: 0x555, unlock2: 0x2aa,
63
- unlock_mask: 0x7ff, manufacturer: 0x01, device: 0xa4)
64
- AM29F010 = Model.new(size: 0x20000, sector_size: 0x4000, unlock1: 0x5555, unlock2: 0x2aaa,
65
- unlock_mask: 0x7fff, manufacturer: 0x01, device: 0x20)
66
-
67
- # The datasheet's typical times, in cycles at 1 MHz.
68
- PROGRAM_CYCLES = 7
69
- ERASE_WINDOW_CYCLES = 50
70
- SECTOR_ERASE_CYCLES = 1_000_000
71
- CHIP_ERASE_CYCLES = 8_000_000
72
-
73
- # The array, read directly while the chip reads it.
74
- class Window
75
- def initialize(flash, base)
76
- @flash = flash
77
- @data = flash.data
78
- @base = base
79
- end
80
-
81
- def peek(addr)
82
- @data[@base | (addr & 0x1fff)]
83
- end
84
- alias [] peek
85
-
86
- def poke(addr, value)
87
- @flash.write(@base | (addr & 0x1fff), value)
88
- end
89
- alias []= poke
90
- end
91
-
92
- # Reads through the chip, for its status and autoselect codes.
93
- class StatusWindow < Window
94
- def peek(addr)
95
- @flash.read(@base | (addr & 0x1fff))
96
- end
97
- alias [] peek
98
- end
99
-
100
- include FlashState
101
-
102
- attr_reader :data, :state
103
- attr_writer :clock
104
-
105
- def initialize(data, model: AM29F040B, clock: -> { 0 })
106
- @model = model
107
- @data = data + ([0xff] * (model.size - data.length))
108
- @clock = clock
109
- @windows = {}
110
- @status_windows = {}
111
- @on_change = nil
112
- @state = :read
113
- @base_state = :read
114
- @cycle = 0
115
- @toggle = 0
116
- end
117
-
118
- # Called when the chip starts or stops answering reads from the array.
119
- def on_change(&block)
120
- @on_change = block
121
- end
122
-
123
- def window(base)
124
- if array_mode?
125
- @windows[base] ||= Window.new(self, base)
126
- else
127
- @status_windows[base] ||= StatusWindow.new(self, base)
128
- end
129
- end
130
-
131
- # Hands out new windows at the bases given, as #window would have.
132
- def rebuild_windows(bases, status_bases)
133
- @windows = {}
134
- @status_windows = {}
135
- bases.each { |base| @windows[base] = Window.new(self, base) }
136
- status_bases.each { |base| @status_windows[base] = StatusWindow.new(self, base) }
137
- end
138
-
139
- def array_mode?
140
- @state == :read || @state == :program_setup
141
- end
142
-
143
- def read(offset)
144
- settle
145
- case @state
146
- when :read then @data[offset]
147
- when :autoselect then autoselect_code(offset)
148
- when :suspended then suspended_read(offset)
149
- else status
150
- end
151
- end
152
-
153
- def write(offset, value)
154
- settle
155
- case @state
156
- when :program_setup then program(offset, value)
157
- when :erase_window then extend_erase(offset, value)
158
- when :erasing then suspend if value == 0xb0
159
- when :suspended then resume if value == 0x30
160
- when :program_error then enter(:read, base: :read) if value == 0xf0
161
- when :programming, :chip_erase then nil
162
- else command(offset, value)
163
- end
164
- end
165
-
166
- private
167
-
168
- def command(offset, value)
169
- if value == 0xf0
170
- @cycle = 0
171
- return enter(:read, base: :read)
172
- end
173
-
174
- address = offset & @model.unlock_mask
175
- @cycle = case @cycle
176
- when 0, 3 then address == @model.unlock1 && value == 0xaa ? @cycle + 1 : 0
177
- when 1, 4 then address == @model.unlock2 && value == 0x55 ? @cycle + 1 : 0
178
- when 2 then command_cycle(address, value)
179
- when 5 then erase_command(offset, address, value)
180
- end
181
- end
182
-
183
- def command_cycle(address, value)
184
- return 0 unless address == @model.unlock1
185
-
186
- case value
187
- when 0x90 then enter(:autoselect, base: :autoselect)
188
- when 0xa0 then @state = :program_setup
189
- when 0x80 then return 3
190
- end
191
- 0
192
- end
193
-
194
- def erase_command(offset, address, value)
195
- if value == 0x10 && address == @model.unlock1
196
- start_busy(:chip_erase, CHIP_ERASE_CYCLES)
197
- elsif value == 0x30
198
- @erasing_sectors = [sector(offset)]
199
- start_busy(:erase_window, ERASE_WINDOW_CYCLES)
200
- end
201
- 0
202
- end
203
-
204
- def program(offset, value)
205
- @programmed = value
206
- @data[offset] &= value
207
- if @data[offset] == value
208
- start_busy(:programming, PROGRAM_CYCLES)
209
- else
210
- enter(:program_error)
211
- end
212
- end
213
-
214
- def extend_erase(offset, value)
215
- case value
216
- when 0x30
217
- @erasing_sectors |= [sector(offset)]
218
- @done_at = now + ERASE_WINDOW_CYCLES
219
- when 0xb0
220
- @remaining = @erasing_sectors.length * SECTOR_ERASE_CYCLES
221
- enter(:suspended)
222
- else
223
- @erasing_sectors = nil
224
- enter(@base_state)
225
- end
226
- end
227
-
228
- def suspend
229
- @remaining = @done_at - now
230
- enter(:suspended)
231
- end
232
-
233
- def resume
234
- start_busy(:erasing, @remaining)
235
- end
236
-
237
- # Moves a timed operation on once the clock has passed its end.
238
- def settle
239
- return unless @done_at && now >= @done_at
240
-
241
- case @state
242
- when :erase_window
243
- start_busy(:erasing, @done_at - now + (@erasing_sectors.length * SECTOR_ERASE_CYCLES))
244
- settle
245
- when :erasing
246
- @erasing_sectors.each { |s| @data.fill(0xff, s * @model.sector_size, @model.sector_size) }
247
- @erasing_sectors = nil
248
- finish
249
- when :chip_erase
250
- @data.fill(0xff)
251
- finish
252
- else
253
- finish
254
- end
255
- end
256
-
257
- def finish
258
- @done_at = nil
259
- enter(@base_state)
260
- end
261
-
262
- def start_busy(state, cycles)
263
- @done_at = now + cycles
264
- @programmed = 0xff unless state == :programming
265
- enter(state)
266
- end
267
-
268
- def enter(state, base: @base_state)
269
- was_array = array_mode?
270
- @state = state
271
- @base_state = base
272
- @done_at = nil unless %i[programming erase_window erasing chip_erase].include?(state)
273
- @on_change&.call if was_array != array_mode?
274
- end
275
-
276
- def status
277
- @toggle ^= 0x40
278
- value = (~@programmed & 0x80) | @toggle
279
- value |= 0x20 if @state == :program_error
280
- value |= 0x08 if @state == :erasing || @state == :chip_erase
281
- value
282
- end
283
-
284
- def suspended_read(offset)
285
- @erasing_sectors.include?(sector(offset)) ? 0x80 : @data[offset]
286
- end
287
-
288
- def autoselect_code(offset)
289
- case offset & 0x43
290
- when 0 then @model.manufacturer
291
- when 1 then @model.device
292
- when 2 then 0x00
293
- else @data[offset]
294
- end
295
- end
296
-
297
- def sector(offset)
298
- offset / @model.sector_size
299
- end
300
-
301
- def now
302
- @clock.call
303
- end
304
- end
305
- end
306
- end
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Cartridge
5
- # The freeze button of a freezer cartridge. A press pulls NMI, and the
6
- # computer calls #freeze! once the CPU has pushed the return address and
7
- # status of the interrupt, so the vector fetch that follows reads the
8
- # cartridge ROM in Ultimax mode. The cartridge lets go of NMI when its
9
- # software acknowledges the freeze.
10
- module Freezer
11
- def freezer? = true
12
-
13
- def press_button
14
- @button = true
15
- self.nmi = true if freeze_allowed?
16
- end
17
-
18
- def release_button
19
- @button = false
20
- end
21
-
22
- private
23
-
24
- def freeze_allowed?
25
- true
26
- end
27
-
28
- def button_pressed?
29
- @button == true
30
- end
31
- end
32
- end
33
- end
@@ -1,38 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Cartridge
5
- # Fun Play / Power Play: up to 16 8K banks. A write to I/O 1 selects the
6
- # bank from bits 3-5 and 0, and either 8K mode ($00 in bits 7, 6, 2 and 1)
7
- # or no ROM ($86 in those bits).
8
- class FunPlay < Cartridge
9
- def poke(addr, value)
10
- return if addr > 0xdeff
11
-
12
- @roml = bank(@banks, self.class.bank_number(value))
13
- case value & 0xc6
14
- when 0x00 then self.mode = :rom8k
15
- when 0x86 then self.mode = :off
16
- end
17
- changed!
18
- end
19
-
20
- # The CRT file numbers each bank by the register value that selects it.
21
- def reset
22
- poke(0xde00, 0)
23
- end
24
-
25
- def self.bank_number(value)
26
- ((value >> 3) & 0x07) | ((value & 0x01) << 3)
27
- end
28
-
29
- private
30
-
31
- def install_chips(chips)
32
- @banks = []
33
- chips.each { |chip| @banks[self.class.bank_number(chip.bank)] = rom_bank(chip.data) }
34
- reset
35
- end
36
- end
37
- end
38
- end
@@ -1,74 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Cartridge
5
- # GMod2: an Am29F040 flash chip of 64 8K banks at ROML. A write to I/O 1
6
- # selects the bank from bits 0-5. Bit 6 selects the EEPROM, which
7
- # switches the ROM out, and bits 6 and 7 together enable flash writes:
8
- # the cartridge then asserts Ultimax on write cycles only, so reads see
9
- # the C64's memory and writes to $E000-$FFFF reach the flash. The EEPROM
10
- # isn't emulated.
11
- class GMod2 < Cartridge
12
- BANKS = 64
13
-
14
- attr_reader :flash
15
-
16
- def clock=(clock)
17
- super
18
- @flash.clock = clock
19
- end
20
-
21
- def poke(addr, value)
22
- return if addr > 0xdeff
23
-
24
- @bank = value & 0x3f
25
- @flash_writes = value.allbits?(0xc0)
26
- self.mode = value.anybits?(0x40) ? :off : :rom8k
27
- select_bank
28
- end
29
-
30
- def romh_writes
31
- @roml if @flash_writes
32
- end
33
-
34
- # Reset selects the first bank in 8K mode, and leaves the flash as it
35
- # is.
36
- def reset
37
- @bank = 0
38
- @flash_writes = false
39
- self.mode = :rom8k
40
- select_bank
41
- end
42
-
43
- private
44
-
45
- def select_bank
46
- @roml = @flash.window(@bank * BANK_SIZE)
47
- changed!
48
- end
49
-
50
- def save_mapper(out)
51
- out.int(@bank).boolean(@flash_writes)
52
- @flash.save_state(out)
53
- end
54
-
55
- def load_mapper(input)
56
- @bank = input.int
57
- @flash_writes = input.boolean?
58
- @flash.load_state(input)
59
- @roml = @flash.window(@bank * BANK_SIZE)
60
- end
61
-
62
- def install_chips(chips)
63
- data = Array.new(BANKS * BANK_SIZE, 0xff)
64
- chips.each do |chip|
65
- bytes = chip.data.first(BANK_SIZE)
66
- data[(chip.bank & 0x3f) * BANK_SIZE, bytes.length] = bytes
67
- end
68
- @flash = Flash.new(data, model: Flash::AM29F040)
69
- @flash.on_change { select_bank }
70
- reset
71
- end
72
- end
73
- end
74
- end
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Cartridge
5
- # C64 Game System / System 3: up to 64 8K banks. Any access to
6
- # $DE00-$DEFF selects the bank from the low six address bits; the data
7
- # is ignored.
8
- class GameSystem < Cartridge
9
- def readable_io_pages
10
- [0xde]
11
- end
12
-
13
- def peek(addr)
14
- select(addr) if addr < 0xdf00
15
- open_bus(addr)
16
- end
17
-
18
- def poke(addr, _value)
19
- select(addr) if addr < 0xdf00
20
- end
21
-
22
- def reset
23
- select(0)
24
- end
25
-
26
- private
27
-
28
- def select(addr)
29
- @roml = bank(@banks, addr & 0x3f)
30
- changed!
31
- end
32
-
33
- def install_chips(chips)
34
- @banks = banks_from(chips).first
35
- self.mode = :rom8k
36
- reset
37
- end
38
- end
39
- end
40
- end
@@ -1,79 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Cartridge
5
- # GEO-RAM: a RAM expansion on the expansion port, seen through a 256-byte
6
- # window at $DE00-$DEFF. Two write-only registers pick the page the
7
- # window shows: $DFFE selects one of the 64 pages of a 16K block, and
8
- # $DFFF selects the block. As in VICE, the registers answer at every
9
- # address from $DF80 up, even for $DFFE and odd for $DFFF, and the block
10
- # number wraps at the number of blocks the RAM holds. Reads of I/O 2 are
11
- # open bus. It leaves EXROM and GAME high, and RES clears both
12
- # registers.
13
- class GeoRAM < Cartridge
14
- SIZES = [64, 128, 256, 512, 1024, 2048, 4096].freeze
15
- BLOCK_SIZE = 0x4000
16
- PAGE_MASK = 0x3f
17
-
18
- attr_reader :size
19
-
20
- # size is the RAM in kilobytes.
21
- def initialize(size: 512)
22
- raise ArgumentError, "Unsupported GEO-RAM size #{size}K" unless SIZES.include?(size)
23
-
24
- @size = size
25
- @block_mask = ((size * 1024) / BLOCK_SIZE) - 1
26
- super(Storage::CRTFile::Image.new(hardware_type: nil, subtype: 0, exrom: 1, game: 1,
27
- name: "GEO-RAM", chips: []))
28
- end
29
-
30
- def readable_io_pages
31
- [0xde]
32
- end
33
-
34
- def peek(addr)
35
- @ram_data[@window + (addr & 0xff)]
36
- end
37
-
38
- def poke(addr, value)
39
- if addr <= 0xdeff
40
- @ram_data[@window + (addr & 0xff)] = value
41
- elsif addr >= 0xdf80
42
- if addr.odd?
43
- @block = value & @block_mask
44
- else
45
- @page = value & PAGE_MASK
46
- end
47
- @window = (@block * BLOCK_SIZE) + (@page * 0x100)
48
- end
49
- end
50
-
51
- def reset
52
- @block = @page = @window = 0
53
- end
54
-
55
- # A GEO-RAM is built from its size alone.
56
- def save_setup(out)
57
- out.int(GEO_RAM_SETUP).int(@size)
58
- end
59
-
60
- private
61
-
62
- def save_mapper(out)
63
- out.blob(@ram_data).int(@block).int(@page).int(@window)
64
- end
65
-
66
- def load_mapper(input)
67
- input.blob_into(@ram_data)
68
- @block = input.int
69
- @page = input.int
70
- @window = input.int
71
- end
72
-
73
- def install_chips(_chips)
74
- @ram_data = Array.new(@size * 1024, 0)
75
- reset
76
- end
77
- end
78
- end
79
- end
@@ -1,75 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Cartridge
5
- # The KCS Power Cartridge: 16K of ROM, 128 bytes of RAM and a freeze
6
- # button. It boots in 16K mode, and any access to I/O 1 sets the lines
7
- # from address bit 1 and the direction:
8
- #
9
- # read, bit 1 clear 8K
10
- # read, bit 1 set off
11
- # write, bit 1 clear 16K
12
- # write, bit 1 set Ultimax
13
- #
14
- # A read of I/O 1 returns the second last page of ROML. I/O 2 holds the
15
- # RAM in its lower half, and the upper half reads the EXROM line in bit 7
16
- # and GAME in bit 6, which the freezer checks to find the mode it
17
- # interrupted. A freeze switches to Ultimax and lets go of NMI.
18
- class KCSPower < Cartridge
19
- include Freezer
20
-
21
- IO1_ROM_PAGE = 0x1e00
22
-
23
- def readable_io_pages
24
- [0xde, 0xdf]
25
- end
26
-
27
- def peek(addr)
28
- if addr < 0xdf00
29
- select_mode(addr.anybits?(0x02) ? :off : :rom8k)
30
- @roml.peek(IO1_ROM_PAGE | (addr & 0xff))
31
- elsif addr.anybits?(0x80)
32
- (@exrom << 7) | (@game << 6) | (open_bus(addr) & 0x3f)
33
- else
34
- @io_ram[addr & 0x7f]
35
- end
36
- end
37
-
38
- def poke(addr, value)
39
- if addr < 0xdf00
40
- select_mode(addr.anybits?(0x02) ? :ultimax : :rom16k)
41
- elsif addr.nobits?(0x80)
42
- @io_ram[addr & 0x7f] = value
43
- end
44
- end
45
-
46
- def reset
47
- self.nmi = false
48
- select_mode(:rom16k)
49
- end
50
-
51
- def freeze!
52
- self.nmi = false
53
- select_mode(:ultimax)
54
- end
55
-
56
- private
57
-
58
- def save_mapper(out)
59
- out.blob(@io_ram)
60
- end
61
-
62
- def load_mapper(input)
63
- input.blob_into(@io_ram)
64
- end
65
-
66
- def install_chips(chips)
67
- roml, romh = banks_from(chips)
68
- @roml = roml.first || EMPTY_BANK
69
- @romh = romh.first || EMPTY_BANK
70
- @io_ram = Array.new(0x80, 0xff)
71
- reset
72
- end
73
- end
74
- end
75
- end
@@ -1,32 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Cartridge
5
- # 8K. Writing I/O 1 switches the ROM in, writing I/O 2 switches it out.
6
- # Both I/O pages read the last 512 bytes of the ROM.
7
- class Mach5 < Cartridge
8
- def readable_io_pages
9
- [0xde, 0xdf]
10
- end
11
-
12
- def peek(addr)
13
- @roml.peek(addr)
14
- end
15
-
16
- def poke(addr, _value)
17
- select_mode(addr < 0xdf00 ? :rom8k : :off)
18
- end
19
-
20
- def reset
21
- select_mode(:rom8k)
22
- end
23
-
24
- private
25
-
26
- def install_chips(chips)
27
- @roml = banks_from(chips).first.compact.first || EMPTY_BANK
28
- reset
29
- end
30
- end
31
- end
32
- end
@@ -1,30 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Cartridge
5
- # Magic Desk: up to 128 8K banks. A write to I/O 1 selects the bank from
6
- # bits 0-6, masked to the size of the ROM and at least four banks, and
7
- # switches the ROM out with bit 7.
8
- class MagicDesk < Cartridge
9
- def poke(addr, value)
10
- return if addr > 0xdeff
11
-
12
- @exrom = value.anybits?(0x80) ? 1 : 0
13
- @roml = bank(@banks, value & @bank_mask)
14
- changed!
15
- end
16
-
17
- def reset
18
- poke(0xde00, 0)
19
- end
20
-
21
- private
22
-
23
- def install_chips(chips)
24
- @banks = banks_from(chips).first
25
- @bank_mask = (bank_mask(@banks) | 0x03) & 0x7f
26
- reset
27
- end
28
- end
29
- end
30
- end