From 2ae4e8331e15850cc86a6dbf7ae40612c55770e8 Mon Sep 17 00:00:00 2001 From: "Adrian.Conlon" Date: Tue, 25 Jul 2017 14:12:34 +0100 Subject: [PATCH] Replace old i8080 disassembler with new (z80) style. Signed-off-by: Adrian.Conlon --- Intel8080/inc/Disassembler.h | 25 +- Intel8080/inc/Intel8080.h | 31 --- Intel8080/src/Disassembler.cpp | 421 +++++++++++++++++++++++++++++--- Intel8080/src/Intel8080.cpp | 55 ----- Intel8080/src/Intel8080.vcxproj | 8 +- Intel8080/src/stdafx.h | 2 + Intel8080/test/Board.cpp | 3 +- Intel8080/test/Board.h | 4 +- 8 files changed, 419 insertions(+), 130 deletions(-) diff --git a/Intel8080/inc/Disassembler.h b/Intel8080/inc/Disassembler.h index b3d4699..c9d4e9e 100644 --- a/Intel8080/inc/Disassembler.h +++ b/Intel8080/inc/Disassembler.h @@ -1,8 +1,10 @@ #pragma once #include +#include namespace EightBit { + class Intel8080; class Disassembler { @@ -10,7 +12,7 @@ namespace EightBit { Disassembler(); 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 flags(uint8_t value); @@ -19,5 +21,26 @@ namespace EightBit { static std::string binary(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); }; } \ No newline at end of file diff --git a/Intel8080/inc/Intel8080.h b/Intel8080/inc/Intel8080.h index bb92a26..78b1138 100644 --- a/Intel8080/inc/Intel8080.h +++ b/Intel8080/inc/Intel8080.h @@ -18,26 +18,10 @@ namespace EightBit { 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); Signal ExecutingInstruction; - const std::array& getInstructions() const { return instructions; } - bool isInterruptable() const; int interrupt(uint8_t value); @@ -65,8 +49,6 @@ namespace EightBit { private: InputOutput& m_ports; - std::array instructions; - register16_t af; register16_t bc; register16_t de; @@ -183,23 +165,10 @@ namespace EightBit { void xhtl(); - // input/output - void out(); void in(); - // control - void ei(); void di(); - - // - - void ___(); - void nop() {} - - static Instruction INS(instruction_t method, AddressingMode mode, std::string disassembly, int cycles); - Instruction UNKNOWN(); - void installInstructions(); }; } \ No newline at end of file diff --git a/Intel8080/src/Disassembler.cpp b/Intel8080/src/Disassembler.cpp index af04489..78a6ffa 100644 --- a/Intel8080/src/Disassembler.cpp +++ b/Intel8080/src/Disassembler.cpp @@ -9,6 +9,8 @@ #include "Intel8080.h" 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) { @@ -42,48 +44,397 @@ std::string EightBit::Disassembler::state(Intel8080& cpu) { 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::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(); - auto pc = cpu.PC(); - auto opcode = memory.peek(pc.word); - const auto& instruction = cpu.getInstructions()[opcode]; + auto opcode = memory.peek(pc); - std::ostringstream output; - - // hex opcode output << hex(opcode); - // hex raw operand - switch (instruction.mode) { - case Intel8080::Immediate: - output << hex(memory.peek(pc.word + 1)); + auto x = (opcode & 0b11000000) >> 6; + auto y = (opcode & 0b111000) >> 3; + auto z = (opcode & 0b111); + + 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; - case Intel8080::Absolute: - output << hex(memory.peek(pc.word + 1)); - output << hex(memory.peek(pc.word + 2)); + case 1: // 8-bit loading + if (z == 6 && y == 6) { // Exception (replaces LD (HL), (HL)) + specification = "HLT"; + } else { + specification = "MOV " + R(y) + "," + R(z); + } 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; } - 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) { @@ -97,11 +448,11 @@ std::string EightBit::Disassembler::flags(uint8_t value) { output << flag(value, Intel8080::SF, "S") << flag(value, Intel8080::ZF, "Z") - << "0" + << flag(value, Processor::Bit5, "5") << flag(value, Intel8080::AC, "A") - << "0" + << flag(value, Processor::Bit3, "3") << flag(value, Intel8080::PF, "P") - << "1" + << flag(value, Processor::Bit1, "1") << flag(value, Intel8080::CF, "C"); return output.str(); } diff --git a/Intel8080/src/Intel8080.cpp b/Intel8080/src/Intel8080.cpp index f1aa668..9c29a39 100644 --- a/Intel8080/src/Intel8080.cpp +++ b/Intel8080/src/Intel8080.cpp @@ -9,7 +9,6 @@ EightBit::Intel8080::Intel8080(Memory& memory, InputOutput& ports) m_interrupt(false), m_ports(ports) { bc.word = de.word = hl.word = 0; - installInstructions(); } void EightBit::Intel8080::initialise() { @@ -673,57 +672,3 @@ void EightBit::Intel8080::execute(int x, int y, int z, int p, int q) { 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); -} \ No newline at end of file diff --git a/Intel8080/src/Intel8080.vcxproj b/Intel8080/src/Intel8080.vcxproj index 0c16d36..7c69427 100644 --- a/Intel8080/src/Intel8080.vcxproj +++ b/Intel8080/src/Intel8080.vcxproj @@ -71,16 +71,16 @@ - ../inc;../../inc;$(VC_IncludePath);$(WindowsSDK_IncludePath) + ..\inc;..\..\inc;C:\local\boost_1_64_0;$(IncludePath) - ../inc;../../inc;$(VC_IncludePath);$(WindowsSDK_IncludePath) + ..\inc;..\..\inc;C:\local\boost_1_64_0;$(IncludePath) - ../inc;../../inc;$(VC_IncludePath);$(WindowsSDK_IncludePath) + ..\inc;..\..\inc;C:\local\boost_1_64_0;$(IncludePath) - ../inc;../../inc;$(VC_IncludePath);$(WindowsSDK_IncludePath) + ..\inc;..\..\inc;C:\local\boost_1_64_0;$(IncludePath) diff --git a/Intel8080/src/stdafx.h b/Intel8080/src/stdafx.h index 20f89d9..b22af77 100644 --- a/Intel8080/src/stdafx.h +++ b/Intel8080/src/stdafx.h @@ -13,6 +13,8 @@ #include #include +#include + #if defined(_M_X64) || defined(_M_IX86 ) # define HOST_LITTLE_ENDIAN #else diff --git a/Intel8080/test/Board.cpp b/Intel8080/test/Board.cpp index ff81f8f..00fcc7d 100644 --- a/Intel8080/test/Board.cpp +++ b/Intel8080/test/Board.cpp @@ -1,6 +1,5 @@ #include "stdafx.h" #include "Board.h" -#include "Disassembler.h" #include "Configuration.h" #include @@ -83,6 +82,6 @@ void Board::Cpu_ExecutingInstruction_Debug(const EightBit::Intel8080&) { std::cerr << EightBit::Disassembler::state(m_cpu) << "\t" - << EightBit::Disassembler::disassemble(m_cpu) + << m_disassembler.disassemble(m_cpu) << '\n'; } diff --git a/Intel8080/test/Board.h b/Intel8080/test/Board.h index 85aea27..1d7f7f3 100644 --- a/Intel8080/test/Board.h +++ b/Intel8080/test/Board.h @@ -1,12 +1,11 @@ #pragma once -//#include - #include "Memory.h" #include "InputOutput.h" #include "Intel8080.h" #include "Profiler.h" #include "EventArgs.h" +#include "Disassembler.h" class Configuration; @@ -24,6 +23,7 @@ private: EightBit::Memory m_memory; EightBit::InputOutput m_ports; EightBit::Intel8080 m_cpu; + EightBit::Disassembler m_disassembler; EightBit::Profiler m_profiler; void Cpu_ExecutingInstruction_Cpm(const EightBit::Intel8080& cpu);