mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
126 lines
2.7 KiB
126 lines
2.7 KiB
// 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, |
|
};
|
|
|