Refactor cartridge code
This commit is contained in:
parent
839c8abf54
commit
a79febdef9
|
@ -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 GAMBATTE_H
|
||||
#define GAMBATTE_H
|
||||
|
||||
|
@ -23,11 +23,10 @@
|
|||
#include "loadres.h"
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <cstdint>
|
||||
#include "newstate.h"
|
||||
|
||||
namespace gambatte {
|
||||
|
||||
enum { BG_PALETTE = 0, SP1_PALETTE = 1, SP2_PALETTE = 2 };
|
||||
|
||||
typedef void (*MemoryCallback)(int32_t address, int64_t cycleOffset);
|
||||
|
@ -57,9 +56,11 @@ public:
|
|||
MULTICART_COMPAT = 4, /**< Use heuristics to detect and support some multicart MBCs disguised as MBC1. */
|
||||
};
|
||||
|
||||
/** Load ROM image.
|
||||
/**
|
||||
* Load ROM image.
|
||||
*
|
||||
* @param romfile Path to rom image file. Typically a .gbc, .gb, or .zip-file (if zip-support is compiled in).
|
||||
* @param romfile Path to rom image file. Typically a .gbc, .gb, or .zip-file (if
|
||||
* zip-support is compiled in).
|
||||
* @param flags ORed combination of LoadFlags.
|
||||
* @return 0 on success, negative value on failure.
|
||||
*/
|
||||
|
@ -68,24 +69,33 @@ public:
|
|||
int loadGBCBios(const char* biosfiledata);
|
||||
int loadDMGBios(const char* biosfiledata);
|
||||
|
||||
/** Emulates until at least 'samples' stereo sound samples are produced in the supplied buffer,
|
||||
* or until a video frame has been drawn.
|
||||
/**
|
||||
* Emulates until at least 'samples' audio samples are produced in the
|
||||
* supplied audio buffer, or until a video frame has been drawn.
|
||||
*
|
||||
* There are 35112 stereo sound samples in a video frame.
|
||||
* May run for up to 2064 stereo samples too long.
|
||||
* A stereo sample consists of two native endian 2s complement 16-bit PCM samples,
|
||||
* with the left sample preceding the right one. Usually casting soundBuf to/from
|
||||
* short* is OK and recommended. The reason for not using a short* in the interface
|
||||
* is to avoid implementation-defined behaviour without compromising performance.
|
||||
* There are 35112 audio (stereo) samples in a video frame.
|
||||
* May run for up to 2064 audio samples too long.
|
||||
*
|
||||
* An audio sample consists of two native endian 2s complement 16-bit PCM samples,
|
||||
* with the left sample preceding the right one. Usually casting audioBuf to
|
||||
* int16_t* is OK. The reason for using an uint_least32_t* in the interface is to
|
||||
* avoid implementation-defined behavior without compromising performance.
|
||||
* libgambatte is strictly c++98, so fixed-width types are not an option (and even
|
||||
* c99/c++11 cannot guarantee their availability).
|
||||
*
|
||||
* Returns early when a new video frame has finished drawing in the video buffer,
|
||||
* such that the caller may update the video output before the frame is overwritten.
|
||||
* The return value indicates whether a new video frame has been drawn, and the
|
||||
* exact time (in number of samples) at which it was drawn.
|
||||
* exact time (in number of samples) at which it was completed.
|
||||
*
|
||||
* @param soundBuf buffer with space >= samples + 2064
|
||||
* @param samples in: number of stereo samples to produce, out: actual number of samples produced
|
||||
* @return sample number at which the video frame was produced. -1 means no frame was produced.
|
||||
* @param videoBuf 160x144 RGB32 (native endian) video frame buffer or 0
|
||||
* @param pitch distance in number of pixels (not bytes) from the start of one line
|
||||
* to the next in videoBuf.
|
||||
* @param audioBuf buffer with space >= samples + 2064
|
||||
* @param samples in: number of stereo samples to produce,
|
||||
* out: actual number of samples produced
|
||||
* @return sample offset in audioBuf at which the video frame was completed, or -1
|
||||
* if no new video frame was completed.
|
||||
*/
|
||||
std::ptrdiff_t runFor(gambatte::uint_least32_t *soundBuf, std::size_t &samples);
|
||||
|
||||
|
@ -93,12 +103,14 @@ public:
|
|||
|
||||
void setLayers(unsigned mask);
|
||||
|
||||
/** Reset to initial state.
|
||||
/**
|
||||
* Reset to initial state.
|
||||
* Equivalent to reloading a ROM image, or turning a Game Boy Color off and on again.
|
||||
*/
|
||||
void reset(std::uint32_t now, unsigned div);
|
||||
|
||||
/** @param palNum 0 <= palNum < 3. One of BG_PALETTE, SP1_PALETTE and SP2_PALETTE.
|
||||
/**
|
||||
* @param palNum 0 <= palNum < 3. One of BG_PALETTE, SP1_PALETTE and SP2_PALETTE.
|
||||
* @param colorNum 0 <= colorNum < 4
|
||||
*/
|
||||
void setDmgPaletteColor(int palNum, int colorNum, unsigned long rgb32);
|
||||
|
@ -150,8 +162,8 @@ private:
|
|||
struct Priv;
|
||||
Priv *const p_;
|
||||
|
||||
GB(const GB &);
|
||||
GB & operator=(const GB &);
|
||||
GB(GB const &);
|
||||
GB & operator=(GB const &);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -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 GAMBATTE_INT_H
|
||||
#define GAMBATTE_INT_H
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,21 +1,21 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2007-2010 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-2010 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 CARTRIDGE_H
|
||||
#define CARTRIDGE_H
|
||||
|
||||
|
@ -30,26 +30,12 @@
|
|||
|
||||
namespace gambatte {
|
||||
|
||||
//DOOM
|
||||
//enum eAddressMappingType
|
||||
//{
|
||||
// eAddressMappingType_ROM,
|
||||
// eAddressMappingType_RAM
|
||||
//};
|
||||
//
|
||||
//struct AddressMapping
|
||||
//{
|
||||
// int32_t address;
|
||||
// eAddressMappingType type;
|
||||
//};
|
||||
|
||||
class Mbc {
|
||||
public:
|
||||
virtual ~Mbc() {}
|
||||
virtual void romWrite(unsigned P, unsigned data) = 0;
|
||||
virtual void loadState(const SaveState::Mem &ss) = 0;
|
||||
virtual void loadState(SaveState::Mem const &ss) = 0;
|
||||
virtual bool isAddressWithinAreaRombankCanBeMappedTo(unsigned address, unsigned rombank) const = 0;
|
||||
//virtual void mapAddress(AddressMapping* mapping, unsigned address) const = 0; //DOOM
|
||||
|
||||
template<bool isReader>void SyncState(NewState *ns)
|
||||
{
|
||||
|
@ -60,52 +46,45 @@ public:
|
|||
};
|
||||
|
||||
class Cartridge {
|
||||
MemPtrs memptrs;
|
||||
Rtc rtc;
|
||||
std::unique_ptr<Mbc> mbc;
|
||||
|
||||
public:
|
||||
void setStatePtrs(SaveState &);
|
||||
void loadState(const SaveState &);
|
||||
|
||||
bool loaded() const { return mbc.get(); }
|
||||
|
||||
const unsigned char * rmem(unsigned area) const { return memptrs.rmem(area); }
|
||||
unsigned char * wmem(unsigned area) const { return memptrs.wmem(area); }
|
||||
unsigned char * vramdata() const { return memptrs.vramdata(); }
|
||||
unsigned char * romdata(unsigned area) const { return memptrs.romdata(area); }
|
||||
unsigned char * wramdata(unsigned area) const { return memptrs.wramdata(area); }
|
||||
const unsigned char * rdisabledRam() const { return memptrs.rdisabledRam(); }
|
||||
const unsigned char * rsrambankptr() const { return memptrs.rsrambankptr(); }
|
||||
unsigned char * wsrambankptr() const { return memptrs.wsrambankptr(); }
|
||||
unsigned char * vrambankptr() const { return memptrs.vrambankptr(); }
|
||||
OamDmaSrc oamDmaSrc() const { return memptrs.oamDmaSrc(); }
|
||||
unsigned curRomBank() const { return memptrs.curRomBank(); }
|
||||
|
||||
void setVrambank(unsigned bank) { memptrs.setVrambank(bank); }
|
||||
void setWrambank(unsigned bank) { memptrs.setWrambank(bank); }
|
||||
void setOamDmaSrc(OamDmaSrc oamDmaSrc) { memptrs.setOamDmaSrc(oamDmaSrc); }
|
||||
|
||||
void mbcWrite(unsigned addr, unsigned data) { mbc->romWrite(addr, data); }
|
||||
|
||||
bool isCgb() const { return gambatte::isCgb(memptrs); }
|
||||
|
||||
void rtcWrite(unsigned data) { rtc.write(data); }
|
||||
unsigned char rtcRead() const { return *rtc.getActive(); }
|
||||
|
||||
void loadSavedata(const char *data);
|
||||
void loadState(SaveState const &);
|
||||
bool loaded() const { return mbc_.get(); }
|
||||
unsigned char const * rmem(unsigned area) const { return memptrs_.rmem(area); }
|
||||
unsigned char * wmem(unsigned area) const { return memptrs_.wmem(area); }
|
||||
unsigned char * vramdata() const { return memptrs_.vramdata(); }
|
||||
unsigned char * romdata(unsigned area) const { return memptrs_.romdata(area); }
|
||||
unsigned char * wramdata(unsigned area) const { return memptrs_.wramdata(area); }
|
||||
unsigned char const * rdisabledRam() const { return memptrs_.rdisabledRam(); }
|
||||
unsigned char const * rsrambankptr() const { return memptrs_.rsrambankptr(); }
|
||||
unsigned char * wsrambankptr() const { return memptrs_.wsrambankptr(); }
|
||||
unsigned char * vrambankptr() const { return memptrs_.vrambankptr(); }
|
||||
OamDmaSrc oamDmaSrc() const { return memptrs_.oamDmaSrc(); }
|
||||
void setVrambank(unsigned bank) { memptrs_.setVrambank(bank); }
|
||||
void setWrambank(unsigned bank) { memptrs_.setWrambank(bank); }
|
||||
void setOamDmaSrc(OamDmaSrc oamDmaSrc) { memptrs_.setOamDmaSrc(oamDmaSrc); }
|
||||
unsigned curRomBank() const { return memptrs_.curRomBank(); }
|
||||
void mbcWrite(unsigned addr, unsigned data) { mbc_->romWrite(addr, data); }
|
||||
bool isCgb() const { return gambatte::isCgb(memptrs_); }
|
||||
void rtcWrite(unsigned data) { rtc_.write(data); }
|
||||
unsigned char rtcRead() const { return *rtc_.activeData(); }
|
||||
void loadSavedata(char const *data);
|
||||
int saveSavedataLength();
|
||||
void saveSavedata(char *dest);
|
||||
|
||||
bool getMemoryArea(int which, unsigned char **data, int *length) const;
|
||||
|
||||
LoadRes loadROM(const char *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat);
|
||||
const char * romTitle() const { return reinterpret_cast<const char *>(memptrs.romdata() + 0x134); }
|
||||
LoadRes loadROM(char const *romfiledata, unsigned romfilelength, bool forceDmg, bool multicartCompat);
|
||||
char const * romTitle() const { return reinterpret_cast<char const *>(memptrs_.romdata() + 0x134); }
|
||||
|
||||
void setRTCCallback(std::uint32_t (*callback)()) {
|
||||
rtc.setRTCCallback(callback);
|
||||
rtc_.setRTCCallback(callback);
|
||||
}
|
||||
|
||||
private:
|
||||
MemPtrs memptrs_;
|
||||
Rtc rtc_;
|
||||
std::unique_ptr<Mbc> mbc_;
|
||||
|
||||
public:
|
||||
template<bool isReader>void SyncState(NewState *ns);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2007-2010 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-2010 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.
|
||||
//
|
||||
|
||||
#include "memptrs.h"
|
||||
#include <algorithm>
|
||||
#include <cstring>
|
||||
|
@ -23,10 +23,19 @@
|
|||
namespace gambatte {
|
||||
|
||||
MemPtrs::MemPtrs()
|
||||
: rmem_(), wmem_(), romdata_(), wramdata_(), vrambankptr_(0), rsrambankptr_(0),
|
||||
wsrambankptr_(0), memchunk_(0), rambankdata_(0), wramdataend_(0), oamDmaSrc_(OAM_DMA_SRC_OFF),
|
||||
curRomBank_(1),
|
||||
memchunk_len(0)
|
||||
: rmem_()
|
||||
, wmem_()
|
||||
, romdata_()
|
||||
, wramdata_()
|
||||
, vrambankptr_(0)
|
||||
, rsrambankptr_(0)
|
||||
, wsrambankptr_(0)
|
||||
, memchunk_(0)
|
||||
, rambankdata_(0)
|
||||
, wramdataend_(0)
|
||||
, oamDmaSrc_(oam_dma_src_off)
|
||||
, curRomBank_(1)
|
||||
, memchunk_len(0)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -34,7 +43,7 @@ MemPtrs::~MemPtrs() {
|
|||
delete []memchunk_;
|
||||
}
|
||||
|
||||
void MemPtrs::reset(const unsigned rombanks, const unsigned rambanks, const unsigned wrambanks) {
|
||||
void MemPtrs::reset(unsigned const rombanks, unsigned const rambanks, unsigned const wrambanks) {
|
||||
delete []memchunk_;
|
||||
memchunk_len = 0x4000 + rombanks * 0x4000ul + 0x4000 + rambanks * 0x2000ul + wrambanks * 0x1000ul + 0x4000;
|
||||
memchunk_ = new unsigned char[memchunk_len];
|
||||
|
@ -46,7 +55,7 @@ void MemPtrs::reset(const unsigned rombanks, const unsigned rambanks, const unsi
|
|||
|
||||
std::memset(rdisabledRamw(), 0xFF, 0x2000);
|
||||
|
||||
oamDmaSrc_ = OAM_DMA_SRC_OFF;
|
||||
oamDmaSrc_ = oam_dma_src_off;
|
||||
rmem_[0x3] = rmem_[0x2] = rmem_[0x1] = rmem_[0x0] = romdata_[0];
|
||||
rmem_[0xC] = wmem_[0xC] = wramdata_[0] - 0xC000;
|
||||
rmem_[0xE] = wmem_[0xE] = wramdata_[0] - 0xE000;
|
||||
|
@ -60,39 +69,43 @@ void MemPtrs::reset(const unsigned rombanks, const unsigned rambanks, const unsi
|
|||
memchunk_savelen = wramdataend() - memchunk_ - memchunk_saveoffs;
|
||||
}
|
||||
|
||||
void MemPtrs::setRombank0(const unsigned bank) {
|
||||
void MemPtrs::setRombank0(unsigned bank) {
|
||||
romdata_[0] = romdata() + bank * 0x4000ul;
|
||||
rmem_[0x3] = rmem_[0x2] = rmem_[0x1] = rmem_[0x0] = romdata_[0];
|
||||
disconnectOamDmaAreas();
|
||||
}
|
||||
|
||||
void MemPtrs::setRombank(const unsigned bank) {
|
||||
void MemPtrs::setRombank(unsigned bank) {
|
||||
curRomBank_ = bank;
|
||||
romdata_[1] = romdata() + bank * 0x4000ul - 0x4000;
|
||||
rmem_[0x7] = rmem_[0x6] = rmem_[0x5] = rmem_[0x4] = romdata_[1];
|
||||
disconnectOamDmaAreas();
|
||||
}
|
||||
|
||||
void MemPtrs::setRambank(const unsigned flags, const unsigned rambank) {
|
||||
unsigned char *const srambankptr = flags & RTC_EN
|
||||
? 0
|
||||
: (rambankdata() != rambankdataend()
|
||||
? rambankdata_ + rambank * 0x2000ul - 0xA000 : wdisabledRam() - 0xA000);
|
||||
void MemPtrs::setRambank(unsigned const flags, unsigned const rambank) {
|
||||
unsigned char *srambankptr = 0;
|
||||
if (!(flags & rtc_en)) {
|
||||
srambankptr = rambankdata() != rambankdataend()
|
||||
? rambankdata_ + rambank * 0x2000ul - 0xA000
|
||||
: wdisabledRam() - 0xA000;
|
||||
}
|
||||
|
||||
rsrambankptr_ = (flags & READ_EN) && srambankptr != wdisabledRam() - 0xA000 ? srambankptr : rdisabledRamw() - 0xA000;
|
||||
wsrambankptr_ = flags & WRITE_EN ? srambankptr : wdisabledRam() - 0xA000;
|
||||
rsrambankptr_ = (flags & read_en) && srambankptr != wdisabledRam() - 0xA000
|
||||
? srambankptr
|
||||
: rdisabledRamw() - 0xA000;
|
||||
wsrambankptr_ = flags & write_en ? srambankptr : wdisabledRam() - 0xA000;
|
||||
rmem_[0xB] = rmem_[0xA] = rsrambankptr_;
|
||||
wmem_[0xB] = wmem_[0xA] = wsrambankptr_;
|
||||
disconnectOamDmaAreas();
|
||||
}
|
||||
|
||||
void MemPtrs::setWrambank(const unsigned bank) {
|
||||
void MemPtrs::setWrambank(unsigned bank) {
|
||||
wramdata_[1] = wramdata_[0] + (bank & 0x07 ? bank & 0x07 : 1) * 0x1000;
|
||||
rmem_[0xD] = wmem_[0xD] = wramdata_[1] - 0xD000;
|
||||
disconnectOamDmaAreas();
|
||||
}
|
||||
|
||||
void MemPtrs::setOamDmaSrc(const OamDmaSrc oamDmaSrc) {
|
||||
void MemPtrs::setOamDmaSrc(OamDmaSrc oamDmaSrc) {
|
||||
rmem_[0x3] = rmem_[0x2] = rmem_[0x1] = rmem_[0x0] = romdata_[0];
|
||||
rmem_[0x7] = rmem_[0x6] = rmem_[0x5] = rmem_[0x4] = romdata_[1];
|
||||
rmem_[0xB] = rmem_[0xA] = rsrambankptr_;
|
||||
|
@ -108,37 +121,37 @@ void MemPtrs::setOamDmaSrc(const OamDmaSrc oamDmaSrc) {
|
|||
void MemPtrs::disconnectOamDmaAreas() {
|
||||
if (isCgb(*this)) {
|
||||
switch (oamDmaSrc_) {
|
||||
case OAM_DMA_SRC_ROM: // fall through
|
||||
case OAM_DMA_SRC_SRAM:
|
||||
case OAM_DMA_SRC_INVALID:
|
||||
case oam_dma_src_rom: // fall through
|
||||
case oam_dma_src_sram:
|
||||
case oam_dma_src_invalid:
|
||||
std::fill(rmem_, rmem_ + 8, static_cast<unsigned char *>(0));
|
||||
rmem_[0xB] = rmem_[0xA] = 0;
|
||||
wmem_[0xB] = wmem_[0xA] = 0;
|
||||
break;
|
||||
case OAM_DMA_SRC_VRAM:
|
||||
case oam_dma_src_vram:
|
||||
break;
|
||||
case OAM_DMA_SRC_WRAM:
|
||||
case oam_dma_src_wram:
|
||||
rmem_[0xE] = rmem_[0xD] = rmem_[0xC] = 0;
|
||||
wmem_[0xE] = wmem_[0xD] = wmem_[0xC] = 0;
|
||||
break;
|
||||
case OAM_DMA_SRC_OFF:
|
||||
case oam_dma_src_off:
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (oamDmaSrc_) {
|
||||
case OAM_DMA_SRC_ROM: // fall through
|
||||
case OAM_DMA_SRC_SRAM:
|
||||
case OAM_DMA_SRC_WRAM:
|
||||
case OAM_DMA_SRC_INVALID:
|
||||
case oam_dma_src_rom: // fall through
|
||||
case oam_dma_src_sram:
|
||||
case oam_dma_src_wram:
|
||||
case oam_dma_src_invalid:
|
||||
std::fill(rmem_, rmem_ + 8, static_cast<unsigned char *>(0));
|
||||
rmem_[0xB] = rmem_[0xA] = 0;
|
||||
wmem_[0xB] = wmem_[0xA] = 0;
|
||||
rmem_[0xE] = rmem_[0xD] = rmem_[0xC] = 0;
|
||||
wmem_[0xE] = wmem_[0xD] = wmem_[0xC] = 0;
|
||||
break;
|
||||
case OAM_DMA_SRC_VRAM:
|
||||
case oam_dma_src_vram:
|
||||
break;
|
||||
case OAM_DMA_SRC_OFF:
|
||||
case oam_dma_src_off:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,21 +1,21 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2007-2010 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-2010 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 MEMPTRS_H
|
||||
#define MEMPTRS_H
|
||||
|
||||
|
@ -23,43 +23,22 @@
|
|||
|
||||
namespace gambatte {
|
||||
|
||||
enum OamDmaSrc { OAM_DMA_SRC_ROM, OAM_DMA_SRC_SRAM, OAM_DMA_SRC_VRAM,
|
||||
OAM_DMA_SRC_WRAM, OAM_DMA_SRC_INVALID, OAM_DMA_SRC_OFF };
|
||||
enum OamDmaSrc { oam_dma_src_rom,
|
||||
oam_dma_src_sram,
|
||||
oam_dma_src_vram,
|
||||
oam_dma_src_wram,
|
||||
oam_dma_src_invalid,
|
||||
oam_dma_src_off, };
|
||||
|
||||
class MemPtrs {
|
||||
const unsigned char *rmem_[0x10];
|
||||
unsigned char *wmem_[0x10];
|
||||
|
||||
unsigned char *romdata_[2];
|
||||
unsigned char *wramdata_[2];
|
||||
unsigned char *vrambankptr_;
|
||||
unsigned char *rsrambankptr_;
|
||||
unsigned char *wsrambankptr_;
|
||||
unsigned char *memchunk_;
|
||||
unsigned char *rambankdata_;
|
||||
unsigned char *wramdataend_;
|
||||
|
||||
OamDmaSrc oamDmaSrc_;
|
||||
|
||||
unsigned curRomBank_;
|
||||
|
||||
int memchunk_len;
|
||||
int memchunk_saveoffs;
|
||||
int memchunk_savelen;
|
||||
|
||||
MemPtrs(const MemPtrs &);
|
||||
MemPtrs & operator=(const MemPtrs &);
|
||||
void disconnectOamDmaAreas();
|
||||
unsigned char * rdisabledRamw() const { return wramdataend_ ; }
|
||||
unsigned char * wdisabledRam() const { return wramdataend_ + 0x2000; }
|
||||
public:
|
||||
enum RamFlag { READ_EN = 1, WRITE_EN = 2, RTC_EN = 4 };
|
||||
enum RamFlag { read_en = 1, write_en = 2, rtc_en = 4 };
|
||||
|
||||
MemPtrs();
|
||||
~MemPtrs();
|
||||
void reset(unsigned rombanks, unsigned rambanks, unsigned wrambanks);
|
||||
|
||||
const unsigned char * rmem(unsigned area) const { return rmem_[area]; }
|
||||
unsigned char const * rmem(unsigned area) const { return rmem_[area]; }
|
||||
unsigned char * wmem(unsigned area) const { return wmem_[area]; }
|
||||
unsigned char * vramdata() const { return rambankdata_ - 0x4000; }
|
||||
unsigned char * vramdataend() const { return rambankdata_; }
|
||||
|
@ -70,8 +49,8 @@ public:
|
|||
unsigned char * wramdataend() const { return wramdataend_; }
|
||||
unsigned char * rambankdata() const { return rambankdata_; }
|
||||
unsigned char * rambankdataend() const { return wramdata_[0]; }
|
||||
const unsigned char * rdisabledRam() const { return rdisabledRamw(); }
|
||||
const unsigned char * rsrambankptr() const { return rsrambankptr_; }
|
||||
unsigned char const * rdisabledRam() const { return rdisabledRamw(); }
|
||||
unsigned char const * rsrambankptr() const { return rsrambankptr_; }
|
||||
unsigned char * wsrambankptr() const { return wsrambankptr_; }
|
||||
unsigned char * vrambankptr() const { return vrambankptr_; }
|
||||
OamDmaSrc oamDmaSrc() const { return oamDmaSrc_; }
|
||||
|
@ -84,10 +63,36 @@ public:
|
|||
void setWrambank(unsigned bank);
|
||||
void setOamDmaSrc(OamDmaSrc oamDmaSrc);
|
||||
|
||||
private:
|
||||
unsigned char const *rmem_[0x10];
|
||||
unsigned char *wmem_[0x10];
|
||||
unsigned char *romdata_[2];
|
||||
unsigned char *wramdata_[2];
|
||||
unsigned char *vrambankptr_;
|
||||
unsigned char *rsrambankptr_;
|
||||
unsigned char *wsrambankptr_;
|
||||
unsigned char *memchunk_;
|
||||
unsigned char *rambankdata_;
|
||||
unsigned char *wramdataend_;
|
||||
OamDmaSrc oamDmaSrc_;
|
||||
|
||||
unsigned curRomBank_;
|
||||
|
||||
int memchunk_len;
|
||||
int memchunk_saveoffs;
|
||||
int memchunk_savelen;
|
||||
|
||||
MemPtrs(MemPtrs const &);
|
||||
MemPtrs & operator=(MemPtrs const &);
|
||||
void disconnectOamDmaAreas();
|
||||
unsigned char * rdisabledRamw() const { return wramdataend_ ; }
|
||||
unsigned char * wdisabledRam() const { return wramdataend_ + 0x2000; }
|
||||
|
||||
public:
|
||||
template<bool isReader>void SyncState(NewState *ns);
|
||||
};
|
||||
|
||||
inline bool isCgb(const MemPtrs &memptrs) {
|
||||
inline bool isCgb(MemPtrs const &memptrs) {
|
||||
return memptrs.wramdataend() - memptrs.wramdata(0) == 0x8000;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
//
|
||||
|
||||
#include "rtc.h"
|
||||
#include "../savestate.h"
|
||||
#include <cstdlib>
|
||||
|
@ -23,155 +23,154 @@
|
|||
namespace gambatte {
|
||||
|
||||
Rtc::Rtc()
|
||||
: activeData(NULL),
|
||||
activeSet(NULL),
|
||||
baseTime(0),
|
||||
haltTime(0),
|
||||
index(5),
|
||||
dataDh(0),
|
||||
dataDl(0),
|
||||
dataH(0),
|
||||
dataM(0),
|
||||
dataS(0),
|
||||
enabled(false),
|
||||
lastLatchData(false),
|
||||
timeCB(0)
|
||||
: activeData_(0)
|
||||
, activeSet_(0)
|
||||
, baseTime_(0)
|
||||
, haltTime_(0)
|
||||
, index_(5)
|
||||
, dataDh_(0)
|
||||
, dataDl_(0)
|
||||
, dataH_(0)
|
||||
, dataM_(0)
|
||||
, dataS_(0)
|
||||
, enabled_(false)
|
||||
, lastLatchData_(false)
|
||||
, timeCB(0)
|
||||
{
|
||||
}
|
||||
|
||||
void Rtc::doLatch() {
|
||||
std::uint32_t tmp = ((dataDh & 0x40) ? haltTime : timeCB()) - baseTime;
|
||||
std::uint32_t tmp = ((dataDh_ & 0x40) ? haltTime_ : timeCB()) - baseTime_;
|
||||
|
||||
while (tmp > 0x1FF * 86400) {
|
||||
baseTime += 0x1FF * 86400;
|
||||
baseTime_ += 0x1FF * 86400;
|
||||
tmp -= 0x1FF * 86400;
|
||||
dataDh |= 0x80;
|
||||
dataDh_ |= 0x80;
|
||||
}
|
||||
|
||||
dataDl = (tmp / 86400) & 0xFF;
|
||||
dataDh &= 0xFE;
|
||||
dataDh |= ((tmp / 86400) & 0x100) >> 8;
|
||||
dataDl_ = (tmp / 86400) & 0xFF;
|
||||
dataDh_ &= 0xFE;
|
||||
dataDh_ |= ((tmp / 86400) & 0x100) >> 8;
|
||||
tmp %= 86400;
|
||||
|
||||
dataH = tmp / 3600;
|
||||
dataH_ = tmp / 3600;
|
||||
tmp %= 3600;
|
||||
|
||||
dataM = tmp / 60;
|
||||
dataM_ = tmp / 60;
|
||||
tmp %= 60;
|
||||
|
||||
dataS = tmp;
|
||||
dataS_ = tmp;
|
||||
}
|
||||
|
||||
void Rtc::doSwapActive() {
|
||||
if (!enabled || index > 4) {
|
||||
activeData = NULL;
|
||||
activeSet = NULL;
|
||||
} else switch (index) {
|
||||
if (!enabled_ || index_ > 4) {
|
||||
activeData_ = 0;
|
||||
activeSet_ = 0;
|
||||
} else switch (index_) {
|
||||
case 0x00:
|
||||
activeData = &dataS;
|
||||
activeSet = &Rtc::setS;
|
||||
activeData_ = &dataS_;
|
||||
activeSet_ = &Rtc::setS;
|
||||
break;
|
||||
case 0x01:
|
||||
activeData = &dataM;
|
||||
activeSet = &Rtc::setM;
|
||||
activeData_ = &dataM_;
|
||||
activeSet_ = &Rtc::setM;
|
||||
break;
|
||||
case 0x02:
|
||||
activeData = &dataH;
|
||||
activeSet = &Rtc::setH;
|
||||
activeData_ = &dataH_;
|
||||
activeSet_ = &Rtc::setH;
|
||||
break;
|
||||
case 0x03:
|
||||
activeData = &dataDl;
|
||||
activeSet = &Rtc::setDl;
|
||||
activeData_ = &dataDl_;
|
||||
activeSet_ = &Rtc::setDl;
|
||||
break;
|
||||
case 0x04:
|
||||
activeData = &dataDh;
|
||||
activeSet = &Rtc::setDh;
|
||||
activeData_ = &dataDh_;
|
||||
activeSet_ = &Rtc::setDh;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Rtc::loadState(const SaveState &state) {
|
||||
baseTime = state.rtc.baseTime;
|
||||
haltTime = state.rtc.haltTime;
|
||||
dataDh = state.rtc.dataDh;
|
||||
dataDl = state.rtc.dataDl;
|
||||
dataH = state.rtc.dataH;
|
||||
dataM = state.rtc.dataM;
|
||||
dataS = state.rtc.dataS;
|
||||
lastLatchData = state.rtc.lastLatchData;
|
||||
|
||||
void Rtc::loadState(SaveState const &state) {
|
||||
baseTime_ = state.rtc.baseTime;
|
||||
haltTime_ = state.rtc.haltTime;
|
||||
dataDh_ = state.rtc.dataDh;
|
||||
dataDl_ = state.rtc.dataDl;
|
||||
dataH_ = state.rtc.dataH;
|
||||
dataM_ = state.rtc.dataM;
|
||||
dataS_ = state.rtc.dataS;
|
||||
lastLatchData_ = state.rtc.lastLatchData;
|
||||
doSwapActive();
|
||||
}
|
||||
|
||||
void Rtc::setDh(const unsigned new_dh) {
|
||||
const std::uint32_t unixtime = (dataDh & 0x40) ? haltTime : timeCB();
|
||||
const std::uint32_t old_highdays = ((unixtime - baseTime) / 86400) & 0x100;
|
||||
baseTime += old_highdays * 86400;
|
||||
baseTime -= ((new_dh & 0x1) << 8) * 86400;
|
||||
void Rtc::setDh(unsigned const newDh) {
|
||||
const std::uint32_t unixtime = (dataDh_ & 0x40) ? haltTime_ : timeCB();
|
||||
const std::uint32_t oldHighdays = ((unixtime - baseTime_) / 86400) & 0x100;
|
||||
baseTime_ += oldHighdays * 86400;
|
||||
baseTime_ -= ((newDh & 0x1) << 8) * 86400;
|
||||
|
||||
if ((dataDh ^ new_dh) & 0x40) {
|
||||
if (new_dh & 0x40)
|
||||
haltTime = timeCB();
|
||||
if ((dataDh_ ^ newDh) & 0x40) {
|
||||
if (newDh & 0x40)
|
||||
haltTime_ = timeCB();
|
||||
else
|
||||
baseTime += timeCB() - haltTime;
|
||||
baseTime_ += timeCB() - haltTime_;
|
||||
}
|
||||
}
|
||||
|
||||
void Rtc::setDl(const unsigned new_lowdays) {
|
||||
const std::uint32_t unixtime = (dataDh & 0x40) ? haltTime : timeCB();
|
||||
const std::uint32_t old_lowdays = ((unixtime - baseTime) / 86400) & 0xFF;
|
||||
baseTime += old_lowdays * 86400;
|
||||
baseTime -= new_lowdays * 86400;
|
||||
void Rtc::setDl(unsigned const newLowdays) {
|
||||
const std::uint32_t unixtime = (dataDh_ & 0x40) ? haltTime_ : timeCB();
|
||||
const std::uint32_t oldLowdays = ((unixtime - baseTime_) / 86400) & 0xFF;
|
||||
baseTime_ += oldLowdays * 86400;
|
||||
baseTime_ -= newLowdays * 86400;
|
||||
}
|
||||
|
||||
void Rtc::setH(const unsigned new_hours) {
|
||||
const std::uint32_t unixtime = (dataDh & 0x40) ? haltTime : timeCB();
|
||||
const std::uint32_t old_hours = ((unixtime - baseTime) / 3600) % 24;
|
||||
baseTime += old_hours * 3600;
|
||||
baseTime -= new_hours * 3600;
|
||||
void Rtc::setH(unsigned const newHours) {
|
||||
const std::uint32_t unixtime = (dataDh_ & 0x40) ? haltTime_ : timeCB();
|
||||
const std::uint32_t oldHours = ((unixtime - baseTime_) / 3600) % 24;
|
||||
baseTime_ += oldHours * 3600;
|
||||
baseTime_ -= newHours * 3600;
|
||||
}
|
||||
|
||||
void Rtc::setM(const unsigned new_minutes) {
|
||||
const std::uint32_t unixtime = (dataDh & 0x40) ? haltTime : timeCB();
|
||||
const std::uint32_t old_minutes = ((unixtime - baseTime) / 60) % 60;
|
||||
baseTime += old_minutes * 60;
|
||||
baseTime -= new_minutes * 60;
|
||||
void Rtc::setM(unsigned const newMinutes) {
|
||||
const std::uint32_t unixtime = (dataDh_ & 0x40) ? haltTime_ : timeCB();
|
||||
const std::uint32_t oldMinutes = ((unixtime - baseTime_) / 60) % 60;
|
||||
baseTime_ += oldMinutes * 60;
|
||||
baseTime_ -= newMinutes * 60;
|
||||
}
|
||||
|
||||
void Rtc::setS(const unsigned new_seconds) {
|
||||
const std::uint32_t unixtime = (dataDh & 0x40) ? haltTime : timeCB();
|
||||
baseTime += (unixtime - baseTime) % 60;
|
||||
baseTime -= new_seconds;
|
||||
void Rtc::setS(unsigned const newSeconds) {
|
||||
const std::uint32_t unixtime = (dataDh_ & 0x40) ? haltTime_ : timeCB();
|
||||
baseTime_ += (unixtime - baseTime_) % 60;
|
||||
baseTime_ -= newSeconds;
|
||||
}
|
||||
|
||||
SYNCFUNC(Rtc)
|
||||
{
|
||||
EBS(activeData, 0);
|
||||
EVS(activeData, &dataS, 1);
|
||||
EVS(activeData, &dataM, 2);
|
||||
EVS(activeData, &dataH, 3);
|
||||
EVS(activeData, &dataDl, 4);
|
||||
EVS(activeData, &dataDh, 5);
|
||||
EES(activeData, NULL);
|
||||
EBS(activeData_, 0);
|
||||
EVS(activeData_, &dataS_, 1);
|
||||
EVS(activeData_, &dataM_, 2);
|
||||
EVS(activeData_, &dataH_, 3);
|
||||
EVS(activeData_, &dataDl_, 4);
|
||||
EVS(activeData_, &dataDh_, 5);
|
||||
EES(activeData_, NULL);
|
||||
|
||||
EBS(activeSet, 0);
|
||||
EVS(activeSet, &Rtc::setS, 1);
|
||||
EVS(activeSet, &Rtc::setM, 2);
|
||||
EVS(activeSet, &Rtc::setH, 3);
|
||||
EVS(activeSet, &Rtc::setDl, 4);
|
||||
EVS(activeSet, &Rtc::setDh, 5);
|
||||
EES(activeSet, NULL);
|
||||
EBS(activeSet_, 0);
|
||||
EVS(activeSet_, &Rtc::setS, 1);
|
||||
EVS(activeSet_, &Rtc::setM, 2);
|
||||
EVS(activeSet_, &Rtc::setH, 3);
|
||||
EVS(activeSet_, &Rtc::setDl, 4);
|
||||
EVS(activeSet_, &Rtc::setDh, 5);
|
||||
EES(activeSet_, NULL);
|
||||
|
||||
NSS(baseTime);
|
||||
NSS(haltTime);
|
||||
NSS(index);
|
||||
NSS(dataDh);
|
||||
NSS(dataDl);
|
||||
NSS(dataH);
|
||||
NSS(dataM);
|
||||
NSS(dataS);
|
||||
NSS(enabled);
|
||||
NSS(lastLatchData);
|
||||
NSS(baseTime_);
|
||||
NSS(haltTime_);
|
||||
NSS(index_);
|
||||
NSS(dataDh_);
|
||||
NSS(dataDl_);
|
||||
NSS(dataH_);
|
||||
NSS(dataM_);
|
||||
NSS(dataS_);
|
||||
NSS(enabled_);
|
||||
NSS(lastLatchData_);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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 RTC_H
|
||||
#define RTC_H
|
||||
|
||||
|
@ -27,69 +27,67 @@ namespace gambatte {
|
|||
struct SaveState;
|
||||
|
||||
class Rtc {
|
||||
private:
|
||||
unsigned char *activeData;
|
||||
void (Rtc::*activeSet)(unsigned);
|
||||
std::uint32_t baseTime;
|
||||
std::uint32_t haltTime;
|
||||
unsigned char index;
|
||||
unsigned char dataDh;
|
||||
unsigned char dataDl;
|
||||
unsigned char dataH;
|
||||
unsigned char dataM;
|
||||
unsigned char dataS;
|
||||
bool enabled;
|
||||
bool lastLatchData;
|
||||
std::uint32_t (*timeCB)();
|
||||
|
||||
void doLatch();
|
||||
void doSwapActive();
|
||||
void setDh(unsigned new_dh);
|
||||
void setDl(unsigned new_lowdays);
|
||||
void setH(unsigned new_hours);
|
||||
void setM(unsigned new_minutes);
|
||||
void setS(unsigned new_seconds);
|
||||
|
||||
public:
|
||||
Rtc();
|
||||
|
||||
const unsigned char* getActive() const { return activeData; }
|
||||
std::uint32_t getBaseTime() const { return baseTime; }
|
||||
unsigned char const * activeData() const { return activeData_; }
|
||||
std::uint32_t getBaseTime() const { return baseTime_; }
|
||||
|
||||
void setBaseTime(const std::uint32_t baseTime) {
|
||||
this->baseTime = baseTime;
|
||||
// doLatch();
|
||||
this->baseTime_ = baseTime;
|
||||
}
|
||||
|
||||
void latch(const unsigned data) {
|
||||
if (!lastLatchData && data == 1)
|
||||
void latch(unsigned data) {
|
||||
if (!lastLatchData_ && data == 1)
|
||||
doLatch();
|
||||
|
||||
lastLatchData = data;
|
||||
lastLatchData_ = data;
|
||||
}
|
||||
|
||||
void loadState(const SaveState &state);
|
||||
void loadState(SaveState const &state);
|
||||
|
||||
void set(const bool enabled, unsigned bank) {
|
||||
void set(bool enabled, unsigned bank) {
|
||||
bank &= 0xF;
|
||||
bank -= 8;
|
||||
|
||||
this->enabled = enabled;
|
||||
this->index = bank;
|
||||
|
||||
enabled_ = enabled;
|
||||
index_ = bank;
|
||||
doSwapActive();
|
||||
}
|
||||
|
||||
void write(const unsigned data) {
|
||||
// if (activeSet)
|
||||
(this->*activeSet)(data);
|
||||
*activeData = data;
|
||||
void write(unsigned data) {
|
||||
(this->*activeSet_)(data);
|
||||
*activeData_ = data;
|
||||
}
|
||||
|
||||
void setRTCCallback(std::uint32_t (*callback)()) {
|
||||
timeCB = callback;
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned char *activeData_;
|
||||
void (Rtc::*activeSet_)(unsigned);
|
||||
std::uint32_t baseTime_;
|
||||
std::uint32_t haltTime_;
|
||||
unsigned char index_;
|
||||
unsigned char dataDh_;
|
||||
unsigned char dataDl_;
|
||||
unsigned char dataH_;
|
||||
unsigned char dataM_;
|
||||
unsigned char dataS_;
|
||||
bool enabled_;
|
||||
bool lastLatchData_;
|
||||
std::uint32_t (*timeCB)();
|
||||
|
||||
void doLatch();
|
||||
void doSwapActive();
|
||||
void setDh(unsigned newDh);
|
||||
void setDl(unsigned newLowdays);
|
||||
void setH(unsigned newHours);
|
||||
void setM(unsigned newMinutes);
|
||||
void setS(unsigned newSeconds);
|
||||
|
||||
public:
|
||||
template<bool isReader>void SyncState(NewState *ns);
|
||||
};
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ void Memory::loadState(const SaveState &state) {
|
|||
: 8;
|
||||
|
||||
cart.setVrambank(ioamhram[0x14F] & isCgb());
|
||||
cart.setOamDmaSrc(OAM_DMA_SRC_OFF);
|
||||
cart.setOamDmaSrc(oam_dma_src_off);
|
||||
cart.setWrambank(isCgb() && (ioamhram[0x170] & 0x07) ? ioamhram[0x170] & 0x07 : 1);
|
||||
|
||||
if (lastOamDmaUpdate != disabled_time) {
|
||||
|
@ -432,11 +432,11 @@ void Memory::updateOamDma(const unsigned long cycleCounter) {
|
|||
|
||||
void Memory::oamDmaInitSetup() {
|
||||
if (ioamhram[0x146] < 0xA0) {
|
||||
cart.setOamDmaSrc(ioamhram[0x146] < 0x80 ? OAM_DMA_SRC_ROM : OAM_DMA_SRC_VRAM);
|
||||
cart.setOamDmaSrc(ioamhram[0x146] < 0x80 ? oam_dma_src_rom : oam_dma_src_vram);
|
||||
} else if (ioamhram[0x146] < 0xFE - isCgb() * 0x1E) {
|
||||
cart.setOamDmaSrc(ioamhram[0x146] < 0xC0 ? OAM_DMA_SRC_SRAM : OAM_DMA_SRC_WRAM);
|
||||
cart.setOamDmaSrc(ioamhram[0x146] < 0xC0 ? oam_dma_src_sram : oam_dma_src_wram);
|
||||
} else
|
||||
cart.setOamDmaSrc(OAM_DMA_SRC_INVALID);
|
||||
cart.setOamDmaSrc(oam_dma_src_invalid);
|
||||
}
|
||||
|
||||
static const unsigned char * oamDmaSrcZero() {
|
||||
|
@ -446,12 +446,12 @@ static const unsigned char * oamDmaSrcZero() {
|
|||
|
||||
const unsigned char * Memory::oamDmaSrcPtr() const {
|
||||
switch (cart.oamDmaSrc()) {
|
||||
case OAM_DMA_SRC_ROM: return cart.romdata(ioamhram[0x146] >> 6) + (ioamhram[0x146] << 8);
|
||||
case OAM_DMA_SRC_SRAM: return cart.rsrambankptr() ? cart.rsrambankptr() + (ioamhram[0x146] << 8) : 0;
|
||||
case OAM_DMA_SRC_VRAM: return cart.vrambankptr() + (ioamhram[0x146] << 8);
|
||||
case OAM_DMA_SRC_WRAM: return cart.wramdata(ioamhram[0x146] >> 4 & 1) + (ioamhram[0x146] << 8 & 0xFFF);
|
||||
case OAM_DMA_SRC_INVALID:
|
||||
case OAM_DMA_SRC_OFF: break;
|
||||
case oam_dma_src_rom: return cart.romdata(ioamhram[0x146] >> 6) + (ioamhram[0x146] << 8);
|
||||
case oam_dma_src_sram: return cart.rsrambankptr() ? cart.rsrambankptr() + (ioamhram[0x146] << 8) : 0;
|
||||
case oam_dma_src_vram: return cart.vrambankptr() + (ioamhram[0x146] << 8);
|
||||
case oam_dma_src_wram: return cart.wramdata(ioamhram[0x146] >> 4 & 1) + (ioamhram[0x146] << 8 & 0xFFF);
|
||||
case oam_dma_src_invalid:
|
||||
case oam_dma_src_off: break;
|
||||
}
|
||||
|
||||
return ioamhram[0x146] == 0xFF && !isCgb() ? oamDmaSrcZero() : cart.rdisabledRam();
|
||||
|
@ -463,7 +463,7 @@ void Memory::startOamDma(const unsigned long cycleCounter) {
|
|||
|
||||
void Memory::endOamDma(const unsigned long cycleCounter) {
|
||||
oamDmaPos = 0xFE;
|
||||
cart.setOamDmaSrc(OAM_DMA_SRC_OFF);
|
||||
cart.setOamDmaSrc(oam_dma_src_off);
|
||||
display.oamChange(ioamhram, cycleCounter);
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
Loading…
Reference in New Issue