badline 0.5.0 → 0.6.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 (137) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +24 -0
  3. data/CLAUDE.md +23 -23
  4. data/CONTRIBUTING.md +5 -0
  5. data/README.md +59 -1
  6. data/doc/pinned-behaviour.md +4 -2
  7. data/exe/badline-ruby +2 -1
  8. data/lib/badline/address_bus/saved_state.rb +72 -0
  9. data/lib/badline/address_bus.rb +1 -0
  10. data/lib/badline/audio/stream.rb +6 -0
  11. data/lib/badline/cartridge/action_replay.rb +15 -0
  12. data/lib/badline/cartridge/comal80.rb +8 -0
  13. data/lib/badline/cartridge/dinamic.rb +8 -0
  14. data/lib/badline/cartridge/easy_flash.rb +20 -1
  15. data/lib/badline/cartridge/epyx_fastload.rb +8 -0
  16. data/lib/badline/cartridge/final_cartridge3.rb +12 -0
  17. data/lib/badline/cartridge/flash.rb +41 -0
  18. data/lib/badline/cartridge/fun_play.rb +8 -0
  19. data/lib/badline/cartridge/g_mod2.rb +12 -0
  20. data/lib/badline/cartridge/game_system.rb +8 -0
  21. data/lib/badline/cartridge/geo_ram.rb +16 -0
  22. data/lib/badline/cartridge/magic_desk.rb +8 -0
  23. data/lib/badline/cartridge/ocean.rb +8 -0
  24. data/lib/badline/cartridge/pagefox.rb +12 -0
  25. data/lib/badline/cartridge/retro_replay.rb +44 -1
  26. data/lib/badline/cartridge/rgcd.rb +10 -0
  27. data/lib/badline/cartridge/super_games.rb +10 -0
  28. data/lib/badline/cartridge/zaxxon.rb +16 -0
  29. data/lib/badline/cartridge.rb +72 -0
  30. data/lib/badline/cia/interrupt_register.rb +17 -0
  31. data/lib/badline/cia/serial.rb +44 -0
  32. data/lib/badline/cia/state.rb +47 -0
  33. data/lib/badline/cia/timer.rb +33 -0
  34. data/lib/badline/cia.rb +24 -2
  35. data/lib/badline/computer/attachments.rb +132 -0
  36. data/lib/badline/computer/saved_state.rb +116 -0
  37. data/lib/badline/computer.rb +8 -31
  38. data/lib/badline/cpu/microcode.rb +8 -0
  39. data/lib/badline/cpu/saved_state.rb +115 -0
  40. data/lib/badline/cpu.rb +2 -0
  41. data/lib/badline/datasette.rb +27 -0
  42. data/lib/badline/drive1541/bus.rb +89 -13
  43. data/lib/badline/drive1541/disk.rb +7 -2
  44. data/lib/badline/drive1541/disk_state.rb +80 -0
  45. data/lib/badline/drive1541/idle.rb +9 -57
  46. data/lib/badline/drive1541/mechanism.rb +2 -0
  47. data/lib/badline/drive1541/mechanism_state.rb +67 -0
  48. data/lib/badline/drive1541/orbit.rb +81 -0
  49. data/lib/badline/drive1541/rotation.rb +10 -0
  50. data/lib/badline/drive1541/serial_port.rb +10 -0
  51. data/lib/badline/drive1541/sleep.rb +114 -0
  52. data/lib/badline/drive1541.rb +52 -2
  53. data/lib/badline/gui/application.rb +41 -14
  54. data/lib/badline/gui/gamepads.rb +7 -0
  55. data/lib/badline/gui/snapshots.rb +67 -0
  56. data/lib/badline/gui.rb +1 -0
  57. data/lib/badline/iec_bus.rb +16 -0
  58. data/lib/badline/kernal_trap/channel.rb +27 -0
  59. data/lib/badline/kernal_trap/drive/channels.rb +25 -0
  60. data/lib/badline/kernal_trap/drive/memory.rb +9 -0
  61. data/lib/badline/kernal_trap/drive/status.rb +8 -0
  62. data/lib/badline/kernal_trap/drive/write_file.rb +21 -0
  63. data/lib/badline/kernal_trap/drive.rb +19 -0
  64. data/lib/badline/kernal_trap/save.rb +8 -0
  65. data/lib/badline/kernal_trap/serial.rb +16 -0
  66. data/lib/badline/memory.rb +11 -0
  67. data/lib/badline/options.rb +3 -2
  68. data/lib/badline/ram_expansion/plus256k.rb +16 -0
  69. data/lib/badline/ram_expansion/plus60k.rb +12 -0
  70. data/lib/badline/ram_expansion/unexpanded.rb +6 -0
  71. data/lib/badline/reu/dma.rb +36 -0
  72. data/lib/badline/reu/ram.rb +15 -0
  73. data/lib/badline/reu/saved_state.rb +52 -0
  74. data/lib/badline/reu.rb +4 -0
  75. data/lib/badline/sdl/events.rb +2 -0
  76. data/lib/badline/sid/envelope/state.rb +68 -0
  77. data/lib/badline/sid/envelope.rb +7 -0
  78. data/lib/badline/sid/filter.rb +38 -0
  79. data/lib/badline/sid/voice.rb +10 -0
  80. data/lib/badline/sid/waveform/state.rb +66 -0
  81. data/lib/badline/sid/waveform.rb +2 -0
  82. data/lib/badline/sid.rb +34 -0
  83. data/lib/badline/snapshot/container.rb +117 -0
  84. data/lib/badline/snapshot/fields.rb +54 -0
  85. data/lib/badline/snapshot/image.rb +70 -0
  86. data/lib/badline/snapshot/machine_state.rb +77 -0
  87. data/lib/badline/snapshot/setup.rb +58 -0
  88. data/lib/badline/snapshot/state.rb +178 -0
  89. data/lib/badline/snapshot/vice/c64_mem.rb +53 -0
  90. data/lib/badline/snapshot/vice/cias.rb +89 -0
  91. data/lib/badline/snapshot/vice/cias_import.rb +70 -0
  92. data/lib/badline/snapshot/vice/main_cpu.rb +76 -0
  93. data/lib/badline/snapshot/vice/peripherals.rb +47 -0
  94. data/lib/badline/snapshot/vice/restore.rb +125 -0
  95. data/lib/badline/snapshot/vice/sid_extended.rb +96 -0
  96. data/lib/badline/snapshot/vice/sid_registers.rb +46 -0
  97. data/lib/badline/snapshot/vice/vicii.rb +119 -0
  98. data/lib/badline/snapshot/vice/vicii_import.rb +131 -0
  99. data/lib/badline/snapshot/vice.rb +74 -0
  100. data/lib/badline/snapshot.rb +52 -0
  101. data/lib/badline/storage/crt_file.rb +9 -3
  102. data/lib/badline/storage/d64_image.rb +2 -0
  103. data/lib/badline/storage/d71_image.rb +2 -0
  104. data/lib/badline/storage/d81_image.rb +2 -0
  105. data/lib/badline/storage/disk_image.rb +11 -2
  106. data/lib/badline/storage/host_directory.rb +5 -0
  107. data/lib/badline/storage/t64.rb +6 -0
  108. data/lib/badline/storage/tap.rb +10 -1
  109. data/lib/badline/storage/unavailable.rb +20 -0
  110. data/lib/badline/storage.rb +34 -0
  111. data/lib/badline/time_of_day.rb +56 -0
  112. data/lib/badline/version.rb +1 -1
  113. data/lib/badline/via/control_lines.rb +15 -0
  114. data/lib/badline/via/fast_forward.rb +15 -0
  115. data/lib/badline/via/interrupt_register.rb +9 -0
  116. data/lib/badline/via/shift_register.rb +13 -0
  117. data/lib/badline/via/state.rb +42 -0
  118. data/lib/badline/via/timer1.rb +19 -0
  119. data/lib/badline/via/timer2.rb +24 -0
  120. data/lib/badline/via.rb +2 -0
  121. data/lib/badline/vic/border_mask.rb +10 -0
  122. data/lib/badline/vic/collisions.rb +11 -0
  123. data/lib/badline/vic/color_patches.rb +11 -0
  124. data/lib/badline/vic/display_state.rb +29 -1
  125. data/lib/badline/vic/graphics_shifter.rb +26 -0
  126. data/lib/badline/vic/register_log.rb +18 -0
  127. data/lib/badline/vic/registers.rb +13 -2
  128. data/lib/badline/vic/sequencer.rb +12 -0
  129. data/lib/badline/vic/sequencer_state.rb +89 -0
  130. data/lib/badline/vic/sprite/internal_bus.rb +11 -0
  131. data/lib/badline/vic/sprite/saved_state.rb +64 -0
  132. data/lib/badline/vic/sprite.rb +2 -0
  133. data/lib/badline/vic/sprites.rb +3 -0
  134. data/lib/badline/vic/sprites_state.rb +57 -0
  135. data/lib/badline/vic.rb +94 -10
  136. data/lib/badline.rb +1 -0
  137. metadata +37 -1
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ class VIC < Cycleable
5
+ class Sprites
6
+ # The sprites' save_state and load_state.
7
+ module SavedState
8
+ # Whether any sprite's DMA runs, set after Sprite#restore_counters.
9
+ def update_any_dma
10
+ @any_dma = @sprites.any?(&:displaying?)
11
+ end
12
+
13
+ # The sprites, their shared bus, the collisions and the register log,
14
+ # then the line's coverage and the pixels carried into the next line,
15
+ # each as x, colour and priority.
16
+ def save_state(out)
17
+ out.boolean(@any_dma).boolean(@stopped_dma).boolean(@carried).int(@lo).int(@hi).int(@sequenced)
18
+ out.blob(@win_color).booleans(@win_priority).ints(@palette)
19
+ [@carry, @carry_next].each { |carry| carry.each { |pixels| save_carry(pixels, out) } }
20
+ @sprites.each { |sprite| sprite.save_state(out) }
21
+ @bus.save_state(out)
22
+ @collisions.save_state(out)
23
+ @log.save_state(out)
24
+ end
25
+
26
+ def load_state(input)
27
+ @any_dma = input.boolean?
28
+ @stopped_dma = input.boolean?
29
+ @carried = input.boolean?
30
+ @lo = input.int
31
+ @hi = input.int
32
+ @sequenced = input.int
33
+ input.blob_into(@win_color)
34
+ input.booleans_into(@win_priority)
35
+ input.ints_into(@palette)
36
+ [@carry, @carry_next].each { |carry| carry.each { |pixels| load_carry(pixels, input) } }
37
+ @sprites.each { |sprite| sprite.load_state(input) }
38
+ @bus.load_state(input)
39
+ @collisions.load_state(input)
40
+ @log.load_state(input)
41
+ end
42
+
43
+ private
44
+
45
+ def save_carry(pixels, out)
46
+ out.int(pixels.length / 3)
47
+ pixels.each_slice(3) { |x, color, priority| out.int(x).int(color).boolean(priority) }
48
+ end
49
+
50
+ def load_carry(pixels, input)
51
+ pixels.clear
52
+ input.int.times { pixels.push(input.int, input.int, input.boolean?) }
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
data/lib/badline/vic.rb CHANGED
@@ -17,6 +17,10 @@ module Badline
17
17
  attr_reader :address_bus, :display, :width, :height, :vic_bank, :column,
18
18
  :rasterline, :dirty_lines, :model, :region
19
19
 
20
+ # The parts a VICE snapshot reads and sets.
21
+ attr_reader :registers, :display_state, :sequencer, :sprites, :character_buffer, :color_buffer,
22
+ :fetch_d011
23
+
20
24
  # Returns the byte the CPU's halted read would see, for the c-accesses
21
25
  # that run before AEC. Without it they read colour RAM.
22
26
  attr_writer :open_bus
@@ -139,6 +143,35 @@ module Badline
139
143
  @raster_match = false
140
144
  end
141
145
 
146
+ # Everything the VIC holds between cycles: the beam, the fetch and
147
+ # g-access pipeline, the light pen and raster latches, the finished
148
+ # lines, the registers and the display, sequencer and sprite logic.
149
+ # Whether it renders is the host's, and every line comes back dirty so
150
+ # a front end repaints.
151
+ def save_state(out)
152
+ out.marker("VIC")
153
+ out.int(@column).int(@rasterline).int(@cycles).boolean(@pending_write)
154
+ out.int(@g_tick).ints(@g_kind).int(@g_kept_char).int(@g_kept_color).boolean(@g_display)
155
+ out.int(@fetch_d011).boolean(@lp_triggered).boolean(@lp_low).boolean(@raster_match)
156
+ out.blob(@character_buffer).blob(@color_buffer).booleans(@sprite_ba)
157
+ @lines.each { |line| out.blob(line) }
158
+ @registers.save_state(out)
159
+ @display_state.save_state(out)
160
+ @sequencer.save_state(out)
161
+ @sprites.save_state(out)
162
+ end
163
+
164
+ def load_state(input)
165
+ input.marker("VIC")
166
+ load_beam(input)
167
+ load_buffers(input)
168
+ load_lines(input)
169
+ @registers.load_state(input)
170
+ @display_state.load_state(input)
171
+ @sequencer.load_state(input)
172
+ @sprites.load_state(input)
173
+ end
174
+
142
175
  def cycle!
143
176
  start_line! if @column.zero?
144
177
 
@@ -288,6 +321,36 @@ module Badline
288
321
  @sequencer.render = on
289
322
  end
290
323
 
324
+ # Puts the beam at the start of `line`.
325
+ def restore_line(line)
326
+ @rasterline = line
327
+ @column = 0
328
+ end
329
+
330
+ # The latches a VICE snapshot holds: the raster match, the light pen's
331
+ # line held low and its trigger, as bits 0, 1 and 2.
332
+ def latch_bits = (@raster_match ? 1 : 0) | (@lp_low ? 2 : 0) | (@lp_triggered ? 4 : 0)
333
+
334
+ # Sets the latches from latch_bits, and the $D011 the next g-access
335
+ # holds.
336
+ def restore_latches(bits, fetch_d011)
337
+ @raster_match = bits.anybits?(1)
338
+ @lp_low = bits.anybits?(2)
339
+ @lp_triggered = bits.anybits?(4)
340
+ @fetch_d011 = fetch_d011
341
+ end
342
+
343
+ # Marks the columns BA is low for the sprites whose DMA runs.
344
+ def rebuild_sprite_ba
345
+ @sprite_ba.fill(false)
346
+ 8.times do |n|
347
+ next unless @sprites[n].displaying?
348
+
349
+ @sprite_ba_tail[n].each { |c| @sprite_ba[c] = true }
350
+ @sprite_ba_head[n].each { |c| @sprite_ba[c] = true }
351
+ end
352
+ end
353
+
291
354
  # Reset the dirty flags once the frontend has consumed them.
292
355
  def clear_dirty_lines!
293
356
  @dirty_lines.fill(false)
@@ -295,6 +358,37 @@ module Badline
295
358
 
296
359
  private
297
360
 
361
+ def load_beam(input)
362
+ @column = input.int
363
+ @rasterline = input.int
364
+ @cycles = input.int
365
+ @pending_write = input.boolean?
366
+ @g_tick = input.int
367
+ input.ints_into(@g_kind)
368
+ @g_kept_char = input.int
369
+ @g_kept_color = input.int
370
+ @g_display = input.boolean?
371
+ @fetch_d011 = input.int
372
+ @lp_triggered = input.boolean?
373
+ @lp_low = input.boolean?
374
+ @raster_match = input.boolean?
375
+ end
376
+
377
+ def load_buffers(input)
378
+ input.blob_into(@character_buffer)
379
+ input.blob_into(@color_buffer)
380
+ input.booleans_into(@sprite_ba)
381
+ end
382
+
383
+ # The display is the finished lines one after another.
384
+ def load_lines(input)
385
+ @lines.each_with_index do |line, number|
386
+ input.blob_into(line)
387
+ @display[number * @width, @width] = line
388
+ end
389
+ @dirty_lines.fill(true)
390
+ end
391
+
298
392
  # The raster counter as $D011/$D012 read it. Every line advances on the
299
393
  # CPU cycle paired with column 62 except line 0, which the counter
300
394
  # reaches a cycle later, together with the line 0 raster compare.
@@ -407,16 +501,6 @@ module Badline
407
501
  @registers[0x15].anybits?(0x01) && @registers[0x01] == (@rasterline & 0xff)
408
502
  end
409
503
 
410
- def rebuild_sprite_ba
411
- @sprite_ba.fill(false)
412
- 8.times do |n|
413
- next unless @sprites[n].displaying?
414
-
415
- @sprite_ba_tail[n].each { |c| @sprite_ba[c] = true }
416
- @sprite_ba_head[n].each { |c| @sprite_ba[c] = true }
417
- end
418
- end
419
-
420
504
  # Splits the sprite BA windows at the end of the line and marks the hook
421
505
  # columns, for a line of the region's length: 14, 15, 53, 54 and 57, and
422
506
  # the line's last column, which starts the vertical border for the line
data/lib/badline.rb CHANGED
@@ -39,4 +39,5 @@ require "badline/cartridge"
39
39
  require "badline/kernal_trap"
40
40
  require "badline/chrout_trap"
41
41
  require "badline/media"
42
+ require "badline/snapshot"
42
43
  require "badline/audio"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: badline
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.0
4
+ version: 0.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Inge Jørgensen
@@ -47,6 +47,7 @@ files:
47
47
  - exe/badline-ruby
48
48
  - lib/badline.rb
49
49
  - lib/badline/address_bus.rb
50
+ - lib/badline/address_bus/saved_state.rb
50
51
  - lib/badline/address_bus/ultimax_pages.rb
51
52
  - lib/badline/addressable.rb
52
53
  - lib/badline/audio.rb
@@ -96,14 +97,18 @@ files:
96
97
  - lib/badline/cia.rb
97
98
  - lib/badline/cia/interrupt_register.rb
98
99
  - lib/badline/cia/serial.rb
100
+ - lib/badline/cia/state.rb
99
101
  - lib/badline/cia/timer.rb
100
102
  - lib/badline/color_memory.rb
101
103
  - lib/badline/computer.rb
104
+ - lib/badline/computer/attachments.rb
105
+ - lib/badline/computer/saved_state.rb
102
106
  - lib/badline/control_ports.rb
103
107
  - lib/badline/cpu.rb
104
108
  - lib/badline/cpu/addressing.rb
105
109
  - lib/badline/cpu/microcode.rb
106
110
  - lib/badline/cpu/operations.rb
111
+ - lib/badline/cpu/saved_state.rb
107
112
  - lib/badline/cpu/stack_operations.rb
108
113
  - lib/badline/cycleable.rb
109
114
  - lib/badline/datasette.rb
@@ -111,13 +116,17 @@ files:
111
116
  - lib/badline/drive1541.rb
112
117
  - lib/badline/drive1541/bus.rb
113
118
  - lib/badline/drive1541/disk.rb
119
+ - lib/badline/drive1541/disk_state.rb
114
120
  - lib/badline/drive1541/disk_via.rb
115
121
  - lib/badline/drive1541/gcr.rb
116
122
  - lib/badline/drive1541/idle.rb
117
123
  - lib/badline/drive1541/mechanism.rb
124
+ - lib/badline/drive1541/mechanism_state.rb
125
+ - lib/badline/drive1541/orbit.rb
118
126
  - lib/badline/drive1541/rotation.rb
119
127
  - lib/badline/drive1541/sector_reader.rb
120
128
  - lib/badline/drive1541/serial_port.rb
129
+ - lib/badline/drive1541/sleep.rb
121
130
  - lib/badline/drive1541/track.rb
122
131
  - lib/badline/gui.rb
123
132
  - lib/badline/gui/application.rb
@@ -128,6 +137,7 @@ files:
128
137
  - lib/badline/gui/palette.rb
129
138
  - lib/badline/gui/pane.rb
130
139
  - lib/badline/gui/screen_pane.rb
140
+ - lib/badline/gui/snapshots.rb
131
141
  - lib/badline/gui/window.rb
132
142
  - lib/badline/iec_bus.rb
133
143
  - lib/badline/input.rb
@@ -176,6 +186,7 @@ files:
176
186
  - lib/badline/reu.rb
177
187
  - lib/badline/reu/dma.rb
178
188
  - lib/badline/reu/ram.rb
189
+ - lib/badline/reu/saved_state.rb
179
190
  - lib/badline/reu/trigger.rb
180
191
  - lib/badline/rom.rb
181
192
  - lib/badline/roms/README
@@ -193,12 +204,32 @@ files:
193
204
  - lib/badline/sid/catch_up.rb
194
205
  - lib/badline/sid/decimator.rb
195
206
  - lib/badline/sid/envelope.rb
207
+ - lib/badline/sid/envelope/state.rb
196
208
  - lib/badline/sid/filter.rb
197
209
  - lib/badline/sid/voice.rb
198
210
  - lib/badline/sid/waveform.rb
199
211
  - lib/badline/sid/waveform/combined.rb
200
212
  - lib/badline/sid/waveform/fast_forward.rb
201
213
  - lib/badline/sid/waveform/noise_writeback.rb
214
+ - lib/badline/sid/waveform/state.rb
215
+ - lib/badline/snapshot.rb
216
+ - lib/badline/snapshot/container.rb
217
+ - lib/badline/snapshot/fields.rb
218
+ - lib/badline/snapshot/image.rb
219
+ - lib/badline/snapshot/machine_state.rb
220
+ - lib/badline/snapshot/setup.rb
221
+ - lib/badline/snapshot/state.rb
222
+ - lib/badline/snapshot/vice.rb
223
+ - lib/badline/snapshot/vice/c64_mem.rb
224
+ - lib/badline/snapshot/vice/cias.rb
225
+ - lib/badline/snapshot/vice/cias_import.rb
226
+ - lib/badline/snapshot/vice/main_cpu.rb
227
+ - lib/badline/snapshot/vice/peripherals.rb
228
+ - lib/badline/snapshot/vice/restore.rb
229
+ - lib/badline/snapshot/vice/sid_extended.rb
230
+ - lib/badline/snapshot/vice/sid_registers.rb
231
+ - lib/badline/snapshot/vice/vicii.rb
232
+ - lib/badline/snapshot/vice/vicii_import.rb
202
233
  - lib/badline/status.rb
203
234
  - lib/badline/storage.rb
204
235
  - lib/badline/storage/crt_file.rb
@@ -218,6 +249,7 @@ files:
218
249
  - lib/badline/storage/song_lengths.rb
219
250
  - lib/badline/storage/t64.rb
220
251
  - lib/badline/storage/tap.rb
252
+ - lib/badline/storage/unavailable.rb
221
253
  - lib/badline/time_of_day.rb
222
254
  - lib/badline/traps.rb
223
255
  - lib/badline/version.rb
@@ -226,6 +258,7 @@ files:
226
258
  - lib/badline/via/fast_forward.rb
227
259
  - lib/badline/via/interrupt_register.rb
228
260
  - lib/badline/via/shift_register.rb
261
+ - lib/badline/via/state.rb
229
262
  - lib/badline/via/timer1.rb
230
263
  - lib/badline/via/timer2.rb
231
264
  - lib/badline/vic.rb
@@ -240,11 +273,14 @@ files:
240
273
  - lib/badline/vic/registers.rb
241
274
  - lib/badline/vic/sequencer.rb
242
275
  - lib/badline/vic/sequencer_output.rb
276
+ - lib/badline/vic/sequencer_state.rb
243
277
  - lib/badline/vic/sprite.rb
244
278
  - lib/badline/vic/sprite/internal_bus.rb
279
+ - lib/badline/vic/sprite/saved_state.rb
245
280
  - lib/badline/vic/sprite/shifter.rb
246
281
  - lib/badline/vic/sprite/timing.rb
247
282
  - lib/badline/vic/sprites.rb
283
+ - lib/badline/vic/sprites_state.rb
248
284
  - packaging/homebrew/badline.rb
249
285
  - vendor/.gitkeep
250
286
  homepage: https://github.com/elektronaut/badline