1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-04-16 16:38:41 +00:00

Starts populating the 68000 state registers.

This commit is contained in:
Thomas Harte 2020-05-16 00:06:04 -04:00
parent 375835a950
commit f7a16762b4
4 changed files with 74 additions and 42 deletions

View File

@ -6,7 +6,7 @@
// Copyright © 2019 Thomas Harte. All rights reserved.
//
#define get_ccr() \
#define ccr() \
( \
(carry_flag_ ? 0x0001 : 0x0000) | \
(overflow_flag_ ? 0x0002 : 0x0000) | \
@ -15,23 +15,23 @@
(extend_flag_ ? 0x0010 : 0x0000) \
)
#define get_status() \
#define status() \
uint16_t( \
get_ccr() | \
ccr() | \
(interrupt_level_ << 8) | \
(trace_flag_ ? 0x8000 : 0x0000) | \
(is_supervisor_ << 13) \
)
#define set_ccr(x) \
#define apply_ccr(x) \
carry_flag_ = (x) & 0x0001; \
overflow_flag_ = (x) & 0x0002; \
zero_result_ = ((x) & 0x0004) ^ 0x0004; \
negative_flag_ = (x) & 0x0008; \
extend_flag_ = (x) & 0x0010;
#define set_status(x) \
set_ccr(x) \
#define apply_status(x) \
apply_ccr(x) \
interrupt_level_ = ((x) >> 8) & 7; \
trace_flag_ = (x) & 0x8000; \
set_is_supervisor(!!(((x) >> 13) & 1));
@ -101,7 +101,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
const auto offending_address = *active_step_->microcycle.address;
active_program_ = nullptr;
active_micro_op_ = long_exception_micro_ops_;
populate_bus_error_steps(2, get_status(), get_bus_code(), offending_address);
populate_bus_error_steps(2, status(), get_bus_code(), offending_address);
program_counter_.full -= 4;
active_step_ = &all_bus_steps_[active_micro_op_->bus_program];
}
@ -116,7 +116,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
const auto offending_address = *active_step_->microcycle.address;
active_program_ = nullptr;
active_micro_op_ = long_exception_micro_ops_;
populate_bus_error_steps(3, get_status(), get_bus_code(), offending_address);
populate_bus_error_steps(3, status(), get_bus_code(), offending_address);
program_counter_.full -= 4;
active_step_ = &all_bus_steps_[active_micro_op_->bus_program];
@ -277,7 +277,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
// The user has set the trace bit in the status register.
active_program_ = nullptr;
active_micro_op_ = short_exception_micro_ops_;
populate_trap_steps(9, get_status());
populate_trap_steps(9, status());
program_counter_.full -= 4;
} else {
#ifdef LOG_TRACE
@ -331,7 +331,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
// A privilege violation has been detected.
active_program_ = nullptr;
active_micro_op_ = short_exception_micro_ops_;
populate_trap_steps(8, get_status());
populate_trap_steps(8, status());
} else {
// Standard instruction dispatch.
active_program_ = &instructions[decoded_instruction_.full];
@ -353,13 +353,13 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
// or one on the A or F lines.
switch(decoded_instruction_.full >> 12) {
default:
populate_trap_steps(4, get_status());
populate_trap_steps(4, status());
break;
case 0xa:
populate_trap_steps(10, get_status());
populate_trap_steps(10, status());
break;
case 0xf:
populate_trap_steps(11, get_status());
populate_trap_steps(11, status());
break;
}
}
@ -887,15 +887,15 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
*/
case Operation::MOVEtoSR:
set_status(source()->full);
apply_status(source()->full);
break;
case Operation::MOVEfromSR:
destination()->halves.low.full = get_status();
destination()->halves.low.full = status();
break;
case Operation::MOVEtoCCR:
set_ccr(source()->full);
apply_ccr(source()->full);
break;
case Operation::EXTbtow:
@ -919,25 +919,25 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
#define eor_op(a, b) a ^= b
#define apply(op, func) {\
auto status = get_status(); \
auto status = status(); \
op(status, prefetch_queue_.halves.high.full); \
func(status); \
program_counter_.full -= 2; \
}
#define apply_sr(op) apply(op, set_status)
#define apply_ccr(op) apply(op, set_ccr)
#define apply_op_sr(op) apply(op, apply_status)
#define apply_op_ccr(op) apply(op, apply_ccr)
case Operation::ANDItoSR: apply_sr(and_op); break;
case Operation::EORItoSR: apply_sr(eor_op); break;
case Operation::ORItoSR: apply_sr(or_op); break;
case Operation::ANDItoSR: apply_op_sr(and_op); break;
case Operation::EORItoSR: apply_op_sr(eor_op); break;
case Operation::ORItoSR: apply_op_sr(or_op); break;
case Operation::ANDItoCCR: apply_ccr(and_op); break;
case Operation::EORItoCCR: apply_ccr(eor_op); break;
case Operation::ORItoCCR: apply_ccr(or_op); break;
case Operation::ANDItoCCR: apply_op_ccr(and_op); break;
case Operation::EORItoCCR: apply_op_ccr(eor_op); break;
case Operation::ORItoCCR: apply_op_ccr(or_op); break;
#undef apply_ccr
#undef apply_sr
#undef apply_op_ccr
#undef apply_op_sr
#undef apply
#undef eor_op
#undef or_op
@ -988,7 +988,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
active_micro_op_ = short_exception_micro_ops_; \
bus_program = &all_bus_steps_[active_micro_op_->bus_program]; \
\
populate_trap_steps(5, get_status()); \
populate_trap_steps(5, status()); \
bus_program->microcycle.length = HalfCycles(20); \
\
program_counter_.full -= 2;
@ -1297,7 +1297,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
case Operation::TRAP: {
// Select the trap steps as next; the initial microcycle should be 4 cycles long.
bus_program = trap_steps_;
populate_trap_steps((decoded_instruction_.full & 15) + 32, get_status());
populate_trap_steps((decoded_instruction_.full & 15) + 32, status());
set_next_microcycle_length(HalfCycles(12));
// The program counter to push is actually one slot ago.
@ -1308,7 +1308,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
if(overflow_flag_) {
// Select the trap steps as next; the initial microcycle should be skipped.
bus_program = trap_steps_;
populate_trap_steps(7, get_status());
populate_trap_steps(7, status());
set_next_microcycle_length(HalfCycles(4));
// Push the address after the TRAPV.
@ -1334,7 +1334,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
// exception is necessary.
if(is_under || is_over) {
bus_program = trap_steps_;
populate_trap_steps(6, get_status());
populate_trap_steps(6, status());
if(is_over) {
set_next_microcycle_length(HalfCycles(20));
} else {
@ -1858,11 +1858,11 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
case Operation::RTE_RTR:
// If this is RTR, patch out the supervisor half of the status register.
if(decoded_instruction_.full == 0x4e77) {
const auto current_status = get_status();
const auto current_status = status();
source_bus_data_[0].halves.low.halves.high =
uint8_t(current_status >> 8);
}
set_status(source_bus_data_[0].full);
apply_status(source_bus_data_[0].full);
break;
/*
@ -1888,7 +1888,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
break;
case Operation::STOP:
set_status(prefetch_queue_.halves.low.full);
apply_status(prefetch_queue_.halves.low.full);
execution_state_ = ExecutionState::Stopped;
break;
@ -1968,7 +1968,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
case int_type(MicroOp::Action::PrepareINT):
// The INT sequence uses the same storage as the TRAP steps, so this'll get
// the necessary stack work set up.
populate_trap_steps(0, get_status());
populate_trap_steps(0, status());
// Mutate neessary internal state — effective_address_[0] is exposed
// on the data bus as the accepted interrupt number during the interrupt
@ -2202,7 +2202,7 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> ProcessorSt
state.supervisor_stack_pointer = stack_pointers_[1].full;
state.program_counter = program_counter_.full;
state.status = get_status();
state.status = status();
return state;
}
@ -2211,17 +2211,25 @@ template <class T, bool dtack_is_implicit, bool signal_will_perform> void Proces
memcpy(data_, state.data, sizeof(state.data));
memcpy(address_, state.address, sizeof(state.address));
set_status(state.status);
apply_status(state.status);
stack_pointers_[0].full = state.user_stack_pointer;
stack_pointers_[1].full = state.supervisor_stack_pointer;
address_[7] = stack_pointers_[is_supervisor_];
}
#undef get_status
#undef set_status
#undef set_ccr
#undef get_ccr
uint16_t ProcessorStorage::get_status() const {
return status();
}
void ProcessorStorage::set_status(uint16_t status) {
apply_status(status);
}
#undef status
#undef apply_status
#undef apply_ccr
#undef ccr
#undef u_extend16
#undef u_extend8
#undef s_extend16

View File

@ -43,7 +43,7 @@ class ProcessorStorage {
Microcycle dtack_cycle_;
Microcycle stop_cycle_;
// Various status bits.
// Various status parts.
int is_supervisor_;
int interrupt_level_;
uint_fast32_t zero_result_; // The zero flag is set if this value is zero.
@ -539,9 +539,13 @@ class ProcessorStorage {
address_[7].full -= 14;
}
inline uint16_t get_status() const;
inline void set_status(uint16_t);
private:
friend class ProcessorStorageConstructor;
friend class ProcessorStorageTests;
friend class State;
};
#endif /* MC68000Storage_h */

View File

@ -11,6 +11,16 @@
using namespace CPU::MC68000;
State::State(const ProcessorBase &src): State() {
for(int c = 0; c < 7; ++c) {
registers.address[c] = src.address_[c].full;
registers.data[c] = src.data_[c].full;
}
registers.data[7] = src.data_[7].full;
registers.user_stack_pointer = src.is_supervisor_ ? src.stack_pointers_[0].full : src.address_[7].full;
registers.supervisor_stack_pointer = src.is_supervisor_ ? src.address_[7].full : src.stack_pointers_[1].full;
registers.status = src.get_status();
registers.program_counter = src.program_counter_.full;
registers.prefetch = src.prefetch_queue_.full;
}
void State::apply(ProcessorBase &target) {
@ -29,6 +39,11 @@ State::Registers::Registers() {
if(needs_declare()) {
DeclareField(data);
DeclareField(address);
DeclareField(user_stack_pointer);
DeclareField(supervisor_stack_pointer);
DeclareField(status);
DeclareField(program_counter);
DeclareField(prefetch);
}
}

View File

@ -29,6 +29,11 @@ struct State: public Reflection::StructImpl<State> {
*/
struct Registers: public Reflection::StructImpl<Registers> {
uint32_t data[8], address[7];
uint32_t user_stack_pointer;
uint32_t supervisor_stack_pointer;
uint16_t status;
uint32_t program_counter;
uint32_t prefetch;
Registers();
} registers;