]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/pc98/pc98/scvtbpc98.c
$Id$ -> $FreeBSD$
[FreeBSD/FreeBSD.git] / sys / pc98 / pc98 / scvtbpc98.c
1 /*-
2  * Copyright (c) 1999 FreeBSD(98) Porting Team.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer as
10  *    the first lines of this file unmodified.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
16  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18  * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  */
28
29 #include "sc.h"
30 #include "opt_syscons.h"
31
32 #if NSC > 0
33
34 #include <sys/param.h>
35 #include <sys/systm.h>
36 #include <sys/kernel.h>
37 #include <sys/malloc.h>
38
39 #include <machine/console.h>
40 #include <machine/md_var.h>
41
42 #include <dev/fb/fbreg.h>
43 #include <dev/syscons/syscons.h>
44
45 #define ATTR_OFFSET     0x2000
46
47 #define vtb_wrap(vtb, at, offset)                               \
48     (((at) + (offset) + (vtb)->vtb_size)%(vtb)->vtb_size)
49
50 static u_int16_t        at2pc98(u_int16_t attr);
51 static vm_offset_t      sc_vtb_attr_pointer(sc_vtb_t *vtb, int at);
52
53 static u_int16_t
54 at2pc98(u_int16_t attr)
55 {
56         static u_char ibmpc_to_pc98[16] = {
57                 0x01, 0x21, 0x81, 0xa1, 0x41, 0x61, 0xc1, 0xe1, 
58                 0x09, 0x29, 0x89, 0xa9, 0x49, 0x69, 0xc9, 0xe9
59         };
60         static u_char ibmpc_to_pc98rev[16] = {
61                 0x05, 0x25, 0x85, 0xa5, 0x45, 0x65, 0xc5, 0xe5, 
62                 0x0d, 0x2d, 0x8d, 0xad, 0x4d, 0x6d, 0xcd, 0xed
63         };
64         u_char fg_at, bg_at;
65         u_int16_t at;
66
67         if (attr & 0x00FF)
68                 return (attr);
69
70         fg_at = ((attr >> 8) & 0x0F);
71         bg_at = ((attr >> 12) & 0x0F);
72
73         if (bg_at) {
74                 if (bg_at & 0x08) {
75                         if (bg_at & 0x07) {
76                                 /* reverse & blink */
77                                 at = ibmpc_to_pc98rev[bg_at] | 0x02;
78                         } else {
79                                 /* normal & blink */
80                                 at = ibmpc_to_pc98[fg_at] | 0x02;
81                         }
82                 } else {
83                         /* reverse */
84                         at = ibmpc_to_pc98rev[bg_at];
85                 }
86         } else {
87                 /* normal */
88                 at = ibmpc_to_pc98[fg_at];
89         }
90         at |= attr;
91         return (at);
92 }
93
94 void
95 sc_vtb_init(sc_vtb_t *vtb, int type, int cols, int rows, void *buf, int wait)
96 {
97         vtb->vtb_flags = 0;
98         vtb->vtb_type = type;
99         vtb->vtb_cols = cols;
100         vtb->vtb_rows = rows;
101         vtb->vtb_size = cols*rows;
102         vtb->vtb_buffer = NULL;
103         vtb->vtb_tail = 0;
104
105         switch (type) {
106         case VTB_MEMORY:
107         case VTB_RINGBUFFER:
108                 if ((buf == NULL) && (cols*rows != 0)) {
109                         vtb->vtb_buffer =
110                                 (vm_offset_t)malloc(cols*rows*sizeof(u_int16_t)*2,
111                                                     M_DEVBUF, 
112                                                     (wait) ? M_WAITOK : M_NOWAIT);
113                         if (vtb->vtb_buffer != NULL) {
114                                 bzero((void *)sc_vtb_pointer(vtb, 0),
115                                       cols*rows*sizeof(u_int16_t)*2);
116                         }
117                 } else {
118                         vtb->vtb_buffer = (vm_offset_t)buf;
119                 }
120                 vtb->vtb_flags |= VTB_VALID;
121                 break;
122         case VTB_FRAMEBUFFER:
123                 vtb->vtb_buffer = (vm_offset_t)buf;
124                 vtb->vtb_flags |= VTB_VALID;
125                 break;
126         default:
127                 break;
128         }
129 }
130
131 void
132 sc_vtb_destroy(sc_vtb_t *vtb)
133 {
134         vm_offset_t p;
135
136         vtb->vtb_flags = 0;
137         vtb->vtb_cols = 0;
138         vtb->vtb_rows = 0;
139         vtb->vtb_size = 0;
140         vtb->vtb_tail = 0;
141
142         p = vtb->vtb_buffer;
143         vtb->vtb_buffer = NULL;
144         switch (vtb->vtb_type) {
145         case VTB_MEMORY:
146         case VTB_RINGBUFFER:
147                 if (p != NULL)
148                         free((void *)p, M_DEVBUF);
149                 break;
150         default:
151                 break;
152         }
153         vtb->vtb_type = VTB_INVALID;
154 }
155
156 size_t
157 sc_vtb_size(int cols, int rows)
158 {
159         return (size_t)(cols*rows*sizeof(u_int16_t)*2);
160 }
161
162 int
163 sc_vtb_getc(sc_vtb_t *vtb, int at)
164 {
165         if (vtb->vtb_type == VTB_FRAMEBUFFER)
166                 return (readw(sc_vtb_pointer(vtb, at)) & 0x00ff);
167         else
168                 return (*(u_int16_t *)sc_vtb_pointer(vtb, at) & 0x00ff);
169 }
170
171 int
172 sc_vtb_geta(sc_vtb_t *vtb, int at)
173 {
174         if (vtb->vtb_type == VTB_FRAMEBUFFER)
175                 return (readw(sc_vtb_attr_pointer(vtb, at)) & 0x00ff);
176         else
177                 return (*(u_int16_t *)sc_vtb_attr_pointer(vtb, at) & 0x00ff);
178 }
179
180 void
181 sc_vtb_putc(sc_vtb_t *vtb, int at, int c, int a)
182 {
183         if (vtb->vtb_type == VTB_FRAMEBUFFER) {
184                 writew(sc_vtb_pointer(vtb, at), c);
185                 writew(sc_vtb_attr_pointer(vtb, at), at2pc98(a));
186         } else {
187                 *(u_int16_t *)sc_vtb_pointer(vtb, at) = c;
188                 *(u_int16_t *)sc_vtb_attr_pointer(vtb, at) = at2pc98(a);
189         }
190 }
191
192 vm_offset_t
193 sc_vtb_putchar(sc_vtb_t *vtb, vm_offset_t p, int c, int a)
194 {
195         if (vtb->vtb_type == VTB_FRAMEBUFFER) {
196                 writew(p, c);
197                 writew(p + ATTR_OFFSET, at2pc98(a));
198         } else {
199                 *(u_int16_t *)p = c;
200                 *(u_int16_t *)(p + vtb->vtb_size*sizeof(u_int16_t)) = at2pc98(a);
201         }
202         return (p + sizeof(u_int16_t));
203 }
204
205 vm_offset_t
206 sc_vtb_pointer(sc_vtb_t *vtb, int at)
207 {
208         return (vtb->vtb_buffer + sizeof(u_int16_t)*(at));
209 }
210
211 static vm_offset_t
212 sc_vtb_attr_pointer(sc_vtb_t *vtb, int at)
213 {
214         return (vtb->vtb_buffer + sizeof(u_int16_t)*(at)
215                 + ((vtb->vtb_type == VTB_FRAMEBUFFER) ? 
216                         ATTR_OFFSET : vtb->vtb_size*sizeof(u_int16_t)));
217 }
218
219 int
220 sc_vtb_pos(sc_vtb_t *vtb, int pos, int offset)
221 {
222         return ((pos + offset + vtb->vtb_size)%vtb->vtb_size);
223 }
224
225 void
226 sc_vtb_clear(sc_vtb_t *vtb, int c, int attr)
227 {
228         if (vtb->vtb_type == VTB_FRAMEBUFFER) {
229                 fillw_io(c, sc_vtb_pointer(vtb, 0), vtb->vtb_size);
230                 fillw_io(at2pc98(attr), sc_vtb_attr_pointer(vtb, 0), vtb->vtb_size);
231         } else {
232                 fillw(c, (void *)sc_vtb_pointer(vtb, 0), vtb->vtb_size);
233                 fillw(at2pc98(attr), (void *)sc_vtb_attr_pointer(vtb, 0), vtb->vtb_size);
234         }
235 }
236
237 void
238 sc_vtb_copy(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int to, int count)
239 {
240         if (vtb2->vtb_type == VTB_FRAMEBUFFER) {
241                 bcopy_toio(sc_vtb_pointer(vtb1, from),
242                            sc_vtb_pointer(vtb2, to),
243                            count*sizeof(u_int16_t));
244                 bcopy_toio(sc_vtb_attr_pointer(vtb1, from),
245                            sc_vtb_attr_pointer(vtb2, to),
246                            count*sizeof(u_int16_t));
247         } else if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
248                 bcopy_fromio(sc_vtb_pointer(vtb1, from),
249                              sc_vtb_pointer(vtb2, to),
250                              count*sizeof(u_int16_t));
251                 bcopy_fromio(sc_vtb_attr_pointer(vtb1, from),
252                              sc_vtb_attr_pointer(vtb2, to),
253                              count*sizeof(u_int16_t));
254         } else {
255                 bcopy((void *)sc_vtb_pointer(vtb1, from),
256                       (void *)sc_vtb_pointer(vtb2, to),
257                       count*sizeof(u_int16_t));
258                 bcopy((void *)sc_vtb_attr_pointer(vtb1, from),
259                       (void *)sc_vtb_attr_pointer(vtb2, to),
260                       count*sizeof(u_int16_t));
261         }
262 }
263
264 void
265 sc_vtb_append(sc_vtb_t *vtb1, int from, sc_vtb_t *vtb2, int count)
266 {
267         int len;
268
269         if (vtb2->vtb_type != VTB_RINGBUFFER)
270                 return;
271
272         while (count > 0) {
273                 len = imin(count, vtb2->vtb_size - vtb2->vtb_tail);
274                 if (vtb1->vtb_type == VTB_FRAMEBUFFER) {
275                         bcopy_fromio(sc_vtb_pointer(vtb1, from),
276                                      sc_vtb_pointer(vtb2, vtb2->vtb_tail),
277                                      len*sizeof(u_int16_t));
278                         bcopy_fromio(sc_vtb_attr_pointer(vtb1, from),
279                                      sc_vtb_attr_pointer(vtb2, vtb2->vtb_tail),
280                                      len*sizeof(u_int16_t));
281                 } else {
282                         bcopy((void *)sc_vtb_pointer(vtb1, from),
283                               (void *)sc_vtb_pointer(vtb2, vtb2->vtb_tail),
284                               len*sizeof(u_int16_t));
285                         bcopy((void *)sc_vtb_attr_pointer(vtb1, from),
286                               (void *)sc_vtb_attr_pointer(vtb2, vtb2->vtb_tail),
287                               len*sizeof(u_int16_t));
288                 }
289                 from += len;
290                 count -= len;
291                 vtb2->vtb_tail = vtb_wrap(vtb2, vtb2->vtb_tail, len);
292         }
293 }
294
295 void
296 sc_vtb_seek(sc_vtb_t *vtb, int pos)
297 {
298         vtb->vtb_tail = pos%vtb->vtb_size;
299 }
300
301 void
302 sc_vtb_erase(sc_vtb_t *vtb, int at, int count, int c, int attr)
303 {
304         if (at + count > vtb->vtb_size)
305                 count = vtb->vtb_size - at;
306         if (vtb->vtb_type == VTB_FRAMEBUFFER) {
307                 fillw_io(c, sc_vtb_pointer(vtb, at), count);
308                 fillw_io(at2pc98(attr), sc_vtb_attr_pointer(vtb, at), count);
309         } else {
310                 fillw(c, (void *)sc_vtb_pointer(vtb, at), count);
311                 fillw(at2pc98(attr), (void *)sc_vtb_attr_pointer(vtb, at), count);
312         }
313 }
314
315 void
316 sc_vtb_move(sc_vtb_t *vtb, int from, int to, int count)
317 {
318         if (from + count > vtb->vtb_size)
319                 count = vtb->vtb_size - from;
320         if (to + count > vtb->vtb_size)
321                 count = vtb->vtb_size - to;
322         if (count <= 0)
323                 return;
324         if (vtb->vtb_type == VTB_FRAMEBUFFER) {
325                 bcopy_io(sc_vtb_pointer(vtb, from),
326                          sc_vtb_pointer(vtb, to), count*sizeof(u_int16_t)); 
327                 bcopy_io(sc_vtb_attr_pointer(vtb, from),
328                          sc_vtb_attr_pointer(vtb, to), count*sizeof(u_int16_t));
329         } else {
330                 bcopy((void *)sc_vtb_pointer(vtb, from),
331                       (void *)sc_vtb_pointer(vtb, to), count*sizeof(u_int16_t));
332                 bcopy((void *)sc_vtb_attr_pointer(vtb, from),
333                       (void *)sc_vtb_attr_pointer(vtb, to), count*sizeof(u_int16_t));
334         }
335 }
336
337 void
338 sc_vtb_delete(sc_vtb_t *vtb, int at, int count, int c, int attr)
339 {
340         int len;
341
342         if (at + count > vtb->vtb_size)
343                 count = vtb->vtb_size - at;
344         len = vtb->vtb_size - at - count;
345         if (len > 0) {
346                 if (vtb->vtb_type == VTB_FRAMEBUFFER) {
347                         bcopy_io(sc_vtb_pointer(vtb, at + count),
348                                  sc_vtb_pointer(vtb, at),
349                                  len*sizeof(u_int16_t)); 
350                         bcopy_io(sc_vtb_attr_pointer(vtb, at + count),
351                                  sc_vtb_attr_pointer(vtb, at),
352                                  len*sizeof(u_int16_t)); 
353                 } else {
354                         bcopy((void *)sc_vtb_pointer(vtb, at + count),
355                               (void *)sc_vtb_pointer(vtb, at),
356                               len*sizeof(u_int16_t)); 
357                         bcopy((void *)sc_vtb_attr_pointer(vtb, at + count),
358                               (void *)sc_vtb_attr_pointer(vtb, at),
359                               len*sizeof(u_int16_t)); 
360                 }
361         }
362         if (vtb->vtb_type == VTB_FRAMEBUFFER) {
363                 fillw_io(c, sc_vtb_pointer(vtb, at + len),
364                          vtb->vtb_size - at - len);
365                 fillw_io(at2pc98(attr),
366                          sc_vtb_attr_pointer(vtb, at + len),
367                          vtb->vtb_size - at - len);
368         } else {
369                 fillw(c, (void *)sc_vtb_pointer(vtb, at + len),
370                       vtb->vtb_size - at - len);
371                 fillw(at2pc98(attr),
372                       (void *)sc_vtb_attr_pointer(vtb, at + len),
373                       vtb->vtb_size - at - len);
374         }
375 }
376
377 void
378 sc_vtb_ins(sc_vtb_t *vtb, int at, int count, int c, int attr)
379 {
380         if (at + count > vtb->vtb_size) {
381                 count = vtb->vtb_size - at;
382         } else {
383                 if (vtb->vtb_type == VTB_FRAMEBUFFER) {
384                         bcopy_io(sc_vtb_pointer(vtb, at),
385                                  sc_vtb_pointer(vtb, at + count),
386                                  (vtb->vtb_size - at - count)*sizeof(u_int16_t)); 
387                         bcopy_io(sc_vtb_attr_pointer(vtb, at),
388                                  sc_vtb_attr_pointer(vtb, at + count),
389                                  (vtb->vtb_size - at - count)*sizeof(u_int16_t)); 
390                 } else {
391                         bcopy((void *)sc_vtb_pointer(vtb, at),
392                               (void *)sc_vtb_pointer(vtb, at + count),
393                               (vtb->vtb_size - at - count)*sizeof(u_int16_t)); 
394                         bcopy((void *)sc_vtb_attr_pointer(vtb, at),
395                               (void *)sc_vtb_attr_pointer(vtb, at + count),
396                               (vtb->vtb_size - at - count)*sizeof(u_int16_t)); 
397                 }
398         }
399         if (vtb->vtb_type == VTB_FRAMEBUFFER) {
400                 fillw_io(c, sc_vtb_pointer(vtb, at), count);
401                 fillw_io(at2pc98(attr),
402                          sc_vtb_attr_pointer(vtb, at), count);
403         } else {
404                 fillw(c, (void *)sc_vtb_pointer(vtb, at), count);
405                 fillw(at2pc98(attr),
406                       (void *)sc_vtb_attr_pointer(vtb, at), count);
407         }
408 }
409
410 #endif /* NSC */