📄 g4drv.c
字号:
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 + -