Fix LCDC for DMG on CGB
This commit is contained in:
parent
23c1c74030
commit
0a6a221653
|
@ -73,8 +73,8 @@ public:
|
||||||
mem_.setLinkCallback(callback);
|
mem_.setLinkCallback(callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadRes load(char const *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat) {
|
LoadRes load(char const *romfiledata, unsigned romfilelength, unsigned flags) {
|
||||||
return mem_.loadROM(romfiledata, romfilelength, forceDmg, multicartCompat);
|
return mem_.loadROM(romfiledata, romfilelength, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool loaded() const { return mem_.loaded(); }
|
bool loaded() const { return mem_.loaded(); }
|
||||||
|
@ -94,7 +94,6 @@ public:
|
||||||
void setRtcDivisorOffset(long const rtcDivisorOffset) { mem_.setRtcDivisorOffset(rtcDivisorOffset); }
|
void setRtcDivisorOffset(long const rtcDivisorOffset) { mem_.setRtcDivisorOffset(rtcDivisorOffset); }
|
||||||
|
|
||||||
void setBios(char const *buffer, std::size_t size) { mem_.setBios(buffer, size); }
|
void setBios(char const *buffer, std::size_t size) { mem_.setBios(buffer, size); }
|
||||||
bool gbIsCgb() { return mem_.gbIsCgb(); }
|
|
||||||
|
|
||||||
unsigned char externalRead(unsigned short addr) {return mem_.peek(addr); }
|
unsigned char externalRead(unsigned short addr) {return mem_.peek(addr); }
|
||||||
|
|
||||||
|
|
|
@ -88,7 +88,7 @@ void GB::reset() {
|
||||||
|
|
||||||
SaveState state;
|
SaveState state;
|
||||||
p_->cpu.setStatePtrs(state);
|
p_->cpu.setStatePtrs(state);
|
||||||
setInitState(state, !(p_->loadflags & FORCE_DMG), p_->loadflags & GBA_CGB);
|
setInitState(state, !(p_->loadflags & FORCE_DMG));
|
||||||
p_->cpu.loadState(state);
|
p_->cpu.loadState(state);
|
||||||
if (length > 0)
|
if (length > 0)
|
||||||
{
|
{
|
||||||
|
@ -139,13 +139,13 @@ void GB::setRtcDivisorOffset(long const rtcDivisorOffset) {
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadRes GB::load(char const *romfiledata, unsigned romfilelength, unsigned const flags) {
|
LoadRes GB::load(char const *romfiledata, unsigned romfilelength, unsigned const flags) {
|
||||||
LoadRes const loadres = p_->cpu.load(romfiledata, romfilelength, flags & FORCE_DMG, flags & MULTICART_COMPAT);
|
LoadRes const loadres = p_->cpu.load(romfiledata, romfilelength, flags);
|
||||||
|
|
||||||
if (loadres == LOADRES_OK) {
|
if (loadres == LOADRES_OK) {
|
||||||
SaveState state;
|
SaveState state;
|
||||||
p_->cpu.setStatePtrs(state);
|
p_->cpu.setStatePtrs(state);
|
||||||
p_->loadflags = flags;
|
p_->loadflags = flags;
|
||||||
setInitState(state, !(flags & FORCE_DMG), flags & GBA_CGB);
|
setInitState(state, !(flags & FORCE_DMG));
|
||||||
p_->cpu.loadState(state);
|
p_->cpu.loadState(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1147,7 +1147,7 @@ static void setInitialDmgIoamhram(unsigned char ioamhram[]) {
|
||||||
|
|
||||||
} // anon namespace
|
} // anon namespace
|
||||||
|
|
||||||
void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbMode) {
|
void gambatte::setInitState(SaveState &state, const bool cgb) {
|
||||||
static unsigned char const cgbObjpDump[0x40] = {
|
static unsigned char const cgbObjpDump[0x40] = {
|
||||||
0x00, 0x00, 0xF2, 0xAB,
|
0x00, 0x00, 0xF2, 0xAB,
|
||||||
0x61, 0xC2, 0xD9, 0xBA,
|
0x61, 0xC2, 0xD9, 0xBA,
|
||||||
|
@ -1182,8 +1182,6 @@ void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbM
|
||||||
state.cpu.prefetched = false;
|
state.cpu.prefetched = false;
|
||||||
state.cpu.skip = false;
|
state.cpu.skip = false;
|
||||||
state.mem.biosMode = true;
|
state.mem.biosMode = true;
|
||||||
state.mem.cgbSwitching = false;
|
|
||||||
state.mem.agbMode = gbaCgbMode;
|
|
||||||
|
|
||||||
std::memset(state.mem.sram.ptr, 0xFF, state.mem.sram.size());
|
std::memset(state.mem.sram.ptr, 0xFF, state.mem.sram.size());
|
||||||
|
|
||||||
|
@ -1222,7 +1220,6 @@ void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbM
|
||||||
state.mem.enableRam = false;
|
state.mem.enableRam = false;
|
||||||
state.mem.rambankMode = false;
|
state.mem.rambankMode = false;
|
||||||
state.mem.hdmaTransfer = false;
|
state.mem.hdmaTransfer = false;
|
||||||
state.mem.gbIsCgb = cgb;
|
|
||||||
state.mem.stopped = false;
|
state.mem.stopped = false;
|
||||||
|
|
||||||
|
|
||||||
|
@ -1269,7 +1266,7 @@ void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbM
|
||||||
state.ppu.nextM0Irq = 0;
|
state.ppu.nextM0Irq = 0;
|
||||||
state.ppu.oldWy = state.mem.ioamhram.get()[0x14A];
|
state.ppu.oldWy = state.mem.ioamhram.get()[0x14A];
|
||||||
state.ppu.pendingLcdstatIrq = false;
|
state.ppu.pendingLcdstatIrq = false;
|
||||||
state.ppu.isCgb = cgb;
|
state.ppu.notCgbDmg = true;
|
||||||
|
|
||||||
// spu.cycleCounter >> 12 & 7 represents the frame sequencer position.
|
// spu.cycleCounter >> 12 & 7 represents the frame sequencer position.
|
||||||
state.spu.cycleCounter = state.cpu.cycleCounter >> 1;
|
state.spu.cycleCounter = state.cpu.cycleCounter >> 1;
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
|
|
||||||
namespace gambatte {
|
namespace gambatte {
|
||||||
|
|
||||||
void setInitState(struct SaveState &state, bool cgb, bool gbaCgbMode);
|
void setInitState(struct SaveState &state, bool cgb);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -43,7 +43,7 @@ void Time::loadState(SaveState const &state) {
|
||||||
lastTime_.tv_sec = state.time.lastTimeSec;
|
lastTime_.tv_sec = state.time.lastTimeSec;
|
||||||
lastTime_.tv_usec = state.time.lastTimeUsec;
|
lastTime_.tv_usec = state.time.lastTimeUsec;
|
||||||
lastCycles_ = state.time.lastCycles;
|
lastCycles_ = state.time.lastCycles;
|
||||||
ds_ = state.ppu.isCgb & state.mem.ioamhram.get()[0x14D] >> 7;
|
ds_ = state.mem.ioamhram.get()[0x14D] >> 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint32_t Time::get(unsigned long const cc) {
|
std::uint32_t Time::get(unsigned long const cc) {
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
#include "gambatte.h"
|
||||||
#include "savestate.h"
|
#include "savestate.h"
|
||||||
#include "sound.h"
|
#include "sound.h"
|
||||||
#include "video.h"
|
#include "video.h"
|
||||||
|
@ -80,9 +81,6 @@ void Memory::setStatePtrs(SaveState &state) {
|
||||||
|
|
||||||
void Memory::loadState(SaveState const &state) {
|
void Memory::loadState(SaveState const &state) {
|
||||||
biosMode_ = state.mem.biosMode;
|
biosMode_ = state.mem.biosMode;
|
||||||
cgbSwitching_ = state.mem.cgbSwitching;
|
|
||||||
agbMode_ = state.mem.agbMode;
|
|
||||||
gbIsCgb_ = state.mem.gbIsCgb;
|
|
||||||
stopped_ = state.mem.stopped;
|
stopped_ = state.mem.stopped;
|
||||||
psg_.loadState(state);
|
psg_.loadState(state);
|
||||||
lcd_.loadState(state, state.mem.oamDmaPos < oam_size ? cart_.rdisabledRam() : ioamhram_);
|
lcd_.loadState(state, state.mem.oamDmaPos < oam_size ? cart_.rdisabledRam() : ioamhram_);
|
||||||
|
@ -1014,17 +1012,17 @@ void Memory::nontrivial_ff_write(unsigned const p, unsigned data, unsigned long
|
||||||
oamDmaInitSetup();
|
oamDmaInitSetup();
|
||||||
return;
|
return;
|
||||||
case 0x47:
|
case 0x47:
|
||||||
if (!isCgb())
|
if (!isCgb() || isCgbDmg())
|
||||||
lcd_.dmgBgPaletteChange(data, cc);
|
lcd_.dmgBgPaletteChange(data, cc);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 0x48:
|
case 0x48:
|
||||||
if (!isCgb())
|
if (!isCgb() || isCgbDmg())
|
||||||
lcd_.dmgSpPalette1Change(data, cc);
|
lcd_.dmgSpPalette1Change(data, cc);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 0x49:
|
case 0x49:
|
||||||
if (!isCgb())
|
if (!isCgb() || isCgbDmg())
|
||||||
lcd_.dmgSpPalette2Change(data, cc);
|
lcd_.dmgSpPalette2Change(data, cc);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -1033,25 +1031,34 @@ void Memory::nontrivial_ff_write(unsigned const p, unsigned data, unsigned long
|
||||||
break;
|
break;
|
||||||
case 0x4B:
|
case 0x4B:
|
||||||
lcd_.wxChange(data, cc);
|
lcd_.wxChange(data, cc);
|
||||||
|
break;
|
||||||
|
case 0x4C:
|
||||||
|
if (!biosMode_)
|
||||||
|
return;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case 0x4D:
|
case 0x4D:
|
||||||
if (isCgb())
|
if (isCgb() && !isCgbDmg())
|
||||||
ioamhram_[0x14D] = (ioamhram_[0x14D] & ~1u) | (data & 1);
|
ioamhram_[0x14D] = (ioamhram_[0x14D] & ~1u) | (data & 1);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
case 0x4F:
|
case 0x4F:
|
||||||
if (isCgb()) {
|
if (isCgb() && !isCgbDmg()) {
|
||||||
cart_.setVrambank(data & 1);
|
cart_.setVrambank(data & 1);
|
||||||
ioamhram_[0x14F] = 0xFE | data;
|
ioamhram_[0x14F] = 0xFE | data;
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
case 0x50:
|
case 0x50:
|
||||||
biosMode_ = false;
|
if (!biosMode_)
|
||||||
if(cgbSwitching_) {
|
return;
|
||||||
|
|
||||||
|
if (isCgb() && (ioamhram_[0x14C] & 0x04)) {
|
||||||
lcd_.copyCgbPalettesToDmg();
|
lcd_.copyCgbPalettesToDmg();
|
||||||
lcd_.setCgb(false);
|
lcd_.setCgbDmg(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
biosMode_ = false;
|
||||||
return;
|
return;
|
||||||
case 0x51:
|
case 0x51:
|
||||||
dmaSource_ = data << 8 | (dmaSource_ & 0xFF);
|
dmaSource_ = data << 8 | (dmaSource_ & 0xFF);
|
||||||
|
@ -1120,14 +1127,12 @@ void Memory::nontrivial_ff_write(unsigned const p, unsigned data, unsigned long
|
||||||
|
|
||||||
return;
|
return;
|
||||||
case 0x6C:
|
case 0x6C:
|
||||||
if (isCgb()) {
|
if (isCgb())
|
||||||
ioamhram_[0x16C] = data | 0xFE;
|
ioamhram_[0x16C] = data | 0xFE;
|
||||||
cgbSwitching_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
case 0x70:
|
case 0x70:
|
||||||
if (isCgb()) {
|
if (isCgb() && !isCgbDmg()) {
|
||||||
cart_.setWrambank(data & 0x07 ? data & 0x07 : 1);
|
cart_.setWrambank(data & 0x07 ? data & 0x07 : 1);
|
||||||
ioamhram_[0x170] = data | 0xF8;
|
ioamhram_[0x170] = data | 0xF8;
|
||||||
}
|
}
|
||||||
|
@ -1211,13 +1216,18 @@ void Memory::nontrivial_write(unsigned const p, unsigned const data, unsigned lo
|
||||||
ioamhram_[p - mm_oam_begin] = data;
|
ioamhram_[p - mm_oam_begin] = data;
|
||||||
}
|
}
|
||||||
|
|
||||||
LoadRes Memory::loadROM(char const *romfiledata, unsigned romfilelength, const bool forceDmg, const bool multicartCompat) {
|
LoadRes Memory::loadROM(char const *romfiledata, unsigned romfilelength, unsigned const flags) {
|
||||||
|
bool const forceDmg = flags & GB::LoadFlag::FORCE_DMG;
|
||||||
|
bool const multicartCompat = flags & GB::LoadFlag::MULTICART_COMPAT;
|
||||||
|
|
||||||
if (LoadRes const fail = cart_.loadROM(romfiledata, romfilelength, forceDmg, multicartCompat))
|
if (LoadRes const fail = cart_.loadROM(romfiledata, romfilelength, forceDmg, multicartCompat))
|
||||||
return fail;
|
return fail;
|
||||||
|
|
||||||
psg_.init(cart_.isCgb());
|
psg_.init(cart_.isCgb());
|
||||||
lcd_.reset(ioamhram_, cart_.vramdata(), cart_.isCgb());
|
lcd_.reset(ioamhram_, cart_.vramdata(), cart_.isCgb());
|
||||||
|
|
||||||
|
agbMode_ = flags & GB::LoadFlag::GBA_CGB;
|
||||||
|
|
||||||
return LOADRES_OK;
|
return LOADRES_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1300,9 +1310,6 @@ SYNCFUNC(Memory)
|
||||||
NSS(serialCnt_);
|
NSS(serialCnt_);
|
||||||
NSS(blanklcd_);
|
NSS(blanklcd_);
|
||||||
NSS(biosMode_);
|
NSS(biosMode_);
|
||||||
NSS(cgbSwitching_);
|
|
||||||
NSS(agbMode_);
|
|
||||||
NSS(gbIsCgb_);
|
|
||||||
NSS(stopped_);
|
NSS(stopped_);
|
||||||
NSS(LINKCABLE_);
|
NSS(LINKCABLE_);
|
||||||
NSS(linkClockTrigger_);
|
NSS(linkClockTrigger_);
|
||||||
|
|
|
@ -55,12 +55,12 @@ public:
|
||||||
memcpy(bios_, buffer, size);
|
memcpy(bios_, buffer, size);
|
||||||
biosSize_ = size;
|
biosSize_ = size;
|
||||||
}
|
}
|
||||||
bool gbIsCgb() { return gbIsCgb_; }
|
|
||||||
|
|
||||||
bool getMemoryArea(int which, unsigned char **data, int *length);
|
bool getMemoryArea(int which, unsigned char **data, int *length);
|
||||||
|
|
||||||
unsigned long stop(unsigned long cycleCounter, bool& skip);
|
unsigned long stop(unsigned long cycleCounter, bool& skip);
|
||||||
bool isCgb() const { return lcd_.isCgb(); }
|
bool isCgb() const { return lcd_.isCgb(); }
|
||||||
|
bool isCgbDmg() const { return lcd_.isCgbDmg(); }
|
||||||
bool ime() const { return intreq_.ime(); }
|
bool ime() const { return intreq_.ime(); }
|
||||||
bool halted() const { return intreq_.halted(); }
|
bool halted() const { return intreq_.halted(); }
|
||||||
unsigned long nextEventTime() const { return intreq_.minEventTime(); }
|
unsigned long nextEventTime() const { return intreq_.minEventTime(); }
|
||||||
|
@ -226,7 +226,7 @@ public:
|
||||||
|
|
||||||
unsigned long event(unsigned long cycleCounter);
|
unsigned long event(unsigned long cycleCounter);
|
||||||
unsigned long resetCounters(unsigned long cycleCounter);
|
unsigned long resetCounters(unsigned long cycleCounter);
|
||||||
LoadRes loadROM(char const *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat);
|
LoadRes loadROM(char const *romfiledata, unsigned romfilelength, unsigned flags);
|
||||||
|
|
||||||
void setInputGetter(unsigned (*getInput)()) {
|
void setInputGetter(unsigned (*getInput)()) {
|
||||||
getInput_ = getInput;
|
getInput_ = getInput;
|
||||||
|
@ -299,9 +299,7 @@ private:
|
||||||
unsigned char serialCnt_;
|
unsigned char serialCnt_;
|
||||||
bool blanklcd_;
|
bool blanklcd_;
|
||||||
bool biosMode_;
|
bool biosMode_;
|
||||||
bool cgbSwitching_;
|
|
||||||
bool agbMode_;
|
bool agbMode_;
|
||||||
bool gbIsCgb_;
|
|
||||||
unsigned long basetime_;
|
unsigned long basetime_;
|
||||||
bool stopped_;
|
bool stopped_;
|
||||||
enum HdmaState { hdma_low, hdma_high, hdma_requested } haltHdmaState_;
|
enum HdmaState { hdma_low, hdma_high, hdma_requested } haltHdmaState_;
|
||||||
|
|
|
@ -36,7 +36,7 @@ struct SaveState {
|
||||||
void set(T *p, std::size_t size) { ptr = p; size_ = size; }
|
void set(T *p, std::size_t size) { ptr = p; size_ = size; }
|
||||||
|
|
||||||
friend class SaverList;
|
friend class SaverList;
|
||||||
friend void setInitState(SaveState &, bool, bool);
|
friend void setInitState(SaveState &, bool);
|
||||||
private:
|
private:
|
||||||
T *ptr;
|
T *ptr;
|
||||||
std::size_t size_;
|
std::size_t size_;
|
||||||
|
@ -83,9 +83,6 @@ struct SaveState {
|
||||||
unsigned char /*bool*/ rambankMode;
|
unsigned char /*bool*/ rambankMode;
|
||||||
unsigned char /*bool*/ hdmaTransfer;
|
unsigned char /*bool*/ hdmaTransfer;
|
||||||
unsigned char /*bool*/ biosMode;
|
unsigned char /*bool*/ biosMode;
|
||||||
unsigned char /*bool*/ cgbSwitching;
|
|
||||||
unsigned char /*bool*/ agbMode;
|
|
||||||
unsigned char /*bool*/ gbIsCgb;
|
|
||||||
unsigned char /*bool*/ stopped;
|
unsigned char /*bool*/ stopped;
|
||||||
} mem;
|
} mem;
|
||||||
|
|
||||||
|
@ -122,7 +119,7 @@ struct SaveState {
|
||||||
unsigned char wscx;
|
unsigned char wscx;
|
||||||
unsigned char /*bool*/ weMaster;
|
unsigned char /*bool*/ weMaster;
|
||||||
unsigned char /*bool*/ pendingLcdstatIrq;
|
unsigned char /*bool*/ pendingLcdstatIrq;
|
||||||
unsigned char /*bool*/ isCgb;
|
unsigned char /*bool*/ notCgbDmg;
|
||||||
} ppu;
|
} ppu;
|
||||||
|
|
||||||
struct SPU {
|
struct SPU {
|
||||||
|
|
|
@ -96,6 +96,7 @@ inline void Channel4::Lfsr::event() {
|
||||||
void Channel4::Lfsr::nr3Change(unsigned newNr3, unsigned long cc) {
|
void Channel4::Lfsr::nr3Change(unsigned newNr3, unsigned long cc) {
|
||||||
updateBackupCounter(cc);
|
updateBackupCounter(cc);
|
||||||
nr3_ = newNr3;
|
nr3_ = newNr3;
|
||||||
|
counter_ = cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Channel4::Lfsr::nr4Init(unsigned long cc) {
|
void Channel4::Lfsr::nr4Init(unsigned long cc) {
|
||||||
|
|
|
@ -24,8 +24,8 @@
|
||||||
using namespace gambatte;
|
using namespace gambatte;
|
||||||
|
|
||||||
unsigned long LCD::gbcToRgb32(const unsigned bgr15) {
|
unsigned long LCD::gbcToRgb32(const unsigned bgr15) {
|
||||||
unsigned long const r = bgr15 & 0x1F;
|
unsigned long const r = bgr15 & 0x1F;
|
||||||
unsigned long const g = bgr15 >> 5 & 0x1F;
|
unsigned long const g = bgr15 >> 5 & 0x1F;
|
||||||
unsigned long const b = bgr15 >> 10 & 0x1F;
|
unsigned long const b = bgr15 >> 10 & 0x1F;
|
||||||
|
|
||||||
return cgbColorsRgb32_[bgr15 & 0x7FFF];
|
return cgbColorsRgb32_[bgr15 & 0x7FFF];
|
||||||
|
@ -69,18 +69,13 @@ namespace {
|
||||||
&& cc >= m0TimeOfCurrentLy;
|
&& cc >= m0TimeOfCurrentLy;
|
||||||
}
|
}
|
||||||
|
|
||||||
void doCgbColorChange(unsigned char* pdata,
|
|
||||||
unsigned long* palette, unsigned index, unsigned data, bool trueColor) {
|
|
||||||
pdata[index] = data;
|
|
||||||
index /= 2;
|
|
||||||
palette[index] = gbcToRgb32(pdata[index * 2] | pdata[index * 2 + 1] * 0x100l);
|
|
||||||
}
|
|
||||||
|
|
||||||
} // unnamed namespace.
|
} // unnamed namespace.
|
||||||
|
|
||||||
void LCD::setDmgPalette(unsigned long palette[], const unsigned long dmgColors[], unsigned data) {
|
void LCD::setDmgPalette(unsigned long palette[], const unsigned long dmgColors[], unsigned data) {
|
||||||
for (int i = 0; i < num_palette_entries; ++i, data /= num_palette_entries)
|
palette[0] = dmgColors[data & 3];
|
||||||
palette[i] = gbcToRgb32(dmgColors[data % num_palette_entries]);
|
palette[1] = dmgColors[data >> 2 & 3];
|
||||||
|
palette[2] = dmgColors[data >> 4 & 3];
|
||||||
|
palette[3] = dmgColors[data >> 6 & 3];
|
||||||
}
|
}
|
||||||
|
|
||||||
void LCD::setCgbPalette(unsigned *lut) {
|
void LCD::setCgbPalette(unsigned *lut) {
|
||||||
|
@ -114,10 +109,6 @@ void LCD::reset(unsigned char const *oamram, unsigned char const *vram, bool cgb
|
||||||
refreshPalettes();
|
refreshPalettes();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LCD::setCgb(bool cgb) {
|
|
||||||
ppu_.setCgb(cgb);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LCD::setStatePtrs(SaveState &state) {
|
void LCD::setStatePtrs(SaveState &state) {
|
||||||
state.ppu.bgpData.set( bgpData_, sizeof bgpData_);
|
state.ppu.bgpData.set( bgpData_, sizeof bgpData_);
|
||||||
state.ppu.objpData.set(objpData_, sizeof objpData_);
|
state.ppu.objpData.set(objpData_, sizeof objpData_);
|
||||||
|
@ -162,7 +153,7 @@ void LCD::loadState(SaveState const &state, unsigned char const *const oamram) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LCD::refreshPalettes() {
|
void LCD::refreshPalettes() {
|
||||||
if (ppu_.cgb()) {
|
if (isCgb() && !isCgbDmg()) {
|
||||||
for (int i = 0; i < max_num_palettes * num_palette_entries; ++i) {
|
for (int i = 0; i < max_num_palettes * num_palette_entries; ++i) {
|
||||||
ppu_.bgPalette()[i] = gbcToRgb32(bgpData_[2 * i] | bgpData_[2 * i + 1] * 0x100l);
|
ppu_.bgPalette()[i] = gbcToRgb32(bgpData_[2 * i] | bgpData_[2 * i + 1] * 0x100l);
|
||||||
ppu_.spPalette()[i] = gbcToRgb32(objpData_[2 * i] | objpData_[2 * i + 1] * 0x100l);
|
ppu_.spPalette()[i] = gbcToRgb32(objpData_[2 * i] | objpData_[2 * i + 1] * 0x100l);
|
||||||
|
@ -186,7 +177,7 @@ void LCD::copyCgbPalettesToDmg() {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static void clear(T *buf, unsigned long color, std::ptrdiff_t dpitch) {
|
void clear(T *buf, unsigned long color, std::ptrdiff_t dpitch) {
|
||||||
unsigned lines = 144;
|
unsigned lines = 144;
|
||||||
|
|
||||||
while (lines--) {
|
while (lines--) {
|
||||||
|
@ -856,6 +847,4 @@ SYNCFUNC(LCD)
|
||||||
SSS(lycIrq_);
|
SSS(lycIrq_);
|
||||||
SSS(nextM0Time_);
|
SSS(nextM0Time_);
|
||||||
NSS(statReg_);
|
NSS(statReg_);
|
||||||
NSS(m2IrqStatReg_);
|
|
||||||
NSS(m1IrqStatReg_);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,13 +50,13 @@ public:
|
||||||
LCD(unsigned char const *oamram, unsigned char const *vram,
|
LCD(unsigned char const *oamram, unsigned char const *vram,
|
||||||
VideoInterruptRequester memEventRequester);
|
VideoInterruptRequester memEventRequester);
|
||||||
void reset(unsigned char const *oamram, unsigned char const *vram, bool cgb);
|
void reset(unsigned char const *oamram, unsigned char const *vram, bool cgb);
|
||||||
|
void setCgbDmg(bool enabled) { ppu_.setCgbDmg(enabled); }
|
||||||
void setStatePtrs(SaveState &state);
|
void setStatePtrs(SaveState &state);
|
||||||
void loadState(SaveState const &state, unsigned char const *oamram);
|
void loadState(SaveState const &state, unsigned char const *oamram);
|
||||||
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned long rgb32);
|
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned long rgb32);
|
||||||
void setCgbPalette(unsigned *lut);
|
void setCgbPalette(unsigned *lut);
|
||||||
void setVideoBuffer(uint_least32_t *videoBuf, std::ptrdiff_t pitch);
|
void setVideoBuffer(uint_least32_t *videoBuf, std::ptrdiff_t pitch);
|
||||||
void setLayers(unsigned mask) { ppu_.setLayers(mask); }
|
void setLayers(unsigned mask) { ppu_.setLayers(mask); }
|
||||||
void setCgb(bool cgb);
|
|
||||||
void copyCgbPalettesToDmg();
|
void copyCgbPalettesToDmg();
|
||||||
|
|
||||||
int debugGetLY() const { return ppu_.lyCounter().ly(); }
|
int debugGetLY() const { return ppu_.lyCounter().ly(); }
|
||||||
|
@ -147,6 +147,7 @@ public:
|
||||||
bool hdmaIsEnabled() const { return eventTimes_(memevent_hdma) != disabled_time; }
|
bool hdmaIsEnabled() const { return eventTimes_(memevent_hdma) != disabled_time; }
|
||||||
void update(unsigned long cycleCounter);
|
void update(unsigned long cycleCounter);
|
||||||
bool isCgb() const { return ppu_.cgb(); }
|
bool isCgb() const { return ppu_.cgb(); }
|
||||||
|
bool isCgbDmg() const { return ppu_.cgbDmg(); }
|
||||||
bool isDoubleSpeed() const { return ppu_.lyCounter().isDoubleSpeed(); }
|
bool isDoubleSpeed() const { return ppu_.lyCounter().isDoubleSpeed(); }
|
||||||
|
|
||||||
unsigned long *bgPalette() { return ppu_.bgPalette(); }
|
unsigned long *bgPalette() { return ppu_.bgPalette(); }
|
||||||
|
|
|
@ -140,6 +140,13 @@ inline void nextCall(int const cycles, PPUState const &state, PPUPriv &p) {
|
||||||
p.nextCallPtr = &state;
|
p.nextCallPtr = &state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline unsigned long const* cgbSpPalette(PPUPriv const& p, unsigned const attrib) {
|
||||||
|
if (!p.cgbDmg)
|
||||||
|
return p.spPalette + (attrib & attr_cgbpalno) * num_palette_entries;
|
||||||
|
else
|
||||||
|
return p.spPalette + (attrib & attr_dmgpalno ? num_palette_entries : 0);
|
||||||
|
}
|
||||||
|
|
||||||
namespace M2_Ly0 {
|
namespace M2_Ly0 {
|
||||||
void f0(PPUPriv& p) {
|
void f0(PPUPriv& p) {
|
||||||
p.weMaster = lcdcWinEn(p) && 0 == p.wy;
|
p.weMaster = lcdcWinEn(p) && 0 == p.wy;
|
||||||
|
@ -444,6 +451,7 @@ namespace M3Loop {
|
||||||
+ expand_lut[(tileDataLine + ts * tno - 2 * ts * (tno & tileIndexSign))[1]] * 2;
|
+ expand_lut[(tileDataLine + ts * tno - 2 * ts * (tno & tileIndexSign))[1]] * 2;
|
||||||
} while (dst != dstend);
|
} while (dst != dstend);
|
||||||
|
|
||||||
|
|
||||||
p.ntileword = ntileword;
|
p.ntileword = ntileword;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -455,6 +463,7 @@ namespace M3Loop {
|
||||||
p.cycles = cycles;
|
p.cycles = cycles;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
uint_least32_t* const dst = dbufline + (xpos - tile_len);
|
uint_least32_t* const dst = dbufline + (xpos - tile_len);
|
||||||
unsigned const tileword = -(p.lcdc & 1u * lcdc_bgen) & p.ntileword;
|
unsigned const tileword = -(p.lcdc & 1u * lcdc_bgen) & p.ntileword;
|
||||||
|
|
||||||
|
@ -541,6 +550,7 @@ namespace M3Loop {
|
||||||
} while (i >= 0 && spx(p.spriteList[i]) > xpos - tile_len);
|
} while (i >= 0 && spx(p.spriteList[i]) > xpos - tile_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned const tno = tileMapLine[tileMapXpos % tile_map_len];
|
unsigned const tno = tileMapLine[tileMapXpos % tile_map_len];
|
||||||
int const ts = tile_size;
|
int const ts = tile_size;
|
||||||
tileMapXpos = tileMapXpos % tile_map_len + 1;
|
tileMapXpos = tileMapXpos % tile_map_len + 1;
|
||||||
|
@ -766,6 +776,7 @@ namespace M3Loop {
|
||||||
} while (i >= 0 && spx(p.spriteList[i]) > xpos - tile_len);
|
} while (i >= 0 && spx(p.spriteList[i]) > xpos - tile_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
unsigned const tno = tileMapLine[tileMapXpos % tile_map_len];
|
unsigned const tno = tileMapLine[tileMapXpos % tile_map_len];
|
||||||
unsigned const nattrib = tileMapLine[tileMapXpos % tile_map_len + vram_bank_size];
|
unsigned const nattrib = tileMapLine[tileMapXpos % tile_map_len + vram_bank_size];
|
||||||
|
@ -786,7 +797,6 @@ namespace M3Loop {
|
||||||
p.xpos = xpos;
|
p.xpos = xpos;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void doFullTilesUnrolled(PPUPriv& p) {
|
void doFullTilesUnrolled(PPUPriv& p) {
|
||||||
int xpos = p.xpos;
|
int xpos = p.xpos;
|
||||||
int const xend = p.wx < p.xpos || p.wx >= xpos_end
|
int const xend = p.wx < p.xpos || p.wx >= xpos_end
|
||||||
|
@ -1768,6 +1778,7 @@ void PPU::loadState(SaveState const& ss, unsigned char const* const oamram) {
|
||||||
void PPU::reset(unsigned char const *oamram, unsigned char const *vram, bool cgb) {
|
void PPU::reset(unsigned char const *oamram, unsigned char const *vram, bool cgb) {
|
||||||
p_.vram = vram;
|
p_.vram = vram;
|
||||||
p_.cgb = cgb;
|
p_.cgb = cgb;
|
||||||
|
p_.cgbDmg = false;
|
||||||
p_.spriteMapper.reset(oamram, cgb);
|
p_.spriteMapper.reset(oamram, cgb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -150,7 +150,6 @@ public:
|
||||||
unsigned long * spPalette() { return p_.spPalette; }
|
unsigned long * spPalette() { return p_.spPalette; }
|
||||||
void update(unsigned long cc);
|
void update(unsigned long cc);
|
||||||
void setLayers(unsigned mask) { p_.layersMask = mask; }
|
void setLayers(unsigned mask) { p_.layersMask = mask; }
|
||||||
void setCgb(bool cgb) { p_.cgb = cgb; }
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PPUPriv p_;
|
PPUPriv p_;
|
||||||
|
|
Loading…
Reference in New Issue