X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=bootcensus;a=blobdiff_plain;f=src%2Fkmain.c;h=99104a2880d0e0a34abf3dc9ad67d643c2108234;hp=af7bc6500fb11598d468ffddd0d78013f96e2588;hb=10843571c724084c68d33d0438167d400cc8de2e;hpb=97356e29f73e12f0856fde92a48e86c73bef387c diff --git a/src/kmain.c b/src/kmain.c index af7bc65..99104a2 100644 --- a/src/kmain.c +++ b/src/kmain.c @@ -16,47 +16,137 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ #include +#include #include #include "segm.h" #include "intr.h" +#include "mem.h" #include "keyb.h" +#include "psaux.h" #include "timer.h" #include "contty.h" +#include "video.h" +#include "vbe.h" +#include "audio.h" +#include "panic.h" +#include "census/census.h" + +static int video_init(void); +static int modecmp(const void *a, const void *b); + +static struct video_mode vmode; +static void *fbptr, *backbuf; +static int fbsize; -void set_mode13h(void); -void logohack(void); void pcboot_main(void) { init_segm(); init_intr(); - kb_init(); + con_init(); + kb_init(); + init_psaux(); + + init_mem(); /* initialize the timer */ init_timer(); + audio_init(); + enable_intr(); printf("PCBoot kernel initialized\n"); + if(video_init() == -1) { + panic("Failed to find suitable video mode"); + } + fbsize = vmode.width * vmode.height * vmode.bpp / 8; + if(!(backbuf = malloc(fbsize))) { + panic("Failed to allocate back buffer"); + } + init_census(backbuf, vmode.width, vmode.height); + for(;;) { - int c; + draw_census(); - halt_cpu(); - while((c = kb_getkey()) >= 0) { - if(c >= KB_F1 && c <= KB_F12) { - set_mode13h(); - logohack(); - } - if(isprint(c)) { - printf("key: %d '%c' \n", c, (char)c); - } else { - printf("key: %d \n", c); + wait_vsync(); + memcpy(fbptr, backbuf, fbsize); + } +} + +static int video_init(void) +{ + struct vbe_edid edid; + struct video_mode vinf, *vmodes; + int i, xres, yres, nmodes, mode_idx = -1; + const char *vendor; + + if(mode_idx == -1 && (vendor = get_video_vendor()) && strstr(vendor, "SeaBIOS")) { + mode_idx = find_video_mode_idx(800, 600, 32); + } + + if(mode_idx == -1 && vbe_get_edid(&edid) == 0 && edid_preferred_resolution(&edid, &xres, &yres) == 0) { + printf("EDID: preferred resolution: %dx%d\n", xres, yres); + mode_idx = find_video_mode_idx(xres, yres, 0); + } + + nmodes = video_mode_count(); + if(!(vmodes = malloc(nmodes * sizeof *vmodes))) { + printf("failed to allocate video modes array (%d modes)\n", nmodes); + return -1; + } + + for(i=0; i= 0) { + if(!(fbptr = set_video_mode(vmodes[mode_idx].mode))) { + printf("failed to set video mode: %x (%dx%d %dbpp)\n", mode_idx, + vmodes[mode_idx].width, vmodes[mode_idx].height, vmodes[mode_idx].bpp); + mode_idx = -1; + } else { + vmode = vmodes[mode_idx]; + printf("video mode: %x (%dx%d %dbpp)\n", vmode.mode, vmode.width, + vmode.height, vmode.bpp); + } + } + + if(mode_idx == -1) { + qsort(vmodes, nmodes, sizeof *vmodes, modecmp); + + for(i=0; i= nmodes) { + printf("failed to find a suitable video mode\n"); + return -1; } } + free(vmodes); + + return 0; +} + + + +static int modecmp(const void *a, const void *b) +{ + const struct video_mode *ma = a; + const struct video_mode *mb = b; + unsigned long aval = ma->width | (ma->height << 16); + unsigned long bval = mb->width | (mb->height << 16); + + if(aval != bval) { + return bval - aval; + } + return mb->bpp - ma->bpp; }