mirror of
https://github.com/MoleskiCoder/EightBit.git
synced 2024-06-02 13:41:33 +00:00
Implement enough changes to build LR35902
This commit is contained in:
parent
1c0fb41027
commit
f3fe475d44
106
LR35902/inc/Bus.h
Normal file
106
LR35902/inc/Bus.h
Normal file
|
@ -0,0 +1,106 @@
|
|||
#pragma once
|
||||
|
||||
#include "Memory.h"
|
||||
|
||||
class Bus : public EightBit::Memory {
|
||||
public:
|
||||
|
||||
enum {
|
||||
TotalLineCount = 154
|
||||
};
|
||||
|
||||
enum {
|
||||
VideoRam = 0x8000
|
||||
};
|
||||
|
||||
enum {
|
||||
|
||||
BASE = 0xFF00,
|
||||
|
||||
// Port/Mode Registers
|
||||
P1 = 0x0,
|
||||
SB = 0x1,
|
||||
SC = 0x2,
|
||||
DIV = 0x4,
|
||||
TIMA = 0x5,
|
||||
TMA = 0x6,
|
||||
TAC = 0x7,
|
||||
|
||||
// Interrupt Flags
|
||||
IF = 0xF,
|
||||
IE = 0xFF,
|
||||
|
||||
// LCD Display Registers
|
||||
LCDC = 0x40,
|
||||
STAT = 0x41,
|
||||
SCY = 0x42,
|
||||
SCX = 0x43,
|
||||
LY = 0x44,
|
||||
LYC = 0x45,
|
||||
DMA = 0x46,
|
||||
BGP = 0x47,
|
||||
OBP0 = 0x48,
|
||||
OBP1 = 0x49,
|
||||
WY = 0x4A,
|
||||
WX = 0x4B,
|
||||
|
||||
// Sound Registers
|
||||
NR10 = 0x10,
|
||||
NR11 = 0x11,
|
||||
NR12 = 0x12,
|
||||
NR13 = 0x13,
|
||||
NR14 = 0x14,
|
||||
NR21 = 0x16,
|
||||
NR22 = 0x17,
|
||||
NR23 = 0x18,
|
||||
NR24 = 0x19,
|
||||
NR30 = 0x1A,
|
||||
NR31 = 0x1B,
|
||||
NR32 = 0x1C,
|
||||
NR33 = 0x1D,
|
||||
NR34 = 0x1E,
|
||||
NR41 = 0x20,
|
||||
NR42 = 0x21,
|
||||
NR43 = 0x22,
|
||||
NR44 = 0x23,
|
||||
NR50 = 0x24,
|
||||
NR51 = 0x25,
|
||||
NR52 = 0x26,
|
||||
|
||||
WPRAM_START = 0x30,
|
||||
WPRAM_END = 0x3F,
|
||||
|
||||
// Boot rom control
|
||||
BOOT_DISABLE = 0x50,
|
||||
};
|
||||
|
||||
Bus();
|
||||
|
||||
void reset();
|
||||
|
||||
uint8_t& REG(int offset) {
|
||||
ADDRESS().word = BASE + offset;
|
||||
return Memory::reference();
|
||||
}
|
||||
|
||||
void incrementLY() {
|
||||
REG(LY) = (REG(LY) + 1) % TotalLineCount;
|
||||
}
|
||||
|
||||
void resetLY() {
|
||||
REG(LY) = 0;
|
||||
}
|
||||
|
||||
void loadBootRom(const std::string& path);
|
||||
|
||||
bool isBootRom(uint16_t address) const {
|
||||
return (address < m_boot.size()) && (peek(BASE + BOOT_DISABLE) == 0);
|
||||
}
|
||||
|
||||
virtual uint8_t peek(uint16_t address) const;
|
||||
|
||||
virtual uint8_t& reference();
|
||||
|
||||
private:
|
||||
std::array<uint8_t, 0x100> m_boot;
|
||||
};
|
|
@ -3,8 +3,9 @@
|
|||
#include <cstdint>
|
||||
|
||||
#include "Processor.h"
|
||||
#include "Bus.h"
|
||||
|
||||
class LR35902 : public Processor {
|
||||
class LR35902 : public EightBit::Processor {
|
||||
public:
|
||||
enum StatusBits {
|
||||
ZF = Bit7,
|
||||
|
@ -15,7 +16,7 @@ public:
|
|||
|
||||
LR35902(Bus& memory);
|
||||
|
||||
Signal<LR35902> ExecutingInstruction;
|
||||
EightBit::Signal<LR35902> ExecutingInstruction;
|
||||
|
||||
void stop() { m_stopped = true; }
|
||||
void start() { m_stopped = false; }
|
||||
|
@ -33,7 +34,7 @@ public:
|
|||
|
||||
// Mutable access to processor!!
|
||||
|
||||
register16_t& AF() {
|
||||
EightBit::register16_t& AF() {
|
||||
m_accumulatorFlag.low &= 0xf0;
|
||||
return m_accumulatorFlag;
|
||||
}
|
||||
|
@ -41,21 +42,21 @@ public:
|
|||
uint8_t& A() { return AF().high; }
|
||||
uint8_t& F() { return AF().low; }
|
||||
|
||||
register16_t& BC() {
|
||||
EightBit::register16_t& BC() {
|
||||
return m_registers[BC_IDX];
|
||||
}
|
||||
|
||||
uint8_t& B() { return BC().high; }
|
||||
uint8_t& C() { return BC().low; }
|
||||
|
||||
register16_t& DE() {
|
||||
EightBit::register16_t& DE() {
|
||||
return m_registers[DE_IDX];
|
||||
}
|
||||
|
||||
uint8_t& D() { return DE().high; }
|
||||
uint8_t& E() { return DE().low; }
|
||||
|
||||
register16_t& HL() {
|
||||
EightBit::register16_t& HL() {
|
||||
return m_registers[HL_IDX];
|
||||
}
|
||||
|
||||
|
@ -68,8 +69,8 @@ public:
|
|||
private:
|
||||
enum { BC_IDX, DE_IDX, HL_IDX };
|
||||
|
||||
std::array<register16_t, 3> m_registers;
|
||||
register16_t m_accumulatorFlag;
|
||||
std::array<EightBit::register16_t, 3> m_registers;
|
||||
EightBit::register16_t m_accumulatorFlag;
|
||||
|
||||
bool m_ime;
|
||||
|
||||
|
@ -80,6 +81,12 @@ private:
|
|||
std::array<bool, 8> m_halfCarryTableAdd = { { false, false, true, false, true, false, true, true } };
|
||||
std::array<bool, 8> m_halfCarryTableSub = { { false, true, true, true, false, false, false, true } };
|
||||
|
||||
EightBit::register16_t fetchWord() {
|
||||
EightBit::register16_t returned;
|
||||
Processor::fetchWord(returned);
|
||||
return returned;
|
||||
}
|
||||
|
||||
int fetchExecute() {
|
||||
return execute(fetchByte());
|
||||
}
|
||||
|
@ -110,28 +117,29 @@ private:
|
|||
case 5:
|
||||
return L();
|
||||
case 6:
|
||||
return m_memory.reference(HL().word);
|
||||
m_memory.ADDRESS() = HL();
|
||||
return m_memory.reference();
|
||||
case 7:
|
||||
return A();
|
||||
}
|
||||
throw std::logic_error("Unhandled registry mechanism");
|
||||
}
|
||||
|
||||
uint16_t& RP(int rp) {
|
||||
EightBit::register16_t& RP(int rp) {
|
||||
switch (rp) {
|
||||
case 3:
|
||||
return sp;
|
||||
default:
|
||||
return m_registers[rp].word;
|
||||
return m_registers[rp];
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t& RP2(int rp) {
|
||||
EightBit::register16_t& RP2(int rp) {
|
||||
switch (rp) {
|
||||
case 3:
|
||||
return AF().word;
|
||||
return AF();
|
||||
default:
|
||||
return m_registers[rp].word;
|
||||
return m_registers[rp];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
83
LR35902/inc/StatusFlags.h
Normal file
83
LR35902/inc/StatusFlags.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <cstdint>
|
||||
|
||||
struct StatusFlags {
|
||||
|
||||
bool SF;
|
||||
bool ZF;
|
||||
bool YF;
|
||||
bool HF;
|
||||
bool XF;
|
||||
bool PF;
|
||||
bool NF;
|
||||
bool CF;
|
||||
|
||||
enum StatusBits {
|
||||
Sign = 0x80, // SF
|
||||
Zero = 0x40, // ZF
|
||||
YFlag = 0x20, // YF
|
||||
HalfCarry = 0x10, // HC
|
||||
XFlag= 0x8, // XF
|
||||
Parity = 0x4, // PF
|
||||
Overflow = 0x4, // PF
|
||||
Subtract = 0x2, // NF
|
||||
Carry = 0x1, // CF
|
||||
};
|
||||
|
||||
StatusFlags(uint8_t value = 0) {
|
||||
SF = (value & StatusBits::Sign) != 0;
|
||||
ZF = (value & StatusBits::Zero) != 0;
|
||||
YF = (value & StatusBits::YFlag) != 0;
|
||||
HF = (value & StatusBits::HalfCarry) != 0;
|
||||
XF = (value & StatusBits::XFlag) != 0;
|
||||
PF = (value & StatusBits::Parity) != 0; // parity/overflow
|
||||
NF = (value & StatusBits::Subtract) != 0;
|
||||
CF = (value & StatusBits::Carry) != 0;
|
||||
}
|
||||
|
||||
operator uint8_t() const {
|
||||
|
||||
uint8_t flags = 0;
|
||||
|
||||
if (SF)
|
||||
flags |= StatusBits::Sign;
|
||||
|
||||
if (ZF)
|
||||
flags |= StatusBits::Zero;
|
||||
|
||||
if (YF)
|
||||
flags |= StatusBits::YFlag;
|
||||
|
||||
if (HF)
|
||||
flags |= StatusBits::HalfCarry;
|
||||
|
||||
if (XF)
|
||||
flags |= StatusBits::XFlag;
|
||||
|
||||
if (PF)
|
||||
flags |= StatusBits::Parity;
|
||||
|
||||
if (NF)
|
||||
flags |= StatusBits::Subtract;
|
||||
|
||||
if (CF)
|
||||
flags |= StatusBits::Carry;
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
operator std::string() const {
|
||||
std::string returned;
|
||||
returned += SF ? "S" : "-";
|
||||
returned += ZF ? "Z" : "-";
|
||||
returned += YF ? "Y" : "-";
|
||||
returned += HF ? "H" : "-";
|
||||
returned += XF ? "X" : "-";
|
||||
returned += PF ? "P" : "-";
|
||||
returned += NF ? "N" : "-";
|
||||
returned += CF ? "C" : "-";
|
||||
return returned;
|
||||
}
|
||||
};
|
32
LR35902/src/Bus.cpp
Normal file
32
LR35902/src/Bus.cpp
Normal file
|
@ -0,0 +1,32 @@
|
|||
#include "stdafx.h"
|
||||
#include "Bus.h"
|
||||
|
||||
Bus::Bus()
|
||||
: Memory(0xffff) {
|
||||
}
|
||||
|
||||
void Bus::reset() {
|
||||
REG(NR52) = 0xf1;
|
||||
REG(LCDC) = 0x91;
|
||||
}
|
||||
|
||||
void Bus::loadBootRom(const std::string& path) {
|
||||
auto size = loadMemory(path, 0);
|
||||
if (size != 0x100)
|
||||
throw std::runtime_error("Incorrectly sized boot ROM");
|
||||
std::copy_n(m_bus.cbegin(), size, m_boot.begin());
|
||||
}
|
||||
|
||||
uint8_t& Bus::reference() {
|
||||
auto effective = effectiveAddress(ADDRESS().word);
|
||||
if (isBootRom(effective))
|
||||
return placeDATA(m_boot[effective]);
|
||||
return Memory::reference();
|
||||
}
|
||||
|
||||
uint8_t Bus::peek(uint16_t address) const {
|
||||
auto effective = effectiveAddress(address);
|
||||
if (isBootRom(effective))
|
||||
return m_boot[effective];
|
||||
return m_bus[effective];
|
||||
}
|
|
@ -34,9 +34,9 @@ std::string Disassembler::state(LR35902& cpu) {
|
|||
std::ostringstream output;
|
||||
|
||||
output
|
||||
<< "PC=" << hex(pc)
|
||||
<< "PC=" << hex(pc.word)
|
||||
<< " "
|
||||
<< "SP=" << hex(sp)
|
||||
<< "SP=" << hex(sp.word)
|
||||
<< " " << "A=" << hex(a) << " " << "F=" << flags(f)
|
||||
<< " " << "B=" << hex(b) << " " << "C=" << hex(c)
|
||||
<< " " << "D=" << hex(d) << " " << "E=" << hex(e)
|
||||
|
@ -142,7 +142,7 @@ std::string Disassembler::alu(int which) {
|
|||
std::string Disassembler::disassemble(LR35902& cpu) {
|
||||
m_prefixCB = false;
|
||||
std::ostringstream output;
|
||||
disassemble(output, cpu, cpu.getProgramCounter());
|
||||
disassemble(output, cpu, cpu.getProgramCounter().word);
|
||||
return output.str();
|
||||
}
|
||||
|
||||
|
@ -162,7 +162,7 @@ void Disassembler::disassemble(std::ostringstream& output, LR35902& cpu, uint16_
|
|||
auto q = (y & 1);
|
||||
|
||||
auto immediate = memory.peek(pc + 1);
|
||||
auto absolute = cpu.getWord(pc + 1);
|
||||
auto absolute = memory.peekWord(pc + 1);
|
||||
auto displacement = (int8_t)immediate;
|
||||
auto relative = pc + displacement + 2;
|
||||
auto indexedImmediate = memory.peek(pc + 1);
|
||||
|
@ -517,10 +517,10 @@ std::string Disassembler::flags(uint8_t value) {
|
|||
<< flag(value, LR35902::NF, "N")
|
||||
<< flag(value, LR35902::HC, "H")
|
||||
<< flag(value, LR35902::CF, "C")
|
||||
<< flag(value, Processor::Bit3, "+")
|
||||
<< flag(value, Processor::Bit2, "+")
|
||||
<< flag(value, Processor::Bit1, "+")
|
||||
<< flag(value, Processor::Bit0, "+");
|
||||
<< flag(value, EightBit::Processor::Bit3, "+")
|
||||
<< flag(value, EightBit::Processor::Bit2, "+")
|
||||
<< flag(value, EightBit::Processor::Bit1, "+")
|
||||
<< flag(value, EightBit::Processor::Bit0, "+");
|
||||
return output.str();
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ LR35902::LR35902(Bus& memory)
|
|||
|
||||
void LR35902::reset() {
|
||||
Processor::reset();
|
||||
setStackPointer(0xfffe);
|
||||
sp.word = 0xfffe;
|
||||
di();
|
||||
}
|
||||
|
||||
|
@ -60,13 +60,13 @@ void LR35902::postDecrement(uint8_t value) {
|
|||
|
||||
void LR35902::restart(uint8_t address) {
|
||||
pushWord(pc);
|
||||
pc = address;
|
||||
pc.word = address;
|
||||
}
|
||||
|
||||
void LR35902::jrConditional(int conditional) {
|
||||
auto offset = (int8_t)fetchByte();
|
||||
if (conditional) {
|
||||
pc += offset;
|
||||
pc.word += offset;
|
||||
cycles++;
|
||||
}
|
||||
}
|
||||
|
@ -121,22 +121,25 @@ void LR35902::jumpConditionalFlag(int flag) {
|
|||
cycles--; // Giving 8 cycles
|
||||
break;
|
||||
case 5: // GB: LD (nn),A
|
||||
m_memory.set(fetchWord(), A());
|
||||
m_memory.ADDRESS() = fetchWord();
|
||||
m_memory.reference() = A();
|
||||
cycles++; // Giving 16 cycles
|
||||
break;
|
||||
case 6: // GB: LD A,(FF00 + C)
|
||||
A() = m_memory.get(0xff00 + C());
|
||||
m_memory.ADDRESS().word = 0xff00 + C();
|
||||
A() = m_memory.reference();
|
||||
cycles--; // 8 cycles
|
||||
break;
|
||||
case 7: // GB: LD A,(nn)
|
||||
A() = m_memory.get(fetchWord());
|
||||
m_memory.ADDRESS() = fetchWord();
|
||||
A() = m_memory.reference();
|
||||
cycles++; // Giving 16 cycles
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void LR35902::ret() {
|
||||
pc = popWord();
|
||||
popWord(pc);
|
||||
}
|
||||
|
||||
void LR35902::reti() {
|
||||
|
@ -172,10 +175,10 @@ void LR35902::returnConditionalFlag(int flag) {
|
|||
case 5: { // GB: ADD SP,dd
|
||||
auto before = sp;
|
||||
auto value = fetchByte();
|
||||
sp += (int8_t)value;
|
||||
sp.word += (int8_t)value;
|
||||
clearFlag(ZF | NF);
|
||||
setFlag(CF, sp & Bit16);
|
||||
adjustHalfCarryAdd(Memory::highByte(before), value, Memory::highByte(sp));
|
||||
setFlag(CF, sp.word & Bit16);
|
||||
adjustHalfCarryAdd(before.high, value, sp.high);
|
||||
}
|
||||
cycles += 2; // 16 cycles
|
||||
break;
|
||||
|
@ -186,11 +189,10 @@ void LR35902::returnConditionalFlag(int flag) {
|
|||
case 7: { // GB: LD HL,SP + dd
|
||||
auto before = sp;
|
||||
auto value = fetchByte();
|
||||
uint16_t result = before + (int8_t)value;
|
||||
HL().word = result;
|
||||
HL().word = before.word + (int8_t)value;
|
||||
clearFlag(ZF | NF);
|
||||
setFlag(CF, result & Bit16);
|
||||
adjustHalfCarryAdd(Memory::highByte(before), value, Memory::highByte(result));
|
||||
setFlag(CF, HL().word & Bit16);
|
||||
adjustHalfCarryAdd(before.high, value, HL().high);
|
||||
}
|
||||
cycles++; // 12 cycles
|
||||
break;
|
||||
|
@ -198,16 +200,14 @@ void LR35902::returnConditionalFlag(int flag) {
|
|||
}
|
||||
|
||||
void LR35902::call(uint16_t address) {
|
||||
pushWord(pc + 2);
|
||||
pc = address;
|
||||
pushWord(pc);
|
||||
pc.word = address;
|
||||
}
|
||||
|
||||
void LR35902::callConditional(uint16_t address, int condition) {
|
||||
if (condition) {
|
||||
call(address);
|
||||
cycles += 3;
|
||||
} else {
|
||||
pc += 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -238,14 +238,14 @@ uint16_t LR35902::sbc(uint16_t value) {
|
|||
|
||||
auto hl = RP(HL_IDX);
|
||||
|
||||
auto high = Memory::highByte(hl);
|
||||
auto highValue = Memory::highByte(value);
|
||||
auto high = hl.high;
|
||||
auto highValue = EightBit::Memory::highByte(value);
|
||||
auto applyCarry = F() & CF;
|
||||
|
||||
uint32_t result = (int)hl - (int)value;
|
||||
uint32_t result = (int)hl.word - (int)value;
|
||||
if (applyCarry)
|
||||
--result;
|
||||
auto highResult = Memory::highByte(result);
|
||||
auto highResult = EightBit::Memory::highByte(result);
|
||||
|
||||
adjustZero(result);
|
||||
adjustHalfCarrySub(high, highValue, highResult);
|
||||
|
@ -260,14 +260,14 @@ uint16_t LR35902::adc(uint16_t value) {
|
|||
|
||||
auto hl = RP(HL_IDX);
|
||||
|
||||
auto high = Memory::highByte(hl);
|
||||
auto highValue = Memory::highByte(value);
|
||||
auto high = hl.high;
|
||||
auto highValue = EightBit::Memory::highByte(value);
|
||||
auto applyCarry = F() & CF;
|
||||
|
||||
uint32_t result = (int)hl + (int)value;
|
||||
uint32_t result = (int)hl.word + (int)value;
|
||||
if (applyCarry)
|
||||
++result;
|
||||
auto highResult = Memory::highByte(result);
|
||||
auto highResult = EightBit::Memory::highByte(result);
|
||||
|
||||
adjustZero(result);
|
||||
adjustHalfCarryAdd(high, highValue, highResult);
|
||||
|
@ -282,12 +282,12 @@ uint16_t LR35902::add(uint16_t value) {
|
|||
|
||||
auto hl = RP(HL_IDX);
|
||||
|
||||
auto high = Memory::highByte(hl);
|
||||
auto highValue = Memory::highByte(value);
|
||||
auto high = hl.high;
|
||||
auto highValue = EightBit::Memory::highByte(value);
|
||||
|
||||
uint32_t result = (int)hl + (int)value;
|
||||
uint32_t result = (int)hl.word + (int)value;
|
||||
|
||||
auto highResult = Memory::highByte(result);
|
||||
auto highResult = EightBit::Memory::highByte(result);
|
||||
|
||||
clearFlag(NF);
|
||||
setFlag(CF, result & Bit16);
|
||||
|
@ -304,7 +304,7 @@ void LR35902::sub(uint8_t& operand, uint8_t value, bool carry) {
|
|||
if (carry && (F() & CF))
|
||||
--result;
|
||||
|
||||
operand = Memory::lowByte(result);
|
||||
operand = EightBit::Memory::lowByte(result);
|
||||
|
||||
adjustZero(operand);
|
||||
adjustHalfCarrySub(before, value, result);
|
||||
|
@ -328,7 +328,7 @@ void LR35902::add(uint8_t& operand, uint8_t value, bool carry) {
|
|||
if (carry && (F() & CF))
|
||||
++result;
|
||||
|
||||
operand = Memory::lowByte(result);
|
||||
operand = EightBit::Memory::lowByte(result);
|
||||
|
||||
adjustZero(operand);
|
||||
adjustHalfCarryAdd(before, value, result);
|
||||
|
@ -625,7 +625,7 @@ void LR35902::executeOther(int x, int y, int z, int p, int q) {
|
|||
cycles++;
|
||||
break;
|
||||
case 1: // GB: LD (nn),SP
|
||||
m_memory.setWord(fetchWord(), sp);
|
||||
m_memory.setWord(fetchWord().word, sp);
|
||||
cycles += 5;
|
||||
break;
|
||||
case 2: // GB: STOP
|
||||
|
@ -649,7 +649,7 @@ void LR35902::executeOther(int x, int y, int z, int p, int q) {
|
|||
cycles += 3;
|
||||
break;
|
||||
case 1: // ADD HL,rp
|
||||
RP(HL_IDX) = add(RP(p));
|
||||
RP(HL_IDX).word = add(RP(p).word);
|
||||
cycles += 2;
|
||||
break;
|
||||
}
|
||||
|
@ -701,10 +701,10 @@ void LR35902::executeOther(int x, int y, int z, int p, int q) {
|
|||
case 3: // 16-bit INC/DEC
|
||||
switch (q) {
|
||||
case 0: // INC rp
|
||||
++RP(p);
|
||||
++RP(p).word;
|
||||
break;
|
||||
case 1: // DEC rp
|
||||
--RP(p);
|
||||
--RP(p).word;
|
||||
break;
|
||||
}
|
||||
cycles += 2;
|
||||
|
@ -806,7 +806,7 @@ void LR35902::executeOther(int x, int y, int z, int p, int q) {
|
|||
case 1: // POP & various ops
|
||||
switch (q) {
|
||||
case 0: // POP rp2[p]
|
||||
RP2(p) = popWord();
|
||||
popWord(RP2(p));
|
||||
cycles += 3;
|
||||
break;
|
||||
case 1:
|
||||
|
@ -820,11 +820,11 @@ void LR35902::executeOther(int x, int y, int z, int p, int q) {
|
|||
cycles += 4;
|
||||
break;
|
||||
case 2: // JP HL
|
||||
pc = HL().word;
|
||||
pc = HL();
|
||||
cycles += 1;
|
||||
break;
|
||||
case 3: // LD SP,HL
|
||||
sp = HL().word;
|
||||
sp = HL();
|
||||
cycles += 2;
|
||||
break;
|
||||
}
|
||||
|
@ -855,7 +855,7 @@ void LR35902::executeOther(int x, int y, int z, int p, int q) {
|
|||
}
|
||||
break;
|
||||
case 4: // Conditional call: CALL cc[y], nn
|
||||
callConditionalFlag(getWord(pc), y);
|
||||
callConditionalFlag(fetchWord().word, y);
|
||||
cycles += 3;
|
||||
break;
|
||||
case 5: // PUSH & various ops
|
||||
|
@ -867,7 +867,7 @@ void LR35902::executeOther(int x, int y, int z, int p, int q) {
|
|||
case 1:
|
||||
switch (p) {
|
||||
case 0: // CALL nn
|
||||
callConditional(getWord(pc), true);
|
||||
callConditional(fetchWord().word, true);
|
||||
cycles += 3;
|
||||
break;
|
||||
}
|
||||
|
|
166
LR35902/src/LR35902.vcxproj
Normal file
166
LR35902/src/LR35902.vcxproj
Normal file
|
@ -0,0 +1,166 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{7730ECF5-8206-4ECB-BA6B-6B5CFE50CFB2}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>LR35902</RootNamespace>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<IncludePath>..\inc;..\..\inc;C:\local\boost_1_64_0;C:\local\SDL2-2.0.5\include;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<IncludePath>..\inc;..\..\inc;C:\local\boost_1_64_0;C:\local\SDL2-2.0.5\include;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<IncludePath>..\inc;..\..\inc;C:\local\boost_1_64_0;C:\local\SDL2-2.0.5\include;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<IncludePath>..\inc;..\..\inc;C:\local\boost_1_64_0;C:\local\SDL2-2.0.5\include;$(IncludePath)</IncludePath>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PrecompiledHeader>Use</PrecompiledHeader>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<SDLCheck>true</SDLCheck>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\inc\Bus.h" />
|
||||
<ClInclude Include="..\inc\Disassembler.h" />
|
||||
<ClInclude Include="..\inc\LR35902.h" />
|
||||
<ClInclude Include="..\inc\Profiler.h" />
|
||||
<ClInclude Include="stdafx.h" />
|
||||
<ClInclude Include="targetver.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Bus.cpp" />
|
||||
<ClCompile Include="Disassembler.cpp" />
|
||||
<ClCompile Include="LR35902.cpp" />
|
||||
<ClCompile Include="Profiler.cpp" />
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
|
||||
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
57
LR35902/src/LR35902.vcxproj.filters
Normal file
57
LR35902/src/LR35902.vcxproj.filters
Normal file
|
@ -0,0 +1,57 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="ReadMe.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="stdafx.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="targetver.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\inc\Disassembler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\inc\LR35902.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\inc\Profiler.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\inc\Bus.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="stdafx.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Disassembler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="LR35902.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Profiler.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Bus.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
1
LR35902/src/stdafx.cpp
Normal file
1
LR35902/src/stdafx.cpp
Normal file
|
@ -0,0 +1 @@
|
|||
#include "stdafx.h"
|
37
LR35902/src/stdafx.h
Normal file
37
LR35902/src/stdafx.h
Normal file
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <stdexcept>
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <vector>
|
||||
#include <array>
|
||||
#include <map>
|
||||
|
||||
#include <bitset>
|
||||
#include <string>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include <iostream>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
|
||||
#include <boost/format.hpp>
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#if SDL_BYTEORDER == SDL_LIL_ENDIAN
|
||||
#define HOST_LITTLE_ENDIAN
|
||||
#endif
|
||||
|
||||
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
|
||||
#define HOST_BIG_ENDIAN
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib, "SDL2.lib")
|
||||
#pragma comment(lib, "SDL2main.lib")
|
||||
#endif
|
15
inc/Memory.h
15
inc/Memory.h
|
@ -28,6 +28,15 @@ namespace EightBit {
|
|||
|
||||
class Memory {
|
||||
public:
|
||||
|
||||
static uint8_t highByte(uint16_t value) {
|
||||
return value >> 8;
|
||||
}
|
||||
|
||||
static uint8_t lowByte(uint16_t value) {
|
||||
return value & 0xff;
|
||||
}
|
||||
|
||||
Memory(uint16_t addressMask);
|
||||
|
||||
virtual register16_t& ADDRESS() { return m_address; }
|
||||
|
@ -62,10 +71,14 @@ namespace EightBit {
|
|||
virtual void setWord(uint16_t address, register16_t value);
|
||||
|
||||
virtual uint8_t& reference() {
|
||||
uint16_t effective = ADDRESS().word & m_addressMask;
|
||||
auto effective = effectiveAddress(ADDRESS().word);
|
||||
return m_locked[effective] ? placeDATA(m_bus[effective]) : referenceDATA(m_bus[effective]);
|
||||
}
|
||||
|
||||
virtual uint16_t effectiveAddress(uint16_t address) const {
|
||||
return address & m_addressMask;
|
||||
}
|
||||
|
||||
void clear();
|
||||
void loadRom(const std::string& path, uint16_t offset);
|
||||
void loadRam(const std::string& path, uint16_t offset);
|
||||
|
|
Loading…
Reference in New Issue
Block a user