Compare commits

...

1 Commits

Author SHA1 Message Date
K. Lange
508b97198d boot: Partial attempt at video mode setting in BIOS loader 2021-10-19 20:29:44 +09:00
4 changed files with 204 additions and 42 deletions

View File

@ -59,7 +59,6 @@ unrealmode:
jmp _oh_no
can_long:
/* Spot check memory */
movl $0x12345678, %eax
movl $0x5000000, %ebx
@ -105,6 +104,71 @@ boot_from_cd:
call do_e820
jc hang
/* Skip video mode set */
jmp vbe_done
/* Get video mode info */
mov $0, %ax
mov %ax, %es
mov $vbe_cont_info, %di
mov $0x4F00, %ax
int $0x10
/* Now let's look at the video modes */
mov (vbe_cont_info_mode_seg), %ax
mov %ax, %fs
mov (vbe_cont_info_mode_off), %ax
mov %ax, %si
mov $vbe_info, %di
vbe_loop:
mov %fs:(%si), %cx
mov $0xFFFF, %dx
cmp %cx, %dx
je vbe_out_of_modes
/* Check the mode */
mov $0x4F01, %ax
int $0x10
/* Is it 1024? */
mov $1024, %dx
movw (vbe_info_width), %ax
cmp %ax, %dx
jne vbe_next
/* Is it 768? */
mov $768, %dx
movw (vbe_info_height), %ax
cmp %ax, %dx
jne vbe_next
/* Is it 32 bpp? */
mov $32, %dl
movb (vbe_info_bpp), %al
cmp %al, %dl
jne vbe_next
mov %cx, %bx
mov $0x4F02, %ax
int $0x10
jmp vbe_done
vbe_next:
add $2, %si
mov $0, %ax
mov %ax, %es
mov $vbe_info, %di
jmp vbe_loop
vbe_out_of_modes:
movw $0x0, (vbe_info_width)
vbe_done:
/* Actually switch to protected mode. */
mov %cr0, %eax
or $1, %eax
@ -359,14 +423,66 @@ drive_params:
drive_params_bps:
.word 0 /* bytes per sector */
.global vbe_info
vbe_info:
.word 0 /* attributes */
.word 0 /* old shit (window a/b) */
.word 0 /* Granulatory of banks, don't care. */
.word 0 /* Window size, don't care. */
.long 0 /* Segments... */
.long 0 /* old bank switching thing */
.global vbe_info_pitch
vbe_info_pitch:
.word 0 /* PITCH */
.global vbe_info_width
vbe_info_width:
.word 0 /* WIDTH */
.global vbe_info_height
vbe_info_height:
.word 0 /* HEIGHT */
.word 0 /* w, y */
.byte 0 /* planes */
.global vbe_info_bpp
vbe_info_bpp:
.byte 0 /* bits per pixel */
.byte 0 /* banks */
.byte 0 /* Memory model */
.byte 0 /* bank size */
.byte 0 /* pages */
.byte 0 /* reserved */
.byte 0 /* RED mask */
.byte 0 /* RED offset */
.byte 0 /* GREEN mask */
.byte 0 /* GREEN offset */
.byte 0 /* BLUE maask */
.byte 0 /* BLUE offset */
.byte 0 /* ALPHA mask */
.byte 0 /* ALPHA offset */
.byte 0 /* Color attributes */
.global vbe_info_fbaddr
vbe_info_fbaddr:
.long 0 /* Framebuffer address */
.long 0 /* Extra memory offset */
.word 0 /* Extra memory size */
.zero 206 /* Other crap */
vbe_cont_info:
.ascii "VBE"
.word 0
.long 0
.long 0 /* caps */
vbe_cont_info_mode_off:
.word 0 /* MODES */
vbe_cont_info_mode_seg:
.word 0
.zero 494
str_Bad:
.asciz "The boot disk does not seem to be a CD."
str_Need_long:
.asciz "ToaruOS 2.0 requires a 64-bit processor."
str_More_mem:
.asciz "ToaruOS 2.0 needs at least 128MiB of RAM, and 1GiB is recommended."
str_Out_of_modes:
.asciz "Out of display modes"
.global disk_space
disk_space:

View File

@ -657,6 +657,19 @@ done:
multiboot_header.cmdline = (uintptr_t)cmdline;
extern uint32_t *vbe_info_fbaddr;
extern uint16_t vbe_info_pitch;
extern uint16_t vbe_info_width;
extern uint16_t vbe_info_height;
extern uint8_t vbe_info_bpp;
if (vbe_info_width) {
multiboot_header.framebuffer_addr = (uint32_t)vbe_info_fbaddr;
multiboot_header.framebuffer_pitch = vbe_info_pitch;
multiboot_header.framebuffer_width = vbe_info_width;
multiboot_header.framebuffer_height = vbe_info_height;
multiboot_header.framebuffer_bpp = vbe_info_bpp;
}
print("Loading kernel from 0x"); print_hex((uint32_t)kernel_load_start); print("... ");
if (!load_kernel()) {
print_("Failed to load kernel.\n");

View File

@ -121,5 +121,4 @@ try_again:
}
#endif

View File

@ -5,17 +5,23 @@ int txt_debug = 0;
#ifdef EFI_PLATFORM
#include <efi.h>
extern EFI_SYSTEM_TABLE *ST;
#else
#include <stdint.h>
#endif
#include "../apps/terminal-font.h"
#define char_height LARGE_FONT_CELL_HEIGHT
#define char_width LARGE_FONT_CELL_WIDTH
EFI_GRAPHICS_OUTPUT_PROTOCOL * GOP;
static int offset_x = 0;
static int offset_y = 0;
static void write_char(int x, int y, int val, int attr);
#ifdef EFI_PLATFORM
EFI_GRAPHICS_OUTPUT_PROTOCOL * GOP;
static EFI_GUID efi_graphics_output_protocol_guid =
{0x9042a9de,0x23dc,0x4a38, {0x96,0xfb,0x7a,0xde,0xd0,0x80,0x51,0x6a}};
@ -46,6 +52,69 @@ no_graphics:
return 1;
}
static void set_point(int x, int y, uint32_t color) {
((uint32_t *)GOP->Mode->FrameBufferBase)[(x + offset_x) + (y + offset_y) * GOP->Mode->Info->PixelsPerScanLine] = color;
}
void clear_() {
x = 0;
y = 0;
memset((void*)GOP->Mode->FrameBufferBase,0,GOP->Mode->FrameBufferSize);
}
static void placech(unsigned char c, int x, int y, int attr) {
write_char(x * char_width, y * char_height, c, attr);
}
#else
extern uint32_t *vbe_info_fbaddr;
extern uint16_t vbe_info_pitch;
extern uint16_t vbe_info_width;
extern uint16_t vbe_info_height;
extern uint8_t vbe_info_bpp;
void init_graphics(void) {
offset_x = (vbe_info_width - 80 * char_width) / 2;
offset_y = (vbe_info_height - 24 * char_height) / 2;
}
static void set_point(int x, int y, uint32_t color) {
if (vbe_info_bpp == 24) {
*((uint8_t*)vbe_info_fbaddr + (x + offset_x) * 3 + (y + offset_y) * (vbe_info_pitch)) = (color >> 0) & 0xFF;
*((uint8_t*)vbe_info_fbaddr + (x + offset_x) * 3 + (y + offset_y) * (vbe_info_pitch) + 1) = (color >> 8) & 0xFF;
*((uint8_t*)vbe_info_fbaddr + (x + offset_x) * 3 + (y + offset_y) * (vbe_info_pitch) + 2) = (color >> 16) & 0xFF;
} else if (vbe_info_bpp == 32) {
vbe_info_fbaddr[(x + offset_x) + (y + offset_y) * (vbe_info_pitch / 4)] = color;
}
}
static unsigned short * textmemptr = (unsigned short *)0xB8000;
static void placech_vga(unsigned char c, int x, int y, int attr) {
unsigned short *where;
unsigned att = attr << 8;
where = textmemptr + (y * 80 + x);
*where = c | att;
}
static void placech(unsigned char c, int x, int y, int attr) {
vbe_info_width ? write_char(x * char_width, y * char_height, c, attr) : placech_vga(c,x,y,attr);
}
void clear_() {
x = 0;
y = 0;
if (vbe_info_width) {
memset(vbe_info_fbaddr, 0, vbe_info_pitch * vbe_info_height);
} else {
for (int y = 0; y < 24; ++y) {
for (int x = 0; x < 80; ++x) {
placech_vga(' ', x, y, 0x00);
}
}
}
}
#endif
static uint32_t term_colors[] = {
0xFF000000,
0xFFCC0000,
@ -71,10 +140,6 @@ char vga_to_ansi[] = {
8,12,10,14, 9,13,11,15
};
static void set_point(int x, int y, uint32_t color) {
((uint32_t *)GOP->Mode->FrameBufferBase)[(x + offset_x) + (y + offset_y) * GOP->Mode->Info->PixelsPerScanLine] = color;
}
static void write_char(int x, int y, int val, int attr) {
if (val > 128) {
@ -96,37 +161,6 @@ static void write_char(int x, int y, int val, int attr) {
}
}
static void placech(unsigned char c, int x, int y, int attr) {
write_char(x * char_width, y * char_height, c, attr);
}
void clear_() {
x = 0;
y = 0;
memset((void*)GOP->Mode->FrameBufferBase,0,GOP->Mode->FrameBufferSize);
}
#else
static unsigned short * textmemptr = (unsigned short *)0xB8000;
static void placech(unsigned char c, int x, int y, int attr) {
unsigned short *where;
unsigned att = attr << 8;
where = textmemptr + (y * 80 + x);
*where = c | att;
}
void clear_() {
x = 0;
y = 0;
for (int y = 0; y < 24; ++y) {
for (int x = 0; x < 80; ++x) {
placech(' ', x, y, 0x00);
}
}
}
#endif
int x = 0;
int y = 0;