File:  [RetroPC.NET] / np2 / sound / fmtimer.c
Revision 1.4: download - view: text, annotated - select for diffs
Fri Nov 14 19:04:56 2003 JST (21 years, 11 months ago) by yui
Branches: MAIN
CVS tags: VER_0_72, VER_0_71, HEAD
fix BIOS / [MacOS9] fix keyboard (T.Yui)

#include	"compiler.h"
#include	"i286.h"
#include	"pccore.h"
#include	"iocore.h"
#include	"sound.h"
#include	"fmboard.h"


static const BYTE irqtable[4] = {0x03, 0x0d, 0x0a, 0x0c};


void fmport_a(NEVENTITEM item) {

	BOOL	intreq = FALSE;

	if (item->flag & NEVENT_SETEVENT) {
		if (fmtimer.reg & 0x04) {
			fmtimer.status |= 0x01;
			intreq = TRUE;
		}
		if (pcm86.fifo & 0x20) {
			sound_sync();
			if (pcm86.virbuf <= pcm86.fifosize) {
				intreq = TRUE;
			}
		}
		if (intreq) {
			pcm86.write = 1;
			pic_setirq(fmtimer.irq);
//			TRACEOUT(("fm int-A"));
		}
//		TRACE_("A: fifo = ", pcm86.fifo);
//		TRACE_("A: virbuf = ", pcm86.virbuf);
//		TRACE_("A: fifosize = ", pcm86.fifosize);
	}
}

void fmport_b(NEVENTITEM item) {

	BOOL	intreq = FALSE;

	if (item->flag & NEVENT_SETEVENT) {
		if (fmtimer.reg & 0x08) {
			fmtimer.status |= 0x02;
			intreq = TRUE;
		}
		if (pcm86.fifo & 0x20) {
			sound_sync();
			if (pcm86.virbuf <= pcm86.fifosize) {
				intreq = TRUE;
			}
		}
		if (intreq) {
			pcm86.write = 1;
			pic_setirq(fmtimer.irq);
//			TRACEOUT(("fm int-B"));
		}
//		TRACE_("B: fifo = ", pcm86.fifo);
//		TRACE_("B: virbuf = ", pcm86.virbuf);
//		TRACE_("B: fifosize = ", pcm86.fifosize);
	}
}

static void set_fmtimeraevent(BOOL absolute) {

	SINT32	l;

	l = 18 * (1024 - fmtimer.timera);
	if (pc.cpumode & CPUMODE_8MHz) {		// 4MHz
		l = (l * 1248 / 625) * pc.multiple;
	}
	else {									// 5MHz
		l = (l * 1536 / 625) * pc.multiple;
	}
	nevent_set(NEVENT_FMTIMERA, l, fmport_a, absolute);
}

static void set_fmtimerbevent(BOOL absolute) {

	SINT32	l;

	l = 288 * (256 - fmtimer.timerb);
	if (pc.cpumode & CPUMODE_8MHz) {		// 4MHz
		l = (l * 1248 / 625) * pc.multiple;
	}
	else {									// 5MHz
		l = (l * 1536 / 625) * pc.multiple;
	}
	nevent_set(NEVENT_FMTIMERB, l, fmport_b, absolute);
}

void fmtimer_reset(BYTE irq) {

	ZeroMemory(&fmtimer, sizeof(fmtimer));

#if 0													// move
	fmtimer.reg = 0x3f;
	set_fmtimeraevent(NEVENT_ABSOLUTE);
	set_fmtimerbevent(NEVENT_ABSOLUTE);
#endif
	fmtimer.intr = irq & 0xc0;
	fmtimer.intdisabel = irq & 0x10;
	fmtimer.irq = irqtable[irq >> 6];
	pic_registext(fmtimer.irq);
}

void fmtimer_setreg(BYTE reg, BYTE value) {

//	TRACEOUT(("fm %x %x [%.4x:%.4x]", reg, value, I286_CS, I286_IP));

	switch(reg) {
		case 0x24:
			fmtimer.timera = (value << 2) + (fmtimer.timera & 3);
			break;

		case 0x25:
			fmtimer.timera = (fmtimer.timera & 0x3fc) + (value & 3);
			break;

		case 0x26:
			fmtimer.timerb = value;
			break;

		case 0x27:
#if 1
			fmtimer.reg = value;
			fmtimer.status &= ~((value & 0x30) >> 4);
			if (value & 0x01) {
				if (!nevent_iswork(NEVENT_FMTIMERA)) {
					set_fmtimeraevent(NEVENT_ABSOLUTE);
				}
			}
			else {
				nevent_reset(NEVENT_FMTIMERA);
			}
			if (value & 0x02) {
				if (!nevent_iswork(NEVENT_FMTIMERB)) {
					set_fmtimerbevent(NEVENT_ABSOLUTE);
				}
			}
			else {
				nevent_reset(NEVENT_FMTIMERB);
			}
			if (!(value & 0x03)) {
				pic_resetirq(fmtimer.irq);
			}
#else
			fmtimer.reg = value;
			fmtimer.status &= ~((value & 0x30) >> 4);
			if ((value & 0x10) && (!nevent_iswork(NEVENT_FMTIMERA))) {
				set_fmtimeraevent(NEVENT_ABSOLUTE);
			}
			if ((value & 0x20) && (!nevent_iswork(NEVENT_FMTIMERB))) {
				set_fmtimerbevent(NEVENT_ABSOLUTE);
			}
#endif
			break;
	}
}


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