Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 | // SPDX-License-Identifier: GPL-2.0-only /* -*- linux-c -*- ------------------------------------------------------- * * * Copyright (C) 1991, 1992 Linus Torvalds * Copyright 2007 rPath, Inc. - All Rights Reserved * Copyright 2009 Intel Corporation; author H. Peter Anvin * * ----------------------------------------------------------------------- */ /* * Standard video BIOS modes * * We have two options for this; silent and scanned. */ #include "boot.h" #include "video.h" static __videocard video_bios; /* Set a conventional BIOS mode */ static int set_bios_mode(u8 mode); static int bios_set_mode(struct mode_info *mi) { return set_bios_mode(mi->mode - VIDEO_FIRST_BIOS); } static int set_bios_mode(u8 mode) { struct biosregs ireg, oreg; u8 new_mode; initregs(&ireg); ireg.al = mode; /* AH=0x00 Set Video Mode */ intcall(0x10, &ireg, NULL); ireg.ah = 0x0f; /* Get Current Video Mode */ intcall(0x10, &ireg, &oreg); do_restore = 1; /* Assume video contents were lost */ /* Not all BIOSes are clean with the top bit */ new_mode = oreg.al & 0x7f; if (new_mode == mode) return 0; /* Mode change OK */ #ifndef _WAKEUP if (new_mode != boot_params.screen_info.orig_video_mode) { /* Mode setting failed, but we didn't end up where we started. That's bad. Try to revert to the original video mode. */ ireg.ax = boot_params.screen_info.orig_video_mode; intcall(0x10, &ireg, NULL); } #endif return -1; } static int bios_probe(void) { u8 mode; #ifdef _WAKEUP u8 saved_mode = 0x03; #else u8 saved_mode = boot_params.screen_info.orig_video_mode; #endif u16 crtc; struct mode_info *mi; int nmodes = 0; if (adapter != ADAPTER_EGA && adapter != ADAPTER_VGA) return 0; set_fs(0); crtc = vga_crtc(); video_bios.modes = GET_HEAP(struct mode_info, 0); for (mode = 0x14; mode <= 0x7f; mode++) { if (!heap_free(sizeof(struct mode_info))) break; if (mode_defined(VIDEO_FIRST_BIOS+mode)) continue; if (set_bios_mode(mode)) continue; /* Try to verify that it's a text mode. */ /* Attribute Controller: make graphics controller disabled */ if (in_idx(0x3c0, 0x10) & 0x01) continue; /* Graphics Controller: verify Alpha addressing enabled */ if (in_idx(0x3ce, 0x06) & 0x01) continue; /* CRTC cursor location low should be zero(?) */ if (in_idx(crtc, 0x0f)) continue; mi = GET_HEAP(struct mode_info, 1); mi->mode = VIDEO_FIRST_BIOS+mode; mi->depth = 0; /* text */ mi->x = rdfs16(0x44a); mi->y = rdfs8(0x484)+1; nmodes++; } set_bios_mode(saved_mode); return nmodes; } static __videocard video_bios = { .card_name = "BIOS", .probe = bios_probe, .set_mode = bios_set_mode, .unsafe = 1, .xmode_first = VIDEO_FIRST_BIOS, .xmode_n = 0x80, }; |