#模拟器 #c64 #commodore #no-std

no-std zinc64-core

Commodore 64 模拟器调试器支持

1 个不稳定版本

0.8.0 2019年5月6日

模拟器 中排名 379

每月下载量 25
4crate使用(2个直接使用)

GPL-3.0+

25KB
517

Zinc64

Build Status Crates.io

** 注意: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 - 软盘支持

入门指南

  1. 安装Rust编译器或按照以下步骤操作:https://www.rust-lang.net.cn/en-US/install.html

     curl https://sh.rustup.rs -sSf | sh
    
  2. 克隆此存储库。

     git clone https://github.com/digitalstreamio/zinc64
    

    或下载zip存档

     https://github.com/digitalstreamio/zinc64/archive/master.zip
    
  3. 构建模拟器。

     cd zinc64
     cargo build --release --all
    
  4. 运行模拟器。

     ./target/release/zinc64
    

    或启动程序

     ./target/release/zinc64 --autostart path
    

Windows注意事项

  1. 安装Microsoft Visual C++ Build Tools 2017。选择Visual C++构建工具工作负载。

  2. 安装SDL2开发库

  3.  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
    
  4.  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