Some support for video initialization using natfeat fVDI, but sadly it seems to return NULL for the framebuffer so it's not usable.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39506 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
François Revol 2010-11-19 13:52:17 +00:00
parent e4f8681e79
commit 42df5ff102
3 changed files with 409 additions and 34 deletions

View File

@ -19,6 +19,13 @@ UsePrivateHeaders [ FDirName storage ] ;
#SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons accelerants common ] ; #SEARCH_SOURCE += [ FDirName $(HAIKU_TOP) src add-ons accelerants common ] ;
local genericPlatformSources =
text_menu.cpp
video_blit.cpp
video_splash.cpp
video_rle.cpp
;
KernelMergeObject boot_platform_atari_m68k_shell.o : KernelMergeObject boot_platform_atari_m68k_shell.o :
shell.S shell.S
@ -51,8 +58,7 @@ KernelMergeObject boot_platform_atari_m68k_other.o :
video.cpp video.cpp
#apm.cpp #apm.cpp
# generic $(genericPlatformSources)
text_menu.cpp
# VESA/DDC EDID # VESA/DDC EDID
#decode_edid.c #decode_edid.c
@ -137,7 +143,7 @@ AtariBootPrgLd haiku.prg :
; ;
SEARCH on [ FGristFiles text_menu.cpp ] SEARCH on [ FGristFiles $(genericPlatformSources) ]
= [ FDirName $(HAIKU_TOP) src system boot platform generic ] ; = [ FDirName $(HAIKU_TOP) src system boot platform generic ] ;
# Tell the build system to where stage1.bin can be found, so it can be used # Tell the build system to where stage1.bin can be found, so it can be used

View File

@ -216,6 +216,7 @@ init_nat_features(void)
if (nat_features()) { if (nat_features()) {
// find debugprintf id // find debugprintf id
gDebugPrintfNatFeatID = nat_feat_getid("DEBUGPRINTF"); gDebugPrintfNatFeatID = nat_feat_getid("DEBUGPRINTF");
dprintf("DEBUGPRINTF natfeat id %d\n", gDebugPrintfNatFeatID);
// pass native features infos to the kernel // pass native features infos to the kernel
gKernelArgs.arch_args.plat_args.atari.nat_feat.nf_get_id = gKernelArgs.arch_args.plat_args.atari.nat_feat.nf_get_id =
nat_features()->nfGetID; nat_features()->nfGetID;
@ -225,6 +226,7 @@ init_nat_features(void)
gDebugPrintfNatFeatID; gDebugPrintfNatFeatID;
// find other natfeat ids // find other natfeat ids
gBootstrapNatFeatID = nat_feat_getid("BOOTSTRAP"); gBootstrapNatFeatID = nat_feat_getid("BOOTSTRAP");
dprintf("BOOTSTRAP natfeat id %d\n", gBootstrapNatFeatID);
} }
return nat_features() ? B_OK : B_ENTRY_NOT_FOUND; return nat_features() ? B_OK : B_ENTRY_NOT_FOUND;
} }

View File

@ -6,7 +6,7 @@
#include "toscalls.h" #include "toscalls.h"
#include "video.h" #include "video.h"
//#include "mmu.h" #include "mmu.h"
//#include "images.h" //#include "images.h"
#include <arch/cpu.h> #include <arch/cpu.h>
@ -14,6 +14,7 @@
#include <boot/platform.h> #include <boot/platform.h>
#include <boot/menu.h> #include <boot/menu.h>
#include <boot/kernel_args.h> #include <boot/kernel_args.h>
#include <boot/platform/generic/video.h>
#include <util/list.h> #include <util/list.h>
#include <drivers/driver_settings.h> #include <drivers/driver_settings.h>
#include <GraphicsDefs.h> #include <GraphicsDefs.h>
@ -35,6 +36,7 @@
// which API to use to handle this mode // which API to use to handle this mode
// cf. http://toshyp.atari.org/004.htm // cf. http://toshyp.atari.org/004.htm
/*
enum { enum {
MODETYPE_XBIOS_ST, MODETYPE_XBIOS_ST,
MODETYPE_XBIOS_TT, MODETYPE_XBIOS_TT,
@ -44,46 +46,149 @@ enum {
MODETYPE_CT60, MODETYPE_CT60,
MODETYPE_NATFEAT MODETYPE_NATFEAT
}; };
*/
class ModeAPI { class ModeOps {
public: public:
ModeAPI(const char *name) { fName = name; }; ModeOps(const char *name) { fName = name; fInitStatus = B_NO_INIT; };
~ModeAPI() {}; ~ModeOps() {};
const char *Name() const { return fName; }; const char *Name() const { return fName; };
virtual status_t Enumerate() = 0; virtual status_t Init() { fInitStatus = B_OK; };
virtual status_t Get(struct video_mode *mode) = 0; status_t InitStatus() const { return fInitStatus; };
virtual status_t Set(const struct video_mode *mode) = 0;
virtual status_t Enumerate() = 0;
virtual status_t Get(struct video_mode *mode) = 0;
virtual status_t Set(const struct video_mode *mode) = 0;
virtual status_t Unset(const struct video_mode *mode) { return B_OK; };
virtual addr_t Framebuffer() { return NULL; };
struct video_mode *AllocMode();
virtual int16 Width(const struct video_mode *mode=NULL);
virtual int16 Height(const struct video_mode *mode=NULL);
virtual int16 Depth(const struct video_mode *mode=NULL);
virtual int16 BytesPerRow(const struct video_mode *mode=NULL);
private: private:
const char *fName; const char *fName;
protected:
status_t fInitStatus;
}; };
struct video_mode { struct video_mode {
list_link link; list_link link;
ModeAPI *ops; ModeOps *ops;
color_space space; color_space space;
uint16 mode; uint16 mode;
uint16 width, height, bits_per_pixel; uint16 width, height, bits_per_pixel;
uint32 bytes_per_row; uint32 bytes_per_row;
status_t Set() { ops->Set(this); };
status_t Unset() { ops->Unset(this); };
}; };
static struct list sModeList; static struct list sModeList;
static video_mode *sMode, *sDefaultMode; static video_mode *sMode, *sDefaultMode;
static uint32 sModeCount;
static addr_t sFrameBuffer;
static bool sModeChosen;
static int
compare_video_modes(video_mode *a, video_mode *b)
{
int compare = a->width - b->width;
if (compare != 0)
return compare;
compare = a->height - b->height;
if (compare != 0)
return compare;
// TODO: compare video_mode::mode?
return a->bits_per_pixel - b->bits_per_pixel;
}
/*! Insert the video mode into the list, sorted by resolution and bit depth.
Higher resolutions/depths come first.
*/
static void
add_video_mode(video_mode *videoMode)
{
dprintf("add_video_mode(%d x %d %s)\n", videoMode->width, videoMode->height, videoMode->ops->Name());
video_mode *mode = NULL;
while ((mode = (video_mode *)list_get_next_item(&sModeList, mode))
!= NULL) {
int compare = compare_video_modes(videoMode, mode);
if (compare == 0) {
// mode already exists
return;
}
if (compare > 0)
break;
}
list_insert_item_before(&sModeList, mode, videoMode);
sModeCount++;
}
// #pragma mark -
struct video_mode *
ModeOps::AllocMode()
{
video_mode *videoMode = (video_mode *)malloc(sizeof(struct video_mode));
if (videoMode == NULL)
return NULL;
videoMode->ops = this;
return videoMode;
}
int16
ModeOps::Width(const struct video_mode *mode)
{
return mode ? mode->width : 0;
}
int16
ModeOps::Height(const struct video_mode *mode)
{
return mode ? mode->height : 0;
}
int16
ModeOps::Depth(const struct video_mode *mode)
{
return mode ? mode->bits_per_pixel : 0;
}
int16
ModeOps::BytesPerRow(const struct video_mode *mode)
{
return mode ? mode->bytes_per_row : 0;
}
// #pragma mark - Falcon XBIOS API // #pragma mark - Falcon XBIOS API
class FalconModeAPI : public ModeAPI { class FalconModeOps : public ModeOps {
public: public:
FalconModeAPI() : ModeAPI("Falcon XBIOS") {}; FalconModeOps() : ModeOps("Falcon XBIOS") { fInitStatus = B_OK; };
~FalconModeAPI() {}; ~FalconModeOps() {};
virtual status_t Enumerate(); virtual status_t Enumerate();
virtual status_t Get(struct video_mode *mode); virtual status_t Get(struct video_mode *mode);
virtual status_t Set(const struct video_mode *mode); virtual status_t Set(const struct video_mode *mode);
}; };
status_t status_t
FalconModeAPI::Enumerate() FalconModeOps::Enumerate()
{ {
int16 monitor; int16 monitor;
monitor = VgetMonitor(); monitor = VgetMonitor();
@ -102,7 +207,7 @@ FalconModeAPI::Enumerate()
status_t status_t
FalconModeAPI::Get(struct video_mode *mode) FalconModeOps::Get(struct video_mode *mode)
{ {
int16 m = VsetMode(VM_INQUIRE); int16 m = VsetMode(VM_INQUIRE);
int bpp; int bpp;
@ -122,13 +227,201 @@ FalconModeAPI::Get(struct video_mode *mode)
status_t status_t
FalconModeAPI::Set(const struct video_mode *mode) FalconModeOps::Set(const struct video_mode *mode)
{ {
return ENODEV; return ENODEV;
} }
static FalconModeAPI sFalconModeAPI; static FalconModeOps sFalconModeOps;
// #pragma mark - ARAnyM NFVDI API
/* NatFeat VDI */
#define FVDIDRV_NFAPI_VERSION 0x14000960L
#define FVDI_GET_VERSION 0
#define FVDI_GET_FBADDR 11
#define FVDI_SET_RESOLUTION 12
#define FVDI_GET_WIDTH 13
#define FVDI_GET_HEIGHT 14
#define FVDI_OPENWK 15
#define FVDI_CLOSEWK 16
#define FVDI_GETBPP 17
class NFVDIModeOps : public ModeOps {
public:
NFVDIModeOps() : ModeOps("NFVDI") {};
~NFVDIModeOps() {};
virtual status_t Init();
virtual status_t Enumerate();
virtual status_t Get(struct video_mode *mode);
virtual status_t Set(const struct video_mode *mode);
virtual status_t Unset(const struct video_mode *mode);
virtual addr_t Framebuffer();
virtual int16 Width(const struct video_mode *mode=NULL);
virtual int16 Height(const struct video_mode *mode=NULL);
virtual int16 Depth(const struct video_mode *mode=NULL);
private:
int32 fNatFeatId;
};
status_t
NFVDIModeOps::Init()
{
// NF calls not available when the ctor is called
fNatFeatId = nat_feat_getid("fVDI");
if (fNatFeatId == 0)
return B_ERROR;
dprintf("fVDI natfeat id %d\n", fNatFeatId);
int32 version = nat_feat_call(fNatFeatId, FVDI_GET_VERSION);
dprintf("fVDI NF version %lx\n", version);
if (version < FVDIDRV_NFAPI_VERSION)
return B_ERROR;
fInitStatus = B_OK;
return fInitStatus;
}
status_t
NFVDIModeOps::Enumerate()
{
if (fNatFeatId == 0)
return B_NO_INIT;
video_mode * videoMode;
videoMode = AllocMode();
if (videoMode == NULL)
return B_ERROR;
Get(videoMode);
//videoMode->space = ;
videoMode->mode = 0;
videoMode->width = 800;
videoMode->height = 600;
videoMode->bits_per_pixel = 8;
videoMode->bytes_per_row = videoMode->width * videoMode->bits_per_pixel / 8;
add_video_mode(videoMode);
videoMode = AllocMode();
if (videoMode == NULL)
return B_ERROR;
Get(videoMode);
//videoMode->space = ;
videoMode->mode = 0;
videoMode->width = 1024;
videoMode->height = 768;
videoMode->bits_per_pixel = 16;
videoMode->bytes_per_row = videoMode->width * videoMode->bits_per_pixel / 8;
add_video_mode(videoMode);
return B_OK;
}
status_t
NFVDIModeOps::Get(struct video_mode *mode)
{
if (mode == NULL)
return B_BAD_VALUE;
if (fNatFeatId == 0)
return B_NOT_SUPPORTED;
mode->width = Width();
mode->height = Height();
mode->bits_per_pixel = Depth();
mode->bytes_per_row = mode->width * mode->bits_per_pixel / 8;
dprintf("Get: %dx%d\n", mode->width, mode->height);
return B_OK;
}
status_t
NFVDIModeOps::Set(const struct video_mode *mode)
{
if (mode == NULL)
return B_BAD_VALUE;
if (fNatFeatId == 0)
return B_NOT_SUPPORTED;
status_t err;
dprintf("fVDI::Set(%ldx%ld %ld)\n", (int32)Width(mode), (int32)Height(mode), (int32)Depth(mode));
err = nat_feat_call(fNatFeatId, FVDI_SET_RESOLUTION,
(int32)Width(mode), (int32)Height(mode), (int32)Depth(mode));
err = toserror(err);
err = nat_feat_call(fNatFeatId, FVDI_OPENWK);
return B_OK;
}
status_t
NFVDIModeOps::Unset(const struct video_mode *mode)
{
if (mode == NULL)
return B_BAD_VALUE;
if (fNatFeatId == 0)
return B_NOT_SUPPORTED;
nat_feat_call(fNatFeatId, FVDI_CLOSEWK);
return B_OK;
}
addr_t
NFVDIModeOps::Framebuffer()
{
addr_t fb;
if (fNatFeatId == 0)
return (addr_t)NULL;
fb = (addr_t)nat_feat_call(fNatFeatId, FVDI_GET_FBADDR);
dprintf("fb 0x%08lx\n", fb);
return fb;
}
int16
NFVDIModeOps::Width(const struct video_mode *mode)
{
if (mode)
return ModeOps::Width(mode);
if (fNatFeatId == 0)
return 0;
return (int16)nat_feat_call(fNatFeatId, FVDI_GET_WIDTH);
}
int16
NFVDIModeOps::Height(const struct video_mode *mode)
{
if (mode)
return ModeOps::Height(mode);
if (fNatFeatId == 0)
return 0;
return (int16)nat_feat_call(fNatFeatId, FVDI_GET_HEIGHT);
}
int16
NFVDIModeOps::Depth(const struct video_mode *mode)
{
if (mode)
return ModeOps::Depth(mode);
if (fNatFeatId == 0)
return 0;
return (int16)nat_feat_call(fNatFeatId, FVDI_GETBPP);
}
static NFVDIModeOps sNFVDIModeOps;
// #pragma mark - // #pragma mark -
@ -137,8 +430,6 @@ static FalconModeAPI sFalconModeAPI;
bool bool
video_mode_hook(Menu *menu, MenuItem *item) video_mode_hook(Menu *menu, MenuItem *item)
{ {
// nothing yet
#if 0
// find selected mode // find selected mode
video_mode *mode = NULL; video_mode *mode = NULL;
@ -151,10 +442,10 @@ video_mode_hook(Menu *menu, MenuItem *item)
sMode = sDefaultMode; sMode = sDefaultMode;
sModeChosen = false; sModeChosen = false;
return true; return true;
case 1: //case 1:
// "Standard VGA" mode special // "Standard VGA" mode special
// sets sMode to NULL which triggers VGA mode // sets sMode to NULL which triggers VGA mode
break; //break;
default: default:
mode = (video_mode *)item->Data(); mode = (video_mode *)item->Data();
break; break;
@ -165,10 +456,10 @@ video_mode_hook(Menu *menu, MenuItem *item)
// update standard mode // update standard mode
// ToDo: update fb settings! // ToDo: update fb settings!
sMode = mode; sMode = mode;
platform_switch_to_logo();
} }
sModeChosen = true; sModeChosen = true;
#endif
return true; return true;
} }
@ -186,19 +477,17 @@ video_mode_menu()
"in the system. If there is no mode configured yet, a viable mode will " "in the system. If there is no mode configured yet, a viable mode will "
"be chosen automatically."); "be chosen automatically.");
#if 0 //menu->AddItem(new(nothrow) MenuItem("Standard VGA"));
menu->AddItem(new(nothrow) MenuItem("Standard VGA"));
video_mode *mode = NULL; video_mode *mode = NULL;
while ((mode = (video_mode *)list_get_next_item(&sModeList, mode)) != NULL) { while ((mode = (video_mode *)list_get_next_item(&sModeList, mode)) != NULL) {
char label[64]; char label[64];
sprintf(label, "%ux%u %u bit", mode->width, mode->height, sprintf(label, "%ux%u %u bit (%s)", mode->width, mode->height,
mode->bits_per_pixel); mode->bits_per_pixel, mode->ops->Name());
menu->AddItem(item = new(nothrow) MenuItem(label)); menu->AddItem(item = new(nothrow) MenuItem(label));
item->SetData(mode); item->SetData(mode);
} }
#endif
menu->AddSeparatorItem(); menu->AddSeparatorItem();
menu->AddItem(item = new(nothrow) MenuItem("Return to main menu")); menu->AddItem(item = new(nothrow) MenuItem("Return to main menu"));
@ -208,30 +497,108 @@ video_mode_menu()
} }
void
platform_blit4(addr_t frameBuffer, const uint8 *data,
uint16 width, uint16 height, uint16 imageWidth, uint16 left, uint16 top)
{
if (!data)
return;
}
extern "C" void
platform_set_palette(const uint8 *palette)
{
}
// #pragma mark - // #pragma mark -
extern "C" void extern "C" void
platform_switch_to_logo(void) platform_switch_to_logo(void)
{ {
// ToDo: implement me // in debug mode, we'll never show the logo
if ((platform_boot_options() & BOOT_OPTION_DEBUG_OUTPUT) != 0)
return;
addr_t lastBase = gKernelArgs.frame_buffer.physical_buffer.start;
size_t lastSize = gKernelArgs.frame_buffer.physical_buffer.size;
// TODO: implement me
if (sMode != NULL) {
sMode->Set();
gKernelArgs.frame_buffer.width = sMode->ops->Width(sMode);
gKernelArgs.frame_buffer.height = sMode->ops->Height(sMode);
gKernelArgs.frame_buffer.bytes_per_row = sMode->ops->BytesPerRow(sMode);
gKernelArgs.frame_buffer.depth = sMode->ops->Depth(sMode);
gKernelArgs.frame_buffer.physical_buffer.size =
gKernelArgs.frame_buffer.height
* gKernelArgs.frame_buffer.bytes_per_row;
gKernelArgs.frame_buffer.physical_buffer.start =
sMode->ops->Framebuffer();
sFrameBuffer = sMode->ops->Framebuffer();
} else {
gKernelArgs.frame_buffer.enabled = false;
return;
}
gKernelArgs.frame_buffer.enabled = true;
#if 0
// If the new frame buffer is either larger than the old one or located at
// a different address, we need to remap it, so we first have to throw
// away its previous mapping
if (lastBase != 0
&& (lastBase != gKernelArgs.frame_buffer.physical_buffer.start
|| lastSize < gKernelArgs.frame_buffer.physical_buffer.size)) {
mmu_free((void *)sFrameBuffer, lastSize);
lastBase = 0;
}
if (lastBase == 0) {
// the graphics memory has not been mapped yet!
sFrameBuffer = mmu_map_physical_memory(
gKernelArgs.frame_buffer.physical_buffer.start,
gKernelArgs.frame_buffer.physical_buffer.size, kDefaultPageFlags);
}
#endif
dprintf("splash fb @ %p\n", sFrameBuffer);
video_display_splash(sFrameBuffer);
dprintf("splash done\n");
} }
extern "C" void extern "C" void
platform_switch_to_text_mode(void) platform_switch_to_text_mode(void)
{ {
// ToDo: implement me // TODO: implement me
if (!gKernelArgs.frame_buffer.enabled) {
return;
}
if (sMode)
sMode->Unset();
gKernelArgs.frame_buffer.enabled = 0;
} }
extern "C" status_t extern "C" status_t
platform_init_video(void) platform_init_video(void)
{ {
gKernelArgs.frame_buffer.enabled = 0;
list_init(&sModeList);
// ToDo: implement me // ToDo: implement me
dprintf("current video mode: \n"); dprintf("current video mode: \n");
dprintf("Vsetmode(-1): 0x%08x\n", VsetMode(VM_INQUIRE)); dprintf("Vsetmode(-1): 0x%08x\n", VsetMode(VM_INQUIRE));
sFalconModeAPI.Enumerate(); sFalconModeOps.Init();
sFalconModeOps.Enumerate();
// NF VDI does not implement FVDI_GET_FBADDR :(
//sNFVDIModeOps.Init();
//sNFVDIModeOps.Enumerate();
return B_OK; return B_OK;
} }