mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2024-12-28 16:31:00 +00:00
112 lines
2.4 KiB
C++
112 lines
2.4 KiB
C++
|
#include "stdafx.h"
|
||
|
#include "Disassembler.h"
|
||
|
|
||
|
#include <sstream>
|
||
|
#include <iomanip>
|
||
|
#include <bitset>
|
||
|
|
||
|
#include "Memory.h"
|
||
|
#include "Intel8080.h"
|
||
|
#include "StatusFlags.h"
|
||
|
|
||
|
EightBit::Disassembler::Disassembler() {
|
||
|
}
|
||
|
|
||
|
std::string EightBit::Disassembler::state(Intel8080& cpu) {
|
||
|
|
||
|
auto pc = cpu.getProgramCounter();
|
||
|
auto sp = cpu.getStackPointer();
|
||
|
|
||
|
auto a = cpu.A();
|
||
|
auto f = cpu.F();
|
||
|
|
||
|
auto b = cpu.B();
|
||
|
auto c = cpu.C();
|
||
|
|
||
|
auto d = cpu.D();
|
||
|
auto e = cpu.E();
|
||
|
|
||
|
auto h = cpu.H();
|
||
|
auto l = cpu.L();
|
||
|
|
||
|
std::ostringstream output;
|
||
|
|
||
|
output
|
||
|
<< "PC=" << hex(pc.word)
|
||
|
<< " "
|
||
|
<< "SP=" << hex(sp.word)
|
||
|
<< " " << "A=" << hex(a) << " " << "F=" << (std::string)f
|
||
|
<< " " << "B=" << hex(b) << " " << "C=" << hex(c)
|
||
|
<< " " << "D=" << hex(d) << " " << "E=" << hex(e)
|
||
|
<< " " << "H=" << hex(h) << " " << "L=" << hex(l);
|
||
|
|
||
|
return output.str();
|
||
|
}
|
||
|
|
||
|
std::string EightBit::Disassembler::disassemble(Intel8080& cpu) {
|
||
|
|
||
|
const auto& memory = cpu.getMemory();
|
||
|
auto pc = cpu.getProgramCounter();
|
||
|
auto opcode = memory.peek(pc.word);
|
||
|
const auto& instruction = cpu.getInstructions()[opcode];
|
||
|
|
||
|
std::ostringstream output;
|
||
|
|
||
|
// hex opcode
|
||
|
output << hex(opcode);
|
||
|
|
||
|
// hex raw operand
|
||
|
switch (instruction.mode) {
|
||
|
case Intel8080::Immediate:
|
||
|
output << hex(memory.peek(pc.word + 1));
|
||
|
break;
|
||
|
case Intel8080::Absolute:
|
||
|
output << hex(memory.peek(pc.word + 1));
|
||
|
output << hex(memory.peek(pc.word + 2));
|
||
|
break;
|
||
|
default:
|
||
|
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(cpu.getWord(pc.word + 1).word);
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
return output.str();
|
||
|
}
|
||
|
|
||
|
std::string EightBit::Disassembler::hex(uint8_t value) {
|
||
|
std::ostringstream output;
|
||
|
output << std::hex << std::setw(2) << std::setfill('0') << (int)value;
|
||
|
return output.str();
|
||
|
}
|
||
|
|
||
|
std::string EightBit::Disassembler::hex(uint16_t value) {
|
||
|
std::ostringstream output;
|
||
|
output << std::hex << std::setw(4) << std::setfill('0') << (int)value;
|
||
|
return output.str();
|
||
|
}
|
||
|
|
||
|
std::string EightBit::Disassembler::binary(uint8_t value) {
|
||
|
std::ostringstream output;
|
||
|
output << std::bitset<8>(value);
|
||
|
return output.str();
|
||
|
}
|
||
|
|
||
|
std::string EightBit::Disassembler::invalid(uint8_t value) {
|
||
|
std::ostringstream output;
|
||
|
output << "Invalid instruction: " << hex(value) << "(" << binary(value) << ")";
|
||
|
return output.str();
|
||
|
}
|