BOOL __section("SectionForFlashOperations")I28F_16_BS_Driver::WriteX(void* context, ByteAddress StartSector, UINT32 NumBytes, BYTE * pSectorBuff, BOOL ReadModifyWrite, BOOL fIncrementDataPtr)
{
    NATIVE_PROFILE_PAL_FLASH();

    volatile CHIP_WORD * ChipAddress;
    BOOL result= TRUE;
    CHIP_WORD * pData = (CHIP_WORD*)pSectorBuff;

    MEMORY_MAPPED_NOR_BLOCK_CONFIG* config = (MEMORY_MAPPED_NOR_BLOCK_CONFIG*)context;

    // if write protected, no update
    const BlockDeviceInfo * deviceInfo = config->BlockConfig.BlockDeviceInformation;
    if (deviceInfo->Attribute.WriteProtected) return FALSE;

    ChipAddress = (volatile CHIP_WORD *)CPU_GetUncachableAddress(StartSector);

    ChipReadOnly( config, FALSE, FLASH_PROTECTION_KEY );

    for(UINT32 i = 0; i < NumBytes; i += sizeof(CHIP_WORD), ChipAddress++)
    {

        // if same, nothing to do, continue nextword.
        if(*ChipAddress != *pData) 
        {
            // check for having to move bits from 0->1, a failure case for a write
            if(0 != (*pData & ~(*ChipAddress)))
            {
                debug_printf( "erase failure: 0x%08x=0x%04x\r\n", (size_t)ChipAddress, *ChipAddress );
                ASSERT(0);
                result =FALSE;
                break;
            }

            CHIP_WORD StatusRegister = Action_WriteWord( ChipAddress, *pData, config );

            if(0 != (StatusRegister & ~SR_WSM_READY))
            {
                debug_printf( "Flash_WriteWord(0x%08x): Status Register non-zero after word program: 0x%08x\r\n", (UINT32)ChipAddress, StatusRegister );
                result= FALSE;
                break;
            }
            
            if (*ChipAddress != *pData)
            {
                debug_printf( "Flash_WriteToSector failure @ 0x%08x, wrote 0x%08x, read 0x%08x\r\n", (UINT32)ChipAddress, *pData, *ChipAddress );
                result = FALSE;
                break;
            }
        }

        if(fIncrementDataPtr) pData++;
    }

    ChipReadOnly(config, TRUE, FLASH_PROTECTION_KEY);
    
    return result;
}
BOOL __section(SectionForFlashOperations) AM29DL_16_BS_Driver::WriteX(void* context, ByteAddress address, UINT32 numBytes, BYTE * pSectorBuff, BOOL ReadModifyWrite, BOOL fIncrementDataPtr)
{
    NATIVE_PROFILE_PAL_FLASH();

    MEMORY_MAPPED_NOR_BLOCK_CONFIG* config = (MEMORY_MAPPED_NOR_BLOCK_CONFIG*)context;
    const BlockDeviceInfo *    deviceInfo = config->BlockConfig.BlockDeviceInformation;

    CHIP_WORD* ChipAddress;
    CHIP_WORD* EndAddress, *pData;
    BOOL result = TRUE;


    if (deviceInfo->Attribute.WriteProtected) return FALSE;

    address = CPU_GetUncachableAddress(address);

    ChipAddress = (CHIP_WORD *)address;
    EndAddress  = (CHIP_WORD *)(address + numBytes); 
    pData       = (CHIP_WORD *)pSectorBuff;

   
    ChipReadOnly(config, FALSE, FLASH_PROTECTION_KEY);

    while(ChipAddress < EndAddress)
    {
       // if same, nothing to do, continue nextword.
       if(*ChipAddress != *pData) 
       {
            // check for having to move bits from 0->1, a failure case for a write
            if(0 != (*pData  & ~(*ChipAddress)))
            {
                debug_printf( "Write X erase failure: 0x%08x=0x%04x\r\n", (size_t)ChipAddress, *ChipAddress );
                ASSERT(0);
                result =FALSE;
                break;
            }

            Action_WriteWord( config, ChipAddress, *pData );

            
            if (*ChipAddress != *pData)
            {
                debug_printf( "Flash_WriteToSector failure @ 0x%08x, wrote 0x%08x, read 0x%08x\r\n", (UINT32)ChipAddress, *pData, *ChipAddress );
                result = FALSE;
                break;
            }
        }

        ChipAddress++;
        if(fIncrementDataPtr) pData++;    
    }

    ChipReadOnly(config, TRUE, FLASH_PROTECTION_KEY);
    
    return result;
}