badline 0.12.0 → 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (516) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +25 -0
  3. data/CLAUDE.md +59 -31
  4. data/README.md +1 -1
  5. data/doc/library.md +9 -9
  6. data/doc/pinned-behaviour.md +105 -105
  7. data/doc/snapshots.md +1 -4
  8. data/lib/badline/audio/bare_player.rb +4 -4
  9. data/lib/badline/audio/cli.rb +6 -6
  10. data/lib/badline/audio/jukebox.rb +2 -2
  11. data/lib/badline/audio/machine_player.rb +2 -2
  12. data/lib/badline/{media → audio}/queue.rb +1 -1
  13. data/lib/badline/audio/queued_tune.rb +6 -6
  14. data/lib/badline/audio/renderer.rb +5 -5
  15. data/lib/badline/audio/stereo.rb +1 -1
  16. data/lib/badline/c128/{bus_state.rb → bus/saved_state.rb} +6 -6
  17. data/lib/badline/c128/bus.rb +30 -51
  18. data/lib/badline/c128/color_lines.rb +2 -2
  19. data/lib/badline/c128/cpu.rb +1 -1
  20. data/lib/badline/c128/drives.rb +10 -11
  21. data/lib/badline/c128/fast_serial.rb +5 -5
  22. data/lib/badline/c128/mmu_pages.rb +1 -1
  23. data/lib/badline/c128/modes.rb +2 -2
  24. data/lib/badline/c128/saved_state.rb +21 -47
  25. data/lib/badline/c128/z80.rb +2 -2
  26. data/lib/badline/c128.rb +18 -72
  27. data/lib/badline/{computer → c64}/attachments.rb +16 -47
  28. data/lib/badline/c64/banked_ram/banking.rb +32 -0
  29. data/lib/badline/c64/banked_ram/plus256k.rb +56 -0
  30. data/lib/badline/c64/banked_ram/plus60k.rb +45 -0
  31. data/lib/badline/c64/banked_ram/unexpanded.rb +30 -0
  32. data/lib/badline/c64/banked_ram.rb +23 -0
  33. data/lib/badline/c64/bus/extra_sids.rb +32 -0
  34. data/lib/badline/c64/bus/fittings.rb +40 -0
  35. data/lib/badline/c64/bus/pla.rb +149 -0
  36. data/lib/badline/c64/bus/roms.rb +41 -0
  37. data/lib/badline/c64/bus/saved_state.rb +68 -0
  38. data/lib/badline/c64/bus/sid_slots.rb +44 -0
  39. data/lib/badline/c64/bus.rb +218 -0
  40. data/lib/badline/c64/cartridge/action_replay.rb +128 -0
  41. data/lib/badline/c64/cartridge/atomic_power.rb +26 -0
  42. data/lib/badline/c64/cartridge/bank.rb +83 -0
  43. data/lib/badline/c64/cartridge/comal80.rb +52 -0
  44. data/lib/badline/c64/cartridge/dinamic.rb +36 -0
  45. data/lib/badline/c64/cartridge/easy_flash.rb +147 -0
  46. data/lib/badline/c64/cartridge/epyx_fastload.rb +81 -0
  47. data/lib/badline/c64/cartridge/final_cartridge3.rb +91 -0
  48. data/lib/badline/c64/cartridge/flash/saved_state.rb +40 -0
  49. data/lib/badline/c64/cartridge/flash.rb +279 -0
  50. data/lib/badline/c64/cartridge/freezer.rb +35 -0
  51. data/lib/badline/c64/cartridge/fun_play.rb +40 -0
  52. data/lib/badline/c64/cartridge/g_mod2.rb +76 -0
  53. data/lib/badline/c64/cartridge/game_system.rb +42 -0
  54. data/lib/badline/c64/cartridge/geo_ram.rb +81 -0
  55. data/lib/badline/c64/cartridge/kcs_power.rb +77 -0
  56. data/lib/badline/c64/cartridge/mach5.rb +34 -0
  57. data/lib/badline/c64/cartridge/magic_desk.rb +32 -0
  58. data/lib/badline/c64/cartridge/ocean.rb +37 -0
  59. data/lib/badline/c64/cartridge/pagefox.rb +70 -0
  60. data/lib/badline/c64/cartridge/retro_replay/saved_state.rb +47 -0
  61. data/lib/badline/c64/cartridge/retro_replay.rb +286 -0
  62. data/lib/badline/c64/cartridge/rex_utility.rb +31 -0
  63. data/lib/badline/c64/cartridge/rgcd.rb +60 -0
  64. data/lib/badline/c64/cartridge/saved_state.rb +63 -0
  65. data/lib/badline/c64/cartridge/simons_basic.rb +37 -0
  66. data/lib/badline/c64/cartridge/standard.rb +17 -0
  67. data/lib/badline/c64/cartridge/super_games.rb +50 -0
  68. data/lib/badline/c64/cartridge/westermann.rb +32 -0
  69. data/lib/badline/c64/cartridge/zaxxon.rb +68 -0
  70. data/lib/badline/c64/cartridge.rb +258 -0
  71. data/lib/badline/c64/color_memory.rb +27 -0
  72. data/lib/badline/c64/common.rb +34 -0
  73. data/lib/badline/c64/kernal_traps.rb +89 -0
  74. data/lib/badline/c64/reu/dma/saved_state.rb +52 -0
  75. data/lib/badline/c64/reu/dma.rb +275 -0
  76. data/lib/badline/c64/reu/ram.rb +109 -0
  77. data/lib/badline/c64/reu/saved_state.rb +55 -0
  78. data/lib/badline/c64/reu/trigger.rb +34 -0
  79. data/lib/badline/c64/reu.rb +291 -0
  80. data/lib/badline/{computer → c64}/saved_state.rb +13 -18
  81. data/lib/badline/{computer → c64}/true_drives.rb +20 -31
  82. data/lib/badline/{computer.rb → c64.rb} +22 -80
  83. data/lib/badline/chips/cia/fast_forward.rb +62 -0
  84. data/lib/badline/chips/cia/interrupt_register.rb +145 -0
  85. data/lib/badline/chips/cia/saved_state.rb +49 -0
  86. data/lib/badline/chips/cia/serial/saved_state.rb +45 -0
  87. data/lib/badline/chips/cia/serial.rb +250 -0
  88. data/lib/badline/chips/cia/time_of_day.rb +232 -0
  89. data/lib/badline/chips/cia/timer.rb +208 -0
  90. data/lib/badline/chips/cia.rb +281 -0
  91. data/lib/badline/chips/cpu/addressing.rb +133 -0
  92. data/lib/badline/chips/cpu/boundary.rb +56 -0
  93. data/lib/badline/chips/cpu/core.rb +167 -0
  94. data/lib/badline/chips/cpu/instruction.rb +338 -0
  95. data/lib/badline/chips/cpu/instruction_set/arithmetic.rb +118 -0
  96. data/lib/badline/chips/cpu/instruction_set/bitwise.rb +130 -0
  97. data/lib/badline/chips/cpu/instruction_set/branch.rb +83 -0
  98. data/lib/badline/chips/cpu/instruction_set/flag.rb +67 -0
  99. data/lib/badline/chips/cpu/instruction_set/illegal.rb +274 -0
  100. data/lib/badline/chips/cpu/instruction_set/inc_dec.rb +73 -0
  101. data/lib/badline/chips/cpu/instruction_set/stack.rb +56 -0
  102. data/lib/badline/chips/cpu/instruction_set/transfer.rb +141 -0
  103. data/lib/badline/chips/cpu/instruction_set.rb +59 -0
  104. data/lib/badline/chips/cpu/interrupts.rb +108 -0
  105. data/lib/badline/chips/cpu/microcode.rb +179 -0
  106. data/lib/badline/chips/cpu/operations.rb +90 -0
  107. data/lib/badline/chips/cpu/port.rb +116 -0
  108. data/lib/badline/chips/cpu/saved_state.rb +117 -0
  109. data/lib/badline/chips/cpu/stack_operations.rb +84 -0
  110. data/lib/badline/chips/cpu/traps.rb +23 -0
  111. data/lib/badline/chips/cpu.rb +12 -0
  112. data/lib/badline/chips/sid/catch_up.rb +122 -0
  113. data/lib/badline/chips/sid/decimator.rb +66 -0
  114. data/lib/badline/chips/sid/envelope/saved_state.rb +70 -0
  115. data/lib/badline/chips/sid/envelope.rb +241 -0
  116. data/lib/badline/chips/sid/filter/saved_state.rb +42 -0
  117. data/lib/badline/chips/sid/filter.rb +241 -0
  118. data/lib/badline/chips/sid/saved_state.rb +52 -0
  119. data/lib/badline/chips/sid/voice.rb +79 -0
  120. data/lib/badline/chips/sid/waveform/combined.rb +128 -0
  121. data/lib/badline/chips/sid/waveform/fast_forward.rb +107 -0
  122. data/lib/badline/chips/sid/waveform/noise_writeback.rb +124 -0
  123. data/lib/badline/chips/sid/waveform/saved_state.rb +68 -0
  124. data/lib/badline/chips/sid/waveform.rb +307 -0
  125. data/lib/badline/chips/sid.rb +265 -0
  126. data/lib/badline/{c128 → chips}/vdc/memory.rb +1 -1
  127. data/lib/badline/{c128 → chips}/vdc/painter.rb +1 -1
  128. data/lib/badline/{c128 → chips}/vdc/raster.rb +1 -1
  129. data/lib/badline/chips/vdc/saved_state.rb +36 -0
  130. data/lib/badline/{c128 → chips}/vdc/window.rb +1 -1
  131. data/lib/badline/{c128 → chips}/vdc.rb +7 -31
  132. data/lib/badline/chips/via/control_lines.rb +124 -0
  133. data/lib/badline/chips/via/fast_forward.rb +55 -0
  134. data/lib/badline/chips/via/interrupt_register.rb +69 -0
  135. data/lib/badline/chips/via/saved_state.rb +44 -0
  136. data/lib/badline/chips/via/shift_register.rb +182 -0
  137. data/lib/badline/chips/via/timer1.rb +133 -0
  138. data/lib/badline/chips/via/timer2.rb +135 -0
  139. data/lib/badline/chips/via.rb +268 -0
  140. data/lib/badline/chips/vic/bank.rb +135 -0
  141. data/lib/badline/chips/vic/border_mask.rb +88 -0
  142. data/lib/badline/chips/vic/collisions.rb +117 -0
  143. data/lib/badline/chips/vic/color_patches.rb +49 -0
  144. data/lib/badline/chips/vic/display_state.rb +187 -0
  145. data/lib/badline/chips/vic/graphics_mode.rb +166 -0
  146. data/lib/badline/chips/vic/graphics_shifter/saved_state.rb +40 -0
  147. data/lib/badline/chips/vic/graphics_shifter.rb +187 -0
  148. data/lib/badline/chips/vic/register_log.rb +83 -0
  149. data/lib/badline/chips/vic/registers.rb +197 -0
  150. data/lib/badline/chips/vic/saved_state.rb +82 -0
  151. data/lib/badline/chips/vic/sequencer/saved_state.rb +91 -0
  152. data/lib/badline/chips/vic/sequencer.rb +277 -0
  153. data/lib/badline/chips/vic/sequencer_output.rb +118 -0
  154. data/lib/badline/chips/vic/sprite/internal_bus.rb +70 -0
  155. data/lib/badline/chips/vic/sprite/saved_state.rb +66 -0
  156. data/lib/badline/chips/vic/sprite/shifter.rb +148 -0
  157. data/lib/badline/chips/vic/sprite/timing.rb +58 -0
  158. data/lib/badline/chips/vic/sprite.rb +339 -0
  159. data/lib/badline/chips/vic/sprites/saved_state.rb +59 -0
  160. data/lib/badline/chips/vic/sprites.rb +284 -0
  161. data/lib/badline/chips/vic.rb +783 -0
  162. data/lib/badline/chips/vic_i/painter/saved_state.rb +40 -0
  163. data/lib/badline/{vic20/vic → chips/vic_i}/painter.rb +6 -30
  164. data/lib/badline/{vic20/vic → chips/vic_i}/saved_state.rb +2 -2
  165. data/lib/badline/chips/vic_i/sound/output.rb +85 -0
  166. data/lib/badline/chips/vic_i/sound.rb +235 -0
  167. data/lib/badline/{vic20/vic → chips/vic_i}/text_window.rb +2 -2
  168. data/lib/badline/{vic20/vic.rb → chips/vic_i.rb} +5 -5
  169. data/lib/badline/chips/z80/arithmetic.rb +119 -0
  170. data/lib/badline/chips/z80/bit_page.rb +57 -0
  171. data/lib/badline/chips/z80/block_io.rb +60 -0
  172. data/lib/badline/chips/z80/block_transfers.rb +61 -0
  173. data/lib/badline/chips/z80/bus_cycles.rb +113 -0
  174. data/lib/badline/chips/z80/core.rb +115 -0
  175. data/lib/badline/chips/z80/exchanges.rb +52 -0
  176. data/lib/badline/chips/z80/extended_page.rb +91 -0
  177. data/lib/badline/chips/z80/flags.rb +39 -0
  178. data/lib/badline/chips/z80/interrupt_acceptance.rb +48 -0
  179. data/lib/badline/chips/z80/jumps.rb +84 -0
  180. data/lib/badline/chips/z80/loads.rb +100 -0
  181. data/lib/badline/chips/z80/main_page.rb +136 -0
  182. data/lib/badline/chips/z80/registers.rb +122 -0
  183. data/lib/badline/chips/z80/saved_state.rb +71 -0
  184. data/lib/badline/chips/z80/shifts.rb +66 -0
  185. data/lib/badline/chips/z80.rb +13 -0
  186. data/lib/badline/core.rb +27 -29
  187. data/lib/badline/drives/datasette/saved_state.rb +37 -0
  188. data/lib/badline/drives/datasette.rb +140 -0
  189. data/lib/badline/drives/engine/core.rb +149 -0
  190. data/lib/badline/drives/engine/fast_serial.rb +75 -0
  191. data/lib/badline/drives/engine/idle.rb +127 -0
  192. data/lib/badline/drives/engine/idle_cpu.rb +30 -0
  193. data/lib/badline/drives/engine/orbit.rb +81 -0
  194. data/lib/badline/drives/engine/serial_lines.rb +75 -0
  195. data/lib/badline/drives/engine/sleep.rb +114 -0
  196. data/lib/badline/drives/engine/vias.rb +86 -0
  197. data/lib/badline/drives/engine/watch.rb +152 -0
  198. data/lib/badline/drives/engine.rb +11 -0
  199. data/lib/badline/drives/model1541/bus.rb +88 -0
  200. data/lib/badline/drives/model1541/byte_ready.rb +50 -0
  201. data/lib/badline/drives/model1541/cpu.rb +13 -0
  202. data/lib/badline/drives/model1541/disk/saved_state.rb +88 -0
  203. data/lib/badline/drives/model1541/disk.rb +317 -0
  204. data/lib/badline/drives/model1541/disk_via.rb +38 -0
  205. data/lib/badline/drives/model1541/gcr.rb +59 -0
  206. data/lib/badline/drives/model1541/mechanism/saved_state.rb +72 -0
  207. data/lib/badline/drives/model1541/mechanism.rb +315 -0
  208. data/lib/badline/drives/model1541/rotation.rb +123 -0
  209. data/lib/badline/drives/model1541/saved_state.rb +44 -0
  210. data/lib/badline/drives/model1541/sector_reader.rb +78 -0
  211. data/lib/badline/drives/model1541/serial_port.rb +20 -0
  212. data/lib/badline/drives/model1541/track.rb +100 -0
  213. data/lib/badline/drives/model1541.rb +81 -0
  214. data/lib/badline/drives/model1571/bus.rb +113 -0
  215. data/lib/badline/drives/model1571/cpu.rb +13 -0
  216. data/lib/badline/drives/model1571/saved_state.rb +47 -0
  217. data/lib/badline/drives/model1571/serial_port.rb +39 -0
  218. data/lib/badline/drives/model1571/serial_via.rb +27 -0
  219. data/lib/badline/drives/model1571/wd1770.rb +122 -0
  220. data/lib/badline/drives/model1571.rb +142 -0
  221. data/lib/badline/drives/model1581/bus.rb +139 -0
  222. data/lib/badline/drives/model1581/cpu.rb +13 -0
  223. data/lib/badline/drives/model1581/disk/saved_state.rb +89 -0
  224. data/lib/badline/drives/model1581/disk.rb +137 -0
  225. data/lib/badline/drives/model1581/mechanism.rb +119 -0
  226. data/lib/badline/drives/model1581/saved_state.rb +42 -0
  227. data/lib/badline/drives/model1581/serial_port.rb +54 -0
  228. data/lib/badline/drives/model1581/slot.rb +79 -0
  229. data/lib/badline/drives/model1581/track.rb +102 -0
  230. data/lib/badline/drives/model1581/track_bytes.rb +77 -0
  231. data/lib/badline/drives/model1581/wd1772/registers.rb +91 -0
  232. data/lib/badline/drives/model1581/wd1772/saved_state.rb +68 -0
  233. data/lib/badline/drives/model1581/wd1772/sector_writes.rb +75 -0
  234. data/lib/badline/drives/model1581/wd1772/sectors.rb +152 -0
  235. data/lib/badline/drives/model1581/wd1772/stepping.rb +111 -0
  236. data/lib/badline/drives/model1581/wd1772/tracks.rb +127 -0
  237. data/lib/badline/drives/model1581/wd1772/turn.rb +75 -0
  238. data/lib/badline/drives/model1581/wd1772.rb +218 -0
  239. data/lib/badline/drives/model1581.rb +206 -0
  240. data/lib/badline/drives/serial_bus.rb +161 -0
  241. data/lib/badline/frontend/boot.rb +10 -61
  242. data/lib/badline/frontend/machine_window.rb +3 -1
  243. data/lib/badline/frontend/player/filter_view.rb +1 -1
  244. data/lib/badline/frontend/player/player_controller.rb +2 -2
  245. data/lib/badline/frontend/player/player_screen.rb +1 -0
  246. data/lib/badline/frontend/player/theme.rb +7 -7
  247. data/lib/badline/frontend/timeline.rb +3 -3
  248. data/lib/badline/input/control_ports.rb +78 -0
  249. data/lib/badline/input/joystick.rb +27 -0
  250. data/lib/badline/input/keyboard.rb +114 -0
  251. data/lib/badline/input.rb +3 -0
  252. data/lib/badline/kernal_trap/{drive → dos}/block_commands.rb +1 -1
  253. data/lib/badline/kernal_trap/dos/channel.rb +183 -0
  254. data/lib/badline/kernal_trap/{drive → dos}/channels.rb +1 -1
  255. data/lib/badline/kernal_trap/{drive → dos}/memory.rb +1 -1
  256. data/lib/badline/kernal_trap/{drive → dos}/parameters.rb +1 -1
  257. data/lib/badline/kernal_trap/{drive → dos}/status.rb +1 -1
  258. data/lib/badline/kernal_trap/{drive → dos}/write_file.rb +1 -1
  259. data/lib/badline/kernal_trap/{drive → dos}/writes.rb +1 -1
  260. data/lib/badline/kernal_trap/{drive.rb → dos.rb} +11 -10
  261. data/lib/badline/kernal_trap/{file.rb → file_routine.rb} +1 -1
  262. data/lib/badline/kernal_trap/load.rb +6 -6
  263. data/lib/badline/kernal_trap/save.rb +5 -5
  264. data/lib/badline/kernal_trap/serial.rb +7 -7
  265. data/lib/badline/kernal_trap.rb +2 -3
  266. data/lib/badline/machine/clocking.rb +50 -0
  267. data/lib/badline/machine.rb +63 -7
  268. data/lib/badline/media/boot_disk.rb +2 -2
  269. data/lib/badline/media/disk_list.rb +3 -3
  270. data/lib/badline/media/disk_set.rb +1 -1
  271. data/lib/badline/media/extensions.rb +33 -0
  272. data/lib/badline/media/program.rb +28 -0
  273. data/lib/badline/media/true_drive.rb +4 -3
  274. data/lib/badline/media/tune.rb +35 -0
  275. data/lib/badline/media/vic20_cartridge.rb +1 -7
  276. data/lib/badline/media/vic20_media.rb +38 -80
  277. data/lib/badline/media.rb +84 -81
  278. data/lib/badline/model.rb +1 -1
  279. data/lib/badline/options/event.rb +3 -1
  280. data/lib/badline/roms/README +6 -6
  281. data/lib/badline/sdl.rb +1 -0
  282. data/lib/badline/{storage/sid_file.rb → sid_tune/file.rb} +3 -3
  283. data/lib/badline/{storage → sid_tune}/hvsc.rb +7 -7
  284. data/lib/badline/{storage → sid_tune}/song_lengths.rb +2 -2
  285. data/lib/badline/{storage → sid_tune}/stil/credit.rb +1 -1
  286. data/lib/badline/{storage → sid_tune}/stil.rb +3 -3
  287. data/lib/badline/sid_tune.rb +6 -0
  288. data/lib/badline/snapshot/c128_setup.rb +43 -0
  289. data/lib/badline/snapshot/c64_setup.rb +79 -0
  290. data/lib/badline/snapshot/image.rb +5 -25
  291. data/lib/badline/snapshot/machine_state.rb +10 -2
  292. data/lib/badline/snapshot/setup.rb +22 -66
  293. data/lib/badline/snapshot/state.rb +8 -17
  294. data/lib/badline/snapshot/storage_setup.rb +68 -0
  295. data/lib/badline/snapshot/vic20_setup.rb +37 -0
  296. data/lib/badline/snapshot/vice/c64_mem.rb +1 -1
  297. data/lib/badline/snapshot/vice/restore.rb +1 -1
  298. data/lib/badline/snapshot/vice/reu1764.rb +1 -1
  299. data/lib/badline/snapshot/vice/reu_fields.rb +40 -0
  300. data/lib/badline/snapshot/vice.rb +7 -5
  301. data/lib/badline/snapshot.rb +13 -12
  302. data/lib/badline/storage/d64_image.rb +15 -9
  303. data/lib/badline/storage/d71_image.rb +0 -2
  304. data/lib/badline/storage/d81_image.rb +0 -2
  305. data/lib/badline/storage/disk_image/writing.rb +2 -2
  306. data/lib/badline/storage/disk_image.rb +3 -6
  307. data/lib/badline/storage/g64_image.rb +2 -2
  308. data/lib/badline/storage/host_directory.rb +0 -5
  309. data/lib/badline/storage/t64.rb +2 -8
  310. data/lib/badline/storage/unavailable.rb +1 -1
  311. data/lib/badline/storage.rb +0 -37
  312. data/lib/badline/support/c128_checkpoint.rb +39 -0
  313. data/lib/badline/support/checkpoint.rb +108 -0
  314. data/lib/badline/support/vic20_checkpoint.rb +38 -0
  315. data/lib/badline/support.rb +5 -0
  316. data/lib/badline/version.rb +1 -1
  317. data/lib/badline/vic20/attachments.rb +11 -81
  318. data/lib/badline/vic20/bus/saved_state.rb +35 -0
  319. data/lib/badline/vic20/bus.rb +3 -25
  320. data/lib/badline/vic20/cpu.rb +1 -1
  321. data/lib/badline/vic20/port_wiring.rb +4 -4
  322. data/lib/badline/vic20/saved_state.rb +16 -60
  323. data/lib/badline/vic20/user_via_ports.rb +2 -2
  324. data/lib/badline/vic20.rb +20 -51
  325. metadata +250 -221
  326. data/lib/badline/address_bus/extra_sids.rb +0 -30
  327. data/lib/badline/address_bus/fittings.rb +0 -38
  328. data/lib/badline/address_bus/pla.rb +0 -147
  329. data/lib/badline/address_bus/roms.rb +0 -39
  330. data/lib/badline/address_bus/saved_state.rb +0 -72
  331. data/lib/badline/address_bus/sid_slots.rb +0 -42
  332. data/lib/badline/address_bus.rb +0 -235
  333. data/lib/badline/cartridge/action_replay.rb +0 -126
  334. data/lib/badline/cartridge/atomic_power.rb +0 -24
  335. data/lib/badline/cartridge/bank.rb +0 -81
  336. data/lib/badline/cartridge/comal80.rb +0 -50
  337. data/lib/badline/cartridge/dinamic.rb +0 -34
  338. data/lib/badline/cartridge/easy_flash.rb +0 -145
  339. data/lib/badline/cartridge/epyx_fastload.rb +0 -79
  340. data/lib/badline/cartridge/final_cartridge3.rb +0 -89
  341. data/lib/badline/cartridge/flash.rb +0 -306
  342. data/lib/badline/cartridge/freezer.rb +0 -33
  343. data/lib/badline/cartridge/fun_play.rb +0 -38
  344. data/lib/badline/cartridge/g_mod2.rb +0 -74
  345. data/lib/badline/cartridge/game_system.rb +0 -40
  346. data/lib/badline/cartridge/geo_ram.rb +0 -79
  347. data/lib/badline/cartridge/kcs_power.rb +0 -75
  348. data/lib/badline/cartridge/mach5.rb +0 -32
  349. data/lib/badline/cartridge/magic_desk.rb +0 -30
  350. data/lib/badline/cartridge/ocean.rb +0 -35
  351. data/lib/badline/cartridge/pagefox.rb +0 -68
  352. data/lib/badline/cartridge/retro_replay.rb +0 -320
  353. data/lib/badline/cartridge/rex_utility.rb +0 -29
  354. data/lib/badline/cartridge/rgcd.rb +0 -58
  355. data/lib/badline/cartridge/simons_basic.rb +0 -35
  356. data/lib/badline/cartridge/standard.rb +0 -15
  357. data/lib/badline/cartridge/super_games.rb +0 -48
  358. data/lib/badline/cartridge/westermann.rb +0 -30
  359. data/lib/badline/cartridge/zaxxon.rb +0 -66
  360. data/lib/badline/cartridge.rb +0 -303
  361. data/lib/badline/checkpoint.rb +0 -98
  362. data/lib/badline/cia/fast_forward.rb +0 -60
  363. data/lib/badline/cia/interrupt_register.rb +0 -143
  364. data/lib/badline/cia/serial.rb +0 -275
  365. data/lib/badline/cia/state.rb +0 -47
  366. data/lib/badline/cia/timer.rb +0 -206
  367. data/lib/badline/cia.rb +0 -279
  368. data/lib/badline/color_memory.rb +0 -25
  369. data/lib/badline/computer/kernal_traps.rb +0 -29
  370. data/lib/badline/control_ports.rb +0 -76
  371. data/lib/badline/cpu/addressing.rb +0 -131
  372. data/lib/badline/cpu/boundary.rb +0 -54
  373. data/lib/badline/cpu/core.rb +0 -165
  374. data/lib/badline/cpu/microcode.rb +0 -177
  375. data/lib/badline/cpu/operations.rb +0 -88
  376. data/lib/badline/cpu/saved_state.rb +0 -115
  377. data/lib/badline/cpu/stack_operations.rb +0 -82
  378. data/lib/badline/cpu.rb +0 -10
  379. data/lib/badline/cycleable.rb +0 -38
  380. data/lib/badline/datasette.rb +0 -161
  381. data/lib/badline/drive/core.rb +0 -147
  382. data/lib/badline/drive/fast_serial.rb +0 -73
  383. data/lib/badline/drive/idle.rb +0 -125
  384. data/lib/badline/drive/idle_cpu.rb +0 -28
  385. data/lib/badline/drive/orbit.rb +0 -79
  386. data/lib/badline/drive/serial_lines.rb +0 -73
  387. data/lib/badline/drive/sleep.rb +0 -112
  388. data/lib/badline/drive/vias.rb +0 -84
  389. data/lib/badline/drive/watch.rb +0 -150
  390. data/lib/badline/drive.rb +0 -11
  391. data/lib/badline/drive1541/bus.rb +0 -86
  392. data/lib/badline/drive1541/byte_ready.rb +0 -48
  393. data/lib/badline/drive1541/cpu.rb +0 -11
  394. data/lib/badline/drive1541/disk.rb +0 -318
  395. data/lib/badline/drive1541/disk_state.rb +0 -94
  396. data/lib/badline/drive1541/disk_via.rb +0 -36
  397. data/lib/badline/drive1541/gcr.rb +0 -57
  398. data/lib/badline/drive1541/mechanism.rb +0 -313
  399. data/lib/badline/drive1541/mechanism_state.rb +0 -68
  400. data/lib/badline/drive1541/rotation.rb +0 -121
  401. data/lib/badline/drive1541/sector_reader.rb +0 -76
  402. data/lib/badline/drive1541/serial_port.rb +0 -18
  403. data/lib/badline/drive1541/track.rb +0 -98
  404. data/lib/badline/drive1541.rb +0 -111
  405. data/lib/badline/drive1571/bus.rb +0 -111
  406. data/lib/badline/drive1571/cpu.rb +0 -11
  407. data/lib/badline/drive1571/serial_port.rb +0 -37
  408. data/lib/badline/drive1571/serial_via.rb +0 -25
  409. data/lib/badline/drive1571/wd1770.rb +0 -120
  410. data/lib/badline/drive1571.rb +0 -175
  411. data/lib/badline/drive1581/bus.rb +0 -137
  412. data/lib/badline/drive1581/cpu.rb +0 -11
  413. data/lib/badline/drive1581/disk.rb +0 -135
  414. data/lib/badline/drive1581/disk_state.rb +0 -87
  415. data/lib/badline/drive1581/mechanism.rb +0 -117
  416. data/lib/badline/drive1581/serial_port.rb +0 -52
  417. data/lib/badline/drive1581/slot.rb +0 -78
  418. data/lib/badline/drive1581/track.rb +0 -100
  419. data/lib/badline/drive1581/track_bytes.rb +0 -75
  420. data/lib/badline/drive1581/wd1772/registers.rb +0 -89
  421. data/lib/badline/drive1581/wd1772/sector_writes.rb +0 -73
  422. data/lib/badline/drive1581/wd1772/sectors.rb +0 -150
  423. data/lib/badline/drive1581/wd1772/state.rb +0 -66
  424. data/lib/badline/drive1581/wd1772/stepping.rb +0 -109
  425. data/lib/badline/drive1581/wd1772/tracks.rb +0 -125
  426. data/lib/badline/drive1581/wd1772/turn.rb +0 -73
  427. data/lib/badline/drive1581/wd1772.rb +0 -216
  428. data/lib/badline/drive1581.rb +0 -233
  429. data/lib/badline/iec_bus.rb +0 -159
  430. data/lib/badline/instruction.rb +0 -334
  431. data/lib/badline/instruction_set/arithmetic.rb +0 -114
  432. data/lib/badline/instruction_set/bitwise.rb +0 -126
  433. data/lib/badline/instruction_set/branch.rb +0 -79
  434. data/lib/badline/instruction_set/flag.rb +0 -63
  435. data/lib/badline/instruction_set/illegal.rb +0 -270
  436. data/lib/badline/instruction_set/inc_dec.rb +0 -69
  437. data/lib/badline/instruction_set/stack.rb +0 -52
  438. data/lib/badline/instruction_set/transfer.rb +0 -137
  439. data/lib/badline/instruction_set.rb +0 -55
  440. data/lib/badline/interrupts.rb +0 -104
  441. data/lib/badline/joystick.rb +0 -25
  442. data/lib/badline/kernal_trap/channel.rb +0 -181
  443. data/lib/badline/keyboard.rb +0 -112
  444. data/lib/badline/ram_expansion/banking.rb +0 -30
  445. data/lib/badline/ram_expansion/plus256k.rb +0 -54
  446. data/lib/badline/ram_expansion/plus60k.rb +0 -43
  447. data/lib/badline/ram_expansion/unexpanded.rb +0 -28
  448. data/lib/badline/ram_expansion.rb +0 -21
  449. data/lib/badline/reu/dma/saved_state.rb +0 -50
  450. data/lib/badline/reu/dma.rb +0 -273
  451. data/lib/badline/reu/ram.rb +0 -107
  452. data/lib/badline/reu/saved_state.rb +0 -80
  453. data/lib/badline/reu/trigger.rb +0 -32
  454. data/lib/badline/reu.rb +0 -289
  455. data/lib/badline/sid/catch_up.rb +0 -120
  456. data/lib/badline/sid/decimator.rb +0 -64
  457. data/lib/badline/sid/envelope/state.rb +0 -68
  458. data/lib/badline/sid/envelope.rb +0 -239
  459. data/lib/badline/sid/filter.rb +0 -263
  460. data/lib/badline/sid/voice.rb +0 -77
  461. data/lib/badline/sid/waveform/combined.rb +0 -126
  462. data/lib/badline/sid/waveform/fast_forward.rb +0 -105
  463. data/lib/badline/sid/waveform/noise_writeback.rb +0 -122
  464. data/lib/badline/sid/waveform/state.rb +0 -66
  465. data/lib/badline/sid/waveform.rb +0 -305
  466. data/lib/badline/sid.rb +0 -303
  467. data/lib/badline/time_of_day.rb +0 -228
  468. data/lib/badline/traps.rb +0 -19
  469. data/lib/badline/via/control_lines.rb +0 -122
  470. data/lib/badline/via/fast_forward.rb +0 -53
  471. data/lib/badline/via/interrupt_register.rb +0 -67
  472. data/lib/badline/via/shift_register.rb +0 -180
  473. data/lib/badline/via/state.rb +0 -42
  474. data/lib/badline/via/timer1.rb +0 -131
  475. data/lib/badline/via/timer2.rb +0 -133
  476. data/lib/badline/via.rb +0 -266
  477. data/lib/badline/vic/bank.rb +0 -133
  478. data/lib/badline/vic/border_mask.rb +0 -86
  479. data/lib/badline/vic/collisions.rb +0 -115
  480. data/lib/badline/vic/color_patches.rb +0 -47
  481. data/lib/badline/vic/display_state.rb +0 -185
  482. data/lib/badline/vic/graphics_mode.rb +0 -164
  483. data/lib/badline/vic/graphics_shifter.rb +0 -207
  484. data/lib/badline/vic/register_log.rb +0 -81
  485. data/lib/badline/vic/registers.rb +0 -195
  486. data/lib/badline/vic/sequencer.rb +0 -275
  487. data/lib/badline/vic/sequencer_output.rb +0 -116
  488. data/lib/badline/vic/sequencer_state.rb +0 -89
  489. data/lib/badline/vic/sprite/internal_bus.rb +0 -68
  490. data/lib/badline/vic/sprite/saved_state.rb +0 -64
  491. data/lib/badline/vic/sprite/shifter.rb +0 -146
  492. data/lib/badline/vic/sprite/timing.rb +0 -56
  493. data/lib/badline/vic/sprite.rb +0 -337
  494. data/lib/badline/vic/sprites.rb +0 -282
  495. data/lib/badline/vic/sprites_state.rb +0 -57
  496. data/lib/badline/vic.rb +0 -852
  497. data/lib/badline/vic20/sound/output.rb +0 -83
  498. data/lib/badline/vic20/sound.rb +0 -233
  499. data/lib/badline/z80/arithmetic.rb +0 -117
  500. data/lib/badline/z80/bit_page.rb +0 -55
  501. data/lib/badline/z80/block_io.rb +0 -58
  502. data/lib/badline/z80/block_transfers.rb +0 -59
  503. data/lib/badline/z80/bus_cycles.rb +0 -111
  504. data/lib/badline/z80/core.rb +0 -113
  505. data/lib/badline/z80/exchanges.rb +0 -50
  506. data/lib/badline/z80/extended_page.rb +0 -89
  507. data/lib/badline/z80/flags.rb +0 -37
  508. data/lib/badline/z80/interrupt_acceptance.rb +0 -46
  509. data/lib/badline/z80/jumps.rb +0 -82
  510. data/lib/badline/z80/loads.rb +0 -98
  511. data/lib/badline/z80/main_page.rb +0 -134
  512. data/lib/badline/z80/registers.rb +0 -120
  513. data/lib/badline/z80/saved_state.rb +0 -69
  514. data/lib/badline/z80/shifts.rb +0 -64
  515. data/lib/badline/z80.rb +0 -11
  516. /data/lib/badline/snapshot/{fields.rb → vice/fields.rb} +0 -0
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Chips
5
+ class Z80
6
+ # INI, IND, OUTI, OUTD and their repeating forms. B counts the bytes
7
+ # and sets S, Z, 5 and 3. The byte's bit 7 sets N, and adding it to C
8
+ # plus or minus one for INI and IND, or to L for OUTI and OUTD, sets H
9
+ # and C on a carry out and P/V from the parity of its low 3 bits
10
+ # exclusive-ored with B.
11
+ module BlockIO
12
+ private
13
+
14
+ def block_input(step, repeat)
15
+ @cycles += 1
16
+ port = bc
17
+ value = input(port)
18
+ @wz = (port + step) & 0xffff
19
+ @b = (@b - 1) & 0xff
20
+ write_byte(hl, value)
21
+ self.hl = (hl + step) & 0xffff
22
+ block_io_flags(value, value + ((@c + step) & 0xff), repeat)
23
+ end
24
+
25
+ def block_output(step, repeat)
26
+ @cycles += 1
27
+ value = read_byte(hl)
28
+ @b = (@b - 1) & 0xff
29
+ output(bc, value)
30
+ self.hl = (hl + step) & 0xffff
31
+ @wz = (bc + step) & 0xffff
32
+ block_io_flags(value, value + @l, repeat)
33
+ end
34
+
35
+ def block_io_flags(value, sum, repeat)
36
+ carry = sum > 0xff ? HF | CF : 0
37
+ assign_flags(SZ53[@b] | ((value >> 6) & NF) | carry | PARITY[(sum & 7) ^ @b])
38
+ return unless repeat && !@b.zero?
39
+
40
+ repeat_block
41
+ repeat_io_flags(value, carry)
42
+ end
43
+
44
+ def repeat_io_flags(value, carry)
45
+ flags = @f & ~HF
46
+ if carry.zero?
47
+ flags ^= PARITY[@b & 7] ^ PF
48
+ elsif value.anybits?(0x80)
49
+ flags ^= PARITY[(@b - 1) & 7] ^ PF
50
+ flags |= HF if @b.nobits?(0x0f)
51
+ else
52
+ flags ^= PARITY[(@b + 1) & 7] ^ PF
53
+ flags |= HF if @b.allbits?(0x0f)
54
+ end
55
+ assign_flags(flags)
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Chips
5
+ class Z80
6
+ # LDI, LDD, CPI, CPD and their repeating forms. A repeating form that
7
+ # goes round again winds the program counter back to its ED and spends
8
+ # 5 T-states more, and bits 5 and 3 then come from the program
9
+ # counter's high byte.
10
+ module BlockTransfers
11
+ private
12
+
13
+ # ED A0-BB: the column picks LD, CP, IN or OUT, bit 3 counts down, and
14
+ # bit 4 repeats.
15
+ def block_operation(opcode)
16
+ step = opcode.nobits?(0x08) ? 1 : -1
17
+ repeat = opcode.anybits?(0x10)
18
+ case opcode & 3
19
+ when 0 then block_load(step, repeat)
20
+ when 1 then block_compare(step, repeat)
21
+ when 2 then block_input(step, repeat)
22
+ else block_output(step, repeat)
23
+ end
24
+ end
25
+
26
+ def block_load(step, repeat)
27
+ value = read_byte(hl)
28
+ write_byte(de, value)
29
+ @cycles += 2
30
+ self.hl = (hl + step) & 0xffff
31
+ self.de = (de + step) & 0xffff
32
+ self.bc = (bc - 1) & 0xffff
33
+ sum = value + @a
34
+ assign_flags((@f & (SF | ZF | CF)) | (sum & XF) | ((sum & 0x02) << 4) | (bc.zero? ? 0 : PF))
35
+ repeat_block if repeat && !bc.zero?
36
+ end
37
+
38
+ def block_compare(step, repeat)
39
+ value = read_byte(hl)
40
+ @cycles += 5
41
+ result = (@a - value) & 0xff
42
+ half = (@a ^ value ^ result) & HF
43
+ adjusted = result - (half >> 4)
44
+ self.hl = (hl + step) & 0xffff
45
+ self.bc = (bc - 1) & 0xffff
46
+ @wz = (@wz + step) & 0xffff
47
+ assign_flags((@f & CF) | NF | half | (SZ53[result] & (SF | ZF)) | (adjusted & XF) | ((adjusted & 0x02) << 4) |
48
+ (bc.zero? ? 0 : PF))
49
+ repeat_block if repeat && !bc.zero? && !result.zero?
50
+ end
51
+
52
+ def repeat_block
53
+ @cycles += 5
54
+ @pc = (@pc - 2) & 0xffff
55
+ @wz = (@pc + 1) & 0xffff
56
+ assign_flags((@f & ~XYF) | ((@pc >> 8) & XYF))
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Chips
5
+ class Z80
6
+ # The machine cycles that reach the bus. An opcode fetch (M1) takes 4
7
+ # T-states and refreshes a row of DRAM, which counts up the low 7 bits
8
+ # of R. A memory read or write takes 3, and an I/O read or write 4,
9
+ # one of them the wait state the Z80 inserts itself. Each calls the bus
10
+ # on its first T-state, and T-states the CPU spends inside lengthen
11
+ # the machine cycle before them.
12
+ module BusCycles
13
+ private
14
+
15
+ def fetch_opcode
16
+ opcode = @bus.fetch(@pc)
17
+ @pc = (@pc + 1) & 0xffff
18
+ refresh
19
+ @cycles += 4
20
+ opcode
21
+ end
22
+
23
+ # A halted CPU fetches from the address after HALT, again and again,
24
+ # and leaves the program counter there.
25
+ def idle_fetch
26
+ @bus.fetch(@pc)
27
+ refresh
28
+ @cycles += 4
29
+ end
30
+
31
+ def refresh
32
+ @r = (@r & 0x80) | ((@r + 1) & 0x7f)
33
+ end
34
+
35
+ def read_byte(address)
36
+ value = @bus.read(address)
37
+ @cycles += 3
38
+ value
39
+ end
40
+
41
+ def write_byte(address, value)
42
+ @bus.write(address, value)
43
+ @cycles += 3
44
+ end
45
+
46
+ def read_word(address)
47
+ low = read_byte(address)
48
+ low | (read_byte((address + 1) & 0xffff) << 8)
49
+ end
50
+
51
+ def write_word(address, value)
52
+ write_byte(address, value & 0xff)
53
+ write_byte((address + 1) & 0xffff, value >> 8)
54
+ end
55
+
56
+ def input(port)
57
+ value = @bus.input(port)
58
+ @cycles += 4
59
+ value
60
+ end
61
+
62
+ def output(port, value)
63
+ @bus.output(port, value)
64
+ @cycles += 4
65
+ end
66
+
67
+ # The byte after the opcode.
68
+ def fetch_byte
69
+ value = read_byte(@pc)
70
+ @pc = (@pc + 1) & 0xffff
71
+ value
72
+ end
73
+
74
+ def fetch_word
75
+ low = fetch_byte
76
+ low | (fetch_byte << 8)
77
+ end
78
+
79
+ def push(value)
80
+ @sp = (@sp - 1) & 0xffff
81
+ write_byte(@sp, value >> 8)
82
+ @sp = (@sp - 1) & 0xffff
83
+ write_byte(@sp, value & 0xff)
84
+ end
85
+
86
+ def pop
87
+ low = read_byte(@sp)
88
+ high = read_byte((@sp + 1) & 0xffff)
89
+ @sp = (@sp + 2) & 0xffff
90
+ low | (high << 8)
91
+ end
92
+
93
+ # The address of an (HL) operand, or of (IX+d), whose displacement is
94
+ # read from after the opcode and added in 5 T-states inside.
95
+ def operand_address
96
+ return hl if @prefix.zero?
97
+
98
+ displaced
99
+ @cycles += 5
100
+ @wz
101
+ end
102
+
103
+ # Reads the displacement of an (IX+d) or (IY+d) operand and leaves
104
+ # the address in WZ.
105
+ def displaced
106
+ offset = fetch_byte
107
+ offset -= 256 if offset > 127
108
+ @wz = (index_register + offset) & 0xffff
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,115 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "badline/chips/z80/flags"
4
+ require "badline/chips/z80/registers"
5
+ require "badline/chips/z80/bus_cycles"
6
+ require "badline/chips/z80/arithmetic"
7
+ require "badline/chips/z80/shifts"
8
+ require "badline/chips/z80/loads"
9
+ require "badline/chips/z80/exchanges"
10
+ require "badline/chips/z80/jumps"
11
+ require "badline/chips/z80/main_page"
12
+ require "badline/chips/z80/bit_page"
13
+ require "badline/chips/z80/extended_page"
14
+ require "badline/chips/z80/block_transfers"
15
+ require "badline/chips/z80/block_io"
16
+ require "badline/chips/z80/interrupt_acceptance"
17
+ require "badline/chips/z80/saved_state"
18
+
19
+ module Badline
20
+ module Chips
21
+ class Z80
22
+ # The Z80 core, on whatever bus +bus+ is. The bus answers
23
+ # fetch(address) for an opcode fetch (M1), read(address) and
24
+ # write(address, value) for memory, input(port) and output(port, value)
25
+ # for I/O, and acknowledge for the byte a device puts on the data bus
26
+ # when the CPU takes a maskable interrupt.
27
+ #
28
+ # #step! runs one instruction, prefixes and all, or takes an interrupt,
29
+ # or idles one opcode fetch while halted. #cycles counts T-states, and
30
+ # each bus call happens while it holds the T-state its machine cycle
31
+ # starts on.
32
+ module Core
33
+ include Flags
34
+ include Registers
35
+ include BusCycles
36
+ include Arithmetic
37
+ include Shifts
38
+ include Loads
39
+ include Exchanges
40
+ include Jumps
41
+ include MainPage
42
+ include BitPage
43
+ include ExtendedPage
44
+ include BlockTransfers
45
+ include BlockIO
46
+ include InterruptAcceptance
47
+ include SavedState
48
+
49
+ attr_reader :bus, :cycles, :nmi
50
+ attr_accessor :int
51
+
52
+ def initialize(bus)
53
+ @bus = bus
54
+ @cycles = 0
55
+ @a = @f = 0xff
56
+ @b = @c = @d = @e = @h = @l = 0xff
57
+ @af_alt = @bc_alt = @de_alt = @hl_alt = 0xffff
58
+ @ix = @iy = @sp = 0xffff
59
+ @wz = @q = @last_q = 0
60
+ @prefix = 0
61
+ @int = @nmi = @nmi_pending = false
62
+ reset!
63
+ end
64
+
65
+ # The RESET line: the program counter, I, R and the interrupt mode go
66
+ # to 0, and interrupts are disabled.
67
+ def reset!
68
+ @pc = @i = @r = @im = 0
69
+ @iff1 = @iff2 = false
70
+ @halted = @after_ei = @after_ld_a_ir = false
71
+ @nmi_pending = false
72
+ end
73
+
74
+ # The NMI line. Asserting it latches an interrupt, taken after the
75
+ # current instruction, and holding it does nothing more.
76
+ def nmi=(asserted)
77
+ @nmi_pending = true if asserted && !@nmi
78
+ @nmi = asserted
79
+ end
80
+
81
+ # The WAIT line: a bus that holds it during an access lengthens that
82
+ # machine cycle by +states+ T-states.
83
+ def wait(states)
84
+ @cycles += states
85
+ end
86
+
87
+ def step!
88
+ if @nmi_pending
89
+ take_nmi
90
+ elsif @int && @iff1 && !@after_ei
91
+ take_int
92
+ else
93
+ @after_ei = @after_ld_a_ir = false
94
+ @last_q = @q
95
+ @q = 0
96
+ @prefix = 0
97
+ @halted ? idle_fetch : execute(fetch_opcode)
98
+ end
99
+ nil
100
+ end
101
+
102
+ def inspect
103
+ "Cycles: #{@cycles}, PC: #{hex(@pc)}, SP: #{hex(@sp)}, AF: #{hex(af)}, BC: #{hex(bc)}, " \
104
+ "DE: #{hex(de)}, HL: #{hex(hl)}, IX: #{hex(@ix)}, IY: #{hex(@iy)}"
105
+ end
106
+
107
+ private
108
+
109
+ def hex(value)
110
+ value.to_s(16).rjust(4, "0")
111
+ end
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Chips
5
+ class Z80
6
+ # EX AF,AF', EXX, EX DE,HL and EX (SP),HL. Only the last swaps IX or IY
7
+ # after a prefix.
8
+ module Exchanges
9
+ private
10
+
11
+ def exchange_alternates
12
+ bc_alt = @bc_alt
13
+ de_alt = @de_alt
14
+ hl_alt = @hl_alt
15
+ @bc_alt = bc
16
+ @de_alt = de
17
+ @hl_alt = hl
18
+ self.bc = bc_alt
19
+ self.de = de_alt
20
+ self.hl = hl_alt
21
+ end
22
+
23
+ def exchange_af
24
+ af_alt = @af_alt
25
+ @af_alt = af
26
+ self.af = af_alt
27
+ end
28
+
29
+ def exchange_de_hl
30
+ d = @d
31
+ e = @e
32
+ @d = @h
33
+ @e = @l
34
+ @h = d
35
+ @l = e
36
+ end
37
+
38
+ def exchange_stack_top
39
+ low = read_byte(@sp)
40
+ high = read_byte((@sp + 1) & 0xffff)
41
+ @cycles += 1
42
+ value = hl_or_index
43
+ write_byte((@sp + 1) & 0xffff, value >> 8)
44
+ write_byte(@sp, value & 0xff)
45
+ @cycles += 2
46
+ @wz = low | (high << 8)
47
+ self.hl_or_index = @wz
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,91 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Chips
5
+ class Z80
6
+ # The interrupt mode each of ED 46, 4E, 56, 5E, 66, 6E, 76 and 7E sets.
7
+ # 4E and 6E set mode 0 on the NMOS Z80.
8
+ INTERRUPT_MODES = [0, 0, 1, 2, 0, 0, 1, 2].freeze
9
+
10
+ # The ED page: its second quarter, the block instructions, and 8
11
+ # T-states of nothing for the rest.
12
+ module ExtendedPage
13
+ private
14
+
15
+ def execute_extended(opcode)
16
+ case opcode >> 6
17
+ when 1 then extended_operation(opcode)
18
+ when 2 then block_operation(opcode) if (opcode & 0x24) == 0x20
19
+ end
20
+ end
21
+
22
+ def extended_operation(opcode)
23
+ row = (opcode >> 3) & 7
24
+ case opcode & 7
25
+ when 0 then input_register(row)
26
+ when 1 then output_register(row)
27
+ when 2 then add_pair_with_carry(row)
28
+ when 3 then row.nobits?(1) ? store_word(pair(row >> 1)) : set_pair(row >> 1, load_word)
29
+ when 4 then neg
30
+ when 5 then return_from_interrupt
31
+ when 6 then @im = INTERRUPT_MODES[row]
32
+ else special_register(row)
33
+ end
34
+ end
35
+
36
+ # IN r,(C), and IN F,(C) at index 6, which sets the flags alone.
37
+ def input_register(index)
38
+ port = bc
39
+ value = input(port)
40
+ @wz = (port + 1) & 0xffff
41
+ assign_flags((@f & CF) | SZ53P[value])
42
+ set_register(index, value) unless index == 6
43
+ end
44
+
45
+ # OUT (C),r, and at index 6 OUT (C),0.
46
+ def output_register(index)
47
+ port = bc
48
+ output(port, index == 6 ? 0 : register(index))
49
+ @wz = (port + 1) & 0xffff
50
+ end
51
+
52
+ def add_pair_with_carry(row)
53
+ row.nobits?(1) ? sbc16(pair(row >> 1)) : adc16(pair(row >> 1))
54
+ @cycles += 7
55
+ end
56
+
57
+ # RETN and RETI both restore IFF1 from IFF2.
58
+ def return_from_interrupt
59
+ @iff1 = @iff2
60
+ return_from_call
61
+ end
62
+
63
+ # LD I,A, LD R,A, LD A,I, LD A,R, RRD and RLD, and two that do
64
+ # nothing.
65
+ def special_register(row)
66
+ case row
67
+ when 0 then @i = load_ir(@a)
68
+ when 1 then @r = load_ir(@a)
69
+ when 2 then @a = load_a_from_ir(@i)
70
+ when 3 then @a = load_a_from_ir(@r)
71
+ when 4 then rotate_digits(false)
72
+ when 5 then rotate_digits(true)
73
+ end
74
+ end
75
+
76
+ def load_ir(value)
77
+ @cycles += 1
78
+ value
79
+ end
80
+
81
+ # P/V copies IFF2, and an interrupt taken next clears it again.
82
+ def load_a_from_ir(value)
83
+ @cycles += 1
84
+ assign_flags((@f & CF) | SZ53[value] | (@iff2 ? PF : 0))
85
+ @after_ld_a_ir = true
86
+ value
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Chips
5
+ class Z80
6
+ CF = 0x01
7
+ NF = 0x02
8
+ PF = 0x04
9
+ XF = 0x08
10
+ HF = 0x10
11
+ YF = 0x20
12
+ ZF = 0x40
13
+ SF = 0x80
14
+
15
+ # Bits 5 and 3, which most instructions copy from a result.
16
+ XYF = YF | XF
17
+
18
+ # S, Z, Y and X as a result byte sets them.
19
+ SZ53 = Array.new(256) { |v| (v & (SF | XYF)) | (v.zero? ? ZF : 0) }.freeze
20
+
21
+ # P/V as parity: set when a byte has an even number of bits set.
22
+ PARITY = Array.new(256) { |v| (0x6996 >> ((v ^ (v >> 4)) & 0x0f)).nobits?(1) ? PF : 0 }.freeze
23
+
24
+ SZ53P = Array.new(256) { |v| SZ53[v] | PARITY[v] }.freeze
25
+
26
+ # The flags, which the core keeps in F as the chip does. Every
27
+ # instruction that sets them through the ALU also latches them in Q,
28
+ # which SCF and CCF read on the next instruction.
29
+ module Flags
30
+ private
31
+
32
+ def assign_flags(value)
33
+ @f = value
34
+ @q = value
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Chips
5
+ class Z80
6
+ # Taking NMI and INT between instructions. Either wakes a halted CPU,
7
+ # whose program counter already points past the HALT.
8
+ module InterruptAcceptance
9
+ private
10
+
11
+ # An opcode fetch whose byte is ignored, a T-state more, and a call
12
+ # to $0066. IFF2 keeps what IFF1 held, for RETN to restore.
13
+ def take_nmi
14
+ @nmi_pending = false
15
+ @halted = false
16
+ @iff1 = false
17
+ @bus.fetch(@pc)
18
+ refresh
19
+ @cycles += 5
20
+ push(@pc)
21
+ @pc = 0x66
22
+ @wz = 0x66
23
+ end
24
+
25
+ # The acknowledge cycle, an M1 with two wait states, reads a byte
26
+ # from the device. Mode 0 runs it as an opcode, which is a RST in
27
+ # practice, mode 1 calls $0038, and mode 2 calls through the vector
28
+ # at I and that byte.
29
+ def take_int
30
+ @halted = false
31
+ @f &= ~PF if @after_ld_a_ir
32
+ @iff1 = @iff2 = false
33
+ @after_ld_a_ir = false
34
+ @prefix = 0
35
+ data = @bus.acknowledge
36
+ refresh
37
+ @cycles += 6
38
+ return execute(data) if @im.zero?
39
+
40
+ @cycles += 1
41
+ push(@pc)
42
+ @pc = @im == 1 ? 0x38 : read_word((@i << 8) | data)
43
+ @wz = @pc
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,84 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Chips
5
+ class Z80
6
+ # Jumps, calls and returns. Each leaves its target in WZ, and JP cc and
7
+ # CALL cc do whether they jump or not.
8
+ module Jumps
9
+ private
10
+
11
+ # The conditions bits 5-3 pick: NZ Z NC C PO PE P M.
12
+ def condition?(index)
13
+ case index
14
+ when 0 then @f.nobits?(ZF)
15
+ when 1 then @f.anybits?(ZF)
16
+ when 2 then @f.nobits?(CF)
17
+ when 3 then @f.anybits?(CF)
18
+ when 4 then @f.nobits?(PF)
19
+ when 5 then @f.anybits?(PF)
20
+ when 6 then @f.nobits?(SF)
21
+ else @f.anybits?(SF)
22
+ end
23
+ end
24
+
25
+ # NOP, EX AF,AF', DJNZ, JR and JR cc.
26
+ def relative_jump(row)
27
+ case row
28
+ when 0 then nil
29
+ when 1 then exchange_af
30
+ when 2 then decrement_and_jump
31
+ when 3 then jump_relative(fetch_byte)
32
+ else
33
+ offset = fetch_byte
34
+ jump_relative(offset) if condition?(row - 4)
35
+ end
36
+ end
37
+
38
+ def decrement_and_jump
39
+ @cycles += 1
40
+ offset = fetch_byte
41
+ @b = (@b - 1) & 0xff
42
+ jump_relative(offset) unless @b.zero?
43
+ end
44
+
45
+ def jump_relative(offset)
46
+ @cycles += 5
47
+ @pc = (@pc + offset - (offset > 127 ? 256 : 0)) & 0xffff
48
+ @wz = @pc
49
+ end
50
+
51
+ def jump(taken)
52
+ @wz = fetch_word
53
+ @pc = @wz if taken
54
+ end
55
+
56
+ def call(taken)
57
+ @wz = fetch_word
58
+ return unless taken
59
+
60
+ @cycles += 1
61
+ push(@pc)
62
+ @pc = @wz
63
+ end
64
+
65
+ def conditional_return(index)
66
+ @cycles += 1
67
+ return_from_call if condition?(index)
68
+ end
69
+
70
+ def return_from_call
71
+ @pc = pop
72
+ @wz = @pc
73
+ end
74
+
75
+ def restart(address)
76
+ @cycles += 1
77
+ push(@pc)
78
+ @pc = address
79
+ @wz = address
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end