|
|
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++);
}
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.