1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-10-01 13:58:20 +00:00

Imports SBCD and NBCD tests, and fixes corresponding operation.

This commit is contained in:
Thomas Harte 2019-06-28 19:39:08 -04:00
parent c5039a4719
commit 241d29ff7c
2 changed files with 150 additions and 13 deletions

View File

@ -105,7 +105,7 @@ class RAM68000: public CPU::MC68000::BusHandler {
case Microcycle::SelectByte:
ram_[word_address % ram_.size()] = uint16_t(
(cycle.value->halves.low << cycle.byte_shift()) |
(ram_[word_address] & cycle.untouched_byte_mask())
(ram_[word_address % ram_.size()] & cycle.untouched_byte_mask())
);
break;
}
@ -4103,6 +4103,68 @@ class CPU::MC68000::ProcessorStorageTests {
XCTAssertEqual(74, _machine->get_cycle_count());
}
// MARK: NBCD
- (void)performNBCDd1:(uint32_t)d1 ccr:(uint8_t)ccr {
_machine->set_program({
0x4801 // NBCD D1
});
auto state = _machine->get_processor_state();
state.status |= ccr;
state.data[1] = d1;
_machine->set_processor_state(state);
_machine->run_for_instructions(1);
XCTAssertEqual(6, _machine->get_cycle_count());
}
- (void)testNBCD_Dn {
[self performNBCDd1:0x7a ccr:0];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0x20);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry | Flag::Overflow);
}
- (void)testNBCD_Dn_extend {
[self performNBCDd1:0x1234567a ccr:Flag::Extend | Flag::Zero];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0x1234561f);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry | Flag::Overflow);
}
- (void)testNBCD_Dn_zero {
[self performNBCDd1:0x12345600 ccr:Flag::Zero];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0x12345600);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Zero);
}
- (void)testNBCD_Dn_negative {
[self performNBCDd1:0x123456ff ccr:Flag::Extend | Flag::Zero];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0x1234569a);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry | Flag::Negative);
}
- (void)testNBCD_Dn_XXXw {
_machine->set_program({
0x4838, 0x3000 // NBCD ($3000).w
});
*_machine->ram_at(0x3000) = 0x0100;
_machine->run_for_instructions(1);
const auto state = _machine->get_processor_state();
XCTAssertEqual(16, _machine->get_cycle_count());
XCTAssertEqual(*_machine->ram_at(0x3000), 0x9900);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry | Flag::Negative);
}
// MARK: NEG
- (void)performNEGb:(uint32_t)value {
@ -5038,6 +5100,78 @@ class CPU::MC68000::ProcessorStorageTests {
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::ConditionCodes);
}
// MARK: SBCD
- (void)performSBCDd1:(uint32_t)d1 d2:(uint32_t)d2 ccr:(uint8_t)ccr {
_machine->set_program({
0x8302 // SBCD D2, D1
});
auto state = _machine->get_processor_state();
state.status |= ccr;
state.data[1] = d1;
state.data[2] = d2;
_machine->set_processor_state(state);
_machine->run_for_instructions(1);
state = _machine->get_processor_state();
XCTAssertEqual(6, _machine->get_cycle_count());
XCTAssertEqual(state.data[2], d2);
}
- (void)testSBCD_Dn {
[self performSBCDd1:0x12345689 d2:0xf745ff78 ccr:Flag::Zero];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0x12345611);
XCTAssertEqual(state.status & Flag::ConditionCodes, 0);
}
- (void)testSBCD_Dn_zero {
[self performSBCDd1:0x123456ff d2:0xf745ffff ccr:Flag::Zero];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0x12345600);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Zero);
}
- (void)testSBCD_Dn_negative {
[self performSBCDd1:0x12345634 d2:0xf745ff45 ccr:Flag::Extend];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0x12345688);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry | Flag::Negative);
}
- (void)testSBCD_Dn_overflow {
[self performSBCDd1:0x123456a9 d2:0xf745ffff ccr:Flag::Extend];
const auto state = _machine->get_processor_state();
XCTAssertEqual(state.data[1], 0x12345643);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Extend | Flag::Carry | Flag::Overflow);
}
- (void)testSBCD_Dn_PreDec {
_machine->set_program({
0x830a // SBCD -(A2), -(A1)
});
*_machine->ram_at(0x3000) = 0xa200;
*_machine->ram_at(0x4000) = 0x1900;
auto state = _machine->get_processor_state();
state.address[1] = 0x3001;
state.address[2] = 0x4001;
state.status |= Flag::Extend;
_machine->set_processor_state(state);
_machine->run_for_instructions(1);
state = _machine->get_processor_state();
XCTAssertEqual(18, _machine->get_cycle_count());
XCTAssertEqual(*_machine->ram_at(0x3000), 0x8200);
XCTAssertEqual(*_machine->ram_at(0x4000), 0x1900);
XCTAssertEqual(state.status & Flag::ConditionCodes, Flag::Negative);
}
// MARK: SUB
- (void)performSUBbIMM:(uint16_t)value d2:(uint32_t)d2 {

View File

@ -376,7 +376,9 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
zero_result_ |= result & 0xff;
extend_flag_ = carry_flag_ = uint_fast32_t(result & ~0xff);
negative_flag_ = result & 0x80;
overflow_flag_ = add_overflow() & 0x80;
const int unadjusted_result = destination + source + (extend_flag_ ? 1 : 0);
overflow_flag_ = ~unadjusted_result & result & 0x80;
// Store the result.
active_program_->destination->halves.low.halves.low = uint8_t(result);
@ -1507,17 +1509,18 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
#define sbcd() \
/* Perform the BCD arithmetic by evaluating the two nibbles separately. */ \
int result = (destination & 0xf) - (source & 0xf) - (extend_flag_ ? 1 : 0); \
if(result > 0x09) result -= 0x06; \
result += (destination & 0xf0) - (source & 0xf0); \
if(result > 0x99) result -= 0x60; \
\
/* Set all flags essentially as if this were normal subtraction. */ \
zero_result_ |= result & 0xff; \
extend_flag_ = carry_flag_ = decltype(carry_flag_)(result & ~0xff); \
negative_flag_ = result & 0x80; \
overflow_flag_ = sub_overflow() & 0x80; \
\
/* Store the result. */ \
if((result & 0x1f) > 0x09) result -= 0x06; \
result += (destination & 0xf0) - (source & 0xf0); \
if((result & 0x1ff) > 0x99) result -= 0x60; \
\
/* Set all flags essentially as if this were normal subtraction. */ \
zero_result_ |= result & 0xff; \
extend_flag_ = carry_flag_ = decltype(carry_flag_)(result & ~0xff); \
negative_flag_ = result & 0x80; \
const int unadjusted_result = destination - source - (extend_flag_ ? 1 : 0); \
overflow_flag_ = unadjusted_result &~ result & 0x80; \
\
/* Store the result. */ \
active_program_->destination->halves.low.halves.low = uint8_t(result);
/*