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

📄 et4000.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
#include <u.h>#include <libc.h>#include <bio.h>#include "pci.h"#include "vga.h"/* * Tseng Labs Inc. ET4000 Video Controller. */enum {	Crtcbx		= 0x217A,	/* Secondary CRT controller */	Sprite		= 0xE0,	NSprite		= 0x10,	Ima		= 0xF0,	NIma		= 0x08,};static voidsetkey(void){	outportb(0x3BF, 0x03);	outportb(0x3D8, 0xA0);	outportb(0x3CD, 0x00);}static voidsnarf(Vga* vga, Ctlr* ctlr){	int i;	setkey();	vga->sequencer[0x06] = vgaxi(Seqx, 0x06);	vga->sequencer[0x07] = vgaxi(Seqx, 0x07);	for(i = 0x30; i < 0x38; i++)		vga->crt[i] = vgaxi(Crtx, i);	vga->crt[0x3F] = vgaxi(Crtx, 0x3F);	vga->attribute[0x16] = vgaxi(Attrx, 0x16);	vga->attribute[0x17] = vgaxi(Attrx, 0x17);	/*	 * Memory size.	 */	switch(vga->crt[0x37] & 0x03){	case 1:		vga->vmz = 256*1024;		break;	case 2:		vga->vmz = 512*1024;		break;	case 3:		vga->vmz = 1024*1024;		break;	}	if(strncmp(ctlr->name, "et4000-w32", 10) == 0){		if(vga->crt[0x32] & 0x80)			vga->vmz *= 2;	}	else if(vga->crt[0x37] & 0x80)		vga->vmz *= 2;	ctlr->flag |= Fsnarf;}static voidoptions(Vga* vga, Ctlr* ctlr){	/*	 * The ET4000 does not need to have the vertical	 * timing values divided by 2 for interlace mode.	 */	if(vga->mode->interlace == 'v')		vga->mode->interlace = 'V';	if(strncmp(ctlr->name, "et4000-w32", 10) == 0)		ctlr->flag |= Hpclk2x8;		ctlr->flag |= Hclkdiv|Foptions;}static voidinit(Vga* vga, Ctlr* ctlr){	Mode *mode;	ulong x;	if(vga->mode->z > 8)		error("depth %d not supported\n", vga->mode->z);	if(ctlr->flag & Upclk2x8){		mode = vga->mode;		vga->crt[0x00] = ((mode->ht/2)>>3)-5;		vga->crt[0x01] = ((mode->x/2)>>3)-1;		vga->crt[0x02] = ((mode->shb/2)>>3)-1;			x = (mode->ehb/2)>>3;		vga->crt[0x03] = 0x80|(x & 0x1F);		vga->crt[0x04] = (mode->shs/2)>>3;		vga->crt[0x05] = ((mode->ehs/2)>>3) & 0x1F;		if(x & 0x20)			vga->crt[0x05] |= 0x80;	}	/*	 * Itth a mythtawee.	 */	if(vga->crt[0x14] & 0x20)		vga->crt[0x17] |= 0x08;	vga->crt[0x17] &= ~0x20;	vga->crt[0x30] = 0x00;	vga->crt[0x33] = 0x00;	/*	 * Overflow High.	 */	vga->crt[0x35] = 0x00;	if(vga->crt[0x15] & 0x400)		vga->crt[0x35] |= 0x01;	if(vga->crt[0x06] & 0x400)		vga->crt[0x35] |= 0x02;	if(vga->crt[0x12] & 0x400)		vga->crt[0x35] |= 0x04;	if(vga->crt[0x10] & 0x400)		vga->crt[0x35] |= 0x08;	if(vga->crt[0x18] & 0x400)		vga->crt[0x35] |= 0x10;	if(vga->mode->interlace == 'V')		vga->crt[0x35] |= 0x80;	/*	 * Horizontal Overflow.	 */	vga->crt[0x3F] = 0x00;	if(vga->crt[0x00] & 0x100)		vga->crt[0x3F] |= 0x01;	if(vga->crt[0x02] & 0x100)		vga->crt[0x3F] |= 0x04;	if(vga->crt[0x04] & 0x100)		vga->crt[0x3F] |= 0x10;	if(vga->crt[0x13] & 0x100)		vga->crt[0x3F] |= 0x80;	/*	 * Turn off MMU buffers, linear map	 * and memory-mapped registers.	 */	vga->crt[0x36] &= ~0x38;	if(strncmp(ctlr->name, "et4000-w32", 10) == 0)		vga->crt[0x37] |= 0x80;	vga->sequencer[0x06] = 0x00;	/*	 * Clock select.	 */	if(vga->f[0] > 86000000)		error("%s: invalid pclk - %ld\n", ctlr->name, vga->f[0]);	vga->misc &= ~0x0C;	vga->misc |= (vga->i[0] & 0x03)<<2;	if(vga->i[0] & 0x04)		vga->crt[0x34] |= 0x02;	else		vga->crt[0x34] &= ~0x02;	vga->crt[0x31] &= ~0xC0;	vga->crt[0x31] |= (vga->i[0] & 0x18)<<3;	vga->sequencer[0x07] &= ~0x41;	if(vga->d[0] == 4)		vga->sequencer[0x07] |= 0x01;	else if(vga->d[0] == 2)		vga->sequencer[0x07] |= 0x40;	vga->attribute[0x10] &= ~0x40;	vga->attribute[0x11] = Pblack;	vga->attribute[0x16] = 0x80;	if(ctlr->flag & Upclk2x8)		vga->attribute[0x16] |= 0x20;	ctlr->flag |= Finit;}static voidload(Vga* vga, Ctlr* ctlr){	vgaxo(Crtx, 0x30, vga->crt[0x30]);	vgaxo(Crtx, 0x31, vga->crt[0x31]);	vgaxo(Crtx, 0x33, vga->crt[0x33]);	vgaxo(Crtx, 0x34, vga->crt[0x34]);	vgaxo(Crtx, 0x35, vga->crt[0x35]);	vgaxo(Crtx, 0x36, vga->crt[0x36]);	vgaxo(Crtx, 0x37, vga->crt[0x37]);	vgaxo(Crtx, 0x3F, vga->crt[0x3F]);	vgaxo(Seqx, 0x06, vga->sequencer[0x06]);	vgaxo(Seqx, 0x07, vga->sequencer[0x07]);	vgaxo(Attrx, 0x16, vga->attribute[0x16]);	ctlr->flag |= Fload;}static voiddump(Vga* vga, Ctlr* ctlr){	int i;	char *name;	ushort shb, vrs, x;	name = ctlr->name;	printitem(name, "Seq06");	printreg(vga->sequencer[0x06]);	printreg(vga->sequencer[0x07]);	printitem(name, "Crt30");	for(i = 0x30; i < 0x38; i++)		printreg(vga->crt[i]);	printitem(name, "Crt3F");	printreg(vga->crt[0x3F]);	printitem(name, "Attr16");	printreg(vga->attribute[0x16]);	printreg(vga->attribute[0x17]);	if(strncmp(name, "et4000-w32", 10) == 0){		printitem(name, "SpriteE0");		for(i = Sprite; i < Sprite+NSprite; i++){			outportb(Crtcbx, i);			printreg(inportb(Crtcbx+1));		}		printitem(name, "ImaF0");		for(i = Ima; i < Ima+NIma; i++){			outportb(Crtcbx, i);			printreg(inportb(Crtcbx+1));		}	}	/*	 * Try to disassemble the snarfed values into	 * understandable numbers.	 * Only do this if we weren't called after Finit.	 */	if(ctlr->flag & Finit)		return;	x = (vga->crt[0x01]+1)<<3;	printitem(name, "hde");	printreg(x);	Bprint(&stdout, "%6ud", x);	shb = ((((vga->crt[0x3F] & 0x04)<<6)|vga->crt[0x02])+1)<<3;	printitem(name, "shb");	printreg(shb);	Bprint(&stdout, "%6ud", shb);	x = (((vga->crt[0x05] & 0x80)>>2)|(vga->crt[0x03] & 0x1F))<<3;	printitem(name, "ehb");	printreg(x);	for(i = 0; x < shb; i++)		x |= 0x200<<i;	Bprint(&stdout, "%6ud", x);	x = ((((vga->crt[0x3F] & 0x01)<<8)|vga->crt[0x00])+5)<<3;	printitem(name, "ht");	printreg(x);	Bprint(&stdout, "%6ud", x);	x = vga->crt[0x12];	if(vga->crt[0x07] & 0x02)		x |= 0x100;	if(vga->crt[0x07] & 0x40)		x |= 0x200;	if(vga->crt[0x35] & 0x04)		x |= 0x400;	x += 1;	printitem(name, "vde");	printreg(x);	Bprint(&stdout, "%6ud", x);	vrs = vga->crt[0x10];	if(vga->crt[0x07] & 0x04)		vrs |= 0x100;	if(vga->crt[0x07] & 0x80)		vrs |= 0x200;	if(vga->crt[0x35] & 0x08)		vrs |= 0x400;	printitem(name, "vrs");	printreg(vrs);	Bprint(&stdout, "%6ud", vrs);	x = (vrs & ~0x0F)|(vga->crt[0x11] & 0x0F);	printitem(name, "vre");	printreg(x);	Bprint(&stdout, "%6ud", x);	x = vga->crt[0x06];	if(vga->crt[0x07] & 0x01)		x |= 0x100;	if(vga->crt[0x07] & 0x20)		x |= 0x200;	if(vga->crt[0x35] & 0x02)		x |= 0x400;	x += 2;	printitem(name, "vt");	printreg(x);	Bprint(&stdout, "%6ud", x);	printitem(name, "d i");	if(vga->sequencer[0x07] & 0x01)		x = 4;	else if(vga->sequencer[0x07] & 0x40)		x = 2;	else		x = 0;	Bprint(&stdout, "%9ud", x);	x = (vga->misc & 0x0C)>>2;	if(vga->crt[0x34] & 0x02)		x |= 0x04;	x |= (vga->crt[0x31] & 0xC0)>>3;	Bprint(&stdout, "%8ud\n", x);}Ctlr et4000 = {	"et4000",			/* name */	snarf,				/* snarf */	options,			/* options */	init,				/* init */	load,				/* load */	dump,				/* dump */};

⌨️ 快捷键说明

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