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,117 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class C128
|
|
5
|
+
# The whole machine as keyed snapshot modules (Snapshot::Keyed), in the
|
|
6
|
+
# order a load applies them, as C64::KeyedModules: BL-MACHINE with the
|
|
7
|
+
# last bus access under bus.*, the RAM, both banks of colour RAM, the
|
|
8
|
+
# MMU, the cartridge, the 8502 with its port, the Z80, the chips, the
|
|
9
|
+
# datasette, device 8 through the traps and the true drives. The
|
|
10
|
+
# machine's own fields load after the Z80's, which z80_ahead counts
|
|
11
|
+
# from.
|
|
12
|
+
module KeyedModules
|
|
13
|
+
def save_modules
|
|
14
|
+
bus = @bus
|
|
15
|
+
sections = [Snapshot::Keyed.section("BL-MACHINE") do |out|
|
|
16
|
+
save_machine_fields(out)
|
|
17
|
+
bus.save_fields(out, "bus.")
|
|
18
|
+
end]
|
|
19
|
+
sections << Snapshot::Keyed.section("BL-RAM") { |out| bus.ram.save_fields(out, "ram") }
|
|
20
|
+
sections << Snapshot::Keyed.section("BL-COLORRAM") { |out| bus.save_color_fields(out) }
|
|
21
|
+
sections << Snapshot::Keyed.section("BL-MMU") { |out| bus.mmu.save_fields(out) }
|
|
22
|
+
cartridge = bus.cartridge
|
|
23
|
+
sections << Snapshot::Keyed.section("BL-CART") { |out| cartridge.save_fields(out) } if cartridge
|
|
24
|
+
save_chip_modules(sections, bus)
|
|
25
|
+
sections << Snapshot::Keyed.section("BL-TAPE") { |out| bus.datasette.save_fields(out) }
|
|
26
|
+
sections << Snapshot::Keyed.section("BL-TRAPDOS") { |out| save_trap_dos_fields(out) } if mounted?
|
|
27
|
+
save_drive_modules(sections)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Raises Snapshot::FormatError for the modules of another model, SID
|
|
31
|
+
# or mode.
|
|
32
|
+
def load_modules(modules)
|
|
33
|
+
machine = modules.machine
|
|
34
|
+
check_snapshot_setup(Snapshot::C128Setup.read_fields(machine))
|
|
35
|
+
bus = @bus
|
|
36
|
+
bus.ram.load_fields(modules.required("BL-RAM"), "ram")
|
|
37
|
+
bus.load_color_fields(modules.required("BL-COLORRAM"))
|
|
38
|
+
bus.mmu.load_fields(modules.required("BL-MMU"))
|
|
39
|
+
load_cartridge_module(modules.optional("BL-CART"))
|
|
40
|
+
load_chip_modules(modules)
|
|
41
|
+
bus.load_fields(machine, "bus.")
|
|
42
|
+
load_machine_fields(machine)
|
|
43
|
+
bus.datasette.load_fields(modules.required("BL-TAPE"))
|
|
44
|
+
trap_dos = modules.optional("BL-TRAPDOS")
|
|
45
|
+
trap_dos ? load_trap_dos_fields(trap_dos, detached: modules.detached?) : unmount
|
|
46
|
+
load_drive_modules(modules)
|
|
47
|
+
modules_restored!
|
|
48
|
+
self
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
private
|
|
52
|
+
|
|
53
|
+
def save_chip_modules(sections, bus)
|
|
54
|
+
sections << Snapshot::Keyed.section("BL-CPU") do |out|
|
|
55
|
+
@cpu.save_fields(out)
|
|
56
|
+
bus.save_port_fields(out)
|
|
57
|
+
end
|
|
58
|
+
sections << Snapshot::Keyed.section("BL-Z80") { |out| @z80.save_fields(out) }
|
|
59
|
+
sections << Snapshot::Keyed.section("BL-VIC") { |out| @vic.save_fields(out) }
|
|
60
|
+
sections << Snapshot::Keyed.section("BL-VDC") { |out| @vdc.save_fields(out) }
|
|
61
|
+
sections << Snapshot::Keyed.section("BL-CIA1") { |out| @cia1.save_fields(out) }
|
|
62
|
+
sections << Snapshot::Keyed.section("BL-CIA2") { |out| @cia2.save_fields(out) }
|
|
63
|
+
sections << Snapshot::Keyed.section("BL-SID") { |out| @sid.save_fields(out) }
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# The port goes in ahead of the chips, as the C64's does, and the bus
|
|
67
|
+
# maps its banks and the keyboard's extra rows once they are in. That
|
|
68
|
+
# hands the bus to the CPU the MMU names, which resets the Z80's
|
|
69
|
+
# schedule and can reset the 8502, so the CPUs, the last bus access
|
|
70
|
+
# and the machine's own fields load after it.
|
|
71
|
+
def load_chip_modules(modules)
|
|
72
|
+
cpu = modules.required("BL-CPU")
|
|
73
|
+
@bus.load_port_fields(cpu)
|
|
74
|
+
@vic.load_fields(modules.required("BL-VIC"))
|
|
75
|
+
@vdc.load_fields(modules.required("BL-VDC"))
|
|
76
|
+
@cia1.load_fields(modules.required("BL-CIA1"))
|
|
77
|
+
@cia2.load_fields(modules.required("BL-CIA2"))
|
|
78
|
+
@sid.load_fields(modules.required("BL-SID"))
|
|
79
|
+
@bus.restored!
|
|
80
|
+
@cpu.load_fields(cpu)
|
|
81
|
+
@z80.load_fields(modules.required("BL-Z80"))
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# The cartridge comes back built afresh from the CRT image the module
|
|
85
|
+
# holds, before its state goes in. No module means no cartridge.
|
|
86
|
+
def load_cartridge_module(input)
|
|
87
|
+
if input
|
|
88
|
+
cartridge = C64::Cartridge.from_fields(input)
|
|
89
|
+
connect_cartridge(cartridge)
|
|
90
|
+
cartridge.load_fields(input)
|
|
91
|
+
elsif @bus.cartridge
|
|
92
|
+
@bus.detach_cartridge
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def modules_restored!
|
|
97
|
+
@cpu.restored!
|
|
98
|
+
@z80.restored!
|
|
99
|
+
@vic.restored!
|
|
100
|
+
@vdc.restored!
|
|
101
|
+
@cia1.restored!
|
|
102
|
+
@cia2.restored!
|
|
103
|
+
@sid.restored!
|
|
104
|
+
machine_restored!
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def check_snapshot_setup(setup)
|
|
108
|
+
ours = snapshot_setup
|
|
109
|
+
return if setup == ours
|
|
110
|
+
|
|
111
|
+
raise Snapshot::FormatError, "the snapshot is of a #{setup}, not a #{ours}"
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
include KeyedModules
|
|
116
|
+
end
|
|
117
|
+
end
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class C128
|
|
5
|
+
# The machine's own fields in a keyed snapshot module (Snapshot::Keyed,
|
|
6
|
+
# BL-MACHINE): the family, its model, SID and mode by name, the cycle
|
|
7
|
+
# count, $D030's clock bits on their way, the NMI glue, the two
|
|
8
|
+
# schedulers' offsets (z80_ahead, the Z80's T-states past when it was
|
|
9
|
+
# due, and chips_ahead), an 8502 reset waiting for the bus, and under
|
|
10
|
+
# host.* the host's typing (the codes still to type, whether it is
|
|
11
|
+
# typing, and where Input::MatrixTypist is in a code on the key
|
|
12
|
+
# matrix), C= held from power-on and the on_init handlers still to run.
|
|
13
|
+
# They load after the Z80's own fields, which z80_ahead counts from.
|
|
14
|
+
module KeyedState
|
|
15
|
+
# How many more on_init handlers the machine a snapshot was taken of had
|
|
16
|
+
# yet to run than this one has. Nil until the machine is restored.
|
|
17
|
+
attr_reader :init_handlers_lost
|
|
18
|
+
|
|
19
|
+
# Whether a snapshot saves now (Machine::Settling): the 8502 between
|
|
20
|
+
# instructions or jammed. While the Z80 runs, the 8502 waits at the
|
|
21
|
+
# boundary it handed the bus over at, and the Z80 runs whole
|
|
22
|
+
# instructions.
|
|
23
|
+
def settled_for_snapshot? = @cpu.boundary? || @cpu.jammed?
|
|
24
|
+
|
|
25
|
+
# The SID's deferred cycles and writes, run up to this cycle, and the
|
|
26
|
+
# VIC's sprite collisions latched up to the beam.
|
|
27
|
+
def settle_chips_for_snapshot
|
|
28
|
+
sid.catch_up!
|
|
29
|
+
@vic.fold_collisions!
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def save_machine_fields(out)
|
|
33
|
+
out.text("family", "c128").text("written_by", VERSION)
|
|
34
|
+
snapshot_setup.write_fields(out)
|
|
35
|
+
out.int("cycles", @cycles).int("clock_bits", @clock_bits).bool("nmi_asserted", @nmi_asserted)
|
|
36
|
+
out.bool("cartridge_nmi", @cartridge_nmi).bool("restore_pulse", @restore_pulse)
|
|
37
|
+
out.int("z80_ahead", @z80.cycles - @z80_due).int("chips_ahead", @chips_ahead)
|
|
38
|
+
out.bool("cpu_reset_pending", @cpu_reset_pending)
|
|
39
|
+
pending = @pending_keys
|
|
40
|
+
out.ints("host.pending_keys", pending) if pending
|
|
41
|
+
out.bool("host.typing", !pending.nil?)
|
|
42
|
+
out.int("host.init_pending", @cycles <= init_threshold ? @init_handlers.length : 0)
|
|
43
|
+
out.bool("host.holding_commodore", @holding_commodore)
|
|
44
|
+
@typist.save_fields(out, "host.typist.")
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def load_machine_fields(input)
|
|
48
|
+
@cycles = input.int("cycles", @cycles)
|
|
49
|
+
@clock_bits = input.int("clock_bits", @clock_bits)
|
|
50
|
+
@nmi_asserted = input.bool("nmi_asserted", @nmi_asserted)
|
|
51
|
+
@cartridge_nmi = input.bool("cartridge_nmi", @cartridge_nmi)
|
|
52
|
+
@restore_pulse = input.bool("restore_pulse", @restore_pulse)
|
|
53
|
+
@z80_due = @z80.cycles - input.int("z80_ahead", @z80.cycles - @z80_due)
|
|
54
|
+
@chips_ahead = input.int("chips_ahead", @chips_ahead)
|
|
55
|
+
@cpu_reset_pending = input.bool("cpu_reset_pending", @cpu_reset_pending)
|
|
56
|
+
pending = input.ints("host.pending_keys", [])
|
|
57
|
+
@pending_keys = input.bool("host.typing", !pending.empty?) ? pending.dup : nil
|
|
58
|
+
@init_handlers_lost = [input.int("host.init_pending", 0) - @init_handlers.length, 0].max
|
|
59
|
+
load_holding_fields(input)
|
|
60
|
+
@typist.load_fields(input, "host.typist.")
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Which CPU has the bus and whose turn it is, from the MMU and the
|
|
64
|
+
# schedulers' offsets, and the serial bus's lines.
|
|
65
|
+
def machine_restored!
|
|
66
|
+
@z80_running = @bus.z80?
|
|
67
|
+
@z80_turn = @z80_running || @chips_ahead.positive?
|
|
68
|
+
push_serial_lines
|
|
69
|
+
push_fast_serial
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
# C= held from power-on until the machine reaches C64 mode
|
|
75
|
+
# (Modes#hold_commodore_key).
|
|
76
|
+
def load_holding_fields(input)
|
|
77
|
+
holding = input.bool("host.holding_commodore", @holding_commodore)
|
|
78
|
+
keyboard.release(:cbm) if @holding_commodore && !holding
|
|
79
|
+
keyboard.press(:cbm) if holding && !@holding_commodore
|
|
80
|
+
@holding_commodore = holding
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# How this machine was built.
|
|
84
|
+
def snapshot_setup
|
|
85
|
+
Snapshot::C128Setup.new(model: @model.name, sid_model: @sid.model, mode: @c64_built ? :c64 : :c128)
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
include KeyedState
|
|
90
|
+
end
|
|
91
|
+
end
|
data/lib/badline/c128/keys.rb
CHANGED
|
@@ -21,6 +21,11 @@ module Badline
|
|
|
21
21
|
@bus.caps_lock = false
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
+
# Pushes CAPS LOCK, down if it was up and up if it was down.
|
|
25
|
+
def push_caps_lock
|
|
26
|
+
@bus.caps_lock = !@bus.caps_lock
|
|
27
|
+
end
|
|
28
|
+
|
|
24
29
|
# The 40/80 DISPLAY key locks down and up. The KERNAL reads it at reset
|
|
25
30
|
# and starts the screen editor on the VDC's 80 columns while it is down.
|
|
26
31
|
def press_display_key
|
|
@@ -30,6 +35,10 @@ module Badline
|
|
|
30
35
|
def release_display_key
|
|
31
36
|
@bus.mmu.display_key = false
|
|
32
37
|
end
|
|
38
|
+
|
|
39
|
+
def push_display_key
|
|
40
|
+
@bus.mmu.display_key = !@bus.mmu.display_key
|
|
41
|
+
end
|
|
33
42
|
end
|
|
34
43
|
end
|
|
35
44
|
end
|
data/lib/badline/c128/mmu.rb
CHANGED
|
@@ -151,16 +151,17 @@ module Badline
|
|
|
151
151
|
end
|
|
152
152
|
end
|
|
153
153
|
|
|
154
|
-
# The registers and the
|
|
155
|
-
#
|
|
156
|
-
|
|
157
|
-
|
|
154
|
+
# The registers and the page pointers' high bytes waiting for their
|
|
155
|
+
# low bytes, in a keyed snapshot module (Snapshot::Keyed). The bus
|
|
156
|
+
# maps its banks from them afterwards.
|
|
157
|
+
def save_fields(out)
|
|
158
|
+
out.bytes("registers", @registers).int("p0h_latch", @p0h_latch).int("p1h_latch", @p1h_latch)
|
|
158
159
|
end
|
|
159
160
|
|
|
160
|
-
def
|
|
161
|
-
input.
|
|
162
|
-
@p0h_latch = input.
|
|
163
|
-
@p1h_latch = input.
|
|
161
|
+
def load_fields(input)
|
|
162
|
+
input.bytes_into("registers", @registers)
|
|
163
|
+
@p0h_latch = input.masked("p0h_latch", @p0h_latch, 0x0f)
|
|
164
|
+
@p1h_latch = input.masked("p1h_latch", @p1h_latch, 0x0f)
|
|
164
165
|
end
|
|
165
166
|
|
|
166
167
|
# CR and the LCRs at $FF00-$FF04: an LCR reads its PCR.
|
|
@@ -46,6 +46,33 @@ module Badline
|
|
|
46
46
|
end
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
+
# The system ROM's byte at +addr+, $8000 or above, as CR value 0 maps it.
|
|
50
|
+
def system_rom_peek(addr)
|
|
51
|
+
if addr < 0xc000
|
|
52
|
+
@basic_high_rom.peek(addr)
|
|
53
|
+
elsif addr < 0xd000
|
|
54
|
+
@editor_rom.peek(addr)
|
|
55
|
+
elsif addr < 0xe000
|
|
56
|
+
@c128_character_rom.peek(addr)
|
|
57
|
+
else
|
|
58
|
+
@c128_kernal_rom.peek(addr)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# The chip's byte at +addr+, in $D000-$DFFF, as C128 mode's I/O maps it.
|
|
63
|
+
def bank_io_peek(addr)
|
|
64
|
+
lay_out_io(@bank_io_reads, @bank_io_writes)
|
|
65
|
+
@bank_io_reads[0xd5] = @mmu
|
|
66
|
+
@bank_io_reads[addr >> 8].peek(addr)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
# Writes the chip at +addr+, in $D000-$DFFF, as C128 mode's I/O maps it.
|
|
70
|
+
def bank_io_poke(addr, value)
|
|
71
|
+
lay_out_io(@bank_io_reads, @bank_io_writes)
|
|
72
|
+
@bank_io_writes[0xd5] = @mmu
|
|
73
|
+
@bank_io_writes[addr >> 8].poke(addr, value)
|
|
74
|
+
end
|
|
75
|
+
|
|
49
76
|
# The bank CR picks, with common RAM in bank 0, then the pages page 0
|
|
50
77
|
# and page 1 move to.
|
|
51
78
|
def map_ram_pages
|
data/lib/badline/c128/modes.rb
CHANGED
|
@@ -46,15 +46,25 @@ module Badline
|
|
|
46
46
|
|
|
47
47
|
# The keyboard buffer of the KERNAL the machine runs: the C64's, or in
|
|
48
48
|
# C128 mode BASIC 7.0's.
|
|
49
|
-
def
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
@
|
|
49
|
+
def keyboard_buffer
|
|
50
|
+
mode == :c64 ? Machine::KeyboardBuffer::C64_LAYOUT : Machine::KeyboardBuffer::C128_LAYOUT
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Types the text type_text left: into the keyboard buffer, or while
|
|
54
|
+
# the Z80 runs, as under CP/M, where no KERNAL reads the buffer, on
|
|
55
|
+
# the key matrix, all of it once begun there.
|
|
56
|
+
def type_pending
|
|
57
|
+
if @z80_running || @typist.typing?
|
|
58
|
+
type_on_matrix
|
|
59
|
+
else
|
|
60
|
+
feed_keyboard
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def type_on_matrix
|
|
65
|
+
pending = @pending_keys
|
|
66
|
+
@typist.cycle!(pending)
|
|
67
|
+
@pending_keys = nil if pending.empty? && !@typist.typing?
|
|
58
68
|
end
|
|
59
69
|
end
|
|
60
70
|
end
|
data/lib/badline/c128.rb
CHANGED
|
@@ -8,12 +8,14 @@ require "badline/c128/io_pages"
|
|
|
8
8
|
require "badline/c128/z80_pages"
|
|
9
9
|
require "badline/c128/color_lines"
|
|
10
10
|
require "badline/c128/banks"
|
|
11
|
-
require "badline/c128/bus/
|
|
11
|
+
require "badline/c128/bus/keyed_state"
|
|
12
12
|
require "badline/c128/bus"
|
|
13
13
|
require "badline/c128/cpu"
|
|
14
14
|
require "badline/c128/z80"
|
|
15
15
|
require "badline/c128/z80_turns"
|
|
16
|
-
require "badline/
|
|
16
|
+
require "badline/snapshot/c128_setup"
|
|
17
|
+
require "badline/c128/keyed_state"
|
|
18
|
+
require "badline/c128/keyed_modules"
|
|
17
19
|
require "badline/c128/keys"
|
|
18
20
|
require "badline/c128/modes"
|
|
19
21
|
require "badline/c128/drives"
|
|
@@ -43,8 +45,9 @@ module Badline
|
|
|
43
45
|
# mirrors, and $D500-$D7FF holds the hidden MMU, the VDC and open bus.
|
|
44
46
|
class C128
|
|
45
47
|
include IntegerHelper
|
|
46
|
-
include KeyboardBuffer
|
|
48
|
+
include Machine::KeyboardBuffer
|
|
47
49
|
include Machine::Clocking
|
|
50
|
+
include Machine::Settling
|
|
48
51
|
include C64::Common
|
|
49
52
|
include C64::Attachments
|
|
50
53
|
include C64::KernalTraps
|
|
@@ -67,10 +70,6 @@ module Badline
|
|
|
67
70
|
# BASIC 7.0's, which is READY by then.
|
|
68
71
|
C128_INIT_THRESHOLD = 2_000_000
|
|
69
72
|
|
|
70
|
-
# The C128 KERNAL's keyboard buffer and its count.
|
|
71
|
-
C128_KEYBOARD_BUFFER = 0x034a
|
|
72
|
-
C128_KEYBOARD_COUNT = 0xd0
|
|
73
|
-
|
|
74
73
|
attr_reader :cpu, :cycles, :drive1541, :model, :init_threshold
|
|
75
74
|
|
|
76
75
|
def family = :c128
|
|
@@ -140,6 +139,7 @@ module Badline
|
|
|
140
139
|
@restore_pulse = false
|
|
141
140
|
@init_handlers = []
|
|
142
141
|
@pending_keys = nil
|
|
142
|
+
@typist = Input::MatrixTypist.new(@bus.keyboard)
|
|
143
143
|
@capture_output = nil
|
|
144
144
|
init_drives
|
|
145
145
|
enter_c64_mode if @c64_built
|
|
@@ -154,7 +154,7 @@ module Badline
|
|
|
154
154
|
return z80_cycle! if @z80_turn
|
|
155
155
|
|
|
156
156
|
handle_init if @cycles == @init_threshold
|
|
157
|
-
|
|
157
|
+
type_pending if @pending_keys
|
|
158
158
|
|
|
159
159
|
clock_bits = @clock_bits
|
|
160
160
|
@clock_bits = @vic.clock_bits
|
|
@@ -37,50 +37,6 @@ module Badline
|
|
|
37
37
|
def push_serial_lines
|
|
38
38
|
@iec_bus.host_lines = @cia2.port_a_lines
|
|
39
39
|
end
|
|
40
|
-
|
|
41
|
-
def save_cartridge(out)
|
|
42
|
-
cartridge = address_bus.cartridge
|
|
43
|
-
out.boolean(!cartridge.nil?)
|
|
44
|
-
cartridge&.save_setup(out)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# A cartridge comes back built afresh from the setup it was built
|
|
48
|
-
# with, before the address bus puts its state into it.
|
|
49
|
-
def load_cartridge(input)
|
|
50
|
-
if input.boolean?
|
|
51
|
-
connect_cartridge(Cartridge.from_setup(input))
|
|
52
|
-
elsif address_bus.cartridge
|
|
53
|
-
address_bus.detach_cartridge
|
|
54
|
-
end
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# A true 1541 on the serial bus, then a 1581.
|
|
58
|
-
def save_serial_bus(out)
|
|
59
|
-
out.boolean(!@drive1541.nil?)
|
|
60
|
-
if @drive1541
|
|
61
|
-
out.int(@drive1541.device)
|
|
62
|
-
@drive1541.save_state(out)
|
|
63
|
-
end
|
|
64
|
-
save_drive1581(out)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def load_serial_bus(input)
|
|
68
|
-
load_drive1541(input)
|
|
69
|
-
load_drive1581(input)
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
# The REU, which the setup says the machine has, and whether it has
|
|
73
|
-
# asked for the bus. Its IRQ line reaches the CPU as it was.
|
|
74
|
-
def save_reu(out)
|
|
75
|
-
@reu&.save_state(out)
|
|
76
|
-
out.boolean(@dma)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def load_reu(input)
|
|
80
|
-
@reu&.load_state(input)
|
|
81
|
-
@reu_irq = @reu ? @reu.irq? : false
|
|
82
|
-
@dma = input.boolean?
|
|
83
|
-
end
|
|
84
40
|
end
|
|
85
41
|
end
|
|
86
42
|
end
|
|
@@ -33,18 +33,26 @@ module Badline
|
|
|
33
33
|
|
|
34
34
|
def type = :plus256k
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
@banks.
|
|
36
|
+
# $D100 as the banks it picks give it, whether it is locked, and
|
|
37
|
+
# banks 1 to 3, in a keyed snapshot module.
|
|
38
|
+
def save_fields(out)
|
|
39
|
+
low = @banks.index(@low_ram).to_i
|
|
40
|
+
video = @banks.index(@video_ram).to_i
|
|
41
|
+
out.int("d100", low | (video << 2) | (@banks.index(@high_ram).to_i << 6)).bool("locked", @locked)
|
|
42
|
+
@banks[1].save_fields(out, "bank1")
|
|
43
|
+
@banks[2].save_fields(out, "bank2")
|
|
44
|
+
@banks[3].save_fields(out, "bank3")
|
|
40
45
|
end
|
|
41
46
|
|
|
42
|
-
def
|
|
43
|
-
|
|
44
|
-
@
|
|
45
|
-
@
|
|
46
|
-
@
|
|
47
|
-
@
|
|
47
|
+
def load_fields(input)
|
|
48
|
+
value = input.byte("d100", 0)
|
|
49
|
+
@low_ram = @banks[value & 0b11]
|
|
50
|
+
@video_ram = @banks[(value >> 2) & 0b11]
|
|
51
|
+
@high_ram = @banks[value >> 6]
|
|
52
|
+
@locked = input.bool("locked", @locked)
|
|
53
|
+
@banks[1].load_fields(input, "bank1")
|
|
54
|
+
@banks[2].load_fields(input, "bank2")
|
|
55
|
+
@banks[3].load_fields(input, "bank3")
|
|
48
56
|
end
|
|
49
57
|
|
|
50
58
|
def power_on!
|
|
@@ -26,14 +26,16 @@ module Badline
|
|
|
26
26
|
|
|
27
27
|
def type = :plus60k
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
29
|
+
# $D100 as bit 7 picks the bank above $1000, and bank 1, in a
|
|
30
|
+
# keyed snapshot module.
|
|
31
|
+
def save_fields(out)
|
|
32
|
+
out.int("d100", @banks.index(@high_ram).to_i << 7)
|
|
33
|
+
@banks[1].save_fields(out, "bank1")
|
|
32
34
|
end
|
|
33
35
|
|
|
34
|
-
def
|
|
35
|
-
@high_ram = @banks
|
|
36
|
-
@banks[1].
|
|
36
|
+
def load_fields(input)
|
|
37
|
+
@high_ram = @banks[(input.byte("d100", @banks.index(@high_ram).to_i << 7) >> 7) & 1]
|
|
38
|
+
@banks[1].load_fields(input, "bank1")
|
|
37
39
|
end
|
|
38
40
|
|
|
39
41
|
def power_on!
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class C64
|
|
5
|
+
class Bus
|
|
6
|
+
# The VICE debug cartridge register, mapped at $D7FF on the C64. It is a
|
|
7
|
+
# VICE facility rather than real hardware, enabled there with -debugcart:
|
|
8
|
+
# writing a byte ends the run with that value as the exit code. The VICE
|
|
9
|
+
# test suites write $00 for success and $ff for failure.
|
|
10
|
+
#
|
|
11
|
+
# Wraps the SID's top mirror page, so every other access falls through.
|
|
12
|
+
class DebugRegister
|
|
13
|
+
ADDRESS = 0xd7ff
|
|
14
|
+
|
|
15
|
+
def initialize(sid, &handler)
|
|
16
|
+
@sid = sid
|
|
17
|
+
@handler = handler
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def peek(addr)
|
|
21
|
+
@sid.peek(addr)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def poke(addr, value)
|
|
25
|
+
return @handler.call(value) if addr == ADDRESS
|
|
26
|
+
|
|
27
|
+
@sid.poke(addr, value)
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -7,7 +7,16 @@ module Badline
|
|
|
7
7
|
# them, each over its 32 bytes of the I/O area (SIDSlots). The SID
|
|
8
8
|
# player's machine has nothing else in I/O 1 and 2, so the rest of a
|
|
9
9
|
# page there reads the open bus.
|
|
10
|
+
#
|
|
11
|
+
# A snapshot holds each in its own keyed module, BL-SID2 onwards in the
|
|
12
|
+
# order they were fitted, with the address it sits at and its model
|
|
13
|
+
# ahead of the SID's own fields.
|
|
10
14
|
module ExtraSIDs
|
|
15
|
+
SID_MODEL_NAMES = %w[mos6581 mos8580].freeze
|
|
16
|
+
|
|
17
|
+
# The SIDs fitted past the first, in the order they were fitted.
|
|
18
|
+
attr_reader :extra_sids
|
|
19
|
+
|
|
11
20
|
# Fits a SID at the address it was built at, where it takes its 32
|
|
12
21
|
# bytes over from whatever maps there.
|
|
13
22
|
def add_sid(sid)
|
|
@@ -18,14 +27,85 @@ module Badline
|
|
|
18
27
|
@sid_slots << slots
|
|
19
28
|
end
|
|
20
29
|
slots.place(sid)
|
|
30
|
+
@extra_sids << sid
|
|
31
|
+
update_overlays!
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Takes the extra SIDs out, giving their addresses back to what maps
|
|
35
|
+
# there.
|
|
36
|
+
def remove_extra_sids
|
|
37
|
+
@sid_slots.clear
|
|
38
|
+
@extra_sids.clear
|
|
21
39
|
update_overlays!
|
|
22
40
|
end
|
|
23
41
|
|
|
42
|
+
def save_extra_sid_modules(sections)
|
|
43
|
+
@extra_sids.each_with_index do |sid, index|
|
|
44
|
+
sections << Snapshot::Keyed.section("BL-SID#{index + 2}") do |out|
|
|
45
|
+
out.int("address", sid.start).text("model", sid.model.to_s)
|
|
46
|
+
sid.save_fields(out)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
sections
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# Fits the extra SIDs the snapshot's modules hold and loads them. A
|
|
53
|
+
# SID already fitted at the same address stays, on the model the
|
|
54
|
+
# snapshot names, and one the snapshot hasn't comes out. A module
|
|
55
|
+
# whose address no SID fits at is left out, and reported.
|
|
56
|
+
def load_extra_sid_modules(modules)
|
|
57
|
+
addresses = []
|
|
58
|
+
inputs = extra_sid_inputs(modules, addresses)
|
|
59
|
+
models = inputs.map { |input| sid_model_named(input.choice("model", SID_MODEL_NAMES, "mos6581")) }
|
|
60
|
+
refit_sids(addresses, models)
|
|
61
|
+
@extra_sids.each_with_index do |sid, index|
|
|
62
|
+
model = models[index]
|
|
63
|
+
sid.model = model unless sid.model == model
|
|
64
|
+
sid.load_fields(inputs[index])
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
24
68
|
private
|
|
25
69
|
|
|
26
70
|
def map_extra_sids
|
|
27
71
|
@sid_slots.each { |slots| @read_pages[slots.page] = @write_pages[slots.page] = slots }
|
|
28
72
|
end
|
|
73
|
+
|
|
74
|
+
def extra_sid_inputs(modules, taken)
|
|
75
|
+
inputs = []
|
|
76
|
+
number = 2
|
|
77
|
+
input = modules.optional("BL-SID2")
|
|
78
|
+
while input
|
|
79
|
+
address = input.word("address", 0xd420)
|
|
80
|
+
if sid_fits?(address) && !taken.include?(address)
|
|
81
|
+
inputs << input
|
|
82
|
+
taken << address
|
|
83
|
+
else
|
|
84
|
+
input.adjust(format("no SID fits at $%04x, so it's left out", address))
|
|
85
|
+
end
|
|
86
|
+
number += 1
|
|
87
|
+
input = modules.optional("BL-SID#{number}")
|
|
88
|
+
end
|
|
89
|
+
inputs
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# A SID's 32 bytes past the first SID's own, in $D420-$D7FF, or in
|
|
93
|
+
# I/O 1 or 2.
|
|
94
|
+
def sid_fits?(address)
|
|
95
|
+
address.nobits?(0x1f) && ((0xd420..0xd7e0).cover?(address) || (0xde00..0xdfe0).cover?(address))
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def sid_model_named(name) = name == "mos8580" ? :mos8580 : :mos6581
|
|
99
|
+
|
|
100
|
+
def refit_sids(addresses, models)
|
|
101
|
+
fitted = @extra_sids.dup
|
|
102
|
+
return if fitted.map(&:start) == addresses
|
|
103
|
+
|
|
104
|
+
remove_extra_sids
|
|
105
|
+
addresses.each_with_index do |address, index|
|
|
106
|
+
add_sid(fitted.find { |sid| sid.start == address } || Chips::SID.new(model: models[index], at: address))
|
|
107
|
+
end
|
|
108
|
+
end
|
|
29
109
|
end
|
|
30
110
|
end
|
|
31
111
|
end
|