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,232 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Chips
|
|
5
|
+
class CIA
|
|
6
|
+
class TimeOfDay
|
|
7
|
+
# The TOD pin is fed from the AC supply. A CIA passes its region's
|
|
8
|
+
# clock and mains frequency, and these are PAL's.
|
|
9
|
+
CLOCK_HZ = Region::PAL.clock_hz
|
|
10
|
+
MAINS_HZ = Region::PAL.mains_hz
|
|
11
|
+
|
|
12
|
+
FIELDS = %i[tenths seconds minutes hours].freeze
|
|
13
|
+
|
|
14
|
+
def initialize(clock_hz: CLOCK_HZ, mains_hz: MAINS_HZ)
|
|
15
|
+
# The accumulator advances mains_hz per cycle, so a TOD pin pulse has
|
|
16
|
+
# arrived when it reaches clock_hz. Integer math keeps it exact.
|
|
17
|
+
@cycles_per_pulse = clock_hz
|
|
18
|
+
@mains_hz = mains_hz
|
|
19
|
+
@accumulator = 0
|
|
20
|
+
@pulses = 0
|
|
21
|
+
@clock = { tenths: 0x00, seconds: 0x00, minutes: 0x00, hours: 0x01 }
|
|
22
|
+
@alarm = { tenths: 0x00, seconds: 0x00, minutes: 0x00, hours: 0x00 }
|
|
23
|
+
@latch = nil
|
|
24
|
+
@stopped = true
|
|
25
|
+
@alarm_pending = false
|
|
26
|
+
self.fifty_hz = false
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# CRA bit 7 divides the TOD pin by 5 instead of 6. The divider has to
|
|
30
|
+
# match the pin frequency to keep time, so PAL software selects 50 Hz.
|
|
31
|
+
def fifty_hz=(enabled)
|
|
32
|
+
@match = enabled ? 4 : 5
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# The clock and the alarm, field by field in FIELDS order, the latch,
|
|
36
|
+
# and the divider's phase.
|
|
37
|
+
def save_state(out)
|
|
38
|
+
out.int(@accumulator).int(@pulses).int(@match).boolean(@stopped).boolean(@alarm_pending)
|
|
39
|
+
FIELDS.each { |field| out.int(@clock[field]).int(@alarm[field]) }
|
|
40
|
+
out.boolean(!@latch.nil?)
|
|
41
|
+
FIELDS.each { |field| out.int(@latch[field]) } if @latch
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def load_state(input)
|
|
45
|
+
@accumulator = input.int
|
|
46
|
+
@pulses = input.int
|
|
47
|
+
@match = input.int
|
|
48
|
+
@stopped = input.boolean?
|
|
49
|
+
@alarm_pending = input.boolean?
|
|
50
|
+
FIELDS.each do |field|
|
|
51
|
+
@clock[field] = input.int
|
|
52
|
+
@alarm[field] = input.int
|
|
53
|
+
end
|
|
54
|
+
@latch = input.boolean? ? FIELDS.to_h { |field| [field, input.int] } : nil
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# Whether the clock is stopped, or gets no pulses on its pin, with no
|
|
58
|
+
# alarm to raise, so its cycles move only the divider's phase.
|
|
59
|
+
def quiet? = (@stopped || @mains_hz.zero?) && !@alarm_pending
|
|
60
|
+
|
|
61
|
+
# Runs +cycles+ quiet cycles at once.
|
|
62
|
+
def fast_forward(cycles)
|
|
63
|
+
@accumulator = (@accumulator + (cycles * @mains_hz)) % @cycles_per_pulse
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def cycle!
|
|
67
|
+
@accumulator += @mains_hz
|
|
68
|
+
pulse! if @accumulator >= @cycles_per_pulse
|
|
69
|
+
return unless @alarm_pending
|
|
70
|
+
|
|
71
|
+
@alarm_pending = false
|
|
72
|
+
yield if block_given?
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def tenths
|
|
76
|
+
value = (@latch || @clock)[:tenths]
|
|
77
|
+
@latch = nil
|
|
78
|
+
value
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def seconds = (@latch || @clock)[:seconds]
|
|
82
|
+
def minutes = (@latch || @clock)[:minutes]
|
|
83
|
+
|
|
84
|
+
def hours
|
|
85
|
+
@latch ||= @clock.dup
|
|
86
|
+
@latch[:hours]
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
attr_reader :pulses
|
|
90
|
+
|
|
91
|
+
# The clock as a read of the tenths would see it: the latch while the
|
|
92
|
+
# clock is latched. In FIELDS order.
|
|
93
|
+
def latched_fields = FIELDS.map { |field| (@latch || @clock)[field] }
|
|
94
|
+
|
|
95
|
+
# The cycles until the clock next steps a tenth, as VICE counts them.
|
|
96
|
+
def cycles_to_tenth
|
|
97
|
+
to_pulse = (@cycles_per_pulse - @accumulator + @mains_hz - 1) / @mains_hz
|
|
98
|
+
to_pulse + ([@match - @pulses, 0].max * @cycles_per_pulse / @mains_hz)
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# Sets the clock, the alarm and the latch from VICE's fields, in FIELDS
|
|
102
|
+
# order, the latch nil while unlatched.
|
|
103
|
+
def restore_fields(clock, alarm, latch)
|
|
104
|
+
FIELDS.each_with_index do |field, i|
|
|
105
|
+
@clock[field] = clock[i]
|
|
106
|
+
@alarm[field] = alarm[i]
|
|
107
|
+
end
|
|
108
|
+
@latch = latch && FIELDS.each_with_index.to_h { |field, i| [field, latch[i]] }
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
# Sets whether the clock is stopped, the pulses counted towards the
|
|
112
|
+
# next tenth and the cycles until it, placing the divider so the tenth
|
|
113
|
+
# lands then.
|
|
114
|
+
def restore_divider(stopped, pulses, cycles_to_tenth)
|
|
115
|
+
@stopped = stopped
|
|
116
|
+
@pulses = pulses
|
|
117
|
+
to_pulse = cycles_to_tenth - ([@match - pulses, 0].max * @cycles_per_pulse / @mains_hz)
|
|
118
|
+
@accumulator = (@cycles_per_pulse - (to_pulse * @mains_hz)).clamp(0, @cycles_per_pulse - 1)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# The clock and alarm as stored, read without latching the clock.
|
|
122
|
+
def registers
|
|
123
|
+
[@clock[:tenths], @clock[:seconds], @clock[:minutes], @clock[:hours],
|
|
124
|
+
@alarm[:tenths], @alarm[:seconds], @alarm[:minutes], @alarm[:hours],
|
|
125
|
+
@stopped ? 1 : 0, @latch ? 1 : 0]
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def write(field, value, alarm:)
|
|
129
|
+
# The frequency counter is held clear while the clock is stopped, and
|
|
130
|
+
# starts counting again from the write to tenths that restarts it.
|
|
131
|
+
if field == :tenths && !alarm && @stopped
|
|
132
|
+
@pulses = 0
|
|
133
|
+
@stopped = false
|
|
134
|
+
end
|
|
135
|
+
store(field, value & (field == :tenths ? 0x0f : 0x7f), alarm: alarm)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# 12-hour BCD value, bit 7 is the AM/PM flag.
|
|
139
|
+
def write_hours(value, alarm:)
|
|
140
|
+
value &= 0x9f
|
|
141
|
+
# Writing 12 to the hour register flips the AM/PM bit, the same way a
|
|
142
|
+
# carry into 12 does. Writing the alarm hours does not.
|
|
143
|
+
value ^= 0x80 if !alarm && (value & 0x1f) == 0x12
|
|
144
|
+
# Halt the clock when writing hours, so that it doesn't
|
|
145
|
+
# advance mid-update.
|
|
146
|
+
@stopped = true unless alarm
|
|
147
|
+
store(:hours, value, alarm: alarm)
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
private
|
|
151
|
+
|
|
152
|
+
def store(field, value, alarm:)
|
|
153
|
+
target = alarm ? @alarm : @clock
|
|
154
|
+
return if target[field] == value
|
|
155
|
+
|
|
156
|
+
target[field] = value
|
|
157
|
+
@alarm_pending = true if alarm?
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
def pulse!
|
|
161
|
+
@accumulator -= @cycles_per_pulse
|
|
162
|
+
return if @stopped
|
|
163
|
+
|
|
164
|
+
# A three-bit ring counter with six states, compared against the
|
|
165
|
+
# divider on each pin pulse rather than on its way past it.
|
|
166
|
+
if @pulses == @match
|
|
167
|
+
@pulses = 0
|
|
168
|
+
advance
|
|
169
|
+
else
|
|
170
|
+
@pulses += 1
|
|
171
|
+
@pulses = 0 if @pulses > 5
|
|
172
|
+
end
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def advance
|
|
176
|
+
tenths = (@clock[:tenths] + 1) & 0x0f
|
|
177
|
+
@clock[:tenths] = tenths == 10 ? 0 : tenths
|
|
178
|
+
carry_seconds if tenths == 10
|
|
179
|
+
@alarm_pending = true if alarm?
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
def carry_seconds
|
|
183
|
+
return unless advance_pair(:seconds)
|
|
184
|
+
return unless advance_pair(:minutes)
|
|
185
|
+
|
|
186
|
+
advance_hours
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
# Seconds and minutes hold a four-bit low digit that carries at ten into
|
|
190
|
+
# a three-bit high digit that carries out at six. Both are plain binary
|
|
191
|
+
# counters, so out-of-range BCD counts up from where it was written.
|
|
192
|
+
def advance_pair(field)
|
|
193
|
+
low = ((@clock[field] & 0x0f) + 1) & 0x0f
|
|
194
|
+
high = (@clock[field] >> 4) & 0x07
|
|
195
|
+
carry = false
|
|
196
|
+
|
|
197
|
+
if low == 10
|
|
198
|
+
low = 0
|
|
199
|
+
high = (high + 1) & 0x07
|
|
200
|
+
if high == 6
|
|
201
|
+
high = 0
|
|
202
|
+
carry = true
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
@clock[field] = (high << 4) | low
|
|
207
|
+
carry
|
|
208
|
+
end
|
|
209
|
+
|
|
210
|
+
# The hour runs 9 -> 10 and 12 -> 1 by swapping its two digits, and the
|
|
211
|
+
# AM/PM bit flips as it passes through 12.
|
|
212
|
+
def advance_hours
|
|
213
|
+
pm = @clock[:hours] & 0x80
|
|
214
|
+
high = (@clock[:hours] >> 4) & 0x01
|
|
215
|
+
low = @clock[:hours] & 0x0f
|
|
216
|
+
|
|
217
|
+
if (high == 1 && low == 2) || (high.zero? && low == 9)
|
|
218
|
+
low = high
|
|
219
|
+
high ^= 1
|
|
220
|
+
else
|
|
221
|
+
low = (low + 1) & 0x0f
|
|
222
|
+
pm ^= 0x80 if high == 1 && low == 2
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
@clock[:hours] = pm | (high << 4) | low
|
|
226
|
+
end
|
|
227
|
+
|
|
228
|
+
def alarm? = @clock == @alarm
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
end
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Chips
|
|
5
|
+
class CIA
|
|
6
|
+
class Timer
|
|
7
|
+
attr_accessor :counter, :latch
|
|
8
|
+
attr_reader :control, :underflowed
|
|
9
|
+
|
|
10
|
+
def initialize(control)
|
|
11
|
+
@control = control
|
|
12
|
+
@counter = @latch = 0xffff
|
|
13
|
+
@pipe = 0
|
|
14
|
+
@load_delay = 0
|
|
15
|
+
@reload = false
|
|
16
|
+
@underflowed = false
|
|
17
|
+
@oneshot_linger = 0
|
|
18
|
+
@toggle = true
|
|
19
|
+
settle
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# The level this timer drives on its port B pin: a square wave that
|
|
23
|
+
# flips on each underflow, or a single high tick when one happens.
|
|
24
|
+
def output?
|
|
25
|
+
control.out_mode? ? @toggle : @underflowed
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Whether the timer is stopped with nothing in its pipeline, so a
|
|
29
|
+
# cycle changes nothing.
|
|
30
|
+
def idle? = @empty && !started?
|
|
31
|
+
|
|
32
|
+
# Whether the timer counts ø2 in continuous mode with nothing pending
|
|
33
|
+
# but the reload after an underflow, so fast_forward can run it. A
|
|
34
|
+
# latch below 2 is left out.
|
|
35
|
+
def free_running?
|
|
36
|
+
started? && !@control.run_mode? && @control.value.nobits?(0x20) && @latch >= 2 && @pipe == 0b11 &&
|
|
37
|
+
(@load_delay | @oneshot_linger).zero? && (@settled || @reload)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# Runs a free-running timer +cycles+ cycles at once, as cycle! would:
|
|
41
|
+
# an underflow every latch + 1 cycles, each one followed by the
|
|
42
|
+
# reload. Returns the underflows.
|
|
43
|
+
def fast_forward(cycles)
|
|
44
|
+
return 0 if cycles.zero?
|
|
45
|
+
return after_underflow(cycles, 0) unless @settled
|
|
46
|
+
|
|
47
|
+
if cycles < @counter
|
|
48
|
+
@counter -= cycles
|
|
49
|
+
return 0
|
|
50
|
+
end
|
|
51
|
+
after_underflow(cycles - @counter, 1)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def cycle!(feed)
|
|
55
|
+
feed &&= @control.value & 0x01 != 0
|
|
56
|
+
if @settled
|
|
57
|
+
return @counter -= 1 if feed && @counter > 1
|
|
58
|
+
elsif @empty
|
|
59
|
+
enter if feed
|
|
60
|
+
return
|
|
61
|
+
end
|
|
62
|
+
run_tick(feed)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def run_tick(feed)
|
|
66
|
+
@underflowed = false
|
|
67
|
+
@oneshot_linger -= 1 if @oneshot_linger.positive?
|
|
68
|
+
tick(feed)
|
|
69
|
+
settle
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# The counter, the latch and the pipeline between them. The control
|
|
73
|
+
# register is the CIA's to save.
|
|
74
|
+
def save_state(out)
|
|
75
|
+
out.int(@counter).int(@latch).int(@pipe).int(@load_delay).boolean(@reload).boolean(@underflowed)
|
|
76
|
+
out.int(@oneshot_linger).boolean(@toggle).boolean(@settled).boolean(@empty)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def load_state(input)
|
|
80
|
+
@counter = input.int
|
|
81
|
+
@latch = input.int
|
|
82
|
+
@pipe = input.int
|
|
83
|
+
@load_delay = input.int
|
|
84
|
+
@reload = input.boolean?
|
|
85
|
+
@underflowed = input.boolean?
|
|
86
|
+
@oneshot_linger = input.int
|
|
87
|
+
@toggle = input.boolean?
|
|
88
|
+
@settled = input.boolean?
|
|
89
|
+
@empty = input.boolean?
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def write_control(value)
|
|
93
|
+
@toggle = true if value.anybits?(0x01) && !started?
|
|
94
|
+
@oneshot_linger = 2 if control.run_mode? && value.nobits?(0x08)
|
|
95
|
+
control.value = value & ~0x10
|
|
96
|
+
@load_delay = 3 if value.anybits?(0x10)
|
|
97
|
+
settle
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def write_latch_low(value)
|
|
101
|
+
@latch = (@latch & 0xff00) | value
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def write_latch_high(value)
|
|
105
|
+
@latch = (value << 8) | (@latch & 0xff)
|
|
106
|
+
@counter = @latch unless started?
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Whether the timer's PB output toggle is high, and its count pipeline
|
|
110
|
+
# as two bits, the newer stage high.
|
|
111
|
+
attr_reader :toggle, :pipe
|
|
112
|
+
|
|
113
|
+
# Sets the control register without its load strobe, the toggle and
|
|
114
|
+
# the count pipeline, as a VICE snapshot gives them.
|
|
115
|
+
def restore_pipeline(control, toggle, pipe)
|
|
116
|
+
@control.value = control & ~0x10
|
|
117
|
+
@toggle = toggle
|
|
118
|
+
@pipe = pipe
|
|
119
|
+
settle
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
private
|
|
123
|
+
|
|
124
|
+
def started?
|
|
125
|
+
@control.value & 0x01 != 0
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
# Where fast_forward lands +cycles+ after an underflow, with
|
|
129
|
+
# +underflows+ underflows counted so far.
|
|
130
|
+
def after_underflow(cycles, underflows)
|
|
131
|
+
periods, rest = cycles.divmod(@latch + 1)
|
|
132
|
+
underflows += periods
|
|
133
|
+
@toggle = !@toggle if underflows.odd?
|
|
134
|
+
@underflowed = rest.zero?
|
|
135
|
+
@reload = rest.zero?
|
|
136
|
+
@counter = @latch - (rest.zero? ? 0 : rest - 1)
|
|
137
|
+
settle
|
|
138
|
+
underflows
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def enter
|
|
142
|
+
@pipe = 0b10
|
|
143
|
+
@empty = false
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
# With no load, reload or one-shot linger pending, a full pipe only
|
|
147
|
+
# counts and an empty one only waits to be fed.
|
|
148
|
+
def settle
|
|
149
|
+
quiet = (@load_delay | @oneshot_linger).zero? && !@reload
|
|
150
|
+
@settled = quiet && @pipe == 0b11
|
|
151
|
+
@empty = quiet && @pipe.zero?
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def tick(feed)
|
|
155
|
+
counting = @pipe.anybits?(0b01)
|
|
156
|
+
@pipe = (@pipe >> 1) | (feed ? 0b10 : 0)
|
|
157
|
+
loading = @reload || @load_delay == 1
|
|
158
|
+
@reload = false
|
|
159
|
+
|
|
160
|
+
if loading
|
|
161
|
+
reload
|
|
162
|
+
elsif premature_underflow?
|
|
163
|
+
underflow
|
|
164
|
+
elsif counting
|
|
165
|
+
count
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
forced_load
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def forced_load
|
|
172
|
+
return unless @load_delay.positive?
|
|
173
|
+
|
|
174
|
+
@load_delay -= 1
|
|
175
|
+
@counter = @latch if @load_delay == 1
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
# the final pipeline stage, before any pending load lands
|
|
179
|
+
def premature_underflow?
|
|
180
|
+
@counter.zero? && @pipe.anybits?(0b01) && started?
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
# A load consumes its tick, so the counter never decrements on it
|
|
184
|
+
def reload
|
|
185
|
+
@counter = @latch
|
|
186
|
+
# A zero latch underflows again on the reload tick while running
|
|
187
|
+
underflow if @counter.zero? && started? && @pipe.anybits?(0b01)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def count
|
|
191
|
+
@counter -= 1 if @counter.positive?
|
|
192
|
+
underflow if @counter.zero? && @pipe.anybits?(0b01)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def underflow
|
|
196
|
+
@underflowed = true
|
|
197
|
+
@reload = true
|
|
198
|
+
@counter = @latch
|
|
199
|
+
@toggle = !@toggle
|
|
200
|
+
return unless control.run_mode? || @oneshot_linger.positive?
|
|
201
|
+
|
|
202
|
+
control.start = false
|
|
203
|
+
@pipe = 0
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
end
|
|
208
|
+
end
|