mirror of
https://github.com/TomHarte/CLK.git
synced 2025-01-11 08:30:55 +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);
|
||||
}
|
||||
|
||||
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.
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user