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/sid.rb
DELETED
|
@@ -1,303 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "badline/sid/waveform"
|
|
4
|
-
require "badline/sid/envelope"
|
|
5
|
-
require "badline/sid/voice"
|
|
6
|
-
require "badline/sid/filter"
|
|
7
|
-
require "badline/sid/decimator"
|
|
8
|
-
require "badline/sid/catch_up"
|
|
9
|
-
|
|
10
|
-
module Badline
|
|
11
|
-
# SID (Sound Interface Device) chip, in either the 6581 or the 8580
|
|
12
|
-
# revision.
|
|
13
|
-
#
|
|
14
|
-
# $D400-$D418 - Voices, filter and volume - write only
|
|
15
|
-
# $D419-$D41A - POTX/POTY paddle inputs - read only
|
|
16
|
-
# $D41B-$D41C - Voice 3 oscillator/envelope - read only
|
|
17
|
-
# $D41D-$D41F - Unconnected
|
|
18
|
-
#
|
|
19
|
-
# The register file mirrors every 32 bytes up to $D7FF. A second or
|
|
20
|
-
# third SID, which only the SID player fits, is built `at` another
|
|
21
|
-
# address and decodes just the 32 bytes there.
|
|
22
|
-
#
|
|
23
|
-
# Reading a write-only or unconnected register returns the last byte the
|
|
24
|
-
# SID saw on the data bus. That value fades to $00 as the capacitance
|
|
25
|
-
# holding it drains. Paddles and the 1351 mouse attach as a pots source
|
|
26
|
-
# responding to #pot_x and #pot_y; with none attached the lines read $FF.
|
|
27
|
-
#
|
|
28
|
-
# Three voices feed the filter and the master volume; #output and #sample
|
|
29
|
-
# read out the mixed result, and #record collects it at an audio rate for
|
|
30
|
-
# #drain_samples. The DSP is clocked lazily and catches up when something
|
|
31
|
-
# asks for its state.
|
|
32
|
-
#
|
|
33
|
-
# The 6581 drives its voices well above ground, so the mix carries a large
|
|
34
|
-
# DC offset that the RC network on the C64 board filters out.
|
|
35
|
-
class SID
|
|
36
|
-
include Addressable
|
|
37
|
-
include CatchUp
|
|
38
|
-
|
|
39
|
-
VOICES = 3
|
|
40
|
-
|
|
41
|
-
# Cycles the data bus holds a value, measured through SID/bitfade.
|
|
42
|
-
BUS_TTL = { mos6581: 0x1d00, mos8580: 0xa2000 }.freeze
|
|
43
|
-
|
|
44
|
-
# Scales the filter's 20-bit mix down to a signed 16-bit sample, as
|
|
45
|
-
# reSID 0.16 does: three voices at full swing and volume 15 span the
|
|
46
|
-
# whole range, on either chip.
|
|
47
|
-
SAMPLE_DIVISOR = ((0xfff * 0xff) >> 7) * 3 * 15 * 2 / (2**16)
|
|
48
|
-
|
|
49
|
-
# Writes the DSP queues between catch-ups. A full queue catches up
|
|
50
|
-
# there and then, so no write loses its timing.
|
|
51
|
-
DEFERRED_WRITES = 0x400
|
|
52
|
-
|
|
53
|
-
# Cycles the filter integrates in one step while synthesizing, after
|
|
54
|
-
# reSID's delta_t_flt. 1 makes the audio exact, at a per-cycle cost.
|
|
55
|
-
FILTER_CHUNK = 4
|
|
56
|
-
|
|
57
|
-
attr_accessor :pots
|
|
58
|
-
attr_reader :model
|
|
59
|
-
|
|
60
|
-
def initialize(model: :mos6581, pots: nil, filter_chunk: FILTER_CHUNK, at: 0xd400)
|
|
61
|
-
addressable_at(at, length: at == 0xd400 ? 2**10 : 2**5)
|
|
62
|
-
@model = model
|
|
63
|
-
@pots = pots
|
|
64
|
-
@bus_ttl_reset = BUS_TTL.fetch(model)
|
|
65
|
-
@filter = Filter.new(model:)
|
|
66
|
-
@synthesizing = false
|
|
67
|
-
@stepped = @synced = false
|
|
68
|
-
@pending_cycles = 0
|
|
69
|
-
@deferred_writes = []
|
|
70
|
-
@decimator = nil
|
|
71
|
-
@samples = []
|
|
72
|
-
@voice_samples = nil
|
|
73
|
-
@filter_chunk = filter_chunk
|
|
74
|
-
@voices = Voice.linked(VOICES, model:)
|
|
75
|
-
@voice1, @voice2, @voice3 = @voices
|
|
76
|
-
@waveform1, @waveform2, @waveform3 = @voices.map(&:waveform)
|
|
77
|
-
reset!
|
|
78
|
-
end
|
|
79
|
-
|
|
80
|
-
# Switches the chip, its filter and its voices to the other model's
|
|
81
|
-
# values. The cycles already passed run on the old model first, and the
|
|
82
|
-
# running state carries over.
|
|
83
|
-
def model=(model)
|
|
84
|
-
catch_up
|
|
85
|
-
@model = model
|
|
86
|
-
@bus_ttl_reset = BUS_TTL.fetch(model)
|
|
87
|
-
@filter.model = model
|
|
88
|
-
@voices.each { |voice| voice.model = model }
|
|
89
|
-
update_span_rules
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
# The RES line clears the registers, the data bus, the filter and the
|
|
93
|
-
# voices, all but their accumulators. Recording carries on across it.
|
|
94
|
-
def reset!
|
|
95
|
-
catch_up
|
|
96
|
-
@registers = Memory.new(length: 2**5)
|
|
97
|
-
@bus_value = 0x00
|
|
98
|
-
@bus_ttl = 0
|
|
99
|
-
@voices.each(&:reset!)
|
|
100
|
-
@filter.reset
|
|
101
|
-
update_span_rules
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
# The DSP only counts cycles as they pass. Whatever asks for its state
|
|
105
|
-
# catches it up, a span at a time: each span fast-forwards the voices
|
|
106
|
-
# and ends on one whole cycle, so everything the CPU can read stays
|
|
107
|
-
# exact. The filter only runs once something wants audio.
|
|
108
|
-
def synthesizing? = @synthesizing
|
|
109
|
-
|
|
110
|
-
def synthesize!
|
|
111
|
-
return if @synthesizing
|
|
112
|
-
|
|
113
|
-
@synthesizing = true
|
|
114
|
-
update_span_rules
|
|
115
|
-
catch_up
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
# Starts collecting the output, averaged down to `rate` samples a
|
|
119
|
-
# second, for #drain_samples. `filter_chunk` overrides the one the SID
|
|
120
|
-
# was built with, for a machine that built its own. `clock_hz` is the
|
|
121
|
-
# rate the SID's cycles are taken to run at.
|
|
122
|
-
def record(rate:, filter_chunk: @filter_chunk, clock_hz: Region::PAL.clock_hz)
|
|
123
|
-
synthesize!
|
|
124
|
-
catch_up
|
|
125
|
-
@filter_chunk = filter_chunk
|
|
126
|
-
@decimator = Decimator.new(clock_hz:, rate:)
|
|
127
|
-
@samples = []
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
# How far the recording has got into the sample it is averaging, for
|
|
131
|
-
# a host that carries on recording from a saved state: it calls
|
|
132
|
-
# #record, then #load_recording.
|
|
133
|
-
def save_recording(out)
|
|
134
|
-
decimator = @decimator
|
|
135
|
-
raise ArgumentError, "the SID isn't recording" if decimator.nil?
|
|
136
|
-
|
|
137
|
-
out.marker("RECORDING")
|
|
138
|
-
decimator.save_state(out)
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
def load_recording(input)
|
|
142
|
-
decimator = @decimator
|
|
143
|
-
raise ArgumentError, "the SID isn't recording" if decimator.nil?
|
|
144
|
-
|
|
145
|
-
input.marker("RECORDING")
|
|
146
|
-
decimator.load_state(input)
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
# Also keeps each voice's own output, before the filter and the volume,
|
|
150
|
-
# as each recorded sample closes, for #drain_voice_samples.
|
|
151
|
-
def record_voices!
|
|
152
|
-
@voice_samples = [] if @voice_samples.nil?
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
# The voices' outputs since the last drain, three to a sample, in voice
|
|
156
|
-
# order, or nothing unless #record_voices! asked for them.
|
|
157
|
-
def drain_voice_samples
|
|
158
|
-
return [] if @voice_samples.nil?
|
|
159
|
-
|
|
160
|
-
catch_up
|
|
161
|
-
samples = @voice_samples
|
|
162
|
-
@voice_samples = []
|
|
163
|
-
samples
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
# The samples recorded since the last drain.
|
|
167
|
-
def drain_samples
|
|
168
|
-
catch_up
|
|
169
|
-
samples = @samples
|
|
170
|
-
@samples = []
|
|
171
|
-
samples
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
def voices
|
|
175
|
-
catch_up
|
|
176
|
-
@voices
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
# Runs the DSP up to the current cycle.
|
|
180
|
-
def catch_up! = catch_up
|
|
181
|
-
|
|
182
|
-
# The byte the data bus holds and the cycles until it fades.
|
|
183
|
-
def bus_state = [@bus_value, @bus_ttl]
|
|
184
|
-
|
|
185
|
-
def restore_bus(value, ttl)
|
|
186
|
-
@bus_value = value
|
|
187
|
-
@bus_ttl = ttl
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
def filter
|
|
191
|
-
catch_up
|
|
192
|
-
@filter
|
|
193
|
-
end
|
|
194
|
-
|
|
195
|
-
# Voice 3's oscillator and envelope, the only synthesis state the CPU
|
|
196
|
-
# can see. Programs poll OSC3 with the noise waveform selected for
|
|
197
|
-
# random numbers, and ENV3 to time hard restarts.
|
|
198
|
-
def osc3
|
|
199
|
-
catch_up
|
|
200
|
-
@waveform3.osc3 >> 4
|
|
201
|
-
end
|
|
202
|
-
|
|
203
|
-
def env3
|
|
204
|
-
catch_up
|
|
205
|
-
@voice3.envelope.env3
|
|
206
|
-
end
|
|
207
|
-
|
|
208
|
-
def output
|
|
209
|
-
synthesize!
|
|
210
|
-
catch_up
|
|
211
|
-
@filter.output
|
|
212
|
-
end
|
|
213
|
-
|
|
214
|
-
def sample
|
|
215
|
-
output
|
|
216
|
-
current_sample
|
|
217
|
-
end
|
|
218
|
-
|
|
219
|
-
def cycle!
|
|
220
|
-
age_bus if @bus_ttl != 0
|
|
221
|
-
@pending_cycles += 1
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
def peek(addr)
|
|
225
|
-
case offset_of(addr) % (2**5)
|
|
226
|
-
when 0x19 then latch(pots ? pots.pot_x : 0xff)
|
|
227
|
-
when 0x1a then latch(pots ? pots.pot_y : 0xff)
|
|
228
|
-
when 0x1b then latch(osc3)
|
|
229
|
-
when 0x1c then latch(env3)
|
|
230
|
-
else @bus_value
|
|
231
|
-
end
|
|
232
|
-
end
|
|
233
|
-
|
|
234
|
-
def poke(addr, value)
|
|
235
|
-
reg = offset_of(addr) % (2**5)
|
|
236
|
-
write_register(reg, value) if reg <= 0x18
|
|
237
|
-
latch(value)
|
|
238
|
-
end
|
|
239
|
-
|
|
240
|
-
# Register contents as written, for save states and debugging.
|
|
241
|
-
def register(reg) = @registers.peek(reg)
|
|
242
|
-
|
|
243
|
-
# The registers, the data bus, the voices and the filter, and the span
|
|
244
|
-
# the DSP has yet to catch up on, as it stands: saving leaves the SID
|
|
245
|
-
# as it was. Whether it synthesizes or records is the host's.
|
|
246
|
-
def save_state(out)
|
|
247
|
-
out.marker("SID")
|
|
248
|
-
@registers.save_state(out)
|
|
249
|
-
out.int(@bus_value).int(@bus_ttl).int(@pending_cycles).ints(@deferred_writes)
|
|
250
|
-
@voices.each { |voice| voice.save_state(out) }
|
|
251
|
-
@filter.save_state(out)
|
|
252
|
-
end
|
|
253
|
-
|
|
254
|
-
def load_state(input)
|
|
255
|
-
input.marker("SID")
|
|
256
|
-
@registers.load_state(input)
|
|
257
|
-
@bus_value = input.int
|
|
258
|
-
@bus_ttl = input.int
|
|
259
|
-
@pending_cycles = input.int
|
|
260
|
-
input.ints_into(@deferred_writes)
|
|
261
|
-
@voices.each { |voice| voice.load_state(input) }
|
|
262
|
-
@filter.load_state(input)
|
|
263
|
-
update_span_rules
|
|
264
|
-
end
|
|
265
|
-
|
|
266
|
-
private
|
|
267
|
-
|
|
268
|
-
def latch(value)
|
|
269
|
-
@bus_ttl = @bus_ttl_reset
|
|
270
|
-
@bus_value = value
|
|
271
|
-
end
|
|
272
|
-
|
|
273
|
-
def age_bus
|
|
274
|
-
@bus_ttl -= 1
|
|
275
|
-
@bus_value = 0x00 if @bus_ttl.zero?
|
|
276
|
-
end
|
|
277
|
-
|
|
278
|
-
def write_register(reg, value)
|
|
279
|
-
@registers.poke(reg, value)
|
|
280
|
-
catch_up if @deferred_writes.length == DEFERRED_WRITES * 3
|
|
281
|
-
@deferred_writes.push(@pending_cycles, reg, value)
|
|
282
|
-
end
|
|
283
|
-
|
|
284
|
-
def apply_write(reg, value)
|
|
285
|
-
reg < 0x15 ? write_voice(reg, value) : @filter.write(reg, value)
|
|
286
|
-
end
|
|
287
|
-
|
|
288
|
-
def write_voice(reg, value)
|
|
289
|
-
voice = @voices[reg / 7]
|
|
290
|
-
case reg % 7
|
|
291
|
-
when 0 then voice.waveform.frequency_low = value
|
|
292
|
-
when 1 then voice.waveform.frequency_high = value
|
|
293
|
-
when 2 then voice.waveform.pulse_width_low = value
|
|
294
|
-
when 3 then voice.waveform.pulse_width_high = value
|
|
295
|
-
when 4
|
|
296
|
-
voice.control = value
|
|
297
|
-
update_span_rules
|
|
298
|
-
when 5 then voice.envelope.attack_decay = value
|
|
299
|
-
when 6 then voice.envelope.sustain_release = value
|
|
300
|
-
end
|
|
301
|
-
end
|
|
302
|
-
end
|
|
303
|
-
end
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
module Snapshot
|
|
5
|
-
# How a machine was built: its VIC, CIA and SID models, its region, its
|
|
6
|
-
# RAM expansion, the size of its REU, its KERNAL, whether it has a
|
|
7
|
-
# datasette and its board, the arguments Computer.new takes. A State
|
|
8
|
-
# starts with them, so a machine to restore it into can be built first.
|
|
9
|
-
Setup = Data.define(:vic_model, :cia_model, :sid_model, :region, :ram_expansion, :reu, :kernal, :datasette,
|
|
10
|
-
:board)
|
|
11
|
-
|
|
12
|
-
class Setup
|
|
13
|
-
SID_MODELS = %i[mos6581 mos8580].freeze
|
|
14
|
-
REGIONS = [Region::PAL, Region::NTSC, Region::NTSC_OLD, Region::DREAN].freeze
|
|
15
|
-
RAM_EXPANSIONS = [:none, *RAMExpansion::TYPES.keys].freeze
|
|
16
|
-
KERNALS = AddressBus::ROMs::KERNALS.keys.freeze
|
|
17
|
-
BOARDS = AddressBus::Fittings::BOARDS
|
|
18
|
-
|
|
19
|
-
def self.of(address_bus)
|
|
20
|
-
new(vic_model: address_bus.vic.model, cia_model: address_bus.cia1.model, sid_model: address_bus.sid.model,
|
|
21
|
-
region: address_bus.region, ram_expansion: address_bus.ram_expansion.type, reu: address_bus.reu&.size_kb,
|
|
22
|
-
kernal: address_bus.kernal, datasette: address_bus.datasette.connected?, board: address_bus.board)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
# Layout 3 has no KERNAL or datasette, and stands for the C64's, and
|
|
26
|
-
# layouts before 6 have no board, and stand for the C64's.
|
|
27
|
-
def self.read(input)
|
|
28
|
-
new(vic_model: VIC::MODELS.fetch(input.int), cia_model: CIA::MODELS.fetch(input.int),
|
|
29
|
-
sid_model: SID_MODELS.fetch(input.int), region: REGIONS.fetch(input.int),
|
|
30
|
-
ram_expansion: ram_expansion(RAM_EXPANSIONS.fetch(input.int)), reu: reu(input.int),
|
|
31
|
-
kernal: input.schema > 3 ? KERNALS.fetch(input.int) : :c64,
|
|
32
|
-
datasette: input.schema > 3 ? input.boolean? : true,
|
|
33
|
-
board: input.schema > 5 ? BOARDS.fetch(input.int) : :c64)
|
|
34
|
-
rescue IndexError
|
|
35
|
-
raise FormatError, "the state names a chip model, region, RAM expansion, KERNAL or board badline doesn't know"
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def self.ram_expansion(name) = name == :none ? nil : name
|
|
39
|
-
|
|
40
|
-
# An REU's size in K, written as 0 for none.
|
|
41
|
-
def self.reu(size_kb)
|
|
42
|
-
return nil if size_kb.zero?
|
|
43
|
-
return size_kb if REU::SIZES_KB.include?(size_kb)
|
|
44
|
-
|
|
45
|
-
raise FormatError, "the state names a #{size_kb}K REU, which badline doesn't build"
|
|
46
|
-
end
|
|
47
|
-
|
|
48
|
-
def write(out)
|
|
49
|
-
out.int(VIC::MODELS.index(vic_model)).int(CIA::MODELS.index(cia_model))
|
|
50
|
-
out.int(SID_MODELS.index(sid_model)).int(REGIONS.index(region))
|
|
51
|
-
out.int(RAM_EXPANSIONS.index(ram_expansion || :none)).int(reu || 0)
|
|
52
|
-
out.int(KERNALS.index(kernal)).boolean(datasette).int(BOARDS.index(board))
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
# A machine built this way, at power-on.
|
|
56
|
-
def build
|
|
57
|
-
Computer.new(vic_model:, cia_model:, sid_model:, region:, ram_expansion:, reu:, kernal:, datasette:, board:)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
# The chips, led by the model's name when they make one of
|
|
61
|
-
# Badline::Model's.
|
|
62
|
-
def to_s
|
|
63
|
-
model = Model.of(self)
|
|
64
|
-
parts = [vic_model, cia_model, sid_model, region.name]
|
|
65
|
-
parts.unshift(model.name) if model
|
|
66
|
-
parts << ram_expansion if ram_expansion
|
|
67
|
-
parts << "a #{reu}K REU" if reu
|
|
68
|
-
parts << "the #{kernal} KERNAL" unless kernal == :c64
|
|
69
|
-
parts << "no datasette" unless datasette
|
|
70
|
-
parts << "the #{board} board" unless board == :c64
|
|
71
|
-
parts.join(", ")
|
|
72
|
-
end
|
|
73
|
-
end
|
|
74
|
-
end
|
|
75
|
-
end
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
module Snapshot
|
|
5
|
-
# A file that isn't a snapshot badline reads, is cut short, or holds a
|
|
6
|
-
# state that doesn't line up with the machine reading it.
|
|
7
|
-
class FormatError < StandardError; end
|
|
8
|
-
|
|
9
|
-
# A machine's state, held in memory: the Integers each chip writes in
|
|
10
|
-
# turn, and the byte strings for memories, names and paths. Booleans
|
|
11
|
-
# are written as 0 and 1. Computer#snapshot takes one and
|
|
12
|
-
# Computer#restore puts it back.
|
|
13
|
-
class State
|
|
14
|
-
# The layout the chips write their fields in. It goes up whenever a
|
|
15
|
-
# save_state writes something else, so a State in another layout
|
|
16
|
-
# fails before anything is read into a machine. Layout 3, without the
|
|
17
|
-
# KERNAL and datasette in the setup, layout 4, without the VIA shift
|
|
18
|
-
# register's clock delay, layout 5, without the board in the setup,
|
|
19
|
-
# layout 6, without the C128's Z80, layout 7, without a 1581 on the
|
|
20
|
-
# serial bus, and layout 8, with the VIC's unused cycle count and
|
|
21
|
-
# pending-write flag, still read.
|
|
22
|
-
SCHEMA = 9
|
|
23
|
-
READABLE = [3, 4, 5, 6, 7, 8, SCHEMA].freeze
|
|
24
|
-
|
|
25
|
-
attr_reader :values, :strings
|
|
26
|
-
|
|
27
|
-
def initialize(values, strings)
|
|
28
|
-
@values = values
|
|
29
|
-
@strings = strings
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def ==(other)
|
|
33
|
-
other.is_a?(State) && values == other.values && strings == other.strings
|
|
34
|
-
end
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# Writes a State. Each chip's save_state writes its fields through one
|
|
38
|
-
# of these, and its load_state reads them back from a StateReader in
|
|
39
|
-
# the same order.
|
|
40
|
-
class StateWriter
|
|
41
|
-
attr_reader :state
|
|
42
|
-
|
|
43
|
-
def initialize
|
|
44
|
-
@values = []
|
|
45
|
-
@strings = []
|
|
46
|
-
@state = State.new(@values, @strings)
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def int(value)
|
|
50
|
-
raise TypeError, "not an Integer: #{value.inspect}" unless value.is_a?(Integer)
|
|
51
|
-
|
|
52
|
-
@values << value.to_i
|
|
53
|
-
self
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def boolean(value)
|
|
57
|
-
@values << (value ? 1 : 0)
|
|
58
|
-
self
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
def optional_int(value)
|
|
62
|
-
return boolean(false) if value.nil?
|
|
63
|
-
|
|
64
|
-
boolean(true).int(value)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def ints(values)
|
|
68
|
-
int(values.length)
|
|
69
|
-
values.each { |value| int(value) }
|
|
70
|
-
self
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
def booleans(values)
|
|
74
|
-
int(values.length)
|
|
75
|
-
values.each { |value| boolean(value) }
|
|
76
|
-
self
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# Bytes, 0 to 255 each, kept as one string.
|
|
80
|
-
def blob(values)
|
|
81
|
-
@strings << values.pack("C*")
|
|
82
|
-
self
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
def string(value)
|
|
86
|
-
@strings << value.to_s.b
|
|
87
|
-
self
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def optional_string(value)
|
|
91
|
-
return boolean(false) if value.nil?
|
|
92
|
-
|
|
93
|
-
boolean(true).string(value)
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
# A name a reader checks for, so a state that has gone out of step
|
|
97
|
-
# fails there instead of loading the wrong fields.
|
|
98
|
-
def marker(name) = string(name)
|
|
99
|
-
|
|
100
|
-
# The State's layout and the badline version writing it, which a
|
|
101
|
-
# reader checks first (StateReader#check_stamp).
|
|
102
|
-
def stamp = int(State::SCHEMA).string(VERSION)
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
# Reads a State back in the order a StateWriter wrote it.
|
|
106
|
-
#
|
|
107
|
-
# A detached reader restores a machine that opens no host file and
|
|
108
|
-
# writes none, for a copy the machine runs on its own: a disk image
|
|
109
|
-
# comes from the bytes the state holds, write-protected, a directory
|
|
110
|
-
# device 8 serves is left out, and a true drive's disk keeps the
|
|
111
|
-
# state's tracks without its image file.
|
|
112
|
-
class StateReader
|
|
113
|
-
# The layout check_stamp found.
|
|
114
|
-
attr_reader :schema
|
|
115
|
-
|
|
116
|
-
def initialize(state, detached: false)
|
|
117
|
-
@values = state.values
|
|
118
|
-
@strings = state.strings
|
|
119
|
-
@value = 0
|
|
120
|
-
@string = 0
|
|
121
|
-
@detached = detached
|
|
122
|
-
@schema = State::SCHEMA
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
def detached? = @detached
|
|
126
|
-
|
|
127
|
-
def int
|
|
128
|
-
raise FormatError, "the state ends early, at value #{@value}" if @value >= @values.length
|
|
129
|
-
|
|
130
|
-
value = @values[@value]
|
|
131
|
-
@value += 1
|
|
132
|
-
value
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
def boolean?
|
|
136
|
-
value = int
|
|
137
|
-
raise FormatError, "expected a boolean in the state, found #{value}" unless value.between?(0, 1)
|
|
138
|
-
|
|
139
|
-
value == 1
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
def optional_int = boolean? ? int : nil
|
|
143
|
-
|
|
144
|
-
def ints = Array.new(int) { int }
|
|
145
|
-
|
|
146
|
-
def booleans = Array.new(int) { boolean? }
|
|
147
|
-
|
|
148
|
-
# Reads into an existing array, in place, so whatever else holds it
|
|
149
|
-
# sees the values.
|
|
150
|
-
def ints_into(array) = array.replace(ints)
|
|
151
|
-
|
|
152
|
-
def booleans_into(array) = array.replace(booleans)
|
|
153
|
-
|
|
154
|
-
def blob = string.bytes
|
|
155
|
-
|
|
156
|
-
def blob_into(array) = array.replace(blob)
|
|
157
|
-
|
|
158
|
-
def string
|
|
159
|
-
raise FormatError, "the state ends early, at string #{@string}" if @string >= @strings.length
|
|
160
|
-
|
|
161
|
-
value = @strings[@string]
|
|
162
|
-
@string += 1
|
|
163
|
-
value
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
def optional_string = boolean? ? string : nil
|
|
167
|
-
|
|
168
|
-
def marker(name)
|
|
169
|
-
found = string
|
|
170
|
-
raise FormatError, "expected #{name} in the state, found #{found[0, 20].inspect}" unless found == name
|
|
171
|
-
end
|
|
172
|
-
|
|
173
|
-
# Fails unless the State was written in a layout this badline reads
|
|
174
|
-
# (State::READABLE) by this badline version.
|
|
175
|
-
def check_stamp
|
|
176
|
-
schema = int
|
|
177
|
-
version = string
|
|
178
|
-
@schema = schema
|
|
179
|
-
return if State::READABLE.include?(schema) && version == VERSION
|
|
180
|
-
|
|
181
|
-
raise FormatError, "the state was written by badline #{version.inspect} in layout #{schema}, " \
|
|
182
|
-
"and this is badline #{VERSION}, layout #{State::SCHEMA}"
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
# Whether every value and string has been read.
|
|
186
|
-
def finished? = @value == @values.length && @string == @strings.length
|
|
187
|
-
end
|
|
188
|
-
end
|
|
189
|
-
end
|