atari:xbios: Move all Falcon specific stuff to specific backend file. SDL-1.2
authorPatrice Mandin <patmandin@gmail.com>
Wed, 30 Jul 2014 17:34:52 +0200
branchSDL-1.2
changeset 9035 23be72ff017a
parent 9029 533ad1d44120
child 9036 e05157cbe85b
atari:xbios: Move all Falcon specific stuff to specific backend file.
src/video/xbios/SDL_xbios.c
src/video/xbios/SDL_xbios.h
src/video/xbios/SDL_xbios_centscreen.c
src/video/xbios/SDL_xbios_centscreen.h
src/video/xbios/SDL_xbios_f30.c
src/video/xbios/SDL_xbios_sb3.c
src/video/xbios/SDL_xbios_sb3.h
--- a/src/video/xbios/SDL_xbios.c	Wed Jul 30 13:30:09 2014 +0200
+++ b/src/video/xbios/SDL_xbios.c	Wed Jul 30 17:34:52 2014 +0200
@@ -46,8 +46,6 @@
 #include "../ataricommon/SDL_atarimxalloc_c.h"
 #include "../ataricommon/SDL_atarigl_c.h"
 #include "SDL_xbios.h"
-#include "SDL_xbios_blowup.h"
-#include "SDL_xbios_centscreen.h"
 #include "SDL_xbios_sb3.h"
 #include "SDL_xbios_tveille.h"
 #include "SDL_xbios_milan.h"
@@ -74,7 +72,6 @@
 static int XBIOS_VideoInit(_THIS, SDL_PixelFormat *vformat);
 static SDL_Rect **XBIOS_ListModes(_THIS, SDL_PixelFormat *format, Uint32 flags);
 static SDL_Surface *XBIOS_SetVideoMode(_THIS, SDL_Surface *current, int width, int height, int bpp, Uint32 flags);
-static int XBIOS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
 static void XBIOS_VideoQuit(_THIS);
 
 /* Hardware surface functions */
@@ -90,36 +87,6 @@
 static void XBIOS_GL_SwapBuffers(_THIS);
 #endif
 
-/* Default list of video modes */
-
-static const xbiosmode_t falconrgbmodes[16]={
-	{BPS16|COL80|OVERSCAN|VERTFLAG,768,480,16,0},
-	{BPS16|COL80|OVERSCAN,768,240,16,0},
-	{BPS16|COL80|VERTFLAG,640,400,16,0},
-	{BPS16|COL80,640,200,16,0},
-	{BPS16|OVERSCAN|VERTFLAG,384,480,16,0},
-	{BPS16|OVERSCAN,384,240,16,0},
-	{BPS16|VERTFLAG,320,400,16,0},
-	{BPS16,320,200,16,0},
-	{BPS8|COL80|OVERSCAN|VERTFLAG,768,480,8,XBIOSMODE_C2P},
-	{BPS8|COL80|OVERSCAN,768,240,8,XBIOSMODE_C2P},
-	{BPS8|COL80|VERTFLAG,640,400,8,XBIOSMODE_C2P},
-	{BPS8|COL80,640,200,8,XBIOSMODE_C2P},
-	{BPS8|OVERSCAN|VERTFLAG,384,480,8,XBIOSMODE_C2P},
-	{BPS8|OVERSCAN,384,240,8,XBIOSMODE_C2P},
-	{BPS8|VERTFLAG,320,400,8,XBIOSMODE_C2P},
-	{BPS8,320,200,8,XBIOSMODE_C2P}
-};
-
-static const xbiosmode_t falconvgamodes[6]={
-	{BPS16,320,480,16,0},
-	{BPS16|VERTFLAG,320,240,16,0},
-	{BPS8|COL80,640,480,8,XBIOSMODE_C2P},
-	{BPS8|COL80|VERTFLAG,640,240,8,XBIOSMODE_C2P},
-	{BPS8,320,480,8,XBIOSMODE_C2P},
-	{BPS8|VERTFLAG,320,240,8,XBIOSMODE_C2P}
-};
-
 /* Xbios driver bootstrap functions */
 
 static int XBIOS_Available(void)
@@ -213,7 +180,7 @@
 	device->VideoInit = XBIOS_VideoInit;
 	device->ListModes = XBIOS_ListModes;
 	device->SetVideoMode = XBIOS_SetVideoMode;
-	device->SetColors = XBIOS_SetColors;
+	device->SetColors = NULL;	/* Defined by each device specific backend */
 	device->UpdateRects = NULL;
 	device->VideoQuit = XBIOS_VideoQuit;
 	device->AllocHWSurface = XBIOS_AllocHWSurface;
@@ -252,7 +219,7 @@
 			SDL_XBIOS_VideoInit_TT(device);
 			break;
 		case VDO_F30:
-			device->SetColors = XBIOS_SetColors;
+			SDL_XBIOS_VideoInit_F30(device);
 			break;
 		case VDO_MILAN:
 			SDL_XBIOS_VideoInit_Milan(device);
@@ -324,40 +291,9 @@
 	}
 }
 
-static void XBIOS_ListFalconRgbModes(_THIS, int actually_add)
-{
-	int i;
-
-	for (i=0; i<16; i++) {
-		xbiosmode_t modeinfo;
-
-		SDL_memcpy(&modeinfo, &falconrgbmodes[i], sizeof(xbiosmode_t));
-		modeinfo.number &= ~(VGA|PAL);
-		modeinfo.number |= XBIOS_oldvmode & (VGA|PAL);
-
-		SDL_XBIOS_AddMode(this, actually_add, &modeinfo);
-	}
-}
-
-static void XBIOS_ListFalconVgaModes(_THIS, int actually_add)
-{
-	int i;
-
-	for (i=0; i<6; i++) {
-		xbiosmode_t modeinfo;
-
-		SDL_memcpy(&modeinfo, &falconvgamodes[i], sizeof(xbiosmode_t));
-		modeinfo.number &= ~(VGA|PAL);
-		modeinfo.number |= XBIOS_oldvmode & (VGA|PAL);
-
-		SDL_XBIOS_AddMode(this, actually_add, &modeinfo);
-	}
-}
-
 static int XBIOS_VideoInit(_THIS, SDL_PixelFormat *vformat)
 {
 	int i;
-	long cookie_blow, cookie_scpn, cookie_cnts;
 
 	/* Initialize all variables that we clean on shutdown */
 	for ( i=0; i<NUM_MODELISTS; ++i ) {
@@ -366,11 +302,6 @@
 		SDL_xbiosmode[i] = NULL;
 	}
 
-	/* Cookie _VDO present ? if not, assume ST machine */
-	if (Getcookie(C__VDO, &XBIOS_cvdo) != C_FOUND) {
-		XBIOS_cvdo = VDO_ST << 16;
-	}
-
 	/* Allocate memory for old palette */
 	XBIOS_oldpalette = (void *)SDL_malloc(256*sizeof(long));
 	if ( !XBIOS_oldpalette ) {
@@ -378,11 +309,6 @@
 		return(-1);
 	}
 
-	/* Initialize video mode list */
-	/* and save current screen status (palette, screen address, video mode) */
-	XBIOS_centscreen = SDL_FALSE;
-	XBIOS_oldvbase = Physbase();
-
 	/* Determine the current screen size */
 	this->info.current_w = 0;
 	this->info.current_h = 0;
@@ -390,62 +316,11 @@
 	/* Determine the screen depth (use default 8-bit depth) */
 	vformat->BitsPerPixel = 8;
 
-	/* First allocate room for needed video modes */
-	switch (XBIOS_cvdo >>16) {
-		case VDO_ST:
-		case VDO_STE:
-			(*XBIOS_saveMode)(this, vformat);
-			(*XBIOS_listModes)(this, 0);
-			break;
-		case VDO_TT:
-			(*XBIOS_saveMode)(this, vformat);
-			(*XBIOS_listModes)(this, 0);
-			break;
-		case VDO_F30:
-			XBIOS_oldvmode=VsetMode(-1);
-
-			XBIOS_oldnumcol= 1<< (1 << (XBIOS_oldvmode & NUMCOLS));
-			if (XBIOS_oldnumcol > 256) {
-				XBIOS_oldnumcol = 0;
-			}
-			if (XBIOS_oldnumcol) {
-				VgetRGB(0, XBIOS_oldnumcol, XBIOS_oldpalette);
-			}
-
-			vformat->BitsPerPixel = 16;
+	/* Save current mode, may update current screen size or preferred depth */
+	(*XBIOS_saveMode)(this, vformat);
 
-			/* ScreenBlaster 3 ? */
-			if (Getcookie(C_SCPN, &cookie_scpn) == C_FOUND) {
-				SDL_XBIOS_ListSB3Modes(this, 0, (scpn_cookie_t *)cookie_scpn);
-			} else
-			/* Centscreen ? */
-			if (Getcookie(C_CNTS, &cookie_cnts) == C_FOUND) {
-				XBIOS_oldvmode = SDL_XBIOS_ListCentscreenModes(this, 0);
-				XBIOS_centscreen = SDL_TRUE;
-			} else
-			/* Standard, with or without Blowup */
-			{
-				switch (VgetMonitor())
-				{
-					case MONITOR_RGB:
-					case MONITOR_TV:
-						XBIOS_ListFalconRgbModes(this, 0);
-						break;
-					case MONITOR_VGA:
-						XBIOS_ListFalconVgaModes(this, 0);
-						break;
-				}
-
-				if (Getcookie(C_BLOW, &cookie_blow) == C_FOUND) {
-					SDL_XBIOS_ListBlowupModes(this, 0, (blow_cookie_t *)cookie_blow);
-				}
-			}
-			break;
-		case VDO_MILAN:
-			(*XBIOS_saveMode)(this, vformat);
-			(*XBIOS_listModes)(this, 0);
-			break;
-	}
+	/* First allocate room for needed video modes */
+	(*XBIOS_listModes)(this, 0);
 
 	for ( i=0; i<NUM_MODELISTS; ++i ) {
 		int j;
@@ -484,46 +359,7 @@
 	}
 
 	/* Now fill the mode list */
-	switch (XBIOS_cvdo >>16) {
-		case VDO_ST:
-		case VDO_STE:
-			(*XBIOS_listModes)(this, 1);
-			break;
-		case VDO_TT:
-			(*XBIOS_listModes)(this, 1);
-			break;
-		case VDO_F30:
-			/* ScreenBlaster 3 ? */
-			if (Getcookie(C_SCPN, &cookie_scpn) == C_FOUND) {
-				SDL_XBIOS_ListSB3Modes(this, 1, (scpn_cookie_t *)cookie_scpn);
-			} else
-			/* Centscreen ? */
-			if (Getcookie(C_CNTS, &cookie_cnts) == C_FOUND) {
-				XBIOS_oldvmode = SDL_XBIOS_ListCentscreenModes(this, 1);
-				XBIOS_centscreen = SDL_TRUE;
-			} else
-			/* Standard, with or without Blowup */
-			{
-				switch (VgetMonitor())
-				{
-					case MONITOR_RGB:
-					case MONITOR_TV:
-						XBIOS_ListFalconRgbModes(this, 1);
-						break;
-					case MONITOR_VGA:
-						XBIOS_ListFalconVgaModes(this, 1);
-						break;
-				}
-
-				if (Getcookie(C_BLOW, &cookie_blow) == C_FOUND) {
-					SDL_XBIOS_ListBlowupModes(this, 1, (blow_cookie_t *)cookie_blow);
-				}
-			}
-			break;
-		case VDO_MILAN:
-			(*XBIOS_listModes)(this, 1);
-			break;
-	}
+	(*XBIOS_listModes)(this, 1);
 
 	XBIOS_screens[0]=NULL;
 	XBIOS_screens[1]=NULL;
@@ -633,7 +469,7 @@
 		}
 	}
 #endif
-	if ((flags & SDL_DOUBLEBUF) && ((XBIOS_cvdo>>16) != VDO_MILAN)) {
+	if (flags & SDL_DOUBLEBUF) {
 		num_buffers = 2;
 		modeflags |= SDL_DOUBLEBUF;
 	}
@@ -682,35 +518,7 @@
 
 #ifndef DEBUG_VIDEO_XBIOS
 	/* Now set the video mode */
-	if ((XBIOS_cvdo>>16) != VDO_MILAN) {
-		Setscreen(-1,XBIOS_screens[0],-1);
-	}
-
-	switch(XBIOS_cvdo >> 16) {
-		case VDO_ST:
-		case VDO_STE:
-			(*XBIOS_setMode)(this, new_video_mode);
-			break;
-		case VDO_TT:
-			(*XBIOS_setMode)(this, new_video_mode);
-			break;
-		case VDO_F30:
-			if (XBIOS_centscreen) {
-				SDL_XBIOS_CentscreenSetmode(this, width, height, new_depth);
-			} else {
-				VsetMode(new_video_mode->number);
-			}
-
-			/* Set hardware palette to black in True Colour */
-			if (new_depth > 8) {
-				SDL_memset(F30_palette, 0, sizeof(F30_palette));
-				VsetRGB(0,256,F30_palette);
-			}
-			break;
-		case VDO_MILAN:
-			(*XBIOS_setMode)(this, new_video_mode);
-			break;
-	}
+	(*XBIOS_setMode)(this, new_video_mode);
 
 	Vsync();
 #endif
@@ -838,30 +646,6 @@
 	return(0);
 }
 
-static int XBIOS_SetColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
-{
-#ifndef DEBUG_VIDEO_XBIOS
-	int		i;
-	int		r,v,b;
-
-	switch( XBIOS_cvdo >> 16) {
-		case VDO_F30:
-			for(i = 0; i < ncolors; i++)
-			{
-				r = colors[i].r;	
-				v = colors[i].g;
-				b = colors[i].b;
-
-				F30_palette[i]=(r<<16)|(v<<8)|b;
-			}
-			VsetRGB(firstcolor,ncolors,F30_palette);
-			break;
-	}
-#endif
-
-	return(1);
-}
-
 /* Note:  If we are terminated, this could be called in the middle of
    another SDL video routine -- notably UpdateRects.
 */
@@ -873,29 +657,8 @@
 
 	/* Restore video mode and palette */
 #ifndef DEBUG_VIDEO_XBIOS
-	switch(XBIOS_cvdo >> 16) {
-		case VDO_ST:
-		case VDO_STE:
-			(*XBIOS_restoreMode)(this);
-			break;
-		case VDO_TT:
-			(*XBIOS_restoreMode)(this);
-			break;
-		case VDO_F30:
-			Setscreen(-1, XBIOS_oldvbase, -1);
-			if (XBIOS_centscreen) {
-				SDL_XBIOS_CentscreenRestore(this, XBIOS_oldvmode);
-			} else {
-				VsetMode(XBIOS_oldvmode);
-			}
-			if (XBIOS_oldnumcol) {
-				VsetRGB(0, XBIOS_oldnumcol, XBIOS_oldpalette);
-			}
-			break;
-		case VDO_MILAN:
-			(*XBIOS_restoreMode)(this);
-			break;
-	}
+	(*XBIOS_restoreMode)(this);
+
 	Vsync();
 #endif
 
--- a/src/video/xbios/SDL_xbios.h	Wed Jul 30 13:30:09 2014 +0200
+++ b/src/video/xbios/SDL_xbios.h	Wed Jul 30 17:34:52 2014 +0200
@@ -46,7 +46,6 @@
 #define NUM_MODELISTS	4		/* 8, 16, 24, and 32 bits-per-pixel */
 
 struct SDL_PrivateVideoData {
-	long cookie_vdo;
 	long old_video_mode;				/* Old video mode before entering SDL */
 	void *old_video_base;			/* Old pointer to screen buffer */
 	void *old_palette;				/* Old palette */
@@ -58,8 +57,6 @@
 	int frame_number;		/* Number of frame for double buffer */
 	int pitch;				/* Destination line width for C2P */
 
-	SDL_bool centscreen;	/* Centscreen extension present ? */
-
 	xbiosmode_t *current;	/* Current set mode */
 	int SDL_nummodes[NUM_MODELISTS];
 	SDL_Rect **SDL_modelist[NUM_MODELISTS];
@@ -103,8 +100,6 @@
 #define SDL_nummodes		(this->hidden->SDL_nummodes)
 #define SDL_modelist		(this->hidden->SDL_modelist)
 #define SDL_xbiosmode		(this->hidden->SDL_xbiosmode)
-#define XBIOS_mutex		    (this->hidden->mutex)
-#define XBIOS_cvdo		    (this->hidden->cookie_vdo)
 #define XBIOS_oldpalette	(this->hidden->old_palette)
 #define XBIOS_oldnumcol		(this->hidden->old_num_colors)
 #define XBIOS_oldvbase		(this->hidden->old_video_base)
@@ -114,7 +109,6 @@
 #define XBIOS_shadowscreen	(this->hidden->shadowscreen)
 #define XBIOS_fbnum			(this->hidden->frame_number)
 #define XBIOS_pitch			(this->hidden->pitch)
-#define XBIOS_centscreen	(this->hidden->centscreen)
 #define XBIOS_current		(this->hidden->current)
 
 #define TT_palette		(this->hidden->palette.pal16)
@@ -138,6 +132,9 @@
 /* SDL_xbios_tt.c */
 void SDL_XBIOS_VideoInit_TT(_THIS);
 
+/* SDL_xbios_f30.c */
+void SDL_XBIOS_VideoInit_F30(_THIS);
+
 /* SDL_xbios_milan.c */
 void SDL_XBIOS_VideoInit_Milan(_THIS);
 
--- a/src/video/xbios/SDL_xbios_centscreen.c	Wed Jul 30 13:30:09 2014 +0200
+++ b/src/video/xbios/SDL_xbios_centscreen.c	Wed Jul 30 17:34:52 2014 +0200
@@ -27,61 +27,87 @@
 	Patrice Mandin
 */
 
+#include <mint/cookie.h>
 #include <mint/falcon.h>
 
 #include "SDL_xbios.h"
 #include "SDL_xbios_centscreen.h"
 
-int SDL_XBIOS_ListCentscreenModes(_THIS, int actually_add)
+static void listModes(_THIS, int actually_add);
+static void saveMode(_THIS, SDL_PixelFormat *vformat);
+static void setMode(_THIS, xbiosmode_t *new_video_mode);
+static void restoreMode(_THIS);
+
+void SDL_XBIOS_VideoInit_Centscreen(_THIS)
+{
+	XBIOS_listModes = listModes;
+	XBIOS_saveMode = saveMode;
+	XBIOS_setMode = setMode;
+	XBIOS_restoreMode = restoreMode;
+}
+
+static void listModes(_THIS, int actually_add)
 {
 	centscreen_mode_t curmode, listedmode;
 	unsigned long result;
-	int cur_handle;	/* Current Centscreen mode handle */
 
 	/* Add Centscreen modes */
 	Vread(&curmode);
-	cur_handle = curmode.handle;
 	curmode.mode = curmode.physx = curmode.physy = curmode.plan =
 		curmode.logx = curmode.logy = -1;
 
 	result = Vfirst(&curmode, &listedmode);
-	if (result==0) {
-		while (result==0) {
-			/* Don't add modes with virtual screen */
-			if ((listedmode.mode & CSCREEN_VIRTUAL)==0) {
-				/* Don't add modes with bpp<8 */
-				if (listedmode.plan>=8) {
-					xbiosmode_t modeinfo;
-
-					modeinfo.number = listedmode.mode;
-					modeinfo.width = listedmode.physx;
-					modeinfo.height = listedmode.physy;
-					modeinfo.depth = listedmode.plan;
-					modeinfo.flags = (modeinfo.depth == 8 ? XBIOSMODE_C2P : 0);
+	while (result==0) {
+		/* Don't add modes with virtual screen */
+		if ((listedmode.mode & CSCREEN_VIRTUAL)==0) {
+			/* Don't add modes with bpp<8 */
+			if (listedmode.plan>=8) {
+				xbiosmode_t modeinfo;
 
-					SDL_XBIOS_AddMode(this, actually_add, &modeinfo);
-				}
+				modeinfo.number = listedmode.mode;
+				modeinfo.width = listedmode.physx;
+				modeinfo.height = listedmode.physy;
+				modeinfo.depth = listedmode.plan;
+				modeinfo.flags = (modeinfo.depth == 8 ? XBIOSMODE_C2P : 0);
+
+				SDL_XBIOS_AddMode(this, actually_add, &modeinfo);
 			}
-			SDL_memcpy(&curmode, &listedmode, sizeof(centscreen_mode_t));
-			curmode.mode = curmode.physx = curmode.physy = curmode.plan =
-				curmode.logx = curmode.logy = -1;
-			result = Vnext(&curmode, &listedmode);
-		}		
-	} else {
-		fprintf(stderr, "No suitable Centscreen modes\n");
-	}
-
-	return cur_handle;
+		}
+		SDL_memcpy(&curmode, &listedmode, sizeof(centscreen_mode_t));
+		curmode.mode = curmode.physx = curmode.physy = curmode.plan =
+			curmode.logx = curmode.logy = -1;
+		result = Vnext(&curmode, &listedmode);
+	}		
 }
 
-void SDL_XBIOS_CentscreenSetmode(_THIS, int width, int height, int planes)
+static void saveMode(_THIS, SDL_PixelFormat *vformat)
+{
+	centscreen_mode_t curmode;
+
+	XBIOS_oldvbase=Physbase();
+
+	Vread(&curmode);
+	XBIOS_oldvmode = curmode.handle;
+
+	XBIOS_oldnumcol= 1<< (1 << (XBIOS_oldvmode & NUMCOLS));
+	if (XBIOS_oldnumcol > 256) {
+		XBIOS_oldnumcol = 256;
+	}
+	if (XBIOS_oldnumcol) {
+		VgetRGB(0, XBIOS_oldnumcol, XBIOS_oldpalette);
+	}
+}
+
+static void setMode(_THIS, xbiosmode_t *new_video_mode)
 {
 	centscreen_mode_t newmode, curmode;
-	
+
+	Setscreen(-1,XBIOS_screens[0],-1);
+
 	newmode.handle = newmode.mode = newmode.logx = newmode.logy = -1;
-	newmode.physx = width;
-	newmode.physy = height;
-	newmode.plan = planes;
+	newmode.physx = new_video_mode->width;
+	newmode.physy = new_video_mode->height;
+	newmode.plan = new_video_mode->depth;
 	Vwrite(0, &newmode, &curmode);
 
 #ifdef SDL_VIDEO_DISABLE_SCREENSAVER
@@ -90,15 +116,26 @@
 	newmode.mode &= ~(CSCREEN_SAVER|CSCREEN_ENERGYSTAR);
 	Vwrite(0, &newmode, &curmode);
 #endif /* SDL_VIDEO_DISABLE_SCREENSAVER */
+
+	/* Set hardware palette to black in True Colour */
+	if (new_video_mode->depth > 8) {
+		SDL_memset(F30_palette, 0, sizeof(F30_palette));
+		VsetRGB(0,256,F30_palette);
+	}
 }
 
-void SDL_XBIOS_CentscreenRestore(_THIS, int prev_handle)
+static void restoreMode(_THIS)
 {
 	centscreen_mode_t newmode, curmode;
 
-	/* Restore old video mode */
-	newmode.handle = prev_handle;
+	Setscreen(-1,XBIOS_oldvbase,-1);
+
+	newmode.handle = XBIOS_oldvmode;
 	newmode.mode = newmode.physx = newmode.physy = newmode.plan =
 		newmode.logx = newmode.logy = -1;
 	Vwrite(0, &newmode, &curmode);
+
+	if (XBIOS_oldnumcol) {
+		VsetRGB(0, XBIOS_oldnumcol, XBIOS_oldpalette);
+	}
 }
--- a/src/video/xbios/SDL_xbios_centscreen.h	Wed Jul 30 13:30:09 2014 +0200
+++ b/src/video/xbios/SDL_xbios_centscreen.h	Wed Jul 30 17:34:52 2014 +0200
@@ -107,8 +107,6 @@
 
 /*--- Functions prototypes ---*/
 
-int SDL_XBIOS_ListCentscreenModes(_THIS, int actually_add);
-void SDL_XBIOS_CentscreenSetmode(_THIS, int width, int height, int planes);
-void SDL_XBIOS_CentscreenRestore(_THIS, int prev_handle);
+void SDL_XBIOS_VideoInit_Centscreen(_THIS);
 
 #endif /* _SDL_xbios_centscreen_h */
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/video/xbios/SDL_xbios_f30.c	Wed Jul 30 17:34:52 2014 +0200
@@ -0,0 +1,179 @@
+/*
+    SDL - Simple DirectMedia Layer
+    Copyright (C) 1997-2012 Sam Lantinga
+
+    This library is free software; you can redistribute it and/or
+    modify it under the terms of the GNU Library General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later version.
+
+    This library is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+    Library General Public License for more details.
+
+    You should have received a copy of the GNU Library General Public
+    License along with this library; if not, write to the Free
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+    Sam Lantinga
+    slouken@libsdl.org
+*/
+#include "SDL_config.h"
+
+/*
+	Falcon Xbios video functions
+
+	Patrice Mandin
+*/
+
+#include <mint/cookie.h>
+#include <mint/osbind.h>
+#include <mint/falcon.h>
+
+#include "SDL_xbios.h"
+#include "SDL_xbios_blowup.h"
+#include "SDL_xbios_sb3.h"
+#include "SDL_xbios_centscreen.h"
+
+static const xbiosmode_t rgb_modes[]={
+	{BPS16|COL80|OVERSCAN|VERTFLAG,768,480,16,0},
+	{BPS16|COL80|OVERSCAN,768,240,16,0},
+	{BPS16|COL80|VERTFLAG,640,400,16,0},
+	{BPS16|COL80,640,200,16,0},
+	{BPS16|OVERSCAN|VERTFLAG,384,480,16,0},
+	{BPS16|OVERSCAN,384,240,16,0},
+	{BPS16|VERTFLAG,320,400,16,0},
+	{BPS16,320,200,16,0},
+	{BPS8|COL80|OVERSCAN|VERTFLAG,768,480,8,XBIOSMODE_C2P},
+	{BPS8|COL80|OVERSCAN,768,240,8,XBIOSMODE_C2P},
+	{BPS8|COL80|VERTFLAG,640,400,8,XBIOSMODE_C2P},
+	{BPS8|COL80,640,200,8,XBIOSMODE_C2P},
+	{BPS8|OVERSCAN|VERTFLAG,384,480,8,XBIOSMODE_C2P},
+	{BPS8|OVERSCAN,384,240,8,XBIOSMODE_C2P},
+	{BPS8|VERTFLAG,320,400,8,XBIOSMODE_C2P},
+	{BPS8,320,200,8,XBIOSMODE_C2P}
+};
+
+static const xbiosmode_t vga_modes[]={
+	{BPS16,320,480,16,0},
+	{BPS16|VERTFLAG,320,240,16,0},
+	{BPS8|COL80,640,480,8,XBIOSMODE_C2P},
+	{BPS8|COL80|VERTFLAG,640,240,8,XBIOSMODE_C2P},
+	{BPS8,320,480,8,XBIOSMODE_C2P},
+	{BPS8|VERTFLAG,320,240,8,XBIOSMODE_C2P}
+};
+
+static void listModes(_THIS, int actually_add);
+static void saveMode(_THIS, SDL_PixelFormat *vformat);
+static void setMode(_THIS, xbiosmode_t *new_video_mode);
+static void restoreMode(_THIS);
+static int setColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);
+
+void SDL_XBIOS_VideoInit_F30(_THIS)
+{
+	long cookie_cnts, cookie_scpn;
+
+	XBIOS_listModes = listModes;
+	XBIOS_saveMode = saveMode;
+	XBIOS_setMode = setMode;
+	XBIOS_restoreMode = restoreMode;
+
+	this->SetColors = setColors;
+
+	/* ScreenBlaster 3 ? */
+	if (Getcookie(C_SCPN, &cookie_scpn) == C_FOUND) {
+		SDL_XBIOS_VideoInit_SB3(this);
+	} else
+	/* Centscreen ? */
+	if (Getcookie(C_CNTS, &cookie_cnts) == C_FOUND) {
+		SDL_XBIOS_VideoInit_Centscreen(this);
+	}
+}
+
+static void listModes(_THIS, int actually_add)
+{
+	long cookie_blow;
+	int i, max_modes = 0;
+	const xbiosmode_t *f30_modes = NULL;
+	xbiosmode_t modeinfo;
+
+	switch (VgetMonitor()) {
+		case MONITOR_RGB:
+		case MONITOR_TV:
+			max_modes = sizeof(rgb_modes)/sizeof(xbiosmode_t);
+			f30_modes = rgb_modes;
+			break;
+		case MONITOR_VGA:
+			max_modes = sizeof(vga_modes)/sizeof(xbiosmode_t);
+			f30_modes = vga_modes;
+			break;
+	}
+
+	for (i=0; i<max_modes; i++) {
+		SDL_memcpy(&modeinfo, &f30_modes[i], sizeof(xbiosmode_t));
+		modeinfo.number &= ~(VGA|PAL);
+		modeinfo.number |= XBIOS_oldvmode & (VGA|PAL);
+
+		SDL_XBIOS_AddMode(this, actually_add, &modeinfo);
+	}
+
+	if (Getcookie(C_BLOW, &cookie_blow) == C_FOUND) {
+		SDL_XBIOS_ListBlowupModes(this, actually_add, (blow_cookie_t *)cookie_blow);
+	}
+}
+
+static void saveMode(_THIS, SDL_PixelFormat *vformat)
+{
+	XBIOS_oldvbase=Physbase();
+
+	XBIOS_oldvmode=VsetMode(-1);
+
+	XBIOS_oldnumcol= 1<< (1 << (XBIOS_oldvmode & NUMCOLS));
+	if (XBIOS_oldnumcol > 256) {
+		XBIOS_oldnumcol = 256;
+	}
+	if (XBIOS_oldnumcol) {
+		VgetRGB(0, XBIOS_oldnumcol, XBIOS_oldpalette);
+	}
+}
+
+static void setMode(_THIS, xbiosmode_t *new_video_mode)
+{
+	Setscreen(-1,XBIOS_screens[0],-1);
+
+	VsetMode(new_video_mode->number);
+
+	/* Set hardware palette to black in True Colour */
+	if (new_video_mode->depth > 8) {
+		SDL_memset(F30_palette, 0, sizeof(F30_palette));
+		VsetRGB(0,256,F30_palette);
+	}
+}
+
+static void restoreMode(_THIS)
+{
+	Setscreen(-1,XBIOS_oldvbase,-1);
+
+	VsetMode(XBIOS_oldvmode);
+
+	if (XBIOS_oldnumcol) {
+		VsetRGB(0, XBIOS_oldnumcol, XBIOS_oldpalette);
+	}
+}
+
+static int setColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors)
+{
+	int i, r,g,b;
+
+	for(i = 0; i < ncolors; i++) {
+		r = colors[i].r;	
+		g = colors[i].g;
+		b = colors[i].b;
+
+		F30_palette[i]=(r<<16)|(g<<8)|b;
+	}
+	VsetRGB(firstcolor,ncolors,F30_palette);
+
+	return 1;
+}
--- a/src/video/xbios/SDL_xbios_sb3.c	Wed Jul 30 13:30:09 2014 +0200
+++ b/src/video/xbios/SDL_xbios_sb3.c	Wed Jul 30 17:34:52 2014 +0200
@@ -29,6 +29,10 @@
 
 /*--- Includes ---*/
 
+#include <mint/cookie.h>
+#include <mint/osbind.h>
+#include <mint/falcon.h>
+
 #include "SDL_stdinc.h"
 #include "SDL_xbios.h"
 #include "SDL_xbios_sb3.h"
@@ -47,6 +51,10 @@
 
 /*--- Functions ---*/
 
+static void listModes(_THIS, int actually_add);
+static void setMode(_THIS, xbiosmode_t *new_video_mode);
+static void restoreMode(_THIS);
+
 int SDL_XBIOS_SB3Usable(scpn_cookie_t *cookie_scpn)
 {
 	scpn_screeninfo_t *scrinfo;
@@ -63,21 +71,53 @@
 	return 0;
 }
 
-void SDL_XBIOS_ListSB3Modes(_THIS, int actually_add, scpn_cookie_t *cookie_scpn)
+void SDL_XBIOS_VideoInit_SB3(_THIS)
 {
+	XBIOS_listModes = listModes;
+	XBIOS_setMode = setMode;
+	XBIOS_restoreMode = restoreMode;
+}
+
+static void listModes(_THIS, int actually_add)
+{
+	long cookie_scpn;
 	scpn_screeninfo_t *scrinfo;
 	xbiosmode_t modeinfo;
 
-	scrinfo = cookie_scpn->screen_info;
-	if (actually_add) {
-		scrinfo->h_pos = scrinfo->v_pos = 0;
+	if (Getcookie(C_SCPN, &cookie_scpn) == C_FOUND) {
+		scrinfo = ((scpn_cookie_t *) cookie_scpn)->screen_info;
+		if (actually_add) {
+			scrinfo->h_pos = scrinfo->v_pos = 0;
+		}
+
+		modeinfo.number = -1;
+		modeinfo.width = scrinfo->virtual_width;
+		modeinfo.height = scrinfo->virtual_height;
+		modeinfo.depth = 1<<(SDL_XBIOS_scpn_planes_device[scrinfo->device]);
+		modeinfo.flags = (modeinfo.depth == 8 ? XBIOSMODE_C2P : 0);
+
+		SDL_XBIOS_AddMode(this, actually_add, &modeinfo);
 	}
+}
 
-	modeinfo.number = -1;
-	modeinfo.width = scrinfo->virtual_width;
-	modeinfo.height = scrinfo->virtual_height;
-	modeinfo.depth = 1<<(SDL_XBIOS_scpn_planes_device[scrinfo->device]);
-	modeinfo.flags = (modeinfo.depth == 8 ? XBIOSMODE_C2P : 0);
+static void setMode(_THIS, xbiosmode_t *new_video_mode)
+{
+	/* SB3 do not allow changing video mode */
+	Setscreen(-1,XBIOS_screens[0],-1);
 
-	SDL_XBIOS_AddMode(this, actually_add, &modeinfo);
+	/* Set hardware palette to black in True Colour */
+	if (new_video_mode->depth > 8) {
+		SDL_memset(F30_palette, 0, sizeof(F30_palette));
+		VsetRGB(0,256,F30_palette);
+	}
 }
+
+static void restoreMode(_THIS)
+{
+	/* SB3 do not allow changing video mode */
+	Setscreen(-1, XBIOS_oldvbase, -1);
+
+	if (XBIOS_oldnumcol) {
+		VsetRGB(0, XBIOS_oldnumcol, XBIOS_oldpalette);
+	}
+}
--- a/src/video/xbios/SDL_xbios_sb3.h	Wed Jul 30 13:30:09 2014 +0200
+++ b/src/video/xbios/SDL_xbios_sb3.h	Wed Jul 30 17:34:52 2014 +0200
@@ -77,6 +77,6 @@
 
 int SDL_XBIOS_SB3Usable(scpn_cookie_t *cookie_scpn);
 
-void SDL_XBIOS_ListSB3Modes(_THIS, int actually_add, scpn_cookie_t *cookie_scpn);
+void SDL_XBIOS_VideoInit_SB3(_THIS);
 
 #endif /* _SDL_xbios_sb3_h_ */