4个版本 (2个稳定版)
1.1.0 | 2021年2月10日 |
---|---|
1.0.0 | 2020年4月8日 |
0.2.0 | 2019年10月11日 |
0.1.0 | 2019年9月24日 |
#56 在 模拟器 中
每月下载量 24次
在 3 个软件包中使用 (通过 gc_nes_core)
250KB
6.5K SLoC
emulator_6502
大家好,未来的雇主,以及搜索“6502模拟器 Rust”的人们,你们找到了我自2019年9月初开始的小型个人项目,该项目用于我在2020年冬季实习面试过程中的一个亮点。项目的目标是展示我在开发复杂系统时学习新编程语言的能力。
这是一个通用的Rust语言实现的MOS 6502模拟器,能够独立执行代码或作为6502被使用的许多系统中的一部分执行代码,包括Commodore 64、Apple II和任天堂娱乐系统。为此,该库提供了Interface6502 trait,允许客户端实现自己的函数来读取和写入内存地址。关于一个实际的实现示例,请查看我的gc_nes_emulator。
定义接口
struct BasicRam{
ram: Box<[u8; u16::max_value() as usize + 1]> //The maximum address range of the 6502
}
impl BasicRam {
fn load_program(&mut self, start: usize, data: &mut Vec<u8>){
self.ram[start..].clone_from_slice(data);
}
}
impl Interface6502 for BasicRam{
fn read(&mut self, address: u16) -> u8{
self.ram[address as usize]
}
fn write(&mut self, address: u16, data: u8){
self.ram[address as usize] = data
}
}
在这个例子中,与模拟器一起使用的接口简单地映射地址到ram位置。客户端负责将希望运行的6502二进制程序加载到地址范围内的合适部分。更复杂的接口可以将特定的地址映射到其他模拟设备组件。
例如,使用此6502模拟器的NES实现将地址0x2000-0x2007的读取和写入映射到与NES图像处理单元的通信,而Commodore 64实现将地址0xd000-0xd3ff映射到屏幕绘制。
运行程序
fn main() -> Result<()>{
let mut ram = BasicRam{ ram: Box::new([0; u16::max_value() as usize + 1]) };
//Load a program into memory...
let mut file = File::open("C:/some_6502_program.bin")?;
let mut buffer = Vec::new();
file.read_to_end(&mut buffer)?;
//Copy it into the BasicRam
ram.load_program(0x0400, &mut buffer);
let mut cpu = MOS6502::new(); //Create a new emulator instance
cpu.set_program_counter(0x0400); //Set the program counter to the first byte of the program in memory
cpu.cycle(&mut ram); // The emulator can execute cycles individually, for systems that require precise timing...
cpu.execute_instruction(&mut ram); // or instruction by instruction for a coarser approach
Ok(())
}
每个周期/指令,处理器借用了接口的可变所有权,以便读取和写入。
注意:当执行指令时,整个计算是在处理器简单地等待剩余周期数之前同时完成的,这意味着读取和写入的定时仅基于指令级别,而不是周期级别。
支持的功能
- 实现了文档化的指令集的全套
- 模拟了原始6502硬件中存在的错误
- 当启用“binary_coded_decimal”编译功能时,使用二进制编码的十进制数
- 当启用“illegal_opcodes”编译功能时,使用非法未记录的操作码
如果未启用“illegal_opcodes”编译功能而调用非法指令码,模拟器将记录警告并在适当数量的周期内运行,不改变状态。
当前版本:1.1.0
许可证:MIT
依赖项
~87KB