/*
 *  timer.cpp - Time Manager emulation
 *
 *  Basilisk II (C) 1997-2008 Christian Bauer
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program 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 General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/*
 *  SEE ALSO
 *    Inside Macintosh: Processes, chapter 3 "Time Manager"
 *    Technote 1063: "Inside Macintosh: Processes: Time Manager Addenda"
 */

#include <stdio.h>

#include "sysdeps.h"
#include "cpu_emulation.h"
#include "main.h"
#include "macos_util.h"
#include "timer.h"

#define DEBUG 0
#include "debug.h"


// Set this to 1 to enable TMQueue management (doesn't work)
#define TM_QUEUE 0


// Definitions for Time Manager
enum {	// TMTask struct
	tmAddr = 6,
	tmCount = 10,
	tmWakeUp = 14,
	tmReserved = 18
};


// Array of additional info for each installed TMTask
struct TMDesc {
	uint32 task;		// Mac address of associated TMTask
	tm_time_t wakeup;	// Time this task is scheduled for execution
	bool in_use;		// Flag: descriptor in use
};

const int NUM_DESCS = 64;		// Maximum number of descriptors
static TMDesc desc[NUM_DESCS];


/*
 *  Allocate descriptor for given TMTask in list
 */

static int alloc_desc(uint32 tm)
{
	// Search for first free descriptor
	for (int i=0; i<NUM_DESCS; i++)
		if (!desc[i].in_use) {
			desc[i].task = tm;
			desc[i].in_use = true;
			return i;
		}
	return -1;
}


/*
 *  Free descriptor in list
 */

inline static void free_desc(int i)
{
	desc[i].in_use = false;
}


/*
 *  Find descriptor associated with given TMTask
 */

inline static int find_desc(uint32 tm)
{
	for (int i=0; i<NUM_DESCS; i++)
		if (desc[i].in_use && desc[i].task == tm)
			return i;
	return -1;
}


/*
 *  Enqueue task in Time Manager queue
 */

static void enqueue_tm(uint32 tm)
{
#if TM_QUEUE
	uint32 tm_var = ReadMacInt32(0xb30);
	WriteMacInt32(tm + qLink, ReadMacInt32(tm_var));
	WriteMacInt32(tm_var, tm);
#endif
}


/*
 *  Remove task from Time Manager queue
 */

static void dequeue_tm(uint32 tm)
{
#if TM_QUEUE
	uint32 p = ReadMacInt32(0xb30);
	while (p) {
		uint32 next = ReadMacInt32(p + qLink);
		if (next == tm) {
			WriteMacInt32(p + qLink, ReadMacInt32(next + qLink));
			return;
		}
	}
#endif
}


/*
 *  Initialize Time Manager
 */

void TimerInit(void)
{
	// Mark all descriptors as inactive
	for (int i=0; i<NUM_DESCS; i++)
		free_desc(i);
}


/*
 *  Exit Time Manager
 */

void TimerExit(void)
{
}


/*
 *  Emulator reset, remove all timer tasks
 */

void TimerReset(void)
{
	// Mark all descriptors as inactive
	for (int i=0; i<NUM_DESCS; i++)
		free_desc(i);
}


/*
 *  Insert timer task
 */

int16 InsTime(uint32 tm, uint16 trap)
{
	D(bug("InsTime %08lx, trap %04x\n", tm, trap));
	WriteMacInt16(tm + qType, ReadMacInt16(tm + qType) & 0x1fff | (trap << 4) & 0x6000);
	if (find_desc(tm) >= 0)
		printf("WARNING: InsTime(): Task re-inserted\n");
	else {
		int i = alloc_desc(tm);
		if (i < 0)
			printf("FATAL: InsTime(): No free Time Manager descriptor\n");
	}
	return 0;
}


/*
 *  Remove timer task
 */

int16 RmvTime(uint32 tm)
{
	D(bug("RmvTime %08lx\n", tm));

	// Find descriptor
	int i = find_desc(tm);
	if (i < 0) {
		printf("WARNING: RmvTime(%08x): Descriptor not found\n", tm);
		return 0;
	}

	// Task active?
	if (ReadMacInt16(tm + qType) & 0x8000) {

		// Yes, make task inactive and remove it from the Time Manager queue
		WriteMacInt16(tm + qType, ReadMacInt16(tm + qType) & 0x7fff);
		dequeue_tm(tm);

		// Compute remaining time
		tm_time_t remaining, current;
		timer_current_time(current);
		timer_sub_time(remaining, desc[i].wakeup, current);
		WriteMacInt32(tm + tmCount, timer_host2mac_time(remaining));
	} else
		WriteMacInt32(tm + tmCount, 0);
	D(bug(" tmCount %d\n", ReadMacInt32(tm + tmCount)));

	// Free descriptor
	free_desc(i);
	return 0;
}


/*
 *  Start timer task
 */

int16 PrimeTime(uint32 tm, int32 time)
{
	D(bug("PrimeTime %08x, time %d\n", tm, time));

	// Find descriptor
	int i = find_desc(tm);
	if (i < 0) {
		printf("FATAL: PrimeTime(): Descriptor not found\n");
		return 0;
	}

	// Extended task?
	if (ReadMacInt16(tm + qType) & 0x4000) {

		// Convert delay time
		tm_time_t delay;
		timer_mac2host_time(delay, time);

		// Yes, tmWakeUp set?
		if (ReadMacInt32(tm + tmWakeUp)) {

			//!! PrimeTime(0) means continue previous delay
			// (save wakeup time in RmvTime?)
			if (time == 0)
				printf("WARNING: Unsupported PrimeTime(0)\n");

			// Yes, calculate wakeup time relative to last scheduled time
			tm_time_t wakeup;
			timer_add_time(wakeup, desc[i].wakeup, delay);
			desc[i].wakeup = wakeup;

		} else {

			// No, calculate wakeup time relative to current time
			tm_time_t now;
			timer_current_time(now);
			timer_add_time(desc[i].wakeup, now, delay);
		}

		// Set tmWakeUp to indicate that task was scheduled
		WriteMacInt32(tm + tmWakeUp, 0x12345678);

	} else {

		// Not extended task, calculate wakeup time relative to current time
		tm_time_t delay;
		timer_mac2host_time(delay, time);
		timer_current_time(desc[i].wakeup);
		timer_add_time(desc[i].wakeup, desc[i].wakeup, delay);
	}

	// Make task active and enqueue it in the Time Manager queue
	WriteMacInt16(tm + qType, ReadMacInt16(tm + qType) | 0x8000);
	enqueue_tm(tm);
	return 0;
}


/*
 *  Timer interrupt function (executed as part of 60Hz interrupt)
 */

void TimerInterrupt(void)
{
	// Look for active TMTasks that have expired
	tm_time_t now;
	timer_current_time(now);
	for (int i=0; i<NUM_DESCS; i++)
		if (desc[i].in_use) {
			uint32 tm = desc[i].task;
			if ((ReadMacInt16(tm + qType) & 0x8000) && timer_cmp_time(desc[i].wakeup, now) < 0) {

				// Found one, mark as inactive and remove it from the Time Manager queue
				WriteMacInt16(tm + qType, ReadMacInt16(tm + qType) & 0x7fff);
				dequeue_tm(tm);

				// Call timer function
				uint32 addr = ReadMacInt32(tm + tmAddr);
				if (addr) {
					D(bug("Calling TimeTask %08lx, addr %08lx\n", tm, addr));
					M68kRegisters r;
					r.a[0] = addr;
					r.a[1] = tm;
					Execute68k(addr, &r);
				}
			}
		}
}
