mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Remove add_pc
and decline_branch
in favour of operation-specific signals.
This commit is contained in:
parent
330ec1b848
commit
0af8660181
@ -49,12 +49,12 @@ template <Model model, typename BusHandler> class Executor {
|
|||||||
// Flow control.
|
// Flow control.
|
||||||
void consume_cycles(int) {}
|
void consume_cycles(int) {}
|
||||||
void set_pc(uint32_t);
|
void set_pc(uint32_t);
|
||||||
void add_pc(uint32_t);
|
|
||||||
void decline_branch() {}
|
|
||||||
|
|
||||||
void raise_exception(int, bool use_current_instruction_pc = true);
|
void raise_exception(int, bool use_current_instruction_pc = true);
|
||||||
void did_update_status();
|
void did_update_status();
|
||||||
|
|
||||||
|
template <typename IntT> void complete_bcc(bool matched_condition, IntT offset);
|
||||||
|
void complete_dbcc(bool matched_condition, bool overflowed, int16_t offset);
|
||||||
void stop();
|
void stop();
|
||||||
void bsr(uint32_t offset);
|
void bsr(uint32_t offset);
|
||||||
void jsr(uint32_t offset);
|
void jsr(uint32_t offset);
|
||||||
|
@ -330,7 +330,6 @@ void Executor<model, BusHandler>::set_state(const Registers &state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Flow Control.
|
// MARK: - Flow Control.
|
||||||
// TODO: flow control, all below here.
|
|
||||||
|
|
||||||
template <Model model, typename BusHandler>
|
template <Model model, typename BusHandler>
|
||||||
void Executor<model, BusHandler>::raise_exception(int index, bool use_current_instruction_pc) {
|
void Executor<model, BusHandler>::raise_exception(int index, bool use_current_instruction_pc) {
|
||||||
@ -367,8 +366,17 @@ void Executor<model, BusHandler>::set_pc(uint32_t address) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <Model model, typename BusHandler>
|
template <Model model, typename BusHandler>
|
||||||
void Executor<model, BusHandler>::add_pc(uint32_t offset) {
|
template <typename IntT> void Executor<model, BusHandler>::complete_bcc(bool branch, IntT offset) {
|
||||||
program_counter_.l = instruction_address_ + offset;
|
if(branch) {
|
||||||
|
program_counter_.l = instruction_address_ + offset + 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <Model model, typename BusHandler>
|
||||||
|
void Executor<model, BusHandler>::complete_dbcc(bool matched_condition, bool overflowed, int16_t offset) {
|
||||||
|
if(!matched_condition && !overflowed) {
|
||||||
|
program_counter_.l = instruction_address_ + offset + 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template <Model model, typename BusHandler>
|
template <Model model, typename BusHandler>
|
||||||
|
@ -254,27 +254,21 @@ template <
|
|||||||
// Special case: the condition code is 1, which is ordinarily false. In that case this
|
// Special case: the condition code is 1, which is ordinarily false. In that case this
|
||||||
// is the trailing step of a BSR.
|
// is the trailing step of a BSR.
|
||||||
case Operation::Bccb:
|
case Operation::Bccb:
|
||||||
if(status.evaluate_condition(instruction.condition())) {
|
flow_controller.template complete_bcc<int8_t>(
|
||||||
flow_controller.add_pc(int8_t(src.b) + 2);
|
status.evaluate_condition(instruction.condition()),
|
||||||
} else {
|
src.b);
|
||||||
flow_controller.decline_branch();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Operation::Bccw:
|
case Operation::Bccw:
|
||||||
if(status.evaluate_condition(instruction.condition())) {
|
flow_controller.template complete_bcc<int16_t>(
|
||||||
flow_controller.add_pc(int16_t(src.w) + 2);
|
status.evaluate_condition(instruction.condition()),
|
||||||
} else {
|
src.w);
|
||||||
flow_controller.decline_branch();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Operation::Bccl:
|
case Operation::Bccl:
|
||||||
if(status.evaluate_condition(instruction.condition())) {
|
flow_controller.template complete_bcc<int32_t>(
|
||||||
flow_controller.add_pc(src.l + 2);
|
status.evaluate_condition(instruction.condition()),
|
||||||
} else {
|
src.l);
|
||||||
flow_controller.decline_branch();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Operation::BSRb:
|
case Operation::BSRb:
|
||||||
@ -287,23 +281,22 @@ template <
|
|||||||
flow_controller.bsr(src.l + 2);
|
flow_controller.bsr(src.l + 2);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Operation::DBcc:
|
case Operation::DBcc: {
|
||||||
// Decide what sort of DBcc this is.
|
const bool matched_condition = status.evaluate_condition(instruction.condition());
|
||||||
if(!status.evaluate_condition(instruction.condition())) {
|
bool overflowed = false;
|
||||||
-- src.w;
|
|
||||||
|
|
||||||
if(src.w == 0xffff) {
|
// Classify the dbcc.
|
||||||
// This DBcc will be ignored as the counter has underflowed.
|
if(!matched_condition) {
|
||||||
flow_controller.decline_branch();
|
-- src.w;
|
||||||
} else {
|
overflowed = src.w == 0xffff;
|
||||||
// Take the branch.
|
|
||||||
flow_controller.add_pc(int16_t(dest.l) + 2);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// This DBcc will be ignored as the condition is true.
|
|
||||||
flow_controller.decline_branch();
|
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
|
// Take the branch.
|
||||||
|
flow_controller.complete_dbcc(
|
||||||
|
matched_condition,
|
||||||
|
overflowed,
|
||||||
|
int16_t(dest.w));
|
||||||
|
} break;
|
||||||
|
|
||||||
case Operation::Scc:
|
case Operation::Scc:
|
||||||
src.b = status.evaluate_condition(instruction.condition()) ? 0xff : 0x00;
|
src.b = status.evaluate_condition(instruction.condition()) ? 0xff : 0x00;
|
||||||
@ -427,9 +420,9 @@ template <
|
|||||||
dest.l = src.l;
|
dest.l = src.l;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
// case Operation::PEA:
|
case Operation::PEA:
|
||||||
// destination_bus_data_ = effective_address_[0];
|
flow_controller.pea(src.l);
|
||||||
// break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Status word moves and manipulations.
|
Status word moves and manipulations.
|
||||||
@ -1205,10 +1198,6 @@ template <
|
|||||||
flow_controller.template movem_toM<uint16_t>(instruction, src.l, dest.l);
|
flow_controller.template movem_toM<uint16_t>(instruction, src.l, dest.l);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Operation::PEA:
|
|
||||||
flow_controller.pea(src.l);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
RTE and RTR share an implementation.
|
RTE and RTR share an implementation.
|
||||||
*/
|
*/
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
|
|
||||||
- (void)setUp {
|
- (void)setUp {
|
||||||
// To limit tests run to a subset of files and/or of tests, uncomment and fill in below.
|
// To limit tests run to a subset of files and/or of tests, uncomment and fill in below.
|
||||||
// _fileSet = [NSSet setWithArray:@[@"chk.json"]];
|
_fileSet = [NSSet setWithArray:@[@"dbcc.json"]];
|
||||||
// _testSet = [NSSet setWithArray:@[@"CHK 4190"]];
|
// _testSet = [NSSet setWithArray:@[@"CHK 4190"]];
|
||||||
// _fileSet = [NSSet setWithArray:@[@"jmp_jsr.json"]];
|
// _fileSet = [NSSet setWithArray:@[@"jmp_jsr.json"]];
|
||||||
// _testSet = [NSSet setWithArray:@[@"CHK 41a8"]];
|
// _testSet = [NSSet setWithArray:@[@"CHK 41a8"]];
|
||||||
|
@ -1766,7 +1766,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
|
|||||||
} break;
|
} break;
|
||||||
case Operation::ROLb: rol(destination()->halves.low.halves.low, 8); break;
|
case Operation::ROLb: rol(destination()->halves.low.halves.low, 8); break;
|
||||||
case Operation::ROLw: rol(destination()->halves.low.full, 16); break;
|
case Operation::ROLw: rol(destination()->halves.low.full, 16); break;
|
||||||
case Operation::ROLl: rol(destination()->full, 32); break;
|
case Operation::ROLl: rol(destination()->full, 32); break;
|
||||||
|
|
||||||
|
|
||||||
#define ror(destination, size) { \
|
#define ror(destination, size) { \
|
||||||
@ -1795,7 +1795,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
|
|||||||
} break;
|
} break;
|
||||||
case Operation::RORb: ror(destination()->halves.low.halves.low, 8); break;
|
case Operation::RORb: ror(destination()->halves.low.halves.low, 8); break;
|
||||||
case Operation::RORw: ror(destination()->halves.low.full, 16); break;
|
case Operation::RORw: ror(destination()->halves.low.full, 16); break;
|
||||||
case Operation::RORl: ror(destination()->full, 32); break;
|
case Operation::RORl: ror(destination()->full, 32); break;
|
||||||
|
|
||||||
#define roxl(destination, size) { \
|
#define roxl(destination, size) { \
|
||||||
decode_shift_count(); \
|
decode_shift_count(); \
|
||||||
|
Loading…
x
Reference in New Issue
Block a user