							/* BCBUG1.C
******************************************************************************
	ANOMALY IN BORLAND C VERSION 3.1

	The "Move invariant code out of loops" optimization causes
	functions that deal with volatile data to fail.
*****************************************************************************/
#include	<dos.h>	/* MK_FP() */

#define		EEPROM_SEG	0x2000

typedef unsigned char		byte;
typedef volatile unsigned char	vbyte;	/* 'volatile' doesn't help */
typedef unsigned		word;
/*****************************************************************************
	name:	writeEEPROMBytes
	action:	writes NumOfBytes bytes at Src into parallel EEPROM
		at offset Offset
	returns:zero if success, -1 if error
*****************************************************************************/
int writeEEPROMBytes(word NumOfBytes, byte *Source, word Offset)
{	byte far *Src;
	vbyte far *Dst;
	word Await;

	Src=(byte far *)Source;
	Dst=(vbyte far *)MK_FP(EEPROM_SEG, Offset);
	for(; NumOfBytes; NumOfBytes--)
/* if the EEPROM already has this value in it, skip this byte (saves wear) */
	{	if(*Dst != *Src)
		{	*Dst=*Src;
/* ... else write it & read it repeatedly until it verifies (D7 polling) */
			for(Await=0x1FFF; Await; Await--)
/***********
	In the following line, *Dst gets cached as a local, temporary,
	byte variable, instead of being re-read from EEPROM. This happens
	despite the use of the 'volatile' keyword.

	The "Move invariant code out of loops" (-Om for BCC) causes this
	bug to materialize.
************/
				if(*Dst == *Src) break;
			if(Await == 0) return(-1); }	/* failure, return */
		Dst++;					/* OK, next byte */
		Src++; }
	return(0); }
/*****************************************************************************
	name:	main
*****************************************************************************/
void main(void)
{	writeEEPROMBytes(6, "Hello", 0); }

