/*
 * Development vehicle for SG4 graphics lib for CoCo
 */

#include <6809io.h>

#define CURPOS		((unsigned int *)0x0088)
#define	TXTBASE		((unsigned int *)0x0400)
#define	TXTWIDTH	32
#define	TXTLINES	16
#define	TXTSIZE		((unsigned int)TXTWIDTH*TXTLINES)
#define	TXTEND		(TXTBASE+TXTSIZE)

#define	SG4MASK(x,y)	(1<<(3-(((y&1)<<1)|(x&1))))

void cls(unsigned char color)
{
	unsigned char *pos, val;

	if (color == 0)
		val = 0x80;
	else
		val = 0x8f | ((color - 1) << 4);

	for (pos = TXTBASE; pos < TXTEND; pos++)
		*pos = val;
}

void curpos(unsigned int val)
{
	if (val > TXTSIZE)
		abort("INVALID CURPOS!");

	*CURPOS = TXTBASE + val;
}

void clrscn(void)
{
	cls(1);
	curpos(0);
}

static unsigned char *_getpos(unsigned char x, unsigned char y)
{
	unsigned char *pos;

	/*
	 * Hand-optimized expression, equivalent to this:
	 *
	 * pos = TXTBASE + ((y / 2) * TXTWIDTH) + (x / 2);
	 *
	 */
	pos = TXTBASE + ((y & 0xfe) << 4) + (x >> 1);

	if (pos > TXTEND)
		return NULL;

	return pos;
}

void set(unsigned char x, unsigned char y, unsigned char color)
{
	unsigned char *pos, val;

	pos = _getpos(x, y);
	if (!pos)
		return;

	val = *pos;
	if (!(val & 0x80))
		val = 0x80;

	val |= SG4MASK(x, y);

	val &= 0x8f;
	val |= ((color - 1) << 4);

	*pos = val;
}

void reset(unsigned char x, unsigned char y)
{
	unsigned char *pos, val;

	pos = _getpos(x, y);
	if (!pos)
		return;

	val = *pos;
	if (!(val & 0x80)) {
		val = 0x80;
		goto exit;
	}

	val &= ~SG4MASK(x, y);

exit:
	*pos = val;
}

char point(unsigned char x, unsigned char y)
{
	unsigned char *pos, val;

	pos = _getpos(x, y);
	if (!pos)
		return;

	val = *pos;
	if (!(val & 0x80))
		return -1;

	if (val & SG4MASK(x, y))
		return (((val & 0x70) >> 4) + 1);

	return 0;
}

void main()
{
	unsigned char h, v;

	clrscn();
	putstr("PRESS ANY KEY...");
	getchr();

	cls(0);

	curpos(397);
	putstr("HELLO");

	for (h=15; h<=48; h++) {
		set(h, 5, 5);
		set(h, 20, 5);
	}

	for (v=5; v<=20; v++) {
		set(15, v, 5);
		set(48, v, 5);
	}

	set(32, 13, 8);

	for (h=28; h<=36; h++) {
		set(h, 16, 4);
	}

	set(25, 10, 3);

	while (!chkch()) {
		set(38, 10, 3);
		reset(38, 10);
	}
}
