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

📄 vgaet4000.c

📁 这是一个同样来自贝尔实验室的和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"static voidsetet4000page(int page){	uchar p;	p = page & 0x0F;	p |= p<<4;	outb(0x3CD, p);	p = (page & 0x30);	p |= p>>4;	outb(0x3CB, p);}static voidet4000page(VGAscr *scr, int page){	lock(&scr->devlock);	setet4000page(page);	unlock(&scr->devlock);}static voidet4000disable(VGAscr*){	uchar imaF7;	outb(0x217A, 0xF7);	imaF7 = inb(0x217B) & ~0x80;	outb(0x217B, imaF7);}static voidet4000enable(VGAscr *scr){	uchar imaF7;	et4000disable(scr);	/*	 * Configure CRTCB for Sprite, 64x64,	 * CRTC pixel overlay.	 */	outb(0x217A, 0xEF);	outb(0x217B, 0x02);	/*	 * Cursor goes in the top left corner	 * of the Sprite area, so the horizontal and	 * vertical presets are 0.	 */	outb(0x217A, 0xE2);	outb(0x217B, 0x00);	outb(0x217A, 0xE3);	outb(0x217B, 0x00);	outb(0x217A, 0xE6);	outb(0x217B, 0x00);	outb(0x217A, 0xE7);	outb(0x217B, 0x00);	/*	 * Find a place for the cursor data in display memory.	 * Must be on a "doubleword" boundary, but put it on a	 * 1024-byte boundary so that there's no danger of it	 * crossing a page.	 */	scr->storage = (scr->gscreen->width*BY2WD*scr->gscreen->r.max.y+1023)/1024;	scr->storage *= 1024/4;	outb(0x217A, 0xE8);	outb(0x217B, scr->storage & 0xFF);	outb(0x217A, 0xE9);	outb(0x217B, (scr->storage>>8) & 0xFF);	outb(0x217A, 0xEA);	outb(0x217B, (scr->storage>>16) & 0x0F);	scr->storage *= 4;	/*	 * Row offset in "quadwords". Must be 2 for Sprite.	 * Bag the pixel-panning.	 * Colour depth, must be 2 for Sprite.	 */	outb(0x217A, 0xEB);	outb(0x217B, 0x02);	outb(0x217A, 0xEC);	outb(0x217B, 0x00);	outb(0x217A, 0xED);	outb(0x217B, 0x00);	outb(0x217A, 0xEE);//	if(vgascreen.ldepth == 3)		outb(0x217B, 0x01);//	else//		outb(0x217B, 0x00);	/*	 * Enable the CRTCB/Sprite.	 */	outb(0x217A, 0xF7);	imaF7 = inb(0x217B);	outb(0x217B, 0x80|imaF7);}static voidet4000load(VGAscr *scr, Cursor *c){	uchar p0, p1, *mem;	int i, x, y;	ushort p;	uchar clr[2*16], set[2*16];	/*	 * Lock the display memory so we can update the	 * cursor bitmap if necessary.	 */	lock(&scr->devlock);	/*	 * Disable the cursor.	 * Set the display page (do we need to restore	 * the current contents when done?) and the	 * pointer to the two planes. What if this crosses	 * into a new page?	 */	et4000disable(scr);	setet4000page(scr->storage>>16);	mem = (uchar*)scr->vaddr + (scr->storage & 0xFFFF);	/*	 * Initialise the 64x64 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 mode gives the following truth table:	 *	p1 p0	colour	 *	 0  0	Sprite Colour 0 (defined as 0x00)	 *	 0  1	Sprite Colour 1 (defined as 0xFF)	 *	 1  0	Transparent (allow CRTC pixel pass through)	 *	 1  1	Invert (allow CRTC pixel invert through)	 * Put the cursor into the top-left of the 64x64 array.	 *	 * This is almost certainly wrong, since it has not	 * been updated for the 3rd edition color values.	 */	memmove(clr, c->clr, sizeof(clr));//	pixreverse(clr, sizeof(clr), 0);	memmove(set, c->set, sizeof(set));//	pixreverse(set, sizeof(set), 0);	for(y = 0; y < 64; y++){		for(x = 0; x < 64/8; x++){			if(x < 16/8 && y < 16){				p0 = clr[x+y*2];				p1 = set[x+y*2];				p = 0x0000;				for(i = 0; i < 8; i++){					if(p1 & (1<<(7-i))){						/* nothing to do */					}					else if(p0 & (1<<(7-i)))						p |= 0x01<<(2*i);					else						p |= 0x02<<(2*i);				}				*mem++ = p & 0xFF;				*mem++ = (p>>8) & 0xFF;			}			else {				*mem++ = 0xAA;				*mem++ = 0xAA;			}		}	}	/*	 * enable the cursor.	 */	outb(0x217A, 0xF7);	p = inb(0x217B)|0x80;	outb(0x217B, p);	unlock(&scr->devlock);}static intet4000move(VGAscr *scr, Point p){	int x, xo, y, yo;	if(canlock(&scr->devlock) == 0)		return 1;	/*	 * Mustn't position the cursor offscreen even partially,	 * or it disappears. Therefore, if x or y is -ve, adjust the	 * cursor presets instead.	 */	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;	/*	 * The cursor image is jerky if we don't do this.	 * The cursor information is probably fetched from	 * display memory during the horizontal blank active	 * time and it doesn't like it if the coordinates	 * are changed underneath.	 */	while((vgai(Status1) & 0x08) == 0)		;	outb(0x217A, 0xE2);	outb(0x217B, xo);	outb(0x217A, 0xE6);	outb(0x217B, yo);	outb(0x217A, 0xE1);	outb(0x217B, (x>>8) & 0xFF);	outb(0x217A, 0xE0);	outb(0x217B, x & 0xFF);	outb(0x217A, 0xE5);	outb(0x217B, (y>>8) & 0xFF);	outb(0x217A, 0xE4);	outb(0x217B, y & 0xFF);	unlock(&scr->devlock);	return 0;}VGAcur vgaet4000cur = {	"et4000hwgc",	et4000enable,	et4000disable,	et4000load,	et4000move,};VGAdev vgaet4000dev = {	"et4000",	0,	0,	et4000page,	0};

⌨️ 快捷键说明

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