13 int savefd, saveframes;
16 char *biosfile = "/sys/games/lib/gbabios.bin";
29 pwrite(savefd, back, nback, BACKTYPELEN);
36 extern uchar bios[16384];
40 fd = open(biosfile, OREAD);
43 readn(fd, bios, 16384);
51 union {char a[4]; u32int u;} s1 = {"EEPR"}, s2 = {"SRAM"}, s3 = {"FLAS"};
57 if(v == s1.u && memcmp(p - 1, "EEPROM_V", 8) == 0){
58 print("backup type is either eeprom4 or eeprom64 -- can't detect which one\n");
61 if(v == s2.u && memcmp(p - 1, "SRAM_V", 6) == 0){
66 if(memcmp(p - 1, "FLASH_V", 7) == 0 || memcmp(p - 1, "FLASH512_V", 10) == 0){
70 if(memcmp(p - 1, "FLASH1M_V", 9) == 0){
80 parsetype(char *s, int *size)
82 if(strcmp(s, "eeprom4") == 0){
85 }else if(strcmp(s, "eeprom64") == 0){
88 }else if(strcmp(s, "sram256") == 0){
91 }else if(strcmp(s, "flash512") == 0){
94 }else if(strcmp(s, "flash1024") == 0){
102 typename(char *s, int type, int size)
116 sysfatal("typestr: unknown type %d -- shouldn't happen", type);
119 snprint(s, BACKTYPELEN, "%s%d", st, size/128);
126 char tstr[BACKTYPELEN];
129 buf = emalloc(strlen(file) + 4);
131 p = strrchr(buf, '.');
133 p = buf + strlen(buf);
135 savefd = open(buf, ORDWR);
137 if(backup == NOBACK){
138 backup = romtype(&nback);
139 if(backup == NOBACK){
140 fprint(2, "failed to autodetect save format\n");
145 savefd = create(buf, OWRITE, 0664);
147 fprint(2, "create: %r");
151 memset(tstr, 0, sizeof(tstr));
152 typename(tstr, backup, nback);
153 write(savefd, tstr, sizeof(tstr));
154 back = emalloc(nback);
155 memset(back, 0, nback);
156 write(savefd, back, nback);
161 readn(savefd, tstr, sizeof(tstr));
163 type = parsetype(tstr, &size);
164 if(type == NOBACK || backup != NOBACK && (type != backup || nback != size))
165 sysfatal("%s: invalid format", buf);
168 back = emalloc(nback);
169 readn(savefd, back, nback);
180 fd = open(file, OREAD);
182 sysfatal("open: %r");
184 if(sz <= 0 || sz > 32*1024*1024)
185 sysfatal("invalid file size");
189 if(readn(fd, rom, sz) < sz)
190 sysfatal("read: %r");
193 if(nrom == 32*KB*KB && backup == EEPROM)
204 flushaudio(audioout);
206 if(saveframes > 0 && --saveframes == 0)
209 if((reg[KEYCNT] & 1<<14) != 0){
210 x = reg[KEYCNT] & keys;
211 if((reg[KEYCNT] & 1<<15) != 0){
212 if(x == (reg[KEYCNT] & 0x3ff))
223 fprint(2, "usage: %s [-a] [-s savetype] [-b biosfile] [-x scale] rom\n", argv0);
228 threadmain(int argc, char **argv)
239 backup = parsetype(s, &nback);
241 sysfatal("unknown save type '%s'", s);
244 biosfile = strdup(EARGF(usage()));
247 fixscale = strtol(EARGF(usage()), nil, 0);
257 initemu(240, 160, 2, CHAN4(CIgnore, 1, CBlue, 5, CGreen, 5, CRed, 5), 1, nil);
258 regkey("b", 'z', 1<<1);
259 regkey("a", 'x', 1<<0);
260 regkey("l1", 'a', 1<<9);
261 regkey("r1", 's', 1<<8);
262 regkey("control", Kshift, 1<<2);
263 regkey("start", '\n', 1<<3);
264 regkey("up", Kup, 1<<6);
265 regkey("down", Kdown, 1<<7);
266 regkey("left", Kleft, 1<<5);
267 regkey("right", Kright, 1<<4);
273 savestate("gba.save");
277 loadstate("gba.save");
291 if((elist->time -= t) <= 0)