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
|
@@ -18,32 +18,24 @@ module Badline
|
|
|
18
18
|
class Save < FileRoutine
|
|
19
19
|
SECONDARY = 0x61
|
|
20
20
|
|
|
21
|
-
# ST bit
|
|
21
|
+
# ST bit
|
|
22
22
|
DEVICE_NOT_PRESENT = 0x80
|
|
23
23
|
|
|
24
|
-
def initialize(cpu:, bus:, layout:,
|
|
24
|
+
def initialize(cpu:, bus:, layout:, dos:)
|
|
25
25
|
super(cpu:, bus:, layout:)
|
|
26
|
-
@
|
|
26
|
+
@dos = dos
|
|
27
27
|
@saving = false
|
|
28
28
|
end
|
|
29
29
|
|
|
30
|
-
def save_state(out)
|
|
31
|
-
out.boolean(@saving)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def load_state(input)
|
|
35
|
-
@saving = input.boolean?
|
|
36
|
-
end
|
|
37
|
-
|
|
38
30
|
def call
|
|
39
31
|
return unless active?
|
|
40
32
|
return finish if @saving
|
|
41
|
-
return unless @
|
|
33
|
+
return unless @dos.saves?
|
|
42
34
|
|
|
43
|
-
@bus.poke(
|
|
35
|
+
@bus.poke(zero_page.secondary_address, SECONDARY)
|
|
44
36
|
return @cpu.program_counter = @layout.missing_file_name_exit if name.empty?
|
|
45
37
|
|
|
46
|
-
@bus.poke(
|
|
38
|
+
@bus.poke(zero_page.status, 0x00)
|
|
47
39
|
@saving = true
|
|
48
40
|
continue_with(@layout.saving_message, @layout.save)
|
|
49
41
|
end
|
|
@@ -56,20 +48,18 @@ module Badline
|
|
|
56
48
|
|
|
57
49
|
def finish
|
|
58
50
|
@saving = false
|
|
59
|
-
saved = @
|
|
60
|
-
@bus.poke(
|
|
61
|
-
|
|
62
|
-
@bus.poke(0xad, @bus.peek(0xaf))
|
|
51
|
+
saved = @dos.save(name, payload, replace: full_filename.start_with?("@"))
|
|
52
|
+
@bus.poke(zero_page.status, DEVICE_NOT_PRESENT) unless saved
|
|
53
|
+
poke_word(zero_page.start_address, peek_word(zero_page.end_address))
|
|
63
54
|
@cpu.y = 0
|
|
64
55
|
@cpu.status.overflow = true
|
|
65
56
|
continue_with(@layout.clock_release, @layout.data_release, @layout.save_done)
|
|
66
57
|
end
|
|
67
58
|
|
|
68
|
-
# Start address at
|
|
69
|
-
# $AE/$AF (EAL)
|
|
59
|
+
# Start address at STAL, end address (exclusive) at EAL
|
|
70
60
|
def payload
|
|
71
|
-
start =
|
|
72
|
-
length = (
|
|
61
|
+
start = peek_word(zero_page.save_start)
|
|
62
|
+
length = (peek_word(zero_page.end_address) - start) & 0xffff
|
|
73
63
|
[low_byte(start), high_byte(start)] +
|
|
74
64
|
Array.new(length) { |i| @layout.file_byte(@bus, (start + i) & 0xffff) }
|
|
75
65
|
end
|
|
@@ -23,9 +23,9 @@ module Badline
|
|
|
23
23
|
|
|
24
24
|
NO_DATA = [0x0d, EOI | READ_TIMEOUT].freeze
|
|
25
25
|
|
|
26
|
-
def initialize(cpu:, bus:, layout:,
|
|
26
|
+
def initialize(cpu:, bus:, layout:, dos:, device: DEVICE)
|
|
27
27
|
super(cpu:, bus:, layout:)
|
|
28
|
-
@
|
|
28
|
+
@dos = dos
|
|
29
29
|
@device = device
|
|
30
30
|
@listening = false
|
|
31
31
|
@talking = false
|
|
@@ -35,22 +35,6 @@ module Badline
|
|
|
35
35
|
@buffer = []
|
|
36
36
|
end
|
|
37
37
|
|
|
38
|
-
# The frame under way, with the channels and the bytes it gathered.
|
|
39
|
-
# The device it answers is the machine's to set.
|
|
40
|
-
def save_state(out)
|
|
41
|
-
out.boolean(@listening).boolean(@talking).optional_int(@listen_channel).optional_int(@talk_channel)
|
|
42
|
-
out.int(@frame).blob(@buffer)
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def load_state(input)
|
|
46
|
-
@listening = input.boolean?
|
|
47
|
-
@talking = input.boolean?
|
|
48
|
-
@listen_channel = input.optional_int
|
|
49
|
-
@talk_channel = input.optional_int
|
|
50
|
-
@frame = input.int
|
|
51
|
-
@buffer = input.blob
|
|
52
|
-
end
|
|
53
|
-
|
|
54
38
|
def install
|
|
55
39
|
routines.each do |address, routine|
|
|
56
40
|
@cpu.install_trap(address) { call_routine(routine) if kernal_mapped? }
|
|
@@ -144,7 +128,7 @@ module Badline
|
|
|
144
128
|
# takes data only on a channel it has open. Otherwise nothing holds
|
|
145
129
|
# the data line when a byte starts, so the KERNAL finds no device.
|
|
146
130
|
def accepted?
|
|
147
|
-
[OPEN, CLOSE].include?(@frame) || @
|
|
131
|
+
[OPEN, CLOSE].include?(@frame) || @dos.listening?(@listen_channel)
|
|
148
132
|
end
|
|
149
133
|
|
|
150
134
|
def unlisten
|
|
@@ -188,15 +172,15 @@ module Badline
|
|
|
188
172
|
return unless @listen_channel
|
|
189
173
|
|
|
190
174
|
case @frame
|
|
191
|
-
when OPEN then @
|
|
192
|
-
when CLOSE then @
|
|
193
|
-
else @
|
|
175
|
+
when OPEN then @dos.open(@listen_channel, @buffer.pack("C*"))
|
|
176
|
+
when CLOSE then @dos.close(@listen_channel)
|
|
177
|
+
else @dos.write(@listen_channel, @buffer)
|
|
194
178
|
end
|
|
195
179
|
@buffer = []
|
|
196
180
|
end
|
|
197
181
|
|
|
198
182
|
def received
|
|
199
|
-
byte, eoi = @
|
|
183
|
+
byte, eoi = @dos.read(@talk_channel)
|
|
200
184
|
return NO_DATA unless byte
|
|
201
185
|
|
|
202
186
|
[byte, eoi ? EOI : 0]
|
|
@@ -205,7 +189,7 @@ module Badline
|
|
|
205
189
|
def update_status(bits)
|
|
206
190
|
return if bits.zero?
|
|
207
191
|
|
|
208
|
-
@bus.poke(
|
|
192
|
+
@bus.poke(zero_page.status, @bus.peek(zero_page.status) | bits)
|
|
209
193
|
end
|
|
210
194
|
end
|
|
211
195
|
end
|
data/lib/badline/kernal_trap.rb
CHANGED
|
@@ -2,9 +2,10 @@
|
|
|
2
2
|
|
|
3
3
|
require "badline/kernal_trap/layout"
|
|
4
4
|
require "badline/kernal_trap/routine"
|
|
5
|
-
require "badline/kernal_trap/
|
|
6
|
-
require "badline/kernal_trap/drive"
|
|
5
|
+
require "badline/kernal_trap/dos"
|
|
7
6
|
require "badline/kernal_trap/file_routine"
|
|
8
7
|
require "badline/kernal_trap/load"
|
|
9
8
|
require "badline/kernal_trap/save"
|
|
10
9
|
require "badline/kernal_trap/serial"
|
|
10
|
+
require "badline/kernal_trap/chrout"
|
|
11
|
+
require "badline/kernal_trap/keyed_state"
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
module Badline
|
|
4
4
|
module Machine
|
|
5
5
|
# Running a machine from outside its own #cycle!, and the handlers that
|
|
6
|
-
# wait for its KERNAL to boot.
|
|
6
|
+
# wait for its KERNAL to boot. C64, Vic20 and C128 each include it
|
|
7
7
|
# and answer #cycle!, #cycles and #init_threshold, the cycle at which
|
|
8
8
|
# #on_init's handlers run, and keep the handlers in @init_handlers.
|
|
9
9
|
module Clocking
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Machine
|
|
5
|
+
# Typing into the KERNAL's keyboard buffer once the machine has booted.
|
|
6
|
+
# The machine that includes it answers #keyboard_buffer, the Layout of
|
|
7
|
+
# the KERNAL it runs, and #ram.
|
|
8
|
+
module KeyboardBuffer
|
|
9
|
+
# Where a KERNAL keeps its keyboard buffer (KEYD), the count of
|
|
10
|
+
# characters in it (NDX), and how many it holds.
|
|
11
|
+
Layout = Data.define(:address, :count, :capacity)
|
|
12
|
+
|
|
13
|
+
# The C64's and the VIC-20's.
|
|
14
|
+
C64_LAYOUT = Layout.new(address: 0x0277, count: 0xc6, capacity: 10)
|
|
15
|
+
|
|
16
|
+
# BASIC 7.0's, in C128 mode.
|
|
17
|
+
C128_LAYOUT = Layout.new(address: 0x034a, count: 0xd0, capacity: 10)
|
|
18
|
+
|
|
19
|
+
# The 264 series KERNAL's, which sets its capacity at $053F to 10
|
|
20
|
+
# ($D86E).
|
|
21
|
+
PLUS4_LAYOUT = Layout.new(address: 0x0527, count: 0xef, capacity: 10)
|
|
22
|
+
|
|
23
|
+
def type_text(text)
|
|
24
|
+
codes = text.bytes.map { |b| ascii_to_petscii(b) }
|
|
25
|
+
on_init { @pending_keys = codes }
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
private
|
|
29
|
+
|
|
30
|
+
def feed_keyboard
|
|
31
|
+
buffer = keyboard_buffer
|
|
32
|
+
return unless ram.peek(buffer.count).zero?
|
|
33
|
+
|
|
34
|
+
chunk = @pending_keys.shift(buffer.capacity)
|
|
35
|
+
ram.write(buffer.address, chunk)
|
|
36
|
+
ram.poke(buffer.count, chunk.length)
|
|
37
|
+
@pending_keys = nil if @pending_keys.empty?
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def ascii_to_petscii(byte)
|
|
41
|
+
case byte
|
|
42
|
+
when 0x61..0x7a then byte - 0x20
|
|
43
|
+
when 0x41..0x5a then byte + 0x80
|
|
44
|
+
else byte
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Machine
|
|
5
|
+
# Brings the machine to the point a snapshot file is saved at: the main
|
|
6
|
+
# CPU between instructions, or jammed, with no REU transfer holding the
|
|
7
|
+
# bus. C64, Vic20 and C128 each include it, and answer
|
|
8
|
+
# #settled_for_snapshot? and #settle_chips_for_snapshot, which brings
|
|
9
|
+
# what each chip defers up to the cycle without running one.
|
|
10
|
+
module Settling
|
|
11
|
+
# The cycles settling may run: the longest instruction stretched by
|
|
12
|
+
# the VIC's longest hold on the bus, and an REU swap of 64K, two
|
|
13
|
+
# cycles a byte, stretched the same way.
|
|
14
|
+
LIMIT = 100 + 0x40000
|
|
15
|
+
|
|
16
|
+
# Runs the machine on, through its own #cycle!, to the settle point,
|
|
17
|
+
# and returns the cycles that took. A settled machine runs none.
|
|
18
|
+
def settle_for_snapshot!
|
|
19
|
+
ran = 0
|
|
20
|
+
while ran < LIMIT && !settled_for_snapshot?
|
|
21
|
+
cycle!
|
|
22
|
+
ran += 1
|
|
23
|
+
end
|
|
24
|
+
settle_chips_for_snapshot
|
|
25
|
+
ran
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
data/lib/badline/machine.rb
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "badline/machine/clocking"
|
|
4
|
+
require "badline/machine/keyboard_buffer"
|
|
5
|
+
require "badline/machine/settling"
|
|
4
6
|
|
|
5
7
|
module Badline
|
|
6
8
|
# = Machine
|
|
7
9
|
#
|
|
8
10
|
# The machines badline builds by family, as the command line's
|
|
9
|
-
# subcommand names them: the C64,
|
|
11
|
+
# subcommand names them: the C64, Badline::C64, the VIC-20, Vic20, and the
|
|
10
12
|
# C128 in C64 mode, C128.
|
|
11
13
|
#
|
|
12
14
|
# A machine answers what the front end, Media, the runners and the
|
|
@@ -28,7 +30,7 @@ module Badline
|
|
|
28
30
|
# +press_cartridge_button+, +release_cartridge_button+,
|
|
29
31
|
# +attach_drive1541+, +drive1541+, +true_drive+ and +plug_true_drive+
|
|
30
32
|
# for the drive Media::TrueDrive plugs in, +attach_drive1581+,
|
|
31
|
-
# +drive1581+ and +plug_drive1581+ for a 1581 (
|
|
33
|
+
# +drive1581+ and +plug_drive1581+ for a 1581 (Drives::Model1581::Slot), and
|
|
32
34
|
# +address_bus+ for its +cartridge+ and +detach_cartridge+.
|
|
33
35
|
# - Snapshots and tests: +snapshot+, +restore+, +save_snapshot+,
|
|
34
36
|
# +install_debug_register+ and +capture_output+.
|
|
@@ -58,16 +60,17 @@ module Badline
|
|
|
58
60
|
# VIC-20's is "pal", with the RAM expansion `ram` names
|
|
59
61
|
# (Vic20::Bus::RAM_CONFIGURATIONS), unexpanded when nil. A C128's is
|
|
60
62
|
# one of C128::Model::ALL, with its SID `sid_model` when not nil, built
|
|
61
|
-
# for C64 mode.
|
|
63
|
+
# for C64 mode. :plus4 is refused until the Plus/4 runs.
|
|
62
64
|
def self.build(family, model:, sid_model: nil, reu: nil, ram: nil)
|
|
63
65
|
return vic20(model, ram) if family == :vic20
|
|
64
66
|
return c128(model, sid_model, :c64) if family == :c128
|
|
67
|
+
raise ArgumentError, "the Plus/4 isn't emulated yet" if family == :plus4
|
|
65
68
|
raise ArgumentError, "no machine family named #{family}" unless family == :c64
|
|
66
69
|
|
|
67
70
|
profile = Model.named(model)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
+
C64.new(vic_model: profile.vic_model, cia_model: profile.cia_model,
|
|
72
|
+
sid_model: sid_model || profile.sid_model, region: profile.region, reu:,
|
|
73
|
+
kernal: profile.kernal, datasette: profile.datasette, board: profile.board)
|
|
71
74
|
end
|
|
72
75
|
|
|
73
76
|
# The machine the command line's `options` name, to start `media`, a
|
|
@@ -119,7 +122,7 @@ module Badline
|
|
|
119
122
|
|
|
120
123
|
extension = File.extname(media).downcase
|
|
121
124
|
return true if extension == ".sid"
|
|
122
|
-
return false unless
|
|
125
|
+
return false unless Media::Extensions::PROGRAMS.include?(extension)
|
|
123
126
|
|
|
124
127
|
[Media::BASIC_START, Media::BASIC_START - 1].include?(Storage::P00.load_address(media))
|
|
125
128
|
end
|
|
@@ -4,7 +4,8 @@ module Badline
|
|
|
4
4
|
module Media
|
|
5
5
|
# A C128 boot disk. At power-on the C128 KERNAL reads track 1, sector 0
|
|
6
6
|
# of the disk in device 8 and runs it when it starts with "CBM", as boot
|
|
7
|
-
# games have it
|
|
7
|
+
# games have it, from a sector image or from the raw GCR of a .g64 or
|
|
8
|
+
# .g71. The 1581's DOS first loads and runs a USR file named
|
|
8
9
|
# COPYRIGHT CBM 86 when the disk has one, which is how CP/M's 1581 disks
|
|
9
10
|
# hand the KERNAL their boot sector, so a .d81 with that file boots too.
|
|
10
11
|
#
|
|
@@ -15,7 +16,7 @@ module Badline
|
|
|
15
16
|
module BootDisk
|
|
16
17
|
SIGNATURE = "CBM".bytes.freeze
|
|
17
18
|
AUTO_BOOT = "copyright cbm 86"
|
|
18
|
-
TYPES = Extensions.of(%i[disk])
|
|
19
|
+
TYPES = Extensions.of(%i[disk gcr])
|
|
19
20
|
|
|
20
21
|
class << self
|
|
21
22
|
def takes?(computer, path)
|
|
@@ -37,6 +38,7 @@ module Badline
|
|
|
37
38
|
def boot?(path)
|
|
38
39
|
type = File.extname(path).downcase
|
|
39
40
|
return false unless TYPES.include?(type) && File.file?(path)
|
|
41
|
+
return gcr_signature(path) == SIGNATURE if Extensions.kind(path) == :gcr
|
|
40
42
|
|
|
41
43
|
image = Media.open_storage(path, { read_only: true })
|
|
42
44
|
block = image.read_block(1, 0)
|
|
@@ -44,6 +46,16 @@ module Badline
|
|
|
44
46
|
|
|
45
47
|
type == ".d81" && !image.read_file(AUTO_BOOT, type: :usr).nil?
|
|
46
48
|
end
|
|
49
|
+
|
|
50
|
+
private
|
|
51
|
+
|
|
52
|
+
# The first three bytes of track 1, sector 0 as the drive reads them
|
|
53
|
+
# off the GCR of a .g64 or .g71, or nil when the sector isn't there.
|
|
54
|
+
def gcr_signature(path)
|
|
55
|
+
track = Drives::Model1541::Disk.open(path, read_only: true).track(2)
|
|
56
|
+
data = track && Drives::Model1541::SectorReader.read(track.bytes, 1)[0]&.data
|
|
57
|
+
data && data[1, 3]
|
|
58
|
+
end
|
|
47
59
|
end
|
|
48
60
|
end
|
|
49
61
|
end
|
|
@@ -28,6 +28,16 @@ module Badline
|
|
|
28
28
|
|
|
29
29
|
# What goes in device 8 through the traps.
|
|
30
30
|
MOUNTABLE = of(%i[disk archive])
|
|
31
|
+
|
|
32
|
+
# What goes in device 8, a true drive's or the traps', and the lists
|
|
33
|
+
# of disks to put there.
|
|
34
|
+
DEVICE8 = of(%i[disk gcr archive disk_list])
|
|
35
|
+
|
|
36
|
+
# Programs, which load on their own.
|
|
37
|
+
PROGRAMS = %w[.prg .p00].freeze
|
|
38
|
+
|
|
39
|
+
# Every medium Media.attach takes by its extension.
|
|
40
|
+
ALL = (KINDS.keys + PROGRAMS).freeze
|
|
31
41
|
end
|
|
32
42
|
end
|
|
33
43
|
end
|
|
@@ -9,7 +9,7 @@ module Badline
|
|
|
9
9
|
# disk's raw GCR, which only a true drive reads, so it plugs one in
|
|
10
10
|
# when there's none yet. The 1541 reads only .d64 and .g64 images, the
|
|
11
11
|
# 1571 .d71 and .g71 as well, and the 1581 only .d81, so a .d81 swaps
|
|
12
|
-
# the drive on device 8 for a 1581 (
|
|
12
|
+
# the drive on device 8 for a 1581 (Drives::Model1581::Slot), and another disk
|
|
13
13
|
# image swaps a 1581 back for the machine's own drive. The traps' other
|
|
14
14
|
# disk media, a .t64 or a host directory, raise Error.
|
|
15
15
|
module TrueDrive
|
data/lib/badline/media/tune.rb
CHANGED
|
@@ -10,9 +10,9 @@ module Badline
|
|
|
10
10
|
# Plays `subtune`, or the tune's own start subtune, and says what
|
|
11
11
|
# plays. A tune for more than one SID raises FormatError.
|
|
12
12
|
def attach(computer, path, autostart:, subtune:)
|
|
13
|
-
tune =
|
|
13
|
+
tune = SIDTune::File.new(path)
|
|
14
14
|
if tune.sids > 1
|
|
15
|
-
raise
|
|
15
|
+
raise SIDTune::File::FormatError, "Written for #{tune.sids} SIDs, which only the SID player plays"
|
|
16
16
|
end
|
|
17
17
|
|
|
18
18
|
subtune = (subtune || tune.start_subtune).clamp(1, tune.subtunes)
|
data/lib/badline/media.rb
CHANGED
|
@@ -4,7 +4,7 @@ require "badline/media/extensions"
|
|
|
4
4
|
require "badline/media/true_drive"
|
|
5
5
|
require "badline/media/boot_disk"
|
|
6
6
|
require "badline/media/not_disk"
|
|
7
|
-
require "badline/
|
|
7
|
+
require "badline/audio/queue"
|
|
8
8
|
require "badline/media/disk_set"
|
|
9
9
|
require "badline/media/disk_list"
|
|
10
10
|
require "badline/media/vic20_basic"
|
|
@@ -83,7 +83,7 @@ module Badline
|
|
|
83
83
|
def sid_model(path, otherwise: :mos6581)
|
|
84
84
|
return otherwise unless path && Extensions.kind(path) == :tune
|
|
85
85
|
|
|
86
|
-
|
|
86
|
+
SIDTune::File.new(path).sid_model
|
|
87
87
|
end
|
|
88
88
|
|
|
89
89
|
# What the medium at `path` is to `computer`, which attach goes by:
|
|
@@ -156,7 +156,7 @@ module Badline
|
|
|
156
156
|
if computer.family == :vic20
|
|
157
157
|
computer.attach_cartridge(Storage::CRTFile.new(path, machine: :vic20).chips)
|
|
158
158
|
else
|
|
159
|
-
computer.attach_cartridge(Cartridge.from_file(path, **options))
|
|
159
|
+
computer.attach_cartridge(C64::Cartridge.from_file(path, **options))
|
|
160
160
|
end
|
|
161
161
|
"Attached cartridge #{path}"
|
|
162
162
|
end
|
data/lib/badline/memory.rb
CHANGED
|
@@ -29,13 +29,10 @@ module Badline
|
|
|
29
29
|
Array(bytes).each_with_index { |b, i| poke(addr + i, b) }
|
|
30
30
|
end
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
end
|
|
32
|
+
# Every byte as one record of a keyed snapshot module, under `key`.
|
|
33
|
+
def save_fields(out, key) = out.bytes(key, @storage)
|
|
35
34
|
|
|
36
|
-
def
|
|
37
|
-
input.blob_into(@storage)
|
|
38
|
-
end
|
|
35
|
+
def load_fields(input, key) = input.bytes_into(key, @storage)
|
|
39
36
|
|
|
40
37
|
# Refills the whole memory as if newly built with `initial`
|
|
41
38
|
def clear!(initial = [])
|
data/lib/badline/model.rb
CHANGED
|
@@ -7,7 +7,7 @@ module Badline
|
|
|
7
7
|
# each was sold with, its video standard, its KERNAL and whether it has
|
|
8
8
|
# a datasette. The names are x64sc's.
|
|
9
9
|
module Model
|
|
10
|
-
# Each field but the name is a keyword
|
|
10
|
+
# Each field but the name is a keyword C64.new takes.
|
|
11
11
|
Profile = Data.define(:name, :vic_model, :cia_model, :sid_model, :region, :kernal, :datasette, :board)
|
|
12
12
|
|
|
13
13
|
# The breadbin PAL C64: the 6569 VIC-II, 6526 CIAs and the 6581 SID.
|
|
@@ -12,13 +12,14 @@ module Badline
|
|
|
12
12
|
|
|
13
13
|
private
|
|
14
14
|
|
|
15
|
-
# Takes `sid`, `c64`, `vic20` or `
|
|
15
|
+
# Takes `sid`, `c64`, `vic20`, `c128` or `plus4` when given first.
|
|
16
16
|
def subcommand(args)
|
|
17
17
|
case args.first
|
|
18
18
|
when "sid" then @sid_command = true
|
|
19
19
|
when "c64" then @family = :c64
|
|
20
20
|
when "vic20" then @family = :vic20
|
|
21
21
|
when "c128" then @family = :c128
|
|
22
|
+
when "plus4" then @family = :plus4
|
|
22
23
|
else return
|
|
23
24
|
end
|
|
24
25
|
@family_named = !@sid_command
|
|
@@ -37,7 +38,9 @@ module Badline
|
|
|
37
38
|
# the C128's.
|
|
38
39
|
def pick_family
|
|
39
40
|
return if @family_named || @sid_command || @media_path.nil?
|
|
40
|
-
|
|
41
|
+
|
|
42
|
+
program = Media::Extensions::PROGRAMS.include?(File.extname(@media_path).downcase)
|
|
43
|
+
return unless program && File.file?(@media_path)
|
|
41
44
|
|
|
42
45
|
@family = :c128 if Storage::P00.load_address(@media_path) == C128_BASIC_START
|
|
43
46
|
end
|
data/lib/badline/options/help.rb
CHANGED
|
@@ -35,6 +35,34 @@ module Badline
|
|
|
35
35
|
|
|
36
36
|
def describe(option) = @native && option.name == "--sound" ? "#{option.text} (default)" : option.text
|
|
37
37
|
|
|
38
|
+
# The media the window opens, by their extensions (Media::Extensions),
|
|
39
|
+
# wrapped as the banner is.
|
|
40
|
+
def media_kinds
|
|
41
|
+
text = "Media can be a #{Media::Extensions::PROGRAMS.join('/')} program, a #{listed(%i[disk])} disk image, " \
|
|
42
|
+
"a #{listed(%i[gcr])} disk image for a true drive, an #{listed(%i[disk_list])} list of disk images, " \
|
|
43
|
+
"a #{listed(%i[archive])} tape archive, a #{listed(%i[tape])} tape, a #{listed(%i[cartridge])} " \
|
|
44
|
+
"cartridge, a #{listed(%i[tune])} tune, a .vsf snapshot, or a directory to mount as device 8."
|
|
45
|
+
wrap(text)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def listed(kinds) = Media::Extensions.of(kinds).join("/")
|
|
49
|
+
|
|
50
|
+
# The words of `text` in lines of at most 70 characters.
|
|
51
|
+
def wrap(text)
|
|
52
|
+
lines = [""]
|
|
53
|
+
text.split.each do |word|
|
|
54
|
+
line = lines.last
|
|
55
|
+
if line.empty?
|
|
56
|
+
lines[-1] = word
|
|
57
|
+
elsif line.size + word.size < 70
|
|
58
|
+
lines[-1] = "#{line} #{word}"
|
|
59
|
+
else
|
|
60
|
+
lines << word
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
lines.join("\n")
|
|
64
|
+
end
|
|
65
|
+
|
|
38
66
|
def banner
|
|
39
67
|
<<~BANNER
|
|
40
68
|
Usage: #{@program} [c64] [options] [media]
|
|
@@ -50,11 +78,8 @@ module Badline
|
|
|
50
78
|
c128 Run a C128 in C128 mode, the one --model names
|
|
51
79
|
sid Play .sid tunes and directories of them
|
|
52
80
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
images, a .t64 tape archive, a .tap tape, a .crt cartridge, a .sid
|
|
56
|
-
tune, a .vsf snapshot, or a directory to mount as device 8. It
|
|
57
|
-
opens in the emulator window. There F11 quicksaves the machine to
|
|
81
|
+
#{media_kinds}
|
|
82
|
+
It opens in the emulator window. There F11 quicksaves the machine to
|
|
58
83
|
the next of five slots in badline's data folder, replacing the
|
|
59
84
|
oldest, and F12 restores the newest quicksave or named save. The
|
|
60
85
|
window also autosaves every two minutes of play, which only the
|
|
@@ -85,17 +110,18 @@ module Badline
|
|
|
85
110
|
|
|
86
111
|
--at and --script run events once a number of frames has run, as
|
|
87
112
|
in --at 3500:key=space or --at 250,500:screenshot=shot%05d.bmp.
|
|
88
|
-
key=NAME presses a
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
and
|
|
97
|
-
|
|
98
|
-
|
|
113
|
+
key=NAME presses a key (space, return, a, f1, run_stop, restore, and
|
|
114
|
+
on the C128 esc, help, keypad1 and the rest) or a joystick's
|
|
115
|
+
direction or fire (joy1-up, joy2-fire) for #{Event::HOLD} frames, and
|
|
116
|
+
pushes the C128's caps_lock or forty_eighty, which lock. type=TEXT
|
|
117
|
+
types it, with \\n for RETURN. insert=FILE swaps in a disk, a list's
|
|
118
|
+
first disk, a tape or a cartridge, and eject=disk, tape or
|
|
119
|
+
cartridge takes one out. screenshot=FILE saves the frame as a .bmp,
|
|
120
|
+
with the frame's number in place of %d. menu opens the pause menu,
|
|
121
|
+
and menu=PAGE opens it on snapshots, drive, datasette, expansion,
|
|
122
|
+
ports, sound or power. Its frames still count, and resume closes
|
|
123
|
+
it. display=vdc or display=vic shows the C128's 80 or 40 column
|
|
124
|
+
screen, as F8 switches them. reset, freeze and quit take no argument.
|
|
99
125
|
BANNER
|
|
100
126
|
end
|
|
101
127
|
|
|
@@ -75,6 +75,8 @@ module Badline
|
|
|
75
75
|
section: "Testing options", needs: :window),
|
|
76
76
|
Option.new("--save-snapshot FILE", "Save the machine as a .vsf snapshot after the last frame",
|
|
77
77
|
section: "Testing options", needs: :window),
|
|
78
|
+
Option.new("--vice", "Add VICE's modules to --save-snapshot's C64 snapshot, for x64sc",
|
|
79
|
+
section: "Testing options", needs: :window),
|
|
78
80
|
Option.new("--at FRAME:EVENT", "Run EVENT once FRAME frames have run (see above)",
|
|
79
81
|
section: "Testing options", needs: :window),
|
|
80
82
|
Option.new("--script FILE", "Run the events in FILE, one FRAME:EVENT a line",
|
data/lib/badline/options.rb
CHANGED
|
@@ -14,7 +14,7 @@ module Badline
|
|
|
14
14
|
# first, plays .sid tunes and directories of them in the terminal.
|
|
15
15
|
# `c64`, `vic20` or `c128`, given first, names the machine family, and
|
|
16
16
|
# without one the family is the C64, or the C128 for a program that loads
|
|
17
|
-
# where C128 BASIC starts. The native build adds --no-sound and
|
|
17
|
+
# where C128 BASIC starts. `plus4` is refused until the Plus/4 runs. The native build adds --no-sound and
|
|
18
18
|
# --version, and badline-ruby adds --disable-jit.
|
|
19
19
|
#
|
|
20
20
|
# TABLE lists the options, and both the parser and the help read it. It
|
|
@@ -94,6 +94,7 @@ module Badline
|
|
|
94
94
|
@true_drive = false
|
|
95
95
|
@screenshot = ""
|
|
96
96
|
@save_snapshot = ""
|
|
97
|
+
@vice = false
|
|
97
98
|
@timeline = []
|
|
98
99
|
@jit = true
|
|
99
100
|
@help = false
|
|
@@ -171,6 +172,9 @@ module Badline
|
|
|
171
172
|
|
|
172
173
|
def true_drive? = @true_drive
|
|
173
174
|
|
|
175
|
+
# Whether --save-snapshot adds VICE's modules, so x64sc opens it.
|
|
176
|
+
def vice? = @vice
|
|
177
|
+
|
|
174
178
|
def jit? = @jit
|
|
175
179
|
|
|
176
180
|
# The name of the model to build: a C64 Badline::Model names, a VIC-20
|
|
@@ -272,6 +276,7 @@ module Badline
|
|
|
272
276
|
when "--no-vsync" then @vsync = false
|
|
273
277
|
when "--verbose" then @verbose = true
|
|
274
278
|
when "--true-drive" then @true_drive = true
|
|
279
|
+
when "--vice" then @vice = true
|
|
275
280
|
when "--ntsc" then @models << "ntsc"
|
|
276
281
|
when "--c64" then @c64_mode = true
|
|
277
282
|
when "--unpaced" then @paced = false
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class Plus4
|
|
5
|
+
# The Plus/4's 6551 ACIA at $FD00-$FD0F, its four registers repeated,
|
|
6
|
+
# as a stub with nothing on the line: it never receives, its
|
|
7
|
+
# transmitter is always empty, and it never interrupts. The command and
|
|
8
|
+
# control registers keep what is written to them, and a write to the
|
|
9
|
+
# status register, a programmed reset, clears the command register's
|
|
10
|
+
# low five bits.
|
|
11
|
+
class ACIA
|
|
12
|
+
STATUS = 0x10
|
|
13
|
+
|
|
14
|
+
attr_reader :command, :control
|
|
15
|
+
|
|
16
|
+
def initialize
|
|
17
|
+
reset!
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def reset!
|
|
21
|
+
@command = 0
|
|
22
|
+
@control = 0
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def irq? = false
|
|
26
|
+
|
|
27
|
+
def peek(addr)
|
|
28
|
+
case addr & 0x03
|
|
29
|
+
when 1 then STATUS
|
|
30
|
+
when 2 then @command
|
|
31
|
+
when 3 then @control
|
|
32
|
+
else 0
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def poke(addr, value)
|
|
37
|
+
case addr & 0x03
|
|
38
|
+
when 1 then @command &= 0xe0
|
|
39
|
+
when 2 then @command = value
|
|
40
|
+
when 3 then @control = value
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|