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/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,
|
|
@@ -45,9 +45,9 @@ module Badline
|
|
|
45
45
|
include IntegerHelper
|
|
46
46
|
include KeyboardBuffer
|
|
47
47
|
include Machine::Clocking
|
|
48
|
-
include
|
|
49
|
-
include
|
|
50
|
-
include
|
|
48
|
+
include C64::Common
|
|
49
|
+
include C64::Attachments
|
|
50
|
+
include C64::KernalTraps
|
|
51
51
|
include Keys
|
|
52
52
|
include Modes
|
|
53
53
|
include Drives
|
|
@@ -56,7 +56,7 @@ module Badline
|
|
|
56
56
|
|
|
57
57
|
# The C64's 8x8 matrix and the three rows K0-K2 select, in port B
|
|
58
58
|
# column order.
|
|
59
|
-
KEYBOARD_MATRIX = (Keyboard::C64_MATRIX + [
|
|
59
|
+
KEYBOARD_MATRIX = (Input::Keyboard::C64_MATRIX + [
|
|
60
60
|
%i[help keypad8 keypad5 tab keypad2 keypad4 keypad7 keypad1],
|
|
61
61
|
%i[esc keypad_plus keypad_minus line_feed keypad_enter keypad6 keypad9 keypad3],
|
|
62
62
|
%i[alt keypad0 keypad_period crsr_up crsr_down crsr_left crsr_right no_scroll]
|
|
@@ -93,6 +93,11 @@ module Badline
|
|
|
93
93
|
|
|
94
94
|
def ram = @bus.ram
|
|
95
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
|
+
|
|
96
101
|
def keyboard = @bus.keyboard
|
|
97
102
|
|
|
98
103
|
def joystick1 = @bus.joystick1
|
|
@@ -116,7 +121,7 @@ module Badline
|
|
|
116
121
|
|
|
117
122
|
@model = Model.named(model)
|
|
118
123
|
@c64_built = mode == :c64
|
|
119
|
-
@init_threshold = @c64_built ?
|
|
124
|
+
@init_threshold = @c64_built ? C64::INIT_THRESHOLD : C128_INIT_THRESHOLD
|
|
120
125
|
@holding_commodore = false
|
|
121
126
|
@bus = Bus.new(@model, sid_model: sid_model || @model.sid_model, mode:)
|
|
122
127
|
@cpu = CPU.new(@bus, debug:)
|
|
@@ -209,7 +214,7 @@ module Badline
|
|
|
209
214
|
@cia2.reset!
|
|
210
215
|
@sid.reset!
|
|
211
216
|
@bus.cartridge&.reset
|
|
212
|
-
@
|
|
217
|
+
@dos&.reset!
|
|
213
218
|
@drive1541&.reset!
|
|
214
219
|
@drive1571&.reset!
|
|
215
220
|
@drive1581&.reset!
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
module Badline
|
|
4
|
-
class
|
|
4
|
+
class C64
|
|
5
5
|
# What plugs into the machine besides its chips, the cartridge, its
|
|
6
6
|
# true drives (TrueDrives) and an REU, and their state for a snapshot.
|
|
7
7
|
# The disk device 8 serves through the traps is KernalTraps'.
|
|
@@ -27,7 +27,7 @@ module Badline
|
|
|
27
27
|
# CIA 2's port A drives the serial bus, which reads CLK and DATA back
|
|
28
28
|
# into it.
|
|
29
29
|
def plug_serial_bus
|
|
30
|
-
@iec_bus =
|
|
30
|
+
@iec_bus = Drives::SerialBus.new
|
|
31
31
|
@cia2.peripheral = @iec_bus
|
|
32
32
|
@cia2.on_port_a_write { push_serial_lines }
|
|
33
33
|
push_serial_lines
|
|
@@ -54,10 +54,9 @@ module Badline
|
|
|
54
54
|
end
|
|
55
55
|
end
|
|
56
56
|
|
|
57
|
-
# A true 1541 on the serial bus, then a 1581.
|
|
58
|
-
# bus itself, which every machine now has.
|
|
57
|
+
# A true 1541 on the serial bus, then a 1581.
|
|
59
58
|
def save_serial_bus(out)
|
|
60
|
-
out.boolean(
|
|
59
|
+
out.boolean(!@drive1541.nil?)
|
|
61
60
|
if @drive1541
|
|
62
61
|
out.int(@drive1541.device)
|
|
63
62
|
@drive1541.save_state(out)
|
|
@@ -66,7 +65,6 @@ module Badline
|
|
|
66
65
|
end
|
|
67
66
|
|
|
68
67
|
def load_serial_bus(input)
|
|
69
|
-
input.boolean?
|
|
70
68
|
load_drive1541(input)
|
|
71
69
|
load_drive1581(input)
|
|
72
70
|
end
|
|
@@ -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
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class C64
|
|
5
|
+
class Bus
|
|
6
|
+
# The C64's PLA: what each page of the CPU's view maps to, from the
|
|
7
|
+
# CPU port's LORAM, HIRAM and CHAREN lines and the cartridge's EXROM
|
|
8
|
+
# and GAME. The bus that includes it supplies the page tables, the
|
|
9
|
+
# ROMs, the chips, #map_ram_pages, which lays out the RAM that the
|
|
10
|
+
# ROMs, the cartridge and I/O map over, and #map_io_pages, which lays
|
|
11
|
+
# out the chips at $D000-$DFFF, with #map_cartridge_io for I/O 1 and 2.
|
|
12
|
+
module PLA
|
|
13
|
+
# A chip's registers seen at another page, which reads and writes
|
|
14
|
+
# them as at the page the chip starts at.
|
|
15
|
+
class Mirror
|
|
16
|
+
def initialize(chip, start)
|
|
17
|
+
@chip = chip
|
|
18
|
+
@start = start
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def peek(addr) = @chip.peek(@start | (addr & 0xff))
|
|
22
|
+
def poke(addr, value) = @chip.poke(@start | (addr & 0xff), value)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def map_pla_pages
|
|
28
|
+
map_ram_pages
|
|
29
|
+
@ultimax ? map_ultimax_pages : map_banked_pages
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def map_banked_pages
|
|
33
|
+
map_rom_overlays
|
|
34
|
+
map_cartridge_ram
|
|
35
|
+
@write_pages.fill(@cartridge.romh_writes, 0xe0, 0x20) if @cartridge&.romh_writes
|
|
36
|
+
|
|
37
|
+
if io?
|
|
38
|
+
map_io_pages
|
|
39
|
+
elsif character?
|
|
40
|
+
@read_pages.fill(character_rom, 0xd0, 0x10)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# Ultimax mode ignores the $01 lines: 4K of RAM, ROML/ROMH windows,
|
|
45
|
+
# I/O always visible and open address space everywhere else. The ROML
|
|
46
|
+
# and ROMH selects fire on writes as well, so cartridge RAM or flash in
|
|
47
|
+
# either window takes the writes there. The MAX has 2K of RAM, and is
|
|
48
|
+
# in Ultimax mode with no cartridge too.
|
|
49
|
+
def map_ultimax_pages
|
|
50
|
+
first = @board == :max ? 0x08 : 0x10
|
|
51
|
+
@read_pages.fill(@open_bus, first, 0x100 - first)
|
|
52
|
+
@write_pages.fill(@open_bus, first, 0x100 - first)
|
|
53
|
+
map_ultimax_cartridge if @cartridge
|
|
54
|
+
map_io_pages
|
|
55
|
+
map_max_io if @board == :max
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def map_ultimax_cartridge
|
|
59
|
+
@read_pages.fill(@cartridge.roml, 0x80, 0x20) if @cartridge.roml
|
|
60
|
+
map_ultimax_writes(@cartridge.roml, 0x80)
|
|
61
|
+
@read_pages.fill(@cartridge.romh, 0xe0, 0x20) if @cartridge.romh
|
|
62
|
+
map_ultimax_writes(@cartridge.romh, 0xe0)
|
|
63
|
+
map_ultimax_a000
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def map_ultimax_writes(bank, first_page)
|
|
67
|
+
@write_pages.fill(bank, first_page, 0x20) if bank.respond_to?(:poke)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def map_ultimax_a000
|
|
71
|
+
return unless (window = @cartridge.ultimax_a000)
|
|
72
|
+
|
|
73
|
+
@read_pages.fill(window, 0xa0, 0x20)
|
|
74
|
+
@write_pages.fill(window, 0xa0, 0x20)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# The MAX has no CIA 2 and no I/O 2: CIA 1 answers all through
|
|
78
|
+
# $DC00-$DFFF, but for the I/O 1 page a cartridge takes.
|
|
79
|
+
def map_max_io
|
|
80
|
+
@cia1_mirror ||= Mirror.new(cia1, 0xdc00)
|
|
81
|
+
(0xdd..0xdf).each { |page| @read_pages[page] = @write_pages[page] = @cia1_mirror }
|
|
82
|
+
return unless @cartridge
|
|
83
|
+
|
|
84
|
+
@write_pages[0xde] = @cartridge
|
|
85
|
+
@read_pages[0xde] = @cartridge if @cartridge.readable_io_pages.include?(0xde)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# EXROM and GAME select the cartridge whether or not it has a chip
|
|
89
|
+
# there, and an empty socket leaves the bus floating.
|
|
90
|
+
def map_rom_overlays
|
|
91
|
+
@read_pages.fill(@cartridge.roml || @open_bus, 0x80, 0x20) if roml?
|
|
92
|
+
if romh?
|
|
93
|
+
@read_pages.fill(@cartridge.romh || @open_bus, 0xa0, 0x20)
|
|
94
|
+
elsif basic?
|
|
95
|
+
@read_pages.fill(basic_rom, 0xa0, 0x20)
|
|
96
|
+
end
|
|
97
|
+
@read_pages.fill(kernal_rom, 0xe0, 0x20) if kernal?
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# Cartridge RAM in the ROML or ROMH window decodes writes itself,
|
|
101
|
+
# whatever the $01 lines say.
|
|
102
|
+
def map_cartridge_ram
|
|
103
|
+
return unless @cartridge&.exrom&.zero?
|
|
104
|
+
|
|
105
|
+
map_cartridge_ram_bank(@cartridge.roml, 0x80)
|
|
106
|
+
map_cartridge_ram_bank(@cartridge.romh, 0xa0) if @cartridge.game.zero?
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def map_cartridge_ram_bank(bank, first_page)
|
|
110
|
+
@write_pages.fill(bank, first_page, 0x20) if bank.is_a?(Cartridge::RAMBank)
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def map_cartridge_io
|
|
114
|
+
@write_pages.fill(@cartridge, 0xde, 2)
|
|
115
|
+
@cartridge.readable_io_pages.each { |p| @read_pages[p] = @cartridge }
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def basic?
|
|
119
|
+
io_port.kernal? && io_port.basic? && game_high?
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def game_high?
|
|
123
|
+
@cartridge.nil? || @cartridge.game == 1
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def roml?
|
|
127
|
+
@cartridge&.exrom&.zero? && io_port.kernal? && io_port.basic?
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def romh?
|
|
131
|
+
@cartridge&.exrom&.zero? && @cartridge.game.zero? && io_port.kernal?
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# In 16K mode LORAM alone leaves $d000 as RAM, where it still maps I/O.
|
|
135
|
+
def character?
|
|
136
|
+
(io_port.kernal? || (io_port.basic? && game_high?)) && !io_port.io?
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def io?
|
|
140
|
+
(io_port.basic? || io_port.kernal?) && io_port.io?
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def kernal?
|
|
144
|
+
io_port.kernal?
|
|
145
|
+
end
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class C64
|
|
5
|
+
class Bus
|
|
6
|
+
# The BASIC, character and KERNAL ROMs, and which KERNAL is fitted.
|
|
7
|
+
module ROMs
|
|
8
|
+
# The KERNAL ROMs a machine can be fitted with, by name: the C64's,
|
|
9
|
+
# the SX-64's, the PET 64's and the C64GS's. The C64GS's is a 16K
|
|
10
|
+
# image of its BASIC and its KERNAL, and fits both.
|
|
11
|
+
KERNALS = {
|
|
12
|
+
c64: "kernal.rom", sx64: "kernal-sx64.rom", pet64: "kernal-pet64.rom", gs: "c64gs.rom"
|
|
13
|
+
}.freeze
|
|
14
|
+
|
|
15
|
+
attr_reader :basic_rom, :character_rom, :kernal_rom, :kernal
|
|
16
|
+
|
|
17
|
+
# Fits the KERNAL ROM KERNALS names `name`, in place of the one before,
|
|
18
|
+
# with the BASIC of a 16K image or else the C64's.
|
|
19
|
+
def kernal=(name)
|
|
20
|
+
raise ArgumentError, "no KERNAL named #{name}" unless KERNALS.key?(name)
|
|
21
|
+
|
|
22
|
+
@kernal = name
|
|
23
|
+
data = ROM.read(KERNALS[name])
|
|
24
|
+
basic = data.length == 0x4000 ? data[0, 0x2000] : ROM.read("basic.rom")
|
|
25
|
+
@basic_rom = ROM.new(basic, length: 0x2000, start: 0xa000)
|
|
26
|
+
@kernal_rom = ROM.new(data[-0x2000, 0x2000], length: 0x2000, start: 0xe000)
|
|
27
|
+
update_overlays!
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def load_roms
|
|
33
|
+
@basic_rom = ROM.load("basic.rom", 0xa000)
|
|
34
|
+
@character_rom = ROM.load("character.rom", 0xd000)
|
|
35
|
+
@kernal = :c64
|
|
36
|
+
@kernal_rom = ROM.load(KERNALS[:c64], 0xe000)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class C64
|
|
5
|
+
class Bus
|
|
6
|
+
# The bus's state for a snapshot: the CPU port, the RAM, colour RAM and
|
|
7
|
+
# a RAM expansion, the cartridge, the datasette and the chips.
|
|
8
|
+
module SavedState
|
|
9
|
+
# The RAM expansion fitted, or an Unexpanded stand-in.
|
|
10
|
+
attr_reader :ram_expansion
|
|
11
|
+
|
|
12
|
+
# Takes the cartridge out of the expansion port, as a restore does for
|
|
13
|
+
# a state without one.
|
|
14
|
+
def detach_cartridge
|
|
15
|
+
@cartridge = nil
|
|
16
|
+
update_overlays!
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# The 6510 port's direction and output registers, and the charge left
|
|
20
|
+
# on its floating bits.
|
|
21
|
+
def port_state = [@cpu_port.ddr, @cpu_port.data, @cpu_port.floating]
|
|
22
|
+
|
|
23
|
+
# Sets the port as port_state reads it, as a snapshot restores it,
|
|
24
|
+
# leaving the RAM under $00 and $01 alone.
|
|
25
|
+
def restore_port(ddr, out, floating)
|
|
26
|
+
@cpu_port.restore(ddr, out, floating)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# The machine's memory and everything on the bus but the keyboard, the
|
|
30
|
+
# joysticks and the pot devices, which the host holds. A cartridge is
|
|
31
|
+
# already in the port, built from its setup (C64#load_state).
|
|
32
|
+
def save_state(out)
|
|
33
|
+
out.marker("BUS")
|
|
34
|
+
out.int(@cpu_port.ddr).int(@cpu_port.data).int(@cpu_port.floating)
|
|
35
|
+
@ram.save_state(out)
|
|
36
|
+
@color_ram.save_state(out)
|
|
37
|
+
@ram_expansion.save_state(out)
|
|
38
|
+
@cartridge&.save_state(out)
|
|
39
|
+
@datasette.save_state(out)
|
|
40
|
+
@vic.save_state(out)
|
|
41
|
+
@cia1.save_state(out)
|
|
42
|
+
@cia2.save_state(out)
|
|
43
|
+
@sid.save_state(out)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def load_state(input)
|
|
47
|
+
input.marker("BUS")
|
|
48
|
+
ddr = input.int
|
|
49
|
+
port_out = input.int
|
|
50
|
+
floating = input.int
|
|
51
|
+
@ram.load_state(input)
|
|
52
|
+
@color_ram.load_state(input)
|
|
53
|
+
@ram_expansion.load_state(input)
|
|
54
|
+
@cartridge&.load_state(input)
|
|
55
|
+
@datasette.load_state(input)
|
|
56
|
+
@cpu_port.load(ddr, port_out, floating)
|
|
57
|
+
update_overlays!
|
|
58
|
+
@vic.load_state(input)
|
|
59
|
+
@cia1.load_state(input)
|
|
60
|
+
@cia2.load_state(input)
|
|
61
|
+
@sid.load_state(input)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
include SavedState
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class C64
|
|
5
|
+
class Bus
|
|
6
|
+
# Stands in for a page of I/O that a second or third SID shares: each 32
|
|
7
|
+
# bytes of it go to the SID placed there, or else to the first SID's
|
|
8
|
+
# mirrors in `$d400-$d7ff`, and to the open bus in I/O 1 and 2.
|
|
9
|
+
class SIDSlots
|
|
10
|
+
attr_reader :page
|
|
11
|
+
|
|
12
|
+
def initialize(page, first, open_bus)
|
|
13
|
+
@page = page
|
|
14
|
+
@io = page >= 0xde
|
|
15
|
+
@first = first
|
|
16
|
+
@open_bus = open_bus
|
|
17
|
+
@sids = []
|
|
18
|
+
@slots = Array.new(8, -1)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def place(sid)
|
|
22
|
+
@slots[(sid.start >> 5) & 7] = @sids.size
|
|
23
|
+
@sids << sid
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def peek(addr)
|
|
27
|
+
index = @slots[(addr >> 5) & 7]
|
|
28
|
+
return @sids[index].peek(addr) unless index.negative?
|
|
29
|
+
|
|
30
|
+
@io ? @open_bus.peek(addr) : @first.peek(addr)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def poke(addr, value)
|
|
34
|
+
index = @slots[(addr >> 5) & 7]
|
|
35
|
+
if !index.negative?
|
|
36
|
+
@sids[index].poke(addr, value)
|
|
37
|
+
elsif !@io
|
|
38
|
+
@first.poke(addr, value)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|