badline 0.17.0 → 0.18.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +153 -0
- data/CLAUDE.md +11 -7
- data/CONTRIBUTING.md +7 -1
- data/README.md +169 -20
- data/doc/pinned-behaviour.md +128 -0
- data/doc/snapshot-format.md +253 -18
- data/doc/snapshots.md +57 -23
- data/exe/badline-ruby +5 -0
- data/lib/badline/audio/terminal.rb +34 -2
- data/lib/badline/c128/keyed_state.rb +2 -0
- data/lib/badline/c128.rb +1 -0
- data/lib/badline/c64/keyed_state.rb +2 -0
- data/lib/badline/c64.rb +1 -0
- data/lib/badline/cbm2/keyed_state.rb +4 -0
- data/lib/badline/cbm2/p500.rb +5 -3
- data/lib/badline/cbm2.rb +6 -3
- data/lib/badline/chips/cia/timer.rb +2 -2
- data/lib/badline/chips/cpu/instruction_set.rb +1 -1
- data/lib/badline/chips/m6809/arithmetic.rb +140 -0
- data/lib/badline/chips/m6809/bus_steps.rb +223 -0
- data/lib/badline/chips/m6809/core.rb +149 -0
- data/lib/badline/chips/m6809/indexed.rb +82 -0
- data/lib/badline/chips/m6809/interrupts.rb +159 -0
- data/lib/badline/chips/m6809/keyed_state.rb +147 -0
- data/lib/badline/chips/m6809/opcodes.rb +159 -0
- data/lib/badline/chips/m6809/operations.rb +258 -0
- data/lib/badline/chips/m6809/plans.rb +143 -0
- data/lib/badline/chips/m6809/registers.rb +82 -0
- data/lib/badline/chips/m6809/stack.rb +140 -0
- data/lib/badline/chips/m6809.rb +13 -0
- data/lib/badline/chips/riot/timer.rb +14 -3
- data/lib/badline/chips/rriot.rb +4 -2
- data/lib/badline/chips/sid/filter.rb +4 -4
- data/lib/badline/chips/sid/waveform.rb +6 -6
- data/lib/badline/chips/vic_i/keyed_parts.rb +7 -2
- data/lib/badline/chips/vic_i.rb +84 -21
- data/lib/badline/data_path.rb +3 -3
- data/lib/badline/drives/ieee_models.rb +54 -0
- data/lib/badline/drives/model1001.rb +37 -0
- data/lib/badline/drives/model2031.rb +6 -0
- data/lib/badline/drives/model4040/disk.rb +62 -0
- data/lib/badline/drives/model4040/ip_bus.rb +46 -0
- data/lib/badline/drives/model4040/keyed_state.rb +57 -0
- data/lib/badline/drives/model4040/mechanism.rb +192 -0
- data/lib/badline/drives/model4040/parts.rb +20 -0
- data/lib/badline/drives/model4040.rb +179 -0
- data/lib/badline/drives/model8050/board.rb +77 -0
- data/lib/badline/drives/model8050/dos_board.rb +91 -0
- data/lib/badline/drives/model8050/idle.rb +11 -7
- data/lib/badline/drives/model8050/keyed_state.rb +5 -2
- data/lib/badline/drives/model8050.rb +18 -130
- data/lib/badline/drives/model9060/idle.rb +149 -0
- data/lib/badline/drives/model9060/keyed_state.rb +123 -0
- data/lib/badline/drives/model9060/parts.rb +98 -0
- data/lib/badline/drives/model9060/sasi_bus.rb +88 -0
- data/lib/badline/drives/model9060/sasi_commands.rb +168 -0
- data/lib/badline/drives/model9060/sasi_target.rb +161 -0
- data/lib/badline/drives/model9060.rb +195 -0
- data/lib/badline/frontend/app.rb +8 -0
- data/lib/badline/frontend/boot.rb +3 -2
- data/lib/badline/frontend/controls.rb +62 -6
- data/lib/badline/frontend/keys.rb +36 -0
- data/lib/badline/frontend/kim1_panel.rb +208 -0
- data/lib/badline/frontend/media_slots.rb +8 -1
- data/lib/badline/frontend/menu/drive_types.rb +56 -0
- data/lib/badline/frontend/menu/menu_dialogs.rb +61 -14
- data/lib/badline/frontend/menu/menu_media.rb +42 -12
- data/lib/badline/frontend/menu/menu_pages.rb +97 -2
- data/lib/badline/frontend/menu/menu_ports.rb +38 -1
- data/lib/badline/frontend/menu/pause_menu.rb +5 -1
- data/lib/badline/frontend/pet_keyboard.rb +23 -1
- data/lib/badline/frontend/screen.rb +1 -1
- data/lib/badline/frontend/screens.rb +40 -2
- data/lib/badline/frontend/teletype_pane.rb +152 -0
- data/lib/badline/frontend/timeline.rb +31 -2
- data/lib/badline/frontend.rb +3 -0
- data/lib/badline/kim1/bus.rb +117 -0
- data/lib/badline/kim1/cpu.rb +25 -0
- data/lib/badline/kim1/host_terminal.rb +74 -0
- data/lib/badline/kim1/key_entry.rb +74 -0
- data/lib/badline/kim1/keyed_modules.rb +53 -0
- data/lib/badline/kim1/keyed_state.rb +133 -0
- data/lib/badline/kim1/panel.rb +176 -0
- data/lib/badline/kim1/rriots.rb +28 -0
- data/lib/badline/kim1/sound.rb +29 -0
- data/lib/badline/kim1/tape.rb +116 -0
- data/lib/badline/kim1/teletype.rb +193 -0
- data/lib/badline/kim1.rb +190 -0
- data/lib/badline/machine/ieee_drives.rb +94 -117
- data/lib/badline/machine/keyboard_buffer.rb +20 -3
- data/lib/badline/machine/line_sound.rb +122 -0
- data/lib/badline/machine.rb +46 -15
- data/lib/badline/media/extensions.rb +8 -4
- data/lib/badline/media/kim1_media.rb +150 -0
- data/lib/badline/media/pet_media.rb +3 -1
- data/lib/badline/media/true_drive.rb +42 -45
- data/lib/badline/media.rb +12 -6
- data/lib/badline/options/family.rb +98 -8
- data/lib/badline/options/help.rb +44 -12
- data/lib/badline/options/table.rb +43 -11
- data/lib/badline/options/validation.rb +44 -8
- data/lib/badline/options.rb +27 -8
- data/lib/badline/pet/bus.rb +16 -2
- data/lib/badline/pet/keyboard_ports.rb +9 -2
- data/lib/badline/pet/keyed_state.rb +4 -0
- data/lib/badline/pet/model.rb +11 -2
- data/lib/badline/pet/rom_sets.rb +1 -0
- data/lib/badline/pet/sound.rb +5 -105
- data/lib/badline/pet/superpet/acia.rb +12 -0
- data/lib/badline/pet/superpet/board.rb +221 -0
- data/lib/badline/pet/superpet/dongle.rb +81 -0
- data/lib/badline/pet/superpet/keyed_modules.rb +63 -0
- data/lib/badline/pet/superpet/keyed_parts.rb +76 -0
- data/lib/badline/pet/superpet/m6809.rb +32 -0
- data/lib/badline/pet/superpet/waterloo_traps.rb +199 -0
- data/lib/badline/pet/superpet.rb +216 -0
- data/lib/badline/pet.rb +19 -3
- data/lib/badline/plus4/keyed_state.rb +2 -0
- data/lib/badline/plus4.rb +1 -0
- data/lib/badline/roms/1001/fdc-251257-02a.rom +0 -0
- data/lib/badline/roms/4040/dos-1.2.rom +0 -0
- data/lib/badline/roms/4040/dos-2.1-rev.rom +0 -0
- data/lib/badline/roms/4040/dos-2.1.rom +0 -0
- data/lib/badline/roms/4040/fdc-901466-02.rom +0 -0
- data/lib/badline/roms/4040/fdc-901466-04.rom +0 -0
- data/lib/badline/roms/9060/dos-3.0.rom +0 -0
- data/lib/badline/roms/9060/sasi-300515-revb.rom +0 -0
- data/lib/badline/roms/README +166 -0
- data/lib/badline/roms/kim1/6530-002.rom +0 -0
- data/lib/badline/roms/kim1/6530-003.rom +0 -0
- data/lib/badline/roms/pet/characters-superpet.rom +0 -0
- data/lib/badline/roms/pet/superpet-a000.rom +0 -0
- data/lib/badline/roms/pet/superpet-c000.rom +0 -0
- data/lib/badline/roms/pet/superpet-e000-50hz.rom +0 -0
- data/lib/badline/roms/pet/superpet-e000.rom +0 -0
- data/lib/badline/snapshot/container.rb +2 -0
- data/lib/badline/snapshot/field_doc/markdown.rb +1 -1
- data/lib/badline/snapshot/field_doc.rb +27 -6
- data/lib/badline/snapshot/image.rb +4 -1
- data/lib/badline/snapshot/kim1_setup.rb +28 -0
- data/lib/badline/snapshot/pet_setup.rb +27 -11
- data/lib/badline/snapshot/storage_setup.rb +4 -1
- data/lib/badline/snapshot/vic20_setup.rb +11 -7
- data/lib/badline/snapshot/vice/pet.rb +13 -7
- data/lib/badline/snapshot/vice/pet_cpu.rb +39 -5
- data/lib/badline/snapshot/vice/pet_crtc.rb +15 -2
- data/lib/badline/snapshot/vice/pet_drive8050.rb +188 -68
- data/lib/badline/snapshot/vice/pet_mem.rb +49 -5
- data/lib/badline/snapshot/vice/pet_restore.rb +40 -11
- data/lib/badline/snapshot.rb +4 -0
- data/lib/badline/status.rb +30 -30
- data/lib/badline/storage/d67_image.rb +55 -0
- data/lib/badline/storage/d90_image.rb +180 -0
- data/lib/badline/storage/disk_image/writing.rb +2 -2
- data/lib/badline/storage/kim_tape.rb +254 -0
- data/lib/badline/storage/papertape.rb +90 -0
- data/lib/badline/storage.rb +4 -0
- data/lib/badline/support/kim1_checkpoint.rb +41 -0
- data/lib/badline/support/superpet_checkpoint.rb +35 -0
- data/lib/badline/version.rb +1 -1
- data/lib/badline/vic20/keyed_modules.rb +6 -3
- data/lib/badline/vic20/keyed_state.rb +6 -4
- data/lib/badline/vic20.rb +26 -12
- data/lib/badline.rb +1 -0
- metadata +77 -1
|
@@ -5,9 +5,11 @@ module Badline
|
|
|
5
5
|
# How a PET was built: its model's name, one of PET::Model::ALL, its
|
|
6
6
|
# RAM below $8000 in K and its editor's frame rate, the arguments
|
|
7
7
|
# PET.new takes, the ROMs it runs by file: BASIC, the editor, the
|
|
8
|
-
# KERNAL and the characters,
|
|
9
|
-
# comma-separated
|
|
10
|
-
|
|
8
|
+
# KERNAL and the characters, the 8296 board's jumpers, by name and
|
|
9
|
+
# comma-separated, and the SuperPET's CPU and RAM switches, as
|
|
10
|
+
# PET::SuperPET::Board names their positions, empty on the others.
|
|
11
|
+
PETSetup = Data.define(:model, :ram_kb, :refresh_hz, :basic, :editor, :kernal, :characters, :jumpers,
|
|
12
|
+
:cpu_switch, :ram_switch)
|
|
11
13
|
|
|
12
14
|
class PETSetup
|
|
13
15
|
MODELS = PET::Model::ALL.map(&:name).freeze
|
|
@@ -20,20 +22,24 @@ module Badline
|
|
|
20
22
|
refresh_hz = machine.refresh_hz
|
|
21
23
|
new(model: model.name, ram_kb: machine.ram.length >> 10, refresh_hz:, basic: model.basic,
|
|
22
24
|
editor: model.editor(refresh_hz), kernal: model.kernal, characters: model.characters,
|
|
23
|
-
jumpers: machine.jumpers.join(",")
|
|
25
|
+
jumpers: machine.jumpers.join(","), cpu_switch: machine.superpet? ? machine.board.cpu_switch : "",
|
|
26
|
+
ram_switch: machine.superpet? ? machine.board.ram_switch : "")
|
|
24
27
|
end
|
|
25
28
|
|
|
26
|
-
# The model by name, the RAM, the frame rate, the ROMs
|
|
27
|
-
#
|
|
29
|
+
# The model by name, the RAM, the frame rate, the ROMs, the jumpers
|
|
30
|
+
# where a board has any and the switches where it has them, in a
|
|
31
|
+
# keyed snapshot module.
|
|
28
32
|
def write_fields(out)
|
|
29
33
|
out.text("model", model).int("ram_kb", ram_kb).int("refresh_hz", refresh_hz)
|
|
30
34
|
out.text("rom.basic", basic).text("rom.editor", editor).text("rom.kernal", kernal)
|
|
31
35
|
out.text("rom.characters", characters)
|
|
32
36
|
out.text("jumpers", jumpers) unless jumpers.empty?
|
|
37
|
+
out.text("cpu_switch", cpu_switch).text("ram_switch", ram_switch) unless cpu_switch.empty?
|
|
33
38
|
end
|
|
34
39
|
|
|
35
|
-
# A ROM the snapshot doesn't name is the model's own,
|
|
36
|
-
#
|
|
40
|
+
# A ROM the snapshot doesn't name is the model's own, a board without
|
|
41
|
+
# jumpers named has none fitted, and a SuperPET without its switches
|
|
42
|
+
# named has them at 6502 and R/W.
|
|
37
43
|
def self.read_fields(input)
|
|
38
44
|
profile = PET::Model.named(input.choice("model", MODELS, PET::Model::DEFAULT))
|
|
39
45
|
ram_kb = input.int("ram_kb", profile.ram_kb)
|
|
@@ -47,18 +53,27 @@ module Badline
|
|
|
47
53
|
end
|
|
48
54
|
|
|
49
55
|
refresh_hz = 60 unless profile.crtc?
|
|
56
|
+
superpet = profile.superpet?
|
|
50
57
|
new(model: profile.name, ram_kb:, refresh_hz:, basic: input.text("rom.basic", profile.basic),
|
|
51
58
|
editor: input.text("rom.editor", profile.editor(refresh_hz)),
|
|
52
59
|
kernal: input.text("rom.kernal", profile.kernal),
|
|
53
|
-
characters: input.text("rom.characters", profile.characters), jumpers: input.text("jumpers", "")
|
|
60
|
+
characters: input.text("rom.characters", profile.characters), jumpers: input.text("jumpers", ""),
|
|
61
|
+
cpu_switch: superpet ? input.choice("cpu_switch", PET::SuperPET::Board::CPU_SWITCH, "6502") : "",
|
|
62
|
+
ram_switch: superpet ? input.choice("ram_switch", PET::SuperPET::Board::RAM_SWITCH, "rw") : "")
|
|
54
63
|
end
|
|
55
64
|
|
|
56
65
|
# A machine built this way, at power-on, with the BASIC, editor and
|
|
57
66
|
# character ROMs PET::ROMSets names for its ROMs.
|
|
58
67
|
def build
|
|
59
68
|
version = PET::ROMSets::BASICS.find { |_, roms| roms.first == basic }&.first
|
|
60
|
-
|
|
61
|
-
|
|
69
|
+
editor_name = PET::ROMSets::EDITORS.key(editor)
|
|
70
|
+
unless cpu_switch.empty?
|
|
71
|
+
return PET::SuperPET.new(refresh_hz:, basic: version, editor: editor_name, cpu: cpu_switch,
|
|
72
|
+
bank_ram: ram_switch)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
PET.new(model:, ram_kb:, refresh_hz:, basic: version, editor: editor_name, characters: fitted_characters,
|
|
76
|
+
jumpers: jumpers.split(","))
|
|
62
77
|
rescue ArgumentError => e
|
|
63
78
|
raise FormatError, "the snapshot is of a #{self}, which badline doesn't build: #{e.message}"
|
|
64
79
|
end
|
|
@@ -68,6 +83,7 @@ module Badline
|
|
|
68
83
|
def to_s
|
|
69
84
|
text = "#{model} with #{ram_kb}K at #{refresh_hz} Hz"
|
|
70
85
|
text = "#{text} jumpered #{jumpers}" unless jumpers.empty?
|
|
86
|
+
text = "#{text} with its CPU switch at #{cpu_switch} and RAM switch at #{ram_switch}" unless cpu_switch.empty?
|
|
71
87
|
roms = [basic, editor, kernal, characters]
|
|
72
88
|
profile = PET::Model.named(model)
|
|
73
89
|
stock = [profile.basic, profile.editor(refresh_hz), profile.kernal, profile.characters]
|
|
@@ -13,6 +13,7 @@ module Badline
|
|
|
13
13
|
T64_ARCHIVE = 4
|
|
14
14
|
D80 = 5
|
|
15
15
|
D82 = 6
|
|
16
|
+
D67 = 7
|
|
16
17
|
|
|
17
18
|
module_function
|
|
18
19
|
|
|
@@ -22,6 +23,7 @@ module Badline
|
|
|
22
23
|
return D81 if image.is_a?(Storage::D81Image)
|
|
23
24
|
return D82 if image.is_a?(Storage::D82Image)
|
|
24
25
|
return D80 if image.is_a?(Storage::D80Image)
|
|
26
|
+
return D67 if image.is_a?(Storage::D67Image)
|
|
25
27
|
|
|
26
28
|
raise ArgumentError, "#{image.class} can't go in a snapshot"
|
|
27
29
|
end
|
|
@@ -41,7 +43,7 @@ module Badline
|
|
|
41
43
|
end
|
|
42
44
|
end
|
|
43
45
|
|
|
44
|
-
KIND_NAMES = %w[directory d64 d71 d81 t64 d80 d82].freeze
|
|
46
|
+
KIND_NAMES = %w[directory d64 d71 d81 t64 d80 d82 d67].freeze
|
|
45
47
|
|
|
46
48
|
# Opens the storage write_fields wrote: the same directory by its
|
|
47
49
|
# path, an archive with the bytes it held, or a disk image with the
|
|
@@ -61,6 +63,7 @@ module Badline
|
|
|
61
63
|
when D71 then Storage::D71Image.new(path, read_only:, bytes:)
|
|
62
64
|
when D80 then Storage::D80Image.new(path, read_only:, bytes:)
|
|
63
65
|
when D82 then Storage::D82Image.new(path, read_only:, bytes:)
|
|
66
|
+
when D67 then Storage::D67Image.new(path, read_only:, bytes:)
|
|
64
67
|
else Storage::D81Image.new(path, read_only:, bytes:)
|
|
65
68
|
end
|
|
66
69
|
end
|
|
@@ -3,26 +3,30 @@
|
|
|
3
3
|
module Badline
|
|
4
4
|
module Snapshot
|
|
5
5
|
# How a VIC-20 was built: its RAM expansion, a key of
|
|
6
|
-
# Vic20::Bus::RAM_CONFIGURATIONS,
|
|
7
|
-
|
|
6
|
+
# Vic20::Bus::RAM_CONFIGURATIONS, and its model, one of Vic20::MODELS,
|
|
7
|
+
# the arguments Vic20.new takes.
|
|
8
|
+
Vic20Setup = Data.define(:ram, :model)
|
|
8
9
|
|
|
9
10
|
class Vic20Setup
|
|
10
11
|
RAM_CONFIGURATIONS = Vic20::Bus::RAM_CONFIGURATIONS.keys.freeze
|
|
11
12
|
|
|
12
|
-
# The RAM expansion by name, in a keyed snapshot module.
|
|
13
|
+
# The RAM expansion and the model by name, in a keyed snapshot module.
|
|
14
|
+
# A snapshot without a model is of a PAL machine, the only one badline
|
|
15
|
+
# built before the NTSC one.
|
|
13
16
|
def write_fields(out)
|
|
14
|
-
out.text("ram", ram.to_s)
|
|
17
|
+
out.text("ram", ram.to_s).text("model", model)
|
|
15
18
|
end
|
|
16
19
|
|
|
17
20
|
def self.read_fields(input)
|
|
18
21
|
text = input.choice("ram", RAM_CONFIGURATIONS.map(&:to_s), "unexpanded")
|
|
19
|
-
new(ram: RAM_CONFIGURATIONS.find { |name| name.to_s == text } || :unexpanded
|
|
22
|
+
new(ram: RAM_CONFIGURATIONS.find { |name| name.to_s == text } || :unexpanded,
|
|
23
|
+
model: input.choice("model", Vic20::MODELS, "pal"))
|
|
20
24
|
end
|
|
21
25
|
|
|
22
26
|
# A machine built this way, at power-on.
|
|
23
|
-
def build = Vic20.new(ram:)
|
|
27
|
+
def build = Vic20.new(ram:, model:)
|
|
24
28
|
|
|
25
|
-
def to_s = ram.to_s
|
|
29
|
+
def to_s = model == "pal" ? ram.to_s : "#{ram} #{model}"
|
|
26
30
|
end
|
|
27
31
|
end
|
|
28
32
|
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "badline/snapshot/vice/cbm2_acia"
|
|
3
4
|
require "badline/snapshot/vice/pet_cpu"
|
|
4
5
|
require "badline/snapshot/vice/pet_mem"
|
|
5
6
|
require "badline/snapshot/vice/pet_pias"
|
|
@@ -22,8 +23,8 @@ module Badline
|
|
|
22
23
|
# The models badline builds by the board PETMEM names (PETMem): the
|
|
23
24
|
# discrete board is a 2001's where xpet's settings say so, and a
|
|
24
25
|
# 3032 otherwise.
|
|
25
|
-
MODELS = { PETMem::CRTC40 => "4032", PETMem::CRTC80 => "8032", PETMem::
|
|
26
|
-
PETMem::CBM8296 => "8296" }.freeze
|
|
26
|
+
MODELS = { PETMem::CRTC40 => "4032", PETMem::CRTC80 => "8032", PETMem::SUPERPET => "superpet",
|
|
27
|
+
PETMem::CBM8096 => "8096", PETMem::CBM8296 => "8296" }.freeze
|
|
27
28
|
# The modules xpet resets the machine without, for the parts badline
|
|
28
29
|
# doesn't model in VICE's terms, each as xpet leaves them with
|
|
29
30
|
# nothing attached: no file system drive open, both cassette ports
|
|
@@ -50,7 +51,8 @@ module Badline
|
|
|
50
51
|
PIAs.export("PIA1", machine.pia1, reader(readers, "BL-PIA1")),
|
|
51
52
|
PIAs.export("PIA2", machine.pia2, reader(readers, "BL-PIA2")), VIA.export(reader(readers, "BL-VIA")),
|
|
52
53
|
*Drive2031.export(machine, readers), *Drive8050.export(machine, readers)] +
|
|
53
|
-
PERIPHERALS.map { |name, major, minor, bytes| FieldWriter.new.bytes(bytes).section(name, major, minor) }
|
|
54
|
+
PERIPHERALS.map { |name, major, minor, bytes| FieldWriter.new.bytes(bytes).section(name, major, minor) } +
|
|
55
|
+
(machine.superpet? ? [CBM2::ACIA.export(reader(readers, "BL-ACIA"), machine.cycles)] : [])
|
|
54
56
|
end
|
|
55
57
|
|
|
56
58
|
def reader(readers, name) = readers[name] || Keyed::Reader.missing(name)
|
|
@@ -61,7 +63,9 @@ module Badline
|
|
|
61
63
|
# xpet doesn't save the keyboard, the ROMs or an 8296's jumpers, so
|
|
62
64
|
# a discrete board is a 3032 with the graphics keyboard unless it is
|
|
63
65
|
# a 2001, each model has its own ROMs, and an 8296 none of its
|
|
64
|
-
# jumpers, as xpet's own has.
|
|
66
|
+
# jumpers, as xpet's own has. Nor does it save the SuperPET's
|
|
67
|
+
# switches: its CPU switch is at the CPU that has the bus, and its
|
|
68
|
+
# RAM switch at R/W, which is the only position xpet has.
|
|
65
69
|
def setup(container)
|
|
66
70
|
memory = memory(container)
|
|
67
71
|
ram_kb = PETMem.ram_kb(memory)
|
|
@@ -75,8 +79,11 @@ module Badline
|
|
|
75
79
|
crtc = nil unless crtc.nil? || CRTC.reads?(crtc)
|
|
76
80
|
refresh_hz = refresh_hz(crtc, profile)
|
|
77
81
|
profile = Badline::PET::Model.upgraded(profile, nil, editor(crtc, profile, refresh_hz))
|
|
82
|
+
superpet = profile.superpet?
|
|
83
|
+
cpu_switch = PETMem.m6809?(memory) ? "6809" : "6502"
|
|
78
84
|
PETSetup.new(model: name, ram_kb:, refresh_hz:, basic: profile.basic, editor: profile.editor(refresh_hz),
|
|
79
|
-
kernal: profile.kernal, characters: profile.characters, jumpers: ""
|
|
85
|
+
kernal: profile.kernal, characters: profile.characters, jumpers: "",
|
|
86
|
+
cpu_switch: superpet ? cpu_switch : "", ram_switch: superpet ? "rw" : "")
|
|
80
87
|
end
|
|
81
88
|
|
|
82
89
|
def memory(container)
|
|
@@ -94,8 +101,7 @@ module Badline
|
|
|
94
101
|
name = MODELS[board]
|
|
95
102
|
return name unless name.nil?
|
|
96
103
|
|
|
97
|
-
|
|
98
|
-
raise FormatError, "#{memory}: #{what}, which badline doesn't build"
|
|
104
|
+
raise FormatError, "#{memory}: board #{board}, which badline doesn't build"
|
|
99
105
|
end
|
|
100
106
|
|
|
101
107
|
# The editor's frame rate, from the cycles the CRTC's registers set
|
|
@@ -25,7 +25,11 @@ module Badline
|
|
|
25
25
|
|
|
26
26
|
def reads?(section) = section.major == MAJOR && section.minor == MINOR
|
|
27
27
|
|
|
28
|
-
def export(machine)
|
|
28
|
+
def export(machine)
|
|
29
|
+
sources = [machine.pia1.irq?, machine.pia2.irq?, machine.via.irq?]
|
|
30
|
+
sources << machine.acia_irq? if machine.superpet?
|
|
31
|
+
write(machine, sources.count(true))
|
|
32
|
+
end
|
|
29
33
|
|
|
30
34
|
# The module for `machine`, whose CPU's IRQ line `irqs` sources
|
|
31
35
|
# pull.
|
|
@@ -52,16 +56,46 @@ module Badline
|
|
|
52
56
|
end
|
|
53
57
|
|
|
54
58
|
# The SuperPET's 6809, CPU6809 1.1, which xpet saves on every model
|
|
55
|
-
# and won't load a snapshot without: the clock
|
|
56
|
-
#
|
|
57
|
-
#
|
|
59
|
+
# and won't load a snapshot without: the clock, X, Y, U, S and PC,
|
|
60
|
+
# DP, CC, A and B, then five bytes. xpet 3.10's layout was inferred
|
|
61
|
+
# from its snapshots of a 6809 running a loop that loads each
|
|
62
|
+
# register with a value of its own; the five bytes are 0 in every
|
|
63
|
+
# snapshot xpet wrote.
|
|
64
|
+
#
|
|
65
|
+
# Written: the clock and the registers, the SuperPET's 6809's
|
|
66
|
+
# between instructions while it has the bus, and otherwise the
|
|
67
|
+
# registers of a 6809 that hasn't run, as xpet leaves them. Read:
|
|
68
|
+
# the registers, with the 6809 on an instruction boundary, as
|
|
69
|
+
# xpet's snapshot is taken on one.
|
|
58
70
|
module CPU6809
|
|
59
71
|
NAME = "CPU6809"
|
|
72
|
+
MAJOR = 1
|
|
73
|
+
MINOR = 1
|
|
74
|
+
# The CC an xpet without a SuperPET board saves.
|
|
75
|
+
IDLE_CC = 0x04
|
|
60
76
|
|
|
61
77
|
module_function
|
|
62
78
|
|
|
79
|
+
def reads?(section) = section.major == MAJOR && section.minor == MINOR
|
|
80
|
+
|
|
63
81
|
def export(machine)
|
|
64
|
-
FieldWriter.new.qword(machine.cycles)
|
|
82
|
+
fields = FieldWriter.new.qword(machine.cycles)
|
|
83
|
+
unless machine.superpet? && machine.m6809_running?
|
|
84
|
+
return fields.zeros(11).byte(IDLE_CC).zeros(7).section(NAME, MAJOR, MINOR)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
cpu = machine.m6809
|
|
88
|
+
[cpu.x, cpu.y, cpu.u, cpu.s, cpu.pc].each { |register| fields.word(register) }
|
|
89
|
+
fields.byte(cpu.dp).byte(cpu.cc).byte(cpu.a).byte(cpu.b).zeros(5).section(NAME, MAJOR, MINOR)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# The registers by their BL-M6809 keys, in a keyed module's writer,
|
|
93
|
+
# with the 6809's cycle count the machine's `cycles`.
|
|
94
|
+
def import(section, out, cycles)
|
|
95
|
+
fields = FieldReader.new(section).skip(8)
|
|
96
|
+
%w[x y u s pc].each { |name| out.int(name, fields.word) }
|
|
97
|
+
%w[dp cc a b].each { |name| out.int(name, fields.byte) }
|
|
98
|
+
out.int("cycles", cycles).bool("nmi.armed", true)
|
|
65
99
|
end
|
|
66
100
|
end
|
|
67
101
|
end
|
|
@@ -6,7 +6,7 @@ module Badline
|
|
|
6
6
|
module PET
|
|
7
7
|
# CRTC 1.2, which xpet saves on every model, the discrete boards'
|
|
8
8
|
# video too, as a 6545 with the registers fixed: the board's screen
|
|
9
|
-
# settings, the registers, the one selected, the beam's character,
|
|
9
|
+
# settings, the character set VIA CA2 picks, the registers, the one selected, the beam's character,
|
|
10
10
|
# row and line in the row, whether the frame is in its vertical
|
|
11
11
|
# adjust, the row's start in screen RAM, the lines of vertical sync
|
|
12
12
|
# left, whether the rows show, the picture's size, the lines in the
|
|
@@ -36,6 +36,13 @@ module Badline
|
|
|
36
36
|
SETTINGS = [0xff, 0x03, 0x00, 0x20, 0x00, 0x20, 0x00, 0x10, 0xff, 0x1f].freeze
|
|
37
37
|
# The 8296's, whose screen RAM spans 4K.
|
|
38
38
|
SETTINGS_8296 = [0xff, 0x0f, 0x00, 0x20, 0x00, 0x20, 0xff, 0x0f, 0xff, 0x1f].freeze
|
|
39
|
+
# The SuperPET's, whose character ROM spans 4K, inferred from
|
|
40
|
+
# xpet 3.10's SuperPET snapshots.
|
|
41
|
+
SETTINGS_SUPERPET = [0xff, 0x03, 0x00, 0x20, 0x00, 0x20, 0x00, 0x10, 0xff, 0x3f].freeze
|
|
42
|
+
# The word after the settings while VIA CA2 is high, picking the
|
|
43
|
+
# character ROM's second set, as xpet 3.10 writes it and paints
|
|
44
|
+
# the picture from on every PET board.
|
|
45
|
+
SECOND_SET = 0x1000
|
|
39
46
|
# The 2001's and 3000 series' video as xpet's CRTC runs it: 64
|
|
40
47
|
# cycles a line, 32 rows of 8 lines and 4 more, the first 25 rows
|
|
41
48
|
# shown.
|
|
@@ -85,7 +92,7 @@ module Badline
|
|
|
85
92
|
crtc_beam(run_on(fresh_crtc(machine), crtc_input, -CRTC_LEAD % frame_cycles(registers)),
|
|
86
93
|
registers)
|
|
87
94
|
end
|
|
88
|
-
fields = FieldWriter.new.bytes(model.
|
|
95
|
+
fields = FieldWriter.new.bytes(settings(model)).word(machine.via.ca2_output ? SECOND_SET : 0)
|
|
89
96
|
fields.byte(0).byte(columns(model))
|
|
90
97
|
fields.byte(model.basic1? ? 1 : 0).bytes(registers).byte(discrete ? 0 : crtc_input.int("selected", 0))
|
|
91
98
|
beam_fields(fields, beam, registers, model)
|
|
@@ -93,6 +100,12 @@ module Badline
|
|
|
93
100
|
fields.section(NAME, MAJOR, MINOR)
|
|
94
101
|
end
|
|
95
102
|
|
|
103
|
+
def settings(model)
|
|
104
|
+
return SETTINGS_8296 if model.cbm8296?
|
|
105
|
+
|
|
106
|
+
model.superpet? ? SETTINGS_SUPERPET : SETTINGS
|
|
107
|
+
end
|
|
108
|
+
|
|
96
109
|
def crtc_registers(input)
|
|
97
110
|
registers = input.bytes("registers", "".b).bytes
|
|
98
111
|
Array.new(REGISTERS) { |index| registers[index] || 0 }
|