Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | 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
	Poststrlen	= 0,
34
	Postcodelen	= 2,
35
	Postlen		= Poststrlen+Postcodelen,
36
};
37
 
38
#define CGASCREENBASE	((uchar*)KADDR(0xB8000))
39
#define CGA		CGASCREENBASE
40
 
41
static int cgapos;
42
static Lock cgascreenlock;
43
 
44
static uchar
45
cgaregr(int index)
46
{
47
	outb(0x3D4, index);
48
	return inb(0x3D4+1) & 0xFF;
49
}
50
 
51
static void
52
cgaregw(int index, int data)
53
{
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
char hex[] = "0123456789ABCDEF";
124
 
125
void
126
cgapost(int code)
127
{
128
	uchar *cga;
129
 
130
	cga = CGA;
131
	cga[Width*Height-Postcodelen*2] = hex[(code>>4) & 0x0F];
132
	cga[Width*Height-Postcodelen*2+1] = Attr;
133
	cga[Width*Height-Postcodelen*2+2] = hex[code & 0x0F];
134
	cga[Width*Height-Postcodelen*2+3] = Attr;
135
}
136
 
137
void
138
screeninit(void)
139
{
140
 
141
	cgapos = cgaregr(0x0E)<<8;
142
	cgapos |= cgaregr(0x0F);
143
	cgapos *= 2;
144
 
145
	screenputs = cgascreenputs;
146
}