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

📄 vgat2r4.c

📁 著名操作系统Plan 9的第三版的部分核心源代码。现在很难找到了。Plan 9是bell实验室开发的Unix后继者。
💻 C
字号:
#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"/* * #9 Ticket to Ride IV. */enum {	IndexLo		= 0x10/4,	IndexHi		= 0x14/4,	Data		= 0x18/4,	IndexCtl	= 0x1C/4,	Zoom		= 0x54/4,};enum {						/* index registers */	CursorSyncCtl	= 0x03,	  HsyncHi = 0x01,	  HsyncLo = 0x02,	  VsyncHi = 0x04,	  VsyncLo = 0x08,	CursorCtl	= 0x30,	CursorXLo	= 0x31,	CursorXHi	= 0x32,	CursorYLo	= 0x33,	CursorYHi	= 0x34,	CursorHotX	= 0x35,	CursorHotY	= 0x36,	CursorR1	= 0x40,	CursorG1	= 0x41,	CursorB1	= 0x42,	CursorR2	= 0x43,	CursorG2	= 0x44,	CursorB2	= 0x45,	CursorR3	= 0x46,	CursorG3	= 0x47,	CursorB3	= 0x48,	CursorArray	= 0x100,	CursorMode32x32	= 0x23,	CursorMode64x64	= 0x27,	CursorMode	= CursorMode32x32,};static ulongt2r4linear(VGAscr* scr, int* size, int* align){	ulong aperture, oaperture;	int oapsize, wasupamem;	Pcidev *p;	oaperture = scr->aperture;	oapsize = scr->apsize;	wasupamem = scr->isupamem;	aperture = 0;	if(p = pcimatch(nil, 0x105D, 0)){		switch(p->did){		case 0x5348:			aperture = p->mem[0].bar & ~0x0F;			*size = p->mem[0].size;			break;		default:			break;		}	}	if(wasupamem){		if(oaperture == aperture)			return oaperture;		upafree(oaperture, oapsize);	}	scr->isupamem = 0;	aperture = upamalloc(aperture, *size, *align);	if(aperture == 0){		if(wasupamem && upamalloc(oaperture, oapsize, 0)){			aperture = oaperture;			scr->isupamem = 1;		}		else			scr->isupamem = 0;	}	else		scr->isupamem = 1;	return aperture;}static voidt2r4enable(VGAscr* scr){	Pcidev *p;	Physseg seg;	int size, align;	ulong aperture, mmio;	/*	 * Only once, can't be disabled for now.	 * scr->mmio holds the virtual address of	 * the MMIO registers.	 */	if(scr->mmio)		return;	if(p = pcimatch(nil, 0x105D, 0)){		switch(p->did){		case 0x5348:			break;		default:			return;		}	}	else		return;	mmio = upamalloc(p->mem[4].bar & ~0x0F, p->mem[4].size, 0);	if(mmio == 0)		return;	memset(&seg, 0, sizeof(seg));	seg.attr = SG_PHYSICAL;	seg.name = smalloc(NAMELEN);	snprint(seg.name, NAMELEN, "t2r4mmio");	seg.pa = mmio;	seg.size = p->mem[4].size;	addphysseg(&seg);	scr->mmio = KADDR(mmio);	size = p->mem[0].size;	align = 0;	aperture = t2r4linear(scr, &size, &align);	if(aperture){		scr->aperture = aperture;		scr->apsize = size;		memset(&seg, 0, sizeof(seg));		seg.attr = SG_PHYSICAL;		seg.name = smalloc(NAMELEN);		snprint(seg.name, NAMELEN, "t2r4screen");		seg.pa = aperture;		seg.size = size;		addphysseg(&seg);	}}static uchart2r4xi(VGAscr* scr, int index){	ulong *mmio;	mmio = scr->mmio;	mmio[IndexLo] = index & 0xFF;	mmio[IndexHi] = (index>>8) & 0xFF;	return mmio[Data];}static voidt2r4xo(VGAscr* scr, int index, uchar data){	ulong *mmio;	mmio = scr->mmio;	mmio[IndexLo] = index & 0xFF;	mmio[IndexHi] = (index>>8) & 0xFF;	mmio[Data] = data;}static voidt2r4curdisable(VGAscr* scr){	if(scr->mmio == 0)		return;	t2r4xo(scr, CursorCtl, 0x00);}static voidt2r4curload(VGAscr* scr, Cursor* curs){	uchar *data;	int size, x, y, zoom;	ulong clr, *mmio, pixels, set;	mmio = scr->mmio;	if(mmio == 0)		return;	/*	 * Make sure cursor is off by initialising the cursor	 * control to defaults.	 */	t2r4xo(scr, CursorCtl, 0x00);	/*	 * Set auto-increment mode for index-register addressing	 * and initialise the cursor array index.	 */	mmio[IndexCtl] = 0x01;	mmio[IndexLo] = CursorArray & 0xFF;	mmio[IndexHi] = (CursorArray>>8) & 0xFF;	/*	 * Initialise the cursor RAM array. There are 2 planes,	 * p0 and p1. Data is written 4 pixels per byte, with p1 the	 * MS bit of each pixel.	 * The cursor is set in X-Windows mode which gives the following	 * truth table:	 *	p1 p0	colour	 *	 0  0	underlying pixel colour	 *	 0  1	underlying pixel colour	 *	 1  0	cursor colour 1	 *	 1  1	cursor colour 2	 * Put the cursor into the top-left of the array.	 *	 * Although this looks a lot like the IBM RGB524 cursor, the	 * scanlines appear to be twice as long as they should be and	 * some of the other features are missing.	 */	if(mmio[Zoom] & 0x0F)		zoom = 32;	else		zoom = 16;	data = (uchar*)&mmio[Data];	for(y = 0; y < zoom; y++){		clr = (curs->clr[2*y]<<8)|curs->clr[y*2 + 1];		set = (curs->set[2*y]<<8)|curs->set[y*2 + 1];		pixels = 0;		for(x = 0; x < 16; x++){			if(set & (1<<x))				pixels |= 0x03<<(x*2);			else if(clr & (1<<x))				pixels |= 0x02<<(x*2);		}		*data = pixels>>24;		*data = pixels>>16;		*data = pixels>>8;		*data = pixels;		*data = 0x00;		*data = 0x00;		*data = 0x00;		*data = 0x00;		if(CursorMode == CursorMode32x32 && zoom == 16)			continue;		*data = pixels>>24;		*data = pixels>>16;		*data = pixels>>8;		*data = pixels;		*data = 0x00;		*data = 0x00;		*data = 0x00;		*data = 0x00;	}	if(CursorMode == CursorMode32x32)		size = 32;	else		size = 64;	while(y < size){		for(x = 0; x < size/8; x++){			*data = 0x00;			*data = 0x00;		}		y++;	}	mmio[IndexCtl] = 0x00;	/*	 * Initialise the hotpoint and enable the cursor.	 */	t2r4xo(scr, CursorHotX, -curs->offset.x);	zoom = (scr->mmio[Zoom] & 0x0F)+1;	t2r4xo(scr, CursorHotY, -curs->offset.y*zoom);	t2r4xo(scr, CursorCtl, CursorMode);}static intt2r4curmove(VGAscr* scr, Point p){	int y, zoom;	if(scr->mmio == 0)		return 1;	t2r4xo(scr, CursorXLo, p.x & 0xFF);	t2r4xo(scr, CursorXHi, (p.x>>8) & 0x0F);	zoom = (scr->mmio[Zoom] & 0x0F)+1;	y = p.y*zoom;	t2r4xo(scr, CursorYLo, y & 0xFF);	t2r4xo(scr, CursorYHi, (y>>8) & 0x0F);	return 0;}static voidt2r4curenable(VGAscr* scr){	t2r4enable(scr);	if(scr->mmio == 0)		return;	/*	 * Make sure cursor is off by initialising the cursor	 * control to defaults.	 */	t2r4xo(scr, CursorCtl, 0x00);	/*	 * Cursor colour 1 (white),	 * cursor colour 2 (black).	 */	t2r4xo(scr, CursorR1, Pwhite);	t2r4xo(scr, CursorG1, Pwhite);	t2r4xo(scr, CursorB1, Pwhite);	t2r4xo(scr, CursorR2, Pblack);	t2r4xo(scr, CursorG2, Pblack);	t2r4xo(scr, CursorB2, Pblack);	/*	 * Load, locate and enable the cursor, 64x64, mode 2.	 */	t2r4curload(scr, &arrow);	t2r4curmove(scr, ZP);	t2r4xo(scr, CursorCtl, CursorMode);}enum {	Flow		= 0x08/4,	Busy		= 0x0C/4,	BufCtl		= 0x20/4,	DeSorg		= 0x28/4,	DeDorg		= 0x2C/4,	DeSptch		= 0x40/4,	DeDptch		= 0x44/4,	CmdOpc		= 0x50/4,	CmdRop		= 0x54/4,	CmdStyle 	= 0x58/4,	CmdPatrn 	= 0x5C/4,	CmdClp		= 0x60/4,	CmdPf		= 0x64/4,	Fore		= 0x68/4,	Back		= 0x6C/4,	Mask		= 0x70/4,	DeKey		= 0x74/4,	Lpat		= 0x78/4,	Pctrl 		= 0x7C/4,	Clptl		= 0x80/4,	Clpbr		= 0x84/4,	XY0		= 0x88/4,	XY1		= 0x8C/4,	XY2		= 0x90/4,	XY3		= 0x94/4,	XY4		= 0x98/4,	Alpha 		= 0x128/4,	ACtl 		= 0x16C/4,	RBaseD 		= 0x4000/4,};/* wait until pipeline ready for new command */static voidwaitforfifo(VGAscr *scr){	int x;	ulong *d;	x = 0;	d = scr->mmio + RBaseD;	while((d[Busy]&1) && x++ < 1000000)		;	if(x >= 1000000)	/* shouldn't happen */		iprint("busy %8lux\n", d[Busy]);}/* wait until command has finished executing */static voidwaitforcmd(VGAscr *scr){	int x;	ulong *d;	x = 0;	d = scr->mmio + RBaseD;	while((d[Flow]&0x1B) && x++ < 1000000)		;	if(x >= 1000000)	/* shouldn't happen */		iprint("flow %8lux\n", d[Flow]);}/* wait until memory controller not busy (i.e. wait for writes to flush) */static voidwaitformem(VGAscr *scr){	int x;	ulong *d;	x = 0;	d = scr->mmio + RBaseD;	while((d[Flow]&2)&& x++ < 1000000)		;	if(x >= 1000000)	/* shouldn't happen */		iprint("mem %8lux\n", d[Busy]);}static intt2r4hwscroll(VGAscr *scr, Rectangle r, Rectangle sr){	int ctl;	Point dp, sp;	ulong *d;	int depth;	if(r.min.y == sr.min.y){	/* a purely horizontal scroll */		depth = scr->gscreen->depth;		switch(depth){		case 32:			/*			 * Using the SGI flat panels with the Ticket-to-Ride IV, horizontal			 * 32-bit scrolls don't work perfectly on rectangles of width <= 24.			 * we bail on a bigger bound for padding.			 */			if(Dx(r) < 32)				return 0;			break;		case 16:			/*			 * Using the SGI flat panels with the Ticket-to-Ride IV, horizontal			 * 16-bit scrolls don't work perfectly on rectangles of width <= 96.			 * we bail on a bigger bound for padding.			 */			if(Dx(r) < 104)				return 0;			break;		}	}	waitformem(scr);	waitforfifo(scr);	d = scr->mmio + RBaseD;	ctl = 0;	if(r.min.x <= sr.min.x){		dp.x = r.min.x;		sp.x = sr.min.x;	}else{		ctl |= 2;		dp.x = r.max.x-1;		sp.x = sr.max.x-1;	}	if(r.min.y < sr.min.y){		dp.y = r.min.y;		sp.y = sr.min.y;	}else{		ctl |= 1;		dp.y = r.max.y-1;		sp.y = sr.max.y-1;	}	d[CmdOpc] = 0x1;	/* bitblt */	d[CmdRop] = 0xC;	/* copy source */	d[CmdStyle] = 0;	d[CmdPatrn] = 0;	d[Fore] = 0;	d[Back] = 0;	/* writing XY1 executes cmd */	d[XY3] = ctl;	d[XY0] = (sp.x<<16)|sp.y;	d[XY2] = (Dx(r)<<16)|Dy(r);	d[XY4] = 0;	d[XY1] = (dp.x<<16)|dp.y;	waitforcmd(scr);	return 1;}static intt2r4hwfill(VGAscr *scr, Rectangle r, ulong sval){	ulong *d;	d = scr->mmio + RBaseD;	waitformem(scr);	waitforfifo(scr);	d[CmdOpc] = 0x1;	/* bitblt */	d[CmdRop] = 0xC;	/* copy source */	d[CmdStyle] = 1;	/* use source from Fore register */	d[CmdPatrn] = 0;	/* no stipple */	d[Fore] = sval;	d[Back] = sval;	/* writing XY1 executes cmd */	d[XY3] = 0;	d[XY0] = (r.min.x<<16)|r.min.y;	d[XY2] = (Dx(r)<<16)|Dy(r);	d[XY4] = 0;	d[XY1] = (r.min.x<<16)|r.min.y;	waitforcmd(scr);	return 1;}static voidt2r4blank(VGAscr *scr, int blank){	uchar x;	x = t2r4xi(scr, CursorSyncCtl);	x &= ~0x0F;	if(blank)		x |= HsyncLo | VsyncLo;	t2r4xo(scr, CursorSyncCtl, x);}static voidt2r4drawinit(VGAscr *scr){	ulong pitch;	int depth;	int fmt;	ulong *d;	pitch = Dx(scr->gscreen->r);	depth = scr->gscreen->depth;	switch(scr->gscreen->chan){	case RGB16:		fmt = 3;		break;	case XRGB32:		fmt = 2;		break;	case RGB15:		fmt = 1;		break;	default:		scr->fill = nil;		scr->scroll = nil;		return;	}	d = scr->mmio + RBaseD;	d[BufCtl] = fmt<<24;	d[DeSorg] = 0;	d[DeDorg] = 0;	d[DeSptch] = (pitch*depth)/8;	d[DeDptch] = (pitch*depth)/8;	d[CmdClp] = 0;	/* 2 = inside rectangle */	d[Mask] = ~0;	d[DeKey] = 0;	d[Clptl] = 0; 	d[Clpbr] = 0xFFF0FFF0;	d[Alpha] = 0;	d[ACtl] = 0;	scr->fill = t2r4hwfill;	scr->scroll = t2r4hwscroll;	scr->blank = t2r4blank;}VGAdev vgat2r4dev = {	"t2r4",	t2r4enable,	nil,	nil,	t2r4linear,	t2r4drawinit,};VGAcur vgat2r4cur = {	"t2r4hwgc",	t2r4curenable,	t2r4curdisable,	t2r4curload,	t2r4curmove,};

⌨️ 快捷键说明

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