1
0
mirror of https://github.com/TomHarte/CLK.git synced 2025-02-18 01:30:56 +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(); 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. // For the string operations, evaluate to either SI and DI or ESI and EDI, depending on the address size.
// [TODO on the latter].
const auto eSI = [&]() -> AddressT& { const auto eSI = [&]() -> AddressT& {
if constexpr (std::is_same_v<AddressT, uint16_t>) { if constexpr (std::is_same_v<AddressT, uint16_t>) {
return registers.si(); 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: // Guide to the below:
// //
// * use hard-coded register names where appropriate; // * use hard-coded register names where appropriate;
@ -1566,11 +1574,10 @@ template <
case Operation::JMPabs: Primitive::jump_absolute(destination(), flow_controller); return; case Operation::JMPabs: Primitive::jump_absolute(destination(), flow_controller); return;
case Operation::JMPfar: Primitive::jump_far<model>(instruction, flow_controller, registers, memory); 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(!eCX()); return;
case Operation::JCXZ: jcc(!registers.cx()); return; case Operation::LOOP: Primitive::loop(eCX(), instruction.offset(), registers, flow_controller); return;
case Operation::LOOP: Primitive::loop(registers.cx(), instruction.offset(), registers, flow_controller); return; case Operation::LOOPE: Primitive::loope(eCX(), instruction.offset(), registers, status, flow_controller); return;
case Operation::LOOPE: Primitive::loope(registers.cx(), instruction.offset(), registers, status, flow_controller); return; case Operation::LOOPNE: Primitive::loopne(eCX(), instruction.offset(), registers, status, flow_controller); return;
case Operation::LOOPNE: Primitive::loopne(registers.cx(), instruction.offset(), registers, status, flow_controller); return;
case Operation::IRET: Primitive::iret(registers, flow_controller, memory, status); return; case Operation::IRET: Primitive::iret(registers, flow_controller, memory, status); return;
case Operation::RETnear: Primitive::ret_near(instruction, registers, flow_controller, memory); return; case Operation::RETnear: Primitive::ret_near(instruction, registers, flow_controller, memory); return;
@ -1639,16 +1646,15 @@ template <
} }
return; 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::POP: source() = Primitive::pop<IntT>(memory, registers); break;
case Operation::PUSH: Primitive::push<IntT>(source(), memory, registers); break; case Operation::PUSH: Primitive::push<IntT>(source(), memory, registers); break;
case Operation::POPF: Primitive::popf(memory, registers, status); break; case Operation::POPF: Primitive::popf(memory, registers, status); break;
case Operation::PUSHF: Primitive::pushf(memory, registers, status); break; case Operation::PUSHF: Primitive::pushf(memory, registers, status); break;
// TODO: don't assume address size below.
case Operation::CMPS: 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; break;
} }

View File

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