📄 sst39vf400a.txt
字号:
/************************************************************************/
/* PROCEDURE: Program_One_Sector */
/* */
/* This procedure can be used to program a total of 2048 words of data */
/* to the SST39VF400A. */
/* */
/* Input: */
/* Src SOURCE address containing the data which will be */
/* written to the 39VF400A */
/* Dst DESTINATION address which will be written with the */
/* data passed in from Src */
/* */
/* Output: */
/* None */
/************************************************************************/
void Program_One_Sector (WORD far *Src, WORD far *Dst)
{
WORD far *Temp;
WORD far *SourceBuf;
WORD far *DestBuf;
int Index;
SourceBuf = Src;
DestBuf = Dst;
Erase_One_Sector(Dst); /* erase the sector first */
for (Index = 0; Index < SECTOR_SIZE; Index++)
{
Temp = (WORD far *)0xC0005555;
/* set up address to be C000:555h */
*Temp = 0xAAAA;
/* write data 0xAAAA to the address */
Temp = (WORD far *)0xC0002AAA;
/* set up address to be C000:2AAAh */
*Temp = 0x5555;
/* write data 0x5555 to the address */
Temp = (WORD far *)0xC0005555;
/* set up address to be C000:5555h */
*Temp = 0xA0A0;
/* write data 0xA0A0 to the address */
Temp = DestBuf;
/* save the original Destination address */
*DestBuf++ = *SourceBuf++;
/* transfer data from source to destination */
Check_Toggle_Ready(Temp);
/* wait for TOGGLE bit to get ready */
}
}
/************************************************************************/
/* PROCEDURE: Program_One_Block */
/* */
/* This procedure can be used to program a total of 32k words of data */
/* to the SST39VF400A. */
/* */
/* Input: */
/* Src SOURCE address containing the data which will be */
/* written to the 39VF400A */
/* Dst DESTINATION address which will be written with the */
/* data passed in from Src */
/* */
/* Output: */
/* None */
/************************************************************************/
void Program_One_Block (WORD far *Src, WORD far *Dst)
{
WORD far *Temp;
WORD far *SourceBuf;
WORD far *DestBuf;
int Index;
SourceBuf = Src;
DestBuf = Dst;
Erase_One_Block(Dst); /* erase the sector first */
for (Index = 0; Index < BLOCK_SIZE; Index++)
{
Temp = (WORD far *)0xC0005555;
/* set up address to be C000:555h */
*Temp = 0xAAAA;
/* write data 0xAAAA to the address */
Temp = (WORD far *)0xC0002AAA;
/* set up address to be C000:2AAAh */
*Temp = 0x5555;
/* write data 0x5555 to the address */
Temp = (WORD far *)0xC0005555;
/* set up address to be C000:5555h */
*Temp = 0xA0A0;
/* write data 0xA0A0 to the address */
Temp = DestBuf;
/* save the original Destination address */
*DestBuf++ = *SourceBuf++;
/* transfer data from source to destination */
Check_Toggle_Ready(Temp);
/* wait for TOGGLE bit to get ready */
}
}
/************************************************************************/
/* PROCEDURE: Check_Toggle_Ready */
/* */
/* During the internal program cycle, any consecutive read operation */
/* on DQ6 will produce alternating 0's and 1's (i.e. toggling between */
/* 0 and 1). When the program cycle is completed, DQ6 of the data will */
/* stop toggling. After the DQ6 data bit stops toggling, the device is */
/* ready for next operation. */
/* */
/* Input: */
/* Dst must already be set-up by the caller */
/* */
/* Output: */
/* None */
/************************************************************************/
void Check_Toggle_Ready (WORD far *Dst)
{
BYTE Loop = TRUE;
WORD PreData;
WORD CurrData;
unsigned long TimeOut = 0;
PreData = *Dst;
PreData = PreData & 0x4040;
while ((TimeOut< 0x07FFFFFF) && (Loop))
{
CurrData = *Dst;
CurrData = CurrData & 0x4040;
if (PreData == CurrData)
Loop = FALSE; /* ready to exit the while loop */
PreData = CurrData;
TimeOut++;
}
}
/************************************************************************/
/* PROCEDURE: Check_Data_Polling */
/* */
/* During the internal program cycle, any attempt to read DQ7 of the */
/* last byte loaded during the page/byte-load cycle will receive the */
/* complement of the true data. Once the program cycle is completed, */
/* DQ7 will show true data. */
/* */
/* Input: */
/* Dst must already be set-up by the caller */
/* True Data is the original (true) data */
/* */
/* Output: */
/* None */
/************************************************************************/
void Check_Data_Polling (WORD far *Dst, WORD TrueData)
{
BYTE Loop = TRUE;
WORD CurrData;
unsigned long TimeOut = 0;
TrueData = TrueData & 0x8080;
while ((TimeOut< 0x07FFFFFF) && (Loop))
{
CurrData = *Dst;
CurrData = CurrData & 0x8080;
if (TrueData == CurrData)
Loop = FALSE; /* ready to exit the while loop */
TimeOut++;
}
}
8086 ASSEMBLY LANGUAGE DRIVERS
; ======================================================================
; Copyright Silicon Storage Technology, Inc. (SST), 1994-2001
; EXAMPLE 8086 assembly Drivers for SST39VF400A 4 Mbit MultiPurpose Flash
; Frank Cirimele, Silicon Storage Technology, Inc.
;
; Revision 1.0, Sept. 12, 2001
;
; This file requires these external "timing" routines:
;
; 1.) Delay_150_Nano_Seconds
; 2.) Delay_25_Milli_Seconds
; 3.) Delay_100_Milli_Seconds
; ======================================================================
SECTOR_SIZE EQU 2048 ; Must be 4096 bytes for SST39VF400A
BLOCK_SIZE EQU 32768
SST_ID EQU 00BFh ; SST Manufacturer's ID code
SST_SST39VF400A EQU 2780h ; SST SST39VF400A internal code, and
; is same device code as SST39VF400
ABS_SEGMENT EQU 0C000h
extrn Delay_150_Nano_Seconds:near
extrn Delay_25_Milli_Seconds:near
extrn Delay_100_Milli_Seconds:near
;=======================================================================
; PROCEDURE: Check_SST_SST39VF400A
;
; This procedure decides whether a physical hardware device has a
; SST39VF400A 4 Mbit Multi-Purpose Flash installed or not.
;
; Input:
; None
;
; Output:
; carry bit: CLEARED means a SST39VF400A is installed
; carry bit: SET means a SST39VF400A is NOT installed
;
;=======================================================================
Check_SST_SST39VF400A proc near
push ax ; save registers
push ds
pushf ; save interrupt state
; It is mandatory to maintain pushf as the last push instruction.
cli ; disable interrupts
mov ax, ABS_SEGMENT ; set up data segment
mov ds, ax
mov ds:word ptr [5555h], 0AAAAh ; issue the 3-byte product ID
mov ds:word ptr [2AAAh], 05555h ; command to the SST39VF400A
mov ds:word ptr [5555h], 09090h
call Delay_150_Nano_Seconds ; insert delay = Tida
mov ax, ds:[0]
cmp ax, SST_ID ; is this a SST part?
jne CSC5 ; NO, then return Carry set
mov ax, ds:[1]
cmp ax, SST_SST39VF400A ; is it a SST39VF400A?
jne CSC5 ; NO, then Non-SST part and
; set Carry flag
CSC4:
pop ax ; get flags from stack
and ax, 0FFFEh ; and clear carry flag
jmp short CSC6
CSC5:
pop ax ; get flags from stack
or ax, 0001h ; and set carry flag
CSC6:
push ax ; return flags to stack
;
; Issue the Software Product ID Exit code thus returning the SST39VF400A
; to the read operation mode.
;
mov ds:word ptr [5555h], 0AAAAh ; issue the 3-byte product ID
mov ds:word ptr [2AAAh], 05555h ; exit command to the
mov ds:word ptr [5555h], 0F0F0h ; SST39VF400A
call Delay_150_Nano_Seconds ; insert delay = Tida
popf ; restore flags
pop ds ; restore registers
pop ax
ret
Check_SST_SST39VF400A endp
;=======================================================================
; PROCEDURE: CFI_Query
;
; This procedure provides access to the CFI information embedded within
; the SST39VF400A 4 Mbit Multi-Purpose Flash device.
;
; Input:
; None
;
; Output:
; None
;
;=======================================================================
CFI_Query proc near
pushf ; save interrupt state
push ax ; save registers
push ds
cli ; disable interrupts
mov ax, ABS_SEGMENT ; set up the ds register
mov ds, ax
mov ds:word ptr [5555h], 0AAAAh ; issue the 3-byte product ID
mov ds:word ptr [2AAAh], 05555h ; command to the SST39VF400A
mov ds:word ptr [5555h], 09898h
call Delay_150_Nano_Seconds ; insert delay = Tida
; -----------------------------------
; Perform all CFI operations here
; NOTE: NO sample code provided
; -----------------------------------
mov ds:word ptr [5555h], 0AAAAh ; issue the 3-byte product ID
mov ds:word ptr [2AAAh], 05555h ; exit command to the SST39VF400A
mov ds:word ptr [5555h], 0F0F0h
call Delay_150_Nano_Seconds ; insert delay = Tida
pop ds ; restore registers
pop ax
popf ; restore flags
ret
CFI_Query endp
; =====================================================================
; PROCEDURE: Erase_One_Sector
;
; This procedure can be used to erase a sector, or total of 2048 bytes,
; in the SST39VF400A.
;
; Input:
; es:di points to the beginning address of the "Destination"
; sector which will be erased.
; ==> Note: The address MUST be on a sector boundary,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -