Add files via upload
This commit is contained in:
parent
6e5eaba155
commit
e65393ec57
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
@ -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
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
Loading…
Reference in New Issue