aboutsummaryrefslogtreecommitdiffstats
path: root/vbe.c
diff options
context:
space:
mode:
authorAnssi Hannula <anssi@mandriva.org>2009-09-06 12:56:21 +0000
committerAnssi Hannula <anssi@mandriva.org>2009-09-06 12:56:21 +0000
commit9724a1766da9ddeeb5f19a2fe28d812fa1436cd2 (patch)
tree87f32e6b21bca823bc2a3bde1e7fb4855cd92b34 /vbe.c
parent2959cd3e36fe2b74ff4ae3f244ac6e1c5a93cbbe (diff)
downloadmonitor-edid-9724a1766da9ddeeb5f19a2fe28d812fa1436cd2.tar
monitor-edid-9724a1766da9ddeeb5f19a2fe28d812fa1436cd2.tar.gz
monitor-edid-9724a1766da9ddeeb5f19a2fe28d812fa1436cd2.tar.bz2
monitor-edid-9724a1766da9ddeeb5f19a2fe28d812fa1436cd2.tar.xz
monitor-edid-9724a1766da9ddeeb5f19a2fe28d812fa1436cd2.zip
monitor-get-edid-using-vbe:
check if the port supports DDC before trying to read EDID data (this should prevent problems when probing nonexistent ports on old cards)
Diffstat (limited to 'vbe.c')
-rw-r--r--vbe.c87
1 files changed, 84 insertions, 3 deletions
diff --git a/vbe.c b/vbe.c
index 7791751..ff02e03 100644
--- a/vbe.c
+++ b/vbe.c
@@ -135,6 +135,42 @@ static int vbe_check_vbe_info(hd_data_t *hd_data)
return 1;
}
+static void parse_ddc_info(int port, int info)
+{
+ log_err("Port %d:\n", port);
+ log_err(" DDC1 %ssupported\n", info & 1 ? "" : "not ");
+ log_err(" DDC2 %ssupported\n", info & 2 ? "" : "not ");
+ log_err(" Screen %sblanked during data transfer\n", info & 4 ? "" : "not ");
+ log_err(" Time to transfer one EDID block: %d sec (rounded up)\n", (info & 0xff00) >> 8);
+}
+
+static int vbe_check_ddc_capabilities(hd_data_t *hd_data, int port)
+{
+ int i;
+ int ax, bx, cx;
+
+ /* Setup registers for the interrupt call */
+ ax = 0x4f15;
+ bx = 0; /* Report DDC Capabilities */
+ cx = port;
+
+ /* Get capabilities */
+ i = CallInt10(&ax, &bx, &cx, NULL, 0, hd_data->flags.cpuemu) & 0xffff;
+ if (i != 0x4f) {
+ log_err("DDC: Error (0x4f15:00): 0x%04x\n", i);
+ return 0;
+ }
+
+ parse_ddc_info(port, bx);
+
+ if (!(bx & 3)) {
+ log_err("DDC (0x4f15:00): DDC not supported, not continuing\n", i);
+ return 0;
+ }
+
+ return 1;
+}
+
/* Get EDID info. */
int vbe_get_edid_info(hd_data_t *hd_data, char *edid, int port)
{
@@ -149,7 +185,7 @@ int vbe_get_edid_info(hd_data_t *hd_data, char *edid, int port)
/* Get EDID block */
i = CallInt10(&ax, &bx, &cx, edid, 256, hd_data->flags.cpuemu) & 0xffff;
if (i != 0x4f) {
- log_err("EDID: Error (0x4f15): 0x%04x\n", i);
+ log_err("EDID: Error (0x4f15:01): 0x%04x\n", i);
return 0;
}
@@ -211,6 +247,49 @@ static int vbe_check_vbe_info__old(void)
return 1;
}
+static int vbe_check_ddc_capabilities__old(int port)
+{
+ int i;
+ struct LRMI_regs regs;
+
+ /* initialize LRMI */
+ if (LRMI_init() == 0) {
+ log_err("EDID: could not initialize LRMI\n");
+ return 0;
+ }
+
+ /* set up registers for the interrupt call. */
+ memset(&regs, 0, sizeof(regs));
+ regs.eax = 0x4f15;
+ regs.ebx = 0x0000;
+ regs.ecx = port;
+ regs.es = 0;
+ regs.edi = 0;
+
+ /* do it. */
+ iopl(3);
+ ioperm(0, 0x400, 1);
+ if (LRMI_int(0x10, &regs) == 0) {
+ return 0;
+ }
+
+ /* check for successful return code */
+ i = regs.eax & 0xffff;
+ if (i != 0x4f) {
+ log_err("DDC: Error (0x4f15:00): 0x%04x\n", i);
+ return 0;
+ }
+
+ parse_ddc_info(port, regs.ebx);
+
+ if (!(regs.ebx & 3)) {
+ log_err("DDC (0x4f15:00): DDC not supported, not continuing\n", i);
+ return 0;
+ }
+
+ return 1;
+}
+
static int vbe_get_edid_info__old(char *edid, int port)
{
int i;
@@ -252,7 +331,7 @@ static int vbe_get_edid_info__old(char *edid, int port)
i = regs.eax & 0xffff;
if (i != 0x4f) {
LRMI_free_real(mem);
- log_err("EDID: Error (0x4f15): 0x%04x\n", i);
+ log_err("EDID: Error (0x4f15:01): 0x%04x\n", i);
return 0;
}
@@ -269,7 +348,8 @@ int get_edid__old(char *edid, int port)
one is also bogus for the other */
log_err("Retrying with old LRMI interface\n");
ok =
- (box_is_xbox() || vbe_check_vbe_info__old()) &&
+ (box_is_xbox() || (vbe_check_vbe_info__old() &&
+ vbe_check_ddc_capabilities__old(port))) &&
vbe_get_edid_info__old(edid, port);
return ok;
}
@@ -287,6 +367,7 @@ int get_edid(hd_data_t *hd_data, char *edid, int port)
if (!box_is_xbox()) {
if (InitInt10(hd_data) == 0) {
ok = vbe_check_vbe_info(hd_data)
+ && vbe_check_ddc_capabilities(hd_data, port)
&& vbe_get_edid_info(hd_data, edid, port);
FreeInt10();
}