了解Z80模拟器中的操作码

时间:2019-05-10 02:45:32

标签: z80

我目前正在使用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到底在做什么。

对于任何提示或问题的帮助,我将不胜感激,在此先感谢您抽出宝贵的时间阅读这些问题。

1 个答案:

答案 0 :(得分:3)

回答您的问题:

  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仿真器将捕获到该端口的文字,从该值中提取颜色代码,并更新屏幕以显示新颜色的边框。