mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2025-01-11 02:29:50 +00:00
Experimental decoding 6502 interpreter. Runs Klaus Dormann tests to completion.
Signed-off-by: Adrian.Conlon <adrian.conlon@gmail.com>
This commit is contained in:
parent
8c81a27224
commit
7ff7ee040f
@ -242,6 +242,98 @@ namespace EightBit {
|
||||
|
||||
#pragma endregion References
|
||||
|
||||
#pragma region 6502 addressing mode switching
|
||||
|
||||
uint8_t& AM_00(int bbb) {
|
||||
switch (bbb) {
|
||||
case 0b000:
|
||||
return AM_Immediate();
|
||||
case 0b001:
|
||||
return AM_ZeroPage();
|
||||
case 0b011:
|
||||
return AM_Absolute();
|
||||
case 0b101:
|
||||
return AM_ZeroPageX();
|
||||
case 0b111:
|
||||
return AM_AbsoluteX();
|
||||
case 0b010:
|
||||
case 0b100:
|
||||
case 0b110:
|
||||
throw std::domain_error("Illegal addressing mode");
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t& AM_01(int bbb) {
|
||||
switch (bbb) {
|
||||
case 0b000:
|
||||
return AM_IndexedIndirectX();
|
||||
case 0b001:
|
||||
return AM_ZeroPage();
|
||||
case 0b010:
|
||||
return AM_Immediate();
|
||||
case 0b011:
|
||||
return AM_Absolute();
|
||||
case 0b100:
|
||||
return AM_IndirectIndexedY();
|
||||
case 0b101:
|
||||
return AM_ZeroPageX();
|
||||
case 0b110:
|
||||
return AM_AbsoluteY();
|
||||
case 0b111:
|
||||
return AM_AbsoluteX();
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t& AM_10(int bbb) {
|
||||
switch (bbb) {
|
||||
case 0b000:
|
||||
return AM_Immediate();
|
||||
case 0b001:
|
||||
return AM_ZeroPage();
|
||||
case 0b010:
|
||||
return AM_A();
|
||||
case 0b011:
|
||||
return AM_Absolute();
|
||||
case 0b101:
|
||||
return AM_ZeroPageX();
|
||||
case 0b111:
|
||||
return AM_AbsoluteX();
|
||||
case 0b100:
|
||||
case 0b110:
|
||||
throw std::domain_error("Illegal addressing mode");
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t& AM_10_x(int bbb, bool x = false) {
|
||||
switch (bbb) {
|
||||
case 0b000:
|
||||
return AM_Immediate();
|
||||
case 0b001:
|
||||
return AM_ZeroPage();
|
||||
case 0b010:
|
||||
return AM_A();
|
||||
case 0b011:
|
||||
return AM_Absolute();
|
||||
case 0b101:
|
||||
return AM_ZeroPageY();
|
||||
case 0b111:
|
||||
return AM_AbsoluteY();
|
||||
case 0b100:
|
||||
case 0b110:
|
||||
throw std::domain_error("Illegal addressing mode");
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma endregion 6502 addressing mode switching
|
||||
|
||||
#pragma endregion 6502 addressing modes
|
||||
|
||||
void DEC(uint8_t& output);
|
||||
|
@ -64,11 +64,265 @@ void EightBit::MOS6502::Interrupt(uint16_t vector) {
|
||||
}
|
||||
|
||||
int EightBit::MOS6502::Execute(uint8_t cell) {
|
||||
|
||||
cycles = 0;
|
||||
const auto& instruction = instructions[cell];
|
||||
const auto& method = instruction.vector;
|
||||
method();
|
||||
cycles += instruction.count;
|
||||
|
||||
// http://www.llx.com/~nparker/a2/opcodes.html
|
||||
|
||||
// Most instructions that explicitly reference memory
|
||||
// locations have bit patterns of the form aaabbbcc.
|
||||
// The aaa and cc bits determine the opcode, and the bbb
|
||||
// bits determine the addressing mode.
|
||||
|
||||
auto aaa = (cell & 0b11100000) >> 5;
|
||||
auto bbb = (cell & 0b00011100) >> 2;
|
||||
auto cc = (cell & 0b00000011);
|
||||
|
||||
switch (cc) {
|
||||
case 0b00:
|
||||
switch (aaa) {
|
||||
case 0b000:
|
||||
switch (bbb) {
|
||||
case 0b000: // BRK
|
||||
BRK_imp();
|
||||
break;
|
||||
case 0b010: // PHP
|
||||
PHP_imp();
|
||||
break;
|
||||
case 0b100: // BPL
|
||||
BPL_rel();
|
||||
break;
|
||||
case 0b110: // CLC
|
||||
CLC_imp();
|
||||
break;
|
||||
default:
|
||||
throw std::domain_error("Illegal instruction");
|
||||
}
|
||||
break;
|
||||
case 0b001:
|
||||
switch (bbb) {
|
||||
case 0b000: // JSR
|
||||
JSR_abs();
|
||||
break;
|
||||
case 0b010: // PLP
|
||||
PLP_imp();
|
||||
break;
|
||||
case 0b100: // BMI
|
||||
BMI_rel();
|
||||
break;
|
||||
case 0b110: // SEC
|
||||
SEC_imp();
|
||||
break;
|
||||
default: // BIT
|
||||
BIT(AM_00(bbb));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0b010:
|
||||
switch (bbb) {
|
||||
case 0b000: // RTI
|
||||
RTI_imp();
|
||||
break;
|
||||
case 0b010: // PHA
|
||||
PHA_imp();
|
||||
break;
|
||||
case 0b011: // JMP
|
||||
JMP_abs();
|
||||
break;
|
||||
case 0b100: // BVC
|
||||
BVC_rel();
|
||||
break;
|
||||
case 0b110: // BVC
|
||||
CLI_imp();
|
||||
break;
|
||||
default:
|
||||
throw std::domain_error("Illegal addressing mode");
|
||||
}
|
||||
break;
|
||||
case 0b011:
|
||||
switch (bbb) {
|
||||
case 0b000: // RTS
|
||||
RTS_imp();
|
||||
break;
|
||||
case 0b010: // PLA
|
||||
PLA_imp();
|
||||
break;
|
||||
case 0b011: // JMP (abs)
|
||||
JMP_ind();
|
||||
break;
|
||||
case 0b100: // BVS
|
||||
BVS_rel();
|
||||
break;
|
||||
case 0b110: // SEI
|
||||
SEI_imp();
|
||||
break;
|
||||
default:
|
||||
throw std::domain_error("Illegal addressing mode");
|
||||
}
|
||||
break;
|
||||
case 0b100:
|
||||
switch (bbb) {
|
||||
case 0b010: // DEY
|
||||
DEY_imp();
|
||||
break;
|
||||
case 0b100: // BCC
|
||||
BCC_rel();
|
||||
break;
|
||||
case 0b110: // TYA
|
||||
TYA_imp();
|
||||
break;
|
||||
default: // STY
|
||||
AM_00(bbb) = Y();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0b101:
|
||||
switch (bbb) {
|
||||
case 0b010: // TAY
|
||||
TAY_imp();
|
||||
break;
|
||||
case 0b100: // BCS
|
||||
BCS_rel();
|
||||
break;
|
||||
case 0b110: // CLV
|
||||
CLV_imp();
|
||||
break;
|
||||
default: // LDY
|
||||
LDY(AM_00(bbb));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0b110:
|
||||
switch (bbb) {
|
||||
case 0b010: // INY
|
||||
INY_imp();
|
||||
break;
|
||||
case 0b100: // BNE
|
||||
BNE_rel();
|
||||
break;
|
||||
case 0b110: // CLD
|
||||
CLD_imp();
|
||||
break;
|
||||
default: // CPY
|
||||
CPY(AM_00(bbb));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0b111:
|
||||
switch (bbb) {
|
||||
case 0b010: // INX
|
||||
INX_imp();
|
||||
break;
|
||||
case 0b100: // BEQ
|
||||
BEQ_rel();
|
||||
break;
|
||||
case 0b110: // SED
|
||||
SED_imp();
|
||||
break;
|
||||
default: // CPX
|
||||
CPX(AM_00(bbb));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0b01:
|
||||
switch (aaa) {
|
||||
case 0b000: // ORA
|
||||
ORA(AM_01(bbb));
|
||||
break;
|
||||
case 0b001: // AND
|
||||
AND(AM_01(bbb));
|
||||
break;
|
||||
case 0b010: // EOR
|
||||
EOR(AM_01(bbb));
|
||||
break;
|
||||
case 0b011: // ADC
|
||||
ADC(AM_01(bbb));
|
||||
break;
|
||||
case 0b100: // STA
|
||||
AM_01(bbb) = A();
|
||||
break;
|
||||
case 0b101: // LDA
|
||||
LDA(AM_01(bbb));
|
||||
break;
|
||||
case 0b110: // CMP
|
||||
CMP(AM_01(bbb));
|
||||
break;
|
||||
case 0b111: // SBC
|
||||
SBC(AM_01(bbb));
|
||||
break;
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
break;
|
||||
case 0b10:
|
||||
switch (aaa) {
|
||||
case 0b000: // ASL
|
||||
ASL(AM_10(bbb));
|
||||
break;
|
||||
case 0b001: // ROL
|
||||
ROL(AM_10(bbb));
|
||||
break;
|
||||
case 0b010: // LSR
|
||||
LSR(AM_10(bbb));
|
||||
break;
|
||||
case 0b011: // ROR
|
||||
ROR(AM_10(bbb));
|
||||
break;
|
||||
case 0b100:
|
||||
switch (bbb) {
|
||||
case 0b010: // TXA
|
||||
TXA_imp();
|
||||
break;
|
||||
case 0b110: // TXS
|
||||
TXS_imp();
|
||||
break;
|
||||
default: // STX
|
||||
AM_10_x(bbb) = X();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0b101:
|
||||
switch (bbb) {
|
||||
case 0b110: // TSX
|
||||
TSX_imp();
|
||||
break;
|
||||
default: // LDX
|
||||
LDX(AM_10_x(bbb));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0b110:
|
||||
switch (bbb) {
|
||||
case 0b010: // DEX
|
||||
DEX_imp();
|
||||
break;
|
||||
default: // DEC
|
||||
DEC(AM_10(bbb));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 0b111:
|
||||
switch (bbb) {
|
||||
case 0b010: // NOP
|
||||
NOP_imp();
|
||||
break;
|
||||
default: // INC
|
||||
INC(AM_10(bbb));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
break;
|
||||
case 0b11:
|
||||
throw std::domain_error("Illegal instruction group");
|
||||
default:
|
||||
__assume(0);
|
||||
}
|
||||
|
||||
return cycles;
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <string>
|
||||
#include <array>
|
||||
|
Loading…
x
Reference in New Issue
Block a user