Fix IN and OUT instructions decoding

This commit is contained in:
Joseph Ferano 2025-03-22 15:20:48 +07:00
parent ab2b107e7e
commit ea7b65994b
2 changed files with 13 additions and 9 deletions

View File

@ -128,7 +128,7 @@ parse_operand :: proc(inst: InstructionInfo, opinfo: OperandInfo, data: []u8, pr
operand = Immediate { value = i16(data[processed^]), size = .Unsigned8 } operand = Immediate { value = i16(data[processed^]), size = .Unsigned8 }
processed^ += 1 processed^ += 1
case .Accumulator: case .Accumulator:
operand = RegisterId { name = Register(0), access = word ? .Full : .Low } operand = RegisterId { name = .ax, access = word ? .Full : .Low }
case .DirectAddress: case .DirectAddress:
// operand = DirectAddress { value = get_i16(data[1:]) } // operand = DirectAddress { value = get_i16(data[1:]) }
operand = (DirectAddress)(get_i16(data[1:])) operand = (DirectAddress)(get_i16(data[1:]))
@ -138,7 +138,14 @@ parse_operand :: proc(inst: InstructionInfo, opinfo: OperandInfo, data: []u8, pr
// NOTE: In order to mimic the label offset, you have to take the value you got and add two // NOTE: In order to mimic the label offset, you have to take the value you got and add two
operand = (Jump)((i8)(data[1]) + 2) operand = (Jump)((i8)(data[1]) + 2)
case .VariablePort: case .VariablePort:
operand = RegisterId { name = Register.dx, access = .Full } // NOTE: This isn't documented in the manual, but you can tell if we need to use
// the dx register or an immediate if the 4th LSB bit is set
if (data[0] & 0b1000) >> 3 == 1 {
operand = RegisterId { name = .dx, access = .Full }
} else {
operand = Immediate { value = i16(i8(data[1])), size = ._8 }
processed^ += 1
}
case .ShiftRotate: case .ShiftRotate:
v_flag := data[0] & 0b10 != 0 v_flag := data[0] & 0b10 != 0
operand = v_flag ? RegisterId { name = Register(1), access = .Low } : Immediate { value = 1 } operand = v_flag ? RegisterId { name = Register(1), access = .Low } : Immediate { value = 1 }

View File

@ -194,16 +194,13 @@ instructions := [?]InstructionInfo {
dst = .Accumulator, src = .Register, dst = .Accumulator, src = .Register,
reg_info = .FirstByteLast3, has_flip = true, word_size = .Always16 }, reg_info = .FirstByteLast3, has_flip = true, word_size = .Always16 },
{ opname = .IN, desc = "", mask = 0b11111110, encoding = 0b11100100, { opname = .IN, desc = "", mask = 0b11111110, encoding = 0b11100100,
dst = .Accumulator, src = .ImmediateUnsigned }, dst = .Accumulator, src = .Immediate, word_size = .LastBit },
{ opname = .IN, desc = "", mask = 0b11111110, encoding = 0b11101100, { opname = .IN, desc = "", mask = 0b11111110, encoding = 0b11101100,
dst = .Accumulator, src = .VariablePort, dst = .Accumulator, src = .VariablePort, word_size = .LastBit, },
word_size = .LastBit, },
{ opname = .OUT, desc = "", mask = 0b11111110, encoding = 0b11100110, { opname = .OUT, desc = "", mask = 0b11111110, encoding = 0b11100110,
dst = .ImmediateUnsigned, src = .Accumulator, dst = .VariablePort, src = .Accumulator, word_size = .LastBit },
word_size = .LastBit, },
{ opname = .OUT, desc = "", mask = 0b11111110, encoding = 0b11101110, { opname = .OUT, desc = "", mask = 0b11111110, encoding = 0b11101110,
dst = .VariablePort, src = .Accumulator, dst = .VariablePort, src = .Accumulator, word_size = .LastBit, },
word_size = .LastBit, },
{ opname = .TEST, desc = "", mask = 0b11111110, encoding = 0b10101000, { opname = .TEST, desc = "", mask = 0b11111110, encoding = 0b10101000,
dst = .Accumulator, src = .Immediate, word_size = .LastBit }, dst = .Accumulator, src = .Immediate, word_size = .LastBit },
{ opname = .XLAT, desc = "", mask = 0b11111111, encoding = 0b11010111,}, { opname = .XLAT, desc = "", mask = 0b11111111, encoding = 0b11010111,},