/*  Tilem, TI-Linux Emulator
 *  Copyright (C) 2001 Solignac Julien <x1cygnus@xcalc.org>
 *  Portions copyright (C) 2004 Benjamin Moody <benjamin@ecg.mit.edu>
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License as published by the Free Software Foundation; either
 *  version 2.1 of the License, or (at your option) any later version.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */


INLINE void LCDDriver(byte val)
{
	extern byte lcdactive;
	extern byte lcdshow;

	if (val <= 1) {
		lcdmode = val;

	} else if (val == 2) {
		lcdactive = 0;

	} else if (val == 3) {
		if (!(lcdactive))
			lcdactive = lcdshow = 1;

	} else if (val <= 7) {
		lcdinc = val;

	} else if ((val >= 0x20) && (val <= 0x2F)){
		xlcd = val - 0x20;
		lcddummyread = 1;

	} else if ((val >= 0x80) && (val <= 0xBF)) {
		ylcd = val - 0x80;
		lcddummyread = 1;
	}

	return;
}


INLINE byte LCDIn()
{
	byte retv=lcddummyread;

	if (xlcd >= 0x10)
		xlcd = 0;
	if (ylcd >= 0x40)
		ylcd = 0;

	if (lcdmode) {
		if (xlcd >= 0x0C)
			return(retv);
		lcddummyread = *(lcdbuf + xlcd + 0x0C * ylcd);

	} else {
		int col = 0x06 * xlcd;
		int ofs = ylcd * 0x0C + (col >> 3);
		int shift = 0x0A - (col & 0x07);

		lcddummyread = ((*(lcdbuf + ofs) << 8) | *(lcdbuf + ofs + 1)) >> shift;
	}

	switch (lcdinc) {
		case 4: ylcd--; break;
		case 5: ylcd++; break;
		case 6: xlcd--; break;
		case 7: xlcd++; break;
	}

	return(retv);
}


INLINE void LCDOut(byte sprite)
{
/*	lcdinit = 1;*/

	if (xlcd >= 0x10)
		xlcd = 0;
	if (ylcd >= 0x40)
		ylcd = 0;

	if (lcdmode) {
		if (xlcd >= 0x0C) return;
		*(lcdbuf + xlcd + 0x0C * ylcd) = sprite;
/* Another one I owe To Rusty... */

	} else {
/* Thanks goes to Rusty Wagner's vti, I wouldn't have known
 * this screen mode existed without it */
		int col = 0x06 * xlcd;
		int ofs = ylcd * 0x0C + (col >> 3);
		int shift = col & 0x07;
		int mask;

		sprite <<= 2;
		mask = ~(0xFC >> shift);
		*(lcdbuf + ofs) = (*(lcdbuf + ofs) & mask) | (sprite >> shift);
		if (shift > 2) {
			ofs++;
			shift = 8 - shift;
			mask = ~(0xFC << shift);
			*(lcdbuf + ofs) = (*(lcdbuf + ofs) & mask) | (sprite << shift);
		}
	}

	switch (lcdinc) {
		case 4: ylcd--; break;
		case 5: ylcd++; break;
		case 6: xlcd--; break;
		case 7: xlcd++; break;
	}

	return;
}
