📄 cirrus.c
字号:
/* Check for CL-GD5420-75QC-B. */ /* It has a Hidden-DAC register. */ outb(0x3C6, 0x00); outb(0x3C6, 0xFF); inb(0x3C6); inb(0x3c6); inb(0x3C6); inb(0x3C6); if (inb(0x3C6) != 0xFF) cirrus_chiptype = CLGD5420B;#endif break; case 0x23: cirrus_chiptype = CLGD5422; break; case 0x24: cirrus_chiptype = CLGD5426; break; case 0x25: cirrus_chiptype = CLGD5424; /* * Some CL-GD5422's ID as CL-GD5424. * Check for writability of GRC. */ v = __svgalib_inGR(0x0C); __svgalib_outGR(0x0C, 0x55); if (__svgalib_inGR(0x0C) != 0x55) cirrus_chiptype = CLGD5422; __svgalib_outGR(0x0C, v); break; case 0x26: cirrus_chiptype = CLGD5428; break; case 0x27: cirrus_chiptype = CLGD5429; break; case 0x28: cirrus_chiptype = CLGD5430; break; case 0x2A: cirrus_chiptype = CLGD5434; if ((partstatus & 0xC0) == 0xC0) /* Rev. E, can do 60 MHz MCLK. */ cirrus_chiprev = 1; break; case 0x2B: cirrus_chiptype = CLGD5436; break; case 0x2E: /* Treat 5446 as 5436. */ cirrus_chiptype = CLGD5436; break; default: printf("Unknown Cirrus chip %2x.\n", cirrus_chiptype); return -1; }#if 0 if (cirrus_chiptype == CLGD5422) { /* Rev. C has programmable MCLK register; */ /* check for it. */ /* This check is wrong. */ if (__svgalib_inSR(0x1F) != 0xFF) cirrus_chiptype = CLGD5422C; }#endif /* Now determine the amount of memory. */ outb(0x3c4, 0x0a); /* read memory register */ /* This depends on the BIOS having set a scratch register. */ v = inb(0x3c5); cirrus_memory = 256 << ((v >> 3) & 3); /* Determine memory the correct way for the 543x, and * for the 542x if the amount seems incorrect. */ if (cirrus_chiptype >= CLGD5430 || (cirrus_memory <= 256 && cirrus_chiptype != CLGD5420)) { unsigned char SRF; cirrus_memory = 512; outb(0x3c4, 0x0f); SRF = inb(0x3c5); if (SRF & 0x10) /* 32-bit DRAM bus. */ cirrus_memory *= 2; if ((SRF & 0x18) == 0x18) /* 64-bit DRAM data bus width; assume 2MB. */ /* Also indicates 2MB memory on the 5430. */ cirrus_memory *= 2; if (cirrus_chiptype != CLGD5430 && (SRF & 0x80)) /* If DRAM bank switching is enabled, there */ /* must be twice as much memory installed. */ /* (4MB on the 5434) */ cirrus_memory *= 2; } } if (__svgalib_driver_report) { printf("Using Cirrus Logic GD542x/3x driver (%s, %dK).\n", cirrus_chipname[cirrus_chiptype], cirrus_memory); } if (CHIP_HAS_MCLK_REGISTER()) actualMCLK = __svgalib_inSR(0x1F) & 0x3F; else { actualMCLK = fixedMCLK[__svgalib_inSR(0x0F) & 3]; } programmedMCLK = actualMCLK; if (cirrus_chiptype == CLGD5434 && cirrus_chiprev > 0) /* 5434 rev. E+ supports 60 MHz in graphics modes. */ programmedMCLK = 0x22; DRAMbandwidth = 14318 * (int) programmedMCLK / 16; if (cirrus_memory >= 512) /* At least 16-bit DRAM bus. */ DRAMbandwidth *= 2; if (cirrus_memory >= 1024 && CHIP_HAS_32BIT_DRAM_BUS()) /* At least 32-bit DRAM bus. */ DRAMbandwidth *= 2; if (cirrus_memory >= 2048 && CHIP_HAS_64BIT_DRAM_BUS()) /* 64-bit DRAM bus. */ DRAMbandwidth *= 2; /* * Calculate highest acceptable DRAM bandwidth to be taken up * by screen refresh. Satisfies * total bandwidth >= refresh bandwidth * 1.1 */ DRAMbandwidthLimit = (DRAMbandwidth * 10) / 11;/* begin: Initialize card specs. */ cardspecs = malloc(sizeof(CardSpecs)); cardspecs->videoMemory = cirrus_memory; /* * First determine clock limits for the chip (DAC), then * adjust them according to the available DRAM bandwidth. * For 32-bit DRAM cards the 16bpp clock limit is initially * set very high, but they are cut down by the DRAM bandwidth * check. */ cardspecs->maxPixelClock4bpp = 75000; /* 5420 */ cardspecs->maxPixelClock8bpp = 45000; /* 5420 */ cardspecs->maxPixelClock16bpp = 0; /* 5420 */ cardspecs->maxPixelClock24bpp = 0; cardspecs->maxPixelClock32bpp = 0; if (cirrus_chiptype == CLGD5420B) { /* * CL-GD5420-75QC-B * Deviating chip, may be used in cheap ISA cards. * 32-bit DRAM bus and Truecolor DAC but cannot do * LUT > 45 MHz, and maybe has less acceleration. */ cardspecs->maxPixelClock16bpp = 75000 / 2; cardspecs->maxPixelClock24bpp = 25175; } if (cirrus_chiptype >= CLGD5422) { /* 5422/24/26/28 have VCLK spec of 80 MHz. */ cardspecs->maxPixelClock4bpp = 80000; cardspecs->maxPixelClock8bpp = 80000; if (cirrus_chiptype >= CLGD5426) /* DRAM bandwidth will be limiting factor. */ cardspecs->maxPixelClock16bpp = 80000; else /* Clock / 2 16bpp requires 32-bit DRAM bus. */ if (cirrus_memory >= 1024) cardspecs->maxPixelClock16bpp = 80000 / 2; /* Clock / 3 24bpp requires 32-bit DRAM bus. */ if (cirrus_memory >= 1024) cardspecs->maxPixelClock24bpp = 80000 / 3; } if (cirrus_chiptype >= CLGD5429) { /* 5429, 5430, 5434 have VCLK spec of 86 MHz. */ cardspecs->maxPixelClock4bpp = 86000; cardspecs->maxPixelClock8bpp = 86000; cardspecs->maxPixelClock16bpp = 86000; if (cirrus_memory >= 1024) cardspecs->maxPixelClock24bpp = 86000 / 3; } if (cirrus_chiptype == CLGD5434) {#ifdef SUPPORT_5434_PALETTE_CLOCK_DOUBLING cardspecs->maxPixelClock8bpp = 108300; if (cirrus_chiprev > 0) /* 5434 rev E+ */ cardspecs->maxPixelClock8bpp = 135300;#endif if (cirrus_memory >= 2048) /* 32bpp requires 64-bit DRAM bus. */ cardspecs->maxPixelClock32bpp = 86000; } if (cirrus_chiptype >=CLGD5436) {#ifdef SUPPORT_5434_PALETTE_CLOCK_DOUBLING cardspecs->maxPixelClock8bpp = 135300;#endif if (cirrus_memory >= 2048) /* 32bpp requires 64-bit DRAM bus. */ cardspecs->maxPixelClock32bpp = 86000; } cardspecs->maxPixelClock8bpp = min(cardspecs->maxPixelClock8bpp, DRAMbandwidthLimit); cardspecs->maxPixelClock16bpp = min(cardspecs->maxPixelClock16bpp, DRAMbandwidthLimit / 2); cardspecs->maxPixelClock24bpp = min(cardspecs->maxPixelClock24bpp, DRAMbandwidthLimit / 3); cardspecs->maxPixelClock32bpp = min(cardspecs->maxPixelClock32bpp, DRAMbandwidthLimit / 4); cardspecs->flags = INTERLACE_DIVIDE_VERT | GREATER_1024_DIVIDE_VERT; /* Initialize clocks (only fixed set for now). */ cardspecs->nClocks = NU_FIXED_CLOCKS; cardspecs->clocks = cirrus_fixed_clocks; cardspecs->mapClock = cirrus_map_clock; cardspecs->mapHorizontalCrtc = cirrus_map_horizontal_crtc; cardspecs->maxHorizontalCrtc = 2040; /* Disable 16-color SVGA modes (don't work correctly). */ cardspecs->maxPixelClock4bpp = 0;/* end: Initialize card specs. */#if 0/* begin: Initialize driver options. */ register_option(5434 _VLB_ZERO_WAITSTATE); register_option(50 MHZ_MCLK); register_option(55 MHZ_MCLK); register_option(60 MHZ_MCLK); register_option(542 X_VLB_NORMAL_WAITSTATES); register_option(CRT_FIFO_CONSERVATIVE); register_option(CRT_FIFO_AGGRESSIVE); register_option(NO_ACCELERATION); register_option(NO_MMIO);/* end: Initialize driver options. */#endif/* Initialize accelspecs structure. */ __svgalib_cirrus_driverspecs.accelspecs = malloc(sizeof(AccelSpecs)); __svgalib_clear_accelspecs(__svgalib_cirrus_driverspecs.accelspecs); __svgalib_cirrus_driverspecs.accelspecs->flags = ACCELERATE_ANY_LINEWIDTH; if (cirrus_chiptype >= CLGD5429) { /* Map memory-mapped I/O register space. */#ifdef OSKIT osenv_mem_map_phys(mmio_base + 0xB8000, 32 * 1024, &mmio_base, 0);#else mmio_base = valloc(32 * 1024); mmap(mmio_base, 32 * 1024, PROT_WRITE, MAP_FIXED | MAP_SHARED, __svgalib_mem_fd, 0xB8000);#endif } /* Set up the correct paging routine */ if (cirrus_memory >= 2048) __svgalib_cirrus_driverspecs.__svgalib_setpage = cirrus_setpage_2M; __svgalib_driverspecs = &__svgalib_cirrus_driverspecs; return 0;}/* Some information on the accelerated features of the 5426, derived from the Databook. port index Addresses have 21 bits (2Mb of memory). 0x3ce, 0x28 bits 0-7 of the destination address 0x3ce, 0x29 bits 8-15 0x3ce, 0x2a bits 16-20 0x3ce, 0x2c bits 0-7 of the source address 0x3ce, 0x2d bits 8-15 0x3ce, 0x2e bits 16-20 Maximum pitch is 4095. 0x3ce, 0x24 bits 0-7 of the destination pitch (screen width) 0x3ce, 0x25 bits 8-11 0x3ce, 0x26 bits 0-7 of the source pitch (screen width) 0x3ce, 0x27 bits 8-11 Maximum width is 2047. 0x3ce, 0x20 bits 0-7 of the box width - 1 0x3ce, 0x21 bits 8-10 Maximum height is 1023. 0x3ce, 0x22 bits 0-7 of the box height - 1 0x3ce, 0x23 bits 8-9 0x3ce, 0x30 BLT mode bit 0: direction (0 = down, 1 = up) bit 1: destination bit 2: source (0 = video memory, 1 = system memory) bit 3: enable transparency compare bit 4: 16-bit color expand/transparency bit 6: 8x8 pattern copy bit 7: enable color expand 0x31 BLT status bit 0: busy bit 1: start operation (1)/suspend (0) bit 2: reset bit 3: set while blit busy/suspended 0x32 BLT raster operation 0x00 black 0x01 white 0x0d copy source 0xd0 copy inverted source 0x0b invert destination 0x05 logical AND 0x6d logical OR (paint) 0x59 XOR 0x34 BLT transparent color 0x35 high byte 0x3ce, 0x00 background color (for color expansion) 0x3ce, 0x01 foreground color 0x3ce, 0x10 high byte of background color for 16-bit pixels 0x3ce, 0x11 high byte of foreground color 0x3ce, 0x0b bit 1: enable BY8 addressing 0x3c4, 0x02 8-bit plane mask for BY8 (corresponds to 8 pixels) (write mode 1, 4, 5) 0x3c5, 0x05 bits 0-2: VGA write mode extended write mode 4: write up to 8 pixels in foreground color (BY8) extended write mode 5: write 8 pixels in foreground/ background color (BY8) This may also work in normal non-BY8 packed-pixel mode. When doing blits from system memory to video memory, pixel data can apparently be written to any video address in 16-bit words, with the each scanline padded to 4-byte alignment. This is handy because the chip handles line transitions and alignment automatically (and can do, for example, masking). The pattern copy requires an 8x8 pattern (64 pixels) at the source address in video memory, and fills a box with specified size and destination address with the pattern. This is in fact the way to do solid fills. mode pattern Color Expansion 8 bytes (monochrome bitmap) 8-bit pixels 64 bytes 16-bit pixels 128 bytes *//* Cirrus Logic acceleration functions implementation. *//* BitBLT modes. */#define FORWARDS 0x00#define BACKWARDS 0x01#define SYSTEMDEST 0x02#define SYSTEMSRC 0x04#define TRANSPARENCYCOMPARE 0x08#define PIXELWIDTH16 0x10#define PIXELWIDTH32 0x30 /* 543x only. */#define PATTERNCOPY 0x40#define COLOREXPAND 0x80/* Macros for normal I/O BitBLT register access. */#define SETSRCADDR(addr) \ outw(0x3CE, (((addr) & 0x000000FF) << 8) | 0x2C); \ outw(0x3CE, (((addr) & 0x0000FF00)) | 0x2D); \ outw(0x3CE, (((addr) & 0x003F0000) >> 8) | 0x2E);#define SETDESTADDR(addr) \ outw(0x3CE, (((addr) & 0x000000FF) << 8) | 0x28); \ outw(0x3CE, (((addr) & 0x0000FF00)) | 0x29); \ outw(0x3CE, (((addr) & 0x003F0000) >> 8) | 0x2A);/* Pitch: the 5426 goes up to 4095, the 5434 can do 8191. */#define SETDESTPITCH(pitch) \ outw(0x3CE, (((pitch) & 0x000000FF) << 8) | 0x24); \ outw(0x3CE, (((pitch) & 0x00001F00)) | 0x25);#define SETSRCPITCH(pitch) \ outw(0x3CE, (((pitch) & 0x000000FF) << 8) | 0x26); \ outw(0x3CE, (((pitch) & 0x00001F00)) | 0x27);/* Width: the 5426 goes up to 2048, the 5434 can do 8192. */#define SETWIDTH(width) \ outw(0x3CE, ((((width) - 1) & 0x000000FF) << 8) | 0x20); \ outw(0x3CE, ((((width) - 1) & 0x00001F00)) | 0x21);/* Height: the 5426 goes up to 1024, the 5434 can do 2048. *//* It appears many 5434's only go up to 1024. */#define SETHEIGHT(height) \ outw(0x3CE, ((((height) - 1) & 0x000000FF) << 8) | 0x22); \ outw(0x3CE, (((height) - 1) & 0x00000700) | 0x23);#define SETBLTMODE(m) \ outw(0x3CE, ((m) << 8) | 0x30);#define SETBLTWRITEMASK(m) \ outw(0x3CE, ((m) << 8) | 0x2F);#define SETTRANSPARENCYCOLOR(c) \ outw(0x3CE, ((c) << 8) | 0x34);#define SETTRANSPARENCYCOLOR16(c) \ outw(0x3CE, ((c) << 8) | 0x34); \ outw(0x3CE, (c & 0xFF00) | 0x35);#define SETTRANSPARENCYCOLORMASK16(m) \ outw(0x3CE, ((m) << 8) | 0x38); \ outw(0x3CE, ((m) & 0xFF00) | 0x39);#define SETROP(rop) \ outw(0x3CE, ((rop) << 8) | 0x32);#define SETFOREGROUNDCOLOR(c) \ outw(0x3CE, 0x01 + ((c) << 8));#define SETBACKGROUNDCOLOR(c) \ outw(0x3CE, 0x00 + ((c) << 8));#define SETFOREGROUNDCOLOR16(c) \ outw(0x3CE, 0x01 + ((c) << 8)); \ outw(0x3CE, 0x11 + ((c) & 0xFF00));#define SETBACKGROUNDCOLOR16(c) \ outw(0x3CE, 0x00 + ((c) << 8)); \ outw(0x3CE, 0x10 + ((c) & 0xFF00)); \#define SETFOREGROUNDCOLOR32(c) \ outw(0x3CE, 0x01 + ((c) << 8)); \ outw(0x3CE, 0x11 + ((c) & 0xFF00)); \ outw(0x3CE, 0x13 + (((c) & 0xFf0000) >> 8)); \ outw(0x3CE, 0x15 + (((unsigned int)(c) & 0xFF000000) >> 16));#define SETBACKGROUNDCOLOR32(c) \ outw(0x3CE, 0x00 + ((c) << 8)); \ outw(0x3CE, 0x10 + ((c) & 0xFF00)); \ outw(0x3CE, 0x12 + (((c) & 0xFF0000) >> 8)); \ outw(0x3CE, 0x14 + (((unsigned int)(c) & 0xFF000000) >> 16));#define STARTBLT() { \ unsigned char tmp; \ outb(0x3CE, 0x31); \ tmp = inb(0x3CF); \ outb(0x3CF, tmp | 0x02); \ }#define BLTBUSY(s) { \ outb(0x3CE, 0x31); \ s = inb(0x3CF) & 1; \ }#define WAITUNTILFINISHED() \ for (;;) { \ int busy; \ BLTBUSY(busy); \ if (!busy) \ break; \ }/* Macros for memory-mapped I/O BitBLT register access. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -