desync fixes

This commit is contained in:
zeromus 2009-07-27 10:14:43 +00:00
parent 624c72fd49
commit 5b98c330e1
13 changed files with 34783 additions and 95 deletions

View File

@ -1,3 +1,14 @@
0.9.4+
- [2468] port r2466 from trunk (permit osd on bottom screen, fix stylus input display)
- [2645] port some of small fixes from trunk:
disable autohold while playing a movie (r2624)
fix movie length (r2629)
keyrepeat improvement (r2641-2643)
- [2665]
fix nitsuja's desynch bugreports (SF 2827543)
fix desynch caused by spu_core forgetting to save a variable
0.9.2 -> 0.9.4 (r1844->r2352->r2437) 0.9.2 -> 0.9.4 (r1844->r2352->r2437)
0.9.3 was skipped due to emu news sites sneaking it out of our staging area and 0.9.3 was skipped due to emu news sites sneaking it out of our staging area and

View File

@ -3199,8 +3199,9 @@ bool gpu_loadstate(std::istream* is, int size)
read32le(&SubScreen.gpu->affineInfo[0].y,is); read32le(&SubScreen.gpu->affineInfo[0].y,is);
read32le(&SubScreen.gpu->affineInfo[1].x,is); read32le(&SubScreen.gpu->affineInfo[1].x,is);
read32le(&SubScreen.gpu->affineInfo[1].y,is); read32le(&SubScreen.gpu->affineInfo[1].y,is);
MainScreen.gpu->refreshAffineStartRegs(-1,-1); //removed per nitsuja feedback. anyway, this same thing will happen almost immediately in gpu line=0
SubScreen.gpu->refreshAffineStartRegs(-1,-1); //MainScreen.gpu->refreshAffineStartRegs(-1,-1);
//SubScreen.gpu->refreshAffineStartRegs(-1,-1);
} }
MainScreen.gpu->updateBLDALPHA(); MainScreen.gpu->updateBLDALPHA();

View File

@ -86,7 +86,7 @@ static u64 isqrt (u64 x) {
return root; return root;
} }
u16 partie = 1; u32 partie = 1;
u32 _MMU_MAIN_MEM_MASK = 0x3FFFFF; u32 _MMU_MAIN_MEM_MASK = 0x3FFFFF;
#define ROM_MASK 3 #define ROM_MASK 3

View File

@ -117,7 +117,6 @@ struct MMU_struct {
u8 powerMan_Reg[4]; u8 powerMan_Reg[4];
memory_chip_t fw; memory_chip_t fw;
memory_chip_t bupmem;
nds_dscard dscard[2]; nds_dscard dscard[2];
u32 CheckTimers; u32 CheckTimers;
@ -244,6 +243,8 @@ u8 FASTCALL _MMU_ARM7_read08(u32 adr);
u16 FASTCALL _MMU_ARM7_read16(u32 adr); u16 FASTCALL _MMU_ARM7_read16(u32 adr);
u32 FASTCALL _MMU_ARM7_read32(u32 adr); u32 FASTCALL _MMU_ARM7_read32(u32 adr);
extern u32 partie;
extern u32 _MMU_MAIN_MEM_MASK; extern u32 _MMU_MAIN_MEM_MASK;
inline void SetupMMU(bool debugConsole) { inline void SetupMMU(bool debugConsole) {
if(debugConsole) _MMU_MAIN_MEM_MASK = 0x7FFFFF; if(debugConsole) _MMU_MAIN_MEM_MASK = 0x7FFFFF;

File diff suppressed because it is too large Load Diff

View File

@ -1255,7 +1255,7 @@ void WAV_WavSoundUpdate(void* soundData, int numSamples)
void spu_savestate(std::ostream* os) void spu_savestate(std::ostream* os)
{ {
//version //version
write32le(0,os); write32le(2,os);
SPU_struct *spu = SPU_core; SPU_struct *spu = SPU_core;
@ -1283,14 +1283,17 @@ void spu_savestate(std::ostream* os)
write16le(chan.x,os); write16le(chan.x,os);
write16le(chan.psgnoise_last,os); write16le(chan.psgnoise_last,os);
} }
write64le(double_to_u64(samples),os);
} }
bool spu_loadstate(std::istream* is, int size) bool spu_loadstate(std::istream* is, int size)
{ {
u64 temp64;
//read version //read version
int version; int version;
if(read32le(&version,is) != 1) return false; if(read32le(&version,is) != 1) return false;
SPU_struct *spu = SPU_core; SPU_struct *spu = SPU_core;
@ -1311,11 +1314,10 @@ bool spu_loadstate(std::istream* is, int size)
read32le(&chan.length,is); read32le(&chan.length,is);
chan.totlength = chan.length + chan.loopstart; chan.totlength = chan.length + chan.loopstart;
chan.double_totlength_shifted = (double)(chan.totlength << format_shift[chan.format]); chan.double_totlength_shifted = (double)(chan.totlength << format_shift[chan.format]);
if(version == 0) if(version != 1)
{ {
u64 temp; read64le(&temp64,is); chan.sampcnt = u64_to_double(temp64);
read64le(&temp,is); chan.sampcnt = u64_to_double(temp); read64le(&temp64,is); chan.sampinc = u64_to_double(temp64);
read64le(&temp,is); chan.sampinc = u64_to_double(temp);
} }
else else
{ {
@ -1333,6 +1335,10 @@ bool spu_loadstate(std::istream* is, int size)
chan.buf8 = (s8*)&MMU.MMU_MEM[1][(chan.addr>>20)&0xFF][(chan.addr & MMU.MMU_MASK[1][(chan.addr >> 20) & 0xFF])]; chan.buf8 = (s8*)&MMU.MMU_MEM[1][(chan.addr>>20)&0xFF][(chan.addr & MMU.MMU_MASK[1][(chan.addr >> 20) & 0xFF])];
} }
if(version==2) {
read64le(&temp64,is); samples = u64_to_double(temp64);
}
//copy the core spu (the more accurate) to the user spu //copy the core spu (the more accurate) to the user spu
if(SPU_user) { if(SPU_user) {
for(int i=0;i<16;i++) for(int i=0;i<16;i++)

View File

@ -309,6 +309,7 @@ void gfx3d_reset()
{ {
gfx3d = GFX3D(); gfx3d = GFX3D();
control = 0;
drawPending = FALSE; drawPending = FALSE;
flushPending = FALSE; flushPending = FALSE;
listTwiddle = 1; listTwiddle = 1;
@ -2282,7 +2283,7 @@ void gfx3d_GetLineData(int line, u16** dst, u8** dstAlpha)
//consider building a little state structure that looks exactly like this describes //consider building a little state structure that looks exactly like this describes
SFORMAT SF_GFX3D[]={ SFORMAT SF_GFX3D[]={
{ "GCTL", 4, 1, &control}, //{ "GCTL", 4, 1, &control}, //this gets regenerated by the code i hate which regenerates gpu regs
{ "GPAT", 4, 1, &polyAttr}, { "GPAT", 4, 1, &polyAttr},
{ "GPAP", 4, 1, &polyAttrPending}, { "GPAP", 4, 1, &polyAttrPending},
{ "GINB", 4, 1, &inBegin}, { "GINB", 4, 1, &inBegin},

View File

@ -228,7 +228,7 @@ u8 fw_transfer(memory_chip_t *mc, u8 data)
bool BackupDevice::save_state(std::ostream* os) bool BackupDevice::save_state(std::ostream* os)
{ {
int version = 0; int version = 1;
write32le(version,os); write32le(version,os);
write32le(write_enable,os); write32le(write_enable,os);
write32le(com,os); write32le(com,os);
@ -237,6 +237,7 @@ bool BackupDevice::save_state(std::ostream* os)
write32le((u32)state,os); write32le((u32)state,os);
writebuffer(data,os); writebuffer(data,os);
writebuffer(data_autodetect,os); writebuffer(data_autodetect,os);
write32le(addr,os);
return true; return true;
} }
@ -244,7 +245,7 @@ bool BackupDevice::load_state(std::istream* is)
{ {
int version; int version;
if(read32le(&version,is)!=1) return false; if(read32le(&version,is)!=1) return false;
if(version==0) { if(version==0 || version==1) {
read32le(&write_enable,is); read32le(&write_enable,is);
read32le(&com,is); read32le(&com,is);
read32le(&addr_size,is); read32le(&addr_size,is);
@ -254,6 +255,8 @@ bool BackupDevice::load_state(std::istream* is)
state = (STATE)temp; state = (STATE)temp;
readbuffer(data,is); readbuffer(data,is);
readbuffer(data_autodetect,is); readbuffer(data_autodetect,is);
if(version==1)
read32le(&addr,is);
} }
return true; return true;
} }

View File

@ -30,6 +30,7 @@
#include "armcpu.h" #include "armcpu.h"
#include <time.h> #include <time.h>
#include <string.h> #include <string.h>
#include "saves.h"
#ifdef WIN32 #ifdef WIN32
#include "windows/main.h" #include "windows/main.h"
#endif #endif
@ -58,11 +59,38 @@ typedef struct
u8 cmdStat; u8 cmdStat;
u8 bitsCount; u8 bitsCount;
u8 data[8]; u8 data[8];
u8 cmdBitsSize[8];
} _RTC; } _RTC;
_RTC rtc; _RTC rtc;
u8 cmdBitsSize[8] = {8, 8, 56, 24, 0, 24, 8, 8}; SFORMAT SF_RTC[]={
{ "R000", 1, 1, &rtc.regStatus1},
{ "R010", 1, 1, &rtc.regStatus2},
{ "R020", 1, 1, &rtc.regAdjustment},
{ "R030", 1, 1, &rtc.regFree},
{ "R040", 1, 1, &rtc._prevSCK},
{ "R050", 1, 1, &rtc._prevCS},
{ "R060", 1, 1, &rtc._prevSIO},
{ "R070", 1, 1, &rtc._SCK},
{ "R080", 1, 1, &rtc._CS},
{ "R090", 1, 1, &rtc._SIO},
{ "R100", 1, 1, &rtc._DD},
{ "R110", 2, 1, &rtc._REG},
{ "R120", 1, 1, &rtc.cmd},
{ "R130", 1, 1, &rtc.cmdStat},
{ "R140", 1, 1, &rtc.bitsCount},
{ "R150", 1, 8, &rtc.data[0]},
{ "R160", 1, 8, &rtc.cmdBitsSize[0]},
{ 0 }
};
static const u8 kDefaultCmdBitsSize[8] = {8, 8, 56, 24, 0, 24, 8, 8};
#define toBCD(x) ((x / 10) << 4) | (x % 10); #define toBCD(x) ((x / 10) << 4) | (x % 10);
@ -260,6 +288,7 @@ static void rtcSend()
void rtcInit() void rtcInit()
{ {
memset(&rtc, 0, sizeof(_RTC)); memset(&rtc, 0, sizeof(_RTC));
memcpy(rtc.cmdBitsSize,kDefaultCmdBitsSize,8);
rtc.regStatus1 |= 0x02; rtc.regStatus1 |= 0x02;
} }
@ -322,9 +351,9 @@ void rtcWrite(u16 val)
if ((rtc.cmd >> 1) == 0x04) if ((rtc.cmd >> 1) == 0x04)
{ {
if ((rtc.regStatus2 & 0x0F) == 0x04) if ((rtc.regStatus2 & 0x0F) == 0x04)
cmdBitsSize[rtc.cmd >> 1] = 24; rtc.cmdBitsSize[rtc.cmd >> 1] = 24;
else else
cmdBitsSize[rtc.cmd >> 1] = 8; rtc.cmdBitsSize[rtc.cmd >> 1] = 8;
} }
if (rtc.cmd & 0x01) if (rtc.cmd & 0x01)
{ {
@ -345,7 +374,7 @@ void rtcWrite(u16 val)
{ {
if(rtc._SIO) rtc.data[rtc.bitsCount >> 3] |= (1 << (rtc.bitsCount & 0x07)); if(rtc._SIO) rtc.data[rtc.bitsCount >> 3] |= (1 << (rtc.bitsCount & 0x07));
rtc.bitsCount++; rtc.bitsCount++;
if (rtc.bitsCount == cmdBitsSize[rtc.cmd >> 1]) if (rtc.bitsCount == rtc.cmdBitsSize[rtc.cmd >> 1])
{ {
rtcSend(); rtcSend();
rtc.cmdStat = 0; rtc.cmdStat = 0;
@ -363,7 +392,7 @@ void rtcWrite(u16 val)
rtc._REG &= ~0x01; rtc._REG &= ~0x01;
rtc.bitsCount++; rtc.bitsCount++;
if (rtc.bitsCount == cmdBitsSize[rtc.cmd >> 1]) if (rtc.bitsCount == rtc.cmdBitsSize[rtc.cmd >> 1])
rtc.cmdStat = 0; rtc.cmdStat = 0;
} }
break; break;

View File

@ -199,6 +199,8 @@ SFORMAT SF_MMU[]={
{ "MIE_", 4, 2, MMU.reg_IE}, { "MIE_", 4, 2, MMU.reg_IE},
{ "MIF_", 4, 2, MMU.reg_IF}, { "MIF_", 4, 2, MMU.reg_IF},
{ "MPAR", 4, 1, &partie},
{ "MDST", 4, 8, MMU.DMAStartTime}, { "MDST", 4, 8, MMU.DMAStartTime},
{ "MDCY", 4, 8, MMU.DMACycle}, { "MDCY", 4, 8, MMU.DMACycle},
{ "MDCR", 4, 8, MMU.DMACrt}, { "MDCR", 4, 8, MMU.DMACrt},
@ -218,15 +220,12 @@ SFORMAT SF_MMU[]={
{ "MSQ4", 4, 1, &MMU.sqrtCycles}, { "MSQ4", 4, 1, &MMU.sqrtCycles},
//begin memory chips //begin memory chips
//we are skipping the firmware, because we really don't want to save the firmware to the savestate { "BUCO", 1, 1, &MMU.fw.com},
//but, we will need to think about the philosophy of this. { "BUAD", 4, 1, &MMU.fw.addr},
//should we perhaps hash the current firmware and save it, so that we can match it against the loader's firmware? { "BUAS", 1, 1, &MMU.fw.addr_shift},
{ "BUCO", 1, 1, &MMU.bupmem.com}, { "BUAZ", 1, 1, &MMU.fw.addr_size},
{ "BUAD", 4, 1, &MMU.bupmem.addr}, { "BUWE", 4, 1, &MMU.fw.write_enable},
{ "BUAS", 1, 1, &MMU.bupmem.addr_shift}, { "BUWR", 4, 1, &MMU.fw.writeable_buffer},
{ "BUAZ", 1, 1, &MMU.bupmem.addr_size},
{ "BUWE", 4, 1, &MMU.bupmem.write_enable},
//writeable_buffer ???
//end memory chips //end memory chips
{ "MC0A", 4, 1, &MMU.dscard[0].address}, { "MC0A", 4, 1, &MMU.dscard[0].address},
@ -264,6 +263,105 @@ static void mmu_savestate(std::ostream* os)
MMU_new.backupDevice.save_state(os); MMU_new.backupDevice.save_state(os);
} }
SFORMAT SF_WIFI[]={
{ "W000", 4, 1, &wifiMac.powerOn},
{ "W010", 4, 1, &wifiMac.powerOnPending},
{ "W020", 2, 1, &wifiMac.rfStatus},
{ "W030", 2, 1, &wifiMac.rfPins},
{ "W040", 2, 1, &wifiMac.IE.val},
{ "W050", 2, 1, &wifiMac.IF.val},
{ "W060", 2, 1, &wifiMac.macMode},
{ "W070", 2, 1, &wifiMac.wepMode},
{ "W080", 4, 1, &wifiMac.WEP_enable},
{ "W090", 2, 3, &wifiMac.TXSlot[0]},
{ "W100", 2, 1, &wifiMac.TXCnt},
{ "W110", 2, 1, &wifiMac.TXOpt},
{ "W120", 2, 1, &wifiMac.TXStat},
{ "W130", 2, 1, &wifiMac.BEACONSlot},
{ "W140", 4, 1, &wifiMac.BEACON_enable},
{ "W150", 1, 1, &wifiMac.txCurSlot},
{ "W160", 1, 3, &wifiMac.txSlotBusy[0]},
{ "W170", 4, 3, &wifiMac.txSlotAddr[0]},
{ "W180", 4, 3, &wifiMac.txSlotLen[0]},
{ "W190", 4, 3, &wifiMac.txSlotRemainingBytes[0]},
{ "W200", 2, 1, &wifiMac.RXCnt},
{ "W210", 2, 1, &wifiMac.RXCheckCounter},
{ "W220", 1, 6, &wifiMac.mac.bytes},
{ "W230", 1, 6, &wifiMac.bss.bytes},
{ "W240", 2, 1, &wifiMac.aid},
{ "W250", 2, 1, &wifiMac.pid},
{ "W260", 2, 1, &wifiMac.retryLimit},
{ "W270", 4, 1, &wifiMac.crystalEnabled},
{ "W280", 8, 1, &wifiMac.usec},
{ "W290", 4, 1, &wifiMac.usecEnable},
{ "W300", 8, 1, &wifiMac.ucmp},
{ "W310", 4, 1, &wifiMac.ucmpEnable},
{ "W320", 2, 1, &wifiMac.eCount},
{ "W330", 4, 1, &wifiMac.eCountEnable},
{ "WR00", 4, 1, &wifiMac.RF.CFG1.val},
{ "WR01", 4, 1, &wifiMac.RF.IFPLL1.val},
{ "WR02", 4, 1, &wifiMac.RF.IFPLL2.val},
{ "WR03", 4, 1, &wifiMac.RF.IFPLL3.val},
{ "WR04", 4, 1, &wifiMac.RF.RFPLL1.val},
{ "WR05", 4, 1, &wifiMac.RF.RFPLL2.val},
{ "WR06", 4, 1, &wifiMac.RF.RFPLL3.val},
{ "WR07", 4, 1, &wifiMac.RF.RFPLL4.val},
{ "WR08", 4, 1, &wifiMac.RF.CAL1.val},
{ "WR09", 4, 1, &wifiMac.RF.TXRX1.val},
{ "WR10", 4, 1, &wifiMac.RF.PCNT1.val},
{ "WR11", 4, 1, &wifiMac.RF.PCNT2.val},
{ "WR12", 4, 1, &wifiMac.RF.VCOT1.val},
{ "W340", 1, 105, &wifiMac.BB.data[0]},
{ "W350", 2, 1, &wifiMac.rfIOCnt.val},
{ "W360", 2, 1, &wifiMac.rfIOStatus.val},
{ "W370", 4, 1, &wifiMac.rfIOData.val},
{ "W380", 2, 1, &wifiMac.bbIOCnt.val},
{ "W390", 1, 1, &wifiMac.bbDataToWrite},
{ "W400", 2, 0x1000, &wifiMac.circularBuffer[0]},
{ "W410", 2, 1, &wifiMac.RXRangeBegin},
{ "W420", 2, 1, &wifiMac.RXRangeEnd},
{ "W430", 2, 1, &wifiMac.RXHWWriteCursor},
{ "W440", 2, 1, &wifiMac.RXHWWriteCursorReg},
{ "W450", 2, 1, &wifiMac.RXHWWriteCursorLatched},
{ "W460", 2, 1, &wifiMac.RXReadCursor},
{ "W470", 2, 1, &wifiMac.RXUnits},
{ "W480", 2, 1, &wifiMac.RXBufCount},
{ "W490", 2, 1, &wifiMac.CircBufReadAddress},
{ "W500", 2, 1, &wifiMac.CircBufWriteAddress},
{ "W510", 2, 1, &wifiMac.CircBufRdEnd},
{ "W520", 2, 1, &wifiMac.CircBufRdSkip},
{ "W530", 2, 1, &wifiMac.CircBufWrEnd},
{ "W540", 2, 1, &wifiMac.CircBufWrSkip},
{ "W540", 4, 1, &wifiMac.curPacketSize[0]},
{ "W550", 4, 1, &wifiMac.curPacketPos[0]},
{ "W560", 4, 1, &wifiMac.curPacketSending[0]},
{ "W570", 2, 0x800, &wifiMac.ioMem[0]},
{ "W580", 2, 1, &wifiMac.randomSeed},
{ "WX00", 8, 1, &wifiMac.SoftAP.usecCounter},
{ "WX10", 1, 4096, &wifiMac.SoftAP.curPacket[0]},
{ "WX20", 4, 1, &wifiMac.SoftAP.curPacketSize},
{ "WX30", 4, 1, &wifiMac.SoftAP.curPacketPos},
{ "WX40", 4, 1, &wifiMac.SoftAP.curPacketSending},
{ 0 }
};
static bool mmu_loadstate(std::istream* is, int size) static bool mmu_loadstate(std::istream* is, int size)
{ {
//read version //read version
@ -448,7 +546,7 @@ void clear_savestates()
void scan_savestates() void scan_savestates()
{ {
struct stat sbuf; struct stat sbuf;
char filename[MAX_PATH]; char filename[MAX_PATH+1];
u8 i; u8 i;
clear_savestates(); clear_savestates();
@ -460,7 +558,7 @@ void scan_savestates()
sprintf(filename+strlen(filename), ".ds%d", i); sprintf(filename+strlen(filename), ".ds%d", i);
if( stat(filename,&sbuf) == -1 ) continue; if( stat(filename,&sbuf) == -1 ) continue;
savestates[i-1].exists = TRUE; savestates[i-1].exists = TRUE;
strncpy(savestates[i-1].date, format_time(sbuf.st_mtime),40-strlen(savestates[i-1].date)); strncpy(savestates[i-1].date, format_time(sbuf.st_mtime),MAX_PATH);
} }
return ; return ;
@ -469,7 +567,12 @@ void scan_savestates()
void savestate_slot(int num) void savestate_slot(int num)
{ {
struct stat sbuf; struct stat sbuf;
char filename[MAX_PATH]; char filename[MAX_PATH+1];
if(num<0 || num>=NB_STATES) {
assert(false);
printf("wtf?? why would you do that.\n");
}
strncpy(filename, pathFilenameToROMwithoutExt, MAX_PATH); strncpy(filename, pathFilenameToROMwithoutExt, MAX_PATH);
if (strlen(filename) + strlen(".dsx") + strlen("-2147483648") /* = biggest string for num */ >MAX_PATH) return ; if (strlen(filename) + strlen(".dsx") + strlen("-2147483648") /* = biggest string for num */ >MAX_PATH) return ;
@ -487,9 +590,9 @@ void savestate_slot(int num)
return; return;
} }
savestates[num-1].exists = TRUE; savestates[num].exists = TRUE;
if( stat(filename,&sbuf) == -1 ) return; if( stat(filename,&sbuf) == -1 ) return;
strncpy(savestates[num-1].date, format_time(sbuf.st_mtime),40-strlen(savestates[num-1].date)); strncpy(savestates[num].date, format_time(sbuf.st_mtime),MAX_PATH);
} }
void loadstate_slot(int num) void loadstate_slot(int num)
@ -569,7 +672,7 @@ int sram_save (const char *file_name) {
} }
static SFORMAT *CheckS(SFORMAT *sf, u32 size, u32 count, char *desc) static const SFORMAT *CheckS(const SFORMAT *sf, u32 size, u32 count, char *desc)
{ {
while(sf->v) while(sf->v)
{ {
@ -594,9 +697,9 @@ static SFORMAT *CheckS(SFORMAT *sf, u32 size, u32 count, char *desc)
} }
static bool ReadStateChunk(std::istream* is, SFORMAT *sf, int size) static bool ReadStateChunk(std::istream* is, const SFORMAT *sf, int size)
{ {
SFORMAT *tmp; const SFORMAT *tmp;
int temp = is->tellg(); int temp = is->tellg();
while(is->tellg()<temp+size) while(is->tellg()<temp+size)
@ -635,7 +738,7 @@ static bool ReadStateChunk(std::istream* is, SFORMAT *sf, int size)
static int SubWrite(std::ostream* os, SFORMAT *sf) static int SubWrite(std::ostream* os, const SFORMAT *sf)
{ {
uint32 acc=0; uint32 acc=0;
@ -691,7 +794,7 @@ static int SubWrite(std::ostream* os, SFORMAT *sf)
return(acc); return(acc);
} }
static int savestate_WriteChunk(std::ostream* os, int type, SFORMAT *sf) static int savestate_WriteChunk(std::ostream* os, int type, const SFORMAT *sf)
{ {
write32le(type,os); write32le(type,os);
if(!sf) return 4; if(!sf) return 4;
@ -791,6 +894,8 @@ bool savestate_save (const char *file_name)
} else return false; } else return false;
} }
extern SFORMAT SF_RTC[];
static void writechunks(std::ostream* os) { static void writechunks(std::ostream* os) {
savestate_WriteChunk(os,1,SF_ARM9); savestate_WriteChunk(os,1,SF_ARM9);
savestate_WriteChunk(os,2,SF_ARM7); savestate_WriteChunk(os,2,SF_ARM7);
@ -805,6 +910,8 @@ static void writechunks(std::ostream* os) {
savestate_WriteChunk(os,91,gfx3d_savestate); savestate_WriteChunk(os,91,gfx3d_savestate);
savestate_WriteChunk(os,100,SF_MOVIE); savestate_WriteChunk(os,100,SF_MOVIE);
savestate_WriteChunk(os,101,mov_savestate); savestate_WriteChunk(os,101,mov_savestate);
savestate_WriteChunk(os,110,SF_WIFI);
savestate_WriteChunk(os,120,SF_RTC);
savestate_WriteChunk(os,0xFFFFFFFF,(SFORMAT*)0); savestate_WriteChunk(os,0xFFFFFFFF,(SFORMAT*)0);
} }
@ -833,6 +940,8 @@ static bool ReadStateChunks(std::istream* is, s32 totalsize)
case 91: if(!gfx3d_loadstate(is,size)) ret=false; break; case 91: if(!gfx3d_loadstate(is,size)) ret=false; break;
case 100: if(!ReadStateChunk(is,SF_MOVIE, size)) ret=false; break; case 100: if(!ReadStateChunk(is,SF_MOVIE, size)) ret=false; break;
case 101: if(!mov_loadstate(is, size)) ret=false; break; case 101: if(!mov_loadstate(is, size)) ret=false; break;
case 110: if(!ReadStateChunk(is,SF_WIFI,size)) ret=false; break;
case 120: if(!ReadStateChunk(is,SF_RTC,size)) ret=false; break;
default: default:
ret=false; ret=false;
break; break;
@ -854,7 +963,8 @@ static void loadstate()
_MMU_write16<ARMCPU_ARM9>(0x04000304, _MMU_read16<ARMCPU_ARM9>(0x04000304)); _MMU_write16<ARMCPU_ARM9>(0x04000304, _MMU_read16<ARMCPU_ARM9>(0x04000304));
// This should regenerate the graphics configuration // This should regenerate the graphics configuration
for (int i = REG_BASE_DISPA; i<=REG_BASE_DISPA + 0x7F; i+=2) //zero 27-jul-09 : was formerly up to 7F but that wrote to dispfifo which is dumb (one of nitsuja's desynch bugs)
for (int i = REG_BASE_DISPA; i<=REG_BASE_DISPA + 0x66; i+=2)
_MMU_write16<ARMCPU_ARM9>(i, _MMU_read16<ARMCPU_ARM9>(i)); _MMU_write16<ARMCPU_ARM9>(i, _MMU_read16<ARMCPU_ARM9>(i));
for (int i = REG_BASE_DISPB; i<=REG_BASE_DISPB + 0x7F; i+=2) for (int i = REG_BASE_DISPB; i<=REG_BASE_DISPB + 0x7F; i+=2)
_MMU_write16<ARMCPU_ARM9>(i, _MMU_read16<ARMCPU_ARM9>(i)); _MMU_write16<ARMCPU_ARM9>(i, _MMU_read16<ARMCPU_ARM9>(i));

View File

@ -1,5 +1,5 @@
/* /* Copyright (C) 2007 Tim Seidel
Copyright (C) 2007 Tim Seidel Copyright (C) 2008-2009 DeSmuME team
This file is part of DeSmuME This file is part of DeSmuME
@ -26,7 +26,15 @@
#ifdef EXPERIMENTAL_WIFI #ifdef EXPERIMENTAL_WIFI
wifimac_t wifiMac ; #ifdef WIN32
#include "windriver.h"
#else
#include "pcap/pcap.h"
#endif
wifimac_t wifiMac;
bool wifi_netEnabled = false;
pcap_t *wifi_bridge = NULL;
#endif #endif
@ -306,6 +314,10 @@ static u32 WIFI_getCRC32(u8 *data, int len)
static void WIFI_initCRC32Table() static void WIFI_initCRC32Table()
{ {
static bool initialized = false;
if(initialized) return;
initialized = true;
u32 polynomial = 0x04C11DB7; u32 polynomial = 0x04C11DB7;
for(int i = 0; i < 0x100; i++) for(int i = 0; i < 0x100; i++)
@ -539,13 +551,15 @@ static void WIFI_triggerIRQ(wifimac_t *wifi, u8 irq)
void WIFI_Init(wifimac_t *wifi) void WIFI_Init(wifimac_t *wifi)
{ {
memset(wifi,0,sizeof(wifimac_t));
WIFI_initCRC32Table(); WIFI_initCRC32Table();
WIFI_resetRF(&wifi->RF) ; WIFI_resetRF(&wifi->RF) ;
wifi->netEnabled = false; wifi_netEnabled = false;
if(driver->WIFI_Host_InitSystem()) if(driver->WIFI_Host_InitSystem())
{ {
wifi->netEnabled = true; wifi_netEnabled = true;
} }
wifi->powerOn = FALSE; wifi->powerOn = FALSE;
wifi->powerOnPending = FALSE; wifi->powerOnPending = FALSE;
@ -1254,12 +1268,11 @@ int WIFI_SoftAP_Init(wifimac_t *wifi)
wifi->SoftAP.usecCounter = 0; wifi->SoftAP.usecCounter = 0;
wifi->SoftAP.curPacket = NULL;
wifi->SoftAP.curPacketSize = 0; wifi->SoftAP.curPacketSize = 0;
wifi->SoftAP.curPacketPos = 0; wifi->SoftAP.curPacketPos = 0;
wifi->SoftAP.curPacketSending = FALSE; wifi->SoftAP.curPacketSending = FALSE;
if(wifiMac.netEnabled) if(wifi_netEnabled)
{ {
if(desmume_pcap_findalldevs(&alldevs, errbuf) == -1) if(desmume_pcap_findalldevs(&alldevs, errbuf) == -1)
{ {
@ -1267,8 +1280,8 @@ int WIFI_SoftAP_Init(wifimac_t *wifi)
return 0; return 0;
} }
wifi->SoftAP.bridge = desmume_pcap_open(WIFI_index_device(alldevs,CommonSettings.wifiBridgeAdapterNum)->name, PACKET_SIZE, 0, 1, errbuf); wifi_bridge = desmume_pcap_open(WIFI_index_device(alldevs,CommonSettings.wifiBridgeAdapterNum)->name, PACKET_SIZE, 0, 1, errbuf);
if(wifi->SoftAP.bridge == NULL) if(wifi_bridge == NULL)
{ {
printf("SoftAP: PCAP error with pcap_open(): %s\n", errbuf); printf("SoftAP: PCAP error with pcap_open(): %s\n", errbuf);
return 0; return 0;
@ -1282,14 +1295,11 @@ int WIFI_SoftAP_Init(wifimac_t *wifi)
void WIFI_SoftAP_Shutdown(wifimac_t *wifi) void WIFI_SoftAP_Shutdown(wifimac_t *wifi)
{ {
if(wifiMac.netEnabled) if(wifi_netEnabled)
{ {
if(wifi->SoftAP.bridge != NULL) if(wifi_bridge != NULL)
desmume_pcap_close(wifi->SoftAP.bridge); desmume_pcap_close(wifi_bridge);
} }
if(wifi->SoftAP.curPacket)
delete wifi->SoftAP.curPacket;
} }
static void WIFI_SoftAP_MakeRXHeader(wifimac_t *wifi, u16 flags, u16 xferRate, u16 len, u8 maxRSSI, u8 minRSSI) static void WIFI_SoftAP_MakeRXHeader(wifimac_t *wifi, u16 flags, u16 xferRate, u16 len, u8 maxRSSI, u8 minRSSI)
@ -1331,8 +1341,6 @@ void WIFI_SoftAP_RecvPacketFromDS(wifimac_t *wifi, u8 *packet, int len)
int packetLen = sizeof(SoftAP_ProbeResponse); int packetLen = sizeof(SoftAP_ProbeResponse);
int totalLen = (packetLen + 12); int totalLen = (packetLen + 12);
wifi->SoftAP.curPacket = new u8[totalLen];
// Make the RX header // Make the RX header
// About the packet length: // About the packet length:
// GBATek says the length entry of the RX header is the length of the IEEE // GBATek says the length entry of the RX header is the length of the IEEE
@ -1368,8 +1376,6 @@ void WIFI_SoftAP_RecvPacketFromDS(wifimac_t *wifi, u8 *packet, int len)
int packetLen = sizeof(SoftAP_AuthFrame); int packetLen = sizeof(SoftAP_AuthFrame);
int totalLen = (packetLen + 12); int totalLen = (packetLen + 12);
wifi->SoftAP.curPacket = new u8[totalLen];
// Make the RX header // Make the RX header
WIFI_SoftAP_MakeRXHeader(wifi, 0x0010, 20, packetLen, 0, 0); WIFI_SoftAP_MakeRXHeader(wifi, 0x0010, 20, packetLen, 0, 0);
@ -1395,8 +1401,6 @@ void WIFI_SoftAP_RecvPacketFromDS(wifimac_t *wifi, u8 *packet, int len)
int packetLen = sizeof(SoftAP_AssocResponse); int packetLen = sizeof(SoftAP_AssocResponse);
int totalLen = (packetLen + 12); int totalLen = (packetLen + 12);
wifi->SoftAP.curPacket = new u8[totalLen];
// Make the RX header // Make the RX header
WIFI_SoftAP_MakeRXHeader(wifi, 0x0010, 20, packetLen, 0, 0); WIFI_SoftAP_MakeRXHeader(wifi, 0x0010, 20, packetLen, 0, 0);
@ -1453,8 +1457,8 @@ void WIFI_SoftAP_RecvPacketFromDS(wifimac_t *wifi, u8 *packet, int len)
// Checksum // Checksum
// TODO ? // TODO ?
if(wifi->netEnabled) //dont try to pcap out the packet unless network is enabled if(wifi_netEnabled) //dont try to pcap out the packet unless network is enabled
desmume_pcap_sendpacket(wifi->SoftAP.bridge, ethernetframe, eflen); desmume_pcap_sendpacket(wifi_bridge, ethernetframe, eflen);
delete ethernetframe; delete ethernetframe;
} }
@ -1467,9 +1471,6 @@ static void WIFI_SoftAP_SendBeacon(wifimac_t *wifi)
int packetLen = sizeof(SoftAP_Beacon); int packetLen = sizeof(SoftAP_Beacon);
int totalLen = (packetLen + 12); int totalLen = (packetLen + 12);
if(wifi->SoftAP.curPacket) delete wifi->SoftAP.curPacket;
wifi->SoftAP.curPacket = new u8[totalLen];
// Make the RX header // Make the RX header
WIFI_SoftAP_MakeRXHeader(wifi, 0x0011, 20, packetLen, 0, 0); WIFI_SoftAP_MakeRXHeader(wifi, 0x0011, 20, packetLen, 0, 0);
@ -1539,9 +1540,6 @@ void WIFI_SoftAP_usTrigger(wifimac_t *wifi)
wifi->SoftAP.curPacketPos = 0; wifi->SoftAP.curPacketPos = 0;
wifi->SoftAP.curPacketSending = FALSE; wifi->SoftAP.curPacketSending = FALSE;
delete wifi->SoftAP.curPacket;
wifi->SoftAP.curPacket = NULL;
wifi->RXHWWriteCursorReg = ((wifi->RXHWWriteCursor + 1) & (~1)); wifi->RXHWWriteCursorReg = ((wifi->RXHWWriteCursor + 1) & (~1));
WIFI_triggerIRQ(wifi, WIFI_IRQ_RECVCOMPLETE); WIFI_triggerIRQ(wifi, WIFI_IRQ_RECVCOMPLETE);

View File

@ -1,5 +1,5 @@
/* /* Copyright (C) 2007 Tim Seidel
Copyright (C) 2007 Tim Seidel Copyright (C) 2008-2009 DeSmuME team
This file is part of DeSmuME This file is part of DeSmuME
@ -25,12 +25,6 @@
#ifdef EXPERIMENTAL_WIFI #ifdef EXPERIMENTAL_WIFI
#ifdef WIN32
#include "windriver.h"
#else
#include "pcap/pcap.h"
#endif
#define HAVE_REMOTE #define HAVE_REMOTE
#define WPCAP #define WPCAP
#define PACKET_SIZE 65535 #define PACKET_SIZE 65535
@ -261,6 +255,7 @@ typedef struct rffilter_t
/* 6*/ unsigned MID_POWER:6; /* 6*/ unsigned MID_POWER:6;
/*12*/ unsigned MAX_POWER:6; /*12*/ unsigned MAX_POWER:6;
} bits ; } bits ;
u32 val ;
} PCNT2 ; } PCNT2 ;
union VCOT1 union VCOT1
{ {
@ -365,6 +360,7 @@ typedef union
/* wifimac_t: the buildin mac (arm7 addressrange: 0x04800000-0x04FFFFFF )*/ /* wifimac_t: the buildin mac (arm7 addressrange: 0x04800000-0x04FFFFFF )*/
/* http://www.akkit.org/info/dswifi.htm#WifiIOMap */ /* http://www.akkit.org/info/dswifi.htm#WifiIOMap */
typedef struct typedef struct
{ {
/* power */ /* power */
@ -404,6 +400,7 @@ typedef struct
/* addressing/handshaking */ /* addressing/handshaking */
union union
{ {
//TODO - is this endian safe? don't think so
u16 words[3] ; u16 words[3] ;
u8 bytes[6] ; u8 bytes[6] ;
} mac ; } mac ;
@ -455,9 +452,8 @@ typedef struct
u16 CircBufWrSkip ; u16 CircBufWrSkip ;
/* tx packets */ /* tx packets */
u8 *curPacket[3]; s32 curPacketSize[3];
int curPacketSize[3]; s32 curPacketPos[3];
int curPacketPos[3];
BOOL curPacketSending[3]; BOOL curPacketSending[3];
/* i/o mem */ /* i/o mem */
@ -469,23 +465,24 @@ typedef struct
/* SoftAP */ /* SoftAP */
struct _SoftAP struct _SoftAP
{ {
pcap_t *bridge;
u64 usecCounter; u64 usecCounter;
u8 *curPacket; u8 curPacket[4096];
int curPacketSize; s32 curPacketSize;
int curPacketPos; s32 curPacketPos;
BOOL curPacketSending; BOOL curPacketSending;
} SoftAP; } SoftAP;
/* desmume host communication */
bool netEnabled;
} wifimac_t ; } wifimac_t ;
extern wifimac_t wifiMac ;
// desmume host communication
typedef struct pcap pcap_t;
extern bool wifi_netEnabled;
extern pcap_t *wifi_bridge;
extern wifimac_t wifiMac;
void WIFI_Init(wifimac_t *wifi); void WIFI_Init(wifimac_t *wifi);

View File

@ -2598,7 +2598,7 @@ void RunConfig(CONFIGSCREEN which)
break; break;
case CONFIGSCREEN_WIFI: case CONFIGSCREEN_WIFI:
#ifdef EXPERIMENTAL_WIFI #ifdef EXPERIMENTAL_WIFI
if(wifiMac.netEnabled) if(wifi_netEnabled)
{ {
DialogBox(hAppInst,MAKEINTRESOURCE(IDD_WIFISETTINGS), hwnd, (DLGPROC) WifiSettingsDlgProc); DialogBox(hAppInst,MAKEINTRESOURCE(IDD_WIFISETTINGS), hwnd, (DLGPROC) WifiSettingsDlgProc);
} }