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,182 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Chips
|
|
5
|
+
class VIA
|
|
6
|
+
# The 6522's shift register, with the CB1 clock and CB2 data lines it
|
|
7
|
+
# takes over in every mode but the first.
|
|
8
|
+
#
|
|
9
|
+
# ACR bits 4-2 pick the mode. Modes 1 to 3 shift in, left, with the new
|
|
10
|
+
# bit taken from CB2 into bit 0 on each rising CB1 edge. Modes 4 to 7
|
|
11
|
+
# shift out: each falling CB1 edge puts bit 7 on CB2 and rotates it back
|
|
12
|
+
# round into bit 0, so after eight bits the byte is back where it
|
|
13
|
+
# started. Modes 1, 4 and 5 clock off timer 2, modes 2 and 6 off φ2, and
|
|
14
|
+
# modes 3 and 7 off whatever drives CB1 from outside.
|
|
15
|
+
#
|
|
16
|
+
# Under its own clock the register drives CB1, idling high. Reading or
|
|
17
|
+
# writing the data register starts a byte, but only while the register
|
|
18
|
+
# is idle and enabled: an access in mode 0, or one before the eighth bit
|
|
19
|
+
# is in, leaves the count alone. CB1 falls on the first clock tick of
|
|
20
|
+
# the byte and rises on the second, and so on, so a byte is eight pulses
|
|
21
|
+
# over sixteen ticks. The interrupt flag is set on the tick that raises
|
|
22
|
+
# CB1 over the eighth bit, and CB1 then stays high until the next
|
|
23
|
+
# access.
|
|
24
|
+
#
|
|
25
|
+
# In modes 2 and 6 a tick is a φ2 cycle, from the second cycle after
|
|
26
|
+
# the access on, which makes a byte sixteen cycles. In modes 1, 4 and 5
|
|
27
|
+
# it comes two cycles after each timer 2 low byte underflow, on the
|
|
28
|
+
# cycle after the low byte reloads, which makes a byte sixteen
|
|
29
|
+
# underflows. Mode 4 never stops and never interrupts: its counter is
|
|
30
|
+
# disabled, and the byte goes round and round.
|
|
31
|
+
#
|
|
32
|
+
# Under an external clock the register shifts on every CB1 edge, access
|
|
33
|
+
# or not. The access only arms the counter: the flag is set on the eighth
|
|
34
|
+
# rising edge after it, and the counter then waits for the next access.
|
|
35
|
+
class ShiftRegister
|
|
36
|
+
DISABLED = 0
|
|
37
|
+
IN_T2 = 1
|
|
38
|
+
IN_PHI2 = 2
|
|
39
|
+
IN_EXTERNAL = 3
|
|
40
|
+
OUT_FREE_RUNNING = 4
|
|
41
|
+
OUT_T2 = 5
|
|
42
|
+
OUT_PHI2 = 6
|
|
43
|
+
OUT_EXTERNAL = 7
|
|
44
|
+
|
|
45
|
+
attr_reader :mode, :data
|
|
46
|
+
attr_accessor :cb2_input
|
|
47
|
+
|
|
48
|
+
def initialize
|
|
49
|
+
@mode = DISABLED
|
|
50
|
+
@data = 0x00
|
|
51
|
+
# Bits still to count before the flag, zero when the counter is idle.
|
|
52
|
+
@bits = 0
|
|
53
|
+
# The clock's last two cycles, newest in bit 0: timer 2 low byte
|
|
54
|
+
# underflows in modes 1, 4 and 5, and whether the byte has started
|
|
55
|
+
# in modes 2 and 6.
|
|
56
|
+
@delay = 0
|
|
57
|
+
@clock = true
|
|
58
|
+
@cb2 = true
|
|
59
|
+
# Nothing drives CB2 from outside, so it floats high.
|
|
60
|
+
@cb2_input = true
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def mode=(value)
|
|
64
|
+
@mode = value & 0x07
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def data=(value)
|
|
68
|
+
@data = value & 0xff
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# A read or write of the data register, which starts a byte if the
|
|
72
|
+
# register is idle and enabled.
|
|
73
|
+
def access!
|
|
74
|
+
return if @mode == DISABLED || @bits.nonzero?
|
|
75
|
+
|
|
76
|
+
@bits = 8
|
|
77
|
+
@delay = 0 if @mode == IN_PHI2 || @mode == OUT_PHI2
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Whether the register is counting bits off its own clock, which
|
|
81
|
+
# changes it from cycle to cycle.
|
|
82
|
+
def clocking? = @bits.nonzero? && internal_clock?
|
|
83
|
+
|
|
84
|
+
def save_state(out)
|
|
85
|
+
out.int(@mode).int(@data).int(@bits).int(@delay).boolean(@clock).boolean(@cb2).boolean(@cb2_input)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def load_state(input)
|
|
89
|
+
@mode = input.int
|
|
90
|
+
@data = input.int
|
|
91
|
+
@bits = input.int
|
|
92
|
+
@delay = input.int
|
|
93
|
+
@clock = input.boolean?
|
|
94
|
+
@cb2 = input.boolean?
|
|
95
|
+
@cb2_input = input.boolean?
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
# Everything the register holds, for comparing it at two points.
|
|
99
|
+
def state = [@mode, @data, @bits, @delay, @clock, @cb2, @cb2_input]
|
|
100
|
+
|
|
101
|
+
# The CB1 level the register drives, or nil when CB1 is an input.
|
|
102
|
+
def cb1_output
|
|
103
|
+
internal_clock? ? @clock : nil
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# The CB2 level the register drives, or nil when it doesn't.
|
|
107
|
+
def cb2_output
|
|
108
|
+
@mode >= OUT_FREE_RUNNING ? @cb2 : nil
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Clocked once per φ2 cycle, with whether timer 2's low byte underflowed
|
|
112
|
+
# on it. Returns true on the cycle that sets the interrupt flag.
|
|
113
|
+
def cycle!(t2_low_underflow)
|
|
114
|
+
case @mode
|
|
115
|
+
when IN_PHI2, OUT_PHI2 then @bits.nonzero? && phi2_tick
|
|
116
|
+
when IN_T2, OUT_T2, OUT_FREE_RUNNING then t2_tick(t2_low_underflow)
|
|
117
|
+
else false
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# A level change on CB1 from outside. Only the external clock modes
|
|
122
|
+
# listen: shifting in samples CB2 as CB1 rises, and shifting out puts
|
|
123
|
+
# the next bit on CB2 as it falls. Returns true when the edge sets the
|
|
124
|
+
# interrupt flag.
|
|
125
|
+
def cb1_edge!(rising)
|
|
126
|
+
return false unless @mode == IN_EXTERNAL || @mode == OUT_EXTERNAL
|
|
127
|
+
|
|
128
|
+
shift_in if rising && @mode == IN_EXTERNAL
|
|
129
|
+
shift_out if !rising && @mode == OUT_EXTERNAL
|
|
130
|
+
rising && eighth_bit?
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
private
|
|
134
|
+
|
|
135
|
+
def internal_clock?
|
|
136
|
+
@mode != DISABLED && @mode != IN_EXTERNAL && @mode != OUT_EXTERNAL
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# A φ2 cycle of a byte: every one but the first ticks.
|
|
140
|
+
def phi2_tick
|
|
141
|
+
started = @delay.nonzero?
|
|
142
|
+
@delay = 1
|
|
143
|
+
started && tick
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# Ticks on the underflow from two cycles back, while a byte is under
|
|
147
|
+
# way.
|
|
148
|
+
def t2_tick(underflow)
|
|
149
|
+
due = @delay.anybits?(2)
|
|
150
|
+
@delay = ((@delay << 1) & 2) | (underflow ? 1 : 0)
|
|
151
|
+
due && @bits.nonzero? && tick
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
# One half period of the register's own clock: a falling edge puts a
|
|
155
|
+
# bit out, and a rising one takes a bit in and counts it.
|
|
156
|
+
def tick
|
|
157
|
+
@clock = !@clock
|
|
158
|
+
shift_out if !@clock && @mode >= OUT_FREE_RUNNING
|
|
159
|
+
shift_in if @clock && @mode < IN_EXTERNAL
|
|
160
|
+
@clock && @mode != OUT_FREE_RUNNING && eighth_bit?
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# Counts a bit, and says whether it was the eighth since the access.
|
|
164
|
+
def eighth_bit?
|
|
165
|
+
return false if @bits.zero?
|
|
166
|
+
|
|
167
|
+
@bits -= 1
|
|
168
|
+
@bits.zero?
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def shift_in
|
|
172
|
+
@data = ((@data << 1) | (@cb2_input ? 1 : 0)) & 0xff
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def shift_out
|
|
176
|
+
@cb2 = @data.anybits?(0x80)
|
|
177
|
+
@data = ((@data << 1) | (@cb2 ? 1 : 0)) & 0xff
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Chips
|
|
5
|
+
class VIA
|
|
6
|
+
# Timer 1: a 16-bit counter that decrements on every φ2 cycle, with a
|
|
7
|
+
# latch it reloads from on every timeout and the PB7 output.
|
|
8
|
+
#
|
|
9
|
+
# Writing the high counter byte loads the counter on the cycle after,
|
|
10
|
+
# so a timer loaded with N reads N, N-1, ... 0 and then $FFFF, which is
|
|
11
|
+
# the cycle its interrupt flag sets: N + 1.5 cycles after the write in
|
|
12
|
+
# the datasheet's terms. The counter then reloads from the latch on the
|
|
13
|
+
# next cycle, which makes the period N + 2 cycles. It does so in one-shot
|
|
14
|
+
# mode too, unlike timer 2.
|
|
15
|
+
#
|
|
16
|
+
# Only a write of the high counter byte arms the timer. An armed timeout
|
|
17
|
+
# sets the flag and inverts PB7, and in one-shot mode disarms it, so the
|
|
18
|
+
# first timeout after the load alone does. Free-running keeps it armed,
|
|
19
|
+
# but switching to free-running doesn't arm it: an unarmed timer counts
|
|
20
|
+
# and reloads without touching the flag or PB7. The load pulls PB7 low,
|
|
21
|
+
# and ACR bit 7 turning on drives it high, so a timer loaded before its
|
|
22
|
+
# PB7 output is enabled reads high until the timeout pulls it low.
|
|
23
|
+
class Timer1
|
|
24
|
+
attr_accessor :counter, :latch
|
|
25
|
+
|
|
26
|
+
# The level the timer drives on PB7 when ACR bit 7 hands it the pin.
|
|
27
|
+
attr_reader :pb7
|
|
28
|
+
|
|
29
|
+
# ACR bit 7 turning on hands PB7 to the timer high.
|
|
30
|
+
def pb7_enabled!
|
|
31
|
+
@pb7 = true
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def initialize
|
|
35
|
+
@counter = @latch = 0xffff
|
|
36
|
+
@reload = @hold = false
|
|
37
|
+
@armed = false
|
|
38
|
+
@pb7 = true
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def write_latch_low(value)
|
|
42
|
+
@latch = (@latch & 0xff00) | value
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def write_latch_high(value)
|
|
46
|
+
@latch = (value << 8) | (@latch & 0xff)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# The high counter byte write: load from the latch, hold the count
|
|
50
|
+
# for a cycle, arm the interrupt and pull PB7 low.
|
|
51
|
+
def start!
|
|
52
|
+
@counter = @latch
|
|
53
|
+
@hold = true
|
|
54
|
+
@reload = false
|
|
55
|
+
@armed = true
|
|
56
|
+
@pb7 = false
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# One φ2 cycle. Returns true on the cycle that sets the interrupt flag.
|
|
60
|
+
def cycle!(free_run)
|
|
61
|
+
if @hold || @reload
|
|
62
|
+
@counter = @latch if @reload
|
|
63
|
+
@hold = @reload = false
|
|
64
|
+
return false
|
|
65
|
+
end
|
|
66
|
+
@counter = (@counter - 1) & 0xffff
|
|
67
|
+
@counter == 0xffff && timeout(free_run)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# How many cycles the timer can run without setting its flag: until
|
|
71
|
+
# an armed timer's timeout, and forever for an unarmed one, whose
|
|
72
|
+
# timeouts only reload the counter. None while an armed timer loads
|
|
73
|
+
# or reloads.
|
|
74
|
+
def quiet_cycles
|
|
75
|
+
return FastForward::QUIET unless @armed
|
|
76
|
+
return 0 if @hold || @reload
|
|
77
|
+
|
|
78
|
+
@counter
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Runs +cycles+ cycles at once, as many as quiet_cycles allows. An
|
|
82
|
+
# unarmed timer goes round its period of latch + 2 cycles: the
|
|
83
|
+
# timeout at $FFFF, the reload, and latch down to 0.
|
|
84
|
+
def fast_forward(cycles)
|
|
85
|
+
if @hold || @reload
|
|
86
|
+
cycle!(false)
|
|
87
|
+
cycles -= 1
|
|
88
|
+
end
|
|
89
|
+
return @counter -= cycles if cycles <= @counter
|
|
90
|
+
|
|
91
|
+
phase = (cycles - @counter - 1) % (@latch + 2)
|
|
92
|
+
@reload = phase.zero?
|
|
93
|
+
@counter = @reload ? 0xffff : @latch - phase + 1
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def save_state(out)
|
|
97
|
+
out.int(@counter).int(@latch).boolean(@hold).boolean(@reload).boolean(@armed).boolean(@pb7)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def load_state(input)
|
|
101
|
+
@counter = input.int
|
|
102
|
+
@latch = input.int
|
|
103
|
+
@hold = input.boolean?
|
|
104
|
+
@reload = input.boolean?
|
|
105
|
+
@armed = input.boolean?
|
|
106
|
+
@pb7 = input.boolean?
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# What the counter and PB7 don't hold, for comparing the timer at two
|
|
110
|
+
# points.
|
|
111
|
+
def state = [@latch, @armed]
|
|
112
|
+
|
|
113
|
+
# Whether a timeout sets the flag.
|
|
114
|
+
def armed? = @armed
|
|
115
|
+
|
|
116
|
+
# The count, for comparing the timer at two points where it matters.
|
|
117
|
+
def count_state = [@counter, @hold, @reload]
|
|
118
|
+
|
|
119
|
+
private
|
|
120
|
+
|
|
121
|
+
# The counter reloads either way. Armed, PB7 inverts and the flag
|
|
122
|
+
# sets, and one-shot mode disarms. Returns whether the flag sets.
|
|
123
|
+
def timeout(free_run)
|
|
124
|
+
interrupt = @armed
|
|
125
|
+
@reload = true
|
|
126
|
+
@pb7 = !@pb7 if @armed
|
|
127
|
+
@armed &&= free_run
|
|
128
|
+
interrupt
|
|
129
|
+
end
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Chips
|
|
5
|
+
class VIA
|
|
6
|
+
# Timer 2: a one-shot 16-bit counter that decrements on every φ2 cycle,
|
|
7
|
+
# or on every falling edge of PB6 when ACR bit 5 sets it counting pulses.
|
|
8
|
+
# Only its low byte has a latch.
|
|
9
|
+
#
|
|
10
|
+
# Timed, it follows timer 1's one-shot timing: loaded with N it reads N
|
|
11
|
+
# on the cycle after the write, and sets its flag on the cycle it rolls
|
|
12
|
+
# from 0 to $FFFF. Where timer 1 would reload, it rolls on down without
|
|
13
|
+
# further interrupts until the next load. Counting pulses, the flag sets
|
|
14
|
+
# on the pulse that takes it past zero, the N + 1st: the datasheet's
|
|
15
|
+
# "reaches zero" is the same underflow it means in timed mode.
|
|
16
|
+
#
|
|
17
|
+
# While the shift register clocks off it, the low byte also counts as
|
|
18
|
+
# an 8-bit timer of its own: on each low byte underflow it reloads from
|
|
19
|
+
# the latch on the next cycle, which makes the shift clock's half period
|
|
20
|
+
# N + 2 cycles. The borrow still reaches the high byte.
|
|
21
|
+
#
|
|
22
|
+
# ACR bit 5 reaches the count input a cycle after the write, so the
|
|
23
|
+
# counter takes one more step in the mode it leaves.
|
|
24
|
+
class Timer2
|
|
25
|
+
attr_accessor :counter, :latch_low
|
|
26
|
+
|
|
27
|
+
# ACR bit 5, which picks PB6 pulses over φ2.
|
|
28
|
+
attr_writer :count_pulses
|
|
29
|
+
|
|
30
|
+
# Whether the low byte underflowed on the last cycle.
|
|
31
|
+
attr_reader :low_underflowed
|
|
32
|
+
|
|
33
|
+
def initialize
|
|
34
|
+
@counter = 0xffff
|
|
35
|
+
@latch_low = 0xff
|
|
36
|
+
@hold = false
|
|
37
|
+
@low_reload = false
|
|
38
|
+
@armed = false
|
|
39
|
+
@low_underflowed = false
|
|
40
|
+
@count_pulses = @counting_pulses = false
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# The high counter byte write: load the counter with it and the low
|
|
44
|
+
# latch, arm the interrupt and hold the count for a cycle.
|
|
45
|
+
def load(high)
|
|
46
|
+
@counter = (high << 8) | @latch_low
|
|
47
|
+
@hold = true
|
|
48
|
+
@low_reload = false
|
|
49
|
+
@armed = true
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# One φ2 cycle, with whether the shift register clocks off the low
|
|
53
|
+
# byte. Returns true on the cycle that sets the flag.
|
|
54
|
+
def cycle!(sr_service)
|
|
55
|
+
pulses = @counting_pulses
|
|
56
|
+
@counting_pulses = @count_pulses
|
|
57
|
+
return idle! if pulses || @hold
|
|
58
|
+
|
|
59
|
+
@low_underflowed = @counter.nobits?(0xff)
|
|
60
|
+
@hold = @low_reload = sr_service && @low_underflowed
|
|
61
|
+
decrement
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# A falling edge on PB6. Returns true when it sets the flag.
|
|
65
|
+
def pulse! = @counting_pulses && decrement
|
|
66
|
+
|
|
67
|
+
# How many cycles the timer can run without setting its flag, taken
|
|
68
|
+
# without the shift register clocking off it: until an armed timer
|
|
69
|
+
# underflows, and forever for one counting pulses or unarmed, which
|
|
70
|
+
# only rolls on. None while a load or a switch of mode is under way.
|
|
71
|
+
def quiet_cycles
|
|
72
|
+
return 0 if @hold || @counting_pulses != @count_pulses
|
|
73
|
+
return FastForward::QUIET if @counting_pulses || !@armed
|
|
74
|
+
|
|
75
|
+
@counter
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# Runs +cycles+ cycles at once, as many as quiet_cycles allows. The
|
|
79
|
+
# low byte's underflow is set when the last cycle took it from $00.
|
|
80
|
+
def fast_forward(cycles)
|
|
81
|
+
@low_underflowed = false
|
|
82
|
+
return if @counting_pulses
|
|
83
|
+
|
|
84
|
+
@counter = (@counter - cycles) & 0xffff
|
|
85
|
+
@low_underflowed = @counter.allbits?(0xff)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def save_state(out)
|
|
89
|
+
out.int(@counter).int(@latch_low)
|
|
90
|
+
[@hold, @low_reload, @armed, @low_underflowed, @count_pulses, @counting_pulses].each do |flag|
|
|
91
|
+
out.boolean(flag)
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def load_state(input)
|
|
96
|
+
@counter = input.int
|
|
97
|
+
@latch_low = input.int
|
|
98
|
+
@hold = input.boolean?
|
|
99
|
+
@low_reload = input.boolean?
|
|
100
|
+
@armed = input.boolean?
|
|
101
|
+
@low_underflowed = input.boolean?
|
|
102
|
+
@count_pulses = input.boolean?
|
|
103
|
+
@counting_pulses = input.boolean?
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# What the counter and the low byte's underflow don't hold, for
|
|
107
|
+
# comparing the timer at two points.
|
|
108
|
+
def state = [@latch_low, @armed, @hold, @low_reload, @count_pulses, @counting_pulses]
|
|
109
|
+
|
|
110
|
+
# Whether the next underflow sets the flag.
|
|
111
|
+
def armed? = @armed
|
|
112
|
+
|
|
113
|
+
# The count, for comparing the timer at two points where it matters.
|
|
114
|
+
def count_state = [@counter, @low_underflowed]
|
|
115
|
+
|
|
116
|
+
private
|
|
117
|
+
|
|
118
|
+
# A cycle while counting pulses, or held after a load or a low byte
|
|
119
|
+
# underflow: the counter stands still, but the hold still ends, so
|
|
120
|
+
# none carries over into timed mode.
|
|
121
|
+
def idle!
|
|
122
|
+
@counter = (@counter & 0xff00) | @latch_low if @low_reload
|
|
123
|
+
@hold = @low_reload = @low_underflowed = false
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def decrement
|
|
127
|
+
@counter = (@counter - 1) & 0xffff
|
|
128
|
+
interrupt = @armed && @counter == 0xffff
|
|
129
|
+
@armed = false if interrupt
|
|
130
|
+
interrupt
|
|
131
|
+
end
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|