badline 0.12.1 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (565) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +66 -1
  3. data/CLAUDE.md +86 -38
  4. data/CONTRIBUTING.md +4 -3
  5. data/README.md +9 -6
  6. data/doc/library.md +9 -9
  7. data/doc/media.md +2 -1
  8. data/doc/pinned-behaviour.md +134 -105
  9. data/doc/snapshot-format.md +1047 -0
  10. data/doc/snapshots.md +73 -43
  11. data/lib/badline/audio/bare_player.rb +53 -20
  12. data/lib/badline/audio/cli.rb +6 -6
  13. data/lib/badline/audio/jukebox.rb +2 -2
  14. data/lib/badline/audio/machine_player.rb +16 -10
  15. data/lib/badline/{media → audio}/queue.rb +1 -1
  16. data/lib/badline/audio/queued_tune.rb +6 -6
  17. data/lib/badline/audio/renderer.rb +33 -22
  18. data/lib/badline/audio/stereo.rb +1 -1
  19. data/lib/badline/c128/banks.rb +6 -3
  20. data/lib/badline/c128/bus/keyed_state.rb +45 -0
  21. data/lib/badline/c128/bus.rb +35 -20
  22. data/lib/badline/c128/color_lines.rb +2 -2
  23. data/lib/badline/c128/cpu.rb +1 -1
  24. data/lib/badline/c128/drives.rb +14 -34
  25. data/lib/badline/c128/fast_serial.rb +5 -5
  26. data/lib/badline/c128/keyed_modules.rb +117 -0
  27. data/lib/badline/c128/keyed_state.rb +91 -0
  28. data/lib/badline/c128/keys.rb +9 -0
  29. data/lib/badline/c128/mmu.rb +9 -8
  30. data/lib/badline/c128/mmu_pages.rb +21 -1
  31. data/lib/badline/c128/modes.rb +21 -11
  32. data/lib/badline/c128/z80.rb +2 -2
  33. data/lib/badline/c128/z80_turns.rb +1 -1
  34. data/lib/badline/c128.rb +21 -16
  35. data/lib/badline/c64/attachments.rb +42 -0
  36. data/lib/badline/c64/banked_ram/banking.rb +32 -0
  37. data/lib/badline/c64/banked_ram/plus256k.rb +64 -0
  38. data/lib/badline/c64/banked_ram/plus60k.rb +47 -0
  39. data/lib/badline/c64/banked_ram/unexpanded.rb +30 -0
  40. data/lib/badline/c64/banked_ram.rb +23 -0
  41. data/lib/badline/c64/bus/debug_register.rb +32 -0
  42. data/lib/badline/c64/bus/extra_sids.rb +32 -0
  43. data/lib/badline/c64/bus/fittings.rb +40 -0
  44. data/lib/badline/c64/bus/keyed_state.rb +41 -0
  45. data/lib/badline/c64/bus/pla.rb +149 -0
  46. data/lib/badline/c64/bus/roms.rb +41 -0
  47. data/lib/badline/c64/bus/sid_slots.rb +44 -0
  48. data/lib/badline/c64/bus.rb +219 -0
  49. data/lib/badline/c64/cartridge/action_replay.rb +115 -0
  50. data/lib/badline/c64/cartridge/atomic_power.rb +26 -0
  51. data/lib/badline/c64/cartridge/bank.rb +83 -0
  52. data/lib/badline/c64/cartridge/comal80.rb +52 -0
  53. data/lib/badline/c64/cartridge/dinamic.rb +36 -0
  54. data/lib/badline/c64/cartridge/easy_flash.rb +132 -0
  55. data/lib/badline/c64/cartridge/epyx_fastload.rb +73 -0
  56. data/lib/badline/c64/cartridge/final_cartridge3.rb +79 -0
  57. data/lib/badline/c64/cartridge/flash.rb +279 -0
  58. data/lib/badline/c64/cartridge/freezer.rb +35 -0
  59. data/lib/badline/c64/cartridge/fun_play.rb +40 -0
  60. data/lib/badline/c64/cartridge/g_mod2.rb +64 -0
  61. data/lib/badline/c64/cartridge/game_system.rb +42 -0
  62. data/lib/badline/c64/cartridge/geo_ram.rb +65 -0
  63. data/lib/badline/c64/cartridge/kcs_power.rb +69 -0
  64. data/lib/badline/c64/cartridge/keyed_state.rb +393 -0
  65. data/lib/badline/c64/cartridge/mach5.rb +34 -0
  66. data/lib/badline/c64/cartridge/magic_desk.rb +32 -0
  67. data/lib/badline/c64/cartridge/ocean.rb +37 -0
  68. data/lib/badline/c64/cartridge/pagefox.rb +60 -0
  69. data/lib/badline/c64/cartridge/retro_replay.rb +278 -0
  70. data/lib/badline/c64/cartridge/rex_utility.rb +31 -0
  71. data/lib/badline/c64/cartridge/rgcd.rb +50 -0
  72. data/lib/badline/c64/cartridge/simons_basic.rb +37 -0
  73. data/lib/badline/c64/cartridge/standard.rb +17 -0
  74. data/lib/badline/c64/cartridge/super_games.rb +40 -0
  75. data/lib/badline/c64/cartridge/westermann.rb +32 -0
  76. data/lib/badline/c64/cartridge/zaxxon.rb +52 -0
  77. data/lib/badline/c64/cartridge.rb +232 -0
  78. data/lib/badline/c64/color_memory.rb +27 -0
  79. data/lib/badline/{computer → c64}/common.rb +2 -2
  80. data/lib/badline/{computer → c64}/kernal_traps.rb +39 -36
  81. data/lib/badline/c64/keyed_modules.rb +111 -0
  82. data/lib/badline/c64/keyed_state.rb +68 -0
  83. data/lib/badline/c64/reu/dma.rb +271 -0
  84. data/lib/badline/c64/reu/keyed_state.rb +140 -0
  85. data/lib/badline/c64/reu/ram.rb +94 -0
  86. data/lib/badline/c64/reu/trigger.rb +34 -0
  87. data/lib/badline/c64/reu.rb +289 -0
  88. data/lib/badline/c64/true_drives.rb +120 -0
  89. data/lib/badline/{computer.rb → c64.rb} +24 -15
  90. data/lib/badline/chips/cia/fast_forward.rb +62 -0
  91. data/lib/badline/chips/cia/interrupt_register.rb +128 -0
  92. data/lib/badline/chips/cia/keyed_parts.rb +213 -0
  93. data/lib/badline/chips/cia/serial.rb +246 -0
  94. data/lib/badline/chips/cia/time_of_day.rb +210 -0
  95. data/lib/badline/chips/cia/timer.rb +188 -0
  96. data/lib/badline/chips/cia.rb +281 -0
  97. data/lib/badline/chips/cpu/addressing.rb +133 -0
  98. data/lib/badline/chips/cpu/boundary.rb +56 -0
  99. data/lib/badline/chips/cpu/core.rb +183 -0
  100. data/lib/badline/chips/cpu/instruction.rb +338 -0
  101. data/lib/badline/chips/cpu/instruction_set/arithmetic.rb +118 -0
  102. data/lib/badline/chips/cpu/instruction_set/bitwise.rb +130 -0
  103. data/lib/badline/chips/cpu/instruction_set/branch.rb +83 -0
  104. data/lib/badline/chips/cpu/instruction_set/flag.rb +67 -0
  105. data/lib/badline/chips/cpu/instruction_set/illegal.rb +274 -0
  106. data/lib/badline/chips/cpu/instruction_set/inc_dec.rb +73 -0
  107. data/lib/badline/chips/cpu/instruction_set/stack.rb +56 -0
  108. data/lib/badline/chips/cpu/instruction_set/transfer.rb +141 -0
  109. data/lib/badline/chips/cpu/instruction_set.rb +59 -0
  110. data/lib/badline/chips/cpu/interrupts.rb +108 -0
  111. data/lib/badline/chips/cpu/keyed_state.rb +177 -0
  112. data/lib/badline/chips/cpu/microcode.rb +195 -0
  113. data/lib/badline/chips/cpu/operations.rb +90 -0
  114. data/lib/badline/chips/cpu/port.rb +133 -0
  115. data/lib/badline/chips/cpu/stack_operations.rb +84 -0
  116. data/lib/badline/chips/cpu/traps.rb +23 -0
  117. data/lib/badline/chips/cpu.rb +17 -0
  118. data/lib/badline/chips/sid/catch_up.rb +122 -0
  119. data/lib/badline/chips/sid/decimator.rb +68 -0
  120. data/lib/badline/chips/sid/envelope.rb +236 -0
  121. data/lib/badline/chips/sid/filter.rb +227 -0
  122. data/lib/badline/chips/sid/keyed_parts.rb +286 -0
  123. data/lib/badline/chips/sid/voice.rb +69 -0
  124. data/lib/badline/chips/sid/waveform/combined.rb +128 -0
  125. data/lib/badline/chips/sid/waveform/fast_forward.rb +107 -0
  126. data/lib/badline/chips/sid/waveform/noise_writeback.rb +124 -0
  127. data/lib/badline/chips/sid/waveform.rb +305 -0
  128. data/lib/badline/chips/sid.rb +264 -0
  129. data/lib/badline/chips/ted/beam.rb +119 -0
  130. data/lib/badline/chips/ted/timers.rb +66 -0
  131. data/lib/badline/chips/ted.rb +143 -0
  132. data/lib/badline/chips/tia.rb +49 -0
  133. data/lib/badline/chips/vdc/keyed_parts.rb +105 -0
  134. data/lib/badline/{c128 → chips}/vdc/memory.rb +1 -1
  135. data/lib/badline/{c128 → chips}/vdc/painter.rb +1 -13
  136. data/lib/badline/{c128 → chips}/vdc/raster.rb +1 -17
  137. data/lib/badline/{c128 → chips}/vdc/window.rb +1 -10
  138. data/lib/badline/{c128 → chips}/vdc.rb +6 -31
  139. data/lib/badline/chips/via/control_lines.rb +109 -0
  140. data/lib/badline/chips/via/fast_forward.rb +55 -0
  141. data/lib/badline/chips/via/interrupt_register.rb +60 -0
  142. data/lib/badline/chips/via/keyed_parts.rb +163 -0
  143. data/lib/badline/chips/via/shift_register.rb +168 -0
  144. data/lib/badline/chips/via/timer1.rb +120 -0
  145. data/lib/badline/chips/via/timer2.rb +117 -0
  146. data/lib/badline/chips/via.rb +267 -0
  147. data/lib/badline/chips/vic/bank.rb +135 -0
  148. data/lib/badline/chips/vic/border_mask.rb +78 -0
  149. data/lib/badline/chips/vic/collisions.rb +106 -0
  150. data/lib/badline/chips/vic/color_patches.rb +38 -0
  151. data/lib/badline/chips/vic/display_state.rb +168 -0
  152. data/lib/badline/chips/vic/graphics_mode.rb +166 -0
  153. data/lib/badline/chips/vic/graphics_shifter.rb +183 -0
  154. data/lib/badline/chips/vic/keyed_parts.rb +228 -0
  155. data/lib/badline/chips/vic/keyed_sprites.rb +225 -0
  156. data/lib/badline/chips/vic/keyed_state.rb +102 -0
  157. data/lib/badline/chips/vic/register_log.rb +65 -0
  158. data/lib/badline/chips/vic/registers.rb +188 -0
  159. data/lib/badline/chips/vic/sequencer.rb +275 -0
  160. data/lib/badline/chips/vic/sequencer_output.rb +118 -0
  161. data/lib/badline/chips/vic/sprite/internal_bus.rb +59 -0
  162. data/lib/badline/chips/vic/sprite/shifter.rb +148 -0
  163. data/lib/badline/chips/vic/sprite/timing.rb +58 -0
  164. data/lib/badline/chips/vic/sprite.rb +337 -0
  165. data/lib/badline/chips/vic/sprites.rb +281 -0
  166. data/lib/badline/chips/vic.rb +787 -0
  167. data/lib/badline/chips/vic_i/keyed_parts.rb +142 -0
  168. data/lib/badline/{vic20/vic → chips/vic_i}/painter.rb +2 -30
  169. data/lib/badline/chips/vic_i/sound/output.rb +85 -0
  170. data/lib/badline/chips/vic_i/sound.rb +227 -0
  171. data/lib/badline/{vic20/vic → chips/vic_i}/text_window.rb +2 -2
  172. data/lib/badline/{vic20/vic.rb → chips/vic_i.rb} +6 -6
  173. data/lib/badline/chips/z80/arithmetic.rb +119 -0
  174. data/lib/badline/chips/z80/bit_page.rb +57 -0
  175. data/lib/badline/chips/z80/block_io.rb +60 -0
  176. data/lib/badline/chips/z80/block_transfers.rb +61 -0
  177. data/lib/badline/chips/z80/bus_cycles.rb +113 -0
  178. data/lib/badline/chips/z80/core.rb +115 -0
  179. data/lib/badline/chips/z80/exchanges.rb +52 -0
  180. data/lib/badline/chips/z80/extended_page.rb +91 -0
  181. data/lib/badline/chips/z80/flags.rb +39 -0
  182. data/lib/badline/chips/z80/interrupt_acceptance.rb +48 -0
  183. data/lib/badline/chips/z80/jumps.rb +84 -0
  184. data/lib/badline/chips/z80/keyed_state.rb +73 -0
  185. data/lib/badline/chips/z80/loads.rb +100 -0
  186. data/lib/badline/chips/z80/main_page.rb +136 -0
  187. data/lib/badline/chips/z80/registers.rb +122 -0
  188. data/lib/badline/chips/z80/shifts.rb +66 -0
  189. data/lib/badline/chips/z80.rb +13 -0
  190. data/lib/badline/chips.rb +10 -0
  191. data/lib/badline/core.rb +13 -32
  192. data/lib/badline/drives/datasette/keyed_state.rb +38 -0
  193. data/lib/badline/drives/datasette.rb +173 -0
  194. data/lib/badline/drives/engine/core.rb +152 -0
  195. data/lib/badline/drives/engine/fast_serial.rb +75 -0
  196. data/lib/badline/drives/engine/idle.rb +127 -0
  197. data/lib/badline/drives/engine/idle_cpu.rb +30 -0
  198. data/lib/badline/drives/engine/orbit.rb +81 -0
  199. data/lib/badline/drives/engine/serial_lines.rb +72 -0
  200. data/lib/badline/drives/engine/sleep.rb +114 -0
  201. data/lib/badline/drives/engine/vias.rb +86 -0
  202. data/lib/badline/drives/engine/watch.rb +152 -0
  203. data/lib/badline/drives/engine.rb +11 -0
  204. data/lib/badline/drives/model1541/bus.rb +75 -0
  205. data/lib/badline/drives/model1541/byte_ready.rb +50 -0
  206. data/lib/badline/drives/model1541/cpu.rb +13 -0
  207. data/lib/badline/drives/model1541/disk.rb +318 -0
  208. data/lib/badline/drives/model1541/disk_via.rb +38 -0
  209. data/lib/badline/drives/model1541/gcr.rb +59 -0
  210. data/lib/badline/drives/model1541/keyed_state.rb +251 -0
  211. data/lib/badline/drives/model1541/mechanism.rb +313 -0
  212. data/lib/badline/drives/model1541/rotation.rb +123 -0
  213. data/lib/badline/drives/model1541/sector_reader.rb +78 -0
  214. data/lib/badline/drives/model1541/serial_port.rb +20 -0
  215. data/lib/badline/drives/model1541/track.rb +100 -0
  216. data/lib/badline/drives/model1541.rb +80 -0
  217. data/lib/badline/drives/model1571/bus.rb +100 -0
  218. data/lib/badline/drives/model1571/cpu.rb +13 -0
  219. data/lib/badline/drives/model1571/keyed_state.rb +108 -0
  220. data/lib/badline/drives/model1571/serial_port.rb +39 -0
  221. data/lib/badline/drives/model1571/serial_via.rb +27 -0
  222. data/lib/badline/drives/model1571/wd1770.rb +108 -0
  223. data/lib/badline/drives/model1571.rb +141 -0
  224. data/lib/badline/drives/model1581/bus.rb +126 -0
  225. data/lib/badline/drives/model1581/cpu.rb +13 -0
  226. data/lib/badline/drives/model1581/disk.rb +133 -0
  227. data/lib/badline/drives/model1581/keyed_state.rb +280 -0
  228. data/lib/badline/drives/model1581/mechanism.rb +98 -0
  229. data/lib/badline/drives/model1581/serial_port.rb +54 -0
  230. data/lib/badline/drives/model1581/slot.rb +61 -0
  231. data/lib/badline/drives/model1581/track.rb +102 -0
  232. data/lib/badline/drives/model1581/track_bytes.rb +77 -0
  233. data/lib/badline/drives/model1581/wd1772/registers.rb +91 -0
  234. data/lib/badline/drives/model1581/wd1772/sector_writes.rb +75 -0
  235. data/lib/badline/drives/model1581/wd1772/sectors.rb +152 -0
  236. data/lib/badline/drives/model1581/wd1772/stepping.rb +111 -0
  237. data/lib/badline/drives/model1581/wd1772/tracks.rb +127 -0
  238. data/lib/badline/drives/model1581/wd1772/turn.rb +75 -0
  239. data/lib/badline/drives/model1581/wd1772.rb +216 -0
  240. data/lib/badline/drives/model1581.rb +206 -0
  241. data/lib/badline/drives/serial_bus.rb +161 -0
  242. data/lib/badline/drives.rb +8 -0
  243. data/lib/badline/frontend/app.rb +3 -3
  244. data/lib/badline/frontend/boot.rb +4 -4
  245. data/lib/badline/frontend/controls.rb +19 -3
  246. data/lib/badline/frontend/drive_led.rb +44 -21
  247. data/lib/badline/frontend/machine_window.rb +3 -1
  248. data/lib/badline/frontend/menu/menu_dialogs.rb +2 -2
  249. data/lib/badline/frontend/player/filter_view.rb +1 -1
  250. data/lib/badline/frontend/player/player_controller.rb +2 -2
  251. data/lib/badline/frontend/player/player_screen.rb +1 -0
  252. data/lib/badline/frontend/player/theme.rb +7 -7
  253. data/lib/badline/frontend/snapshots.rb +12 -1
  254. data/lib/badline/frontend/timeline.rb +30 -12
  255. data/lib/badline/input/control_ports.rb +78 -0
  256. data/lib/badline/input/joystick.rb +27 -0
  257. data/lib/badline/input/keyboard.rb +114 -0
  258. data/lib/badline/input/matrix_typist.rb +98 -0
  259. data/lib/badline/input.rb +4 -0
  260. data/lib/badline/kernal_trap/chrout.rb +45 -0
  261. data/lib/badline/kernal_trap/{drive → dos}/block_commands.rb +1 -1
  262. data/lib/badline/kernal_trap/dos/channel.rb +156 -0
  263. data/lib/badline/kernal_trap/{drive → dos}/channels.rb +1 -26
  264. data/lib/badline/kernal_trap/{drive → dos}/memory.rb +1 -10
  265. data/lib/badline/kernal_trap/{drive → dos}/parameters.rb +1 -1
  266. data/lib/badline/kernal_trap/{drive → dos}/status.rb +1 -9
  267. data/lib/badline/kernal_trap/{drive → dos}/write_file.rb +1 -19
  268. data/lib/badline/kernal_trap/{drive → dos}/writes.rb +1 -1
  269. data/lib/badline/kernal_trap/{drive.rb → dos.rb} +9 -27
  270. data/lib/badline/kernal_trap/file_routine.rb +4 -4
  271. data/lib/badline/kernal_trap/keyed_state.rb +150 -0
  272. data/lib/badline/kernal_trap/layout.rb +75 -11
  273. data/lib/badline/kernal_trap/load.rb +19 -21
  274. data/lib/badline/kernal_trap/routine.rb +12 -0
  275. data/lib/badline/kernal_trap/save.rb +12 -22
  276. data/lib/badline/kernal_trap/serial.rb +8 -24
  277. data/lib/badline/kernal_trap.rb +3 -2
  278. data/lib/badline/machine/clocking.rb +1 -1
  279. data/lib/badline/machine/keyboard_buffer.rb +49 -0
  280. data/lib/badline/machine/settling.rb +29 -0
  281. data/lib/badline/machine.rb +10 -7
  282. data/lib/badline/media/boot_disk.rb +14 -2
  283. data/lib/badline/media/extensions.rb +10 -0
  284. data/lib/badline/media/true_drive.rb +1 -1
  285. data/lib/badline/media/tune.rb +2 -2
  286. data/lib/badline/media.rb +3 -3
  287. data/lib/badline/memory.rb +3 -6
  288. data/lib/badline/model.rb +1 -1
  289. data/lib/badline/options/family.rb +5 -2
  290. data/lib/badline/options/help.rb +42 -16
  291. data/lib/badline/options/table.rb +2 -0
  292. data/lib/badline/options/validation.rb +2 -0
  293. data/lib/badline/options.rb +6 -1
  294. data/lib/badline/plus4/acia.rb +45 -0
  295. data/lib/badline/plus4/bus.rb +312 -0
  296. data/lib/badline/plus4/cpu.rb +10 -0
  297. data/lib/badline/plus4/cpu_port.rb +93 -0
  298. data/lib/badline/plus4/keyboard_port.rb +51 -0
  299. data/lib/badline/plus4/model.rb +38 -0
  300. data/lib/badline/plus4/user_port.rb +31 -0
  301. data/lib/badline/plus4.rb +164 -0
  302. data/lib/badline/roms/README +44 -6
  303. data/lib/badline/roms/plus4/basic.rom +0 -0
  304. data/lib/badline/roms/plus4/function-high.rom +0 -0
  305. data/lib/badline/roms/plus4/function-low.rom +0 -0
  306. data/lib/badline/roms/plus4/kernal-ntsc.rom +0 -0
  307. data/lib/badline/roms/plus4/kernal-pal.rom +0 -0
  308. data/lib/badline/sdl.rb +1 -0
  309. data/lib/badline/{storage/sid_file.rb → sid_tune/file.rb} +3 -3
  310. data/lib/badline/{storage → sid_tune}/hvsc.rb +7 -7
  311. data/lib/badline/{storage → sid_tune}/song_lengths.rb +2 -2
  312. data/lib/badline/{storage → sid_tune}/stil/credit.rb +1 -1
  313. data/lib/badline/{storage → sid_tune}/stil.rb +3 -3
  314. data/lib/badline/sid_tune.rb +6 -0
  315. data/lib/badline/snapshot/c128_setup.rb +32 -0
  316. data/lib/badline/snapshot/c64_setup.rb +83 -0
  317. data/lib/badline/snapshot/container.rb +4 -0
  318. data/lib/badline/snapshot/field_doc/markdown.rb +112 -0
  319. data/lib/badline/snapshot/field_doc.rb +109 -0
  320. data/lib/badline/snapshot/image.rb +132 -46
  321. data/lib/badline/snapshot/keyed/cursor.rb +40 -0
  322. data/lib/badline/snapshot/keyed/modules.rb +66 -0
  323. data/lib/badline/snapshot/keyed/reader.rb +188 -0
  324. data/lib/badline/snapshot/keyed/recorder.rb +88 -0
  325. data/lib/badline/snapshot/keyed/report.rb +26 -0
  326. data/lib/badline/snapshot/keyed/writer.rb +55 -0
  327. data/lib/badline/snapshot/keyed.rb +64 -0
  328. data/lib/badline/snapshot/machine_state.rb +17 -64
  329. data/lib/badline/snapshot/storage_setup.rb +63 -0
  330. data/lib/badline/snapshot/vic20_setup.rb +28 -0
  331. data/lib/badline/snapshot/vice/c64_mem.rb +1 -1
  332. data/lib/badline/snapshot/vice/restore.rb +1 -1
  333. data/lib/badline/snapshot/vice/reu1764.rb +3 -3
  334. data/lib/badline/snapshot/vice/reu_fields.rb +40 -0
  335. data/lib/badline/snapshot/vice.rb +13 -35
  336. data/lib/badline/snapshot.rb +44 -22
  337. data/lib/badline/storage/crt_file.rb +3 -1
  338. data/lib/badline/storage/d64_image.rb +0 -2
  339. data/lib/badline/storage/d71_image.rb +0 -2
  340. data/lib/badline/storage/d81_image.rb +0 -2
  341. data/lib/badline/storage/disk_image.rb +3 -6
  342. data/lib/badline/storage/g64_image.rb +10 -5
  343. data/lib/badline/storage/host_directory.rb +0 -5
  344. data/lib/badline/storage/t64.rb +2 -8
  345. data/lib/badline/storage/tap.rb +43 -15
  346. data/lib/badline/storage/unavailable.rb +1 -1
  347. data/lib/badline/storage.rb +0 -37
  348. data/lib/badline/support/c128_checkpoint.rb +39 -0
  349. data/lib/badline/support/checkpoint.rb +108 -0
  350. data/lib/badline/support/vic20_checkpoint.rb +38 -0
  351. data/lib/badline/support.rb +5 -0
  352. data/lib/badline/version.rb +1 -1
  353. data/lib/badline/vic20/attachments.rb +8 -5
  354. data/lib/badline/vic20/bus/keyed_state.rb +52 -0
  355. data/lib/badline/vic20/bus.rb +2 -25
  356. data/lib/badline/vic20/cpu.rb +1 -1
  357. data/lib/badline/vic20/keyed_modules.rb +73 -0
  358. data/lib/badline/vic20/keyed_state.rb +45 -0
  359. data/lib/badline/vic20/port_wiring.rb +4 -4
  360. data/lib/badline/vic20/user_via_ports.rb +2 -2
  361. data/lib/badline/vic20.rb +22 -17
  362. data/lib/badline.rb +1 -0
  363. metadata +271 -228
  364. data/lib/badline/address_bus/extra_sids.rb +0 -30
  365. data/lib/badline/address_bus/fittings.rb +0 -38
  366. data/lib/badline/address_bus/pla.rb +0 -147
  367. data/lib/badline/address_bus/roms.rb +0 -39
  368. data/lib/badline/address_bus/saved_state.rb +0 -66
  369. data/lib/badline/address_bus/sid_slots.rb +0 -42
  370. data/lib/badline/address_bus.rb +0 -216
  371. data/lib/badline/c128/bus_state.rb +0 -53
  372. data/lib/badline/c128/saved_state.rb +0 -143
  373. data/lib/badline/cartridge/action_replay.rb +0 -126
  374. data/lib/badline/cartridge/atomic_power.rb +0 -24
  375. data/lib/badline/cartridge/bank.rb +0 -81
  376. data/lib/badline/cartridge/comal80.rb +0 -50
  377. data/lib/badline/cartridge/dinamic.rb +0 -34
  378. data/lib/badline/cartridge/easy_flash.rb +0 -145
  379. data/lib/badline/cartridge/epyx_fastload.rb +0 -79
  380. data/lib/badline/cartridge/final_cartridge3.rb +0 -89
  381. data/lib/badline/cartridge/flash.rb +0 -306
  382. data/lib/badline/cartridge/freezer.rb +0 -33
  383. data/lib/badline/cartridge/fun_play.rb +0 -38
  384. data/lib/badline/cartridge/g_mod2.rb +0 -74
  385. data/lib/badline/cartridge/game_system.rb +0 -40
  386. data/lib/badline/cartridge/geo_ram.rb +0 -79
  387. data/lib/badline/cartridge/kcs_power.rb +0 -75
  388. data/lib/badline/cartridge/mach5.rb +0 -32
  389. data/lib/badline/cartridge/magic_desk.rb +0 -30
  390. data/lib/badline/cartridge/ocean.rb +0 -35
  391. data/lib/badline/cartridge/pagefox.rb +0 -68
  392. data/lib/badline/cartridge/retro_replay.rb +0 -320
  393. data/lib/badline/cartridge/rex_utility.rb +0 -29
  394. data/lib/badline/cartridge/rgcd.rb +0 -58
  395. data/lib/badline/cartridge/simons_basic.rb +0 -35
  396. data/lib/badline/cartridge/standard.rb +0 -15
  397. data/lib/badline/cartridge/super_games.rb +0 -48
  398. data/lib/badline/cartridge/westermann.rb +0 -30
  399. data/lib/badline/cartridge/zaxxon.rb +0 -66
  400. data/lib/badline/cartridge.rb +0 -303
  401. data/lib/badline/checkpoint.rb +0 -98
  402. data/lib/badline/chrout_trap.rb +0 -43
  403. data/lib/badline/cia/fast_forward.rb +0 -60
  404. data/lib/badline/cia/interrupt_register.rb +0 -143
  405. data/lib/badline/cia/serial.rb +0 -275
  406. data/lib/badline/cia/state.rb +0 -47
  407. data/lib/badline/cia/timer.rb +0 -206
  408. data/lib/badline/cia.rb +0 -279
  409. data/lib/badline/color_memory.rb +0 -25
  410. data/lib/badline/computer/attachments.rb +0 -88
  411. data/lib/badline/computer/saved_state.rb +0 -117
  412. data/lib/badline/computer/true_drives.rb +0 -69
  413. data/lib/badline/control_ports.rb +0 -76
  414. data/lib/badline/cpu/addressing.rb +0 -131
  415. data/lib/badline/cpu/boundary.rb +0 -54
  416. data/lib/badline/cpu/core.rb +0 -165
  417. data/lib/badline/cpu/microcode.rb +0 -177
  418. data/lib/badline/cpu/operations.rb +0 -88
  419. data/lib/badline/cpu/saved_state.rb +0 -115
  420. data/lib/badline/cpu/stack_operations.rb +0 -82
  421. data/lib/badline/cpu.rb +0 -10
  422. data/lib/badline/cpu_port.rb +0 -112
  423. data/lib/badline/datasette.rb +0 -161
  424. data/lib/badline/debug_register.rb +0 -28
  425. data/lib/badline/drive/core.rb +0 -147
  426. data/lib/badline/drive/fast_serial.rb +0 -73
  427. data/lib/badline/drive/idle.rb +0 -125
  428. data/lib/badline/drive/idle_cpu.rb +0 -28
  429. data/lib/badline/drive/orbit.rb +0 -79
  430. data/lib/badline/drive/serial_lines.rb +0 -73
  431. data/lib/badline/drive/sleep.rb +0 -112
  432. data/lib/badline/drive/vias.rb +0 -84
  433. data/lib/badline/drive/watch.rb +0 -150
  434. data/lib/badline/drive.rb +0 -11
  435. data/lib/badline/drive1541/bus.rb +0 -86
  436. data/lib/badline/drive1541/byte_ready.rb +0 -48
  437. data/lib/badline/drive1541/cpu.rb +0 -11
  438. data/lib/badline/drive1541/disk.rb +0 -315
  439. data/lib/badline/drive1541/disk_state.rb +0 -86
  440. data/lib/badline/drive1541/disk_via.rb +0 -36
  441. data/lib/badline/drive1541/gcr.rb +0 -57
  442. data/lib/badline/drive1541/mechanism.rb +0 -313
  443. data/lib/badline/drive1541/mechanism_state.rb +0 -68
  444. data/lib/badline/drive1541/rotation.rb +0 -121
  445. data/lib/badline/drive1541/sector_reader.rb +0 -76
  446. data/lib/badline/drive1541/serial_port.rb +0 -18
  447. data/lib/badline/drive1541/track.rb +0 -98
  448. data/lib/badline/drive1541.rb +0 -111
  449. data/lib/badline/drive1571/bus.rb +0 -111
  450. data/lib/badline/drive1571/cpu.rb +0 -11
  451. data/lib/badline/drive1571/serial_port.rb +0 -37
  452. data/lib/badline/drive1571/serial_via.rb +0 -25
  453. data/lib/badline/drive1571/wd1770.rb +0 -120
  454. data/lib/badline/drive1571.rb +0 -175
  455. data/lib/badline/drive1581/bus.rb +0 -137
  456. data/lib/badline/drive1581/cpu.rb +0 -11
  457. data/lib/badline/drive1581/disk.rb +0 -135
  458. data/lib/badline/drive1581/disk_state.rb +0 -87
  459. data/lib/badline/drive1581/mechanism.rb +0 -117
  460. data/lib/badline/drive1581/serial_port.rb +0 -52
  461. data/lib/badline/drive1581/slot.rb +0 -78
  462. data/lib/badline/drive1581/track.rb +0 -100
  463. data/lib/badline/drive1581/track_bytes.rb +0 -75
  464. data/lib/badline/drive1581/wd1772/registers.rb +0 -89
  465. data/lib/badline/drive1581/wd1772/sector_writes.rb +0 -73
  466. data/lib/badline/drive1581/wd1772/sectors.rb +0 -150
  467. data/lib/badline/drive1581/wd1772/state.rb +0 -66
  468. data/lib/badline/drive1581/wd1772/stepping.rb +0 -109
  469. data/lib/badline/drive1581/wd1772/tracks.rb +0 -125
  470. data/lib/badline/drive1581/wd1772/turn.rb +0 -73
  471. data/lib/badline/drive1581/wd1772.rb +0 -216
  472. data/lib/badline/drive1581.rb +0 -233
  473. data/lib/badline/iec_bus.rb +0 -159
  474. data/lib/badline/instruction.rb +0 -334
  475. data/lib/badline/instruction_set/arithmetic.rb +0 -114
  476. data/lib/badline/instruction_set/bitwise.rb +0 -126
  477. data/lib/badline/instruction_set/branch.rb +0 -79
  478. data/lib/badline/instruction_set/flag.rb +0 -63
  479. data/lib/badline/instruction_set/illegal.rb +0 -270
  480. data/lib/badline/instruction_set/inc_dec.rb +0 -69
  481. data/lib/badline/instruction_set/stack.rb +0 -52
  482. data/lib/badline/instruction_set/transfer.rb +0 -137
  483. data/lib/badline/instruction_set.rb +0 -55
  484. data/lib/badline/interrupts.rb +0 -104
  485. data/lib/badline/joystick.rb +0 -25
  486. data/lib/badline/kernal_trap/channel.rb +0 -181
  487. data/lib/badline/keyboard.rb +0 -112
  488. data/lib/badline/keyboard_buffer.rb +0 -33
  489. data/lib/badline/ram_expansion/banking.rb +0 -30
  490. data/lib/badline/ram_expansion/plus256k.rb +0 -54
  491. data/lib/badline/ram_expansion/plus60k.rb +0 -43
  492. data/lib/badline/ram_expansion/unexpanded.rb +0 -28
  493. data/lib/badline/ram_expansion.rb +0 -21
  494. data/lib/badline/reu/dma/saved_state.rb +0 -50
  495. data/lib/badline/reu/dma.rb +0 -273
  496. data/lib/badline/reu/ram.rb +0 -107
  497. data/lib/badline/reu/saved_state.rb +0 -80
  498. data/lib/badline/reu/trigger.rb +0 -32
  499. data/lib/badline/reu.rb +0 -289
  500. data/lib/badline/sid/catch_up.rb +0 -120
  501. data/lib/badline/sid/decimator.rb +0 -64
  502. data/lib/badline/sid/envelope/state.rb +0 -68
  503. data/lib/badline/sid/envelope.rb +0 -239
  504. data/lib/badline/sid/filter.rb +0 -263
  505. data/lib/badline/sid/voice.rb +0 -77
  506. data/lib/badline/sid/waveform/combined.rb +0 -126
  507. data/lib/badline/sid/waveform/fast_forward.rb +0 -105
  508. data/lib/badline/sid/waveform/noise_writeback.rb +0 -122
  509. data/lib/badline/sid/waveform/state.rb +0 -66
  510. data/lib/badline/sid/waveform.rb +0 -305
  511. data/lib/badline/sid.rb +0 -303
  512. data/lib/badline/snapshot/setup.rb +0 -75
  513. data/lib/badline/snapshot/state.rb +0 -189
  514. data/lib/badline/time_of_day.rb +0 -228
  515. data/lib/badline/traps.rb +0 -19
  516. data/lib/badline/via/control_lines.rb +0 -122
  517. data/lib/badline/via/fast_forward.rb +0 -53
  518. data/lib/badline/via/interrupt_register.rb +0 -67
  519. data/lib/badline/via/shift_register.rb +0 -180
  520. data/lib/badline/via/state.rb +0 -42
  521. data/lib/badline/via/timer1.rb +0 -131
  522. data/lib/badline/via/timer2.rb +0 -133
  523. data/lib/badline/via.rb +0 -266
  524. data/lib/badline/vic/bank.rb +0 -133
  525. data/lib/badline/vic/border_mask.rb +0 -86
  526. data/lib/badline/vic/collisions.rb +0 -115
  527. data/lib/badline/vic/color_patches.rb +0 -47
  528. data/lib/badline/vic/display_state.rb +0 -185
  529. data/lib/badline/vic/graphics_mode.rb +0 -164
  530. data/lib/badline/vic/graphics_shifter.rb +0 -207
  531. data/lib/badline/vic/register_log.rb +0 -81
  532. data/lib/badline/vic/registers.rb +0 -195
  533. data/lib/badline/vic/sequencer.rb +0 -275
  534. data/lib/badline/vic/sequencer_output.rb +0 -116
  535. data/lib/badline/vic/sequencer_state.rb +0 -89
  536. data/lib/badline/vic/sprite/internal_bus.rb +0 -68
  537. data/lib/badline/vic/sprite/saved_state.rb +0 -64
  538. data/lib/badline/vic/sprite/shifter.rb +0 -146
  539. data/lib/badline/vic/sprite/timing.rb +0 -56
  540. data/lib/badline/vic/sprite.rb +0 -337
  541. data/lib/badline/vic/sprites.rb +0 -282
  542. data/lib/badline/vic/sprites_state.rb +0 -57
  543. data/lib/badline/vic.rb +0 -853
  544. data/lib/badline/vic20/saved_state.rb +0 -124
  545. data/lib/badline/vic20/sound/output.rb +0 -83
  546. data/lib/badline/vic20/sound.rb +0 -233
  547. data/lib/badline/vic20/vic/saved_state.rb +0 -55
  548. data/lib/badline/z80/arithmetic.rb +0 -117
  549. data/lib/badline/z80/bit_page.rb +0 -55
  550. data/lib/badline/z80/block_io.rb +0 -58
  551. data/lib/badline/z80/block_transfers.rb +0 -59
  552. data/lib/badline/z80/bus_cycles.rb +0 -111
  553. data/lib/badline/z80/core.rb +0 -113
  554. data/lib/badline/z80/exchanges.rb +0 -50
  555. data/lib/badline/z80/extended_page.rb +0 -89
  556. data/lib/badline/z80/flags.rb +0 -37
  557. data/lib/badline/z80/interrupt_acceptance.rb +0 -46
  558. data/lib/badline/z80/jumps.rb +0 -82
  559. data/lib/badline/z80/loads.rb +0 -98
  560. data/lib/badline/z80/main_page.rb +0 -134
  561. data/lib/badline/z80/registers.rb +0 -120
  562. data/lib/badline/z80/saved_state.rb +0 -69
  563. data/lib/badline/z80/shifts.rb +0 -64
  564. data/lib/badline/z80.rb +0 -11
  565. /data/lib/badline/snapshot/{fields.rb → vice/fields.rb} +0 -0
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Chips
5
+ class CPU
6
+ module InstructionSet
7
+ module Bitwise
8
+ # Performs bitwise AND on accumulator with memory.
9
+ #
10
+ # Opcodes:
11
+ # $21 - indirect_x - 6 cycles
12
+ # $25 - zeropage - 3 cycles
13
+ # $29 - immediate - 2 cycles
14
+ # $2D - absolute - 4 cycles
15
+ # $31 - indirect_y - 5+ cycles
16
+ # $35 - zeropage_x - 4 cycles
17
+ # $39 - absolute_y - 4+ cycles
18
+ # $3D - absolute_x - 4+ cycles
19
+ def and(_addr, value)
20
+ @a &= value
21
+ update_number_flags(@a)
22
+ end
23
+
24
+ # Arithmetic shift left. Shifts bits left by one position.
25
+ #
26
+ # Opcodes:
27
+ # $06 - zeropage - 5 cycles
28
+ # $0A - accumulator- 2 cycles
29
+ # $0E - absolute - 6 cycles
30
+ # $16 - zeropage_x - 6 cycles
31
+ # $1E - absolute_x - 7 cycles
32
+ def asl(addr, value)
33
+ result = (value << 1) & 0xff
34
+ status.carry = value[7]
35
+ write_modified(addr, result)
36
+ update_number_flags(result)
37
+ end
38
+
39
+ # Tests bits in memory with accumulator.
40
+ #
41
+ # Opcodes:
42
+ # $24 - zeropage - 3 cycles
43
+ # $2C - absolute - 4 cycles
44
+ def bit(_addr, value)
45
+ status.value = ((status.value & 0b00111111) +
46
+ (value & 0b11000000)).to_i
47
+ status.zero = (a & value).nobits?(0xff)
48
+ end
49
+
50
+ # Performs bitwise XOR on accumulator with memory.
51
+ #
52
+ # Opcodes:
53
+ # $41 - indirect_x - 6 cycles
54
+ # $45 - zeropage - 3 cycles
55
+ # $49 - immediate - 2 cycles
56
+ # $4D - absolute - 4 cycles
57
+ # $51 - indirect_y - 5+ cycles
58
+ # $55 - zeropage_x - 4 cycles
59
+ # $59 - absolute_y - 4+ cycles
60
+ # $5D - absolute_x - 4+ cycles
61
+ def eor(_addr, value)
62
+ @a = (@a ^ value) & 0xff
63
+ update_number_flags(@a)
64
+ end
65
+
66
+ # Logical shift right. Shifts bits right by one position.
67
+ #
68
+ # Opcodes:
69
+ # $46 - zeropage - 5 cycles
70
+ # $4A - accumulator- 2 cycles
71
+ # $4E - absolute - 6 cycles
72
+ # $56 - zeropage_x - 6 cycles
73
+ # $5E - absolute_x - 7 cycles
74
+ def lsr(addr, value)
75
+ result = (value >> 1) & 0xff
76
+ status.carry = value[0]
77
+ write_modified(addr, result)
78
+ update_number_flags(result)
79
+ end
80
+
81
+ # Performs bitwise OR on accumulator with memory.
82
+ #
83
+ # Opcodes:
84
+ # $01 - indirect_x - 6 cycles
85
+ # $05 - zeropage - 3 cycles
86
+ # $09 - immediate - 2 cycles
87
+ # $0D - absolute - 4 cycles
88
+ # $11 - indirect_y - 5+ cycles
89
+ # $15 - zeropage_x - 4 cycles
90
+ # $19 - absolute_y - 4+ cycles
91
+ # $1D - absolute_x - 4+ cycles
92
+ def ora(_addr, value)
93
+ @a |= value
94
+ update_number_flags(@a)
95
+ end
96
+
97
+ # Rotate left through carry.
98
+ #
99
+ # Opcodes:
100
+ # $26 - zeropage - 5 cycles
101
+ # $2A - accumulator- 2 cycles
102
+ # $2E - absolute - 6 cycles
103
+ # $36 - zeropage_x - 6 cycles
104
+ # $3E - absolute_x - 7 cycles
105
+ def rol(addr, value)
106
+ result = ((value << 1) + status.carry) & 0xff
107
+ status.carry = value[7]
108
+ write_modified(addr, result)
109
+ update_number_flags(result)
110
+ end
111
+
112
+ # Rotate right through carry.
113
+ #
114
+ # Opcodes:
115
+ # $66 - zeropage - 5 cycles
116
+ # $6A - accumulator- 2 cycles
117
+ # $6E - absolute - 6 cycles
118
+ # $76 - zeropage_x - 6 cycles
119
+ # $7E - absolute_x - 7 cycles
120
+ def ror(addr, value)
121
+ result = ((value >> 1) + (status.carry? ? 0x80 : 0)) & 0xff
122
+ status.carry = value[0]
123
+ write_modified(addr, result)
124
+ update_number_flags(result)
125
+ end
126
+ end
127
+ end
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,83 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Chips
5
+ class CPU
6
+ module InstructionSet
7
+ module Branch
8
+ # Branch if carry clear (C=0).
9
+ #
10
+ # Opcodes:
11
+ # $90 - relative - 2+ cycles
12
+ def bcc(_addr, _value)
13
+ take_branch unless status.carry?
14
+ end
15
+
16
+ # Branch if carry set (C=1).
17
+ #
18
+ # Opcodes:
19
+ # $B0 - relative - 2+ cycles
20
+ def bcs(_addr, _value)
21
+ take_branch if status.carry?
22
+ end
23
+
24
+ # Branch if equal (Z=1).
25
+ #
26
+ # Opcodes:
27
+ # $F0 - relative - 2+ cycles
28
+ def beq(_addr, _value)
29
+ take_branch if status.zero?
30
+ end
31
+
32
+ # Branch if minus (N=1).
33
+ #
34
+ # Opcodes:
35
+ # $30 - relative - 2+ cycles
36
+ def bmi(_addr, _value)
37
+ take_branch if status.negative?
38
+ end
39
+
40
+ # Branch if not equal (Z=0).
41
+ #
42
+ # Opcodes:
43
+ # $D0 - relative - 2+ cycles
44
+ def bne(_addr, _value)
45
+ take_branch unless status.zero?
46
+ end
47
+
48
+ # Branch if plus (N=0).
49
+ #
50
+ # Opcodes:
51
+ # $10 - relative - 2+ cycles
52
+ def bpl(_addr, _value)
53
+ take_branch unless status.negative?
54
+ end
55
+
56
+ # Branch if overflow clear (V=0).
57
+ #
58
+ # Opcodes:
59
+ # $50 - relative - 2+ cycles
60
+ def bvc(_addr, _value)
61
+ take_branch unless status.overflow?
62
+ end
63
+
64
+ # Branch if overflow set (V=1).
65
+ #
66
+ # Opcodes:
67
+ # $70 - relative - 2+ cycles
68
+ def bvs(_addr, _value)
69
+ take_branch if status.overflow?
70
+ end
71
+
72
+ private
73
+
74
+ # Marks the branch as taken. Operations#op_relative reads the flag
75
+ # and runs the extra cycles.
76
+ def take_branch
77
+ @branch_taken = true
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,67 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Chips
5
+ class CPU
6
+ module InstructionSet
7
+ module Flag
8
+ # Clear carry flag.
9
+ #
10
+ # Opcodes:
11
+ # $18 - implied - 2 cycles
12
+ def clc(_addr, _value)
13
+ status.carry = false
14
+ end
15
+
16
+ # Clear decimal mode flag.
17
+ #
18
+ # Opcodes:
19
+ # $D8 - implied - 2 cycles
20
+ def cld(_addr, _value)
21
+ status.decimal = false
22
+ end
23
+
24
+ # Clear interrupt disable flag.
25
+ #
26
+ # Opcodes:
27
+ # $58 - implied - 2 cycles
28
+ def cli(_addr, _value)
29
+ status.interrupt = false
30
+ end
31
+
32
+ # Clear overflow flag.
33
+ #
34
+ # Opcodes:
35
+ # $B8 - implied - 2 cycles
36
+ def clv(_addr, _value)
37
+ status.overflow = false
38
+ end
39
+
40
+ # Set carry flag.
41
+ #
42
+ # Opcodes:
43
+ # $38 - implied - 2 cycles
44
+ def sec(_addr, _value)
45
+ status.carry = true
46
+ end
47
+
48
+ # Set decimal mode flag.
49
+ #
50
+ # Opcodes:
51
+ # $F8 - implied - 2 cycles
52
+ def sed(_addr, _value)
53
+ status.decimal = true
54
+ end
55
+
56
+ # Set interrupt disable flag.
57
+ #
58
+ # Opcodes:
59
+ # $78 - implied - 2 cycles
60
+ def sei(_addr, _value)
61
+ status.interrupt = true
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,274 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Chips
5
+ class CPU
6
+ module InstructionSet
7
+ # Illegal opcodes
8
+ module Illegal
9
+ # Combination of AND and LSR.
10
+ #
11
+ # Opcodes:
12
+ # $4B - immediate - 2 cycles
13
+ def alr(_addr, value)
14
+ @a &= value
15
+ status.carry = @a[0]
16
+ @a = (@a >> 1) & 0xff
17
+ update_number_flags(@a)
18
+ end
19
+
20
+ # Combination of AND where carry is set to bit 7 of result.
21
+ #
22
+ # Opcodes:
23
+ # $0B, $2B - immediate - 2 cycles
24
+ def anc(addr, value)
25
+ self.and(addr, value)
26
+ status.carry = status.negative
27
+ end
28
+
29
+ # Unstable instruction. AND's value with A|magic_const and X.
30
+ # Magic constant varies by CPU. A VIC stall between the opcode and
31
+ # operand fetches clears its bits 0 and 4.
32
+ #
33
+ # Opcodes:
34
+ # $8B - immediate - 2 cycles
35
+ def ane(_addr, value)
36
+ magic_const = stalled_before_this_cycle? ? @ane_constant & 0xee : @ane_constant
37
+ @a = (a | magic_const) & x & value
38
+ update_number_flags(@a)
39
+ end
40
+
41
+ # Combination of AND and ROR.
42
+ #
43
+ # Opcodes:
44
+ # $6B - immediate - 2 cycles
45
+ def arr(_addr, value)
46
+ tmp = a & value
47
+ result = (tmp >> 1) | (status.carry? ? 0x80 : 0)
48
+ status.zero = result.zero?
49
+ status.negative = status.carry
50
+
51
+ if status.decimal?
52
+ status.overflow = (result ^ tmp).anybits?(0x40)
53
+
54
+ # Low nibble
55
+ result = (result & 0xf0) | ((result + 0x06) & 0x0f) if ((tmp & 0x0f) + (tmp & 0x01)) > 0x05
56
+
57
+ # High nibble + carry
58
+ if ((tmp & 0xf0) + (tmp & 0x10)) > 0x50
59
+ result = (result & 0x0f) | ((result + 0x60) & 0xf0)
60
+ status.carry = true
61
+ else
62
+ status.carry = false
63
+ end
64
+ else
65
+ status.carry = tmp[7] == 1
66
+ status.overflow = tmp[7] ^ tmp[6]
67
+ end
68
+
69
+ @a = result
70
+ end
71
+
72
+ # Combination of DEC and CMP operations.
73
+ #
74
+ # Opcodes:
75
+ # $C3 - indirect_x - 8 cycles
76
+ # $C7 - zeropage - 5 cycles
77
+ # $CF - absolute - 6 cycles
78
+ # $D3 - indirect_y - 8 cycles
79
+ # $D7 - zeropage_x - 6 cycles
80
+ # $DB - absolute_y - 7 cycles
81
+ # $DF - absolute_x - 7 cycles
82
+ def dcp(addr, value)
83
+ cmp(addr, dec(addr, value))
84
+ end
85
+
86
+ # Combination of INC and SBC operations.
87
+ #
88
+ # Opcodes:
89
+ # $E3 - indirect_x - 8 cycles
90
+ # $E7 - zeropage - 5 cycles
91
+ # $EF - absolute - 6 cycles
92
+ # $F3 - indirect_y - 8 cycles
93
+ # $F7 - zeropage_x - 6 cycles
94
+ # $FB - absolute_y - 7 cycles
95
+ # $FF - absolute_x - 7 cycles
96
+ def isc(addr, value)
97
+ sbc(addr, inc(addr, value))
98
+ end
99
+
100
+ # Loads A and S with value AND stack pointer.
101
+ #
102
+ # Opcodes:
103
+ # $BB - absolute_y - 4 cycles
104
+ def las(_addr, value)
105
+ @a = @x = @stack_pointer = value & stack_pointer
106
+ update_number_flags(@a)
107
+ end
108
+
109
+ # Combination of LDA and LDX with same value.
110
+ #
111
+ # Opcodes:
112
+ # $A3 - indirect_x - 6 cycles
113
+ # $A7 - zeropage - 3 cycles
114
+ # $AF - absolute - 4 cycles
115
+ # $B3 - indirect_y - 5+ cycles
116
+ # $B7 - zeropage_y - 4 cycles
117
+ # $BF - absolute_y - 4+ cycles
118
+ def lax(_addr, value)
119
+ @a = @x = value
120
+
121
+ update_number_flags(@a)
122
+ end
123
+
124
+ # Unstable immediate form of LAX. Loads A and X with
125
+ # (A | magic_const) AND value. Magic constant varies by CPU.
126
+ #
127
+ # Opcodes:
128
+ # $AB - immediate - 2 cycles
129
+ def lxa(_addr, value)
130
+ magic_const = 0xee
131
+ @a = @x = (a | magic_const) & value
132
+ update_number_flags(@a)
133
+ end
134
+
135
+ # Special no-operation instruction that does not consume a CPU cycle,
136
+ # unlike the standard NOP. Used by some illegal opcodes.
137
+ #
138
+ # Opcodes:
139
+ # $80, $82, $89, $C2, $E2 - immediate - 2 cycles
140
+ def nop_nocycle(_addr, _value); end
141
+
142
+ # Combination of ROL and AND operations.
143
+ #
144
+ # Opcodes:
145
+ # $23 - indirect_x - 8 cycles
146
+ # $27 - zeropage - 5 cycles
147
+ # $2F - absolute - 6 cycles
148
+ # $33 - indirect_y - 8 cycles
149
+ # $37 - zeropage_x - 6 cycles
150
+ # $3B - absolute_y - 7 cycles
151
+ # $3F - absolute_x - 7 cycles
152
+ def rla(addr, value)
153
+ self.and(addr, rol(addr, value))
154
+ end
155
+
156
+ # Combination of ROR and ADC operations.
157
+ #
158
+ # Opcodes:
159
+ # $63 - indirect_x - 8 cycles
160
+ # $67 - zeropage - 5 cycles
161
+ # $6F - absolute - 6 cycles
162
+ # $73 - indirect_y - 8 cycles
163
+ # $77 - zeropage_x - 6 cycles
164
+ # $7B - absolute_y - 7 cycles
165
+ # $7F - absolute_x - 7 cycles
166
+ def rra(addr, value)
167
+ adc(addr, ror(addr, value))
168
+ end
169
+
170
+ # Store A AND X.
171
+ #
172
+ # Opcodes:
173
+ # $83 - indirect_x - 6 cycles
174
+ # $87 - zeropage - 3 cycles
175
+ # $8F - absolute - 4 cycles
176
+ # $97 - zeropage_y - 4 cycles
177
+ def sax(addr, _value)
178
+ write_byte(addr, @a & @x)
179
+ end
180
+
181
+ # AND X register with accumulator and subtract value.
182
+ #
183
+ # Opcodes:
184
+ # $CB - immediate - 2 cycles
185
+ def sbx(_addr, value)
186
+ result = (@x & @a) - value
187
+ status.carry = result >= 0
188
+ @x = result & 0xff
189
+ update_number_flags(@x)
190
+ end
191
+
192
+ # Stores A AND X AND (high byte of base address + 1) at addr.
193
+ #
194
+ # Opcodes:
195
+ # $93 - indirect_y - 6 cycles
196
+ # $9F - absolute_y - 5 cycles
197
+ def sha(addr, _value)
198
+ store_high_and(a & x, addr)
199
+ end
200
+
201
+ # Stores X AND (high byte of base address + 1) at addr.
202
+ #
203
+ # Opcodes:
204
+ # $9E - absolute_y - 5 cycles
205
+ def shx(addr, _value)
206
+ store_high_and(x, addr)
207
+ end
208
+
209
+ # Stores Y AND (high byte of base address + 1) at addr.
210
+ #
211
+ # Opcodes:
212
+ # $9C - absolute_x - 5 cycles
213
+ def shy(addr, _value)
214
+ store_high_and(y, addr)
215
+ end
216
+
217
+ # Combination of ASL and ORA operations.
218
+ #
219
+ # Opcodes:
220
+ # $03 - indirect_x - 8 cycles
221
+ # $07 - zeropage - 5 cycles
222
+ # $0F - absolute - 6 cycles
223
+ # $13 - indirect_y - 8 cycles
224
+ # $17 - zeropage_x - 6 cycles
225
+ # $1B - absolute_y - 7 cycles
226
+ # $1F - absolute_x - 7 cycles
227
+ def slo(addr, value)
228
+ ora(addr, asl(addr, value))
229
+ end
230
+
231
+ # Combination of LSR and EOR operations.
232
+ #
233
+ # Opcodes:
234
+ # $43 - indirect_x - 8 cycles
235
+ # $47 - zeropage - 5 cycles
236
+ # $4F - absolute - 6 cycles
237
+ # $53 - indirect_y - 8 cycles
238
+ # $57 - zeropage_x - 6 cycles
239
+ # $5B - absolute_y - 7 cycles
240
+ # $5F - absolute_x - 7 cycles
241
+ def sre(addr, value)
242
+ eor(addr, lsr(addr, value))
243
+ end
244
+
245
+ # Stores A AND X in SP, then stores SP AND (high byte of base + 1) at
246
+ # addr.
247
+ #
248
+ # Opcodes:
249
+ # $9B - absolute_y - 5 cycles
250
+ def tas(addr, _value)
251
+ @stack_pointer = @a & @x
252
+ store_high_and(stack_pointer, addr)
253
+ end
254
+
255
+ private
256
+
257
+ # A VIC stall right before the dummy read, the second-to-last cycle,
258
+ # drops the & (H+1) from the stored value but not from the high byte
259
+ # of a page-crossing target.
260
+ def store_high_and(register, addr)
261
+ base_high = if boundary_crossed
262
+ (high_byte(addr) - 1) & 0xff
263
+ else
264
+ high_byte(addr)
265
+ end
266
+ result = register & ((base_high + 1) & 0xff)
267
+ target = boundary_crossed ? uint16(low_byte(addr), result) : addr
268
+ write_byte(target, stalled_before_previous_cycle? ? register : result)
269
+ end
270
+ end
271
+ end
272
+ end
273
+ end
274
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Chips
5
+ class CPU
6
+ module InstructionSet
7
+ module IncDec
8
+ # Decrements memory location by one.
9
+ #
10
+ # Opcodes:
11
+ # $C6 - zeropage - 5 cycles
12
+ # $CE - absolute - 6 cycles
13
+ # $D6 - zeropage_x - 6 cycles
14
+ # $DE - absolute_x - 7 cycles
15
+ def dec(addr, value)
16
+ result = (value - 1) & 0xff
17
+ write_modified(addr, result)
18
+ update_number_flags(result)
19
+ end
20
+
21
+ # Decrements X register by one.
22
+ #
23
+ # Opcodes:
24
+ # $CA - implied - 2 cycles
25
+ def dex(_addr, _value)
26
+ @x = (@x - 1) & 0xff
27
+ update_number_flags(@x)
28
+ end
29
+
30
+ # Decrements Y register by one.
31
+ #
32
+ # Opcodes:
33
+ # $88 - implied - 2 cycles
34
+ def dey(_addr, _value)
35
+ @y = (@y - 1) & 0xff
36
+ update_number_flags(@y)
37
+ end
38
+
39
+ # Increments memory location by one.
40
+ #
41
+ # Opcodes:
42
+ # $E6 - zeropage - 5 cycles
43
+ # $EE - absolute - 6 cycles
44
+ # $F6 - zeropage_x - 6 cycles
45
+ # $FE - absolute_x - 7 cycles
46
+ def inc(addr, value)
47
+ result = (value + 1) & 0xff
48
+ write_modified(addr, result)
49
+ update_number_flags(result)
50
+ end
51
+
52
+ # Increments X register by one.
53
+ #
54
+ # Opcodes:
55
+ # $E8 - implied - 2 cycles
56
+ def inx(_addr, _value)
57
+ @x = (@x + 1) & 0xff
58
+ update_number_flags(@x)
59
+ end
60
+
61
+ # Increments Y register by one.
62
+ #
63
+ # Opcodes:
64
+ # $C8 - implied - 2 cycles
65
+ def iny(_addr, _value)
66
+ @y = (@y + 1) & 0xff
67
+ update_number_flags(@y)
68
+ end
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Chips
5
+ class CPU
6
+ module InstructionSet
7
+ module Stack
8
+ # Push accumulator onto the stack.
9
+ #
10
+ # Opcodes:
11
+ # $48 - implied - 3 cycles
12
+ def pha(_addr, _value)
13
+ stack_push(@a)
14
+ end
15
+
16
+ # Push processor status onto the stack.
17
+ #
18
+ # Opcodes:
19
+ # $08 - implied - 3 cycles
20
+ def php(_addr, _value)
21
+ stack_push(p | 0b00010000)
22
+ end
23
+
24
+ # Pull accumulator from stack.
25
+ #
26
+ # Opcodes:
27
+ # $68 - implied - 4 cycles
28
+ def pla(_addr, _value)
29
+ @a = stack_pull
30
+ update_number_flags(@a)
31
+ end
32
+
33
+ # Pull processor status from stack.
34
+ #
35
+ # Opcodes:
36
+ # $28 - implied - 4 cycles
37
+ def plp(_addr, _value)
38
+ status.value = stack_pull & 0b11101111
39
+ end
40
+
41
+ private
42
+
43
+ def stack_pull
44
+ @stack_pointer = (@stack_pointer + 1) & 0xff
45
+ @memory.peek(stack_address)
46
+ end
47
+
48
+ def stack_push(value)
49
+ write_byte(stack_address, value)
50
+ @stack_pointer = (@stack_pointer - 1) & 0xff
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end