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
|
@@ -7,8 +7,7 @@ module Badline
|
|
|
7
7
|
# The names Badline::Model builds, in the order the help lists them.
|
|
8
8
|
MODELS = %w[c64 c64c ntsc newntsc oldntsc drean sx64 pet64 c64gs ultimax].freeze
|
|
9
9
|
|
|
10
|
-
# The VIC-20's models, as xvic names its video standards.
|
|
11
|
-
# emulated.
|
|
10
|
+
# The VIC-20's models, as xvic names its video standards.
|
|
12
11
|
VIC20_MODELS = %w[pal ntsc].freeze
|
|
13
12
|
|
|
14
13
|
# The C128's models, as C128::Model names them.
|
|
@@ -20,12 +19,22 @@ module Badline
|
|
|
20
19
|
|
|
21
20
|
# The PETs and CBMs, as PET::Model names them, the 8032 first, the
|
|
22
21
|
# default.
|
|
23
|
-
PET_MODELS = %w[8032 8096 8296 4032 3032 3032b 2001].freeze
|
|
22
|
+
PET_MODELS = %w[8032 8096 8296 4032 3032 3032b 2001 superpet].freeze
|
|
24
23
|
|
|
25
24
|
# The CBM-II's B series, as CBM2::Model names them, the 610 first, the
|
|
26
25
|
# default, and the P500, as CBM2::P500::Model names them.
|
|
27
26
|
CBM2_MODELS = %w[610 620 710 720 510 510ntsc].freeze
|
|
28
27
|
|
|
28
|
+
# The KIM-1, which has the one model.
|
|
29
|
+
KIM1_MODELS = %w[kim1].freeze
|
|
30
|
+
|
|
31
|
+
# The KIM-1 teletype's rates, as KIM1::Teletype takes them.
|
|
32
|
+
KIM1_BAUDS = %w[110 300 1200 2400 4800 9600].freeze
|
|
33
|
+
|
|
34
|
+
# The KIM-1's RAM as --ram names it, and the names
|
|
35
|
+
# KIM1::Bus::RAM_CONFIGURATIONS gives it.
|
|
36
|
+
KIM1_RAM = { "1k" => :"1k", "5k" => :"5k", "expanded" => :expanded }.freeze
|
|
37
|
+
|
|
29
38
|
# The B series' KERNALs --kernal names, 901244-04a first, the default.
|
|
30
39
|
CBM2_KERNALS = %w[04a 03b].freeze
|
|
31
40
|
|
|
@@ -49,6 +58,22 @@ module Badline
|
|
|
49
58
|
Option.new("--disable-jit", "Run without enabling YJIT", section: "Options", build: :ruby),
|
|
50
59
|
Option.new("-h, --help", "Show this help", section: "Options"),
|
|
51
60
|
Option.new("--version", "Show the version and what built it", section: "Options", build: :native),
|
|
61
|
+
Option.new("--tty", "Fit the KIM-1's TTY/KB jumper, so its monitor talks to a teletype: a pane in the " \
|
|
62
|
+
"window, or the terminal with --headless",
|
|
63
|
+
section: "Options"),
|
|
64
|
+
Option.new("--baud N", "The KIM-1 teletype's baud: #{KIM1_BAUDS.join(', ')} (default: 9600)",
|
|
65
|
+
section: "Options"),
|
|
66
|
+
Option.new("--tty-load", "Load the KIM-1's .ptp or .pap through its monitor's L command on the teletype, " \
|
|
67
|
+
"in real time, instead of straight into RAM; implies --tty",
|
|
68
|
+
section: "Options"),
|
|
69
|
+
Option.new("--load-address ADDR", "Where the KIM-1 loads a .bin, in hex (default: 0200)",
|
|
70
|
+
section: "Options"),
|
|
71
|
+
Option.new("--start-address ADDR", "Where the KIM-1 starts its program, in hex (default: where it loads)",
|
|
72
|
+
section: "Options"),
|
|
73
|
+
Option.new("--ram SIZE", "VIC-20 RAM expansion: #{RAM_NAMES.join(', ')} (default: unexpanded); " \
|
|
74
|
+
"Plus/4 RAM: 16k, 32k or 64k; PET RAM: 4k, 8k, 16k or 32k (default: the model's own); " \
|
|
75
|
+
"KIM-1 RAM: 1k, 5k or expanded (default: 1k)",
|
|
76
|
+
section: "Options"),
|
|
52
77
|
Option.new("--no-autostart", "Boot to READY. instead of running the program",
|
|
53
78
|
section: "Window options", needs: :window),
|
|
54
79
|
Option.new("--writable", "Let the machine write to disk images, changing their files",
|
|
@@ -60,19 +85,20 @@ module Badline
|
|
|
60
85
|
"a 1551 on the Plus/4, a 2031 on the PET or the CBM-II, or for a .d80 or .d82 " \
|
|
61
86
|
"an 8050 or 8250",
|
|
62
87
|
section: "Window options", needs: :window),
|
|
63
|
-
Option.new("--drive-type MODEL", "The Plus/4's true drive: 1541 or 1551 (default: 1551);
|
|
88
|
+
Option.new("--drive-type MODEL", "The Plus/4's true drive: 1541 or 1551 (default: 1551); the PET's and the " \
|
|
89
|
+
"CBM-II's: #{Drives::IEEEModels::NAMES.join(', ')} (default: 2031); " \
|
|
90
|
+
"implies --true-drive",
|
|
64
91
|
section: "Window options", needs: :window),
|
|
65
92
|
Option.new("--reu SIZE", "Plug in an REU of SIZE K: 128, 256, 512 (a 1750) or up to 16384",
|
|
66
93
|
section: "Window options", needs: :window),
|
|
67
|
-
Option.new("--model NAME", "C64 to run: #{MODELS.join(', ')} (default: #{MODELS.first});
|
|
68
|
-
"
|
|
94
|
+
Option.new("--model NAME", "C64 to run: #{MODELS.join(', ')} (default: #{MODELS.first}); " \
|
|
95
|
+
"VIC-20: #{VIC20_MODELS.join(', ')}; C128: #{C128_MODELS.join(', ')}; " \
|
|
96
|
+
"Plus/4: #{PLUS4_MODELS.join(', ')}; " \
|
|
69
97
|
"PET: #{PET_MODELS.join(', ')}; CBM-II: #{CBM2_MODELS.join(', ')}",
|
|
70
98
|
section: "Window options", needs: :window),
|
|
71
|
-
Option.new("--ntsc", "Run an NTSC C64, as --model ntsc does",
|
|
72
|
-
Option.new("--c64", "Start the C128 in C64 mode, holding C= at power-on",
|
|
99
|
+
Option.new("--ntsc", "Run an NTSC C64 or VIC-20, as --model ntsc does",
|
|
73
100
|
section: "Window options", needs: :window),
|
|
74
|
-
Option.new("--
|
|
75
|
-
"Plus/4 RAM: 16k, 32k or 64k; PET RAM: 4k, 8k, 16k or 32k (default: the model's own)",
|
|
101
|
+
Option.new("--c64", "Start the C128 in C64 mode, holding C= at power-on",
|
|
76
102
|
section: "Window options", needs: :window),
|
|
77
103
|
Option.new("--60hz", "Run a CRTC PET's 60 Hz editor instead of its 50 Hz one, or a CBM-II on 60 Hz mains",
|
|
78
104
|
section: "Window options", needs: :window),
|
|
@@ -90,6 +116,12 @@ module Badline
|
|
|
90
116
|
"$9000 and $A000, userport for the user port's PA0-PA2 to switch in " \
|
|
91
117
|
"the RAM under the ROMs",
|
|
92
118
|
section: "Window options", needs: :window),
|
|
119
|
+
Option.new("--cpu CPU", "Set the SuperPET's CPU switch: 6502, 6809 or prog, for the system latch to pick " \
|
|
120
|
+
"(default: 6502)",
|
|
121
|
+
section: "Window options", needs: :window),
|
|
122
|
+
Option.new("--bank-ram MODE", "Set the SuperPET's bank RAM switch: rw, read for write-protected, or prog, " \
|
|
123
|
+
"for the system latch to pick (default: rw)",
|
|
124
|
+
section: "Window options", needs: :window),
|
|
93
125
|
Option.new("--c1lo FILE", "Put a .bin ROM image in the Plus/4's cartridge 1, low slot ($8000)",
|
|
94
126
|
section: "Window options", needs: :window),
|
|
95
127
|
Option.new("--c1hi FILE", "Put a .bin ROM image in cartridge 1's high slot ($C000)",
|
|
@@ -108,7 +140,7 @@ module Badline
|
|
|
108
140
|
section: "Window options", needs: :window),
|
|
109
141
|
Option.new("--verbose", "Print the display, sound and gamepad setup and the frame timing",
|
|
110
142
|
section: "Window options", needs: :window),
|
|
111
|
-
Option.new("--headless", "Play a .sid tune in the terminal instead of the window",
|
|
143
|
+
Option.new("--headless", "Play a .sid tune, or run the KIM-1's teletype, in the terminal instead of the window",
|
|
112
144
|
section: "Options without the window"),
|
|
113
145
|
Option.new("--audio-out FILE", "Render a .sid tune to a .wav or .aiff file",
|
|
114
146
|
section: "Options without the window"),
|
|
@@ -52,7 +52,9 @@ module Badline
|
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def drive_type_for(value)
|
|
55
|
-
|
|
55
|
+
unless (PLUS4_DRIVE_TYPES + Drives::IEEEModels::NAMES).include?(value)
|
|
56
|
+
raise Error, "invalid argument: --drive-type #{value}"
|
|
57
|
+
end
|
|
56
58
|
|
|
57
59
|
value
|
|
58
60
|
end
|
|
@@ -63,6 +65,12 @@ module Badline
|
|
|
63
65
|
value
|
|
64
66
|
end
|
|
65
67
|
|
|
68
|
+
def baud_for(value)
|
|
69
|
+
raise Error, "invalid argument: --baud #{value}" unless KIM1_BAUDS.include?(value)
|
|
70
|
+
|
|
71
|
+
value.to_i
|
|
72
|
+
end
|
|
73
|
+
|
|
66
74
|
def reu_size(value)
|
|
67
75
|
raise Error, "invalid argument: --reu #{value}" unless REU_SIZES.include?(value)
|
|
68
76
|
|
|
@@ -83,7 +91,7 @@ module Badline
|
|
|
83
91
|
|
|
84
92
|
def validate
|
|
85
93
|
validate_family
|
|
86
|
-
|
|
94
|
+
validate_drive_type
|
|
87
95
|
|
|
88
96
|
validate_mode
|
|
89
97
|
validate_models
|
|
@@ -91,10 +99,20 @@ module Badline
|
|
|
91
99
|
validate_paths
|
|
92
100
|
end
|
|
93
101
|
|
|
102
|
+
def validate_drive_type
|
|
103
|
+
return if @drive_type.nil?
|
|
104
|
+
|
|
105
|
+
types = @family == :plus4 ? PLUS4_DRIVE_TYPES : Drives::IEEEModels::NAMES
|
|
106
|
+
return if %i[plus4 pet cbm2].include?(@family) && types.include?(@drive_type)
|
|
107
|
+
|
|
108
|
+
raise Error, "--drive-type needs #{PLUS4_DRIVE_TYPES.include?(@drive_type) ? 'plus4' : 'pet or cbm2'}"
|
|
109
|
+
end
|
|
110
|
+
|
|
94
111
|
def validate_mode
|
|
95
112
|
if headless?
|
|
96
113
|
raise Error, "#{@window_only.first} needs the window" unless @window_only.empty?
|
|
97
114
|
raise Error, "#{@any_window_only.first} needs the window" unless player_window? || @any_window_only.empty?
|
|
115
|
+
return if @family == :kim1
|
|
98
116
|
raise Error, "no tune given" if tune_paths.empty? && !player_window?
|
|
99
117
|
|
|
100
118
|
tune_paths.each { |path| validate_tune(path) }
|
|
@@ -105,6 +123,7 @@ module Badline
|
|
|
105
123
|
|
|
106
124
|
def validate_family
|
|
107
125
|
ram_option
|
|
126
|
+
@family == :kim1 ? validate_kim1 : refuse_kim1_options
|
|
108
127
|
validate_vic20 if @family == :vic20
|
|
109
128
|
@family == :plus4 ? validate_plus4 : refuse_plus4_options
|
|
110
129
|
@family == :pet ? validate_pet : refuse_pet_options
|
|
@@ -125,7 +144,8 @@ module Badline
|
|
|
125
144
|
when :vic20 then @ram = ram_configuration(@ram_name)
|
|
126
145
|
when :plus4 then @ram_kb = plus4_ram(@ram_name)
|
|
127
146
|
when :pet then @ram_kb = pet_ram(@ram_name)
|
|
128
|
-
|
|
147
|
+
when :kim1 then @ram = kim1_ram(@ram_name)
|
|
148
|
+
else raise Error, "--ram needs vic20, plus4, pet or kim1"
|
|
129
149
|
end
|
|
130
150
|
end
|
|
131
151
|
|
|
@@ -137,11 +157,8 @@ module Badline
|
|
|
137
157
|
raise Error, "the C128 needs the window" if headless?
|
|
138
158
|
end
|
|
139
159
|
|
|
140
|
-
# The VIC-20
|
|
141
|
-
# REU.
|
|
160
|
+
# The VIC-20 runs in the window, without the C64's SID and REU.
|
|
142
161
|
def validate_vic20
|
|
143
|
-
raise Error, "the NTSC VIC-20 isn't emulated yet" if @models.include?("ntsc")
|
|
144
|
-
|
|
145
162
|
raise Error, "--sid needs the C64" unless @sid_model.nil?
|
|
146
163
|
raise Error, "--reu needs the C64" unless @reu.nil?
|
|
147
164
|
raise Error, "the VIC-20 needs the window" if headless?
|
|
@@ -185,6 +202,8 @@ module Badline
|
|
|
185
202
|
raise Error, "--editor needs pet" unless @editor.nil?
|
|
186
203
|
raise Error, "--characters needs pet" unless @characters.nil?
|
|
187
204
|
raise Error, "--jumpers needs pet" unless @jumpers.empty?
|
|
205
|
+
raise Error, "--cpu needs pet --model superpet" unless @cpu.nil?
|
|
206
|
+
raise Error, "--bank-ram needs pet --model superpet" unless @bank_ram.nil?
|
|
188
207
|
end
|
|
189
208
|
|
|
190
209
|
# The PET runs in the window, without the C64's SID and REU, at the
|
|
@@ -202,7 +221,8 @@ module Badline
|
|
|
202
221
|
end
|
|
203
222
|
|
|
204
223
|
# --characters names a character ROM the board takes, --jumpers the
|
|
205
|
-
# 8296 board's jumpers, and the 8296 has all of its RAM soldered on
|
|
224
|
+
# 8296 board's jumpers, and the 8296 has all of its RAM soldered on,
|
|
225
|
+
# as the SuperPET has besides its bank RAM.
|
|
206
226
|
def validate_pet_board
|
|
207
227
|
unless @characters.nil? || PET::ROMSets.characters(model).include?(@characters)
|
|
208
228
|
raise Error, "the #{model} takes no character ROM #{@characters}"
|
|
@@ -211,6 +231,22 @@ module Badline
|
|
|
211
231
|
unknown = @jumpers.find { |jumper| !PET::ROMSets.jumpers(model).include?(jumper) }
|
|
212
232
|
raise Error, "the #{model} has no jumper #{unknown}" unless unknown.nil?
|
|
213
233
|
raise Error, "the 8296 has 32k of RAM" if model == "8296" && ![nil, 32].include?(@ram_kb)
|
|
234
|
+
raise Error, "--ram doesn't fit the superpet" if model == "superpet" && !@ram_kb.nil?
|
|
235
|
+
|
|
236
|
+
validate_cpu_switch
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
# --cpu and --bank-ram set the SuperPET's switches, which no other
|
|
240
|
+
# PET has.
|
|
241
|
+
def validate_cpu_switch
|
|
242
|
+
validate_switch("--cpu", @cpu, PET::SuperPET::Board::CPU_SWITCH)
|
|
243
|
+
validate_switch("--bank-ram", @bank_ram, PET::SuperPET::Board::RAM_SWITCH)
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
def validate_switch(flag, value, positions)
|
|
247
|
+
return if value.nil?
|
|
248
|
+
raise Error, "#{flag} needs pet --model superpet" unless model == "superpet"
|
|
249
|
+
raise Error, "invalid argument: #{flag} #{value}" unless positions.include?(value)
|
|
214
250
|
end
|
|
215
251
|
|
|
216
252
|
# --basic and --editor name ROMs the model's board takes
|
data/lib/badline/options.rb
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "badline/pet/rom_sets"
|
|
4
|
+
require "badline/drives/ieee_models"
|
|
4
5
|
require "badline/options/option"
|
|
5
6
|
require "badline/options/event"
|
|
6
7
|
require "badline/options/table"
|
|
@@ -17,7 +18,7 @@ module Badline
|
|
|
17
18
|
# the machine family, and without one the family is the C64, the C128
|
|
18
19
|
# for a program that loads where C128 BASIC starts, the PET for an
|
|
19
20
|
# 8050's or 8250's disk or a PET tape, or the CBM-II for a cartridge
|
|
20
|
-
# signed as its own.
|
|
21
|
+
# signed as its own. `kim1` runs a MOS KIM-1.
|
|
21
22
|
# The native build adds --no-sound and --version, and badline-ruby adds
|
|
22
23
|
# --disable-jit.
|
|
23
24
|
#
|
|
@@ -41,7 +42,7 @@ module Badline
|
|
|
41
42
|
SID_MODELS = { "6581" => :mos6581, "8580" => :mos8580 }.freeze
|
|
42
43
|
|
|
43
44
|
# What `sid` leaves out besides the window's options.
|
|
44
|
-
NOT_FOR_SID = %w[--audio-out].freeze
|
|
45
|
+
NOT_FOR_SID = %w[--audio-out --tty --baud --tty-load --load-address --start-address --ram].freeze
|
|
45
46
|
|
|
46
47
|
REU_SIZES = %w[128 256 512 1024 2048 4096 8192 16384].freeze
|
|
47
48
|
|
|
@@ -89,8 +90,17 @@ module Badline
|
|
|
89
90
|
# The 8296's board jumpers --jumpers names (PET::Bus::Expansion::JUMPERS).
|
|
90
91
|
attr_reader :jumpers
|
|
91
92
|
|
|
93
|
+
# The SuperPET's CPU switch, as --cpu sets it: "6502", "6809" or
|
|
94
|
+
# "prog".
|
|
95
|
+
def cpu = @cpu || "6502"
|
|
96
|
+
|
|
97
|
+
# The SuperPET's bank RAM switch, as --bank-ram sets it: "rw", "read"
|
|
98
|
+
# or "prog".
|
|
99
|
+
def bank_ram = @bank_ram || "rw"
|
|
100
|
+
|
|
92
101
|
# The VIC-20's RAM expansion --ram names, a key of
|
|
93
|
-
# Vic20::Bus::RAM_CONFIGURATIONS, or
|
|
102
|
+
# Vic20::Bus::RAM_CONFIGURATIONS, or the KIM-1's, one of
|
|
103
|
+
# KIM1::Bus::RAM_CONFIGURATIONS, or nil without --ram.
|
|
94
104
|
attr_reader :ram
|
|
95
105
|
|
|
96
106
|
# The Plus/4's or the PET's RAM in K --ram names, one of PLUS4_RAM's or
|
|
@@ -138,6 +148,7 @@ module Badline
|
|
|
138
148
|
@ram_kb = nil
|
|
139
149
|
@ram_name = nil
|
|
140
150
|
initialize_pet
|
|
151
|
+
initialize_kim1
|
|
141
152
|
@kernal = nil
|
|
142
153
|
@cartridges = {}
|
|
143
154
|
@autostart = true
|
|
@@ -230,8 +241,9 @@ module Badline
|
|
|
230
241
|
|
|
231
242
|
def true_drive? = @true_drive || !@drive_type.nil?
|
|
232
243
|
|
|
233
|
-
# The
|
|
234
|
-
|
|
244
|
+
# The true drive --drive-type names: without it, "1551" on the Plus/4
|
|
245
|
+
# and the 2031 on the PET and the CBM-II.
|
|
246
|
+
def drive_type = @drive_type || (@family == :plus4 ? "1551" : Drives::IEEEModels::DEFAULT)
|
|
235
247
|
|
|
236
248
|
# Whether --save-snapshot adds VICE's modules, so x64sc opens it.
|
|
237
249
|
def vice? = @vice
|
|
@@ -277,7 +289,7 @@ module Badline
|
|
|
277
289
|
# A .sid on its own plays in the SID player, as `sid` would, unless an
|
|
278
290
|
# option of the emulator's window asks for the machine.
|
|
279
291
|
def play_lone_tune
|
|
280
|
-
return if @sid_command || %i[vic20 plus4 pet cbm2].include?(@family) || headless? || !@window_only.empty?
|
|
292
|
+
return if @sid_command || %i[vic20 plus4 pet cbm2 kim1].include?(@family) || headless? || !@window_only.empty?
|
|
281
293
|
return if @media_path.nil?
|
|
282
294
|
|
|
283
295
|
@sid_command = File.extname(@media_path).casecmp?(".sid")
|
|
@@ -337,7 +349,7 @@ module Badline
|
|
|
337
349
|
when "--model" then @models << value
|
|
338
350
|
when "--reu" then @reu = reu_size(value)
|
|
339
351
|
when "--ram" then @ram_name = value
|
|
340
|
-
when "--basic", "--editor", "--characters", "--jumpers" then pet_option(name, value)
|
|
352
|
+
when "--basic", "--editor", "--characters", "--jumpers", "--cpu", "--bank-ram" then pet_option(name, value)
|
|
341
353
|
when "--drive-type" then @drive_type = drive_type_for(value)
|
|
342
354
|
when "--kernal" then @kernal = kernal_for(value)
|
|
343
355
|
when "--c1lo", "--c1hi", "--c2lo", "--c2hi" then @cartridges[CARTRIDGE_SLOTS.fetch(name)] = value
|
|
@@ -349,12 +361,16 @@ module Badline
|
|
|
349
361
|
when "--seconds" then @seconds = decimal(flag, value)
|
|
350
362
|
when "--songlengths" then @songlengths = value
|
|
351
363
|
when "--rate" then @rate = number(flag, value)
|
|
364
|
+
when "--baud", "--load-address", "--start-address" then kim1_option(name, flag, value)
|
|
352
365
|
else @filter_chunk = number(flag, value)
|
|
353
366
|
end
|
|
354
367
|
end
|
|
355
368
|
|
|
356
|
-
# The PET's frame rate, ROMs
|
|
369
|
+
# The PET's frame rate, ROMs, board jumpers and the SuperPET's CPU and
|
|
370
|
+
# bank RAM switches, its own until named.
|
|
357
371
|
def initialize_pet
|
|
372
|
+
@cpu = nil
|
|
373
|
+
@bank_ram = nil
|
|
358
374
|
@refresh_hz = nil
|
|
359
375
|
@basic = nil
|
|
360
376
|
@editor = nil
|
|
@@ -367,6 +383,8 @@ module Badline
|
|
|
367
383
|
when "--basic" then @basic = value
|
|
368
384
|
when "--editor" then @editor = value
|
|
369
385
|
when "--characters" then @characters = value
|
|
386
|
+
when "--cpu" then @cpu = value
|
|
387
|
+
when "--bank-ram" then @bank_ram = value
|
|
370
388
|
else @jumpers = value.split(",")
|
|
371
389
|
end
|
|
372
390
|
end
|
|
@@ -391,6 +409,7 @@ module Badline
|
|
|
391
409
|
when "--headless" then @headless = true
|
|
392
410
|
when "--quiet" then @quiet = true
|
|
393
411
|
when "--all-subtunes" then @all_subtunes = true
|
|
412
|
+
when "--tty", "--tty-load" then kim1_switch(name)
|
|
394
413
|
else @tui = false
|
|
395
414
|
end
|
|
396
415
|
end
|
data/lib/badline/pet/bus.rb
CHANGED
|
@@ -8,11 +8,12 @@ module Badline
|
|
|
8
8
|
#
|
|
9
9
|
# $0000-$7FFF - RAM, 4K, 8K, 16K or 32K of it from $0000, then nothing
|
|
10
10
|
# $8000-$8FFF - screen RAM, repeated (Model), then nothing
|
|
11
|
-
# $9000-$AFFF - two empty ROM sockets
|
|
11
|
+
# $9000-$AFFF - two empty ROM sockets, or the SuperPET's bank RAM at
|
|
12
|
+
# $9000
|
|
12
13
|
# $B000-$DFFF - BASIC 4, or BASIC 1 or 2 from $C000
|
|
13
14
|
# $E000-$E7FF - the screen editor ROM
|
|
14
15
|
# $E800-$E8FF - I/O (IO)
|
|
15
|
-
# $E900-$EFFF - nothing
|
|
16
|
+
# $E900-$EFFF - nothing, but the SuperPET's I/O page at $EF00
|
|
16
17
|
# $F000-$FFFF - the KERNAL ROM
|
|
17
18
|
#
|
|
18
19
|
# The data lines hold the last byte they carried, so a read from an
|
|
@@ -136,6 +137,7 @@ module Badline
|
|
|
136
137
|
@user_port = !@expansion.nil? && @expansion.user_port?
|
|
137
138
|
@debug_register = nil
|
|
138
139
|
@io_write_handler = nil
|
|
140
|
+
@board = nil
|
|
139
141
|
map_pages
|
|
140
142
|
end
|
|
141
143
|
|
|
@@ -174,6 +176,11 @@ module Badline
|
|
|
174
176
|
@write_pages[addr >> 8].poke(addr, value)
|
|
175
177
|
end
|
|
176
178
|
|
|
179
|
+
# #peek and #poke as the SuperPET's 6809 calls them.
|
|
180
|
+
def read(addr) = peek(addr)
|
|
181
|
+
|
|
182
|
+
def write(addr, value) = poke(addr, value)
|
|
183
|
+
|
|
177
184
|
# Whether the CPU reads the KERNAL ROM at $F000-$FFFF, which an 8096's
|
|
178
185
|
# board covers while its control register turns it on, and an 8296's
|
|
179
186
|
# RAM too.
|
|
@@ -185,6 +192,12 @@ module Badline
|
|
|
185
192
|
map_pages
|
|
186
193
|
end
|
|
187
194
|
|
|
195
|
+
# Lays the SuperPET's board (SuperPET::Board) over its pages.
|
|
196
|
+
def fit_board(board)
|
|
197
|
+
@board = board
|
|
198
|
+
map_pages
|
|
199
|
+
end
|
|
200
|
+
|
|
188
201
|
# Lays the pages out again, for the board's control register.
|
|
189
202
|
def map_pages
|
|
190
203
|
map(@open_bus, 0x00, 0x100)
|
|
@@ -195,6 +208,7 @@ module Badline
|
|
|
195
208
|
map(@io, 0xe8, 0x01)
|
|
196
209
|
@read_pages.fill(@kernal_rom, 0xf0, 0x10)
|
|
197
210
|
@expansion&.map(@read_pages, @write_pages)
|
|
211
|
+
@board&.map(@read_pages, @write_pages)
|
|
198
212
|
map_debug_register if @debug_register
|
|
199
213
|
end
|
|
200
214
|
|
|
@@ -42,8 +42,12 @@ module Badline
|
|
|
42
42
|
|
|
43
43
|
attr_reader :keyboard
|
|
44
44
|
|
|
45
|
+
# Whether the SuperPET's board pulls the diagnostic sense low.
|
|
46
|
+
attr_accessor :diagnostic_low
|
|
47
|
+
|
|
45
48
|
def initialize(keyboard)
|
|
46
49
|
@keyboard = keyboard
|
|
50
|
+
@diagnostic_low = false
|
|
47
51
|
@pia = nil
|
|
48
52
|
@ieee = nil
|
|
49
53
|
@cassettes = nil
|
|
@@ -60,8 +64,11 @@ module Badline
|
|
|
60
64
|
|
|
61
65
|
# Port A's other lines: PA4 and PA5 read the cassette sense switches,
|
|
62
66
|
# PA6 the IEEE bus's EOI, and the diagnostic sense on PA7 floats high
|
|
63
|
-
# with nothing on it.
|
|
64
|
-
def read_a(_lines)
|
|
67
|
+
# with nothing on it but the SuperPET's board, which can pull it low.
|
|
68
|
+
def read_a(_lines)
|
|
69
|
+
lines = @ieee.eoi_input & @cassettes.sense_input
|
|
70
|
+
@diagnostic_low ? lines & 0x7f : lines
|
|
71
|
+
end
|
|
65
72
|
|
|
66
73
|
def read_b(lines)
|
|
67
74
|
row = @pia.port_a_output & 0x0f
|
|
@@ -25,7 +25,9 @@ module Badline
|
|
|
25
25
|
out.int("cycles", @cycles).bool("vertical_drive", @vertical_drive)
|
|
26
26
|
pending = @pending_keys
|
|
27
27
|
out.ints("host.pending_keys", pending) if pending
|
|
28
|
+
save_init_keys(out)
|
|
28
29
|
out.int("host.init_pending", @cycles <= @init_threshold ? @init_handlers.length : 0)
|
|
30
|
+
save_ieee_drive_fields(out)
|
|
29
31
|
end
|
|
30
32
|
|
|
31
33
|
def load_machine_fields(input)
|
|
@@ -33,7 +35,9 @@ module Badline
|
|
|
33
35
|
@vertical_drive = input.bool("vertical_drive", @vertical_drive)
|
|
34
36
|
pending = input.ints("host.pending_keys", [])
|
|
35
37
|
@pending_keys = pending.empty? ? nil : pending.dup
|
|
38
|
+
load_init_keys(input)
|
|
36
39
|
@init_handlers_lost = [input.int("host.init_pending", 0) - @init_handlers.length, 0].max
|
|
40
|
+
load_ieee_drive_fields(input)
|
|
37
41
|
end
|
|
38
42
|
end
|
|
39
43
|
|
data/lib/badline/pet/model.rb
CHANGED
|
@@ -17,7 +17,8 @@ module Badline
|
|
|
17
17
|
# 1K twice over and the 80-column ones with 2K. The 8296 has 128K of
|
|
18
18
|
# dynamic RAM, the 32K below $8000, the 32K above it, of which the
|
|
19
19
|
# screen is the start and the rest lies under the ROMs, and the 64K
|
|
20
|
-
# board (Bus::Expansion).
|
|
20
|
+
# board (Bus::Expansion). The SuperPET is an 8032 with the 901640-01
|
|
21
|
+
# character ROM, twice the 8032's size, and its own board (SuperPET).
|
|
21
22
|
module Model
|
|
22
23
|
Profile = Data.define(:name, :ram_kb, :basic, :editor_50hz, :editor_60hz, :kernal, :characters, :keyboard,
|
|
23
24
|
:video, :expansion) do
|
|
@@ -28,6 +29,9 @@ module Badline
|
|
|
28
29
|
# The 8296, whose board decodes its memory in a PLA.
|
|
29
30
|
def cbm8296? = name == "8296"
|
|
30
31
|
|
|
32
|
+
# The SuperPET, an 8032 with the Waterloo board (SuperPET).
|
|
33
|
+
def superpet? = name == "superpet"
|
|
34
|
+
|
|
31
35
|
# The screen RAM's bytes, and on the 8296 all 32K of RAM from $8000.
|
|
32
36
|
def screen_bytes
|
|
33
37
|
return 0x8000 if cbm8296?
|
|
@@ -86,7 +90,12 @@ module Badline
|
|
|
86
90
|
kernal: "pet/kernal4.rom", characters: "pet/characters2.rom", keyboard: :business,
|
|
87
91
|
video: :crtc80, expansion: true)
|
|
88
92
|
|
|
89
|
-
|
|
93
|
+
SUPERPET = Profile.new(name: "superpet", ram_kb: 32, basic: "pet/basic4.rom",
|
|
94
|
+
editor_50hz: "pet/editor4-80-b-50hz.rom", editor_60hz: "pet/editor4-80-b-60hz.rom",
|
|
95
|
+
kernal: "pet/kernal4.rom", characters: "pet/characters-superpet.rom",
|
|
96
|
+
keyboard: :business, video: :crtc80, expansion: false)
|
|
97
|
+
|
|
98
|
+
ALL = [PET2001, PET3032, PET3032B, PET4032, CBM8032, CBM8096, CBM8296, SUPERPET].freeze
|
|
90
99
|
|
|
91
100
|
DEFAULT = "8032"
|
|
92
101
|
|
data/lib/badline/pet/rom_sets.rb
CHANGED
|
@@ -39,6 +39,7 @@ module Badline
|
|
|
39
39
|
"4032" => { "4" => %w[4-40-n-50hz 4-40-n-60hz] },
|
|
40
40
|
"8032" => { "4" => %w[4-80-b-50hz 4-80-b-50hz-0283 4-80-b-60hz] },
|
|
41
41
|
"8096" => { "4" => %w[4-80-b-50hz 4-80-b-50hz-0283 4-80-b-60hz] },
|
|
42
|
+
"superpet" => { "4" => %w[4-80-b-50hz 4-80-b-50hz-0283 4-80-b-60hz] },
|
|
42
43
|
"8296" => { "4" => %w[4-80-b-50hz-8296 4-80-b-50hz 4-80-b-50hz-0283 4-80-b-60hz] }
|
|
43
44
|
}.freeze
|
|
44
45
|
|
data/lib/badline/pet/sound.rb
CHANGED
|
@@ -8,121 +8,21 @@ module Badline
|
|
|
8
8
|
# added. CB2 carries the shift register's bits in its shift-out modes,
|
|
9
9
|
# mode 4's free-running square wave under timer 2 for the bell and most
|
|
10
10
|
# PET music, and the PCR's CB2 output otherwise, held high or low by
|
|
11
|
-
# hand or floating high as an input.
|
|
12
|
-
#
|
|
13
|
-
# The machine calls #cycle! once a cycle while #recording?, from #record
|
|
14
|
-
# on, so a sound nobody records costs only that check. Each sample is
|
|
15
|
-
# the share of its cycles CB2 spent high, through the output stage: a
|
|
16
|
-
# one-pole low-pass at 5 kHz and a one-pole high-pass at 100 Hz, so a
|
|
17
|
-
# line left high or low settles to silence.
|
|
11
|
+
# hand or floating high as an input. Machine::LineSound turns it into
|
|
12
|
+
# samples.
|
|
18
13
|
class Sound
|
|
19
|
-
|
|
20
|
-
HIGH_PASS_HZ = 100
|
|
21
|
-
|
|
22
|
-
# A swing from CB2 low to CB2 high, as a signed 16-bit sample.
|
|
23
|
-
SCALE = 24_000.0
|
|
14
|
+
include Machine::LineSound
|
|
24
15
|
|
|
25
16
|
def initialize(via)
|
|
26
17
|
@via = via
|
|
27
|
-
|
|
28
|
-
@high = true
|
|
29
|
-
@run = 0
|
|
30
|
-
@rate = 0
|
|
31
|
-
@clock_hz = 0
|
|
32
|
-
@remainder = 0
|
|
33
|
-
@window = 0
|
|
34
|
-
@left = 0
|
|
35
|
-
@sum = 0
|
|
36
|
-
@low = 0.0
|
|
37
|
-
@drift = 0.0
|
|
38
|
-
@low_pass = 0.0
|
|
39
|
-
@high_pass = 0.0
|
|
40
|
-
@samples = []
|
|
18
|
+
init_line_sound
|
|
41
19
|
end
|
|
42
20
|
|
|
43
21
|
def model = :cb2
|
|
44
22
|
|
|
45
|
-
attr_reader :recording
|
|
46
|
-
alias recording? recording
|
|
47
|
-
|
|
48
|
-
# Starts collecting the output, averaged down to `rate` samples a
|
|
49
|
-
# second at `clock_hz` cycles a second, for #drain_samples. The
|
|
50
|
-
# output stage takes CB2's level now as settled.
|
|
51
|
-
def record(rate:, clock_hz: 1_000_000)
|
|
52
|
-
@rate = rate
|
|
53
|
-
@clock_hz = clock_hz
|
|
54
|
-
@remainder = 0
|
|
55
|
-
@window = next_window
|
|
56
|
-
@left = @window
|
|
57
|
-
@sum = 0
|
|
58
|
-
@high = @via.cb2_output
|
|
59
|
-
@run = 0
|
|
60
|
-
@low = @drift = @high ? 1.0 : 0.0
|
|
61
|
-
@low_pass = 1.0 - Math.exp(-2.0 * Math::PI * LOW_PASS_HZ / rate)
|
|
62
|
-
@high_pass = 1.0 - Math.exp(-2.0 * Math::PI * HIGH_PASS_HZ / rate)
|
|
63
|
-
@samples = []
|
|
64
|
-
@recording = true
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# Takes CB2's level for this cycle, while recording.
|
|
68
|
-
def cycle!
|
|
69
|
-
high = @via.cb2_output
|
|
70
|
-
if high == @high
|
|
71
|
-
@run += 1
|
|
72
|
-
else
|
|
73
|
-
hold(@high, @run)
|
|
74
|
-
@high = high
|
|
75
|
-
@run = 1
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# The samples closed since the last drain.
|
|
80
|
-
def drain_samples
|
|
81
|
-
return [] unless @recording
|
|
82
|
-
|
|
83
|
-
hold(@high, @run)
|
|
84
|
-
@run = 0
|
|
85
|
-
samples = @samples
|
|
86
|
-
@samples = []
|
|
87
|
-
samples
|
|
88
|
-
end
|
|
89
|
-
|
|
90
23
|
private
|
|
91
24
|
|
|
92
|
-
|
|
93
|
-
# they finish.
|
|
94
|
-
def hold(high, cycles)
|
|
95
|
-
left = @left
|
|
96
|
-
while cycles >= left
|
|
97
|
-
@sum += left if high
|
|
98
|
-
cycles -= left
|
|
99
|
-
close
|
|
100
|
-
left = @left
|
|
101
|
-
end
|
|
102
|
-
@sum += cycles if high
|
|
103
|
-
@left = left - cycles
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def close
|
|
107
|
-
@low += @low_pass * (@sum.fdiv(@window) - @low)
|
|
108
|
-
@drift += @high_pass * (@low - @drift)
|
|
109
|
-
sample = ((@low - @drift) * SCALE).round
|
|
110
|
-
sample = 32_767 if sample > 32_767
|
|
111
|
-
sample = -32_768 if sample < -32_768
|
|
112
|
-
@samples << sample
|
|
113
|
-
@sum = 0
|
|
114
|
-
@window = next_window
|
|
115
|
-
@left = @window
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
# Each window is a whole number of cycles, and they add up to the
|
|
119
|
-
# clock's cycles over a second.
|
|
120
|
-
def next_window
|
|
121
|
-
@remainder += @clock_hz
|
|
122
|
-
cycles = @remainder / @rate
|
|
123
|
-
@remainder -= cycles * @rate
|
|
124
|
-
cycles
|
|
125
|
-
end
|
|
25
|
+
def line_high? = @via.cb2_output
|
|
126
26
|
end
|
|
127
27
|
end
|
|
128
28
|
end
|