File:  [Plan 9 NeXT] / lucent / sys / src / boot / pc / cga.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 18:01:05 2018 UTC (8 years, 1 month ago) by root
Branches: lucent, MAIN
CVS tags: plan9, HEAD
Plan 9 NeXT

#include	"u.h"
#include	"lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"

#define	WIDTH	160
#define	HEIGHT	24
#define SCREEN	((char *)(0xB8000|KZERO))
#define ATTR	0x02

static int inited;
static int pos;

static uchar
cgaregr(uchar index)
{
	outb(0x03D4, index);
	return inb(0x03D4+1);
}

static void
cgaregw(uchar index, uchar data)
{
	outb(0x03D4, index);
	outb(0x03D4+1, data);
}

static void
clearline(int lineno)
{
	char *p;
	int i;

	p = &SCREEN[WIDTH*lineno];
	for(i = 0; i < WIDTH; i += 2){
		*p++ = 0x00;
		*p++ = ATTR;
	}
}

static void
movecursor(void)
{
	cgaregw(0x0E, (pos/2>>8) & 0xFF);
	cgaregw(0x0F, pos/2 & 0xFF);
}

void
cgainit(void)
{
	int i;

	for(i = pos/WIDTH; i < HEIGHT; i++)
		clearline(i);
	movecursor();
	inited = 1;
}

static void
cgaputc(int c)
{
	int i;

	if(c == '\n'){
		if(inited == 0){
			for(i = (pos % WIDTH); i < WIDTH; i += 2)
				cgaputc(' ');
		}
		else{
			pos = pos/WIDTH;
			pos = (pos+1)*WIDTH;
		}
	} else if(c == '\t'){
		i = 4 - ((pos/2)&3);
		while(i-->0)
			cgaputc(' ');
	} else if(c == '\b'){
		if(pos >= 2)
			pos -= 2;
		cgaputc(' ');
		pos -= 2;
	} else {
		SCREEN[pos++] = c;
		SCREEN[pos++] = ATTR;
	}
	if(pos >= WIDTH*HEIGHT){
		memmove(SCREEN, &SCREEN[WIDTH], WIDTH*(HEIGHT-1));
		clearline(HEIGHT-1);
		pos = WIDTH*(HEIGHT-1);
	}
	movecursor();
}

void
cgaputs(IOQ*, char *s, int n)
{
	while(n-- > 0)
		cgaputc(*s++);
}

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.