File indexing completed on 2025-05-11 08:23:04
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 #include <bsp.h>
0028 #include <bsp/vc.h>
0029 #include <bsp/rpi-fb.h>
0030 #include <rtems/fb.h>
0031
0032 #include <stdlib.h>
0033 #include <string.h>
0034 #include "font_data.h"
0035
0036 static void wr_cursor(
0037 int r,
0038 int c
0039 )
0040 {
0041
0042 }
0043
0044 #define TAB_SPACE 4
0045 #define CONSOLE_BG_COL 0x00
0046 #define CONSOLE_FG_COL 0xa0
0047
0048 static void *fb_mem = NULL;
0049 static unsigned short maxCol;
0050 static unsigned short maxRow;
0051 static unsigned short bytes_per_pixel;
0052 static unsigned int bytes_per_line;
0053 static unsigned int bytes_per_char_line;
0054 static unsigned char row;
0055 static unsigned char column;
0056 static unsigned int nLines;
0057 static uint32_t fgx, bgx, eorx;
0058 static int rpi_video_initialized;
0059
0060 static const int video_font_draw_table32[ 16 ][ 4 ] = {
0061 { 0x00000000, 0x00000000, 0x00000000, 0x00000000 },
0062 { 0x00000000, 0x00000000, 0x00000000, 0x00ffffff },
0063 { 0x00000000, 0x00000000, 0x00ffffff, 0x00000000 },
0064 { 0x00000000, 0x00000000, 0x00ffffff, 0x00ffffff },
0065 { 0x00000000, 0x00ffffff, 0x00000000, 0x00000000 },
0066 { 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff },
0067 { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00000000 },
0068 { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00ffffff },
0069 { 0x00ffffff, 0x00000000, 0x00000000, 0x00000000 },
0070 { 0x00ffffff, 0x00000000, 0x00000000, 0x00ffffff },
0071 { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000 },
0072 { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00ffffff },
0073 { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00000000 },
0074 { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00ffffff },
0075 { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00000000 },
0076 { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff }
0077 };
0078
0079 static void scroll( void )
0080 {
0081 int i, j;
0082 uint8_t *pt_scroll, *pt_bitmap;
0083
0084 pt_bitmap = fb_mem;
0085 j = 0;
0086 pt_bitmap = pt_bitmap + j;
0087 pt_scroll = pt_bitmap + bytes_per_char_line;
0088
0089 for ( i = j; i < maxRow - 1; i++ ) {
0090 memcpy( pt_bitmap, pt_scroll, bytes_per_char_line );
0091 pt_bitmap = pt_bitmap + bytes_per_char_line;
0092 pt_scroll = pt_bitmap + bytes_per_char_line;
0093 }
0094
0095
0096
0097
0098 memset( pt_bitmap, 0, bytes_per_char_line );
0099 }
0100
0101 static void doCRNL(
0102 int cr,
0103 int nl
0104 )
0105 {
0106 if ( nl ) {
0107 if ( ++row == maxRow ) {
0108 scroll();
0109 row = maxRow - 1;
0110 }
0111
0112 nLines++;
0113 }
0114
0115 if ( cr )
0116 column = 0;
0117
0118
0119 if ( cr || nl ) {
0120 wr_cursor( row, column );
0121 }
0122 }
0123
0124 static void advanceCursor( void )
0125 {
0126 if ( ++column == maxCol )
0127 doCRNL( 1, 1 );
0128 else
0129 wr_cursor( row, column );
0130 }
0131
0132 static void gotorc(
0133 int r,
0134 int c
0135 )
0136 {
0137 column = c;
0138 row = r;
0139 wr_cursor( row, column );
0140 }
0141
0142 static void video_drawchars(
0143 int r,
0144 int c,
0145 unsigned char ch
0146 )
0147 {
0148 if ( fb_mem == NULL ) {
0149 return;
0150 }
0151
0152 uint8_t *cdat, *dest, *dest0;
0153 int rows, offset;
0154
0155 offset = r * bytes_per_char_line + c * bytes_per_pixel * RPI_FONT_WIDTH;
0156 dest0 = fb_mem + offset;
0157
0158
0159
0160
0161 cdat = rpi_font + ch * RPI_FONT_HEIGHT;
0162
0163 for ( rows = RPI_FONT_HEIGHT, dest = dest0;
0164 rows--; dest += bytes_per_line ) {
0165 uint8_t bits = *cdat++;
0166
0167 ( (uint32_t *) dest )[ 0 ] =
0168 ( video_font_draw_table32
0169 [ bits >> 4 ][ 0 ] & eorx ) ^ bgx;
0170 ( (uint32_t *) dest )[ 1 ] =
0171 ( video_font_draw_table32
0172 [ bits >> 4 ][ 1 ] & eorx ) ^ bgx;
0173 ( (uint32_t *) dest )[ 2 ] =
0174 ( video_font_draw_table32
0175 [ bits >> 4 ][ 2 ] & eorx ) ^ bgx;
0176 ( (uint32_t *) dest )[ 3 ] =
0177 ( video_font_draw_table32
0178 [ bits >> 4 ][ 3 ] & eorx ) ^ bgx;
0179
0180 ( (uint32_t *) dest )[ 4 ] =
0181 ( video_font_draw_table32
0182 [ bits & 15 ][ 0 ] & eorx ) ^ bgx;
0183 ( (uint32_t *) dest )[ 5 ] =
0184 ( video_font_draw_table32
0185 [ bits & 15 ][ 1 ] & eorx ) ^ bgx;
0186 ( (uint32_t *) dest )[ 6 ] =
0187 ( video_font_draw_table32
0188 [ bits & 15 ][ 2 ] & eorx ) ^ bgx;
0189 ( (uint32_t *) dest )[ 7 ] =
0190 ( video_font_draw_table32
0191 [ bits & 15 ][ 3 ] & eorx ) ^ bgx;
0192 }
0193 }
0194
0195 #define ESC ( (char) 27 )
0196
0197 #define BLANK ( (char) 0x7f )
0198
0199 static void videoPutChar( char ch )
0200 {
0201 switch ( ch ) {
0202 case '\b': {
0203 if ( column )
0204 column--;
0205
0206
0207 wr_cursor( row, column );
0208 return;
0209 }
0210 case '\t': {
0211 int i;
0212
0213 i = TAB_SPACE - ( column & ( TAB_SPACE - 1 ) );
0214
0215 while ( i-- ) {
0216
0217 video_drawchars( row, column, ' ' );
0218 column += 1;
0219
0220 if ( column >= maxCol ) {
0221 doCRNL( 1, 1 );
0222 return;
0223 }
0224 }
0225
0226 wr_cursor( row, column );
0227
0228 return;
0229 }
0230 case '\n': {
0231 doCRNL( 0, 1 );
0232 return;
0233 }
0234 case 7: {
0235 return;
0236 }
0237 case '\r': {
0238 doCRNL( 1, 0 );
0239 return;
0240 }
0241 case BLANK: {
0242 video_drawchars( row, column, ' ' );
0243
0244 wr_cursor( row, column );
0245
0246 return;
0247 }
0248 default: {
0249
0250 video_drawchars( row, column, ch );
0251 advanceCursor();
0252 return;
0253 }
0254 }
0255 }
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273 #define DONE ( -1 )
0274
0275 static int handleEscape(
0276 int oldState,
0277 char ch
0278 )
0279 {
0280 int rval = 0;
0281 int ro, co;
0282
0283 switch ( oldState ) {
0284 case DONE:
0285 case 0:
0286
0287 if ( 27 == ch ) {
0288 rval = 27;
0289 }
0290
0291 break;
0292
0293 case 27:
0294
0295 if ( '[' == ch ) {
0296 rval = ch;
0297 } else {
0298
0299 videoPutChar( ESC );
0300 }
0301
0302 break;
0303
0304 case '[':
0305
0306 ro = row;
0307 co = column;
0308 rval = DONE;
0309
0310 switch ( ch ) {
0311 case 'D':
0312
0313 if ( co > 0 )
0314 co--;
0315
0316 break;
0317 case 'C':
0318
0319 if ( co < maxCol )
0320 co++;
0321
0322 break;
0323 case 'A':
0324
0325 if ( ro > 0 )
0326 ro--;
0327
0328 break;
0329 case 'B':
0330
0331 if ( ro < maxRow )
0332 ro++;
0333
0334 break;
0335 case 'H':
0336 ro = co = 0;
0337 break;
0338 case 'K':
0339
0340 while ( column < maxCol - 1 )
0341 videoPutChar( ' ' );
0342
0343 videoPutChar( BLANK );
0344 break;
0345 case 'J':
0346
0347 while ( ( ( row < maxRow - 1 ) || ( column < maxCol - 1 ) ) )
0348 videoPutChar( ' ' );
0349
0350 videoPutChar( BLANK );
0351 break;
0352 default:
0353 videoPutChar( ESC );
0354 videoPutChar( '[' );
0355
0356 ro = -1;
0357 rval = 0;
0358 break;
0359 }
0360
0361
0362 if ( ro >= 0 )
0363 gotorc( ro, co );
0364
0365 default:
0366 break;
0367 }
0368
0369 return rval;
0370 }
0371
0372 static void clear_screen( void )
0373 {
0374 int i, j;
0375
0376 for ( j = 0; j < maxRow; j++ ) {
0377 for ( i = 0; i < maxCol; i++ ) {
0378 videoPutChar( ' ' );
0379 }
0380 }
0381
0382 column = 0;
0383 row = 0;
0384 }
0385
0386 void rpi_fb_outch( char c )
0387 {
0388 static int escaped = 0;
0389
0390 if ( !( escaped = handleEscape( escaped, c ) ) ) {
0391 if ( '\n' == c )
0392 videoPutChar( '\r' );
0393
0394 videoPutChar( c );
0395 }
0396 }
0397
0398 void rpi_video_init( void )
0399 {
0400 int ret = rpi_fb_init();
0401
0402 if ( ( ret != RPI_FB_INIT_OK ) &&
0403 ( ret != RPI_FB_INIT_ALREADY_INITIALIZED ) ) {
0404 rpi_video_initialized = 0;
0405 return;
0406 }
0407
0408 struct fb_var_screeninfo fb_var_info;
0409 struct fb_fix_screeninfo fb_fix_info;
0410 rpi_get_var_screen_info( &fb_var_info );
0411 rpi_get_fix_screen_info( &fb_fix_info );
0412 maxCol = fb_var_info.xres / RPI_FONT_WIDTH;
0413 maxRow = fb_var_info.yres / RPI_FONT_HEIGHT;
0414 bytes_per_pixel = fb_var_info.bits_per_pixel / 8;
0415 bytes_per_line = bytes_per_pixel * fb_var_info.xres;
0416 bytes_per_char_line = RPI_FONT_HEIGHT * bytes_per_line;
0417 fb_mem = RTEMS_DEVOLATILE( void *, fb_fix_info.smem_start );
0418 column = 0;
0419 row = 0;
0420 nLines = 0;
0421 fgx = ( CONSOLE_FG_COL << 24 ) |
0422 ( CONSOLE_FG_COL << 16 ) |
0423 ( CONSOLE_FG_COL << 8 ) |
0424 CONSOLE_FG_COL;
0425 bgx = ( CONSOLE_BG_COL << 24 ) |
0426 ( CONSOLE_BG_COL << 16 ) |
0427 ( CONSOLE_BG_COL << 8 ) |
0428 CONSOLE_BG_COL;
0429 eorx = fgx ^ bgx;
0430 clear_screen();
0431 rpi_video_initialized = 1;
0432 }
0433
0434 int rpi_video_is_initialized( void )
0435 {
0436 return rpi_video_initialized;
0437 }
0438
0439
0440 void gotoxy(
0441 int x,
0442 int y
0443 );
0444 int whereX( void );
0445 int whereY( void );
0446
0447 void gotoxy(
0448 int x,
0449 int y
0450 )
0451 {
0452 gotorc( y, x );
0453 }
0454
0455 int whereX( void )
0456 {
0457 return row;
0458 }
0459
0460 int whereY( void )
0461 {
0462 return column;
0463 }