Rudolf Cornelissen 4/2003-1/2006
*/
#define MODULE_BIT 0x00040000
#include "nm_std.h"
status_t nm_crtc_validate_timing(
uint16 *hd_e,uint16 *hs_s,uint16 *hs_e,uint16 *ht,
uint16 *vd_e,uint16 *vs_s,uint16 *vs_e,uint16 *vt
)
{
*hd_e &= 0xfff8;
*hs_s &= 0xfff8;
*hs_e &= 0xfff8;
*ht &= 0xfff8;
if (*hd_e > ((0xff - 2) << 3)) *hd_e = ((0xff - 2) << 3);
if (*hs_s > ((0xff - 1) << 3)) *hs_s = ((0xff - 1) << 3);
if (*hs_e > ( 0xff << 3)) *hs_e = ( 0xff << 3);
if (*ht > ((0xff + 5) << 3)) *ht = ((0xff + 5) << 3);
if (*hd_e < 640) *hd_e = 640;
if (*hd_e > si->ps.max_crtc_width) *hd_e = si->ps.max_crtc_width;
if (*ht < (*hd_e + 80)) *ht = (*hd_e + 80);
if (*ht > (*hd_e + 0x1f8)) *ht = (*hd_e + 0x1f8);
if (*hs_e > (*ht - 8)) *hs_e = (*ht - 8);
if (*hs_s < (*hd_e + 8)) *hs_s = (*hd_e + 8);
* there are only 5 bits available to save this in the card registers! */
if (*hs_e > (*hs_s + 0xf8)) *hs_e = (*hs_s + 0xf8);
if (si->ps.card_type < NM2200)
{
if (*vd_e > (0x3ff - 2)) *vd_e = (0x3ff - 2);
if (*vs_s > (0x3ff - 1)) *vs_s = (0x3ff - 1);
if (*vs_e > 0x3ff ) *vs_e = 0x3ff ;
if (*vt > (0x3ff + 2)) *vt = (0x3ff + 2);
}
else
{
if (*vd_e > (0x7ff - 2)) *vd_e = (0x7ff - 2);
if (*vs_s > (0x7ff - 1)) *vs_s = (0x7ff - 1);
if (*vs_e > 0x7ff ) *vs_e = 0x7ff ;
if (*vt > (0x7ff + 2)) *vt = (0x7ff + 2);
}
if (*vd_e < 480) *vd_e = 480;
if (*vd_e > si->ps.max_crtc_height) *vd_e = si->ps.max_crtc_height;
if (*vt < (*vd_e + 3)) *vt = (*vd_e + 3);
if (*vt > (*vd_e + 0xff)) *vt = (*vd_e + 0xff);
if (*vs_e > (*vt - 1)) *vs_e = (*vt - 1);
if (*vs_s < (*vd_e + 1)) *vs_s = (*vd_e + 1);
* there are only 4 bits available to save this in the card registers! */
if (*vs_e > (*vs_s + 0x0f)) *vs_e = (*vs_s + 0x0f);
return B_OK;
}
status_t nm_crtc_set_timing(display_mode target, bool crt_only)
{
uint8 temp;
uint32 htotal;
uint32 hdisp_e;
uint32 hsync_s;
uint32 hsync_e;
uint32 hblnk_s;
uint32 hblnk_e;
uint32 vtotal;
uint32 vdisp_e;
uint32 vsync_s;
uint32 vsync_e;
uint32 vblnk_s;
uint32 vblnk_e;
uint32 linecomp;
LOG(4,("CRTC: setting timing\n"));
* the display_mode as placed in si->dm may _not_ be modified!) */
if (!crt_only)
{
if (target.timing.h_display > si->ps.panel_width)
{
target.timing.h_display = si->ps.panel_width;
LOG(4,
("CRTC: req. width > panel width: setting panning mode\n"));
}
if (target.timing.v_display > si->ps.panel_height)
{
target.timing.v_display = si->ps.panel_height;
LOG(4,
("CRTC: req. height > panel height: setting scrolling "
"mode\n"));
}
* (needed to maintain correct panel centering):
* both polarities must be negative (confirmed NM2160) */
target.timing.flags &= ~(B_POSITIVE_HSYNC | B_POSITIVE_VSYNC);
}
htotal = ((target.timing.h_total >> 3) - 5);
hdisp_e = ((target.timing.h_display >> 3) - 1);
hblnk_s = hdisp_e;
hblnk_e = (htotal + 0);
hsync_s = (target.timing.h_sync_start >> 3);
hsync_e = (target.timing.h_sync_end >> 3);
vtotal = target.timing.v_total - 2;
vdisp_e = target.timing.v_display - 1;
vblnk_s = vdisp_e;
vblnk_e = (vtotal + 1);
vsync_s = target.timing.v_sync_start;
vsync_e = target.timing.v_sync_end;
linecomp = target.timing.v_display;
if (crt_only)
{
LOG(4,("CRTC: CRT only mode, setting full timing...\n"));
LOG(2,("CRTC:\n\tHTOT:%x\n\tHDISPEND:%x\n\tHBLNKS:%x\n\tHBLNKE:%x\n\tHSYNCS:%x\n\tHSYNCE:%x\n\t",htotal,hdisp_e,hblnk_s,hblnk_e,hsync_s,hsync_e));
LOG(2,("VTOT:%x\n\tVDISPEND:%x\n\tVBLNKS:%x\n\tVBLNKE:%x\n\tVSYNCS:%x\n\tVSYNCE:%x\n",vtotal,vdisp_e,vblnk_s,vblnk_e,vsync_s,vsync_e));
temp = (ISACRTCR(VSYNCE) & 0x7f);
snooze(10);
ISACRTCW(VSYNCE, temp);
ISACRTCW(HTOTAL, (htotal & 0xff));
ISACRTCW(HDISPE, (hdisp_e & 0xff));
ISACRTCW(HBLANKS, (hblnk_s & 0xff));
ISACRTCW(HBLANKE, ((hblnk_e & 0x1f) | 0x80));
ISACRTCW(HSYNCS, (hsync_s & 0xff));
ISACRTCW(HSYNCE, ((hsync_e & 0x1f) | ((hblnk_e & 0x20) << 2)));
ISACRTCW(VTOTAL, (vtotal & 0xff));
ISACRTCW(OVERFLOW,
(
((vtotal & 0x100) >> (8 - 0)) | ((vtotal & 0x200) >> (9 - 5)) |
((vdisp_e & 0x100) >> (8 - 1)) | ((vdisp_e & 0x200) >> (9 - 6)) |
((vsync_s & 0x100) >> (8 - 2)) | ((vsync_s & 0x200) >> (9 - 7)) |
((vblnk_s & 0x100) >> (8 - 3)) | ((linecomp & 0x100) >> (8 - 4))
));
ISACRTCW(PRROWSCN, 0x00);
ISACRTCW(MAXSCLIN, (((vblnk_s & 0x200) >> (9 - 5))
| ((linecomp & 0x200) >> (9 - 6))));
ISACRTCW(VSYNCS, (vsync_s & 0xff));
temp = (ISACRTCR(VSYNCE) & 0xf0);
snooze(10);
ISACRTCW(VSYNCE, (temp | (vsync_e & 0x0f)));
ISACRTCW(VDISPE, (vdisp_e & 0xff));
ISACRTCW(VBLANKS, (vblnk_s & 0xff));
ISACRTCW(VBLANKE, (vblnk_e & 0xff));
ISACRTCW(LINECOMP, (linecomp & 0xff));
if (si->ps.card_type >= NM2200)
ISACRTCW(VEXT,
(
((vtotal & 0x400) >> (10 - 0)) |
((vdisp_e & 0x400) >> (10 - 1)) |
((vblnk_s & 0x400) >> (10 - 2)) |
((vsync_s & 0x400) >> (10 - 3))
((linecomp&0x400)>>3)*/
));
}
else
{
LOG(4,
("CRTC: internal flatpanel active, setting display region only\n"));
temp = (ISACRTCR(VSYNCE) & 0x7f);
snooze(10);
ISACRTCW(VSYNCE, temp);
ISACRTCW(HDISPE, (hdisp_e & 0xff));
temp = (ISACRTCR(OVERFLOW) & ~0x52);
snooze(10);
ISACRTCW(OVERFLOW,
(
temp |
((vdisp_e & 0x100) >> (8 - 1)) |
((vdisp_e & 0x200) >> (9 - 6)) |
((linecomp & 0x100) >> (8 - 4))
));
ISACRTCW(PRROWSCN, 0x00);
temp = (ISACRTCR(MAXSCLIN) & ~0x40);
snooze(10);
ISACRTCW(MAXSCLIN, (temp | ((linecomp & 0x200) >> (9 - 6))));
ISACRTCW(VDISPE, (vdisp_e & 0xff));
ISACRTCW(LINECOMP, (linecomp & 0xff));
if (si->ps.card_type >= NM2200)
{
temp = (ISACRTCR(VEXT) & ~0x02);
snooze(10);
ISACRTCW(VEXT,
(
temp |
((vdisp_e & 0x400) >> (10 - 1))
((linecomp&0x400)>>3)*/
));
}
}
LOG(2,("CRTC: sync polarity: "));
temp = ISARB(MISCR);
if (target.timing.flags & B_POSITIVE_HSYNC)
{
LOG(2,("H:pos "));
temp &= ~0x40;
}
else
{
LOG(2,("H:neg "));
temp |= 0x40;
}
if (target.timing.flags & B_POSITIVE_VSYNC)
{
LOG(2,("V:pos "));
temp &= ~0x80;
}
else
{
LOG(2,("V:neg "));
temp |= 0x80;
}
snooze(10);
ISAWB(MISCW, temp);
LOG(2,(", MISC reg readback: $%02x\n", ISARB(MISCR)));
if (si->ps.card_type != NM2070)
{
uint8 width;
temp = ISAGRPHR(PANELCTRL1);
snooze(10);
switch (target.timing.h_display)
{
case 1280:
width = (3 << 5);
break;
case 1024:
width = (2 << 5);
break;
case 800:
width = (1 << 5);
break;
case 640:
default:
width = (0 << 5);
break;
}
switch (si->ps.card_type)
{
case NM2090:
case NM2093:
case NM2097:
case NM2160:
ISAGRPHW(PANELCTRL1, ((temp & ~0x20) | (width & 0x20)));
break;
default:
ISAGRPHW(PANELCTRL1, ((temp & ~0x60) | (width & 0x60)));
break;
}
}
return B_OK;
}
status_t nm_crtc_depth(int mode)
{
uint8 vid_delay = 0;
LOG(4,("CRTC: setting colordepth to be displayed\n"));
switch(mode)
{
case BPP8:
vid_delay = 0x01;
break;
case BPP15:
vid_delay = 0x02;
break;
case BPP16:
vid_delay = 0x03;
break;
case BPP24:
vid_delay = 0x04;
break;
default:
LOG(4,("CRTC: colordepth not supported, aborting!\n"));
return B_ERROR;
break;
}
switch (si->ps.card_type)
{
case NM2070:
vid_delay |= (ISAGRPHR(COLDEPTH) & 0xf0);
break;
default:
vid_delay |= (ISAGRPHR(COLDEPTH) & 0x70);
break;
}
snooze(10);
ISAGRPHW(COLDEPTH, vid_delay);
snooze(10);
LOG(4,("CRTC: colordepth register readback $%02x\n", (ISAGRPHR(COLDEPTH))));
return B_OK;
}
status_t nm_crtc_dpms(bool display, bool h, bool v)
{
char msg[100];
const char* displayStatus;
const char* horizontalSync;
const char* verticalSync;
uint8 temp, size_outputs;
sprintf(msg, "CRTC: setting DPMS: ");
ISASEQW(RESET, 0x01);
temp = ISASEQR(CLKMODE);
snooze(10);
if (display)
{
ISASEQW(CLKMODE, (temp & ~0x20));
ISASEQW(RESET, 0x03);
displayStatus = "on";
}
else
{
ISASEQW(CLKMODE, (temp | 0x20));
displayStatus = "off";
}
temp = 0x00;
if (h)
{
horizontalSync = "enabled";
}
else
{
temp |= 0x10;
horizontalSync = "disabled";
}
if (v)
{
verticalSync = "enabled";
}
else
{
temp |= 0x20;
verticalSync = "disabled";
}
snprintf(msg, sizeof(msg),
"CRTC: setting DPMS: display %s, hsync %s, vsync %s\n",
displayStatus, horizontalSync, verticalSync);
LOG(4, (msg));
size_outputs = nm_general_output_read();
snooze(10);
if (si->ps.card_type < NM2200)
{
if (temp)
{
ISAGRPHW(PANELCTRL1, (size_outputs & 0xfc));
}
else
{
ISAGRPHW(PANELCTRL1, size_outputs);
}
}
else
{
if (temp)
{
ISAGRPHW(PANELCTRL1, (size_outputs & 0xfd));
}
else
{
ISAGRPHW(PANELCTRL1, size_outputs);
}
if (size_outputs & 0x01)
{
temp |= ((ISAGRPHR(ENSETRESET) & 0x0f) | 0x80);
snooze(10);
ISAGRPHW(ENSETRESET, temp);
snooze(10);
LOG(4,("CRTC: DPMS readback $%02x, programmed $%02x\n",
ISAGRPHR(ENSETRESET), temp));
}
}
return B_OK;
}
status_t nm_crtc_set_display_pitch()
{
uint32 offset;
LOG(4,("CRTC: setting card pitch (offset between lines)\n"));
offset = si->fbc.bytes_per_row / 8;
LOG(2,("CRTC: offset register set to: $%04x\n", offset));
ISACRTCW(PITCHL, (offset & 0xff));
if (si->ps.card_type != NM2070)
ISAGRPHW(CRTC_PITCHE, ((offset & 0xff00) >> 8));
return B_OK;
}
status_t nm_crtc_set_display_start(uint32 startadd,uint8 bpp)
{
uint8 val;
uint32 timeout = 0;
LOG(2,("CRTC: relative startadd: $%06x\n",startadd));
LOG(2,("CRTC: frameRAM: $%08x\n",si->framebuffer));
LOG(2,("CRTC: framebuffer: $%08x\n",si->fbc.frame_buffer));
* wait 25mS max. for retrace to occur (refresh > 40Hz) */
while ((!(ISARB(INSTAT1) & 0x08)) && (timeout < (25000/4)))
{
snooze(4);
timeout++;
}
timeout = 0;
while ((ISARB(INSTAT1) & 0x08) && (timeout < (25000/4)))
{
snooze(4);
timeout++;
}
ISACRTCW(FBSTADDH, ((startadd & 0x03fc00) >> 10));
ISACRTCW(FBSTADDL, ((startadd & 0x0003fc) >> 2));
val = ISAGRPHR(FBSTADDE);
snooze(10);
if (si->ps.card_type < NM2200)
ISAGRPHW(FBSTADDE,(((startadd >> 18) & 0x07) | (val & 0xf8)));
else
ISAGRPHW(FBSTADDE,(((startadd >> 18) & 0x0f) | (val & 0xf0)));
* Neomagic cards work with _pixel_ offset here. */
switch(bpp)
{
case 8:
ISAATBW(HORPIXPAN, (startadd & 0x00000003));
break;
case 15:
case 16:
ISAATBW(HORPIXPAN, ((startadd & 0x00000002) >> 1));
break;
case 24:
ISAATBW(HORPIXPAN, ((4 - (startadd & 0x00000003)) & 0x03));
break;
}
return B_OK;
}
status_t nm_crtc_center(display_mode target, bool crt_only)
{
* NM2070 apparantly doesn't support horizontal */
uint8 vcent1, vcent2, vcent3, vcent4, vcent5;
uint8 hcent1, hcent2, hcent3, hcent4, hcent5;
uint8 ctrl2, ctrl3;
uint16 hoffset = 0;
uint16 voffset = 0;
vcent1 = vcent2 = vcent3 = vcent4 = vcent5 = 0x00;
hcent1 = hcent2 = hcent3 = hcent4 = hcent5 = 0x00;
ctrl2 = ctrl3 = 0x00;
if (!crt_only)
{
if (target.timing.h_display < si->ps.panel_width)
{
hoffset = (si->ps.panel_width - target.timing.h_display);
* horizontal center granularity is 16 pixels */
hoffset = ((hoffset >> 4) - 1);
ctrl3 = 0x10;
}
if (target.timing.v_display < si->ps.panel_height)
{
voffset = (si->ps.panel_height - target.timing.v_display);
* vertical center granularity is 2 pixels */
voffset = ((voffset >> 1) - 2);
ctrl2 = 0x01;
}
switch(target.timing.h_display)
{
case 640:
hcent1 = hoffset;
vcent3 = voffset;
break;
case 800:
hcent2 = hoffset;
switch(target.timing.v_display)
{
case 480:
vcent3 = voffset;
break;
case 600:
vcent4 = voffset;
break;
}
break;
case 1024:
hcent5 = hoffset;
vcent5 = voffset;
break;
case 1280:
* newest chip: so no centering needed here. */
break;
default:
break;
}
}
ISAGRPHW(PANELVCENT1, vcent1);
ISAGRPHW(PANELVCENT2, vcent2);
ISAGRPHW(PANELVCENT3, vcent3);
if (si->ps.card_type > NM2070)
{
ISAGRPHW(PANELVCENT4, vcent4);
ISAGRPHW(PANELHCENT1, hcent1);
ISAGRPHW(PANELHCENT2, hcent2);
ISAGRPHW(PANELHCENT3, hcent3);
}
if (si->ps.card_type >= NM2160)
{
ISAGRPHW(PANELHCENT4, hcent4);
}
if (si->ps.card_type >= NM2200)
{
ISAGRPHW(PANELVCENT5, vcent5);
ISAGRPHW(PANELHCENT5, hcent5);
}
ctrl2 |= (ISAGRPHR(PANELCTRL2) & 0x38);
snooze(10);
ISAGRPHW(PANELCTRL2, ctrl2);
if (si->ps.card_type > NM2070)
{
ctrl3 |= (ISAGRPHR(PANELCTRL3) & 0xef);
snooze(10);
ISAGRPHW(PANELCTRL3, ctrl3);
}
return B_OK;
}
status_t nm_crtc_prg_panel()
{
status_t stat = B_ERROR;
if (si->ps.card_type > NM2070) return B_OK;
switch(si->ps.panel_width)
{
case 640:
ISACRTCW(PANEL_0x40, 0x5f);
ISACRTCW(PANEL_0x41, 0x50);
ISACRTCW(PANEL_0x42, 0x02);
ISACRTCW(PANEL_0x43, 0x55);
ISACRTCW(PANEL_0x44, 0x81);
ISACRTCW(PANEL_0x45, 0x0b);
ISACRTCW(PANEL_0x46, 0x2e);
ISACRTCW(PANEL_0x47, 0xea);
ISACRTCW(PANEL_0x48, 0x0c);
ISACRTCW(PANEL_0x49, 0xe7);
ISACRTCW(PANEL_0x4a, 0x04);
ISACRTCW(PANEL_0x4b, 0x2d);
ISACRTCW(PANEL_0x4c, 0x28);
ISACRTCW(PANEL_0x4d, 0x90);
ISACRTCW(PANEL_0x4e, 0x2b);
ISACRTCW(PANEL_0x4f, 0xa0);
stat = B_OK;
break;
case 800:
switch(si->ps.panel_height)
{
case 600:
ISACRTCW(PANEL_0x40, 0x7f);
ISACRTCW(PANEL_0x41, 0x63);
ISACRTCW(PANEL_0x42, 0x02);
ISACRTCW(PANEL_0x43, 0x6c);
ISACRTCW(PANEL_0x44, 0x1c);
ISACRTCW(PANEL_0x45, 0x72);
ISACRTCW(PANEL_0x46, 0xe0);
ISACRTCW(PANEL_0x47, 0x58);
ISACRTCW(PANEL_0x48, 0x0c);
ISACRTCW(PANEL_0x49, 0x57);
ISACRTCW(PANEL_0x4a, 0x73);
ISACRTCW(PANEL_0x4b, 0x3d);
ISACRTCW(PANEL_0x4c, 0x31);
ISACRTCW(PANEL_0x4d, 0x01);
ISACRTCW(PANEL_0x4e, 0x36);
ISACRTCW(PANEL_0x4f, 0x1e);
if (si->ps.card_type > NM2070)
{
ISACRTCW(PANEL_0x50, 0x6b);
ISACRTCW(PANEL_0x51, 0x4f);
ISACRTCW(PANEL_0x52, 0x0e);
ISACRTCW(PANEL_0x53, 0x58);
ISACRTCW(PANEL_0x54, 0x88);
ISACRTCW(PANEL_0x55, 0x33);
ISACRTCW(PANEL_0x56, 0x27);
ISACRTCW(PANEL_0x57, 0x16);
ISACRTCW(PANEL_0x58, 0x2c);
ISACRTCW(PANEL_0x59, 0x94);
}
stat = B_OK;
break;
case 480:
ISACRTCW(PANEL_0x40, 0x7f);
ISACRTCW(PANEL_0x41, 0x63);
ISACRTCW(PANEL_0x42, 0x02);
ISACRTCW(PANEL_0x43, 0x6b);
ISACRTCW(PANEL_0x44, 0x1b);
ISACRTCW(PANEL_0x45, 0x72);
ISACRTCW(PANEL_0x46, 0xe0);
ISACRTCW(PANEL_0x47, 0x1c);
ISACRTCW(PANEL_0x48, 0x00);
ISACRTCW(PANEL_0x49, 0x57);
ISACRTCW(PANEL_0x4a, 0x73);
ISACRTCW(PANEL_0x4b, 0x3e);
ISACRTCW(PANEL_0x4c, 0x31);
ISACRTCW(PANEL_0x4d, 0x01);
ISACRTCW(PANEL_0x4e, 0x36);
ISACRTCW(PANEL_0x4f, 0x1e);
ISACRTCW(PANEL_0x50, 0x6b);
ISACRTCW(PANEL_0x51, 0x4f);
ISACRTCW(PANEL_0x52, 0x0e);
ISACRTCW(PANEL_0x53, 0x57);
ISACRTCW(PANEL_0x54, 0x87);
ISACRTCW(PANEL_0x55, 0x33);
ISACRTCW(PANEL_0x56, 0x27);
ISACRTCW(PANEL_0x57, 0x16);
ISACRTCW(PANEL_0x58, 0x2c);
ISACRTCW(PANEL_0x59, 0x94);
stat = B_OK;
break;
}
break;
case 1024:
switch(si->ps.panel_height)
{
case 768:
* (NM2097 and later ?) */
ISACRTCW(PANEL_0x40, 0xa3);
ISACRTCW(PANEL_0x41, 0x7f);
ISACRTCW(PANEL_0x42, 0x06);
ISACRTCW(PANEL_0x43, 0x85);
ISACRTCW(PANEL_0x44, 0x96);
ISACRTCW(PANEL_0x45, 0x24);
ISACRTCW(PANEL_0x46, 0xe5);
ISACRTCW(PANEL_0x47, 0x02);
ISACRTCW(PANEL_0x48, 0x08);
ISACRTCW(PANEL_0x49, 0xff);
ISACRTCW(PANEL_0x4a, 0x25);
ISACRTCW(PANEL_0x4b, 0x4f);
ISACRTCW(PANEL_0x4c, 0x40);
ISACRTCW(PANEL_0x4d, 0x00);
ISACRTCW(PANEL_0x4e, 0x44);
ISACRTCW(PANEL_0x4f, 0x0c);
ISACRTCW(PANEL_0x50, 0x7a);
ISACRTCW(PANEL_0x51, 0x56);
ISACRTCW(PANEL_0x52, 0x00);
ISACRTCW(PANEL_0x53, 0x5d);
ISACRTCW(PANEL_0x54, 0x0e);
ISACRTCW(PANEL_0x55, 0x3b);
ISACRTCW(PANEL_0x56, 0x2b);
ISACRTCW(PANEL_0x57, 0x00);
ISACRTCW(PANEL_0x58, 0x2f);
ISACRTCW(PANEL_0x59, 0x18);
ISACRTCW(PANEL_0x60, 0x88);
ISACRTCW(PANEL_0x61, 0x63);
ISACRTCW(PANEL_0x62, 0x0b);
ISACRTCW(PANEL_0x63, 0x69);
ISACRTCW(PANEL_0x64, 0x1a);
stat = B_OK;
break;
case 480:
* (NM2097 and later ?) */
ISACRTCW(PANEL_0x40, 0xa3);
ISACRTCW(PANEL_0x41, 0x7f);
ISACRTCW(PANEL_0x42, 0x1b);
ISACRTCW(PANEL_0x43, 0x89);
ISACRTCW(PANEL_0x44, 0x16);
ISACRTCW(PANEL_0x45, 0x0b);
ISACRTCW(PANEL_0x46, 0x2c);
ISACRTCW(PANEL_0x47, 0xe8);
ISACRTCW(PANEL_0x48, 0x0c);
ISACRTCW(PANEL_0x49, 0xe7);
ISACRTCW(PANEL_0x4a, 0x09);
ISACRTCW(PANEL_0x4b, 0x4f);
ISACRTCW(PANEL_0x4c, 0x40);
ISACRTCW(PANEL_0x4d, 0x00);
ISACRTCW(PANEL_0x4e, 0x44);
ISACRTCW(PANEL_0x4f, 0x0c);
ISACRTCW(PANEL_0x50, 0x7a);
ISACRTCW(PANEL_0x51, 0x56);
ISACRTCW(PANEL_0x52, 0x00);
ISACRTCW(PANEL_0x53, 0x5d);
ISACRTCW(PANEL_0x54, 0x0e);
ISACRTCW(PANEL_0x55, 0x3b);
ISACRTCW(PANEL_0x56, 0x2a);
ISACRTCW(PANEL_0x57, 0x00);
ISACRTCW(PANEL_0x58, 0x2f);
ISACRTCW(PANEL_0x59, 0x18);
ISACRTCW(PANEL_0x60, 0x88);
ISACRTCW(PANEL_0x61, 0x63);
ISACRTCW(PANEL_0x62, 0x0b);
ISACRTCW(PANEL_0x63, 0x69);
ISACRTCW(PANEL_0x64, 0x1a);
stat = B_OK;
break;
}
break;
case 1280:
break;
}
if (stat != B_OK)
LOG(2,("CRTC: unable to program panel: unknown modeline needed.\n"));
return stat;
}
status_t nm_crtc_cursor_init()
{
int i;
vuint32 * fb;
uint32 curadd, curreg;
curadd = ((si->ps.memory_size * 1024) - si->ps.curmem_size);
* so they get placed at the correct registerbits */
curreg = (((curadd >> 10) & 0x000f) << 8);
curreg |= (((curadd >> 10) & 0x0ff0) >> 4);
curreg |= ((curadd >> 10) & 0x1000);
if (si->ps.card_type < NM2200)
CR1W(CURADDRESS, curreg);
else
CR1W(22CURADDRESS, curreg);
if (si->ps.card_type < NM2200)
{
CR1W(CURBGCOLOR, 0x00000000);
CR1W(CURFGCOLOR, 0x00ffffff);
}
else
{
CR1W(22CURBGCOLOR, 0x00000000);
CR1W(22CURFGCOLOR, 0x00ffffff);
}
* in old pre 8-bit color VGA modes some planemask is in effect apparantly,
* allowing access only to every 7th and 8th RAM byte across the
* entire RAM. */
nm_crtc_depth(BPP8);
fb = ((vuint32 *)(((uintptr_t)si->framebuffer) + curadd));
for (i = 0; i < (1024/4); i++)
{
fb[i] = 0;
}
nm_crtc_cursor_show();
return B_OK;
}
status_t nm_crtc_cursor_show()
{
if (si->ps.card_type < NM2200)
{
CR1W(CURCTRL, 0x00000001);
}
else
{
CR1W(22CURCTRL, 0x00000001);
}
return B_OK;
}
status_t nm_crtc_cursor_hide()
{
if (si->ps.card_type < NM2200)
{
CR1W(CURCTRL, 0x00000000);
}
else
{
CR1W(22CURCTRL, 0x00000000);
}
*/
ISAGRPHW(CURCTRL,0x00);
return B_OK;
}
status_t nm_crtc_cursor_define(uint8* andMask,uint8* xorMask)
{
uint8 y;
vuint8 * cursor;
cursor = (vuint8*) si->framebuffer;
cursor += ((si->ps.memory_size * 1024) - si->ps.curmem_size);
for(y=0;y<16;y++)
{
cursor[y*16+8]=~*andMask++;
cursor[y*16+0]=*xorMask++;
cursor[y*16+9]=~*andMask++;
cursor[y*16+1]=*xorMask++;
}
float pclk;
uint8 n,m,x = 1;
n = ISAGRPHR(PLLC_NL);
m = ISAGRPHR(PLLC_M);
LOG(4,("CRTC: PLLSEL $%02x\n", ISARB(MISCR)));
LOG(4,("CRTC: PLLN $%02x\n", n));
LOG(4,("CRTC: PLLM $%02x\n", m));
if (n & 0x80) x = 2;
n &= 0x7f;
pclk = ((si->ps.f_ref * (n + 1)) / ((m + 1) * x));
LOG(2,("CRTC: Pixelclock is %fMHz\n", pclk));
nm_general_output_select();
}
*/
return B_OK;
}
status_t nm_crtc_cursor_position(uint16 x ,uint16 y)
{
* during our reprogramming them (double buffering feature) */
while (ACCR(STATUS) & 0x08)
{
snooze(4);
}
*/
if (si->ps.card_type < NM2200)
{
CR1W(CURX, (uint32)x);
CR1W(CURY, (uint32)y);
}
else
{
CR1W(22CURX, (uint32)x);
CR1W(22CURY, (uint32)y);
}
return B_OK;
}