📄 ct69000.cpp
字号:
//
modeNo = m_ulVideoMode;
//
// return smaller desktop here if you want to test
// e.g. 480x240 on larger configurations...
//
*pMode = *gpemodes[modeNo];
#if EMULATE_PPCDISPLAY
pMode->width =PPC_WIDTH;
pMode->height=PPC_HEIGHT;
#endif //EMULATE_PPCDISPLAY
return S_OK;
}
//-----------------------------------------------------------------------
//
// CT69000::NumModes
//
// return number of supported video modes
//
//-----------------------------------------------------------------------
INT
CT69000::NumModes(void)
{
DEBUGMSG(CT69K_ZONE_FUNCTION, (TEXT("CT69000::NumModes()\r\n")));
//
// since Win CE GDI cannot change the video mode on the fly, we return
// always 1 here
//
return 1;
return N_GPEMODES;
}
//-----------------------------------------------------------------------
//
// DrvGetMasks
//
// return RGB mask info
//
//-----------------------------------------------------------------------
PULONG APIENTRY
DrvGetMasks(DHPDEV dhpdev)
{
CT69000 *pCT69k=(CT69000 *) dhpdev;
return pCT69k->m_ulBitMasks;
}
//-----------------------------------------------------------------------
//
// CT69000::GetPhysicalVideoMemory
//
// return some frame buffer data to gpe
//
//-----------------------------------------------------------------------
VOID
CT69000::GetPhysicalVideoMemory(PULONG pPhysicalMemoryBase,
PULONG pVideoMemorySize)
{
*pPhysicalMemoryBase = (ULONG) m_pFrameBuffer;
*pVideoMemorySize = m_ulVideoMemorySize;
}
#if !BIOSSETUP
//-----------------------------------------------------------------------
//
// CT69000::SetDisplayMode
//
// take a register/data list and fill hardware registers with setup
// for specified video mode
//
//-----------------------------------------------------------------------
VOID
CT69000::SetDisplayMode( VGAPortData *pData)
{
//
// some default setups!
//
WRITE_LIN_UCHAR( VGA_MSR_REG, 3); // set regs to CGA emulation (3dx)
SetXR( 9, 1);
SetXR( 0xa, 2); // enable linear frame buffer, disable a0000 window
SetXR( 0xb, 9); // enable pci bursts, disable for text expansion
SetXR( 0x20, 2); // reset blt engine
SetXR( 0x40, 3); // high res modes, no wrap!
if (m_bHasVGARegs)
{
while (pData->wAddress != 0)
{
if (pData->bIndex==0xff)
{
//
// just write data on address without index
//
WRITE_PORT_UCHAR( (PUCHAR)pData->wAddress, pData->bData);
} else
{
//
// write VGA type of indexed register
//
WRITE_PORT_UCHAR( (PUCHAR)pData->wAddress, pData->bIndex);
//
// special handling if writing on attribute controller:
// be aware to reset toggle flip-flop and data is written
// on index port!
//
if (pData->wAddress==0x3c0)
{
WRITE_PORT_UCHAR( (PUCHAR)(pData->wAddress), pData->bData);
READ_PORT_UCHAR( (PUCHAR) 0x3da); // reset 0x3c0 toggle flipflop
} else
{
WRITE_PORT_UCHAR( (PUCHAR)(pData->wAddress+1), pData->bData);
}
}
pData++;
}
} else
{
//
// in the case that our card has no VGA registers, we need to
// initialize through the memory mapped registers!
//
while (pData->wAddress != 0)
{
if (pData->bIndex==0xff)
{
//
// just write data on address without index
//
WRITE_LIN_UCHAR( pData->wAddress, pData->bData);
} else
{
//
// write VGA type of indexed register
//
WRITE_LIN_UCHAR( pData->wAddress, pData->bIndex);
//
// special handling if writing on attribute controller:
// be aware to reset toggle flip-flop and data is written
// on index port!
//
if (pData->wAddress==0x3c0)
{
WRITE_LIN_UCHAR( (pData->wAddress), pData->bData);
READ_LIN_UCHAR( 0x3da); // reset 0x3c0 toggle flipflop
} else
{
WRITE_LIN_UCHAR( (pData->wAddress+1), pData->bData);
}
}
pData++;
}
}
}
//-----------------------------------------------------------------------
//
// CT69000::GetClockSpeed
//
// bBase----oscillator n (n=0..3)
// return---clock of VCO output in Hz
//
//-----------------------------------------------------------------------
INT
CT69000::GetClockSpeed ( DWORD dwBase)
{
DWORD dwFOut, dwVCO;
DWORD dwM, dwN, dwPD, dwVLD;
dwBase = 0xc0+dwBase*4;
dwM=GetXR((BYTE)dwBase)+2;
dwN=GetXR((BYTE)dwBase+1)+2;
DWORD dwTemp= GetXR((BYTE)dwBase+3);
dwPD = 1<<((dwTemp >> 4) & 7);
dwVLD= (dwTemp & 4)?1:4;
dwVCO=(CT69000_REF_CLOCK * dwM * dwVLD) / dwN ;
dwFOut=dwVCO / dwPD;
DEBUGMSG( CT69K_ZONE_INIT,
(TEXT("osc: %02x, M: %d N: %d PD: %d VLD: %d clock: %ld %ld\r\n"),
dwBase, dwM, dwN, dwPD, dwVLD, dwVCO, dwFOut));
return dwFOut;
}
//-----------------------------------------------------------------------
//
// CT69000::SetVCO
//
// program VCO to new clock speed.
//
// dwBase---oscillator 0..3
// see manual for m,n,vld and pd.
// note: only oscillator 2 should be changed.
//
//-----------------------------------------------------------------------
VOID
CT69000::SetVCO ( DWORD dwBase, INT M, INT N, INT VLD, INT PD)
{
DWORD dwRealPD;
dwBase = 0xc0+dwBase*4;
SetXR((BYTE) dwBase, (BYTE) (M-2));
SetXR((BYTE) dwBase+1, (BYTE)(N-2));
dwRealPD=0;
while (PD>1)
{
PD >>= 1;
dwRealPD++;
}
SetXR((BYTE) dwBase+3, (BYTE)((dwRealPD << 4) | ((VLD==1)?4:0)));
}
//-----------------------------------------------------------------------
//
// CT69000::SetRefreshRate
//
// set refresh rate to 60Hz, 75Hz or 85Hz
// this function can only be called once after resetting the device.
// It assumes the current videomode was programmed for 60 Hz and
// increases the clock speed of oscillator 2 according to the factor
// of refreshrate/60Hz. Not tested with LCD/TFT displays.
//
//-----------------------------------------------------------------------
VOID
CT69000::SetRefreshRate( DWORD dwRefreshRate)
{
INT M, N, PD, VLD;
INT BestM, BestN;
INT BestClock;
INT BaseClock, NewClock;
#if DEBUG
//
// read DotClock 2:
//
GetClockSpeed(0);
GetClockSpeed(1);
GetClockSpeed(2);
GetClockSpeed(3);
#endif
//
// set refresh rate
//
if (dwRefreshRate<=60) return;
BaseClock=GetClockSpeed( 2);
NewClock =(BaseClock/60)*dwRefreshRate;
VLD = 1;
N = 1;
M = 1;
BestM=1;
BestN=1;
//
// first adjust post divide VCO speed should be larger than 100Mhz
//
PD = 1;
while (NewClock*PD < 100000000L)
{
PD <<= 1;
}
BestClock=ClockSpeed( M, N, VLD, PD);
//
// iterate until N is at largest value
//
while (N<=257)
{
INT CurrentClock=ClockSpeed( M, N, VLD, PD);
if (labs(CurrentClock-NewClock) <
labs(BestClock-NewClock))
{
//
// we should check here for exclusion conditions
// otherwise remember new best fit
BestClock=CurrentClock;
BestM=M;
BestN=N;
}
if (CurrentClock>NewClock)
{
// clock too high, increase N
N++;
//
// decrease M until new clock speed is lower than
// demanded speed
//
while ( M>1 &&
ClockSpeed( M, N, VLD, PD)>NewClock)
M--;
} else
{
// clock too low, increase M
//
M++;
// !end!
//
if (M>257)
break;
}
}
DEBUGMSG( CT69K_ZONE_INIT,
(TEXT("new oscillator settings found for %ld:\r\n"), NewClock));
DEBUGMSG( CT69K_ZONE_INIT,
(TEXT("-- M: %d N: %d PD: %d VLD: %d clock: %ld %ld\r\n"),
BestM, BestN, PD, VLD, VCOSpeed(BestM, BestN, VLD),
ClockSpeed(BestM, BestN, VLD, PD)));
//
// finally program VCO
//
SetVCO( 2, BestM, BestN, VLD, PD);
}
#endif //!BIOSSETUP
//-----------------------------------------------------------------------
//
// CT69000::InVBlank()
//
// Return TRUE if in Vertical Blank, otherwise FALSE
//
//-----------------------------------------------------------------------
INT
CT69000::InVBlank()
{
return GetVGAStatus() & 0x08;
}
//-----------------------------------------------------------------------
//
// CT69000::SetPalette
//
// src---------data for palette entries
// firstEntry--index of first entry to modify
// numEntries--number of entries to modify
//
// modify numEntries of palette data beginning from firstEntry with src
//
//-----------------------------------------------------------------------
SCODE
CT69000::SetPalette( const PALETTEENTRY *src,
USHORT firstEntry,
USHORT numEntries)
{
DEBUGMSG(CT69K_ZONE_FUNCTION, (TEXT("CT69000::SetPalette()\r\n")));
if (firstEntry < 0 || firstEntry + numEntries > 256)
return E_INVALIDARG;
if (!m_bChip69030)
{
for (; numEntries; numEntries--)
{
WRITE_LIN_UCHAR( VGA_DAC_WR_AD, (UCHAR)firstEntry++);
WRITE_LIN_UCHAR( VGA_DAC_DATA, src->peRed >> 2);
WRITE_LIN_UCHAR( VGA_DAC_DATA, src->peGreen >> 2);
WRITE_LIN_UCHAR( VGA_DAC_DATA, src->peBlue >> 2);
src++;
}
}
else
{
//
// chip bug! PC hangs if ports were accessed via memory port
//
for (; numEntries; numEntries--)
{
WRITE_PORT_UCHAR( (PUCHAR)VGA_DAC_WR_AD, (UCHAR)firstEntry++);
WRITE_PORT_UCHAR( (PUCHAR)VGA_DAC_DATA, src->peRed >> 2);
WRITE_PORT_UCHAR( (PUCHAR)VGA_DAC_DATA, src->peGreen >> 2);
WRITE_PORT_UCHAR( (PUCHAR)VGA_DAC_DATA, src->peBlue >> 2);
src++;
}
}
return S_OK;
}
//-----------------------------------------------------------------------
//
// CT69000::SetXRPort
//
// C&T69000 specific: write XR register (ucIndex) with ucData
//
//-----------------------------------------------------------------------
VOID
CT69000::SetXRPort( UCHAR ucIndex, UCHAR ucData)
{
ASSERT(m_bHasVGARegs);
WRITE_PORT_UCHAR(CT69000_XRPORTINDEX,ucIndex);
WRITE_PORT_UCHAR(CT69000_XRPORTDATA,ucData);
}
//-----------------------------------------------------------------------
//
// CT69000::GetXRPort
//
// C&T69000 specific: read XR register (ucIndex)
//
//-----------------------------------------------------------------------
UCHAR
CT69000::GetXRPort( UCHAR ucIndex)
{
ASSERT(m_bHasVGARegs);
WRITE_PORT_UCHAR(CT69000_XRPORTINDEX,ucIndex);
return READ_PORT_UCHAR(CT69000_XRPORTDATA);
}
//-----------------------------------------------------------------------
//
// CT69000::WRITE_LIN_UCHAR
//
// write bData to a VGA port at wAddress via the shadow in linear memory
//
//-----------------------------------------------------------------------
VOID
CT69000::WRITE_LIN_UCHAR( WORD wAddress, BYTE bData)
{
m_pCtrlRegister[VGAtoLinear[wAddress-CT69000_VGABASE]] = bData;
}
//-----------------------------------------------------------------------
//
// CT69000::READ_LIN_UCHAR
//
// read from a VGA port at wAddress via the shadow in linear memory
//
//-----------------------------------------------------------------------
BYTE
CT69000::READ_LIN_UCHAR( WORD wAddress)
{
return m_pCtrlRegister[VGAtoLinear[wAddress-CT69000_VGABASE]];
}
//-----------------------------------------------------------------------
//
// CT69000::IsBusy()
//
// return TRUE if hardware is busy drawing or FALSE when hardware
// has finished.
//
//-----------------------------------------------------------------------
INT
CT69000::IsBusy()
{
return BltEngineBusy();
}
//-----------------------------------------------------------------------
//
// CT69000::WaitForNotBusy
//
// This function is called by gpe before each software drawing
// operation. Wait here until hardware has finished drawing to avoid
// visible artifacts when software starts to draw before hardware has
// finished
//
//-----------------------------------------------------------------------
VOID
CT69000::WaitForNotBusy()
{
INT i=5000000;
//
// dummy read from buffer to flush cached writes
//
UCHAR ucTmp=*m_pFrameBuffer;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -