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

📄 pcivideo.cpp

📁 djgpp bt878 capture for DOS
💻 CPP
📖 第 1 页 / 共 2 页
字号:

    value = ReadLocalDWORD( 0x00 ) & 0x80;

    return( (value) ? TRUE : FALSE );
}


/*******************************************************************************
    Start the current RISC program.
*******************************************************************************/
void PCI_VIDEO::RunRisc( void )
{
    Odd->RunRisc();
}


/*******************************************************************************
    Stop the current RISC program.
*******************************************************************************/
void PCI_VIDEO::HaltRisc( void )
{
    Odd->HaltRisc();
}


DWORD PCI_VIDEO::GetInterruptStatus(void)
{
    DWORD value;
    
    value = ReadLocalDWORD( 0x100 );

    return value;
}

void PCI_VIDEO::SetInterruptStatus(DWORD value)
{
    WriteLocalDWORD( 0x100, value);
}

DWORD PCI_VIDEO::GetInterruptMask(void)
{
    DWORD value;
    
    value = ReadLocalDWORD( 0x104 );

    return value & 0x0FFFFFFF;
}

void PCI_VIDEO::SetInterruptMask(DWORD value)
{
    WriteLocalDWORD( 0x104, value & 0x0FFFFFFF);
}


void PCI_VIDEO::SetPLL()
{
    WriteLocalDWORD( 0xf0, 0xf9);
    WriteLocalDWORD( 0xf4, 0xdc);
    WriteLocalDWORD( 0xf8, 0x8e);
    WriteLocalDWORD( 0x84, 0x08);
}


void PCI_VIDEO::SetOutputFormat(int bpp)
{
    if( bpp == 8 )
    {
        Even->SetColorFormat( ColorFormatRGB8 );
        Odd->SetColorFormat( ColorFormatRGB8 );
    }
    else if( bpp == 15 )
    {
        Even->SetColorFormat( ColorFormatRGB15 );
        Odd->SetColorFormat( ColorFormatRGB15 );
    }
    else if( bpp == 16 )
    {
        Even->SetColorFormat( ColorFormatRGB16 );
        Odd->SetColorFormat( ColorFormatRGB16 );
    }
    else if( bpp == 24 )
    {
        Even->SetColorFormat( ColorFormatRGB24 );
        Odd->SetColorFormat( ColorFormatRGB24 );
    }
    else if( bpp == 32 )
    {
        Even->SetColorFormat( ColorFormatRGB32 );
        Odd->SetColorFormat( ColorFormatRGB32 );
    }
}


void PCI_VIDEO::CreateRiscWxH(DWORD buffer, int width, int height, int bpp, int offset)
{
    int i;
    DWORD risc_main[1024];
    int risc_loc = 0;

    width *= ((++bpp)>>3);
    
    risc_main[risc_loc++] = RESYNC|VRE_STAT;
    risc_main[risc_loc++] = 0x0;
    if( offset == 0 )
        risc_main[risc_loc++] = RESYNC|FM1_STAT|RESET_RISCS_1111;
    else
        risc_main[risc_loc++] = RESYNC|FM1_STAT|SET_RISCS_0001|RESET_RISCS_1110;
    risc_main[risc_loc++] = 0x0;
    
    if( height > 240 )
    {
        for (i = 0; i < height; i+=2)
        {
            risc_main[risc_loc++] = WRITE | SOL | EOL | width;
            risc_main[risc_loc++] = buffer + width*i;
        }
    }
    else
    {
        for (i = 0; i < height; i++)
        {
            risc_main[risc_loc++] = WRITE | SOL | EOL | width;
            risc_main[risc_loc++] = buffer + width*i;
        }
    }
    
    risc_main[risc_loc++] = RESYNC|VRO_STAT;
    risc_main[risc_loc++] = 0x0;
    risc_main[risc_loc++] = JUMP;
    risc_main[risc_loc++] = Even->GetRiscAddr() + offset;
    
    Odd->SetRisc( risc_main, risc_loc * 4, offset );

    /* now do Even field */
    risc_loc = 0;
    risc_main[risc_loc++] = RESYNC|FM1_STAT;
    risc_main[risc_loc++] = 0x0;
    
    /* create risc program */
    if( height > 240 )
    {
        for (i = 1; i < height; i+=2)
        {
            risc_main[risc_loc++] = WRITE | SOL | EOL | width;
            risc_main[risc_loc++] = buffer + width*i;
        }
    }
    else
    {
        for (i = 0; i < height; i++)
        {
            risc_main[risc_loc++] = WRITE | SOL | EOL | width;
            risc_main[risc_loc++] = buffer + width*i;
        }
    }

    risc_main[risc_loc++] = RESYNC|VRE_STAT;
    risc_main[risc_loc++] = 0x0;
    risc_main[risc_loc++] = JUMP;
    risc_main[risc_loc++] = Odd->GetRiscAddr()+ 8 + offset;

    Even->SetRisc( risc_main, risc_loc * 4, offset );
}


void PCI_VIDEO::CreateRiscWxH_I(DWORD buffer, int width, int height, int bpp, int offset )
{
    int i;
    DWORD risc_main[1024];
    int risc_loc = 0;

    width *= ((++bpp)>>3);
    
    risc_main[risc_loc++] = RESYNC|VRE_STAT;
    risc_main[risc_loc++] = 0x0;
    if( offset == 0 )
        risc_main[risc_loc++] = RESYNC|FM1_STAT|RESET_RISCS_1111;
    else
        risc_main[risc_loc++] = RESYNC|FM1_STAT|SET_RISCS_0001|RESET_RISCS_1110;
    risc_main[risc_loc++] = 0x0;
    
    /* Create odd risc program for width by height output */
    for (i = 0; i < (height+1)/2; i++)
    {
        risc_main[risc_loc++] = WRITE | SOL | EOL | width;
        risc_main[risc_loc++] = buffer + width*i;
    }

    risc_main[risc_loc++] = RESYNC|VRO_STAT;
    risc_main[risc_loc++] = 0x0;
    risc_main[risc_loc++] = JUMP | IRQ;
    risc_main[risc_loc++] = Even->GetRiscAddr() + offset;
    
    Odd->SetRisc( risc_main, risc_loc * 4, offset );

    /* now do Even field */
    risc_loc = 0;
    risc_main[risc_loc++] = RESYNC|FM1_STAT;
    risc_main[risc_loc++] = 0x0;
    
    /* Create even risc program for width by height output */
    for (i = 0; i < height/2; i++)
    {
        risc_main[risc_loc++] = WRITE | SOL | EOL | width;
        risc_main[risc_loc++] = buffer + width*i + 1;
    }

    risc_main[risc_loc++] = RESYNC|VRE_STAT;
    risc_main[risc_loc++] = 0x0;
    risc_main[risc_loc++] = JUMP | IRQ;
    risc_main[risc_loc++] = Odd->GetRiscAddr()+ 8 + offset;

    Even->SetRisc( risc_main, risc_loc * 4, offset );
}

void PCI_VIDEO::Scale(int width, int height, int field )
{
    int value;
    WORD Clkx1_HACTIVE;
    WORD Clkx1_HDELAY;
    WORD Min_Pixels;
    WORD Active_lines_per_field;
    int  VActive;
    WORD AnalogWin_top = 0; /* ??? */
    WORD AnalogWin_left = 0;
    VIDEO_FIELD *vid_field;

    if( field == FieldEven )
        vid_field = Even;
    else
        vid_field = Odd;

    if( GetVideoFormat() == VideoFormatAuto )
        SetVideoFormat( VideoFormatNTSC );

    if( GetVideoFormat() == VideoFormatNTSC )
    {
        Clkx1_HACTIVE = 730;
        Clkx1_HDELAY = 148;
        Min_Pixels = 44;
        Active_lines_per_field = 240;
        VActive = 0x1F4;
    }
    else
    {
        Clkx1_HACTIVE = 914;
        Clkx1_HDELAY = 190;
        Min_Pixels = 48;
        Active_lines_per_field = 284;
        VActive = 0x238;
        SetAGCDelay( 0x7F );
        SetBurstDelay( 0x72 );
    }

    if( height > Active_lines_per_field )
        height /= 2;

    WORD Min_UncroppedPixels = Min_Pixels + 20;
//    WORD Min_UncroppedPixels = Min_Pixels + 100;
    WORD Max_Pixels = ((Clkx1_HACTIVE < 774) ? Clkx1_HACTIVE - 6 : 768);
    WORD Min_Lines = (Active_lines_per_field / 16 + 1) * 2;
    WORD Max_Lines = Active_lines_per_field;
    WORD Max_VFilter1_Pixels = ((Clkx1_HACTIVE > 796) ? 384 : (Clkx1_HACTIVE * 14 / 29));
    WORD Max_VFilter2_Pixels = Clkx1_HACTIVE * 8 / 33;
    WORD Max_VFilter3_Pixels = Clkx1_HACTIVE * 8 / 33;
    WORD Max_VFilter1_Lines = Active_lines_per_field;
    WORD Max_VFilter2_Lines = Active_lines_per_field / 2;
    WORD Max_VFilter3_Lines = Active_lines_per_field * 2 / 5;

    // Calculate Hactive
    WORD m_HActive = min( Max_Pixels, max( (WORD)width, Min_Pixels ) );

    vid_field->SetHActive( m_HActive );


    // No calculation needed for VActive register since it based on the UNSCALED image
    vid_field->SetVActive( VActive );


    // Calculate Vertical Scaling
    WORD m_lines = min( Max_Lines, max( (WORD)height, Min_Lines ) );

    WORD LPB_VScale_Factor = (WORD) ( 1 + ( m_lines - 1 ) / Active_lines_per_field );

    m_lines = (WORD) ( ( m_lines + LPB_VScale_Factor - 1 ) / LPB_VScale_Factor );

    value = (WORD) ( ( 0x10000L - ((DWORD)Active_lines_per_field * 512L / (DWORD)m_lines) + 512L ) & 0x1FFFL );

    vid_field->SetVScale( value );


    // Set the Vertical Filter
    // this is to remove junk lines at the top of video. flag set to off
    // when image hight is above CIF
    DWORD m_VFilter;
    
    if ( VFilterFlag_ == Off )
    {
        m_VFilter = 0;
    }
    else
    {
        if ( ( m_HActive <= Max_VFilter3_Pixels ) &&
              ( m_lines    <= Max_VFilter3_Lines ) )
            m_VFilter = 3;
        else if ( ( m_HActive <= Max_VFilter2_Pixels ) &&
                 ( m_lines    <= Max_VFilter2_Lines ) )
            m_VFilter = 2;
        else if ( ( m_HActive <= Max_VFilter1_Pixels ) &&
                 ( m_lines    <= Max_VFilter1_Lines ) )
            m_VFilter = 1;
        else
            m_VFilter = 0;
    }
    
    vid_field->SetVerticalFilter( m_VFilter );


    WORD VDelay, moreDelay;

    // increase VDelay will eliminate garbage lines at top of image
    switch ( m_VFilter )
    {
        case 3:
            moreDelay = 4;
            break;

        case 2:
            moreDelay = 2;
            break;
                 
        case 1:
        case 0:
        default:
            moreDelay = 0;
            break;
    }

    if ( GetVideoFormat() == VideoFormatNTSC )
        VDelay = 0x001A + moreDelay;     // NTSC
    else
        VDelay = 0x0026 + moreDelay;     // PAL/SECAM
                                     
    // now add the cropping region into VDelay register; i.e. skip some pixels
    // before we start taking them as real image
    VDelay += (WORD)( ( (DWORD)Max_Lines * (DWORD)AnalogWin_top + m_lines - 1 ) / (DWORD)m_lines * 2 );

    vid_field->SetVDelay( VDelay );


   // calculations here requires calculation of HActive first!
    WORD m_pixels = m_HActive;
    if ( m_pixels < Min_UncroppedPixels )
        m_pixels += (WORD) ( ( Min_UncroppedPixels - m_pixels + 9 ) / 10 );

    DWORD a = (DWORD)m_pixels * (DWORD)Clkx1_HDELAY;
    DWORD b = (DWORD)Clkx1_HACTIVE * 2L;
    WORD HDelay = (WORD) ( ( a + (DWORD)Clkx1_HACTIVE * 2 - 1) / b * 2L );

    // now add the cropping region into HDelay register; i.e. skip some pixels
    // before we start taking them as real image
    HDelay += (WORD)AnalogWin_left;

    // HDelay must be even or else color would be wrong
    HDelay &= ~01;

    vid_field->SetHDelay( HDelay );

    // since we increase HDelay, we should decrease HActive by the same amount
    m_HActive -= (WORD)AnalogWin_left;
    vid_field->SetHActive( m_HActive );


    value = (WORD) ( ( ( (DWORD)Clkx1_HACTIVE * 4096L ) / (DWORD)m_pixels ) - 4096L );

    vid_field->SetHScale( value );


    if ( GetVideoFormat() != VideoFormatSECAM )
        value = HFilterAutoFormat;
    else  // SECAM
        if ( m_pixels < Clkx1_HACTIVE / 7 )
            value = HFilterICON;
        else
            value = HFilterQCIF;

    vid_field->SetHorizontalFilter( value );
}


void PCI_VIDEO::StartScaleVideo(DWORD buffer, int width, int height, int bpp )
{
    int offset = 0;
    
    if( height > 576 )
        height = 576;
    if( width > 768 )
        width = 768;
        
    Odd->HaltRisc();
    
    SetOutputFormat(bpp);

    if( height > 240 )
        CreateRiscWxH_I( buffer, width, height, bpp, offset );
    else        
        CreateRiscWxH( buffer, width, height, bpp, offset );

    if( height > 240 )
    {
        Scale(width, (height+1)/2, FieldOdd );
        Scale(width, height/2, FieldEven );
    }
    else
    {
        Scale(width, height, FieldOdd );
        Scale(width, height, FieldEven );
    }


}   

void PCI_VIDEO::CreateRisc384x288(DWORD dwOdd, DWORD dwEven, int bpp)
{
    int i;
    DWORD risc_main[1024];
    int risc_loc = 0;

    int width = 384 * ((++bpp)>>3);
    
    risc_main[risc_loc++] = RESYNC | VRE_STAT;
    risc_main[risc_loc++] = 0x0;
    
    risc_main[risc_loc++] = RESYNC | FM1_STAT;
    
    risc_main[risc_loc++] = 0x0;
    
    for (i = 0; i < 288; i++)
    {
        risc_main[risc_loc++] = WRITE | SOL | EOL | width;
        risc_main[risc_loc++] = dwOdd + width*i;
    }
    
    risc_main[risc_loc++] = RESYNC | VRO_STAT | SET_RISCS_0001;
    risc_main[risc_loc++] = 0x0;
    risc_main[risc_loc++] = JUMP | IRQ;
    risc_main[risc_loc++] = Even->GetRiscAddr();
    
    Odd->SetRisc( risc_main, risc_loc * 4, 0 );
    
    /* now do Even field */
    risc_loc = 0;
    risc_main[risc_loc++] = RESYNC | FM1_STAT;
    risc_main[risc_loc++] = 0x0;
    
    /* create risc program */
    for (i = 0; i < 288; i++)
    {
        risc_main[risc_loc++] = WRITE | SOL | EOL | width;
           risc_main[risc_loc++] = dwEven + width*i;
    }

    risc_main[risc_loc++] = RESYNC | VRE_STAT | RESET_RISCS_0001;
    risc_main[risc_loc++] = 0x0;
    risc_main[risc_loc++] = JUMP | IRQ;
    risc_main[risc_loc++] = Odd->GetRiscAddr()+ 8;

    Even->SetRisc( risc_main, risc_loc * 4, 0);
}


void PCI_VIDEO::Scale384x288x16()
{
    WORD HSCALE;
    WORD HDELAY;
    WORD HACTIVE;
    WORD VSCALE;
    WORD VDELAY;
    WORD VACTIVE;
    
    SetVideoFormat( VideoFormatPAL );
    SetOutputFormat(16);
    SetAGCDelay( 0x7F );
    SetBurstDelay( 0x72 );
    
    HSCALE = 0x1615;
    HDELAY = 0x50;
    HACTIVE = 0x180;
    
    VSCALE = 0x0000;
    VDELAY = 0x20;
    VACTIVE = 0x240;
    
    Odd->SetHScale(HSCALE);
    Even->SetHScale(HSCALE);
    
    Odd->SetHDelay(HDELAY);
    Even->SetHDelay(HDELAY);
    
    Odd->SetHActive(HACTIVE);
    Even->SetHActive(HACTIVE);
    
    Odd->SetVScale(VSCALE);
    Even->SetVScale(VSCALE);
    
    Odd->SetVDelay(VDELAY);
    Even->SetVDelay(VDELAY);
    
    Odd->SetVActive(VACTIVE);
    Even->SetVActive(VACTIVE);
    
    Odd->SetVerticalFilter( 1 );
    Even->SetVerticalFilter( 1 );
    
    SetPLL();
}

⌨️ 快捷键说明

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