1
0
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:
Thomas Harte
2020-10-12 22:33:43 -04:00
parent 6a47571d17
commit a15d4a156b
3 changed files with 40 additions and 17 deletions

View File

@@ -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: {

View File

@@ -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

View File

@@ -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_;