OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [tags/] [MW_0_8_9PRE7/] [mw/] [src/] [drivers/] [fblin4hp.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 673 markom
/*
2
 * Copyright (c) 1999 Greg Haerr <greg@censoft.com>
3
 *
4
 * 4bpp Packed Linear Video Driver for Microwindows
5
 *      This driver is written for the Vr41xx Palm PC machines
6
 *      Hopefully, we can get the 4bpp mode running 320x240x16
7
 *
8
 *      In this driver, psd->linelen is line byte length, not line pixel length
9
 */
10
/*#define NDEBUG*/
11
#include <assert.h>
12
#include <string.h>
13
#include "device.h"
14
#include "fb.h"
15
 
16
//static unsigned char notmask[2] = { 0x0f, 0xf0};  // non-linear 
17
static unsigned char notmask[2] = { 0xf0, 0x0f };   // linear
18
static unsigned char revnotmask[2] = { 0xf0, 0x0f};
19
 
20
/* Calc linelen and mmap size, return 0 on fail*/
21
static int
22
linear4_init(PSD psd)
23
{
24
        if (!psd->size)
25
                psd->size = psd->yres * psd->linelen;
26
        /* linelen in bytes for bpp 1, 2, 4, 8 so no change*/
27
        return 1;
28
}
29
 
30
#if 1  // kykim
31
/* Read pixel at x, y*/
32
static MWPIXELVAL
33
linear4_readpixel(PSD psd, MWCOORD x, MWCOORD y)
34
{
35
        ADDR8   addr = psd->addr;
36
 
37
        assert (addr != 0);
38
        assert (x >= 0 && x < psd->xres);
39
        assert (y >= 0 && y < psd->yres);
40
 
41
        return (addr[(x>>1) + y * psd->linelen] >> (((x&1))<<2) ) & 0x0f;
42
}
43
 
44
/* Draw a vertical line from x,y1 to x,y2 including final point*/
45
static void
46
linear4_drawvertline(PSD psd, MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c)
47
{
48
        ADDR8   addr = psd->addr;
49
        int     linelen = psd->linelen;
50
 
51
        assert (addr != 0);
52
        assert (x >= 0 && x < psd->xres);
53
        assert (y1 >= 0 && y1 < psd->yres);
54
        assert (y2 >= 0 && y2 < psd->yres);
55
        assert (y2 >= y1);
56
        assert (c < psd->ncolors);
57
 
58
        DRAWON;
59
        addr += (x>>1) + y1 * linelen;
60
        while(y1++ <= y2) {
61
                *addr = (*addr & notmask[x&1]) | (c << (((x&1))<<2));
62
                addr += linelen;
63
        }
64
        DRAWOFF;
65
}
66
#endif  // kykim
67
/* ########################################################################## */
68
#if 0  // For 8 bit memory access
69
/* Set pixel at x, y, to pixelval c*/
70
static void
71
linear4_drawpixel(PSD psd, MWCOORD x, MWCOORD y, MWPIXELVAL c)
72
{
73
        ADDR8   addr = psd->addr;
74
 
75
        assert (addr != 0);
76
        assert (x >= 0 && x < psd->xres);
77
        assert (y >= 0 && y < psd->yres);
78
        assert (c < psd->ncolors);
79
 
80
        DRAWON;
81
        addr += (x>>1) + y * psd->linelen;
82
//      if(gr_mode == MWMODE_XOR)
83
//              *addr ^= c << ((1-(x&1))<<2);
84
//      else
85
        *addr = (*addr & notmask[x&1]) | (c << (((x&1))<<2) );
86
        DRAWOFF;
87
}
88
 
89
/* Read pixel at x, y*/
90
static MWPIXELVAL
91
linear4_readpixel(PSD psd, MWCOORD x, MWCOORD y)
92
{
93
        ADDR8   addr = psd->addr;
94
 
95
        assert (addr != 0);
96
        assert (x >= 0 && x < psd->xres);
97
        assert (y >= 0 && y < psd->yres);
98
 
99
        return (addr[(x>>1) + y * psd->linelen] >> (((x&1))<<2) ) & 0x0f;
100
}
101
 
102
/* Draw horizontal line from x1,y to x2,y including final point*/
103
static void
104
linear4_drawhorzline(PSD psd, MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c)
105
{
106
        ADDR8   addr = psd->addr;
107
 
108
        assert (addr != 0);
109
        assert (x1 >= 0 && x1 < psd->xres);
110
        assert (x2 >= 0 && x2 < psd->xres);
111
        assert (x2 >= x1);
112
        assert (y >= 0 && y < psd->yres);
113
        assert (c < psd->ncolors);
114
 
115
        DRAWON;
116
        addr += (x1>>1) + y * psd->linelen;
117
/*      if(gr_mode == MWMODE_XOR) {
118
                while(x1 <= x2) {
119
                        *addr ^= c << ((1-(x1&1))<<2);
120
                        if((++x1 & 1) == 0)
121
                                ++addr;
122
                }
123
        } else {
124
*/
125
        while(x1 <= x2) {
126
                *addr = (*addr & notmask[x1&1]) | (c << (((x1&1))<<2));
127
                if((++x1 & 1) == 0)
128
                        ++addr;
129
        }
130
//      }
131
        DRAWOFF;
132
}
133
 
134
/* Draw a vertical line from x,y1 to x,y2 including final point*/
135
static void
136
linear4_drawvertline(PSD psd, MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c)
137
{
138
        ADDR8   addr = psd->addr;
139
        int     linelen = psd->linelen;
140
 
141
        assert (addr != 0);
142
        assert (x >= 0 && x < psd->xres);
143
        assert (y1 >= 0 && y1 < psd->yres);
144
        assert (y2 >= 0 && y2 < psd->yres);
145
        assert (y2 >= y1);
146
        assert (c < psd->ncolors);
147
 
148
        DRAWON;
149
        addr += (x>>1) + y1 * linelen;
150
        while(y1++ <= y2) {
151
                *addr = (*addr & notmask[x&1]) | (c << (((x&1))<<2));
152
                addr += linelen;
153
        }
154
        DRAWOFF;
155
}
156
 
157
/* srccopy bitblt, opcode is currently ignored*/
158
static void
159
linear4_blit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD w, MWCOORD h,
160
        PSD srcpsd, MWCOORD srcx, MWCOORD srcy, long op)
161
{
162
        ADDR8   dst;
163
        ADDR8   src;
164
        int     i;
165
        int     dlinelen = dstpsd->linelen;
166
        int     slinelen = srcpsd->linelen;
167
 
168
        assert (dstpsd->addr != 0);
169
        assert (dstx >= 0 && dstx < dstpsd->xres);
170
        assert (dsty >= 0 && dsty < dstpsd->yres);
171
        assert (w > 0);
172
        assert (h > 0);
173
        assert (srcpsd->addr != 0);
174
        assert (srcx >= 0 && srcx < srcpsd->xres);
175
        assert (srcy >= 0 && srcy < srcpsd->yres);
176
        assert (dstx+w <= dstpsd->xres);
177
        assert (dsty+h <= dstpsd->yres);
178
        assert (srcx+w <= srcpsd->xres);
179
        assert (srcy+h <= srcpsd->yres);
180
 
181
        DRAWON;
182
        dst = dstpsd->addr + (dstx>>1) + dsty * dlinelen;
183
        src = srcpsd->addr + (srcx>>1) + srcy * slinelen;
184
        while(--h >= 0) {
185
                ADDR8   d = dst;
186
                ADDR8   s = src;
187
                MWCOORD dx = dstx;
188
                MWCOORD sx = srcx;
189
                for(i=0; i<w; ++i) {
190
                        *d = (*d & notmask[dx&1]) |
191
                           ((*s >> (((sx&1))<<2) & 0x0f) << (((dx&1))<<2));
192
                        if((++dx & 1) == 0)
193
                                ++d;
194
                        if((++sx & 1) == 0)
195
                                ++s;
196
                }
197
                dst += dlinelen;
198
                src += slinelen;
199
        }
200
        DRAWOFF;
201
}
202
 
203
#endif  // For 8 bit memory access
204
/* ########################################################################## */
205
 
206
 
207
// All these functions are working using the same philosophie:
208
// There are 8 pixels in an int (pixel0= bit 0 to 3, ....)
209
// As this is a 32 bits micro, all access should be made
210
// on 32 bits and should try to work on as many pixels as necceseray
211
// in order to minimize memory access.
212
 
213
typedef unsigned int T8p;   // set of 8 pixels
214
typedef unsigned int * P8p; // pointer on a set of 8 pixels
215
 
216
// this set of mask allows to select the n first pixels of an int
217
static const T8p Masks[]=
218
      {0x00000000, 0x0000000f, 0x000000ff, 0x00000fff,
219
       0x0000ffff, 0x000fffff, 0x00ffffff, 0x0fffffff};
220
 
221
// this set of mask allow to select the n first pixels of an int. 
222
// but a selection of 0 pixels selects in fact the 8 pixels.
223
static const T8p Masks2[]=
224
      {0xffffffff, 0x0000000f, 0x000000ff, 0x00000fff,
225
       0x0000ffff, 0x000fffff, 0x00ffffff, 0x0fffffff};
226
 
227
// this function create a set of 8 pixels of the same color.
228
static inline T8p EColor(T8p c)
229
{
230
  c|= c<<4; c|= c<<8; c|= c<<16;
231
  return(c);
232
}
233
 
234
// this function compute the addres of the group of pixels containing
235
// pixel x, y when the graphic is pointed by m and the size of a line is
236
// LineSize bytes
237
static inline P8p PPointer(P8p m, int LineSize, int x, int y)
238
{
239
  return( (P8p) (((int)m+((x>>1)+y*LineSize))&~3) );
240
}
241
 
242
// this function is a memset, but faster, and for ints....
243
void intset(int *d, int value, int nbInts);
244
 
245
#define swap(t, a, b) { t temp= a; a= b; b= temp; }
246
 
247
static
248
void linear41_drawpixel(PSD psd, MWCOORD x, MWCOORD y, MWPIXELVAL c)
249
{
250
  P8p p= PPointer(psd->addr, psd->linelen, x, y);       // get pixel address
251
  DRAWON;
252
  x= (x&0x7)<<2;                                        // get pixel position in the word (pixel number * 4)
253
  *p= ((*p)&~(0xf<<x))|(c<<x);                          // graphic = graphic - current pixel at pos + new picel at pos
254
  DRAWOFF;
255
}
256
 
257
/*
258
// timing used to check if the video memory is cachable.
259
// to use: uncomment, and uncomment the call to ltime in drawhorzline.
260
// if the result is around 170us, it's not chached.
261
// if it's around 10us, it's cached.
262
 
263
#include <sys/time.h>
264
#include <stdio.h>
265
 
266
long gt()
267
{
268
  struct timeval tv;
269
 
270
  gettimeofday(&tv, NULL);
271
  return(tv.tv_sec*1000000+tv.tv_usec);
272
}
273
 
274
static void ltime(int *p)
275
{
276
  int i;
277
  static int toto= 0;
278
  if (toto==0)
279
  {
280
     long t2, t3, t= gt();
281
     for (i= 1000; i!=0; i--)
282
        intset(p, 12345678, 1024);
283
     t2= gt(); t3= gt();
284
     toto= 1;
285
     printf("4KB = %dus\r\n", (int)(t2-t-t3+t2)/1000);
286
  }
287
}*/
288
 
289
static void intset2(int *p, int v, int c) { while(c>0) { c--; *p++= v; } }
290
 
291
static
292
void linear41_drawhorzline(PSD psd, MWCOORD x1, MWCOORD x2, MWCOORD y, MWPIXELVAL c)
293
{
294
  T8p Mask1, Mask2;                                     // start of line and end of line mask
295
  P8p p;                                                // pointer on line
296
  DRAWON;
297
  if (x1>x2) swap(int, x1, x2);                         // ensure x1<x2
298
//  ltime(psd->addr);
299
  x2= x2-x1+1;                                          // get number of pixels to draw
300
  p= PPointer(psd->addr, psd->linelen, x1, y);          // get pointer on start of line
301
  x1&= 7;
302
  Mask1= Masks[x1];                                     // get end and begining of lines
303
  Mask2= Masks2[(x1+x2)&7];
304
  x2= (x1+x2+7)>>3;                                     // get number of full words to write
305
  c= EColor(c);                                         // get 8 times the color
306
  switch(x2)                                            // unrolled loops for up to 120pixels.
307
  {
308
    case 0: break;
309
    case 1:  Mask1= Mask1|~Mask2; *p= (*p&Mask1)|(c&~Mask1); break;
310
    case 2:  *p++= (*p&Mask1)|(c&~Mask1); *p= (*p&~Mask2)|(c&Mask2); break;
311
    case 3:  *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p= (*p&~Mask2)|(c&Mask2); break;
312
    case 4:  *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); break;
313
    case 5:  *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); break;
314
    case 6:  *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); break;
315
    case 7:  *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); break;
316
    case 8:  *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); break;
317
    case 9:  *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); break;
318
    case 10: *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); break;
319
    case 11: *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); break;
320
    case 12: *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); break;
321
    case 13: *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); break;
322
    case 14: *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); break;
323
    case 15: *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); break;
324
    default:
325
            x2-= 2;
326
            *p++= (*p&Mask1)|(c&~Mask1);                        // write start mask
327
            intset(p, c, x2);                                   // write n time 8 pixels
328
            *(p+x2)= (*(p+x2)&~Mask2)|(c&Mask2);                // write end mask
329
            break;
330
  }
331
  DRAWOFF;
332
}
333
 
334
static
335
void linear41_drawvertline(PSD psd, MWCOORD x, MWCOORD y1, MWCOORD y2, MWPIXELVAL c)
336
{
337
  P8p p; T8p m; int d;
338
  DRAWON;
339
  if (y1>y2) swap(int, y1, y2);                         // ensure y1 < y2
340
  y2= y2-y1+1;                                          // get number of pixels to draw
341
  p= PPointer(psd->addr, psd->linelen, x, y1);          // get pointer on first pixel
342
  c<<= (x&7)<<2;                                        // get the color at the right place
343
  m= (0xf<<((x&7)<<2));                                 // get the mask
344
  d= psd->linelen >> 2;                                 // get the line lenght
345
  for(;y2!=0; y2--) { *p= (*p&~m)|c; p+= d; }            // for all lines, update the video data and jump to next line
346
  DRAWOFF;
347
}
348
 
349
static
350
void linear41_fillrect(PSD psd, MWCOORD x1, MWCOORD y1, MWCOORD x2, MWCOORD y2, MWPIXELVAL c)
351
{
352
  int d;
353
  T8p Mask1, Mask2;                                     // start of line and end of line mask    
354
  P8p p;                                                // pointer on line                       
355
  if (x1>x2) swap(int, x1, x2);                         // ensure x1<x2                                                                   
356
  if (y1>y2) swap(int, y1, y2);                         // ensure y1<y2                          
357
  DRAWON;
358
  x2= x2-x1+1;                                          // get number of pixels to draw          
359
  p= PPointer(psd->addr, psd->linelen, x1, y1);         // get pointer on start of line          
360
  d= (psd->linelen)>>2;                                 // line size                                         
361
  x1&= 7;
362
  Mask1= Masks[x1];                                     // get end and begining of lines masks
363
  Mask2= Masks2[(x1+x2)&7];
364
  x2= (x1+x2+7)>>3;                                     // get number of full words to write     
365
  c= EColor(c);                                         // get 8 times the color                 
366
  y2-= y1-1;                                            // number of lines to draw 
367
 
368
  switch(x2)                                            // unrolled loop for up to 120 pixels
369
  {
370
    case 0: break;
371
    case 1:  Mask1= Mask1|~Mask2; for (; y2!=0; y2--) { *p= (*p&Mask1)|(c&~Mask1); p+=d; } break;
372
    case 2:  d= d-x2+1; for (; y2!=0; y2--) { *p++= (*p&Mask1)|(c&~Mask1); *p= (*p&~Mask2)|(c&Mask2); p+=d; } break;
373
    case 3:  d= d-x2+1; for (; y2!=0; y2--) { *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p= (*p&~Mask2)|(c&Mask2); p+=d; } break;
374
    case 4:  d= d-x2+1; for (; y2!=0; y2--) { *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); p+=d; } break;
375
    case 5:  d= d-x2+1; for (; y2!=0; y2--) { *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); p+=d; } break;
376
    case 6:  d= d-x2+1; for (; y2!=0; y2--) { *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); p+=d; } break;
377
    case 7:  d= d-x2+1; for (; y2!=0; y2--) { *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); p+=d; } break;
378
    case 8:  d= d-x2+1; for (; y2!=0; y2--) { *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); p+=d; } break;
379
    case 9:  d= d-x2+1; for (; y2!=0; y2--) { *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); p+=d; } break;
380
    case 10: d= d-x2+1; for (; y2!=0; y2--) { *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); p+=d; } break;
381
    case 11: d= d-x2+1; for (; y2!=0; y2--) { *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); p+=d; } break;
382
    case 12: d= d-x2+1; for (; y2!=0; y2--) { *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); p+=d; } break;
383
    case 13: d= d-x2+1; for (; y2!=0; y2--) { *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); p+=d; } break;
384
    case 14: d= d-x2+1; for (; y2!=0; y2--) { *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); p+=d; } break;
385
    case 15: d= d-x2+1; for (; y2!=0; y2--) { *p++= (*p&Mask1)|(c&~Mask1); *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p++= c; *p= (*p&~Mask2)|(c&Mask2); p+=d; } break;
386
    default:
387
             d--; x2-= 2;
388
             for (; y2!=0; y2--)
389
             {
390
               *p++= (*p&Mask1)|(c&~Mask1);                        // write start mask
391
               intset(p, c, x2);                                   // write n time 8 pixels
392
               *(p+x2)= (*(p+x2)&~Mask2)|(c&Mask2);                // write end mask
393
               p+= d;
394
             }
395
            break;
396
  }
397
  DRAWOFF;
398
}
399
 
400
#include "SubRepl.h"                                    // includes all the sub functions of blit
401
 
402
static
403
void linear41_blit(PSD dstpsd, MWCOORD x, MWCOORD y, MWCOORD w, MWCOORD h, PSD srcpsd, MWCOORD sx, MWCOORD sy, long op)
404
{
405
  int ds, ss, shift;
406
  T8p Mask1, Mask2;
407
  // compute source and dest pointers
408
  P8p dData= PPointer(dstpsd->addr, dstpsd->linelen, x, y);
409
  P8p sData= PPointer(srcpsd->addr, srcpsd->linelen, sx, sy);
410
  // compute mask and shift
411
  x&=7; sx&=7;
412
  shift= (x-sx)<<2;
413
  Mask1= Masks[x];        // mask used to select what bellongs to the dest bitmap and source bitmap at the begining of each line
414
  Mask2= Masks2[(x+w)&7]; // mask used to select what bellongs to dest and source bitmap at the end of each line.
415
  // number of full int to work with+1
416
  w= -1+((w+x+7)>>3);
417
  // compute number of workd to skip at end of each line in the source and the destination
418
  ds= (dstpsd->linelen>>2)-w;
419
  ss= (srcpsd->linelen>>2)-w;
420
 
421
//printf("blt x %d y %d sx %d sy %d w %d h%d\r\n", x, y, sx, sy, w, h);
422
  // dispatching on sub functions
423
  if (shift!=0)
424
  {
425
    switch ((4&(shift>>28))|(w>2?3:w)) // sign: bit2, w: bits 0&1
426
    {
427
      case  0: Blt_Shift_Positif_w0(sData, dData, ss, ds, shift, Mask1, Mask2, w-1, h); return;
428
      case  1: Blt_Shift_Positif_w1(sData, dData, ss, ds, shift, Mask1, Mask2, w-1, h); return;
429
      case  2: Blt_Shift_Positif_w2(sData, dData, ss, ds, shift, Mask1, Mask2, w-1, h); return;
430
      case  3: Blt_Shift_Positif   (sData, dData, ss, ds, shift, Mask1, Mask2, w-1, h); return;
431
      case  4: Blt_Shift_Negatif_w0(sData, dData, ss, ds, shift, Mask1, Mask2, w-1, h); return;
432
      case  5: Blt_Shift_Negatif_w1(sData, dData, ss, ds, shift, Mask1, Mask2, w-1, h); return;
433
      case  6: Blt_Shift_Negatif_w2(sData, dData, ss, ds, shift, Mask1, Mask2, w-1, h); return;
434
      case  7: Blt_Shift_Negatif   (sData, dData, ss, ds, shift, Mask1, Mask2, w-1, h); return;
435
      default: return;
436
    }
437
  } else {
438
    switch (w)
439
    {
440
      case 0:  Blt_Shift_Null_w0   (sData, dData, ss, ds, shift, Mask1, Mask2, w-1, h); return;
441
      case 1:  Blt_Shift_Null_w1   (sData, dData, ss, ds, shift, Mask1, Mask2, w-1, h); return;
442
      case 2:  Blt_Shift_Null_w2   (sData, dData, ss, ds, shift, Mask1, Mask2, w-1, h); return;
443
      case 3:  Blt_Shift_Null_w3   (sData, dData, ss, ds, shift, Mask1, Mask2, w-1, h); return;
444
      default: Blt_Shift_Null      (sData, dData, ss, ds, shift, Mask1, Mask2, w-1, h); return;
445
    }
446
  }
447
}
448
 
449
/* srccopy stretchblt*/
450
static void
451
linear4_stretchblit(PSD dstpsd, MWCOORD dstx, MWCOORD dsty, MWCOORD dstw,
452
        MWCOORD dsth, PSD srcpsd, MWCOORD srcx, MWCOORD srcy, MWCOORD srcw,
453
        MWCOORD srch, long op)
454
{
455
        ADDR8   dst;
456
        ADDR8   src;
457
        int     dlinelen = dstpsd->linelen;
458
        int     slinelen = srcpsd->linelen;
459
        int     i, ymax;
460
        int     row_pos, row_inc;
461
        int     col_pos, col_inc;
462
        unsigned char pixel = 0;
463
 
464
        assert (dstpsd->addr != 0);
465
        assert (dstx >= 0 && dstx < dstpsd->xres);
466
        assert (dsty >= 0 && dsty < dstpsd->yres);
467
        assert (dstw > 0);
468
        assert (dsth > 0);
469
        assert (srcpsd->addr != 0);
470
        assert (srcx >= 0 && srcx < srcpsd->xres);
471
        assert (srcy >= 0 && srcy < srcpsd->yres);
472
        assert (srcw > 0);
473
        assert (srch > 0);
474
        assert (dstx+dstw <= dstpsd->xres);
475
        assert (dsty+dsth <= dstpsd->yres);
476
        assert (srcx+srcw <= srcpsd->xres);
477
        assert (srcy+srch <= srcpsd->yres);
478
 
479
        DRAWON;
480
        row_pos = 0x10000;
481
        row_inc = (srch << 16) / dsth;
482
 
483
        /* stretch blit using integer ratio between src/dst height/width*/
484
        for (ymax = dsty+dsth; dsty<ymax; ++dsty) {
485
                MWCOORD dx;
486
                MWCOORD sx;
487
 
488
                /* find source y position*/
489
                while (row_pos >= 0x10000L) {
490
                        ++srcy;
491
                        row_pos -= 0x10000L;
492
                }
493
 
494
                dst = dstpsd->addr + (dstx>>1) + dsty*dlinelen;
495
                src = srcpsd->addr + (srcx>>1) + (srcy-1)*slinelen;
496
 
497
                /* copy a row of pixels*/
498
                col_pos = 0x10000;
499
                col_inc = (srcw << 16) / dstw;
500
                sx = srcx;
501
                dx = dstx;
502
                for (i=0; i<dstw; ++i) {
503
                        /* get source x pixel*/
504
                        while (col_pos >= 0x10000L) {
505
                                //pixel = (*src >> (((sx&1))<<2) ) & 0x0f;
506
                                pixel = (*src >> ((1-(sx&1))<<2) ) & 0x0f;
507
                                if (++sx & 1)
508
                                        ++src;
509
                                col_pos -= 0x10000L;
510
                        }
511
                        *dst = (*dst & notmask[dx&1]) | (pixel << (((dx&1))<<2) );
512
                        //*dst = (*dst & revnotmask[dx&1]) | (pixel << ((1-(dx&1))<<2));
513
                        if (++dx & 1)
514
                                ++dst;
515
                        col_pos += col_inc;
516
                }
517
 
518
                row_pos += row_inc;
519
        }
520
        DRAWOFF;
521
}
522
 
523
#if 1 
524
SUBDRIVER fblinear4 = {
525
        linear4_init,
526
        linear41_drawpixel,
527
        linear4_readpixel,
528
        linear41_drawhorzline,
529
        linear4_drawvertline,
530
        linear41_fillrect,
531
        linear41_blit,
532
        NULL,
533
        linear4_stretchblit
534
};
535
#else
536
SUBDRIVER fblinear4 = {
537
        linear4_init,
538
        linear4_drawpixel,
539
        linear4_readpixel,
540
        linear4_drawhorzline,
541
        linear4_drawvertline,
542
        gen_fillrect,
543
        linear4_blit,
544
        NULL,
545
        linear4_stretchblit
546
};
547
#endif 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.