badline 0.12.1 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -0
- data/CLAUDE.md +59 -31
- data/README.md +1 -1
- data/doc/library.md +9 -9
- data/doc/pinned-behaviour.md +105 -105
- data/doc/snapshots.md +1 -4
- data/lib/badline/audio/bare_player.rb +3 -3
- data/lib/badline/audio/cli.rb +6 -6
- data/lib/badline/audio/jukebox.rb +2 -2
- data/lib/badline/audio/machine_player.rb +2 -2
- data/lib/badline/{media → audio}/queue.rb +1 -1
- data/lib/badline/audio/queued_tune.rb +6 -6
- data/lib/badline/audio/renderer.rb +5 -5
- data/lib/badline/audio/stereo.rb +1 -1
- data/lib/badline/c128/{bus_state.rb → bus/saved_state.rb} +1 -1
- data/lib/badline/c128/bus.rb +18 -17
- data/lib/badline/c128/color_lines.rb +2 -2
- data/lib/badline/c128/cpu.rb +1 -1
- data/lib/badline/c128/drives.rb +10 -11
- data/lib/badline/c128/fast_serial.rb +5 -5
- data/lib/badline/c128/mmu_pages.rb +1 -1
- data/lib/badline/c128/modes.rb +2 -2
- data/lib/badline/c128/saved_state.rb +21 -47
- data/lib/badline/c128/z80.rb +2 -2
- data/lib/badline/c128.rb +14 -9
- data/lib/badline/{computer → c64}/attachments.rb +4 -6
- data/lib/badline/c64/banked_ram/banking.rb +32 -0
- data/lib/badline/c64/banked_ram/plus256k.rb +56 -0
- data/lib/badline/c64/banked_ram/plus60k.rb +45 -0
- data/lib/badline/c64/banked_ram/unexpanded.rb +30 -0
- data/lib/badline/c64/banked_ram.rb +23 -0
- data/lib/badline/c64/bus/extra_sids.rb +32 -0
- data/lib/badline/c64/bus/fittings.rb +40 -0
- data/lib/badline/c64/bus/pla.rb +149 -0
- data/lib/badline/c64/bus/roms.rb +41 -0
- data/lib/badline/c64/bus/saved_state.rb +68 -0
- data/lib/badline/c64/bus/sid_slots.rb +44 -0
- data/lib/badline/c64/bus.rb +218 -0
- data/lib/badline/c64/cartridge/action_replay.rb +128 -0
- data/lib/badline/c64/cartridge/atomic_power.rb +26 -0
- data/lib/badline/c64/cartridge/bank.rb +83 -0
- data/lib/badline/c64/cartridge/comal80.rb +52 -0
- data/lib/badline/c64/cartridge/dinamic.rb +36 -0
- data/lib/badline/c64/cartridge/easy_flash.rb +147 -0
- data/lib/badline/c64/cartridge/epyx_fastload.rb +81 -0
- data/lib/badline/c64/cartridge/final_cartridge3.rb +91 -0
- data/lib/badline/c64/cartridge/flash/saved_state.rb +40 -0
- data/lib/badline/c64/cartridge/flash.rb +279 -0
- data/lib/badline/c64/cartridge/freezer.rb +35 -0
- data/lib/badline/c64/cartridge/fun_play.rb +40 -0
- data/lib/badline/c64/cartridge/g_mod2.rb +76 -0
- data/lib/badline/c64/cartridge/game_system.rb +42 -0
- data/lib/badline/c64/cartridge/geo_ram.rb +81 -0
- data/lib/badline/c64/cartridge/kcs_power.rb +77 -0
- data/lib/badline/c64/cartridge/mach5.rb +34 -0
- data/lib/badline/c64/cartridge/magic_desk.rb +32 -0
- data/lib/badline/c64/cartridge/ocean.rb +37 -0
- data/lib/badline/c64/cartridge/pagefox.rb +70 -0
- data/lib/badline/c64/cartridge/retro_replay/saved_state.rb +47 -0
- data/lib/badline/c64/cartridge/retro_replay.rb +286 -0
- data/lib/badline/c64/cartridge/rex_utility.rb +31 -0
- data/lib/badline/c64/cartridge/rgcd.rb +60 -0
- data/lib/badline/c64/cartridge/saved_state.rb +63 -0
- data/lib/badline/c64/cartridge/simons_basic.rb +37 -0
- data/lib/badline/c64/cartridge/standard.rb +17 -0
- data/lib/badline/c64/cartridge/super_games.rb +50 -0
- data/lib/badline/c64/cartridge/westermann.rb +32 -0
- data/lib/badline/c64/cartridge/zaxxon.rb +68 -0
- data/lib/badline/c64/cartridge.rb +258 -0
- data/lib/badline/c64/color_memory.rb +27 -0
- data/lib/badline/{computer → c64}/common.rb +2 -2
- data/lib/badline/{computer → c64}/kernal_traps.rb +18 -18
- data/lib/badline/c64/reu/dma/saved_state.rb +52 -0
- data/lib/badline/c64/reu/dma.rb +275 -0
- data/lib/badline/c64/reu/ram.rb +109 -0
- data/lib/badline/c64/reu/saved_state.rb +55 -0
- data/lib/badline/c64/reu/trigger.rb +34 -0
- data/lib/badline/c64/reu.rb +291 -0
- data/lib/badline/{computer → c64}/saved_state.rb +13 -18
- data/lib/badline/{computer → c64}/true_drives.rb +11 -11
- data/lib/badline/{computer.rb → c64.rb} +18 -13
- data/lib/badline/chips/cia/fast_forward.rb +62 -0
- data/lib/badline/chips/cia/interrupt_register.rb +145 -0
- data/lib/badline/chips/cia/saved_state.rb +49 -0
- data/lib/badline/chips/cia/serial/saved_state.rb +45 -0
- data/lib/badline/chips/cia/serial.rb +250 -0
- data/lib/badline/chips/cia/time_of_day.rb +232 -0
- data/lib/badline/chips/cia/timer.rb +208 -0
- data/lib/badline/chips/cia.rb +281 -0
- data/lib/badline/chips/cpu/addressing.rb +133 -0
- data/lib/badline/chips/cpu/boundary.rb +56 -0
- data/lib/badline/chips/cpu/core.rb +167 -0
- data/lib/badline/chips/cpu/instruction.rb +338 -0
- data/lib/badline/chips/cpu/instruction_set/arithmetic.rb +118 -0
- data/lib/badline/chips/cpu/instruction_set/bitwise.rb +130 -0
- data/lib/badline/chips/cpu/instruction_set/branch.rb +83 -0
- data/lib/badline/chips/cpu/instruction_set/flag.rb +67 -0
- data/lib/badline/chips/cpu/instruction_set/illegal.rb +274 -0
- data/lib/badline/chips/cpu/instruction_set/inc_dec.rb +73 -0
- data/lib/badline/chips/cpu/instruction_set/stack.rb +56 -0
- data/lib/badline/chips/cpu/instruction_set/transfer.rb +141 -0
- data/lib/badline/chips/cpu/instruction_set.rb +59 -0
- data/lib/badline/chips/cpu/interrupts.rb +108 -0
- data/lib/badline/chips/cpu/microcode.rb +179 -0
- data/lib/badline/chips/cpu/operations.rb +90 -0
- data/lib/badline/chips/cpu/port.rb +116 -0
- data/lib/badline/chips/cpu/saved_state.rb +117 -0
- data/lib/badline/chips/cpu/stack_operations.rb +84 -0
- data/lib/badline/chips/cpu/traps.rb +23 -0
- data/lib/badline/chips/cpu.rb +12 -0
- data/lib/badline/chips/sid/catch_up.rb +122 -0
- data/lib/badline/chips/sid/decimator.rb +66 -0
- data/lib/badline/chips/sid/envelope/saved_state.rb +70 -0
- data/lib/badline/chips/sid/envelope.rb +241 -0
- data/lib/badline/chips/sid/filter/saved_state.rb +42 -0
- data/lib/badline/chips/sid/filter.rb +241 -0
- data/lib/badline/chips/sid/saved_state.rb +52 -0
- data/lib/badline/chips/sid/voice.rb +79 -0
- data/lib/badline/chips/sid/waveform/combined.rb +128 -0
- data/lib/badline/chips/sid/waveform/fast_forward.rb +107 -0
- data/lib/badline/chips/sid/waveform/noise_writeback.rb +124 -0
- data/lib/badline/chips/sid/waveform/saved_state.rb +68 -0
- data/lib/badline/chips/sid/waveform.rb +307 -0
- data/lib/badline/chips/sid.rb +265 -0
- data/lib/badline/{c128 → chips}/vdc/memory.rb +1 -1
- data/lib/badline/{c128 → chips}/vdc/painter.rb +1 -1
- data/lib/badline/{c128 → chips}/vdc/raster.rb +1 -1
- data/lib/badline/chips/vdc/saved_state.rb +36 -0
- data/lib/badline/{c128 → chips}/vdc/window.rb +1 -1
- data/lib/badline/{c128 → chips}/vdc.rb +7 -31
- data/lib/badline/chips/via/control_lines.rb +124 -0
- data/lib/badline/chips/via/fast_forward.rb +55 -0
- data/lib/badline/chips/via/interrupt_register.rb +69 -0
- data/lib/badline/chips/via/saved_state.rb +44 -0
- data/lib/badline/chips/via/shift_register.rb +182 -0
- data/lib/badline/chips/via/timer1.rb +133 -0
- data/lib/badline/chips/via/timer2.rb +135 -0
- data/lib/badline/chips/via.rb +268 -0
- data/lib/badline/chips/vic/bank.rb +135 -0
- data/lib/badline/chips/vic/border_mask.rb +88 -0
- data/lib/badline/chips/vic/collisions.rb +117 -0
- data/lib/badline/chips/vic/color_patches.rb +49 -0
- data/lib/badline/chips/vic/display_state.rb +187 -0
- data/lib/badline/chips/vic/graphics_mode.rb +166 -0
- data/lib/badline/chips/vic/graphics_shifter/saved_state.rb +40 -0
- data/lib/badline/chips/vic/graphics_shifter.rb +187 -0
- data/lib/badline/chips/vic/register_log.rb +83 -0
- data/lib/badline/chips/vic/registers.rb +197 -0
- data/lib/badline/chips/vic/saved_state.rb +82 -0
- data/lib/badline/chips/vic/sequencer/saved_state.rb +91 -0
- data/lib/badline/chips/vic/sequencer.rb +277 -0
- data/lib/badline/chips/vic/sequencer_output.rb +118 -0
- data/lib/badline/chips/vic/sprite/internal_bus.rb +70 -0
- data/lib/badline/chips/vic/sprite/saved_state.rb +66 -0
- data/lib/badline/chips/vic/sprite/shifter.rb +148 -0
- data/lib/badline/chips/vic/sprite/timing.rb +58 -0
- data/lib/badline/chips/vic/sprite.rb +339 -0
- data/lib/badline/chips/vic/sprites/saved_state.rb +59 -0
- data/lib/badline/chips/vic/sprites.rb +284 -0
- data/lib/badline/chips/vic.rb +783 -0
- data/lib/badline/chips/vic_i/painter/saved_state.rb +40 -0
- data/lib/badline/{vic20/vic → chips/vic_i}/painter.rb +6 -30
- data/lib/badline/{vic20/vic → chips/vic_i}/saved_state.rb +2 -2
- data/lib/badline/chips/vic_i/sound/output.rb +85 -0
- data/lib/badline/chips/vic_i/sound.rb +235 -0
- data/lib/badline/{vic20/vic → chips/vic_i}/text_window.rb +2 -2
- data/lib/badline/{vic20/vic.rb → chips/vic_i.rb} +5 -5
- data/lib/badline/chips/z80/arithmetic.rb +119 -0
- data/lib/badline/chips/z80/bit_page.rb +57 -0
- data/lib/badline/chips/z80/block_io.rb +60 -0
- data/lib/badline/chips/z80/block_transfers.rb +61 -0
- data/lib/badline/chips/z80/bus_cycles.rb +113 -0
- data/lib/badline/chips/z80/core.rb +115 -0
- data/lib/badline/chips/z80/exchanges.rb +52 -0
- data/lib/badline/chips/z80/extended_page.rb +91 -0
- data/lib/badline/chips/z80/flags.rb +39 -0
- data/lib/badline/chips/z80/interrupt_acceptance.rb +48 -0
- data/lib/badline/chips/z80/jumps.rb +84 -0
- data/lib/badline/chips/z80/loads.rb +100 -0
- data/lib/badline/chips/z80/main_page.rb +136 -0
- data/lib/badline/chips/z80/registers.rb +122 -0
- data/lib/badline/chips/z80/saved_state.rb +71 -0
- data/lib/badline/chips/z80/shifts.rb +66 -0
- data/lib/badline/chips/z80.rb +13 -0
- data/lib/badline/core.rb +26 -28
- data/lib/badline/drives/datasette/saved_state.rb +37 -0
- data/lib/badline/drives/datasette.rb +140 -0
- data/lib/badline/drives/engine/core.rb +149 -0
- data/lib/badline/drives/engine/fast_serial.rb +75 -0
- data/lib/badline/drives/engine/idle.rb +127 -0
- data/lib/badline/drives/engine/idle_cpu.rb +30 -0
- data/lib/badline/drives/engine/orbit.rb +81 -0
- data/lib/badline/drives/engine/serial_lines.rb +75 -0
- data/lib/badline/drives/engine/sleep.rb +114 -0
- data/lib/badline/drives/engine/vias.rb +86 -0
- data/lib/badline/drives/engine/watch.rb +152 -0
- data/lib/badline/drives/engine.rb +11 -0
- data/lib/badline/drives/model1541/bus.rb +88 -0
- data/lib/badline/drives/model1541/byte_ready.rb +50 -0
- data/lib/badline/drives/model1541/cpu.rb +13 -0
- data/lib/badline/drives/model1541/disk/saved_state.rb +88 -0
- data/lib/badline/drives/model1541/disk.rb +317 -0
- data/lib/badline/drives/model1541/disk_via.rb +38 -0
- data/lib/badline/drives/model1541/gcr.rb +59 -0
- data/lib/badline/drives/model1541/mechanism/saved_state.rb +72 -0
- data/lib/badline/drives/model1541/mechanism.rb +315 -0
- data/lib/badline/drives/model1541/rotation.rb +123 -0
- data/lib/badline/drives/model1541/saved_state.rb +44 -0
- data/lib/badline/drives/model1541/sector_reader.rb +78 -0
- data/lib/badline/drives/model1541/serial_port.rb +20 -0
- data/lib/badline/drives/model1541/track.rb +100 -0
- data/lib/badline/drives/model1541.rb +81 -0
- data/lib/badline/drives/model1571/bus.rb +113 -0
- data/lib/badline/drives/model1571/cpu.rb +13 -0
- data/lib/badline/drives/model1571/saved_state.rb +47 -0
- data/lib/badline/drives/model1571/serial_port.rb +39 -0
- data/lib/badline/drives/model1571/serial_via.rb +27 -0
- data/lib/badline/drives/model1571/wd1770.rb +122 -0
- data/lib/badline/drives/model1571.rb +142 -0
- data/lib/badline/drives/model1581/bus.rb +139 -0
- data/lib/badline/drives/model1581/cpu.rb +13 -0
- data/lib/badline/drives/model1581/disk/saved_state.rb +89 -0
- data/lib/badline/drives/model1581/disk.rb +137 -0
- data/lib/badline/drives/model1581/mechanism.rb +119 -0
- data/lib/badline/drives/model1581/saved_state.rb +42 -0
- data/lib/badline/drives/model1581/serial_port.rb +54 -0
- data/lib/badline/drives/model1581/slot.rb +79 -0
- data/lib/badline/drives/model1581/track.rb +102 -0
- data/lib/badline/drives/model1581/track_bytes.rb +77 -0
- data/lib/badline/drives/model1581/wd1772/registers.rb +91 -0
- data/lib/badline/drives/model1581/wd1772/saved_state.rb +68 -0
- data/lib/badline/drives/model1581/wd1772/sector_writes.rb +75 -0
- data/lib/badline/drives/model1581/wd1772/sectors.rb +152 -0
- data/lib/badline/drives/model1581/wd1772/stepping.rb +111 -0
- data/lib/badline/drives/model1581/wd1772/tracks.rb +127 -0
- data/lib/badline/drives/model1581/wd1772/turn.rb +75 -0
- data/lib/badline/drives/model1581/wd1772.rb +218 -0
- data/lib/badline/drives/model1581.rb +206 -0
- data/lib/badline/drives/serial_bus.rb +161 -0
- data/lib/badline/frontend/boot.rb +3 -3
- data/lib/badline/frontend/machine_window.rb +3 -1
- data/lib/badline/frontend/player/filter_view.rb +1 -1
- data/lib/badline/frontend/player/player_controller.rb +2 -2
- data/lib/badline/frontend/player/player_screen.rb +1 -0
- data/lib/badline/frontend/player/theme.rb +7 -7
- data/lib/badline/frontend/timeline.rb +3 -3
- data/lib/badline/input/control_ports.rb +78 -0
- data/lib/badline/input/joystick.rb +27 -0
- data/lib/badline/input/keyboard.rb +114 -0
- data/lib/badline/input.rb +3 -0
- data/lib/badline/kernal_trap/{drive → dos}/block_commands.rb +1 -1
- data/lib/badline/kernal_trap/dos/channel.rb +183 -0
- data/lib/badline/kernal_trap/{drive → dos}/channels.rb +1 -1
- data/lib/badline/kernal_trap/{drive → dos}/memory.rb +1 -1
- data/lib/badline/kernal_trap/{drive → dos}/parameters.rb +1 -1
- data/lib/badline/kernal_trap/{drive → dos}/status.rb +1 -1
- data/lib/badline/kernal_trap/{drive → dos}/write_file.rb +1 -1
- data/lib/badline/kernal_trap/{drive → dos}/writes.rb +1 -1
- data/lib/badline/kernal_trap/{drive.rb → dos.rb} +11 -10
- data/lib/badline/kernal_trap/load.rb +5 -5
- data/lib/badline/kernal_trap/save.rb +4 -4
- data/lib/badline/kernal_trap/serial.rb +7 -7
- data/lib/badline/kernal_trap.rb +1 -2
- data/lib/badline/machine/clocking.rb +1 -1
- data/lib/badline/machine.rb +5 -5
- data/lib/badline/media/true_drive.rb +1 -1
- data/lib/badline/media/tune.rb +2 -2
- data/lib/badline/media.rb +3 -3
- data/lib/badline/model.rb +1 -1
- data/lib/badline/roms/README +6 -6
- data/lib/badline/sdl.rb +1 -0
- data/lib/badline/{storage/sid_file.rb → sid_tune/file.rb} +3 -3
- data/lib/badline/{storage → sid_tune}/hvsc.rb +7 -7
- data/lib/badline/{storage → sid_tune}/song_lengths.rb +2 -2
- data/lib/badline/{storage → sid_tune}/stil/credit.rb +1 -1
- data/lib/badline/{storage → sid_tune}/stil.rb +3 -3
- data/lib/badline/sid_tune.rb +6 -0
- data/lib/badline/snapshot/c128_setup.rb +43 -0
- data/lib/badline/snapshot/c64_setup.rb +79 -0
- data/lib/badline/snapshot/image.rb +5 -25
- data/lib/badline/snapshot/machine_state.rb +1 -1
- data/lib/badline/snapshot/setup.rb +22 -66
- data/lib/badline/snapshot/state.rb +8 -18
- data/lib/badline/snapshot/storage_setup.rb +68 -0
- data/lib/badline/snapshot/vic20_setup.rb +37 -0
- data/lib/badline/snapshot/vice/c64_mem.rb +1 -1
- data/lib/badline/snapshot/vice/restore.rb +1 -1
- data/lib/badline/snapshot/vice/reu1764.rb +1 -1
- data/lib/badline/snapshot/vice/reu_fields.rb +40 -0
- data/lib/badline/snapshot/vice.rb +7 -5
- data/lib/badline/snapshot.rb +3 -4
- data/lib/badline/storage/d64_image.rb +0 -2
- data/lib/badline/storage/d71_image.rb +0 -2
- data/lib/badline/storage/d81_image.rb +0 -2
- data/lib/badline/storage/disk_image.rb +3 -6
- data/lib/badline/storage/g64_image.rb +2 -2
- data/lib/badline/storage/host_directory.rb +0 -5
- data/lib/badline/storage/t64.rb +2 -8
- data/lib/badline/storage/unavailable.rb +1 -1
- data/lib/badline/storage.rb +0 -37
- data/lib/badline/support/c128_checkpoint.rb +39 -0
- data/lib/badline/support/checkpoint.rb +108 -0
- data/lib/badline/support/vic20_checkpoint.rb +38 -0
- data/lib/badline/support.rb +5 -0
- data/lib/badline/version.rb +1 -1
- data/lib/badline/vic20/attachments.rb +5 -5
- data/lib/badline/vic20/bus/saved_state.rb +35 -0
- data/lib/badline/vic20/bus.rb +3 -25
- data/lib/badline/vic20/cpu.rb +1 -1
- data/lib/badline/vic20/port_wiring.rb +4 -4
- data/lib/badline/vic20/saved_state.rb +16 -30
- data/lib/badline/vic20/user_via_ports.rb +2 -2
- data/lib/badline/vic20.rb +19 -14
- metadata +245 -221
- data/lib/badline/address_bus/extra_sids.rb +0 -30
- data/lib/badline/address_bus/fittings.rb +0 -38
- data/lib/badline/address_bus/pla.rb +0 -147
- data/lib/badline/address_bus/roms.rb +0 -39
- data/lib/badline/address_bus/saved_state.rb +0 -66
- data/lib/badline/address_bus/sid_slots.rb +0 -42
- data/lib/badline/address_bus.rb +0 -216
- data/lib/badline/cartridge/action_replay.rb +0 -126
- data/lib/badline/cartridge/atomic_power.rb +0 -24
- data/lib/badline/cartridge/bank.rb +0 -81
- data/lib/badline/cartridge/comal80.rb +0 -50
- data/lib/badline/cartridge/dinamic.rb +0 -34
- data/lib/badline/cartridge/easy_flash.rb +0 -145
- data/lib/badline/cartridge/epyx_fastload.rb +0 -79
- data/lib/badline/cartridge/final_cartridge3.rb +0 -89
- data/lib/badline/cartridge/flash.rb +0 -306
- data/lib/badline/cartridge/freezer.rb +0 -33
- data/lib/badline/cartridge/fun_play.rb +0 -38
- data/lib/badline/cartridge/g_mod2.rb +0 -74
- data/lib/badline/cartridge/game_system.rb +0 -40
- data/lib/badline/cartridge/geo_ram.rb +0 -79
- data/lib/badline/cartridge/kcs_power.rb +0 -75
- data/lib/badline/cartridge/mach5.rb +0 -32
- data/lib/badline/cartridge/magic_desk.rb +0 -30
- data/lib/badline/cartridge/ocean.rb +0 -35
- data/lib/badline/cartridge/pagefox.rb +0 -68
- data/lib/badline/cartridge/retro_replay.rb +0 -320
- data/lib/badline/cartridge/rex_utility.rb +0 -29
- data/lib/badline/cartridge/rgcd.rb +0 -58
- data/lib/badline/cartridge/simons_basic.rb +0 -35
- data/lib/badline/cartridge/standard.rb +0 -15
- data/lib/badline/cartridge/super_games.rb +0 -48
- data/lib/badline/cartridge/westermann.rb +0 -30
- data/lib/badline/cartridge/zaxxon.rb +0 -66
- data/lib/badline/cartridge.rb +0 -303
- data/lib/badline/checkpoint.rb +0 -98
- data/lib/badline/cia/fast_forward.rb +0 -60
- data/lib/badline/cia/interrupt_register.rb +0 -143
- data/lib/badline/cia/serial.rb +0 -275
- data/lib/badline/cia/state.rb +0 -47
- data/lib/badline/cia/timer.rb +0 -206
- data/lib/badline/cia.rb +0 -279
- data/lib/badline/color_memory.rb +0 -25
- data/lib/badline/control_ports.rb +0 -76
- data/lib/badline/cpu/addressing.rb +0 -131
- data/lib/badline/cpu/boundary.rb +0 -54
- data/lib/badline/cpu/core.rb +0 -165
- data/lib/badline/cpu/microcode.rb +0 -177
- data/lib/badline/cpu/operations.rb +0 -88
- data/lib/badline/cpu/saved_state.rb +0 -115
- data/lib/badline/cpu/stack_operations.rb +0 -82
- data/lib/badline/cpu.rb +0 -10
- data/lib/badline/cpu_port.rb +0 -112
- data/lib/badline/datasette.rb +0 -161
- data/lib/badline/drive/core.rb +0 -147
- data/lib/badline/drive/fast_serial.rb +0 -73
- data/lib/badline/drive/idle.rb +0 -125
- data/lib/badline/drive/idle_cpu.rb +0 -28
- data/lib/badline/drive/orbit.rb +0 -79
- data/lib/badline/drive/serial_lines.rb +0 -73
- data/lib/badline/drive/sleep.rb +0 -112
- data/lib/badline/drive/vias.rb +0 -84
- data/lib/badline/drive/watch.rb +0 -150
- data/lib/badline/drive.rb +0 -11
- data/lib/badline/drive1541/bus.rb +0 -86
- data/lib/badline/drive1541/byte_ready.rb +0 -48
- data/lib/badline/drive1541/cpu.rb +0 -11
- data/lib/badline/drive1541/disk.rb +0 -315
- data/lib/badline/drive1541/disk_state.rb +0 -86
- data/lib/badline/drive1541/disk_via.rb +0 -36
- data/lib/badline/drive1541/gcr.rb +0 -57
- data/lib/badline/drive1541/mechanism.rb +0 -313
- data/lib/badline/drive1541/mechanism_state.rb +0 -68
- data/lib/badline/drive1541/rotation.rb +0 -121
- data/lib/badline/drive1541/sector_reader.rb +0 -76
- data/lib/badline/drive1541/serial_port.rb +0 -18
- data/lib/badline/drive1541/track.rb +0 -98
- data/lib/badline/drive1541.rb +0 -111
- data/lib/badline/drive1571/bus.rb +0 -111
- data/lib/badline/drive1571/cpu.rb +0 -11
- data/lib/badline/drive1571/serial_port.rb +0 -37
- data/lib/badline/drive1571/serial_via.rb +0 -25
- data/lib/badline/drive1571/wd1770.rb +0 -120
- data/lib/badline/drive1571.rb +0 -175
- data/lib/badline/drive1581/bus.rb +0 -137
- data/lib/badline/drive1581/cpu.rb +0 -11
- data/lib/badline/drive1581/disk.rb +0 -135
- data/lib/badline/drive1581/disk_state.rb +0 -87
- data/lib/badline/drive1581/mechanism.rb +0 -117
- data/lib/badline/drive1581/serial_port.rb +0 -52
- data/lib/badline/drive1581/slot.rb +0 -78
- data/lib/badline/drive1581/track.rb +0 -100
- data/lib/badline/drive1581/track_bytes.rb +0 -75
- data/lib/badline/drive1581/wd1772/registers.rb +0 -89
- data/lib/badline/drive1581/wd1772/sector_writes.rb +0 -73
- data/lib/badline/drive1581/wd1772/sectors.rb +0 -150
- data/lib/badline/drive1581/wd1772/state.rb +0 -66
- data/lib/badline/drive1581/wd1772/stepping.rb +0 -109
- data/lib/badline/drive1581/wd1772/tracks.rb +0 -125
- data/lib/badline/drive1581/wd1772/turn.rb +0 -73
- data/lib/badline/drive1581/wd1772.rb +0 -216
- data/lib/badline/drive1581.rb +0 -233
- data/lib/badline/iec_bus.rb +0 -159
- data/lib/badline/instruction.rb +0 -334
- data/lib/badline/instruction_set/arithmetic.rb +0 -114
- data/lib/badline/instruction_set/bitwise.rb +0 -126
- data/lib/badline/instruction_set/branch.rb +0 -79
- data/lib/badline/instruction_set/flag.rb +0 -63
- data/lib/badline/instruction_set/illegal.rb +0 -270
- data/lib/badline/instruction_set/inc_dec.rb +0 -69
- data/lib/badline/instruction_set/stack.rb +0 -52
- data/lib/badline/instruction_set/transfer.rb +0 -137
- data/lib/badline/instruction_set.rb +0 -55
- data/lib/badline/interrupts.rb +0 -104
- data/lib/badline/joystick.rb +0 -25
- data/lib/badline/kernal_trap/channel.rb +0 -181
- data/lib/badline/keyboard.rb +0 -112
- data/lib/badline/ram_expansion/banking.rb +0 -30
- data/lib/badline/ram_expansion/plus256k.rb +0 -54
- data/lib/badline/ram_expansion/plus60k.rb +0 -43
- data/lib/badline/ram_expansion/unexpanded.rb +0 -28
- data/lib/badline/ram_expansion.rb +0 -21
- data/lib/badline/reu/dma/saved_state.rb +0 -50
- data/lib/badline/reu/dma.rb +0 -273
- data/lib/badline/reu/ram.rb +0 -107
- data/lib/badline/reu/saved_state.rb +0 -80
- data/lib/badline/reu/trigger.rb +0 -32
- data/lib/badline/reu.rb +0 -289
- data/lib/badline/sid/catch_up.rb +0 -120
- data/lib/badline/sid/decimator.rb +0 -64
- data/lib/badline/sid/envelope/state.rb +0 -68
- data/lib/badline/sid/envelope.rb +0 -239
- data/lib/badline/sid/filter.rb +0 -263
- data/lib/badline/sid/voice.rb +0 -77
- data/lib/badline/sid/waveform/combined.rb +0 -126
- data/lib/badline/sid/waveform/fast_forward.rb +0 -105
- data/lib/badline/sid/waveform/noise_writeback.rb +0 -122
- data/lib/badline/sid/waveform/state.rb +0 -66
- data/lib/badline/sid/waveform.rb +0 -305
- data/lib/badline/sid.rb +0 -303
- data/lib/badline/time_of_day.rb +0 -228
- data/lib/badline/traps.rb +0 -19
- data/lib/badline/via/control_lines.rb +0 -122
- data/lib/badline/via/fast_forward.rb +0 -53
- data/lib/badline/via/interrupt_register.rb +0 -67
- data/lib/badline/via/shift_register.rb +0 -180
- data/lib/badline/via/state.rb +0 -42
- data/lib/badline/via/timer1.rb +0 -131
- data/lib/badline/via/timer2.rb +0 -133
- data/lib/badline/via.rb +0 -266
- data/lib/badline/vic/bank.rb +0 -133
- data/lib/badline/vic/border_mask.rb +0 -86
- data/lib/badline/vic/collisions.rb +0 -115
- data/lib/badline/vic/color_patches.rb +0 -47
- data/lib/badline/vic/display_state.rb +0 -185
- data/lib/badline/vic/graphics_mode.rb +0 -164
- data/lib/badline/vic/graphics_shifter.rb +0 -207
- data/lib/badline/vic/register_log.rb +0 -81
- data/lib/badline/vic/registers.rb +0 -195
- data/lib/badline/vic/sequencer.rb +0 -275
- data/lib/badline/vic/sequencer_output.rb +0 -116
- data/lib/badline/vic/sequencer_state.rb +0 -89
- data/lib/badline/vic/sprite/internal_bus.rb +0 -68
- data/lib/badline/vic/sprite/saved_state.rb +0 -64
- data/lib/badline/vic/sprite/shifter.rb +0 -146
- data/lib/badline/vic/sprite/timing.rb +0 -56
- data/lib/badline/vic/sprite.rb +0 -337
- data/lib/badline/vic/sprites.rb +0 -282
- data/lib/badline/vic/sprites_state.rb +0 -57
- data/lib/badline/vic.rb +0 -853
- data/lib/badline/vic20/sound/output.rb +0 -83
- data/lib/badline/vic20/sound.rb +0 -233
- data/lib/badline/z80/arithmetic.rb +0 -117
- data/lib/badline/z80/bit_page.rb +0 -55
- data/lib/badline/z80/block_io.rb +0 -58
- data/lib/badline/z80/block_transfers.rb +0 -59
- data/lib/badline/z80/bus_cycles.rb +0 -111
- data/lib/badline/z80/core.rb +0 -113
- data/lib/badline/z80/exchanges.rb +0 -50
- data/lib/badline/z80/extended_page.rb +0 -89
- data/lib/badline/z80/flags.rb +0 -37
- data/lib/badline/z80/interrupt_acceptance.rb +0 -46
- data/lib/badline/z80/jumps.rb +0 -82
- data/lib/badline/z80/loads.rb +0 -98
- data/lib/badline/z80/main_page.rb +0 -134
- data/lib/badline/z80/registers.rb +0 -120
- data/lib/badline/z80/saved_state.rb +0 -69
- data/lib/badline/z80/shifts.rb +0 -64
- data/lib/badline/z80.rb +0 -11
- /data/lib/badline/snapshot/{fields.rb → vice/fields.rb} +0 -0
|
@@ -42,12 +42,9 @@ module Badline
|
|
|
42
42
|
# Whether the image was opened write-protected.
|
|
43
43
|
def read_only? = @read_only
|
|
44
44
|
|
|
45
|
-
#
|
|
46
|
-
#
|
|
47
|
-
|
|
48
|
-
def save_setup(out)
|
|
49
|
-
out.int(storage_kind).string(File.expand_path(@path)).boolean(@read_only).blob(@bytes + @errors.to_a)
|
|
50
|
-
end
|
|
45
|
+
# The image as its file holds it, with its error table after the
|
|
46
|
+
# blocks.
|
|
47
|
+
def contents = @bytes + @errors.to_a
|
|
51
48
|
|
|
52
49
|
# A LOAD reads only PRG files. An OPEN names the type it wants, or
|
|
53
50
|
# takes the first file of any type with a nil `type`.
|
|
@@ -5,7 +5,7 @@ module Badline
|
|
|
5
5
|
# A .g64 image: a 1541 disk's flux as raw GCR, track by track, for the
|
|
6
6
|
# true drive to read the way it reads a real disk, copy protection and
|
|
7
7
|
# all. It has no file system of its own, so only the true drive
|
|
8
|
-
# (
|
|
8
|
+
# (Drives::Model1541::Disk.from_g64) can use it. A .g71 holds a 1571 disk the
|
|
9
9
|
# same way, with "GCR-1571" for its signature and 168 half tracks,
|
|
10
10
|
# the first side's 84 and then the second's.
|
|
11
11
|
#
|
|
@@ -21,7 +21,7 @@ module Badline
|
|
|
21
21
|
# A larger one is the offset of a speed map, two bits a byte, four
|
|
22
22
|
# track bytes to a map byte, the first byte's in the top two bits, for
|
|
23
23
|
# a track whose zone changes along it. The drive passes each byte
|
|
24
|
-
# under the head at its own zone's rate (
|
|
24
|
+
# under the head at its own zone's rate (Drives::Model1541::Track).
|
|
25
25
|
#
|
|
26
26
|
# The drive writes a track at one zone, so a track written back takes
|
|
27
27
|
# that zone as its speed entry. Writing it puts it in its own block,
|
|
@@ -17,11 +17,6 @@ module Badline
|
|
|
17
17
|
@path = path
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
# What Storage.reopen needs to open the directory again.
|
|
21
|
-
def save_setup(out)
|
|
22
|
-
out.int(HOST_DIRECTORY).string(File.expand_path(@path))
|
|
23
|
-
end
|
|
24
|
-
|
|
25
20
|
def read_file(name, **)
|
|
26
21
|
entry = find(name)
|
|
27
22
|
return unless entry
|
data/lib/badline/storage/t64.rb
CHANGED
|
@@ -20,14 +20,8 @@ module Badline
|
|
|
20
20
|
raise FormatError, "Missing T64 signature" unless @bytes[0, 3] == SIGNATURE
|
|
21
21
|
end
|
|
22
22
|
|
|
23
|
-
# The host file's path, as it was opened.
|
|
24
|
-
attr_reader :path
|
|
25
|
-
|
|
26
|
-
# What Storage.reopen needs to open the archive again: its path and
|
|
27
|
-
# its bytes.
|
|
28
|
-
def save_setup(out)
|
|
29
|
-
out.int(T64_ARCHIVE).string(File.expand_path(@path)).blob(@bytes)
|
|
30
|
-
end
|
|
23
|
+
# The host file's path, as it was opened, and its bytes.
|
|
24
|
+
attr_reader :path, :bytes
|
|
31
25
|
|
|
32
26
|
def read_file(name, **)
|
|
33
27
|
pattern = Storage.matcher(name)
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module Badline
|
|
4
4
|
module Storage
|
|
5
5
|
# Stands in for a directory a detached restore leaves out
|
|
6
|
-
# (Snapshot::
|
|
6
|
+
# (Snapshot::StorageSetup): it finds no files and refuses every write
|
|
7
7
|
# as a write-protected disk does.
|
|
8
8
|
class Unavailable
|
|
9
9
|
def path = ""
|
data/lib/badline/storage.rb
CHANGED
|
@@ -11,10 +11,6 @@ require "badline/storage/g64_image"
|
|
|
11
11
|
require "badline/storage/t64"
|
|
12
12
|
require "badline/storage/tap"
|
|
13
13
|
require "badline/storage/crt_file"
|
|
14
|
-
require "badline/storage/sid_file"
|
|
15
|
-
require "badline/storage/hvsc"
|
|
16
|
-
require "badline/storage/song_lengths"
|
|
17
|
-
require "badline/storage/stil"
|
|
18
14
|
require "badline/storage/unavailable"
|
|
19
15
|
|
|
20
16
|
module Badline
|
|
@@ -36,29 +32,7 @@ module Badline
|
|
|
36
32
|
end
|
|
37
33
|
end
|
|
38
34
|
|
|
39
|
-
# The storage a snapshot's device 8 serves, by the number save_setup
|
|
40
|
-
# writes first.
|
|
41
|
-
HOST_DIRECTORY = 0
|
|
42
|
-
D64 = 1
|
|
43
|
-
D71 = 2
|
|
44
|
-
D81 = 3
|
|
45
|
-
T64_ARCHIVE = 4
|
|
46
|
-
|
|
47
35
|
class << self
|
|
48
|
-
# Opens the storage a save_setup wrote: the same directory by its
|
|
49
|
-
# path, an archive with the bytes it held, or a disk image with the
|
|
50
|
-
# bytes it held, writes and all. A detached reader gets the image
|
|
51
|
-
# write-protected, and Unavailable for a directory.
|
|
52
|
-
def reopen(input)
|
|
53
|
-
kind = input.int
|
|
54
|
-
path = input.string
|
|
55
|
-
case kind
|
|
56
|
-
when HOST_DIRECTORY then input.detached? ? Unavailable.new : HostDirectory.new(path)
|
|
57
|
-
when T64_ARCHIVE then T64.new(path, bytes: input.blob)
|
|
58
|
-
else reopen_image(kind, path, input)
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
36
|
# Folds shifted PETSCII letters to their ASCII equivalents.
|
|
63
37
|
def ascii(bytes)
|
|
64
38
|
bytes.map { |b| b.between?(0xc1, 0xda) ? b - 0x80 : b }.pack("C*")
|
|
@@ -83,17 +57,6 @@ module Badline
|
|
|
83
57
|
[base.to_s, FILE_TYPES[type.to_s.strip[0]&.upcase]]
|
|
84
58
|
end
|
|
85
59
|
|
|
86
|
-
def reopen_image(kind, path, input)
|
|
87
|
-
read_only = input.boolean? || input.detached?
|
|
88
|
-
bytes = input.blob
|
|
89
|
-
case kind
|
|
90
|
-
when D64 then D64Image.new(path, read_only:, bytes:)
|
|
91
|
-
when D71 then D71Image.new(path, read_only:, bytes:)
|
|
92
|
-
when D81 then D81Image.new(path, read_only:, bytes:)
|
|
93
|
-
else raise Snapshot::FormatError, "unknown storage #{kind} in the state"
|
|
94
|
-
end
|
|
95
|
-
end
|
|
96
|
-
|
|
97
60
|
# CBM-style filename pattern: "*" and "?" wildcards, case-insensitive.
|
|
98
61
|
# The DOS stops comparing at the first "*", so whatever follows it
|
|
99
62
|
# is ignored.
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Support
|
|
5
|
+
# A Checkpoint of a C128, in either mode: a C64's components, with the
|
|
6
|
+
# whole 128K of RAM in place of bank 0 and the colour RAM bank the 8502
|
|
7
|
+
# sees, and besides them the VDC's registers and beam, the VDC's RAM, the
|
|
8
|
+
# MMU's registers and the Z80.
|
|
9
|
+
module C128Checkpoint
|
|
10
|
+
COMPONENTS = %w[cpu ram color_ram display vic cia1 cia2 sid vdc vdc_ram mmu z80].freeze
|
|
11
|
+
|
|
12
|
+
def self.take(machine)
|
|
13
|
+
Checkpoint.new(machine.cycles, [
|
|
14
|
+
Checkpoint.fnv1a(Checkpoint.cpu_state(machine.cpu)),
|
|
15
|
+
Checkpoint.fnv1a(Checkpoint.ram(machine.ram, 0x20000)),
|
|
16
|
+
Checkpoint.fnv1a(Checkpoint.color_ram(machine.address_bus.color_ram, 0xd800)),
|
|
17
|
+
Checkpoint.fnv1a(machine.vic.display),
|
|
18
|
+
Checkpoint.fnv1a(Checkpoint.vic_state(machine.vic)),
|
|
19
|
+
Checkpoint.fnv1a(Checkpoint.cia_state(machine.cia1)),
|
|
20
|
+
Checkpoint.fnv1a(Checkpoint.cia_state(machine.cia2)),
|
|
21
|
+
Checkpoint.fnv1a(Array.new(0x20) { |reg| machine.sid.register(reg) }),
|
|
22
|
+
Checkpoint.fnv1a(machine.vdc.registers + [machine.vdc.frame]),
|
|
23
|
+
Checkpoint.fnv1a(machine.vdc.ram),
|
|
24
|
+
Checkpoint.fnv1a(machine.mmu.registers),
|
|
25
|
+
Checkpoint.fnv1a(z80_state(machine.z80))
|
|
26
|
+
], COMPONENTS)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.parse(line) = Checkpoint.parse(line, COMPONENTS)
|
|
30
|
+
|
|
31
|
+
def self.z80_state(z80)
|
|
32
|
+
[z80.pc, z80.sp, z80.af, z80.bc, z80.de, z80.hl, z80.ix, z80.iy, z80.af_alt, z80.bc_alt, z80.de_alt,
|
|
33
|
+
z80.hl_alt, z80.i, z80.r, z80.im, flag(z80.iff1), flag(z80.iff2), flag(z80.halted), z80.cycles]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def self.flag(value) = value == true ? 1 : 0
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Support
|
|
5
|
+
# A digest of the machine's state at one cycle, for comparing two runs of
|
|
6
|
+
# the same scenario, on two builds or two revisions. Each component is
|
|
7
|
+
# hashed on its own with 32-bit FNV-1a, so a mismatch names the part of the
|
|
8
|
+
# machine that went its own way. Nothing is read through a chip's bus
|
|
9
|
+
# interface, so taking a checkpoint leaves the machine as it was.
|
|
10
|
+
#
|
|
11
|
+
# Checkpoint.take digests a C64's components, COMPONENTS.
|
|
12
|
+
# Vic20Checkpoint and C128Checkpoint digest the other families', each
|
|
13
|
+
# with a list of its own, which a checkpoint carries as +components+.
|
|
14
|
+
#
|
|
15
|
+
# Colour RAM is digested as the four bits each cell stores: the upper
|
|
16
|
+
# nibble a CPU read sees comes off the open bus.
|
|
17
|
+
class Checkpoint
|
|
18
|
+
COMPONENTS = %w[cpu ram color_ram display vic cia1 cia2 sid].freeze
|
|
19
|
+
|
|
20
|
+
FNV_OFFSET = 0x811c9dc5
|
|
21
|
+
FNV_PRIME = 0x01000193
|
|
22
|
+
|
|
23
|
+
attr_reader :cycle, :digests, :components
|
|
24
|
+
|
|
25
|
+
class << self
|
|
26
|
+
def take(computer)
|
|
27
|
+
new(computer.cycles, [
|
|
28
|
+
fnv1a(cpu_state(computer.cpu)),
|
|
29
|
+
fnv1a(ram(computer.ram, 0x10000)),
|
|
30
|
+
fnv1a(color_ram(computer.address_bus.color_ram, 0xd800)),
|
|
31
|
+
fnv1a(computer.vic.display),
|
|
32
|
+
fnv1a(vic_state(computer.vic)),
|
|
33
|
+
fnv1a(cia_state(computer.cia1)),
|
|
34
|
+
fnv1a(cia_state(computer.cia2)),
|
|
35
|
+
fnv1a(Array.new(0x20) { |reg| computer.sid.register(reg) })
|
|
36
|
+
])
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Reads a line written by #to_s, with a digest for each of
|
|
40
|
+
# `components`.
|
|
41
|
+
def parse(line, components = COMPONENTS)
|
|
42
|
+
fields = line.split
|
|
43
|
+
digests = components.map do |name|
|
|
44
|
+
field = fields.find { |f| f.start_with?("#{name}=") }
|
|
45
|
+
raise ArgumentError, "no #{name} digest in #{line.inspect}" unless field
|
|
46
|
+
|
|
47
|
+
field.split("=").last.to_i(16)
|
|
48
|
+
end
|
|
49
|
+
new(fields.first.to_i, digests, components)
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def fnv1a(values)
|
|
53
|
+
hash = FNV_OFFSET
|
|
54
|
+
values.each { |value| hash = ((hash ^ (value & 0xffffffff)) * FNV_PRIME) & 0xffffffff }
|
|
55
|
+
hash
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# The registers and cycle count of a 6502 or an 8502.
|
|
59
|
+
def cpu_state(cpu)
|
|
60
|
+
[cpu.program_counter, cpu.a, cpu.x, cpu.y, cpu.stack_pointer, cpu.p, cpu.cycles]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# The first `length` bytes of `memory`.
|
|
64
|
+
def ram(memory, length)
|
|
65
|
+
Array.new(length) { |addr| memory.peek(addr) }
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# The 1K of colour RAM at `start`.
|
|
69
|
+
def color_ram(memory, start)
|
|
70
|
+
Array.new(0x400) { |offset| memory.nibble(start + offset) }
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# A VIC-II's or a VIC-I's registers and beam position.
|
|
74
|
+
def vic_state(vic)
|
|
75
|
+
vic.register_file + [vic.rasterline, vic.column]
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def cia_state(cia)
|
|
79
|
+
start = cia.start
|
|
80
|
+
[cia.peek(start), cia.peek(start + 1), cia.peek(start + 2), cia.peek(start + 3),
|
|
81
|
+
cia.timer_a, cia.timer_a_latch, cia.timer_b, cia.timer_b_latch, cia.serial.data,
|
|
82
|
+
cia.control_a.value, cia.control_b.value, cia.interrupt_status.value,
|
|
83
|
+
cia.interrupt_control.value] + cia.time_of_day.registers
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def initialize(cycle, digests, components = COMPONENTS)
|
|
88
|
+
@cycle = cycle
|
|
89
|
+
@digests = digests
|
|
90
|
+
@components = components
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# The components whose digests differ from `other`'s.
|
|
94
|
+
def differences(other)
|
|
95
|
+
components.each_index.reject { |i| digests[i] == other.digests[i] }.map { |i| components[i] }
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def ==(other)
|
|
99
|
+
other.is_a?(Checkpoint) && cycle == other.cycle && components == other.components && digests == other.digests
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def to_s
|
|
103
|
+
fields = components.each_index.map { |i| "#{components[i]}=#{digests[i].to_s(16).rjust(8, '0')}" }
|
|
104
|
+
"#{cycle} #{fields.join(' ')}"
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Support
|
|
5
|
+
# A Checkpoint of a VIC-20: its CPU, the 48K of RAM the bus decodes, the
|
|
6
|
+
# colour RAM, the VIC-I's display and registers, both VIAs and the
|
|
7
|
+
# sound. The sound's shift registers and noise LFSR move only while it
|
|
8
|
+
# records, so a run that wants them digested records it.
|
|
9
|
+
module Vic20Checkpoint
|
|
10
|
+
COMPONENTS = %w[cpu ram color_ram display vic via1 via2 sound].freeze
|
|
11
|
+
|
|
12
|
+
def self.take(machine)
|
|
13
|
+
Checkpoint.new(machine.cycles, [
|
|
14
|
+
Checkpoint.fnv1a(Checkpoint.cpu_state(machine.cpu)),
|
|
15
|
+
Checkpoint.fnv1a(Checkpoint.ram(machine.ram, 0xc000)),
|
|
16
|
+
Checkpoint.fnv1a(Checkpoint.color_ram(machine.bus.color_ram, 0)),
|
|
17
|
+
Checkpoint.fnv1a(machine.vic.display),
|
|
18
|
+
Checkpoint.fnv1a(Checkpoint.vic_state(machine.vic)),
|
|
19
|
+
Checkpoint.fnv1a(via_state(machine.via1)),
|
|
20
|
+
Checkpoint.fnv1a(via_state(machine.via2)),
|
|
21
|
+
Checkpoint.fnv1a(sound_state(machine.sound))
|
|
22
|
+
], COMPONENTS)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def self.parse(line) = Checkpoint.parse(line, COMPONENTS)
|
|
26
|
+
|
|
27
|
+
def self.via_state(via)
|
|
28
|
+
[via.port_a_output, via.port_b_output, via.timer1, via.timer1_latch, via.timer2,
|
|
29
|
+
via.shift_register.data, via.acr, via.pcr, via.interrupt_flags, via.interrupt_enable]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def self.sound_state(sound)
|
|
33
|
+
[sound.volume, sound.shift_register(0), sound.shift_register(1), sound.shift_register(2),
|
|
34
|
+
sound.shift_register(3), sound.lfsr]
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
data/lib/badline/version.rb
CHANGED
|
@@ -4,11 +4,11 @@ module Badline
|
|
|
4
4
|
class Vic20
|
|
5
5
|
# What plugs into the VIC-20 besides its chips: cartridge ROM in the
|
|
6
6
|
# expansion blocks, the disk device 8 serves through the KERNAL traps
|
|
7
|
-
# (
|
|
8
|
-
# (
|
|
7
|
+
# (C64::KernalTraps), and a true 1541 or 1581 on the serial bus
|
|
8
|
+
# (C64::TrueDrives).
|
|
9
9
|
module Attachments
|
|
10
|
-
include
|
|
11
|
-
include
|
|
10
|
+
include C64::TrueDrives
|
|
11
|
+
include C64::KernalTraps
|
|
12
12
|
|
|
13
13
|
# The cycle by which a 1541 switched on with the machine has run its
|
|
14
14
|
# DOS's reset, the RAM test and the ROM checksum, and waits on the
|
|
@@ -46,7 +46,7 @@ module Badline
|
|
|
46
46
|
# A 1581 plugged in, as a 1541 does, holds the machine's on_init
|
|
47
47
|
# handlers back until its DOS has booted.
|
|
48
48
|
def drive1581_attached
|
|
49
|
-
@init_threshold = [@init_threshold,
|
|
49
|
+
@init_threshold = [@init_threshold, Drives::Model1581::BOOT_CYCLES].max if @cycles < @init_threshold
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
52
|
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class Vic20
|
|
5
|
+
class Bus
|
|
6
|
+
# The bus's state for a snapshot.
|
|
7
|
+
module SavedState
|
|
8
|
+
# The RAM, the colour RAM, the byte each side's data lines hold and the
|
|
9
|
+
# cartridge's ROM chips, for a snapshot. The expansion blocks are how
|
|
10
|
+
# the machine was built.
|
|
11
|
+
def save_state(out)
|
|
12
|
+
out.marker("VIC20 BUS")
|
|
13
|
+
@ram.save_state(out)
|
|
14
|
+
out.blob(@color_ram.cells).int(@data).int(@video_data).int(@roms.length)
|
|
15
|
+
@roms.each do |rom|
|
|
16
|
+
out.int(rom.start)
|
|
17
|
+
rom.save_state(out)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def load_state(input)
|
|
22
|
+
input.marker("VIC20 BUS")
|
|
23
|
+
@ram.load_state(input)
|
|
24
|
+
input.blob_into(@color_ram.cells)
|
|
25
|
+
@data = input.int
|
|
26
|
+
@video_data = input.int
|
|
27
|
+
chips = Array.new(input.int) { [input.int, input.blob] }
|
|
28
|
+
@roms = []
|
|
29
|
+
chips.each { |chip| @roms << ROM.new(chip[1], length: chip[1].length, start: chip[0]) }
|
|
30
|
+
map_pages
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
data/lib/badline/vic20/bus.rb
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "badline/vic20/bus/saved_state"
|
|
4
|
+
|
|
3
5
|
module Badline
|
|
4
6
|
class Vic20
|
|
5
7
|
# The CPU's bus:
|
|
@@ -27,6 +29,7 @@ module Badline
|
|
|
27
29
|
# Writes to ROM and to empty spots go nowhere.
|
|
28
30
|
class Bus
|
|
29
31
|
include Addressable
|
|
32
|
+
include SavedState
|
|
30
33
|
|
|
31
34
|
# The pages each expansion block covers, as [first page, count].
|
|
32
35
|
BLOCKS = {
|
|
@@ -215,31 +218,6 @@ module Badline
|
|
|
215
218
|
@ram.clear!(RAM_POWER_ON)
|
|
216
219
|
end
|
|
217
220
|
|
|
218
|
-
# The RAM, the colour RAM, the byte each side's data lines hold and the
|
|
219
|
-
# cartridge's ROM chips, for a snapshot. The expansion blocks are how
|
|
220
|
-
# the machine was built.
|
|
221
|
-
def save_state(out)
|
|
222
|
-
out.marker("VIC20 BUS")
|
|
223
|
-
@ram.save_state(out)
|
|
224
|
-
out.blob(@color_ram.cells).int(@data).int(@video_data).int(@roms.length)
|
|
225
|
-
@roms.each do |rom|
|
|
226
|
-
out.int(rom.start)
|
|
227
|
-
rom.save_state(out)
|
|
228
|
-
end
|
|
229
|
-
end
|
|
230
|
-
|
|
231
|
-
def load_state(input)
|
|
232
|
-
input.marker("VIC20 BUS")
|
|
233
|
-
@ram.load_state(input)
|
|
234
|
-
input.blob_into(@color_ram.cells)
|
|
235
|
-
@data = input.int
|
|
236
|
-
@video_data = input.int
|
|
237
|
-
chips = Array.new(input.int) { [input.int, input.blob] }
|
|
238
|
-
@roms = []
|
|
239
|
-
chips.each { |chip| @roms << ROM.new(chip[1], length: chip[1].length, start: chip[0]) }
|
|
240
|
-
map_pages
|
|
241
|
-
end
|
|
242
|
-
|
|
243
221
|
# Whether +block+ (BLOCKS) holds RAM.
|
|
244
222
|
def ram?(block) = @blocks.include?(block)
|
|
245
223
|
|
data/lib/badline/vic20/cpu.rb
CHANGED
|
@@ -16,12 +16,12 @@ module Badline
|
|
|
16
16
|
# on VIA 1's PA6, its motor runs while VIA 1's CA2 is low, and VIA 2's
|
|
17
17
|
# PB3 drives its write line, the same pin as a keyboard column.
|
|
18
18
|
module PortWiring
|
|
19
|
-
# The lines the machine pulls, as
|
|
19
|
+
# The lines the machine pulls, as Drives::SerialBus host lines.
|
|
20
20
|
def serial_lines
|
|
21
21
|
lines = 0
|
|
22
|
-
lines |=
|
|
23
|
-
lines |=
|
|
24
|
-
lines |=
|
|
22
|
+
lines |= Drives::SerialBus::HOST_ATN_OUT if @via1.port_a_output.anybits?(0x80)
|
|
23
|
+
lines |= Drives::SerialBus::HOST_CLK_OUT if @via2.ca2_output
|
|
24
|
+
lines |= Drives::SerialBus::HOST_DATA_OUT if @via2.cb2_output
|
|
25
25
|
lines
|
|
26
26
|
end
|
|
27
27
|
|
|
@@ -1,23 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "badline/snapshot/vic20_setup"
|
|
4
|
+
|
|
3
5
|
module Badline
|
|
4
6
|
class Vic20
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
# The RAM expansion of the machine a State from #snapshot was taken
|
|
8
|
-
# of, a key of Bus::RAM_CONFIGURATIONS.
|
|
9
|
-
def self.setup(state)
|
|
10
|
-
input = Snapshot::StateReader.new(state)
|
|
11
|
-
input.marker(MARKER)
|
|
12
|
-
input.check_stamp
|
|
13
|
-
SavedState.read_ram(input)
|
|
14
|
-
end
|
|
7
|
+
# How the machine a State from #snapshot was taken of was built.
|
|
8
|
+
def self.setup(state) = Snapshot::Vic20Setup.from(state)
|
|
15
9
|
|
|
16
10
|
# A new machine, built as the one a State from #snapshot was taken of,
|
|
17
11
|
# at that state.
|
|
18
|
-
def self.restored(state) =
|
|
12
|
+
def self.restored(state) = setup(state).build.apply_state(state)
|
|
19
13
|
|
|
20
|
-
# The whole machine's state for a snapshot, as
|
|
14
|
+
# The whole machine's state for a snapshot, as C64's: the
|
|
21
15
|
# machine's own latches, the bus with its RAM and cartridge ROM, the
|
|
22
16
|
# VIC with its sound, both VIAs, the CPU, the datasette and its tape,
|
|
23
17
|
# the disk device 8 serves through the traps, and a true 1541. The
|
|
@@ -26,14 +20,6 @@ module Badline
|
|
|
26
20
|
# and callbacks, whether the display renders, whether the sound
|
|
27
21
|
# records, and whether the datasette records.
|
|
28
22
|
module SavedState
|
|
29
|
-
RAM_CONFIGURATIONS = Bus::RAM_CONFIGURATIONS.keys.freeze
|
|
30
|
-
|
|
31
|
-
def self.read_ram(input)
|
|
32
|
-
RAM_CONFIGURATIONS.fetch(input.int)
|
|
33
|
-
rescue IndexError
|
|
34
|
-
raise Snapshot::FormatError, "the state names a VIC-20 RAM expansion badline doesn't know"
|
|
35
|
-
end
|
|
36
|
-
|
|
37
23
|
# How many more on_init handlers the machine a State was taken of had
|
|
38
24
|
# yet to run than this one has. Nil until the machine is restored.
|
|
39
25
|
attr_reader :init_handlers_lost
|
|
@@ -49,7 +35,7 @@ module Badline
|
|
|
49
35
|
# Raises Snapshot::FormatError for a state of another machine or RAM
|
|
50
36
|
# expansion.
|
|
51
37
|
def restore(state)
|
|
52
|
-
|
|
38
|
+
check_setup(Vic20.setup(state))
|
|
53
39
|
Vic20.restored(state)
|
|
54
40
|
apply_state(state)
|
|
55
41
|
end
|
|
@@ -64,8 +50,8 @@ module Badline
|
|
|
64
50
|
end
|
|
65
51
|
|
|
66
52
|
def save_state(out)
|
|
67
|
-
out.marker(MARKER).stamp
|
|
68
|
-
|
|
53
|
+
out.marker(Snapshot::Vic20Setup::MARKER).stamp
|
|
54
|
+
Snapshot::Vic20Setup.new(ram: @ram_configuration).write(out)
|
|
69
55
|
out.int(@cycles).boolean(@nmi_asserted).boolean(!@pending_keys.nil?)
|
|
70
56
|
out.ints(@pending_keys) if @pending_keys
|
|
71
57
|
out.int(@cycles <= @init_threshold ? @init_handlers.length : 0)
|
|
@@ -76,15 +62,15 @@ module Badline
|
|
|
76
62
|
@via2.save_state(out)
|
|
77
63
|
@cpu.save_state(out)
|
|
78
64
|
@datasette.save_state(out)
|
|
79
|
-
|
|
65
|
+
save_trap_dos(out)
|
|
80
66
|
save_drive1541(out)
|
|
81
67
|
save_drive1581(out)
|
|
82
68
|
end
|
|
83
69
|
|
|
84
70
|
def load_state(input)
|
|
85
|
-
input.marker(MARKER)
|
|
71
|
+
input.marker(Snapshot::Vic20Setup::MARKER)
|
|
86
72
|
input.check_stamp
|
|
87
|
-
|
|
73
|
+
check_setup(Snapshot::Vic20Setup.read(input))
|
|
88
74
|
@cycles = input.int
|
|
89
75
|
@nmi_asserted = input.boolean?
|
|
90
76
|
@pending_keys = nil
|
|
@@ -98,7 +84,7 @@ module Badline
|
|
|
98
84
|
@cpu.load_state(input)
|
|
99
85
|
via_written
|
|
100
86
|
@datasette.load_state(input)
|
|
101
|
-
|
|
87
|
+
load_trap_dos(input)
|
|
102
88
|
load_drive1541(input)
|
|
103
89
|
load_drive1581(input)
|
|
104
90
|
end
|
|
@@ -114,10 +100,10 @@ module Badline
|
|
|
114
100
|
@drive1541.save_state(out)
|
|
115
101
|
end
|
|
116
102
|
|
|
117
|
-
def
|
|
118
|
-
return if ram == @ram_configuration
|
|
103
|
+
def check_setup(setup)
|
|
104
|
+
return if setup.ram == @ram_configuration
|
|
119
105
|
|
|
120
|
-
raise Snapshot::FormatError, "the state is of a VIC-20 with #{ram} RAM, not #{@ram_configuration}"
|
|
106
|
+
raise Snapshot::FormatError, "the state is of a VIC-20 with #{setup.ram} RAM, not #{@ram_configuration}"
|
|
121
107
|
end
|
|
122
108
|
end
|
|
123
109
|
end
|
|
@@ -38,8 +38,8 @@ module Badline
|
|
|
38
38
|
def serial_inputs
|
|
39
39
|
low = @serial_bus.low_lines
|
|
40
40
|
value = 0x03
|
|
41
|
-
value &= ~0x01 if low.anybits?(
|
|
42
|
-
value &= ~0x02 if low.anybits?(
|
|
41
|
+
value &= ~0x01 if low.anybits?(Drives::SerialBus::CLK)
|
|
42
|
+
value &= ~0x02 if low.anybits?(Drives::SerialBus::DATA)
|
|
43
43
|
value
|
|
44
44
|
end
|
|
45
45
|
end
|
data/lib/badline/vic20.rb
CHANGED
|
@@ -6,8 +6,8 @@ require "badline/vic20/cpu"
|
|
|
6
6
|
require "badline/vic20/keyboard_via_ports"
|
|
7
7
|
require "badline/vic20/port_wiring"
|
|
8
8
|
require "badline/vic20/user_via_ports"
|
|
9
|
-
require "badline/
|
|
10
|
-
require "badline/
|
|
9
|
+
require "badline/chips/vic_i"
|
|
10
|
+
require "badline/chips/vic_i/sound"
|
|
11
11
|
require "badline/vic20/saved_state"
|
|
12
12
|
|
|
13
13
|
module Badline
|
|
@@ -36,6 +36,11 @@ module Badline
|
|
|
36
36
|
|
|
37
37
|
def ram = @bus.ram
|
|
38
38
|
|
|
39
|
+
# Reads and writes memory as the CPU sees it, through the bus.
|
|
40
|
+
def peek(addr) = @bus.peek(addr)
|
|
41
|
+
|
|
42
|
+
def poke(addr, value) = @bus.poke(addr, value)
|
|
43
|
+
|
|
39
44
|
def family = :vic20
|
|
40
45
|
|
|
41
46
|
# The one control port's joystick, which the front end's second
|
|
@@ -48,26 +53,26 @@ module Badline
|
|
|
48
53
|
# +ram+ names the RAM expansion, one of Bus::RAM_CONFIGURATIONS.
|
|
49
54
|
def initialize(ram: :unexpanded, debug: false)
|
|
50
55
|
@ram_configuration = ram
|
|
51
|
-
@vic =
|
|
52
|
-
@keyboard = Keyboard.new(matrix: KeyboardVIAPorts::MATRIX)
|
|
53
|
-
@joystick1 = Joystick.new
|
|
54
|
-
@iec_bus =
|
|
55
|
-
@datasette = Datasette.new
|
|
56
|
-
@via1 = VIA.new(start: 0x9000, peripheral: UserVIAPorts.new(joystick: @joystick1, serial_bus: @iec_bus,
|
|
57
|
-
|
|
56
|
+
@vic = Chips::VICI.new
|
|
57
|
+
@keyboard = Input::Keyboard.new(matrix: KeyboardVIAPorts::MATRIX)
|
|
58
|
+
@joystick1 = Input::Joystick.new
|
|
59
|
+
@iec_bus = Drives::SerialBus.new
|
|
60
|
+
@datasette = Drives::Datasette.new
|
|
61
|
+
@via1 = Chips::VIA.new(start: 0x9000, peripheral: UserVIAPorts.new(joystick: @joystick1, serial_bus: @iec_bus,
|
|
62
|
+
datasette: @datasette))
|
|
58
63
|
keyboard_ports = KeyboardVIAPorts.new(keyboard: @keyboard, joystick: @joystick1)
|
|
59
|
-
@via2 = VIA.new(start: 0x9000, peripheral: keyboard_ports)
|
|
64
|
+
@via2 = Chips::VIA.new(start: 0x9000, peripheral: keyboard_ports)
|
|
60
65
|
keyboard_ports.connect(@via2)
|
|
61
66
|
@bus = Bus.new(vic: @vic, via1: @via1, via2: @via2, blocks: Bus::RAM_CONFIGURATIONS.fetch(ram))
|
|
62
67
|
@vic.connect(@bus)
|
|
63
68
|
@cpu = CPU.new(@bus, debug:)
|
|
64
69
|
@cycles = 0
|
|
65
|
-
@sound = Sound.new(self, @vic.profile.clock_hz)
|
|
70
|
+
@sound = Chips::VICI::Sound.new(self, @vic.profile.clock_hz)
|
|
66
71
|
@vic.sound = @sound
|
|
67
72
|
@nmi_asserted = false
|
|
68
73
|
@init_handlers = []
|
|
69
74
|
@pending_keys = nil
|
|
70
|
-
@
|
|
75
|
+
@dos = nil
|
|
71
76
|
@serial_trap = nil
|
|
72
77
|
@save_trap = nil
|
|
73
78
|
@capture_output = nil
|
|
@@ -111,7 +116,7 @@ module Badline
|
|
|
111
116
|
# xvic draws them.
|
|
112
117
|
def timing
|
|
113
118
|
profile = @vic.profile
|
|
114
|
-
width = profile.cycles_per_line *
|
|
119
|
+
width = profile.cycles_per_line * Chips::VICI::PIXELS_PER_CYCLE
|
|
115
120
|
blanked = profile.blanked_lines
|
|
116
121
|
Timing.new(clock_hz: profile.clock_hz, cycles_per_line: profile.cycles_per_line,
|
|
117
122
|
lines_per_frame: profile.lines_per_frame,
|
|
@@ -148,7 +153,7 @@ module Badline
|
|
|
148
153
|
@via1.reset!
|
|
149
154
|
@via2.reset!
|
|
150
155
|
via_written
|
|
151
|
-
@
|
|
156
|
+
@dos&.reset!
|
|
152
157
|
@drive1541&.reset!
|
|
153
158
|
@drive1581&.reset!
|
|
154
159
|
@nmi_asserted = false
|