badline 0.12.1 → 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 +66 -1
- data/CLAUDE.md +86 -38
- data/CONTRIBUTING.md +4 -3
- data/README.md +9 -6
- data/doc/library.md +9 -9
- data/doc/media.md +2 -1
- data/doc/pinned-behaviour.md +134 -105
- data/doc/snapshot-format.md +1047 -0
- data/doc/snapshots.md +73 -43
- data/lib/badline/audio/bare_player.rb +53 -20
- data/lib/badline/audio/cli.rb +6 -6
- data/lib/badline/audio/jukebox.rb +2 -2
- data/lib/badline/audio/machine_player.rb +16 -10
- data/lib/badline/{media → audio}/queue.rb +1 -1
- data/lib/badline/audio/queued_tune.rb +6 -6
- data/lib/badline/audio/renderer.rb +33 -22
- data/lib/badline/audio/stereo.rb +1 -1
- data/lib/badline/c128/banks.rb +6 -3
- data/lib/badline/c128/bus/keyed_state.rb +45 -0
- data/lib/badline/c128/bus.rb +35 -20
- data/lib/badline/c128/color_lines.rb +2 -2
- data/lib/badline/c128/cpu.rb +1 -1
- data/lib/badline/c128/drives.rb +14 -34
- data/lib/badline/c128/fast_serial.rb +5 -5
- 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 +21 -1
- data/lib/badline/c128/modes.rb +21 -11
- data/lib/badline/c128/z80.rb +2 -2
- data/lib/badline/c128/z80_turns.rb +1 -1
- data/lib/badline/c128.rb +21 -16
- data/lib/badline/c64/attachments.rb +42 -0
- data/lib/badline/c64/banked_ram/banking.rb +32 -0
- data/lib/badline/c64/banked_ram/plus256k.rb +64 -0
- data/lib/badline/c64/banked_ram/plus60k.rb +47 -0
- data/lib/badline/c64/banked_ram/unexpanded.rb +30 -0
- data/lib/badline/c64/banked_ram.rb +23 -0
- data/lib/badline/c64/bus/debug_register.rb +32 -0
- data/lib/badline/c64/bus/extra_sids.rb +32 -0
- data/lib/badline/c64/bus/fittings.rb +40 -0
- data/lib/badline/c64/bus/keyed_state.rb +41 -0
- data/lib/badline/c64/bus/pla.rb +149 -0
- data/lib/badline/c64/bus/roms.rb +41 -0
- data/lib/badline/c64/bus/sid_slots.rb +44 -0
- data/lib/badline/c64/bus.rb +219 -0
- data/lib/badline/c64/cartridge/action_replay.rb +115 -0
- data/lib/badline/c64/cartridge/atomic_power.rb +26 -0
- data/lib/badline/c64/cartridge/bank.rb +83 -0
- data/lib/badline/c64/cartridge/comal80.rb +52 -0
- data/lib/badline/c64/cartridge/dinamic.rb +36 -0
- data/lib/badline/c64/cartridge/easy_flash.rb +132 -0
- data/lib/badline/c64/cartridge/epyx_fastload.rb +73 -0
- data/lib/badline/c64/cartridge/final_cartridge3.rb +79 -0
- data/lib/badline/c64/cartridge/flash.rb +279 -0
- data/lib/badline/c64/cartridge/freezer.rb +35 -0
- data/lib/badline/c64/cartridge/fun_play.rb +40 -0
- data/lib/badline/c64/cartridge/g_mod2.rb +64 -0
- data/lib/badline/c64/cartridge/game_system.rb +42 -0
- data/lib/badline/c64/cartridge/geo_ram.rb +65 -0
- data/lib/badline/c64/cartridge/kcs_power.rb +69 -0
- data/lib/badline/c64/cartridge/keyed_state.rb +393 -0
- data/lib/badline/c64/cartridge/mach5.rb +34 -0
- data/lib/badline/c64/cartridge/magic_desk.rb +32 -0
- data/lib/badline/c64/cartridge/ocean.rb +37 -0
- data/lib/badline/c64/cartridge/pagefox.rb +60 -0
- data/lib/badline/c64/cartridge/retro_replay.rb +278 -0
- data/lib/badline/c64/cartridge/rex_utility.rb +31 -0
- data/lib/badline/c64/cartridge/rgcd.rb +50 -0
- data/lib/badline/c64/cartridge/simons_basic.rb +37 -0
- data/lib/badline/c64/cartridge/standard.rb +17 -0
- data/lib/badline/c64/cartridge/super_games.rb +40 -0
- data/lib/badline/c64/cartridge/westermann.rb +32 -0
- data/lib/badline/c64/cartridge/zaxxon.rb +52 -0
- data/lib/badline/c64/cartridge.rb +232 -0
- data/lib/badline/c64/color_memory.rb +27 -0
- data/lib/badline/{computer → c64}/common.rb +2 -2
- data/lib/badline/{computer → c64}/kernal_traps.rb +39 -36
- 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 +271 -0
- data/lib/badline/c64/reu/keyed_state.rb +140 -0
- data/lib/badline/c64/reu/ram.rb +94 -0
- data/lib/badline/c64/reu/trigger.rb +34 -0
- data/lib/badline/c64/reu.rb +289 -0
- data/lib/badline/c64/true_drives.rb +120 -0
- data/lib/badline/{computer.rb → c64.rb} +24 -15
- data/lib/badline/chips/cia/fast_forward.rb +62 -0
- data/lib/badline/chips/cia/interrupt_register.rb +128 -0
- data/lib/badline/chips/cia/keyed_parts.rb +213 -0
- data/lib/badline/chips/cia/serial.rb +246 -0
- data/lib/badline/chips/cia/time_of_day.rb +210 -0
- data/lib/badline/chips/cia/timer.rb +188 -0
- data/lib/badline/chips/cia.rb +281 -0
- data/lib/badline/chips/cpu/addressing.rb +133 -0
- data/lib/badline/chips/cpu/boundary.rb +56 -0
- data/lib/badline/chips/cpu/core.rb +183 -0
- data/lib/badline/chips/cpu/instruction.rb +338 -0
- data/lib/badline/chips/cpu/instruction_set/arithmetic.rb +118 -0
- data/lib/badline/chips/cpu/instruction_set/bitwise.rb +130 -0
- data/lib/badline/chips/cpu/instruction_set/branch.rb +83 -0
- data/lib/badline/chips/cpu/instruction_set/flag.rb +67 -0
- data/lib/badline/chips/cpu/instruction_set/illegal.rb +274 -0
- data/lib/badline/chips/cpu/instruction_set/inc_dec.rb +73 -0
- data/lib/badline/chips/cpu/instruction_set/stack.rb +56 -0
- data/lib/badline/chips/cpu/instruction_set/transfer.rb +141 -0
- data/lib/badline/chips/cpu/instruction_set.rb +59 -0
- data/lib/badline/chips/cpu/interrupts.rb +108 -0
- data/lib/badline/chips/cpu/keyed_state.rb +177 -0
- data/lib/badline/chips/cpu/microcode.rb +195 -0
- data/lib/badline/chips/cpu/operations.rb +90 -0
- data/lib/badline/chips/cpu/port.rb +133 -0
- data/lib/badline/chips/cpu/stack_operations.rb +84 -0
- data/lib/badline/chips/cpu/traps.rb +23 -0
- data/lib/badline/chips/cpu.rb +17 -0
- data/lib/badline/chips/sid/catch_up.rb +122 -0
- data/lib/badline/chips/sid/decimator.rb +68 -0
- data/lib/badline/chips/sid/envelope.rb +236 -0
- data/lib/badline/chips/sid/filter.rb +227 -0
- data/lib/badline/chips/sid/keyed_parts.rb +286 -0
- data/lib/badline/chips/sid/voice.rb +69 -0
- data/lib/badline/chips/sid/waveform/combined.rb +128 -0
- data/lib/badline/chips/sid/waveform/fast_forward.rb +107 -0
- data/lib/badline/chips/sid/waveform/noise_writeback.rb +124 -0
- data/lib/badline/chips/sid/waveform.rb +305 -0
- data/lib/badline/chips/sid.rb +264 -0
- 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/{c128 → chips}/vdc/memory.rb +1 -1
- data/lib/badline/{c128 → chips}/vdc/painter.rb +1 -13
- data/lib/badline/{c128 → chips}/vdc/raster.rb +1 -17
- data/lib/badline/{c128 → chips}/vdc/window.rb +1 -10
- data/lib/badline/{c128 → chips}/vdc.rb +6 -31
- data/lib/badline/chips/via/control_lines.rb +109 -0
- data/lib/badline/chips/via/fast_forward.rb +55 -0
- data/lib/badline/chips/via/interrupt_register.rb +60 -0
- data/lib/badline/chips/via/keyed_parts.rb +163 -0
- data/lib/badline/chips/via/shift_register.rb +168 -0
- data/lib/badline/chips/via/timer1.rb +120 -0
- data/lib/badline/chips/via/timer2.rb +117 -0
- data/lib/badline/chips/via.rb +267 -0
- data/lib/badline/chips/vic/bank.rb +135 -0
- data/lib/badline/chips/vic/border_mask.rb +78 -0
- data/lib/badline/chips/vic/collisions.rb +106 -0
- data/lib/badline/chips/vic/color_patches.rb +38 -0
- data/lib/badline/chips/vic/display_state.rb +168 -0
- data/lib/badline/chips/vic/graphics_mode.rb +166 -0
- data/lib/badline/chips/vic/graphics_shifter.rb +183 -0
- 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 +65 -0
- data/lib/badline/chips/vic/registers.rb +188 -0
- data/lib/badline/chips/vic/sequencer.rb +275 -0
- data/lib/badline/chips/vic/sequencer_output.rb +118 -0
- data/lib/badline/chips/vic/sprite/internal_bus.rb +59 -0
- data/lib/badline/chips/vic/sprite/shifter.rb +148 -0
- data/lib/badline/chips/vic/sprite/timing.rb +58 -0
- data/lib/badline/chips/vic/sprite.rb +337 -0
- data/lib/badline/chips/vic/sprites.rb +281 -0
- data/lib/badline/chips/vic.rb +787 -0
- data/lib/badline/chips/vic_i/keyed_parts.rb +142 -0
- data/lib/badline/{vic20/vic → chips/vic_i}/painter.rb +2 -30
- data/lib/badline/chips/vic_i/sound/output.rb +85 -0
- data/lib/badline/chips/vic_i/sound.rb +227 -0
- data/lib/badline/{vic20/vic → chips/vic_i}/text_window.rb +2 -2
- data/lib/badline/{vic20/vic.rb → chips/vic_i.rb} +6 -6
- data/lib/badline/chips/z80/arithmetic.rb +119 -0
- data/lib/badline/chips/z80/bit_page.rb +57 -0
- data/lib/badline/chips/z80/block_io.rb +60 -0
- data/lib/badline/chips/z80/block_transfers.rb +61 -0
- data/lib/badline/chips/z80/bus_cycles.rb +113 -0
- data/lib/badline/chips/z80/core.rb +115 -0
- data/lib/badline/chips/z80/exchanges.rb +52 -0
- data/lib/badline/chips/z80/extended_page.rb +91 -0
- data/lib/badline/chips/z80/flags.rb +39 -0
- data/lib/badline/chips/z80/interrupt_acceptance.rb +48 -0
- data/lib/badline/chips/z80/jumps.rb +84 -0
- data/lib/badline/chips/z80/keyed_state.rb +73 -0
- data/lib/badline/chips/z80/loads.rb +100 -0
- data/lib/badline/chips/z80/main_page.rb +136 -0
- data/lib/badline/chips/z80/registers.rb +122 -0
- data/lib/badline/chips/z80/shifts.rb +66 -0
- data/lib/badline/chips/z80.rb +13 -0
- data/lib/badline/chips.rb +10 -0
- data/lib/badline/core.rb +13 -32
- data/lib/badline/drives/datasette/keyed_state.rb +38 -0
- data/lib/badline/drives/datasette.rb +173 -0
- data/lib/badline/drives/engine/core.rb +152 -0
- data/lib/badline/drives/engine/fast_serial.rb +75 -0
- data/lib/badline/drives/engine/idle.rb +127 -0
- data/lib/badline/drives/engine/idle_cpu.rb +30 -0
- data/lib/badline/drives/engine/orbit.rb +81 -0
- data/lib/badline/drives/engine/serial_lines.rb +72 -0
- data/lib/badline/drives/engine/sleep.rb +114 -0
- data/lib/badline/drives/engine/vias.rb +86 -0
- data/lib/badline/drives/engine/watch.rb +152 -0
- data/lib/badline/drives/engine.rb +11 -0
- data/lib/badline/drives/model1541/bus.rb +75 -0
- data/lib/badline/drives/model1541/byte_ready.rb +50 -0
- data/lib/badline/drives/model1541/cpu.rb +13 -0
- data/lib/badline/drives/model1541/disk.rb +318 -0
- data/lib/badline/drives/model1541/disk_via.rb +38 -0
- data/lib/badline/drives/model1541/gcr.rb +59 -0
- data/lib/badline/drives/model1541/keyed_state.rb +251 -0
- data/lib/badline/drives/model1541/mechanism.rb +313 -0
- data/lib/badline/drives/model1541/rotation.rb +123 -0
- data/lib/badline/drives/model1541/sector_reader.rb +78 -0
- data/lib/badline/drives/model1541/serial_port.rb +20 -0
- data/lib/badline/drives/model1541/track.rb +100 -0
- data/lib/badline/drives/model1541.rb +80 -0
- data/lib/badline/drives/model1571/bus.rb +100 -0
- data/lib/badline/drives/model1571/cpu.rb +13 -0
- data/lib/badline/drives/model1571/keyed_state.rb +108 -0
- data/lib/badline/drives/model1571/serial_port.rb +39 -0
- data/lib/badline/drives/model1571/serial_via.rb +27 -0
- data/lib/badline/drives/model1571/wd1770.rb +108 -0
- data/lib/badline/drives/model1571.rb +141 -0
- data/lib/badline/drives/model1581/bus.rb +126 -0
- data/lib/badline/drives/model1581/cpu.rb +13 -0
- data/lib/badline/drives/model1581/disk.rb +133 -0
- data/lib/badline/drives/model1581/keyed_state.rb +280 -0
- data/lib/badline/drives/model1581/mechanism.rb +98 -0
- data/lib/badline/drives/model1581/serial_port.rb +54 -0
- data/lib/badline/drives/model1581/slot.rb +61 -0
- data/lib/badline/drives/model1581/track.rb +102 -0
- data/lib/badline/drives/model1581/track_bytes.rb +77 -0
- data/lib/badline/drives/model1581/wd1772/registers.rb +91 -0
- data/lib/badline/drives/model1581/wd1772/sector_writes.rb +75 -0
- data/lib/badline/drives/model1581/wd1772/sectors.rb +152 -0
- data/lib/badline/drives/model1581/wd1772/stepping.rb +111 -0
- data/lib/badline/drives/model1581/wd1772/tracks.rb +127 -0
- data/lib/badline/drives/model1581/wd1772/turn.rb +75 -0
- data/lib/badline/drives/model1581/wd1772.rb +216 -0
- data/lib/badline/drives/model1581.rb +206 -0
- data/lib/badline/drives/serial_bus.rb +161 -0
- data/lib/badline/drives.rb +8 -0
- data/lib/badline/frontend/app.rb +3 -3
- data/lib/badline/frontend/boot.rb +4 -4
- data/lib/badline/frontend/controls.rb +19 -3
- data/lib/badline/frontend/drive_led.rb +44 -21
- data/lib/badline/frontend/machine_window.rb +3 -1
- data/lib/badline/frontend/menu/menu_dialogs.rb +2 -2
- data/lib/badline/frontend/player/filter_view.rb +1 -1
- data/lib/badline/frontend/player/player_controller.rb +2 -2
- data/lib/badline/frontend/player/player_screen.rb +1 -0
- data/lib/badline/frontend/player/theme.rb +7 -7
- data/lib/badline/frontend/snapshots.rb +12 -1
- data/lib/badline/frontend/timeline.rb +30 -12
- data/lib/badline/input/control_ports.rb +78 -0
- data/lib/badline/input/joystick.rb +27 -0
- data/lib/badline/input/keyboard.rb +114 -0
- data/lib/badline/input/matrix_typist.rb +98 -0
- data/lib/badline/input.rb +4 -0
- data/lib/badline/kernal_trap/chrout.rb +45 -0
- data/lib/badline/kernal_trap/{drive → dos}/block_commands.rb +1 -1
- data/lib/badline/kernal_trap/dos/channel.rb +156 -0
- data/lib/badline/kernal_trap/{drive → dos}/channels.rb +1 -26
- data/lib/badline/kernal_trap/{drive → dos}/memory.rb +1 -10
- data/lib/badline/kernal_trap/{drive → dos}/parameters.rb +1 -1
- data/lib/badline/kernal_trap/{drive → dos}/status.rb +1 -9
- data/lib/badline/kernal_trap/{drive → dos}/write_file.rb +1 -19
- data/lib/badline/kernal_trap/{drive → dos}/writes.rb +1 -1
- data/lib/badline/kernal_trap/{drive.rb → dos.rb} +9 -27
- 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 +19 -21
- data/lib/badline/kernal_trap/routine.rb +12 -0
- data/lib/badline/kernal_trap/save.rb +12 -22
- data/lib/badline/kernal_trap/serial.rb +8 -24
- data/lib/badline/kernal_trap.rb +3 -2
- data/lib/badline/machine/clocking.rb +1 -1
- data/lib/badline/machine/keyboard_buffer.rb +49 -0
- data/lib/badline/machine/settling.rb +29 -0
- data/lib/badline/machine.rb +10 -7
- data/lib/badline/media/boot_disk.rb +14 -2
- data/lib/badline/media/extensions.rb +10 -0
- data/lib/badline/media/true_drive.rb +1 -1
- data/lib/badline/media/tune.rb +2 -2
- data/lib/badline/media.rb +3 -3
- data/lib/badline/memory.rb +3 -6
- data/lib/badline/model.rb +1 -1
- 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 +44 -6
- 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/sdl.rb +1 -0
- data/lib/badline/{storage/sid_file.rb → sid_tune/file.rb} +3 -3
- data/lib/badline/{storage → sid_tune}/hvsc.rb +7 -7
- data/lib/badline/{storage → sid_tune}/song_lengths.rb +2 -2
- data/lib/badline/{storage → sid_tune}/stil/credit.rb +1 -1
- data/lib/badline/{storage → sid_tune}/stil.rb +3 -3
- data/lib/badline/sid_tune.rb +6 -0
- data/lib/badline/snapshot/c128_setup.rb +32 -0
- data/lib/badline/snapshot/c64_setup.rb +83 -0
- 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 +132 -46
- 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 +63 -0
- data/lib/badline/snapshot/vic20_setup.rb +28 -0
- data/lib/badline/snapshot/vice/c64_mem.rb +1 -1
- data/lib/badline/snapshot/vice/restore.rb +1 -1
- data/lib/badline/snapshot/vice/reu1764.rb +3 -3
- data/lib/badline/snapshot/vice/reu_fields.rb +40 -0
- data/lib/badline/snapshot/vice.rb +13 -35
- data/lib/badline/snapshot.rb +44 -22
- data/lib/badline/storage/crt_file.rb +3 -1
- data/lib/badline/storage/d64_image.rb +0 -2
- data/lib/badline/storage/d71_image.rb +0 -2
- data/lib/badline/storage/d81_image.rb +0 -2
- data/lib/badline/storage/disk_image.rb +3 -6
- data/lib/badline/storage/g64_image.rb +10 -5
- data/lib/badline/storage/host_directory.rb +0 -5
- data/lib/badline/storage/t64.rb +2 -8
- data/lib/badline/storage/tap.rb +43 -15
- data/lib/badline/storage/unavailable.rb +1 -1
- data/lib/badline/storage.rb +0 -37
- data/lib/badline/support/c128_checkpoint.rb +39 -0
- data/lib/badline/support/checkpoint.rb +108 -0
- data/lib/badline/support/vic20_checkpoint.rb +38 -0
- data/lib/badline/support.rb +5 -0
- data/lib/badline/version.rb +1 -1
- data/lib/badline/vic20/attachments.rb +8 -5
- data/lib/badline/vic20/bus/keyed_state.rb +52 -0
- data/lib/badline/vic20/bus.rb +2 -25
- data/lib/badline/vic20/cpu.rb +1 -1
- data/lib/badline/vic20/keyed_modules.rb +73 -0
- data/lib/badline/vic20/keyed_state.rb +45 -0
- data/lib/badline/vic20/port_wiring.rb +4 -4
- data/lib/badline/vic20/user_via_ports.rb +2 -2
- data/lib/badline/vic20.rb +22 -17
- data/lib/badline.rb +1 -0
- metadata +271 -228
- data/lib/badline/address_bus/extra_sids.rb +0 -30
- data/lib/badline/address_bus/fittings.rb +0 -38
- data/lib/badline/address_bus/pla.rb +0 -147
- data/lib/badline/address_bus/roms.rb +0 -39
- data/lib/badline/address_bus/saved_state.rb +0 -66
- data/lib/badline/address_bus/sid_slots.rb +0 -42
- data/lib/badline/address_bus.rb +0 -216
- data/lib/badline/c128/bus_state.rb +0 -53
- data/lib/badline/c128/saved_state.rb +0 -143
- data/lib/badline/cartridge/action_replay.rb +0 -126
- data/lib/badline/cartridge/atomic_power.rb +0 -24
- data/lib/badline/cartridge/bank.rb +0 -81
- data/lib/badline/cartridge/comal80.rb +0 -50
- data/lib/badline/cartridge/dinamic.rb +0 -34
- data/lib/badline/cartridge/easy_flash.rb +0 -145
- data/lib/badline/cartridge/epyx_fastload.rb +0 -79
- data/lib/badline/cartridge/final_cartridge3.rb +0 -89
- data/lib/badline/cartridge/flash.rb +0 -306
- data/lib/badline/cartridge/freezer.rb +0 -33
- data/lib/badline/cartridge/fun_play.rb +0 -38
- data/lib/badline/cartridge/g_mod2.rb +0 -74
- data/lib/badline/cartridge/game_system.rb +0 -40
- data/lib/badline/cartridge/geo_ram.rb +0 -79
- data/lib/badline/cartridge/kcs_power.rb +0 -75
- data/lib/badline/cartridge/mach5.rb +0 -32
- data/lib/badline/cartridge/magic_desk.rb +0 -30
- data/lib/badline/cartridge/ocean.rb +0 -35
- data/lib/badline/cartridge/pagefox.rb +0 -68
- data/lib/badline/cartridge/retro_replay.rb +0 -320
- data/lib/badline/cartridge/rex_utility.rb +0 -29
- data/lib/badline/cartridge/rgcd.rb +0 -58
- data/lib/badline/cartridge/simons_basic.rb +0 -35
- data/lib/badline/cartridge/standard.rb +0 -15
- data/lib/badline/cartridge/super_games.rb +0 -48
- data/lib/badline/cartridge/westermann.rb +0 -30
- data/lib/badline/cartridge/zaxxon.rb +0 -66
- data/lib/badline/cartridge.rb +0 -303
- data/lib/badline/checkpoint.rb +0 -98
- data/lib/badline/chrout_trap.rb +0 -43
- data/lib/badline/cia/fast_forward.rb +0 -60
- data/lib/badline/cia/interrupt_register.rb +0 -143
- data/lib/badline/cia/serial.rb +0 -275
- data/lib/badline/cia/state.rb +0 -47
- data/lib/badline/cia/timer.rb +0 -206
- data/lib/badline/cia.rb +0 -279
- data/lib/badline/color_memory.rb +0 -25
- data/lib/badline/computer/attachments.rb +0 -88
- data/lib/badline/computer/saved_state.rb +0 -117
- data/lib/badline/computer/true_drives.rb +0 -69
- data/lib/badline/control_ports.rb +0 -76
- data/lib/badline/cpu/addressing.rb +0 -131
- data/lib/badline/cpu/boundary.rb +0 -54
- data/lib/badline/cpu/core.rb +0 -165
- data/lib/badline/cpu/microcode.rb +0 -177
- data/lib/badline/cpu/operations.rb +0 -88
- data/lib/badline/cpu/saved_state.rb +0 -115
- data/lib/badline/cpu/stack_operations.rb +0 -82
- data/lib/badline/cpu.rb +0 -10
- data/lib/badline/cpu_port.rb +0 -112
- data/lib/badline/datasette.rb +0 -161
- data/lib/badline/debug_register.rb +0 -28
- data/lib/badline/drive/core.rb +0 -147
- data/lib/badline/drive/fast_serial.rb +0 -73
- data/lib/badline/drive/idle.rb +0 -125
- data/lib/badline/drive/idle_cpu.rb +0 -28
- data/lib/badline/drive/orbit.rb +0 -79
- data/lib/badline/drive/serial_lines.rb +0 -73
- data/lib/badline/drive/sleep.rb +0 -112
- data/lib/badline/drive/vias.rb +0 -84
- data/lib/badline/drive/watch.rb +0 -150
- data/lib/badline/drive.rb +0 -11
- data/lib/badline/drive1541/bus.rb +0 -86
- data/lib/badline/drive1541/byte_ready.rb +0 -48
- data/lib/badline/drive1541/cpu.rb +0 -11
- data/lib/badline/drive1541/disk.rb +0 -315
- data/lib/badline/drive1541/disk_state.rb +0 -86
- data/lib/badline/drive1541/disk_via.rb +0 -36
- data/lib/badline/drive1541/gcr.rb +0 -57
- data/lib/badline/drive1541/mechanism.rb +0 -313
- data/lib/badline/drive1541/mechanism_state.rb +0 -68
- data/lib/badline/drive1541/rotation.rb +0 -121
- data/lib/badline/drive1541/sector_reader.rb +0 -76
- data/lib/badline/drive1541/serial_port.rb +0 -18
- data/lib/badline/drive1541/track.rb +0 -98
- data/lib/badline/drive1541.rb +0 -111
- data/lib/badline/drive1571/bus.rb +0 -111
- data/lib/badline/drive1571/cpu.rb +0 -11
- data/lib/badline/drive1571/serial_port.rb +0 -37
- data/lib/badline/drive1571/serial_via.rb +0 -25
- data/lib/badline/drive1571/wd1770.rb +0 -120
- data/lib/badline/drive1571.rb +0 -175
- data/lib/badline/drive1581/bus.rb +0 -137
- data/lib/badline/drive1581/cpu.rb +0 -11
- data/lib/badline/drive1581/disk.rb +0 -135
- data/lib/badline/drive1581/disk_state.rb +0 -87
- data/lib/badline/drive1581/mechanism.rb +0 -117
- data/lib/badline/drive1581/serial_port.rb +0 -52
- data/lib/badline/drive1581/slot.rb +0 -78
- data/lib/badline/drive1581/track.rb +0 -100
- data/lib/badline/drive1581/track_bytes.rb +0 -75
- data/lib/badline/drive1581/wd1772/registers.rb +0 -89
- data/lib/badline/drive1581/wd1772/sector_writes.rb +0 -73
- data/lib/badline/drive1581/wd1772/sectors.rb +0 -150
- data/lib/badline/drive1581/wd1772/state.rb +0 -66
- data/lib/badline/drive1581/wd1772/stepping.rb +0 -109
- data/lib/badline/drive1581/wd1772/tracks.rb +0 -125
- data/lib/badline/drive1581/wd1772/turn.rb +0 -73
- data/lib/badline/drive1581/wd1772.rb +0 -216
- data/lib/badline/drive1581.rb +0 -233
- data/lib/badline/iec_bus.rb +0 -159
- data/lib/badline/instruction.rb +0 -334
- data/lib/badline/instruction_set/arithmetic.rb +0 -114
- data/lib/badline/instruction_set/bitwise.rb +0 -126
- data/lib/badline/instruction_set/branch.rb +0 -79
- data/lib/badline/instruction_set/flag.rb +0 -63
- data/lib/badline/instruction_set/illegal.rb +0 -270
- data/lib/badline/instruction_set/inc_dec.rb +0 -69
- data/lib/badline/instruction_set/stack.rb +0 -52
- data/lib/badline/instruction_set/transfer.rb +0 -137
- data/lib/badline/instruction_set.rb +0 -55
- data/lib/badline/interrupts.rb +0 -104
- data/lib/badline/joystick.rb +0 -25
- data/lib/badline/kernal_trap/channel.rb +0 -181
- data/lib/badline/keyboard.rb +0 -112
- data/lib/badline/keyboard_buffer.rb +0 -33
- data/lib/badline/ram_expansion/banking.rb +0 -30
- data/lib/badline/ram_expansion/plus256k.rb +0 -54
- data/lib/badline/ram_expansion/plus60k.rb +0 -43
- data/lib/badline/ram_expansion/unexpanded.rb +0 -28
- data/lib/badline/ram_expansion.rb +0 -21
- data/lib/badline/reu/dma/saved_state.rb +0 -50
- data/lib/badline/reu/dma.rb +0 -273
- data/lib/badline/reu/ram.rb +0 -107
- data/lib/badline/reu/saved_state.rb +0 -80
- data/lib/badline/reu/trigger.rb +0 -32
- data/lib/badline/reu.rb +0 -289
- data/lib/badline/sid/catch_up.rb +0 -120
- data/lib/badline/sid/decimator.rb +0 -64
- data/lib/badline/sid/envelope/state.rb +0 -68
- data/lib/badline/sid/envelope.rb +0 -239
- data/lib/badline/sid/filter.rb +0 -263
- data/lib/badline/sid/voice.rb +0 -77
- data/lib/badline/sid/waveform/combined.rb +0 -126
- data/lib/badline/sid/waveform/fast_forward.rb +0 -105
- data/lib/badline/sid/waveform/noise_writeback.rb +0 -122
- data/lib/badline/sid/waveform/state.rb +0 -66
- data/lib/badline/sid/waveform.rb +0 -305
- data/lib/badline/sid.rb +0 -303
- data/lib/badline/snapshot/setup.rb +0 -75
- data/lib/badline/snapshot/state.rb +0 -189
- data/lib/badline/time_of_day.rb +0 -228
- data/lib/badline/traps.rb +0 -19
- data/lib/badline/via/control_lines.rb +0 -122
- data/lib/badline/via/fast_forward.rb +0 -53
- data/lib/badline/via/interrupt_register.rb +0 -67
- data/lib/badline/via/shift_register.rb +0 -180
- data/lib/badline/via/state.rb +0 -42
- data/lib/badline/via/timer1.rb +0 -131
- data/lib/badline/via/timer2.rb +0 -133
- data/lib/badline/via.rb +0 -266
- data/lib/badline/vic/bank.rb +0 -133
- data/lib/badline/vic/border_mask.rb +0 -86
- data/lib/badline/vic/collisions.rb +0 -115
- data/lib/badline/vic/color_patches.rb +0 -47
- data/lib/badline/vic/display_state.rb +0 -185
- data/lib/badline/vic/graphics_mode.rb +0 -164
- data/lib/badline/vic/graphics_shifter.rb +0 -207
- data/lib/badline/vic/register_log.rb +0 -81
- data/lib/badline/vic/registers.rb +0 -195
- data/lib/badline/vic/sequencer.rb +0 -275
- data/lib/badline/vic/sequencer_output.rb +0 -116
- data/lib/badline/vic/sequencer_state.rb +0 -89
- data/lib/badline/vic/sprite/internal_bus.rb +0 -68
- data/lib/badline/vic/sprite/saved_state.rb +0 -64
- data/lib/badline/vic/sprite/shifter.rb +0 -146
- data/lib/badline/vic/sprite/timing.rb +0 -56
- data/lib/badline/vic/sprite.rb +0 -337
- data/lib/badline/vic/sprites.rb +0 -282
- data/lib/badline/vic/sprites_state.rb +0 -57
- data/lib/badline/vic.rb +0 -853
- data/lib/badline/vic20/saved_state.rb +0 -124
- data/lib/badline/vic20/sound/output.rb +0 -83
- data/lib/badline/vic20/sound.rb +0 -233
- data/lib/badline/vic20/vic/saved_state.rb +0 -55
- data/lib/badline/z80/arithmetic.rb +0 -117
- data/lib/badline/z80/bit_page.rb +0 -55
- data/lib/badline/z80/block_io.rb +0 -58
- data/lib/badline/z80/block_transfers.rb +0 -59
- data/lib/badline/z80/bus_cycles.rb +0 -111
- data/lib/badline/z80/core.rb +0 -113
- data/lib/badline/z80/exchanges.rb +0 -50
- data/lib/badline/z80/extended_page.rb +0 -89
- data/lib/badline/z80/flags.rb +0 -37
- data/lib/badline/z80/interrupt_acceptance.rb +0 -46
- data/lib/badline/z80/jumps.rb +0 -82
- data/lib/badline/z80/loads.rb +0 -98
- data/lib/badline/z80/main_page.rb +0 -134
- data/lib/badline/z80/registers.rb +0 -120
- data/lib/badline/z80/saved_state.rb +0 -69
- data/lib/badline/z80/shifts.rb +0 -64
- data/lib/badline/z80.rb +0 -11
- /data/lib/badline/snapshot/{fields.rb → vice/fields.rb} +0 -0
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class C64
|
|
5
|
+
class REU
|
|
6
|
+
# One transfer between the C64 and the REU's RAM, clocked a cycle at a
|
|
7
|
+
# time while the REC holds the bus. The REC only reads the C64's bus
|
|
8
|
+
# while BA is high, so a read followed by BA low waits for BA to rise.
|
|
9
|
+
# After a write it goes on through the first BA-low cycle and stops at
|
|
10
|
+
# the second. See doc/pinned-behaviour.md, REU DMA.
|
|
11
|
+
class DMA
|
|
12
|
+
# Transfer types, as the command register's bottom two bits give
|
|
13
|
+
# them.
|
|
14
|
+
STASH = 0
|
|
15
|
+
FETCH = 1
|
|
16
|
+
SWAP = 2
|
|
17
|
+
VERIFY = 3
|
|
18
|
+
|
|
19
|
+
# What the REC did on the cycle before.
|
|
20
|
+
IDLE = 0
|
|
21
|
+
READ = 1
|
|
22
|
+
WRITE = 2
|
|
23
|
+
|
|
24
|
+
# Where the transfer stopped, what it left for the length register,
|
|
25
|
+
# and the status bits it ended with.
|
|
26
|
+
attr_reader :c64, :expansion, :length, :events
|
|
27
|
+
|
|
28
|
+
def initialize(ram, span, bus)
|
|
29
|
+
@ram = ram
|
|
30
|
+
@span = span
|
|
31
|
+
@bus = bus
|
|
32
|
+
@c64 = @expansion = @length = @events = 0
|
|
33
|
+
@holding = false
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# Whether the REC held the bus on the last cycle clocked, which it
|
|
37
|
+
# does while it waits for BA too, since the CPU stays halted.
|
|
38
|
+
def holds_bus? = @holding
|
|
39
|
+
|
|
40
|
+
# A length of 0 moves 64K. control is the address control register,
|
|
41
|
+
# which can hold either address where it is.
|
|
42
|
+
def start(type, c64, expansion, length, control)
|
|
43
|
+
@type = type
|
|
44
|
+
@c64 = c64
|
|
45
|
+
@expansion = expansion
|
|
46
|
+
@length = length.zero? ? 0x10000 : length
|
|
47
|
+
@c64_step = control.anybits?(FIX_C64) ? 0 : 1
|
|
48
|
+
@expansion_step = control.anybits?(FIX_EXPANSION) ? 0 : 1
|
|
49
|
+
@events = 0
|
|
50
|
+
@holding = true
|
|
51
|
+
@last = IDLE
|
|
52
|
+
@waiting = false
|
|
53
|
+
@ba_low_after_writes = 0
|
|
54
|
+
@stopped_after_write = false
|
|
55
|
+
@swap_write_due = false
|
|
56
|
+
@swap_read_again = false
|
|
57
|
+
@swap_byte = 0
|
|
58
|
+
@held_read = 0
|
|
59
|
+
@moved_all = false
|
|
60
|
+
@extra_cycle = false
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Writes the byte a fetch from these addresses starts with, without
|
|
64
|
+
# counting it. Other transfers start with a read.
|
|
65
|
+
def write_ahead(type, c64, expansion)
|
|
66
|
+
return unless type == FETCH
|
|
67
|
+
|
|
68
|
+
@c64 = c64
|
|
69
|
+
byte = @ram.peek(expansion)
|
|
70
|
+
@ram.latch = byte
|
|
71
|
+
write_c64(byte)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# One cycle of the transfer. The cycle the REC lets go of the bus on
|
|
75
|
+
# is the CPU's. late says BA fell on this cycle but a REC that moved a
|
|
76
|
+
# byte on the last one doesn't see it yet (VIC#reu_ba_late?), and
|
|
77
|
+
# handed_on that BA runs on from a bad line's DMA into a sprite's
|
|
78
|
+
# here (VIC#reu_ba_handed_on?).
|
|
79
|
+
def cycle!(ba_low, late, handed_on)
|
|
80
|
+
note_ba(ba_low, late)
|
|
81
|
+
@swap_read_again ||= handed_on && @swap_write_due
|
|
82
|
+
settle_held_read(ba_low) if @held_read.positive?
|
|
83
|
+
return if @waiting && ba_low
|
|
84
|
+
|
|
85
|
+
@waiting = false
|
|
86
|
+
@moved_all ? wind_down : move(ba_low)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
private
|
|
90
|
+
|
|
91
|
+
# The second BA-low cycle in a row after writes stops the REC, and so
|
|
92
|
+
# does any BA-low cycle after a read. It then waits for BA to rise.
|
|
93
|
+
def note_ba(ba_low, late)
|
|
94
|
+
seen = ba_low && !late
|
|
95
|
+
if @last == READ
|
|
96
|
+
note_ba_after_read(seen)
|
|
97
|
+
elsif @last == WRITE
|
|
98
|
+
note_ba_after_write(seen)
|
|
99
|
+
end
|
|
100
|
+
@last = IDLE
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# A swap's read that BA stops before its write is made again.
|
|
104
|
+
def note_ba_after_read(ba_low)
|
|
105
|
+
@waiting = ba_low
|
|
106
|
+
@ba_low_after_writes = 0
|
|
107
|
+
@swap_read_again = ba_low && @swap_write_due && @held_read.zero?
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# A fetch's last write doesn't go through the first BA-low cycle.
|
|
111
|
+
# Pinned by REU/reutiming2/d and d2.
|
|
112
|
+
def note_ba_after_write(ba_low)
|
|
113
|
+
@ba_low_after_writes = ba_low ? @ba_low_after_writes + 1 : 0
|
|
114
|
+
@stopped_after_write = @ba_low_after_writes == 2 || (ba_low && @type == FETCH && @length == 1)
|
|
115
|
+
return unless @stopped_after_write
|
|
116
|
+
|
|
117
|
+
@waiting = true
|
|
118
|
+
@ba_low_after_writes = 0
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# A fetch or a swap whose last write ran into BA, or a verify that
|
|
122
|
+
# found a difference before its last byte, takes one more cycle before
|
|
123
|
+
# the REC lets go of the bus.
|
|
124
|
+
def wind_down
|
|
125
|
+
if @extra_cycle || (@stopped_after_write && (@type == FETCH || @type == SWAP))
|
|
126
|
+
@extra_cycle = @stopped_after_write = false
|
|
127
|
+
@last = READ
|
|
128
|
+
return
|
|
129
|
+
end
|
|
130
|
+
|
|
131
|
+
@holding = false
|
|
132
|
+
settle
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def move(ba_low)
|
|
136
|
+
case @type
|
|
137
|
+
when STASH then stash
|
|
138
|
+
when FETCH then fetch
|
|
139
|
+
when SWAP then swap(ba_low)
|
|
140
|
+
else verify
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# The REU's data bus latch keeps the last byte the REC stored.
|
|
145
|
+
def stash
|
|
146
|
+
byte = read_c64
|
|
147
|
+
@ram.poke(@expansion, byte)
|
|
148
|
+
@ram.latch = byte
|
|
149
|
+
step
|
|
150
|
+
@last = READ
|
|
151
|
+
end
|
|
152
|
+
|
|
153
|
+
def fetch
|
|
154
|
+
byte = @ram.peek(@expansion)
|
|
155
|
+
@ram.latch = byte
|
|
156
|
+
write_c64(byte)
|
|
157
|
+
step
|
|
158
|
+
@last = WRITE
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
# Two cycles a byte: the C64's byte is read and stored while the
|
|
162
|
+
# REU's is fetched, and the REU's is written to the C64 on the next.
|
|
163
|
+
def swap(ba_low)
|
|
164
|
+
return read_swap_again if @swap_read_again
|
|
165
|
+
|
|
166
|
+
if @swap_write_due
|
|
167
|
+
@swap_write_due = false
|
|
168
|
+
write_c64(@swap_byte)
|
|
169
|
+
step
|
|
170
|
+
@last = WRITE
|
|
171
|
+
return
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
@swap_byte = @ram.peek(@expansion)
|
|
175
|
+
@swap_write_due = true
|
|
176
|
+
@last = READ
|
|
177
|
+
return swap_read_on_ba if ba_low
|
|
178
|
+
|
|
179
|
+
@ram.poke(@expansion, read_c64)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# A swap's read on the first BA-low cycle after a write, while AEC is
|
|
183
|
+
# still high. On the last byte the read is made there, the write
|
|
184
|
+
# follows on the next cycle whatever BA does, and the REC lets go.
|
|
185
|
+
# Otherwise the read stays open and takes what is on the bus two
|
|
186
|
+
# cycles later, or on the cycle BA rises if that comes first. Pinned
|
|
187
|
+
# by REU/reutiming2/e5-m2, f3-m2 and f4-m2.
|
|
188
|
+
def swap_read_on_ba
|
|
189
|
+
return @held_read = 2 unless @length == 1
|
|
190
|
+
|
|
191
|
+
@ram.poke(@expansion, read_c64)
|
|
192
|
+
@last = IDLE
|
|
193
|
+
@ba_low_after_writes = 0
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
# A swap's read that BA cut off from its write is made again when BA
|
|
197
|
+
# rises, and the write follows it. Pinned by REU/reutiming2/e4-m2,
|
|
198
|
+
# e6-m2 and g3-m2.
|
|
199
|
+
def read_swap_again
|
|
200
|
+
@swap_read_again = false
|
|
201
|
+
@ram.poke(@expansion, read_c64)
|
|
202
|
+
@last = READ
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
def settle_held_read(ba_low)
|
|
206
|
+
@held_read -= 1
|
|
207
|
+
return if @held_read.positive? && ba_low
|
|
208
|
+
|
|
209
|
+
@held_read = 0
|
|
210
|
+
@ram.poke(@expansion, read_c64)
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# A difference ends the transfer, with one cycle more if bytes were
|
|
214
|
+
# left to compare.
|
|
215
|
+
def verify
|
|
216
|
+
same = @ram.peek(@expansion) == read_c64
|
|
217
|
+
step
|
|
218
|
+
@last = READ
|
|
219
|
+
return if same
|
|
220
|
+
|
|
221
|
+
@events |= FAULT
|
|
222
|
+
@extra_cycle = @length.positive?
|
|
223
|
+
@moved_all = true
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# The REC reaches C64 memory as the CPU sees it, but at $00 and $01
|
|
227
|
+
# it reaches the RAM under the CPU's port.
|
|
228
|
+
def read_c64
|
|
229
|
+
@c64 < 0x02 ? @bus.ram.peek(@c64) : @bus.peek(@c64)
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def write_c64(byte)
|
|
233
|
+
@c64 < 0x02 ? @bus.ram.poke(@c64, byte) : @bus.poke(@c64, byte)
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
# The REC counts the expansion address in its 19 low bits, from the
|
|
237
|
+
# top of its span back to 0, and leaves the bank bits above them as
|
|
238
|
+
# they were.
|
|
239
|
+
def step
|
|
240
|
+
@c64 = (@c64 + @c64_step) & 0xffff
|
|
241
|
+
low = (@expansion & 0x7ffff) + @expansion_step
|
|
242
|
+
@expansion = (@expansion & 0xf80000) | (low == @span ? 0 : low)
|
|
243
|
+
@length -= 1
|
|
244
|
+
@moved_all = true if @length.zero?
|
|
245
|
+
end
|
|
246
|
+
|
|
247
|
+
# The length register is left at 1 after a whole block. A fetch has
|
|
248
|
+
# already fetched the byte after its last into the latch.
|
|
249
|
+
def settle
|
|
250
|
+
return settle_verify if @type == VERIFY
|
|
251
|
+
|
|
252
|
+
@length += 1
|
|
253
|
+
@events |= END_OF_BLOCK
|
|
254
|
+
@ram.latch = @ram.peek(@expansion) if @type == FETCH
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
# A verify that compared every byte ends the block. One that found a
|
|
258
|
+
# difference on the byte before the last compares the last too, and
|
|
259
|
+
# ends the block if that one is the same.
|
|
260
|
+
def settle_verify
|
|
261
|
+
if @length.zero?
|
|
262
|
+
@length = 1
|
|
263
|
+
@events |= END_OF_BLOCK
|
|
264
|
+
elsif @length == 1 && @ram.peek(@expansion) == read_c64
|
|
265
|
+
@events |= END_OF_BLOCK
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
end
|
|
270
|
+
end
|
|
271
|
+
end
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class C64
|
|
5
|
+
class REU
|
|
6
|
+
class DMA
|
|
7
|
+
# The kinds of transfer, by name.
|
|
8
|
+
TYPE_NAMES = %w[stash fetch swap verify].freeze
|
|
9
|
+
|
|
10
|
+
# A transfer's fields in a keyed snapshot module, under `prefix`.
|
|
11
|
+
# Before the first transfer, the fields it sets on starting are
|
|
12
|
+
# absent.
|
|
13
|
+
module KeyedState
|
|
14
|
+
def save_fields(out, prefix)
|
|
15
|
+
out.int("#{prefix}c64", @c64).int("#{prefix}expansion", @expansion).int("#{prefix}length", @length)
|
|
16
|
+
out.int("#{prefix}events", @events)
|
|
17
|
+
type = @type
|
|
18
|
+
out.text("#{prefix}type", TYPE_NAMES.fetch(type)) unless type.nil?
|
|
19
|
+
out.optional_int("#{prefix}c64_step", @c64_step).optional_int("#{prefix}expansion_step", @expansion_step)
|
|
20
|
+
out.optional_int("#{prefix}last", @last).optional_int("#{prefix}ba_low_after_writes", @ba_low_after_writes)
|
|
21
|
+
out.optional_int("#{prefix}swap_byte", @swap_byte).optional_int("#{prefix}held_read", @held_read)
|
|
22
|
+
save_flag_fields(out, prefix)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def load_fields(input, prefix)
|
|
26
|
+
@c64 = input.word("#{prefix}c64", @c64)
|
|
27
|
+
@expansion = input.int("#{prefix}expansion", @expansion)
|
|
28
|
+
@length = input.int("#{prefix}length", @length)
|
|
29
|
+
@events = input.int("#{prefix}events", @events)
|
|
30
|
+
type = input.choice("#{prefix}type", TYPE_NAMES + ["none"], "none")
|
|
31
|
+
@type = type == "none" ? nil : TYPE_NAMES.index(type)
|
|
32
|
+
@c64_step = input.optional_int("#{prefix}c64_step")
|
|
33
|
+
@expansion_step = input.optional_int("#{prefix}expansion_step")
|
|
34
|
+
@last = input.optional_int("#{prefix}last")
|
|
35
|
+
@ba_low_after_writes = input.optional_int("#{prefix}ba_low_after_writes")
|
|
36
|
+
@swap_byte = input.optional_int("#{prefix}swap_byte")
|
|
37
|
+
@held_read = input.optional_int("#{prefix}held_read")
|
|
38
|
+
load_flag_fields(input, prefix)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def save_flag_fields(out, prefix)
|
|
44
|
+
out.bool("#{prefix}holding", @holding).bool("#{prefix}waiting", @waiting)
|
|
45
|
+
out.bool("#{prefix}stopped_after_write", @stopped_after_write)
|
|
46
|
+
out.bool("#{prefix}swap_write_due", @swap_write_due).bool("#{prefix}swap_read_again", @swap_read_again)
|
|
47
|
+
out.bool("#{prefix}moved_all", @moved_all).bool("#{prefix}extra_cycle", @extra_cycle)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def load_flag_fields(input, prefix)
|
|
51
|
+
@holding = input.bool("#{prefix}holding", @holding)
|
|
52
|
+
@waiting = input.bool("#{prefix}waiting", @waiting)
|
|
53
|
+
@stopped_after_write = input.bool("#{prefix}stopped_after_write", @stopped_after_write)
|
|
54
|
+
@swap_write_due = input.bool("#{prefix}swap_write_due", @swap_write_due)
|
|
55
|
+
@swap_read_again = input.bool("#{prefix}swap_read_again", @swap_read_again)
|
|
56
|
+
@moved_all = input.bool("#{prefix}moved_all", @moved_all)
|
|
57
|
+
@extra_cycle = input.bool("#{prefix}extra_cycle", @extra_cycle)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
include KeyedState
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
class RAM
|
|
65
|
+
# The data latch and each bank the REC has touched, as bank<N>; a
|
|
66
|
+
# bank left out holds its power-on contents.
|
|
67
|
+
module KeyedState
|
|
68
|
+
def save_fields(out)
|
|
69
|
+
out.int("latch", @latch)
|
|
70
|
+
@banks.each_with_index { |bank, number| out.bytes("bank#{number}", bank) unless bank.empty? }
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def load_fields(input)
|
|
74
|
+
@latch = input.byte("latch", @latch)
|
|
75
|
+
@banks.each_index do |number|
|
|
76
|
+
@banks[number] = input.bytes("bank#{number}", "".b).bytes
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
include KeyedState
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# The REU's fields in a keyed snapshot module (Snapshot::Keyed): the
|
|
85
|
+
# REC's registers and the values its counters start from, an armed or
|
|
86
|
+
# running transfer, the transfer under dma.*, and the RAM. The IRQ
|
|
87
|
+
# line comes from the status register on load.
|
|
88
|
+
module KeyedState
|
|
89
|
+
# The REU's size in K, which the machine's setup names.
|
|
90
|
+
def size_kb = @size_kb
|
|
91
|
+
|
|
92
|
+
def save_fields(out)
|
|
93
|
+
out.int("status", @status).int("command", @command).int("c64", @c64).int("c64_start", @c64_start)
|
|
94
|
+
out.int("expansion", @expansion).int("expansion_start", @expansion_start).int("bank", @bank)
|
|
95
|
+
out.int("bank_start", @bank_start).int("length", @length).int("length_start", @length_start)
|
|
96
|
+
out.int("interrupt_mask", @interrupt_mask).int("address_control", @address_control)
|
|
97
|
+
out.bool("armed", @armed).bool("requested", @requested).bool("running", @running)
|
|
98
|
+
out.bool("ba_was_low", @ba_was_low)
|
|
99
|
+
@dma.save_fields(out, "dma.")
|
|
100
|
+
@ram.save_fields(out)
|
|
101
|
+
out
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def load_fields(input)
|
|
105
|
+
load_register_fields(input)
|
|
106
|
+
@armed = input.bool("armed", @armed)
|
|
107
|
+
@requested = input.bool("requested", @requested)
|
|
108
|
+
@running = input.bool("running", @running)
|
|
109
|
+
@ba_was_low = input.bool("ba_was_low", @ba_was_low)
|
|
110
|
+
@dma.load_fields(input, "dma.")
|
|
111
|
+
@ram.load_fields(input)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Without calling back into the machine, which reads the line again.
|
|
115
|
+
def restored!
|
|
116
|
+
@irq = @status.anybits?(INTERRUPT_PENDING)
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
private
|
|
120
|
+
|
|
121
|
+
def load_register_fields(input)
|
|
122
|
+
@status = input.byte("status", @status)
|
|
123
|
+
@command = input.byte("command", @command)
|
|
124
|
+
@c64 = input.word("c64", @c64)
|
|
125
|
+
@c64_start = input.word("c64_start", @c64_start)
|
|
126
|
+
@expansion = input.word("expansion", @expansion)
|
|
127
|
+
@expansion_start = input.word("expansion_start", @expansion_start)
|
|
128
|
+
@bank = input.byte("bank", @bank)
|
|
129
|
+
@bank_start = input.byte("bank_start", @bank_start)
|
|
130
|
+
@length = input.word("length", @length)
|
|
131
|
+
@length_start = input.word("length_start", @length_start)
|
|
132
|
+
@interrupt_mask = input.byte("interrupt_mask", @interrupt_mask)
|
|
133
|
+
@address_control = input.byte("address_control", @address_control)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
include KeyedState
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class C64
|
|
5
|
+
class REU
|
|
6
|
+
# The REU's DRAM, as the REC addresses it. The REC counts 19 address
|
|
7
|
+
# bits, 17 on the 1700, and the 1764 fills only the first 256K of
|
|
8
|
+
# them: past that a read finds the latch on the REU's data bus, which
|
|
9
|
+
# holds the last byte the REC moved. A unit past 512K takes its upper
|
|
10
|
+
# address lines from the bank register.
|
|
11
|
+
class RAM
|
|
12
|
+
BANK_SIZE = 0x10000
|
|
13
|
+
|
|
14
|
+
# Where a bank of a 1764 that has just been switched on reads
|
|
15
|
+
# inverted, over the first 128K of each 256K. Over the second 128K
|
|
16
|
+
# it is the rest of the bank that reads inverted. Measured from
|
|
17
|
+
# REU/raminitpattern/dumpfile-256k-x1541.bin, a real 1764's dump.
|
|
18
|
+
INVERTED = [0x2a00...0x5400, 0x8000...0xac00, 0xd600...0x10000].freeze
|
|
19
|
+
|
|
20
|
+
attr_reader :size
|
|
21
|
+
attr_accessor :latch
|
|
22
|
+
|
|
23
|
+
def initialize(size, span)
|
|
24
|
+
@size = size
|
|
25
|
+
@mask = (size > 0x80000 ? size : span) - 1
|
|
26
|
+
@banks = Array.new(size / BANK_SIZE) { [] }
|
|
27
|
+
@power_on = [[], []]
|
|
28
|
+
@latch = 0xff
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def peek(addr)
|
|
32
|
+
addr &= @mask
|
|
33
|
+
addr < @size ? bank(addr >> 16)[addr & 0xffff] : @latch
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def poke(addr, value)
|
|
37
|
+
addr &= @mask
|
|
38
|
+
bank(addr >> 16)[addr & 0xffff] = value if addr < @size
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# Every byte, as one string, with a bank the REC hasn't touched at
|
|
42
|
+
# its power-on contents.
|
|
43
|
+
def contents
|
|
44
|
+
power_on = power_on_strings
|
|
45
|
+
Array.new(@banks.length) do |number|
|
|
46
|
+
bank = @banks[number]
|
|
47
|
+
bank.empty? ? power_on[(number >> 1) & 1] : bank.pack("C*")
|
|
48
|
+
end.join
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Takes every byte from a string as long as the RAM. A bank that
|
|
52
|
+
# holds its power-on contents stays untouched.
|
|
53
|
+
def restore(bytes)
|
|
54
|
+
power_on = power_on_strings
|
|
55
|
+
@banks.each_index do |number|
|
|
56
|
+
slice = bytes.byteslice(number * BANK_SIZE, BANK_SIZE).to_s
|
|
57
|
+
@banks[number] = slice == power_on[(number >> 1) & 1] ? [] : slice.bytes
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
def power_on_strings
|
|
64
|
+
[0, 1].map do |half|
|
|
65
|
+
@power_on[half] = power_on_bank(half == 1) if @power_on[half].empty?
|
|
66
|
+
@power_on[half].pack("C*")
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# A bank takes its power-on contents the first time it is touched,
|
|
71
|
+
# so an REU costs only the memory a program uses.
|
|
72
|
+
def bank(number)
|
|
73
|
+
bank = @banks[number]
|
|
74
|
+
return bank unless bank.empty?
|
|
75
|
+
|
|
76
|
+
half = (number >> 1) & 1
|
|
77
|
+
@power_on[half] = power_on_bank(half == 1) if @power_on[half].empty?
|
|
78
|
+
@banks[number] = @power_on[half].dup
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Pairs of $FF and $00 bytes, starting with a single $FF, and each
|
|
82
|
+
# odd page the inverse of the even one before it.
|
|
83
|
+
def power_on_bank(upper)
|
|
84
|
+
Array.new(BANK_SIZE) do |offset|
|
|
85
|
+
byte = (offset + 1).anybits?(2) ? 0x00 : 0xff
|
|
86
|
+
byte ^= 0xff if offset.anybits?(0x100)
|
|
87
|
+
inverted = INVERTED.any? { |range| range.cover?(offset) }
|
|
88
|
+
inverted == upper ? byte : byte ^ 0xff
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class C64
|
|
5
|
+
class REU
|
|
6
|
+
# Stands in for the page at $FF00 in the write table, passing each
|
|
7
|
+
# write on to what is mapped there and telling the REC when $FF00 is
|
|
8
|
+
# written, which starts an armed transfer.
|
|
9
|
+
class Trigger
|
|
10
|
+
ADDRESS = 0xff00
|
|
11
|
+
|
|
12
|
+
def initialize(reu)
|
|
13
|
+
@reu = reu
|
|
14
|
+
@target = nil
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Puts the trigger in front of target and returns it.
|
|
18
|
+
def wrap(target)
|
|
19
|
+
@target = target
|
|
20
|
+
self
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def peek(addr)
|
|
24
|
+
@target.peek(addr)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def poke(addr, value)
|
|
28
|
+
@target.poke(addr, value)
|
|
29
|
+
@reu.ff00_written if addr == ADDRESS
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|