badline 0.12.1 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +66 -1
- data/CLAUDE.md +86 -38
- data/CONTRIBUTING.md +4 -3
- data/README.md +9 -6
- data/doc/library.md +9 -9
- data/doc/media.md +2 -1
- data/doc/pinned-behaviour.md +134 -105
- data/doc/snapshot-format.md +1047 -0
- data/doc/snapshots.md +73 -43
- data/lib/badline/audio/bare_player.rb +53 -20
- data/lib/badline/audio/cli.rb +6 -6
- data/lib/badline/audio/jukebox.rb +2 -2
- data/lib/badline/audio/machine_player.rb +16 -10
- data/lib/badline/{media → audio}/queue.rb +1 -1
- data/lib/badline/audio/queued_tune.rb +6 -6
- data/lib/badline/audio/renderer.rb +33 -22
- data/lib/badline/audio/stereo.rb +1 -1
- data/lib/badline/c128/banks.rb +6 -3
- data/lib/badline/c128/bus/keyed_state.rb +45 -0
- data/lib/badline/c128/bus.rb +35 -20
- data/lib/badline/c128/color_lines.rb +2 -2
- data/lib/badline/c128/cpu.rb +1 -1
- data/lib/badline/c128/drives.rb +14 -34
- data/lib/badline/c128/fast_serial.rb +5 -5
- data/lib/badline/c128/keyed_modules.rb +117 -0
- data/lib/badline/c128/keyed_state.rb +91 -0
- data/lib/badline/c128/keys.rb +9 -0
- data/lib/badline/c128/mmu.rb +9 -8
- data/lib/badline/c128/mmu_pages.rb +21 -1
- data/lib/badline/c128/modes.rb +21 -11
- data/lib/badline/c128/z80.rb +2 -2
- data/lib/badline/c128/z80_turns.rb +1 -1
- data/lib/badline/c128.rb +21 -16
- data/lib/badline/c64/attachments.rb +42 -0
- data/lib/badline/c64/banked_ram/banking.rb +32 -0
- data/lib/badline/c64/banked_ram/plus256k.rb +64 -0
- data/lib/badline/c64/banked_ram/plus60k.rb +47 -0
- data/lib/badline/c64/banked_ram/unexpanded.rb +30 -0
- data/lib/badline/c64/banked_ram.rb +23 -0
- data/lib/badline/c64/bus/debug_register.rb +32 -0
- data/lib/badline/c64/bus/extra_sids.rb +32 -0
- data/lib/badline/c64/bus/fittings.rb +40 -0
- data/lib/badline/c64/bus/keyed_state.rb +41 -0
- data/lib/badline/c64/bus/pla.rb +149 -0
- data/lib/badline/c64/bus/roms.rb +41 -0
- data/lib/badline/c64/bus/sid_slots.rb +44 -0
- data/lib/badline/c64/bus.rb +219 -0
- data/lib/badline/c64/cartridge/action_replay.rb +115 -0
- data/lib/badline/c64/cartridge/atomic_power.rb +26 -0
- data/lib/badline/c64/cartridge/bank.rb +83 -0
- data/lib/badline/c64/cartridge/comal80.rb +52 -0
- data/lib/badline/c64/cartridge/dinamic.rb +36 -0
- data/lib/badline/c64/cartridge/easy_flash.rb +132 -0
- data/lib/badline/c64/cartridge/epyx_fastload.rb +73 -0
- data/lib/badline/c64/cartridge/final_cartridge3.rb +79 -0
- data/lib/badline/c64/cartridge/flash.rb +279 -0
- data/lib/badline/c64/cartridge/freezer.rb +35 -0
- data/lib/badline/c64/cartridge/fun_play.rb +40 -0
- data/lib/badline/c64/cartridge/g_mod2.rb +64 -0
- data/lib/badline/c64/cartridge/game_system.rb +42 -0
- data/lib/badline/c64/cartridge/geo_ram.rb +65 -0
- data/lib/badline/c64/cartridge/kcs_power.rb +69 -0
- data/lib/badline/c64/cartridge/keyed_state.rb +393 -0
- data/lib/badline/c64/cartridge/mach5.rb +34 -0
- data/lib/badline/c64/cartridge/magic_desk.rb +32 -0
- data/lib/badline/c64/cartridge/ocean.rb +37 -0
- data/lib/badline/c64/cartridge/pagefox.rb +60 -0
- data/lib/badline/c64/cartridge/retro_replay.rb +278 -0
- data/lib/badline/c64/cartridge/rex_utility.rb +31 -0
- data/lib/badline/c64/cartridge/rgcd.rb +50 -0
- data/lib/badline/c64/cartridge/simons_basic.rb +37 -0
- data/lib/badline/c64/cartridge/standard.rb +17 -0
- data/lib/badline/c64/cartridge/super_games.rb +40 -0
- data/lib/badline/c64/cartridge/westermann.rb +32 -0
- data/lib/badline/c64/cartridge/zaxxon.rb +52 -0
- data/lib/badline/c64/cartridge.rb +232 -0
- data/lib/badline/c64/color_memory.rb +27 -0
- data/lib/badline/{computer → c64}/common.rb +2 -2
- data/lib/badline/{computer → c64}/kernal_traps.rb +39 -36
- data/lib/badline/c64/keyed_modules.rb +111 -0
- data/lib/badline/c64/keyed_state.rb +68 -0
- data/lib/badline/c64/reu/dma.rb +271 -0
- data/lib/badline/c64/reu/keyed_state.rb +140 -0
- data/lib/badline/c64/reu/ram.rb +94 -0
- data/lib/badline/c64/reu/trigger.rb +34 -0
- data/lib/badline/c64/reu.rb +289 -0
- data/lib/badline/c64/true_drives.rb +120 -0
- data/lib/badline/{computer.rb → c64.rb} +24 -15
- data/lib/badline/chips/cia/fast_forward.rb +62 -0
- data/lib/badline/chips/cia/interrupt_register.rb +128 -0
- data/lib/badline/chips/cia/keyed_parts.rb +213 -0
- data/lib/badline/chips/cia/serial.rb +246 -0
- data/lib/badline/chips/cia/time_of_day.rb +210 -0
- data/lib/badline/chips/cia/timer.rb +188 -0
- data/lib/badline/chips/cia.rb +281 -0
- data/lib/badline/chips/cpu/addressing.rb +133 -0
- data/lib/badline/chips/cpu/boundary.rb +56 -0
- data/lib/badline/chips/cpu/core.rb +183 -0
- data/lib/badline/chips/cpu/instruction.rb +338 -0
- data/lib/badline/chips/cpu/instruction_set/arithmetic.rb +118 -0
- data/lib/badline/chips/cpu/instruction_set/bitwise.rb +130 -0
- data/lib/badline/chips/cpu/instruction_set/branch.rb +83 -0
- data/lib/badline/chips/cpu/instruction_set/flag.rb +67 -0
- data/lib/badline/chips/cpu/instruction_set/illegal.rb +274 -0
- data/lib/badline/chips/cpu/instruction_set/inc_dec.rb +73 -0
- data/lib/badline/chips/cpu/instruction_set/stack.rb +56 -0
- data/lib/badline/chips/cpu/instruction_set/transfer.rb +141 -0
- data/lib/badline/chips/cpu/instruction_set.rb +59 -0
- data/lib/badline/chips/cpu/interrupts.rb +108 -0
- data/lib/badline/chips/cpu/keyed_state.rb +177 -0
- data/lib/badline/chips/cpu/microcode.rb +195 -0
- data/lib/badline/chips/cpu/operations.rb +90 -0
- data/lib/badline/chips/cpu/port.rb +133 -0
- data/lib/badline/chips/cpu/stack_operations.rb +84 -0
- data/lib/badline/chips/cpu/traps.rb +23 -0
- data/lib/badline/chips/cpu.rb +17 -0
- data/lib/badline/chips/sid/catch_up.rb +122 -0
- data/lib/badline/chips/sid/decimator.rb +68 -0
- data/lib/badline/chips/sid/envelope.rb +236 -0
- data/lib/badline/chips/sid/filter.rb +227 -0
- data/lib/badline/chips/sid/keyed_parts.rb +286 -0
- data/lib/badline/chips/sid/voice.rb +69 -0
- data/lib/badline/chips/sid/waveform/combined.rb +128 -0
- data/lib/badline/chips/sid/waveform/fast_forward.rb +107 -0
- data/lib/badline/chips/sid/waveform/noise_writeback.rb +124 -0
- data/lib/badline/chips/sid/waveform.rb +305 -0
- data/lib/badline/chips/sid.rb +264 -0
- data/lib/badline/chips/ted/beam.rb +119 -0
- data/lib/badline/chips/ted/timers.rb +66 -0
- data/lib/badline/chips/ted.rb +143 -0
- data/lib/badline/chips/tia.rb +49 -0
- data/lib/badline/chips/vdc/keyed_parts.rb +105 -0
- data/lib/badline/{c128 → chips}/vdc/memory.rb +1 -1
- data/lib/badline/{c128 → chips}/vdc/painter.rb +1 -13
- data/lib/badline/{c128 → chips}/vdc/raster.rb +1 -17
- data/lib/badline/{c128 → chips}/vdc/window.rb +1 -10
- data/lib/badline/{c128 → chips}/vdc.rb +6 -31
- data/lib/badline/chips/via/control_lines.rb +109 -0
- data/lib/badline/chips/via/fast_forward.rb +55 -0
- data/lib/badline/chips/via/interrupt_register.rb +60 -0
- data/lib/badline/chips/via/keyed_parts.rb +163 -0
- data/lib/badline/chips/via/shift_register.rb +168 -0
- data/lib/badline/chips/via/timer1.rb +120 -0
- data/lib/badline/chips/via/timer2.rb +117 -0
- data/lib/badline/chips/via.rb +267 -0
- data/lib/badline/chips/vic/bank.rb +135 -0
- data/lib/badline/chips/vic/border_mask.rb +78 -0
- data/lib/badline/chips/vic/collisions.rb +106 -0
- data/lib/badline/chips/vic/color_patches.rb +38 -0
- data/lib/badline/chips/vic/display_state.rb +168 -0
- data/lib/badline/chips/vic/graphics_mode.rb +166 -0
- data/lib/badline/chips/vic/graphics_shifter.rb +183 -0
- data/lib/badline/chips/vic/keyed_parts.rb +228 -0
- data/lib/badline/chips/vic/keyed_sprites.rb +225 -0
- data/lib/badline/chips/vic/keyed_state.rb +102 -0
- data/lib/badline/chips/vic/register_log.rb +65 -0
- data/lib/badline/chips/vic/registers.rb +188 -0
- data/lib/badline/chips/vic/sequencer.rb +275 -0
- data/lib/badline/chips/vic/sequencer_output.rb +118 -0
- data/lib/badline/chips/vic/sprite/internal_bus.rb +59 -0
- data/lib/badline/chips/vic/sprite/shifter.rb +148 -0
- data/lib/badline/chips/vic/sprite/timing.rb +58 -0
- data/lib/badline/chips/vic/sprite.rb +337 -0
- data/lib/badline/chips/vic/sprites.rb +281 -0
- data/lib/badline/chips/vic.rb +787 -0
- data/lib/badline/chips/vic_i/keyed_parts.rb +142 -0
- data/lib/badline/{vic20/vic → chips/vic_i}/painter.rb +2 -30
- data/lib/badline/chips/vic_i/sound/output.rb +85 -0
- data/lib/badline/chips/vic_i/sound.rb +227 -0
- data/lib/badline/{vic20/vic → chips/vic_i}/text_window.rb +2 -2
- data/lib/badline/{vic20/vic.rb → chips/vic_i.rb} +6 -6
- data/lib/badline/chips/z80/arithmetic.rb +119 -0
- data/lib/badline/chips/z80/bit_page.rb +57 -0
- data/lib/badline/chips/z80/block_io.rb +60 -0
- data/lib/badline/chips/z80/block_transfers.rb +61 -0
- data/lib/badline/chips/z80/bus_cycles.rb +113 -0
- data/lib/badline/chips/z80/core.rb +115 -0
- data/lib/badline/chips/z80/exchanges.rb +52 -0
- data/lib/badline/chips/z80/extended_page.rb +91 -0
- data/lib/badline/chips/z80/flags.rb +39 -0
- data/lib/badline/chips/z80/interrupt_acceptance.rb +48 -0
- data/lib/badline/chips/z80/jumps.rb +84 -0
- data/lib/badline/chips/z80/keyed_state.rb +73 -0
- data/lib/badline/chips/z80/loads.rb +100 -0
- data/lib/badline/chips/z80/main_page.rb +136 -0
- data/lib/badline/chips/z80/registers.rb +122 -0
- data/lib/badline/chips/z80/shifts.rb +66 -0
- data/lib/badline/chips/z80.rb +13 -0
- data/lib/badline/chips.rb +10 -0
- data/lib/badline/core.rb +13 -32
- data/lib/badline/drives/datasette/keyed_state.rb +38 -0
- data/lib/badline/drives/datasette.rb +173 -0
- data/lib/badline/drives/engine/core.rb +152 -0
- data/lib/badline/drives/engine/fast_serial.rb +75 -0
- data/lib/badline/drives/engine/idle.rb +127 -0
- data/lib/badline/drives/engine/idle_cpu.rb +30 -0
- data/lib/badline/drives/engine/orbit.rb +81 -0
- data/lib/badline/drives/engine/serial_lines.rb +72 -0
- data/lib/badline/drives/engine/sleep.rb +114 -0
- data/lib/badline/drives/engine/vias.rb +86 -0
- data/lib/badline/drives/engine/watch.rb +152 -0
- data/lib/badline/drives/engine.rb +11 -0
- data/lib/badline/drives/model1541/bus.rb +75 -0
- data/lib/badline/drives/model1541/byte_ready.rb +50 -0
- data/lib/badline/drives/model1541/cpu.rb +13 -0
- data/lib/badline/drives/model1541/disk.rb +318 -0
- data/lib/badline/drives/model1541/disk_via.rb +38 -0
- data/lib/badline/drives/model1541/gcr.rb +59 -0
- data/lib/badline/drives/model1541/keyed_state.rb +251 -0
- data/lib/badline/drives/model1541/mechanism.rb +313 -0
- data/lib/badline/drives/model1541/rotation.rb +123 -0
- data/lib/badline/drives/model1541/sector_reader.rb +78 -0
- data/lib/badline/drives/model1541/serial_port.rb +20 -0
- data/lib/badline/drives/model1541/track.rb +100 -0
- data/lib/badline/drives/model1541.rb +80 -0
- data/lib/badline/drives/model1571/bus.rb +100 -0
- data/lib/badline/drives/model1571/cpu.rb +13 -0
- data/lib/badline/drives/model1571/keyed_state.rb +108 -0
- data/lib/badline/drives/model1571/serial_port.rb +39 -0
- data/lib/badline/drives/model1571/serial_via.rb +27 -0
- data/lib/badline/drives/model1571/wd1770.rb +108 -0
- data/lib/badline/drives/model1571.rb +141 -0
- data/lib/badline/drives/model1581/bus.rb +126 -0
- data/lib/badline/drives/model1581/cpu.rb +13 -0
- data/lib/badline/drives/model1581/disk.rb +133 -0
- data/lib/badline/drives/model1581/keyed_state.rb +280 -0
- data/lib/badline/drives/model1581/mechanism.rb +98 -0
- data/lib/badline/drives/model1581/serial_port.rb +54 -0
- data/lib/badline/drives/model1581/slot.rb +61 -0
- data/lib/badline/drives/model1581/track.rb +102 -0
- data/lib/badline/drives/model1581/track_bytes.rb +77 -0
- data/lib/badline/drives/model1581/wd1772/registers.rb +91 -0
- data/lib/badline/drives/model1581/wd1772/sector_writes.rb +75 -0
- data/lib/badline/drives/model1581/wd1772/sectors.rb +152 -0
- data/lib/badline/drives/model1581/wd1772/stepping.rb +111 -0
- data/lib/badline/drives/model1581/wd1772/tracks.rb +127 -0
- data/lib/badline/drives/model1581/wd1772/turn.rb +75 -0
- data/lib/badline/drives/model1581/wd1772.rb +216 -0
- data/lib/badline/drives/model1581.rb +206 -0
- data/lib/badline/drives/serial_bus.rb +161 -0
- data/lib/badline/drives.rb +8 -0
- data/lib/badline/frontend/app.rb +3 -3
- data/lib/badline/frontend/boot.rb +4 -4
- data/lib/badline/frontend/controls.rb +19 -3
- data/lib/badline/frontend/drive_led.rb +44 -21
- data/lib/badline/frontend/machine_window.rb +3 -1
- data/lib/badline/frontend/menu/menu_dialogs.rb +2 -2
- data/lib/badline/frontend/player/filter_view.rb +1 -1
- data/lib/badline/frontend/player/player_controller.rb +2 -2
- data/lib/badline/frontend/player/player_screen.rb +1 -0
- data/lib/badline/frontend/player/theme.rb +7 -7
- data/lib/badline/frontend/snapshots.rb +12 -1
- data/lib/badline/frontend/timeline.rb +30 -12
- data/lib/badline/input/control_ports.rb +78 -0
- data/lib/badline/input/joystick.rb +27 -0
- data/lib/badline/input/keyboard.rb +114 -0
- data/lib/badline/input/matrix_typist.rb +98 -0
- data/lib/badline/input.rb +4 -0
- data/lib/badline/kernal_trap/chrout.rb +45 -0
- data/lib/badline/kernal_trap/{drive → dos}/block_commands.rb +1 -1
- data/lib/badline/kernal_trap/dos/channel.rb +156 -0
- data/lib/badline/kernal_trap/{drive → dos}/channels.rb +1 -26
- data/lib/badline/kernal_trap/{drive → dos}/memory.rb +1 -10
- data/lib/badline/kernal_trap/{drive → dos}/parameters.rb +1 -1
- data/lib/badline/kernal_trap/{drive → dos}/status.rb +1 -9
- data/lib/badline/kernal_trap/{drive → dos}/write_file.rb +1 -19
- data/lib/badline/kernal_trap/{drive → dos}/writes.rb +1 -1
- data/lib/badline/kernal_trap/{drive.rb → dos.rb} +9 -27
- data/lib/badline/kernal_trap/file_routine.rb +4 -4
- data/lib/badline/kernal_trap/keyed_state.rb +150 -0
- data/lib/badline/kernal_trap/layout.rb +75 -11
- data/lib/badline/kernal_trap/load.rb +19 -21
- data/lib/badline/kernal_trap/routine.rb +12 -0
- data/lib/badline/kernal_trap/save.rb +12 -22
- data/lib/badline/kernal_trap/serial.rb +8 -24
- data/lib/badline/kernal_trap.rb +3 -2
- data/lib/badline/machine/clocking.rb +1 -1
- data/lib/badline/machine/keyboard_buffer.rb +49 -0
- data/lib/badline/machine/settling.rb +29 -0
- data/lib/badline/machine.rb +10 -7
- data/lib/badline/media/boot_disk.rb +14 -2
- data/lib/badline/media/extensions.rb +10 -0
- data/lib/badline/media/true_drive.rb +1 -1
- data/lib/badline/media/tune.rb +2 -2
- data/lib/badline/media.rb +3 -3
- data/lib/badline/memory.rb +3 -6
- data/lib/badline/model.rb +1 -1
- data/lib/badline/options/family.rb +5 -2
- data/lib/badline/options/help.rb +42 -16
- data/lib/badline/options/table.rb +2 -0
- data/lib/badline/options/validation.rb +2 -0
- data/lib/badline/options.rb +6 -1
- data/lib/badline/plus4/acia.rb +45 -0
- data/lib/badline/plus4/bus.rb +312 -0
- data/lib/badline/plus4/cpu.rb +10 -0
- data/lib/badline/plus4/cpu_port.rb +93 -0
- data/lib/badline/plus4/keyboard_port.rb +51 -0
- data/lib/badline/plus4/model.rb +38 -0
- data/lib/badline/plus4/user_port.rb +31 -0
- data/lib/badline/plus4.rb +164 -0
- data/lib/badline/roms/README +44 -6
- data/lib/badline/roms/plus4/basic.rom +0 -0
- data/lib/badline/roms/plus4/function-high.rom +0 -0
- data/lib/badline/roms/plus4/function-low.rom +0 -0
- data/lib/badline/roms/plus4/kernal-ntsc.rom +0 -0
- data/lib/badline/roms/plus4/kernal-pal.rom +0 -0
- data/lib/badline/sdl.rb +1 -0
- data/lib/badline/{storage/sid_file.rb → sid_tune/file.rb} +3 -3
- data/lib/badline/{storage → sid_tune}/hvsc.rb +7 -7
- data/lib/badline/{storage → sid_tune}/song_lengths.rb +2 -2
- data/lib/badline/{storage → sid_tune}/stil/credit.rb +1 -1
- data/lib/badline/{storage → sid_tune}/stil.rb +3 -3
- data/lib/badline/sid_tune.rb +6 -0
- data/lib/badline/snapshot/c128_setup.rb +32 -0
- data/lib/badline/snapshot/c64_setup.rb +83 -0
- data/lib/badline/snapshot/container.rb +4 -0
- data/lib/badline/snapshot/field_doc/markdown.rb +112 -0
- data/lib/badline/snapshot/field_doc.rb +109 -0
- data/lib/badline/snapshot/image.rb +132 -46
- data/lib/badline/snapshot/keyed/cursor.rb +40 -0
- data/lib/badline/snapshot/keyed/modules.rb +66 -0
- data/lib/badline/snapshot/keyed/reader.rb +188 -0
- data/lib/badline/snapshot/keyed/recorder.rb +88 -0
- data/lib/badline/snapshot/keyed/report.rb +26 -0
- data/lib/badline/snapshot/keyed/writer.rb +55 -0
- data/lib/badline/snapshot/keyed.rb +64 -0
- data/lib/badline/snapshot/machine_state.rb +17 -64
- data/lib/badline/snapshot/storage_setup.rb +63 -0
- data/lib/badline/snapshot/vic20_setup.rb +28 -0
- data/lib/badline/snapshot/vice/c64_mem.rb +1 -1
- data/lib/badline/snapshot/vice/restore.rb +1 -1
- data/lib/badline/snapshot/vice/reu1764.rb +3 -3
- data/lib/badline/snapshot/vice/reu_fields.rb +40 -0
- data/lib/badline/snapshot/vice.rb +13 -35
- data/lib/badline/snapshot.rb +44 -22
- data/lib/badline/storage/crt_file.rb +3 -1
- data/lib/badline/storage/d64_image.rb +0 -2
- data/lib/badline/storage/d71_image.rb +0 -2
- data/lib/badline/storage/d81_image.rb +0 -2
- data/lib/badline/storage/disk_image.rb +3 -6
- data/lib/badline/storage/g64_image.rb +10 -5
- data/lib/badline/storage/host_directory.rb +0 -5
- data/lib/badline/storage/t64.rb +2 -8
- data/lib/badline/storage/tap.rb +43 -15
- data/lib/badline/storage/unavailable.rb +1 -1
- data/lib/badline/storage.rb +0 -37
- data/lib/badline/support/c128_checkpoint.rb +39 -0
- data/lib/badline/support/checkpoint.rb +108 -0
- data/lib/badline/support/vic20_checkpoint.rb +38 -0
- data/lib/badline/support.rb +5 -0
- data/lib/badline/version.rb +1 -1
- data/lib/badline/vic20/attachments.rb +8 -5
- data/lib/badline/vic20/bus/keyed_state.rb +52 -0
- data/lib/badline/vic20/bus.rb +2 -25
- data/lib/badline/vic20/cpu.rb +1 -1
- data/lib/badline/vic20/keyed_modules.rb +73 -0
- data/lib/badline/vic20/keyed_state.rb +45 -0
- data/lib/badline/vic20/port_wiring.rb +4 -4
- data/lib/badline/vic20/user_via_ports.rb +2 -2
- data/lib/badline/vic20.rb +22 -17
- data/lib/badline.rb +1 -0
- metadata +271 -228
- data/lib/badline/address_bus/extra_sids.rb +0 -30
- data/lib/badline/address_bus/fittings.rb +0 -38
- data/lib/badline/address_bus/pla.rb +0 -147
- data/lib/badline/address_bus/roms.rb +0 -39
- data/lib/badline/address_bus/saved_state.rb +0 -66
- data/lib/badline/address_bus/sid_slots.rb +0 -42
- data/lib/badline/address_bus.rb +0 -216
- data/lib/badline/c128/bus_state.rb +0 -53
- data/lib/badline/c128/saved_state.rb +0 -143
- data/lib/badline/cartridge/action_replay.rb +0 -126
- data/lib/badline/cartridge/atomic_power.rb +0 -24
- data/lib/badline/cartridge/bank.rb +0 -81
- data/lib/badline/cartridge/comal80.rb +0 -50
- data/lib/badline/cartridge/dinamic.rb +0 -34
- data/lib/badline/cartridge/easy_flash.rb +0 -145
- data/lib/badline/cartridge/epyx_fastload.rb +0 -79
- data/lib/badline/cartridge/final_cartridge3.rb +0 -89
- data/lib/badline/cartridge/flash.rb +0 -306
- data/lib/badline/cartridge/freezer.rb +0 -33
- data/lib/badline/cartridge/fun_play.rb +0 -38
- data/lib/badline/cartridge/g_mod2.rb +0 -74
- data/lib/badline/cartridge/game_system.rb +0 -40
- data/lib/badline/cartridge/geo_ram.rb +0 -79
- data/lib/badline/cartridge/kcs_power.rb +0 -75
- data/lib/badline/cartridge/mach5.rb +0 -32
- data/lib/badline/cartridge/magic_desk.rb +0 -30
- data/lib/badline/cartridge/ocean.rb +0 -35
- data/lib/badline/cartridge/pagefox.rb +0 -68
- data/lib/badline/cartridge/retro_replay.rb +0 -320
- data/lib/badline/cartridge/rex_utility.rb +0 -29
- data/lib/badline/cartridge/rgcd.rb +0 -58
- data/lib/badline/cartridge/simons_basic.rb +0 -35
- data/lib/badline/cartridge/standard.rb +0 -15
- data/lib/badline/cartridge/super_games.rb +0 -48
- data/lib/badline/cartridge/westermann.rb +0 -30
- data/lib/badline/cartridge/zaxxon.rb +0 -66
- data/lib/badline/cartridge.rb +0 -303
- data/lib/badline/checkpoint.rb +0 -98
- data/lib/badline/chrout_trap.rb +0 -43
- data/lib/badline/cia/fast_forward.rb +0 -60
- data/lib/badline/cia/interrupt_register.rb +0 -143
- data/lib/badline/cia/serial.rb +0 -275
- data/lib/badline/cia/state.rb +0 -47
- data/lib/badline/cia/timer.rb +0 -206
- data/lib/badline/cia.rb +0 -279
- data/lib/badline/color_memory.rb +0 -25
- data/lib/badline/computer/attachments.rb +0 -88
- data/lib/badline/computer/saved_state.rb +0 -117
- data/lib/badline/computer/true_drives.rb +0 -69
- data/lib/badline/control_ports.rb +0 -76
- data/lib/badline/cpu/addressing.rb +0 -131
- data/lib/badline/cpu/boundary.rb +0 -54
- data/lib/badline/cpu/core.rb +0 -165
- data/lib/badline/cpu/microcode.rb +0 -177
- data/lib/badline/cpu/operations.rb +0 -88
- data/lib/badline/cpu/saved_state.rb +0 -115
- data/lib/badline/cpu/stack_operations.rb +0 -82
- data/lib/badline/cpu.rb +0 -10
- data/lib/badline/cpu_port.rb +0 -112
- data/lib/badline/datasette.rb +0 -161
- data/lib/badline/debug_register.rb +0 -28
- data/lib/badline/drive/core.rb +0 -147
- data/lib/badline/drive/fast_serial.rb +0 -73
- data/lib/badline/drive/idle.rb +0 -125
- data/lib/badline/drive/idle_cpu.rb +0 -28
- data/lib/badline/drive/orbit.rb +0 -79
- data/lib/badline/drive/serial_lines.rb +0 -73
- data/lib/badline/drive/sleep.rb +0 -112
- data/lib/badline/drive/vias.rb +0 -84
- data/lib/badline/drive/watch.rb +0 -150
- data/lib/badline/drive.rb +0 -11
- data/lib/badline/drive1541/bus.rb +0 -86
- data/lib/badline/drive1541/byte_ready.rb +0 -48
- data/lib/badline/drive1541/cpu.rb +0 -11
- data/lib/badline/drive1541/disk.rb +0 -315
- data/lib/badline/drive1541/disk_state.rb +0 -86
- data/lib/badline/drive1541/disk_via.rb +0 -36
- data/lib/badline/drive1541/gcr.rb +0 -57
- data/lib/badline/drive1541/mechanism.rb +0 -313
- data/lib/badline/drive1541/mechanism_state.rb +0 -68
- data/lib/badline/drive1541/rotation.rb +0 -121
- data/lib/badline/drive1541/sector_reader.rb +0 -76
- data/lib/badline/drive1541/serial_port.rb +0 -18
- data/lib/badline/drive1541/track.rb +0 -98
- data/lib/badline/drive1541.rb +0 -111
- data/lib/badline/drive1571/bus.rb +0 -111
- data/lib/badline/drive1571/cpu.rb +0 -11
- data/lib/badline/drive1571/serial_port.rb +0 -37
- data/lib/badline/drive1571/serial_via.rb +0 -25
- data/lib/badline/drive1571/wd1770.rb +0 -120
- data/lib/badline/drive1571.rb +0 -175
- data/lib/badline/drive1581/bus.rb +0 -137
- data/lib/badline/drive1581/cpu.rb +0 -11
- data/lib/badline/drive1581/disk.rb +0 -135
- data/lib/badline/drive1581/disk_state.rb +0 -87
- data/lib/badline/drive1581/mechanism.rb +0 -117
- data/lib/badline/drive1581/serial_port.rb +0 -52
- data/lib/badline/drive1581/slot.rb +0 -78
- data/lib/badline/drive1581/track.rb +0 -100
- data/lib/badline/drive1581/track_bytes.rb +0 -75
- data/lib/badline/drive1581/wd1772/registers.rb +0 -89
- data/lib/badline/drive1581/wd1772/sector_writes.rb +0 -73
- data/lib/badline/drive1581/wd1772/sectors.rb +0 -150
- data/lib/badline/drive1581/wd1772/state.rb +0 -66
- data/lib/badline/drive1581/wd1772/stepping.rb +0 -109
- data/lib/badline/drive1581/wd1772/tracks.rb +0 -125
- data/lib/badline/drive1581/wd1772/turn.rb +0 -73
- data/lib/badline/drive1581/wd1772.rb +0 -216
- data/lib/badline/drive1581.rb +0 -233
- data/lib/badline/iec_bus.rb +0 -159
- data/lib/badline/instruction.rb +0 -334
- data/lib/badline/instruction_set/arithmetic.rb +0 -114
- data/lib/badline/instruction_set/bitwise.rb +0 -126
- data/lib/badline/instruction_set/branch.rb +0 -79
- data/lib/badline/instruction_set/flag.rb +0 -63
- data/lib/badline/instruction_set/illegal.rb +0 -270
- data/lib/badline/instruction_set/inc_dec.rb +0 -69
- data/lib/badline/instruction_set/stack.rb +0 -52
- data/lib/badline/instruction_set/transfer.rb +0 -137
- data/lib/badline/instruction_set.rb +0 -55
- data/lib/badline/interrupts.rb +0 -104
- data/lib/badline/joystick.rb +0 -25
- data/lib/badline/kernal_trap/channel.rb +0 -181
- data/lib/badline/keyboard.rb +0 -112
- data/lib/badline/keyboard_buffer.rb +0 -33
- data/lib/badline/ram_expansion/banking.rb +0 -30
- data/lib/badline/ram_expansion/plus256k.rb +0 -54
- data/lib/badline/ram_expansion/plus60k.rb +0 -43
- data/lib/badline/ram_expansion/unexpanded.rb +0 -28
- data/lib/badline/ram_expansion.rb +0 -21
- data/lib/badline/reu/dma/saved_state.rb +0 -50
- data/lib/badline/reu/dma.rb +0 -273
- data/lib/badline/reu/ram.rb +0 -107
- data/lib/badline/reu/saved_state.rb +0 -80
- data/lib/badline/reu/trigger.rb +0 -32
- data/lib/badline/reu.rb +0 -289
- data/lib/badline/sid/catch_up.rb +0 -120
- data/lib/badline/sid/decimator.rb +0 -64
- data/lib/badline/sid/envelope/state.rb +0 -68
- data/lib/badline/sid/envelope.rb +0 -239
- data/lib/badline/sid/filter.rb +0 -263
- data/lib/badline/sid/voice.rb +0 -77
- data/lib/badline/sid/waveform/combined.rb +0 -126
- data/lib/badline/sid/waveform/fast_forward.rb +0 -105
- data/lib/badline/sid/waveform/noise_writeback.rb +0 -122
- data/lib/badline/sid/waveform/state.rb +0 -66
- data/lib/badline/sid/waveform.rb +0 -305
- data/lib/badline/sid.rb +0 -303
- data/lib/badline/snapshot/setup.rb +0 -75
- data/lib/badline/snapshot/state.rb +0 -189
- data/lib/badline/time_of_day.rb +0 -228
- data/lib/badline/traps.rb +0 -19
- data/lib/badline/via/control_lines.rb +0 -122
- data/lib/badline/via/fast_forward.rb +0 -53
- data/lib/badline/via/interrupt_register.rb +0 -67
- data/lib/badline/via/shift_register.rb +0 -180
- data/lib/badline/via/state.rb +0 -42
- data/lib/badline/via/timer1.rb +0 -131
- data/lib/badline/via/timer2.rb +0 -133
- data/lib/badline/via.rb +0 -266
- data/lib/badline/vic/bank.rb +0 -133
- data/lib/badline/vic/border_mask.rb +0 -86
- data/lib/badline/vic/collisions.rb +0 -115
- data/lib/badline/vic/color_patches.rb +0 -47
- data/lib/badline/vic/display_state.rb +0 -185
- data/lib/badline/vic/graphics_mode.rb +0 -164
- data/lib/badline/vic/graphics_shifter.rb +0 -207
- data/lib/badline/vic/register_log.rb +0 -81
- data/lib/badline/vic/registers.rb +0 -195
- data/lib/badline/vic/sequencer.rb +0 -275
- data/lib/badline/vic/sequencer_output.rb +0 -116
- data/lib/badline/vic/sequencer_state.rb +0 -89
- data/lib/badline/vic/sprite/internal_bus.rb +0 -68
- data/lib/badline/vic/sprite/saved_state.rb +0 -64
- data/lib/badline/vic/sprite/shifter.rb +0 -146
- data/lib/badline/vic/sprite/timing.rb +0 -56
- data/lib/badline/vic/sprite.rb +0 -337
- data/lib/badline/vic/sprites.rb +0 -282
- data/lib/badline/vic/sprites_state.rb +0 -57
- data/lib/badline/vic.rb +0 -853
- data/lib/badline/vic20/saved_state.rb +0 -124
- data/lib/badline/vic20/sound/output.rb +0 -83
- data/lib/badline/vic20/sound.rb +0 -233
- data/lib/badline/vic20/vic/saved_state.rb +0 -55
- data/lib/badline/z80/arithmetic.rb +0 -117
- data/lib/badline/z80/bit_page.rb +0 -55
- data/lib/badline/z80/block_io.rb +0 -58
- data/lib/badline/z80/block_transfers.rb +0 -59
- data/lib/badline/z80/bus_cycles.rb +0 -111
- data/lib/badline/z80/core.rb +0 -113
- data/lib/badline/z80/exchanges.rb +0 -50
- data/lib/badline/z80/extended_page.rb +0 -89
- data/lib/badline/z80/flags.rb +0 -37
- data/lib/badline/z80/interrupt_acceptance.rb +0 -46
- data/lib/badline/z80/jumps.rb +0 -82
- data/lib/badline/z80/loads.rb +0 -98
- data/lib/badline/z80/main_page.rb +0 -134
- data/lib/badline/z80/registers.rb +0 -120
- data/lib/badline/z80/saved_state.rb +0 -69
- data/lib/badline/z80/shifts.rb +0 -64
- data/lib/badline/z80.rb +0 -11
- /data/lib/badline/snapshot/{fields.rb → vice/fields.rb} +0 -0
data/lib/badline/time_of_day.rb
DELETED
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
class TimeOfDay
|
|
5
|
-
# The TOD pin is fed from the AC supply. A CIA passes its region's
|
|
6
|
-
# clock and mains frequency, and these are PAL's.
|
|
7
|
-
CLOCK_HZ = Region::PAL.clock_hz
|
|
8
|
-
MAINS_HZ = Region::PAL.mains_hz
|
|
9
|
-
|
|
10
|
-
FIELDS = %i[tenths seconds minutes hours].freeze
|
|
11
|
-
|
|
12
|
-
def initialize(clock_hz: CLOCK_HZ, mains_hz: MAINS_HZ)
|
|
13
|
-
# The accumulator advances mains_hz per cycle, so a TOD pin pulse has
|
|
14
|
-
# arrived when it reaches clock_hz. Integer math keeps it exact.
|
|
15
|
-
@cycles_per_pulse = clock_hz
|
|
16
|
-
@mains_hz = mains_hz
|
|
17
|
-
@accumulator = 0
|
|
18
|
-
@pulses = 0
|
|
19
|
-
@clock = { tenths: 0x00, seconds: 0x00, minutes: 0x00, hours: 0x01 }
|
|
20
|
-
@alarm = { tenths: 0x00, seconds: 0x00, minutes: 0x00, hours: 0x00 }
|
|
21
|
-
@latch = nil
|
|
22
|
-
@stopped = true
|
|
23
|
-
@alarm_pending = false
|
|
24
|
-
self.fifty_hz = false
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# CRA bit 7 divides the TOD pin by 5 instead of 6. The divider has to
|
|
28
|
-
# match the pin frequency to keep time, so PAL software selects 50 Hz.
|
|
29
|
-
def fifty_hz=(enabled)
|
|
30
|
-
@match = enabled ? 4 : 5
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# The clock and the alarm, field by field in FIELDS order, the latch,
|
|
34
|
-
# and the divider's phase.
|
|
35
|
-
def save_state(out)
|
|
36
|
-
out.int(@accumulator).int(@pulses).int(@match).boolean(@stopped).boolean(@alarm_pending)
|
|
37
|
-
FIELDS.each { |field| out.int(@clock[field]).int(@alarm[field]) }
|
|
38
|
-
out.boolean(!@latch.nil?)
|
|
39
|
-
FIELDS.each { |field| out.int(@latch[field]) } if @latch
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def load_state(input)
|
|
43
|
-
@accumulator = input.int
|
|
44
|
-
@pulses = input.int
|
|
45
|
-
@match = input.int
|
|
46
|
-
@stopped = input.boolean?
|
|
47
|
-
@alarm_pending = input.boolean?
|
|
48
|
-
FIELDS.each do |field|
|
|
49
|
-
@clock[field] = input.int
|
|
50
|
-
@alarm[field] = input.int
|
|
51
|
-
end
|
|
52
|
-
@latch = input.boolean? ? FIELDS.to_h { |field| [field, input.int] } : nil
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
# Whether the clock is stopped, or gets no pulses on its pin, with no
|
|
56
|
-
# alarm to raise, so its cycles move only the divider's phase.
|
|
57
|
-
def quiet? = (@stopped || @mains_hz.zero?) && !@alarm_pending
|
|
58
|
-
|
|
59
|
-
# Runs +cycles+ quiet cycles at once.
|
|
60
|
-
def fast_forward(cycles)
|
|
61
|
-
@accumulator = (@accumulator + (cycles * @mains_hz)) % @cycles_per_pulse
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def cycle!
|
|
65
|
-
@accumulator += @mains_hz
|
|
66
|
-
pulse! if @accumulator >= @cycles_per_pulse
|
|
67
|
-
return unless @alarm_pending
|
|
68
|
-
|
|
69
|
-
@alarm_pending = false
|
|
70
|
-
yield if block_given?
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def tenths
|
|
74
|
-
value = (@latch || @clock)[:tenths]
|
|
75
|
-
@latch = nil
|
|
76
|
-
value
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def seconds = (@latch || @clock)[:seconds]
|
|
80
|
-
def minutes = (@latch || @clock)[:minutes]
|
|
81
|
-
|
|
82
|
-
def hours
|
|
83
|
-
@latch ||= @clock.dup
|
|
84
|
-
@latch[:hours]
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
attr_reader :pulses
|
|
88
|
-
|
|
89
|
-
# The clock as a read of the tenths would see it: the latch while the
|
|
90
|
-
# clock is latched. In FIELDS order.
|
|
91
|
-
def latched_fields = FIELDS.map { |field| (@latch || @clock)[field] }
|
|
92
|
-
|
|
93
|
-
# The cycles until the clock next steps a tenth, as VICE counts them.
|
|
94
|
-
def cycles_to_tenth
|
|
95
|
-
to_pulse = (@cycles_per_pulse - @accumulator + @mains_hz - 1) / @mains_hz
|
|
96
|
-
to_pulse + ([@match - @pulses, 0].max * @cycles_per_pulse / @mains_hz)
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
# Sets the clock, the alarm and the latch from VICE's fields, in FIELDS
|
|
100
|
-
# order, the latch nil while unlatched.
|
|
101
|
-
def restore_fields(clock, alarm, latch)
|
|
102
|
-
FIELDS.each_with_index do |field, i|
|
|
103
|
-
@clock[field] = clock[i]
|
|
104
|
-
@alarm[field] = alarm[i]
|
|
105
|
-
end
|
|
106
|
-
@latch = latch && FIELDS.each_with_index.to_h { |field, i| [field, latch[i]] }
|
|
107
|
-
end
|
|
108
|
-
|
|
109
|
-
# Sets whether the clock is stopped, the pulses counted towards the
|
|
110
|
-
# next tenth and the cycles until it, placing the divider so the tenth
|
|
111
|
-
# lands then.
|
|
112
|
-
def restore_divider(stopped, pulses, cycles_to_tenth)
|
|
113
|
-
@stopped = stopped
|
|
114
|
-
@pulses = pulses
|
|
115
|
-
to_pulse = cycles_to_tenth - ([@match - pulses, 0].max * @cycles_per_pulse / @mains_hz)
|
|
116
|
-
@accumulator = (@cycles_per_pulse - (to_pulse * @mains_hz)).clamp(0, @cycles_per_pulse - 1)
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
# The clock and alarm as stored, read without latching the clock.
|
|
120
|
-
def registers
|
|
121
|
-
[@clock[:tenths], @clock[:seconds], @clock[:minutes], @clock[:hours],
|
|
122
|
-
@alarm[:tenths], @alarm[:seconds], @alarm[:minutes], @alarm[:hours],
|
|
123
|
-
@stopped ? 1 : 0, @latch ? 1 : 0]
|
|
124
|
-
end
|
|
125
|
-
|
|
126
|
-
def write(field, value, alarm:)
|
|
127
|
-
# The frequency counter is held clear while the clock is stopped, and
|
|
128
|
-
# starts counting again from the write to tenths that restarts it.
|
|
129
|
-
if field == :tenths && !alarm && @stopped
|
|
130
|
-
@pulses = 0
|
|
131
|
-
@stopped = false
|
|
132
|
-
end
|
|
133
|
-
store(field, value & (field == :tenths ? 0x0f : 0x7f), alarm: alarm)
|
|
134
|
-
end
|
|
135
|
-
|
|
136
|
-
# 12-hour BCD value, bit 7 is the AM/PM flag.
|
|
137
|
-
def write_hours(value, alarm:)
|
|
138
|
-
value &= 0x9f
|
|
139
|
-
# Writing 12 to the hour register flips the AM/PM bit, the same way a
|
|
140
|
-
# carry into 12 does. Writing the alarm hours does not.
|
|
141
|
-
value ^= 0x80 if !alarm && (value & 0x1f) == 0x12
|
|
142
|
-
# Halt the clock when writing hours, so that it doesn't
|
|
143
|
-
# advance mid-update.
|
|
144
|
-
@stopped = true unless alarm
|
|
145
|
-
store(:hours, value, alarm: alarm)
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
private
|
|
149
|
-
|
|
150
|
-
def store(field, value, alarm:)
|
|
151
|
-
target = alarm ? @alarm : @clock
|
|
152
|
-
return if target[field] == value
|
|
153
|
-
|
|
154
|
-
target[field] = value
|
|
155
|
-
@alarm_pending = true if alarm?
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
def pulse!
|
|
159
|
-
@accumulator -= @cycles_per_pulse
|
|
160
|
-
return if @stopped
|
|
161
|
-
|
|
162
|
-
# A three-bit ring counter with six states, compared against the
|
|
163
|
-
# divider on each pin pulse rather than on its way past it.
|
|
164
|
-
if @pulses == @match
|
|
165
|
-
@pulses = 0
|
|
166
|
-
advance
|
|
167
|
-
else
|
|
168
|
-
@pulses += 1
|
|
169
|
-
@pulses = 0 if @pulses > 5
|
|
170
|
-
end
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
def advance
|
|
174
|
-
tenths = (@clock[:tenths] + 1) & 0x0f
|
|
175
|
-
@clock[:tenths] = tenths == 10 ? 0 : tenths
|
|
176
|
-
carry_seconds if tenths == 10
|
|
177
|
-
@alarm_pending = true if alarm?
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
def carry_seconds
|
|
181
|
-
return unless advance_pair(:seconds)
|
|
182
|
-
return unless advance_pair(:minutes)
|
|
183
|
-
|
|
184
|
-
advance_hours
|
|
185
|
-
end
|
|
186
|
-
|
|
187
|
-
# Seconds and minutes hold a four-bit low digit that carries at ten into
|
|
188
|
-
# a three-bit high digit that carries out at six. Both are plain binary
|
|
189
|
-
# counters, so out-of-range BCD counts up from where it was written.
|
|
190
|
-
def advance_pair(field)
|
|
191
|
-
low = ((@clock[field] & 0x0f) + 1) & 0x0f
|
|
192
|
-
high = (@clock[field] >> 4) & 0x07
|
|
193
|
-
carry = false
|
|
194
|
-
|
|
195
|
-
if low == 10
|
|
196
|
-
low = 0
|
|
197
|
-
high = (high + 1) & 0x07
|
|
198
|
-
if high == 6
|
|
199
|
-
high = 0
|
|
200
|
-
carry = true
|
|
201
|
-
end
|
|
202
|
-
end
|
|
203
|
-
|
|
204
|
-
@clock[field] = (high << 4) | low
|
|
205
|
-
carry
|
|
206
|
-
end
|
|
207
|
-
|
|
208
|
-
# The hour runs 9 -> 10 and 12 -> 1 by swapping its two digits, and the
|
|
209
|
-
# AM/PM bit flips as it passes through 12.
|
|
210
|
-
def advance_hours
|
|
211
|
-
pm = @clock[:hours] & 0x80
|
|
212
|
-
high = (@clock[:hours] >> 4) & 0x01
|
|
213
|
-
low = @clock[:hours] & 0x0f
|
|
214
|
-
|
|
215
|
-
if (high == 1 && low == 2) || (high.zero? && low == 9)
|
|
216
|
-
low = high
|
|
217
|
-
high ^= 1
|
|
218
|
-
else
|
|
219
|
-
low = (low + 1) & 0x0f
|
|
220
|
-
pm ^= 0x80 if high == 1 && low == 2
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
@clock[:hours] = pm | (high << 4) | low
|
|
224
|
-
end
|
|
225
|
-
|
|
226
|
-
def alarm? = @clock == @alarm
|
|
227
|
-
end
|
|
228
|
-
end
|
data/lib/badline/traps.rb
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
module Traps
|
|
5
|
-
def install_trap(addr, &handler)
|
|
6
|
-
(@traps ||= {})[addr] = handler
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
def remove_trap(addr)
|
|
10
|
-
@traps&.delete(addr)
|
|
11
|
-
end
|
|
12
|
-
|
|
13
|
-
private
|
|
14
|
-
|
|
15
|
-
def run_traps
|
|
16
|
-
@traps[@program_counter]&.call if @traps
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
end
|
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
class VIA
|
|
5
|
-
# One port's pair of control lines, CA1 and CA2 or CB1 and CB2, set up
|
|
6
|
-
# by a nibble of the peripheral control register, and their two
|
|
7
|
-
# interrupt flags. Bit 0 picks the active edge of C1, rising when set.
|
|
8
|
-
# Bits 3-1 pick the C2 mode:
|
|
9
|
-
#
|
|
10
|
-
# 000 input, falling edge 100 handshake output
|
|
11
|
-
# 001 independent, falling 101 pulse output
|
|
12
|
-
# 010 input, rising edge 110 low output
|
|
13
|
-
# 011 independent, rising 111 high output
|
|
14
|
-
#
|
|
15
|
-
# A port access clears both flags, but an independent input keeps C2's.
|
|
16
|
-
# In handshake mode C2 goes low on a port access and back high on the
|
|
17
|
-
# next active C1 edge. In pulse mode it goes low for the cycle after the
|
|
18
|
-
# access. Port A handshakes on reads and writes, port B on writes only.
|
|
19
|
-
class ControlLines
|
|
20
|
-
attr_reader :control, :c1_high, :c2_high
|
|
21
|
-
|
|
22
|
-
# The level driven on C2, high while it is an input.
|
|
23
|
-
attr_reader :c2_output
|
|
24
|
-
|
|
25
|
-
def initialize(interrupts, c1_flag:, c2_flag:, handshake_on_read:)
|
|
26
|
-
@interrupts = interrupts
|
|
27
|
-
@c1_flag = c1_flag
|
|
28
|
-
@c2_flag = c2_flag
|
|
29
|
-
@handshake_on_read = handshake_on_read
|
|
30
|
-
@c1_high = @c2_high = true
|
|
31
|
-
reset!
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# Back to input mode with both handshake outputs released. The input
|
|
35
|
-
# levels carry over.
|
|
36
|
-
def reset!
|
|
37
|
-
@control = 0
|
|
38
|
-
@handshake_low = false
|
|
39
|
-
@pulse = 0
|
|
40
|
-
drive
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def control=(nibble)
|
|
44
|
-
@control = nibble & 0x0f
|
|
45
|
-
drive
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
# Only the pulse output needs the clock.
|
|
49
|
-
def pulsing? = @pulse.positive?
|
|
50
|
-
|
|
51
|
-
def cycle!
|
|
52
|
-
@pulse -= 1
|
|
53
|
-
drive if @pulse.zero?
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def active_c1_edge?(high) = high == @control.anybits?(0x01)
|
|
57
|
-
|
|
58
|
-
# The lines' levels and mode. Which flags they set, and whether reads
|
|
59
|
-
# handshake, are the port's wiring.
|
|
60
|
-
def save_state(out)
|
|
61
|
-
out.int(@control).boolean(@c1_high).boolean(@c2_high).boolean(@handshake_low).int(@pulse).boolean(@c2_output)
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def load_state(input)
|
|
65
|
-
@control = input.int
|
|
66
|
-
@c1_high = input.boolean?
|
|
67
|
-
@c2_high = input.boolean?
|
|
68
|
-
@handshake_low = input.boolean?
|
|
69
|
-
@pulse = input.int
|
|
70
|
-
@c2_output = input.boolean?
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
# Everything the lines hold, for comparing them at two points.
|
|
74
|
-
def state = [@control, @c1_high, @c2_high, @handshake_low, @pulse, @c2_output]
|
|
75
|
-
|
|
76
|
-
# A new C1 level. An active edge sets the flag and ends a handshake.
|
|
77
|
-
def c1=(high)
|
|
78
|
-
return if high == @c1_high
|
|
79
|
-
|
|
80
|
-
@c1_high = high
|
|
81
|
-
return unless active_c1_edge?(high)
|
|
82
|
-
|
|
83
|
-
@handshake_low = false
|
|
84
|
-
drive
|
|
85
|
-
@interrupts.set(@c1_flag)
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
# A new C2 level. An active edge sets the flag while C2 is an input.
|
|
89
|
-
def c2=(high)
|
|
90
|
-
return if high == @c2_high
|
|
91
|
-
|
|
92
|
-
@c2_high = high
|
|
93
|
-
@interrupts.set(@c2_flag) if @control.nobits?(0x08) && high == @control.anybits?(0x04)
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
# A read or write of the handshaking port register.
|
|
97
|
-
def access!(write)
|
|
98
|
-
@interrupts.clear(independent? ? @c1_flag : @c1_flag | @c2_flag)
|
|
99
|
-
return unless write || @handshake_on_read
|
|
100
|
-
|
|
101
|
-
case @control >> 1
|
|
102
|
-
when 4 then @handshake_low = true
|
|
103
|
-
when 5 then @pulse = 2
|
|
104
|
-
end
|
|
105
|
-
drive
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
private
|
|
109
|
-
|
|
110
|
-
def independent? = @control & 0x0a == 0x02
|
|
111
|
-
|
|
112
|
-
def drive
|
|
113
|
-
@c2_output = case @control >> 1
|
|
114
|
-
when 4 then !@handshake_low
|
|
115
|
-
when 5 then @pulse.zero?
|
|
116
|
-
when 6 then false
|
|
117
|
-
else true
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
end
|
|
122
|
-
end
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
class VIA
|
|
5
|
-
# Running a VIA a stretch of cycles at once while nothing but its
|
|
6
|
-
# counters would change, for Drive::Idle.
|
|
7
|
-
module FastForward
|
|
8
|
-
# quiet_cycles for a VIA that will never set a flag of its own.
|
|
9
|
-
QUIET = 1 << 40
|
|
10
|
-
|
|
11
|
-
# How many cycles the VIA can run with nothing but its counters
|
|
12
|
-
# changing: no flag set, no pulse on a control line and no bit
|
|
13
|
-
# shifted. See Drive::Idle.
|
|
14
|
-
def quiet_cycles
|
|
15
|
-
return 0 if @sr_uses_t2 || @shift_register.clocking? || @ca.pulsing? || @cb.pulsing?
|
|
16
|
-
|
|
17
|
-
[@t1.quiet_cycles, @t2.quiet_cycles].min
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# Runs +cycles+ cycles at once, as many as quiet_cycles allows, which
|
|
21
|
-
# moves only the counters.
|
|
22
|
-
def fast_forward(cycles)
|
|
23
|
-
return if cycles.zero?
|
|
24
|
-
|
|
25
|
-
@t1.fast_forward(cycles)
|
|
26
|
-
@t2.fast_forward(cycles)
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
# The counters an orbit (see Drive::Idle) has to bring back: those
|
|
30
|
-
# of the armed timers, and of the timers +touched+ names (bit 0 for
|
|
31
|
-
# timer 1, bit 1 for timer 2). The others only count.
|
|
32
|
-
def counter_state(touched)
|
|
33
|
-
[(@t1.count_state if @t1.armed? || touched.anybits?(1)),
|
|
34
|
-
(@t2.count_state if @t2.armed? || touched.anybits?(2))]
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# Runs +cycles+ cycles of whole orbits at once: the counters
|
|
38
|
-
# counter_state leaves out move on, and the rest come back round.
|
|
39
|
-
def skip_orbits(cycles, touched)
|
|
40
|
-
@t1.fast_forward(cycles) unless @t1.armed? || touched.anybits?(1)
|
|
41
|
-
@t2.fast_forward(cycles) unless @t2.armed? || touched.anybits?(2)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
# Everything the VIA holds but its counters, for comparing it at two
|
|
45
|
-
# points. Timer 1's PB7 level counts only while ACR bit 7 puts it on
|
|
46
|
-
# the pin: nothing reads it otherwise.
|
|
47
|
-
def idle_state
|
|
48
|
-
[@ora, @orb, @ddra, @ddrb, @latch_a, @latch_b, @acr, @pcr, @pb6_high, @ifr.flags, @ifr.enable,
|
|
49
|
-
@acr.anybits?(0x80) && @t1.pb7, *@t1.state, *@t2.state, *@ca.state, *@cb.state, *@shift_register.state]
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
class VIA
|
|
5
|
-
# The interrupt flag and enable registers. Each source has a flag bit,
|
|
6
|
-
# and IRQ is pulled low while any flag is set with its enable bit.
|
|
7
|
-
class InterruptRegister
|
|
8
|
-
CA2 = 0x01
|
|
9
|
-
CA1 = 0x02
|
|
10
|
-
SR = 0x04
|
|
11
|
-
CB2 = 0x08
|
|
12
|
-
CB1 = 0x10
|
|
13
|
-
TIMER2 = 0x20
|
|
14
|
-
TIMER1 = 0x40
|
|
15
|
-
|
|
16
|
-
attr_reader :flags, :enable
|
|
17
|
-
|
|
18
|
-
def initialize
|
|
19
|
-
reset!
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def reset!
|
|
23
|
-
@flags = 0x00
|
|
24
|
-
@enable = 0x00
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def save_state(out)
|
|
28
|
-
out.int(@flags).int(@enable)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
def load_state(input)
|
|
32
|
-
@flags = input.int
|
|
33
|
-
@enable = input.int
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def set(bits)
|
|
37
|
-
@flags |= bits
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
def clear(bits)
|
|
41
|
-
@flags &= ~bits
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
def irq? = @flags.anybits?(@enable)
|
|
45
|
-
|
|
46
|
-
# Bit 7 reads the IRQ output.
|
|
47
|
-
def read = irq? ? @flags | 0x80 : @flags
|
|
48
|
-
|
|
49
|
-
# Writing 1s clears the flags; bit 7 is ignored.
|
|
50
|
-
def write(value)
|
|
51
|
-
clear(value & 0x7f)
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
# Bit 7 reads as 1.
|
|
55
|
-
def read_enable = @enable | 0x80
|
|
56
|
-
|
|
57
|
-
# Bit 7 picks between setting and clearing the enable bits given.
|
|
58
|
-
def write_enable(value)
|
|
59
|
-
if value.anybits?(0x80)
|
|
60
|
-
@enable |= value & 0x7f
|
|
61
|
-
else
|
|
62
|
-
@enable &= ~value & 0x7f
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
@@ -1,180 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
class VIA
|
|
5
|
-
# The 6522's shift register, with the CB1 clock and CB2 data lines it
|
|
6
|
-
# takes over in every mode but the first.
|
|
7
|
-
#
|
|
8
|
-
# ACR bits 4-2 pick the mode. Modes 1 to 3 shift in, left, with the new
|
|
9
|
-
# bit taken from CB2 into bit 0 on each rising CB1 edge. Modes 4 to 7
|
|
10
|
-
# shift out: each falling CB1 edge puts bit 7 on CB2 and rotates it back
|
|
11
|
-
# round into bit 0, so after eight bits the byte is back where it
|
|
12
|
-
# started. Modes 1, 4 and 5 clock off timer 2, modes 2 and 6 off φ2, and
|
|
13
|
-
# modes 3 and 7 off whatever drives CB1 from outside.
|
|
14
|
-
#
|
|
15
|
-
# Under its own clock the register drives CB1, idling high. Reading or
|
|
16
|
-
# writing the data register starts a byte, but only while the register
|
|
17
|
-
# is idle and enabled: an access in mode 0, or one before the eighth bit
|
|
18
|
-
# is in, leaves the count alone. CB1 falls on the first clock tick of
|
|
19
|
-
# the byte and rises on the second, and so on, so a byte is eight pulses
|
|
20
|
-
# over sixteen ticks. The interrupt flag is set on the tick that raises
|
|
21
|
-
# CB1 over the eighth bit, and CB1 then stays high until the next
|
|
22
|
-
# access.
|
|
23
|
-
#
|
|
24
|
-
# In modes 2 and 6 a tick is a φ2 cycle, from the second cycle after
|
|
25
|
-
# the access on, which makes a byte sixteen cycles. In modes 1, 4 and 5
|
|
26
|
-
# it comes two cycles after each timer 2 low byte underflow, on the
|
|
27
|
-
# cycle after the low byte reloads, which makes a byte sixteen
|
|
28
|
-
# underflows. Mode 4 never stops and never interrupts: its counter is
|
|
29
|
-
# disabled, and the byte goes round and round.
|
|
30
|
-
#
|
|
31
|
-
# Under an external clock the register shifts on every CB1 edge, access
|
|
32
|
-
# or not. The access only arms the counter: the flag is set on the eighth
|
|
33
|
-
# rising edge after it, and the counter then waits for the next access.
|
|
34
|
-
class ShiftRegister
|
|
35
|
-
DISABLED = 0
|
|
36
|
-
IN_T2 = 1
|
|
37
|
-
IN_PHI2 = 2
|
|
38
|
-
IN_EXTERNAL = 3
|
|
39
|
-
OUT_FREE_RUNNING = 4
|
|
40
|
-
OUT_T2 = 5
|
|
41
|
-
OUT_PHI2 = 6
|
|
42
|
-
OUT_EXTERNAL = 7
|
|
43
|
-
|
|
44
|
-
attr_reader :mode, :data
|
|
45
|
-
attr_accessor :cb2_input
|
|
46
|
-
|
|
47
|
-
def initialize
|
|
48
|
-
@mode = DISABLED
|
|
49
|
-
@data = 0x00
|
|
50
|
-
# Bits still to count before the flag, zero when the counter is idle.
|
|
51
|
-
@bits = 0
|
|
52
|
-
# The clock's last two cycles, newest in bit 0: timer 2 low byte
|
|
53
|
-
# underflows in modes 1, 4 and 5, and whether the byte has started
|
|
54
|
-
# in modes 2 and 6.
|
|
55
|
-
@delay = 0
|
|
56
|
-
@clock = true
|
|
57
|
-
@cb2 = true
|
|
58
|
-
# Nothing drives CB2 from outside, so it floats high.
|
|
59
|
-
@cb2_input = true
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def mode=(value)
|
|
63
|
-
@mode = value & 0x07
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def data=(value)
|
|
67
|
-
@data = value & 0xff
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
# A read or write of the data register, which starts a byte if the
|
|
71
|
-
# register is idle and enabled.
|
|
72
|
-
def access!
|
|
73
|
-
return if @mode == DISABLED || @bits.nonzero?
|
|
74
|
-
|
|
75
|
-
@bits = 8
|
|
76
|
-
@delay = 0 if @mode == IN_PHI2 || @mode == OUT_PHI2
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# Whether the register is counting bits off its own clock, which
|
|
80
|
-
# changes it from cycle to cycle.
|
|
81
|
-
def clocking? = @bits.nonzero? && internal_clock?
|
|
82
|
-
|
|
83
|
-
def save_state(out)
|
|
84
|
-
out.int(@mode).int(@data).int(@bits).int(@delay).boolean(@clock).boolean(@cb2).boolean(@cb2_input)
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def load_state(input)
|
|
88
|
-
@mode = input.int
|
|
89
|
-
@data = input.int
|
|
90
|
-
@bits = input.int
|
|
91
|
-
@delay = input.schema > 4 ? input.int : 0
|
|
92
|
-
@clock = input.boolean?
|
|
93
|
-
@cb2 = input.boolean?
|
|
94
|
-
@cb2_input = input.boolean?
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
# Everything the register holds, for comparing it at two points.
|
|
98
|
-
def state = [@mode, @data, @bits, @delay, @clock, @cb2, @cb2_input]
|
|
99
|
-
|
|
100
|
-
# The CB1 level the register drives, or nil when CB1 is an input.
|
|
101
|
-
def cb1_output
|
|
102
|
-
internal_clock? ? @clock : nil
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
# The CB2 level the register drives, or nil when it doesn't.
|
|
106
|
-
def cb2_output
|
|
107
|
-
@mode >= OUT_FREE_RUNNING ? @cb2 : nil
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
# Clocked once per φ2 cycle, with whether timer 2's low byte underflowed
|
|
111
|
-
# on it. Returns true on the cycle that sets the interrupt flag.
|
|
112
|
-
def cycle!(t2_low_underflow)
|
|
113
|
-
case @mode
|
|
114
|
-
when IN_PHI2, OUT_PHI2 then @bits.nonzero? && phi2_tick
|
|
115
|
-
when IN_T2, OUT_T2, OUT_FREE_RUNNING then t2_tick(t2_low_underflow)
|
|
116
|
-
else false
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
# A level change on CB1 from outside. Only the external clock modes
|
|
121
|
-
# listen: shifting in samples CB2 as CB1 rises, and shifting out puts
|
|
122
|
-
# the next bit on CB2 as it falls. Returns true when the edge sets the
|
|
123
|
-
# interrupt flag.
|
|
124
|
-
def cb1_edge!(rising)
|
|
125
|
-
return false unless @mode == IN_EXTERNAL || @mode == OUT_EXTERNAL
|
|
126
|
-
|
|
127
|
-
shift_in if rising && @mode == IN_EXTERNAL
|
|
128
|
-
shift_out if !rising && @mode == OUT_EXTERNAL
|
|
129
|
-
rising && eighth_bit?
|
|
130
|
-
end
|
|
131
|
-
|
|
132
|
-
private
|
|
133
|
-
|
|
134
|
-
def internal_clock?
|
|
135
|
-
@mode != DISABLED && @mode != IN_EXTERNAL && @mode != OUT_EXTERNAL
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
# A φ2 cycle of a byte: every one but the first ticks.
|
|
139
|
-
def phi2_tick
|
|
140
|
-
started = @delay.nonzero?
|
|
141
|
-
@delay = 1
|
|
142
|
-
started && tick
|
|
143
|
-
end
|
|
144
|
-
|
|
145
|
-
# Ticks on the underflow from two cycles back, while a byte is under
|
|
146
|
-
# way.
|
|
147
|
-
def t2_tick(underflow)
|
|
148
|
-
due = @delay.anybits?(2)
|
|
149
|
-
@delay = ((@delay << 1) & 2) | (underflow ? 1 : 0)
|
|
150
|
-
due && @bits.nonzero? && tick
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
# One half period of the register's own clock: a falling edge puts a
|
|
154
|
-
# bit out, and a rising one takes a bit in and counts it.
|
|
155
|
-
def tick
|
|
156
|
-
@clock = !@clock
|
|
157
|
-
shift_out if !@clock && @mode >= OUT_FREE_RUNNING
|
|
158
|
-
shift_in if @clock && @mode < IN_EXTERNAL
|
|
159
|
-
@clock && @mode != OUT_FREE_RUNNING && eighth_bit?
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
# Counts a bit, and says whether it was the eighth since the access.
|
|
163
|
-
def eighth_bit?
|
|
164
|
-
return false if @bits.zero?
|
|
165
|
-
|
|
166
|
-
@bits -= 1
|
|
167
|
-
@bits.zero?
|
|
168
|
-
end
|
|
169
|
-
|
|
170
|
-
def shift_in
|
|
171
|
-
@data = ((@data << 1) | (@cb2_input ? 1 : 0)) & 0xff
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
def shift_out
|
|
175
|
-
@cb2 = @data.anybits?(0x80)
|
|
176
|
-
@data = ((@data << 1) | (@cb2 ? 1 : 0)) & 0xff
|
|
177
|
-
end
|
|
178
|
-
end
|
|
179
|
-
end
|
|
180
|
-
end
|