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}