badline 0.13.0 → 0.15.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 (286) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +72 -1
  3. data/CLAUDE.md +42 -12
  4. data/CONTRIBUTING.md +4 -3
  5. data/README.md +76 -13
  6. data/doc/media.md +2 -1
  7. data/doc/pinned-behaviour.md +174 -0
  8. data/doc/snapshot-format.md +1197 -0
  9. data/doc/snapshots.md +90 -40
  10. data/lib/badline/audio/bare_player.rb +46 -17
  11. data/lib/badline/audio/machine_player.rb +6 -10
  12. data/lib/badline/audio/renderer.rb +32 -21
  13. data/lib/badline/c128/banks.rb +7 -6
  14. data/lib/badline/c128/bus/keyed_state.rb +45 -0
  15. data/lib/badline/c128/bus.rb +36 -4
  16. data/lib/badline/c128/drives.rb +6 -25
  17. data/lib/badline/c128/keyed_modules.rb +117 -0
  18. data/lib/badline/c128/keyed_state.rb +91 -0
  19. data/lib/badline/c128/keys.rb +9 -0
  20. data/lib/badline/c128/mmu.rb +9 -8
  21. data/lib/badline/c128/mmu_pages.rb +27 -0
  22. data/lib/badline/c128/modes.rb +19 -9
  23. data/lib/badline/c128/z80_turns.rb +1 -1
  24. data/lib/badline/c128.rb +8 -8
  25. data/lib/badline/c64/attachments.rb +0 -44
  26. data/lib/badline/c64/banked_ram/plus256k.rb +18 -10
  27. data/lib/badline/c64/banked_ram/plus60k.rb +8 -6
  28. data/lib/badline/c64/banked_ram/unexpanded.rb +2 -2
  29. data/lib/badline/c64/bus/debug_register.rb +32 -0
  30. data/lib/badline/c64/bus/extra_sids.rb +80 -0
  31. data/lib/badline/c64/bus/keyed_state.rb +41 -0
  32. data/lib/badline/c64/bus.rb +3 -1
  33. data/lib/badline/c64/cartridge/action_replay.rb +6 -15
  34. data/lib/badline/c64/cartridge/comal80.rb +1 -0
  35. data/lib/badline/c64/cartridge/dinamic.rb +3 -1
  36. data/lib/badline/c64/cartridge/easy_flash.rb +0 -15
  37. data/lib/badline/c64/cartridge/epyx_fastload.rb +0 -8
  38. data/lib/badline/c64/cartridge/final_cartridge3.rb +1 -12
  39. data/lib/badline/c64/cartridge/flash.rb +3 -3
  40. data/lib/badline/c64/cartridge/fun_play.rb +2 -1
  41. data/lib/badline/c64/cartridge/g_mod2.rb +0 -12
  42. data/lib/badline/c64/cartridge/game_system.rb +2 -1
  43. data/lib/badline/c64/cartridge/geo_ram.rb +0 -16
  44. data/lib/badline/c64/cartridge/kcs_power.rb +0 -8
  45. data/lib/badline/c64/cartridge/keyed_state.rb +514 -0
  46. data/lib/badline/c64/cartridge/magic_desk.rb +2 -1
  47. data/lib/badline/c64/cartridge/ocean.rb +1 -0
  48. data/lib/badline/c64/cartridge/pagefox.rb +1 -10
  49. data/lib/badline/c64/cartridge/retro_replay.rb +0 -8
  50. data/lib/badline/c64/cartridge/rgcd.rb +2 -11
  51. data/lib/badline/c64/cartridge/super_games.rb +3 -12
  52. data/lib/badline/c64/cartridge/zaxxon.rb +1 -16
  53. data/lib/badline/c64/cartridge.rb +4 -30
  54. data/lib/badline/c64/kernal_traps.rb +28 -25
  55. data/lib/badline/c64/keyed_modules.rb +115 -0
  56. data/lib/badline/c64/keyed_state.rb +68 -0
  57. data/lib/badline/c64/reu/dma.rb +0 -4
  58. data/lib/badline/c64/reu/keyed_state.rb +140 -0
  59. data/lib/badline/c64/reu/ram.rb +0 -15
  60. data/lib/badline/c64/reu.rb +1 -3
  61. data/lib/badline/c64/true_drives.rb +56 -5
  62. data/lib/badline/c64.rb +7 -3
  63. data/lib/badline/chips/cia/interrupt_register.rb +0 -17
  64. data/lib/badline/chips/cia/keyed_parts.rb +213 -0
  65. data/lib/badline/chips/cia/serial.rb +0 -4
  66. data/lib/badline/chips/cia/time_of_day.rb +0 -22
  67. data/lib/badline/chips/cia/timer.rb +0 -20
  68. data/lib/badline/chips/cia.rb +2 -2
  69. data/lib/badline/chips/cpu/core.rb +18 -2
  70. data/lib/badline/chips/cpu/keyed_state.rb +177 -0
  71. data/lib/badline/chips/cpu/microcode.rb +16 -0
  72. data/lib/badline/chips/cpu/port.rb +20 -3
  73. data/lib/badline/chips/cpu.rb +5 -0
  74. data/lib/badline/chips/sid/decimator.rb +10 -8
  75. data/lib/badline/chips/sid/envelope.rb +1 -6
  76. data/lib/badline/chips/sid/filter.rb +0 -14
  77. data/lib/badline/chips/sid/keyed_parts.rb +286 -0
  78. data/lib/badline/chips/sid/voice.rb +0 -10
  79. data/lib/badline/chips/sid/waveform.rb +0 -2
  80. data/lib/badline/chips/sid.rb +1 -2
  81. data/lib/badline/chips/ted/beam.rb +118 -0
  82. data/lib/badline/chips/ted/fetches.rb +199 -0
  83. data/lib/badline/chips/ted/keyed_state.rb +156 -0
  84. data/lib/badline/chips/ted/modes.rb +134 -0
  85. data/lib/badline/chips/ted/palette.rb +43 -0
  86. data/lib/badline/chips/ted/picture.rb +182 -0
  87. data/lib/badline/chips/ted/sound/output.rb +86 -0
  88. data/lib/badline/chips/ted/sound.rb +284 -0
  89. data/lib/badline/chips/ted/timers.rb +66 -0
  90. data/lib/badline/chips/ted.rb +190 -0
  91. data/lib/badline/chips/tia.rb +61 -0
  92. data/lib/badline/chips/vdc/keyed_parts.rb +105 -0
  93. data/lib/badline/chips/vdc/painter.rb +0 -12
  94. data/lib/badline/chips/vdc/raster.rb +0 -16
  95. data/lib/badline/chips/vdc/window.rb +0 -9
  96. data/lib/badline/chips/vdc.rb +1 -2
  97. data/lib/badline/chips/via/control_lines.rb +0 -15
  98. data/lib/badline/chips/via/interrupt_register.rb +0 -9
  99. data/lib/badline/chips/via/keyed_parts.rb +163 -0
  100. data/lib/badline/chips/via/shift_register.rb +0 -14
  101. data/lib/badline/chips/via/timer1.rb +0 -13
  102. data/lib/badline/chips/via/timer2.rb +0 -18
  103. data/lib/badline/chips/via.rb +1 -2
  104. data/lib/badline/chips/vic/border_mask.rb +0 -10
  105. data/lib/badline/chips/vic/collisions.rb +0 -11
  106. data/lib/badline/chips/vic/color_patches.rb +0 -11
  107. data/lib/badline/chips/vic/display_state.rb +0 -19
  108. data/lib/badline/chips/vic/graphics_shifter.rb +0 -4
  109. data/lib/badline/chips/vic/keyed_parts.rb +228 -0
  110. data/lib/badline/chips/vic/keyed_sprites.rb +225 -0
  111. data/lib/badline/chips/vic/keyed_state.rb +102 -0
  112. data/lib/badline/chips/vic/register_log.rb +0 -18
  113. data/lib/badline/chips/vic/registers.rb +0 -9
  114. data/lib/badline/chips/vic/sequencer.rb +0 -2
  115. data/lib/badline/chips/vic/sprite/internal_bus.rb +0 -11
  116. data/lib/badline/chips/vic/sprite.rb +0 -2
  117. data/lib/badline/chips/vic/sprites.rb +0 -3
  118. data/lib/badline/chips/vic.rb +6 -2
  119. data/lib/badline/chips/vic_i/keyed_parts.rb +142 -0
  120. data/lib/badline/chips/vic_i/painter.rb +0 -4
  121. data/lib/badline/chips/vic_i/sound.rb +38 -46
  122. data/lib/badline/chips/vic_i.rb +2 -2
  123. data/lib/badline/chips/z80/core.rb +2 -2
  124. data/lib/badline/chips/z80/keyed_state.rb +73 -0
  125. data/lib/badline/chips.rb +10 -0
  126. data/lib/badline/core.rb +4 -21
  127. data/lib/badline/drives/datasette/keyed_state.rb +43 -0
  128. data/lib/badline/drives/datasette.rb +62 -12
  129. data/lib/badline/drives/engine/core.rb +3 -0
  130. data/lib/badline/drives/engine/serial_lines.rb +4 -7
  131. data/lib/badline/drives/model1541/bus.rb +0 -13
  132. data/lib/badline/drives/model1541/disk.rb +9 -8
  133. data/lib/badline/drives/model1541/keyed_state.rb +251 -0
  134. data/lib/badline/drives/model1541/mechanism.rb +0 -2
  135. data/lib/badline/drives/model1541.rb +1 -2
  136. data/lib/badline/drives/model1571/bus.rb +0 -13
  137. data/lib/badline/drives/model1571/keyed_state.rb +108 -0
  138. data/lib/badline/drives/model1571/wd1770.rb +0 -14
  139. data/lib/badline/drives/model1571.rb +1 -2
  140. data/lib/badline/drives/model1581/bus.rb +0 -13
  141. data/lib/badline/drives/model1581/disk.rb +0 -4
  142. data/lib/badline/drives/model1581/keyed_state.rb +280 -0
  143. data/lib/badline/drives/model1581/mechanism.rb +0 -21
  144. data/lib/badline/drives/model1581/slot.rb +0 -18
  145. data/lib/badline/drives/model1581/wd1772.rb +0 -2
  146. data/lib/badline/drives/model1581.rb +2 -2
  147. data/lib/badline/drives.rb +8 -0
  148. data/lib/badline/frontend/app.rb +3 -3
  149. data/lib/badline/frontend/boot.rb +4 -2
  150. data/lib/badline/frontend/controls.rb +25 -5
  151. data/lib/badline/frontend/drive_led.rb +44 -21
  152. data/lib/badline/frontend/keys.rb +14 -2
  153. data/lib/badline/frontend/media_slots.rb +11 -1
  154. data/lib/badline/frontend/menu/menu_dialogs.rb +4 -3
  155. data/lib/badline/frontend/menu/menu_media.rb +13 -3
  156. data/lib/badline/frontend/menu/menu_pages.rb +8 -8
  157. data/lib/badline/frontend/menu/menu_ports.rb +13 -1
  158. data/lib/badline/frontend/screen.rb +33 -12
  159. data/lib/badline/frontend/screens.rb +2 -1
  160. data/lib/badline/frontend/snapshots.rb +12 -1
  161. data/lib/badline/frontend/sound.rb +4 -4
  162. data/lib/badline/frontend/timeline.rb +43 -12
  163. data/lib/badline/input/matrix_typist.rb +98 -0
  164. data/lib/badline/input.rb +1 -0
  165. data/lib/badline/kernal_trap/chrout.rb +45 -0
  166. data/lib/badline/kernal_trap/dos/channel.rb +0 -27
  167. data/lib/badline/kernal_trap/dos/channels.rb +0 -25
  168. data/lib/badline/kernal_trap/dos/memory.rb +0 -9
  169. data/lib/badline/kernal_trap/dos/status.rb +0 -8
  170. data/lib/badline/kernal_trap/dos/write_file.rb +0 -18
  171. data/lib/badline/kernal_trap/dos.rb +0 -19
  172. data/lib/badline/kernal_trap/file_routine.rb +4 -4
  173. data/lib/badline/kernal_trap/keyed_state.rb +150 -0
  174. data/lib/badline/kernal_trap/layout.rb +75 -11
  175. data/lib/badline/kernal_trap/load.rb +14 -16
  176. data/lib/badline/kernal_trap/routine.rb +12 -0
  177. data/lib/badline/kernal_trap/save.rb +8 -18
  178. data/lib/badline/kernal_trap/serial.rb +1 -17
  179. data/lib/badline/kernal_trap.rb +2 -0
  180. data/lib/badline/machine/keyboard_buffer.rb +49 -0
  181. data/lib/badline/machine/settling.rb +29 -0
  182. data/lib/badline/machine.rb +29 -6
  183. data/lib/badline/media/boot_disk.rb +14 -2
  184. data/lib/badline/media/extensions.rb +10 -0
  185. data/lib/badline/media/plus4_media.rb +68 -0
  186. data/lib/badline/media/program.rb +20 -6
  187. data/lib/badline/media.rb +33 -12
  188. data/lib/badline/memory.rb +3 -6
  189. data/lib/badline/options/family.rb +6 -2
  190. data/lib/badline/options/help.rb +66 -16
  191. data/lib/badline/options/table.rb +17 -2
  192. data/lib/badline/options/validation.rb +26 -2
  193. data/lib/badline/options.rb +42 -9
  194. data/lib/badline/plus4/acia.rb +45 -0
  195. data/lib/badline/plus4/bus.rb +375 -0
  196. data/lib/badline/plus4/cassette_sense.rb +21 -0
  197. data/lib/badline/plus4/cpu.rb +10 -0
  198. data/lib/badline/plus4/cpu_port.rb +93 -0
  199. data/lib/badline/plus4/keyboard_port.rb +76 -0
  200. data/lib/badline/plus4/keyed_modules.rb +99 -0
  201. data/lib/badline/plus4/keyed_parts.rb +143 -0
  202. data/lib/badline/plus4/keyed_state.rb +41 -0
  203. data/lib/badline/plus4/model.rb +38 -0
  204. data/lib/badline/plus4/user_port.rb +31 -0
  205. data/lib/badline/plus4.rb +240 -0
  206. data/lib/badline/roms/README +38 -0
  207. data/lib/badline/roms/plus4/basic.rom +0 -0
  208. data/lib/badline/roms/plus4/function-high.rom +0 -0
  209. data/lib/badline/roms/plus4/function-low.rom +0 -0
  210. data/lib/badline/roms/plus4/kernal-ntsc.rom +0 -0
  211. data/lib/badline/roms/plus4/kernal-pal.rom +0 -0
  212. data/lib/badline/snapshot/c128_setup.rb +9 -20
  213. data/lib/badline/snapshot/c64_setup.rb +28 -24
  214. data/lib/badline/snapshot/container.rb +6 -0
  215. data/lib/badline/snapshot/field_doc/markdown.rb +113 -0
  216. data/lib/badline/snapshot/field_doc.rb +148 -0
  217. data/lib/badline/snapshot/image.rb +143 -28
  218. data/lib/badline/snapshot/keyed/cursor.rb +40 -0
  219. data/lib/badline/snapshot/keyed/modules.rb +66 -0
  220. data/lib/badline/snapshot/keyed/reader.rb +188 -0
  221. data/lib/badline/snapshot/keyed/recorder.rb +88 -0
  222. data/lib/badline/snapshot/keyed/report.rb +26 -0
  223. data/lib/badline/snapshot/keyed/writer.rb +55 -0
  224. data/lib/badline/snapshot/keyed.rb +64 -0
  225. data/lib/badline/snapshot/machine_state.rb +17 -64
  226. data/lib/badline/snapshot/plus4_setup.rb +39 -0
  227. data/lib/badline/snapshot/storage_setup.rb +29 -34
  228. data/lib/badline/snapshot/vic20_setup.rb +6 -15
  229. data/lib/badline/snapshot/vice/reu1764.rb +2 -2
  230. data/lib/badline/snapshot/vice.rb +7 -31
  231. data/lib/badline/snapshot.rb +48 -20
  232. data/lib/badline/storage/crt_file.rb +3 -1
  233. data/lib/badline/storage/g64_image.rb +9 -4
  234. data/lib/badline/storage/tap.rb +57 -20
  235. data/lib/badline/support/checkpoint.rb +3 -2
  236. data/lib/badline/support/plus4_checkpoint.rb +42 -0
  237. data/lib/badline/version.rb +1 -1
  238. data/lib/badline/vic20/attachments.rb +3 -0
  239. data/lib/badline/vic20/bus/keyed_state.rb +52 -0
  240. data/lib/badline/vic20/bus.rb +1 -2
  241. data/lib/badline/vic20/keyed_modules.rb +73 -0
  242. data/lib/badline/vic20/keyed_state.rb +45 -0
  243. data/lib/badline/vic20.rb +5 -5
  244. data/lib/badline.rb +1 -0
  245. metadata +75 -42
  246. data/lib/badline/c128/bus/saved_state.rb +0 -53
  247. data/lib/badline/c128/saved_state.rb +0 -117
  248. data/lib/badline/c64/bus/saved_state.rb +0 -68
  249. data/lib/badline/c64/cartridge/flash/saved_state.rb +0 -40
  250. data/lib/badline/c64/cartridge/retro_replay/saved_state.rb +0 -47
  251. data/lib/badline/c64/cartridge/saved_state.rb +0 -63
  252. data/lib/badline/c64/reu/dma/saved_state.rb +0 -52
  253. data/lib/badline/c64/reu/saved_state.rb +0 -55
  254. data/lib/badline/c64/saved_state.rb +0 -112
  255. data/lib/badline/chips/cia/saved_state.rb +0 -49
  256. data/lib/badline/chips/cia/serial/saved_state.rb +0 -45
  257. data/lib/badline/chips/cpu/saved_state.rb +0 -117
  258. data/lib/badline/chips/sid/envelope/saved_state.rb +0 -70
  259. data/lib/badline/chips/sid/filter/saved_state.rb +0 -42
  260. data/lib/badline/chips/sid/saved_state.rb +0 -52
  261. data/lib/badline/chips/sid/waveform/saved_state.rb +0 -68
  262. data/lib/badline/chips/vdc/saved_state.rb +0 -36
  263. data/lib/badline/chips/via/saved_state.rb +0 -44
  264. data/lib/badline/chips/vic/graphics_shifter/saved_state.rb +0 -40
  265. data/lib/badline/chips/vic/saved_state.rb +0 -82
  266. data/lib/badline/chips/vic/sequencer/saved_state.rb +0 -91
  267. data/lib/badline/chips/vic/sprite/saved_state.rb +0 -66
  268. data/lib/badline/chips/vic/sprites/saved_state.rb +0 -59
  269. data/lib/badline/chips/vic_i/painter/saved_state.rb +0 -40
  270. data/lib/badline/chips/vic_i/saved_state.rb +0 -55
  271. data/lib/badline/chips/z80/saved_state.rb +0 -71
  272. data/lib/badline/chrout_trap.rb +0 -43
  273. data/lib/badline/debug_register.rb +0 -28
  274. data/lib/badline/drives/datasette/saved_state.rb +0 -37
  275. data/lib/badline/drives/model1541/disk/saved_state.rb +0 -88
  276. data/lib/badline/drives/model1541/mechanism/saved_state.rb +0 -72
  277. data/lib/badline/drives/model1541/saved_state.rb +0 -44
  278. data/lib/badline/drives/model1571/saved_state.rb +0 -47
  279. data/lib/badline/drives/model1581/disk/saved_state.rb +0 -89
  280. data/lib/badline/drives/model1581/saved_state.rb +0 -42
  281. data/lib/badline/drives/model1581/wd1772/saved_state.rb +0 -68
  282. data/lib/badline/keyboard_buffer.rb +0 -33
  283. data/lib/badline/snapshot/setup.rb +0 -31
  284. data/lib/badline/snapshot/state.rb +0 -179
  285. data/lib/badline/vic20/bus/saved_state.rb +0 -35
  286. data/lib/badline/vic20/saved_state.rb +0 -110
@@ -1,70 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- module Chips
5
- class SID
6
- class Envelope
7
- # A snapshot of an envelope: its rates, the gate, the state and the
8
- # counters and pipelines between them, and the same fields as reSID
9
- # keeps them, for VICE's SIDEXTENDED module.
10
- module SavedState
11
- # The fields reSID keeps for an envelope between cycles: the rate and
12
- # exponential counters, the level, the state as an index into STATES,
13
- # whether it holds at zero, the two periods and the pipeline.
14
- def resid_fields
15
- [@rate_counter, @exponential_counter, @counter, STATES.index(@state).to_i, @hold_zero ? 1 : 0,
16
- @rate_period, @exponential_period, @envelope_pipeline]
17
- end
18
-
19
- # Takes the fields resid_fields gives from `fields`, from `at` on.
20
- def restore_resid_fields(fields, at)
21
- @rate_counter = fields[at]
22
- @exponential_counter = fields[at + 1]
23
- @counter = @env3 = fields[at + 2]
24
- state = fields[at + 3]
25
- @state = @next_state = STATES.fetch(state.clamp(0, STATES.length - 1)).to_sym
26
- @hold_zero = fields[at + 4] != 0
27
- @rate_period = fields[at + 5]
28
- @exponential_period = fields[at + 6]
29
- @envelope_pipeline = fields[at + 7]
30
- end
31
-
32
- def save_state(out)
33
- [@attack, @decay, @sustain, @release].each { |rate| out.int(rate) }
34
- out.boolean(@gate).int(STATES.index(@state)).int(STATES.index(@next_state))
35
- out.int(@counter).int(@env3).int(@rate_counter).int(@rate_period).boolean(@reset_rate_counter)
36
- out.int(@exponential_counter).int(@exponential_period)
37
- out.int(@state_pipeline).int(@envelope_pipeline).int(@exponential_pipeline).boolean(@hold_zero)
38
- end
39
-
40
- def load_state(input)
41
- @attack = input.int
42
- @decay = input.int
43
- @sustain = input.int
44
- @release = input.int
45
- @gate = input.boolean?
46
- @state = STATES.fetch(input.int).to_sym
47
- @next_state = STATES.fetch(input.int).to_sym
48
- load_counters(input)
49
- end
50
-
51
- private
52
-
53
- def load_counters(input)
54
- @counter = input.int
55
- @env3 = input.int
56
- @rate_counter = input.int
57
- @rate_period = input.int
58
- @reset_rate_counter = input.boolean?
59
- @exponential_counter = input.int
60
- @exponential_period = input.int
61
- @state_pipeline = input.int
62
- @envelope_pipeline = input.int
63
- @exponential_pipeline = input.int
64
- @hold_zero = input.boolean?
65
- end
66
- end
67
- end
68
- end
69
- end
70
- end
@@ -1,42 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- module Chips
5
- class SID
6
- class Filter
7
- # The filter's state for a snapshot.
8
- module SavedState
9
- # The registers as the filter decoded them and its integrators. The
10
- # W0 table is the model's.
11
- def save_state(out)
12
- out.int(@cutoff).int(@routing).int(@mode).int(@volume).boolean(@voice3_off).int(@w0).int(@resonance)
13
- [@highpass, @bandpass, @lowpass, @unfiltered, @input].each { |value| out.int(value) }
14
- @external.save_state(out)
15
- end
16
-
17
- def load_state(input)
18
- @cutoff = input.int
19
- @routing = input.int
20
- @mode = input.int
21
- @volume = input.int
22
- @voice3_off = input.boolean?
23
- @w0 = input.int
24
- @resonance = input.int
25
- load_integrators(input)
26
- end
27
-
28
- private
29
-
30
- def load_integrators(input)
31
- @highpass = input.int
32
- @bandpass = input.int
33
- @lowpass = input.int
34
- @unfiltered = input.int
35
- @input = input.int
36
- @external.load_state(input)
37
- end
38
- end
39
- end
40
- end
41
- end
42
- end
@@ -1,52 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- module Chips
5
- class SID
6
- # The SID's state for a snapshot.
7
- module SavedState
8
- # How far the recording has got into the sample it is averaging, for
9
- # a host that carries on recording from a saved state: it calls
10
- # #record, then #load_recording.
11
- def save_recording(out)
12
- decimator = @decimator
13
- raise ArgumentError, "the SID isn't recording" if decimator.nil?
14
-
15
- out.marker("RECORDING")
16
- decimator.save_state(out)
17
- end
18
-
19
- def load_recording(input)
20
- decimator = @decimator
21
- raise ArgumentError, "the SID isn't recording" if decimator.nil?
22
-
23
- input.marker("RECORDING")
24
- decimator.load_state(input)
25
- end
26
-
27
- # The registers, the data bus, the voices and the filter, and the span
28
- # the DSP has yet to catch up on, as it stands: saving leaves the SID
29
- # as it was. Whether it synthesizes or records is the host's.
30
- def save_state(out)
31
- out.marker("SID")
32
- @registers.save_state(out)
33
- out.int(@bus_value).int(@bus_ttl).int(@pending_cycles).ints(@deferred_writes)
34
- @voices.each { |voice| voice.save_state(out) }
35
- @filter.save_state(out)
36
- end
37
-
38
- def load_state(input)
39
- input.marker("SID")
40
- @registers.load_state(input)
41
- @bus_value = input.int
42
- @bus_ttl = input.int
43
- @pending_cycles = input.int
44
- input.ints_into(@deferred_writes)
45
- @voices.each { |voice| voice.load_state(input) }
46
- @filter.load_state(input)
47
- update_span_rules
48
- end
49
- end
50
- end
51
- end
52
- end
@@ -1,68 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- module Chips
5
- class SID
6
- class Waveform
7
- # A snapshot of an oscillator: its phase, the noise register and the
8
- # output latch, and the same fields as reSID keeps them, for VICE's
9
- # SIDEXTENDED module. The model's tables and the voices it syncs with
10
- # are the SID's wiring.
11
- module SavedState
12
- # The fields reSID keeps for an oscillator between cycles: the phase,
13
- # the noise register, its shift pipeline and reset countdown, the
14
- # floating output's countdown and the pulse level.
15
- def resid_fields
16
- [@accumulator, @shift_register, @shift_pipeline, @shift_register_reset, @floating_ttl, @pulse]
17
- end
18
-
19
- # Takes the fields resid_fields gives from `fields`, from `at` on.
20
- def restore_resid_fields(fields, at)
21
- @accumulator = fields[at]
22
- @shift_register = fields[at + 1]
23
- @shift_pipeline = fields[at + 2]
24
- @shift_register_reset = fields[at + 3]
25
- @floating_ttl = fields[at + 4]
26
- @pulse = fields[at + 5]
27
- @stale = true
28
- end
29
-
30
- def save_state(out)
31
- out.int(@accumulator).int(@delayed_triangle).int(@delayed_sawtooth)
32
- out.int(@shift_register).int(@shift_register_reset).int(@shift_pipeline)
33
- out.int(@frequency).int(@pulse_width).int(@selected)
34
- [@test, @ring, @sync, @msb_rising].each { |flag| out.boolean(flag) }
35
- out.int(@floating).int(@floating_ttl).int(@pulse).int(@output).boolean(@stale)
36
- end
37
-
38
- def load_state(input)
39
- @accumulator = input.int
40
- @delayed_triangle = input.int
41
- @delayed_sawtooth = input.int
42
- @shift_register = input.int
43
- @shift_register_reset = input.int
44
- @shift_pipeline = input.int
45
- @frequency = input.int
46
- @pulse_width = input.int
47
- @selected = input.int
48
- load_latches(input)
49
- end
50
-
51
- private
52
-
53
- def load_latches(input)
54
- @test = input.boolean?
55
- @ring = input.boolean?
56
- @sync = input.boolean?
57
- @msb_rising = input.boolean?
58
- @floating = input.int
59
- @floating_ttl = input.int
60
- @pulse = input.int
61
- @output = input.int
62
- @stale = input.boolean?
63
- end
64
- end
65
- end
66
- end
67
- end
68
- end
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- module Chips
5
- class VDC
6
- # The VDC's state for a snapshot.
7
- module SavedState
8
- # Everything the VDC holds but its display, which it paints again
9
- # while it renders: the registers, the RAM, the data port and the
10
- # raster. Whether it renders is the host's.
11
- def save_state(out)
12
- out.marker("VDC")
13
- out.ints(@registers).blob(@memory.ram)
14
- out.int(@selected).int(@read_latch).int(@write_data).int(@busy_until).int(@phase).int(@line_units)
15
- @raster.save_state(out)
16
- @painter.save_state(out)
17
- end
18
-
19
- def load_state(input)
20
- input.marker("VDC")
21
- input.ints_into(@registers)
22
- input.blob_into(@memory.ram)
23
- @memory.mode64 = @registers[28].anybits?(0x10)
24
- @selected = input.int
25
- @read_latch = input.int
26
- @write_data = input.int
27
- @busy_until = input.int
28
- @phase = input.int
29
- @line_units = input.int
30
- @raster.load_state(input)
31
- @painter.load_state(input)
32
- end
33
- end
34
- end
35
- end
36
- end
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- module Chips
5
- class VIA
6
- # Saving and restoring a VIA for a snapshot.
7
- module SavedState
8
- # The registers, the timers, the shift register, the interrupt flags
9
- # and the control lines. The peripheral is the drive's wiring.
10
- def save_state(out)
11
- out.int(@ora).int(@orb).int(@ddra).int(@ddrb).int(@latch_a).int(@latch_b).int(@acr).int(@pcr)
12
- out.boolean(@pb6_high).boolean(@sr_uses_t2)
13
- @t1.save_state(out)
14
- @t2.save_state(out)
15
- @shift_register.save_state(out)
16
- @ifr.save_state(out)
17
- @ca.save_state(out)
18
- @cb.save_state(out)
19
- end
20
-
21
- # Puts the state back without telling the peripheral, which restores
22
- # its own.
23
- def load_state(input)
24
- @ora = input.int
25
- @orb = input.int
26
- @ddra = input.int
27
- @ddrb = input.int
28
- @latch_a = input.int
29
- @latch_b = input.int
30
- @acr = input.int
31
- @pcr = input.int
32
- @pb6_high = input.boolean?
33
- @sr_uses_t2 = input.boolean?
34
- @t1.load_state(input)
35
- @t2.load_state(input)
36
- @shift_register.load_state(input)
37
- @ifr.load_state(input)
38
- @ca.load_state(input)
39
- @cb.load_state(input)
40
- end
41
- end
42
- end
43
- end
44
- end
@@ -1,40 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- module Chips
5
- class VIC
6
- class GraphicsShifter
7
- # The shifter's state for a snapshot.
8
- module SavedState
9
- def save_state(out)
10
- out.int(@next_ecm_bmm).int(@black_below).ints(@colors).booleans(@fg)
11
- out.int(@gbuf).int(@vbuf).int(@cbuf).int(@flop).int(@pixel)
12
- out.int(@mode_lookup).int(@mode_read).boolean(@late_mcm).boolean(@late_read)
13
- end
14
-
15
- def load_state(input)
16
- @next_ecm_bmm = input.int
17
- @black_below = input.int
18
- input.ints_into(@colors)
19
- input.booleans_into(@fg)
20
- load_buffers(input)
21
- @mode_lookup = input.int
22
- @mode_read = input.int
23
- @late_mcm = input.boolean?
24
- @late_read = input.boolean?
25
- end
26
-
27
- private
28
-
29
- def load_buffers(input)
30
- @gbuf = input.int
31
- @vbuf = input.int
32
- @cbuf = input.int
33
- @flop = input.int
34
- @pixel = input.int
35
- end
36
- end
37
- end
38
- end
39
- end
40
- end
@@ -1,82 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- module Chips
5
- class VIC
6
- # The VIC's state for a snapshot.
7
- module SavedState
8
- # Everything the VIC holds between cycles: the beam, the fetch and
9
- # g-access pipeline, the light pen and raster latches, the finished
10
- # lines, on the VIC-IIe the display line and the TEST bit's wrap, the
11
- # registers and the display, sequencer and sprite logic.
12
- # Whether it renders is the host's, and every line comes back dirty so
13
- # a front end repaints.
14
- def save_state(out)
15
- out.marker("VIC")
16
- out.int(@column).int(@rasterline)
17
- out.int(@g_tick).ints(@g_kind).int(@g_kept_char).int(@g_kept_color).boolean(@g_display)
18
- out.int(@fetch_d011).boolean(@lp_triggered).boolean(@lp_low).boolean(@raster_match)
19
- out.int(@vic_bank.lines)
20
- out.blob(@character_buffer).blob(@color_buffer).booleans(@sprite_ba)
21
- @lines.each { |line| out.blob(line) }
22
- out.int(@output_line).boolean(@test_wrap) if @iie
23
- @registers.save_state(out)
24
- @display_state.save_state(out)
25
- @sequencer.save_state(out)
26
- @sprites.save_state(out)
27
- end
28
-
29
- def load_state(input)
30
- input.marker("VIC")
31
- load_beam(input)
32
- load_buffers(input)
33
- load_lines(input)
34
- load_test_state(input) if @iie
35
- @registers.load_state(input)
36
- @display_state.load_state(input)
37
- @sequencer.load_state(input)
38
- @sprites.load_state(input)
39
- end
40
-
41
- private
42
-
43
- def load_beam(input)
44
- @column = input.int
45
- @rasterline = @output_line = input.int
46
- @g_tick = input.int
47
- input.ints_into(@g_kind)
48
- @g_kept_char = input.int
49
- @g_kept_color = input.int
50
- @g_display = input.boolean?
51
- @fetch_d011 = input.int
52
- @lp_triggered = input.boolean?
53
- @lp_low = input.boolean?
54
- @raster_match = input.boolean?
55
- @vic_bank.lines = input.int
56
- end
57
-
58
- def load_buffers(input)
59
- input.blob_into(@character_buffer)
60
- input.blob_into(@color_buffer)
61
- input.booleans_into(@sprite_ba)
62
- end
63
-
64
- # The VIC-IIe's display line and TEST wrap, which only its TEST bit
65
- # moves off the raster line.
66
- def load_test_state(input)
67
- @output_line = input.int
68
- @test_wrap = input.boolean?
69
- end
70
-
71
- # The display is the finished lines one after another.
72
- def load_lines(input)
73
- @lines.each_with_index do |line, number|
74
- input.blob_into(line)
75
- @display[number * @width, @width] = line
76
- end
77
- @dirty_lines.fill(true)
78
- end
79
- end
80
- end
81
- end
82
- end
@@ -1,91 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- module Chips
5
- class VIC
6
- class Sequencer
7
- # The sequencer's save_state and load_state.
8
- module SavedState
9
- FG_SHIFTER = -1
10
- PAIR_CODES = 256
11
-
12
- # The line buffers, the border flip-flops, the g-access ring and the
13
- # pixel pipeline. The foreground masks the groups point at go as
14
- # FG_SHIFTER for the shift register's, or their data byte in
15
- # GraphicsMode's HIRES_FG, or that plus 256 in its PAIR_FG. The left
16
- # vertical border compare goes as -1 before it has run.
17
- def save_state(out)
18
- out.int(@line).boolean(@first_csel).int(@left_vertical_border.nil? ? -1 : bit(@left_vertical_border))
19
- out.blob(@colors).booleans(@fg)
20
- @border_mask.save_state(out)
21
- out.ints(@cur_colors).int(fg_code(@cur_fg)).ints(@prev_colors).int(fg_code(@prev_fg))
22
- out.boolean(@vertical_border).boolean(@vertical_armed).boolean(@main_border)
23
- @color_patches.save_state(out)
24
- @shifter.save_state(out)
25
- out.int(@xscroll).int(@last_shift).int(@last_mode).boolean(@settling).boolean(@prev_fresh).boolean(@check)
26
- out.ints(@ring_data).ints(@ring_char).ints(@ring_color)
27
- end
28
-
29
- def load_state(input)
30
- load_line(input)
31
- @border_mask.load_state(input)
32
- input.ints_into(@cur_colors)
33
- @cur_fg = fg_pattern(input.int)
34
- input.ints_into(@prev_colors)
35
- @prev_fg = fg_pattern(input.int)
36
- @vertical_border = input.boolean?
37
- @vertical_armed = input.boolean?
38
- @main_border = input.boolean?
39
- @color_patches.load_state(input)
40
- @shifter.load_state(input)
41
- load_pipeline(input)
42
- end
43
-
44
- private
45
-
46
- def bit(flag) = flag ? 1 : 0
47
-
48
- def load_line(input)
49
- @line = input.int
50
- @first_csel = input.boolean?
51
- left = input.int
52
- @left_vertical_border = left.negative? ? nil : left == 1
53
- input.blob_into(@colors)
54
- input.booleans_into(@fg)
55
- end
56
-
57
- def load_pipeline(input)
58
- @xscroll = input.int
59
- @last_shift = input.int
60
- @last_mode = input.int
61
- @settling = input.boolean?
62
- @prev_fresh = input.boolean?
63
- @check = input.boolean?
64
- input.ints_into(@ring_data)
65
- input.ints_into(@ring_char)
66
- input.ints_into(@ring_color)
67
- end
68
-
69
- def fg_code(pattern)
70
- return FG_SHIFTER if pattern.equal?(@shifter.fg)
71
-
72
- hires = GraphicsMode::HIRES_FG.index { |fg| fg.equal?(pattern) }
73
- return hires if hires
74
-
75
- pair = GraphicsMode::PAIR_FG.index { |fg| fg.equal?(pattern) }
76
- raise ArgumentError, "a foreground mask the sequencer doesn't know" unless pair
77
-
78
- PAIR_CODES + pair
79
- end
80
-
81
- def fg_pattern(code)
82
- return @shifter.fg if code == FG_SHIFTER
83
- return GraphicsMode::HIRES_FG.fetch(code) if code < PAIR_CODES
84
-
85
- GraphicsMode::PAIR_FG.fetch(code - PAIR_CODES)
86
- end
87
- end
88
- end
89
- end
90
- end
91
- end
@@ -1,66 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- module Chips
5
- class VIC
6
- class Sprite
7
- # The sprite's save_state and load_state.
8
- module SavedState
9
- # The shift register, MC, MCBASE, the expansion flip-flop and whether
10
- # the sprite shows, for a VICE snapshot.
11
- attr_reader :sr, :mc, :mcbase, :exp_ff, :display_on
12
-
13
- # Sets MC, MCBASE, the expansion flip-flop, whether the sprite's DMA
14
- # runs and whether it shows, as a VICE snapshot gives them.
15
- def restore_counters(counter, base, expanded, dma, shows)
16
- @mc = counter
17
- @mcbase = base
18
- @exp_ff = expanded
19
- @dma = dma
20
- @display_on = shows
21
- end
22
-
23
- def save_state(out)
24
- out.boolean(@dma).boolean(@display_on).int(@mcbase).int(@mc).boolean(@exp_ff).optional_int(@crunched_mc)
25
- out.int(@bits).boolean(@row_ready).optional_int(@prev_bits).boolean(@first_byte_lost).boolean(@blind)
26
- out.int(@show_from).optional_int(@stop_x)
27
- out.ints(@codes).int(@leftmost).int(@span).ints(@reload_codes).int(@reload_leftmost).int(@reload_span)
28
- out.int(@sr).int(@latch).boolean(@mc_flop).boolean(@xe_flop)
29
- end
30
-
31
- def load_state(input)
32
- load_counters(input)
33
- @show_from = input.int
34
- @stop_x = input.optional_int
35
- input.ints_into(@codes)
36
- @leftmost = input.int
37
- @span = input.int
38
- input.ints_into(@reload_codes)
39
- @reload_leftmost = input.int
40
- @reload_span = input.int
41
- @sr = input.int
42
- @latch = input.int
43
- @mc_flop = input.boolean?
44
- @xe_flop = input.boolean?
45
- end
46
-
47
- private
48
-
49
- def load_counters(input)
50
- @dma = input.boolean?
51
- @display_on = input.boolean?
52
- @mcbase = input.int
53
- @mc = input.int
54
- @exp_ff = input.boolean?
55
- @crunched_mc = input.optional_int
56
- @bits = input.int
57
- @row_ready = input.boolean?
58
- @prev_bits = input.optional_int
59
- @first_byte_lost = input.boolean?
60
- @blind = input.boolean?
61
- end
62
- end
63
- end
64
- end
65
- end
66
- end
@@ -1,59 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Badline
4
- module Chips
5
- class VIC
6
- class Sprites
7
- # The sprites' save_state and load_state.
8
- module SavedState
9
- # Whether any sprite's DMA runs, set after Sprite#restore_counters.
10
- def update_any_dma
11
- @any_dma = @sprites.any?(&:displaying?)
12
- end
13
-
14
- # The sprites, their shared bus, the collisions and the register log,
15
- # then the line's coverage and the pixels carried into the next line,
16
- # each as x, colour and priority.
17
- def save_state(out)
18
- out.boolean(@any_dma).boolean(@stopped_dma).boolean(@carried).int(@lo).int(@hi).int(@sequenced)
19
- out.blob(@win_color).booleans(@win_priority).ints(@palette)
20
- [@carry, @carry_next].each { |carry| carry.each { |pixels| save_carry(pixels, out) } }
21
- @sprites.each { |sprite| sprite.save_state(out) }
22
- @bus.save_state(out)
23
- @collisions.save_state(out)
24
- @log.save_state(out)
25
- end
26
-
27
- def load_state(input)
28
- @any_dma = input.boolean?
29
- @stopped_dma = input.boolean?
30
- @carried = input.boolean?
31
- @lo = input.int
32
- @hi = input.int
33
- @sequenced = input.int
34
- input.blob_into(@win_color)
35
- input.booleans_into(@win_priority)
36
- input.ints_into(@palette)
37
- [@carry, @carry_next].each { |carry| carry.each { |pixels| load_carry(pixels, input) } }
38
- @sprites.each { |sprite| sprite.load_state(input) }
39
- @bus.load_state(input)
40
- @collisions.load_state(input)
41
- @log.load_state(input)
42
- end
43
-
44
- private
45
-
46
- def save_carry(pixels, out)
47
- out.int(pixels.length / 3)
48
- pixels.each_slice(3) { |x, color, priority| out.int(x).int(color).boolean(priority) }
49
- end
50
-
51
- def load_carry(pixels, input)
52
- pixels.clear
53
- input.int.times { pixels.push(input.int, input.int, input.boolean?) }
54
- end
55
- end
56
- end
57
- end
58
- end
59
- end