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

📄 smf_lpt.c

📁 the test file for GP32 gameboy hack
💻 C
📖 第 1 页 / 共 4 页
字号:
	parit16_1 <<= 3;
	parit32_2 <<= 4;
	parit32_1 <<= 5;
	parit64_2 <<= 6;
	parit64_1 <<= 7;

	p_ecc[0] = ~(parit64_1 | parit64_2 | parit32_1 | parit32_2 | parit16_1 | parit16_2 | parit8_1 | parit8_2);
	p_ecc[1] = ~(parit1024_1 |parit1024_2 | parit512_1 | parit512_2 | parit256_1 | parit256_2 | parit128_1 | parit128_2);
	p_ecc[2] = ~(parit4_1 | parit4_2 | parit2_1 | parit2_2 | parit1_1 | parit1_2);

	return SM_OK;
}


/**********
 * Function: sm_ECCCorrect
 * Remarks:
 *	- adopted from source code that was corrected by SeoGyu Kim, Infomedia Lab. SEC.
 **********/
ERR_CODE sm_ECCCorrect(const ubyte *p_data, const ubyte *ecc1, const ubyte *ecc2, ubyte *p_offset, ubyte *p_corrected) 
{
	int i;
	ubyte tmp0_bit[8],tmp1_bit[8],tmp2_bit[8], tmp0, tmp1, tmp2;
	ubyte comp0_bit[8],comp1_bit[8],comp2_bit[8];
	ubyte ecc_bit[22];
	ubyte ecc_gen[3];
	ubyte ecc_sum=0;
	ubyte ecc_value,find_byte,find_bit;

	tmp0 = ~ecc1[0];
	tmp1 = ~ecc1[1];
	tmp2 = ~ecc1[2];

	for (i = 0; i <= 2; ++i) 
	{
		ecc_gen[i] = ~ecc2[i];
	}

	tmp0_bit[0]= tmp0 & 0x01;
	tmp0 >>= 1;
	tmp0_bit[1]= tmp0 & 0x01;
	tmp0 >>= 1;
	tmp0_bit[2]= tmp0 & 0x01;
	tmp0 >>= 1;
	tmp0_bit[3]= tmp0 & 0x01;
	tmp0 >>= 1;
	tmp0_bit[4]= tmp0 & 0x01;
	tmp0 >>= 1;
	tmp0_bit[5]= tmp0 & 0x01;
	tmp0 >>= 1;
	tmp0_bit[6]= tmp0 & 0x01;
	tmp0 >>= 1;
	tmp0_bit[7]= tmp0 & 0x01;

	tmp1_bit[0]= tmp1 & 0x01;
	tmp1 >>= 1;
	tmp1_bit[1]= tmp1 & 0x01;
	tmp1 >>= 1;
	tmp1_bit[2]= tmp1 & 0x01;
	tmp1 >>= 1;
	tmp1_bit[3]= tmp1 & 0x01;
	tmp1 >>= 1;
	tmp1_bit[4]= tmp1 & 0x01;
	tmp1 >>= 1;
	tmp1_bit[5]= tmp1 & 0x01;
	tmp1 >>= 1;
	tmp1_bit[6]= tmp1 & 0x01;
	tmp1 >>= 1;
	tmp1_bit[7]= tmp1 & 0x01;

	tmp2_bit[0]= tmp2 & 0x01;
	tmp2 >>= 1;
	tmp2_bit[1]= tmp2 & 0x01;
	tmp2 >>= 1;
	tmp2_bit[2]= tmp2 & 0x01;
	tmp2 >>= 1;
	tmp2_bit[3]= tmp2 & 0x01;
	tmp2 >>= 1;
	tmp2_bit[4]= tmp2 & 0x01;
	tmp2 >>= 1;
	tmp2_bit[5]= tmp2 & 0x01;
	tmp2 >>= 1;
	tmp2_bit[6]= tmp2 & 0x01;
	tmp2 >>= 1;
	tmp2_bit[7]= tmp2 & 0x01;

	comp0_bit[0]= ecc_gen[0] & 0x01;
	ecc_gen[0] >>= 1;
	comp0_bit[1]= ecc_gen[0] & 0x01;
	ecc_gen[0] >>= 1;
	comp0_bit[2]= ecc_gen[0] & 0x01;
	ecc_gen[0] >>= 1;
	comp0_bit[3]= ecc_gen[0] & 0x01;
	ecc_gen[0] >>= 1;
	comp0_bit[4]= ecc_gen[0] & 0x01;
	ecc_gen[0] >>= 1;
	comp0_bit[5]= ecc_gen[0] & 0x01;
	ecc_gen[0] >>= 1;
	comp0_bit[6]= ecc_gen[0] & 0x01;
	ecc_gen[0] >>= 1;
	comp0_bit[7]= ecc_gen[0] & 0x01;

	comp1_bit[0]= ecc_gen[1] & 0x01;
	ecc_gen[1] >>= 1;
	comp1_bit[1]= ecc_gen[1] & 0x01;
	ecc_gen[1] >>= 1;
	comp1_bit[2]= ecc_gen[1] & 0x01;
	ecc_gen[1] >>= 1;
	comp1_bit[3]= ecc_gen[1] & 0x01;
	ecc_gen[1] >>= 1;
	comp1_bit[4]= ecc_gen[1] & 0x01;
	ecc_gen[1] >>= 1;
	comp1_bit[5]= ecc_gen[1] & 0x01;
	ecc_gen[1] >>= 1;
	comp1_bit[6]= ecc_gen[1] & 0x01;
	ecc_gen[1] >>= 1;
	comp1_bit[7]= ecc_gen[1] & 0x01;

	comp2_bit[0]= ecc_gen[2] & 0x01;
	ecc_gen[2] >>= 1;
	comp2_bit[1]= ecc_gen[2] & 0x01;
	ecc_gen[2] >>= 1;
	comp2_bit[2]= ecc_gen[2] & 0x01;
	ecc_gen[2] >>= 1;
	comp2_bit[3]= ecc_gen[2] & 0x01;
	ecc_gen[2] >>= 1;
	comp2_bit[4]= ecc_gen[2] & 0x01;
	ecc_gen[2] >>= 1;
	comp2_bit[5]= ecc_gen[2] & 0x01;
	ecc_gen[2] >>= 1;
	comp2_bit[6]= ecc_gen[2] & 0x01;
	ecc_gen[2] >>= 1;
	comp2_bit[7]= ecc_gen[2] & 0x01;

	for (i = 0; i <= 5; ++i) 
	{
		ecc_bit[i] = tmp2_bit[i + 2] ^ comp2_bit[i + 2];
	}

	for (i = 0; i <= 7; ++i) 
	{
		ecc_bit[i + 6] = tmp0_bit[i] ^ comp0_bit[i];
	}

	for (i = 0; i <= 7; ++i) 
	{
		ecc_bit[i + 14] = tmp1_bit[i] ^ comp1_bit[i];
	}

	for (i = 0; i <= 21; ++i) 
	{
		ecc_sum += ecc_bit[i];
	}

	if (ecc_sum == 11) 
	{
		find_byte = (ecc_bit[21] << 7) + (ecc_bit[19] << 6) + (ecc_bit[17] << 5) + (ecc_bit[15] << 4) + (ecc_bit[13] << 3) + (ecc_bit[11] << 2) + (ecc_bit[9] << 1) + ecc_bit[7];
		find_bit = (ecc_bit[5] << 2) + (ecc_bit[3] << 1) + ecc_bit[1];
		ecc_value = (p_data[find_byte] >> find_bit) & 0x01;
		if (ecc_value == 0) 
			ecc_value = 1;
		else 
			ecc_value = 0;

		*p_offset = find_byte;
		*p_corrected = p_data[find_byte];

		tmp0_bit[0] = *p_corrected & 0x01;
		*p_corrected >>= 1;
		tmp0_bit[1] = *p_corrected & 0x01;
		*p_corrected >>= 1;
		tmp0_bit[2] = *p_corrected & 0x01;
		*p_corrected >>= 1;
		tmp0_bit[3] = *p_corrected & 0x01;
		*p_corrected >>= 1;
		tmp0_bit[4] = *p_corrected & 0x01;
		*p_corrected >>= 1;
		tmp0_bit[5] = *p_corrected & 0x01;
		*p_corrected >>= 1;
		tmp0_bit[6] = *p_corrected & 0x01;
		*p_corrected >>= 1;
		tmp0_bit[7] = *p_corrected & 0x01;

		tmp0_bit[find_bit] = ecc_value;

		*p_corrected = (tmp0_bit[7] << 7) + (tmp0_bit[6] << 6) + (tmp0_bit[5] << 5) + (tmp0_bit[4] << 4) + (tmp0_bit[3] << 3) + (tmp0_bit[2] << 2) + (tmp0_bit[1] << 1) + tmp0_bit[0];

		return ERR_ECC_CORRECTABLE;
	}
	else if ((ecc_sum == 0) || (ecc_sum == 1)) 
	{
		return SM_OK;
	}
	else 
	{
		return ERR_ECC;
	}

	return SM_OK;
}


/**********
 * Function: sm_ECCDecode
 * Remarks:
 *	- 1 bit error correction is implemented
 **********/
ERR_CODE sm_ECCDecode(const ubyte* p_buf, const ubyte* p_ecc) 
{
	ubyte ecc_data[3];
	ubyte offset;
	ubyte corrected;
	udword ret_val;

	sm_ECCEncode(p_buf, ecc_data);

	if ((p_ecc[0] != ecc_data[0]) || (p_ecc[1] != ecc_data[1]) || (p_ecc[2] != ecc_data[2])) 
	{
		ret_val = sm_ECCCorrect(p_buf, p_ecc, ecc_data, &offset, &corrected);
		if (ret_val == ERR_ECC_CORRECTABLE) 
		{
			*((ubyte*)p_buf + offset) = corrected;
		}
		else if (ret_val == ERR_ECC) 
			return ERR_ECC;
	}

	return SM_OK;
}


/**********
 * Function: sm_ReadBlock
 * Remarks:
 *	- read data within 1 block
 *	- cannot read beyond the block boundary
 *	- if there is an ECC error, p_buf is filled with flash data as in the normal case, but return value is ERR_ECC
 **********/
ERR_CODE sm_ReadBlock(udword drv_no, udword lblock_no, udword offset, void* p_buf, udword read_size) 
{
	udword pba;

	pba = GET_LB_TBL(drv_no, lblock_no);
	return sm_ReadPhysBlock(drv_no, pba, offset, p_buf, read_size);
}

/**********
 * Function: sm_ReadPhysBlock
 * Remarks:
 *	- read data within 1 block
 *	- cannot read beyond the block boundary
 *	- if there is an ECC error, p_buf is filled with flash data as in the normal case, but return value is ERR_ECC
 **********/
ERR_CODE sm_ReadPhysBlock(udword drv_no, udword pba, udword offset, void* p_buf, udword read_size) 
{
	udword i;
	udword addr;
	udword page_size;
#ifndef ECC_DECODE_DISABLE
	ubyte spare[16];
	bool b_ecc_error = FALSE;
#endif
	udword first_read_size = 0;
	udword last_read_size = 0;
	udword temp_read_size;

	/*
	 * check if the (offset + read_size) is beyond the block boundary
	 * if(offset + read_size > SECTOR_SIZE * conDevInfo[sDevID[drv_no].device].SpB)
	 * return ERR_INVALID_PARAM;
	 */

	if ((pba >= s_devInfo[s_devID[drv_no].device].PBpV) || (pba == UNUSED_LBLOCK)) 
	{
		return ERR_INVALID_BLOCK;
	}

	addr = pba * SECTOR_SIZE * s_devInfo[s_devID[drv_no].device].SpB + offset;
	page_size = s_devInfo[s_devID[drv_no].device].szP;

	/* read head side until the first sector boundary or until the read_size */
	if (offset & (SECTOR_SIZE - 1)) 	/* <= (offset % SECTOR_SIZE) */
	{
		first_read_size = SECTOR_SIZE - (offset & (SECTOR_SIZE - 1));	/* <= (offset % SECTOR_SIZE); */

		/* check if the first_read_size is beyond read_size */
		if (first_read_size > read_size) 
		{
			first_read_size = read_size;
		}

		if (page_size == 256) 
		{
			/* check if the start & end are on the different pages */
			if ((offset / 256) != ((offset + first_read_size) / 256)) 
			{
				temp_read_size = first_read_size - ((offset + first_read_size) % 256);

				s_smlErr = smpFlashReadPage(drv_no, addr, (ubyte*)p_buf, temp_read_size);
				if (s_smlErr != SM_OK) 
					return s_smlErr;

				s_smlErr = smpFlashReadPage(drv_no, addr + temp_read_size, (ubyte*)p_buf + temp_read_size, first_read_size - temp_read_size);
				if (s_smlErr != SM_OK) 
					return s_smlErr;
			}
			else 
			{
				s_smlErr = smpFlashReadPage(drv_no, addr, (ubyte*)p_buf, first_read_size);
				if (s_smlErr != SM_OK) 
					return s_smlErr;
			}
		}
		else if (page_size == 512) 
		{
			if ((offset & (SECTOR_SIZE - 1)) < 256) 	/* <= ((offset % SECTOR_SIZE) < 256) */
			{
				s_smlErr = smpFlashReadPage(drv_no, addr, (ubyte*)p_buf, first_read_size);
				if (s_smlErr != SM_OK) 
					return s_smlErr;
			}
			else 
			{
				s_smlErr = smpFlashReadPage2(drv_no, addr, (ubyte*)p_buf, first_read_size);
				if (s_smlErr != SM_OK) 
					return s_smlErr;
			}
		}

		addr += first_read_size;
		p_buf = (ubyte*)p_buf + first_read_size;
		read_size -= first_read_size;
	}

	/* read tail side from the last sector boundary */
	if (read_size & (SECTOR_SIZE - 1)) 	/* <= (read_size % SECTOR_SIZE) */
	{
		last_read_size = read_size & (SECTOR_SIZE - 1);	/* <= read_size % SECTOR_SIZE; */
		if (page_size == 256) 
		{
			if (last_read_size < 256) 
			{
				s_smlErr = smpFlashReadPage(drv_no, addr + read_size - last_read_size, (ubyte*)p_buf + read_size - last_read_size, last_read_size);
				if (s_smlErr != SM_OK) 
					return s_smlErr;
			}
			else 
			{
				s_smlErr = smpFlashReadPage(drv_no, addr + read_size - last_read_size, (ubyte*)p_buf + read_size - last_read_size, 256);
				if (s_smlErr != SM_OK) 
					return s_smlErr;

				s_smlErr = smpFlashReadPage(drv_no, addr + read_size - last_read_size + 256, (ubyte*)p_buf + read_size - last_read_size + 256, last_read_size - 256);
				if (s_smlErr != SM_OK) 
					return s_smlErr;
			}
		}
		else if (page_size == 512) 
		{
			s_smlErr = smpFlashReadPage(drv_no, addr + read_size - last_read_size, (ubyte*)p_buf + read_size - last_read_size, last_read_size);
			if (s_smlErr != SM_OK) 
				return s_smlErr;
		}

		read_size -= last_read_size;
	}

	/*
	 * now, offset and (offset + read_size) is on the sector boundary.
	 *  (if not, there was an error in the upper processing)
	 */
	if (read_size > 0) 
	{
		for (i = 0; i < read_size; i += SECTOR_SIZE, addr += SECTOR_SIZE, p_buf = (ubyte*)p_buf + SECTOR_SIZE) 
		{
			if (page_size == 256) 
			{
				s_smlErr = smpFlashReadPage(drv_no, addr, (ubyte*)p_buf, 256);
				if (s_smlErr != SM_OK) 
					return s_smlErr;

				s_smlErr = smpFlashReadPage(drv_no, addr + 256, (ubyte*)p_buf + 256, 256);
				if (s_smlErr != SM_OK) 
					return s_smlErr;

#ifndef ECC_DECODE_DISABLE
				s_smlErr = smpFlashReadSpare(drv_no, addr + 256, spare, 8);
				if (s_smlErr != SM_OK) 
					return s_smlErr;

				if (sm_ECCDecode((const ubyte*)p_buf, spare + 5) != SM_OK) 
					b_ecc_error = TRUE;

				if (sm_ECCDecode((ubyte*)p_buf + 256, spare) != SM_OK) 
					b_ecc_error = TRUE;
#endif
			}
			else if(page_size == 512) 
			{
				s_smlErr = smpFlashReadPage(drv_no, addr, (ubyte*)p_buf, 512);
				if (s_smlErr != SM_OK) 
					return s_smlErr;

#ifndef ECC_DECODE_DISABLE
				s_smlErr = smpFlashReadSpare(drv_no, addr, spare, 16);
				if (s_smlErr != SM_OK) 
					return s_smlErr;

				if (sm_ECCDecode((const ubyte*)p_buf, spare + 13) != SM_OK) 
					b_ecc_error = TRUE;

				if (sm_ECCDecode((const ubyte*)p_buf + 256, spare + 8) != SM_OK) 
					b_ecc_error = TRUE;
#endif
			}
		}
	}

#ifndef ECC_DECODE_DISABLE
	if (b_ecc_error) 
		return ERR_ECC;
#endif

	return SM_OK;
}

/**********
 * Function: sm_WriteCISBlock
 * Remarks:
 *	- write CIS data to the defined physical block
 **********/
ERR_CODE sm_WriteCISBlock(udword drv_no, udword pblock_no) 
{
	udword sector;
	udword page_size;
	ubyte spare[16];
	ubyte* acLPTBuf = SMB_ALLOC_BUF();

	if (!acLPTBuf) 
		return ERR_OUT_OF_MEMORY;

	sector = pblock_no * s_devInfo[s_devID[drv_no].device].SpB;
	page_size = s_devInfo[s_devID[drv_no].device].szP;

	SM_MEMSET(spare, 0xff, 16);
	spare[5] = 0xff;
	spare[6] = spare[7] = spare[11] = spare[12] = 0;

	/* first sector */
	SM_MEMSET(acLPTBuf, 0, SECTOR_SIZE);
	SM_MEMCPY(acLPTBuf, s_cis, sizeof(s_cis));

#ifndef ECC_ENCODE_DISABLE
	sm_ECCEncode(acLPTBuf, spare + 13);
	sm_ECCEncode(acLPTBuf + 256, spare + 8);
#endif

	s_smlErr = smpFlashWriteSector(drv_no, sector, acLPTBuf, spare);
	if (s_smlErr != SM_OK) 
	{
		SMB_FREE_BUF(acLPTBuf);
		LPT_RETURN(drv_no, s_smlErr);
	}

	SMB_FREE_BUF(acLPTBuf);
	LPT_RETURN(drv_no, SM_OK);
}


/**********
 * Function: sm_MakeBAA
 * Remarks:
 *	- get the value that should be saved to SmartMedia from the logical block number
 **********/
uword sm_MakeBAA(udword lblock_no) 
{
	udword converted_lba;
	udword parity;
	udword i;

	converted_lba = lblock_no % L_ZONE_MAX;
	parity = 1;
	for (i = 0; i < 10; ++i) 
	{
		parity ^= (converted_lba >> i) & 0x01;
	}
	converted_lba = 0x1000 | (converted_lba << 1) | parity;

	return (uword)converted_lba;
}

⌨️ 快捷键说明

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