Replace old i8080 disassembler with new (z80) style.

Signed-off-by: Adrian.Conlon <adrian.conlon@arup.com>
This commit is contained in:
Adrian.Conlon 2017-07-25 14:12:34 +01:00
parent dfc02c7e54
commit 2ae4e8331e
8 changed files with 419 additions and 130 deletions

View File

@ -1,8 +1,10 @@
#pragma once #pragma once
#include <string> #include <string>
#include <boost/format.hpp>
namespace EightBit { namespace EightBit {
class Intel8080; class Intel8080;
class Disassembler { class Disassembler {
@ -10,7 +12,7 @@ namespace EightBit {
Disassembler(); Disassembler();
static std::string state(Intel8080& cpu); static std::string state(Intel8080& cpu);
static std::string disassemble(Intel8080& cpu); std::string disassemble(Intel8080& cpu);
static std::string flag(uint8_t value, int flag, const std::string& represents); static std::string flag(uint8_t value, int flag, const std::string& represents);
static std::string flags(uint8_t value); static std::string flags(uint8_t value);
@ -19,5 +21,26 @@ namespace EightBit {
static std::string binary(uint8_t value); static std::string binary(uint8_t value);
static std::string invalid(uint8_t value); static std::string invalid(uint8_t value);
private:
mutable boost::format m_formatter;
void disassemble(std::ostringstream& output, const Intel8080& cpu, uint16_t pc);
void disassemble(
std::ostringstream& output,
const Intel8080& cpu,
uint16_t pc,
std::string& specification,
int& dumpCount,
int x, int y, int z,
int p, int q);
std::string RP(int rp) const;
std::string RP2(int rp) const;
std::string R(int r) const;
static std::string cc(int flag);
static std::string alu(int which);
static std::string alu2(int which);
}; };
} }

View File

@ -18,26 +18,10 @@ namespace EightBit {
CF = Bit0, CF = Bit0,
}; };
enum AddressingMode {
Unknown,
Implied, // zero bytes
Immediate, // single byte
Absolute // two bytes, little endian
};
struct Instruction {
instruction_t vector = nullptr;
AddressingMode mode = Unknown;
std::string disassembly;
int count = 0;
};
Intel8080(Memory& memory, InputOutput& ports); Intel8080(Memory& memory, InputOutput& ports);
Signal<Intel8080> ExecutingInstruction; Signal<Intel8080> ExecutingInstruction;
const std::array<Instruction, 0x100>& getInstructions() const { return instructions; }
bool isInterruptable() const; bool isInterruptable() const;
int interrupt(uint8_t value); int interrupt(uint8_t value);
@ -65,8 +49,6 @@ namespace EightBit {
private: private:
InputOutput& m_ports; InputOutput& m_ports;
std::array<Instruction, 0x100> instructions;
register16_t af; register16_t af;
register16_t bc; register16_t bc;
register16_t de; register16_t de;
@ -183,23 +165,10 @@ namespace EightBit {
void xhtl(); void xhtl();
// input/output
void out(); void out();
void in(); void in();
// control
void ei(); void ei();
void di(); void di();
//
void ___();
void nop() {}
static Instruction INS(instruction_t method, AddressingMode mode, std::string disassembly, int cycles);
Instruction UNKNOWN();
void installInstructions();
}; };
} }

View File

@ -9,6 +9,8 @@
#include "Intel8080.h" #include "Intel8080.h"
EightBit::Disassembler::Disassembler() { EightBit::Disassembler::Disassembler() {
// Disable exceptions where too many format arguments are available
m_formatter.exceptions(boost::io::all_error_bits ^ boost::io::too_many_args_bit);
} }
std::string EightBit::Disassembler::state(Intel8080& cpu) { std::string EightBit::Disassembler::state(Intel8080& cpu) {
@ -42,48 +44,397 @@ std::string EightBit::Disassembler::state(Intel8080& cpu) {
return output.str(); return output.str();
} }
std::string EightBit::Disassembler::RP(int rp) const {
switch (rp) {
case 0:
return "B";
case 1:
return "D";
case 2:
return "H";
case 3:
return "SP";
}
throw std::logic_error("Unhandled register pair");
}
std::string EightBit::Disassembler::RP2(int rp) const {
switch (rp) {
case 0:
return "B";
case 1:
return "D";
case 2:
return "H";
case 3:
return "PSW";
}
throw std::logic_error("Unhandled register pair");
}
std::string EightBit::Disassembler::R(int r) const {
switch (r) {
case 0:
return "B";
case 1:
return "C";
case 2:
return "D";
case 3:
return "E";
case 4:
return "H";
case 5:
return "L";
case 6:
return "M";
case 7:
return "A";
}
throw std::logic_error("Unhandled register");
}
std::string EightBit::Disassembler::cc(int flag) {
switch (flag) {
case 0:
return "NZ";
case 1:
return "Z";
case 2:
return "NC";
case 3:
return "C";
case 4:
return "PO";
case 5:
return "PE";
case 6:
return "P";
case 7:
return "M";
}
throw std::logic_error("Unhandled condition");
}
std::string EightBit::Disassembler::alu(int which) {
switch (which) {
case 0: // ADD A,n
return "ADD";
case 1: // ADC
return "ADC";
case 2: // SUB n
return "SUB";
case 3: // SBC A,n
return "SBB";
case 4: // AND n
return "ANA";
case 5: // XOR n
return "XRA";
case 6: // OR n
return "ORA";
case 7: // CP n
return "CMP";
}
throw std::logic_error("Unhandled alu operation");
}
std::string EightBit::Disassembler::alu2(int which) {
switch (which) {
case 0: // ADD A,n
return "ADI";
case 1: // ADC
return "ACI";
case 2: // SUB n
return "SUI";
case 3: // SBC A,n
return "SBI";
case 4: // AND n
return "ANI";
case 5: // XOR n
return "XRI";
case 6: // OR n
return "ORI";
case 7: // CP n
return "CPI";
}
throw std::logic_error("Unhandled alu operation");
}
std::string EightBit::Disassembler::disassemble(Intel8080& cpu) { std::string EightBit::Disassembler::disassemble(Intel8080& cpu) {
std::ostringstream output;
disassemble(output, cpu, cpu.PC().word);
return output.str();
}
void EightBit::Disassembler::disassemble(std::ostringstream& output, const Intel8080& cpu, uint16_t pc) {
const auto& memory = cpu.getMemory(); const auto& memory = cpu.getMemory();
auto pc = cpu.PC(); auto opcode = memory.peek(pc);
auto opcode = memory.peek(pc.word);
const auto& instruction = cpu.getInstructions()[opcode];
std::ostringstream output;
// hex opcode
output << hex(opcode); output << hex(opcode);
// hex raw operand auto x = (opcode & 0b11000000) >> 6;
switch (instruction.mode) { auto y = (opcode & 0b111000) >> 3;
case Intel8080::Immediate: auto z = (opcode & 0b111);
output << hex(memory.peek(pc.word + 1));
auto p = (y & 0b110) >> 1;
auto q = (y & 1);
auto immediate = memory.peek(pc + 1);
auto absolute = memory.peekWord(pc + 1);
auto displacement = (int8_t)immediate;
auto relative = pc + displacement + 2;
auto indexedImmediate = memory.peek(pc + 1);
auto dumpCount = 0;
std::string specification = "";
disassemble(
output, cpu, pc,
specification, dumpCount,
x, y, z, p, q);
for (int i = 0; i < dumpCount; ++i)
output << hex(memory.peek(pc + i + 1));
output << '\t';
m_formatter.parse(specification);
output << m_formatter % (int)immediate % (int)absolute % relative % (int)displacement % indexedImmediate;
}
void EightBit::Disassembler::disassemble(
std::ostringstream& output,
const Intel8080& cpu,
uint16_t pc,
std::string& specification,
int& dumpCount,
int x, int y, int z,
int p, int q) {
switch (x) {
case 0:
switch (z) {
case 0: // Relative jumps and assorted ops
switch (y) {
case 0: // NOP
specification = "NOP";
break;
case 1: // EX AF AF'
break;
case 2: // DJNZ d
break;
case 3: // JR d
break;
default: // JR cc,d
break;
}
break;
case 1: // 16-bit load immediate/add
switch (q) {
case 0: // LD rp,nn
specification = "LXI " + RP(p) + ",%2$04XH";
dumpCount += 2;
break;
case 1: // ADD HL,rp
specification = "DAD " + RP(p);
break;
}
break;
case 2: // Indirect loading
switch (q) {
case 0:
switch (p) {
case 0: // LD (BC),A
specification = "STAX B";
break;
case 1: // LD (DE),A
specification = "STAX D";
break;
case 2: // LD (nn),HL
specification = "SHLD %2$04XH";
dumpCount += 2;
break;
case 3: // LD (nn),A
specification = "STA %2$04XH";
dumpCount += 2;
break;
}
break;
case 1:
switch (p) {
case 0: // LD A,(BC)
specification = "LDAX B";
break;
case 1: // LD A,(DE)
specification = "LDAX D";
break;
case 2: // LD HL,(nn)
specification = "LHLD %2$04XH";
dumpCount += 2;
break;
case 3: // LD A,(nn)
specification = "LDA %2$04XH";
dumpCount += 2;
break;
}
break;
}
break;
case 3: // 16-bit INC/DEC
switch (q) {
case 0: // INC rp
specification = "INX " + RP(p);
break;
case 1: // DEC rp
specification = "DCX " + RP(p);
break;
}
break;
case 4: // 8-bit INC
specification = "INR " + R(y);
break;
case 5: // 8-bit DEC
specification = "DCR " + R(y);
break;
case 6: // 8-bit load immediate
specification = "MVI " + R(y) + ",%1$02XH";
dumpCount++;
break;
case 7: // Assorted operations on accumulator/flags
switch (y) {
case 0:
specification = "RLC";
break;
case 1:
specification = "RRC";
break;
case 2:
specification = "RAL";
break;
case 3:
specification = "RAR";
break;
case 4:
specification = "DAA";
break;
case 5:
specification = "CMA";
break;
case 6:
specification = "STC";
break;
case 7:
specification = "CMC";
break;
}
break;
}
break; break;
case Intel8080::Absolute: case 1: // 8-bit loading
output << hex(memory.peek(pc.word + 1)); if (z == 6 && y == 6) { // Exception (replaces LD (HL), (HL))
output << hex(memory.peek(pc.word + 2)); specification = "HLT";
} else {
specification = "MOV " + R(y) + "," + R(z);
}
break; break;
default: case 2: // Operate on accumulator and register/memory location
specification = alu(y) + " A," + R(z);
break;
case 3:
switch (z) {
case 0: // Conditional return
specification = "R" + cc(y);
break;
case 1: // POP & various ops
switch (q) {
case 0: // POP rp2[p]
specification = "POP " + RP2(p);
break;
case 1:
switch (p) {
case 0: // RET
specification = "RET";
break;
case 1: // EXX
break;
case 2: // JP HL
specification = "PCHL";
break;
case 3: // LD SP,HL
specification = "SPHL";
break;
}
}
break;
case 2: // Conditional jump
specification = "J" + cc(y) + " %2$04XH";
dumpCount += 2;
break;
case 3: // Assorted operations
switch (y) {
case 0: // JP nn
specification = "JMP %2$04XH";
dumpCount += 2;
break;
case 1: // CB prefix
break;
case 2: // OUT (n),A
specification = "OUT %1$02XH";
dumpCount++;
break;
case 3: // IN A,(n)
specification = "IN %1$02XH";
dumpCount++;
break;
case 4: // EX (SP),HL
specification = "XHTL";
break;
case 5: // EX DE,HL
specification = "XCHG";
break;
case 6: // DI
specification = "DI";
break;
case 7: // EI
specification = "EI";
break;
}
break;
case 4: // Conditional call: CALL cc[y], nn
specification = "C" + cc(y) + " %2$04XH";
dumpCount += 2;
break;
case 5: // PUSH & various ops
switch (q) {
case 0: // PUSH rp2[p]
specification = "PUSH " + RP2(p);
break;
case 1:
switch (p) {
case 0: // CALL nn
specification = "CALL %2$04XH";
dumpCount += 2;
break;
case 1: // DD prefix
break;
case 2: // ED prefix
break;
case 3: // FD prefix
break;
}
}
break;
case 6: // Operate on accumulator and immediate operand: alu[y] n
specification = alu2(y) + " %1$02XH";
dumpCount++;
break;
case 7: // Restart: RST y * 8
specification = "RST " + hex((uint8_t)y);
break;
}
break; break;
} }
output << "\t";
// base disassembly
output << instruction.disassembly;
// disassembly operand
switch (instruction.mode) {
case Intel8080::Immediate:
output << hex(memory.peek(pc.word + 1));
break;
case Intel8080::Absolute:
output << hex(memory.peekWord(pc.word + 1));
break;
default:
break;
}
return output.str();
} }
std::string EightBit::Disassembler::flag(uint8_t value, int flag, const std::string& represents) { std::string EightBit::Disassembler::flag(uint8_t value, int flag, const std::string& represents) {
@ -97,11 +448,11 @@ std::string EightBit::Disassembler::flags(uint8_t value) {
output output
<< flag(value, Intel8080::SF, "S") << flag(value, Intel8080::SF, "S")
<< flag(value, Intel8080::ZF, "Z") << flag(value, Intel8080::ZF, "Z")
<< "0" << flag(value, Processor::Bit5, "5")
<< flag(value, Intel8080::AC, "A") << flag(value, Intel8080::AC, "A")
<< "0" << flag(value, Processor::Bit3, "3")
<< flag(value, Intel8080::PF, "P") << flag(value, Intel8080::PF, "P")
<< "1" << flag(value, Processor::Bit1, "1")
<< flag(value, Intel8080::CF, "C"); << flag(value, Intel8080::CF, "C");
return output.str(); return output.str();
} }

View File

@ -9,7 +9,6 @@ EightBit::Intel8080::Intel8080(Memory& memory, InputOutput& ports)
m_interrupt(false), m_interrupt(false),
m_ports(ports) { m_ports(ports) {
bc.word = de.word = hl.word = 0; bc.word = de.word = hl.word = 0;
installInstructions();
} }
void EightBit::Intel8080::initialise() { void EightBit::Intel8080::initialise() {
@ -673,57 +672,3 @@ void EightBit::Intel8080::execute(int x, int y, int z, int p, int q) {
break; break;
} }
} }
//
EightBit::Intel8080::Instruction EightBit::Intel8080::INS(instruction_t method, AddressingMode mode, std::string disassembly, int cycles) {
Intel8080::Instruction returnValue;
returnValue.vector = method;
returnValue.mode = mode;
returnValue.disassembly = disassembly;
returnValue.count = cycles;
return returnValue;
}
EightBit::Intel8080::Instruction EightBit::Intel8080::UNKNOWN() {
Intel8080::Instruction returnValue;
returnValue.vector = std::bind(&Intel8080::___, this);
returnValue.mode = Unknown;
returnValue.disassembly = "";
returnValue.count = 0;
return returnValue;
}
#define BIND(method) std::bind(&Intel8080:: method, this)
void EightBit::Intel8080::installInstructions() {
instructions = {
//// 0 1 2 3 4 5 6 7 8 9 A B C D E F
/* 0 */ INS(BIND(nop), Implied, "NOP", 4), INS(BIND(nop), Absolute, "LXI B,", 10), INS(BIND(nop), Implied, "STAX B", 7), INS(BIND(nop), Implied, "INX B", 5), INS(BIND(nop), Implied, "INR B", 5), INS(BIND(nop), Implied, "DCR B", 5), INS(BIND(nop), Immediate, "MVI B,", 7), INS(BIND(nop), Implied, "RLC", 4), UNKNOWN(), INS(BIND(nop), Implied, "DAD B", 10), INS(BIND(nop), Implied, "LDAX B", 7), INS(BIND(nop), Implied, "DCX B", 5), INS(BIND(nop), Implied, "INR C", 5), INS(BIND(nop), Implied, "DCR C", 5), INS(BIND(nop), Immediate, "MVI C,", 7), INS(BIND(nop), Implied, "RRC", 4), // 0
/* 1 */ UNKNOWN(), INS(BIND(nop), Absolute, "LXI D,", 10), INS(BIND(nop), Implied, "STAX D", 7), INS(BIND(nop), Implied, "INX D", 5), INS(BIND(nop), Implied, "INR D", 5), INS(BIND(nop), Implied, "DCR D", 5), INS(BIND(nop), Immediate, "MVI D,", 7), INS(BIND(nop), Implied, "RAL", 4), UNKNOWN(), INS(BIND(nop), Implied, "DAD D", 10), INS(BIND(nop), Implied, "LDAX D", 7), INS(BIND(nop), Implied, "DCX D", 5), INS(BIND(nop), Implied, "INR E", 5), INS(BIND(nop), Implied, "DCR E", 5), INS(BIND(nop), Immediate, "MVI E,", 7), INS(BIND(nop), Implied, "RAR", 4), // 1
/* 2 */ UNKNOWN(), INS(BIND(nop), Absolute, "LXI H,", 10), INS(BIND(nop), Absolute, "SHLD", 16), INS(BIND(nop), Implied, "INX H", 5), INS(BIND(nop), Implied, "INR H", 5), INS(BIND(nop), Implied, "DCR H", 5), INS(BIND(nop), Immediate, "MVI H,",7), INS(BIND(nop), Implied, "DAA", 4), UNKNOWN(), INS(BIND(nop), Implied, "DAD H", 10), INS(BIND(nop), Absolute, "LHLD ", 16), INS(BIND(nop), Implied, "DCX H", 5), INS(BIND(nop), Implied, "INR L", 5), INS(BIND(nop), Implied, "DCR L", 5), INS(BIND(nop), Immediate, "MVI L,", 7), INS(BIND(nop), Implied, "CMA", 4), // 2
/* 3 */ UNKNOWN(), INS(BIND(nop), Absolute, "LXI SP,", 10), INS(BIND(nop), Absolute, "STA ", 13), INS(BIND(nop), Implied, "INX SP", 5), INS(BIND(nop), Implied, "INR M", 10), INS(BIND(nop), Implied, "DCR M", 10), INS(BIND(nop), Immediate, "MVI M,", 10), INS(BIND(nop), Implied, "STC", 4), UNKNOWN(), INS(BIND(nop), Implied, "DAD SP", 10), INS(BIND(nop), Absolute, "LDA ", 13), INS(BIND(nop), Implied, "DCX SP", 5), INS(BIND(nop), Implied, "INR A", 5), INS(BIND(nop), Implied, "DCR A", 5), INS(BIND(nop), Immediate, "MVI A,", 7), INS(BIND(nop), Implied, "CMC", 4), // 3
/* 4 */ INS(BIND(nop), Implied, "MOV B,B", 5), INS(BIND(nop), Implied, "MOV B,C", 5), INS(BIND(nop), Implied, "MOV B,D", 5), INS(BIND(nop), Implied, "MOV B,E", 5), INS(BIND(nop), Implied, "MOV B,H", 5), INS(BIND(nop), Implied, "MOV B,L", 5), INS(BIND(nop), Implied, "MOV B,M", 7), INS(BIND(nop), Implied, "MOV B,A", 5), INS(BIND(nop), Implied, "MOV C,B", 5), INS(BIND(nop), Implied, "MOV C,C", 5), INS(BIND(nop), Implied, "MOV C,D", 5), INS(BIND(nop), Implied, "MOV C,E", 5), INS(BIND(nop), Implied, "MOV C,H", 5), INS(BIND(nop), Implied, "MOV C,L", 5), INS(BIND(nop), Implied, "MOV C,M", 7), INS(BIND(nop), Implied, "MOV C,A", 5), // 4
/* 5 */ INS(BIND(nop), Implied, "MOV D,B", 5), INS(BIND(nop), Implied, "MOV D,C", 5), INS(BIND(nop), Implied, "MOV D,D", 5), INS(BIND(nop), Implied, "MOV D,E", 5), INS(BIND(nop), Implied, "MOV D,H", 5), INS(BIND(nop), Implied, "MOV D,L", 5), INS(BIND(nop), Implied, "MOV D,M", 7), INS(BIND(nop), Implied, "MOV D,A", 5), INS(BIND(nop), Implied, "MOV E,B", 5), INS(BIND(nop), Implied, "MOV E,C", 5), INS(BIND(nop), Implied, "MOV E,D", 5), INS(BIND(nop), Implied, "MOV E,E", 5), INS(BIND(nop), Implied, "MOV E,H", 5), INS(BIND(nop), Implied, "MOV E,L", 5), INS(BIND(nop), Implied, "MOV E,M", 7), INS(BIND(nop), Implied, "MOV E,A", 5), // 5
/* 6 */ INS(BIND(nop), Implied, "MOV H,B", 5), INS(BIND(nop), Implied, "MOV H,C", 5), INS(BIND(nop), Implied, "MOV H,D", 5), INS(BIND(nop), Implied, "MOV H,E", 5), INS(BIND(nop), Implied, "MOV H,H", 5), INS(BIND(nop), Implied, "MOV H,L", 5), INS(BIND(nop), Implied, "MOV H,M", 7), INS(BIND(nop), Implied, "MOV H,A", 5), INS(BIND(nop), Implied, "MOV L,B", 5), INS(BIND(nop), Implied, "MOV L,C", 5), INS(BIND(nop), Implied, "MOV L,D", 5), INS(BIND(nop), Implied, "MOV L,E", 5), INS(BIND(nop), Implied, "MOV L,H", 5), INS(BIND(nop), Implied, "MOV L,L", 5), INS(BIND(nop), Implied, "MOV L,M", 7), INS(BIND(nop), Implied, "MOV L,A", 5), // 6
/* 7 */ INS(BIND(nop), Implied, "MOV M,B", 7), INS(BIND(nop), Implied, "MOV M,C", 7), INS(BIND(nop), Implied, "MOV M,D", 7), INS(BIND(nop), Implied, "MOV M,E", 7), INS(BIND(nop), Implied, "MOV M,H", 7), INS(BIND(nop), Implied, "MOV M,L", 7), INS(BIND(nop), Implied, "HLT", 7), INS(BIND(nop), Implied, "MOV M,A", 7), INS(BIND(nop), Implied, "MOV A,B", 5), INS(BIND(nop), Implied, "MOV A,C", 5), INS(BIND(nop), Implied, "MOV A,D", 5), INS(BIND(nop), Implied, "MOV A,E", 5), INS(BIND(nop), Implied, "MOV A,H", 5), INS(BIND(nop), Implied, "MOV A,L", 5), INS(BIND(nop), Implied, "MOV A,M", 7), INS(BIND(nop), Implied, "MOV A,A", 5), // 7
/* 8 */ INS(BIND(nop), Implied, "ADD B", 4), INS(BIND(nop), Implied, "ADD C", 4), INS(BIND(nop), Implied, "ADD D", 4), INS(BIND(nop), Implied, "ADD E", 4), INS(BIND(nop), Implied, "ADD H", 4), INS(BIND(nop), Implied, "ADD L", 4), INS(BIND(nop), Implied, "ADD M", 7), INS(BIND(nop), Implied, "ADD A", 4), INS(BIND(nop), Implied, "ADC B", 4), INS(BIND(nop), Implied, "ADC C", 4), INS(BIND(nop), Implied, "ADC D", 4), INS(BIND(nop), Implied, "ADC E", 4), INS(BIND(nop), Implied, "ADC H", 4), INS(BIND(nop), Implied, "ADC L", 4), INS(BIND(nop), Implied, "ADC M", 4), INS(BIND(nop), Implied, "ADC A", 4), // 8
/* 9 */ INS(BIND(nop), Implied, "SUB B", 4), INS(BIND(nop), Implied, "SUB C", 4), INS(BIND(nop), Implied, "SUB D", 4), INS(BIND(nop), Implied, "SUB E", 4), INS(BIND(nop), Implied, "SUB H", 4), INS(BIND(nop), Implied, "SUB L", 4), INS(BIND(nop), Implied, "SUB M", 7), INS(BIND(nop), Implied, "SUB A", 4), INS(BIND(nop), Implied, "SBB B", 4), INS(BIND(nop), Implied, "SBB C", 4), INS(BIND(nop), Implied, "SBB D", 4), INS(BIND(nop), Implied, "SBB E", 4), INS(BIND(nop), Implied, "SBB H", 4), INS(BIND(nop), Implied, "SBB L", 4), INS(BIND(nop), Implied, "SBB M", 4), INS(BIND(nop), Implied, "SBB A", 4), // 9
/* A */ INS(BIND(nop), Implied, "ANA B", 4), INS(BIND(nop), Implied, "ANA C", 4), INS(BIND(nop), Implied, "ANA D", 4), INS(BIND(nop), Implied, "ANA E", 4), INS(BIND(nop), Implied, "ANA H", 4), INS(BIND(nop), Implied, "ANA L", 4), INS(BIND(nop), Implied, "ANA M", 7), INS(BIND(nop), Implied, "ANA A", 4), INS(BIND(nop), Implied, "XRA B", 4), INS(BIND(nop), Implied, "XRA C", 4), INS(BIND(nop), Implied, "XRA D", 4), INS(BIND(nop), Implied, "XRA E", 4), INS(BIND(nop), Implied, "XRA H", 4), INS(BIND(nop), Implied, "XRA L", 4), INS(BIND(nop), Implied, "XRA M", 4), INS(BIND(nop), Implied, "XRA A", 4), // A
/* B */ INS(BIND(nop), Implied, "ORA B", 4), INS(BIND(nop), Implied, "ORA C", 4), INS(BIND(nop), Implied, "ORA D", 4), INS(BIND(nop), Implied, "ORA E", 4), INS(BIND(nop), Implied, "ORA H", 4), INS(BIND(nop), Implied, "ORA L", 4), INS(BIND(nop), Implied, "ORA M", 7), INS(BIND(nop), Implied, "ORA A", 4), INS(BIND(nop), Implied, "CMP B", 4), INS(BIND(nop), Implied, "CMP C", 4), INS(BIND(nop), Implied, "CMP D", 4), INS(BIND(nop), Implied, "CMP E", 4), INS(BIND(nop), Implied, "CMP H", 4), INS(BIND(nop), Implied, "CMP L", 4), INS(BIND(nop), Implied, "CMP M", 4), INS(BIND(nop), Implied, "CMP A", 4), // B
/* C */ INS(BIND(nop), Implied, "RNZ", 5), INS(BIND(nop), Implied, "POP B", 10), INS(BIND(nop), Absolute, "JNZ ", 10), INS(BIND(nop), Absolute, "JMP ", 10), INS(BIND(nop), Absolute, "CNZ ", 11), INS(BIND(nop), Implied, "PUSH B", 11), INS(BIND(nop), Immediate, "ADI ", 7), INS(BIND(nop), Implied, "RST 0", 11), INS(BIND(nop), Implied, "RZ", 11), INS(BIND(nop), Implied, "RET", 10), INS(BIND(nop), Absolute, "JZ ", 10), UNKNOWN(), INS(BIND(nop), Absolute, "CZ ", 11), INS(BIND(nop), Absolute, "CALL ", 17), INS(BIND(nop), Immediate, "ACI ", 7), INS(BIND(nop), Implied, "RST 1", 11), // C
/* D */ INS(BIND(nop), Implied, "RNC", 5), INS(BIND(nop), Implied, "POP D", 10), INS(BIND(nop), Absolute, "JNC ", 10), INS(BIND(nop), Immediate, "OUT ", 10), INS(BIND(nop), Absolute, "CNC ", 11), INS(BIND(nop), Implied, "PUSH D", 11), INS(BIND(nop), Immediate, "SUI ", 7), INS(BIND(nop), Implied, "RST 2", 11), INS(BIND(nop), Implied, "RC", 11), UNKNOWN(), INS(BIND(nop), Absolute, "JC ", 10), INS(BIND(nop), Immediate, "IN ", 10), INS(BIND(nop), Absolute, "CC ", 11), UNKNOWN(), INS(BIND(nop), Immediate, "SBI ", 7), INS(BIND(nop), Implied, "RST 3", 11), // D
/* E */ INS(BIND(nop), Implied, "RPO", 5), INS(BIND(nop), Implied, "POP H", 10), INS(BIND(nop), Absolute, "JPO ", 10), INS(BIND(nop), Implied, "XHTL", 18), INS(BIND(nop), Absolute, "CPO ", 11), INS(BIND(nop), Implied, "PUSH H", 11), INS(BIND(nop), Immediate, "ANI ", 7), INS(BIND(nop), Implied, "RST 4", 11), INS(BIND(nop), Implied, "RPE", 11), INS(BIND(nop), Implied, "PCHL", 5), INS(BIND(nop), Absolute, "JPE ", 10), INS(BIND(nop), Implied, "XCHG", 4), INS(BIND(nop), Absolute, "CPE ", 11), UNKNOWN(), INS(BIND(nop), Immediate, "XRI ", 7), INS(BIND(nop), Implied, "RST 5", 11), // E
/* F */ INS(BIND(nop), Implied, "RP", 5), INS(BIND(nop), Implied, "POP PSW", 10), INS(BIND(nop), Absolute, "JP ", 10), INS(BIND(nop), Implied, "DI ", 4), INS(BIND(nop), Absolute, "CP ", 11), INS(BIND(nop), Implied, "PUSH PSW", 11), INS(BIND(nop), Immediate, "ORI ", 7), INS(BIND(nop), Implied, "RST 6", 11), INS(BIND(nop), Implied, "RM", 11), INS(BIND(nop), Implied, "SPHL", 5), INS(BIND(nop), Absolute, "JM ", 10), INS(BIND(nop), Implied, "EI", 4), INS(BIND(nop), Absolute, "CM ", 11), UNKNOWN(), INS(BIND(nop), Immediate, "CPI ", 7), INS(BIND(nop), Implied, "RST 7", 11), // F
};
}
void EightBit::Intel8080::___() {
m_memory.ADDRESS().word = PC().word - 1;
auto opcode = m_memory.reference();
auto message = Disassembler::invalid(opcode);
throw std::domain_error(message);
}

View File

@ -71,16 +71,16 @@
</ImportGroup> </ImportGroup>
<PropertyGroup Label="UserMacros" /> <PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<IncludePath>../inc;../../inc;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath> <IncludePath>..\inc;..\..\inc;C:\local\boost_1_64_0;$(IncludePath)</IncludePath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<IncludePath>../inc;../../inc;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath> <IncludePath>..\inc;..\..\inc;C:\local\boost_1_64_0;$(IncludePath)</IncludePath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<IncludePath>../inc;../../inc;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath> <IncludePath>..\inc;..\..\inc;C:\local\boost_1_64_0;$(IncludePath)</IncludePath>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<IncludePath>../inc;../../inc;$(VC_IncludePath);$(WindowsSDK_IncludePath)</IncludePath> <IncludePath>..\inc;..\..\inc;C:\local\boost_1_64_0;$(IncludePath)</IncludePath>
</PropertyGroup> </PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile> <ClCompile>

View File

@ -13,6 +13,8 @@
#include <vector> #include <vector>
#include <bitset> #include <bitset>
#include <boost/format.hpp>
#if defined(_M_X64) || defined(_M_IX86 ) #if defined(_M_X64) || defined(_M_IX86 )
# define HOST_LITTLE_ENDIAN # define HOST_LITTLE_ENDIAN
#else #else

View File

@ -1,6 +1,5 @@
#include "stdafx.h" #include "stdafx.h"
#include "Board.h" #include "Board.h"
#include "Disassembler.h"
#include "Configuration.h" #include "Configuration.h"
#include <iostream> #include <iostream>
@ -83,6 +82,6 @@ void Board::Cpu_ExecutingInstruction_Debug(const EightBit::Intel8080&) {
std::cerr std::cerr
<< EightBit::Disassembler::state(m_cpu) << EightBit::Disassembler::state(m_cpu)
<< "\t" << "\t"
<< EightBit::Disassembler::disassemble(m_cpu) << m_disassembler.disassemble(m_cpu)
<< '\n'; << '\n';
} }

View File

@ -1,12 +1,11 @@
#pragma once #pragma once
//#include <string>
#include "Memory.h" #include "Memory.h"
#include "InputOutput.h" #include "InputOutput.h"
#include "Intel8080.h" #include "Intel8080.h"
#include "Profiler.h" #include "Profiler.h"
#include "EventArgs.h" #include "EventArgs.h"
#include "Disassembler.h"
class Configuration; class Configuration;
@ -24,6 +23,7 @@ private:
EightBit::Memory m_memory; EightBit::Memory m_memory;
EightBit::InputOutput m_ports; EightBit::InputOutput m_ports;
EightBit::Intel8080 m_cpu; EightBit::Intel8080 m_cpu;
EightBit::Disassembler m_disassembler;
EightBit::Profiler m_profiler; EightBit::Profiler m_profiler;
void Cpu_ExecutingInstruction_Cpm(const EightBit::Intel8080& cpu); void Cpu_ExecutingInstruction_Cpm(const EightBit::Intel8080& cpu);