all repos — mgba @ f4fa4231351c6beb34f01c5e31231bca5db7ab94

mGBA Game Boy Advance Emulator

src/gba/gba-savedata.c (view raw)

  1#include "gba-savedata.h"
  2
  3#include "gba.h"
  4
  5#include <fcntl.h>
  6#include <string.h>
  7#include <sys/mman.h>
  8#include <unistd.h>
  9
 10void GBASavedataInit(struct GBASavedata* savedata, const char* filename) {
 11	savedata->type = SAVEDATA_NONE;
 12	savedata->data = 0;
 13	savedata->fd = -1;
 14	savedata->filename = filename;
 15}
 16
 17void GBASavedataDeinit(struct GBASavedata* savedata) {
 18	switch (savedata->type) {
 19	case SAVEDATA_SRAM:
 20		munmap(savedata->data, SIZE_CART_SRAM);
 21		break;
 22	case SAVEDATA_FLASH512:
 23		munmap(savedata->data, SIZE_CART_FLASH512);
 24		break;
 25	case SAVEDATA_FLASH1M:
 26		munmap(savedata->data, SIZE_CART_FLASH1M);
 27		break;
 28	case SAVEDATA_EEPROM:
 29		munmap(savedata->data, SIZE_CART_EEPROM);
 30		break;
 31	default:
 32		break;
 33	}
 34	close(savedata->fd);
 35	savedata->type = SAVEDATA_NONE;
 36}
 37
 38void GBASavedataInitFlash(struct GBASavedata* savedata) {
 39	savedata->type = SAVEDATA_FLASH512;
 40	savedata->fd = open(savedata->filename, O_RDWR | O_CREAT, 0666);
 41	if (savedata->fd < 0) {
 42		GBALog(GBA_LOG_WARN, "Cannot open savedata file %s", savedata->filename);
 43		return;
 44	}
 45	// mmap enough so that we can expand the file if we need to
 46	savedata->data = mmap(0, SIZE_CART_FLASH1M, PROT_READ | PROT_WRITE, MAP_SHARED, savedata->fd, 0);
 47
 48	off_t end = lseek(savedata->fd, 0, SEEK_END);
 49	if (end < SIZE_CART_FLASH512) {
 50		ftruncate(savedata->fd, SIZE_CART_SRAM);
 51		memset(&savedata->data[end], 0xFF, SIZE_CART_SRAM - end);
 52	}
 53}
 54
 55void GBASavedataInitEEPROM(struct GBASavedata* savedata) {
 56	savedata->type = SAVEDATA_EEPROM;
 57	savedata->fd = open(savedata->filename, O_RDWR | O_CREAT, 0666);
 58	if (savedata->fd < 0) {
 59		GBALog(GBA_LOG_WARN, "Cannot open savedata file %s", savedata->filename);
 60		return;
 61	}
 62	savedata->data = mmap(0, SIZE_CART_EEPROM, PROT_READ | PROT_WRITE, MAP_SHARED, savedata->fd, 0);
 63
 64	off_t end = lseek(savedata->fd, 0, SEEK_END);
 65	if (end < SIZE_CART_EEPROM) {
 66		ftruncate(savedata->fd, SIZE_CART_EEPROM);
 67		memset(&savedata->data[end], 0xFF, SIZE_CART_EEPROM - end);
 68	}
 69}
 70
 71void GBASavedataInitSRAM(struct GBASavedata* savedata) {
 72	savedata->type = SAVEDATA_SRAM;
 73	savedata->fd = open(savedata->filename, O_RDWR | O_CREAT, 0666);
 74	off_t end;
 75	int flags = MAP_SHARED;
 76	if (savedata->fd < 0) {
 77		GBALog(GBA_LOG_WARN, "Cannot open savedata file %s", savedata->filename);
 78		end = 0;
 79		flags |= MAP_ANON;
 80	} else {
 81		end = lseek(savedata->fd, 0, SEEK_END);
 82		if (end < SIZE_CART_SRAM) {
 83			ftruncate(savedata->fd, SIZE_CART_SRAM);
 84		}
 85	}
 86	savedata->data = mmap(0, SIZE_CART_SRAM, PROT_READ | PROT_WRITE, flags, savedata->fd, 0);
 87	if (end < SIZE_CART_SRAM) {
 88		memset(&savedata->data[end], 0xFF, SIZE_CART_SRAM - end);
 89	}
 90}
 91
 92
 93void GBASavedataWriteFlash(struct GBASavedata* savedata, uint8_t value) {
 94	(void)(savedata);
 95	(void)(value);
 96	GBALog(GBA_LOG_STUB, "Flash memory unimplemented");
 97}
 98
 99void GBASavedataWriteEEPROM(struct GBASavedata* savedata, uint16_t value) {
100	(void)(savedata);
101	(void)(value);
102	GBALog(GBA_LOG_STUB, "EEPROM unimplemented");
103}
104
105uint16_t GBASavedataReadEEPROM(struct GBASavedata* savedata) {
106	(void)(savedata);
107	GBALog(GBA_LOG_STUB, "EEPROM unimplemented");
108	return 0;
109}