1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-09-29 16:55:59 +00:00

Better plans project layout.

This commit is contained in:
Thomas Harte 2021-01-15 18:16:01 -05:00
parent ca94e9038e
commit ddb4bb1421
10 changed files with 340 additions and 283 deletions

View File

@ -1,12 +1,12 @@
//
// PowerPC.cpp
// Decoder.cpp
// Clock Signal
//
// Created by Thomas Harte on 12/30/20.
// Copyright © 2020 Thomas Harte. All rights reserved.
//
#include "PowerPC.hpp"
#include "Decoder.hpp"
using namespace CPU::Decoder::PowerPC;

View File

@ -0,0 +1,58 @@
//
// Decoder.hpp
// Clock Signal
//
// Created by Thomas Harte on 12/30/20.
// Copyright © 2020 Thomas Harte. All rights reserved.
//
#ifndef InstructionSets_PowerPC_Decoder_hpp
#define InstructionSets_PowerPC_Decoder_hpp
#include "Instruction.hpp"
namespace CPU {
namespace Decoder {
namespace PowerPC {
enum class Model {
/// i.e. 32-bit, with POWER carry-over instructions.
MPC601,
/// i.e. 32-bit, no POWER instructions.
MPC603,
/// i.e. 64-bit.
MPC620,
};
/*!
Implements PowerPC instruction decoding.
This is an experimental implementation; it has not yet undergone significant testing.
*/
struct Decoder {
public:
Decoder(Model model);
Instruction decode(uint32_t opcode);
private:
Model model_;
bool is64bit() const {
return model_ == Model::MPC620;
}
bool is32bit() const {
return !is64bit();
}
bool is601() const {
return model_ == Model::MPC601;
}
};
}
}
}
#endif /* InstructionSets_PowerPC_Decoder_hpp */

View File

@ -1,30 +1,20 @@
//
// PowerPC.hpp
// Instruction.hpp
// Clock Signal
//
// Created by Thomas Harte on 12/30/20.
// Copyright © 2020 Thomas Harte. All rights reserved.
// Created by Thomas Harte on 1/15/21.
// Copyright © 2021 Thomas Harte. All rights reserved.
//
#ifndef PowerPC_hpp
#define PowerPC_hpp
#ifndef InstructionSets_PowerPC_Instruction_h
#define InstructionSets_PowerPC_Instruction_h
#include <cstddef>
#include <cstdint>
namespace CPU {
namespace Decoder {
namespace PowerPC {
enum class Model {
/// i.e. 32-bit, with POWER carry-over instructions.
MPC601,
/// i.e. 32-bit, no POWER instructions.
MPC603,
/// i.e. 64-bit.
MPC620,
};
enum class Operation: uint8_t {
Undefined,
@ -33,7 +23,7 @@ enum class Operation: uint8_t {
absx, clcs, divx, divsx, dozx, dozi, lscbxx, maskgx, maskirx, mulx,
nabsx, rlmix, rribx, slex, sleqx, sliqx, slliqx, sllqx, slqx,
sraiqx, sraqx, srex, sreax, sreqx, sriqx, srliqx, srlqx, srqx,
// 32- and 64-bit PowerPC instructions.
addx, addcx, addex, addi, addic, addic_, addis, addmex, addzex, andx,
andcx, andi_, andis_, bx, bcx, bcctrx, bclrx, cmp, cmpi, cmpl, cmpli,
@ -192,39 +182,11 @@ struct Instruction {
uint32_t oe() const { return opcode & 0x800; }
};
// Sanity check on Instruction size.
static_assert(sizeof(Instruction) <= 8);
/*!
Implements PowerPC instruction decoding.
This is an experimental implementation; it has not yet undergone significant testing.
*/
struct Decoder {
public:
Decoder(Model model);
Instruction decode(uint32_t opcode);
private:
Model model_;
bool is64bit() const {
return model_ == Model::MPC620;
}
bool is32bit() const {
return !is64bit();
}
bool is601() const {
return model_ == Model::MPC601;
}
};
}
}
}
#include <stdio.h>
#endif /* PowerPC_hpp */
#endif /* InstructionSets_PowerPC_Instruction_h */

View File

@ -1,24 +1,25 @@
# Decoders
# Instruction Sets
## Decoders
A decoder extracts fully-decoded instructions from a data stream for its associated architecture.
An instruction is 'fully-decoded' when an instance of a suitable struct or class has been created that can provide at least the instruction's length, and will usually also provide as relevant:
The meaning of 'fully-decoded' is flexible but it means that a caller can easily discern at least:
* the operation in use;
* its addressing mode; and
* relevant registers.
It will have access to the original data stream again before being asked to provide any immediate values associated with the instruction.
It may be assumed that callers will have access to the original data stream for immediate values, if it is sensible to do so.
In deciding what to expose, what to store ahead of time and what to obtain just-in-time a decoder should have an eye on three main potential types of consumer:
1. disassemblers;
2. instruction executors; and
3. bus-centric CPU emulators.
In deciding what to expose, what to store ahead of time and what to obtain just-in-time a decoder should have an eye on two principal consumers:
1. disassemblers; and
2. instruction executors.
The first of those is likely to decode an instruction, output it to somewhere, and then immediately forget about it.
It may also be reasonable to make allowances for bus-centric CPU emulators, but those will be tightly coupled to specific decoders so no general rules need apply.
The second may opt to cache the decoded forms of instructions to reduce recurrent costs, but will always be dealing with an actual instruction stream. The chance of caching means that decoded instructions should seek to be small; however it also implies that as much processing cost as is reasonable should be spent up-front.
Disassemblers are likely to decode an instruction, output it, and then immediately forget about it.
The third may use a decoder live (especially if the instruction stream is complicated, or instruction words are large) or may use one once ahead of time in order to build up internal tables related to abstract interpretation of operations. The first use suggests a further premium on speed, the second implies that 'fully-decoded' instructions shouldn't seek to collect all possible immediate values ahead of time whenever doing so is avoidable — as a reult of thumb, they will usually return an instruction as soon as its length is fully known.
Instruction executors may opt to cache decoded instructions to reduce recurrent costs, but will always be dealing with an actual instruction stream. The chance of caching means that decoded instructions should seek to be small. If helpful then a decoder might prefer to return a `std::pair` or similar of ephemeral information and stuff that it is meaningful to store.
## Likely Interfaces
@ -30,19 +31,21 @@ If the instructions are a fixed size, the decoder can provide what is functional
Instruction decode(word_type instruction) { ... }
For now I have preferred not to make this a simple constructor on `Instruction` because I'm reserving the option of switching to an ephemeral/permanent split in what's returned. More consideration needs to be applied here.
### Variable-size instruction words
If instructions are a variable size, the decoder should maintain internal state such that it can be provided with fragments of instructions until a full decoding has occurred.
If instructions are a variable size, the decoder should maintain internal state such that it can be provided with fragments of instructions until a full decoding has occurred — this avoids an assumption that all source bytes will always be laid out linearly in memory.
A sample interface:
Instruction decode(word_type *stream, size_t length) { ... }
std::pair<int, Instruction> decode(word_type *stream, size_t length) { ... }
The returned instruction has a size that is one of:
* a positive number, indicating a successful decoding that consumed that many `word_type`s; or
In this sample the returned pair provides an `int` size that is one of:
* a positive number, indicating a completed decoding that consumed that many `word_type`s; or
* a negative number, indicating the [negatived] minimum number of `word_type`s that the caller should try to get hold of before calling `decode` again.
A caller is permitted to react in any way it prefers to negative numbers; they're a hint potentially to reduce calling overhead only.
A caller is permitted to react in any way it prefers to negative numbers; they're a hint potentially to reduce calling overhead only. A size of `0` would be taken to have the same meaning as a size of `-1`.
## Tying Decoders into Instruction Executors

View File

@ -6,7 +6,7 @@
// Copyright © 2021 Thomas Harte. All rights reserved.
//
#include "x86.hpp"
#include "Decoder.hpp"
#include <algorithm>
#include <cassert>
@ -17,7 +17,7 @@ using namespace CPU::Decoder::x86;
// Only 8086 is suppoted for now.
Decoder::Decoder(Model) {}
std::pair<int, Instruction> Decoder::decode(const uint8_t *source, size_t length) {
std::pair<int, CPU::Decoder::x86::Instruction> Decoder::decode(const uint8_t *source, size_t length) {
const uint8_t *const end = source + length;
// MARK: - Prefixes (if present) and the opcode.

View File

@ -1,16 +1,17 @@
//
// x86.hpp
// Decoder.hpp
// Clock Signal
//
// Created by Thomas Harte on 1/1/21.
// Copyright © 2021 Thomas Harte. All rights reserved.
//
#ifndef x86_hpp
#define x86_hpp
#ifndef InstructionSets_x86_Decoder_hpp
#define InstructionSets_x86_Decoder_hpp
#include <cstddef>
#include <cstdint>
#include "Instruction.hpp"
#include <utility>
namespace CPU {
namespace Decoder {
@ -20,172 +21,6 @@ enum class Model {
i8086,
};
enum class Operation: uint8_t {
Invalid,
/// ASCII adjust after addition; source will be AL and destination will be AX.
AAA,
/// ASCII adjust before division; destination will be AX and source will be a multiplier.
AAD,
/// ASCII adjust after multiplication; destination will be AX and source will be a divider.
AAM,
/// ASCII adjust after subtraction; source will be AL and destination will be AX.
AAS,
/// Add with carry; source, destination, operand and displacement will be populated appropriately.
ADC,
/// Add; source, destination, operand and displacement will be populated appropriately.
ADD,
/// And; source, destination, operand and displacement will be populated appropriately.
AND,
/// Far call; see the segment() and offset() fields.
CALLF,
/// Displacement call; followed by a 16-bit operand providing a call offset.
CALLD,
/// Near call.
CALLN,
/// Convert byte into word; source will be AL, destination will be AH.
CBW,
/// Clear carry flag; no source or destination provided.
CLC,
/// Clear direction flag; no source or destination provided.
CLD,
/// Clear interrupt flag; no source or destination provided.
CLI,
/// Complement carry flag; no source or destination provided.
CMC,
/// Compare; source, destination, operand and displacement will be populated appropriately.
CMP,
/// Compare [bytes or words, per operation size]; source and destination implied to be DS:[SI] and ES:[DI].
CMPS,
/// Convert word to double word; source will be AX and destination will be DX.
CWD,
/// Decimal adjust after addition; source and destination will be AL.
DAA,
/// Decimal adjust after subtraction; source and destination will be AL.
DAS,
/// Dec; source, destination, operand and displacement will be populated appropriately.
DEC,
DIV, ESC, HLT, IDIV, IMUL, IN,
INC, INT, INT3, INTO, IRET,
JO, JNO, JB, JNB, JE, JNE, JBE, JNBE,
JS, JNS, JP, JNP, JL, JNL, JLE, JNLE,
JMPN,
JMPF,
JCXZ,
LAHF, LDS, LEA,
LODS, LOOPE, LOOPNE, MOV, MOVS, MUL, NEG, NOP, NOT, OR, OUT,
POP, POPF, PUSH, PUSHF, RCL, RCR, REP, ROL, ROR, SAHF,
SAR, SBB, SCAS, SAL, SHR, STC, STD, STI, STOS, SUB, TEST,
WAIT, XCHG, XLAT, XOR,
LES, LOOP, JPCX,
RETF,
RETN,
};
enum class Size: uint8_t {
Implied = 0,
Byte = 1,
Word = 2,
DWord = 4,
};
enum class Source: uint8_t {
None,
CS, DS, ES, SS,
AL, AH, AX,
BL, BH, BX,
CL, CH, CX,
DL, DH, DX,
SI, DI,
BP, SP,
IndBXPlusSI,
IndBXPlusDI,
IndBPPlusSI,
IndBPPlusDI,
IndSI,
IndDI,
DirectAddress,
IndBP,
IndBX,
Immediate
};
enum class Repetition: uint8_t {
None, RepE, RepNE
};
class Instruction {
public:
Operation operation = Operation::Invalid;
bool operator ==(const Instruction &rhs) const {
return
repetition_size_ == rhs.repetition_size_ &&
sources_ == rhs.sources_ &&
displacement_ == rhs.displacement_ &&
operand_ == rhs.operand_;
}
private:
// b0, b1: a Repetition;
// b2+: operation size.
uint8_t repetition_size_ = 0;
// b0b5: source;
// b6b11: destination;
// b12b14: segment override;
// b15: lock.
uint16_t sources_ = 0;
// Unpackable fields.
int16_t displacement_ = 0;
uint16_t operand_ = 0; // ... or used to store a segment for far operations.
public:
Source source() const { return Source(sources_ & 0x3f); }
Source destination() const { return Source((sources_ >> 6) & 0x3f); }
bool lock() const { return sources_ & 0x8000; }
Source segment_override() const { return Source((sources_ >> 12) & 7); }
Repetition repetition() const { return Repetition(repetition_size_ & 3); }
Size operation_size() const { return Size(repetition_size_ >> 2); }
uint16_t segment() const { return uint16_t(operand_); }
uint16_t offset() const { return uint16_t(displacement_); }
int16_t displacement() const { return displacement_; }
uint16_t operand() const { return operand_; }
Instruction() noexcept {}
Instruction(
Operation operation,
Source source,
Source destination,
bool lock,
Source segment_override,
Repetition repetition,
Size operation_size,
int16_t displacement,
uint16_t operand) noexcept :
operation(operation),
repetition_size_(uint8_t((int(operation_size) << 2) | int(repetition))),
sources_(uint16_t(
int(source) |
(int(destination) << 6) |
(int(segment_override) << 12) |
(int(lock) << 15)
)),
displacement_(displacement),
operand_(operand) {}
};
static_assert(sizeof(Instruction) <= 8);
/*!
Implements Intel x86 instruction decoding.
@ -318,4 +153,4 @@ struct Decoder {
}
}
#endif /* x86_hpp */
#endif /* InstructionSets_x86_Decoder_hpp */

View File

@ -0,0 +1,188 @@
//
// Instruction.hpp
// Clock Signal
//
// Created by Thomas Harte on 1/15/21.
// Copyright © 2021 Thomas Harte. All rights reserved.
//
#ifndef InstructionSets_x86_Instruction_h
#define InstructionSets_x86_Instruction_h
#include <cstdint>
namespace CPU {
namespace Decoder {
namespace x86 {
enum class Operation: uint8_t {
Invalid,
/// ASCII adjust after addition; source will be AL and destination will be AX.
AAA,
/// ASCII adjust before division; destination will be AX and source will be a multiplier.
AAD,
/// ASCII adjust after multiplication; destination will be AX and source will be a divider.
AAM,
/// ASCII adjust after subtraction; source will be AL and destination will be AX.
AAS,
/// Add with carry; source, destination, operand and displacement will be populated appropriately.
ADC,
/// Add; source, destination, operand and displacement will be populated appropriately.
ADD,
/// And; source, destination, operand and displacement will be populated appropriately.
AND,
/// Far call; see the segment() and offset() fields.
CALLF,
/// Displacement call; followed by a 16-bit operand providing a call offset.
CALLD,
/// Near call.
CALLN,
/// Convert byte into word; source will be AL, destination will be AH.
CBW,
/// Clear carry flag; no source or destination provided.
CLC,
/// Clear direction flag; no source or destination provided.
CLD,
/// Clear interrupt flag; no source or destination provided.
CLI,
/// Complement carry flag; no source or destination provided.
CMC,
/// Compare; source, destination, operand and displacement will be populated appropriately.
CMP,
/// Compare [bytes or words, per operation size]; source and destination implied to be DS:[SI] and ES:[DI].
CMPS,
/// Convert word to double word; source will be AX and destination will be DX.
CWD,
/// Decimal adjust after addition; source and destination will be AL.
DAA,
/// Decimal adjust after subtraction; source and destination will be AL.
DAS,
/// Dec; source, destination, operand and displacement will be populated appropriately.
DEC,
DIV, ESC, HLT, IDIV, IMUL, IN,
INC, INT, INT3, INTO, IRET,
JO, JNO, JB, JNB, JE, JNE, JBE, JNBE,
JS, JNS, JP, JNP, JL, JNL, JLE, JNLE,
JMPN,
JMPF,
JCXZ,
LAHF, LDS, LEA,
LODS, LOOPE, LOOPNE, MOV, MOVS, MUL, NEG, NOP, NOT, OR, OUT,
POP, POPF, PUSH, PUSHF, RCL, RCR, REP, ROL, ROR, SAHF,
SAR, SBB, SCAS, SAL, SHR, STC, STD, STI, STOS, SUB, TEST,
WAIT, XCHG, XLAT, XOR,
LES, LOOP, JPCX,
RETF,
RETN,
};
enum class Size: uint8_t {
Implied = 0,
Byte = 1,
Word = 2,
DWord = 4,
};
enum class Source: uint8_t {
None,
CS, DS, ES, SS,
AL, AH, AX,
BL, BH, BX,
CL, CH, CX,
DL, DH, DX,
SI, DI,
BP, SP,
IndBXPlusSI,
IndBXPlusDI,
IndBPPlusSI,
IndBPPlusDI,
IndSI,
IndDI,
DirectAddress,
IndBP,
IndBX,
Immediate
};
enum class Repetition: uint8_t {
None, RepE, RepNE
};
class Instruction {
public:
Operation operation = Operation::Invalid;
bool operator ==(const Instruction &rhs) const {
return
repetition_size_ == rhs.repetition_size_ &&
sources_ == rhs.sources_ &&
displacement_ == rhs.displacement_ &&
operand_ == rhs.operand_;
}
private:
// b0, b1: a Repetition;
// b2+: operation size.
uint8_t repetition_size_ = 0;
// b0b5: source;
// b6b11: destination;
// b12b14: segment override;
// b15: lock.
uint16_t sources_ = 0;
// Unpackable fields.
int16_t displacement_ = 0;
uint16_t operand_ = 0; // ... or used to store a segment for far operations.
public:
Source source() const { return Source(sources_ & 0x3f); }
Source destination() const { return Source((sources_ >> 6) & 0x3f); }
bool lock() const { return sources_ & 0x8000; }
Source segment_override() const { return Source((sources_ >> 12) & 7); }
Repetition repetition() const { return Repetition(repetition_size_ & 3); }
Size operation_size() const { return Size(repetition_size_ >> 2); }
uint16_t segment() const { return uint16_t(operand_); }
uint16_t offset() const { return uint16_t(displacement_); }
int16_t displacement() const { return displacement_; }
uint16_t operand() const { return operand_; }
Instruction() noexcept {}
Instruction(
Operation operation,
Source source,
Source destination,
bool lock,
Source segment_override,
Repetition repetition,
Size operation_size,
int16_t displacement,
uint16_t operand) noexcept :
operation(operation),
repetition_size_(uint8_t((int(operation_size) << 2) | int(repetition))),
sources_(uint16_t(
int(source) |
(int(destination) << 6) |
(int(segment_override) << 12) |
(int(lock) << 15)
)),
displacement_(displacement),
operand_(operand) {}
};
static_assert(sizeof(Instruction) <= 8);
}
}
}
#endif /* InstructionSets_x86_Instruction_h */

View File

@ -183,8 +183,6 @@
4B3BA0D01D318B44005DD7A7 /* MOS6532Bridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0CB1D318B44005DD7A7 /* MOS6532Bridge.mm */; };
4B3BA0D11D318B44005DD7A7 /* TestMachine6502.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BA0CD1D318B44005DD7A7 /* TestMachine6502.mm */; };
4B3BF5B01F146265005B6C36 /* CSW.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3BF5AE1F146264005B6C36 /* CSW.cpp */; };
4B3F76AE25A0196100178AEC /* x86.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3F76AD25A0196100178AEC /* x86.cpp */; };
4B3F76AF25A0196100178AEC /* x86.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3F76AD25A0196100178AEC /* x86.cpp */; };
4B3F76B925A1635300178AEC /* PowerPCDecoderTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B3F76B825A1635300178AEC /* PowerPCDecoderTests.mm */; };
4B3FCC40201EC24200960631 /* MultiMachine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3FCC3F201EC24200960631 /* MultiMachine.cpp */; };
4B3FE75E1F3CF68B00448EE4 /* CPM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3FE75C1F3CF68B00448EE4 /* CPM.cpp */; };
@ -847,8 +845,6 @@
4BDB61EB2032806E0048AF91 /* CSAtari2600.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B2A539A1D117D36003C6002 /* CSAtari2600.mm */; };
4BDB61EC203285AE0048AF91 /* Atari2600OptionsPanel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4B8FE21F1DA19D7C0090D3CE /* Atari2600OptionsPanel.swift */; };
4BDDBA991EF3451200347E61 /* Z80MachineCycleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BDDBA981EF3451200347E61 /* Z80MachineCycleTests.swift */; };
4BDDBBD7259D757800CEFF58 /* PowerPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BDDBBD5259D757800CEFF58 /* PowerPC.cpp */; };
4BDDBBD8259D757800CEFF58 /* PowerPC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BDDBBD5259D757800CEFF58 /* PowerPC.cpp */; };
4BE0A3EE237BB170002AB46F /* ST.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE0A3EC237BB170002AB46F /* ST.cpp */; };
4BE0A3EF237BB170002AB46F /* ST.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BE0A3EC237BB170002AB46F /* ST.cpp */; };
4BE211DE253E4E4800435408 /* 65C02_no_Rockwell_test.bin in Resources */ = {isa = PBXBuildFile; fileRef = 4BE211DD253E4E4800435408 /* 65C02_no_Rockwell_test.bin */; };
@ -862,13 +858,20 @@
4BEBFB4E2002C4BF000708CC /* MSXDSK.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEBFB4B2002C4BF000708CC /* MSXDSK.cpp */; };
4BEBFB512002DB30000708CC /* DiskROM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEBFB4F2002DB30000708CC /* DiskROM.cpp */; };
4BEBFB522002DB30000708CC /* DiskROM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEBFB4F2002DB30000708CC /* DiskROM.cpp */; };
4BEDA3BA25B25563000C2DBD /* Decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEDA3B425B25563000C2DBD /* Decoder.cpp */; };
4BEDA3BB25B25563000C2DBD /* Decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEDA3B425B25563000C2DBD /* Decoder.cpp */; };
4BEDA3BC25B25563000C2DBD /* Decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEDA3B425B25563000C2DBD /* Decoder.cpp */; };
4BEDA3BD25B25563000C2DBD /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 4BEDA3B625B25563000C2DBD /* README.md */; };
4BEDA3BE25B25563000C2DBD /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = 4BEDA3B625B25563000C2DBD /* README.md */; };
4BEDA3BF25B25563000C2DBD /* Decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEDA3B925B25563000C2DBD /* Decoder.cpp */; };
4BEDA3C025B25563000C2DBD /* Decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEDA3B925B25563000C2DBD /* Decoder.cpp */; };
4BEDA3C125B25563000C2DBD /* Decoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEDA3B925B25563000C2DBD /* Decoder.cpp */; };
4BEE0A6F1D72496600532C7B /* Cartridge.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEE0A6A1D72496600532C7B /* Cartridge.cpp */; };
4BEE0A701D72496600532C7B /* PRG.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEE0A6D1D72496600532C7B /* PRG.cpp */; };
4BEE149A227FC0EA00133682 /* IWM.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BEE1498227FC0EA00133682 /* IWM.cpp */; };
4BEE1EC022B5E236000A26A6 /* MacGCRTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BEE1EBF22B5E236000A26A6 /* MacGCRTests.mm */; };
4BEE1EC122B5E2FD000A26A6 /* Encoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4BD67DCE209BF27B00AB2146 /* Encoder.cpp */; };
4BEE4BD425A26E2B00011BD2 /* x86DecoderTests.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BEE4BD325A26E2B00011BD2 /* x86DecoderTests.mm */; };
4BEE4BE125A26F8100011BD2 /* x86.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4B3F76AD25A0196100178AEC /* x86.cpp */; };
4BEEE6BD20DC72EB003723BF /* CompositeOptions.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4BEEE6BB20DC72EA003723BF /* CompositeOptions.xib */; };
4BEF6AAA1D35CE9E00E73575 /* DigitalPhaseLockedLoopBridge.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4BEF6AA91D35CE9E00E73575 /* DigitalPhaseLockedLoopBridge.mm */; };
4BEF6AAC1D35D1C400E73575 /* DPLLTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4BEF6AAB1D35D1C400E73575 /* DPLLTests.swift */; };
@ -1081,9 +1084,6 @@
4B3BA0CD1D318B44005DD7A7 /* TestMachine6502.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = TestMachine6502.mm; sourceTree = "<group>"; };
4B3BF5AE1F146264005B6C36 /* CSW.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CSW.cpp; sourceTree = "<group>"; };
4B3BF5AF1F146264005B6C36 /* CSW.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CSW.hpp; sourceTree = "<group>"; };
4B3F769E259FCE0F00178AEC /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
4B3F76AC25A0196100178AEC /* x86.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = x86.hpp; sourceTree = "<group>"; };
4B3F76AD25A0196100178AEC /* x86.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = x86.cpp; sourceTree = "<group>"; };
4B3F76B825A1635300178AEC /* PowerPCDecoderTests.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = PowerPCDecoderTests.mm; sourceTree = "<group>"; };
4B3FCC3E201EC24200960631 /* MultiMachine.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = MultiMachine.hpp; sourceTree = "<group>"; };
4B3FCC3F201EC24200960631 /* MultiMachine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MultiMachine.cpp; sourceTree = "<group>"; };
@ -1777,8 +1777,6 @@
4BDB3D8522833321002D3CEE /* Keyboard.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Keyboard.hpp; sourceTree = "<group>"; };
4BDCC5F81FB27A5E001220C5 /* ROMMachine.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ROMMachine.hpp; sourceTree = "<group>"; };
4BDDBA981EF3451200347E61 /* Z80MachineCycleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Z80MachineCycleTests.swift; sourceTree = "<group>"; };
4BDDBBD5259D757800CEFF58 /* PowerPC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PowerPC.cpp; sourceTree = "<group>"; };
4BDDBBD6259D757800CEFF58 /* PowerPC.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = PowerPC.hpp; sourceTree = "<group>"; };
4BE0A3EC237BB170002AB46F /* ST.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = ST.cpp; sourceTree = "<group>"; };
4BE0A3ED237BB170002AB46F /* ST.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = ST.hpp; sourceTree = "<group>"; };
4BE211DD253E4E4800435408 /* 65C02_no_Rockwell_test.bin */ = {isa = PBXFileReference; lastKnownFileType = archive.macbinary; name = 65C02_no_Rockwell_test.bin; path = "Klaus Dormann/65C02_no_Rockwell_test.bin"; sourceTree = "<group>"; };
@ -1801,6 +1799,13 @@
4BEBFB4C2002C4BF000708CC /* MSXDSK.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = MSXDSK.hpp; sourceTree = "<group>"; };
4BEBFB4F2002DB30000708CC /* DiskROM.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = DiskROM.cpp; path = MSX/DiskROM.cpp; sourceTree = "<group>"; };
4BEBFB502002DB30000708CC /* DiskROM.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; name = DiskROM.hpp; path = MSX/DiskROM.hpp; sourceTree = "<group>"; };
4BEDA3B425B25563000C2DBD /* Decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Decoder.cpp; sourceTree = "<group>"; };
4BEDA3B525B25563000C2DBD /* Decoder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Decoder.hpp; sourceTree = "<group>"; };
4BEDA3B625B25563000C2DBD /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = "<group>"; };
4BEDA3B825B25563000C2DBD /* Decoder.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Decoder.hpp; sourceTree = "<group>"; };
4BEDA3B925B25563000C2DBD /* Decoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Decoder.cpp; sourceTree = "<group>"; };
4BEDA3D225B257F2000C2DBD /* Instruction.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Instruction.hpp; sourceTree = "<group>"; };
4BEDA3DB25B2588F000C2DBD /* Instruction.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Instruction.hpp; sourceTree = "<group>"; };
4BEE0A6A1D72496600532C7B /* Cartridge.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Cartridge.cpp; sourceTree = "<group>"; };
4BEE0A6B1D72496600532C7B /* Cartridge.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Cartridge.hpp; sourceTree = "<group>"; };
4BEE0A6D1D72496600532C7B /* PRG.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PRG.cpp; sourceTree = "<group>"; };
@ -2332,15 +2337,6 @@
path = Bridges;
sourceTree = "<group>";
};
4B3F76AB25A0196100178AEC /* x86 */ = {
isa = PBXGroup;
children = (
4B3F76AC25A0196100178AEC /* x86.hpp */,
4B3F76AD25A0196100178AEC /* x86.cpp */,
);
path = x86;
sourceTree = "<group>";
};
4B3FCC3D201EC24200960631 /* MultiMachine */ = {
isa = PBXGroup;
children = (
@ -3407,6 +3403,7 @@
4B31B88E1FBFBCD800C140D5 /* Configurable */,
4B055A761FAE78210060FFFF /* Frameworks */,
4B86E2581F8C628F006FAA45 /* Inputs */,
4BEDA3B225B25563000C2DBD /* InstructionSets */,
4BB73EDC1B587CA500552FC2 /* Machines */,
4B7BA03C23D55E7900B98D9E /* Numeric */,
4B366DFD1B5C165F0026627B /* Outputs */,
@ -3562,7 +3559,6 @@
4B4DEC15252BFA9C004583AC /* 6502Esque */,
4BF8D4CC251C0C9C00BBE21B /* 65816 */,
4BFF1D332233778C00838EA1 /* 68000 */,
4BDDBBD3259D757800CEFF58 /* Decoders */,
4B77069E1EC9045B0053B588 /* Z80 */,
);
name = Processors;
@ -3905,25 +3901,6 @@
path = 5380;
sourceTree = "<group>";
};
4BDDBBD3259D757800CEFF58 /* Decoders */ = {
isa = PBXGroup;
children = (
4B3F769E259FCE0F00178AEC /* README.md */,
4BDDBBD4259D757800CEFF58 /* PowerPC */,
4B3F76AB25A0196100178AEC /* x86 */,
);
path = Decoders;
sourceTree = "<group>";
};
4BDDBBD4259D757800CEFF58 /* PowerPC */ = {
isa = PBXGroup;
children = (
4BDDBBD5259D757800CEFF58 /* PowerPC.cpp */,
4BDDBBD6259D757800CEFF58 /* PowerPC.hpp */,
);
path = PowerPC;
sourceTree = "<group>";
};
4BE5F85A1C3E1C2500C43F01 /* Resources */ = {
isa = PBXGroup;
children = (
@ -3950,6 +3927,37 @@
name = Zexall;
sourceTree = "<group>";
};
4BEDA3B225B25563000C2DBD /* InstructionSets */ = {
isa = PBXGroup;
children = (
4BEDA3B625B25563000C2DBD /* README.md */,
4BEDA3B325B25563000C2DBD /* PowerPC */,
4BEDA3B725B25563000C2DBD /* x86 */,
);
name = InstructionSets;
path = ../../InstructionSets;
sourceTree = "<group>";
};
4BEDA3B325B25563000C2DBD /* PowerPC */ = {
isa = PBXGroup;
children = (
4BEDA3B425B25563000C2DBD /* Decoder.cpp */,
4BEDA3B525B25563000C2DBD /* Decoder.hpp */,
4BEDA3D225B257F2000C2DBD /* Instruction.hpp */,
);
path = PowerPC;
sourceTree = "<group>";
};
4BEDA3B725B25563000C2DBD /* x86 */ = {
isa = PBXGroup;
children = (
4BEDA3B925B25563000C2DBD /* Decoder.cpp */,
4BEDA3B825B25563000C2DBD /* Decoder.hpp */,
4BEDA3DB25B2588F000C2DBD /* Instruction.hpp */,
);
path = x86;
sourceTree = "<group>";
};
4BEE0A691D72496600532C7B /* Cartridge */ = {
isa = PBXGroup;
children = (
@ -4180,6 +4188,7 @@
4B2C45421E3C3896002A2389 /* cartridge.png in Resources */,
4BB73EA91B587A5100552FC2 /* Assets.xcassets in Resources */,
4B79E4451E3AF38600141F11 /* floppy35.png in Resources */,
4BEDA3BD25B25563000C2DBD /* README.md in Resources */,
4B55DD8420DF06680043F2E5 /* MachinePicker.xib in Resources */,
4BDA00DA22E60EE300AC3CD0 /* ROMRequester.xib in Resources */,
4BC5FC3020CDDDEF00410AA0 /* AppleIIOptions.xib in Resources */,
@ -4216,6 +4225,7 @@
4BB2994E1B587D8400A49093 /* dexn in Resources */,
4BB299971B587D8400A49093 /* nopa in Resources */,
4B018B89211930DE002A3937 /* 65C02_extended_opcodes_test.bin in Resources */,
4BEDA3BE25B25563000C2DBD /* README.md in Resources */,
4BFCA1291ECBE7A700AC40C1 /* zexall.com in Resources */,
4BB299521B587D8400A49093 /* eoray in Resources */,
4BB299411B587D8400A49093 /* cpyb in Resources */,
@ -4650,7 +4660,7 @@
4BD67DD1209BF27B00AB2146 /* Encoder.cpp in Sources */,
4B89451F201967B4007DE474 /* Tape.cpp in Sources */,
4B055AA81FAE85EF0060FFFF /* Shifter.cpp in Sources */,
4BDDBBD8259D757800CEFF58 /* PowerPC.cpp in Sources */,
4BEDA3BC25B25563000C2DBD /* Decoder.cpp in Sources */,
4B8318B422D3E546006DB630 /* DriveSpeedAccumulator.cpp in Sources */,
4B055AC81FAE9AFB0060FFFF /* C1540.cpp in Sources */,
4B055A8F1FAE85A90060FFFF /* FileHolder.cpp in Sources */,
@ -4685,7 +4695,7 @@
4B0F94FF208C1A1600FE41D9 /* NIB.cpp in Sources */,
4B0E04EB1FC9E78800F43484 /* CAS.cpp in Sources */,
4BB0A65D2045009000FB3688 /* ColecoVision.cpp in Sources */,
4B3F76AF25A0196100178AEC /* x86.cpp in Sources */,
4BEDA3C125B25563000C2DBD /* Decoder.cpp in Sources */,
4BB0A65C2044FD3000FB3688 /* SN76489.cpp in Sources */,
4B595FAE2086DFBA0083CAA8 /* AudioToggle.cpp in Sources */,
4B055AB91FAE86170060FFFF /* Acorn.cpp in Sources */,
@ -4758,7 +4768,7 @@
4B54C0BF1F8D8F450050900F /* Keyboard.cpp in Sources */,
4B3FE75E1F3CF68B00448EE4 /* CPM.cpp in Sources */,
4B2BFDB21DAEF5FF001A68B8 /* Video.cpp in Sources */,
4B3F76AE25A0196100178AEC /* x86.cpp in Sources */,
4BEDA3BF25B25563000C2DBD /* Decoder.cpp in Sources */,
4B4DC82B1D2C27A4003C5BF8 /* SerialBus.cpp in Sources */,
4BBFFEE61F7B27F1005F3FEB /* TrackSerialiser.cpp in Sources */,
4BAE49582032881E004BE78E /* CSZX8081.mm in Sources */,
@ -4795,7 +4805,7 @@
4B45189F1F75FD1C00926311 /* AcornADF.cpp in Sources */,
4B7BA03023C2B19C00B98D9E /* Jasmin.cpp in Sources */,
4B7136911F789C93008B8ED9 /* SegmentParser.cpp in Sources */,
4BDDBBD7259D757800CEFF58 /* PowerPC.cpp in Sources */,
4BEDA3BA25B25563000C2DBD /* Decoder.cpp in Sources */,
4B4518A21F75FD1C00926311 /* G64.cpp in Sources */,
4B89452C201967B4007DE474 /* Tape.cpp in Sources */,
4B448E811F1C45A00009ABD6 /* TZX.cpp in Sources */,
@ -4969,7 +4979,6 @@
4B4F477C253530B7004245B8 /* Jeek816Tests.swift in Sources */,
4B778F0F23A5EC560000D260 /* PCMTrack.cpp in Sources */,
4B778F1123A5EC650000D260 /* FileHolder.cpp in Sources */,
4BEE4BE125A26F8100011BD2 /* x86.cpp in Sources */,
4B778EFC23A5EB8B0000D260 /* AcornADF.cpp in Sources */,
4B778F2023A5EDCE0000D260 /* HFV.cpp in Sources */,
4B778F3323A5F0FB0000D260 /* MassStorageDevice.cpp in Sources */,
@ -4982,6 +4991,7 @@
4B778F4823A5F1E70000D260 /* StaticAnalyser.cpp in Sources */,
4B92EACA1B7C112B00246143 /* 6502TimingTests.swift in Sources */,
4B778F2823A5EEF80000D260 /* Cartridge.cpp in Sources */,
4BEDA3C025B25563000C2DBD /* Decoder.cpp in Sources */,
4B778F4C23A5F2090000D260 /* StaticAnalyser.cpp in Sources */,
4B778F2623A5EE350000D260 /* Acorn.cpp in Sources */,
4B778F5B23A5F2DE0000D260 /* Tape.cpp in Sources */,
@ -4992,6 +5002,7 @@
4BEE1EC122B5E2FD000A26A6 /* Encoder.cpp in Sources */,
4B121F9B1E06293F00BFDA12 /* PCMSegmentEventSourceTests.mm in Sources */,
4B778EFF23A5EB940000D260 /* D64.cpp in Sources */,
4BEDA3BB25B25563000C2DBD /* Decoder.cpp in Sources */,
4B778F2423A5EDEE0000D260 /* PRG.cpp in Sources */,
4B778F5A23A5F2D50000D260 /* 6502.cpp in Sources */,
4B778F6223A5F35F0000D260 /* File.cpp in Sources */,

View File

@ -8,7 +8,7 @@
#import <XCTest/XCTest.h>
#include "../../../Processors/Decoders/PowerPC/PowerPC.hpp"
#include "../../../InstructionSets/PowerPC/Decoder.hpp"
namespace {
using Operation = CPU::Decoder::PowerPC::Operation;

View File

@ -10,7 +10,7 @@
#include <initializer_list>
#include <vector>
#include "../../../Processors/Decoders/x86/x86.hpp"
#include "../../../InstructionSets/x86/Decoder.hpp"
namespace {
using Operation = CPU::Decoder::x86::Operation;