badline 0.12.0 → 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 +25 -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 +4 -4
- 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} +6 -6
- data/lib/badline/c128/bus.rb +30 -51
- 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 +18 -72
- data/lib/badline/{computer → c64}/attachments.rb +16 -47
- 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/c64/common.rb +34 -0
- data/lib/badline/c64/kernal_traps.rb +89 -0
- 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 +20 -31
- data/lib/badline/{computer.rb → c64.rb} +22 -80
- 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 +27 -29
- 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 +10 -61
- 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/{file.rb → file_routine.rb} +1 -1
- data/lib/badline/kernal_trap/load.rb +6 -6
- data/lib/badline/kernal_trap/save.rb +5 -5
- data/lib/badline/kernal_trap/serial.rb +7 -7
- data/lib/badline/kernal_trap.rb +2 -3
- data/lib/badline/machine/clocking.rb +50 -0
- data/lib/badline/machine.rb +63 -7
- data/lib/badline/media/boot_disk.rb +2 -2
- data/lib/badline/media/disk_list.rb +3 -3
- data/lib/badline/media/disk_set.rb +1 -1
- data/lib/badline/media/extensions.rb +33 -0
- data/lib/badline/media/program.rb +28 -0
- data/lib/badline/media/true_drive.rb +4 -3
- data/lib/badline/media/tune.rb +35 -0
- data/lib/badline/media/vic20_cartridge.rb +1 -7
- data/lib/badline/media/vic20_media.rb +38 -80
- data/lib/badline/media.rb +84 -81
- data/lib/badline/model.rb +1 -1
- data/lib/badline/options/event.rb +3 -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 +10 -2
- data/lib/badline/snapshot/setup.rb +22 -66
- data/lib/badline/snapshot/state.rb +8 -17
- 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 +13 -12
- data/lib/badline/storage/d64_image.rb +15 -9
- data/lib/badline/storage/d71_image.rb +0 -2
- data/lib/badline/storage/d81_image.rb +0 -2
- data/lib/badline/storage/disk_image/writing.rb +2 -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 +11 -81
- 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 -60
- data/lib/badline/vic20/user_via_ports.rb +2 -2
- data/lib/badline/vic20.rb +20 -51
- metadata +250 -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 -72
- data/lib/badline/address_bus/sid_slots.rb +0 -42
- data/lib/badline/address_bus.rb +0 -235
- 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/computer/kernal_traps.rb +0 -29
- 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/cycleable.rb +0 -38
- 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 -318
- data/lib/badline/drive1541/disk_state.rb +0 -94
- 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 -852
- data/lib/badline/vic20/sound/output.rb +0 -83
- data/lib/badline/vic20/sound.rb +0 -233
- data/lib/badline/z80/arithmetic.rb +0 -117
- data/lib/badline/z80/bit_page.rb +0 -55
- data/lib/badline/z80/block_io.rb +0 -58
- data/lib/badline/z80/block_transfers.rb +0 -59
- data/lib/badline/z80/bus_cycles.rb +0 -111
- data/lib/badline/z80/core.rb +0 -113
- data/lib/badline/z80/exchanges.rb +0 -50
- data/lib/badline/z80/extended_page.rb +0 -89
- data/lib/badline/z80/flags.rb +0 -37
- data/lib/badline/z80/interrupt_acceptance.rb +0 -46
- data/lib/badline/z80/jumps.rb +0 -82
- data/lib/badline/z80/loads.rb +0 -98
- data/lib/badline/z80/main_page.rb +0 -134
- data/lib/badline/z80/registers.rb +0 -120
- data/lib/badline/z80/saved_state.rb +0 -69
- data/lib/badline/z80/shifts.rb +0 -64
- data/lib/badline/z80.rb +0 -11
- /data/lib/badline/snapshot/{fields.rb → vice/fields.rb} +0 -0
|
@@ -1,26 +1,17 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
+
require "badline/snapshot/c128_setup"
|
|
4
|
+
|
|
3
5
|
module Badline
|
|
4
6
|
class C128
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
# The model, the SID and the mode it resets into of the machine a State
|
|
8
|
-
# from #snapshot was taken of, the arguments C128.new takes.
|
|
9
|
-
def self.setup(state)
|
|
10
|
-
input = Snapshot::StateReader.new(state)
|
|
11
|
-
input.marker(MARKER)
|
|
12
|
-
input.check_stamp
|
|
13
|
-
SavedState.read_setup(input)
|
|
14
|
-
end
|
|
7
|
+
# How the machine a State from #snapshot was taken of was built.
|
|
8
|
+
def self.setup(state) = Snapshot::C128Setup.from(state)
|
|
15
9
|
|
|
16
10
|
# A new machine, built as the one a State from #snapshot was taken of,
|
|
17
11
|
# at that state.
|
|
18
|
-
def self.restored(state)
|
|
19
|
-
setup = setup(state)
|
|
20
|
-
new(model: setup[0], sid_model: setup[1], mode: setup[2]).apply_state(state)
|
|
21
|
-
end
|
|
12
|
+
def self.restored(state) = setup(state).build.apply_state(state)
|
|
22
13
|
|
|
23
|
-
# The whole machine's state for a snapshot, as
|
|
14
|
+
# The whole machine's state for a snapshot, as C64's: the
|
|
24
15
|
# machine's own latches, FAST and TEST as they last took hold, the bus with its RAM, the MMU, the chips and
|
|
25
16
|
# the VDC, the CPU, the cartridge, the disk device 8 serves through the
|
|
26
17
|
# traps and a true 1541. The serial lines go back into the bus from the
|
|
@@ -28,21 +19,6 @@ module Badline
|
|
|
28
19
|
# joysticks, CAPS LOCK and 40/80 DISPLAY, the traps and callbacks, and
|
|
29
20
|
# which chip renders.
|
|
30
21
|
module SavedState
|
|
31
|
-
SID_MODELS = %i[mos6581 mos8580].freeze
|
|
32
|
-
MODES = %i[c64 c128].freeze
|
|
33
|
-
|
|
34
|
-
# The model's name, the SID's model and the mode.
|
|
35
|
-
def self.read_setup(input)
|
|
36
|
-
name = input.string
|
|
37
|
-
known = Model::ALL.any? { |model| model.name == name }
|
|
38
|
-
raise Snapshot::FormatError, "the state names a C128 model badline doesn't know" unless known
|
|
39
|
-
|
|
40
|
-
sid_model = SID_MODELS.fetch(input.int)
|
|
41
|
-
[name, sid_model, MODES.fetch(input.int)]
|
|
42
|
-
rescue IndexError
|
|
43
|
-
raise Snapshot::FormatError, "the state names a SID or a mode badline doesn't know"
|
|
44
|
-
end
|
|
45
|
-
|
|
46
22
|
# How many more on_init handlers the machine a State was taken of had
|
|
47
23
|
# yet to run than this one has. Nil until the machine is restored.
|
|
48
24
|
attr_reader :init_handlers_lost
|
|
@@ -72,8 +48,8 @@ module Badline
|
|
|
72
48
|
end
|
|
73
49
|
|
|
74
50
|
def save_state(out)
|
|
75
|
-
out.marker(MARKER).stamp
|
|
76
|
-
|
|
51
|
+
out.marker(Snapshot::C128Setup::MARKER).stamp
|
|
52
|
+
snapshot_setup.write(out)
|
|
77
53
|
out.int(@cycles).int(@clock_bits).boolean(@nmi_asserted).boolean(@cartridge_nmi).boolean(@restore_pulse)
|
|
78
54
|
out.boolean(!@pending_keys.nil?)
|
|
79
55
|
out.ints(@pending_keys) if @pending_keys
|
|
@@ -83,14 +59,14 @@ module Badline
|
|
|
83
59
|
@cpu.save_state(out)
|
|
84
60
|
@z80.save_state(out)
|
|
85
61
|
out.int(@z80_due).int(@chips_ahead).boolean(@cpu_reset_pending)
|
|
86
|
-
|
|
62
|
+
save_trap_dos(out)
|
|
87
63
|
save_serial_bus(out)
|
|
88
64
|
end
|
|
89
65
|
|
|
90
66
|
def load_state(input)
|
|
91
|
-
input.marker(MARKER)
|
|
67
|
+
input.marker(Snapshot::C128Setup::MARKER)
|
|
92
68
|
input.check_stamp
|
|
93
|
-
check_setup(
|
|
69
|
+
check_setup(Snapshot::C128Setup.read(input))
|
|
94
70
|
@cycles = input.int
|
|
95
71
|
@clock_bits = input.int
|
|
96
72
|
@nmi_asserted = input.boolean?
|
|
@@ -105,24 +81,17 @@ module Badline
|
|
|
105
81
|
push_serial_lines
|
|
106
82
|
@cpu.load_state(input)
|
|
107
83
|
load_z80(input)
|
|
108
|
-
|
|
84
|
+
load_trap_dos(input)
|
|
109
85
|
load_serial_bus(input)
|
|
110
86
|
push_fast_serial
|
|
111
87
|
end
|
|
112
88
|
|
|
113
89
|
private
|
|
114
90
|
|
|
115
|
-
# The Z80 and which CPU has the bus
|
|
116
|
-
#
|
|
117
|
-
# to its CPU without resetting the 8502.
|
|
91
|
+
# The Z80 and which CPU has the bus. The bus, restored before it,
|
|
92
|
+
# hands the bus to its CPU without resetting the 8502.
|
|
118
93
|
def load_z80(input)
|
|
119
94
|
@z80_running = @bus.z80?
|
|
120
|
-
@z80_turn = @z80_running
|
|
121
|
-
@z80_due = @z80.cycles
|
|
122
|
-
@chips_ahead = 0
|
|
123
|
-
@cpu_reset_pending = false
|
|
124
|
-
return unless input.schema > 6
|
|
125
|
-
|
|
126
95
|
@z80.load_state(input)
|
|
127
96
|
@z80_due = input.int
|
|
128
97
|
@chips_ahead = input.int
|
|
@@ -130,11 +99,16 @@ module Badline
|
|
|
130
99
|
@z80_turn = @z80_running || @chips_ahead.positive?
|
|
131
100
|
end
|
|
132
101
|
|
|
102
|
+
# How this machine was built.
|
|
103
|
+
def snapshot_setup
|
|
104
|
+
Snapshot::C128Setup.new(model: @model.name, sid_model: @sid.model, mode: @c64_built ? :c64 : :c128)
|
|
105
|
+
end
|
|
106
|
+
|
|
133
107
|
def check_setup(setup)
|
|
134
|
-
ours =
|
|
108
|
+
ours = snapshot_setup
|
|
135
109
|
return if setup == ours
|
|
136
110
|
|
|
137
|
-
raise Snapshot::FormatError, "the state is of a #{setup
|
|
111
|
+
raise Snapshot::FormatError, "the state is of a #{setup}, not a #{ours}"
|
|
138
112
|
end
|
|
139
113
|
end
|
|
140
114
|
|
data/lib/badline/c128/z80.rb
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require "badline/z80/core"
|
|
3
|
+
require "badline/chips/z80/core"
|
|
4
4
|
|
|
5
5
|
module Badline
|
|
6
6
|
class C128
|
|
7
7
|
# The C128's Z80A, on the Z80's side of the C128::Bus.
|
|
8
8
|
class Z80
|
|
9
|
-
include Badline::Z80::Core
|
|
9
|
+
include Badline::Chips::Z80::Core
|
|
10
10
|
end
|
|
11
11
|
|
|
12
12
|
# The Z80's accesses, through the pages C128::Bus lays out for it
|
data/lib/badline/c128.rb
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
require "badline/c128/model"
|
|
4
4
|
require "badline/c128/mmu"
|
|
5
|
-
require "badline/
|
|
5
|
+
require "badline/chips/vdc"
|
|
6
6
|
require "badline/c128/mmu_pages"
|
|
7
7
|
require "badline/c128/io_pages"
|
|
8
8
|
require "badline/c128/z80_pages"
|
|
9
9
|
require "badline/c128/color_lines"
|
|
10
10
|
require "badline/c128/banks"
|
|
11
|
-
require "badline/c128/
|
|
11
|
+
require "badline/c128/bus/saved_state"
|
|
12
12
|
require "badline/c128/bus"
|
|
13
13
|
require "badline/c128/cpu"
|
|
14
14
|
require "badline/c128/z80"
|
|
@@ -18,7 +18,7 @@ require "badline/c128/keys"
|
|
|
18
18
|
require "badline/c128/modes"
|
|
19
19
|
require "badline/c128/drives"
|
|
20
20
|
require "badline/c128/fast_serial"
|
|
21
|
-
require "badline/
|
|
21
|
+
require "badline/drives/model1571"
|
|
22
22
|
|
|
23
23
|
module Badline
|
|
24
24
|
# The Commodore 128: the 8502 on the VIC-IIe's clock, two CIAs, the SID,
|
|
@@ -44,8 +44,10 @@ module Badline
|
|
|
44
44
|
class C128
|
|
45
45
|
include IntegerHelper
|
|
46
46
|
include KeyboardBuffer
|
|
47
|
-
include
|
|
48
|
-
include
|
|
47
|
+
include Machine::Clocking
|
|
48
|
+
include C64::Common
|
|
49
|
+
include C64::Attachments
|
|
50
|
+
include C64::KernalTraps
|
|
49
51
|
include Keys
|
|
50
52
|
include Modes
|
|
51
53
|
include Drives
|
|
@@ -54,7 +56,7 @@ module Badline
|
|
|
54
56
|
|
|
55
57
|
# The C64's 8x8 matrix and the three rows K0-K2 select, in port B
|
|
56
58
|
# column order.
|
|
57
|
-
KEYBOARD_MATRIX = (Keyboard::C64_MATRIX + [
|
|
59
|
+
KEYBOARD_MATRIX = (Input::Keyboard::C64_MATRIX + [
|
|
58
60
|
%i[help keypad8 keypad5 tab keypad2 keypad4 keypad7 keypad1],
|
|
59
61
|
%i[esc keypad_plus keypad_minus line_feed keypad_enter keypad6 keypad9 keypad3],
|
|
60
62
|
%i[alt keypad0 keypad_period crsr_up crsr_down crsr_left crsr_right no_scroll]
|
|
@@ -71,10 +73,6 @@ module Badline
|
|
|
71
73
|
|
|
72
74
|
attr_reader :cpu, :cycles, :drive1541, :model, :init_threshold
|
|
73
75
|
|
|
74
|
-
# The path of the disk or directory device 8 serves through the traps
|
|
75
|
-
# (Computer::Attachments), or an empty one.
|
|
76
|
-
def mounted_path = @drive.nil? ? "" : @drive.path
|
|
77
|
-
|
|
78
76
|
def family = :c128
|
|
79
77
|
|
|
80
78
|
def address_bus = @bus
|
|
@@ -95,6 +93,11 @@ module Badline
|
|
|
95
93
|
|
|
96
94
|
def ram = @bus.ram
|
|
97
95
|
|
|
96
|
+
# Reads and writes memory as the CPU sees it, through the bus.
|
|
97
|
+
def peek(addr) = @bus.peek(addr)
|
|
98
|
+
|
|
99
|
+
def poke(addr, value) = @bus.poke(addr, value)
|
|
100
|
+
|
|
98
101
|
def keyboard = @bus.keyboard
|
|
99
102
|
|
|
100
103
|
def joystick1 = @bus.joystick1
|
|
@@ -118,7 +121,7 @@ module Badline
|
|
|
118
121
|
|
|
119
122
|
@model = Model.named(model)
|
|
120
123
|
@c64_built = mode == :c64
|
|
121
|
-
@init_threshold = @c64_built ?
|
|
124
|
+
@init_threshold = @c64_built ? C64::INIT_THRESHOLD : C128_INIT_THRESHOLD
|
|
122
125
|
@holding_commodore = false
|
|
123
126
|
@bus = Bus.new(@model, sid_model: sid_model || @model.sid_model, mode:)
|
|
124
127
|
@cpu = CPU.new(@bus, debug:)
|
|
@@ -173,36 +176,6 @@ module Badline
|
|
|
173
176
|
@cycles += 1
|
|
174
177
|
end
|
|
175
178
|
|
|
176
|
-
# Runs `count` cycles, one #cycle! after another.
|
|
177
|
-
def run_cycles(count)
|
|
178
|
-
i = 0
|
|
179
|
-
while i < count
|
|
180
|
-
cycle!
|
|
181
|
-
i += 1
|
|
182
|
-
end
|
|
183
|
-
end
|
|
184
|
-
|
|
185
|
-
# Runs cycles until the block returns true or the cycle count passes
|
|
186
|
-
# `limit`, checking before each cycle.
|
|
187
|
-
def run_until(limit)
|
|
188
|
-
cycle! until yield || @cycles > limit
|
|
189
|
-
end
|
|
190
|
-
|
|
191
|
-
def on_init(&block)
|
|
192
|
-
if @cycles < init_threshold
|
|
193
|
-
@init_handlers << block
|
|
194
|
-
else
|
|
195
|
-
block.call
|
|
196
|
-
end
|
|
197
|
-
end
|
|
198
|
-
|
|
199
|
-
# The clock, the raster and the crop of the VIC-IIe's region.
|
|
200
|
-
def timing
|
|
201
|
-
region = @bus.region
|
|
202
|
-
Timing.new(clock_hz: region.clock_hz, cycles_per_line: region.cycles_per_line,
|
|
203
|
-
lines_per_frame: region.lines_per_frame, crop: region.crop, pixel_width: 1)
|
|
204
|
-
end
|
|
205
|
-
|
|
206
179
|
# The chip whose #display a front end shows: the VIC-IIe, or with
|
|
207
180
|
# :vdc the VDC, whose display paints only while its #render is on.
|
|
208
181
|
def video(chip = :vic) = chip == :vdc ? @vdc : @vic
|
|
@@ -217,12 +190,6 @@ module Badline
|
|
|
217
190
|
# The chip a front end records the machine's sound from.
|
|
218
191
|
def sound_source = @sid
|
|
219
192
|
|
|
220
|
-
def load_prg(data)
|
|
221
|
-
uint16(data[0], data[1]).tap do |load_addr|
|
|
222
|
-
ram.write(load_addr, data[2..])
|
|
223
|
-
end
|
|
224
|
-
end
|
|
225
|
-
|
|
226
193
|
# A cartridge goes in with the power off.
|
|
227
194
|
def attach_cartridge(cartridge)
|
|
228
195
|
connect_cartridge(cartridge)
|
|
@@ -247,7 +214,7 @@ module Badline
|
|
|
247
214
|
@cia2.reset!
|
|
248
215
|
@sid.reset!
|
|
249
216
|
@bus.cartridge&.reset
|
|
250
|
-
@
|
|
217
|
+
@dos&.reset!
|
|
251
218
|
@drive1541&.reset!
|
|
252
219
|
@drive1571&.reset!
|
|
253
220
|
@drive1581&.reset!
|
|
@@ -255,19 +222,11 @@ module Badline
|
|
|
255
222
|
reset_z80
|
|
256
223
|
end
|
|
257
224
|
|
|
258
|
-
# CHROUT is at $FFD2 in both KERNALs, and the trap follows the mode.
|
|
259
|
-
def capture_output
|
|
260
|
-
@capture_output ||= ChroutTrap.new(cpu:, bus: @bus, layout: trap_layout).tap do |trap|
|
|
261
|
-
cpu.install_trap(ChroutTrap::ADDRESS) { trap.call }
|
|
262
|
-
end
|
|
263
|
-
end
|
|
264
|
-
|
|
265
|
-
def inspect
|
|
266
|
-
"#<#{self.class.name} cycles=#{@cycles} cpu=(#{@cpu.inspect})>"
|
|
267
|
-
end
|
|
268
|
-
|
|
269
225
|
private
|
|
270
226
|
|
|
227
|
+
# The bus the KERNAL traps read and write through.
|
|
228
|
+
def trap_bus = @bus
|
|
229
|
+
|
|
271
230
|
# The C128 KERNAL leaves $D02F at $FF, every extra keyboard row
|
|
272
231
|
# deselected, before it jumps to the C64's reset.
|
|
273
232
|
def enter_c64_mode
|
|
@@ -275,15 +234,6 @@ module Badline
|
|
|
275
234
|
@bus.control_ports.extra_rows = 0xff
|
|
276
235
|
end
|
|
277
236
|
|
|
278
|
-
# The NMI line is wired-OR between CIA 2, the cartridge and RESTORE,
|
|
279
|
-
# and the CPU takes an interrupt on its falling edge.
|
|
280
|
-
def drive_nmi
|
|
281
|
-
nmi = @cia2.interrupted? || @cartridge_nmi || @restore_pulse
|
|
282
|
-
@restore_pulse = false
|
|
283
|
-
@cpu.nmi = true if nmi && !@nmi_asserted
|
|
284
|
-
@nmi_asserted = nmi
|
|
285
|
-
end
|
|
286
|
-
|
|
287
237
|
# BA halts the CPU on a read cycle.
|
|
288
238
|
def clock_cpu
|
|
289
239
|
@cpu.pending_write? || !@vic.ba_low? ? @cpu.cycle! : @cpu.stall!
|
|
@@ -311,9 +261,5 @@ module Badline
|
|
|
311
261
|
@cpu.cycle!
|
|
312
262
|
@vic.take_cpu_bus(phi1, @bus.data, @bus.vic_access?)
|
|
313
263
|
end
|
|
314
|
-
|
|
315
|
-
def handle_init
|
|
316
|
-
@init_handlers.each(&:call)
|
|
317
|
-
end
|
|
318
264
|
end
|
|
319
265
|
end
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Badline
|
|
4
|
-
class
|
|
5
|
-
# What plugs into the machine besides its chips, the cartridge,
|
|
6
|
-
#
|
|
7
|
-
#
|
|
4
|
+
class C64
|
|
5
|
+
# What plugs into the machine besides its chips, the cartridge, its
|
|
6
|
+
# true drives (TrueDrives) and an REU, and their state for a snapshot.
|
|
7
|
+
# The disk device 8 serves through the traps is KernalTraps'.
|
|
8
8
|
module Attachments
|
|
9
9
|
include TrueDrives
|
|
10
10
|
|
|
@@ -17,30 +17,6 @@ module Badline
|
|
|
17
17
|
address_bus.attach_cartridge(cartridge)
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
# Puts the storage in device 8. Mounting again swaps the disk at any
|
|
21
|
-
# point while the machine runs: the drive keeps its RAM, which only a
|
|
22
|
-
# drive reset clears, and its status. The traps go on the KERNAL the
|
|
23
|
-
# machine runs (#trap_layout).
|
|
24
|
-
def mount(storage)
|
|
25
|
-
return @drive.insert(storage) if @drive
|
|
26
|
-
|
|
27
|
-
@drive = KernalTrap::Drive.new(storage)
|
|
28
|
-
install_kernal_traps(trap_layout)
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# Takes device 8's mounted storage out, and with it the LOAD, SAVE and
|
|
32
|
-
# serial traps, so the KERNAL's routines go out over the serial bus.
|
|
33
|
-
# Mounting again starts a new drive, with its RAM cleared.
|
|
34
|
-
def unmount
|
|
35
|
-
return unless @drive
|
|
36
|
-
|
|
37
|
-
remove_kernal_traps
|
|
38
|
-
@drive = nil
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# Whether device 8 serves a disk or directory through the traps.
|
|
42
|
-
def mounted? = !@drive.nil?
|
|
43
|
-
|
|
44
20
|
# The serial bus, which CIA 2's port A drives through the C64's own
|
|
45
21
|
# inverters and reads back on PA6 and PA7, with or without a drive on
|
|
46
22
|
# it.
|
|
@@ -51,7 +27,7 @@ module Badline
|
|
|
51
27
|
# CIA 2's port A drives the serial bus, which reads CLK and DATA back
|
|
52
28
|
# into it.
|
|
53
29
|
def plug_serial_bus
|
|
54
|
-
@iec_bus =
|
|
30
|
+
@iec_bus = Drives::SerialBus.new
|
|
55
31
|
@cia2.peripheral = @iec_bus
|
|
56
32
|
@cia2.on_port_a_write { push_serial_lines }
|
|
57
33
|
push_serial_lines
|
|
@@ -78,26 +54,19 @@ module Badline
|
|
|
78
54
|
end
|
|
79
55
|
end
|
|
80
56
|
|
|
81
|
-
#
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
@save_trap.save_state(out)
|
|
57
|
+
# A true 1541 on the serial bus, then a 1581.
|
|
58
|
+
def save_serial_bus(out)
|
|
59
|
+
out.boolean(!@drive1541.nil?)
|
|
60
|
+
if @drive1541
|
|
61
|
+
out.int(@drive1541.device)
|
|
62
|
+
@drive1541.save_state(out)
|
|
63
|
+
end
|
|
64
|
+
save_drive1581(out)
|
|
90
65
|
end
|
|
91
66
|
|
|
92
|
-
def
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
storage = Storage.reopen(input)
|
|
96
|
-
unmount
|
|
97
|
-
mount(storage)
|
|
98
|
-
@drive.load_state(input)
|
|
99
|
-
@serial_trap.load_state(input)
|
|
100
|
-
@save_trap.load_state(input)
|
|
67
|
+
def load_serial_bus(input)
|
|
68
|
+
load_drive1541(input)
|
|
69
|
+
load_drive1581(input)
|
|
101
70
|
end
|
|
102
71
|
|
|
103
72
|
# The REU, which the setup says the machine has, and whether it has
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class C64
|
|
5
|
+
module BankedRAM
|
|
6
|
+
# The register and page mapping the expansions share. #map lays the
|
|
7
|
+
# selected banks out in the address bus's page tables, and #map_io puts
|
|
8
|
+
# the register over the VIC's I/O page at $D100.
|
|
9
|
+
module Banking
|
|
10
|
+
attr_reader :low_ram, :high_ram, :video_ram
|
|
11
|
+
|
|
12
|
+
# The block runs whenever the register moves a bank.
|
|
13
|
+
def on_change(&block)
|
|
14
|
+
@on_change = block
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def peek(_addr) = 0xff
|
|
18
|
+
|
|
19
|
+
def map(read_pages, write_pages)
|
|
20
|
+
[read_pages, write_pages].each do |pages|
|
|
21
|
+
pages.fill(@low_ram, 0x00, 0x10)
|
|
22
|
+
pages.fill(@high_ram, 0x10, 0xf0)
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def map_io(read_pages, write_pages)
|
|
27
|
+
read_pages[0xd1] = write_pages[0xd1] = self
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class C64
|
|
5
|
+
module BankedRAM
|
|
6
|
+
# The +256K: four 64K banks, the first of them the machine's own RAM.
|
|
7
|
+
# $D100 picks one for $0000-$0FFF (bits 0-1), one for the VIC (bits 2-3)
|
|
8
|
+
# and one for $1000-$FFFF (bits 6-7). Setting bit 4 locks the register
|
|
9
|
+
# until the next reset.
|
|
10
|
+
class Plus256k
|
|
11
|
+
include Banking
|
|
12
|
+
|
|
13
|
+
def initialize(ram)
|
|
14
|
+
@banks = [ram, Memory.new, Memory.new, Memory.new]
|
|
15
|
+
@on_change = nil
|
|
16
|
+
reset!
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def poke(_addr, value)
|
|
20
|
+
return if @locked
|
|
21
|
+
|
|
22
|
+
@low_ram = @banks[value & 0b11]
|
|
23
|
+
@video_ram = @banks[(value >> 2) & 0b11]
|
|
24
|
+
@high_ram = @banks[value >> 6]
|
|
25
|
+
@locked = value.anybits?(0x10)
|
|
26
|
+
@on_change&.call
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def reset!
|
|
30
|
+
@low_ram = @video_ram = @high_ram = @banks[0]
|
|
31
|
+
@locked = false
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def type = :plus256k
|
|
35
|
+
|
|
36
|
+
def save_state(out)
|
|
37
|
+
[@low_ram, @video_ram, @high_ram].each { |bank| out.int(@banks.index(bank)) }
|
|
38
|
+
out.boolean(@locked)
|
|
39
|
+
@banks.drop(1).each { |bank| bank.save_state(out) }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def load_state(input)
|
|
43
|
+
@low_ram = @banks.fetch(input.int)
|
|
44
|
+
@video_ram = @banks.fetch(input.int)
|
|
45
|
+
@high_ram = @banks.fetch(input.int)
|
|
46
|
+
@locked = input.boolean?
|
|
47
|
+
@banks.drop(1).each { |bank| bank.load_state(input) }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def power_on!
|
|
51
|
+
@banks.drop(1).each(&:clear!)
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class C64
|
|
5
|
+
module BankedRAM
|
|
6
|
+
# The +60K: a second bank of RAM behind $1000-$FFFF, selected by bit 7
|
|
7
|
+
# of $D100. $0000-$0FFF stays the machine's own RAM, and so does all of
|
|
8
|
+
# what the VIC sees.
|
|
9
|
+
class Plus60k
|
|
10
|
+
include Banking
|
|
11
|
+
|
|
12
|
+
def initialize(ram)
|
|
13
|
+
@low_ram = @video_ram = @high_ram = ram
|
|
14
|
+
@banks = [ram, Memory.new]
|
|
15
|
+
@on_change = nil
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def poke(_addr, value)
|
|
19
|
+
@high_ram = @banks[value >> 7]
|
|
20
|
+
@on_change&.call
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def reset!
|
|
24
|
+
@high_ram = @banks[0]
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def type = :plus60k
|
|
28
|
+
|
|
29
|
+
def save_state(out)
|
|
30
|
+
out.int(@banks.index(@high_ram))
|
|
31
|
+
@banks[1].save_state(out)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def load_state(input)
|
|
35
|
+
@high_ram = @banks.fetch(input.int)
|
|
36
|
+
@banks[1].load_state(input)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def power_on!
|
|
40
|
+
@banks[1].clear!
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class C64
|
|
5
|
+
module BankedRAM
|
|
6
|
+
# The machine with no expansion fitted: its own RAM everywhere, and
|
|
7
|
+
# $D100 left to the VIC.
|
|
8
|
+
class Unexpanded
|
|
9
|
+
include Banking
|
|
10
|
+
|
|
11
|
+
def initialize(ram)
|
|
12
|
+
@low_ram = @video_ram = @high_ram = ram
|
|
13
|
+
@on_change = nil
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def type = nil
|
|
17
|
+
|
|
18
|
+
def map_io(_read_pages, _write_pages); end
|
|
19
|
+
|
|
20
|
+
def save_state(_out); end
|
|
21
|
+
|
|
22
|
+
def load_state(_input); end
|
|
23
|
+
|
|
24
|
+
def reset!; end
|
|
25
|
+
|
|
26
|
+
def power_on!; end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "badline/c64/banked_ram/banking"
|
|
4
|
+
require "badline/c64/banked_ram/unexpanded"
|
|
5
|
+
require "badline/c64/banked_ram/plus60k"
|
|
6
|
+
require "badline/c64/banked_ram/plus256k"
|
|
7
|
+
|
|
8
|
+
module Badline
|
|
9
|
+
class C64
|
|
10
|
+
# RAM expansions that bank extra memory in under the CPU through a
|
|
11
|
+
# register at $D100, in the VIC's I/O page. Any write to $D100-$D1FF
|
|
12
|
+
# sets the register, which reads back as $FF.
|
|
13
|
+
module BankedRAM
|
|
14
|
+
TYPES = { plus60k: Plus60k, plus256k: Plus256k }.freeze
|
|
15
|
+
|
|
16
|
+
def self.build(type, ram, &)
|
|
17
|
+
expansion = type ? TYPES.fetch(type).new(ram) : Unexpanded.new(ram)
|
|
18
|
+
expansion.on_change(&)
|
|
19
|
+
expansion
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class C64
|
|
5
|
+
class Bus
|
|
6
|
+
# The second and third SIDs the SID player fits for a tune written for
|
|
7
|
+
# them, each over its 32 bytes of the I/O area (SIDSlots). The SID
|
|
8
|
+
# player's machine has nothing else in I/O 1 and 2, so the rest of a
|
|
9
|
+
# page there reads the open bus.
|
|
10
|
+
module ExtraSIDs
|
|
11
|
+
# Fits a SID at the address it was built at, where it takes its 32
|
|
12
|
+
# bytes over from whatever maps there.
|
|
13
|
+
def add_sid(sid)
|
|
14
|
+
page = sid.start >> 8
|
|
15
|
+
slots = @sid_slots.find { |candidate| candidate.page == page }
|
|
16
|
+
if slots.nil?
|
|
17
|
+
slots = SIDSlots.new(page, @sid, @open_bus)
|
|
18
|
+
@sid_slots << slots
|
|
19
|
+
end
|
|
20
|
+
slots.place(sid)
|
|
21
|
+
update_overlays!
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
private
|
|
25
|
+
|
|
26
|
+
def map_extra_sids
|
|
27
|
+
@sid_slots.each { |slots| @read_pages[slots.page] = @write_pages[slots.page] = slots }
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class C64
|
|
5
|
+
class Bus
|
|
6
|
+
# What a model fits around the chips: its KERNAL, a datasette or none,
|
|
7
|
+
# and the board and case they sit in.
|
|
8
|
+
module Fittings
|
|
9
|
+
# The keywords #fit takes.
|
|
10
|
+
NAMES = %i[kernal datasette board].freeze
|
|
11
|
+
|
|
12
|
+
# The C64's board and case, the PET 64's, whose built-in monitor
|
|
13
|
+
# shows the VIC's output in shades of green, the C64GS's, which has
|
|
14
|
+
# no keyboard, or the MAX Machine's (:max): 2K of RAM, no ROMs, CIA 1
|
|
15
|
+
# alone at $DC00-$DFFF and the cartridge port in Ultimax mode.
|
|
16
|
+
BOARDS = %i[c64 pet64 gs max].freeze
|
|
17
|
+
|
|
18
|
+
attr_reader :board
|
|
19
|
+
|
|
20
|
+
# Fits the KERNAL ROM ROMs::KERNALS names, leaves the cassette port
|
|
21
|
+
# empty unless `datasette`, and puts the chips in the board BOARDS
|
|
22
|
+
# names.
|
|
23
|
+
def fit(kernal: :c64, datasette: true, board: :c64)
|
|
24
|
+
self.kernal = kernal unless kernal == :c64
|
|
25
|
+
@datasette.disconnect! unless datasette
|
|
26
|
+
self.board = board unless board == :c64
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def board=(name)
|
|
30
|
+
raise ArgumentError, "no board named #{name}" unless BOARDS.include?(name)
|
|
31
|
+
|
|
32
|
+
@board = name
|
|
33
|
+
vic.palette = name == :pet64 ? Chips::VIC::GREEN_PALETTE : Chips::VIC::PALETTE
|
|
34
|
+
keyboard.connected = name != :gs
|
|
35
|
+
update_overlays!
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|