mirror of
https://github.com/TomHarte/CLK.git
synced 2025-08-07 23:25:00 +00:00
Starts trying to ensure appropriate address wrapping.
This commit is contained in:
@@ -89,8 +89,8 @@ template <typename BusHandler> void Processor<BusHandler>::run_for(const Cycles
|
|||||||
// Data fetches and stores.
|
// Data fetches and stores.
|
||||||
//
|
//
|
||||||
|
|
||||||
#define increment_data_address() data_address_ = (data_address_ & 0xff0000) + ((data_address_ + 1) & 0xffff)
|
#define increment_data_address() data_address_ = (data_address_ & ~data_address_increment_mask_) + ((data_address_ + 1) & data_address_increment_mask_)
|
||||||
#define decrement_data_address() data_address_ = (data_address_ & 0xff0000) + ((data_address_ - 1) & 0xffff)
|
#define decrement_data_address() data_address_ = (data_address_ & ~data_address_increment_mask_) + ((data_address_ - 1) & data_address_increment_mask_)
|
||||||
|
|
||||||
|
|
||||||
case CycleFetchData:
|
case CycleFetchData:
|
||||||
@@ -229,18 +229,22 @@ template <typename BusHandler> void Processor<BusHandler>::run_for(const Cycles
|
|||||||
|
|
||||||
case OperationConstructAbsolute:
|
case OperationConstructAbsolute:
|
||||||
data_address_ = instruction_buffer_.value + data_bank_;
|
data_address_ = instruction_buffer_.value + data_bank_;
|
||||||
|
data_address_increment_mask_ = 0xff'ff'ff;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case OperationConstructAbsoluteLong:
|
case OperationConstructAbsoluteLong:
|
||||||
data_address_ = instruction_buffer_.value;
|
data_address_ = instruction_buffer_.value;
|
||||||
|
data_address_increment_mask_ = 0xff'ff'ff;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case OperationConstructAbsoluteIndexedIndirect:
|
case OperationConstructAbsoluteIndexedIndirect:
|
||||||
data_address_ = (instruction_buffer_.value + x()) & 0xffff;
|
data_address_ = (instruction_buffer_.value + x()) & 0xffff;
|
||||||
|
data_address_increment_mask_ = 0x00'ff'ff;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case OperationConstructAbsoluteLongX:
|
case OperationConstructAbsoluteLongX:
|
||||||
data_address_ = (instruction_buffer_.value + x()) & 0xffff + instruction_buffer_.value & 0xff0000;
|
data_address_ = instruction_buffer_.value + x();
|
||||||
|
data_address_increment_mask_ = 0xff'ff'ff;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case OperationConstructAbsoluteXRead:
|
case OperationConstructAbsoluteXRead:
|
||||||
@@ -252,6 +256,7 @@ template <typename BusHandler> void Processor<BusHandler>::run_for(const Cycles
|
|||||||
if(operation == OperationConstructAbsoluteXRead && data_address_ == incorrect_data_address_) {
|
if(operation == OperationConstructAbsoluteXRead && data_address_ == incorrect_data_address_) {
|
||||||
++next_op_;
|
++next_op_;
|
||||||
}
|
}
|
||||||
|
data_address_increment_mask_ = 0xff'ff'ff;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case OperationConstructAbsoluteYRead:
|
case OperationConstructAbsoluteYRead:
|
||||||
@@ -263,10 +268,13 @@ template <typename BusHandler> void Processor<BusHandler>::run_for(const Cycles
|
|||||||
if(operation == OperationConstructAbsoluteYRead && data_address_ == incorrect_data_address_) {
|
if(operation == OperationConstructAbsoluteYRead && data_address_ == incorrect_data_address_) {
|
||||||
++next_op_;
|
++next_op_;
|
||||||
}
|
}
|
||||||
|
data_address_increment_mask_ = 0xff'ff'ff;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case OperationConstructDirect:
|
case OperationConstructDirect:
|
||||||
|
// TODO: is this address correct in emulation mode when the low byte is zero?
|
||||||
data_address_ = (direct_ + instruction_buffer_.value) & 0xffff;
|
data_address_ = (direct_ + instruction_buffer_.value) & 0xffff;
|
||||||
|
data_address_increment_mask_ = 0x00'ff'ff;
|
||||||
if(!(direct_&0xff)) {
|
if(!(direct_&0xff)) {
|
||||||
++next_op_;
|
++next_op_;
|
||||||
}
|
}
|
||||||
@@ -277,62 +285,74 @@ template <typename BusHandler> void Processor<BusHandler>::run_for(const Cycles
|
|||||||
((direct_ + x() + instruction_buffer_.value) & e_masks_[1]) +
|
((direct_ + x() + instruction_buffer_.value) & e_masks_[1]) +
|
||||||
(direct_ & e_masks_[0])
|
(direct_ & e_masks_[0])
|
||||||
) & 0xffff;
|
) & 0xffff;
|
||||||
|
data_address_increment_mask_ = 0x00'ff'ff;
|
||||||
|
|
||||||
if(!(direct_&0xff)) {
|
if(!(direct_&0xff)) {
|
||||||
++next_op_;
|
++next_op_;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case OperationConstructDirectIndirect:
|
case OperationConstructDirectIndirect: // TODO: seems very incorrect. Check this and the programs that use it;
|
||||||
data_address_ = data_bank_ + (direct_ + instruction_buffer_.value) & 0xffff;
|
// 12 looks wrong, the others look correct?
|
||||||
|
data_address_ = (direct_ + instruction_buffer_.value) & 0xffff;
|
||||||
|
data_address_increment_mask_ = 0x00'ff'ff;
|
||||||
|
|
||||||
if(!(direct_&0xff)) {
|
if(!(direct_&0xff)) {
|
||||||
++next_op_;
|
++next_op_;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case OperationConstructDirectIndirectIndexedLong:
|
case OperationConstructDirectIndirectIndexedLong:
|
||||||
// TODO: assumed here is that the low 16-bit calculation can't carry into
|
data_address_ = y() + instruction_buffer_.value;
|
||||||
// the high byte. Test this!
|
data_address_increment_mask_ = 0xff'ff'ff;
|
||||||
data_address_ = (y() + instruction_buffer_.value) & 0xffff + instruction_buffer_.value & 0xff0000;
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case OperationConstructDirectIndirectLong:
|
case OperationConstructDirectIndirectLong:
|
||||||
data_address_ = instruction_buffer_.value;
|
data_address_ = instruction_buffer_.value;
|
||||||
|
data_address_increment_mask_ = 0xff'ff'ff;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case OperationConstructDirectX: {
|
// TODO: confirm incorrect_data_address_ below.
|
||||||
|
|
||||||
|
case OperationConstructDirectX:
|
||||||
data_address_ = (
|
data_address_ = (
|
||||||
(direct_ & e_masks_[0]) +
|
(direct_ & e_masks_[0]) +
|
||||||
((instruction_buffer_.value + direct_ + x()) & e_masks_[1])
|
((instruction_buffer_.value + direct_ + x()) & e_masks_[1])
|
||||||
) & 0xffff;
|
) & 0xffff;
|
||||||
|
data_address_increment_mask_ = 0x00'ff'ff;
|
||||||
|
|
||||||
incorrect_data_address_ = (direct_ & 0xff00) + (data_address_ & 0x00ff);
|
incorrect_data_address_ = (direct_ & 0xff00) + (data_address_ & 0x00ff);
|
||||||
if(!(direct_&0xff)) {
|
if(!(direct_&0xff)) {
|
||||||
++next_op_;
|
++next_op_;
|
||||||
}
|
}
|
||||||
} continue;
|
continue;
|
||||||
|
|
||||||
case OperationConstructDirectY:
|
case OperationConstructDirectY:
|
||||||
data_address_ = (
|
data_address_ = (
|
||||||
(direct_ & e_masks_[0]) +
|
(direct_ & e_masks_[0]) +
|
||||||
((instruction_buffer_.value + direct_ + y()) & e_masks_[1])
|
((instruction_buffer_.value + direct_ + y()) & e_masks_[1])
|
||||||
) & 0xffff;
|
) & 0xffff;
|
||||||
// TODO: given the 16-bit internal arithmetic, confirm this is the correct spurious address.
|
data_address_increment_mask_ = 0x00'ff'ff;
|
||||||
|
|
||||||
incorrect_data_address_ = (direct_ & 0xff00) + (data_address_ & 0x00ff);
|
incorrect_data_address_ = (direct_ & 0xff00) + (data_address_ & 0x00ff);
|
||||||
if(!(direct_&0xff)) {
|
if(!(direct_&0xff)) {
|
||||||
++next_op_;
|
++next_op_;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case OperationConstructPER:
|
|
||||||
data_buffer_.value = instruction_buffer_.value + pc_;
|
|
||||||
data_buffer_.size = 2;
|
|
||||||
continue;
|
|
||||||
|
|
||||||
case OperationConstructStackRelative:
|
case OperationConstructStackRelative:
|
||||||
data_address_ = (s_.full + instruction_buffer_.value) & 0xffff;
|
data_address_ = (s_.full + instruction_buffer_.value) & 0xffff;
|
||||||
|
data_address_increment_mask_ = 0x00'ff'ff;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case OperationConstructStackRelativeIndexedIndirect:
|
case OperationConstructStackRelativeIndexedIndirect:
|
||||||
data_address_ = data_bank_ + (instruction_buffer_.value + y()) & 0xffff;
|
data_address_ = (instruction_buffer_.value + y()) & 0xffff;
|
||||||
|
data_address_increment_mask_ = 0xff'ff'ff;
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case OperationConstructPER:
|
||||||
|
data_buffer_.value = instruction_buffer_.value + pc_;
|
||||||
|
data_buffer_.size = 2;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case OperationPrepareException: {
|
case OperationPrepareException: {
|
||||||
|
@@ -238,6 +238,7 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
|
|||||||
target(CycleFetchPC); // New AAH.
|
target(CycleFetchPC); // New AAH.
|
||||||
|
|
||||||
target(OperationConstructAbsolute); // Calculate data address.
|
target(OperationConstructAbsolute); // Calculate data address.
|
||||||
|
// TODO: needs to apply a 16-bit limit here:
|
||||||
target(CycleFetchIncrementData); // New PCL
|
target(CycleFetchIncrementData); // New PCL
|
||||||
target(CycleFetchIncrementData); // New PCH
|
target(CycleFetchIncrementData); // New PCH
|
||||||
target(CycleFetchData); // New PBR
|
target(CycleFetchData); // New PBR
|
||||||
@@ -251,6 +252,7 @@ struct CPU::WDC65816::ProcessorStorageConstructor {
|
|||||||
target(CycleFetchPC); // New AAH.
|
target(CycleFetchPC); // New AAH.
|
||||||
|
|
||||||
target(OperationConstructAbsolute); // Calculate data address.
|
target(OperationConstructAbsolute); // Calculate data address.
|
||||||
|
// TODO: needs to apply a 16-bit limit here:
|
||||||
target(CycleFetchIncrementData); // New PCL
|
target(CycleFetchIncrementData); // New PCL
|
||||||
target(CycleFetchData); // New PCH
|
target(CycleFetchData); // New PCH
|
||||||
|
|
||||||
|
@@ -328,6 +328,7 @@ struct ProcessorStorage {
|
|||||||
};
|
};
|
||||||
Buffer instruction_buffer_, data_buffer_;
|
Buffer instruction_buffer_, data_buffer_;
|
||||||
uint32_t data_address_;
|
uint32_t data_address_;
|
||||||
|
uint32_t data_address_increment_mask_ = 0xffff;
|
||||||
uint32_t incorrect_data_address_;
|
uint32_t incorrect_data_address_;
|
||||||
|
|
||||||
std::vector<MicroOp> micro_ops_;
|
std::vector<MicroOp> micro_ops_;
|
||||||
|
Reference in New Issue
Block a user