我可以使用两个补充的SUB指令gameboy模拟吗?

时间:2017-01-02 13:26:17

标签: emulation z80 gameboy

您好我正在为Game Boy编写模拟器。

我正在与SUB intruction挣扎

print calendar.get_properties([dav.DisplayName()])

给出SUB a, 0x92

我在做的是:

a = 0x90

我使用2补充方法进行减法。

0x90 + (-0x92)

因此,减法等同于以下添加:

-0x92 <=>
2_complement(0x92) <=>
2_complement(10010010) <=>
01101101 + 1 <=>
01101110

在此过程中,没有进位,没有半进位,所以我没有设置标志。而且我认为这是一个错误,因为其他仿真器(如BGB)也是如此。 请注意,结果是正确的,只有标志不正确。

所以我认为真正的处理器不使用2补码方法,因为没有自由的方法来检索进位和半进位。

但是,我可以使用两个补码来模拟带有标志处理的SUB指令,还是应该依赖“经典”减法逻辑?

2 个答案:

答案 0 :(得分:1)

你可以在这里找到如何设置add / sub work和carry / overflow标志的答案:

TraCIMobility.h

My answer to: Overflow and Carry flags on Z80

答案 1 :(得分:1)

真正的CPU在进行减法时确实依赖于参数的反转。

首先请注意,两个补码本身是另一个加法(在反转所有位后加1),所以完全相同的做法会很慢。

让我们看看只添加一个倒置的参数:

0x90 +(~0x92)= 0x90 + 0x6D = 0xFD,你没有进位。从正确的结果中减去1。

要修复结果,必须添加另一个,这可以通过将carry in = 1传递给加法器来方便地完成。因此,您必须像对待参数一样完成转换进位。 毫不奇怪,结果携带也是倒置的。

示例:从0x34减去0x12: 0x34 +(~0x12)+ 1(反向输入进位)= 0x34 + 0xED + 1 = 0x122:无执行(取反输出进位)并校正结果。 传入进位为1:0x34 + 0xED + 0 = 0x121(无执行,结果减1)。

然而,有些CPU不会反转输入和结果进位:包括6502(反向进位输入和输出SBC命令)和32位ARM。他们只是颠倒了论点。