1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-06-25 18:30:07 +00:00

Implement INS, OUTS.

This commit is contained in:
Thomas Harte 2023-10-21 22:52:50 -04:00
parent aade91f043
commit e3cdf113d1
2 changed files with 50 additions and 20 deletions

View File

@ -1460,6 +1460,32 @@ void stos(const InstructionT &instruction, AddressT &eCX, AddressT &eDI, IntT &e
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>
void out(uint16_t port, IntT value, IOT &io) {
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:
//
// * use hard-coded register names where appropriate;
@ -1703,22 +1737,8 @@ template <
}
return;
case Operation::OUT: {
uint16_t port;
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::OUT: Primitive::out(port(instruction.destination().source()), pair_low(), io); return;
case Operation::IN: Primitive::in(port(instruction.source().source()), pair_low(), io); return;
case Operation::XLAT: Primitive::xlat<AddressT>(instruction, memory, registers); return;
@ -1742,6 +1762,12 @@ template <
case Operation::SCAS:
Primitive::scas<IntT, AddressT>(instruction, eCX(), eDI(), pair_low(), memory, status, flow_controller);
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.

View File

@ -354,7 +354,7 @@ struct FailedExecution {
@"4C.json.gz", @"4D.json.gz", @"4E.json.gz", @"4F.json.gz",
@"FE.1.json.gz",
@"FF.1.json.gz",
*/
// OUT
@"E6.json.gz", @"E7.json.gz",
@"EE.json.gz", @"EF.json.gz",
@ -362,7 +362,7 @@ struct FailedExecution {
// IN
@"E4.json.gz", @"E5.json.gz",
@"EC.json.gz", @"ED.json.gz",
/*
@"70.json.gz", // JO
@"71.json.gz", // JNO
@"72.json.gz", // JB
@ -423,9 +423,13 @@ struct FailedExecution {
// SCAS
@"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
@"E1.json.gz", // LOOPE
@"E2.json.gz", // LOOP