Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • kernel/genarch/src/fb/fb.c

    r7ddc2c7 rc43b89e8  
    5656#define INV_COLOR    0xaaaaaa
    5757
    58 #define FB_PAGES  8
    59 
    6058#define RED(x, bits)    (((x) >> (8 + 8 + 8 - (bits))) & ((1 << (bits)) - 1))
    6159#define GREEN(x, bits)  (((x) >> (8 + 8 - (bits))) & ((1 << (bits)) - 1))
     
    7270
    7371#define BB_POS(instance, col, row) \
    74         ((((instance)->start_row + (row)) % (instance)->rows) * \
    75             (instance)->cols + (col))
     72        ((row) * (instance)->cols + (col))
    7673
    7774#define GLYPH_POS(instance, glyph, y) \
     
    9592        unsigned int yres;
    9693       
    97         /** Number of rows that fit on framebuffer */
    9894        unsigned int rowtrim;
    9995       
     
    105101        unsigned int bgscanbytes;
    106102       
    107         /** Number of columns in the backbuffer */
    108103        unsigned int cols;
    109         /** Number of rows in the backbuffer */
    110104        unsigned int rows;
    111105       
    112         /** Starting row in the cyclic backbuffer */
    113         unsigned int start_row;
    114        
    115         /** Top-most visible row (relative to start_row) */
    116         unsigned int offset_row;
    117        
    118         /** Current backbuffer position */
    119106        unsigned int position;
    120107} fb_instance_t;
    121108
    122 static void fb_putchar(outdev_t *, wchar_t);
    123 static void fb_redraw(outdev_t *);
    124 static void fb_scroll_up(outdev_t *);
    125 static void fb_scroll_down(outdev_t *);
     109static void fb_putchar(outdev_t *dev, wchar_t ch);
     110static void fb_redraw_internal(fb_instance_t *instance);
     111static void fb_redraw(outdev_t *dev);
    126112
    127113static outdev_operations_t fbdev_ops = {
    128114        .write = fb_putchar,
    129         .redraw = fb_redraw,
    130         .scroll_up = fb_scroll_up,
    131         .scroll_down = fb_scroll_down
     115        .redraw = fb_redraw
    132116};
    133117
     
    232216    unsigned int col, unsigned int row, bool overlay)
    233217{
     218        unsigned int x = COL2X(col);
     219        unsigned int y = ROW2Y(row);
     220        unsigned int yd;
     221       
    234222        if (!overlay)
    235223                instance->backbuf[BB_POS(instance, col, row)] = glyph;
    236224       
    237         /* Do not output if the framebuffer is used by user space */
    238         if ((instance->parea.mapped) && (!console_override))
    239                 return;
    240        
    241         /* Check whether the glyph should be visible */
    242         if (row < instance->offset_row)
    243                 return;
    244        
    245         unsigned int rel_row = row - instance->offset_row;
    246         if (rel_row >= instance->rowtrim)
    247                 return;
    248        
    249         unsigned int x = COL2X(col);
    250         unsigned int y = ROW2Y(rel_row);
    251        
    252         for (unsigned int yd = 0; yd < FONT_SCANLINES; yd++)
    253                 memcpy(&instance->addr[FB_POS(instance, x, y + yd)],
    254                     &instance->glyphs[GLYPH_POS(instance, glyph, yd)],
    255                     instance->glyphscanline);
     225        if ((!instance->parea.mapped) || (console_override)) {
     226                for (yd = 0; yd < FONT_SCANLINES; yd++)
     227                        memcpy(&instance->addr[FB_POS(instance, x, y + yd)],
     228                            &instance->glyphs[GLYPH_POS(instance, glyph, yd)],
     229                            instance->glyphscanline);
     230        }
    256231}
    257232
    258233/** Scroll screen down by one row
    259234 *
     235 *
    260236 */
    261237static void screen_scroll(fb_instance_t *instance)
    262238{
    263239        if ((!instance->parea.mapped) || (console_override)) {
    264                 for (unsigned int rel_row = 0; rel_row < instance->rowtrim; rel_row++) {
    265                         unsigned int y = ROW2Y(rel_row);
    266                         unsigned int row = rel_row + instance->offset_row;
     240                unsigned int row;
     241               
     242                for (row = 0; row < instance->rows; row++) {
     243                        unsigned int y = ROW2Y(row);
     244                        unsigned int yd;
    267245                       
    268                         for (unsigned int yd = 0; yd < FONT_SCANLINES; yd++) {
     246                        for (yd = 0; yd < FONT_SCANLINES; yd++) {
    269247                                unsigned int x;
    270248                                unsigned int col;
     
    291269        }
    292270       
    293         /*
    294          * Implement backbuffer scrolling by wrapping around
    295          * the cyclic buffer.
    296          */
    297        
    298         instance->start_row++;
    299         if (instance->start_row == instance->rows)
    300                 instance->start_row = 0;
    301        
     271        memmove(instance->backbuf, &instance->backbuf[BB_POS(instance, 0, 1)],
     272            instance->cols * (instance->rows - 1) * sizeof(uint16_t));
    302273        memsetw(&instance->backbuf[BB_POS(instance, 0, instance->rows - 1)],
    303274            instance->cols, 0);
     
    363334}
    364335
     336/** Print character to screen
     337 *
     338 * Emulate basic terminal commands.
     339 *
     340 */
     341static void fb_putchar(outdev_t *dev, wchar_t ch)
     342{
     343        fb_instance_t *instance = (fb_instance_t *) dev->data;
     344        spinlock_lock(&instance->lock);
     345       
     346        switch (ch) {
     347        case '\n':
     348                cursor_remove(instance);
     349                instance->position += instance->cols;
     350                instance->position -= instance->position % instance->cols;
     351                break;
     352        case '\r':
     353                cursor_remove(instance);
     354                instance->position -= instance->position % instance->cols;
     355                break;
     356        case '\b':
     357                cursor_remove(instance);
     358                if (instance->position % instance->cols)
     359                        instance->position--;
     360                break;
     361        case '\t':
     362                cursor_remove(instance);
     363                do {
     364                        glyph_draw(instance, fb_font_glyph(' '),
     365                            instance->position % instance->cols,
     366                            instance->position / instance->cols, false);
     367                        instance->position++;
     368                } while (((instance->position % instance->cols) % 8 != 0) &&
     369                    (instance->position < instance->cols * instance->rows));
     370                break;
     371        default:
     372                glyph_draw(instance, fb_font_glyph(ch),
     373                    instance->position % instance->cols,
     374                    instance->position / instance->cols, false);
     375                instance->position++;
     376        }
     377       
     378        if (instance->position >= instance->cols * instance->rows) {
     379                instance->position -= instance->cols;
     380                screen_scroll(instance);
     381        }
     382       
     383        cursor_put(instance);
     384       
     385        spinlock_unlock(&instance->lock);
     386}
     387
    365388static void fb_redraw_internal(fb_instance_t *instance)
    366389{
    367         for (unsigned int rel_row = 0; rel_row < instance->rowtrim; rel_row++) {
    368                 unsigned int y = ROW2Y(rel_row);
    369                 unsigned int row = rel_row + instance->offset_row;
    370                
    371                 for (unsigned int yd = 0; yd < FONT_SCANLINES; yd++) {
     390        unsigned int row;
     391       
     392        for (row = 0; row < instance->rowtrim; row++) {
     393                unsigned int y = ROW2Y(row);
     394                unsigned int yd;
     395               
     396                for (yd = 0; yd < FONT_SCANLINES; yd++) {
    372397                        unsigned int x;
    373398                        unsigned int col;
     
    403428}
    404429
    405 /** Print character to screen
    406  *
    407  * Emulate basic terminal commands.
    408  *
    409  */
    410 static void fb_putchar(outdev_t *dev, wchar_t ch)
    411 {
    412         fb_instance_t *instance = (fb_instance_t *) dev->data;
    413         spinlock_lock(&instance->lock);
    414        
    415         switch (ch) {
    416         case '\n':
    417                 cursor_remove(instance);
    418                 instance->position += instance->cols;
    419                 instance->position -= instance->position % instance->cols;
    420                 break;
    421         case '\r':
    422                 cursor_remove(instance);
    423                 instance->position -= instance->position % instance->cols;
    424                 break;
    425         case '\b':
    426                 cursor_remove(instance);
    427                 if (instance->position % instance->cols)
    428                         instance->position--;
    429                 break;
    430         case '\t':
    431                 cursor_remove(instance);
    432                 do {
    433                         glyph_draw(instance, fb_font_glyph(' '),
    434                             instance->position % instance->cols,
    435                             instance->position / instance->cols, false);
    436                         instance->position++;
    437                 } while (((instance->position % instance->cols) % 8 != 0) &&
    438                     (instance->position < instance->cols * instance->rows));
    439                 break;
    440         default:
    441                 glyph_draw(instance, fb_font_glyph(ch),
    442                     instance->position % instance->cols,
    443                     instance->position / instance->cols, false);
    444                 instance->position++;
    445         }
    446        
    447         if (instance->position >= instance->cols * instance->rows) {
    448                 instance->position -= instance->cols;
    449                 screen_scroll(instance);
    450         }
    451        
    452         cursor_put(instance);
    453        
    454         spinlock_unlock(&instance->lock);
    455 }
    456 
    457 /** Scroll the framebuffer up
    458  *
    459  */
    460 static void fb_scroll_up(outdev_t *dev)
    461 {
    462         fb_instance_t *instance = (fb_instance_t *) dev->data;
    463         spinlock_lock(&instance->lock);
    464        
    465         if (instance->offset_row >= instance->rowtrim / 2)
    466                 instance->offset_row -= instance->rowtrim / 2;
    467         else
    468                 instance->offset_row = 0;
    469        
    470         fb_redraw_internal(instance);
    471         cursor_put(instance);
    472        
    473         spinlock_unlock(&instance->lock);
    474 }
    475 
    476 /** Scroll the framebuffer down
    477  *
    478  */
    479 static void fb_scroll_down(outdev_t *dev)
    480 {
    481         fb_instance_t *instance = (fb_instance_t *) dev->data;
    482         spinlock_lock(&instance->lock);
    483        
    484         if (instance->offset_row + instance->rowtrim / 2 <=
    485             instance->rows - instance->rowtrim)
    486                 instance->offset_row += instance->rowtrim / 2;
    487         else
    488                 instance->offset_row = instance->rows - instance->rowtrim;
    489        
    490         fb_redraw_internal(instance);
    491         cursor_put(instance);
    492        
    493         spinlock_unlock(&instance->lock);
    494 }
    495 
    496430/** Refresh the screen
    497431 *
     
    589523        instance->yres = props->y;
    590524        instance->scanline = props->scan;
    591        
    592         instance->rowtrim = Y2ROW(instance->yres);
     525        instance->position = 0;
    593526       
    594527        instance->cols = X2COL(instance->xres);
    595         instance->rows = FB_PAGES * instance->rowtrim;
    596        
    597         instance->start_row = instance->rows - instance->rowtrim;
    598         instance->offset_row = instance->start_row;
    599         instance->position = instance->start_row * instance->cols;
     528        instance->rows = Y2ROW(instance->yres);
     529       
     530        instance->rowtrim = instance->rows;
    600531       
    601532        instance->glyphscanline = FONT_WIDTH * instance->pixelbytes;
Note: See TracChangeset for help on using the changeset viewer.