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
|
@@ -0,0 +1,514 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class C64
|
|
5
|
+
class Cartridge
|
|
6
|
+
# A cartridge's fields in a keyed snapshot module (Snapshot::Keyed,
|
|
7
|
+
# BL-CART): the CRT image it was built from and its jumpers, which
|
|
8
|
+
# build it again (Cartridge.from_fields), the EXROM and GAME lines,
|
|
9
|
+
# its pull on NMI, the button, and each mapper's own registers, from
|
|
10
|
+
# which a load works out where ROML and ROMH point again.
|
|
11
|
+
#
|
|
12
|
+
# Snapshots from 0.14.0 name the bank or view each window shows
|
|
13
|
+
# instead (window_labels), under roml and romh. A load reads those
|
|
14
|
+
# when the mapper's register isn't there, and works the register out
|
|
15
|
+
# from the windows.
|
|
16
|
+
module KeyedState
|
|
17
|
+
def save_fields(out)
|
|
18
|
+
save_setup_fields(out)
|
|
19
|
+
out.int("exrom", @exrom).int("game", @game).bool("nmi", @nmi).bool("button", @button == true)
|
|
20
|
+
save_mapper_fields(out)
|
|
21
|
+
out
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def load_fields(input)
|
|
25
|
+
@exrom = input.masked("exrom", @exrom, 1)
|
|
26
|
+
@game = input.masked("game", @game, 1)
|
|
27
|
+
@nmi = input.bool("nmi", @nmi)
|
|
28
|
+
@button = input.bool("button", false)
|
|
29
|
+
load_mapper_fields(input)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
private
|
|
33
|
+
|
|
34
|
+
def save_setup_fields(out)
|
|
35
|
+
out.bytes("crt", Storage::CRTFile.encode(@crt))
|
|
36
|
+
save_jumper_fields(out)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def save_jumper_fields(_out); end
|
|
40
|
+
|
|
41
|
+
def save_mapper_fields(_out); end
|
|
42
|
+
|
|
43
|
+
def load_mapper_fields(_input); end
|
|
44
|
+
|
|
45
|
+
# The register at `key`, cut to `mask`, or nil for a snapshot that
|
|
46
|
+
# names the windows instead, with the windows put back from their
|
|
47
|
+
# names.
|
|
48
|
+
def latch_or_windows(input, key, default, mask)
|
|
49
|
+
return input.masked(key, default, mask) if input.tags.key?(key)
|
|
50
|
+
|
|
51
|
+
load_window_fields(input)
|
|
52
|
+
nil
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# The number of the bank among `banks` that `window` shows, or of the
|
|
56
|
+
# first the image leaves out for erased ROM.
|
|
57
|
+
def number_showing(banks, window)
|
|
58
|
+
number = banks.index { |each| each.equal?(window) }
|
|
59
|
+
return number if number
|
|
60
|
+
return 0 unless window.equal?(EMPTY_BANK)
|
|
61
|
+
|
|
62
|
+
banks.index(nil) || banks.length
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# The name of each of `windows`, in the same order: bank<N> for the
|
|
66
|
+
# mapper's banks, and empty for erased ROM.
|
|
67
|
+
def window_labels
|
|
68
|
+
banks = @banks
|
|
69
|
+
return [] unless banks
|
|
70
|
+
|
|
71
|
+
[*Array.new(banks.length) { |number| "bank#{number}" }, "empty"]
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def load_window_fields(input)
|
|
75
|
+
choices = windows
|
|
76
|
+
return unless choices
|
|
77
|
+
|
|
78
|
+
labels = window_labels
|
|
79
|
+
@roml = window_named(input.choice("roml", [*labels, "none"], "none"), choices, labels)
|
|
80
|
+
@romh = window_named(input.choice("romh", [*labels, "none"], "none"), choices, labels)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def window_named(label, choices, labels)
|
|
84
|
+
index = labels.index(label)
|
|
85
|
+
index.nil? ? nil : choices.fetch(index)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
include KeyedState
|
|
90
|
+
|
|
91
|
+
class << self
|
|
92
|
+
# A cartridge built afresh from the CRT image and the jumpers a
|
|
93
|
+
# keyed snapshot module holds, before load_fields puts its state in.
|
|
94
|
+
def from_fields(input)
|
|
95
|
+
kb = input.int("geo_ram_kb", 0)
|
|
96
|
+
return GeoRAM.new(size: kb) if kb.positive?
|
|
97
|
+
|
|
98
|
+
crt = Storage::CRTFile.new(bytes: input.bytes("crt", "".b))
|
|
99
|
+
mapper_for(crt).from_jumper_fields(crt, input)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def from_jumper_fields(crt, _input) = new(crt)
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# One bank register, under bank, selecting the bank ROML shows.
|
|
106
|
+
module BankLatch
|
|
107
|
+
private
|
|
108
|
+
|
|
109
|
+
def save_mapper_fields(out)
|
|
110
|
+
out.int("bank", @bank)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def load_mapper_fields(input)
|
|
114
|
+
latch = latch_or_windows(input, "bank", @bank, bank_latch_mask)
|
|
115
|
+
if latch.nil?
|
|
116
|
+
@bank = number_showing(@banks, @roml)
|
|
117
|
+
else
|
|
118
|
+
@bank = latch
|
|
119
|
+
show_bank
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def show_bank
|
|
124
|
+
@roml = bank(@banks, @bank)
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Two banks of ROM, one behind each window: roml<N> and romh<N>, both
|
|
129
|
+
# selected by one bank register, under bank.
|
|
130
|
+
module SplitBanks
|
|
131
|
+
private
|
|
132
|
+
|
|
133
|
+
def save_mapper_fields(out)
|
|
134
|
+
out.int("bank", @bank)
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def load_mapper_fields(input)
|
|
138
|
+
latch = latch_or_windows(input, "bank", @bank, bank_latch_mask)
|
|
139
|
+
if latch.nil?
|
|
140
|
+
@bank = number_showing(@roml_banks, @roml)
|
|
141
|
+
else
|
|
142
|
+
@bank = latch
|
|
143
|
+
@roml = bank(@roml_banks, @bank)
|
|
144
|
+
@romh = bank(@romh_banks, @bank)
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def window_labels
|
|
149
|
+
[*Array.new(@roml_banks.length) { |number| "roml#{number}" },
|
|
150
|
+
*Array.new(@romh_banks.length) { |number| "romh#{number}" }, "empty"]
|
|
151
|
+
end
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
class Ocean
|
|
155
|
+
include BankLatch
|
|
156
|
+
|
|
157
|
+
private
|
|
158
|
+
|
|
159
|
+
def bank_latch_mask = @bank_mask
|
|
160
|
+
|
|
161
|
+
def show_bank = select_bank(@bank)
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
class FunPlay
|
|
165
|
+
include BankLatch
|
|
166
|
+
|
|
167
|
+
private
|
|
168
|
+
|
|
169
|
+
def bank_latch_mask = 0x0f
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
class GameSystem
|
|
173
|
+
include BankLatch
|
|
174
|
+
|
|
175
|
+
private
|
|
176
|
+
|
|
177
|
+
def bank_latch_mask = 0x3f
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
class Dinamic
|
|
181
|
+
include BankLatch
|
|
182
|
+
|
|
183
|
+
private
|
|
184
|
+
|
|
185
|
+
def bank_latch_mask = 0x0f
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
class MagicDesk
|
|
189
|
+
include BankLatch
|
|
190
|
+
|
|
191
|
+
private
|
|
192
|
+
|
|
193
|
+
def bank_latch_mask = @bank_mask
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
class SuperGames
|
|
197
|
+
include SplitBanks
|
|
198
|
+
|
|
199
|
+
private
|
|
200
|
+
|
|
201
|
+
def bank_latch_mask = 0x03
|
|
202
|
+
|
|
203
|
+
def save_mapper_fields(out)
|
|
204
|
+
super
|
|
205
|
+
out.bool("locked", @locked)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def load_mapper_fields(input)
|
|
209
|
+
super
|
|
210
|
+
@locked = input.bool("locked", @locked)
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
class Comal80
|
|
215
|
+
include SplitBanks
|
|
216
|
+
|
|
217
|
+
private
|
|
218
|
+
|
|
219
|
+
def bank_latch_mask = 0x07
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
class FinalCartridge3
|
|
223
|
+
include SplitBanks
|
|
224
|
+
|
|
225
|
+
private
|
|
226
|
+
|
|
227
|
+
def bank_latch_mask = @bank_mask
|
|
228
|
+
|
|
229
|
+
def save_mapper_fields(out)
|
|
230
|
+
super
|
|
231
|
+
out.bool("register_visible", @register_visible).bool("phi1_ultimax", @phi1_ultimax)
|
|
232
|
+
end
|
|
233
|
+
|
|
234
|
+
def load_mapper_fields(input)
|
|
235
|
+
super
|
|
236
|
+
@io_bank = @roml
|
|
237
|
+
@register_visible = input.bool("register_visible", @register_visible)
|
|
238
|
+
@phi1_ultimax = input.bool("phi1_ultimax", @phi1_ultimax)
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
class RGCD
|
|
243
|
+
include BankLatch
|
|
244
|
+
|
|
245
|
+
private
|
|
246
|
+
|
|
247
|
+
def bank_latch_mask = @bank_mask
|
|
248
|
+
|
|
249
|
+
def save_mapper_fields(out)
|
|
250
|
+
super
|
|
251
|
+
out.bool("disabled", @disabled)
|
|
252
|
+
end
|
|
253
|
+
|
|
254
|
+
def load_mapper_fields(input)
|
|
255
|
+
super
|
|
256
|
+
@disabled = input.bool("disabled", @disabled)
|
|
257
|
+
end
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
class Zaxxon
|
|
261
|
+
class High
|
|
262
|
+
def save_fields(out)
|
|
263
|
+
out.int("high_bank", @number)
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
def load_fields(input)
|
|
267
|
+
select(input.int("high_bank", 0).clamp(0, @banks.length))
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
|
|
271
|
+
private
|
|
272
|
+
|
|
273
|
+
def save_mapper_fields(out) = @romh.save_fields(out)
|
|
274
|
+
|
|
275
|
+
def load_mapper_fields(input) = @romh.load_fields(input)
|
|
276
|
+
end
|
|
277
|
+
|
|
278
|
+
class EpyxFastload
|
|
279
|
+
private
|
|
280
|
+
|
|
281
|
+
# How long ago the capacitor was discharged, on the machine's clock.
|
|
282
|
+
def save_mapper_fields(out)
|
|
283
|
+
out.int("discharged_ago", now_cycles - @discharged_at)
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
def load_mapper_fields(input)
|
|
287
|
+
@discharged_at = now_cycles - input.int("discharged_ago", now_cycles - @discharged_at)
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
def now_cycles
|
|
291
|
+
clock = @clock
|
|
292
|
+
clock ? clock.call : 0
|
|
293
|
+
end
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
class ActionReplay
|
|
297
|
+
private
|
|
298
|
+
|
|
299
|
+
def window_labels
|
|
300
|
+
["through", "isolated", "contended", *Array.new(@rom_banks.length) { |number| "rom#{number}" }, "empty"]
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
def save_mapper_fields(out)
|
|
304
|
+
out.int("control", @control).bool("active", @active).bytes("ram", @ram_data)
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
def load_mapper_fields(input)
|
|
308
|
+
latch = latch_or_windows(input, "control", @control, 0xff)
|
|
309
|
+
if latch.nil?
|
|
310
|
+
load_legacy_fields(input)
|
|
311
|
+
else
|
|
312
|
+
@control = latch
|
|
313
|
+
@rom = bank(@rom_banks, (@control >> 3) & 0x03)
|
|
314
|
+
configure(@control)
|
|
315
|
+
end
|
|
316
|
+
@active = input.bool("active", @active)
|
|
317
|
+
input.bytes_into("ram", @ram_data)
|
|
318
|
+
end
|
|
319
|
+
|
|
320
|
+
# The ROM bank by name, and whether I/O 2 shows the RAM, from which
|
|
321
|
+
# the register is worked out.
|
|
322
|
+
def load_legacy_fields(input)
|
|
323
|
+
labels = window_labels
|
|
324
|
+
@rom = window_named(input.choice("rom", labels, "rom0"), windows, labels)
|
|
325
|
+
@io2_ram = input.bool("io2_ram", @io2_ram)
|
|
326
|
+
number = number_showing(@rom_banks, @rom) << 3
|
|
327
|
+
@control = if @roml.equal?(@contended) || @romh.equal?(@isolated)
|
|
328
|
+
0x22 | number
|
|
329
|
+
else
|
|
330
|
+
mode = @exrom.zero? ? 1 - @game : 3 - @game
|
|
331
|
+
mode | (@io2_ram ? 0x20 : 0) | number
|
|
332
|
+
end
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
class KCSPower
|
|
337
|
+
private
|
|
338
|
+
|
|
339
|
+
def save_mapper_fields(out) = out.bytes("io_ram", @io_ram)
|
|
340
|
+
|
|
341
|
+
def load_mapper_fields(input) = input.bytes_into("io_ram", @io_ram)
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
class Pagefox
|
|
345
|
+
private
|
|
346
|
+
|
|
347
|
+
def window_labels
|
|
348
|
+
[*Array.new(@roml_banks.length) { |number| "roml#{number}" },
|
|
349
|
+
*Array.new(@romh_banks.length) { |number| "romh#{number}" },
|
|
350
|
+
*Array.new(@ram_banks.length) { |number| "ram#{number}" }, "open_bus", "empty"]
|
|
351
|
+
end
|
|
352
|
+
|
|
353
|
+
def save_mapper_fields(out)
|
|
354
|
+
out.int("control", @control)
|
|
355
|
+
@ram_banks.each_with_index { |ram, number| out.bytes("ram#{number}.data", ram.data) }
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
def load_mapper_fields(input)
|
|
359
|
+
latch = latch_or_windows(input, "control", @control, 0xff)
|
|
360
|
+
if latch.nil?
|
|
361
|
+
selected = (0...8).find { |select| window(select >> 1, select & 0x01) == [@roml, @romh] } || 0
|
|
362
|
+
@control = (selected << 1) | (@exrom == 1 && @game == 1 ? 0x10 : 0)
|
|
363
|
+
else
|
|
364
|
+
@control = latch
|
|
365
|
+
@roml, @romh = window((@control >> 2) & 0x03, (@control >> 1) & 0x01)
|
|
366
|
+
end
|
|
367
|
+
@ram_banks.each_with_index { |ram, number| input.bytes_into("ram#{number}.data", ram.data) }
|
|
368
|
+
end
|
|
369
|
+
end
|
|
370
|
+
|
|
371
|
+
class GeoRAM
|
|
372
|
+
private
|
|
373
|
+
|
|
374
|
+
def save_setup_fields(out) = out.int("geo_ram_kb", @size)
|
|
375
|
+
|
|
376
|
+
def save_mapper_fields(out)
|
|
377
|
+
out.bytes("ram", @ram_data).int("block", @block).int("page", @page).int("window", @window)
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
def load_mapper_fields(input)
|
|
381
|
+
input.bytes_into("ram", @ram_data)
|
|
382
|
+
@block = input.int("block", @block)
|
|
383
|
+
@page = input.int("page", @page)
|
|
384
|
+
@window = input.int("window", @window)
|
|
385
|
+
end
|
|
386
|
+
end
|
|
387
|
+
|
|
388
|
+
class Flash
|
|
389
|
+
# The array, the command state by name, how far through a command
|
|
390
|
+
# sequence, the toggle bit, a timed operation's end in cycles from
|
|
391
|
+
# now, and the windows handed out so far, under `prefix`.
|
|
392
|
+
module KeyedState
|
|
393
|
+
STATE_NAMES = STATES.map(&:to_s).freeze
|
|
394
|
+
|
|
395
|
+
def save_fields(out, prefix)
|
|
396
|
+
out.bytes("#{prefix}data", @data).text("#{prefix}state", @state.to_s)
|
|
397
|
+
out.text("#{prefix}base_state", @base_state.to_s).int("#{prefix}cycle", @cycle)
|
|
398
|
+
out.int("#{prefix}toggle", @toggle)
|
|
399
|
+
done_at = @done_at
|
|
400
|
+
out.int("#{prefix}done_in", done_at - @clock.call) unless done_at.nil?
|
|
401
|
+
out.optional_int("#{prefix}programmed", @programmed).optional_int("#{prefix}remaining", @remaining)
|
|
402
|
+
sectors = @erasing_sectors
|
|
403
|
+
out.ints("#{prefix}erasing_sectors", sectors) if sectors
|
|
404
|
+
out.ints("#{prefix}windows", @windows.keys).ints("#{prefix}status_windows", @status_windows.keys)
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
def load_fields(input, prefix)
|
|
408
|
+
input.bytes_into("#{prefix}data", @data)
|
|
409
|
+
@state = state_named(input.choice("#{prefix}state", STATE_NAMES, "read"))
|
|
410
|
+
@base_state = state_named(input.choice("#{prefix}base_state", STATE_NAMES, "read"))
|
|
411
|
+
@cycle = input.int("#{prefix}cycle", @cycle)
|
|
412
|
+
@toggle = input.int("#{prefix}toggle", @toggle)
|
|
413
|
+
done_in = input.optional_int("#{prefix}done_in")
|
|
414
|
+
@done_at = done_in.nil? ? nil : @clock.call + done_in
|
|
415
|
+
@programmed = input.optional_int("#{prefix}programmed")
|
|
416
|
+
@remaining = input.optional_int("#{prefix}remaining")
|
|
417
|
+
sectors = input.ints("#{prefix}erasing_sectors", [])
|
|
418
|
+
@erasing_sectors = sectors.empty? ? nil : sectors.dup
|
|
419
|
+
rebuild_windows(input.ints("#{prefix}windows", []), input.ints("#{prefix}status_windows", []))
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
private
|
|
423
|
+
|
|
424
|
+
def state_named(name)
|
|
425
|
+
STATES.find { |state| state.to_s == name } || :read
|
|
426
|
+
end
|
|
427
|
+
end
|
|
428
|
+
|
|
429
|
+
include KeyedState
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
class GMod2
|
|
433
|
+
private
|
|
434
|
+
|
|
435
|
+
def save_mapper_fields(out)
|
|
436
|
+
out.int("bank", @bank).bool("flash_writes", @flash_writes)
|
|
437
|
+
@flash.save_fields(out, "flash.")
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
def load_mapper_fields(input)
|
|
441
|
+
@bank = input.int("bank", @bank)
|
|
442
|
+
@flash_writes = input.bool("flash_writes", @flash_writes)
|
|
443
|
+
@flash.load_fields(input, "flash.")
|
|
444
|
+
@roml = @flash.window(@bank * BANK_SIZE)
|
|
445
|
+
end
|
|
446
|
+
end
|
|
447
|
+
|
|
448
|
+
class EasyFlash
|
|
449
|
+
private
|
|
450
|
+
|
|
451
|
+
def save_mapper_fields(out)
|
|
452
|
+
out.int("bank", @bank).int("control", @control).bytes("io_ram", @io_ram)
|
|
453
|
+
@low_flash.save_fields(out, "flash_low.")
|
|
454
|
+
@high_flash.save_fields(out, "flash_high.")
|
|
455
|
+
end
|
|
456
|
+
|
|
457
|
+
def load_mapper_fields(input)
|
|
458
|
+
@bank = input.int("bank", @bank)
|
|
459
|
+
@control = input.byte("control", @control)
|
|
460
|
+
input.bytes_into("io_ram", @io_ram)
|
|
461
|
+
@low_flash.load_fields(input, "flash_low.")
|
|
462
|
+
@high_flash.load_fields(input, "flash_high.")
|
|
463
|
+
map_bank
|
|
464
|
+
end
|
|
465
|
+
end
|
|
466
|
+
|
|
467
|
+
class RetroReplay
|
|
468
|
+
CONFIG_NAMES = CONTROL_MODES.map(&:to_s).freeze
|
|
469
|
+
|
|
470
|
+
# The flash and bank jumpers, as the board has them set.
|
|
471
|
+
def self.from_jumper_fields(crt, input)
|
|
472
|
+
new(crt, flash_jumper: input.bool("jumper.flash", false), bank_jumper: input.bool("jumper.bank", false))
|
|
473
|
+
end
|
|
474
|
+
|
|
475
|
+
private
|
|
476
|
+
|
|
477
|
+
def save_jumper_fields(out)
|
|
478
|
+
out.bool("jumper.flash", @flash_jumper).bool("jumper.bank", @bank_jumper)
|
|
479
|
+
end
|
|
480
|
+
|
|
481
|
+
def save_mapper_fields(out)
|
|
482
|
+
out.bool("active", @active).bool("frozen", @frozen).bool("phi1_ultimax", @phi1_ultimax)
|
|
483
|
+
out.bool("ram_enabled", @ram_enabled).bool("ram_at_a000", @ram_at_a000).bool("allow_bank", @allow_bank)
|
|
484
|
+
out.bool("no_freeze", @no_freeze).bool("reu_mapping", @reu_mapping).bool("write_once", @write_once)
|
|
485
|
+
out.int("bank", @bank).text("config", @config.to_s)
|
|
486
|
+
@ram_data.each_with_index { |data, number| out.bytes("ram#{number}", data) }
|
|
487
|
+
@flash.save_fields(out, "flash.")
|
|
488
|
+
end
|
|
489
|
+
|
|
490
|
+
def load_mapper_fields(input)
|
|
491
|
+
load_flag_fields(input)
|
|
492
|
+
@bank = input.int("bank", @bank)
|
|
493
|
+
config = input.choice("config", CONFIG_NAMES, "rom8k")
|
|
494
|
+
@config = CONTROL_MODES.find { |mode| mode.to_s == config } || :rom8k
|
|
495
|
+
@ram_data.each_with_index { |data, number| input.bytes_into("ram#{number}", data) }
|
|
496
|
+
@flash.load_fields(input, "flash.")
|
|
497
|
+
map_windows
|
|
498
|
+
end
|
|
499
|
+
|
|
500
|
+
def load_flag_fields(input)
|
|
501
|
+
@active = input.bool("active", @active)
|
|
502
|
+
@frozen = input.bool("frozen", @frozen)
|
|
503
|
+
@phi1_ultimax = input.bool("phi1_ultimax", @phi1_ultimax)
|
|
504
|
+
@ram_enabled = input.bool("ram_enabled", @ram_enabled)
|
|
505
|
+
@ram_at_a000 = input.bool("ram_at_a000", @ram_at_a000)
|
|
506
|
+
@allow_bank = input.bool("allow_bank", @allow_bank)
|
|
507
|
+
@no_freeze = input.bool("no_freeze", @no_freeze)
|
|
508
|
+
@reu_mapping = input.bool("reu_mapping", @reu_mapping)
|
|
509
|
+
@write_once = input.bool("write_once", @write_once)
|
|
510
|
+
end
|
|
511
|
+
end
|
|
512
|
+
end
|
|
513
|
+
end
|
|
514
|
+
end
|
|
@@ -30,19 +30,10 @@ module Badline
|
|
|
30
30
|
|
|
31
31
|
private
|
|
32
32
|
|
|
33
|
-
def save_mapper(out)
|
|
34
|
-
super
|
|
35
|
-
@ram_banks.each { |ram| out.blob(ram.data) }
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def load_mapper(input)
|
|
39
|
-
super
|
|
40
|
-
@ram_banks.each { |ram| input.blob_into(ram.data) }
|
|
41
|
-
end
|
|
42
|
-
|
|
43
33
|
def windows = [*@roml_banks, *@romh_banks, *@ram_banks, @open_bus || EMPTY_BANK, EMPTY_BANK]
|
|
44
34
|
|
|
45
35
|
def select(value)
|
|
36
|
+
@control = value
|
|
46
37
|
half = (value >> 1) & 0x01
|
|
47
38
|
chip = (value >> 2) & 0x03
|
|
48
39
|
@roml, @romh = window(chip, half)
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "badline/c64/cartridge/retro_replay/saved_state"
|
|
4
|
-
|
|
5
3
|
module Badline
|
|
6
4
|
class C64
|
|
7
5
|
class Cartridge
|
|
@@ -47,7 +45,6 @@ module Badline
|
|
|
47
45
|
# the half in bit 5.
|
|
48
46
|
class RetroReplay < Cartridge
|
|
49
47
|
include Freezer
|
|
50
|
-
include SavedState
|
|
51
48
|
|
|
52
49
|
CONTROL_MODES = %i[rom8k rom16k off ultimax].freeze
|
|
53
50
|
IO1_PAGE = 0x1e00
|
|
@@ -55,11 +52,6 @@ module Badline
|
|
|
55
52
|
|
|
56
53
|
attr_reader :flash
|
|
57
54
|
|
|
58
|
-
def self.from_jumpers(crt, input)
|
|
59
|
-
input.boolean?
|
|
60
|
-
new(crt, flash_jumper: input.boolean?, bank_jumper: input.boolean?)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
55
|
def initialize(crt, flash_jumper: false, bank_jumper: false)
|
|
64
56
|
@nordic = crt.subtype == 1
|
|
65
57
|
@flash_jumper = flash_jumper
|
|
@@ -29,23 +29,14 @@ module Badline
|
|
|
29
29
|
|
|
30
30
|
private
|
|
31
31
|
|
|
32
|
-
def save_mapper(out)
|
|
33
|
-
super
|
|
34
|
-
out.boolean(@disabled)
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def load_mapper(input)
|
|
38
|
-
super
|
|
39
|
-
@disabled = input.boolean?
|
|
40
|
-
end
|
|
41
|
-
|
|
42
32
|
def select(value)
|
|
43
33
|
value ^= 0x07 if @hucky
|
|
44
34
|
if value.anybits?(0x08)
|
|
45
35
|
@disabled = true
|
|
46
36
|
self.mode = :off
|
|
47
37
|
else
|
|
48
|
-
@
|
|
38
|
+
@bank = value & @bank_mask
|
|
39
|
+
@roml = bank(@banks, @bank)
|
|
49
40
|
end
|
|
50
41
|
end
|
|
51
42
|
|
|
@@ -21,21 +21,12 @@ module Badline
|
|
|
21
21
|
|
|
22
22
|
private
|
|
23
23
|
|
|
24
|
-
def save_mapper(out)
|
|
25
|
-
super
|
|
26
|
-
out.boolean(@locked)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def load_mapper(input)
|
|
30
|
-
super
|
|
31
|
-
@locked = input.boolean?
|
|
32
|
-
end
|
|
33
|
-
|
|
34
24
|
def windows = [*@roml_banks, *@romh_banks, EMPTY_BANK]
|
|
35
25
|
|
|
36
26
|
def select(value)
|
|
37
|
-
@
|
|
38
|
-
@
|
|
27
|
+
@bank = value & 0x03
|
|
28
|
+
@roml = bank(@roml_banks, @bank)
|
|
29
|
+
@romh = bank(@romh_banks, @bank)
|
|
39
30
|
self.mode = value.anybits?(0x04) ? :off : :rom16k
|
|
40
31
|
@locked = value.anybits?(0x08)
|
|
41
32
|
end
|
|
@@ -26,20 +26,13 @@ module Badline
|
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
def select(number)
|
|
29
|
+
@number = number
|
|
29
30
|
@bank = @banks[number] || EMPTY_BANK
|
|
30
31
|
end
|
|
31
32
|
|
|
32
33
|
def peek(addr)
|
|
33
34
|
@bank.peek(addr)
|
|
34
35
|
end
|
|
35
|
-
|
|
36
|
-
def save_state(out)
|
|
37
|
-
out.int([*@banks, EMPTY_BANK].index { |bank| bank.equal?(@bank) })
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def load_state(input)
|
|
41
|
-
@bank = [*@banks, EMPTY_BANK].fetch(input.int)
|
|
42
|
-
end
|
|
43
36
|
end
|
|
44
37
|
|
|
45
38
|
def reset
|
|
@@ -48,14 +41,6 @@ module Badline
|
|
|
48
41
|
|
|
49
42
|
private
|
|
50
43
|
|
|
51
|
-
def save_mapper(out)
|
|
52
|
-
@romh.save_state(out)
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def load_mapper(input)
|
|
56
|
-
@romh.load_state(input)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
44
|
def install_chips(chips)
|
|
60
45
|
roml, romh = banks_from(chips)
|
|
61
46
|
@romh = High.new(romh)
|