mirror of
https://github.com/TomHarte/CLK.git
synced 2025-03-25 06:30:38 +00:00
Tidy up and comment a little further.
This commit is contained in:
parent
9566a8de67
commit
d7bb1a9ee1
InstructionSets/x86/Implementation
@ -16,7 +16,10 @@
|
||||
namespace InstructionSet::x86::Primitive {
|
||||
|
||||
template <typename ContextT>
|
||||
void aaa(CPU::RegisterPair16 &ax, ContextT &context) { // P. 313
|
||||
void aaa(
|
||||
CPU::RegisterPair16 &ax,
|
||||
ContextT &context
|
||||
) { // P. 313
|
||||
/*
|
||||
IF ((AL AND 0FH) > 9) OR (AF = 1)
|
||||
THEN
|
||||
@ -45,7 +48,11 @@ void aaa(CPU::RegisterPair16 &ax, ContextT &context) { // P. 313
|
||||
}
|
||||
|
||||
template <typename ContextT>
|
||||
void aad(CPU::RegisterPair16 &ax, uint8_t imm, ContextT &context) {
|
||||
void aad(
|
||||
CPU::RegisterPair16 &ax,
|
||||
uint8_t imm,
|
||||
ContextT &context
|
||||
) {
|
||||
/*
|
||||
tempAL ← AL;
|
||||
tempAH ← AH;
|
||||
@ -62,7 +69,11 @@ void aad(CPU::RegisterPair16 &ax, uint8_t imm, ContextT &context) {
|
||||
}
|
||||
|
||||
template <typename ContextT>
|
||||
void aam(CPU::RegisterPair16 &ax, uint8_t imm, ContextT &context) {
|
||||
void aam(
|
||||
CPU::RegisterPair16 &ax,
|
||||
uint8_t imm,
|
||||
ContextT &context
|
||||
) {
|
||||
/*
|
||||
tempAL ← AL;
|
||||
AH ← tempAL / imm8; (* imm8 is set to 0AH for the AAD mnemonic *)
|
||||
@ -86,7 +97,10 @@ void aam(CPU::RegisterPair16 &ax, uint8_t imm, ContextT &context) {
|
||||
}
|
||||
|
||||
template <typename ContextT>
|
||||
void aas(CPU::RegisterPair16 &ax, ContextT &context) {
|
||||
void aas(
|
||||
CPU::RegisterPair16 &ax,
|
||||
ContextT &context
|
||||
) {
|
||||
/*
|
||||
IF ((AL AND 0FH) > 9) OR (AF = 1)
|
||||
THEN
|
||||
@ -115,7 +129,10 @@ void aas(CPU::RegisterPair16 &ax, ContextT &context) {
|
||||
}
|
||||
|
||||
template <typename ContextT>
|
||||
void daa(uint8_t &al, ContextT &context) {
|
||||
void daa(
|
||||
uint8_t &al,
|
||||
ContextT &context
|
||||
) {
|
||||
/*
|
||||
(as modified by https://www.felixcloutier.com/x86/daa ...)
|
||||
|
||||
@ -167,7 +184,10 @@ void daa(uint8_t &al, ContextT &context) {
|
||||
}
|
||||
|
||||
template <typename ContextT>
|
||||
void das(uint8_t &al, ContextT &context) {
|
||||
void das(
|
||||
uint8_t &al,
|
||||
ContextT &context
|
||||
) {
|
||||
/*
|
||||
(as modified by https://www.felixcloutier.com/x86/daa ...)
|
||||
|
||||
|
@ -165,13 +165,16 @@ template <
|
||||
|
||||
// Guide to the below:
|
||||
//
|
||||
// * use hard-coded register names where appropriate;
|
||||
// * use hard-coded register names where appropriate, otherwise use the source_X() and destination_X() lambdas;
|
||||
// * return directly if there is definitely no possible write back to RAM;
|
||||
// * otherwise use the source() and destination() lambdas, and break in order to allow a writeback if necessary.
|
||||
// * break if there's a chance of writeback.
|
||||
switch(instruction.operation()) {
|
||||
default:
|
||||
assert(false);
|
||||
|
||||
case Operation::ESC:
|
||||
case Operation::NOP: return;
|
||||
|
||||
case Operation::AAA: Primitive::aaa(context.registers.axp(), context); return;
|
||||
case Operation::AAD: Primitive::aad(context.registers.axp(), instruction.operand(), context); return;
|
||||
case Operation::AAM: Primitive::aam(context.registers.axp(), instruction.operand(), context); return;
|
||||
@ -182,14 +185,15 @@ template <
|
||||
case Operation::CBW: Primitive::cbw(pair_low()); return;
|
||||
case Operation::CWD: Primitive::cwd(pair_high(), pair_low()); return;
|
||||
|
||||
case Operation::ESC:
|
||||
case Operation::NOP: return;
|
||||
|
||||
case Operation::HLT: context.flow_controller.halt(); return;
|
||||
case Operation::WAIT: context.flow_controller.wait(); return;
|
||||
|
||||
case Operation::ADC: Primitive::add<true, IntT>(destination_rmw(), source_r(), context); break;
|
||||
case Operation::ADD: Primitive::add<false, IntT>(destination_rmw(), source_r(), context); break;
|
||||
case Operation::ADC:
|
||||
Primitive::add<true, IntT>(destination_rmw(), source_r(), context);
|
||||
break;
|
||||
case Operation::ADD:
|
||||
Primitive::add<false, IntT>(destination_rmw(), source_r(), context);
|
||||
break;
|
||||
case Operation::SBB:
|
||||
Primitive::sub<true, AccessType::ReadModifyWrite, IntT>(destination_rmw(), source_r(), context);
|
||||
break;
|
||||
@ -199,7 +203,9 @@ template <
|
||||
case Operation::CMP:
|
||||
Primitive::sub<false, AccessType::Read, IntT>(destination_r(), source_r(), context);
|
||||
return;
|
||||
case Operation::TEST: Primitive::test<IntT>(destination_r(), source_r(), context); return;
|
||||
case Operation::TEST:
|
||||
Primitive::test<IntT>(destination_r(), source_r(), context);
|
||||
return;
|
||||
|
||||
case Operation::MUL: Primitive::mul<IntT>(pair_high(), pair_low(), source_r(), context); return;
|
||||
case Operation::IMUL_1: Primitive::imul<IntT>(pair_high(), pair_low(), source_r(), context); return;
|
||||
@ -238,8 +244,12 @@ template <
|
||||
case Operation::SAHF: Primitive::sahf(context.registers.ah(), context); return;
|
||||
case Operation::LAHF: Primitive::lahf(context.registers.ah(), context); return;
|
||||
|
||||
case Operation::LDS: if constexpr (data_size == DataSize::Word) Primitive::ld<Source::DS>(instruction, destination_w(), context); return;
|
||||
case Operation::LES: if constexpr (data_size == DataSize::Word) Primitive::ld<Source::ES>(instruction, destination_w(), context); return;
|
||||
case Operation::LDS:
|
||||
if constexpr (data_size == DataSize::Word) Primitive::ld<Source::DS>(instruction, destination_w(), context);
|
||||
return;
|
||||
case Operation::LES:
|
||||
if constexpr (data_size == DataSize::Word) Primitive::ld<Source::ES>(instruction, destination_w(), context);
|
||||
return;
|
||||
|
||||
case Operation::LEA: Primitive::lea<IntT>(instruction, destination_w(), context); return;
|
||||
case Operation::MOV: Primitive::mov<IntT>(destination_w(), source_r()); break;
|
||||
@ -285,7 +295,8 @@ template <
|
||||
Primitive::setmo<IntT>(destination_w(), context);
|
||||
break;
|
||||
} else {
|
||||
// TODO.
|
||||
// TODO: perform ENTER as of the 80186.
|
||||
static_assert(int(Operation::SETMO) == int(Operation::ENTER));
|
||||
}
|
||||
return;
|
||||
case Operation::SETMOC:
|
||||
@ -297,12 +308,13 @@ template <
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
// TODO.
|
||||
// TODO: perform BOUND as of the 80186.
|
||||
static_assert(int(Operation::SETMOC) == int(Operation::BOUND));
|
||||
}
|
||||
return;
|
||||
|
||||
case Operation::OUT: Primitive::out<IntT>(port(instruction.destination().source()), pair_low(), context); return;
|
||||
case Operation::IN: Primitive::in<IntT>(port(instruction.source().source()), pair_low(), context); return;
|
||||
case Operation::IN: Primitive::in<IntT>(port(instruction.source().source()), pair_low(), context); return;
|
||||
|
||||
case Operation::XLAT: Primitive::xlat<AddressT>(instruction, context); return;
|
||||
|
||||
@ -372,10 +384,19 @@ template <
|
||||
|
||||
// Write to memory if required to complete this operation.
|
||||
//
|
||||
// TODO: can I eliminate this with some RAII magic?
|
||||
// This is not currently handled via RAII because of the amount of context that would need to place onto the stack;
|
||||
// instead code has been set up to make sure there is only at most one writeable target on loan for potential
|
||||
// write back. I might flip-flop on this, especially if I can verify whether extra stack context is easily
|
||||
// optimised out.
|
||||
context.memory.template write_back<IntT>();
|
||||
}
|
||||
|
||||
//
|
||||
// Public function; just a trampoline into a version of perform templated on data and address size.
|
||||
//
|
||||
// Which, yes, means there's an outer switch leading to an inner switch, which could be reduced to one big switch.
|
||||
// It'd be a substantial effort to find the most neat expression of that, I think, so it is not currently done.
|
||||
//
|
||||
template <
|
||||
typename InstructionT,
|
||||
typename ContextT
|
||||
|
Loading…
x
Reference in New Issue
Block a user