Fork me on GitHub

root/drivers/video/vgacon.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. vgacon_put_char
  2. vgacon_insert_char
  3. vgacon_delete_char
  4. vgacon_update_curpos
  5. vgacon_show_cursor
  6. vgacon_get_curpos
  7. vgacon_write_screen
  8. vgacon_blank_screen
  9. vgacon_scroll_screen
  10. vgacon_restore_screen
  11. vgacon_screen_on
  12. vgacon_screen_off
  13. vgacon_buf_scroll
  14. vgacon_cursor_blink
  15. vgacon_init

   1 /*
   2  * fiwix/drivers/char/vgacon.c
   3  *
   4  * Copyright 2021, Jordi Sanfeliu. All rights reserved.
   5  * Distributed under the terms of the Fiwix License.
   6  */
   7 
   8 #include <fiwix/asm.h>
   9 #include <fiwix/config.h>
  10 #include <fiwix/segments.h>
  11 #include <fiwix/vgacon.h>
  12 #include <fiwix/console.h>
  13 #include <fiwix/timer.h>
  14 #include <fiwix/stdio.h>
  15 #include <fiwix/string.h>
  16 
  17 /* ISO/IEC 8859-1:1998 (aka latin1, IBM819, CP819), same as in Linux */
  18 static const char *iso8859 =
  19         "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
  20         "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
  21         " !\"#$%&'()*+,-./0123456789:;<=>?"
  22         "@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"
  23         "`abcdefghijklmnopqrstuvwxyz{|}~\0"
  24         "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
  25         "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
  26         "\377\255\233\234\376\235\174\025\376\376\246\256\252\055\376\376"
  27         "\370\361\375\376\376\346\024\371\376\376\247\257\254\253\376\250"
  28         "\376\376\376\376\216\217\222\200\376\220\376\376\376\376\376\376"
  29         "\376\245\376\376\376\376\231\376\350\376\376\376\232\376\376\341"
  30         "\205\240\203\376\204\206\221\207\212\202\210\211\215\241\214\213"
  31         "\376\244\225\242\223\376\224\366\355\227\243\226\201\376\376\230"
  32 ;
  33 
  34 struct video_parms video;
  35 static unsigned char screen_is_off = 0;
  36 
  37 void vgacon_put_char(struct vconsole *vc, unsigned char ch)
  38 {
  39         short int *vidmem, *screen;
  40 
  41         ch = iso8859[ch];
  42         screen = vc->screen;
  43 
  44         if(!(vc->flags & CONSOLE_HAS_FOCUS)) {
  45                 screen[(vc->y * vc->columns) + vc->x] = vc->color_attr | ch;
  46                 return;
  47         }
  48 
  49         vidmem = (short int *)vc->vidmem;
  50         vidmem[(vc->y * vc->columns) + vc->x] = vc->color_attr | ch;
  51         screen[(vc->y * vc->columns) + vc->x] = vc->color_attr | ch;
  52         vcbuf[(video.buf_y * vc->columns) + vc->x] = vc->color_attr | ch;
  53 }
  54 
  55 void vgacon_insert_char(struct vconsole *vc)
  56 {
  57         int n, offset;
  58         short int tmp, last_char, *vidmem, *screen;
  59 
  60         vidmem = (short int *)vc->vidmem;
  61         screen = vc->screen;
  62         offset = (vc->y * vc->columns) + vc->x;
  63         n = vc->x;
  64         last_char = BLANK_MEM;
  65 
  66         while(n++ < vc->columns) {
  67                 if(vc->flags & CONSOLE_HAS_FOCUS) {
  68                         memcpy_w(&tmp, vidmem + offset, 1);
  69                         memset_w(vidmem + offset, last_char, 1);
  70                 }
  71                 memcpy_w(&tmp, screen + offset, 1);
  72                 memset_w(screen + offset, last_char, 1);
  73                 last_char = tmp;
  74                 offset++;
  75         }
  76 }
  77 
  78 void vgacon_delete_char(struct vconsole *vc)
  79 {
  80         int offset, count;
  81         short int *vidmem, *screen;
  82 
  83         vidmem = (short int *)vc->vidmem;
  84         screen = vc->screen;
  85         offset = (vc->y * vc->columns) + vc->x;
  86         count = vc->columns - vc->x;
  87 
  88         if(vc->flags & CONSOLE_HAS_FOCUS) {
  89                 memcpy_w(vidmem + offset, vidmem + offset + 1, count);
  90                 memset_w(vidmem + offset + count, BLANK_MEM, 1);
  91         }
  92         memcpy_w(screen + offset, screen + offset + 1, count);
  93         memset_w(screen + offset + count, BLANK_MEM, 1);
  94 }
  95 
  96 void vgacon_update_curpos(struct vconsole *vc)
  97 {
  98         unsigned short int curpos;
  99 
 100         if(vc->flags & CONSOLE_HAS_FOCUS) {
 101                 curpos = (vc->y * vc->columns) + vc->x;
 102                 outport_b(video.port + CRT_INDEX, CRT_CURSOR_POS_HI);
 103                 outport_b(video.port + CRT_DATA, (curpos >> 8) & 0xFF);
 104                 outport_b(video.port + CRT_INDEX, CRT_CURSOR_POS_LO);
 105                 outport_b(video.port + CRT_DATA, (curpos & 0xFF));
 106         }
 107 }
 108 
 109 void vgacon_show_cursor(struct vconsole *vc, int mode)
 110 {
 111         int status;
 112 
 113         switch(mode) {
 114                 case COND:
 115                         if(!(video.flags & VPF_CURSOR_ON)) {
 116                                 break;
 117                         }
 118                         /* fall through */
 119                 case ON:
 120                         outport_b(video.port + CRT_INDEX, CRT_CURSOR_STR);
 121                         status = inport_b(video.port + CRT_DATA);
 122                         outport_b(video.port + CRT_DATA, status & CURSOR_MASK);
 123                         video.flags |= VPF_CURSOR_ON;
 124                         break;
 125                 case OFF:
 126                         outport_b(video.port + CRT_INDEX, CRT_CURSOR_STR);
 127                         status = inport_b(video.port + CRT_DATA);
 128                         outport_b(video.port + CRT_DATA, status | CURSOR_DISABLE);
 129                         video.flags &= ~VPF_CURSOR_ON;
 130                         break;
 131         }
 132 }
 133 
 134 void vgacon_get_curpos(struct vconsole *vc)
 135 {
 136         unsigned short int curpos;
 137 
 138         outport_b(video.port + CRT_INDEX, CRT_CURSOR_POS_HI);
 139         curpos = inport_b(video.port + CRT_DATA) << 8;
 140         outport_b(video.port + CRT_INDEX, CRT_CURSOR_POS_LO);
 141         curpos |= inport_b(video.port + CRT_DATA);
 142 
 143         vc->x = curpos % vc->columns;
 144         vc->y = curpos / vc->columns;
 145 }       
 146 
 147 void vgacon_write_screen(struct vconsole *vc, int from, int count, short int color)
 148 {
 149         short int *vidmem, *screen;
 150 
 151         screen = vc->screen;
 152         if(!(vc->flags & CONSOLE_HAS_FOCUS)) {
 153                 memset_w(screen + from, color, count);
 154                 return;
 155         }
 156 
 157         vidmem = (short int *)vc->vidmem;
 158         memset_w(vidmem + from, color, count);
 159         memset_w(screen + from, color, count);
 160 }
 161 
 162 void vgacon_blank_screen(struct vconsole *vc)
 163 {
 164         short int *vidmem;
 165 
 166         if(vc->flags & CONSOLE_BLANKED) {
 167                 return;
 168         }
 169 
 170         if(vc->flags & CONSOLE_HAS_FOCUS) {
 171                 vidmem = (short int *)vc->vidmem;
 172                 memset_w(vidmem, BLANK_MEM, SCREEN_SIZE);
 173         }
 174         vc->flags |= CONSOLE_BLANKED;
 175         vgacon_show_cursor(vc, OFF);
 176 }
 177 
 178 void vgacon_scroll_screen(struct vconsole *vc, int top, int mode)
 179 {
 180         int n, offset, count;
 181         short int *vidmem, *screen;
 182 
 183         vidmem = (short int *)vc->vidmem;
 184         screen = vc->screen;
 185 
 186         if(!top) {
 187                 top = vc->top;
 188         }
 189         switch(mode) {
 190                 case SCROLL_UP:
 191                         count = vc->columns * (vc->lines - top - 1);
 192                         offset = top * vc->columns;
 193                         top = (top + 1) * vc->columns;
 194                         if(vc->flags & CONSOLE_HAS_FOCUS) {
 195                                 memcpy_w(vidmem + offset, vidmem + top, count);
 196                                 memset_w(vidmem + offset + count, BLANK_MEM, vc->columns);
 197                         }
 198                         memcpy_w(screen + offset, screen + top, count);
 199                         memset_w(screen + offset + count, BLANK_MEM, vc->columns);
 200                         break;
 201                 case SCROLL_DOWN:
 202                         count = vc->columns;
 203                         for(n = vc->lines - 1; n > top; n--) {
 204                                 memcpy_w(screen + (vc->columns * n), screen + (vc->columns * (n - 1)), count);
 205                                 if(vc->flags & CONSOLE_HAS_FOCUS) {
 206                                         memcpy_w(vidmem + (vc->columns * n), screen + (vc->columns * (n - 1)), count);
 207                                 }
 208                         }
 209                         memset_w(screen + (top * vc->columns), BLANK_MEM, count);
 210                         if(vc->flags & CONSOLE_HAS_FOCUS) {
 211                                 memset_w(vidmem + (top * vc->columns), BLANK_MEM, count);
 212                         }
 213                         break;
 214         }
 215         return;
 216 }
 217 
 218 void vgacon_restore_screen(struct vconsole *vc)
 219 {
 220         short int *vidmem;
 221 
 222         if(vc->flags & CONSOLE_HAS_FOCUS) {
 223                 vidmem = (short int *)vc->vidmem;
 224                 memcpy_w(vidmem, vc->screen, SCREEN_SIZE);
 225         }
 226 }
 227 
 228 void vgacon_screen_on(struct vconsole *vc)
 229 {
 230         unsigned long int flags;
 231         struct callout_req creq;
 232 
 233         if(screen_is_off) {
 234                 SAVE_FLAGS(flags); CLI();
 235                 inport_b(INPUT_STAT1);
 236                 inport_b(0x3BA);
 237                 outport_b(ATTR_CONTROLLER, ATTR_CONTROLLER_PAS);
 238                 RESTORE_FLAGS(flags);
 239         }
 240 
 241         if(BLANK_INTERVAL) {
 242                 creq.fn = vgacon_screen_off;
 243                 creq.arg = 0;
 244                 add_callout(&creq, BLANK_INTERVAL);
 245         }
 246 }
 247 
 248 void vgacon_screen_off(unsigned int arg)
 249 {
 250         unsigned long int flags;
 251 
 252         screen_is_off = 1;
 253         SAVE_FLAGS(flags); CLI();
 254         inport_b(INPUT_STAT1);
 255         inport_b(0x3BA);
 256         outport_b(ATTR_CONTROLLER, 0);
 257         RESTORE_FLAGS(flags);
 258 }
 259 
 260 void vgacon_buf_scroll(struct vconsole *vc, int mode)
 261 {
 262         short int *vidmem;
 263 
 264         if(video.buf_y <= SCREEN_LINES) {
 265                 return;
 266         }
 267 
 268         vidmem = (short int *)vc->vidmem;
 269         if(mode == SCROLL_UP) {
 270                 if(video.buf_top < 0) {
 271                         return;
 272                 }
 273                 if(!video.buf_top) {
 274                         video.buf_top = (video.buf_y - SCREEN_LINES + 1) * SCREEN_COLS;
 275                 }
 276                 video.buf_top -= (SCREEN_LINES / 2) * SCREEN_COLS;
 277                 if(video.buf_top < 0) {
 278                         video.buf_top = 0;
 279                 }
 280                 memcpy_w(vidmem, vcbuf + video.buf_top, SCREEN_SIZE);
 281                 if(!video.buf_top) {
 282                         video.buf_top = -1;
 283                 }
 284                 vgacon_show_cursor(vc, OFF);
 285                 return;
 286         }
 287         if(mode == SCROLL_DOWN) {
 288                 if(!video.buf_top) {
 289                         return;
 290                 }
 291                 if(video.buf_top == video.buf_y * SCREEN_COLS) {
 292                         return;
 293                 }
 294                 if(video.buf_top < 0) {
 295                         video.buf_top = 0;
 296                 }
 297                 video.buf_top += (SCREEN_LINES / 2) * SCREEN_COLS;
 298                 if(video.buf_top >= (video.buf_y - SCREEN_LINES + 1) * SCREEN_COLS) {
 299                         vgacon_restore_screen(vc);
 300                         video.buf_top = 0;
 301                         vgacon_show_cursor(vc, ON);
 302                         vgacon_update_curpos(vc);
 303                         return;
 304                 }
 305                 memcpy_w(vidmem, vcbuf + video.buf_top, SCREEN_SIZE);
 306                 return;
 307         }
 308 }
 309 
 310 void vgacon_cursor_blink(unsigned int arg)
 311 {
 312         /* not used */
 313 }
 314 
 315 void vgacon_init(void)
 316 {
 317         short int *bios_data;
 318 
 319         /* get the VGA type from the BIOS equipment information */
 320         bios_data = (short int *)(KERNEL_BASE_ADDR + 0x410);
 321         if((*bios_data & 0x30) == 0x30) {
 322                 /* monochrome = 0x30 */
 323                 video.address = (void *)MONO_ADDR;
 324                 video.port = MONO_6845_ADDR;
 325                 strcpy((char *)video.signature, "VGA monochrome 80x25");
 326         } else {
 327                 /* color = 0x00 || 0x20 */
 328                 video.address = (void *)COLOR_ADDR;
 329                 video.port = COLOR_6845_ADDR;
 330                 strcpy((char *)video.signature, "VGA color 80x25");
 331         }
 332 
 333         /* some parameters already set in multiboot.c */
 334 
 335         video.put_char = vgacon_put_char;
 336         video.insert_char = vgacon_insert_char;
 337         video.delete_char = vgacon_delete_char;
 338         video.update_curpos = vgacon_update_curpos;
 339         video.show_cursor = vgacon_show_cursor;
 340         video.get_curpos = vgacon_get_curpos;
 341         video.write_screen = vgacon_write_screen;
 342         video.blank_screen = vgacon_blank_screen;
 343         video.scroll_screen = vgacon_scroll_screen;
 344         video.restore_screen = vgacon_restore_screen;
 345         video.screen_on = vgacon_screen_on;
 346         video.buf_scroll = vgacon_buf_scroll;
 347         video.cursor_blink = vgacon_cursor_blink;
 348 
 349         memcpy_w(vcbuf, video.address, SCREEN_SIZE * 2);
 350 }

/* [previous][next][first][last][top][bottom][index][help] */