我正在尝试用 C# 编写一个chip8 模拟器。有必要在软件中模拟实际芯片上硬件中发生的操作。
有一个操作码需要检测两个二进制数相减过程中是否发生借位。
Byte1 - Byte2
有没有人知道如何使用 C# 来判断是否发生了借用?
我正在尝试用 C# 编写一个chip8 模拟器。有必要在软件中模拟实际芯片上硬件中发生的操作。
有一个操作码需要检测两个二进制数相减过程中是否发生借位。
Byte1 - Byte2
有没有人知道如何使用 C# 来判断是否发生了借用?
在Wikipedia中搜索您未提及的神秘操作码并寻找一些实现之后。我可以得出结论,操作码 8XY5 和 8XY7(其中 X 和 Y 是寄存器标识符)将进行减法运算。
对于 8XY5,寄存器 X 将设置为寄存器 X 的值减去寄存器 Y 的值。如果寄存器 Y 的值大于或等于寄存器 X 的值,则寄存器 F 将设置为 1 (否则为 0)。
对于 8XY7,寄存器 X 将设置为寄存器 Y 的值减去寄存器 X 的值。如果寄存器 X 的值大于或等于寄存器 Y 的值,则寄存器 F 将设置为 1 (否则为 0)。
这是 8XY5 的“伪”代码:
x = opcode[1]
y = opcode[2]
if (register[x] >= register[y])
register[0xF] = 1
else
register[0xF] = 0
result = register[x] - register[y]
if result < 0
result += 256
register[x] = result
这是 8XY7 的“伪”代码:
x = opcode[1]
y = opcode[2]
if (register[y] >= register[x])
register[0xF] = 1
else
register[0xF] = 0
result = register[y] - register[x]
if result < 0
result += 256
register[x] = result
这是一个 C# 实现:
const byte B_0 = 0x0;
const byte B_1 = 0x1;
const byte B_F = 0xF;
static void Main()
{
byte[] registers = new byte[16];
registers[0x1] = 255;
registers[0x2] = 127;
Opcode8XY5(registers, 1, 2);
Console.WriteLine(registers[0x1]);
Console.WriteLine(registers[0x2]);
Console.WriteLine(registers[0xF]);
Opcode8XY7(registers, 1, 2);
Console.WriteLine(registers[0x1]);
Console.WriteLine(registers[0x2]);
Console.WriteLine(registers[0xF]);
Console.ReadLine();
}
static void Opcode8XY5(byte[] registers, byte x, byte y)
{
registers[B_F] = registers[x] >= registers[y] ? B_1 : B_0;
registers[x] = (byte)(registers[x] - registers[y]);
}
static void Opcode8XY7(byte[] registers, byte x, byte y)
{
registers[B_F] = registers[y] >= registers[x] ? B_1 : B_0;
registers[x] = (byte)(registers[y] - registers[x]);
}
检查此实现以供参考。
您将需要比较字节的每一位...如果设置了第二个字节位但未设置第一个字节,则您有借用条件:
static void Main(string[] args) {
byte b1 = byte.Parse(args[0]);
byte b2 = byte.Parse(args[1]);
bool borrow = false;
for (int mask = 0x01; mask <= 0x80; mask <<= 1) {
if ((b2 & mask) > (b1 & mask)) {
borrow = true;
}
}
Console.WriteLine(Convert.ToString(b1, 2).PadLeft(8, '0'));
Console.WriteLine(Convert.ToString(b2, 2).PadLeft(8, '0'));
Console.WriteLine("borrowed: {0}", borrow);
}
可能有一个非常聪明的布尔逻辑可以给你答案,但我现在想不出。
如果类型转换不是符号传播,您需要使用更广泛的类型进行数学计算。然后检查结果是否将第 8 位设置为 1。如果已设置,则借位。然后将结果保存为字节。