1 /*        $NetBSD: ite_subr.c,v 1.11 2011/02/12 05:08:41 tsutsui Exp $          */
2 
3 /*
4  * Copyright (c) 1988 University of Utah.
5  * Copyright (c) 1990, 1993
6  *        The Regents of the University of California.  All rights reserved.
7  *
8  * This code is derived from software contributed to Berkeley by
9  * the Systems Programming Group of the University of Utah Computer
10  * Science Department.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  * 3. Neither the name of the University nor the names of its contributors
21  *    may be used to endorse or promote products derived from this software
22  *    without specific prior written permission.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  *
36  * from: Utah $Hdr: ite_subr.c 1.2 92/01/20$
37  *
38  *        @(#)ite_subr.c      8.1 (Berkeley) 6/10/93
39  */
40 
41 #ifdef ITECONSOLE
42 
43 #include <sys/param.h>
44 
45 #include <hp300/stand/common/itereg.h>
46 
47 #include <hp300/stand/common/samachdep.h>
48 #include <hp300/stand/common/itevar.h>
49 
50 static void ite_writeglyph(struct ite_data *, u_char *, u_char *);
51 
52 void
ite_fontinfo(struct ite_data * ip)53 ite_fontinfo(struct ite_data *ip)
54 {
55           u_long fontaddr = getword(ip, getword(ip, FONTROM) + FONTADDR);
56 
57           ip->ftheight = getbyte(ip, fontaddr + FONTHEIGHT);
58           ip->ftwidth  = getbyte(ip, fontaddr + FONTWIDTH);
59           ip->rows     = ip->dheight / ip->ftheight;
60           ip->cols     = ip->dwidth / ip->ftwidth;
61 
62           if (ip->fbwidth > ip->dwidth) {
63                     /*
64                      * Stuff goes to right of display.
65                      */
66                     ip->fontx    = ip->dwidth;
67                     ip->fonty    = 0;
68                     ip->cpl      = (ip->fbwidth - ip->dwidth) / ip->ftwidth;
69                     ip->cblankx  = ip->dwidth;
70                     ip->cblanky  = ip->fonty + ((128 / ip->cpl) +1) * ip->ftheight;
71           } else {
72                     /*
73                      * Stuff goes below the display.
74                      */
75                     ip->fontx   = 0;
76                     ip->fonty   = ip->dheight;
77                     ip->cpl     = ip->fbwidth / ip->ftwidth;
78                     ip->cblankx = 0;
79                     ip->cblanky = ip->fonty + ((128 / ip->cpl) + 1) * ip->ftheight;
80           }
81 }
82 
83 void
ite_fontinit1bpp(struct ite_data * ip)84 ite_fontinit1bpp(struct ite_data *ip)
85 {
86           u_char *fbmem, *dp;
87           int c, l, b;
88           int stride, width;
89 
90           dp = (u_char *)(getword(ip, getword(ip, FONTROM) + FONTADDR) +
91               (char *)ip->regbase) + FONTDATA;
92           stride = ip->fbwidth >> 3;
93           width = (ip->ftwidth + 7) / 8;
94 
95           for (c = 0; c < 128; c++) {
96                     fbmem = (u_char *)FBBASE +
97                         (ip->fonty + (c / ip->cpl) * ip->ftheight) * stride;
98                     fbmem += (ip->fontx >> 3) + (c % ip->cpl) * width;
99                     for (l = 0; l < ip->ftheight; l++) {
100                               for (b = 0; b < width; b++) {
101                                         *fbmem++ = *dp;
102                                         dp += 2;
103                               }
104                               fbmem -= width;
105                               fbmem += stride;
106                     }
107           }
108 }
109 
110 void
ite_fontinit8bpp(struct ite_data * ip)111 ite_fontinit8bpp(struct ite_data *ip)
112 {
113           int bytewidth = (((ip->ftwidth - 1) / 8) + 1);
114           int glyphsize = bytewidth * ip->ftheight;
115           u_char fontbuf[500];
116           u_char *dp, *fbmem;
117           int c, i, romp;
118 
119           romp = getword(ip, getword(ip, FONTROM) + FONTADDR) + FONTDATA;
120           for (c = 0; c < 128; c++) {
121                     fbmem = (u_char *)(FBBASE +
122                          (ip->fonty + (c / ip->cpl) * ip->ftheight) * ip->fbwidth +
123                          (ip->fontx + (c % ip->cpl) * ip->ftwidth));
124                     dp = fontbuf;
125                     for (i = 0; i < glyphsize; i++) {
126                               *dp++ = getbyte(ip, romp);
127                               romp += 2;
128                     }
129                     ite_writeglyph(ip, fbmem, fontbuf);
130           }
131 }
132 
133 static void
ite_writeglyph(struct ite_data * ip,u_char * fbmem,u_char * glyphp)134 ite_writeglyph(struct ite_data *ip, u_char *fbmem, u_char *glyphp)
135 {
136           int bn;
137           int l, b;
138 
139           for (l = 0; l < ip->ftheight; l++) {
140                     bn = 7;
141                     for (b = 0; b < ip->ftwidth; b++) {
142                               if ((1 << bn) & *glyphp)
143                                         *fbmem++ = 1;
144                               else
145                                         *fbmem++ = 0;
146                               if (--bn < 0) {
147                                         bn = 7;
148                                         glyphp++;
149                               }
150                     }
151                     if (bn < 7)
152                               glyphp++;
153                     fbmem -= ip->ftwidth;
154                     fbmem += ip->fbwidth;
155           }
156 }
157 
158 /*
159  * The cursor is just an inverted space.
160  */
161 #define flip_cursor(ip) \
162           (*ip->bmv)(ip, ip->cblanky, ip->cblankx, ip->cursory * ip->ftheight, \
163               ip->cursorx * ip->ftwidth, ip->ftheight, ip->ftwidth, RR_XOR)
164 
165 void
ite_dio_cursor(struct ite_data * ip,int flag)166 ite_dio_cursor(struct ite_data *ip, int flag)
167 {
168 
169           switch (flag) {
170           case MOVE_CURSOR:
171                     flip_cursor(ip);
172                     /* FALLTHROUGH */
173           case DRAW_CURSOR:
174                     ip->cursorx = ip->curx;
175                     ip->cursory = ip->cury;
176                     /* FALLTHROUGH */
177           default:
178                     flip_cursor(ip);
179                     break;
180           }
181 }
182 
183 void
ite_dio_putc1bpp(struct ite_data * ip,int c,int dy,int dx)184 ite_dio_putc1bpp(struct ite_data *ip, int c, int dy, int dx)
185 {
186 
187           ite_dio_windowmove1bpp(ip, charY(ip, c), charX1bpp(ip, c),
188               dy * ip->ftheight, dx * ip->ftwidth,
189               ip->ftheight, ip->ftwidth, RR_COPY);
190 }
191 
192 void
ite_dio_putc8bpp(struct ite_data * ip,int c,int dy,int dx)193 ite_dio_putc8bpp(struct ite_data *ip, int c, int dy, int dx)
194 {
195 
196           (*ip->bmv)(ip, charY(ip, c), charX(ip, c),
197               dy * ip->ftheight, dx * ip->ftwidth,
198               ip->ftheight, ip->ftwidth, RR_COPY);
199 }
200 
201 void
ite_dio_clear(struct ite_data * ip,int sy,int sx,int h,int w)202 ite_dio_clear(struct ite_data *ip, int sy, int sx, int h, int w)
203 {
204 
205           (*ip->bmv)(ip, sy * ip->ftheight, sx * ip->ftwidth,
206               sy * ip->ftheight, sx * ip->ftwidth,
207               h  * ip->ftheight, w  * ip->ftwidth, RR_CLEAR);
208 }
209 
210 void
ite_dio_scroll(struct ite_data * ip)211 ite_dio_scroll(struct ite_data *ip)
212 {
213 
214           flip_cursor(ip);
215 
216           (*ip->bmv)(ip, ip->ftheight, 0, 0, 0, (ip->rows - 1) * ip->ftheight,
217               ip->cols * ip->ftwidth, RR_COPY);
218 }
219 
220 #include <hp300/stand/common/maskbits.h>
221 
222 /* NOTE:
223  * the first element in starttab could be 0xffffffff.  making it 0
224  * lets us deal with a full first word in the middle loop, rather
225  * than having to do the multiple reads and masks that we'd
226  * have to do if we thought it was partial.
227  */
228 int starttab[32] = {
229           0x00000000,
230           0x7FFFFFFF,
231           0x3FFFFFFF,
232           0x1FFFFFFF,
233           0x0FFFFFFF,
234           0x07FFFFFF,
235           0x03FFFFFF,
236           0x01FFFFFF,
237           0x00FFFFFF,
238           0x007FFFFF,
239           0x003FFFFF,
240           0x001FFFFF,
241           0x000FFFFF,
242           0x0007FFFF,
243           0x0003FFFF,
244           0x0001FFFF,
245           0x0000FFFF,
246           0x00007FFF,
247           0x00003FFF,
248           0x00001FFF,
249           0x00000FFF,
250           0x000007FF,
251           0x000003FF,
252           0x000001FF,
253           0x000000FF,
254           0x0000007F,
255           0x0000003F,
256           0x0000001F,
257           0x0000000F,
258           0x00000007,
259           0x00000003,
260           0x00000001
261 };
262 
263 int endtab[32] = {
264           0x00000000,
265           0x80000000,
266           0xC0000000,
267           0xE0000000,
268           0xF0000000,
269           0xF8000000,
270           0xFC000000,
271           0xFE000000,
272           0xFF000000,
273           0xFF800000,
274           0xFFC00000,
275           0xFFE00000,
276           0xFFF00000,
277           0xFFF80000,
278           0xFFFC0000,
279           0xFFFE0000,
280           0xFFFF0000,
281           0xFFFF8000,
282           0xFFFFC000,
283           0xFFFFE000,
284           0xFFFFF000,
285           0xFFFFF800,
286           0xFFFFFC00,
287           0xFFFFFE00,
288           0xFFFFFF00,
289           0xFFFFFF80,
290           0xFFFFFFC0,
291           0xFFFFFFE0,
292           0xFFFFFFF0,
293           0xFFFFFFF8,
294           0xFFFFFFFC,
295           0xFFFFFFFE
296 };
297 
298 void
ite_dio_windowmove1bpp(struct ite_data * ip,int sy,int sx,int dy,int dx,int h,int w,int func)299 ite_dio_windowmove1bpp(struct ite_data *ip, int sy, int sx, int dy, int dx,
300     int h, int w, int func)
301 {
302           int width;                    /* add to get to same position in next line */
303 
304           unsigned int *psrcLine, *pdstLine;
305                                         /* pointers to line with current src and dst */
306           unsigned int *psrc; /* pointer to current src longword */
307           unsigned int *pdst; /* pointer to current dst longword */
308 
309                                         /* following used for looping through a line */
310           unsigned int startmask, endmask;  /* masks for writing ends of dst */
311           int nlMiddle;                 /* whole longwords in dst */
312           int nl;                       /* temp copy of nlMiddle */
313           unsigned int tmpSrc;          /* place to store full source word */
314           int xoffSrc;                  /* offset (>= 0, < 32) from which to
315                                            fetch whole longwords fetched
316                                            in src */
317           int nstart;                   /* number of ragged bits at start of dst */
318           int nend;           /* number of ragged bits at end of dst */
319           int srcStartOver;   /* pulling nstart bits from src
320                                            overflows into the next word? */
321 
322           if (h == 0 || w == 0)
323                     return;
324 
325           width = ip->fbwidth >> 5;
326           psrcLine = ((unsigned int *) ip->fbbase) + (sy * width);
327           pdstLine = ((unsigned int *) ip->fbbase) + (dy * width);
328 
329           /* x direction doesn't matter for < 1 longword */
330           if (w <= 32) {
331                     int srcBit, dstBit;     /* bit offset of src and dst */
332 
333                     pdstLine += (dx >> 5);
334                     psrcLine += (sx >> 5);
335                     psrc = psrcLine;
336                     pdst = pdstLine;
337 
338                     srcBit = sx & 0x1f;
339                     dstBit = dx & 0x1f;
340 
341                     while (h--) {
342                               getandputrop(psrc, srcBit, dstBit, w, pdst, func);
343                               pdst += width;
344                               psrc += width;
345                     }
346           } else {
347                     maskbits(dx, w, startmask, endmask, nlMiddle);
348                     if (startmask)
349                               nstart = 32 - (dx & 0x1f);
350                     else
351                               nstart = 0;
352                     if (endmask)
353                               nend = (dx + w) & 0x1f;
354                     else
355                               nend = 0;
356 
357                     xoffSrc = ((sx & 0x1f) + nstart) & 0x1f;
358                     srcStartOver = ((sx & 0x1f) + nstart) > 31;
359 
360                     pdstLine += (dx >> 5);
361                     psrcLine += (sx >> 5);
362 
363                     while (h--) {
364                               psrc = psrcLine;
365                               pdst = pdstLine;
366 
367                               if (startmask) {
368                                         getandputrop(psrc, (sx & 0x1f), (dx & 0x1f),
369                                             nstart, pdst, func);
370                                         pdst++;
371                                         if (srcStartOver)
372                                                   psrc++;
373                               }
374 
375                               /* special case for aligned operations */
376                               if (xoffSrc == 0) {
377                                         nl = nlMiddle;
378                                         while (nl--) {
379                                                   DoRop(*pdst, func, *psrc++, *pdst);
380                                                   pdst++;
381                                         }
382                               } else {
383                                         nl = nlMiddle + 1;
384                                         while (--nl) {
385                                                   getunalignedword(psrc, xoffSrc, tmpSrc);
386                                                   DoRop(*pdst, func, tmpSrc, *pdst);
387                                                   pdst++;
388                                                   psrc++;
389                                         }
390                               }
391 
392                               if (endmask) {
393                                         getandputrop0(psrc, xoffSrc, nend, pdst, func);
394                               }
395 
396                               pdstLine += width;
397                               psrcLine += width;
398                     }
399           }
400 }
401 #endif
402