1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-05 10:28:58 +00:00

Adds BTST.

This commit is contained in:
Thomas Harte 2019-04-04 21:43:22 -04:00
parent 068ce23716
commit 2d153359f8
3 changed files with 125 additions and 1 deletions

View File

@ -147,6 +147,16 @@ template <class T, bool dtack_is_implicit> void Processor<T, dtack_is_implicit>:
}
} break;
// Two BTSTs: set the zero flag according to the value of the destination masked by
// the bit named in the source modulo the operation size.
case Operation::BTSTb:
zero_result_ = active_program_->destination->full & (1 << (active_program_->source->full & 7));
break;
case Operation::BTSTl:
zero_result_ = active_program_->destination->full & (1 << (active_program_->source->full & 31));
break;
// Bcc: evaluates the relevant condition and displacement size and then:
// if condition is false, schedules bus operations to get past this instruction;
// otherwise applies the offset and schedules bus operations to refill the prefetch queue.

View File

@ -266,6 +266,8 @@ struct ProcessorStorageConstructor {
JMP, // six lowest bits are [mode, register], decoding to JMP
ADDSUB,
ADDASUBA,
BTST, // bit 9,10,11 are register, six lowest bits are [mode, register], decoding to BTST
BTSTIMM, // six lowest bits are [mode, register], decoding to BTST #
};
using Operation = ProcessorStorage::Operation;
@ -331,6 +333,9 @@ struct ProcessorStorageConstructor {
{0xf1c0, 0xd1c0, Operation::ADDAl, Decoder::ADDASUBA}, // 4-7 (p111)
{0xf1c0, 0x90c0, Operation::SUBAw, Decoder::ADDASUBA}, // 4-177 (p281)
{0xf1c0, 0x91c0, Operation::SUBAl, Decoder::ADDASUBA}, // 4-177 (p281)
{0xf1c0, 0x0100, Operation::BTSTb, Decoder::BTST}, // 4-62 (p166)
{0xffc0, 0x0800, Operation::BTSTb, Decoder::BTSTIMM}, // 4-63 (p167)
};
std::vector<size_t> micro_op_pointers(65536, std::numeric_limits<size_t>::max());
@ -686,6 +691,114 @@ struct ProcessorStorageConstructor {
op(Action::PerformOperation, seq("n np np"));
} break;
// Decodes a BTST, potential mutating the operation into a BTSTl.
case Decoder::BTST: {
const int mask_register = (instruction >> 9) & 7;
storage_.instructions[instruction].set_source(storage_, 0, mask_register);
storage_.instructions[instruction].set_destination(storage_, source_mode, source_register);
const int mode = combined_mode(source_mode, source_register);
switch(mode) {
default: continue;
case 0x00: // BTST.l Dn, Dn
operation = Operation::BTSTl;
op(Action::PerformOperation, seq("np n"));
break;
case 0x02: // BTST.b Dn, (An)
case 0x03: // BTST.b Dn, (An)+
op(Action::None, seq("nrd np", { &storage_.data_[source_register].full }, false));
op(Action::PerformOperation);
if(mode == 0x03) {
op(int(Action::Increment1) | MicroOp::DestinationMask);
}
break;
case 0x04: // BTST.b Dn, -(An)
op(int(Action::Decrement1) | MicroOp::DestinationMask, seq("n nrd np", { &storage_.data_[source_register].full }, false));
op(Action::PerformOperation);
break;
case 0x05: // BTST.b Dn, (d16, An)
case 0x06: // BTST.b Dn, (d8, An, Xn)
case 0x12: // BTST.b Dn, (d16, PC)
case 0x13: // BTST.b Dn, (d8, PC, Xn)
op( calc_action_for_mode(mode) | MicroOp::DestinationMask,
seq(pseq("np nrd np", mode), { ea(1) }, false));
op(Action::PerformOperation);
break;
case 0x10: // BTST.b Dn, (xxx).w
op( int(Action::AssembleWordAddressFromPrefetch) | MicroOp::DestinationMask,
seq("np nrd np", { ea(1) }, false));
op(Action::PerformOperation);
break;
case 0x11: // BTST.b Dn, (xxx).l
op(Action::None, seq("np"));
op( int(Action::AssembleLongWordAddressFromPrefetch) | MicroOp::DestinationMask,
seq("np nrd np", { ea(1) }, false));
op(Action::PerformOperation);
break;
}
} break;
case Decoder::BTSTIMM: {
storage_.instructions[instruction].source = &storage_.source_bus_data_[0];
storage_.instructions[instruction].set_destination(storage_, source_mode, source_register);
const int mode = combined_mode(source_mode, source_register);
switch(mode) {
default: continue;
case 0x00: // BTST.l #, Dn
operation = Operation::BTSTl;
op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np np n"));
op(Action::PerformOperation);
break;
case 0x02: // BTST.b #, (An)
case 0x03: // BTST.b #, (An)+
op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np nrd np", { &storage_.data_[source_register].full }, false));
op(Action::PerformOperation);
if(mode == 0x03) {
op(int(Action::Increment1) | MicroOp::DestinationMask);
}
break;
case 0x04: // BTST.b #, -(An)
op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np"));
op(int(Action::Decrement1) | MicroOp::DestinationMask, seq("n nrd np", { &storage_.data_[source_register].full }, false));
op(Action::PerformOperation);
break;
case 0x05: // BTST.b #, (d16, An)
case 0x06: // BTST.b #, (d8, An, Xn)
case 0x12: // BTST.b #, (d16, PC)
case 0x13: // BTST.b #, (d8, PC, Xn)
op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np"));
op( calc_action_for_mode(mode) | MicroOp::DestinationMask,
seq(pseq("np nrd np", mode), { ea(1) }, false));
op(Action::PerformOperation);
break;
case 0x10: // BTST.b #, (xxx).w
op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np"));
op( int(Action::AssembleWordAddressFromPrefetch) | MicroOp::DestinationMask,
seq("np nrd np", { ea(1) }, false));
op(Action::PerformOperation);
break;
case 0x11: // BTST.b #, (xxx).l
op(int(Action::AssembleWordDataFromPrefetch) | MicroOp::SourceMask, seq("np np"));
op( int(Action::AssembleLongWordAddressFromPrefetch) | MicroOp::DestinationMask,
seq("np nrd np", { ea(1) }, false));
op(Action::PerformOperation);
break;
}
} break;
// Decodes the format used by ABCD and SBCD.
case Decoder::Decimal: {
const int destination_register = (instruction >> 9) & 7;

View File

@ -57,8 +57,9 @@ class ProcessorStorage {
MOVEtoSR, MOVEfromSR,
CMPb, CMPw, CMPl,
BTSTb, BTSTl,
BRA, Bcc, JMP
BRA, Bcc, JMP,
};
/*!