badline 0.16.0 → 0.17.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 +76 -0
- data/CLAUDE.md +1 -1
- data/README.md +130 -17
- data/doc/media.md +14 -2
- data/doc/pinned-behaviour.md +61 -0
- data/doc/snapshot-format.md +379 -70
- data/doc/snapshots.md +185 -10
- data/lib/badline/cbm2/acia.rb +10 -0
- data/lib/badline/cbm2/bus.rb +263 -0
- data/lib/badline/cbm2/cpu.rb +58 -0
- data/lib/badline/cbm2/crtc_video.rb +133 -0
- data/lib/badline/cbm2/ieee_drive.rb +18 -0
- data/lib/badline/cbm2/ieee_layout.rb +69 -0
- data/lib/badline/cbm2/ieee_ports.rb +104 -0
- data/lib/badline/cbm2/ieee_traps.rb +81 -0
- data/lib/badline/cbm2/keyboard_ports.rb +60 -0
- data/lib/badline/cbm2/keyed_modules.rb +67 -0
- data/lib/badline/cbm2/keyed_state.rb +91 -0
- data/lib/badline/cbm2/model.rb +44 -0
- data/lib/badline/cbm2/p500/control_ports.rb +80 -0
- data/lib/badline/cbm2/p500/ieee_layout.rb +41 -0
- data/lib/badline/cbm2/p500/keyed_state.rb +85 -0
- data/lib/badline/cbm2/p500/model.rb +39 -0
- data/lib/badline/cbm2/p500/pages.rb +57 -0
- data/lib/badline/cbm2/p500.rb +262 -0
- data/lib/badline/cbm2/sid_page.rb +19 -0
- data/lib/badline/cbm2.rb +267 -0
- data/lib/badline/{plus4 → chips}/acia/frames.rb +1 -1
- data/lib/badline/chips/acia/keyed_state.rb +47 -0
- data/lib/badline/chips/acia.rb +307 -0
- data/lib/badline/chips/crtc.rb +3 -2
- data/lib/badline/chips/riot/fast_forward.rb +72 -0
- data/lib/badline/chips/riot/keyed_parts.rb +69 -0
- data/lib/badline/chips/riot/timer.rb +80 -0
- data/lib/badline/chips/riot.rb +162 -0
- data/lib/badline/chips/rriot/keyed_state.rb +30 -0
- data/lib/badline/chips/rriot.rb +132 -0
- data/lib/badline/chips/tpi/keyed_state.rb +38 -0
- data/lib/badline/chips/tpi.rb +233 -0
- data/lib/badline/chips/vic/bank.rb +60 -5
- data/lib/badline/chips/vic/sprite.rb +4 -3
- data/lib/badline/drives/datasette/keyed_state.rb +9 -1
- data/lib/badline/drives/datasette.rb +27 -3
- data/lib/badline/drives/ieee_bus.rb +50 -4
- data/lib/badline/drives/model2031/ieee_port.rb +133 -0
- data/lib/badline/drives/model2031/keyed_state.rb +66 -0
- data/lib/badline/drives/model2031/parts.rb +25 -0
- data/lib/badline/drives/model2031.rb +92 -0
- data/lib/badline/drives/model8050/disk.rb +163 -0
- data/lib/badline/drives/model8050/fdc_bus.rb +102 -0
- data/lib/badline/drives/model8050/idle.rb +177 -0
- data/lib/badline/drives/model8050/ieee_port.rb +147 -0
- data/lib/badline/drives/model8050/ip_bus.rb +93 -0
- data/lib/badline/drives/model8050/keyed_state.rb +160 -0
- data/lib/badline/drives/model8050/mechanism.rb +230 -0
- data/lib/badline/drives/model8050/parts.rb +37 -0
- data/lib/badline/drives/model8050.rb +243 -0
- data/lib/badline/frontend/app.rb +10 -3
- data/lib/badline/frontend/boot.rb +1 -1
- data/lib/badline/frontend/controls.rb +51 -15
- data/lib/badline/frontend/gamepads.rb +3 -3
- data/lib/badline/frontend/keys.rb +61 -2
- data/lib/badline/frontend/media_slots.rb +1 -1
- data/lib/badline/frontend/menu/menu_media.rb +14 -11
- data/lib/badline/frontend/menu/menu_pages.rb +29 -6
- data/lib/badline/frontend/menu/menu_ports.rb +40 -4
- data/lib/badline/frontend/menu/pause_menu.rb +1 -1
- data/lib/badline/frontend/pet_keyboard.rb +23 -7
- data/lib/badline/frontend/timeline.rb +19 -10
- data/lib/badline/kernal_trap/dos/disk_commands.rb +80 -0
- data/lib/badline/kernal_trap/dos/status.rb +3 -0
- data/lib/badline/kernal_trap/dos.rb +18 -5
- data/lib/badline/kernal_trap/ieee.rb +7 -2
- data/lib/badline/kernal_trap/ieee_layout.rb +95 -43
- data/lib/badline/machine/ieee_drives.rb +194 -0
- data/lib/badline/machine/settling.rb +4 -0
- data/lib/badline/machine.rb +26 -8
- data/lib/badline/media/cbm2_media.rb +29 -0
- data/lib/badline/media/pet_media.rb +5 -5
- data/lib/badline/media/program.rb +6 -3
- data/lib/badline/media/true_drive.rb +50 -8
- data/lib/badline/media.rb +21 -8
- data/lib/badline/options/family.rb +15 -3
- data/lib/badline/options/help.rb +24 -6
- data/lib/badline/options/table.rb +25 -5
- data/lib/badline/options/validation.rb +47 -7
- data/lib/badline/options.rb +48 -15
- data/lib/badline/pet/bus/expansion.rb +99 -5
- data/lib/badline/pet/bus.rb +30 -12
- data/lib/badline/pet/cassettes.rb +22 -1
- data/lib/badline/pet/characters.rb +8 -2
- data/lib/badline/pet/crtc_video.rb +20 -7
- data/lib/badline/pet/ieee_drive.rb +17 -0
- data/lib/badline/pet/ieee_ports.rb +19 -1
- data/lib/badline/pet/ieee_traps.rb +10 -5
- data/lib/badline/pet/keyed_modules.rb +4 -1
- data/lib/badline/pet/keyed_parts.rb +10 -6
- data/lib/badline/pet/model.rb +56 -6
- data/lib/badline/pet/rom_sets.rb +30 -6
- data/lib/badline/pet.rb +45 -16
- data/lib/badline/plus4/acia.rb +4 -298
- data/lib/badline/plus4/keyed_parts.rb +0 -44
- data/lib/badline/plus4.rb +1 -0
- data/lib/badline/roms/8050/dos-2.7.rom +0 -0
- data/lib/badline/roms/8050/fdc-901869-01.rom +0 -0
- data/lib/badline/roms/8050/fdc-901885-04.rom +0 -0
- data/lib/badline/roms/README +144 -1
- data/lib/badline/roms/cbm2/basic128-02b.rom +0 -0
- data/lib/badline/roms/cbm2/basic128.rom +0 -0
- data/lib/badline/roms/cbm2/basic256.rom +0 -0
- data/lib/badline/roms/cbm2/characters-600.rom +0 -0
- data/lib/badline/roms/cbm2/characters-700.rom +0 -0
- data/lib/badline/roms/cbm2/kernal-03b.rom +0 -0
- data/lib/badline/roms/cbm2/kernal-04a.rom +0 -0
- data/lib/badline/roms/cbm2/p500-basic.rom +0 -0
- data/lib/badline/roms/cbm2/p500-kernal.rom +0 -0
- data/lib/badline/roms/dos2031.rom +0 -0
- data/lib/badline/roms/pet/characters-din.rom +0 -0
- data/lib/badline/roms/pet/editor4-80-b-50hz-8296.rom +0 -0
- data/lib/badline/snapshot/cbm2_setup.rb +53 -0
- data/lib/badline/snapshot/container.rb +9 -1
- data/lib/badline/snapshot/field_doc/markdown.rb +4 -2
- data/lib/badline/snapshot/field_doc.rb +39 -3
- data/lib/badline/snapshot/image.rb +79 -15
- data/lib/badline/snapshot/pet_setup.rb +30 -13
- data/lib/badline/snapshot/vice/cbm2.rb +93 -0
- data/lib/badline/snapshot/vice/cbm2_acia.rb +75 -0
- data/lib/badline/snapshot/vice/cbm2_crtc.rb +127 -0
- data/lib/badline/snapshot/vice/cbm2_mains.rb +49 -0
- data/lib/badline/snapshot/vice/cbm2_mem.rb +75 -0
- data/lib/badline/snapshot/vice/cbm2_restore.rb +204 -0
- data/lib/badline/snapshot/vice/cbm2_tpi.rb +58 -0
- data/lib/badline/snapshot/vice/cias.rb +13 -9
- data/lib/badline/snapshot/vice/p500.rb +96 -0
- data/lib/badline/snapshot/vice/p500_restore.rb +130 -0
- data/lib/badline/snapshot/vice/p500_vicii.rb +166 -0
- data/lib/badline/snapshot/vice/pet.rb +121 -0
- data/lib/badline/snapshot/vice/pet_cpu.rb +70 -0
- data/lib/badline/snapshot/vice/pet_crtc.rb +241 -0
- data/lib/badline/snapshot/vice/pet_drive.rb +180 -0
- data/lib/badline/snapshot/vice/pet_drive8050.rb +216 -0
- data/lib/badline/snapshot/vice/pet_mem.rb +93 -0
- data/lib/badline/snapshot/vice/pet_pias.rb +56 -0
- data/lib/badline/snapshot/vice/pet_restore.rb +214 -0
- data/lib/badline/snapshot/vice/pet_via.rb +165 -0
- data/lib/badline/snapshot/vice/sid_registers.rb +2 -1
- data/lib/badline/snapshot/vice/vicii_import.rb +10 -6
- data/lib/badline/snapshot/vice.rb +4 -0
- data/lib/badline/snapshot.rb +11 -3
- data/lib/badline/storage/crt_file.rb +7 -1
- data/lib/badline/storage/d64_image.rb +7 -0
- data/lib/badline/storage/d80_image.rb +17 -1
- data/lib/badline/storage/d81_image.rb +14 -0
- data/lib/badline/storage/disk_image/bam.rb +18 -3
- data/lib/badline/storage/disk_image/formatting.rb +69 -0
- data/lib/badline/storage/disk_image/writing.rb +35 -0
- data/lib/badline/storage/disk_image.rb +2 -0
- data/lib/badline/storage.rb +1 -0
- data/lib/badline/support/cbm2_checkpoint.rb +48 -0
- data/lib/badline/support/p500_checkpoint.rb +35 -0
- data/lib/badline/version.rb +1 -1
- data/lib/badline.rb +1 -0
- metadata +87 -2
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "badline/chips/riot"
|
|
4
|
+
require "badline/chips/rriot"
|
|
5
|
+
require "badline/drives/ieee_bus"
|
|
6
|
+
require "badline/drives/engine"
|
|
7
|
+
require "badline/drives/model8050/ip_bus"
|
|
8
|
+
require "badline/drives/model8050/fdc_bus"
|
|
9
|
+
require "badline/drives/model8050/parts"
|
|
10
|
+
require "badline/drives/model8050/ieee_port"
|
|
11
|
+
require "badline/drives/model8050/disk"
|
|
12
|
+
require "badline/drives/model8050/mechanism"
|
|
13
|
+
require "badline/drives/model8050/idle"
|
|
14
|
+
require "badline/drives/model8050/keyed_state"
|
|
15
|
+
|
|
16
|
+
module Badline
|
|
17
|
+
module Drives
|
|
18
|
+
# The 8050 dual disk drive of the PET and CBM-II, two drives on one
|
|
19
|
+
# IEEE-488 unit (schematic 8050001; the 8050/8250 service manual).
|
|
20
|
+
#
|
|
21
|
+
# Two 6502s share the board, clocked at 1 MHz from one 12 MHz crystal
|
|
22
|
+
# on opposite phases. The interface processor (IP) runs DOS 2.7 from
|
|
23
|
+
# 16 KB of ROM at $C000, with two 6532s (IPBus): their RAM is its zero
|
|
24
|
+
# page and stack, and their ports face the IEEE-488 bus (IEEEPort). The
|
|
25
|
+
# floppy controller (FDC) runs the 1 KB program in its 6530's ROM, with
|
|
26
|
+
# a VIA and the 6530 facing the drives (FDCBus, Mechanism). The two
|
|
27
|
+
# meet in 4 KB of common RAM, which each reaches in its own half of
|
|
28
|
+
# the cycle: the IP leaves jobs there, and the FDC runs them.
|
|
29
|
+
#
|
|
30
|
+
# Reset starts both. The FDC waits on the common RAM for the IP, which
|
|
31
|
+
# tests it, copies the FDC's start-up code into it ($C370) and waits for
|
|
32
|
+
# the FDC to answer, before both settle into their idle loops.
|
|
33
|
+
#
|
|
34
|
+
# The drive clocks against the host through a phase accumulator, as
|
|
35
|
+
# Drives::Engine::Core does: each host cycle adds 1 MHz of phase, and
|
|
36
|
+
# every whole host period in it runs a cycle of both processors. While
|
|
37
|
+
# both processors idle, it sleeps instead (Idle), and the readers of its
|
|
38
|
+
# parts catch it up first.
|
|
39
|
+
class Model8050
|
|
40
|
+
include Idle
|
|
41
|
+
|
|
42
|
+
CLOCK_HZ = 1_000_000
|
|
43
|
+
|
|
44
|
+
# The host cycles by which a unit switched on with the machine has
|
|
45
|
+
# run the IP's RAM test and the FDC's start-up and reads its jumpers.
|
|
46
|
+
BOOT_CYCLES = 1_500_000
|
|
47
|
+
|
|
48
|
+
attr_reader :device, :ieee_bus
|
|
49
|
+
|
|
50
|
+
def ip_cpu = settled(@ip_cpu)
|
|
51
|
+
|
|
52
|
+
def fdc_cpu = settled(@fdc_cpu)
|
|
53
|
+
|
|
54
|
+
def ip_bus = settled(@ip_bus)
|
|
55
|
+
|
|
56
|
+
def fdc_bus = settled(@fdc_bus)
|
|
57
|
+
|
|
58
|
+
def common = settled(@common)
|
|
59
|
+
|
|
60
|
+
def data_riot = settled(@data_riot)
|
|
61
|
+
|
|
62
|
+
def control_riot = settled(@control_riot)
|
|
63
|
+
|
|
64
|
+
def via = settled(@via)
|
|
65
|
+
|
|
66
|
+
def rriot = settled(@rriot)
|
|
67
|
+
|
|
68
|
+
def mechanism = settled(@mechanism)
|
|
69
|
+
|
|
70
|
+
def cycles
|
|
71
|
+
settle!
|
|
72
|
+
@cycles
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
attr_writer :host_clock_hz
|
|
76
|
+
|
|
77
|
+
def model_name = "8050"
|
|
78
|
+
|
|
79
|
+
# The sides each drive's disk has.
|
|
80
|
+
def sides = 1
|
|
81
|
+
|
|
82
|
+
# +dos_rom+ covers $C000-$FFFF and +fdc_rom+ is the 6530's mask, each
|
|
83
|
+
# defaulting to the image in the ROM path: DOS 2.7 and the mask for
|
|
84
|
+
# MPI mechanisms. +device+ is the number the jumpers set, 8 to 15.
|
|
85
|
+
def initialize(dos_rom: nil, fdc_rom: nil, host_clock_hz: CLOCK_HZ, device: 8)
|
|
86
|
+
@device = device
|
|
87
|
+
@host_clock_hz = host_clock_hz
|
|
88
|
+
@phase = 0
|
|
89
|
+
@cycles = 0
|
|
90
|
+
build_ip(dos_rom || ROM.load("8050/dos-2.7.rom", 0xc000))
|
|
91
|
+
build_fdc(fdc_rom || ROM.read("8050/fdc-901869-01.rom"))
|
|
92
|
+
@ip_cpu = IPCPU.new(@ip_bus)
|
|
93
|
+
@fdc_cpu = FDCCPU.new(@fdc_bus)
|
|
94
|
+
init_idle
|
|
95
|
+
@ieee_bus.attach(self)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Plugs the unit into an IEEE-488 bus, leaving the one it was on.
|
|
99
|
+
def connect(ieee_bus)
|
|
100
|
+
settle!
|
|
101
|
+
@ieee_bus.detach(self)
|
|
102
|
+
@ieee_bus = ieee_bus
|
|
103
|
+
@ieee_port.bus = ieee_bus
|
|
104
|
+
ieee_bus.attach(self)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# The lines the unit pulls on the bus while ATN is low or not
|
|
108
|
+
# (IEEEPort).
|
|
109
|
+
def ieee_low_lines(atn) = @ieee_port.ieee_low_lines(atn)
|
|
110
|
+
|
|
111
|
+
# The controller pushed its lines into the bus.
|
|
112
|
+
def host_written! = nil
|
|
113
|
+
|
|
114
|
+
# Which LEDs are lit: bit 0 drive 1's, bit 1 drive 0's, bit 2 the
|
|
115
|
+
# error LED. They hold still while the unit sleeps, so reading them
|
|
116
|
+
# leaves it asleep.
|
|
117
|
+
def leds = @ieee_port.leds
|
|
118
|
+
|
|
119
|
+
def led_on? = leds.anybits?(0x03)
|
|
120
|
+
|
|
121
|
+
# Puts a Disk in +drive+, 0 or 1. Nil takes the disk out.
|
|
122
|
+
def insert(disk, drive: 0)
|
|
123
|
+
settle!
|
|
124
|
+
@mechanism.insert(disk, drive)
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Puts in the .d80 or .d82 image at +path+, write-protected with
|
|
128
|
+
# `read_only`.
|
|
129
|
+
def insert_image(path, drive: 0, read_only: false)
|
|
130
|
+
image_class = File.extname(path).casecmp?(".d82") ? Storage::D82Image : Storage::D80Image
|
|
131
|
+
insert(Disk.new(image_class.new(path, read_only:)), drive:)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# The Disk in +drive+, or nil.
|
|
135
|
+
def disk(drive = 0) = @mechanism.disk(drive)
|
|
136
|
+
|
|
137
|
+
# Stores what the heads wrote in the disks' images, as the motors
|
|
138
|
+
# stopping do.
|
|
139
|
+
def flush
|
|
140
|
+
settle!
|
|
141
|
+
@mechanism.flush
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def power_led_on? = true
|
|
145
|
+
|
|
146
|
+
# Runs the drive cycles that fall in one host cycle, then takes the
|
|
147
|
+
# controller's lines for the next. Asleep, the unit owes the cycles
|
|
148
|
+
# instead, and wakes once the controller has moved a line.
|
|
149
|
+
def host_cycle!
|
|
150
|
+
phase = @phase + CLOCK_HZ
|
|
151
|
+
while phase >= @host_clock_hz
|
|
152
|
+
@asleep ? owe_cycle : run_cycle
|
|
153
|
+
phase -= @host_clock_hz
|
|
154
|
+
end
|
|
155
|
+
@phase = phase
|
|
156
|
+
settle! if @asleep && @ieee_port.lines_moved?
|
|
157
|
+
@ieee_port.latch_host
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def cycle!
|
|
161
|
+
settle!
|
|
162
|
+
run_cycle
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# The bus's IFC line resets both processors and every chip. RAM keeps
|
|
166
|
+
# its contents.
|
|
167
|
+
def reset!
|
|
168
|
+
settle!
|
|
169
|
+
@data_riot.reset!
|
|
170
|
+
@control_riot.reset!
|
|
171
|
+
@via.reset!
|
|
172
|
+
@rriot.reset!
|
|
173
|
+
@ip_cpu.reset!
|
|
174
|
+
@fdc_cpu.reset!
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def inspect
|
|
178
|
+
"#<#{self.class.name} cycles=#{@cycles} ip=(#{@ip_cpu.inspect}) fdc=(#{@fdc_cpu.inspect})>"
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
private
|
|
182
|
+
|
|
183
|
+
def settled(part)
|
|
184
|
+
settle!
|
|
185
|
+
part
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def run_cycle
|
|
189
|
+
step
|
|
190
|
+
watch_loops if @idle_skip
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
def build_ip(rom)
|
|
194
|
+
@common = Memory.new([], length: 0x1000)
|
|
195
|
+
@ieee_bus = IEEEBus.new
|
|
196
|
+
@ieee_port = IEEEPort.new(device: @device, bus: @ieee_bus)
|
|
197
|
+
@data_riot = DataRIOT.new(peripheral: DataLines.new(@ieee_port))
|
|
198
|
+
@control_riot = ControlRIOT.new(peripheral: ControlLines.new(@ieee_port))
|
|
199
|
+
@ieee_port.data_riot = @data_riot
|
|
200
|
+
@ieee_port.control_riot = @control_riot
|
|
201
|
+
@ip_bus = IPBus.new(rom:, common: @common, data_riot: @data_riot, control_riot: @control_riot)
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def build_fdc(rom)
|
|
205
|
+
@mechanism = Mechanism.new(sides:)
|
|
206
|
+
@via = ControllerVIA.new(start: 0x0040, peripheral: ReadLines.new(@mechanism))
|
|
207
|
+
@rriot = ControllerRRIOT.new(rom:, peripheral: StatusLines.new(@mechanism))
|
|
208
|
+
@fdc_bus = FDCBus.new(common: @common, via: @via, rriot: @rriot)
|
|
209
|
+
@mechanism.via = @via
|
|
210
|
+
@mechanism.rriot = @rriot
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# One cycle of the board: the drives, then the chips, then the IP and
|
|
214
|
+
# the FDC, each in its own half of the cycle. ATN reaches UE1's PA7 as
|
|
215
|
+
# the port latched it. UE1 pulls the IP's IRQ, and the VIA and the
|
|
216
|
+
# 6530 the FDC's. Byte ready sets the FDC's V flag through SO for the
|
|
217
|
+
# next cycle's instruction step, as on the 1541.
|
|
218
|
+
def step
|
|
219
|
+
so = @mechanism.take_so
|
|
220
|
+
@mechanism.cycle!
|
|
221
|
+
@control_riot.pa7 = @ieee_port.atn_low?
|
|
222
|
+
@data_riot.cycle!
|
|
223
|
+
@control_riot.cycle!
|
|
224
|
+
@via.cycle!
|
|
225
|
+
@rriot.cycle!
|
|
226
|
+
@ip_cpu.irq = @control_riot.irq?
|
|
227
|
+
@ip_cpu.cycle!
|
|
228
|
+
@fdc_cpu.irq = @via.irq? || @rriot.irq?
|
|
229
|
+
@fdc_cpu.so! if so
|
|
230
|
+
@fdc_cpu.cycle!
|
|
231
|
+
@cycles += 1
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
# The 8250: the 8050's board driving double-sided mechanisms, 154 tracks
|
|
236
|
+
# a disk, with jumper E3 grounding the 6530's PB6 to say so.
|
|
237
|
+
class Model8250 < Model8050
|
|
238
|
+
def model_name = "8250"
|
|
239
|
+
|
|
240
|
+
def sides = 2
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
data/lib/badline/frontend/app.rb
CHANGED
|
@@ -111,16 +111,23 @@ module Badline
|
|
|
111
111
|
end
|
|
112
112
|
end
|
|
113
113
|
|
|
114
|
+
# The window keeps F8, F9, F10, Tab and the snapshot keys for itself,
|
|
115
|
+
# but for the keys the machine claims (Controls#claims?).
|
|
114
116
|
def handle_key(scancode, down)
|
|
115
|
-
|
|
117
|
+
claimed = @controls.claims?(scancode)
|
|
118
|
+
if !claimed && toggle?(scancode)
|
|
116
119
|
handle_toggle(scancode) if down
|
|
117
|
-
elsif down && @snapshots.key(scancode)
|
|
120
|
+
elsif !claimed && down && @snapshots.key(scancode)
|
|
118
121
|
swap(@snapshots.computer)
|
|
119
|
-
elsif !Snapshots::KEYS.include?(scancode)
|
|
122
|
+
elsif claimed || !Snapshots::KEYS.include?(scancode)
|
|
120
123
|
@controls.key(scancode, down)
|
|
121
124
|
end
|
|
122
125
|
end
|
|
123
126
|
|
|
127
|
+
def toggle?(scancode)
|
|
128
|
+
[Keys::F8, Keys::F9, Keys::F10].include?(scancode) || (scancode == Keys::TAB && @controls.tab_toggles?)
|
|
129
|
+
end
|
|
130
|
+
|
|
124
131
|
# Runs the restored machine in place of the one before: the screen,
|
|
125
132
|
# the drive LED, the controls, the gamepads and the sound go over to
|
|
126
133
|
# it.
|
|
@@ -10,7 +10,7 @@ module Badline
|
|
|
10
10
|
# attach, an --at key names nothing or an event fails, which it warns
|
|
11
11
|
# about.
|
|
12
12
|
def self.run(options)
|
|
13
|
-
error = Timeline.error(options.timeline, options.family)
|
|
13
|
+
error = Timeline.error(options.timeline, options.p500? ? :p500 : options.family)
|
|
14
14
|
unless error.empty?
|
|
15
15
|
warn "#{options.program}: #{error}"
|
|
16
16
|
return 1
|
|
@@ -8,10 +8,12 @@ module Badline
|
|
|
8
8
|
# switches, the arrow cluster and space drive one joystick and WASD
|
|
9
9
|
# and left shift the other. The arrows start on joystick 2, and
|
|
10
10
|
# #swap_ports swaps them. The VIC-20's one joystick takes both. The
|
|
11
|
-
# PET
|
|
12
|
-
# (PETKeyboard)
|
|
13
|
-
#
|
|
14
|
-
#
|
|
11
|
+
# PET's and the CBM-II's keys go by the character they type
|
|
12
|
+
# (PETKeyboard), and the PET and the CBM-II's B series have no
|
|
13
|
+
# joystick.
|
|
14
|
+
# - A pot device the pause menu plugs into a control port of a C64, a
|
|
15
|
+
# C128 or a P500: a 1351 mouse or a pair of paddles, which the host
|
|
16
|
+
# mouse drives. Motion
|
|
15
17
|
# turns the paddles or moves the mouse, and the host's left and right
|
|
16
18
|
# buttons go to whichever lines the device puts them on.
|
|
17
19
|
class Controls
|
|
@@ -24,6 +26,21 @@ module Badline
|
|
|
24
26
|
# The pot device plugged in, one of POTS.
|
|
25
27
|
attr_reader :pot, :arrows_port
|
|
26
28
|
|
|
29
|
+
# Whether the machine has joysticks: all but the PET and the CBM-II's
|
|
30
|
+
# B series.
|
|
31
|
+
def self.joysticks?(computer)
|
|
32
|
+
family = computer.family
|
|
33
|
+
family != :pet && (family != :cbm2 || p500?(computer))
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Whether the machine is the CBM-II's P500, which has the B series'
|
|
37
|
+
# keyboard and two joysticks.
|
|
38
|
+
def self.p500?(computer) = computer.is_a?(CBM2::P500)
|
|
39
|
+
|
|
40
|
+
# Whether the machine's keys go by the character they type: the PET's
|
|
41
|
+
# and the CBM-II's.
|
|
42
|
+
def self.symbolic?(computer) = %i[pet cbm2].include?(computer.family)
|
|
43
|
+
|
|
27
44
|
def initialize(computer)
|
|
28
45
|
@computer = computer
|
|
29
46
|
@joystick = false
|
|
@@ -58,9 +75,19 @@ module Badline
|
|
|
58
75
|
self.joystick_mode = !@joystick if tab_toggles?
|
|
59
76
|
end
|
|
60
77
|
|
|
61
|
-
# Whether Tab switches the keys to the joysticks, or on
|
|
62
|
-
#
|
|
63
|
-
def tab_toggles? = @computer
|
|
78
|
+
# Whether Tab switches the keys to the joysticks, or on a machine
|
|
79
|
+
# without them is a key of its own.
|
|
80
|
+
def tab_toggles? = Controls.joysticks?(@computer)
|
|
81
|
+
|
|
82
|
+
# Whether the machine takes a key the window would otherwise keep for
|
|
83
|
+
# itself: on the CBM-II, F8, RUN/STOP on F12, Alt with F9 or F10, and
|
|
84
|
+
# the release of any key it pressed.
|
|
85
|
+
def claims?(scancode)
|
|
86
|
+
return false unless @computer.family == :cbm2
|
|
87
|
+
return true if @pet_keyboard.holds?(scancode) || [Keys::F8, Keys::F12].include?(scancode)
|
|
88
|
+
|
|
89
|
+
@pet_keyboard.alt? && [Keys::F9, Keys::F10].include?(scancode)
|
|
90
|
+
end
|
|
64
91
|
|
|
65
92
|
# Plugs in one of POTS, in place of the one before.
|
|
66
93
|
def plug(pot)
|
|
@@ -116,7 +143,7 @@ module Badline
|
|
|
116
143
|
# A host key lets go of the key it pressed, though the C128 has
|
|
117
144
|
# switched between C64 and C128 mode since and maps it elsewhere.
|
|
118
145
|
def machine_key(scancode, down)
|
|
119
|
-
return @pet_keyboard.key(scancode, down) if @computer
|
|
146
|
+
return @pet_keyboard.key(scancode, down) if Controls.symbolic?(@computer)
|
|
120
147
|
|
|
121
148
|
@held[scancode] = host_key(scancode) if down || !@held.key?(scancode)
|
|
122
149
|
key = @held[scancode]
|
|
@@ -159,7 +186,7 @@ module Badline
|
|
|
159
186
|
# A fresh pot device on its port, and none on the other. A machine
|
|
160
187
|
# without the ports takes none.
|
|
161
188
|
def attach_pot_device
|
|
162
|
-
ports = @computer
|
|
189
|
+
ports = Controls.p500?(@computer) || !Controls.symbolic?(@computer) ? @computer.control_ports : nil
|
|
163
190
|
if ports.nil?
|
|
164
191
|
@pot = :none
|
|
165
192
|
return
|
|
@@ -211,17 +238,26 @@ module Badline
|
|
|
211
238
|
down ? joystick.press(direction) : joystick.release(direction)
|
|
212
239
|
end
|
|
213
240
|
|
|
214
|
-
# The PET's keyboard for a PET, and for any other machine
|
|
215
|
-
# uses.
|
|
241
|
+
# The PET's keyboard for a PET or a CBM-II, and for any other machine
|
|
242
|
+
# one it never uses.
|
|
216
243
|
def pet_keyboard(computer)
|
|
217
|
-
|
|
244
|
+
layout = case computer.family
|
|
245
|
+
when :pet then computer.model.keyboard
|
|
246
|
+
when :cbm2 then :cbm2
|
|
247
|
+
else :graphics
|
|
248
|
+
end
|
|
249
|
+
PETKeyboard.new(computer.keyboard, layout)
|
|
218
250
|
end
|
|
219
251
|
|
|
220
252
|
def release_all
|
|
221
|
-
|
|
253
|
+
if Controls.symbolic?(@computer)
|
|
254
|
+
@pet_keyboard.release_all
|
|
255
|
+
else
|
|
256
|
+
Keys::ARROWS.each_key { |scancode| @computer.keyboard.release(host_key(scancode)) }
|
|
257
|
+
Keys::WASD.each_key { |scancode| @computer.keyboard.release(host_key(scancode)) }
|
|
258
|
+
end
|
|
259
|
+
return unless Controls.joysticks?(@computer)
|
|
222
260
|
|
|
223
|
-
Keys::ARROWS.each_key { |scancode| @computer.keyboard.release(host_key(scancode)) }
|
|
224
|
-
Keys::WASD.each_key { |scancode| @computer.keyboard.release(host_key(scancode)) }
|
|
225
261
|
Keys::ARROWS.each_value do |direction|
|
|
226
262
|
@computer.joystick1.release(direction)
|
|
227
263
|
@computer.joystick2.release(direction)
|
|
@@ -7,8 +7,8 @@ module Badline
|
|
|
7
7
|
# second one joystick 1. PadPort holds the mapping.
|
|
8
8
|
#
|
|
9
9
|
# The controllers are polled every frame, and rescanned whenever SDL
|
|
10
|
-
# reports one added or removed. The PET
|
|
11
|
-
# controllers steer two that nothing reads.
|
|
10
|
+
# reports one added or removed. The PET and the CBM-II's B series have
|
|
11
|
+
# no joysticks, and the controllers steer two that nothing reads.
|
|
12
12
|
class Gamepads
|
|
13
13
|
PORTS = [2, 1].freeze
|
|
14
14
|
|
|
@@ -53,7 +53,7 @@ module Badline
|
|
|
53
53
|
private
|
|
54
54
|
|
|
55
55
|
def joystick(computer, port)
|
|
56
|
-
return Input::Joystick.new
|
|
56
|
+
return Input::Joystick.new unless Controls.joysticks?(computer)
|
|
57
57
|
|
|
58
58
|
port == 1 ? computer.joystick1 : computer.joystick2
|
|
59
59
|
end
|
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
module Badline
|
|
4
4
|
module Frontend
|
|
5
5
|
# SDL scancodes follow key positions on a US layout. They map onto the C64
|
|
6
|
-
# keys, the C128's and the
|
|
7
|
-
# joystick directions.
|
|
6
|
+
# keys, the C128's, the 264's, the PET's and the CBM-II's own keys and,
|
|
7
|
+
# in joystick mode, the joystick directions.
|
|
8
8
|
module Keys
|
|
9
9
|
RETURN = 40
|
|
10
10
|
ESCAPE = 41
|
|
@@ -118,6 +118,41 @@ module Badline
|
|
|
118
118
|
# The cursor keys, CRSR ⇔ and CRSR ⇕, each with SHIFT for left or up.
|
|
119
119
|
PET_CURSORS = { RIGHT => :cursor_h, LEFT => :cursor_h, DOWN => :cursor_v, UP => :cursor_v }.freeze
|
|
120
120
|
|
|
121
|
+
# The CBM-II's keys for the characters a host key types: those it
|
|
122
|
+
# types without SHIFT, then those it types with it, as the KERNAL's
|
|
123
|
+
# key tables place them. ← is on _ and `, and SHIFT turns it into \.
|
|
124
|
+
CBM2_CHARACTERS = {
|
|
125
|
+
"1" => :"1", "2" => :"2", "3" => :"3", "4" => :"4", "5" => :"5", "6" => :"6", "7" => :"7", "8" => :"8",
|
|
126
|
+
"9" => :"9", "0" => :"0", "-" => :-, "=" => :"=", "[" => :"[", "]" => :"]", ";" => :";", "'" => :"'",
|
|
127
|
+
"," => :",", "." => :".", "/" => :/, "_" => :left_arrow, "`" => :left_arrow
|
|
128
|
+
}.freeze
|
|
129
|
+
|
|
130
|
+
CBM2_SHIFTED = {
|
|
131
|
+
"!" => :"1", "@" => :"2", "#" => :"3", "$" => :"4", "%" => :"5", "^" => :"6", "&" => :"7", "*" => :"8",
|
|
132
|
+
"(" => :"9", ")" => :"0", "+" => :"=", ":" => :";", "\"" => :"'", "<" => :",", ">" => :".", "?" => :/,
|
|
133
|
+
"\\" => :left_arrow
|
|
134
|
+
}.freeze
|
|
135
|
+
|
|
136
|
+
# The CBM-II's keys that don't type a character, which keep the
|
|
137
|
+
# host's SHIFT: RETURN, INST/DEL on Backspace, CLR/HOME on Home, ESC,
|
|
138
|
+
# TAB, RUN/STOP on F12, CTRL on Control, the four cursor keys on the
|
|
139
|
+
# arrows, F1-F8 on F1-F8, and the keypad on the host's.
|
|
140
|
+
CBM2_KEYS = {
|
|
141
|
+
40 => :return, 42 => :delete, 44 => :space, 74 => :clr_home, 41 => :escape, 43 => :tab, 69 => :run_stop,
|
|
142
|
+
224 => :control, 228 => :control, 79 => :cursor_right, 80 => :cursor_left, 81 => :cursor_down,
|
|
143
|
+
82 => :cursor_up, 58 => :f1, 59 => :f2, 60 => :f3, 61 => :f4, 62 => :f5, 63 => :f6, 64 => :f7, 65 => :f8,
|
|
144
|
+
84 => :kp_divide, 85 => :kp_multiply, 86 => :kp_minus, 87 => :kp_plus, 88 => :kp_enter, 89 => :kp1,
|
|
145
|
+
90 => :kp2, 91 => :kp3, 92 => :kp4, 93 => :kp5, 94 => :kp6, 95 => :kp7, 96 => :kp8, 97 => :kp9,
|
|
146
|
+
98 => :kp0, 99 => :kp_period
|
|
147
|
+
}.freeze
|
|
148
|
+
|
|
149
|
+
# The CBM-II's keys that Alt and a host key press: C= on C, CE on E,
|
|
150
|
+
# NORM/GRAPH on G, OFF/RVS on R, π on P, 00 on 0, and F9 and F10 on
|
|
151
|
+
# F9 and F10, which open the pause menu and mute without Alt.
|
|
152
|
+
CBM2_ALT_KEYS = {
|
|
153
|
+
6 => :cbm, 8 => :ce, 10 => :norm_graph, 21 => :off_rvs, 19 => :pi, 39 => :kp00, 66 => :f9, 67 => :f10
|
|
154
|
+
}.freeze
|
|
155
|
+
|
|
121
156
|
ARROWS = { 44 => :fire, 228 => :fire, 79 => :right, 80 => :left, 81 => :down, 82 => :up }.freeze
|
|
122
157
|
WASD = { 225 => :fire, 7 => :right, 4 => :left, 22 => :down, 26 => :up }.freeze
|
|
123
158
|
|
|
@@ -177,6 +212,30 @@ module Badline
|
|
|
177
212
|
shifted.nil? ? %i[none host] : [shifted, :on]
|
|
178
213
|
end
|
|
179
214
|
|
|
215
|
+
# The CBM-II key for the scancode, with the host's SHIFT down if
|
|
216
|
+
# +shift+, and how the CBM-II's SHIFT goes with it, as pet_key gives
|
|
217
|
+
# them.
|
|
218
|
+
def self.cbm2_key(scancode, shift)
|
|
219
|
+
return [LETTERS[scancode - 4], :host] if scancode.between?(4, 29)
|
|
220
|
+
|
|
221
|
+
key = CBM2_KEYS[scancode]
|
|
222
|
+
return [key, :host] unless key.nil?
|
|
223
|
+
|
|
224
|
+
characters = US_CHARACTERS[scancode]
|
|
225
|
+
return %i[none host] if characters.nil?
|
|
226
|
+
|
|
227
|
+
character = characters[shift ? 1 : 0]
|
|
228
|
+
unshifted = CBM2_CHARACTERS[character]
|
|
229
|
+
return [unshifted, :off] unless unshifted.nil?
|
|
230
|
+
|
|
231
|
+
shifted = CBM2_SHIFTED[character]
|
|
232
|
+
shifted.nil? ? %i[none host] : [shifted, :on]
|
|
233
|
+
end
|
|
234
|
+
|
|
235
|
+
# The CBM-II key Alt and the scancode press, which keeps the host's
|
|
236
|
+
# SHIFT, or :none.
|
|
237
|
+
def self.cbm2_alt_key(scancode) = [CBM2_ALT_KEYS[scancode] || :none, :host]
|
|
238
|
+
|
|
180
239
|
# The character the key types on a US layout: a letter, a capital
|
|
181
240
|
# with `shift`, or a digit, and "" for any other key.
|
|
182
241
|
def self.character(scancode, shift)
|
|
@@ -35,7 +35,7 @@ module Badline
|
|
|
35
35
|
# either cartridge's slots.
|
|
36
36
|
def cartridge?(computer)
|
|
37
37
|
return !computer.cartridge_slots.empty? if computer.family == :plus4
|
|
38
|
-
return false if computer.family
|
|
38
|
+
return false if %i[pet cbm2].include?(computer.family)
|
|
39
39
|
|
|
40
40
|
!computer.address_bus.cartridge.nil?
|
|
41
41
|
end
|
|
@@ -50,6 +50,8 @@ module Badline
|
|
|
50
50
|
Media.insert_disk(@computer, disk, read_only: !@writable)
|
|
51
51
|
list(path)
|
|
52
52
|
else
|
|
53
|
+
raise Machine::Unsupported, "the CBM-II has no datasette" if @computer.family == :cbm2
|
|
54
|
+
|
|
53
55
|
@computer.datasette.insert(Storage::TAP.new(path))
|
|
54
56
|
end
|
|
55
57
|
end
|
|
@@ -100,17 +102,18 @@ module Badline
|
|
|
100
102
|
end
|
|
101
103
|
|
|
102
104
|
# The extensions of the cartridges the machine takes: .crt, on the
|
|
103
|
-
# Plus/4 raw .bin ROM images too, and none on the PET
|
|
105
|
+
# Plus/4 raw .bin ROM images too, and none on the PET, or on the
|
|
106
|
+
# CBM-II, whose cartridge goes in from the command line.
|
|
104
107
|
def cartridge_extensions
|
|
105
|
-
extensions = Media::Extensions.of(@computer.family
|
|
108
|
+
extensions = Media::Extensions.of(%i[pet cbm2].include?(@computer.family) ? %i[none] : %i[cartridge])
|
|
106
109
|
@computer.family == :plus4 ? extensions + [Media::Plus4Media::ROM_IMAGE] : extensions
|
|
107
110
|
end
|
|
108
111
|
|
|
109
|
-
# The extensions of what goes in device 8: on the PET the
|
|
110
|
-
# 8250's disk images besides the others, and no raw
|
|
111
|
-
# a serial true drive reads.
|
|
112
|
+
# The extensions of what goes in device 8: on the PET and the CBM-II
|
|
113
|
+
# the 8050's and 8250's disk images besides the others, and no raw
|
|
114
|
+
# GCR, which only a serial true drive reads.
|
|
112
115
|
def disk_extensions
|
|
113
|
-
return Media::Extensions.of(%i[disk ieee_disk archive disk_list]) if @computer.family
|
|
116
|
+
return Media::Extensions.of(%i[disk ieee_disk archive disk_list]) if %i[pet cbm2].include?(@computer.family)
|
|
114
117
|
|
|
115
118
|
Media::Extensions::DEVICE8
|
|
116
119
|
end
|
|
@@ -125,14 +128,14 @@ module Badline
|
|
|
125
128
|
|
|
126
129
|
# What a save of the machine is named after: the cartridge, the disk,
|
|
127
130
|
# the tape, or BASIC, without the bracketed parts of a file's name. A
|
|
128
|
-
# VIC-20's are named after its disk, or else the machine,
|
|
129
|
-
#
|
|
131
|
+
# VIC-20's are named after its disk, or else the machine, a Plus/4's
|
|
132
|
+
# or a PET's after its disk or tape, and a CBM-II's after its disk.
|
|
130
133
|
def game_name
|
|
131
134
|
vic20 = @computer.family == :vic20
|
|
132
|
-
name = vic20 || %i[plus4 pet].include?(@computer.family) ? "" : cartridge_name
|
|
135
|
+
name = vic20 || %i[plus4 pet cbm2].include?(@computer.family) ? "" : cartridge_name
|
|
133
136
|
disk = disk_path
|
|
134
137
|
name = File.basename(disk, File.extname(disk)) if name.empty? && !disk.empty?
|
|
135
|
-
name = tape_name if name.empty? && !vic20
|
|
138
|
+
name = tape_name if name.empty? && !vic20 && @computer.family != :cbm2
|
|
136
139
|
name = name.sub(/\s*[(\[].*\z/, "").strip
|
|
137
140
|
return name unless name.empty?
|
|
138
141
|
|
|
@@ -154,7 +157,7 @@ module Badline
|
|
|
154
157
|
case @computer.family
|
|
155
158
|
when :plus4 then @computer.cartridge_slots.map { |slot| slot_name(slot) }.uniq.join(", ")
|
|
156
159
|
when :vic20 then @computer.cartridge_name
|
|
157
|
-
when :pet then ""
|
|
160
|
+
when :pet, :cbm2 then ""
|
|
158
161
|
else
|
|
159
162
|
cartridge = @computer.address_bus.cartridge
|
|
160
163
|
cartridge.nil? ? "" : cartridge.name
|
|
@@ -88,6 +88,14 @@ module Badline
|
|
|
88
88
|
# Whether the machine is a PET, whose ports page shows its keyboard.
|
|
89
89
|
def pet? = @computer.family == :pet
|
|
90
90
|
|
|
91
|
+
# Whether the machine is a CBM-II, whose ports page shows its keyboard
|
|
92
|
+
# too.
|
|
93
|
+
def cbm2? = @computer.family == :cbm2
|
|
94
|
+
|
|
95
|
+
# Whether the machine is the CBM-II's B series, whose ports page is
|
|
96
|
+
# its keyboard's alone.
|
|
97
|
+
def b_series? = cbm2? && !Controls.p500?(@computer)
|
|
98
|
+
|
|
91
99
|
private
|
|
92
100
|
|
|
93
101
|
def vic20? = @computer.family == :vic20
|
|
@@ -112,7 +120,10 @@ module Badline
|
|
|
112
120
|
info("DEVICE", drive.nil? ? "FAST LOADING" : "#{drive.model_name}, TRUE DRIVE")
|
|
113
121
|
end
|
|
114
122
|
|
|
123
|
+
# The CBM-II has no datasette.
|
|
115
124
|
def draw_datasette
|
|
125
|
+
return info("TAPE", "") if cbm2?
|
|
126
|
+
|
|
116
127
|
datasette = @computer.datasette
|
|
117
128
|
tape = datasette.tape
|
|
118
129
|
info("TAPE", tape.nil? ? "" : File.basename(tape.path))
|
|
@@ -126,6 +137,7 @@ module Badline
|
|
|
126
137
|
|
|
127
138
|
def draw_expansion
|
|
128
139
|
return draw_pet_memory if pet?
|
|
140
|
+
return info("RAM", "#{@computer.model.ram_kb}K") if cbm2?
|
|
129
141
|
|
|
130
142
|
info("CARTRIDGE", @media.cartridge_name)
|
|
131
143
|
return info("RAM EXPANSION", RAM_NAMES.fetch(@computer.ram_configuration)) if vic20?
|
|
@@ -156,10 +168,19 @@ module Badline
|
|
|
156
168
|
toggle(plus4? ? "SID CARD" : "SID", :sid, [%w[6581 8580], %i[sid6581 sid8580], model == :mos8580 ? 1 : 0])
|
|
157
169
|
end
|
|
158
170
|
|
|
159
|
-
# The PET's memory: its RAM,
|
|
171
|
+
# The PET's memory: its RAM, the 8096's 64K board, and the 8296's
|
|
172
|
+
# 128K with the jumpers that put RAM under its ROMs.
|
|
160
173
|
def draw_pet_memory
|
|
174
|
+
model = @computer.model
|
|
175
|
+
return draw_8296_memory if model.cbm8296?
|
|
176
|
+
|
|
161
177
|
info("RAM", "#{@computer.ram_kb}K")
|
|
162
|
-
info("EXPANSION RAM",
|
|
178
|
+
info("EXPANSION RAM", model.expansion ? "64K BOARD" : "")
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def draw_8296_memory
|
|
182
|
+
info("RAM", "128K, 64K OF IT BANKED")
|
|
183
|
+
info("JUMPERS", @computer.jumpers.join(", ").upcase)
|
|
163
184
|
end
|
|
164
185
|
|
|
165
186
|
# Saving now and by name, loading a named save, and the quicksaves
|
|
@@ -177,12 +198,14 @@ module Badline
|
|
|
177
198
|
end
|
|
178
199
|
end
|
|
179
200
|
|
|
180
|
-
# The C128 names its model and the mode it runs in first, the Plus/4
|
|
181
|
-
# and the
|
|
182
|
-
# it has one
|
|
201
|
+
# The C128 names its model and the mode it runs in first, the Plus/4,
|
|
202
|
+
# the PET and the CBM-II their model and RAM, the Plus/4 its RAM
|
|
203
|
+
# expansion if it has one, and the CBM-II its KERNAL, the B series'
|
|
204
|
+
# 901244 or the P500's 901234.
|
|
183
205
|
def draw_power
|
|
184
206
|
info("MACHINE", "#{@computer.model.name.upcase}, #{@computer.mode.to_s.upcase} MODE") if c128?
|
|
185
|
-
info("MACHINE", @computer.model_label) if pet?
|
|
207
|
+
info("MACHINE", @computer.model_label.upcase) if pet? || cbm2?
|
|
208
|
+
info("KERNAL", "#{Controls.p500?(@computer) ? 901_234 : 901_244}-#{@computer.kernal.upcase}") if cbm2?
|
|
186
209
|
if plus4?
|
|
187
210
|
info("MACHINE", @computer.model_label)
|
|
188
211
|
expansion = @computer.ram_expansion_label
|