Notice: We have migrated to GitLab launching 2024-05-01 see here: https://gitlab.rtems.org/

NewTicket: cfb_console.c

File cfb_console.c, 30.0 KB (added by ostyche, on 02/09/22 at 13:45:54)
Line 
1/*
2 * (C) Copyright 2002 ELTEC Elektronik AG
3 * Frank Gottschling <fgottschling@eltec.de>
4 *
5 * See file CREDITS for list of people who contributed to this
6 * project.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License as
10 * published by the Free Software Foundation; either version 2 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
21 * MA 02111-1307 USA
22 */
23
24/*
25 * cfb_console.c
26 *
27 * Color Framebuffer Console driver for 8/15/16/24/32 bits per pixel.
28 *
29 * At the moment only the 8x16 font is tested and the font fore- and
30 * background color is limited to black/white/gray colors. The Linux
31 * logo can be placed in the upper left corner and additional board
32 * information strings (that normaly goes to serial port) can be drawed.
33 *
34 * The console driver can use the standard PC keyboard interface (i8042)
35 * for character input. Character output goes to a memory mapped video
36 * framebuffer with little or big-endian organisation.
37 * With environment setting 'console=serial' the console i/o can be
38 * forced to serial port.
39
40 The driver uses graphic specific defines/parameters/functions:
41
42 (for SMI LynxE graphic chip)
43
44 CONFIG_VIDEO_SMI_LYNXEM - use graphic driver for SMI 710,712,810
45 VIDEO_FB_LITTLE_ENDIAN  - framebuffer organisation default: big endian
46 VIDEO_HW_RECTFILL       - graphic driver supports hardware rectangle fill
47 VIDEO_HW_BITBLT         - graphic driver supports hardware bit blt
48
49 Console Parameters are set by graphic drivers global struct:
50
51 VIDEO_VISIBLE_COLS          - x resolution
52 VIDEO_VISIBLE_ROWS          - y resolution
53 VIDEO_PIXEL_SIZE            - storage size in byte per pixel
54 VIDEO_DATA_FORMAT           - graphical data format GDF
55 VIDEO_FB_ADRS               - start of video memory
56
57 CONFIG_I8042_KBD            - AT Keyboard driver for i8042
58 VIDEO_KBD_INIT_FCT          - init function for keyboard
59 VIDEO_TSTC_FCT              - keyboard_tstc function
60 VIDEO_GETC_FCT              - keyboard_getc function
61
62 CONFIG_CONSOLE_CURSOR       - on/off drawing cursor is done with delay
63                               loop in VIDEO_TSTC_FCT (i8042)
64 CFG_CONSOLE_BLINK_COUNT     - value for delay loop - blink rate
65 CONFIG_CONSOLE_TIME         - display time/date in upper right corner,
66                               needs CFG_CMD_DATE and CONFIG_CONSOLE_CURSOR
67 CONFIG_VIDEO_LOGO           - display Linux Logo in upper left corner
68 CONFIG_VIDEO_BMP_LOGO       - use bmp_logo instead of linux_logo
69 CONFIG_CONSOLE_EXTRA_INFO   - display additional board information strings
70                               that normaly goes to serial port. This define
71                               requires a board specific function:
72                               video_drawstring (VIDEO_INFO_X,
73                                                 VIDEO_INFO_Y + i*VIDEO_FONT_HEIGHT,
74                                                 info);
75                               that fills a info buffer at i=row.
76                               s.a: board/eltec/bab7xx.
77CONFIG_VGA_AS_SINGLE_DEVICE  - If set the framebuffer device will be initialised
78                               as an output only device. The Keyboard driver
79                               will not be set-up. This may be used, if you
80                               have none or more than one Keyboard devices
81                               (USB Keyboard, AT Keyboard).
82
83CONFIG_VIDEO_SW_CURSOR:      - Draws a cursor after the last character. No
84                               blinking is provided. Uses the macros CURSOR_SET
85                               and CURSOR_OFF.
86CONFIG_VIDEO_HW_CURSOR:      - Uses the hardware cursor capability of the
87                               graphic chip. Uses the macro CURSOR_SET.
88                               ATTENTION: If booting an OS, the display driver
89                               must disable the hardware register of the graphic
90                               chip. Otherwise a blinking field is displayed
91*/
92
93/* this is software sursor shape.it can be modified*/
94#define SOFTWARECURSOR  219
95
96#include <rtems.h>
97
98/*****************************************************************************/
99/* some Macros                                                               */
100/*****************************************************************************/
101
102#define X800x600
103
104/*
105 * Graphic Data Format (GDF) bits for VIDEO_DATA_FORMAT
106 */
107#define GDF__8BIT_INDEX         0
108#define GDF_15BIT_555RGB        1
109#define GDF_16BIT_565RGB        2
110#define GDF_32BIT_X888RGB       3
111#define GDF_24BIT_888RGB        4
112#define GDF__8BIT_332RGB        5
113#define GDF__1BIT               6
114#define GDF__2BIT               7
115#define GDF__4BIT               8
116
117#if defined(X800x600)
118#define VIDEO_VISIBLE_COLS      800
119#define VIDEO_VISIBLE_ROWS      600
120#elif defined(X1024x768)
121#define VIDEO_VISIBLE_COLS      1024
122#define VIDEO_VISIBLE_ROWS      768
123#elif defined(X1280x1024)
124#define VIDEO_VISIBLE_COLS      1280
125#define VIDEO_VISIBLE_ROWS      1024
126#elif defined(X640x480)
127#define VIDEO_VISIBLE_COLS      640
128#define VIDEO_VISIBLE_ROWS      480
129#endif
130
131#define VIDEO_PIXEL_SIZE        2
132#define VIDEO_DATA_FORMAT       GDF_16BIT_565RGB
133#define VIDEO_FB_ADRS           0xc0000000
134
135/*****************************************************************************/
136/* Console device                                                            */
137/*****************************************************************************/
138
139#include "video_font.h"
140
141#define VIDEO_COLS              VIDEO_VISIBLE_COLS
142#define VIDEO_ROWS              VIDEO_VISIBLE_ROWS
143#if  defined(CONFIG_VIDEO_1BPP)
144#define VIDEO_SIZE              (VIDEO_ROWS*VIDEO_COLS*VIDEO_PIXEL_SIZE/8)
145#define VIDEO_LINE_LEN          (VIDEO_COLS*VIDEO_PIXEL_SIZE/8)
146#elif   defined(CONFIG_VIDEO_2BPP)
147#define VIDEO_SIZE              (VIDEO_ROWS*VIDEO_COLS*VIDEO_PIXEL_SIZE/4)
148#define VIDEO_LINE_LEN          (VIDEO_COLS*VIDEO_PIXEL_SIZE/4)
149#elif   defined(CONFIG_VIDEO_4BPP)
150#define VIDEO_SIZE              (VIDEO_ROWS*VIDEO_COLS*VIDEO_PIXEL_SIZE/2)
151#define VIDEO_LINE_LEN          (VIDEO_COLS*VIDEO_PIXEL_SIZE/2)
152#else
153#define VIDEO_SIZE              (VIDEO_ROWS*VIDEO_COLS*VIDEO_PIXEL_SIZE)
154#define VIDEO_LINE_LEN          (VIDEO_COLS*VIDEO_PIXEL_SIZE)
155#endif
156#define VIDEO_PIX_BLOCKS        (VIDEO_SIZE >> 2)
157#define VIDEO_BURST_LEN         (VIDEO_COLS/8)
158
159#define CONSOLE_ROWS            (VIDEO_ROWS / VIDEO_FONT_HEIGHT)
160
161#define CONSOLE_COLS            (VIDEO_COLS / VIDEO_FONT_WIDTH)
162#define CONSOLE_ROW_SIZE        (VIDEO_FONT_HEIGHT * VIDEO_LINE_LEN)
163#define CONSOLE_ROW_FIRST       (video_console_address)
164#define CONSOLE_ROW_SECOND      (video_console_address + CONSOLE_ROW_SIZE)
165#define CONSOLE_ROW_LAST        (video_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE)
166/* #define CONSOLE_SIZE         (CONSOLE_ROW_SIZE * CONSOLE_ROWS) */
167#if  defined(CONFIG_VIDEO_1BPP)
168#define CONSOLE_SIZE            (VIDEO_COLS * VIDEO_ROWS * VIDEO_PIXEL_SIZE/8)
169#elif   defined(CONFIG_VIDEO_2BPP)
170#define CONSOLE_SIZE            (VIDEO_COLS * VIDEO_ROWS * VIDEO_PIXEL_SIZE/4)
171#elif   defined(CONFIG_VIDEO_4BPP)
172#define CONSOLE_SIZE            (VIDEO_COLS * VIDEO_ROWS * VIDEO_PIXEL_SIZE/2)
173#else
174#define CONSOLE_SIZE            (VIDEO_COLS * VIDEO_ROWS * VIDEO_PIXEL_SIZE)
175#endif
176
177#define CONSOLE_SCROLL_SIZE     (CONSOLE_SIZE - CONSOLE_ROW_SIZE)
178
179/* Macros */
180#ifdef  VIDEO_FB_LITTLE_ENDIAN
181#define BYTESWAP32(x)   (x)
182#define SWAP16(x)        ((((x) & 0x00ff) << 8) | ( (x) >> 8))
183#define SWAP32(x)        ((((x) & 0x000000ff) << 24) | (((x) & 0x0000ff00) << 8)|\
184                      (((x) & 0x00ff0000) >>  8) | (((x) & 0xff000000) >> 24) )
185#define SHORTSWAP32(x)   ((((x) & 0x000000ff) <<  8) | (((x) & 0x0000ff00) >> 8)|\
186                          (((x) & 0x00ff0000) <<  8) | (((x) & 0xff000000) >> 8) )
187#else
188#define BYTESWAP32(x)    ((((x) & 0x000000ff) <<  24) | (((x) & 0x0000ff00) << 8)|\
189                          (((x) & 0x00ff0000) >>  8) | (((x) & 0xff000000) >> 24) )
190#define SWAP16(x)        (x)
191#define SWAP32(x)        (x)
192#define SHORTSWAP32(x)   (x)
193#endif
194
195#define CURSOR_SET
196#define CURSOR_OFF
197#define CONSOLE_BG_COL            0x00
198#define CONSOLE_FG_COL            0xff
199#define VIDEO_LOGO_HEIGHT       0
200
201#if defined(DEBUG) || defined(DEBUG_CFB_CONSOLE)
202#define PRINTD(x)         printk(x)
203#else
204#define PRINTD(x)
205#endif
206
207
208static volatile unsigned char *video_fb_address = ( volatile unsigned char * )VIDEO_FB_ADRS;            /* frame buffer address */
209static volatile unsigned char *video_console_address = ( volatile unsigned char * )VIDEO_FB_ADRS;       /* console buffer start address */
210
211#ifndef VIDEO_HW_BITBLT
212#ifndef MEM_PRINTTO_VIDEO
213#define MEM_PRINTTO_VIDEO
214static char memfb[CONSOLE_ROWS *CONSOLE_COLS];
215#endif
216#endif
217
218static int console_col = 0; /* cursor col */
219static int console_row = 0; /* cursor row */
220unsigned int eorx, fgx, bgx;  /* color pats */
221
222static const char video_font_draw_table2[] =
223{
224        0x00, 0x03, 0x0c, 0x0f,
225        0x30, 0x33, 0x3c, 0x3f,
226        0xc0, 0xc3, 0xcc, 0xcf,
227        0xf0, 0xf3, 0xfc, 0xff
228};
229static const char video_font_draw_table4[] =
230{
231        0x00, 0x0f, 0xf0, 0xff
232};
233static const int video_font_draw_table8[] =
234{
235        0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff,
236        0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff,
237        0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff,
238        0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff
239};
240
241static const int video_font_draw_table15[] =
242{
243        0x00000000, 0x00007fff, 0x7fff0000, 0x7fff7fff
244};
245
246static const int video_font_draw_table16[] =
247{
248        0x00000000, 0xffff0000, 0x0000ffff, 0xffffffff
249};
250
251static const int video_font_draw_table24[16][3] =
252{
253        { 0x00000000, 0x00000000, 0x00000000 },
254        { 0x00000000, 0x00000000, 0x00ffffff },
255        { 0x00000000, 0x0000ffff, 0xff000000 },
256        { 0x00000000, 0x0000ffff, 0xffffffff },
257        { 0x000000ff, 0xffff0000, 0x00000000 },
258        { 0x000000ff, 0xffff0000, 0x00ffffff },
259        { 0x000000ff, 0xffffffff, 0xff000000 },
260        { 0x000000ff, 0xffffffff, 0xffffffff },
261        { 0xffffff00, 0x00000000, 0x00000000 },
262        { 0xffffff00, 0x00000000, 0x00ffffff },
263        { 0xffffff00, 0x0000ffff, 0xff000000 },
264        { 0xffffff00, 0x0000ffff, 0xffffffff },
265        { 0xffffffff, 0xffff0000, 0x00000000 },
266        { 0xffffffff, 0xffff0000, 0x00ffffff },
267        { 0xffffffff, 0xffffffff, 0xff000000 },
268        { 0xffffffff, 0xffffffff, 0xffffffff }
269};
270
271static const int video_font_draw_table32[16][4] =
272{
273        { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
274        { 0x00000000, 0x00000000, 0x00000000, 0x00ffffff },
275        { 0x00000000, 0x00000000, 0x00ffffff, 0x00000000 },
276        { 0x00000000, 0x00000000, 0x00ffffff, 0x00ffffff },
277        { 0x00000000, 0x00ffffff, 0x00000000, 0x00000000 },
278        { 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff },
279        { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00000000 },
280        { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00ffffff },
281        { 0x00ffffff, 0x00000000, 0x00000000, 0x00000000 },
282        { 0x00ffffff, 0x00000000, 0x00000000, 0x00ffffff },
283        { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000 },
284        { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00ffffff },
285        { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00000000 },
286        { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00ffffff },
287        { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00000000 },
288        { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff }
289};
290
291
292static void memsetl ( int *p, int c, int v );
293void video_putchar ( int xx, int yy, unsigned char c );
294static void memcpyl ( int *d, int *s, int c );
295
296/******************************************************************************/
297void video_drawchars ( int xx, int yy, unsigned char *s, int count )
298{
299        unsigned char *cdat;
300        volatile unsigned char *dest0, *dest;
301        int rows, offset, c;
302        int i;
303        offset = yy * VIDEO_LINE_LEN + xx * VIDEO_PIXEL_SIZE;
304        dest0 = video_fb_address + offset;
305
306        switch ( VIDEO_DATA_FORMAT )
307        {
308                case GDF__1BIT:
309                        while ( count-- )
310                        {
311                                c = *s;
312                                cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
313
314                                for ( i = 0; i < VIDEO_FONT_HEIGHT; i++ )
315                                {
316                                        offset = ( ( yy + i ) * ( VIDEO_VISIBLE_COLS ) + xx ) / 8;
317                                        *( unsigned char * )( video_fb_address + offset ) = ( ( unsigned char * )cdat )[i];
318                                }
319
320                                s++;
321                        }
322
323                        break;
324
325                case GDF__2BIT:
326                        while ( count-- )
327                        {
328                                c = *s;
329                                cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
330
331                                for ( i = 0; i < VIDEO_FONT_HEIGHT; i++ )
332                                {
333                                        unsigned char bits = *cdat++;
334                                        offset = ( ( yy + i ) * ( VIDEO_VISIBLE_COLS ) + xx ) / 4;
335                                        dest = video_fb_address + offset;
336                                        dest[0] = video_font_draw_table2[bits >> 4] ;
337                                        dest[1] = video_font_draw_table2[bits & 15] ;
338                                }
339
340                                s++;
341                        }
342
343                        break;
344
345                case GDF__4BIT:
346                        while ( count-- )
347                        {
348                                c = *s;
349                                cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
350
351                                for ( i = 0; i < VIDEO_FONT_HEIGHT; i++ )
352                                {
353                                        unsigned char bits = *cdat++;
354                                        offset = ( ( yy + i ) * ( VIDEO_VISIBLE_COLS ) + xx ) / 2;
355                                        dest = video_fb_address + offset;
356                                        dest[0] = video_font_draw_table4[bits >> 6] ;
357                                        dest[1] = video_font_draw_table4[bits >> 4 & 3] ;
358                                        dest[2] = video_font_draw_table4[bits >> 2 & 3] ;
359                                        dest[3] = video_font_draw_table4[bits & 3] ;
360                                }
361
362                                s++;
363                        }
364
365                        break;
366
367                case GDF__8BIT_INDEX:
368                case GDF__8BIT_332RGB:
369                        while ( count-- )
370                        {
371                                c = *s;
372                                cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
373
374                                for ( rows = VIDEO_FONT_HEIGHT, dest = dest0;
375                                        rows--;
376                                        dest += VIDEO_LINE_LEN )
377                                {
378                                        unsigned char bits = *cdat++;
379                                        ( ( volatile unsigned int * ) dest )[0] = BYTESWAP32( ( video_font_draw_table8[bits >> 4] & eorx ) ^ bgx );
380                                        ( ( volatile unsigned int * ) dest )[1] = BYTESWAP32( ( video_font_draw_table8[bits & 15] & eorx ) ^ bgx );
381                                }
382
383                                dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
384                                s++;
385                        }
386
387                        break;
388
389                case GDF_15BIT_555RGB:
390                        while ( count-- )
391                        {
392                                c = *s;
393                                cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
394
395                                for ( rows = VIDEO_FONT_HEIGHT, dest = dest0;
396                                        rows--;
397                                        dest += VIDEO_LINE_LEN )
398                                {
399                                        unsigned char bits = *cdat++;
400                                        ( ( volatile unsigned int * ) dest )[0] = SHORTSWAP32 ( ( video_font_draw_table15 [bits >> 6] & eorx ) ^ bgx );
401                                        ( ( volatile unsigned int * ) dest )[1] = SHORTSWAP32 ( ( video_font_draw_table15 [bits >> 4 & 3] & eorx ) ^ bgx );
402                                        ( ( volatile unsigned int * ) dest )[2] = SHORTSWAP32 ( ( video_font_draw_table15 [bits >> 2 & 3] & eorx ) ^ bgx );
403                                        ( ( volatile unsigned int * ) dest )[3] = SHORTSWAP32 ( ( video_font_draw_table15 [bits & 3] & eorx ) ^ bgx );
404                                }
405
406                                dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
407                                s++;
408                        }
409
410                        break;
411
412                        /*here*/
413                case GDF_16BIT_565RGB:
414                        while ( count-- )
415                        {
416                                c = *s;
417                                cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
418
419                                for ( rows = VIDEO_FONT_HEIGHT, dest = dest0;
420                                        rows--;
421                                        dest += VIDEO_LINE_LEN )
422                                {
423                                        unsigned char bits = *cdat++;
424                                        ( ( volatile unsigned int * ) dest )[0] = SHORTSWAP32 ( ( video_font_draw_table16 [bits >> 6] & eorx ) ^ bgx );
425                                        ( ( volatile unsigned int * ) dest )[1] = SHORTSWAP32 ( ( video_font_draw_table16 [bits >> 4 & 3] & eorx ) ^ bgx );
426                                        ( ( volatile unsigned int * ) dest )[2] = SHORTSWAP32 ( ( video_font_draw_table16 [bits >> 2 & 3] & eorx ) ^ bgx );
427                                        ( ( volatile unsigned int * ) dest )[3] = SHORTSWAP32 ( ( video_font_draw_table16 [bits & 3] & eorx ) ^ bgx );
428                                }
429
430                                dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
431                                s++;
432                        }
433
434                        break;
435
436                case GDF_32BIT_X888RGB:
437                        while ( count-- )
438                        {
439                                c = *s;
440                                cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
441
442                                for ( rows = VIDEO_FONT_HEIGHT, dest = dest0;
443                                        rows--;
444                                        dest += VIDEO_LINE_LEN )
445                                {
446                                        unsigned char bits = *cdat++;
447                                        ( ( volatile unsigned int * ) dest )[0] = SWAP32 ( ( video_font_draw_table32 [bits >> 4][0] & eorx ) ^ bgx );
448                                        ( ( volatile unsigned int * ) dest )[1] = SWAP32 ( ( video_font_draw_table32 [bits >> 4][1] & eorx ) ^ bgx );
449                                        ( ( volatile unsigned int * ) dest )[2] = SWAP32 ( ( video_font_draw_table32 [bits >> 4][2] & eorx ) ^ bgx );
450                                        ( ( volatile unsigned int * ) dest )[3] = SWAP32 ( ( video_font_draw_table32 [bits >> 4][3] & eorx ) ^ bgx );
451                                        ( ( volatile unsigned int * ) dest )[4] = SWAP32 ( ( video_font_draw_table32 [bits & 15][0] & eorx ) ^ bgx );
452                                        ( ( volatile unsigned int * ) dest )[5] = SWAP32 ( ( video_font_draw_table32 [bits & 15][1] & eorx ) ^ bgx );
453                                        ( ( volatile unsigned int * ) dest )[6] = SWAP32 ( ( video_font_draw_table32 [bits & 15][2] & eorx ) ^ bgx );
454                                        ( ( volatile unsigned int * ) dest )[7] = SWAP32 ( ( video_font_draw_table32 [bits & 15][3] & eorx ) ^ bgx );
455                                }
456
457                                dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
458                                s++;
459                        }
460
461                        break;
462
463                case GDF_24BIT_888RGB:
464                        while ( count-- )
465                        {
466                                c = *s;
467                                cdat = video_fontdata + c * VIDEO_FONT_HEIGHT;
468
469                                for ( rows = VIDEO_FONT_HEIGHT, dest = dest0;
470                                        rows--;
471                                        dest += VIDEO_LINE_LEN )
472                                {
473                                        unsigned char bits = *cdat++;
474                                        ( ( volatile unsigned int * ) dest )[0] = ( video_font_draw_table24[bits >> 4][0] & eorx ) ^ bgx;
475                                        ( ( volatile unsigned int * ) dest )[1] = ( video_font_draw_table24[bits >> 4][1] & eorx ) ^ bgx;
476                                        ( ( volatile unsigned int * ) dest )[2] = ( video_font_draw_table24[bits >> 4][2] & eorx ) ^ bgx;
477                                        ( ( volatile unsigned int * ) dest )[3] = ( video_font_draw_table24[bits & 15][0] & eorx ) ^ bgx;
478                                        ( ( volatile unsigned int * ) dest )[4] = ( video_font_draw_table24[bits & 15][1] & eorx ) ^ bgx;
479                                        ( ( volatile unsigned int * ) dest )[5] = ( video_font_draw_table24[bits & 15][2] & eorx ) ^ bgx;
480                                }
481
482                                dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE;
483                                s++;
484                        }
485
486                        break;
487        }
488}
489
490/*****************************************************************************/
491
492void video_drawstring ( int xx, int yy, unsigned char *s )
493{
494        video_drawchars ( xx, yy, s, strlen ( ( char * )s ) );
495}
496
497/*****************************************************************************/
498
499#ifndef VIDEO_HW_BITBLT
500void video_drawsline( char *str, int rows, int cols )
501{
502        int xx, yy;
503        int pos;
504
505        for ( yy = 1; yy < rows; yy++ )
506        {
507                pos = yy * cols;
508
509                for ( xx = 0; xx < cols; xx++ )
510                {
511                        if ( str[pos + xx] != str[pos - cols + xx] )
512                        {
513                                video_putchar( xx * VIDEO_FONT_WIDTH, ( yy - 1 ) * VIDEO_FONT_HEIGHT, str[pos + xx] );
514                        }
515                }
516        }
517
518        memcpyl ( ( int * )str, ( int * )&str[cols], ( rows - 1 ) *cols >> 2 );
519        memsetl ( ( int * )&str[( rows - 1 ) * cols], cols >> 2, CONSOLE_BG_COL );
520}
521
522#endif
523
524void video_putchar ( int xx, int yy, unsigned char c )
525{
526        video_drawchars ( xx, yy + VIDEO_LOGO_HEIGHT, &c, 1 );
527}
528#ifdef INTERFACE_3A780E
529void video_putchar1( int xx, int yy, unsigned char c )
530{
531        video_drawchars ( xx, yy, &c, 1 );
532}
533#endif
534
535/*****************************************************************************/
536
537#if 1
538
539static void memsetl ( int *p, int c, int v )
540{
541        while ( c-- )
542        {
543                *( p++ ) = v;
544        }
545}
546#endif
547
548/*****************************************************************************/
549
550#ifndef VIDEO_HW_BITBLT
551static void memcpyl ( int *d, int *s, int c )
552{
553        while ( c-- )
554        {
555                *( d++ ) = *( s++ );
556        }
557}
558#endif
559
560/*****************************************************************************/
561
562static void console_scrollup ( void )
563{
564        /* copy up rows ignoring the first one */
565#if defined(MEM_PRINTTO_VIDEO)
566        video_drawsline( memfb, CONSOLE_ROWS, CONSOLE_COLS );
567#else
568#ifdef __mips__
569#define UNCACHED_TO_CACHED(x) PHYS_TO_CACHED(UNCACHED_TO_PHYS(x))
570
571        if ( CONSOLE_ROW_FIRST < 0xb0000000 && CONSOLE_ROW_FIRST >= 0xa0000000 )
572        {
573                memcpyl ( UNCACHED_TO_CACHED( CONSOLE_ROW_FIRST ), UNCACHED_TO_CACHED( CONSOLE_ROW_SECOND ),
574                          CONSOLE_SCROLL_SIZE >> 2 );
575                pci_sync_cache( 0, ( vm_offset_t )UNCACHED_TO_CACHED( CONSOLE_ROW_FIRST ), CONSOLE_SCROLL_SIZE >> 2, SYNC_W );
576        }
577
578        else
579#endif
580                memcpyl ( CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND,
581                          CONSOLE_SCROLL_SIZE >> 2 );
582
583#endif
584        /* clear the last one */
585#ifdef VIDEO_HW_RECTFILL
586#ifdef RADEON7000
587        video_hw_rectfill ( VIDEO_PIXEL_SIZE,   /* bytes per pixel */
588                            0,  /* dest pos x */
589                            VIDEO_VISIBLE_ROWS - VIDEO_FONT_HEIGHT,     /* dest pos y */
590                            VIDEO_VISIBLE_COLS, /* frame width */
591                            VIDEO_FONT_HEIGHT,  /* frame height */
592                            CONSOLE_BG_COL      /* fill color */
593                          );
594#elif (defined(SMI502)||defined(SMI712))
595        AutodeFillRectModify( CONSOLE_BG_COL );
596#ifdef X800x480
597        memsetl ( CONSOLE_ROW_LAST, CONSOLE_ROW_SIZE >> 2, CONSOLE_BG_COL );
598#endif
599#else
600        memsetl ( CONSOLE_ROW_LAST, CONSOLE_ROW_SIZE >> 2, CONSOLE_BG_COL );
601#endif
602#elif defined(X800x600)
603        memsetl ( ( int * )( CONSOLE_ROW_LAST - CONSOLE_ROW_SIZE / 2 ), CONSOLE_ROW_SIZE >> 2, CONSOLE_BG_COL );
604#else
605        memsetl ( ( int * )( CONSOLE_ROW_LAST - CONSOLE_ROW_SIZE / 2 ), CONSOLE_ROW_SIZE >> 2, CONSOLE_BG_COL );
606#endif
607}
608
609/*****************************************************************************/
610
611static void console_back ( void )
612{
613        console_col--;
614
615        if ( console_col < 0 )
616        {
617                console_col = CONSOLE_COLS - 1;
618                console_row--;
619
620                if ( console_row < 0 )
621                {
622                        console_row = 0;
623                }
624        }
625}
626
627/*****************************************************************************/
628
629static void console_newline ( void )
630{
631        console_row++;
632        console_col = 0;
633
634        /* Check if we need to scroll the terminal */
635        if ( console_row >= CONSOLE_ROWS )
636        {
637                /* Scroll everything up */
638                console_scrollup ();
639                /* Decrement row number */
640                console_row--;
641        }
642}
643
644/*****************************************************************************/
645
646void video_putc ( const char c )
647{
648        switch ( c )
649        {
650                case 13:                /* ignore */
651                        CURSOR_OFF
652                        break;
653
654                case '\n':              /* next line */
655                        CURSOR_OFF
656                        console_newline ();
657                        break;
658
659                case 9:         /* tab 8 */
660                        CURSOR_OFF console_col |= 0x0008;
661                        console_col &= ~0x0007;
662
663                        if ( console_col >= CONSOLE_COLS )
664                        {
665                                console_newline ();
666                        }
667
668                        break;
669
670                case 8:         /* backspace */
671                        CURSOR_OFF
672                        console_back ();
673                        break;
674
675                default
676                                :               /* draw the char */
677                        video_putchar ( console_col * VIDEO_FONT_WIDTH,
678                                        console_row * VIDEO_FONT_HEIGHT,
679                                        c );
680#ifdef MEM_PRINTTO_VIDEO
681                        memfb[console_row * CONSOLE_COLS + console_col] = c;
682#endif
683                        console_col++;
684
685                        /* check for newline */
686                        if ( console_col >= CONSOLE_COLS )
687                        {
688                                console_newline ();
689                        }
690        }
691
692        CURSOR_SET
693}
694
695
696/*****************************************************************************/
697
698void video_cls_all( void )
699{
700        memsetl ( ( int * )video_fb_address,
701                  CONSOLE_SIZE,
702                  CONSOLE_BG_COL );
703}
704
705void video_set_background( unsigned char r, unsigned char g, unsigned char b )
706{
707        int cnt = CONSOLE_SIZE - VIDEO_LOGO_HEIGHT * VIDEO_LINE_LEN;
708        volatile unsigned short *p = ( volatile unsigned short * )( video_fb_address + VIDEO_LOGO_HEIGHT * VIDEO_LINE_LEN );
709        unsigned short color = SWAP16 ( ( unsigned short ) ( ( ( r >> 3 ) << 11 ) | ( ( g >> 2 ) << 5 ) | ( b >> 3 ) ) );
710
711        while ( cnt > 0 )
712        {
713                *( p++ ) = color;
714                cnt -= 2;
715        }
716}
717
718static int record = 1;
719/*80*24*/
720#if defined(X640x480)
721char console_buffer[2][31][81] = {{{32}}}; /*80*30->640x480*/
722#elif defined(X800x480)
723char console_buffer[2][37][101] = {32};
724#elif defined(X800x600)
725char console_buffer[2][37][101] = {{{32}}};
726#elif defined(X1024x768)
727char console_buffer[2][49][129] = {32}; /*128*48->1024x768*/
728#elif defined(X1280x1024)
729char console_buffer[2][65][161] = {32}; /*128*48->1024x768*/
730#elif defined(X320x240)
731char console_buffer[2][16][41] = {32}; /*40*15->320x240*/
732#else
733char console_buffer[2][31][81] = {32}; /*80*30->640x480*/
734#endif
735
736void video_console_print( int console_col, int console_row, unsigned char *s )
737{
738        int count = strlen ( ( char * )s );
739
740        while ( count-- )
741        {
742                video_putchar ( console_col * VIDEO_FONT_WIDTH,
743                                console_row * VIDEO_FONT_HEIGHT,
744                                *s );
745
746                if ( record )
747                {
748                        console_buffer[0][console_row][console_col] = *s;
749                        console_buffer[1][console_row][console_col] = ( char )bgx;
750                }
751
752                console_col++;
753                s++;
754        }
755}
756void begin_record( void )
757{
758        record = 1;
759}
760
761void stop_record( void )
762{
763        record = 0;
764}
765
766
767char video_get_console_char( int console_col, int console_row )
768{
769        return console_buffer[0][console_row][console_col];
770}
771
772char video_get_console_bgcolor( int console_col, int console_row )
773{
774        return console_buffer[1][console_row][console_col];
775}
776
777void video_set_bg( unsigned char r, unsigned char g, unsigned char b )
778{
779        bgx = SWAP16 ( ( unsigned short ) ( ( ( r >> 3 ) << 11 ) | ( ( g >> 2 ) << 5 ) | ( b >> 3 ) ) );
780        bgx |= ( bgx << 16 );
781        fgx =  SWAP16 ( ( unsigned short ) ( ( ( 128 >> 3 ) << 11 ) | ( ( 128 >> 2 ) << 5 ) | ( 128 >> 3 ) ) );
782        fgx |= ( fgx << 16 );
783        eorx = fgx ^ bgx;
784}
785
786
787unsigned short pallete[16] =
788{
789        SWAP16 ( ( unsigned short ) ( ( ( 0   >> 3 ) << 11 ) | ( ( 0   >> 2 ) << 5 ) | ( 0   >> 3 ) ) ),
790        SWAP16 ( ( unsigned short ) ( ( ( 0   >> 3 ) << 11 ) | ( ( 0   >> 2 ) << 5 ) | ( 128 >> 3 ) ) ),
791        SWAP16 ( ( unsigned short ) ( ( ( 0   >> 3 ) << 11 ) | ( ( 128 >> 2 ) << 5 ) | ( 0   >> 3 ) ) ),
792        SWAP16 ( ( unsigned short ) ( ( ( 0   >> 3 ) << 11 ) | ( ( 128 >> 2 ) << 5 ) | ( 128 >> 3 ) ) ),
793        SWAP16 ( ( unsigned short ) ( ( ( 128 >> 3 ) << 11 ) | ( ( 0   >> 2 ) << 5 ) | ( 0   >> 3 ) ) ),
794        SWAP16 ( ( unsigned short ) ( ( ( 128 >> 3 ) << 11 ) | ( ( 0   >> 2 ) << 5 ) | ( 128 >> 3 ) ) ),
795        SWAP16 ( ( unsigned short ) ( ( ( 128 >> 3 ) << 11 ) | ( ( 128 >> 2 ) << 5 ) | ( 0   >> 3 ) ) ),
796        SWAP16 ( ( unsigned short ) ( ( ( 0xc0 >> 3 ) << 11 ) | ( ( 0xc0 >> 2 ) << 5 ) | ( 0xc0 >> 3 ) ) ),
797        SWAP16 ( ( unsigned short ) ( ( ( 128 >> 3 ) << 11 ) | ( ( 128 >> 2 ) << 5 ) | ( 128 >> 3 ) ) ),
798        SWAP16 ( ( unsigned short ) ( ( ( 0   >> 3 ) << 11 ) | ( ( 0   >> 2 ) << 5 ) | ( 255 >> 3 ) ) ),
799        SWAP16 ( ( unsigned short ) ( ( ( 0   >> 3 ) << 11 ) | ( ( 255 >> 2 ) << 5 ) | ( 0   >> 3 ) ) ),
800        SWAP16 ( ( unsigned short ) ( ( ( 0   >> 3 ) << 11 ) | ( ( 255 >> 2 ) << 5 ) | ( 255 >> 3 ) ) ),
801        SWAP16 ( ( unsigned short ) ( ( ( 255 >> 3 ) << 11 ) | ( ( 0   >> 2 ) << 5 ) | ( 0   >> 3 ) ) ),
802        SWAP16 ( ( unsigned short ) ( ( ( 255 >> 3 ) << 11 ) | ( ( 0   >> 2 ) << 5 ) | ( 255 >> 3 ) ) ),
803        SWAP16 ( ( unsigned short ) ( ( ( 255 >> 3 ) << 11 ) | ( ( 255 >> 2 ) << 5 ) | ( 0   >> 3 ) ) ),
804        SWAP16 ( ( unsigned short ) ( ( ( 255 >> 3 ) << 11 ) | ( ( 255 >> 2 ) << 5 ) | ( 255 >> 3 ) ) )
805};
806
807#ifdef INTERFACE_3A780E
808void video_set_color( unsigned char color )
809{
810#ifndef FB_MENU_NOCLOLOR
811        bgx = pallete[color >> 4];
812        bgx |= ( bgx << 16 );
813        fgx =  pallete[color & 0xf];
814        fgx |= ( fgx << 16 );
815        eorx = fgx ^ bgx;
816#endif
817}
818#endif
819static void __cprint( int y, int x, int width, char color, const char *buf )
820{
821#ifndef FB_MENU_NOCLOLOR
822        bgx = pallete[color >> 4];
823        bgx |= ( bgx << 16 );
824        fgx =  pallete[color & 0xf];
825        fgx |= ( fgx << 16 );
826        eorx = fgx ^ bgx;
827#endif
828        video_console_print( x, y, ( unsigned char * )buf );
829#ifndef FB_MENU_NOCLOLOR
830        bgx = 0;
831        fgx =  SWAP16 ( ( unsigned short ) ( ( ( 128 >> 3 ) << 11 ) | ( ( 128 >> 2 ) << 5 ) | ( 128 >> 3 ) ) );
832        fgx |= ( fgx << 16 );
833        eorx = fgx ^ bgx;
834#endif
835}
836
837void cprintfb( int y, int x, int width, char color, const char *text )
838{
839        int i, l;
840        char buf[200];
841
842        if ( width == 0 && text )
843        {
844                width = strlen( text );
845        }
846
847        if ( text && ( l = strlen( text ) ) )
848        {
849                memcpy( buf, text, ( width && l > width ) ? width : l );
850        }
851
852        else
853        {
854                l = 0;
855        }
856
857        if ( l < width )
858                for ( i = 0; i < width - l; i++ )
859                {
860                        buf[l + i] = 0x20;
861                }
862
863        if ( width )
864        {
865                buf[width] = 0;
866                __cprint( y, x, width, color, buf );
867        }
868}
869
870void set_cursor_fb( unsigned char x, unsigned char y )
871{
872        console_col = x;
873        console_row = y;
874}
875
876int fb_init( void )
877{
878        unsigned char color8;
879
880        /* AppInit drawing pats */
881        switch ( VIDEO_DATA_FORMAT )
882        {
883#if 0
884
885                case GDF__8BIT_INDEX:
886                        video_set_lut ( 0x01, CONSOLE_FG_COL, CONSOLE_FG_COL, CONSOLE_FG_COL );
887                        video_set_lut ( 0x00, CONSOLE_BG_COL, CONSOLE_BG_COL, CONSOLE_BG_COL );
888                        fgx = 0x01010101;
889                        bgx = 0x00000000;
890                        break;
891#endif
892
893                case GDF__1BIT:
894                        fgx = 1;
895                        bgx = 0;
896                        break;
897
898                case GDF__2BIT:
899                        fgx = 3;
900                        bgx = 0;
901                        break;
902
903                case GDF__4BIT:
904                        fgx = 0xf;
905                        bgx = 0;
906                        break;
907
908                case GDF__8BIT_332RGB:
909                        color8 = ( ( CONSOLE_FG_COL & 0xe0 ) |
910                                   ( ( CONSOLE_FG_COL >> 3 ) & 0x1c ) | CONSOLE_FG_COL >> 6 );
911                        fgx = ( color8 << 24 ) | ( color8 << 16 ) | ( color8 << 8 ) | color8;
912                        color8 = ( ( CONSOLE_BG_COL & 0xe0 ) |
913                                   ( ( CONSOLE_BG_COL >> 3 ) & 0x1c ) | CONSOLE_BG_COL >> 6 );
914                        bgx = ( color8 << 24 ) | ( color8 << 16 ) | ( color8 << 8 ) | color8;
915                        break;
916
917                case GDF_15BIT_555RGB:
918                        fgx = ( ( ( CONSOLE_FG_COL >> 3 ) << 26 ) |
919                                ( ( CONSOLE_FG_COL >> 3 ) << 21 ) | ( ( CONSOLE_FG_COL >> 3 ) << 16 ) |
920                                ( ( CONSOLE_FG_COL >> 3 ) << 10 ) | ( ( CONSOLE_FG_COL >> 3 ) << 5 ) |
921                                ( CONSOLE_FG_COL >> 3 ) );
922                        bgx = ( ( ( CONSOLE_BG_COL >> 3 ) << 26 ) |
923                                ( ( CONSOLE_BG_COL >> 3 ) << 21 ) | ( ( CONSOLE_BG_COL >> 3 ) << 16 ) |
924                                ( ( CONSOLE_BG_COL >> 3 ) << 10 ) | ( ( CONSOLE_BG_COL >> 3 ) << 5 ) |
925                                ( CONSOLE_BG_COL >> 3 ) );
926                        break;
927
928                case GDF_16BIT_565RGB:
929                        fgx = ( ( ( CONSOLE_FG_COL >> 3 ) << 27 ) |
930                                ( ( CONSOLE_FG_COL >> 2 ) << 21 ) | ( ( CONSOLE_FG_COL >> 3 ) << 16 ) |
931                                ( ( CONSOLE_FG_COL >> 3 ) << 11 ) | ( ( CONSOLE_FG_COL >> 2 ) << 5 ) |
932                                ( CONSOLE_FG_COL >> 3 ) );
933                        bgx = ( ( ( CONSOLE_BG_COL >> 3 ) << 27 ) |
934                                ( ( CONSOLE_BG_COL >> 2 ) << 21 ) | ( ( CONSOLE_BG_COL >> 3 ) << 16 ) |
935                                ( ( CONSOLE_BG_COL >> 3 ) << 11 ) | ( ( CONSOLE_BG_COL >> 2 ) << 5 ) |
936                                ( CONSOLE_BG_COL >> 3 ) );
937                        break;
938
939                case GDF_32BIT_X888RGB:
940                        fgx = ( CONSOLE_FG_COL << 16 ) | ( CONSOLE_FG_COL << 8 ) | CONSOLE_FG_COL;
941                        bgx = ( CONSOLE_BG_COL << 16 ) | ( CONSOLE_BG_COL << 8 ) | CONSOLE_BG_COL;
942                        break;
943
944                case GDF_24BIT_888RGB:
945                        fgx = ( CONSOLE_FG_COL << 24 ) | ( CONSOLE_FG_COL << 16 ) |
946                              ( CONSOLE_FG_COL << 8 ) | CONSOLE_FG_COL;
947                        bgx = ( CONSOLE_BG_COL << 24 ) | ( CONSOLE_BG_COL << 16 ) |
948                              ( CONSOLE_BG_COL << 8 ) | CONSOLE_BG_COL;
949                        break;
950        }
951
952        eorx = fgx ^ bgx;
953        memsetl ( ( int * )video_fb_address, VIDEO_COLS * VIDEO_ROWS * VIDEO_PIXEL_SIZE / 4, CONSOLE_BG_COL );
954        /* Initialize the console */
955        console_col = 0;
956        console_row = 0;
957        memset ( console_buffer, ' ', sizeof console_buffer );
958#if defined(MEM_PRINTTO_VIDEO)
959        memset ( memfb, 0, CONSOLE_ROWS * CONSOLE_COLS );
960#endif
961        return 0;
962}
963