📄 ct69000.c
字号:
out8 ((pGD->isaBase + index), val);}/********************************************************************************* Read CT ISA register indexed*/static unsigned charctRead_i (unsigned short index, char reg){ GraphicDevice *pGD = (GraphicDevice *) & ctfb; if (index == CT_AR_O) /* synch the Flip Flop */ in8 (pGD->isaBase + CT_STATUS_REG1_O); out8 ((pGD->isaBase + index), reg); return (in8 (pGD->isaBase + index + 1));}/********************************************************************************* Write CT ISA register indexed*/static voidctWrite_i (unsigned short index, char reg, char val){ GraphicDevice *pGD = (GraphicDevice *) & ctfb; if (index == CT_AR_O) { /* synch the Flip Flop */ in8 (pGD->isaBase + CT_STATUS_REG1_O); out8 ((pGD->isaBase + index), reg); out8 ((pGD->isaBase + index), val); } else { out8 ((pGD->isaBase + index), reg); out8 ((pGD->isaBase + index + 1), val); }}/********************************************************************************* Write a table of CT ISA register*/static voidctLoadRegs (unsigned short index, CT_CFG_TABLE * regTab){ while (regTab->reg != 0xFF) { ctWrite_i (index, regTab->reg, regTab->val); regTab++; }}/*****************************************************************************/static voidSetArRegs (void){ int i, tmp; for (i = 0; i < 0x10; i++) ctWrite_i (CT_AR_O, i, i); if (text) tmp = 0x04; else tmp = 0x41; ctWrite_i (CT_AR_O, 0x10, tmp); /* Mode Control Register */ ctWrite_i (CT_AR_O, 0x11, 0x00); /* Overscan Color Register */ ctWrite_i (CT_AR_O, 0x12, 0x0f); /* Memory Plane Enable Register */ if (fntwidth == 9) tmp = 0x08; else tmp = 0x00; ctWrite_i (CT_AR_O, 0x13, tmp); /* Horizontal Pixel Panning */ ctWrite_i (CT_AR_O, 0x14, 0x00); /* Color Select Register */ ctWrite (CT_AR_O, 0x20); /* enable video */}/*****************************************************************************/static voidSetGrRegs (void){ /* Set Graphics Mode */ int i; for (i = 0; i < 0x05; i++) ctWrite_i (CT_GR_O, i, 0); if (text) { ctWrite_i (CT_GR_O, 0x05, 0x10); ctWrite_i (CT_GR_O, 0x06, 0x02); } else { ctWrite_i (CT_GR_O, 0x05, 0x40); ctWrite_i (CT_GR_O, 0x06, 0x05); } ctWrite_i (CT_GR_O, 0x07, 0x0f); ctWrite_i (CT_GR_O, 0x08, 0xff);}/*****************************************************************************/static voidSetSrRegs (void){ int tmp = 0; ctWrite_i (CT_SR_O, 0x00, 0x00); /* reset */ /*rr( sr, 0x01, tmp ); if( fntwidth == 8 ) tmp |= 0x01; else tmp &= ~0x01; wr( sr, 0x01, tmp ); */ if (fntwidth == 8) ctWrite_i (CT_SR_O, 0x01, 0x01); /* Clocking Mode Register */ else ctWrite_i (CT_SR_O, 0x01, 0x00); /* Clocking Mode Register */ ctWrite_i (CT_SR_O, 0x02, 0x0f); /* Enable CPU wr access to given memory plane */ ctWrite_i (CT_SR_O, 0x03, 0x00); /* Character Map Select Register */ if (text) tmp = 0x02; else tmp = 0x0e; ctWrite_i (CT_SR_O, 0x04, tmp); /* Enable CPU accesses to the rest of the 256KB total VGA memory beyond the first 64KB and set fb mapping mode. */ ctWrite_i (CT_SR_O, 0x00, 0x03); /* enable */}/*****************************************************************************/static voidSetBitsPerPixelIntoXrRegs (int bpp){ unsigned int n = (bpp >> 3), tmp; /* only for 15, 8, 16, 24 bpp */ static char md[4] = { 0x04, 0x02, 0x05, 0x06 }; /* DisplayColorMode */ static char off[4] = { ~0x20, ~0x30, ~0x20, ~0x10 }; /* mask */ static char on[4] = { 0x10, 0x00, 0x10, 0x20 }; /* mask */ if (bpp == 15) n = 0; tmp = ctRead_i (CT_XR_O, 0x20); tmp &= off[n]; tmp |= on[n]; ctWrite_i (CT_XR_O, 0x20, tmp); /* BitBLT Configuration */ ctWrite_i (CT_XR_O, 0x81, md[n]);}/*****************************************************************************/static voidSetCrRegs (struct ctfb_res_modes *var, int bits_per_pixel){ /* he -le- ht|0 hd -ri- hs -h- he */ unsigned char cr[0x7a]; int i, tmp; unsigned int hd, hs, he, ht, hbe; /* Horizontal. */ unsigned int vd, vs, ve, vt; /* vertical */ unsigned int bpp, wd, dblscan, interlaced, bcast, CrtHalfLine; unsigned int CompSyncCharClkDelay, CompSyncPixelClkDelay; unsigned int NTSC_PAL_HorizontalPulseWidth, BlDelayCtrl; unsigned int HorizontalEqualizationPulses; unsigned int HorizontalSerration1Start, HorizontalSerration2Start; const int LineCompare = 0x3ff; unsigned int TextScanLines = 1; /* this is in fact a vertical zoom factor */ unsigned int RAMDAC_BlankPedestalEnable = 0; /* 1=en-, 0=disable, see XR82 */ hd = (var->xres) / 8; /* HDisp. */ hs = (var->xres + var->right_margin) / 8; /* HsStrt */ he = (var->xres + var->right_margin + var->hsync_len) / 8; /* HsEnd */ ht = (var->left_margin + var->xres + var->right_margin + var->hsync_len) / 8; /* HTotal */ hbe = ht - 1; /* HBlankEnable todo docu wants ht here, but it does not work */ /* ve -up- vt|0 vd -lo- vs -v- ve */ vd = var->yres; /* VDisplay */ vs = var->yres + var->lower_margin; /* VSyncStart */ ve = var->yres + var->lower_margin + var->vsync_len; /* VSyncEnd */ vt = var->upper_margin + var->yres + var->lower_margin + var->vsync_len; /* VTotal */ bpp = bits_per_pixel; dblscan = (var->vmode & FB_VMODE_DOUBLE) ? 1 : 0; interlaced = var->vmode & FB_VMODE_INTERLACED; bcast = var->sync & FB_SYNC_BROADCAST; CrtHalfLine = bcast ? (hd >> 1) : 0; BlDelayCtrl = bcast ? 1 : 0; CompSyncCharClkDelay = 0; /* 2 bit */ CompSyncPixelClkDelay = 0; /* 3 bit */ if (bcast) { NTSC_PAL_HorizontalPulseWidth = 7; /*( var->hsync_len >> 1 ) + 1 */ HorizontalEqualizationPulses = 0; /* inverse value */ HorizontalSerration1Start = 31; /* ( ht >> 1 ) */ HorizontalSerration2Start = 89; /* ( ht >> 1 ) */ } else { NTSC_PAL_HorizontalPulseWidth = 0; /* 4 bit: hsync pulse width = ( ( CR74[4:0] - CR74[5] ) * / 2 ) + 1 --> CR74[4:0] = 2*(hs-1) + CR74[5] */ HorizontalEqualizationPulses = 1; /* inverse value */ HorizontalSerration1Start = 0; /* ( ht >> 1 ) */ HorizontalSerration2Start = 0; /* ( ht >> 1 ) */ } if (bpp == 15) bpp = 16; wd = var->xres * bpp / 64; /* double words per line */ if (interlaced) { /* we divide all vertical timings, exept vd */ vs >>= 1; ve >>= 1; vt >>= 1; } memset (cr, 0, sizeof (cr)); cr[0x00] = 0xff & (ht - 5); cr[0x01] = hd - 1; /* soll:4f ist 59 */ cr[0x02] = hd; cr[0x03] = (hbe & 0x1F) | 0x80; /* hd + ht - hd */ cr[0x04] = hs; cr[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f); cr[0x06] = (vt - 2) & 0xFF; cr[0x30] = (vt - 2) >> 8; cr[0x07] = ((vt & 0x100) >> 8) | ((vd & 0x100) >> 7) | ((vs & 0x100) >> 6) | ((vs & 0x100) >> 5) | ((LineCompare & 0x100) >> 4) | ((vt & 0x200) >> 4) | ((vd & 0x200) >> 3) | ((vs & 0x200) >> 2); cr[0x08] = 0x00; cr[0x09] = (dblscan << 7) | ((LineCompare & 0x200) >> 3) | ((vs & 0x200) >> 4) | (TextScanLines - 1); cr[0x10] = vs & 0xff; /* VSyncPulseStart */ cr[0x32] = (vs & 0xf00) >> 8; /* VSyncPulseStart */ cr[0x11] = (ve & 0x0f); /* | 0x20; */ cr[0x12] = (vd - 1) & 0xff; /* LineCount */ cr[0x31] = ((vd - 1) & 0xf00) >> 8; /* LineCount */ cr[0x13] = wd & 0xff; cr[0x41] = (wd & 0xf00) >> 8; cr[0x15] = vs & 0xff; cr[0x33] = (vs & 0xf00) >> 8; cr[0x38] = (0x100 & (ht - 5)) >> 8; cr[0x3C] = 0xc0 & hbe; cr[0x16] = (vt - 1) & 0xff; /* vbe - docu wants vt here, */ cr[0x17] = 0xe3; /* but it does not work */ cr[0x18] = 0xff & LineCompare; cr[0x22] = 0xff; /* todo? */ cr[0x70] = interlaced ? (0x80 | CrtHalfLine) : 0x00; /* check:0xa6 */ cr[0x71] = 0x80 | (RAMDAC_BlankPedestalEnable << 6) | (BlDelayCtrl << 5) | ((0x03 & CompSyncCharClkDelay) << 3) | (0x07 & CompSyncPixelClkDelay); /* todo: see XR82 */ cr[0x72] = HorizontalSerration1Start; cr[0x73] = HorizontalSerration2Start; cr[0x74] = (HorizontalEqualizationPulses << 5) | NTSC_PAL_HorizontalPulseWidth; /* todo: ct69000 has also 0x75-79 */ /* now set the registers */ for (i = 0; i <= 0x0d; i++) { /*CR00 .. CR0D */ ctWrite_i (CT_CR_O, i, cr[i]); } for (i = 0x10; i <= 0x18; i++) { /*CR10 .. CR18 */ ctWrite_i (CT_CR_O, i, cr[i]); } i = 0x22; /*CR22 */ ctWrite_i (CT_CR_O, i, cr[i]); for (i = 0x30; i <= 0x33; i++) { /*CR30 .. CR33 */ ctWrite_i (CT_CR_O, i, cr[i]); } i = 0x38; /*CR38 */ ctWrite_i (CT_CR_O, i, cr[i]); i = 0x3C; /*CR3C */ ctWrite_i (CT_CR_O, i, cr[i]); for (i = 0x40; i <= 0x41; i++) { /*CR40 .. CR41 */ ctWrite_i (CT_CR_O, i, cr[i]); } for (i = 0x70; i <= 0x74; i++) { /*CR70 .. CR74 */ ctWrite_i (CT_CR_O, i, cr[i]); } tmp = ctRead_i (CT_CR_O, 0x40); tmp &= 0x0f; tmp |= 0x80; ctWrite_i (CT_CR_O, 0x40, tmp); /* StartAddressEnable */}/* pixelclock control *//***************************************************************************** We have a rational number p/q and need an m/n which is very close to p/q but has m and n within mnmin and mnmax. We have no floating point in the kernel. We can use long long without divide. And we have time to compute...******************************************************************************/static unsigned intFindBestPQFittingMN (unsigned int p, unsigned int q, unsigned int mnmin, unsigned int mnmax, unsigned int *pm, unsigned int *pn){ /* this code is not for general purpose usable but good for our number ranges */ unsigned int n = mnmin, m = 0; long long int L = 0, P = p, Q = q, H = P >> 1; long long int D = 0x7ffffffffffffffLL; for (n = mnmin; n <= mnmax; n++) { m = mnmin; /* p/q ~ m/n -> p*n ~ m*q -> p*n-x*q ~ 0 */ L = P * n - m * Q; /* n * vco - m * fref should be near 0 */ while (L > 0 && m < mnmax) { L -= q; /* difference is greater as 0 subtract fref */ m++; /* and increment m */ } /* difference is less or equal than 0 or m > maximum */ if (m > mnmax) break; /* no solution: if we increase n we get the same situation */ /* L is <= 0 now */ if (-L > H && m > mnmin) { /* if difference > the half fref */ L += q; /* we take the situation before */ m--; /* because its closer to 0 */ } L = (L < 0) ? -L : +L; /* absolute value */ if (D < L) /* if last difference was better take next n */ continue; D = L; *pm = m; *pn = n; /* keep improved data */ if (D == 0) break; /* best result we can get */ } return (unsigned int) (0xffffffff & D);}/* that is the hardware < 69000 we have to manage +---------+ +-------------------+ +----------------------+ +--+ | REFCLK |__|NTSC Divisor Select|__|FVCO Reference Divisor|__|鱊|__ | 14.3MHz | |(NTSCDS) (
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -