File:  [RetroPC.NET] / xmil / nds / xmil9.cpp
Revision 1.1: download - view: text, annotated - select for diffs
Tue Mar 24 22:52:51 2009 JST (16 years, 7 months ago) by yui
Branches: MAIN
CVS tags: HEAD
add nds-win32 simulation project

#include "compiler.h"
#include "libnds.h"
#include "xmil9.h"
#if defined(_WIN32) && defined(NDS_SIMULATE)
#include "dosio.h"
#endif
#include "sysmng.h"
#include "z80core.h"
#include "pccore.h"
#include "iocore.h"
#include "joymng.h"
#include "timing.h"
#include "makescrn.h"
#include "fddfile.h"
#include "font.h"
#include "nds9psg.h"
#include "vram.h"
#include "vsyncff.h"
#include "resource.h"
#include "softkbd9.h"
#if defined(SUPPORT_ROMEO2)
#include "ds_fpga.h"
#include "nds_fpga_raw.h"
#endif	// defined(SUPPORT_ROMEO2)


#if 0 && defined(TRACE)
	XMILOSCFG	xmiloscfg = {1, 1};
#else
	XMILOSCFG	xmiloscfg = {0, 0};
#endif

#define	MAX_FRAMESKIP		4


#if defined(NDS_SIMULATE)
static bool diskimgset1(REG8 cDrv, LPCTSTR lpcszFile)
{
	FILEH fh = FILEH_INVALID;
	UINT8 *pWork = 0;
	do
	{
		fh = file_open_rb_c(lpcszFile);
		if (fh == FILEH_INVALID)
		{
			break;
		}
		const UINT uSize = file_getsize(fh);
		if (uSize == 0)
		{
			break;
		}
		pWork = new UINT8 [uSize];
		if (!pWork)
		{
			break;
		}
		if (file_read(fh, pWork, uSize) != uSize)
		{
			break;
		}
		file_close(fh);
		fddfile_set(cDrv, FTYPE_D88, pWork, uSize);
		return true;
	} while(0 /*CONSTCOND*/);

	if (pWork)
	{
		delete[] pWork;
	}
	if (fh != FILEH_INVALID)
	{
		file_close(fh);
	}
	return false;
}

static void diskimgset()
{
	diskimgset1(0, _T("disk1.d88"));
	diskimgset1(1, _T("disk2.d88"));
}

#else	// defined(NDS_SIMULATE)

static bool diskimgset1(REG8 cDrv, const unsigned char *lpcsData, UINT uSize)
{
	if ((lpcsData) && (uSize))
	{
		fddfile_set(cDrv, FTYPE_D88, lpcsData, uSize);
		return true;
	}
	return false;
}

static void diskimgset()
{
	diskimgset1(0, __extromimage.sDisk1, __extromimage.uDisk1Size);
	diskimgset1(1, __extromimage.sDisk2, __extromimage.uDisk2Size);
}
#endif	// defined(NDS_SIMULATE)



// ---- bitmap
#if defined(SUPPORT_ROMEO2)
static void withRomeo2()
{
	const unsigned char *p = reinterpret_cast<const unsigned char *>(g_sDemoBmp);
	p = p + 16 + (192 * 256);

	unsigned char *q = reinterpret_cast<unsigned char *>(BG_GFX_SUB);
	q = q + 188 + (64 * 256);

	for (int y=0; y<8; y++)
	{
		for (int x=0; x<68; x+=2)
		{
			*(reinterpret_cast<uint16 *>(q + x)) = *(reinterpret_cast<const uint16 *>(p + x));
		}
		p = p + 256;
		q = q + 256;
	}
}
#endif	// defined(SUPPORT_ROMEO2)


// ----

struct tagXmilMain
{
	UINT uFrameCount;
	UINT uWaitCount;
	UINT uFrameMax;
};
typedef struct tagXmilMain		XMILMAIN;
typedef struct tagXmilMain		*PXMILMAIN;


static void framereset(XMILMAIN &xmm, UINT uCount)
{
	xmm.uFrameCount = 0;
	sysmng_dispclock();
	sysmng_fddsync(uCount);
}

static void processwait(XMILMAIN &xmm, UINT uCount)
{
	if (timing_getcount() >= uCount)
	{
		timing_setcount(0);
		framereset(xmm, uCount);
	}
	else
	{
		Sleep(1);
	}
}

static void exec1frame(XMILMAIN &xmm)
{
	joymng_setflags();
	pccore_exec((BRESULT)(xmm.uFrameCount == 0));
	xmm.uFrameCount++;
	nds9psg_sync(&nds9psg);
	softkbd9_sync();
}

int nds9main()
{
	XMILMAIN	xmilmain;

	if ((sizeof(z80core) != 0x40) ||
		(sizeof(dma) != 0x40) ||
		(sizeof(iocore) != 0x214) ||
		(sizeof(ppi) != 0x4) ||
		(sizeof(crtc) != 0x44) ||
		(sizeof(nds9psg) != 0x18) ||
		(sizeof(subcpu) != 0x4c) ||
		(sizeof(ctc) != 0xe4) ||
		(sizeof(cgrom) != 0xc) ||
		(sizeof(fdc) != 0x40))
	{
		while(1) { Sleep(1000); }
	}

	TRACEINIT();

//	xmilopen();

	irqInit();
	irqSet(IRQ_VBLANK, vsyncff_int);
	irqSet(IRQ_TIMER3, ndscore_timer3int);

	ndscore_timer3init();
	vsyncff_init();


	irqEnable(IRQ_VBLANK | IRQ_TIMER3);

#if defined(DISPCLOCK) && (!defined(NDS_SIMULATE)) 
#define VRAMBPARAM	VRAM_B_MAIN_SPRITE_0x06400000
#else	// defined(DISPCLOCK) && (!defined(NDS_SIMULATE))
#define VRAMBPARAM	VRAM_B_LCD
#endif	// defined(DISPCLOCK) && (!defined(NDS_SIMULATE))
#if defined(TRACE)
#define VRAMCPARAM	VRAM_C_SUB_BG
#else	// defined(TRACE)
#define VRAMCPARAM	VRAM_C_SUB_BG_0x06200000
#endif	// defined(TRACE)

	vramSetMainBanks(VRAM_A_MAIN_BG_0x06000000, VRAMBPARAM, VRAMCPARAM, VRAM_D_LCD);

#if defined(DISPCLOCK) && (!defined(NDS_SIMULATE))
	videoSetMode(MODE_5_2D | DISPLAY_SPR_ACTIVE | DISPLAY_BG3_ACTIVE | DISPLAY_SPR_1D);
#else	// defined(DISPCLOCK) && (!defined(NDS_SIMULATE))
	videoSetMode(MODE_5_2D | DISPLAY_BG3_ACTIVE);
#endif	// defined(DISPCLOCK) && (!defined(NDS_SIMULATE))

#if MAKESCRN_VRAMFF
	BG3_CR = BG_BMP8_512x256;
#else	// MAKESCRN_VRAMFF
	BG3_CR = BG_BMP8_256x256;
#endif	// MAKESCRN_VRAMFF
	BG3_XDX = 1 << 8;
	BG3_XDY = 0;
	BG3_YDX = 0;
	BG3_YDY = 1 << 8;
	BG3_CX = 0;
	BG3_CY = 0 << 8;

#if defined(TRACE)
	videoSetModeSub(MODE_0_2D | DISPLAY_BG0_ACTIVE);
	SUB_BG0_CR = BG_MAP_BASE(31);
	BG_PALETTE_SUB[255] = RGB15(31,31,31);
	consoleInitDefault((u16*)SCREEN_BASE_BLOCK_SUB(31), (u16*)CHAR_BASE_BLOCK_SUB(0), 16);
#else	// defined(TRACE)
	videoSetModeSub(MODE_5_2D | DISPLAY_BG3_ACTIVE);
	SUB_BG3_CR = BG_BMP8_256x256;
	SUB_BG3_XDX = 1 << 8;
	SUB_BG3_XDY = 0;
	SUB_BG3_YDX = 0;
	SUB_BG3_YDY = 1 << 8;
	SUB_BG3_CX = 0;
	SUB_BG3_CY = 0 << 8;
	dmaCopy(g_sDemoBmp, BG_GFX_SUB, 256*192);
	dmaCopy(g_sDemoPal, BG_PALETTE_SUB, 256*2);
#endif	// defined(TRACE)

#if defined(SUPPORT_ROMEO2)
	ds_fpga_bus_init();
	const int nFpgaError = ds_fpga_configration(g_nds_fpga_raw, g_nds_fpga_raw_size);
	if (nFpgaError == FPGA_NO_ERR)
	{
		/* Enable OPM Sound */
		xmilcfg.SOUND_SW = 1;
		withRomeo2();
	}
#endif	// defined(SUPPORT_ROMEO2)

	softkbd9_initialize();

	extrom_initialize();

	sysmng_initialize();

	pccore_initialize();
	pccore_reset();

	diskimgset();

	xmilmain.uFrameCount = 0;
	xmilmain.uWaitCount = 0;
	xmilmain.uFrameMax = 1;

	sysmng_clockreset();

	CopyMemory(font_ank, __extromimage.ank, 0x800);

#if 1
	while(ndssys_task())
	{
		if (xmiloscfg.NOWAIT)
		{
			exec1frame(xmilmain);
			if (xmiloscfg.DRAW_SKIP)
			{
				// nowait frame skip
				if (xmilmain.uFrameCount >= xmiloscfg.DRAW_SKIP)
				{
					processwait(xmilmain, 0);
				}
			}
			else
			{
				// nowait auto skip
				if (timing_getcount())
				{
					processwait(xmilmain, 0);
				}
			}
		}
		else if (xmiloscfg.DRAW_SKIP)
		{
			// frame skip
			if (xmilmain.uFrameCount < xmiloscfg.DRAW_SKIP)
			{
				exec1frame(xmilmain);
			}
			else
			{
				processwait(xmilmain, xmiloscfg.DRAW_SKIP);
			}
		}
		else
		{
			// auto skip
			if (!xmilmain.uWaitCount)
			{
				exec1frame(xmilmain);
				const UINT uCount = timing_getcount();
				if (xmilmain.uFrameCount > uCount)
				{
					xmilmain.uWaitCount = xmilmain.uFrameCount;
					if (xmilmain.uFrameMax > 1)
					{
						xmilmain.uFrameMax--;
					}
				}
				else if (xmilmain.uFrameCount >= xmilmain.uFrameMax)
				{
					if (xmilmain.uFrameMax < MAX_FRAMESKIP)
					{
						xmilmain.uFrameMax++;
					}
					if (uCount >= MAX_FRAMESKIP)
					{
						timing_reset();
					}
					else
					{
						timing_setcount(uCount - xmilmain.uFrameCount);
					}
					framereset(xmilmain, 0);
				}
			}
			else
			{
				processwait(xmilmain, xmilmain.uWaitCount);
				xmilmain.uWaitCount = xmilmain.uFrameCount;
			}
		}
	}
#else
	while(ndssys_task())
	{
		if (xmilmain.uFrameCount < 2)
		{
			exec1frame(xmilmain);
		}
		else
		{
			processwait(xmilmain, 2);
		}
	}
#endif

	pccore_deinitialize();

	TRACETERM();

	return 0;
}


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