badline 0.12.1 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -0
- data/CLAUDE.md +59 -31
- data/README.md +1 -1
- data/doc/library.md +9 -9
- data/doc/pinned-behaviour.md +105 -105
- data/doc/snapshots.md +1 -4
- data/lib/badline/audio/bare_player.rb +3 -3
- data/lib/badline/audio/cli.rb +6 -6
- data/lib/badline/audio/jukebox.rb +2 -2
- data/lib/badline/audio/machine_player.rb +2 -2
- data/lib/badline/{media → audio}/queue.rb +1 -1
- data/lib/badline/audio/queued_tune.rb +6 -6
- data/lib/badline/audio/renderer.rb +5 -5
- data/lib/badline/audio/stereo.rb +1 -1
- data/lib/badline/c128/{bus_state.rb → bus/saved_state.rb} +1 -1
- data/lib/badline/c128/bus.rb +18 -17
- data/lib/badline/c128/color_lines.rb +2 -2
- data/lib/badline/c128/cpu.rb +1 -1
- data/lib/badline/c128/drives.rb +10 -11
- data/lib/badline/c128/fast_serial.rb +5 -5
- data/lib/badline/c128/mmu_pages.rb +1 -1
- data/lib/badline/c128/modes.rb +2 -2
- data/lib/badline/c128/saved_state.rb +21 -47
- data/lib/badline/c128/z80.rb +2 -2
- data/lib/badline/c128.rb +14 -9
- data/lib/badline/{computer → c64}/attachments.rb +4 -6
- data/lib/badline/c64/banked_ram/banking.rb +32 -0
- data/lib/badline/c64/banked_ram/plus256k.rb +56 -0
- data/lib/badline/c64/banked_ram/plus60k.rb +45 -0
- data/lib/badline/c64/banked_ram/unexpanded.rb +30 -0
- data/lib/badline/c64/banked_ram.rb +23 -0
- data/lib/badline/c64/bus/extra_sids.rb +32 -0
- data/lib/badline/c64/bus/fittings.rb +40 -0
- data/lib/badline/c64/bus/pla.rb +149 -0
- data/lib/badline/c64/bus/roms.rb +41 -0
- data/lib/badline/c64/bus/saved_state.rb +68 -0
- data/lib/badline/c64/bus/sid_slots.rb +44 -0
- data/lib/badline/c64/bus.rb +218 -0
- data/lib/badline/c64/cartridge/action_replay.rb +128 -0
- data/lib/badline/c64/cartridge/atomic_power.rb +26 -0
- data/lib/badline/c64/cartridge/bank.rb +83 -0
- data/lib/badline/c64/cartridge/comal80.rb +52 -0
- data/lib/badline/c64/cartridge/dinamic.rb +36 -0
- data/lib/badline/c64/cartridge/easy_flash.rb +147 -0
- data/lib/badline/c64/cartridge/epyx_fastload.rb +81 -0
- data/lib/badline/c64/cartridge/final_cartridge3.rb +91 -0
- data/lib/badline/c64/cartridge/flash/saved_state.rb +40 -0
- data/lib/badline/c64/cartridge/flash.rb +279 -0
- data/lib/badline/c64/cartridge/freezer.rb +35 -0
- data/lib/badline/c64/cartridge/fun_play.rb +40 -0
- data/lib/badline/c64/cartridge/g_mod2.rb +76 -0
- data/lib/badline/c64/cartridge/game_system.rb +42 -0
- data/lib/badline/c64/cartridge/geo_ram.rb +81 -0
- data/lib/badline/c64/cartridge/kcs_power.rb +77 -0
- data/lib/badline/c64/cartridge/mach5.rb +34 -0
- data/lib/badline/c64/cartridge/magic_desk.rb +32 -0
- data/lib/badline/c64/cartridge/ocean.rb +37 -0
- data/lib/badline/c64/cartridge/pagefox.rb +70 -0
- data/lib/badline/c64/cartridge/retro_replay/saved_state.rb +47 -0
- data/lib/badline/c64/cartridge/retro_replay.rb +286 -0
- data/lib/badline/c64/cartridge/rex_utility.rb +31 -0
- data/lib/badline/c64/cartridge/rgcd.rb +60 -0
- data/lib/badline/c64/cartridge/saved_state.rb +63 -0
- data/lib/badline/c64/cartridge/simons_basic.rb +37 -0
- data/lib/badline/c64/cartridge/standard.rb +17 -0
- data/lib/badline/c64/cartridge/super_games.rb +50 -0
- data/lib/badline/c64/cartridge/westermann.rb +32 -0
- data/lib/badline/c64/cartridge/zaxxon.rb +68 -0
- data/lib/badline/c64/cartridge.rb +258 -0
- data/lib/badline/c64/color_memory.rb +27 -0
- data/lib/badline/{computer → c64}/common.rb +2 -2
- data/lib/badline/{computer → c64}/kernal_traps.rb +18 -18
- data/lib/badline/c64/reu/dma/saved_state.rb +52 -0
- data/lib/badline/c64/reu/dma.rb +275 -0
- data/lib/badline/c64/reu/ram.rb +109 -0
- data/lib/badline/c64/reu/saved_state.rb +55 -0
- data/lib/badline/c64/reu/trigger.rb +34 -0
- data/lib/badline/c64/reu.rb +291 -0
- data/lib/badline/{computer → c64}/saved_state.rb +13 -18
- data/lib/badline/{computer → c64}/true_drives.rb +11 -11
- data/lib/badline/{computer.rb → c64.rb} +18 -13
- data/lib/badline/chips/cia/fast_forward.rb +62 -0
- data/lib/badline/chips/cia/interrupt_register.rb +145 -0
- data/lib/badline/chips/cia/saved_state.rb +49 -0
- data/lib/badline/chips/cia/serial/saved_state.rb +45 -0
- data/lib/badline/chips/cia/serial.rb +250 -0
- data/lib/badline/chips/cia/time_of_day.rb +232 -0
- data/lib/badline/chips/cia/timer.rb +208 -0
- data/lib/badline/chips/cia.rb +281 -0
- data/lib/badline/chips/cpu/addressing.rb +133 -0
- data/lib/badline/chips/cpu/boundary.rb +56 -0
- data/lib/badline/chips/cpu/core.rb +167 -0
- data/lib/badline/chips/cpu/instruction.rb +338 -0
- data/lib/badline/chips/cpu/instruction_set/arithmetic.rb +118 -0
- data/lib/badline/chips/cpu/instruction_set/bitwise.rb +130 -0
- data/lib/badline/chips/cpu/instruction_set/branch.rb +83 -0
- data/lib/badline/chips/cpu/instruction_set/flag.rb +67 -0
- data/lib/badline/chips/cpu/instruction_set/illegal.rb +274 -0
- data/lib/badline/chips/cpu/instruction_set/inc_dec.rb +73 -0
- data/lib/badline/chips/cpu/instruction_set/stack.rb +56 -0
- data/lib/badline/chips/cpu/instruction_set/transfer.rb +141 -0
- data/lib/badline/chips/cpu/instruction_set.rb +59 -0
- data/lib/badline/chips/cpu/interrupts.rb +108 -0
- data/lib/badline/chips/cpu/microcode.rb +179 -0
- data/lib/badline/chips/cpu/operations.rb +90 -0
- data/lib/badline/chips/cpu/port.rb +116 -0
- data/lib/badline/chips/cpu/saved_state.rb +117 -0
- data/lib/badline/chips/cpu/stack_operations.rb +84 -0
- data/lib/badline/chips/cpu/traps.rb +23 -0
- data/lib/badline/chips/cpu.rb +12 -0
- data/lib/badline/chips/sid/catch_up.rb +122 -0
- data/lib/badline/chips/sid/decimator.rb +66 -0
- data/lib/badline/chips/sid/envelope/saved_state.rb +70 -0
- data/lib/badline/chips/sid/envelope.rb +241 -0
- data/lib/badline/chips/sid/filter/saved_state.rb +42 -0
- data/lib/badline/chips/sid/filter.rb +241 -0
- data/lib/badline/chips/sid/saved_state.rb +52 -0
- data/lib/badline/chips/sid/voice.rb +79 -0
- data/lib/badline/chips/sid/waveform/combined.rb +128 -0
- data/lib/badline/chips/sid/waveform/fast_forward.rb +107 -0
- data/lib/badline/chips/sid/waveform/noise_writeback.rb +124 -0
- data/lib/badline/chips/sid/waveform/saved_state.rb +68 -0
- data/lib/badline/chips/sid/waveform.rb +307 -0
- data/lib/badline/chips/sid.rb +265 -0
- data/lib/badline/{c128 → chips}/vdc/memory.rb +1 -1
- data/lib/badline/{c128 → chips}/vdc/painter.rb +1 -1
- data/lib/badline/{c128 → chips}/vdc/raster.rb +1 -1
- data/lib/badline/chips/vdc/saved_state.rb +36 -0
- data/lib/badline/{c128 → chips}/vdc/window.rb +1 -1
- data/lib/badline/{c128 → chips}/vdc.rb +7 -31
- data/lib/badline/chips/via/control_lines.rb +124 -0
- data/lib/badline/chips/via/fast_forward.rb +55 -0
- data/lib/badline/chips/via/interrupt_register.rb +69 -0
- data/lib/badline/chips/via/saved_state.rb +44 -0
- data/lib/badline/chips/via/shift_register.rb +182 -0
- data/lib/badline/chips/via/timer1.rb +133 -0
- data/lib/badline/chips/via/timer2.rb +135 -0
- data/lib/badline/chips/via.rb +268 -0
- data/lib/badline/chips/vic/bank.rb +135 -0
- data/lib/badline/chips/vic/border_mask.rb +88 -0
- data/lib/badline/chips/vic/collisions.rb +117 -0
- data/lib/badline/chips/vic/color_patches.rb +49 -0
- data/lib/badline/chips/vic/display_state.rb +187 -0
- data/lib/badline/chips/vic/graphics_mode.rb +166 -0
- data/lib/badline/chips/vic/graphics_shifter/saved_state.rb +40 -0
- data/lib/badline/chips/vic/graphics_shifter.rb +187 -0
- data/lib/badline/chips/vic/register_log.rb +83 -0
- data/lib/badline/chips/vic/registers.rb +197 -0
- data/lib/badline/chips/vic/saved_state.rb +82 -0
- data/lib/badline/chips/vic/sequencer/saved_state.rb +91 -0
- data/lib/badline/chips/vic/sequencer.rb +277 -0
- data/lib/badline/chips/vic/sequencer_output.rb +118 -0
- data/lib/badline/chips/vic/sprite/internal_bus.rb +70 -0
- data/lib/badline/chips/vic/sprite/saved_state.rb +66 -0
- data/lib/badline/chips/vic/sprite/shifter.rb +148 -0
- data/lib/badline/chips/vic/sprite/timing.rb +58 -0
- data/lib/badline/chips/vic/sprite.rb +339 -0
- data/lib/badline/chips/vic/sprites/saved_state.rb +59 -0
- data/lib/badline/chips/vic/sprites.rb +284 -0
- data/lib/badline/chips/vic.rb +783 -0
- data/lib/badline/chips/vic_i/painter/saved_state.rb +40 -0
- data/lib/badline/{vic20/vic → chips/vic_i}/painter.rb +6 -30
- data/lib/badline/{vic20/vic → chips/vic_i}/saved_state.rb +2 -2
- data/lib/badline/chips/vic_i/sound/output.rb +85 -0
- data/lib/badline/chips/vic_i/sound.rb +235 -0
- data/lib/badline/{vic20/vic → chips/vic_i}/text_window.rb +2 -2
- data/lib/badline/{vic20/vic.rb → chips/vic_i.rb} +5 -5
- data/lib/badline/chips/z80/arithmetic.rb +119 -0
- data/lib/badline/chips/z80/bit_page.rb +57 -0
- data/lib/badline/chips/z80/block_io.rb +60 -0
- data/lib/badline/chips/z80/block_transfers.rb +61 -0
- data/lib/badline/chips/z80/bus_cycles.rb +113 -0
- data/lib/badline/chips/z80/core.rb +115 -0
- data/lib/badline/chips/z80/exchanges.rb +52 -0
- data/lib/badline/chips/z80/extended_page.rb +91 -0
- data/lib/badline/chips/z80/flags.rb +39 -0
- data/lib/badline/chips/z80/interrupt_acceptance.rb +48 -0
- data/lib/badline/chips/z80/jumps.rb +84 -0
- data/lib/badline/chips/z80/loads.rb +100 -0
- data/lib/badline/chips/z80/main_page.rb +136 -0
- data/lib/badline/chips/z80/registers.rb +122 -0
- data/lib/badline/chips/z80/saved_state.rb +71 -0
- data/lib/badline/chips/z80/shifts.rb +66 -0
- data/lib/badline/chips/z80.rb +13 -0
- data/lib/badline/core.rb +26 -28
- data/lib/badline/drives/datasette/saved_state.rb +37 -0
- data/lib/badline/drives/datasette.rb +140 -0
- data/lib/badline/drives/engine/core.rb +149 -0
- data/lib/badline/drives/engine/fast_serial.rb +75 -0
- data/lib/badline/drives/engine/idle.rb +127 -0
- data/lib/badline/drives/engine/idle_cpu.rb +30 -0
- data/lib/badline/drives/engine/orbit.rb +81 -0
- data/lib/badline/drives/engine/serial_lines.rb +75 -0
- data/lib/badline/drives/engine/sleep.rb +114 -0
- data/lib/badline/drives/engine/vias.rb +86 -0
- data/lib/badline/drives/engine/watch.rb +152 -0
- data/lib/badline/drives/engine.rb +11 -0
- data/lib/badline/drives/model1541/bus.rb +88 -0
- data/lib/badline/drives/model1541/byte_ready.rb +50 -0
- data/lib/badline/drives/model1541/cpu.rb +13 -0
- data/lib/badline/drives/model1541/disk/saved_state.rb +88 -0
- data/lib/badline/drives/model1541/disk.rb +317 -0
- data/lib/badline/drives/model1541/disk_via.rb +38 -0
- data/lib/badline/drives/model1541/gcr.rb +59 -0
- data/lib/badline/drives/model1541/mechanism/saved_state.rb +72 -0
- data/lib/badline/drives/model1541/mechanism.rb +315 -0
- data/lib/badline/drives/model1541/rotation.rb +123 -0
- data/lib/badline/drives/model1541/saved_state.rb +44 -0
- data/lib/badline/drives/model1541/sector_reader.rb +78 -0
- data/lib/badline/drives/model1541/serial_port.rb +20 -0
- data/lib/badline/drives/model1541/track.rb +100 -0
- data/lib/badline/drives/model1541.rb +81 -0
- data/lib/badline/drives/model1571/bus.rb +113 -0
- data/lib/badline/drives/model1571/cpu.rb +13 -0
- data/lib/badline/drives/model1571/saved_state.rb +47 -0
- data/lib/badline/drives/model1571/serial_port.rb +39 -0
- data/lib/badline/drives/model1571/serial_via.rb +27 -0
- data/lib/badline/drives/model1571/wd1770.rb +122 -0
- data/lib/badline/drives/model1571.rb +142 -0
- data/lib/badline/drives/model1581/bus.rb +139 -0
- data/lib/badline/drives/model1581/cpu.rb +13 -0
- data/lib/badline/drives/model1581/disk/saved_state.rb +89 -0
- data/lib/badline/drives/model1581/disk.rb +137 -0
- data/lib/badline/drives/model1581/mechanism.rb +119 -0
- data/lib/badline/drives/model1581/saved_state.rb +42 -0
- data/lib/badline/drives/model1581/serial_port.rb +54 -0
- data/lib/badline/drives/model1581/slot.rb +79 -0
- data/lib/badline/drives/model1581/track.rb +102 -0
- data/lib/badline/drives/model1581/track_bytes.rb +77 -0
- data/lib/badline/drives/model1581/wd1772/registers.rb +91 -0
- data/lib/badline/drives/model1581/wd1772/saved_state.rb +68 -0
- data/lib/badline/drives/model1581/wd1772/sector_writes.rb +75 -0
- data/lib/badline/drives/model1581/wd1772/sectors.rb +152 -0
- data/lib/badline/drives/model1581/wd1772/stepping.rb +111 -0
- data/lib/badline/drives/model1581/wd1772/tracks.rb +127 -0
- data/lib/badline/drives/model1581/wd1772/turn.rb +75 -0
- data/lib/badline/drives/model1581/wd1772.rb +218 -0
- data/lib/badline/drives/model1581.rb +206 -0
- data/lib/badline/drives/serial_bus.rb +161 -0
- data/lib/badline/frontend/boot.rb +3 -3
- data/lib/badline/frontend/machine_window.rb +3 -1
- data/lib/badline/frontend/player/filter_view.rb +1 -1
- data/lib/badline/frontend/player/player_controller.rb +2 -2
- data/lib/badline/frontend/player/player_screen.rb +1 -0
- data/lib/badline/frontend/player/theme.rb +7 -7
- data/lib/badline/frontend/timeline.rb +3 -3
- data/lib/badline/input/control_ports.rb +78 -0
- data/lib/badline/input/joystick.rb +27 -0
- data/lib/badline/input/keyboard.rb +114 -0
- data/lib/badline/input.rb +3 -0
- data/lib/badline/kernal_trap/{drive → dos}/block_commands.rb +1 -1
- data/lib/badline/kernal_trap/dos/channel.rb +183 -0
- data/lib/badline/kernal_trap/{drive → dos}/channels.rb +1 -1
- data/lib/badline/kernal_trap/{drive → dos}/memory.rb +1 -1
- data/lib/badline/kernal_trap/{drive → dos}/parameters.rb +1 -1
- data/lib/badline/kernal_trap/{drive → dos}/status.rb +1 -1
- data/lib/badline/kernal_trap/{drive → dos}/write_file.rb +1 -1
- data/lib/badline/kernal_trap/{drive → dos}/writes.rb +1 -1
- data/lib/badline/kernal_trap/{drive.rb → dos.rb} +11 -10
- data/lib/badline/kernal_trap/load.rb +5 -5
- data/lib/badline/kernal_trap/save.rb +4 -4
- data/lib/badline/kernal_trap/serial.rb +7 -7
- data/lib/badline/kernal_trap.rb +1 -2
- data/lib/badline/machine/clocking.rb +1 -1
- data/lib/badline/machine.rb +5 -5
- data/lib/badline/media/true_drive.rb +1 -1
- data/lib/badline/media/tune.rb +2 -2
- data/lib/badline/media.rb +3 -3
- data/lib/badline/model.rb +1 -1
- data/lib/badline/roms/README +6 -6
- data/lib/badline/sdl.rb +1 -0
- data/lib/badline/{storage/sid_file.rb → sid_tune/file.rb} +3 -3
- data/lib/badline/{storage → sid_tune}/hvsc.rb +7 -7
- data/lib/badline/{storage → sid_tune}/song_lengths.rb +2 -2
- data/lib/badline/{storage → sid_tune}/stil/credit.rb +1 -1
- data/lib/badline/{storage → sid_tune}/stil.rb +3 -3
- data/lib/badline/sid_tune.rb +6 -0
- data/lib/badline/snapshot/c128_setup.rb +43 -0
- data/lib/badline/snapshot/c64_setup.rb +79 -0
- data/lib/badline/snapshot/image.rb +5 -25
- data/lib/badline/snapshot/machine_state.rb +1 -1
- data/lib/badline/snapshot/setup.rb +22 -66
- data/lib/badline/snapshot/state.rb +8 -18
- data/lib/badline/snapshot/storage_setup.rb +68 -0
- data/lib/badline/snapshot/vic20_setup.rb +37 -0
- data/lib/badline/snapshot/vice/c64_mem.rb +1 -1
- data/lib/badline/snapshot/vice/restore.rb +1 -1
- data/lib/badline/snapshot/vice/reu1764.rb +1 -1
- data/lib/badline/snapshot/vice/reu_fields.rb +40 -0
- data/lib/badline/snapshot/vice.rb +7 -5
- data/lib/badline/snapshot.rb +3 -4
- data/lib/badline/storage/d64_image.rb +0 -2
- data/lib/badline/storage/d71_image.rb +0 -2
- data/lib/badline/storage/d81_image.rb +0 -2
- data/lib/badline/storage/disk_image.rb +3 -6
- data/lib/badline/storage/g64_image.rb +2 -2
- data/lib/badline/storage/host_directory.rb +0 -5
- data/lib/badline/storage/t64.rb +2 -8
- data/lib/badline/storage/unavailable.rb +1 -1
- data/lib/badline/storage.rb +0 -37
- data/lib/badline/support/c128_checkpoint.rb +39 -0
- data/lib/badline/support/checkpoint.rb +108 -0
- data/lib/badline/support/vic20_checkpoint.rb +38 -0
- data/lib/badline/support.rb +5 -0
- data/lib/badline/version.rb +1 -1
- data/lib/badline/vic20/attachments.rb +5 -5
- data/lib/badline/vic20/bus/saved_state.rb +35 -0
- data/lib/badline/vic20/bus.rb +3 -25
- data/lib/badline/vic20/cpu.rb +1 -1
- data/lib/badline/vic20/port_wiring.rb +4 -4
- data/lib/badline/vic20/saved_state.rb +16 -30
- data/lib/badline/vic20/user_via_ports.rb +2 -2
- data/lib/badline/vic20.rb +19 -14
- metadata +245 -221
- data/lib/badline/address_bus/extra_sids.rb +0 -30
- data/lib/badline/address_bus/fittings.rb +0 -38
- data/lib/badline/address_bus/pla.rb +0 -147
- data/lib/badline/address_bus/roms.rb +0 -39
- data/lib/badline/address_bus/saved_state.rb +0 -66
- data/lib/badline/address_bus/sid_slots.rb +0 -42
- data/lib/badline/address_bus.rb +0 -216
- data/lib/badline/cartridge/action_replay.rb +0 -126
- data/lib/badline/cartridge/atomic_power.rb +0 -24
- data/lib/badline/cartridge/bank.rb +0 -81
- data/lib/badline/cartridge/comal80.rb +0 -50
- data/lib/badline/cartridge/dinamic.rb +0 -34
- data/lib/badline/cartridge/easy_flash.rb +0 -145
- data/lib/badline/cartridge/epyx_fastload.rb +0 -79
- data/lib/badline/cartridge/final_cartridge3.rb +0 -89
- data/lib/badline/cartridge/flash.rb +0 -306
- data/lib/badline/cartridge/freezer.rb +0 -33
- data/lib/badline/cartridge/fun_play.rb +0 -38
- data/lib/badline/cartridge/g_mod2.rb +0 -74
- data/lib/badline/cartridge/game_system.rb +0 -40
- data/lib/badline/cartridge/geo_ram.rb +0 -79
- data/lib/badline/cartridge/kcs_power.rb +0 -75
- data/lib/badline/cartridge/mach5.rb +0 -32
- data/lib/badline/cartridge/magic_desk.rb +0 -30
- data/lib/badline/cartridge/ocean.rb +0 -35
- data/lib/badline/cartridge/pagefox.rb +0 -68
- data/lib/badline/cartridge/retro_replay.rb +0 -320
- data/lib/badline/cartridge/rex_utility.rb +0 -29
- data/lib/badline/cartridge/rgcd.rb +0 -58
- data/lib/badline/cartridge/simons_basic.rb +0 -35
- data/lib/badline/cartridge/standard.rb +0 -15
- data/lib/badline/cartridge/super_games.rb +0 -48
- data/lib/badline/cartridge/westermann.rb +0 -30
- data/lib/badline/cartridge/zaxxon.rb +0 -66
- data/lib/badline/cartridge.rb +0 -303
- data/lib/badline/checkpoint.rb +0 -98
- data/lib/badline/cia/fast_forward.rb +0 -60
- data/lib/badline/cia/interrupt_register.rb +0 -143
- data/lib/badline/cia/serial.rb +0 -275
- data/lib/badline/cia/state.rb +0 -47
- data/lib/badline/cia/timer.rb +0 -206
- data/lib/badline/cia.rb +0 -279
- data/lib/badline/color_memory.rb +0 -25
- data/lib/badline/control_ports.rb +0 -76
- data/lib/badline/cpu/addressing.rb +0 -131
- data/lib/badline/cpu/boundary.rb +0 -54
- data/lib/badline/cpu/core.rb +0 -165
- data/lib/badline/cpu/microcode.rb +0 -177
- data/lib/badline/cpu/operations.rb +0 -88
- data/lib/badline/cpu/saved_state.rb +0 -115
- data/lib/badline/cpu/stack_operations.rb +0 -82
- data/lib/badline/cpu.rb +0 -10
- data/lib/badline/cpu_port.rb +0 -112
- data/lib/badline/datasette.rb +0 -161
- data/lib/badline/drive/core.rb +0 -147
- data/lib/badline/drive/fast_serial.rb +0 -73
- data/lib/badline/drive/idle.rb +0 -125
- data/lib/badline/drive/idle_cpu.rb +0 -28
- data/lib/badline/drive/orbit.rb +0 -79
- data/lib/badline/drive/serial_lines.rb +0 -73
- data/lib/badline/drive/sleep.rb +0 -112
- data/lib/badline/drive/vias.rb +0 -84
- data/lib/badline/drive/watch.rb +0 -150
- data/lib/badline/drive.rb +0 -11
- data/lib/badline/drive1541/bus.rb +0 -86
- data/lib/badline/drive1541/byte_ready.rb +0 -48
- data/lib/badline/drive1541/cpu.rb +0 -11
- data/lib/badline/drive1541/disk.rb +0 -315
- data/lib/badline/drive1541/disk_state.rb +0 -86
- data/lib/badline/drive1541/disk_via.rb +0 -36
- data/lib/badline/drive1541/gcr.rb +0 -57
- data/lib/badline/drive1541/mechanism.rb +0 -313
- data/lib/badline/drive1541/mechanism_state.rb +0 -68
- data/lib/badline/drive1541/rotation.rb +0 -121
- data/lib/badline/drive1541/sector_reader.rb +0 -76
- data/lib/badline/drive1541/serial_port.rb +0 -18
- data/lib/badline/drive1541/track.rb +0 -98
- data/lib/badline/drive1541.rb +0 -111
- data/lib/badline/drive1571/bus.rb +0 -111
- data/lib/badline/drive1571/cpu.rb +0 -11
- data/lib/badline/drive1571/serial_port.rb +0 -37
- data/lib/badline/drive1571/serial_via.rb +0 -25
- data/lib/badline/drive1571/wd1770.rb +0 -120
- data/lib/badline/drive1571.rb +0 -175
- data/lib/badline/drive1581/bus.rb +0 -137
- data/lib/badline/drive1581/cpu.rb +0 -11
- data/lib/badline/drive1581/disk.rb +0 -135
- data/lib/badline/drive1581/disk_state.rb +0 -87
- data/lib/badline/drive1581/mechanism.rb +0 -117
- data/lib/badline/drive1581/serial_port.rb +0 -52
- data/lib/badline/drive1581/slot.rb +0 -78
- data/lib/badline/drive1581/track.rb +0 -100
- data/lib/badline/drive1581/track_bytes.rb +0 -75
- data/lib/badline/drive1581/wd1772/registers.rb +0 -89
- data/lib/badline/drive1581/wd1772/sector_writes.rb +0 -73
- data/lib/badline/drive1581/wd1772/sectors.rb +0 -150
- data/lib/badline/drive1581/wd1772/state.rb +0 -66
- data/lib/badline/drive1581/wd1772/stepping.rb +0 -109
- data/lib/badline/drive1581/wd1772/tracks.rb +0 -125
- data/lib/badline/drive1581/wd1772/turn.rb +0 -73
- data/lib/badline/drive1581/wd1772.rb +0 -216
- data/lib/badline/drive1581.rb +0 -233
- data/lib/badline/iec_bus.rb +0 -159
- data/lib/badline/instruction.rb +0 -334
- data/lib/badline/instruction_set/arithmetic.rb +0 -114
- data/lib/badline/instruction_set/bitwise.rb +0 -126
- data/lib/badline/instruction_set/branch.rb +0 -79
- data/lib/badline/instruction_set/flag.rb +0 -63
- data/lib/badline/instruction_set/illegal.rb +0 -270
- data/lib/badline/instruction_set/inc_dec.rb +0 -69
- data/lib/badline/instruction_set/stack.rb +0 -52
- data/lib/badline/instruction_set/transfer.rb +0 -137
- data/lib/badline/instruction_set.rb +0 -55
- data/lib/badline/interrupts.rb +0 -104
- data/lib/badline/joystick.rb +0 -25
- data/lib/badline/kernal_trap/channel.rb +0 -181
- data/lib/badline/keyboard.rb +0 -112
- data/lib/badline/ram_expansion/banking.rb +0 -30
- data/lib/badline/ram_expansion/plus256k.rb +0 -54
- data/lib/badline/ram_expansion/plus60k.rb +0 -43
- data/lib/badline/ram_expansion/unexpanded.rb +0 -28
- data/lib/badline/ram_expansion.rb +0 -21
- data/lib/badline/reu/dma/saved_state.rb +0 -50
- data/lib/badline/reu/dma.rb +0 -273
- data/lib/badline/reu/ram.rb +0 -107
- data/lib/badline/reu/saved_state.rb +0 -80
- data/lib/badline/reu/trigger.rb +0 -32
- data/lib/badline/reu.rb +0 -289
- data/lib/badline/sid/catch_up.rb +0 -120
- data/lib/badline/sid/decimator.rb +0 -64
- data/lib/badline/sid/envelope/state.rb +0 -68
- data/lib/badline/sid/envelope.rb +0 -239
- data/lib/badline/sid/filter.rb +0 -263
- data/lib/badline/sid/voice.rb +0 -77
- data/lib/badline/sid/waveform/combined.rb +0 -126
- data/lib/badline/sid/waveform/fast_forward.rb +0 -105
- data/lib/badline/sid/waveform/noise_writeback.rb +0 -122
- data/lib/badline/sid/waveform/state.rb +0 -66
- data/lib/badline/sid/waveform.rb +0 -305
- data/lib/badline/sid.rb +0 -303
- data/lib/badline/time_of_day.rb +0 -228
- data/lib/badline/traps.rb +0 -19
- data/lib/badline/via/control_lines.rb +0 -122
- data/lib/badline/via/fast_forward.rb +0 -53
- data/lib/badline/via/interrupt_register.rb +0 -67
- data/lib/badline/via/shift_register.rb +0 -180
- data/lib/badline/via/state.rb +0 -42
- data/lib/badline/via/timer1.rb +0 -131
- data/lib/badline/via/timer2.rb +0 -133
- data/lib/badline/via.rb +0 -266
- data/lib/badline/vic/bank.rb +0 -133
- data/lib/badline/vic/border_mask.rb +0 -86
- data/lib/badline/vic/collisions.rb +0 -115
- data/lib/badline/vic/color_patches.rb +0 -47
- data/lib/badline/vic/display_state.rb +0 -185
- data/lib/badline/vic/graphics_mode.rb +0 -164
- data/lib/badline/vic/graphics_shifter.rb +0 -207
- data/lib/badline/vic/register_log.rb +0 -81
- data/lib/badline/vic/registers.rb +0 -195
- data/lib/badline/vic/sequencer.rb +0 -275
- data/lib/badline/vic/sequencer_output.rb +0 -116
- data/lib/badline/vic/sequencer_state.rb +0 -89
- data/lib/badline/vic/sprite/internal_bus.rb +0 -68
- data/lib/badline/vic/sprite/saved_state.rb +0 -64
- data/lib/badline/vic/sprite/shifter.rb +0 -146
- data/lib/badline/vic/sprite/timing.rb +0 -56
- data/lib/badline/vic/sprite.rb +0 -337
- data/lib/badline/vic/sprites.rb +0 -282
- data/lib/badline/vic/sprites_state.rb +0 -57
- data/lib/badline/vic.rb +0 -853
- data/lib/badline/vic20/sound/output.rb +0 -83
- data/lib/badline/vic20/sound.rb +0 -233
- data/lib/badline/z80/arithmetic.rb +0 -117
- data/lib/badline/z80/bit_page.rb +0 -55
- data/lib/badline/z80/block_io.rb +0 -58
- data/lib/badline/z80/block_transfers.rb +0 -59
- data/lib/badline/z80/bus_cycles.rb +0 -111
- data/lib/badline/z80/core.rb +0 -113
- data/lib/badline/z80/exchanges.rb +0 -50
- data/lib/badline/z80/extended_page.rb +0 -89
- data/lib/badline/z80/flags.rb +0 -37
- data/lib/badline/z80/interrupt_acceptance.rb +0 -46
- data/lib/badline/z80/jumps.rb +0 -82
- data/lib/badline/z80/loads.rb +0 -98
- data/lib/badline/z80/main_page.rb +0 -134
- data/lib/badline/z80/registers.rb +0 -120
- data/lib/badline/z80/saved_state.rb +0 -69
- data/lib/badline/z80/shifts.rb +0 -64
- data/lib/badline/z80.rb +0 -11
- /data/lib/badline/snapshot/{fields.rb → vice/fields.rb} +0 -0
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module KernalTrap
|
|
5
|
+
class DOS
|
|
6
|
+
# One open channel on the virtual drive, holding a file, a block buffer
|
|
7
|
+
# or the command channel's status message. It gives out one byte at a
|
|
8
|
+
# time and flags the last one, so the bus can raise EOI with it. A
|
|
9
|
+
# channel cut short by a read error never flags one, and holds the
|
|
10
|
+
# error for the drive to report once its bytes run out.
|
|
11
|
+
class Channel
|
|
12
|
+
attr_accessor :buffer
|
|
13
|
+
attr_reader :error, :pointer
|
|
14
|
+
attr_writer :lead
|
|
15
|
+
|
|
16
|
+
def initialize(bytes = [], error: nil, writable: false, base: 0)
|
|
17
|
+
@base = base
|
|
18
|
+
replace(bytes)
|
|
19
|
+
@error = error
|
|
20
|
+
@writable = writable
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# A block buffer opened with "#", which reads and writes one of the
|
|
24
|
+
# drive's buffers in its RAM, so M-R and M-W reach the same bytes. It
|
|
25
|
+
# hands out the whole block unless a B-R sets a shorter end, and
|
|
26
|
+
# flags that byte as the last. The DOS opens it with the pointer at 1
|
|
27
|
+
# and the buffer's number as the byte to send, so the first read
|
|
28
|
+
# answers with the number and the next one moves on to the third
|
|
29
|
+
# byte.
|
|
30
|
+
def self.buffer(memory, number)
|
|
31
|
+
new(memory.ram, writable: true, base: Memory.buffer_address(number)).tap do |channel|
|
|
32
|
+
channel.buffer = number
|
|
33
|
+
channel.rewind(BLOCK_SIZE)
|
|
34
|
+
channel.pointer = 1
|
|
35
|
+
channel.lead = number
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# A file's bytes, up to the first block its chain can't read. The
|
|
40
|
+
# drive reads a block ahead before sending the last byte of the one
|
|
41
|
+
# before, so a bad block holds that byte back too, and a bad first
|
|
42
|
+
# block or a missing file leaves nothing to send.
|
|
43
|
+
def self.for_file(storage, name, type)
|
|
44
|
+
data = storage.read_file(name, type:)
|
|
45
|
+
return new([], error: [FILE_NOT_FOUND]) unless data
|
|
46
|
+
|
|
47
|
+
failure = storage.respond_to?(:read_error) && storage.read_error(name, type:)
|
|
48
|
+
return new(data) unless failure
|
|
49
|
+
|
|
50
|
+
new(data[0, failure[:offset] - 1] || [], error: failure.values_at(:error, :track, :sector))
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# The file an open names. The drive keeps the first block of the file
|
|
54
|
+
# a LOAD (secondary address 0) opens at $7E and $026F of its memory,
|
|
55
|
+
# and a LOAD of a name starting with "*" reopens that file rather than
|
|
56
|
+
# the first one on the disk. Loaders write the block there with M-W
|
|
57
|
+
# to load a file the directory doesn't list. A LOAD of "$" reads the
|
|
58
|
+
# directory as a BASIC program, which a pattern after a colon narrows
|
|
59
|
+
# to the files it names.
|
|
60
|
+
def self.for_name(storage, memory, secondary, name, type)
|
|
61
|
+
return new(storage.directory.bytes(name)) if listing?(storage, secondary, name)
|
|
62
|
+
|
|
63
|
+
file = Storage.parse_name(name).first
|
|
64
|
+
return for_file(storage, file, type) unless secondary.zero? && storage.respond_to?(:first_block)
|
|
65
|
+
|
|
66
|
+
last = memory.last_program if name.start_with?("*")
|
|
67
|
+
return at_block(storage, *last) if last
|
|
68
|
+
|
|
69
|
+
block = storage.first_block(file, type:)
|
|
70
|
+
memory.last_program = block if block
|
|
71
|
+
for_file(storage, file, type)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def self.listing?(storage, secondary, name)
|
|
75
|
+
secondary.zero? && name.start_with?("$") && storage.respond_to?(:directory)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
# The file whose chain starts at the block.
|
|
79
|
+
def self.at_block(storage, track, sector)
|
|
80
|
+
data = storage.read_file_at(track, sector)
|
|
81
|
+
data ? new(data) : new([], error: [ILLEGAL_TRACK_OR_SECTOR, track, sector])
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# Reads what save_state wrote after the flag that marks a file open
|
|
85
|
+
# for writing (Channels.channel_from_state). A buffer channel
|
|
86
|
+
# takes its block in `ram`, the drive's RAM, again.
|
|
87
|
+
def self.from_state(input, ram)
|
|
88
|
+
new.tap { |channel| channel.load_state(input, ram) }
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# A buffer channel's bytes are the drive's RAM, which the drive
|
|
92
|
+
# writes itself.
|
|
93
|
+
def save_state(out)
|
|
94
|
+
out.boolean(false).boolean(@writable).int(@base).int(@length).int(@pointer)
|
|
95
|
+
out.optional_int(@lead).optional_int(@buffer).boolean(!@error.nil?)
|
|
96
|
+
out.ints(@error) if @error
|
|
97
|
+
out.blob(@bytes) unless @writable
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def load_state(input, ram)
|
|
101
|
+
@writable = input.boolean?
|
|
102
|
+
@base = input.int
|
|
103
|
+
@length = input.int
|
|
104
|
+
@pointer = input.int
|
|
105
|
+
@lead = input.optional_int
|
|
106
|
+
@buffer = input.optional_int
|
|
107
|
+
@error = input.boolean? ? input.ints : nil
|
|
108
|
+
@bytes = @writable ? ram : input.blob
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
def replace(bytes, length = bytes.length)
|
|
112
|
+
@bytes = bytes
|
|
113
|
+
rewind(length)
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
def rewind(length)
|
|
117
|
+
@length = length
|
|
118
|
+
self.pointer = 0
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def pointer=(position)
|
|
122
|
+
@pointer = position
|
|
123
|
+
@lead = nil
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
# A block read into the channel. A buffer channel takes it into its
|
|
127
|
+
# buffer, a file channel hands it out in place of the file.
|
|
128
|
+
def load(block, length)
|
|
129
|
+
return replace(block.dup, length) unless @writable
|
|
130
|
+
|
|
131
|
+
@bytes[@base, block.length] = block
|
|
132
|
+
rewind(length)
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def writable? = @writable
|
|
136
|
+
|
|
137
|
+
# A buffer channel's block, as a block write puts it on the disk.
|
|
138
|
+
def block = @bytes[@base, BLOCK_SIZE]
|
|
139
|
+
|
|
140
|
+
def exhausted?
|
|
141
|
+
@pointer >= @length
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
# A file that holds nothing but its error never opened.
|
|
145
|
+
def failed?
|
|
146
|
+
exhausted? && !@error.nil?
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# Each byte lands at the pointer, which wraps within the block.
|
|
150
|
+
def write(bytes)
|
|
151
|
+
@lead = nil
|
|
152
|
+
bytes.each do |byte|
|
|
153
|
+
@bytes[@base + @pointer] = byte
|
|
154
|
+
@pointer = (@pointer + 1) & 0xff
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def read
|
|
159
|
+
return read_buffer if @writable
|
|
160
|
+
return if exhausted?
|
|
161
|
+
|
|
162
|
+
byte = @lead || @bytes[@base + @pointer]
|
|
163
|
+
@lead = nil
|
|
164
|
+
@pointer += 1
|
|
165
|
+
[byte, exhausted? && !@error]
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
private
|
|
169
|
+
|
|
170
|
+
# A buffer never runs out. Past its last byte, which goes out with
|
|
171
|
+
# EOI, the pointer wraps back to the second, and a pointer set past
|
|
172
|
+
# the end runs on around the block to it.
|
|
173
|
+
def read_buffer
|
|
174
|
+
byte = @lead || @bytes[@base + @pointer]
|
|
175
|
+
@lead = nil
|
|
176
|
+
last = @pointer == @length - 1
|
|
177
|
+
@pointer = last ? 1 : (@pointer + 1) & 0xff
|
|
178
|
+
[byte, last]
|
|
179
|
+
end
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
end
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Badline
|
|
4
4
|
module KernalTrap
|
|
5
|
-
class
|
|
5
|
+
class DOS
|
|
6
6
|
# The drive's open data channels by secondary address, and the five
|
|
7
7
|
# buffers they hold. The DOS hands out the highest free buffer.
|
|
8
8
|
# Reading the BAM when it initializes the disk takes buffer 4, so
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Badline
|
|
4
4
|
module KernalTrap
|
|
5
|
-
class
|
|
5
|
+
class DOS
|
|
6
6
|
# The drive's 2K of RAM, as M-W and M-R reach it, with the job queue
|
|
7
7
|
# that runs a read job written into it: a job code for each of five
|
|
8
8
|
# buffers at $00, their track and sector pairs from $06, and the
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Badline
|
|
4
4
|
module KernalTrap
|
|
5
|
-
class
|
|
5
|
+
class DOS
|
|
6
6
|
# The numbers a DOS command takes. The DOS skips spaces, commas and
|
|
7
7
|
# cursor-rights before a parameter, reads it from the characters $30
|
|
8
8
|
# to $3F that follow, the low nibble of each, and skips whatever
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Badline
|
|
4
4
|
module KernalTrap
|
|
5
|
-
class
|
|
5
|
+
class DOS
|
|
6
6
|
# A channel open for writing a file. It gathers the bytes sent to it,
|
|
7
7
|
# and the drive writes the file to the disk when the channel closes.
|
|
8
8
|
# An append starts from the file's end, a replace writes over the
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
module Badline
|
|
4
4
|
module KernalTrap
|
|
5
|
-
class
|
|
5
|
+
class DOS
|
|
6
6
|
# Opens for writing, the S command and the reports a write makes. A
|
|
7
7
|
# file open for writing takes the type its name asks for, or SEQ on a
|
|
8
8
|
# data channel. On a write-protected disk, or storage that doesn't
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "badline/kernal_trap/
|
|
4
|
-
require "badline/kernal_trap/
|
|
5
|
-
require "badline/kernal_trap/
|
|
6
|
-
require "badline/kernal_trap/
|
|
7
|
-
require "badline/kernal_trap/
|
|
8
|
-
require "badline/kernal_trap/
|
|
9
|
-
require "badline/kernal_trap/
|
|
3
|
+
require "badline/kernal_trap/dos/block_commands"
|
|
4
|
+
require "badline/kernal_trap/dos/channel"
|
|
5
|
+
require "badline/kernal_trap/dos/channels"
|
|
6
|
+
require "badline/kernal_trap/dos/memory"
|
|
7
|
+
require "badline/kernal_trap/dos/parameters"
|
|
8
|
+
require "badline/kernal_trap/dos/status"
|
|
9
|
+
require "badline/kernal_trap/dos/writes"
|
|
10
|
+
require "badline/kernal_trap/dos/write_file"
|
|
10
11
|
|
|
11
12
|
module Badline
|
|
12
13
|
module KernalTrap
|
|
@@ -16,7 +17,7 @@ module Badline
|
|
|
16
17
|
# LOAD. A disk image whose host file takes writes takes files, blocks
|
|
17
18
|
# and BAM changes too. Other disks are write-protected, though storage
|
|
18
19
|
# that can write files still takes a SAVE handed over whole.
|
|
19
|
-
class
|
|
20
|
+
class DOS
|
|
20
21
|
include BlockCommands
|
|
21
22
|
include Writes
|
|
22
23
|
|
|
@@ -146,10 +147,10 @@ module Badline
|
|
|
146
147
|
# vector, as U: does.
|
|
147
148
|
def reset! = reset(cold: true)
|
|
148
149
|
|
|
149
|
-
# The mounted storage's setup
|
|
150
|
+
# The mounted storage's setup (Snapshot::StorageSetup), then the drive's
|
|
150
151
|
# RAM, its status and its open channels.
|
|
151
152
|
def save_state(out)
|
|
152
|
-
@storage
|
|
153
|
+
Snapshot::StorageSetup.write(@storage, out)
|
|
153
154
|
out.marker("TRAP DRIVE")
|
|
154
155
|
@memory.save_state(out)
|
|
155
156
|
@status.save_state(out)
|
|
@@ -23,9 +23,9 @@ module Badline
|
|
|
23
23
|
# address even when the first one relocated.
|
|
24
24
|
LOAD_SECONDARY = 0x60
|
|
25
25
|
|
|
26
|
-
def initialize(cpu:, bus:, layout:,
|
|
26
|
+
def initialize(cpu:, bus:, layout:, dos:)
|
|
27
27
|
super(cpu:, bus:, layout:)
|
|
28
|
-
@
|
|
28
|
+
@dos = dos
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
def call
|
|
@@ -38,7 +38,7 @@ module Badline
|
|
|
38
38
|
|
|
39
39
|
data, complete = receive(name)
|
|
40
40
|
if low_memory?(data)
|
|
41
|
-
@
|
|
41
|
+
@dos.close(0)
|
|
42
42
|
else
|
|
43
43
|
finish(data, complete)
|
|
44
44
|
end
|
|
@@ -50,10 +50,10 @@ module Badline
|
|
|
50
50
|
# flagged EOI. A read error in the file's chain stops the bytes early,
|
|
51
51
|
# with no EOI.
|
|
52
52
|
def receive(name)
|
|
53
|
-
@
|
|
53
|
+
@dos.open(0, name)
|
|
54
54
|
data = []
|
|
55
55
|
loop do
|
|
56
|
-
byte, eoi = @
|
|
56
|
+
byte, eoi = @dos.read(0)
|
|
57
57
|
return [data, false] unless byte
|
|
58
58
|
|
|
59
59
|
data << byte
|
|
@@ -21,9 +21,9 @@ module Badline
|
|
|
21
21
|
# ST bit at $90
|
|
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
|
|
|
@@ -38,7 +38,7 @@ module Badline
|
|
|
38
38
|
def call
|
|
39
39
|
return unless active?
|
|
40
40
|
return finish if @saving
|
|
41
|
-
return unless @
|
|
41
|
+
return unless @dos.saves?
|
|
42
42
|
|
|
43
43
|
@bus.poke(0xb9, SECONDARY)
|
|
44
44
|
return @cpu.program_counter = @layout.missing_file_name_exit if name.empty?
|
|
@@ -56,7 +56,7 @@ module Badline
|
|
|
56
56
|
|
|
57
57
|
def finish
|
|
58
58
|
@saving = false
|
|
59
|
-
saved = @
|
|
59
|
+
saved = @dos.save(name, payload, replace: full_filename.start_with?("@"))
|
|
60
60
|
@bus.poke(0x90, DEVICE_NOT_PRESENT) unless saved
|
|
61
61
|
@bus.poke(0xac, @bus.peek(0xae))
|
|
62
62
|
@bus.poke(0xad, @bus.peek(0xaf))
|
|
@@ -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
|
|
@@ -144,7 +144,7 @@ module Badline
|
|
|
144
144
|
# takes data only on a channel it has open. Otherwise nothing holds
|
|
145
145
|
# the data line when a byte starts, so the KERNAL finds no device.
|
|
146
146
|
def accepted?
|
|
147
|
-
[OPEN, CLOSE].include?(@frame) || @
|
|
147
|
+
[OPEN, CLOSE].include?(@frame) || @dos.listening?(@listen_channel)
|
|
148
148
|
end
|
|
149
149
|
|
|
150
150
|
def unlisten
|
|
@@ -188,15 +188,15 @@ module Badline
|
|
|
188
188
|
return unless @listen_channel
|
|
189
189
|
|
|
190
190
|
case @frame
|
|
191
|
-
when OPEN then @
|
|
192
|
-
when CLOSE then @
|
|
193
|
-
else @
|
|
191
|
+
when OPEN then @dos.open(@listen_channel, @buffer.pack("C*"))
|
|
192
|
+
when CLOSE then @dos.close(@listen_channel)
|
|
193
|
+
else @dos.write(@listen_channel, @buffer)
|
|
194
194
|
end
|
|
195
195
|
@buffer = []
|
|
196
196
|
end
|
|
197
197
|
|
|
198
198
|
def received
|
|
199
|
-
byte, eoi = @
|
|
199
|
+
byte, eoi = @dos.read(@talk_channel)
|
|
200
200
|
return NO_DATA unless byte
|
|
201
201
|
|
|
202
202
|
[byte, eoi ? EOI : 0]
|
data/lib/badline/kernal_trap.rb
CHANGED
|
@@ -2,8 +2,7 @@
|
|
|
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"
|
|
@@ -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
|
data/lib/badline/machine.rb
CHANGED
|
@@ -6,7 +6,7 @@ module Badline
|
|
|
6
6
|
# = Machine
|
|
7
7
|
#
|
|
8
8
|
# The machines badline builds by family, as the command line's
|
|
9
|
-
# subcommand names them: the C64,
|
|
9
|
+
# subcommand names them: the C64, Badline::C64, the VIC-20, Vic20, and the
|
|
10
10
|
# C128 in C64 mode, C128.
|
|
11
11
|
#
|
|
12
12
|
# A machine answers what the front end, Media, the runners and the
|
|
@@ -28,7 +28,7 @@ module Badline
|
|
|
28
28
|
# +press_cartridge_button+, +release_cartridge_button+,
|
|
29
29
|
# +attach_drive1541+, +drive1541+, +true_drive+ and +plug_true_drive+
|
|
30
30
|
# for the drive Media::TrueDrive plugs in, +attach_drive1581+,
|
|
31
|
-
# +drive1581+ and +plug_drive1581+ for a 1581 (
|
|
31
|
+
# +drive1581+ and +plug_drive1581+ for a 1581 (Drives::Model1581::Slot), and
|
|
32
32
|
# +address_bus+ for its +cartridge+ and +detach_cartridge+.
|
|
33
33
|
# - Snapshots and tests: +snapshot+, +restore+, +save_snapshot+,
|
|
34
34
|
# +install_debug_register+ and +capture_output+.
|
|
@@ -65,9 +65,9 @@ module Badline
|
|
|
65
65
|
raise ArgumentError, "no machine family named #{family}" unless family == :c64
|
|
66
66
|
|
|
67
67
|
profile = Model.named(model)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
C64.new(vic_model: profile.vic_model, cia_model: profile.cia_model,
|
|
69
|
+
sid_model: sid_model || profile.sid_model, region: profile.region, reu:,
|
|
70
|
+
kernal: profile.kernal, datasette: profile.datasette, board: profile.board)
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
# The machine the command line's `options` name, to start `media`, a
|
|
@@ -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/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.
|
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
|
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) }
|