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/>.
33 #include "census/census.h"
35 static int video_init(void);
36 static int modecmp(const void *a, const void *b);
38 static struct video_mode vmode;
39 static void *fbptr, *backbuf;
43 void pcboot_main(void)
54 /* initialize the timer */
61 printf("PCBoot kernel initialized\n");
63 if(video_init() == -1) {
64 panic("Failed to find suitable video mode");
66 fbsize = vmode.width * vmode.height * vmode.bpp / 8;
67 if(!(backbuf = malloc(fbsize))) {
68 panic("Failed to allocate back buffer");
70 init_census(backbuf, vmode.width, vmode.height);
76 memcpy(fbptr, backbuf, fbsize);
80 static int video_init(void)
83 struct video_mode vinf, *vmodes;
84 int i, xres, yres, nmodes, mode_idx = -1;
87 if(mode_idx == -1 && (vendor = get_video_vendor()) && strstr(vendor, "SeaBIOS")) {
88 mode_idx = find_video_mode_idx(800, 600, 32);
91 if(mode_idx == -1 && vbe_get_edid(&edid) == 0 && edid_preferred_resolution(&edid, &xres, &yres) == 0) {
92 printf("EDID: preferred resolution: %dx%d\n", xres, yres);
93 mode_idx = find_video_mode_idx(xres, yres, 0);
96 nmodes = video_mode_count();
97 if(!(vmodes = malloc(nmodes * sizeof *vmodes))) {
98 printf("failed to allocate video modes array (%d modes)\n", nmodes);
102 for(i=0; i<nmodes; i++) {
103 video_mode_info(i, &vinf);
108 if(!(fbptr = set_video_mode(vmodes[mode_idx].mode))) {
109 printf("failed to set video mode: %x (%dx%d %dbpp)\n", mode_idx,
110 vmodes[mode_idx].width, vmodes[mode_idx].height, vmodes[mode_idx].bpp);
113 vmode = vmodes[mode_idx];
114 printf("video mode: %x (%dx%d %dbpp)\n", vmode.mode, vmode.width,
115 vmode.height, vmode.bpp);
120 qsort(vmodes, nmodes, sizeof *vmodes, modecmp);
122 for(i=0; i<nmodes; i++) {
123 printf("trying video mode: %x (%dx%d %dbpp)\n", vmodes[i].mode, vmodes[i].width,
124 vmodes[i].height, vmodes[i].bpp);
126 if((fbptr = set_video_mode(vmodes[i].mode))) {
132 printf("failed to find a suitable video mode\n");
143 static int modecmp(const void *a, const void *b)
145 const struct video_mode *ma = a;
146 const struct video_mode *mb = b;
147 unsigned long aval = ma->width | (ma->height << 16);
148 unsigned long bval = mb->width | (mb->height << 16);
153 return mb->bpp - ma->bpp;