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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [packages/] [hal/] [arm/] [sa11x0/] [cerfpda/] [v2_0/] [src/] [lcd_support.c] - Blame information for rev 565

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 unneback
//==========================================================================
2
//
3
//        lcd_support.c
4
//
5
//        SA1110/CerfCube - LCD support routines
6
//
7
//==========================================================================
8
//####ECOSGPLCOPYRIGHTBEGIN####
9
// -------------------------------------------
10
// This file is part of eCos, the Embedded Configurable Operating System.
11
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12
//
13
// eCos is free software; you can redistribute it and/or modify it under
14
// the terms of the GNU General Public License as published by the Free
15
// Software Foundation; either version 2 or (at your option) any later version.
16
//
17
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
19
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20
// for more details.
21
//
22
// You should have received a copy of the GNU General Public License along
23
// with eCos; if not, write to the Free Software Foundation, Inc.,
24
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25
//
26
// As a special exception, if other files instantiate templates or use macros
27
// or inline functions from this file, or you compile this file and link it
28
// with other works to produce a work based on this file, this file does not
29
// by itself cause the resulting work to be covered by the GNU General Public
30
// License. However the source code for this file must still be made available
31
// in accordance with section (3) of the GNU General Public License.
32
//
33
// This exception does not invalidate any other reasons why a work based on
34
// this file might be covered by the GNU General Public License.
35
//
36
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37
// at http://sources.redhat.com/ecos/ecos-license/
38
// -------------------------------------------
39
//####ECOSGPLCOPYRIGHTEND####
40
//==========================================================================
41
//#####DESCRIPTIONBEGIN####
42
//
43
// Author(s):     gthomas
44
// Contributors:  gthomas
45
// Date:          2000-06-05
46
// Description:   Tool used to test LCD stuff
47
//####DESCRIPTIONEND####
48
 
49
#include <pkgconf/system.h>
50
 
51
#include <cyg/infra/diag.h>
52
#include <cyg/hal/hal_io.h>       // IO macros
53
#include <cyg/hal/hal_arch.h>     // Register state info
54
#include <cyg/hal/hal_intr.h>     // HAL interrupt macros
55
 
56
#include <cyg/hal/hal_sa11x0.h>   // Board definitions
57
#include <cyg/hal/cerfpda.h>
58
#include <cyg/hal/hal_cache.h>
59
 
60
#ifdef CYGPKG_ISOINFRA
61
# include <pkgconf/isoinfra.h>
62
# ifdef CYGINT_ISO_STDIO_FORMATTED_IO
63
#  include <stdio.h>  // sscanf
64
# endif
65
#endif
66
 
67
#include "banner.xpm"
68
 
69
#ifndef FALSE
70
#define FALSE 0
71
#define TRUE  1
72
#endif
73
 
74
static struct lcd_frame {
75
    unsigned short palette[16];
76
    unsigned short pixels[240][320];
77
    unsigned char  pad[256];
78
} lcd_frame_buffer;
79
 
80
#define RGB_RED(x)   (((x)&0x1F)<<11)
81
#define RGB_GREEN(x) (((x)&0x3F)<<5)
82
#define RGB_BLUE(x)  ((x)&0x1F)
83
 
84
static volatile struct lcd_frame *fp;
85
 
86
static int
87
_hexdigit(char c)
88
{
89
    if ((c >= '0') && (c <= '9')) {
90
        return c - '0';
91
    } else
92
    if ((c >= 'A') && (c <= 'F')) {
93
        return (c - 'A') + 0x0A;
94
    } else
95
    if ((c >= 'a') && (c <= 'f')) {
96
        return (c - 'a') + 0x0a;
97
    }
98
}
99
 
100
static int
101
_hex(char *cp)
102
{
103
    return (_hexdigit(*cp)<<4) | _hexdigit(*(cp+1));
104
}
105
 
106
static unsigned short
107
parse_color(char *cp)
108
{
109
    int red, green, blue;
110
 
111
    if (*cp == '#') {
112
        red = _hex(cp+1);
113
        green = _hex(cp+3);
114
        blue = _hex(cp+5);
115
        return RGB_RED(red>>3) | RGB_GREEN(green>>2) | RGB_BLUE(blue>>3);
116
    } else {
117
        // Should be "None"
118
        return 0xFFFF;
119
    }
120
}
121
 
122
#ifndef CYGINT_ISO_STDIO_FORMATTED_IO
123
static int
124
get_int(char **_cp)
125
{
126
    char *cp = *_cp;
127
    char c;
128
    int val = 0;
129
 
130
    while ((c = *cp++) && (c != ' ')) {
131
        if ((c >= '0') && (c <= '9')) {
132
            val = val * 10 + (c - '0');
133
        } else {
134
            return -1;
135
        }
136
    }
137
    *_cp = cp;
138
    return val;
139
}
140
#endif
141
 
142
void
143
show_xpm(char *xpm[])
144
{
145
    int i, row, col;
146
    char *cp;
147
    int nrows, ncols, nclrs;
148
    unsigned short colors[256];  // Mapped by character index
149
 
150
    cp = xpm[0];
151
#ifdef CYGINT_ISO_STDIO_FORMATTED_IO
152
    if (sscanf(cp, "%d %d %d", &ncols, &nrows, &nclrs) != 3) {
153
#else
154
    if (((ncols = get_int(&cp)) < 0) ||
155
        ((nrows = get_int(&cp)) < 0) ||
156
        ((nclrs = get_int(&cp)) < 0)) {
157
#endif
158
        diag_printf("Can't parse XPM data, sorry\n");
159
        return;
160
    }
161
    //    diag_printf("%d rows, %d cols, %d colors\n", nrows, ncols, nclrs);
162
 
163
    for (i = 0;  i < 256;  i++) {
164
        colors[i] = 0x0000;
165
    }
166
    for (i = 0;  i < nclrs;  i++) {
167
        cp = xpm[i+1];
168
        colors[(unsigned int)*cp] = parse_color(&cp[4]);
169
//        printf("Color[%c] = %x\n", *cp, colors[(unsigned int)*cp]);
170
    }
171
 
172
    for (row = 0;  row < nrows;  row++) {
173
        cp = xpm[nclrs+1+row];
174
        for (col = 0;  col < ncols;  col++) {
175
            fp->pixels[row][col] = colors[(unsigned int)*cp++];
176
        }
177
    }
178
    //    cyg_thread_delay(100);
179
}
180
 
181
// 8x8 Font - from Helios
182
 
183
#define FIRST_CHAR 0x20
184
#define LAST_CHAR  0x7E
185
#define FONT_HEIGHT 8
186
#define FONT_WIDTH  8
187
#define CURSOR_ON  0x5F
188
#define CURSOR_OFF 0x20
189
static const char font_table[LAST_CHAR-FIRST_CHAR+1][8] =
190
{
191
        {        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /*   */
192
        {        0x18, 0x18, 0x18, 0x18, 0x18, 0x00, 0x18, 0x00 }, /* ! */
193
        {        0x36, 0x36, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* " */
194
        {        0x6C, 0x6C, 0xFE, 0x6C, 0xFE, 0x6C, 0x6C, 0x00 }, /* # */
195
        {        0x30, 0xFC, 0x16, 0x7C, 0xD0, 0x7E, 0x18, 0x00 }, /* $ */
196
        {        0x06, 0x66, 0x30, 0x18, 0x0C, 0x66, 0x60, 0x00 }, /* % */
197
        {        0x1C, 0x36, 0x36, 0x1C, 0xB6, 0x66, 0xDC, 0x00 }, /* & */
198
        {        0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* ' */
199
        {        0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x18, 0x30, 0x00 }, /* ( */
200
        {        0x0C, 0x18, 0x30, 0x30, 0x30, 0x18, 0x0C, 0x00 }, /* ) */
201
        {        0x00, 0x18, 0x7E, 0x3C, 0x7E, 0x18, 0x00, 0x00 }, /* * */
202
        {        0x00, 0x18, 0x18, 0x7E, 0x18, 0x18, 0x00, 0x00 }, /* + */
203
        {        0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x0C }, /* , */
204
        {        0x00, 0x00, 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00 }, /* - */
205
        {        0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x00 }, /* . */
206
        {        0x00, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x00, 0x00 }, /* / */
207
        {        0x3C, 0x66, 0x76, 0x7E, 0x6E, 0x66, 0x3C, 0x00 }, /* 0 */
208
        {        0x18, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00 }, /* 1 */
209
        {        0x3C, 0x66, 0x60, 0x30, 0x18, 0x0C, 0x7E, 0x00 }, /* 2 */
210
        {        0x3C, 0x66, 0x60, 0x38, 0x60, 0x66, 0x3C, 0x00 }, /* 3 */
211
        {        0x30, 0x38, 0x3C, 0x36, 0x7E, 0x30, 0x30, 0x00 }, /* 4 */
212
        {        0x7E, 0x06, 0x3E, 0x60, 0x60, 0x66, 0x3C, 0x00 }, /* 5 */
213
        {        0x38, 0x0C, 0x06, 0x3E, 0x66, 0x66, 0x3C, 0x00 }, /* 6 */
214
        {        0x7E, 0x60, 0x30, 0x18, 0x0C, 0x0C, 0x0C, 0x00 }, /* 7 */
215
        {        0x3C, 0x66, 0x66, 0x3C, 0x66, 0x66, 0x3C, 0x00 }, /* 8 */
216
        {        0x3C, 0x66, 0x66, 0x7C, 0x60, 0x30, 0x1C, 0x00 }, /* 9 */
217
        {        0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x00 }, /* : */
218
        {        0x00, 0x00, 0x18, 0x18, 0x00, 0x18, 0x18, 0x0C }, /* ; */
219
        {        0x30, 0x18, 0x0C, 0x06, 0x0C, 0x18, 0x30, 0x00 }, /* < */
220
        {        0x00, 0x00, 0x7E, 0x00, 0x7E, 0x00, 0x00, 0x00 }, /* = */
221
        {        0x0C, 0x18, 0x30, 0x60, 0x30, 0x18, 0x0C, 0x00 }, /* > */
222
        {        0x3C, 0x66, 0x30, 0x18, 0x18, 0x00, 0x18, 0x00 }, /* ? */
223
        {        0x3C, 0x66, 0x76, 0x56, 0x76, 0x06, 0x3C, 0x00 }, /* @ */
224
        {        0x3C, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00 }, /* A */
225
        {        0x3E, 0x66, 0x66, 0x3E, 0x66, 0x66, 0x3E, 0x00 }, /* B */
226
        {        0x3C, 0x66, 0x06, 0x06, 0x06, 0x66, 0x3C, 0x00 }, /* C */
227
        {        0x1E, 0x36, 0x66, 0x66, 0x66, 0x36, 0x1E, 0x00 }, /* D */
228
        {        0x7E, 0x06, 0x06, 0x3E, 0x06, 0x06, 0x7E, 0x00 }, /* E */
229
        {        0x7E, 0x06, 0x06, 0x3E, 0x06, 0x06, 0x06, 0x00 }, /* F */
230
        {        0x3C, 0x66, 0x06, 0x76, 0x66, 0x66, 0x3C, 0x00 }, /* G */
231
        {        0x66, 0x66, 0x66, 0x7E, 0x66, 0x66, 0x66, 0x00 }, /* H */
232
        {        0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x7E, 0x00 }, /* I */
233
        {        0x7C, 0x30, 0x30, 0x30, 0x30, 0x36, 0x1C, 0x00 }, /* J */
234
        {        0x66, 0x36, 0x1E, 0x0E, 0x1E, 0x36, 0x66, 0x00 }, /* K */
235
        {        0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x7E, 0x00 }, /* L */
236
        {        0xC6, 0xEE, 0xFE, 0xD6, 0xD6, 0xC6, 0xC6, 0x00 }, /* M */
237
        {        0x66, 0x66, 0x6E, 0x7E, 0x76, 0x66, 0x66, 0x00 }, /* N */
238
        {        0x3C, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00 }, /* O */
239
        {        0x3E, 0x66, 0x66, 0x3E, 0x06, 0x06, 0x06, 0x00 }, /* P */
240
        {        0x3C, 0x66, 0x66, 0x66, 0x56, 0x36, 0x6C, 0x00 }, /* Q */
241
        {        0x3E, 0x66, 0x66, 0x3E, 0x36, 0x66, 0x66, 0x00 }, /* R */
242
        {        0x3C, 0x66, 0x06, 0x3C, 0x60, 0x66, 0x3C, 0x00 }, /* S */
243
        {        0x7E, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00 }, /* T */
244
        {        0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x00 }, /* U */
245
        {        0x66, 0x66, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00 }, /* V */
246
        {        0xC6, 0xC6, 0xD6, 0xD6, 0xFE, 0xEE, 0xC6, 0x00 }, /* W */
247
        {        0x66, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x66, 0x00 }, /* X */
248
        {        0x66, 0x66, 0x66, 0x3C, 0x18, 0x18, 0x18, 0x00 }, /* Y */
249
        {        0x7E, 0x60, 0x30, 0x18, 0x0C, 0x06, 0x7E, 0x00 }, /* Z */
250
        {        0x3E, 0x06, 0x06, 0x06, 0x06, 0x06, 0x3E, 0x00 }, /* [ */
251
        {        0x00, 0x06, 0x0C, 0x18, 0x30, 0x60, 0x00, 0x00 }, /* \ */
252
        {        0x7C, 0x60, 0x60, 0x60, 0x60, 0x60, 0x7C, 0x00 }, /* ] */
253
        {        0x3C, 0x66, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* ^ */
254
        {        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF }, /* _ */
255
        {        0x0C, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }, /* ` */
256
        {        0x00, 0x00, 0x3C, 0x60, 0x7C, 0x66, 0x7C, 0x00 }, /* a */
257
        {        0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x3E, 0x00 }, /* b */
258
        {        0x00, 0x00, 0x3C, 0x66, 0x06, 0x66, 0x3C, 0x00 }, /* c */
259
        {        0x60, 0x60, 0x7C, 0x66, 0x66, 0x66, 0x7C, 0x00 }, /* d */
260
        {        0x00, 0x00, 0x3C, 0x66, 0x7E, 0x06, 0x3C, 0x00 }, /* e */
261
        {        0x38, 0x0C, 0x0C, 0x3E, 0x0C, 0x0C, 0x0C, 0x00 }, /* f */
262
        {        0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0x3C }, /* g */
263
        {        0x06, 0x06, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x00 }, /* h */
264
        {        0x18, 0x00, 0x1C, 0x18, 0x18, 0x18, 0x3C, 0x00 }, /* i */
265
        {        0x18, 0x00, 0x1C, 0x18, 0x18, 0x18, 0x18, 0x0E }, /* j */
266
        {        0x06, 0x06, 0x66, 0x36, 0x1E, 0x36, 0x66, 0x00 }, /* k */
267
        {        0x1C, 0x18, 0x18, 0x18, 0x18, 0x18, 0x3C, 0x00 }, /* l */
268
        {        0x00, 0x00, 0x6C, 0xFE, 0xD6, 0xD6, 0xC6, 0x00 }, /* m */
269
        {        0x00, 0x00, 0x3E, 0x66, 0x66, 0x66, 0x66, 0x00 }, /* n */
270
        {        0x00, 0x00, 0x3C, 0x66, 0x66, 0x66, 0x3C, 0x00 }, /* o */
271
        {        0x00, 0x00, 0x3E, 0x66, 0x66, 0x3E, 0x06, 0x06 }, /* p */
272
        {        0x00, 0x00, 0x7C, 0x66, 0x66, 0x7C, 0x60, 0xE0 }, /* q */
273
        {        0x00, 0x00, 0x36, 0x6E, 0x06, 0x06, 0x06, 0x00 }, /* r */
274
        {        0x00, 0x00, 0x7C, 0x06, 0x3C, 0x60, 0x3E, 0x00 }, /* s */
275
        {        0x0C, 0x0C, 0x3E, 0x0C, 0x0C, 0x0C, 0x38, 0x00 }, /* t */
276
        {        0x00, 0x00, 0x66, 0x66, 0x66, 0x66, 0x7C, 0x00 }, /* u */
277
        {        0x00, 0x00, 0x66, 0x66, 0x66, 0x3C, 0x18, 0x00 }, /* v */
278
        {        0x00, 0x00, 0xC6, 0xD6, 0xD6, 0xFE, 0x6C, 0x00 }, /* w */
279
        {        0x00, 0x00, 0x66, 0x3C, 0x18, 0x3C, 0x66, 0x00 }, /* x */
280
        {        0x00, 0x00, 0x66, 0x66, 0x66, 0x7C, 0x60, 0x3C }, /* y */
281
        {        0x00, 0x00, 0x7E, 0x30, 0x18, 0x0C, 0x7E, 0x00 }, /* z */
282
        {        0x30, 0x18, 0x18, 0x0E, 0x18, 0x18, 0x30, 0x00 }, /* { */
283
        {        0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00 }, /* | */
284
        {        0x0C, 0x18, 0x18, 0x70, 0x18, 0x18, 0x0C, 0x00 }, /* } */
285
        {        0x8C, 0xD6, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00 }  /* ~ */
286
};
287
 
288
#define LCD_WIDTH  320
289
#define LCD_HEIGHT 240
290
#define LCD_DEPTH   16
291
 
292
// This can be 1 or 2
293
#define SCREEN_SCALE 2
294
#define NIBBLES_PER_PIXEL (1*SCREEN_SCALE)
295
#define PIXELS_PER_BYTE (2/NIBBLES_PER_PIXEL)
296
#define PIXEL_MASK      ((1<<PIXELS_PER_BYTE)-1)
297
 
298
// Physical screen info
299
//static int lcd_depth  = LCD_DEPTH;  // Should be 1, 2, or 4
300
static int lcd_width  = LCD_WIDTH;
301
static int lcd_height = LCD_HEIGHT;
302
 
303
// Virtual screen info
304
static int curX = 0;  // Last used position
305
static int curY = 0;
306
//static int width = LCD_WIDTH / (FONT_WIDTH*NIBBLES_PER_PIXEL);
307
//static int height = LCD_HEIGHT / (FONT_HEIGHT*SCREEN_SCALE);
308
static int fg = RGB_RED(0) | RGB_GREEN(0) | RGB_BLUE(0);
309
static int bg = RGB_RED(31) | RGB_GREEN(63) | RGB_BLUE(31);
310
#define SCREEN_WIDTH  (LCD_WIDTH/FONT_WIDTH)
311
#define SCREEN_HEIGHT (LCD_HEIGHT/FONT_HEIGHT)
312
static char screen[SCREEN_HEIGHT][SCREEN_WIDTH];
313
#define SCREEN_START 7
314
 
315
// Functions
316
static void lcd_drawc(cyg_int8 c, int x, int y);
317
 
318
void
319
lcd_init(int depth)
320
{
321
    // Currently only color/16bpp supported
322
 
323
    unsigned long _fp;
324
 
325
    // Frame buffer must be aligned on a 16 byte boundary
326
    _fp = (((unsigned long)&lcd_frame_buffer) + 15) & ~15;
327
    fp = (struct lcd_frame *)(_fp + SA11X0_RAM_BANK0_BASE);
328
    // Enable LCD in 320x240 16bpp
329
    *SA1110_DBAR1 = (unsigned long)&(fp->palette);
330
    *SA1110_LCCR1 = 0x1D1D0930;
331
    *SA1110_LCCR2 = 0xEF;
332
    *SA1110_LCCR3 = 0x0c;
333
    fp->palette[0] = 0x2000;  // Tell controller 16 bits
334
//    *SA1110_LCCR0 = 0xBB;  // B&W
335
    *SA1110_LCCR0 = 0xB9;  // Color
336
//    cerfpda_BCR(SA1110_BCR_LCD_BPP, SA1110_BCR_LCD_12BPP);
337
    cerfpda_BCR(SA1110_BCR_LCD_BPP, SA1110_BCR_LCD_16BPP);
338
    cerfpda_BCR(SA1110_BCR_LCD, SA1110_BCR_LCD_ON);
339
    cerfpda_BCR(SA1110_BCR_BACKLIGHT, SA1110_BCR_BACKLIGHT);
340
}
341
 
342
// Clear screen
343
void
344
lcd_clear(void)
345
{
346
    int row, col;
347
    for (row = 0;  row < lcd_height;  row++) {
348
        for (col = 0;  col < lcd_width;  col++) {
349
            fp->pixels[row][col] = bg;
350
        }
351
    }
352
    for (row = 0;  row < SCREEN_HEIGHT;  row++) {
353
        for (col = 0;  col < SCREEN_WIDTH;  col++) {
354
            screen[row][col] = ' ';
355
        }
356
    }
357
    // Note: Row 0 seems to wrap incorrectly
358
    curX = 0;  curY = SCREEN_START;
359
    lcd_drawc(CURSOR_ON, curX, curY);
360
    show_xpm(banner_xpm);
361
}
362
 
363
// Position cursor
364
void
365
lcd_moveto(int X, int Y)
366
{
367
    lcd_drawc(CURSOR_OFF, curX, curY);
368
    if (X < 0) X = 0;
369
    if (X >= SCREEN_WIDTH) X = SCREEN_WIDTH-1;
370
    curX = X;
371
    if (Y < SCREEN_START) Y = SCREEN_START;
372
    if (Y >= SCREEN_HEIGHT) Y = SCREEN_HEIGHT-1;
373
    curY = Y;
374
    lcd_drawc(CURSOR_ON, curX, curY);
375
}
376
 
377
// Render a character at position (X,Y) with current background/foreground
378
static void
379
lcd_drawc(cyg_int8 c, int x, int y)
380
{
381
    // Currently hard-coded for 16bpp
382
    cyg_uint8 bits;
383
    cyg_uint16 *pixels;
384
    int l, p;
385
 
386
    screen[curY][curX] = c;
387
    for (l = 0;  l < FONT_HEIGHT;  l++) {
388
        bits = font_table[c-FIRST_CHAR][l];
389
        pixels = &fp->pixels[curY*FONT_HEIGHT+l][curX*FONT_WIDTH];
390
        for (p = 0;  p < 8;  p++) {
391
            if (bits & 0x01) {
392
                *pixels++ = fg;
393
            } else {
394
                *pixels++ = bg;
395
            }
396
            bits >>= 1;
397
        }
398
    }
399
}
400
 
401
static void
402
lcd_scroll(void)
403
{
404
    int row, col;
405
    cyg_uint8 *c1, *c2;
406
    cyg_uint16 *p1, *p2;
407
 
408
    // First scroll up the virtual screen
409
    for (row = SCREEN_START;  row < SCREEN_HEIGHT;  row++) {
410
        c1 = &screen[row-1][0];
411
        c2 = &screen[row][0];
412
        for (col = 0;  col < SCREEN_WIDTH;  col++) {
413
            *c1++ = *c2++;
414
        }
415
    }
416
    c1 = &screen[SCREEN_HEIGHT-1][0];
417
    for (col = 0;  col < SCREEN_WIDTH;  col++) {
418
        *c1++ = 0x20;
419
    }
420
    // Now the physical screen
421
    for (row = FONT_HEIGHT*(SCREEN_START+1);  row < LCD_HEIGHT;  row++) {
422
        p1 = &fp->pixels[row-FONT_HEIGHT][0];
423
        p2 = &fp->pixels[row][0];
424
        for (col = 0;  col < LCD_WIDTH;  col++) {
425
            *p1++ = *p2++;
426
        }
427
    }
428
    for (row = LCD_HEIGHT-FONT_HEIGHT;  row < LCD_HEIGHT;  row++) {
429
        p1 = &fp->pixels[row][0];
430
        for (col = 0;  col < LCD_WIDTH;  col++) {
431
            *p1++ = bg;
432
        }
433
    }
434
}
435
 
436
// Draw one character at the current position
437
void
438
lcd_putc(cyg_int8 c)
439
{
440
    lcd_drawc(CURSOR_OFF, curX, curY);
441
    switch (c) {
442
    case '\r':
443
        curX = 0;
444
        break;
445
    case '\n':
446
        curY++;
447
        if (curY == SCREEN_HEIGHT) {
448
            lcd_scroll();
449
            curY--;
450
        }
451
        break;
452
    case '\b':
453
        curX--;
454
        if (curX < 0) {
455
            curY--;
456
            if (curY < 0) curY = 0;
457
            curX = SCREEN_WIDTH-1;
458
        }
459
        break;
460
    default:
461
        lcd_drawc(c, curX, curY);
462
        curX++;
463
        if (curX == SCREEN_WIDTH) {
464
            curY++;
465
            curX = 0;
466
        }
467
    }
468
    lcd_drawc(CURSOR_ON, curX, curY);
469
}
470
 
471
// Basic LCD 'printf()' support
472
 
473
#include <stdarg.h>
474
 
475
#define is_digit(c) ((c >= '0') && (c <= '9'))
476
 
477
static int
478
_cvt(unsigned long val, char *buf, long radix, char *digits)
479
{
480
    char temp[80];
481
    char *cp = temp;
482
    int length = 0;
483
    if (val == 0) {
484
        /* Special case */
485
        *cp++ = '0';
486
    } else {
487
        while (val) {
488
            *cp++ = digits[val % radix];
489
            val /= radix;
490
        }
491
    }
492
    while (cp != temp) {
493
        *buf++ = *--cp;
494
        length++;
495
    }
496
    *buf = '\0';
497
    return (length);
498
}
499
 
500
int
501
lcd_vprintf(void (*putc)(cyg_int8), const char *fmt0, va_list ap)
502
{
503
    char c, sign, *cp;
504
    int left_prec, right_prec, zero_fill, length, pad, pad_on_right;
505
    char buf[32];
506
    long val;
507
    while ((c = *fmt0++)) {
508
        cp = buf;
509
        length = 0;
510
        if (c == '%') {
511
            c = *fmt0++;
512
            left_prec = right_prec = pad_on_right = 0;
513
            if (c == '-') {
514
                c = *fmt0++;
515
                pad_on_right++;
516
            }
517
            if (c == '0') {
518
                zero_fill = TRUE;
519
                c = *fmt0++;
520
            } else {
521
                zero_fill = FALSE;
522
            }
523
            while (is_digit(c)) {
524
                left_prec = (left_prec * 10) + (c - '0');
525
                c = *fmt0++;
526
            }
527
            if (c == '.') {
528
                c = *fmt0++;
529
                zero_fill++;
530
                while (is_digit(c)) {
531
                    right_prec = (right_prec * 10) + (c - '0');
532
                    c = *fmt0++;
533
                }
534
            } else {
535
                right_prec = left_prec;
536
            }
537
            sign = '\0';
538
            switch (c) {
539
            case 'd':
540
            case 'x':
541
            case 'X':
542
                val = va_arg(ap, long);
543
                switch (c) {
544
                case 'd':
545
                    if (val < 0) {
546
                        sign = '-';
547
                        val = -val;
548
                    }
549
                    length = _cvt(val, buf, 10, "0123456789");
550
                    break;
551
                case 'x':
552
                    length = _cvt(val, buf, 16, "0123456789abcdef");
553
                    break;
554
                case 'X':
555
                    length = _cvt(val, buf, 16, "0123456789ABCDEF");
556
                    break;
557
                }
558
                break;
559
            case 's':
560
                cp = va_arg(ap, char *);
561
                length = strlen(cp);
562
                break;
563
            case 'c':
564
                c = va_arg(ap, long /*char*/);
565
                (*putc)(c);
566
                continue;
567
            default:
568
                (*putc)('?');
569
            }
570
            pad = left_prec - length;
571
            if (sign != '\0') {
572
                pad--;
573
            }
574
            if (zero_fill) {
575
                c = '0';
576
                if (sign != '\0') {
577
                    (*putc)(sign);
578
                    sign = '\0';
579
                }
580
            } else {
581
                c = ' ';
582
            }
583
            if (!pad_on_right) {
584
                while (pad-- > 0) {
585
                    (*putc)(c);
586
                }
587
            }
588
            if (sign != '\0') {
589
                (*putc)(sign);
590
            }
591
            while (length-- > 0) {
592
                (*putc)(c = *cp++);
593
                if (c == '\n') {
594
                    (*putc)('\r');
595
                }
596
            }
597
            if (pad_on_right) {
598
                while (pad-- > 0) {
599
                    (*putc)(' ');
600
                }
601
            }
602
        } else {
603
            (*putc)(c);
604
            if (c == '\n') {
605
                (*putc)('\r');
606
            }
607
        }
608
    }
609
}
610
 
611
int
612
lcd_printf(char const *fmt, ...)
613
{
614
        int ret;
615
        va_list ap;
616
 
617
        va_start(ap, fmt);
618
        ret = lcd_vprintf(lcd_putc, fmt, ap);
619
        va_end(ap);
620
        return (ret);
621
}
622
 
623
void
624
set_bg(int red, int green, int blue)
625
{
626
    bg = RGB_RED(red) | RGB_GREEN(green) | RGB_BLUE(blue);
627
}
628
 
629
void
630
set_fg(int red, int green, int blue)
631
{
632
    fg = RGB_RED(red) | RGB_GREEN(green) | RGB_BLUE(blue);
633
}

powered by: WebSVN 2.1.0

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