📄 oak.c
字号:
{ int temp; /* Unprotect CRTC[0-7] */ outb(__svgalib_CRT_I, 0x11); temp = inb(__svgalib_CRT_D); outb(__svgalib_CRT_D, temp & 0x7F); temp = OAKGetByte(OTI_CRT_CNTL); OAKSetByte(OTI_CRT_CNTL, temp & 0xf0); oak_lockreg_save = temp;}/* oak_lock() Lock Oak registers * Prevents registers from accidental change * * _No effect with OTI-087 -- register is nonfunctional_ */static void oak_lock(void){ int temp; /* don't set the i/o write test bit, though we cleared it on entry */ OAKSetByte(OTI_CRT_CNTL, oak_lockreg_save & 0xf7); /* Protect CRTC[0-7] */ outb(__svgalib_CRT_I, 0x11); temp = inb(__svgalib_CRT_D); outb(__svgalib_CRT_D, (temp & 0x7F) | 0x80);}/* oak_test() Probe for Oak card * Checks for Oak segment register, then chip type and memory size. * * Returns 1 for Oak, 0 otherwise. */static int oak_test(void){ int save, temp1; oak_unlock(); save = OAKGetByte(OTI_SEGMENT); OAKSetByte(OTI_SEGMENT, save ^ 0x11); temp1 = OAKGetByte(OTI_SEGMENT); OAKSetByte(OTI_SEGMENT, save); if (temp1 != (save ^ 0x11)) { oak_lock(); /* unsuccesful */ return 0; } /* HH: Only allow 087, 077 support seems to be broken for at */ /* least one 512K card. May be due to mode dump configuring */ /* for 1024K. */ /* Reallow 067 and 077 */ /* if (oak_chipdetect() < 87) return 0; */ return oak_init(0, 0, 0);}/* oak_setpage( int page ) Set read/write pages * Sets both read and write extended segments (64k bank number) * Should be good for 5 bits with OTI-087 */static void oak_setpage(int page){ if (oak_chiptype == 87) { OAKSetByte(OTI87_XCOMMONSEGMENT, page); } else { OAKSetByte(OTI_SEGMENT, (last_page = page | (page << 4))); }}/* oak_setrdpage( int page ) Set read page * Sets read extended segment (64k bank number) * Should be good for 5 bits with OTI-087 */static void oak_setrdpage(int page){ if (oak_chiptype == 87) { OAKSetByte(OTI87_XREADSEGMENT, page); } else { last_page &= 0xF0; last_page |= page; OAKSetByte(OTI_SEGMENT, last_page); }}/* oak_setwrpage( int page ) Set write page * Sets write extended segment (64k bank number) * Should be good for 5 bits with OTI-087 */static void oak_setwrpage(int page){ if (oak_chiptype == 87) { OAKSetByte(OTI87_XWRITESEGMENT, page); } else { last_page &= 0x0F; last_page |= page << 4; OAKSetByte(OTI_SEGMENT, last_page); }}/* oak_setdisplaystart( int address ) Set display address * Sets display start address. * First word goes into CRT_IC indices 0x0c and 0x0d * If 067, bit 16 goes to OTI_OVERFLOW bit 3 * If 077, bit 17 goes to OTI_OVERFLOW2 bit 3 * If 087, bits 16, 17, and 18 go to OTI87_XCRTC bits 0-2 */static void oak_setdisplaystart(int address){ outw(CRT_IC, 0x0d + ((address >> 2) & 0x00ff) * 256); /* sa2-sa9 */ outw(CRT_IC, 0x0c + ((address >> 2) & 0xff00)); /* sa10-sa17 */ inb(0x3da); /* set ATC to addressing mode */ outb(ATT_IW, 0x13 + 0x20); /* select ATC reg 0x13 */ outb(ATT_IW, (inb(ATT_R) & 0xf0) | ((address & 3) << 1)); /* write sa0-1 to bits 1-2 */ if (oak_chiptype == 87) { OAKSetByte(OTI87_XCRTC, (address & 0x1c0000) >> 18); } else { OAKSetByte(OTI_OVERFLOW, (OAKGetByte(OTI_OVERFLOW) & 0xf7) | ((address & 0x40000) >> 15)); /* write sa18 to bit 3 */ if (oak_chiptype == 77) { OAKSetByte(OTI_OVERFLOW2, (OAKGetByte(OTI_OVERFLOW2) & 0xf7) | ((address & 0x80000) >> 16)); /* write sa19 to bit 3 */ } }}/* oak_setlogicalwidth( int width ) Set scanline length * Set logical scanline length (usually multiple of 8) * Multiples of 8 to 2040 */static void oak_setlogicalwidth(int width){ outw(CRT_IC, 0x13 + (width >> 3) * 256); /* lw3-lw11 */}/* oak_init ( int force, int par1, int par2) Initialize chipset * Detects Oak chipset type and installed video memory. * Returns 1 if chipset is supported, 0 otherwise */static int oak_init(int force, int par1, int par2){ if (force) { oak_chiptype = par1; oak_memory = par2; } else { oak_chiptype = oak_chipdetect(); if (oak_chiptype == 0) { return 0; /* not supported */ } oak_memory = oak_memorydetect(); } if (__svgalib_driver_report) { printf("Using Oak driver (OTI-0%d, %dK).\n", oak_chiptype, oak_memory); } __svgalib_driverspecs = &__svgalib_oak_driverspecs; __svgalib_banked_mem_base=0xa0000; __svgalib_banked_mem_size=0x10000; __svgalib_linear_mem_base=0xe00000; __svgalib_linear_mem_size=oak_memory*0x400; return 1;}/* oak_memorydetect() Report installed video RAM * Returns size (in Kb) of installed video memory * Defined values are 256, 512, 1024, and 2048 (OTI-087 only) */static int oak_memorydetect(void){ int temp1; if (oak_chiptype == 87) { temp1 = OAKGetByte(OTI87_STATUS) & 0x06; if (temp1 == 0x06) return 2048; else if (temp1 == 0x04) return 1024; else if (temp1 == 0x02) return 512; else if (temp1 == 0x00) return 512; else { printf("Oak driver: Invalid amount of memory. Using 256K.\n"); return 256; } } else { temp1 = OAKGetByte(OTI_MISC) & 0xc0; if (temp1 == 0xC0) return 1024; else if (temp1 == 0x80) return 512; else if (temp1 == 0x00) return 256; else { printf("Oak driver: Invalid amount of memory. Using 256K.\n"); return 256; } }}/* oak_chipdetect() Detect Oak chip type * Returns chip id (67, 77, 87) if video chipset is a supported Oak type * (57 is _not_ supported). * Returns 0 otherwise */static int oak_chipdetect(void){ int temp1; temp1 = inb(OTI_INDEX); temp1 &= 0xe0; if (temp1 == 0x40) return 67; if (temp1 == 0xa0) return 77; /* not a '67 or '77 ... try for '87 ... */ temp1 = OAKGetByte(OTI87_PRODUCT) & 0x01; if (temp1 == 0x01) return 87; /* none of the above ... maybe the nonexistant '97 I've been hearing about? *//* printf("Oak driver: Unknown chipset (id = %2x)\n", temp1);*/ oak_lock(); return 0;}/* oak_inlinearmode() Check if OTI-087 is in linear mode * Bit 0 set if yes, clear if no * Return: true/false */static int oak_inlinearmode(void){ return (OAKGetByte(OTI87_VIDMAP) & 0x01) != 0;}/* oak_setlinearmode() Set linear mode for OTI-087 * For simplicity's sake, we're forcing map at the E0000 (14M) mark * We grab the memory size from OTI87_STATUS, and we're mapping it all. * * Video map register looks like this: * Bit 0: 0 = VGA mapping (A0000-BFFFF) 1 = Linear * Bit 1: 0 = Enable DMA 1 = Disable DMA * Bit 2/3: Aperature (256/512/1024/2048, bitwise) * Bit 4-7: Starting address (High nybble, 1-F) */static void oak_setlinearmode(void){ int temp1; temp1 = ((OAKGetByte(OTI87_STATUS) & 0x06) << 1) | 0xe1; OAKSetByte(OTI87_VIDMAP, temp1);/* linearframebuffer = (unsigned char *) mmap((caddr_t) 0x40000000, oak_memory * 1024, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, __svgalib_mem_fd, 0xe00000);*/ linearframebuffer=LINEAR_MEM_POINTER; VGAMemory_Save = __svgalib_graph_mem; __svgalib_modeinfo_linearset |= IS_LINEAR;}/* oak_clearlinearmode() Stop linear mode for OTI-087 * Switches linear mode off, reset aperture and address range * (see oak_golinearmode() for register description) */static void oak_clearlinearmode(void){ OAKSetByte(OTI87_VIDMAP, 0x00); __svgalib_modeinfo_linearset ^= IS_LINEAR; __svgalib_graph_mem = VGAMemory_Save; graph_mem = VGAMemory_Save;}/* OAK_WriteDAC ( int dac_value ) Write value to DAC * Writes function command to DAC at 0x03c6 * (Assumes that DAC is SC11487 ... may not work for others) * */static void OAK_WriteDAC(int dac_value){ inb(DAC_REVERT); /* reset DAC r/w pointer */ inb(DAC_SC11487); /* do this four times to set register A */ inb(DAC_SC11487); inb(DAC_SC11487); inb(DAC_SC11487); outb(DAC_SC11487, dac_value); inb(DAC_REVERT); /* and reset DAC ... */}/* OAKSetByte ( index, value) Set extended register * Puts a specified value in a specified extended register. * Splitting this commonly used instruction sequence into its own subroutine * saves about 100 bytes of code overall ... */static void OAKSetByte(int OTI_index, int OTI_value){ outb(OTI_INDEX, OTI_index); outb(OTI_R_W, OTI_value);}/* OAKGetByte ( index ) Returns ext. register * Returns value from specified extended register. * As with OakSetByte, this tightens the code considerably. */static int OAKGetByte(int OTI_index){ outb(OTI_INDEX, OTI_index); return inb(OTI_R_W);}/* Function table (exported) */DriverSpecs __svgalib_oak_driverspecs ={ oak_saveregs, oak_setregs, oak_unlock, oak_lock, oak_test, oak_init, oak_setpage, oak_setrdpage, oak_setwrpage, oak_setmode, oak_modeavailable, oak_setdisplaystart, oak_setlogicalwidth, oak_getmodeinfo, 0, /* bitblt */ 0, /* imageblt */ 0, /* fillblt */ 0, /* hlinelistblt */ 0, /* bltwait */ 0, /* extset */ 0, 0, /* linear */ NULL, /* Accelspecs */ NULL, /* Emulation */#if 0 (int (*)()) oak_setlinearmode, (int (*)()) oak_clearlinearmode, (int (*)()) OAK_WriteDAC,#endif};
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -