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

📄 2k_mass.c

📁 HID-Ukey底层源码实现(st72651芯片) windows上层驱动
💻 C
📖 第 1 页 / 共 3 页
字号:
/****************** (c) 1999  STMicroelectronics *****************************

PROJECT : USB - ST7

VERSION : SMC_Mass.c	1.0 Beta2

CREATION DATE :

AUTHOR : CMG / ST Rousset

-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

REM: 

-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-

MODIFICATIONS :

******************************************************************************/
#include "Map_7265.h"
#include "MAL_Map.h"
#include "MAL_2K.h"
#include "DTC_Func.h"
#include "2K_DTC.h"
#include "2K_Mass.h"
#include "MAL.h"
#include "Mconfig.h"

#pragma DATA_SEG SHORT MAL_RAM0
extern unsigned char DTC_Code_Number;
#ifdef debug
static unsigned char counter; //for debug
#endif
//#define Bytes2K_PAGE


#pragma DATA_SEG DEFAULT_RAM 
#ifdef debug
static unsigned int Error_Laddr[40]; //for debug of corruption
static unsigned char Error_Page[40]; 
static unsigned char Error_offset[40];
#endif

#pragma CODE_SEG SMC_CODE
#define ID_CYCLES 5

//#define Copy_malPaddr()	{ *((unsigned long*)&Buffer_Param[SMC_RespFrame_AddrBeg]) = malPaddr; }
void Copy_malPaddr()
{
	*((unsigned long*)&Buffer_Param[SMC_RespFrame_AddrBeg]) = malPaddr;
}

/*-*-*-*-*-*-*-* Calculate the parity bit of the address -*-*-*-*-*-*-*-*-*-*/
#pragma NO_ENTRY
static unsigned int DTC_SMC_Addr_Parity(unsigned int Addr)
{
#if	0
	unsigned int tAddr;
	// Calculate the parity bit
	tAddr = (Addr << 1) | 0x1000 | 0x01;
	do {
		if (Addr & 0x01)
			tAddr ^= 1;
		Addr >>= 1;
	} while (Addr);

	return tAddr;
#endif

	// Calculate the parity bit
	asm {
		LD		Y, A
		SCF					// OR 0x01
		RLC		A
		RLC		X
		LD		Addr, A		// Lobyte of tAddr
		LD		A, X
		OR		A, #0x10
		PUSH	A			// Hibyte of tAddr
		RRC		X			// Shift back the hi-byte of Addr
	}
	asm {
		LD		A, Addr		// Lobyte of tAddr
Parity_Loop:
		SRL		X			// Hibyte of Addr
		RRC		Y			// Lobyte of Addr
		JRNC	Parity_Next
		XOR		A, #0x01
Parity_Next:
		TNZ		Y
		JRNE	Parity_Loop
		TNZ		X
		JRNE	Parity_Loop

		POP		X			// Hibyte of result
	}
}

/*-----------------------------------------------------------------------------
ROUTINE NAME : DTC_SMC_Send_Cmd
INPUT/OUTPUT : Buffer_Param[0x20] contains the command to be sent
DESCRIPTION  : Send the specified command to the SMC
-----------------------------------------------------------------------------*/
void DTC_SMC_Send_Cmd(void)
{
	if (DTC_Code_Number != CODE_DTC_PLAY) {
//		DTC_Load_Code(SMC_DTC_Play);
		DTC_Load_Code(SMC_DTC_Play256);//for 256 MB
		DTC_Code_Number = CODE_DTC_PLAY;
	}

	No_DTC_Int();
	DTC_Process(SMC_DTC_Play_Send_Cmd);
	DTC_Wait_Stop();
}

/*-----------------------------------------------------------------------------
ROUTINE NAME : SMC_USB
INPUT/OUTPUT :
DESCRIPTION  : None
-----------------------------------------------------------------------------*/
void DTC_SMC_Init()
{
	if (DTC_Code_Number != CODE_DTC_CODE0) {
		DTC_Load_Code(SMC_DTC_Code0);
		DTC_Code_Number = CODE_DTC_CODE0;
	}

	No_DTC_Int();
	DTC_Process(SMC_DTC_Code_Init_SMC_Mode);
	DTC_Wait_Stop();

	Buffer_Param[0x20] = Reset;
	DTC_SMC_Send_Cmd();
}

/*-----------------------------------------------------------------------------
ROUTINE NAME : SMC_Send_Addr
INPUT/OUTPUT : Buffer_Param[0x22-0x25] contains the address to be sent
               Buffer_Param[0x26] a byte indicates number of address bytes
DESCRIPTION  : Send the specified address to the SMC
-----------------------------------------------------------------------------*/
void SMC_Send_Addr(void)
{
	No_DTC_Int();
	DTC_Process(SMC_DTC_Play_Send_Addr);
	DTC_Wait_Stop();
}

/*-----------------------------------------------------------------------------
ROUTINE NAME : SMC_Read_Status
INPUT/OUTPUT :
DESCRIPTION  : Read the status byte and return it
-----------------------------------------------------------------------------*/
unsigned char SMC_Read_Status(void)
{
	Buffer_Param[0x20] = Read_Status;
	DTC_SMC_Send_Cmd();

	DTC_Process(SMC_DTC_Play_Read_Status);
	DTC_Wait_Stop();

	return Buffer_Param[0x3E];
}

/*-----------------------------------------------------------------------------
ROUTINE NAME : Read_SMC_ID
INPUT/OUTPUT : None
DESCRIPTION  : None
-----------------------------------------------------------------------------*/
unsigned char DTC_SMC_ReadID(void)
{
	Buffer_Param[0x3C] = ID_CYCLES;
	Buffer_Param[0x20] = ID_Read;
	DTC_SMC_Send_Cmd();

	No_DTC_Int();
	DTC_Process(SMC_DTC_Play_Read_ID);
	DTC_Wait_Stop();

	return Buffer_Param[0x31];
}

/*--------------------------------------------------------------------------------------------------------------------
Routine : DTC_SMC_Map_Zone
Input   :	malPaddr = the first page of the zone
			malNpage = pages of one cluster
			malRaddr = number of clusters in the zone
Output  : void
Description 
---------------------------------------------------------------------------------------------------------------------*/
#define	CONVERT_ASM	1
//#define	CONVERT_ASM 0
#pragma NO_ENTRY
void DTC_SMC_Map_Zone(unsigned short *SMC_Lookup_Table)
{
	unsigned short *pScan, *pLookup, *pBad, item;

#if	CONVERT_ASM
	unsigned char loop;
#else
	unsigned short	value;
#endif
/******For 256MB**********/  

	asm {	// Since this function is almost assembly code, the compiler optimized this code
			// This is the entry code, I have to make it myself

		LD		SMC_Lookup_Table:1, A
		LD		SMC_Lookup_Table, X
	}

	if (DTC_Code_Number != CODE_MAP_ZONE) {
//		DTC_Load_Code(SMC_DTC_Map_Zone);
		DTC_Load_Code(SMC_DTC_Map_Zone256); //For 256MB
		DTC_Code_Number = CODE_MAP_ZONE;
	}

	Buffer_Param[0x3F] = malNpage;
	Buffer_Param[0x25]= 0x00;//First Add byte
	Copy_malPaddr();

	No_DTC_Int();
	DTC_Process(0);		// Collect mapping information for the 1st half of the zone
#if	CONVERT_ASM
	asm {
		CLR		X
		LD		Y, #8
mark_as_free:
		LD		A, #0x40
		LD		([SMC_Lookup_Table.W],X), A
		INC		X
		CLR		A
		LD		([SMC_Lookup_Table.W],X), A
		INC		X
		JRNE	mark_as_free
		INC		SMC_Lookup_Table
		DEC		Y
		JRNE	mark_as_free
		LD		A, SMC_Lookup_Table
		SUB		A, #8
		LD		SMC_Lookup_Table, A
	}
#else
	for (item = 1023; item >= 0; item--)
		SMC_Lookup_Table[item] = 0x4000;	// mark all as free
#endif

	DTC_Wait_Stop();

#if	CONVERT_ASM
	asm {
		CLR		item:1
		CLR		item
		LD		A, SMC_Lookup_Table:1
		LD		pLookup:1, A
		ADD		A, #0xFE			// point to end of the word array
		LD		pBad:1, A
		LD		A, SMC_Lookup_Table
		LD		pLookup, A
		ADC		A, #0x07			// point to end of the word array
		LD		pBad, A
		LD		A, #Buffer_0
		LD		pScan:1, A
		LD		A, #HIGH(Buffer_0)
		LD		pScan, A
		CALLR	convert_table
	}
#else
	item = 0;
	pBad = SMC_Lookup_Table + 1023;
	pScan = (unsigned short *)Buffer_0;
	pLookup = SMC_Lookup_Table;
	for (item = 0; item < 512; item++) {

		value = *pScan >> 1;
		if (value != 0x7FFF) {
			*pLookup &= ~0x4000;			// mark as not free
			if (value == 0x0800)
				*pBad-- |= item | 0xA000;	// mark as bad
			else {
	// debug	if (SMC_Lookup_Table[value] != 0x4000)
	// debug		asm nop;
				SMC_Lookup_Table[value] |= item | 0x8000;	// mapping
			//	item_good++;
			}
		}
	//	else
	//		item_free++;
		pScan++;
		pLookup++;
	}
#endif

	// Second half of the table
	if ((unsigned short)malRaddr == 512)
		goto scan_free_clusters;

	DTC_Process(0);
	DTC_Wait_Stop();		// Collect mapping informat for the 2nd half of the zone

#if	CONVERT_ASM
	asm {
		LD		A, #Buffer_0
		LD		pScan:1, A
		LD		A, #HIGH(Buffer_0)
		LD		pScan, A
		CALLR	convert_table
		JRA		map_free_cluster

convert_table:
		CLR		X
		LD		A, #4
		LD		loop, A
convert_table0:
		LD		A, ([pScan.w],X)		// load high byte of the Scan
		LD		Y, A					// save it in Y
		INC		X
		LD		A, ([pScan.w],X)		// load low byte of the Scan
		CP		Y, #0xFF
		JRNE	check_bad				
		CP		A, #0xFE
		JREQ	next_cluster			// this is a free cluster
check_bad:
		CP		Y, #0x10
		JRNE	map_cluster
		TNZ		A
		JREQ	bad_cluster
map_cluster:
		PUSH	X
		PUSH	A						// low byte of value
		LD		X, SMC_Lookup_Table		// save it
		LD		A, Y
		ADD		A, SMC_Lookup_Table
		LD		SMC_Lookup_Table, A
		POP		Y
		LD		A, ([SMC_Lookup_Table.W],Y)	// SMC_Lookup_Table[value] |= item | 0x8000
		OR		A, item
		OR		A, #0x80
		LD		([SMC_Lookup_Table.W],Y), A	// high byte of above result
		INC		Y
		LD		A, item:1
		LD		([SMC_Lookup_Table.W],Y), A	// low byte of above result
		LD		SMC_Lookup_Table, X			// restore the variable of SMC_Lookup_Table
		POP		X
		JRA		not_free_cluster
bad_cluster:
		LD		Y, #1
		LD		A, item:1
		LD		([pBad.W],Y), A		// low byte
		LD		A, [pBad.W]
		OR		A, item
		OR		A, #0xA0
		LD		[pBad.W], A			// high byte
		LD		A, pBad:1
		SUB		A, #0x02
		LD		pBad:1, A
		LD		A, pBad
		SBC		A, #0
		LD		pBad, A
not_free_cluster:
		DEC		X
		LD		A, ([pLookup.W],X)
		AND		A, #0xBF
		LD		([pLookup.W],X), A
		INC		X
next_cluster:
		INC		item:1
		JRNE	next_cluster0
		INC		item
next_cluster0:
		INC		X
		JRNE	convert_table0
		INC		pScan
		INC		pLookup
		DEC		loop
		JRNE	convert_table0
convert_end:
		RET

map_free_cluster:
		NOP
	}
#else
	pScan = (unsigned short *)Buffer_0;
	for (item = 512; item < 1024; item++) {
		value = *pScan >> 1;
		if (value != 0x7FFF) {
			*pLookup &= ~0x4000;			// mark as not free
			if (value == 0x0800)
				*pBad-- |= item | 0xA000;	// mark as bad
			else {
	// debug	if (SMC_Lookup_Table[value] != 0x4000)
	// debug		asm nop;
				SMC_Lookup_Table[value] |= item | 0x8000;	// mapping
			//	item_good++;
			}
		}
	//	else
	//		item_free++;
		pScan++;
		pLookup++;
	}
#endif

scan_free_clusters:
#if	CONVERT_ASM
	asm {
		LD		A, SMC_Lookup_Table:1
		LD		pScan:1, A
		LD		pLookup:1, A
		LD		pBad:1, A
		LD		A, SMC_Lookup_Table
		LD		pScan, A
		LD		pLookup, A
		ADD		A, #0x08			// point to end of the word array
		LD		pBad, A
	}

//	loop = ((unsigned short)malRaddr == 512) ? 4 : 8;
	asm {
		LD		X, #8
		LD		A, malRaddr
		CP		A, #2
		JRNE	loop_8
		LD		A, malRaddr:1
		JRNE	loop_8
	// For 4MB card only
		LD		A, pLookup
		ADD		A, #4
		LD		pBad, A
		LD		X, #4
loop_8:
		LD		loop, X
	}
	asm {
		CLR		X
		CLR		Y
scan_free_cluster:
		LD		A, ([pScan.W], X)
		BCP		A, #0x80
		JRNE	scan_next_free0
search_free:
		LD		A, ([pLookup.W], Y)
		BCP		A, #0x40
		JRNE	found_free
		INC		Y
		INC		Y
		JRNE	search_free
		INC		pLookup
		LD		A, pLookup
		CP		A, pBad
		JRNE	search_free
		RET					// no more free cluster
							// some logical cluster got 2 or more physical location
found_free:
		AND		A, #0xBF
		LD		([pLookup.W], Y), A	// map it, clear the free flag
		LD		A, pLookup
		SUB		A, SMC_Lookup_Table
		SRL		A
		OR		A, #0x0C			// 0x0c is the mark of free cluster
		OR		A, ([pScan.W], X)	// keep the free marking if there is one
		LD		([pScan.W], X), A
		LD		A, Y
		RRC		A
		INC		X
		LD		([pScan.W], X), A	// *pScan = 0xC00 | (pLookup - SMC_Lookup_Table);
		JRA		scan_next_free
scan_next_free0:
		INC		X
scan_next_free:
		INC		X
		JRNE	scan_free_cluster
		INC		pScan
		DEC		loop
		JRNE	scan_free_cluster
	}
#else
	pScan = SMC_Lookup_Table;
	pLookup = SMC_Lookup_Table;
	pBad = SMC_Lookup_Table + 1024;	// guard the pLookup
	for (item = 0; item < (unsigned short)malRaddr; item++, pScan++) {
		if (*pScan & 0x8000)
			continue;		// a mapped cluster
		while ((*pLookup & 0x4000) == 0) {
			pLookup++;
			if (pLookup >= pBad)
				goto Map_Zone_END;
		}
		*pScan = 0xC00 | (pLookup - SMC_Lookup_Table);
		*pLookup &= ~0x4000;
	}
Map_Zone_END:	;
#endif

/*
	if (DTC_Code_Number != CODE_DTC_PLAY) {
		DTC_Load_Code(SMC_DTC_Play);
		DTC_Code_Number = CODE_DTC_PLAY;
	}

	DTC_SMC_Command = 0x01;	// read spare area
	for (Sectors = malRaddr; Sectors; Sectors--) {   
	//	CopyStartAddr(malPaddr);
		Copy_malPaddr();
		
		No_DTC_Int();
		DTC_Process(SMC_DTC_Read_Data_4Addr);
		DTC_Wait_Stop();
		
		if ( (Spare_Area.Block_Status_Byte == 0xFF)	&& (Spare_Area.Data_Status_Byte == 0xFF)
					&& (Spare_Area.Block_Address_Field_1 == Spare_Area.Block_Address_Field_2)) {
			if (Spare_Area.Block_Address_Field_1 == 0xFFFF)
				*SMC_Lookup_Table = 0x73FF;
			else {
				if ((Spare_Area.Block_Address_Field_1 & 0x1000) == 0x0000)
					*SMC_Lookup_Table = 0x800;
				else {
					#define	Logical_Block ((Spare_Area.Block_Address_Field_1 >> 1) & 0x03FF)
					*SMC_Lookup_Table = Logical_Block | 0x4000;
				}
			}
		}
		else
			*SMC_Lookup_Table = 0x800;

		SMC_Lookup_Table++;
		malPaddr += (unsigned long)malNpage;
	}
*/
}

/*----------------------------------------------------------------------------------------------------------------
Routine : DTC_Read_FF
Input   :
Output  : void
Description 
-----------------------------------------------------------------------------------------------------------------*/
unsigned char DTC_Read_FF(void)
{
	if (DTC_Code_Number != CODE_READ_USB) {
		DTC_Load_Code(SMC_DTC_USB_Mass_Upld);
		DTC_Code_Number = CODE_READ_USB;
	}

	Buffer_Param[0x3F] = malNpage;	// Nb of Sectors processed
	
	Enable_DTC_Int();
	DTC_Process(SMC_DTC_USB_Upload_FF);
	return 0x00;
}

/*---------------------------------------------------------------------------
Routine : DTC_SMC_Read_USB
Input   :
Output  : void
Description 

⌨️ 快捷键说明

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