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
data/lib/badline/cpu_port.rb
DELETED
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
# The I/O port of the 6510 and the 8502 at $00 (direction) and $01
|
|
5
|
-
# (data). An input pin reads its pull-up, P4 reads the datasette's sense
|
|
6
|
-
# line, and a pin without a pull-up holds the charge last driven onto
|
|
7
|
-
# it. P5 drives the datasette motor through an inverter: low runs it.
|
|
8
|
-
#
|
|
9
|
-
# The 6510 has pull-ups on P0-P2 and P4 and leaves P3, P6 and P7
|
|
10
|
-
# floating. The 8502 adds a CAPS LOCK pin on P6, high while the key is
|
|
11
|
-
# up.
|
|
12
|
-
class CPUPort
|
|
13
|
-
TAPE_SENSE = 0b0001_0000
|
|
14
|
-
|
|
15
|
-
# The direction and output registers, and the charge on the floating
|
|
16
|
-
# pins.
|
|
17
|
-
attr_reader :ddr, :data, :floating
|
|
18
|
-
|
|
19
|
-
# The port as the banking logic reads it (PortStatus).
|
|
20
|
-
attr_reader :status
|
|
21
|
-
|
|
22
|
-
# Whether CAPS LOCK is down, holding its pin low.
|
|
23
|
-
attr_reader :caps_lock
|
|
24
|
-
|
|
25
|
-
# +pullups+ and +floating+ are the masks of the pins with a pull-up and
|
|
26
|
-
# of the floating ones, and +caps_lock+ the CAPS LOCK pin's, 0 where
|
|
27
|
-
# there is none.
|
|
28
|
-
def initialize(datasette, pullups:, floating:, caps_lock: 0)
|
|
29
|
-
@datasette = datasette
|
|
30
|
-
@pullups = pullups
|
|
31
|
-
@floating_mask = floating
|
|
32
|
-
@caps_lock_pin = caps_lock
|
|
33
|
-
@caps_lock = false
|
|
34
|
-
@ddr = 0x00
|
|
35
|
-
@data = 0x00
|
|
36
|
-
@floating = 0x00
|
|
37
|
-
@change_handler = nil
|
|
38
|
-
@status = PortStatus.new(%i[basic kernal io tape_out tape_switch tape_motor], value: input_value)
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# Calls the block after every write to the port, for the bus to remap
|
|
42
|
-
# its banks.
|
|
43
|
-
def on_change(&handler)
|
|
44
|
-
@change_handler = handler
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
# What a read of $01 sees.
|
|
48
|
-
def value = @status.value
|
|
49
|
-
|
|
50
|
-
def write_ddr(value)
|
|
51
|
-
@ddr = value
|
|
52
|
-
update
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def write_data(value)
|
|
56
|
-
@data = value
|
|
57
|
-
update
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
# The RES line clears the direction and output registers. The floating
|
|
61
|
-
# pins keep their charge.
|
|
62
|
-
def reset!
|
|
63
|
-
@ddr = 0x00
|
|
64
|
-
@data = 0x00
|
|
65
|
-
update
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
# Sets the registers and the charge, as a snapshot restores them, and
|
|
69
|
-
# drives the motor and calls the change handler as a write does.
|
|
70
|
-
def restore(ddr, data, floating)
|
|
71
|
-
load(ddr, data, floating)
|
|
72
|
-
update
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
# Sets the registers and the charge, as a snapshot loads them, without
|
|
76
|
-
# driving the motor or calling the change handler.
|
|
77
|
-
def load(ddr, data, floating)
|
|
78
|
-
@ddr = ddr
|
|
79
|
-
@data = data
|
|
80
|
-
@floating = floating
|
|
81
|
-
refresh
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# Holds CAPS LOCK down, or lets it up.
|
|
85
|
-
def caps_lock=(down)
|
|
86
|
-
@caps_lock = down
|
|
87
|
-
refresh
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
# Reads the inputs again, after the datasette's sense line changes.
|
|
91
|
-
def refresh
|
|
92
|
-
@status.value = input_value
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
private
|
|
96
|
-
|
|
97
|
-
def update
|
|
98
|
-
driven = @ddr & @floating_mask
|
|
99
|
-
@floating = (@floating & ~driven) | (@data & driven)
|
|
100
|
-
refresh
|
|
101
|
-
@datasette.motor = !@status.tape_motor?
|
|
102
|
-
@change_handler&.call
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
def input_value
|
|
106
|
-
input = @pullups | (@floating & @floating_mask)
|
|
107
|
-
input |= @caps_lock_pin unless @caps_lock
|
|
108
|
-
input &= ~TAPE_SENSE if @datasette.sense_low?
|
|
109
|
-
(@data & @ddr) | (input & ~@ddr & 0xff)
|
|
110
|
-
end
|
|
111
|
-
end
|
|
112
|
-
end
|
data/lib/badline/datasette.rb
DELETED
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
# The 1530 datasette. Plays a pulse stream into CIA 1's FLAG pin while the
|
|
5
|
-
# motor runs with a key pressed, and reports the keys through the cassette
|
|
6
|
-
# sense line on the $01 port. With RECORD down too, it records the
|
|
7
|
-
# machine's write line onto the tape instead.
|
|
8
|
-
class Datasette
|
|
9
|
-
# What inserting a tape raises on a machine without a cassette port.
|
|
10
|
-
class Missing < ArgumentError; end
|
|
11
|
-
|
|
12
|
-
attr_reader :tape
|
|
13
|
-
attr_writer :motor
|
|
14
|
-
|
|
15
|
-
def initialize(tape = nil)
|
|
16
|
-
@tape = tape
|
|
17
|
-
@connected = true
|
|
18
|
-
@playing = false
|
|
19
|
-
@recording = false
|
|
20
|
-
@write_high = true
|
|
21
|
-
@since = 0
|
|
22
|
-
@motor = false
|
|
23
|
-
@countdown = 0
|
|
24
|
-
@flag_handler = nil
|
|
25
|
-
@sense_handler = nil
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
# Falling edges on the tape read line.
|
|
29
|
-
def on_flag(&handler)
|
|
30
|
-
@flag_handler = handler
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
# The cassette sense line, which the $01 port reads back.
|
|
34
|
-
def on_sense_change(&handler)
|
|
35
|
-
@sense_handler = handler
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
# Whether the machine has a datasette at its cassette port. The SX-64
|
|
39
|
-
# has none: its keys stay up and it takes no tape.
|
|
40
|
-
def connected? = @connected
|
|
41
|
-
|
|
42
|
-
def disconnect!
|
|
43
|
-
eject
|
|
44
|
-
@connected = false
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def insert(tape)
|
|
48
|
-
raise Missing, "this machine has no datasette" unless @connected
|
|
49
|
-
|
|
50
|
-
@tape = tape
|
|
51
|
-
rewind
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def eject
|
|
55
|
-
stop!
|
|
56
|
-
@tape = nil
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
def rewind
|
|
60
|
-
@tape&.rewind
|
|
61
|
-
@countdown = 0
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def play! = press(true)
|
|
65
|
-
def stop! = press(false)
|
|
66
|
-
|
|
67
|
-
# Presses RECORD and PLAY together.
|
|
68
|
-
def record!
|
|
69
|
-
return if !@connected || @tape.nil?
|
|
70
|
-
|
|
71
|
-
press(true)
|
|
72
|
-
@recording = true
|
|
73
|
-
@since = 0
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
def recording? = @recording
|
|
77
|
-
|
|
78
|
-
# The machine's tape write line. While the deck records with its motor
|
|
79
|
-
# running, each rising edge ends a pulse on the tape, as long as the
|
|
80
|
-
# time since the edge before, and plays back as a falling edge on the
|
|
81
|
-
# read line.
|
|
82
|
-
def write_line=(high)
|
|
83
|
-
rose = high && !@write_high
|
|
84
|
-
@write_high = high
|
|
85
|
-
return unless rose && @recording && running?
|
|
86
|
-
|
|
87
|
-
@tape.record_pulse(@since)
|
|
88
|
-
@since = 0
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
def playing? = @playing
|
|
92
|
-
|
|
93
|
-
# Sense reads low while a key is down on the deck.
|
|
94
|
-
def sense_low? = @playing
|
|
95
|
-
|
|
96
|
-
def motor? = @motor
|
|
97
|
-
|
|
98
|
-
def running? = @playing && @motor && !@tape.nil?
|
|
99
|
-
|
|
100
|
-
# The keys, the motor, the countdown to the next pulse and the tape:
|
|
101
|
-
# its path, its bytes and how far it has played.
|
|
102
|
-
def save_state(out)
|
|
103
|
-
out.marker("DATASETTE")
|
|
104
|
-
out.boolean(@playing).boolean(@motor).int(@countdown).boolean(!@tape.nil?)
|
|
105
|
-
return unless @tape
|
|
106
|
-
|
|
107
|
-
out.string(@tape.path).blob(@tape.bytes).int(@tape.position)
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
# The tape goes back in from the bytes the state holds, without its
|
|
111
|
-
# host file, unless the tape in is the same one. The sense and flag
|
|
112
|
-
# handlers don't fire.
|
|
113
|
-
def load_state(input)
|
|
114
|
-
input.marker("DATASETTE")
|
|
115
|
-
@playing = input.boolean?
|
|
116
|
-
@motor = input.boolean?
|
|
117
|
-
@countdown = input.int
|
|
118
|
-
return @tape = nil unless input.boolean?
|
|
119
|
-
|
|
120
|
-
path = input.string
|
|
121
|
-
bytes = input.blob
|
|
122
|
-
position = input.int
|
|
123
|
-
@tape = Storage::TAP.new(path, bytes:) unless @tape&.path&.b == path && @tape.bytes == bytes
|
|
124
|
-
@tape.position = position
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
def cycle!
|
|
128
|
-
return unless running?
|
|
129
|
-
return @since += 1 if @recording
|
|
130
|
-
|
|
131
|
-
@countdown = @tape.next_pulse.to_i if @countdown.zero?
|
|
132
|
-
return if @countdown.zero?
|
|
133
|
-
|
|
134
|
-
@countdown -= 1
|
|
135
|
-
@flag_handler&.call if @countdown.zero?
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
def inspect
|
|
139
|
-
"#<#{self.class.name} tape=#{@tape ? @tape.class.name : 'none'} " \
|
|
140
|
-
"playing=#{@playing} motor=#{@motor}>"
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
private
|
|
144
|
-
|
|
145
|
-
def press(down)
|
|
146
|
-
return if down == @playing || !@connected
|
|
147
|
-
|
|
148
|
-
finish_recording unless down
|
|
149
|
-
@playing = down
|
|
150
|
-
@sense_handler&.call
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
# Releasing the keys ends a recording, and writes the tape out.
|
|
154
|
-
def finish_recording
|
|
155
|
-
return unless @recording
|
|
156
|
-
|
|
157
|
-
@recording = false
|
|
158
|
-
@tape.save
|
|
159
|
-
end
|
|
160
|
-
end
|
|
161
|
-
end
|
data/lib/badline/drive/core.rb
DELETED
|
@@ -1,147 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
module Drive
|
|
5
|
-
# What every Commodore disk drive here shares: a 6502 running the DOS
|
|
6
|
-
# ROM, with chips on its bus facing the serial bus and the disk
|
|
7
|
-
# mechanism, on a clock of its own.
|
|
8
|
-
#
|
|
9
|
-
# The drive runs on its own crystal, so it clocks against the host's
|
|
10
|
-
# clock through a fractional accumulator: each host cycle adds the
|
|
11
|
-
# drive's clock rate worth of phase, and every whole host period in it
|
|
12
|
-
# runs a drive cycle. Against the PAL C64's 985,248 Hz a drive at
|
|
13
|
-
# 1 MHz runs one drive cycle per host cycle and a second one about
|
|
14
|
-
# every 67. The host sets its clock on attaching the drive, and until
|
|
15
|
-
# then a 1 MHz drive runs one cycle per host cycle.
|
|
16
|
-
#
|
|
17
|
-
# The Mechanism reads a Disk put in with insert.
|
|
18
|
-
#
|
|
19
|
-
# While the DOS idles, host_cycle! skips the drive's cycles and catches
|
|
20
|
-
# up on them later, exactly (see Idle). The readers of the drive's parts
|
|
21
|
-
# catch up first, so they find the drive as running every cycle would
|
|
22
|
-
# have left it. Once the DOS's timer interrupts come round, the drive
|
|
23
|
-
# sleeps through them too (see Orbit).
|
|
24
|
-
#
|
|
25
|
-
# A model includes Core and builds its parts, sets @clock_hz and
|
|
26
|
-
# @idle_loop, and runs one drive cycle in step. It hears ATN on
|
|
27
|
-
# connecting (hear_atn), drives the serial bus (serial_output), and
|
|
28
|
-
# answers Idle's and Orbit's questions about its chips, as VIAs does
|
|
29
|
-
# for the 1541 and the 1571.
|
|
30
|
-
module Core
|
|
31
|
-
include Sleep
|
|
32
|
-
include Idle
|
|
33
|
-
include Orbit
|
|
34
|
-
|
|
35
|
-
attr_reader :device, :serial_bus
|
|
36
|
-
|
|
37
|
-
def cpu
|
|
38
|
-
settle!
|
|
39
|
-
@cpu
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
def bus
|
|
43
|
-
settle!
|
|
44
|
-
@bus
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def mechanism
|
|
48
|
-
settle!
|
|
49
|
-
@mechanism
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
def cycles
|
|
53
|
-
settle!
|
|
54
|
-
@cycles
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def ram = bus.ram
|
|
58
|
-
|
|
59
|
-
def host_clock_hz=(clock_hz)
|
|
60
|
-
settle!
|
|
61
|
-
@host_clock_hz = clock_hz
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
# Plugs the drive into a serial bus, leaving the one it was on. A drive
|
|
65
|
-
# starts out on a bus of its own, with nothing else on it.
|
|
66
|
-
def connect(serial_bus)
|
|
67
|
-
settle!
|
|
68
|
-
@serial_bus&.detach(self)
|
|
69
|
-
@serial_bus = serial_bus
|
|
70
|
-
@serial_port.bus = serial_bus
|
|
71
|
-
serial_bus.attach(self)
|
|
72
|
-
hear_atn
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
# Puts a Disk in the drive (Disk.from_d64 makes one from an image).
|
|
76
|
-
# Nil takes the disk out.
|
|
77
|
-
def insert(disk)
|
|
78
|
-
settle!
|
|
79
|
-
@mechanism.insert(disk)
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def disk = mechanism.disk
|
|
83
|
-
|
|
84
|
-
# Whether the LED is lit. Reading it leaves the drive asleep: the LED
|
|
85
|
-
# is the same at the end of every pass the drive sleeps through.
|
|
86
|
-
def led_on? = @mechanism.led_on?
|
|
87
|
-
|
|
88
|
-
# Stores what the head wrote since the motor last stopped in the
|
|
89
|
-
# disk's image, as the motor stopping does.
|
|
90
|
-
def flush
|
|
91
|
-
settle!
|
|
92
|
-
@mechanism.flush
|
|
93
|
-
end
|
|
94
|
-
|
|
95
|
-
# Runs the drive cycles that fall in one host cycle: none, one or two.
|
|
96
|
-
# The host has run this cycle already, and the drive sees what it did
|
|
97
|
-
# from the next one on (see SerialPort). Asleep, the drive owes the
|
|
98
|
-
# cycles instead, until ATN moves or its counters are due (see Idle).
|
|
99
|
-
# It looks at ATN only after the machine pushed its lines into the bus
|
|
100
|
-
# (see host_written!).
|
|
101
|
-
def host_cycle!
|
|
102
|
-
if @asleep
|
|
103
|
-
return if (@slept += 1) != @wake_at && @host_still
|
|
104
|
-
|
|
105
|
-
return doze
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
phase = @phase + @clock_hz
|
|
109
|
-
while phase >= @host_clock_hz
|
|
110
|
-
@asleep ? @owed += 1 : run_cycle
|
|
111
|
-
phase -= @host_clock_hz
|
|
112
|
-
end
|
|
113
|
-
@phase = phase
|
|
114
|
-
settle! if @serial_port.atn_moved?
|
|
115
|
-
@serial_port.latch_host
|
|
116
|
-
plan_wake if @asleep
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
# The machine pushed its lines into the bus, so ATN may have moved.
|
|
120
|
-
def host_written!
|
|
121
|
-
@host_still = false
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
# The host moved its fast serial pins, which a 1541 has none to hear.
|
|
125
|
-
def fast_lines_moved = nil
|
|
126
|
-
|
|
127
|
-
# Runs one drive cycle, catching up first on any the drive owes (see
|
|
128
|
-
# step).
|
|
129
|
-
def cycle!
|
|
130
|
-
settle!
|
|
131
|
-
step
|
|
132
|
-
end
|
|
133
|
-
|
|
134
|
-
def inspect
|
|
135
|
-
"#<#{self.class.name} cycles=#{cycles} cpu=(#{cpu.inspect})>"
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
private
|
|
139
|
-
|
|
140
|
-
# A drive cycle from host_cycle!, which may find the idle loop.
|
|
141
|
-
def run_cycle
|
|
142
|
-
step
|
|
143
|
-
idle_loop_reached if @cpu.program_counter == @idle_loop && @idle_skip
|
|
144
|
-
end
|
|
145
|
-
end
|
|
146
|
-
end
|
|
147
|
-
end
|
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
module Drive
|
|
5
|
-
# Fast serial on a drive with a CIA, the 1571's 6526 or the 1581's
|
|
6
|
-
# 8520: through buffers a port line turns round, the CIA's CNT drives
|
|
7
|
-
# SRQ and its SP drives DATA, or it hears them. The drive pushes its
|
|
8
|
-
# pins into the bus as they move, and hears the host's as the host
|
|
9
|
-
# pushes them, pin by pin, so each byte goes through both shift
|
|
10
|
-
# registers bit by bit. The CIA takes no part in a pass of the idle
|
|
11
|
-
# loop, and any access to it, or the host moving its fast serial pins,
|
|
12
|
-
# wakes the drive.
|
|
13
|
-
#
|
|
14
|
-
# A model includes it beside Core, and calls turn_fast_serial when its
|
|
15
|
-
# direction line moves and drive_fast_serial each cycle the buffers
|
|
16
|
-
# face out. Its serial_output carries @fast_output above its port.
|
|
17
|
-
module FastSerial
|
|
18
|
-
# Whether the buffers face out, the drive's CIA driving DATA and SRQ.
|
|
19
|
-
attr_reader :fast_serial_out
|
|
20
|
-
|
|
21
|
-
# The host moved its fast serial pins: the CIA hears SRQ on CNT and
|
|
22
|
-
# DATA on SP while the buffers face in.
|
|
23
|
-
def fast_lines_moved
|
|
24
|
-
settle!
|
|
25
|
-
hear_fast_serial unless @fast_serial_out
|
|
26
|
-
end
|
|
27
|
-
|
|
28
|
-
private
|
|
29
|
-
|
|
30
|
-
def init_fast_serial
|
|
31
|
-
@fast_serial_out = false
|
|
32
|
-
@fast_output = 0
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
# The buffers turned round: outwards the CIA's pins drive the lines,
|
|
36
|
-
# and inwards they let go and hear them.
|
|
37
|
-
def turn_fast_serial(out)
|
|
38
|
-
@fast_serial_out = out
|
|
39
|
-
return unless @serial_bus
|
|
40
|
-
|
|
41
|
-
push_fast_output(out ? fast_pins : 0)
|
|
42
|
-
hear_fast_serial unless out
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
def drive_fast_serial
|
|
46
|
-
low = fast_pins
|
|
47
|
-
push_fast_output(low) if low != @fast_output
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
# The lines the CIA's CNT and SP pull while its serial port drives
|
|
51
|
-
# them.
|
|
52
|
-
def fast_pins
|
|
53
|
-
serial = @cia.serial
|
|
54
|
-
return 0 unless serial.output?
|
|
55
|
-
|
|
56
|
-
low = serial.cnt ? 0 : IECBus::DRIVE_FAST_SRQ
|
|
57
|
-
serial.sp_out ? low : low | IECBus::DRIVE_FAST_DATA
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def push_fast_output(low)
|
|
61
|
-
@fast_output = low
|
|
62
|
-
@serial_bus&.drives_fast_moved!
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
def hear_fast_serial
|
|
66
|
-
low = @serial_bus.low_lines
|
|
67
|
-
serial = @cia.serial
|
|
68
|
-
serial.cnt_in = low.nobits?(IECBus::SRQ)
|
|
69
|
-
serial.sp_in = low.nobits?(IECBus::DATA)
|
|
70
|
-
end
|
|
71
|
-
end
|
|
72
|
-
end
|
|
73
|
-
end
|
data/lib/badline/drive/idle.rb
DELETED
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
module Drive
|
|
5
|
-
# Skipping the drive's cycles while the DOS idles, exactly.
|
|
6
|
-
#
|
|
7
|
-
# With nothing to do, the DOS goes round its idle loop from the
|
|
8
|
-
# model's @idle_loop ($EBFF in the 1541, 446 cycles a pass), until VIA
|
|
9
|
-
# 2's timer 1 interrupts it every 14,850 cycles for the job loop, or
|
|
10
|
-
# ATN interrupts it through VIA 1's CA1. A pass writes RAM and VIA 2's
|
|
11
|
-
# port B, but puts back what it found, so the drive comes round to the
|
|
12
|
-
# loop's start as it left it. Only the timers' counters and the cycle
|
|
13
|
-
# counts move.
|
|
14
|
-
#
|
|
15
|
-
# Each time the CPU comes to the loop's start, the drive records the
|
|
16
|
-
# pass that follows. At the next it checks that the pass
|
|
17
|
-
#
|
|
18
|
-
# - left the CPU, both VIAs but for their counters, the bus's last
|
|
19
|
-
# byte, the SO pin, the mechanism (Mechanism#idle_state) and what
|
|
20
|
-
# the ports read from it, and every byte of RAM it read or wrote as
|
|
21
|
-
# it found them (Bus#watch!)
|
|
22
|
-
# - read nothing that changes from pass to pass: no counter, no shift
|
|
23
|
-
# register, and not VIA 1's port B, which reads the serial bus
|
|
24
|
-
# - wrote nothing that reaches outside the drive: not VIA 1, whose port
|
|
25
|
-
# B drives the serial bus, and not the motor on
|
|
26
|
-
# - ran while no counter could set a flag (VIA#quiet_cycles), with the
|
|
27
|
-
# motor off, no interrupt pulled and no trap on the CPU.
|
|
28
|
-
#
|
|
29
|
-
# Such a pass runs the same way again from where it ended, for as
|
|
30
|
-
# long as ATN holds still and no counter sets a flag, so the drive
|
|
31
|
-
# sleeps: host_cycle! only counts the host cycles that go by (see
|
|
32
|
-
# Sleep). It wakes
|
|
33
|
-
# when ATN moves, when a counter is due to set a flag, or when something
|
|
34
|
-
# outside reads or changes the drive (the readers in Core call
|
|
35
|
-
# settle!). Waking counts off the whole passes it owes in bulk,
|
|
36
|
-
# moving the counters on, and runs the rest cycle by cycle.
|
|
37
|
-
#
|
|
38
|
-
# The loop reads neither CLK nor DATA, so the drive sleeps through them
|
|
39
|
-
# moving and takes the C64's lines as they stand once it wakes. Its
|
|
40
|
-
# own lines hold still while it sleeps, so the C64 reads them without
|
|
41
|
-
# waking it (serial_output).
|
|
42
|
-
#
|
|
43
|
-
# A pass starts at the loop's start, where the CPU always comes from
|
|
44
|
-
# the loop's last instruction, a JMP, so what that leaves in the CPU's
|
|
45
|
-
# working registers is the same each time round.
|
|
46
|
-
#
|
|
47
|
-
# The timer's interrupts come round too, and once they do, the drive
|
|
48
|
-
# sleeps on through them (see Orbit).
|
|
49
|
-
module Idle
|
|
50
|
-
# Whether the drive may sleep through its idle loop. On by default,
|
|
51
|
-
# but for a drive whose CPU logs each instruction.
|
|
52
|
-
attr_reader :idle_skip
|
|
53
|
-
|
|
54
|
-
def idle_skip=(on)
|
|
55
|
-
settle!
|
|
56
|
-
@idle_skip = on
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
private
|
|
60
|
-
|
|
61
|
-
def init_idle(debug)
|
|
62
|
-
@idle_skip = !debug
|
|
63
|
-
@recording = false
|
|
64
|
-
@pass_cycles = 0
|
|
65
|
-
@pass_instructions = 0
|
|
66
|
-
init_sleep
|
|
67
|
-
init_orbits
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
# The CPU is at the loop's start. At an instruction boundary, the
|
|
71
|
-
# drive sleeps if the pass it recorded can repeat, and otherwise
|
|
72
|
-
# records the next.
|
|
73
|
-
def idle_loop_reached
|
|
74
|
-
return unless @cpu.boundary?
|
|
75
|
-
|
|
76
|
-
if @recording
|
|
77
|
-
stop_recording
|
|
78
|
-
return fall_asleep if repeatable_pass? && room_for_pass?
|
|
79
|
-
end
|
|
80
|
-
start_recording
|
|
81
|
-
end
|
|
82
|
-
|
|
83
|
-
def start_recording
|
|
84
|
-
return if busy_for_pass? || @cpu.trapped?
|
|
85
|
-
|
|
86
|
-
@recording = true
|
|
87
|
-
@record_state = idle_state
|
|
88
|
-
@record_cycles = @cycles
|
|
89
|
-
@record_instructions = @cpu.instructions
|
|
90
|
-
@record_quiet = quiet_cycles
|
|
91
|
-
@bus.watch!
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
def stop_recording
|
|
95
|
-
@recording = false
|
|
96
|
-
@bus.unwatch!
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
# Whether the pass just recorded can repeat.
|
|
100
|
-
def repeatable_pass?
|
|
101
|
-
!@bus.volatile && @cycles - @record_cycles <= @record_quiet && idle_state == @record_state &&
|
|
102
|
-
ram_as_found?
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
# Whether the counters leave room for a whole pass.
|
|
106
|
-
def room_for_pass? = quiet_cycles >= @cycles - @record_cycles
|
|
107
|
-
|
|
108
|
-
# Sleeps through the pass just recorded, over and over.
|
|
109
|
-
def fall_asleep
|
|
110
|
-
@pass_cycles = @cycles - @record_cycles
|
|
111
|
-
@pass_instructions = @cpu.instructions - @record_instructions
|
|
112
|
-
@asleep = true
|
|
113
|
-
@host_still = false
|
|
114
|
-
@owed = 0
|
|
115
|
-
@budget = quiet_cycles
|
|
116
|
-
anchor
|
|
117
|
-
end
|
|
118
|
-
|
|
119
|
-
def ram_as_found?
|
|
120
|
-
ram = @bus.ram
|
|
121
|
-
@bus.touched.all? { |addr, value| ram.peek(addr) == value }
|
|
122
|
-
end
|
|
123
|
-
end
|
|
124
|
-
end
|
|
125
|
-
end
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Badline
|
|
4
|
-
module Drive
|
|
5
|
-
# What Idle needs of a drive's 6502, which includes it beside
|
|
6
|
-
# CPU::Core.
|
|
7
|
-
module IdleCPU
|
|
8
|
-
# Everything the CPU holds but its cycle and instruction counts: the
|
|
9
|
-
# registers, the interrupt lines and pipeline, and what the last
|
|
10
|
-
# instruction left in its working registers. Drive::Idle compares
|
|
11
|
-
# it at two instruction boundaries.
|
|
12
|
-
def idle_state
|
|
13
|
-
[@program_counter, @stack_pointer, @a, @x, @y, @status.value,
|
|
14
|
-
@irq, @nmi, @irq_sample, @irq_pending, @nmi_sample, @nmi_pending, @skip_poll,
|
|
15
|
-
@boundary_irq, @boundary_nmi, @so_high, @interrupt, @brk, @pending_write, @stalled_at, @traps,
|
|
16
|
-
@operation, @optional_dummy, @boundary_crossed, @branch_taken,
|
|
17
|
-
@address, @pointer, @dummy_address, @value, @rmw_result]
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
# Counts +cycles+ cycles and +instructions+ instructions that ran
|
|
21
|
-
# without changing anything idle_state holds.
|
|
22
|
-
def fast_forward(cycles, instructions)
|
|
23
|
-
@cycles += cycles
|
|
24
|
-
@instructions += instructions
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|