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,86 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
class VIC
|
|
5
|
-
# Border coverage per 8-pixel group, tracked as the sequencer outputs
|
|
6
|
-
# a line.
|
|
7
|
-
#
|
|
8
|
-
# The border is repainted over composited sprites from a snapshot of
|
|
9
|
-
# the finished line, which keeps mid-line border color splits intact.
|
|
10
|
-
class BorderMask
|
|
11
|
-
FULL = 0
|
|
12
|
-
NONE = 1
|
|
13
|
-
MIXED = 2
|
|
14
|
-
|
|
15
|
-
# The group table and per-pixel mask are exposed so the sequencer's
|
|
16
|
-
# pixel loops can write them without a method call per column.
|
|
17
|
-
attr_reader :groups, :mask
|
|
18
|
-
|
|
19
|
-
def initialize(width)
|
|
20
|
-
@width = width
|
|
21
|
-
@groups = Array.new(width / 8, FULL)
|
|
22
|
-
@mask = Array.new(width, true)
|
|
23
|
-
@snapshot = Array.new(width, 0)
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
def reset
|
|
27
|
-
@groups.fill(FULL)
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def save_state(out)
|
|
31
|
-
out.ints(@groups).booleans(@mask).blob(@snapshot)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def load_state(input)
|
|
35
|
-
input.ints_into(@groups)
|
|
36
|
-
input.booleans_into(@mask)
|
|
37
|
-
input.blob_into(@snapshot)
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def at?(pixel_x)
|
|
41
|
-
case @groups[pixel_x >> 3]
|
|
42
|
-
when FULL then true
|
|
43
|
-
when MIXED then @mask[pixel_x]
|
|
44
|
-
else false
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def snapshot(colors)
|
|
49
|
-
@snapshot[0, @width] = colors
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def restore(colors)
|
|
53
|
-
group = 0
|
|
54
|
-
while group < @groups.length
|
|
55
|
-
case @groups[group]
|
|
56
|
-
when FULL then group = restore_full(colors, group)
|
|
57
|
-
when MIXED then restore_mixed(colors, group * 8)
|
|
58
|
-
end
|
|
59
|
-
group += 1
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
private
|
|
64
|
-
|
|
65
|
-
# Copies a run of full-border groups in one splice and returns its
|
|
66
|
-
# last group.
|
|
67
|
-
def restore_full(colors, first)
|
|
68
|
-
last = first
|
|
69
|
-
last += 1 while @groups[last + 1] == FULL
|
|
70
|
-
x_pos = first * 8
|
|
71
|
-
length = (last - first + 1) * 8
|
|
72
|
-
colors[x_pos, length] = @snapshot[x_pos, length]
|
|
73
|
-
last
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def restore_mixed(colors, x_pos)
|
|
77
|
-
i = 0
|
|
78
|
-
while i < 8
|
|
79
|
-
x = x_pos + i
|
|
80
|
-
colors[x] = @snapshot[x] if @mask[x]
|
|
81
|
-
i += 1
|
|
82
|
-
end
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
class VIC
|
|
5
|
-
# = Sprite collisions
|
|
6
|
-
#
|
|
7
|
-
# The $D01E/$D01F latches and the per-pixel sprite coverage that feeds
|
|
8
|
-
# them. Collisions latch as the beam passes each covered pixel, so a
|
|
9
|
-
# read mid-line sees the pixels drawn before the reading cycle and none
|
|
10
|
-
# of the ones after it.
|
|
11
|
-
class Collisions
|
|
12
|
-
# $D019 latch bits raised by the collision registers.
|
|
13
|
-
SPRITE_COLLISION_IRQ = 0x04 # IMMC, mirrors $D01E
|
|
14
|
-
DATA_COLLISION_IRQ = 0x02 # IMBC, mirrors $D01F
|
|
15
|
-
|
|
16
|
-
# A read holds the register's reset asserted past the cycle that
|
|
17
|
-
# issued it, so the pixels drawn under it never reach the register.
|
|
18
|
-
# The read still reports only the pixels drawn before its own cycle,
|
|
19
|
-
# which is why the two numbers do not cancel out.
|
|
20
|
-
CLEAR_OVERRUN = 12
|
|
21
|
-
|
|
22
|
-
# The pixel the last fold reached, so the sprites know whether a read
|
|
23
|
-
# has anything left to latch.
|
|
24
|
-
attr_reader :folded
|
|
25
|
-
|
|
26
|
-
# One bitmask per pixel of the line, written straight by the sprite
|
|
27
|
-
# merge and read back here and by the composite.
|
|
28
|
-
attr_reader :hits
|
|
29
|
-
|
|
30
|
-
def initialize(registers, width)
|
|
31
|
-
@registers = registers
|
|
32
|
-
@width = width
|
|
33
|
-
@hits = Array.new(width, 0)
|
|
34
|
-
@folded = 0
|
|
35
|
-
@cleared_sprite = 0
|
|
36
|
-
@cleared_data = 0
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
def save_state(out)
|
|
40
|
-
out.blob(@hits).int(@folded).int(@cleared_sprite).int(@cleared_data)
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def load_state(input)
|
|
44
|
-
input.blob_into(@hits)
|
|
45
|
-
@folded = input.int
|
|
46
|
-
@cleared_sprite = input.int
|
|
47
|
-
@cleared_data = input.int
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def start_line
|
|
51
|
-
@folded = 0
|
|
52
|
-
@cleared_sprite = carry(@cleared_sprite)
|
|
53
|
-
@cleared_data = carry(@cleared_data)
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
# Latch every covered pixel between the last fold and the beam. The
|
|
57
|
-
# sprites' touched span bounds the scan; the coverage is zero outside
|
|
58
|
-
# it either way.
|
|
59
|
-
def fold(mask, upto, low, high)
|
|
60
|
-
from = [@folded, low].max
|
|
61
|
-
@folded = upto
|
|
62
|
-
scan(mask, from, [upto, high].min)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
# A read resets its register for the pixels that follow the reading
|
|
66
|
-
# cycle as well as for everything before it.
|
|
67
|
-
def clear(reg, beam_x)
|
|
68
|
-
if reg == 0x1e
|
|
69
|
-
@cleared_sprite = beam_x + CLEAR_OVERRUN
|
|
70
|
-
else
|
|
71
|
-
@cleared_data = beam_x + CLEAR_OVERRUN
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
private
|
|
76
|
-
|
|
77
|
-
# Two or more sprites on a pixel collide with each other; any sprite
|
|
78
|
-
# over a foreground pixel collides with the graphics. Pixels still
|
|
79
|
-
# under a read's reset are dropped rather than latched.
|
|
80
|
-
def scan(mask, from, upto)
|
|
81
|
-
sprite_clash = 0
|
|
82
|
-
data_clash = 0
|
|
83
|
-
pos = from
|
|
84
|
-
while pos < upto
|
|
85
|
-
bits = @hits[pos]
|
|
86
|
-
unless bits.zero?
|
|
87
|
-
sprite_clash |= bits if pos >= @cleared_sprite && bits.anybits?(bits - 1)
|
|
88
|
-
data_clash |= bits if pos >= @cleared_data && mask[pos]
|
|
89
|
-
end
|
|
90
|
-
pos += 1
|
|
91
|
-
end
|
|
92
|
-
latch(sprite_clash, data_clash)
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
def latch(sprite_clash, data_clash)
|
|
96
|
-
latch_one(0x1e, sprite_clash, SPRITE_COLLISION_IRQ)
|
|
97
|
-
latch_one(0x1f, data_clash, DATA_COLLISION_IRQ)
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
# The IRQ is raised on the edge out of an empty register, so a
|
|
101
|
-
# collision folded on top of an unread one raises nothing.
|
|
102
|
-
def latch_one(reg, clash, irq)
|
|
103
|
-
return if clash.zero?
|
|
104
|
-
return unless @registers.collide!(reg, clash)
|
|
105
|
-
|
|
106
|
-
@registers.latch_irq!(irq)
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
# A reset still asserted at the line wrap carries into the new line.
|
|
110
|
-
def carry(cleared)
|
|
111
|
-
cleared > @width ? cleared - @width : 0
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
end
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
class VIC
|
|
5
|
-
# A mid-line color register write becomes visible one pixel into the
|
|
6
|
-
# column emitted the cycle after the write. That emit paints the whole
|
|
7
|
-
# column with the new color, so the boundary pixel is patched back to
|
|
8
|
-
# the old one before the line is finished. On the 8565 the boundary
|
|
9
|
-
# pixel shows light grey instead, the grey dot, whatever the old and new
|
|
10
|
-
# colors are.
|
|
11
|
-
class ColorPatches
|
|
12
|
-
def initialize(sequencer, grey_dots: false)
|
|
13
|
-
@sequencer = sequencer
|
|
14
|
-
@grey_dots = grey_dots
|
|
15
|
-
@patches = []
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
def clear = @patches.clear
|
|
19
|
-
|
|
20
|
-
# Each patch as its four numbers: the boundary pixel, the register,
|
|
21
|
-
# the old colour and the new.
|
|
22
|
-
def save_state(out)
|
|
23
|
-
out.int(@patches.length)
|
|
24
|
-
@patches.each { |patch| out.ints(patch) }
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def load_state(input)
|
|
28
|
-
@patches.replace(Array.new(input.int) { input.ints })
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def log(reg, old, value, boundary_x)
|
|
32
|
-
@patches << [boundary_x, reg, @grey_dots ? GREY_DOT : old & 0x0f, value & 0x0f]
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def apply(colors, fg_mask)
|
|
36
|
-
@patches.each do |(x, reg, old, value)|
|
|
37
|
-
border = @sequencer.border_at?(x)
|
|
38
|
-
if reg == 0x20
|
|
39
|
-
colors[x] = old if border
|
|
40
|
-
elsif !border && !fg_mask[x] && colors[x] == value
|
|
41
|
-
colors[x] = old
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
end
|
|
47
|
-
end
|
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
class VIC
|
|
5
|
-
# = VIC-II display state
|
|
6
|
-
#
|
|
7
|
-
# The bad line condition, the video counters it drives, and the DMA it
|
|
8
|
-
# starts. A condition that arrives mid-line opens the row late, which is
|
|
9
|
-
# what makes the screen scroll sideways or lose a column of cells.
|
|
10
|
-
class DisplayState
|
|
11
|
-
FIRST_LINE = 0x30 # 48: bad lines and the DEN-at-$30 latch begin here
|
|
12
|
-
LAST_LINE = 0xf7 # 247
|
|
13
|
-
COLUMNS_PER_ROW = 40
|
|
14
|
-
|
|
15
|
-
# AEC follows BA three cycles later; the c-accesses before it read
|
|
16
|
-
# the bus the CPU still drives.
|
|
17
|
-
BA_DELAY = 3
|
|
18
|
-
|
|
19
|
-
# Columns run two ahead of Bauer's cycle numbers: column 10 is his
|
|
20
|
-
# cycle 12. BA falls on a match in columns 10-52, the c-accesses run
|
|
21
|
-
# in 13-52 and the g-accesses in 14-53. VC and VMLI reload in column
|
|
22
|
-
# 12 and the row counter steps in column 56.
|
|
23
|
-
DMA_FIRST = 10
|
|
24
|
-
DMA_LAST = 52
|
|
25
|
-
FETCH_FIRST = 13
|
|
26
|
-
GRAPHICS_FIRST = 14
|
|
27
|
-
GRAPHICS_LAST = 53
|
|
28
|
-
LOAD_COLUMN = 12
|
|
29
|
-
RC_COLUMN = 56
|
|
30
|
-
|
|
31
|
-
GRAPHICS_COLUMNS = Array.new(65) { |column| column.between?(GRAPHICS_FIRST, GRAPHICS_LAST) }.freeze
|
|
32
|
-
|
|
33
|
-
attr_reader :vc_base, :vc, :vmli, :rc, :bad_lines_enabled
|
|
34
|
-
|
|
35
|
-
# The wrap column is the last column of a rasterline, 62 on the 6569,
|
|
36
|
-
# which already compares against the line about to start, the same
|
|
37
|
-
# wrap the raster IRQ latch uses.
|
|
38
|
-
def initialize(registers, wrap_column = 62)
|
|
39
|
-
@registers = registers
|
|
40
|
-
@wrap_column = wrap_column
|
|
41
|
-
@vc_base = 0
|
|
42
|
-
@vc = 0
|
|
43
|
-
@vmli = 0
|
|
44
|
-
@rc = 0
|
|
45
|
-
@display = false
|
|
46
|
-
@bad_lines_enabled = false
|
|
47
|
-
@matched = false
|
|
48
|
-
@ba = nil
|
|
49
|
-
new_line(0)
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def display? = @display
|
|
53
|
-
|
|
54
|
-
# Sets VCBASE, VC, RC and VMLI, in that order, and the display and
|
|
55
|
-
# bad-line flags, as a VICE snapshot gives them.
|
|
56
|
-
def restore_counters(counters, display, bad_lines_enabled)
|
|
57
|
-
@vc_base, @vc, @rc, @vmli = counters
|
|
58
|
-
@display = display
|
|
59
|
-
@bad_lines_enabled = bad_lines_enabled
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def idle? = !@display
|
|
63
|
-
def bad_line? = !@ba.nil?
|
|
64
|
-
|
|
65
|
-
# The bad line condition as the last column compared it.
|
|
66
|
-
def bad_line_condition? = @matched
|
|
67
|
-
|
|
68
|
-
# True once AEC has followed BA down and the VIC owns the bus.
|
|
69
|
-
def bus_taken?(column) = @ba ? column >= @ba + BA_DELAY : false
|
|
70
|
-
|
|
71
|
-
# The CPU kept the bus through the cycle before +column+, so on a bad
|
|
72
|
-
# line AEC falls BA_DELAY cycles after it at the earliest.
|
|
73
|
-
def keep_bus(column)
|
|
74
|
-
@ba &&= column
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
def fetching?(column)
|
|
78
|
-
@matched && column >= FETCH_FIRST && column <= DMA_LAST
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def save_state(out)
|
|
82
|
-
out.int(@vc_base).int(@vc).int(@vmli).int(@rc).boolean(@display).boolean(@bad_lines_enabled)
|
|
83
|
-
out.boolean(@matched).optional_int(@ba).int(@line_bits).boolean(@den_line).boolean(@in_window)
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def load_state(input)
|
|
87
|
-
@vc_base = input.int
|
|
88
|
-
@vc = input.int
|
|
89
|
-
@vmli = input.int
|
|
90
|
-
@rc = input.int
|
|
91
|
-
@display = input.boolean?
|
|
92
|
-
@bad_lines_enabled = input.boolean?
|
|
93
|
-
@matched = input.boolean?
|
|
94
|
-
@ba = input.optional_int
|
|
95
|
-
@line_bits = input.int
|
|
96
|
-
@den_line = input.boolean?
|
|
97
|
-
@in_window = input.boolean?
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
def new_frame
|
|
101
|
-
@vc_base = 0
|
|
102
|
-
@bad_lines_enabled = false
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def new_line(line)
|
|
106
|
-
@ba = nil
|
|
107
|
-
raster_step(line)
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
# The raster counter moved on to +line+, at the line's start or, under
|
|
111
|
-
# the VIC-IIe's TEST bit, within it.
|
|
112
|
-
def raster_step(line)
|
|
113
|
-
@line_bits = line & 0b111
|
|
114
|
-
@den_line = line == FIRST_LINE
|
|
115
|
-
@in_window = line.between?(FIRST_LINE, LAST_LINE)
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
# Returns true when this compare opened display state.
|
|
119
|
-
def cycle(rasterline, column)
|
|
120
|
-
match = column == @wrap_column ? wrap_match(rasterline + 1) : line_match
|
|
121
|
-
@matched = match
|
|
122
|
-
opened = false
|
|
123
|
-
if match
|
|
124
|
-
opened = !@display
|
|
125
|
-
@display = true
|
|
126
|
-
@ba = column if @ba.nil? && column >= DMA_FIRST && column <= DMA_LAST
|
|
127
|
-
end
|
|
128
|
-
load_counters(match) if column == LOAD_COLUMN
|
|
129
|
-
check_row_counter(match) if column == RC_COLUMN
|
|
130
|
-
opened
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
# A g-access in display state consumes one buffer cell and one video
|
|
134
|
-
# matrix address. A row that opens mid-line makes fewer of them, and
|
|
135
|
-
# the shortfall carries into VCBASE.
|
|
136
|
-
def graphics_column?(column) = GRAPHICS_COLUMNS[column]
|
|
137
|
-
|
|
138
|
-
def graphics_access(column)
|
|
139
|
-
return unless graphics_column?(column)
|
|
140
|
-
|
|
141
|
-
@vc = (@vc + 1) & 0x3ff
|
|
142
|
-
@vmli += 1
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
private
|
|
146
|
-
|
|
147
|
-
def line_match
|
|
148
|
-
latch_den if @den_line
|
|
149
|
-
@bad_lines_enabled && @in_window && @line_bits == @registers.yscroll
|
|
150
|
-
end
|
|
151
|
-
|
|
152
|
-
# The wrap column compares against the line about to start. The DEN
|
|
153
|
-
# latch is level-sensitive across the counter's increment, so this one
|
|
154
|
-
# column sees both the line ending and the line starting.
|
|
155
|
-
def wrap_match(line)
|
|
156
|
-
latch_den if @den_line || line == FIRST_LINE
|
|
157
|
-
return false unless line.between?(FIRST_LINE, LAST_LINE)
|
|
158
|
-
|
|
159
|
-
@bad_lines_enabled && (line & 0b111) == @registers.yscroll
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
def latch_den
|
|
163
|
-
@bad_lines_enabled = true if @registers.display_enabled?
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
def load_counters(match)
|
|
167
|
-
@vc = @vc_base
|
|
168
|
-
@vmli = 0
|
|
169
|
-
@rc = 0 if match
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
# A condition still standing when the row counter wraps puts the logic
|
|
173
|
-
# straight back into display state, so a forced row rolls into the
|
|
174
|
-
# next one instead of leaving the line idle (Bauer 3.7.2 step 5).
|
|
175
|
-
def check_row_counter(match)
|
|
176
|
-
if @rc == 7
|
|
177
|
-
@display = false
|
|
178
|
-
@vc_base = @vc
|
|
179
|
-
end
|
|
180
|
-
@display ||= match
|
|
181
|
-
@rc = (@rc + 1) & 0b111 if @display
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
end
|
|
185
|
-
end
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
class VIC
|
|
5
|
-
module GraphicsMode
|
|
6
|
-
# Foreground masks depend only on the data byte, so each byte maps to a
|
|
7
|
-
# precomputed frozen pattern shared by reference instead of being
|
|
8
|
-
# written out pixel by pixel.
|
|
9
|
-
HIRES_FG = Array.new(256) do |data|
|
|
10
|
-
Array.new(8) { |i| data.anybits?(1 << (7 - i)) }.freeze
|
|
11
|
-
end.freeze
|
|
12
|
-
|
|
13
|
-
# The high bit of each 2-bit pair (10/11) is foreground.
|
|
14
|
-
PAIR_FG = Array.new(256) do |data|
|
|
15
|
-
Array.new(8) { |i| (data >> (6 - (i & ~1))).allbits?(0b10) }.freeze
|
|
16
|
-
end.freeze
|
|
17
|
-
|
|
18
|
-
# The same patterns as masks, all bits set for a foreground pixel.
|
|
19
|
-
HIRES_MASK = Array.new(256) do |data|
|
|
20
|
-
Array.new(8) { |i| data.anybits?(1 << (7 - i)) ? -1 : 0 }.freeze
|
|
21
|
-
end.freeze
|
|
22
|
-
|
|
23
|
-
NO_FG = HIRES_FG[0]
|
|
24
|
-
|
|
25
|
-
module Hires
|
|
26
|
-
def paint_hires(data, color, background, seq)
|
|
27
|
-
seq.cur_fg = HIRES_FG[data]
|
|
28
|
-
colors = seq.cur_colors
|
|
29
|
-
return colors.fill(background) if data.zero?
|
|
30
|
-
|
|
31
|
-
mask = HIRES_MASK[data]
|
|
32
|
-
flip = color ^ background
|
|
33
|
-
colors[0] = background ^ (flip & mask[0])
|
|
34
|
-
colors[1] = background ^ (flip & mask[1])
|
|
35
|
-
colors[2] = background ^ (flip & mask[2])
|
|
36
|
-
colors[3] = background ^ (flip & mask[3])
|
|
37
|
-
colors[4] = background ^ (flip & mask[4])
|
|
38
|
-
colors[5] = background ^ (flip & mask[5])
|
|
39
|
-
colors[6] = background ^ (flip & mask[6])
|
|
40
|
-
colors[7] = background ^ (flip & mask[7])
|
|
41
|
-
end
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
# Decodes 2-bit pixel pairs into double-wide pixels, each pair indexing
|
|
45
|
-
# the four colours in the mode's palette.
|
|
46
|
-
module Multicolor
|
|
47
|
-
def paint_pairs(data, seq)
|
|
48
|
-
seq.cur_fg = PAIR_FG[data]
|
|
49
|
-
colors = seq.cur_colors
|
|
50
|
-
palette = @palette
|
|
51
|
-
colors[0] = colors[1] = palette[data >> 6]
|
|
52
|
-
colors[2] = colors[3] = palette[(data >> 4) & 0b11]
|
|
53
|
-
colors[4] = colors[5] = palette[(data >> 2) & 0b11]
|
|
54
|
-
colors[6] = colors[7] = palette[data & 0b11]
|
|
55
|
-
end
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
# Each mode paints the byte a g-access read with the screen byte and
|
|
59
|
-
# colour nibble it latched. The VIC reads the byte itself, in the
|
|
60
|
-
# g-access column. #fg gives the foreground mask #paint would leave,
|
|
61
|
-
# without the colours.
|
|
62
|
-
class Text
|
|
63
|
-
include Hires
|
|
64
|
-
|
|
65
|
-
def paint(data, _screencode, color, seq)
|
|
66
|
-
paint_hires(data, color, seq.registers.background, seq)
|
|
67
|
-
end
|
|
68
|
-
|
|
69
|
-
def fg(data, _screencode, _color) = HIRES_FG[data]
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
class MulticolorText
|
|
73
|
-
include Hires
|
|
74
|
-
include Multicolor
|
|
75
|
-
|
|
76
|
-
def initialize
|
|
77
|
-
@palette = Array.new(4, 0)
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
def paint(data, _screencode, color, seq)
|
|
81
|
-
registers = seq.registers
|
|
82
|
-
if color.anybits?(0x08)
|
|
83
|
-
palette = @palette
|
|
84
|
-
palette[0] = registers.background(0)
|
|
85
|
-
palette[1] = registers.background(1)
|
|
86
|
-
palette[2] = registers.background(2)
|
|
87
|
-
palette[3] = color & 0x07
|
|
88
|
-
paint_pairs(data, seq)
|
|
89
|
-
else
|
|
90
|
-
paint_hires(data, color & 0x07, registers.background, seq)
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def fg(data, _screencode, color) = color.anybits?(0x08) ? PAIR_FG[data] : HIRES_FG[data]
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
class ExtendedBackgroundText
|
|
98
|
-
include Hires
|
|
99
|
-
|
|
100
|
-
def paint(data, screencode, color, seq)
|
|
101
|
-
background = seq.registers.background((screencode >> 6) & 0b11)
|
|
102
|
-
paint_hires(data, color, background, seq)
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def fg(data, _screencode, _color) = HIRES_FG[data]
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
class Bitmap
|
|
109
|
-
include Hires
|
|
110
|
-
|
|
111
|
-
def paint(data, screencode, _color, seq)
|
|
112
|
-
foreground = (screencode >> 4) & 0x0f
|
|
113
|
-
background = screencode & 0x0f
|
|
114
|
-
paint_hires(data, foreground, background, seq)
|
|
115
|
-
end
|
|
116
|
-
|
|
117
|
-
def fg(data, _screencode, _color) = HIRES_FG[data]
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
class MulticolorBitmap
|
|
121
|
-
include Multicolor
|
|
122
|
-
|
|
123
|
-
def initialize
|
|
124
|
-
@palette = Array.new(4, 0)
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
def paint(data, screencode, color, seq)
|
|
128
|
-
palette = @palette
|
|
129
|
-
palette[0] = seq.registers.background(0)
|
|
130
|
-
palette[1] = (screencode >> 4) & 0x0f
|
|
131
|
-
palette[2] = screencode & 0x0f
|
|
132
|
-
palette[3] = color & 0x0f
|
|
133
|
-
paint_pairs(data, seq)
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
def fg(data, _screencode, _color) = PAIR_FG[data]
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
class Null
|
|
140
|
-
def paint(_data, _screencode, _color, seq)
|
|
141
|
-
seq.cur_fg = NO_FG
|
|
142
|
-
seq.cur_colors.fill(0)
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
def fg(_data, _screencode, _color) = NO_FG
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
NULL_MODE = Null.new
|
|
149
|
-
|
|
150
|
-
# Indexed by ECM/BMM/MCM; the three invalid combinations decode to
|
|
151
|
-
# black.
|
|
152
|
-
MODES = [
|
|
153
|
-
Text.new, # 000 standard text
|
|
154
|
-
MulticolorText.new, # 001 multicolour text
|
|
155
|
-
Bitmap.new, # 010 standard bitmap
|
|
156
|
-
MulticolorBitmap.new, # 011 multicolour bitmap
|
|
157
|
-
ExtendedBackgroundText.new, # 100 ECM text
|
|
158
|
-
NULL_MODE, # 101 invalid
|
|
159
|
-
NULL_MODE, # 110 invalid
|
|
160
|
-
NULL_MODE # 111 invalid
|
|
161
|
-
].freeze
|
|
162
|
-
end
|
|
163
|
-
end
|
|
164
|
-
end
|