【问题标题】:Understanding opcodes in Z80 emulator了解 Z80 模拟器中的操作码
【发布时间】:2019-05-10 02:45:32
【问题描述】:

我目前正在使用 Z80 处理器仿真器,作为初学者,我发现了一个为内存分配值以显示“Hello World!”的示例。

1. 0x21, 0x0C, 0X00,// ld hl, 0008
2. 0x06, 0x0F, // ld b,0f
3. 0x7e, // ld a,(hl)
4. 0x23, // inc hl
5. 0xD3, 0x00, // out (00), a
6. 0x10, 0xFA, // djnz
7. 0x76, // halt
8. 0x48, 0x65, 0x6C, 0x6C, 0x6F, // Hello
9. 0x2D, 0x77, 0x6F, 0x72, 0x6C, //  Worl  
10. 0x64, 0x21, 0x20, 0x21//d! !  

我对内存中的值有一些疑问:

  1. 在第一行,对于命令0x21 定义了LD HL,XX 指令,所以它在汇编程序中是LD HL,0CH,那0x00 在那里做什么?我认为LD HL,xx 是一个 16 位指令,所以用八个零来补充0C,但我认为这是不正确的。

  2. 在第 5 行,OUT (00),A 到底在做什么?我通过一些研究发现OUT 将数据从累加器传输到输出端口,但我不太清楚0x00 的具体用途。

非常感谢您对我的问题的任何提示或帮助,提前感谢您抽出时间阅读它们。

【问题讨论】:

  • LD HL, XX 将 16 位值加载到 HL 中。指定一个 16 位值需要两个字节。在第 5 行,00 是端口号。听起来您需要先学习 Z80 汇编语言,然后才能开始编写模拟器。
  • 并且代码被错误地复制和粘贴。它是Hello-world! !,只有 14 个字节长,而 DJNZ 被初始化为循环 15 次。 :) 显然,HL 加载的是地址 0x000C 而不是评论所声称的 0x0008。
  • @tum_ 现在我对DJNZ 范围感到困惑,15 是在哪里给出的?当我检查表格时,0xFAJP M,XX 的操作码。提前感谢您的关注。
  • 10 n DJNZ PC + n - 所以 10(hex) 是操作码,FA (== -6) 是要跳转到的偏移量。 DJNZ 递减寄存器 B,将其与 0 比较,如果非零 - 跳转,否则 - 失败。 B 设置为 0F,即 15。

标签: z80


【解决方案1】:

回答您的问题:

  1. 0x21 是三字节 LD HL, nn 指令的操作码。 nn 部分是一个 16 位立即数操作数。在 Z80 中,所有 16 位立即数都以字节的小端顺序编码,这意味着包含最低有效位 (LSB) 的字节在前,然后是包含值的最高有效位 (MSB) 的字节.在您的示例中,字节为0x0c, 0x00。因此,生成的 16 位值是 0x000c,指令是 ld hl, 0x000c,即使注释提到了不同的值。

  2. out (n), a 是一条 Z80 指令,它将寄存器 a 的值输出到端口。尽管 Z80 端口有 16 位地址(就像内存地址一样),但指定端口的 n 操作数是 8 位立即数。这个立即数转到完整端口地址的低字节,而地址的高字节是寄存器a 的值。这是它在我的模拟器中的样子:

    void on_out_n_a(fast_u8 n) {
        fast_u8 a = self().on_get_a();
        self().on_output_cycle(make16(a, n), a);
        self().on_set_wz(make16(a, inc8(n)));
    }

OUT (n), A

在硬件层面发生的事情是,处理器将其信号线(如~IORQ、~RD、~WR 和地址总线引脚)设置为特定状态,以便连接到处理器的外围设备能够识别输出循环并“查看”写入哪个值和哪个端口。您可以在 Z80 用户手册的“输入或输出循环”部分中找到有关输出循环期间发生的情况的更多详细信息。

Z80 User Manual

为了让您的模拟器能够将值实际输出到外围设备,您需要这些设备(无论是真实设备还是模拟设备)确认输出并提供端口地址和输出值,以便它们能够计算出他们是否应该做出反应以及他们应该如何具体地做出反应。例如,在 ZX Spectrum 中,输出端口 0xfe(十进制 254)的三个最低位决定了屏幕边框的颜色。因此,Spectrum 模拟器会捕获对该端口的写入,从值中提取颜色代码并更新屏幕以显示新颜色的边框。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-24
    • 2011-07-22
    • 1970-01-01
    • 2017-10-14
    • 2016-05-25
    • 1970-01-01
    • 1970-01-01
    • 2017-09-28
    相关资源
    最近更新 更多