📄 smilynx.c
字号:
pGenDriver->fill = uglGeneric16BitFill;
pGenDriver->hLine = uglGeneric16BitHLine;
pGenDriver->rectFill = uglGeneric16BitRectFill;
pGenDriver->vLine = uglGeneric16BitVLine;
}
smiLynxEnable((SMI_DRIVER*)pDriver);
smiLynxSetVgaRegisters((SMI_DRIVER*)pDriver);
return(UGL_STATUS_OK);
}
UGL_STATUS smiLynxDestroy(UGL_DEVICE_ID devId)
{
SMI_DRIVER * pDriver = (SMI_DRIVER *)devId;
TRACK;
smiLynxDisable(pDriver);
uglGenericClutDestroy(&pDriver->generic);
uglUgiDevDeinit(&pDriver->generic.ugi);
UGL_FREE(devId);
return(UGL_STATUS_OK);
}
UGL_STATUS smiLynxPageDrawSet (UGL_DEVICE_ID devId, UGL_PAGE * pPage)
{
TRACK;
return(UGL_STATUS_OK);
}
UGL_STATUS smiLynxPageVisibleSet (UGL_DEVICE_ID devId, UGL_PAGE * pPage)
{
TRACK;
return(UGL_STATUS_OK);
}
UGL_STATUS smiLynxClutSet(UGL_DEVICE_ID devId, int startIndex,
UGL_ARGB* pColors, UGL_SIZE numColors)
{
SMI_DRIVER * pDriver = (SMI_DRIVER *)devId;
UGL_STATUS status;
int i;
TRACK;
status = uglGenericClutSet(&pDriver->generic.ugi, startIndex,
pColors, numColors);
if (status == UGL_STATUS_OK)
{
sysOutByte(0xfe000000+VGA_DAC_WRITE_REG, startIndex);
for (i = 0; i < numColors; i++)
{
sysOutByte(0xfe000000+VGA_DAC_PEL_DATA, (UGL_RGB_RED(pColors[i])>>2));
sysOutByte(0xfe000000+VGA_DAC_PEL_DATA, (UGL_RGB_GREEN(pColors[i])>> 2));
sysOutByte(0xfe000000+VGA_DAC_PEL_DATA, (UGL_RGB_BLUE(pColors[i])>> 2));
}
}
return(status);
}
UGL_STATUS smiLynxClutGet(UGL_DEVICE_ID devId, int startIndex,
UGL_ARGB* pColors, UGL_SIZE numColors)
{
SMI_DRIVER * pDriver = (SMI_DRIVER *)devId;
TRACK;
return(uglGenericClutGet(&pDriver->generic.ugi, startIndex,
pColors, numColors));
}
#include <stdio.h>
double showmclk(SMI_DRIVER * pDriver)
{
double mclk;
int shift;
char mnr;
char mdr;
mnr = smiReadVgaIndexed(pDriver, VGA_SEQUENCER_REG,
VGA_SEQUENCER_DATA, 0x6a);
mdr = (0x3f & smiReadVgaIndexed(pDriver, VGA_SEQUENCER_REG,
VGA_SEQUENCER_DATA, 0x6b));
switch (mdr >> 6)
{
default:
shift = 1;
break;
case 1:
shift = 4;
break;
case 2:
shift = 2;
break;
}
mdr &= 0x3F;
mclk = ((1431818 * mnr) / mdr / shift + 50) / 100;
printf("mclk: %f\n", mclk);
return(mclk);
}
void vclk(SMI_DRIVER * pDriver)
{
char vnr;
char vdr;
vnr = smiReadVgaIndexed(pDriver, VGA_SEQUENCER_REG,
VGA_SEQUENCER_DATA, 0x6c);
vdr = smiReadVgaIndexed(pDriver, VGA_SEQUENCER_REG,
VGA_SEQUENCER_DATA, 0x6d);
printf("vnr: 0x%x\n", vnr);
printf("vdr: 0x%x\n", vdr);
}
#define BASE_FREQ 14.31818 /* MHz */
void
SMI_CommonCalcClock(long freq, int min_m, int min_n1, int max_n1, int min_n2,
int max_n2, long freq_min, long freq_max,
unsigned char *mdiv, unsigned char *ndiv)
{
double div, diff, best_diff;
unsigned int m;
unsigned char n1, n2;
unsigned char best_n1 = 63, best_n2 = 3, best_m = 255;
double ffreq = freq / 1000.0 / BASE_FREQ;
double ffreq_min = freq_min / 1000.0 / BASE_FREQ;
double ffreq_max = freq_max / 1000.0 / BASE_FREQ;
if (ffreq < ffreq_min / (1 << max_n2))
{
printf("invalid frequency %1.3f MHz [freq >= %1.3f MHz]\n",
ffreq * BASE_FREQ, ffreq_min * BASE_FREQ / (1 << max_n2));
ffreq = ffreq_min / (1 << max_n2);
}
if (ffreq > ffreq_max / (1 << min_n2))
{
printf("invalid frequency %1.3f MHz [freq <= %1.3f MHz]\n",
ffreq * BASE_FREQ, ffreq_max * BASE_FREQ / (1 << min_n2));
ffreq = ffreq_max / (1 << min_n2);
}
/* work out suitable timings */
best_diff = ffreq;
for (n2 = min_n2; n2 <= max_n2; n2++)
{
for (n1 = min_n1; n1 <= max_n1; n1++)
{
m = (int)(ffreq * n1 * (1 << n2) + 0.5);
if ( (m < min_m) || (m > 255) )
{
continue;
}
div = (double)(m) / (double)(n1);
if ( (div >= ffreq_min) && (div <= ffreq_max) )
{
diff = ffreq - div / (1 << n2);
if (diff < 0.0)
{
diff = -diff;
}
if (diff < best_diff)
{
best_diff = diff;
best_m = m;
best_n1 = n1;
best_n2 = n2;
}
}
}
}
printf("Clock parameters for %1.6f MHz: m=%d, n1=%d, n2=%d\n",
((double)(best_m) / (double)(best_n1) / (1 << best_n2)) * BASE_FREQ, best_m, best_n1, best_n2);
*ndiv = best_n1 | (best_n2 << 6);
*mdiv = best_m;
}
void calcclk(SMI_DRIVER * pDriver)
{
char SR6A, SR6B;
SMI_CommonCalcClock(showmclk(pDriver), 1, 1, 31, 0, 2, pDriver->minClock,
pDriver->maxClock, &SR6A, &SR6B);
printf("SR6A: 0x%x\n", SR6A);
printf("SR6B: 0x%x\n", SR6B);
}
void writeVpr(SMI_DRIVER * pDriver, int offset, int value)
{
WRITE_VPR(pDriver, offset, value);
}
void readSmiRegisters(SMI_DRIVER * pDriver)
{
int i;
SMIRegisters * save = &pDriver->smiregs;
save->SR32 = smiReadVgaIndexed(pDriver, VGA_SEQUENCER_REG, VGA_SEQUENCER_DATA, 0x32);
/* select primary shadow registers */
save->CR90[14] = smiReadVgaIndexed(pDriver, VGA_CRTC_REG, VGA_CRTC_DATA, 0x9E);
smiWriteVgaIndexed(pDriver, VGA_CRTC_REG, VGA_CRTC_DATA, 0x9E, save->CR90[14] & ~0x20);
/* read primary shadow registers */
for (i = 0; i < 16; i++)
{
save->CR90[i] = smiReadVgaIndexed(pDriver, VGA_CRTC_REG, VGA_CRTC_DATA, 0x90 + i);
}
save->CR33 = smiReadVgaIndexed(pDriver, VGA_CRTC_REG, VGA_CRTC_DATA, 0x33);
save->CR3A = smiReadVgaIndexed(pDriver, VGA_CRTC_REG, VGA_CRTC_DATA, 0x3A);
for (i = 0; i < 14; i++)
{
save->CR40[i] = smiReadVgaIndexed(pDriver, VGA_CRTC_REG, VGA_CRTC_DATA, 0x40 + i);
}
/* select secondary shadow registers */
smiWriteVgaIndexed(pDriver, VGA_CRTC_REG, VGA_CRTC_DATA, 0x9E, save->CR90[14] | 0x20);
/* read secondary shadow registers */
save->CR33_2 = smiReadVgaIndexed(pDriver, VGA_CRTC_REG, VGA_CRTC_DATA, 0x33);
for (i = 0; i < 14; i++)
{
save->CR40_2[i] = smiReadVgaIndexed(pDriver, VGA_CRTC_REG, VGA_CRTC_DATA, 0x40 + i);
}
save->CR9F_2 = smiReadVgaIndexed(pDriver, VGA_CRTC_REG, VGA_CRTC_DATA, 0x9F);
/* save common registers */
for (i = 0; i < 14; i++)
{
save->CRA0[i] = smiReadVgaIndexed(pDriver, VGA_CRTC_REG, VGA_CRTC_DATA, 0xA0 + i);
}
}
void writeSmiRegisters(SMI_DRIVER * pDriver)
{
int i;
SMIRegisters * restore = &pDriver->smiregs;
smiWriteVgaIndexed(pDriver, VGA_SEQUENCER_REG, VGA_SEQUENCER_DATA, 0x32, restore->SR32);
/* select primary shadow registers */
smiWriteVgaIndexed(pDriver, VGA_CRTC_REG, VGA_CRTC_DATA, 0x9E, restore->CR90[14] & ~0x20);
/* write primary shadow registers */
for (i = 0; i < 16; i++)
{
smiWriteVgaIndexed(pDriver, VGA_CRTC_REG, VGA_CRTC_DATA, 0x90 + i, restore->CR90[i]);
}
smiWriteVgaIndexed(pDriver, VGA_CRTC_REG, VGA_CRTC_DATA, 0x33, restore->CR33);
smiWriteVgaIndexed(pDriver, VGA_CRTC_REG, VGA_CRTC_DATA, 0x3A, restore->CR3A);
for (i = 0; i < 14; i++)
{
smiWriteVgaIndexed(pDriver, VGA_CRTC_REG, VGA_CRTC_DATA, 0x40 + i, restore->CR40[i]);
}
#if 0 /* maybe someday these registers will be important */
/* select secondary shadow registers */
smiWriteVgaIndexed(pDriver, VGA_CRTC_REG, VGA_CRTC_DATA, 0x9E, restore->CR90[14] | 0x20);
/* write secondary shadow registers */
smiWriteVgaIndexed(pDriver, VGA_CRTC_REG, VGA_CRTC_DATA, 0x33, restore->CR33_2);
for (i = 0; i < 14; i++)
{
smiWriteVgaIndexed(pDriver, VGA_CRTC_REG, VGA_CRTC_DATA, 0x40 + i, restore->CR40_2[i]);
}
smiWriteVgaIndexed(pDriver, VGA_CRTC_REG, VGA_CRTC_DATA, 0x9F, restore->CR9F_2);
#endif
/* save common registers */
for (i = 0; i < 14; i++)
{
smiWriteVgaIndexed(pDriver, VGA_CRTC_REG, VGA_CRTC_DATA, 0xA0 + i, restore->CRA0[i]);
}
}
static unsigned char PanelTable[3][14] =
{
{ 0x5F, 0x4F, 0x00, 0x52, 0x1E, 0x0B, 0xDF, 0x00, 0xE9, 0x0B, 0x2E,
0x00, 0x4F, 0xDF },
{ 0x7F, 0x63, 0x00, 0x69, 0x19, 0x72, 0x57, 0x00, 0x58, 0x0C, 0xe0,
0x20, 0x4F, 0x57},
{ 0xA3, 0x7F, 0x00, 0x83, 0x14, 0x24, 0xFF, 0x00, 0x02, 0x08, 0xe5,
0xE0, 0x55, 0xFF },
#if 0 /* 1024x768 original crt settings from frido's code */
{ 0xA3, 0x7F, 0x00, 0x83, 0x14, 0x24, 0xFF, 0x00, 0x02, 0x08, 0xA7,
0xE0, 0x4F, 0xDF },
#endif
};
void shadowRegs(SMI_DRIVER* pDriver)
{
int i, panelIndex;
int width = pDriver->generic.ugi.pMode->width;
SMIRegisters * new = &pDriver->smiregs;
readSmiRegisters(pDriver);
if (width == 640)
{
panelIndex = 0;
}
else if (width == 800)
{
panelIndex = 1;
}
else
{
panelIndex = 2;
}
for (i = 0; i < 14; i++)
{
new->CR40[i] = PanelTable[panelIndex][i];
}
new->CR90[14] = 0x03;
new->CR90[15] = 0x00;
new->CRA0[6] = 0;
new->CRA0[7] = 0;
new->SR32 |= 0x4;
writeSmiRegisters(pDriver);
}
void smiWriteVgaIndexed(SMI_DRIVER * pDriver, UGL_UINT16 indexPort,
UGL_UINT16 dataPort, UGL_UINT8 index, UGL_UINT8 data)
{
*(volatile char *)(((char*)(pDriver->ioBase)) + indexPort) = index;
*(volatile char *)(((char*)(pDriver->ioBase)) + dataPort) = data;
}
void smiWriteVgaIndexed1(SMI_DRIVER * pDriver, UGL_UINT16 indexPort,
UGL_UINT16 dataPort, UGL_UINT8 index, UGL_UINT8 data)
{
*(volatile char *)(((char*)(0xdcf00000)) + indexPort) = index;
*(volatile char *)(((char*)(0xdcf00000)) + dataPort) = data;
}
UGL_UINT8 smiReadVgaIndexed1(SMI_DRIVER * pDriver, UGL_UINT16 indexPort,
UGL_UINT16 dataPort, UGL_UINT8 index)
{
*(volatile char *)(((char*)(0xdcf00000)) + indexPort) = index;
return(*(volatile char *)(((char*)(0xdcf00000)) + dataPort));
}
void smiWriteVga(SMI_DRIVER * pDriver, UGL_UINT16 port, UGL_UINT8 data)
{
*(volatile char *)(((char*)(pDriver->ioBase)) + port) = data;
}
UGL_UINT8 smiReadVgaIndexed(SMI_DRIVER * pDriver, UGL_UINT16 indexPort,
UGL_UINT16 dataPort, UGL_UINT8 index)
{
*(volatile char *)(((char*)(pDriver->ioBase)) + indexPort) = index;
return(*(volatile char *)(((char*)(pDriver->ioBase)) + dataPort));
}
UGL_UINT8 smiReadVga(SMI_DRIVER * pDriver, UGL_UINT16 port)
{
return(*(volatile char *)(((char*)(pDriver->ioBase)) + port));
}
UGL_UINT8 smiReadVga1(SMI_DRIVER * pDriver, UGL_UINT16 port)
{
return(*(volatile char *)(((char*)(0xdcf00000)) + port));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -