source: mainline/kernel/genarch/src/drivers/ega/ega.c

Last change on this file was 39e1b9a, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 2 months ago

Convert console output devices to batch printing

  • Property mode set to 100644
File size: 12.8 KB
RevLine 
[f761f1eb]1/*
[df4ed85]2 * Copyright (c) 2001-2004 Jakub Jermar
[f761f1eb]3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
[6404aca]29/** @addtogroup kernel_genarch
[b45c443]30 * @{
31 */
[3c5006a0]32/**
33 * @file
34 * @brief EGA driver.
[b45c443]35 */
36
[63e27ef]37#include <debug.h>
[f245145]38#include <genarch/drivers/ega/ega.h>
[d4673296]39#include <mm/km.h>
[fc1e4f6]40#include <mm/as.h>
[aafed15]41#include <stdlib.h>
[d99c1d2]42#include <typedefs.h>
[f761f1eb]43#include <arch/asm.h>
[b169619]44#include <memw.h>
[19f857a]45#include <str.h>
[973be64e]46#include <console/chardev.h>
47#include <console/console.h>
[018f95a]48#include <sysinfo/sysinfo.h>
[f8ddd17]49#include <ddi/ddi.h>
[f761f1eb]50
51/*
52 * The EGA driver.
53 * Simple and short. Function for displaying characters and "scrolling".
54 */
55
[a0e1b48]56#define SPACE 0x20
[accc088]57#define STYLE 0x1e
58#define INVAL 0x17
[5d9d9a9]59
[accc088]60#define EMPTY_CHAR ((STYLE << 8) | SPACE)
61
[a71c158]62typedef struct {
[c263c77]63 IRQ_SPINLOCK_DECLARE(lock);
[a35b458]64
[b366a6f4]65 parea_t parea;
[a35b458]66
[a71c158]67 uint32_t cursor;
68 uint8_t *addr;
69 uint8_t *backbuf;
70 ioport8_t *base;
[39e1b9a]71 mbstate_t mbstate;
[a71c158]72} ega_instance_t;
73
[39e1b9a]74static void ega_write(outdev_t *, const char *, size_t);
[da1bafb]75static void ega_redraw(outdev_t *);
[a71c158]76
77static outdev_operations_t egadev_ops = {
[39e1b9a]78 .write = ega_write,
[7ddc2c7]79 .redraw = ega_redraw,
80 .scroll_up = NULL,
81 .scroll_down = NULL
[a71c158]82};
83
[28a5ebd]84static uint16_t ega_oem_glyph(const char32_t ch)
[accc088]85{
[28a5ebd]86 if (ch <= 0x007f)
[accc088]87 return ch;
[a35b458]88
[accc088]89 if (ch == 0x00a0)
90 return 255;
[a35b458]91
[accc088]92 if (ch == 0x00a1)
93 return 173;
[a35b458]94
[accc088]95 if ((ch >= 0x00a2) && (ch <= 0x00a3))
96 return (ch - 7);
[a35b458]97
[accc088]98 if (ch == 0x00a5)
99 return 157;
[a35b458]100
[accc088]101 if (ch == 0x00aa)
102 return 166;
[a35b458]103
[accc088]104 if (ch == 0x00ab)
105 return 174;
[a35b458]106
[accc088]107 if (ch == 0x00ac)
108 return 170;
[a35b458]109
[accc088]110 if (ch == 0x00b0)
111 return 248;
[a35b458]112
[accc088]113 if (ch == 0x00b1)
114 return 241;
[a35b458]115
[accc088]116 if (ch == 0x00b2)
117 return 253;
[a35b458]118
[accc088]119 if (ch == 0x00b5)
120 return 230;
[a35b458]121
[accc088]122 if (ch == 0x00b7)
123 return 250;
[a35b458]124
[accc088]125 if (ch == 0x00ba)
126 return 167;
[a35b458]127
[accc088]128 if (ch == 0x00bb)
129 return 175;
[a35b458]130
[accc088]131 if (ch == 0x00bc)
132 return 172;
[a35b458]133
[accc088]134 if (ch == 0x00bd)
135 return 171;
[a35b458]136
[accc088]137 if (ch == 0x00bf)
138 return 168;
[a35b458]139
[accc088]140 if ((ch >= 0x00c4) && (ch <= 0x00c5))
141 return (ch - 54);
[a35b458]142
[accc088]143 if (ch == 0x00c6)
144 return 146;
[a35b458]145
[accc088]146 if (ch == 0x00c7)
147 return 128;
[a35b458]148
[accc088]149 if (ch == 0x00c9)
150 return 144;
[a35b458]151
[accc088]152 if (ch == 0x00d1)
153 return 165;
[a35b458]154
[accc088]155 if (ch == 0x00d6)
156 return 153;
[a35b458]157
[accc088]158 if (ch == 0x00dc)
159 return 154;
[a35b458]160
[accc088]161 if (ch == 0x00df)
162 return 225;
[a35b458]163
[accc088]164 if (ch == 0x00e0)
165 return 133;
[a35b458]166
[accc088]167 if (ch == 0x00e1)
168 return 160;
[a35b458]169
[accc088]170 if (ch == 0x00e2)
171 return 131;
[a35b458]172
[accc088]173 if (ch == 0x00e4)
174 return 132;
[a35b458]175
[accc088]176 if (ch == 0x00e5)
177 return 134;
[a35b458]178
[accc088]179 if (ch == 0x00e6)
180 return 145;
[a35b458]181
[accc088]182 if (ch == 0x00e7)
183 return 135;
[a35b458]184
[accc088]185 if (ch == 0x00e8)
186 return 138;
[a35b458]187
[accc088]188 if (ch == 0x00e9)
189 return 130;
[a35b458]190
[accc088]191 if ((ch >= 0x00ea) && (ch <= 0x00eb))
192 return (ch - 98);
[a35b458]193
[accc088]194 if (ch == 0x00ec)
195 return 141;
[a35b458]196
[accc088]197 if (ch == 0x00ed)
198 return 161;
[a35b458]199
[accc088]200 if (ch == 0x00ee)
201 return 140;
[a35b458]202
[accc088]203 if (ch == 0x00ef)
204 return 139;
[a35b458]205
[accc088]206 if (ch == 0x00f1)
207 return 164;
[a35b458]208
[accc088]209 if (ch == 0x00f2)
210 return 149;
[a35b458]211
[accc088]212 if (ch == 0x00f3)
213 return 162;
[a35b458]214
[accc088]215 if (ch == 0x00f4)
216 return 147;
[a35b458]217
[accc088]218 if (ch == 0x00f6)
219 return 148;
[a35b458]220
[accc088]221 if (ch == 0x00f7)
222 return 246;
[a35b458]223
[accc088]224 if (ch == 0x00f9)
225 return 151;
[a35b458]226
[accc088]227 if (ch == 0x00fa)
228 return 163;
[a35b458]229
[accc088]230 if (ch == 0x00fb)
231 return 150;
[a35b458]232
[accc088]233 if (ch == 0x00fc)
234 return 129;
[a35b458]235
[accc088]236 if (ch == 0x00ff)
237 return 152;
[a35b458]238
[accc088]239 if (ch == 0x0192)
240 return 159;
[a35b458]241
[accc088]242 if (ch == 0x0393)
243 return 226;
[a35b458]244
[accc088]245 if (ch == 0x0398)
246 return 233;
[a35b458]247
[accc088]248 if (ch == 0x03a3)
249 return 228;
[a35b458]250
[accc088]251 if (ch == 0x03a6)
252 return 232;
[a35b458]253
[accc088]254 if (ch == 0x03a9)
255 return 234;
[a35b458]256
[accc088]257 if (ch == 0x03b1)
258 return 224;
[a35b458]259
[accc088]260 if (ch == 0x03b4)
261 return 235;
[a35b458]262
[accc088]263 if (ch == 0x03b5)
264 return 238;
[a35b458]265
[accc088]266 if (ch == 0x03c0)
267 return 227;
[a35b458]268
[accc088]269 if (ch == 0x03c3)
270 return 229;
[a35b458]271
[accc088]272 if (ch == 0x03c4)
273 return 231;
[a35b458]274
[accc088]275 if (ch == 0x03c6)
276 return 237;
[a35b458]277
[accc088]278 if (ch == 0x207f)
279 return 252;
[a35b458]280
[accc088]281 if (ch == 0x20a7)
282 return 158;
[a35b458]283
[accc088]284 if (ch == 0x2219)
285 return 249;
[a35b458]286
[accc088]287 if (ch == 0x221a)
288 return 251;
[a35b458]289
[accc088]290 if (ch == 0x221e)
291 return 236;
[a35b458]292
[accc088]293 if (ch == 0x2229)
294 return 239;
[a35b458]295
[accc088]296 if (ch == 0x2248)
297 return 247;
[a35b458]298
[accc088]299 if (ch == 0x2261)
300 return 240;
[a35b458]301
[accc088]302 if (ch == 0x2264)
303 return 243;
[a35b458]304
[accc088]305 if (ch == 0x2265)
306 return 242;
[a35b458]307
[accc088]308 if (ch == 0x2310)
309 return 169;
[a35b458]310
[accc088]311 if ((ch >= 0x2320) && (ch <= 0x2321))
312 return (ch - 8748);
[a35b458]313
[accc088]314 if (ch == 0x2500)
315 return 196;
[a35b458]316
[accc088]317 if (ch == 0x2502)
318 return 179;
[a35b458]319
[accc088]320 if (ch == 0x250c)
321 return 218;
[a35b458]322
[accc088]323 if (ch == 0x2510)
324 return 191;
[a35b458]325
[accc088]326 if (ch == 0x2514)
327 return 192;
[a35b458]328
[accc088]329 if (ch == 0x2518)
330 return 217;
[a35b458]331
[accc088]332 if (ch == 0x251c)
333 return 195;
[a35b458]334
[accc088]335 if (ch == 0x2524)
336 return 180;
[a35b458]337
[accc088]338 if (ch == 0x252c)
339 return 194;
[a35b458]340
[accc088]341 if (ch == 0x2534)
342 return 193;
[a35b458]343
[accc088]344 if (ch == 0x253c)
345 return 197;
[a35b458]346
[accc088]347 if (ch == 0x2550)
348 return 205;
[a35b458]349
[accc088]350 if (ch == 0x2551)
351 return 186;
[a35b458]352
[accc088]353 if ((ch >= 0x2552) && (ch <= 0x2553))
354 return (ch - 9341);
[a35b458]355
[accc088]356 if (ch == 0x2554)
357 return 201;
[a35b458]358
[accc088]359 if (ch == 0x2555)
360 return 184;
[a35b458]361
[accc088]362 if (ch == 0x2556)
363 return 183;
[a35b458]364
[accc088]365 if (ch == 0x2557)
366 return 187;
[a35b458]367
[accc088]368 if (ch == 0x2558)
369 return 212;
[a35b458]370
[accc088]371 if (ch == 0x2559)
372 return 211;
[a35b458]373
[accc088]374 if (ch == 0x255a)
375 return 200;
[a35b458]376
[accc088]377 if (ch == 0x255b)
378 return 190;
[a35b458]379
[accc088]380 if (ch == 0x255c)
381 return 189;
[a35b458]382
[accc088]383 if (ch == 0x255d)
384 return 188;
[a35b458]385
[accc088]386 if ((ch >= 0x255e) && (ch <= 0x255f))
387 return (ch - 9368);
[a35b458]388
[accc088]389 if (ch == 0x2560)
390 return 204;
[a35b458]391
[accc088]392 if ((ch >= 0x2561) && (ch <= 0x2562))
393 return (ch - 9388);
[a35b458]394
[accc088]395 if (ch == 0x2563)
396 return 185;
[a35b458]397
[accc088]398 if ((ch >= 0x2564) && (ch <= 0x2565))
399 return (ch - 9363);
[a35b458]400
[accc088]401 if (ch == 0x2566)
402 return 203;
[a35b458]403
[accc088]404 if ((ch >= 0x2567) && (ch <= 0x2568))
405 return (ch - 9368);
[a35b458]406
[accc088]407 if (ch == 0x2569)
408 return 202;
[a35b458]409
[accc088]410 if (ch == 0x256a)
411 return 216;
[a35b458]412
[accc088]413 if (ch == 0x256b)
414 return 215;
[a35b458]415
[accc088]416 if (ch == 0x256c)
417 return 206;
[a35b458]418
[accc088]419 if (ch == 0x2580)
420 return 223;
[a35b458]421
[accc088]422 if (ch == 0x2584)
423 return 220;
[a35b458]424
[accc088]425 if (ch == 0x2588)
426 return 219;
[a35b458]427
[accc088]428 if (ch == 0x258c)
429 return 221;
[a35b458]430
[accc088]431 if (ch == 0x2590)
432 return 222;
[a35b458]433
[accc088]434 if ((ch >= 0x2591) && (ch <= 0x2593))
435 return (ch - 9441);
[a35b458]436
[accc088]437 return 256;
438}
[f761f1eb]439
440/*
441 * This function takes care of scrolling.
442 */
[b366a6f4]443static void ega_check_cursor(ega_instance_t *instance)
[f761f1eb]444{
[a71c158]445 if (instance->cursor < EGA_SCREEN)
[76cec1e]446 return;
[a35b458]447
[a71c158]448 memmove((void *) instance->backbuf,
449 (void *) (instance->backbuf + EGA_COLS * 2),
[9979acb]450 (EGA_SCREEN - EGA_COLS) * 2);
[a71c158]451 memsetw(instance->backbuf + (EGA_SCREEN - EGA_COLS) * 2,
452 EGA_COLS, EMPTY_CHAR);
[a35b458]453
[b366a6f4]454 if ((!instance->parea.mapped) || (console_override)) {
[a71c158]455 memmove((void *) instance->addr,
456 (void *) (instance->addr + EGA_COLS * 2),
[d797054c]457 (EGA_SCREEN - EGA_COLS) * 2);
[a71c158]458 memsetw(instance->addr + (EGA_SCREEN - EGA_COLS) * 2,
459 EGA_COLS, EMPTY_CHAR);
[d797054c]460 }
[a35b458]461
[a71c158]462 instance->cursor = instance->cursor - EGA_COLS;
[f761f1eb]463}
464
[b366a6f4]465static void ega_show_cursor(ega_instance_t *instance)
[c214a65]466{
[b366a6f4]467 if ((!instance->parea.mapped) || (console_override)) {
[a71c158]468 pio_write_8(instance->base + EGA_INDEX_REG, 0x0a);
469 uint8_t stat = pio_read_8(instance->base + EGA_DATA_REG);
470 pio_write_8(instance->base + EGA_INDEX_REG, 0x0a);
471 pio_write_8(instance->base + EGA_DATA_REG, stat & (~(1 << 5)));
[d797054c]472 }
[c214a65]473}
474
[b366a6f4]475static void ega_move_cursor(ega_instance_t *instance)
[f761f1eb]476{
[b366a6f4]477 if ((!instance->parea.mapped) || (console_override)) {
[a71c158]478 pio_write_8(instance->base + EGA_INDEX_REG, 0x0e);
479 pio_write_8(instance->base + EGA_DATA_REG,
480 (uint8_t) ((instance->cursor >> 8) & 0xff));
481 pio_write_8(instance->base + EGA_INDEX_REG, 0x0f);
482 pio_write_8(instance->base + EGA_DATA_REG,
483 (uint8_t) (instance->cursor & 0xff));
[d797054c]484 }
[516ff92]485}
486
[b366a6f4]487static void ega_sync_cursor(ega_instance_t *instance)
[c214a65]488{
[b366a6f4]489 if ((!instance->parea.mapped) || (console_override)) {
[a71c158]490 pio_write_8(instance->base + EGA_INDEX_REG, 0x0e);
491 uint8_t hi = pio_read_8(instance->base + EGA_DATA_REG);
492 pio_write_8(instance->base + EGA_INDEX_REG, 0x0f);
493 uint8_t lo = pio_read_8(instance->base + EGA_DATA_REG);
[a35b458]494
[a71c158]495 instance->cursor = (hi << 8) | lo;
[d797054c]496 } else
[a71c158]497 instance->cursor = 0;
[a35b458]498
[a71c158]499 if (instance->cursor >= EGA_SCREEN)
500 instance->cursor = 0;
[a35b458]501
[a71c158]502 if ((instance->cursor % EGA_COLS) != 0)
503 instance->cursor =
504 (instance->cursor + EGA_COLS) - instance->cursor % EGA_COLS;
[a35b458]505
[a71c158]506 memsetw(instance->backbuf + instance->cursor * 2,
507 EGA_SCREEN - instance->cursor, EMPTY_CHAR);
[a35b458]508
[b366a6f4]509 if ((!instance->parea.mapped) || (console_override))
[a71c158]510 memsetw(instance->addr + instance->cursor * 2,
511 EGA_SCREEN - instance->cursor, EMPTY_CHAR);
[a35b458]512
[b366a6f4]513 ega_check_cursor(instance);
514 ega_move_cursor(instance);
515 ega_show_cursor(instance);
[c214a65]516}
517
[28a5ebd]518static void ega_display_wchar(ega_instance_t *instance, char32_t ch)
[516ff92]519{
[accc088]520 uint16_t index = ega_oem_glyph(ch);
521 uint8_t glyph;
522 uint8_t style;
[a35b458]523
[accc088]524 if ((index >> 8)) {
[c8bf88d]525 glyph = U_SPECIAL;
[accc088]526 style = INVAL;
527 } else {
528 glyph = index & 0xff;
529 style = STYLE;
530 }
[a35b458]531
[a71c158]532 instance->backbuf[instance->cursor * 2] = glyph;
533 instance->backbuf[instance->cursor * 2 + 1] = style;
[a35b458]534
[b366a6f4]535 if ((!instance->parea.mapped) || (console_override)) {
[a71c158]536 instance->addr[instance->cursor * 2] = glyph;
537 instance->addr[instance->cursor * 2 + 1] = style;
[a0e1b48]538 }
[516ff92]539}
[f761f1eb]540
[39e1b9a]541static void _putuchar(ega_instance_t *instance, char32_t ch)
[516ff92]542{
[f761f1eb]543 switch (ch) {
[6dbe6844]544 case '\n':
[3bacee1]545 instance->cursor = (instance->cursor + EGA_COLS) -
546 instance->cursor % EGA_COLS;
[6dbe6844]547 break;
548 case '\t':
[3bacee1]549 instance->cursor = (instance->cursor + 8) -
550 instance->cursor % 8;
[accc088]551 break;
[6dbe6844]552 case '\b':
[a71c158]553 if (instance->cursor % EGA_COLS)
554 instance->cursor--;
[6dbe6844]555 break;
556 default:
[ed88c8e]557 ega_display_wchar(instance, ch);
[a71c158]558 instance->cursor++;
[6dbe6844]559 break;
[018f95a]560 }
[b366a6f4]561 ega_check_cursor(instance);
562 ega_move_cursor(instance);
[39e1b9a]563}
564
565static void ega_write(outdev_t *dev, const char *s, size_t n)
566{
567 ega_instance_t *instance = (ega_instance_t *) dev->data;
568
569 irq_spinlock_lock(&instance->lock, true);
570
571 size_t offset = 0;
572 char32_t ch;
573
574 while ((ch = str_decode_r(s, &offset, n, U_SPECIAL, &instance->mbstate)))
575 _putuchar(instance, ch);
[a35b458]576
[c263c77]577 irq_spinlock_unlock(&instance->lock, true);
[f761f1eb]578}
579
[e037cf37]580static void ega_redraw_internal(ega_instance_t *instance)
581{
582 memcpy(instance->addr, instance->backbuf, EGA_VRAM_SIZE);
583 ega_move_cursor(instance);
584 ega_show_cursor(instance);
585}
586
[a71c158]587static void ega_redraw(outdev_t *dev)
[f761f1eb]588{
[a71c158]589 ega_instance_t *instance = (ega_instance_t *) dev->data;
[a35b458]590
[c263c77]591 irq_spinlock_lock(&instance->lock, true);
[e037cf37]592 ega_redraw_internal(instance);
593 irq_spinlock_unlock(&instance->lock, true);
594}
[a35b458]595
[e037cf37]596/** EGA was mapped or unmapped.
597 *
598 * @param arg EGA instance
599 */
600static void ega_mapped_changed(void *arg)
601{
602 ega_instance_t *instance = (ega_instance_t *) arg;
[a35b458]603
[e037cf37]604 if (!instance->parea.mapped) {
605 irq_spinlock_lock(&instance->lock, true);
606 ega_redraw_internal(instance);
607 irq_spinlock_unlock(&instance->lock, true);
608 }
[f761f1eb]609}
[b45c443]610
[a71c158]611outdev_t *ega_init(ioport8_t *base, uintptr_t addr)
[9a63657]612{
[11b285d]613 outdev_t *egadev = malloc(sizeof(outdev_t));
[a71c158]614 if (!egadev)
615 return NULL;
[a35b458]616
[11b285d]617 ega_instance_t *instance = malloc(sizeof(ega_instance_t));
[a71c158]618 if (!instance) {
619 free(egadev);
620 return NULL;
621 }
[a35b458]622
[a71c158]623 outdev_initialize("egadev", egadev, &egadev_ops);
624 egadev->data = instance;
[a35b458]625
[c263c77]626 irq_spinlock_initialize(&instance->lock, "*ega.instance.lock");
[a35b458]627
[a71c158]628 instance->base = base;
[adec5b45]629 instance->addr = (uint8_t *) km_map(addr, EGA_VRAM_SIZE,
[a1b9f63]630 KM_NATURAL_ALIGNMENT, PAGE_WRITE | PAGE_NOT_CACHEABLE);
[a71c158]631 if (!instance->addr) {
632 LOG("Unable to EGA video memory.");
633 free(instance);
634 free(egadev);
635 return NULL;
636 }
[a35b458]637
[11b285d]638 instance->backbuf = (uint8_t *) malloc(EGA_VRAM_SIZE);
[a71c158]639 if (!instance->backbuf) {
640 LOG("Unable to allocate backbuffer.");
641 free(instance);
642 free(egadev);
643 return NULL;
644 }
[a35b458]645
[6f7071b]646 ddi_parea_init(&instance->parea);
[b366a6f4]647 instance->parea.pbase = addr;
648 instance->parea.frames = SIZE2FRAMES(EGA_VRAM_SIZE);
649 instance->parea.unpriv = false;
650 instance->parea.mapped = false;
[e037cf37]651 instance->parea.mapped_changed = ega_mapped_changed;
652 instance->parea.arg = (void *) instance;
[b366a6f4]653 ddi_parea_register(&instance->parea);
[a35b458]654
[a71c158]655 /* Synchronize the back buffer and cursor position. */
656 memcpy(instance->backbuf, instance->addr, EGA_VRAM_SIZE);
[b366a6f4]657 ega_sync_cursor(instance);
[a35b458]658
[a71c158]659 if (!fb_exported) {
660 /*
[b366a6f4]661 * We export the kernel framebuffer for uspace usage.
662 * This is used in the case the uspace framebuffer
663 * driver is not self-sufficient.
[a71c158]664 */
665 sysinfo_set_item_val("fb", NULL, true);
666 sysinfo_set_item_val("fb.kind", NULL, 2);
667 sysinfo_set_item_val("fb.width", NULL, EGA_COLS);
668 sysinfo_set_item_val("fb.height", NULL, EGA_ROWS);
669 sysinfo_set_item_val("fb.blinking", NULL, true);
670 sysinfo_set_item_val("fb.address.physical", NULL, addr);
[a35b458]671
[a71c158]672 fb_exported = true;
673 }
[a35b458]674
[a71c158]675 return egadev;
[9a63657]676}
677
[3c5006a0]678/** @}
[b45c443]679 */
Note: See TracBrowser for help on using the repository browser.