/** ** VESADRV.C ---- EGA, VGA, VESA Super VGA driver for GRX 1.03 ** ** Copyright (C) 1991 DJ Delorie, 24 Kirsten Ave, Rochester NH 03867-2954 ** Copyright (C) 1992 Csaba Biegl, 820 Stirrup Dr, Nashville, TN 37221 ** Copyright (C) 1993 Grzegorz Mazur, gbm@ii.pw.edu.pl ** ** This file is distributed under the terms listed in the document ** "copying.dj", available from DJ Delorie at the address above. ** A copy of "copying.dj" should accompany this file; if not, a copy ** should be available from where this file was obtained. This file ** may not be distributed without a verbatim copy of "copying.dj". ** ** This file is distributed WITHOUT ANY WARRANTY; without even the implied ** warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. **/ #pragma inline #include #include #include "vdr.h" char driver_name[] = {"GRX 1.03 VESA driver"}; #define MAX_TEXT_MODES 20 /* maximum text mode table size */ #define EGA_TEXT_START 6 /* start of the EGA mode table */ #define EGA_TEXT_MODES 5 /* number of EGA text modes (incl end marker) */ #define VESA_TEXT_START 4 GrModeEntry text_mode_table[MAX_TEXT_MODES] = { {80, 25, 2, 0x007, SETUP_STANDARD}, {40, 25, 16, 0x001, SETUP_STANDARD}, {80, 25, 16, 0x003, SETUP_STANDARD}, {80, 50, 16, 0x003, SETUP_8X8_FNT}, {132, 25, 16, 0x109, SETUP_STANDARD}, {132, 43, 16, 0x10a, SETUP_STANDARD}, {132, 50, 16, 0x10b, SETUP_STANDARD}, {132, 60, 16, 0x10c, SETUP_STANDARD}, {0, 0, 0, UNSUP, 0} }; #define MAX_GRAPH_MODES 40 /* maximum graphics mode table size */ #define EGA_GRAPH_START 8 /* start of the EGA mode table */ #define EGA_GRAPH_MODES 4 /* number of EGA graphics modes (incl end marker) */ #define VESA_GRAPHIC_START 5 GrModeEntry graphics_mode_table[MAX_GRAPH_MODES] = { {320, 200, 16, 0x00d, SETUP_STANDARD}, {640, 200, 16, 0x00e, SETUP_STANDARD}, {640, 350, 16, 0x010, SETUP_STANDARD}, {640, 480, 16, 0x012, SETUP_STANDARD}, {320, 200, 256, 0x013, SETUP_STANDARD}, {640, 350, 256, 0x11c, SETUP_STANDARD}, {640, 400, 256, 0x100, SETUP_STANDARD}, {640, 480, 256, 0x101, SETUP_STANDARD}, {800, 600, 256, 0x103, SETUP_STANDARD}, {1024, 768, 256, 0x105, SETUP_STANDARD}, {1280, 1024, 256, 0x107, SETUP_STANDARD}, {320, 200, 32768U, 0x10d, SETUP_STANDARD}, {640, 350, 32768U, 0x11d, SETUP_STANDARD}, {640, 400, 32768U, 0x11e, SETUP_STANDARD}, {640, 480, 32768U, 0x110, SETUP_STANDARD}, {800, 600, 32768U, 0x113, SETUP_STANDARD}, {1024, 768, 32768U, 0x116, SETUP_STANDARD}, {1280, 1024, 32768U, 0x119, SETUP_STANDARD}, {320, 200, 0xc010U, 0x10e, SETUP_STANDARD}, {640, 350, 0xc010U, 0x11f, SETUP_STANDARD}, {640, 400, 0xc010U, 0x120, SETUP_STANDARD}, {640, 480, 0xc010U, 0x111, SETUP_STANDARD}, {800, 600, 0xc010U, 0x114, SETUP_STANDARD}, {1024, 768, 0xc010U, 0x117, SETUP_STANDARD}, {1280, 1024, 0xc010U, 0x11a, SETUP_STANDARD}, {320, 200, 0xc018U, 0x10f, SETUP_STANDARD}, {640, 350, 0xc018U, 0x121, SETUP_STANDARD}, {640, 400, 0xc018U, 0x122, SETUP_STANDARD}, {640, 480, 0xc018U, 0x112, SETUP_STANDARD}, {800, 600, 0xc018U, 0x115, SETUP_STANDARD}, {1024, 768, 0xc018U, 0x118, SETUP_STANDARD}, {1280, 1024, 0xc018U, 0x11b, SETUP_STANDARD}, {0, 0, 0, UNSUP, 0} }; #include "pieces/vesainfo.c" #include "paging/vesa.c" int do_driver_init(void) { VgaInfoBlock *vb; short far *modeptr; int mode, table_mode; GrModeEntry *table; HDR->memory_size = 0; vb = VESAgetInfo(); if (vb == NULL) { for (table = text_mode_table + VESA_TEXT_START; table->width > 0; ++table) table->mode.vdr.BIOS_mode = UNSUP; for (table = graphics_mode_table + VESA_GRAPHIC_START; table->width > 0; ++table) table->mode.vdr.BIOS_mode = UNSUP; } else { for (table = text_mode_table + VESA_TEXT_START; table->width > 0; ++table) { modeptr = vb->VideoModePtr; table_mode = table->mode.vdr.BIOS_mode; while ((mode = *modeptr++) != (-1)) { if (table_mode == mode) break; } if (mode == (-1)) table->mode.vdr.BIOS_mode = UNSUP; } for (table = graphics_mode_table + VESA_GRAPHIC_START; table->width > 0; ++table) { modeptr = vb->VideoModePtr; table_mode = table->mode.vdr.BIOS_mode; while ((mode = *modeptr++) != (-1)) { if (table_mode == mode) break; } if (mode == (-1)) table->mode.vdr.BIOS_mode = UNSUP; } } HDR->driver_flags = GRD_VGA | GRD_NEW_DRIVER | GRD_NO_RW | GRD_4096K; return (1); } #include "pieces/textfont.c" int do_mode_set(GrModeEntry * md, int noclear, int *vw, int *vh, char *vflag) { int BIOSno, memmode, pgmode; switch (md->mode.vdr.custom_setup_index) { case SETUP_8X8_FNT: return (mode_set_8x8_font(md, noclear)); } if ((BIOSno = md->mode.vdr.BIOS_mode) > 0x13) { if (noclear) BIOSno |= 0x8000; _AX = VESA_FUNC + VESA_SET_MODE; _BX = BIOSno; geninterrupt(0x10); if (_AX != VESA_SUCCESS) return (-1); } else { if (noclear) BIOSno |= 0x80; _AX = BIOSno; geninterrupt(0x10); } pgmode = setup_VESA_paging(md); if (pgmode == (-1)) return (-1); switch ((unsigned) md->number_of_colors) { case 2U: memmode = GRD_1_PLANE; break; case 16U: memmode = GRD_4_PLANES; break; case 256U: memmode = GRD_8_PLANES; break; case 32768U: memmode = GRD_16_PLANES; break; case 0xc000U + 16: memmode = GRD_16_R_PLANES; break; case 0xc000U + 24: memmode = GRD_24_PLANES; break; default: return (-1); } #if 0 if ((md->number_of_colors > 256) && (VESAversion >= VESA_VERSION(1, 2))) { ModeInfoBlock *mb = VESAgetModeInfo(md->mode.vdr.BIOS_mode); if (mb) { HDR->r_mask = mb->RedMaskSize; HDR->r_offs = mb->RedMaskPos; HDR->g_mask = mb->GreenMaskSize; HDR->g_offs = mb->GreenMaskPos; HDR->b_mask = mb->BlueMaskSize; HDR->b_offs = mb->BlueMaskPos; HDR->f_mask = mb->ReservedMaskSize; HDR->f_offs = mb->ReservedMaskPos; /* is that 16 really only 15 ? */ if ((memmode == GRD_16_R_PLANES) && (HDR->f_mask > 0)) memmode = GRD_16_PLANES; } } #endif #if 0 if ((*vw > md->width) || (*vh > md->height)) { int virw = *vw; int virh = *vh; _BX = (virw > md->width) ? 0 : 1; /* inquire only if width stays the same */ _CX = virw; _AX = VESA_FUNC + VESA_SCAN_LNLEN; geninterrupt(0x10); if (_AX == VESA_SUCCESS) { virw = _CX; virh = _DX; HDR->line_offset = _BX; if ((virw > md->width) || (virh > md->height)) { *vw = virw; *vh = virh; *vflag = 1; } } } #endif return ((HDR->driver_flags & ~(GRD_PLANE_MASK | GRD_PAGING_MASK)) | memmode | pgmode); } void do_screen_start_set(int *cp, int *rp) { _CX = *cp; _DX = *rp; _BX = 0; _AX = VESA_FUNC + VESA_DISP_START; geninterrupt(0x10); if (_AX == VESA_SUCCESS) { *cp = _CX; *rp = _DX; } } #include "pieces/vdrmain.c"