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,275 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "badline/vic/border_mask"
|
|
4
|
-
require "badline/vic/color_patches"
|
|
5
|
-
require "badline/vic/graphics_mode"
|
|
6
|
-
require "badline/vic/graphics_shifter"
|
|
7
|
-
require "badline/vic/sequencer_output"
|
|
8
|
-
require "badline/vic/sequencer_state"
|
|
9
|
-
|
|
10
|
-
module Badline
|
|
11
|
-
class VIC
|
|
12
|
-
# = VIC-II Sequencer
|
|
13
|
-
#
|
|
14
|
-
# Turns fetched graphics data into output pixels.
|
|
15
|
-
class Sequencer
|
|
16
|
-
include Output
|
|
17
|
-
include SavedState
|
|
18
|
-
|
|
19
|
-
BORDER_Y_BOUNDS = [
|
|
20
|
-
[55, 247].freeze,
|
|
21
|
-
[51, 251].freeze
|
|
22
|
-
].freeze
|
|
23
|
-
|
|
24
|
-
MODES = GraphicsMode::MODES
|
|
25
|
-
|
|
26
|
-
attr_reader :colors, :fg, :registers, :bank, :cur_colors,
|
|
27
|
-
:color_patches
|
|
28
|
-
# The fg masks are shared frozen patterns assigned by reference, never
|
|
29
|
-
# mutated in place.
|
|
30
|
-
attr_accessor :cur_fg
|
|
31
|
-
# False leaves the line's colours unpainted and keeps only the
|
|
32
|
-
# foreground mask the sprite collisions read.
|
|
33
|
-
attr_writer :render
|
|
34
|
-
|
|
35
|
-
def initialize(width, registers, bank, model: :mos6569, region: Region::PAL)
|
|
36
|
-
@width = width
|
|
37
|
-
window_bounds(region.display_x_bounds)
|
|
38
|
-
@registers = registers
|
|
39
|
-
@bank = bank
|
|
40
|
-
@colors = Array.new(width, 0)
|
|
41
|
-
@fg = Array.new(width, false)
|
|
42
|
-
@border_mask = BorderMask.new(width)
|
|
43
|
-
# Hot-path aliases: the pixel loops write coverage straight into the
|
|
44
|
-
# mask's arrays.
|
|
45
|
-
@border = @border_mask.mask
|
|
46
|
-
@border_groups = @border_mask.groups
|
|
47
|
-
@cur_colors = Array.new(8, 0)
|
|
48
|
-
@cur_fg = GraphicsMode::NO_FG
|
|
49
|
-
@prev_colors = Array.new(8, 0)
|
|
50
|
-
@prev_fg = GraphicsMode::NO_FG
|
|
51
|
-
@vertical_border = true
|
|
52
|
-
@vertical_armed = true
|
|
53
|
-
@main_border = true
|
|
54
|
-
@color_patches = ColorPatches.new(self, grey_dots: model == :mos8565)
|
|
55
|
-
@shifter = GraphicsShifter.new(registers, model:)
|
|
56
|
-
@xscroll = 0
|
|
57
|
-
@last_shift = 0
|
|
58
|
-
@last_mode = 0
|
|
59
|
-
@settling = false
|
|
60
|
-
@ring_data = Array.new(4, 0)
|
|
61
|
-
@ring_char = Array.new(4, 0)
|
|
62
|
-
@ring_color = Array.new(4, 1)
|
|
63
|
-
@prev_fresh = false
|
|
64
|
-
@check = true
|
|
65
|
-
@render = true
|
|
66
|
-
new_line(0)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
# Reset the line buffers at the start of a rasterline.
|
|
70
|
-
def new_line(line)
|
|
71
|
-
@line = line
|
|
72
|
-
@left_vertical_border = nil
|
|
73
|
-
@first_csel = @registers.csel?
|
|
74
|
-
@colors.fill(@registers.border)
|
|
75
|
-
@fg.fill(false)
|
|
76
|
-
@border_mask.reset
|
|
77
|
-
@prev_colors.fill(@registers.background)
|
|
78
|
-
@prev_fg = GraphicsMode::NO_FG
|
|
79
|
-
@prev_fresh = false
|
|
80
|
-
@check = true
|
|
81
|
-
@color_patches.clear
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# The load point for the next group's byte: XSCROLL as a g-access
|
|
85
|
-
# column with the border open sees it, a column before the group that
|
|
86
|
-
# uses it (VICE x64sc `xscroll_pipe`).
|
|
87
|
-
def latch_xscroll(xscroll = @registers.xscroll)
|
|
88
|
-
return if xscroll == @xscroll
|
|
89
|
-
|
|
90
|
-
@xscroll = xscroll
|
|
91
|
-
@check = true
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
# A write to a register the painted colours depend on: the byte kept
|
|
95
|
-
# from the previous group is painted again before its pixels are shown.
|
|
96
|
-
def colors_changed!
|
|
97
|
-
@prev_fresh = false
|
|
98
|
-
@check = true
|
|
99
|
-
end
|
|
100
|
-
|
|
101
|
-
def apply_color_patches
|
|
102
|
-
@color_patches.apply(@colors, @fg)
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
# The vertical border compares run in every cycle of their line (VICE
|
|
106
|
-
# x64sc). The top one resets the flip-flop at once when DEN is set. The
|
|
107
|
-
# bottom one only arms it, and the armed state takes hold at the line's
|
|
108
|
-
# first cycle and at the left window edge (Bauer §3.9 rules 2-5). The
|
|
109
|
-
# VIC calls this after each $d011 write.
|
|
110
|
-
def compare_vertical_border(line)
|
|
111
|
-
top, bottom = BORDER_Y_BOUNDS[@registers.rsel? ? 1 : 0]
|
|
112
|
-
@vertical_armed = true if line == bottom
|
|
113
|
-
@vertical_armed = @vertical_border = false if line == top && @registers.display_enabled?
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
# The line's first cycle, Bauer's cycle 1, which is the last column of
|
|
117
|
-
# the line before it.
|
|
118
|
-
def start_vertical_border(line)
|
|
119
|
-
compare_vertical_border(line)
|
|
120
|
-
@vertical_border = @vertical_armed
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
# The 40-column left compare, a column before the column that draws its
|
|
124
|
-
# pixel. The 38-column one runs in the drawing column.
|
|
125
|
-
def left_compare_vertical_border
|
|
126
|
-
@left_vertical_border = start_vertical_border(@line) if @registers.csel?
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
def border_at?(pixel_x) = @border_mask.at?(pixel_x)
|
|
130
|
-
|
|
131
|
-
# True while the vertical border flip-flop is set and stays set for the
|
|
132
|
-
# rest of the line: it can only clear mid-line on a top compare line
|
|
133
|
-
# with DEN set.
|
|
134
|
-
def vertical_closed?
|
|
135
|
-
return false unless @vertical_border
|
|
136
|
-
return true unless @line == 51 || @line == 55
|
|
137
|
-
|
|
138
|
-
top, = BORDER_Y_BOUNDS[@registers.rsel? ? 1 : 0]
|
|
139
|
-
!(@line == top && @registers.display_enabled?)
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
# Snapshot the finished line so apply_border can restore the border
|
|
143
|
-
# pixels sprites were composited over, keeping mid-line border splits.
|
|
144
|
-
def snapshot_line = @border_mask.snapshot(@colors)
|
|
145
|
-
|
|
146
|
-
# Repaint the border over the composited line, hiding the sprites.
|
|
147
|
-
def apply_border = @border_mask.restore(@colors)
|
|
148
|
-
|
|
149
|
-
# The g-accesses the VIC hands over, as a ring the column's slot
|
|
150
|
-
# indexes: the byte read, the screen byte and the colour nibble. The
|
|
151
|
-
# slot before is the byte the previous group loaded.
|
|
152
|
-
attr_reader :ring_data, :ring_char, :ring_color
|
|
153
|
-
|
|
154
|
-
# The border flip-flops: vertical, the vertical one armed to set, and
|
|
155
|
-
# the main one.
|
|
156
|
-
def borders = [@vertical_border, @vertical_armed, @main_border]
|
|
157
|
-
|
|
158
|
-
def restore_borders(vertical, armed, main)
|
|
159
|
-
@vertical_border = vertical
|
|
160
|
-
@vertical_armed = armed
|
|
161
|
-
@main_border = main
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
# Paints the byte in the slot through the current mode. An idle access
|
|
165
|
-
# latches 0/0 and one that made no access passes on zero data with the
|
|
166
|
-
# kept values; under a closed border neither has foreground. A group
|
|
167
|
-
# where the mode or the load point changes, and the one after it, run
|
|
168
|
-
# the shift register pixel by pixel.
|
|
169
|
-
def emit(slot, col, display)
|
|
170
|
-
mode = @registers.mode
|
|
171
|
-
return emit_checked(slot, col, display, mode) if @check || mode != @last_mode
|
|
172
|
-
|
|
173
|
-
paint_slot(slot, mode, display)
|
|
174
|
-
output(col, @last_shift)
|
|
175
|
-
roll
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
private
|
|
179
|
-
|
|
180
|
-
# The display window's edges per CSEL state, as the region gives them.
|
|
181
|
-
# The graphics window always spans the full 40 columns, ignoring CSEL,
|
|
182
|
-
# and the border flip-flop takes [left compare, right compare] per
|
|
183
|
-
# CSEL state.
|
|
184
|
-
def window_bounds(bounds)
|
|
185
|
-
narrow, wide = bounds
|
|
186
|
-
@gfx_x_start = wide[0]
|
|
187
|
-
@gfx_x_end = wide[1] + 1
|
|
188
|
-
@window_compares = [
|
|
189
|
-
[narrow[0], narrow[1] + 1].freeze,
|
|
190
|
-
[@gfx_x_start, @gfx_x_end].freeze
|
|
191
|
-
].freeze
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
# After a mode, XSCROLL or colour change: groups paint whole bytes
|
|
195
|
-
# again once the change has settled, and run pixel by pixel until then.
|
|
196
|
-
def emit_checked(slot, col, display, mode)
|
|
197
|
-
shift = @xscroll
|
|
198
|
-
if mode == @last_mode && shift == @last_shift && !@settling
|
|
199
|
-
emit_settled(slot, col, display, mode, shift)
|
|
200
|
-
else
|
|
201
|
-
emit_pixels(slot, col, mode, shift, !display && border_hidden?)
|
|
202
|
-
@settling = mode != @last_mode || shift != @last_shift
|
|
203
|
-
@last_mode = mode
|
|
204
|
-
@last_shift = shift
|
|
205
|
-
end
|
|
206
|
-
end
|
|
207
|
-
|
|
208
|
-
def emit_settled(slot, col, display, mode, shift)
|
|
209
|
-
repaint_previous(mode, (slot - 1) & 3) unless @prev_fresh || shift.zero?
|
|
210
|
-
paint_slot(slot, mode, display)
|
|
211
|
-
output(col, shift)
|
|
212
|
-
roll
|
|
213
|
-
@prev_fresh = true
|
|
214
|
-
@check = false
|
|
215
|
-
end
|
|
216
|
-
|
|
217
|
-
def paint_slot(slot, mode, display)
|
|
218
|
-
if !display && border_hidden?
|
|
219
|
-
@cur_fg = GraphicsMode::NO_FG
|
|
220
|
-
else
|
|
221
|
-
paint(slot, mode)
|
|
222
|
-
end
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
def repaint_previous(mode, slot)
|
|
226
|
-
roll
|
|
227
|
-
paint(slot, mode)
|
|
228
|
-
roll
|
|
229
|
-
end
|
|
230
|
-
|
|
231
|
-
def paint(slot, mode)
|
|
232
|
-
if @render
|
|
233
|
-
MODES[mode].paint(@ring_data[slot], @ring_char[slot], @ring_color[slot], self)
|
|
234
|
-
else
|
|
235
|
-
@cur_fg = MODES[mode].fg(@ring_data[slot], @ring_char[slot], @ring_color[slot])
|
|
236
|
-
end
|
|
237
|
-
end
|
|
238
|
-
|
|
239
|
-
def emit_pixels(slot, col, mode, shift, hidden)
|
|
240
|
-
prime_shifter((slot - 1) & 3) unless @settling
|
|
241
|
-
@shifter.draw(hidden ? 0 : @ring_data[slot], @ring_char[slot], @ring_color[slot], shift, mode)
|
|
242
|
-
@cur_colors[0, 8] = @shifter.colors
|
|
243
|
-
@cur_fg = @shifter.fg
|
|
244
|
-
output(col, 0)
|
|
245
|
-
@prev_fresh = false
|
|
246
|
-
@check = true
|
|
247
|
-
end
|
|
248
|
-
|
|
249
|
-
# Picks up from a group that painted whole bytes.
|
|
250
|
-
def prime_shifter(slot)
|
|
251
|
-
@shifter.prime(@ring_data[slot], @ring_char[slot], @ring_color[slot], @last_shift, @last_mode)
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
# The group is border throughout when the main flip-flop is set and the
|
|
255
|
-
# vertical one keeps it from clearing.
|
|
256
|
-
def border_hidden? = @main_border && vertical_closed?
|
|
257
|
-
|
|
258
|
-
def pixel_shown?(pixel_x, left_compare, right_compare)
|
|
259
|
-
@main_border = true if pixel_x == right_compare
|
|
260
|
-
@main_border = false if pixel_x == left_compare && !left_vertical_border
|
|
261
|
-
!@main_border
|
|
262
|
-
end
|
|
263
|
-
|
|
264
|
-
def left_vertical_border
|
|
265
|
-
@left_vertical_border.nil? ? start_vertical_border(@line) : @left_vertical_border
|
|
266
|
-
end
|
|
267
|
-
|
|
268
|
-
def roll
|
|
269
|
-
@prev_colors, @cur_colors = @cur_colors, @prev_colors
|
|
270
|
-
@prev_fg, @cur_fg = @cur_fg, @prev_fg
|
|
271
|
-
nil
|
|
272
|
-
end
|
|
273
|
-
end
|
|
274
|
-
end
|
|
275
|
-
end
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
class VIC
|
|
5
|
-
class Sequencer
|
|
6
|
-
# Writes a column's 8-pixel group into the line buffers, through the
|
|
7
|
-
# main border flip-flop and XSCROLL.
|
|
8
|
-
module Output
|
|
9
|
-
private
|
|
10
|
-
|
|
11
|
-
# Write the 8-pixel group for a column into the line buffers. The main
|
|
12
|
-
# border flip-flop only changes state in the groups containing the
|
|
13
|
-
# window edge compares, so all other groups take a branch-free bulk
|
|
14
|
-
# path: fully border or fully window. A group's first pixel, where the
|
|
15
|
-
# 40-column compares fall, still sees CSEL as the column before had it.
|
|
16
|
-
def output(col, shift)
|
|
17
|
-
x_pos = (col + 16) * 8
|
|
18
|
-
csel = @registers.csel?
|
|
19
|
-
first = @window_compares[@first_csel ? 1 : 0]
|
|
20
|
-
@first_csel = csel
|
|
21
|
-
compares = @window_compares[csel ? 1 : 0]
|
|
22
|
-
win_lo, right_compare = compares
|
|
23
|
-
|
|
24
|
-
if !first.equal?(compares) || boundary_group?(x_pos, win_lo, right_compare)
|
|
25
|
-
output_boundary(x_pos, first, compares, shift)
|
|
26
|
-
elsif @main_border
|
|
27
|
-
output_border(x_pos)
|
|
28
|
-
else
|
|
29
|
-
output_window(x_pos, shift)
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# True if the group contains a window edge, where the main border
|
|
34
|
-
# flip-flop can change state.
|
|
35
|
-
def boundary_group?(x_pos, win_lo, right_compare)
|
|
36
|
-
lo_delta = win_lo - x_pos
|
|
37
|
-
hi_delta = right_compare - x_pos
|
|
38
|
-
(lo_delta >= 0 && lo_delta < 8) || (hi_delta >= 0 && hi_delta < 8)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
def output_border(x_pos)
|
|
42
|
-
@colors.fill(@registers.border, x_pos, 8) if @render
|
|
43
|
-
@border_groups[x_pos >> 3] = BorderMask::FULL
|
|
44
|
-
@fg.fill(false, x_pos, 8)
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def output_window(x_pos, shift)
|
|
48
|
-
in_gfx = x_pos >= @gfx_x_start && x_pos < @gfx_x_end
|
|
49
|
-
@border_groups[x_pos >> 3] = BorderMask::NONE
|
|
50
|
-
|
|
51
|
-
if shift.zero?
|
|
52
|
-
@colors[x_pos, 8] = @cur_colors if @render
|
|
53
|
-
if in_gfx
|
|
54
|
-
@fg[x_pos, 8] = @cur_fg
|
|
55
|
-
else
|
|
56
|
-
@fg.fill(false, x_pos, 8)
|
|
57
|
-
end
|
|
58
|
-
else
|
|
59
|
-
output_window_shifted(x_pos, in_gfx, shift)
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def output_window_shifted(x_pos, in_gfx, shift)
|
|
64
|
-
keep = 8 - shift
|
|
65
|
-
|
|
66
|
-
if @render
|
|
67
|
-
copy(@cur_colors, 0, @colors, x_pos + shift, keep)
|
|
68
|
-
copy(@prev_colors, keep, @colors, x_pos, shift)
|
|
69
|
-
end
|
|
70
|
-
output_shifted_fg(x_pos, in_gfx, shift, keep)
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def output_shifted_fg(x_pos, in_gfx, shift, keep)
|
|
74
|
-
return @fg.fill(false, x_pos, 8) unless in_gfx
|
|
75
|
-
|
|
76
|
-
copy(@cur_fg, 0, @fg, x_pos + shift, keep)
|
|
77
|
-
copy(@prev_fg, keep, @fg, x_pos, shift)
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def copy(src, from, dest, to, count)
|
|
81
|
-
i = 0
|
|
82
|
-
while i < count
|
|
83
|
-
dest[to + i] = src[from + i]
|
|
84
|
-
i += 1
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
# Slow path for the groups where the border flip-flop can change state.
|
|
89
|
-
def output_boundary(x_pos, first, compares, shift)
|
|
90
|
-
border = @registers.border
|
|
91
|
-
win_lo, right_compare = first
|
|
92
|
-
@border_groups[x_pos >> 3] = BorderMask::MIXED
|
|
93
|
-
|
|
94
|
-
i = 0
|
|
95
|
-
while i < 8
|
|
96
|
-
src = i - shift
|
|
97
|
-
if src >= 0
|
|
98
|
-
pixel = @cur_colors[src]
|
|
99
|
-
mask = @cur_fg[src]
|
|
100
|
-
else
|
|
101
|
-
pixel = @prev_colors[8 + src]
|
|
102
|
-
mask = @prev_fg[8 + src]
|
|
103
|
-
end
|
|
104
|
-
x = x_pos + i
|
|
105
|
-
shown = pixel_shown?(x, win_lo, right_compare)
|
|
106
|
-
@colors[x] = shown ? pixel : border
|
|
107
|
-
@border[x] = !shown
|
|
108
|
-
@fg[x] = x >= @gfx_x_start && x < @gfx_x_end ? mask : false
|
|
109
|
-
win_lo, right_compare = compares if i.zero?
|
|
110
|
-
i += 1
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
end
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
class VIC
|
|
5
|
-
class Sequencer
|
|
6
|
-
# The sequencer's save_state and load_state.
|
|
7
|
-
module SavedState
|
|
8
|
-
FG_SHIFTER = -1
|
|
9
|
-
PAIR_CODES = 256
|
|
10
|
-
|
|
11
|
-
# The line buffers, the border flip-flops, the g-access ring and the
|
|
12
|
-
# pixel pipeline. The foreground masks the groups point at go as
|
|
13
|
-
# FG_SHIFTER for the shift register's, or their data byte in
|
|
14
|
-
# GraphicsMode's HIRES_FG, or that plus 256 in its PAIR_FG. The left
|
|
15
|
-
# vertical border compare goes as -1 before it has run.
|
|
16
|
-
def save_state(out)
|
|
17
|
-
out.int(@line).boolean(@first_csel).int(@left_vertical_border.nil? ? -1 : bit(@left_vertical_border))
|
|
18
|
-
out.blob(@colors).booleans(@fg)
|
|
19
|
-
@border_mask.save_state(out)
|
|
20
|
-
out.ints(@cur_colors).int(fg_code(@cur_fg)).ints(@prev_colors).int(fg_code(@prev_fg))
|
|
21
|
-
out.boolean(@vertical_border).boolean(@vertical_armed).boolean(@main_border)
|
|
22
|
-
@color_patches.save_state(out)
|
|
23
|
-
@shifter.save_state(out)
|
|
24
|
-
out.int(@xscroll).int(@last_shift).int(@last_mode).boolean(@settling).boolean(@prev_fresh).boolean(@check)
|
|
25
|
-
out.ints(@ring_data).ints(@ring_char).ints(@ring_color)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def load_state(input)
|
|
29
|
-
load_line(input)
|
|
30
|
-
@border_mask.load_state(input)
|
|
31
|
-
input.ints_into(@cur_colors)
|
|
32
|
-
@cur_fg = fg_pattern(input.int)
|
|
33
|
-
input.ints_into(@prev_colors)
|
|
34
|
-
@prev_fg = fg_pattern(input.int)
|
|
35
|
-
@vertical_border = input.boolean?
|
|
36
|
-
@vertical_armed = input.boolean?
|
|
37
|
-
@main_border = input.boolean?
|
|
38
|
-
@color_patches.load_state(input)
|
|
39
|
-
@shifter.load_state(input)
|
|
40
|
-
load_pipeline(input)
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
private
|
|
44
|
-
|
|
45
|
-
def bit(flag) = flag ? 1 : 0
|
|
46
|
-
|
|
47
|
-
def load_line(input)
|
|
48
|
-
@line = input.int
|
|
49
|
-
@first_csel = input.boolean?
|
|
50
|
-
left = input.int
|
|
51
|
-
@left_vertical_border = left.negative? ? nil : left == 1
|
|
52
|
-
input.blob_into(@colors)
|
|
53
|
-
input.booleans_into(@fg)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def load_pipeline(input)
|
|
57
|
-
@xscroll = input.int
|
|
58
|
-
@last_shift = input.int
|
|
59
|
-
@last_mode = input.int
|
|
60
|
-
@settling = input.boolean?
|
|
61
|
-
@prev_fresh = input.boolean?
|
|
62
|
-
@check = input.boolean?
|
|
63
|
-
input.ints_into(@ring_data)
|
|
64
|
-
input.ints_into(@ring_char)
|
|
65
|
-
input.ints_into(@ring_color)
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def fg_code(pattern)
|
|
69
|
-
return FG_SHIFTER if pattern.equal?(@shifter.fg)
|
|
70
|
-
|
|
71
|
-
hires = GraphicsMode::HIRES_FG.index { |fg| fg.equal?(pattern) }
|
|
72
|
-
return hires if hires
|
|
73
|
-
|
|
74
|
-
pair = GraphicsMode::PAIR_FG.index { |fg| fg.equal?(pattern) }
|
|
75
|
-
raise ArgumentError, "a foreground mask the sequencer doesn't know" unless pair
|
|
76
|
-
|
|
77
|
-
PAIR_CODES + pair
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def fg_pattern(code)
|
|
81
|
-
return @shifter.fg if code == FG_SHIFTER
|
|
82
|
-
return GraphicsMode::HIRES_FG.fetch(code) if code < PAIR_CODES
|
|
83
|
-
|
|
84
|
-
GraphicsMode::PAIR_FG.fetch(code - PAIR_CODES)
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
end
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
class VIC
|
|
5
|
-
class Sprite
|
|
6
|
-
# = InternalBus
|
|
7
|
-
#
|
|
8
|
-
# What a sprite's s-accesses read while its DMA is off. The first and
|
|
9
|
-
# third fall in phi2, where the VIC's internal bus floats to $ff unless
|
|
10
|
-
# the CPU reads or writes a VIC register in that cycle, and the middle
|
|
11
|
-
# one is the idle fetch at $3fff (sbsprf24's readme).
|
|
12
|
-
class InternalBus
|
|
13
|
-
# The columns of a raster line, and where the region puts the
|
|
14
|
-
# sprites in it.
|
|
15
|
-
attr_reader :columns, :timing
|
|
16
|
-
|
|
17
|
-
def initialize(bank, timing)
|
|
18
|
-
@bank = bank
|
|
19
|
-
@timing = timing
|
|
20
|
-
@columns = timing.columns
|
|
21
|
-
@sprite_cycle = timing.sprite_cycle
|
|
22
|
-
@lines = 0
|
|
23
|
-
@ghost = 0xff
|
|
24
|
-
@value = Array.new(columns, 0xff)
|
|
25
|
-
@line = Array.new(columns, -1)
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
def save_state(out)
|
|
29
|
-
out.int(@lines).int(@ghost).ints(@value).ints(@line)
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def load_state(input)
|
|
33
|
-
@lines = input.int
|
|
34
|
-
@ghost = input.int
|
|
35
|
-
input.ints_into(@value)
|
|
36
|
-
input.ints_into(@line)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
# Sprites 3-7 fetch in Bauer cycles 1-10, so the idle byte is taken
|
|
40
|
-
# as the line starts.
|
|
41
|
-
def start_line(sprites_enabled)
|
|
42
|
-
@lines += 1
|
|
43
|
-
@ghost = @bank.peek(0x3fff) if sprites_enabled
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
# The VIC has advanced to `column`, so the access runs in Bauer cycle
|
|
47
|
-
# `column + 1`, and column 0 is the first cycle of the line about to
|
|
48
|
-
# start.
|
|
49
|
-
def access(column, value)
|
|
50
|
-
@value[column] = value
|
|
51
|
-
@line[column] = column.zero? ? @lines + 1 : @lines
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
# The row sprite `index` (3-7) fetched this line, in the phi2 halves
|
|
55
|
-
# of the two cycles from its p-access: Bauer cycles 2n-5 and 2n-4 on
|
|
56
|
-
# the 6569.
|
|
57
|
-
def row(index)
|
|
58
|
-
column = (@sprite_cycle + (2 * index) - 1) % @columns
|
|
59
|
-
(phi2(column) << 16) | (@ghost << 8) | phi2(column + 1)
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
private
|
|
63
|
-
|
|
64
|
-
def phi2(column) = @line[column] == @lines ? @value[column] : 0xff
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
68
|
-
end
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
class VIC
|
|
5
|
-
class Sprite
|
|
6
|
-
# The sprite's save_state and load_state.
|
|
7
|
-
module SavedState
|
|
8
|
-
# The shift register, MC, MCBASE, the expansion flip-flop and whether
|
|
9
|
-
# the sprite shows, for a VICE snapshot.
|
|
10
|
-
attr_reader :sr, :mc, :mcbase, :exp_ff, :display_on
|
|
11
|
-
|
|
12
|
-
# Sets MC, MCBASE, the expansion flip-flop, whether the sprite's DMA
|
|
13
|
-
# runs and whether it shows, as a VICE snapshot gives them.
|
|
14
|
-
def restore_counters(counter, base, expanded, dma, shows)
|
|
15
|
-
@mc = counter
|
|
16
|
-
@mcbase = base
|
|
17
|
-
@exp_ff = expanded
|
|
18
|
-
@dma = dma
|
|
19
|
-
@display_on = shows
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def save_state(out)
|
|
23
|
-
out.boolean(@dma).boolean(@display_on).int(@mcbase).int(@mc).boolean(@exp_ff).optional_int(@crunched_mc)
|
|
24
|
-
out.int(@bits).boolean(@row_ready).optional_int(@prev_bits).boolean(@first_byte_lost).boolean(@blind)
|
|
25
|
-
out.int(@show_from).optional_int(@stop_x)
|
|
26
|
-
out.ints(@codes).int(@leftmost).int(@span).ints(@reload_codes).int(@reload_leftmost).int(@reload_span)
|
|
27
|
-
out.int(@sr).int(@latch).boolean(@mc_flop).boolean(@xe_flop)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def load_state(input)
|
|
31
|
-
load_counters(input)
|
|
32
|
-
@show_from = input.int
|
|
33
|
-
@stop_x = input.optional_int
|
|
34
|
-
input.ints_into(@codes)
|
|
35
|
-
@leftmost = input.int
|
|
36
|
-
@span = input.int
|
|
37
|
-
input.ints_into(@reload_codes)
|
|
38
|
-
@reload_leftmost = input.int
|
|
39
|
-
@reload_span = input.int
|
|
40
|
-
@sr = input.int
|
|
41
|
-
@latch = input.int
|
|
42
|
-
@mc_flop = input.boolean?
|
|
43
|
-
@xe_flop = input.boolean?
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
private
|
|
47
|
-
|
|
48
|
-
def load_counters(input)
|
|
49
|
-
@dma = input.boolean?
|
|
50
|
-
@display_on = input.boolean?
|
|
51
|
-
@mcbase = input.int
|
|
52
|
-
@mc = input.int
|
|
53
|
-
@exp_ff = input.boolean?
|
|
54
|
-
@crunched_mc = input.optional_int
|
|
55
|
-
@bits = input.int
|
|
56
|
-
@row_ready = input.boolean?
|
|
57
|
-
@prev_bits = input.optional_int
|
|
58
|
-
@first_byte_lost = input.boolean?
|
|
59
|
-
@blind = input.boolean?
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
end
|