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,232 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "badline/c64/cartridge/bank"
|
|
4
|
+
require "badline/c64/cartridge/flash"
|
|
5
|
+
require "badline/c64/cartridge/standard"
|
|
6
|
+
require "badline/c64/cartridge/simons_basic"
|
|
7
|
+
require "badline/c64/cartridge/ocean"
|
|
8
|
+
require "badline/c64/cartridge/fun_play"
|
|
9
|
+
require "badline/c64/cartridge/super_games"
|
|
10
|
+
require "badline/c64/cartridge/epyx_fastload"
|
|
11
|
+
require "badline/c64/cartridge/westermann"
|
|
12
|
+
require "badline/c64/cartridge/rex_utility"
|
|
13
|
+
require "badline/c64/cartridge/game_system"
|
|
14
|
+
require "badline/c64/cartridge/dinamic"
|
|
15
|
+
require "badline/c64/cartridge/zaxxon"
|
|
16
|
+
require "badline/c64/cartridge/magic_desk"
|
|
17
|
+
require "badline/c64/cartridge/comal80"
|
|
18
|
+
require "badline/c64/cartridge/easy_flash"
|
|
19
|
+
require "badline/c64/cartridge/mach5"
|
|
20
|
+
require "badline/c64/cartridge/pagefox"
|
|
21
|
+
require "badline/c64/cartridge/rgcd"
|
|
22
|
+
require "badline/c64/cartridge/g_mod2"
|
|
23
|
+
require "badline/c64/cartridge/freezer"
|
|
24
|
+
require "badline/c64/cartridge/action_replay"
|
|
25
|
+
require "badline/c64/cartridge/atomic_power"
|
|
26
|
+
require "badline/c64/cartridge/final_cartridge3"
|
|
27
|
+
require "badline/c64/cartridge/retro_replay"
|
|
28
|
+
require "badline/c64/cartridge/kcs_power"
|
|
29
|
+
require "badline/c64/cartridge/geo_ram"
|
|
30
|
+
|
|
31
|
+
module Badline
|
|
32
|
+
class C64
|
|
33
|
+
class Cartridge
|
|
34
|
+
class UnsupportedTypeError < StandardError; end
|
|
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
|
+
def mapper_for(crt)
|
|
70
|
+
HARDWARE_TYPES.fetch(crt.hardware_type) do
|
|
71
|
+
raise UnsupportedTypeError,
|
|
72
|
+
"Unsupported cartridge hardware type #{crt.hardware_type}"
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# Keeps the image it was built from, so a snapshot's machine can build
|
|
78
|
+
# the same cartridge before the snapshot's state goes into it.
|
|
79
|
+
def initialize(crt)
|
|
80
|
+
@crt = crt
|
|
81
|
+
@name = crt.name
|
|
82
|
+
@exrom = crt.exrom
|
|
83
|
+
@game = crt.game
|
|
84
|
+
@roml = @romh = nil
|
|
85
|
+
@banks = nil
|
|
86
|
+
@on_change = nil
|
|
87
|
+
@on_nmi_change = nil
|
|
88
|
+
@nmi = false
|
|
89
|
+
@open_bus = nil
|
|
90
|
+
@clock = nil
|
|
91
|
+
install_chips(crt.chips)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def on_change(&block)
|
|
95
|
+
@on_change = block
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Called with the level of the cartridge's pull on the NMI line when it
|
|
99
|
+
# changes. The line is wired-OR with CIA 2's.
|
|
100
|
+
def on_nmi_change(&block)
|
|
101
|
+
@on_nmi_change = block
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def nmi?
|
|
105
|
+
@nmi
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
# The address bus hands over the C64's RAM, for mappers that write
|
|
109
|
+
# through to it, and the open bus, for I/O reads the cartridge doesn't
|
|
110
|
+
# drive.
|
|
111
|
+
def connect(ram:, open_bus:)
|
|
112
|
+
@ram = ram
|
|
113
|
+
@open_bus = open_bus
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def ultimax?
|
|
117
|
+
@game.zero? && @exrom == 1
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# Whether the first half of the cycle, where the VIC does most of its
|
|
121
|
+
# fetching, sees Ultimax mode. Some cartridges drive GAME and EXROM
|
|
122
|
+
# differently in the two halves; #ultimax? is the second, the CPU's.
|
|
123
|
+
def phi1_ultimax?
|
|
124
|
+
ultimax?
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# The I/O pages ($de, $df) whose reads the mapper drives. Reads of the
|
|
128
|
+
# others are open bus.
|
|
129
|
+
def readable_io_pages
|
|
130
|
+
[]
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def poke(_addr, _value); end
|
|
134
|
+
|
|
135
|
+
# A window taking writes to $E000-$FFFF while reads there see the C64's
|
|
136
|
+
# memory, for a cartridge that asserts Ultimax on write cycles only.
|
|
137
|
+
def romh_writes; end
|
|
138
|
+
|
|
139
|
+
# A window at $A000-$BFFF in Ultimax mode, where the C64 maps nothing.
|
|
140
|
+
def ultimax_a000; end
|
|
141
|
+
|
|
142
|
+
# The RES line on the expansion port.
|
|
143
|
+
def reset; end
|
|
144
|
+
|
|
145
|
+
# Whether the cartridge has a freeze button.
|
|
146
|
+
def freezer? = false
|
|
147
|
+
|
|
148
|
+
# The freeze button, which cartridges without one ignore.
|
|
149
|
+
def press_button; end
|
|
150
|
+
|
|
151
|
+
def release_button; end
|
|
152
|
+
|
|
153
|
+
private
|
|
154
|
+
|
|
155
|
+
# The banks and views ROML and ROMH can point at, which a snapshot
|
|
156
|
+
# names them by: the mapper's banks, or nothing for a mapper whose
|
|
157
|
+
# windows stay where install_chips put them.
|
|
158
|
+
def windows
|
|
159
|
+
[*@banks, EMPTY_BANK] if @banks
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def window_index(window, windows)
|
|
163
|
+
return -1 if window.nil?
|
|
164
|
+
|
|
165
|
+
windows.index { |candidate| candidate.equal?(window) } ||
|
|
166
|
+
raise(ArgumentError, "#{self.class.name}: a window that isn't among its banks")
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def nmi=(level)
|
|
170
|
+
return if @nmi == level
|
|
171
|
+
|
|
172
|
+
@nmi = level
|
|
173
|
+
@on_nmi_change&.call(level)
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def changed!
|
|
177
|
+
@on_change&.call
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def mode=(mode)
|
|
181
|
+
@exrom, @game = MODES.fetch(mode)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
# Sets the lines and tells the machine to map the cartridge again.
|
|
185
|
+
def select_mode(mode)
|
|
186
|
+
self.mode = mode
|
|
187
|
+
changed!
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def open_bus(addr)
|
|
191
|
+
@open_bus ? @open_bus.peek(addr) : 0xff
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def install_chips(_chips)
|
|
195
|
+
raise NotImplementedError
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
def rom_bank(data)
|
|
199
|
+
Bank.new(data)
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# A bank the image leaves out reads as erased ROM.
|
|
203
|
+
def bank(banks, number)
|
|
204
|
+
banks[number] || EMPTY_BANK
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
# The bank register bits a ROM decodes. The ROM holds the highest bank
|
|
208
|
+
# in the image, and has address lines for the power of two that covers
|
|
209
|
+
# it; the register bits above those lines are ignored.
|
|
210
|
+
def bank_mask(banks)
|
|
211
|
+
(1 << (banks.length - 1).bit_length) - 1
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# Sorts the CHIP packets into ROML and ROMH banks by load address. A 16K
|
|
215
|
+
# chip at $8000 spans both.
|
|
216
|
+
def banks_from(chips)
|
|
217
|
+
roml = []
|
|
218
|
+
romh = []
|
|
219
|
+
chips.each do |chip|
|
|
220
|
+
if chip.address >= ROMH_START
|
|
221
|
+
romh[chip.bank] = rom_bank(chip.data)
|
|
222
|
+
else
|
|
223
|
+
roml[chip.bank] = rom_bank(chip.data[0, BANK_SIZE])
|
|
224
|
+
romh[chip.bank] = rom_bank(chip.data[BANK_SIZE, BANK_SIZE]) if chip.data.length > BANK_SIZE
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
[roml, romh]
|
|
228
|
+
end
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
require "badline/c64/cartridge/keyed_state"
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class C64
|
|
5
|
+
# Colour RAM is four bits wide. A CPU read takes the upper nibble off the
|
|
6
|
+
# open data bus, which still holds the byte the VIC fetched in phi1.
|
|
7
|
+
class ColorMemory < Memory
|
|
8
|
+
def initialize(vic, start: 0xd800, length: 2**10)
|
|
9
|
+
super(start:, length:)
|
|
10
|
+
@vic = vic
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def peek(addr)
|
|
14
|
+
(@vic.phi1_data & 0xf0) | @storage[offset_of(addr)]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def poke(addr, value)
|
|
18
|
+
super(addr, value & 0x0f)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# The four bits the cell stores, as the VIC's c-access sees them.
|
|
22
|
+
def nibble(addr)
|
|
23
|
+
@storage[offset_of(addr)]
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Badline
|
|
4
|
-
class
|
|
4
|
+
class C64
|
|
5
5
|
# What the C128 does as the C64 does: the NMI line, a PRG put into RAM
|
|
6
|
-
# and the region's timing.
|
|
6
|
+
# and the region's timing. C64 and C128 each include it.
|
|
7
7
|
module Common
|
|
8
8
|
# The clock, the raster and the crop of the machine's region, a pixel
|
|
9
9
|
# to a window pixel.
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Badline
|
|
4
|
-
class
|
|
4
|
+
class C64
|
|
5
5
|
# The disk device 8 serves through the LOAD, SAVE and serial traps, and
|
|
6
|
-
# CHROUT capture, on the KERNAL the machine runs.
|
|
6
|
+
# CHROUT capture, on the KERNAL the machine runs. C64, Vic20 and
|
|
7
7
|
# C128 each include it and answer two private methods: #trap_layout,
|
|
8
8
|
# the KernalTrap::Layout of that KERNAL, and #trap_bus, the bus the
|
|
9
9
|
# traps read and write through.
|
|
@@ -13,9 +13,9 @@ module Badline
|
|
|
13
13
|
# drive reset clears, and its status. The traps go on the KERNAL the
|
|
14
14
|
# machine runs (#trap_layout).
|
|
15
15
|
def mount(storage)
|
|
16
|
-
return @
|
|
16
|
+
return @dos.insert(storage) if @dos
|
|
17
17
|
|
|
18
|
-
@
|
|
18
|
+
@dos = KernalTrap::DOS.new(storage)
|
|
19
19
|
install_kernal_traps(trap_layout)
|
|
20
20
|
end
|
|
21
21
|
|
|
@@ -23,35 +23,60 @@ module Badline
|
|
|
23
23
|
# serial traps, so the KERNAL's routines go out over the serial bus.
|
|
24
24
|
# Mounting again starts a new drive, with its RAM cleared.
|
|
25
25
|
def unmount
|
|
26
|
-
return unless @
|
|
26
|
+
return unless @dos
|
|
27
27
|
|
|
28
28
|
remove_kernal_traps
|
|
29
|
-
@
|
|
29
|
+
@dos = nil
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
# Whether device 8 serves a disk or directory through the traps.
|
|
33
|
-
def mounted? = !@
|
|
33
|
+
def mounted? = !@dos.nil?
|
|
34
34
|
|
|
35
35
|
# The path of the disk or directory device 8 serves through the
|
|
36
36
|
# traps, or an empty one.
|
|
37
|
-
def mounted_path = @
|
|
37
|
+
def mounted_path = @dos.nil? ? "" : @dos.path
|
|
38
38
|
|
|
39
|
-
# Records what the KERNAL prints through CHROUT (
|
|
39
|
+
# Records what the KERNAL prints through CHROUT (KernalTrap::Chrout).
|
|
40
40
|
def capture_output
|
|
41
|
-
@capture_output ||=
|
|
42
|
-
cpu.install_trap(
|
|
41
|
+
@capture_output ||= KernalTrap::Chrout.new(cpu:, bus: trap_bus, layout: trap_layout).tap do |trap|
|
|
42
|
+
cpu.install_trap(KernalTrap::Chrout::ADDRESS) { trap.call }
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
45
|
|
|
46
|
+
# Device 8 through the KERNAL traps in a keyed snapshot module
|
|
47
|
+
# (BL-TRAPDOS): the storage under storage.*, the DOS, the serial
|
|
48
|
+
# trap under serial.* and the SAVE trap under save.*. Nothing mounted
|
|
49
|
+
# writes nothing.
|
|
50
|
+
def save_trap_dos_fields(out)
|
|
51
|
+
dos = @dos
|
|
52
|
+
return unless dos
|
|
53
|
+
|
|
54
|
+
Snapshot::StorageSetup.write_fields(dos.storage, out)
|
|
55
|
+
dos.save_fields(out)
|
|
56
|
+
@serial_trap&.save_fields(out, "serial.")
|
|
57
|
+
@save_trap&.save_fields(out, "save.")
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# `detached` mounts a disk image write-protected and no directory.
|
|
61
|
+
def load_trap_dos_fields(input, detached: false)
|
|
62
|
+
unmount
|
|
63
|
+
return if input.missing?
|
|
64
|
+
|
|
65
|
+
mount(Snapshot::StorageSetup.read_fields(input, detached:))
|
|
66
|
+
@dos&.load_fields(input)
|
|
67
|
+
@serial_trap&.load_fields(input, "serial.")
|
|
68
|
+
@save_trap&.load_fields(input, "save.")
|
|
69
|
+
end
|
|
70
|
+
|
|
46
71
|
private
|
|
47
72
|
|
|
48
73
|
def install_kernal_traps(layout)
|
|
49
74
|
@trap_layout = layout
|
|
50
|
-
load_trap = KernalTrap::Load.new(cpu:, bus: trap_bus, layout:,
|
|
75
|
+
load_trap = KernalTrap::Load.new(cpu:, bus: trap_bus, layout:, dos: @dos)
|
|
51
76
|
cpu.install_trap(layout.load) { load_trap.call }
|
|
52
|
-
@serial_trap = KernalTrap::Serial.new(cpu:, bus: trap_bus, layout:,
|
|
77
|
+
@serial_trap = KernalTrap::Serial.new(cpu:, bus: trap_bus, layout:, dos: @dos,
|
|
53
78
|
device: serial_trap_device).install
|
|
54
|
-
save_trap = @save_trap = KernalTrap::Save.new(cpu:, bus: trap_bus, layout:,
|
|
79
|
+
save_trap = @save_trap = KernalTrap::Save.new(cpu:, bus: trap_bus, layout:, dos: @dos)
|
|
55
80
|
cpu.install_trap(layout.save) { save_trap.call }
|
|
56
81
|
end
|
|
57
82
|
|
|
@@ -62,28 +87,6 @@ module Badline
|
|
|
62
87
|
@serial_trap = nil
|
|
63
88
|
@save_trap = nil
|
|
64
89
|
end
|
|
65
|
-
|
|
66
|
-
# The disk device 8 serves through the traps, with the traps' own
|
|
67
|
-
# state: open channels, the drive's status and RAM, a SAVE under way.
|
|
68
|
-
def save_trap_drive(out)
|
|
69
|
-
out.boolean(!@drive.nil?)
|
|
70
|
-
return unless @drive
|
|
71
|
-
|
|
72
|
-
@drive.save_state(out)
|
|
73
|
-
@serial_trap.save_state(out)
|
|
74
|
-
@save_trap.save_state(out)
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def load_trap_drive(input)
|
|
78
|
-
return unmount unless input.boolean?
|
|
79
|
-
|
|
80
|
-
storage = Storage.reopen(input)
|
|
81
|
-
unmount
|
|
82
|
-
mount(storage)
|
|
83
|
-
@drive.load_state(input)
|
|
84
|
-
@serial_trap.load_state(input)
|
|
85
|
-
@save_trap.load_state(input)
|
|
86
|
-
end
|
|
87
90
|
end
|
|
88
91
|
end
|
|
89
92
|
end
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class C64
|
|
5
|
+
# The whole machine as keyed snapshot modules (Snapshot::Keyed), in the
|
|
6
|
+
# order a load applies them: BL-MACHINE with the setup, the memories,
|
|
7
|
+
# the cartridge, the CPU with its port, the chips, an REU, the
|
|
8
|
+
# datasette, device 8 through the traps and the true drives. A load
|
|
9
|
+
# reads the CPU's port before the chips, so the banks are mapped as the
|
|
10
|
+
# chips load, and the CPU's own fields after them. What each unit works
|
|
11
|
+
# out again from its fields comes last, once every unit is loaded.
|
|
12
|
+
module KeyedModules
|
|
13
|
+
def save_modules
|
|
14
|
+
bus = address_bus
|
|
15
|
+
sections = [Snapshot::Keyed.section("BL-MACHINE") { |out| save_machine_fields(out) },
|
|
16
|
+
Snapshot::Keyed.section("BL-RAM") { |out| bus.ram.save_fields(out, "ram") }]
|
|
17
|
+
expansion = bus.ram_expansion
|
|
18
|
+
sections << Snapshot::Keyed.section("BL-RAMEXP") { |out| expansion.save_fields(out) } if expansion.type
|
|
19
|
+
sections << Snapshot::Keyed.section("BL-COLORRAM") { |out| bus.color_ram.save_fields(out, "ram") }
|
|
20
|
+
cartridge = bus.cartridge
|
|
21
|
+
sections << Snapshot::Keyed.section("BL-CART") { |out| cartridge.save_fields(out) } if cartridge
|
|
22
|
+
save_chip_modules(sections, bus)
|
|
23
|
+
reu = @reu
|
|
24
|
+
sections << Snapshot::Keyed.section("BL-REU") { |out| reu.save_fields(out) } if reu
|
|
25
|
+
sections << Snapshot::Keyed.section("BL-TAPE") { |out| bus.datasette.save_fields(out) }
|
|
26
|
+
sections << Snapshot::Keyed.section("BL-TRAPDOS") { |out| save_trap_dos_fields(out) } if mounted?
|
|
27
|
+
save_drive_modules(sections)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Raises Snapshot::FormatError for the modules of a machine built
|
|
31
|
+
# another way.
|
|
32
|
+
def load_modules(modules)
|
|
33
|
+
machine = modules.machine
|
|
34
|
+
check_snapshot_setup(Snapshot::C64Setup.read_fields(machine))
|
|
35
|
+
load_machine_fields(machine)
|
|
36
|
+
bus = address_bus
|
|
37
|
+
bus.ram.load_fields(modules.required("BL-RAM"), "ram")
|
|
38
|
+
bus.ram_expansion.load_fields(modules.required("BL-RAMEXP")) if bus.ram_expansion.type
|
|
39
|
+
bus.color_ram.load_fields(modules.required("BL-COLORRAM"), "ram")
|
|
40
|
+
load_cartridge_module(modules.optional("BL-CART"))
|
|
41
|
+
cpu = modules.required("BL-CPU")
|
|
42
|
+
bus.load_port_fields(cpu)
|
|
43
|
+
bus.restored!
|
|
44
|
+
load_chip_modules(modules, cpu)
|
|
45
|
+
bus.datasette.load_fields(modules.required("BL-TAPE"))
|
|
46
|
+
load_trap_dos_module(modules)
|
|
47
|
+
load_drive_modules(modules)
|
|
48
|
+
modules_restored!
|
|
49
|
+
self
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
private
|
|
53
|
+
|
|
54
|
+
def save_chip_modules(sections, bus)
|
|
55
|
+
sections << Snapshot::Keyed.section("BL-CPU") do |out|
|
|
56
|
+
@cpu.save_fields(out)
|
|
57
|
+
bus.save_port_fields(out)
|
|
58
|
+
end
|
|
59
|
+
sections << Snapshot::Keyed.section("BL-VIC") { |out| @vic.save_fields(out) }
|
|
60
|
+
sections << Snapshot::Keyed.section("BL-CIA1") { |out| @cia1.save_fields(out) }
|
|
61
|
+
sections << Snapshot::Keyed.section("BL-CIA2") { |out| @cia2.save_fields(out) }
|
|
62
|
+
sections << Snapshot::Keyed.section("BL-SID") { |out| @sid.save_fields(out) }
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def load_chip_modules(modules, cpu)
|
|
66
|
+
@vic.load_fields(modules.required("BL-VIC"))
|
|
67
|
+
@cia1.load_fields(modules.required("BL-CIA1"))
|
|
68
|
+
@cia2.load_fields(modules.required("BL-CIA2"))
|
|
69
|
+
@sid.load_fields(modules.required("BL-SID"))
|
|
70
|
+
@reu&.load_fields(modules.required("BL-REU"))
|
|
71
|
+
@cpu.load_fields(cpu)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# The cartridge comes back built afresh from the CRT image the module
|
|
75
|
+
# holds, before its state goes in. No module means no cartridge.
|
|
76
|
+
def load_cartridge_module(input)
|
|
77
|
+
if input
|
|
78
|
+
cartridge = Cartridge.from_fields(input)
|
|
79
|
+
connect_cartridge(cartridge)
|
|
80
|
+
cartridge.load_fields(input)
|
|
81
|
+
elsif address_bus.cartridge
|
|
82
|
+
address_bus.detach_cartridge
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def load_trap_dos_module(modules)
|
|
87
|
+
input = modules.optional("BL-TRAPDOS")
|
|
88
|
+
input ? load_trap_dos_fields(input, detached: modules.detached?) : unmount
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
def modules_restored!
|
|
92
|
+
@cpu.restored!
|
|
93
|
+
@vic.restored!
|
|
94
|
+
@cia1.restored!
|
|
95
|
+
@cia2.restored!
|
|
96
|
+
@sid.restored!
|
|
97
|
+
@reu&.restored!
|
|
98
|
+
machine_restored!
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def check_snapshot_setup(setup)
|
|
102
|
+
ours = Snapshot::C64Setup.of(address_bus)
|
|
103
|
+
return if setup == ours
|
|
104
|
+
|
|
105
|
+
raise Snapshot::FormatError, "the snapshot is of a machine with #{setup}, not #{ours}"
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
include KeyedModules
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class C64
|
|
5
|
+
# The machine's own fields in a keyed snapshot module (Snapshot::Keyed,
|
|
6
|
+
# BL-MACHINE): the family, its setup by name, the cycle count, the NMI
|
|
7
|
+
# glue, the freezer's write count and the REU's hold on the bus, and the
|
|
8
|
+
# host's typing still to feed and on_init handlers still to run under
|
|
9
|
+
# host.*. The badline version that wrote it is written for reports and
|
|
10
|
+
# never read.
|
|
11
|
+
module KeyedState
|
|
12
|
+
# How many more on_init handlers the machine a snapshot was taken of had
|
|
13
|
+
# yet to run than this one has: they are the host's blocks, which a
|
|
14
|
+
# snapshot can't hold. Nil until the machine is restored.
|
|
15
|
+
attr_reader :init_handlers_lost
|
|
16
|
+
|
|
17
|
+
# Sets the machine's cycle count, for a snapshot from VICE, which
|
|
18
|
+
# counts from its own clock.
|
|
19
|
+
def resume_at(cycles)
|
|
20
|
+
@cycles = cycles
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Whether a snapshot saves now (Machine::Settling): the CPU between
|
|
24
|
+
# instructions or jammed, and no REU transfer under way.
|
|
25
|
+
def settled_for_snapshot? = (@cpu.boundary? || @cpu.jammed?) && !reu&.dma?
|
|
26
|
+
|
|
27
|
+
# The SID's deferred cycles and writes, run up to this cycle, and the
|
|
28
|
+
# VIC's sprite collisions latched up to the beam.
|
|
29
|
+
def settle_chips_for_snapshot
|
|
30
|
+
sid.catch_up!
|
|
31
|
+
@vic.fold_collisions!
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def save_machine_fields(out)
|
|
35
|
+
out.text("family", "c64").text("written_by", VERSION)
|
|
36
|
+
Snapshot::C64Setup.of(address_bus).write_fields(out)
|
|
37
|
+
out.int("cycles", @cycles).bool("nmi_asserted", @nmi_asserted).bool("cartridge_nmi", @cartridge_nmi)
|
|
38
|
+
out.bool("restore_pulse", @restore_pulse).bool("freezing", @freezing).int("freeze_writes", @freeze_writes)
|
|
39
|
+
out.bool("dma", @dma)
|
|
40
|
+
pending = @pending_keys
|
|
41
|
+
out.ints("host.pending_keys", pending) if pending
|
|
42
|
+
out.int("host.init_pending", booting? ? @init_handlers.length : 0)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def load_machine_fields(input)
|
|
46
|
+
@cycles = input.int("cycles", @cycles)
|
|
47
|
+
@nmi_asserted = input.bool("nmi_asserted", @nmi_asserted)
|
|
48
|
+
@cartridge_nmi = input.bool("cartridge_nmi", @cartridge_nmi)
|
|
49
|
+
@restore_pulse = input.bool("restore_pulse", @restore_pulse)
|
|
50
|
+
@freezing = input.bool("freezing", @freezing)
|
|
51
|
+
@freeze_writes = input.int("freeze_writes", @freeze_writes)
|
|
52
|
+
@dma = input.bool("dma", @dma)
|
|
53
|
+
pending = input.ints("host.pending_keys", [])
|
|
54
|
+
@pending_keys = pending.empty? ? nil : pending.dup
|
|
55
|
+
@init_handlers_lost = [input.int("host.init_pending", 0) - @init_handlers.length, 0].max
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# The REU's IRQ line and the serial bus's lines from CIA 2, once the
|
|
59
|
+
# chips are loaded.
|
|
60
|
+
def machine_restored!
|
|
61
|
+
@reu_irq = @reu.nil? ? false : @reu.irq?
|
|
62
|
+
push_serial_lines
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
include KeyedState
|
|
67
|
+
end
|
|
68
|
+
end
|