shithub: riscv

Download patch

ref: 46168ec503ec75926366a8f4ab505fd44ef271b7
parent: 4b0467ce442ad6a4eef0caf44391f7b924186a1b
author: aiju <devnull@localhost>
date: Fri Mar 21 06:53:33 EDT 2014

games/snes: added state saving

--- a/sys/src/games/snes/dat.h
+++ b/sys/src/games/snes/dat.h
@@ -1,10 +1,9 @@
 typedef signed char s8int;
 typedef signed short s16int;
 
-extern u16int pc;
-extern u32int rPB, curpc;
-extern u8int dma, nmi, irq;
-extern u32int hdma;
+extern u8int rP, dma, nmi, irq, emu, wai;
+extern u16int rA, rX, rY, rS, rD, pc;
+extern u32int rPB, rDB, curpc, hdma;
 extern int trace;
 extern int memcyc;
 
@@ -11,8 +10,8 @@
 extern uchar *prg, *sram;
 extern int nprg, nsram, hirom;
 extern u32int keys, keylatch, lastkeys;
-extern u8int reg[32768], spcmem[65536], vram[65536], oam[544];
-extern u16int cgram[256];
+extern u8int reg[32768], mem[131072], spcmem[65536], vram[65536], oam[544];
+extern u16int cgram[256], vramlatch;
 
 extern int ppux, ppuy, rx;
 extern u16int vtime, htime, subcolor, oamaddr;
@@ -19,8 +18,13 @@
 extern u16int hofs[5], vofs[5];
 extern s16int m7[6];
 
-extern u8int spcmem[65536];
+extern u8int spcmem[65536], spctimer[4], dsp[256];
+extern u8int sA, sX, sY, sP, sS;
+extern u16int spc;
+extern u8int dspstate;
+extern u16int dspcounter, noise;
 
+extern int ppuclock, spcclock, dspclock, stimerclock;
 extern int battery, saveclock, scale, mouse;
 
 enum {
--- a/sys/src/games/snes/dsp.c
+++ b/sys/src/games/snes/dsp.c
@@ -4,8 +4,8 @@
 #include "dat.h"
 #include "fns.h"
 
-static u8int dsp[256], dspstate;
-static u16int counter, noise;
+u8int dsp[256], dspstate;
+u16int dspcounter, noise;
 static s16int samp[2], echoin[2];
 
 enum {
@@ -134,9 +134,9 @@
 	if(r >= 30){
 		if(r == 31)
 			return 1;
-		return (counter & 1) == 0;
+		return (dspcounter & 1) == 0;
 	}
-	c = counter;
+	c = dspcounter;
 	switch(r % 3){
 	case 0: c += 536; break;
 	case 2: c += 1040; break;
@@ -515,8 +515,8 @@
 			dsp[INT|KOFF] = dsp[KOFF];
 			dsp[INT|KON] = dsp[NEWKON];
 		}
-		if(counter-- == 0)
-			counter = 0x77ff;
+		if(dspcounter-- == 0)
+			dspcounter = 0x77ff;
 		break;
 	case 31: voice(0, 4); voice(2, 1); break;
 	}
--- a/sys/src/games/snes/fns.h
+++ b/sys/src/games/snes/fns.h
@@ -17,3 +17,6 @@
 void	dspreset(void);
 void	audioinit(void);
 int	audioout(void);
+void	flushram(void);
+void	loadstate(char *);
+void	savestate(char *);
--- a/sys/src/games/snes/mkfile
+++ b/sys/src/games/snes/mkfile
@@ -9,6 +9,7 @@
 	ppu.$O\
 	spc.$O\
 	dsp.$O\
+	state.$O\
 
 HFILES=dat.h fns.h
 
--- a/sys/src/games/snes/ppu.c
+++ b/sys/src/games/snes/ppu.c
@@ -7,7 +7,7 @@
 int ppux, ppuy, rx;
 static u8int mode, bright, pixelpri[2];
 static u32int pixelcol[2];
-u16int vtime = 0x1ff, htime = 0x1ff, subcolor, mosatop;
+u16int vtime = 0x1ff, htime = 0x1ff, subcolor;
 uchar pic[256*239*2*9];
 u16int hofs[5], vofs[5];
 s16int m7[6];
--- a/sys/src/games/snes/snes.c
+++ b/sys/src/games/snes/snes.c
@@ -15,7 +15,7 @@
 Mousectl *mc;
 QLock pauselock;
 u32int keys;
-int savefd, scale, profile, mouse;
+int savefd, scale, profile, mouse, loadreq, savereq;
 Rectangle picr;
 Image *tmp, *bg;
 
@@ -126,6 +126,10 @@
 		if(read(fd, buf, sizeof(buf) - 1) <= 0)
 			sysfatal("read /dev/kbd: %r");
 		if(buf[0] == 'c'){
+			if(utfrune(buf, KF|5))
+				savereq = 1;
+			if(utfrune(buf, KF|6))
+				loadreq = 1;
 			if(utfrune(buf, Kdel)){
 				close(fd);
 				threadexitsall(nil);
@@ -251,6 +255,14 @@
 	spcreset();
 	dspreset();
 	for(;;){
+		if(savereq){
+			savestate("snes.save");
+			savereq = 0;
+		}
+		if(loadreq){
+			loadstate("snes.save");
+			loadreq = 0;
+		}
 		if(paused){
 			qlock(&pauselock);
 			qunlock(&pauselock);
--- /dev/null
+++ b/sys/src/games/snes/state.c
@@ -1,0 +1,184 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <draw.h>
+#include <bio.h>
+#include "dat.h"
+#include "fns.h"
+
+static Biobuf *bp;
+
+void
+put8(u8int i)
+{
+	Bputc(bp, i);
+}
+
+void
+put16(u16int i)
+{
+	put8(i);
+	put8(i >> 8);
+}
+
+void
+put32(u32int i)
+{
+	put8(i);
+	put8(i >> 8);
+	put8(i >> 16);
+	put8(i >> 24);
+}
+
+void
+put16s(u16int *p, int n)
+{
+	while(n--)
+		put16(*p++);
+}
+
+int
+get8(void)
+{
+	return Bgetc(bp);
+}
+
+int
+get16(void)
+{
+	int i;
+	
+	i = get8();
+	i |= get8() << 8;
+	return i;
+}
+
+int
+get32(void)
+{
+	int i;
+	
+	i = get8();
+	i |= get8() << 8;
+	i |= get8() << 16;
+	i |= get8() << 24;
+	return i;
+}
+
+void
+get16s(u16int *p, int n)
+{
+	while(n--)
+		*p++ = get16();
+}
+
+void
+loadstate(char *file)
+{
+	bp = Bopen(file, OREAD);
+	if(bp == nil){
+		message("open: %r");
+		return;
+	}
+	Bread(bp, reg, sizeof(reg));
+	Bread(bp, mem, sizeof(mem));
+	Bread(bp, vram, sizeof(vram));
+	Bread(bp, oam, sizeof(oam));
+	Bread(bp, spcmem, sizeof(spcmem));
+	Bread(bp, dsp, sizeof(dsp));
+	get16s(cgram, nelem(cgram));
+	ppuclock = get32();
+	spcclock = get32();
+	dspclock = get32();
+	stimerclock = get32();
+	rA = get16();
+	rX = get16();
+	rY = get16();
+	rS = get16();
+	rP = get8();
+	rD = get16();
+	rDB = get8()<<16;
+	pc = get16();
+	rPB = get8()<<16;
+	emu = get8();
+	irq = get8();
+	nmi = get8();
+	dma = get8();
+	hdma = get32();
+	wai = get8();
+	oamaddr = get16();
+	vramlatch = get16();
+	keylatch = get32();
+	ppux = get16();
+	ppuy = get16();
+	htime = reg[0x4207] | reg[0x4208] << 8 & 0x100;
+	vtime = reg[0x4209] | reg[0x420a] << 8 & 0x100;
+	subcolor = get16();
+	get16s(hofs, nelem(hofs));
+	get16s(vofs, nelem(vofs));
+	get16s((u16int*) m7, nelem(m7));
+	sA = get8();
+	sX = get8();
+	sY = get8();
+	sS = get8();
+	sP = get8();
+	dspstate = get8();
+	dspcounter = get16();
+	noise = get16();
+	Bterm(bp);
+}
+
+void
+savestate(char *file)
+{
+	flushram();
+	bp = Bopen(file, OWRITE);
+	if(bp == nil){
+		message("open: %r");
+		return;
+	}
+	Bwrite(bp, reg, sizeof(reg));
+	Bwrite(bp, mem, sizeof(mem));
+	Bwrite(bp, vram, sizeof(vram));
+	Bwrite(bp, oam, sizeof(oam));
+	Bwrite(bp, spcmem, sizeof(spcmem));
+	Bwrite(bp, dsp, sizeof(dsp));
+	put16s(cgram, nelem(cgram));
+	put32(ppuclock);
+	put32(spcclock);
+	put32(dspclock);
+	put32(stimerclock);
+	put16(rA);
+	put16(rX);
+	put16(rY);
+	put16(rS);
+	put8(rP);
+	put16(rD);
+	put8(rDB>>16);
+	put16(pc);
+	put8(rPB>>16);
+	put8(emu);
+	put8(irq);
+	put8(nmi);
+	put8(dma);
+	put32(hdma);
+	put8(wai);
+	put16(oamaddr);
+	put16(vramlatch);
+	put32(keylatch);
+	put16(ppux);
+	put16(ppuy);
+	put16(subcolor);
+	put16s(hofs, nelem(hofs));
+	put16s(vofs, nelem(vofs));
+	put16s((u16int*) m7, nelem(m7));
+	put8(sA);
+	put8(sX);
+	put8(sY);
+	put8(sS);
+	put8(sP);
+	put8(dspstate);
+	put16(dspcounter);
+	put16(noise);
+	Bterm(bp);
+}