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
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
class Drive1581
|
|
5
|
-
# The drive CPU's bus, as the 74LS139 decodes A13-A15 (1581 Service
|
|
6
|
-
# Manual, memory map and schematic sheet 1):
|
|
7
|
-
#
|
|
8
|
-
# $0000-$1FFF - 8 KB of RAM
|
|
9
|
-
# $2000-$3FFF - nothing: open bus
|
|
10
|
-
# $4000-$5FFF - the 8520, its sixteen registers mirrored
|
|
11
|
-
# $6000-$7FFF - the WD1772, its four registers mirrored
|
|
12
|
-
# $8000-$FFFF - the DOS ROM
|
|
13
|
-
#
|
|
14
|
-
# Writes to the ROM and to open bus go nowhere, and a read from open
|
|
15
|
-
# bus finds the last byte on the data bus, as on the 1541. A write to
|
|
16
|
-
# either of the 8520's ports or their direction registers moves the
|
|
17
|
-
# drive's lines (Drive1581#ports_written).
|
|
18
|
-
#
|
|
19
|
-
# While Idle records a pass of the DOS's idle loop, the bus watches it
|
|
20
|
-
# (watch!): the RAM it reads and writes, and whether it touched the
|
|
21
|
-
# 8520 or the WD1772, either of which makes the pass volatile. While
|
|
22
|
-
# Idle looks for an orbit, the bus guards the drive (guard!), and any
|
|
23
|
-
# access to either chip taints it.
|
|
24
|
-
class Bus
|
|
25
|
-
include Addressable
|
|
26
|
-
|
|
27
|
-
attr_reader :ram, :rom, :cia, :fdc, :data, :volatile, :touched, :tainted, :touched_timers
|
|
28
|
-
|
|
29
|
-
def initialize(rom:, cia:, fdc:, drive:)
|
|
30
|
-
addressable_at(0, length: 2**16)
|
|
31
|
-
@ram = Memory.new([], length: 0x2000, start: 0)
|
|
32
|
-
@rom = rom
|
|
33
|
-
@cia = cia
|
|
34
|
-
@fdc = fdc
|
|
35
|
-
@drive = drive
|
|
36
|
-
@data = 0
|
|
37
|
-
@recording = @guarding = @watching = false
|
|
38
|
-
@volatile = @tainted = false
|
|
39
|
-
@touched = {}
|
|
40
|
-
@touched_timers = 0
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# The last byte on the data bus and the RAM. What a watched stretch
|
|
44
|
-
# touched is Idle's, and a restored bus isn't watching.
|
|
45
|
-
def save_state(out)
|
|
46
|
-
out.int(@data)
|
|
47
|
-
@ram.save_state(out)
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def load_state(input)
|
|
51
|
-
@data = input.int
|
|
52
|
-
@ram.load_state(input)
|
|
53
|
-
@watching = false
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def peek(addr)
|
|
57
|
-
return @data = @rom.peek(addr) if addr >= 0x8000
|
|
58
|
-
return @data = chip_peek(addr) if addr >= 0x2000
|
|
59
|
-
|
|
60
|
-
touch(addr) if @recording
|
|
61
|
-
@data = @ram.peek(addr)
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def poke(addr, value)
|
|
65
|
-
@data = value
|
|
66
|
-
return if addr >= 0x8000
|
|
67
|
-
return chip_poke(addr, value) if addr >= 0x2000
|
|
68
|
-
|
|
69
|
-
touch(addr) if @recording
|
|
70
|
-
@ram.poke(addr, value)
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
# Starts watching: see volatile and touched.
|
|
74
|
-
def watch!
|
|
75
|
-
@recording = true
|
|
76
|
-
@volatile = false
|
|
77
|
-
@touched = {}
|
|
78
|
-
watching!
|
|
79
|
-
end
|
|
80
|
-
|
|
81
|
-
def unwatch!
|
|
82
|
-
@recording = false
|
|
83
|
-
watching!
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
# Starts guarding: see tainted.
|
|
87
|
-
def guard!
|
|
88
|
-
@guarding = true
|
|
89
|
-
@tainted = false
|
|
90
|
-
watching!
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
private
|
|
94
|
-
|
|
95
|
-
def chip_peek(addr)
|
|
96
|
-
watch_chip if @watching
|
|
97
|
-
if addr >= 0x6000
|
|
98
|
-
@fdc.peek(addr & 0x03)
|
|
99
|
-
elsif addr >= 0x4000
|
|
100
|
-
@cia.peek(0x4000 | (addr & 0x0f))
|
|
101
|
-
else
|
|
102
|
-
@data
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def chip_poke(addr, value)
|
|
107
|
-
watch_chip if @watching
|
|
108
|
-
if addr >= 0x6000
|
|
109
|
-
@fdc.poke(addr & 0x03, value)
|
|
110
|
-
elsif addr >= 0x4000
|
|
111
|
-
@cia.poke(0x4000 | (addr & 0x0f), value)
|
|
112
|
-
@drive.ports_written if addr.nobits?(0x0c)
|
|
113
|
-
end
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
def touch(addr)
|
|
117
|
-
@touched[addr] = @ram.peek(addr) unless @touched.key?(addr)
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
def watching!
|
|
121
|
-
@watching = @recording || @guarding
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
def watch_chip
|
|
125
|
-
if @recording
|
|
126
|
-
@volatile = true
|
|
127
|
-
@recording = false
|
|
128
|
-
end
|
|
129
|
-
if @guarding
|
|
130
|
-
@tainted = true
|
|
131
|
-
@guarding = false
|
|
132
|
-
end
|
|
133
|
-
watching!
|
|
134
|
-
end
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
end
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
require "badline/drive1581/disk_state"
|
|
4
|
-
|
|
5
|
-
module Badline
|
|
6
|
-
class Drive1581
|
|
7
|
-
# A 3.5" double-sided disk as the WD1772 sees it: a Track on each side
|
|
8
|
-
# of 80 cylinders, or none where it was never formatted.
|
|
9
|
-
#
|
|
10
|
-
# A .d81 image holds the 1581 DOS's logical blocks in order, 40 of 256
|
|
11
|
-
# bytes on each logical track 1 to 80 (1581 Service Manual, format
|
|
12
|
-
# organization). Logical track t is cylinder t - 1, and the DOS puts
|
|
13
|
-
# its sectors 0 to 19 on side 0 and 20 to 39 on side 1, two to each
|
|
14
|
-
# 512-byte physical sector, numbered from 1. So physical sector s on
|
|
15
|
-
# side h of cylinder c holds logical sectors 20h + 2(s - 1) and the one
|
|
16
|
-
# after it, and every cylinder of the image is a standard Track
|
|
17
|
-
# (Track.standard) on both sides. A block the image's error table
|
|
18
|
-
# marks 20 or 21 loses its sector's ID field, 27 spoils the ID's CRC,
|
|
19
|
-
# 22 loses the data field and 23 spoils its CRC.
|
|
20
|
-
#
|
|
21
|
-
# The WD1772 writes into the tracks, and flush stores the standard
|
|
22
|
-
# sectors of each one written back in the image, which writes its host
|
|
23
|
-
# file. A track formatted another way stays on the disk alone. The disk
|
|
24
|
-
# is write-protected when the image won't take writes.
|
|
25
|
-
class Disk
|
|
26
|
-
include State
|
|
27
|
-
|
|
28
|
-
CYLINDERS = 80
|
|
29
|
-
SIDES = 2
|
|
30
|
-
|
|
31
|
-
# Logical blocks a side of a cylinder holds.
|
|
32
|
-
SIDE_BLOCKS = 20
|
|
33
|
-
|
|
34
|
-
# A logical block's bytes, and how many a physical sector holds.
|
|
35
|
-
BLOCK_SIZE = 256
|
|
36
|
-
BLOCKS = Track::SECTOR_SIZE / BLOCK_SIZE
|
|
37
|
-
|
|
38
|
-
# A disk from the .d81 image at +path+. `read_only` opens the image
|
|
39
|
-
# write-protected.
|
|
40
|
-
def self.open(path, read_only: false)
|
|
41
|
-
new(Storage::D81Image.new(path, read_only:)).opened(path, read_only)
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
attr_reader :image
|
|
45
|
-
|
|
46
|
-
def initialize(image = nil)
|
|
47
|
-
@image = image
|
|
48
|
-
@tracks = Array.new(CYLINDERS * SIDES)
|
|
49
|
-
@written = {}
|
|
50
|
-
@changed = {}
|
|
51
|
-
@path = nil
|
|
52
|
-
@read_only = false
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
# The Track on +side+ of +cylinder+, or nil where there is none: past
|
|
56
|
-
# the image's cylinders, or on a disk without an image that the head
|
|
57
|
-
# never formatted.
|
|
58
|
-
def track(cylinder, side)
|
|
59
|
-
index = (cylinder * SIDES) + side
|
|
60
|
-
return @tracks[index] if @tracks[index] || !@image || cylinder >= CYLINDERS
|
|
61
|
-
|
|
62
|
-
@tracks[index] = image_track(cylinder, side)
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
# A write track laid +track+ down on +side+ of +cylinder+, or a write
|
|
66
|
-
# sector changed it.
|
|
67
|
-
def write(cylinder, side, track)
|
|
68
|
-
return if cylinder >= CYLINDERS
|
|
69
|
-
|
|
70
|
-
index = (cylinder * SIDES) + side
|
|
71
|
-
@tracks[index] = track
|
|
72
|
-
@written[index] = true
|
|
73
|
-
@changed[index] = true
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
# Whether the write-protect hole is open: the disk's image won't take
|
|
77
|
-
# writes, or a disk without an image was opened read-only.
|
|
78
|
-
def write_protected? = @image.nil? ? @read_only : !@image.writable?
|
|
79
|
-
|
|
80
|
-
# Whether any track was written since the last flush.
|
|
81
|
-
def written? = !@written.empty?
|
|
82
|
-
|
|
83
|
-
# Stores the standard sectors of each track written since the last
|
|
84
|
-
# flush in the image, all in one write to its host file.
|
|
85
|
-
def flush
|
|
86
|
-
written = @written.keys.sort
|
|
87
|
-
@written.clear
|
|
88
|
-
return if @image.nil? || written.empty?
|
|
89
|
-
|
|
90
|
-
@image.store_blocks(written.flat_map { |index| track_blocks(index / SIDES, index % SIDES) })
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
private
|
|
94
|
-
|
|
95
|
-
def image_track(cylinder, side)
|
|
96
|
-
track = Track.standard(cylinder, side) { |sector| physical_block(cylinder, side, sector) }
|
|
97
|
-
track.sectors.each { |sector| mark_errors(cylinder, side, sector) }
|
|
98
|
-
track.sectors.reject! { |sector| sector.id.nil? }
|
|
99
|
-
track
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
# The logical track and first sector physical sector +sector+ holds.
|
|
103
|
-
def logical(cylinder, side, sector) = [cylinder + 1, (side * SIDE_BLOCKS) + ((sector - 1) * BLOCKS)]
|
|
104
|
-
|
|
105
|
-
def physical_block(cylinder, side, sector)
|
|
106
|
-
track, first = logical(cylinder, side, sector)
|
|
107
|
-
Array.new(BLOCKS) { |i| @image.read_block(track, first + i) || [] }.flatten
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
def mark_errors(cylinder, side, sector)
|
|
111
|
-
track, first = logical(cylinder, side, sector.id.bytes[2])
|
|
112
|
-
errors = Array.new(BLOCKS) { |i| @image.block_error(track, first + i) }
|
|
113
|
-
sector.id.good = false if errors.include?(27)
|
|
114
|
-
sector.data.good = false if errors.include?(23)
|
|
115
|
-
sector.data = nil if errors.include?(22)
|
|
116
|
-
sector.id = nil if errors.include?(20) || errors.include?(21)
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
# [track, sector, data, nil] for DiskImage#store_blocks, for each
|
|
120
|
-
# logical block a standard sector of the track holds.
|
|
121
|
-
def track_blocks(cylinder, side)
|
|
122
|
-
track = @tracks[(cylinder * SIDES) + side]
|
|
123
|
-
Track::SECTORS.times.flat_map do |index|
|
|
124
|
-
data = track.sector([cylinder, side, index + 1, Track::SIZE_CODE])&.data
|
|
125
|
-
next [] unless data
|
|
126
|
-
|
|
127
|
-
logical_track, first = logical(cylinder, side, index + 1)
|
|
128
|
-
Array.new(BLOCKS) do |i|
|
|
129
|
-
[logical_track, first + i, data.bytes[i * BLOCK_SIZE, BLOCK_SIZE], nil]
|
|
130
|
-
end
|
|
131
|
-
end
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
|
-
end
|
|
135
|
-
end
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
class Drive1581
|
|
5
|
-
class Disk
|
|
6
|
-
# Saving and restoring a Disk for a snapshot: the image by its path,
|
|
7
|
-
# and every track the head wrote since the disk went in, with those
|
|
8
|
-
# written since the last flush. The rest come from the image, read
|
|
9
|
-
# again from its host file where there still is one.
|
|
10
|
-
module State
|
|
11
|
-
# The image's path, expanded, and whether it was opened read-only,
|
|
12
|
-
# for a disk from Disk.open. Nil for a disk made another way.
|
|
13
|
-
attr_reader :path, :read_only
|
|
14
|
-
|
|
15
|
-
# The disk a state from save_state describes: +current+ when it was
|
|
16
|
-
# opened from the same image the same way, and otherwise a disk for
|
|
17
|
-
# the image at the path the state names. Where no file is at that
|
|
18
|
-
# path, the disk has no image and is write-protected, and a
|
|
19
|
-
# detached reader always gets one without an image.
|
|
20
|
-
def self.load(input, current)
|
|
21
|
-
path = input.optional_string
|
|
22
|
-
read_only = input.boolean?
|
|
23
|
-
disk = current if current && !path.nil? && current.path == path && current.read_only == read_only
|
|
24
|
-
disk ||= fresh(path, read_only, input.detached?)
|
|
25
|
-
disk.load_tracks(input)
|
|
26
|
-
disk
|
|
27
|
-
end
|
|
28
|
-
|
|
29
|
-
def self.fresh(path, read_only, detached)
|
|
30
|
-
return Disk.new if path.nil? || detached
|
|
31
|
-
return Disk.new.opened(path, true) unless File.file?(path)
|
|
32
|
-
|
|
33
|
-
Disk.open(path, read_only:)
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# Notes the image's path and how it was opened.
|
|
37
|
-
def opened(path, read_only)
|
|
38
|
-
@path = File.expand_path(path)
|
|
39
|
-
@read_only = read_only
|
|
40
|
-
self
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
def save_state(out)
|
|
44
|
-
out.optional_string(@path).boolean(@read_only)
|
|
45
|
-
changed = @changed.keys.sort
|
|
46
|
-
out.ints(changed)
|
|
47
|
-
changed.each { |index| save_track(@tracks[index], out) }
|
|
48
|
-
out.ints(@written.keys)
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
def load_tracks(input)
|
|
52
|
-
@changed.clear
|
|
53
|
-
input.ints.each do |index|
|
|
54
|
-
@tracks[index] = load_track(input)
|
|
55
|
-
@changed[index] = true
|
|
56
|
-
end
|
|
57
|
-
@written.clear
|
|
58
|
-
input.ints.each { |index| @written[index] = true }
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
private
|
|
62
|
-
|
|
63
|
-
def save_track(track, out)
|
|
64
|
-
out.int(track.sectors.length)
|
|
65
|
-
track.sectors.each do |sector|
|
|
66
|
-
save_field(sector.id, out)
|
|
67
|
-
out.boolean(!sector.data.nil?)
|
|
68
|
-
save_field(sector.data, out) if sector.data
|
|
69
|
-
end
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def save_field(field, out)
|
|
73
|
-
out.int(field.mark).ints(field.bytes).boolean(field.good).boolean(field.deleted)
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def load_track(input)
|
|
77
|
-
Track.new(Array.new(input.int) do
|
|
78
|
-
id = load_field(input)
|
|
79
|
-
Track::Sector.new(id, input.boolean? ? load_field(input) : nil)
|
|
80
|
-
end)
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def load_field(input) = Track::Field.new(input.int, input.ints, input.boolean?, input.boolean?)
|
|
84
|
-
end
|
|
85
|
-
end
|
|
86
|
-
end
|
|
87
|
-
end
|
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
class Drive1581
|
|
5
|
-
# The 1581's 3.5" mechanism: the spindle motor, the head on one of
|
|
6
|
-
# its cylinders and sides, the index sensor, and the lines it reports
|
|
7
|
-
# on the drive connector (1581 Service Manual, schematic sheet 2).
|
|
8
|
-
#
|
|
9
|
-
# The motor runs while /MOTOR is low and turns a disk at 300 rpm, a
|
|
10
|
-
# turn every REVOLUTION drive cycles at 2 MHz. The index sensor pulses
|
|
11
|
-
# for INDEX_PULSE cycles at the start of each turn, which is where a
|
|
12
|
-
# Track's bytes start. /RDY is low while the motor turns a disk. The
|
|
13
|
-
# WD1772 steps the head, and /TR00 is low while it sits on cylinder 0.
|
|
14
|
-
# /WPRT is low while the disk's write-protect hole is open, or without
|
|
15
|
-
# a disk.
|
|
16
|
-
#
|
|
17
|
-
# /DISK CHNG goes low as a disk comes out, and at power-on, and goes
|
|
18
|
-
# high again at a step pulse with a disk in, as on any Shugart-style
|
|
19
|
-
# drive with a disk change line. The DOS steps in and out after
|
|
20
|
-
# spinning the motor up to find out whether a disk is in.
|
|
21
|
-
#
|
|
22
|
-
# Times are the WD1772's cycle count (WD1772#now), which the drive
|
|
23
|
-
# passes in: the angle under the head follows from how long the disk
|
|
24
|
-
# has turned.
|
|
25
|
-
class Mechanism
|
|
26
|
-
REVOLUTION = 400_000
|
|
27
|
-
INDEX_PULSE = 4_000
|
|
28
|
-
LAST_CYLINDER = 83
|
|
29
|
-
|
|
30
|
-
attr_reader :disk, :cylinder
|
|
31
|
-
attr_accessor :side
|
|
32
|
-
|
|
33
|
-
def initialize
|
|
34
|
-
@disk = nil
|
|
35
|
-
@cylinder = 0
|
|
36
|
-
@side = 0
|
|
37
|
-
@motor = false
|
|
38
|
-
@changed = true
|
|
39
|
-
@angle = 0
|
|
40
|
-
@since = 0
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# Puts a Disk in, or with nil takes it out. Whatever was in is
|
|
44
|
-
# flushed first, and the disk change line goes low.
|
|
45
|
-
def insert(disk, now)
|
|
46
|
-
@angle = angle(now)
|
|
47
|
-
@since = now
|
|
48
|
-
flush
|
|
49
|
-
@disk = disk
|
|
50
|
-
@changed = true
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def flush = @disk&.flush
|
|
54
|
-
|
|
55
|
-
def motor_on? = @motor
|
|
56
|
-
|
|
57
|
-
# Turns the motor on or off at +now+.
|
|
58
|
-
def motor(on, now)
|
|
59
|
-
@angle = angle(now)
|
|
60
|
-
@since = now
|
|
61
|
-
@motor = on
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
# Whether a disk turns.
|
|
65
|
-
def spinning? = @motor && !@disk.nil?
|
|
66
|
-
|
|
67
|
-
# How far into its turn the disk is at +now+, in cycles from the
|
|
68
|
-
# index.
|
|
69
|
-
def angle(now) = spinning? ? (@angle + now - @since) % REVOLUTION : @angle
|
|
70
|
-
|
|
71
|
-
def index?(now) = spinning? && angle(now) < INDEX_PULSE
|
|
72
|
-
|
|
73
|
-
def ready? = spinning?
|
|
74
|
-
|
|
75
|
-
def track0? = @cylinder.zero?
|
|
76
|
-
|
|
77
|
-
def disk_changed? = @changed
|
|
78
|
-
|
|
79
|
-
def write_protected? = @disk.nil? || @disk.write_protected?
|
|
80
|
-
|
|
81
|
-
# A step pulse, towards the hub with +inward+.
|
|
82
|
-
def step(inward)
|
|
83
|
-
@cylinder = (@cylinder + (inward ? 1 : -1)).clamp(0, LAST_CYLINDER)
|
|
84
|
-
@changed = false if @disk
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# The Track under the head, or nil.
|
|
88
|
-
def track = @disk&.track(@cylinder, @side)
|
|
89
|
-
|
|
90
|
-
# Stores a track the WD1772 laid down under the head.
|
|
91
|
-
def write(track)
|
|
92
|
-
@disk&.write(@cylinder, @side, track)
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
# The disk (Disk#save_state) and the motor, the head and the turn.
|
|
96
|
-
def save_state(out)
|
|
97
|
-
out.boolean(!@disk.nil?)
|
|
98
|
-
@disk&.save_state(out)
|
|
99
|
-
out.int(@cylinder).int(@side).int(@angle).int(@since).boolean(@motor).boolean(@changed)
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
# Puts the state back, reusing the disk in when it's the one the state
|
|
103
|
-
# names (Disk::State.load). A disk taken out is flushed.
|
|
104
|
-
def load_state(input)
|
|
105
|
-
disk = input.boolean? ? Disk::State.load(input, @disk) : nil
|
|
106
|
-
flush unless disk.equal?(@disk)
|
|
107
|
-
@disk = disk
|
|
108
|
-
@cylinder = input.int
|
|
109
|
-
@side = input.int
|
|
110
|
-
@angle = input.int
|
|
111
|
-
@since = input.int
|
|
112
|
-
@motor = input.boolean?
|
|
113
|
-
@changed = input.boolean?
|
|
114
|
-
end
|
|
115
|
-
end
|
|
116
|
-
end
|
|
117
|
-
end
|
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
class Drive1581
|
|
5
|
-
# What the 8520's ports read from outside the chip (1581 Service
|
|
6
|
-
# Manual, schematic sheet 3; the DOS's I/O definitions):
|
|
7
|
-
#
|
|
8
|
-
# PA0 side select (out) PB0 DATA IN (in)
|
|
9
|
-
# PA1 /RDY from the mechanism PB1 DATA OUT (out)
|
|
10
|
-
# PA2 /MOTOR (out) PB2 CLK IN (in)
|
|
11
|
-
# PA3 device number switch 1 PB3 CLK OUT (out)
|
|
12
|
-
# PA4 device number switch 2 PB4 ATN ACK (out)
|
|
13
|
-
# PA5 power LED (out) PB5 fast serial direction (out)
|
|
14
|
-
# PA6 activity LED (out) PB6 /WPRT from the mechanism
|
|
15
|
-
# PA7 /DISK CHNG from the mech. PB7 ATN IN (in)
|
|
16
|
-
#
|
|
17
|
-
# DATA IN, CLK IN and ATN IN come through inverters, so a pulled line
|
|
18
|
-
# reads 1, as on the 1541 (Drive::SerialLines). A closed switch pulls
|
|
19
|
-
# its line low, and both closed make device 8. The ports' outputs
|
|
20
|
-
# read back as driven: the peripheral pulls only the inputs.
|
|
21
|
-
class SerialPort
|
|
22
|
-
include Drive::SerialLines
|
|
23
|
-
|
|
24
|
-
READY = 0x02
|
|
25
|
-
SWITCHES = 0x18
|
|
26
|
-
DISK_CHANGE = 0x80
|
|
27
|
-
PROTECT = 0x40
|
|
28
|
-
|
|
29
|
-
def initialize(mechanism, device: 8, bus: IECBus.new)
|
|
30
|
-
@mechanism = mechanism
|
|
31
|
-
@switches = (0xff & ~SWITCHES) | (((device - 8) & 0x03) << 3)
|
|
32
|
-
init_serial_lines(device, bus)
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
def read_a(_port_a, _port_b)
|
|
36
|
-
value = @switches
|
|
37
|
-
value &= ~READY if @mechanism.ready?
|
|
38
|
-
value &= ~DISK_CHANGE if @mechanism.disk_changed?
|
|
39
|
-
value
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def read_b(_port_a, _port_b)
|
|
43
|
-
low = @bus.low_lines(@host)
|
|
44
|
-
value = 0xff & ~(SERIAL_INPUTS | PROTECT)
|
|
45
|
-
value |= DATA_IN if low.anybits?(IECBus::DATA)
|
|
46
|
-
value |= CLK_IN if low.anybits?(IECBus::CLK)
|
|
47
|
-
value |= ATN_IN if low.anybits?(IECBus::ATN)
|
|
48
|
-
@mechanism.write_protected? ? value : value | PROTECT
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
class Drive1581
|
|
5
|
-
# A machine's place for a Drive1581 on its serial bus, in a field of
|
|
6
|
-
# its own beside its other true drives, so none of them makes another's
|
|
7
|
-
# per-cycle call a union. The C64, the VIC-20 and the C128 include it,
|
|
8
|
-
# and run the drive from their cycle as they run a 1541.
|
|
9
|
-
#
|
|
10
|
-
# A 1581 reads only .d81 images and the others none, so a .d81 put in
|
|
11
|
-
# device 8 swaps the true drive there for a 1581, and any other disk
|
|
12
|
-
# swaps a 1581 back for the machine's own true drive
|
|
13
|
-
# (Media::TrueDrive).
|
|
14
|
-
module Slot
|
|
15
|
-
attr_reader :drive1581
|
|
16
|
-
|
|
17
|
-
# Plugs in a Drive1581, which then runs alongside the machine on its
|
|
18
|
-
# own clock and talks to it over the serial bus, as a 1541 does.
|
|
19
|
-
def attach_drive1581(drive)
|
|
20
|
-
@iec_bus.detach(@drive1581) if @drive1581
|
|
21
|
-
drive.host_clock_hz = timing.clock_hz
|
|
22
|
-
@drive1581 = drive
|
|
23
|
-
drive.connect(@iec_bus)
|
|
24
|
-
@serial_trap&.device = serial_trap_device
|
|
25
|
-
drive1581_attached
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# Unplugs the Drive1581.
|
|
29
|
-
def detach_drive1581
|
|
30
|
-
return unless @drive1581
|
|
31
|
-
|
|
32
|
-
@iec_bus.detach(@drive1581)
|
|
33
|
-
@drive1581 = nil
|
|
34
|
-
@serial_trap&.device = serial_trap_device
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
# Plugs in a 1581 as device 8, in place of the true drive there, and
|
|
38
|
-
# returns it.
|
|
39
|
-
def plug_drive1581
|
|
40
|
-
unplug_device8
|
|
41
|
-
Drive1581.new.tap { |drive| attach_drive1581(drive) }
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
private
|
|
45
|
-
|
|
46
|
-
# Unplugs the 1541 if it is device 8, for a 1581 to take its place.
|
|
47
|
-
def unplug_device8
|
|
48
|
-
detach_drive1541 if @drive1541&.device == KernalTrap::Routine::DEVICE
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
# What the machine does as a 1581 goes on its bus. The VIC-20 waits
|
|
52
|
-
# for its DOS to boot before typing.
|
|
53
|
-
def drive1581_attached = nil
|
|
54
|
-
|
|
55
|
-
# Whether the 1581 is device 8.
|
|
56
|
-
def drive1581_on_device8? = @drive1581&.device == KernalTrap::Routine::DEVICE
|
|
57
|
-
|
|
58
|
-
# The 1581 on the serial bus, with its device number.
|
|
59
|
-
def save_drive1581(out)
|
|
60
|
-
out.boolean(!@drive1581.nil?)
|
|
61
|
-
return unless @drive1581
|
|
62
|
-
|
|
63
|
-
out.int(@drive1581.device)
|
|
64
|
-
@drive1581.save_state(out)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# Layouts before 8 have no 1581.
|
|
68
|
-
def load_drive1581(input)
|
|
69
|
-
return detach_drive1581 if input.schema < 8 || !input.boolean?
|
|
70
|
-
|
|
71
|
-
device = input.int
|
|
72
|
-
detach_drive1581 if @drive1581 && @drive1581.device != device
|
|
73
|
-
attach_drive1581(Drive1581.new(device:)) unless @drive1581
|
|
74
|
-
@drive1581.load_state(input)
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
end
|