mirror of
https://github.com/wichtounet/thor-os.git
synced 2025-09-08 11:58:36 -04:00
Get a VESA mode
This commit is contained in:
parent
f5ff78ea08
commit
e1acb58c12
2
Makefile
2
Makefile
@ -31,7 +31,7 @@ thor.flp: bootloader/stage1.bin bootloader/stage2.bin kernel/kernel.bin programs
|
||||
sudo /sbin/losetup -d /dev/loop0
|
||||
|
||||
qemu: default
|
||||
qemu-kvm -cpu host -hda hdd.img
|
||||
qemu-kvm -cpu host -vga std -hda hdd.img
|
||||
|
||||
bochs: default
|
||||
bochs -qf bochsrc.txt
|
||||
|
@ -98,6 +98,8 @@ static_assert(sizeof(mode_info_block_t) == 256, "The size of a mode info block i
|
||||
|
||||
extern vbe_info_block_t vbe_info_block;
|
||||
extern bool vesa_enabled;
|
||||
extern mode_info_block_t mode_info_block;
|
||||
extern uint16_t modes;
|
||||
|
||||
} //end of vesa namespace
|
||||
|
||||
|
@ -37,7 +37,9 @@ int16_t e820::bios_e820_entry_count = 0;
|
||||
#include "vesa.hpp"
|
||||
|
||||
vesa::vbe_info_block_t vesa::vbe_info_block;
|
||||
vesa::mode_info_block_t vesa::mode_info_block;
|
||||
bool vesa::vesa_enabled = false;
|
||||
uint16_t vesa::modes = 0;
|
||||
|
||||
namespace {
|
||||
|
||||
@ -64,6 +66,10 @@ void set_es(uint16_t seg){
|
||||
asm volatile("mov es, %0" : : "rm" (seg));
|
||||
}
|
||||
|
||||
void set_gs(uint16_t seg){
|
||||
asm volatile("mov gs, %0" : : "rm" (seg));
|
||||
}
|
||||
|
||||
void reset_segments(){
|
||||
set_ds(0);
|
||||
set_es(0);
|
||||
@ -106,16 +112,104 @@ void detect_memory(){
|
||||
e820::bios_e820_entry_count = detect_memory_e820();
|
||||
}
|
||||
|
||||
uint16_t read_mode(uint16_t i){
|
||||
uint16_t mode;
|
||||
asm volatile("mov gs, %0; mov si, %1; add si, %3; mov %0, gs:[si]"
|
||||
: "=a" (mode)
|
||||
: "rm" (vesa::vbe_info_block.video_modes_ptr[0]),
|
||||
"rm" (vesa::vbe_info_block.video_modes_ptr[1]),
|
||||
"rm" (i));
|
||||
return mode;
|
||||
}
|
||||
|
||||
uint16_t abs_diff(uint16_t a, uint16_t b){
|
||||
if(a > b){
|
||||
return a - b;
|
||||
} else {
|
||||
return b - a;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr bool bit_set(const T& value, uint8_t bit){
|
||||
return value & (1 << bit);
|
||||
}
|
||||
|
||||
void setup_vesa(){
|
||||
vesa::vbe_info_block.signature[0] = 'V';
|
||||
vesa::vbe_info_block.signature[1] = 'B';
|
||||
vesa::vbe_info_block.signature[2] = 'E';
|
||||
vesa::vbe_info_block.signature[3] = '2';
|
||||
|
||||
uint16_t return_code;
|
||||
asm volatile ("int 0x10"
|
||||
: "=a"(return_code)
|
||||
: "a"(0x4F00), "D"(&vesa::vbe_info_block));
|
||||
: "a"(0x4F00), "D"(&vesa::vbe_info_block)
|
||||
: "memory");
|
||||
|
||||
if(return_code == 0x4F){
|
||||
vesa::vesa_enabled = true;
|
||||
uint16_t wanted_x = 1024;
|
||||
uint16_t wanted_y = 768;
|
||||
|
||||
uint16_t best_mode = 0;
|
||||
uint16_t best_size_diff = 65535;
|
||||
|
||||
bool one = false;
|
||||
|
||||
for(uint16_t mode = 0; mode != 0xFFFF; ++mode){
|
||||
asm volatile ("int 0x10"
|
||||
: "=a"(return_code)
|
||||
: "a"(0x4F01), "c"(mode), "D"(&vesa::mode_info_block)
|
||||
: "memory");
|
||||
|
||||
//Make sure the mode is supported by get mode info function
|
||||
if(return_code != 0x4F){
|
||||
continue;
|
||||
}
|
||||
|
||||
//Check that the mode support Linear Frame Buffer
|
||||
if(!bit_set(vesa::mode_info_block.mode_attributes, 7)){
|
||||
continue;
|
||||
}
|
||||
|
||||
//Make sure it is a packed pixel or direct color model
|
||||
if(vesa::mode_info_block.memory_model != 4 && vesa::mode_info_block.memory_model != 6){
|
||||
continue;
|
||||
}
|
||||
|
||||
one = true;
|
||||
|
||||
auto x_res = vesa::mode_info_block.width;
|
||||
auto y_res = vesa::mode_info_block.height;
|
||||
|
||||
auto size_diff = abs_diff(x_res, wanted_x) + abs_diff(y_res, wanted_y);
|
||||
|
||||
if(size_diff < best_size_diff){
|
||||
best_mode = mode;
|
||||
best_size_diff = size_diff;
|
||||
}
|
||||
}
|
||||
|
||||
if(!one || best_mode == 0xFFFF){
|
||||
vesa::vesa_enabled = false;
|
||||
} else {
|
||||
asm volatile ("int 0x10"
|
||||
: "=a"(return_code)
|
||||
: "a"(0x4F01), "c"(best_mode), "D"(&vesa::mode_info_block)
|
||||
: "memory");
|
||||
|
||||
if(return_code == 0x4F){
|
||||
vesa::vesa_enabled = true;
|
||||
//asm volatile ("int 0x10"
|
||||
// : "=a"(return_code)
|
||||
// : "a"(0x4F02), "b"(best_mode));
|
||||
} else {
|
||||
vesa::vesa_enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
set_gs(0);
|
||||
}
|
||||
|
||||
void disable_interrupts(){
|
||||
@ -259,15 +353,15 @@ void __attribute__ ((noreturn)) rm_main(){
|
||||
//Analyze memory
|
||||
detect_memory();
|
||||
|
||||
//Make sure a20 gate is enabled
|
||||
enable_a20_gate();
|
||||
|
||||
//Enable VESA
|
||||
setup_vesa();
|
||||
|
||||
//Disable interrupts
|
||||
disable_interrupts();
|
||||
|
||||
//Make sure a20 gate is enabled
|
||||
enable_a20_gate();
|
||||
|
||||
//Setup an IDT with null limits to prevents interrupts from being used in
|
||||
//protected mode
|
||||
setup_idt();
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "rtc.hpp"
|
||||
#include "elf.hpp"
|
||||
#include "paging.hpp"
|
||||
#include "vesa.hpp"
|
||||
|
||||
//Commands
|
||||
#include "sysinfo.hpp"
|
||||
@ -67,13 +68,14 @@ void touch_command(const std::vector<std::string>& params);
|
||||
void readelf_command(const std::vector<std::string>& params);
|
||||
void exec_command(const std::vector<std::string>& params);
|
||||
void shutdown_command(const std::vector<std::string>& params);
|
||||
void vesainfo_command(const std::vector<std::string>& params);
|
||||
|
||||
struct command_definition {
|
||||
const char* name;
|
||||
void (*function)(const std::vector<std::string>&);
|
||||
};
|
||||
|
||||
command_definition commands[26] = {
|
||||
command_definition commands[27] = {
|
||||
{"reboot", reboot_command},
|
||||
{"help", help_command},
|
||||
{"uptime", uptime_command},
|
||||
@ -100,6 +102,7 @@ command_definition commands[26] = {
|
||||
{"readelf", readelf_command},
|
||||
{"exec", exec_command},
|
||||
{"shutdown", shutdown_command},
|
||||
{"vesainfo", vesainfo_command},
|
||||
};
|
||||
|
||||
std::string current_input(16);
|
||||
@ -841,6 +844,19 @@ void exec_command(const std::vector<std::string>& params){
|
||||
}
|
||||
}
|
||||
|
||||
void vesainfo_command(const std::vector<std::string>&){
|
||||
k_print_line(vesa::modes);
|
||||
k_printf("x=%u : y=%u \n", (size_t) vesa::mode_info_block.width, (size_t) vesa::mode_info_block.height);
|
||||
k_print_line(vesa::mode_info_block.mode_attributes);
|
||||
if(vesa::vesa_enabled){
|
||||
k_print_line("VESA Enabled");
|
||||
|
||||
k_printf("x=%u : y=%u \n", (size_t) vesa::mode_info_block.width, (size_t) vesa::mode_info_block.height);
|
||||
} else {
|
||||
k_print_line("VESA Disabled");
|
||||
}
|
||||
}
|
||||
|
||||
void shutdown_command(const std::vector<std::string>&){
|
||||
if(!acpi::init()){
|
||||
k_print_line("Unable to init ACPI");
|
||||
|
Loading…
x
Reference in New Issue
Block a user