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

📄 mode15k.c

📁 用来将电脑连接到电视荧幕, 并以15Khz输出的源码, 请只用在支援15Khz的荧幕上, 以免伤害荧幕
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -