xref: /haiku/src/system/boot/platform/amiga_m68k/video.cpp (revision 220d04022750f40f8bac8f01fa551211e28d04f2)
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