1
0
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:
Thomas Harte 2022-05-11 07:52:23 -04:00
parent 4b97427937
commit 943c924382
5 changed files with 51 additions and 4 deletions

View File

@ -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;

View File

@ -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) {

View File

@ -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.
*/ */

View File

@ -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

View File

@ -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();