-fw.* files renamed to mc.* since it's not just firmware stuff in it anymore.

-Moved those files to main source tree, since it doesn't make sense to have in a separate directory
-Removed spi.* from arm7 directory since they're redundant.
-A few other fixes
This commit is contained in:
cyberwarriorx 2006-10-12 15:42:11 +00:00
parent 0b402eee65
commit b6e940d480
5 changed files with 305 additions and 14 deletions

View File

@ -263,12 +263,12 @@ void MMUInit(void) {
for(i = 0;i < 16;i++)
FIFOInit(MMU.fifos + i);
mc_init(&MMU.spi7.fw, MC_TYPE_FLASH); /* init fw device */
mc_alloc(&MMU.spi7.fw, NDS_FW_SIZE_V1);
mc_init(&MMU.fw, MC_TYPE_FLASH); /* init fw device */
mc_alloc(&MMU.fw, NDS_FW_SIZE_V1);
// Init Backup Memory device, this should really be done when the rom is loaded
mc_init(&MMU.spi7.bupmem, MC_TYPE_EEPROM2);
mc_alloc(&MMU.spi7.bupmem, 65536); // For now we're use 512Kbit support. Eventually this should be detected when rom is loaded
mc_init(&MMU.bupmem, MC_TYPE_EEPROM2);
mc_alloc(&MMU.bupmem, 65536); // For now we're use 512Kbit support. Eventually this should be detected when rom is loaded
}
void MMUDeInit(void) {
@ -786,7 +786,7 @@ void FASTCALL MMU_write16(u32 proc, u32 adr, u16 val)
AUX_SPI_CNT = val;
if (val == 0)
mc_reset_com(&MMU.spi7.bupmem); /* reset backup memory device communication */
mc_reset_com(&MMU.bupmem); /* reset backup memory device communication */
return;
case CARD_EEPDATA:
@ -795,7 +795,7 @@ void FASTCALL MMU_write16(u32 proc, u32 adr, u16 val)
AUX_SPI_CMD = val & 0xFF;
}
MEM_16(MMU.MMU_MEM[proc], CARD_EEPDATA) = bm_transfer(&MMU.spi7.bupmem, val); /* transfer data to backup memory chip and receive back */
MEM_16(MMU.MMU_MEM[proc], CARD_EEPDATA) = bm_transfer(&MMU.bupmem, val); /* transfer data to backup memory chip and receive back */
return;
case REG_SPICNT :
@ -803,9 +803,9 @@ void FASTCALL MMU_write16(u32 proc, u32 adr, u16 val)
{
SPI_CNT = val;
//MMU.spi7.fw.com == 0; /* reset fw device communication */
//MMU.fw.com == 0; /* reset fw device communication */
mc_reset_com(&MMU.spi7.fw); /* reset fw device communication */
mc_reset_com(&MMU.fw); /* reset fw device communication */
}
MEM_16(MMU.MMU_MEM[proc], REG_SPICNT) = val;
@ -832,7 +832,7 @@ void FASTCALL MMU_write16(u32 proc, u32 adr, u16 val)
MEM_16(MMU.MMU_MEM[proc], REG_SPIDATA) = 0;
break;
}
MEM_16(MMU.MMU_MEM[proc], REG_SPIDATA) = fw_transfer(&MMU.spi7.fw, val); /* transfer data to fw chip and receive back */
MEM_16(MMU.MMU_MEM[proc], REG_SPIDATA) = fw_transfer(&MMU.fw, val); /* transfer data to fw chip and receive back */
return;
case SPI_DEVICE_TOUCH:

View File

@ -26,7 +26,8 @@
#include "dscard.h"
#include "arm9/ARM9.h"
#include "arm7/spi.h"
#include "nds/serial.h"
#include "mc.h"
extern char szRomPath[512];
@ -88,7 +89,8 @@ typedef struct {
u32 DMACrt[2][4];
BOOL DMAing[2][4];
nds7_spi_t spi7; /* NOTICE: arm7 only, perhaps should be moved in an arm7-specific struct */
memory_chip_t fw;
memory_chip_t bupmem;
nds_dscard dscard[2];

View File

@ -9,8 +9,7 @@ libdesmume_a_SOURCES = \
debug.c debug.h \
MMU.c MMU.h NDSSystem.c NDSSystem.h \
thumb_instructions.c thumb_instructions.h \
arm7/fw.c arm7/fw.h \
arm7/spi.c arm7/spi.h \
mc.c mc.h \
arm9/GPU.c arm9/GPU.h \
arm9/ARM9.c arm9/ARM9.h \
windows/cflash.c windows/cflash.h fs.h \

245
desmume/src/mc.c Normal file
View File

@ -0,0 +1,245 @@
#include <stdlib.h>
#include "debug.h"
#include "types.h"
#include "mc.h"
#define FW_CMD_READ 0x3
#define FW_CMD_WRITEDISABLE 0x4
#define FW_CMD_READSTATUS 0x5
#define FW_CMD_WRITEENABLE 0x6
#define FW_CMD_PAGEWRITE 0xA
#define BM_CMD_WRITESTATUS 0x1
#define BM_CMD_WRITELOW 0x2
#define BM_CMD_READLOW 0x3
#define BM_CMD_WRITEDISABLE 0x4
#define BM_CMD_READSTATUS 0x5
#define BM_CMD_WRITEENABLE 0x6
#define BM_CMD_WRITEHIGH 0xA
#define BM_CMD_READHIGH 0xB
void mc_init(memory_chip_t *mc, int type)
{
mc->com = 0;
mc->addr = 0;
mc->addr_shift = 0;
mc->data = NULL;
mc->size = 0;
mc->write_enable = FALSE;
mc->writeable_buffer = FALSE;
mc->type = type;
switch(mc->type)
{
case MC_TYPE_EEPROM1:
mc->addr_size = 1;
break;
case MC_TYPE_EEPROM2:
mc->addr_size = 2;
break;
case MC_TYPE_FLASH:
mc->addr_size = 3;
break;
default: break;
}
}
u8 *mc_alloc(memory_chip_t *mc, u32 size)
{
u8 *buffer;
buffer = malloc(size);
if(!buffer) { return NULL; }
mc->data = buffer;
mc->size = size;
mc->writeable_buffer = TRUE;
}
void mc_free(memory_chip_t *mc)
{
if(mc->data) free(mc->data);
mc_init(mc, 0);
}
void mc_reset_com(memory_chip_t *mc)
{
mc->com = 0;
}
u8 fw_transfer(memory_chip_t *mc, u8 data)
{
if(mc->com == FW_CMD_READ || mc->com == FW_CMD_PAGEWRITE) /* check if we are in a command that needs 3 bytes address */
{
if(mc->addr_shift > 0) /* if we got a complete address */
{
mc->addr_shift--;
mc->addr |= data << (mc->addr_shift * 8); /* argument is a byte of address */
}
else /* if we have received 3 bytes of address, proceed command */
{
switch(mc->com)
{
case FW_CMD_READ:
if(mc->addr < mc->size) /* check if we can read */
{
data = mc->data[mc->addr]; /* return byte */
mc->addr++; /* then increment address */
}
break;
case FW_CMD_PAGEWRITE:
if(mc->addr < mc->size)
{
mc->data[mc->addr] = data; /* write byte */
mc->addr++;
}
break;
}
}
}
else if(mc->com == FW_CMD_READSTATUS)
{
return 0;
}
else /* finally, check if it's a new command */
{
switch(data)
{
case 0: break; /* nothing */
case FW_CMD_READ: /* read command */
mc->addr = 0;
mc->addr_shift = 3;
mc->com = FW_CMD_READ;
break;
case FW_CMD_WRITEENABLE: /* enable writing */
if(mc->writeable_buffer) { mc->write_enable = TRUE; }
break;
case FW_CMD_WRITEDISABLE: /* disable writing */
mc->write_enable = FALSE;
break;
case FW_CMD_PAGEWRITE: /* write command */
if(mc->write_enable)
{
mc->addr = 0;
mc->addr_shift = 3;
mc->com = FW_CMD_PAGEWRITE;
}
else { data = 0; }
break;
case FW_CMD_READSTATUS: /* status register command */
mc->com = FW_CMD_READSTATUS;
break;
default:
LOG("Unhandled FW command: %02X\n", data);
break;
}
}
return data;
}
u8 bm_transfer(memory_chip_t *mc, u8 data)
{
if(mc->com == BM_CMD_READLOW || mc->com == BM_CMD_READHIGH ||
mc->com == BM_CMD_WRITELOW || mc->com == BM_CMD_WRITEHIGH) /* check if we are in a command that needs multiple byte address */
{
if(mc->addr_shift > 0) /* if we got a complete address */
{
mc->addr_shift--;
mc->addr |= data << (mc->addr_shift * 8); /* argument is a byte of address */
}
else /* if we have received all bytes of address, proceed command */
{
switch(mc->com)
{
case BM_CMD_READLOW:
if(mc->addr < mc->size) /* check if we can read */
{
LOG("Read Backup Memory addr %08X(%02X)\n", mc->addr, mc->data[mc->addr]);
data = mc->data[mc->addr]; /* return byte */
mc->addr++; /* then increment address */
}
break;
case BM_CMD_WRITELOW:
if(mc->addr < mc->size)
{
LOG("Write Backup Memory addr %08X with %02X\n", mc->addr, data);
mc->data[mc->addr] = data; /* write byte */
mc->addr++;
}
break;
}
}
}
else if(mc->com == BM_CMD_READSTATUS)
{
LOG("Backup Memory Read Status: %02X\n", mc->writeable_buffer << 1);
return (mc->writeable_buffer << 1);
}
else /* finally, check if it's a new command */
{
switch(data)
{
case 0: break; /* nothing */
case BM_CMD_WRITELOW: /* write command */
if(mc->write_enable)
{
mc->addr = 0;
mc->addr_shift = mc->addr_size;
mc->com = BM_CMD_WRITELOW;
}
else { data = 0; }
break;
case BM_CMD_READLOW: /* read command */
mc->addr = 0;
mc->addr_shift = mc->addr_size;
mc->com = BM_CMD_READLOW;
break;
case BM_CMD_WRITEDISABLE: /* disable writing */
mc->write_enable = FALSE;
break;
case BM_CMD_READSTATUS: /* status register command */
mc->com = BM_CMD_READSTATUS;
break;
case BM_CMD_WRITEENABLE: /* enable writing */
if(mc->writeable_buffer) { mc->write_enable = TRUE; }
break;
case BM_CMD_WRITEHIGH: /* write command that's only available on ST M95040-W that I know of */
if(mc->write_enable)
{
mc->addr = 0x1;
mc->addr_shift = mc->addr_size;
mc->com = BM_CMD_WRITELOW;
}
else { data = 0; }
break;
case BM_CMD_READHIGH: /* read command that's only available on ST M95040-W that I know of */
mc->addr = 0x1;
mc->addr_shift = mc->addr_size;
mc->com = BM_CMD_READLOW;
break;
default:
LOG("Unhandled Backup Memory command: %02X\n", data);
break;
}
}
return data;
}

45
desmume/src/mc.h Normal file
View File

@ -0,0 +1,45 @@
#ifndef __FW_H__
#define __FW_H__
#ifdef __cplusplus
extern "C" {
#endif
#include "types.h"
#include "nds/serial.h"
#define MC_TYPE_EEPROM1 0x1
#define MC_TYPE_EEPROM2 0x2
#define MC_TYPE_FLASH 0x3
typedef struct
{
u8 com; /* persistent command actually handled */
u32 addr; /* current address for reading/writing */
u8 addr_shift; /* shift for address (since addresses are transfered by 3 bytes units) */
u8 addr_size; /* size of addr when writing/reading */
BOOL write_enable; /* is write enabled ? */
u8 *data; /* memory data */
u32 size; /* memory size */
BOOL writeable_buffer; /* is "data" writeable ? */
int type; /* type of Memory */
} memory_chip_t;
#define NDS_FW_SIZE_V1 (256 * 1024) /* size of fw memory on nds v1 */
#define NDS_FW_SIZE_V2 (512 * 1024) /* size of fw memory on nds v2 */
void mc_init(memory_chip_t *mc, int type); /* reset and init values for memory struct */
u8 *mc_alloc(memory_chip_t *mc, u32 size); /* alloc mc memory */
void mc_free(memory_chip_t *mc); /* delete mc memory */
void mc_reset_com(memory_chip_t *mc); /* reset communication with mc */
u8 fw_transfer(memory_chip_t *mc, u8 data); /* transfer to, then receive data from firmware */
u8 bm_transfer(memory_chip_t *mc, u8 data); /* transfer to, then receive data from backup memory */
#ifdef __cplusplus
}
#endif
#endif /*__FW_H__*/