ite_subr.c revision 1.13 1 /* $NetBSD: ite_subr.c,v 1.13 2025/05/31 18:11:50 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 *, uint8_t *, uint8_t *);
51
52 void
53 ite_fontinfo(struct ite_data *ip)
54 {
55 uint32_t 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
84 ite_fontinit1bpp(struct ite_data *ip)
85 {
86 uint8_t *fbmem, *dp;
87 int c, l, b;
88 int stride, width;
89
90 dp = (uint8_t *)(getword(ip, getword(ip, FONTROM) + FONTADDR) +
91 (uint8_t *)ip->regbase) + FONTDATA;
92 stride = ip->fbwidth >> 3;
93 width = (ip->ftwidth + 7) / 8;
94
95 for (c = 0; c < 128; c++) {
96 fbmem = (uint8_t *)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
111 ite_fontinit8bpp(struct ite_data *ip)
112 {
113 int bytewidth = (((ip->ftwidth - 1) / 8) + 1);
114 int glyphsize = bytewidth * ip->ftheight;
115 uint8_t fontbuf[500];
116 uint8_t *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 = (uint8_t *)(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
134 ite_writeglyph(struct ite_data *ip, uint8_t *fbmem, uint8_t *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
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 case ERASE_CURSOR:
178 default:
179 flip_cursor(ip);
180 break;
181 }
182 }
183
184 void
185 ite_dio_putc1bpp(struct ite_data *ip, int c, int dy, int dx)
186 {
187
188 ite_dio_windowmove1bpp(ip, charY(ip, c), charX1bpp(ip, c),
189 dy * ip->ftheight, dx * ip->ftwidth,
190 ip->ftheight, ip->ftwidth, RR_COPY);
191 }
192
193 void
194 ite_dio_putc8bpp(struct ite_data *ip, int c, int dy, int dx)
195 {
196
197 (*ip->bmv)(ip, charY(ip, c), charX(ip, c),
198 dy * ip->ftheight, dx * ip->ftwidth,
199 ip->ftheight, ip->ftwidth, RR_COPY);
200 }
201
202 void
203 ite_dio_clear(struct ite_data *ip, int sy, int sx, int h, int w)
204 {
205
206 (*ip->bmv)(ip, sy * ip->ftheight, sx * ip->ftwidth,
207 sy * ip->ftheight, sx * ip->ftwidth,
208 h * ip->ftheight, w * ip->ftwidth, RR_CLEAR);
209 }
210
211 void
212 ite_dio_scroll(struct ite_data *ip)
213 {
214
215 (*ip->bmv)(ip, ip->ftheight, 0, 0, 0, (ip->rows - 1) * ip->ftheight,
216 ip->cols * ip->ftwidth, RR_COPY);
217 }
218
219 #include <hp300/stand/common/maskbits.h>
220
221 /* NOTE:
222 * the first element in starttab could be 0xffffffff. making it 0
223 * lets us deal with a full first word in the middle loop, rather
224 * than having to do the multiple reads and masks that we'd
225 * have to do if we thought it was partial.
226 */
227 static const uint32_t starttab[32] = {
228 0x00000000,
229 0x7FFFFFFF,
230 0x3FFFFFFF,
231 0x1FFFFFFF,
232 0x0FFFFFFF,
233 0x07FFFFFF,
234 0x03FFFFFF,
235 0x01FFFFFF,
236 0x00FFFFFF,
237 0x007FFFFF,
238 0x003FFFFF,
239 0x001FFFFF,
240 0x000FFFFF,
241 0x0007FFFF,
242 0x0003FFFF,
243 0x0001FFFF,
244 0x0000FFFF,
245 0x00007FFF,
246 0x00003FFF,
247 0x00001FFF,
248 0x00000FFF,
249 0x000007FF,
250 0x000003FF,
251 0x000001FF,
252 0x000000FF,
253 0x0000007F,
254 0x0000003F,
255 0x0000001F,
256 0x0000000F,
257 0x00000007,
258 0x00000003,
259 0x00000001
260 };
261
262 static const uint32_t endtab[32] = {
263 0x00000000,
264 0x80000000,
265 0xC0000000,
266 0xE0000000,
267 0xF0000000,
268 0xF8000000,
269 0xFC000000,
270 0xFE000000,
271 0xFF000000,
272 0xFF800000,
273 0xFFC00000,
274 0xFFE00000,
275 0xFFF00000,
276 0xFFF80000,
277 0xFFFC0000,
278 0xFFFE0000,
279 0xFFFF0000,
280 0xFFFF8000,
281 0xFFFFC000,
282 0xFFFFE000,
283 0xFFFFF000,
284 0xFFFFF800,
285 0xFFFFFC00,
286 0xFFFFFE00,
287 0xFFFFFF00,
288 0xFFFFFF80,
289 0xFFFFFFC0,
290 0xFFFFFFE0,
291 0xFFFFFFF0,
292 0xFFFFFFF8,
293 0xFFFFFFFC,
294 0xFFFFFFFE
295 };
296
297 void
298 ite_dio_windowmove1bpp(struct ite_data *ip, int sy, int sx, int dy, int dx,
299 int h, int w, int func)
300 {
301 int width; /* add to get to same position in next line */
302
303 uint32_t *psrcLine, *pdstLine;
304 /* pointers to line with current src and dst */
305 uint32_t *psrc; /* pointer to current src longword */
306 uint32_t *pdst; /* pointer to current dst longword */
307
308 /* following used for looping through a line */
309 uint32_t startmask, endmask; /* masks for writing ends of dst */
310 int nlMiddle; /* whole longwords in dst */
311 int nl; /* temp copy of nlMiddle */
312 uint32_t tmpSrc; /* place to store full source word */
313 int xoffSrc; /* offset (>= 0, < 32) from which to
314 fetch whole longwords fetched
315 in src */
316 int nstart; /* number of ragged bits at start of dst */
317 int nend; /* number of ragged bits at end of dst */
318 int srcStartOver; /* pulling nstart bits from src
319 overflows into the next word? */
320
321 if (h == 0 || w == 0)
322 return;
323
324 width = ip->fbwidth >> 5;
325 psrcLine = ((uint32_t *)ip->fbbase) + (sy * width);
326 pdstLine = ((uint32_t *)ip->fbbase) + (dy * width);
327
328 /* x direction doesn't matter for < 1 longword */
329 if (w <= 32) {
330 int srcBit, dstBit; /* bit offset of src and dst */
331
332 pdstLine += (dx >> 5);
333 psrcLine += (sx >> 5);
334 psrc = psrcLine;
335 pdst = pdstLine;
336
337 srcBit = sx & 0x1f;
338 dstBit = dx & 0x1f;
339
340 while (h-- > 0) {
341 getandputrop(psrc, srcBit, dstBit, w, pdst, func);
342 pdst += width;
343 psrc += width;
344 }
345 } else {
346 maskbits(dx, w, startmask, endmask, nlMiddle);
347 if (startmask != 0)
348 nstart = 32 - (dx & 0x1f);
349 else
350 nstart = 0;
351 if (endmask != 0)
352 nend = (dx + w) & 0x1f;
353 else
354 nend = 0;
355
356 xoffSrc = ((sx & 0x1f) + nstart) & 0x1f;
357 srcStartOver = ((sx & 0x1f) + nstart) > 31;
358
359 pdstLine += (dx >> 5);
360 psrcLine += (sx >> 5);
361
362 while (h-- > 0) {
363 psrc = psrcLine;
364 pdst = pdstLine;
365
366 if (startmask != 0) {
367 getandputrop(psrc, (sx & 0x1f), (dx & 0x1f),
368 nstart, pdst, func);
369 pdst++;
370 if (srcStartOver != 0)
371 psrc++;
372 }
373
374 /* special case for aligned operations */
375 if (xoffSrc == 0) {
376 nl = nlMiddle;
377 while (nl-- > 0) {
378 DoRop(*pdst, func, *psrc++, *pdst);
379 pdst++;
380 }
381 } else {
382 nl = nlMiddle + 1;
383 while (--nl > 0) {
384 getunalignedword(psrc, xoffSrc, tmpSrc);
385 DoRop(*pdst, func, tmpSrc, *pdst);
386 pdst++;
387 psrc++;
388 }
389 }
390
391 if (endmask != 0) {
392 getandputrop0(psrc, xoffSrc, nend, pdst, func);
393 }
394
395 pdstLine += width;
396 psrcLine += width;
397 }
398 }
399 }
400 #endif
401