1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-12-23 20:29:42 +00:00

Extends to offer simpler 8-bit access handling.

This commit is contained in:
Thomas Harte 2019-12-08 20:19:44 -05:00
parent 4536c6a224
commit 407cc78c78

View File

@ -49,23 +49,25 @@ namespace MC68000 {
avoid the runtime cost of actual DTack emulation. But such as the bus allows.)
*/
struct Microcycle {
/// Indicates that the address strobe and exactly one of the data strobes are active; you can determine
/// which by inspecting the low bit of the provided address. The RW line indicates a read.
static const int SelectByte = 1 << 0;
// Maintenance note: this is bit 0 to reduce the cost of getting a host-endian
// bytewise address. See implementation of host_endian_byte_address().
/// Indicates that the address and both data select strobes are active.
static const int SelectWord = 1 << 1;
/// A NewAddress cycle is one in which the address strobe is initially low but becomes high;
/// this correlates to states 0 to 5 of a standard read/write cycle.
static const int NewAddress = 1 << 0;
static const int NewAddress = 1 << 2;
/// A SameAddress cycle is one in which the address strobe is continuously asserted, but neither
/// of the data strobes are.
static const int SameAddress = 1 << 1;
static const int SameAddress = 1 << 3;
/// A Reset cycle is one in which the RESET output is asserted.
static const int Reset = 1 << 2;
/// Indicates that the address and both data select strobes are active.
static const int SelectWord = 1 << 3;
/// Indicates that the address strobe and exactly one of the data strobes are active; you can determine
/// which by inspecting the low bit of the provided address. The RW line indicates a read.
static const int SelectByte = 1 << 4;
static const int Reset = 1 << 4;
/// If set, indicates a read. Otherwise, a write.
static const int Read = 1 << 5;
@ -196,6 +198,25 @@ struct Microcycle {
return (address ? (*address) & 0x00fffffe : 0) >> 1;
}
/*!
@returns the address of the word or byte being accessed at byte precision,
in the endianness of the host platform.
So: if this is a word access, and the 68000 wants to select the word at address
@c n, this will evaluate to @c n regardless of the host machine's endianness..
If this is a byte access and the host machine is big endian it will evalue to @c n.
If the host machine is little endian then it will evaluate to @c n^1.
*/
forceinline uint32_t host_endian_byte_address() const {
#if TARGET_RT_BIG_ENDIAN
return *address & 0xffffff;
#else
return (*address ^ (1 & operation & SelectByte)) & 0xffffff;
#endif
}
/*!
@returns the value on the data bus all 16 bits, with any inactive lines
(as er the upper and lower data selects) being represented by 1s. Assumes
@ -273,6 +294,34 @@ struct Microcycle {
return ((*address) & 0x00fffffe) >> 1;
}
/*!
Assuming this to be a cycle with a data select active, applies it to @c target,
where 'applies' means:
* if this is a byte read, reads a single byte from @c target;
* if this is a word read, reads a word (in the host platform's endianness) from @c target; and
* if this is a write, does the converse of a read.
*/
forceinline void apply(uint8_t *target) const {
switch(operation & (SelectWord | SelectByte | Read)) {
default:
break;
case SelectWord | Read:
value->full = *reinterpret_cast<uint16_t *>(target);
break;
case SelectByte | Read:
value->halves.low = *target;
break;
case Microcycle::SelectWord:
*reinterpret_cast<uint16_t *>(target) = value->full;
break;
case Microcycle::SelectByte:
*target = value->halves.low;
break;
}
}
#ifndef NDEBUG
bool is_resizeable = false;
#endif