📄 mode15k.c
字号:
#include <dos.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "define.h"
#include "mode15k.h"
#include "port.h"
extern SCRLIST ScrModeList[];
static CRTCPARAM mode640x200_60 = {
// HTotal Disp BSta SSta SEnd BEnd VTotal Disp BSta SSta SEnd BEnd
896, 640, 640, 768, 848, 888, 263, 200, 200, 221, 223, 262,
// width height HPlr VPlr DblScn Intrlc Iratio
640, 200, 1, 1, 0, 0, 0,
// dotclkHz horzHz vertHz(in 0.01)
14138880, 15780, 6000
};
int GetScreenHeight(int VDisp, int doublescan, int interlace)
{
int result;
result = VDisp;
if(interlace != 0){
result *= 2;
}
if(doublescan != 0){
result /= 2;
}
return result;
}
void Copy_VGACRTC_to_VIDEOMODE(int *width, int *height)
{
extern PROGRAMtag PROGRAM;
int d0;
int d1;
int d2;
VIDEOMODE *vm;
vm=&PROGRAM.VideoModes[MAXVIDEOMODES-1];
SetCrtcReg(0x11, BitMov(GetCrtcReg(0x11), 7, 0, 0));
SetCrtcReg(0x03, GetCrtcReg(0x03) | 0x80);
d2=8;
if((GetSeqReg(0x01) & 0x01) == 0)
d2=9;
vm->HTotal = (GetCrtcReg(0x00) + 5) * d2;
vm->HDisp = (GetCrtcReg(0x01) + 1) * d2;
d0 = GetCrtcReg(0x02);
vm->HBStart = d0 * d2;
d1 = (GetCrtcReg(0x03) & 0x1F) | BitMov(0, 5, GetCrtcReg(0x05), 7);
while( (d0 & 0x3F) != (d1 & 0x3F) )
{
d0 += 1;
}
vm->HBEnd = d0 * d2;
d0 = GetCrtcReg(0x04);
vm->HSStart = d0 * d2; // + mc->hskew;
d1 = (GetCrtcReg(0x05) & 0x1F);
while( (d0 & 0x1F) != (d1 & 0x1F) )
{
d0 += 1;
}
vm->HSEnd = d0 * d2;
vm->VTotal = (GetCrtcReg(0x06) | BitMov(0, 8, GetCrtcReg(0x07), 0) | BitMov(0, 9, GetCrtcReg(0x07), 5) ) + 2;
vm->VDisp = (GetCrtcReg(0x12) | BitMov(0, 8, GetCrtcReg(0x07), 1) | BitMov(0, 9, GetCrtcReg(0x07), 6) ) + 1;
vm->VBStart = (GetCrtcReg(0x15) | BitMov(0, 8, GetCrtcReg(0x07), 3) | BitMov(0, 9, GetCrtcReg(0x09), 5) );
vm->VSStart = (GetCrtcReg(0x10) | BitMov(0, 8, GetCrtcReg(0x07), 2) | BitMov(0, 9, GetCrtcReg(0x07), 7) );
d0 = vm->VSStart;
d1 = GetCrtcReg(0x11) & 0x0F;
while( (d0 & 0x0F) != (d1 & 0x0F) )
{
d0 += 1;
}
vm->VSEnd = d0;
d0 = vm->VBStart;
d1 = GetCrtcReg(0x16);
while( (d0 & 0xFF) != (d1 & 0xFF) )
{
d0 += 1;
}
vm->VBEnd = d0;
//GetPolarity(&vm->hpolarity, &vm->vpolarity);
vm->doublescan = BitMov(0, 0, GetCrtcReg(0x09), 7);
// vm->dotclockHz = GetVGAVClk() / (long)GetSeqDivider();
vm->horzHz = CalcHorizontalHz(vm->dotclockHz, vm->HTotal);
vm->vert001Hz = CalcVert001Hz(vm->dotclockHz, vm->HTotal, vm->VTotal, 0);
vm->width=vm->HDisp;
vm->height=vm->VDisp/((GetCrtcReg(0x09) & 0x1F) + 1);//GetScreenHeight(vm->VDisp, vm->doublescan, vm->interlace);
*width=vm->width;
*height=vm->height;
}
void Copy_CRTCPARAM_to_VIDEOMODE(VIDEOMODE *vm, CRTCPARAM *cp)
{
vm->HTotal = cp->HTotal; /* Horizontal */
vm->HDisp = cp->HDisp;
vm->HBStart = cp->HBStart;
vm->HSStart = cp->HSStart;
vm->HSEnd = cp->HSEnd;
vm->HBEnd = cp->HBEnd;
vm->VTotal = cp->VTotal; /* Vertical */
vm->VDisp = cp->VDisp;
vm->VBStart = cp->VBStart;
vm->VSStart = cp->VSStart;
vm->VSEnd = cp->VSEnd;
vm->VBEnd = cp->VBEnd;
vm->hpolarity = cp->hpolarity; /* Others */
vm->vpolarity = cp->vpolarity;
vm->doublescan = cp->doublescan;
vm->interlace = cp->interlace;
vm->interlaceratio = cp->interlaceratio;
vm->dotclockHz = cp->dotclockHz; /* Clock */
vm->horzHz = cp->horzHz;
vm->vert001Hz = cp->vert001Hz;
vm->width = cp->width;
vm->height = cp->height;
}
void Copy_VIDEOMODE_to_CRTCPARAM(CRTCPARAM *cp, VIDEOMODE *vm)
{
cp->HTotal = vm->HTotal; /* Horizontal */
cp->HDisp = vm->HDisp;
cp->HBStart = vm->HBStart;
cp->HSStart = vm->HSStart;
cp->HSEnd = vm->HSEnd;
cp->HBEnd = vm->HBEnd;
cp->VTotal = vm->VTotal; /* Vertical */
cp->VDisp = vm->VDisp;
cp->VBStart = vm->VBStart;
cp->VSStart = vm->VSStart;
cp->VSEnd = vm->VSEnd;
cp->VBEnd = vm->VBEnd;
cp->hpolarity = vm->hpolarity; /* Others */
cp->vpolarity = vm->vpolarity;
cp->doublescan = vm->doublescan;
cp->interlace = vm->interlace;
cp->interlaceratio = vm->interlaceratio;
cp->dotclockHz = vm->dotclockHz; /* Clock */
cp->horzHz = vm->horzHz;
cp->vert001Hz = vm->vert001Hz;
cp->width = vm->width;
cp->height = vm->height;
}
int GetMode15KHz(CRTCPARAM *cp, int xres, int yres)
{
extern PROGRAMtag PROGRAM;
VIDEOMODE *ListPtr;
int idx;
char found;
int x;
int y;
ListPtr = &PROGRAM.VideoModes[0];
found = 0;
idx = 0;
while(1)
{
x = (ListPtr + idx)->width;
y = (ListPtr + idx)->height;
if(x == 0 || y == 0 || (ListPtr + idx)->index == 0)
{
/* Mode not found */
break;
}
else if(x == xres && y == yres)
{
found = 1;
break;
}
idx += 1;
}
if (found)
{
Copy_VIDEOMODE_to_CRTCPARAM(cp, (ListPtr + idx));
}else{
*cp = mode640x200_60;
}
return found;
}
void SetGenericVGARegister(CRTCPARAM *cp, int h_sync_delay, int h_disp_delay)
{
int d0;
int d1;
int HDispSkew;
int HSyncDelay;
HSyncDelay = h_sync_delay & 0x03;
HDispSkew = h_disp_delay & 0x03;
// Unlock
SetCrtcReg(0x11, BitMov(GetCrtcReg(0x11), 7, 0, 0));
// HTotal
d0 = cp->HTotal;
d0 = (d0 / 8) - 5;
SetCrtcReg(0x00, d0 & 0xFF);
// HDisp
d0 = cp->HDisp;
d0 = (d0 / 8) - 1;
SetCrtcReg(0x01, d0 & 0xFF);
// HBlankStart
d0 = cp->HBStart;
d0 = d0 / 8;
SetCrtcReg(0x02, d0 & 0xFF);
// HBlankEnd
d0 = cp->HBEnd;
d0 = d0 / 8;
d1 = GetCrtcReg(0x03);
d1 = BitMov(d1, 0, d0, 0);
d1 = BitMov(d1, 1, d0, 1);
d1 = BitMov(d1, 2, d0, 2);
d1 = BitMov(d1, 3, d0, 3);
d1 = BitMov(d1, 4, d0, 4);
d1 = BitMov(d1, 5, HDispSkew, 0); // horizontal disp skew
d1 = BitMov(d1, 6, HDispSkew, 1); // horizontal disp skew
d1 = BitMov(d1, 7, 1, 0); // compatible read
SetCrtcReg(0x03, d1);
SetCrtcReg(0x05, BitMov(GetCrtcReg(0x05), 7, d0, 5));
// HSyncStart
d0 = cp->HSStart;
d0 = d0 / 8;
SetCrtcReg(0x04, d0 & 0xFF);
// HSyncEnd
d0 = cp->HSEnd;
d0 = d0 / 8;
d1 = GetCrtcReg(0x05);
d1 = BitMov(d1, 0, d0, 0);
d1 = BitMov(d1, 1, d0, 1);
d1 = BitMov(d1, 2, d0, 2);
d1 = BitMov(d1, 3, d0, 3);
d1 = BitMov(d1, 4, d0, 4);
d1 = BitMov(d1, 5, HSyncDelay, 0);
d1 = BitMov(d1, 6, HSyncDelay, 1);
SetCrtcReg(0x05, d1);
// VTotal
d0 = cp->VTotal;
d0 = d0 - 2;
SetCrtcReg(0x06, d0 & 0xFF);
SetCrtcReg(0x07, BitMov(GetCrtcReg(0x07), 0, d0, 8));
SetCrtcReg(0x07, BitMov(GetCrtcReg(0x07), 5, d0, 9));
// VDisp
d0 = cp->VDisp;
d0 = d0 - 1;
SetCrtcReg(0x12, d0 & 0xFF);
SetCrtcReg(0x07, BitMov(GetCrtcReg(0x07), 1, d0, 8));
SetCrtcReg(0x07, BitMov(GetCrtcReg(0x07), 6, d0, 9));
// VBlankStart
d0 = cp->VBStart;
SetCrtcReg(0x15, d0 & 0xFF);
SetCrtcReg(0x07, BitMov(GetCrtcReg(0x07), 3, d0, 8));
SetCrtcReg(0x09, BitMov(GetCrtcReg(0x09), 5, d0, 9));
// VBlankEnd
d0 = cp->VBEnd;
SetCrtcReg(0x16, d0 & 0xFF);
// VSyncStart
d0 = cp->VSStart;
SetCrtcReg(0x10, d0 & 0xFF);
d1 = GetCrtcReg(0x07);
d1 = BitMov(d1, 2, d0, 8); // bit 8
d1 = BitMov(d1, 7, d0, 9); // bit 9
SetCrtcReg(0x07, d1);
// VSyncEnd
d0 = cp->VSEnd;
d0 = d0 & 0x0F;
d1 = GetCrtcReg(0x11) & 0xF0;
d1 = d1 | d0;
SetCrtcReg(0x11, d1);
// Double Scan Dis.
SetCrtcReg(0x09, BitMov(GetCrtcReg(0x09), 7, 0, 0));
}
void AdjustCenter(CRTCPARAM *cp, int center_x, int center_y)
{
int d0;
if(center_x < 0){
if((cp->HSStart + center_x) < (cp->HDisp + 8)){
d0 = cp->HSStart;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -