1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-07-04 18:29:40 +00:00

Improve error reporting, remove some dead TODOs.

This commit is contained in:
Thomas Harte 2023-10-20 17:00:32 -04:00
parent a71db54212
commit 49ac2d8e0c
2 changed files with 37 additions and 23 deletions

View File

@ -1489,8 +1489,7 @@ template <
else if constexpr (data_size == DataSize::DWord) return registers.eax();
};
// For the string versions, evaluate to either SI and DI or ESI and EDI, depending on the address size.
// [TODO on the latter].
// For the string operations, evaluate to either SI and DI or ESI and EDI, depending on the address size.
const auto eSI = [&]() -> AddressT& {
if constexpr (std::is_same_v<AddressT, uint16_t>) {
return registers.si();
@ -1506,6 +1505,15 @@ template <
}
};
// For counts, provide either eCX or CX depending on address size.
const auto eCX = [&]() -> AddressT& {
if constexpr (std::is_same_v<AddressT, uint16_t>) {
return registers.cx();
} else {
return registers.ecx();
}
};
// Guide to the below:
//
// * use hard-coded register names where appropriate;
@ -1566,11 +1574,10 @@ template <
case Operation::JMPabs: Primitive::jump_absolute(destination(), flow_controller); return;
case Operation::JMPfar: Primitive::jump_far<model>(instruction, flow_controller, registers, memory); return;
// TODO: use ECX rather than CX for all of below if address size is 32-bit.
case Operation::JCXZ: jcc(!registers.cx()); return;
case Operation::LOOP: Primitive::loop(registers.cx(), instruction.offset(), registers, flow_controller); return;
case Operation::LOOPE: Primitive::loope(registers.cx(), instruction.offset(), registers, status, flow_controller); return;
case Operation::LOOPNE: Primitive::loopne(registers.cx(), instruction.offset(), registers, status, flow_controller); return;
case Operation::JCXZ: jcc(!eCX()); return;
case Operation::LOOP: Primitive::loop(eCX(), instruction.offset(), registers, flow_controller); return;
case Operation::LOOPE: Primitive::loope(eCX(), instruction.offset(), registers, status, flow_controller); return;
case Operation::LOOPNE: Primitive::loopne(eCX(), instruction.offset(), registers, status, flow_controller); return;
case Operation::IRET: Primitive::iret(registers, flow_controller, memory, status); return;
case Operation::RETnear: Primitive::ret_near(instruction, registers, flow_controller, memory); return;
@ -1639,16 +1646,15 @@ template <
}
return;
case Operation::XLAT: Primitive::xlat<uint16_t>(instruction, memory, registers); return;
case Operation::XLAT: Primitive::xlat<AddressT>(instruction, memory, registers); return;
case Operation::POP: source() = Primitive::pop<IntT>(memory, registers); break;
case Operation::PUSH: Primitive::push<IntT>(source(), memory, registers); break;
case Operation::POPF: Primitive::popf(memory, registers, status); break;
case Operation::PUSHF: Primitive::pushf(memory, registers, status); break;
// TODO: don't assume address size below.
case Operation::CMPS:
Primitive::cmps<IntT, uint16_t>(instruction, eSI(), eDI(), memory, registers, status, flow_controller);
Primitive::cmps<IntT, AddressT>(instruction, eSI(), eDI(), memory, registers, status, flow_controller);
break;
}

View File

@ -769,19 +769,27 @@ struct FailedExecution {
}
if(!registersEqual) {
NSMutableArray<NSString *> *registers = [[NSMutableArray alloc] init];
if(intended_registers.ax() != execution_support.registers.ax()) [registers addObject:@"ax"];
if(intended_registers.cx() != execution_support.registers.cx()) [registers addObject:@"cx"];
if(intended_registers.dx() != execution_support.registers.dx()) [registers addObject:@"dx"];
if(intended_registers.bx() != execution_support.registers.bx()) [registers addObject:@"bx"];
if(intended_registers.sp() != execution_support.registers.sp()) [registers addObject:@"sp"];
if(intended_registers.bp() != execution_support.registers.bp()) [registers addObject:@"bp"];
if(intended_registers.si() != execution_support.registers.si()) [registers addObject:@"si"];
if(intended_registers.di() != execution_support.registers.di()) [registers addObject:@"di"];
if(intended_registers.ip() != execution_support.registers.ip()) [registers addObject:@"ip"];
if(intended_registers.es() != execution_support.registers.es()) [registers addObject:@"es"];
if(intended_registers.cs() != execution_support.registers.cs()) [registers addObject:@"cs"];
if(intended_registers.ds() != execution_support.registers.ds()) [registers addObject:@"ds"];
if(intended_registers.ss() != execution_support.registers.ss()) [registers addObject:@"ss"];
#define Reg(x) \
if(intended_registers.x() != execution_support.registers.x()) \
[registers addObject: \
[NSString stringWithFormat: \
@#x" is %04x rather than %04x", execution_support.registers.x(), intended_registers.x()]];
Reg(ax);
Reg(cx);
Reg(dx);
Reg(bx);
Reg(sp);
Reg(bp);
Reg(si);
Reg(di);
Reg(ip);
Reg(es);
Reg(cs);
Reg(ds);
Reg(ss);
#undef Reg
[reasons addObject:[NSString stringWithFormat:
@"registers don't match: %@", [registers componentsJoinedByString:@", "]
]];