add: 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)));
context: status_t nm_crtc_set_timing(display_mode target, bool crt_only){	uint8 temp;	uint32 htotal;		/*total horizontal total VCLKs*/	uint32 hdisp_e;            /*end of horizontal display (begins at 0)*/	uint32 hsync_s;            /*begin of horizontal sync pulse*/	uint32 hsync_e;            /*end of horizontal sync pulse*/	uint32 hblnk_s;            /*begin horizontal blanking*/	uint32 hblnk_e;            /*end horizontal blanking*/	uint32 vtotal;		/*total vertical total scanlines*/	uint32 vdisp_e;            /*end of vertical display*/	uint32 vsync_s;            /*begin of vertical sync pulse*/	uint32 vsync_e;            /*end of vertical sync pulse*/	uint32 vblnk_s;            /*begin vertical blanking*/	uint32 vblnk_e;            /*end vertical blanking*/	uint32 linecomp;	/*split screen and vdisp_e interrupt*/	LOG(4,("CRTC: setting timing\n"));	/* modify visible sceensize if needed */	/* (note that MOVE_CURSOR checks for a panning/scrolling mode itself,	 *  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"));		}	}	/* Modify parameters as required by standard VGA */	htotal = ((target.timing.h_total >> 3) - 5);	hdisp_e = ((target.timing.h_display >> 3) - 1);	hblnk_s = hdisp_e;	hblnk_e = (htotal + 0); /* this register differs from standard VGA! (says + 4) */			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;//-1;	vsync_e = target.timing.v_sync_end;//-1;	/* prevent memory adress counter from being reset (linecomp may not occur) */	linecomp = target.timing.v_display;	if (crt_only)	{		LOG(4,("CRTC: CRT only mode, setting full timing...\n"));		/* log the mode that will be set */		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));		/* actually program the card! */		/* unlock CRTC registers at index 0-7 */		temp = (ISACRTCR(VSYNCE) & 0x7f);		/* we need to wait a bit or the card will mess-up it's register values.. */		snooze(10);		ISACRTCW(VSYNCE, temp);		/* horizontal standard VGA regs */		ISACRTCW(HTOTAL, (htotal & 0xff));		ISACRTCW(HDISPE, (hdisp_e & 0xff));		ISACRTCW(HBLANKS, (hblnk_s & 0xff));		/* also unlock vertical retrace registers in advance */		ISACRTCW(HBLANKE, ((hblnk_e & 0x1f) | 0x80));		ISACRTCW(HSYNCS, (hsync_s & 0xff));		ISACRTCW(HSYNCE, ((hsync_e & 0x1f) | ((hblnk_e & 0x20) << 2)));		/* vertical standard VGA regs */		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); /* not used */		ISACRTCW(MAXSCLIN, (((vblnk_s & 0x200) >> (9 - 5)) | ((linecomp & 0x200) >> (9 - 6))));		ISACRTCW(VSYNCS, (vsync_s & 0xff));		temp = (ISACRTCR(VSYNCE) & 0xf0);		/* we need to wait a bit or the card will mess-up it's register values.. */		snooze(10);		ISACRTCW(VSYNCE, (temp | (vsync_e & 0x0f)));		ISACRTCW(VDISPE, (vdisp_e & 0xff));		ISACRTCW(VBLANKS, (vblnk_s & 0xff));		ISACRTCW(VBLANKE, (vblnk_e & 0xff));//linux: (BIOSmode)//	regp->CRTC[23] = 0xC3;		ISACRTCW(LINECOMP, (linecomp & 0xff));		/* horizontal - no extended regs available or needed on NeoMagic chips */		/* vertical - extended regs *///fixme: checkout if b2 or 3 should be switched! (linux contains error here)//fixme: linecomp should also have an extra bit... testable by setting linecomp//to 100 for example and then try out writing an '1' to b2, b3(!) and the rest//for screenorig reset visible on upper half of the screen or not at all..		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)*/			));		/* setup HSYNC & VSYNC polarity */		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;		}		/* we need to wait a bit or the card will mess-up it's register values.. */		snooze(10);		ISAWB(MISCW, temp);		LOG(2,(", MISC reg readback: $%02x\n", ISARB(MISCR)));	}	else	{		LOG(4,("CRTC: internal flatpanel active, setting display region only\n"));		/* actually program the card! */		/* unlock CRTC registers at index 0-7 */		temp = (ISACRTCR(VSYNCE) & 0x7f);		/* we need to wait a bit or the card will mess-up it's register values.. */		snooze(10);		ISACRTCW(VSYNCE, temp);		/* horizontal standard VGA regs */		ISACRTCW(HDISPE, (hdisp_e & 0xff));		/* vertical standard VGA regs */		temp = (ISACRTCR(OVERFLOW) & ~0x52);		/* we need to wait a bit or the card will mess-up it's register values.. */		snooze(10);		ISACRTCW(OVERFLOW,		(				temp |			((vdisp_e & 0x100) >> (8 - 1)) |			((vdisp_e & 0x200) >> (9 - 6)) |			((linecomp & 0x100) >> (8 - 4))		));		ISACRTCW(PRROWSCN, 0x00); /* not used */		temp = (ISACRTCR(MAXSCLIN) & ~0x40);		/* we need to wait a bit or the card will mess-up it's register values.. */		snooze(10);		ISACRTCW(MAXSCLIN, (temp | ((linecomp & 0x200) >> (9 - 6))));		ISACRTCW(VDISPE, (vdisp_e & 0xff));//linux:(BIOSmode)//	regp->CRTC[23] = 0xC3;		ISACRTCW(LINECOMP, (linecomp & 0xff));		/* horizontal - no extended regs available or needed on NeoMagic chips */		/* vertical - extended regs *///fixme: linecomp should have an extra bit... testable by setting linecomp//to 100 for example and then try out writing an '1' to b2, b3(!) and the rest//for screenorig reset visible on upper half of the screen or not at all..		if (si->ps.card_type >= NM2200)		{			temp = (ISACRTCR(VEXT) & ~0x02);			/* we need to wait a bit or the card will mess-up it's register values.. */			snooze(10);			ISACRTCW(VEXT,			(				temp |				((vdisp_e & 0x400) >> (10 - 1))/*|				((linecomp&0x400)>>3)*/			));		}	}	/* program 'fixed' mode if needed */	if (si->ps.card_type != NM2070)	{		uint8 width;		temp = ISAGRPHR(PANELCTRL1);		/* we need to wait a bit or the card will mess-up it's register values.. */		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: //fixme: non-std modes should be in between above modes?!?			width = (0 << 5);			break;		}		switch (si->ps.card_type)		{		case NM2090:		case NM2093:		case NM2097:		case NM2160:			//fixme: checkout b6????			ISAGRPHW(PANELCTRL1, ((temp & ~0x20) | (width & 0x20)));			break;		default:			/* NM2200 and later */			ISAGRPHW(PANELCTRL1, ((temp & ~0x60) | (width & 0x60)));			break;		}	}	return B_OK;}