Add files via upload

This commit is contained in:
alyosha-tas 2017-06-24 12:56:18 -04:00 committed by GitHub
parent 6e5eaba155
commit e65393ec57
8 changed files with 1557 additions and 1513 deletions

View File

@ -29,9 +29,9 @@ GBEXPORT void gambatte_destroy(GB *g)
delete g; delete g;
} }
GBEXPORT int gambatte_load(GB *g, const char *romfiledata, unsigned romfilelength, long long now, unsigned flags) GBEXPORT int gambatte_load(GB *g, const char *romfiledata, unsigned romfilelength, const char *biosfiledata, unsigned biosfilelength, long long now, unsigned flags)
{ {
int ret = g->load(romfiledata, romfilelength, now, flags); int ret = g->load(romfiledata, romfilelength, biosfiledata, biosfilelength, now, flags);
return ret; return ret;
} }

View File

@ -1,132 +1,136 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2007 by Sindre Aamås * * Copyright (C) 2007 by Sindre Aamås *
* aamas@stud.ntnu.no * * aamas@stud.ntnu.no *
* * * *
* This program is free software; you can redistribute it and/or modify * * 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 * * it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. * * published by the Free Software Foundation. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License version 2 for more details. * * GNU General Public License version 2 for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the * * version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef CPU_H #ifndef CPU_H
#define CPU_H #define CPU_H
#include "memory.h" #include "memory.h"
#include "newstate.h" #include "newstate.h"
namespace gambatte { namespace gambatte {
class CPU { class CPU {
Memory memory; Memory memory;
unsigned long cycleCounter_; unsigned long cycleCounter_;
unsigned short PC; unsigned short PC;
unsigned short SP; unsigned short SP;
unsigned HF1, HF2, ZF, CF; unsigned HF1, HF2, ZF, CF;
unsigned char A, B, C, D, E, /*F,*/ H, L; unsigned char A, B, C, D, E, /*F,*/ H, L;
bool skip; bool skip;
void process(unsigned long cycles); void process(unsigned long cycles);
void (*tracecallback)(void *); void (*tracecallback)(void *);
public: public:
CPU(); CPU();
// void halt(); // void halt();
// unsigned interrupt(unsigned address, unsigned cycleCounter); // unsigned interrupt(unsigned address, unsigned cycleCounter);
long runFor(unsigned long cycles); long runFor(unsigned long cycles);
void setStatePtrs(SaveState &state); void setStatePtrs(SaveState &state);
void loadState(const SaveState &state); void loadState(const SaveState &state);
void setLayers(unsigned mask) { memory.setLayers(mask); } void setLayers(unsigned mask) { memory.setLayers(mask); }
void loadSavedata(const char *data) { memory.loadSavedata(data); } void loadSavedata(const char *data) { memory.loadSavedata(data); }
int saveSavedataLength() {return memory.saveSavedataLength(); } int saveSavedataLength() {return memory.saveSavedataLength(); }
void saveSavedata(char *dest) { memory.saveSavedata(dest); } void saveSavedata(char *dest) { memory.saveSavedata(dest); }
bool getMemoryArea(int which, unsigned char **data, int *length) { return memory.getMemoryArea(which, data, length); } 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) { void setVideoBuffer(uint_least32_t *const videoBuf, const int pitch) {
memory.setVideoBuffer(videoBuf, pitch); memory.setVideoBuffer(videoBuf, pitch);
} }
void setInputGetter(unsigned (*getInput)()) { void setInputGetter(unsigned (*getInput)()) {
memory.setInputGetter(getInput); memory.setInputGetter(getInput);
} }
void setReadCallback(void (*callback)(unsigned)) { void setReadCallback(void (*callback)(unsigned)) {
memory.setReadCallback(callback); memory.setReadCallback(callback);
} }
void setWriteCallback(void (*callback)(unsigned)) { void setWriteCallback(void (*callback)(unsigned)) {
memory.setWriteCallback(callback); memory.setWriteCallback(callback);
} }
void setExecCallback(void (*callback)(unsigned)) { void setExecCallback(void (*callback)(unsigned)) {
memory.setExecCallback(callback); memory.setExecCallback(callback);
} }
void setCDCallback(CDCallback cdc) { void setCDCallback(CDCallback cdc) {
memory.setCDCallback(cdc); memory.setCDCallback(cdc);
} }
void setTraceCallback(void (*callback)(void *)) { void setTraceCallback(void (*callback)(void *)) {
tracecallback = callback; tracecallback = callback;
} }
void setScanlineCallback(void (*callback)(), int sl) { void setScanlineCallback(void (*callback)(), int sl) {
memory.setScanlineCallback(callback, sl); memory.setScanlineCallback(callback, sl);
} }
void setRTCCallback(std::uint32_t (*callback)()) { void setRTCCallback(std::uint32_t (*callback)()) {
memory.setRTCCallback(callback); memory.setRTCCallback(callback);
} }
int load(const char *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat) { void reset_bios(int setting) {
return memory.loadROM(romfiledata, romfilelength, forceDmg, multicartCompat); memory.bios_reset(setting);
} }
bool loaded() const { return memory.loaded(); } int load(const char *romfiledata, unsigned romfilelength, const char *biosfiledata, unsigned biosfilelength, bool forceDmg, bool multicartCompat) {
const char * romTitle() const { return memory.romTitle(); } return memory.loadROM(romfiledata, romfilelength, biosfiledata, biosfilelength, forceDmg, multicartCompat);
}
void setSoundBuffer(uint_least32_t *const buf) { memory.setSoundBuffer(buf); }
unsigned fillSoundBuffer() { return memory.fillSoundBuffer(cycleCounter_); } bool loaded() const { return memory.loaded(); }
const char * romTitle() const { return memory.romTitle(); }
bool isCgb() const { return memory.isCgb(); }
void setSoundBuffer(uint_least32_t *const buf) { memory.setSoundBuffer(buf); }
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned rgb32) { unsigned fillSoundBuffer() { return memory.fillSoundBuffer(cycleCounter_); }
memory.setDmgPaletteColor(palNum, colorNum, rgb32);
} bool isCgb() const { return memory.isCgb(); }
void setCgbPalette(unsigned *lut) { void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned rgb32) {
memory.setCgbPalette(lut); memory.setDmgPaletteColor(palNum, colorNum, rgb32);
} }
//unsigned char ExternalRead(unsigned short addr) { return memory.read(addr, cycleCounter_); } void setCgbPalette(unsigned *lut) {
unsigned char ExternalRead(unsigned short addr) { return memory.peek(addr); } memory.setCgbPalette(lut);
void ExternalWrite(unsigned short addr, unsigned char val) { memory.write_nocb(addr, val, cycleCounter_); } }
int LinkStatus(int which) { return memory.LinkStatus(which); } //unsigned char ExternalRead(unsigned short addr) { return memory.read(addr, cycleCounter_); }
unsigned char ExternalRead(unsigned short addr) { return memory.peek(addr); }
void GetRegs(int *dest); 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);
template<bool isReader>void SyncState(NewState *ns); template<bool isReader>void SyncState(NewState *ns);
}; };
} }
#endif #endif

View File

@ -94,7 +94,15 @@ void GB::reset(const std::uint32_t now) {
SaveState state; SaveState state;
p_->cpu.setStatePtrs(state); p_->cpu.setStatePtrs(state);
setInitState(state, p_->cpu.isCgb(), p_->gbaCgbMode, now); if (use_bios)
{
p_->cpu.reset_bios(0);
}
else
{
}
setInitState(state, p_->cpu.isCgb(), p_->gbaCgbMode, now, use_bios);
p_->cpu.loadState(state); p_->cpu.loadState(state);
if (length > 0) if (length > 0)
{ {
@ -136,16 +144,17 @@ void GB::setRTCCallback(std::uint32_t (*callback)()) {
p_->cpu.setRTCCallback(callback); p_->cpu.setRTCCallback(callback);
} }
int GB::load(const char *romfiledata, unsigned romfilelength, const std::uint32_t now, const unsigned flags) { int GB::load(const char *romfiledata, unsigned romfilelength, const char *biosfiledata, unsigned biosfilelength, const std::uint32_t now, const unsigned flags) {
//if (p_->cpu.loaded()) //if (p_->cpu.loaded())
// p_->cpu.saveSavedata(); // p_->cpu.saveSavedata();
const int failed = p_->cpu.load(romfiledata, romfilelength, flags & FORCE_DMG, flags & MULTICART_COMPAT); const int failed = p_->cpu.load(romfiledata, romfilelength, biosfiledata, biosfilelength, flags & FORCE_DMG, flags & MULTICART_COMPAT);
use_bios = biosfilelength > 0 ? true : false;
if (!failed) { if (!failed) {
SaveState state; SaveState state;
p_->cpu.setStatePtrs(state); p_->cpu.setStatePtrs(state);
setInitState(state, p_->cpu.isCgb(), p_->gbaCgbMode = flags & GBA_CGB, now); setInitState(state, p_->cpu.isCgb(), p_->gbaCgbMode = flags & GBA_CGB, now, use_bios);
p_->cpu.loadState(state); p_->cpu.loadState(state);
//p_->cpu.loadSavedata(); //p_->cpu.loadSavedata();
} }

View File

@ -1146,7 +1146,7 @@ static void setInitialDmgIoamhram(unsigned char *const ioamhram) {
} // anon namespace } // anon namespace
void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbMode, const std::uint32_t now) { void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbMode, const std::uint32_t now, bool boot_bios) {
static const unsigned char cgbObjpDump[0x40] = { static const unsigned char cgbObjpDump[0x40] = {
0x00, 0x00, 0xF2, 0xAB, 0x00, 0x00, 0xF2, 0xAB,
0x61, 0xC2, 0xD9, 0xBA, 0x61, 0xC2, 0xD9, 0xBA,
@ -1166,22 +1166,47 @@ void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbM
0x83, 0x40, 0x0B, 0x77 0x83, 0x40, 0x0B, 0x77
}; };
state.cpu.cycleCounter = cgb ? 0x102A0 : 0x102A0 + 0x8D2C; if (boot_bios)
state.cpu.PC = 0x100; {
state.cpu.SP = 0xFFFE; state.cpu.PC = 0x00;
state.cpu.A = cgb * 0x10 | 0x01; state.cpu.SP = 0xFFFF;
state.cpu.B = cgb & gbaCgbMode; state.cpu.A = 0;
state.cpu.C = 0x13; state.cpu.B = 0;
state.cpu.D = 0x00; state.cpu.C = 0x0;
state.cpu.E = 0xD8; state.cpu.D = 0x0;
state.cpu.F = 0xB0; state.cpu.E = 0x0;
state.cpu.H = 0x01; state.cpu.F = 0x0;
state.cpu.L = 0x4D; state.cpu.H = 0x0;
state.cpu.skip = false; state.cpu.L = 0x0;
state.cpu.skip = false;
state.cpu.cycleCounter = 0;
state.mem.ioamhram.ptr[0x140] = 0x00;
state.mem.ioamhram.ptr[0x104] = 0x00;
}
else
{
state.cpu.PC = 0x100;
state.cpu.SP = 0xFFFE;
state.cpu.A = cgb * 0x10 | 0x01;
state.cpu.B = cgb & gbaCgbMode;
state.cpu.C = 0x13;
state.cpu.D = 0x00;
state.cpu.E = 0xD8;
state.cpu.F = 0xB0;
state.cpu.H = 0x01;
state.cpu.L = 0x4D;
state.cpu.skip = false;
setInitialVram(state.mem.vram.ptr, cgb);
state.cpu.cycleCounter = cgb ? 0x102A0 : 0x102A0 + 0x8D2C;
state.mem.ioamhram.ptr[0x140] = 0x91;
state.mem.ioamhram.ptr[0x104] = 0x1C;
}
std::memset(state.mem.sram.ptr, 0xFF, state.mem.sram.getSz()); std::memset(state.mem.sram.ptr, 0xFF, state.mem.sram.getSz());
setInitialVram(state.mem.vram.ptr, cgb);
if (cgb) { if (cgb) {
setInitialCgbWram(state.mem.wram.ptr); setInitialCgbWram(state.mem.wram.ptr);
@ -1191,8 +1216,6 @@ void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbM
setInitialDmgIoamhram(state.mem.ioamhram.ptr); setInitialDmgIoamhram(state.mem.ioamhram.ptr);
} }
state.mem.ioamhram.ptr[0x104] = 0x1C;
state.mem.ioamhram.ptr[0x140] = 0x91;
state.mem.ioamhram.ptr[0x144] = 0x00; state.mem.ioamhram.ptr[0x144] = 0x00;
state.mem.divLastUpdate = 0; state.mem.divLastUpdate = 0;
@ -1258,7 +1281,6 @@ void gambatte::setInitState(SaveState &state, const bool cgb, const bool gbaCgbM
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.spu.cycleCounter = 0x1000 | (state.cpu.cycleCounter >> 1 & 0xFFF); // spu.cycleCounter >> 12 & 7 represents the frame sequencer position. state.spu.cycleCounter = 0x1000 | (state.cpu.cycleCounter >> 1 & 0xFFF); // spu.cycleCounter >> 12 & 7 represents the frame sequencer position.
state.spu.ch1.sweep.counter = SoundUnit::COUNTER_DISABLED; state.spu.ch1.sweep.counter = SoundUnit::COUNTER_DISABLED;

View File

@ -22,7 +22,7 @@
#include <cstdint> #include <cstdint>
namespace gambatte { namespace gambatte {
void setInitState(struct SaveState &state, bool cgb, bool gbaCgbMode, std::uint32_t now); void setInitState(struct SaveState &state, bool cgb, bool gbaCgbMode, std::uint32_t now, bool boot_bios);
} }
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -1,293 +1,297 @@
/*************************************************************************** /***************************************************************************
* Copyright (C) 2007 by Sindre Aamås * * Copyright (C) 2007 by Sindre Aamås *
* aamas@stud.ntnu.no * * aamas@stud.ntnu.no *
* * * *
* This program is free software; you can redistribute it and/or modify * * 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 * * it under the terms of the GNU General Public License version 2 as *
* published by the Free Software Foundation. * * published by the Free Software Foundation. *
* * * *
* This program is distributed in the hope that it will be useful, * * This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of * * but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License version 2 for more details. * * GNU General Public License version 2 for more details. *
* * * *
* You should have received a copy of the GNU General Public License * * You should have received a copy of the GNU General Public License *
* version 2 along with this program; if not, write to the * * version 2 along with this program; if not, write to the *
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef MEMORY_H #ifndef MEMORY_H
#define MEMORY_H #define MEMORY_H
#include "mem/cartridge.h" #include "mem/cartridge.h"
#include "video.h" #include "video.h"
#include "sound.h" #include "sound.h"
#include "interrupter.h" #include "interrupter.h"
#include "tima.h" #include "tima.h"
#include "newstate.h" #include "newstate.h"
#include "gambatte.h" #include "gambatte.h"
namespace gambatte { namespace gambatte {
class InputGetter; class InputGetter;
class FilterInfo; class FilterInfo;
class Memory { class Memory {
Cartridge cart; Cartridge cart;
unsigned char ioamhram[0x200]; unsigned char ioamhram[0x200];
void (*readCallback)(unsigned); void (*readCallback)(unsigned);
void (*writeCallback)(unsigned); void (*writeCallback)(unsigned);
void (*execCallback)(unsigned); void (*execCallback)(unsigned);
CDCallback cdCallback; CDCallback cdCallback;
unsigned (*getInput)(); unsigned (*getInput)();
unsigned long divLastUpdate; unsigned long divLastUpdate;
unsigned long lastOamDmaUpdate; unsigned long lastOamDmaUpdate;
InterruptRequester intreq; InterruptRequester intreq;
Tima tima; Tima tima;
LCD display; LCD display;
PSG sound; PSG sound;
Interrupter interrupter; Interrupter interrupter;
unsigned short dmaSource; unsigned short dmaSource;
unsigned short dmaDestination; unsigned short dmaDestination;
unsigned char oamDmaPos; unsigned char oamDmaPos;
unsigned char serialCnt; unsigned char serialCnt;
bool blanklcd; bool blanklcd;
bool LINKCABLE; bool LINKCABLE;
bool linkClockTrigger; bool linkClockTrigger;
void decEventCycles(MemEventId eventId, unsigned long dec); void decEventCycles(MemEventId eventId, unsigned long dec);
void oamDmaInitSetup(); void oamDmaInitSetup();
void updateOamDma(unsigned long cycleCounter); void updateOamDma(unsigned long cycleCounter);
void startOamDma(unsigned long cycleCounter); void startOamDma(unsigned long cycleCounter);
void endOamDma(unsigned long cycleCounter); void endOamDma(unsigned long cycleCounter);
const unsigned char * oamDmaSrcPtr() const; const unsigned char * oamDmaSrcPtr() const;
unsigned nontrivial_ff_read(unsigned P, unsigned long cycleCounter); unsigned nontrivial_ff_read(unsigned P, unsigned long cycleCounter);
unsigned nontrivial_read(unsigned P, unsigned long cycleCounter); unsigned nontrivial_read(unsigned P, unsigned long cycleCounter);
void nontrivial_ff_write(unsigned P, unsigned data, unsigned long cycleCounter); void nontrivial_ff_write(unsigned P, unsigned data, unsigned long cycleCounter);
void nontrivial_write(unsigned P, unsigned data, unsigned long cycleCounter); void nontrivial_write(unsigned P, unsigned data, unsigned long cycleCounter);
unsigned nontrivial_peek(unsigned P); unsigned nontrivial_peek(unsigned P);
unsigned nontrivial_ff_peek(unsigned P); unsigned nontrivial_ff_peek(unsigned P);
void updateSerial(unsigned long cc); void updateSerial(unsigned long cc);
void updateTimaIrq(unsigned long cc); void updateTimaIrq(unsigned long cc);
void updateIrqs(unsigned long cc); void updateIrqs(unsigned long cc);
bool isDoubleSpeed() const { return display.isDoubleSpeed(); } bool isDoubleSpeed() const { return display.isDoubleSpeed(); }
public: public:
explicit Memory(const Interrupter &interrupter); explicit Memory(const Interrupter &interrupter);
bool loaded() const { return cart.loaded(); } bool loaded() const { return cart.loaded(); }
const char * romTitle() const { return cart.romTitle(); } const char * romTitle() const { return cart.romTitle(); }
int debugGetLY() const { return display.debugGetLY(); } void bios_reset(int setting) {
nontrivial_ff_write(0x50, setting, 0);
void setStatePtrs(SaveState &state); }
void loadState(const SaveState &state/*, unsigned long oldCc*/);
void loadSavedata(const char *data) { cart.loadSavedata(data); } int debugGetLY() const { return display.debugGetLY(); }
int saveSavedataLength() {return cart.saveSavedataLength(); }
void saveSavedata(char *dest) { cart.saveSavedata(dest); } void setStatePtrs(SaveState &state);
void updateInput(); void loadState(const SaveState &state/*, unsigned long oldCc*/);
void loadSavedata(const char *data) { cart.loadSavedata(data); }
bool getMemoryArea(int which, unsigned char **data, int *length); // { return cart.getMemoryArea(which, data, length); } int saveSavedataLength() {return cart.saveSavedataLength(); }
void saveSavedata(char *dest) { cart.saveSavedata(dest); }
unsigned long stop(unsigned long cycleCounter); void updateInput();
bool isCgb() const { return display.isCgb(); }
bool ime() const { return intreq.ime(); } bool getMemoryArea(int which, unsigned char **data, int *length); // { return cart.getMemoryArea(which, data, length); }
bool halted() const { return intreq.halted(); }
unsigned long nextEventTime() const { return intreq.minEventTime(); } unsigned long stop(unsigned long cycleCounter);
bool isCgb() const { return display.isCgb(); }
void setLayers(unsigned mask) { display.setLayers(mask); } bool ime() const { return intreq.ime(); }
bool halted() const { return intreq.halted(); }
bool isActive() const { return intreq.eventTime(END) != DISABLED_TIME; } unsigned long nextEventTime() const { return intreq.minEventTime(); }
long cyclesSinceBlit(const unsigned long cc) const { void setLayers(unsigned mask) { display.setLayers(mask); }
return cc < intreq.eventTime(BLIT) ? -1 : static_cast<long>((cc - intreq.eventTime(BLIT)) >> isDoubleSpeed());
} bool isActive() const { return intreq.eventTime(END) != DISABLED_TIME; }
void halt() { intreq.halt(); } long cyclesSinceBlit(const unsigned long cc) const {
void ei(unsigned long cycleCounter) { if (!ime()) { intreq.ei(cycleCounter); } } return cc < intreq.eventTime(BLIT) ? -1 : static_cast<long>((cc - intreq.eventTime(BLIT)) >> isDoubleSpeed());
}
void di() { intreq.di(); }
void halt() { intreq.halt(); }
unsigned ff_read(const unsigned P, const unsigned long cycleCounter) { void ei(unsigned long cycleCounter) { if (!ime()) { intreq.ei(cycleCounter); } }
return P < 0xFF80 ? nontrivial_ff_read(P, cycleCounter) : ioamhram[P - 0xFE00];
} void di() { intreq.di(); }
struct CDMapResult unsigned ff_read(const unsigned P, const unsigned long cycleCounter) {
{ return P < 0xFF80 ? nontrivial_ff_read(P, cycleCounter) : ioamhram[P - 0xFE00];
eCDLog_AddrType type; }
unsigned addr;
}; struct CDMapResult
{
CDMapResult CDMap(const unsigned P) const eCDLog_AddrType type;
{ unsigned addr;
if(P<0x4000) };
{
CDMapResult ret = { eCDLog_AddrType_ROM, P }; CDMapResult CDMap(const unsigned P) const
return ret; {
} if(P<0x4000)
else if(P<0x8000) {
{ CDMapResult ret = { eCDLog_AddrType_ROM, P };
unsigned bank = cart.rmem(P>>12) - cart.rmem(0); return ret;
unsigned addr = P+bank; }
CDMapResult ret = { eCDLog_AddrType_ROM, addr }; else if(P<0x8000)
return ret; {
} unsigned bank = cart.rmem(P>>12) - cart.rmem(0);
else if(P<0xA000) {} unsigned addr = P+bank;
else if(P<0xC000) CDMapResult ret = { eCDLog_AddrType_ROM, addr };
{ return ret;
if(cart.wsrambankptr()) }
{ else if(P<0xA000) {}
//not bankable. but. we're not sure how much might be here else if(P<0xC000)
unsigned char *data; {
int length; if(cart.wsrambankptr())
bool has = cart.getMemoryArea(3,&data,&length); {
unsigned addr = P&(length-1); //not bankable. but. we're not sure how much might be here
if(has && length!=0) unsigned char *data;
{ int length;
CDMapResult ret = { eCDLog_AddrType_CartRAM, addr }; bool has = cart.getMemoryArea(3,&data,&length);
return ret; unsigned addr = P&(length-1);
} if(has && length!=0)
} {
} CDMapResult ret = { eCDLog_AddrType_CartRAM, addr };
else if(P<0xE000) return ret;
{ }
unsigned bank = cart.wramdata(P >> 12 & 1) - cart.wramdata(0); }
unsigned addr = (P&0xFFF)+bank; }
CDMapResult ret = { eCDLog_AddrType_WRAM, addr }; else if(P<0xE000)
return ret; {
} unsigned bank = cart.wramdata(P >> 12 & 1) - cart.wramdata(0);
else if(P<0xFF80) {} unsigned addr = (P&0xFFF)+bank;
else CDMapResult ret = { eCDLog_AddrType_WRAM, addr };
{ return ret;
////this is just for debugging, really, it's pretty useless }
//CDMapResult ret = { eCDLog_AddrType_HRAM, (P-0xFF80) }; else if(P<0xFF80) {}
//return ret; else
} {
////this is just for debugging, really, it's pretty useless
CDMapResult ret = { eCDLog_AddrType_None }; //CDMapResult ret = { eCDLog_AddrType_HRAM, (P-0xFF80) };
return ret; //return ret;
} }
CDMapResult ret = { eCDLog_AddrType_None };
unsigned read(const unsigned P, const unsigned long cycleCounter) { return ret;
if (readCallback) }
readCallback(P);
if(cdCallback)
{ unsigned read(const unsigned P, const unsigned long cycleCounter) {
CDMapResult map = CDMap(P); if (readCallback)
if(map.type != eCDLog_AddrType_None) readCallback(P);
cdCallback(map.addr,map.type,eCDLog_Flags_Data); if(cdCallback)
} {
return cart.rmem(P >> 12) ? cart.rmem(P >> 12)[P] : nontrivial_read(P, cycleCounter); CDMapResult map = CDMap(P);
} if(map.type != eCDLog_AddrType_None)
cdCallback(map.addr,map.type,eCDLog_Flags_Data);
unsigned read_excb(const unsigned P, const unsigned long cycleCounter, bool first) { }
if (execCallback) return cart.rmem(P >> 12) ? cart.rmem(P >> 12)[P] : nontrivial_read(P, cycleCounter);
execCallback(P); }
if(cdCallback)
{ unsigned read_excb(const unsigned P, const unsigned long cycleCounter, bool first) {
CDMapResult map = CDMap(P); if (execCallback)
if(map.type != eCDLog_AddrType_None) execCallback(P);
cdCallback(map.addr,map.type,first?eCDLog_Flags_ExecFirst : eCDLog_Flags_ExecOperand); if(cdCallback)
} {
return cart.rmem(P >> 12) ? cart.rmem(P >> 12)[P] : nontrivial_read(P, cycleCounter); CDMapResult map = CDMap(P);
} if(map.type != eCDLog_AddrType_None)
cdCallback(map.addr,map.type,first?eCDLog_Flags_ExecFirst : eCDLog_Flags_ExecOperand);
unsigned peek(const unsigned P) { }
return cart.rmem(P >> 12) ? cart.rmem(P >> 12)[P] : nontrivial_peek(P); return cart.rmem(P >> 12) ? cart.rmem(P >> 12)[P] : nontrivial_read(P, cycleCounter);
} }
void write_nocb(const unsigned P, const unsigned data, const unsigned long cycleCounter) { unsigned peek(const unsigned P) {
if (cart.wmem(P >> 12)) { return cart.rmem(P >> 12) ? cart.rmem(P >> 12)[P] : nontrivial_peek(P);
cart.wmem(P >> 12)[P] = data; }
} else
nontrivial_write(P, data, cycleCounter); void write_nocb(const unsigned P, const unsigned data, const unsigned long cycleCounter) {
} if (cart.wmem(P >> 12)) {
cart.wmem(P >> 12)[P] = data;
void write(const unsigned P, const unsigned data, const unsigned long cycleCounter) { } else
if (cart.wmem(P >> 12)) { nontrivial_write(P, data, cycleCounter);
cart.wmem(P >> 12)[P] = data; }
} else
nontrivial_write(P, data, cycleCounter); void write(const unsigned P, const unsigned data, const unsigned long cycleCounter) {
if (writeCallback) if (cart.wmem(P >> 12)) {
writeCallback(P); cart.wmem(P >> 12)[P] = data;
if(cdCallback) } else
{ nontrivial_write(P, data, cycleCounter);
CDMapResult map = CDMap(P); if (writeCallback)
if(map.type != eCDLog_AddrType_None) writeCallback(P);
cdCallback(map.addr,map.type,eCDLog_Flags_Data); if(cdCallback)
} {
} CDMapResult map = CDMap(P);
if(map.type != eCDLog_AddrType_None)
void ff_write(const unsigned P, const unsigned data, const unsigned long cycleCounter) { cdCallback(map.addr,map.type,eCDLog_Flags_Data);
if (P - 0xFF80u < 0x7Fu) { }
ioamhram[P - 0xFE00] = data; }
} else
nontrivial_ff_write(P, data, cycleCounter); void ff_write(const unsigned P, const unsigned data, const unsigned long cycleCounter) {
if(cdCallback) if (P - 0xFF80u < 0x7Fu) {
{ ioamhram[P - 0xFE00] = data;
CDMapResult map = CDMap(P); } else
if(map.type != eCDLog_AddrType_None) nontrivial_ff_write(P, data, cycleCounter);
cdCallback(map.addr,map.type,eCDLog_Flags_Data); if(cdCallback)
} {
} CDMapResult map = CDMap(P);
if(map.type != eCDLog_AddrType_None)
unsigned long event(unsigned long cycleCounter); cdCallback(map.addr,map.type,eCDLog_Flags_Data);
unsigned long resetCounters(unsigned long cycleCounter); }
}
int loadROM(const char *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat);
unsigned long event(unsigned long cycleCounter);
void setInputGetter(unsigned (*getInput)()) { unsigned long resetCounters(unsigned long cycleCounter);
this->getInput = getInput;
} int loadROM(const char *romfiledata, unsigned romfilelength, const char *biosfiledata, unsigned biosfilelength, bool forceDmg, bool multicartCompat);
void setReadCallback(void (*callback)(unsigned)) { void setInputGetter(unsigned (*getInput)()) {
this->readCallback = callback; this->getInput = getInput;
} }
void setWriteCallback(void (*callback)(unsigned)) {
this->writeCallback = callback; void setReadCallback(void (*callback)(unsigned)) {
} this->readCallback = callback;
void setExecCallback(void (*callback)(unsigned)) { }
this->execCallback = callback; void setWriteCallback(void (*callback)(unsigned)) {
} this->writeCallback = callback;
void setCDCallback(CDCallback cdc) { }
this->cdCallback = cdc; void setExecCallback(void (*callback)(unsigned)) {
} this->execCallback = callback;
}
void setScanlineCallback(void (*callback)(), int sl) { void setCDCallback(CDCallback cdc) {
display.setScanlineCallback(callback, sl); this->cdCallback = cdc;
} }
void setRTCCallback(std::uint32_t (*callback)()) { void setScanlineCallback(void (*callback)(), int sl) {
cart.setRTCCallback(callback); display.setScanlineCallback(callback, sl);
} }
void setEndtime(unsigned long cc, unsigned long inc); void setRTCCallback(std::uint32_t (*callback)()) {
cart.setRTCCallback(callback);
void setSoundBuffer(uint_least32_t *const buf) { sound.setBuffer(buf); } }
unsigned fillSoundBuffer(unsigned long cc);
void setEndtime(unsigned long cc, unsigned long inc);
void setVideoBuffer(uint_least32_t *const videoBuf, const int pitch) {
display.setVideoBuffer(videoBuf, pitch); void setSoundBuffer(uint_least32_t *const buf) { sound.setBuffer(buf); }
} unsigned fillSoundBuffer(unsigned long cc);
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned long rgb32); void setVideoBuffer(uint_least32_t *const videoBuf, const int pitch) {
void setCgbPalette(unsigned *lut); display.setVideoBuffer(videoBuf, pitch);
}
int LinkStatus(int which);
void setDmgPaletteColor(unsigned palNum, unsigned colorNum, unsigned long rgb32);
void setCgbPalette(unsigned *lut);
int LinkStatus(int which);
template<bool isReader>void SyncState(NewState *ns); template<bool isReader>void SyncState(NewState *ns);
}; };
} }
#endif #endif

View File

@ -38,7 +38,7 @@ struct SaveState {
void set(T *ptr, const unsigned long sz) { this->ptr = ptr; this->sz = sz; } void set(T *ptr, const unsigned long sz) { this->ptr = ptr; this->sz = sz; }
friend class SaverList; friend class SaverList;
friend void setInitState(SaveState &, bool, bool, std::uint32_t); friend void setInitState(SaveState &, bool, bool, std::uint32_t, bool);
}; };
struct CPU { struct CPU {