【问题标题】:Writing a graphical Z80 emulator in C or C++ [closed]用 C 或 C++ 编写图形 Z80 仿真器 [关闭]
【发布时间】:2023-04-06 10:10:01
【问题描述】:

我想有兴趣为Z80 处理器编写我自己的简单模拟器。我对这种类型的编程没有经验。我最擅长使用基于 C 的语言,因为它们是我最了解的语言。

我需要什么来完成这项工作,有哪些好的教程/参考资料可以帮助我完成这个项目?

我还想要一个为我的TI-84 Plus 计算器编写 ROM 转储应用程序的教程,这样我就可以将它的 ROM 与这个模拟器一起使用。

【问题讨论】:

    标签: c++ c emulation z80


    【解决方案1】:

    需要补充的一些东西(尤其是 Z80):

    1. 不要相信文档是 100% 没有错误的

      我没有看到任何没有错误,包括这里提到的错误。

    2. 正确测试您的 CPU 内核是否存在错误

      它将使您免于以后的许多头痛和困惑。

    为了进行测试,我使用了三种方法:

    1. 对已知代码进行步进/跟踪(通常注释为 ROM 反汇编)

      这是第一步,还没有任何效果。您将看到错误(解码)编码的指令。

    2. 在您的模拟器中包含不同的 Z80 内核,并将所有内容作为双重模拟处理

      制作两个具有相同步进、跟踪和运行系统的“分离”模拟器。两个 CPU 都应该有自己的内存硬件等。

      • 运行模拟器并在每条指令之后比较寄存器和即时内存位置,例如[hl],[sp],[sp-1]...
      • 在第一个差异停止,看看是什么指令导致它。
        调试它并继续,直到你“没有错误”。注意第二个内核也可能有问题,因此请谨慎调试。
    3. 当你更容易运行时使用核心测试器

      使用ZEXALL Exerciser。它是 Z80 上最好的(至少从我的经验来看)。它帮助了我很多事情(我的核心现在 100% 兼容 ZEXALL)。它是针对真实硬件完成的,因此没有错误。它来自 CP/M,因此某些版本需要 64K RAM 模式 才能运行。不同的 OS/ROM 或其他任何可能导致内存访问失败的指令,因此对于那些您需要找到更正的 CRC 或与真实硬件进行比较的指令。

      例如,原始 ZEXALLZX Spectrum 上会失败很多事情(就像 MSX64K RAM strong> 没有 ROM),但也有针对真正的 ZX Spectrum 完成的版本,它们在 ZX Spectrum 上是 100% OK strong>(在我的模拟器上也是:))

      Z80all instruction exerciser
      
      <adc,sbc> hl,<bc,de,hl,sp>...OK
      add hl,<bc,de,hl,sp>.........OK
      add ix,<bc,de,ix,sp>.........OK
      add iy,<bc,de,iy,sp>.........OK
      aluop a,nn...................OK
      aluop a,<b,c,d,e,h,l,(hl),a>.OK
      aluop a,<ixh,ixl,iyh,iyl>....OK
      aluop a,(<ix,iy>+1)..........OK
      bit n,(<ix,iy>+1)............OK
      bit n,<b,c,d,e,h,l,(hl),a>...OK
      cpd<r>.......................OK
      cpi<r>.......................OK
      <daa,cpl,scf,ccf>............OK
      <inc,dec> a..................OK
      <inc,dec> b..................OK
      <inc,dec> bc.................OK
      <inc,dec> c..................OK
      <inc,dec> d..................OK
      <inc,dec> de.................OK
      <inc,dec> e..................OK
      <inc,dec> h..................OK
      <inc,dec> hl.................OK
      <inc,dec> ix.................OK
      <inc,dec> iy.................OK
      <inc,dec> l..................OK
      <inc,dec> (hl)...............OK
      <inc,dec> sp.................OK
      <inc,dec> (<ix,iy>+1)........OK
      <inc,dec> ixh................OK
      <inc,dec> ixl................OK
      <inc,dec>  iyh...............OK
      <inc,dec> iyl................OK
      ld <bc,de>,(nnnn)............OK
      ld hl,(nnnn).................OK
      ld sp,(nnnn).................OK
      ld <ix,iy>,(nnnn)............OK
      ld (nnnn),<bc,de>............OK
      ld (nnnn),hl.................OK
      ld (nnnn),sp.................OK
      ld (nnnn),<ix,iy>............OK
      ld <bc,de,hl,sp>,nnnn........OK
      ld <ix,iy>,nnnn..............OK
      ld a,<(bc),(de)>.............OK
      ld <b,c,d,e,h,l,(hl),a>,nn...OK
      ld (<ix,iy>+1),nn............OK
      ld <b,c,d,e>,(<ix,iy>+1).....OK
      ld <h,l>,(<ix,iy>+1).........OK
      ld a,(<ix,iy>+1).............OK
      ld <ixh,ixl,iyh,iyl>,nn......OK
      ld <bcdehla>,<bcdehla>.......OK
      ld <bcdexya>,<bcdexya>.......OK
      ld a,(nnnn) / ld (nnnn),a....OK
      ldd<r> (1)...................OK
      ldd<r> (2)...................OK
      ldi<r> (1)...................OK
      ldi<r> (2)...................OK
      neg..........................OK
      <rrd,rld>....................OK
      <rlca,rrca,rla,rra>..........OK
      shf/rot (<ix,iy>+1)..........OK
      shf/rot <b,c,d,e,h,l,(hl),a>.OK
      <set,res> n,<bcdehl(hl)a>....OK
      <set,res> n,(<ix,iy>+1)......OK
      ld (<ix,iy>+1),<b,c,d,e>.....OK
      ld (<ix,iy>+1),<h,l>.........OK
      ld (<ix,iy>+1),a.............OK
      ld (<bc,de>),a...............OK
      Tests complete
      

      如果您即将使用 ZEXALL,请注意它确实是详尽的测试,并且 IIRC~50MHz 仿真上花费了大约 30-60分钟完成。而且它需要按一个键滚动几次......

      如果您需要争用模型,请添加适当的测试。然后找一个。 ZX Spectrum 有许多浮动总线、中断和屏幕测试器。对于 TI 我不知道...(我不是 TI 计算器用户)

    顺便说一句:你的模拟器怎么样? (你做到了吗?)

    指令集

    我会在此处复制我的指令集,但它有 1792 行和 121 KB,因此不符合 30 KB 的限制。相反,您可以在我的这个答案的下载链接中找到它

    它包含带有正确 OP 代码、编码时间和机器周期的“所有”ZX 指令。我花了几年时间整理所有文档,所以我正确地通过了 ZEXALL 100%。我的模拟器将这个(1792 指令)文本文件加载到init 上的核心,并在运行时配置指令解码器和处理器,所以我能够非常快速和简单地改变事情(如果检测到错误)......它为我节省了 很多 时间。

    【讨论】:

    • 这就是我所说的交叉口译员。我使用这种方法来更正新解释器与旧解释器的一些细节,它极大地有助于更正错误的指令。关键是让模拟器执行一个程序,而交叉解释器在两个解释器中执行指令,然后检查结果:如果有分歧,则转储细节。
    【解决方案2】:

    尝试看看 Sega Master System 和 Game Gear 模拟器(我很确定其中一些是开源的)。这些控制台有一个 Z80 作为 CPU,并且 ZX Spectrum也用过,http://www.worldofspectrum.org/emulators.html

    【讨论】:

      【解决方案3】:

      我建议您首先考虑为稍微简单但相关的 CPU 8080 编写一个模拟器。 Z80 实际上相当复杂(多字节指令、更多寻址模式、索引寄存器等),而 8080 指令非常容易解码(您可以使用 256 项查找表,作为一阶解决方案) .

      如果您决定继续尝试 Z80,您为控制程序而编写的所有代码(显示、数据输入、内存转储等)都应该是可重复使用的,而且您确实应该将用户界面设计为独立于模拟处理器。

      【讨论】:

      • 我不同意解码。 Z80 指令很容易解码,将它们分解为 {2, 3, 3} 位字段。我已经做到了。
      • Z80 有单字节和双字节操作码(不包括地址信息)。因此,8080(只有单字节操作码)非常容易解码。此外,您需要处理的寻址模式数量在 8080 上较少。因此,编写 8080 仿真器更容易。顺便说一句,我都写过。
      【解决方案4】:

      米奇完全正确。从了解处理器开始。然后通过编写代码来实现特定指令来玩一下。为此使用 C++,顺便说一句,而不是 C,否则处理器的概念将不会映射到代码中的类。

      在执行指令的过程中,您会发现需要定义标志和指令指针等内容。这最终会让您到达需要实现内存模型甚至 I/O 模型的地方。

      您最终必须弄清楚如何将代码和数据加载到内存中,或许还需要弄清楚如何将其转储回磁盘。

      只有这样你才需要在给定的指令指针处模拟代码的执行,加载到内存中。

      【讨论】:

      • 我也要感谢您的建议。
      【解决方案5】:

      我在这里了解了有关 Z80 和计算器组件的所有信息:http://www.ticalc.org/programming/

      【讨论】:

        【解决方案6】:

        您似乎想要的仿真器不仅仅是一个处理器,而是一个完整的机器。您还将承担模拟其余硬件的任务,而查找相关文档很可能是等待您完成的更困难的任务。

        根据您的目标,您可能希望从现有的 Z80 模拟器开始。快速搜索给出了其中的几个,但没有 TI-84 的仿真器。 simh,旧计算机仿真框架已经具有 Z80 处理器的仿真,添加其余硬件的仿真应该比从头开始更容易。即使您不走那条路,那里也有一些设计文档可以帮助您。

        【讨论】:

          【解决方案7】:

          这有点偏题,但既然你说你没有这种类型的编程经验,你可能想从2006 ICFP programming contestUniversal Virtual Machine 构建一个模拟器开始。这是一项需要经验丰富的程序员 90 分钟的任务,但许多没有经验的团队能够在几天内完成。当你完成模拟器后,它会解锁一堆有趣的东西,在你接触 Z80 之前这可能是一个很好的热身。

          【讨论】:

            【解决方案8】:
            猜你喜欢
            • 2012-11-06
            • 1970-01-01
            • 2019-12-29
            • 2011-12-10
            • 2010-11-03
            • 2015-11-05
            • 1970-01-01
            • 1970-01-01
            • 2021-07-10
            相关资源
            最近更新 更多