diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/kernel/graphics/vesa.c | 116 | ||||
-rw-r--r-- | src/kernel/graphics/vesa.h | 17 | ||||
-rw-r--r-- | src/kernel/kernel.c | 4 |
3 files changed, 66 insertions, 71 deletions
diff --git a/src/kernel/graphics/vesa.c b/src/kernel/graphics/vesa.c index b6aca1a..8c85d49 100644 --- a/src/kernel/graphics/vesa.c +++ b/src/kernel/graphics/vesa.c @@ -30,116 +30,100 @@ struct edid_data get_edid() { return *edid; } -struct vbe_mode_info *vbe_set_mode(unsigned short mode) { +void vbe_set_mode(unsigned short mode) { serial_write("Setting VBE mode!\n"); serial_write_hex(mode); vesa_available = 0; regs16_t regs; regs.ax = 0x4F02; - regs.bx = mode | (1 << 14); + regs.bx |= 0b0100000000000000; + regs.bx &= 0b0111111111111111; disable_paging(); int32(0x10, ®s); enable_paging(); - - if (regs.ax == 0x004F) { - struct vbe_mode_info *vbe_info = (struct vbe_mode_info *) 0x7E00; - regs16_t regs2; - regs2.ax = 0x4F01; - regs2.cx = mode; - regs2.es = 0; - regs2.di = 0x7E00; - disable_paging(); - int32(0x10, ®s2); - enable_paging(); - - if (regs2.ax != 0x004F) { - switch_to_vga(); - return ((void *) 0); - } - - struct vbe_mode_info *vbe_info_final = (struct vbe_mode_info *) kmalloc(sizeof(vbe_info)); - memory_copy(vbe_info_final, vbe_info, sizeof(vbe_info)); - - vbe_width = vbe_info_final->width; - vbe_height = vbe_info_final->height; - vbe_bpp = vbe_info_final->bpp / 8; - vbe_pitch = vbe_info_final->pitch; - fb = (char *) vbe_info_final->framebuffer; - - /*for (int i = 0; i < vbe_width * vbe_height * vbe_bpp; i++) { - fb[i] = 100; - fb[i + 1] = 100; - fb[i + 2] = 100; - }*/ - - vesa_available = 1; - - return vbe_info; - } else { - switch_to_vga(); - return ((void *) 0); - } } uint16_t *vbe_get_modes() { vesa_available = 0; - struct vbe_info *info = (struct vbe_info *) 0x7E00; - - memory_copy(info->signature, "VBE2", 4); + char *info_address = (char *) 0x7E00; + strcpy(info_address, "VBE2"); + for (int i = 4; i < 512; i++) *(info_address + i) = 0; regs16_t regs; regs.ax = 0x4F00; regs.es = 0; regs.di = 0x7E00; disable_paging(); - int32(0x10, ®s); + int32(0x10, ®s); // CRASH enable_paging(); + struct vbe_info *info = (struct vbe_info *) info_address; + if (regs.ax != 0x004F || strcmp(info->signature, "VESA") != 0) { switch_to_vga(); return ((void *) 0); } + // Get number of modes uint16_t *mode_ptr = get_ptr(info->video_modes); int number_modes = 1; for (uint16_t *p = mode_ptr; *p != 0xFFFF; p++) number_modes++; uint16_t *video_modes = (uint16_t *) kmalloc(sizeof(uint16_t) * number_modes); - for (int i = 0; i < number_modes; i++) video_modes[i] = mode_ptr[i]; + for (int i = 0; i < number_modes; i++) + video_modes[i] = mode_ptr[i]; return video_modes; } +struct vbe_mode_info *vbe_get_mode_info(uint16_t mode) { + regs16_t regs; + regs.ax = 0x4F01; + regs.cx = mode; + regs.es = 0; + regs.di = 0x7E00; + disable_paging(); + int32(0x10, ®s); + enable_paging(); + + struct vbe_mode_info_all *mode_info = (struct vbe_mode_info_all *) 0x7E00; + struct vbe_mode_info *mode_info_final = (struct vbe_mode_info *) kmalloc(sizeof(struct vbe_mode_info)); + mode_info_final->attributes = mode_info->attributes; + mode_info_final->width = mode_info->width; + mode_info_final->height = mode_info->height; + mode_info_final->bpp = mode_info->bpp; + mode_info_final->pitch = mode_info->pitch; + mode_info_final->framebuffer = mode_info->framebuffer; + + return mode_info_final; +} + void set_optimal_resolution() { uint16_t *video_modes = vbe_get_modes(); - uint16_t mode; uint16_t highest = 0x11B; uint16_t highest_width = 0; - while ((mode = *video_modes++) != 0xFFFF) { - mode &= 0x1FF; - regs16_t regs2; - regs2.ax = 0x4F01; - regs2.cx = mode; - regs2.es = 0; - regs2.di = 0x7E00; - disable_paging(); - int32(0x10, ®s2); - enable_paging(); - - struct vbe_mode_info *mode_info = (struct vbe_mode_info *) 0x7E00; + for (uint16_t *mode = video_modes; *mode != 0xFFFF; mode++) { + struct vbe_mode_info *mode_info = vbe_get_mode_info(*mode); - if ((mode_info->attributes & 0x90) != 0x90) continue; - - if (mode_info->width >= highest_width && + if (mode_info->width >= highest_width /*&& (float) mode_info->width / (float) mode_info->height < 2.0 && - (mode_info->attributes & 0x1) != 0x1 && - (mode_info->attributes & 0x90) != 0x90 && - mode_info->memory_model != 6) { - highest = mode; + (mode_info->attributes & 0x80) != 0*/) { + highest = *mode; highest_width = mode_info->width; + kfree(mode_info); } + kfree(mode_info); } + kfree(video_modes); + + struct vbe_mode_info *highest_info = vbe_get_mode_info(highest); + vbe_width = highest_info->width; + vbe_height = highest_info->height; + vbe_bpp = highest_info->bpp / 8; + vbe_pitch = highest_info->pitch; + fb = (char *) highest_info->framebuffer; + serial_write("Reached set mode!\n"); vbe_set_mode(highest); } diff --git a/src/kernel/graphics/vesa.h b/src/kernel/graphics/vesa.h index 9dbd96d..d24e2d2 100644 --- a/src/kernel/graphics/vesa.h +++ b/src/kernel/graphics/vesa.h @@ -56,7 +56,7 @@ struct vbe_info { * The CPUs response to the 0x4F01 call * Used to get information about a specific video mode code */ -struct vbe_mode_info { +struct vbe_mode_info_all { uint16_t attributes; uint8_t window_a; uint8_t window_b; @@ -95,6 +95,18 @@ struct vbe_mode_info { } __attribute__ ((packed)); /** + * The actual vbe mode info structure + */ +struct vbe_mode_info { + uint16_t attributes; + uint16_t pitch; + uint16_t width; + uint16_t height; + uint8_t bpp; + uint32_t framebuffer; +} __attribute__ ((packed)); + +/** * Get the monitors EDID information * TODO: Add EDID/VBE resolution mode verification * @return The EDID information @@ -105,9 +117,8 @@ struct edid_data get_edid(); * Set the video mode to a specified resolution using * a video mode code * @param mode The requested video mode code from 0x4F00 call - * @return A structure with information about the video mode */ -struct vbe_mode_info *vbe_set_mode(unsigned short mode); +void vbe_set_mode(unsigned short mode); /** * Find the highest resolution using 0x4F00 and call diff --git a/src/kernel/kernel.c b/src/kernel/kernel.c index d96ea00..cdad8dd 100644 --- a/src/kernel/kernel.c +++ b/src/kernel/kernel.c @@ -11,18 +11,18 @@ void init() { timer_install(); gdt_install(); + initialise_paging(); idt_install(); isrs_install(); irq_install(); - initialise_paging(); init_serial(); + set_optimal_resolution(); // terminal_initialize(); // TODO: Replace VGA functions with VESA asm volatile ("sti"); } void kernel_main(void) { init(); - set_optimal_resolution(); // vesa_draw_string("This is a testing text!"); |