Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HuC3 mapper support #118

Merged
merged 1 commit into from
Nov 28, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Makefile.common
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ SOURCES_CXX := $(CORE_DIR)/bootloader.cpp \
$(CORE_DIR)/video_libretro.cpp \
$(CORE_DIR)/mem/cartridge.cpp \
$(CORE_DIR)/mem/cartridge_libretro.cpp \
$(CORE_DIR)/mem/huc3.cpp \
$(CORE_DIR)/mem/memptrs.cpp \
$(CORE_DIR)/mem/rtc.cpp \
$(CORE_DIR)/sound/channel1.cpp \
Expand Down
10 changes: 9 additions & 1 deletion libgambatte/src/gambatte-memory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -471,7 +471,10 @@ void Memory::updateOamDma(unsigned long const cc) {
if (oamDmaPos_ == 0)
startOamDma(lastOamDmaUpdate_ - 1);

ioamhram_[oamDmaPos_] = oamDmaSrc ? oamDmaSrc[oamDmaPos_] : cart_.rtcRead();
if (oamDmaSrc) ioamhram_[oamDmaPos_] = oamDmaSrc[oamDmaPos_];
else if (cart_.isHuC3()) ioamhram_[oamDmaPos_] = cart_.HuC3Read(oamDmaPos_, cc);
else ioamhram_[oamDmaPos_] = cart_.rtcRead();

} else if (oamDmaPos_ == 0xA0) {
endOamDma(lastOamDmaUpdate_ - 1);
lastOamDmaUpdate_ = disabled_time;
Expand Down Expand Up @@ -639,6 +642,9 @@ unsigned Memory::nontrivial_read(unsigned const p, unsigned long const cc) {
if (cart_.rsrambankptr())
return cart_.rsrambankptr()[p];

if (cart_.isHuC3())
return cart_.HuC3Read(p, cc);

return cart_.rtcRead();
}

Expand Down Expand Up @@ -1134,6 +1140,8 @@ void Memory::nontrivial_write(unsigned const p, unsigned const data, unsigned lo
} else if (p < 0xC000) {
if (cart_.wsrambankptr())
cart_.wsrambankptr()[p] = data;
else if (cart_.isHuC3())
cart_.HuC3Write(p, data);
else
cart_.rtcWrite(data);
} else
Expand Down
11 changes: 11 additions & 0 deletions libgambatte/src/initstate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1334,4 +1334,15 @@ void gambatte::setInitState(SaveState &state, bool const cgb, bool const gbaCgbM
state.rtc.dataM = 0;
state.rtc.dataS = 0;
state.rtc.lastLatchData = false;

state.huc3.baseTime = std::time(0);
state.huc3.haltTime = state.huc3.baseTime;
state.huc3.dataTime = 0;
state.huc3.writingTime = 0;
state.huc3.irBaseCycle = 0;
state.huc3.halted = false;
state.huc3.shift = 0;
state.huc3.ramValue = 1;
state.huc3.modeflag = 2; // huc3_none
state.huc3.irReceivingPulse = false;
}
80 changes: 78 additions & 2 deletions libgambatte/src/mem/cartridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,74 @@ namespace gambatte
setRombank();
}
};
class HuC3 : public DefaultMbc {
MemPtrs &memptrs_;
HuC3Chip *const huc3_;
unsigned char rombank_;
unsigned char rambank_;
unsigned char ramflag_;
void setRambank() const {
huc3_->setRamflag(ramflag_);
unsigned flags;
if(ramflag_ >= 0x0B && ramflag_ < 0x0F) {
// System registers mode
flags = MemPtrs::READ_EN | MemPtrs::WRITE_EN | MemPtrs::RTC_EN;
}
else if(ramflag_ == 0x0A || ramflag_ > 0x0D) {
// Read/write mode
flags = MemPtrs::READ_EN | MemPtrs::WRITE_EN;
}
else {
// Read-only mode ??
flags = MemPtrs::READ_EN;
}
memptrs_.setRambank(flags, rambank_ & (rambanks(memptrs_) - 1));
}
void setRombank() const { memptrs_.setRombank(std::max(rombank_ & (rombanks(memptrs_) - 1), 1u)); }
public:
explicit HuC3(MemPtrs &memptrs, HuC3Chip *const huc3)
: memptrs_(memptrs),
huc3_(huc3),
rombank_(1),
rambank_(0),
ramflag_(0)
{
}
virtual void romWrite(unsigned const p, unsigned const data) {
switch (p >> 13 & 3) {
case 0:
ramflag_ = data;
//printf("[HuC3] set ramflag to %02X\n", data);
setRambank();
break;
case 1:
//printf("[HuC3] set rombank to %02X\n", data);
rombank_ = data;
setRombank();
break;
case 2:
//printf("[HuC3] set rambank to %02X\n", data);
rambank_ = data;
setRambank();
break;
case 3:
// GEST: "programs will write 1 here"
break;
}
}
virtual void saveState(SaveState::Mem &ss) const {
ss.rombank = rombank_;
ss.rambank = rambank_;
ss.HuC3RAMflag = ramflag_;
}
virtual void loadState(SaveState::Mem const &ss) {
rombank_ = ss.rombank;
rambank_ = ss.rambank;
ramflag_ = ss.HuC3RAMflag;
setRambank();
setRombank();
}
};
class Mbc5 : public DefaultMbc {
MemPtrs &memptrs;
unsigned short rombank;
Expand Down Expand Up @@ -400,6 +468,7 @@ namespace gambatte
{
switch (headerByte0x147)
{
case 0xFE: // huc3
case 0x0F:
case 0x10:
return true;
Expand All @@ -419,10 +488,12 @@ namespace gambatte
{
mbc->saveState(state.mem);
rtc_.saveState(state);
huc3_.saveState(state);
}

void Cartridge::loadState(const SaveState &state)
{
huc3_.loadState(state);
rtc_.loadState(state);
mbc->loadState(state.mem);
}
Expand Down Expand Up @@ -455,7 +526,7 @@ namespace gambatte
unsigned rambanks = 1;
unsigned rombanks = 2;
bool cgb = false;
enum Cartridgetype { PLAIN, MBC1, MBC2, MBC3, MBC5, HUC1 } type = PLAIN;
enum Cartridgetype { PLAIN, MBC1, MBC2, MBC3, MBC5, HUC1, HUC3 } type = PLAIN;

{
unsigned i;
Expand Down Expand Up @@ -494,7 +565,7 @@ namespace gambatte
case 0x22: printf("MBC7 ROM not supported.\n"); return -1;
case 0xFC: printf("Pocket Camera ROM not supported.\n"); return -1;
case 0xFD: printf("Bandai TAMA5 ROM not supported.\n"); return -1;
case 0xFE: printf("HuC3 ROM+RAM+BATTERY loaded.\n"); return -1;
case 0xFE: printf("HuC3 ROM+RAM+BATTERY loaded.\n"); type = HUC3; break;
case 0xFF: printf("HuC1 ROM+BATTERY loaded.\n"); type = HUC1; break;
default: printf("Wrong data-format, corrupt or unsupported ROM.\n"); return -1;
}
Expand Down Expand Up @@ -541,6 +612,7 @@ namespace gambatte
mbc.reset();
memptrs_.reset(rombanks, rambanks, cgb ? 8 : 2);
rtc_.set(false, 0);
huc3_.set(false);

memcpy(memptrs_.romdata(), romdata, ((romsize / 0x4000) * 0x4000ul) * sizeof(unsigned char));
std::memset(memptrs_.romdata() + (romsize / 0x4000) * 0x4000ul, 0xFF, (rombanks - romsize / 0x4000) * 0x4000ul);
Expand All @@ -560,6 +632,10 @@ namespace gambatte
case MBC3: mbc.reset(new Mbc3(memptrs_, hasRtc(memptrs_.romdata()[0x147]) ? &rtc_ : 0)); break;
case MBC5: mbc.reset(new Mbc5(memptrs_)); break;
case HUC1: mbc.reset(new HuC1(memptrs_)); break;
case HUC3:
huc3_.set(true);
mbc.reset(new HuC3(memptrs_, &huc3_));
break;
}

return 0;
Expand Down
6 changes: 6 additions & 0 deletions libgambatte/src/mem/cartridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

#include "memptrs.h"
#include "rtc.h"
#include "huc3.h"
#include "savestate.h"
#include <memory>
#include <string>
Expand Down Expand Up @@ -134,6 +135,10 @@ namespace gambatte
void setGameGenie(const std::string &codes);
void clearCheats();

bool isHuC3() const { return huc3_.isHuC3(); }
unsigned char HuC3Read(unsigned p, unsigned long const cc) { return huc3_.read(p, cc); }
void HuC3Write(unsigned p, unsigned data) { huc3_.write(p, data); }

void *savedata_ptr();
unsigned savedata_size();

Expand All @@ -152,6 +157,7 @@ namespace gambatte
};
MemPtrs memptrs_;
Rtc rtc_;
HuC3Chip huc3_;

std::auto_ptr<Mbc> mbc;

Expand Down
20 changes: 16 additions & 4 deletions libgambatte/src/mem/cartridge_libretro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ namespace gambatte
case 0x13:
case 0x1B:
case 0x1E:
case 0xFE:
case 0xFF:
return true;
default:
Expand All @@ -32,6 +33,7 @@ namespace gambatte
{
switch (headerByte0x147)
{
case 0xFE: // huc3
case 0x0F:
case 0x10:
return true;
Expand All @@ -57,15 +59,25 @@ namespace gambatte

void *Cartridge::rtcdata_ptr()
{
if (hasRtc(memptrs_.romdata()[0x147]))
return &rtc_.getBaseTime();
if (hasRtc(memptrs_.romdata()[0x147])) {
if (isHuC3()) {
return &huc3_.getBaseTime();
} else {
return &rtc_.getBaseTime();
}
}
return 0;
}

unsigned Cartridge::rtcdata_size()
{
if (hasRtc(memptrs_.romdata()[0x147]))
return sizeof(rtc_.getBaseTime());
if (hasRtc(memptrs_.romdata()[0x147])) {
if (isHuC3()) {
return sizeof(huc3_.getBaseTime());
} else {
return sizeof(rtc_.getBaseTime());
}
}
return 0;
}

Expand Down
Loading