Implement enough changes to build LR35902

This commit is contained in:
Adrian.Conlon 2017-06-09 10:23:51 +01:00
parent 1c0fb41027
commit f3fe475d44
11 changed files with 567 additions and 64 deletions

106
LR35902/inc/Bus.h Normal file
View 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;
};

View File

@ -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
View 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
View 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];
}

View File

@ -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();
}

View File

@ -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
View 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>

View 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
View File

@ -0,0 +1 @@
#include "stdafx.h"

37
LR35902/src/stdafx.h Normal file
View 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

View File

@ -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);