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
@@ -1,58 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Z80
5
- # INI, IND, OUTI, OUTD and their repeating forms. B counts the bytes
6
- # and sets S, Z, 5 and 3. The byte's bit 7 sets N, and adding it to C
7
- # plus or minus one for INI and IND, or to L for OUTI and OUTD, sets H
8
- # and C on a carry out and P/V from the parity of its low 3 bits
9
- # exclusive-ored with B.
10
- module BlockIO
11
- private
12
-
13
- def block_input(step, repeat)
14
- @cycles += 1
15
- port = bc
16
- value = input(port)
17
- @wz = (port + step) & 0xffff
18
- @b = (@b - 1) & 0xff
19
- write_byte(hl, value)
20
- self.hl = (hl + step) & 0xffff
21
- block_io_flags(value, value + ((@c + step) & 0xff), repeat)
22
- end
23
-
24
- def block_output(step, repeat)
25
- @cycles += 1
26
- value = read_byte(hl)
27
- @b = (@b - 1) & 0xff
28
- output(bc, value)
29
- self.hl = (hl + step) & 0xffff
30
- @wz = (bc + step) & 0xffff
31
- block_io_flags(value, value + @l, repeat)
32
- end
33
-
34
- def block_io_flags(value, sum, repeat)
35
- carry = sum > 0xff ? HF | CF : 0
36
- assign_flags(SZ53[@b] | ((value >> 6) & NF) | carry | PARITY[(sum & 7) ^ @b])
37
- return unless repeat && !@b.zero?
38
-
39
- repeat_block
40
- repeat_io_flags(value, carry)
41
- end
42
-
43
- def repeat_io_flags(value, carry)
44
- flags = @f & ~HF
45
- if carry.zero?
46
- flags ^= PARITY[@b & 7] ^ PF
47
- elsif value.anybits?(0x80)
48
- flags ^= PARITY[(@b - 1) & 7] ^ PF
49
- flags |= HF if @b.nobits?(0x0f)
50
- else
51
- flags ^= PARITY[(@b + 1) & 7] ^ PF
52
- flags |= HF if @b.allbits?(0x0f)
53
- end
54
- assign_flags(flags)
55
- end
56
- end
57
- end
58
- end
@@ -1,59 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Z80
5
- # LDI, LDD, CPI, CPD and their repeating forms. A repeating form that
6
- # goes round again winds the program counter back to its ED and spends
7
- # 5 T-states more, and bits 5 and 3 then come from the program
8
- # counter's high byte.
9
- module BlockTransfers
10
- private
11
-
12
- # ED A0-BB: the column picks LD, CP, IN or OUT, bit 3 counts down, and
13
- # bit 4 repeats.
14
- def block_operation(opcode)
15
- step = opcode.nobits?(0x08) ? 1 : -1
16
- repeat = opcode.anybits?(0x10)
17
- case opcode & 3
18
- when 0 then block_load(step, repeat)
19
- when 1 then block_compare(step, repeat)
20
- when 2 then block_input(step, repeat)
21
- else block_output(step, repeat)
22
- end
23
- end
24
-
25
- def block_load(step, repeat)
26
- value = read_byte(hl)
27
- write_byte(de, value)
28
- @cycles += 2
29
- self.hl = (hl + step) & 0xffff
30
- self.de = (de + step) & 0xffff
31
- self.bc = (bc - 1) & 0xffff
32
- sum = value + @a
33
- assign_flags((@f & (SF | ZF | CF)) | (sum & XF) | ((sum & 0x02) << 4) | (bc.zero? ? 0 : PF))
34
- repeat_block if repeat && !bc.zero?
35
- end
36
-
37
- def block_compare(step, repeat)
38
- value = read_byte(hl)
39
- @cycles += 5
40
- result = (@a - value) & 0xff
41
- half = (@a ^ value ^ result) & HF
42
- adjusted = result - (half >> 4)
43
- self.hl = (hl + step) & 0xffff
44
- self.bc = (bc - 1) & 0xffff
45
- @wz = (@wz + step) & 0xffff
46
- assign_flags((@f & CF) | NF | half | (SZ53[result] & (SF | ZF)) | (adjusted & XF) | ((adjusted & 0x02) << 4) |
47
- (bc.zero? ? 0 : PF))
48
- repeat_block if repeat && !bc.zero? && !result.zero?
49
- end
50
-
51
- def repeat_block
52
- @cycles += 5
53
- @pc = (@pc - 2) & 0xffff
54
- @wz = (@pc + 1) & 0xffff
55
- assign_flags((@f & ~XYF) | ((@pc >> 8) & XYF))
56
- end
57
- end
58
- end
59
- end
@@ -1,111 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Z80
5
- # The machine cycles that reach the bus. An opcode fetch (M1) takes 4
6
- # T-states and refreshes a row of DRAM, which counts up the low 7 bits
7
- # of R. A memory read or write takes 3, and an I/O read or write 4,
8
- # one of them the wait state the Z80 inserts itself. Each calls the bus
9
- # on its first T-state, and T-states the CPU spends inside lengthen
10
- # the machine cycle before them.
11
- module BusCycles
12
- private
13
-
14
- def fetch_opcode
15
- opcode = @bus.fetch(@pc)
16
- @pc = (@pc + 1) & 0xffff
17
- refresh
18
- @cycles += 4
19
- opcode
20
- end
21
-
22
- # A halted CPU fetches from the address after HALT, again and again,
23
- # and leaves the program counter there.
24
- def idle_fetch
25
- @bus.fetch(@pc)
26
- refresh
27
- @cycles += 4
28
- end
29
-
30
- def refresh
31
- @r = (@r & 0x80) | ((@r + 1) & 0x7f)
32
- end
33
-
34
- def read_byte(address)
35
- value = @bus.read(address)
36
- @cycles += 3
37
- value
38
- end
39
-
40
- def write_byte(address, value)
41
- @bus.write(address, value)
42
- @cycles += 3
43
- end
44
-
45
- def read_word(address)
46
- low = read_byte(address)
47
- low | (read_byte((address + 1) & 0xffff) << 8)
48
- end
49
-
50
- def write_word(address, value)
51
- write_byte(address, value & 0xff)
52
- write_byte((address + 1) & 0xffff, value >> 8)
53
- end
54
-
55
- def input(port)
56
- value = @bus.input(port)
57
- @cycles += 4
58
- value
59
- end
60
-
61
- def output(port, value)
62
- @bus.output(port, value)
63
- @cycles += 4
64
- end
65
-
66
- # The byte after the opcode.
67
- def fetch_byte
68
- value = read_byte(@pc)
69
- @pc = (@pc + 1) & 0xffff
70
- value
71
- end
72
-
73
- def fetch_word
74
- low = fetch_byte
75
- low | (fetch_byte << 8)
76
- end
77
-
78
- def push(value)
79
- @sp = (@sp - 1) & 0xffff
80
- write_byte(@sp, value >> 8)
81
- @sp = (@sp - 1) & 0xffff
82
- write_byte(@sp, value & 0xff)
83
- end
84
-
85
- def pop
86
- low = read_byte(@sp)
87
- high = read_byte((@sp + 1) & 0xffff)
88
- @sp = (@sp + 2) & 0xffff
89
- low | (high << 8)
90
- end
91
-
92
- # The address of an (HL) operand, or of (IX+d), whose displacement is
93
- # read from after the opcode and added in 5 T-states inside.
94
- def operand_address
95
- return hl if @prefix.zero?
96
-
97
- displaced
98
- @cycles += 5
99
- @wz
100
- end
101
-
102
- # Reads the displacement of an (IX+d) or (IY+d) operand and leaves
103
- # the address in WZ.
104
- def displaced
105
- offset = fetch_byte
106
- offset -= 256 if offset > 127
107
- @wz = (index_register + offset) & 0xffff
108
- end
109
- end
110
- end
111
- end
@@ -1,113 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "badline/z80/flags"
4
- require "badline/z80/registers"
5
- require "badline/z80/bus_cycles"
6
- require "badline/z80/arithmetic"
7
- require "badline/z80/shifts"
8
- require "badline/z80/loads"
9
- require "badline/z80/exchanges"
10
- require "badline/z80/jumps"
11
- require "badline/z80/main_page"
12
- require "badline/z80/bit_page"
13
- require "badline/z80/extended_page"
14
- require "badline/z80/block_transfers"
15
- require "badline/z80/block_io"
16
- require "badline/z80/interrupt_acceptance"
17
- require "badline/z80/saved_state"
18
-
19
- module Badline
20
- class Z80
21
- # The Z80 core, on whatever bus +bus+ is. The bus answers
22
- # fetch(address) for an opcode fetch (M1), read(address) and
23
- # write(address, value) for memory, input(port) and output(port, value)
24
- # for I/O, and acknowledge for the byte a device puts on the data bus
25
- # when the CPU takes a maskable interrupt.
26
- #
27
- # #step! runs one instruction, prefixes and all, or takes an interrupt,
28
- # or idles one opcode fetch while halted. #cycles counts T-states, and
29
- # each bus call happens while it holds the T-state its machine cycle
30
- # starts on.
31
- module Core
32
- include Flags
33
- include Registers
34
- include BusCycles
35
- include Arithmetic
36
- include Shifts
37
- include Loads
38
- include Exchanges
39
- include Jumps
40
- include MainPage
41
- include BitPage
42
- include ExtendedPage
43
- include BlockTransfers
44
- include BlockIO
45
- include InterruptAcceptance
46
- include SavedState
47
-
48
- attr_reader :bus, :cycles, :nmi
49
- attr_accessor :int
50
-
51
- def initialize(bus)
52
- @bus = bus
53
- @cycles = 0
54
- @a = @f = 0xff
55
- @b = @c = @d = @e = @h = @l = 0xff
56
- @af_alt = @bc_alt = @de_alt = @hl_alt = 0xffff
57
- @ix = @iy = @sp = 0xffff
58
- @wz = @q = @last_q = 0
59
- @prefix = 0
60
- @int = @nmi = @nmi_pending = false
61
- reset!
62
- end
63
-
64
- # The RESET line: the program counter, I, R and the interrupt mode go
65
- # to 0, and interrupts are disabled.
66
- def reset!
67
- @pc = @i = @r = @im = 0
68
- @iff1 = @iff2 = false
69
- @halted = @after_ei = @after_ld_a_ir = false
70
- @nmi_pending = false
71
- end
72
-
73
- # The NMI line. Asserting it latches an interrupt, taken after the
74
- # current instruction, and holding it does nothing more.
75
- def nmi=(asserted)
76
- @nmi_pending = true if asserted && !@nmi
77
- @nmi = asserted
78
- end
79
-
80
- # The WAIT line: a bus that holds it during an access lengthens that
81
- # machine cycle by +states+ T-states.
82
- def wait(states)
83
- @cycles += states
84
- end
85
-
86
- def step!
87
- if @nmi_pending
88
- take_nmi
89
- elsif @int && @iff1 && !@after_ei
90
- take_int
91
- else
92
- @after_ei = @after_ld_a_ir = false
93
- @last_q = @q
94
- @q = 0
95
- @prefix = 0
96
- @halted ? idle_fetch : execute(fetch_opcode)
97
- end
98
- nil
99
- end
100
-
101
- def inspect
102
- "Cycles: #{@cycles}, PC: #{hex(@pc)}, SP: #{hex(@sp)}, AF: #{hex(af)}, BC: #{hex(bc)}, " \
103
- "DE: #{hex(de)}, HL: #{hex(hl)}, IX: #{hex(@ix)}, IY: #{hex(@iy)}"
104
- end
105
-
106
- private
107
-
108
- def hex(value)
109
- value.to_s(16).rjust(4, "0")
110
- end
111
- end
112
- end
113
- end
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Z80
5
- # EX AF,AF', EXX, EX DE,HL and EX (SP),HL. Only the last swaps IX or IY
6
- # after a prefix.
7
- module Exchanges
8
- private
9
-
10
- def exchange_alternates
11
- bc_alt = @bc_alt
12
- de_alt = @de_alt
13
- hl_alt = @hl_alt
14
- @bc_alt = bc
15
- @de_alt = de
16
- @hl_alt = hl
17
- self.bc = bc_alt
18
- self.de = de_alt
19
- self.hl = hl_alt
20
- end
21
-
22
- def exchange_af
23
- af_alt = @af_alt
24
- @af_alt = af
25
- self.af = af_alt
26
- end
27
-
28
- def exchange_de_hl
29
- d = @d
30
- e = @e
31
- @d = @h
32
- @e = @l
33
- @h = d
34
- @l = e
35
- end
36
-
37
- def exchange_stack_top
38
- low = read_byte(@sp)
39
- high = read_byte((@sp + 1) & 0xffff)
40
- @cycles += 1
41
- value = hl_or_index
42
- write_byte((@sp + 1) & 0xffff, value >> 8)
43
- write_byte(@sp, value & 0xff)
44
- @cycles += 2
45
- @wz = low | (high << 8)
46
- self.hl_or_index = @wz
47
- end
48
- end
49
- end
50
- end
@@ -1,89 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Z80
5
- # The interrupt mode each of ED 46, 4E, 56, 5E, 66, 6E, 76 and 7E sets.
6
- # 4E and 6E set mode 0 on the NMOS Z80.
7
- INTERRUPT_MODES = [0, 0, 1, 2, 0, 0, 1, 2].freeze
8
-
9
- # The ED page: its second quarter, the block instructions, and 8
10
- # T-states of nothing for the rest.
11
- module ExtendedPage
12
- private
13
-
14
- def execute_extended(opcode)
15
- case opcode >> 6
16
- when 1 then extended_operation(opcode)
17
- when 2 then block_operation(opcode) if (opcode & 0x24) == 0x20
18
- end
19
- end
20
-
21
- def extended_operation(opcode)
22
- row = (opcode >> 3) & 7
23
- case opcode & 7
24
- when 0 then input_register(row)
25
- when 1 then output_register(row)
26
- when 2 then add_pair_with_carry(row)
27
- when 3 then row.nobits?(1) ? store_word(pair(row >> 1)) : set_pair(row >> 1, load_word)
28
- when 4 then neg
29
- when 5 then return_from_interrupt
30
- when 6 then @im = INTERRUPT_MODES[row]
31
- else special_register(row)
32
- end
33
- end
34
-
35
- # IN r,(C), and IN F,(C) at index 6, which sets the flags alone.
36
- def input_register(index)
37
- port = bc
38
- value = input(port)
39
- @wz = (port + 1) & 0xffff
40
- assign_flags((@f & CF) | SZ53P[value])
41
- set_register(index, value) unless index == 6
42
- end
43
-
44
- # OUT (C),r, and at index 6 OUT (C),0.
45
- def output_register(index)
46
- port = bc
47
- output(port, index == 6 ? 0 : register(index))
48
- @wz = (port + 1) & 0xffff
49
- end
50
-
51
- def add_pair_with_carry(row)
52
- row.nobits?(1) ? sbc16(pair(row >> 1)) : adc16(pair(row >> 1))
53
- @cycles += 7
54
- end
55
-
56
- # RETN and RETI both restore IFF1 from IFF2.
57
- def return_from_interrupt
58
- @iff1 = @iff2
59
- return_from_call
60
- end
61
-
62
- # LD I,A, LD R,A, LD A,I, LD A,R, RRD and RLD, and two that do
63
- # nothing.
64
- def special_register(row)
65
- case row
66
- when 0 then @i = load_ir(@a)
67
- when 1 then @r = load_ir(@a)
68
- when 2 then @a = load_a_from_ir(@i)
69
- when 3 then @a = load_a_from_ir(@r)
70
- when 4 then rotate_digits(false)
71
- when 5 then rotate_digits(true)
72
- end
73
- end
74
-
75
- def load_ir(value)
76
- @cycles += 1
77
- value
78
- end
79
-
80
- # P/V copies IFF2, and an interrupt taken next clears it again.
81
- def load_a_from_ir(value)
82
- @cycles += 1
83
- assign_flags((@f & CF) | SZ53[value] | (@iff2 ? PF : 0))
84
- @after_ld_a_ir = true
85
- value
86
- end
87
- end
88
- end
89
- end
@@ -1,37 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Z80
5
- CF = 0x01
6
- NF = 0x02
7
- PF = 0x04
8
- XF = 0x08
9
- HF = 0x10
10
- YF = 0x20
11
- ZF = 0x40
12
- SF = 0x80
13
-
14
- # Bits 5 and 3, which most instructions copy from a result.
15
- XYF = YF | XF
16
-
17
- # S, Z, Y and X as a result byte sets them.
18
- SZ53 = Array.new(256) { |v| (v & (SF | XYF)) | (v.zero? ? ZF : 0) }.freeze
19
-
20
- # P/V as parity: set when a byte has an even number of bits set.
21
- PARITY = Array.new(256) { |v| (0x6996 >> ((v ^ (v >> 4)) & 0x0f)).nobits?(1) ? PF : 0 }.freeze
22
-
23
- SZ53P = Array.new(256) { |v| SZ53[v] | PARITY[v] }.freeze
24
-
25
- # The flags, which the core keeps in F as the chip does. Every
26
- # instruction that sets them through the ALU also latches them in Q,
27
- # which SCF and CCF read on the next instruction.
28
- module Flags
29
- private
30
-
31
- def assign_flags(value)
32
- @f = value
33
- @q = value
34
- end
35
- end
36
- end
37
- end
@@ -1,46 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Z80
5
- # Taking NMI and INT between instructions. Either wakes a halted CPU,
6
- # whose program counter already points past the HALT.
7
- module InterruptAcceptance
8
- private
9
-
10
- # An opcode fetch whose byte is ignored, a T-state more, and a call
11
- # to $0066. IFF2 keeps what IFF1 held, for RETN to restore.
12
- def take_nmi
13
- @nmi_pending = false
14
- @halted = false
15
- @iff1 = false
16
- @bus.fetch(@pc)
17
- refresh
18
- @cycles += 5
19
- push(@pc)
20
- @pc = 0x66
21
- @wz = 0x66
22
- end
23
-
24
- # The acknowledge cycle, an M1 with two wait states, reads a byte
25
- # from the device. Mode 0 runs it as an opcode, which is a RST in
26
- # practice, mode 1 calls $0038, and mode 2 calls through the vector
27
- # at I and that byte.
28
- def take_int
29
- @halted = false
30
- @f &= ~PF if @after_ld_a_ir
31
- @iff1 = @iff2 = false
32
- @after_ld_a_ir = false
33
- @prefix = 0
34
- data = @bus.acknowledge
35
- refresh
36
- @cycles += 6
37
- return execute(data) if @im.zero?
38
-
39
- @cycles += 1
40
- push(@pc)
41
- @pc = @im == 1 ? 0x38 : read_word((@i << 8) | data)
42
- @wz = @pc
43
- end
44
- end
45
- end
46
- end
@@ -1,82 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- class Z80
5
- # Jumps, calls and returns. Each leaves its target in WZ, and JP cc and
6
- # CALL cc do whether they jump or not.
7
- module Jumps
8
- private
9
-
10
- # The conditions bits 5-3 pick: NZ Z NC C PO PE P M.
11
- def condition?(index)
12
- case index
13
- when 0 then @f.nobits?(ZF)
14
- when 1 then @f.anybits?(ZF)
15
- when 2 then @f.nobits?(CF)
16
- when 3 then @f.anybits?(CF)
17
- when 4 then @f.nobits?(PF)
18
- when 5 then @f.anybits?(PF)
19
- when 6 then @f.nobits?(SF)
20
- else @f.anybits?(SF)
21
- end
22
- end
23
-
24
- # NOP, EX AF,AF', DJNZ, JR and JR cc.
25
- def relative_jump(row)
26
- case row
27
- when 0 then nil
28
- when 1 then exchange_af
29
- when 2 then decrement_and_jump
30
- when 3 then jump_relative(fetch_byte)
31
- else
32
- offset = fetch_byte
33
- jump_relative(offset) if condition?(row - 4)
34
- end
35
- end
36
-
37
- def decrement_and_jump
38
- @cycles += 1
39
- offset = fetch_byte
40
- @b = (@b - 1) & 0xff
41
- jump_relative(offset) unless @b.zero?
42
- end
43
-
44
- def jump_relative(offset)
45
- @cycles += 5
46
- @pc = (@pc + offset - (offset > 127 ? 256 : 0)) & 0xffff
47
- @wz = @pc
48
- end
49
-
50
- def jump(taken)
51
- @wz = fetch_word
52
- @pc = @wz if taken
53
- end
54
-
55
- def call(taken)
56
- @wz = fetch_word
57
- return unless taken
58
-
59
- @cycles += 1
60
- push(@pc)
61
- @pc = @wz
62
- end
63
-
64
- def conditional_return(index)
65
- @cycles += 1
66
- return_from_call if condition?(index)
67
- end
68
-
69
- def return_from_call
70
- @pc = pop
71
- @wz = @pc
72
- end
73
-
74
- def restart(address)
75
- @cycles += 1
76
- push(@pc)
77
- @pc = address
78
- @wz = address
79
- end
80
- end
81
- end
82
- end