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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-3.0/] [packages/] [hal/] [arm/] [sa11x0/] [cerfpda/] [current/] [src/] [lcd_support.c] - Blame information for rev 856

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

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

powered by: WebSVN 2.1.0

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