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/roms/README
CHANGED
|
@@ -20,7 +20,7 @@ The character generator ROM.
|
|
|
20
20
|
kernal-sx64.rom
|
|
21
21
|
---------------
|
|
22
22
|
The SX-64's KERNAL, 251104-04. It boots with the SX-64's banner and
|
|
23
|
-
colours, and loads from device 8 rather than tape.
|
|
23
|
+
colours, and loads from device 8 rather than tape. C64.new(kernal:
|
|
24
24
|
:sx64) fits it, as --model sx64 does.
|
|
25
25
|
|
|
26
26
|
Downloaded from
|
|
@@ -32,7 +32,7 @@ kernal-pet64.rom
|
|
|
32
32
|
The KERNAL of the PET 64, 4064 and Educator 64, 901246-01. It boots
|
|
33
33
|
with the "**** COMMODORE 4064 BASIC V2.0 ****" banner and a white
|
|
34
34
|
cursor, and its interrupt routine keeps the border, background and
|
|
35
|
-
sprite colours black unless bit 7 of $0286 is set.
|
|
35
|
+
sprite colours black unless bit 7 of $0286 is set. C64.new(kernal:
|
|
36
36
|
:pet64) fits it, as --model pet64 does.
|
|
37
37
|
|
|
38
38
|
Downloaded from
|
|
@@ -45,7 +45,7 @@ The C64GS's BASIC and KERNAL, 390852-01, 16 KB: BASIC for $A000-$BFFF
|
|
|
45
45
|
followed by the KERNAL for $E000-$FFFF. Its BASIC is 901226-01's but
|
|
46
46
|
for 30 unused bytes. Its KERNAL is 901227-03's with most changes in
|
|
47
47
|
$F72C-$FC92, the cassette routines' place, and many jumps redirected to
|
|
48
|
-
I/O error 5.
|
|
48
|
+
I/O error 5. C64.new(kernal: :gs) fits both, as --model c64gs does.
|
|
49
49
|
|
|
50
50
|
Downloaded from
|
|
51
51
|
https://www.zimmers.net/anonftp/pub/cbm/firmware/computers/c64/64gs.390852-01.bin
|
|
@@ -54,7 +54,7 @@ MD5 049e657afafbdd802e8c6a4f88f3d730.
|
|
|
54
54
|
dos1541.rom
|
|
55
55
|
-----------
|
|
56
56
|
The 1541 disk drive's DOS 2.6, 16 KB for $C000-$FFFF: 325302-01
|
|
57
|
-
($C000-$DFFF) followed by 901229-05 ($E000-$FFFF).
|
|
57
|
+
($C000-$DFFF) followed by 901229-05 ($E000-$FFFF). Drives::Model1541 loads it.
|
|
58
58
|
|
|
59
59
|
Both halves downloaded from
|
|
60
60
|
https://www.zimmers.net/anonftp/pub/cbm/firmware/drives/new/1541/
|
|
@@ -64,7 +64,7 @@ SHA-1 ab16f56989b27d89babe5f89c5a8cb3da71a82f0.
|
|
|
64
64
|
dos1571.rom
|
|
65
65
|
-----------
|
|
66
66
|
The 1571 disk drive's DOS 3.0, 310654-05, 32 KB for $8000-$FFFF.
|
|
67
|
-
|
|
67
|
+
Drives::Model1571 loads it.
|
|
68
68
|
|
|
69
69
|
Downloaded from
|
|
70
70
|
https://www.zimmers.net/anonftp/pub/cbm/firmware/drives/new/1571/1571-rom.310654-05.bin
|
|
@@ -73,7 +73,7 @@ SHA-1 f1be619c106641a685f6609e4d43d6fc9eac1e70.
|
|
|
73
73
|
dos1581.rom
|
|
74
74
|
-----------
|
|
75
75
|
The 1581 disk drive's DOS, 318045-02, 32 KB for $8000-$FFFF.
|
|
76
|
-
|
|
76
|
+
Drives::Model1581 loads it.
|
|
77
77
|
|
|
78
78
|
Downloaded from
|
|
79
79
|
https://www.zimmers.net/anonftp/pub/cbm/firmware/drives/new/1581/1581-rom.318045-02.bin
|
|
@@ -132,3 +132,41 @@ c128/character.rom
|
|
|
132
132
|
The character generator ROM, 390059-01 (characters.390059-01.bin),
|
|
133
133
|
8 KB: the C64's set, the same as character.rom, followed by the C128's.
|
|
134
134
|
SHA-1 29ed066d513f2d5c09ff26d9166ba23c2afb2b3f.
|
|
135
|
+
|
|
136
|
+
Commodore 264 series ROMs
|
|
137
|
+
=========================
|
|
138
|
+
|
|
139
|
+
Downloaded from
|
|
140
|
+
https://www.zimmers.net/anonftp/pub/cbm/firmware/computers/plus4/
|
|
141
|
+
for the Plus/4, the C16 and the C116, which share BASIC and the KERNAL.
|
|
142
|
+
Nothing maps them yet.
|
|
143
|
+
|
|
144
|
+
plus4/basic.rom
|
|
145
|
+
---------------
|
|
146
|
+
BASIC 3.5, 318006-01 (basic.318006-01.bin), for $8000-$BFFF in ROM
|
|
147
|
+
bank 0.
|
|
148
|
+
SHA-1 161c96b4ad20f3a4f2321808e37a5ded26a135dd.
|
|
149
|
+
|
|
150
|
+
plus4/kernal-pal.rom
|
|
151
|
+
--------------------
|
|
152
|
+
The PAL KERNAL, 318004-05 (kernal.318004-05.bin), for $C000-$FFFF in
|
|
153
|
+
ROM bank 0, with the character set from $D000.
|
|
154
|
+
SHA-1 7c7e07f016391174a557e790c4ef1cbe33512cdb.
|
|
155
|
+
|
|
156
|
+
plus4/kernal-ntsc.rom
|
|
157
|
+
---------------------
|
|
158
|
+
The NTSC KERNAL, 318005-05 (kernal.318005-05.bin), for $C000-$FFFF in
|
|
159
|
+
ROM bank 0.
|
|
160
|
+
SHA-1 a3d9e5be091b98de39a046ab167fb7632d053682.
|
|
161
|
+
|
|
162
|
+
plus4/function-low.rom
|
|
163
|
+
----------------------
|
|
164
|
+
The Plus/4's 3-plus-1 function ROM, low half, 317053-01
|
|
165
|
+
(3-plus-1.317053-01.bin), for $8000-$BFFF in ROM bank 1.
|
|
166
|
+
SHA-1 3b69f6e7cb4c18bb08e203fb18b7dabfa853390f.
|
|
167
|
+
|
|
168
|
+
plus4/function-high.rom
|
|
169
|
+
-----------------------
|
|
170
|
+
The Plus/4's 3-plus-1 function ROM, high half, 317054-01
|
|
171
|
+
(3-plus-1.317054-01.bin), for $C000-$FFFF in ROM bank 1.
|
|
172
|
+
SHA-1 0ad7ac2db7da692d972e586ca0dfd747d82c7693.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/lib/badline/sdl.rb
CHANGED
|
@@ -3,10 +3,10 @@
|
|
|
3
3
|
require "digest"
|
|
4
4
|
|
|
5
5
|
module Badline
|
|
6
|
-
module
|
|
6
|
+
module SIDTune
|
|
7
7
|
# PSID/RSID tunes: a memory image plus the addresses of the routines
|
|
8
8
|
# that initialise it and produce one frame of music.
|
|
9
|
-
class
|
|
9
|
+
class File
|
|
10
10
|
include IntegerHelper
|
|
11
11
|
|
|
12
12
|
class FormatError < StandardError; end
|
|
@@ -147,7 +147,7 @@ module Badline
|
|
|
147
147
|
attr_reader :format
|
|
148
148
|
|
|
149
149
|
def initialize(path)
|
|
150
|
-
@bytes = File.binread(path).bytes
|
|
150
|
+
@bytes = ::File.binread(path).bytes
|
|
151
151
|
@format = @bytes[0, 4].pack("C*")
|
|
152
152
|
raise FormatError, "Missing PSID or RSID signature" unless %w[PSID RSID].include?(@format)
|
|
153
153
|
raise FormatError, "Truncated header" if truncated?
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Badline
|
|
4
|
-
module
|
|
4
|
+
module SIDTune
|
|
5
5
|
# The layout of an HVSC collection: tunes in directories under its root,
|
|
6
6
|
# and databases about them in `DOCUMENTS`. A tune's HVSC path is its path
|
|
7
7
|
# from the root, as `/MUSICIANS/H/Hubbard_Rob/Commando.sid`.
|
|
@@ -10,15 +10,15 @@ module Badline
|
|
|
10
10
|
# The named file in the DOCUMENTS directory of a collection above the
|
|
11
11
|
# tune, or else of the one `$HVSC_BASE` points at.
|
|
12
12
|
def document(tune_path, name)
|
|
13
|
-
candidates(tune_path).map { |dir| File.join(dir, "DOCUMENTS", name) }
|
|
14
|
-
.find { |path| File.file?(path) }
|
|
13
|
+
candidates(tune_path).map { |dir| ::File.join(dir, "DOCUMENTS", name) }
|
|
14
|
+
.find { |path| ::File.file?(path) }
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
# The tune's HVSC path in the collection that holds the document, or
|
|
18
18
|
# nil when the tune lies outside it.
|
|
19
19
|
def path(tune_path, document)
|
|
20
|
-
root = File.dirname(File.expand_path(document), 2)
|
|
21
|
-
tune = File.expand_path(tune_path)
|
|
20
|
+
root = ::File.dirname(::File.expand_path(document), 2)
|
|
21
|
+
tune = ::File.expand_path(tune_path)
|
|
22
22
|
tune.start_with?("#{root}/") ? tune[root.length..] : nil
|
|
23
23
|
end
|
|
24
24
|
|
|
@@ -26,10 +26,10 @@ module Badline
|
|
|
26
26
|
|
|
27
27
|
def candidates(tune_path)
|
|
28
28
|
dirs = []
|
|
29
|
-
dir = File.dirname(File.expand_path(tune_path))
|
|
29
|
+
dir = ::File.dirname(::File.expand_path(tune_path))
|
|
30
30
|
until dirs.last == dir
|
|
31
31
|
dirs << dir
|
|
32
|
-
dir = File.dirname(dir)
|
|
32
|
+
dir = ::File.dirname(dir)
|
|
33
33
|
end
|
|
34
34
|
base = ENV.fetch("HVSC_BASE", nil)
|
|
35
35
|
dirs << base if base
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Badline
|
|
4
|
-
module
|
|
4
|
+
module SIDTune
|
|
5
5
|
# HVSC's subtune length database. Each tune gets a comment naming its path
|
|
6
6
|
# and a line keyed by the MD5 of the whole `.sid` file, holding one
|
|
7
7
|
# `m:ss` time per subtune, optionally down to milliseconds:
|
|
@@ -23,7 +23,7 @@ module Badline
|
|
|
23
23
|
# The tune's per-subtune lengths in seconds, or nil when it isn't listed.
|
|
24
24
|
def lengths(md5)
|
|
25
25
|
prefix = "#{md5.downcase}="
|
|
26
|
-
File.foreach(@path) do |line|
|
|
26
|
+
::File.foreach(@path) do |line|
|
|
27
27
|
next unless line.start_with?(prefix)
|
|
28
28
|
|
|
29
29
|
return line[prefix.length..].split.map { |time| seconds(time) }
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "badline/
|
|
3
|
+
require "badline/sid_tune/stil/credit"
|
|
4
4
|
|
|
5
5
|
module Badline
|
|
6
|
-
module
|
|
6
|
+
module SIDTune
|
|
7
7
|
# HVSC's SID Tune Information List, `DOCUMENTS/STIL.txt`: covers,
|
|
8
8
|
# subtune names and composers' comments, keyed by each tune's HVSC path.
|
|
9
9
|
# An entry holds fields for the whole file, then a block per subtune
|
|
@@ -89,7 +89,7 @@ module Badline
|
|
|
89
89
|
def entry(hvsc_path) = entries[hvsc_path]
|
|
90
90
|
|
|
91
91
|
def entries
|
|
92
|
-
@entries ||= parse(Storage.latin1(File.binread(@path).bytes))
|
|
92
|
+
@entries ||= parse(Storage.latin1(::File.binread(@path).bytes))
|
|
93
93
|
end
|
|
94
94
|
|
|
95
95
|
private
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Snapshot
|
|
5
|
+
# How a C128 was built: its model's name, its SID's model and the
|
|
6
|
+
# mode it resets into, the arguments C128.new takes.
|
|
7
|
+
C128Setup = Data.define(:model, :sid_model, :mode)
|
|
8
|
+
|
|
9
|
+
class C128Setup
|
|
10
|
+
SID_MODELS = %i[mos6581 mos8580].freeze
|
|
11
|
+
MODES = %i[c64 c128].freeze
|
|
12
|
+
|
|
13
|
+
# The model, the SID and the mode by name, in a keyed snapshot module.
|
|
14
|
+
def write_fields(out)
|
|
15
|
+
out.text("model", model).text("sid_model", sid_model.to_s).text("mode", mode.to_s)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.read_fields(input)
|
|
19
|
+
model = input.choice("model", C128::Model::ALL.map(&:name), "c128")
|
|
20
|
+
sid = input.choice("sid_model", SID_MODELS.map(&:to_s), "mos6581")
|
|
21
|
+
mode = input.choice("mode", MODES.map(&:to_s), "c64")
|
|
22
|
+
new(model:, sid_model: SID_MODELS.find { |name| name.to_s == sid } || :mos6581,
|
|
23
|
+
mode: MODES.find { |name| name.to_s == mode } || :c64)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# A machine built this way, at power-on.
|
|
27
|
+
def build = C128.new(model:, sid_model:, mode:)
|
|
28
|
+
|
|
29
|
+
def to_s = [model, sid_model, mode].join(" with a ")
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Snapshot
|
|
5
|
+
# How a C64 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 C64.new takes.
|
|
8
|
+
C64Setup = Data.define(:vic_model, :cia_model, :sid_model, :region, :ram_expansion, :reu, :kernal, :datasette,
|
|
9
|
+
:board)
|
|
10
|
+
|
|
11
|
+
class C64Setup
|
|
12
|
+
SID_MODELS = %i[mos6581 mos8580].freeze
|
|
13
|
+
REGIONS = [Region::PAL, Region::NTSC, Region::NTSC_OLD, Region::DREAN].freeze
|
|
14
|
+
RAM_EXPANSIONS = [:none, *C64::BankedRAM::TYPES.keys].freeze
|
|
15
|
+
KERNALS = C64::Bus::ROMs::KERNALS.keys.freeze
|
|
16
|
+
BOARDS = C64::Bus::Fittings::BOARDS
|
|
17
|
+
|
|
18
|
+
def self.of(address_bus)
|
|
19
|
+
new(vic_model: address_bus.vic.model, cia_model: address_bus.cia1.model, sid_model: address_bus.sid.model,
|
|
20
|
+
region: address_bus.region, ram_expansion: address_bus.ram_expansion.type, reu: address_bus.reu&.size_kb,
|
|
21
|
+
kernal: address_bus.kernal, datasette: address_bus.datasette.connected?, board: address_bus.board)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.ram_expansion(name) = name == :none ? nil : name
|
|
25
|
+
|
|
26
|
+
# An REU's size in K, written as 0 for none.
|
|
27
|
+
def self.reu(size_kb)
|
|
28
|
+
return nil if size_kb.zero?
|
|
29
|
+
return size_kb if C64::REU::SIZES_KB.include?(size_kb)
|
|
30
|
+
|
|
31
|
+
raise FormatError, "the snapshot names a #{size_kb}K REU, which badline doesn't build"
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# The setup in a keyed snapshot module (Snapshot::Keyed), with each
|
|
35
|
+
# model, the region, the RAM expansion, the KERNAL and the board by
|
|
36
|
+
# name.
|
|
37
|
+
def write_fields(out)
|
|
38
|
+
out.text("vic_model", vic_model.to_s).text("cia_model", cia_model.to_s).text("sid_model", sid_model.to_s)
|
|
39
|
+
out.text("region", region.name.to_s).text("ram_expansion", (ram_expansion || :none).to_s)
|
|
40
|
+
out.int("reu_kb", reu || 0).text("kernal", kernal.to_s).bool("datasette", datasette)
|
|
41
|
+
out.text("board", board.to_s)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# The setup a keyed snapshot module names, a C64's at power-on for
|
|
45
|
+
# anything it leaves out or names that badline doesn't build.
|
|
46
|
+
def self.read_fields(input)
|
|
47
|
+
region = named(input, "region", REGIONS.map(&:name), :pal)
|
|
48
|
+
new(vic_model: named(input, "vic_model", Chips::VIC::MODELS, :mos6569),
|
|
49
|
+
cia_model: named(input, "cia_model", Chips::CIA::MODELS, :mos6526),
|
|
50
|
+
sid_model: named(input, "sid_model", SID_MODELS, :mos6581),
|
|
51
|
+
region: REGIONS.find { |each| each.name == region } || Region::PAL,
|
|
52
|
+
ram_expansion: ram_expansion(named(input, "ram_expansion", RAM_EXPANSIONS, :none)),
|
|
53
|
+
reu: reu(input.int("reu_kb", 0)), kernal: named(input, "kernal", KERNALS, :c64),
|
|
54
|
+
datasette: input.bool("datasette", true), board: named(input, "board", BOARDS, :c64))
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# The Symbol of `names` the text at `key` names.
|
|
58
|
+
def self.named(input, key, names, default)
|
|
59
|
+
text = input.choice(key, names.map(&:to_s), default.to_s)
|
|
60
|
+
names.find { |name| name.to_s == text } || default
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# A machine built this way, at power-on.
|
|
64
|
+
def build
|
|
65
|
+
C64.new(vic_model:, cia_model:, sid_model:, region:, ram_expansion:, reu:, kernal:, datasette:, board:)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# The chips, led by the model's name when they make one of
|
|
69
|
+
# Badline::Model's.
|
|
70
|
+
def to_s
|
|
71
|
+
model = Model.of(self)
|
|
72
|
+
parts = [vic_model, cia_model, sid_model, region.name]
|
|
73
|
+
parts.unshift(model.name) if model
|
|
74
|
+
parts << ram_expansion if ram_expansion
|
|
75
|
+
parts << "a #{reu}K REU" if reu
|
|
76
|
+
parts << "the #{kernal} KERNAL" unless kernal == :c64
|
|
77
|
+
parts << "no datasette" unless datasette
|
|
78
|
+
parts << "the #{board} board" unless board == :c64
|
|
79
|
+
parts.join(", ")
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
@@ -4,6 +4,10 @@ require "zlib"
|
|
|
4
4
|
|
|
5
5
|
module Badline
|
|
6
6
|
module Snapshot
|
|
7
|
+
# A file that isn't a snapshot badline reads, is cut short, or is of a
|
|
8
|
+
# machine built another way.
|
|
9
|
+
class FormatError < StandardError; end
|
|
10
|
+
|
|
7
11
|
# One module of a snapshot: its name, its version and its payload,
|
|
8
12
|
# without the 22-byte module header.
|
|
9
13
|
Section = Data.define(:name, :major, :minor, :data) do
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Snapshot
|
|
5
|
+
module FieldDoc
|
|
6
|
+
# The doc's markdown: one table per module, of each key, its type and
|
|
7
|
+
# its default, with keys that differ only in a unit's number, such as
|
|
8
|
+
# voice1 to voice3, on one row.
|
|
9
|
+
class Markdown
|
|
10
|
+
NAMES = { "c64" => "C64", "vic20" => "VIC-20", "c128" => "C128" }.freeze
|
|
11
|
+
TAG_TYPES = { Keyed::INT => "int", Keyed::BOOL => "bool", Keyed::BYTES => "bytes", Keyed::INTS => "ints",
|
|
12
|
+
Keyed::TEXT => "text" }.freeze
|
|
13
|
+
|
|
14
|
+
# A row: the key, the type, and the defaults each family whose
|
|
15
|
+
# machines read or write it reads it with.
|
|
16
|
+
Row = Struct.new(:key, :type, :defaults)
|
|
17
|
+
|
|
18
|
+
INTRO = <<~MARKDOWN
|
|
19
|
+
# Snapshot format
|
|
20
|
+
|
|
21
|
+
This file is generated by `rake snapshot:fields` from the code that
|
|
22
|
+
loads a snapshot. Don't edit it by hand. doc/snapshots.md covers
|
|
23
|
+
what a snapshot holds and which versions load.
|
|
24
|
+
|
|
25
|
+
A snapshot is a VICE `.vsf` container. The machine is in modules
|
|
26
|
+
named `BL-` plus a unit, each a deflated list of records: a key, a
|
|
27
|
+
type and a value. The types are `int` (a zigzag BER integer), `bool`,
|
|
28
|
+
`bytes`, `ints` (a list of integers) and `text`. A load skips a key
|
|
29
|
+
it doesn't know, and a key that isn't there leaves the value a
|
|
30
|
+
machine built afresh has: the default below. `word`, `byte` and
|
|
31
|
+
`int & 0x..` are ints cut to the latch's width. A text that lists
|
|
32
|
+
its values takes one of them. An optional int is absent when the
|
|
33
|
+
latch holds nothing. A true drive's modules are named from its
|
|
34
|
+
device number, `BL-D8` to `BL-D11`. Keys with `<N>` stand for each
|
|
35
|
+
numbered unit. A default of "written only" is a key the load
|
|
36
|
+
doesn't read, or reads only when the snapshot has it. Where the
|
|
37
|
+
machines differ, the default is given for each, and a key only
|
|
38
|
+
some of them have names them.
|
|
39
|
+
MARKDOWN
|
|
40
|
+
|
|
41
|
+
def initialize(loads)
|
|
42
|
+
@modules = {}
|
|
43
|
+
loads.each { |load| add(load) }
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def to_s
|
|
47
|
+
sections = @modules.map do |name, rows|
|
|
48
|
+
families = rows.values.flat_map { |row| row.defaults.keys }.uniq
|
|
49
|
+
["## #{name}", "", "Written by the #{families.map { |family| NAMES.fetch(family) }.join(', ')}.", "",
|
|
50
|
+
"| Key | Type | Default |", "| --- | --- | --- |",
|
|
51
|
+
*rows.values.map { |row| line(row, families) }].join("\n")
|
|
52
|
+
end
|
|
53
|
+
"#{INTRO}\n#{sections.join("\n\n")}\n"
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
private
|
|
57
|
+
|
|
58
|
+
def add(load)
|
|
59
|
+
load.fields.each do |name, fields|
|
|
60
|
+
numbered = numbered_keys(load.written[name].keys + fields.map(&:key))
|
|
61
|
+
fields.each { |field| note(name, numbered.fetch(field.key, field.key), field.type, load.family, field) }
|
|
62
|
+
read = fields.to_set(&:key)
|
|
63
|
+
load.written[name].each do |key, tag|
|
|
64
|
+
next if read.include?(key)
|
|
65
|
+
|
|
66
|
+
note(name, numbered.fetch(key, key), TAG_TYPES.fetch(tag, "?"), load.family, nil)
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def note(name, key, type, family, field)
|
|
72
|
+
row = (@modules[name] ||= {})[key] ||= Row.new(key, type, {})
|
|
73
|
+
(row.defaults[family] ||= []) << (field ? brief(field.default, field.type) : "written only")
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Keys that differ only in a number, as the same key with <N>: each
|
|
77
|
+
# key whose number another key in the module shares the rest of.
|
|
78
|
+
def numbered_keys(keys)
|
|
79
|
+
groups = keys.uniq.group_by { |key| key.gsub(/(?<=[a-z])\d+(?=\.|\z)/, "<N>") }
|
|
80
|
+
groups.each_with_object({}) do |(general, members), numbered|
|
|
81
|
+
members.each { |key| numbered[key] = general } if members.length > 1
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def line(row, families)
|
|
86
|
+
each = row.defaults.transform_values { |defaults| summary(defaults.uniq) }
|
|
87
|
+
default = if each.values.uniq.length == 1 && each.length == families.length then each.values.first
|
|
88
|
+
else each.map { |family, value| "#{NAMES.fetch(family)}: #{value}" }.join("; ")
|
|
89
|
+
end
|
|
90
|
+
"| `#{row.key}` | #{row.type} | #{default} |"
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def summary(defaults) = defaults.length > 3 ? "varies" : defaults.join(" or ")
|
|
94
|
+
|
|
95
|
+
def brief(value, type)
|
|
96
|
+
case value
|
|
97
|
+
when nil then "absent"
|
|
98
|
+
when Array then list(value)
|
|
99
|
+
when String then type.start_with?("bytes") ? list(value.bytes) : value.inspect
|
|
100
|
+
else value.to_s
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def list(values)
|
|
105
|
+
return values.inspect if values.length <= 8
|
|
106
|
+
|
|
107
|
+
values.uniq.length == 1 ? "#{values.length} × #{values.first}" : "#{values.length} values"
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
end
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "badline"
|
|
4
|
+
require "badline/c128"
|
|
5
|
+
|
|
6
|
+
module Badline
|
|
7
|
+
module Snapshot
|
|
8
|
+
# doc/snapshot-format.md, written by running the code: each family's
|
|
9
|
+
# machine is saved with its attachments, and its modules loaded into a
|
|
10
|
+
# machine built the same way at power-on through Keyed::Recorders,
|
|
11
|
+
# which note every key read with its type and the value the new machine
|
|
12
|
+
# had, its default. `rake snapshot:fields` writes it, and a spec checks
|
|
13
|
+
# that the file matches.
|
|
14
|
+
module FieldDoc
|
|
15
|
+
PATH = File.expand_path("../../../doc/snapshot-format.md", __dir__)
|
|
16
|
+
|
|
17
|
+
# Modules read through Recorders.
|
|
18
|
+
class RecordingModules < Keyed::Modules
|
|
19
|
+
private
|
|
20
|
+
|
|
21
|
+
def parse(section) = Keyed::Recorder.parse(section)
|
|
22
|
+
|
|
23
|
+
def missing(name) = Keyed::Recorder.missing(name)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# One machine saved and loaded: the family it belongs to, and for
|
|
27
|
+
# each module the keys its records hold, with their tags, and the fields the load read.
|
|
28
|
+
Load = Data.define(:family, :written, :fields)
|
|
29
|
+
|
|
30
|
+
# The machines the doc is made from: each family at power-on, and the
|
|
31
|
+
# C64 with each kind of expansion, cartridge and media.
|
|
32
|
+
def self.machines
|
|
33
|
+
{
|
|
34
|
+
"c64" => [C64.new, C64.new(ram_expansion: :plus256k), C64.new(reu: 512), with_cartridge, with_trap_dos,
|
|
35
|
+
with_tape, with_drive(:d64), with_drive(:d81)],
|
|
36
|
+
"vic20" => [Vic20.new, with_rom],
|
|
37
|
+
"c128" => [C128.new(mode: :c128), with_drive(:d71)]
|
|
38
|
+
}
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def self.blank(length) = Array.new(length, 0)
|
|
42
|
+
|
|
43
|
+
def self.with_cartridge
|
|
44
|
+
chips = [0x8000, 0xa000].map do |address|
|
|
45
|
+
Storage::CRTFile::Chip.new(chip_type: 2, bank: 0, address:, data: blank(0x2000))
|
|
46
|
+
end
|
|
47
|
+
image = Storage::CRTFile::Image.new(hardware_type: 32, subtype: 0, exrom: 1, game: 0, name: "DOC", chips:)
|
|
48
|
+
C64.new.tap do |machine|
|
|
49
|
+
machine.attach_cartridge(C64::Cartridge.from_crt(Storage::CRTFile.new(bytes: Storage::CRTFile.encode(image))))
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def self.with_trap_dos
|
|
54
|
+
C64.new.tap { |machine| machine.mount(Storage::D64Image.new("", read_only: true, bytes: blank(174_848))) }
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def self.with_tape
|
|
58
|
+
bytes = "C64-TAPE-RAW".bytes + [1, 0, 0, 0, 4, 0, 0, 0, 0x30, 0x30, 0x30, 0x30]
|
|
59
|
+
C64.new.tap { |machine| machine.datasette.insert(Storage::TAP.new("", bytes:)) }
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def self.with_drive(kind)
|
|
63
|
+
case kind
|
|
64
|
+
when :d81
|
|
65
|
+
C64.new.tap do |machine|
|
|
66
|
+
machine.plug_drive1581.insert(Drives::Model1581::Disk.new(Storage::D81Image.new("", bytes: blank(819_200))))
|
|
67
|
+
end
|
|
68
|
+
when :d71
|
|
69
|
+
C128.new(mode: :c128).tap do |machine|
|
|
70
|
+
image = Storage::D71Image.new("", bytes: blank(349_696))
|
|
71
|
+
machine.plug_true_drive.insert(Drives::Model1541::Disk.decode(image))
|
|
72
|
+
end
|
|
73
|
+
else
|
|
74
|
+
C64.new.tap do |machine|
|
|
75
|
+
image = Storage::D64Image.new("", bytes: blank(174_848))
|
|
76
|
+
machine.plug_true_drive.insert(Drives::Model1541::Disk.decode(image))
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def self.with_rom
|
|
82
|
+
Vic20.new.tap { |machine| machine.bus.map_rom(0xa000, blank(0x2000)) }
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Saves `machine` and loads it into a new one through Recorders.
|
|
86
|
+
def self.load(family, machine)
|
|
87
|
+
modules = RecordingModules.new(Image.of(machine).sections)
|
|
88
|
+
Image.setup(modules.machine).build.load_modules(modules)
|
|
89
|
+
modules.machine.text("written_by", "")
|
|
90
|
+
written = {}
|
|
91
|
+
fields = {}
|
|
92
|
+
modules.readers.each do |reader|
|
|
93
|
+
written[reader.name] = reader.tags
|
|
94
|
+
fields[reader.name] = reader.fields
|
|
95
|
+
end
|
|
96
|
+
Load.new(family:, written:, fields:)
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def self.loads = machines.flat_map { |family, list| list.map { |machine| load(family, machine) } }
|
|
100
|
+
|
|
101
|
+
# The doc, as markdown.
|
|
102
|
+
def self.markdown(loads = self.loads) = Markdown.new(loads).to_s
|
|
103
|
+
|
|
104
|
+
def self.write(path = PATH) = File.write(path, markdown)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
require "badline/snapshot/field_doc/markdown"
|