mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Correct data size when accessing address registers.
This commit is contained in:
parent
84ac68a58b
commit
9f12c009d6
@ -82,13 +82,13 @@ 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, allow_write) \
|
||||||
case Source::x: \
|
case Source::x: \
|
||||||
if constexpr(allow_write && is_write) {\
|
if constexpr(allow_write && is_write) { \
|
||||||
registers.template write<DataT, register_for_source<DataT>(Source::x)>(v); \
|
registers.template write<decltype(v), register_for_source<decltype(v)>(Source::x)>(v); \
|
||||||
} else { \
|
} else { \
|
||||||
value = registers.template read<DataT, register_for_source<DataT>(Source::x)>(); \
|
v = registers.template read<decltype(v), register_for_source<decltype(v)>(Source::x)>(); \
|
||||||
} \
|
} \
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#define ALLREGS(v) f(v, eAX); f(v, eCX); f(v, eDX); f(v, eBX); \
|
#define ALLREGS(v) f(v, eAX); f(v, eCX); f(v, eDX); f(v, eBX); \
|
||||||
@ -118,7 +118,8 @@ template <Model model, typename RegistersT, typename MemoryT> class DataPointerR
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case Source::Indirect: {
|
case Source::Indirect: {
|
||||||
uint32_t base = 0, index = 0;
|
using AddressT = typename Instruction<is_32bit(model)>::AddressComponentT;
|
||||||
|
AddressT base = 0, index = 0;
|
||||||
|
|
||||||
#define f(x, y) read_or_write(x, y, false)
|
#define f(x, y) read_or_write(x, y, false)
|
||||||
switch(pointer.base()) {
|
switch(pointer.base()) {
|
||||||
@ -132,14 +133,17 @@ template <Model model, typename RegistersT, typename MemoryT> class DataPointerR
|
|||||||
}
|
}
|
||||||
#undef f
|
#undef f
|
||||||
|
|
||||||
|
// Compute address as 32-bit; its always at least 20 bits
|
||||||
|
// and at most 32.
|
||||||
|
uint32_t address = index;
|
||||||
if constexpr (model >= Model::i80386) {
|
if constexpr (model >= Model::i80386) {
|
||||||
index <<= pointer.scale();
|
address <<= pointer.scale();
|
||||||
} else {
|
} else {
|
||||||
assert(!pointer.scale());
|
assert(!pointer.scale());
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: verify application of memory_mask here.
|
// TODO: verify application of memory_mask here.
|
||||||
const uint32_t address = (base & memory_mask) + (index & memory_mask);
|
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>(
|
||||||
|
@ -511,6 +511,7 @@ template<bool is_32bit> class Instruction {
|
|||||||
|
|
||||||
using DisplacementT = typename std::conditional<is_32bit, int32_t, int16_t>::type;
|
using DisplacementT = typename std::conditional<is_32bit, int32_t, int16_t>::type;
|
||||||
using ImmediateT = typename std::conditional<is_32bit, uint32_t, uint16_t>::type;
|
using ImmediateT = typename std::conditional<is_32bit, uint32_t, uint16_t>::type;
|
||||||
|
using AddressComponentT = ImmediateT;
|
||||||
|
|
||||||
/* Note to self — current thinking is:
|
/* Note to self — current thinking is:
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ using namespace InstructionSet::x86;
|
|||||||
template<typename DataT> DataT read(Source segment, uint32_t address) {
|
template<typename DataT> DataT read(Source segment, uint32_t address) {
|
||||||
(void)segment;
|
(void)segment;
|
||||||
(void)address;
|
(void)address;
|
||||||
printf("Access at %d\n", 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) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user