CPU refactoring

This commit is contained in:
MrWint 2019-05-25 22:11:58 +02:00
parent a6aeef840a
commit 6020542182
8 changed files with 1406 additions and 2255 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,21 +1,21 @@
/***************************************************************************
* Copyright (C) 2007 by Sindre Aamås *
* aamas@stud.ntnu.no *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License version 2 for more details. *
* *
* You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
//
// Copyright (C) 2007 by sinamas <sinamas at users.sourceforge.net>
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2 as
// published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License version 2 for more details.
//
// You should have received a copy of the GNU General Public License
// version 2 along with this program; if not, write to the
// Free Software Foundation, Inc.,
// 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
//
#ifndef CPU_H
#define CPU_H
@ -25,18 +25,100 @@
namespace gambatte {
class CPU {
Memory memory;
public:
CPU();
long runFor(unsigned long cycles);
void setStatePtrs(SaveState &state);
void loadState(SaveState const &state);
void setLayers(unsigned mask) { mem_.setLayers(mask); }
void loadSavedata(const char *data) { mem_.loadSavedata(data); }
int saveSavedataLength() {return mem_.saveSavedataLength(); }
void saveSavedata(char *dest) { mem_.saveSavedata(dest); }
bool getMemoryArea(int which, unsigned char **data, int *length) { return mem_.getMemoryArea(which, data, length); }
void setVideoBuffer(uint_least32_t *videoBuf, std::ptrdiff_t pitch) {
mem_.setVideoBuffer(videoBuf, pitch);
}
void setInputGetter(unsigned (*getInput)()) {
mem_.setInputGetter(getInput);
}
void setReadCallback(MemoryCallback callback) {
mem_.setReadCallback(callback);
}
void setWriteCallback(MemoryCallback callback) {
mem_.setWriteCallback(callback);
}
void setExecCallback(MemoryCallback callback) {
mem_.setExecCallback(callback);
}
void setCDCallback(CDCallback cdc) {
mem_.setCDCallback(cdc);
}
void setTraceCallback(void (*callback)(void *)) {
tracecallback = callback;
}
void setScanlineCallback(void (*callback)(), int sl) {
mem_.setScanlineCallback(callback, sl);
}
void setRTCCallback(std::uint32_t (*callback)()) {
mem_.setRTCCallback(callback);
}
void setLinkCallback(void(*callback)()) {
mem_.setLinkCallback(callback);
}
LoadRes load(char const *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat) {
return mem_.loadROM(romfiledata, romfilelength, forceDmg, multicartCompat);
}
bool loaded() const { return mem_.loaded(); }
char const * romTitle() const { return mem_.romTitle(); }
void setSoundBuffer(uint_least32_t *buf) { mem_.setSoundBuffer(buf); }
std::size_t fillSoundBuffer() { return mem_.fillSoundBuffer(cycleCounter_); }
bool isCgb() const { return mem_.isCgb(); }
void setDmgPaletteColor(int palNum, int colorNum, unsigned long rgb32) {
mem_.setDmgPaletteColor(palNum, colorNum, rgb32);
}
void setCgbPalette(unsigned *lut) {
mem_.setCgbPalette(lut);
}
unsigned char* cgbBiosBuffer() { return mem_.cgbBiosBuffer(); }
unsigned char* dmgBiosBuffer() { return mem_.dmgBiosBuffer(); }
bool gbIsCgb() { return mem_.gbIsCgb(); }
unsigned char externalRead(unsigned short addr) {return mem_.peek(addr); }
void externalWrite(unsigned short addr, unsigned char val) {
mem_.write_nocb(addr, val, cycleCounter_);
}
int LinkStatus(int which) { return mem_.LinkStatus(which); }
void getRegs(int *dest);
void setInterruptAddresses(int *addrs, int numAddrs);
int getHitInterruptAddress();
private:
Memory mem_;
unsigned long cycleCounter_;
unsigned short PC;
unsigned short SP;
unsigned HF1, HF2, ZF, CF;
unsigned char A, B, C, D, E, /*F,*/ H, L;
bool skip;
unsigned short pc;
unsigned short sp;
unsigned hf1, hf2, zf, cf;
unsigned char a, b, c, d, e, /*f,*/ h, l;
bool skip_;
int *interruptAddresses;
int numInterruptAddresses;
@ -47,98 +129,6 @@ class CPU {
void (*tracecallback)(void *);
public:
CPU();
// void halt();
// unsigned interrupt(unsigned address, unsigned cycleCounter);
long runFor(unsigned long cycles);
void setStatePtrs(SaveState &state);
void loadState(const SaveState &state);
void setLayers(unsigned mask) { memory.setLayers(mask); }
void loadSavedata(const char *data) { memory.loadSavedata(data); }
int saveSavedataLength() {return memory.saveSavedataLength(); }
void saveSavedata(char *dest) { memory.saveSavedata(dest); }
bool getMemoryArea(int which, unsigned char **data, int *length) { return memory.getMemoryArea(which, data, length); }
void setVideoBuffer(uint_least32_t *const videoBuf, const int pitch) {
memory.setVideoBuffer(videoBuf, pitch);
}
void setInputGetter(unsigned (*getInput)()) {
memory.setInputGetter(getInput);
}
void setReadCallback(MemoryCallback callback) {
memory.setReadCallback(callback);
}
void setWriteCallback(MemoryCallback callback) {
memory.setWriteCallback(callback);
}
void setExecCallback(MemoryCallback callback) {
memory.setExecCallback(callback);
}
void setCDCallback(CDCallback cdc) {
memory.setCDCallback(cdc);
}
void setTraceCallback(void (*callback)(void *)) {
tracecallback = callback;
}
void setScanlineCallback(void (*callback)(), int sl) {
memory.setScanlineCallback(callback, sl);
}
void setRTCCallback(std::uint32_t (*callback)()) {
memory.setRTCCallback(callback);
}
void setLinkCallback(void(*callback)()) {
memory.setLinkCallback(callback);
}
LoadRes load(const char *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat) {
return memory.loadROM(romfiledata, romfilelength, forceDmg, multicartCompat);
}
bool loaded() const { return memory.loaded(); }
const char * romTitle() const { return memory.romTitle(); }
void setSoundBuffer(uint_least32_t *const buf) { memory.setSoundBuffer(buf); }
unsigned fillSoundBuffer() { return memory.fillSoundBuffer(cycleCounter_); }
bool isCgb() const { return memory.isCgb(); }
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned rgb32) {
memory.setDmgPaletteColor(palNum, colorNum, rgb32);
}
void setCgbPalette(unsigned *lut) {
memory.setCgbPalette(lut);
}
unsigned char* cgbBiosBuffer() { return memory.cgbBiosBuffer(); }
unsigned char* dmgBiosBuffer() { return memory.dmgBiosBuffer(); }
bool gbIsCgb() { return memory.gbIsCgb(); }
//unsigned char ExternalRead(unsigned short addr) { return memory.read(addr, cycleCounter_); }
unsigned char ExternalRead(unsigned short addr) { return memory.peek(addr); }
void ExternalWrite(unsigned short addr, unsigned char val) { memory.write_nocb(addr, val, cycleCounter_); }
int LinkStatus(int which) { return memory.LinkStatus(which); }
void GetRegs(int *dest);
void SetInterruptAddresses(int *addrs, int numAddrs);
int GetHitInterruptAddress();
template<bool isReader>void SyncState(NewState *ns);
};

View File

@ -200,14 +200,14 @@ bool GB::getMemoryArea(int which, unsigned char **data, int *length) {
unsigned char GB::ExternalRead(unsigned short addr) {
if (p_->cpu.loaded())
return p_->cpu.ExternalRead(addr);
return p_->cpu.externalRead(addr);
else
return 0;
}
void GB::ExternalWrite(unsigned short addr, unsigned char val) {
if (p_->cpu.loaded())
p_->cpu.ExternalWrite(addr, val);
p_->cpu.externalWrite(addr, val);
}
@ -235,17 +235,17 @@ int GB::LinkStatus(int which) {
}
void GB::GetRegs(int *dest) {
p_->cpu.GetRegs(dest);
p_->cpu.getRegs(dest);
}
void GB::SetInterruptAddresses(int *addrs, int numAddrs)
{
p_->cpu.SetInterruptAddresses(addrs, numAddrs);
p_->cpu.setInterruptAddresses(addrs, numAddrs);
}
int GB::GetHitInterruptAddress()
{
return p_->cpu.GetHitInterruptAddress();
return p_->cpu.getHitInterruptAddress();
}
SYNCFUNC(GB)

View File

@ -1167,16 +1167,16 @@ void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbM
};
state.cpu.cycleCounter = 8;
state.cpu.PC = 0;
state.cpu.SP = 0;
state.cpu.A = 0;
state.cpu.B = 0;
state.cpu.C = 0;
state.cpu.D = 0;
state.cpu.E = 0;
state.cpu.F = 0;
state.cpu.H = 0;
state.cpu.L = 0;
state.cpu.pc = 0;
state.cpu.sp = 0;
state.cpu.a = 0;
state.cpu.b = 0;
state.cpu.c = 0;
state.cpu.d = 0;
state.cpu.e = 0;
state.cpu.f = 0;
state.cpu.h = 0;
state.cpu.l = 0;
state.cpu.skip = false;
state.mem.biosMode = true;
state.mem.cgbSwitching = false;

View File

@ -471,7 +471,7 @@ unsigned Memory::nontrivial_ff_read(const unsigned P, const unsigned long cycleC
if (lastOamDmaUpdate != disabled_time)
updateOamDma(cycleCounter);
switch (P & 0x7F) {
switch (P) {
case 0x00:
updateInput();
break;
@ -531,7 +531,7 @@ unsigned Memory::nontrivial_ff_read(const unsigned P, const unsigned long cycleC
default: break;
}
return ioamhram[P - 0xFE00];
return ioamhram[P + 0x100];
}
static bool isInOamDmaConflictArea(const OamDmaSrc oamDmaSrc, const unsigned addr, const bool cgb) {
@ -589,8 +589,9 @@ unsigned Memory::nontrivial_read(const unsigned P, const unsigned long cycleCoun
if (P < 0xFE00)
return cart.wramdata(P >> 12 & 1)[P & 0xFFF];
if (P >= 0xFF00)
return nontrivial_ff_read(P, cycleCounter);
long const ffp = long(P) - 0xFF00;
if (ffp >= 0)
return nontrivial_ff_read(ffp, cycleCounter);
if (!display.oamReadable(cycleCounter) || oamDmaPos < 0xA0)
return 0xFF;
@ -794,7 +795,7 @@ void Memory::nontrivial_ff_write(const unsigned P, unsigned data, const unsigned
sound.generateSamples(cycleCounter, isDoubleSpeed());
if (!(data & 0x80)) {
for (unsigned i = 0xFF10; i < 0xFF26; ++i)
for (unsigned i = 0x10; i < 0x26; ++i)
ff_write(i, 0, cycleCounter);
sound.setEnabled(false);
@ -1016,7 +1017,7 @@ void Memory::nontrivial_ff_write(const unsigned P, unsigned data, const unsigned
return;
}
ioamhram[P - 0xFE00] = data;
ioamhram[P + 0x100] = data;
}
void Memory::nontrivial_write(const unsigned P, const unsigned data, const unsigned long cycleCounter) {
@ -1045,13 +1046,14 @@ void Memory::nontrivial_write(const unsigned P, const unsigned data, const unsig
} else
cart.wramdata(P >> 12 & 1)[P & 0xFFF] = data;
} else if (P - 0xFF80u >= 0x7Fu) {
if (P < 0xFF00) {
long const ffp = long(P) - 0xFF00;
if (ffp < 0) {
if (display.oamWritable(cycleCounter) && oamDmaPos >= 0xA0 && (P < 0xFEA0 || isCgb())) {
display.oamChange(cycleCounter);
ioamhram[P - 0xFE00] = data;
}
} else
nontrivial_ff_write(P, data, cycleCounter);
nontrivial_ff_write(ffp, data, cycleCounter);
} else
ioamhram[P - 0xFE00] = data;
}

View File

@ -139,7 +139,7 @@ public:
unsigned ff_read(const unsigned P, const unsigned long cycleCounter) {
if (readCallback)
readCallback(P, (cycleCounter - basetime) >> 1);
return P < 0xFF80 ? nontrivial_ff_read(P, cycleCounter) : ioamhram[P - 0xFE00];
return P < 0x80 ? nontrivial_ff_read(P, cycleCounter) : ioamhram[P + 0x100];
}
struct CDMapResult
@ -279,8 +279,8 @@ public:
}
void ff_write(const unsigned P, const unsigned data, const unsigned long cycleCounter) {
if (P - 0xFF80u < 0x7Fu) {
ioamhram[P - 0xFE00] = data;
if (P - 0x80u < 0x7Fu) {
ioamhram[P + 0x100] = data;
} else
nontrivial_ff_write(P, data, cycleCounter);
if (writeCallback)

View File

@ -43,17 +43,17 @@ struct SaveState {
struct CPU {
unsigned long cycleCounter;
unsigned short PC;
unsigned short SP;
unsigned char A;
unsigned char B;
unsigned char C;
unsigned char D;
unsigned char E;
unsigned char F;
unsigned char H;
unsigned char L;
bool skip;
unsigned short pc;
unsigned short sp;
unsigned char a;
unsigned char b;
unsigned char c;
unsigned char d;
unsigned char e;
unsigned char f;
unsigned char h;
unsigned char l;
unsigned char /*bool*/ skip;
} cpu;
struct Mem {

Binary file not shown.