badline 0.12.0 → 0.12.1
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 +8 -0
- data/lib/badline/address_bus/saved_state.rb +4 -10
- data/lib/badline/address_bus.rb +8 -27
- data/lib/badline/audio/bare_player.rb +1 -1
- data/lib/badline/c128/bus.rb +13 -35
- data/lib/badline/c128/bus_state.rb +5 -5
- data/lib/badline/c128.rb +5 -64
- data/lib/badline/computer/attachments.rb +16 -45
- data/lib/badline/computer/common.rb +34 -0
- data/lib/badline/computer/kernal_traps.rb +65 -5
- data/lib/badline/computer/true_drives.rb +12 -23
- data/lib/badline/computer.rb +5 -68
- data/lib/badline/core.rb +2 -2
- data/lib/badline/cpu_port.rb +112 -0
- data/lib/badline/drive1541/disk.rb +14 -17
- data/lib/badline/drive1541/disk_state.rb +7 -15
- data/lib/badline/drive1581/wd1772.rb +1 -1
- data/lib/badline/frontend/boot.rb +8 -59
- data/lib/badline/kernal_trap/{file.rb → file_routine.rb} +1 -1
- data/lib/badline/kernal_trap/load.rb +1 -1
- data/lib/badline/kernal_trap/save.rb +1 -1
- data/lib/badline/kernal_trap.rb +1 -1
- data/lib/badline/machine/clocking.rb +50 -0
- data/lib/badline/machine.rb +58 -2
- data/lib/badline/media/boot_disk.rb +2 -2
- data/lib/badline/media/disk_list.rb +3 -3
- data/lib/badline/media/disk_set.rb +1 -1
- data/lib/badline/media/extensions.rb +33 -0
- data/lib/badline/media/program.rb +28 -0
- data/lib/badline/media/true_drive.rb +3 -2
- data/lib/badline/media/tune.rb +35 -0
- data/lib/badline/media/vic20_cartridge.rb +1 -7
- data/lib/badline/media/vic20_media.rb +38 -80
- data/lib/badline/media.rb +82 -79
- data/lib/badline/options/event.rb +3 -1
- data/lib/badline/sid.rb +1 -1
- data/lib/badline/snapshot/machine_state.rb +9 -1
- data/lib/badline/snapshot/state.rb +5 -4
- data/lib/badline/snapshot.rb +11 -9
- data/lib/badline/storage/d64_image.rb +15 -7
- data/lib/badline/storage/disk_image/writing.rb +2 -2
- data/lib/badline/storage/disk_image.rb +1 -1
- data/lib/badline/storage/host_directory.rb +1 -1
- data/lib/badline/storage/t64.rb +1 -1
- data/lib/badline/version.rb +1 -1
- data/lib/badline/vic/bank.rb +1 -1
- data/lib/badline/vic/border_mask.rb +1 -1
- data/lib/badline/vic/collisions.rb +1 -1
- data/lib/badline/vic/color_patches.rb +1 -1
- data/lib/badline/vic/display_state.rb +1 -1
- data/lib/badline/vic/graphics_mode.rb +1 -1
- data/lib/badline/vic/graphics_shifter.rb +1 -1
- data/lib/badline/vic/register_log.rb +1 -1
- data/lib/badline/vic/registers.rb +1 -1
- data/lib/badline/vic/sequencer.rb +1 -1
- data/lib/badline/vic/sequencer_output.rb +1 -1
- data/lib/badline/vic/sequencer_state.rb +1 -1
- data/lib/badline/vic/sprite/internal_bus.rb +1 -1
- data/lib/badline/vic/sprite/saved_state.rb +1 -1
- data/lib/badline/vic/sprite/shifter.rb +1 -1
- data/lib/badline/vic/sprite/timing.rb +1 -1
- data/lib/badline/vic/sprite.rb +1 -1
- data/lib/badline/vic/sprites.rb +1 -1
- data/lib/badline/vic/sprites_state.rb +1 -1
- data/lib/badline/vic.rb +6 -5
- data/lib/badline/vic20/attachments.rb +10 -80
- data/lib/badline/vic20/saved_state.rb +0 -30
- data/lib/badline/vic20.rb +1 -37
- metadata +8 -3
- data/lib/badline/cycleable.rb +0 -38
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "badline/media/extensions"
|
|
4
|
+
|
|
3
5
|
module Badline
|
|
4
6
|
class Options
|
|
5
7
|
# One event of --at or --script: what to do, with its argument, once
|
|
@@ -23,7 +25,7 @@ module Badline
|
|
|
23
25
|
|
|
24
26
|
# What insert takes: disk images, tapes and cartridges, or an .m3u
|
|
25
27
|
# or .vfl list of disks or a directory to mount as device 8.
|
|
26
|
-
INSERTABLE = %
|
|
28
|
+
INSERTABLE = Media::Extensions.of(%i[disk gcr archive tape cartridge disk_list])
|
|
27
29
|
|
|
28
30
|
attr_reader :frame, :action, :argument
|
|
29
31
|
|
data/lib/badline/sid.rb
CHANGED
|
@@ -119,7 +119,7 @@ module Badline
|
|
|
119
119
|
# second, for #drain_samples. `filter_chunk` overrides the one the SID
|
|
120
120
|
# was built with, for a machine that built its own. `clock_hz` is the
|
|
121
121
|
# rate the SID's cycles are taken to run at.
|
|
122
|
-
def record(rate:, filter_chunk: @filter_chunk, clock_hz:
|
|
122
|
+
def record(rate:, filter_chunk: @filter_chunk, clock_hz: Region::PAL.clock_hz)
|
|
123
123
|
synthesize!
|
|
124
124
|
catch_up
|
|
125
125
|
@filter_chunk = filter_chunk
|
|
@@ -19,6 +19,10 @@ module Badline
|
|
|
19
19
|
MAJOR = 2
|
|
20
20
|
MINOR = 0
|
|
21
21
|
|
|
22
|
+
# The values a 64-bit integer holds once encode doubles them, which a
|
|
23
|
+
# native build's integers can't exceed.
|
|
24
|
+
VALUES = (-(1 << 62))..((1 << 62) - 1)
|
|
25
|
+
|
|
22
26
|
module_function
|
|
23
27
|
|
|
24
28
|
def section(state)
|
|
@@ -41,7 +45,11 @@ module Badline
|
|
|
41
45
|
strings = state.strings
|
|
42
46
|
numbers = [values.length, strings.length]
|
|
43
47
|
strings.each { |string| numbers << string.bytesize }
|
|
44
|
-
values.each
|
|
48
|
+
values.each do |value|
|
|
49
|
+
raise RangeError, "#{value} is too large for a snapshot" unless VALUES.cover?(value)
|
|
50
|
+
|
|
51
|
+
numbers << (value.negative? ? (-2 * value) - 1 : 2 * value)
|
|
52
|
+
end
|
|
45
53
|
index = numbers.pack("w*")
|
|
46
54
|
[index.bytesize].pack("V") + index + strings.join
|
|
47
55
|
end
|
|
@@ -16,10 +16,11 @@ module Badline
|
|
|
16
16
|
# fails before anything is read into a machine. Layout 3, without the
|
|
17
17
|
# KERNAL and datasette in the setup, layout 4, without the VIA shift
|
|
18
18
|
# register's clock delay, layout 5, without the board in the setup,
|
|
19
|
-
# layout 6, without the C128's Z80,
|
|
20
|
-
# serial bus,
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
# layout 6, without the C128's Z80, layout 7, without a 1581 on the
|
|
20
|
+
# serial bus, and layout 8, with the VIC's unused cycle count and
|
|
21
|
+
# pending-write flag, still read.
|
|
22
|
+
SCHEMA = 9
|
|
23
|
+
READABLE = [3, 4, 5, 6, 7, 8, SCHEMA].freeze
|
|
23
24
|
|
|
24
25
|
attr_reader :values, :strings
|
|
25
26
|
|
data/lib/badline/snapshot.rb
CHANGED
|
@@ -47,23 +47,25 @@ module Badline
|
|
|
47
47
|
# applied and left out, yielding a line for each thing left out. A
|
|
48
48
|
# snapshot that fails leaves the machine as it was.
|
|
49
49
|
def restore(computer, path, &) = read(path).restore(computer, &)
|
|
50
|
+
|
|
51
|
+
# A machine's snapshots as .vsf files. Computer, Vic20 and C128 each
|
|
52
|
+
# include it.
|
|
53
|
+
module Files
|
|
54
|
+
def save_snapshot(path) = Snapshot.save(self, path)
|
|
55
|
+
|
|
56
|
+
def restore_snapshot(path, &) = Snapshot.restore(self, path, &)
|
|
57
|
+
end
|
|
50
58
|
end
|
|
51
59
|
|
|
52
60
|
class Computer
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
def restore_snapshot(path, &) = Snapshot.restore(self, path, &)
|
|
61
|
+
include Snapshot::Files
|
|
56
62
|
end
|
|
57
63
|
|
|
58
64
|
class Vic20
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
def restore_snapshot(path, &) = Snapshot.restore(self, path, &)
|
|
65
|
+
include Snapshot::Files
|
|
62
66
|
end
|
|
63
67
|
|
|
64
68
|
class C128
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
def restore_snapshot(path, &) = Snapshot.restore(self, path, &)
|
|
69
|
+
include Snapshot::Files
|
|
68
70
|
end
|
|
69
71
|
end
|
|
@@ -20,15 +20,23 @@ module Badline
|
|
|
20
20
|
# The sides of a disk the image's tracks fill.
|
|
21
21
|
def sides = 1
|
|
22
22
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
23
|
+
# The last track of each of the 1541's speed zones but the innermost,
|
|
24
|
+
# from the outermost, zone 3, in: tracks 1-17, 18-24 and 25-30, and
|
|
25
|
+
# zone 0 from 31 on.
|
|
26
|
+
ZONE_LAST_TRACKS = [17, 24, 30].freeze
|
|
27
|
+
|
|
28
|
+
# The sectors a track holds in each zone, by its number.
|
|
29
|
+
ZONE_SECTORS = [17, 18, 19, 21].freeze
|
|
30
|
+
|
|
31
|
+
# The speed zone a track is written in, 3 for the outermost.
|
|
32
|
+
def self.zone(track)
|
|
33
|
+
zone = 3
|
|
34
|
+
zone -= 1 while zone.positive? && track > ZONE_LAST_TRACKS[3 - zone]
|
|
35
|
+
zone
|
|
30
36
|
end
|
|
31
37
|
|
|
38
|
+
def sectors_in(track) = ZONE_SECTORS[D64Image.zone(track)]
|
|
39
|
+
|
|
32
40
|
private
|
|
33
41
|
|
|
34
42
|
def error_tables = ERROR_TABLES
|
|
@@ -11,7 +11,7 @@ module Badline
|
|
|
11
11
|
module Writing
|
|
12
12
|
# Whether the disk takes writes: the image wasn't opened read-only
|
|
13
13
|
# and the host file takes them.
|
|
14
|
-
def writable? = !read_only? &&
|
|
14
|
+
def writable? = !read_only? && File.writable?(@path)
|
|
15
15
|
|
|
16
16
|
# Writes a new file, or with `replace` writes over the one of the
|
|
17
17
|
# same name in its directory entry. A name already on the disk
|
|
@@ -87,7 +87,7 @@ module Badline
|
|
|
87
87
|
saved = [@bytes.dup, @errors&.dup]
|
|
88
88
|
begin
|
|
89
89
|
yield
|
|
90
|
-
|
|
90
|
+
File.binwrite(@path, (@bytes + @errors.to_a).pack("C*"))
|
|
91
91
|
rescue WriteError, SystemCallError => e
|
|
92
92
|
@bytes, @errors = saved
|
|
93
93
|
raise e.is_a?(WriteError) ? e : WriteError.new(WriteError::WRITE_PROTECT_ON)
|
|
@@ -46,7 +46,7 @@ module Badline
|
|
|
46
46
|
# path, whether it is write-protected, and its bytes with the error
|
|
47
47
|
# table after them.
|
|
48
48
|
def save_setup(out)
|
|
49
|
-
out.int(storage_kind).string(
|
|
49
|
+
out.int(storage_kind).string(File.expand_path(@path)).boolean(@read_only).blob(@bytes + @errors.to_a)
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
# A LOAD reads only PRG files. An OPEN names the type it wants, or
|
data/lib/badline/storage/t64.rb
CHANGED
|
@@ -26,7 +26,7 @@ module Badline
|
|
|
26
26
|
# What Storage.reopen needs to open the archive again: its path and
|
|
27
27
|
# its bytes.
|
|
28
28
|
def save_setup(out)
|
|
29
|
-
out.int(T64_ARCHIVE).string(
|
|
29
|
+
out.int(T64_ARCHIVE).string(File.expand_path(@path)).blob(@bytes)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
def read_file(name, **)
|
data/lib/badline/version.rb
CHANGED
data/lib/badline/vic/bank.rb
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Badline
|
|
4
|
-
class VIC
|
|
4
|
+
class VIC
|
|
5
5
|
# A mid-line color register write becomes visible one pixel into the
|
|
6
6
|
# column emitted the cycle after the write. That emit paints the whole
|
|
7
7
|
# column with the new color, so the boundary pixel is patched back to
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Badline
|
|
4
|
-
class VIC
|
|
4
|
+
class VIC
|
|
5
5
|
# The graphics shift register, pixel by pixel, for the groups where a
|
|
6
6
|
# mode or XSCROLL change lands (VICE x64sc `draw_graphics`). The
|
|
7
7
|
# sequencer paints whole bytes everywhere else, which comes to the same
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Badline
|
|
4
|
-
class VIC
|
|
4
|
+
class VIC
|
|
5
5
|
# Mid-line writes to the sprite registers, keyed by the pixel at which
|
|
6
6
|
# they become visible. Compositing replays the line through the log, so
|
|
7
7
|
# each pixel is drawn with the register values that were in effect when
|
data/lib/badline/vic/sprite.rb
CHANGED
data/lib/badline/vic/sprites.rb
CHANGED
data/lib/badline/vic.rb
CHANGED
|
@@ -7,7 +7,7 @@ require "badline/vic/sequencer"
|
|
|
7
7
|
require "badline/vic/sprites"
|
|
8
8
|
|
|
9
9
|
module Badline
|
|
10
|
-
class VIC
|
|
10
|
+
class VIC
|
|
11
11
|
include Addressable
|
|
12
12
|
include IntegerHelper
|
|
13
13
|
|
|
@@ -145,7 +145,6 @@ module Badline
|
|
|
145
145
|
@render = true
|
|
146
146
|
|
|
147
147
|
power_on!
|
|
148
|
-
super()
|
|
149
148
|
end
|
|
150
149
|
|
|
151
150
|
# The VIC has no reset pin, so only a power cycle brings back the
|
|
@@ -192,7 +191,7 @@ module Badline
|
|
|
192
191
|
# a front end repaints.
|
|
193
192
|
def save_state(out)
|
|
194
193
|
out.marker("VIC")
|
|
195
|
-
out.int(@column).int(@rasterline)
|
|
194
|
+
out.int(@column).int(@rasterline)
|
|
196
195
|
out.int(@g_tick).ints(@g_kind).int(@g_kept_char).int(@g_kept_color).boolean(@g_display)
|
|
197
196
|
out.int(@fetch_d011).boolean(@lp_triggered).boolean(@lp_low).boolean(@raster_match)
|
|
198
197
|
out.int(@vic_bank.lines)
|
|
@@ -469,8 +468,10 @@ module Badline
|
|
|
469
468
|
def load_beam(input)
|
|
470
469
|
@column = input.int
|
|
471
470
|
@rasterline = @output_line = input.int
|
|
472
|
-
|
|
473
|
-
|
|
471
|
+
if input.schema < 9
|
|
472
|
+
input.int
|
|
473
|
+
input.boolean?
|
|
474
|
+
end
|
|
474
475
|
@g_tick = input.int
|
|
475
476
|
input.ints_into(@g_kind)
|
|
476
477
|
@g_kept_char = input.int
|
|
@@ -3,10 +3,12 @@
|
|
|
3
3
|
module Badline
|
|
4
4
|
class Vic20
|
|
5
5
|
# What plugs into the VIC-20 besides its chips: cartridge ROM in the
|
|
6
|
-
# expansion blocks, the disk device 8 serves through the KERNAL traps
|
|
7
|
-
# and a true 1541 or 1581 on the serial bus
|
|
6
|
+
# expansion blocks, the disk device 8 serves through the KERNAL traps
|
|
7
|
+
# (Computer::KernalTraps), and a true 1541 or 1581 on the serial bus
|
|
8
|
+
# (Computer::TrueDrives).
|
|
8
9
|
module Attachments
|
|
9
|
-
include
|
|
10
|
+
include Computer::TrueDrives
|
|
11
|
+
include Computer::KernalTraps
|
|
10
12
|
|
|
11
13
|
# The cycle by which a 1541 switched on with the machine has run its
|
|
12
14
|
# DOS's reset, the RAM test and the ROM checksum, and waits on the
|
|
@@ -27,90 +29,18 @@ module Badline
|
|
|
27
29
|
power_cycle!
|
|
28
30
|
end
|
|
29
31
|
|
|
30
|
-
|
|
31
|
-
# point while the machine runs: the drive keeps its RAM and its
|
|
32
|
-
# status.
|
|
33
|
-
def mount(storage)
|
|
34
|
-
return @drive.insert(storage) if @drive
|
|
35
|
-
|
|
36
|
-
@drive = KernalTrap::Drive.new(storage)
|
|
37
|
-
layout = KernalTrap::VIC20_LAYOUT
|
|
38
|
-
load_trap = KernalTrap::Load.new(cpu:, bus:, layout:, drive: @drive)
|
|
39
|
-
cpu.install_trap(layout.load) { load_trap.call }
|
|
40
|
-
@serial_trap = KernalTrap::Serial.new(cpu:, bus:, layout:, drive: @drive, device: serial_trap_device).install
|
|
41
|
-
save_trap = @save_trap = KernalTrap::Save.new(cpu:, bus:, layout:, drive: @drive)
|
|
42
|
-
cpu.install_trap(layout.save) { save_trap.call }
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# Takes device 8's mounted storage out, and with it the LOAD, SAVE and
|
|
46
|
-
# serial traps, so the KERNAL's routines go out over the serial bus.
|
|
47
|
-
# Mounting again starts a new drive, with its RAM cleared.
|
|
48
|
-
def unmount
|
|
49
|
-
return unless @drive
|
|
32
|
+
private
|
|
50
33
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
@serial_trap.uninstall
|
|
54
|
-
@serial_trap = nil
|
|
55
|
-
@save_trap = nil
|
|
56
|
-
@drive = nil
|
|
57
|
-
end
|
|
34
|
+
# The VIC-20's KERNAL, which the traps stand in for.
|
|
35
|
+
def trap_layout = KernalTrap::VIC20_LAYOUT
|
|
58
36
|
|
|
59
|
-
|
|
60
|
-
def mounted? = !@drive.nil?
|
|
37
|
+
def trap_bus = @bus
|
|
61
38
|
|
|
62
|
-
# Plugs in a Drive1541, which then runs alongside the VIC-20 on its own
|
|
63
|
-
# clock and talks to it over the serial bus. The serial traps stop
|
|
64
|
-
# answering the drive's device number, so the KERNAL's TALK, LISTEN
|
|
65
|
-
# and byte transfers reach the drive. The LOAD and SAVE traps stay,
|
|
66
|
-
# and still serve a mounted image.
|
|
67
|
-
#
|
|
68
39
|
# A drive that powers on with the machine takes longer to boot than
|
|
69
40
|
# the KERNAL, and doesn't answer the bus until it has, so the
|
|
70
41
|
# machine's on_init handlers wait for it too.
|
|
71
|
-
def
|
|
42
|
+
def drive1541_attached
|
|
72
43
|
@init_threshold = [@init_threshold, DRIVE_BOOT_CYCLES].max if @cycles < @init_threshold
|
|
73
|
-
@iec_bus.detach(@drive1541) if @drive1541
|
|
74
|
-
drive.host_clock_hz = timing.clock_hz
|
|
75
|
-
@drive1541 = drive
|
|
76
|
-
drive.connect(@iec_bus)
|
|
77
|
-
@serial_trap&.device = serial_trap_device
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
# The true drive on the serial bus: the Drive1581 ahead of the
|
|
81
|
-
# Drive1541, or nil.
|
|
82
|
-
def true_drive = @drive1581 || @drive1541
|
|
83
|
-
|
|
84
|
-
# Plugs a Drive1541 in as device 8, in place of a 1581 there, and
|
|
85
|
-
# returns it.
|
|
86
|
-
def plug_true_drive
|
|
87
|
-
detach_drive1581 if drive1581_on_device8?
|
|
88
|
-
Drive1541.new.tap { |drive| attach_drive1541(drive) }
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
# Unplugs the Drive1541, leaving the serial bus with nothing on it.
|
|
92
|
-
def detach_drive1541
|
|
93
|
-
return unless @drive1541
|
|
94
|
-
|
|
95
|
-
@iec_bus.detach(@drive1541)
|
|
96
|
-
@drive1541 = nil
|
|
97
|
-
@serial_trap&.device = serial_trap_device
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
# Records what the KERNAL prints through CHROUT (ChroutTrap).
|
|
101
|
-
def capture_output
|
|
102
|
-
@capture_output ||= ChroutTrap.new(cpu:, bus:, layout: KernalTrap::VIC20_LAYOUT).tap do |trap|
|
|
103
|
-
cpu.install_trap(ChroutTrap::ADDRESS) { trap.call }
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
private
|
|
108
|
-
|
|
109
|
-
# The device number the serial traps answer: device 8, unless a true
|
|
110
|
-
# drive is on the bus as device 8.
|
|
111
|
-
def serial_trap_device
|
|
112
|
-
device = KernalTrap::Routine::DEVICE
|
|
113
|
-
@drive1541&.device == device || drive1581_on_device8? ? nil : device
|
|
114
44
|
end
|
|
115
45
|
|
|
116
46
|
# A 1581 plugged in, as a 1541 does, holds the machine's on_init
|
|
@@ -105,27 +105,6 @@ module Badline
|
|
|
105
105
|
|
|
106
106
|
private
|
|
107
107
|
|
|
108
|
-
# The disk device 8 serves through the traps, with its channels.
|
|
109
|
-
def save_trap_drive(out)
|
|
110
|
-
out.boolean(!@drive.nil?)
|
|
111
|
-
return unless @drive
|
|
112
|
-
|
|
113
|
-
@drive.save_state(out)
|
|
114
|
-
@serial_trap.save_state(out)
|
|
115
|
-
@save_trap.save_state(out)
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def load_trap_drive(input)
|
|
119
|
-
return unmount unless input.boolean?
|
|
120
|
-
|
|
121
|
-
storage = Storage.reopen(input)
|
|
122
|
-
unmount
|
|
123
|
-
mount(storage)
|
|
124
|
-
@drive.load_state(input)
|
|
125
|
-
@serial_trap.load_state(input)
|
|
126
|
-
@save_trap.load_state(input)
|
|
127
|
-
end
|
|
128
|
-
|
|
129
108
|
# A true 1541 on the serial bus, with its device number.
|
|
130
109
|
def save_drive1541(out)
|
|
131
110
|
out.boolean(!@drive1541.nil?)
|
|
@@ -135,15 +114,6 @@ module Badline
|
|
|
135
114
|
@drive1541.save_state(out)
|
|
136
115
|
end
|
|
137
116
|
|
|
138
|
-
def load_drive1541(input)
|
|
139
|
-
return detach_drive1541 unless input.boolean?
|
|
140
|
-
|
|
141
|
-
device = input.int
|
|
142
|
-
detach_drive1541 if @drive1541 && @drive1541.device != device
|
|
143
|
-
attach_drive1541(Drive1541.new(device:)) unless @drive1541
|
|
144
|
-
@drive1541.load_state(input)
|
|
145
|
-
end
|
|
146
|
-
|
|
147
117
|
def check_ram(ram)
|
|
148
118
|
return if ram == @ram_configuration
|
|
149
119
|
|
data/lib/badline/vic20.rb
CHANGED
|
@@ -23,6 +23,7 @@ module Badline
|
|
|
23
23
|
class Vic20
|
|
24
24
|
include IntegerHelper
|
|
25
25
|
include KeyboardBuffer
|
|
26
|
+
include Machine::Clocking
|
|
26
27
|
include Attachments
|
|
27
28
|
include PortWiring
|
|
28
29
|
include SavedState
|
|
@@ -33,10 +34,6 @@ module Badline
|
|
|
33
34
|
# The RAM expansion it was built with, a key of Bus::RAM_CONFIGURATIONS.
|
|
34
35
|
attr_reader :ram_configuration
|
|
35
36
|
|
|
36
|
-
# The path of the disk or directory device 8 serves through the traps
|
|
37
|
-
# (Attachments), or an empty one.
|
|
38
|
-
def mounted_path = @drive.nil? ? "" : @drive.path
|
|
39
|
-
|
|
40
37
|
def ram = @bus.ram
|
|
41
38
|
|
|
42
39
|
def family = :vic20
|
|
@@ -100,31 +97,6 @@ module Badline
|
|
|
100
97
|
@cycles += 1
|
|
101
98
|
end
|
|
102
99
|
|
|
103
|
-
# Runs `count` cycles, one #cycle! after another.
|
|
104
|
-
def run_cycles(count)
|
|
105
|
-
i = 0
|
|
106
|
-
while i < count
|
|
107
|
-
cycle!
|
|
108
|
-
i += 1
|
|
109
|
-
end
|
|
110
|
-
end
|
|
111
|
-
|
|
112
|
-
# Runs cycles until the block returns true or the cycle count passes
|
|
113
|
-
# `limit`, checking before each cycle.
|
|
114
|
-
def run_until(limit)
|
|
115
|
-
cycle! until yield || @cycles > limit
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
# Runs the block once the KERNAL has booted (see init_threshold), or
|
|
119
|
-
# now if it has.
|
|
120
|
-
def on_init(&block)
|
|
121
|
-
if @cycles < @init_threshold
|
|
122
|
-
@init_handlers << block
|
|
123
|
-
else
|
|
124
|
-
block.call
|
|
125
|
-
end
|
|
126
|
-
end
|
|
127
|
-
|
|
128
100
|
# The chip whose #display a front end shows.
|
|
129
101
|
def video = @vic
|
|
130
102
|
|
|
@@ -192,10 +164,6 @@ module Badline
|
|
|
192
164
|
reset!
|
|
193
165
|
end
|
|
194
166
|
|
|
195
|
-
def inspect
|
|
196
|
-
"#<#{self.class.name} cycles=#{@cycles} cpu=(#{@cpu.inspect})>"
|
|
197
|
-
end
|
|
198
|
-
|
|
199
167
|
private
|
|
200
168
|
|
|
201
169
|
# The cycle by which the KERNAL has booted and BASIC printed READY,
|
|
@@ -215,9 +183,5 @@ module Badline
|
|
|
215
183
|
@cpu.nmi = true if nmi && !@nmi_asserted
|
|
216
184
|
@nmi_asserted = nmi
|
|
217
185
|
end
|
|
218
|
-
|
|
219
|
-
def handle_init
|
|
220
|
-
@init_handlers.each(&:call)
|
|
221
|
-
end
|
|
222
186
|
end
|
|
223
187
|
end
|