Skip to content
Permalink
Browse files

atari:xbios: Add CTPCI backend.

  • Loading branch information
pmandin committed Jul 30, 2014
1 parent 76af310 commit 3de5d5b5c9bbabd914b907f6043c28b8071bc9f0
Showing with 337 additions and 6 deletions.
  1. +3 −5 src/video/xbios/SDL_xbios.c
  2. +3 −0 src/video/xbios/SDL_xbios.h
  3. +323 −0 src/video/xbios/SDL_xbios_ctpci.c
  4. +8 −1 src/video/xbios/SDL_xbios_f30.c
@@ -181,7 +181,7 @@ static SDL_VideoDevice *XBIOS_CreateDevice(int devindex)
device->ListModes = XBIOS_ListModes;
device->SetVideoMode = XBIOS_SetVideoMode;
device->SetColors = NULL; /* Defined by each device specific backend */
device->UpdateRects = NULL;
device->UpdateRects = XBIOS_UpdateRects;
device->VideoQuit = XBIOS_VideoQuit;
device->AllocHWSurface = XBIOS_AllocHWSurface;
device->LockHWSurface = XBIOS_LockHWSurface;
@@ -394,7 +394,7 @@ static void XBIOS_FreeBuffers(_THIS)
{
(*XBIOS_freeVbuffers)(this);

if (XBIOS_shadowscreen!=NULL) {
if (XBIOS_shadowscreen) {
Mfree(XBIOS_shadowscreen);
XBIOS_shadowscreen=NULL;
}
@@ -495,7 +495,7 @@ static SDL_Surface *XBIOS_SetVideoMode(_THIS, SDL_Surface *current,
/* this is for C2P conversion */
XBIOS_pitch = (new_video_mode->width * new_video_mode->depth)>>3;

if (new_video_mode->flags & XBIOSMODE_C2P)
if (XBIOS_shadowscreen)
current->pixels = XBIOS_shadowscreen;
else
current->pixels = XBIOS_screens[0];
@@ -523,8 +523,6 @@ static SDL_Surface *XBIOS_SetVideoMode(_THIS, SDL_Surface *current,
Vsync();
#endif

this->UpdateRects = XBIOS_UpdateRects;

return (current);
}

@@ -138,4 +138,7 @@ void SDL_XBIOS_VideoInit_F30(_THIS);
/* SDL_xbios_milan.c */
void SDL_XBIOS_VideoInit_Milan(_THIS);

/* SDL_xbios_ctpci.c */
void SDL_XBIOS_VideoInit_Ctpci(_THIS);

#endif /* _SDL_xbios_h */
@@ -0,0 +1,323 @@
/*
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"

/*
CTPCI Xbios video functions
Pawel Goralski
Patrice Mandin
*/

#include <mint/cookie.h>
#include <mint/osbind.h>
#include <mint/falcon.h>

#include "../SDL_sysvideo.h"

#include "../ataricommon/SDL_atarimxalloc_c.h"

#include "SDL_xbios.h"
#include "SDL_xbios_milan.h"

/* use predefined, hardcoded table if CTPCI_USE_TABLE == 1
else enumerate all non virtual video modes */
#define CTPCI_USE_TABLE 1

typedef struct {
Uint16 modecode, width, height;
} predefined_mode_t;

static const predefined_mode_t mode_list[]={
{0x4260,320,200},
{0x4270,320,240},
{0x4138,640,480},
{0x4160,800,600},
{0x4188,1024,768},
{0x42c8,1280,800},
{0x41e0,1280,1024},
{0x4210,1600,1200}
};

static const Uint8 mode_bpp[]={
8, 16, 32
};

/*--- Variables ---*/

static int enum_actually_add;
static SDL_VideoDevice *enum_this;

/*--- Functions ---*/

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 void swapVbuffers(_THIS);
static int allocVbuffers(_THIS, int num_buffers, int bufsize);
static void freeVbuffers(_THIS);
static void updateRects(_THIS, int numrects, SDL_Rect *rects);
static int flipHWSurface(_THIS, SDL_Surface *surface);

void SDL_XBIOS_VideoInit_Ctpci(_THIS)
{
XBIOS_listModes = listModes;
XBIOS_saveMode = saveMode;
XBIOS_setMode = setMode;
XBIOS_restoreMode = restoreMode;
XBIOS_swapVbuffers = swapVbuffers;
XBIOS_allocVbuffers = allocVbuffers;
XBIOS_freeVbuffers = freeVbuffers;

this->UpdateRects = updateRects;
this->FlipHWSurface = flipHWSurface;
}

static unsigned long /*cdecl*/ enumfunc(SCREENINFO *inf, unsigned long flag)
{
xbiosmode_t modeinfo;

modeinfo.number = inf->devID;
modeinfo.width = inf->scrWidth;
modeinfo.height = inf->scrHeight;
modeinfo.depth = inf->scrPlanes;
modeinfo.flags = 0;

SDL_XBIOS_AddMode(enum_this, enum_actually_add, &modeinfo);

return ENUMMODE_CONT;
}

static void listModes(_THIS, int actually_add)
{
#ifdef CTPCI_USE_TABLE
int i;

/* Read validated predefined modes */
for (i=0; i<sizeof(mode_list)/sizeof(predefined_mode_t); i++) {
int j;
Uint16 deviceid = mode_list[i].modecode;

for (j=3; j<5; j++) {
if (Validmode(deviceid + j)) {
xbiosmode_t modeinfo;

modeinfo.number = deviceid + j;
modeinfo.width = mode_list[i].width;
modeinfo.height = mode_list[i].height;
modeinfo.depth = mode_bpp[j-3];
modeinfo.flags = 0;

SDL_XBIOS_AddMode(this, actually_add, &modeinfo);
}
}
}
#else
/* Read custom created modes */
enum_this = this;
enum_actually_add = actually_add;
VsetScreen(-1, &enumfunc, VN_MAGIC, CMD_ENUMMODES);
#endif
}

static void saveMode(_THIS, SDL_PixelFormat *vformat)
{
SCREENINFO si;

/* Read infos about current mode */
VsetScreen(-1, &XBIOS_oldvmode, VN_MAGIC, CMD_GETMODE);

si.size = sizeof(SCREENINFO);
si.devID = XBIOS_oldvmode;
si.scrFlags = 0;
VsetScreen(-1, &si, VN_MAGIC, CMD_GETINFO);

this->info.current_w = si.scrWidth;
this->info.current_h = si.scrHeight;

vformat->BitsPerPixel = si.scrPlanes;

XBIOS_oldnumcol = 0;
if (si.scrFlags & SCRINFO_OK) {
if (si.scrPlanes <= 8) {
XBIOS_oldnumcol = 1<<si.scrPlanes;
}
}
if (XBIOS_oldnumcol) {
VgetRGB(0, XBIOS_oldnumcol, XBIOS_oldpalette);
}
}

static void setMode(_THIS, xbiosmode_t *new_video_mode)
{
SCREENINFO si;

VsetScreen(-1, XBIOS_screens[0], VN_MAGIC, CMD_SETADR);

VsetScreen(-1, new_video_mode->number, VN_MAGIC, CMD_SETMODE);

/* 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);
}

/* Set pitch of new mode */
si.size = sizeof(SCREENINFO);
si.devID = new_video_mode->number;
si.scrFlags = 0;
VsetScreen(-1, &si, VN_MAGIC, CMD_GETINFO);
if (si.scrFlags & SCRINFO_OK) {
XBIOS_pitch = si.lineWrap;
}
}

static void restoreMode(_THIS)
{
VsetScreen(-1, &XBIOS_oldvbase, VN_MAGIC, CMD_SETADR);
VsetScreen(-1, &XBIOS_oldvmode, VN_MAGIC, CMD_SETMODE);
if (XBIOS_oldnumcol) {
VsetRGB(0, XBIOS_oldnumcol, XBIOS_oldpalette);
}
}

static void swapVbuffers(_THIS)
{
VsetScreen(-1, XBIOS_screens[XBIOS_fbnum], VN_MAGIC, CMD_SETADR);
}

static int allocVbuffers(_THIS, int num_buffers, int bufsize)
{
int i;

for (i=0; i<num_buffers; i++) {
if (i==0) {
/* Buffer 0 is current screen */
XBIOS_screensmem[i] = XBIOS_oldvbase;
} else {
VsetScreen(-1, &XBIOS_screensmem[i], VN_MAGIC, CMD_ALLOCPAGE);
}

if (!XBIOS_screensmem[i]) {
SDL_SetError("Can not allocate %d KB for buffer %d", bufsize>>10, i);
return (0);
}
SDL_memset(XBIOS_screensmem[i], 0, bufsize);

XBIOS_screens[i]=XBIOS_screensmem[i];
}

/*--- Always use shadow buffer ---*/
if (XBIOS_shadowscreen) {
Mfree(XBIOS_shadowscreen);
XBIOS_shadowscreen=NULL;
}

/* allocate shadow buffer in TT-RAM, blitting directly to screen is
damn slow, send postcards to R.Czuba for fixing TT-RAM->CTPCI burst
mode */
XBIOS_shadowscreen = Atari_SysMalloc(bufsize, MX_PREFTTRAM);

if (XBIOS_shadowscreen == NULL) {
SDL_SetError("Can not allocate %d KB for shadow buffer", bufsize>>10);
return (0);
}
SDL_memset(XBIOS_shadowscreen, 0, bufsize);

return (1);
}

static void freeVbuffers(_THIS)
{
int i;

for (i=0;i<2;i++) {
if (XBIOS_screensmem[i]) {
if (i==1) {
VsetScreen(-1, -1, VN_MAGIC, CMD_FREEPAGE);
} else {
/* Do not touch buffer 0 */
}
XBIOS_screensmem[i]=NULL;
}
}
}

static void updateRects(_THIS, int numrects, SDL_Rect *rects)
{
SDL_Surface *surface;
int i;
/*unsigned long offset,size;*/

surface = this->screen;

/* Center on destination screen */
/*offset=XBIOS_pitch * ((newScreenInfo.virtHeight - surface->h) >> 1);
offset=offset+(newScreenInfo.scrPlanes>>3)*((newScreenInfo.virtWidth - surface->w) >> 1);
destscr = (void *)((unsigned long)destscr+offset);*/

for (i=0;i<numrects;i++) {
Uint8 *blockSrcStart, *blockDstStart;
int y;

blockSrcStart = (Uint8 *) surface->pixels;
blockSrcStart += surface->pitch*rects[i].y;
blockSrcStart += surface->format->BytesPerPixel*rects[i].x;

blockDstStart = (Uint8 *) XBIOS_screens[XBIOS_fbnum];
blockDstStart += XBIOS_pitch*rects[i].y;
blockDstStart += surface->format->BytesPerPixel*rects[i].x;

for(y=0;y<rects[i].h;y++){
SDL_memcpy(blockDstStart,blockSrcStart,surface->pitch);

blockSrcStart += surface->pitch;
blockDstStart += XBIOS_pitch;
}
}

Vsync();

if ((surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) {
XBIOS_fbnum ^= 1;
}
}

static int flipHWSurface(_THIS, SDL_Surface *surface)
{
/* Center on destination screen */
/*offset=XBIOS_pitch * ((newScreenInfo.virtHeight - surface->h) >> 1);
offset=offset+(newScreenInfo.scrPlanes>>3)*((newScreenInfo.virtWidth - surface->w) >> 1);
destscr = (void *)((unsigned long)destscr+offset);*/

SDL_memcpy(XBIOS_screens[XBIOS_fbnum], surface->pixels, surface->h * surface->pitch);

VsetScreen(-1L, -1L, VN_MAGIC, CMD_FLIPPAGE);
Vsync();

if ((surface->flags & SDL_DOUBLEBUF) == SDL_DOUBLEBUF) {
XBIOS_fbnum ^= 1;
}

return(0);
}
@@ -72,7 +72,7 @@ static int setColors(_THIS, int firstcolor, int ncolors, SDL_Color *colors);

void SDL_XBIOS_VideoInit_F30(_THIS)
{
long cookie_cnts, cookie_scpn;
long cookie_cnts, cookie_scpn, cookie_dummy;

XBIOS_listModes = listModes;
XBIOS_saveMode = saveMode;
@@ -81,6 +81,13 @@ void SDL_XBIOS_VideoInit_F30(_THIS)

this->SetColors = setColors;

/* CTPCI ? */
if ((Getcookie(C_CT60, &cookie_dummy) == C_FOUND)
&& (Getcookie(C__PCI, &cookie_dummy) == C_FOUND)
&& ((unsigned long)Physbase()>=0x01000000UL))
{
SDL_XBIOS_VideoInit_Ctpci(this);
} else
/* ScreenBlaster 3 ? */
if (Getcookie(C_SCPN, &cookie_scpn) == C_FOUND) {
SDL_XBIOS_VideoInit_SB3(this);

0 comments on commit 3de5d5b

Please sign in to comment.