#define MODULE_BIT 0x00200000
#include "acc_std.h"
static void
interrupt_enable(bool flag)
{
nm_set_bool_state sbs;
if (si->ps.int_assigned) {
sbs.magic = NM_PRIVATE_DATA_MAGIC;
sbs.do_it = flag;
ioctl(fd, NM_RUN_INTERRUPTS, &sbs, sizeof(sbs));
}
}
status_t SET_DISPLAY_MODE(display_mode *mode_to_set)
{
display_mode target;
uint8 colour_depth = 24;
uint32 startadd;
bool crt_only = true;
target = *mode_to_set;
LOG(1, ("SETMODE: (ENTER) initial modeflags: $%08x\n", target.flags));
LOG(1, ("SETMODE: requested target pixelclock %dkHz\n", target.timing.pixel_clock));
LOG(1, ("SETMODE: requested virtual_width %d, virtual_height %d\n",
target.virtual_width, target.virtual_height));
if (PROPOSE_DISPLAY_MODE(&target, &target, &target) == B_ERROR) return B_ERROR;
interrupt_enable(false);
nm_unlock();
if (nm_general_output_read() & 0x02)
{
LOG(4,("SETMODE: internal flatpanel enabled, skipping CRTC/pixelPLL setup\n"));
crt_only = false;
}
nm_crtc_dpms(false, false, false);
startadd = (uint8*)si->fbc.frame_buffer - (uint8*)si->framebuffer;
{
status_t status = B_OK;
int colour_mode = BPP24;
switch(target.space)
{
case B_CMAP8: colour_depth = 8; colour_mode = BPP8; break;
case B_RGB15_LITTLE: colour_depth = 16; colour_mode = BPP15; break;
case B_RGB16_LITTLE: colour_depth = 16; colour_mode = BPP16; break;
case B_RGB24_LITTLE: colour_depth = 24; colour_mode = BPP24; break;
default:
LOG(8,("SETMODE: Invalid colorspace $%08x\n", target.space));
return B_ERROR;
}
nm_general_validate_pic_size (&target, &si->fbc.bytes_per_row, &si->acc_mode);
if (crt_only)
{
status = nm_dac_set_pix_pll(target);
if (status == B_ERROR)
LOG(8,("CRTC: error setting pixelclock\n"));
}
nm_dac_mode(colour_mode, 1.0);
nm_crtc_depth(colour_mode);
nm_crtc_set_display_pitch();
nm_crtc_set_display_start(startadd,colour_depth);
nm_crtc_set_timing(target, crt_only);
nm_crtc_center(target, crt_only);
if (!crt_only) nm_crtc_prg_panel();
}
si->dm = target;
nm_acc_init();
SET_DPMS_MODE(si->dpms_flags);
nm_general_output_select();
LOG(1,("SETMODE: booted since %f mS\n", system_time()/1000.0));
interrupt_enable(true);
nm_set_cas_latency();
return B_OK;
}
status_t MOVE_DISPLAY(uint16 h_display_start, uint16 v_display_start)
{
uint8 colour_depth;
uint32 startadd;
uint16 h_display = si->dm.timing.h_display;
uint16 v_display = si->dm.timing.v_display;
LOG(4,("MOVE_DISPLAY: h %d, v %d\n", h_display_start, v_display_start));
switch(si->dm.space)
{
case B_CMAP8:
colour_depth=8;
break;
case B_RGB15_LITTLE:
case B_RGB16_LITTLE:
colour_depth=16;
break;
case B_RGB24_LITTLE:
colour_depth=24;
break;
default:
return B_ERROR;
}
if (nm_general_output_read() & 0x02)
{
if (h_display > si->ps.panel_width) h_display = si->ps.panel_width;
if (v_display > si->ps.panel_height) v_display = si->ps.panel_height;
}
if ((h_display + h_display_start) > si->dm.virtual_width)
return B_ERROR;
if ((v_display + v_display_start) > si->dm.virtual_height)
return B_ERROR;
si->dm.h_display_start = h_display_start;
si->dm.v_display_start = v_display_start;
startadd = v_display_start * si->fbc.bytes_per_row;
startadd += h_display_start * (colour_depth >> 3);
startadd += (uint8*)si->fbc.frame_buffer - (uint8*)si->framebuffer;
interrupt_enable(false);
nm_crtc_set_display_start(startadd,colour_depth);
interrupt_enable(true);
return B_OK;
}
void SET_INDEXED_COLORS(uint count, uint8 first, uint8 *color_data, uint32 flags) {
int i;
uint8 *r,*g,*b;
if (si->dm.space != B_CMAP8) return;
r = si->color_data;
g = r + 256;
b = g + 256;
i = first;
while (count--)
{
r[i] = *color_data++;
g[i] = *color_data++;
b[i] = *color_data++;
i++;
}
nm_dac_palette(r,g,b, 256);
}
status_t SET_DPMS_MODE(uint32 dpms_flags)
{
interrupt_enable(false);
LOG(4,("SET_DPMS_MODE: $%08x\n", dpms_flags));
si->dpms_flags = dpms_flags;
switch(dpms_flags)
{
case B_DPMS_ON:
nm_crtc_dpms(true, true , true);
break;
case B_DPMS_STAND_BY:
nm_crtc_dpms(false, false, true);
break;
case B_DPMS_SUSPEND:
nm_crtc_dpms(false, true, false);
break;
case B_DPMS_OFF:
nm_crtc_dpms(false, false, false);
break;
default:
LOG(8,("SET_DPMS_MODE: Invalid DPMS settings) $%08x\n", dpms_flags));
interrupt_enable(true);
return B_ERROR;
}
interrupt_enable(true);
return B_OK;
}
uint32 DPMS_CAPABILITIES(void)
{
if (si->ps.card_type < NM2200)
return B_DPMS_ON | B_DPMS_OFF;
else
return B_DPMS_ON | B_DPMS_STAND_BY | B_DPMS_SUSPEND | B_DPMS_OFF;
}
uint32 DPMS_MODE(void)
{
return si->dpms_flags;
}