mirror of
https://github.com/TomHarte/CLK.git
synced 2024-11-26 23:52:26 +00:00
Implements MOVE to SR, fleshing out the final bits of storage for the status word.
This commit is contained in:
parent
47359dc8f1
commit
3ccec1c996
@ -6,6 +6,28 @@
|
|||||||
// Copyright © 2019 Thomas Harte. All rights reserved.
|
// Copyright © 2019 Thomas Harte. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#define get_status() \
|
||||||
|
( \
|
||||||
|
(carry_flag_ ? 0x0001 : 0x0000) | \
|
||||||
|
(overflow_flag_ ? 0x0002 : 0x0000) | \
|
||||||
|
(zero_result_ ? 0x0000 : 0x0004) | \
|
||||||
|
(negative_flag_ ? 0x0008 : 0x0000) | \
|
||||||
|
(extend_flag_ ? 0x0010 : 0x0000) | \
|
||||||
|
(interrupt_level_ << 8) | \
|
||||||
|
(trace_flag_ ? 0x8000 : 0x0000) | \
|
||||||
|
(is_supervisor_ << 13) \
|
||||||
|
)
|
||||||
|
|
||||||
|
#define set_status(x) \
|
||||||
|
carry_flag_ = (x) & 0x0001; \
|
||||||
|
overflow_flag_ = (x) & 0x0002; \
|
||||||
|
zero_result_ = ((x) & 0x0004) ^ 0x0004; \
|
||||||
|
negative_flag_ = (x) & 0x0008; \
|
||||||
|
extend_flag_ = (x) & 0x0010; \
|
||||||
|
interrupt_level_ = ((x) >> 8) & 7; \
|
||||||
|
trace_flag_ = (x) & 0x8000; \
|
||||||
|
is_supervisor_ = ((x) >> 13) & 1;
|
||||||
|
|
||||||
template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>::run_for(HalfCycles duration) {
|
template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>::run_for(HalfCycles duration) {
|
||||||
HalfCycles remaining_duration = duration + half_cycles_left_to_run_;
|
HalfCycles remaining_duration = duration + half_cycles_left_to_run_;
|
||||||
while(remaining_duration > HalfCycles(0)) {
|
while(remaining_duration > HalfCycles(0)) {
|
||||||
@ -55,7 +77,7 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
|
|||||||
if(result > 0x99) result += 0x60;
|
if(result > 0x99) result += 0x60;
|
||||||
|
|
||||||
// Set all flags essentially as if this were normal addition.
|
// Set all flags essentially as if this were normal addition.
|
||||||
zero_flag_ |= 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_ = ~(source ^ destination) & (destination ^ result) & 0x80;
|
||||||
@ -76,7 +98,7 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
|
|||||||
if(result > 0x99) result -= 0x60;
|
if(result > 0x99) result -= 0x60;
|
||||||
|
|
||||||
// Set all flags essentially as if this were normal subtraction.
|
// Set all flags essentially as if this were normal subtraction.
|
||||||
zero_flag_ |= 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_ = (source ^ destination) & (destination ^ result) & 0x80;
|
||||||
@ -90,20 +112,20 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
|
|||||||
and set negative, zero, overflow and carry as appropriate.
|
and set negative, zero, overflow and carry as appropriate.
|
||||||
*/
|
*/
|
||||||
case Operation::MOVEb:
|
case Operation::MOVEb:
|
||||||
zero_flag_ = active_program_->destination->halves.low.halves.low = active_program_->source->halves.low.halves.low;
|
zero_result_ = active_program_->destination->halves.low.halves.low = active_program_->source->halves.low.halves.low;
|
||||||
negative_flag_ = zero_flag_ & 0x80;
|
negative_flag_ = zero_result_ & 0x80;
|
||||||
overflow_flag_ = carry_flag_ = 0;
|
overflow_flag_ = carry_flag_ = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Operation::MOVEw:
|
case Operation::MOVEw:
|
||||||
zero_flag_ = active_program_->destination->halves.low.full = active_program_->source->halves.low.full;
|
zero_result_ = active_program_->destination->halves.low.full = active_program_->source->halves.low.full;
|
||||||
negative_flag_ = zero_flag_ & 0x8000;
|
negative_flag_ = zero_result_ & 0x8000;
|
||||||
overflow_flag_ = carry_flag_ = 0;
|
overflow_flag_ = carry_flag_ = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Operation::MOVEl:
|
case Operation::MOVEl:
|
||||||
zero_flag_ = active_program_->destination->full = active_program_->source->full;
|
zero_result_ = active_program_->destination->full = active_program_->source->full;
|
||||||
negative_flag_ = zero_flag_ & 0x80000000;
|
negative_flag_ = zero_result_ & 0x80000000;
|
||||||
overflow_flag_ = carry_flag_ = 0;
|
overflow_flag_ = carry_flag_ = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -122,6 +144,21 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
|
|||||||
active_program_->destination->full = active_program_->source->full;
|
active_program_->destination->full = active_program_->source->full;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Status word moves.
|
||||||
|
*/
|
||||||
|
|
||||||
|
case Operation::MOVEtoSR:
|
||||||
|
set_status(active_program_->source->full);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Operation::MOVEfromSR:
|
||||||
|
active_program_->source->halves.low.full = get_status();
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
Development period debugging.
|
||||||
|
*/
|
||||||
default:
|
default:
|
||||||
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;
|
||||||
@ -129,20 +166,20 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case int(MicroOp::Action::SetMoveFlagsb):
|
case int(MicroOp::Action::SetMoveFlagsb):
|
||||||
zero_flag_ = active_program_->source->halves.low.halves.low;
|
zero_result_ = active_program_->source->halves.low.halves.low;
|
||||||
negative_flag_ = zero_flag_ & 0x80;
|
negative_flag_ = zero_result_ & 0x80;
|
||||||
overflow_flag_ = carry_flag_ = 0;
|
overflow_flag_ = carry_flag_ = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case int(MicroOp::Action::SetMoveFlagsw):
|
case int(MicroOp::Action::SetMoveFlagsw):
|
||||||
zero_flag_ = active_program_->source->halves.low.full;
|
zero_result_ = active_program_->source->halves.low.full;
|
||||||
negative_flag_ = zero_flag_ & 0x8000;
|
negative_flag_ = zero_result_ & 0x8000;
|
||||||
overflow_flag_ = carry_flag_ = 0;
|
overflow_flag_ = carry_flag_ = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case int(MicroOp::Action::SetMoveFlagsl):
|
case int(MicroOp::Action::SetMoveFlagsl):
|
||||||
zero_flag_ = active_program_->source->full;
|
zero_result_ = active_program_->source->full;
|
||||||
negative_flag_ = zero_flag_ & 0x80000000;
|
negative_flag_ = zero_result_ & 0x80000000;
|
||||||
overflow_flag_ = carry_flag_ = 0;
|
overflow_flag_ = carry_flag_ = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -322,15 +359,7 @@ template <class T, bool dtack_is_implicit> ProcessorState Processor<T, dtack_is_
|
|||||||
state.user_stack_pointer = stack_pointers_[0].full;
|
state.user_stack_pointer = stack_pointers_[0].full;
|
||||||
state.supervisor_stack_pointer = stack_pointers_[1].full;
|
state.supervisor_stack_pointer = stack_pointers_[1].full;
|
||||||
|
|
||||||
// TODO: rest of status word: interrupt level, trace flag.
|
state.status = get_status();
|
||||||
state.status =
|
|
||||||
(carry_flag_ ? 0x0001 : 0x0000) |
|
|
||||||
(overflow_flag_ ? 0x0002 : 0x0000) |
|
|
||||||
(zero_flag_ ? 0x0000 : 0x0004) |
|
|
||||||
(negative_flag_ ? 0x0008 : 0x0000) |
|
|
||||||
(extend_flag_ ? 0x0010 : 0x0000) |
|
|
||||||
|
|
||||||
(is_supervisor_ << 13);
|
|
||||||
|
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
@ -341,14 +370,10 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
|
|||||||
stack_pointers_[0].full = state.user_stack_pointer;
|
stack_pointers_[0].full = state.user_stack_pointer;
|
||||||
stack_pointers_[1].full = state.supervisor_stack_pointer;
|
stack_pointers_[1].full = state.supervisor_stack_pointer;
|
||||||
|
|
||||||
carry_flag_ = state.status & 0x0001;
|
set_status(state.status);
|
||||||
overflow_flag_ = state.status & 0x0002;
|
|
||||||
zero_flag_ = (state.status & 0x0004) ^ 0x0004;
|
|
||||||
negative_flag_ = state.status & 0x0008;
|
|
||||||
extend_flag_ = state.status & 0x0010;
|
|
||||||
|
|
||||||
is_supervisor_ = (state.status >> 13) & 1;
|
|
||||||
address_[7] = stack_pointers_[is_supervisor_];
|
address_[7] = stack_pointers_[is_supervisor_];
|
||||||
|
|
||||||
// TODO: rest of status word: interrupt level, trace flag.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#undef get_status
|
||||||
|
#undef set_status
|
||||||
|
@ -18,6 +18,17 @@ struct ProcessorStorageConstructor {
|
|||||||
|
|
||||||
using BusStep = ProcessorStorage::BusStep;
|
using BusStep = ProcessorStorage::BusStep;
|
||||||
|
|
||||||
|
int calc_action_for_mode(int mode) const {
|
||||||
|
using Action = ProcessorBase::MicroOp::Action;
|
||||||
|
switch(mode & 0xff) {
|
||||||
|
default: return 0;
|
||||||
|
case 0x12: return int(Action::CalcD16PC); // (d16, PC)
|
||||||
|
case 0x13: return int(Action::CalcD8PCXn); // (d8, PC, Xn)
|
||||||
|
case 0x05: return int(Action::CalcD16An); // (d16, An)
|
||||||
|
case 0x06: return int(Action::CalcD8AnXn); // (d8, An, Xn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Installs BusSteps that implement the described program into the relevant
|
Installs BusSteps that implement the described program into the relevant
|
||||||
instance storage, returning the offset within @c all_bus_steps_ at which
|
instance storage, returning the offset within @c all_bus_steps_ at which
|
||||||
@ -163,8 +174,10 @@ struct ProcessorStorageConstructor {
|
|||||||
}
|
}
|
||||||
steps.push_back(step);
|
steps.push_back(step);
|
||||||
|
|
||||||
++address_iterator;
|
if(!isupper(access_pattern[1])) {
|
||||||
if(!isupper(access_pattern[1])) ++(*scratch_data);
|
++(*scratch_data);
|
||||||
|
++address_iterator;
|
||||||
|
}
|
||||||
access_pattern += 2;
|
access_pattern += 2;
|
||||||
} break;
|
} break;
|
||||||
}
|
}
|
||||||
@ -214,7 +227,9 @@ struct ProcessorStorageConstructor {
|
|||||||
RegOpModeReg,
|
RegOpModeReg,
|
||||||
SizeModeRegisterImmediate,
|
SizeModeRegisterImmediate,
|
||||||
DataSizeModeQuick,
|
DataSizeModeQuick,
|
||||||
RegisterModeModeRegister
|
RegisterModeModeRegister, // i.e. twelve lowest bits are register, mode, mode, register, for destination and source respectively.
|
||||||
|
ModeRegister, // i.e. six lowest bits are mode, then register.
|
||||||
|
MOVEtoSR
|
||||||
};
|
};
|
||||||
|
|
||||||
using Operation = ProcessorStorage::Operation;
|
using Operation = ProcessorStorage::Operation;
|
||||||
@ -254,6 +269,8 @@ struct ProcessorStorageConstructor {
|
|||||||
{0xf000, 0x1000, Operation::MOVEb, Decoder::RegisterModeModeRegister}, // 4-116 (p220)
|
{0xf000, 0x1000, Operation::MOVEb, Decoder::RegisterModeModeRegister}, // 4-116 (p220)
|
||||||
{0xf000, 0x2000, Operation::MOVEl, Decoder::RegisterModeModeRegister}, // 4-116 (p220)
|
{0xf000, 0x2000, Operation::MOVEl, Decoder::RegisterModeModeRegister}, // 4-116 (p220)
|
||||||
{0xf000, 0x3000, Operation::MOVEw, Decoder::RegisterModeModeRegister}, // 4-116 (p220)
|
{0xf000, 0x3000, Operation::MOVEw, Decoder::RegisterModeModeRegister}, // 4-116 (p220)
|
||||||
|
|
||||||
|
{0xffc0, 0x46c0, Operation::MOVEtoSR, Decoder::MOVEtoSR}, // 6-19 (p473)
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<size_t> micro_op_pointers(65536, std::numeric_limits<size_t>::max());
|
std::vector<size_t> micro_op_pointers(65536, std::numeric_limits<size_t>::max());
|
||||||
@ -295,7 +312,82 @@ struct ProcessorStorageConstructor {
|
|||||||
}
|
}
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
// Decodes the format used by all the MOVEs.
|
case Decoder::MOVEtoSR: {
|
||||||
|
const int source_register = instruction & 7;
|
||||||
|
const int source_mode = (instruction >> 3) & 7;
|
||||||
|
|
||||||
|
switch(source_mode) {
|
||||||
|
case 0: // Dn
|
||||||
|
storage_.instructions[instruction].source = &storage_.data_[source_register];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: continue; // An
|
||||||
|
|
||||||
|
default: // (An), (An)+, -(An), (d16, An), (d8, An Xn), (xxx).W, (xxx).L
|
||||||
|
storage_.instructions[instruction].source = &storage_.bus_data_[0];
|
||||||
|
storage_.instructions[instruction].destination = &storage_.bus_data_[1];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 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. */
|
||||||
|
switch( (source_mode == 7) ? (0x10 | source_register) : source_mode) {
|
||||||
|
case 0x00: // MOVE Dn, SR
|
||||||
|
op(Action::PerformOperation, seq("nn np"));
|
||||||
|
op();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x02: // MOVE (An), SR
|
||||||
|
case 0x03: // MOVE (An)+, SR
|
||||||
|
op(Action::None, seq("nr nn nn np", { &storage_.address_[source_register].full }));
|
||||||
|
if(source_mode == 0x3) {
|
||||||
|
op(int(Action::Increment2) | MicroOp::SourceMask);
|
||||||
|
}
|
||||||
|
op(Action::PerformOperation);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x04: // MOVE -(An), SR
|
||||||
|
op(Action::Decrement2, seq("n nr nn nn np", { &storage_.address_[source_register].full }));
|
||||||
|
op(Action::PerformOperation);
|
||||||
|
break;
|
||||||
|
|
||||||
|
#define pseq(x) ((source_mode == 0x06) || (source_mode == 0x13) ? "n" x : x)
|
||||||
|
|
||||||
|
case 0x12: // MOVE (d16, PC), SR
|
||||||
|
case 0x13: // MOVE (d8, PC, Xn), SR
|
||||||
|
case 0x05: // MOVE (d16, An), SR
|
||||||
|
case 0x06: // MOVE (d8, An, Xn), SR
|
||||||
|
op(calc_action_for_mode(source_mode) | MicroOp::SourceMask, seq(pseq("np nr nn nn np"), { &storage_.effective_address_[0] }));
|
||||||
|
op(Action::PerformOperation);
|
||||||
|
break;
|
||||||
|
|
||||||
|
#undef pseq
|
||||||
|
|
||||||
|
case 0x10: // MOVE (xxx).W, SR
|
||||||
|
op(
|
||||||
|
int(MicroOp::Action::AssembleWordFromPrefetch) | MicroOp::SourceMask,
|
||||||
|
seq("np nr nn nn np", { &storage_.effective_address_[0] }));
|
||||||
|
op(Action::PerformOperation);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x11: // MOVE (xxx).L, SR
|
||||||
|
op(Action::None, seq("np"));
|
||||||
|
op(int(MicroOp::Action::AssembleLongWordFromPrefetch) | MicroOp::SourceMask, seq("np nr", { &storage_.effective_address_[0] }));
|
||||||
|
op(Action::PerformOperation, seq("nn nn np"));
|
||||||
|
op();
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0x14: // MOVE #, SR
|
||||||
|
storage_.instructions[instruction].source = &storage_.prefetch_queue_;
|
||||||
|
op(int(Action::PerformOperation), seq("np nn nn np"));
|
||||||
|
op();
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: continue;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
|
||||||
|
// Decodes the format used by most MOVEs and all MOVEAs.
|
||||||
case Decoder::RegisterModeModeRegister: {
|
case Decoder::RegisterModeModeRegister: {
|
||||||
const int source_register = instruction & 7;
|
const int source_register = instruction & 7;
|
||||||
const int source_mode = (instruction >> 3) & 7;
|
const int source_mode = (instruction >> 3) & 7;
|
||||||
@ -445,18 +537,44 @@ struct ProcessorStorageConstructor {
|
|||||||
operation = Operation::MOVEAl;
|
operation = Operation::MOVEAl;
|
||||||
case 0x10200: // MOVE.l (An), Dn
|
case 0x10200: // MOVE.l (An), Dn
|
||||||
case 0x10300: // MOVE.l (An)+, Dn
|
case 0x10300: // MOVE.l (An)+, Dn
|
||||||
op(Action::CopySourceToEffectiveAddress, seq("nR nr np", {&storage_.effective_address_[0], &storage_.effective_address_[0]}));
|
op(Action::CopySourceToEffectiveAddress, seq("nR nr np", { &storage_.effective_address_[0] }));
|
||||||
if(source_mode == 0x3) {
|
if(source_mode == 0x3) {
|
||||||
op(int(Action::Increment4) | MicroOp::SourceMask);
|
op(int(Action::Increment4) | MicroOp::SourceMask);
|
||||||
}
|
}
|
||||||
op(Action::PerformOperation);
|
op(Action::PerformOperation);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x0202: // MOVE (An), (An)
|
case 0x00202: // MOVE.bw (An), (An)
|
||||||
case 0x0302: // MOVE (An)+, (An)
|
case 0x00302: // MOVE.bw (An)+, (An)
|
||||||
case 0x0203: // MOVE (An), (An)+
|
case 0x00203: // MOVE.bw (An), (An)+
|
||||||
case 0x0303: // MOVE (An)+, (An)+
|
case 0x00303: // MOVE.bw (An)+, (An)+
|
||||||
// nr nw np
|
op(Action::None, seq("nr", { &storage_.address_[source_register].full }));
|
||||||
|
op(Action::PerformOperation, seq("nw np", { &storage_.address_[destination_register].full }));
|
||||||
|
if(source_mode == 0x3 || destination_mode == 0x3) {
|
||||||
|
op(
|
||||||
|
int(is_byte_access ? Action::Increment1 : Action::Increment2) |
|
||||||
|
(source_mode == 0x3 ? MicroOp::SourceMask : 0) |
|
||||||
|
(source_mode == 0x3 ? MicroOp::DestinationMask : 0));
|
||||||
|
} else {
|
||||||
|
op();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
|
||||||
|
case 0x10202: // MOVE.l (An), (An)
|
||||||
|
case 0x10302: // MOVE.l (An)+, (An)
|
||||||
|
case 0x10203: // MOVE.l (An), (An)+
|
||||||
|
case 0x10303: // MOVE.l (An)+, (An)+
|
||||||
|
op(Action::CopyDestinationToEffectiveAddress);
|
||||||
|
op(Action::CopySourceToEffectiveAddress, seq("nR nr", { &storage_.effective_address_[0] }));
|
||||||
|
op(Action::PerformOperation, seq("nW nw np", { &storage_.effective_address_[1] }));
|
||||||
|
if(source_mode == 0x3 || destination_mode == 0x3) {
|
||||||
|
op(
|
||||||
|
int(Action::Increment4) |
|
||||||
|
(source_mode == 0x3 ? MicroOp::SourceMask : 0) |
|
||||||
|
(source_mode == 0x3 ? MicroOp::DestinationMask : 0));
|
||||||
|
} else {
|
||||||
|
op();
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case 0x0204: // MOVE (An), -(An)
|
case 0x0204: // MOVE (An), -(An)
|
||||||
@ -620,11 +738,12 @@ struct ProcessorStorageConstructor {
|
|||||||
// Source = (xxx).L
|
// Source = (xxx).L
|
||||||
//
|
//
|
||||||
|
|
||||||
case 0x1101: // MOVEA (xxx).W, Dn
|
case 0x1101: // MOVEA (xxx).L, Dn
|
||||||
operation = Operation::MOVEAw;
|
operation = Operation::MOVEAw;
|
||||||
case 0x1100: // MOVE (xxx).W, Dn
|
case 0x1100: // MOVE (xxx).L, Dn
|
||||||
op(int(MicroOp::Action::AssembleWordFromPrefetch) | MicroOp::SourceMask, seq("np np"));
|
op(Action::None, seq("np"));
|
||||||
op(Action::PerformOperation, seq("nr np", { &storage_.effective_address_[0] }, !is_byte_access));
|
op(int(MicroOp::Action::AssembleLongWordFromPrefetch) | MicroOp::SourceMask, seq("np nr", { &storage_.effective_address_[0] }, !is_byte_access));
|
||||||
|
op(Action::PerformOperation, seq("np"));
|
||||||
op();
|
op();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -26,11 +26,13 @@ class ProcessorStorage {
|
|||||||
|
|
||||||
// Various status bits.
|
// Various status bits.
|
||||||
int is_supervisor_;
|
int is_supervisor_;
|
||||||
uint_fast32_t zero_flag_; // The zero flag is set if this value is zero.
|
int interrupt_level_;
|
||||||
|
uint_fast32_t zero_result_; // The zero flag is set if this value is zero.
|
||||||
uint_fast32_t carry_flag_; // The carry flag is set if this value is non-zero.
|
uint_fast32_t carry_flag_; // The carry flag is set if this value is non-zero.
|
||||||
uint_fast32_t extend_flag_; // The extend flag is set if this value is non-zero.
|
uint_fast32_t extend_flag_; // The extend flag is set if this value is non-zero.
|
||||||
uint_fast32_t overflow_flag_; // The overflow flag is set if this value is non-zero.
|
uint_fast32_t overflow_flag_; // The overflow flag is set if this value is non-zero.
|
||||||
uint_fast32_t negative_flag_; // The negative flag is set if this value is non-zero.
|
uint_fast32_t negative_flag_; // The negative flag is set if this value is non-zero.
|
||||||
|
uint_fast32_t trace_flag_; // The trace flag is set if this value is non-zero.
|
||||||
|
|
||||||
// Generic sources and targets for memory operations;
|
// Generic sources and targets for memory operations;
|
||||||
// by convention: [0] = source, [1] = destination.
|
// by convention: [0] = source, [1] = destination.
|
||||||
@ -44,7 +46,9 @@ class ProcessorStorage {
|
|||||||
ADD, AND, EOR, OR, SUB,
|
ADD, AND, EOR, OR, SUB,
|
||||||
|
|
||||||
MOVEb, MOVEw, MOVEl,
|
MOVEb, MOVEw, MOVEl,
|
||||||
MOVEAw, MOVEAl
|
MOVEAw, MOVEAl,
|
||||||
|
|
||||||
|
MOVEtoSR, MOVEfromSR
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
@ -192,6 +196,7 @@ class ProcessorStorage {
|
|||||||
RegisterPair32 *source = nullptr;
|
RegisterPair32 *source = nullptr;
|
||||||
RegisterPair32 *destination = nullptr;
|
RegisterPair32 *destination = nullptr;
|
||||||
Operation operation;
|
Operation operation;
|
||||||
|
bool requires_supervisor = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Storage for all the sequences of bus steps and micro-ops used throughout
|
// Storage for all the sequences of bus steps and micro-ops used throughout
|
||||||
|
Loading…
Reference in New Issue
Block a user