File:  [RetroPC.NET] / xmil / nevent.c
Revision 1.2: download - view: text, annotated - select for diffs
Thu Aug 12 01:09:04 2004 JST (21 years, 2 months ago) by yui
Branches: MAIN
CVS tags: HEAD
fix...

#include	"compiler.h"
#include	"z80core.h"
#include	"pccore.h"
#include	"nevent.h"


	_NEVENT		nevent;


void nevent_allreset(void) {

	ZeroMemory(&nevent, sizeof(nevent));
}

void nevent_progress(void) {

	SINT32		nextbase;
	UINT		eventnum;
	UINT		waitevents;
	UINT		i;
	UINT		curid;
	NEVENTITEM	item;
	UINT		waitlevel[NEVENT_MAXEVENTS];

	CPU_CLOCK += CPU_BASECLOCK;

	nextbase = NEVENT_MAXCLOCK;
	eventnum = 0;
	waitevents = 0;
	for (i=0; i<nevent.readyevents; i++) {
		curid = nevent.level[i];
		item = nevent.item + curid;
		item->clock -= CPU_BASECLOCK;
		if (item->clock > 0) {
			// イベント待ち中
			nevent.level[eventnum++] = curid;
			if (nextbase >= item->clock) {
				nextbase = item->clock;
			}
		}
		else {
			waitlevel[waitevents++] = curid;
//			TRACEOUT(("event = %x", curid));
		}
	}
	nevent.readyevents = eventnum;
	CPU_BASECLOCK = nextbase;
	CPU_REMCLOCK += nextbase;
//	TRACEOUT(("nextbase = %d (%d)", nextbase, CPU_REMCLOCK));

	// イベント発生
	for (i=0; i<waitevents; i++) {
		curid = waitlevel[i];
		item = nevent.item + curid;
		if (item->proc != NULL) {
			item->proc(curid);
		}
	}
}

void nevent_reset(UINT id) {

	UINT	i;

	// 現在進行してるイベントを検索
	for (i=0; i<nevent.readyevents; i++) {
		if (nevent.level[i] == id) {
			break;
		}
	}
	// イベントは存在した?
	if (i < nevent.readyevents) {
		// 存在していたら削る
		nevent.readyevents--;
		for (; i<nevent.readyevents; i++) {
			nevent.level[i] = nevent.level[i+1];
		}
	}
}

void nevent_set(UINT id, SINT32 eventclock, NEVENTCB proc, BRESULT absolute) {

	SINT32		clock;
	NEVENTITEM	item;
	UINT		eventid;
	UINT		i;

	TRACEOUT(("event %d - %xclocks", id, eventclock));

	clock = CPU_BASECLOCK - CPU_REMCLOCK;
	item = nevent.item + id;
	item->baseclock = eventclock;
	item->proc = proc;
	if (absolute) {
		item->clock = eventclock + clock;
	}
	else {
		item->clock += eventclock;
	}

	// イベントの削除
	nevent_reset(id);

	// イベントの挿入位置の検索
	for (eventid=0; eventid<nevent.readyevents; eventid++) {
		if (item->clock < nevent.item[nevent.level[eventid]].clock) {
			break;
		}
	}

	// イベントの挿入
	for (i=nevent.readyevents; i>eventid; i--) {
		nevent.level[i] = nevent.level[i-1];
	}
	nevent.level[eventid] = id;
	nevent.readyevents++;

	// もし最短イベントだったら...
	if (eventid == 0) {
		clock = CPU_BASECLOCK;
		if (item->clock > 0) {
			clock -= item->clock;
		}
		CPU_BASECLOCK -= clock;
		CPU_REMCLOCK -= clock;
//		TRACEOUT(("reset nextbase -%d (%d)", clock, CPU_REMCLOCK));
	}
}

void nevent_repeat(UINT id) {

	NEVENTITEM	item;

	item = nevent.item + id;
	nevent_set(id, item->baseclock, item->proc, NEVENT_RELATIVE);
}

void nevent_setbyms(UINT id, SINT32 ms, NEVENTCB proc, BRESULT absolute) {

	nevent_set(id, (pccore.realclock / 1000) * ms, proc, absolute);
}

BRESULT nevent_iswork(UINT id) {

	UINT	i;

	// 現在進行してるイベントを検索
	for (i=0; i<nevent.readyevents; i++) {
		if (nevent.level[i] == id) {
			return(TRUE);
		}
	}
	return(FALSE);
}

SINT32 nevent_getwork(UINT id) {

	UINT	i;

	// 現在進行してるイベントを検索
	for (i=0; i<nevent.readyevents; i++) {
		if (nevent.level[i] == id) {
			return(nevent.item[id].baseclock - 
				(nevent.item[id].clock - (CPU_BASECLOCK - CPU_REMCLOCK)));
		}
	}
	return(-1);
}

SINT32 nevent_getremain(UINT id) {

	UINT	i;

	// 現在進行してるイベントを検索
	for (i=0; i<nevent.readyevents; i++) {
		if (nevent.level[i] == id) {
			return(nevent.item[id].clock - (CPU_BASECLOCK - CPU_REMCLOCK));
		}
	}
	return(-1);
}

void nevent_forceexit(void) {

	if (CPU_REMCLOCK > 0) {
		CPU_BASECLOCK -= CPU_REMCLOCK;
		CPU_REMCLOCK = 0;
	}
}


RetroPC.NET-CVS <cvs@retropc.net>