scvtb.c revision 48190
1/*-
2 * $Id: scvtbpc98.c,v 1.1 1999/06/24 10:51:34 kato Exp $
3 */
4
5#include "sc.h"
6#include "opt_syscons.h"
7
8#if NSC > 0
9
10#include <sys/param.h>
11#include <sys/systm.h>
12#include <sys/kernel.h>
13#include <sys/malloc.h>
14
15#include <machine/console.h>
16#include <machine/md_var.h>
17
18#include <dev/fb/fbreg.h>
19#include <dev/syscons/syscons.h>
20
21#define ATTR_OFFSET	0x2000
22
23#define vtb_wrap(vtb, at, offset)				\
24    (((at) + (offset) + (vtb)->vtb_size)%(vtb)->vtb_size)
25
26static u_int16_t	at2pc98(u_int16_t attr);
27static vm_offset_t	sc_vtb_attr_pointer(sc_vtb_t *vtb, int at);
28
29static u_int16_t
30at2pc98(u_int16_t attr)
31{
32	static u_char ibmpc_to_pc98[16] = {
33		0x01, 0x21, 0x81, 0xa1, 0x41, 0x61, 0xc1, 0xe1,
34		0x09, 0x29, 0x89, 0xa9, 0x49, 0x69, 0xc9, 0xe9
35	};
36	static u_char ibmpc_to_pc98rev[16] = {
37		0x05, 0x25, 0x85, 0xa5, 0x45, 0x65, 0xc5, 0xe5,
38		0x0d, 0x2d, 0x8d, 0xad, 0x4d, 0x6d, 0xcd, 0xed
39	};
40	u_char fg_at, bg_at;
41	u_int16_t at;
42
43	if (attr & 0x00FF)
44		return (attr);
45
46	fg_at = ((attr >> 8) & 0x0F);
47	bg_at = ((attr >> 12) & 0x0F);
48
49	if (bg_at) {
50		if (bg_at & 0x08) {
51			if (bg_at & 0x07) {
52				/* reverse & blink */
53				at = ibmpc_to_pc98rev[bg_at] | 0x02;
54			} else {
55				/* normal & blink */
56				at = ibmpc_to_pc98[fg_at] | 0x02;
57			}
58		} else {
59			/* reverse */
60			at = ibmpc_to_pc98rev[bg_at];
61		}
62	} else {
63		/* normal */
64		at = ibmpc_to_pc98[fg_at];
65	}
66	at |= attr;
67	return (at);
68}
69
70void
71sc_vtb_init(sc_vtb_t *vtb, int type, int cols, int rows, void *buf, int wait)
72{
73	vtb->vtb_flags = 0;
74	vtb->vtb_type = type;
75	vtb->vtb_cols = cols;
76	vtb->vtb_rows = rows;
77	vtb->vtb_size = cols*rows;
78	vtb->vtb_buffer = NULL;
79	vtb->vtb_tail = 0;
80
81	switch (type) {
82	case VTB_MEMORY:
83	case VTB_RINGBUFFER:
84		if ((buf == NULL) && (cols*rows != 0)) {
85			vtb->vtb_buffer =
86				(vm_offset_t)malloc(cols*rows*sizeof(u_int16_t)*2,
87						    M_DEVBUF,
88						    (wait) ? M_WAITOK : M_NOWAIT);
89			if (vtb->vtb_buffer != NULL) {
90				bzero((void *)sc_vtb_pointer(vtb, 0),
91				      cols*rows*sizeof(u_int16_t)*2);
92			}
93		} else {
94			vtb->vtb_buffer = (vm_offset_t)buf;
95		}
96		vtb->vtb_flags |= VTB_VALID;
97		break;
98	case VTB_FRAMEBUFFER:
99		vtb->vtb_buffer = (vm_offset_t)buf;
100		vtb->vtb_flags |= VTB_VALID;
101		break;
102	default:
103		break;
104	}
105}
106
107void
108sc_vtb_destroy(sc_vtb_t *vtb)
109{
110	vm_offset_t p;
111
112	vtb->vtb_flags = 0;
113	vtb->vtb_cols = 0;
114	vtb->vtb_rows = 0;
115	vtb->vtb_size = 0;
116	vtb->vtb_tail = 0;
117
118	p = vtb->vtb_buffer;
119	vtb->vtb_buffer = NULL;
120	switch (vtb->vtb_type) {
121	case VTB_MEMORY:
122	case VTB_RINGBUFFER:
123		if (p != NULL)
124			free((void *)p, M_DEVBUF);
125		break;
126	default:
127		break;
128	}
129	vtb->vtb_type = VTB_INVALID;
130}
131
132size_t
133sc_vtb_size(int cols, int rows)
134{
135	return (size_t)(cols*rows*sizeof(u_int16_t)*2);
136}
137
138int
139sc_vtb_getc(sc_vtb_t *vtb, int at)
140{
141	if (vtb->vtb_type == VTB_FRAMEBUFFER)
142		return (readw(sc_vtb_pointer(vtb, at)) & 0x00ff);
143	else
144		return (*(u_int16_t *)sc_vtb_pointer(vtb, at) & 0x00ff);
145}
146
147int
148sc_vtb_geta(sc_vtb_t *vtb, int at)
149{
150	if (vtb->vtb_type == VTB_FRAMEBUFFER)
151		return (readw(sc_vtb_attr_pointer(vtb, at)) & 0x00ff);
152	else
153		return (*(u_int16_t *)sc_vtb_attr_pointer(vtb, at) & 0x00ff);
154}
155
156void
157sc_vtb_putc(sc_vtb_t *vtb, int at, int c, int a)
158{
159	if (vtb->vtb_type == VTB_FRAMEBUFFER) {
160		writew(sc_vtb_pointer(vtb, at), c);
161		writew(sc_vtb_attr_pointer(vtb, at), at2pc98(a));
162	} else {
163		*(u_int16_t *)sc_vtb_pointer(vtb, at) = c;
164		*(u_int16_t *)sc_vtb_attr_pointer(vtb, at) = at2pc98(a);
165	}
166}
167
168vm_offset_t
169sc_vtb_putchar(sc_vtb_t *vtb, vm_offset_t p, int c, int a)
170{
171	if (vtb->vtb_type == VTB_FRAMEBUFFER) {
172		writew(p, c);
173		writew(p + ATTR_OFFSET, at2pc98(a));
174	} else {
175		*(u_int16_t *)p = c;
176		*(u_int16_t *)(p + vtb->vtb_size*sizeof(u_int16_t)) = at2pc98(a);
177	}
178	return (p + sizeof(u_int16_t));
179}
180
181vm_offset_t
182sc_vtb_pointer(sc_vtb_t *vtb, int at)
183{
184	return (vtb->vtb_buffer + sizeof(u_int16_t)*(at));
185}
186
187static vm_offset_t
188sc_vtb_attr_pointer(sc_vtb_t *vtb, int at)
189{
190	return (vtb->vtb_buffer + sizeof(u_int16_t)*(at)
191		+ ((vtb->vtb_type == VTB_FRAMEBUFFER) ?
192			ATTR_OFFSET : vtb->vtb_size*sizeof(u_int16_t)));
193}
194
195int
196sc_vtb_pos(sc_vtb_t *vtb, int pos, int offset)
197{
198	return ((pos + offset + vtb->vtb_size)%vtb->vtb_size);
199}
200
201void
202sc_vtb_clear(sc_vtb_t *vtb, int c, int attr)
203{
204	if (vtb->vtb_type == VTB_FRAMEBUFFER) {
205		fillw_io(c, sc_vtb_pointer(vtb, 0), vtb->vtb_size);
206		fillw_io(at2pc98(attr), sc_vtb_attr_pointer(vtb, 0), vtb->vtb_size);
207	} else {
208		fillw(c, (void *)sc_vtb_pointer(vtb, 0), vtb->vtb_size);
209		fillw(at2pc98(attr), (void *)sc_vtb_attr_pointer(vtb, 0), vtb->vtb_size);
210	}
211}
212
213void
214sc_vtb_copy(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int to, int count)
215{
216	if (vtb2->vtb_type == VTB_FRAMEBUFFER) {
217		bcopy_toio(sc_vtb_pointer(vtb1, from),
218			   sc_vtb_pointer(vtb2, to),
219			   count*sizeof(u_int16_t));
220		bcopy_toio(sc_vtb_attr_pointer(vtb1, from),
221			   sc_vtb_attr_pointer(vtb2, to),
222			   count*sizeof(u_int16_t));
223	} else if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
224		bcopy_fromio(sc_vtb_pointer(vtb1, from),
225			     sc_vtb_pointer(vtb2, to),
226			     count*sizeof(u_int16_t));
227		bcopy_fromio(sc_vtb_attr_pointer(vtb1, from),
228			     sc_vtb_attr_pointer(vtb2, to),
229			     count*sizeof(u_int16_t));
230	} else {
231		bcopy((void *)sc_vtb_pointer(vtb1, from),
232		      (void *)sc_vtb_pointer(vtb2, to),
233		      count*sizeof(u_int16_t));
234		bcopy((void *)sc_vtb_attr_pointer(vtb1, from),
235		      (void *)sc_vtb_attr_pointer(vtb2, to),
236		      count*sizeof(u_int16_t));
237	}
238}
239
240void
241sc_vtb_append(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int count)
242{
243	int len;
244
245	if (vtb2->vtb_type != VTB_RINGBUFFER)
246		return;
247
248	while (count > 0) {
249		len = imin(count, vtb2->vtb_size - vtb2->vtb_tail);
250		if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
251			bcopy_fromio(sc_vtb_pointer(vtb1, from),
252				     sc_vtb_pointer(vtb2, vtb2->vtb_tail),
253				     len*sizeof(u_int16_t));
254			bcopy_fromio(sc_vtb_attr_pointer(vtb1, from),
255				     sc_vtb_attr_pointer(vtb2, vtb2->vtb_tail),
256				     len*sizeof(u_int16_t));
257		} else {
258			bcopy((void *)sc_vtb_pointer(vtb1, from),
259			      (void *)sc_vtb_pointer(vtb2, vtb2->vtb_tail),
260			      len*sizeof(u_int16_t));
261			bcopy((void *)sc_vtb_attr_pointer(vtb1, from),
262			      (void *)sc_vtb_attr_pointer(vtb2, vtb2->vtb_tail),
263			      len*sizeof(u_int16_t));
264		}
265		from += len;
266		count -= len;
267		vtb2->vtb_tail = vtb_wrap(vtb2, vtb2->vtb_tail, len);
268	}
269}
270
271void
272sc_vtb_seek(sc_vtb_t *vtb, int pos)
273{
274	vtb->vtb_tail = pos%vtb->vtb_size;
275}
276
277void
278sc_vtb_erase(sc_vtb_t *vtb, int at, int count, int c, int attr)
279{
280	if (at + count > vtb->vtb_size)
281		count = vtb->vtb_size - at;
282	if (vtb->vtb_type == VTB_FRAMEBUFFER) {
283		fillw_io(c, sc_vtb_pointer(vtb, at), count);
284		fillw_io(at2pc98(attr), sc_vtb_attr_pointer(vtb, at), count);
285	} else {
286		fillw(c, (void *)sc_vtb_pointer(vtb, at), count);
287		fillw(at2pc98(attr), (void *)sc_vtb_attr_pointer(vtb, at), count);
288	}
289}
290
291void
292sc_vtb_move(sc_vtb_t *vtb, int from, int to, int count)
293{
294	if (from + count > vtb->vtb_size)
295		count = vtb->vtb_size - from;
296	if (to + count > vtb->vtb_size)
297		count = vtb->vtb_size - to;
298	if (count <= 0)
299		return;
300	if (vtb->vtb_type == VTB_FRAMEBUFFER) {
301		bcopy_io(sc_vtb_pointer(vtb, from),
302			 sc_vtb_pointer(vtb, to), count*sizeof(u_int16_t));
303		bcopy_io(sc_vtb_attr_pointer(vtb, from),
304			 sc_vtb_attr_pointer(vtb, to), count*sizeof(u_int16_t));
305	} else {
306		bcopy((void *)sc_vtb_pointer(vtb, from),
307		      (void *)sc_vtb_pointer(vtb, to), count*sizeof(u_int16_t));
308		bcopy((void *)sc_vtb_attr_pointer(vtb, from),
309		      (void *)sc_vtb_attr_pointer(vtb, to), count*sizeof(u_int16_t));
310	}
311}
312
313void
314sc_vtb_delete(sc_vtb_t *vtb, int at, int count, int c, int attr)
315{
316	int len;
317
318	if (at + count > vtb->vtb_size)
319		count = vtb->vtb_size - at;
320	len = vtb->vtb_size - at - count;
321	if (len > 0) {
322		if (vtb->vtb_type == VTB_FRAMEBUFFER) {
323			bcopy_io(sc_vtb_pointer(vtb, at + count),
324				 sc_vtb_pointer(vtb, at),
325				 len*sizeof(u_int16_t));
326			bcopy_io(sc_vtb_attr_pointer(vtb, at + count),
327				 sc_vtb_attr_pointer(vtb, at),
328				 len*sizeof(u_int16_t));
329		} else {
330			bcopy((void *)sc_vtb_pointer(vtb, at + count),
331			      (void *)sc_vtb_pointer(vtb, at),
332			      len*sizeof(u_int16_t));
333			bcopy((void *)sc_vtb_attr_pointer(vtb, at + count),
334			      (void *)sc_vtb_attr_pointer(vtb, at),
335			      len*sizeof(u_int16_t));
336		}
337	}
338	if (vtb->vtb_type == VTB_FRAMEBUFFER) {
339		fillw_io(c, sc_vtb_pointer(vtb, at + len),
340			 vtb->vtb_size - at - len);
341		fillw_io(at2pc98(attr),
342			 sc_vtb_attr_pointer(vtb, at + len),
343			 vtb->vtb_size - at - len);
344	} else {
345		fillw(c, (void *)sc_vtb_pointer(vtb, at + len),
346		      vtb->vtb_size - at - len);
347		fillw(at2pc98(attr),
348		      (void *)sc_vtb_attr_pointer(vtb, at + len),
349		      vtb->vtb_size - at - len);
350	}
351}
352
353void
354sc_vtb_ins(sc_vtb_t *vtb, int at, int count, int c, int attr)
355{
356	if (at + count > vtb->vtb_size) {
357		count = vtb->vtb_size - at;
358	} else {
359		if (vtb->vtb_type == VTB_FRAMEBUFFER) {
360			bcopy_io(sc_vtb_pointer(vtb, at),
361				 sc_vtb_pointer(vtb, at + count),
362				 (vtb->vtb_size - at - count)*sizeof(u_int16_t));
363			bcopy_io(sc_vtb_attr_pointer(vtb, at),
364				 sc_vtb_attr_pointer(vtb, at + count),
365				 (vtb->vtb_size - at - count)*sizeof(u_int16_t));
366		} else {
367			bcopy((void *)sc_vtb_pointer(vtb, at),
368			      (void *)sc_vtb_pointer(vtb, at + count),
369			      (vtb->vtb_size - at - count)*sizeof(u_int16_t));
370			bcopy((void *)sc_vtb_attr_pointer(vtb, at),
371			      (void *)sc_vtb_attr_pointer(vtb, at + count),
372			      (vtb->vtb_size - at - count)*sizeof(u_int16_t));
373		}
374	}
375	if (vtb->vtb_type == VTB_FRAMEBUFFER) {
376		fillw_io(c, sc_vtb_pointer(vtb, at), count);
377		fillw_io(at2pc98(attr),
378			 sc_vtb_attr_pointer(vtb, at), count);
379	} else {
380		fillw(c, (void *)sc_vtb_pointer(vtb, at), count);
381		fillw(at2pc98(attr),
382		      (void *)sc_vtb_attr_pointer(vtb, at), count);
383	}
384}
385
386#endif /* NSC */
387