badline 0.13.0 → 0.14.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 +49 -1
- data/CLAUDE.md +27 -7
- data/CONTRIBUTING.md +4 -3
- data/README.md +8 -5
- data/doc/media.md +2 -1
- data/doc/pinned-behaviour.md +29 -0
- data/doc/snapshot-format.md +1047 -0
- data/doc/snapshots.md +72 -39
- data/lib/badline/audio/bare_player.rb +50 -17
- data/lib/badline/audio/machine_player.rb +15 -9
- data/lib/badline/audio/renderer.rb +32 -21
- data/lib/badline/c128/banks.rb +6 -3
- data/lib/badline/c128/bus/keyed_state.rb +45 -0
- data/lib/badline/c128/bus.rb +17 -3
- 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 +20 -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/keyed_state.rb +41 -0
- data/lib/badline/c64/bus.rb +2 -1
- data/lib/badline/c64/cartridge/action_replay.rb +0 -13
- 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 +0 -12
- data/lib/badline/c64/cartridge/flash.rb +3 -3
- data/lib/badline/c64/cartridge/g_mod2.rb +0 -12
- 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 +393 -0
- data/lib/badline/c64/cartridge/pagefox.rb +0 -10
- data/lib/badline/c64/cartridge/retro_replay.rb +0 -8
- data/lib/badline/c64/cartridge/rgcd.rb +0 -10
- data/lib/badline/c64/cartridge/super_games.rb +0 -10
- data/lib/badline/c64/cartridge/zaxxon.rb +0 -16
- data/lib/badline/c64/cartridge.rb +1 -27
- data/lib/badline/c64/kernal_traps.rb +28 -25
- data/lib/badline/c64/keyed_modules.rb +111 -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 +119 -0
- data/lib/badline/chips/ted/timers.rb +66 -0
- data/lib/badline/chips/ted.rb +143 -0
- data/lib/badline/chips/tia.rb +49 -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 +38 -0
- data/lib/badline/drives/datasette.rb +40 -7
- 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 +1 -1
- data/lib/badline/frontend/controls.rb +19 -3
- data/lib/badline/frontend/drive_led.rb +44 -21
- data/lib/badline/frontend/menu/menu_dialogs.rb +2 -2
- data/lib/badline/frontend/snapshots.rb +12 -1
- data/lib/badline/frontend/timeline.rb +28 -10
- 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 +5 -2
- data/lib/badline/media/boot_disk.rb +14 -2
- data/lib/badline/media/extensions.rb +10 -0
- data/lib/badline/memory.rb +3 -6
- data/lib/badline/options/family.rb +5 -2
- data/lib/badline/options/help.rb +42 -16
- data/lib/badline/options/table.rb +2 -0
- data/lib/badline/options/validation.rb +2 -0
- data/lib/badline/options.rb +6 -1
- data/lib/badline/plus4/acia.rb +45 -0
- data/lib/badline/plus4/bus.rb +312 -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 +51 -0
- data/lib/badline/plus4/model.rb +38 -0
- data/lib/badline/plus4/user_port.rb +31 -0
- data/lib/badline/plus4.rb +164 -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 +4 -0
- data/lib/badline/snapshot/field_doc/markdown.rb +112 -0
- data/lib/badline/snapshot/field_doc.rb +109 -0
- data/lib/badline/snapshot/image.rb +134 -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/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 +43 -20
- data/lib/badline/storage/crt_file.rb +3 -1
- data/lib/badline/storage/g64_image.rb +8 -3
- data/lib/badline/storage/tap.rb +43 -15
- 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 +61 -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,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,26 @@ 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
|
+
|
|
49
69
|
# The bank CR picks, with common RAM in bank 0, then the pages page 0
|
|
50
70
|
# and page 1 move to.
|
|
51
71
|
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
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class C64
|
|
5
|
+
class Bus
|
|
6
|
+
# The 6510's port under port.* in a keyed snapshot module
|
|
7
|
+
# (Snapshot::Keyed, BL-CPU), and the bus once its memories, the port
|
|
8
|
+
# and the cartridge are loaded: the banks the CPU and the VIC see are
|
|
9
|
+
# worked out again.
|
|
10
|
+
module KeyedState
|
|
11
|
+
# The RAM expansion fitted, or an Unexpanded stand-in.
|
|
12
|
+
attr_reader :ram_expansion
|
|
13
|
+
|
|
14
|
+
# Takes the cartridge out of the expansion port, as a restore does for
|
|
15
|
+
# a snapshot without one.
|
|
16
|
+
def detach_cartridge
|
|
17
|
+
@cartridge = nil
|
|
18
|
+
update_overlays!
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# The 6510 port's direction and output registers, and the charge left
|
|
22
|
+
# on its floating bits.
|
|
23
|
+
def port_state = [@cpu_port.ddr, @cpu_port.data, @cpu_port.floating]
|
|
24
|
+
|
|
25
|
+
# Sets the port as port_state reads it, as a snapshot restores it,
|
|
26
|
+
# leaving the RAM under $00 and $01 alone.
|
|
27
|
+
def restore_port(ddr, out, floating)
|
|
28
|
+
@cpu_port.restore(ddr, out, floating)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def save_port_fields(out) = @cpu_port.save_fields(out, "port.")
|
|
32
|
+
|
|
33
|
+
def load_port_fields(input) = @cpu_port.load_fields(input, "port.")
|
|
34
|
+
|
|
35
|
+
def restored! = update_overlays!
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
include KeyedState
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
data/lib/badline/c64/bus.rb
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "badline/c64/bus/
|
|
3
|
+
require "badline/c64/bus/keyed_state"
|
|
4
4
|
require "badline/c64/bus/sid_slots"
|
|
5
5
|
require "badline/c64/bus/extra_sids"
|
|
6
6
|
require "badline/c64/bus/pla"
|
|
7
7
|
require "badline/c64/bus/roms"
|
|
8
8
|
require "badline/c64/bus/fittings"
|
|
9
|
+
require "badline/c64/bus/debug_register"
|
|
9
10
|
|
|
10
11
|
module Badline
|
|
11
12
|
# Memory layout:
|
|
@@ -65,19 +65,6 @@ module Badline
|
|
|
65
65
|
|
|
66
66
|
private
|
|
67
67
|
|
|
68
|
-
def save_mapper(out)
|
|
69
|
-
super
|
|
70
|
-
out.int(window_index(@rom, windows)).boolean(@active).boolean(@io2_ram).blob(@ram_data)
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def load_mapper(input)
|
|
74
|
-
super
|
|
75
|
-
@rom = window_at(input.int, windows)
|
|
76
|
-
@active = input.boolean?
|
|
77
|
-
@io2_ram = input.boolean?
|
|
78
|
-
input.blob_into(@ram_data)
|
|
79
|
-
end
|
|
80
|
-
|
|
81
68
|
def windows = [@through, @isolated, @contended, *@rom_banks, EMPTY_BANK]
|
|
82
69
|
|
|
83
70
|
def io2_peek(addr)
|
|
@@ -88,21 +88,6 @@ module Badline
|
|
|
88
88
|
@romh = @high_flash.window(@bank * BANK_SIZE)
|
|
89
89
|
end
|
|
90
90
|
|
|
91
|
-
def save_mapper(out)
|
|
92
|
-
out.int(@bank).int(@control).blob(@io_ram)
|
|
93
|
-
@low_flash.save_state(out)
|
|
94
|
-
@high_flash.save_state(out)
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def load_mapper(input)
|
|
98
|
-
@bank = input.int
|
|
99
|
-
@control = input.int
|
|
100
|
-
input.blob_into(@io_ram)
|
|
101
|
-
@low_flash.load_state(input)
|
|
102
|
-
@high_flash.load_state(input)
|
|
103
|
-
map_bank
|
|
104
|
-
end
|
|
105
|
-
|
|
106
91
|
def apply_control
|
|
107
92
|
game = @control.nobits?(0x04) || @control.anybits?(0x01)
|
|
108
93
|
exrom = @control.anybits?(0x02)
|
|
@@ -61,18 +61,6 @@ module Badline
|
|
|
61
61
|
|
|
62
62
|
private
|
|
63
63
|
|
|
64
|
-
def save_mapper(out)
|
|
65
|
-
super
|
|
66
|
-
out.boolean(@register_visible).boolean(@phi1_ultimax)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def load_mapper(input)
|
|
70
|
-
super
|
|
71
|
-
@io_bank = @roml
|
|
72
|
-
@register_visible = input.boolean?
|
|
73
|
-
@phi1_ultimax = input.boolean?
|
|
74
|
-
end
|
|
75
|
-
|
|
76
64
|
def windows = [*@roml_banks, *@romh_banks, EMPTY_BANK]
|
|
77
65
|
|
|
78
66
|
def select(number)
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "badline/c64/cartridge/flash/saved_state"
|
|
4
|
-
|
|
5
3
|
module Badline
|
|
6
4
|
class C64
|
|
7
5
|
class Cartridge
|
|
@@ -69,7 +67,9 @@ module Badline
|
|
|
69
67
|
alias [] peek
|
|
70
68
|
end
|
|
71
69
|
|
|
72
|
-
|
|
70
|
+
# The command states, which a snapshot names.
|
|
71
|
+
STATES = %i[read program_setup autoselect programming erase_window erasing suspended chip_erase
|
|
72
|
+
program_error].freeze
|
|
73
73
|
|
|
74
74
|
attr_reader :data, :state
|
|
75
75
|
attr_writer :clock
|
|
@@ -48,18 +48,6 @@ module Badline
|
|
|
48
48
|
changed!
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
def save_mapper(out)
|
|
52
|
-
out.int(@bank).boolean(@flash_writes)
|
|
53
|
-
@flash.save_state(out)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def load_mapper(input)
|
|
57
|
-
@bank = input.int
|
|
58
|
-
@flash_writes = input.boolean?
|
|
59
|
-
@flash.load_state(input)
|
|
60
|
-
@roml = @flash.window(@bank * BANK_SIZE)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
51
|
def install_chips(chips)
|
|
64
52
|
data = Array.new(BANKS * BANK_SIZE, 0xff)
|
|
65
53
|
chips.each do |chip|
|
|
@@ -53,24 +53,8 @@ module Badline
|
|
|
53
53
|
@block = @page = @window = 0
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
-
# A GEO-RAM is built from its size alone.
|
|
57
|
-
def save_setup(out)
|
|
58
|
-
out.int(GEO_RAM_SETUP).int(@size)
|
|
59
|
-
end
|
|
60
|
-
|
|
61
56
|
private
|
|
62
57
|
|
|
63
|
-
def save_mapper(out)
|
|
64
|
-
out.blob(@ram_data).int(@block).int(@page).int(@window)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def load_mapper(input)
|
|
68
|
-
input.blob_into(@ram_data)
|
|
69
|
-
@block = input.int
|
|
70
|
-
@page = input.int
|
|
71
|
-
@window = input.int
|
|
72
|
-
end
|
|
73
|
-
|
|
74
58
|
def install_chips(_chips)
|
|
75
59
|
@ram_data = Array.new(@size * 1024, 0)
|
|
76
60
|
reset
|
|
@@ -56,14 +56,6 @@ module Badline
|
|
|
56
56
|
|
|
57
57
|
private
|
|
58
58
|
|
|
59
|
-
def save_mapper(out)
|
|
60
|
-
out.blob(@io_ram)
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def load_mapper(input)
|
|
64
|
-
input.blob_into(@io_ram)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
59
|
def install_chips(chips)
|
|
68
60
|
roml, romh = banks_from(chips)
|
|
69
61
|
@roml = roml.first || EMPTY_BANK
|