/* System VIA implementation */

#include "utils.h"		// For kbmap
#include "Registry.h"		// For SetKeyEvent

static void SYSVIA_KeyEvent (int row, int col, SYSVIA *via)
{
	via->DoKey (row, col);
}

void SYSVIA::DoKey (int row, int col)
{
	if (row < 0)
	{
		switch (col)
		{
			case 0:
			printf ("Break!\n");
			cur_model->Break ();
			break;
			
			case 1:
			cur_model->Reset ();
			break;
		}
	}
	else
		DoKbdCheck ();
}

SYSVIA::SYSVIA (void): VIA6522 (0xffe0, 0xfe40)
{
	SetKeyEvent (SYSVIA_KeyEvent, this);
}

SYSVIA::~SYSVIA (void)
{
	SetKeyEvent (NULL, NULL);
}

void SYSVIA::PinAchange (void)
{
	if (latch_KBEN)
	{
		//printf ("kb check %d %d\n", PinA & 0x0f, (PinA >> 4) & 0x07);
		DoKbdCheck ();
		if (kbmap[PinA & 0x0f][(PinA >> 4) & 0x07])
		{
			//printf ("kb succ %d %d\n", PinA & 0x0f, (PinA >> 4) & 0x07);
			PinA |= 0x80;
		}
		else
			PinA &= ~0x80;
	}
}

void SYSVIA::PinBchange (void)
{
	switch (PinB & 0x07)
	{
		case 0:		// Sound chip
		/*latch_SOUND = (PinB & 0x08) ? 0 : 1;
		if (latch_SOUND)
			sound->Write (PinA);*/
		break;
		
		case 3:		// Keyboard
		latch_KBEN = (PinB & 0x08) ? 0 : 1;
		DoKbdCheck ();
		break;
		
		case 4:		// C0
		/*wrap_code = (wrap_code & 2) | ((PinB & 0x08) ? 1 : 0);
		Set_Wrap ();*/
		break;
		
		case 5:		// C1
		/*wrap_code = (wrap_code & 1) | ((PinB & 0x08) ? 2 : 0);
		Set_Wrap ();*/
		break;
	}
}

void SYSVIA::DoKbdCheck (void)
{
	int keysdown = 0, i, j;
	static int old_keysdown = 0;
	
	if (latch_KBEN)
	{
		for (i = 1; i < 8; i++)
			if (kbmap[PinA & 0x0f][i])
				break;
		if (i < 8)
			SetCA2 (1);
		else
			SetCA2 (0);
	}
	else
	{
		for (i = 0; i < 0x10; i++)
		{
			for (j = 1; j < 8; j++)
				if (kbmap[i][j])
				{
					keysdown = 1;
					break;
				}
			if (j < 8)
				break;
		}
		if (keysdown)
			SetCA2 (1);
		else if (!keysdown && old_keysdown)
			SetCA2 (0);
		old_keysdown = keysdown;
	}
}

void SYSVIA::SignalInt (void)
{
	SignalIRQ (IRQ_SYSVIA);
}

void SYSVIA::ClearInt (void)
{
	ClearIRQ (IRQ_SYSVIA);
}

void SYSVIA::Break (void)
{
	// Do nothing
}

/* End of file. */
