mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 23:52:26 +00:00
Add missing: MOVE to/from USP, RESET.
This commit is contained in:
parent
4b97427937
commit
943c924382
@ -31,6 +31,7 @@ enum class FunctionCode {
|
||||
struct BusHandler {
|
||||
template <typename IntT> void write(uint32_t address, IntT value, FunctionCode function);
|
||||
template <typename IntT> IntT read(uint32_t address, FunctionCode function);
|
||||
void reset();
|
||||
};
|
||||
|
||||
/// Ties together the decoder, sequencer and performer to provide an executor for 680x0 instruction streams.
|
||||
@ -64,11 +65,15 @@ template <Model model, typename BusHandler> class Executor: public NullFlowContr
|
||||
void rts();
|
||||
void rte();
|
||||
void stop();
|
||||
void reset();
|
||||
|
||||
void link(Preinstruction instruction, uint32_t offset);
|
||||
void unlink(uint32_t &address);
|
||||
void pea(uint32_t address);
|
||||
|
||||
void move_to_usp(uint32_t address);
|
||||
void move_from_usp(uint32_t &address);
|
||||
|
||||
template <typename IntT> void movep(Preinstruction instruction, uint32_t source, uint32_t dest);
|
||||
template <typename IntT> void movem_toM(Preinstruction instruction, uint32_t source, uint32_t dest);
|
||||
template <typename IntT> void movem_toR(Preinstruction instruction, uint32_t source, uint32_t dest);
|
||||
@ -92,7 +97,7 @@ template <Model model, typename BusHandler> class Executor: public NullFlowContr
|
||||
BusHandler &bus_handler_;
|
||||
Predecoder<model> decoder_;
|
||||
|
||||
void reset();
|
||||
void reset_processor();
|
||||
struct EffectiveAddress {
|
||||
CPU::SlicedInt32 value;
|
||||
bool requires_fetch;
|
||||
|
@ -26,11 +26,11 @@ namespace M68k {
|
||||
|
||||
template <Model model, typename BusHandler>
|
||||
Executor<model, BusHandler>::Executor(BusHandler &handler) : bus_handler_(handler) {
|
||||
reset();
|
||||
reset_processor();
|
||||
}
|
||||
|
||||
template <Model model, typename BusHandler>
|
||||
void Executor<model, BusHandler>::reset() {
|
||||
void Executor<model, BusHandler>::reset_processor() {
|
||||
// Establish: supervisor state, all interrupts blocked.
|
||||
status_.set_status(0b0010'0011'1000'0000);
|
||||
did_update_status();
|
||||
@ -255,7 +255,9 @@ void Executor<model, BusHandler>::run_for_instructions(int count) {
|
||||
try {
|
||||
program_counter_.l = read<uint32_t>(vector_address);
|
||||
} catch (uint64_t) {
|
||||
reset();
|
||||
// TODO: I think this is incorrect, but need to verify consistency
|
||||
// across different 680x0s.
|
||||
reset_processor();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -412,6 +414,11 @@ void Executor<model, BusHandler>::did_update_status() {
|
||||
template <Model model, typename BusHandler>
|
||||
void Executor<model, BusHandler>::stop() {}
|
||||
|
||||
template <Model model, typename BusHandler>
|
||||
void Executor<model, BusHandler>::reset() {
|
||||
bus_handler_.reset();
|
||||
}
|
||||
|
||||
template <Model model, typename BusHandler>
|
||||
void Executor<model, BusHandler>::jmp(uint32_t address) {
|
||||
program_counter_.l = address;
|
||||
@ -504,6 +511,16 @@ void Executor<model, BusHandler>::tas(Preinstruction instruction, uint32_t addre
|
||||
status_.negative_flag_ = value & 0x80;
|
||||
}
|
||||
|
||||
template <Model model, typename BusHandler>
|
||||
void Executor<model, BusHandler>::move_to_usp(uint32_t address) {
|
||||
stack_pointers_[0].l = address;
|
||||
}
|
||||
|
||||
template <Model model, typename BusHandler>
|
||||
void Executor<model, BusHandler>::move_from_usp(uint32_t &address) {
|
||||
address = stack_pointers_[0].l;
|
||||
}
|
||||
|
||||
template <Model model, typename BusHandler>
|
||||
template <typename IntT>
|
||||
void Executor<model, BusHandler>::movep(Preinstruction instruction, uint32_t source, uint32_t dest) {
|
||||
|
@ -427,6 +427,14 @@ template <
|
||||
status.set_ccr(src.w);
|
||||
break;
|
||||
|
||||
case Operation::MOVEtoUSP:
|
||||
flow_controller.move_to_usp(src.l);
|
||||
break;
|
||||
|
||||
case Operation::MOVEfromUSP:
|
||||
flow_controller.move_from_usp(src.l);
|
||||
break;
|
||||
|
||||
case Operation::EXTbtow:
|
||||
src.w = uint16_t(int8_t(src.b));
|
||||
status.overflow_flag_ = status.carry_flag_ = 0;
|
||||
@ -1162,6 +1170,10 @@ template <
|
||||
flow_controller.stop();
|
||||
break;
|
||||
|
||||
case Operation::RESET:
|
||||
flow_controller.reset();
|
||||
break;
|
||||
|
||||
/*
|
||||
Development period debugging.
|
||||
*/
|
||||
|
@ -84,6 +84,9 @@ struct NullFlowController {
|
||||
/// Put the processor into the stopped state, waiting for interrupts.
|
||||
void stop();
|
||||
|
||||
/// Assert the reset output.
|
||||
void reset();
|
||||
|
||||
/// Perform LINK using the address register identified by @c instruction and the specified @c offset.
|
||||
void link(Preinstruction instruction, uint32_t offset);
|
||||
|
||||
@ -93,6 +96,14 @@ struct NullFlowController {
|
||||
/// Push @c address to the stack.
|
||||
void pea(uint32_t address);
|
||||
|
||||
/// Replace the current user stack pointer with @c address.
|
||||
/// The processor is guranteed to be in supervisor mode.
|
||||
void move_to_usp(uint32_t address);
|
||||
|
||||
/// Put the value of the user stack pointer into @c address.
|
||||
/// The processor is guranteed to be in supervisor mode.
|
||||
void move_from_usp(uint32_t &address);
|
||||
|
||||
/// Perform an atomic TAS cycle; if @c instruction indicates that this is a TAS Dn then
|
||||
/// perform the TAS directly upon that register; otherwise perform it on the memory at
|
||||
/// @c address. If this is a TAS Dn then @c address will contain the initial value of
|
||||
|
@ -267,6 +267,8 @@
|
||||
ram[(address+3) & 0xffffff] = uint8_t(value);
|
||||
}
|
||||
}
|
||||
|
||||
void reset() {}
|
||||
};
|
||||
auto uniqueTest68000 = std::make_unique<Test68000>();
|
||||
auto test68000 = uniqueTest68000.get();
|
||||
|
Loading…
Reference in New Issue
Block a user