Commit cae61cef8976a819e590df66068f056e758c7429

Authored by bellard
1 parent 6411cfb6

bochs vbe: virtual screen support and bank switch (untested)


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@605 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 67 additions and 20 deletions
hw/vga.c
... ... @@ -116,11 +116,13 @@ typedef struct VGAState {
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,28 +539,34 @@ static void vbe_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
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,9 +592,9 @@ static void vbe_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
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,12 +617,49 @@ static void vbe_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
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,9 +678,9 @@ static uint32_t vga_mem_readb(uint32_t addr)
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,9 +756,9 @@ void vga_mem_writeb(uint32_t addr, uint32_t val, uint32_t vaddr)
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,9 +1656,11 @@ int vga_initialize(DisplayState *ds, uint8_t *vga_ram_base,
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  
... ...