mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2024-12-23 00:29:47 +00:00
Replace old i8080 disassembler with new (z80) style.
Signed-off-by: Adrian.Conlon <adrian.conlon@arup.com>
This commit is contained in:
parent
dfc02c7e54
commit
2ae4e8331e
@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <boost/format.hpp>
|
||||
|
||||
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);
|
||||
};
|
||||
}
|
@ -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<Intel8080> ExecutingInstruction;
|
||||
|
||||
const std::array<Instruction, 0x100>& getInstructions() const { return instructions; }
|
||||
|
||||
bool isInterruptable() const;
|
||||
|
||||
int interrupt(uint8_t value);
|
||||
@ -65,8 +49,6 @@ namespace EightBit {
|
||||
private:
|
||||
InputOutput& m_ports;
|
||||
|
||||
std::array<Instruction, 0x100> 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();
|
||||
};
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
@ -71,16 +71,16 @@
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<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 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 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 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>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
|
@ -13,6 +13,8 @@
|
||||
#include <vector>
|
||||
#include <bitset>
|
||||
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#if defined(_M_X64) || defined(_M_IX86 )
|
||||
# define HOST_LITTLE_ENDIAN
|
||||
#else
|
||||
|
@ -1,6 +1,5 @@
|
||||
#include "stdafx.h"
|
||||
#include "Board.h"
|
||||
#include "Disassembler.h"
|
||||
#include "Configuration.h"
|
||||
|
||||
#include <iostream>
|
||||
@ -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';
|
||||
}
|
||||
|
@ -1,12 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
//#include <string>
|
||||
|
||||
#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);
|
||||
|
Loading…
Reference in New Issue
Block a user