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 "io.h"
7
#include "../port/error.h"
8
 
9
#define	Image	IMAGE
10
#include <draw.h>
11
#include <memdraw.h>
12
#include <cursor.h>
13
#include "screen.h"
14
 
15
/*
16
 * Hardware graphics cursor support for
17
 * Brooktree Bt485 Monolithic True-Color RAMDAC.
18
 * Assumes hooked up to an S3 86C928.
19
 *
20
 * BUGS:
21
 *	64x64x2 cursor always used;
22
 *	no support for interlaced mode.
23
 */
24
enum {
25
	AddrW		= 0x00,		/* Address register; palette/cursor RAM write */
26
	Palette		= 0x01,		/* 6/8-bit color palette data */
27
	Pmask		= 0x02,		/* Pixel mask register */
28
	AddrR		= 0x03,		/* Address register; palette/cursor RAM read */
29
	ColorW		= 0x04,		/* Address register; cursor/overscan color write */
30
	Color		= 0x05,		/* Cursor/overscan color data */
31
	Cmd0		= 0x06,		/* Command register 0 */
32
	ColorR		= 0x07,		/* Address register; cursor/overscan color read */
33
	Cmd1		= 0x08,		/* Command register 1 */
34
	Cmd2		= 0x09,		/* Command register 2 */
35
	Status		= 0x0A,		/* Status */
36
	Cmd3		= 0x1A,		/* Command register 3 */
37
	Cram		= 0x0B,		/* Cursor RAM array data */
38
	Cxlr		= 0x0C,		/* Cursor x-low register */
39
	Cxhr		= 0x0D,		/* Cursor x-high register */
40
	Cylr		= 0x0E,		/* Cursor y-low register */
41
	Cyhr		= 0x0F,		/* Cursor y-high register */
42
 
43
	Nreg		= 0x10,
44
};
45
 
46
/*
47
 * Lower 2-bits of indirect DAC register
48
 * addressing.
49
 */
50
static ushort dacxreg[4] = {
51
	PaddrW, Pdata, Pixmask, PaddrR
52
};
53
 
54
static uchar
55
bt485io(uchar reg)
56
{
57
	uchar crt55, cr0;
58
 
59
	crt55 = vgaxi(Crtx, 0x55) & 0xFC;
60
	if((reg & 0x0F) == Status){
61
		/*
62
		 * 1,2: Set indirect addressing for Status or
63
		 *      Cmd3 - set bit7 of Cr0.
64
		 */
65
		vgaxo(Crtx, 0x55, crt55|((Cmd0>>2) & 0x03));
66
		cr0 = vgai(dacxreg[Cmd0 & 0x03])|0x80;
67
		vgao(dacxreg[Cmd0 & 0x03], cr0);
68
 
69
		/*
70
		 * 3,4: Set the index into the Write register,
71
		 *      index == 0x00 for Status, 0x01 for Cmd3.
72
		 */
73
		vgaxo(Crtx, 0x55, crt55|((AddrW>>2) & 0x03));
74
		vgao(dacxreg[AddrW & 0x03], (reg == Status) ? 0x00: 0x01);
75
 
76
		/*
77
		 * 5,6: Get the contents of the appropriate
78
		 *      register at 0x0A.
79
		 */
80
	}
81
 
82
	return crt55;
83
}
84
 
85
static uchar
86
bt485i(uchar reg)
87
{
88
	uchar crt55, r;
89
 
90
	crt55 = bt485io(reg);
91
	vgaxo(Crtx, 0x55, crt55|((reg>>2) & 0x03));
92
	r = vgai(dacxreg[reg & 0x03]);
93
	vgaxo(Crtx, 0x55, crt55);
94
 
95
	return r;
96
}
97
 
98
static void
99
bt485o(uchar reg, uchar data)
100
{
101
	uchar crt55;
102
 
103
	crt55 = bt485io(reg);
104
	vgaxo(Crtx, 0x55, crt55|((reg>>2) & 0x03));
105
	vgao(dacxreg[reg & 0x03], data);
106
	vgaxo(Crtx, 0x55, crt55);
107
}
108
 
109
static void
110
bt485disable(VGAscr*)
111
{
112
	uchar r;
113
 
114
	/*
115
	 * Disable 
116
	 *	cursor mode 3;
117
	 *	cursor control enable for Bt485 DAC;
118
	 *	the hardware cursor external operation mode.
119
	 */
120
	r = bt485i(Cmd2) & ~0x03;
121
	bt485o(Cmd2, r);
122
 
123
	r = vgaxi(Crtx, 0x45) & ~0x20;
124
	vgaxo(Crtx, 0x45, r);
125
 
126
	r = vgaxi(Crtx, 0x55) & ~0x20;
127
	vgaxo(Crtx, 0x55, r);
128
}
129
 
130
static void
131
bt485enable(VGAscr*)
132
{
133
	uchar r;
134
 
135
	/*
136
	 * Turn cursor off.
137
	 */
138
	r = bt485i(Cmd2) & 0xFC;
139
	bt485o(Cmd2, r);
140
 
141
	/*
142
	 * Overscan colour,
143
	 * cursor colour 1 (white),
144
	 * cursor colour 2, 3 (black).
145
	 */
146
	bt485o(ColorW, 0x00);
147
	bt485o(Color, Pwhite); bt485o(Color, Pwhite); bt485o(Color, Pwhite);
148
 
149
	bt485o(Color, Pwhite); bt485o(Color, Pwhite); bt485o(Color, Pwhite);
150
 
151
	bt485o(Color, Pblack); bt485o(Color, Pblack); bt485o(Color, Pblack);
152
	bt485o(Color, Pblack); bt485o(Color, Pblack); bt485o(Color, Pblack);
153
 
154
	/*
155
	 * Finally, enable
156
	 *	the hardware cursor external operation mode;
157
	 *	cursor control enable for Bt485 DAC.
158
	 * The #9GXE cards seem to need the 86C928 Bt485 support
159
	 * enabled in order to work at all in enhanced mode.
160
	 */
161
 
162
	r = vgaxi(Crtx, 0x55)|0x20;
163
	vgaxo(Crtx, 0x55, r);
164
 
165
	r = vgaxi(Crtx, 0x45)|0x20;
166
	vgaxo(Crtx, 0x45, r);
167
}
168
 
169
static void
170
bt485load(VGAscr* scr, Cursor* curs)
171
{
172
	uchar r;
173
	int x, y;
174
 
175
	/*
176
	 * Turn cursor off;
177
	 * put cursor into 64x64x2 mode and clear MSBs of address;
178
	 * clear LSBs of address;
179
	 */
180
	r = bt485i(Cmd2) & 0xFC;
181
	bt485o(Cmd2, r);
182
 
183
	r = (bt485i(Cmd3) & 0xFC)|0x04;
184
	bt485o(Cmd3, r);
185
 
186
	bt485o(AddrW, 0x00);
187
 
188
	/*
189
	 * Now load the cursor RAM array, both planes.
190
	 * The cursor is 16x16, the array 64x64; put
191
	 * the cursor in the top left. The 0,0 cursor
192
	 * point is bottom-right, so positioning will
193
	 * have to take that into account.
194
	 */
195
	for(y = 0; y < 64; y++){
196
		for(x = 0; x < 64/8; x++){
197
			if(x < 16/8 && y < 16)
198
				bt485o(Cram, curs->clr[x+y*2]);
199
			else
200
				bt485o(Cram, 0x00);
201
		}
202
	}
203
	for(y = 0; y < 64; y++){
204
		for(x = 0; x < 64/8; x++){
205
			if(x < 16/8 && y < 16)
206
				bt485o(Cram, curs->set[x+y*2]);
207
			else
208
				bt485o(Cram, 0x00);
209
		}
210
	}
211
 
212
	/*
213
	 * Initialise the cursor hot-point
214
	 * and enable the cursor.
215
	 */
216
	scr->offset.x = 64+curs->offset.x;
217
	scr->offset.y = 64+curs->offset.y;
218
 
219
	r = (bt485i(Cmd2) & 0xFC)|0x01;
220
	bt485o(Cmd2, r);
221
}
222
 
223
static int
224
bt485move(VGAscr* scr, Point p)
225
{
226
	int x, y;
227
 
228
	x = p.x+scr->offset.x;
229
	y = p.y+scr->offset.y;
230
 
231
	bt485o(Cxlr, x & 0xFF);
232
	bt485o(Cxhr, (x>>8) & 0x0F);
233
	bt485o(Cylr, y & 0xFF);
234
	bt485o(Cyhr, (y>>8) & 0x0F);
235
 
236
	return 0;
237
}
238
 
239
VGAcur vgabt485cur = {
240
	"bt485hwgc",
241
 
242
	bt485enable,
243
	bt485disable,
244
	bt485load,
245
	bt485move,
246
};