Revision cae61cef hw/vga.c

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