1 /* 2 * Copyright 2004-2007, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include "rom_calls.h" 8 #include "console.h" 9 #include "video.h" 10 //#include "mmu.h" 11 //#include "images.h" 12 13 #include <arch/cpu.h> 14 #include <boot/stage2.h> 15 #include <boot/platform.h> 16 #include <boot/menu.h> 17 #include <boot/kernel_args.h> 18 #include <boot/platform/generic/video.h> 19 #include <util/list.h> 20 #include <drivers/driver_settings.h> 21 #include <GraphicsDefs.h> 22 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <string.h> 26 27 28 //#define TRACE_VIDEO 29 #ifdef TRACE_VIDEO 30 # define TRACE(x) dprintf x 31 #else 32 # define TRACE(x) ; 33 #endif 34 35 static addr_t sFrameBuffer; 36 37 38 static void 39 probe_video_mode() 40 { 41 if (gScreen == NULL) { 42 gKernelArgs.frame_buffer.enabled = false; 43 return; 44 } 45 /* 46 if (gScreen->RastPort.BitMap->Depth < 8) { 47 gKernelArgs.frame_buffer.enabled = false; 48 return; 49 } 50 */ 51 52 /* 53 dprintf("Video mode:\n"); 54 dprintf("BytesPerRow %d\n", gScreen->RastPort.BitMap->BytesPerRow); 55 dprintf("Rows %d\n", gScreen->RastPort.BitMap->Rows); 56 dprintf("Flags %02x\n", gScreen->RastPort.BitMap->Flags); 57 dprintf("Depth %d\n", gScreen->RastPort.BitMap->Depth); 58 for (int i = 0; i < 8; i++) 59 dprintf("Planes[%d] %p\n", i, gScreen->RastPort.BitMap->Planes[i]); 60 */ 61 62 //XXX how do we tell it's a planar framebuffer ?? 63 64 gKernelArgs.frame_buffer.width = gScreen->RastPort.BitMap->BytesPerRow * 8; 65 gKernelArgs.frame_buffer.height = gScreen->RastPort.BitMap->Rows; 66 gKernelArgs.frame_buffer.bytes_per_row = gScreen->RastPort.BitMap->BytesPerRow; 67 gKernelArgs.frame_buffer.depth = gScreen->RastPort.BitMap->Depth; 68 gKernelArgs.frame_buffer.physical_buffer.size 69 = gKernelArgs.frame_buffer.width 70 * gKernelArgs.frame_buffer.height 71 * gScreen->RastPort.BitMap->Depth / 8; 72 gKernelArgs.frame_buffer.physical_buffer.start 73 = (phys_addr_t)(gScreen->RastPort.BitMap->Planes[0]); 74 75 dprintf("video mode: %ux%ux%u\n", gKernelArgs.frame_buffer.width, 76 gKernelArgs.frame_buffer.height, gKernelArgs.frame_buffer.depth); 77 78 gKernelArgs.frame_buffer.enabled = true; 79 } 80 81 82 // #pragma mark - 83 84 85 bool 86 video_mode_hook(Menu *menu, MenuItem *item) 87 { 88 // nothing yet 89 return true; 90 } 91 92 93 Menu * 94 video_mode_menu() 95 { 96 Menu *menu = new(nothrow) Menu(CHOICE_MENU, "Select Video Mode"); 97 MenuItem *item; 98 99 menu->AddItem(item = new(nothrow) MenuItem("Default")); 100 item->SetMarked(true); 101 item->Select(true); 102 item->SetHelpText("The Default video mode is the one currently configured " 103 "in the system. If there is no mode configured yet, a viable mode will " 104 "be chosen automatically."); 105 106 /* 107 video_mode *mode = NULL; 108 while ((mode = (video_mode *)list_get_next_item(&sModeList, mode)) != NULL) { 109 char label[64]; 110 sprintf(label, "%ux%u %u bit", mode->width, mode->height, 111 mode->bits_per_pixel); 112 113 menu->AddItem(item = new(nothrow) MenuItem(label)); 114 item->SetData(mode); 115 } 116 */ 117 #if 1 118 uint32 modeID = INVALID_ID; 119 while ((modeID = NextDisplayInfo(modeID)) != INVALID_ID) { 120 //DisplayInfoHandle handle = FindDisplayInfo(modeID); 121 //if (handle == NULL) 122 // continue; 123 struct DisplayInfo info; 124 struct DimensionInfo dimension; 125 struct NameInfo name; 126 if (GetDisplayInfoData(NULL, (uint8 *)&info, sizeof(info), 127 DTAG_DISP, modeID) < 48/*sizeof(struct DisplayInfo)*/) 128 continue; 129 if (GetDisplayInfoData(NULL, (uint8 *)&dimension, sizeof(dimension), 130 DTAG_DIMS, modeID) < 66) 131 continue; 132 /*if (GetDisplayInfoData(NULL, (uint8 *)&name, sizeof(name), 133 DTAG_NAME, modeID) < sizeof(name) - 8) 134 continue;*/ 135 if (info.NotAvailable) 136 continue; 137 if (info.PropertyFlags & DIPF_IS_HAM) 138 continue; 139 if (info.PropertyFlags & DIPF_IS_DUALPF) 140 continue; 141 if (dimension.MaxDepth < 4) 142 continue; 143 // skip 5 & 6 bit modes 144 if (dimension.MaxDepth < 8 && dimension.MaxDepth != 4) 145 continue; 146 //dprintf("name: %s\n", name.Name); 147 /* 148 dprintf("mode 0x%08lx: %dx%d flags: 0x%08lx bpp: %d\n", 149 modeID, info.Resolution.x, info.Resolution.y, info.PropertyFlags, 150 info.RedBits + info.GreenBits + info.BlueBits); 151 dprintf("mode: %dx%d -> %dx%d\n", 152 dimension.MinRasterWidth, dimension.MinRasterHeight, 153 dimension.MaxRasterWidth, dimension.MaxRasterHeight); 154 */ 155 dprintf("mode: %dx%d %dbpp flags: 0x%08lx\n", 156 dimension.Nominal.MaxX - dimension.Nominal.MinX + 1, 157 dimension.Nominal.MaxY - dimension.Nominal.MinY + 1, 158 dimension.MaxDepth, info.PropertyFlags); 159 160 char label[128]; 161 sprintf(label, "%ux%u %u bit %08lx%s%s", 162 dimension.Nominal.MaxX - dimension.Nominal.MinX + 1, 163 dimension.Nominal.MaxY - dimension.Nominal.MinY + 1, 164 dimension.MaxDepth, info.PropertyFlags, 165 (info.PropertyFlags & DIPF_IS_LACE) ? " i" : "", 166 (info.PropertyFlags & DIPF_IS_PAL) ? " pal" : ""); 167 168 menu->AddItem(item = new(nothrow) MenuItem(label)); 169 item->SetData((void *)modeID); 170 } 171 172 #endif 173 dprintf("done\n"); 174 175 menu->AddSeparatorItem(); 176 menu->AddItem(item = new(nothrow) MenuItem("Return to main menu")); 177 item->SetType(MENU_ITEM_NO_CHOICE); 178 179 return menu; 180 } 181 182 183 // #pragma mark - blit 184 185 186 extern "C" void 187 platform_blit4(addr_t frameBuffer, const uint8 *data, 188 uint16 width, uint16 height, uint16 imageWidth, uint16 left, uint16 top) 189 { 190 if (!data) 191 return; 192 // TODO 193 } 194 195 196 extern "C" void 197 platform_set_palette(const uint8 *palette) 198 { 199 switch (gKernelArgs.frame_buffer.depth) { 200 case 4: 201 //vga_set_palette((const uint8 *)kPalette16, 0, 16); 202 break; 203 case 8: 204 //if (vesa_set_palette((const uint8 *)palette, 0, 256) != B_OK) 205 // dprintf("set palette failed!\n"); 206 207 break; 208 default: 209 break; 210 } 211 } 212 213 214 // #pragma mark - 215 216 217 extern "C" void 218 platform_switch_to_logo(void) 219 { 220 return; 221 // in debug mode, we'll never show the logo 222 if ((platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT) != 0) 223 return; 224 225 addr_t lastBase = gKernelArgs.frame_buffer.physical_buffer.start; 226 size_t lastSize = gKernelArgs.frame_buffer.physical_buffer.size; 227 228 // TODO: implement me 229 230 probe_video_mode(); 231 232 // map to virtual memory 233 // (should be ok in bootloader thanks to TT0) 234 235 sFrameBuffer = gKernelArgs.frame_buffer.physical_buffer.start; 236 237 //video_display_splash(sFrameBuffer); 238 239 } 240 241 242 extern "C" void 243 platform_switch_to_text_mode(void) 244 { 245 // TODO: implement me 246 // force Intuition to redraw everything 247 RemakeDisplay(); 248 } 249 250 251 extern "C" status_t 252 platform_init_video(void) 253 { 254 // TODO: implement me 255 probe_video_mode(); 256 257 return B_OK; 258 } 259 260