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

📄 rbc.c

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

PROJECT : USB - ST7 FULL SPEED

VERSION :  v 0.96

CREATION DATE :  01/12/2000

AUTHOR : MICROCONTROLLER DIVISION / ST Rousset

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

MODIFICATIONS : 

******************************************************************************/


#include "CondComp.h"
#include "hidef.h"
#include "lib_bits.h"
#include "define.h"
#include MAP_FILE
#include "MConfig.h"
#include "MSL.h"
#include "MAL.h"
#include "RBC.h"
#include "SenseDat.h"
#include "Descript.h"

// RBC Extention Major version
#define RBC_EXT_MAJ		0x10
// RBC Extention Minor version
#define RBC_EXT_MIN		0x11

#pragma DATA_SEG SHORT CLASS_RAM0
unsigned char Sense_Head;
unsigned char Sense_Tail;
unsigned char MSL_Param_Size;

#pragma DATA_SEG CLASS_RAM
static unsigned char Current_Operation;
static tRBC_CMD	sRBC_CMD;
//static unsigned char	FormatProgress;
//static unsigned int		NextProgress;
static unsigned int Format_Blk_Done;

#define SENSE_LIST_DEEPTH 4
typedef struct _SENSE_ITEM {                
	char Skey;
	union {
		struct _ASCs {
			char ASC;
			char ASCQ;
		}b;
		unsigned short	ASC;
		char *pData;
	} w;
} SENSE_ITEM;                         
SENSE_ITEM Sense_List[SENSE_LIST_DEEPTH];

unsigned char MSL_Param_Buffer[SIZ_MSL_PARAM];
// PFD variable
#pragma DATA_SEG DEFAULT_RAM
unsigned char Current_Mode = 0;
unsigned char Flash_State = 0;
unsigned char Windows_2000 = 0;
unsigned long Private_Zone_Size = 0;
unsigned char Slot_Description[34];
unsigned char PassWord[34];
unsigned char Serial_Number[66];

#pragma CODE_SEG CLASS_ROM
/*-----------------------------------------------------------------------------
ROUTINE NAME : RBC_Init
INPUT/OUTPUT : None
DESCRIPTION  :  
-----------------------------------------------------------------------------*/
void RBC_Init(void)
{
	Sense_Tail = 0;
	Sense_Head = 0;
	Format_Blk_Done = 0;
	Current_Operation = RBC_OP_IDLE;
}

/*-----------------------------------------------------------------------------
ROUTINE NAME : SenseCode
INPUT/OUTPUT :
DESCRIPTION  :  
-----------------------------------------------------------------------------*/
void SenseCode(unsigned char Key, unsigned int ASC)
{
	Sense_List[Sense_Tail].Skey = Key;
	Sense_List[Sense_Tail].w.ASC = ASC;
	Sense_Tail++;
	if (Sense_Tail == SENSE_LIST_DEEPTH)
		Sense_Tail = 0;
}

/*-----------------------------------------------------------------------------
ROUTINE NAME : RBC_MAL_Error()
INPUT/OUTPUT : None
DESCRIPTION  : Take care all the error code and return the Sense data
				Return only on RBC_GOOD
-----------------------------------------------------------------------------*/
unsigned char RBC_MAL_Error(unsigned char Errno)
{
	if (Errno == MAL_GOOD)
		return RBC_STATUS_GOOD;

	if (Errno == MAL_NO_CARD)
		SenseCode(NOT_READY, MEDIUM_NOT_PRESENT);
	else if (Errno == MAL_NEW_CARD)
		SenseCode(UNIT_ATTENTION, MEDIUM_HAVE_CHANGED);
	else if (Errno == MAL_CARD_UNKNOWN)
		SenseCode(MEDIUM_ERROR, READ_UNKNOW_FORMAT);
	else if (Errno == MAL_OUT_RANGE)
		SenseCode(ILLEGAL_REQUEST, ADDRESS_OUT_OF_RANGE);
	else if (Errno == MAL_NO_WRITE)
		SenseCode(MEDIUM_ERROR, WRITE_PROTECTED);
	else
		SenseCode(HARDWARE_ERROR, 0);		// Unknow error, must be s/w bug in MAL
	return RBC_STATUS_FAIL;
}

/*-----------------------------------------------------------------------------
ROUTINE NAME : RBC_CopyCmd
INPUT/OUTPUT : None
DESCRIPTION  :  
-----------------------------------------------------------------------------*/
#pragma NO_ENTRY
void RBC_CopyCmd(unsigned char *pRBC)
{
	asm {
		ld		pRBC:1, A
		ld		pRBC, X
		ld		X, #15
copy_loop:
		ld		A, ([pRBC.w], X)
		ld		(RBC_Cmd, X), A
		dec		X
		jrpl	copy_loop
	}
//	unsigned char index;
//	for (index = 16; index; ) {
//		index--;
//		RBC_Cmd[index] = pRBC[index];
//	}
}


/*-----------------------------------------------------------------------------
ROUTINE NAME : RBC_Test_Ready
INPUT/OUTPUT : None
DESCRIPTION  :  
-----------------------------------------------------------------------------*/
char RBC_Test_Ready(void)
{
	return RBC_MAL_Error( MAL_Test_Ready() );
}

#pragma NO_ENTRY
unsigned short div16x16(unsigned short dividend, unsigned short divisor)
{
	unsigned short quotient;
	asm {
		LD		Y, #17

		// shift out leading zero's of divisor
		TNZ		X
		JRMI	after_shift_divisor
shift_divisor:
		INC		Y
		SLA		A
		RLC		X
		JRPL	shift_divisor
after_shift_divisor:
		LD		divisor, X
		LD		divisor:1, A

		// Initialize the quotient
		LD		A, #0xFF
		LD		quotient, A
		LD		quotient:1, A

		// shift out leading zero's of dividend
		LD		X, dividend:1
		LD		A, dividend
		JRMI	after_shift_dividend
shift_dividend:
		DEC		Y
		SLA		X
		RLC		A
		JRPL	shift_dividend
after_shift_dividend:
;		LD		dividend, A
;		LD		dividend:1, X

compare_divisor:
		CP		A, divisor
		JRULT	shift_quotient
		JRUGT	subtract_divisor
		CP		X, divisor:1
		JRUGE	shift_8_bits
		JRT		shift_quotient
//		JRULT	shift_quotient
subtract_divisor:
		PUSH	A
		LD		A, X
		SUB		A, divisor:1
		LD		X, A
		POP		A
		SBC		A, divisor
shift_quotient:
		RLC		quotient:1
		RLC		quotient

		DEC		Y
		JREQ	return_quotient

		// shift left the dividend
		SLA		X
		RLC		A
		JRNC	compare_divisor

		PUSH	A
		LD		A, X
		SUB		A, divisor:1
		LD		X, A
		POP		A
		SBC		A, divisor
		RCF
		JRT		shift_quotient

shift_quotient_only:
		LD		A, quotient:1
		LD		X, quotient
		RCF
shift_less8_bits:
		RLC		A
		RLC		X
		DEC		Y
		JRNE	shift_less8_bits
		CPL		A
		CPL		X
		RET
shift_8_bits:
		LD		A, X
		SUB		A, divisor:1
		LD		X, A
		LD		A, Y
		SUB		A, #8
		JRULT	shift_quotient_only
		LD		Y, A
		LD		A, quotient:1
		LD		quotient, A
		LD		A, #0x7F
		LD		quotient:1, A
		LD		A, X
		CLR		X
		CP		Y, #0
		JRNE	compare_divisor

return_quotient:
	}
	return ~quotient;
}

static unsigned int _RBC_Percentage_Done()
{
/*	Use following version if MAL_Capacity is 2^n
	unsigned char Percent_Temp;
	asm {
		PUSH	Y
		LD		A, MAL_Capacity:2
		LD		Percent_Temp, A

		LD		Y, Format_Blk_Done
		LD		X, Format_Blk_Done:1
		CLR		A

percent_shift:
		SRA		Percent_Temp
		JRC		percent_ret
		SRA		Y
		RRC		X
		RRC		A
		JRT		percent_shift
percent_ret:
		POP		Y
	}
*/
//	if (Format_Blk_Done == 0)
//		return 1;
	return div16x16(Format_Blk_Done, (unsigned short)MAL_Capacity);
//	((unsigned long)Format_Blk_Done << 16) / MAL_Capacity;
}

/*-----------------------------------------------------------------------------
ROUTINE NAME : RBC_Request_Sense
INPUT/OUTPUT : None
DESCRIPTION  :  
-----------------------------------------------------------------------------*/
char RBC_Request_Sense(void)
{
	char Index;

	for (Index = 20; Index > 0; ) {
		Index--;
		MSL_Param_Buffer[Index] = 0x0;	// Clear all to zero
	}
	MSL_Param_Buffer[0]	= 0x70;		// Response Code
	MSL_Param_Buffer[7]	= 12;		// Additional sense length

	if (Sense_Head != Sense_Tail) {
		MSL_Param_Buffer[2]	= Sense_List[Sense_Head].Skey;		// Sense Key
		MSL_Param_Buffer[12]= Sense_List[Sense_Head].w.b.ASC;	// Additional sense code
		MSL_Param_Buffer[13]= Sense_List[Sense_Head].w.b.ASCQ;	// Additional sense code qualifier
		Sense_Head++;
		if (Sense_Head == SENSE_LIST_DEEPTH)
			Sense_Head = 0; 
	}
	else if (MAL_State == MAL_FORMATTING || Format_Blk_Done) {	// When formation is on going
#define pSense ((SENSE_DATA*)MSL_Param_Buffer)

		Format_Blk_Done = (unsigned short)MAL_Capacity - MAL_Block_Numbers;
	//	if (Format_Blk_Done >= NextProgress) {
	//		FormatProgress += (Format_Flags & 0x01) ? 1 : 5;
	//		if (FormatProgress > 100)
	//			NextProgress = 0;
	//		else
	//			NextProgress = MAL_Capacity * FormatProgress / 100;
	//	}
		pSense->Sense_Key = NOT_READY;	// Sense Key
		pSense->ASC = 0x04;				// Additional sense code
		pSense->ASCQ = 0x04;			// Additional sense code qualifier
										// FORMAT IN PROGRESS
		pSense->TBD = 0x80;				// Sense Key specific
		pSense->Sense_Key_Specific  = _RBC_Percentage_Done();

		if (MAL_Block_Numbers == 0)
			Format_Blk_Done = 0;
	}
	else // everything is allright, send back 0 !
		;

	MSL_Param_Size = 20;
	return RBC_STATUS_GOOD;
}

/*-----------------------------------------------------------------------------
ROUTINE NAME : RBC_Inquiry
INPUT/OUTPUT : None
DESCRIPTION  :  
-----------------------------------------------------------------------------*/
char RBC_Inquiry(CMD_INQUIRY *pCmd)	// char Page, unsigned long Length)
{
	unsigned char Page = pCmd->Page;
	unsigned char Length = pCmd->Allocation_Length;
	unsigned char *pPage;

	if (pCmd->CmdDt == 1) {
		SenseCode(ILLEGAL_REQUEST, INVALID_CDB_FIELD);
		return RBC_STATUS_FAIL;
	}

	if (pCmd->Evpd == 1) {
		if (Page == 0x80) {
			if (Length > LENGTH_INQUIRY_PAGE80)
				Length = LENGTH_INQUIRY_PAGE80;
			pPage = Page80_Inquiry_Data;
		}
		else if (Page == 0x83) {
			if (Length > LENGTH_INQUIRY_PAGE83)
				Length = LENGTH_INQUIRY_PAGE83;
			pPage = Page83_Inquiry_Data;
		}
		else {
			SenseCode(ILLEGAL_REQUEST, INVALID_CDB_FIELD);
			return RBC_STATUS_FAIL;
		}
	}
	else
		if (Page == 0x00) {
			if (Length > LENGTH_INQUIRY_PAGE00)
				Length = LENGTH_INQUIRY_PAGE00;
			pPage = Standard_Inquiry_Data;
		}
		else {
			SenseCode(ILLEGAL_REQUEST, INVALID_CDB_FIELD);
			return RBC_STATUS_FAIL;
		}

	MSL_Param_Size = Length;
	while (Length) {
		Length--;
		MSL_Param_Buffer[Length] = pPage[Length];
	}

	return RBC_STATUS_GOOD;
}

/*-----------------------------------------------------------------------------
ROUTINE NAME : RBC_Mode_Sense6(CMD_MSense6 *pCmd)
INPUT/OUTPUT : None
DESCRIPTION  :  
-----------------------------------------------------------------------------*/
char RBC_Mode_Sense6(CMD_MODE_SENSE6 *pCmd)
{
	unsigned char index;

	if (pCmd->PC_Page != 0x3F && pCmd->PC_Page != 0x00) {
		SenseCode(ILLEGAL_REQUEST, INVALID_CDB_FIELD);
		return RBC_STATUS_FAIL;
	}

	index = MODE_SENSE6_LEN;
	while (index) {
		index--;
		MSL_Param_Buffer[index] = MODE_SENSE6_data[index];
	}
	MSL_Param_Size = MODE_SENSE6_LEN;
	if (isWRITE_PROTECT())
		MSL_Param_Buffer[2] = 0x80;

	return RBC_STATUS_GOOD;
}

/*-----------------------------------------------------------------------------
ROUTINE NAME : RBC_Mode_Select6(CMD_MSelect6 *pCmd)
INPUT/OUTPUT : None
DESCRIPTION  :  
-----------------------------------------------------------------------------*/
char RBC_Mode_Select6(CMD_MODE_SELECT6 *pCmd)
{
	SenseCode(ILLEGAL_REQUEST, INVALID_CDB_FIELD);
	return RBC_STATUS_FAIL;
}

/*-----------------------------------------------------------------------------
ROUTINE NAME : RBC_Mode_Sense10(CMD_MSense10 *pCmd)
INPUT/OUTPUT : None
DESCRIPTION  :  
-----------------------------------------------------------------------------*/
char RBC_Mode_Sense10(CMD_MODE_SENSE10 *pCmd)
{
	unsigned char index;

	if (pCmd->PC_Page != 0x3F) {
		SenseCode(ILLEGAL_REQUEST, INVALID_CDB_FIELD);
		return RBC_STATUS_FAIL;
	}

	index = MODE_SENSE10_LEN;
	while (index) {
		index--;
		MSL_Param_Buffer[index] = MODE_SENSE10_data[index];
	}
	MSL_Param_Size = MODE_SENSE10_LEN;
	if (isWRITE_PROTECT())
		MSL_Param_Buffer[3] = 0x80;

	return RBC_STATUS_GOOD;
}

/*-----------------------------------------------------------------------------
ROUTINE NAME : RBC_Read_Capacity
INPUT/OUTPUT : None
DESCRIPTION  :  
-----------------------------------------------------------------------------*/
char RBC_Read_Capacity(void)
{
	unsigned char Errno;
	Errno = RBC_MAL_Error( MAL_Read_Capacity() );
	if (Errno != RBC_STATUS_GOOD)
		return Errno;

	MSL_Param_Size = 8;

	if(!MAL_Mediano)
	{
		if((Windows_2000) && (Current_Mode == 2))	// Under Win2000 and Private Mode
		{
			if(Private_Zone_Size == 0)
				*((unsigned long *)MSL_Param_Buffer) = 0;
			else
				*((unsigned long *)MSL_Param_Buffer) = (MAL_Capacity - Private_Zone_Size) - 1;
		}
		else{
			if(Private_Zone_Size == 0)
				*((unsigned long *)MSL_Param_Buffer) = MAL_Capacity - 1;
			else{
				if(!Current_Mode)
					*((unsigned long *)MSL_Param_Buffer) = MAL_Capacity - 1;
				else
					*((unsigned long *)MSL_Param_Buffer) = Private_Zone_Size - 1;
			}
		}
	}
	else{
		if(Private_Zone_Size == 0)
			*((unsigned long *)MSL_Param_Buffer) = 0;
		else

⌨️ 快捷键说明

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