#instructions #simulator #read #tested #systems #cpu #computer

w65c02s

W65C02S 微处理器的周期精确、全面测试的模拟器

3 个版本

0.9.2 2020年9月2日
0.9.1 2019年8月22日
0.9.0 2019年6月8日

模拟 中排名第 78

每月下载量 27

Zlib 许可证

91KB
1.5K SLoC

这个箱子是 WDC W65C02S 的周期精确模拟器,是家用电脑革命催化剂 6502 最先进的直系后代。

此箱子准确模拟了 W65C02S 的所有总线信号(除了 RDY、SOB 和 BE,这些都可以由外部代码模拟)。它被编写成这样,通常未使用的总线逻辑会被优化掉。请确保在您的 Cargo.toml 中启用了 LTO 以获得巨大的速度提升。

[profile.release]
lto = true

此箱子不依赖于任何其他库,包括标准库。

W65C02S 指令集包括原始的 NMOS 6502 指令、所有 CMOS 6502 支持的附加指令、“Rockwell 位扩展” (BBRx/BBSx/RMBx/SMBx) 以及 WAISTP 指令。

此模拟的准确性已经在包含超过 4500 个测试的 65test 测试套件 上进行了测试。在每个测试中,模拟器的总线流量都与真实硬件完全相同——甚至到中断请求 (IRQ) 和非屏蔽中断 (NMI) 信号的时序。这意味着此模拟器适合用于使用 W65C02S 处理器的实际系统原型设计和模拟,包括基于 W65C134S MCU 的系统。

要使用它,您需要一个 W65C02S 实例和一个 System 的实现。 W65C02S 模拟 CPU;System 必须模拟连接到总线的硬件(内存、I/O 设备等)。

use w65c02s::*;

pub fn main() {
    let mut system = HelloWorldSystem::new();
    let mut cpu = W65C02S::new();
    while cpu.get_state() != State::Stopped { cpu.step(&mut system); }
}

/// A simple system with 64K of RAM, along with an output-only "serial
/// port" mapped to $0000.
struct HelloWorldSystem {
    ram: [u8; 65536],
}

impl HelloWorldSystem {
    pub fn new() -> HelloWorldSystem {
        // initialize RAM with all 0xFFs
        let mut ram = [0xFF; 65536];
        // initialize the message
        ram[0x0001..0x000F].copy_from_slice(b"Hello World!\n\0");
        // initialize the program
        ram[0x0200..0x020C].copy_from_slice(&[
            op::LDX_IMM, 0,     //   LDX #0
                                // loop:
            op::LDA_ZPX, 1,     //   LDA $01, X
            op::BNE, 1,         //   BNE +
            op::STP,            //   STP
            op::STA_ZP, 0,      // + STA $00
            op::INC_X,          //   INX
            op::BRA, 0xF6,      //   BRA loop
        ]);
        // initialize the reset vector to point to $0200
        ram[0xFFFC..0xFFFE].copy_from_slice(&[0x00, 0x02]);
        HelloWorldSystem { ram }
    }
}

impl System for HelloWorldSystem {
    fn read(&mut self, _cpu: &mut W65C02S, addr: u16) -> u8 {
        // all reads return RAM values directly
        self.ram[addr as usize]
    }
    fn write(&mut self, _cpu: &mut W65C02S, addr: u16, value: u8) {
        if addr == 0 {
            // writing address $0000 outputs on an ASCII-only "serial port"
            print!("{}", String::from_utf8_lossy(&[value]));
        }
        else {
            // all other writes write to RAM
            self.ram[addr as usize] = value
        }
    }
}

此模拟器基于原始的 ARS 模拟器

许可证

w65c02s 根据 zlib 许可证发布。完整的文本如下

版权所有 (c) 2019, Solra Bizna

此软件按“原样”提供,不提供任何明示或暗示的保证。在任何情况下,作者都不会因使用此软件而承担任何损害赔偿责任。

本软件的使用权授予任何人,用于任何目的,包括商业应用,并可自由修改和重新分发,但须遵守以下限制:

  1. 本软件的来源不得被虚假陈述;不得声称您是原始软件的作者。如果您将此软件用于产品中,产品文档中的致谢将受到欢迎,但不是必需的。
  2. 修改后的源代码版本必须清楚地标记为修改版本,并且不得被虚假陈述为原始软件。
  3. 本声明不得从任何源分发中删除或修改。

无运行时依赖。