badline 0.13.0 → 0.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +72 -1
- data/CLAUDE.md +42 -12
- data/CONTRIBUTING.md +4 -3
- data/README.md +76 -13
- data/doc/media.md +2 -1
- data/doc/pinned-behaviour.md +174 -0
- data/doc/snapshot-format.md +1197 -0
- data/doc/snapshots.md +90 -40
- data/lib/badline/audio/bare_player.rb +46 -17
- data/lib/badline/audio/machine_player.rb +6 -10
- data/lib/badline/audio/renderer.rb +32 -21
- data/lib/badline/c128/banks.rb +7 -6
- data/lib/badline/c128/bus/keyed_state.rb +45 -0
- data/lib/badline/c128/bus.rb +36 -4
- data/lib/badline/c128/drives.rb +6 -25
- data/lib/badline/c128/keyed_modules.rb +117 -0
- data/lib/badline/c128/keyed_state.rb +91 -0
- data/lib/badline/c128/keys.rb +9 -0
- data/lib/badline/c128/mmu.rb +9 -8
- data/lib/badline/c128/mmu_pages.rb +27 -0
- data/lib/badline/c128/modes.rb +19 -9
- data/lib/badline/c128/z80_turns.rb +1 -1
- data/lib/badline/c128.rb +8 -8
- data/lib/badline/c64/attachments.rb +0 -44
- data/lib/badline/c64/banked_ram/plus256k.rb +18 -10
- data/lib/badline/c64/banked_ram/plus60k.rb +8 -6
- data/lib/badline/c64/banked_ram/unexpanded.rb +2 -2
- data/lib/badline/c64/bus/debug_register.rb +32 -0
- data/lib/badline/c64/bus/extra_sids.rb +80 -0
- data/lib/badline/c64/bus/keyed_state.rb +41 -0
- data/lib/badline/c64/bus.rb +3 -1
- data/lib/badline/c64/cartridge/action_replay.rb +6 -15
- data/lib/badline/c64/cartridge/comal80.rb +1 -0
- data/lib/badline/c64/cartridge/dinamic.rb +3 -1
- data/lib/badline/c64/cartridge/easy_flash.rb +0 -15
- data/lib/badline/c64/cartridge/epyx_fastload.rb +0 -8
- data/lib/badline/c64/cartridge/final_cartridge3.rb +1 -12
- data/lib/badline/c64/cartridge/flash.rb +3 -3
- data/lib/badline/c64/cartridge/fun_play.rb +2 -1
- data/lib/badline/c64/cartridge/g_mod2.rb +0 -12
- data/lib/badline/c64/cartridge/game_system.rb +2 -1
- data/lib/badline/c64/cartridge/geo_ram.rb +0 -16
- data/lib/badline/c64/cartridge/kcs_power.rb +0 -8
- data/lib/badline/c64/cartridge/keyed_state.rb +514 -0
- data/lib/badline/c64/cartridge/magic_desk.rb +2 -1
- data/lib/badline/c64/cartridge/ocean.rb +1 -0
- data/lib/badline/c64/cartridge/pagefox.rb +1 -10
- data/lib/badline/c64/cartridge/retro_replay.rb +0 -8
- data/lib/badline/c64/cartridge/rgcd.rb +2 -11
- data/lib/badline/c64/cartridge/super_games.rb +3 -12
- data/lib/badline/c64/cartridge/zaxxon.rb +1 -16
- data/lib/badline/c64/cartridge.rb +4 -30
- data/lib/badline/c64/kernal_traps.rb +28 -25
- data/lib/badline/c64/keyed_modules.rb +115 -0
- data/lib/badline/c64/keyed_state.rb +68 -0
- data/lib/badline/c64/reu/dma.rb +0 -4
- data/lib/badline/c64/reu/keyed_state.rb +140 -0
- data/lib/badline/c64/reu/ram.rb +0 -15
- data/lib/badline/c64/reu.rb +1 -3
- data/lib/badline/c64/true_drives.rb +56 -5
- data/lib/badline/c64.rb +7 -3
- data/lib/badline/chips/cia/interrupt_register.rb +0 -17
- data/lib/badline/chips/cia/keyed_parts.rb +213 -0
- data/lib/badline/chips/cia/serial.rb +0 -4
- data/lib/badline/chips/cia/time_of_day.rb +0 -22
- data/lib/badline/chips/cia/timer.rb +0 -20
- data/lib/badline/chips/cia.rb +2 -2
- data/lib/badline/chips/cpu/core.rb +18 -2
- data/lib/badline/chips/cpu/keyed_state.rb +177 -0
- data/lib/badline/chips/cpu/microcode.rb +16 -0
- data/lib/badline/chips/cpu/port.rb +20 -3
- data/lib/badline/chips/cpu.rb +5 -0
- data/lib/badline/chips/sid/decimator.rb +10 -8
- data/lib/badline/chips/sid/envelope.rb +1 -6
- data/lib/badline/chips/sid/filter.rb +0 -14
- data/lib/badline/chips/sid/keyed_parts.rb +286 -0
- data/lib/badline/chips/sid/voice.rb +0 -10
- data/lib/badline/chips/sid/waveform.rb +0 -2
- data/lib/badline/chips/sid.rb +1 -2
- data/lib/badline/chips/ted/beam.rb +118 -0
- data/lib/badline/chips/ted/fetches.rb +199 -0
- data/lib/badline/chips/ted/keyed_state.rb +156 -0
- data/lib/badline/chips/ted/modes.rb +134 -0
- data/lib/badline/chips/ted/palette.rb +43 -0
- data/lib/badline/chips/ted/picture.rb +182 -0
- data/lib/badline/chips/ted/sound/output.rb +86 -0
- data/lib/badline/chips/ted/sound.rb +284 -0
- data/lib/badline/chips/ted/timers.rb +66 -0
- data/lib/badline/chips/ted.rb +190 -0
- data/lib/badline/chips/tia.rb +61 -0
- data/lib/badline/chips/vdc/keyed_parts.rb +105 -0
- data/lib/badline/chips/vdc/painter.rb +0 -12
- data/lib/badline/chips/vdc/raster.rb +0 -16
- data/lib/badline/chips/vdc/window.rb +0 -9
- data/lib/badline/chips/vdc.rb +1 -2
- data/lib/badline/chips/via/control_lines.rb +0 -15
- data/lib/badline/chips/via/interrupt_register.rb +0 -9
- data/lib/badline/chips/via/keyed_parts.rb +163 -0
- data/lib/badline/chips/via/shift_register.rb +0 -14
- data/lib/badline/chips/via/timer1.rb +0 -13
- data/lib/badline/chips/via/timer2.rb +0 -18
- data/lib/badline/chips/via.rb +1 -2
- data/lib/badline/chips/vic/border_mask.rb +0 -10
- data/lib/badline/chips/vic/collisions.rb +0 -11
- data/lib/badline/chips/vic/color_patches.rb +0 -11
- data/lib/badline/chips/vic/display_state.rb +0 -19
- data/lib/badline/chips/vic/graphics_shifter.rb +0 -4
- data/lib/badline/chips/vic/keyed_parts.rb +228 -0
- data/lib/badline/chips/vic/keyed_sprites.rb +225 -0
- data/lib/badline/chips/vic/keyed_state.rb +102 -0
- data/lib/badline/chips/vic/register_log.rb +0 -18
- data/lib/badline/chips/vic/registers.rb +0 -9
- data/lib/badline/chips/vic/sequencer.rb +0 -2
- data/lib/badline/chips/vic/sprite/internal_bus.rb +0 -11
- data/lib/badline/chips/vic/sprite.rb +0 -2
- data/lib/badline/chips/vic/sprites.rb +0 -3
- data/lib/badline/chips/vic.rb +6 -2
- data/lib/badline/chips/vic_i/keyed_parts.rb +142 -0
- data/lib/badline/chips/vic_i/painter.rb +0 -4
- data/lib/badline/chips/vic_i/sound.rb +38 -46
- data/lib/badline/chips/vic_i.rb +2 -2
- data/lib/badline/chips/z80/core.rb +2 -2
- data/lib/badline/chips/z80/keyed_state.rb +73 -0
- data/lib/badline/chips.rb +10 -0
- data/lib/badline/core.rb +4 -21
- data/lib/badline/drives/datasette/keyed_state.rb +43 -0
- data/lib/badline/drives/datasette.rb +62 -12
- data/lib/badline/drives/engine/core.rb +3 -0
- data/lib/badline/drives/engine/serial_lines.rb +4 -7
- data/lib/badline/drives/model1541/bus.rb +0 -13
- data/lib/badline/drives/model1541/disk.rb +9 -8
- data/lib/badline/drives/model1541/keyed_state.rb +251 -0
- data/lib/badline/drives/model1541/mechanism.rb +0 -2
- data/lib/badline/drives/model1541.rb +1 -2
- data/lib/badline/drives/model1571/bus.rb +0 -13
- data/lib/badline/drives/model1571/keyed_state.rb +108 -0
- data/lib/badline/drives/model1571/wd1770.rb +0 -14
- data/lib/badline/drives/model1571.rb +1 -2
- data/lib/badline/drives/model1581/bus.rb +0 -13
- data/lib/badline/drives/model1581/disk.rb +0 -4
- data/lib/badline/drives/model1581/keyed_state.rb +280 -0
- data/lib/badline/drives/model1581/mechanism.rb +0 -21
- data/lib/badline/drives/model1581/slot.rb +0 -18
- data/lib/badline/drives/model1581/wd1772.rb +0 -2
- data/lib/badline/drives/model1581.rb +2 -2
- data/lib/badline/drives.rb +8 -0
- data/lib/badline/frontend/app.rb +3 -3
- data/lib/badline/frontend/boot.rb +4 -2
- data/lib/badline/frontend/controls.rb +25 -5
- data/lib/badline/frontend/drive_led.rb +44 -21
- data/lib/badline/frontend/keys.rb +14 -2
- data/lib/badline/frontend/media_slots.rb +11 -1
- data/lib/badline/frontend/menu/menu_dialogs.rb +4 -3
- data/lib/badline/frontend/menu/menu_media.rb +13 -3
- data/lib/badline/frontend/menu/menu_pages.rb +8 -8
- data/lib/badline/frontend/menu/menu_ports.rb +13 -1
- data/lib/badline/frontend/screen.rb +33 -12
- data/lib/badline/frontend/screens.rb +2 -1
- data/lib/badline/frontend/snapshots.rb +12 -1
- data/lib/badline/frontend/sound.rb +4 -4
- data/lib/badline/frontend/timeline.rb +43 -12
- data/lib/badline/input/matrix_typist.rb +98 -0
- data/lib/badline/input.rb +1 -0
- data/lib/badline/kernal_trap/chrout.rb +45 -0
- data/lib/badline/kernal_trap/dos/channel.rb +0 -27
- data/lib/badline/kernal_trap/dos/channels.rb +0 -25
- data/lib/badline/kernal_trap/dos/memory.rb +0 -9
- data/lib/badline/kernal_trap/dos/status.rb +0 -8
- data/lib/badline/kernal_trap/dos/write_file.rb +0 -18
- data/lib/badline/kernal_trap/dos.rb +0 -19
- data/lib/badline/kernal_trap/file_routine.rb +4 -4
- data/lib/badline/kernal_trap/keyed_state.rb +150 -0
- data/lib/badline/kernal_trap/layout.rb +75 -11
- data/lib/badline/kernal_trap/load.rb +14 -16
- data/lib/badline/kernal_trap/routine.rb +12 -0
- data/lib/badline/kernal_trap/save.rb +8 -18
- data/lib/badline/kernal_trap/serial.rb +1 -17
- data/lib/badline/kernal_trap.rb +2 -0
- data/lib/badline/machine/keyboard_buffer.rb +49 -0
- data/lib/badline/machine/settling.rb +29 -0
- data/lib/badline/machine.rb +29 -6
- data/lib/badline/media/boot_disk.rb +14 -2
- data/lib/badline/media/extensions.rb +10 -0
- data/lib/badline/media/plus4_media.rb +68 -0
- data/lib/badline/media/program.rb +20 -6
- data/lib/badline/media.rb +33 -12
- data/lib/badline/memory.rb +3 -6
- data/lib/badline/options/family.rb +6 -2
- data/lib/badline/options/help.rb +66 -16
- data/lib/badline/options/table.rb +17 -2
- data/lib/badline/options/validation.rb +26 -2
- data/lib/badline/options.rb +42 -9
- data/lib/badline/plus4/acia.rb +45 -0
- data/lib/badline/plus4/bus.rb +375 -0
- data/lib/badline/plus4/cassette_sense.rb +21 -0
- data/lib/badline/plus4/cpu.rb +10 -0
- data/lib/badline/plus4/cpu_port.rb +93 -0
- data/lib/badline/plus4/keyboard_port.rb +76 -0
- data/lib/badline/plus4/keyed_modules.rb +99 -0
- data/lib/badline/plus4/keyed_parts.rb +143 -0
- data/lib/badline/plus4/keyed_state.rb +41 -0
- data/lib/badline/plus4/model.rb +38 -0
- data/lib/badline/plus4/user_port.rb +31 -0
- data/lib/badline/plus4.rb +240 -0
- data/lib/badline/roms/README +38 -0
- data/lib/badline/roms/plus4/basic.rom +0 -0
- data/lib/badline/roms/plus4/function-high.rom +0 -0
- data/lib/badline/roms/plus4/function-low.rom +0 -0
- data/lib/badline/roms/plus4/kernal-ntsc.rom +0 -0
- data/lib/badline/roms/plus4/kernal-pal.rom +0 -0
- data/lib/badline/snapshot/c128_setup.rb +9 -20
- data/lib/badline/snapshot/c64_setup.rb +28 -24
- data/lib/badline/snapshot/container.rb +6 -0
- data/lib/badline/snapshot/field_doc/markdown.rb +113 -0
- data/lib/badline/snapshot/field_doc.rb +148 -0
- data/lib/badline/snapshot/image.rb +143 -28
- data/lib/badline/snapshot/keyed/cursor.rb +40 -0
- data/lib/badline/snapshot/keyed/modules.rb +66 -0
- data/lib/badline/snapshot/keyed/reader.rb +188 -0
- data/lib/badline/snapshot/keyed/recorder.rb +88 -0
- data/lib/badline/snapshot/keyed/report.rb +26 -0
- data/lib/badline/snapshot/keyed/writer.rb +55 -0
- data/lib/badline/snapshot/keyed.rb +64 -0
- data/lib/badline/snapshot/machine_state.rb +17 -64
- data/lib/badline/snapshot/plus4_setup.rb +39 -0
- data/lib/badline/snapshot/storage_setup.rb +29 -34
- data/lib/badline/snapshot/vic20_setup.rb +6 -15
- data/lib/badline/snapshot/vice/reu1764.rb +2 -2
- data/lib/badline/snapshot/vice.rb +7 -31
- data/lib/badline/snapshot.rb +48 -20
- data/lib/badline/storage/crt_file.rb +3 -1
- data/lib/badline/storage/g64_image.rb +9 -4
- data/lib/badline/storage/tap.rb +57 -20
- data/lib/badline/support/checkpoint.rb +3 -2
- data/lib/badline/support/plus4_checkpoint.rb +42 -0
- data/lib/badline/version.rb +1 -1
- data/lib/badline/vic20/attachments.rb +3 -0
- data/lib/badline/vic20/bus/keyed_state.rb +52 -0
- data/lib/badline/vic20/bus.rb +1 -2
- data/lib/badline/vic20/keyed_modules.rb +73 -0
- data/lib/badline/vic20/keyed_state.rb +45 -0
- data/lib/badline/vic20.rb +5 -5
- data/lib/badline.rb +1 -0
- metadata +75 -42
- data/lib/badline/c128/bus/saved_state.rb +0 -53
- data/lib/badline/c128/saved_state.rb +0 -117
- data/lib/badline/c64/bus/saved_state.rb +0 -68
- data/lib/badline/c64/cartridge/flash/saved_state.rb +0 -40
- data/lib/badline/c64/cartridge/retro_replay/saved_state.rb +0 -47
- data/lib/badline/c64/cartridge/saved_state.rb +0 -63
- data/lib/badline/c64/reu/dma/saved_state.rb +0 -52
- data/lib/badline/c64/reu/saved_state.rb +0 -55
- data/lib/badline/c64/saved_state.rb +0 -112
- data/lib/badline/chips/cia/saved_state.rb +0 -49
- data/lib/badline/chips/cia/serial/saved_state.rb +0 -45
- data/lib/badline/chips/cpu/saved_state.rb +0 -117
- data/lib/badline/chips/sid/envelope/saved_state.rb +0 -70
- data/lib/badline/chips/sid/filter/saved_state.rb +0 -42
- data/lib/badline/chips/sid/saved_state.rb +0 -52
- data/lib/badline/chips/sid/waveform/saved_state.rb +0 -68
- data/lib/badline/chips/vdc/saved_state.rb +0 -36
- data/lib/badline/chips/via/saved_state.rb +0 -44
- data/lib/badline/chips/vic/graphics_shifter/saved_state.rb +0 -40
- data/lib/badline/chips/vic/saved_state.rb +0 -82
- data/lib/badline/chips/vic/sequencer/saved_state.rb +0 -91
- data/lib/badline/chips/vic/sprite/saved_state.rb +0 -66
- data/lib/badline/chips/vic/sprites/saved_state.rb +0 -59
- data/lib/badline/chips/vic_i/painter/saved_state.rb +0 -40
- data/lib/badline/chips/vic_i/saved_state.rb +0 -55
- data/lib/badline/chips/z80/saved_state.rb +0 -71
- data/lib/badline/chrout_trap.rb +0 -43
- data/lib/badline/debug_register.rb +0 -28
- data/lib/badline/drives/datasette/saved_state.rb +0 -37
- data/lib/badline/drives/model1541/disk/saved_state.rb +0 -88
- data/lib/badline/drives/model1541/mechanism/saved_state.rb +0 -72
- data/lib/badline/drives/model1541/saved_state.rb +0 -44
- data/lib/badline/drives/model1571/saved_state.rb +0 -47
- data/lib/badline/drives/model1581/disk/saved_state.rb +0 -89
- data/lib/badline/drives/model1581/saved_state.rb +0 -42
- data/lib/badline/drives/model1581/wd1772/saved_state.rb +0 -68
- data/lib/badline/keyboard_buffer.rb +0 -33
- data/lib/badline/snapshot/setup.rb +0 -31
- data/lib/badline/snapshot/state.rb +0 -179
- data/lib/badline/vic20/bus/saved_state.rb +0 -35
- data/lib/badline/vic20/saved_state.rb +0 -110
|
@@ -38,14 +38,11 @@ module Badline
|
|
|
38
38
|
@host = @bus.host_lines
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
# The host's lines as
|
|
42
|
-
|
|
43
|
-
def save_state(out)
|
|
44
|
-
out.int(@host)
|
|
45
|
-
end
|
|
41
|
+
# The host's lines as the port latched them, under `prefix`.
|
|
42
|
+
def save_fields(out, prefix) = out.int("#{prefix}host", @host)
|
|
46
43
|
|
|
47
|
-
def
|
|
48
|
-
@host = input.int
|
|
44
|
+
def load_fields(input, prefix)
|
|
45
|
+
@host = input.int("#{prefix}host", @host)
|
|
49
46
|
end
|
|
50
47
|
|
|
51
48
|
# Whether the host has moved ATN since the last latch_host.
|
|
@@ -38,19 +38,6 @@ module Badline
|
|
|
38
38
|
init_watch
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
-
# The last byte on the data bus and the RAM. What a watched stretch
|
|
42
|
-
# touched is Idle's, and a restored bus isn't watching.
|
|
43
|
-
def save_state(out)
|
|
44
|
-
out.int(@data)
|
|
45
|
-
@ram.save_state(out)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def load_state(input)
|
|
49
|
-
@data = input.int
|
|
50
|
-
@ram.load_state(input)
|
|
51
|
-
@watching = false
|
|
52
|
-
end
|
|
53
|
-
|
|
54
41
|
def peek(addr)
|
|
55
42
|
return @data = @rom.peek(addr | 0x4000) if addr >= 0x8000
|
|
56
43
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "badline/media/extensions"
|
|
3
4
|
require "badline/drives/model1541/sector_reader"
|
|
4
|
-
require "badline/drives/model1541/disk/saved_state"
|
|
5
5
|
|
|
6
6
|
module Badline
|
|
7
7
|
module Drives
|
|
@@ -23,7 +23,8 @@ module Badline
|
|
|
23
23
|
# host file. The disk is write-protected when the image won't take
|
|
24
24
|
# writes.
|
|
25
25
|
class Disk
|
|
26
|
-
|
|
26
|
+
# Whether the image is a .g64 or .g71, by its name.
|
|
27
|
+
def self.g64?(path) = Media::Extensions.kind(path) == :gcr
|
|
27
28
|
|
|
28
29
|
MAX_HALF_TRACK = 84
|
|
29
30
|
|
|
@@ -61,16 +62,16 @@ module Badline
|
|
|
61
62
|
# formatted. `read_only` opens the image write-protected.
|
|
62
63
|
def self.open(path, read_only: false)
|
|
63
64
|
image = image_for(path, read_only)
|
|
64
|
-
(
|
|
65
|
+
(Disk.g64?(path) ? from_g64(image) : from_d64(image)).opened(path, read_only)
|
|
65
66
|
end
|
|
66
67
|
|
|
67
68
|
# The image at +path+, by its name: a .g64 or .g71, a .d71, and
|
|
68
|
-
# anything else a .d64.
|
|
69
|
-
def self.image_for(path, read_only)
|
|
70
|
-
return Storage::G64Image.new(path, read_only:) if
|
|
71
|
-
return Storage::D71Image.new(path, read_only:) if File.extname(path).casecmp?(".d71")
|
|
69
|
+
# anything else a .d64. `bytes` stands in for the file's contents.
|
|
70
|
+
def self.image_for(path, read_only, bytes = nil)
|
|
71
|
+
return Storage::G64Image.new(path, read_only:, bytes:) if Disk.g64?(path)
|
|
72
|
+
return Storage::D71Image.new(path, read_only:, bytes:) if File.extname(path).casecmp?(".d71")
|
|
72
73
|
|
|
73
|
-
Storage::D64Image.new(path, read_only:)
|
|
74
|
+
Storage::D64Image.new(path, read_only:, bytes:)
|
|
74
75
|
end
|
|
75
76
|
|
|
76
77
|
# A disk from a G64 or G71 image, each half track as the image stores
|
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Drives
|
|
5
|
+
class Model1541
|
|
6
|
+
class Disk
|
|
7
|
+
# The kinds of image a disk embeds, by name.
|
|
8
|
+
IMAGE_KINDS = %w[none d64 d71 g64].freeze
|
|
9
|
+
|
|
10
|
+
# A disk's fields in a keyed snapshot module (BL-D8-DISK): the image
|
|
11
|
+
# file's path and how it was opened, the image as last flushed,
|
|
12
|
+
# embedded under image and image.kind, each half track that differs
|
|
13
|
+
# from what the image decodes to, as track<H>.zone, track<H>.speeds
|
|
14
|
+
# and track<H>.gcr, raw GCR as the head sees it, and the half tracks
|
|
15
|
+
# written since the last flush.
|
|
16
|
+
module KeyedState
|
|
17
|
+
# The image's path, expanded, and whether it was opened read-only,
|
|
18
|
+
# for a disk from Disk.open. Nil for a disk made another way.
|
|
19
|
+
attr_reader :path, :read_only
|
|
20
|
+
|
|
21
|
+
# Notes the image's path and how it was opened.
|
|
22
|
+
def opened(path, read_only)
|
|
23
|
+
@path = File.expand_path(path)
|
|
24
|
+
@read_only = read_only
|
|
25
|
+
self
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def save_fields(out)
|
|
29
|
+
path = @path
|
|
30
|
+
out.text("path", path) if path
|
|
31
|
+
out.bool("read_only", @read_only == true)
|
|
32
|
+
image = @image
|
|
33
|
+
decoded = nil
|
|
34
|
+
if image
|
|
35
|
+
out.text("image.kind", Disk.image_kind(image)).text("image.path", image.path.to_s)
|
|
36
|
+
out.bytes("image", image.contents)
|
|
37
|
+
decoded = Disk.decode(image)
|
|
38
|
+
end
|
|
39
|
+
@tracks.each_with_index { |track, half| save_track_fields(out, half, track, decoded) }
|
|
40
|
+
out.ints("written", @written.keys)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def load_track_fields(input)
|
|
44
|
+
@tracks.each_index do |half|
|
|
45
|
+
zone = input.optional_int("track#{half}.zone")
|
|
46
|
+
next if zone.nil?
|
|
47
|
+
|
|
48
|
+
speeds = input.ints("track#{half}.speeds", [])
|
|
49
|
+
gcr = input.bytes("track#{half}.gcr", "".b).bytes
|
|
50
|
+
@tracks[half] = Track.new(gcr, zone, speeds.empty? ? nil : speeds.dup)
|
|
51
|
+
end
|
|
52
|
+
@written.clear
|
|
53
|
+
input.ints("written", []).each { |half| @written[half] = true }
|
|
54
|
+
self
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
def save_track_fields(out, half, track, decoded)
|
|
60
|
+
return if track.nil?
|
|
61
|
+
|
|
62
|
+
original = decoded&.track(half)
|
|
63
|
+
return if original && original.zone == track.zone && original.speeds == track.speeds &&
|
|
64
|
+
original.bytes == track.bytes
|
|
65
|
+
|
|
66
|
+
out.int("track#{half}.zone", track.zone)
|
|
67
|
+
speeds = track.speeds
|
|
68
|
+
out.ints("track#{half}.speeds", speeds) if speeds
|
|
69
|
+
out.bytes("track#{half}.gcr", track.bytes)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
include KeyedState
|
|
74
|
+
|
|
75
|
+
# The kind of `image`, by name.
|
|
76
|
+
def self.image_kind(image)
|
|
77
|
+
return "g64" if image.is_a?(Storage::G64Image)
|
|
78
|
+
return "d71" if image.is_a?(Storage::D71Image)
|
|
79
|
+
|
|
80
|
+
"d64"
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# The tracks `image` holds, as an insert decodes them.
|
|
84
|
+
def self.decode(image) = image.is_a?(Storage::G64Image) ? from_g64(image) : from_d64(image)
|
|
85
|
+
|
|
86
|
+
# The disk a keyed snapshot module describes: its embedded image
|
|
87
|
+
# decoded, with the tracks the module holds laid over it. The image
|
|
88
|
+
# takes writes back to its file only while that file is there and
|
|
89
|
+
# the reader isn't `detached`. With no image, the disk is the
|
|
90
|
+
# tracks alone, write-protected.
|
|
91
|
+
def self.from_fields(input, detached: false)
|
|
92
|
+
path = input.text("path", "")
|
|
93
|
+
read_only = input.bool("read_only", false)
|
|
94
|
+
kind = input.choice("image.kind", IMAGE_KINDS, "none")
|
|
95
|
+
image_path = input.text("image.path", "")
|
|
96
|
+
disk = kind == "none" ? Disk.new : from_image(input, kind, image_path, read_only || detached)
|
|
97
|
+
disk.opened(path, read_only || kind == "none") unless path.empty?
|
|
98
|
+
disk.load_track_fields(input)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def self.from_image(input, kind, path, read_only)
|
|
102
|
+
bytes = input.bytes("image", "".b).bytes
|
|
103
|
+
writable_path = path.empty? || !File.file?(path) ? "" : path
|
|
104
|
+
image = case kind
|
|
105
|
+
when "g64" then Storage::G64Image.new(writable_path, read_only:, bytes:)
|
|
106
|
+
when "d71" then Storage::D71Image.new(writable_path, read_only:, bytes:)
|
|
107
|
+
else Storage::D64Image.new(writable_path, read_only:, bytes:)
|
|
108
|
+
end
|
|
109
|
+
decode(image)
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
class Mechanism
|
|
114
|
+
# The head, the motor, the stepper and the read and write
|
|
115
|
+
# electronics in a keyed snapshot module (BL-D8-MECH): where the
|
|
116
|
+
# head is, the disk's place in its turn, the read clock's next
|
|
117
|
+
# clock in cycles from now, the shift registers and the flags. The
|
|
118
|
+
# cell under the head, its width and the next event come from the
|
|
119
|
+
# track and the time on load, the cell period from the zone, and
|
|
120
|
+
# the write protection from the disk.
|
|
121
|
+
module KeyedState
|
|
122
|
+
def save_fields(out)
|
|
123
|
+
out.int("half_track", @half_track).int("slip", @slip).int("side", @side_base).int("zone", @zone)
|
|
124
|
+
out.int("time", @time).int("read_clock_in", @clock_at - @time).int("clocks", @clocks)
|
|
125
|
+
out.int("shift", @shift).int("ones", @ones).int("bits", @bits).int("write_shift", @write_shift)
|
|
126
|
+
out.bool("motor", @motor).bool("led", @led).bool("sync", @sync).bool("byte_ready", @byte_ready)
|
|
127
|
+
out.bool("byte_latched", @byte_latched).bool("writing", @writing).bool("write_gate", @write_gate)
|
|
128
|
+
out.bool("track_written", @track_written).optional_int("write_index", @write_index)
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
# Puts `disk` under the head without flushing the one there, as a
|
|
132
|
+
# snapshot load replaces it.
|
|
133
|
+
def load_fields(input, disk)
|
|
134
|
+
@disk = disk
|
|
135
|
+
load_head_fields(input)
|
|
136
|
+
load_flag_fields(input)
|
|
137
|
+
@clock = Track.cell(@zone)
|
|
138
|
+
@protected = disk&.write_protected? || false
|
|
139
|
+
track_written = input.bool("track_written", false)
|
|
140
|
+
write_index = input.optional_int("write_index")
|
|
141
|
+
load_track(@time)
|
|
142
|
+
@track_written = track_written
|
|
143
|
+
@write_index = write_index
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
private
|
|
147
|
+
|
|
148
|
+
def load_head_fields(input)
|
|
149
|
+
@half_track = input.int("half_track", @half_track)
|
|
150
|
+
@slip = input.masked("slip", @slip, 0x03)
|
|
151
|
+
@side_base = input.int("side", @side_base)
|
|
152
|
+
@zone = input.masked("zone", @zone, 0x03)
|
|
153
|
+
@time = input.int("time", @time)
|
|
154
|
+
@clock_at = @time + input.int("read_clock_in", @clock_at - @time)
|
|
155
|
+
@clocks = input.int("clocks", @clocks)
|
|
156
|
+
@shift = input.int("shift", @shift)
|
|
157
|
+
@ones = input.int("ones", @ones)
|
|
158
|
+
@bits = input.int("bits", @bits)
|
|
159
|
+
@write_shift = input.int("write_shift", @write_shift)
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def load_flag_fields(input)
|
|
163
|
+
@motor = input.bool("motor", @motor)
|
|
164
|
+
@led = input.bool("led", @led)
|
|
165
|
+
@sync = input.bool("sync", @sync)
|
|
166
|
+
@byte_ready = input.bool("byte_ready", @byte_ready)
|
|
167
|
+
@byte_latched = input.bool("byte_latched", @byte_latched)
|
|
168
|
+
@writing = input.bool("writing", @writing)
|
|
169
|
+
@write_gate = input.bool("write_gate", @write_gate)
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
include KeyedState
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
class Bus
|
|
177
|
+
# The drive's RAM and the byte last on its data bus, in a keyed
|
|
178
|
+
# snapshot module (BL-D8-RAM).
|
|
179
|
+
def save_fields(out)
|
|
180
|
+
out.int("data", @data).bytes("ram", @ram.read(0, @ram.length))
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def load_fields(input)
|
|
184
|
+
@data = input.byte("data", @data)
|
|
185
|
+
ram = @ram.read(0, @ram.length)
|
|
186
|
+
@ram.write(0, input.bytes_into("ram", ram))
|
|
187
|
+
@watching = false
|
|
188
|
+
end
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
# The drive's own fields in a keyed snapshot module (BL-D8): its model,
|
|
192
|
+
# its clock phase and cycle count, the SO pulse due, and the host's
|
|
193
|
+
# lines as the serial port latched them. A save settles the drive first, so it is awake;
|
|
194
|
+
# a load forgets its orbits.
|
|
195
|
+
module KeyedState
|
|
196
|
+
def save_fields(out)
|
|
197
|
+
settle!
|
|
198
|
+
out.text("model", model_name).int("phase", @phase).int("cycles", @cycles)
|
|
199
|
+
out.bool("so_pending", @mechanism.so_pending)
|
|
200
|
+
@serial_port.save_fields(out, "serial.")
|
|
201
|
+
out
|
|
202
|
+
end
|
|
203
|
+
|
|
204
|
+
def load_fields(input)
|
|
205
|
+
settle!
|
|
206
|
+
input.choice("model", [model_name], model_name)
|
|
207
|
+
@phase = input.int("phase", @phase)
|
|
208
|
+
@cycles = input.int("cycles", @cycles)
|
|
209
|
+
@mechanism.so_pending = input.bool("so_pending", @mechanism.so_pending)
|
|
210
|
+
@serial_port.load_fields(input, "serial.")
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def restored! = forget_orbits
|
|
214
|
+
|
|
215
|
+
# The drive as modules of its own, named from `name` (BL-D8 for
|
|
216
|
+
# device 8): its own fields, its RAM, each VIA, the CPU, the
|
|
217
|
+
# mechanism and the disk, when one is in.
|
|
218
|
+
def save_modules(sections, name)
|
|
219
|
+
sections << Snapshot::Keyed.section(name) { |out| save_fields(out) }
|
|
220
|
+
sections << Snapshot::Keyed.section("#{name}-RAM") { |out| @bus.save_fields(out) }
|
|
221
|
+
sections << Snapshot::Keyed.section("#{name}-VIA1") { |out| @via1.save_fields(out) }
|
|
222
|
+
sections << Snapshot::Keyed.section("#{name}-VIA2") { |out| @via2.save_fields(out) }
|
|
223
|
+
sections << Snapshot::Keyed.section("#{name}-CPU") { |out| @cpu.save_fields(out) }
|
|
224
|
+
sections << Snapshot::Keyed.section("#{name}-MECH") { |out| @mechanism.save_fields(out) }
|
|
225
|
+
disk = @mechanism.disk
|
|
226
|
+
sections << Snapshot::Keyed.section("#{name}-DISK") { |out| disk.save_fields(out) } if disk
|
|
227
|
+
sections
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# The drive from its modules, `input` being its own. No disk module
|
|
231
|
+
# means no disk in the drive.
|
|
232
|
+
def load_modules(modules, input, name)
|
|
233
|
+
load_fields(input)
|
|
234
|
+
@bus.load_fields(modules.required("#{name}-RAM"))
|
|
235
|
+
@via1.load_fields(modules.required("#{name}-VIA1"))
|
|
236
|
+
@via2.load_fields(modules.required("#{name}-VIA2"))
|
|
237
|
+
@cpu.load_fields(modules.required("#{name}-CPU"))
|
|
238
|
+
disk = modules.optional("#{name}-DISK")
|
|
239
|
+
mechanism = modules.required("#{name}-MECH")
|
|
240
|
+
@mechanism.load_fields(mechanism, disk.nil? ? nil : Disk.from_fields(disk, detached: modules.detached?))
|
|
241
|
+
@via1.restored!
|
|
242
|
+
@via2.restored!
|
|
243
|
+
@cpu.restored!
|
|
244
|
+
restored!
|
|
245
|
+
end
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
include KeyedState
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
end
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "badline/drives/model1541/rotation"
|
|
4
|
-
require "badline/drives/model1541/mechanism/saved_state"
|
|
5
4
|
require "badline/drives/model1541/byte_ready"
|
|
6
5
|
|
|
7
6
|
module Badline
|
|
@@ -71,7 +70,6 @@ module Badline
|
|
|
71
70
|
# its track 0 sensor looks for the head (Mechanism.new's +slip+).
|
|
72
71
|
class Mechanism
|
|
73
72
|
include Rotation
|
|
74
|
-
include SavedState
|
|
75
73
|
include ByteReady
|
|
76
74
|
|
|
77
75
|
MOTOR = 0x04
|
|
@@ -9,7 +9,7 @@ require "badline/drives/model1541/track"
|
|
|
9
9
|
require "badline/drives/model1541/disk"
|
|
10
10
|
require "badline/drives/model1541/mechanism"
|
|
11
11
|
require "badline/drives/model1541/disk_via"
|
|
12
|
-
require "badline/drives/model1541/
|
|
12
|
+
require "badline/drives/model1541/keyed_state"
|
|
13
13
|
|
|
14
14
|
module Badline
|
|
15
15
|
module Drives
|
|
@@ -19,7 +19,6 @@ module Badline
|
|
|
19
19
|
class Model1541
|
|
20
20
|
include Engine::Core
|
|
21
21
|
include Engine::VIAs
|
|
22
|
-
include SavedState
|
|
23
22
|
|
|
24
23
|
CLOCK_HZ = 1_000_000
|
|
25
24
|
|
|
@@ -40,19 +40,6 @@ module Badline
|
|
|
40
40
|
init_watch
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
-
# The last byte on the data bus and the RAM. What a watched stretch
|
|
44
|
-
# touched is Idle's, and a restored bus isn't watching.
|
|
45
|
-
def save_state(out)
|
|
46
|
-
out.int(@data)
|
|
47
|
-
@ram.save_state(out)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def load_state(input)
|
|
51
|
-
@data = input.int
|
|
52
|
-
@ram.load_state(input)
|
|
53
|
-
@watching = false
|
|
54
|
-
end
|
|
55
|
-
|
|
56
43
|
def peek(addr)
|
|
57
44
|
return @data = @rom.peek(addr) if addr >= 0x8000
|
|
58
45
|
return @data = chip_peek(addr) if addr >= 0x2000
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Drives
|
|
5
|
+
class Model1571
|
|
6
|
+
class WD1770
|
|
7
|
+
# The controller's registers, status and result in a keyed snapshot
|
|
8
|
+
# module (BL-D8-FDC), and how many of the drive CPU's cycles until a
|
|
9
|
+
# command under way finishes. It loads after the CPU, which that
|
|
10
|
+
# counts from.
|
|
11
|
+
def save_fields(out)
|
|
12
|
+
out.ints("registers", @registers).int("status", @status).int("result", @result)
|
|
13
|
+
out.int("due_in", @due - @cpu.cycles)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def load_fields(input)
|
|
17
|
+
input.ints_into("registers", @registers)
|
|
18
|
+
@status = input.byte("status", @status)
|
|
19
|
+
@result = input.int("result", @result)
|
|
20
|
+
@due = @cpu.cycles + input.int("due_in", @due - @cpu.cycles)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class Bus
|
|
25
|
+
# The drive's RAM and the byte last on its data bus, in a keyed
|
|
26
|
+
# snapshot module (BL-D8-RAM).
|
|
27
|
+
def save_fields(out)
|
|
28
|
+
out.int("data", @data).bytes("ram", @ram.read(0, @ram.length))
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def load_fields(input)
|
|
32
|
+
@data = input.byte("data", @data)
|
|
33
|
+
ram = @ram.read(0, @ram.length)
|
|
34
|
+
@ram.write(0, input.bytes_into("ram", ram))
|
|
35
|
+
@watching = false
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# The drive's own fields in a keyed snapshot module (BL-D8), as the
|
|
40
|
+
# 1541's. The clock rate, the side and the fast serial direction come
|
|
41
|
+
# from VIA 1's port A once the VIAs are loaded.
|
|
42
|
+
module KeyedState
|
|
43
|
+
def save_fields(out)
|
|
44
|
+
settle!
|
|
45
|
+
out.text("model", model_name).int("phase", @phase).int("cycles", @cycles)
|
|
46
|
+
out.bool("so_pending", @mechanism.so_pending)
|
|
47
|
+
@serial_port.save_fields(out, "serial.")
|
|
48
|
+
out
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def load_fields(input)
|
|
52
|
+
settle!
|
|
53
|
+
input.choice("model", [model_name], model_name)
|
|
54
|
+
@phase = input.int("phase", @phase)
|
|
55
|
+
@cycles = input.int("cycles", @cycles)
|
|
56
|
+
@mechanism.so_pending = input.bool("so_pending", @mechanism.so_pending)
|
|
57
|
+
@serial_port.load_fields(input, "serial.")
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def restored!
|
|
61
|
+
@fast_serial_out = @via1.port_a_output.anybits?(FAST_SERIAL_OUT)
|
|
62
|
+
port_a_written(@via1.port_a_output)
|
|
63
|
+
push_fast_output(@fast_serial_out ? fast_pins : 0)
|
|
64
|
+
forget_orbits
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# The drive as modules of its own, as the 1541's, with the CIA and
|
|
68
|
+
# the WD1770.
|
|
69
|
+
def save_modules(sections, name)
|
|
70
|
+
sections << Snapshot::Keyed.section(name) { |out| save_fields(out) }
|
|
71
|
+
sections << Snapshot::Keyed.section("#{name}-RAM") { |out| @bus.save_fields(out) }
|
|
72
|
+
sections << Snapshot::Keyed.section("#{name}-VIA1") { |out| @via1.save_fields(out) }
|
|
73
|
+
sections << Snapshot::Keyed.section("#{name}-VIA2") { |out| @via2.save_fields(out) }
|
|
74
|
+
sections << Snapshot::Keyed.section("#{name}-CIA") { |out| @cia.save_fields(out) }
|
|
75
|
+
sections << Snapshot::Keyed.section("#{name}-CPU") { |out| @cpu.save_fields(out) }
|
|
76
|
+
sections << Snapshot::Keyed.section("#{name}-FDC") { |out| @fdc.save_fields(out) }
|
|
77
|
+
sections << Snapshot::Keyed.section("#{name}-MECH") { |out| @mechanism.save_fields(out) }
|
|
78
|
+
disk = @mechanism.disk
|
|
79
|
+
sections << Snapshot::Keyed.section("#{name}-DISK") { |out| disk.save_fields(out) } if disk
|
|
80
|
+
sections
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# The drive from its modules, `input` being its own. The WD1770
|
|
84
|
+
# counts from the CPU's cycles, so it loads after the CPU.
|
|
85
|
+
def load_modules(modules, input, name)
|
|
86
|
+
load_fields(input)
|
|
87
|
+
@bus.load_fields(modules.required("#{name}-RAM"))
|
|
88
|
+
@via1.load_fields(modules.required("#{name}-VIA1"))
|
|
89
|
+
@via2.load_fields(modules.required("#{name}-VIA2"))
|
|
90
|
+
@cia.load_fields(modules.required("#{name}-CIA"))
|
|
91
|
+
@cpu.load_fields(modules.required("#{name}-CPU"))
|
|
92
|
+
@fdc.load_fields(modules.required("#{name}-FDC"))
|
|
93
|
+
disk = modules.optional("#{name}-DISK")
|
|
94
|
+
mechanism = modules.required("#{name}-MECH")
|
|
95
|
+
@mechanism.load_fields(mechanism,
|
|
96
|
+
disk.nil? ? nil : Model1541::Disk.from_fields(disk, detached: modules.detached?))
|
|
97
|
+
@via1.restored!
|
|
98
|
+
@via2.restored!
|
|
99
|
+
@cia.restored!
|
|
100
|
+
@cpu.restored!
|
|
101
|
+
restored!
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
include KeyedState
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
@@ -54,20 +54,6 @@ module Badline
|
|
|
54
54
|
offset.zero? ? command(value) : @registers[offset] = value
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
-
def save_state(out)
|
|
58
|
-
out.ints([*@registers, @status, @due, @result])
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
# A state from before the controller ran commands holds the four
|
|
62
|
-
# registers alone.
|
|
63
|
-
def load_state(input)
|
|
64
|
-
values = input.ints
|
|
65
|
-
@registers = values[0, 4]
|
|
66
|
-
@status = values[4] || 0
|
|
67
|
-
@due = values[5] || 0
|
|
68
|
-
@result = values[6] || 0
|
|
69
|
-
end
|
|
70
|
-
|
|
71
57
|
private
|
|
72
58
|
|
|
73
59
|
def command(value)
|
|
@@ -5,7 +5,7 @@ require "badline/drives/model1571/wd1770"
|
|
|
5
5
|
require "badline/drives/model1571/serial_port"
|
|
6
6
|
require "badline/drives/model1571/serial_via"
|
|
7
7
|
require "badline/drives/model1571/bus"
|
|
8
|
-
require "badline/drives/model1571/
|
|
8
|
+
require "badline/drives/model1571/keyed_state"
|
|
9
9
|
|
|
10
10
|
module Badline
|
|
11
11
|
module Drives
|
|
@@ -28,7 +28,6 @@ module Badline
|
|
|
28
28
|
include Engine::Core
|
|
29
29
|
include Engine::VIAs
|
|
30
30
|
include Engine::FastSerial
|
|
31
|
-
include SavedState
|
|
32
31
|
|
|
33
32
|
CLOCK_HZ = 1_000_000
|
|
34
33
|
FAST_CLOCK_HZ = 2_000_000
|
|
@@ -41,19 +41,6 @@ module Badline
|
|
|
41
41
|
@touched_timers = 0
|
|
42
42
|
end
|
|
43
43
|
|
|
44
|
-
# The last byte on the data bus and the RAM. What a watched stretch
|
|
45
|
-
# touched is Idle's, and a restored bus isn't watching.
|
|
46
|
-
def save_state(out)
|
|
47
|
-
out.int(@data)
|
|
48
|
-
@ram.save_state(out)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def load_state(input)
|
|
52
|
-
@data = input.int
|
|
53
|
-
@ram.load_state(input)
|
|
54
|
-
@watching = false
|
|
55
|
-
end
|
|
56
|
-
|
|
57
44
|
def peek(addr)
|
|
58
45
|
return @data = @rom.peek(addr) if addr >= 0x8000
|
|
59
46
|
return @data = chip_peek(addr) if addr >= 0x2000
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "badline/drives/model1581/disk/saved_state"
|
|
4
|
-
|
|
5
3
|
module Badline
|
|
6
4
|
module Drives
|
|
7
5
|
class Model1581
|
|
@@ -24,8 +22,6 @@ module Badline
|
|
|
24
22
|
# file. A track formatted another way stays on the disk alone. The disk
|
|
25
23
|
# is write-protected when the image won't take writes.
|
|
26
24
|
class Disk
|
|
27
|
-
include SavedState
|
|
28
|
-
|
|
29
25
|
CYLINDERS = 80
|
|
30
26
|
SIDES = 2
|
|
31
27
|
|