Updated drivers to use BIOS module instead of vm86.
This commit is contained in:
@@ -14,7 +14,6 @@
|
|||||||
#include <graphic_driver.h>
|
#include <graphic_driver.h>
|
||||||
#ifdef __HAIKU__
|
#ifdef __HAIKU__
|
||||||
#include <boot_item.h>
|
#include <boot_item.h>
|
||||||
#include <arch/x86/vm86.h>
|
|
||||||
#endif // __HAIKU__
|
#endif // __HAIKU__
|
||||||
|
|
||||||
#include "DriverInterface.h"
|
#include "DriverInterface.h"
|
||||||
|
|||||||
@@ -8,12 +8,12 @@
|
|||||||
|
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
#include <PCI.h>
|
#include <PCI.h>
|
||||||
|
#include <drivers/bios.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <graphic_driver.h>
|
#include <graphic_driver.h>
|
||||||
#include <boot_item.h>
|
#include <boot_item.h>
|
||||||
#include <arch/x86/vm86.h>
|
|
||||||
|
|
||||||
#include "DriverInterface.h"
|
#include "DriverInterface.h"
|
||||||
|
|
||||||
@@ -249,52 +249,60 @@ GetEdidFromBIOS(edid1_raw& edidRaw)
|
|||||||
#define ADDRESS_SEGMENT(address) ((addr_t)(address) >> 4)
|
#define ADDRESS_SEGMENT(address) ((addr_t)(address) >> 4)
|
||||||
#define ADDRESS_OFFSET(address) ((addr_t)(address) & 0xf)
|
#define ADDRESS_OFFSET(address) ((addr_t)(address) & 0xf)
|
||||||
|
|
||||||
vm86_state vmState;
|
bios_module_info* biosModule;
|
||||||
|
status_t status = get_module(B_BIOS_MODULE_NAME, (module_info**)&biosModule);
|
||||||
status_t status = vm86_prepare(&vmState, 0x2000);
|
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
TRACE("GetEdidFromBIOS(); vm86_prepare() failed, status: 0x%lx\n",
|
TRACE("GetEdidFromBIOS(): failed to get BIOS module: 0x%" B_PRIx32 "\n",
|
||||||
status);
|
status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
vmState.regs.eax = 0x4f15;
|
bios_state* state;
|
||||||
vmState.regs.ebx = 0; // 0 = report DDC service
|
status = biosModule->prepare(&state);
|
||||||
vmState.regs.ecx = 0;
|
if (status != B_OK) {
|
||||||
vmState.regs.es = 0;
|
TRACE("GetEdidFromBIOS(): bios_prepare() failed: 0x%" B_PRIx32 "\n",
|
||||||
vmState.regs.edi = 0;
|
status);
|
||||||
|
put_module(B_BIOS_MODULE_NAME);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
status = vm86_do_int(&vmState, 0x10);
|
bios_regs regs = {};
|
||||||
|
regs.eax = 0x4f15;
|
||||||
|
regs.ebx = 0; // 0 = report DDC service
|
||||||
|
regs.ecx = 0;
|
||||||
|
regs.es = 0;
|
||||||
|
regs.edi = 0;
|
||||||
|
|
||||||
|
status = biosModule->interrupt(state, 0x10, ®s);
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
// AH contains the error code, and AL determines whether or not the
|
// AH contains the error code, and AL determines whether or not the
|
||||||
// function is supported.
|
// function is supported.
|
||||||
if (vmState.regs.eax != 0x4f)
|
if (regs.eax != 0x4f)
|
||||||
status = B_NOT_SUPPORTED;
|
status = B_NOT_SUPPORTED;
|
||||||
|
|
||||||
// Test if DDC is supported by the monitor.
|
// Test if DDC is supported by the monitor.
|
||||||
if ((vmState.regs.ebx & 3) == 0)
|
if ((regs.ebx & 3) == 0)
|
||||||
status = B_NOT_SUPPORTED;
|
status = B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
// According to the author of the vm86 functions, the address of any
|
edid1_raw* edid = (edid1_raw*)biosModule->allocate_mem(state,
|
||||||
// object to receive data must be >= 0x1000 and within the ram size
|
sizeof(edid1_raw));
|
||||||
// specified in the second argument of the vm86_prepare() call above.
|
if (edid == NULL) {
|
||||||
// Thus, the address of the struct to receive the EDID info is set to
|
status = B_NO_MEMORY;
|
||||||
// 0x1000.
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
edid1_raw* edid = (edid1_raw*)0x1000;
|
regs.eax = 0x4f15;
|
||||||
|
regs.ebx = 1; // 1 = read EDID
|
||||||
|
regs.ecx = 0;
|
||||||
|
regs.edx = 0;
|
||||||
|
regs.es = ADDRESS_SEGMENT(edid);
|
||||||
|
regs.edi = ADDRESS_OFFSET(edid);
|
||||||
|
|
||||||
vmState.regs.eax = 0x4f15;
|
status = biosModule->interrupt(state, 0x10, ®s);
|
||||||
vmState.regs.ebx = 1; // 1 = read EDID
|
|
||||||
vmState.regs.ecx = 0;
|
|
||||||
vmState.regs.edx = 0;
|
|
||||||
vmState.regs.es = ADDRESS_SEGMENT(edid);
|
|
||||||
vmState.regs.edi = ADDRESS_OFFSET(edid);
|
|
||||||
|
|
||||||
status = vm86_do_int(&vmState, 0x10);
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
if (vmState.regs.eax != 0x4f) {
|
if (regs.eax != 0x4f) {
|
||||||
status = B_NOT_SUPPORTED;
|
status = B_NOT_SUPPORTED;
|
||||||
} else {
|
} else {
|
||||||
// Copy the EDID info to the caller's location, and compute the
|
// Copy the EDID info to the caller's location, and compute the
|
||||||
@@ -322,8 +330,9 @@ GetEdidFromBIOS(edid1_raw& edidRaw)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vm86_cleanup(&vmState);
|
out:
|
||||||
|
biosModule->finish(state);
|
||||||
|
put_module(B_BIOS_MODULE_NAME);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,31 +345,40 @@ SetVesaDisplayMode(uint16 mode)
|
|||||||
#define SET_MODE_MASK 0x01ff
|
#define SET_MODE_MASK 0x01ff
|
||||||
#define SET_MODE_LINEAR_BUFFER (1 << 14)
|
#define SET_MODE_LINEAR_BUFFER (1 << 14)
|
||||||
|
|
||||||
vm86_state vmState;
|
bios_module_info* biosModule;
|
||||||
|
status_t status = get_module(B_BIOS_MODULE_NAME, (module_info**)&biosModule);
|
||||||
status_t status = vm86_prepare(&vmState, 0x2000);
|
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
TRACE("SetVesaDisplayMode(); vm86_prepare() failed, status: 0x%lx\n",
|
TRACE("SetVesaDisplayMode(0x%x): failed to get BIOS module: 0x%" B_PRIx32
|
||||||
status);
|
"\n", mode, status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
vmState.regs.eax = 0x4f02;
|
bios_state* state;
|
||||||
vmState.regs.ebx = (mode & SET_MODE_MASK) | SET_MODE_LINEAR_BUFFER;
|
status = biosModule->prepare(&state);
|
||||||
|
|
||||||
status = vm86_do_int(&vmState, 0x10);
|
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
TRACE("SetVesaDisplayMode(0x%x): vm86_do_int failed\n", mode);
|
TRACE("SetVesaDisplayMode(0x%x): bios_prepare() failed: 0x%" B_PRIx32
|
||||||
|
"\n", mode, status);
|
||||||
|
put_module(B_BIOS_MODULE_NAME);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == B_OK && (vmState.regs.eax & 0xffff) != 0x4f) {
|
bios_regs regs = {};
|
||||||
TRACE("SetVesaDisplayMode(0x%x): BIOS returned 0x%04lx\n", mode,
|
regs.eax = 0x4f02;
|
||||||
vmState.regs.eax & 0xffff);
|
regs.ebx = (mode & SET_MODE_MASK) | SET_MODE_LINEAR_BUFFER;
|
||||||
|
|
||||||
|
status = biosModule->interrupt(state, 0x10, ®s);
|
||||||
|
if (status != B_OK) {
|
||||||
|
TRACE("SetVesaDisplayMode(0x%x): BIOS interrupt failed\n", mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == B_OK && (regs.eax & 0xffff) != 0x4f) {
|
||||||
|
TRACE("SetVesaDisplayMode(0x%x): BIOS returned 0x%04" B_PRIx32 "\n",
|
||||||
|
mode, regs.eax & 0xffff);
|
||||||
status = B_ERROR;
|
status = B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
vm86_cleanup(&vmState);
|
biosModule->finish(state);
|
||||||
|
put_module(B_BIOS_MODULE_NAME);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,12 +10,12 @@
|
|||||||
#include <AGP.h>
|
#include <AGP.h>
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
#include <PCI.h>
|
#include <PCI.h>
|
||||||
|
#include <drivers/bios.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <graphic_driver.h>
|
#include <graphic_driver.h>
|
||||||
#include <boot_item.h>
|
#include <boot_item.h>
|
||||||
#include <arch/x86/vm86.h>
|
|
||||||
|
|
||||||
#include "DriverInterface.h"
|
#include "DriverInterface.h"
|
||||||
|
|
||||||
@@ -148,52 +148,60 @@ GetEdidFromBIOS(edid1_raw& edidRaw)
|
|||||||
#define ADDRESS_SEGMENT(address) ((addr_t)(address) >> 4)
|
#define ADDRESS_SEGMENT(address) ((addr_t)(address) >> 4)
|
||||||
#define ADDRESS_OFFSET(address) ((addr_t)(address) & 0xf)
|
#define ADDRESS_OFFSET(address) ((addr_t)(address) & 0xf)
|
||||||
|
|
||||||
vm86_state vmState;
|
bios_module_info* biosModule;
|
||||||
|
status_t status = get_module(B_BIOS_MODULE_NAME, (module_info**)&biosModule);
|
||||||
status_t status = vm86_prepare(&vmState, 0x2000);
|
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
TRACE("GetEdidFromBIOS(); vm86_prepare() failed, status: 0x%lx\n",
|
TRACE("GetEdidFromBIOS(): failed to get BIOS module: 0x%" B_PRIx32 "\n",
|
||||||
status);
|
status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
vmState.regs.eax = 0x4f15;
|
bios_state* state;
|
||||||
vmState.regs.ebx = 0; // 0 = report DDC service
|
status = biosModule->prepare(&state);
|
||||||
vmState.regs.ecx = 0;
|
if (status != B_OK) {
|
||||||
vmState.regs.es = 0;
|
TRACE("GetEdidFromBIOS(): bios_prepare() failed: 0x%" B_PRIx32 "\n",
|
||||||
vmState.regs.edi = 0;
|
status);
|
||||||
|
put_module(B_BIOS_MODULE_NAME);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
status = vm86_do_int(&vmState, 0x10);
|
bios_regs regs = {};
|
||||||
|
regs.eax = 0x4f15;
|
||||||
|
regs.ebx = 0; // 0 = report DDC service
|
||||||
|
regs.ecx = 0;
|
||||||
|
regs.es = 0;
|
||||||
|
regs.edi = 0;
|
||||||
|
|
||||||
|
status = biosModule->interrupt(state, 0x10, ®s);
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
// AH contains the error code, and AL determines wether or not the
|
// AH contains the error code, and AL determines whether or not the
|
||||||
// function is supported.
|
// function is supported.
|
||||||
if (vmState.regs.eax != 0x4f)
|
if (regs.eax != 0x4f)
|
||||||
status = B_NOT_SUPPORTED;
|
status = B_NOT_SUPPORTED;
|
||||||
|
|
||||||
// Test if DDC is supported by the monitor.
|
// Test if DDC is supported by the monitor.
|
||||||
if ((vmState.regs.ebx & 3) == 0)
|
if ((regs.ebx & 3) == 0)
|
||||||
status = B_NOT_SUPPORTED;
|
status = B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
// According to the author of the vm86 functions, the address of any
|
edid1_raw* edid = (edid1_raw*)biosModule->allocate_mem(state,
|
||||||
// object to receive data must be >= 0x1000 and within the ram size
|
sizeof(edid1_raw));
|
||||||
// specified in the second argument of the vm86_prepare() call above.
|
if (edid == NULL) {
|
||||||
// Thus, the address of the struct to receive the EDID info is set to
|
status = B_NO_MEMORY;
|
||||||
// 0x1000.
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
edid1_raw* edid = (edid1_raw*)0x1000;
|
regs.eax = 0x4f15;
|
||||||
|
regs.ebx = 1; // 1 = read EDID
|
||||||
|
regs.ecx = 0;
|
||||||
|
regs.edx = 0;
|
||||||
|
regs.es = ADDRESS_SEGMENT(edid);
|
||||||
|
regs.edi = ADDRESS_OFFSET(edid);
|
||||||
|
|
||||||
vmState.regs.eax = 0x4f15;
|
status = biosModule->interrupt(state, 0x10, ®s);
|
||||||
vmState.regs.ebx = 1; // 1 = read EDID
|
|
||||||
vmState.regs.ecx = 0;
|
|
||||||
vmState.regs.edx = 0;
|
|
||||||
vmState.regs.es = ADDRESS_SEGMENT(edid);
|
|
||||||
vmState.regs.edi = ADDRESS_OFFSET(edid);
|
|
||||||
|
|
||||||
status = vm86_do_int(&vmState, 0x10);
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
if (vmState.regs.eax != 0x4f) {
|
if (regs.eax != 0x4f) {
|
||||||
status = B_NOT_SUPPORTED;
|
status = B_NOT_SUPPORTED;
|
||||||
} else {
|
} else {
|
||||||
// Copy the EDID info to the caller's location, and compute the
|
// Copy the EDID info to the caller's location, and compute the
|
||||||
@@ -221,9 +229,11 @@ GetEdidFromBIOS(edid1_raw& edidRaw)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vm86_cleanup(&vmState);
|
out:
|
||||||
|
biosModule->finish(state);
|
||||||
|
put_module(B_BIOS_MODULE_NAME);
|
||||||
|
|
||||||
TRACE("GetEdidFromBIOS() status: 0x%lx\n", status);
|
TRACE("GetEdidFromBIOS() status: 0x%" B_PRIx32 "\n", status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,13 +8,13 @@
|
|||||||
|
|
||||||
#include <KernelExport.h>
|
#include <KernelExport.h>
|
||||||
#include <PCI.h>
|
#include <PCI.h>
|
||||||
|
#ifdef __HAIKU__
|
||||||
|
#include <drivers/bios.h>
|
||||||
|
#endif // __HAIKU__
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <graphic_driver.h>
|
#include <graphic_driver.h>
|
||||||
#ifdef __HAIKU__
|
|
||||||
#include <arch/x86/vm86.h>
|
|
||||||
#endif // __HAIKU__
|
|
||||||
|
|
||||||
#include "DriverInterface.h"
|
#include "DriverInterface.h"
|
||||||
|
|
||||||
@@ -493,51 +493,60 @@ GetEdidFromBIOS(edid1_raw& edidRaw)
|
|||||||
#define ADDRESS_SEGMENT(address) ((addr_t)(address) >> 4)
|
#define ADDRESS_SEGMENT(address) ((addr_t)(address) >> 4)
|
||||||
#define ADDRESS_OFFSET(address) ((addr_t)(address) & 0xf)
|
#define ADDRESS_OFFSET(address) ((addr_t)(address) & 0xf)
|
||||||
|
|
||||||
vm86_state vmState;
|
bios_module_info* biosModule;
|
||||||
|
status_t status = get_module(B_BIOS_MODULE_NAME, (module_info**)&biosModule);
|
||||||
status_t status = vm86_prepare(&vmState, 0x2000);
|
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
TRACE("GetEdidFromBIOS(); vm86_prepare() failed, status: %lx\n", status);
|
TRACE("GetEdidFromBIOS(): failed to get BIOS module: 0x%" B_PRIx32 "\n",
|
||||||
|
status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
vmState.regs.eax = 0x4f15;
|
bios_state* state;
|
||||||
vmState.regs.ebx = 0; // 0 = report DDC service
|
status = biosModule->prepare(&state);
|
||||||
vmState.regs.ecx = 0;
|
if (status != B_OK) {
|
||||||
vmState.regs.es = 0;
|
TRACE("GetEdidFromBIOS(): bios_prepare() failed: 0x%" B_PRIx32 "\n",
|
||||||
vmState.regs.edi = 0;
|
status);
|
||||||
|
put_module(B_BIOS_MODULE_NAME);
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
status = vm86_do_int(&vmState, 0x10);
|
bios_regs regs = {};
|
||||||
|
regs.eax = 0x4f15;
|
||||||
|
regs.ebx = 0; // 0 = report DDC service
|
||||||
|
regs.ecx = 0;
|
||||||
|
regs.es = 0;
|
||||||
|
regs.edi = 0;
|
||||||
|
|
||||||
|
status = biosModule->interrupt(state, 0x10, ®s);
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
// AH contains the error code, and AL determines whether or not the
|
// AH contains the error code, and AL determines whether or not the
|
||||||
// function is supported.
|
// function is supported.
|
||||||
if (vmState.regs.eax != 0x4f)
|
if (regs.eax != 0x4f)
|
||||||
status = B_NOT_SUPPORTED;
|
status = B_NOT_SUPPORTED;
|
||||||
|
|
||||||
// Test if DDC is supported by the monitor.
|
// Test if DDC is supported by the monitor.
|
||||||
if ((vmState.regs.ebx & 3) == 0)
|
if ((regs.ebx & 3) == 0)
|
||||||
status = B_NOT_SUPPORTED;
|
status = B_NOT_SUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
// According to the author of the vm86 functions, the address of any
|
edid1_raw* edid = (edid1_raw*)biosModule->allocate_mem(state,
|
||||||
// object to receive data must be >= 0x1000 and within the ram size
|
sizeof(edid1_raw));
|
||||||
// specified in the second argument of the vm86_prepare() call above.
|
if (edid == NULL) {
|
||||||
// Thus, the address of the struct to receive the EDID info is set to
|
status = B_NO_MEMORY;
|
||||||
// 0x1000.
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
edid1_raw* edid = (edid1_raw*)0x1000;
|
regs.eax = 0x4f15;
|
||||||
|
regs.ebx = 1; // 1 = read EDID
|
||||||
|
regs.ecx = 0;
|
||||||
|
regs.edx = 0;
|
||||||
|
regs.es = ADDRESS_SEGMENT(edid);
|
||||||
|
regs.edi = ADDRESS_OFFSET(edid);
|
||||||
|
|
||||||
vmState.regs.eax = 0x4f15;
|
status = biosModule->interrupt(state, 0x10, ®s);
|
||||||
vmState.regs.ebx = 1; // 1 = read EDID
|
|
||||||
vmState.regs.ecx = 0;
|
|
||||||
vmState.regs.edx = 0;
|
|
||||||
vmState.regs.es = ADDRESS_SEGMENT(edid);
|
|
||||||
vmState.regs.edi = ADDRESS_OFFSET(edid);
|
|
||||||
|
|
||||||
status = vm86_do_int(&vmState, 0x10);
|
|
||||||
if (status == B_OK) {
|
if (status == B_OK) {
|
||||||
if (vmState.regs.eax != 0x4f) {
|
if (regs.eax != 0x4f) {
|
||||||
status = B_NOT_SUPPORTED;
|
status = B_NOT_SUPPORTED;
|
||||||
} else {
|
} else {
|
||||||
// Copy the EDID info to the caller's location, and compute the
|
// Copy the EDID info to the caller's location, and compute the
|
||||||
@@ -565,9 +574,11 @@ GetEdidFromBIOS(edid1_raw& edidRaw)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vm86_cleanup(&vmState);
|
out:
|
||||||
|
biosModule->finish(state);
|
||||||
|
put_module(B_BIOS_MODULE_NAME);
|
||||||
|
|
||||||
TRACE("GetEdidFromBIOS() status: 0x%lx\n", status);
|
TRACE("GetEdidFromBIOS() status: 0x%" B_PRIx32 "\n", status);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,10 +9,11 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <drivers/bios.h>
|
||||||
|
|
||||||
#include <boot_item.h>
|
#include <boot_item.h>
|
||||||
#include <frame_buffer_console.h>
|
#include <frame_buffer_console.h>
|
||||||
#include <util/kernel_cpp.h>
|
#include <util/kernel_cpp.h>
|
||||||
#include <arch/x86/vm86.h>
|
|
||||||
#include <vm/vm.h>
|
#include <vm/vm.h>
|
||||||
|
|
||||||
#include "driver.h"
|
#include "driver.h"
|
||||||
@@ -20,6 +21,43 @@
|
|||||||
#include "vesa_info.h"
|
#include "vesa_info.h"
|
||||||
|
|
||||||
|
|
||||||
|
static bios_module_info* sBIOSModule;
|
||||||
|
|
||||||
|
|
||||||
|
/*! Loads the BIOS module and sets up a state for it. The BIOS module is only
|
||||||
|
loaded when we need it, as it is quite a large module.
|
||||||
|
*/
|
||||||
|
static status_t
|
||||||
|
vbe_call_prepare(bios_state** state)
|
||||||
|
{
|
||||||
|
status_t status;
|
||||||
|
|
||||||
|
status = get_module(B_BIOS_MODULE_NAME, (module_info**)&sBIOSModule);
|
||||||
|
if (status != B_OK) {
|
||||||
|
dprintf(DEVICE_NAME ": failed to get BIOS module: %s\n",
|
||||||
|
strerror(status));
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
status = sBIOSModule->prepare(state);
|
||||||
|
if (status != B_OK) {
|
||||||
|
dprintf(DEVICE_NAME ": failed to prepare BIOS state: %s\n",
|
||||||
|
strerror(status));
|
||||||
|
put_module(B_BIOS_MODULE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
vbe_call_finish(bios_state* state)
|
||||||
|
{
|
||||||
|
sBIOSModule->finish(state);
|
||||||
|
put_module(B_BIOS_MODULE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
find_graphics_card(addr_t frameBuffer, addr_t& base, size_t& size)
|
find_graphics_card(addr_t frameBuffer, addr_t& base, size_t& size)
|
||||||
{
|
{
|
||||||
@@ -80,26 +118,31 @@ get_color_space_for_depth(uint32 depth)
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
vbe_get_mode_info(struct vm86_state& vmState, uint16 mode,
|
vbe_get_mode_info(bios_state* state, uint16 mode, struct vbe_mode_info* modeInfo)
|
||||||
struct vbe_mode_info* modeInfo)
|
|
||||||
{
|
{
|
||||||
struct vbe_mode_info* vbeModeInfo = (struct vbe_mode_info*)0x1000;
|
void* vbeModeInfo = sBIOSModule->allocate_mem(state,
|
||||||
|
sizeof(struct vbe_mode_info));
|
||||||
|
if (vbeModeInfo == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
memset(vbeModeInfo, 0, sizeof(vbe_mode_info));
|
memset(vbeModeInfo, 0, sizeof(vbe_mode_info));
|
||||||
vmState.regs.eax = 0x4f01;
|
|
||||||
vmState.regs.ecx = mode;
|
|
||||||
vmState.regs.es = 0x1000 >> 4;
|
|
||||||
vmState.regs.edi = 0x0000;
|
|
||||||
|
|
||||||
status_t status = vm86_do_int(&vmState, 0x10);
|
uint32 physicalAddress = sBIOSModule->physical_address(state, vbeModeInfo);
|
||||||
|
bios_regs regs = {};
|
||||||
|
regs.eax = 0x4f01;
|
||||||
|
regs.ecx = mode;
|
||||||
|
regs.es = physicalAddress >> 4;
|
||||||
|
regs.edi = physicalAddress - (regs.es << 4);
|
||||||
|
|
||||||
|
status_t status = sBIOSModule->interrupt(state, 0x10, ®s);
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
dprintf(DEVICE_NAME ": vbe_get_mode_info(%u): vm86 failed\n", mode);
|
dprintf(DEVICE_NAME ": vbe_get_mode_info(%u): BIOS failed: %s\n", mode,
|
||||||
|
strerror(status));
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((vmState.regs.eax & 0xffff) != 0x4f) {
|
if ((regs.eax & 0xffff) != 0x4f) {
|
||||||
dprintf(DEVICE_NAME ": vbe_get_mode_info(): BIOS returned 0x%04lx\n",
|
dprintf(DEVICE_NAME ": vbe_get_mode_info(%u): BIOS returned "
|
||||||
vmState.regs.eax & 0xffff);
|
"0x%04" B_PRIx32 "\n", mode, regs.eax & 0xffff);
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,20 +152,22 @@ vbe_get_mode_info(struct vm86_state& vmState, uint16 mode,
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
vbe_set_mode(struct vm86_state& vmState, uint16 mode)
|
vbe_set_mode(bios_state* state, uint16 mode)
|
||||||
{
|
{
|
||||||
vmState.regs.eax = 0x4f02;
|
bios_regs regs = {};
|
||||||
vmState.regs.ebx = (mode & SET_MODE_MASK) | SET_MODE_LINEAR_BUFFER;
|
regs.eax = 0x4f02;
|
||||||
|
regs.ebx = (mode & SET_MODE_MASK) | SET_MODE_LINEAR_BUFFER;
|
||||||
|
|
||||||
status_t status = vm86_do_int(&vmState, 0x10);
|
status_t status = sBIOSModule->interrupt(state, 0x10, ®s);
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
dprintf(DEVICE_NAME ": vbe_set_mode(%u): vm86 failed\n", mode);
|
dprintf(DEVICE_NAME ": vbe_set_mode(%u): BIOS failed: %s\n", mode,
|
||||||
|
strerror(status));
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((vmState.regs.eax & 0xffff) != 0x4f) {
|
if ((regs.eax & 0xffff) != 0x4f) {
|
||||||
dprintf(DEVICE_NAME ": vbe_set_mode(): BIOS returned 0x%04lx\n",
|
dprintf(DEVICE_NAME ": vbe_set_mode(%u): BIOS returned 0x%04" B_PRIx32
|
||||||
vmState.regs.eax & 0xffff);
|
"\n", mode, regs.eax & 0xffff);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,64 +197,64 @@ vbe_get_dpms_capabilities(uint32& vbeMode, uint32& mode)
|
|||||||
vbeMode = 0;
|
vbeMode = 0;
|
||||||
mode = B_DPMS_ON;
|
mode = B_DPMS_ON;
|
||||||
|
|
||||||
// Prepare vm86 mode environment
|
// Prepare BIOS environment
|
||||||
struct vm86_state vmState;
|
bios_state* state;
|
||||||
status_t status = vm86_prepare(&vmState, 0x20000);
|
status_t status = vbe_call_prepare(&state);
|
||||||
if (status != B_OK) {
|
if (status != B_OK)
|
||||||
dprintf(DEVICE_NAME": vbe_get_dpms_capabilities(): vm86_prepare "
|
|
||||||
"failed: %s\n", strerror(status));
|
|
||||||
return status;
|
return status;
|
||||||
}
|
|
||||||
|
|
||||||
vmState.regs.eax = 0x4f10;
|
bios_regs regs = {};
|
||||||
vmState.regs.ebx = 0;
|
regs.eax = 0x4f10;
|
||||||
vmState.regs.esi = 0;
|
regs.ebx = 0;
|
||||||
vmState.regs.edi = 0;
|
regs.esi = 0;
|
||||||
|
regs.edi = 0;
|
||||||
|
|
||||||
status = vm86_do_int(&vmState, 0x10);
|
status = sBIOSModule->interrupt(state, 0x10, ®s);
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
dprintf(DEVICE_NAME ": vbe_get_dpms_capabilities(): vm86 failed\n");
|
dprintf(DEVICE_NAME ": vbe_get_dpms_capabilities(): BIOS failed: %s\n",
|
||||||
|
strerror(status));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((vmState.regs.eax & 0xffff) != 0x4f) {
|
if ((regs.eax & 0xffff) != 0x4f) {
|
||||||
dprintf(DEVICE_NAME ": vbe_get_dpms_capabilities(): BIOS returned "
|
dprintf(DEVICE_NAME ": vbe_get_dpms_capabilities(): BIOS returned "
|
||||||
"0x%04lx\n", vmState.regs.eax & 0xffff);
|
"0x%04" B_PRIx32 "\n", regs.eax & 0xffff);
|
||||||
status = B_ERROR;
|
status = B_ERROR;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
vbeMode = vmState.regs.ebx >> 8;
|
vbeMode = regs.ebx >> 8;
|
||||||
mode = vbe_to_system_dpms(vbeMode);
|
mode = vbe_to_system_dpms(vbeMode);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
vm86_cleanup(&vmState);
|
vbe_call_finish(state);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
vbe_set_bits_per_gun(vm86_state& vmState, vesa_info& info, uint8 bits)
|
vbe_set_bits_per_gun(bios_state* state, vesa_info& info, uint8 bits)
|
||||||
{
|
{
|
||||||
info.bits_per_gun = 6;
|
info.bits_per_gun = 6;
|
||||||
|
|
||||||
vmState.regs.eax = 0x4f08;
|
bios_regs regs = {};
|
||||||
vmState.regs.ebx = (bits << 8) | 1;
|
regs.eax = 0x4f08;
|
||||||
|
regs.ebx = (bits << 8) | 1;
|
||||||
|
|
||||||
status_t status = vm86_do_int(&vmState, 0x10);
|
status_t status = sBIOSModule->interrupt(state, 0x10, ®s);
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
dprintf(DEVICE_NAME ": vbe_set_bits_per_gun(): vm86 failed: %s\n",
|
dprintf(DEVICE_NAME ": vbe_set_bits_per_gun(): BIOS failed: %s\n",
|
||||||
strerror(status));
|
strerror(status));
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((vmState.regs.eax & 0xffff) != 0x4f) {
|
if ((regs.eax & 0xffff) != 0x4f) {
|
||||||
dprintf(DEVICE_NAME ": vbe_set_bits_per_gun(): BIOS returned 0x%04lx\n",
|
dprintf(DEVICE_NAME ": vbe_set_bits_per_gun(): BIOS returned "
|
||||||
vmState.regs.eax & 0xffff);
|
"0x%04" B_PRIx32 "\n", regs.eax & 0xffff);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
info.bits_per_gun = vmState.regs.ebx >> 8;
|
info.bits_per_gun = regs.ebx >> 8;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,17 +264,14 @@ vbe_set_bits_per_gun(vesa_info& info, uint8 bits)
|
|||||||
{
|
{
|
||||||
info.bits_per_gun = 6;
|
info.bits_per_gun = 6;
|
||||||
|
|
||||||
struct vm86_state vmState;
|
bios_state* state;
|
||||||
status_t status = vm86_prepare(&vmState, 0x20000);
|
status_t status = vbe_call_prepare(&state);
|
||||||
if (status != B_OK) {
|
if (status != B_OK)
|
||||||
dprintf(DEVICE_NAME": vbe_set_bits_per_gun(): vm86_prepare failed: "
|
|
||||||
"%s\n", strerror(status));
|
|
||||||
return status;
|
return status;
|
||||||
}
|
|
||||||
|
|
||||||
status = vbe_set_bits_per_gun(vmState, info, bits);
|
status = vbe_set_bits_per_gun(state, info, bits);
|
||||||
|
|
||||||
vm86_cleanup(&vmState);
|
vbe_call_finish(state);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -386,31 +428,29 @@ vesa_set_display_mode(vesa_info& info, uint32 mode)
|
|||||||
if (mode >= info.shared_info->vesa_mode_count)
|
if (mode >= info.shared_info->vesa_mode_count)
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
// Prepare vm86 mode environment
|
// Prepare BIOS environment
|
||||||
struct vm86_state vmState;
|
bios_state* state;
|
||||||
status_t status = vm86_prepare(&vmState, 0x20000);
|
status_t status = vbe_call_prepare(&state);
|
||||||
if (status != B_OK) {
|
if (status != B_OK)
|
||||||
dprintf(DEVICE_NAME": vesa_set_display_mode(): vm86_prepare failed\n");
|
|
||||||
return status;
|
return status;
|
||||||
}
|
|
||||||
|
|
||||||
// Get mode information
|
// Get mode information
|
||||||
struct vbe_mode_info modeInfo;
|
struct vbe_mode_info modeInfo;
|
||||||
status = vbe_get_mode_info(vmState, info.modes[mode].mode, &modeInfo);
|
status = vbe_get_mode_info(state, info.modes[mode].mode, &modeInfo);
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
dprintf(DEVICE_NAME": vesa_set_display_mode(): cannot get mode info\n");
|
dprintf(DEVICE_NAME": vesa_set_display_mode(): cannot get mode info\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set mode
|
// Set mode
|
||||||
status = vbe_set_mode(vmState, info.modes[mode].mode);
|
status = vbe_set_mode(state, info.modes[mode].mode);
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
dprintf(DEVICE_NAME": vesa_set_display_mode(): cannot set mode\n");
|
dprintf(DEVICE_NAME": vesa_set_display_mode(): cannot set mode\n");
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (info.modes[mode].bits_per_pixel <= 8)
|
if (info.modes[mode].bits_per_pixel <= 8)
|
||||||
vbe_set_bits_per_gun(vmState, info, 8);
|
vbe_set_bits_per_gun(state, info, 8);
|
||||||
|
|
||||||
// Map new frame buffer if necessary
|
// Map new frame buffer if necessary
|
||||||
|
|
||||||
@@ -426,7 +466,7 @@ vesa_set_display_mode(vesa_info& info, uint32 mode)
|
|||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
vm86_cleanup(&vmState);
|
vbe_call_finish(state);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -437,38 +477,36 @@ vesa_get_dpms_mode(vesa_info& info, uint32& mode)
|
|||||||
mode = B_DPMS_ON;
|
mode = B_DPMS_ON;
|
||||||
// we always return a valid mode
|
// we always return a valid mode
|
||||||
|
|
||||||
// Prepare vm86 mode environment
|
// Prepare BIOS environment
|
||||||
struct vm86_state vmState;
|
bios_state* state;
|
||||||
status_t status = vm86_prepare(&vmState, 0x20000);
|
status_t status = vbe_call_prepare(&state);
|
||||||
if (status != B_OK) {
|
if (status != B_OK)
|
||||||
dprintf(DEVICE_NAME": vesa_get_dpms_mode(): vm86_prepare failed: %s\n",
|
|
||||||
strerror(status));
|
|
||||||
return status;
|
return status;
|
||||||
}
|
|
||||||
|
|
||||||
vmState.regs.eax = 0x4f10;
|
bios_regs regs = {};
|
||||||
vmState.regs.ebx = 2;
|
regs.eax = 0x4f10;
|
||||||
vmState.regs.esi = 0;
|
regs.ebx = 2;
|
||||||
vmState.regs.edi = 0;
|
regs.esi = 0;
|
||||||
|
regs.edi = 0;
|
||||||
|
|
||||||
status = vm86_do_int(&vmState, 0x10);
|
status = sBIOSModule->interrupt(state, 0x10, ®s);
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
dprintf(DEVICE_NAME ": vesa_get_dpms_mode(): vm86 failed: %s\n",
|
dprintf(DEVICE_NAME ": vesa_get_dpms_mode(): BIOS failed: %s\n",
|
||||||
strerror(status));
|
strerror(status));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((vmState.regs.eax & 0xffff) != 0x4f) {
|
if ((regs.eax & 0xffff) != 0x4f) {
|
||||||
dprintf(DEVICE_NAME ": vesa_get_dpms_mode(): BIOS returned 0x%04lx\n",
|
dprintf(DEVICE_NAME ": vesa_get_dpms_mode(): BIOS returned "
|
||||||
vmState.regs.eax & 0xffff);
|
"0x%" B_PRIx32 "\n", regs.eax & 0xffff);
|
||||||
status = B_ERROR;
|
status = B_ERROR;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
mode = vbe_to_system_dpms(vmState.regs.ebx >> 8);
|
mode = vbe_to_system_dpms(regs.ebx >> 8);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
vm86_cleanup(&vmState);
|
vbe_call_finish(state);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,36 +527,34 @@ vesa_set_dpms_mode(vesa_info& info, uint32 mode)
|
|||||||
|
|
||||||
vbeMode &= info.vbe_dpms_capabilities;
|
vbeMode &= info.vbe_dpms_capabilities;
|
||||||
|
|
||||||
// Prepare vm86 mode environment
|
// Prepare BIOS environment
|
||||||
struct vm86_state vmState;
|
bios_state* state;
|
||||||
status_t status = vm86_prepare(&vmState, 0x20000);
|
status_t status = vbe_call_prepare(&state);
|
||||||
if (status != B_OK) {
|
if (status != B_OK)
|
||||||
dprintf(DEVICE_NAME": vesa_set_dpms_mode(): vm86_prepare failed: %s\n",
|
|
||||||
strerror(status));
|
|
||||||
return status;
|
return status;
|
||||||
}
|
|
||||||
|
|
||||||
vmState.regs.eax = 0x4f10;
|
bios_regs regs = {};
|
||||||
vmState.regs.ebx = (vbeMode << 8) | 1;
|
regs.eax = 0x4f10;
|
||||||
vmState.regs.esi = 0;
|
regs.ebx = (vbeMode << 8) | 1;
|
||||||
vmState.regs.edi = 0;
|
regs.esi = 0;
|
||||||
|
regs.edi = 0;
|
||||||
|
|
||||||
status = vm86_do_int(&vmState, 0x10);
|
status = sBIOSModule->interrupt(state, 0x10, ®s);
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
dprintf(DEVICE_NAME ": vesa_set_dpms_mode(): vm86 failed: %s\n",
|
dprintf(DEVICE_NAME ": vesa_set_dpms_mode(): BIOS failed: %s\n",
|
||||||
strerror(status));
|
strerror(status));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((vmState.regs.eax & 0xffff) != 0x4f) {
|
if ((regs.eax & 0xffff) != 0x4f) {
|
||||||
dprintf(DEVICE_NAME ": vesa_set_dpms_mode(): BIOS returned 0x%04lx\n",
|
dprintf(DEVICE_NAME ": vesa_set_dpms_mode(): BIOS returned "
|
||||||
vmState.regs.eax & 0xffff);
|
"0x%04" B_PRIx32 "\n", regs.eax & 0xffff);
|
||||||
status = B_ERROR;
|
status = B_ERROR;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
vm86_cleanup(&vmState);
|
vbe_call_finish(state);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -527,26 +563,33 @@ status_t
|
|||||||
vesa_set_indexed_colors(vesa_info& info, uint8 first, uint8* colors,
|
vesa_set_indexed_colors(vesa_info& info, uint8 first, uint8* colors,
|
||||||
uint16 count)
|
uint16 count)
|
||||||
{
|
{
|
||||||
|
bios_regs regs = {};
|
||||||
|
uint32 shift, physicalAddress;
|
||||||
|
|
||||||
if (first + count > 256)
|
if (first + count > 256)
|
||||||
count = 256 - first;
|
count = 256 - first;
|
||||||
|
|
||||||
// Prepare vm86 mode environment
|
// Prepare BIOS environment
|
||||||
struct vm86_state vmState;
|
bios_state* state;
|
||||||
status_t status = vm86_prepare(&vmState, 0x20000);
|
status_t status = vbe_call_prepare(&state);
|
||||||
if (status != B_OK) {
|
if (status != B_OK)
|
||||||
dprintf(DEVICE_NAME": vesa_set_indexed_colors(): vm86_prepare failed: "
|
|
||||||
"%s\n", strerror(status));
|
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
|
uint8* palette = (uint8*)sBIOSModule->allocate_mem(state, 256 * 4);
|
||||||
|
if (palette == NULL) {
|
||||||
|
status = B_NO_MEMORY;
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8* palette = (uint8*)0x1000;
|
shift = 8 - info.bits_per_gun;
|
||||||
uint32 shift = 8 - info.bits_per_gun;
|
|
||||||
|
|
||||||
// convert colors to VESA palette
|
// convert colors to VESA palette
|
||||||
for (int32 i = first; i < count; i++) {
|
for (int32 i = first; i < count; i++) {
|
||||||
uint8 color[3];
|
uint8 color[3];
|
||||||
if (user_memcpy(color, &colors[i * 3], 3) < B_OK)
|
if (user_memcpy(color, &colors[i * 3], 3) < B_OK) {
|
||||||
return B_BAD_ADDRESS;
|
status = B_BAD_ADDRESS;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
// order is BGR-
|
// order is BGR-
|
||||||
palette[i * 4 + 0] = color[2] >> shift;
|
palette[i * 4 + 0] = color[2] >> shift;
|
||||||
@@ -556,27 +599,28 @@ vesa_set_indexed_colors(vesa_info& info, uint8 first, uint8* colors,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// set palette
|
// set palette
|
||||||
vmState.regs.eax = 0x4f09;
|
physicalAddress = sBIOSModule->physical_address(state, palette);
|
||||||
vmState.regs.ebx = 0;
|
regs.eax = 0x4f09;
|
||||||
vmState.regs.ecx = count;
|
regs.ebx = 0;
|
||||||
vmState.regs.edx = first;
|
regs.ecx = count;
|
||||||
vmState.regs.es = 0x1000 >> 4;
|
regs.edx = first;
|
||||||
vmState.regs.edi = 0x0000;
|
regs.es = physicalAddress >> 4;
|
||||||
|
regs.edi = physicalAddress - (regs.es << 4);
|
||||||
|
|
||||||
status = vm86_do_int(&vmState, 0x10);
|
status = sBIOSModule->interrupt(state, 0x10, ®s);
|
||||||
if (status != B_OK) {
|
if (status != B_OK) {
|
||||||
dprintf(DEVICE_NAME ": vesa_set_indexed_colors(): vm86 failed: %s\n",
|
dprintf(DEVICE_NAME ": vesa_set_indexed_colors(): BIOS failed: %s\n",
|
||||||
strerror(status));
|
strerror(status));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((vmState.regs.eax & 0xffff) != 0x4f) {
|
if ((regs.eax & 0xffff) != 0x4f) {
|
||||||
dprintf(DEVICE_NAME ": vesa_set_indexed_colors(): BIOS returned "
|
dprintf(DEVICE_NAME ": vesa_set_indexed_colors(): BIOS returned "
|
||||||
"0x%04lx\n", vmState.regs.eax & 0xffff);
|
"0x%04" B_PRIx32 "\n", regs.eax & 0xffff);
|
||||||
status = B_ERROR;
|
status = B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
out:
|
out:
|
||||||
vm86_cleanup(&vmState);
|
vbe_call_finish(state);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user