mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +00:00
Implements ASL, ASR, LSL and LSR.
This commit is contained in:
parent
a07de97df4
commit
43f619a081
@ -53,16 +53,16 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
|
||||
|
||||
// TODO: unless an interrupt is pending, or the trap flag is set.
|
||||
|
||||
const uint16_t next_instruction = prefetch_queue_.halves.high.full;
|
||||
if(!instructions[next_instruction].micro_operations) {
|
||||
decoded_instruction_ = prefetch_queue_.halves.high.full;
|
||||
if(!instructions[decoded_instruction_].micro_operations) {
|
||||
// TODO: once all instructions are implemnted, this should be an instruction error.
|
||||
std::cerr << "68000 Abilities exhausted; can't manage instruction " << std::hex << next_instruction << " from " << (program_counter_.full - 4) << std::endl;
|
||||
std::cerr << "68000 Abilities exhausted; can't manage instruction " << std::hex << decoded_instruction_ << " from " << (program_counter_.full - 4) << std::endl;
|
||||
return;
|
||||
} else {
|
||||
std::cout << "Performing " << std::hex << next_instruction << " from " << (program_counter_.full - 4) << std::endl;
|
||||
std::cout << "Performing " << std::hex << decoded_instruction_ << " from " << (program_counter_.full - 4) << std::endl;
|
||||
}
|
||||
|
||||
active_program_ = &instructions[next_instruction];
|
||||
active_program_ = &instructions[decoded_instruction_];
|
||||
active_micro_op_ = active_program_->micro_operations;
|
||||
}
|
||||
|
||||
@ -523,28 +523,51 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
|
||||
overflow_flag_ = (value ^ zero_result_) & m; \
|
||||
extend_flag_ = carry_flag_ = value & t;
|
||||
|
||||
#define decode_shift_count() \
|
||||
const int shift_count = (decoded_instruction_ & 32) ? data_[(decoded_instruction_ >> 9) & 7].full&63 : (decoded_instruction_ >> 9) & 7; \
|
||||
active_step_->microcycle.length = HalfCycles(4 * shift_count);
|
||||
|
||||
#define set_flags_b(t) set_flags(active_program_->destination->halves.low.halves.low, 0x80, t)
|
||||
#define set_flags_w(t) set_flags(active_program_->destination->halves.low.full, 0x8000, t)
|
||||
#define set_flags_l(t) set_flags(active_program_->destination->full, 0x80000000, t)
|
||||
|
||||
case Operation::LSLm:
|
||||
case Operation::ASLm: {
|
||||
const auto value = active_program_->destination->halves.low.full;
|
||||
active_program_->destination->halves.low.full <<= 1;
|
||||
set_flags_w(0x8000);
|
||||
} break;
|
||||
#define shift_op(name, op, mb, mw, ml) \
|
||||
case Operation::name##b: { \
|
||||
decode_shift_count(); \
|
||||
const auto value = active_program_->destination->halves.low.halves.low; \
|
||||
op(active_program_->destination->halves.low.halves.low, shift_count, 0xff, 7); \
|
||||
set_flags_b(mb); \
|
||||
} break; \
|
||||
\
|
||||
case Operation::name##w: { \
|
||||
decode_shift_count(); \
|
||||
const auto value = active_program_->destination->halves.low.full; \
|
||||
op(active_program_->destination->halves.low.full, shift_count, 0xffff, 15); \
|
||||
set_flags_w(mw); \
|
||||
} break; \
|
||||
\
|
||||
case Operation::name##l: { \
|
||||
decode_shift_count(); \
|
||||
const auto value = active_program_->destination->full; \
|
||||
op(active_program_->destination->full, shift_count, 0xffffffff, 31); \
|
||||
set_flags_l(ml); \
|
||||
} break; \
|
||||
\
|
||||
case Operation::name##m: { \
|
||||
const auto value = active_program_->destination->halves.low.full; \
|
||||
op(active_program_->destination->halves.low.full, 1, 0xffff, 15); \
|
||||
set_flags_w(mw); \
|
||||
} break;
|
||||
|
||||
case Operation::LSRm: {
|
||||
const auto value = active_program_->destination->halves.low.full;
|
||||
active_program_->destination->halves.low.full >>= 1;
|
||||
set_flags_w(0x0001);
|
||||
} break;
|
||||
#define lsl(x, c, m, d) x <<= c
|
||||
#define lsr(x, c, m, d) x >>= c
|
||||
#define asl(x, c, m, d) x <<= c
|
||||
#define asr(x, c, m, d) x = (x >> c) | (((value >> d) & 1) * (m ^ (m >> c)))
|
||||
|
||||
case Operation::ASRm: {
|
||||
const auto value = active_program_->destination->halves.low.full;
|
||||
active_program_->destination->halves.low.full = (active_program_->destination->halves.low.full >> 1) | (value & 0x8000);
|
||||
set_flags_w(0x0001);
|
||||
} break;
|
||||
shift_op(LSL, lsl, 0x80, 0x8000, 0x80000000);
|
||||
shift_op(ASL, lsl, 0x80, 0x8000, 0x80000000);
|
||||
shift_op(LSR, lsr, 0x01, 0x0001, 0x00000001);
|
||||
shift_op(ASR, asr, 0x01, 0x0001, 0x00000001);
|
||||
|
||||
#undef set_flags
|
||||
#define set_flags(v, m, t) \
|
||||
@ -580,6 +603,7 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
|
||||
} break;
|
||||
|
||||
#undef set_flags
|
||||
#undef decode_shift_count
|
||||
#undef set_flags_b
|
||||
#undef set_flags_w
|
||||
#undef set_flags_l
|
||||
|
@ -59,6 +59,9 @@ struct ProcessorStorageConstructor {
|
||||
|
||||
* n: no operation for four cycles; data bus is not used;
|
||||
* nn: no operation for eight cycles; data bus is not used;
|
||||
* r: a 'replaceable'-length no operation; data bus is not used and no guarantees are
|
||||
made about the length of the cycle other than that when it reaches the interpreter,
|
||||
it is safe to alter the length and leave it altered;
|
||||
* np: program fetch; reads from the PC and adds two to it, advancing the prefetch queue;
|
||||
* nW: write MSW of something onto the bus;
|
||||
* nw: write LSW of something onto the bus;
|
||||
@ -121,10 +124,17 @@ struct ProcessorStorageConstructor {
|
||||
|
||||
// Do nothing (possibly twice).
|
||||
if(token == "n" || token == "nn") {
|
||||
steps.push_back(step);
|
||||
if(token.size() == 2) {
|
||||
steps.push_back(step);
|
||||
step.microcycle.length = HalfCycles(8);
|
||||
}
|
||||
steps.push_back(step);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Do nothing, but with a length that definitely won't map it to the other do-nothings.
|
||||
if(token == "r"){
|
||||
step.microcycle.length = HalfCycles(0);
|
||||
steps.push_back(step);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -384,45 +394,45 @@ struct ProcessorStorageConstructor {
|
||||
{0xffc0, 0x4640, Operation::NOTw, Decoder::CLRNEGNEGXNOT}, // 4-148 (p250)
|
||||
{0xffc0, 0x4680, Operation::NOTl, Decoder::CLRNEGNEGXNOT}, // 4-148 (p250)
|
||||
|
||||
{0xf1d8, 0xe000, Operation::ASLb, Decoder::ASLRLSLRROLRROXLRr}, // 4-22 (p126)
|
||||
{0xf1d8, 0xe040, Operation::ASLw, Decoder::ASLRLSLRROLRROXLRr}, // 4-22 (p126)
|
||||
{0xf1d8, 0xe080, Operation::ASLl, Decoder::ASLRLSLRROLRROXLRr}, // 4-22 (p126)
|
||||
{0xffc0, 0xe0c0, Operation::ASLm, Decoder::ASLRLSLRROLRROXLRm}, // 4-22 (p126)
|
||||
{0xf1d8, 0xe100, Operation::ASLb, Decoder::ASLRLSLRROLRROXLRr}, // 4-22 (p126)
|
||||
{0xf1d8, 0xe140, Operation::ASLw, Decoder::ASLRLSLRROLRROXLRr}, // 4-22 (p126)
|
||||
{0xf1d8, 0xe180, Operation::ASLl, Decoder::ASLRLSLRROLRROXLRr}, // 4-22 (p126)
|
||||
{0xffc0, 0xe1c0, Operation::ASLm, Decoder::ASLRLSLRROLRROXLRm}, // 4-22 (p126)
|
||||
|
||||
{0xf1d8, 0xe100, Operation::ASRb, Decoder::ASLRLSLRROLRROXLRr}, // 4-22 (p126)
|
||||
{0xf1d8, 0xe140, Operation::ASRw, Decoder::ASLRLSLRROLRROXLRr}, // 4-22 (p126)
|
||||
{0xf1d8, 0xe180, Operation::ASRl, Decoder::ASLRLSLRROLRROXLRr}, // 4-22 (p126)
|
||||
{0xffc0, 0xe1c0, Operation::ASRm, Decoder::ASLRLSLRROLRROXLRm}, // 4-22 (p126)
|
||||
{0xf1d8, 0xe000, Operation::ASRb, Decoder::ASLRLSLRROLRROXLRr}, // 4-22 (p126)
|
||||
{0xf1d8, 0xe040, Operation::ASRw, Decoder::ASLRLSLRROLRROXLRr}, // 4-22 (p126)
|
||||
{0xf1d8, 0xe080, Operation::ASRl, Decoder::ASLRLSLRROLRROXLRr}, // 4-22 (p126)
|
||||
{0xffc0, 0xe0c0, Operation::ASRm, Decoder::ASLRLSLRROLRROXLRm}, // 4-22 (p126)
|
||||
|
||||
{0xf1d8, 0xe008, Operation::LSLb, Decoder::ASLRLSLRROLRROXLRr}, // 4-113 (p217)
|
||||
{0xf1d8, 0xe048, Operation::LSLw, Decoder::ASLRLSLRROLRROXLRr}, // 4-113 (p217)
|
||||
{0xf1d8, 0xe088, Operation::LSLl, Decoder::ASLRLSLRROLRROXLRr}, // 4-113 (p217)
|
||||
{0xffc0, 0xe2c0, Operation::LSLm, Decoder::ASLRLSLRROLRROXLRm}, // 4-113 (p217)
|
||||
{0xf1d8, 0xe108, Operation::LSLb, Decoder::ASLRLSLRROLRROXLRr}, // 4-113 (p217)
|
||||
{0xf1d8, 0xe148, Operation::LSLw, Decoder::ASLRLSLRROLRROXLRr}, // 4-113 (p217)
|
||||
{0xf1d8, 0xe188, Operation::LSLl, Decoder::ASLRLSLRROLRROXLRr}, // 4-113 (p217)
|
||||
{0xffc0, 0xe3c0, Operation::LSLm, Decoder::ASLRLSLRROLRROXLRm}, // 4-113 (p217)
|
||||
|
||||
{0xf1d8, 0xe108, Operation::LSRb, Decoder::ASLRLSLRROLRROXLRr}, // 4-113 (p217)
|
||||
{0xf1d8, 0xe148, Operation::LSRw, Decoder::ASLRLSLRROLRROXLRr}, // 4-113 (p217)
|
||||
{0xf1d8, 0xe188, Operation::LSRl, Decoder::ASLRLSLRROLRROXLRr}, // 4-113 (p217)
|
||||
{0xffc0, 0xe3c0, Operation::LSRm, Decoder::ASLRLSLRROLRROXLRm}, // 4-113 (p217)
|
||||
{0xf1d8, 0xe008, Operation::LSRb, Decoder::ASLRLSLRROLRROXLRr}, // 4-113 (p217)
|
||||
{0xf1d8, 0xe048, Operation::LSRw, Decoder::ASLRLSLRROLRROXLRr}, // 4-113 (p217)
|
||||
{0xf1d8, 0xe088, Operation::LSRl, Decoder::ASLRLSLRROLRROXLRr}, // 4-113 (p217)
|
||||
{0xffc0, 0xe2c0, Operation::LSRm, Decoder::ASLRLSLRROLRROXLRm}, // 4-113 (p217)
|
||||
|
||||
{0xf1d8, 0xe018, Operation::ROLb, Decoder::ASLRLSLRROLRROXLRr}, // 4-160 (p264)
|
||||
{0xf1d8, 0xe058, Operation::ROLw, Decoder::ASLRLSLRROLRROXLRr}, // 4-160 (p264)
|
||||
{0xf1d8, 0xe098, Operation::ROLl, Decoder::ASLRLSLRROLRROXLRr}, // 4-160 (p264)
|
||||
{0xffc0, 0xe6c0, Operation::ROLm, Decoder::ASLRLSLRROLRROXLRm}, // 4-160 (p264)
|
||||
{0xf1d8, 0xe118, Operation::ROLb, Decoder::ASLRLSLRROLRROXLRr}, // 4-160 (p264)
|
||||
{0xf1d8, 0xe158, Operation::ROLw, Decoder::ASLRLSLRROLRROXLRr}, // 4-160 (p264)
|
||||
{0xf1d8, 0xe198, Operation::ROLl, Decoder::ASLRLSLRROLRROXLRr}, // 4-160 (p264)
|
||||
{0xffc0, 0xe7c0, Operation::ROLm, Decoder::ASLRLSLRROLRROXLRm}, // 4-160 (p264)
|
||||
|
||||
{0xf1d8, 0xe118, Operation::RORb, Decoder::ASLRLSLRROLRROXLRr}, // 4-160 (p264)
|
||||
{0xf1d8, 0xe158, Operation::RORw, Decoder::ASLRLSLRROLRROXLRr}, // 4-160 (p264)
|
||||
{0xf1d8, 0xe198, Operation::RORl, Decoder::ASLRLSLRROLRROXLRr}, // 4-160 (p264)
|
||||
{0xffc0, 0xe7c0, Operation::RORm, Decoder::ASLRLSLRROLRROXLRm}, // 4-160 (p264)
|
||||
{0xf1d8, 0xe018, Operation::RORb, Decoder::ASLRLSLRROLRROXLRr}, // 4-160 (p264)
|
||||
{0xf1d8, 0xe058, Operation::RORw, Decoder::ASLRLSLRROLRROXLRr}, // 4-160 (p264)
|
||||
{0xf1d8, 0xe098, Operation::RORl, Decoder::ASLRLSLRROLRROXLRr}, // 4-160 (p264)
|
||||
{0xffc0, 0xe6c0, Operation::RORm, Decoder::ASLRLSLRROLRROXLRm}, // 4-160 (p264)
|
||||
|
||||
{0xf1d8, 0xe010, Operation::ROXLb, Decoder::ASLRLSLRROLRROXLRr}, // 4-163 (p267)
|
||||
{0xf1d8, 0xe050, Operation::ROXLw, Decoder::ASLRLSLRROLRROXLRr}, // 4-163 (p267)
|
||||
{0xf1d8, 0xe090, Operation::ROXLl, Decoder::ASLRLSLRROLRROXLRr}, // 4-163 (p267)
|
||||
{0xffc0, 0xe4c0, Operation::ROXLm, Decoder::ASLRLSLRROLRROXLRm}, // 4-163 (p267)
|
||||
{0xf1d8, 0xe110, Operation::ROXLb, Decoder::ASLRLSLRROLRROXLRr}, // 4-163 (p267)
|
||||
{0xf1d8, 0xe150, Operation::ROXLw, Decoder::ASLRLSLRROLRROXLRr}, // 4-163 (p267)
|
||||
{0xf1d8, 0xe190, Operation::ROXLl, Decoder::ASLRLSLRROLRROXLRr}, // 4-163 (p267)
|
||||
{0xffc0, 0xe5c0, Operation::ROXLm, Decoder::ASLRLSLRROLRROXLRm}, // 4-163 (p267)
|
||||
|
||||
{0xf1d8, 0xe110, Operation::ROXRb, Decoder::ASLRLSLRROLRROXLRr}, // 4-163 (p267)
|
||||
{0xf1d8, 0xe150, Operation::ROXRw, Decoder::ASLRLSLRROLRROXLRr}, // 4-163 (p267)
|
||||
{0xf1d8, 0xe190, Operation::ROXRl, Decoder::ASLRLSLRROLRROXLRr}, // 4-163 (p267)
|
||||
{0xffc0, 0xe5c0, Operation::ROXRm, Decoder::ASLRLSLRROLRROXLRm}, // 4-163 (p267)
|
||||
{0xf1d8, 0xe010, Operation::ROXRb, Decoder::ASLRLSLRROLRROXLRr}, // 4-163 (p267)
|
||||
{0xf1d8, 0xe050, Operation::ROXRw, Decoder::ASLRLSLRROLRROXLRr}, // 4-163 (p267)
|
||||
{0xf1d8, 0xe090, Operation::ROXRl, Decoder::ASLRLSLRROLRROXLRr}, // 4-163 (p267)
|
||||
{0xffc0, 0xe4c0, Operation::ROXRm, Decoder::ASLRLSLRROLRROXLRm}, // 4-163 (p267)
|
||||
};
|
||||
|
||||
#ifndef NDEBUG
|
||||
@ -928,7 +938,9 @@ struct ProcessorStorageConstructor {
|
||||
} else {
|
||||
op(Action::None, seq("np n"));
|
||||
}
|
||||
op(Action::PerformOperation);
|
||||
|
||||
// Use a no-op bus cycle that can have its length filled in later.
|
||||
op(Action::PerformOperation, seq("r"));
|
||||
} break;
|
||||
|
||||
case Decoder::ASLRLSLRROLRROXLRm: {
|
||||
|
@ -282,6 +282,7 @@ class ProcessorStorage {
|
||||
Program *active_program_ = nullptr;
|
||||
MicroOp *active_micro_op_ = nullptr;
|
||||
BusStep *active_step_ = nullptr;
|
||||
uint16_t decoded_instruction_;
|
||||
|
||||
/// Copies address_[7] to the proper stack pointer based on current mode.
|
||||
void write_back_stack_pointer();
|
||||
|
Loading…
x
Reference in New Issue
Block a user