File:  [RetroPC.NET] / xmil / io / iocore.c
Revision 1.12: download - view: text, annotated - select for diffs
Tue Jun 3 05:07:31 2008 JST (17 years, 4 months ago) by yui
Branches: MAIN
CVS tags: HEAD
change to c style comment


/* #define IOCOUNTER */

#include	"compiler.h"
#include	"pccore.h"
#include	"iocore.h"


	IOCORE		iocore;
	CGROM		cgrom;
	CMT			cmt;
	CRTC		crtc;
	CTC			ctc;
	DMAC		dma;
	FDC			fdc;
	PCG			pcg;
	PPI			ppi;
	SIO			sio;
	SNDBOARD	sndboard;
	SUBCPU		subcpu;


/* ---- */

static void IOOUTCALL dummy_out(UINT port, REG8 dat) {

	(void)port;
	(void)dat;
}

static REG8 IOINPCALL dummy_inp(UINT port) {

	(void)port;
	return(0xff);
}


/* ---- */

static void IOOUTCALL port1fxx_o(UINT port, REG8 dat) {

	REG8	lsb;
	REG8	msb6;

	lsb = (UINT8)port;
	if (lsb == 0xd0) {
		scrn_o(port, dat);
		return;
	}
	if (lsb < 0x80) {
		return;
	}
	msb6 = lsb & (~3);
	if (lsb < 0x90) {
		dmac_o(port, dat);
		return;
	}
	if (msb6 == 0x90) {
		sio_o(port, dat);
		return;
	}
	if ((msb6 == 0xa0) || (msb6 == 0xa8)) {
		ctc_o(port, dat);
		return;
	}
	if (lsb == 0xe0) {
		blackctrl_o(port, dat);
		return;
	}
#if defined(SUPPORT_TURBOZ)
	if (pccore.ROM_TYPE >= 3) {
		if (lsb == 0xb0) {
			extpal_o(port, dat);
			return;
		}
		if (lsb == 0xc0) {
			exttextdisp_o(port, dat);
			return;
		}
		if (lsb == 0xc5) {
			extgrphpal_o(port, dat);
			return;
		}
		if ((lsb >= 0xb9) && (lsb < 0xc0)) {
			exttextpal_o(port, dat);
			return;
		}
	}
#endif
}

static REG8 IOINPCALL port1fxx_i(UINT port) {

	REG8	lsb;
	REG8	msb6;

	lsb = (UINT8)port;
	if (lsb == 0xd0) {
		return(scrn_i(port));
	}
	if (lsb < 0x80) {
		return(0xff);
	}
	msb6 = lsb & (~3);
	if (lsb < 0x90) {
		return(dmac_i(port));
	}
	if (msb6 == 0x90) {
		return(sio_i(port));
	}
	if ((msb6 == 0xa0) || (msb6 == 0xa8)) {
		return(ctc_i(port));
	}
	if (lsb >= 0xf0) {
		return(dipsw_i(port));
	}
#if defined(SUPPORT_TURBOZ)
	if (pccore.ROM_TYPE >= 3) {
		if (lsb == 0xb0) {
			return(extpal_i(port));
		}
		if (lsb == 0xc0) {
			return(exttextdisp_i(port));
		}
		if (lsb == 0xc5) {
			return(extgrphpal_i(port));
		}
		if ((lsb >= 0xb9) && (lsb < 0xc0)) {
			return(exttextpal_i(port));
		}
		if (lsb == 0xe0) {
			return(blackctrl_i(port));
		}
	}
#endif
	return(0xff);
}


/* ---- */

static const IOINP definp[0x20] = {
			dummy_inp,			dummy_inp,
			dummy_inp,			dummy_inp,
			dummy_inp,			dummy_inp,
			dummy_inp,			dummy_inp,

			dummy_inp,			dummy_inp,
			dummy_inp,			dummy_inp,
			dummy_inp,			dummy_inp,
			cgrom_i,			fdc_i,

			dummy_inp,			dummy_inp,
			dummy_inp,			dummy_inp,
			pcg_i,				pcg_i,
			pcg_i,				pcg_i,

			dummy_inp,			subcpu_i,
			ppi_i,				sndboard_psgsta,
			dummy_inp,			dummy_inp,
			dummy_inp,			dummy_inp};

static const IOOUT defout[0x20] = {
			dummy_out,			dummy_out,
			dummy_out,			dummy_out,
			dummy_out,			dummy_out,
			dummy_out,			dummy_out,

			dummy_out,			dummy_out,
			dummy_out,			dummy_out,
			dummy_out,			dummy_out,
			cgrom_o,			fdc_o,

			palette_o,			palette_o,
			palette_o,			ply_o,
			dummy_out,			pcg_o,
			pcg_o,				pcg_o,

			crtc_o,				subcpu_o,
			ppi_o,				sndboard_psgdat,
			sndboard_psgreg,	memio_rom,
			memio_ram,			dummy_out};


typedef void (*INITFN)(void);

static const INITFN initfn[] = {
			cgrom_reset,	cmt_reset,		crtc_reset,
			ctc_reset,		dmac_reset,		fdc_reset,
			memio_reset,	pcg_reset,		ppi_reset,
			sio_reset,		sndboard_reset,	subcpu_reset,
			vramio_reset};


/* ---- */

void iocore_reset(void) {

	UINT	i;

	ZeroMemory(&iocore, sizeof(iocore));
	CopyMemory(iocore.f.inpfn, definp, sizeof(definp));
	CopyMemory(iocore.f.outfn, defout, sizeof(defout));
	for (i=0; i<0x10; i++) {
		iocore.f.inpfn[i+0x20] = tram_atr_i;
		iocore.f.inpfn[i+0x30] = tram_ank_i;
		iocore.f.outfn[i+0x20] = tram_atr_o;
		iocore.f.outfn[i+0x30] = tram_ank_o;
	}
	if (pccore.ROM_TYPE >= 2) {
#if defined(SUPPORT_BANKMEM)
		iocore.f.inpfn[0x0b] = memio_bank_i;
		iocore.f.outfn[0x0b] = memio_bank_o;
#endif
		iocore.f.inpfn[0x1f] = port1fxx_i;
		iocore.f.outfn[0x1f] = port1fxx_o;
		for (i=0; i<8; i++) {
			iocore.f.inpfn[i+0x38] = tram_knj_i;
			iocore.f.outfn[i+0x38] = tram_knj_o;
		}
	}
#if defined(SUPPORT_TURBOZ)
	if (pccore.ROM_TYPE >= 3) {
		iocore.f.inpfn[0x10] = palette_i;
		iocore.f.inpfn[0x11] = palette_i;
		iocore.f.inpfn[0x12] = palette_i;
		iocore.f.inpfn[0x13] = ply_i;
	}
#endif
#if defined(SUPPORT_TURBOZ) || defined(SUPPORT_OPM)
	if (pccore.SOUND_SW) {
		iocore.f.inpfn[0x07] = opm_i;
		iocore.f.outfn[0x07] = opm_o;
	}
#endif
	for (i=0; i<NELEMENTS(initfn); i++) {
		(initfn[i])();
	}
}


/* ---- */

#if defined(TRACE) && defined(IOCOUNTER)
extern	UINT	ocounter[0x2008];
extern	UINT	icounter[0x2008];
#endif

void IOOUTCALL iocore_out(UINT port, REG8 dat) {

	UINT	msb;

	msb = port >> 8;
	if (iocore.s.mode) {
		gram2_o(port, dat);
	}
	else if (msb >= 0x40) {
		gram_o(port, dat);
#if defined(TRACE) && defined(IOCOUNTER)
		ocounter[0x2000 + (port >> 14)]++;
#endif
	}
	else {
#if defined(TRACE) && defined(IOCOUNTER)
		if (port < 0x2000) {
			ocounter[port]++;
		}
		else {
			ocounter[0x1ffc + (port >> 11)]++;
		}
#endif
		(*iocore.f.outfn[msb])(port, dat);
	}
}

REG8 IOINPCALL iocore_inp(UINT port) {

	UINT	msb;

	msb = port >> 8;
	iocore.s.mode = 0;
	if (msb >= 0x40) {
#if defined(TRACE) && defined(IOCOUNTER)
		icounter[0x2000 + (port >> 14)]++;
#endif
		return(gram_i(port));
	}
	else {
#if defined(TRACE) && defined(IOCOUNTER)
		if (port < 0x2000) {
			icounter[port]++;
		}
		else {
			icounter[0x1ffc + (port >> 11)]++;
		}
#endif
		return((*iocore.f.inpfn[msb])(port));
	}
}


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