Changes in kernel/genarch/src/drivers/ega/ega.c [a71c158:d797054c] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/genarch/src/drivers/ega/ega.c
ra71c158 rd797054c 56 56 */ 57 57 58 SPINLOCK_INITIALIZE(egalock); 59 static uint32_t ega_cursor; 60 static uint8_t *videoram; 61 static uint8_t *backbuf; 62 static ioport8_t *ega_base; 63 58 64 #define SPACE 0x20 59 65 #define STYLE 0x1e … … 62 68 #define EMPTY_CHAR ((STYLE << 8) | SPACE) 63 69 64 typedef struct {65 SPINLOCK_DECLARE(lock);66 67 uint32_t cursor;68 uint8_t *addr;69 uint8_t *backbuf;70 ioport8_t *base;71 } ega_instance_t;72 73 static void ega_putchar(outdev_t *dev, wchar_t ch, bool silent);74 static void ega_redraw(outdev_t *dev);75 76 static outdev_operations_t egadev_ops = {77 .write = ega_putchar,78 .redraw = ega_redraw79 };80 81 70 static uint16_t ega_oem_glyph(const wchar_t ch) 82 71 { … … 438 427 * This function takes care of scrolling. 439 428 */ 440 static void ega_check_cursor( ega_instance_t *instance,bool silent)441 { 442 if ( instance->cursor < EGA_SCREEN)429 static void ega_check_cursor(bool silent) 430 { 431 if (ega_cursor < EGA_SCREEN) 443 432 return; 444 433 445 memmove((void *) instance->backbuf, 446 (void *) (instance->backbuf + EGA_COLS * 2), 434 memmove((void *) backbuf, (void *) (backbuf + EGA_COLS * 2), 447 435 (EGA_SCREEN - EGA_COLS) * 2); 448 memsetw(instance->backbuf + (EGA_SCREEN - EGA_COLS) * 2, 449 EGA_COLS, EMPTY_CHAR); 436 memsetw(backbuf + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR); 450 437 451 438 if (!silent) { 452 memmove((void *) instance->addr, 453 (void *) (instance->addr + EGA_COLS * 2), 439 memmove((void *) videoram, (void *) (videoram + EGA_COLS * 2), 454 440 (EGA_SCREEN - EGA_COLS) * 2); 455 memsetw(instance->addr + (EGA_SCREEN - EGA_COLS) * 2, 456 EGA_COLS, EMPTY_CHAR); 441 memsetw(videoram + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR); 457 442 } 458 443 459 instance->cursor = instance->cursor - EGA_COLS;460 } 461 462 static void ega_show_cursor( ega_instance_t *instance,bool silent)444 ega_cursor = ega_cursor - EGA_COLS; 445 } 446 447 static void ega_show_cursor(bool silent) 463 448 { 464 449 if (!silent) { 465 pio_write_8( instance->base + EGA_INDEX_REG, 0x0a);466 uint8_t stat = pio_read_8( instance->base + EGA_DATA_REG);467 pio_write_8( instance->base + EGA_INDEX_REG, 0x0a);468 pio_write_8( instance->base + EGA_DATA_REG, stat & (~(1 << 5)));450 pio_write_8(ega_base + EGA_INDEX_REG, 0x0a); 451 uint8_t stat = pio_read_8(ega_base + EGA_DATA_REG); 452 pio_write_8(ega_base + EGA_INDEX_REG, 0x0a); 453 pio_write_8(ega_base + EGA_DATA_REG, stat & (~(1 << 5))); 469 454 } 470 455 } 471 456 472 static void ega_move_cursor( ega_instance_t *instance,bool silent)457 static void ega_move_cursor(bool silent) 473 458 { 474 459 if (!silent) { 475 pio_write_8(instance->base + EGA_INDEX_REG, 0x0e); 476 pio_write_8(instance->base + EGA_DATA_REG, 477 (uint8_t) ((instance->cursor >> 8) & 0xff)); 478 pio_write_8(instance->base + EGA_INDEX_REG, 0x0f); 479 pio_write_8(instance->base + EGA_DATA_REG, 480 (uint8_t) (instance->cursor & 0xff)); 460 pio_write_8(ega_base + EGA_INDEX_REG, 0x0e); 461 pio_write_8(ega_base + EGA_DATA_REG, (uint8_t) ((ega_cursor >> 8) & 0xff)); 462 pio_write_8(ega_base + EGA_INDEX_REG, 0x0f); 463 pio_write_8(ega_base + EGA_DATA_REG, (uint8_t) (ega_cursor & 0xff)); 481 464 } 482 465 } 483 466 484 static void ega_sync_cursor( ega_instance_t *instance,bool silent)467 static void ega_sync_cursor(bool silent) 485 468 { 486 469 if (!silent) { 487 pio_write_8( instance->base + EGA_INDEX_REG, 0x0e);488 uint8_t hi = pio_read_8( instance->base + EGA_DATA_REG);489 pio_write_8( instance->base + EGA_INDEX_REG, 0x0f);490 uint8_t lo = pio_read_8( instance->base + EGA_DATA_REG);470 pio_write_8(ega_base + EGA_INDEX_REG, 0x0e); 471 uint8_t hi = pio_read_8(ega_base + EGA_DATA_REG); 472 pio_write_8(ega_base + EGA_INDEX_REG, 0x0f); 473 uint8_t lo = pio_read_8(ega_base + EGA_DATA_REG); 491 474 492 instance->cursor = (hi << 8) | lo;475 ega_cursor = (hi << 8) | lo; 493 476 } else 494 instance->cursor = 0; 495 496 if (instance->cursor >= EGA_SCREEN) 497 instance->cursor = 0; 498 499 if ((instance->cursor % EGA_COLS) != 0) 500 instance->cursor = 501 (instance->cursor + EGA_COLS) - instance->cursor % EGA_COLS; 502 503 memsetw(instance->backbuf + instance->cursor * 2, 504 EGA_SCREEN - instance->cursor, EMPTY_CHAR); 477 ega_cursor = 0; 478 479 if (ega_cursor >= EGA_SCREEN) 480 ega_cursor = 0; 481 482 if ((ega_cursor % EGA_COLS) != 0) 483 ega_cursor = (ega_cursor + EGA_COLS) - ega_cursor % EGA_COLS; 484 485 memsetw(backbuf + ega_cursor * 2, EGA_SCREEN - ega_cursor, EMPTY_CHAR); 505 486 506 487 if (!silent) 507 memsetw(instance->addr + instance->cursor * 2, 508 EGA_SCREEN - instance->cursor, EMPTY_CHAR); 509 510 ega_check_cursor(instance, silent); 511 ega_move_cursor(instance, silent); 512 ega_show_cursor(instance, silent); 513 } 514 515 static void ega_display_char(ega_instance_t *instance, wchar_t ch, bool silent) 488 memsetw(videoram + ega_cursor * 2, EGA_SCREEN - ega_cursor, EMPTY_CHAR); 489 490 ega_check_cursor(silent); 491 ega_move_cursor(silent); 492 ega_show_cursor(silent); 493 } 494 495 static void ega_display_char(wchar_t ch, bool silent) 516 496 { 517 497 uint16_t index = ega_oem_glyph(ch); … … 527 507 } 528 508 529 instance->backbuf[instance->cursor * 2] = glyph;530 instance->backbuf[instance->cursor * 2 + 1] = style;509 backbuf[ega_cursor * 2] = glyph; 510 backbuf[ega_cursor * 2 + 1] = style; 531 511 532 512 if (!silent) { 533 instance->addr[instance->cursor * 2] = glyph;534 instance->addr[instance->cursor * 2 + 1] = style;513 videoram[ega_cursor * 2] = glyph; 514 videoram[ega_cursor * 2 + 1] = style; 535 515 } 536 516 } 537 517 538 static void ega_putchar(outdev_t *dev , wchar_t ch, bool silent)539 { 540 ega_instance_t *instance = (ega_instance_t *) dev->data;541 542 ipl _t ipl= interrupts_disable();543 spinlock_lock(& instance->lock);518 static void ega_putchar(outdev_t *dev __attribute__((unused)), wchar_t ch, bool silent) 519 { 520 ipl_t ipl; 521 522 ipl = interrupts_disable(); 523 spinlock_lock(&egalock); 544 524 545 525 switch (ch) { 546 526 case '\n': 547 instance->cursor = (instance->cursor + EGA_COLS) 548 - instance->cursor % EGA_COLS; 527 ega_cursor = (ega_cursor + EGA_COLS) - ega_cursor % EGA_COLS; 549 528 break; 550 529 case '\t': 551 instance->cursor = (instance->cursor + 8) 552 - instance->cursor % 8; 530 ega_cursor = (ega_cursor + 8) - ega_cursor % 8; 553 531 break; 554 532 case '\b': 555 if ( instance->cursor % EGA_COLS)556 instance->cursor--;533 if (ega_cursor % EGA_COLS) 534 ega_cursor--; 557 535 break; 558 536 default: 559 ega_display_char( instance,ch, silent);560 instance->cursor++;537 ega_display_char(ch, silent); 538 ega_cursor++; 561 539 break; 562 540 } 563 ega_check_cursor( instance,silent);564 ega_move_cursor( instance,silent);565 566 spinlock_unlock(& instance->lock);541 ega_check_cursor(silent); 542 ega_move_cursor(silent); 543 544 spinlock_unlock(&egalock); 567 545 interrupts_restore(ipl); 568 546 } 569 547 570 static void ega_redraw(outdev_t *dev) 571 { 572 ega_instance_t *instance = (ega_instance_t *) dev->data; 573 574 ipl_t ipl = interrupts_disable(); 575 spinlock_lock(&instance->lock); 576 577 memcpy(instance->addr, instance->backbuf, EGA_VRAM_SIZE); 578 ega_move_cursor(instance, silent); 579 ega_show_cursor(instance, silent); 580 581 spinlock_unlock(&instance->lock); 582 interrupts_restore(ipl); 583 } 584 585 outdev_t *ega_init(ioport8_t *base, uintptr_t addr) 586 { 587 outdev_t *egadev = malloc(sizeof(outdev_t), FRAME_ATOMIC); 588 if (!egadev) 589 return NULL; 590 591 ega_instance_t *instance = malloc(sizeof(ega_instance_t), FRAME_ATOMIC); 592 if (!instance) { 593 free(egadev); 594 return NULL; 595 } 596 597 outdev_initialize("egadev", egadev, &egadev_ops); 598 egadev->data = instance; 599 600 spinlock_initialize(&instance->lock, "*ega_lock"); 601 602 instance->base = base; 603 instance->addr = (uint8_t *) hw_map(addr, EGA_VRAM_SIZE); 604 if (!instance->addr) { 605 LOG("Unable to EGA video memory."); 606 free(instance); 607 free(egadev); 608 return NULL; 609 } 610 611 instance->backbuf = (uint8_t *) malloc(EGA_VRAM_SIZE, 0); 612 if (!instance->backbuf) { 613 LOG("Unable to allocate backbuffer."); 614 free(instance); 615 free(egadev); 616 return NULL; 617 } 548 static outdev_t ega_console; 549 static outdev_operations_t ega_ops = { 550 .write = ega_putchar 551 }; 552 553 void ega_init(ioport8_t *base, uintptr_t videoram_phys) 554 { 555 /* Initialize the software structure. */ 556 ega_base = base; 557 558 backbuf = (uint8_t *) malloc(EGA_VRAM_SIZE, 0); 559 if (!backbuf) 560 panic("Unable to allocate backbuffer."); 561 562 videoram = (uint8_t *) hw_map(videoram_phys, EGA_VRAM_SIZE); 618 563 619 564 /* Synchronize the back buffer and cursor position. */ 620 memcpy( instance->backbuf, instance->addr, EGA_VRAM_SIZE);621 ega_sync_cursor( instance,silent);622 623 if (!fb_exported) {624 /*625 * This is the necessary evil until the userspace driver is entirely626 * self-sufficient.627 */628 sysinfo_set_item_val("fb", NULL, true);629 sysinfo_set_item_val("fb.kind", NULL, 2);630 sysinfo_set_item_val("fb.width", NULL, EGA_COLS);631 sysinfo_set_item_val("fb.height", NULL, EGA_ROWS);632 sysinfo_set_item_val("fb.blinking", NULL, true); 633 sysinfo_set_item_val("fb.address.physical", NULL, addr); 634 635 fb_exported = true; 636 }637 638 return egadev;565 memcpy(backbuf, videoram, EGA_VRAM_SIZE); 566 ega_sync_cursor(silent); 567 568 outdev_initialize("ega", &ega_console, &ega_ops); 569 stdout = &ega_console; 570 571 sysinfo_set_item_val("fb", NULL, true); 572 sysinfo_set_item_val("fb.kind", NULL, 2); 573 sysinfo_set_item_val("fb.width", NULL, EGA_COLS); 574 sysinfo_set_item_val("fb.height", NULL, EGA_ROWS); 575 sysinfo_set_item_val("fb.blinking", NULL, true); 576 sysinfo_set_item_val("fb.address.physical", NULL, videoram_phys); 577 } 578 579 void ega_redraw(void) 580 { 581 memcpy(videoram, backbuf, EGA_VRAM_SIZE); 582 ega_move_cursor(silent); 583 ega_show_cursor(silent); 639 584 } 640 585
Note:
See TracChangeset
for help on using the changeset viewer.