gpt4 book ai didi

javascript - 6502 仿真实现 ADC 和 SBC 的正确方法

转载 作者:可可西里 更新时间:2023-11-01 02:50:42 26 4
gpt4 key购买 nike

我一直在为 MOS 6502 开发仿真器,但我似乎无法让 ADC 和 SBC 正常工作。我正在用 AllSuiteA program 测试我的模拟器加载到模拟内存中的 0x4000,对于 test09,我当前的 ADC 和 SBC 实现只是没有获得正确的标志。我已经尝试过无数次更改他们的算法,但每次,进位标志和溢出标志都足够重要,并导致测试分支/不分支。

Both of my functions are based off this.

内存[0x10000] 是累加器。它存储在内存范围之外,因此我可以有一个单独的寻址 switch 语句。

这是我对这些功能的实现之一:

case "ADC":
var t = memory[0x10000] + memory[address] + getFlag(flag_carry);
(memory[0x10000] & 0x80) != (t & 0x80) ? setFlag(flag_overflow) : clearFlag(flag_overflow);
signCalc(memory[0x10000]);
zeroCalc(t);

t > 255 ? setFlag(flag_carry) : clearFlag(flag_carry);

memory[0x10000] = t & 0xFF;
break;

case "SBC":
var t = memory[0x10000] - memory[address] - (!getFlag(flag_carry));
(t > 127 || t < -128) ? setFlag(flag_overflow) : clearFlag(flag_overflow);

t >= 0 ? setFlag(flag_carry) : clearFlag(flag_carry);
signCalc(t);
zeroCalc(t);

memory[0x10000] = t & 0xFF;
break;

我现在完全没有想法,but I did also run into the same problem with the data offered here.因此,让我失望的不仅仅是一个实现计划。

最佳答案

(我在写下面的答案时忘记了 NES 6502 缺少的 Decimal 模式。无论如何我都会保留它,因为它可能对编写 NES 模拟器的人有用。)

一旦您的模拟器具有 ADC

SBC 就很容易实现。您需要做的就是反转参数的位并将其传递给 ADC 实现。要直观地了解为什么会这样,请注意将 arg 的所有位取反会以二进制补码形式生成 -arg - 1,并研究 时发生的情况>carry 标志已设置和未设置。

这是我的模拟器中 SBC 的完整源代码。所有标志也将正确设置。

static void sbc(uint8_t arg) { adc(~arg); /* -arg - 1 */ }

实现 ADC 时最棘手的部分是溢出标志的计算。它被设置的条件是结果有“错误”的标志。由于范围的计算方式,事实证明这只会在两种情况下发生:

  1. 两个正数相加,结果为负数。
  2. 两个负数相加,结果为正数。

(1)和(2)可以简化为如下条件:

  • 两个符号相同的数相加,结果符号不同。

通过一些 XOR 技巧,这允许设置 overflow 标志,如下面的代码(来 self 的模拟器的完整 ADC 实现):

static void adc(uint8_t arg) {
unsigned const sum = a + arg + carry;
carry = sum > 0xFF;
// The overflow flag is set when the sign of the addends is the same and
// differs from the sign of the sum
overflow = ~(a ^ arg) & (a ^ sum) & 0x80;
zn = a /* (uint8_t) */ = sum;
}
如果 a 寄存器和 arg 不同,

(a ^ arg) 在符号位位置给出 0x80在标志。 ~ 翻转位,如果 aarg 具有相同的符号,您将得到 0x80。用更通俗的英语,条件可以写成

overflow = <'a' and 'arg' have the same sign> &  
<the sign of 'a' and 'sum' differs> &
<extract sign bit>

ADC 实现(以及许多其他指令)也使用一个技巧将 标志存储在一起。

可以找到我的 CPU 实现(来自 NES 模拟器)here顺便一提。搜索“核心指令逻辑”将为您提供所有指令(包括非官方指令)的简单实现。

我已经通过大量测试 ROM 运行它而没有失败(NES 仿真的一个好处是有很多很棒的测试 ROM 可用),我认为此时它应该几乎没有错误(除了一些极其晦涩的东西,例如在某些情况下涉及开放式总线值)。

关于javascript - 6502 仿真实现 ADC 和 SBC 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29193303/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com