xref: /netbsd-src/sys/arch/amiga/dev/ite_cc.c (revision cda4f8f6ee55684e8d311b86c99ea59191e6b74f)
1 #include "ite.h"
2 #if NITE > 0
3 
4 #include "param.h"
5 #include "conf.h"
6 #include "proc.h"
7 #include "ioctl.h"
8 #include "tty.h"
9 #include "systm.h"
10 
11 #include "itevar.h"
12 
13 #include "machine/cpu.h"
14 
15 /* XXX */
16 #include "grfioctl.h"
17 #include "grfvar.h"
18 #include "grf_ccreg.h"
19 
20 extern unsigned char kernel_font_width, kernel_font_height;
21 extern unsigned char kernel_font_lo, kernel_font_hi;
22 extern unsigned char kernel_font[], kernel_cursor[];
23 
24 
25 customc_init(ip)
26 	register struct ite_softc *ip;
27 {
28   struct ccfb *fb;
29   int fboff, fbsize;
30 
31   if (ip->grf == 0)
32     ip->grf = &grf_softc[ip - ite_softc];
33 
34   ip->priv = ip->grf->g_display.gd_regaddr;
35   fb = (struct ccfb *) ip->priv;
36   fbsize = ip->grf->g_display.gd_fbsize;
37 
38 #if 0
39   /* already done in the grf layer */
40 
41   /* clear the display. bzero only likes regions up to 64k, so call multiple times */
42   for (fboff = 0; fboff < fbsize; fboff += 64*1024)
43     bzero (fb->fb + fboff, fbsize - fboff > 64*1024 ? 64*1024 : fbsize - fboff);
44 #endif
45 
46   /* this is a dreadful font, but I don't have an alternative at the moment.. */
47   ip->font     = kernel_font;
48   ip->font_lo  = kernel_font_lo;
49   ip->font_hi  = kernel_font_hi;
50   ip->ftwidth  = kernel_font_width;
51   ip->ftheight = kernel_font_height;
52   ip->cursor   = kernel_cursor;
53 
54   ip->rows     = fb->disp_height / ip->ftheight;
55   ip->cols     = fb->disp_width  / ip->ftwidth;
56 
57 
58 #if 0
59   printf ("font@%x, cursor@%x\n", ip->font, ip->cursor);
60   dump_copperlist (fb->cop1);
61   dump_copperlist (fb->cop2);
62 #endif
63 }
64 
65 customc_deinit(ip)
66 	struct ite_softc *ip;
67 {
68   ip->flags &= ~ITE_INITED;
69 }
70 
71 
72 void static inline
73 customc_windowmove (src, srcx, srcy, srcmod,
74 		    dst, dstx, dsty, dstmod, h, w, op)
75     unsigned char *src, *dst;
76     unsigned short srcx, srcy, srcmod;
77     unsigned short dstx, dsty, dstmod;
78     unsigned short h, w;
79     unsigned char op;
80 {
81   int i;
82 
83   src += srcmod*srcy + (srcx >> 3);
84   dst += dstmod*dsty + (dstx >> 3);
85 
86 #if 0
87 printf("ccwm: %x-%x-%x-%x-%c\n", src, dst, h, w,
88 	op == RR_XOR ? '^' : op == RR_COPY ? '|' : op == RR_CLEAR ? 'C' : 'I');
89 #endif
90 
91   /* currently, only drawing to byte slots is supported... */
92   if ((srcx & 07) || (dstx & 07) || (w & 07))
93     panic ("customc_windowmove: odd offset");
94 
95   w >>= 3;
96   while (h--)
97     {
98       if (src > dst)
99 	for (i = 0; i < w; i++)
100 	  switch (op)
101 	    {
102 	    case RR_COPY:
103 	      dst[i] = src[i];
104 	      break;
105 
106 	    case RR_CLEAR:
107 	      dst[i] = 0;
108 	      break;
109 
110 	    case RR_XOR:
111 	      dst[i] ^= src[i];
112 	      break;
113 
114 	    case RR_COPYINVERTED:
115 	      dst[i] = ~src[i];
116 	      break;
117 	    }
118       else
119 	for (i = w - 1; i >= 0; i--)
120 	  switch (op)
121 	    {
122 	    case RR_COPY:
123 	      dst[i] = src[i];
124 	      break;
125 
126 	    case RR_CLEAR:
127 	      dst[i] = 0;
128 	      break;
129 
130 	    case RR_XOR:
131 	      dst[i] ^= src[i];
132 	      break;
133 
134 	    case RR_COPYINVERTED:
135 	      dst[i] = ~src[i];
136 	      break;
137 	    }
138 
139 
140       src += srcmod;
141       dst += dstmod;
142     }
143 
144 }
145 
146 
147 customc_putc(ip, c, dy, dx, mode)
148 	register struct ite_softc *ip;
149         register int dy, dx;
150 	int c, mode;
151 {
152   register int wrr = ((mode == ATTR_INV) ? RR_COPYINVERTED : RR_COPY);
153   struct ccfb *fb = (struct ccfb *) ip->priv;
154 
155   if (c >= ip->font_lo && c <= ip->font_hi)
156     {
157       c -= ip->font_lo;
158 
159       customc_windowmove (ip->font, 0, c * ip->ftheight, 1,
160     			  fb->fb, fb->fb_x + dx * ip->ftwidth,
161     			  fb->fb_y + dy * ip->ftheight,
162     			  fb->fb_width >> 3,
163     			  ip->ftheight, ip->ftwidth, wrr);
164     }
165 }
166 
167 customc_cursor(ip, flag)
168 	register struct ite_softc *ip;
169         register int flag;
170 {
171   struct ccfb *fb = (struct ccfb *) ip->priv;
172 
173   if (flag != DRAW_CURSOR)
174     {
175       /* erase it */
176       customc_windowmove (ip->cursor, 0, 0, 1,
177 	  		  fb->fb, fb->fb_x + ip->cursorx * ip->ftwidth,
178     			  fb->fb_y + ip->cursory * ip->ftheight,
179     			  fb->fb_width >> 3,
180     			  ip->ftheight, ip->ftwidth, RR_XOR);
181     }
182   if (flag == DRAW_CURSOR || flag == MOVE_CURSOR)
183     {
184       /* draw it */
185       customc_windowmove (ip->cursor, 0, 0, 1,
186 	    		  fb->fb, fb->fb_x + ip->curx * ip->ftwidth,
187     			  fb->fb_y + ip->cury * ip->ftheight,
188     			  fb->fb_width >> 3,
189     			  ip->ftheight, ip->ftwidth, RR_XOR);
190       ip->cursorx = ip->curx;
191       ip->cursory = ip->cury;
192     }
193 }
194 
195 customc_clear(ip, sy, sx, h, w)
196 	struct ite_softc *ip;
197 	register int sy, sx, h, w;
198 {
199   struct ccfb *fb = (struct ccfb *) ip->priv;
200 
201   customc_windowmove (0, 0, 0, 0,
202   		      fb->fb, fb->fb_x + sx * ip->ftwidth,
203     		      fb->fb_y + sy * ip->ftheight,
204     		      fb->fb_width >> 3,
205     		      h * ip->ftheight, w * ip->ftwidth, RR_CLEAR);
206 }
207 
208 customc_blockmove(ip, sy, sx, dy, dx, h, w)
209 	register struct ite_softc *ip;
210 	int sy, sx, dy, dx, h, w;
211 {
212   struct ccfb *fb = (struct ccfb *) ip->priv;
213 
214   customc_windowmove(fb->fb, fb->fb_x + sx * ip->ftwidth,
215 		     fb->fb_y + sy * ip->ftheight,
216 		     fb->fb_width >> 3,
217 		     fb->fb, fb->fb_x + dx * ip->ftwidth,
218 		     fb->fb_y + dy * ip->ftheight,
219 		     fb->fb_width >> 3,
220 		     h * ip->ftheight, w * ip->ftwidth, RR_COPY);
221 }
222 
223 customc_scroll(ip, sy, sx, count, dir)
224         register struct ite_softc *ip;
225         register int sy;
226         int dir, sx, count;
227 {
228   register int height, dy, i;
229 
230   customc_cursor(ip, ERASE_CURSOR);
231 
232   if (dir == SCROLL_UP)
233     {
234       dy = sy - count;
235       height = ip->bottom_margin - sy + 1;
236       for (i = 0; i < height; i++)
237 	customc_blockmove(ip, sy + i, sx, dy + i, 0, 1, ip->cols);
238     }
239   else if (dir == SCROLL_DOWN)
240     {
241       dy = sy + count;
242       height = ip->bottom_margin - dy + 1;
243       for (i = (height - 1); i >= 0; i--)
244 	customc_blockmove(ip, sy + i, sx, dy + i, 0, 1, ip->cols);
245     }
246   else if (dir == SCROLL_RIGHT)
247     {
248       customc_blockmove(ip, sy, sx, sy, sx + count, 1, ip->cols - (sx + count));
249     }
250   else
251     {
252       customc_blockmove(ip, sy, sx, sy, sx - count, 1, ip->cols - sx);
253     }
254 }
255 
256 #endif
257