xref: /haiku/src/system/boot/platform/amiga_m68k/video.cpp (revision 04cbc2588e36a60992d89793dece7f8cc6475ec9)
14ae92968SFrançois Revol /*
24ae92968SFrançois Revol  * Copyright 2004-2007, Axel Dörfler, axeld@pinc-software.de.
34ae92968SFrançois Revol  * Distributed under the terms of the MIT License.
44ae92968SFrançois Revol  */
54ae92968SFrançois Revol 
64ae92968SFrançois Revol 
77ddba3d2SFrançois Revol #include "rom_calls.h"
8499f2a5cSFrançois Revol #include "console.h"
94ae92968SFrançois Revol #include "video.h"
104ae92968SFrançois Revol //#include "mmu.h"
114ae92968SFrançois Revol //#include "images.h"
124ae92968SFrançois Revol 
134ae92968SFrançois Revol #include <arch/cpu.h>
144ae92968SFrançois Revol #include <boot/stage2.h>
154ae92968SFrançois Revol #include <boot/platform.h>
164ae92968SFrançois Revol #include <boot/menu.h>
174ae92968SFrançois Revol #include <boot/kernel_args.h>
18499f2a5cSFrançois Revol #include <boot/platform/generic/video.h>
194ae92968SFrançois Revol #include <util/list.h>
204ae92968SFrançois Revol #include <drivers/driver_settings.h>
214ae92968SFrançois Revol #include <GraphicsDefs.h>
224ae92968SFrançois Revol 
234ae92968SFrançois Revol #include <stdio.h>
244ae92968SFrançois Revol #include <stdlib.h>
254ae92968SFrançois Revol #include <string.h>
264ae92968SFrançois Revol 
274ae92968SFrançois Revol 
284ae92968SFrançois Revol //#define TRACE_VIDEO
294ae92968SFrançois Revol #ifdef TRACE_VIDEO
304ae92968SFrançois Revol #	define TRACE(x) dprintf x
314ae92968SFrançois Revol #else
324ae92968SFrançois Revol #	define TRACE(x) ;
334ae92968SFrançois Revol #endif
344ae92968SFrançois Revol 
35499f2a5cSFrançois Revol static addr_t sFrameBuffer;
364ae92968SFrançois Revol 
374ae92968SFrançois Revol 
38499f2a5cSFrançois Revol static void
probe_video_mode()39499f2a5cSFrançois Revol probe_video_mode()
40499f2a5cSFrançois Revol {
41499f2a5cSFrançois Revol 	if (gScreen == NULL) {
42499f2a5cSFrançois Revol 		gKernelArgs.frame_buffer.enabled = false;
43499f2a5cSFrançois Revol 		return;
44499f2a5cSFrançois Revol 	}
45499f2a5cSFrançois Revol 	/*
46499f2a5cSFrançois Revol 	if (gScreen->RastPort.BitMap->Depth < 8) {
47499f2a5cSFrançois Revol 		gKernelArgs.frame_buffer.enabled = false;
48499f2a5cSFrançois Revol 		return;
49499f2a5cSFrançois Revol 	}
50499f2a5cSFrançois Revol 	*/
51499f2a5cSFrançois Revol 
52499f2a5cSFrançois Revol 	/*
53499f2a5cSFrançois Revol 	dprintf("Video mode:\n");
54499f2a5cSFrançois Revol 	dprintf("BytesPerRow %d\n", gScreen->RastPort.BitMap->BytesPerRow);
55499f2a5cSFrançois Revol 	dprintf("Rows %d\n", gScreen->RastPort.BitMap->Rows);
56499f2a5cSFrançois Revol 	dprintf("Flags %02x\n", gScreen->RastPort.BitMap->Flags);
57499f2a5cSFrançois Revol 	dprintf("Depth %d\n", gScreen->RastPort.BitMap->Depth);
58499f2a5cSFrançois Revol 	for (int i = 0; i < 8; i++)
59499f2a5cSFrançois Revol 		dprintf("Planes[%d] %p\n", i, gScreen->RastPort.BitMap->Planes[i]);
60499f2a5cSFrançois Revol 	*/
61499f2a5cSFrançois Revol 
62499f2a5cSFrançois Revol 	//XXX how do we tell it's a planar framebuffer ??
63499f2a5cSFrançois Revol 
64499f2a5cSFrançois Revol 	gKernelArgs.frame_buffer.width = gScreen->RastPort.BitMap->BytesPerRow * 8;
65499f2a5cSFrançois Revol 	gKernelArgs.frame_buffer.height = gScreen->RastPort.BitMap->Rows;
66499f2a5cSFrançois Revol 	gKernelArgs.frame_buffer.bytes_per_row = gScreen->RastPort.BitMap->BytesPerRow;
67499f2a5cSFrançois Revol 	gKernelArgs.frame_buffer.depth = gScreen->RastPort.BitMap->Depth;
68499f2a5cSFrançois Revol 	gKernelArgs.frame_buffer.physical_buffer.size
69499f2a5cSFrançois Revol 		= gKernelArgs.frame_buffer.width
70499f2a5cSFrançois Revol 		* gKernelArgs.frame_buffer.height
71499f2a5cSFrançois Revol 		* gScreen->RastPort.BitMap->Depth / 8;
72499f2a5cSFrançois Revol 	gKernelArgs.frame_buffer.physical_buffer.start
73499f2a5cSFrançois Revol 		= (phys_addr_t)(gScreen->RastPort.BitMap->Planes[0]);
74499f2a5cSFrançois Revol 
75499f2a5cSFrançois Revol 	dprintf("video mode: %ux%ux%u\n", gKernelArgs.frame_buffer.width,
76499f2a5cSFrançois Revol 		gKernelArgs.frame_buffer.height, gKernelArgs.frame_buffer.depth);
77499f2a5cSFrançois Revol 
78499f2a5cSFrançois Revol 	gKernelArgs.frame_buffer.enabled = true;
79499f2a5cSFrançois Revol }
80b14f1607SFrançois Revol 
81b14f1607SFrançois Revol 
824ae92968SFrançois Revol //	#pragma mark -
834ae92968SFrançois Revol 
844ae92968SFrançois Revol 
854ae92968SFrançois Revol bool
video_mode_hook(Menu * menu,MenuItem * item)864ae92968SFrançois Revol video_mode_hook(Menu *menu, MenuItem *item)
874ae92968SFrançois Revol {
884ae92968SFrançois Revol 	// nothing yet
894ae92968SFrançois Revol 	return true;
904ae92968SFrançois Revol }
914ae92968SFrançois Revol 
924ae92968SFrançois Revol 
934ae92968SFrançois Revol Menu *
video_mode_menu()944ae92968SFrançois Revol video_mode_menu()
954ae92968SFrançois Revol {
96b14f1607SFrançois Revol 	Menu *menu = new(nothrow) Menu(CHOICE_MENU, "Select Video Mode");
97b14f1607SFrançois Revol 	MenuItem *item;
98b14f1607SFrançois Revol 
99b14f1607SFrançois Revol 	menu->AddItem(item = new(nothrow) MenuItem("Default"));
100b14f1607SFrançois Revol 	item->SetMarked(true);
101b14f1607SFrançois Revol 	item->Select(true);
102b14f1607SFrançois Revol 	item->SetHelpText("The Default video mode is the one currently configured "
103b14f1607SFrançois Revol 		"in the system. If there is no mode configured yet, a viable mode will "
104b14f1607SFrançois Revol 		"be chosen automatically.");
105b14f1607SFrançois Revol 
106b14f1607SFrançois Revol /*
107b14f1607SFrançois Revol 	video_mode *mode = NULL;
108b14f1607SFrançois Revol 	while ((mode = (video_mode *)list_get_next_item(&sModeList, mode)) != NULL) {
109b14f1607SFrançois Revol 		char label[64];
110b14f1607SFrançois Revol 		sprintf(label, "%ux%u %u bit", mode->width, mode->height,
111b14f1607SFrançois Revol 			mode->bits_per_pixel);
112b14f1607SFrançois Revol 
113b14f1607SFrançois Revol 		menu->AddItem(item = new(nothrow) MenuItem(label));
114b14f1607SFrançois Revol 		item->SetData(mode);
115b14f1607SFrançois Revol 	}
116b14f1607SFrançois Revol */
117b14f1607SFrançois Revol #if 1
118b14f1607SFrançois Revol 	uint32 modeID = INVALID_ID;
119b14f1607SFrançois Revol 	while ((modeID = NextDisplayInfo(modeID)) != INVALID_ID) {
120b14f1607SFrançois Revol 		//DisplayInfoHandle handle = FindDisplayInfo(modeID);
121b14f1607SFrançois Revol 		//if (handle == NULL)
122b14f1607SFrançois Revol 		//	continue;
123b14f1607SFrançois Revol 		struct DisplayInfo info;
124b14f1607SFrançois Revol 		struct DimensionInfo dimension;
125b14f1607SFrançois Revol 		struct NameInfo name;
126b14f1607SFrançois Revol 		if (GetDisplayInfoData(NULL, (uint8 *)&info, sizeof(info),
127b14f1607SFrançois Revol 			DTAG_DISP, modeID) < 48/*sizeof(struct DisplayInfo)*/)
128b14f1607SFrançois Revol 			continue;
129b14f1607SFrançois Revol 		if (GetDisplayInfoData(NULL, (uint8 *)&dimension, sizeof(dimension),
130b14f1607SFrançois Revol 			DTAG_DIMS, modeID) < 66)
131b14f1607SFrançois Revol 			continue;
132b14f1607SFrançois Revol 		/*if (GetDisplayInfoData(NULL, (uint8 *)&name, sizeof(name),
133b14f1607SFrançois Revol 			DTAG_NAME, modeID) < sizeof(name) - 8)
134b14f1607SFrançois Revol 			continue;*/
135b14f1607SFrançois Revol 		if (info.NotAvailable)
136b14f1607SFrançois Revol 			continue;
137499f2a5cSFrançois Revol 		if (info.PropertyFlags & DIPF_IS_HAM)
138499f2a5cSFrançois Revol 			continue;
139499f2a5cSFrançois Revol 		if (info.PropertyFlags & DIPF_IS_DUALPF)
140499f2a5cSFrançois Revol 			continue;
141b14f1607SFrançois Revol 		if (dimension.MaxDepth < 4)
142b14f1607SFrançois Revol 			continue;
143499f2a5cSFrançois Revol 		// skip 5 & 6 bit modes
144499f2a5cSFrançois Revol 		if (dimension.MaxDepth < 8 && dimension.MaxDepth != 4)
145499f2a5cSFrançois Revol 			continue;
146b14f1607SFrançois Revol 		//dprintf("name: %s\n", name.Name);
147b14f1607SFrançois Revol 		/*
148b14f1607SFrançois Revol 		dprintf("mode 0x%08lx: %dx%d flags: 0x%08lx bpp: %d\n",
149b14f1607SFrançois Revol 			modeID, info.Resolution.x, info.Resolution.y, info.PropertyFlags,
150b14f1607SFrançois Revol 			info.RedBits + info.GreenBits + info.BlueBits);
151b14f1607SFrançois Revol 		dprintf("mode: %dx%d -> %dx%d\n",
152b14f1607SFrançois Revol 			dimension.MinRasterWidth, dimension.MinRasterHeight,
153b14f1607SFrançois Revol 			dimension.MaxRasterWidth, dimension.MaxRasterHeight);
154499f2a5cSFrançois Revol 		*/
155b14f1607SFrançois Revol 		dprintf("mode: %dx%d %dbpp flags: 0x%08lx\n",
156b14f1607SFrançois Revol 			dimension.Nominal.MaxX - dimension.Nominal.MinX + 1,
157b14f1607SFrançois Revol 			dimension.Nominal.MaxY - dimension.Nominal.MinY + 1,
158b14f1607SFrançois Revol 			dimension.MaxDepth, info.PropertyFlags);
159499f2a5cSFrançois Revol 
160ee0c1302SFrançois Revol 		char label[128];
161ee0c1302SFrançois Revol 		sprintf(label, "%ux%u %u bit %08lx%s%s",
162b14f1607SFrançois Revol 			dimension.Nominal.MaxX - dimension.Nominal.MinX + 1,
163b14f1607SFrançois Revol 			dimension.Nominal.MaxY - dimension.Nominal.MinY + 1,
164ee0c1302SFrançois Revol 			dimension.MaxDepth, info.PropertyFlags,
165499f2a5cSFrançois Revol 			(info.PropertyFlags & DIPF_IS_LACE) ? " i" : "",
166499f2a5cSFrançois Revol 			(info.PropertyFlags & DIPF_IS_PAL) ? " pal" : "");
167b14f1607SFrançois Revol 
168b14f1607SFrançois Revol 		menu->AddItem(item = new(nothrow) MenuItem(label));
169b14f1607SFrançois Revol 		item->SetData((void *)modeID);
170b14f1607SFrançois Revol 	}
171b14f1607SFrançois Revol 
172b14f1607SFrançois Revol #endif
173b14f1607SFrançois Revol 	dprintf("done\n");
174b14f1607SFrançois Revol 
175b14f1607SFrançois Revol 	menu->AddSeparatorItem();
176b14f1607SFrançois Revol 	menu->AddItem(item = new(nothrow) MenuItem("Return to main menu"));
177b14f1607SFrançois Revol 	item->SetType(MENU_ITEM_NO_CHOICE);
178b14f1607SFrançois Revol 
179b14f1607SFrançois Revol 	return menu;
1804ae92968SFrançois Revol }
1814ae92968SFrançois Revol 
1824ae92968SFrançois Revol 
183499f2a5cSFrançois Revol //	#pragma mark - blit
184499f2a5cSFrançois Revol 
185499f2a5cSFrançois Revol 
186499f2a5cSFrançois Revol extern "C" void
platform_blit4(addr_t frameBuffer,const uint8 * data,uint16 width,uint16 height,uint16 imageWidth,uint16 left,uint16 top)187499f2a5cSFrançois Revol platform_blit4(addr_t frameBuffer, const uint8 *data,
188499f2a5cSFrançois Revol 	uint16 width, uint16 height, uint16 imageWidth, uint16 left, uint16 top)
189499f2a5cSFrançois Revol {
190499f2a5cSFrançois Revol 	if (!data)
191499f2a5cSFrançois Revol 		return;
192499f2a5cSFrançois Revol 	// TODO
193499f2a5cSFrançois Revol }
194499f2a5cSFrançois Revol 
195499f2a5cSFrançois Revol 
196499f2a5cSFrançois Revol extern "C" void
platform_set_palette(const uint8 * palette)197499f2a5cSFrançois Revol platform_set_palette(const uint8 *palette)
198499f2a5cSFrançois Revol {
199499f2a5cSFrançois Revol 	switch (gKernelArgs.frame_buffer.depth) {
200499f2a5cSFrançois Revol 		case 4:
201499f2a5cSFrançois Revol 			//vga_set_palette((const uint8 *)kPalette16, 0, 16);
202499f2a5cSFrançois Revol 			break;
203499f2a5cSFrançois Revol 		case 8:
204499f2a5cSFrançois Revol 			//if (vesa_set_palette((const uint8 *)palette, 0, 256) != B_OK)
205499f2a5cSFrançois Revol 			//	dprintf("set palette failed!\n");
206499f2a5cSFrançois Revol 
207499f2a5cSFrançois Revol 			break;
208499f2a5cSFrançois Revol 		default:
209499f2a5cSFrançois Revol 			break;
210499f2a5cSFrançois Revol 	}
211499f2a5cSFrançois Revol }
212499f2a5cSFrançois Revol 
213499f2a5cSFrançois Revol 
2144ae92968SFrançois Revol //	#pragma mark -
2154ae92968SFrançois Revol 
2164ae92968SFrançois Revol 
2174ae92968SFrançois Revol extern "C" void
platform_switch_to_logo(void)2184ae92968SFrançois Revol platform_switch_to_logo(void)
2194ae92968SFrançois Revol {
220499f2a5cSFrançois Revol 	return;
221499f2a5cSFrançois Revol 	// in debug mode, we'll never show the logo
222499f2a5cSFrançois Revol 	if ((platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT) != 0)
223499f2a5cSFrançois Revol 		return;
224499f2a5cSFrançois Revol 
225499f2a5cSFrançois Revol 	addr_t lastBase = gKernelArgs.frame_buffer.physical_buffer.start;
226499f2a5cSFrançois Revol 	size_t lastSize = gKernelArgs.frame_buffer.physical_buffer.size;
227499f2a5cSFrançois Revol 
2284ae92968SFrançois Revol 	// TODO: implement me
229499f2a5cSFrançois Revol 
230499f2a5cSFrançois Revol 	probe_video_mode();
231499f2a5cSFrançois Revol 
232499f2a5cSFrançois Revol 	// map to virtual memory
233499f2a5cSFrançois Revol 	// (should be ok in bootloader thanks to TT0)
234499f2a5cSFrançois Revol 
235499f2a5cSFrançois Revol 	sFrameBuffer = gKernelArgs.frame_buffer.physical_buffer.start;
236499f2a5cSFrançois Revol 
237*04cbc258SFredrik Holmqvist 	//video_display_splash(sFrameBuffer);
238499f2a5cSFrançois Revol 
2394ae92968SFrançois Revol }
2404ae92968SFrançois Revol 
2414ae92968SFrançois Revol 
2424ae92968SFrançois Revol extern "C" void
platform_switch_to_text_mode(void)2434ae92968SFrançois Revol platform_switch_to_text_mode(void)
2444ae92968SFrançois Revol {
2454ae92968SFrançois Revol 	// TODO: implement me
2464219bd96SFrançois Revol 	// force Intuition to redraw everything
2474219bd96SFrançois Revol 	RemakeDisplay();
2484ae92968SFrançois Revol }
2494ae92968SFrançois Revol 
2504ae92968SFrançois Revol 
2514ae92968SFrançois Revol extern "C" status_t
platform_init_video(void)2524ae92968SFrançois Revol platform_init_video(void)
2534ae92968SFrançois Revol {
2544ae92968SFrançois Revol 	// TODO: implement me
255499f2a5cSFrançois Revol 	probe_video_mode();
256499f2a5cSFrançois Revol 
2574ae92968SFrançois Revol 	return B_OK;
2584ae92968SFrançois Revol }
2594ae92968SFrançois Revol 
260