mirror of
https://github.com/TomHarte/CLK.git
synced 2025-02-19 23:29:05 +00:00
Implements MOVE to CCR.
This commit is contained in:
parent
652f4ebfed
commit
eda88cc462
@ -6,24 +6,32 @@
|
|||||||
// Copyright © 2019 Thomas Harte. All rights reserved.
|
// Copyright © 2019 Thomas Harte. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#define get_status() \
|
#define get_ccr() \
|
||||||
( \
|
( \
|
||||||
(carry_flag_ ? 0x0001 : 0x0000) | \
|
(carry_flag_ ? 0x0001 : 0x0000) | \
|
||||||
(overflow_flag_ ? 0x0002 : 0x0000) | \
|
(overflow_flag_ ? 0x0002 : 0x0000) | \
|
||||||
(zero_result_ ? 0x0000 : 0x0004) | \
|
(zero_result_ ? 0x0000 : 0x0004) | \
|
||||||
(negative_flag_ ? 0x0008 : 0x0000) | \
|
(negative_flag_ ? 0x0008 : 0x0000) | \
|
||||||
(extend_flag_ ? 0x0010 : 0x0000) | \
|
(extend_flag_ ? 0x0010 : 0x0000) \
|
||||||
|
)
|
||||||
|
|
||||||
|
#define get_status() \
|
||||||
|
( \
|
||||||
|
get_ccr() | \
|
||||||
(interrupt_level_ << 8) | \
|
(interrupt_level_ << 8) | \
|
||||||
(trace_flag_ ? 0x8000 : 0x0000) | \
|
(trace_flag_ ? 0x8000 : 0x0000) | \
|
||||||
(is_supervisor_ << 13) \
|
(is_supervisor_ << 13) \
|
||||||
)
|
)
|
||||||
|
|
||||||
#define set_status(x) \
|
#define set_ccr(x) \
|
||||||
carry_flag_ = (x) & 0x0001; \
|
carry_flag_ = (x) & 0x0001; \
|
||||||
overflow_flag_ = (x) & 0x0002; \
|
overflow_flag_ = (x) & 0x0002; \
|
||||||
zero_result_ = ((x) & 0x0004) ^ 0x0004; \
|
zero_result_ = ((x) & 0x0004) ^ 0x0004; \
|
||||||
negative_flag_ = (x) & 0x0008; \
|
negative_flag_ = (x) & 0x0008; \
|
||||||
extend_flag_ = (x) & 0x0010; \
|
extend_flag_ = (x) & 0x0010;
|
||||||
|
|
||||||
|
#define set_status(x) \
|
||||||
|
set_ccr(x) \
|
||||||
interrupt_level_ = ((x) >> 8) & 7; \
|
interrupt_level_ = ((x) >> 8) & 7; \
|
||||||
trace_flag_ = (x) & 0x8000; \
|
trace_flag_ = (x) & 0x8000; \
|
||||||
set_is_supervisor(!!(((x) >> 13) & 1));
|
set_is_supervisor(!!(((x) >> 13) & 1));
|
||||||
@ -58,9 +66,6 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
|
|||||||
active_micro_op_ = active_program_->micro_operations;
|
active_micro_op_ = active_program_->micro_operations;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define sub_overflow() (source ^ destination) & (destination ^ result)
|
|
||||||
#define add_overflow() ~(source ^ destination) & (destination ^ result)
|
|
||||||
|
|
||||||
switch(active_micro_op_->action) {
|
switch(active_micro_op_->action) {
|
||||||
default:
|
default:
|
||||||
std::cerr << "Unhandled 68000 micro op action " << std::hex << active_micro_op_->action << std::endl;
|
std::cerr << "Unhandled 68000 micro op action " << std::hex << active_micro_op_->action << std::endl;
|
||||||
@ -69,6 +74,8 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
|
|||||||
case int(MicroOp::Action::None): break;
|
case int(MicroOp::Action::None): break;
|
||||||
|
|
||||||
case int(MicroOp::Action::PerformOperation):
|
case int(MicroOp::Action::PerformOperation):
|
||||||
|
#define sub_overflow() (source ^ destination) & (destination ^ result)
|
||||||
|
#define add_overflow() ~(source ^ destination) & (destination ^ result)
|
||||||
switch(active_program_->operation) {
|
switch(active_program_->operation) {
|
||||||
/*
|
/*
|
||||||
ABCD adds the lowest bytes form the source and destination using BCD arithmetic,
|
ABCD adds the lowest bytes form the source and destination using BCD arithmetic,
|
||||||
@ -332,6 +339,10 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
|
|||||||
active_program_->source->halves.low.full = get_status();
|
active_program_->source->halves.low.full = get_status();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Operation::MOVEtoCCR:
|
||||||
|
set_ccr(active_program_->source->full);
|
||||||
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
NEGs: negatives the destination, setting the zero,
|
NEGs: negatives the destination, setting the zero,
|
||||||
negative, overflow and carry flags appropriate, and extend.
|
negative, overflow and carry flags appropriate, and extend.
|
||||||
@ -403,9 +414,9 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
|
|||||||
const int source = 0;
|
const int source = 0;
|
||||||
const int destination = active_program_->destination->full;
|
const int destination = active_program_->destination->full;
|
||||||
int64_t result = source - destination - (extend_flag_ ? 1 : 0);
|
int64_t result = source - destination - (extend_flag_ ? 1 : 0);
|
||||||
active_program_->destination->full = result;
|
active_program_->destination->full = uint32_t(result);
|
||||||
|
|
||||||
zero_result_ = result;
|
zero_result_ = uint_fast32_t(result);
|
||||||
extend_flag_ = carry_flag_ = result >> 32;
|
extend_flag_ = carry_flag_ = result >> 32;
|
||||||
negative_flag_ = result & 0x80000000;
|
negative_flag_ = result & 0x80000000;
|
||||||
overflow_flag_ = sub_overflow() & 0x80000000;
|
overflow_flag_ = sub_overflow() & 0x80000000;
|
||||||
@ -456,7 +467,7 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
|
|||||||
zero_result_ |= result & 0xff;
|
zero_result_ |= result & 0xff;
|
||||||
extend_flag_ = carry_flag_ = result & ~0xff;
|
extend_flag_ = carry_flag_ = result & ~0xff;
|
||||||
negative_flag_ = result & 0x80;
|
negative_flag_ = result & 0x80;
|
||||||
overflow_flag_ = (source ^ destination) & (destination ^ result) & 0x80;
|
overflow_flag_ = sub_overflow() & 0x80;
|
||||||
|
|
||||||
// Store the result.
|
// Store the result.
|
||||||
active_program_->destination->halves.low.halves.low = uint8_t(result);
|
active_program_->destination->halves.low.halves.low = uint8_t(result);
|
||||||
@ -470,7 +481,7 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
|
|||||||
zero_result_ = active_program_->destination->halves.low.halves.low = uint8_t(result);
|
zero_result_ = active_program_->destination->halves.low.halves.low = uint8_t(result);
|
||||||
extend_flag_ = carry_flag_ = result & ~0xff;
|
extend_flag_ = carry_flag_ = result & ~0xff;
|
||||||
negative_flag_ = result & 0x80;
|
negative_flag_ = result & 0x80;
|
||||||
overflow_flag_ = (source ^ destination) & (destination ^ result) & 0x80;
|
overflow_flag_ = sub_overflow() & 0x80;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Operation::SUBw: {
|
case Operation::SUBw: {
|
||||||
@ -481,7 +492,7 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
|
|||||||
zero_result_ = active_program_->destination->halves.low.full = uint16_t(result);
|
zero_result_ = active_program_->destination->halves.low.full = uint16_t(result);
|
||||||
extend_flag_ = carry_flag_ = result & ~0xffff;
|
extend_flag_ = carry_flag_ = result & ~0xffff;
|
||||||
negative_flag_ = result & 0x8000;
|
negative_flag_ = result & 0x8000;
|
||||||
overflow_flag_ = (source ^ destination) & (destination ^ result) & 0x8000;
|
overflow_flag_ = sub_overflow() & 0x8000;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Operation::SUBl: {
|
case Operation::SUBl: {
|
||||||
@ -492,7 +503,7 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
|
|||||||
zero_result_ = active_program_->destination->halves.low.full = uint32_t(result);
|
zero_result_ = active_program_->destination->halves.low.full = uint32_t(result);
|
||||||
extend_flag_ = carry_flag_ = result >> 32;
|
extend_flag_ = carry_flag_ = result >> 32;
|
||||||
negative_flag_ = result & 0x80000000;
|
negative_flag_ = result & 0x80000000;
|
||||||
overflow_flag_ = (source ^ destination) & (destination ^ result) & 0x80000000;
|
overflow_flag_ = sub_overflow() & 0x80000000;
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Operation::SUBAw:
|
case Operation::SUBAw:
|
||||||
@ -510,6 +521,8 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
|
|||||||
std::cerr << "Should do something with program operation " << int(active_program_->operation) << std::endl;
|
std::cerr << "Should do something with program operation " << int(active_program_->operation) << std::endl;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#undef sub_overflow
|
||||||
|
#undef add_overflow
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case int(MicroOp::Action::SetMoveFlagsb):
|
case int(MicroOp::Action::SetMoveFlagsb):
|
||||||
@ -775,3 +788,5 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
|
|||||||
|
|
||||||
#undef get_status
|
#undef get_status
|
||||||
#undef set_status
|
#undef set_status
|
||||||
|
#undef set_ccr
|
||||||
|
#undef get_ccr
|
||||||
|
@ -256,7 +256,7 @@ struct ProcessorStorageConstructor {
|
|||||||
enum class Decoder {
|
enum class Decoder {
|
||||||
Decimal,
|
Decimal,
|
||||||
MOVE, // twelve lowest bits are register, mode, mode, register, for destination and source respectively.
|
MOVE, // twelve lowest bits are register, mode, mode, register, for destination and source respectively.
|
||||||
MOVEtoSR, // six lowest bits are [mode, register], decoding to MOVE SR
|
MOVEtoSRCCR, // six lowest bits are [mode, register], decoding to MOVE SR/CCR
|
||||||
CMPI, // eight lowest bits are [size, mode, register], decoding to CMPI
|
CMPI, // eight lowest bits are [size, mode, register], decoding to CMPI
|
||||||
BRA, // eight lowest bits are ignored, and an 'n np np' is scheduled
|
BRA, // eight lowest bits are ignored, and an 'n np np' is scheduled
|
||||||
Bcc, // twelve lowest bits are ignored, only a PerformAction is scheduled
|
Bcc, // twelve lowest bits are ignored, only a PerformAction is scheduled
|
||||||
@ -309,7 +309,8 @@ struct ProcessorStorageConstructor {
|
|||||||
{0xf000, 0x2000, Operation::MOVEl, Decoder::MOVE}, // 4-116 (p220)
|
{0xf000, 0x2000, Operation::MOVEl, Decoder::MOVE}, // 4-116 (p220)
|
||||||
{0xf000, 0x3000, Operation::MOVEw, Decoder::MOVE}, // 4-116 (p220)
|
{0xf000, 0x3000, Operation::MOVEw, Decoder::MOVE}, // 4-116 (p220)
|
||||||
|
|
||||||
{0xffc0, 0x46c0, Operation::MOVEtoSR, Decoder::MOVEtoSR}, // 6-19 (p473)
|
{0xffc0, 0x46c0, Operation::MOVEtoSR, Decoder::MOVEtoSRCCR}, // 6-19 (p473)
|
||||||
|
{0xffc0, 0x44c0, Operation::MOVEtoCCR, Decoder::MOVEtoSRCCR}, // 4-123 (p227)
|
||||||
|
|
||||||
{0xf1c0, 0xb000, Operation::CMPb, Decoder::CMP}, // 4-75 (p179)
|
{0xf1c0, 0xb000, Operation::CMPb, Decoder::CMP}, // 4-75 (p179)
|
||||||
{0xf1c0, 0xb040, Operation::CMPw, Decoder::CMP}, // 4-75 (p179)
|
{0xf1c0, 0xb040, Operation::CMPw, Decoder::CMP}, // 4-75 (p179)
|
||||||
@ -1245,10 +1246,10 @@ struct ProcessorStorageConstructor {
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case Decoder::MOVEtoSR: {
|
case Decoder::MOVEtoSRCCR: {
|
||||||
if(ea_mode == 1) continue;
|
if(ea_mode == 1) continue;
|
||||||
storage_.instructions[instruction].set_source(storage_, ea_mode, ea_register);
|
storage_.instructions[instruction].set_source(storage_, ea_mode, ea_register);
|
||||||
storage_.instructions[instruction].requires_supervisor = true;
|
storage_.instructions[instruction].requires_supervisor = (operation == Operation::MOVEtoSR);
|
||||||
|
|
||||||
/* DEVIATION FROM YACHT.TXT: it has all of these reading an extra word from the PC;
|
/* DEVIATION FROM YACHT.TXT: it has all of these reading an extra word from the PC;
|
||||||
this looks like a mistake so I've padded with nil cycles in the middle. */
|
this looks like a mistake so I've padded with nil cycles in the middle. */
|
||||||
|
@ -55,6 +55,7 @@ class ProcessorStorage {
|
|||||||
MOVEAw, MOVEAl,
|
MOVEAw, MOVEAl,
|
||||||
|
|
||||||
MOVEtoSR, MOVEfromSR,
|
MOVEtoSR, MOVEfromSR,
|
||||||
|
MOVEtoCCR,
|
||||||
|
|
||||||
CMPb, CMPw, CMPl,
|
CMPb, CMPw, CMPl,
|
||||||
BTSTb, BTSTl,
|
BTSTb, BTSTl,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user