1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-26 23:52:26 +00:00

Takes a run at 0x82 and 0x83, completing the set.

This commit is contained in:
Thomas Harte 2021-01-13 20:29:44 -05:00
parent 5058a8b96a
commit a24ae727a7
2 changed files with 37 additions and 6 deletions

View File

@ -165,13 +165,10 @@ std::pair<int, Instruction> Decoder::decode(const uint8_t *source, size_t length
case 0x7e: Jump(JLE); break;
case 0x7f: Jump(JNLE); break;
// TODO:
//
// 0x82, 0x83, which will require me to do something
// re: word-sign extended.
case 0x80: MemRegReg(Invalid, MemRegADD_to_CMP, 1); break;
case 0x81: MemRegReg(Invalid, MemRegADD_to_CMP, 2); break;
case 0x82: MemRegReg(Invalid, MemRegADC_to_CMP, 1); break;
case 0x83: MemRegReg(Invalid, MemRegADC_to_CMP, 2); break;
case 0x84: MemRegReg(TEST, MemReg_Reg, 1); break;
case 0x85: MemRegReg(TEST, MemReg_Reg, 2); break;
@ -531,6 +528,27 @@ std::pair<int, Instruction> Decoder::decode(const uint8_t *source, size_t length
}
break;
case ModRegRMFormat::MemRegADC_to_CMP:
destination_ = memreg;
source_ = Source::Immediate;
operand_size_ = 1; // ... and always 1; it'll be sign extended if
// the operation requires it.
switch(reg) {
default: {
const auto result = std::make_pair(consumed_, Instruction());
reset_parsing();
return result;
}
case 0: operation_ = Operation::ADD; break;
case 2: operation_ = Operation::ADC; break;
case 3: operation_ = Operation::SBB; break;
case 5: operation_ = Operation::SUB; break;
case 7: operation_ = Operation::CMP; break;
}
break;
default: assert(false);
}
@ -562,7 +580,14 @@ std::pair<int, Instruction> Decoder::decode(const uint8_t *source, size_t length
switch(operand_size_) {
default: operand_ = 0; break;
case 1: operand_ = inward_data_ >> 56; inward_data_ <<= 8; break;
case 1:
operand_ = inward_data_ >> 56; inward_data_ <<= 8;
// Sign extend if a single byte operand is feeding a two-byte instruction.
if(operation_size_ == 2) {
operand_ |= (operand_ & 0x80) ? 0xff : 0x00;
}
break;
case 2: operand_ = inward_data_ >> 48; inward_data_ <<= 16; break;
}
switch(displacement_size_) {

View File

@ -259,6 +259,12 @@ struct Decoder {
// 'register' field to pick from INC/DEC/CALL/JMP/PUSH, altering
// the source to ::Immediate and setting an operand size if necessary.
MemRegINC_to_PUSH,
// Parse for mode and register/memory fields, populating the
// source_ and destination_ fields with the result. Uses the
// 'register' field to pick from ADD/ADC/SBB/SUB/CMP, altering
// the source to ::Immediate and setting an appropriate operand size.
MemRegADC_to_CMP,
} modregrm_format_ = ModRegRMFormat::MemReg_Reg;
// Ephemeral decoding state.