/* VGAlib version 1.2 - (c) 1993 Tommy Frandsen */ /* */ /* This library is free software; you can redistribute it and/or */ /* modify it without any restrictions. This library is distributed */ /* in the hope that it will be useful, but without any warranty. */ /* Multi-chipset support Copyright 1993 Harm Hanemaayer */ /* partially copyrighted (C) 1993 by Hartmut Schirmer */ #include /* for NULL */ #include "vga.h" #include "libvga.h" #include "driver.h" /* BIOS mode 0Dh - 320x200x16 */ static const unsigned char g320x200x16_regs[60] = { 0x2D, 0x27, 0x28, 0x90, 0x2B, 0x80, 0xBF, 0x1F, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x14, 0x00, 0x96, 0xB9, 0xE3, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x01, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x20, 0x00, 0x00, 0x05, 0x0F, 0xFF, 0x03, 0x09, 0x0F, 0x00, 0x06, 0x63 }; /* BIOS mode 0Eh - 640x200x16 */ static const unsigned char g640x200x16_regs[60] = { 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x00, 0x96, 0xB9, 0xE3, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x01, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x20, 0x00, 0x00, 0x05, 0x0F, 0xFF, 0x03, 0x01, 0x0F, 0x00, 0x06, 0x63 }; /* BIOS mode 10h - 640x350x16 */ static const unsigned char g640x350x16_regs[60] = { 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x85, 0x5D, 0x28, 0x0F, 0x63, 0xBA, 0xE3, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x01, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x20, 0x00, 0x00, 0x05, 0x0F, 0xFF, 0x03, 0x01, 0x0F, 0x00, 0x06, 0xA3 }; /* BIOS mode 12h - 640x480x16 */ static const unsigned char g640x480x16_regs[60] = { 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0B, 0x3E, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA, 0x8C, 0xDF, 0x28, 0x00, 0xE7, 0x04, 0xE3, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x01, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x20, 0x00, 0x00, 0x05, 0x0F, 0xFF, 0x03, 0x01, 0x0F, 0x00, 0x06, 0xE3 }; /* BIOS mode 13h - 320x200x256 */ static const unsigned char g320x200x256_regs[60] = { 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x40, 0x96, 0xB9, 0xA3, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF, 0x03, 0x01, 0x0F, 0x00, 0x0E, 0x63 }; /* non-BIOS mode - 320x240x256 */ static const unsigned char g320x240x256_regs[60] = { 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0x0D, 0x3E, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA, 0xAC, 0xDF, 0x28, 0x00, 0xE7, 0x06, 0xE3, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF, 0x03, 0x01, 0x0F, 0x00, 0x06, 0xE3 }; /* non-BIOS mode - 320x400x256 */ static const unsigned char g320x400x256_regs[60] = { 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x8E, 0x8F, 0x28, 0x00, 0x96, 0xB9, 0xE3, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF, 0x03, 0x01, 0x0F, 0x00, 0x06, 0x63 }; /* non-BIOS mode - 360x480x256 */ static const unsigned char g360x480x256_regs[60] = { 0x6B, 0x59, 0x5A, 0x8E, 0x5E, 0x8A, 0x0D, 0x3E, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA, 0xAC, 0xDF, 0x2D, 0x00, 0xE7, 0x06, 0xE3, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x41, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF, 0x03, 0x01, 0x0F, 0x00, 0x06, 0xE7 }; /* monochrome mode based on BIOS mode 12h - 640x480x2 */ #define g640x480x2_regs g640x480x16_regs /* non BIOS mode - 720x348x2 based on mode 10h */ static const unsigned char g720x348x2_regs[60] = { 0x6B, 0x59, 0x5A, 0x8E, 0x5E, 0x8A, 0xBF, 0x1F, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x85, 0x5D, 0x2D, 0x0F, 0x63, 0xBA, 0xE3, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x01, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x0F, 0x00, 0x20, 0x00, 0x00, 0x05, 0x0F, 0xFF, 0x03, 0x01, 0x0F, 0x00, 0x06, 0xA7 }; /* Mode table */ static ModeTable vga_modes[] = { /* *INDENT-OFF* */ OneModeEntry(640x480x2), OneModeEntry(720x348x2), OneModeEntry(320x200x16), OneModeEntry(640x200x16), OneModeEntry(640x350x16), OneModeEntry(640x480x16), OneModeEntry(320x200x256), OneModeEntry(320x240x256), OneModeEntry(320x400x256), OneModeEntry(360x480x256), #ifdef G720x350x16 OneModeEntry(720x350x16), #endif END_OF_MODE_TABLE /* *INDENT-ON* */ }; /* Fill in chipset-specific modeinfo */ static void getmodeinfo(int mode, vga_modeinfo * modeinfo) { if (modeinfo->bytesperpixel == 1) { /* 320x200x256 linear mode */ modeinfo->maxpixels = 65536; modeinfo->startaddressrange = 0xffff; } else switch (modeinfo->colors) { case 16: /* 4-plane 16 color mode */ modeinfo->maxpixels = 65536 * 8; modeinfo->startaddressrange = 0x7ffff; break; case 256: /* 4-plane 256 color mode */ modeinfo->maxpixels = 65536 * 4; modeinfo->startaddressrange = 0x3ffff; break; } modeinfo->maxlogicalwidth = 2040; modeinfo->haveblit = 0; modeinfo->flags &= ~(IS_INTERLACED | HAVE_RWPAGE); } static void nothing(void) { } static int saveregs(unsigned char regs[]) { return 0; } static void setregs(const unsigned char regs[], int mode) { } /* Return nonzero if mode available */ static int modeavailable(int mode) { const unsigned char *regs; regs = LOOKUPMODE(vga_modes, mode); if (regs != NULL && regs != DISABLE_MODE) return STDVGADRV; return 0; } /* Set a mode */ static int lastmode; static int setmode(int mode, int prv_mode) { /* standard VGA driver: setmode */ const unsigned char *regs; if (mode == TEXT) return 0; /* Do nothing. */ regs = LOOKUPMODE(vga_modes, mode); if (regs == NULL || regs == DISABLE_MODE) return 1; lastmode = mode; __svgalib_setregs(regs); return 0; } /* Set display start */ static void setdisplaystart(int address) { vga_modeinfo *modeinfo; modeinfo = vga_getmodeinfo(lastmode); if (modeinfo->bytesperpixel == 0) /* not 320x200x256 linear */ switch (modeinfo->colors) { case 16: /* planar 16-color mode */ inb(0x3da); outb(0x3c0, 0x13 + 0x20); outb(0x3c0, (inb(0x3c1) & 0xf0) | (address & 7)); /* write sa0-2 to bits 0-2 */ address >>= 3; break; case 256: /* planar 256-color mode */ inb(0x3da); outb(0x3c0, 0x13 + 0x20); outb(0x3c0, (inb(0x3c1) & 0xf0) | ((address & 3) << 1)); /* write sa0-1 to bits 1-2 */ address >>= 2; break; } outw(0x3d4, 0x0d + (address & 0x00ff) * 256); /* sa0-sa7 */ outw(0x3d4, 0x0c + (address & 0xff00)); /* sa8-sa15 */ } static void setlogicalwidth(int width) { outw(0x3d4, 0x13 + (width >> 3) * 256); /* lw3-lw11 */ } static int vgadrv_init(int, int, int); static int vga_test(void) { unsigned char save, back; /* Check if a DAC is present */ save = inb(PEL_IW); __svgalib_delay(); outb(PEL_IW, ~save); __svgalib_delay(); back = inb(PEL_IW); __svgalib_delay(); outb(PEL_IW, save); save = ~save; if (back == save) { vgadrv_init(0, 0, 0); return 1; } return 0; } DriverSpecs __svgalib_vga_driverspecs = { /* standard VGA */ saveregs, setregs, nothing, /* unlock */ nothing, /* lock */ vga_test, vgadrv_init, (void (*)(int)) nothing, /* __svgalib_setpage */ (void (*)(int)) nothing, /* __svgalib_setrdpage */ (void (*)(int)) nothing, /* __svgalib_setwrpage */ setmode, modeavailable, setdisplaystart, setlogicalwidth, getmodeinfo, 0, /* bitblt */ 0, /* imageblt */ 0, /* fillblt */ 0, /* hlinelistblt */ 0, /* bltwait */ 0, /* extset */ 0, 0, /* linear */ NULL, /* Accelspecs */ NULL, /* Emulation */ }; /* Initialize chipset (called after detection) */ static int vgadrv_init(int force, int par1, int par2) { if (__svgalib_driver_report) printf("Using VGA driver.\n"); __svgalib_driverspecs = &__svgalib_vga_driverspecs; return 0; }