⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vgamach64xx.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
📖 第 1 页 / 共 2 页
字号:
#include "u.h"#include "../port/lib.h"#include "mem.h"#include "dat.h"#include "fns.h"#include "io.h"#include "../port/error.h"#define	Image	IMAGE#include <draw.h>#include <memdraw.h>#include <cursor.h>#include "screen.h"char Eunsupportedformat[] = "unsupported video format";char Enotconfigured[] = "device not configured";#define SCALE_ZERO_EXTEND           	0x0#define SCALE_DYNAMIC               		0x1#define SCALE_RED_TEMP_6500K        	0x0#define SCALE_RED_TEMP_9800K        	0x2#define SCALE_HORZ_BLEND            	0x0#define SCALE_HORZ_REP              		0x4#define SCALE_VERT_BLEND            		0x0#define SCALE_VERT_REP              		0x8#define SCALE_BANDWIDTH_NORMAL     0x0#define SCALE_BANDWIDTH_EXCEEDED  0x4000000#define SCALE_BANDWIDTH_RESET       	0x4000000#define SCALE_CLK_ACTIVITY          	0x0#define SCALE_CLK_CONTINUOUS        	0x20000000#define OVERLAY_DISABLE             		0x0#define OVERLAY_ENABLE              		0x40000000#define SCALE_DISABLE               		0x0#define SCALE_ENABLE                		0x80000000#define SCALER_FRAME_READ_MODE_FULL 	0x0#define SCALER_BUF_MODE_SINGLE      		0x0#define SCALER_BUF_MODE_DOUBLE      		0x40000#define SCALER_BUF_NEXT_0           		0x0#define SCALER_BUF_NEXT_1           		0x80000#define SCALER_BUF_STATUS_0         		0x0#define SCALER_BUF_STATUS_1         		0x100000#define OVERLAY_MIX_G_CMP           		0x0#define OVERLAY_MIX_ALWAYS_G        		0x100#define OVERLAY_MIX_ALWAYS_V        		0x200#define OVERLAY_MIX_NOT_G           		0x300#define OVERLAY_MIX_NOT_V           		0x400#define OVERLAY_MIX_G_XOR_V         		0x500#define OVERLAY_MIX_NOT_G_XOR_V     	0x600#define OVERLAY_MIX_V_CMP           		0x700#define OVERLAY_MIX_NOT_G_OR_NOT_V	0x800#define OVERLAY_MIX_G_OR_NOT_V      	0x900#define OVERLAY_MIX_NOT_G_OR_V      	0xA00#define OVERLAY_MIX_G_OR_V          		0xB00#define OVERLAY_MIX_G_AND_V         		0xC00#define OVERLAY_MIX_NOT_G_AND_V     	0xD00#define OVERLAY_MIX_G_AND_NOT_V     	0xE00#define OVERLAY_MIX_NOT_G_AND_NOT_V 	0xF00#define OVERLAY_EXCLUSIVE_NORMAL    	0x0#define OVERLAY_EXCLUSIVE_V_ONLY    	0x80000000#define VIDEO_IN_8BPP               			0x2#define VIDEO_IN_16BPP              			0x4#define VIDEO_IN_32BPP              			0x6#define VIDEO_IN_VYUY422            			0xB         		/*16 bpp */#define VIDEO_IN_YVYU422            			0xC         		/* 16 bpp */#define SCALE_IN_15BPP              			0x30000     	/* aRGB 1555 */#define SCALE_IN_16BPP              			0x40000     	/* RGB 565 */#define SCALE_IN_32BPP              			0x60000     	/* aRGB 8888 */#define SCALE_IN_YUV9               			0x90000     	/* planar */#define SCALE_IN_YUV12              			0xA0000     	/* planar */#define SCALE_IN_VYUY422            			0xB0000     	/* 16 bpp */#define SCALE_IN_YVYU422            			0xC0000     	/* 16 bpp */#define HOST_YUV_APERTURE_UPPER     		0x0#define HOST_YUV_APERTURE_LOWER     	0x20000000#define HOST_MEM_MODE_Y             		0x40000000#define HOST_MEM_MODE_U             		0x80000000#define HOST_MEM_MODE_V             		0xC0000000#define HOST_MEM_MODE_NORMAL     		HOST_YUV_APERTURE_UPPER static Chan *ovl_chan;	/* Channel of controlling process */static int ovl_width;		/* Width of input overlay buffer */static int ovl_height;		/* Height of input overlay buffer */static int ovl_format;	/* Overlay format */static ulong ovl_fib;		/* Frame in bytes */enum {	 VTGTB1S1        = 0x01,            //  Asic description for VTB1S1 and GTB1S1.	 VT4GTIIC        	= 0x3A,            // asic descr for VT4 and RAGE IIC	 GTB1U1          	= 0x19,            //  Asic description for GTB1U1.	 GTB1S2          	= 0x41,            //  Asic description for GTB1S2.	 GTB2U1          	= 0x1A,	 GTB2U2          	= 0x5A,	 GTB2U3          	= 0x9A,	 GTIIIC1U1       	= 0x1B,            // 3D RAGE PRO asic descrp.	 GTIIIC1U2       	= 0x5B,            // 3D RAGE PRO asic descrp.	 GTIIIC2U1       	= 0x1C,            // 3D RAGE PRO asic descrp.	 GTIIIC2U2       	= 0x5C,           // 3D RAGE PRO asic descrp.	 GTIIIC2U3       	= 0x7C,            // 3D RAGE PRO asic descrp.	 GTBC            	= 0x3A,            // 3D RAGE IIC asic descrp.	 LTPRO           	= 0x9C,            // 3D RAGE LT PRO};/* * ATI Mach64(CT|ET|G*|V*|L*). */typedef struct Mach64types Mach64types;struct Mach64types {	ushort 	m64_id;			/* Chip ID */	int 		m64_vtgt;		/* Is this a VT or GT chipset? */	ulong	m64_ovlclock;		/* Max. overlay clock frequency */	int		m64_pro;			/* Is this a PRO? */};static ulong mach64refclock;static Mach64types *mach64type;static int mach64revb;			/* Revision B or greater? */static ulong mach64overlay;		/* Overlay buffer */static Mach64types mach64s[] = {	('C'<<8)|'T',	0,	1350000, /*?*/	0,	/* 4354: CT */	('E'<<8)|'T',	0,	1350000, /*?*/	0,	/* 4554: ET */	('G'<<8)|'B',	1,	1250000,		1, 	/* 4742: 264GT PRO */	('G'<<8)|'D',	1,	1250000,		1, 	/* 4744: 264GT PRO */	('G'<<8)|'I',	1,	1250000,		1, 	/* 4749: 264GT PRO */	('G'<<8)|'M',	0,	1350000,		0,	/* 474D: Rage XL */	('G'<<8)|'P',	1,	1250000,		1, 	/* 4750: 264GT PRO */	('G'<<8)|'Q',	1,	1250000,		1,	/* 4751: 264GT PRO */	('G'<<8)|'R',	1,	1250000,		1,	/* 4752: */	('G'<<8)|'T',	1,	800000,		0,	/* 4754: 264GT[B] */	('G'<<8)|'U',	1,	1000000,		0,	/* 4755: 264GT DVD */	('G'<<8)|'V',	1,	1000000,		0,	/* 4756: Rage2C */	('G'<<8)|'Z',	1,	1000000,		0,	/* 475A: Rage2C */	('V'<<8)|'T',	1,	800000,		0,	/* 5654: 264VT/GT/VTB */	('V'<<8)|'U',	1,	800000,		0,	/* 5655: 264VT3 */	('V'<<8)|'V',	1,	1000000,		0,	/* 5656: 264VT4 */	('L'<<8)|'B',	0,	1350000,		1,	/* 4C42: Rage LTPro AGP */	('L'<<8)|'I',		0,	1350000,		0,	/* 4C49: Rage LTPro AGP */	('L'<<8)|'M',	0,	1350000,		0,	/* 4C4D: Rage Mobility */	('L'<<8)|'P',	0,	1350000,		1,	/* 4C50: 264LT PRO */};static int hwfill(VGAscr*, Rectangle, ulong);static int hwscroll(VGAscr*, Rectangle, Rectangle);static void initengine(VGAscr*);static Pcidev*mach64xxpci(void){	Pcidev *p;	int i;	if((p = pcimatch(nil, 0x1002, 0)) == nil)		return nil;	for (i = 0; i != nelem(mach64s); i++)		if (mach64s[i].m64_id == p->did) {			mach64type = &mach64s[i];			return p;		}	return nil;}static voidmach64xxenable(VGAscr* scr){	Pcidev *p;	if(scr->io)		return;	if(p = mach64xxpci()){		scr->id = p->did;		scr->pci = p;		/*		 * The CT doesn't always have the I/O base address		 * in the PCI base registers. There is a way to find		 * it via the vendor-specific PCI config space but		 * this will do for now.		 */		scr->io = p->mem[1].bar & ~0x03;		if(scr->io == 0)			scr->io = 0x2EC;	}}static voidmach64xxlinear(VGAscr* scr, int size, int){	vgalinearpci(scr);	if(scr->paddr == 0)		return;	scr->mmio = (ulong*)((uchar*)scr->vaddr+size-1024);	addvgaseg("mach64mmio", scr->paddr+size-BY2PG, BY2PG);	addvgaseg("mach64screen", scr->paddr, scr->apsize);}enum {	CrtcOffPitch	= 0x05,	CrtcGenCtl	= 0x07,	CurClr0		= 0x0B,		/* I/O Select */	CurClr1		= 0x0C,	CurOffset	= 0x0D,	CurHVposn	= 0x0E,	CurHVoff	= 0x0F,	BusCntl	= 0x13,	GenTestCntl	= 0x19,	CrtcHsyncDis	= 0x04,	CrtcVsyncDis	= 0x08,	ContextMask	= 0x100,	/* not accessible via I/O */	FifoStat,	GuiStat,	DpFrgdClr,	DpBkgdClr,	DpWriteMask,	DpMix,	DpPixWidth,	DpSrc,	ClrCmpCntl,	GuiTrajCntl,	ScLeftRight,	ScTopBottom,	DstOffPitch,	DstYX,	DstHeightWidth,	DstCntl,	DstHeight,	DstBresErr,	DstBresInc,	DstBresDec,	SrcCntl,	SrcHeight1Width1,	SrcHeight2Width2,	SrcYX,	SrcWidth1,	SrcYXstart,	HostCntl,	PatReg0,	PatReg1,	PatCntl,	ScBottom,	ScLeft,	ScRight,	ScTop,	ClrCmpClr,	ClrCmpMask,	DpChainMask,	SrcOffPitch,		LcdIndex,	LcdData,	ClockCntl,	OverlayScaleCntl,	ConfigChipId,	Buf0Pitch,	ScalerBuf0Pitch,	CaptureConfig,	OverlayKeyCntl,	ScalerColourCntl,	ScalerHCoef0,	ScalerHCoef1,	ScalerHCoef2,	ScalerHCoef3,	ScalerHCoef4,	VideoFormat,	Buf0Offset,	ScalerBuf0Offset,	CrtcGenCntl,	OverlayScaleInc,	OverlayYX,	OverlayYXEnd,	ScalerHeightWidth,	HTotalDisp,	VTotalDisp,};enum {	LCD_ConfigPanel = 0,	LCD_GenCtrl,	LCD_DstnCntl,	LCD_HfbPitchAddr,	LCD_HorzStretch,	LCD_VertStretch,	LCD_ExtVertStretch,	LCD_LtGio,	LCD_PowerMngmnt,	LCD_ZvgPio,	Nlcd,};#define Bank1			(-0x100)		/* 1KB */static int mmoffset[] = {	[HTotalDisp]		0x00,	[VTotalDisp]		0x02,	[CrtcOffPitch]		0x05,	[CrtcGenCntl]		0x07,	[CurClr0]			0x18,	[CurClr1]			0x19,	[CurOffset]		0x1A,	[CurHVposn]		0x1B,	[CurHVoff]		0x1C,	[ClockCntl]		0x24,	[BusCntl]			0x28,	[LcdIndex]		0x29,	[LcdData]			0x2A,	[GenTestCntl]		0x34,	[ConfigChipId]		0x38,	[DstOffPitch]		0x40,	[DstYX]			0x43,	[DstHeight]		0x45,	[DstHeightWidth]	0x46,	[DstBresErr]		0x49,	[DstBresInc]		0x4A,	[DstBresDec]		0x4B,	[DstCntl]			0x4C,	[SrcOffPitch]		0x60,	[SrcYX]			0x63,	[SrcWidth1]		0x64,	[SrcYXstart]		0x69,	[SrcHeight1Width1]	0x66,	[SrcHeight2Width2]	0x6C,	[SrcCntl]			0x6D,	[HostCntl]			0x90,	[PatReg0]			0xA0,	[PatReg1]			0xA1,	[PatCntl]			0xA2,	[ScLeft]			0xA8,	[ScRight]			0xA9,	[ScLeftRight]		0xAA,	[ScTop]			0xAB,	[ScBottom] 		0xAC,	[ScTopBottom]		0xAD,	[DpBkgdClr]		0xB0,	[DpFrgdClr]		0xB1,	[DpWriteMask]		0xB2,	[DpChainMask]		0xB3,	[DpPixWidth]		0xB4,	[DpMix]			0xB5,	[DpSrc]			0xB6,	[ClrCmpClr]		0xC0,	[ClrCmpMask]		0xC1,	[ClrCmpCntl]		0xC2,	[FifoStat]			0xC4,	[ContextMask]		0xC8,	[GuiTrajCntl]		0xCC,	[GuiStat]			0xCE,	/* Bank1 */	[OverlayYX]		Bank1 + 0x00,	[OverlayYXEnd]		Bank1 + 0x01,	[OverlayKeyCntl]	Bank1 + 0x06,	[OverlayScaleInc]	Bank1 + 0x08,	[OverlayScaleCntl]	Bank1 + 0x09,	[ScalerHeightWidth]	Bank1 + 0x0A,	[ScalerBuf0Offset]	Bank1 + 0x0D,	[ScalerBuf0Pitch]	Bank1 + 0x0F,	[VideoFormat]		Bank1 + 0x12,	[CaptureConfig]	Bank1 + 0x14,	[Buf0Offset]		Bank1 + 0x20,	[Buf0Pitch]		Bank1 + 0x23,	[ScalerColourCntl]	Bank1 + 0x54,	[ScalerHCoef0]		Bank1 + 0x55,	[ScalerHCoef1]		Bank1 + 0x56,	[ScalerHCoef2]		Bank1 + 0x57,	[ScalerHCoef3]		Bank1 + 0x58,	[ScalerHCoef4]		Bank1 + 0x59,};static ulongior32(VGAscr* scr, int r){	if(scr->io == 0x2EC || scr->io == 0x1C8)		return inl((r<<10)+scr->io);	if(r >= 0x100 && scr->mmio != nil)		return scr->mmio[mmoffset[r]];	return inl((mmoffset[r]<<2)+scr->io);}static voidiow32(VGAscr* scr, int r, ulong l){	if(scr->io == 0x2EC || scr->io == 0x1C8)		outl(((r)<<10)+scr->io, l);	else if(r >= 0x100 && scr->mmio != nil)		scr->mmio[mmoffset[r]] = l;	else		outl((mmoffset[r]<<2)+scr->io, l);}static ulonglcdr32(VGAscr *scr, ulong r){	ulong or;	or = ior32(scr, LcdIndex);	iow32(scr, LcdIndex, (or&~0x0F) | (r&0x0F));	return ior32(scr, LcdData);}static voidlcdw32(VGAscr *scr, ulong r, ulong v){	ulong or;	or = ior32(scr, LcdIndex);	iow32(scr, LcdIndex, (or&~0x0F) | (r&0x0F));	iow32(scr, LcdData, v);}static voidmach64xxcurdisable(VGAscr* scr){	ulong r;	r = ior32(scr, GenTestCntl);	iow32(scr, GenTestCntl, r & ~0x80);}static voidmach64xxcurload(VGAscr* scr, Cursor* curs){	uchar *p;	int i, y;	ulong c, s, m, r;	/*	 * Disable the cursor.	 */	r = ior32(scr, GenTestCntl);	iow32(scr, GenTestCntl, r & ~0x80);	p = scr->vaddr;	p += scr->storage;	/*	 * Initialise the 64x64 cursor RAM array.	 * The cursor mode gives the following truth table:	 *	p1 p0	colour	 *	 0  0	Cursor Colour 0	 *	 0  1	Cursor Colour 1	 *	 1  0	Transparent	 *	 1  1	Complement	 * Put the cursor into the top-right of the 64x64 array.	 */	for(y = 0; y < 16; y++){		for(i = 0; i < (64-16)/8; i++){			*p++ = 0xAA;			*p++ = 0xAA;		}		c = (curs->clr[2*y]<<8)|curs->clr[y*2 + 1];		s = (curs->set[2*y]<<8)|curs->set[y*2 + 1];		m = 0x00000000;		for(i = 0; i < 16; i++){			if(s & (1<<(15-i)))				m |= 0x01<<(2*i);			else if(c & (1<<(15-i))){				/* nothing to do */			}			else				m |= 0x02<<(2*i);		}		*p++ = m;		*p++ = m>>8;		*p++ = m>>16;		*p++ = m>>24;	}	memset(p, 0xAA, (64-16)*16);	/*	 * Set the cursor hotpoint and enable the cursor.	 */	scr->offset = curs->offset;	iow32(scr, GenTestCntl, 0x80|r);}static intptalmostinrect(Point p, Rectangle r){	return p.x>=r.min.x && p.x<=r.max.x &&	       p.y>=r.min.y && p.y<=r.max.y;}/* * If necessary, translate the rectangle physr * some multiple of [dx dy] so that it includes p. * Return 1 if the rectangle changed. */static intscreenpan(Point p, Rectangle *physr, int dx, int dy){	int d;	if(ptalmostinrect(p, *physr))		return 0;	if(p.y < physr->min.y){		d = physr->min.y - (p.y&~(dy-1));		physr->min.y -= d;		physr->max.y -= d;	}	if(p.y > physr->max.y){		d = ((p.y+dy-1)&~(dy-1)) - physr->max.y;		physr->min.y += d;		physr->max.y += d;	}	if(p.x < physr->min.x){		d = physr->min.x - (p.x&~(dx-1));		physr->min.x -= d;		physr->max.x -= d;	}	if(p.x > physr->max.x){		d = ((p.x+dx-1)&~(dx-1)) - physr->max.x;		physr->min.x += d;		physr->max.x += d;	}	return 1;}static intmach64xxcurmove(VGAscr* scr, Point p){	int x, xo, y, yo;	int dx;	ulong off, pitch;	/*	 * If the point we want to display is outside the current	 * screen rectangle, pan the screen to display it.	 *	 * We have to move in 64-bit chunks.	 */	if(scr->gscreen->depth == 24)		dx = (64*3)/24;	else		dx = 64 / scr->gscreen->depth;	if(panning && screenpan(p, &physgscreenr, dx, 1)){		off = (physgscreenr.min.y*Dx(scr->gscreen->r)+physgscreenr.min.x)/dx;		pitch = Dx(scr->gscreen->r)/8;		iow32(scr, CrtcOffPitch, (pitch<<22)|off);	}	p.x -= physgscreenr.min.x;	p.y -= physgscreenr.min.y;	/*	 * Mustn't position the cursor offscreen even partially,	 * or it disappears. Therefore, if x or y is -ve, adjust the	 * cursor presets instead. If y is negative also have to	 * adjust the starting offset.	 */	if((x = p.x+scr->offset.x) < 0){		xo = x;		x = 0;	}	else		xo = 0;	if((y = p.y+scr->offset.y) < 0){		yo = y;		y = 0;	}	else		yo = 0;	iow32(scr, CurHVoff, ((64-16-yo)<<16)|(64-16-xo));	iow32(scr, CurOffset, scr->storage/8 + (-yo*2));	iow32(scr, CurHVposn, (y<<16)|x);	return 0;}static voidmach64xxcurenable(VGAscr* scr){	ulong r, storage;	mach64xxenable(scr);	if(scr->io == 0)		return;	r = ior32(scr, GenTestCntl);	iow32(scr, GenTestCntl, r & ~0x80);	iow32(scr, CurClr0, (Pwhite<<24)|(Pwhite<<16)|(Pwhite<<8)|Pwhite);	iow32(scr, CurClr1, (Pblack<<24)|(Pblack<<16)|(Pblack<<8)|Pblack);	/*	 * Find a place for the cursor data in display memory.	 * Must be 64-bit aligned.	 */	storage = (scr->gscreen->width*BY2WD*scr->gscreen->r.max.y+7)/8;	iow32(scr, CurOffset, storage);	scr->storage = storage*8;	/*	 * Cursor goes in the top right corner of the 64x64 array	 * so the horizontal and vertical presets are 64-16.	 */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -