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

Add enough wiring to consolidate failure on lazy handling of flags.

This commit is contained in:
Thomas Harte 2023-10-06 13:22:35 -04:00
parent 82f0cd790f
commit b6d000ac5e
4 changed files with 82 additions and 13 deletions

View File

@ -11,6 +11,7 @@
#include "../../../Numeric/Carry.hpp"
#include "../../../Numeric/RegisterSizes.hpp"
#include "../Interrupts.hpp"
namespace InstructionSet::x86 {
@ -108,7 +109,8 @@ inline void aad(CPU::RegisterPair16 &ax, uint8_t imm, Status &status) {
status.parity = status.zero = ax.halves.low;
}
inline void aam(CPU::RegisterPair16 &ax, uint8_t imm, Status &status) {
template <typename FlowControllerT>
inline void aam(CPU::RegisterPair16 &ax, uint8_t imm, Status &status, FlowControllerT &flow_controller) {
/*
tempAL AL;
AH tempAL / imm8; (* imm8 is set to 0AH for the AAD mnemonic *)
@ -121,12 +123,15 @@ inline void aam(CPU::RegisterPair16 &ax, uint8_t imm, Status &status) {
/*
If ... an immediate value of 0 is used, it will cause a #DE (divide error) exception.
*/
if(!imm) {
flow_controller.interrupt(Interrupt::DivideByZero);
return;
}
ax.halves.high = ax.halves.low / imm;
ax.halves.low = ax.halves.low % imm;
status.sign = ax.halves.low & 0x80;
status.parity = status.zero = ax.halves.low;
// TODO: #DE.
}
inline void aas(CPU::RegisterPair16 &ax, Status &status) {
@ -303,13 +308,13 @@ template <
default: return;
//assert(false);
case Operation::AAA: Primitive::aaa(registers.axp(), status); return;
case Operation::AAD: Primitive::aad(registers.axp(), instruction.operand(), status); return;
case Operation::AAM: Primitive::aam(registers.axp(), instruction.operand(), status); return;
case Operation::AAS: Primitive::aas(registers.axp(), status); return;
case Operation::AAA: Primitive::aaa(registers.axp(), status); return;
case Operation::AAD: Primitive::aad(registers.axp(), instruction.operand(), status); return;
case Operation::AAM: Primitive::aam(registers.axp(), instruction.operand(), status, flow_controller); return;
case Operation::AAS: Primitive::aas(registers.axp(), status); return;
case Operation::ADC: Primitive::adc(destination(), source(), status); break;
case Operation::ADD: Primitive::add(destination(), source(), status); break;
case Operation::ADC: Primitive::adc(destination(), source(), status); break;
case Operation::ADD: Primitive::add(destination(), source(), status); break;
}
// Write to memory if required to complete this operation.

View File

@ -0,0 +1,24 @@
//
// Interrupts.hpp
// Clock Signal
//
// Created by Thomas Harte on 06/10/2023.
// Copyright © 2023 Thomas Harte. All rights reserved.
//
#ifndef InstructionSets_M68k_Interrupts_h
#define InstructionSets_M68k_Interrupts_h
namespace InstructionSet::x86 {
enum Interrupt {
DivideByZero = 0,
SingleStep = 1,
NMI = 2,
OneByte = 3,
OnOverflow = 4,
};
}
#endif /* InstructionSets_M68k_Interrupts_h */

View File

@ -1129,6 +1129,7 @@
42437B342ACF02A9006DFED1 /* Status.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Status.hpp; sourceTree = "<group>"; };
42437B352ACF0AA2006DFED1 /* Perform.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Perform.hpp; sourceTree = "<group>"; };
42437B382ACF2798006DFED1 /* PerformImplementation.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = PerformImplementation.hpp; sourceTree = "<group>"; };
42437B392AD07465006DFED1 /* Interrupts.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Interrupts.hpp; sourceTree = "<group>"; };
4281572E2AA0334300E16AA1 /* Carry.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Carry.hpp; sourceTree = "<group>"; };
428168372A16C25C008ECD27 /* LineLayout.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = LineLayout.hpp; sourceTree = "<group>"; };
428168392A37AFB4008ECD27 /* DispatcherTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = DispatcherTests.mm; sourceTree = "<group>"; };
@ -5007,6 +5008,7 @@
42437B352ACF0AA2006DFED1 /* Perform.hpp */,
42437B342ACF02A9006DFED1 /* Status.hpp */,
42437B372ACF2798006DFED1 /* Implementation */,
42437B392AD07465006DFED1 /* Interrupts.hpp */,
);
path = x86;
sourceTree = "<group>";

View File

@ -27,6 +27,7 @@ namespace {
// provide their real path here.
constexpr char TestSuiteHome[] = "/Users/tharte/Projects/ProcessorTests/8088/v1";
using Status = InstructionSet::x86::Status;
struct Registers {
CPU::RegisterPair16 ax_;
uint8_t &al() { return ax_.halves.low; }
@ -97,15 +98,52 @@ struct Memory {
default: physical_address = registers_.ds_; break;
case Source::ES: physical_address = registers_.es_; break;
case Source::CS: physical_address = registers_.cs_; break;
case Source::DS: physical_address = registers_.ds_; break;
case Source::SS: physical_address = registers_.ss_; break;
}
physical_address = ((physical_address << 4) + address) & 0xf'ffff;
return *reinterpret_cast<IntT *>(&memory[physical_address]);
return access<IntT>(physical_address);
}
template <typename IntT> IntT &access(uint32_t address) {
return *reinterpret_cast<IntT *>(&memory[address]);
}
};
struct IO {
};
struct FlowController {
class FlowController {
public:
FlowController(Memory &memory, Registers &registers, Status &status) :
memory_(memory), registers_(registers), status_(status) {}
void interrupt(int index) {
const uint16_t address = static_cast<uint16_t>(index) << 2;
const uint16_t new_ip = memory_.access<uint16_t>(address);
const uint16_t new_cs = memory_.access<uint16_t>(address + 2);
push(status_.get());
// TODO: set I and TF
// status_.
// Push CS and IP.
push(registers_.cs_);
push(registers_.ip_);
registers_.cs_ = new_cs;
registers_.ip_ = new_ip;
}
private:
Memory &memory_;
Registers &registers_;
Status status_;
void push(uint16_t value) {
--registers_.sp_;
memory_.access<uint8_t>(InstructionSet::x86::Source::SS, registers_.sp_) = value >> 8;
--registers_.sp_;
memory_.access<uint8_t>(InstructionSet::x86::Source::SS, registers_.sp_) = value & 0xff;
}
};
}
@ -275,9 +313,9 @@ struct FlowController {
const auto decoded = decoder.decode(data.data(), data.size());
InstructionSet::x86::Status status;
FlowController flow_controller;
Registers registers;
Memory memory(registers);
FlowController flow_controller(memory, registers, status);
IO io;
// Apply initial state.