CPU refactoring
This commit is contained in:
parent
a6aeef840a
commit
6020542182
File diff suppressed because it is too large
Load Diff
|
@ -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);
|
||||
};
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
Loading…
Reference in New Issue