badline 0.14.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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +23 -0
  3. data/CLAUDE.md +15 -5
  4. data/README.md +68 -8
  5. data/doc/pinned-behaviour.md +145 -0
  6. data/doc/snapshot-format.md +188 -38
  7. data/doc/snapshots.md +18 -1
  8. data/lib/badline/audio/bare_player.rb +4 -8
  9. data/lib/badline/audio/machine_player.rb +2 -12
  10. data/lib/badline/c128/banks.rb +1 -3
  11. data/lib/badline/c128/bus.rb +19 -1
  12. data/lib/badline/c128/mmu_pages.rb +7 -0
  13. data/lib/badline/c64/bus/extra_sids.rb +80 -0
  14. data/lib/badline/c64/bus.rb +1 -0
  15. data/lib/badline/c64/cartridge/action_replay.rb +6 -2
  16. data/lib/badline/c64/cartridge/comal80.rb +1 -0
  17. data/lib/badline/c64/cartridge/dinamic.rb +3 -1
  18. data/lib/badline/c64/cartridge/final_cartridge3.rb +1 -0
  19. data/lib/badline/c64/cartridge/fun_play.rb +2 -1
  20. data/lib/badline/c64/cartridge/game_system.rb +2 -1
  21. data/lib/badline/c64/cartridge/keyed_state.rb +155 -34
  22. data/lib/badline/c64/cartridge/magic_desk.rb +2 -1
  23. data/lib/badline/c64/cartridge/ocean.rb +1 -0
  24. data/lib/badline/c64/cartridge/pagefox.rb +1 -0
  25. data/lib/badline/c64/cartridge/rgcd.rb +2 -1
  26. data/lib/badline/c64/cartridge/super_games.rb +3 -2
  27. data/lib/badline/c64/cartridge/zaxxon.rb +1 -0
  28. data/lib/badline/c64/cartridge.rb +3 -3
  29. data/lib/badline/c64/keyed_modules.rb +6 -2
  30. data/lib/badline/chips/ted/beam.rb +13 -14
  31. data/lib/badline/chips/ted/fetches.rb +199 -0
  32. data/lib/badline/chips/ted/keyed_state.rb +156 -0
  33. data/lib/badline/chips/ted/modes.rb +134 -0
  34. data/lib/badline/chips/ted/palette.rb +43 -0
  35. data/lib/badline/chips/ted/picture.rb +182 -0
  36. data/lib/badline/chips/ted/sound/output.rb +86 -0
  37. data/lib/badline/chips/ted/sound.rb +284 -0
  38. data/lib/badline/chips/ted.rb +53 -6
  39. data/lib/badline/chips/tia.rb +12 -0
  40. data/lib/badline/drives/datasette/keyed_state.rb +7 -2
  41. data/lib/badline/drives/datasette.rb +22 -5
  42. data/lib/badline/frontend/boot.rb +3 -1
  43. data/lib/badline/frontend/controls.rb +7 -3
  44. data/lib/badline/frontend/keys.rb +14 -2
  45. data/lib/badline/frontend/media_slots.rb +11 -1
  46. data/lib/badline/frontend/menu/menu_dialogs.rb +2 -1
  47. data/lib/badline/frontend/menu/menu_media.rb +13 -3
  48. data/lib/badline/frontend/menu/menu_pages.rb +8 -8
  49. data/lib/badline/frontend/menu/menu_ports.rb +13 -1
  50. data/lib/badline/frontend/screen.rb +33 -12
  51. data/lib/badline/frontend/screens.rb +2 -1
  52. data/lib/badline/frontend/sound.rb +4 -4
  53. data/lib/badline/frontend/timeline.rb +19 -6
  54. data/lib/badline/machine/settling.rb +1 -1
  55. data/lib/badline/machine.rb +26 -6
  56. data/lib/badline/media/plus4_media.rb +68 -0
  57. data/lib/badline/media/program.rb +20 -6
  58. data/lib/badline/media.rb +33 -12
  59. data/lib/badline/options/family.rb +1 -0
  60. data/lib/badline/options/help.rb +30 -6
  61. data/lib/badline/options/table.rb +15 -2
  62. data/lib/badline/options/validation.rb +26 -4
  63. data/lib/badline/options.rb +37 -9
  64. data/lib/badline/plus4/bus.rb +77 -14
  65. data/lib/badline/plus4/cassette_sense.rb +21 -0
  66. data/lib/badline/plus4/keyboard_port.rb +35 -10
  67. data/lib/badline/plus4/keyed_modules.rb +99 -0
  68. data/lib/badline/plus4/keyed_parts.rb +143 -0
  69. data/lib/badline/plus4/keyed_state.rb +41 -0
  70. data/lib/badline/plus4.rb +92 -16
  71. data/lib/badline/snapshot/container.rb +2 -0
  72. data/lib/badline/snapshot/field_doc/markdown.rb +7 -6
  73. data/lib/badline/snapshot/field_doc.rb +46 -7
  74. data/lib/badline/snapshot/image.rb +12 -3
  75. data/lib/badline/snapshot/plus4_setup.rb +39 -0
  76. data/lib/badline/snapshot.rb +9 -4
  77. data/lib/badline/storage/g64_image.rb +1 -1
  78. data/lib/badline/storage/tap.rb +21 -12
  79. data/lib/badline/support/checkpoint.rb +3 -2
  80. data/lib/badline/support/plus4_checkpoint.rb +42 -0
  81. data/lib/badline/version.rb +1 -1
  82. metadata +15 -1
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "badline"
4
4
  require "badline/c128"
5
+ require "badline/plus4"
5
6
 
6
7
  module Badline
7
8
  module Snapshot
@@ -27,29 +28,45 @@ module Badline
27
28
  # each module the keys its records hold, with their tags, and the fields the load read.
28
29
  Load = Data.define(:family, :written, :fields)
29
30
 
30
- # The machines the doc is made from: each family at power-on, and the
31
- # C64 with each kind of expansion, cartridge and media.
31
+ # The cartridges by CRT hardware type: EasyFlash, then a mapper of
32
+ # each kind of register: Ocean's bank, Comal-80's bank for both
33
+ # windows, Zaxxon's ROMH bank, and the Action Replay's and the
34
+ # Pagefox's control registers.
35
+ CARTRIDGES = [32, 5, 21, 18, 1, 53].freeze
36
+
37
+ # The machines the doc is made from: each family at power-on, the C64
38
+ # with each kind of expansion, cartridge and media, and a second SID,
39
+ # and the 264 series' models, its TCBM interface, cartridge, tape and
40
+ # true drive.
32
41
  def self.machines
33
42
  {
34
- "c64" => [C64.new, C64.new(ram_expansion: :plus256k), C64.new(reu: 512), with_cartridge, with_trap_dos,
35
- with_tape, with_drive(:d64), with_drive(:d81)],
43
+ "c64" => [C64.new, C64.new(ram_expansion: :plus256k), C64.new(reu: 512),
44
+ *CARTRIDGES.map { |type| with_cartridge(type) }, with_trap_dos, with_tape, with_drive(:d64),
45
+ with_drive(:d81), with_extra_sids],
36
46
  "vic20" => [Vic20.new, with_rom],
37
- "c128" => [C128.new(mode: :c128), with_drive(:d71)]
47
+ "c128" => [C128.new(mode: :c128), with_drive(:d71)],
48
+ "plus4" => [Plus4.new, Plus4.new(model: "c16"), Plus4.new(tcbm: true), plus4_with_cartridge,
49
+ plus4_with_tape, plus4_with_drive]
38
50
  }
39
51
  end
40
52
 
41
53
  def self.blank(length) = Array.new(length, 0)
42
54
 
43
- def self.with_cartridge
55
+ def self.with_cartridge(type)
44
56
  chips = [0x8000, 0xa000].map do |address|
45
57
  Storage::CRTFile::Chip.new(chip_type: 2, bank: 0, address:, data: blank(0x2000))
46
58
  end
47
- image = Storage::CRTFile::Image.new(hardware_type: 32, subtype: 0, exrom: 1, game: 0, name: "DOC", chips:)
59
+ image = Storage::CRTFile::Image.new(hardware_type: type, subtype: 0, exrom: 1, game: 0, name: "DOC", chips:)
48
60
  C64.new.tap do |machine|
49
61
  machine.attach_cartridge(C64::Cartridge.from_crt(Storage::CRTFile.new(bytes: Storage::CRTFile.encode(image))))
50
62
  end
51
63
  end
52
64
 
65
+ # The SID player's machine for a tune on two SIDs.
66
+ def self.with_extra_sids
67
+ C64.new.tap { |machine| machine.address_bus.add_sid(Chips::SID.new(at: 0xd420)) }
68
+ end
69
+
53
70
  def self.with_trap_dos
54
71
  C64.new.tap { |machine| machine.mount(Storage::D64Image.new("", read_only: true, bytes: blank(174_848))) }
55
72
  end
@@ -78,6 +95,28 @@ module Badline
78
95
  end
79
96
  end
80
97
 
98
+ # A Plus/4 with a cartridge in each of cartridge 1's slots.
99
+ def self.plus4_with_cartridge
100
+ chips = [0x8000, 0xc000].map do |address|
101
+ Storage::CRTFile::Chip.new(chip_type: 0, bank: 0, address:, data: blank(0x4000))
102
+ end
103
+ Plus4.new.tap { |machine| machine.attach_cartridge(chips) }
104
+ end
105
+
106
+ # A C16 with a version 2 tape in its datasette, which times the read
107
+ # line's level.
108
+ def self.plus4_with_tape
109
+ bytes = "C16-TAPE-RAW".bytes + [2, 2, 0, 0, 4, 0, 0, 0, 0x30, 0x30, 0x30, 0x30]
110
+ Plus4.new(model: "c16").tap { |machine| machine.datasette.insert(Storage::TAP.new("", bytes:)) }
111
+ end
112
+
113
+ def self.plus4_with_drive
114
+ Plus4.new.tap do |machine|
115
+ image = Storage::D64Image.new("", bytes: blank(174_848))
116
+ machine.plug_true_drive.insert(Drives::Model1541::Disk.decode(image))
117
+ end
118
+ end
119
+
81
120
  def self.with_rom
82
121
  Vic20.new.tap { |machine| machine.bus.map_rom(0xa000, blank(0x2000)) }
83
122
  end
@@ -34,7 +34,7 @@ module Badline
34
34
  # of a machine in memory (.of).
35
35
  class Image
36
36
  MACHINE = "BL-MACHINE"
37
- FAMILIES = { "c64" => "C64", "vic20" => "VIC-20", "c128" => "C128" }.freeze
37
+ FAMILIES = { "c64" => "C64", "vic20" => "VIC-20", "c128" => "C128", "plus4" => "Plus/4" }.freeze
38
38
 
39
39
  attr_reader :container
40
40
 
@@ -54,8 +54,11 @@ module Badline
54
54
  end
55
55
 
56
56
  # The snapshot with VICE's modules ahead of the BL-* ones for a C64,
57
- # so x64sc opens it too.
57
+ # so x64sc opens it too. Raises FormatError for a Plus/4, whose
58
+ # snapshots badline doesn't write for xplus4.
58
59
  def self.exported(computer)
60
+ raise FormatError, "badline doesn't export a Plus/4's snapshot for VICE" if computer.family == :plus4
61
+
59
62
  computer.settle_for_snapshot!
60
63
  sections = computer.save_modules
61
64
  sections = Vice.export(computer) + sections if computer.family == :c64
@@ -67,6 +70,7 @@ module Badline
67
70
  case computer.family
68
71
  when :vic20 then Container::VIC20
69
72
  when :c128 then Container::C128
73
+ when :plus4 then Container::PLUS4
70
74
  else Container::MACHINE
71
75
  end
72
76
  end
@@ -77,6 +81,7 @@ module Badline
77
81
  case machine.choice("family", FAMILIES.keys, "c64")
78
82
  when "vic20" then Vic20Setup.read_fields(machine)
79
83
  when "c128" then C128Setup.read_fields(machine)
84
+ when "plus4" then Plus4Setup.read_fields(machine)
80
85
  else C64Setup.read_fields(machine)
81
86
  end
82
87
  end
@@ -92,7 +97,7 @@ module Badline
92
97
 
93
98
  # A new machine, built as the snapshot's was and restored from it. A
94
99
  # badline snapshot restores from its BL-* modules alone, and a VICE
95
- # one through the modules badline reads. xvic's and x128's own
100
+ # one through the modules badline reads. xvic's, x128's and xplus4's own
96
101
  # modules aren't read. Yields a line for each thing left out, or
97
102
  # warns it without a block. `detached` restores it without the host's
98
103
  # files (Keyed::Modules).
@@ -100,6 +105,7 @@ module Badline
100
105
  refuse_old_layout
101
106
  raise FormatError, "badline reads only its own VIC-20 snapshots, not xvic's" if vic20? && !badline?
102
107
  raise FormatError, "badline reads only its own C128 snapshots, not x128's" if c128? && !badline?
108
+ raise FormatError, "badline reads only its own Plus/4 snapshots, not xplus4's" if plus4? && !badline?
103
109
  return load_vice(&) unless badline?
104
110
 
105
111
  modules = Keyed::Modules.new(sections, detached:)
@@ -114,6 +120,9 @@ module Badline
114
120
  # Whether the machine is a C128, as the container names it.
115
121
  def c128? = @container.machine == Container::C128
116
122
 
123
+ # Whether the machine is of the 264 series, as the container names it.
124
+ def plus4? = @container.machine == Container::PLUS4
125
+
117
126
  # Restores `computer` from the snapshot, and returns the Report. The
118
127
  # snapshot goes into a new machine first, so one that fails, or is of
119
128
  # a machine built another way, leaves `computer` as it was.
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Snapshot
5
+ # How a 264 series machine was built: its model's name, one of
6
+ # Plus4::Model::ALL, which also says whether the Plus/4's function ROMs
7
+ # are fitted, its RAM in K, and whether a 1551's TCBM interface is
8
+ # plugged in, the arguments Plus4.new takes.
9
+ Plus4Setup = Data.define(:model, :ram_kb, :tcbm)
10
+
11
+ class Plus4Setup
12
+ MODELS = Plus4::Model::ALL.map(&:name).freeze
13
+
14
+ # The setup of `machine`.
15
+ def self.of(machine) = new(model: machine.model.name, ram_kb: machine.ram_kb, tcbm: !machine.tias.empty?)
16
+
17
+ # The model by name, the RAM and the TCBM interface, in a keyed
18
+ # snapshot module.
19
+ def write_fields(out)
20
+ out.text("model", model).int("ram_kb", ram_kb).bool("tcbm", tcbm)
21
+ end
22
+
23
+ def self.read_fields(input)
24
+ model = input.choice("model", MODELS, "plus4")
25
+ ram_kb = input.int("ram_kb", Plus4::Model.named(model).ram_kb)
26
+ unless Plus4::Model::RAM_SIZES.include?(ram_kb)
27
+ raise FormatError, "the snapshot is of a Plus/4 with #{ram_kb}K of RAM, which badline doesn't build"
28
+ end
29
+
30
+ new(model:, ram_kb:, tcbm: input.bool("tcbm", false))
31
+ end
32
+
33
+ # A machine built this way, at power-on.
34
+ def build = Plus4.new(model:, ram: ram_kb, tcbm:)
35
+
36
+ def to_s = "#{model} with #{ram_kb}K#{' and a TCBM interface' if tcbm}"
37
+ end
38
+ end
39
+ end
@@ -35,8 +35,9 @@ module Badline
35
35
  # The machine's snapshot file. Saving first runs the machine on to the
36
36
  # end of the instruction its CPU is in, and of an REU transfer under
37
37
  # way (Machine::Settling), so a save advances it by a few cycles, and a
38
- # second save straight after runs none. A VIC-20's or a C128's snapshot
39
- # is in a container named as xvic or x128 names its machine.
38
+ # second save straight after runs none. A VIC-20's, a C128's or a
39
+ # Plus/4's snapshot is in a container named as xvic, x128 or xplus4
40
+ # names its machine.
40
41
  def dump(computer) = Image.of(computer).to_s
41
42
 
42
43
  def read(path) = Image.new(Container.parse(File.binread(path)), name: File.basename(path))
@@ -50,8 +51,8 @@ module Badline
50
51
  # snapshot that fails leaves the machine as it was.
51
52
  def restore(computer, path, &) = read(path).restore(computer, &)
52
53
 
53
- # A machine's snapshots, as .vsf files and in memory. C64, Vic20 and
54
- # C128 each include it.
54
+ # A machine's snapshots, as .vsf files and in memory. C64, Vic20, C128
55
+ # and Plus4 each include it.
55
56
  module Files
56
57
  def save_snapshot(path) = Snapshot.save(self, path)
57
58
 
@@ -90,4 +91,8 @@ module Badline
90
91
  class C128
91
92
  include Snapshot::Files
92
93
  end
94
+
95
+ class Plus4
96
+ include Snapshot::Files
97
+ end
93
98
  end
@@ -47,7 +47,7 @@ module Badline
47
47
  # track 1 and 1 for track 1.5, laid out as VICE lays one out: every
48
48
  # block as long as the longest track.
49
49
  def self.create(path, tracks, half_tracks: HALF_TRACKS)
50
- max = [MAX_TRACK_SIZE, *tracks.values.map { |bytes, _| bytes.length }].max
50
+ max = tracks.values.map { |bytes, _| bytes.length }.push(MAX_TRACK_SIZE).max
51
51
  offsets = Array.new(half_tracks, 0)
52
52
  zones = Array.new(half_tracks, 0)
53
53
  blocks = +"".b
@@ -19,10 +19,12 @@ module Badline
19
19
  # The file it was read from, expanded, and the file's bytes.
20
20
  attr_reader :version, :platform, :path, :bytes
21
21
 
22
- # A blank version 1 tape for `platform` (0 C64, 1 VIC-20) at `path`,
23
- # written to the host file.
22
+ # A blank tape for `platform` at `path`, written to the host file: a
23
+ # version 1 tape for the C64 (0) or the VIC-20 (1), and a version 2
24
+ # C16 tape for the 264 series (2).
24
25
  def self.create(path, platform:)
25
- File.binwrite(path, (SIGNATURE + [1, platform, 0, 0, 0, 0, 0, 0]).pack("C*"))
26
+ header = platform == 2 ? C16_SIGNATURE + [2] : SIGNATURE + [1]
27
+ File.binwrite(path, (header + [platform, 0, 0, 0, 0, 0, 0]).pack("C*"))
26
28
  new(path)
27
29
  end
28
30
 
@@ -61,15 +63,16 @@ module Badline
61
63
  # cycle count for a long one (a lone zero, an overflow, on a version 0
62
64
  # tape). A version 2 tape records it as two equal halves.
63
65
  def record_pulse(cycles)
64
- @bytes.slice!(@pos..)
65
- if version == 2
66
- half = cycles / 2
67
- @bytes.concat(encode(cycles - half))
68
- @bytes.concat(encode(half))
69
- else
70
- @bytes.concat(encode(cycles))
71
- end
72
- @pos = @end = @bytes.length
66
+ return record(encode(cycles)) unless version == 2
67
+
68
+ half = cycles / 2
69
+ record(encode(cycles - half) + encode(half))
70
+ end
71
+
72
+ # Records a half wave `cycles` long at the position, in place of the
73
+ # rest of the tape, as a version 2 tape times them.
74
+ def record_half_wave(cycles)
75
+ record(encode(cycles))
73
76
  end
74
77
 
75
78
  # Writes the tape back to its host file, with the data size the
@@ -111,6 +114,12 @@ module Badline
111
114
  version.zero? ? OVERFLOW : long_pulse
112
115
  end
113
116
 
117
+ def record(times)
118
+ @bytes.slice!(@pos..)
119
+ @bytes.concat(times)
120
+ @pos = @end = @bytes.length
121
+ end
122
+
114
123
  def encode(cycles)
115
124
  units = (cycles + 4) / 8
116
125
  return [units] if units.between?(1, 0xff)
@@ -9,8 +9,9 @@ module Badline
9
9
  # interface, so taking a checkpoint leaves the machine as it was.
10
10
  #
11
11
  # Checkpoint.take digests a C64's components, COMPONENTS.
12
- # Vic20Checkpoint and C128Checkpoint digest the other families', each
13
- # with a list of its own, which a checkpoint carries as +components+.
12
+ # Vic20Checkpoint, C128Checkpoint and Plus4Checkpoint digest the other
13
+ # families', each with a list of its own, which a checkpoint carries as
14
+ # +components+.
14
15
  #
15
16
  # Colour RAM is digested as the four bits each cell stores: the upper
16
17
  # nibble a CPU read sees comes off the open bus.
@@ -0,0 +1,42 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Badline
4
+ module Support
5
+ # A Checkpoint of a 264 series machine: its CPU, its RAM, the TED's
6
+ # picture, the TED's registers, timers and beam, its sound, and the
7
+ # CPU's port with the ROM banks. The sound's voices are run up to the
8
+ # cycle to read them, which changes nothing they do.
9
+ module Plus4Checkpoint
10
+ COMPONENTS = %w[cpu ram display ted sound port].freeze
11
+
12
+ def self.take(machine)
13
+ ram = machine.ram
14
+ Checkpoint.new(machine.cycles, [
15
+ Checkpoint.fnv1a(Checkpoint.cpu_state(machine.cpu)),
16
+ Checkpoint.fnv1a(Checkpoint.ram(ram, ram.length)),
17
+ Checkpoint.fnv1a(machine.ted.display),
18
+ Checkpoint.fnv1a(ted_state(machine.ted)),
19
+ Checkpoint.fnv1a(sound_state(machine.sound)),
20
+ Checkpoint.fnv1a(port_state(machine))
21
+ ], COMPONENTS)
22
+ end
23
+
24
+ def self.parse(line) = Checkpoint.parse(line, COMPONENTS)
25
+
26
+ def self.ted_state(ted)
27
+ Array.new(0x20) { |register| ted.peek(0xff00 + register) } +
28
+ ted.timer_counts + [ted.line, ted.column, ted.interrupt_flags, ted.cpu_slots]
29
+ end
30
+
31
+ def self.sound_state(sound)
32
+ [sound.noise, sound.phase(0), sound.phase(1), sound.level, sound.volume, sound.control]
33
+ end
34
+
35
+ def self.port_state(machine)
36
+ port = machine.port
37
+ bus = machine.bus
38
+ [port.ddr, port.data, bus.low_bank, bus.high_bank, bus.rom_selected ? 1 : 0]
39
+ end
40
+ end
41
+ end
42
+ end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Badline
4
- VERSION = "0.14.0"
4
+ VERSION = "0.15.0"
5
5
  end
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.14.0
4
+ version: 0.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Inge Jørgensen
@@ -182,6 +182,13 @@ files:
182
182
  - lib/badline/chips/sid/waveform/noise_writeback.rb
183
183
  - lib/badline/chips/ted.rb
184
184
  - lib/badline/chips/ted/beam.rb
185
+ - lib/badline/chips/ted/fetches.rb
186
+ - lib/badline/chips/ted/keyed_state.rb
187
+ - lib/badline/chips/ted/modes.rb
188
+ - lib/badline/chips/ted/palette.rb
189
+ - lib/badline/chips/ted/picture.rb
190
+ - lib/badline/chips/ted/sound.rb
191
+ - lib/badline/chips/ted/sound/output.rb
185
192
  - lib/badline/chips/ted/timers.rb
186
193
  - lib/badline/chips/tia.rb
187
194
  - lib/badline/chips/vdc.rb
@@ -376,6 +383,7 @@ files:
376
383
  - lib/badline/media/disk_set.rb
377
384
  - lib/badline/media/extensions.rb
378
385
  - lib/badline/media/not_disk.rb
386
+ - lib/badline/media/plus4_media.rb
379
387
  - lib/badline/media/program.rb
380
388
  - lib/badline/media/true_drive.rb
381
389
  - lib/badline/media/tune.rb
@@ -394,9 +402,13 @@ files:
394
402
  - lib/badline/plus4.rb
395
403
  - lib/badline/plus4/acia.rb
396
404
  - lib/badline/plus4/bus.rb
405
+ - lib/badline/plus4/cassette_sense.rb
397
406
  - lib/badline/plus4/cpu.rb
398
407
  - lib/badline/plus4/cpu_port.rb
399
408
  - lib/badline/plus4/keyboard_port.rb
409
+ - lib/badline/plus4/keyed_modules.rb
410
+ - lib/badline/plus4/keyed_parts.rb
411
+ - lib/badline/plus4/keyed_state.rb
400
412
  - lib/badline/plus4/model.rb
401
413
  - lib/badline/plus4/user_port.rb
402
414
  - lib/badline/region.rb
@@ -448,6 +460,7 @@ files:
448
460
  - lib/badline/snapshot/keyed/report.rb
449
461
  - lib/badline/snapshot/keyed/writer.rb
450
462
  - lib/badline/snapshot/machine_state.rb
463
+ - lib/badline/snapshot/plus4_setup.rb
451
464
  - lib/badline/snapshot/storage_setup.rb
452
465
  - lib/badline/snapshot/vic20_setup.rb
453
466
  - lib/badline/snapshot/vice.rb
@@ -485,6 +498,7 @@ files:
485
498
  - lib/badline/support.rb
486
499
  - lib/badline/support/c128_checkpoint.rb
487
500
  - lib/badline/support/checkpoint.rb
501
+ - lib/badline/support/plus4_checkpoint.rb
488
502
  - lib/badline/support/vic20_checkpoint.rb
489
503
  - lib/badline/timing.rb
490
504
  - lib/badline/version.rb