www.pudn.com > SamsungFlashV11.rar > SamsungFlashV11.asm


//====================================================== 
// 文件名称:	SamsungflashV12.asm 
// 功能描述:   K9F1208的读写、擦除  
// 使用方法: 
//    建议使用以下顺序 
//    初始化过程: 
//     InitSamsungFlash()      
//    写过程:  
//     InitWriteSamsungFlash() -> FillSamsungFlash(Data) -> ... -> StopWriteSamsungFlash() 
//    读过程: 
//     InitReadSamsungFlash()  -> ExtractSamsungFlash()  -> ...-> StopReadSamsungFlash() 
//    流控制: 
//     GetColAddr() 
//     GetPage() 
//     GetBlock() 
// 
//    Note:  
//    1. 注意每次读/写操作都要调用初始化和结束函数   
//    2. 为了避免错误,请不要交迭使用读/写操作 
//    3. 当program/erase错误发生的时候, 用户必须根据自己的文件系统自行处理  
//       请参考_SP_FillSamsungFlash和_SamsungEraseBlock,这里假定没有错误产生  
// 完成日期:   2004-4-12 
// V12修改日期:2004-12-25    Edit By Xinqiang Zhang  xinqiang@sunnorth.com.cn  Tel:010-62981668-2916 
//======================================================================================== 
.INCLUDE hardware.inc; 
 
.PUBLIC _SP_InitSamsungFlash 
.PUBLIC _SP_FillSamsungFlash 
.PUBLIC _SP_ExtractSamsungFlash 
.PUBLIC _SP_InitReadSamsungFlash 
.PUBLIC _SP_InitWriteSamsungFlash 
.PUBLIC _SP_StopWriteSamsungFlash 
.PUBLIC _SP_StopReadSamsungFlash 
.PUBLIC _SP_SamsungEraseBlock 
.PUBLIC _SP_SamsungMassErase 
.PUBLIC _SP_GetColAddr 
.PUBLIC _SP_GetPage 
.PUBLIC _SP_GetBlock 
.PUBLIC _SP_SamsungReadByte 
.PUBLIC _SP_SamsungWriteByte 
.PUBLIC _SP_SamsungReadPageW 
.PUBLIC _SP_SamsungWritePageW 
 
.public _SP_SamsungReadWord						//Add by xinqiang 2004.12.24 
.public _SP_SamsungReadWord_1 
.public _SP_SamsungWriteWord					//Add by xinqiang 2004.12.24 
.PUBLIC _SP_InitReadSamsungFlash_1 
// Flash 控制信号  
.DEFINE RE_BIT  0x04//0x02//0x01	          	 
.DEFINE WE_BIT  0x02//0x20//0x02		 
.DEFINE CE_BIT  0x04		 
.DEFINE ALE_BIT 0x20//0x10//0x08		 
.DEFINE CLE_BIT 0x10//0x08//0x10		 
.DEFINE BASE_CONF 0x003e//0x003a//e 
.define BASE_MASK 0x00c1//4					//用来MASKIOB口中没有用到的IO位 
 
// K9F1208的地址边界 
.define C_Flash_EN	0xff7f					//Add by xinqiang 2004.12.24 
.define C_Flash_UN	0x0080					//Add by xinqiang 2004.12.24 
 
.DEFINE C_PageBin   0x0000         
.DEFINE C_PageEnd   0x1FFFF       
.DEFINE C_BlockBin  0x0000       
.DEFINE C_MaxBlock  0x0FFF      // 4096 block 
 
.DEFINE Port_IOA_Attrib     P_IOA_Attrib 
.DEFINE Port_IOA_Dir 	    P_IOA_Dir 
.DEFINE Port_IOA_Data       P_IOA_Data 
.DEFINE Port_IOA_Buffer     P_IOA_Buffer 
.DEFINE Port_IOB_Attrib     P_IOB_Attrib 
.DEFINE Port_IOB_Dir        P_IOB_Dir 
.DEFINE Port_IOB_Data       P_IOB_Data 
.DEFINE Port_IOB_Buffer     P_IOB_Buffer 
.DEFINE Port_TimeBaseSetup  P_TimeBase_Setup         
.DEFINE Port_Watchdog_Clear P_Watchdog_Clear       
.DEFINE Port_SystemClock    P_SystemClock          
 
// 数据Buffer 
.DEFINE C_PageSize 0x200  			// 512  bytes 
.DEFINE C_MaxPageBufferBytes 0x80 	// 128  bytes 2*C_MaxPageBuffer 
.DEFINE C_MaxPageBuffer 0x40 		// 64   words 
 
.IRAM 
.VAR R_CurrAddr = 0  
.VAR R_CurrPage = C_PageBin  
.VAR R_WriteIndex = 0 
.VAR R_ReadIndex  = C_MaxPageBuffer 
 
.var R_ReadIndex_First				//第一次要读的数据个数 word 
.var R_ReadIndex_Secon				//第二次要读的数据个数 
 
.var R_Addr25 = 0					//Edit by xinqiang 2004.12.20 增加高位的地址寄存器 
.var R_PageBin = C_PageBin 
 
.RAM 
T_PageBuffer: .DW C_MaxPageBuffer dup(0) 
.TEXT 
.public _InitSignalLine 
_InitSignalLine: .proc 
	r1 = RE_BIT|WE_BIT//CE_BIT|RE_BIT|WE_BIT; 
	[Port_IOB_Buffer]=r1; 
	.endp 
 
//-------------------------------------------------------------------- 
//-- 宏名: M_SaveIoSetting for IOA & IOB   M_SaveIOSetting_1 for IOB 
//-- 参数: 无 
//-- 把IO设置保存到堆栈 
//-------------------------------------------------------------------- 
M_SaveIoSetting: .MACRO 
    R5 = [Port_IOB_Buffer]; 
    R5 &= 0xFFD0 
    push R5 to [SP] 
	R5 = [Port_IOA_Buffer]; 
	R5 &= 0xFF00 
	push R5 to [SP] 
.ENDM 
 
M_SaveIoSetting_1:.MACRO 
	r5 = [Port_IOA_Buffer] 
	r5 &= C_Flash_EN 
	[Port_IOA_Data] = r5 
	r5 = [Port_IOB_Buffer]; 
	r5 &= BASE_CONF//0x00d0 
	push r5 to [sp] 
.endm 
//-------------------------------------------------------------------- 
//-- 宏名: M_RetrieveIoSetting for IOA & IOB   M_RetrieveIoSetting_1 for IOB   
//-- 参数: 无 
//-- 从堆栈恢复IO设置 
//-------------------------------------------------------------------- 
M_RetrieveIoSetting: .MACRO 
	pop R5 from [SP] 
	[Port_IOA_Data] = R5 
	pop R5 from [SP] 
	R5 |= CE_BIT 
	[Port_IOB_Data] = R5 
.ENDM 
M_RetrieveIoSetting_1: .MACRO 
	pop R5 from [SP] 
//	R5 |= CE_BIT 
	[Port_IOB_Data] = R5 
	r5 = [Port_IOA_Buffer] 
	r5 |= C_Flash_UN 
	[Port_IOA_Data] = r5 
.ENDM 
//-------------------------------------------------------------------- 
//-- 宏名: M_InitIOAOut for IOA & IOB   M_InitIOAOut_1 for IOB 
//-- 参数: 无 
//-------------------------------------------------------------------- 
M_InitIOAOut: .MACRO 
	R5 = [Port_IOA_Attrib] 
	R5 |= 0x00FF 
	[Port_IOA_Attrib] = R5 
	R5 = [Port_IOA_Dir] 
	R5 |= 0x00FF 
	[Port_IOA_Dir] = R5 
.ENDM 
M_InitIOAOut_1: .MACRO 
	R5 = [Port_IOB_Attrib] 
	R5 |= 0xff00 
	[Port_IOB_Attrib] = R5 
	R5 = [Port_IOB_Dir] 
	R5 |= 0xff00 
	[Port_IOB_Dir] = R5 
.ENDM 
//-------------------------------------------------------------------- 
//-- 宏名: M_InitIOAIn for IOA & IOB   M_InitIOAIn_1 for IOB 
//-- 参数: 无 
//-------------------------------------------------------------------- 
M_InitIOAIn: .MACRO 
	R5 = [P_IOA_Attrib] 
	R5 &= 0xFF00 
	[P_IOA_Attrib] = R5 
	R5 = [P_IOA_Dir] 
	R5 &= 0xFF00 
	[P_IOA_Dir] = R5 
.ENDM 
M_InitIOAIn_1: .MACRO 
	R5 = [P_IOB_Attrib] 
	R5 &= 0x00ff 
	[P_IOB_Attrib] = R5 
	R5 = [P_IOB_Dir] 
	R5 &= 0x00ff 
	[P_IOB_Dir] = R5 
.ENDM 
//-------------------------------------------------------------------- 
//-- 宏名: M_SendReadCmd 
//-- 参数: column,page,portA,portB 
//-- 发送 0x00, 0x01 or 0x50 
//-------------------------------------------------------------------- 
M_SendReadCmd: .MACRO column,page,portA,portB 
	R5 = SP 
	portA = [R5+1]		 
	portB = [R5+2]		 
	R5 = (CLE_BIT|RE_BIT) 
	R5 |= portB 
	[Port_IOB_Data] = R5 
	R5 = 0x0000						//read0 命令  
	cmp column, 256 
	jb ?NotChArea 
	column -= 256 
	R5 = 0x0001  					//read1 命令  
	cmp column, 256 
	jb ?NotChArea 
	column -= 256 
	R5 = 0x0050  					//read2 命令  
?NotChArea: 
	R5 |= portA 
	[Port_IOA_Data] = R5 
	R5 = (CLE_BIT|RE_BIT|WE_BIT) 
	R5 |= portB 
	[Port_IOB_Data] = R5			//WE高电平  
	R5 = (WE_BIT|ALE_BIT|RE_BIT)	//CLE低电平 , WE高电平 , ALE高电平 , RE高电平  
	R5 |= portB 
	[Port_IOB_Data] = R5 
	//.....写地址..................... 
	portB |= (ALE_BIT|RE_BIT) 
	[Port_IOB_Data] = portB			//WE低电平  
	column |= portA 
	[Port_IOA_Data] = column		//Address0 - 7 
	[Port_IOB_Data] = R5			//WE, ALE, RE高电平  
	[Port_IOB_Data] = portB			//WE低电平  
	column = page & 0x00FF 
	column |= portA 
	[Port_IOA_Data] = column		//Address9 - 16 
	[Port_IOB_Data] = R5			//WE, ALE高电平  
	[Port_IOB_Data] = portB			//WE低电平  
	page = page LSR 4 
	page = page LSR 4 
	page |= portA 
	[Port_IOA_Data] = page			//Address17 - 22 
	[Port_IOB_Data] = R5			//WE, ALE高电平  
 
	[Port_IOB_Data] = portB			//WE低电平  
	push r1 to [sp] 
	r1 = [R_Addr25]//0					//Edit by xinqiang 2004.12.20 从寄存器地址中读取高位地址 
	[Port_IOA_Data] = r1			//Address25 
	pop r1 from [sp] 
	[Port_IOB_Data] = R5			//WE, ALE高电平  
 
	R5 = SP 
	portB = [R5+2] 
	R5 = (WE_BIT|RE_BIT) 
	R5 |= portB 
	[Port_IOB_Data] = R5			//WE高电平 , RE高电平 , ALE低电平 	 
.ENDM 
 
//-------------------------------------------------------------------- 
//-- 宏名: M_SendWriteCmd 
//-- 参数: column,page,portA,portB 
//-- 发送 0x80 
//-------------------------------------------------------------------- 
M_SendWriteCmd: .MACRO column,page,portA,portB 
	R5 = SP 
	portA = [R5+1]		 
	portB = [R5+2]	 
	R5 = (CLE_BIT|RE_BIT) 
	R5 |= portB 
	[Port_IOB_Data] = R5 
	R5 = 0x0000 
	cmp column, 256 
	jb ?NotChArea 
	column -= 256 
	R5 = 0x0001 
	cmp column, 256 
	jb ?NotChArea 
	column -= 256 
	R5 = 0x0050 
?NotChArea: 
	R5 |= portA 
	[Port_IOA_Data] = R5 
	R5 = (CLE_BIT|RE_BIT|WE_BIT) 
	R5 |= portB 
	[Port_IOB_Data] = R5 
	R5 = (CLE_BIT|RE_BIT)  
	R5 |= portB 
	[Port_IOB_Data] = R5 
	R5 = 0x0080 					 // 连续数据输入命令  
	R5 |= portA 
	[Port_IOA_Data] = R5 
	R5 = (CLE_BIT|RE_BIT|WE_BIT) 
	R5 |= portB 
	[Port_IOB_Data] = R5			//WE高电平  
	R5 = (WE_BIT|ALE_BIT|RE_BIT)	//CLE低电平 , WE高电平 , ALE高电平 , RE高电平  
	R5 |= portB 
	[Port_IOB_Data] = R5 
	//.....写地址..................... 
	portB |= (ALE_BIT|RE_BIT) 
	[Port_IOB_Data] = portB			//WE低电平  
	column |= portA 
	[Port_IOA_Data] = column		//Address0 - 7 
	[Port_IOB_Data] = R5			//WE, ALE, RE高电平  
	[Port_IOB_Data] = portB			//WE低电平  
	column = page & 0x00FF 
	column |= portA 
	[Port_IOA_Data] = column		//Address9 - 16 
	[Port_IOB_Data] = R5			//WE, ALE高电平  
	[Port_IOB_Data] = portB			//WE低电平  
	page = page LSR 4 
	page = page LSR 4 
	page |= portA 
	[Port_IOA_Data] = page		//Address17 - 22 
	[Port_IOB_Data] = R5		//WE, ALE高电平 	 
 
//for debug,no a25 
	[Port_IOB_Data] = R4		//WE低电平  
	push r1 to [sp] 
	r1 = [R_Addr25]//0					//Edit by xinqiang 2004.12.20 从寄存器中读取高位地址 
	[Port_IOA_Data] = r1			//Address25 
	pop r1 from [sp] 
	[Port_IOB_Data] = R5		//WE, ALE高电平  
// 
 
	R5 = SP 
	portB = [R5+2] 
.ENDM 
 
//-------------------------------------------------------------------- 
//-- 宏名: M_StartProgram 
//-- 参数: portA,portB 
//-- Send 0x10  
//-------------------------------------------------------------------- 
M_StartProgram: .MACRO portA,portB 
	R5 = (CLE_BIT|RE_BIT) 
	R5 |= portB 
	[Port_IOB_Data] = R5		//WE低电平 , RE高电平 , CLE高电平  
 
	R5 = 0x0010					//program 命令  
	R5 |= portA 
	[Port_IOA_Data] = R5		//WE低电平 , RE高电平 , CLE高电平  
	R5 = (CLE_BIT|RE_BIT|WE_BIT) 
	R5 |= portB 
	[Port_IOB_Data] = R5 
.ENDM 
M_StartProgram_1: .MACRO portA,portB 
	R5 = (CLE_BIT|RE_BIT) 
	R5 |= portB 
	[Port_IOB_Data] = R5		//WE低电平 , RE高电平 , CLE高电平  
	r5 &= 0x00ff 
	R5 |= 0x1000					//program 命令  
	[Port_IOB_Data] = R5		//WE低电平 , RE高电平 , CLE高电平  
	R5 |= WE_BIT//(CLE_BIT|RE_BIT|WE_BIT) 
	[Port_IOB_Data] = R5 
.ENDM 
//-------------------------------------------------------------------- 
//-- 函数名: _SP_InitSamsungFlash 
//-- 参数: 无 
//-- 返回值: 无 
//2004.12.23  Edit by xinqiang Zhang for change the IO 
//-------------------------------------------------------------------- 
_SP_InitSamsungFlash: .proc 
_InitSamsungFlash: 
	push R1 to [SP] 
	R1 = 0  
	[Port_TimeBaseSetup] = R1 
//	[Port_SystemClock] = R1 
//	R1 = 0x01 
//	[Port_Watchdog_Clear] = R1 
//	R1 = [Port_IOA_Attrib] 
//	R1 |= C_Flash_UN//0xFF00 
//	[Port_IOA_Attrib] = R1 
//	R1 = [Port_IOA_Dir] 
//	R1 |= C_Flash_UN//0xFF00 
//	[Port_IOA_Dir] = R1 
	 
	R1 = [Port_IOB_Attrib] 
	R1 &= BASE_MASK//0x00c0//0xFFD0 
	R1 |= BASE_CONF 
	[Port_IOB_Attrib] = R1 
	R1 = [Port_IOB_Dir] 
	R1 &= BASE_MASK//0x00c0//0xFFD0 
	R1 |= BASE_CONF 
	[Port_IOB_Dir] = R1 
//	R1 = [Port_IOB_Buffer] 
//	R1 |= CE_BIT					//////note that for next time will change it to IOA 
//	[Port_IOB_Data] = R1 
	pop R1 from [SP] 
	retf 
.endp 
//-------------------------------------------------------------------- 
//-- 函数名: _SP_InitWriteSamsungFlash 
//-- 语法: InitWriteSamsungFlash() 
//-- 参数: 无 
//-- 返回值: 无 
//-------------------------------------------------------------------- 
_SP_InitWriteSamsungFlash: .proc 
	 
	PUSH R1,R5 TO [SP];					//Edit by xinqiang 2004.12.20 
	r5 = sp+8							//.... 
//	r3 = [r5++] 
	r1 = [r5++]							//page number 
	r2 = [r5]							//block number  
//	[R_CurrAddr]=R3; 
    R3 = 0; 
    [R_WriteIndex]=R3; 
    [R_CurrAddr]=R3; 
    r2 = r2 rol 4 
    r2 = r2 rol 1 
    r3 = r2&0xffe0 
    r2 = r2 rol 4 
    r2 = r2&0x0001 
    r1 = r1|r3 
 //   R1 = C_PageBin; 
    [R_CurrPage]=R1;   
    [R_PageBin]=r1;				//Edit by xinqiang 
      
    [R_Addr25]=r2;  
	POP R1,R5 FROM [SP]; 
	retf 
.endp 
//-------------------------------------------------------------------- 
//-- 函数名: _SP_StopWriteSamsungFlash 
//-- 语法: SP_StopWriteSamsungFlash() 
//-- 参数: 无 
//-- 返回值: 无 
//-------------------------------------------------------------------- 
_SP_StopWriteSamsungFlash: .proc 
 
	PUSH R1,R4 TO [SP]; 
    R2=0; 
    R5=[R_CurrAddr]; 
    cmp R5, C_MaxPageBufferBytes; 
    jb ?L_LowerPage; 
    R2=C_MaxPageBufferBytes; 
?L_LowerPage: 
    R1 = R2; 
    R2 = [R_CurrPage];     
    R3 = T_PageBuffer; 
    R4 = [R_WriteIndex]; 
    R4 = R4 lsl 1 
 
	call F_SamsungWritePageW; 
	 
    R1 = 0; 
    [R_WriteIndex]=R1; 
    [R_CurrAddr]=R1;    
    R1 = [R_PageBin];//C_PageBin; 
    [R_CurrPage]=R1;     
	POP R1,R4 FROM [SP]; 
	retf 
.endp 
//-------------------------------------------------------------------- 
//-- 函数名: _SP_InitReadSamsungFlash 
//-- 语法: SP_InitReadSamsungFlash() 
//-- 参数: 无 
//-- 返回值: 无 
//-------------------------------------------------------------------- 
_SP_InitReadSamsungFlash: .proc 
 
	PUSH R1,R5 TO [SP];						//Edit By xinqiang 2004.12.20 
	r5 = sp+8 
	r1 = [r5++]								//get the page number 
	r2 = [r5]								//get the block number 
    R3=C_MaxPageBuffer; 
    [R_ReadIndex]=R3; 
 //   R1=C_PageBin;    
    r2 = r2 rol 4 
    r2 = r2 rol 1 
    r3 = r2&0xffe0 
    r2 = r2 rol 4 
    r2 = r2&0x0001 
    r1 = r1|r3 
    [R_CurrPage]=R1;  
 //   [R_PageBin] = r1				//Edit by xinqiang 
    [R_Addr25] = r2 
    R1=0; 
    [R_CurrAddr]=R1; 
     
    R1 = 64 
    [R_ReadIndex_First] = R1 
    [R_ReadIndex_Secon] = R1	 
	POP R1,R5 FROM [SP]; 
	retf 
.endp 
 
//-------------------------------------------------------------------- 
//-- 函数名: _SP_InitReadSamsungFlash_1 
//-- 语法: SP_InitReadSamsungFlash_1() 
//-- 参数: r1 page number r2 block number r3 clraddr 
//-- 返回值: 无 
//-------------------------------------------------------------------- 
_SP_InitReadSamsungFlash_1: .proc 
 
	PUSH R1,R5 TO [SP];						//Edit By xinqiang 2004.12.20 
	r5 = sp+8 
	r3 = [r5++] 
	r1 = [r5++]								//get the page number 
	r2 = [r5]								//get the block number 
	[R_CurrAddr]=R3;						//Get the currAddr 
?InitRead_2: 
	cmp r3,64 
	jb ?InitRead_1 
	r3 -= 64 
	jmp ?InitRead_2	 
?InitRead_1: 
	r4 = 64 
	r4 -= r3 
	[R_ReadIndex_First] = r4 
	[R_ReadIndex_Secon] = r4 
  //  R3=C_MaxPageBuffer; 
    [R_ReadIndex]=R4//R3; 
 //   R1=C_PageBin;    
    r2 = r2 rol 4 
    r2 = r2 rol 1 
    r3 = r2&0xffe0 
    r2 = r2 rol 4 
    r2 = r2&0x0001 
    r1 = r1|r3 
    [R_CurrPage]=R1;  
    [R_Addr25] = r2 
     
	POP R1,R5 FROM [SP]; 
	retf 
.endp 
//-------------------------------------------------------------------- 
//-- 函数名: _SP_StopReadSamsungFlash 
//-- 语法: SP_StopReadSamsungFlash() 
//-- 参数: 无 
//-- 返回值: 无 
//-------------------------------------------------------------------- 
_SP_StopReadSamsungFlash: .proc 
 
	PUSH R1,R1 TO [SP]; 
    R1 = [R_PageBin];//C_PageBin;  
    [R_CurrPage] = R1; 
    R1=0;   
    [R_ReadIndex] = R1;   
    [R_CurrAddr]=R1; 
	POP R1,R1 FROM [SP]; 
	retf 
.endp 
//-------------------------------------------------------------------- 
//-- 函数名: _SP_GetColAddr 
//-- 语法: SP_GetColAddr() 
//-- 参数: 无 
//-- 返回值: R1=Column Addr 
//-------------------------------------------------------------------- 
_SP_GetColAddr: .proc 
 
    PUSH BP,BP TO [SP]; 
    
    R1=[R_CurrAddr]; 
    
    POP BP,BP FROM [SP]; 
    retf 
.endp 
//-------------------------------------------------------------------- 
//-- 函数名: _SP_GetPage 
//-- 语法: SP_GetPage() 
//-- 参数: 无 
//-- 返回值: R1=Page low  R2=Page high 
//-------------------------------------------------------------------- 
_SP_GetPage: .proc 
 
    PUSH BP,BP TO [SP]; 
     
    R1=[R_CurrPage]; 
    r2 = [R_Addr25]; 
    POP BP,BP FROM [SP]; 
    retf 
.endp 
//-------------------------------------------------------------------- 
//-- 函数名: _SP_GetBlock 
//-- 语法: SP_GetBlock() 
//-- 参数: 无 
//-- 返回值: R1=Block 
//-------------------------------------------------------------------- 
_SP_GetBlock: .proc 
 
    PUSH BP,BP TO [SP]; 
     
    R1=[R_CurrPage]; 
    R1= R1 LSR 4;    
    POP BP,BP FROM [SP]; 
    retf 
.endp 
//-------------------------------------------------------------------- 
//-- 函数名: _SP_FillSamsungFlash 
//-- 语法: SP_FillSamsungFlash(Data) 
//-- 参数: R1=Data 
//-- 返回值: 无 
//-------------------------------------------------------------------- 
_SP_FillSamsungFlash: .proc 
 
    PUSH BP,BP TO [SP]; 
    BP = SP + 1 
    R1=[BP+3] 
    call F_FillSamsungFlash    
	POP BP,BP FROM [SP]; 
	retf 
.endp 
 
F_FillSamsungFlash:    
    push R2,R5 to [SP]; 
    // Fill the data to buffer 
    R2=[R_WriteIndex]; 
    R3=T_PageBuffer; 
    R3+=R2; 
    [R3]=R1; 
    //..... Update Buffer used and Addr	 
    R2=R2+1; 
    [R_WriteIndex]=R2; 
    R2 =[R_CurrAddr]; 
    R2+=2; 
    [R_CurrAddr]=R2; 
    //..... Check buffer full 
    R2=[R_WriteIndex] 
    cmp R2,C_MaxPageBuffer; 
    jb ?L_Done 
    // ..... Get Status 
?L_WaitForProgramFlash: 
    call _SamsungGetStatus_1;     
    R2=R1&0x40;    // ..... Check busy/ready        
    jz ?L_WaitForProgramFlash 
    //R2=R1&0x0001;     // Check success/failure 
    //jz ?L_ProgramFlash 
    //  ... Handle Program Error here according to you file system ... 
    // ..... Program Flash 
?L_ProgramFlash: 
    R1=[R_CurrAddr]; 
    R1-=C_MaxPageBufferBytes; 
    R2=[R_CurrPage]; 
    R3= T_PageBuffer; 
    R4= C_MaxPageBufferBytes; 
     
	call F_SamsungWritePageW; 
	 
	R2=[R_CurrAddr];	 
	cmp R2, C_PageSize; 
    jb ?L_LowerPage 
	R1=0;	 
	[R_CurrAddr]=R1; 
	R2=[R_CurrPage];	     
	R2+=1; 
	[R_CurrPage]=R2; 
		 
?L_LowerPage: 
    R1=0; 
    [R_WriteIndex]=R1; 
?L_Done:	 
	pop R2,R5 from [SP] 
retf	 
//-------------------------------------------------------------------- 
//-- 函数名: _SP_ExtractSamsungFlash 
//-- 语法: SP_ExtractSamsungFlash() 
//-- 参数: 无 
//-- 返回值: R1=Data 
//-- 2004.12.25  Edit by Xinqiang Zhang for change IO 
//-------------------------------------------------------------------- 
_SP_ExtractSamsungFlash: .proc 
    PUSH BP,BP TO [SP]; 
    BP = SP + 1 
    call F_ExtractSamsungFlash   
	POP BP,BP FROM [SP]; 
	retf 
.endp 
 
F_ExtractSamsungFlash:   
    push R2,R5 to [SP] 
    // ..... Buffer check 
    R2=[R_ReadIndex] 
    R1 = [R_ReadIndex_First] 
    cmp R2,R1//C_MaxPageBuffer 
     
    jb ?L_ExtractBuffer  // Data in buffer , go read it 
    // ..... Get Status 
/////////////////////////////////////////// 
//debug     
?L_WaitForReadFlash: 
    call _SamsungGetStatus_1;     
    R1&=0x40      // ..... Check busy     
    jz ?L_WaitForReadFlash 
//	r1=0xfff 
//?L_WaitForReadFlash: 
//	r1-=1 
//	jnz ?L_WaitForReadFlash 
 
//////////////////////////////////////// 
    // ..... Read Flash 
    R1= [R_CurrAddr]; 
    R2= [R_CurrPage]; 
    cmp R1 ,C_PageSize; 
    
    jb ?L_LowerPage ; 
    R1=0; 
    [R_CurrAddr]=R1; 
    // Next Page 
    R2+=1; 
    [R_CurrPage]=R2; 
    jnz ?L_LowerPage 
    r2 = 0x0001 
    [R_Addr25] = r2 
    
?L_LowerPage: 
    R3 = T_PageBuffer; 
    R4= [R_ReadIndex_Secon]//C_MaxPageBufferBytes;   
    R4 = R4 lsl 1  
 
    call  F_SamsungReadPageW; 
     
    // Update Data 
    R1=0 
    [R_ReadIndex]=R1;  
    R1 = [R_ReadIndex_Secon] 
    [R_ReadIndex_First] = r1 
    r1 = 64 
    [R_ReadIndex_Secon] = r1 
     
?L_ExtractBuffer: 
    R3=[R_CurrAddr]; 
    R3+=2; 
    [R_CurrAddr]=R3; 
    R1=T_PageBuffer; 
    R2=[R_ReadIndex]; 
    R2+=R1; 
    R1=[R2];   // returned value     
    //..... Update Buffer used and Addr 
    R2=[R_ReadIndex]; 
    R2+=1; 
	[R_ReadIndex]=R2; 
   
	pop R2,R5 from [SP]; 
retf 
//-------------------------------------------------------------------- 
//-- 函数名: _SP_GetFlashStatus 
//-- 语法: SP_GetStatus() 
//-- 参数: 无 
//-- 返回值: R1 = Status. 
//-------------------------------------------------------------------- 
_SP_GetFlashStatus: .proc 
    PUSH BP,BP TO [SP]; 
    call _SamsungGetStatus_1; 
	POP BP,BP FROM [SP];	 
    retf 
.endp 
//-------------------------------------------------------------------- 
//-- 函数名: _SamsungGetStatus 
//-- 参数: 无 
//-- 返回值: R1 = Status. 
//-------------------------------------------------------------------- 
_SamsungGetStatus: //.proc 
	push R2, R5 to [SP] 
    M_SaveIoSetting; 
	//......init port A0-A7 as output....... 
	M_InitIOAOut; 
	//......send 命令 .................... 
	R5 = SP 
	R2 = [R5+1]					//portA 
	R3 = [R5+2]					//portB 
	R4 = (CLE_BIT|RE_BIT) 
	R4 |= R3 
	[Port_IOB_Data] = R4 
	R5 = 0x0070  				//read0 命令  
	R5 |= R2 
	[Port_IOA_Data] = R5 
	R4 |= WE_BIT 
	[Port_IOB_Data] = R4		//WE高电平  
	R4 = (WE_BIT|RE_BIT)		//CLE低电平 , WE高电平 , RE高电平  
	R4 |= R3 
	[Port_IOB_Data] = R4 
	//.....init port A0-A7 as input.......... 
	M_InitIOAIn; 
	//....................................... 
	R4 = WE_BIT					//RE低电平  
	R4 |= R3 
	[Port_IOB_Data] = R4 
//	nop 
	R1 = [Port_IOA_Data]		 
	R1 &= 0x00FF 
	M_RetrieveIoSetting; 
	pop R2, R5 from [SP] 
	retf 
//.endp 
  
//-------------------------------------------------------------------- 
//-- 函数名: _SP_SamsungReadByte 
//-- 语法: SP_SamsungReadByte(column address, page address) 
//-- 参数: R1 = column address (0 - 527) 
//--            R2 = page address (A9 - A22) 
//-- 返回值: R1 = Byte value. 
//-------------------------------------------------------------------- 
_SP_SamsungReadByte: .proc 
    PUSH BP,BP TO [SP]; 
    BP = SP + 1 
 	R1=[BP+3] 
	R2=[BP+4] 
   
    call _SamsungReadByte; 
 
    R1=R3; 
	POP BP,BP FROM [SP]; 
	retf 
.endp 
//-------------------------------------------------------------------- 
//-- 函数名: _SamsungReadByte 
//-- 参数: R1 = column address (0 - 527) 
//--            R2 = page address (A9 - A22) 
//-- 返回值: R3 = Byte value. 
//2004.12.23 Edit by xinqiang zhang for change the IO 
//-------------------------------------------------------------------- 
_SamsungReadByte: //.proc 
	push R1, R2 to [SP] 
	push R4, R5 to [SP] 
    M_SaveIoSetting_1; 
	//......init port A0-A7 as output........ 
	M_InitIOAOut_1; 
	//......send 命令 ..................... 
    call MM_SendReadCmd 
    //M_SendReadCmd R1,R2,R3,R4; 
	//.....init port A0-A7 as input.......... 
    M_InitIOAIn_1; 
	//......start of reading data............ 
	R1 = 25                                                  //edit by hongyan 
?waitLp: 
	R1 -= 1 
	jnz ?waitLp					 
	R4 |= WE_BIT					//RE低电平  
	[Port_IOB_Data] = R4 
//	nop 
//	nop 
//	nop 
	R3 = [Port_IOB_Data] 
	R3 &= 0xff00//0x00FF 
	M_RetrieveIoSetting_1; 
	r3 = r3 lsr 4 
	r3 = r3 lsr 4 
	pop R4, R5 from [SP] 
	pop R1, R2 from [SP] 
	retf 
//.endp 
//-------------------------------------------------------------------- 
//-- 函数名: _SP_SamsungReadPageW 
//-- 语法: SP_SamsungReadPageW(column address, page address,address of buffer,# of bytes to be stored) 
//-- 参数: R1 = column address (0 - 527) 
//--            R2 = page address (A9 - A22) 
//--			R3 = Address of buffer 
//--			R4 = Number of bytes to be read 
//-- 返回值: 无. 
//-------------------------------------------------------------------- 
_SP_SamsungReadPageW: .proc 
    PUSH BP,BP TO [SP]; 
	BP=SP+1; 
	R1 = [BP+3]; 
	R2 = [BP+4]; 
    R3 = [BP+5]; 
    R4 = [BP+6]; 
 
    call F_SamsungReadPageW; 
 
	POP BP,BP FROM [SP]; 
	retf 
.endp 
//-------------------------------------------------------------------- 
//-- 函数名: _SamsungReadWord 
//-- 参数: R1 = column address (0 - 527) 
//--            R2 = page address (A9 - A22) 
//-- 返回值: R3 = Byte value. 
//-------------------------------------------------------------------- 
 
_SP_SamsungReadWord:.proc 
	push r5 to [sp] 
	r5 = sp+1 
	r1 = [r5+3] 
	r2 = [r5+4] 
	call _SamsungReadByte 
	push r3 to [sp] 
	r1+=1 
	call _SamsungReadByte 
	r3 = r3 lsl 4 
	r3 = r3 lsl 4 
	pop r1 from [sp] 
	r1 = r1|r3 
	pop r5 from [sp] 
	retf 
.endp 
//-------------------------------------------------------------------- 
//-- 函数名: _SamsungReadWord_1   Read a word from flash anyaddr 
//-- 参数: R1 = column address (0 - 527) 
//--            R2 = page address (A9 - A24) 
//--				R3 = Block address (A25) 
//-- 返回值: R3 = Byte value. 
//-- 2004.12.25   Edit by xinqiang   for change IO 
//-------------------------------------------------------------------- 
 
_SP_SamsungReadWord_1:.proc 
	push r5 to [sp] 
	r5 = sp+1 
	r1 = [r5+3] 
	r2 = [r5+4] 
	r3 = [r5+5]					//get the block number 
	r4 = r3 & 0x0800 
	r4 = r4 lsr 4 
	r4 = r4 lsr 4 
	r4 = r4 lsr 3 
	r4 &= 0x0001 
	[R_Addr25] = r4 
	r3 = r3 lsl 4 
	r3 = r3 lsl 1 
	r2 |= r3 
	call _SamsungReadByte		//Read the low byte 
	push r3 to [sp] 
	r1+=1 
	call _SamsungReadByte		//Read the hight byte 
	r3 = r3 lsl 4 
	r3 = r3 lsl 4 
	pop r1 from [sp] 
	r1 = r1|r3 
	pop r5 from [sp] 
	retf 
.endp 
//-------------------------------------------------------------------- 
//-- Function: F_SamsungReadPageW 
//-- 参数: R1 = column address (0 - 527) 
//--            R2 = page address (A9 - A22) 
//--			R3 = Address of buffer 
//--			R4 = Number of bytes to be read 
//-- 返回值: 无. 
//2004.12.23  Edit by xinqiang for change the IO 
//-------------------------------------------------------------------- 
F_SamsungReadPageW: 
    push R3, R5 to [SP] 
	M_SaveIoSetting_1; 
	//......init port A0-A7 as output........ 
	M_InitIOAOut_1; 
	//......send 命令 ..................... 
    call MM_SendReadCmd //R1,R2,R3,R4; 
	//.....init port A0-A7 as input.......... 
    M_InitIOAIn_1; 
	//......start of reading data............ 
	R1 = 20 
?waitLp: 
	R1 -= 1 
	jnz ?waitLp 
	R2 = R4 
	R5 = SP + 1//2 
	R3 = [R5+1] 
	R4 = [R5+2] 
	R1 = WE_BIT 
	R1 |= R2 
	R2 = R1|RE_BIT 
?readLp: 
	[P_IOB_Data] = R1 
	R5 = [P_IOB_Data]			// Get低电平 er byte 
	R5 &= 0xff00//0x00FF 
	r5 = r5 lsr 4 
	r5 = r5 lsr 4 
	[P_IOB_Data] = r2//R1 
	[P_IOB_Data] = R1 
	push r1 to [sp] 
	R1 = [P_IOB_Data]   		// Get高电平 er byte 
	r1 &= 0xff00 
	R5 |= R1; 
	[R3++] = R5; 
	[P_IOB_Data] = r2//R1 
	pop r1 from [sp] 
	R4 -= 2		 
	jnz ?readLp 
	M_RetrieveIoSetting_1; 
	pop R3, R5 from [SP] 
retf  
//-------------------------------------------------------------------- 
//-- 函数名: _SP_SamsungWriteByte 
//-- 语法: SP_SamsungWriteByte(column address, page address,data to store) 
//-- 参数: R1 = column address (0 - 527) 
//--            R2 = page address (A9 - A22) 
//--			R3 = data to store 
//-- 返回值: R1=0: success, R1=1: failure  
//--		(only detect "1"s that are not successfully program to "0"s). 
//-------------------------------------------------------------------- 
_SP_SamsungWriteByte: .proc 
    PUSH BP,BP TO [SP]; 
	BP=SP+1 
	R1 = [BP+3] 
	R2 = [BP+4] 
    R3 = [BP+5] 
    r4 = CE_BIT 
    [Port_IOB_Data] = r4 
	call _SamsungWriteByte 
 
    POP BP,BP FROM [SP]; 
	//pop R2, R5 from [SP] 
	retf 
.endp 
//-------------------------------------------------------------------- 
//-- 函数名: _SP_SamsungWriteWord 
//-- 语法: SP_SamsungWriteWord(column address, page address,data to store) 
//-- 参数: R1 = column address (0 - 263) 
//--            R2 = page address (A9 - A24) 
//--			R3 = data to store 
//-- 返回值: R1=0: success, R1=1: failure  
//--		(only detect "1"s that are not successfully program to "0"s). 
//note: the Address 25 have define in function SP_InitWrite~~~~ 
//Date: 2004.12.24 Edit by xinqiang Zhang 
//-------------------------------------------------------------------- 
_SP_SamsungWriteWord: .proc 
    PUSH BP,BP TO [SP]; 
	BP=SP+1 
	R1 = [BP+3] 
	R2 = [BP+4] 
    R3 = [BP+5] 
	call _SamsungWriteByte 
	R1 = [BP+3] 
    R3 = [BP+5] 
	call _SamsungWriteByte 
	R1 = [BP+3] 
	r1+=1 
    R3 = [BP+5] 
    r3 = r3 lsr 4 
    r3 = r3 lsr 4 
	call _SamsungWriteByte 
 
    POP BP,BP FROM [SP]; 
	//pop R2, R5 from [SP] 
	retf 
.endp 
//-------------------------------------------------------------------- 
//-- 函数名: _SamsungWriteByte 
//-- 参数: R1 = column address (0 - 527) 
//--            R2 = page address (A9 - A22) 
//--			R3 = data to store 
//-- 返回值: R1=0: success, R1=1: failure  
//--		(only detect "1"s that are not successfully program to "0"s). 
//-------------------------------------------------------------------- 
_SamsungWriteByte: //.proc 
	push R2, R5 to [SP] 
	M_SaveIoSetting_1; 
	//......init port A0-A7 as output....... 
	M_InitIOAOut_1; 
	//......send 命令 ......... 
//	M_SendWriteCmd R1,R2,R3,R4; 
	call MM_SendWriteCmd 
	//......write data sequence.............. 
//	R1 = R3						//portA 
	R2 = R4						//portB 
	R2 &= 0x00ff 
	R5 = SP + 1//2 
	R3 = [R5+2] 
	R5 = RE_BIT 
	R5 |= R2 
	[Port_IOB_Data] = R5		//WE低电平 , RE高电平 , ALE低电平  
//	R3 &= 0x00FF 
	r3 = r3 lsl 4 
	r3 = r3 lsl 4 
	R5 |= R3 //R3 |= R1 
	[Port_IOB_Data] = R5//[Port_IOA_Data] = R3 
	R5 |= WE_BIT//= (RE_BIT|WE_BIT) 
//	R5 |= R2 
	[Port_IOB_Data] = R5 
	//.......start program process............... 
    M_StartProgram_1 R1,R2; 
	//.......read status......................... 
	R4 = (CLE_BIT|RE_BIT)	 
	R4 |= R2 
	[Port_IOB_Data] = R4 
	R4 |= 0x7000//= 0x0070					//get status 
//	R4 |= R1 
	[Port_IOB_Data] = R4//[Port_IOA_Data] = R4		//WE低电平 , RE高电平 , CLE高电平  
	R4 |= WE_BIT//= (CLE_BIT|RE_BIT|WE_BIT) 
	//R4 |= R2 
	[Port_IOB_Data] = R4 
	//........init port A0-A7 as input............ 
	M_InitIOAIn_1; 
	//............................................ 
	R4 = WE_BIT 
	R4 |= R2 
	R5 = (WE_BIT|RE_BIT) 
	R5 |= R2 
?busyLp: 
	[Port_IOB_Data] = R4 
	R1 = [Port_IOB_Data]//[Port_IOA_Data] 
	[Port_IOB_Data] = R5 
	R2 = R1 & 0x4000//0x0040 
	jz ?busyLp 
	R1 &= 0x0001 
    M_RetrieveIoSetting_1; 
	pop R2, R5 from [SP] 
	retf 
//.endp 
//-------------------------------------------------------------------- 
//-- 函数名: _SP_SamsungWritePageW 
//-- 语法: SamsungWritePageW(column address, page address,address of buffer,# of bytes to be stored) 
//-- 参数: R1 = column address (0 - 527) 
//--            R2 = page address (A9 - A22) 
//--			R3 = address of buffer 
//--			R4 = Number of bytes to be stored 
//-- 返回值: 无 
//-------------------------------------------------------------------- 
_SP_SamsungWritePageW: .proc 
   PUSH BP,BP TO [SP]; 
	BP=SP+1 
	R1 = [BP+3] 
	R2 = [BP+4] 
    R3 = [BP+5] 
    R4 = [BP+6]   	 
     
    call F_SamsungWritePageW 
    POP BP,BP FROM [SP]; 
	retf 
.endp 
//-------------------------------------------------------------------- 
//-- Function: F_SamsungWritePageW 
//-- 参数: R1 = column address (0 - 527) 
//--            R2 = page address (A9 - A22) 
//--			R3 = address of buffer 
//--			R4 = Number of bytes to be stored (must be even) 
//-- 返回值: 无 
//-------------------------------------------------------------------- 
F_SamsungWritePageW:  
	push R3, R5 to [SP] 
	M_SaveIoSetting_1; 
	//......init port A0-A7 as output....... 
	M_InitIOAOut_1; 
	//......send 命令 ......... 
	//M_SendWriteCmd R1,R2,R3,R4; 
	call MM_SendWriteCmd 
	//......write data sequence.............. 
//	R1 = R3						//portA 
	R2 = R4						//portB 
	r2 &= 0x00ff 
	R5 = SP + 1//2 
	R3 = [R5+1] 
	R4 = [R5+2] 
?writeLp: 
	R5 = RE_BIT 
	R5 |= R2 
	[P_IOB_Data] = R5		//WE低电平 , RE高电平 , ALE低电平  
	R1 = [R3]//R5 = [R3]             	//extract低电平 er byte 
//	R5 &= 0x00FF; 
	R1 = R1 lsl 4 
	r1 = R1 lsl 4 
	R5 |= R1 
	[Port_IOB_Data] = r5//[P_IOA_Data] =  R5 
 
	R5 |= WE_BIT// (RE_BIT|WE_BIT) 
//	R5 |= R2 
	[Port_IOB_Data] = R5 
	R5 = RE_BIT 
	R5 |= R2 
	[P_IOB_Data] = R5		//WE低电平 , RE高电平 , ALE低电平 	 
	R1 = [R3++]//R5 = [R3++]             //extract高电平 er byte 
//	R5 = R5 lsr 4 
//	R5 = R5 lsr 4 
	R1 &= 0xff00 
	R5 |= R1 
	[Port_IOB_Data] = r5//[P_IOA_Data] = R5 
	R5 |= WE_BIT//= (RE_BIT|WE_BIT) 
//	R5 |= R2 
	[Port_IOB_Data] = R5 
	R4 -= 2 
	jnz ?writeLp 
	nop 
	//.......start program process............... 
    M_StartProgram_1 R1,R2; 
     
    // Not checking status here	     
	M_RetrieveIoSetting_1; 
	pop R3, R5 from [SP] 
retf 
//-------------------------------------------------------------------- 
//-- 函数名: _SP_SamsungEraseBlock 
//-- 语法: SP_SamsungEraseBlock(Block address) 
//-- 参数: 
//--	R1 = Block address (0 - 1023). 
//--	Each block contains 16 pages = 8KBytes + 256 Bytes of spare space 
//-- 返回值: 
//--	R1 = 0 if success, R1 = 1 if failure 
//-------------------------------------------------------------------- 
_SP_SamsungEraseBlock: .proc 
    PUSH BP,BP TO [SP]; 
    BP = SP + 1; 
    R1 = [BP+3]; 
     
    call _SamsungEraseBlock 
 
    POP BP,BP FROM [SP]; 
	retf 
.endp 
//-------------------------------------------------------------------- 
//-- 函数名: _SamsungEraseBlock 
//-- 参数: 
//--	R1 = Block address (0 - 4095). 
//--	Each block contains 32 pages = 16KBytes + 512 Bytes of spare space 
//-- 返回值: 
//--	R1 = 0 if success, R1 = 1 if failure 
//-------------------------------------------------------------------- 
_SamsungEraseBlock: //.proc 
	push R2, R5 to [SP] 
	M_SaveIoSetting_1; 
	//......init port A0-A7 as output....... 
	M_InitIOAOut_1; 
	//......send 命令 .................... 
	R5 = SP 
	R3 = [R5+1]						//get the IOB statu}K 
	r3 &= BASE_MASK 
//	R4 = r3//[R5+2] 
	R5 = (CLE_BIT|RE_BIT) 
	R5 |= R3//R4 
	[Port_IOB_Data] = R5 
//	R5 = 0x0060 					//auto block erase setup 
	r2 = 0x6000 
	r2 |= r3//r4 
	r5 |= r2 
//	R5 |= R3 
	[Port_IOB_Data] = r5//[Port_IOA_Data] = R5 
	R5 |= WE_BIT//R5 = (CLE_BIT|RE_BIT|WE_BIT) 
	//R5 |= r4 
	[Port_IOB_Data] = R5			//WE高电平  
	R5 = (WE_BIT|ALE_BIT|RE_BIT)	//CLE低电平 , WE高电平 , ALE高电平 , RE高电平  
	R5 |= R2//R4 
	[Port_IOB_Data] = R5 
	//.....写地址..................... 
	R4 = (ALE_BIT|RE_BIT)//R4 |= (ALE_BIT|RE_BIT) 
	r4 |= r3				//add new line 
	[Port_IOB_Data] = R4			//WE低电平  
	R1 = R1 LSL 4 
	r1 = r1 lsl 1 
	r2 = r1 lsl 4 
	r2 = r2 lsl 4 
	R2 &= 0xff00//= //R1 & 0x00FF 
	R2 |= R4//R3 
	[Port_IOB_Data] = r2//[Port_IOA_Data] = R2			//Address9 - 16 
	r5 &= 0x00ff			//add new 
	r5 |= r2 				//add new 
	[Port_IOB_Data] = R5			//WE, ALE, RE高电平  
	[Port_IOB_Data] = R2//R4			//WE低电平  
//	R1 = R1 LSR 4 
//	R1 = R1 LSR 4 
	r2 = r1&0xff00 
	r4 &= 0x00ff 
	r2 = r2|r4 
//	R1 |= R3 
	[Port_IOB_Data] = r2//[Port_IOA_Data] = R1			//Address17 - 24 
	r5 &= 0x00ff			//add new 
	r5 |= r2 				//add new 
	[Port_IOB_Data] = R5			//WE, ALE高电平  
	 
	[Port_IOB_Data] = R2			//WE低电平  
	push r1 to [sp] 
	r1 = [R_Addr25]//0					//Edit by xinqiang 2004.12.20 从寄存器中读高位地址 
	//[Port_IOA_Data] = r1			//Address25 
	r1 = r1 lsl 4 
	r1 = r1 lsl 4 
	r1 = r1|r4 
	[Port_IOB_Data] = r1 
	r5 = r5&0x00ff 
	r5 |= r1 
	pop r1 from [sp] 
	[Port_IOB_Data] = R5			//WE, ALE高电平  
	 
//	R5 = SP 
//	R4 = [R5+2] 
	R5 = RE_BIT 
	R5 |= R3//R4 
	[Port_IOB_Data] = R5			//WE低电平 , RE高电平 , ALE低电平  
	//.......开始erase................. 
//	R1 = R3 
//	R2 = R4 
	R5 = (CLE_BIT|RE_BIT) 
	R5 |= R3//R2 
	[Port_IOB_Data] = R5			//WE低电平 , RE高电平 , CLE高电平  
	R4 = 0xd000//R5 = //0x00D0						//清除命令  
	R4 |= R5//R5 |= R1 
	[Port_IOB_Data] = r4//[Port_IOA_Data] = R5 
//	R5 = (CLE_BIT|RE_BIT|WE_BIT) 
//	R5 |= R2 
	r4 |= WE_BIT 
	[Port_IOB_Data] = R4//R5 
	//.......读status......................... 
//	R4 = (CLE_BIT|RE_BIT)	 
//	R4 |= R2 
	r5 |= 0xd000 
	[Port_IOB_Data] = R5//R4 
	r5 &= 0x00ff 
	R4 = r5|0x7000//0x0070						//获得status 
//	R4 |= R5//R1 
	[Port_IOB_Data] = R4			//WE低电平 , RE高电平 , CLE高电平  
//	R4 = (CLE_BIT|RE_BIT|WE_BIT) 
//	R4 |= R2 
	R4 |= WE_BIT 
	[Port_IOB_Data] = R4 
	//........把A0-A7初始化为输入............ 
	M_InitIOAIn_1; 
	//............................................ 
	R4 = WE_BIT 
	R4 |= R3//R2 
	R5 = (WE_BIT|RE_BIT) 
	R5 |= R3//R2 
?busyLp: 
	[Port_IOB_Data] = R4 
	R1 = [Port_IOB_Data]//[Port_IOA_Data] 
	[Port_IOB_Data] = R5 
	//R2 = R1 & 0x0040 
	test R1,0x4000 
	jz ?busyLp 
	R1 &= 0x0001 
    // 在这里处理erase错误 
    M_RetrieveIoSetting_1; 
	pop R2, R5 from [SP] 
	retf 
//.endp 
//-------------------------------------------------------------------- 
//-- 函数名: _SP_SamsungMassErase 
//-- 语法: SamsungMassEraseBlock() 
//-- 参数: 
//--	R1 = Block address (0 - 4095). 
//--	Each block contains 16 pages = 8KBytes + 256 Bytes of spare space 
//-- 返回值: 
//--	R1 = 0 if success, R1 >= 1 the # of block erase failures 
//-------------------------------------------------------------------- 
_SP_SamsungMassErase: .proc 
    push R2,R3 to [SP]; 
    R2 = C_BlockBin;    	// 全部Erase 
    R3 = 0;       			// #代表失败  
?L_EraseLoop: 
    R1 = R2;    
    call _SamsungEraseBlock 
   
    R3+=R1;   				// #代表失败 
?L_BlockEraseSuccess:  
    R2+=1; 
    cmp R2, C_MaxBlock; 
    jb ?L_EraseLoop; 
    R1 = R3; 
    pop R2,R3 from [SP]; 
    retf 
.endp 
//-------------------------------------------------------------------- 
//-- 宏名: MM_SendReadCmd 
//-- 参数: r1=column,r2=page, r3=portA,r4=portB 
//-- 发送 0x00, 0x01 or 0x50 
//-------------------------------------------------------------------- 
 
MM_SendReadCmd:.proc  
	r5 = sp 
	r4 = [r5+3]						//get the portB 
	r4 &= BASE_MASK 
	push r4 to [sp] 
	r4 |= (CLE_BIT|RE_BIT)			//CLE\RE hight 
	[Port_IOB_Data] = r4 
	r5 = 0x0000							//read cmd 0 
	cmp r1,256 
	jb ?MM_NotChArea 
	r1 -= 256 
	r5 = 0x0100							//read cmd 1 
	cmp r1,256 
	jb ?MM_NotChArea 
	r1 -= 256						//read cmd 2 
	r5 = 0x0500 
?MM_NotChArea: 
	r4 |= r5						//or the cmd 
	[Port_IOB_Data] = r4 
	r4 |= WE_BIT					//WE高电平 
	//nop 
	[Port_IOB_Data] = r4 
	r4 &= 0x00c0 
	r4 |= (WE_BIT|ALE_BIT|RE_BIT)	//CLE低电平 , WE高电平 , ALE高电平 , RE高电平  
	[Port_IOB_Data] = r4 
	//............写地址............... 
	r4 &= 0xffc0 
	r4 |= (ALE_BIT|RE_BIT)			//WE low 
	[Port_IOB_Data] = r4 
	r1 = r1 lsl 4 
	r1 = r1 lsl 4 
	r4 |= r1 
	[Port_IOB_Data] = r4			//addr0~7 
	r5 = r4|WE_BIT 
	[Port_IOB_Data] = r5 
//	nop										////////..... 
	[Port_IOB_Data] = r4 
	r1 = r2 lsl 4					//get the addr 
	r1 = r1 lsl 4 
	r4 &=0x00ff 
	r4 |= r1 
	r5 = r4|WE_BIT 
	[Port_IOB_Data] = r4			//addr9~16 
//	nop									/////...... 
	[Port_IOB_Data] = r5 
//	nop 
	[Port_IOB_Data] = r4 
	r1 = r2&0xff00 
	r4 &= 0x00ff 
	r4 |= r1 
	r5 = r4|WE_BIT 
	[Port_IOB_Data] = r4			//Addr17~24 
//	nop 
	[Port_IOB_Data] = r5 
//	nop									////..... 
	[Port_IOB_Data] = r4 
	 
	r1 = [R_Addr25] 
	r1 = R1 lsl 4 
	r1 = r1 lsl 4 
	r4 = r4 & 0x00ff 
	r4 |= r1 
	r5 = r4|WE_BIT 
	[Port_IOB_Data] = r4 
//	nop												////...... 
	[Port_IOB_Data] = r5 
	r1 = 0xffff 
	r1 = r1^ALE_BIT 
	r5 &= r1 
	[Port_IOB_Data] = r5 
	pop r4 from [sp] 
	retf 
.endp 
 
//-------------------------------------------------------------------- 
//-- 宏名: MM_SendWriteCmd 
//-- 参数: column,page,portA,portB 
//-- 发送 0x80 
//-------------------------------------------------------------------- 
MM_SendWriteCmd: .proc 
	r5 = sp 
	r4 = [r5+3]						//get the portB 
	r4 &= BASE_MASK 
	push r4 to [sp] 
	r4 |= (CLE_BIT|RE_BIT)			//CLE\RE hight 
	[Port_IOB_Data] = r4 
	r5 = 0x0000							//read cmd 0 
	cmp r1,256 
	jb ?MM_NotChArea_W 
	r1 -= 256 
	r5 = 0x0100							//read cmd 1 
	cmp r1,256 
	jb ?MM_NotChArea_W 
	r1 -= 256						//read cmd 2 
	r5 = 0x0500 
?MM_NotChArea_W: 
	r4 |= r5						//or the cmd 
	[Port_IOB_Data] = r4 
	r4 |= WE_BIT					//WE高电平 
	[Port_IOB_Data] = r4 
	r4 &= 0x00c0 
	R4 |= (CLE_BIT|RE_BIT)  
	[Port_IOB_Data] = R4 
	R4 |= 0x8000 					 // 连续数据输入命令  
	[Port_IOB_Data] = R4 
	R4 |= WE_BIT 
	[Port_IOB_Data] = R4			//WE高电平  
	r4 &= 0x00c0 
	r5 = r4|(ALE_BIT|RE_BIT) 
	R4 |= (WE_BIT|ALE_BIT|RE_BIT)	//CLE低电平 , WE高电平 , ALE高电平 , RE高电平  
	[Port_IOB_Data] = R4 
	//.....写地址..................... 
	[Port_IOB_Data] = r5//portB			//WE低电平  
	r1 = r1 lsl 4 
	r1 = r1 lsl 4 
	r5 |= r1 
	[Port_IOB_Data] = r5//column		//Address0 - 7 
	r4 |= r1 
	[Port_IOB_Data] = R4			//WE, ALE, RE高电平  
	[Port_IOB_Data] = r5			//WE低电平  
	r1 = r2 lsl 4 
	r1 = r1 lsl 4 
	r5 &= 0x00ff 
	r5 |= r1 
	[Port_IOB_Data] = R5		//Address9 - 16 
	r4 &= 0x00ff 
	r4 |= r1 
	[Port_IOB_Data] = r4			//WE, ALE高电平  
	[Port_IOB_Data] = r5			//WE低电平  
	r2 &= 0xff00 
	r5 &= 0x00ff 
	r5 |= r2 
	[Port_IOB_Data] = r5		//Address17 - 22 
	r4 &= 0x00ff 
	r4 |= r2 
	[Port_IOB_Data] = R4		//WE, ALE高电平 	 
//for debug,no a25 
	[Port_IOB_Data] = R5		//WE低电平  
	r1 = [R_Addr25]//0					//Edit by xinqiang 2004.12.20 从寄存器中读取高位地址 
	r1 = r1 lsl 4 
	r1 = r1 lsl 4 
	r5 &= 0x00ff 
	r5 |= r1 
	[Port_IOB_Data] = r5			//Address25 
	r4 &= 0x00ff 
	r4 |= r1 
	[Port_IOB_Data] = R4		//WE, ALE高电平  
// 
	pop r4 from [sp] 
	retf 
.endp 
//-------------------------------------------------------------------- 
//-- 函数名: _SamsungGetStatus_1		得到Flash 状态 
//-- 参数: 无 
//-- 返回值: R1 = Status. 
//2004.12.23   Edit by xinqiang zhang  for change IO 
//-------------------------------------------------------------------- 
_SamsungGetStatus_1: //.proc 
	push R2, R5 to [SP] 
    M_SaveIoSetting_1; 
	//......init port A0-A7 as output....... 
	M_InitIOAOut_1; 
	//......send 命令 .................... 
	R5 = SP 
	R2 = [R5+1]					//portA 
	r2 &= BASE_MASK 
	r3 = r2 
//	R3 = [R5+2]					//portB 
	R4 = (CLE_BIT|RE_BIT) 
	R4 |= R2 
	[Port_IOB_Data] = R4 
	R5 = 0x7000//0x0070  				//read0 命令  
	R5 |= r4//R2 
//	r2 = r2|r5 
	[Port_IOB_Data] = R5 
	R5 |= WE_BIT 
	[Port_IOB_Data] = R5		//WE高电平  
	R4 = (WE_BIT|RE_BIT)		//CLE低电平 , WE高电平 , RE高电平  
	R4 |= R2 
	[Port_IOB_Data] = R4 
	//.....init port A0-A7 as input.......... 
	M_InitIOAIn_1; 
	//....................................... 
	R4 = WE_BIT					//RE低电平  
	R4 |= R3 
	[Port_IOB_Data] = R4 
	nop 
	R1 = [Port_IOB_Data]		 
	R1 &= 0xff00 
	r1 = r1 lsr 4 
	r1 = r1 lsr 4 
	M_RetrieveIoSetting_1; 
	pop R2, R5 from [SP] 
	retf