badline 0.12.1 → 0.13.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 +17 -0
- data/CLAUDE.md +59 -31
- data/README.md +1 -1
- data/doc/library.md +9 -9
- data/doc/pinned-behaviour.md +105 -105
- data/doc/snapshots.md +1 -4
- data/lib/badline/audio/bare_player.rb +3 -3
- data/lib/badline/audio/cli.rb +6 -6
- data/lib/badline/audio/jukebox.rb +2 -2
- data/lib/badline/audio/machine_player.rb +2 -2
- data/lib/badline/{media → audio}/queue.rb +1 -1
- data/lib/badline/audio/queued_tune.rb +6 -6
- data/lib/badline/audio/renderer.rb +5 -5
- data/lib/badline/audio/stereo.rb +1 -1
- data/lib/badline/c128/{bus_state.rb → bus/saved_state.rb} +1 -1
- data/lib/badline/c128/bus.rb +18 -17
- data/lib/badline/c128/color_lines.rb +2 -2
- data/lib/badline/c128/cpu.rb +1 -1
- data/lib/badline/c128/drives.rb +10 -11
- data/lib/badline/c128/fast_serial.rb +5 -5
- data/lib/badline/c128/mmu_pages.rb +1 -1
- data/lib/badline/c128/modes.rb +2 -2
- data/lib/badline/c128/saved_state.rb +21 -47
- data/lib/badline/c128/z80.rb +2 -2
- data/lib/badline/c128.rb +14 -9
- data/lib/badline/{computer → c64}/attachments.rb +4 -6
- data/lib/badline/c64/banked_ram/banking.rb +32 -0
- data/lib/badline/c64/banked_ram/plus256k.rb +56 -0
- data/lib/badline/c64/banked_ram/plus60k.rb +45 -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/extra_sids.rb +32 -0
- data/lib/badline/c64/bus/fittings.rb +40 -0
- data/lib/badline/c64/bus/pla.rb +149 -0
- data/lib/badline/c64/bus/roms.rb +41 -0
- data/lib/badline/c64/bus/saved_state.rb +68 -0
- data/lib/badline/c64/bus/sid_slots.rb +44 -0
- data/lib/badline/c64/bus.rb +218 -0
- data/lib/badline/c64/cartridge/action_replay.rb +128 -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 +147 -0
- data/lib/badline/c64/cartridge/epyx_fastload.rb +81 -0
- data/lib/badline/c64/cartridge/final_cartridge3.rb +91 -0
- data/lib/badline/c64/cartridge/flash/saved_state.rb +40 -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 +76 -0
- data/lib/badline/c64/cartridge/game_system.rb +42 -0
- data/lib/badline/c64/cartridge/geo_ram.rb +81 -0
- data/lib/badline/c64/cartridge/kcs_power.rb +77 -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 +70 -0
- data/lib/badline/c64/cartridge/retro_replay/saved_state.rb +47 -0
- data/lib/badline/c64/cartridge/retro_replay.rb +286 -0
- data/lib/badline/c64/cartridge/rex_utility.rb +31 -0
- data/lib/badline/c64/cartridge/rgcd.rb +60 -0
- data/lib/badline/c64/cartridge/saved_state.rb +63 -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 +50 -0
- data/lib/badline/c64/cartridge/westermann.rb +32 -0
- data/lib/badline/c64/cartridge/zaxxon.rb +68 -0
- data/lib/badline/c64/cartridge.rb +258 -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 +18 -18
- data/lib/badline/c64/reu/dma/saved_state.rb +52 -0
- data/lib/badline/c64/reu/dma.rb +275 -0
- data/lib/badline/c64/reu/ram.rb +109 -0
- data/lib/badline/c64/reu/saved_state.rb +55 -0
- data/lib/badline/c64/reu/trigger.rb +34 -0
- data/lib/badline/c64/reu.rb +291 -0
- data/lib/badline/{computer → c64}/saved_state.rb +13 -18
- data/lib/badline/{computer → c64}/true_drives.rb +11 -11
- data/lib/badline/{computer.rb → c64.rb} +18 -13
- data/lib/badline/chips/cia/fast_forward.rb +62 -0
- data/lib/badline/chips/cia/interrupt_register.rb +145 -0
- data/lib/badline/chips/cia/saved_state.rb +49 -0
- data/lib/badline/chips/cia/serial/saved_state.rb +45 -0
- data/lib/badline/chips/cia/serial.rb +250 -0
- data/lib/badline/chips/cia/time_of_day.rb +232 -0
- data/lib/badline/chips/cia/timer.rb +208 -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 +167 -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/microcode.rb +179 -0
- data/lib/badline/chips/cpu/operations.rb +90 -0
- data/lib/badline/chips/cpu/port.rb +116 -0
- data/lib/badline/chips/cpu/saved_state.rb +117 -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 +12 -0
- data/lib/badline/chips/sid/catch_up.rb +122 -0
- data/lib/badline/chips/sid/decimator.rb +66 -0
- data/lib/badline/chips/sid/envelope/saved_state.rb +70 -0
- data/lib/badline/chips/sid/envelope.rb +241 -0
- data/lib/badline/chips/sid/filter/saved_state.rb +42 -0
- data/lib/badline/chips/sid/filter.rb +241 -0
- data/lib/badline/chips/sid/saved_state.rb +52 -0
- data/lib/badline/chips/sid/voice.rb +79 -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/saved_state.rb +68 -0
- data/lib/badline/chips/sid/waveform.rb +307 -0
- data/lib/badline/chips/sid.rb +265 -0
- data/lib/badline/{c128 → chips}/vdc/memory.rb +1 -1
- data/lib/badline/{c128 → chips}/vdc/painter.rb +1 -1
- data/lib/badline/{c128 → chips}/vdc/raster.rb +1 -1
- data/lib/badline/chips/vdc/saved_state.rb +36 -0
- data/lib/badline/{c128 → chips}/vdc/window.rb +1 -1
- data/lib/badline/{c128 → chips}/vdc.rb +7 -31
- data/lib/badline/chips/via/control_lines.rb +124 -0
- data/lib/badline/chips/via/fast_forward.rb +55 -0
- data/lib/badline/chips/via/interrupt_register.rb +69 -0
- data/lib/badline/chips/via/saved_state.rb +44 -0
- data/lib/badline/chips/via/shift_register.rb +182 -0
- data/lib/badline/chips/via/timer1.rb +133 -0
- data/lib/badline/chips/via/timer2.rb +135 -0
- data/lib/badline/chips/via.rb +268 -0
- data/lib/badline/chips/vic/bank.rb +135 -0
- data/lib/badline/chips/vic/border_mask.rb +88 -0
- data/lib/badline/chips/vic/collisions.rb +117 -0
- data/lib/badline/chips/vic/color_patches.rb +49 -0
- data/lib/badline/chips/vic/display_state.rb +187 -0
- data/lib/badline/chips/vic/graphics_mode.rb +166 -0
- data/lib/badline/chips/vic/graphics_shifter/saved_state.rb +40 -0
- data/lib/badline/chips/vic/graphics_shifter.rb +187 -0
- data/lib/badline/chips/vic/register_log.rb +83 -0
- data/lib/badline/chips/vic/registers.rb +197 -0
- data/lib/badline/chips/vic/saved_state.rb +82 -0
- data/lib/badline/chips/vic/sequencer/saved_state.rb +91 -0
- data/lib/badline/chips/vic/sequencer.rb +277 -0
- data/lib/badline/chips/vic/sequencer_output.rb +118 -0
- data/lib/badline/chips/vic/sprite/internal_bus.rb +70 -0
- data/lib/badline/chips/vic/sprite/saved_state.rb +66 -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 +339 -0
- data/lib/badline/chips/vic/sprites/saved_state.rb +59 -0
- data/lib/badline/chips/vic/sprites.rb +284 -0
- data/lib/badline/chips/vic.rb +783 -0
- data/lib/badline/chips/vic_i/painter/saved_state.rb +40 -0
- data/lib/badline/{vic20/vic → chips/vic_i}/painter.rb +6 -30
- data/lib/badline/{vic20/vic → chips/vic_i}/saved_state.rb +2 -2
- data/lib/badline/chips/vic_i/sound/output.rb +85 -0
- data/lib/badline/chips/vic_i/sound.rb +235 -0
- data/lib/badline/{vic20/vic → chips/vic_i}/text_window.rb +2 -2
- data/lib/badline/{vic20/vic.rb → chips/vic_i.rb} +5 -5
- 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/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/saved_state.rb +71 -0
- data/lib/badline/chips/z80/shifts.rb +66 -0
- data/lib/badline/chips/z80.rb +13 -0
- data/lib/badline/core.rb +26 -28
- data/lib/badline/drives/datasette/saved_state.rb +37 -0
- data/lib/badline/drives/datasette.rb +140 -0
- data/lib/badline/drives/engine/core.rb +149 -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 +75 -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 +88 -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/saved_state.rb +88 -0
- data/lib/badline/drives/model1541/disk.rb +317 -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/mechanism/saved_state.rb +72 -0
- data/lib/badline/drives/model1541/mechanism.rb +315 -0
- data/lib/badline/drives/model1541/rotation.rb +123 -0
- data/lib/badline/drives/model1541/saved_state.rb +44 -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 +81 -0
- data/lib/badline/drives/model1571/bus.rb +113 -0
- data/lib/badline/drives/model1571/cpu.rb +13 -0
- data/lib/badline/drives/model1571/saved_state.rb +47 -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 +122 -0
- data/lib/badline/drives/model1571.rb +142 -0
- data/lib/badline/drives/model1581/bus.rb +139 -0
- data/lib/badline/drives/model1581/cpu.rb +13 -0
- data/lib/badline/drives/model1581/disk/saved_state.rb +89 -0
- data/lib/badline/drives/model1581/disk.rb +137 -0
- data/lib/badline/drives/model1581/mechanism.rb +119 -0
- data/lib/badline/drives/model1581/saved_state.rb +42 -0
- data/lib/badline/drives/model1581/serial_port.rb +54 -0
- data/lib/badline/drives/model1581/slot.rb +79 -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/saved_state.rb +68 -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 +218 -0
- data/lib/badline/drives/model1581.rb +206 -0
- data/lib/badline/drives/serial_bus.rb +161 -0
- data/lib/badline/frontend/boot.rb +3 -3
- data/lib/badline/frontend/machine_window.rb +3 -1
- 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/timeline.rb +3 -3
- 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.rb +3 -0
- data/lib/badline/kernal_trap/{drive → dos}/block_commands.rb +1 -1
- data/lib/badline/kernal_trap/dos/channel.rb +183 -0
- data/lib/badline/kernal_trap/{drive → dos}/channels.rb +1 -1
- data/lib/badline/kernal_trap/{drive → dos}/memory.rb +1 -1
- data/lib/badline/kernal_trap/{drive → dos}/parameters.rb +1 -1
- data/lib/badline/kernal_trap/{drive → dos}/status.rb +1 -1
- data/lib/badline/kernal_trap/{drive → dos}/write_file.rb +1 -1
- data/lib/badline/kernal_trap/{drive → dos}/writes.rb +1 -1
- data/lib/badline/kernal_trap/{drive.rb → dos.rb} +11 -10
- data/lib/badline/kernal_trap/load.rb +5 -5
- data/lib/badline/kernal_trap/save.rb +4 -4
- data/lib/badline/kernal_trap/serial.rb +7 -7
- data/lib/badline/kernal_trap.rb +1 -2
- data/lib/badline/machine/clocking.rb +1 -1
- data/lib/badline/machine.rb +5 -5
- 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/model.rb +1 -1
- data/lib/badline/roms/README +6 -6
- 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 +43 -0
- data/lib/badline/snapshot/c64_setup.rb +79 -0
- data/lib/badline/snapshot/image.rb +5 -25
- data/lib/badline/snapshot/machine_state.rb +1 -1
- data/lib/badline/snapshot/setup.rb +22 -66
- data/lib/badline/snapshot/state.rb +8 -18
- data/lib/badline/snapshot/storage_setup.rb +68 -0
- data/lib/badline/snapshot/vic20_setup.rb +37 -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 +1 -1
- data/lib/badline/snapshot/vice/reu_fields.rb +40 -0
- data/lib/badline/snapshot/vice.rb +7 -5
- data/lib/badline/snapshot.rb +3 -4
- 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 +2 -2
- data/lib/badline/storage/host_directory.rb +0 -5
- data/lib/badline/storage/t64.rb +2 -8
- 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 +5 -5
- data/lib/badline/vic20/bus/saved_state.rb +35 -0
- data/lib/badline/vic20/bus.rb +3 -25
- data/lib/badline/vic20/cpu.rb +1 -1
- data/lib/badline/vic20/port_wiring.rb +4 -4
- data/lib/badline/vic20/saved_state.rb +16 -30
- data/lib/badline/vic20/user_via_ports.rb +2 -2
- data/lib/badline/vic20.rb +19 -14
- metadata +245 -221
- 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/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/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/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/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/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/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/sound/output.rb +0 -83
- data/lib/badline/vic20/sound.rb +0 -233
- data/lib/badline/z80/arithmetic.rb +0 -117
- data/lib/badline/z80/bit_page.rb +0 -55
- data/lib/badline/z80/block_io.rb +0 -58
- data/lib/badline/z80/block_transfers.rb +0 -59
- data/lib/badline/z80/bus_cycles.rb +0 -111
- data/lib/badline/z80/core.rb +0 -113
- data/lib/badline/z80/exchanges.rb +0 -50
- data/lib/badline/z80/extended_page.rb +0 -89
- data/lib/badline/z80/flags.rb +0 -37
- data/lib/badline/z80/interrupt_acceptance.rb +0 -46
- data/lib/badline/z80/jumps.rb +0 -82
- data/lib/badline/z80/loads.rb +0 -98
- data/lib/badline/z80/main_page.rb +0 -134
- data/lib/badline/z80/registers.rb +0 -120
- data/lib/badline/z80/saved_state.rb +0 -69
- data/lib/badline/z80/shifts.rb +0 -64
- data/lib/badline/z80.rb +0 -11
- /data/lib/badline/snapshot/{fields.rb → vice/fields.rb} +0 -0
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Chips
|
|
5
|
+
class VIC
|
|
6
|
+
class Sequencer
|
|
7
|
+
# Writes a column's 8-pixel group into the line buffers, through the
|
|
8
|
+
# main border flip-flop and XSCROLL.
|
|
9
|
+
module Output
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
# Write the 8-pixel group for a column into the line buffers. The main
|
|
13
|
+
# border flip-flop only changes state in the groups containing the
|
|
14
|
+
# window edge compares, so all other groups take a branch-free bulk
|
|
15
|
+
# path: fully border or fully window. A group's first pixel, where the
|
|
16
|
+
# 40-column compares fall, still sees CSEL as the column before had it.
|
|
17
|
+
def output(col, shift)
|
|
18
|
+
x_pos = (col + 16) * 8
|
|
19
|
+
csel = @registers.csel?
|
|
20
|
+
first = @window_compares[@first_csel ? 1 : 0]
|
|
21
|
+
@first_csel = csel
|
|
22
|
+
compares = @window_compares[csel ? 1 : 0]
|
|
23
|
+
win_lo, right_compare = compares
|
|
24
|
+
|
|
25
|
+
if !first.equal?(compares) || boundary_group?(x_pos, win_lo, right_compare)
|
|
26
|
+
output_boundary(x_pos, first, compares, shift)
|
|
27
|
+
elsif @main_border
|
|
28
|
+
output_border(x_pos)
|
|
29
|
+
else
|
|
30
|
+
output_window(x_pos, shift)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# True if the group contains a window edge, where the main border
|
|
35
|
+
# flip-flop can change state.
|
|
36
|
+
def boundary_group?(x_pos, win_lo, right_compare)
|
|
37
|
+
lo_delta = win_lo - x_pos
|
|
38
|
+
hi_delta = right_compare - x_pos
|
|
39
|
+
(lo_delta >= 0 && lo_delta < 8) || (hi_delta >= 0 && hi_delta < 8)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def output_border(x_pos)
|
|
43
|
+
@colors.fill(@registers.border, x_pos, 8) if @render
|
|
44
|
+
@border_groups[x_pos >> 3] = BorderMask::FULL
|
|
45
|
+
@fg.fill(false, x_pos, 8)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def output_window(x_pos, shift)
|
|
49
|
+
in_gfx = x_pos >= @gfx_x_start && x_pos < @gfx_x_end
|
|
50
|
+
@border_groups[x_pos >> 3] = BorderMask::NONE
|
|
51
|
+
|
|
52
|
+
if shift.zero?
|
|
53
|
+
@colors[x_pos, 8] = @cur_colors if @render
|
|
54
|
+
if in_gfx
|
|
55
|
+
@fg[x_pos, 8] = @cur_fg
|
|
56
|
+
else
|
|
57
|
+
@fg.fill(false, x_pos, 8)
|
|
58
|
+
end
|
|
59
|
+
else
|
|
60
|
+
output_window_shifted(x_pos, in_gfx, shift)
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def output_window_shifted(x_pos, in_gfx, shift)
|
|
65
|
+
keep = 8 - shift
|
|
66
|
+
|
|
67
|
+
if @render
|
|
68
|
+
copy(@cur_colors, 0, @colors, x_pos + shift, keep)
|
|
69
|
+
copy(@prev_colors, keep, @colors, x_pos, shift)
|
|
70
|
+
end
|
|
71
|
+
output_shifted_fg(x_pos, in_gfx, shift, keep)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def output_shifted_fg(x_pos, in_gfx, shift, keep)
|
|
75
|
+
return @fg.fill(false, x_pos, 8) unless in_gfx
|
|
76
|
+
|
|
77
|
+
copy(@cur_fg, 0, @fg, x_pos + shift, keep)
|
|
78
|
+
copy(@prev_fg, keep, @fg, x_pos, shift)
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def copy(src, from, dest, to, count)
|
|
82
|
+
i = 0
|
|
83
|
+
while i < count
|
|
84
|
+
dest[to + i] = src[from + i]
|
|
85
|
+
i += 1
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Slow path for the groups where the border flip-flop can change state.
|
|
90
|
+
def output_boundary(x_pos, first, compares, shift)
|
|
91
|
+
border = @registers.border
|
|
92
|
+
win_lo, right_compare = first
|
|
93
|
+
@border_groups[x_pos >> 3] = BorderMask::MIXED
|
|
94
|
+
|
|
95
|
+
i = 0
|
|
96
|
+
while i < 8
|
|
97
|
+
src = i - shift
|
|
98
|
+
if src >= 0
|
|
99
|
+
pixel = @cur_colors[src]
|
|
100
|
+
mask = @cur_fg[src]
|
|
101
|
+
else
|
|
102
|
+
pixel = @prev_colors[8 + src]
|
|
103
|
+
mask = @prev_fg[8 + src]
|
|
104
|
+
end
|
|
105
|
+
x = x_pos + i
|
|
106
|
+
shown = pixel_shown?(x, win_lo, right_compare)
|
|
107
|
+
@colors[x] = shown ? pixel : border
|
|
108
|
+
@border[x] = !shown
|
|
109
|
+
@fg[x] = x >= @gfx_x_start && x < @gfx_x_end ? mask : false
|
|
110
|
+
win_lo, right_compare = compares if i.zero?
|
|
111
|
+
i += 1
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Chips
|
|
5
|
+
class VIC
|
|
6
|
+
class Sprite
|
|
7
|
+
# = InternalBus
|
|
8
|
+
#
|
|
9
|
+
# What a sprite's s-accesses read while its DMA is off. The first and
|
|
10
|
+
# third fall in phi2, where the VIC's internal bus floats to $ff unless
|
|
11
|
+
# the CPU reads or writes a VIC register in that cycle, and the middle
|
|
12
|
+
# one is the idle fetch at $3fff (sbsprf24's readme).
|
|
13
|
+
class InternalBus
|
|
14
|
+
# The columns of a raster line, and where the region puts the
|
|
15
|
+
# sprites in it.
|
|
16
|
+
attr_reader :columns, :timing
|
|
17
|
+
|
|
18
|
+
def initialize(bank, timing)
|
|
19
|
+
@bank = bank
|
|
20
|
+
@timing = timing
|
|
21
|
+
@columns = timing.columns
|
|
22
|
+
@sprite_cycle = timing.sprite_cycle
|
|
23
|
+
@lines = 0
|
|
24
|
+
@ghost = 0xff
|
|
25
|
+
@value = Array.new(columns, 0xff)
|
|
26
|
+
@line = Array.new(columns, -1)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def save_state(out)
|
|
30
|
+
out.int(@lines).int(@ghost).ints(@value).ints(@line)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def load_state(input)
|
|
34
|
+
@lines = input.int
|
|
35
|
+
@ghost = input.int
|
|
36
|
+
input.ints_into(@value)
|
|
37
|
+
input.ints_into(@line)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Sprites 3-7 fetch in Bauer cycles 1-10, so the idle byte is taken
|
|
41
|
+
# as the line starts.
|
|
42
|
+
def start_line(sprites_enabled)
|
|
43
|
+
@lines += 1
|
|
44
|
+
@ghost = @bank.peek(0x3fff) if sprites_enabled
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# The VIC has advanced to `column`, so the access runs in Bauer cycle
|
|
48
|
+
# `column + 1`, and column 0 is the first cycle of the line about to
|
|
49
|
+
# start.
|
|
50
|
+
def access(column, value)
|
|
51
|
+
@value[column] = value
|
|
52
|
+
@line[column] = column.zero? ? @lines + 1 : @lines
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# The row sprite `index` (3-7) fetched this line, in the phi2 halves
|
|
56
|
+
# of the two cycles from its p-access: Bauer cycles 2n-5 and 2n-4 on
|
|
57
|
+
# the 6569.
|
|
58
|
+
def row(index)
|
|
59
|
+
column = (@sprite_cycle + (2 * index) - 1) % @columns
|
|
60
|
+
(phi2(column) << 16) | (@ghost << 8) | phi2(column + 1)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
private
|
|
64
|
+
|
|
65
|
+
def phi2(column) = @line[column] == @lines ? @value[column] : 0xff
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Chips
|
|
5
|
+
class VIC
|
|
6
|
+
class Sprite
|
|
7
|
+
# The sprite's save_state and load_state.
|
|
8
|
+
module SavedState
|
|
9
|
+
# The shift register, MC, MCBASE, the expansion flip-flop and whether
|
|
10
|
+
# the sprite shows, for a VICE snapshot.
|
|
11
|
+
attr_reader :sr, :mc, :mcbase, :exp_ff, :display_on
|
|
12
|
+
|
|
13
|
+
# Sets MC, MCBASE, the expansion flip-flop, whether the sprite's DMA
|
|
14
|
+
# runs and whether it shows, as a VICE snapshot gives them.
|
|
15
|
+
def restore_counters(counter, base, expanded, dma, shows)
|
|
16
|
+
@mc = counter
|
|
17
|
+
@mcbase = base
|
|
18
|
+
@exp_ff = expanded
|
|
19
|
+
@dma = dma
|
|
20
|
+
@display_on = shows
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def save_state(out)
|
|
24
|
+
out.boolean(@dma).boolean(@display_on).int(@mcbase).int(@mc).boolean(@exp_ff).optional_int(@crunched_mc)
|
|
25
|
+
out.int(@bits).boolean(@row_ready).optional_int(@prev_bits).boolean(@first_byte_lost).boolean(@blind)
|
|
26
|
+
out.int(@show_from).optional_int(@stop_x)
|
|
27
|
+
out.ints(@codes).int(@leftmost).int(@span).ints(@reload_codes).int(@reload_leftmost).int(@reload_span)
|
|
28
|
+
out.int(@sr).int(@latch).boolean(@mc_flop).boolean(@xe_flop)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def load_state(input)
|
|
32
|
+
load_counters(input)
|
|
33
|
+
@show_from = input.int
|
|
34
|
+
@stop_x = input.optional_int
|
|
35
|
+
input.ints_into(@codes)
|
|
36
|
+
@leftmost = input.int
|
|
37
|
+
@span = input.int
|
|
38
|
+
input.ints_into(@reload_codes)
|
|
39
|
+
@reload_leftmost = input.int
|
|
40
|
+
@reload_span = input.int
|
|
41
|
+
@sr = input.int
|
|
42
|
+
@latch = input.int
|
|
43
|
+
@mc_flop = input.boolean?
|
|
44
|
+
@xe_flop = input.boolean?
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def load_counters(input)
|
|
50
|
+
@dma = input.boolean?
|
|
51
|
+
@display_on = input.boolean?
|
|
52
|
+
@mcbase = input.int
|
|
53
|
+
@mc = input.int
|
|
54
|
+
@exp_ff = input.boolean?
|
|
55
|
+
@crunched_mc = input.optional_int
|
|
56
|
+
@bits = input.int
|
|
57
|
+
@row_ready = input.boolean?
|
|
58
|
+
@prev_bits = input.optional_int
|
|
59
|
+
@first_byte_lost = input.boolean?
|
|
60
|
+
@blind = input.boolean?
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Chips
|
|
5
|
+
class VIC
|
|
6
|
+
class Sprite
|
|
7
|
+
# The X comparator and the 24-bit shift register behind it: where a
|
|
8
|
+
# line fires the sprite, and the pixels each firing shifts out.
|
|
9
|
+
module Shifter
|
|
10
|
+
private
|
|
11
|
+
|
|
12
|
+
# The first pixel of every comparator match along the line. Writes to
|
|
13
|
+
# $d000/$d010 move the compare value mid-line, so a sprite can miss
|
|
14
|
+
# its match entirely and pick up a later one, a second one, or none.
|
|
15
|
+
def comparator_hits(log)
|
|
16
|
+
return compare_x(@registers) unless log
|
|
17
|
+
|
|
18
|
+
hits = []
|
|
19
|
+
log.rewind
|
|
20
|
+
log.advance(0)
|
|
21
|
+
from = 0
|
|
22
|
+
while from < @width
|
|
23
|
+
upto = [log.next_x, @width].min
|
|
24
|
+
compare_x(log).each do |start|
|
|
25
|
+
match = (start - 1) % @width
|
|
26
|
+
hits << start if match >= from && match < upto
|
|
27
|
+
end
|
|
28
|
+
break if upto >= @width
|
|
29
|
+
|
|
30
|
+
from = upto
|
|
31
|
+
log.advance(from)
|
|
32
|
+
end
|
|
33
|
+
hits
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# The pixels the sprite starts at, one past each comparator match.
|
|
37
|
+
# The 6569's X counter only runs to 503, so the eight coordinates
|
|
38
|
+
# above it never match and the sprite stays dark — the gap the
|
|
39
|
+
# spritegap tests find at $1f8.
|
|
40
|
+
def compare_x(view)
|
|
41
|
+
msb = view[0x10].anybits?(@bit) ? 0x100 : 0
|
|
42
|
+
@timing.x_pixels[msb | view[index * 2]]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Pixels from the X match to the next reload.
|
|
46
|
+
def reload_cut(start) = (start < @reload_x ? @reload_x : @reload_x + @width) - start
|
|
47
|
+
|
|
48
|
+
# A run that reaches the next reload is cut there, holding its last
|
|
49
|
+
# pixel through K+6. Returns the span that is left.
|
|
50
|
+
def cut_at_reload(cut, span, codes)
|
|
51
|
+
return span if cut > span || cut >= MAX_SPAN
|
|
52
|
+
|
|
53
|
+
RELOAD_HOLD.times { |i| codes[cut + i] = codes[cut - 1] }
|
|
54
|
+
cut + RELOAD_HOLD
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Shift one firing out into `codes`, up to the sprite's end, `cut`
|
|
58
|
+
# pixels from the reload.
|
|
59
|
+
def run(log, start, codes, bits, cut)
|
|
60
|
+
@sr = bits
|
|
61
|
+
log&.rewind
|
|
62
|
+
pos = start
|
|
63
|
+
count = 0
|
|
64
|
+
boundary = log ? 0 : Float::INFINITY
|
|
65
|
+
mc = multicolor?
|
|
66
|
+
expanded = x_expanded?
|
|
67
|
+
while count < MAX_SPAN
|
|
68
|
+
if pos >= boundary
|
|
69
|
+
log.advance(pos)
|
|
70
|
+
expanded = log[0x1d].anybits?(@bit)
|
|
71
|
+
mc = logged_multicolor(log, mc, expanded, count)
|
|
72
|
+
boundary = log.next_x
|
|
73
|
+
end
|
|
74
|
+
count.zero? ? prime(mc) : step(mc, expanded, count == cut - 1)
|
|
75
|
+
break if @latch.zero? && @sr.zero?
|
|
76
|
+
|
|
77
|
+
codes[count] = @latch
|
|
78
|
+
count += 1
|
|
79
|
+
pos += 1
|
|
80
|
+
end
|
|
81
|
+
count
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# The X match loads the shift register and arms both flip-flops, so
|
|
85
|
+
# the sprite's first pixel comes straight off the fetched row.
|
|
86
|
+
def prime(multicolor)
|
|
87
|
+
@mc_flop = @new_chip && !multicolor
|
|
88
|
+
@xe_flop = false
|
|
89
|
+
@latch = (@sr >> 22) & (multicolor ? 3 : 2)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# The multicolor bit as the log has it at the pixel. A change after
|
|
93
|
+
# the first pixel reaches the 8565's flip-flop.
|
|
94
|
+
def logged_multicolor(log, was, expanded, count)
|
|
95
|
+
multicolor = log[0x1c].anybits?(@bit)
|
|
96
|
+
switch_multicolor(multicolor, expanded) if @new_chip && multicolor != was && count.positive?
|
|
97
|
+
multicolor
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# On the 8565 a multicolor change works on the flip-flop instead of
|
|
101
|
+
# the next pixels. It stays as it is unless the change lands between
|
|
102
|
+
# the two halves of an expanded pixel, where it flips, or is set by a
|
|
103
|
+
# switch to hi-res.
|
|
104
|
+
def switch_multicolor(multicolor, expanded)
|
|
105
|
+
return unless expanded && !@xe_flop
|
|
106
|
+
|
|
107
|
+
@mc_flop = multicolor ? !@mc_flop : true
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# One pixel of the sequencer. An unexpanded sprite shifts every pixel;
|
|
111
|
+
# an expanded one shifts every other, and the multicolor latch reloads
|
|
112
|
+
# every other shift, so its pairs stretch with the expansion. Both
|
|
113
|
+
# flip-flops sit idle while their register bit is clear, which is why
|
|
114
|
+
# the first pixel after a mid-sprite change repeats the last one.
|
|
115
|
+
def step(multicolor, expanded, last)
|
|
116
|
+
shift = true
|
|
117
|
+
if expanded
|
|
118
|
+
shift = @xe_flop
|
|
119
|
+
@xe_flop = !@xe_flop
|
|
120
|
+
else
|
|
121
|
+
@xe_flop = false
|
|
122
|
+
end
|
|
123
|
+
@mc_flop = false unless multicolor || @new_chip
|
|
124
|
+
return unless shift
|
|
125
|
+
|
|
126
|
+
@sr = (@sr << 1) & 0xffffff
|
|
127
|
+
load_latch(multicolor, last)
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# A multicolor pair loaded on the last pixel before the reload keeps
|
|
131
|
+
# only its high bit, as a hi-res pixel does (spritefetchbug).
|
|
132
|
+
# On the 8565 a hi-res pixel with the multicolor flip-flop clear
|
|
133
|
+
# sets it and loads nothing, so the latch repeats its last pixel.
|
|
134
|
+
def load_latch(multicolor, last)
|
|
135
|
+
if multicolor
|
|
136
|
+
@latch = (@sr >> 22) & (last ? 2 : 3) if @mc_flop
|
|
137
|
+
@mc_flop = !@mc_flop
|
|
138
|
+
elsif @new_chip && !@mc_flop
|
|
139
|
+
@mc_flop = true
|
|
140
|
+
else
|
|
141
|
+
@latch = (@sr >> 22) & 2
|
|
142
|
+
end
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Chips
|
|
5
|
+
class VIC
|
|
6
|
+
class Sprite
|
|
7
|
+
# = Timing
|
|
8
|
+
#
|
|
9
|
+
# Where a region puts the sprites in the line: the cycles of their
|
|
10
|
+
# fetches and of the display compare, the pixels those land on, and
|
|
11
|
+
# the raster pixels the X counter reads each coordinate at. Where the
|
|
12
|
+
# fetches or the compare run a cycle later than on the 6569, what
|
|
13
|
+
# hangs off them moves 8 pixels with them.
|
|
14
|
+
class Timing
|
|
15
|
+
# The X counter's value where it steps back on a raster of more than
|
|
16
|
+
# 512 pixels, to run over the eight values below it again.
|
|
17
|
+
HOLD_AT = 0x188
|
|
18
|
+
|
|
19
|
+
attr_reader :columns, :sprite_cycle, :display_off_x, :x_pixels
|
|
20
|
+
|
|
21
|
+
def initialize(region)
|
|
22
|
+
@columns = region.cycles_per_line
|
|
23
|
+
@sprite_cycle = region.sprite_cycle
|
|
24
|
+
@shift = region.sprite_cycle - Region::PAL.sprite_cycle
|
|
25
|
+
@display_off_x = DISPLAY_OFF_X + (8 * (region.sprite_display_cycle - Region::PAL.sprite_display_cycle))
|
|
26
|
+
@x_pixels = Timing.x_pixels(@columns * 8, region.x_hold)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# The column BA falls in for a sprite's own fetch: 55 for sprite 0 on
|
|
30
|
+
# the 6569, and two later for each sprite after it.
|
|
31
|
+
def ba_column(index) = 55 + @shift + (2 * index)
|
|
32
|
+
|
|
33
|
+
# The raster pixel of a sprite's reload, counted from the start of
|
|
34
|
+
# the line it is fetched on, so past the end of it for sprites 3-7
|
|
35
|
+
# on the 6569.
|
|
36
|
+
def reload_x(index) = RELOAD_X + (8 * @shift) + (RELOAD_STEP * index)
|
|
37
|
+
|
|
38
|
+
# The X counter at a raster pixel: X_OFFSET behind it, wrapping at
|
|
39
|
+
# the end of the line, less the pixels it held for from HOLD_AT on,
|
|
40
|
+
# where it ran over $180-$187 a second time.
|
|
41
|
+
def self.xpos(pixel, width, hold)
|
|
42
|
+
count = (pixel - X_OFFSET) % width
|
|
43
|
+
count < HOLD_AT ? count : count - hold
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# The raster pixels at which the X counter reads each coordinate, 512
|
|
47
|
+
# lists. A sprite starts at one where its X matches. On the 6569 the
|
|
48
|
+
# coordinates past 503 have none.
|
|
49
|
+
def self.x_pixels(width, hold)
|
|
50
|
+
pixels = Array.new(512) { [] }
|
|
51
|
+
width.times { |pixel| pixels[xpos(pixel, width, hold)] << pixel }
|
|
52
|
+
pixels.each(&:freeze).freeze
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|