7 个不稳定版本
0.4.0 | 2022 年 12 月 18 日 |
---|---|
0.3.3 | 2022 年 12 月 2 日 |
0.3.2 | 2021 年 1 月 20 日 |
0.3.0 | 2020 年 11 月 19 日 |
0.1.0 | 2020 年 9 月 21 日 |
#83 in 模拟器
在 2 crates 中使用
740KB
15K SLoC
这是什么?为什么?
有很多 ZX Spectrum 模拟器,其中很大一部分是开源的,一些非常先进,大多数都是出于娱乐目的。但除了几个 Z80 CPU 模拟器的例子之外,我所看到的每一个都是完整的程序,代码不易构建或移植到其他系统。我所找到的大部分是用 C 编写的,很多是用 Java 编写的,甚至有一些是用javascript编写的。
一个引人注目的例子是使用 C 编写且代码易读的 Free Unix Spectrum Emulator。模拟器的组件很好地分离了,具有高度的聚合性,但遗憾的是,这里和那里都散布着大量的全局变量。然而,我可以想象,只要有足够的耐心和技能,就可以在这样的基础上构建成功的项目。
SPECTRUSTY 是从头开始构建的,部分是出于娱乐目的,但也是作为一个 Rust 抽象测试设施。我需要一些主题来深入 Rust 面向对象模型,用于教育目的,我选择了 ZX Spectrum,因为它是一个非常简单的机器,彻底地进行了逆向工程和文档化。这也是我拥有的第一台计算机。从一开始,目标就不是构建一个完整的模拟器程序,而是一个库,你可以相对容易地在这个库的基础上构建适合你特定需求的模拟器。
在这个库中,每个组件都是一个独立的实体,它不知道任何关于世界的事情,通过特质接口来实现其目的。大多数结构体都是使用泛型参数定义的,这些参数可以由互补的组件替代,以完成或扩展其基本功能。
要使用 SPECTRUSTY 创建你的模拟器,首先你需要选择你需要的组件,然后选择它们组合的方式,最后通过特质方法实现它们的函数。
注意事项
由于大量使用多态和静态分发,针对每套频谱芯片组、设备套件和CPU,都会因为单态化而产生单独的代码。如果您希望这些集合在运行时都可用,可能会生成相当大的输出代码。另一方面,产生的代码效率相当高。
如何使用
因为最好的学习方法是通过实例,我邀请您查看教程。
在示例目录中可以找到使用SPECTRUSTY可以构建的几个示例,这些示例作为独立的crate提供。
贡献和反馈
由于ZX Spectrum的普及,从各种来源都可以找到大量技术信息。另一方面,信息的确定性已经被误导,因为一些资源相互矛盾。不幸的是,我对真实硬件的访问非常有限——我自豪地拥有一个TC2048,它至今仍在工作。如果您发现某些内容被错误地模拟,请毫不犹豫地提交一个问题。
功能
以下您将找到库的特色功能和其路线图。
CPU
通过一个独立的z80emu crate执行Zilog Z80 CPU模拟,该crate可以模拟CPU的NMOS
、CMOS
和BM1
变体。
核心芯片组模型
对 Sinclair/Amstrad 机器的视频和争用时序进行了彻底测试,至少与Fuse模拟器的时序相匹配。SCLD实现尚未实施单独的时序,因此目前它可以借用 Sinclair 模型的时序。
- - Ferranti ULA (未提交逻辑阵列) 用于 Sinclair ZX Spectrum 16k/48k (PAL 和 NTSC 时序)。
- - Ferranti ULA 128 用于 Sinclair ZX Spectrum 128k/+2。
- - Amstrad 门阵列用于 ZX Spectrum +2A/+3。
- - (部分) NCR Corporation 的 SCLD 用于 Timex TC2048/TC2068/TS2068 系列(目前使用 Ferrant ULA 的争用时序)。
- - ULAplus 屏幕和颜色模式(包括灰度)作为其他芯片组的增强包装。
- - Chloe 用于 ZX Spectrum SE(272kB RAM)。
- - 俄罗斯五角形和毒蛇模型。
- - 斯洛伐克的 Didaktik 系列。
- - 如果我找到一些详细的规格,将包括波兰 Elwro 800 Junior。
模拟芯片组的原始错误和功能
- - "慢"内存争用。
- - 如原始机器上的部分端口解码。
- - 在 Ferranti ULA 芯片组上读取未使用的端口时出现浮动总线。
- - ULA端口读取时的键盘问题(2/3/none/scld)——当没有磁带信号时,确定EAR IN位值。
- - EAR/MIC 输出允许从两个来源进行声音模拟。
- - Ferranti ULA "雪花"错误干扰——当寄存器I设置为争用页面时(参见128k模型上的Robocop 3或Vectron)。然而,RFSH影响干扰的确切时序目前尚不清楚,因此这是一个近似值。错误模拟也不会像真实机器那样挂起 Spectrum。
- - 早期/晚期时序方案。
- - I/O端口争用与Fuse模拟器相同。大多数模拟器假设端口读写操作在最后一个IO周期 -
T4
执行,然而Z80的IO_IORQ
信号在T1
和T4
之间是激活的,并且Fuse端口读写在T1
进行时间戳记录。这对于精确模拟边界效应尤为重要。 - - 从端口0x7ffd读取会导致ULA 128崩溃,因为它的HAL10H8芯片无法区分对这个端口的读写操作,导致使用浮动的数据总线来设置分页寄存器。
模拟的外设
- - 磁带信号接口作为脉冲迭代器(输入和输出)。
- - AY-3-8910声音处理器和通用的I/O A和B端口(用于128k / Melodik / FullerBox / Timex)。
- - 128k RS-232端口作为AY-3-8910端口附件。
- - 128k键盘作为AY-3-8910端口附件。
- - +2A/+3 centronics端口。
- - 接口1 ROM扩展。
- - 接口1 - 微型驱动器(包括IN 0错误)。
- - 接口1 - RS232。
- - 接口1 - ZX-NET(具有实时UDP数据包封装!)。
- - 游戏手柄:Kempston,Fuller,Sinclair,Cursor。
- - Kempston鼠标。
- - +3软盘驱动器。
- - 其他软盘驱动器系统(TR-DOS,DiSCIPLE,+D,FDD 3000,...)
文件格式
- - .SNA格式加载/保存器
- - .Z80 v1/2/3格式加载/保存器
- - .SLT
- - .SZX
- - .TAP格式读取/写入器,脉冲编码/解码器
- - .TZX格式读取/写入器,脉冲编码/解码器
- - .PZX格式读取/写入器,脉冲编码/解码器
- - .RZX格式读取/写入器,录音/播放器
- - .MDR微型驱动器格式读取/写入器,文件系统浏览器
- - .SCR格式加载/保存器
- - .ZXP格式加载/保存器
- - .AY播放器格式解析器
Rust版本要求
由于依赖于Rust 2021版以及其他在此版本中稳定的API的crate使用,此版本的spectrusty
需要Rustc版本1.59或更高版本。
版权
SPECTRUSTY库可在GNU LGPL版本3或更高版本下使用。
依赖关系
~1–32MB
~479K SLoC