X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?a=blobdiff_plain;ds=inline;f=src%2Fkmain.c;h=99104a2880d0e0a34abf3dc9ad67d643c2108234;hb=10843571c724084c68d33d0438167d400cc8de2e;hp=3c256a65af8960586b0b14262b820c8479df21b8;hpb=5e8cc93aaf1173688852acaa0825698c2dc0cb3f;p=bootcensus
diff --git a/src/kmain.c b/src/kmain.c
index 3c256a6..99104a2 100644
--- a/src/kmain.c
+++ b/src/kmain.c
@@ -26,11 +26,18 @@ along with this program. If not, see .
#include "timer.h"
#include "contty.h"
#include "video.h"
-#include "pci.h"
-#include "vbetest.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 logohack(void);
void pcboot_main(void)
{
@@ -43,39 +50,103 @@ void pcboot_main(void)
init_mem();
- init_pci();
-
/* 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;
-
- halt_cpu();
- while((c = kb_getkey()) >= 0) {
- switch(c) {
- case KB_F1:
- set_vga_mode(0x13);
- logohack();
- set_vga_mode(3);
- break;
+ draw_census();
- case KB_F2:
- vbetest();
+ 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;
}