Esempio n. 1
0
int WriteBlock(int port, int slot, unsigned short int PageSize, unsigned short int BlockSize, unsigned int block, void *buffer){
	unsigned char *ECC_data;
	unsigned int i, ECCBlockLen, ECCBlockSect;
	int result;

	ECCBlockLen=PageSize/32; /* Size calculated based on information extracted from Jimmikaelkael's MCMAN module */

	if((ECC_data=malloc(ECCBlockLen))!=NULL){
		memset(ECC_data, 0, ECCBlockLen);

		/* If someone can tell me how the EraseBlock function really works, that will be informative. The Sony MCSERV module calculates the checksum of the block to be written separately.
			So since EraseBlock probably doesn't calculate the checksums of the blocks... what does it really calculate?
		*/
		if((result=McEraseBlock(port, 0, block, NULL, NULL))>=0){
			for(i=0; i<BlockSize; i++){
				/* Manually calculate the ECC for each 128-byte block for each page of the block to be written. See the comment above for more details. */
				for(ECCBlockSect=0; ECCBlockSect<(PageSize/128); ECCBlockSect++) McDataChecksum(&((unsigned char *)buffer)[i*PageSize+ECCBlockSect*128], &ECC_data[ECCBlockSect*3]);

				if((result=McWritePage(port, slot, block*BlockSize+i, &((unsigned char *)buffer)[i*PageSize], ECC_data))!=sceMcResSucceed){
					break;
				}
			}
		}

		free(ECC_data);
	}
	else result=-ENOMEM;

	return result;
}
Esempio n. 2
0
//--------------------------------------------------------------
int _McWritePage(void *rpc_buf)
{
	g_descParam_t *dP = (g_descParam_t *)rpc_buf;
	register int fastsize, i, j;
	SifRpcReceiveData_t	rD;
	u8 eccbuf[16];

#ifdef DEBUG
	DPRINTF("mcserv: _McWritePage port%d slot%d page %d\n", dP->port, dP->slot, dP->fd);
#endif

	fastsize = ((u32)dP->buffer) & 0xf;
	if (fastsize == 0)
		goto fullpage;

	sceSifGetOtherData(&rD, (void *)(dP->buffer - (fastsize - 16)), &mcserv_buf, 496, 0);

	i = fastsize;
	while (i < 16) {
		mcserv_buf[i] = dP->data[i - fastsize];
		i++;
	}

	if (fastsize == 0)
		goto ecc_calc;


	j = 16;
	i = 0;
	while (i < fastsize) {
		mcserv_buf[496 + j] = dP->data[j - fastsize];
		i++;
		j++;
	}

	goto ecc_calc;

fullpage:

	sceSifGetOtherData(&rD, dP->buffer, &mcserv_buf, 512, 0);

ecc_calc:

	McDataChecksum((void *)(mcserv_buf + fastsize), &eccbuf[0]);
	McDataChecksum(&mcserv_buf[128], &eccbuf[3]);
	McDataChecksum(&mcserv_buf[256], &eccbuf[6]);
	McDataChecksum(&mcserv_buf[384], &eccbuf[9]);

	return McWritePage((dP->port & 1) | 2, dP->slot, dP->fd, (void *)(mcserv_buf + fastsize), eccbuf);
}
Esempio n. 3
0
//--------------------------------------------------------------
int _McEraseBlock(void *rpc_buf)
{
	g_descParam_t *dP = (g_descParam_t *)rpc_buf;
	register int pagenum, r;
	u8 eccbuf[16];

#ifdef DEBUG
	DPRINTF("mcserv: _McEraseBlock port%d slot%d offset %d\n", dP->port, dP->slot, dP->offset);
#endif

	dP->port = (dP->port & 1) + 2;

	if (McGetMcType(dP->port, dP->slot) == 2) {
		r = McEraseBlock(dP->port, dP->offset, NULL, NULL);
		if (r != 0)
			return r;

		if (dP->origin == -1)
			return r;

		memset(mcserv_buf, dP->origin, 512);

		McDataChecksum(&mcserv_buf[0], &eccbuf[0]);
		McDataChecksum(&mcserv_buf[128], &eccbuf[3]);
		McDataChecksum(&mcserv_buf[256], &eccbuf[6]);
		McDataChecksum(&mcserv_buf[384], &eccbuf[9]);

		pagenum = 0;

		do {
			r = McWritePage(dP->port, dP->slot, (dP->offset << 4) + pagenum, mcserv_buf, eccbuf);

		} while (++pagenum < 16);   // <-- and the last page of the block ???

		return r;

	}

	memset(mcserv_buf, dP->origin, 128);

	r = McWritePS1PDACard(dP->port, dP->slot, dP->offset, mcserv_buf);

	return r;
}