diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a1110f1f..03a4bfe0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -10,6 +10,7 @@ add_library(core STATIC CP15.cpp CRC32.cpp DMA.cpp + GBACart.cpp GPU.cpp GPU2D.cpp GPU3D.cpp diff --git a/src/GBACart.cpp b/src/GBACart.cpp new file mode 100644 index 00000000..7c2faad0 --- /dev/null +++ b/src/GBACart.cpp @@ -0,0 +1,197 @@ +/* + Copyright 2019 Arisotura, Raphaël Zumer + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS 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 for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#include +#include +#include "GBACart.h" +#include "CRC32.h" +#include "Platform.h" + + +namespace GBACart_SRAM +{ + +u8* SRAM; +u32 SRAMLength; + +char SRAMPath[1024]; + + +bool Init() +{ + SRAM = NULL; + return true; +} + +void DeInit() +{ + if (SRAM) delete[] SRAM; +} + +void Reset() +{ + if (SRAM) delete[] SRAM; + SRAM = NULL; +} + +void DoSavestate(Savestate* file) +{ + // TODO? +} + +void LoadSave(const char* path) +{ + if (SRAM) delete[] SRAM; + + strncpy(SRAMPath, path, 1023); + SRAMPath[1023] = '\0'; + + FILE* f = Platform::OpenFile(path, "rb"); + if (f) + { + fseek(f, 0, SEEK_END); + SRAMLength = (u32)ftell(f); + SRAM = new u8[SRAMLength]; + + fseek(f, 0, SEEK_SET); + fread(SRAM, SRAMLength, 1, f); + + fclose(f); + } + else + { + int SRAMLength = 65536; // max GBA SRAM size + + SRAM = new u8[SRAMLength]; + memset(SRAM, 0xFF, SRAMLength); + } +} + +void RelocateSave(const char* path, bool write) +{ + if (!write) + { + LoadSave(path); // lazy + return; + } + + strncpy(SRAMPath, path, 1023); + SRAMPath[1023] = '\0'; + + FILE* f = Platform::OpenFile(path, "wb"); + if (!f) + { + printf("GBACart_SRAM::RelocateSave: failed to create new file. fuck\n"); + return; + } + + fwrite(SRAM, SRAMLength, 1, f); + fclose(f); +} + +} + + +namespace GBACart +{ + +bool CartInserted; +u8* CartROM; +u32 CartROMSize; +u32 CartCRC; +u32 CartID; + + +bool Init() +{ + if (!GBACart_SRAM::Init()) return false; + + CartROM = NULL; + + return true; +} + +void DeInit() +{ + if (CartROM) delete[] CartROM; + + GBACart_SRAM::DeInit(); +} + +void Reset() +{ + CartInserted = false; + if (CartROM) delete[] CartROM; + CartROM = NULL; + CartROMSize = 0; + + GBACart_SRAM::Reset(); +} + +void DoSavestate(Savestate* file) +{ + // TODO? +} + +bool LoadROM(const char* path, const char* sram) +{ + FILE* f = Platform::OpenFile(path, "rb"); + if (!f) + { + return false; + } + + fseek(f, 0, SEEK_END); + u32 len = (u32)ftell(f); + + CartROMSize = 0x200; + while (CartROMSize < len) + CartROMSize <<= 1; + + u32 gamecode; + fseek(f, 0xAC, SEEK_SET); + fread(&gamecode, 4, 1, f); + printf("Game code: %c%c%c%c\n", gamecode&0xFF, (gamecode>>8)&0xFF, (gamecode>>16)&0xFF, gamecode>>24); + + CartROM = new u8[CartROMSize]; + memset(CartROM, 0, CartROMSize); + fseek(f, 0, SEEK_SET); + fread(CartROM, 1, len, f); + + fclose(f); + //CartROM = f; + + CartCRC = CRC32(CartROM, CartROMSize); + printf("ROM CRC32: %08X\n", CartCRC); + + CartInserted = true; + + // save + printf("Save file: %s\n", sram); + GBACart_SRAM::LoadSave(sram); + + return true; +} + +void RelocateSave(const char* path, bool write) +{ + // derp herp + GBACart_SRAM::RelocateSave(path, write); +} + +} diff --git a/src/GBACart.h b/src/GBACart.h new file mode 100644 index 00000000..94da0b27 --- /dev/null +++ b/src/GBACart.h @@ -0,0 +1,52 @@ +/* + Copyright 2019 Arisotura, Raphaël Zumer + + This file is part of melonDS. + + melonDS is free software: you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation, either version 3 of the License, or (at your option) + any later version. + + melonDS 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 for more details. + + You should have received a copy of the GNU General Public License along + with melonDS. If not, see http://www.gnu.org/licenses/. +*/ + +#ifndef GBACART_H +#define GBACART_H + +#include "types.h" +#include "Savestate.h" + + +namespace GBACart_SRAM +{ + +extern u8* SRAM; +extern u32 SRAMLength; + +} + + +namespace GBACart +{ + +extern bool CartInserted; +extern u8* CartROM; +extern u32 CartROMSize; + +bool Init(); +void DeInit(); +void Reset(); + +void DoSavestate(Savestate* file); +bool LoadROM(const char* path, const char* sram); +void RelocateSave(const char* path, bool write); + +} + +#endif // GBACART_H diff --git a/src/NDS.cpp b/src/NDS.cpp index 0957ea35..a16eb1c0 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -22,6 +22,7 @@ #include "NDS.h" #include "ARM.h" #include "NDSCart.h" +#include "GBACart.h" #include "DMA.h" #include "FIFO.h" #include "GPU.h" @@ -1611,14 +1612,18 @@ u8 ARM9Read8(u32 addr) case 0x08000000: case 0x09000000: if (ExMemCnt[0] & (1<<7)) return 0x00; // deselected CPU is 00h-filled - //return *(u8*)&NDSCart::CartROM[addr & (NDSCart::CartROMSize-1)]; - //printf("GBA read8 %08X\n", addr); - // TODO!!! + if (GBACart::CartInserted) + { + return *(u8*)&GBACart::CartROM[addr & (GBACart::CartROMSize-1)]; + } return 0xFF; // TODO: proper open bus case 0x0A000000: if (ExMemCnt[0] & (1<<7)) return 0x00; // deselected CPU is 00h-filled - // TODO!!! + if (GBACart::CartInserted) + { + return *(u8*)&GBACart_SRAM::SRAM[addr & (GBACart_SRAM::SRAMLength-1)]; + } return 0xFF; // TODO: proper open bus } @@ -1672,14 +1677,18 @@ u16 ARM9Read16(u32 addr) case 0x08000000: case 0x09000000: if (ExMemCnt[0] & (1<<7)) return 0x0000; // deselected CPU is 00h-filled - //return *(u8*)&NDSCart::CartROM[addr & (NDSCart::CartROMSize-1)]; - //printf("GBA read8 %08X\n", addr); - // TODO!!! + if (GBACart::CartInserted) + { + return *(u16*)&GBACart::CartROM[addr & (GBACart::CartROMSize-1)]; + } return 0xFFFF; // TODO: proper open bus case 0x0A000000: if (ExMemCnt[0] & (1<<7)) return 0x0000; // deselected CPU is 00h-filled - // TODO!!! + if (GBACart::CartInserted) + { + return *(u16*)&GBACart_SRAM::SRAM[addr & (GBACart_SRAM::SRAMLength-1)]; + } return 0xFFFF; // TODO: proper open bus } @@ -1733,14 +1742,18 @@ u32 ARM9Read32(u32 addr) case 0x08000000: case 0x09000000: if (ExMemCnt[0] & (1<<7)) return 0x00000000; // deselected CPU is 00h-filled - //return *(u8*)&NDSCart::CartROM[addr & (NDSCart::CartROMSize-1)]; - //printf("GBA read8 %08X\n", addr); - // TODO!!! + if (GBACart::CartInserted) + { + return *(u32*)&GBACart::CartROM[addr & (GBACart::CartROMSize-1)]; + } return 0xFFFFFFFF; // TODO: proper open bus case 0x0A000000: if (ExMemCnt[0] & (1<<7)) return 0x00000000; // deselected CPU is 00h-filled - // TODO!!! + if (GBACart::CartInserted) + { + return *(u32*)&GBACart_SRAM::SRAM[addr & (GBACart_SRAM::SRAMLength-1)]; + } return 0xFFFFFFFF; // TODO: proper open bus } @@ -1936,14 +1949,18 @@ u8 ARM7Read8(u32 addr) case 0x08000000: case 0x09000000: if (!(ExMemCnt[0] & (1<<7))) return 0x00; // deselected CPU is 00h-filled - //return *(u8*)&NDSCart::CartROM[addr & (NDSCart::CartROMSize-1)]; - //printf("GBA read8 %08X\n", addr); - // TODO!!! + if (GBACart::CartInserted) + { + return *(u8*)&GBACart::CartROM[addr & (GBACart::CartROMSize-1)]; + } return 0xFF; // TODO: proper open bus case 0x0A000000: if (!(ExMemCnt[0] & (1<<7))) return 0x00; // deselected CPU is 00h-filled - // TODO!!! + if (GBACart::CartInserted) + { + return *(u8*)&GBACart_SRAM::SRAM[addr & (GBACart_SRAM::SRAMLength-1)]; + } return 0xFF; // TODO: proper open bus } @@ -1999,14 +2016,18 @@ u16 ARM7Read16(u32 addr) case 0x08000000: case 0x09000000: if (!(ExMemCnt[0] & (1<<7))) return 0x0000; // deselected CPU is 00h-filled - //return *(u8*)&NDSCart::CartROM[addr & (NDSCart::CartROMSize-1)]; - //printf("GBA read8 %08X\n", addr); - // TODO!!! + if (GBACart::CartInserted) + { + return *(u16*)&GBACart::CartROM[addr & (GBACart::CartROMSize-1)]; + } return 0xFFFF; // TODO: proper open bus case 0x0A000000: if (!(ExMemCnt[0] & (1<<7))) return 0x0000; // deselected CPU is 00h-filled - // TODO!!! + if (GBACart::CartInserted) + { + return *(u16*)&GBACart_SRAM::SRAM[addr & (GBACart_SRAM::SRAMLength-1)]; + } return 0xFFFF; // TODO: proper open bus } @@ -2062,14 +2083,18 @@ u32 ARM7Read32(u32 addr) case 0x08000000: case 0x09000000: if (!(ExMemCnt[0] & (1<<7))) return 0x00000000; // deselected CPU is 00h-filled - //return *(u8*)&NDSCart::CartROM[addr & (NDSCart::CartROMSize-1)]; - //printf("GBA read8 %08X\n", addr); - // TODO!!! + if (GBACart::CartInserted) + { + return *(u32*)&GBACart::CartROM[addr & (GBACart::CartROMSize-1)]; + } return 0xFFFFFFFF; // TODO: proper open bus case 0x0A000000: if (!(ExMemCnt[0] & (1<<7))) return 0x00000000; // deselected CPU is 00h-filled - // TODO!!! + if (GBACart::CartInserted) + { + return *(u32*)&GBACart_SRAM::SRAM[addr & (GBACart_SRAM::SRAMLength-1)]; + } return 0xFFFFFFFF; // TODO: proper open bus }