badline 0.12.1 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +66 -1
- data/CLAUDE.md +86 -38
- data/CONTRIBUTING.md +4 -3
- data/README.md +9 -6
- data/doc/library.md +9 -9
- data/doc/media.md +2 -1
- data/doc/pinned-behaviour.md +134 -105
- data/doc/snapshot-format.md +1047 -0
- data/doc/snapshots.md +73 -43
- data/lib/badline/audio/bare_player.rb +53 -20
- data/lib/badline/audio/cli.rb +6 -6
- data/lib/badline/audio/jukebox.rb +2 -2
- data/lib/badline/audio/machine_player.rb +16 -10
- data/lib/badline/{media → audio}/queue.rb +1 -1
- data/lib/badline/audio/queued_tune.rb +6 -6
- data/lib/badline/audio/renderer.rb +33 -22
- data/lib/badline/audio/stereo.rb +1 -1
- data/lib/badline/c128/banks.rb +6 -3
- data/lib/badline/c128/bus/keyed_state.rb +45 -0
- data/lib/badline/c128/bus.rb +35 -20
- data/lib/badline/c128/color_lines.rb +2 -2
- data/lib/badline/c128/cpu.rb +1 -1
- data/lib/badline/c128/drives.rb +14 -34
- data/lib/badline/c128/fast_serial.rb +5 -5
- data/lib/badline/c128/keyed_modules.rb +117 -0
- data/lib/badline/c128/keyed_state.rb +91 -0
- data/lib/badline/c128/keys.rb +9 -0
- data/lib/badline/c128/mmu.rb +9 -8
- data/lib/badline/c128/mmu_pages.rb +21 -1
- data/lib/badline/c128/modes.rb +21 -11
- data/lib/badline/c128/z80.rb +2 -2
- data/lib/badline/c128/z80_turns.rb +1 -1
- data/lib/badline/c128.rb +21 -16
- data/lib/badline/c64/attachments.rb +42 -0
- data/lib/badline/c64/banked_ram/banking.rb +32 -0
- data/lib/badline/c64/banked_ram/plus256k.rb +64 -0
- data/lib/badline/c64/banked_ram/plus60k.rb +47 -0
- data/lib/badline/c64/banked_ram/unexpanded.rb +30 -0
- data/lib/badline/c64/banked_ram.rb +23 -0
- data/lib/badline/c64/bus/debug_register.rb +32 -0
- data/lib/badline/c64/bus/extra_sids.rb +32 -0
- data/lib/badline/c64/bus/fittings.rb +40 -0
- data/lib/badline/c64/bus/keyed_state.rb +41 -0
- data/lib/badline/c64/bus/pla.rb +149 -0
- data/lib/badline/c64/bus/roms.rb +41 -0
- data/lib/badline/c64/bus/sid_slots.rb +44 -0
- data/lib/badline/c64/bus.rb +219 -0
- data/lib/badline/c64/cartridge/action_replay.rb +115 -0
- data/lib/badline/c64/cartridge/atomic_power.rb +26 -0
- data/lib/badline/c64/cartridge/bank.rb +83 -0
- data/lib/badline/c64/cartridge/comal80.rb +52 -0
- data/lib/badline/c64/cartridge/dinamic.rb +36 -0
- data/lib/badline/c64/cartridge/easy_flash.rb +132 -0
- data/lib/badline/c64/cartridge/epyx_fastload.rb +73 -0
- data/lib/badline/c64/cartridge/final_cartridge3.rb +79 -0
- data/lib/badline/c64/cartridge/flash.rb +279 -0
- data/lib/badline/c64/cartridge/freezer.rb +35 -0
- data/lib/badline/c64/cartridge/fun_play.rb +40 -0
- data/lib/badline/c64/cartridge/g_mod2.rb +64 -0
- data/lib/badline/c64/cartridge/game_system.rb +42 -0
- data/lib/badline/c64/cartridge/geo_ram.rb +65 -0
- data/lib/badline/c64/cartridge/kcs_power.rb +69 -0
- data/lib/badline/c64/cartridge/keyed_state.rb +393 -0
- data/lib/badline/c64/cartridge/mach5.rb +34 -0
- data/lib/badline/c64/cartridge/magic_desk.rb +32 -0
- data/lib/badline/c64/cartridge/ocean.rb +37 -0
- data/lib/badline/c64/cartridge/pagefox.rb +60 -0
- data/lib/badline/c64/cartridge/retro_replay.rb +278 -0
- data/lib/badline/c64/cartridge/rex_utility.rb +31 -0
- data/lib/badline/c64/cartridge/rgcd.rb +50 -0
- data/lib/badline/c64/cartridge/simons_basic.rb +37 -0
- data/lib/badline/c64/cartridge/standard.rb +17 -0
- data/lib/badline/c64/cartridge/super_games.rb +40 -0
- data/lib/badline/c64/cartridge/westermann.rb +32 -0
- data/lib/badline/c64/cartridge/zaxxon.rb +52 -0
- data/lib/badline/c64/cartridge.rb +232 -0
- data/lib/badline/c64/color_memory.rb +27 -0
- data/lib/badline/{computer → c64}/common.rb +2 -2
- data/lib/badline/{computer → c64}/kernal_traps.rb +39 -36
- data/lib/badline/c64/keyed_modules.rb +111 -0
- data/lib/badline/c64/keyed_state.rb +68 -0
- data/lib/badline/c64/reu/dma.rb +271 -0
- data/lib/badline/c64/reu/keyed_state.rb +140 -0
- data/lib/badline/c64/reu/ram.rb +94 -0
- data/lib/badline/c64/reu/trigger.rb +34 -0
- data/lib/badline/c64/reu.rb +289 -0
- data/lib/badline/c64/true_drives.rb +120 -0
- data/lib/badline/{computer.rb → c64.rb} +24 -15
- data/lib/badline/chips/cia/fast_forward.rb +62 -0
- data/lib/badline/chips/cia/interrupt_register.rb +128 -0
- data/lib/badline/chips/cia/keyed_parts.rb +213 -0
- data/lib/badline/chips/cia/serial.rb +246 -0
- data/lib/badline/chips/cia/time_of_day.rb +210 -0
- data/lib/badline/chips/cia/timer.rb +188 -0
- data/lib/badline/chips/cia.rb +281 -0
- data/lib/badline/chips/cpu/addressing.rb +133 -0
- data/lib/badline/chips/cpu/boundary.rb +56 -0
- data/lib/badline/chips/cpu/core.rb +183 -0
- data/lib/badline/chips/cpu/instruction.rb +338 -0
- data/lib/badline/chips/cpu/instruction_set/arithmetic.rb +118 -0
- data/lib/badline/chips/cpu/instruction_set/bitwise.rb +130 -0
- data/lib/badline/chips/cpu/instruction_set/branch.rb +83 -0
- data/lib/badline/chips/cpu/instruction_set/flag.rb +67 -0
- data/lib/badline/chips/cpu/instruction_set/illegal.rb +274 -0
- data/lib/badline/chips/cpu/instruction_set/inc_dec.rb +73 -0
- data/lib/badline/chips/cpu/instruction_set/stack.rb +56 -0
- data/lib/badline/chips/cpu/instruction_set/transfer.rb +141 -0
- data/lib/badline/chips/cpu/instruction_set.rb +59 -0
- data/lib/badline/chips/cpu/interrupts.rb +108 -0
- data/lib/badline/chips/cpu/keyed_state.rb +177 -0
- data/lib/badline/chips/cpu/microcode.rb +195 -0
- data/lib/badline/chips/cpu/operations.rb +90 -0
- data/lib/badline/chips/cpu/port.rb +133 -0
- data/lib/badline/chips/cpu/stack_operations.rb +84 -0
- data/lib/badline/chips/cpu/traps.rb +23 -0
- data/lib/badline/chips/cpu.rb +17 -0
- data/lib/badline/chips/sid/catch_up.rb +122 -0
- data/lib/badline/chips/sid/decimator.rb +68 -0
- data/lib/badline/chips/sid/envelope.rb +236 -0
- data/lib/badline/chips/sid/filter.rb +227 -0
- data/lib/badline/chips/sid/keyed_parts.rb +286 -0
- data/lib/badline/chips/sid/voice.rb +69 -0
- data/lib/badline/chips/sid/waveform/combined.rb +128 -0
- data/lib/badline/chips/sid/waveform/fast_forward.rb +107 -0
- data/lib/badline/chips/sid/waveform/noise_writeback.rb +124 -0
- data/lib/badline/chips/sid/waveform.rb +305 -0
- data/lib/badline/chips/sid.rb +264 -0
- data/lib/badline/chips/ted/beam.rb +119 -0
- data/lib/badline/chips/ted/timers.rb +66 -0
- data/lib/badline/chips/ted.rb +143 -0
- data/lib/badline/chips/tia.rb +49 -0
- data/lib/badline/chips/vdc/keyed_parts.rb +105 -0
- data/lib/badline/{c128 → chips}/vdc/memory.rb +1 -1
- data/lib/badline/{c128 → chips}/vdc/painter.rb +1 -13
- data/lib/badline/{c128 → chips}/vdc/raster.rb +1 -17
- data/lib/badline/{c128 → chips}/vdc/window.rb +1 -10
- data/lib/badline/{c128 → chips}/vdc.rb +6 -31
- data/lib/badline/chips/via/control_lines.rb +109 -0
- data/lib/badline/chips/via/fast_forward.rb +55 -0
- data/lib/badline/chips/via/interrupt_register.rb +60 -0
- data/lib/badline/chips/via/keyed_parts.rb +163 -0
- data/lib/badline/chips/via/shift_register.rb +168 -0
- data/lib/badline/chips/via/timer1.rb +120 -0
- data/lib/badline/chips/via/timer2.rb +117 -0
- data/lib/badline/chips/via.rb +267 -0
- data/lib/badline/chips/vic/bank.rb +135 -0
- data/lib/badline/chips/vic/border_mask.rb +78 -0
- data/lib/badline/chips/vic/collisions.rb +106 -0
- data/lib/badline/chips/vic/color_patches.rb +38 -0
- data/lib/badline/chips/vic/display_state.rb +168 -0
- data/lib/badline/chips/vic/graphics_mode.rb +166 -0
- data/lib/badline/chips/vic/graphics_shifter.rb +183 -0
- data/lib/badline/chips/vic/keyed_parts.rb +228 -0
- data/lib/badline/chips/vic/keyed_sprites.rb +225 -0
- data/lib/badline/chips/vic/keyed_state.rb +102 -0
- data/lib/badline/chips/vic/register_log.rb +65 -0
- data/lib/badline/chips/vic/registers.rb +188 -0
- data/lib/badline/chips/vic/sequencer.rb +275 -0
- data/lib/badline/chips/vic/sequencer_output.rb +118 -0
- data/lib/badline/chips/vic/sprite/internal_bus.rb +59 -0
- data/lib/badline/chips/vic/sprite/shifter.rb +148 -0
- data/lib/badline/chips/vic/sprite/timing.rb +58 -0
- data/lib/badline/chips/vic/sprite.rb +337 -0
- data/lib/badline/chips/vic/sprites.rb +281 -0
- data/lib/badline/chips/vic.rb +787 -0
- data/lib/badline/chips/vic_i/keyed_parts.rb +142 -0
- data/lib/badline/{vic20/vic → chips/vic_i}/painter.rb +2 -30
- data/lib/badline/chips/vic_i/sound/output.rb +85 -0
- data/lib/badline/chips/vic_i/sound.rb +227 -0
- data/lib/badline/{vic20/vic → chips/vic_i}/text_window.rb +2 -2
- data/lib/badline/{vic20/vic.rb → chips/vic_i.rb} +6 -6
- data/lib/badline/chips/z80/arithmetic.rb +119 -0
- data/lib/badline/chips/z80/bit_page.rb +57 -0
- data/lib/badline/chips/z80/block_io.rb +60 -0
- data/lib/badline/chips/z80/block_transfers.rb +61 -0
- data/lib/badline/chips/z80/bus_cycles.rb +113 -0
- data/lib/badline/chips/z80/core.rb +115 -0
- data/lib/badline/chips/z80/exchanges.rb +52 -0
- data/lib/badline/chips/z80/extended_page.rb +91 -0
- data/lib/badline/chips/z80/flags.rb +39 -0
- data/lib/badline/chips/z80/interrupt_acceptance.rb +48 -0
- data/lib/badline/chips/z80/jumps.rb +84 -0
- data/lib/badline/chips/z80/keyed_state.rb +73 -0
- data/lib/badline/chips/z80/loads.rb +100 -0
- data/lib/badline/chips/z80/main_page.rb +136 -0
- data/lib/badline/chips/z80/registers.rb +122 -0
- data/lib/badline/chips/z80/shifts.rb +66 -0
- data/lib/badline/chips/z80.rb +13 -0
- data/lib/badline/chips.rb +10 -0
- data/lib/badline/core.rb +13 -32
- data/lib/badline/drives/datasette/keyed_state.rb +38 -0
- data/lib/badline/drives/datasette.rb +173 -0
- data/lib/badline/drives/engine/core.rb +152 -0
- data/lib/badline/drives/engine/fast_serial.rb +75 -0
- data/lib/badline/drives/engine/idle.rb +127 -0
- data/lib/badline/drives/engine/idle_cpu.rb +30 -0
- data/lib/badline/drives/engine/orbit.rb +81 -0
- data/lib/badline/drives/engine/serial_lines.rb +72 -0
- data/lib/badline/drives/engine/sleep.rb +114 -0
- data/lib/badline/drives/engine/vias.rb +86 -0
- data/lib/badline/drives/engine/watch.rb +152 -0
- data/lib/badline/drives/engine.rb +11 -0
- data/lib/badline/drives/model1541/bus.rb +75 -0
- data/lib/badline/drives/model1541/byte_ready.rb +50 -0
- data/lib/badline/drives/model1541/cpu.rb +13 -0
- data/lib/badline/drives/model1541/disk.rb +318 -0
- data/lib/badline/drives/model1541/disk_via.rb +38 -0
- data/lib/badline/drives/model1541/gcr.rb +59 -0
- data/lib/badline/drives/model1541/keyed_state.rb +251 -0
- data/lib/badline/drives/model1541/mechanism.rb +313 -0
- data/lib/badline/drives/model1541/rotation.rb +123 -0
- data/lib/badline/drives/model1541/sector_reader.rb +78 -0
- data/lib/badline/drives/model1541/serial_port.rb +20 -0
- data/lib/badline/drives/model1541/track.rb +100 -0
- data/lib/badline/drives/model1541.rb +80 -0
- data/lib/badline/drives/model1571/bus.rb +100 -0
- data/lib/badline/drives/model1571/cpu.rb +13 -0
- data/lib/badline/drives/model1571/keyed_state.rb +108 -0
- data/lib/badline/drives/model1571/serial_port.rb +39 -0
- data/lib/badline/drives/model1571/serial_via.rb +27 -0
- data/lib/badline/drives/model1571/wd1770.rb +108 -0
- data/lib/badline/drives/model1571.rb +141 -0
- data/lib/badline/drives/model1581/bus.rb +126 -0
- data/lib/badline/drives/model1581/cpu.rb +13 -0
- data/lib/badline/drives/model1581/disk.rb +133 -0
- data/lib/badline/drives/model1581/keyed_state.rb +280 -0
- data/lib/badline/drives/model1581/mechanism.rb +98 -0
- data/lib/badline/drives/model1581/serial_port.rb +54 -0
- data/lib/badline/drives/model1581/slot.rb +61 -0
- data/lib/badline/drives/model1581/track.rb +102 -0
- data/lib/badline/drives/model1581/track_bytes.rb +77 -0
- data/lib/badline/drives/model1581/wd1772/registers.rb +91 -0
- data/lib/badline/drives/model1581/wd1772/sector_writes.rb +75 -0
- data/lib/badline/drives/model1581/wd1772/sectors.rb +152 -0
- data/lib/badline/drives/model1581/wd1772/stepping.rb +111 -0
- data/lib/badline/drives/model1581/wd1772/tracks.rb +127 -0
- data/lib/badline/drives/model1581/wd1772/turn.rb +75 -0
- data/lib/badline/drives/model1581/wd1772.rb +216 -0
- data/lib/badline/drives/model1581.rb +206 -0
- data/lib/badline/drives/serial_bus.rb +161 -0
- data/lib/badline/drives.rb +8 -0
- data/lib/badline/frontend/app.rb +3 -3
- data/lib/badline/frontend/boot.rb +4 -4
- data/lib/badline/frontend/controls.rb +19 -3
- data/lib/badline/frontend/drive_led.rb +44 -21
- data/lib/badline/frontend/machine_window.rb +3 -1
- data/lib/badline/frontend/menu/menu_dialogs.rb +2 -2
- data/lib/badline/frontend/player/filter_view.rb +1 -1
- data/lib/badline/frontend/player/player_controller.rb +2 -2
- data/lib/badline/frontend/player/player_screen.rb +1 -0
- data/lib/badline/frontend/player/theme.rb +7 -7
- data/lib/badline/frontend/snapshots.rb +12 -1
- data/lib/badline/frontend/timeline.rb +30 -12
- data/lib/badline/input/control_ports.rb +78 -0
- data/lib/badline/input/joystick.rb +27 -0
- data/lib/badline/input/keyboard.rb +114 -0
- data/lib/badline/input/matrix_typist.rb +98 -0
- data/lib/badline/input.rb +4 -0
- data/lib/badline/kernal_trap/chrout.rb +45 -0
- data/lib/badline/kernal_trap/{drive → dos}/block_commands.rb +1 -1
- data/lib/badline/kernal_trap/dos/channel.rb +156 -0
- data/lib/badline/kernal_trap/{drive → dos}/channels.rb +1 -26
- data/lib/badline/kernal_trap/{drive → dos}/memory.rb +1 -10
- data/lib/badline/kernal_trap/{drive → dos}/parameters.rb +1 -1
- data/lib/badline/kernal_trap/{drive → dos}/status.rb +1 -9
- data/lib/badline/kernal_trap/{drive → dos}/write_file.rb +1 -19
- data/lib/badline/kernal_trap/{drive → dos}/writes.rb +1 -1
- data/lib/badline/kernal_trap/{drive.rb → dos.rb} +9 -27
- data/lib/badline/kernal_trap/file_routine.rb +4 -4
- data/lib/badline/kernal_trap/keyed_state.rb +150 -0
- data/lib/badline/kernal_trap/layout.rb +75 -11
- data/lib/badline/kernal_trap/load.rb +19 -21
- data/lib/badline/kernal_trap/routine.rb +12 -0
- data/lib/badline/kernal_trap/save.rb +12 -22
- data/lib/badline/kernal_trap/serial.rb +8 -24
- data/lib/badline/kernal_trap.rb +3 -2
- data/lib/badline/machine/clocking.rb +1 -1
- data/lib/badline/machine/keyboard_buffer.rb +49 -0
- data/lib/badline/machine/settling.rb +29 -0
- data/lib/badline/machine.rb +10 -7
- data/lib/badline/media/boot_disk.rb +14 -2
- data/lib/badline/media/extensions.rb +10 -0
- data/lib/badline/media/true_drive.rb +1 -1
- data/lib/badline/media/tune.rb +2 -2
- data/lib/badline/media.rb +3 -3
- data/lib/badline/memory.rb +3 -6
- data/lib/badline/model.rb +1 -1
- data/lib/badline/options/family.rb +5 -2
- data/lib/badline/options/help.rb +42 -16
- data/lib/badline/options/table.rb +2 -0
- data/lib/badline/options/validation.rb +2 -0
- data/lib/badline/options.rb +6 -1
- data/lib/badline/plus4/acia.rb +45 -0
- data/lib/badline/plus4/bus.rb +312 -0
- data/lib/badline/plus4/cpu.rb +10 -0
- data/lib/badline/plus4/cpu_port.rb +93 -0
- data/lib/badline/plus4/keyboard_port.rb +51 -0
- data/lib/badline/plus4/model.rb +38 -0
- data/lib/badline/plus4/user_port.rb +31 -0
- data/lib/badline/plus4.rb +164 -0
- data/lib/badline/roms/README +44 -6
- data/lib/badline/roms/plus4/basic.rom +0 -0
- data/lib/badline/roms/plus4/function-high.rom +0 -0
- data/lib/badline/roms/plus4/function-low.rom +0 -0
- data/lib/badline/roms/plus4/kernal-ntsc.rom +0 -0
- data/lib/badline/roms/plus4/kernal-pal.rom +0 -0
- data/lib/badline/sdl.rb +1 -0
- data/lib/badline/{storage/sid_file.rb → sid_tune/file.rb} +3 -3
- data/lib/badline/{storage → sid_tune}/hvsc.rb +7 -7
- data/lib/badline/{storage → sid_tune}/song_lengths.rb +2 -2
- data/lib/badline/{storage → sid_tune}/stil/credit.rb +1 -1
- data/lib/badline/{storage → sid_tune}/stil.rb +3 -3
- data/lib/badline/sid_tune.rb +6 -0
- data/lib/badline/snapshot/c128_setup.rb +32 -0
- data/lib/badline/snapshot/c64_setup.rb +83 -0
- data/lib/badline/snapshot/container.rb +4 -0
- data/lib/badline/snapshot/field_doc/markdown.rb +112 -0
- data/lib/badline/snapshot/field_doc.rb +109 -0
- data/lib/badline/snapshot/image.rb +132 -46
- data/lib/badline/snapshot/keyed/cursor.rb +40 -0
- data/lib/badline/snapshot/keyed/modules.rb +66 -0
- data/lib/badline/snapshot/keyed/reader.rb +188 -0
- data/lib/badline/snapshot/keyed/recorder.rb +88 -0
- data/lib/badline/snapshot/keyed/report.rb +26 -0
- data/lib/badline/snapshot/keyed/writer.rb +55 -0
- data/lib/badline/snapshot/keyed.rb +64 -0
- data/lib/badline/snapshot/machine_state.rb +17 -64
- data/lib/badline/snapshot/storage_setup.rb +63 -0
- data/lib/badline/snapshot/vic20_setup.rb +28 -0
- data/lib/badline/snapshot/vice/c64_mem.rb +1 -1
- data/lib/badline/snapshot/vice/restore.rb +1 -1
- data/lib/badline/snapshot/vice/reu1764.rb +3 -3
- data/lib/badline/snapshot/vice/reu_fields.rb +40 -0
- data/lib/badline/snapshot/vice.rb +13 -35
- data/lib/badline/snapshot.rb +44 -22
- data/lib/badline/storage/crt_file.rb +3 -1
- data/lib/badline/storage/d64_image.rb +0 -2
- data/lib/badline/storage/d71_image.rb +0 -2
- data/lib/badline/storage/d81_image.rb +0 -2
- data/lib/badline/storage/disk_image.rb +3 -6
- data/lib/badline/storage/g64_image.rb +10 -5
- data/lib/badline/storage/host_directory.rb +0 -5
- data/lib/badline/storage/t64.rb +2 -8
- data/lib/badline/storage/tap.rb +43 -15
- data/lib/badline/storage/unavailable.rb +1 -1
- data/lib/badline/storage.rb +0 -37
- data/lib/badline/support/c128_checkpoint.rb +39 -0
- data/lib/badline/support/checkpoint.rb +108 -0
- data/lib/badline/support/vic20_checkpoint.rb +38 -0
- data/lib/badline/support.rb +5 -0
- data/lib/badline/version.rb +1 -1
- data/lib/badline/vic20/attachments.rb +8 -5
- data/lib/badline/vic20/bus/keyed_state.rb +52 -0
- data/lib/badline/vic20/bus.rb +2 -25
- data/lib/badline/vic20/cpu.rb +1 -1
- data/lib/badline/vic20/keyed_modules.rb +73 -0
- data/lib/badline/vic20/keyed_state.rb +45 -0
- data/lib/badline/vic20/port_wiring.rb +4 -4
- data/lib/badline/vic20/user_via_ports.rb +2 -2
- data/lib/badline/vic20.rb +22 -17
- data/lib/badline.rb +1 -0
- metadata +271 -228
- data/lib/badline/address_bus/extra_sids.rb +0 -30
- data/lib/badline/address_bus/fittings.rb +0 -38
- data/lib/badline/address_bus/pla.rb +0 -147
- data/lib/badline/address_bus/roms.rb +0 -39
- data/lib/badline/address_bus/saved_state.rb +0 -66
- data/lib/badline/address_bus/sid_slots.rb +0 -42
- data/lib/badline/address_bus.rb +0 -216
- data/lib/badline/c128/bus_state.rb +0 -53
- data/lib/badline/c128/saved_state.rb +0 -143
- data/lib/badline/cartridge/action_replay.rb +0 -126
- data/lib/badline/cartridge/atomic_power.rb +0 -24
- data/lib/badline/cartridge/bank.rb +0 -81
- data/lib/badline/cartridge/comal80.rb +0 -50
- data/lib/badline/cartridge/dinamic.rb +0 -34
- data/lib/badline/cartridge/easy_flash.rb +0 -145
- data/lib/badline/cartridge/epyx_fastload.rb +0 -79
- data/lib/badline/cartridge/final_cartridge3.rb +0 -89
- data/lib/badline/cartridge/flash.rb +0 -306
- data/lib/badline/cartridge/freezer.rb +0 -33
- data/lib/badline/cartridge/fun_play.rb +0 -38
- data/lib/badline/cartridge/g_mod2.rb +0 -74
- data/lib/badline/cartridge/game_system.rb +0 -40
- data/lib/badline/cartridge/geo_ram.rb +0 -79
- data/lib/badline/cartridge/kcs_power.rb +0 -75
- data/lib/badline/cartridge/mach5.rb +0 -32
- data/lib/badline/cartridge/magic_desk.rb +0 -30
- data/lib/badline/cartridge/ocean.rb +0 -35
- data/lib/badline/cartridge/pagefox.rb +0 -68
- data/lib/badline/cartridge/retro_replay.rb +0 -320
- data/lib/badline/cartridge/rex_utility.rb +0 -29
- data/lib/badline/cartridge/rgcd.rb +0 -58
- data/lib/badline/cartridge/simons_basic.rb +0 -35
- data/lib/badline/cartridge/standard.rb +0 -15
- data/lib/badline/cartridge/super_games.rb +0 -48
- data/lib/badline/cartridge/westermann.rb +0 -30
- data/lib/badline/cartridge/zaxxon.rb +0 -66
- data/lib/badline/cartridge.rb +0 -303
- data/lib/badline/checkpoint.rb +0 -98
- data/lib/badline/chrout_trap.rb +0 -43
- data/lib/badline/cia/fast_forward.rb +0 -60
- data/lib/badline/cia/interrupt_register.rb +0 -143
- data/lib/badline/cia/serial.rb +0 -275
- data/lib/badline/cia/state.rb +0 -47
- data/lib/badline/cia/timer.rb +0 -206
- data/lib/badline/cia.rb +0 -279
- data/lib/badline/color_memory.rb +0 -25
- data/lib/badline/computer/attachments.rb +0 -88
- data/lib/badline/computer/saved_state.rb +0 -117
- data/lib/badline/computer/true_drives.rb +0 -69
- data/lib/badline/control_ports.rb +0 -76
- data/lib/badline/cpu/addressing.rb +0 -131
- data/lib/badline/cpu/boundary.rb +0 -54
- data/lib/badline/cpu/core.rb +0 -165
- data/lib/badline/cpu/microcode.rb +0 -177
- data/lib/badline/cpu/operations.rb +0 -88
- data/lib/badline/cpu/saved_state.rb +0 -115
- data/lib/badline/cpu/stack_operations.rb +0 -82
- data/lib/badline/cpu.rb +0 -10
- data/lib/badline/cpu_port.rb +0 -112
- data/lib/badline/datasette.rb +0 -161
- data/lib/badline/debug_register.rb +0 -28
- data/lib/badline/drive/core.rb +0 -147
- data/lib/badline/drive/fast_serial.rb +0 -73
- data/lib/badline/drive/idle.rb +0 -125
- data/lib/badline/drive/idle_cpu.rb +0 -28
- data/lib/badline/drive/orbit.rb +0 -79
- data/lib/badline/drive/serial_lines.rb +0 -73
- data/lib/badline/drive/sleep.rb +0 -112
- data/lib/badline/drive/vias.rb +0 -84
- data/lib/badline/drive/watch.rb +0 -150
- data/lib/badline/drive.rb +0 -11
- data/lib/badline/drive1541/bus.rb +0 -86
- data/lib/badline/drive1541/byte_ready.rb +0 -48
- data/lib/badline/drive1541/cpu.rb +0 -11
- data/lib/badline/drive1541/disk.rb +0 -315
- data/lib/badline/drive1541/disk_state.rb +0 -86
- data/lib/badline/drive1541/disk_via.rb +0 -36
- data/lib/badline/drive1541/gcr.rb +0 -57
- data/lib/badline/drive1541/mechanism.rb +0 -313
- data/lib/badline/drive1541/mechanism_state.rb +0 -68
- data/lib/badline/drive1541/rotation.rb +0 -121
- data/lib/badline/drive1541/sector_reader.rb +0 -76
- data/lib/badline/drive1541/serial_port.rb +0 -18
- data/lib/badline/drive1541/track.rb +0 -98
- data/lib/badline/drive1541.rb +0 -111
- data/lib/badline/drive1571/bus.rb +0 -111
- data/lib/badline/drive1571/cpu.rb +0 -11
- data/lib/badline/drive1571/serial_port.rb +0 -37
- data/lib/badline/drive1571/serial_via.rb +0 -25
- data/lib/badline/drive1571/wd1770.rb +0 -120
- data/lib/badline/drive1571.rb +0 -175
- data/lib/badline/drive1581/bus.rb +0 -137
- data/lib/badline/drive1581/cpu.rb +0 -11
- data/lib/badline/drive1581/disk.rb +0 -135
- data/lib/badline/drive1581/disk_state.rb +0 -87
- data/lib/badline/drive1581/mechanism.rb +0 -117
- data/lib/badline/drive1581/serial_port.rb +0 -52
- data/lib/badline/drive1581/slot.rb +0 -78
- data/lib/badline/drive1581/track.rb +0 -100
- data/lib/badline/drive1581/track_bytes.rb +0 -75
- data/lib/badline/drive1581/wd1772/registers.rb +0 -89
- data/lib/badline/drive1581/wd1772/sector_writes.rb +0 -73
- data/lib/badline/drive1581/wd1772/sectors.rb +0 -150
- data/lib/badline/drive1581/wd1772/state.rb +0 -66
- data/lib/badline/drive1581/wd1772/stepping.rb +0 -109
- data/lib/badline/drive1581/wd1772/tracks.rb +0 -125
- data/lib/badline/drive1581/wd1772/turn.rb +0 -73
- data/lib/badline/drive1581/wd1772.rb +0 -216
- data/lib/badline/drive1581.rb +0 -233
- data/lib/badline/iec_bus.rb +0 -159
- data/lib/badline/instruction.rb +0 -334
- data/lib/badline/instruction_set/arithmetic.rb +0 -114
- data/lib/badline/instruction_set/bitwise.rb +0 -126
- data/lib/badline/instruction_set/branch.rb +0 -79
- data/lib/badline/instruction_set/flag.rb +0 -63
- data/lib/badline/instruction_set/illegal.rb +0 -270
- data/lib/badline/instruction_set/inc_dec.rb +0 -69
- data/lib/badline/instruction_set/stack.rb +0 -52
- data/lib/badline/instruction_set/transfer.rb +0 -137
- data/lib/badline/instruction_set.rb +0 -55
- data/lib/badline/interrupts.rb +0 -104
- data/lib/badline/joystick.rb +0 -25
- data/lib/badline/kernal_trap/channel.rb +0 -181
- data/lib/badline/keyboard.rb +0 -112
- data/lib/badline/keyboard_buffer.rb +0 -33
- data/lib/badline/ram_expansion/banking.rb +0 -30
- data/lib/badline/ram_expansion/plus256k.rb +0 -54
- data/lib/badline/ram_expansion/plus60k.rb +0 -43
- data/lib/badline/ram_expansion/unexpanded.rb +0 -28
- data/lib/badline/ram_expansion.rb +0 -21
- data/lib/badline/reu/dma/saved_state.rb +0 -50
- data/lib/badline/reu/dma.rb +0 -273
- data/lib/badline/reu/ram.rb +0 -107
- data/lib/badline/reu/saved_state.rb +0 -80
- data/lib/badline/reu/trigger.rb +0 -32
- data/lib/badline/reu.rb +0 -289
- data/lib/badline/sid/catch_up.rb +0 -120
- data/lib/badline/sid/decimator.rb +0 -64
- data/lib/badline/sid/envelope/state.rb +0 -68
- data/lib/badline/sid/envelope.rb +0 -239
- data/lib/badline/sid/filter.rb +0 -263
- data/lib/badline/sid/voice.rb +0 -77
- data/lib/badline/sid/waveform/combined.rb +0 -126
- data/lib/badline/sid/waveform/fast_forward.rb +0 -105
- data/lib/badline/sid/waveform/noise_writeback.rb +0 -122
- data/lib/badline/sid/waveform/state.rb +0 -66
- data/lib/badline/sid/waveform.rb +0 -305
- data/lib/badline/sid.rb +0 -303
- data/lib/badline/snapshot/setup.rb +0 -75
- data/lib/badline/snapshot/state.rb +0 -189
- data/lib/badline/time_of_day.rb +0 -228
- data/lib/badline/traps.rb +0 -19
- data/lib/badline/via/control_lines.rb +0 -122
- data/lib/badline/via/fast_forward.rb +0 -53
- data/lib/badline/via/interrupt_register.rb +0 -67
- data/lib/badline/via/shift_register.rb +0 -180
- data/lib/badline/via/state.rb +0 -42
- data/lib/badline/via/timer1.rb +0 -131
- data/lib/badline/via/timer2.rb +0 -133
- data/lib/badline/via.rb +0 -266
- data/lib/badline/vic/bank.rb +0 -133
- data/lib/badline/vic/border_mask.rb +0 -86
- data/lib/badline/vic/collisions.rb +0 -115
- data/lib/badline/vic/color_patches.rb +0 -47
- data/lib/badline/vic/display_state.rb +0 -185
- data/lib/badline/vic/graphics_mode.rb +0 -164
- data/lib/badline/vic/graphics_shifter.rb +0 -207
- data/lib/badline/vic/register_log.rb +0 -81
- data/lib/badline/vic/registers.rb +0 -195
- data/lib/badline/vic/sequencer.rb +0 -275
- data/lib/badline/vic/sequencer_output.rb +0 -116
- data/lib/badline/vic/sequencer_state.rb +0 -89
- data/lib/badline/vic/sprite/internal_bus.rb +0 -68
- data/lib/badline/vic/sprite/saved_state.rb +0 -64
- data/lib/badline/vic/sprite/shifter.rb +0 -146
- data/lib/badline/vic/sprite/timing.rb +0 -56
- data/lib/badline/vic/sprite.rb +0 -337
- data/lib/badline/vic/sprites.rb +0 -282
- data/lib/badline/vic/sprites_state.rb +0 -57
- data/lib/badline/vic.rb +0 -853
- data/lib/badline/vic20/saved_state.rb +0 -124
- data/lib/badline/vic20/sound/output.rb +0 -83
- data/lib/badline/vic20/sound.rb +0 -233
- data/lib/badline/vic20/vic/saved_state.rb +0 -55
- data/lib/badline/z80/arithmetic.rb +0 -117
- data/lib/badline/z80/bit_page.rb +0 -55
- data/lib/badline/z80/block_io.rb +0 -58
- data/lib/badline/z80/block_transfers.rb +0 -59
- data/lib/badline/z80/bus_cycles.rb +0 -111
- data/lib/badline/z80/core.rb +0 -113
- data/lib/badline/z80/exchanges.rb +0 -50
- data/lib/badline/z80/extended_page.rb +0 -89
- data/lib/badline/z80/flags.rb +0 -37
- data/lib/badline/z80/interrupt_acceptance.rb +0 -46
- data/lib/badline/z80/jumps.rb +0 -82
- data/lib/badline/z80/loads.rb +0 -98
- data/lib/badline/z80/main_page.rb +0 -134
- data/lib/badline/z80/registers.rb +0 -120
- data/lib/badline/z80/saved_state.rb +0 -69
- data/lib/badline/z80/shifts.rb +0 -64
- data/lib/badline/z80.rb +0 -11
- /data/lib/badline/snapshot/{fields.rb → vice/fields.rb} +0 -0
|
@@ -0,0 +1,312 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class Plus4
|
|
5
|
+
# The CPU's bus:
|
|
6
|
+
#
|
|
7
|
+
# $0000-$0001 - the 7501's port (CPUPort), over RAM
|
|
8
|
+
# $0002-$7FFF - RAM
|
|
9
|
+
# $8000-$BFFF - the low ROM bank, or RAM
|
|
10
|
+
# $C000-$FCFF - the high ROM bank, or RAM; $FC00-$FCFF is always the
|
|
11
|
+
# KERNAL's while ROM is selected
|
|
12
|
+
# $FD00-$FD0F - the 6551 ACIA (Plus/4 only)
|
|
13
|
+
# $FD10-$FD1F - the user port's 6529 (Plus/4 only)
|
|
14
|
+
# $FD30-$FD3F - the keyboard's 6529 (KeyboardPort)
|
|
15
|
+
# $FDD0-$FDDF - the ROM bank latch
|
|
16
|
+
# $FF00-$FF1F - the TED
|
|
17
|
+
# $FF3E/$FF3F - a write selects ROM or RAM at $8000-$FFFF
|
|
18
|
+
# $FF40-$FFFF - the high ROM bank, or RAM
|
|
19
|
+
#
|
|
20
|
+
# A write to $FF3E selects ROM and one to $FF3F RAM, everywhere in
|
|
21
|
+
# $8000-$FFFF but $FD00-$FF3F, which holds I/O either way. ROM is
|
|
22
|
+
# selected at power-on and reset. A write to ROM goes to the RAM under
|
|
23
|
+
# it. The ROM bank latch takes the address written to, not the byte:
|
|
24
|
+
# bits 0-1 pick the low bank and bits 2-3 the high bank, 0 for BASIC
|
|
25
|
+
# and the KERNAL, 1 for the Plus/4's function ROMs, 2 and 3 for the two
|
|
26
|
+
# cartridges.
|
|
27
|
+
#
|
|
28
|
+
# RAM smaller than 64K repeats through the 64K, as the C16's 16K does
|
|
29
|
+
# without A14 and A15. Where nothing answers, a read finds the last byte
|
|
30
|
+
# on the bus.
|
|
31
|
+
class Bus
|
|
32
|
+
include Addressable
|
|
33
|
+
|
|
34
|
+
RAM_POWER_ON = 0x00
|
|
35
|
+
|
|
36
|
+
# RAM through a size it repeats at.
|
|
37
|
+
class MirroredRAM
|
|
38
|
+
def initialize(ram, mask)
|
|
39
|
+
@ram = ram
|
|
40
|
+
@mask = mask
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def peek(addr) = @ram.peek(addr & @mask)
|
|
44
|
+
|
|
45
|
+
def poke(addr, value)
|
|
46
|
+
@ram.poke(addr & @mask, value)
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# The last byte the CPU moved, which an empty spot reads back.
|
|
51
|
+
class OpenBus
|
|
52
|
+
def initialize(bus)
|
|
53
|
+
@bus = bus
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def peek(_addr) = @bus.data
|
|
57
|
+
def poke(_addr, _value); end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Page 0: the port at $00 and $01, RAM above it.
|
|
61
|
+
class ZeroPage
|
|
62
|
+
def initialize(port, ram)
|
|
63
|
+
@port = port
|
|
64
|
+
@ram = ram
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def peek(addr) = addr < 2 ? @port.peek(addr) : @ram.peek(addr)
|
|
68
|
+
|
|
69
|
+
def poke(addr, value)
|
|
70
|
+
return @port.poke(addr, value) if addr < 2
|
|
71
|
+
|
|
72
|
+
@ram.poke(addr, value)
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Page $FD: the ACIA, the user port, the keyboard port and the ROM
|
|
77
|
+
# bank latch, by the address's bits 4-7. +acia+ and +user_port+ are
|
|
78
|
+
# nil where the machine has none.
|
|
79
|
+
class IOPage
|
|
80
|
+
def initialize(keyboard_port:, acia: nil, user_port: nil)
|
|
81
|
+
@bus = nil
|
|
82
|
+
@acia = acia
|
|
83
|
+
@user_port = user_port
|
|
84
|
+
@keyboard_port = keyboard_port
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# The bus whose last byte an empty spot reads and whose bank latch
|
|
88
|
+
# a write to $FDD0-$FDDF sets.
|
|
89
|
+
def connect(bus)
|
|
90
|
+
@bus = bus
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def peek(addr)
|
|
94
|
+
case addr & 0xf0
|
|
95
|
+
when 0x00 then @acia ? @acia.peek(addr) : @bus.data
|
|
96
|
+
when 0x10 then @user_port ? @user_port.peek(addr) : @bus.data
|
|
97
|
+
when 0x30 then @keyboard_port.peek(addr)
|
|
98
|
+
else @bus.data
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def poke(addr, value)
|
|
103
|
+
case addr & 0xf0
|
|
104
|
+
when 0x00 then @acia&.poke(addr, value)
|
|
105
|
+
when 0x10 then @user_port&.poke(addr, value)
|
|
106
|
+
when 0x30 then @keyboard_port.poke(addr, value)
|
|
107
|
+
when 0xd0 then @bus.select_banks(addr)
|
|
108
|
+
end
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# VICE's debug cartridge register at $FDCF, a spot in the I/O page
|
|
113
|
+
# that nothing answers (plus4world forum post 31417). A write there
|
|
114
|
+
# calls the handler with the byte, the exit code the VICE testprogs
|
|
115
|
+
# report. Every other access falls through to the I/O page.
|
|
116
|
+
class DebugRegister
|
|
117
|
+
ADDRESS = 0xfdcf
|
|
118
|
+
|
|
119
|
+
def initialize(io, &handler)
|
|
120
|
+
@io = io
|
|
121
|
+
@handler = handler
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
def peek(addr) = @io.peek(addr)
|
|
125
|
+
|
|
126
|
+
def poke(addr, value)
|
|
127
|
+
return @handler.call(value) if addr == ADDRESS
|
|
128
|
+
|
|
129
|
+
@io.poke(addr, value)
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Page $FE with a 1551's TCBM interface plugged in: the 6523 TIA
|
|
134
|
+
# that talks to drive 9 at $FEC0-$FEDF and drive 8's at $FEE0-$FEFF.
|
|
135
|
+
# The rest of the page is open.
|
|
136
|
+
class TCBMPage
|
|
137
|
+
def initialize(bus, drive8:, drive9:)
|
|
138
|
+
@bus = bus
|
|
139
|
+
@drive8 = drive8
|
|
140
|
+
@drive9 = drive9
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def peek(addr)
|
|
144
|
+
return @bus.data if addr < 0xfec0
|
|
145
|
+
|
|
146
|
+
addr < 0xfee0 ? @drive9.peek(addr) : @drive8.peek(addr)
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def poke(addr, value)
|
|
150
|
+
return if addr < 0xfec0
|
|
151
|
+
|
|
152
|
+
addr < 0xfee0 ? @drive9.poke(addr, value) : @drive8.poke(addr, value)
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# Page $FF: the TED in $FF00-$FF3F, its two phantom registers, and
|
|
157
|
+
# ROM or RAM above.
|
|
158
|
+
class TopPage
|
|
159
|
+
def initialize(bus, ted)
|
|
160
|
+
@bus = bus
|
|
161
|
+
@ted = ted
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
def peek(addr)
|
|
165
|
+
return @ted.peek(addr) if addr < 0xff40
|
|
166
|
+
|
|
167
|
+
@bus.top_memory.peek(addr)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def poke(addr, value)
|
|
171
|
+
return @bus.ram_view.poke(addr, value) if addr >= 0xff40
|
|
172
|
+
|
|
173
|
+
case addr
|
|
174
|
+
when 0xff3e then @bus.rom_selected = true
|
|
175
|
+
when 0xff3f then @bus.rom_selected = false
|
|
176
|
+
else @ted.poke(addr, value)
|
|
177
|
+
end
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
attr_reader :ram, :ram_view, :data, :low_bank, :high_bank
|
|
182
|
+
|
|
183
|
+
# What the top page reads above $FF3F: the high ROM bank or RAM.
|
|
184
|
+
attr_reader :top_memory
|
|
185
|
+
|
|
186
|
+
# The CPU sees ROM at $8000-$FFFF.
|
|
187
|
+
attr_reader :rom_selected
|
|
188
|
+
|
|
189
|
+
# +io+ is the IOPage, +model+ a Model profile, whose KERNAL it maps
|
|
190
|
+
# and whose function ROMs it maps where the model has them, and
|
|
191
|
+
# +ram_kb+ the RAM fitted.
|
|
192
|
+
def initialize(ted:, port:, io:, model: Model::PLUS4, ram_kb: model.ram_kb)
|
|
193
|
+
addressable_at(0, length: 2**16)
|
|
194
|
+
size = ram_kb * 1024
|
|
195
|
+
@ram = Memory.new(Array.new(size, RAM_POWER_ON), length: size, start: 0)
|
|
196
|
+
@ram_view = MirroredRAM.new(@ram, size - 1)
|
|
197
|
+
@ted = ted
|
|
198
|
+
@open_bus = OpenBus.new(self)
|
|
199
|
+
@low_roms = [ROM.load("plus4/basic.rom", 0x8000), nil, nil, nil]
|
|
200
|
+
@high_roms = [ROM.load(model.kernal, 0xc000), nil, nil, nil]
|
|
201
|
+
if model.plus4_parts
|
|
202
|
+
@low_roms[1] = ROM.load("plus4/function-low.rom", 0x8000)
|
|
203
|
+
@high_roms[1] = ROM.load("plus4/function-high.rom", 0xc000)
|
|
204
|
+
end
|
|
205
|
+
@zero_page = ZeroPage.new(port, @ram_view)
|
|
206
|
+
@io_page = io
|
|
207
|
+
io.connect(self)
|
|
208
|
+
@top_page = TopPage.new(self, ted)
|
|
209
|
+
@tcbm_page = @open_bus
|
|
210
|
+
@debug_register = nil
|
|
211
|
+
@data = 0
|
|
212
|
+
@read_pages = Array.new(256, @open_bus)
|
|
213
|
+
@write_pages = Array.new(256, @ram_view)
|
|
214
|
+
@low_bank = @high_bank = 0
|
|
215
|
+
@rom_selected = true
|
|
216
|
+
@top_memory = @ram_view
|
|
217
|
+
map_writes
|
|
218
|
+
map_reads
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def power_on!
|
|
222
|
+
@ram.clear!(Array.new(@ram.length, RAM_POWER_ON))
|
|
223
|
+
reset!
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
# The RESET line selects ROM and the first bank of each.
|
|
227
|
+
def reset!
|
|
228
|
+
@low_bank = @high_bank = 0
|
|
229
|
+
self.rom_selected = true
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
def rom_selected=(selected)
|
|
233
|
+
@rom_selected = selected
|
|
234
|
+
@ted.rom_selected = selected
|
|
235
|
+
map_reads
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
# Whether the CPU reads the KERNAL at $C000-$FFFF: ROM selected, with
|
|
239
|
+
# the KERNAL's bank, high bank 0.
|
|
240
|
+
def kernal_selected? = @rom_selected && @high_bank.zero?
|
|
241
|
+
|
|
242
|
+
# A write to the ROM bank latch at +addr+.
|
|
243
|
+
def select_banks(addr)
|
|
244
|
+
@low_bank = addr & 0x03
|
|
245
|
+
@high_bank = (addr >> 2) & 0x03
|
|
246
|
+
map_reads
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
# Calls the block with each byte written to $FDCF (DebugRegister).
|
|
250
|
+
def install_debug_register(&)
|
|
251
|
+
@debug_register = DebugRegister.new(@io_page, &)
|
|
252
|
+
map_writes
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# Plugs in a 1551's TCBM interface, the TIAs at $FEC0-$FEFF.
|
|
256
|
+
def plug_tcbm(drive8:, drive9:)
|
|
257
|
+
@tcbm_page = TCBMPage.new(self, drive8:, drive9:)
|
|
258
|
+
map_writes
|
|
259
|
+
map_reads
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
# Puts a cartridge's ROM chips in the slots of cartridge 1: a chip at
|
|
263
|
+
# $8000 in low bank 2 and one at $C000 in high bank 2, each repeated
|
|
264
|
+
# through the bank's 16K.
|
|
265
|
+
def attach_cartridge(chips)
|
|
266
|
+
chips.each do |chip|
|
|
267
|
+
data = chip.data * (0x4000 / chip.data.length)
|
|
268
|
+
if chip.address < 0xc000
|
|
269
|
+
@low_roms[2] = ROM.new(data, length: 0x4000, start: 0x8000)
|
|
270
|
+
else
|
|
271
|
+
@high_roms[2] = ROM.new(data, length: 0x4000, start: 0xc000)
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
map_reads
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
def peek(addr)
|
|
278
|
+
@data = @read_pages[addr >> 8].peek(addr)
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
def poke(addr, value)
|
|
282
|
+
@data = value
|
|
283
|
+
@write_pages[addr >> 8].poke(addr, value)
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
private
|
|
287
|
+
|
|
288
|
+
def map_writes
|
|
289
|
+
@write_pages[0x00] = @zero_page
|
|
290
|
+
@write_pages[0xfd] = @debug_register || @io_page
|
|
291
|
+
@write_pages[0xfe] = @tcbm_page
|
|
292
|
+
@write_pages[0xff] = @top_page
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def map_reads
|
|
296
|
+
@read_pages.fill(@ram_view, 0x00, 0xfd)
|
|
297
|
+
@read_pages[0x00] = @zero_page
|
|
298
|
+
map_roms if @rom_selected
|
|
299
|
+
@top_memory = @rom_selected ? @high_roms[@high_bank] || @open_bus : @ram_view
|
|
300
|
+
@read_pages[0xfd] = @io_page
|
|
301
|
+
@read_pages[0xfe] = @tcbm_page
|
|
302
|
+
@read_pages[0xff] = @top_page
|
|
303
|
+
end
|
|
304
|
+
|
|
305
|
+
def map_roms
|
|
306
|
+
@read_pages.fill(@low_roms[@low_bank] || @open_bus, 0x80, 0x40)
|
|
307
|
+
@read_pages.fill(@high_roms[@high_bank] || @open_bus, 0xc0, 0x3c)
|
|
308
|
+
@read_pages[0xfc] = @high_roms[0]
|
|
309
|
+
end
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
end
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class Plus4
|
|
5
|
+
# The 7501's I/O port at $00 (direction) and $01 (data). Its seven
|
|
6
|
+
# pins carry the serial bus and the cassette port, and none of them
|
|
7
|
+
# banks memory:
|
|
8
|
+
#
|
|
9
|
+
# - P0, P1 and P2 drive the serial bus's DATA, CLK and ATN through
|
|
10
|
+
# inverters, so a 1 pulls the line low, and P1 is the cassette write
|
|
11
|
+
# line too.
|
|
12
|
+
# - P3 runs the cassette motor while it is low.
|
|
13
|
+
# - P4 reads the cassette read line, P6 the serial CLK line and P7 the
|
|
14
|
+
# DATA line, 1 while the line is high.
|
|
15
|
+
# - P5 has no pin and reads 1.
|
|
16
|
+
#
|
|
17
|
+
# An output pin reads back what it drives. A pin left as an input reads
|
|
18
|
+
# what drives it from outside, and the serial outputs, P0-P2, float high
|
|
19
|
+
# there, so they pull their lines, as an output of 1 does.
|
|
20
|
+
class CPUPort
|
|
21
|
+
DATA_OUT = 0x01
|
|
22
|
+
CLK_OUT = 0x02
|
|
23
|
+
ATN_OUT = 0x04
|
|
24
|
+
MOTOR = 0x08
|
|
25
|
+
TAPE_READ = 0x10
|
|
26
|
+
CLK_IN = 0x40
|
|
27
|
+
DATA_IN = 0x80
|
|
28
|
+
|
|
29
|
+
attr_reader :ddr, :data
|
|
30
|
+
|
|
31
|
+
def initialize(serial_bus:, datasette:)
|
|
32
|
+
@serial_bus = serial_bus
|
|
33
|
+
@datasette = datasette
|
|
34
|
+
@ddr = 0
|
|
35
|
+
@data = 0
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def reset!
|
|
39
|
+
@ddr = 0
|
|
40
|
+
@data = 0
|
|
41
|
+
changed
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def peek(addr)
|
|
45
|
+
return @ddr if addr.zero?
|
|
46
|
+
|
|
47
|
+
(@data & @ddr) | (inputs & ~@ddr & 0xff)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def poke(addr, value)
|
|
51
|
+
if addr.zero?
|
|
52
|
+
@ddr = value
|
|
53
|
+
else
|
|
54
|
+
@data = value
|
|
55
|
+
end
|
|
56
|
+
changed
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# The pins' levels as they leave the chip, inputs floating high.
|
|
60
|
+
def levels = (@data & @ddr) | (~@ddr & 0xff)
|
|
61
|
+
|
|
62
|
+
# The serial bus lines the port pulls low, as Drives::SerialBus host
|
|
63
|
+
# lines.
|
|
64
|
+
def serial_lines
|
|
65
|
+
out = levels
|
|
66
|
+
lines = 0
|
|
67
|
+
lines |= Drives::SerialBus::HOST_ATN_OUT if out.anybits?(ATN_OUT)
|
|
68
|
+
lines |= Drives::SerialBus::HOST_CLK_OUT if out.anybits?(CLK_OUT)
|
|
69
|
+
lines |= Drives::SerialBus::HOST_DATA_OUT if out.anybits?(DATA_OUT)
|
|
70
|
+
lines
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
private
|
|
74
|
+
|
|
75
|
+
def inputs
|
|
76
|
+
value = 0x2f
|
|
77
|
+
value |= TAPE_READ if @datasette.read_high?
|
|
78
|
+
low = @serial_bus.low_lines
|
|
79
|
+
value |= CLK_IN unless low.anybits?(Drives::SerialBus::CLK)
|
|
80
|
+
value |= DATA_IN unless low.anybits?(Drives::SerialBus::DATA)
|
|
81
|
+
value
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def changed
|
|
85
|
+
lines = serial_lines
|
|
86
|
+
@serial_bus.host_lines = lines unless lines == @serial_bus.host_lines
|
|
87
|
+
out = levels
|
|
88
|
+
@datasette.motor = out.nobits?(MOTOR)
|
|
89
|
+
@datasette.write_line = out.anybits?(CLK_OUT)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class Plus4
|
|
5
|
+
# The keyboard: the 6529 at $FD30-$FD3F, whose eight outputs drive the
|
|
6
|
+
# key matrix's lines, and the TED's K0-K7 inputs, which $FF08 latches
|
|
7
|
+
# (Chips::TED#keyboard_port=). The KERNAL's scan ($DB11) writes each
|
|
8
|
+
# line's mask to $FD30 and $FF08 and reads the keys back from $FF08,
|
|
9
|
+
# and its key table at $E026 puts each key at line times 8 plus input
|
|
10
|
+
# bit.
|
|
11
|
+
#
|
|
12
|
+
# The 6529 is a quasi-bidirectional latch: a read returns what was
|
|
13
|
+
# written to it.
|
|
14
|
+
class KeyboardPort
|
|
15
|
+
# One row of keys per 6529 output, in K0-K7 order, after the
|
|
16
|
+
# KERNAL's key table. HELP is the KERNAL's F7, and the two SHIFT keys
|
|
17
|
+
# share one place.
|
|
18
|
+
MATRIX = [
|
|
19
|
+
%i[delete return £ help f1 f2 f3 @],
|
|
20
|
+
%i[3 w a 4 z s e lshift],
|
|
21
|
+
%i[5 r d 6 c f t x],
|
|
22
|
+
%i[7 y g 8 b h u v],
|
|
23
|
+
%i[9 i j 0 m k o n],
|
|
24
|
+
%i[crsr_down p l crsr_up . : - ,],
|
|
25
|
+
%i[crsr_left * ; crsr_right esc = + /],
|
|
26
|
+
%i[1 clr_home control 2 space cbm q run_stop]
|
|
27
|
+
].freeze
|
|
28
|
+
|
|
29
|
+
attr_reader :keyboard, :output
|
|
30
|
+
|
|
31
|
+
def initialize(keyboard)
|
|
32
|
+
@keyboard = keyboard
|
|
33
|
+
@output = 0xff
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def reset!
|
|
37
|
+
@output = 0xff
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def peek(_addr) = @output
|
|
41
|
+
|
|
42
|
+
def poke(_addr, value)
|
|
43
|
+
@output = value
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# The K0-K7 inputs the TED latches on a write of +_value+ to $FF08:
|
|
47
|
+
# high but where a held key joins a line the 6529 pulls low.
|
|
48
|
+
def latch(_value) = @keyboard.scan(@output, 0xff).last
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class Plus4
|
|
5
|
+
# The 264 series machines badline builds by name, after xplus4's
|
|
6
|
+
# -model names, with the C116 as another name for the C16: one board
|
|
7
|
+
# design with its RAM, its video standard and KERNAL, and whether the
|
|
8
|
+
# Plus/4's own parts are fitted (the 3-plus-1 function ROMs, the 6551
|
|
9
|
+
# ACIA and the user port's 6529).
|
|
10
|
+
module Model
|
|
11
|
+
Profile = Data.define(:name, :ram_kb, :ted, :kernal, :plus4_parts)
|
|
12
|
+
|
|
13
|
+
PLUS4 = Profile.new(name: "plus4", ram_kb: 64, ted: Chips::TED::PAL, kernal: "plus4/kernal-pal.rom",
|
|
14
|
+
plus4_parts: true)
|
|
15
|
+
PLUS4_NTSC = Profile.new(name: "plus4ntsc", ram_kb: 64, ted: Chips::TED::NTSC,
|
|
16
|
+
kernal: "plus4/kernal-ntsc.rom", plus4_parts: true)
|
|
17
|
+
C16 = Profile.new(name: "c16", ram_kb: 16, ted: Chips::TED::PAL, kernal: "plus4/kernal-pal.rom",
|
|
18
|
+
plus4_parts: false)
|
|
19
|
+
C16_NTSC = Profile.new(name: "c16ntsc", ram_kb: 16, ted: Chips::TED::NTSC, kernal: "plus4/kernal-ntsc.rom",
|
|
20
|
+
plus4_parts: false)
|
|
21
|
+
|
|
22
|
+
ALL = [PLUS4, PLUS4_NTSC, C16, C16_NTSC].freeze
|
|
23
|
+
|
|
24
|
+
# Other names a model goes by.
|
|
25
|
+
ALIASES = { "c116" => "c16" }.freeze
|
|
26
|
+
|
|
27
|
+
# The RAM sizes a machine can have, in K.
|
|
28
|
+
RAM_SIZES = [16, 32, 64].freeze
|
|
29
|
+
|
|
30
|
+
def self.named(name)
|
|
31
|
+
model = ALL.find { |candidate| candidate.name == ALIASES.fetch(name, name) }
|
|
32
|
+
raise ArgumentError, "no Plus/4 model named #{name}" if model.nil?
|
|
33
|
+
|
|
34
|
+
model
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
class Plus4
|
|
5
|
+
# The Plus/4's user port 6529 at $FD10-$FD1F, a quasi-bidirectional
|
|
6
|
+
# latch: a line reads low where the latch or the outside pulls it. With
|
|
7
|
+
# nothing plugged into the user port, the outside pulls only bit 2, the
|
|
8
|
+
# cassette sense switch, low while a key is down on the deck. The
|
|
9
|
+
# KERNAL's IRQ reads it there ($CFBF).
|
|
10
|
+
class UserPort
|
|
11
|
+
TAPE_SENSE = 0x04
|
|
12
|
+
|
|
13
|
+
attr_reader :output
|
|
14
|
+
|
|
15
|
+
def initialize(datasette)
|
|
16
|
+
@datasette = datasette
|
|
17
|
+
@output = 0xff
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def reset!
|
|
21
|
+
@output = 0xff
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def peek(_addr) = @datasette.sense_low? ? @output & ~TAPE_SENSE : @output
|
|
25
|
+
|
|
26
|
+
def poke(_addr, value)
|
|
27
|
+
@output = value
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "badline/chips/ted"
|
|
4
|
+
require "badline/chips/tia"
|
|
5
|
+
require "badline/plus4/model"
|
|
6
|
+
require "badline/plus4/cpu"
|
|
7
|
+
require "badline/plus4/cpu_port"
|
|
8
|
+
require "badline/plus4/keyboard_port"
|
|
9
|
+
require "badline/plus4/user_port"
|
|
10
|
+
require "badline/plus4/acia"
|
|
11
|
+
require "badline/plus4/bus"
|
|
12
|
+
|
|
13
|
+
module Badline
|
|
14
|
+
# The Commodore 264 series: the Plus/4, the C16 and the C116. A 7501 on
|
|
15
|
+
# the TED's clock, which runs it once or twice a TED cycle (Chips::TED's
|
|
16
|
+
# Beam), the TED and, on the Plus/4, a 6551 ACIA and the user port's
|
|
17
|
+
# 6529. Only the TED pulls IRQ, and nothing pulls NMI, which the 7501
|
|
18
|
+
# doesn't have.
|
|
19
|
+
#
|
|
20
|
+
# It runs headless only: the TED paints no picture yet. Device 8
|
|
21
|
+
# serves disks through the KERNAL traps (C64::KernalTraps), and
|
|
22
|
+
# cartridges go in cartridge 1's slots.
|
|
23
|
+
class Plus4
|
|
24
|
+
include IntegerHelper
|
|
25
|
+
include Machine::KeyboardBuffer
|
|
26
|
+
include Machine::Clocking
|
|
27
|
+
include C64::KernalTraps
|
|
28
|
+
|
|
29
|
+
# The cycle by which the KERNAL has booted and BASIC printed READY,
|
|
30
|
+
# with a margin, in TED cycles. READY is up by about 116,000 on a PAL
|
|
31
|
+
# Plus/4, 126,000 on an NTSC one and sooner on a C16.
|
|
32
|
+
INIT_THRESHOLD = 200_000
|
|
33
|
+
|
|
34
|
+
attr_reader :model, :bus, :cpu, :ted, :port, :keyboard, :keyboard_port, :acia, :user_port, :datasette, :tias,
|
|
35
|
+
:iec_bus, :cycles, :ram_kb
|
|
36
|
+
|
|
37
|
+
def family = :plus4
|
|
38
|
+
|
|
39
|
+
def init_threshold = INIT_THRESHOLD
|
|
40
|
+
|
|
41
|
+
def ram = @bus.ram
|
|
42
|
+
|
|
43
|
+
# Reads and writes memory as the CPU sees it, through the bus.
|
|
44
|
+
def peek(addr) = @bus.peek(addr)
|
|
45
|
+
|
|
46
|
+
def poke(addr, value) = @bus.poke(addr, value)
|
|
47
|
+
|
|
48
|
+
# +model+ names one of Model::ALL, or c116 for the C16, and +ram+ the
|
|
49
|
+
# RAM in K, one of Model::RAM_SIZES, when not the model's own. +tcbm+
|
|
50
|
+
# plugs in a 1551's TCBM interface, the TIAs at $FEC0-$FEFF, with no
|
|
51
|
+
# drive answering on the other side.
|
|
52
|
+
def initialize(model: "plus4", ram: nil, tcbm: false, debug: false)
|
|
53
|
+
@model = Model.named(model)
|
|
54
|
+
@ram_kb = ram || @model.ram_kb
|
|
55
|
+
raise ArgumentError, "no Plus/4 RAM size of #{@ram_kb}K" unless Model::RAM_SIZES.include?(@ram_kb)
|
|
56
|
+
|
|
57
|
+
@ted = Chips::TED.new(@model.ted)
|
|
58
|
+
@keyboard = Input::Keyboard.new(matrix: KeyboardPort::MATRIX)
|
|
59
|
+
@keyboard_port = KeyboardPort.new(@keyboard)
|
|
60
|
+
@ted.keyboard_port = @keyboard_port
|
|
61
|
+
@iec_bus = Drives::SerialBus.new
|
|
62
|
+
@datasette = Drives::Datasette.new(level: true)
|
|
63
|
+
@port = CPUPort.new(serial_bus: @iec_bus, datasette: @datasette)
|
|
64
|
+
plus4_parts = @model.plus4_parts
|
|
65
|
+
@acia = plus4_parts ? ACIA.new : nil
|
|
66
|
+
@user_port = plus4_parts ? UserPort.new(@datasette) : nil
|
|
67
|
+
io = Bus::IOPage.new(keyboard_port: @keyboard_port, acia: @acia, user_port: @user_port)
|
|
68
|
+
@bus = Bus.new(ted: @ted, port: @port, io:, model: @model, ram_kb: @ram_kb)
|
|
69
|
+
@tias = tcbm ? [Chips::TIA.new, Chips::TIA.new] : []
|
|
70
|
+
@bus.plug_tcbm(drive8: @tias[0], drive9: @tias[1]) if tcbm
|
|
71
|
+
@cpu = CPU.new(@bus, debug:)
|
|
72
|
+
@cycles = 0
|
|
73
|
+
@init_handlers = []
|
|
74
|
+
@pending_keys = nil
|
|
75
|
+
@dos = nil
|
|
76
|
+
@serial_trap = nil
|
|
77
|
+
@save_trap = nil
|
|
78
|
+
@capture_output = nil
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# One TED cycle: the TED moves on and decides the CPU's clock, then the
|
|
82
|
+
# CPU runs its cycles in it, none while the TED holds the bus.
|
|
83
|
+
def cycle!
|
|
84
|
+
handle_init if @cycles == INIT_THRESHOLD
|
|
85
|
+
feed_keyboard if @pending_keys
|
|
86
|
+
|
|
87
|
+
ted = @ted
|
|
88
|
+
ted.cycle!
|
|
89
|
+
@datasette.cycle!
|
|
90
|
+
@cpu.irq = ted.irq?
|
|
91
|
+
slots = ted.cpu_slots
|
|
92
|
+
if slots.zero?
|
|
93
|
+
@cpu.stall!
|
|
94
|
+
else
|
|
95
|
+
clock_cpu(ted)
|
|
96
|
+
clock_cpu(ted) if slots == 2
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
@cycles += 1
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# The RESET line: the CPU, the port, the 6529s, the ACIA, the bank
|
|
103
|
+
# latch and ROM selection. The TED has no reset pin.
|
|
104
|
+
def reset!
|
|
105
|
+
@port.reset!
|
|
106
|
+
@keyboard_port.reset!
|
|
107
|
+
@user_port&.reset!
|
|
108
|
+
@dos&.reset!
|
|
109
|
+
@acia&.reset!
|
|
110
|
+
@tias.each(&:reset!)
|
|
111
|
+
@bus.reset!
|
|
112
|
+
@cpu.reset!
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
# Switches the machine off and on: RAM and the TED start from their
|
|
116
|
+
# power-on state, and the RES line resets everything else.
|
|
117
|
+
def power_cycle!
|
|
118
|
+
@bus.power_on!
|
|
119
|
+
@ted.power_on!
|
|
120
|
+
reset!
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
# Calls the block with the exit code a VICE testprog writes to $FDCF.
|
|
124
|
+
def install_debug_register(&) = @bus.install_debug_register(&)
|
|
125
|
+
|
|
126
|
+
# Puts a cartridge's ROM chips in cartridge 1's slots (Bus#attach_cartridge)
|
|
127
|
+
# and switches the machine off and on, as a cartridge goes in with the
|
|
128
|
+
# power off. The KERNAL starts it at reset when it signs itself with CBM
|
|
129
|
+
# at $8007.
|
|
130
|
+
def attach_cartridge(chips)
|
|
131
|
+
@bus.attach_cartridge(chips)
|
|
132
|
+
power_cycle!
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
# Stores a PRG's bytes from its load address on, into RAM, and returns
|
|
136
|
+
# that address.
|
|
137
|
+
def load_prg(data)
|
|
138
|
+
load_addr = uint16(data[0], data[1])
|
|
139
|
+
bytes = data[2..] || []
|
|
140
|
+
bytes = bytes[0, 0x10000 - load_addr] if load_addr + bytes.length > 0x10000
|
|
141
|
+
bytes.each_with_index { |byte, i| @bus.ram_view.poke(load_addr + i, byte) }
|
|
142
|
+
load_addr
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
private
|
|
146
|
+
|
|
147
|
+
# The 264 KERNAL's keyboard buffer.
|
|
148
|
+
def keyboard_buffer = Machine::KeyboardBuffer::PLUS4_LAYOUT
|
|
149
|
+
|
|
150
|
+
# The 264 KERNAL, which the traps stand in for.
|
|
151
|
+
def trap_layout = KernalTrap::PLUS4_LAYOUT
|
|
152
|
+
|
|
153
|
+
def trap_bus = @bus
|
|
154
|
+
|
|
155
|
+
# Device 8, which the serial traps answer for, with no true drive on
|
|
156
|
+
# the bus to take it.
|
|
157
|
+
def serial_trap_device = KernalTrap::Routine::DEVICE
|
|
158
|
+
|
|
159
|
+
# BA stops the CPU at a read, and a write goes ahead.
|
|
160
|
+
def clock_cpu(ted)
|
|
161
|
+
ted.ba_low? && !@cpu.pending_write? ? @cpu.stall! : @cpu.cycle!
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|