Revision cae61cef
b/hw/vga.c | ||
---|---|---|
116 | 116 |
uint8_t dac_write_index; |
117 | 117 |
uint8_t dac_cache[3]; /* used when writing */ |
118 | 118 |
uint8_t palette[768]; |
119 |
uint32_t bank_offset; |
|
119 | 120 |
#ifdef CONFIG_BOCHS_VBE |
120 | 121 |
uint16_t vbe_index; |
121 | 122 |
uint16_t vbe_regs[VBE_DISPI_INDEX_NB]; |
122 | 123 |
uint32_t vbe_start_addr; |
123 | 124 |
uint32_t vbe_line_offset; |
125 |
uint32_t vbe_bank_mask; |
|
124 | 126 |
#endif |
125 | 127 |
/* display refresh support */ |
126 | 128 |
DisplayState *ds; |
... | ... | |
537 | 539 |
#endif |
538 | 540 |
switch(s->vbe_index) { |
539 | 541 |
case VBE_DISPI_INDEX_ID: |
540 |
if (val != VBE_DISPI_ID0 && |
|
541 |
val != VBE_DISPI_ID1 && |
|
542 |
val != VBE_DISPI_ID2) |
|
543 |
return; |
|
542 |
if (val == VBE_DISPI_ID0 || |
|
543 |
val == VBE_DISPI_ID1 || |
|
544 |
val == VBE_DISPI_ID2) { |
|
545 |
s->vbe_regs[s->vbe_index] = val; |
|
546 |
} |
|
544 | 547 |
break; |
545 | 548 |
case VBE_DISPI_INDEX_XRES: |
546 |
if ((val > VBE_DISPI_MAX_XRES) || ((val & 7) != 0)) |
|
547 |
return; |
|
549 |
if ((val <= VBE_DISPI_MAX_XRES) && ((val & 7) == 0)) { |
|
550 |
s->vbe_regs[s->vbe_index] = val; |
|
551 |
} |
|
548 | 552 |
break; |
549 | 553 |
case VBE_DISPI_INDEX_YRES: |
550 |
if (val > VBE_DISPI_MAX_YRES) |
|
551 |
return; |
|
554 |
if (val <= VBE_DISPI_MAX_YRES) { |
|
555 |
s->vbe_regs[s->vbe_index] = val; |
|
556 |
} |
|
552 | 557 |
break; |
553 | 558 |
case VBE_DISPI_INDEX_BPP: |
554 | 559 |
if (val == 0) |
555 | 560 |
val = 8; |
556 |
if (val != 4 && val != 8 && val != 15 && |
|
557 |
val != 16 && val != 24 && val != 32) |
|
558 |
return; |
|
561 |
if (val == 4 || val == 8 || val == 15 || |
|
562 |
val == 16 || val == 24 || val == 32) { |
|
563 |
s->vbe_regs[s->vbe_index] = val; |
|
564 |
} |
|
559 | 565 |
break; |
560 | 566 |
case VBE_DISPI_INDEX_BANK: |
561 |
val &= 0xff; |
|
567 |
val &= s->vbe_bank_mask; |
|
568 |
s->vbe_regs[s->vbe_index] = val; |
|
569 |
s->bank_offset = (val << 16) - 0xa0000; |
|
562 | 570 |
break; |
563 | 571 |
case VBE_DISPI_INDEX_ENABLE: |
564 | 572 |
if (val & VBE_DISPI_ENABLED) { |
... | ... | |
584 | 592 |
s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset); |
585 | 593 |
} |
586 | 594 |
|
587 |
/* we initialize graphic mode force graphic mode
|
|
588 |
(should be done in BIOS) */
|
|
589 |
s->gr[6] |= 1;
|
|
595 |
/* we initialize the VGA graphic mode (should be done
|
|
596 |
in BIOS) */ |
|
597 |
s->gr[0x06] = (s->gr[0x06] & ~0x0c) | 0x05; /* graphic mode + memory map 1 */
|
|
590 | 598 |
s->cr[0x17] |= 3; /* no CGA modes */ |
591 | 599 |
s->cr[0x13] = s->vbe_line_offset >> 3; |
592 | 600 |
/* width */ |
... | ... | |
609 | 617 |
} |
610 | 618 |
s->gr[0x05] = (s->gr[0x05] & ~0x60) | (shift_control << 5); |
611 | 619 |
s->cr[0x09] &= ~0x9f; /* no double scan */ |
620 |
s->vbe_regs[s->vbe_index] = val; |
|
621 |
} else { |
|
622 |
/* XXX: the bios should do that */ |
|
623 |
s->bank_offset = -0xa0000; |
|
624 |
} |
|
625 |
break; |
|
626 |
case VBE_DISPI_INDEX_VIRT_WIDTH: |
|
627 |
{ |
|
628 |
int w, h, line_offset; |
|
629 |
|
|
630 |
if (val < s->vbe_regs[VBE_DISPI_INDEX_XRES]) |
|
631 |
return; |
|
632 |
w = val; |
|
633 |
if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) |
|
634 |
line_offset = w >> 1; |
|
635 |
else |
|
636 |
line_offset = w * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3); |
|
637 |
h = s->vram_size / line_offset; |
|
638 |
/* XXX: support weird bochs semantics ? */ |
|
639 |
if (h < s->vbe_regs[VBE_DISPI_INDEX_YRES]) |
|
640 |
return; |
|
641 |
s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = w; |
|
642 |
s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = h; |
|
643 |
s->vbe_line_offset = line_offset; |
|
644 |
} |
|
645 |
break; |
|
646 |
case VBE_DISPI_INDEX_X_OFFSET: |
|
647 |
case VBE_DISPI_INDEX_Y_OFFSET: |
|
648 |
{ |
|
649 |
int x; |
|
650 |
s->vbe_regs[s->vbe_index] = val; |
|
651 |
s->vbe_start_addr = s->vbe_line_offset * s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET]; |
|
652 |
x = s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET]; |
|
653 |
if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) |
|
654 |
s->vbe_start_addr += x >> 1; |
|
655 |
else |
|
656 |
s->vbe_start_addr += x * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3); |
|
657 |
s->vbe_start_addr >>= 2; |
|
612 | 658 |
} |
613 | 659 |
break; |
614 | 660 |
default: |
615 | 661 |
break; |
616 | 662 |
} |
617 |
s->vbe_regs[s->vbe_index] = val; |
|
618 | 663 |
} |
619 | 664 |
} |
620 | 665 |
#endif |
... | ... | |
633 | 678 |
addr -= 0xa0000; |
634 | 679 |
break; |
635 | 680 |
case 1: |
636 |
addr -= 0xa0000; |
|
637 |
if (addr >= 0x10000) |
|
681 |
if (addr >= 0xb0000) |
|
638 | 682 |
return 0xff; |
683 |
addr += s->bank_offset; |
|
639 | 684 |
break; |
640 | 685 |
case 2: |
641 | 686 |
addr -= 0xb0000; |
... | ... | |
711 | 756 |
addr -= 0xa0000; |
712 | 757 |
break; |
713 | 758 |
case 1: |
714 |
addr -= 0xa0000; |
|
715 |
if (addr >= 0x10000) |
|
759 |
if (addr >= 0xb0000) |
|
716 | 760 |
return; |
761 |
addr += s->bank_offset; |
|
717 | 762 |
break; |
718 | 763 |
case 2: |
719 | 764 |
addr -= 0xb0000; |
... | ... | |
1611 | 1656 |
register_ioport_read(0x3d4, 2, vga_ioport_read, 1); |
1612 | 1657 |
register_ioport_read(0x3ba, 1, vga_ioport_read, 1); |
1613 | 1658 |
register_ioport_read(0x3da, 1, vga_ioport_read, 1); |
1659 |
s->bank_offset = -0xa0000; |
|
1614 | 1660 |
|
1615 | 1661 |
#ifdef CONFIG_BOCHS_VBE |
1616 | 1662 |
s->vbe_regs[VBE_DISPI_INDEX_ID] = VBE_DISPI_ID0; |
1663 |
s->vbe_bank_mask = ((s->vram_size >> 16) - 1); |
|
1617 | 1664 |
register_ioport_read(0x1ce, 1, vbe_ioport_read, 2); |
1618 | 1665 |
register_ioport_read(0x1cf, 1, vbe_ioport_read, 2); |
1619 | 1666 |
|
Also available in: Unified diff