mirror of
https://github.com/TomHarte/CLK.git
synced 2024-09-28 09:54:49 +00:00
Implement INS, OUTS.
This commit is contained in:
parent
aade91f043
commit
e3cdf113d1
@ -1460,6 +1460,32 @@ void stos(const InstructionT &instruction, AddressT &eCX, AddressT &eDI, IntT &e
|
|||||||
repeat<AddressT>(instruction, eCX, flow_controller);
|
repeat<AddressT>(instruction, eCX, flow_controller);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename IntT, typename AddressT, typename InstructionT, typename MemoryT, typename IOT, typename FlowControllerT>
|
||||||
|
void outs(const InstructionT &instruction, AddressT &eCX, uint16_t port, AddressT &eSI, MemoryT &memory, IOT &io, Status &status, FlowControllerT &flow_controller) {
|
||||||
|
if(repetition_over<AddressT>(instruction, eCX)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Source source_segment = instruction.segment_override();
|
||||||
|
if(source_segment == Source::None) source_segment = Source::DS;
|
||||||
|
io.template out<IntT>(port, memory.template access<IntT>(source_segment, eSI));
|
||||||
|
eSI += status.direction<AddressT>() * sizeof(IntT);
|
||||||
|
|
||||||
|
repeat<AddressT>(instruction, eCX, flow_controller);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename IntT, typename AddressT, typename InstructionT, typename MemoryT, typename IOT, typename FlowControllerT>
|
||||||
|
void ins(const InstructionT &instruction, AddressT &eCX, uint16_t port, AddressT &eDI, MemoryT &memory, IOT &io, Status &status, FlowControllerT &flow_controller) {
|
||||||
|
if(repetition_over<AddressT>(instruction, eCX)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
memory.template access<IntT>(Source::ES, eDI) = io.template in<IntT>(port);
|
||||||
|
eDI += status.direction<AddressT>() * sizeof(IntT);
|
||||||
|
|
||||||
|
repeat<AddressT>(instruction, eCX, flow_controller);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename IntT, typename IOT>
|
template <typename IntT, typename IOT>
|
||||||
void out(uint16_t port, IntT value, IOT &io) {
|
void out(uint16_t port, IntT value, IOT &io) {
|
||||||
io.template out<IntT>(port, value);
|
io.template out<IntT>(port, value);
|
||||||
@ -1571,6 +1597,14 @@ template <
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Gets the port for an IN or OUT; these are always 16-bit.
|
||||||
|
const auto port = [&](Source source) -> uint16_t {
|
||||||
|
switch(source) {
|
||||||
|
case Source::DirectAddress: return instruction.operand();
|
||||||
|
default: return registers.dx();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// Guide to the below:
|
// Guide to the below:
|
||||||
//
|
//
|
||||||
// * use hard-coded register names where appropriate;
|
// * use hard-coded register names where appropriate;
|
||||||
@ -1703,22 +1737,8 @@ template <
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case Operation::OUT: {
|
case Operation::OUT: Primitive::out(port(instruction.destination().source()), pair_low(), io); return;
|
||||||
uint16_t port;
|
case Operation::IN: Primitive::in(port(instruction.source().source()), pair_low(), io); return;
|
||||||
switch(instruction.destination().source()) {
|
|
||||||
case Source::DirectAddress: port = instruction.operand(); break;
|
|
||||||
default: port = registers.dx(); break;
|
|
||||||
}
|
|
||||||
Primitive::out(port, pair_low(), io);
|
|
||||||
} return;
|
|
||||||
case Operation::IN: {
|
|
||||||
uint16_t port;
|
|
||||||
switch(instruction.source().source()) {
|
|
||||||
case Source::DirectAddress: port = instruction.operand(); break;
|
|
||||||
default: port = registers.dx(); break;
|
|
||||||
}
|
|
||||||
Primitive::in(port, pair_low(), io);
|
|
||||||
} return;
|
|
||||||
|
|
||||||
case Operation::XLAT: Primitive::xlat<AddressT>(instruction, memory, registers); return;
|
case Operation::XLAT: Primitive::xlat<AddressT>(instruction, memory, registers); return;
|
||||||
|
|
||||||
@ -1742,6 +1762,12 @@ template <
|
|||||||
case Operation::SCAS:
|
case Operation::SCAS:
|
||||||
Primitive::scas<IntT, AddressT>(instruction, eCX(), eDI(), pair_low(), memory, status, flow_controller);
|
Primitive::scas<IntT, AddressT>(instruction, eCX(), eDI(), pair_low(), memory, status, flow_controller);
|
||||||
break;
|
break;
|
||||||
|
case Operation::OUTS:
|
||||||
|
Primitive::outs<IntT, AddressT>(instruction, eCX(), registers.dx(), eSI(), memory, io, status, flow_controller);
|
||||||
|
break;
|
||||||
|
case Operation::INS:
|
||||||
|
Primitive::outs<IntT, AddressT>(instruction, eCX(), registers.dx(), eDI(), memory, io, status, flow_controller);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write to memory if required to complete this operation.
|
// Write to memory if required to complete this operation.
|
||||||
|
@ -354,7 +354,7 @@ struct FailedExecution {
|
|||||||
@"4C.json.gz", @"4D.json.gz", @"4E.json.gz", @"4F.json.gz",
|
@"4C.json.gz", @"4D.json.gz", @"4E.json.gz", @"4F.json.gz",
|
||||||
@"FE.1.json.gz",
|
@"FE.1.json.gz",
|
||||||
@"FF.1.json.gz",
|
@"FF.1.json.gz",
|
||||||
*/
|
|
||||||
// OUT
|
// OUT
|
||||||
@"E6.json.gz", @"E7.json.gz",
|
@"E6.json.gz", @"E7.json.gz",
|
||||||
@"EE.json.gz", @"EF.json.gz",
|
@"EE.json.gz", @"EF.json.gz",
|
||||||
@ -362,7 +362,7 @@ struct FailedExecution {
|
|||||||
// IN
|
// IN
|
||||||
@"E4.json.gz", @"E5.json.gz",
|
@"E4.json.gz", @"E5.json.gz",
|
||||||
@"EC.json.gz", @"ED.json.gz",
|
@"EC.json.gz", @"ED.json.gz",
|
||||||
/*
|
|
||||||
@"70.json.gz", // JO
|
@"70.json.gz", // JO
|
||||||
@"71.json.gz", // JNO
|
@"71.json.gz", // JNO
|
||||||
@"72.json.gz", // JB
|
@"72.json.gz", // JB
|
||||||
@ -423,9 +423,13 @@ struct FailedExecution {
|
|||||||
|
|
||||||
// SCAS
|
// SCAS
|
||||||
@"AE.json.gz", @"AF.json.gz",
|
@"AE.json.gz", @"AF.json.gz",
|
||||||
|
*/
|
||||||
|
// OUTS
|
||||||
|
@"6E.json.gz", @"6F.json.gz",
|
||||||
|
|
||||||
// TODO: INS, OUTS
|
// INS
|
||||||
|
@"6C.json.gz", @"6D.json.gz",
|
||||||
|
/*
|
||||||
@"E0.json.gz", // LOOPNE
|
@"E0.json.gz", // LOOPNE
|
||||||
@"E1.json.gz", // LOOPE
|
@"E1.json.gz", // LOOPE
|
||||||
@"E2.json.gz", // LOOP
|
@"E2.json.gz", // LOOP
|
||||||
|
Loading…
Reference in New Issue
Block a user