13 u32int sramctl, nsram, sram0, sram1;
16 int dmaclock, vdpclock, z80clock, audioclock, ymclock, saveclock;
22 pwrite(savefd, sram, nsram, 0);
31 strncpy(buf, file, sizeof buf - 5);
33 savefd = create(buf, ORDWR | OEXCL, 0666);
35 savefd = open(buf, ORDWR);
39 readn(savefd, sram, nsram);
45 static uchar hdr[512], buf[4096];
50 fd = open(file, OREAD);
53 if(readn(fd, hdr, 512) < 512)
55 if(memcmp(hdr + 0x100, "SEGA MEGA DRIVE ", 16) != 0 && memcmp(hdr + 0x100, "SEGA GENESIS ", 16) != 0)
56 sysfatal("invalid rom");
57 v = hdr[0x1a0] << 24 | hdr[0x1a1] << 16 | hdr[0x1a2] << 8 | hdr[0x1a3];
59 sysfatal("rom starts at nonzero address");
60 v = hdr[0x1a4] << 24 | hdr[0x1a5] << 16 | hdr[0x1a6] << 8 | hdr[0x1a7];
63 sysfatal("invalid rom");
66 sysfatal("malloc: %r");
69 rc = readn(fd, buf, sizeof buf);
76 for(i = 0; i < rc; i += 2)
77 *p++ = buf[i] << 8 | buf[i+1];
81 if(hdr[0x1b0] == 0x52 && hdr[0x1b1] == 0x41){
82 sramctl = SRAM | hdr[0x1b2] >> 1 & ADDRMASK;
83 if((hdr[0x1b2] & 0x40) != 0)
85 sram0 = hdr[0x1b4] << 24 | hdr[0x1b5] << 16 | hdr[0x1b6] << 8 | hdr[0x1b7] & 0xfe;
86 sram1 = hdr[0x1b8] << 24 | hdr[0x1b9] << 16 | hdr[0x1ba] << 8 | hdr[0x1bb] | 1;
88 print("SRAM of size <= 0?\n");
91 nsram = sram1 - sram0;
92 if((sramctl & ADDRMASK) != ADDRBOTH)
96 sysfatal("malloc: %r");
97 if((sramctl & BATTERY) != 0){
108 fprint(2, "usage: %s [-a] [-x scale] rom\n", argv0);
113 threadmain(int argc, char **argv)
122 fixscale = strtol(EARGF(usage()), nil, 0);
130 initemu(320, 224, 4, XRGB32, 1, nil);
131 regkey("a", 'c', 1<<5);
132 regkey("b", 'x', 1<<4);
133 regkey("y", 'z', 1<<12);
134 regkey("start", '\n', 1<<13);
135 regkey("up", Kup, 0x101);
136 regkey("down", Kdown, 0x202);
137 regkey("left", Kleft, 1<<2);
138 regkey("right", Kright, 1<<3);
165 z80clock += z80step() * Z80DIV;
166 while(audioclock >= SAMPDIV){
168 audioclock -= SAMPDIV;
170 while(ymclock >= YMDIV){
189 flushaudio(audioout);