21

この一見マイナーな質問についてお詫びしますが、どこにも答えが見つからないようです-Z80エミュレーターにDAA命令を実装するところですが、Zilogマニュアルで、調整を目的としていることに気付きました。 2進化10進演算用のアキュムレータ。命令は、加算または減算命令の直後に実行されることを意図していると書かれています。

私の質問は次のとおりです。

  • 別の命令の後に実行するとどうなりますか?
  • どの命令がそれに先行したかをどうやって知るのですか?
  • Nフラグがあることに気づきましたが、これは確かに前の命令が加算または減算命令であったことを明確に示すものではありませんか?
  • 前の命令に関係なく、DAAテーブルに設定された条件に基づいて、とにかくアキュムレータを変更するだけですか?
4

4 に答える 4

17

前の命令に関係なく、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   |
|------------------------------------------------------------------------------|

私は言わなければならない、私はdafter命令仕様を見たことがない。C表を注意深く調べると、命令の効果は、フラグとアキュムレータの値にのみ依存していることがわかりますH。前の命令にはまったく依存していません。C=0また、たとえば、、、およびアキュムレータの下の桁が4または5の場合はどうなるかはわかりません。そのため、このような場合H=1はを実行するNOPか、エラーメッセージなどを生成する必要があります。

于 2011-11-14T09:55:14.597 に答える
10

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」への変換を終了します。つまり、2進数から16進数へのコンバーターです。

于 2012-01-13T09:03:42.633 に答える
9

この命令もかなり紛らわしいと思いましたが、z80-heavenからのその動作のこの説明が最も役立つことがわかりました。

この命令を実行すると、Aレジスタはフラグの内容を使用してBCD補正されます。正確なプロセスは次のとおりです。Aの最下位4ビットに非BCD桁が含まれている場合(つまり、9より大きい場合)、またはHフラグが設定されている場合、$06がレジスタに追加されます。次に、最上位4ビットがチェックされます。この有効数字も9より大きい場合、またはCフラグが設定されている場合は、$60が追加されます。

これにより、命令の単純なパターンが提供されます。

  • 下位4ビットが9より大きい数値を形成するか、Hが設定されている場合は、アキュムレータに$06を追加します。
  • 上位4ビットが9より大きい数を形成するか、Cが設定されている場合は、アキュムレータに$60を追加します。

また、DAAは加算または減算の後に実行することを目的としていますが、いつでも実行できます。

于 2015-05-01T15:39:50.747 に答える
5

これは本番環境のコードであり、DAAを正しく実装し、zexall / zexdoc /z80testZ80オペコードテストスーツに合格しています。

文書化されていない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の相互作用を視覚化するために、デバッグの目的で、実際のZX SpectrumまたはDAAを正確にエミュレートするエミュレーションで実行できる小さなZ80アセンブリプログラムを作成しました:https ://github.com/ruyrybeyro/daatable

動作として、前述のアセンブリプログラムで生成されたDAAの前後のフラグN、C、HおよびレジスタAのテーブルを取得しました:https ://github.com/ruyrybeyro/daatable/blob/master/daaoutput.txt

于 2019-09-07T19:57:42.157 に答える