emulate firmware command 0x9F (read ID) and update test

This commit is contained in:
zeromus 2010-08-30 06:30:57 +00:00
parent e1901a2f08
commit a199a91f47
5 changed files with 230 additions and 161 deletions

View File

@ -1,6 +1,6 @@
/* Copyright (C) 2006 thoduv /* Copyright (C) 2006 thoduv
Copyright (C) 2006-2007 Theo Berkau Copyright (C) 2006-2007 Theo Berkau
Copyright (C) 2008-2009 DeSmuME team Copyright (C) 2008-2010 DeSmuME team
This file is part of DeSmuME This file is part of DeSmuME
@ -35,21 +35,22 @@
#include <xtl.h> // it`s really need? #include <xtl.h> // it`s really need?
#endif #endif
#define FW_CMD_READ 0x3 #define FW_CMD_READ 0x03
#define FW_CMD_WRITEDISABLE 0x4 #define FW_CMD_WRITEDISABLE 0x04
#define FW_CMD_READSTATUS 0x5 #define FW_CMD_READSTATUS 0x05
#define FW_CMD_WRITEENABLE 0x6 #define FW_CMD_WRITEENABLE 0x06
#define FW_CMD_PAGEWRITE 0xA #define FW_CMD_PAGEWRITE 0x0A
#define FW_CMD_READ_ID 0x9F
#define BM_CMD_AUTODETECT 0xFF #define BM_CMD_AUTODETECT 0xFF
#define BM_CMD_WRITESTATUS 0x1 #define BM_CMD_WRITESTATUS 0x01
#define BM_CMD_WRITELOW 0x2 #define BM_CMD_WRITELOW 0x02
#define BM_CMD_READLOW 0x3 #define BM_CMD_READLOW 0x03
#define BM_CMD_WRITEDISABLE 0x4 #define BM_CMD_WRITEDISABLE 0x04
#define BM_CMD_READSTATUS 0x5 #define BM_CMD_READSTATUS 0x05
#define BM_CMD_WRITEENABLE 0x6 #define BM_CMD_WRITEENABLE 0x06
#define BM_CMD_WRITEHIGH 0xA #define BM_CMD_WRITEHIGH 0x0A
#define BM_CMD_READHIGH 0xB #define BM_CMD_READHIGH 0x0B
/* FLASH*/ /* FLASH*/
#define COMM_PAGE_WRITE 0x0A #define COMM_PAGE_WRITE 0x0A
@ -228,31 +229,57 @@ u8 fw_transfer(memory_chip_t *mc, u8 data)
} }
} }
else if(mc->com == FW_CMD_READ_ID)
{
switch(mc->addr)
{
//here is an ID string measured from an old ds fat: 62 16 00 (0x62=sanyo)
//but we chose to use an ST from martin's ds fat string so programs might have a clue as to the firmware size:
//20 40 12
case 0:
data = 0x20;
mc->addr=1;
break;
case 1:
data = 0x40; //according to gbatek this is the device ID for the flash on someone's ds fat
mc->addr=2;
break;
case 2:
data = 0x12;
mc->addr = 0;
break;
}
}
else if(mc->com == FW_CMD_READSTATUS) else if(mc->com == FW_CMD_READSTATUS)
{ {
return (mc->write_enable ? 0x02 : 0x00); return (mc->write_enable ? 0x02 : 0x00);
} }
else /* finally, check if it's a new command */ else //finally, check if it's a new command
{ {
switch(data) switch(data)
{ {
case 0: break; /* nothing */ case 0: break; //nothing
case FW_CMD_READ_ID:
mc->addr = 0;
mc->com = FW_CMD_READ_ID;
break;
case FW_CMD_READ: /* read command */ case FW_CMD_READ: //read command
mc->addr = 0; mc->addr = 0;
mc->addr_shift = 3; mc->addr_shift = 3;
mc->com = FW_CMD_READ; mc->com = FW_CMD_READ;
break; break;
case FW_CMD_WRITEENABLE: /* enable writing */ case FW_CMD_WRITEENABLE: //enable writing
if(mc->writeable_buffer) { mc->write_enable = TRUE; } if(mc->writeable_buffer) { mc->write_enable = TRUE; }
break; break;
case FW_CMD_WRITEDISABLE: /* disable writing */ case FW_CMD_WRITEDISABLE: //disable writing
mc->write_enable = FALSE; mc->write_enable = FALSE;
break; break;
case FW_CMD_PAGEWRITE: /* write command */ case FW_CMD_PAGEWRITE: //write command
if(mc->write_enable) if(mc->write_enable)
{ {
mc->addr = 0; mc->addr = 0;
@ -262,7 +289,7 @@ u8 fw_transfer(memory_chip_t *mc, u8 data)
else { data = 0; } else { data = 0; }
break; break;
case FW_CMD_READSTATUS: /* status register command */ case FW_CMD_READSTATUS: //status register command
mc->com = FW_CMD_READSTATUS; mc->com = FW_CMD_READSTATUS;
break; break;

View File

@ -1,6 +1,6 @@
/* Copyright (C) 2006 thoduv /* Copyright (C) 2006 thoduv
Copyright (C) 2006 Theo Berkau Copyright (C) 2006 Theo Berkau
Copyright (C) 2008-2009 DeSmuME team Copyright (C) 2008-2010 DeSmuME team
This file is part of DeSmuME This file is part of DeSmuME
@ -50,24 +50,24 @@
#define MC_SIZE_256MBITS 0x2000000 #define MC_SIZE_256MBITS 0x2000000
#define MC_SIZE_512MBITS 0x4000000 #define MC_SIZE_512MBITS 0x4000000
typedef struct struct memory_chip_t
{ {
u8 com; /* persistent command actually handled */ u8 com; //persistent command actually handled
u32 addr; /* current address for reading/writing */ u32 addr; //current address for reading/writing
u8 addr_shift; /* shift for address (since addresses are transfered by 3 bytes units) */ u8 addr_shift; //shift for address (since addresses are transfered by 3 bytes units)
u8 addr_size; /* size of addr when writing/reading */ u8 addr_size; //size of addr when writing/reading
BOOL write_enable; /* is write enabled ? */ BOOL write_enable; //is write enabled ?
u8 *data; /* memory data */ u8 *data; //memory data
u32 size; /* memory size */ u32 size; //memory size
BOOL writeable_buffer; /* is "data" writeable ? */ BOOL writeable_buffer; //is "data" writeable ?
int type; /* type of Memory */ int type; //type of Memory
char *filename; char *filename;
FILE *fp; FILE *fp;
u8 autodetectbuf[32768]; u8 autodetectbuf[32768];
int autodetectsize; int autodetectsize;
} memory_chip_t; };
//the new backup system by zeromus //the new backup system by zeromus
class BackupDevice class BackupDevice

View File

@ -1,122 +1,162 @@
/*--------------------------------------------------------------------------------- /*---------------------------------------------------------------------------------
once upon a time, this was: default ARM7 core once upon a time, this was: default ARM7 core
Copyright (C) 2005 Copyright (C) 2005
Michael Noland (joat) Michael Noland (joat)
Jason Rogers (dovoto) Jason Rogers (dovoto)
Dave Murphy (WinterMute) Dave Murphy (WinterMute)
This software is provided 'as-is', without any express or implied This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any warranty. In no event will the authors be held liable for any
damages arising from the use of this software. damages arising from the use of this software.
Permission is granted to anyone to use this software for any Permission is granted to anyone to use this software for any
purpose, including commercial applications, and to alter it and purpose, including commercial applications, and to alter it and
redistribute it freely, subject to the following restrictions: redistribute it freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you 1. The origin of this software must not be misrepresented; you
must not claim that you wrote the original software. If you use must not claim that you wrote the original software. If you use
this software in a product, an acknowledgment in the product this software in a product, an acknowledgment in the product
documentation would be appreciated but is not required. documentation would be appreciated but is not required.
2. Altered source versions must be plainly marked as such, and 2. Altered source versions must be plainly marked as such, and
must not be misrepresented as being the original software. must not be misrepresented as being the original software.
3. This notice may not be removed or altered from any source 3. This notice may not be removed or altered from any source
distribution. distribution.
---------------------------------------------------------------------------------*/ ---------------------------------------------------------------------------------*/
#include <nds.h> #include <nds.h>
#include <dswifi7.h> #include <dswifi7.h>
#include <maxmod7.h> #include <maxmod7.h>
#include "../../regstest.h" #include "../../regstest.h"
#include <nds/arm7/serial.h>
arm7comm_t *arm7comm; arm7comm_t *arm7comm;
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
void VcountHandler() { void VcountHandler() {
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
inputGetAndSend(); inputGetAndSend();
} }
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
void VblankHandler(void) { void VblankHandler(void) {
//--------------------------------------------------------------------------------- //---------------------------------------------------------------------------------
Wifi_Update(); Wifi_Update();
} }
void pokeMessage(const char* msg) //modified from: http://www.bottledlight.com/ds/index.php/Main/Firmware
{ #define FW_READ_ID 0x9F
const char* cp = msg; #define FW_READ 0x03
int i=0; #define FW_READ_STATUS 0x05
while(*cp) u32 getFirmwareType()
arm7comm->message[i++] = *cp++; {
arm7comm->message[i] = 0; u32 result;
}
// Get ID
void fail(const char* msg, u32 offender=0) while (REG_SPICNT & SPI_BUSY);
{ REG_SPICNT = SPI_ENABLE | SPI_CONTINUOUS | SPI_DEVICE_FIRMWARE;
arm7comm->code = 1; REG_SPIDATA = FW_READ_ID;
arm7comm->offender = offender; while (REG_SPICNT & SPI_BUSY);
pokeMessage(msg);
result = 0;
fifoSendValue32(FIFO_USER_01,0); for (int i = 0; i < 3; i++) {
while (1) swiWaitForVBlank(); REG_SPIDATA = 0;
} while (REG_SPICNT & SPI_BUSY);
result = (REG_SPIDATA & 0xFF) | (result<<8);
//--------------------------------------------------------------------------------- }
int main() {
//--------------------------------------------------------------------------------- // Get status
irqInit(); //zeromus note: this is broken. not only does it put the byte in a different spot than the docs said it does,
fifoInit(); //it is coded otherwise glitchily and just returns bytes of the 3-Byte flash ID
//(desmume shows five reads during the ID command; apparently this code fails to reset correctly)
// read User Settings from firmware while (REG_SPICNT & SPI_BUSY);
readUserSettings(); REG_SPICNT = SPI_ENABLE | SPI_CONTINUOUS | SPI_DEVICE_FIRMWARE;
REG_SPIDATA = FW_READ_STATUS;
// Start the RTC tracking IRQ while (REG_SPICNT & SPI_BUSY);
initClockIRQ();
REG_SPIDATA = 0;
SetYtrigger(80); while (REG_SPICNT & SPI_BUSY);
result = ((REG_SPIDATA & 0xFF) << 24) | result;
installWifiFIFO();
installSoundFIFO(); return result;
}
mmInstall(FIFO_MAXMOD);
installSystemFIFO();
void pokeMessage(const char* msg)
irqSet(IRQ_VCOUNT, VcountHandler); {
irqSet(IRQ_VBLANK, VblankHandler); const char* cp = msg;
int i=0;
irqEnable( IRQ_VBLANK | IRQ_VCOUNT | IRQ_NETWORK); while(*cp)
arm7comm->message[i++] = *cp++;
//find out where the arm9 wants us to stash our info arm7comm->message[i] = 0;
while(!fifoCheckAddress(FIFO_USER_01)) swiWaitForVBlank(); }
arm7comm = (arm7comm_t*)fifoGetAddress(FIFO_USER_01);
void fail(const char* msg, u32 offender=0)
{
//spu source reg should only be 27bit arm7comm->code = 1;
//but it is not readable so what does it matter arm7comm->offender = offender;
for(int i=0;i<16;i++) pokeMessage(msg);
{
vu32* reg = (vu32*)(0x04000404 + (i<<4)); fifoSendValue32(FIFO_USER_01,0);
*reg = 0xFFFFFFFF; while (1) swiWaitForVBlank();
//if(*reg != 0x07FFFFFF) fail("spu source reg is only 27bit.\nshould be 0x07FFFFFF",*reg); }
if(*reg != 0x00000000) fail("spu source reg is not readable!",*reg);
} //---------------------------------------------------------------------------------
int main() {
//spu length reg should only be 22bit //---------------------------------------------------------------------------------
for(int i=0;i<16;i++) irqInit();
{ fifoInit();
vu32* reg = (vu32*)(0x0400040C + (i<<4));
*reg = 0xFFFFFFFF; // read User Settings from firmware
//if(*reg != 0x003FFFFF) fail("spu length reg is only 22bit.\nshould be 0x003FFFFF",*reg); readUserSettings();
if(*reg != 0x00000000) fail("spu length reg is not readable!",*reg);
} // Start the RTC tracking IRQ
initClockIRQ();
arm7comm->code = 2; SetYtrigger(80);
fifoSendValue32(FIFO_USER_01,0);
while (1) swiWaitForVBlank(); installWifiFIFO();
} installSoundFIFO();
mmInstall(FIFO_MAXMOD);
installSystemFIFO();
irqSet(IRQ_VCOUNT, VcountHandler);
irqSet(IRQ_VBLANK, VblankHandler);
irqEnable( IRQ_VBLANK | IRQ_VCOUNT | IRQ_NETWORK);
//find out where the arm9 wants us to stash our info
while(!fifoCheckAddress(FIFO_USER_01)) swiWaitForVBlank();
arm7comm = (arm7comm_t*)fifoGetAddress(FIFO_USER_01);
//spu source reg should only be 27bit
//but it is not readable so what does it matter
for(int i=0;i<16;i++)
{
vu32* reg = (vu32*)(0x04000404 + (i<<4));
*reg = 0xFFFFFFFF;
//if(*reg != 0x07FFFFFF) fail("spu source reg is only 27bit.\nshould be 0x07FFFFFF",*reg);
if(*reg != 0x00000000) fail("spu source reg is not readable!",*reg);
}
//spu length reg should only be 22bit
for(int i=0;i<16;i++)
{
vu32* reg = (vu32*)(0x0400040C + (i<<4));
*reg = 0xFFFFFFFF;
//if(*reg != 0x003FFFFF) fail("spu length reg is only 22bit.\nshould be 0x003FFFFF",*reg);
if(*reg != 0x00000000) fail("spu length reg is not readable!",*reg);
}
arm7comm->firmwareId = getFirmwareType();
arm7comm->code = 2;
fifoSendValue32(FIFO_USER_01,0);
while (1) swiWaitForVBlank();
}

View File

@ -90,6 +90,7 @@ int main(void) {
swiWaitForVBlank(); swiWaitForVBlank();
} }
iprintf("firmwareID: %08X\n",arm7comm.firmwareId);
iprintf("arm7 finish code: %d\n",arm7comm.code); iprintf("arm7 finish code: %d\n",arm7comm.code);
if(arm7comm.code == 1) if(arm7comm.code == 1)

View File

@ -1,8 +1,9 @@
typedef struct _arm7comm_t struct arm7comm_t
{ {
int code; int code;
u32 offender; u32 offender;
char message[1024]; char message[1024];
} arm7comm_t; u32 firmwareId;
};
//#define arm7comm ( (arm7comm_t*)0x02200000 ) //#define arm7comm ( (arm7comm_t*)0x02200000 )