mirror of
https://github.com/TomHarte/CLK.git
synced 2025-08-06 16:25:35 +00:00
Incorporate displacement, switch macro flag.
This commit is contained in:
@@ -82,9 +82,9 @@ template <Model model, typename RegistersT, typename MemoryT> class DataPointerR
|
|||||||
DataT &value) {
|
DataT &value) {
|
||||||
const Source source = pointer.source();
|
const Source source = pointer.source();
|
||||||
|
|
||||||
#define read_or_write(v, x, allow_write) \
|
#define read_or_write(v, x, is_for_indirection) \
|
||||||
case Source::x: \
|
case Source::x: \
|
||||||
if constexpr(allow_write && is_write) { \
|
if constexpr(!is_for_indirection && is_write) { \
|
||||||
registers.template write<decltype(v), register_for_source<decltype(v)>(Source::x)>(v); \
|
registers.template write<decltype(v), register_for_source<decltype(v)>(Source::x)>(v); \
|
||||||
} else { \
|
} else { \
|
||||||
v = registers.template read<decltype(v), register_for_source<decltype(v)>(Source::x)>(); \
|
v = registers.template read<decltype(v), register_for_source<decltype(v)>(Source::x)>(); \
|
||||||
@@ -102,7 +102,7 @@ template <Model model, typename RegistersT, typename MemoryT> class DataPointerR
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
#define f(x, y) read_or_write(x, y, true)
|
#define f(x, y) read_or_write(x, y, false)
|
||||||
ALLREGS(value);
|
ALLREGS(value);
|
||||||
#undef f
|
#undef f
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ template <Model model, typename RegistersT, typename MemoryT> class DataPointerR
|
|||||||
using AddressT = typename Instruction<is_32bit(model)>::AddressComponentT;
|
using AddressT = typename Instruction<is_32bit(model)>::AddressComponentT;
|
||||||
AddressT base = 0, index = 0;
|
AddressT base = 0, index = 0;
|
||||||
|
|
||||||
#define f(x, y) read_or_write(x, y, false)
|
#define f(x, y) read_or_write(x, y, true)
|
||||||
switch(pointer.base()) {
|
switch(pointer.base()) {
|
||||||
default: break;
|
default: break;
|
||||||
ALLREGS(base);
|
ALLREGS(base);
|
||||||
@@ -133,8 +133,12 @@ template <Model model, typename RegistersT, typename MemoryT> class DataPointerR
|
|||||||
}
|
}
|
||||||
#undef f
|
#undef f
|
||||||
|
|
||||||
// Compute address as 32-bit; its always at least 20 bits
|
// Always compute address as 32-bit.
|
||||||
// and at most 32.
|
// TODO: verify application of memory_mask here.
|
||||||
|
// The point of memory_mask is that 32-bit x86 offers the memory size modifier,
|
||||||
|
// permitting 16-bit addresses to be generated in 32-bit mode and vice versa.
|
||||||
|
// To figure out is at what point in the calculation the 16-bit constraint is
|
||||||
|
// applied when active.
|
||||||
uint32_t address = index;
|
uint32_t address = index;
|
||||||
if constexpr (model >= Model::i80386) {
|
if constexpr (model >= Model::i80386) {
|
||||||
address <<= pointer.scale();
|
address <<= pointer.scale();
|
||||||
@@ -142,8 +146,7 @@ template <Model model, typename RegistersT, typename MemoryT> class DataPointerR
|
|||||||
assert(!pointer.scale());
|
assert(!pointer.scale());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: verify application of memory_mask here.
|
address = (address & memory_mask) + (base & memory_mask) + instruction.displacement();
|
||||||
address = (address & memory_mask) + (base & memory_mask);
|
|
||||||
|
|
||||||
if constexpr (is_write) {
|
if constexpr (is_write) {
|
||||||
value = memory.template read<DataT>(
|
value = memory.template read<DataT>(
|
||||||
|
@@ -46,10 +46,8 @@ using namespace InstructionSet::x86;
|
|||||||
} registers;
|
} registers;
|
||||||
|
|
||||||
struct Memory {
|
struct Memory {
|
||||||
template<typename DataT> DataT read(Source segment, uint32_t address) {
|
template<typename DataT> DataT read(Source, uint32_t address) {
|
||||||
(void)segment;
|
if(address == 01234 + 0x00ee) return 0xff;
|
||||||
(void)address;
|
|
||||||
printf("Access at %08x\n", address);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
template<typename DataT> void write(Source, uint32_t, DataT) {
|
template<typename DataT> void write(Source, uint32_t, DataT) {
|
||||||
@@ -58,9 +56,7 @@ using namespace InstructionSet::x86;
|
|||||||
|
|
||||||
} memory;
|
} memory;
|
||||||
|
|
||||||
const auto instruction = Instruction<false>();/*[self
|
const auto instruction = Instruction<false>();
|
||||||
instruction16WithSourceDataPointer:pointer];*/
|
|
||||||
|
|
||||||
const uint8_t value = DataPointerResolver<
|
const uint8_t value = DataPointerResolver<
|
||||||
Model::i8086, Registers, Memory>::read<uint8_t>(
|
Model::i8086, Registers, Memory>::read<uint8_t>(
|
||||||
registers,
|
registers,
|
||||||
@@ -69,7 +65,7 @@ using namespace InstructionSet::x86;
|
|||||||
pointer
|
pointer
|
||||||
);
|
);
|
||||||
|
|
||||||
printf("%d\n", value);
|
XCTAssertEqual(value, 0xff);
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
Reference in New Issue
Block a user