mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Fix $8e data size, add $8c.
This commit is contained in:
parent
1afcbba218
commit
eb180656bb
@ -233,9 +233,12 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
|
|||||||
case 0x89: MemRegReg(MOV, MemReg_Reg, data_size_); break;
|
case 0x89: MemRegReg(MOV, MemReg_Reg, data_size_); break;
|
||||||
case 0x8a: MemRegReg(MOV, Reg_MemReg, DataSize::Byte); break;
|
case 0x8a: MemRegReg(MOV, Reg_MemReg, DataSize::Byte); break;
|
||||||
case 0x8b: MemRegReg(MOV, Reg_MemReg, data_size_); break;
|
case 0x8b: MemRegReg(MOV, Reg_MemReg, data_size_); break;
|
||||||
// 0x8c: not used.
|
case 0x8c:
|
||||||
|
RequiresMin(i80286); // TODO: or is this 80386?
|
||||||
|
MemRegReg(MOV, MemReg_Seg, DataSize::Word);
|
||||||
|
break;
|
||||||
case 0x8d: MemRegReg(LEA, Reg_MemReg, data_size_); break;
|
case 0x8d: MemRegReg(LEA, Reg_MemReg, data_size_); break;
|
||||||
case 0x8e: MemRegReg(MOV, SegReg, data_size_); break;
|
case 0x8e: MemRegReg(MOV, Seg_MemReg, DataSize::Word); break;
|
||||||
case 0x8f: MemRegReg(POP, MemRegPOP, data_size_); break;
|
case 0x8f: MemRegReg(POP, MemRegPOP, data_size_); break;
|
||||||
|
|
||||||
case 0x90: Complete(NOP, None, None, DataSize::None); break; // Or XCHG AX, AX?
|
case 0x90: Complete(NOP, None, None, DataSize::None); break; // Or XCHG AX, AX?
|
||||||
@ -430,10 +433,15 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
|
|||||||
++consumed_;
|
++consumed_;
|
||||||
|
|
||||||
Source memreg;
|
Source memreg;
|
||||||
|
|
||||||
|
// TODO: can I just eliminate these lookup tables given the deliberate ordering within Source?
|
||||||
constexpr Source reg_table[8] = {
|
constexpr Source reg_table[8] = {
|
||||||
Source::eAX, Source::eCX, Source::eDX, Source::eBX,
|
Source::eAX, Source::eCX, Source::eDX, Source::eBX,
|
||||||
Source::eSPorAH, Source::eBPorCH, Source::eSIorDH, Source::eDIorBH,
|
Source::eSPorAH, Source::eBPorCH, Source::eSIorDH, Source::eDIorBH,
|
||||||
};
|
};
|
||||||
|
constexpr Source seg_table[6] = {
|
||||||
|
Source::ES, Source::CS, Source::SS, Source::DS, Source::FS, Source::GS
|
||||||
|
};
|
||||||
switch(mod) {
|
switch(mod) {
|
||||||
default: {
|
default: {
|
||||||
const DataSize sizes[] = {DataSize::Byte, data_size_};
|
const DataSize sizes[] = {DataSize::Byte, data_size_};
|
||||||
@ -495,20 +503,29 @@ std::pair<int, typename Decoder<model>::InstructionT> Decoder<model>::decode(con
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ModRegRMFormat::SegReg: {
|
case ModRegRMFormat::Seg_MemReg:
|
||||||
source_ = memreg;
|
case ModRegRMFormat::MemReg_Seg:
|
||||||
|
// The 16-bit chips have four segment registers;
|
||||||
constexpr Source seg_table[4] = {
|
// the 80386 onwards has six.
|
||||||
Source::ES, Source::CS,
|
if(!is_32bit(model) && reg > 3) {
|
||||||
Source::SS, Source::DS,
|
undefined();
|
||||||
};
|
} else if(reg > 5) {
|
||||||
|
|
||||||
if(reg & 4) {
|
|
||||||
undefined();
|
undefined();
|
||||||
}
|
}
|
||||||
|
|
||||||
destination_ = seg_table[reg];
|
if(modregrm_format_ == ModRegRMFormat::Seg_MemReg) {
|
||||||
} break;
|
source_ = memreg;
|
||||||
|
destination_ = seg_table[reg];
|
||||||
|
|
||||||
|
// 80286 and later disallow MOV to CS.
|
||||||
|
if(model >= Model::i80286 && destination_ == Source::CS) {
|
||||||
|
undefined();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
source_ = seg_table[reg];
|
||||||
|
destination_ = memreg;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case ModRegRMFormat::MemRegROL_to_SAR:
|
case ModRegRMFormat::MemRegROL_to_SAR:
|
||||||
destination_ = memreg;
|
destination_ = memreg;
|
||||||
|
@ -65,7 +65,7 @@ template <Model model> class Decoder {
|
|||||||
/// are packaged into an Instruction.
|
/// are packaged into an Instruction.
|
||||||
enum class ModRegRMFormat: uint8_t {
|
enum class ModRegRMFormat: uint8_t {
|
||||||
// Parse the ModRegRM for mode, register and register/memory fields
|
// Parse the ModRegRM for mode, register and register/memory fields
|
||||||
// and populate the source_ and destination_ fields appropriate.
|
// and populate the source_ and destination_ fields appropriately.
|
||||||
MemReg_Reg,
|
MemReg_Reg,
|
||||||
Reg_MemReg,
|
Reg_MemReg,
|
||||||
|
|
||||||
@ -82,7 +82,8 @@ template <Model model> class Decoder {
|
|||||||
// Parse for mode and register/memory fields, populating the
|
// Parse for mode and register/memory fields, populating the
|
||||||
// source_ field with the result. Fills destination_ with a segment
|
// source_ field with the result. Fills destination_ with a segment
|
||||||
// register based on the reg field.
|
// register based on the reg field.
|
||||||
SegReg,
|
Seg_MemReg,
|
||||||
|
MemReg_Seg,
|
||||||
|
|
||||||
//
|
//
|
||||||
// 'Group 1'
|
// 'Group 1'
|
||||||
|
Loading…
x
Reference in New Issue
Block a user