mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-16 18:30:32 +00:00
Introduces the easy F page instructions.
This commit is contained in:
parent
7ceb3369eb
commit
0bd63cf00f
@ -81,6 +81,12 @@ std::pair<int, InstructionSet::x86::Instruction> Decoder::decode(const uint8_t *
|
||||
displacement_size_ = 2; \
|
||||
operand_size_ = 1; \
|
||||
|
||||
#define undefined() { \
|
||||
const auto result = std::make_pair(consumed_, Instruction()); \
|
||||
reset_parsing(); \
|
||||
return result; \
|
||||
}
|
||||
|
||||
while(phase_ == Phase::Instruction && source != end) {
|
||||
// Retain the instruction byte, in case additional decoding is deferred
|
||||
// to the ModRegRM byte.
|
||||
@ -88,12 +94,6 @@ std::pair<int, InstructionSet::x86::Instruction> Decoder::decode(const uint8_t *
|
||||
++source;
|
||||
++consumed_;
|
||||
|
||||
#define undefined() { \
|
||||
const auto result = std::make_pair(consumed_, Instruction()); \
|
||||
reset_parsing(); \
|
||||
return result; \
|
||||
}
|
||||
|
||||
switch(instr_) {
|
||||
default: undefined();
|
||||
|
||||
@ -112,6 +112,13 @@ std::pair<int, InstructionSet::x86::Instruction> Decoder::decode(const uint8_t *
|
||||
PartialBlock(0x08, OR); break;
|
||||
case 0x0e: Complete(PUSH, CS, None, 2); break;
|
||||
|
||||
// The 286 onwards have a further set of instructions
|
||||
// prefixed with $0f.
|
||||
case 0x0f:
|
||||
if(model_ < Model::i80286) undefined();
|
||||
phase_ = Phase::InstructionPageF;
|
||||
break;
|
||||
|
||||
PartialBlock(0x10, ADC); break;
|
||||
case 0x16: Complete(PUSH, SS, None, 2); break;
|
||||
case 0x17: Complete(POP, None, SS, 2); break;
|
||||
@ -167,6 +174,10 @@ std::pair<int, InstructionSet::x86::Instruction> Decoder::decode(const uint8_t *
|
||||
if(model_ < Model::i80186) undefined();
|
||||
MemRegReg(BOUND, Reg_MemReg, 2);
|
||||
break;
|
||||
case 0x63:
|
||||
if(model_ < Model::i80286) undefined();
|
||||
MemRegReg(ARPL, MemReg_Reg, 2);
|
||||
break;
|
||||
case 0x6c: // INSB
|
||||
if(model_ < Model::i80186) undefined();
|
||||
Complete(INS, None, None, 1);
|
||||
@ -365,6 +376,28 @@ std::pair<int, InstructionSet::x86::Instruction> Decoder::decode(const uint8_t *
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Additional F page of instructions.
|
||||
if(phase_ == Phase::InstructionPageF && source != end) {
|
||||
// Update the instruction acquired.
|
||||
instr_ = 0x0f00 | *source;
|
||||
++source;
|
||||
++consumed_;
|
||||
|
||||
// NB: to reach here, the instruction set must be at least
|
||||
// that of an 80286.
|
||||
switch(instr_) {
|
||||
default: undefined();
|
||||
|
||||
case 0x02: MemRegReg(LAR, Reg_MemReg, 2); break;
|
||||
case 0x03: MemRegReg(LSL, Reg_MemReg, 2); break;
|
||||
case 0x06: Complete(CLTS, None, None, 1); break;
|
||||
}
|
||||
// TODO: 0x0f 0x00 -> LLDT/SLDT/VERR/VERW/LTR/STR
|
||||
// TODO: 0x0f 0x01 -> LGDT/LIDT/SGDT/SIDT/LMSW/SMSW
|
||||
// TODO: 0x0f 0x05 -> LOADALL
|
||||
|
||||
}
|
||||
|
||||
#undef Far
|
||||
#undef Jump
|
||||
#undef MemRegReg
|
||||
|
@ -48,6 +48,8 @@ class Decoder {
|
||||
enum class Phase {
|
||||
/// Captures all prefixes and continues until an instruction byte is encountered.
|
||||
Instruction,
|
||||
/// Having encountered a 0x0f first instruction byte, waits for the next byte fully to determine the instruction.
|
||||
InstructionPageF,
|
||||
/// Receives a ModRegRM byte and either populates the source_ and dest_ fields appropriately
|
||||
/// or completes decoding of the instruction, as per the instruction format.
|
||||
ModRegRM,
|
||||
@ -119,7 +121,7 @@ class Decoder {
|
||||
|
||||
// Ephemeral decoding state.
|
||||
Operation operation_ = Operation::Invalid;
|
||||
uint8_t instr_ = 0x00; // TODO: is this desired, versus loading more context into ModRegRMFormat?
|
||||
uint16_t instr_ = 0x0000; // TODO: is this desired, versus loading more context into ModRegRMFormat?
|
||||
int consumed_ = 0, operand_bytes_ = 0;
|
||||
|
||||
// Source and destination locations.
|
||||
|
Loading…
x
Reference in New Issue
Block a user