badline 0.12.1 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +66 -1
- data/CLAUDE.md +86 -38
- data/CONTRIBUTING.md +4 -3
- data/README.md +9 -6
- data/doc/library.md +9 -9
- data/doc/media.md +2 -1
- data/doc/pinned-behaviour.md +134 -105
- data/doc/snapshot-format.md +1047 -0
- data/doc/snapshots.md +73 -43
- data/lib/badline/audio/bare_player.rb +53 -20
- data/lib/badline/audio/cli.rb +6 -6
- data/lib/badline/audio/jukebox.rb +2 -2
- data/lib/badline/audio/machine_player.rb +16 -10
- data/lib/badline/{media → audio}/queue.rb +1 -1
- data/lib/badline/audio/queued_tune.rb +6 -6
- data/lib/badline/audio/renderer.rb +33 -22
- data/lib/badline/audio/stereo.rb +1 -1
- data/lib/badline/c128/banks.rb +6 -3
- data/lib/badline/c128/bus/keyed_state.rb +45 -0
- data/lib/badline/c128/bus.rb +35 -20
- data/lib/badline/c128/color_lines.rb +2 -2
- data/lib/badline/c128/cpu.rb +1 -1
- data/lib/badline/c128/drives.rb +14 -34
- data/lib/badline/c128/fast_serial.rb +5 -5
- data/lib/badline/c128/keyed_modules.rb +117 -0
- data/lib/badline/c128/keyed_state.rb +91 -0
- data/lib/badline/c128/keys.rb +9 -0
- data/lib/badline/c128/mmu.rb +9 -8
- data/lib/badline/c128/mmu_pages.rb +21 -1
- data/lib/badline/c128/modes.rb +21 -11
- data/lib/badline/c128/z80.rb +2 -2
- data/lib/badline/c128/z80_turns.rb +1 -1
- data/lib/badline/c128.rb +21 -16
- data/lib/badline/c64/attachments.rb +42 -0
- data/lib/badline/c64/banked_ram/banking.rb +32 -0
- data/lib/badline/c64/banked_ram/plus256k.rb +64 -0
- data/lib/badline/c64/banked_ram/plus60k.rb +47 -0
- data/lib/badline/c64/banked_ram/unexpanded.rb +30 -0
- data/lib/badline/c64/banked_ram.rb +23 -0
- data/lib/badline/c64/bus/debug_register.rb +32 -0
- data/lib/badline/c64/bus/extra_sids.rb +32 -0
- data/lib/badline/c64/bus/fittings.rb +40 -0
- data/lib/badline/c64/bus/keyed_state.rb +41 -0
- data/lib/badline/c64/bus/pla.rb +149 -0
- data/lib/badline/c64/bus/roms.rb +41 -0
- data/lib/badline/c64/bus/sid_slots.rb +44 -0
- data/lib/badline/c64/bus.rb +219 -0
- data/lib/badline/c64/cartridge/action_replay.rb +115 -0
- data/lib/badline/c64/cartridge/atomic_power.rb +26 -0
- data/lib/badline/c64/cartridge/bank.rb +83 -0
- data/lib/badline/c64/cartridge/comal80.rb +52 -0
- data/lib/badline/c64/cartridge/dinamic.rb +36 -0
- data/lib/badline/c64/cartridge/easy_flash.rb +132 -0
- data/lib/badline/c64/cartridge/epyx_fastload.rb +73 -0
- data/lib/badline/c64/cartridge/final_cartridge3.rb +79 -0
- data/lib/badline/c64/cartridge/flash.rb +279 -0
- data/lib/badline/c64/cartridge/freezer.rb +35 -0
- data/lib/badline/c64/cartridge/fun_play.rb +40 -0
- data/lib/badline/c64/cartridge/g_mod2.rb +64 -0
- data/lib/badline/c64/cartridge/game_system.rb +42 -0
- data/lib/badline/c64/cartridge/geo_ram.rb +65 -0
- data/lib/badline/c64/cartridge/kcs_power.rb +69 -0
- data/lib/badline/c64/cartridge/keyed_state.rb +393 -0
- data/lib/badline/c64/cartridge/mach5.rb +34 -0
- data/lib/badline/c64/cartridge/magic_desk.rb +32 -0
- data/lib/badline/c64/cartridge/ocean.rb +37 -0
- data/lib/badline/c64/cartridge/pagefox.rb +60 -0
- data/lib/badline/c64/cartridge/retro_replay.rb +278 -0
- data/lib/badline/c64/cartridge/rex_utility.rb +31 -0
- data/lib/badline/c64/cartridge/rgcd.rb +50 -0
- data/lib/badline/c64/cartridge/simons_basic.rb +37 -0
- data/lib/badline/c64/cartridge/standard.rb +17 -0
- data/lib/badline/c64/cartridge/super_games.rb +40 -0
- data/lib/badline/c64/cartridge/westermann.rb +32 -0
- data/lib/badline/c64/cartridge/zaxxon.rb +52 -0
- data/lib/badline/c64/cartridge.rb +232 -0
- data/lib/badline/c64/color_memory.rb +27 -0
- data/lib/badline/{computer → c64}/common.rb +2 -2
- data/lib/badline/{computer → c64}/kernal_traps.rb +39 -36
- data/lib/badline/c64/keyed_modules.rb +111 -0
- data/lib/badline/c64/keyed_state.rb +68 -0
- data/lib/badline/c64/reu/dma.rb +271 -0
- data/lib/badline/c64/reu/keyed_state.rb +140 -0
- data/lib/badline/c64/reu/ram.rb +94 -0
- data/lib/badline/c64/reu/trigger.rb +34 -0
- data/lib/badline/c64/reu.rb +289 -0
- data/lib/badline/c64/true_drives.rb +120 -0
- data/lib/badline/{computer.rb → c64.rb} +24 -15
- data/lib/badline/chips/cia/fast_forward.rb +62 -0
- data/lib/badline/chips/cia/interrupt_register.rb +128 -0
- data/lib/badline/chips/cia/keyed_parts.rb +213 -0
- data/lib/badline/chips/cia/serial.rb +246 -0
- data/lib/badline/chips/cia/time_of_day.rb +210 -0
- data/lib/badline/chips/cia/timer.rb +188 -0
- data/lib/badline/chips/cia.rb +281 -0
- data/lib/badline/chips/cpu/addressing.rb +133 -0
- data/lib/badline/chips/cpu/boundary.rb +56 -0
- data/lib/badline/chips/cpu/core.rb +183 -0
- data/lib/badline/chips/cpu/instruction.rb +338 -0
- data/lib/badline/chips/cpu/instruction_set/arithmetic.rb +118 -0
- data/lib/badline/chips/cpu/instruction_set/bitwise.rb +130 -0
- data/lib/badline/chips/cpu/instruction_set/branch.rb +83 -0
- data/lib/badline/chips/cpu/instruction_set/flag.rb +67 -0
- data/lib/badline/chips/cpu/instruction_set/illegal.rb +274 -0
- data/lib/badline/chips/cpu/instruction_set/inc_dec.rb +73 -0
- data/lib/badline/chips/cpu/instruction_set/stack.rb +56 -0
- data/lib/badline/chips/cpu/instruction_set/transfer.rb +141 -0
- data/lib/badline/chips/cpu/instruction_set.rb +59 -0
- data/lib/badline/chips/cpu/interrupts.rb +108 -0
- data/lib/badline/chips/cpu/keyed_state.rb +177 -0
- data/lib/badline/chips/cpu/microcode.rb +195 -0
- data/lib/badline/chips/cpu/operations.rb +90 -0
- data/lib/badline/chips/cpu/port.rb +133 -0
- data/lib/badline/chips/cpu/stack_operations.rb +84 -0
- data/lib/badline/chips/cpu/traps.rb +23 -0
- data/lib/badline/chips/cpu.rb +17 -0
- data/lib/badline/chips/sid/catch_up.rb +122 -0
- data/lib/badline/chips/sid/decimator.rb +68 -0
- data/lib/badline/chips/sid/envelope.rb +236 -0
- data/lib/badline/chips/sid/filter.rb +227 -0
- data/lib/badline/chips/sid/keyed_parts.rb +286 -0
- data/lib/badline/chips/sid/voice.rb +69 -0
- data/lib/badline/chips/sid/waveform/combined.rb +128 -0
- data/lib/badline/chips/sid/waveform/fast_forward.rb +107 -0
- data/lib/badline/chips/sid/waveform/noise_writeback.rb +124 -0
- data/lib/badline/chips/sid/waveform.rb +305 -0
- data/lib/badline/chips/sid.rb +264 -0
- data/lib/badline/chips/ted/beam.rb +119 -0
- data/lib/badline/chips/ted/timers.rb +66 -0
- data/lib/badline/chips/ted.rb +143 -0
- data/lib/badline/chips/tia.rb +49 -0
- data/lib/badline/chips/vdc/keyed_parts.rb +105 -0
- data/lib/badline/{c128 → chips}/vdc/memory.rb +1 -1
- data/lib/badline/{c128 → chips}/vdc/painter.rb +1 -13
- data/lib/badline/{c128 → chips}/vdc/raster.rb +1 -17
- data/lib/badline/{c128 → chips}/vdc/window.rb +1 -10
- data/lib/badline/{c128 → chips}/vdc.rb +6 -31
- data/lib/badline/chips/via/control_lines.rb +109 -0
- data/lib/badline/chips/via/fast_forward.rb +55 -0
- data/lib/badline/chips/via/interrupt_register.rb +60 -0
- data/lib/badline/chips/via/keyed_parts.rb +163 -0
- data/lib/badline/chips/via/shift_register.rb +168 -0
- data/lib/badline/chips/via/timer1.rb +120 -0
- data/lib/badline/chips/via/timer2.rb +117 -0
- data/lib/badline/chips/via.rb +267 -0
- data/lib/badline/chips/vic/bank.rb +135 -0
- data/lib/badline/chips/vic/border_mask.rb +78 -0
- data/lib/badline/chips/vic/collisions.rb +106 -0
- data/lib/badline/chips/vic/color_patches.rb +38 -0
- data/lib/badline/chips/vic/display_state.rb +168 -0
- data/lib/badline/chips/vic/graphics_mode.rb +166 -0
- data/lib/badline/chips/vic/graphics_shifter.rb +183 -0
- data/lib/badline/chips/vic/keyed_parts.rb +228 -0
- data/lib/badline/chips/vic/keyed_sprites.rb +225 -0
- data/lib/badline/chips/vic/keyed_state.rb +102 -0
- data/lib/badline/chips/vic/register_log.rb +65 -0
- data/lib/badline/chips/vic/registers.rb +188 -0
- data/lib/badline/chips/vic/sequencer.rb +275 -0
- data/lib/badline/chips/vic/sequencer_output.rb +118 -0
- data/lib/badline/chips/vic/sprite/internal_bus.rb +59 -0
- data/lib/badline/chips/vic/sprite/shifter.rb +148 -0
- data/lib/badline/chips/vic/sprite/timing.rb +58 -0
- data/lib/badline/chips/vic/sprite.rb +337 -0
- data/lib/badline/chips/vic/sprites.rb +281 -0
- data/lib/badline/chips/vic.rb +787 -0
- data/lib/badline/chips/vic_i/keyed_parts.rb +142 -0
- data/lib/badline/{vic20/vic → chips/vic_i}/painter.rb +2 -30
- data/lib/badline/chips/vic_i/sound/output.rb +85 -0
- data/lib/badline/chips/vic_i/sound.rb +227 -0
- data/lib/badline/{vic20/vic → chips/vic_i}/text_window.rb +2 -2
- data/lib/badline/{vic20/vic.rb → chips/vic_i.rb} +6 -6
- data/lib/badline/chips/z80/arithmetic.rb +119 -0
- data/lib/badline/chips/z80/bit_page.rb +57 -0
- data/lib/badline/chips/z80/block_io.rb +60 -0
- data/lib/badline/chips/z80/block_transfers.rb +61 -0
- data/lib/badline/chips/z80/bus_cycles.rb +113 -0
- data/lib/badline/chips/z80/core.rb +115 -0
- data/lib/badline/chips/z80/exchanges.rb +52 -0
- data/lib/badline/chips/z80/extended_page.rb +91 -0
- data/lib/badline/chips/z80/flags.rb +39 -0
- data/lib/badline/chips/z80/interrupt_acceptance.rb +48 -0
- data/lib/badline/chips/z80/jumps.rb +84 -0
- data/lib/badline/chips/z80/keyed_state.rb +73 -0
- data/lib/badline/chips/z80/loads.rb +100 -0
- data/lib/badline/chips/z80/main_page.rb +136 -0
- data/lib/badline/chips/z80/registers.rb +122 -0
- data/lib/badline/chips/z80/shifts.rb +66 -0
- data/lib/badline/chips/z80.rb +13 -0
- data/lib/badline/chips.rb +10 -0
- data/lib/badline/core.rb +13 -32
- data/lib/badline/drives/datasette/keyed_state.rb +38 -0
- data/lib/badline/drives/datasette.rb +173 -0
- data/lib/badline/drives/engine/core.rb +152 -0
- data/lib/badline/drives/engine/fast_serial.rb +75 -0
- data/lib/badline/drives/engine/idle.rb +127 -0
- data/lib/badline/drives/engine/idle_cpu.rb +30 -0
- data/lib/badline/drives/engine/orbit.rb +81 -0
- data/lib/badline/drives/engine/serial_lines.rb +72 -0
- data/lib/badline/drives/engine/sleep.rb +114 -0
- data/lib/badline/drives/engine/vias.rb +86 -0
- data/lib/badline/drives/engine/watch.rb +152 -0
- data/lib/badline/drives/engine.rb +11 -0
- data/lib/badline/drives/model1541/bus.rb +75 -0
- data/lib/badline/drives/model1541/byte_ready.rb +50 -0
- data/lib/badline/drives/model1541/cpu.rb +13 -0
- data/lib/badline/drives/model1541/disk.rb +318 -0
- data/lib/badline/drives/model1541/disk_via.rb +38 -0
- data/lib/badline/drives/model1541/gcr.rb +59 -0
- data/lib/badline/drives/model1541/keyed_state.rb +251 -0
- data/lib/badline/drives/model1541/mechanism.rb +313 -0
- data/lib/badline/drives/model1541/rotation.rb +123 -0
- data/lib/badline/drives/model1541/sector_reader.rb +78 -0
- data/lib/badline/drives/model1541/serial_port.rb +20 -0
- data/lib/badline/drives/model1541/track.rb +100 -0
- data/lib/badline/drives/model1541.rb +80 -0
- data/lib/badline/drives/model1571/bus.rb +100 -0
- data/lib/badline/drives/model1571/cpu.rb +13 -0
- data/lib/badline/drives/model1571/keyed_state.rb +108 -0
- data/lib/badline/drives/model1571/serial_port.rb +39 -0
- data/lib/badline/drives/model1571/serial_via.rb +27 -0
- data/lib/badline/drives/model1571/wd1770.rb +108 -0
- data/lib/badline/drives/model1571.rb +141 -0
- data/lib/badline/drives/model1581/bus.rb +126 -0
- data/lib/badline/drives/model1581/cpu.rb +13 -0
- data/lib/badline/drives/model1581/disk.rb +133 -0
- data/lib/badline/drives/model1581/keyed_state.rb +280 -0
- data/lib/badline/drives/model1581/mechanism.rb +98 -0
- data/lib/badline/drives/model1581/serial_port.rb +54 -0
- data/lib/badline/drives/model1581/slot.rb +61 -0
- data/lib/badline/drives/model1581/track.rb +102 -0
- data/lib/badline/drives/model1581/track_bytes.rb +77 -0
- data/lib/badline/drives/model1581/wd1772/registers.rb +91 -0
- data/lib/badline/drives/model1581/wd1772/sector_writes.rb +75 -0
- data/lib/badline/drives/model1581/wd1772/sectors.rb +152 -0
- data/lib/badline/drives/model1581/wd1772/stepping.rb +111 -0
- data/lib/badline/drives/model1581/wd1772/tracks.rb +127 -0
- data/lib/badline/drives/model1581/wd1772/turn.rb +75 -0
- data/lib/badline/drives/model1581/wd1772.rb +216 -0
- data/lib/badline/drives/model1581.rb +206 -0
- data/lib/badline/drives/serial_bus.rb +161 -0
- data/lib/badline/drives.rb +8 -0
- data/lib/badline/frontend/app.rb +3 -3
- data/lib/badline/frontend/boot.rb +4 -4
- data/lib/badline/frontend/controls.rb +19 -3
- data/lib/badline/frontend/drive_led.rb +44 -21
- data/lib/badline/frontend/machine_window.rb +3 -1
- data/lib/badline/frontend/menu/menu_dialogs.rb +2 -2
- data/lib/badline/frontend/player/filter_view.rb +1 -1
- data/lib/badline/frontend/player/player_controller.rb +2 -2
- data/lib/badline/frontend/player/player_screen.rb +1 -0
- data/lib/badline/frontend/player/theme.rb +7 -7
- data/lib/badline/frontend/snapshots.rb +12 -1
- data/lib/badline/frontend/timeline.rb +30 -12
- data/lib/badline/input/control_ports.rb +78 -0
- data/lib/badline/input/joystick.rb +27 -0
- data/lib/badline/input/keyboard.rb +114 -0
- data/lib/badline/input/matrix_typist.rb +98 -0
- data/lib/badline/input.rb +4 -0
- data/lib/badline/kernal_trap/chrout.rb +45 -0
- data/lib/badline/kernal_trap/{drive → dos}/block_commands.rb +1 -1
- data/lib/badline/kernal_trap/dos/channel.rb +156 -0
- data/lib/badline/kernal_trap/{drive → dos}/channels.rb +1 -26
- data/lib/badline/kernal_trap/{drive → dos}/memory.rb +1 -10
- data/lib/badline/kernal_trap/{drive → dos}/parameters.rb +1 -1
- data/lib/badline/kernal_trap/{drive → dos}/status.rb +1 -9
- data/lib/badline/kernal_trap/{drive → dos}/write_file.rb +1 -19
- data/lib/badline/kernal_trap/{drive → dos}/writes.rb +1 -1
- data/lib/badline/kernal_trap/{drive.rb → dos.rb} +9 -27
- data/lib/badline/kernal_trap/file_routine.rb +4 -4
- data/lib/badline/kernal_trap/keyed_state.rb +150 -0
- data/lib/badline/kernal_trap/layout.rb +75 -11
- data/lib/badline/kernal_trap/load.rb +19 -21
- data/lib/badline/kernal_trap/routine.rb +12 -0
- data/lib/badline/kernal_trap/save.rb +12 -22
- data/lib/badline/kernal_trap/serial.rb +8 -24
- data/lib/badline/kernal_trap.rb +3 -2
- data/lib/badline/machine/clocking.rb +1 -1
- data/lib/badline/machine/keyboard_buffer.rb +49 -0
- data/lib/badline/machine/settling.rb +29 -0
- data/lib/badline/machine.rb +10 -7
- data/lib/badline/media/boot_disk.rb +14 -2
- data/lib/badline/media/extensions.rb +10 -0
- data/lib/badline/media/true_drive.rb +1 -1
- data/lib/badline/media/tune.rb +2 -2
- data/lib/badline/media.rb +3 -3
- data/lib/badline/memory.rb +3 -6
- data/lib/badline/model.rb +1 -1
- data/lib/badline/options/family.rb +5 -2
- data/lib/badline/options/help.rb +42 -16
- data/lib/badline/options/table.rb +2 -0
- data/lib/badline/options/validation.rb +2 -0
- data/lib/badline/options.rb +6 -1
- data/lib/badline/plus4/acia.rb +45 -0
- data/lib/badline/plus4/bus.rb +312 -0
- data/lib/badline/plus4/cpu.rb +10 -0
- data/lib/badline/plus4/cpu_port.rb +93 -0
- data/lib/badline/plus4/keyboard_port.rb +51 -0
- data/lib/badline/plus4/model.rb +38 -0
- data/lib/badline/plus4/user_port.rb +31 -0
- data/lib/badline/plus4.rb +164 -0
- data/lib/badline/roms/README +44 -6
- data/lib/badline/roms/plus4/basic.rom +0 -0
- data/lib/badline/roms/plus4/function-high.rom +0 -0
- data/lib/badline/roms/plus4/function-low.rom +0 -0
- data/lib/badline/roms/plus4/kernal-ntsc.rom +0 -0
- data/lib/badline/roms/plus4/kernal-pal.rom +0 -0
- data/lib/badline/sdl.rb +1 -0
- data/lib/badline/{storage/sid_file.rb → sid_tune/file.rb} +3 -3
- data/lib/badline/{storage → sid_tune}/hvsc.rb +7 -7
- data/lib/badline/{storage → sid_tune}/song_lengths.rb +2 -2
- data/lib/badline/{storage → sid_tune}/stil/credit.rb +1 -1
- data/lib/badline/{storage → sid_tune}/stil.rb +3 -3
- data/lib/badline/sid_tune.rb +6 -0
- data/lib/badline/snapshot/c128_setup.rb +32 -0
- data/lib/badline/snapshot/c64_setup.rb +83 -0
- data/lib/badline/snapshot/container.rb +4 -0
- data/lib/badline/snapshot/field_doc/markdown.rb +112 -0
- data/lib/badline/snapshot/field_doc.rb +109 -0
- data/lib/badline/snapshot/image.rb +132 -46
- data/lib/badline/snapshot/keyed/cursor.rb +40 -0
- data/lib/badline/snapshot/keyed/modules.rb +66 -0
- data/lib/badline/snapshot/keyed/reader.rb +188 -0
- data/lib/badline/snapshot/keyed/recorder.rb +88 -0
- data/lib/badline/snapshot/keyed/report.rb +26 -0
- data/lib/badline/snapshot/keyed/writer.rb +55 -0
- data/lib/badline/snapshot/keyed.rb +64 -0
- data/lib/badline/snapshot/machine_state.rb +17 -64
- data/lib/badline/snapshot/storage_setup.rb +63 -0
- data/lib/badline/snapshot/vic20_setup.rb +28 -0
- data/lib/badline/snapshot/vice/c64_mem.rb +1 -1
- data/lib/badline/snapshot/vice/restore.rb +1 -1
- data/lib/badline/snapshot/vice/reu1764.rb +3 -3
- data/lib/badline/snapshot/vice/reu_fields.rb +40 -0
- data/lib/badline/snapshot/vice.rb +13 -35
- data/lib/badline/snapshot.rb +44 -22
- data/lib/badline/storage/crt_file.rb +3 -1
- data/lib/badline/storage/d64_image.rb +0 -2
- data/lib/badline/storage/d71_image.rb +0 -2
- data/lib/badline/storage/d81_image.rb +0 -2
- data/lib/badline/storage/disk_image.rb +3 -6
- data/lib/badline/storage/g64_image.rb +10 -5
- data/lib/badline/storage/host_directory.rb +0 -5
- data/lib/badline/storage/t64.rb +2 -8
- data/lib/badline/storage/tap.rb +43 -15
- data/lib/badline/storage/unavailable.rb +1 -1
- data/lib/badline/storage.rb +0 -37
- data/lib/badline/support/c128_checkpoint.rb +39 -0
- data/lib/badline/support/checkpoint.rb +108 -0
- data/lib/badline/support/vic20_checkpoint.rb +38 -0
- data/lib/badline/support.rb +5 -0
- data/lib/badline/version.rb +1 -1
- data/lib/badline/vic20/attachments.rb +8 -5
- data/lib/badline/vic20/bus/keyed_state.rb +52 -0
- data/lib/badline/vic20/bus.rb +2 -25
- data/lib/badline/vic20/cpu.rb +1 -1
- data/lib/badline/vic20/keyed_modules.rb +73 -0
- data/lib/badline/vic20/keyed_state.rb +45 -0
- data/lib/badline/vic20/port_wiring.rb +4 -4
- data/lib/badline/vic20/user_via_ports.rb +2 -2
- data/lib/badline/vic20.rb +22 -17
- data/lib/badline.rb +1 -0
- metadata +271 -228
- data/lib/badline/address_bus/extra_sids.rb +0 -30
- data/lib/badline/address_bus/fittings.rb +0 -38
- data/lib/badline/address_bus/pla.rb +0 -147
- data/lib/badline/address_bus/roms.rb +0 -39
- data/lib/badline/address_bus/saved_state.rb +0 -66
- data/lib/badline/address_bus/sid_slots.rb +0 -42
- data/lib/badline/address_bus.rb +0 -216
- data/lib/badline/c128/bus_state.rb +0 -53
- data/lib/badline/c128/saved_state.rb +0 -143
- data/lib/badline/cartridge/action_replay.rb +0 -126
- data/lib/badline/cartridge/atomic_power.rb +0 -24
- data/lib/badline/cartridge/bank.rb +0 -81
- data/lib/badline/cartridge/comal80.rb +0 -50
- data/lib/badline/cartridge/dinamic.rb +0 -34
- data/lib/badline/cartridge/easy_flash.rb +0 -145
- data/lib/badline/cartridge/epyx_fastload.rb +0 -79
- data/lib/badline/cartridge/final_cartridge3.rb +0 -89
- data/lib/badline/cartridge/flash.rb +0 -306
- data/lib/badline/cartridge/freezer.rb +0 -33
- data/lib/badline/cartridge/fun_play.rb +0 -38
- data/lib/badline/cartridge/g_mod2.rb +0 -74
- data/lib/badline/cartridge/game_system.rb +0 -40
- data/lib/badline/cartridge/geo_ram.rb +0 -79
- data/lib/badline/cartridge/kcs_power.rb +0 -75
- data/lib/badline/cartridge/mach5.rb +0 -32
- data/lib/badline/cartridge/magic_desk.rb +0 -30
- data/lib/badline/cartridge/ocean.rb +0 -35
- data/lib/badline/cartridge/pagefox.rb +0 -68
- data/lib/badline/cartridge/retro_replay.rb +0 -320
- data/lib/badline/cartridge/rex_utility.rb +0 -29
- data/lib/badline/cartridge/rgcd.rb +0 -58
- data/lib/badline/cartridge/simons_basic.rb +0 -35
- data/lib/badline/cartridge/standard.rb +0 -15
- data/lib/badline/cartridge/super_games.rb +0 -48
- data/lib/badline/cartridge/westermann.rb +0 -30
- data/lib/badline/cartridge/zaxxon.rb +0 -66
- data/lib/badline/cartridge.rb +0 -303
- data/lib/badline/checkpoint.rb +0 -98
- data/lib/badline/chrout_trap.rb +0 -43
- data/lib/badline/cia/fast_forward.rb +0 -60
- data/lib/badline/cia/interrupt_register.rb +0 -143
- data/lib/badline/cia/serial.rb +0 -275
- data/lib/badline/cia/state.rb +0 -47
- data/lib/badline/cia/timer.rb +0 -206
- data/lib/badline/cia.rb +0 -279
- data/lib/badline/color_memory.rb +0 -25
- data/lib/badline/computer/attachments.rb +0 -88
- data/lib/badline/computer/saved_state.rb +0 -117
- data/lib/badline/computer/true_drives.rb +0 -69
- data/lib/badline/control_ports.rb +0 -76
- data/lib/badline/cpu/addressing.rb +0 -131
- data/lib/badline/cpu/boundary.rb +0 -54
- data/lib/badline/cpu/core.rb +0 -165
- data/lib/badline/cpu/microcode.rb +0 -177
- data/lib/badline/cpu/operations.rb +0 -88
- data/lib/badline/cpu/saved_state.rb +0 -115
- data/lib/badline/cpu/stack_operations.rb +0 -82
- data/lib/badline/cpu.rb +0 -10
- data/lib/badline/cpu_port.rb +0 -112
- data/lib/badline/datasette.rb +0 -161
- data/lib/badline/debug_register.rb +0 -28
- data/lib/badline/drive/core.rb +0 -147
- data/lib/badline/drive/fast_serial.rb +0 -73
- data/lib/badline/drive/idle.rb +0 -125
- data/lib/badline/drive/idle_cpu.rb +0 -28
- data/lib/badline/drive/orbit.rb +0 -79
- data/lib/badline/drive/serial_lines.rb +0 -73
- data/lib/badline/drive/sleep.rb +0 -112
- data/lib/badline/drive/vias.rb +0 -84
- data/lib/badline/drive/watch.rb +0 -150
- data/lib/badline/drive.rb +0 -11
- data/lib/badline/drive1541/bus.rb +0 -86
- data/lib/badline/drive1541/byte_ready.rb +0 -48
- data/lib/badline/drive1541/cpu.rb +0 -11
- data/lib/badline/drive1541/disk.rb +0 -315
- data/lib/badline/drive1541/disk_state.rb +0 -86
- data/lib/badline/drive1541/disk_via.rb +0 -36
- data/lib/badline/drive1541/gcr.rb +0 -57
- data/lib/badline/drive1541/mechanism.rb +0 -313
- data/lib/badline/drive1541/mechanism_state.rb +0 -68
- data/lib/badline/drive1541/rotation.rb +0 -121
- data/lib/badline/drive1541/sector_reader.rb +0 -76
- data/lib/badline/drive1541/serial_port.rb +0 -18
- data/lib/badline/drive1541/track.rb +0 -98
- data/lib/badline/drive1541.rb +0 -111
- data/lib/badline/drive1571/bus.rb +0 -111
- data/lib/badline/drive1571/cpu.rb +0 -11
- data/lib/badline/drive1571/serial_port.rb +0 -37
- data/lib/badline/drive1571/serial_via.rb +0 -25
- data/lib/badline/drive1571/wd1770.rb +0 -120
- data/lib/badline/drive1571.rb +0 -175
- data/lib/badline/drive1581/bus.rb +0 -137
- data/lib/badline/drive1581/cpu.rb +0 -11
- data/lib/badline/drive1581/disk.rb +0 -135
- data/lib/badline/drive1581/disk_state.rb +0 -87
- data/lib/badline/drive1581/mechanism.rb +0 -117
- data/lib/badline/drive1581/serial_port.rb +0 -52
- data/lib/badline/drive1581/slot.rb +0 -78
- data/lib/badline/drive1581/track.rb +0 -100
- data/lib/badline/drive1581/track_bytes.rb +0 -75
- data/lib/badline/drive1581/wd1772/registers.rb +0 -89
- data/lib/badline/drive1581/wd1772/sector_writes.rb +0 -73
- data/lib/badline/drive1581/wd1772/sectors.rb +0 -150
- data/lib/badline/drive1581/wd1772/state.rb +0 -66
- data/lib/badline/drive1581/wd1772/stepping.rb +0 -109
- data/lib/badline/drive1581/wd1772/tracks.rb +0 -125
- data/lib/badline/drive1581/wd1772/turn.rb +0 -73
- data/lib/badline/drive1581/wd1772.rb +0 -216
- data/lib/badline/drive1581.rb +0 -233
- data/lib/badline/iec_bus.rb +0 -159
- data/lib/badline/instruction.rb +0 -334
- data/lib/badline/instruction_set/arithmetic.rb +0 -114
- data/lib/badline/instruction_set/bitwise.rb +0 -126
- data/lib/badline/instruction_set/branch.rb +0 -79
- data/lib/badline/instruction_set/flag.rb +0 -63
- data/lib/badline/instruction_set/illegal.rb +0 -270
- data/lib/badline/instruction_set/inc_dec.rb +0 -69
- data/lib/badline/instruction_set/stack.rb +0 -52
- data/lib/badline/instruction_set/transfer.rb +0 -137
- data/lib/badline/instruction_set.rb +0 -55
- data/lib/badline/interrupts.rb +0 -104
- data/lib/badline/joystick.rb +0 -25
- data/lib/badline/kernal_trap/channel.rb +0 -181
- data/lib/badline/keyboard.rb +0 -112
- data/lib/badline/keyboard_buffer.rb +0 -33
- data/lib/badline/ram_expansion/banking.rb +0 -30
- data/lib/badline/ram_expansion/plus256k.rb +0 -54
- data/lib/badline/ram_expansion/plus60k.rb +0 -43
- data/lib/badline/ram_expansion/unexpanded.rb +0 -28
- data/lib/badline/ram_expansion.rb +0 -21
- data/lib/badline/reu/dma/saved_state.rb +0 -50
- data/lib/badline/reu/dma.rb +0 -273
- data/lib/badline/reu/ram.rb +0 -107
- data/lib/badline/reu/saved_state.rb +0 -80
- data/lib/badline/reu/trigger.rb +0 -32
- data/lib/badline/reu.rb +0 -289
- data/lib/badline/sid/catch_up.rb +0 -120
- data/lib/badline/sid/decimator.rb +0 -64
- data/lib/badline/sid/envelope/state.rb +0 -68
- data/lib/badline/sid/envelope.rb +0 -239
- data/lib/badline/sid/filter.rb +0 -263
- data/lib/badline/sid/voice.rb +0 -77
- data/lib/badline/sid/waveform/combined.rb +0 -126
- data/lib/badline/sid/waveform/fast_forward.rb +0 -105
- data/lib/badline/sid/waveform/noise_writeback.rb +0 -122
- data/lib/badline/sid/waveform/state.rb +0 -66
- data/lib/badline/sid/waveform.rb +0 -305
- data/lib/badline/sid.rb +0 -303
- data/lib/badline/snapshot/setup.rb +0 -75
- data/lib/badline/snapshot/state.rb +0 -189
- data/lib/badline/time_of_day.rb +0 -228
- data/lib/badline/traps.rb +0 -19
- data/lib/badline/via/control_lines.rb +0 -122
- data/lib/badline/via/fast_forward.rb +0 -53
- data/lib/badline/via/interrupt_register.rb +0 -67
- data/lib/badline/via/shift_register.rb +0 -180
- data/lib/badline/via/state.rb +0 -42
- data/lib/badline/via/timer1.rb +0 -131
- data/lib/badline/via/timer2.rb +0 -133
- data/lib/badline/via.rb +0 -266
- data/lib/badline/vic/bank.rb +0 -133
- data/lib/badline/vic/border_mask.rb +0 -86
- data/lib/badline/vic/collisions.rb +0 -115
- data/lib/badline/vic/color_patches.rb +0 -47
- data/lib/badline/vic/display_state.rb +0 -185
- data/lib/badline/vic/graphics_mode.rb +0 -164
- data/lib/badline/vic/graphics_shifter.rb +0 -207
- data/lib/badline/vic/register_log.rb +0 -81
- data/lib/badline/vic/registers.rb +0 -195
- data/lib/badline/vic/sequencer.rb +0 -275
- data/lib/badline/vic/sequencer_output.rb +0 -116
- data/lib/badline/vic/sequencer_state.rb +0 -89
- data/lib/badline/vic/sprite/internal_bus.rb +0 -68
- data/lib/badline/vic/sprite/saved_state.rb +0 -64
- data/lib/badline/vic/sprite/shifter.rb +0 -146
- data/lib/badline/vic/sprite/timing.rb +0 -56
- data/lib/badline/vic/sprite.rb +0 -337
- data/lib/badline/vic/sprites.rb +0 -282
- data/lib/badline/vic/sprites_state.rb +0 -57
- data/lib/badline/vic.rb +0 -853
- data/lib/badline/vic20/saved_state.rb +0 -124
- data/lib/badline/vic20/sound/output.rb +0 -83
- data/lib/badline/vic20/sound.rb +0 -233
- data/lib/badline/vic20/vic/saved_state.rb +0 -55
- data/lib/badline/z80/arithmetic.rb +0 -117
- data/lib/badline/z80/bit_page.rb +0 -55
- data/lib/badline/z80/block_io.rb +0 -58
- data/lib/badline/z80/block_transfers.rb +0 -59
- data/lib/badline/z80/bus_cycles.rb +0 -111
- data/lib/badline/z80/core.rb +0 -113
- data/lib/badline/z80/exchanges.rb +0 -50
- data/lib/badline/z80/extended_page.rb +0 -89
- data/lib/badline/z80/flags.rb +0 -37
- data/lib/badline/z80/interrupt_acceptance.rb +0 -46
- data/lib/badline/z80/jumps.rb +0 -82
- data/lib/badline/z80/loads.rb +0 -98
- data/lib/badline/z80/main_page.rb +0 -134
- data/lib/badline/z80/registers.rb +0 -120
- data/lib/badline/z80/saved_state.rb +0 -69
- data/lib/badline/z80/shifts.rb +0 -64
- data/lib/badline/z80.rb +0 -11
- /data/lib/badline/snapshot/{fields.rb → vice/fields.rb} +0 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Drives
|
|
5
|
+
class Model1581
|
|
6
|
+
class WD1772
|
|
7
|
+
# The type I commands, which move the head:
|
|
8
|
+
#
|
|
9
|
+
# 0000hVrr restore step out to track 0, the track register to 0
|
|
10
|
+
# 0001hVrr seek step until the track register holds the data
|
|
11
|
+
# register's track
|
|
12
|
+
# 001uhVrr step one step the way the last one went
|
|
13
|
+
# 010uhVrr step in one step towards the hub
|
|
14
|
+
# 011uhVrr step out one step towards the rim
|
|
15
|
+
#
|
|
16
|
+
# Each step waits out the step rate rr picks (STEP_RATES), and u has
|
|
17
|
+
# a step update the track register, as restore and seek always do.
|
|
18
|
+
# With V the head settles and the command reads IDs until one carries
|
|
19
|
+
# the track register's track, or sets NOT_FOUND after five turns.
|
|
20
|
+
module Stepping
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
def start_type1
|
|
24
|
+
@type1 = true
|
|
25
|
+
@status = 0
|
|
26
|
+
@drq = false
|
|
27
|
+
@phase = STEPPED
|
|
28
|
+
@steps = 0
|
|
29
|
+
if @command < 0x10
|
|
30
|
+
@track = 0xff
|
|
31
|
+
@data = 0
|
|
32
|
+
elsif @command >= 0x40
|
|
33
|
+
@inward = @command < 0x60
|
|
34
|
+
end
|
|
35
|
+
step_done unless spinning_up?(STEPPED)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def spun_up
|
|
39
|
+
@status |= SPUN_UP
|
|
40
|
+
@phase = @after_spin_up
|
|
41
|
+
case @after_spin_up
|
|
42
|
+
when STEPPED then step_done
|
|
43
|
+
when SEARCH then resume_type2
|
|
44
|
+
else resume_track
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# The step rate has passed: the next step, or the end of the moves.
|
|
49
|
+
def step_done
|
|
50
|
+
return next_step if @steps.zero? || @command < 0x20
|
|
51
|
+
|
|
52
|
+
moved
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Restore and seek step until the track register matches, restore
|
|
56
|
+
# also stopping at track 0. The others step once.
|
|
57
|
+
def next_step
|
|
58
|
+
return single_step if @command >= 0x20
|
|
59
|
+
return seek_restore if @command < 0x10 && restored?
|
|
60
|
+
|
|
61
|
+
if @track == @data
|
|
62
|
+
moved
|
|
63
|
+
else
|
|
64
|
+
@inward = @data > @track
|
|
65
|
+
@track = (@track + (@inward ? 1 : -1)) & 0xff
|
|
66
|
+
pulse
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def restored?
|
|
71
|
+
return false unless @mechanism.track0? || @steps >= 255
|
|
72
|
+
|
|
73
|
+
@status |= NOT_FOUND if !@mechanism.track0? && @command.anybits?(VERIFY)
|
|
74
|
+
true
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def seek_restore
|
|
78
|
+
@track = 0 if @mechanism.track0?
|
|
79
|
+
moved
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def single_step
|
|
83
|
+
@track = (@track + (@inward ? 1 : -1)) & 0xff if @command.anybits?(UPDATE)
|
|
84
|
+
pulse
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def pulse
|
|
88
|
+
@steps += 1
|
|
89
|
+
@mechanism.step(@inward)
|
|
90
|
+
@phase = STEPPED
|
|
91
|
+
@due = @now + STEP_RATES[@command & 0x03]
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# The head is there: with V it settles, and the command ends
|
|
95
|
+
# otherwise.
|
|
96
|
+
def moved
|
|
97
|
+
return finish unless @command.anybits?(VERIFY) && @status.nobits?(NOT_FOUND)
|
|
98
|
+
|
|
99
|
+
@phase = SETTLED
|
|
100
|
+
@due = @now + SETTLE
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def verify_track
|
|
104
|
+
@mode = VERIFY_TRACK
|
|
105
|
+
begin_search
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Drives
|
|
5
|
+
class Model1581
|
|
6
|
+
class WD1772
|
|
7
|
+
# The type III commands that take a whole turn, from one index pulse
|
|
8
|
+
# to the next:
|
|
9
|
+
#
|
|
10
|
+
# 11100hE00 read track every byte under the head (Track#raw)
|
|
11
|
+
# 11110hEP0 write track every byte the CPU sends, for a format
|
|
12
|
+
#
|
|
13
|
+
# Write track asks for its first byte at once and starts at the index
|
|
14
|
+
# pulse, giving up with LOST_DATA if the byte hasn't come three bytes
|
|
15
|
+
# later. $F5 writes a sync mark, an $A1, and the first of a run starts
|
|
16
|
+
# the CRC over; $F6 writes $C2; $F7 writes the CRC's two bytes. At
|
|
17
|
+
# the next index pulse the track under the head becomes the fields
|
|
18
|
+
# found in what went down (Track.parse).
|
|
19
|
+
module Tracks
|
|
20
|
+
LATE = 3
|
|
21
|
+
|
|
22
|
+
private
|
|
23
|
+
|
|
24
|
+
def start_type3
|
|
25
|
+
@type1 = false
|
|
26
|
+
@status = 0
|
|
27
|
+
@drq = false
|
|
28
|
+
@mode = @command.anybits?(0x10) ? WRITE : READ
|
|
29
|
+
resume_track unless spinning_up?(TRACK_INDEX)
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def resume_track
|
|
33
|
+
if @mode == WRITE
|
|
34
|
+
if @mechanism.write_protected?
|
|
35
|
+
@status |= PROTECTED
|
|
36
|
+
return finish
|
|
37
|
+
end
|
|
38
|
+
@drq = true
|
|
39
|
+
end
|
|
40
|
+
@phase = @mode == WRITE ? WRITE_TRACK_START : TRACK_INDEX
|
|
41
|
+
return wait_index(@phase) if @command.nobits?(SETTLE_DELAY)
|
|
42
|
+
|
|
43
|
+
@due = @now + SETTLE
|
|
44
|
+
@settling = true
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def wait_index(phase)
|
|
48
|
+
@settling = false
|
|
49
|
+
@phase = phase
|
|
50
|
+
@due = next_index
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def track_index
|
|
54
|
+
return wait_index(TRACK_INDEX) if @settling
|
|
55
|
+
|
|
56
|
+
@bytes = (@mechanism.track || Track.new([])).raw
|
|
57
|
+
@index = 0
|
|
58
|
+
@phase = READ_TRACK
|
|
59
|
+
@due = @now + BYTE
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def track_byte_read
|
|
63
|
+
@status |= LOST_DATA if @drq
|
|
64
|
+
@data = @bytes[@index]
|
|
65
|
+
@drq = true
|
|
66
|
+
@index += 1
|
|
67
|
+
@index == Track::LENGTH ? finish : @due += BYTE
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def write_track_start
|
|
71
|
+
return wait_index(WRITE_TRACK_START) if @settling
|
|
72
|
+
|
|
73
|
+
@bytes = []
|
|
74
|
+
@syncs = []
|
|
75
|
+
@crc = 0xffff
|
|
76
|
+
@phase = WRITE_TRACK
|
|
77
|
+
return track_byte_written unless @drq
|
|
78
|
+
|
|
79
|
+
@late = true
|
|
80
|
+
@due = @now + (LATE * BYTE)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# The next byte from the data register goes under the head, a 0
|
|
84
|
+
# where DRQ went unanswered.
|
|
85
|
+
def track_byte_written
|
|
86
|
+
return lost if @late && @drq
|
|
87
|
+
return track_written if @bytes.length >= Track::LENGTH
|
|
88
|
+
|
|
89
|
+
@late = false
|
|
90
|
+
value = @drq ? 0 : @data
|
|
91
|
+
@status |= LOST_DATA if @drq
|
|
92
|
+
@drq = true
|
|
93
|
+
before = @bytes.length
|
|
94
|
+
lay_byte(value)
|
|
95
|
+
@due = @now + ((@bytes.length - before) * BYTE)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def lay_byte(value)
|
|
99
|
+
case value
|
|
100
|
+
when 0xf5
|
|
101
|
+
@crc = 0xffff unless @syncs.last
|
|
102
|
+
push_byte(Track::SYNC, true)
|
|
103
|
+
when 0xf6 then push_byte(0xc2, false)
|
|
104
|
+
when 0xf7
|
|
105
|
+
crc = @crc
|
|
106
|
+
push_byte(crc >> 8, false)
|
|
107
|
+
push_byte(crc & 0xff, false)
|
|
108
|
+
else push_byte(value, false)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def push_byte(value, sync)
|
|
113
|
+
@bytes << value
|
|
114
|
+
@syncs << sync
|
|
115
|
+
@crc = Track.crc([value], @crc)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def track_written
|
|
119
|
+
@drq = false
|
|
120
|
+
@mechanism.write(Track.parse(@bytes.first(Track::LENGTH), @syncs))
|
|
121
|
+
finish
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
end
|
|
127
|
+
end
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Drives
|
|
5
|
+
class Model1581
|
|
6
|
+
class WD1772
|
|
7
|
+
# The disk turning under the head: the index pulses a phase waits
|
|
8
|
+
# for or counts, and the cycle the head comes to a place round the
|
|
9
|
+
# track.
|
|
10
|
+
module Turn
|
|
11
|
+
# The disk began or stopped turning: a phase waiting on the turn
|
|
12
|
+
# starts its wait again.
|
|
13
|
+
def spin_changed
|
|
14
|
+
case @phase
|
|
15
|
+
when SPIN_UP, MOTOR_IDLE, INDEX_INTERRUPT then count_index
|
|
16
|
+
when SEARCH then begin_search
|
|
17
|
+
when TRACK_INDEX, WRITE_TRACK_START then wait_index(@phase)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
# The motor starts: with h clear and the motor off, the command waits
|
|
24
|
+
# out six index pulses first, and the phase comes after them.
|
|
25
|
+
def spinning_up?(phase)
|
|
26
|
+
spin_up = !@motor_on && @command.nobits?(NO_SPIN_UP)
|
|
27
|
+
@motor_on = true
|
|
28
|
+
return false unless spin_up
|
|
29
|
+
|
|
30
|
+
@after_spin_up = phase
|
|
31
|
+
@phase = SPIN_UP
|
|
32
|
+
@count = 6
|
|
33
|
+
count_index
|
|
34
|
+
true
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Waits for @count index pulses, or for the disk to turn.
|
|
38
|
+
def count_index
|
|
39
|
+
@due = next_index
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def index_counted
|
|
43
|
+
@count -= 1
|
|
44
|
+
return @due += Mechanism::REVOLUTION if @count.positive?
|
|
45
|
+
|
|
46
|
+
case @phase
|
|
47
|
+
when SPIN_UP then spun_up
|
|
48
|
+
when MOTOR_IDLE
|
|
49
|
+
@motor_on = false
|
|
50
|
+
idle
|
|
51
|
+
else
|
|
52
|
+
@intrq = true
|
|
53
|
+
idle
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# The cycle the next index pulse starts, or NEVER while no disk turns.
|
|
58
|
+
def next_index = at_angle(0)
|
|
59
|
+
|
|
60
|
+
# The cycle the head next comes to +angle+, from the index.
|
|
61
|
+
def at_angle(angle)
|
|
62
|
+
return NEVER unless @mechanism.spinning?
|
|
63
|
+
|
|
64
|
+
delta = (angle - @mechanism.angle(@now)) % Mechanism::REVOLUTION
|
|
65
|
+
@now + (delta.zero? ? Mechanism::REVOLUTION : delta)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# The cycle the byte at +position+ round the track has passed under
|
|
69
|
+
# the head.
|
|
70
|
+
def byte_end(position) = at_angle(((position + 1) % Track::LENGTH) * BYTE)
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "badline/drives/model1581/wd1772/registers"
|
|
4
|
+
require "badline/drives/model1581/wd1772/turn"
|
|
5
|
+
require "badline/drives/model1581/wd1772/stepping"
|
|
6
|
+
require "badline/drives/model1581/wd1772/sectors"
|
|
7
|
+
require "badline/drives/model1581/wd1772/sector_writes"
|
|
8
|
+
require "badline/drives/model1581/wd1772/tracks"
|
|
9
|
+
|
|
10
|
+
module Badline
|
|
11
|
+
module Drives
|
|
12
|
+
class Model1581
|
|
13
|
+
# The WD1772 floppy disk controller at $6000, as the WD177x data sheet
|
|
14
|
+
# describes it, working on the Mechanism's Track at sector level: it
|
|
15
|
+
# finds ID and data fields where they lie round the turn and moves
|
|
16
|
+
# their bytes at the MFM double-density rate, a byte every 32 µs, but
|
|
17
|
+
# keeps no flux or bitstream.
|
|
18
|
+
#
|
|
19
|
+
# $6000 status (read), command (write)
|
|
20
|
+
# $6001 track
|
|
21
|
+
# $6002 sector
|
|
22
|
+
# $6003 data
|
|
23
|
+
#
|
|
24
|
+
# It runs on the drive's clock, 2 MHz here, so the data sheet's times,
|
|
25
|
+
# given for 8 MHz on the chip's clock pin, come out as BYTE cycles a
|
|
26
|
+
# byte, STEP_RATES between steps and SETTLE for the head to settle.
|
|
27
|
+
#
|
|
28
|
+
# A command runs as a chain of phases, each due at a cycle (@due): a
|
|
29
|
+
# step, an index pulse, the end of a byte under the head. Between them
|
|
30
|
+
# nothing happens, so cycle! only counts. BUSY sets as the command is
|
|
31
|
+
# written, and the chip takes it up START cycles later, 16 µs, so a
|
|
32
|
+
# command with nothing to do, such as a seek to the track the head is
|
|
33
|
+
# on, still shows BUSY to the DOS, which polls for it before waiting
|
|
34
|
+
# for it to clear.
|
|
35
|
+
#
|
|
36
|
+
# The 1581 leaves INTRQ and DRQ unconnected and polls the status
|
|
37
|
+
# register instead (schematic sheet 2), but both are here (intrq?,
|
|
38
|
+
# drq?). Its DOS sets h in every command, so the motor spin-up wait
|
|
39
|
+
# never runs; the spindle follows the 8520's /MOTOR line instead.
|
|
40
|
+
class WD1772
|
|
41
|
+
include Registers
|
|
42
|
+
include Turn
|
|
43
|
+
include Stepping
|
|
44
|
+
include Sectors
|
|
45
|
+
include SectorWrites
|
|
46
|
+
include Tracks
|
|
47
|
+
|
|
48
|
+
BYTE = 64
|
|
49
|
+
START = 32
|
|
50
|
+
STEP_RATES = [12_000, 24_000, 4_000, 6_000].freeze
|
|
51
|
+
SETTLE = 30_000
|
|
52
|
+
|
|
53
|
+
NEVER = 1 << 60
|
|
54
|
+
|
|
55
|
+
# Status bits. Bits 1 and 2 report the index pulse and track 0 after
|
|
56
|
+
# a type I command, and DRQ and lost data after the others; bit 5
|
|
57
|
+
# reports spin-up after a type I command and a deleted data mark
|
|
58
|
+
# after a read.
|
|
59
|
+
BUSY = 0x01
|
|
60
|
+
INDEX = 0x02
|
|
61
|
+
DATA_REQUEST = 0x02
|
|
62
|
+
TRACK0 = 0x04
|
|
63
|
+
LOST_DATA = 0x04
|
|
64
|
+
CRC_ERROR = 0x08
|
|
65
|
+
NOT_FOUND = 0x10
|
|
66
|
+
SPUN_UP = 0x20
|
|
67
|
+
DELETED = 0x20
|
|
68
|
+
PROTECTED = 0x40
|
|
69
|
+
MOTOR_ON = 0x80
|
|
70
|
+
|
|
71
|
+
# Command flags.
|
|
72
|
+
NO_SPIN_UP = 0x08
|
|
73
|
+
VERIFY = 0x04
|
|
74
|
+
SETTLE_DELAY = 0x04
|
|
75
|
+
MULTIPLE = 0x10
|
|
76
|
+
UPDATE = 0x10
|
|
77
|
+
DELETED_MARK = 0x01
|
|
78
|
+
|
|
79
|
+
# Phases.
|
|
80
|
+
IDLE = 0
|
|
81
|
+
SPIN_UP = 1
|
|
82
|
+
STEPPED = 2
|
|
83
|
+
SETTLED = 3
|
|
84
|
+
SEARCH = 4
|
|
85
|
+
READ_DATA = 5
|
|
86
|
+
WRITE_GATE = 6
|
|
87
|
+
WRITE_DATA = 7
|
|
88
|
+
READ_TRACK = 8
|
|
89
|
+
TRACK_INDEX = 9
|
|
90
|
+
WRITE_TRACK = 10
|
|
91
|
+
MOTOR_IDLE = 11
|
|
92
|
+
INDEX_INTERRUPT = 12
|
|
93
|
+
SETTLE_SEARCH = 13
|
|
94
|
+
READ_ADDRESS = 14
|
|
95
|
+
WRITE_TRACK_START = 15
|
|
96
|
+
STARTING = 16
|
|
97
|
+
|
|
98
|
+
# What a search for an ID field is for.
|
|
99
|
+
READ = 0
|
|
100
|
+
WRITE = 1
|
|
101
|
+
ADDRESS = 2
|
|
102
|
+
VERIFY_TRACK = 3
|
|
103
|
+
|
|
104
|
+
attr_reader :now, :track, :sector, :data, :command
|
|
105
|
+
|
|
106
|
+
def initialize(mechanism)
|
|
107
|
+
@mechanism = mechanism
|
|
108
|
+
@now = 0
|
|
109
|
+
@due = NEVER
|
|
110
|
+
@phase = IDLE
|
|
111
|
+
reset!
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# The MR line: the registers as the data sheet leaves them, $03 in
|
|
115
|
+
# the command register and 1 in the sector register, and no command
|
|
116
|
+
# running.
|
|
117
|
+
def reset!
|
|
118
|
+
@command = 0x03
|
|
119
|
+
@track = 0
|
|
120
|
+
@sector = 1
|
|
121
|
+
@data = 0
|
|
122
|
+
@status = 0
|
|
123
|
+
@type1 = true
|
|
124
|
+
@drq = false
|
|
125
|
+
@intrq = false
|
|
126
|
+
@motor_on = false
|
|
127
|
+
@inward = true
|
|
128
|
+
clear_command
|
|
129
|
+
idle
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
def cycle!
|
|
133
|
+
@now += 1
|
|
134
|
+
advance if @now == @due
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
# How many cycles can go by before the next phase is due.
|
|
138
|
+
def quiet_cycles = @due - @now - 1
|
|
139
|
+
|
|
140
|
+
# Runs +cycles+ cycles at once, as many as quiet_cycles allows.
|
|
141
|
+
def fast_forward(cycles)
|
|
142
|
+
@now += cycles
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
def busy? = @phase != IDLE && @phase != MOTOR_IDLE && @phase != INDEX_INTERRUPT
|
|
146
|
+
|
|
147
|
+
def drq? = @drq
|
|
148
|
+
|
|
149
|
+
def intrq? = @intrq
|
|
150
|
+
|
|
151
|
+
def motor_on? = @motor_on
|
|
152
|
+
|
|
153
|
+
private
|
|
154
|
+
|
|
155
|
+
# A command ends: INTRQ, and the motor turns off after nine more
|
|
156
|
+
# index pulses unless a command comes first.
|
|
157
|
+
def finish
|
|
158
|
+
@intrq = true
|
|
159
|
+
@phase = MOTOR_IDLE
|
|
160
|
+
@count = 9
|
|
161
|
+
count_index
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
# What a command keeps between its phases.
|
|
165
|
+
def clear_command
|
|
166
|
+
@steps = 0
|
|
167
|
+
@count = 0
|
|
168
|
+
@after_spin_up = IDLE
|
|
169
|
+
@mode = 0
|
|
170
|
+
@deadline = NEVER
|
|
171
|
+
@id_at = NEVER
|
|
172
|
+
@found = -1
|
|
173
|
+
@bytes = []
|
|
174
|
+
@syncs = []
|
|
175
|
+
@index = 0
|
|
176
|
+
@crc = 0xffff
|
|
177
|
+
@crc_good = true
|
|
178
|
+
@write_id = 0
|
|
179
|
+
@size = 0
|
|
180
|
+
@gate_open = false
|
|
181
|
+
@late = false
|
|
182
|
+
@settling = false
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def idle
|
|
186
|
+
@phase = IDLE
|
|
187
|
+
@due = NEVER
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def advance
|
|
191
|
+
case @phase
|
|
192
|
+
when STARTING then start_command
|
|
193
|
+
when SPIN_UP, MOTOR_IDLE, INDEX_INTERRUPT then index_counted
|
|
194
|
+
when STEPPED then step_done
|
|
195
|
+
when SETTLED then verify_track
|
|
196
|
+
when SETTLE_SEARCH then begin_search
|
|
197
|
+
when SEARCH then id_passed
|
|
198
|
+
when READ_DATA, READ_ADDRESS then byte_read
|
|
199
|
+
else advance_write
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def advance_write
|
|
204
|
+
case @phase
|
|
205
|
+
when WRITE_GATE then write_gate
|
|
206
|
+
when WRITE_DATA then byte_written
|
|
207
|
+
when READ_TRACK then track_byte_read
|
|
208
|
+
when TRACK_INDEX then track_index
|
|
209
|
+
when WRITE_TRACK_START then write_track_start
|
|
210
|
+
when WRITE_TRACK then track_byte_written
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|