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

📄 g4drv.c

📁 用来将电脑连接到电视荧幕, 并以15Khz输出的源码, 请只用在支援15Khz的荧幕上, 以免伤害荧幕
💻 C
📖 第 1 页 / 共 2 页
字号:
	double ref = BASE_FREQ;
	double Fvco;

	vclk = vclk / 1000;
	*P = 0;
	if(vclk > 240000) vclk = 240000;
	if( 	 vclk <   30000){
		*P = 8;
	}else if(vclk <   60000){
		*P = 4;
	}else if(vclk <  120000){
		*P = 2;
	}else if(vclk <= 240000){
		*P = 1;
	}

	*N = 0;
	*M = 0;
	tempfd = 0;
	tempdt = 0;
	fd = vclk * (*P);
	dt = 240000;

	d0 = 8;
	while(d0 <= 128){
		d1 = 2;
		while(d1 <= 32){
			tempfd = ref * d0 / d1;
			tempdt = fd - tempfd;
			if(tempdt < 0) tempdt *= -1;
			if(dt > tempdt){
				*N = d0;
				*M = d1;
				dt = tempdt;
			}
			d1 += 1;
		}
		d0 += 1;
	}

	Fvco = ref * (*N) / (*M);
	tempfd = Fvco / (*P);

	*S = 0;
	if( 	 Fvco < 110000){
		*S = 0;
	}else if(Fvco < 170000){
		*S = 1;
	}else if(Fvco < 240000){
		*S = 2;
	}else if(Fvco < 310000){
		*S = 3;
	}

#if 0
	logerror( "N: %d\n", *N);
	logerror( "M: %d\n", *M);
	logerror( "P: %d\n", *P);
	logerror( "S: %d\n", *S);

	logerror( "Fd	%f\n", fd / (*P));
	logerror( "Fout %f\n", tempfd);
	logerror( "Fvco %f\n", Fvco);
#endif


	return (long)(tempfd * 1000);
}



static void SetVClock(int N, int M, int P, int S)
{
	int PLLn;

	SetSeqDiv(1);

	G400IdxReg_outb(0x1A, BitMov(G400IdxReg_inb(0x1A), 2, 1, 0));

	PLLn = _inb(0x3CC);
	PLLn = PLLn | 0x0C;
	_outb(0x3C2, PLLn);

	M -= 1;
	N -= 1;
	P -= 1;

	M = M & 0x1F;
	G400IdxReg_outb(0x4C, M);
	N = N & 0x7F;
	G400IdxReg_outb(0x4D, N);
	P = P | (S << 3);
	P = P & 0x1F;
	G400IdxReg_outb(0x4E, P);

	while(1){
		if( (G400IdxReg_inb(0x4F) & 0x40) != 0 ) break;
	}

	G400IdxReg_outb(0x1A, BitMov(G400IdxReg_inb(0x1A), 2, 0, 0));

}




static void SetHZoom(int d0)
{
	if(d0 == 1){
		d0 = 0;
	}else if(d0 == 2){
		d0 = 1;
	}else if(d0 == 4){
		d0 = 3;
	}else{
		d0 = 0;
	}
	G400IdxReg_outb(0x38, d0);
}


static void SetCompositeSync(int flag)
{
	int d0;

	d0 = G400CrtcExtReg_inb(0x03);
	if(flag != 0){
		d0 = BitMov(d0, 6, 1, 0);
	}else{
		d0 = BitMov(d0, 6, 0, 0);
	}
	G400CrtcExtReg_outb(0x03, d0);
}

static void SetDoubleScan(int flag)
{
	int d0;

	d0 = GetCrtcReg(0x09) & ~0x1F;
	if(flag != 0){
		d0 = d0 | 0x01;
	}
	SetCrtcReg(0x09, d0);
}








BYTE G400IdxReg_inb(BYTE _index)
{
	G400_outb(0x3C00, _index);
	return G400_inb(0x3C0A);
}

void G400IdxReg_outb(BYTE _index, BYTE _data)
{
	G400_outb(0x3C00, _index);
	G400_outb(0x3C0A, _data);
}

BYTE G400CrtcExtReg_inb(BYTE _index)
{
	G400_outb(0x1FDE, _index);
	return G400_inb(0x1FDF);
}

void G400CrtcExtReg_outb(BYTE _index, BYTE _data)
{
	G400_outb(0x1FDE, _index);
	G400_outb(0x1FDF, _data);
}


void SetG400VGA(int x, int y, int center_x, int center_y, int hsyncdelay, int hdispdelay)
{
	CRTCPARAM cp;
	int hzoom;
	int N, M, P, S;
	long vclk;


	GetMode15KHz(&cp, x, y);
	hzoom = 1;

	cp.HBStart = cp.HDisp - 8;
	cp.HBEnd   = cp.HTotal - 16;
	cp.VBStart = cp.VDisp  - 1;
	cp.VBEnd   = cp.VTotal - 1;


	vclk = get_vclk_param(cp.dotclockHz, &N, &M, &P, &S);

	AdjustSyncParam(&cp, vclk);
	AdjustCenter(&cp, center_x, center_y);

	DisableGenerateSignal();
	SetInterlaceStatus(0);
	SetGenericVGARegister(&cp, hsyncdelay, hdispdelay);
	SetG400ExtRegister(&cp);
	SetVClock(N, M, P, S);
	SetHZoom(hzoom);
	SetDoubleScan(cp.doublescan);
	SetHVPolarity(cp.hpolarity, cp.vpolarity);
	SetTextWidth(8);
	EnableGenerateSignal();
}


void SetG400Text40x25(int center_x, int center_y, int hsyncdelay, int hdispdelay)
{
	CRTCPARAM cp;
	int hzoom;
	int N, M, P, S;
	long vclk;


	GetMode15KHz(&cp, 320, 200); /* 40x25 */
	hzoom = 1;

	cp.HBStart = cp.HDisp - 8;
	cp.HBEnd   = cp.HTotal - 16;
	cp.VBStart = cp.VDisp  - 1;
	cp.VBEnd   = cp.VTotal - 1;

	vclk = get_vclk_param(cp.dotclockHz, &N, &M, &P, &S);

	AdjustSyncParam(&cp, vclk);
	AdjustCenter(&cp, center_x, center_y);

	DisableGenerateSignal();
	SetInterlaceStatus(0);
	SetGenericVGARegister(&cp, hsyncdelay, hdispdelay);
	SetG400ExtRegister(&cp);
	SetVClock(N, M, P, S);
	SetHZoom(hzoom);
	SetDoubleScan(cp.doublescan);
	SetHVPolarity(cp.hpolarity, cp.vpolarity);
	SetTextHeight(8);
	SetTextWidth(8);
	EnableGenerateSignal();
}

void SetG400Text80x25(int center_x, int center_y, int hsyncdelay, int hdispdelay)
{
	CRTCPARAM cp;
	int hzoom;
	int N, M, P, S;
	long vclk;
	long min14;
	long max14;

	GetMode15KHz(&cp, 640, 200); /* 80x25 */
	hzoom = 1;

	cp.HBStart = cp.HDisp - 8;
	cp.HBEnd   = cp.HTotal - 16;
	cp.VBStart = cp.VDisp  - 1;
	cp.VBEnd   = cp.VTotal - 1;

	vclk = get_vclk_param(cp.dotclockHz, &N, &M, &P, &S);

	AdjustSyncParam(&cp, vclk);
	AdjustCenter(&cp, center_x, center_y);

	DisableGenerateSignal();
	SetInterlaceStatus(0);
	SetGenericVGARegister(&cp, hsyncdelay, hdispdelay);
	SetG400ExtRegister(&cp);

	min14 = 14000000;		/* 14.0MHz */
	max14 = 14300000;		/* 14.3MHz */
	if(min14 <= vclk && vclk <= max14){
		Set14MHz(); 		/* set 14.161MHz */
	}else{
		SetVClock(N, M, P, S);
	}

	SetHZoom(hzoom);
	SetDoubleScan(cp.doublescan);
	SetHVPolarity(cp.hpolarity, cp.vpolarity);
	SetTextHeight(8);
	SetTextWidth(8);
	EnableGenerateSignal();
}


void SetG400ModeX(int x, int y, int center_x, int center_y, int hsyncdelay, int hdispdelay)
{
	CRTCPARAM cp;
	int hzoom;
	int N, M, P, S;
	long vclk;

	if(GetMode15KHz(&cp, x, y) == 0)
		GetMode15KHz(&cp, 640, 200);

	hzoom = 1;

	cp.HBStart = cp.HDisp - 8;
	cp.HBEnd   = cp.HTotal - 16;
	cp.VBStart = cp.VDisp  - 1;
	cp.VBEnd   = cp.VTotal - 1;

	vclk = get_vclk_param(cp.dotclockHz, &N, &M, &P, &S);

	AdjustSyncParam(&cp, vclk);
	AdjustCenter(&cp, center_x, center_y);

	DisableGenerateSignal();
	SetInterlaceStatus(0);
	SetGenericVGARegister(&cp, hsyncdelay, hdispdelay);
	SetG400ExtRegister(&cp);
	SetVClock(N, M, P, S);
	SetHZoom(hzoom);
	SetHVPolarity(cp.hpolarity, cp.vpolarity);
	SetTextWidth(8);

	SetDoubleScan(0);
	SetTextHeight(cp.doublescan + 1);

	EnableGenerateSignal();

}










/********************************************************************/


int  Detect15KHz(void)
{
	return DetectG400();
}

int  SetSVGA(int xres, int yres, int center_x, int center_y, int hsyncdelay, int hdispdelay)
{
	return SetG400(xres, yres, center_x, center_y, hsyncdelay, hdispdelay);
}

void SetVGA(int x, int y, int center_x, int center_y, int hsyncdelay, int hdispdelay)
{
	SetG400VGA(x, y, center_x, center_y, hsyncdelay, hdispdelay);
}

void SetVGAText40x25(int center_x, int center_y, int hsyncdelay, int hdispdelay)
{
	SetG400Text40x25(center_x, center_y, hsyncdelay, hdispdelay);
}

void SetVGAText80x25(int center_x, int center_y, int hsyncdelay, int hdispdelay)
{
	SetG400Text80x25(center_x, center_y, hsyncdelay, hdispdelay);
}

void SetModeX(int center_x, int center_y, int hsyncdelay, int hdispdelay)
{
	int x;
	int y;
	Copy_VGACRTC_to_VIDEOMODE(&x, &y);
	SetG400ModeX(x, y, center_x, center_y, hsyncdelay, hdispdelay);
}


WORD  AdjustBytesPerLine(WORD bytesperline)
{
	return (WORD)AdjustG400BytesPerLine((WORD)bytesperline);
}

WORD  GetBytesPerLine(void)
{
	return (WORD)GetG400BytesPerLine();
}

void  SetBytesPerLine(WORD bytesperline)
{
	SetG400BytesPerLine((DWORD)bytesperline);
}


DWORD GetScreenStartAddress(void)
{
	return GetG400ScreenStartAddress();
}

void  SetScreenStartAddress(DWORD address)
{
	SetG400ScreenStartAddress(address);
}

WORD  GetMaxBytesPerLine(void)
{
	return GetG400MaxBytesPerLine();
}

char NotFoundG400[] = "No G400 found!\n";

char* NotFoundMessage(void)
{
	return NotFoundG400;
}


WORD GetActualVesaMode(int xres, int yres, int bpp)
{
	int mode;

	mode = _640x480x8;
	if(xres <= 640 && yres <= 480){
		if(bpp == 8){
			mode = _640x480x8;
		}else if(bpp == 15){
			mode = _640x480x15;
		}else if(bpp == 16){
			mode = _640x480x16;
		}else if(bpp == 32){
			mode = _640x480_TC;
		}
	}else if(xres <= 1024 && yres <= 768){
		if(bpp == 8){
			mode = _1024x768x8;
		}else if(bpp == 15){
			mode = _1024x768x15;
		}else if(bpp == 16){
			mode = _1024x768x16;
		}else if(bpp == 32){
			mode = _1024x768_TC;
		}
	}else{
		if(bpp == 8){
			mode = _1280x1024x8;
		}else if(bpp == 15){
			mode = _1280x1024x15;
		}else if(bpp == 16){
			mode = _1280x1024x16;
		}else if(bpp == 32){
			mode = _1280x1024_TC;
		}
	}

	return mode;
}

int GetAvailableBpp(int bpp)
{
	int result;

	result = 8;
	if(bpp == 8){
		result = 8;
	}else if(bpp == 15){
		result = 15;
	}else if(bpp == 16){
		result = 16;
#if 0
	}else if(bpp == 24){
		result = 32;
	}else if(bpp == 32){
		result = 32;
#endif
	}

	return result;
}

⌨️ 快捷键说明

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