Changeset a71c158 in mainline for kernel/genarch/src/drivers/ega/ega.c
- Timestamp:
- 2009-08-21T14:12:45Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0e6dce8, b50b5af2, e5792d1
- Parents:
- 90c8b8d
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/genarch/src/drivers/ega/ega.c
r90c8b8d ra71c158 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 64 58 #define SPACE 0x20 65 59 #define STYLE 0x1e … … 68 62 #define EMPTY_CHAR ((STYLE << 8) | SPACE) 69 63 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_redraw 79 }; 80 70 81 static uint16_t ega_oem_glyph(const wchar_t ch) 71 82 { … … 427 438 * This function takes care of scrolling. 428 439 */ 429 static void ega_check_cursor( bool silent)430 { 431 if ( ega_cursor < EGA_SCREEN)440 static void ega_check_cursor(ega_instance_t *instance, bool silent) 441 { 442 if (instance->cursor < EGA_SCREEN) 432 443 return; 433 444 434 memmove((void *) backbuf, (void *) (backbuf + EGA_COLS * 2), 445 memmove((void *) instance->backbuf, 446 (void *) (instance->backbuf + EGA_COLS * 2), 435 447 (EGA_SCREEN - EGA_COLS) * 2); 436 memsetw(backbuf + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR); 448 memsetw(instance->backbuf + (EGA_SCREEN - EGA_COLS) * 2, 449 EGA_COLS, EMPTY_CHAR); 437 450 438 451 if (!silent) { 439 memmove((void *) videoram, (void *) (videoram + EGA_COLS * 2), 452 memmove((void *) instance->addr, 453 (void *) (instance->addr + EGA_COLS * 2), 440 454 (EGA_SCREEN - EGA_COLS) * 2); 441 memsetw(videoram + (EGA_SCREEN - EGA_COLS) * 2, EGA_COLS, EMPTY_CHAR); 442 } 443 444 ega_cursor = ega_cursor - EGA_COLS; 445 } 446 447 static void ega_show_cursor(bool silent) 455 memsetw(instance->addr + (EGA_SCREEN - EGA_COLS) * 2, 456 EGA_COLS, EMPTY_CHAR); 457 } 458 459 instance->cursor = instance->cursor - EGA_COLS; 460 } 461 462 static void ega_show_cursor(ega_instance_t *instance, bool silent) 448 463 { 449 464 if (!silent) { 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)));454 } 455 } 456 457 static void ega_move_cursor( bool 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))); 469 } 470 } 471 472 static void ega_move_cursor(ega_instance_t *instance, bool silent) 458 473 { 459 474 if (!silent) { 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)); 464 } 465 } 466 467 static void ega_sync_cursor(bool 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)); 481 } 482 } 483 484 static void ega_sync_cursor(ega_instance_t *instance, bool silent) 468 485 { 469 486 if (!silent) { 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);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); 474 491 475 ega_cursor = (hi << 8) | lo;492 instance->cursor = (hi << 8) | lo; 476 493 } else 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); 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); 486 505 487 506 if (!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) 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) 496 516 { 497 517 uint16_t index = ega_oem_glyph(ch); … … 507 527 } 508 528 509 backbuf[ega_cursor * 2] = glyph;510 backbuf[ega_cursor * 2 + 1] = style;529 instance->backbuf[instance->cursor * 2] = glyph; 530 instance->backbuf[instance->cursor * 2 + 1] = style; 511 531 512 532 if (!silent) { 513 videoram[ega_cursor * 2] = glyph;514 videoram[ega_cursor * 2 + 1] = style;515 } 516 } 517 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);533 instance->addr[instance->cursor * 2] = glyph; 534 instance->addr[instance->cursor * 2 + 1] = style; 535 } 536 } 537 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); 524 544 525 545 switch (ch) { 526 546 case '\n': 527 ega_cursor = (ega_cursor + EGA_COLS) - ega_cursor % EGA_COLS; 547 instance->cursor = (instance->cursor + EGA_COLS) 548 - instance->cursor % EGA_COLS; 528 549 break; 529 550 case '\t': 530 ega_cursor = (ega_cursor + 8) - ega_cursor % 8; 551 instance->cursor = (instance->cursor + 8) 552 - instance->cursor % 8; 531 553 break; 532 554 case '\b': 533 if ( ega_cursor % EGA_COLS)534 ega_cursor--;555 if (instance->cursor % EGA_COLS) 556 instance->cursor--; 535 557 break; 536 558 default: 537 ega_display_char( ch, silent);538 ega_cursor++;559 ega_display_char(instance, ch, silent); 560 instance->cursor++; 539 561 break; 540 562 } 541 ega_check_cursor( silent);542 ega_move_cursor( silent);543 544 spinlock_unlock(& egalock);563 ega_check_cursor(instance, silent); 564 ega_move_cursor(instance, silent); 565 566 spinlock_unlock(&instance->lock); 545 567 interrupts_restore(ipl); 546 568 } 547 569 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); 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 } 563 618 564 619 /* Synchronize the back buffer and cursor position. */ 565 memcpy( backbuf, videoram, EGA_VRAM_SIZE);566 ega_sync_cursor( silent);567 568 outdev_initialize("ega", &ega_console, &ega_ops);569 stdout_wire(&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);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 entirely 626 * 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; 584 639 } 585 640
Note:
See TracChangeset
for help on using the changeset viewer.