^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /* -*- linux-c -*- ------------------------------------------------------- *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (C) 1991, 1992 Linus Torvalds
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright 2007 rPath, Inc. - All Rights Reserved
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright 2009 Intel Corporation; author H. Peter Anvin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * ----------------------------------------------------------------------- */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Common all-VGA modes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include "boot.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include "video.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) static struct mode_info vga_modes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) { VIDEO_80x25, 80, 25, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) { VIDEO_8POINT, 80, 50, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) { VIDEO_80x43, 80, 43, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) { VIDEO_80x28, 80, 28, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) { VIDEO_80x30, 80, 30, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) { VIDEO_80x34, 80, 34, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) { VIDEO_80x60, 80, 60, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) static struct mode_info ega_modes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) { VIDEO_80x25, 80, 25, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) { VIDEO_8POINT, 80, 43, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) static struct mode_info cga_modes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) { VIDEO_80x25, 80, 25, 0 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) static __videocard video_vga;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) /* Set basic 80x25 mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) static u8 vga_set_basic_mode(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) struct biosregs ireg, oreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) u8 mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) initregs(&ireg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* Query current mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) ireg.ax = 0x0f00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) intcall(0x10, &ireg, &oreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) mode = oreg.al;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (mode != 3 && mode != 7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) mode = 3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /* Set the mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) ireg.ax = mode; /* AH=0: set mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) intcall(0x10, &ireg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) do_restore = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) return mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) static void vga_set_8font(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) /* Set 8x8 font - 80x43 on EGA, 80x50 on VGA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct biosregs ireg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) initregs(&ireg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) /* Set 8x8 font */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) ireg.ax = 0x1112;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) /* ireg.bl = 0; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) intcall(0x10, &ireg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /* Use alternate print screen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) ireg.ax = 0x1200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) ireg.bl = 0x20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) intcall(0x10, &ireg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) /* Turn off cursor emulation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) ireg.ax = 0x1201;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) ireg.bl = 0x34;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) intcall(0x10, &ireg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) /* Cursor is scan lines 6-7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) ireg.ax = 0x0100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) ireg.cx = 0x0607;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) intcall(0x10, &ireg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static void vga_set_14font(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) /* Set 9x14 font - 80x28 on VGA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) struct biosregs ireg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) initregs(&ireg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /* Set 9x14 font */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) ireg.ax = 0x1111;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) /* ireg.bl = 0; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) intcall(0x10, &ireg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) /* Turn off cursor emulation */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) ireg.ax = 0x1201;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) ireg.bl = 0x34;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) intcall(0x10, &ireg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) /* Cursor is scan lines 11-12 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) ireg.ax = 0x0100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) ireg.cx = 0x0b0c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) intcall(0x10, &ireg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) static void vga_set_80x43(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* Set 80x43 mode on VGA (not EGA) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) struct biosregs ireg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) initregs(&ireg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) /* Set 350 scans */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) ireg.ax = 0x1201;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) ireg.bl = 0x30;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) intcall(0x10, &ireg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) /* Reset video mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) ireg.ax = 0x0003;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) intcall(0x10, &ireg, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) vga_set_8font();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) /* I/O address of the VGA CRTC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) u16 vga_crtc(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) return (inb(0x3cc) & 1) ? 0x3d4 : 0x3b4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) static void vga_set_480_scanlines(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) u16 crtc; /* CRTC base address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) u8 csel; /* CRTC miscellaneous output register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) crtc = vga_crtc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) out_idx(0x0c, crtc, 0x11); /* Vertical sync end, unlock CR0-7 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) out_idx(0x0b, crtc, 0x06); /* Vertical total */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) out_idx(0x3e, crtc, 0x07); /* Vertical overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) out_idx(0xea, crtc, 0x10); /* Vertical sync start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) out_idx(0xdf, crtc, 0x12); /* Vertical display end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) out_idx(0xe7, crtc, 0x15); /* Vertical blank start */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) out_idx(0x04, crtc, 0x16); /* Vertical blank end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) csel = inb(0x3cc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) csel &= 0x0d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) csel |= 0xe2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) outb(csel, 0x3c2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) static void vga_set_vertical_end(int lines)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) u16 crtc; /* CRTC base address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) u8 ovfw; /* CRTC overflow register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) int end = lines-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) crtc = vga_crtc();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) ovfw = 0x3c | ((end >> (8-1)) & 0x02) | ((end >> (9-6)) & 0x40);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) out_idx(ovfw, crtc, 0x07); /* Vertical overflow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) out_idx(end, crtc, 0x12); /* Vertical display end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) static void vga_set_80x30(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) vga_set_480_scanlines();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) vga_set_vertical_end(30*16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) static void vga_set_80x34(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) vga_set_480_scanlines();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) vga_set_14font();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) vga_set_vertical_end(34*14);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) static void vga_set_80x60(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) vga_set_480_scanlines();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) vga_set_8font();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) vga_set_vertical_end(60*8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static int vga_set_mode(struct mode_info *mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) /* Set the basic mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) vga_set_basic_mode();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) /* Override a possibly broken BIOS */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) force_x = mode->x;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) force_y = mode->y;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) switch (mode->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) case VIDEO_80x25:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) case VIDEO_8POINT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) vga_set_8font();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) case VIDEO_80x43:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) vga_set_80x43();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) case VIDEO_80x28:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) vga_set_14font();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) case VIDEO_80x30:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) vga_set_80x30();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) case VIDEO_80x34:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) vga_set_80x34();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) case VIDEO_80x60:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) vga_set_80x60();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) * Note: this probe includes basic information required by all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) * systems. It should be executed first, by making sure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * video-vga.c is listed first in the Makefile.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) static int vga_probe(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static const char *card_name[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) "CGA/MDA/HGC", "EGA", "VGA"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) static struct mode_info *mode_lists[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) cga_modes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) ega_modes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) vga_modes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) static int mode_count[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) ARRAY_SIZE(cga_modes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) ARRAY_SIZE(ega_modes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) ARRAY_SIZE(vga_modes),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) struct biosregs ireg, oreg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) initregs(&ireg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) ireg.ax = 0x1200;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) ireg.bl = 0x10; /* Check EGA/VGA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) intcall(0x10, &ireg, &oreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) #ifndef _WAKEUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) boot_params.screen_info.orig_video_ega_bx = oreg.bx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) /* If we have MDA/CGA/HGC then BL will be unchanged at 0x10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (oreg.bl != 0x10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /* EGA/VGA */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) ireg.ax = 0x1a00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) intcall(0x10, &ireg, &oreg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) if (oreg.al == 0x1a) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) adapter = ADAPTER_VGA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) #ifndef _WAKEUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) boot_params.screen_info.orig_video_isVGA = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) adapter = ADAPTER_EGA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) adapter = ADAPTER_CGA;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) video_vga.modes = mode_lists[adapter];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) video_vga.card_name = card_name[adapter];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) return mode_count[adapter];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) static __videocard video_vga = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) .card_name = "VGA",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) .probe = vga_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) .set_mode = vga_set_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) };