java - 在 Java 中确定 6502 仿真中的进位和溢出标志?

标签 java emulation flags 6502 carryflag

我正在制作一个 6502 仿真器,但我在开始时就卡住了(或者我认为我至少是)(实现 ADC 操作)。问题是我必须确定是否有进位或溢出。问题是,在我的实现中我无法真正理解它们之间的区别。我知道进位是在运算后出现第 9 位时,而且我知道当结果大于 255 时会发生溢出。这不会使确定进位和溢出标志成为同一件事吗?

if(result > 255) { 
    carry = 1;
    overflow = 1;
} else { 
    carry = 0; 
    overflow = 0;
}

这不对吗?如果不是,什么是正确的,为什么?

最佳答案

溢出标志指示数字的符号何时被不正确地改变。因此,如果您将两个正数相加并得到负数,则会发生溢出。如果您将两个负数相加并得到正数,也会发生溢出。

添加两个不同符号的数字时不会溢出,因为范围不允许。最小的正数加上最大的负数是 0 + (-128),这很合适——0 加上任何适合 8 位的东西显然也适合 8 位。最小的负值加上最大的正值是 -1 + 127 = 126。这很合适。

(编辑:即使有进位,0 + -128 + 1 = -127,适合,-1 + 127 + 1 = 127,适合)

因此,如果两个具有相同符号的输入产生具有不同符号的结果,则会设置溢出。否则很清楚。

您可以将其表示为符号位上的简单按位运算。假设你有 a + b = c。

a ^ b

如果符号不同,则符号位为 1。你想知道它的反面。所以:

~(a ^ b)

如果符号相同,则在符号位中给出 1。这是测试的第一部分。假设 a 和 b 具有相同的符号,您可以针对其中任何一个测试 c。这一次你确实想测试差异,所以这只是:

a ^ c

您需要在测试的两个部分都设置被测试的位,这样您就可以将它们与二进制文件结合起来(在其中留下很多括号以链接到口头推理):

(~(a ^ b))&(a ^ c)

你只想要符号位,所以屏蔽掉它:

(~(a ^ b))&(a ^ c)&0x80

如果应该清除溢出标志,则计算结果为 0x00,如果应该设置,则计算结果为 0x80。所以只需将其移到位即可。

(旁白:虽然在 6502 上有很多指令设置标志并且只有一个暴露状态寄存器,因此仿真器通常以任何方便的形式单独保存标志并根据需要组成状态寄存器,在这种情况下你不会打扰移动和组合,您只需存储该结果)

关于java - 在 Java 中确定 6502 仿真中的进位和溢出标志?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16845912/

相关文章:

android - HTC ONE X (4.0.3)..安卓模拟器

c++ - 检查位标志

php - 两个用户同时写入一个文件? (PHP/file_put_contents)

mysql - 案例陈述 :Operand should contain 1 column(s)

java - JAX Web 服务无法在 CodenameOne 项目中工作

c# - 使用 wpf : click, 拖动、输入、退出进行完全鼠标控制模拟

java - @Fetch(FetchMode.SELECT) 和 fetch = FetchType.LAZY 的区别

Java:如何模拟 XInput 游戏 handle / Controller ?

java - 使用 hibernate 保存具有引用依赖实体的实体

java - 如何在 Spring Boot Rest 中正确发布 json 对象