mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-18 16:30:29 +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 {
|
struct BusHandler {
|
||||||
template <typename IntT> void write(uint32_t address, IntT value, FunctionCode function);
|
template <typename IntT> void write(uint32_t address, IntT value, FunctionCode function);
|
||||||
template <typename IntT> IntT read(uint32_t address, 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.
|
/// 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 rts();
|
||||||
void rte();
|
void rte();
|
||||||
void stop();
|
void stop();
|
||||||
|
void reset();
|
||||||
|
|
||||||
void link(Preinstruction instruction, uint32_t offset);
|
void link(Preinstruction instruction, uint32_t offset);
|
||||||
void unlink(uint32_t &address);
|
void unlink(uint32_t &address);
|
||||||
void pea(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 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_toM(Preinstruction instruction, uint32_t source, uint32_t dest);
|
||||||
template <typename IntT> void movem_toR(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_;
|
BusHandler &bus_handler_;
|
||||||
Predecoder<model> decoder_;
|
Predecoder<model> decoder_;
|
||||||
|
|
||||||
void reset();
|
void reset_processor();
|
||||||
struct EffectiveAddress {
|
struct EffectiveAddress {
|
||||||
CPU::SlicedInt32 value;
|
CPU::SlicedInt32 value;
|
||||||
bool requires_fetch;
|
bool requires_fetch;
|
||||||
|
@ -26,11 +26,11 @@ namespace M68k {
|
|||||||
|
|
||||||
template <Model model, typename BusHandler>
|
template <Model model, typename BusHandler>
|
||||||
Executor<model, BusHandler>::Executor(BusHandler &handler) : bus_handler_(handler) {
|
Executor<model, BusHandler>::Executor(BusHandler &handler) : bus_handler_(handler) {
|
||||||
reset();
|
reset_processor();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <Model model, typename BusHandler>
|
template <Model model, typename BusHandler>
|
||||||
void Executor<model, BusHandler>::reset() {
|
void Executor<model, BusHandler>::reset_processor() {
|
||||||
// Establish: supervisor state, all interrupts blocked.
|
// Establish: supervisor state, all interrupts blocked.
|
||||||
status_.set_status(0b0010'0011'1000'0000);
|
status_.set_status(0b0010'0011'1000'0000);
|
||||||
did_update_status();
|
did_update_status();
|
||||||
@ -255,7 +255,9 @@ void Executor<model, BusHandler>::run_for_instructions(int count) {
|
|||||||
try {
|
try {
|
||||||
program_counter_.l = read<uint32_t>(vector_address);
|
program_counter_.l = read<uint32_t>(vector_address);
|
||||||
} catch (uint64_t) {
|
} 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>
|
template <Model model, typename BusHandler>
|
||||||
void Executor<model, BusHandler>::stop() {}
|
void Executor<model, BusHandler>::stop() {}
|
||||||
|
|
||||||
|
template <Model model, typename BusHandler>
|
||||||
|
void Executor<model, BusHandler>::reset() {
|
||||||
|
bus_handler_.reset();
|
||||||
|
}
|
||||||
|
|
||||||
template <Model model, typename BusHandler>
|
template <Model model, typename BusHandler>
|
||||||
void Executor<model, BusHandler>::jmp(uint32_t address) {
|
void Executor<model, BusHandler>::jmp(uint32_t address) {
|
||||||
program_counter_.l = address;
|
program_counter_.l = address;
|
||||||
@ -504,6 +511,16 @@ void Executor<model, BusHandler>::tas(Preinstruction instruction, uint32_t addre
|
|||||||
status_.negative_flag_ = value & 0x80;
|
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 <Model model, typename BusHandler>
|
||||||
template <typename IntT>
|
template <typename IntT>
|
||||||
void Executor<model, BusHandler>::movep(Preinstruction instruction, uint32_t source, uint32_t dest) {
|
void Executor<model, BusHandler>::movep(Preinstruction instruction, uint32_t source, uint32_t dest) {
|
||||||
|
@ -427,6 +427,14 @@ template <
|
|||||||
status.set_ccr(src.w);
|
status.set_ccr(src.w);
|
||||||
break;
|
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:
|
case Operation::EXTbtow:
|
||||||
src.w = uint16_t(int8_t(src.b));
|
src.w = uint16_t(int8_t(src.b));
|
||||||
status.overflow_flag_ = status.carry_flag_ = 0;
|
status.overflow_flag_ = status.carry_flag_ = 0;
|
||||||
@ -1162,6 +1170,10 @@ template <
|
|||||||
flow_controller.stop();
|
flow_controller.stop();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Operation::RESET:
|
||||||
|
flow_controller.reset();
|
||||||
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Development period debugging.
|
Development period debugging.
|
||||||
*/
|
*/
|
||||||
|
@ -84,6 +84,9 @@ struct NullFlowController {
|
|||||||
/// Put the processor into the stopped state, waiting for interrupts.
|
/// Put the processor into the stopped state, waiting for interrupts.
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
|
/// Assert the reset output.
|
||||||
|
void reset();
|
||||||
|
|
||||||
/// Perform LINK using the address register identified by @c instruction and the specified @c offset.
|
/// Perform LINK using the address register identified by @c instruction and the specified @c offset.
|
||||||
void link(Preinstruction instruction, uint32_t offset);
|
void link(Preinstruction instruction, uint32_t offset);
|
||||||
|
|
||||||
@ -93,6 +96,14 @@ struct NullFlowController {
|
|||||||
/// Push @c address to the stack.
|
/// Push @c address to the stack.
|
||||||
void pea(uint32_t address);
|
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 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
|
/// 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
|
/// @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);
|
ram[(address+3) & 0xffffff] = uint8_t(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void reset() {}
|
||||||
};
|
};
|
||||||
auto uniqueTest68000 = std::make_unique<Test68000>();
|
auto uniqueTest68000 = std::make_unique<Test68000>();
|
||||||
auto test68000 = uniqueTest68000.get();
|
auto test68000 = uniqueTest68000.get();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user