Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "u.h"
2
#include "../port/lib.h"
3
#include "mem.h"
4
#include "dat.h"
5
#include "fns.h"
6
#include "../port/error.h"
7
 
8
enum {
9
	Black,
10
	Blue,
11
	Green,
12
	Cyan,
13
	Red,
14
	Magenta,
15
	Brown,
16
	Grey,
17
 
18
	Bright = 0x08,
19
	Blinking = 0x80,
20
 
21
	Yellow = Bright|Brown,
22
	White = Bright|Grey,
23
};
24
 
25
enum {
26
	Width		= 80*2,
27
	Height		= 25,
28
 
29
	Attr		= (Black<<4)|Grey,	/* high nibble background
30
						 * low foreground
31
						 */
32
};
33
 
34
#define CGASCREENBASE	((uchar*)KADDR(0xB8000))
35
 
36
#define inb(x)		0	/* TODO */
37
#define outb(x, y)			/* TODO */
38
 
39
static int cgapos;
40
static Lock cgascreenlock;
41
 
42
static uchar
43
cgaregr(int index)
44
{
45
	USED(index);
46
	outb(0x3D4, index);
47
	return inb(0x3D4+1) & 0xFF;
48
}
49
 
50
static void
51
cgaregw(int index, int data)
52
{
53
	USED(index, data);
54
	outb(0x3D4, index);
55
	outb(0x3D4+1, data);
56
}
57
 
58
static void
59
movecursor(void)
60
{
61
	cgaregw(0x0E, (cgapos/2>>8) & 0xFF);
62
	cgaregw(0x0F, cgapos/2 & 0xFF);
63
	CGASCREENBASE[cgapos+1] = Attr;
64
}
65
 
66
static void
67
cgascreenputc(int c)
68
{
69
	int i;
70
	uchar *p;
71
 
72
	if(c == '\n'){
73
		cgapos = cgapos/Width;
74
		cgapos = (cgapos+1)*Width;
75
	}
76
	else if(c == '\t'){
77
		i = 8 - ((cgapos/2)&7);
78
		while(i-->0)
79
			cgascreenputc(' ');
80
	}
81
	else if(c == '\b'){
82
		if(cgapos >= 2)
83
			cgapos -= 2;
84
		cgascreenputc(' ');
85
		cgapos -= 2;
86
	}
87
	else{
88
		CGASCREENBASE[cgapos++] = c;
89
		CGASCREENBASE[cgapos++] = Attr;
90
	}
91
	if(cgapos >= Width*Height){
92
		memmove(CGASCREENBASE, &CGASCREENBASE[Width], Width*(Height-1));
93
		p = &CGASCREENBASE[Width*(Height-1)];
94
		for(i=0; i<Width/2; i++){
95
			*p++ = ' ';
96
			*p++ = Attr;
97
		}
98
		cgapos = Width*(Height-1);
99
	}
100
	movecursor();
101
}
102
 
103
static void
104
cgascreenputs(char* s, int n)
105
{
106
	if(!islo()){
107
		/*
108
		 * Don't deadlock trying to
109
		 * print in an interrupt.
110
		 */
111
		if(!canlock(&cgascreenlock))
112
			return;
113
	}
114
	else
115
		lock(&cgascreenlock);
116
 
117
	while(n-- > 0)
118
		cgascreenputc(*s++);
119
 
120
	unlock(&cgascreenlock);
121
}
122
 
123
void
124
screeninit(void)
125
{
126
 
127
	cgapos = cgaregr(0x0E)<<8;
128
	cgapos |= cgaregr(0x0F);
129
	cgapos *= 2;
130
 
131
	screenputs = cgascreenputs;
132
}