1 个不稳定版本
0.8.0 | 2019年5月6日 |
---|
在 模拟器 中排名 379
每月下载量 25
被 4 个crate使用(2个直接使用)
25KB
517 行
Zinc64
** 注意:zinc64 包已重命名为 zinc64-emu **
概述
zinc64 是一个带有“电池”的 Commodore 64 模拟器工具包,但可以更换。它设计为作为独立模拟器或用于构建新模拟器的库。设计理念允许每个组件可以替换为不同的实现。因此,对芯片之间的交互进行了特殊考虑,以避免它们之间的耦合。
它实现了 MOS 6510 CPU、MOS 6526 CIA、MOS 6581 SID、MOS 6567/6569 VIC 芯片组以及与 C64 一起提供的各种设备和外围设备。
故事
zinc64 是作为学习 Rust 和更详细地探索 Commodore 64 硬件的练习开始的。大约在 2016 年中旬,为了满足我的 8 位怀旧之情,我购买了一台可工作的 Commodore 64(实体版本),并开始组装各种将软件加载到其上的所需配件。不久,我就买到了一本 C64 程序员参考指南,其余的就是历史了。
2019 年带来了对修订的 SDL 端口的支持,包括控制台支持和裸机环境,更具体地说是一个裸机 Raspberry Pi 3 端口。请参阅 zinc64-rpi 以获取早期预览。
设计
特性 std
zinc64-emu crate 无需标准库即可运行,例如在裸机环境中。要在 #[no_std] 环境中使用 zinc64-emu,请使用
[dependencies]
zinc64-emu = { version = "0.8.0", default-features = false }
可扩展性
可以通过提供自定义 core::ChipFactory trait 实现来替换模拟器组件。core::ChipFactory trait 的默认实现是通过 system::C64Factory 完成的。芯片工厂对象传递给 system::C64 组件,该组件提供核心模拟器功能。
以下是一个如何一起使用这些组件的示例
let config = Rc::new(Config::new(SystemModel::from("pal")));
let chip_factory = Box::new(C64Factory::new(config.clone()));
let mut c64 = C64::new(config.clone(), chip_factory).unwrap();
c64.reset(true);
用于模拟系统操作的四个核心特质是 Chip、Cpu、Mmu 和 Addressable。
/// A chip represents a system component that is driven by clock signal.
pub trait Chip {
/// The core method of the chip, emulates one clock cycle of the chip.
fn clock(&mut self);
/// Process delta cycles at once.
fn clock_delta(&mut self, delta: u32);
/// Handle vsync event.
fn process_vsync(&mut self);
/// Handle reset signal.
fn reset(&mut self);
// I/O
/// Read value from the specified register.
fn read(&mut self, reg: u8) -> u8;
/// Write value to the specified register.
fn write(&mut self, reg: u8, value: u8);
}
/// CPU is responsible for decoding and executing instructions.
pub trait Cpu {
...
/// The core method of the cpu, decodes and executes one instruction. Tick callback is invoked
/// for each elapsed clock cycle.
fn step(&mut self, tick_fn: &TickFn);
// I/O
/// Read byte from the specified address.
fn read(&self, address: u16) -> u8;
/// Write byte to the specified address.
fn write(&mut self, address: u16, value: u8);
}
/// Represents memory management unit which controls visible memory banks
/// and is used by CPU to read from and write to memory locations.
pub trait Mmu {
/// Change bank configuration based on the specified mode.
fn switch_banks(&mut self, mode: u8);
// I/O
/// Read byte from the specified address.
fn read(&self, address: u16) -> u8;
/// Write byte to the specified address.
fn write(&mut self, address: u16, value: u8);
}
/// Addressable represents a bank of memory.
pub trait Addressable {
/// Read byte from the specified address.
fn read(&self, address: u16) -> u8;
/// Write byte to the specified address.
fn write(&mut self, address: u16, value: u8);
}
由于除 Cpu 和 Mmu 之外的所有系统组件都实现了 Chip 特质,因此芯片与其他组件之间的交互仅限于通过提供给芯片构造函数的共享 I/O 线/引脚来处理。这允许芯片的实现相互解耦。
状态
类别 | 组件 | 状态 |
---|---|---|
芯片组 | 6510 CPU | 完成 |
芯片组 | 内存 | 完成 |
芯片组 | 6526 CIA | 完成 |
芯片组 | 6581 SID | 完成 |
芯片组 | 6567 VIC | 完成 |
设备 | 卡带 | 完成 |
设备 | 软盘 | 未开始 |
设备 | 数据磁带 | 完成 |
设备 | 键盘 | 完成 |
设备 | 游戏手柄 | 完成 |
设备 | 鼠标 | 未开始 |
调试器 | 远程 | 完成 |
调试器 | Radare2 | 完成 |
格式 | 二进制 | 完成 |
格式 | Crt | 完成 |
格式 | D64 | 未开始 |
格式 | P00 | 完成 |
格式 | Prg | 完成 |
格式 | Tap | 完成 |
格式 | T64 | 未开始 |
客户端 | SDL | 进行中 |
客户端 | Raspi3 | 进行中 |
路线图
- v0.9 - rpi端口
- v0.10 - 软盘支持
入门指南
-
安装Rust编译器或按照以下步骤操作:https://www.rust-lang.net.cn/en-US/install.html。
curl https://sh.rustup.rs -sSf | sh
-
克隆此存储库。
git clone https://github.com/digitalstreamio/zinc64
或下载zip存档
https://github.com/digitalstreamio/zinc64/archive/master.zip
-
构建模拟器。
cd zinc64 cargo build --release --all
-
运行模拟器。
./target/release/zinc64
或启动程序
./target/release/zinc64 --autostart path
Windows注意事项
-
安装Microsoft Visual C++ Build Tools 2017。选择Visual C++构建工具工作负载。
-
安装SDL2开发库。
-
从
SDL2-devel-2.0.x-VC\SDL2-2.0.x\lib\x64\
复制所有SDL2库文件到
C:\Users\{Your Username}\.rustup\toolchains\stable-x86_64-pc-windows-msvc\lib\rustlib\x86_64-pc-windows-msvc\lib
-
从
SDL2-devel-2.0.x-VC\SDL2-2.0.x\lib\x64\
将SDL2.dll复制到zinc64项目目录
调试器
要启动调试器,使用'-d'或'--debug'选项运行模拟器。可选地,您可以指定'--debugaddress'以绑定到特定地址。
./target/release/zinc64 --debug
要连接到调试器,使用telnet连接到调试器使用的地址和端口。
telnet localhost 9999
调试器命令和语法模仿Vice模拟器。要查看可用命令列表,在调试会话中输入
help
或要获取特定命令的帮助
help <command>
Radare2
从版本0.3开始支持radare2已被合并。要启动带有RAP服务器支持的模拟器,运行
./target/release/zinc64 --rap 127.0.0.1:9999
并使用
radare2 -a 6502 -d rap://localhost:9999/1
示例
我包含了一些来自Kick汇编器的示例,我使用这些示例来测试模拟器的各个组件。它们位于此存储库的bin文件夹中,可以使用模拟器的自动启动选项启动。
./target/release/zinc64 --autostart bin/SineAndGraphics.prg
程序 | 状态 |
---|---|
6502_functional_test.bin | 通过 |
FloydSteinberg.prg | 通过 |
KoalaShower.prg | 通过 |
Message.prg | 通过 |
MusicIrq.prg | 通过 |
Scroll.prg | 通过 |
SID_Player.prg | 通过 |
SimpleSplits.prg | 失败 |
SineAndGraphics.prg | 通过 |
测试
使用Klaus2m5的6502处理器功能测试的帮助进行了CPU验证
./target/release/zinc64 --binary bin/6502_functional_test.bin --offset=1024 --console --loglevel trace
快捷键
快捷键 | 功能 |
---|---|
Esc | 控制台 |
Alt-Enter | 切换全屏 |
Alt-F9 | 重置 |
Alt-H | 激活调试器 |
Alt-M | 切换静音 |
Alt-P | 切换暂停 |
Alt-Q | 退出 |
Alt-W | 快进模式 |
Ctrl-F1 | 磁带播放/停止 |
NumPad-2 | 摇杆向下 |
NumPad-4 | 摇杆左 |
NumPad-5 | 摇杆开火 |
NumPad-6 | 摇杆右 |
NumPad-8 | 摇杆向上 |
致谢
- 感谢Commodore爱好者们建造了一个标志性的8位机器
- 感谢Rust开发者们提供了一个令人难以置信的开发语言
- 感谢Rafal Wiosna将他对8位机器的一些热情传递给我 ;)
- 感谢Klaus Dormann的6502_65C02_functional_tests,没有它我会迷失方向
- 感谢Dag Lem的reSID实现
- 感谢Christian Bauer的精彩论文“MOS 6567/6569视频控制器(VIC-II)及其在Commodore 64中的应用”
- 感谢Peter Schepers的“各种模拟器文件格式介绍”
- 感谢c64-wiki.com为我提供了关于各种硬件组件的参考资料
依赖关系
~29KB