X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=pico%2Farea.c;h=23e00daed36a2d4877407eed680f58aa2bd3b359;hb=679af8a3f466a2a4a20f58e4181a231fb73e9836;hp=876320d6367b69676197b467fa9844d1628f7b2e;hpb=1cfc5cc4ce06642b9bc45ca3b9d32793718e9455;p=picodrive.git diff --git a/pico/area.c b/pico/area.c index 876320d..23e00da 100644 --- a/pico/area.c +++ b/pico/area.c @@ -8,6 +8,7 @@ #include "pico_int.h" +#include // ym2612 #include "sound/ym2612.h" @@ -15,7 +16,6 @@ // sn76496 extern int *sn76496_regs; - struct PicoArea { void *data; int len; char *name; }; // strange observation on Symbian OS 9.1, m600 organizer fw r3a06: @@ -32,16 +32,18 @@ void (*PicoLoadStateHook)(void) = NULL; // Scan one variable and callback -static int ScanVar(void *data,int len,char *name,void *PmovFile,int PmovAction) +static int ScanVar(void *data,int len,char *name,void *PmovFile,int is_write) { int ret = 0; - if ((PmovAction&3)==1) ret = areaWrite(data,1,len,PmovFile); - if ((PmovAction&3)==2) ret = areaRead (data,1,len,PmovFile); + if (is_write) + ret = areaWrite(data,1,len,PmovFile); + else + ret = areaRead (data,1,len,PmovFile); return (ret != len); } -#define SCAN_VAR(x,y) ScanVar(&x,sizeof(x),y,PmovFile,PmovAction); -#define SCANP(x) ScanVar(&Pico.x,sizeof(Pico.x),#x,PmovFile,PmovAction); +#define SCAN_VAR(x,y) ScanVar(&x,sizeof(x),y,PmovFile,is_write); +#define SCANP(x) ScanVar(&Pico.x,sizeof(Pico.x),#x,PmovFile,is_write); // Pack the cpu into a common format: PICO_INTERNAL void PicoAreaPackCpu(unsigned char *cpu, int is_sub) @@ -86,8 +88,9 @@ PICO_INTERNAL void PicoAreaUnpackCpu(unsigned char *cpu, int is_sub) CycloneSetSr(context, *(unsigned int *)(cpu+0x44)); context->osp=*(unsigned int *)(cpu+0x48); memcpy(context->d,cpu,0x40); - context->membase=0; - context->pc = context->checkpc(*(unsigned int *)(cpu+0x40)); // Base pc + context->membase = 0; + context->pc = *(unsigned int *)(cpu+0x40); + CycloneUnpack(context, NULL); // rebase PC context->irq = cpu[0x4c]; context->state_flags = 0; if (cpu[0x4d]) @@ -115,7 +118,7 @@ PICO_INTERNAL void PicoAreaUnpackCpu(unsigned char *cpu, int is_sub) } // Scan the contents of the virtual machine's memory for saving or loading -static int PicoAreaScan(int PmovAction,unsigned int ver, void *PmovFile) +static int PicoAreaScan(int is_write, unsigned int ver, void *PmovFile) { void *ym2612_regs; unsigned char cpu[0x60]; @@ -124,59 +127,60 @@ static int PicoAreaScan(int PmovAction,unsigned int ver, void *PmovFile) memset(&cpu,0,sizeof(cpu)); memset(&cpu_z80,0,sizeof(cpu_z80)); + Pico.m.scanline=0; ym2612_regs = YM2612GetRegs(); - if (PmovAction&4) - { - Pico.m.scanline=0; - - // Scan all the memory areas: - SCANP(ram) SCANP(vram) SCANP(zram) SCANP(cram) SCANP(vsram) - - // Pack, scan and unpack the cpu data: - if((PmovAction&3)==1) PicoAreaPackCpu(cpu, 0); - //PicoMemInit(); - SCAN_VAR(cpu,"cpu") - if((PmovAction&3)==2) PicoAreaUnpackCpu(cpu, 0); - - SCAN_VAR(Pico.m ,"misc") - SCAN_VAR(Pico.video,"video") - - if (PicoOpt&7) { - if((PmovAction&3)==1) z80_pack(cpu_z80); - ret = SCAN_VAR(cpu_z80,"cpu_z80") - // do not unpack if we fail to load z80 state - if((PmovAction&3)==2) { - if(ret) z80_reset(); - else z80_unpack(cpu_z80); - } - } - if (PicoOpt&3) - ScanVar(sn76496_regs,28*4,"SN76496state", PmovFile, PmovAction); // regs and other stuff - if (PicoOpt&1) { - if((PmovAction&3)==1) ym2612_pack_state(); - ScanVar(ym2612_regs, 0x200+4, "YM2612state", PmovFile, PmovAction); // regs + addr line - if((PmovAction&3)==2) ym2612_unpack_state(); // reload YM2612 state from it's regs - } + // Scan all the memory areas: + SCANP(ram) SCANP(vram) SCANP(zram) SCANP(cram) SCANP(vsram) + + // Pack, scan and unpack the cpu data: + if (is_write) + PicoAreaPackCpu(cpu, 0); + SCAN_VAR(cpu,"cpu") + if (!is_write) + PicoAreaUnpackCpu(cpu, 0); + + SCAN_VAR(Pico.m ,"misc") + SCAN_VAR(Pico.video,"video") + + // no longer keeping eeprom data in sram_reg + if (!is_write && (Pico.m.sram_reg & 4)) + Pico.m.sram_reg = SRR_MAPPED; + + if (is_write) + z80_pack(cpu_z80); + ret = SCAN_VAR(cpu_z80,"cpu_z80") + // do not unpack if we fail to load z80 state + if (!is_write) { + if (ret) z80_reset(); + else z80_unpack(cpu_z80); } + ScanVar(sn76496_regs, 28*4, "SN76496state", PmovFile, is_write); + if (is_write) + ym2612_pack_state(); + ret = ScanVar(ym2612_regs, 0x200+4, "YM2612state", PmovFile, is_write); // regs + addr line + if (!is_write && !ret) + ym2612_unpack_state(); + return 0; } // --------------------------------------------------------------------------- // Helper code to save/load to a file handle +// XXX: error checking // Save or load the state from PmovFile: -int PmovState(int PmovAction, void *PmovFile) +static int PmovState(int is_write, void *PmovFile) { - int minimum=0; unsigned char head[32]; if ((PicoAHW & PAHW_MCD) || carthw_chunks != NULL) { - if (PmovAction&1) return PicoCdSaveState(PmovFile); - if (PmovAction&2) { + if (is_write) + return PicoCdSaveState(PmovFile); + else { int ret = PicoCdLoadState(PmovFile); if (PicoLoadStateHook) PicoLoadStateHook(); return ret; @@ -185,23 +189,112 @@ int PmovState(int PmovAction, void *PmovFile) memset(head,0,sizeof(head)); - // Find out minimal compatible version: - //PicoAreaScan(PmovAction&0xc,&minimum); - minimum = 0x0021; - + // not really used.. memcpy(head,"Pico",4); - *(unsigned int *)(head+0x8)=PicoVer; - *(unsigned int *)(head+0xc)=minimum; + *(unsigned int *)(head+0x8)=0x0133; + *(unsigned int *)(head+0xc)=0x0021; // Scan header: - if (PmovAction&1) areaWrite(head,1,sizeof(head),PmovFile); - if (PmovAction&2) areaRead (head,1,sizeof(head),PmovFile); + if (is_write) + areaWrite(head,1,sizeof(head),PmovFile); + else + areaRead (head,1,sizeof(head),PmovFile); // Scan memory areas: - PicoAreaScan(PmovAction, *(unsigned int *)(head+0x8), PmovFile); + PicoAreaScan(is_write, *(unsigned int *)(head+0x8), PmovFile); + + if (!is_write && PicoLoadStateHook) + PicoLoadStateHook(); + + return 0; +} - if ((PmovAction&2) && PicoLoadStateHook) PicoLoadStateHook(); +static size_t gzRead2(void *p, size_t _size, size_t _n, void *file) +{ + return gzread(file, p, _n); +} + +static size_t gzWrite2(void *p, size_t _size, size_t _n, void *file) +{ + return gzwrite(file, p, _n); +} +static void set_cbs(int gz) +{ + if (gz) { + areaRead = gzRead2; + areaWrite = gzWrite2; + areaEof = (areaeof *) gzeof; + areaSeek = (areaseek *) gzseek; + areaClose = (areaclose *) gzclose; + } else { + areaRead = (arearw *) fread; + areaWrite = (arearw *) fwrite; + areaEof = (areaeof *) feof; + areaSeek = (areaseek *) fseek; + areaClose = (areaclose *) fclose; + } +} + +int PicoState(const char *fname, int is_save) +{ + void *afile = NULL; + int ret; + + if (strcmp(fname + strlen(fname) - 3, ".gz") == 0) + { + if ( (afile = gzopen(fname, is_save ? "wb" : "rb")) ) { + set_cbs(1); + if (is_save) + gzsetparams(afile, 9, Z_DEFAULT_STRATEGY); + } + } + else + { + if ( (afile = fopen(fname, is_save ? "wb" : "rb")) ) { + set_cbs(0); + } + } + + if (afile == NULL) + return -1; + + ret = PmovState(is_save, afile); + areaClose(afile); + if (!is_save) + Pico.m.dirtyPal=1; + + return ret; +} + +int PicoStateLoadVDP(const char *fname) +{ + void *afile = NULL; + if (strcmp(fname + strlen(fname) - 3, ".gz") == 0) + { + if ( (afile = gzopen(fname, "rb")) ) + set_cbs(1); + } + else + { + if ( (afile = fopen(fname, "rb")) ) + set_cbs(0); + } + if (afile == NULL) + return -1; + + if ((PicoAHW & PAHW_MCD) || carthw_chunks != NULL) { + PicoCdLoadStateGfx(afile); + } else { + areaSeek(afile, 0x10020, SEEK_SET); // skip header and RAM in state file + areaRead(Pico.vram, 1, sizeof(Pico.vram), afile); + areaSeek(afile, 0x2000, SEEK_CUR); + areaRead(Pico.cram, 1, sizeof(Pico.cram), afile); + areaRead(Pico.vsram, 1, sizeof(Pico.vsram), afile); + areaSeek(afile, 0x221a0, SEEK_SET); + areaRead(&Pico.video, 1, sizeof(Pico.video), afile); + } + areaClose(afile); return 0; }