/** \file memory.c:
 * Contains wrapper functions for continuous adressation of bankstick and
 * the edit buffer array.
 */

/**
 *  realizes continuous adressation of bankstick with 3-byte long adress.
 *  first byte of "adress" sets chip nr. on bankstick
 *  \param adress range from 0x00000 to 0x7FFFF
 *  \param value is written at "adress" in bankstick
 */

void writeBank(unsigned long address,unsigned char value) {
	unsigned char err=0;

	if (address >= MAX_MEM)
		return;
	if(address<0x80000L && bankstick==1) {
		MIOS_IIC_Stop();
		MIOS_Delay(10);
		MIOS_DOUT_PinSet(7, 0);
		bankstick=0;
		MIOS_Delay(10);
		MIOS_IIC_Start();
		MIOS_Delay(10);
	} else
	if(address>=0x80000L && bankstick==0) {
		MIOS_IIC_Stop();
		MIOS_Delay(10);
		MIOS_DOUT_PinSet(7, 1);
		bankstick=1;
		MIOS_Delay(10);
		MIOS_IIC_Start();
		MIOS_Delay(10);
	}
	//if (bankchip != (address >> 16))						// select BankChip
	MIOS_BANKSTICK_CtrlSet(bankchip=(address>>16));
	again: MIOS_BANKSTICK_Write(address, value);
	if( !MIOS_BOX_STAT.BS_AVAILABLE ) {
		if(++err<=3)
			goto again;
		//else
			//debug("bs_write_err");
	}
}



/**
 * one byte is read from bankstick at "adress"
 * realizes continuous adressation of bankstick with 3-byte long adress.
 * first byte of "adress" sets chip nr. on bankstick
 * 	\param adress range from 0x00000 to 0x7FFFF
 * 	\return byte which was read from bankstick
 */
unsigned char readBank(unsigned long address) {
	unsigned char err=0;
	unsigned char ret;
	unsigned char switched=0;

	if (address >= MAX_MEM) {
		MIOS_BOX_STAT.BS_AVAILABLE=0;
		return 0;
	}
	if(address<0x80000L && bankstick==1) {
		MIOS_IIC_Stop();
		MIOS_Delay(2);
		MIOS_DOUT_PinSet(7, 0);
		bankstick=0;
		switched=1;
		MIOS_Delay(2);
		MIOS_IIC_Start();
		MIOS_Delay(2);
	} else
	if(address>=0x80000L && bankstick==0) {
		MIOS_IIC_Stop();
		MIOS_Delay(2);
		MIOS_DOUT_PinSet(7, 1);
		bankstick=1;
		switched=1;
		MIOS_Delay(2);
		MIOS_IIC_Start();
		MIOS_Delay(2);
	}
	//if (bankchip != (address >>16))						// select BankChip
	MIOS_BANKSTICK_CtrlSet(bankchip=(address>>16));
	again: ret=MIOS_BANKSTICK_Read(address);
	if( !MIOS_BOX_STAT.BS_AVAILABLE ) {
			if(++err<=3)
				goto again;
			//else
				//debug("bs_read_err");
	}
	return ret;
}


/**
 *  realizes continuous writing/reading of bytestream to/from bankstick:
 *  one byte is written/read to/from bankstick at "mem_adress",
 *  which is then incremented
 *  \param byte is written into bankstick at location of global variable mem_adress
 */
void writeStream (unsigned char byte) {
	writeBank (mem_adress, byte);
	++mem_adress;
}

/**
 * reads byte from bankstick from the location of the global variable mem_adress
 * \return byte which was read from bankstick
 */
unsigned char readStream (void) {
 	mem_adress++;
  	return readBank (mem_adress-1);
}

/**
 * combines 8 small arrays into one big edit buffer array of the size 2k
 * writes one byte into this big "array"
 * \param adress adress in new "array" from 0x000 to 0x800
 * \param value value which is put into edit buffer
 */
void writeEditBuffer(int address, char value) {
	if (0<=address && address<256)
		edit_buffer0[address]=value;
	if (256<=address && address<512)
		edit_buffer1[address]=value;
	if (512<=address && address<768)
		edit_buffer2[address]=value;
	if (768<=address && address<1024)
		edit_buffer3[address]=value;
	if (1024<=address && address<1280)
		edit_buffer4[address]=value;
	if (1280<=address && address<1536)
		edit_buffer5[address]=value;
	if (1536<=address && address<1792)
		edit_buffer6[address]=value;
	if (1792<=address && address<2048)
		edit_buffer7[address]=value;
	if (address>=2048)
		return;
}

/**
 * combines 8 small arrays into one big edit buffer array of the size 2k
 * writes one byte into this big "array"
 * \param adress adress in new "array" from 0x000 to 0x800
 * \return value which was read from edit buffer
 */
char readEditBuffer(int address) {
	if (0<=address && address<256)
		return edit_buffer0[address];
	if (256<=address && address<512)
		return edit_buffer1[address];
	if (512<=address && address<768)
		return edit_buffer2[address];
	if (768<=address && address<1024)
		return edit_buffer3[address];
	if (1024<=address && address<1280)
		return edit_buffer4[address];
	if (1280<=address && address<1536)
		return edit_buffer5[address];
	if (1536<=address && address<1792)
		return edit_buffer6[address];
	if (1792<=address && address<2048)
		return edit_buffer7[address];
	return 0;
}
