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,161 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Drives
|
|
5
|
+
# The serial bus between the C64 and its drives: ATN, CLK and DATA, each
|
|
6
|
+
# an open-collector line with a pull-up. A line is low while any device
|
|
7
|
+
# pulls it (wired-AND), and high otherwise. Every read works the levels
|
|
8
|
+
# out from what each side drives now.
|
|
9
|
+
#
|
|
10
|
+
# The C64 drives the lines from CIA 2's port A through 7406 inverters, so
|
|
11
|
+
# an output bit of 1 pulls its line low: PA3 ATN, PA4 CLK and PA5 DATA.
|
|
12
|
+
# The machine pushes those bits into the bus (host_lines=), which holds
|
|
13
|
+
# them. PA6 and PA7 read CLK and DATA directly, 1 for a released line.
|
|
14
|
+
# The bus stands in as CIA 2's peripheral for those two inputs.
|
|
15
|
+
#
|
|
16
|
+
# A drive drives CLK and DATA from VIA 1's PB3 and PB1, the same way. It
|
|
17
|
+
# also pulls DATA while ATN IN differs from its ATN acknowledge on PB4
|
|
18
|
+
# (an XOR gate), which answers ATN in hardware before the DOS gets to it.
|
|
19
|
+
# SerialPort reads the lines back into VIA 1. A drive whose
|
|
20
|
+
# serial_output sets DRIVE_ATN_GATED pulls DATA that way only while
|
|
21
|
+
# ATN is low, as the 1581's NAND does.
|
|
22
|
+
#
|
|
23
|
+
# Fast serial adds SRQ, which the C64 leaves alone. A C128 and a 1571
|
|
24
|
+
# clock bytes over it from a CIA's CNT, with the bits on DATA from its
|
|
25
|
+
# SP, through buffers each side turns towards the bus to send. A pin low
|
|
26
|
+
# pulls its line low. Each side pushes the lines it pulls when they
|
|
27
|
+
# move: the host through host_fast_lines=, which tells the drives
|
|
28
|
+
# (fast_lines_moved), and a drive through drives_fast_moved!, which
|
|
29
|
+
# tells the host (on_fast_change).
|
|
30
|
+
class SerialBus
|
|
31
|
+
# CIA 2 port A
|
|
32
|
+
HOST_ATN_OUT = 0x08
|
|
33
|
+
HOST_CLK_OUT = 0x10
|
|
34
|
+
HOST_DATA_OUT = 0x20
|
|
35
|
+
HOST_CLK_IN = 0x40
|
|
36
|
+
HOST_DATA_IN = 0x80
|
|
37
|
+
|
|
38
|
+
# VIA 1 port B
|
|
39
|
+
DRIVE_DATA_OUT = 0x02
|
|
40
|
+
DRIVE_CLK_OUT = 0x08
|
|
41
|
+
DRIVE_ATNA = 0x10
|
|
42
|
+
|
|
43
|
+
# The lines pulled low, as ATN, CLK, DATA and SRQ bits
|
|
44
|
+
ATN = 0x01
|
|
45
|
+
CLK = 0x02
|
|
46
|
+
DATA = 0x04
|
|
47
|
+
SRQ = 0x08
|
|
48
|
+
|
|
49
|
+
# A drive's serial_output bits above VIA 1's port B: its fast serial
|
|
50
|
+
# pins pulling DATA and SRQ.
|
|
51
|
+
DRIVE_FAST_DATA = 0x100
|
|
52
|
+
DRIVE_FAST_SRQ = 0x200
|
|
53
|
+
|
|
54
|
+
# A drive's serial_output bit whose ATN acknowledge pulls DATA only
|
|
55
|
+
# while ATN is low.
|
|
56
|
+
DRIVE_ATN_GATED = 0x400
|
|
57
|
+
|
|
58
|
+
attr_reader :drives, :host_lines
|
|
59
|
+
|
|
60
|
+
# The lines the host's fast serial pins pull, as DATA and SRQ bits.
|
|
61
|
+
attr_reader :host_fast_lines
|
|
62
|
+
|
|
63
|
+
def initialize
|
|
64
|
+
@drives = []
|
|
65
|
+
@host_lines = 0
|
|
66
|
+
@host_fast_lines = 0
|
|
67
|
+
@drive_fast_lines = 0
|
|
68
|
+
@on_fast_change = nil
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# The host's fast serial pins moved: +low+ is the lines they pull, as
|
|
72
|
+
# DATA and SRQ bits.
|
|
73
|
+
def host_fast_lines=(low)
|
|
74
|
+
return if low == @host_fast_lines
|
|
75
|
+
|
|
76
|
+
@host_fast_lines = low
|
|
77
|
+
@drives.each(&:fast_lines_moved)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# A drive's fast serial pins moved (serial_output's fast bits).
|
|
81
|
+
def drives_fast_moved!
|
|
82
|
+
low = 0
|
|
83
|
+
@drives.each do |drive|
|
|
84
|
+
output = drive.serial_output
|
|
85
|
+
low |= DATA if output.anybits?(DRIVE_FAST_DATA)
|
|
86
|
+
low |= SRQ if output.anybits?(DRIVE_FAST_SRQ)
|
|
87
|
+
end
|
|
88
|
+
return if low == @drive_fast_lines
|
|
89
|
+
|
|
90
|
+
@drive_fast_lines = low
|
|
91
|
+
@on_fast_change&.call
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Calls the block whenever the drives move their fast serial pins.
|
|
95
|
+
def on_fast_change(&block)
|
|
96
|
+
@on_fast_change = block
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# The machine pushes the lines it pulls, as port A bits, whenever they
|
|
100
|
+
# may have moved: its output bits, with input bits floating high as the
|
|
101
|
+
# 7406 inputs see them. A bus with only drives on it keeps 0.
|
|
102
|
+
def host_lines=(lines)
|
|
103
|
+
@host_lines = lines
|
|
104
|
+
@drives.each(&:host_written!)
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def attach(drive)
|
|
108
|
+
@drives << drive unless @drives.include?(drive)
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def detach(drive)
|
|
112
|
+
@drives.delete(drive)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# One pass over everything on the bus, for a reader that wants more
|
|
116
|
+
# than one line, SRQ included. +host+ is the C64's port A lines as the
|
|
117
|
+
# reader sees them, which a drive takes a cycle late (see
|
|
118
|
+
# Drives::Engine::SerialLines).
|
|
119
|
+
def low_lines(host = @host_lines)
|
|
120
|
+
atn = host.anybits?(HOST_ATN_OUT)
|
|
121
|
+
low = @host_fast_lines | @drive_fast_lines
|
|
122
|
+
low |= ATN if atn
|
|
123
|
+
low |= CLK if host.anybits?(HOST_CLK_OUT)
|
|
124
|
+
low |= DATA if host.anybits?(HOST_DATA_OUT)
|
|
125
|
+
i = 0
|
|
126
|
+
while i < @drives.length
|
|
127
|
+
drive = @drives[i].serial_output
|
|
128
|
+
low |= CLK if drive.anybits?(DRIVE_CLK_OUT)
|
|
129
|
+
low |= DATA if drive.anybits?(DRIVE_DATA_OUT) || acknowledging?(drive, atn)
|
|
130
|
+
i += 1
|
|
131
|
+
end
|
|
132
|
+
low
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def atn_low?(host = @host_lines) = host.anybits?(HOST_ATN_OUT)
|
|
136
|
+
|
|
137
|
+
# Whether a drive's ATN acknowledge pulls DATA, with its serial_output
|
|
138
|
+
# +drive+, while ATN is +atn+.
|
|
139
|
+
def acknowledging?(drive, atn)
|
|
140
|
+
atn != drive.anybits?(DRIVE_ATNA) && (atn || drive.nobits?(DRIVE_ATN_GATED))
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def clk_low? = low_lines.anybits?(CLK)
|
|
144
|
+
|
|
145
|
+
def data_low? = low_lines.anybits?(DATA)
|
|
146
|
+
|
|
147
|
+
# CIA 2's port A pins as the bus leaves them: CLK IN and DATA IN low
|
|
148
|
+
# while their lines are.
|
|
149
|
+
def read_a(_port_a, _port_b)
|
|
150
|
+
low = low_lines
|
|
151
|
+
value = 0xff
|
|
152
|
+
value &= ~HOST_CLK_IN if low.anybits?(CLK)
|
|
153
|
+
value &= ~HOST_DATA_IN if low.anybits?(DATA)
|
|
154
|
+
value
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# Port B goes to the user port, not the serial bus.
|
|
158
|
+
def read_b(_port_a, _port_b) = 0xff
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
@@ -33,9 +33,9 @@ module Badline
|
|
|
33
33
|
def self.media_problem
|
|
34
34
|
yield
|
|
35
35
|
""
|
|
36
|
-
rescue Machine::Unsupported, Media::TrueDrive::Error, Media::DiskList::Error, Media::NotDisk, Datasette::Missing,
|
|
37
|
-
SystemCallError,
|
|
38
|
-
Storage::CRTFile::FormatError, Storage::G64Image::FormatError, Cartridge::UnsupportedTypeError,
|
|
36
|
+
rescue Machine::Unsupported, Media::TrueDrive::Error, Media::DiskList::Error, Media::NotDisk, Drives::Datasette::Missing,
|
|
37
|
+
SystemCallError, SIDTune::File::FormatError, Storage::T64::FormatError, Storage::TAP::FormatError,
|
|
38
|
+
Storage::CRTFile::FormatError, Storage::G64Image::FormatError, C64::Cartridge::UnsupportedTypeError,
|
|
39
39
|
Snapshot::FormatError => e
|
|
40
40
|
e.message
|
|
41
41
|
end
|
|
@@ -17,7 +17,8 @@ module Badline
|
|
|
17
17
|
attr_reader :renderer, :texture
|
|
18
18
|
|
|
19
19
|
# Opens the window for `screen`, presenting in step with the display
|
|
20
|
-
# when `vsync`.
|
|
20
|
+
# when `vsync`. Text input stays off, so a dead key such as ´ on a Mac
|
|
21
|
+
# arrives as a key press, as every other key does.
|
|
21
22
|
def initialize(screen, vsync:)
|
|
22
23
|
abort "SDL_Init: #{SDL.SDL_GetError}" unless SDL.SDL_Init(SDL::INIT_VIDEO | SDL::INIT_EVENTS).zero?
|
|
23
24
|
|
|
@@ -28,6 +29,7 @@ module Badline
|
|
|
28
29
|
TITLE, SDL::WINDOWPOS_CENTERED, SDL::WINDOWPOS_CENTERED, @width * SCALE, @height * SCALE,
|
|
29
30
|
SDL::WINDOW_RESIZABLE
|
|
30
31
|
)
|
|
32
|
+
SDL.SDL_StopTextInput
|
|
31
33
|
flags = SDL::RENDERER_ACCELERATED
|
|
32
34
|
flags |= SDL::RENDERER_PRESENTVSYNC if vsync
|
|
33
35
|
@renderer = SDL.SDL_CreateRenderer(@window, -1, flags)
|
|
@@ -31,7 +31,7 @@ module Badline
|
|
|
31
31
|
cutoff = (history.register(frame, 0x15) & 0x07) | (history.register(frame, 0x16) << 3)
|
|
32
32
|
resonance = history.register(frame, 0x17) >> 4
|
|
33
33
|
mode_volume = history.register(frame, 0x18)
|
|
34
|
-
hertz = SID::Filter::W0.fetch(model)[cutoff] / (2 * Math::PI * SID::Filter::SCALE)
|
|
34
|
+
hertz = Chips::SID::Filter::W0.fetch(model)[cutoff] / (2 * Math::PI * Chips::SID::Filter::SCALE)
|
|
35
35
|
paint = @painter
|
|
36
36
|
paint.text(LEFT, top, "FILTER", BRIGHT)
|
|
37
37
|
x = LEFT + 64
|
|
@@ -106,7 +106,7 @@ module Badline
|
|
|
106
106
|
# Keeps the subtune's STIL credits for the header and the whole entry
|
|
107
107
|
# for the INFO view.
|
|
108
108
|
def stil(fields, subtune, subtune_fields)
|
|
109
|
-
@credits =
|
|
109
|
+
@credits = SIDTune::STIL::Credit.list(subtune_fields.empty? ? fields : subtune_fields)
|
|
110
110
|
@stil = fields
|
|
111
111
|
@stil_subtune = subtune
|
|
112
112
|
@subtune_stil = subtune_fields
|
|
@@ -211,7 +211,7 @@ module Badline
|
|
|
211
211
|
|
|
212
212
|
def draw
|
|
213
213
|
@next_draw = now + FRAME
|
|
214
|
-
@screen.draw(@state, @player, @history, @tune_file,
|
|
214
|
+
@screen.draw(@state, @player, @history, @tune_file, SIDTune::STIL::Credit.at(@credits, @state.played))
|
|
215
215
|
end
|
|
216
216
|
|
|
217
217
|
def now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
|
|
@@ -31,6 +31,7 @@ module Badline
|
|
|
31
31
|
SDL.SDL_SetHint("SDL_RENDER_SCALE_QUALITY", "0")
|
|
32
32
|
@window = SDL.SDL_CreateWindow(TITLE, SDL::WINDOWPOS_CENTERED, SDL::WINDOWPOS_CENTERED,
|
|
33
33
|
WIDTH * SCALE, height(view) * SCALE, SDL::WINDOW_RESIZABLE)
|
|
34
|
+
SDL.SDL_StopTextInput
|
|
34
35
|
@renderer = SDL.SDL_CreateRenderer(@window, -1, SDL::RENDERER_ACCELERATED)
|
|
35
36
|
SDL.SDL_RenderSetLogicalSize(@renderer, WIDTH, height(view))
|
|
36
37
|
build
|
|
@@ -6,13 +6,13 @@ module Badline
|
|
|
6
6
|
# C64's palette: one for each voice, and light blue on blue as on the
|
|
7
7
|
# machine's screen.
|
|
8
8
|
module PlayerTheme
|
|
9
|
-
TEXT = VIC::PALETTE[14]
|
|
10
|
-
BRIGHT = VIC::PALETTE[1]
|
|
11
|
-
DIM = VIC::PALETTE[11]
|
|
12
|
-
BOX = VIC::PALETTE[0]
|
|
13
|
-
BACKGROUND = VIC::PALETTE[6]
|
|
14
|
-
WARNING = VIC::PALETTE[10]
|
|
15
|
-
VOICE_COLORS = [VIC::PALETTE[7], VIC::PALETTE[13], VIC::PALETTE[3]].freeze
|
|
9
|
+
TEXT = Chips::VIC::PALETTE[14]
|
|
10
|
+
BRIGHT = Chips::VIC::PALETTE[1]
|
|
11
|
+
DIM = Chips::VIC::PALETTE[11]
|
|
12
|
+
BOX = Chips::VIC::PALETTE[0]
|
|
13
|
+
BACKGROUND = Chips::VIC::PALETTE[6]
|
|
14
|
+
WARNING = Chips::VIC::PALETTE[10]
|
|
15
|
+
VOICE_COLORS = [Chips::VIC::PALETTE[7], Chips::VIC::PALETTE[13], Chips::VIC::PALETTE[3]].freeze
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
18
|
end
|
|
@@ -39,15 +39,15 @@ module Badline
|
|
|
39
39
|
|
|
40
40
|
# The Keyboard's key for a name such as space, return or a.
|
|
41
41
|
def self.keyboard_key(name)
|
|
42
|
-
key = Keyboard.new.matrix.flatten.find { |candidate| candidate.to_s == name }
|
|
43
|
-
key.nil? ? Keyboard::COMBINATIONS.keys.find { |candidate| candidate.to_s == name } : key
|
|
42
|
+
key = Input::Keyboard.new.matrix.flatten.find { |candidate| candidate.to_s == name }
|
|
43
|
+
key.nil? ? Input::Keyboard::COMBINATIONS.keys.find { |candidate| candidate.to_s == name } : key
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
# The direction of joy1-NAME or joy2-NAME, such as up or fire.
|
|
47
47
|
def self.joystick_direction(name)
|
|
48
48
|
return nil unless name.start_with?("joy1-") || name.start_with?("joy2-")
|
|
49
49
|
|
|
50
|
-
Joystick::DIRECTIONS.keys.find { |direction| direction.to_s == name[5, name.size - 5] }
|
|
50
|
+
Input::Joystick::DIRECTIONS.keys.find { |direction| direction.to_s == name[5, name.size - 5] }
|
|
51
51
|
end
|
|
52
52
|
|
|
53
53
|
# The screenshot's file name, with the frame's number in place of %d,
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Input
|
|
5
|
+
# CIA 1's control ports and the keyboard matrix that spans them.
|
|
6
|
+
#
|
|
7
|
+
# Port A carries the matrix rows together with joystick 2, port B the matrix
|
|
8
|
+
# columns together with joystick 1. Every switch is active low, so the
|
|
9
|
+
# joysticks are wired-AND onto the lines *before* the matrix settles: a stick
|
|
10
|
+
# held in a direction selects rows and columns of its own, which is where
|
|
11
|
+
# hardware's phantom keypresses come from. Paddles and a 1351 mouse have
|
|
12
|
+
# buttons on those same lines.
|
|
13
|
+
#
|
|
14
|
+
# The ports also carry SID's POTX/POTY lines, which reach them through analog
|
|
15
|
+
# switches closed by CIA 1 PA6 (port 1) and PA7 (port 2). Close both and the
|
|
16
|
+
# pots sit in parallel, so SID charges through the lower of the two
|
|
17
|
+
# resistances; close neither and the lines float high. Reading a pot asks the
|
|
18
|
+
# CIA for the current select lines, since a program sets them and then goes
|
|
19
|
+
# straight to SID without touching the ports again.
|
|
20
|
+
#
|
|
21
|
+
# A matrix may have rows beyond port A's eight. Their select lines come from
|
|
22
|
+
# outside the CIA and are pushed into +extra_rows+, bit 0 for the ninth row
|
|
23
|
+
# upwards, active low like port A; idle, every line is high and none of
|
|
24
|
+
# those rows is selected. They settle with port A's lines as rows 8 and up,
|
|
25
|
+
# so their keys reach port B, but port A reads only its own eight.
|
|
26
|
+
class ControlPorts
|
|
27
|
+
PORT1_POTS = 0x40
|
|
28
|
+
PORT2_POTS = 0x80
|
|
29
|
+
FIRE = 0x10
|
|
30
|
+
|
|
31
|
+
attr_reader :keyboard, :joystick1, :joystick2
|
|
32
|
+
attr_accessor :device1, :device2, :port_a_source, :extra_rows
|
|
33
|
+
|
|
34
|
+
def initialize(keyboard:, joystick1:, joystick2:)
|
|
35
|
+
@keyboard = keyboard
|
|
36
|
+
@joystick1 = joystick1
|
|
37
|
+
@joystick2 = joystick2
|
|
38
|
+
@device1 = nil
|
|
39
|
+
@device2 = nil
|
|
40
|
+
@port_a_source = nil
|
|
41
|
+
@extra_rows = 0xff
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def read_a(port_a, port_b) = scan(port_a, port_b).first & 0xff
|
|
45
|
+
|
|
46
|
+
def read_b(port_a, port_b) = scan(port_a, port_b).last
|
|
47
|
+
|
|
48
|
+
# Control port 1 pin 6 is both the port B fire line and the VIC's light
|
|
49
|
+
# pen input, so joystick 1's button and a 1351's left button latch
|
|
50
|
+
# $D013/$D014. The CIA samples this every cycle, so it skips the matrix and
|
|
51
|
+
# asks only what the port's own devices drive.
|
|
52
|
+
def port_b4_high? = port_bits(@joystick1, @device1).anybits?(FIRE)
|
|
53
|
+
|
|
54
|
+
def pot_x = selected_devices.map(&:pot_x).min || 0xff
|
|
55
|
+
|
|
56
|
+
def pot_y = selected_devices.map(&:pot_y).min || 0xff
|
|
57
|
+
|
|
58
|
+
private
|
|
59
|
+
|
|
60
|
+
def selected_devices
|
|
61
|
+
lines = @port_a_source&.port_a_lines || 0x00
|
|
62
|
+
devices = []
|
|
63
|
+
devices << @device1 if @device1 && lines.anybits?(PORT1_POTS)
|
|
64
|
+
devices << @device2 if @device2 && lines.anybits?(PORT2_POTS)
|
|
65
|
+
devices
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def scan(port_a, port_b)
|
|
69
|
+
keyboard.scan((port_a & port_bits(@joystick2, @device2)) | (@extra_rows << 8),
|
|
70
|
+
port_b & port_bits(@joystick1, @device1))
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def port_bits(joystick, device)
|
|
74
|
+
device ? joystick.port_bits & device.port_bits : joystick.port_bits
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Input
|
|
5
|
+
class Joystick
|
|
6
|
+
DIRECTIONS = { up: 0, down: 1, left: 2, right: 3, fire: 4 }.freeze
|
|
7
|
+
|
|
8
|
+
# Kept up to date as switches move, since the CIA samples the fire line
|
|
9
|
+
# every cycle to drive the light pen input.
|
|
10
|
+
attr_reader :port_bits
|
|
11
|
+
|
|
12
|
+
def initialize
|
|
13
|
+
@port_bits = 0xff
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def press(direction)
|
|
17
|
+
bit = DIRECTIONS[direction]
|
|
18
|
+
@port_bits &= ~(1 << bit) if bit
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def release(direction)
|
|
22
|
+
bit = DIRECTIONS[direction]
|
|
23
|
+
@port_bits |= 1 << bit if bit
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Input
|
|
5
|
+
# The key matrix spanning CIA 1's two ports: rows on port A, columns on
|
|
6
|
+
# port B. Row lines beyond the eighth sit above port A's bits in +rows+.
|
|
7
|
+
#
|
|
8
|
+
# A pressed key shorts its row line to its column line, so whichever side is
|
|
9
|
+
# pulled low drags the other down with it. Scanning works in either
|
|
10
|
+
# direction, and chains of keys sharing a line propagate the pulldown -- the
|
|
11
|
+
# ghost keys real hardware reports.
|
|
12
|
+
class Keyboard
|
|
13
|
+
include IntegerHelper
|
|
14
|
+
|
|
15
|
+
# Keys the C64 types as a combination: cursor up and cursor left are the
|
|
16
|
+
# shifted cursor keys. Pressing one holds both of its matrix keys, while
|
|
17
|
+
# a shift key held on its own stays down when it is released.
|
|
18
|
+
COMBINATIONS = {
|
|
19
|
+
cursor_up: %i[lshift cursor_v],
|
|
20
|
+
cursor_left: %i[lshift cursor_h]
|
|
21
|
+
}.freeze
|
|
22
|
+
|
|
23
|
+
# The C64's wiring: one row of keys per port A line, in port B column
|
|
24
|
+
# order.
|
|
25
|
+
C64_MATRIX = [
|
|
26
|
+
%i[delete return cursor_h f7 f1 f3 f5 cursor_v],
|
|
27
|
+
%i[3 w a 4 z s e lshift],
|
|
28
|
+
%i[5 r d 6 c f t x],
|
|
29
|
+
%i[7 y g 8 b h u v],
|
|
30
|
+
%i[9 i j 0 m k o n],
|
|
31
|
+
%i[+ p l - . : @ ,],
|
|
32
|
+
%i[£ * ; clr_home rshift = up /],
|
|
33
|
+
%i[1 left control 2 space cbm q run_stop]
|
|
34
|
+
].freeze
|
|
35
|
+
|
|
36
|
+
attr_reader :keys, :matrix
|
|
37
|
+
|
|
38
|
+
def initialize(matrix: C64_MATRIX)
|
|
39
|
+
@keys = []
|
|
40
|
+
@row_masks = nil
|
|
41
|
+
@matrix = matrix
|
|
42
|
+
@connected = true
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Whether the machine has a keyboard. The C64GS has none: no key goes
|
|
46
|
+
# down on it.
|
|
47
|
+
def connected? = @connected
|
|
48
|
+
|
|
49
|
+
def connected=(connected)
|
|
50
|
+
@connected = connected
|
|
51
|
+
@keys.clear unless connected
|
|
52
|
+
@row_masks = nil
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def press(key)
|
|
56
|
+
return unless @connected && valid_key?(key)
|
|
57
|
+
|
|
58
|
+
@keys << key
|
|
59
|
+
@row_masks = nil
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def release(key)
|
|
63
|
+
@keys.reject! { |k| k == key }
|
|
64
|
+
@row_masks = nil
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Settles the row (port A) and column (port B) lines against each other
|
|
68
|
+
# until no key contact pulls a line low any more, and returns both.
|
|
69
|
+
def scan(rows, cols)
|
|
70
|
+
return [rows, cols] if keys.empty?
|
|
71
|
+
|
|
72
|
+
loop do
|
|
73
|
+
settled_rows = rows
|
|
74
|
+
settled_cols = cols
|
|
75
|
+
|
|
76
|
+
row_masks.each_with_index do |mask, row|
|
|
77
|
+
bit = 1 << row
|
|
78
|
+
next if mask.zero? || (rows.allbits?(bit) && cols.allbits?(mask))
|
|
79
|
+
|
|
80
|
+
rows &= ~bit
|
|
81
|
+
cols &= ~mask
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
return [rows, cols] if rows == settled_rows && cols == settled_cols
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def read_a(port_a, port_b) = scan(port_a, port_b).first
|
|
89
|
+
|
|
90
|
+
def read_b(port_a, port_b) = scan(port_a, port_b).last
|
|
91
|
+
|
|
92
|
+
private
|
|
93
|
+
|
|
94
|
+
# Columns held down per row, as a bit mask of port B lines.
|
|
95
|
+
def row_masks
|
|
96
|
+
@row_masks ||= begin
|
|
97
|
+
pressed = held
|
|
98
|
+
matrix.map do |row|
|
|
99
|
+
row.each_with_index.sum { |key, column| pressed.include?(key) ? 1 << column : 0 }
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# The matrix keys held down, with each combination expanded.
|
|
105
|
+
def held
|
|
106
|
+
keys.flat_map { |key| COMBINATIONS[key] || [key] }
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def valid_key?(key)
|
|
110
|
+
COMBINATIONS.key?(key) || matrix.flatten.include?(key)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
data/lib/badline/input.rb
CHANGED