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
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
class Cartridge
|
|
5
|
-
# Super Games: four 16K banks. A write to I/O 2 selects the bank from bits
|
|
6
|
-
# 0-1, switches the ROM out with bit 2, and with bit 3 locks the register
|
|
7
|
-
# until reset.
|
|
8
|
-
class SuperGames < Cartridge
|
|
9
|
-
def poke(addr, value)
|
|
10
|
-
return if addr < 0xdf00 || @locked
|
|
11
|
-
|
|
12
|
-
select(value)
|
|
13
|
-
changed!
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def reset
|
|
17
|
-
select(0)
|
|
18
|
-
changed!
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
private
|
|
22
|
-
|
|
23
|
-
def save_mapper(out)
|
|
24
|
-
super
|
|
25
|
-
out.boolean(@locked)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def load_mapper(input)
|
|
29
|
-
super
|
|
30
|
-
@locked = input.boolean?
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
def windows = [*@roml_banks, *@romh_banks, EMPTY_BANK]
|
|
34
|
-
|
|
35
|
-
def select(value)
|
|
36
|
-
@roml = bank(@roml_banks, value & 0x03)
|
|
37
|
-
@romh = bank(@romh_banks, value & 0x03)
|
|
38
|
-
self.mode = value.anybits?(0x04) ? :off : :rom16k
|
|
39
|
-
@locked = value.anybits?(0x08)
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def install_chips(chips)
|
|
43
|
-
@roml_banks, @romh_banks = banks_from(chips)
|
|
44
|
-
reset
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
class Cartridge
|
|
5
|
-
# 16K. Reading I/O 2 switches ROMH out (8K mode) until reset.
|
|
6
|
-
class Westermann < Cartridge
|
|
7
|
-
def readable_io_pages
|
|
8
|
-
[0xdf]
|
|
9
|
-
end
|
|
10
|
-
|
|
11
|
-
def peek(addr)
|
|
12
|
-
select_mode(:rom8k) if addr >= 0xdf00
|
|
13
|
-
open_bus(addr)
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def reset
|
|
17
|
-
select_mode(:rom16k)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
private
|
|
21
|
-
|
|
22
|
-
def install_chips(chips)
|
|
23
|
-
roml, romh = banks_from(chips)
|
|
24
|
-
@roml = bank(roml, 0)
|
|
25
|
-
@romh = bank(romh, 0)
|
|
26
|
-
reset
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|
|
30
|
-
end
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
class Cartridge
|
|
5
|
-
# Zaxxon / Super Zaxxon: 16K mode with a 4K ROML mirrored across
|
|
6
|
-
# $8000-$9FFF and two 8K ROMH banks. A read through ROML selects the
|
|
7
|
-
# ROMH bank: $8000-$8FFF the first, $9000-$9FFF the second.
|
|
8
|
-
class Zaxxon < Cartridge
|
|
9
|
-
class Low
|
|
10
|
-
def initialize(rom, high)
|
|
11
|
-
@rom = rom
|
|
12
|
-
@high = high
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
def peek(addr)
|
|
16
|
-
@high.select(addr[12])
|
|
17
|
-
@rom.peek(addr)
|
|
18
|
-
end
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
class High
|
|
22
|
-
def initialize(banks)
|
|
23
|
-
@banks = banks
|
|
24
|
-
select(0)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def select(number)
|
|
28
|
-
@bank = @banks[number] || EMPTY_BANK
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def peek(addr)
|
|
32
|
-
@bank.peek(addr)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def save_state(out)
|
|
36
|
-
out.int([*@banks, EMPTY_BANK].index { |bank| bank.equal?(@bank) })
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def load_state(input)
|
|
40
|
-
@bank = [*@banks, EMPTY_BANK].fetch(input.int)
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def reset
|
|
45
|
-
@romh.select(0)
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
private
|
|
49
|
-
|
|
50
|
-
def save_mapper(out)
|
|
51
|
-
@romh.save_state(out)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def load_mapper(input)
|
|
55
|
-
@romh.load_state(input)
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def install_chips(chips)
|
|
59
|
-
roml, romh = banks_from(chips)
|
|
60
|
-
@romh = High.new(romh)
|
|
61
|
-
@roml = Low.new(roml.first || EMPTY_BANK, @romh)
|
|
62
|
-
self.mode = :rom16k
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
end
|
data/lib/badline/cartridge.rb
DELETED
|
@@ -1,303 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "badline/cartridge/bank"
|
|
4
|
-
require "badline/cartridge/flash"
|
|
5
|
-
require "badline/cartridge/standard"
|
|
6
|
-
require "badline/cartridge/simons_basic"
|
|
7
|
-
require "badline/cartridge/ocean"
|
|
8
|
-
require "badline/cartridge/fun_play"
|
|
9
|
-
require "badline/cartridge/super_games"
|
|
10
|
-
require "badline/cartridge/epyx_fastload"
|
|
11
|
-
require "badline/cartridge/westermann"
|
|
12
|
-
require "badline/cartridge/rex_utility"
|
|
13
|
-
require "badline/cartridge/game_system"
|
|
14
|
-
require "badline/cartridge/dinamic"
|
|
15
|
-
require "badline/cartridge/zaxxon"
|
|
16
|
-
require "badline/cartridge/magic_desk"
|
|
17
|
-
require "badline/cartridge/comal80"
|
|
18
|
-
require "badline/cartridge/easy_flash"
|
|
19
|
-
require "badline/cartridge/mach5"
|
|
20
|
-
require "badline/cartridge/pagefox"
|
|
21
|
-
require "badline/cartridge/rgcd"
|
|
22
|
-
require "badline/cartridge/g_mod2"
|
|
23
|
-
require "badline/cartridge/freezer"
|
|
24
|
-
require "badline/cartridge/action_replay"
|
|
25
|
-
require "badline/cartridge/atomic_power"
|
|
26
|
-
require "badline/cartridge/final_cartridge3"
|
|
27
|
-
require "badline/cartridge/retro_replay"
|
|
28
|
-
require "badline/cartridge/kcs_power"
|
|
29
|
-
require "badline/cartridge/geo_ram"
|
|
30
|
-
|
|
31
|
-
module Badline
|
|
32
|
-
class Cartridge
|
|
33
|
-
class UnsupportedTypeError < StandardError; end
|
|
34
|
-
|
|
35
|
-
ROMH_START = 0xa000
|
|
36
|
-
BANK_SIZE = 0x2000
|
|
37
|
-
|
|
38
|
-
HARDWARE_TYPES = {
|
|
39
|
-
0 => Standard, 1 => ActionReplay, 2 => KCSPower, 3 => FinalCartridge3,
|
|
40
|
-
4 => SimonsBasic, 5 => Ocean, 7 => FunPlay, 8 => SuperGames,
|
|
41
|
-
9 => AtomicPower, 10 => EpyxFastload, 11 => Westermann,
|
|
42
|
-
12 => RexUtility, 15 => GameSystem, 17 => Dinamic, 18 => Zaxxon,
|
|
43
|
-
19 => MagicDesk, 21 => Comal80, 32 => EasyFlash, 36 => RetroReplay,
|
|
44
|
-
51 => Mach5, 53 => Pagefox, 57 => RGCD, 60 => GMod2
|
|
45
|
-
}.freeze
|
|
46
|
-
|
|
47
|
-
# The EXROM and GAME line levels of each memory configuration. The lines
|
|
48
|
-
# are active low.
|
|
49
|
-
MODES = {
|
|
50
|
-
rom8k: [0, 1].freeze, rom16k: [0, 0].freeze,
|
|
51
|
-
ultimax: [1, 0].freeze, off: [1, 1].freeze
|
|
52
|
-
}.freeze
|
|
53
|
-
|
|
54
|
-
attr_reader :name, :exrom, :game, :roml, :romh
|
|
55
|
-
|
|
56
|
-
# A callable returning the current cycle, for mappers with timed state.
|
|
57
|
-
attr_writer :clock
|
|
58
|
-
|
|
59
|
-
class << self
|
|
60
|
-
# Options set the cartridge's jumpers, for the mappers that have them.
|
|
61
|
-
def from_file(path, **)
|
|
62
|
-
from_crt(Storage::CRTFile.new(path), **)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def from_crt(crt, **)
|
|
66
|
-
mapper_for(crt).new(crt, **)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
# A cartridge built afresh from what save_setup wrote, before
|
|
70
|
-
# load_state puts its state in.
|
|
71
|
-
def from_setup(input)
|
|
72
|
-
return GeoRAM.new(size: input.int) if input.int == GEO_RAM_SETUP
|
|
73
|
-
|
|
74
|
-
crt = Storage::CRTFile.new(bytes: input.string)
|
|
75
|
-
mapper_for(crt).from_jumpers(crt, input)
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
# A cartridge from its image and what save_jumpers wrote: whether
|
|
79
|
-
# there are jumpers, then their settings on a mapper that has them.
|
|
80
|
-
def from_jumpers(crt, input)
|
|
81
|
-
input.boolean?
|
|
82
|
-
new(crt)
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def mapper_for(crt)
|
|
86
|
-
HARDWARE_TYPES.fetch(crt.hardware_type) do
|
|
87
|
-
raise UnsupportedTypeError,
|
|
88
|
-
"Unsupported cartridge hardware type #{crt.hardware_type}"
|
|
89
|
-
end
|
|
90
|
-
end
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
# What save_setup writes first: a cartridge from a CRT image, or a
|
|
94
|
-
# GEO-RAM.
|
|
95
|
-
CRT_SETUP = 0
|
|
96
|
-
GEO_RAM_SETUP = 1
|
|
97
|
-
|
|
98
|
-
# Keeps the image it was built from, so a snapshot's machine can build
|
|
99
|
-
# the same cartridge before the snapshot's state goes into it.
|
|
100
|
-
def initialize(crt)
|
|
101
|
-
@crt = crt
|
|
102
|
-
@name = crt.name
|
|
103
|
-
@exrom = crt.exrom
|
|
104
|
-
@game = crt.game
|
|
105
|
-
@roml = @romh = nil
|
|
106
|
-
@banks = nil
|
|
107
|
-
@on_change = nil
|
|
108
|
-
@on_nmi_change = nil
|
|
109
|
-
@nmi = false
|
|
110
|
-
@open_bus = nil
|
|
111
|
-
@clock = nil
|
|
112
|
-
install_chips(crt.chips)
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
def on_change(&block)
|
|
116
|
-
@on_change = block
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
# What builds the same cartridge afresh (Cartridge.from_setup): the CRT
|
|
120
|
-
# image it was built from, and the jumpers of a mapper that has them.
|
|
121
|
-
def save_setup(out)
|
|
122
|
-
out.int(CRT_SETUP).string(Storage::CRTFile.encode(@crt))
|
|
123
|
-
save_jumpers(out)
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
# The lines, the pull on NMI, the button and the mapper's own state.
|
|
127
|
-
# Loading sets them without calling back into the machine, which maps
|
|
128
|
-
# the cartridge again afterwards.
|
|
129
|
-
def save_state(out)
|
|
130
|
-
out.marker("CARTRIDGE")
|
|
131
|
-
out.int(@exrom).int(@game).boolean(@nmi).boolean(@button == true)
|
|
132
|
-
save_mapper(out)
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
def load_state(input)
|
|
136
|
-
input.marker("CARTRIDGE")
|
|
137
|
-
@exrom = input.int
|
|
138
|
-
@game = input.int
|
|
139
|
-
@nmi = input.boolean?
|
|
140
|
-
@button = input.boolean?
|
|
141
|
-
load_mapper(input)
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
# Called with the level of the cartridge's pull on the NMI line when it
|
|
145
|
-
# changes. The line is wired-OR with CIA 2's.
|
|
146
|
-
def on_nmi_change(&block)
|
|
147
|
-
@on_nmi_change = block
|
|
148
|
-
end
|
|
149
|
-
|
|
150
|
-
def nmi?
|
|
151
|
-
@nmi
|
|
152
|
-
end
|
|
153
|
-
|
|
154
|
-
# The address bus hands over the C64's RAM, for mappers that write
|
|
155
|
-
# through to it, and the open bus, for I/O reads the cartridge doesn't
|
|
156
|
-
# drive.
|
|
157
|
-
def connect(ram:, open_bus:)
|
|
158
|
-
@ram = ram
|
|
159
|
-
@open_bus = open_bus
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
def ultimax?
|
|
163
|
-
@game.zero? && @exrom == 1
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
# Whether the first half of the cycle, where the VIC does most of its
|
|
167
|
-
# fetching, sees Ultimax mode. Some cartridges drive GAME and EXROM
|
|
168
|
-
# differently in the two halves; #ultimax? is the second, the CPU's.
|
|
169
|
-
def phi1_ultimax?
|
|
170
|
-
ultimax?
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
# The I/O pages ($de, $df) whose reads the mapper drives. Reads of the
|
|
174
|
-
# others are open bus.
|
|
175
|
-
def readable_io_pages
|
|
176
|
-
[]
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
def poke(_addr, _value); end
|
|
180
|
-
|
|
181
|
-
# A window taking writes to $E000-$FFFF while reads there see the C64's
|
|
182
|
-
# memory, for a cartridge that asserts Ultimax on write cycles only.
|
|
183
|
-
def romh_writes; end
|
|
184
|
-
|
|
185
|
-
# A window at $A000-$BFFF in Ultimax mode, where the C64 maps nothing.
|
|
186
|
-
def ultimax_a000; end
|
|
187
|
-
|
|
188
|
-
# The RES line on the expansion port.
|
|
189
|
-
def reset; end
|
|
190
|
-
|
|
191
|
-
# Whether the cartridge has a freeze button.
|
|
192
|
-
def freezer? = false
|
|
193
|
-
|
|
194
|
-
# The freeze button, which cartridges without one ignore.
|
|
195
|
-
def press_button; end
|
|
196
|
-
|
|
197
|
-
def release_button; end
|
|
198
|
-
|
|
199
|
-
private
|
|
200
|
-
|
|
201
|
-
def save_jumpers(out)
|
|
202
|
-
out.boolean(false)
|
|
203
|
-
end
|
|
204
|
-
|
|
205
|
-
# The mapper's own state: where its windows point, for a mapper that
|
|
206
|
-
# moves them, and whatever a mapper adds after calling super.
|
|
207
|
-
def save_mapper(out)
|
|
208
|
-
save_windows(out, windows) if windows
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
def load_mapper(input)
|
|
212
|
-
load_windows(input, windows) if windows
|
|
213
|
-
end
|
|
214
|
-
|
|
215
|
-
# The banks and views ROML and ROMH can point at, which a snapshot
|
|
216
|
-
# names them by: the mapper's banks, or nothing for a mapper whose
|
|
217
|
-
# windows stay where install_chips put them.
|
|
218
|
-
def windows
|
|
219
|
-
[*@banks, EMPTY_BANK] if @banks
|
|
220
|
-
end
|
|
221
|
-
|
|
222
|
-
# Where the ROML and ROMH windows point, as their places in `windows`,
|
|
223
|
-
# the banks and views the mapper picks them from, or -1 for none.
|
|
224
|
-
def save_windows(out, windows)
|
|
225
|
-
out.int(window_index(@roml, windows)).int(window_index(@romh, windows))
|
|
226
|
-
end
|
|
227
|
-
|
|
228
|
-
def load_windows(input, windows)
|
|
229
|
-
@roml = window_at(input.int, windows)
|
|
230
|
-
@romh = window_at(input.int, windows)
|
|
231
|
-
end
|
|
232
|
-
|
|
233
|
-
def window_index(window, windows)
|
|
234
|
-
return -1 if window.nil?
|
|
235
|
-
|
|
236
|
-
windows.index { |candidate| candidate.equal?(window) } ||
|
|
237
|
-
raise(ArgumentError, "#{self.class.name}: a window that isn't among its banks")
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
def window_at(index, windows) = index.negative? ? nil : windows.fetch(index)
|
|
241
|
-
|
|
242
|
-
def nmi=(level)
|
|
243
|
-
return if @nmi == level
|
|
244
|
-
|
|
245
|
-
@nmi = level
|
|
246
|
-
@on_nmi_change&.call(level)
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
def changed!
|
|
250
|
-
@on_change&.call
|
|
251
|
-
end
|
|
252
|
-
|
|
253
|
-
def mode=(mode)
|
|
254
|
-
@exrom, @game = MODES.fetch(mode)
|
|
255
|
-
end
|
|
256
|
-
|
|
257
|
-
# Sets the lines and tells the machine to map the cartridge again.
|
|
258
|
-
def select_mode(mode)
|
|
259
|
-
self.mode = mode
|
|
260
|
-
changed!
|
|
261
|
-
end
|
|
262
|
-
|
|
263
|
-
def open_bus(addr)
|
|
264
|
-
@open_bus ? @open_bus.peek(addr) : 0xff
|
|
265
|
-
end
|
|
266
|
-
|
|
267
|
-
def install_chips(_chips)
|
|
268
|
-
raise NotImplementedError
|
|
269
|
-
end
|
|
270
|
-
|
|
271
|
-
def rom_bank(data)
|
|
272
|
-
Bank.new(data)
|
|
273
|
-
end
|
|
274
|
-
|
|
275
|
-
# A bank the image leaves out reads as erased ROM.
|
|
276
|
-
def bank(banks, number)
|
|
277
|
-
banks[number] || EMPTY_BANK
|
|
278
|
-
end
|
|
279
|
-
|
|
280
|
-
# The bank register bits a ROM decodes. The ROM holds the highest bank
|
|
281
|
-
# in the image, and has address lines for the power of two that covers
|
|
282
|
-
# it; the register bits above those lines are ignored.
|
|
283
|
-
def bank_mask(banks)
|
|
284
|
-
(1 << (banks.length - 1).bit_length) - 1
|
|
285
|
-
end
|
|
286
|
-
|
|
287
|
-
# Sorts the CHIP packets into ROML and ROMH banks by load address. A 16K
|
|
288
|
-
# chip at $8000 spans both.
|
|
289
|
-
def banks_from(chips)
|
|
290
|
-
roml = []
|
|
291
|
-
romh = []
|
|
292
|
-
chips.each do |chip|
|
|
293
|
-
if chip.address >= ROMH_START
|
|
294
|
-
romh[chip.bank] = rom_bank(chip.data)
|
|
295
|
-
else
|
|
296
|
-
roml[chip.bank] = rom_bank(chip.data[0, BANK_SIZE])
|
|
297
|
-
romh[chip.bank] = rom_bank(chip.data[BANK_SIZE, BANK_SIZE]) if chip.data.length > BANK_SIZE
|
|
298
|
-
end
|
|
299
|
-
end
|
|
300
|
-
[roml, romh]
|
|
301
|
-
end
|
|
302
|
-
end
|
|
303
|
-
end
|
data/lib/badline/checkpoint.rb
DELETED
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
# A digest of the machine's state at one cycle, for comparing two runs of
|
|
5
|
-
# the same scenario, on two builds or two revisions. Each component is
|
|
6
|
-
# hashed on its own with 32-bit FNV-1a, so a mismatch names the part of the
|
|
7
|
-
# machine that went its own way. Nothing is read through a chip's bus
|
|
8
|
-
# interface, so taking a checkpoint leaves the machine as it was.
|
|
9
|
-
#
|
|
10
|
-
# Colour RAM is digested as the four bits each cell stores: the upper
|
|
11
|
-
# nibble a CPU read sees comes off the open bus.
|
|
12
|
-
class Checkpoint
|
|
13
|
-
COMPONENTS = %w[cpu ram color_ram display vic cia1 cia2 sid].freeze
|
|
14
|
-
|
|
15
|
-
FNV_OFFSET = 0x811c9dc5
|
|
16
|
-
FNV_PRIME = 0x01000193
|
|
17
|
-
|
|
18
|
-
attr_reader :cycle, :digests
|
|
19
|
-
|
|
20
|
-
class << self
|
|
21
|
-
def take(computer)
|
|
22
|
-
new(computer.cycles, [
|
|
23
|
-
fnv1a(cpu_state(computer.cpu)),
|
|
24
|
-
fnv1a(ram(computer.ram)),
|
|
25
|
-
fnv1a(color_ram(computer.address_bus.color_ram)),
|
|
26
|
-
fnv1a(computer.vic.display),
|
|
27
|
-
fnv1a(vic_state(computer.vic)),
|
|
28
|
-
fnv1a(cia_state(computer.cia1)),
|
|
29
|
-
fnv1a(cia_state(computer.cia2)),
|
|
30
|
-
fnv1a(Array.new(0x20) { |reg| computer.sid.register(reg) })
|
|
31
|
-
])
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# Reads a line written by #to_s.
|
|
35
|
-
def parse(line)
|
|
36
|
-
fields = line.split
|
|
37
|
-
digests = COMPONENTS.map do |name|
|
|
38
|
-
field = fields.find { |f| f.start_with?("#{name}=") }
|
|
39
|
-
raise ArgumentError, "no #{name} digest in #{line.inspect}" unless field
|
|
40
|
-
|
|
41
|
-
field.split("=").last.to_i(16)
|
|
42
|
-
end
|
|
43
|
-
new(fields.first.to_i, digests)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def fnv1a(values)
|
|
47
|
-
hash = FNV_OFFSET
|
|
48
|
-
values.each { |value| hash = ((hash ^ (value & 0xffffffff)) * FNV_PRIME) & 0xffffffff }
|
|
49
|
-
hash
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
private
|
|
53
|
-
|
|
54
|
-
def cpu_state(cpu)
|
|
55
|
-
[cpu.program_counter, cpu.a, cpu.x, cpu.y, cpu.stack_pointer, cpu.p, cpu.cycles]
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def ram(memory)
|
|
59
|
-
Array.new(0x10000) { |addr| memory.peek(addr) }
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def color_ram(memory)
|
|
63
|
-
Array.new(0x400) { |offset| memory.nibble(0xd800 + offset) }
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def vic_state(vic)
|
|
67
|
-
vic.register_file + [vic.rasterline, vic.column]
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
def cia_state(cia)
|
|
71
|
-
start = cia.start
|
|
72
|
-
[cia.peek(start), cia.peek(start + 1), cia.peek(start + 2), cia.peek(start + 3),
|
|
73
|
-
cia.timer_a, cia.timer_a_latch, cia.timer_b, cia.timer_b_latch, cia.serial.data,
|
|
74
|
-
cia.control_a.value, cia.control_b.value, cia.interrupt_status.value,
|
|
75
|
-
cia.interrupt_control.value] + cia.time_of_day.registers
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def initialize(cycle, digests)
|
|
80
|
-
@cycle = cycle
|
|
81
|
-
@digests = digests
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# The components whose digests differ from `other`'s.
|
|
85
|
-
def differences(other)
|
|
86
|
-
COMPONENTS.each_index.reject { |i| digests[i] == other.digests[i] }.map { |i| COMPONENTS[i] }
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def ==(other)
|
|
90
|
-
other.is_a?(Checkpoint) && cycle == other.cycle && digests == other.digests
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def to_s
|
|
94
|
-
fields = COMPONENTS.each_index.map { |i| "#{COMPONENTS[i]}=#{digests[i].to_s(16).rjust(8, '0')}" }
|
|
95
|
-
"#{cycle} #{fields.join(' ')}"
|
|
96
|
-
end
|
|
97
|
-
end
|
|
98
|
-
end
|
data/lib/badline/chrout_trap.rb
DELETED
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
# Observe-only PC trap on the KERNAL CHROUT routine ($FFD2). Records each
|
|
5
|
-
# character written while the layout finds the KERNAL mapped in, then lets execution fall
|
|
6
|
-
# through to the ROM, so the screen output is unaffected. Used for headless
|
|
7
|
-
# capture of program output.
|
|
8
|
-
class ChroutTrap
|
|
9
|
-
ADDRESS = 0xffd2
|
|
10
|
-
|
|
11
|
-
attr_reader :output
|
|
12
|
-
|
|
13
|
-
# The KERNAL layout whose mapping the trap checks.
|
|
14
|
-
attr_writer :layout
|
|
15
|
-
|
|
16
|
-
def initialize(cpu:, bus:, layout:)
|
|
17
|
-
@cpu = cpu
|
|
18
|
-
@bus = bus
|
|
19
|
-
@layout = layout
|
|
20
|
-
@output = +""
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def call
|
|
24
|
-
@output << ascii(@cpu.a) if @layout.kernal_mapped?(@bus)
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def inspect
|
|
28
|
-
"#<#{self.class.name} output=#{@output.inspect}>"
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
private
|
|
32
|
-
|
|
33
|
-
def ascii(byte)
|
|
34
|
-
case byte
|
|
35
|
-
when 0x0d then "\n"
|
|
36
|
-
when 0x41..0x5a then (byte + 0x20).chr
|
|
37
|
-
when 0xc1..0xda then (byte - 0x80).chr
|
|
38
|
-
when 0x20..0x7e then byte.chr
|
|
39
|
-
else ""
|
|
40
|
-
end
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
end
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
class CIA
|
|
5
|
-
# Running a CIA a stretch of cycles at once, for Drive::Idle.
|
|
6
|
-
module FastForward
|
|
7
|
-
# quiet_cycles for a CIA whose counters will never set a flag.
|
|
8
|
-
QUIET = 1 << 40
|
|
9
|
-
|
|
10
|
-
# Whether fast_forward can run the CIA: timer B stopped with nothing
|
|
11
|
-
# in its pipeline, no interrupt or acknowledge on its way, CNT where it
|
|
12
|
-
# was, the TOD clock stopped, and timer A either stopped, or free
|
|
13
|
-
# running (Timer#free_running?) with its interrupt masked and the
|
|
14
|
-
# serial port an idle input. Drive::Idle sleeps the 1571's CIA through
|
|
15
|
-
# such cycles, which its DOS leaves timer A running in.
|
|
16
|
-
def quiet?
|
|
17
|
-
return false unless @tb.idle? && @icr.quiet && @tod.quiet? && cnt_steady?
|
|
18
|
-
|
|
19
|
-
@ta.idle? ? @serial.idle : timer_a_free_running?
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# How many cycles the CIA can run with nothing but its counters
|
|
23
|
-
# moving: as quiet? allows, but with timer B free running too, up to
|
|
24
|
-
# the cycle before it underflows. The 1581's DOS leaves timer B
|
|
25
|
-
# interrupting every 10 ms.
|
|
26
|
-
def quiet_cycles
|
|
27
|
-
return 0 unless @icr.quiet && @tod.quiet? && cnt_steady? && timer_a_quiet?
|
|
28
|
-
return QUIET if @tb.idle?
|
|
29
|
-
return 0 unless @tb.free_running? && @control_b.value.nobits?(0x60)
|
|
30
|
-
|
|
31
|
-
@tb.counter - 1
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# Runs +cycles+ cycles at once while quiet? or for quiet_cycles, as
|
|
35
|
-
# cycle! would: timer A's underflows flag in the ICR, and reach the
|
|
36
|
-
# serial port's underflow line.
|
|
37
|
-
def fast_forward(cycles)
|
|
38
|
-
@tod.fast_forward(cycles)
|
|
39
|
-
@tb.fast_forward(cycles) unless @tb.idle?
|
|
40
|
-
return if @ta.idle?
|
|
41
|
-
|
|
42
|
-
@icr.flag(:timer_a) if @ta.fast_forward(cycles).positive?
|
|
43
|
-
@serial.follow_underflow(@ta.underflowed)
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
private
|
|
47
|
-
|
|
48
|
-
def timer_a_quiet? = @ta.idle? ? @serial.idle : timer_a_free_running?
|
|
49
|
-
|
|
50
|
-
# Timer A free running with its interrupt masked, and the serial port
|
|
51
|
-
# an idle input it only clocks.
|
|
52
|
-
def timer_a_free_running?
|
|
53
|
-
@ta.free_running? && !@control_a.serial_mode? && @icr.mask.value.nobits?(0x01) && @serial.drained?
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
# Whether CNT holds the level the last cycle sampled.
|
|
57
|
-
def cnt_steady? = @serial.cnt == @cnt_high && !@cnt_rise
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
end
|