⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smf_lpt.c

📁 the test file for GP32 gameboy hack
💻 C
📖 第 1 页 / 共 4 页
字号:
	udword i, j, k;
	udword cnt;
	udword zone;
	udword total_blocks;
	udword p_num;
	udword l_offset;
	udword p_end;
	udword lba;
	udword parity;
	ubyte acLPTBuf[8];

	s_lptFlag[drv_no] = NOT_INITIALIZED;

	/*
	 * Device Info initial
	 */
	s_smlErr = smpFlashReadID(drv_no, acLPTBuf, 2);
	if (s_smlErr != SM_OK) 
		return s_smlErr;

	/* search manufacture code table */
	for (i = 0; i < MAX_MI_NUM; ++i) 
	{
		if (acLPTBuf[0] == g_mCode[i]) 
			break;
	}
	if (i >= MAX_MI_NUM) 
		return ERR_CARD_NOT_DETECTED;

	s_devID[drv_no].manufacture = i;

	/* search device code table */
	for (j = 0; j < MAX_DI_NUM; ++j) 
	{
		for (k = 0; k < MAX_VI_NUM; ++k) 
		{
			if (acLPTBuf[1] == g_dCode[i][j][k]) 
				break;
		}

		if (k < MAX_VI_NUM) 
			break;
	}

	if (j >= MAX_DI_NUM) 
		return ERR_CARD_NOT_DETECTED;

	s_devID[drv_no].device = j;

	total_blocks = s_devInfo[s_devID[drv_no].device].PBpV;

	/*
	 * s_pBlock[MAX_DRIVE] table initial
	 */
	if (s_pBlock[drv_no] != NULL) 
		SM_FREE(s_pBlock[drv_no]);

	s_pBlock[drv_no] = (uword*)SM_MALLOC(2 * total_blocks);
	if (s_pBlock[drv_no] == NULL) 
		return ERR_INTERNAL;

	for (i = 0; i < total_blocks; ++i) 
	{
		s_smlErr = smpFlashReadSpare(drv_no, i * (SECTOR_SIZE * s_devInfo[s_devID[drv_no].device].SpB),	acLPTBuf, 8);
		if (s_smlErr != SM_OK) 
		{
			SM_FREE(s_pBlock[drv_no]);
			s_pBlock[drv_no] = NULL;
			return (s_smlErr);
		}

		if (acLPTBuf[5] != 0xff) 
		{
			for (j = 0, cnt = 0; j < 8; ++j) 
			{
				if ((acLPTBuf[5] >> j) & 0x01) 
					++cnt;
			}

			if (cnt <= 6) 
			{
				SET_PB_TBL(drv_no, i, INVALID_PBLOCK);
				continue;
			}
		}

		SET_PB_TBL(drv_no, i, ((uword)acLPTBuf[6] << 8) | acLPTBuf[7]);
	}

	/*
	 * pLBlock[MAX_DRIVE] table initial
	 */
	if (s_lBlock[drv_no] != NULL) 
		SM_FREE(s_lBlock[drv_no]);

	s_lBlock[drv_no] = (uword*)SM_MALLOC(2 * total_blocks);
	if (s_lBlock[drv_no] == NULL) 
	{
		SM_FREE(s_pBlock[drv_no]);
		s_pBlock[drv_no] = NULL;
		return ERR_INTERNAL;
	}

	for (i = 0; i < total_blocks; ++i) 
	{
		SET_LB_TBL(drv_no, i, UNUSED_LBLOCK);
	}


	for (zone = 0; zone < total_blocks / P_ZONE_MAX + 1; ++zone) 
	{
		l_offset = zone * L_ZONE_MAX;

		if (total_blocks < P_ZONE_MAX * (zone + 1)) 
			p_end = total_blocks;
		else 
			p_end = P_ZONE_MAX * (zone + 1);

		for (p_num = zone * P_ZONE_MAX; p_num < p_end; ++p_num) 
		{
			if ((GET_PB_TBL(drv_no, p_num) == INVALID_PBLOCK) || (GET_PB_TBL(drv_no, p_num) == UNUSED_PBLOCK)
				|| (GET_PB_TBL(drv_no, p_num) == 0)) 		/* CIS Block is set to 0 */
			{
				continue;
			}

			lba = GET_PB_TBL(drv_no, p_num);

			/* parity check */
			parity = 0;
			for (i = 1; i < 16; ++i) 
			{
				parity ^= (lba >> i) & 0x01;
			}

			if ((lba & 0x01) != parity) 
				continue;

			lba = ((lba >> 1) & 0x3ff) + l_offset;
			if (lba >= total_blocks) 		/* invalid contents */
				continue;

			SET_LB_TBL(drv_no, lba, (uword)p_num);
		}
	}

	/* start of random zone */
	s_lBlockSearchStart[drv_no] = (SM_RANDOM() % s_devInfo[s_devID[drv_no].device].LBpV);
	s_lBlockSearchStart[drv_no] -= (s_lBlockSearchStart[drv_no] % L_ZONE_MAX);

	/* random index of random zone */
	s_pBlockSearchStart[drv_no] = (SM_RANDOM() % s_devInfo[s_devID[drv_no].device].PBpV);

	s_lptFlag[drv_no] = INITIALIZED;

	return SM_OK;
}


/**********
 * Function: sm_PreLPT
 * Remarks:
 *	- called at the first of LPT APIs
 **********/
ERR_CODE sm_PreLPT(udword drv_no) 
{
	if (s_lptFlag[drv_no] != INITIALIZED) 
	{
		s_smlErr = sm_LPTInit(drv_no);
		if (s_smlErr != SM_OK) 
			return s_smlErr;
	}

	return SM_OK;
}


/**********
 * Function: sm_PostLPT
 * Remarks:
 *	- called at the end of LPT APIs
 **********/
ERR_CODE sm_PostLPT(udword drv_no) 
{
	return SM_OK;
}


#if 0	/* sm_SearchFreeLBlock is now obsolete */
/**********
 * Function: sm_SearchFreeLBlock
 * Remark:
 *	- at start, checks one more time the index retunred last
 *		(this is for the case that the value is not used after return)
 **********/
ERR_CODE sm_SearchFreeLBlock(udword drv_no, udword* pLba) 
{
	udword i;

	for (i = 0; i < s_devInfo[s_devID[drv_no].device].LBpV; ++i) 
	{
		if (s_lBlockSearchStart[drv_no] >= s_devInfo[s_devID[drv_no].device].LBpV) 
		{
			s_lBlockSearchStart[drv_no] = 0;
		}

		if (GET_LB_TBL(drv_no, s_lBlockSearchStart[drv_no]) == UNUSED_LBLOCK) 
		{
			*pLba = s_lBlockSearchStart[drv_no];
			return SM_OK;
		}

		++s_lBlockSearchStart[drv_no];
	}

	return ERR_NO_EMPTY_BLOCK;
}
#endif


/**********
 * Function: sm_SearchFreePBlock
 * Remark:
 *	- at start, checks one more time the index retunred last
 *		(this is for the case that the value is not used after return)
 *	- if present udPBlockSearchStart[] is in the different zone from the lba zone,
 *		udPBlockSearchStart[] is set to random value in the same zone as lba's
 **********/
ERR_CODE sm_SearchFreePBlock(udword drv_no, udword lba, udword* pPba) 
{
	udword i;
	udword zone;
	udword count;
	udword min_block, max_block;
	udword start_backup;
	udword pba;

	if (lba >= s_devInfo[s_devID[drv_no].device].LBpV) 
		return ERR_INVALID_PARAM;

	/* if physical block for lba already exists, return it */
	pba = GET_LB_TBL(drv_no, lba);
	if (pba != UNUSED_LBLOCK) 
	{
		*pPba = pba;
		return SM_OK;
	}

	zone = lba / L_ZONE_MAX;

	/* locate MBR at first valid block for convenience */
	if (lba == 0) 
	{
		start_backup = s_pBlockSearchStart[drv_no];
		s_pBlockSearchStart[drv_no] = 3;
	}

	/* if udPBlockSearchStart[] is not in the same zone, this value is newly randomized in the same zone */
	if (s_pBlockSearchStart[drv_no] / P_ZONE_MAX != zone) 
	{
		if (s_devInfo[s_devID[drv_no].device].PBpV < P_ZONE_MAX) 
		{
			s_pBlockSearchStart[drv_no] = SM_RANDOM() % s_devInfo[s_devID[drv_no].device].PBpV;
		}
		else 
		{
			s_pBlockSearchStart[drv_no] = SM_RANDOM() % P_ZONE_MAX;
			s_pBlockSearchStart[drv_no] += (zone * P_ZONE_MAX);
		}
	}

	if (s_devInfo[s_devID[drv_no].device].PBpV < P_ZONE_MAX) 
	{
		count = s_devInfo[s_devID[drv_no].device].PBpV;
		min_block = 0;
		max_block = s_devInfo[s_devID[drv_no].device].PBpV - 1;
	}
	else 
	{
		count = P_ZONE_MAX;
		min_block = P_ZONE_MAX * zone;
		max_block = P_ZONE_MAX * (zone + 1) - 1;
	}

	for (i = 0; i < count; ++i) 
	{
		if (s_pBlockSearchStart[drv_no] > max_block) 
		{
			s_pBlockSearchStart[drv_no] = min_block;
		}

		if(GET_PB_TBL(drv_no, s_pBlockSearchStart[drv_no]) == UNUSED_PBLOCK) 
		{
			*pPba = s_pBlockSearchStart[drv_no];
			break;
		}

		++s_pBlockSearchStart[drv_no];
	}

	/* restore the old search_start block when lba is MBR block */
	if (lba == 0) 
	{
		s_pBlockSearchStart[drv_no] = start_backup;
	}

	if (i < count) 
		return SM_OK;

	return ERR_NO_EMPTY_BLOCK;
}


/**********
 * Function: sm_ECCEncode
 * Remark:
 *	- adopted from "ECC Algorithm for SmartMedia V3.0"
 *		by Memory Product & Technology, Samsung Electronics Co. (ecc30.pdf)
 **********/
ERR_CODE sm_ECCEncode(const ubyte* p_buf, ubyte* p_ecc) 
{
	udword i, j;
	ubyte paritr[256], tmp = 0, tmp2 = 0;
	ubyte data_table0[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 };
	ubyte data_table1[16] = { 1, 0, 0, 1, 0, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1 };
	ubyte sum = 0, paritc = 0;
	ubyte parit0c = 0, parit1c = 0, parit2c = 0, parit3c = 0;
	ubyte parit4c = 0, parit5c = 0, parit6c = 0, parit7c = 0;
	ubyte parit1_1, parit1_2, parit2_1, parit2_2, parit4_1, parit4_2;
	ubyte parit8_1 = 0, parit8_2 = 0, parit16_1 = 0, parit16_2 = 0, parit32_1 = 0, parit32_2 = 0;
	ubyte parit64_1 = 0, parit64_2 = 0, parit128_1 = 0, parit128_2 = 0, parit256_1 = 0, parit256_2 = 0;
	ubyte parit512_1 = 0, parit512_2 = 0, parit1024_1 = 0, parit1024_2 = 0;
	ubyte* paritr_ptr;

	paritr_ptr = paritr;
	for (i = 0; i < 256; ++i, ++paritr_ptr, ++p_buf) 
	{
		paritc ^= *p_buf;
		tmp = (*p_buf & 0xf0) >> 4;
		tmp2 = *p_buf & 0x0f;

		switch (tmp) 
		{
			case 0:
			case 3:
			case 5:
			case 6:
			case 9:
			case 10:
			case 12:
			case 15:
				*paritr_ptr = *(data_table0 + tmp2);
				break;

			case 1:
			case 2:
			case 4:
			case 7:
			case 8:
			case 11:
			case 13:
			case 14:
				*paritr_ptr = *(data_table1 + tmp2);
				break;
		}
	}

	parit0c = (paritc & 0x01) ? 1 : 0;
	parit1c = (paritc & 0x02) ? 1 : 0;
	parit2c = (paritc & 0x04) ? 1 : 0;
	parit3c = (paritc & 0x08) ? 1 : 0;
	parit4c = (paritc & 0x10) ? 1 : 0;
	parit5c = (paritc & 0x20) ? 1 : 0;
	parit6c = (paritc & 0x40) ? 1 : 0;
	parit7c = (paritc & 0x80) ? 1 : 0;
	parit1_2 = parit6c ^ parit4c ^ parit2c ^ parit0c;
	parit1_1 = parit7c ^ parit5c ^ parit3c ^ parit1c;
	parit2_2 = parit5c ^ parit4c ^ parit1c ^ parit0c;
	parit2_1 = parit7c ^ parit6c ^ parit3c ^ parit2c;
	parit4_2 = parit3c ^ parit2c ^ parit1c ^ parit0c;
	parit4_1 = parit7c ^ parit6c ^ parit5c ^ parit4c;

	paritr_ptr = paritr;
	for (i = 0; i < 256; ++i, ++paritr_ptr) 
	{
		sum ^= *paritr_ptr;
	}

	paritr_ptr = paritr;
	for (i = 0; i < 256; i += 2, paritr_ptr += 2) 
	{
		parit8_2 ^= *paritr_ptr;
	}

	paritr_ptr = paritr;
	for (i = 0; i < 256; i += 4, paritr_ptr += 4) 
	{
		parit16_2 ^= *paritr_ptr;
		parit16_2 ^= *(paritr_ptr + 1);
	}

	paritr_ptr = paritr;
	for (i = 0; i < 256; i += 8, paritr_ptr += 8) 
	{
		for (j = 0; j <= 3; ++j) 
		{
			parit32_2 ^= *(paritr_ptr + j);
		}
	}

	paritr_ptr = paritr;
	for (i = 0; i < 256; i += 16, paritr_ptr += 16) 
	{
		for (j = 0; j <= 7; ++j) 
		{
			parit64_2 ^= *(paritr_ptr + j);
		}
	}

	paritr_ptr = paritr;
	for (i = 0; i < 256; i += 32, paritr_ptr += 32) 
	{
		for (j = 0; j <= 15; ++j) 
		{
			parit128_2 ^= *(paritr_ptr + j);
		}
	}

	paritr_ptr = paritr;
	for (i = 0; i < 256; i += 64, paritr_ptr += 64) 
	{
		for (j = 0; j <= 31; ++j) 
		{
			parit256_2 ^= *(paritr_ptr + j);
		}
	}

	paritr_ptr = paritr;
	for (i = 0; i < 256; i += 128, paritr_ptr += 128) 
	{
		for (j = 0; j <= 63; ++j) 
		{
			parit512_2 ^= *(paritr_ptr + j);
		}
	}

	paritr_ptr = paritr;
	for (i = 0; i < 256; i += 256, paritr_ptr += 256) 
	{
		for (j = 0; j <= 127; ++j) 
		{
			parit1024_2 ^= *(paritr_ptr + j);
		}
	}

	if (sum==0) 
	{
		parit1024_1 = parit1024_2;
		parit512_1 = parit512_2;
		parit256_1 = parit256_2;
		parit128_1 = parit128_2;
		parit64_1 = parit64_2;
		parit32_1 = parit32_2;
		parit16_1 = parit16_2;
		parit8_1 = parit8_2;
	}
	else 
	{
		parit1024_1 = parit1024_2 ? 0 : 1;
		parit512_1 = parit512_2 ? 0 : 1;
		parit256_1 = parit256_2 ? 0 : 1;
		parit128_1 = parit128_2 ? 0 : 1;
		parit64_1 = parit64_2 ? 0 : 1;
		parit32_1 = parit32_2 ? 0 : 1;
		parit16_1 = parit16_2 ? 0 : 1;
		parit8_1 = parit8_2 ? 0 : 1;
	}

	parit1_2 <<= 2;
	parit1_1 <<= 3;
	parit2_2 <<= 4;
	parit2_1 <<= 5;
	parit4_2 <<= 6;
	parit4_1 <<= 7;
	parit128_1 <<= 1;
	parit256_2 <<= 2;
	parit256_1 <<= 3;
	parit512_2 <<= 4;
	parit512_1 <<= 5;
	parit1024_2 <<= 6;
	parit1024_1 <<= 7;
	parit8_1 <<= 1;
	parit16_2 <<= 2;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -