Z80 DAA指令

发布于 2024-12-15 12:06:55 字数 302 浏览 4 评论 0原文

对于这个看似小问题的歉意,但我似乎无法在任何地方找到答案 - 我只是要在我的 Z80 模拟器中实现 DAA 指令,我在 Zilog 手册中注意到它是为了调整的目的用于二进制编码十进制算术的累加器。它表示该指令旨在在加法或减法指令之后立即运行。

我的问题是:

  • 如果在另一条指令之后运行它会发生什么?
  • 它如何知道它之前的指令是什么?
  • 我意识到有 N 标志 - 但这肯定不会明确表明前一条指令是加法或减法指令?
  • 它是否只是根据 DAA 表中规定的条件修改累加器,而不管前面的指令如何?

Apologies for this seemingly minor question, but I can't seem to find the answer anywhere - I'm just coming up to implementing the DAA instruction in my Z80 emulator, and I noticed in the Zilog manual that it is for the purposes of adjusting the accumulator for binary coded decimal arithmetic. It says the instruction is intended to be run right after an addition or subtraction instruction.

My questions are:

  • what happens if it is run after another instruction?
  • how does it know what instruction preceeded it?
  • I realise there is the N flag - but this surely wouldnt definitively indicate that the previous instruction was an addition or subtraction instruction?
  • Does it just modify the accumulator anyway, based on the conditions set out in the DAA table, regardless of the previous instruction?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

方觉久 2024-12-22 12:06:55

它是否只是根据 DAA 表中规定的条件修改累加器,而不管之前的指令如何?

是的。该文档仅告诉您 DAA 的用途。也许您指的是此链接处的表格:

--------------------------------------------------------------------------------
|           | C Flag  | HEX value in | H Flag | HEX value in | Number  | C flag|
| Operation | Before  | upper digit  | Before | lower digit  | added   | After |
|           | DAA     | (bit 7-4)    | DAA    | (bit 3-0)    | to byte | DAA   |
|------------------------------------------------------------------------------|
|           |    0    |     0-9      |   0    |     0-9      |   00    |   0   |
|   ADD     |    0    |     0-8      |   0    |     A-F      |   06    |   0   |
|           |    0    |     0-9      |   1    |     0-3      |   06    |   0   |
|   ADC     |    0    |     A-F      |   0    |     0-9      |   60    |   1   |
|           |    0    |     9-F      |   0    |     A-F      |   66    |   1   |
|   INC     |    0    |     A-F      |   1    |     0-3      |   66    |   1   |
|           |    1    |     0-2      |   0    |     0-9      |   60    |   1   |
|           |    1    |     0-2      |   0    |     A-F      |   66    |   1   |
|           |    1    |     0-3      |   1    |     0-3      |   66    |   1   |
|------------------------------------------------------------------------------|
|   SUB     |    0    |     0-9      |   0    |     0-9      |   00    |   0   |
|   SBC     |    0    |     0-8      |   1    |     6-F      |   FA    |   0   |
|   DEC     |    1    |     7-F      |   0    |     0-9      |   A0    |   1   |
|   NEG     |    1    |     6-F      |   1    |     6-F      |   9A    |   1   |
|------------------------------------------------------------------------------|

我必须说,我从来没有看到了一个较迟的指令规范。如果仔细检查该表,您会发现指令的效果仅取决于 CH 标志以及累加器中的值 - 它并不依赖于完全取决于之前的指令。此外,它也没有透露,例如,C=0H=1 以及累加器中的低位数字是 4 或 5 时会发生什么。因此,您在这种情况下,必须执行 NOP,或者生成错误消息或其他内容。

Does it just modify the accumulator anyway, based on the conditions set out in the DAA table, regardless of the previous instruction?

Yes. The documentation is only telling you what DAA is intended to be used for. Perhaps you are referring to the table at this link:

--------------------------------------------------------------------------------
|           | C Flag  | HEX value in | H Flag | HEX value in | Number  | C flag|
| Operation | Before  | upper digit  | Before | lower digit  | added   | After |
|           | DAA     | (bit 7-4)    | DAA    | (bit 3-0)    | to byte | DAA   |
|------------------------------------------------------------------------------|
|           |    0    |     0-9      |   0    |     0-9      |   00    |   0   |
|   ADD     |    0    |     0-8      |   0    |     A-F      |   06    |   0   |
|           |    0    |     0-9      |   1    |     0-3      |   06    |   0   |
|   ADC     |    0    |     A-F      |   0    |     0-9      |   60    |   1   |
|           |    0    |     9-F      |   0    |     A-F      |   66    |   1   |
|   INC     |    0    |     A-F      |   1    |     0-3      |   66    |   1   |
|           |    1    |     0-2      |   0    |     0-9      |   60    |   1   |
|           |    1    |     0-2      |   0    |     A-F      |   66    |   1   |
|           |    1    |     0-3      |   1    |     0-3      |   66    |   1   |
|------------------------------------------------------------------------------|
|   SUB     |    0    |     0-9      |   0    |     0-9      |   00    |   0   |
|   SBC     |    0    |     0-8      |   1    |     6-F      |   FA    |   0   |
|   DEC     |    1    |     7-F      |   0    |     0-9      |   A0    |   1   |
|   NEG     |    1    |     6-F      |   1    |     6-F      |   9A    |   1   |
|------------------------------------------------------------------------------|

I must say, I've never seen a dafter instruction spec. If you examine the table carefully, you will see that the effect of the instruction depends only on the C and H flags and the value in the accumulator -- it doesn't depend on the previous instruction at all. Also, it doesn't divulge what happens if, for example, C=0, H=1, and the lower digit in the accumulator is 4 or 5. So you will have to execute a NOP in such cases, or generate an error message, or something.

旧时模样 2024-12-22 12:06:55

只是想补充一下,当他们谈论之前的操作时,N 标志就是他们的意思。加法设置 N = 0,减法设置 N = 1。因此,A 寄存器和 C、H 和 N 标志的内容决定结果。

该指令旨在支持 BCD 算术,但还有其他用途。考虑以下代码:

    and  15
    add  a,90h
    daa
    adc  a,40h
    daa

它最终将 A 寄存器的低 4 位转换为 ASCII 值“0”、“1”、...“9”、“A”、“B”、...、“F”。换句话说,二进制到十六进制的转换器。

Just wanted to add that the N flag is what they mean when they talk about the previous operation. Additions set N = 0, subtractions set N = 1. Thus the contents of the A register and the C, H and N flags determine the result.

The instruction is intended to support BCD arithmetic but has other uses. Consider this code:

    and  15
    add  a,90h
    daa
    adc  a,40h
    daa

It ends converting the lower 4 bits of A register into the ASCII values '0', '1', ... '9', 'A', 'B', ..., 'F'. In other words, a binary to hexadecimal converter.

您的好友蓝忘机已上羡 2024-12-22 12:06:55

这是生产中的代码,正确实现 DAA 并通过了 zexall/zexdoc/z80test Z80 操作码测试套件。

基于未记录的 Z80 记录,第 17-18 页。

void daa()
{
   int t;
    
   t=0;
    
   // 4 T states
   T(4);
    
   if(flags.H || ((A & 0xF) > 9) )
         t++;
    
   if(flags.C || (A > 0x99) )
   {
         t += 2;
         flags.C = 1;
   }
    
   // builds final H flag
   if (flags.N && !flags.H)
      flags.H=0;
   else
   {
       if (flags.N && flags.H)
          flags.H = (((A & 0x0F)) < 6);
       else
          flags.H = ((A & 0x0F) >= 0x0A);
   }
    
   switch(t)
   {
        case 1:
            A += (flags.N)?0xFA:0x06; // -6:6
            break;
        case 2:
            A += (flags.N)?0xA0:0x60; // -0x60:0x60
            break;
        case 3:
            A += (flags.N)?0x9A:0x66; // -0x66:0x66
            break;
   }
    
   flags.S = (A & BIT_7);
   flags.Z = !A;
   flags.P = parity(A);
   flags.X = A & BIT_5;
   flags.Y = A & BIT_3;
}

为了可视化 DAA 交互,出于调试目的,我编写了一个小型 Z80 汇编程序,该程序可以在实际的 ZX Spectrum 或准确模拟 DAA 的仿真中运行:https://github.com/ruyrybeyro/daatable

至于它的行为方式,之前得到了一个标志 N、C、H 的表并注册了 A使用上述汇编程序生成 DAA 后: https://github.com/ruyrybeyro /daatable/blob/master/daaoutput.txt

This is code in production, implementing DAA correctly and passes the zexall/zexdoc/z80test Z80 opcode test suits.

Based on The Undocumented Z80 Documented, pag 17-18.

void daa()
{
   int t;
    
   t=0;
    
   // 4 T states
   T(4);
    
   if(flags.H || ((A & 0xF) > 9) )
         t++;
    
   if(flags.C || (A > 0x99) )
   {
         t += 2;
         flags.C = 1;
   }
    
   // builds final H flag
   if (flags.N && !flags.H)
      flags.H=0;
   else
   {
       if (flags.N && flags.H)
          flags.H = (((A & 0x0F)) < 6);
       else
          flags.H = ((A & 0x0F) >= 0x0A);
   }
    
   switch(t)
   {
        case 1:
            A += (flags.N)?0xFA:0x06; // -6:6
            break;
        case 2:
            A += (flags.N)?0xA0:0x60; // -0x60:0x60
            break;
        case 3:
            A += (flags.N)?0x9A:0x66; // -0x66:0x66
            break;
   }
    
   flags.S = (A & BIT_7);
   flags.Z = !A;
   flags.P = parity(A);
   flags.X = A & BIT_5;
   flags.Y = A & BIT_3;
}

For visualising the DAA interactions, for debugging purposes, I have written a small Z80 assembly program, that can be run in an actual ZX Spectrum or in an emulation that emulates accurately DAA: https://github.com/ruyrybeyro/daatable

As how it behaves, got a table of flags N,C,H and register A before and after DAA produced with the aforementioned assembly program: https://github.com/ruyrybeyro/daatable/blob/master/daaoutput.txt

埖埖迣鎅 2024-12-22 12:06:55

我发现这条指令也相当令人困惑,但我发现它的行为描述来自 z80-heaven 是最有帮助的。

执行该指令时,A 寄存器使用标志的内容进行 BCD 校正。具体过程如下:如果A的最低有效四位包含非BCD数字(即大于9)或H标志被设置,则将$06添加到寄存器中。然后检查四个最高有效位。如果这个更有效的数字也恰好大于 9 或设置了 C 标志,则添加 60 美元。

这为指令提供了一个简单的模式:

  • 如果低 4 位形成大于 9 的数字或设置了 H,则将 $06 添加到累加器;
  • 如果高 4 位形成大于 9 的数字或设置了 C,则将 $60 添加到累加器。 另外,虽然 DAA打算在加法或减法之后运行,但

可以随时运行。

I found this instruction rather confusing as well, but I found this description of its behavior from z80-heaven to be most helpful.

When this instruction is executed, the A register is BCD corrected using the contents of the flags. The exact process is the following: if the least significant four bits of A contain a non-BCD digit (i. e. it is greater than 9) or the H flag is set, then $06 is added to the register. Then the four most significant bits are checked. If this more significant digit also happens to be greater than 9 or the C flag is set, then $60 is added.

This provides a simple pattern for the instruction:

  • if the lower 4 bits form a number greater than 9 or H is set, add $06 to the accumulator
  • if the upper 4 bits form a number greater than 9 or C is set, add $60 to the accumulator

Also, while DAA is intended to be run after an addition or subtraction, it can be run at any time.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文