/*  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
 */

#include "../../../config.h"

#include<gtk/gtk.h>

#ifndef __WIN32__
# include<unistd.h>
#endif

#ifndef USLEEP
# if HAVE_USLEEP
#  define USLEEP usleep
# else
#  define USLEEP g_usleep
# endif
#endif

/* >>> Resources */
/* Resources <<< */


/* >>> Concat */
#include "Z80.c"
#include "Z80Debug.c"
/* Concat <<< */




/* >>> Globals */
G_LOCK_DEFINE(runctrl);
G_LOCK_DEFINE(running);
volatile byte running;
byte *lcdbuf;
/* Globals <<< */


/* >>> Exported */
void *core(void *sdebug)
{
	G_LOCK_EXTERN(ctrlspeed);
	G_LOCK_EXTERN(cleanquit);
	extern byte ctrlspeed;

	GTimer *freqmeter;
	gulong timereg;
	glong timediff=0;
/* I don't know whether I'll have to use Gdk_Threads_Enter to use the timer
 * so for the moment I'll leave it out and 'wait and see'... */

	/* jcdebug = (pid_t) sdebug; */
	running = 1;
	G_LOCK(cleanquit);

	puts("Starting Z80 Emulation Core...");

	G_LOCK(running);
	Z80_Reset();
	Rezet(1);
	G_UNLOCK(running);

	G_LOCK(runctrl);

	freqmeter = g_timer_new();
	g_timer_start(freqmeter);
	
	while (1) {
		G_UNLOCK(runctrl);
		G_LOCK(running);
		if (!running)
			break;
		G_UNLOCK(running);
		G_LOCK(runctrl);

		Z80_Execute();

/* Executes 50000 cycles at a time */
		G_LOCK(ctrlspeed);
		if (ctrlspeed) {
			g_timer_elapsed(freqmeter, &timereg);
			g_timer_reset(freqmeter);
			timediff += 8333 - timereg;

			if (timediff > 0) {
				USLEEP(timediff);
				g_timer_elapsed(freqmeter, &timereg);
				g_timer_reset(freqmeter);
				timediff -= timereg;
			}

			/* if ((timereg < 8333) && (ctrlspeed))
			   USLEEP(8333 - timereg); */
		}
		G_UNLOCK(ctrlspeed);
	}

	G_UNLOCK(runctrl);

	g_timer_destroy(freqmeter);
	G_UNLOCK(cleanquit);

	return NULL;
}
/* Exported <<< */
