mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-29 12:50:28 +00:00
It's differing mildly from DataPointResolver, but segue towards a world of real data.
This commit is contained in:
parent
eb100e3b29
commit
ada411c0d8
@ -197,12 +197,92 @@ template <
|
|||||||
[[maybe_unused]] IOT &io
|
[[maybe_unused]] IOT &io
|
||||||
) {
|
) {
|
||||||
using IntT = typename DataSizeType<data_size>::type;
|
using IntT = typename DataSizeType<data_size>::type;
|
||||||
|
using AddressT = typename AddressT<is_32bit(model)>::type;
|
||||||
|
|
||||||
// Establish source() and destination() shorthand to fetch data if necessary.
|
// Establish source() and destination() shorthand to fetch data if necessary.
|
||||||
IntT fetched_data;
|
IntT fetched_data = 0, original_data = 0;
|
||||||
bool needs_writeback = false;
|
Source segment;
|
||||||
|
AddressT address;
|
||||||
|
|
||||||
|
static constexpr IntT zero = 0;
|
||||||
auto data = [&](DataPointer source) -> IntT& {
|
auto data = [&](DataPointer source) -> IntT& {
|
||||||
// TODO.
|
// Rules:
|
||||||
|
//
|
||||||
|
// * if this is a memory access, set target_address and break;
|
||||||
|
// * otherwise return the appropriate value.
|
||||||
|
switch(source.source<false>()) {
|
||||||
|
case Source::eAX:
|
||||||
|
switch(data_size) {
|
||||||
|
default: return registers.al();
|
||||||
|
case DataSize::Word: return registers.ax();
|
||||||
|
case DataSize::DWord: return registers.eax();
|
||||||
|
}
|
||||||
|
case Source::eCX:
|
||||||
|
switch(data_size) {
|
||||||
|
default: return registers.cl();
|
||||||
|
case DataSize::Word: return registers.cx();
|
||||||
|
case DataSize::DWord: return registers.ecx();
|
||||||
|
}
|
||||||
|
case Source::eDX:
|
||||||
|
switch(data_size) {
|
||||||
|
default: return registers.dl();
|
||||||
|
case DataSize::Word: return registers.dx();
|
||||||
|
case DataSize::DWord: return registers.edx();
|
||||||
|
}
|
||||||
|
case Source::eBX:
|
||||||
|
switch(data_size) {
|
||||||
|
default: return registers.bl();
|
||||||
|
case DataSize::Word: return registers.bx();
|
||||||
|
case DataSize::DWord: return registers.ebx();
|
||||||
|
}
|
||||||
|
case Source::eSPorAH:
|
||||||
|
switch(data_size) {
|
||||||
|
default: return registers.ah();
|
||||||
|
case DataSize::Word: return registers.sp();
|
||||||
|
case DataSize::DWord: return registers.esp();
|
||||||
|
}
|
||||||
|
case Source::eBPorCH:
|
||||||
|
switch(data_size) {
|
||||||
|
default: return registers.ch();
|
||||||
|
case DataSize::Word: return registers.bp();
|
||||||
|
case DataSize::DWord: return registers.ebp();
|
||||||
|
}
|
||||||
|
case Source::eSIorDH:
|
||||||
|
switch(data_size) {
|
||||||
|
default: return registers.dh();
|
||||||
|
case DataSize::Word: return registers.si();
|
||||||
|
case DataSize::DWord: return registers.esi();
|
||||||
|
}
|
||||||
|
case Source::eDIorBH:
|
||||||
|
switch(data_size) {
|
||||||
|
default: return registers.bh();
|
||||||
|
case DataSize::Word: return registers.di();
|
||||||
|
case DataSize::DWord: return registers.edi();
|
||||||
|
}
|
||||||
|
|
||||||
|
case Source::ES: return registers.es();
|
||||||
|
case Source::CS: return registers.cs();
|
||||||
|
case Source::SS: return registers.ss();
|
||||||
|
case Source::DS: return registers.ds();
|
||||||
|
case Source::FS: return registers.fs();
|
||||||
|
case Source::GS: return registers.gs();
|
||||||
|
|
||||||
|
case Source::Immediate: // TODO (here the use of a reference falls down?)
|
||||||
|
|
||||||
|
case Source::None: return zero;
|
||||||
|
|
||||||
|
case Source::Indirect: // TODO
|
||||||
|
case Source::IndirectNoBase: // TODO
|
||||||
|
|
||||||
|
case Source::DirectAddress:
|
||||||
|
address = instruction.offset();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If execution has reached here then a memory fetch is required.
|
||||||
|
// Do it and exit.
|
||||||
|
segment = Source::DS; // TODO.
|
||||||
|
fetched_data = original_data = memory.template read<IntT>(segment, address);
|
||||||
return fetched_data;
|
return fetched_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -225,7 +305,7 @@ template <
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Write to memory if required to complete this operation.
|
// Write to memory if required to complete this operation.
|
||||||
if(needs_writeback) {
|
if(original_data != fetched_data) {
|
||||||
// TODO.
|
// TODO.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
#ifndef Model_h
|
#ifndef Model_h
|
||||||
#define Model_h
|
#define Model_h
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
namespace InstructionSet::x86 {
|
namespace InstructionSet::x86 {
|
||||||
|
|
||||||
enum class Model {
|
enum class Model {
|
||||||
@ -20,6 +22,9 @@ enum class Model {
|
|||||||
|
|
||||||
static constexpr bool is_32bit(Model model) { return model >= Model::i80386; }
|
static constexpr bool is_32bit(Model model) { return model >= Model::i80386; }
|
||||||
|
|
||||||
|
template <bool is_32bit> struct AddressT { using type = uint16_t; };
|
||||||
|
template <> struct AddressT<true> { using type = uint32_t; };
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Model_h */
|
#endif /* Model_h */
|
||||||
|
Loading…
Reference in New Issue
Block a user