⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 grengine.cpp

📁 SNES game emulator. C and asm files.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
		{ 360, 0x6B, 0x59, 0x5A, 0x8E, 0x5E, 0x8A, 1, 1 },
		{ 376, 0x6E, 0x5D, 0x5E, 0x91, 0x62, 0x8F, 1, 1 },
		{ 400, 0x70, 0x63, 0x64, 0x92, 0x69, 0x85, 1, 0 }
	};
	static struct {
		int res;
		int overflow, v_total;
		int v_retracestart, v_retraceend;
		int v_enableend, v_blankstart, v_blankend;
		int v_polarity, v_maxscan;
	} y [9] = {
		{ 400, 0x1F, 0xBF, 0x9C, 0x8E, 0x8F, 0x96, 0xB9, 0, 0x40 },
		{ 480, 0x3E, 0x0D, 0xEA, 0xAC, 0xDF, 0xE7, 0x06, 1, 0x40 },
		{ 360, 0x1F, 0xBF, 0x88, 0x85, 0x67, 0x6D, 0xBA, 0, 0x40 },
		{ 512, 0xB2, 0x30, 0x0A, 0xAC, 0xFF, 0x07, 0x1A, 1, 0x60 },
		{ 600, 0xF0, 0x70, 0x5B, 0x8C, 0x57, 0x58, 0x70, 1, 0x60 },
		{ 564, 0xF0, 0x62, 0x37, 0x89, 0x33, 0x3C, 0x5C, 1, 0x60 },
		{ 540, 0xF0, 0x30, 0x20, 0xA9, 0x1B, 0x1F, 0x2F, 1, 0x60 },
		{ 448, 0x3E, 0x0B, 0xDA, 0x9C, 0xBF, 0xC7, 0x04, 1, 0x40 },
		{ 300, 0x1F, 0x46, 0x31, 0x80, 0x2B, 0x2F, 0x44, 1, 0x40 },
	};
	
	switch (mode) {
	case 0:
		xres = 160; yres = 25;
		break;
	case 1:
		xres = 256; yres = 256;
		xregset = 1; yregset = 3;
		break;
	case 2:
		xres = 320; yres = 200;
		break;
	case 3:
		xres = 320; yres = 240;
		xregset = 0; yregset = 1; chained = false;
		break;
	case 4:
		xres = 360; yres = 240;
		xregset = 2; yregset = 1; chained = false;
		break;
	case 5:
		xres = 360; yres = 360;
		xregset = 2; yregset = 2; chained = false;
		doublescan = false;
		break;
	}
	if (qsize) {
		xres = 256;
		yres = 256;
	}
	if (mode == vidmode) {
		if (qsize && !chained) // Select all planes for changing at once: set all bits of register 2
			outpw (_SEQU, 0x0F02);
		memset (_VGA_PTR, 0, 0xFFFF);
		return;
	}
	if (mode != 0) {
		regs.w.ax = 0x0013;
		int386 (0x10, &regs, &regs); // Set regular mode 13h
	} else {
		regs.w.ax = 0x0003;
		int386 (0x10, &regs, &regs); // Set text mode
	}
	if (mode != 0 && mode != 2) {
		outp (_CRTC, 0x11);
		v = inp (_CRTC+1) & 0x7F;
		outp (_CRTC, 0x11);
		outp (_CRTC+1, v);
			// Write protect off
		outp(0x3C2, 0x23 | (x [xregset].clockselect << 2) |
				(x [xregset].h_polarity << 6) | (y [yregset].v_polarity << 7));
			// Write misc.output
		outp(_CRTC, 0x00); outp(_CRTC+1, x [xregset].h_total);
			// Write horizontal total
		outp(_CRTC, 0x01); outp(_CRTC+1, x [xregset].h_enableend);
			// Write horizontal display enable end
		outp(_CRTC, 0x02); outp(_CRTC+1, x [xregset].h_blankstart);
			// Write horizontal blank start
		outp(_CRTC, 0x03); outp(_CRTC+1, x [xregset].h_blankend);
			// Write horizontal blank end
		outp(_CRTC, 0x04); outp(_CRTC+1, x [xregset].h_retracestart);
			// Write horizontal retrace start
		outp(_CRTC, 0x05); outp(_CRTC+1, x [xregset].h_retraceend);
			// Write horizontal retrace end
		outp(_CRTC, 0x06); outp(_CRTC+1, y [yregset].v_total);
			// Write vertical total
		outp(_CRTC, 0x07); outp(_CRTC+1, y [yregset].overflow);
			// Write overflow register
		outp(_CRTC, 0x08); outp(_CRTC+1, 0x08);
			// Write preset row scan
		outp(_CRTC, 0x09); outp(_CRTC+1, 0x40 | ((y [yregset].res & 512) >> 4) | doublescan);
			// Write number of duplicate scans and split screen scanline bit 9 (to help disable it)
		outp(_CRTC, 0x10); outp(_CRTC+1, y [yregset].v_retracestart);
			// Write vertical retrace start
		outp(_CRTC, 0x11); outp(_CRTC+1, y [yregset].v_retraceend);
			// Write vertical retrace end
		outp(_CRTC, 0x12); outp(_CRTC+1, y [yregset].v_enableend);
			// Write vertical display enable end
		outp(_CRTC, 0x13); outp(_CRTC+1, x [xregset].res / 8);
			// Write virtual width
		outp(_CRTC, 0x14); outp(_CRTC+1, chained << 6);
			// Write Underline location OR DWord mode off OR Byte mode on
			// (Well, which one is it? I dunno)
		outp(_CRTC, 0x15); outp(_CRTC+1, y [yregset].v_blankstart);
			// Write vertical blank start
		outp(_CRTC, 0x16); outp(_CRTC+1, y [yregset].v_blankend);
			// Write vertical blank end
		outp(_CRTC, 0x17); outp(_CRTC+1, 0xE3 - (chained << 6));
			// Mode Control: same in all versions of Mode X
		outp(_CRTC, 0x18); outp(_CRTC+1, y [yregset].res & 255);
			// Send split screen scanline bits 0 to 7 (to disable split screen)
		// _SEQU = 0x3C4
		outpw (_SEQU, 0x0100);
		outpw (_SEQU, 0x0101);
		outpw (_SEQU, 0x0300);
			// Set clock mode register
		if (!chained) // Turn off chain-4: bit 2(??) of register ("index") 4.
			outpw (_SEQU, 0x0604);
		// _GRAC = 0x3CE
		outpw (_GRAC, 0x4005);
		outpw (_GRAC, 0x0506);
			// Set mode and misc. regs
		inp (0x3DA); outp (0x3C0, 0x10); outp (0x3C0, 0x41);
			// Reset flop-flop, write index, write value
			// ...of mode control.
		inp (0x3DA); outp (0x3C0, 0x13); outp (0x3C0, 0x00);
			// Reset flop-flop, write index, write value
			// ...of horizontal panning.
		outp (0x3C0, 0x20);
			// Re-enable display

		if (!chained) // Select all planes for changing at once: set all bits of register 2
			outpw (_SEQU, 0x0F02);
		memset (_VGA_PTR, 0, 0xFFFF);
			// Clear video memory.

		outp (0,0);
	}
	vidmode = mode;
	debug0("video mode Set!");
}

//----------------------------------------------------------------------------
void testpattern ()
{
	int x, y;
	int starttime;

	setvideomode (vidmode, true);
	for (y = 0; y < 256; y++) {
		for (x = 0; x < 256; x++) {
			vs [(y << 8) + x] = (((x*x + y*y) & 255) >> 4) + 16;
		}
		
	}
	copyscreen ();
	tdelay (500);
	clearscreen ();
	setvideomode (vidmode, false);
	starttime = tmsec;
	for (y = 0; y < 256; y++) {
		memset (&vs [y * xres], y, xres);
		copyscreen ();
		clearscreen();
	}
	debug0 ("Video mode %d: 256 pageflips in %d milliseconds. %d fps.", vidmode, tmsec-starttime, 256000/(tmsec-starttime));
}

//----------------------------------------------------------------------------
void waitforretrace ()
{
	if (leadingedge) {
		while (inp (0x3DA) & 8)
			;
	}
	while (!(inp (0x3DA) & 8))
		;
}

int modexflip = true;

extern void move64k     (void *src, void *dest);
extern void move64k_fpu (void *src, void *dest);

#pragma aux move64k =           \
		"cld"                   \
		"mov ecx, 0x4000"       \
		"rep movsd"             \
		parm   [esi] [edi]      \
		modify [esi edi ecx];

//      "mov ax, ds"            \
		"mov es, ax"            \
		"pusha"\
		"pushf"\
		"mov ax, seg vs"\
		"mov ds, ax"\
		"popf"\
		"popa"\
		"mov debugesi, eax"\
		"mov debugedi, ecx"\
		"mov edi, 0xA0000"                   \
		"mov esi, offset vs"                   \

#pragma aux move64k_fpu =\
"        mov ecx, 0x1000"\
"TOP:    FILD    QWORD PTR [ESI]"\
"        FILD    QWORD PTR [ESI+8]"\
"        FXCH"\
"        FISTP   QWORD PTR [EDI]"\
"        FISTP   QWORD PTR [EDI+8]"\
"        ADD     ESI, 16"\
"        ADD     EDI, 16"\
"        DEC     ECX"\
"        JNZ     TOP"\
		parm   [esi] [edi]      \
		modify [esi edi ecx];
		
extern void clear64k (void *dest, dword fill);

#pragma aux clear64k =          \
		"cld"                   \
		"mov ecx, 0x4000"       \
		"rep stosd"             \
		parm   [edi] [eax]       \
		modify [edi ecx];

//      "mov byte ptr debugesi, al"\
		"mov debugedi, edi"\

extern void modexcopy (void *src, void *dest, int amount);
	// src is always vs

int amnt;
byte iter;
int strt;
void *vgadest;

//#pragma aux modexcopy =          \
		"pusha"\
		"cld"                   \
	"again: mov dh, byte ptr iter" /*4 iterations starting with plane 3*/\
		"shr dh, 1"\
		"mov dl, 2"\
		"mov ax, 0x3C4"\
		"out dx, ax"\
		"mov esi, offset vs"\
		"add esi, strt"\
		"mov edi, vgadest"\
		"mov ecx, amnt"\
	"inner: movsb"\
		"add edi, 3"\
		"loop inner"\
		"mov ecx, strt"\
		"dec ecx"\
		"jnz again"\
		"popa"\
		parm   [edi] [ecx]\
		modify [ax];

// ecx=amount
// esi=vs[strt]
// edi=
#pragma aux modexcopy = \
	"inner: mov al,ds:[esi]"\
		"mov es:[edi],al"\
		"add esi, 4"\
		"inc edi"\
		"dec cx"\
		"jnz inner"\
		parm   [esi] [edi] [ecx]\
		modify [edi esi ecx al];

//      "cld"\
	"inner: movsb"\
		"add esi, 3"\
		"dec cx"\
		"jnz inner"\
		parm   [esi] [edi] [ecx]\
		modify [edi esi ecx al];


/*
		last = ((xres * yres) >> 2) + drawstart;
		for (p = 0; p < 4; p++) {
			qpos = p;
			outp (_SEQU, 0x02); outp (_SEQU+1, 1 << p);
			for (x = drawstart; x < last; x++) {
				_VGA_PTR [x] = vs [qpos];
				qpos += 4;
			}
		}
*/

//----------------------------------------------------------------------------
void copyscreen ()
{
	int x, y, p, qpos, start, linesize, last;
	static visiblestart = 0;
	static drawstart = modexflip ? 0x8000 : 0;
	//double *ptr, *ptr2;
	
	if (waitretrace)
		waitforretrace ();
	if (vidmode == 2 && xres == 256) { // Mode Q screen must be squished to 200 lines
		for (x = 0, y = 0; y < 256; y++) {
			if (y & 7) {
				memcpy (_VGA_PTR + x * 320 + 32, vs + y * 256, 256);
				x++;
			}
		}
	} else if (vidmode < 3) { // Linear mode
		//memcpy (_VGA_PTR, vs, 65536);
		if (fpucopy) {
			move64k_fpu (vs, _VGA_PTR);
			//for (ptr = (double*)_VGA_PTR, ptr2 = (double*)vs; ptr < (double*)(_VGA_PTR+0x10000); ptr++, ptr2++) {
			//	*ptr = *ptr2;
			//}
		} else {
			move64k (vs, _VGA_PTR);
		}
	} else if (xres == 256 && yres == 256) { // Mode X copy of 256x256 buffer.
		switch (vidmode) {
		case 3: linesize = 80; last = 240; break;
		case 4: linesize = 90; last = 240; break;
		case 5: linesize = 90; last = 256; break;
		}
		for (p = 0; p < 4; p++) {
			switch (vidmode) {
			case 3: start = 8; break;
			case 4: start = 13; break;
			case 5: start = 6493; break;
			}
			start += drawstart;
			qpos = p;
			outp (_SEQU, 0x02); outp (_SEQU+1, 1 << p);
			for (y = 0; y < last; y++) {
				for (x = 0; x < 64; x++) {
					_VGA_PTR [start + x] = vs [qpos];
					qpos += 4;
				}
				start += linesize;
			}
		}
	} else { // Mode X copy
		last = ((xres * yres) >> 2);
		for (p = 0; p < 4; p++) {
			outp (_SEQU, 0x02); outp (_SEQU+1, 1 << p);
			modexcopy (vs+p, _VGA_PTR+drawstart, last);
		}/**/
		/*last = ((xres * yres) >> 2) + drawstart;
		for (p = 0; p < 4; p++) {
			qpos = p;
			outp (_SEQU, 0x02); outp (_SEQU+1, 1 << p);
			for (x = drawstart; x < last; x++) {
				_VGA_PTR [x] = vs [qpos];
				qpos += 4;
			}
		}*/
	}
	if (modexflip && vidmode > 2) {
		drawstart ^= 0x8000;
		visiblestart ^= 0x8000;
		outp (_CRTC, 0x0C);
		outp (_CRTC + 1, visiblestart >> 8);
		outp (_CRTC, 0x0D);
		outp (_CRTC + 1, visiblestart & 255);
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -