2 pcboot - bootable PC demo/game kernel
3 Copyright (C) 2018 John Tsiombikas <nuclear@member.fsf.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY, without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>.
32 #include "census/census.h"
34 static int video_init(void);
35 static int modecmp(const void *a, const void *b);
37 static struct video_mode vmode;
38 static void *fbptr, *backbuf;
42 void pcboot_main(void)
53 /* initialize the timer */
60 printf("PCBoot kernel initialized\n");
62 if(video_init() == -1) {
63 panic("Failed to find suitable video mode");
65 fbsize = vmode.width * vmode.height * vmode.bpp / 8;
66 if(!(backbuf = malloc(fbsize))) {
67 panic("Failed to allocate back buffer");
69 init_census(backbuf, vmode.width, vmode.height);
75 memcpy(fbptr, backbuf, fbsize);
79 static int video_init(void)
82 struct video_mode vinf, *vmodes;
83 int i, xres, yres, nmodes, mode_idx = -1;
86 if(mode_idx == -1 && (vendor = get_video_vendor()) && strstr(vendor, "SeaBIOS")) {
87 mode_idx = find_video_mode_idx(800, 600, 32);
90 if(mode_idx == -1 && vbe_get_edid(&edid) == 0 && edid_preferred_resolution(&edid, &xres, &yres) == 0) {
91 printf("EDID: preferred resolution: %dx%d\n", xres, yres);
92 mode_idx = find_video_mode_idx(xres, yres, 0);
95 nmodes = video_mode_count();
96 if(!(vmodes = malloc(nmodes * sizeof *vmodes))) {
97 printf("failed to allocate video modes array (%d modes)\n", nmodes);
101 for(i=0; i<nmodes; i++) {
102 video_mode_info(i, &vinf);
107 if(!(fbptr = set_video_mode(vmodes[mode_idx].mode))) {
108 printf("failed to set video mode: %x (%dx%d %dbpp)\n", mode_idx,
109 vmodes[mode_idx].width, vmodes[mode_idx].height, vmodes[mode_idx].bpp);
112 vmode = vmodes[mode_idx];
113 printf("video mode: %x (%dx%d %dbpp)\n", vmode.mode, vmode.width,
114 vmode.height, vmode.bpp);
119 qsort(vmodes, nmodes, sizeof *vmodes, modecmp);
121 for(i=0; i<nmodes; i++) {
122 if((fbptr = set_video_mode(vmodes[i].mode))) {
124 printf("video mode: %x (%dx%d %dbpp)\n", vmode.mode, vmode.width,
125 vmode.height, vmode.bpp);
130 printf("failed to find a suitable video mode\n");
141 static int modecmp(const void *a, const void *b)
143 const struct video_mode *ma = a;
144 const struct video_mode *mb = b;
145 unsigned long aval = ma->width | (ma->height << 16);
146 unsigned long bval = mb->width | (mb->height << 16);
151 return mb->bpp - ma->bpp;