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,141 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Chips
|
|
5
|
+
class CPU
|
|
6
|
+
module InstructionSet
|
|
7
|
+
module Transfer
|
|
8
|
+
# +begin_src ruby
|
|
9
|
+
# Load accumulator with memory.
|
|
10
|
+
#
|
|
11
|
+
# Opcodes:
|
|
12
|
+
# $A1 - indirect_x - 6 cycles
|
|
13
|
+
# $A5 - zeropage - 3 cycles
|
|
14
|
+
# $A9 - immediate - 2 cycles
|
|
15
|
+
# $AD - absolute - 4 cycles
|
|
16
|
+
# $B1 - indirect_y - 5+ cycles
|
|
17
|
+
# $B5 - zeropage_x - 4 cycles
|
|
18
|
+
# $B9 - absolute_y - 4+ cycles
|
|
19
|
+
# $BD - absolute_x - 4+ cycles
|
|
20
|
+
def lda(_addr, value)
|
|
21
|
+
@a = value
|
|
22
|
+
update_number_flags(@a)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Load X register with memory.
|
|
26
|
+
#
|
|
27
|
+
# Opcodes:
|
|
28
|
+
# $A2 - immediate - 2 cycles
|
|
29
|
+
# $A6 - zeropage - 3 cycles
|
|
30
|
+
# $AE - absolute - 4 cycles
|
|
31
|
+
# $B6 - zeropage_y - 4 cycles
|
|
32
|
+
# $BE - absolute_y - 4+ cycles
|
|
33
|
+
def ldx(_addr, value)
|
|
34
|
+
@x = value
|
|
35
|
+
update_number_flags(@x)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Load Y register with memory.
|
|
39
|
+
#
|
|
40
|
+
# Opcodes:
|
|
41
|
+
# $A0 - immediate - 2 cycles
|
|
42
|
+
# $A4 - zeropage - 3 cycles
|
|
43
|
+
# $AC - absolute - 4 cycles
|
|
44
|
+
# $B4 - zeropage_x - 4 cycles
|
|
45
|
+
# $BC - absolute_x - 4+ cycles
|
|
46
|
+
def ldy(_addr, value)
|
|
47
|
+
@y = value
|
|
48
|
+
update_number_flags(@y)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Store accumulator in memory.
|
|
52
|
+
#
|
|
53
|
+
# Opcodes:
|
|
54
|
+
# $81 - indirect_x - 6 cycles
|
|
55
|
+
# $85 - zeropage - 3 cycles
|
|
56
|
+
# $8D - absolute - 4 cycles
|
|
57
|
+
# $91 - indirect_y - 6 cycles
|
|
58
|
+
# $95 - zeropage_x - 4 cycles
|
|
59
|
+
# $99 - absolute_y - 5 cycles
|
|
60
|
+
# $9D - absolute_x - 5 cycles
|
|
61
|
+
def sta(addr, _value)
|
|
62
|
+
write_byte(addr, @a)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Store X register in memory.
|
|
66
|
+
#
|
|
67
|
+
# Opcodes:
|
|
68
|
+
# $86 - zeropage - 3 cycles
|
|
69
|
+
# $8E - absolute - 4 cycles
|
|
70
|
+
# $96 - zeropage_y - 4 cycles
|
|
71
|
+
def stx(addr, _value)
|
|
72
|
+
write_byte(addr, @x)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Store Y register in memory.
|
|
76
|
+
#
|
|
77
|
+
# Opcodes:
|
|
78
|
+
# $84 - zeropage - 3 cycles
|
|
79
|
+
# $8C - absolute - 4 cycles
|
|
80
|
+
# $94 - zeropage_x - 4 cycles
|
|
81
|
+
def sty(addr, _value)
|
|
82
|
+
write_byte(addr, @y)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Transfer accumulator to X register.
|
|
86
|
+
#
|
|
87
|
+
# Opcodes:
|
|
88
|
+
# $AA - implied - 2 cycles
|
|
89
|
+
def tax(_addr, _value)
|
|
90
|
+
@x = a
|
|
91
|
+
update_number_flags(@x)
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# Transfer accumulator to Y register.
|
|
95
|
+
#
|
|
96
|
+
# Opcodes:
|
|
97
|
+
# $A8 - implied - 2 cycles
|
|
98
|
+
def tay(_addr, _value)
|
|
99
|
+
@y = a
|
|
100
|
+
update_number_flags(@y)
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
# Transfer stack pointer to X register.
|
|
104
|
+
#
|
|
105
|
+
# Opcodes:
|
|
106
|
+
# $BA - implied - 2 cycles
|
|
107
|
+
def tsx(_addr, _value)
|
|
108
|
+
@x = stack_pointer
|
|
109
|
+
update_number_flags(@x)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Transfer X register to accumulator.
|
|
113
|
+
#
|
|
114
|
+
# Opcodes:
|
|
115
|
+
# $8A - implied - 2 cycles
|
|
116
|
+
def txa(_addr, _operand)
|
|
117
|
+
@a = x
|
|
118
|
+
update_number_flags(@a)
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# Transfer X register to stack pointer.
|
|
122
|
+
#
|
|
123
|
+
# Opcodes:
|
|
124
|
+
# $9A - implied - 2 cycles
|
|
125
|
+
def txs(_addr, _operand)
|
|
126
|
+
@stack_pointer = x
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# Transfer Y register to accumulator.
|
|
130
|
+
#
|
|
131
|
+
# Opcodes:
|
|
132
|
+
# $98 - implied - 2 cycles
|
|
133
|
+
def tya(_addr, _operand)
|
|
134
|
+
@a = y
|
|
135
|
+
update_number_flags(@a)
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "badline/chips/cpu/instruction_set/arithmetic"
|
|
4
|
+
require "badline/chips/cpu/instruction_set/bitwise"
|
|
5
|
+
require "badline/chips/cpu/instruction_set/branch"
|
|
6
|
+
require "badline/chips/cpu/instruction_set/inc_dec"
|
|
7
|
+
require "badline/chips/cpu/instruction_set/flag"
|
|
8
|
+
require "badline/chips/cpu/instruction_set/illegal"
|
|
9
|
+
require "badline/chips/cpu/instruction_set/stack"
|
|
10
|
+
require "badline/chips/cpu/instruction_set/transfer"
|
|
11
|
+
|
|
12
|
+
module Badline
|
|
13
|
+
module Chips
|
|
14
|
+
class CPU
|
|
15
|
+
# http://www.6502.org/tutorials/6502opcodes.html
|
|
16
|
+
# http://www.e-tradition.net/bytes/6502/6502_instruction_set.html
|
|
17
|
+
module InstructionSet
|
|
18
|
+
include InstructionSet::Arithmetic
|
|
19
|
+
include InstructionSet::Bitwise
|
|
20
|
+
include InstructionSet::Branch
|
|
21
|
+
include InstructionSet::IncDec
|
|
22
|
+
include InstructionSet::Flag
|
|
23
|
+
include InstructionSet::Illegal
|
|
24
|
+
include InstructionSet::Stack
|
|
25
|
+
include InstructionSet::Transfer
|
|
26
|
+
|
|
27
|
+
# No operation. The illegal forms with an operand still read it, in
|
|
28
|
+
# the steps before this is called.
|
|
29
|
+
#
|
|
30
|
+
# Opcodes:
|
|
31
|
+
# $EA - implied - 2 cycles
|
|
32
|
+
# $04, $44, $64 - zeropage - 3 cycles (illegal)
|
|
33
|
+
# $14, $34, $54, $74, $D4, $F4 - zeropage_x - 4 cycles (illegal)
|
|
34
|
+
# $0C - absolute - 4 cycles (illegal)
|
|
35
|
+
# $1C, $3C, $5C, $7C, $DC, $FC - absolute_x - 4+ cycles (illegal)
|
|
36
|
+
# $1A, $3A, $5A, $7A, $DA, $FA - implied - 2 cycles (illegal)
|
|
37
|
+
def nop(_addr, _value); end
|
|
38
|
+
|
|
39
|
+
private
|
|
40
|
+
|
|
41
|
+
def update_number_flags(value)
|
|
42
|
+
status.zero = value.zero?
|
|
43
|
+
status.negative = value & 0x80 != 0
|
|
44
|
+
value
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Stores a read-modify-write result. For memory, the write happens in
|
|
48
|
+
# the steps that follow (see Operations#op_rmw_read).
|
|
49
|
+
def write_modified(addr, result)
|
|
50
|
+
if addr == :accumulator
|
|
51
|
+
@a = result
|
|
52
|
+
else
|
|
53
|
+
@rmw_result = result
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Chips
|
|
5
|
+
class CPU
|
|
6
|
+
module Interrupts
|
|
7
|
+
BREAK_MASK = 0x10
|
|
8
|
+
|
|
9
|
+
private
|
|
10
|
+
|
|
11
|
+
# Samples the IRQ line and the NMI latch once per cycle. An instruction
|
|
12
|
+
# boundary commits the sample taken on its second-to-last cycle.
|
|
13
|
+
def poll
|
|
14
|
+
if @skip_poll
|
|
15
|
+
@skip_poll = false
|
|
16
|
+
return
|
|
17
|
+
end
|
|
18
|
+
@irq_pending = @irq_sample
|
|
19
|
+
@nmi_pending = @nmi_sample
|
|
20
|
+
@irq_sample = @irq && !@status.interrupt?
|
|
21
|
+
@nmi_sample = @nmi
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# A cycle the VIC stalls through BA keeps sampling the lines, OR-ed with
|
|
25
|
+
# the sample it already holds, but the boundary pipeline doesn't advance
|
|
26
|
+
# and a skipped poll stays owed to the next real cycle.
|
|
27
|
+
def sample_while_stalled
|
|
28
|
+
@irq_sample ||= @irq && !interrupt_disabled_after_stall?
|
|
29
|
+
@nmi_sample = true if @nmi
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# A stalled CLI or SEI execute cycle masks with the I it is about to
|
|
33
|
+
# set. Every other step masks with the current I, PLP included: its
|
|
34
|
+
# pulled I only arrives with the stalled stack read.
|
|
35
|
+
def interrupt_disabled_after_stall?
|
|
36
|
+
return @status.interrupt? unless @plan.equal?(CPU::IMPLIED_PLAN)
|
|
37
|
+
|
|
38
|
+
case @operation
|
|
39
|
+
when :cli then false
|
|
40
|
+
when :sei then true
|
|
41
|
+
else @status.interrupt?
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
# Runs in the opcode fetch cycle in place of the fetch, with no bus
|
|
46
|
+
# access, and switches to the interrupt plan.
|
|
47
|
+
def start_interrupt
|
|
48
|
+
@interrupt = @boundary_nmi ? 0xfffa : 0xfffe
|
|
49
|
+
@brk = false
|
|
50
|
+
@plan = CPU::INTERRUPT_PLAN
|
|
51
|
+
@writes = CPU::INTERRUPT_WRITES
|
|
52
|
+
@index = 1
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# BRK reads the byte after its opcode and ignores it, and selects the
|
|
56
|
+
# IRQ vector.
|
|
57
|
+
def op_brk_dummy
|
|
58
|
+
@memory.peek(@program_counter)
|
|
59
|
+
@interrupt = 0xfffe
|
|
60
|
+
@brk = true
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def op_int_push_pch
|
|
64
|
+
@address = @brk ? (@program_counter + 1) & 0xffff : @program_counter
|
|
65
|
+
@memory.poke(stack_address, high_byte(@address))
|
|
66
|
+
@stack_pointer = (@stack_pointer - 1) & 0xff
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def op_int_push_pcl
|
|
70
|
+
@memory.poke(stack_address, low_byte(@address))
|
|
71
|
+
@stack_pointer = (@stack_pointer - 1) & 0xff
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def op_int_push_status
|
|
75
|
+
value = @brk ? @status.value | BREAK_MASK : @status.value & ~BREAK_MASK
|
|
76
|
+
@memory.poke(stack_address, value)
|
|
77
|
+
@stack_pointer = (@stack_pointer - 1) & 0xff
|
|
78
|
+
@status.interrupt = true
|
|
79
|
+
# An NMI that arrives before cycle 4 of a BRK or IRQ takes it over:
|
|
80
|
+
# the sequence finishes with the NMI vector.
|
|
81
|
+
@interrupt = 0xfffa if @interrupt == 0xfffe && @nmi_pending
|
|
82
|
+
@nmi = false if @interrupt == 0xfffa
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def op_int_vector_low
|
|
86
|
+
@address = @memory.peek(@interrupt)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Clears any interrupt that is pending, so the handler's first
|
|
90
|
+
# instruction always runs before the next interrupt. This applies to
|
|
91
|
+
# BRK too.
|
|
92
|
+
def op_int_vector_high
|
|
93
|
+
high = @memory.peek((@interrupt + 1) & 0xffff)
|
|
94
|
+
@program_counter = @address | (high << 8)
|
|
95
|
+
@irq_sample = @irq_pending = false
|
|
96
|
+
@nmi_sample = @nmi_pending = false
|
|
97
|
+
@interrupt = nil
|
|
98
|
+
if @brk
|
|
99
|
+
@status.break = false
|
|
100
|
+
end_instruction
|
|
101
|
+
else
|
|
102
|
+
end_sequence
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
end
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Chips
|
|
5
|
+
class CPU
|
|
6
|
+
# Where a CPU caught inside an instruction is, as a snapshot names it:
|
|
7
|
+
# an opcode's instruction, an IRQ or NMI sequence, or jammed.
|
|
8
|
+
POSITIONS = %w[boundary op interrupt jam].freeze
|
|
9
|
+
|
|
10
|
+
# The CPU's fields in a keyed snapshot module (Snapshot::Keyed): the
|
|
11
|
+
# registers, the interrupt lines' pipeline, the counts and, inside an
|
|
12
|
+
# instruction, where it is in hardware terms (pos.*), rather than as
|
|
13
|
+
# the microcode lays it out.
|
|
14
|
+
module KeyedState
|
|
15
|
+
def save_fields(out)
|
|
16
|
+
out.int("pc", @program_counter).int("sp", @stack_pointer).int("a", @a).int("x", @x).int("y", @y)
|
|
17
|
+
out.int("p", @status.value).bool("nmi", @nmi).bool("so_high", @so_high)
|
|
18
|
+
out.bool("irq.sample", @irq_sample).bool("irq.pending", @irq_pending).bool("irq.boundary", @boundary_irq)
|
|
19
|
+
out.bool("nmi.sample", @nmi_sample).bool("nmi.pending", @nmi_pending).bool("nmi.boundary", @boundary_nmi)
|
|
20
|
+
out.bool("skip_poll", @skip_poll).optional_int("stalled", stalled_ago)
|
|
21
|
+
out.int("cycles", @cycles).int("instructions", @instructions)
|
|
22
|
+
save_position(out) unless boundary?
|
|
23
|
+
out
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def load_fields(input)
|
|
27
|
+
@program_counter = input.word("pc", @program_counter)
|
|
28
|
+
@stack_pointer = input.byte("sp", @stack_pointer)
|
|
29
|
+
@a = input.byte("a", @a)
|
|
30
|
+
@x = input.byte("x", @x)
|
|
31
|
+
@y = input.byte("y", @y)
|
|
32
|
+
@status.value = input.byte("p", @status.value)
|
|
33
|
+
load_lines(input)
|
|
34
|
+
@cycles = input.int("cycles", @cycles)
|
|
35
|
+
@instructions = input.int("instructions", @instructions)
|
|
36
|
+
stalled = input.optional_int("stalled")
|
|
37
|
+
@stalled_at = stalled.nil? ? nil : @cycles - stalled
|
|
38
|
+
load_position(input)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# What the fields leave to be worked out: whether the next step
|
|
42
|
+
# writes.
|
|
43
|
+
def restored!
|
|
44
|
+
@pending_write = @writes[@index]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
# Cycles since the CPU last stalled, when that was this cycle or the
|
|
50
|
+
# one before, the only ones an instruction looks back at.
|
|
51
|
+
def stalled_ago
|
|
52
|
+
stalled_at = @stalled_at
|
|
53
|
+
return nil if stalled_at.nil?
|
|
54
|
+
|
|
55
|
+
ago = @cycles - stalled_at
|
|
56
|
+
ago.between?(0, 1) ? ago : nil
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def load_lines(input)
|
|
60
|
+
@nmi = input.bool("nmi", @nmi)
|
|
61
|
+
@so_high = input.bool("so_high", @so_high)
|
|
62
|
+
@irq_sample = input.bool("irq.sample", @irq_sample)
|
|
63
|
+
@irq_pending = input.bool("irq.pending", @irq_pending)
|
|
64
|
+
@boundary_irq = input.bool("irq.boundary", @boundary_irq)
|
|
65
|
+
@nmi_sample = input.bool("nmi.sample", @nmi_sample)
|
|
66
|
+
@nmi_pending = input.bool("nmi.pending", @nmi_pending)
|
|
67
|
+
@boundary_nmi = input.bool("nmi.boundary", @boundary_nmi)
|
|
68
|
+
@skip_poll = input.bool("skip_poll", @skip_poll)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def save_position(out)
|
|
72
|
+
source = plan_source
|
|
73
|
+
if source == JAMMED
|
|
74
|
+
out.text("pos.seq", "jam")
|
|
75
|
+
return
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
out.text("pos.seq", source == INTERRUPT ? "interrupt" : "op")
|
|
79
|
+
out.int("pos.op", source) unless source == INTERRUPT
|
|
80
|
+
out.int("pos.t", position_t(source)).bool("pos.crossed", @boundary_crossed)
|
|
81
|
+
out.bool("pos.branch_taken", @branch_taken == true).bool("pos.brk", @brk)
|
|
82
|
+
out.optional_int("pos.vector", @interrupt)
|
|
83
|
+
out.optional_int("pos.address", @address).optional_int("pos.dummy_address", @dummy_address)
|
|
84
|
+
out.optional_int("pos.value", @value).optional_int("pos.rmw", @rmw_result)
|
|
85
|
+
out.optional_int("pos.pointer", @pointer)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# The cycles of the instruction or sequence run so far, counting the
|
|
89
|
+
# opcode fetch as 1 and leaving out stalled cycles.
|
|
90
|
+
def position_t(source)
|
|
91
|
+
return @index if source == INTERRUPT
|
|
92
|
+
|
|
93
|
+
MICROCODE.fetch(source).t_at(@index, @boundary_crossed)
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def load_position(input)
|
|
97
|
+
case input.choice("pos.seq", POSITIONS, "boundary")
|
|
98
|
+
when "op" then load_instruction(input)
|
|
99
|
+
when "interrupt" then load_interrupt(input)
|
|
100
|
+
when "jam" then load_jam
|
|
101
|
+
else load_boundary
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def load_instruction(input)
|
|
106
|
+
micro = MICROCODE.fetch(input.byte("pos.op", 0xea))
|
|
107
|
+
use_plan(micro.plan, micro.writes)
|
|
108
|
+
@operation = micro.operation
|
|
109
|
+
@optional_dummy = micro.optional_dummy
|
|
110
|
+
@boundary_crossed = input.bool("pos.crossed", false)
|
|
111
|
+
@index = micro.index_at(input.int("pos.t", 1), @boundary_crossed).clamp(1, micro.plan.length - 1)
|
|
112
|
+
load_latches(input)
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def load_interrupt(input)
|
|
116
|
+
use_plan(INTERRUPT_PLAN, INTERRUPT_WRITES)
|
|
117
|
+
@boundary_crossed = input.bool("pos.crossed", false)
|
|
118
|
+
@index = input.int("pos.t", 1).clamp(1, INTERRUPT_PLAN.length - 1)
|
|
119
|
+
load_latches(input)
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def load_jam
|
|
123
|
+
use_plan(JAMMED_PLAN, JAMMED_WRITES)
|
|
124
|
+
@index = 0
|
|
125
|
+
clear_latches
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
def load_boundary
|
|
129
|
+
use_plan(FETCH_PLAN, FETCH_WRITES)
|
|
130
|
+
@index = 0
|
|
131
|
+
clear_latches
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def load_latches(input)
|
|
135
|
+
@branch_taken = input.bool("pos.branch_taken", false)
|
|
136
|
+
@brk = input.bool("pos.brk", false)
|
|
137
|
+
@interrupt = input.optional_int("pos.vector")
|
|
138
|
+
@address = input.optional_int("pos.address")
|
|
139
|
+
@dummy_address = input.optional_int("pos.dummy_address")
|
|
140
|
+
@value = input.optional_int("pos.value")
|
|
141
|
+
@rmw_result = input.optional_int("pos.rmw")
|
|
142
|
+
@pointer = input.optional_int("pos.pointer")
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# The working registers no step reads before the next instruction
|
|
146
|
+
# sets them.
|
|
147
|
+
def clear_latches
|
|
148
|
+
@boundary_crossed = false
|
|
149
|
+
@branch_taken = false
|
|
150
|
+
@brk = false
|
|
151
|
+
@interrupt = nil
|
|
152
|
+
@address = nil
|
|
153
|
+
@dummy_address = nil
|
|
154
|
+
@value = nil
|
|
155
|
+
@rmw_result = nil
|
|
156
|
+
@pointer = nil
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
# Where the plan running comes from: an opcode's microcode, or FETCH,
|
|
160
|
+
# INTERRUPT or JAMMED below it.
|
|
161
|
+
def plan_source
|
|
162
|
+
return FETCH if @plan.equal?(FETCH_PLAN)
|
|
163
|
+
return INTERRUPT if @plan.equal?(INTERRUPT_PLAN)
|
|
164
|
+
return JAMMED if @plan.equal?(JAMMED_PLAN)
|
|
165
|
+
|
|
166
|
+
MICROCODE.index { |micro| micro.plan.equal?(@plan) && micro.operation == @operation } ||
|
|
167
|
+
MICROCODE.index { |micro| micro.plan.equal?(@plan) }
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def use_plan(plan, writes)
|
|
171
|
+
@plan = plan
|
|
172
|
+
@writes = writes
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
end
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Badline
|
|
4
|
+
module Chips
|
|
5
|
+
class CPU
|
|
6
|
+
class InvalidOpcodeError < StandardError; end
|
|
7
|
+
|
|
8
|
+
# Steps that write to memory. The CPU keeps running through BA on
|
|
9
|
+
# cycles that write, so C64#cycle! asks before each cycle whether
|
|
10
|
+
# the next step is one of these.
|
|
11
|
+
WRITE_STEPS = %i[
|
|
12
|
+
op_mem_write op_rmw_write_original op_rmw_write_result op_push_exec op_jsr_push_high op_jsr_push_low
|
|
13
|
+
op_int_push_pch op_int_push_pcl op_int_push_status
|
|
14
|
+
].freeze
|
|
15
|
+
|
|
16
|
+
# The steps each addressing mode takes to work out the address an
|
|
17
|
+
# instruction operates on. They run after the opcode fetch.
|
|
18
|
+
ADDRESSING_STEPS = {
|
|
19
|
+
zeropage: %i[op_zp],
|
|
20
|
+
zeropage_x: %i[op_zp op_zp_x],
|
|
21
|
+
zeropage_y: %i[op_zp op_zp_y],
|
|
22
|
+
absolute: %i[op_abs_low op_abs_high],
|
|
23
|
+
absolute_x: %i[op_abs_low op_abs_high_x op_idx_dummy],
|
|
24
|
+
absolute_y: %i[op_abs_low op_abs_high_y op_idx_dummy],
|
|
25
|
+
indirect_x: %i[op_zp_pointer op_pointer_x op_pointer_low op_pointer_high],
|
|
26
|
+
indirect_y: %i[op_zp_pointer op_pointer_low op_pointer_high_y op_idx_dummy]
|
|
27
|
+
}.freeze
|
|
28
|
+
|
|
29
|
+
# The steps that read or write that address, once it is known.
|
|
30
|
+
OPERATION_STEPS = {
|
|
31
|
+
read: %i[op_mem_read],
|
|
32
|
+
write: %i[op_mem_write],
|
|
33
|
+
rmw: %i[op_rmw_read op_rmw_write_original op_rmw_write_result]
|
|
34
|
+
}.freeze
|
|
35
|
+
|
|
36
|
+
STORES = %i[sta stx sty sax sha shx shy tas].freeze
|
|
37
|
+
READ_MODIFY_WRITES = %i[asl lsr rol ror inc dec slo sre rla rra isc dcp].freeze
|
|
38
|
+
BRANCHES = %i[bcc bcs beq bmi bne bpl bvc bvs].freeze
|
|
39
|
+
|
|
40
|
+
# The addresses a 6502 reads after a JAM opcode, before it settles into
|
|
41
|
+
# JAMMED_PLAN.
|
|
42
|
+
JAM_ADDRESSES = [0xffff, 0xfffe, 0xfffe].freeze
|
|
43
|
+
|
|
44
|
+
# The plan between instructions: the next cycle fetches an opcode.
|
|
45
|
+
FETCH_PLAN = %i[op_fetch].freeze
|
|
46
|
+
|
|
47
|
+
IMPLIED_PLAN = %i[op_fetch op_implied_exec].freeze
|
|
48
|
+
ACCUMULATOR_PLAN = %i[op_fetch op_accumulator_exec].freeze
|
|
49
|
+
IMMEDIATE_PLAN = %i[op_fetch op_immediate_read].freeze
|
|
50
|
+
|
|
51
|
+
# $10, $30, $50, $70, $90, $B0, $D0, $F0 - relative - 2+ cycles.
|
|
52
|
+
# A branch that is not taken takes 2 cycles. A taken branch takes 3,
|
|
53
|
+
# or 4 when the target is on another page.
|
|
54
|
+
BRANCH_PLAN = %i[op_fetch op_relative op_branch op_branch_fixup].freeze
|
|
55
|
+
|
|
56
|
+
# $4C - absolute - 3 cycles
|
|
57
|
+
JMP_ABSOLUTE_PLAN = %i[op_fetch op_abs_low op_jmp_high].freeze
|
|
58
|
+
|
|
59
|
+
# $6C - indirect - 5 cycles
|
|
60
|
+
JMP_INDIRECT_PLAN = %i[op_fetch op_abs_low op_abs_high op_indirect_low op_indirect_high].freeze
|
|
61
|
+
|
|
62
|
+
# $20 - absolute - 6 cycles
|
|
63
|
+
JSR_PLAN = %i[op_fetch op_jsr_low op_jsr_dummy op_jsr_push_high op_jsr_push_low op_jsr_high].freeze
|
|
64
|
+
|
|
65
|
+
# $60 - implied - 6 cycles
|
|
66
|
+
RTS_PLAN = %i[op_fetch op_implied_dummy op_pull_dummy op_pull_low op_pull_high op_rts_fixup].freeze
|
|
67
|
+
|
|
68
|
+
# $40 - implied - 6 cycles
|
|
69
|
+
RTI_PLAN = %i[op_fetch op_implied_dummy op_pull_dummy op_rti_pull_status op_pull_low op_rti_pull_high].freeze
|
|
70
|
+
|
|
71
|
+
# $08, $48 - implied - 3 cycles
|
|
72
|
+
PUSH_PLAN = %i[op_fetch op_implied_dummy op_push_exec].freeze
|
|
73
|
+
|
|
74
|
+
# $28, $68 - implied - 4 cycles
|
|
75
|
+
PULL_PLAN = %i[op_fetch op_implied_dummy op_pull_dummy op_pull_exec].freeze
|
|
76
|
+
|
|
77
|
+
# $02, $12, $22, $32, $42, $52, $62, $72, $92, $B2, $D2, $F2 - illegal
|
|
78
|
+
JAM_PLAN = [:op_fetch, :op_implied_dummy, *Array.new(JAM_ADDRESSES.length, :op_jam)].freeze
|
|
79
|
+
|
|
80
|
+
# A jammed CPU reads $FFFF on every cycle until reset. It never reaches
|
|
81
|
+
# an instruction boundary, so a pending IRQ or NMI never starts.
|
|
82
|
+
JAMMED_PLAN = %i[op_jammed].freeze
|
|
83
|
+
|
|
84
|
+
# BRK and hardware interrupts push the return address and status, then
|
|
85
|
+
# read the new PC from a vector. Only the second step differs: BRK's
|
|
86
|
+
# selects the IRQ vector and sets the break flag it pushes.
|
|
87
|
+
#
|
|
88
|
+
# $00 - implied - 7 cycles (BRK)
|
|
89
|
+
INTERRUPT_PLAN = %i[
|
|
90
|
+
op_fetch op_implied_dummy op_int_push_pch op_int_push_pcl op_int_push_status
|
|
91
|
+
op_int_vector_low op_int_vector_high
|
|
92
|
+
].freeze
|
|
93
|
+
BRK_PLAN = %i[
|
|
94
|
+
op_fetch op_brk_dummy op_int_push_pch op_int_push_pcl op_int_push_status
|
|
95
|
+
op_int_vector_low op_int_vector_high
|
|
96
|
+
].freeze
|
|
97
|
+
|
|
98
|
+
SPECIAL_PLANS = {
|
|
99
|
+
brk: BRK_PLAN, jam: JAM_PLAN, jsr: JSR_PLAN, rts: RTS_PLAN,
|
|
100
|
+
rti: RTI_PLAN, pha: PUSH_PLAN, php: PUSH_PLAN,
|
|
101
|
+
pla: PULL_PLAN, plp: PULL_PLAN
|
|
102
|
+
}.freeze
|
|
103
|
+
|
|
104
|
+
# Everything the CPU needs to run one opcode:
|
|
105
|
+
# - +operation+: the instruction method to call, such as :lda
|
|
106
|
+
# - +plan+: the step to run on each cycle
|
|
107
|
+
# - +writes+: which of those steps write to memory
|
|
108
|
+
# - +optional_dummy+: true for indexed reads, which skip the extra
|
|
109
|
+
# cycle unless indexing crosses a page
|
|
110
|
+
Microcode = Struct.new(:operation, :plan, :writes, :optional_dummy) do
|
|
111
|
+
def self.table
|
|
112
|
+
Array.new(256) do |opcode|
|
|
113
|
+
instruction = Instruction.find(opcode)
|
|
114
|
+
raise InvalidOpcodeError, format("$%02x", opcode) unless instruction
|
|
115
|
+
|
|
116
|
+
build(instruction)
|
|
117
|
+
end.freeze
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# The plan step that follows `cycles` cycles of the instruction, counting
|
|
121
|
+
# the opcode fetch as 1: one further on once an indexed read has
|
|
122
|
+
# skipped its dummy read, which it does when the index add didn't
|
|
123
|
+
# cross a page.
|
|
124
|
+
def index_at(cycles, crossed) = skips_dummy?(cycles, crossed) ? cycles + 1 : cycles
|
|
125
|
+
|
|
126
|
+
# The cycles run before plan step `index`, as index_at counts them.
|
|
127
|
+
def t_at(index, crossed) = skips_dummy?(index - 1, crossed) ? index - 1 : index
|
|
128
|
+
|
|
129
|
+
def skips_dummy?(cycles, crossed)
|
|
130
|
+
return false unless optional_dummy && !crossed
|
|
131
|
+
|
|
132
|
+
dummy = plan.index(:op_idx_dummy)
|
|
133
|
+
!dummy.nil? && cycles >= dummy
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def self.write_mask(plan)
|
|
137
|
+
plan.map { |step| WRITE_STEPS.include?(step) }.freeze
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def self.build(instruction)
|
|
141
|
+
plan = plan_for(instruction)
|
|
142
|
+
new(instruction.name, plan, write_mask(plan),
|
|
143
|
+
instruction.boundary_cycle?)
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def self.plan_for(instruction)
|
|
147
|
+
case instruction.name
|
|
148
|
+
when :jmp
|
|
149
|
+
if instruction.addressing_mode == :indirect
|
|
150
|
+
JMP_INDIRECT_PLAN
|
|
151
|
+
else
|
|
152
|
+
JMP_ABSOLUTE_PLAN
|
|
153
|
+
end
|
|
154
|
+
when *BRANCHES then BRANCH_PLAN
|
|
155
|
+
else SPECIAL_PLANS[instruction.name] || addressed_plan(instruction)
|
|
156
|
+
end
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def self.addressed_plan(instruction)
|
|
160
|
+
mode = instruction.addressing_mode
|
|
161
|
+
case mode
|
|
162
|
+
when :implied then IMPLIED_PLAN
|
|
163
|
+
when :accumulator then ACCUMULATOR_PLAN
|
|
164
|
+
when :immediate then IMMEDIATE_PLAN
|
|
165
|
+
else
|
|
166
|
+
[:op_fetch, *ADDRESSING_STEPS.fetch(mode),
|
|
167
|
+
*OPERATION_STEPS.fetch(operation_kind(instruction.name))].freeze
|
|
168
|
+
end
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def self.operation_kind(name)
|
|
172
|
+
return :write if STORES.include?(name)
|
|
173
|
+
return :rmw if READ_MODIFY_WRITES.include?(name)
|
|
174
|
+
|
|
175
|
+
:read
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
private_class_method :build, :plan_for, :addressed_plan, :operation_kind
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
FETCH_WRITES = Microcode.write_mask(FETCH_PLAN)
|
|
182
|
+
INTERRUPT_WRITES = Microcode.write_mask(INTERRUPT_PLAN)
|
|
183
|
+
JAMMED_WRITES = Microcode.write_mask(JAMMED_PLAN)
|
|
184
|
+
MICROCODE = Microcode.table
|
|
185
|
+
|
|
186
|
+
# The instruction methods, in a fixed order a snapshot names them by.
|
|
187
|
+
OPERATIONS = MICROCODE.map(&:operation).uniq.freeze
|
|
188
|
+
|
|
189
|
+
# The plans a snapshot names that aren't an opcode's.
|
|
190
|
+
FETCH = -1
|
|
191
|
+
INTERRUPT = -2
|
|
192
|
+
JAMMED = -3
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
end
|