Promoted newest 3dfx video driver by Gerald Zajac in place of the outdated tdfx driver.
Added to Haiku image. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@37294 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
e4eb2e7e45
commit
307ff45454
@ -117,6 +117,7 @@ SYSTEM_ADD_ONS_ACCELERANTS = $(X86_ONLY)radeon.accelerant
|
||||
$(X86_ONLY)neomagic.accelerant $(X86_ONLY)intel_extreme.accelerant
|
||||
$(X86_ONLY)s3.accelerant $(X86_ONLY)vesa.accelerant
|
||||
$(X86_ONLY)ati.accelerant
|
||||
$(X86_ONLY)3dfx.accelerant
|
||||
#$(X86_ONLY)via.accelerant
|
||||
#$(X86_ONLY)vmware.accelerant
|
||||
;
|
||||
@ -162,7 +163,7 @@ SYSTEM_ADD_ONS_DRIVERS_AUDIO_OLD = ; #cmedia sis7018 usb_audio ;
|
||||
SYSTEM_ADD_ONS_DRIVERS_GRAPHICS = $(X86_ONLY)radeon $(X86_ONLY)nvidia
|
||||
$(X86_ONLY)neomagic $(X86_ONLY)matrox $(X86_ONLY)intel_extreme
|
||||
$(X86_ONLY)s3 $(X86_ONLY)vesa #$(X86_ONLY)via #$(X86_ONLY)vmware
|
||||
$(X86_ONLY)ati
|
||||
$(X86_ONLY)ati $(X86_ONLY)3dfx
|
||||
;
|
||||
SYSTEM_ADD_ONS_DRIVERS_MIDI = emuxki usb_midi ;
|
||||
SYSTEM_ADD_ONS_DRIVERS_NET = $(X86_ONLY)3com $(X86_ONLY)atheros813x
|
||||
|
@ -1,188 +0,0 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
*/
|
||||
|
||||
#ifndef DRIVERINTERFACE_H
|
||||
#define DRIVERINTERFACE_H
|
||||
|
||||
#include <Accelerant.h>
|
||||
#include <Drivers.h>
|
||||
#include <PCI.h>
|
||||
#include <OS.h>
|
||||
|
||||
/*
|
||||
This is the info that needs to be shared between the kernel driver and
|
||||
the accelerant for the sample driver.
|
||||
*/
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define MAXBUFFERS 8
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16 slopspace;
|
||||
uint32 size;
|
||||
} int_buf_info;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
sem_id sem;
|
||||
int32 ben;
|
||||
} benaphore;
|
||||
|
||||
#define INIT_BEN(x) x.sem = create_sem(0, "VOODOO "#x" benaphore"); x.ben = 0;
|
||||
#define AQUIRE_BEN(x) if((atomic_add(&(x.ben), 1)) >= 1) acquire_sem(x.sem);
|
||||
#define RELEASE_BEN(x) if((atomic_add(&(x.ben), -1)) > 1) release_sem(x.sem);
|
||||
#define DELETE_BEN(x) delete_sem(x.sem);
|
||||
|
||||
|
||||
#define VOODOO_PRIVATE_DATA_MAGIC 0x1234 /* a private driver rev, of sorts */
|
||||
|
||||
#define MAX_VOODOO_DEVICE_NAME_LENGTH 32
|
||||
|
||||
#define SKD_MOVE_CURSOR 0x00000001
|
||||
#define SKD_PROGRAM_CLUT 0x00000002
|
||||
#define SKD_SET_START_ADDR 0x00000004
|
||||
#define SKD_SET_CURSOR 0x00000008
|
||||
#define SKD_HANDLER_INSTALLED 0x80000000
|
||||
|
||||
enum
|
||||
{
|
||||
VOODOO_GET_PRIVATE_DATA = B_DEVICE_OP_CODES_END + 1,
|
||||
VOODOO_GET_PCI,
|
||||
VOODOO_SET_PCI,
|
||||
VOODOO_DEVICE_NAME,
|
||||
VOODOO_RUN_INTERRUPTS,
|
||||
VOODOO_DPRINTF,
|
||||
VOODOO_INB,
|
||||
VOODOO_INW,
|
||||
VOODOO_INL,
|
||||
VOODOO_OUTB,
|
||||
VOODOO_OUTW,
|
||||
VOODOO_OUTL
|
||||
};
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint16 vendor_id; /* PCI vendor ID, from pci_info */
|
||||
uint16 device_id; /* PCI device ID, from pci_info */
|
||||
uint8 revision; /* PCI device revsion, from pci_info */
|
||||
uint32 iobase; /* PCI IOBase */
|
||||
|
||||
area_id regs_area; /* Kernel's area_id for the memory mapped registers.
|
||||
It will be cloned into the accelerant's address
|
||||
space. */
|
||||
area_id fb_area; /* Frame buffer's area_id. The addresses are shared
|
||||
with all teams. */
|
||||
void *framebuffer; /* As viewed from virtual memory */
|
||||
void *framebuffer_pci; /* As viewed from the PCI bus (for DMA) */
|
||||
|
||||
area_id io_area; /* Mapped ROM's area_id */
|
||||
uint32 io; /* As viewed from virtual memory. Shared by all teams */
|
||||
area_id mode_area; /* Contains the list of display modes the driver supports */
|
||||
uint32 mode_count; /* Number of display modes in the list */
|
||||
sem_id vblank; /* The vertical blank semaphore. Ownership will be
|
||||
transfered to the team opening the device first */
|
||||
int32 flags;
|
||||
int32 start_addr;
|
||||
|
||||
struct
|
||||
{
|
||||
uint8* data; /* Pointer into the frame buffer to where the
|
||||
cursor data starts */
|
||||
uint16 hot_x; /* Cursor hot spot. The top left corner of the cursor */
|
||||
uint16 hot_y; /* is 0,0 */
|
||||
uint16 x; /* The location of the cursor hot spot on the */
|
||||
uint16 y; /* display (or desktop?) */
|
||||
uint16 width; /* Width and height of the cursor shape */
|
||||
uint16 height;
|
||||
bool is_visible; /* Is the cursor currently displayed? */
|
||||
} cursor;
|
||||
uint16 first_color;
|
||||
uint16 color_count;
|
||||
bigtime_t refresh_period; /* Duration of one frame (ie 1/refresh rate) */
|
||||
bigtime_t blank_period; /* Duration of the blanking period. These are
|
||||
usefull when faking vertical blanking
|
||||
interrupts. */
|
||||
uint8 color_data[3 * 256]; /* */
|
||||
uint8 cursor0[64*64/8]; /* AND mask for a 64x64 cursor */
|
||||
uint8 cursor1[512]; /* XOR mask for a 64x64 cursor */
|
||||
display_mode dm; /* current display mode configuration */
|
||||
frame_buffer_config
|
||||
fbc; /* bytes_per_row and start of frame buffer */
|
||||
struct
|
||||
{
|
||||
uint64 count; /* last fifo slot used */
|
||||
uint64 last_idle; /* last fifo slot we *know* the engine was idle after */
|
||||
benaphore lock; /* for serializing access to the acceleration engine */
|
||||
} engine;
|
||||
|
||||
struct
|
||||
{
|
||||
overlay_buffer myBuffer[MAXBUFFERS]; /* scaler input buffers */
|
||||
int_buf_info myBufInfo[MAXBUFFERS]; /* extra info on scaler input buffers */
|
||||
overlay_token myToken; /* scaler is free/in use */
|
||||
benaphore lock; /* for creating buffers and aquiring overlay unit routines */
|
||||
} overlay;
|
||||
|
||||
uint32 pix_clk_max8; /* The maximum speed the pixel clock should run */
|
||||
uint32 pix_clk_max16; /* at for a given pixel width. Usually a function */
|
||||
uint32 pix_clk_max32; /* of memory and DAC bandwidths. */
|
||||
uint32 mem_size; /* Frame buffer memory, in bytes. */
|
||||
|
||||
|
||||
} shared_info;
|
||||
|
||||
/* Read or write a value in PCI configuration space */
|
||||
typedef struct
|
||||
{
|
||||
uint32 magic; /* magic number to make sure the caller groks us */
|
||||
uint32 offset; /* Offset to read/write */
|
||||
uint32 size; /* Number of bytes to transfer */
|
||||
uint32 value; /* The value read or written */
|
||||
} voodoo_get_set_pci;
|
||||
|
||||
/* Set some boolean condition (like enabling or disabling interrupts) */
|
||||
typedef struct
|
||||
{
|
||||
uint32 magic; /* magic number to make sure the caller groks us */
|
||||
bool do_it; /* state to set */
|
||||
} voodoo_set_bool_state;
|
||||
|
||||
/* Retrieve the area_id of the kernel/accelerant shared info */
|
||||
typedef struct
|
||||
{
|
||||
uint32 magic; /* magic number to make sure the caller groks us */
|
||||
area_id shared_info_area; /* area_id containing the shared information */
|
||||
} voodoo_get_private_data;
|
||||
|
||||
/* Retrieve the device name. Usefull for when we have a file handle, but want
|
||||
to know the device name (like when we are cloning the accelerant) */
|
||||
typedef struct
|
||||
{
|
||||
uint32 magic; /* magic number to make sure the caller groks us */
|
||||
char *name; /* The name of the device, less the /dev root */
|
||||
} voodoo_device_name;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint32 port;
|
||||
uint8 data8;
|
||||
uint16 data16;
|
||||
uint32 data32;
|
||||
} voodoo_port_io;
|
||||
|
||||
enum
|
||||
{
|
||||
VOODOO_WAIT_FOR_VBLANK = (1 << 0)
|
||||
};
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
@ -12,7 +12,6 @@ SubInclude HAIKU_TOP src add-ons accelerants nvidia ;
|
||||
SubInclude HAIKU_TOP src add-ons accelerants radeon ;
|
||||
SubInclude HAIKU_TOP src add-ons accelerants radeon_hd ;
|
||||
SubInclude HAIKU_TOP src add-ons accelerants s3 ;
|
||||
SubInclude HAIKU_TOP src add-ons accelerants tdfx ;
|
||||
SubInclude HAIKU_TOP src add-ons accelerants vesa ;
|
||||
SubInclude HAIKU_TOP src add-ons accelerants via ;
|
||||
SubInclude HAIKU_TOP src add-ons accelerants vmware ;
|
||||
|
@ -1,93 +0,0 @@
|
||||
/*
|
||||
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
|
||||
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
|
||||
|
||||
*/
|
||||
|
||||
#include "GlobalData.h"
|
||||
#include "generic.h"
|
||||
#include "voodoo3_accelerant.h"
|
||||
|
||||
void
|
||||
SCREEN_TO_SCREEN_BLIT (
|
||||
engine_token *et, blit_params *list, uint32 count)
|
||||
{
|
||||
uint32 stride, bpp;
|
||||
stride = si->fbc.bytes_per_row;
|
||||
bpp = voodoo3_bits_per_pixel();
|
||||
|
||||
while (count--)
|
||||
{
|
||||
list_packet_blit packet;
|
||||
packet.src_x = list->src_left;
|
||||
packet.src_y = list->src_top;
|
||||
packet.dest_x = list->dest_left;
|
||||
packet.dest_y = list->dest_top;
|
||||
packet.width = list->width + 1;
|
||||
packet.height = list->height + 1;
|
||||
|
||||
voodoo3_screen_to_screen_blit(&packet, stride, bpp);
|
||||
list ++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FILL_RECTANGLE (
|
||||
engine_token *et, uint32 color, fill_rect_params *list, uint32 count)
|
||||
{
|
||||
uint32 stride, bpp;
|
||||
stride = si->fbc.bytes_per_row;
|
||||
bpp = voodoo3_bits_per_pixel();
|
||||
|
||||
while (count--)
|
||||
{
|
||||
list_packet packet;
|
||||
packet.x = list->left;
|
||||
packet.y = list->top;
|
||||
packet.w = list->right - packet.x + 1;
|
||||
packet.h = list->bottom - packet.y + 1;
|
||||
voodoo3_fill_rect(&packet, color, stride, bpp);
|
||||
list++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
INVERT_RECTANGLE (
|
||||
engine_token *et, fill_rect_params *list, uint32 count)
|
||||
{
|
||||
uint32 stride, bpp, color;
|
||||
stride = si->fbc.bytes_per_row;
|
||||
bpp = voodoo3_bits_per_pixel();
|
||||
color = 0;
|
||||
|
||||
while (count--)
|
||||
{
|
||||
list_packet packet;
|
||||
packet.x = list->left;
|
||||
packet.y = list->top;
|
||||
packet.w = list->right - packet.x + 1;
|
||||
packet.h = list->bottom - packet.y + 1;
|
||||
voodoo3_invert_rect(&packet, color, stride, bpp);
|
||||
list++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
FILL_SPAN (
|
||||
engine_token *et, uint32 color, uint16 *list, uint32 count)
|
||||
{
|
||||
uint32 stride, bpp;
|
||||
stride = si->fbc.bytes_per_row;
|
||||
bpp = voodoo3_bits_per_pixel();
|
||||
|
||||
while (count--)
|
||||
{
|
||||
list_packet packet;
|
||||
packet.y = *list ++;
|
||||
packet.x = *list ++;
|
||||
packet.w = *list - packet.x + 1;
|
||||
packet.h = 1;
|
||||
list ++;
|
||||
voodoo3_fill_span(&packet, color, stride, bpp);
|
||||
}
|
||||
}
|
@ -1,114 +0,0 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
|
||||
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
|
||||
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
|
||||
|
||||
*/
|
||||
|
||||
#include "GlobalData.h"
|
||||
#include "generic.h"
|
||||
#include "voodoo3_accelerant.h"
|
||||
|
||||
void set_cursor_colors(void);
|
||||
|
||||
void set_cursor_colors(void)
|
||||
{
|
||||
/* it's only called by the INIT_ACCELERANT() */
|
||||
voodoo3_set_cursor_colors(0, ~0);
|
||||
}
|
||||
|
||||
status_t
|
||||
SET_CURSOR_SHAPE (
|
||||
uint16 width, uint16 height, uint16 hot_x, uint16 hot_y,
|
||||
uint8 *andMask, uint8 *xorMask)
|
||||
{
|
||||
/* NOTE: Currently, for BeOS, cursor width and height must be equal to 16. */
|
||||
|
||||
if ((width != 16) || (height != 16))
|
||||
{
|
||||
return B_ERROR;
|
||||
}
|
||||
else if ((hot_x >= width) || (hot_y >= height))
|
||||
{
|
||||
return B_ERROR;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Update cursor variables appropriately. */
|
||||
si->cursor.width = width;
|
||||
si->cursor.height = height;
|
||||
si->cursor.hot_x = hot_x;
|
||||
si->cursor.hot_y = hot_y;
|
||||
voodoo3_set_cursor((uint8 *)framebuffer, width, height, andMask, xorMask);
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
Move the cursor to the specified position on the desktop. If we're
|
||||
using some kind of virtual desktop, adjust the display start position
|
||||
accordingly and position the cursor in the proper "virtual" location.
|
||||
*/
|
||||
void MOVE_CURSOR (uint16 x_p, uint16 y_p)
|
||||
{
|
||||
int x = x_p, y = y_p;
|
||||
bool move_screen = false;
|
||||
/* the current horizontal starting pixel */
|
||||
uint16 hds = si->dm.h_display_start;
|
||||
/* the current vertical starting line */
|
||||
uint16 vds = si->dm.v_display_start;
|
||||
|
||||
/* Need to set this value for 32 bit */
|
||||
uint16 h_adjust = 3;
|
||||
|
||||
/* clamp cursor to virtual display */
|
||||
if (x >= si->dm.virtual_width) x = si->dm.virtual_width - 1;
|
||||
if (y >= si->dm.virtual_height) y = si->dm.virtual_height - 1;
|
||||
|
||||
/* adjust h/v_display_start to move cursor onto screen */
|
||||
if (x >= (si->dm.timing.h_display + hds))
|
||||
{
|
||||
hds = ((x - si->dm.timing.h_display) + 1 + h_adjust) & ~h_adjust;
|
||||
move_screen = true;
|
||||
}
|
||||
else if (x < hds)
|
||||
{
|
||||
hds = x & ~h_adjust;
|
||||
move_screen = true;
|
||||
}
|
||||
if (y >= (si->dm.timing.v_display + vds))
|
||||
{
|
||||
vds = y - si->dm.timing.v_display + 1;
|
||||
move_screen = true;
|
||||
}
|
||||
else if (y < vds)
|
||||
{
|
||||
vds = y;
|
||||
move_screen = true;
|
||||
}
|
||||
|
||||
/* reposition the desktop on the display if required */
|
||||
if (move_screen) MOVE_DISPLAY(hds,vds);
|
||||
|
||||
/* put cursor in correct physical position */
|
||||
x -= hds;
|
||||
y -= vds;
|
||||
x -= si->cursor.hot_x;
|
||||
y -= si->cursor.hot_y;
|
||||
|
||||
/* position the cursor on the display */
|
||||
voodoo3_move_cursor(x, y);
|
||||
}
|
||||
|
||||
void SHOW_CURSOR (bool is_visible)
|
||||
{
|
||||
if (is_visible)
|
||||
voodoo3_show_cursor();
|
||||
else
|
||||
voodoo3_hide_cursor();
|
||||
/* record for our info */
|
||||
si->cursor.is_visible = is_visible;
|
||||
}
|
@ -1,67 +0,0 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
|
||||
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
|
||||
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
|
||||
|
||||
*/
|
||||
|
||||
#include "GlobalData.h"
|
||||
#include "generic.h"
|
||||
|
||||
static engine_token voodoo_engine_token = { 1, B_2D_ACCELERATION, NULL };
|
||||
|
||||
uint32 ACCELERANT_ENGINE_COUNT(void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
status_t
|
||||
ACQUIRE_ENGINE (
|
||||
uint32 capabilities, uint32 max_wait,
|
||||
sync_token *st, engine_token **et)
|
||||
{
|
||||
/* acquire the shared benaphore */
|
||||
AQUIRE_BEN(si->engine.lock)
|
||||
/* sync if required */
|
||||
if (st) SYNC_TO_TOKEN(st);
|
||||
|
||||
/* return an engine token */
|
||||
*et = &voodoo_engine_token;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t RELEASE_ENGINE (engine_token *et, sync_token *st)
|
||||
{
|
||||
/* update the sync token, if any */
|
||||
if (st)
|
||||
{
|
||||
st->engine_id = et->engine_id;
|
||||
st->counter = si->engine.count;
|
||||
}
|
||||
|
||||
/* release the shared benaphore */
|
||||
RELEASE_BEN(si->engine.lock)
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
void WAIT_ENGINE_IDLE(void)
|
||||
{
|
||||
// note our current possition
|
||||
si->engine.last_idle = si->engine.count;
|
||||
}
|
||||
|
||||
status_t GET_SYNC_TOKEN(engine_token *et, sync_token *st)
|
||||
{
|
||||
st->engine_id = et->engine_id;
|
||||
st->counter = si->engine.count;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t SYNC_TO_TOKEN(sync_token *st)
|
||||
{
|
||||
si->engine.last_idle = st->counter;
|
||||
return B_OK;
|
||||
}
|
||||
|
@ -1,129 +0,0 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
|
||||
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
|
||||
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
|
||||
|
||||
*/
|
||||
#include "generic.h"
|
||||
|
||||
status_t check_overlay_capability(uint32 feature);
|
||||
|
||||
/*
|
||||
|
||||
The standard entry point. Given a uint32 feature identifier, this routine
|
||||
returns a pointer to the function that implements the feature. Some features
|
||||
require more information than just the identifier to select the proper
|
||||
function. The extra information (which is specific to the feature) is
|
||||
pointed at by the void *data parameter. By default, no extra information
|
||||
is available. Any extra information available to choose the function will be
|
||||
noted on a case by case below.
|
||||
|
||||
*/
|
||||
void * get_accelerant_hook(uint32 feature, void *data) {
|
||||
switch (feature) {
|
||||
/*
|
||||
These definitions are out of pure lazyness.
|
||||
*/
|
||||
#define HOOK(x) case B_##x: return (void *)x
|
||||
#define ZERO(x) case B_##x: return (void *)0
|
||||
|
||||
/*
|
||||
One of either B_INIT_ACCELERANT or B_CLONE_ACCELERANT will be requested and
|
||||
subsequently called before any other hook is requested. All other feature
|
||||
hook selections can be predicated on variables assigned during the accelerant
|
||||
initialization process.
|
||||
*/
|
||||
/* initialization */
|
||||
HOOK(INIT_ACCELERANT);
|
||||
HOOK(CLONE_ACCELERANT);
|
||||
|
||||
HOOK(ACCELERANT_CLONE_INFO_SIZE);
|
||||
HOOK(GET_ACCELERANT_CLONE_INFO);
|
||||
HOOK(UNINIT_ACCELERANT);
|
||||
HOOK(GET_ACCELERANT_DEVICE_INFO);
|
||||
HOOK(ACCELERANT_RETRACE_SEMAPHORE);
|
||||
|
||||
/* mode configuration */
|
||||
HOOK(ACCELERANT_MODE_COUNT);
|
||||
HOOK(GET_MODE_LIST);
|
||||
HOOK(PROPOSE_DISPLAY_MODE);
|
||||
HOOK(SET_DISPLAY_MODE);
|
||||
HOOK(GET_DISPLAY_MODE);
|
||||
HOOK(GET_FRAME_BUFFER_CONFIG);
|
||||
HOOK(GET_PIXEL_CLOCK_LIMITS);
|
||||
HOOK(MOVE_DISPLAY);
|
||||
HOOK(SET_INDEXED_COLORS);
|
||||
HOOK(GET_TIMING_CONSTRAINTS);
|
||||
|
||||
HOOK(DPMS_CAPABILITIES);
|
||||
HOOK(DPMS_MODE);
|
||||
HOOK(SET_DPMS_MODE);
|
||||
|
||||
/* cursor managment */
|
||||
HOOK(SET_CURSOR_SHAPE);
|
||||
HOOK(MOVE_CURSOR);
|
||||
HOOK(SHOW_CURSOR);
|
||||
|
||||
/* synchronization */
|
||||
HOOK(ACCELERANT_ENGINE_COUNT);
|
||||
HOOK(ACQUIRE_ENGINE);
|
||||
HOOK(RELEASE_ENGINE);
|
||||
HOOK(WAIT_ENGINE_IDLE);
|
||||
HOOK(GET_SYNC_TOKEN);
|
||||
HOOK(SYNC_TO_TOKEN);
|
||||
|
||||
/*
|
||||
When requesting an acceleration hook, the calling application provides a
|
||||
pointer to the display_mode for which the acceleration function will be used.
|
||||
Depending on the engine architecture, you may choose to provide a different
|
||||
function to be used with each bit-depth. In the sample driver we return
|
||||
the same function all the time.
|
||||
*/
|
||||
/* 2D acceleration */
|
||||
HOOK(SCREEN_TO_SCREEN_BLIT);
|
||||
HOOK(FILL_RECTANGLE);
|
||||
HOOK(INVERT_RECTANGLE);
|
||||
HOOK(FILL_SPAN);
|
||||
|
||||
/* only export video overlay functions if card is capable of it */
|
||||
HOOK(OVERLAY_COUNT);
|
||||
HOOK(OVERLAY_SUPPORTED_SPACES);
|
||||
HOOK(OVERLAY_SUPPORTED_FEATURES);
|
||||
HOOK(ALLOCATE_OVERLAY_BUFFER);
|
||||
HOOK(RELEASE_OVERLAY_BUFFER);
|
||||
HOOK(GET_OVERLAY_CONSTRAINTS);
|
||||
HOOK(ALLOCATE_OVERLAY);
|
||||
HOOK(RELEASE_OVERLAY);
|
||||
HOOK(CONFIGURE_OVERLAY);
|
||||
|
||||
#undef HOOK
|
||||
#undef ZERO
|
||||
}
|
||||
/*
|
||||
Return a null pointer for any feature we don't understand.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
status_t check_overlay_capability(uint32 feature)
|
||||
{
|
||||
/* setup logmessage text */
|
||||
switch (feature)
|
||||
{
|
||||
case B_OVERLAY_COUNT:
|
||||
case B_OVERLAY_SUPPORTED_SPACES:
|
||||
case B_OVERLAY_SUPPORTED_FEATURES:
|
||||
case B_ALLOCATE_OVERLAY_BUFFER:
|
||||
case B_RELEASE_OVERLAY_BUFFER:
|
||||
case B_GET_OVERLAY_CONSTRAINTS:
|
||||
case B_ALLOCATE_OVERLAY:
|
||||
case B_RELEASE_OVERLAY:
|
||||
case B_CONFIGURE_OVERLAY:
|
||||
return B_OK;
|
||||
default:
|
||||
return B_ERROR;
|
||||
|
||||
}
|
||||
}
|
@ -1,97 +0,0 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
|
||||
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
|
||||
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
|
||||
|
||||
*/
|
||||
|
||||
#include "GlobalData.h"
|
||||
#include "generic.h"
|
||||
|
||||
/*
|
||||
Return the current display mode. The only time you might return an
|
||||
error is if a mode hasn't been set.
|
||||
*/
|
||||
status_t GET_DISPLAY_MODE (display_mode *current_mode)
|
||||
{
|
||||
/* easy for us, we return the last mode we set */
|
||||
*current_mode = si->dm;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
Return the frame buffer configuration information.
|
||||
*/
|
||||
status_t GET_FRAME_BUFFER_CONFIG(frame_buffer_config *afb)
|
||||
{
|
||||
/* easy again, as the last mode set stored the info in a convienient form */
|
||||
*afb = si->fbc;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
Return the maximum and minium pixel clock limits for the specified mode.
|
||||
*/
|
||||
status_t GET_PIXEL_CLOCK_LIMITS(display_mode *dm, uint32 *low, uint32 *high)
|
||||
{
|
||||
/*
|
||||
Note that we're not making any guarantees about the ability of the attached
|
||||
display to handle pixel clocks within the limits we return. A future monitor
|
||||
capablilities database will post-process this information.
|
||||
*/
|
||||
uint32 total_pix = (uint32)dm->timing.h_total * (uint32)dm->timing.v_total;
|
||||
uint32 clock_limit;
|
||||
|
||||
/* max pixel clock is pixel depth dependant */
|
||||
switch (dm->space & ~0x3000)
|
||||
{
|
||||
case B_RGB32: clock_limit = si->pix_clk_max32; break;
|
||||
case B_RGB15:
|
||||
case B_RGB16: clock_limit = si->pix_clk_max16; break;
|
||||
case B_CMAP8: clock_limit = si->pix_clk_max8; break;
|
||||
default:
|
||||
clock_limit = 0;
|
||||
}
|
||||
/* lower limit of about 48Hz vertical refresh */
|
||||
*low = (total_pix * 48L) / 1000L;
|
||||
if (*low > clock_limit) return B_ERROR;
|
||||
*high = clock_limit;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
status_t GET_TIMING_CONSTRAINTS(display_timing_constraints *dtc)
|
||||
{
|
||||
status_t retval;
|
||||
|
||||
dtc->h_res = 8;
|
||||
dtc->h_sync_min = 2*8;
|
||||
dtc->h_sync_max = 32*8 - 1;
|
||||
dtc->h_blank_min = 0;
|
||||
dtc->h_blank_max = 64*8 - 1;
|
||||
dtc->v_res = 1;
|
||||
dtc->v_sync_min = 2;
|
||||
dtc->v_sync_max = 15;
|
||||
dtc->v_blank_min = 0;
|
||||
dtc->v_blank_max = 255;
|
||||
|
||||
retval = B_OK;
|
||||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
Return the semaphore id that will be used to signal a vertical retrace
|
||||
occured.
|
||||
*/
|
||||
sem_id ACCELERANT_RETRACE_SEMAPHORE(void)
|
||||
{
|
||||
/*
|
||||
NOTE:
|
||||
The kernel driver created this for us. We don't know if the system is
|
||||
using real interrupts, or if we're faking it, and we don't care.
|
||||
If we choose not to support this at all, we'd just return B_ERROR here,
|
||||
and the user wouldn't get any kind of vertical retrace support.
|
||||
*/
|
||||
return /*si->vblank*/B_ERROR;
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
|
||||
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
|
||||
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
|
||||
|
||||
*/
|
||||
#include "GlobalData.h"
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
int fd;
|
||||
shared_info *si;
|
||||
area_id shared_info_area;
|
||||
vuint32 *regs;
|
||||
area_id regs_area;
|
||||
vuint32 *framebuffer;
|
||||
area_id fb_area;
|
||||
display_mode *my_mode_list;
|
||||
area_id my_mode_list_area;
|
||||
int accelerantIsClone;
|
||||
|
||||
area_id iobase_area;
|
||||
vuint32 *iobase;
|
||||
|
||||
#ifdef DEBUG
|
||||
void dpf (const char * format, ...)
|
||||
{
|
||||
char buffer[4096] = "VOODOO: ";
|
||||
va_list args;
|
||||
va_start (args, format);
|
||||
vsprintf (buffer + 8, format, args);
|
||||
ioctl (fd, VOODOO_DPRINTF, buffer, 0);
|
||||
va_end (args);
|
||||
}
|
||||
#endif
|
||||
|
||||
void outb(uint32 port, uint8 data)
|
||||
{
|
||||
voodoo_port_io io;
|
||||
io.port = port;
|
||||
io.data8 = data;
|
||||
ioctl(fd, VOODOO_OUTB, &io, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
void outw(uint32 port, uint16 data)
|
||||
{
|
||||
voodoo_port_io io;
|
||||
io.port = port;
|
||||
io.data16 = data;
|
||||
ioctl(fd, VOODOO_OUTW, &io, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
void outl(uint32 port, uint32 data)
|
||||
{
|
||||
voodoo_port_io io;
|
||||
io.port = port;
|
||||
io.data32 = data;
|
||||
ioctl(fd, VOODOO_OUTL, &io, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
uint8 inb(uint32 port)
|
||||
{
|
||||
voodoo_port_io io;
|
||||
io.port = port;
|
||||
ioctl(fd, VOODOO_INB, &io, 0);
|
||||
return(io.data8);
|
||||
}
|
||||
|
||||
uint16 inw(uint32 port)
|
||||
{
|
||||
voodoo_port_io io;
|
||||
io.port = port;
|
||||
ioctl(fd, VOODOO_INW, &io, 0);
|
||||
return(io.data16);
|
||||
}
|
||||
|
||||
uint32 inl(uint32 port)
|
||||
{
|
||||
voodoo_port_io io;
|
||||
io.port = port;
|
||||
ioctl(fd, VOODOO_INL, &io, 0);
|
||||
return(io.data32);
|
||||
}
|
@ -1,45 +0,0 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
|
||||
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
|
||||
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
|
||||
|
||||
*/
|
||||
|
||||
#if !defined(GLOBALDATA_H)
|
||||
#define GLOBALDATA_H
|
||||
|
||||
#include <video_overlay.h>
|
||||
#include <DriverInterface.h>
|
||||
#include <strings.h>
|
||||
|
||||
extern int fd;
|
||||
extern shared_info *si;
|
||||
extern area_id shared_info_area;
|
||||
extern vuint32 *regs;
|
||||
extern area_id regs_area;
|
||||
extern area_id iobase_area;
|
||||
extern vuint32 *iobase;
|
||||
extern vuint32 *framebuffer;
|
||||
extern area_id fb_area;
|
||||
extern display_mode *my_mode_list;
|
||||
extern area_id my_mode_list_area;
|
||||
extern int accelerantIsClone;
|
||||
|
||||
/* Print debug message through kernel driver. Should move to other location later. */
|
||||
// #define DEBUG
|
||||
|
||||
#ifdef DEBUG
|
||||
#define ddpf(a) dpf a
|
||||
extern void dpf (const char * format, ...);
|
||||
#else
|
||||
#define ddpf(a)
|
||||
#endif
|
||||
extern void outb(uint32 port, uint8 data);
|
||||
extern void outw(uint32 port, uint16 data);
|
||||
extern void outl(uint32 port, uint32 data);
|
||||
extern uint8 inb(uint32 port);
|
||||
extern uint16 inw(uint32 port);
|
||||
extern uint32 inl(uint32 port);
|
||||
#endif
|
@ -1,365 +0,0 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
|
||||
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
|
||||
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
|
||||
|
||||
*/
|
||||
|
||||
#include "GlobalData.h"
|
||||
#include "generic.h"
|
||||
#include "voodoo3_accelerant.h"
|
||||
#include "string.h"
|
||||
#include "unistd.h"
|
||||
#include "sys/types.h"
|
||||
#include "sys/stat.h"
|
||||
#include "fcntl.h"
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
/* defined in ProposeDisplayMode.c */
|
||||
extern status_t create_mode_list(void);
|
||||
/* defined in Cursor.c */
|
||||
extern void set_cursor_colors(void);
|
||||
|
||||
static status_t init_common(int the_fd);
|
||||
|
||||
static int tty = 0;
|
||||
/* Initialization code shared between primary and cloned accelerants */
|
||||
static status_t init_common(int the_fd)
|
||||
{
|
||||
status_t result;
|
||||
voodoo_get_private_data gpd;
|
||||
|
||||
/* memorize the file descriptor */
|
||||
fd = the_fd;
|
||||
ddpf(("TDFXV3:init_common_called: %d times\n", tty));
|
||||
tty++;
|
||||
|
||||
ddpf (("TDFXV3:init_common begin\n"));
|
||||
/* set the magic number so the driver knows we're for real */
|
||||
gpd.magic = VOODOO_PRIVATE_DATA_MAGIC;
|
||||
/* contact driver and get a pointer to the registers and shared data */
|
||||
result = ioctl(fd, VOODOO_GET_PRIVATE_DATA, &gpd, sizeof(gpd));
|
||||
if (result != B_OK) goto error0;
|
||||
|
||||
/* clone the shared area for our use */
|
||||
shared_info_area = clone_area (
|
||||
"VOODOO shared info", (void **)&si, B_ANY_ADDRESS,
|
||||
B_READ_AREA | B_WRITE_AREA, gpd.shared_info_area);
|
||||
if (shared_info_area < 0)
|
||||
{
|
||||
result = shared_info_area;
|
||||
goto error0;
|
||||
}
|
||||
/* clone the memory mapped registers for our use */
|
||||
regs_area = clone_area (
|
||||
"VOODOO regs area", (void **)®s, B_ANY_ADDRESS,
|
||||
B_READ_AREA | B_WRITE_AREA, si->regs_area);
|
||||
if (regs_area < 0)
|
||||
{
|
||||
result = regs_area;
|
||||
goto error1;
|
||||
}
|
||||
// We don't use it here, we use it trough Kernel Driver
|
||||
/*
|
||||
iobase_area = clone_area(
|
||||
"VOODOO io area", (void **)&iobase, B_ANY_ADDRESS,
|
||||
B_READ_AREA | B_WRITE_AREA, si->io_area);
|
||||
*/
|
||||
|
||||
/* clone the framebuffer buffer for our use */
|
||||
fb_area = clone_area (
|
||||
"VOODOO fb area", (void **)&framebuffer, B_ANY_ADDRESS,
|
||||
B_READ_AREA | B_WRITE_AREA, si->fb_area);
|
||||
|
||||
if (fb_area < 0)
|
||||
{
|
||||
result = regs_area;
|
||||
goto error2;
|
||||
}
|
||||
ddpf (("TDFXV3:starting voodoo3_init\n"));
|
||||
|
||||
voodoo3_init((uint8 *)regs, si->iobase);
|
||||
/* all done */
|
||||
goto error0;
|
||||
|
||||
error2:
|
||||
delete_area(regs_area);
|
||||
error1:
|
||||
delete_area(shared_info_area);
|
||||
error0:
|
||||
ddpf (("TDFXV3:init_common done\n"));
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Clean up code shared between primary and cloned accelrants */
|
||||
static void uninit_common(void)
|
||||
{
|
||||
/* release framebuffer area */
|
||||
delete_area (fb_area);
|
||||
/* release the memory mapped registers */
|
||||
delete_area(regs_area);
|
||||
/* a little cheap paranoia */
|
||||
|
||||
// delete_area(iobase_area);
|
||||
|
||||
/* a little cheap paranoia */
|
||||
framebuffer = 0;
|
||||
regs = 0;
|
||||
/* release our copy of the shared info from the kernel driver */
|
||||
delete_area(shared_info_area);
|
||||
/* more cheap paranoia */
|
||||
si = 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Initialize the accelerant. the_fd is the file handle of the device (in
|
||||
/dev/graphics) that has been opened by the app_server (or some test harness).
|
||||
We need to determine if the kernel driver and the accelerant are compatible.
|
||||
If they are, get the accelerant ready to handle other hook functions and
|
||||
report success or failure.
|
||||
*/
|
||||
|
||||
status_t INIT_ACCELERANT(int the_fd)
|
||||
{
|
||||
status_t result;
|
||||
uint32 cnt;
|
||||
/* note that we're the primary accelerant (accelerantIsClone is global) */
|
||||
accelerantIsClone = 0;
|
||||
|
||||
/* do the initialization common to both the primary and the clones */
|
||||
result = init_common(the_fd);
|
||||
|
||||
/* bail out if the common initialization failed */
|
||||
if (result != B_OK) goto error0;
|
||||
|
||||
/*
|
||||
If there is a possiblity that the kernel driver will recognize a card that
|
||||
the accelerant can't support, you should check for that here. Perhaps some
|
||||
odd memory configuration or some such.
|
||||
*/
|
||||
|
||||
/*
|
||||
This is a good place to go and initialize your card. The details are so
|
||||
device specific, we're not even going to pretend to provide you with sample
|
||||
code. If this fails, we'll have to bail out, cleaning up the resources
|
||||
we've already allocated.
|
||||
*/
|
||||
/* call the device specific init code */
|
||||
ddpf (("TDFXV3:pixelclock 8: %li\n", si->pix_clk_max8));
|
||||
ddpf (("TDFXV3:pixelclock 16: %li\n", si->pix_clk_max16));
|
||||
ddpf (("TDFXV3:pixelclock 32: %li\n", si->pix_clk_max32));
|
||||
|
||||
voodoo3_set_monitor_defaults();
|
||||
si->mem_size = voodoo3_get_memory_size();
|
||||
ddpf (("TDFXV3:mem_size = %dMB\n", si->mem_size / 1024 / 1024));
|
||||
if (!si->mem_size) {
|
||||
result=-1;
|
||||
goto error0;
|
||||
}
|
||||
|
||||
/*
|
||||
Now would be a good time to figure out what video modes your card supports.
|
||||
We'll place the list of modes in another shared area so all of the copies
|
||||
of the driver can see them. The primary copy of the accelerant (ie the one
|
||||
initialized with this routine) will own the "one true copy" of the list.
|
||||
Everybody else get's a read-only clone.
|
||||
*/
|
||||
result = create_mode_list();
|
||||
if (result != B_OK) goto error2;
|
||||
|
||||
/*
|
||||
Initialize the frame buffer and cursor pointers. Most newer video cards
|
||||
have integrated the DAC into the graphics engine, and so the cursor shape
|
||||
is stored in the frame buffer RAM. Also, newer cards tend not to have as
|
||||
many restrictions about the placement of the start of the frame buffer in
|
||||
frame buffer RAM. If you're supporting an older card with frame buffer
|
||||
positioning restrictions, or one without an integrated DAC, you'll have to
|
||||
change this accordingly.
|
||||
*/
|
||||
/*
|
||||
Put the cursor at the start of the frame buffer. The typical 64x64 4 color
|
||||
(black, white, transparent, inverse) takes up 1024 bytes of RAM.
|
||||
*/
|
||||
|
||||
si->cursor.data = (uint8 *)si->framebuffer;// + 131072;
|
||||
/* Initialize the rest of the cursor information while we're here */
|
||||
si->cursor.width = 0;
|
||||
si->cursor.height = 0;
|
||||
si->cursor.hot_x = 0;
|
||||
si->cursor.hot_y = 0;
|
||||
si->cursor.x = 0;
|
||||
si->cursor.y = 0;
|
||||
/*
|
||||
Put the frame buffer immediately following the cursor data. We store this
|
||||
info in a frame_buffer_config structure to make it convienient to return
|
||||
to the app_server later.
|
||||
*/
|
||||
si->fbc.frame_buffer = (void *)(((char *)si->framebuffer) + 1024);
|
||||
si->fbc.frame_buffer_dma = (void *)(((char *)si->framebuffer_pci) + 1024);
|
||||
si->start_addr = 1024;
|
||||
|
||||
/* init the shared semaphore */
|
||||
INIT_BEN(si->engine.lock);
|
||||
INIT_BEN(si->overlay.lock);
|
||||
for (cnt = 0; cnt < MAXBUFFERS; cnt++)
|
||||
{
|
||||
/* make sure overlay buffers are 'marked' as being free */
|
||||
si->overlay.myBuffer[cnt].buffer = NULL;
|
||||
si->overlay.myBuffer[cnt].buffer_dma = NULL;
|
||||
}
|
||||
/* make sure overlay unit is 'marked' as being free */
|
||||
si->overlay.myToken = NULL;
|
||||
|
||||
/* initialize the engine synchronization variables */
|
||||
|
||||
/* count of issued parameters or commands */
|
||||
si->engine.last_idle = si->engine.count = 0;
|
||||
|
||||
/* set the cursor colors. You may or may not have to do this, depending
|
||||
on the device. */
|
||||
|
||||
voodoo3_init_cursor_address();
|
||||
set_cursor_colors();
|
||||
|
||||
/* ensure cursor state */
|
||||
SHOW_CURSOR(false);
|
||||
/* a winner! */
|
||||
result = B_OK;
|
||||
goto error0;
|
||||
|
||||
/* free up the benaphore */
|
||||
DELETE_BEN(si->engine.lock);
|
||||
DELETE_BEN(si->overlay.lock);
|
||||
|
||||
error2:
|
||||
/*
|
||||
Clean up any resources allocated in your device specific initialization
|
||||
code.
|
||||
*/
|
||||
|
||||
/*
|
||||
Initialization failed after init_common() succeeded, so we need to clean
|
||||
up before quiting.
|
||||
*/
|
||||
uninit_common();
|
||||
|
||||
error0:
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
Return the number of bytes required to hold the information required
|
||||
to clone the device.
|
||||
*/
|
||||
ssize_t ACCELERANT_CLONE_INFO_SIZE(void)
|
||||
{
|
||||
/*
|
||||
Since we're passing the name of the device as the only required
|
||||
info, return the size of the name buffer
|
||||
*/
|
||||
return MAX_VOODOO_DEVICE_NAME_LENGTH;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Return the info required to clone the device. void *data points to
|
||||
a buffer at least ACCELERANT_CLONE_INFO_SIZE() bytes in length.
|
||||
*/
|
||||
void GET_ACCELERANT_CLONE_INFO(void *data)
|
||||
{
|
||||
voodoo_device_name dn;
|
||||
status_t result;
|
||||
|
||||
/* call the kernel driver to get the device name */
|
||||
dn.magic = VOODOO_PRIVATE_DATA_MAGIC;
|
||||
/* store the returned info directly into the passed buffer */
|
||||
dn.name = (char *)data;
|
||||
result = ioctl(fd, VOODOO_DEVICE_NAME, &dn, sizeof(dn));
|
||||
}
|
||||
|
||||
/*
|
||||
Initialize a copy of the accelerant as a clone. void *data points to
|
||||
a copy of the data returned by GET_ACCELERANT_CLONE_INFO().
|
||||
*/
|
||||
status_t CLONE_ACCELERANT(void *data)
|
||||
{
|
||||
status_t result;
|
||||
char path[MAXPATHLEN];
|
||||
|
||||
/* the data is the device name */
|
||||
strcpy(path, "/dev/");
|
||||
strcat(path, (const char *)data);
|
||||
/* open the device, the permissions aren't important */
|
||||
fd = open(path, B_READ_WRITE);
|
||||
if (fd < 0)
|
||||
{
|
||||
result = fd;
|
||||
goto error0;
|
||||
}
|
||||
|
||||
/* note that we're a clone accelerant */
|
||||
accelerantIsClone = 1;
|
||||
|
||||
/* call the shared initialization code */
|
||||
result = init_common(fd);
|
||||
|
||||
/* bail out if the common initialization failed */
|
||||
if (result != B_OK) goto error1;
|
||||
|
||||
/* get shared area for display modes */
|
||||
result = my_mode_list_area = clone_area(
|
||||
"VOODOO cloned display_modes",
|
||||
(void **)&my_mode_list,
|
||||
B_ANY_ADDRESS,
|
||||
B_READ_AREA,
|
||||
si->mode_area
|
||||
);
|
||||
if (result < B_OK) goto error2;
|
||||
|
||||
/* all done */
|
||||
result = B_OK;
|
||||
goto error0;
|
||||
|
||||
error2:
|
||||
/* free up the areas we cloned */
|
||||
uninit_common();
|
||||
error1:
|
||||
/* close the device we opened */
|
||||
close(fd);
|
||||
error0:
|
||||
return result;
|
||||
}
|
||||
|
||||
void UNINIT_ACCELERANT(void)
|
||||
{
|
||||
/* free our mode list area */
|
||||
delete_area(my_mode_list_area);
|
||||
/* paranoia */
|
||||
my_mode_list = 0;
|
||||
/* release our cloned data */
|
||||
uninit_common();
|
||||
/* close the file handle ONLY if we're the clone */
|
||||
if (accelerantIsClone) close(fd);
|
||||
}
|
||||
|
||||
status_t GET_ACCELERANT_DEVICE_INFO(accelerant_device_info *adi)
|
||||
{
|
||||
status_t retval;
|
||||
char * names[] =
|
||||
{ "Voodoo3" };
|
||||
|
||||
adi->version = 0x10000;
|
||||
strcpy (adi->name, names[0]);
|
||||
strcpy (adi->chipset, names[0]);
|
||||
strcpy (adi->serial_no, "0");
|
||||
adi->memory = si->mem_size;
|
||||
adi->dac_speed = 300;
|
||||
|
||||
retval = B_OK;
|
||||
return retval;
|
||||
}
|
||||
|
@ -1,21 +0,0 @@
|
||||
SubDir HAIKU_TOP src add-ons accelerants tdfx ;
|
||||
|
||||
UsePrivateHeaders graphics ;
|
||||
UsePrivateHeaders [ FDirName graphics tdfx ] ;
|
||||
|
||||
|
||||
Addon tdfx.accelerant :
|
||||
voodoo3_accelerant.c
|
||||
Acceleration.c
|
||||
Cursor.c
|
||||
EngineManagment.c
|
||||
GetAccelerantHook.c
|
||||
GetModeInfo.c
|
||||
GlobalData.c
|
||||
InitAccelerant.c
|
||||
ProposeDisplayMode.c
|
||||
SetDisplayMode.c
|
||||
Overlay.c
|
||||
;
|
||||
|
||||
Depends tdfx.accelerant : tdfx.driver ;
|
@ -1,317 +0,0 @@
|
||||
/* Overlay.c Framwork Taken from Rudolf Cornelissen (Open)BeOS MGA Driver
|
||||
05/09-2002 V0.13 beta1 */
|
||||
|
||||
#include "GlobalData.h"
|
||||
#include "generic.h"
|
||||
#include "voodoo3_accelerant.h"
|
||||
|
||||
static uint32 overlay_colorspaces [] = {(uint32)B_YCbCr422,
|
||||
#if defined(__POWERPC__)
|
||||
(uint32)B_RGB16_BIG,
|
||||
#else
|
||||
(uint32)B_RGB16,
|
||||
#endif
|
||||
(uint32)B_NO_COLOR_SPACE };
|
||||
|
||||
|
||||
// This method is never used AFAIK though it *is* exported on R5.0.3 and DANO.
|
||||
// Does someone know howto invoke it?
|
||||
// apparantly overlay count should report the number of 'overlay units' on the card
|
||||
|
||||
uint32 OVERLAY_COUNT(const display_mode *dm) {
|
||||
if (dm == NULL)
|
||||
ddpf( ("OVERLAY_COUNT:No DM given\n"));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// This method is never used AFAIK though it *is* exported on R5.0.3 and DANO.
|
||||
// Does someone know howto invoke it?
|
||||
const uint32 *OVERLAY_SUPPORTED_SPACES(const display_mode *dm) {
|
||||
if (dm == NULL) {
|
||||
ddpf (("OVERLAY_SUPPORTED_SPACES:No DM given\n"));
|
||||
return NULL;
|
||||
}
|
||||
/* return a B_NO_COLOR_SPACE terminated list */
|
||||
return &overlay_colorspaces[0];
|
||||
}
|
||||
|
||||
// This method is never used AFAIK. On R5.0.3 and DANO it is not even exported!
|
||||
uint32 OVERLAY_SUPPORTED_FEATURES(uint32 a_color_space) {
|
||||
switch (a_color_space){
|
||||
default:
|
||||
return
|
||||
( B_OVERLAY_COLOR_KEY |
|
||||
B_OVERLAY_HORIZONTAL_FILTERING |
|
||||
B_OVERLAY_VERTICAL_FILTERING );
|
||||
}
|
||||
}
|
||||
|
||||
const overlay_buffer *ALLOCATE_OVERLAY_BUFFER(color_space cs, uint16 width, uint16 height) {
|
||||
|
||||
int offset = 0; // used to determine next buffer to create
|
||||
uint32 adress, adress2, temp32; // used to calculate buffer adresses
|
||||
uint32 oldsize = 0; // used to 'squeeze' new buffers between already existing ones
|
||||
int cnt;
|
||||
|
||||
|
||||
/* acquire the shared benaphore */
|
||||
AQUIRE_BEN(si->overlay.lock)
|
||||
|
||||
/* find first empty slot (room for another buffer?) */
|
||||
for (offset = 0; offset < MAXBUFFERS; offset++)
|
||||
if (si->overlay.myBuffer[offset].buffer == NULL) break;
|
||||
|
||||
/* I just could make a lookup on overlay_colorspaces instead but its overhead I thing */
|
||||
|
||||
if (offset < MAXBUFFERS) {
|
||||
switch (cs) {
|
||||
case B_YCbCr422:
|
||||
#if defined(__POWERPC__)
|
||||
case B_RGB16_BIG:
|
||||
#else
|
||||
case B_RGB16:
|
||||
#endif
|
||||
si->overlay.myBuffer[offset].width = width;
|
||||
si->overlay.myBuffer[offset].bytes_per_row = 2 * si->overlay.myBuffer[offset].width;
|
||||
if (si->overlay.myBuffer[offset].width > 2048) {
|
||||
// release the shared benaphore
|
||||
RELEASE_BEN(si->overlay.lock)
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
// release the shared benaphore */
|
||||
RELEASE_BEN(si->overlay.lock)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// store slopspace (in pixels) for each bitmap for use by 'overlay unit' (BES)
|
||||
si->overlay.myBufInfo[offset].slopspace = si->overlay.myBuffer[offset].width - width;
|
||||
|
||||
si->overlay.myBuffer[offset].space = cs;
|
||||
si->overlay.myBuffer[offset].height = height;
|
||||
|
||||
// we define the overlay buffers to reside 'in the back' of the cards RAM
|
||||
|
||||
// calculate first free RAM adress in card:
|
||||
adress2 = (((uint32)((uint8*)si->fbc.frame_buffer)) +
|
||||
(si->fbc.bytes_per_row * si->dm.virtual_height));
|
||||
// calculate 'preliminary' buffer size including slopspace
|
||||
oldsize = si->overlay.myBufInfo[offset].size;
|
||||
si->overlay.myBufInfo[offset].size =
|
||||
si->overlay.myBuffer[offset].bytes_per_row * si->overlay.myBuffer[offset].height;
|
||||
|
||||
// calculate virtual memory adress that would be needed for a new bitmap
|
||||
|
||||
adress = (((uint32)((uint8*)si->framebuffer)) + (si->mem_size));
|
||||
for (cnt = 0; cnt <= offset; cnt++) adress -= si->overlay.myBufInfo[cnt].size;
|
||||
|
||||
// the > G200 scalers require buffers to be aligned to 16 byte pages cardRAM offset, G200 can do with
|
||||
// 8 byte pages cardRAM offset. Compatible settings used, has no real downside consequences here
|
||||
|
||||
// Check if we need to modify the buffers starting adress and thus the size
|
||||
// calculate 'would be' cardRAM offset
|
||||
temp32 = (adress - ((uint32)((vuint32 *)si->framebuffer)));
|
||||
|
||||
// check if it is aligned //
|
||||
if (temp32 != (temp32 & ~3)) {
|
||||
// update the (already calculated) buffersize to get it aligned
|
||||
si->overlay.myBufInfo[offset].size += (temp32 - (temp32 & ~3));
|
||||
// update the (already calculated) adress to get it aligned
|
||||
adress -= (temp32 - (temp32 & ~3));
|
||||
}
|
||||
|
||||
// First check now if buffer to be defined is 'last one' in memory (speaking backwards):
|
||||
// this is done to prevent a large buffer getting created in the space a small buffer
|
||||
// occupied earlier, if not all buffers created were deleted.
|
||||
|
||||
for (cnt = offset; cnt < MAXBUFFERS; cnt++) {
|
||||
if (si->overlay.myBuffer[cnt].buffer != NULL) {
|
||||
// Check if the new buffer would fit into the space the single old one used here
|
||||
if (si->overlay.myBufInfo[offset].size <= oldsize) {
|
||||
// It does, so we reset to the old size and adresses to prevent the space from shrinking
|
||||
// if we get here again...
|
||||
adress -= (oldsize - si->overlay.myBufInfo[offset].size);
|
||||
si->overlay.myBufInfo[offset].size = oldsize;
|
||||
// force exiting the FOR loop
|
||||
cnt = MAXBUFFERS;
|
||||
} else {
|
||||
// Reset to the old size to prevent the space from 'growing' if we get here again...
|
||||
si->overlay.myBufInfo[offset].size = oldsize;
|
||||
// release the shared benaphore
|
||||
RELEASE_BEN(si->overlay.lock)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
// check if we have enough space to setup this new bitmap
|
||||
// (preventing overlap of desktop RAMspace & overlay bitmap RAMspace here)
|
||||
if (adress < adress2) {
|
||||
// nope, sorry
|
||||
RELEASE_BEN(si->overlay.lock)
|
||||
return NULL;
|
||||
}
|
||||
// continue buffer setup
|
||||
si->overlay.myBuffer[offset].buffer = (void *) adress;
|
||||
|
||||
// calculate physical memory adress (for dma use)
|
||||
adress = (((uint32)((uint8*)si->framebuffer_pci)) + (si->mem_size));
|
||||
for (cnt = 0; cnt <= offset; cnt++)
|
||||
adress -= si->overlay.myBufInfo[cnt].size;
|
||||
// this adress is already aligned to the scaler's requirements (via the already modified sizes)
|
||||
|
||||
si->overlay.myBuffer[offset].buffer_dma = (void *) adress;
|
||||
|
||||
// release the shared benaphore
|
||||
RELEASE_BEN(si->overlay.lock)
|
||||
return &si->overlay.myBuffer[offset];
|
||||
} else {
|
||||
// sorry, no more room for buffers */
|
||||
RELEASE_BEN(si->overlay.lock)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
status_t RELEASE_OVERLAY_BUFFER(const overlay_buffer *ob) {
|
||||
int offset = 0;
|
||||
if (ob != NULL) {
|
||||
//Find the buffer
|
||||
for (offset = 0; offset < MAXBUFFERS; offset++)
|
||||
if (si->overlay.myBuffer[offset].buffer == ob->buffer) break;
|
||||
|
||||
if (offset < MAXBUFFERS) { // delete current buffer
|
||||
si->overlay.myBuffer[offset].buffer = NULL;
|
||||
si->overlay.myBuffer[offset].buffer_dma = NULL;
|
||||
|
||||
return B_OK;
|
||||
} else {
|
||||
return B_ERROR;
|
||||
}
|
||||
} else {
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
status_t GET_OVERLAY_CONSTRAINTS (const display_mode *dm, const overlay_buffer *ob, overlay_constraints *oc) {
|
||||
|
||||
int offset = 0;
|
||||
// Check for NULL Pointers
|
||||
if ((dm == NULL) || (ob == NULL) || (oc == NULL)) {
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// find the buffer
|
||||
for (offset = 0; offset < MAXBUFFERS; offset++)
|
||||
if (si->overlay.myBuffer[offset].buffer == ob->buffer) break;
|
||||
|
||||
if (offset < MAXBUFFERS) {
|
||||
// scaler input (values are in pixels)
|
||||
oc->view.h_alignment = 3;
|
||||
oc->view.v_alignment = 3;
|
||||
|
||||
switch (ob->space) {
|
||||
default:
|
||||
// we should not be here, but set the worst-case value just to be safe anyway
|
||||
oc->view.width_alignment = 3;
|
||||
break;
|
||||
}
|
||||
|
||||
oc->view.height_alignment = 3;
|
||||
oc->view.width.min = 1;
|
||||
oc->view.height.min = 2; // two fields
|
||||
oc->view.width.max = ob->width;
|
||||
oc->view.height.max = ob->height;
|
||||
|
||||
// scaler output restrictions
|
||||
oc->window.h_alignment = 3;
|
||||
oc->window.v_alignment = 3;
|
||||
oc->window.width_alignment = 3;
|
||||
oc->window.height_alignment = 3;
|
||||
oc->window.width.min = 2;
|
||||
if (dm->virtual_width > 2048) oc->window.width.max = 2048; else
|
||||
oc->window.width.max = dm->virtual_width;
|
||||
|
||||
oc->window.height.min = 2;
|
||||
|
||||
if (dm->virtual_height > 2048) oc->window.height.max = 2048; else
|
||||
oc->window.height.max = dm->virtual_height;
|
||||
|
||||
oc->h_scale.min = 1.0f;
|
||||
oc->h_scale.max = 4.0f;
|
||||
oc->v_scale.min = 1.0f;
|
||||
oc->v_scale.max = 4.0f;
|
||||
return B_OK;
|
||||
} else {
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
overlay_token ALLOCATE_OVERLAY(void)
|
||||
{
|
||||
uint32 tmpToken;
|
||||
// come up with a token
|
||||
tmpToken = 0x12345678;
|
||||
|
||||
// acquire the shared benaphore
|
||||
AQUIRE_BEN(si->overlay.lock)
|
||||
// overlay unit already in use?
|
||||
if (si->overlay.myToken == NULL) {
|
||||
// overlay unit is available
|
||||
si->overlay.myToken = &tmpToken;
|
||||
// release the shared benaphore
|
||||
RELEASE_BEN(si->overlay.lock)
|
||||
return si->overlay.myToken;
|
||||
} else {
|
||||
RELEASE_BEN(si->overlay.lock)
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
status_t RELEASE_OVERLAY(overlay_token ot) {
|
||||
|
||||
// is this call for real?
|
||||
if ((ot == NULL) || (si->overlay.myToken == NULL) || (ot != si->overlay.myToken)) {
|
||||
return B_ERROR;
|
||||
} else {
|
||||
// Do really something here!
|
||||
voodoo3_stop_overlay();
|
||||
si->overlay.myToken = NULL;
|
||||
return B_OK;
|
||||
}
|
||||
}
|
||||
|
||||
status_t CONFIGURE_OVERLAY (overlay_token ot, const overlay_buffer *ob, const overlay_window *ow, const overlay_view *ov) {
|
||||
|
||||
int offset = 0; // used for buffer index
|
||||
|
||||
|
||||
// in BeOS R5.0.3 (maybe DANO works different):
|
||||
// ov' is the output size on the desktop: does not change if clipped.
|
||||
// h_start and v_start are always 0, width and heigth are the size of the window.
|
||||
// Because the width and height can also be found in '*ow', '*ov' is not used.
|
||||
|
||||
if ((ow == NULL) || (ov == NULL)) {
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
if (ob == NULL) {
|
||||
return B_ERROR;
|
||||
}
|
||||
|
||||
// is this call done by the app that owns us? */
|
||||
if ((ot == NULL) || (si->overlay.myToken == NULL) || (ot != si->overlay.myToken)) {
|
||||
// nope, abort //
|
||||
return B_ERROR;
|
||||
} else {
|
||||
// call is for real
|
||||
for (offset = 0; offset < MAXBUFFERS; offset++)
|
||||
if (si->overlay.myBuffer[offset].buffer == ob->buffer) break;
|
||||
|
||||
if (offset < MAXBUFFERS) {
|
||||
voodoo3_display_overlay(ow, ob, ov);
|
||||
return B_OK;
|
||||
} else {
|
||||
return B_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,388 +0,0 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
|
||||
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
|
||||
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
|
||||
|
||||
*/
|
||||
#include "GlobalData.h"
|
||||
#include "generic.h"
|
||||
|
||||
status_t create_mode_list(void);
|
||||
|
||||
#define T_POSITIVE_SYNC (B_POSITIVE_HSYNC | B_POSITIVE_VSYNC)
|
||||
#define MODE_FLAGS (B_SCROLL|B_8_BIT_DAC|B_HARDWARE_CURSOR|B_PARALLEL_ACCESS)
|
||||
#define MODE_COUNT (sizeof (mode_list) / sizeof (display_mode))
|
||||
|
||||
static const display_mode mode_list[] = {
|
||||
{ { 25175, 640, 656, 752, 800, 480, 490, 492, 525, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(640X480X8.Z1) */
|
||||
{ { 27500, 640, 672, 768, 864, 480, 488, 494, 530, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* 640X480X60Hz */
|
||||
{ { 30500, 640, 672, 768, 864, 480, 517, 523, 588, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* SVGA_640X480X60HzNI */
|
||||
{ { 31500, 640, 664, 704, 832, 480, 489, 492, 520, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70-72Hz_(640X480X8.Z1) */
|
||||
{ { 31500, 640, 656, 720, 840, 480, 481, 484, 500, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(640X480X8.Z1) */
|
||||
{ { 36000, 640, 696, 752, 832, 480, 481, 484, 509, 0}, B_CMAP8, 640, 480, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(640X480X8.Z1) */
|
||||
{ { 38100, 800, 832, 960, 1088, 600, 602, 606, 620, 0}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* SVGA_800X600X56HzNI */
|
||||
{ { 40000, 800, 840, 968, 1056, 600, 601, 605, 628, T_POSITIVE_SYNC}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(800X600X8.Z1) */
|
||||
{ { 49500, 800, 816, 896, 1056, 600, 601, 604, 625, T_POSITIVE_SYNC}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(800X600X8.Z1) */
|
||||
{ { 50000, 800, 856, 976, 1040, 600, 637, 643, 666, T_POSITIVE_SYNC}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70-72Hz_(800X600X8.Z1) */
|
||||
{ { 56250, 800, 832, 896, 1048, 600, 601, 604, 631, T_POSITIVE_SYNC}, B_CMAP8, 800, 600, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(800X600X8.Z1) */
|
||||
{ { 65000, 1024, 1048, 1184, 1344, 768, 771, 777, 806, 0}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1024X768X8.Z1) */
|
||||
{ { 75000, 1024, 1048, 1184, 1328, 768, 771, 777, 806, 0}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70-72Hz_(1024X768X8.Z1) */
|
||||
{ { 78750, 1024, 1040, 1136, 1312, 768, 769, 772, 800, T_POSITIVE_SYNC}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1024X768X8.Z1) */
|
||||
{ { 94500, 1024, 1072, 1168, 1376, 768, 769, 772, 808, T_POSITIVE_SYNC}, B_CMAP8, 1024, 768, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(1024X768X8.Z1) */
|
||||
{ { 94200, 1152, 1184, 1280, 1472, 864, 865, 868, 914, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70Hz_(1152X864X8.Z1) */
|
||||
{ { 108000, 1152, 1216, 1344, 1600, 864, 865, 868, 900, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1152X864X8.Z1) */
|
||||
{ { 121500, 1152, 1216, 1344, 1568, 864, 865, 868, 911, T_POSITIVE_SYNC}, B_CMAP8, 1152, 864, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(1152X864X8.Z1) */
|
||||
{ { 108000, 1280, 1328, 1440, 1688, 1024, 1025, 1028, 1066, T_POSITIVE_SYNC}, B_CMAP8, 1280, 1024, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1280X1024X8.Z1) */
|
||||
{ { 135000, 1280, 1296, 1440, 1688, 1024, 1025, 1028, 1066, T_POSITIVE_SYNC}, B_CMAP8, 1280, 1024, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1280X1024X8.Z1) */
|
||||
{ { 157500, 1280, 1344, 1504, 1728, 1024, 1025, 1028, 1072, T_POSITIVE_SYNC}, B_CMAP8, 1280, 1024, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@85Hz_(1280X1024X8.Z1) */
|
||||
{ { 162000, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@60Hz_(1600X1200X8.Z1) */
|
||||
{ { 175500, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@65Hz_(1600X1200X8.Z1) */
|
||||
{ { 189000, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@70Hz_(1600X1200X8.Z1) */
|
||||
{ { 202500, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@75Hz_(1600X1200X8.Z1) */
|
||||
{ { 216000, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS}, /* Vesa_Monitor_@80Hz_(1600X1200X8.Z1) */
|
||||
{ { 229500, 1600, 1664, 1856, 2160, 1200, 1201, 1204, 1250, T_POSITIVE_SYNC}, B_CMAP8, 1600, 1200, 0, 0, MODE_FLAGS} /* Vesa_Monitor_@85Hz_(1600X1200X8.Z1) */
|
||||
};
|
||||
|
||||
|
||||
/* create a mask of one "bits" bits wide */
|
||||
#define MASKFROMWIDTH(bits) ((1 << bits) - 1)
|
||||
|
||||
/*
|
||||
Validate a target display mode is both
|
||||
a) a valid display mode for this device and
|
||||
b) falls between the contraints imposed by "low" and "high"
|
||||
|
||||
If the mode is not (or cannot) be made valid for this device, return B_ERROR.
|
||||
If a valid mode can be constructed, but it does not fall within the limits,
|
||||
return B_BAD_VALUE.
|
||||
If the mode is both valid AND falls within the limits, return B_OK.
|
||||
*/
|
||||
status_t PROPOSE_DISPLAY_MODE (
|
||||
display_mode *target, const display_mode *low, const display_mode *high)
|
||||
{
|
||||
|
||||
/* const uint16 h_display_bits = MASKFROMWIDTH(8); */
|
||||
const uint16 h_sync_bits = MASKFROMWIDTH(5);
|
||||
const uint16 h_total_bits = MASKFROMWIDTH(9);
|
||||
const uint16 v_display_bits = MASKFROMWIDTH(11);
|
||||
const uint16 v_sync_bits = MASKFROMWIDTH(5);
|
||||
/* const uint16 v_total_bits = MASKFROMWIDTH(11); */
|
||||
|
||||
status_t
|
||||
result = B_OK;
|
||||
uint32
|
||||
row_bytes,
|
||||
limit_clock;
|
||||
double
|
||||
target_refresh = ((double)target->timing.pixel_clock * 1000.0)
|
||||
/ ((double)target->timing.h_total
|
||||
* (double)target->timing.v_total);
|
||||
bool
|
||||
want_same_width = target->timing.h_display == target->virtual_width,
|
||||
want_same_height = target->timing.v_display == target->virtual_height;
|
||||
|
||||
/*
|
||||
NOTE:
|
||||
Different devices provide different levels of control over the
|
||||
various CRTC values. This code should be used as a *GUIDELINE ONLY*.
|
||||
The device you're controling may have very different constraints,
|
||||
and the code below may be insufficient to insure that a particular
|
||||
display_mode is valid for your device. You would do well to spend
|
||||
quite a bit of time ensuring that you understand the limitations of
|
||||
your device, as setting these values incorrectly can create a
|
||||
display_mode that could turn your monitor into a useless slag of
|
||||
molten components, burn up your card, lock up the PCI bus, cause
|
||||
partialy or multiply repeating display images, or otherwise look
|
||||
just plain wierd. Honest.
|
||||
*/
|
||||
/*
|
||||
NOTE:
|
||||
This code doesn't explicitly support interlaced video modes.
|
||||
*/
|
||||
|
||||
/* validate horizontal timings */
|
||||
{
|
||||
/* for most devices, horizontal parameters must be multiples of 8 */
|
||||
uint16 h_display = target->timing.h_display >> 3;
|
||||
uint16 h_sync_start = target->timing.h_sync_start >> 3;
|
||||
uint16 h_sync_end = target->timing.h_sync_end >> 3;
|
||||
uint16 h_total = target->timing.h_total >> 3;
|
||||
|
||||
/* ensure reasonable minium display and sequential order of parms */
|
||||
if (h_display < (320 >> 3)) h_display = 320 >> 3;
|
||||
if (h_display > (2048 >> 3)) h_display = 2048 >> 3;
|
||||
if (h_sync_start < (h_display + 2)) h_sync_start = h_display + 2;
|
||||
if (h_sync_end < (h_sync_start + 3))
|
||||
h_sync_end = h_sync_start + 3; /*(0x001f >> 2);*/
|
||||
if (h_total < (h_sync_end + 1)) h_total = h_sync_end + 1;
|
||||
/* adjust for register limitations: */
|
||||
/* h_total is 9 bits */
|
||||
if (h_total > h_total_bits) h_total = h_total_bits;
|
||||
/* h_display is 8 bits - handled above */
|
||||
/* h_sync_start is 9 bits */
|
||||
/* h_sync_width is 5 bits */
|
||||
if ((h_sync_end - h_sync_start) > h_sync_bits)
|
||||
h_sync_end = h_sync_start + h_sync_bits;
|
||||
|
||||
/* shift back to the full width values */
|
||||
target->timing.h_display = h_display << 3;
|
||||
target->timing.h_sync_start = h_sync_start << 3;
|
||||
target->timing.h_sync_end = h_sync_end << 3;
|
||||
target->timing.h_total = h_total << 3;
|
||||
}
|
||||
|
||||
/* did we fall out of one of the limits? */
|
||||
if (
|
||||
(target->timing.h_display < low->timing.h_display) ||
|
||||
(target->timing.h_display > high->timing.h_display) ||
|
||||
(target->timing.h_sync_start < low->timing.h_sync_start) ||
|
||||
(target->timing.h_sync_start > high->timing.h_sync_start) ||
|
||||
(target->timing.h_sync_end < low->timing.h_sync_end) ||
|
||||
(target->timing.h_sync_end > high->timing.h_sync_end) ||
|
||||
(target->timing.h_total < low->timing.h_total) ||
|
||||
(target->timing.h_total > high->timing.h_total)
|
||||
) result = B_BAD_VALUE;
|
||||
|
||||
|
||||
/* validate vertical timings */
|
||||
{
|
||||
uint16 v_display = target->timing.v_display;
|
||||
uint16 v_sync_start = target->timing.v_sync_start;
|
||||
uint16 v_sync_end = target->timing.v_sync_end;
|
||||
uint16 v_total = target->timing.v_total;
|
||||
|
||||
/* ensure reasonable minium display and sequential order of parms */
|
||||
/* v_display is 11 bits */
|
||||
/* v_total is 11 bits */
|
||||
/* v_sync_start is 11 bits */
|
||||
/* v_sync_width is 5 bits */
|
||||
if (v_display < 200) v_display = 200;
|
||||
if (v_display > (v_display_bits - 5)) v_display = (v_display_bits - 5); /* leave room for the sync pulse */
|
||||
if (v_sync_start < (v_display + 1)) v_sync_start = v_display + 1;
|
||||
if (v_sync_end < v_sync_start) v_sync_end = v_sync_start + 3;
|
||||
if (v_total < (v_sync_end + 1)) v_total = v_sync_end + 1;
|
||||
/* adjust for register limitations */
|
||||
if ((v_sync_end - v_sync_start) > v_sync_bits)
|
||||
v_sync_end = v_sync_start + v_sync_bits;
|
||||
target->timing.v_display = v_display;
|
||||
target->timing.v_sync_start = v_sync_start;
|
||||
target->timing.v_sync_end = v_sync_end;
|
||||
target->timing.v_total = v_total;
|
||||
}
|
||||
|
||||
/* did we fall out of one of the limits? */
|
||||
if (
|
||||
(target->timing.v_display < low->timing.v_display) ||
|
||||
(target->timing.v_display > high->timing.v_display) ||
|
||||
(target->timing.v_sync_start < low->timing.v_sync_start) ||
|
||||
(target->timing.v_sync_start > high->timing.h_sync_start) ||
|
||||
(target->timing.v_sync_end < low->timing.v_sync_end) ||
|
||||
(target->timing.v_sync_end > high->timing.v_sync_end) ||
|
||||
(target->timing.v_total < low->timing.v_total) ||
|
||||
(target->timing.v_total > high->timing.v_total)
|
||||
) result = B_BAD_VALUE;
|
||||
|
||||
/* adjust pixel clock for DAC limits and target refresh rate */
|
||||
/*
|
||||
We're re-calcuating the pixel_clock here because we might have
|
||||
changed the h/v totals above. If we didn't change anything
|
||||
the calculation is wasted, but it's no big deal.
|
||||
*/
|
||||
target->timing.pixel_clock = target_refresh
|
||||
* ((double)target->timing.h_total)
|
||||
* ((double)target->timing.v_total) / 1000.0;
|
||||
|
||||
/*
|
||||
Select the maximum pixel clock based on the color space. Your
|
||||
device may have other constraints. In this sample driver, we
|
||||
calculated the maximum pixel clock for this device in the
|
||||
initialization code.
|
||||
This is also a convienient place to determine the number of bytes
|
||||
per pixel for a later display pitch calculation.
|
||||
*/
|
||||
switch (target->space & 0x0fff)
|
||||
{
|
||||
case B_CMAP8:
|
||||
limit_clock = si->pix_clk_max8;
|
||||
row_bytes = 1;
|
||||
break;
|
||||
case B_RGB15:
|
||||
case B_RGB16:
|
||||
case B_RGB15_BIG:
|
||||
case B_RGB16_BIG:
|
||||
limit_clock = si->pix_clk_max16;
|
||||
row_bytes = 2;
|
||||
break;
|
||||
case B_RGB32:
|
||||
case B_RGB32_BIG:
|
||||
limit_clock = si->pix_clk_max32;
|
||||
row_bytes = 4;
|
||||
break;
|
||||
default:
|
||||
/* no amount of adjusting will fix not being able to support
|
||||
the pixel format */
|
||||
return B_ERROR;
|
||||
}
|
||||
/* make sure we don't generate more pixel bandwidth than the device
|
||||
can handle */
|
||||
if (target->timing.pixel_clock > limit_clock)
|
||||
target->timing.pixel_clock = limit_clock;
|
||||
/* we probably ought to check against too low of a pixel rate,
|
||||
but I'm lazy */
|
||||
|
||||
/* note if we fell outside the limits */
|
||||
if (
|
||||
(target->timing.pixel_clock < low->timing.pixel_clock) ||
|
||||
(target->timing.pixel_clock > high->timing.pixel_clock)
|
||||
) result = B_BAD_VALUE;
|
||||
|
||||
/* validate display vs. virtual */
|
||||
if ((target->timing.h_display > target->virtual_width) || want_same_width)
|
||||
target->virtual_width = target->timing.h_display;
|
||||
if ((target->timing.v_display > target->virtual_height) || want_same_height)
|
||||
target->virtual_height = target->timing.v_display;
|
||||
if (target->virtual_width > 2048)
|
||||
target->virtual_width = 2048;
|
||||
|
||||
/* adjust virtual width for engine limitations */
|
||||
target->virtual_width = (target->virtual_width + 7) & ~7;
|
||||
if (
|
||||
(target->virtual_width < low->virtual_width) ||
|
||||
(target->virtual_width > high->virtual_width)
|
||||
) result = B_BAD_VALUE;
|
||||
|
||||
/* calculate rowbytes after we've nailed the virtual width */
|
||||
row_bytes *= target->virtual_width;
|
||||
|
||||
/* memory requirement for frame buffer */
|
||||
if ((row_bytes * target->virtual_height) > si->mem_size)
|
||||
target->virtual_height = si->mem_size / row_bytes;
|
||||
|
||||
if (target->virtual_height > 2048)
|
||||
target->virtual_height = 2048;
|
||||
|
||||
if (target->virtual_height < target->timing.v_display)
|
||||
/* not enough frame buffer memory for the mode */
|
||||
return B_ERROR;
|
||||
else if (
|
||||
(target->virtual_height < low->virtual_height) ||
|
||||
(target->virtual_height > high->virtual_height)
|
||||
) result = B_BAD_VALUE;
|
||||
|
||||
/*
|
||||
Bit Flag Encoding
|
||||
|
||||
The way the bit flags works is as follows:
|
||||
|
||||
low high meaning
|
||||
--- ---- -------
|
||||
0 0 Feature must NOT be enabled
|
||||
0 1 Feature MAY be enabled, prefered enabled
|
||||
1 0 Feature MAY be enabled, prefered disabled
|
||||
1 1 Feature MUST be enabled
|
||||
|
||||
*/
|
||||
/* MORE WORK REQUIRED HERE. Current drivers mostly ignore the flags */
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
Return the number of modes this device will return from GET_MODE_LIST().
|
||||
*/
|
||||
uint32 ACCELERANT_MODE_COUNT(void)
|
||||
{
|
||||
/* return the number of 'built-in' display modes */
|
||||
return si->mode_count;
|
||||
}
|
||||
|
||||
/*
|
||||
Copy the list of guaranteed supported video modes to the location
|
||||
provided.
|
||||
*/
|
||||
status_t GET_MODE_LIST(display_mode *dm)
|
||||
{
|
||||
/* copy them to the buffer pointed at by *dm */
|
||||
memcpy(dm, my_mode_list, si->mode_count * sizeof(display_mode));
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Create a list of display_modes to pass back to the caller.
|
||||
*/
|
||||
status_t create_mode_list(void)
|
||||
{
|
||||
size_t max_size;
|
||||
uint32
|
||||
i, j,
|
||||
pix_clk_range;
|
||||
const display_mode
|
||||
*src;
|
||||
display_mode
|
||||
*dst,
|
||||
low,
|
||||
high;
|
||||
|
||||
/*
|
||||
We prefer frame buffers to have the same endianness as the host
|
||||
CPU, but it's not required. You can even return both, although
|
||||
there isn't a way for the current Screen preferences panel to
|
||||
allow the user to choose which one to use.
|
||||
*/
|
||||
#if defined(__INTEL__)
|
||||
color_space spaces[] =
|
||||
{B_CMAP8, B_RGB16_LITTLE, B_RGB32_LITTLE};
|
||||
#else
|
||||
// We could replace LITTLE with BIG
|
||||
color_space spaces[] =
|
||||
{B_CMAP8, B_RGB16_BIG, B_RGB32_BIG};
|
||||
#endif
|
||||
|
||||
/* figure out how big the list could be, and adjust up to nearest
|
||||
multiple of B_PAGE_SIZE */
|
||||
max_size = (((MODE_COUNT * sizeof (spaces) / sizeof (color_space))
|
||||
* sizeof(display_mode))
|
||||
+ (B_PAGE_SIZE-1)) & ~(B_PAGE_SIZE-1);
|
||||
/* create an area to hold the info */
|
||||
si->mode_area = my_mode_list_area =
|
||||
create_area (
|
||||
"VOODOO accelerant mode info", (void **)&my_mode_list,
|
||||
B_ANY_ADDRESS, max_size, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
|
||||
if (my_mode_list_area < B_OK) return my_mode_list_area;
|
||||
|
||||
/* walk through our predefined list and see which modes fit this device */
|
||||
src = mode_list;
|
||||
dst = my_mode_list;
|
||||
si->mode_count = 0;
|
||||
for (i = 0; i < MODE_COUNT; i++)
|
||||
{
|
||||
/* set ranges for acceptable values */
|
||||
low = high = *src;
|
||||
/* range is 6.25% of default clock: arbitrarily picked */
|
||||
pix_clk_range = low.timing.pixel_clock >> 5;
|
||||
low.timing.pixel_clock -= pix_clk_range;
|
||||
high.timing.pixel_clock += pix_clk_range;
|
||||
/* some cards need wider virtual widths for certain modes */
|
||||
high.virtual_width = 2048;
|
||||
/* do it once for each depth we want to support */
|
||||
for (j = 0; j < (sizeof(spaces) / sizeof(color_space)); j++) {
|
||||
/* set target values */
|
||||
*dst = *src;
|
||||
/* poke the specific space */
|
||||
dst->space = low.space = high.space = spaces[j];
|
||||
if (spaces[j] != B_CMAP8) dst->flags &= ~B_8_BIT_DAC;
|
||||
/* ask for a compatible mode */
|
||||
if (1 || PROPOSE_DISPLAY_MODE(dst, &low, &high) != B_ERROR) {
|
||||
/* count it, and move on to next mode */
|
||||
dst++;
|
||||
si->mode_count++;
|
||||
}
|
||||
}
|
||||
/* advance to next mode */
|
||||
src++;
|
||||
}
|
||||
|
||||
return B_OK;
|
||||
}
|
@ -1,254 +0,0 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
|
||||
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
|
||||
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
|
||||
|
||||
*/
|
||||
|
||||
#include "GlobalData.h"
|
||||
#include "generic.h"
|
||||
#include <sys/ioctl.h>
|
||||
#include "voodoo3_accelerant.h"
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
Enable/Disable interrupts. Just a wrapper around the
|
||||
ioctl() to the kernel driver.
|
||||
*/
|
||||
static void interrupt_enable(bool flag)
|
||||
{
|
||||
status_t result;
|
||||
voodoo_set_bool_state sbs;
|
||||
|
||||
/* set the magic number so the driver knows we're for real */
|
||||
sbs.magic = VOODOO_PRIVATE_DATA_MAGIC;
|
||||
sbs.do_it = flag;
|
||||
/* contact driver and get a pointer to the registers and shared data */
|
||||
result = ioctl(fd, VOODOO_RUN_INTERRUPTS, &sbs, sizeof(sbs));
|
||||
}
|
||||
|
||||
/*
|
||||
Calculates the number of bits for a given color_space.
|
||||
Usefull for mode setup routines, etc.
|
||||
*/
|
||||
static uint32 calcBitsPerPixel(uint32 cs)
|
||||
{
|
||||
uint32 bpp = 0;
|
||||
|
||||
switch (cs)
|
||||
{
|
||||
case B_RGB32_BIG:
|
||||
case B_RGBA32_BIG:
|
||||
case B_RGB32_LITTLE:
|
||||
case B_RGBA32_LITTLE:
|
||||
bpp = 32; break;
|
||||
case B_RGB24_BIG:
|
||||
case B_RGB24_LITTLE:
|
||||
bpp = 24; break;
|
||||
case B_RGB16_BIG:
|
||||
case B_RGB16_LITTLE:
|
||||
bpp = 16; break;
|
||||
case B_RGB15_BIG:
|
||||
case B_RGBA15_BIG:
|
||||
case B_RGB15_LITTLE:
|
||||
case B_RGBA15_LITTLE:
|
||||
bpp = 15; break;
|
||||
case B_CMAP8:
|
||||
bpp = 8; break;
|
||||
}
|
||||
return bpp;
|
||||
}
|
||||
|
||||
|
||||
static void do_set_display_mode(display_mode *dm)
|
||||
{
|
||||
uint32 bpp;
|
||||
/* disable interrupts using the kernel driver */
|
||||
interrupt_enable(false);
|
||||
|
||||
bpp = calcBitsPerPixel (dm->space);
|
||||
voodoo_set_desktop_regs(bpp, dm);
|
||||
/* enable interrupts using the kernel driver */
|
||||
interrupt_enable(true);
|
||||
si->fbc.bytes_per_row = (dm->virtual_width * bpp + 7) / 8;
|
||||
}
|
||||
|
||||
/*
|
||||
The exported mode setting routine. First validate the mode,
|
||||
then call our private routine to hammer the registers.
|
||||
*/
|
||||
status_t SET_DISPLAY_MODE (display_mode *mode_to_set)
|
||||
{
|
||||
display_mode bounds, target;
|
||||
|
||||
/* ask for the specific mode */
|
||||
target = bounds = *mode_to_set;
|
||||
if (PROPOSE_DISPLAY_MODE(&target, &bounds, &bounds) == B_ERROR)
|
||||
return B_ERROR;
|
||||
do_set_display_mode(&target);
|
||||
si->dm = target;
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
Set which pixel of the virtual frame buffer will show up in the
|
||||
top left corner of the display device. Used for page-flipping
|
||||
games and virtual desktops.
|
||||
*/
|
||||
status_t MOVE_DISPLAY (uint16 h_display_start, uint16 v_display_start)
|
||||
{
|
||||
/*
|
||||
Many devices have limitations on the granularity of the horizontal offset.
|
||||
Make any checks for this here. A future revision of the driver API will
|
||||
add a hook to return the granularity for a given display mode.
|
||||
*/
|
||||
/* most cards can handle multiples of 8 */
|
||||
|
||||
if (h_display_start & 0x07)
|
||||
return B_ERROR;
|
||||
/* do not run past end of display */
|
||||
if ((si->dm.timing.h_display + h_display_start) > si->dm.virtual_width)
|
||||
return B_ERROR;
|
||||
if ((si->dm.timing.v_display + v_display_start) > si->dm.virtual_height)
|
||||
return B_ERROR;
|
||||
|
||||
/* everybody remember where we parked... */
|
||||
si->dm.h_display_start = h_display_start;
|
||||
si->dm.v_display_start = v_display_start;
|
||||
|
||||
/* actually set the registers */
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
Set the indexed color palette.
|
||||
*/
|
||||
void SET_INDEXED_COLORS (
|
||||
uint count, uint8 first, uint8 *color_data, uint32 flags)
|
||||
{
|
||||
/*
|
||||
Some cards use the indexed color regisers in the DAC for gamma correction.
|
||||
If this is true with your device (and it probably is), you need to protect
|
||||
against setting these registers when not in an indexed mode.
|
||||
*/
|
||||
if (si->dm.space != B_CMAP8) return;
|
||||
|
||||
/*
|
||||
There isn't any need to keep a copy of the data being stored,
|
||||
as the app_server will set the colors each time it switches to
|
||||
an 8bpp mode, or takes ownership of an 8bpp mode after a GameKit
|
||||
app has used it.
|
||||
*/
|
||||
while(count--) {
|
||||
uint32 color = ((color_data[0] << 16) | (color_data[1] << 8) | (color_data[2]));
|
||||
voodoo3_set_palette(first++, color);
|
||||
color_data += 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* masks for DPMS control bits */
|
||||
enum
|
||||
{
|
||||
H_SYNC_OFF = 0x01,
|
||||
V_SYNC_OFF = 0x02,
|
||||
DISPLAY_OFF = 0x04,
|
||||
BITSMASK = H_SYNC_OFF | V_SYNC_OFF | DISPLAY_OFF
|
||||
};
|
||||
|
||||
/*
|
||||
Put the display into one of the Display Power Management modes.
|
||||
*/
|
||||
status_t SET_DPMS_MODE(uint32 dpms_flags)
|
||||
{
|
||||
uint32 LTemp;
|
||||
|
||||
/*
|
||||
The register containing the horizontal and vertical sync control bits
|
||||
usually contains other control bits, so do a read-modify-write.
|
||||
*/
|
||||
/* FIXME - read the bits */
|
||||
LTemp = *regs;
|
||||
/* this mask is device dependant */
|
||||
LTemp &= ~BITSMASK; /* clear all disable bits (including display disable) */
|
||||
|
||||
/* now pick one of the DPMS configurations */
|
||||
switch(dpms_flags)
|
||||
{
|
||||
case B_DPMS_ON: /* H: on, V: on */
|
||||
/* do nothing, bits already clear */
|
||||
/* usually, but it may be different for your device */
|
||||
break;
|
||||
case B_DPMS_STAND_BY: /* H: off, V: on, display off */
|
||||
LTemp |= H_SYNC_OFF | DISPLAY_OFF;
|
||||
break;
|
||||
case B_DPMS_SUSPEND: /* H: on, V: off, display off */
|
||||
LTemp |= V_SYNC_OFF | DISPLAY_OFF;
|
||||
break;
|
||||
case B_DPMS_OFF: /* H: off, V: off, display off */
|
||||
LTemp |= H_SYNC_OFF | V_SYNC_OFF | DISPLAY_OFF;
|
||||
break;
|
||||
default:
|
||||
return B_ERROR;
|
||||
}
|
||||
/* FIXME - write the bits */
|
||||
*regs = LTemp;
|
||||
|
||||
/*
|
||||
NOTE: if you're driving a device with a backlight (like a digital
|
||||
LCD), you may want to turn off the backlight here when in a DPMS
|
||||
power saving mode.
|
||||
*/
|
||||
if (dpms_flags == B_DPMS_ON)
|
||||
/* turn on the back light */
|
||||
;
|
||||
else
|
||||
/* turn off the back light */
|
||||
;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
Report device DPMS capabilities. Most newer cards can do it all.
|
||||
I've only seen one older card that can do a subset (ON and OFF).
|
||||
Very early cards may not be able to do this at all.
|
||||
*/
|
||||
uint32 DPMS_CAPABILITIES (void)
|
||||
{
|
||||
return B_DPMS_ON | B_DPMS_STAND_BY | B_DPMS_SUSPEND | B_DPMS_OFF;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Return the current DPMS mode.
|
||||
*/
|
||||
uint32 DPMS_MODE (void)
|
||||
{
|
||||
uint32 LTemp;
|
||||
uint32 mode = B_DPMS_ON;
|
||||
|
||||
/* read the control bits from the device */
|
||||
/* FIXME - read the bits */
|
||||
LTemp = *regs;
|
||||
|
||||
/* what mode is set? */
|
||||
switch (LTemp & (H_SYNC_OFF | V_SYNC_OFF))
|
||||
{
|
||||
case 0: /* H: on, V: on */
|
||||
mode = B_DPMS_ON;
|
||||
break;
|
||||
case H_SYNC_OFF: /* H: off, V: on */
|
||||
mode = B_DPMS_STAND_BY;
|
||||
break;
|
||||
case V_SYNC_OFF: /* H: on, V: off */
|
||||
mode = B_DPMS_SUSPEND;
|
||||
break;
|
||||
case (H_SYNC_OFF | V_SYNC_OFF): /* H: off, V: off */
|
||||
mode = B_DPMS_OFF;
|
||||
break;
|
||||
}
|
||||
return mode;
|
||||
}
|
@ -1,66 +0,0 @@
|
||||
/*
|
||||
Copyright 1999, Be Incorporated. All Rights Reserved.
|
||||
This file may be used under the terms of the Be Sample Code License.
|
||||
|
||||
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
|
||||
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
|
||||
|
||||
*/
|
||||
|
||||
#if !defined(GENERIC_H)
|
||||
#define GENERIC_H
|
||||
|
||||
#include <Accelerant.h>
|
||||
#include <video_overlay.h>
|
||||
status_t INIT_ACCELERANT(int fd);
|
||||
ssize_t ACCELERANT_CLONE_INFO_SIZE(void);
|
||||
void GET_ACCELERANT_CLONE_INFO(void *data);
|
||||
status_t CLONE_ACCELERANT(void *data);
|
||||
void UNINIT_ACCELERANT(void);
|
||||
status_t GET_ACCELERANT_DEVICE_INFO(accelerant_device_info *adi);
|
||||
sem_id ACCELERANT_RETRACE_SEMAPHORE(void);
|
||||
|
||||
uint32 ACCELERANT_MODE_COUNT(void);
|
||||
status_t GET_MODE_LIST(display_mode *dm);
|
||||
status_t PROPOSE_DISPLAY_MODE(display_mode *target, const display_mode *low, const display_mode *high);
|
||||
status_t SET_DISPLAY_MODE(display_mode *mode_to_set);
|
||||
status_t GET_DISPLAY_MODE(display_mode *current_mode);
|
||||
status_t GET_FRAME_BUFFER_CONFIG(frame_buffer_config *a_frame_buffer);
|
||||
status_t GET_PIXEL_CLOCK_LIMITS(display_mode *dm, uint32 *low, uint32 *high);
|
||||
status_t MOVE_DISPLAY(uint16 h_display_start, uint16 v_display_start);
|
||||
status_t GET_TIMING_CONSTRAINTS(display_timing_constraints *dtc);
|
||||
void SET_INDEXED_COLORS(uint count, uint8 first, uint8 *color_data, uint32 flags);
|
||||
|
||||
uint32 DPMS_CAPABILITIES(void);
|
||||
uint32 DPMS_MODE(void);
|
||||
status_t SET_DPMS_MODE(uint32 dpms_flags);
|
||||
|
||||
|
||||
status_t SET_CURSOR_SHAPE(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y, uint8 *andMask, uint8 *xorMask);
|
||||
void MOVE_CURSOR(uint16 x, uint16 y);
|
||||
void SHOW_CURSOR(bool is_visible);
|
||||
|
||||
uint32 ACCELERANT_ENGINE_COUNT(void);
|
||||
status_t ACQUIRE_ENGINE(uint32 capabilities, uint32 max_wait, sync_token *st, engine_token **et);
|
||||
status_t RELEASE_ENGINE(engine_token *et, sync_token *st);
|
||||
void WAIT_ENGINE_IDLE(void);
|
||||
status_t GET_SYNC_TOKEN(engine_token *et, sync_token *st);
|
||||
status_t SYNC_TO_TOKEN(sync_token *st);
|
||||
|
||||
void SCREEN_TO_SCREEN_BLIT(engine_token *et, blit_params *list, uint32 count);
|
||||
void FILL_RECTANGLE(engine_token *et, uint32 color, fill_rect_params *list, uint32 count);
|
||||
void INVERT_RECTANGLE(engine_token *et, fill_rect_params *list, uint32 count);
|
||||
void FILL_SPAN(engine_token *et, uint32 color, uint16 *list, uint32 count);
|
||||
|
||||
/* video_overlay */
|
||||
uint32 OVERLAY_COUNT(const display_mode *dm);
|
||||
const uint32 *OVERLAY_SUPPORTED_SPACES(const display_mode *dm);
|
||||
uint32 OVERLAY_SUPPORTED_FEATURES(uint32 a_color_space);
|
||||
const overlay_buffer *ALLOCATE_OVERLAY_BUFFER(color_space cs, uint16 width, uint16 height);
|
||||
status_t RELEASE_OVERLAY_BUFFER(const overlay_buffer *ob);
|
||||
status_t GET_OVERLAY_CONSTRAINTS(const display_mode *dm, const overlay_buffer *ob, overlay_constraints *oc);
|
||||
overlay_token ALLOCATE_OVERLAY(void);
|
||||
status_t RELEASE_OVERLAY(overlay_token ot);
|
||||
status_t CONFIGURE_OVERLAY(overlay_token ot, const overlay_buffer *ob, const overlay_window *ow, const overlay_view *ov);
|
||||
|
||||
#endif
|
@ -1,812 +0,0 @@
|
||||
/*
|
||||
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
|
||||
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
|
||||
|
||||
*/
|
||||
#include <Accelerant.h>
|
||||
#include "voodoo3_io.h"
|
||||
#include "voodoo3_accelerant.h"
|
||||
#include "GlobalData.h"
|
||||
#include <ByteOrder.h>
|
||||
|
||||
static Voodoo3Accel accel = { 0, 0, 0, 0, 0};
|
||||
#define abs(x) (x<0?-x:x)
|
||||
|
||||
|
||||
static __inline__ void
|
||||
write_crt_registers(uint8 reg, uint8 val)
|
||||
{
|
||||
outw(accel.io_base + CRTC_INDEX - 0x300, (val << 8) | reg);
|
||||
}
|
||||
|
||||
|
||||
static __inline__ void
|
||||
write_seq_registers(uint8 reg, uint8 val)
|
||||
{
|
||||
outw(accel.io_base + SEQ_INDEX - 0x300, (val << 8) | reg);
|
||||
}
|
||||
|
||||
|
||||
static __inline__ void
|
||||
write_graph_registers(uint8 reg, uint8 val)
|
||||
{
|
||||
outw(accel.io_base + GRA_INDEX - 0x300, (val << 8) | reg);
|
||||
}
|
||||
|
||||
|
||||
static __inline__ void
|
||||
write_attr_registers(uint8 reg, uint8 val)
|
||||
{
|
||||
uint8 index;
|
||||
inb (accel.io_base + IS1_R - 0x300);
|
||||
index = inb(accel.io_base + ATT_IW - 0x300);
|
||||
outb(accel.io_base + ATT_IW - 0x300, reg);
|
||||
outb(accel.io_base + ATT_IW - 0x300, val);
|
||||
outb(accel.io_base + ATT_IW - 0x300, index);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
vga_outb(unsigned long reg, unsigned char val)
|
||||
{
|
||||
outb(accel.io_base + reg - 0x300, val);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
voodoo3_write32(unsigned int reg, unsigned long val)
|
||||
{
|
||||
PCI_MEM_WR_32(accel.regs_base + reg, val);
|
||||
}
|
||||
|
||||
|
||||
static inline uint32
|
||||
voodoo3_read32(unsigned int reg)
|
||||
{
|
||||
return PCI_MEM_RD_32(accel.regs_base + reg);
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
voodoo3_make_room(unsigned int len)
|
||||
{
|
||||
while((voodoo3_read32(STATUS) & 0x1f) < len);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
voodoo3_initialize(void)
|
||||
{
|
||||
unsigned long vgainit0 = 0;
|
||||
unsigned long vidcfg = 0;
|
||||
unsigned long cpp = 16;
|
||||
vgainit0 =
|
||||
VGAINIT0_8BIT_DAC |
|
||||
VGAINIT0_EXT_ENABLE |
|
||||
VGAINIT0_WAKEUP_3C3 |
|
||||
VGAINIT0_ALT_READBACK |
|
||||
VGAINIT0_EXTSHIFTOUT;
|
||||
|
||||
vidcfg =
|
||||
VIDCFG_VIDPROC_ENABLE |
|
||||
VIDCFG_DESK_ENABLE |
|
||||
((cpp - 1) << VIDCFG_PIXFMT_SHIFT) |
|
||||
(cpp != 1 ? VIDCFG_CLUT_BYPASS : 0);
|
||||
|
||||
voodoo3_make_room(2);
|
||||
voodoo3_write32(VGAINIT0, vgainit0);
|
||||
voodoo3_write32(VIDPROCCFG, vidcfg);
|
||||
voodoo3_wait_idle();
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
voodoo3_init(uint8 *registers_base, uint32 io_base)
|
||||
{
|
||||
if(!registers_base) return 0;
|
||||
accel.regs_base = registers_base;
|
||||
accel.io_base = io_base;
|
||||
voodoo3_initialize();
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
voodoo3_bits_per_pixel(void)
|
||||
{
|
||||
return accel.bpp;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
voodoo3_set_monitor_defaults(void)
|
||||
{
|
||||
MonitorRegs m;
|
||||
MonitorRegs *mode;
|
||||
int i;
|
||||
|
||||
memset(&m, 0, sizeof(MonitorRegs));
|
||||
|
||||
mode = &m;
|
||||
mode->crtc_regs[0] = 159;
|
||||
mode->crtc_regs[1] = 127;
|
||||
mode->crtc_regs[2] = 127;
|
||||
mode->crtc_regs[3] = 131;
|
||||
mode->crtc_regs[4] = 129;
|
||||
|
||||
mode->crtc_regs[5] = 141;
|
||||
mode->crtc_regs[6] = 30;
|
||||
mode->crtc_regs[7] = 245;
|
||||
mode->crtc_regs[8] = 0;
|
||||
mode->crtc_regs[9] = 96;
|
||||
|
||||
mode->crtc_regs[10] = 0;
|
||||
mode->crtc_regs[11] = 0;
|
||||
mode->crtc_regs[12] = 0;
|
||||
mode->crtc_regs[13] = 0;
|
||||
mode->crtc_regs[14] = 0;
|
||||
mode->crtc_regs[15] = 0;
|
||||
|
||||
mode->crtc_regs[16] = 1;
|
||||
mode->crtc_regs[17] = 36;
|
||||
mode->crtc_regs[18] = 255;
|
||||
mode->crtc_regs[19] = 127;
|
||||
mode->crtc_regs[20] = 0;
|
||||
mode->crtc_regs[21] = 255;
|
||||
|
||||
mode->crtc_regs[22] = 31;
|
||||
mode->crtc_regs[23] = 128;
|
||||
mode->crtc_regs[24] = 255;
|
||||
|
||||
vga_outb(MISC_W, 0x0f);
|
||||
|
||||
for (i = 0; i < 0x19; i ++)
|
||||
write_crt_registers(i, mode->crtc_regs[i]);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
voodoo3_wait_idle(void)
|
||||
{
|
||||
int i = 0;
|
||||
|
||||
voodoo3_make_room(1);
|
||||
voodoo3_write32(COMMAND_3D, COMMAND_3D_NOP);
|
||||
|
||||
while(1) {
|
||||
i = (voodoo3_read32(STATUS) & STATUS_BUSY) ? 0 : i + 1;
|
||||
if(i == 3) break;
|
||||
}
|
||||
}
|
||||
|
||||
#define REFFREQ 14318.18
|
||||
|
||||
static int
|
||||
voodoo3_calc_pll(int freq, int *f_out, int isBanshee)
|
||||
{
|
||||
int m, n, k, best_m, best_n, best_k, f_cur, best_error;
|
||||
int minm, maxm;
|
||||
|
||||
best_error=freq;
|
||||
best_n=best_m=best_k=0;
|
||||
if (isBanshee) {
|
||||
minm=24;
|
||||
maxm=24;
|
||||
} else {
|
||||
minm=1;
|
||||
maxm=57; /* This used to be 64, alas it seems the last 8 (funny that ?)
|
||||
* values cause jittering at lower resolutions. I've not done
|
||||
* any calculations to what the adjustment affects clock ranges,
|
||||
* but I can still run at 1600x1200@75Hz */
|
||||
}
|
||||
for (n=1; n<256; n++) {
|
||||
f_cur=REFFREQ*(n+2);
|
||||
if (f_cur<freq) {
|
||||
f_cur=f_cur/3;
|
||||
if (freq-f_cur<best_error) {
|
||||
best_error=freq-f_cur;
|
||||
best_n=n;
|
||||
best_m=1;
|
||||
best_k=0;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
for (m=minm; m<maxm; m++) {
|
||||
for (k=0; k<4; k++) {
|
||||
f_cur=REFFREQ*(n+2)/(m+2)/(1<<k);
|
||||
if (abs(f_cur-freq)<best_error) {
|
||||
best_error=abs(f_cur-freq);
|
||||
best_n=n;
|
||||
best_m=m;
|
||||
best_k=k;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
n=best_n;
|
||||
m=best_m;
|
||||
k=best_k;
|
||||
*f_out=REFFREQ*(n+2)/(m+2)/(1<<k);
|
||||
return (n<<8)|(m<<2)|k;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
voodoo3_setup_monitor(display_mode *dm)
|
||||
{
|
||||
MonitorRegs mod; MonitorRegs *mode;
|
||||
int i;
|
||||
uint32 horizontal_display_end, horizontal_sync_start,
|
||||
horizontal_sync_end, horizontal_total, horizontal_blanking_start,
|
||||
horizontal_blanking_end;
|
||||
|
||||
uint32 vertical_display_enable_end, vertical_sync_start,
|
||||
vertical_sync_end, vertical_total, vertical_blanking_start,
|
||||
vertical_blanking_end;
|
||||
|
||||
uint32 wd; // CRTC offset
|
||||
|
||||
memset(&mod, 0, sizeof(mode));
|
||||
|
||||
mode = &mod;
|
||||
|
||||
wd = (dm->timing.h_display >> 3) - 1;
|
||||
horizontal_display_end = (dm->timing.h_display >> 3) - 1;
|
||||
horizontal_sync_start = (dm->timing.h_sync_start >> 3) - 1;
|
||||
horizontal_sync_end = (dm->timing.h_sync_end >> 3) - 1;
|
||||
horizontal_total = (dm->timing.h_total >> 3) - 1;
|
||||
horizontal_blanking_start = horizontal_display_end;
|
||||
horizontal_blanking_end = horizontal_total;
|
||||
|
||||
vertical_display_enable_end = dm->timing.v_display - 1;
|
||||
vertical_sync_start = dm->timing.v_sync_start;// - 1;
|
||||
vertical_sync_end = dm->timing.v_sync_end;// - 1;
|
||||
vertical_total = dm->timing.v_total - 2;
|
||||
vertical_blanking_start = vertical_display_enable_end;
|
||||
vertical_blanking_end = vertical_total;
|
||||
|
||||
mode->misc =
|
||||
0x0f |
|
||||
(dm->timing.h_display < 400 ? 0xa0 :
|
||||
dm->timing.h_display < 480 ? 0x60 :
|
||||
dm->timing.h_display < 768 ? 0xe0 : 0x20);
|
||||
|
||||
mode->seq_regs[0] = 3;
|
||||
mode->seq_regs[1] = 1;
|
||||
mode->seq_regs[2] = 8;
|
||||
mode->seq_regs[3] = 0;
|
||||
mode->seq_regs[4] = 6;
|
||||
|
||||
// crtc regs start
|
||||
mode->crtc_regs[0] = horizontal_total - 4;
|
||||
mode->crtc_regs[1] = horizontal_display_end;
|
||||
mode->crtc_regs[2] = horizontal_blanking_start;
|
||||
mode->crtc_regs[3] = 0x80 | (horizontal_blanking_end & 0x1f);
|
||||
mode->crtc_regs[4] = horizontal_sync_start;
|
||||
|
||||
mode->crtc_regs[5] = ((horizontal_blanking_end & 0x20) << 2) | (horizontal_sync_end & 0x1f);
|
||||
mode->crtc_regs[6] = vertical_total;
|
||||
mode->crtc_regs[7] = ((vertical_sync_start & 0x200) >> 2) |
|
||||
((vertical_display_enable_end & 0x200) >> 3) |
|
||||
((vertical_total & 0x200) >> 4) |
|
||||
0x10 |
|
||||
((vertical_blanking_start & 0x100) >> 5) |
|
||||
((vertical_sync_start & 0x100) >> 6) |
|
||||
((vertical_display_enable_end & 0x100) >> 7) |
|
||||
((vertical_total & 0x100) >> 8);
|
||||
|
||||
mode->crtc_regs[8] = 0;
|
||||
mode->crtc_regs[9] = 0x40 |
|
||||
((vertical_blanking_start & 0x200) >> 4);
|
||||
|
||||
mode->crtc_regs[10] = 0;
|
||||
mode->crtc_regs[11] = 0;
|
||||
mode->crtc_regs[12] = 0;
|
||||
mode->crtc_regs[13] = 0;
|
||||
mode->crtc_regs[14] = 0;
|
||||
mode->crtc_regs[15] = 0;
|
||||
|
||||
mode->crtc_regs[16] = vertical_sync_start;
|
||||
mode->crtc_regs[17] = (vertical_sync_end & 0x0f) | 0x20;
|
||||
mode->crtc_regs[18] = vertical_display_enable_end;
|
||||
mode->crtc_regs[19] = wd; // CRTC offset
|
||||
mode->crtc_regs[20] = 0;
|
||||
mode->crtc_regs[21] = vertical_blanking_start;
|
||||
|
||||
mode->crtc_regs[22] = vertical_blanking_end + 1;
|
||||
mode->crtc_regs[23] = 128;
|
||||
mode->crtc_regs[24] = 255;
|
||||
|
||||
// attr regs start
|
||||
mode->attr_regs[0] = 0;
|
||||
mode->attr_regs[1] = 0;
|
||||
mode->attr_regs[2] = 0;
|
||||
mode->attr_regs[3] = 0;
|
||||
mode->attr_regs[4] = 0;
|
||||
mode->attr_regs[5] = 0;
|
||||
|
||||
mode->attr_regs[6] = 0;
|
||||
mode->attr_regs[7] = 0;
|
||||
mode->attr_regs[8] = 0;
|
||||
mode->attr_regs[9] = 0;
|
||||
mode->attr_regs[10] = 0;
|
||||
mode->attr_regs[11] = 0;
|
||||
|
||||
mode->attr_regs[12] = 0;
|
||||
mode->attr_regs[13] = 0;
|
||||
mode->attr_regs[14] = 0;
|
||||
mode->attr_regs[15] = 0;
|
||||
mode->attr_regs[16] = 1;
|
||||
mode->attr_regs[17] = 0;
|
||||
mode->attr_regs[18] = 15;
|
||||
mode->attr_regs[19] = 0;
|
||||
// attr regs end
|
||||
|
||||
// graph regs start
|
||||
mode->graph_regs[0] = 159;
|
||||
mode->graph_regs[1] = 127;
|
||||
mode->graph_regs[2] = 127;
|
||||
mode->graph_regs[3] = 131;
|
||||
mode->graph_regs[4] = 130;
|
||||
mode->graph_regs[5] = 142;
|
||||
mode->graph_regs[6] = 30;
|
||||
mode->graph_regs[7] = 245;
|
||||
mode->graph_regs[8] = 0;
|
||||
|
||||
vga_outb(MISC_W, mode->misc | 0x01);
|
||||
|
||||
for(i = 0; i < 5; i++)
|
||||
write_seq_registers(i, mode->seq_regs[i]);
|
||||
for (i = 0; i < 0x19; i ++)
|
||||
write_crt_registers(i, mode->crtc_regs[i]);
|
||||
for (i = 0; i < 0x14; i ++)
|
||||
write_attr_registers(i, mode->attr_regs[i]);
|
||||
for (i = 0; i < 0x09; i ++)
|
||||
write_graph_registers(i, mode->graph_regs[i]);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
voodoo_set_desktop_regs(uint32 bits_per_pixel, display_mode *dm)
|
||||
{
|
||||
uint32 miscinit0=0;
|
||||
int vidpll, fout;
|
||||
int vidproc = VIDPROCDEFAULT;
|
||||
uint32 bpp = (bits_per_pixel + 7) / 8;
|
||||
uint32 bytes_per_row = (dm->virtual_width * bits_per_pixel + 7) / 8;
|
||||
|
||||
accel.bpp = bits_per_pixel;
|
||||
accel.width = dm->virtual_width;
|
||||
accel.height = dm->virtual_height;
|
||||
voodoo3_setup_monitor(dm);
|
||||
|
||||
vidproc &= ~(0x1c0000); // clear bits 18 to 20, bpp in vidproccfg
|
||||
vidproc |= ((bpp - 1) << VIDCFG_PIXFMT_SHIFT); // enable bits 18 to 20 to the required bpp
|
||||
vidpll = voodoo3_calc_pll(dm->timing.pixel_clock, &fout, 0);
|
||||
|
||||
switch(bits_per_pixel) { // bit 10 of vidproccfg, is enabled or disabled as needed for the Desktop
|
||||
case 8:
|
||||
vidproc &= ~(1 << 10); // bit 10 off for palettized modes only, off means palette is used
|
||||
break;
|
||||
case 16:
|
||||
#if __POWERPC__
|
||||
miscinit0 = 0xc0000000;
|
||||
#endif
|
||||
vidproc |= (1 << 10); // bypass palette for 16bit modes
|
||||
break;
|
||||
case 32:
|
||||
#if __POWERPC__
|
||||
miscinit0 = 0x40000000;
|
||||
#endif
|
||||
vidproc |= (1 << 10); // Same for 32bit modes
|
||||
break;
|
||||
}
|
||||
|
||||
voodoo3_wait_idle();
|
||||
|
||||
voodoo3_write32(MISCINIT1, voodoo3_read32(MISCINIT1) | 0x01);
|
||||
|
||||
voodoo3_make_room(4);
|
||||
voodoo3_write32(VGAINIT0, 4928);
|
||||
voodoo3_write32(DACMODE, 0);
|
||||
voodoo3_write32(VIDDESKSTRIDE, bytes_per_row);
|
||||
voodoo3_write32(PLLCTRL0, vidpll);
|
||||
|
||||
voodoo3_make_room(5);
|
||||
voodoo3_write32(VIDSCREENSIZE, dm->virtual_width | (dm->virtual_height << 12));
|
||||
voodoo3_write32(VIDDESKSTART, 1024);
|
||||
voodoo3_write32(VIDPROCCFG, vidproc);
|
||||
voodoo3_write32(VGAINIT1, 0);
|
||||
voodoo3_write32(MISCINIT0, miscinit0);
|
||||
|
||||
voodoo3_make_room(8);
|
||||
voodoo3_write32(SRCBASE, 1024);
|
||||
voodoo3_write32(DSTBASE, 1024);
|
||||
voodoo3_write32(COMMANDEXTRA_2D, 0);
|
||||
voodoo3_write32(CLIP0MIN, 0);
|
||||
voodoo3_write32(CLIP0MAX, 0x0fff0fff);
|
||||
voodoo3_write32(CLIP1MIN, 0);
|
||||
voodoo3_write32(CLIP1MAX, 0x0fff0fff);
|
||||
voodoo3_write32(SRCXY, 0);
|
||||
voodoo3_wait_idle();
|
||||
}
|
||||
|
||||
#if __POWERPC__
|
||||
// ToDo: use the standard ByteOrder.h macros!
|
||||
static uint32
|
||||
ppcSwap(uint32 val, uint32 bpp)
|
||||
{
|
||||
switch (bpp) {
|
||||
default:
|
||||
return val;
|
||||
case 16:
|
||||
return ((val & 0x00ff00ff) << 8) |
|
||||
((val & 0xff00ff00) >> 8);
|
||||
case 24:
|
||||
case 32:
|
||||
return ((((val) & 0x000000ff) << 24) |
|
||||
(((val) & 0x0000ff00) << 8) |
|
||||
(((val) & 0x00ff0000) >> 8) |
|
||||
(((val) & 0xff000000) >> 24));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void
|
||||
voodoo3_set_cursor(uint8 *data, uint16 width, uint8 height, uint8 *andMask,
|
||||
uint8 *xorMask)
|
||||
{
|
||||
int i;
|
||||
uint32 fbcurptr=voodoo3_read32(HWCURPATADDR);
|
||||
uint8 *cursor = (uint8 *)data + fbcurptr;
|
||||
uint16 *xordata = (uint16 *)xorMask;
|
||||
uint16 *anddata = (uint16 *)andMask;
|
||||
uint64 *cursor64 = (uint64 *)cursor;
|
||||
#if __POWERPC__
|
||||
uint32 *cursor32 = (uint32 *)data + fbcurptr;
|
||||
#endif
|
||||
for(i = 0; i < 16; i++) {
|
||||
*cursor64++ = ((~0 << 16) | (*anddata++));
|
||||
*cursor64++ = ((0 << 16) | (*xordata++));
|
||||
}
|
||||
|
||||
for(i = 128; i < 176; i++) {
|
||||
*cursor64++ = ~0;
|
||||
*cursor64++ = 0;
|
||||
}
|
||||
// for PPC Byteswapping
|
||||
#if __POWERPC__
|
||||
for (i=0; i<256; i++) {
|
||||
uint32 val = cursor32[i];
|
||||
cursor32[i] = ppcSwap(val,accel.bpp);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
voodoo3_init_cursor_address(void)
|
||||
{
|
||||
voodoo3_make_room(1);
|
||||
voodoo3_write32(HWCURPATADDR, 0);
|
||||
voodoo3_wait_idle();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
voodoo3_set_cursor_colors(int fg, int bg)
|
||||
{
|
||||
voodoo3_make_room(2);
|
||||
voodoo3_write32(HWCURC0, bg & 0xffffff);
|
||||
voodoo3_write32(HWCURC1, fg & 0xffffff);
|
||||
voodoo3_wait_idle();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
voodoo3_show_cursor(void)
|
||||
{
|
||||
voodoo3_make_room(1);
|
||||
voodoo3_write32(VIDPROCCFG, voodoo3_read32(VIDPROCCFG) | (1 << 27));
|
||||
voodoo3_wait_idle();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
voodoo3_hide_cursor(void)
|
||||
{
|
||||
voodoo3_make_room(1);
|
||||
voodoo3_write32(VIDPROCCFG, voodoo3_read32(VIDPROCCFG) & ~(1 << 27));
|
||||
voodoo3_wait_idle();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
voodoo3_move_cursor(int x, int y)
|
||||
{
|
||||
#if __INTEL__
|
||||
#define xoffset 63
|
||||
#define yoffset 63
|
||||
#else
|
||||
#define xoffset 15
|
||||
#define yoffset 63
|
||||
#endif
|
||||
x += xoffset;
|
||||
y += yoffset;
|
||||
voodoo3_write32(HWCURLOC, x | (y << 16));
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
voodoo3_screen_to_screen_blit(list_packet_blit *list, uint32 bytes_per_row,
|
||||
uint32 bits_per_pixel)
|
||||
{
|
||||
uint32 fmt = bytes_per_row | ((bits_per_pixel + ((bits_per_pixel == 8) ? 0 : 8)) << 13);
|
||||
uint32 blitcmd = COMMAND_2D_S2S_BITBLT | (ROP_COPY << 24);
|
||||
|
||||
if (list->src_x <= list->dest_x) {
|
||||
blitcmd |= BIT(14);
|
||||
list->src_x += (list->width - 1); list->dest_x += (list->width - 1);
|
||||
}
|
||||
if (list->src_y <= list->dest_y) {
|
||||
blitcmd |= BIT(15);
|
||||
list->src_y += (list->height - 1); list->dest_y += (list->height - 1);
|
||||
}
|
||||
voodoo3_make_room(6);
|
||||
|
||||
voodoo3_write32(SRCFORMAT, fmt);
|
||||
voodoo3_write32(DSTFORMAT, fmt);
|
||||
voodoo3_write32(COMMAND_2D, blitcmd);
|
||||
voodoo3_write32(DSTSIZE, list->width | (list->height << 16));
|
||||
voodoo3_write32(DSTXY, list->dest_x | (list->dest_y << 16));
|
||||
voodoo3_write32(LAUNCH_2D, list->src_x | (list->src_y << 16));
|
||||
voodoo3_wait_idle();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
voodoo3_fill_rect(list_packet *list, uint32 color, uint32 bytes_per_row,
|
||||
uint32 bits_per_pixel)
|
||||
{
|
||||
uint32 fmt;
|
||||
fmt = bytes_per_row | ((bits_per_pixel + ((bits_per_pixel == 8) ? 0 : 8)) << 13);
|
||||
|
||||
voodoo3_make_room(5);
|
||||
voodoo3_write32(DSTFORMAT, fmt);
|
||||
voodoo3_write32(COLORFORE, color);
|
||||
voodoo3_write32(COMMAND_2D, COMMAND_2D_FILLRECT | (ROP_COPY << 24));
|
||||
voodoo3_write32(DSTSIZE, list->w | (list->h << 16));
|
||||
voodoo3_write32(LAUNCH_2D, list->x | (list->y << 16));
|
||||
voodoo3_wait_idle();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
voodoo3_invert_rect(list_packet *list, uint32 color, uint32 bytes_per_row,
|
||||
uint32 bits_per_pixel)
|
||||
{
|
||||
uint32 fmt;
|
||||
fmt = bytes_per_row | ((bits_per_pixel + ((bits_per_pixel == 8) ? 0 : 8)) << 13);
|
||||
|
||||
voodoo3_make_room(5);
|
||||
voodoo3_write32(DSTFORMAT, fmt);
|
||||
voodoo3_write32(COLORFORE, color);
|
||||
voodoo3_write32(COMMAND_2D, COMMAND_2D_FILLRECT | (ROP_INVERT << 24));
|
||||
voodoo3_write32(DSTSIZE, list->w | (list->h << 16));
|
||||
voodoo3_write32(LAUNCH_2D, list->x | (list->y << 16));
|
||||
voodoo3_wait_idle();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
voodoo3_fill_span(list_packet *list, uint32 color, uint32 bytes_per_row,
|
||||
uint32 bits_per_pixel)
|
||||
{
|
||||
uint32 fmt;
|
||||
fmt = bytes_per_row | ((bits_per_pixel + ((bits_per_pixel == 8) ? 0 : 8)) << 13);
|
||||
|
||||
voodoo3_make_room(5);
|
||||
voodoo3_write32(DSTFORMAT, fmt);
|
||||
voodoo3_write32(COLORFORE, color);
|
||||
voodoo3_write32(COMMAND_2D, COMMAND_2D_FILLRECT | (ROP_COPY << 24));
|
||||
voodoo3_write32(DSTSIZE, list->w | (list->h << 16));
|
||||
voodoo3_write32(LAUNCH_2D, list->x | (list->y << 16));
|
||||
voodoo3_wait_idle();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
voodoo3_set_palette(int index, uint32 color)
|
||||
{
|
||||
|
||||
voodoo3_make_room(2);
|
||||
voodoo3_write32(DACADDR, index);
|
||||
voodoo3_write32(DACDATA, color);
|
||||
|
||||
}
|
||||
|
||||
|
||||
uint32
|
||||
voodoo3_get_memory_size(void)
|
||||
{
|
||||
uint32 draminit0 = 0;
|
||||
uint32 draminit1 = 0;
|
||||
uint32 miscinit1 = 0;
|
||||
uint32 lfbsize = 0;
|
||||
int32 sgram_p = 0;
|
||||
draminit0 = voodoo3_read32(DRAMINIT0);
|
||||
draminit1 = voodoo3_read32(DRAMINIT1);
|
||||
sgram_p = (draminit1 & DRAMINIT1_MEM_SDRAM) ? 0 : 1;
|
||||
lfbsize = sgram_p ?
|
||||
(((draminit0 & DRAMINIT0_SGRAM_NUM) ? 2 : 1) *
|
||||
((draminit0 & DRAMINIT0_SGRAM_TYPE) ? 8 : 4) * 1024 * 1024) :
|
||||
16 * 1024 * 1024;
|
||||
|
||||
/* disable block writes for SDRAM (why?) */
|
||||
miscinit1 = voodoo3_read32(MISCINIT1);
|
||||
miscinit1 |= sgram_p ? 0 : MISCINIT1_2DBLOCK_DIS;
|
||||
miscinit1 |= MISCINIT1_CLUT_INV;
|
||||
voodoo3_make_room(1);
|
||||
voodoo3_write32(MISCINIT1, miscinit1);
|
||||
return lfbsize;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
voodoo3_display_overlay(const overlay_window *ow, const overlay_buffer *ob,
|
||||
const overlay_view *ov)
|
||||
{
|
||||
uint8 red, green, blue;
|
||||
|
||||
int32 offset;
|
||||
int32 pitch;
|
||||
int32 dudx, dvdy;
|
||||
uint32 left=0;
|
||||
uint32 srcwidth;
|
||||
uint32 vidcfg, stride;
|
||||
uint32 x1, y1, x2, y2;
|
||||
uint32 offset_left, offset_top;
|
||||
|
||||
if (ow==NULL||ob==NULL||ov==NULL) return;
|
||||
|
||||
offset=(uint32)ob->buffer_dma; // Start OFFSET as PCI Space
|
||||
pitch=((ob->width<<1) + 3) & ~3; // offset (of Desktop && Overlay)
|
||||
|
||||
|
||||
offset_left=ow->h_start<0?-ow->h_start:0;
|
||||
offset_top=ow->v_start<0?-ow->v_start:0;
|
||||
|
||||
dudx = (ob->width << 20) / (ow->width);
|
||||
dvdy = (ob->height << 20) / (ow->height);
|
||||
|
||||
left = ((offset_left*dudx<<16) & 0x0001ffff) << 3;
|
||||
|
||||
x1=ow->h_start + offset_left;
|
||||
y1=ow->v_start + offset_top;
|
||||
x2=x1 + ow->width;
|
||||
if (x2>=accel.width) x2=accel.width;
|
||||
y2=y1 + ow->height;
|
||||
if (y2>=accel.height) y2=accel.height;
|
||||
|
||||
offset+=((offset_left*dudx>>20) & ~1) << 1;
|
||||
srcwidth=(ob->width<<20);
|
||||
|
||||
vidcfg=voodoo3_read32(VIDPROCCFG);
|
||||
stride=voodoo3_read32(VIDDESKTOPOVERLAYSTRIDE);
|
||||
|
||||
vidcfg &= ~VIDPROCCFGMASK;
|
||||
vidcfg |= VIDCFG_CHROMA_KEY | VIDCFG_OVL_ENABLE | VIDCFG_OVL_NOT_VIDEO_IN |
|
||||
VIDCFG_OVL_CLUT_BYPASS;
|
||||
|
||||
if(ob->width != ow->width)
|
||||
vidcfg |= VIDCFG_OVL_HSCALE;
|
||||
if(ob->height != ow->height)
|
||||
vidcfg |= VIDCFG_OVL_VSCALE;
|
||||
|
||||
switch( ob->space) {
|
||||
case B_YCbCr422:
|
||||
#if __POWERPC__
|
||||
switch(accel.bpp) {
|
||||
case 8:
|
||||
vidcfg |= VIDCFG_OVL_FMT_YUYV422 << VIDCFG_OVL_FMT_SHIFT;
|
||||
break;
|
||||
case 16:
|
||||
vidcfg |= VIDCFG_OVL_FMT_UYVY422 << VIDCFG_OVL_FMT_SHIFT;
|
||||
break;
|
||||
default:
|
||||
ddpf(( "YCbCr overlays aren't supported in 32 bit mode" ));
|
||||
return;
|
||||
}
|
||||
#else
|
||||
vidcfg |= VIDCFG_OVL_FMT_YUYV422 << VIDCFG_OVL_FMT_SHIFT;
|
||||
#endif
|
||||
break;
|
||||
#if __POWERPC__
|
||||
case B_RGB16_BIG:
|
||||
#else
|
||||
case B_RGB16:
|
||||
#endif
|
||||
vidcfg |= VIDCFG_OVL_FMT_RGB565 << VIDCFG_OVL_FMT_SHIFT;
|
||||
break;
|
||||
default: return;
|
||||
|
||||
}
|
||||
|
||||
/* can't do bilinear filtering when in 2X mode */
|
||||
if( (vidcfg & VIDCFG_2X) == 0 )
|
||||
vidcfg |= VIDCFG_OVL_FILTER_BILIN << VIDCFG_OVL_FILTER_SHIFT;
|
||||
|
||||
voodoo3_make_room( 12 );
|
||||
|
||||
voodoo3_write32(VIDPROCCFG, vidcfg);
|
||||
|
||||
if ((ow->flags & B_OVERLAY_COLOR_KEY)==B_OVERLAY_COLOR_KEY) {
|
||||
uint32 color=0;
|
||||
red=ow->red.value & ow->red.mask;
|
||||
green=ow->green.value & ow->green.mask;
|
||||
blue=ow->blue.value & ow->blue.mask;
|
||||
switch (voodoo3_bits_per_pixel()) {
|
||||
case(8):
|
||||
case(32):
|
||||
color= (red << 16)+(green << 8)+(blue << 0);
|
||||
break;
|
||||
case(16):
|
||||
color= (red << 11)+(green << 5)+(blue << 0);
|
||||
break;
|
||||
}
|
||||
voodoo3_write32(VIDCHROMAMIN, color);
|
||||
voodoo3_write32(VIDCHROMAMAX, color);
|
||||
}
|
||||
|
||||
/* Setting up position of Overlaywindow on Screen */
|
||||
voodoo3_write32(VIDOVERLAYSTARTCOORDS, x1 | (y1 << 12));
|
||||
voodoo3_write32(VIDOVERLAYENDSCREENCOORDS, (x2 - 1) | ((y2 - 1) << 12));
|
||||
/* Setting up scale and position of overlay in Graphics Memory */
|
||||
voodoo3_write32(VIDOVERLAYDUDX, dudx);
|
||||
voodoo3_write32(VIDOVERLAYDUDXOFFSETSRCWIDTH, left | srcwidth);
|
||||
voodoo3_write32(VIDOVERLAYDVDY, dvdy);
|
||||
voodoo3_write32(VIDOVERLAYDVDYOFFSET, (y1 & 0x0000ffff) << 3);
|
||||
|
||||
stride &= 0x0000ffff;
|
||||
stride |= pitch << 16;
|
||||
|
||||
voodoo3_write32(VIDDESKTOPOVERLAYSTRIDE, stride);
|
||||
voodoo3_write32(SST_3D_LEFTOVERLAYBUF, offset);
|
||||
voodoo3_write32(VIDINADDR0, offset);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
voodoo3_reset_overlay(void)
|
||||
{
|
||||
uint32 vidcfg, stride;
|
||||
|
||||
vidcfg=voodoo3_read32(VIDPROCCFG);
|
||||
stride=voodoo3_read32(VIDDESKTOPOVERLAYSTRIDE);
|
||||
|
||||
|
||||
/* reset the video */
|
||||
vidcfg &= ~VIDPROCCFGMASK;
|
||||
voodoo3_write32(VIDPROCCFG, vidcfg);
|
||||
voodoo3_write32(RGBMAXDELTA, 0x0080808);
|
||||
voodoo3_write32(VIDCHROMAMIN, 0);
|
||||
voodoo3_write32(VIDCHROMAMAX, 0);
|
||||
}
|
||||
|
||||
|
||||
// To stop the overlay
|
||||
|
||||
void
|
||||
voodoo3_stop_overlay(void)
|
||||
{
|
||||
uint32 vidcfg;
|
||||
|
||||
vidcfg=voodoo3_read32(VIDPROCCFG);
|
||||
|
||||
/* reset the video */
|
||||
vidcfg &= ~VIDPROCCFGMASK;
|
||||
voodoo3_write32(VIDPROCCFG, vidcfg);
|
||||
}
|
||||
|
@ -1,82 +0,0 @@
|
||||
/*
|
||||
- Overlay support
|
||||
- PPC Port: Andreas Drewke (andreas_dr@gmx.de)
|
||||
- Voodoo3Driver 0.02 (c) by Carwyn Jones (2002)
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __VOODOO3_ACCELERANT_H__
|
||||
#define __VOODOO3_ACCELERANT_H__
|
||||
|
||||
#include <SupportDefs.h>
|
||||
#include <video_overlay.h>
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8 *regs_base;
|
||||
uint32 io_base;
|
||||
uint32 bpp, width, height;
|
||||
} Voodoo3Accel;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8 seq_regs[5];
|
||||
uint8 crtc_regs[25];
|
||||
uint8 attr_regs[21];
|
||||
uint8 graph_regs[9];
|
||||
uint8 misc;
|
||||
} MonitorRegs;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
} list_packet;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int src_x;
|
||||
int src_y;
|
||||
int dest_x;
|
||||
int dest_y;
|
||||
int width;
|
||||
int height;
|
||||
} list_packet_blit;
|
||||
|
||||
// Initialize
|
||||
int voodoo3_init(uint8 *registers_base, uint32 io_base);
|
||||
void voodoo3_set_monitor_defaults(void);
|
||||
void voodoo3_wait_idle(void);
|
||||
void voodoo_set_desktop_regs(uint32 bpp, display_mode *dm);
|
||||
|
||||
// Cursor functionality
|
||||
void voodoo3_show_cursor(void);
|
||||
void voodoo3_hide_cursor(void);
|
||||
void voodoo3_move_cursor(int x, int y);
|
||||
void voodoo3_set_cursor(uint8 *data, uint16 width, uint8 height, uint8 *andMask, uint8 *xorMask);
|
||||
void voodoo3_set_cursor_colors(int bg, int fg);
|
||||
void voodoo3_init_cursor_address(void);
|
||||
|
||||
// handle colortable
|
||||
void voodoo3_set_palette(int index, uint32 color);
|
||||
|
||||
// accelerated 2d functions
|
||||
void voodoo3_screen_to_screen_blit(list_packet_blit *list, uint32 bytes_per_row, uint32 bits_per_pixel);
|
||||
void voodoo3_fill_rect(list_packet *list, uint32 color, uint32 bytes_per_row, uint32 bits_per_pixel);
|
||||
void voodoo3_invert_rect(list_packet *list, uint32 color, uint32 bytes_per_row, uint32 bits_per_pixel);
|
||||
void voodoo3_fill_span(list_packet *list, uint32 color, uint32 bytes_per_row, uint32 bits_per_pixel);
|
||||
|
||||
// Runtime information
|
||||
uint32 voodoo3_bits_per_pixel(void);
|
||||
uint32 voodoo3_get_memory_size(void);
|
||||
|
||||
void voodoo3_setup_monitor(display_mode *);
|
||||
|
||||
// Overlay
|
||||
void voodoo3_display_overlay(const overlay_window *ow, const overlay_buffer *ob, const overlay_view* ov);
|
||||
void voodoo3_reset_overlay(void);
|
||||
void voodoo3_stop_overlay(void);
|
||||
|
||||
#endif
|
@ -1,182 +0,0 @@
|
||||
#ifndef __VOODOO3_IO_H__
|
||||
#define __VOODOO3_IO_H__
|
||||
|
||||
#include <ByteOrder.h>
|
||||
|
||||
// voodoo3 register locations in pci memory space
|
||||
/* membase0 register offsets */
|
||||
#define STATUS 0x00
|
||||
#define PCIINIT0 0x04
|
||||
#define SIPMONITOR 0x08
|
||||
#define LFBMEMORYCONFIG 0x0c
|
||||
#define MISCINIT0 0x10
|
||||
#define MISCINIT1 0x14
|
||||
#define DRAMINIT0 0x18
|
||||
#define DRAMINIT1 0x1c
|
||||
#define AGPINIT 0x20
|
||||
#define TMUGBEINIT 0x24
|
||||
#define VGAINIT0 0x28
|
||||
#define VGAINIT1 0x2c
|
||||
#define DRAMCOMMAND 0x30
|
||||
#define DRAMDATA 0x34
|
||||
/* reserved 0x38 */
|
||||
/* reserved 0x3c */
|
||||
#define PLLCTRL0 0x40
|
||||
#define PLLCTRL1 0x44
|
||||
#define PLLCTRL2 0x48
|
||||
#define DACMODE 0x4c
|
||||
#define DACADDR 0x50
|
||||
#define DACDATA 0x54
|
||||
#define RGBMAXDELTA 0x58
|
||||
#define VIDPROCCFG 0x5c
|
||||
#define HWCURPATADDR 0x60
|
||||
#define HWCURLOC 0x64
|
||||
#define HWCURC0 0x68
|
||||
#define HWCURC1 0x6c
|
||||
#define VIDINFORMAT 0x70
|
||||
#define VIDINSTATUS 0x74
|
||||
#define VIDSERPARPORT 0x78
|
||||
#define VIDINXDELTA 0x7c
|
||||
#define VIDININITERR 0x80
|
||||
#define VIDINYDELTA 0x84
|
||||
#define VIDPIXBUFTHOLD 0x88
|
||||
#define VIDCHRMIN 0x8c
|
||||
#define VIDCHRMAX 0x90
|
||||
#define VIDCURLIN 0x94
|
||||
#define VIDSCREENSIZE 0x98
|
||||
#define VIDOVRSTARTCRD 0x9c
|
||||
#define VIDOVRENDCRD 0xa0
|
||||
#define VIDOVRDUDX 0xa4
|
||||
#define VIDOVRDUDXOFF 0xa8
|
||||
#define VIDOVRDVDY 0xac
|
||||
/* ... */
|
||||
|
||||
#define VIDOVRDVDYOFF 0xe0
|
||||
#define VIDDESKSTART 0xe4
|
||||
#define VIDDESKSTRIDE 0xe8
|
||||
#define VIDINADDR0 0xec
|
||||
#define VIDINADDR1 0xf0
|
||||
#define VIDINADDR2 0xf4
|
||||
#define VIDINSTRIDE 0xf8
|
||||
#define VIDCUROVRSTART 0xfc
|
||||
#define VIDOVERLAYSTARTCOORDS 0x9c
|
||||
#define VIDOVERLAYENDSCREENCOORDS 0xa0
|
||||
#define VIDOVERLAYDUDX 0xa4
|
||||
#define VIDOVERLAYDUDXOFFSETSRCWIDTH 0xa8
|
||||
#define VIDOVERLAYDVDY 0xac
|
||||
#define VIDOVERLAYDVDYOFFSET 0xe0
|
||||
|
||||
#define SST_3D_OFFSET 0x200000
|
||||
#define SST_3D_LEFTOVERLAYBUF SST_3D_OFFSET+0x250
|
||||
|
||||
#define INTCTRL (0x00100000 + 0x04)
|
||||
#define CLIP0MIN (0x00100000 + 0x08)
|
||||
#define CLIP0MAX (0x00100000 + 0x0c)
|
||||
#define DSTBASE (0x00100000 + 0x10)
|
||||
#define DSTFORMAT (0x00100000 + 0x14)
|
||||
#define SRCBASE (0x00100000 + 0x34)
|
||||
#define COMMANDEXTRA_2D (0x00100000 + 0x38)
|
||||
#define CLIP1MIN (0x00100000 + 0x4c)
|
||||
#define CLIP1MAX (0x00100000 + 0x50)
|
||||
#define SRCFORMAT (0x00100000 + 0x54)
|
||||
#define SRCSIZE (0x00100000 + 0x58)
|
||||
#define SRCXY (0x00100000 + 0x5c)
|
||||
#define COLORBACK (0x00100000 + 0x60)
|
||||
#define COLORFORE (0x00100000 + 0x64)
|
||||
#define DSTSIZE (0x00100000 + 0x68)
|
||||
#define DSTXY (0x00100000 + 0x6c)
|
||||
#define COMMAND_2D (0x00100000 + 0x70)
|
||||
#define LAUNCH_2D (0x00100000 + 0x80)
|
||||
|
||||
#define COMMAND_3D (0x00200000 + 0x120)
|
||||
|
||||
/* register bitfields (not all, only as needed) */
|
||||
|
||||
#define BIT(x) (1UL << (x))
|
||||
|
||||
/* COMMAND_2D reg. values */
|
||||
#define ROP_COPY 0xcc // src
|
||||
#define ROP_INVERT 0x55 // NOT dst
|
||||
#define ROP_XOR 0x66 // src XOR dst
|
||||
|
||||
#define AUTOINC_DSTX BIT(10)
|
||||
#define AUTOINC_DSTY BIT(11)
|
||||
#define COMMAND_2D_FILLRECT 0x05
|
||||
#define COMMAND_2D_S2S_BITBLT 0x01 // screen to screen
|
||||
#define COMMAND_2D_H2S_BITBLT 0x03 // host to screen
|
||||
|
||||
|
||||
#define COMMAND_3D_NOP 0x00
|
||||
#define STATUS_RETRACE BIT(6)
|
||||
#define STATUS_BUSY BIT(9)
|
||||
#define MISCINIT1_CLUT_INV BIT(0)
|
||||
#define MISCINIT1_2DBLOCK_DIS BIT(15)
|
||||
#define DRAMINIT0_SGRAM_NUM BIT(26)
|
||||
#define DRAMINIT0_SGRAM_TYPE BIT(27)
|
||||
#define DRAMINIT1_MEM_SDRAM BIT(30)
|
||||
#define VGAINIT0_VGA_DISABLE BIT(0)
|
||||
#define VGAINIT0_EXT_TIMING BIT(1)
|
||||
#define VGAINIT0_8BIT_DAC BIT(2)
|
||||
#define VGAINIT0_EXT_ENABLE BIT(6)
|
||||
#define VGAINIT0_WAKEUP_3C3 BIT(8)
|
||||
#define VGAINIT0_LEGACY_DISABLE BIT(9)
|
||||
#define VGAINIT0_ALT_READBACK BIT(10)
|
||||
#define VGAINIT0_FAST_BLINK BIT(11)
|
||||
#define VGAINIT0_EXTSHIFTOUT BIT(12)
|
||||
#define VGAINIT0_DECODE_3C6 BIT(13)
|
||||
#define VGAINIT0_SGRAM_HBLANK_DISABLE BIT(22)
|
||||
#define VGAINIT1_MASK 0x1fffff
|
||||
#define VIDCFG_VIDPROC_ENABLE BIT(0)
|
||||
#define VIDCFG_CURS_X11 BIT(1)
|
||||
#define VIDCFG_HALF_MODE BIT(4)
|
||||
#define VIDCFG_CHROMA_KEY BIT(5)
|
||||
#define VIDCFG_CHROMA_KEY_INVERSION BIT(6)
|
||||
#define VIDCFG_DESK_ENABLE BIT(7)
|
||||
#define VIDCFG_OVL_ENABLE BIT(8)
|
||||
#define VIDCFG_OVL_NOT_VIDEO_IN BIT(9)
|
||||
#define VIDCFG_CLUT_BYPASS BIT(10)
|
||||
#define VIDCFG_OVL_CLUT_BYPASS BIT(11)
|
||||
#define VIDCFG_OVL_HSCALE BIT(14)
|
||||
#define VIDCFG_OVL_VSCALE BIT(15)
|
||||
#define VIDCFG_OVL_FILTER_SHIFT 16
|
||||
#define VIDCFG_OVL_FILTER_POINT 0
|
||||
#define VIDCFG_OVL_FILTER_2X2 1
|
||||
#define VIDCFG_OVL_FILTER_4X4 2
|
||||
#define VIDCFG_OVL_FILTER_BILIN 3
|
||||
#define VIDCFG_OVL_FMT_SHIFT 21
|
||||
#define VIDCFG_OVL_FMT_RGB565 1
|
||||
#define VIDCFG_OVL_FMT_YUV411 4
|
||||
#define VIDCFG_OVL_FMT_YUYV422 5
|
||||
#define VIDCFG_OVL_FMT_UYVY422 6
|
||||
#define VIDCFG_OVL_FMT_RGB565_DITHER 7
|
||||
|
||||
#define VIDCFG_2X BIT(26)
|
||||
#define VIDCFG_HWCURSOR_ENABLE BIT(27)
|
||||
#define VIDCFG_PIXFMT_SHIFT 18
|
||||
#define DACMODE_2X BIT(0)
|
||||
#define VIDPROCCFGMASK 0xa2e3eb6c
|
||||
#define VIDPROCDEFAULT 134481025
|
||||
|
||||
#define VIDCHROMAMIN 0x8c
|
||||
#define VIDCHROMAMAX 0x90
|
||||
#define VIDDESKTOPOVERLAYSTRIDE 0xe8
|
||||
|
||||
#define CRTC_INDEX 0x3d4
|
||||
#define CRTC_DATA 0x3d5
|
||||
#define SEQ_INDEX 0x3c4
|
||||
#define SEQ_DATA 0x3c5
|
||||
#define MISC_W 0x3c2
|
||||
#define GRA_INDEX 0x3ce
|
||||
#define ATT_IW 0x3c0
|
||||
#define IS1_R 0x3da
|
||||
|
||||
// pci read from memory
|
||||
#define PCI_MEM_RD_8(address) (*(volatile uint8 *) (address))
|
||||
#define PCI_MEM_RD_16(address) B_LENDIAN_TO_HOST_INT16((*(volatile uint16 *) (address)))
|
||||
#define PCI_MEM_RD_32(address) B_LENDIAN_TO_HOST_INT32((*(volatile uint32 *) (address)))
|
||||
// pci write to memory
|
||||
#define PCI_MEM_WR_8(address, value) ((*(volatile uint8 *) (address)) = (uint8) (value))
|
||||
#define PCI_MEM_WR_16(address, value) ((*(volatile uint16 *) (address)) = (uint16) B_HOST_TO_LENDIAN_INT16((value))
|
||||
#define PCI_MEM_WR_32(address, value) ((*(volatile uint32 *) (address)) = (uint32) B_HOST_TO_LENDIAN_INT32(value))
|
||||
|
||||
#endif
|
@ -13,7 +13,6 @@ SubInclude HAIKU_TOP src add-ons kernel drivers graphics radeon ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers graphics radeon_hd ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers graphics s3 ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers graphics skeleton ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers graphics tdfx ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers graphics vesa ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers graphics via ;
|
||||
SubInclude HAIKU_TOP src add-ons kernel drivers graphics vmware ;
|
||||
|
@ -1,9 +0,0 @@
|
||||
SubDir HAIKU_TOP src add-ons kernel drivers graphics tdfx ;
|
||||
|
||||
UsePrivateHeaders graphics ;
|
||||
UsePrivateHeaders [ FDirName graphics tdfx ] ;
|
||||
|
||||
KernelAddon tdfx.driver :
|
||||
driver.c
|
||||
;
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user