diff --git a/InstructionSets/x86/Decoder.cpp b/InstructionSets/x86/Decoder.cpp index 6b8ccf718..50b5c0d6b 100644 --- a/InstructionSets/x86/Decoder.cpp +++ b/InstructionSets/x86/Decoder.cpp @@ -26,8 +26,8 @@ std::pair::InstructionT> Decoder::decode(con // be back to wherever it started, so it's safe to spit out a NOP and reset parsing // without any loss of context. This reduces the risk of the decoder tricking a caller into // an infinite loop. - static constexpr std::size_t max_instruction_length = model >= Model::i80386 ? 15 : (model == Model::i80286 ? 10 : 65536); - const uint8_t *const end = source + std::min(length, max_instruction_length - consumed_); + static constexpr int max_instruction_length = model >= Model::i80386 ? 15 : (model == Model::i80286 ? 10 : 65536); + const uint8_t *const end = source + std::min(length, size_t(max_instruction_length - consumed_)); // MARK: - Prefixes (if present) and the opcode. diff --git a/InstructionSets/x86/Decoder.hpp b/InstructionSets/x86/Decoder.hpp index 47ea4e6e2..7ca9bcc3e 100644 --- a/InstructionSets/x86/Decoder.hpp +++ b/InstructionSets/x86/Decoder.hpp @@ -172,7 +172,7 @@ template class Decoder { // Ephemeral decoding state. Operation operation_ = Operation::Invalid; - uint32_t consumed_ = 0, operand_bytes_ = 0; + int consumed_ = 0, operand_bytes_ = 0; // Source and destination locations. Source source_ = Source::None; diff --git a/InstructionSets/x86/Implementation/FlowControl.hpp b/InstructionSets/x86/Implementation/FlowControl.hpp index 63965cde6..a8be5cb53 100644 --- a/InstructionSets/x86/Implementation/FlowControl.hpp +++ b/InstructionSets/x86/Implementation/FlowControl.hpp @@ -36,7 +36,7 @@ void jump( // TODO: proper behaviour in 32-bit. if(condition) { - context.flow_controller.jump(uint16_t(context.registers.ip() + displacement)); + context.flow_controller.template jump(uint16_t(context.registers.ip() + displacement)); } } @@ -48,7 +48,7 @@ void loop( ) { --counter; if(counter) { - context.flow_controller.jump(context.registers.ip() + displacement); + context.flow_controller.template jump(context.registers.ip() + displacement); } } @@ -60,7 +60,7 @@ void loope( ) { --counter; if(counter && context.flags.template flag()) { - context.flow_controller.jump(context.registers.ip() + displacement); + context.flow_controller.template jump(context.registers.ip() + displacement); } } @@ -72,26 +72,30 @@ void loopne( ) { --counter; if(counter && !context.flags.template flag()) { - context.flow_controller.jump(context.registers.ip() + displacement); + context.flow_controller.template jump(context.registers.ip() + displacement); } } -template +template void call_relative( - typename std::make_signed::type offset, + typename std::make_signed::type offset, ContextT &context ) { - push(context.registers.ip(), context); - context.flow_controller.jump(context.registers.ip() + offset); + if constexpr (std::is_same_v) { + push(context.registers.ip(), context); + context.flow_controller.template jump(AddressT(context.registers.ip() + offset)); + } else { + assert(false); + } } -template +template void call_absolute( read_t target, ContextT &context ) { push(context.registers.ip(), context); - context.flow_controller.jump(target); + context.flow_controller.template jump(AddressT(target)); } template @@ -99,10 +103,10 @@ void jump_absolute( read_t target, ContextT &context ) { - context.flow_controller.jump(target); + context.flow_controller.template jump(target); } -template +template void call_far( InstructionT &instruction, ContextT &context @@ -118,17 +122,17 @@ void call_far( case Source::Immediate: push(context.registers.cs(), context); push(context.registers.ip(), context); - context.flow_controller.jump(instruction.segment(), instruction.offset()); + context.flow_controller.template jump(instruction.segment(), instruction.offset()); return; case Source::Indirect: - source_address = address(instruction, pointer, context); + source_address = uint16_t(address(instruction, pointer, context)); break; case Source::IndirectNoBase: - source_address = address(instruction, pointer, context); + source_address = uint16_t(address(instruction, pointer, context)); break; case Source::DirectAddress: - source_address = address(instruction, pointer, context); + source_address = uint16_t(address(instruction, pointer, context)); break; } @@ -141,7 +145,7 @@ void call_far( push(context.registers.cs(), context); push(context.registers.ip(), context); - context.flow_controller.jump(segment, offset); + context.flow_controller.template jump(segment, offset); } template @@ -154,16 +158,16 @@ void jump_far( const auto pointer = instruction.destination(); switch(pointer.source()) { default: - case Source::Immediate: context.flow_controller.jump(instruction.segment(), instruction.offset()); return; + case Source::Immediate: context.flow_controller.template jump(instruction.segment(), instruction.offset()); return; case Source::Indirect: - source_address = address(instruction, pointer, context); + source_address = uint16_t(address(instruction, pointer, context)); break; case Source::IndirectNoBase: - source_address = address(instruction, pointer, context); + source_address = uint16_t(address(instruction, pointer, context)); break; case Source::DirectAddress: - source_address = address(instruction, pointer, context); + source_address = uint16_t(address(instruction, pointer, context)); break; } @@ -173,7 +177,7 @@ void jump_far( const uint16_t offset = context.memory.template access(source_segment, source_address); source_address += 2; const uint16_t segment = context.memory.template access(source_segment, source_address); - context.flow_controller.jump(segment, offset); + context.flow_controller.template jump(segment, offset); } template @@ -185,7 +189,7 @@ void iret( const auto ip = pop(context); const auto cs = pop(context); context.flags.set(pop(context)); - context.flow_controller.jump(cs, ip); + context.flow_controller.template jump(cs, ip); } template @@ -195,7 +199,7 @@ void ret_near( ) { const auto ip = pop(context); context.registers.sp() += instruction.operand(); - context.flow_controller.jump(ip); + context.flow_controller.template jump(ip); } template @@ -207,7 +211,7 @@ void ret_far( const auto ip = pop(context); const auto cs = pop(context); context.registers.sp() += instruction.operand(); - context.flow_controller.jump(cs, ip); + context.flow_controller.template jump(cs, ip); } template diff --git a/InstructionSets/x86/Implementation/LoadStore.hpp b/InstructionSets/x86/Implementation/LoadStore.hpp index fc05fbb81..6c916b759 100644 --- a/InstructionSets/x86/Implementation/LoadStore.hpp +++ b/InstructionSets/x86/Implementation/LoadStore.hpp @@ -35,7 +35,7 @@ void ld( ContextT &context ) { const auto pointer = instruction.source(); - auto source_address = address(instruction, pointer, context); + uint16_t source_address = uint16_t(address(instruction, pointer, context)); const Source source_segment = instruction.data_segment(); context.memory.preauthorise_read(source_segment, source_address, 4); diff --git a/InstructionSets/x86/Implementation/Logical.hpp b/InstructionSets/x86/Implementation/Logical.hpp index 74c7816ba..3095ad61f 100644 --- a/InstructionSets/x86/Implementation/Logical.hpp +++ b/InstructionSets/x86/Implementation/Logical.hpp @@ -136,7 +136,7 @@ void setmo( write_t destination, ContextT &context ) { - const auto result = destination = ~0; + const auto result = destination = IntT(~0); context.flags.template set_from(0); context.flags.template set_from(result); } diff --git a/InstructionSets/x86/Implementation/PerformImplementation.hpp b/InstructionSets/x86/Implementation/PerformImplementation.hpp index d0d034801..6c65c7cae 100644 --- a/InstructionSets/x86/Implementation/PerformImplementation.hpp +++ b/InstructionSets/x86/Implementation/PerformImplementation.hpp @@ -237,8 +237,8 @@ template < case Operation::CALLrel: Primitive::call_relative(instruction.displacement(), context); return; - case Operation::CALLabs: Primitive::call_absolute(destination_r(), context); return; - case Operation::CALLfar: Primitive::call_far(instruction, context); return; + case Operation::CALLabs: Primitive::call_absolute(destination_r(), context); return; + case Operation::CALLfar: Primitive::call_far(instruction, context); return; case Operation::JMPrel: jcc(true); return; case Operation::JMPabs: Primitive::jump_absolute(destination_r(), context); return; diff --git a/InstructionSets/x86/Implementation/Resolver.hpp b/InstructionSets/x86/Implementation/Resolver.hpp index f64239d6b..23e23d9c2 100644 --- a/InstructionSets/x86/Implementation/Resolver.hpp +++ b/InstructionSets/x86/Implementation/Resolver.hpp @@ -199,7 +199,9 @@ typename Accessor::type resolve( // If execution has reached here then a memory fetch is required. // Do it and exit. - return context.memory.template access(instruction.data_segment(), target_address); + // + // TODO: support 32-bit addresses. + return context.memory.template access(instruction.data_segment(), uint16_t(target_address)); } } diff --git a/Machines/PCCompatible/PCCompatible.cpp b/Machines/PCCompatible/PCCompatible.cpp index dd0cb875e..c0ce68025 100644 --- a/Machines/PCCompatible/PCCompatible.cpp +++ b/Machines/PCCompatible/PCCompatible.cpp @@ -807,11 +807,15 @@ class FlowController { registers_(registers), segments_(segments) {} // Requirements for perform. - void jump(uint16_t address) { + template + void jump(AddressT address) { + static_assert(std::is_same_v); registers_.ip() = address; } - void jump(uint16_t segment, uint16_t address) { + template + void jump(uint16_t segment, AddressT address) { + static_assert(std::is_same_v); registers_.cs() = segment; segments_.did_update(Segments::Source::CS); registers_.ip() = address; @@ -916,7 +920,7 @@ class ConcreteMachine: // MARK: - TimedMachine. void run_for(const Cycles duration) override { - const auto pit_ticks = duration.as_integral(); + const auto pit_ticks = duration.as(); int ticks; if constexpr (!turbo) { diff --git a/OSBindings/Mac/Clock SignalTests/8088Tests.mm b/OSBindings/Mac/Clock SignalTests/8088Tests.mm index adffeecd0..ed1c4e35d 100644 --- a/OSBindings/Mac/Clock SignalTests/8088Tests.mm +++ b/OSBindings/Mac/Clock SignalTests/8088Tests.mm @@ -371,11 +371,15 @@ class FlowController { registers_(registers), segments_(segments) {} // Requirements for perform. - void jump(uint16_t address) { + template + void jump(AddressT address) { + static_assert(std::is_same_v); registers_.ip() = address; } - void jump(uint16_t segment, uint16_t address) { + template + void jump(uint16_t segment, AddressT address) { + static_assert(std::is_same_v); registers_.cs() = segment; segments_.did_update(Segments::Source::CS); registers_.ip() = address;