Revision 798b0c25 hw/vga.c

b/hw/vga.c
22 22
 * THE SOFTWARE.
23 23
 */
24 24
#include "vl.h"
25
#include "vga_int.h"
25 26

  
26 27
//#define DEBUG_VGA
27 28
//#define DEBUG_VGA_MEM
......
33 34
/* S3 VGA is deprecated - another graphic card will be emulated */
34 35
//#define CONFIG_S3VGA
35 36

  
36
#define MSR_COLOR_EMULATION 0x01
37
#define MSR_PAGE_SELECT     0x20
38

  
39
#define ST01_V_RETRACE      0x08
40
#define ST01_DISP_ENABLE    0x01
41

  
42
/* bochs VBE support */
43
#define CONFIG_BOCHS_VBE
44

  
45
#define VBE_DISPI_MAX_XRES              1024
46
#define VBE_DISPI_MAX_YRES              768
47

  
48
#define VBE_DISPI_INDEX_ID              0x0
49
#define VBE_DISPI_INDEX_XRES            0x1
50
#define VBE_DISPI_INDEX_YRES            0x2
51
#define VBE_DISPI_INDEX_BPP             0x3
52
#define VBE_DISPI_INDEX_ENABLE          0x4
53
#define VBE_DISPI_INDEX_BANK            0x5
54
#define VBE_DISPI_INDEX_VIRT_WIDTH      0x6
55
#define VBE_DISPI_INDEX_VIRT_HEIGHT     0x7
56
#define VBE_DISPI_INDEX_X_OFFSET        0x8
57
#define VBE_DISPI_INDEX_Y_OFFSET        0x9
58
#define VBE_DISPI_INDEX_NB              0xa
59
      
60
#define VBE_DISPI_ID0                   0xB0C0
61
#define VBE_DISPI_ID1                   0xB0C1
62
#define VBE_DISPI_ID2                   0xB0C2
63
  
64
#define VBE_DISPI_DISABLED              0x00
65
#define VBE_DISPI_ENABLED               0x01
66
#define VBE_DISPI_LFB_ENABLED           0x40
67
#define VBE_DISPI_NOCLEARMEM            0x80
68
  
69
#define VBE_DISPI_LFB_PHYSICAL_ADDRESS  0xE0000000
70

  
71
typedef struct VGAState {
72
    uint8_t *vram_ptr;
73
    unsigned long vram_offset;
74
    unsigned int vram_size;
75
    uint32_t latch;
76
    uint8_t sr_index;
77
    uint8_t sr[8];
78
    uint8_t gr_index;
79
    uint8_t gr[16];
80
    uint8_t ar_index;
81
    uint8_t ar[21];
82
    int ar_flip_flop;
83
    uint8_t cr_index;
84
    uint8_t cr[256]; /* CRT registers */
85
    uint8_t msr; /* Misc Output Register */
86
    uint8_t fcr; /* Feature Control Register */
87
    uint8_t st00; /* status 0 */
88
    uint8_t st01; /* status 1 */
89
    uint8_t dac_state;
90
    uint8_t dac_sub_index;
91
    uint8_t dac_read_index;
92
    uint8_t dac_write_index;
93
    uint8_t dac_cache[3]; /* used when writing */
94
    uint8_t palette[768];
95
    int32_t bank_offset;
96
#ifdef CONFIG_BOCHS_VBE
97
    uint16_t vbe_index;
98
    uint16_t vbe_regs[VBE_DISPI_INDEX_NB];
99
    uint32_t vbe_start_addr;
100
    uint32_t vbe_line_offset;
101
    uint32_t vbe_bank_mask;
102
#endif
103
    /* display refresh support */
104
    DisplayState *ds;
105
    uint32_t font_offsets[2];
106
    int graphic_mode;
107
    uint8_t shift_control;
108
    uint8_t double_scan;
109
    uint32_t line_offset;
110
    uint32_t line_compare;
111
    uint32_t start_addr;
112
    uint8_t last_cw, last_ch;
113
    uint32_t last_width, last_height; /* in chars or pixels */
114
    uint32_t last_scr_width, last_scr_height; /* in pixels */
115
    uint8_t cursor_start, cursor_end;
116
    uint32_t cursor_offset;
117
    unsigned int (*rgb_to_pixel)(unsigned int r, unsigned int g, unsigned b);
118
    /* tell for each page if it has been updated since the last time */
119
    uint32_t last_palette[256];
120
#define CH_ATTR_SIZE (160 * 100)
121
    uint32_t last_ch_attr[CH_ATTR_SIZE]; /* XXX: make it dynamic */
122
} VGAState;
123

  
124 37
/* force some bits to zero */
125
static const uint8_t sr_mask[8] = {
38
const uint8_t sr_mask[8] = {
126 39
    (uint8_t)~0xfc,
127 40
    (uint8_t)~0xc2,
128 41
    (uint8_t)~0xf0,
......
133 46
    (uint8_t)~0x00,
134 47
};
135 48

  
136
static const uint8_t gr_mask[16] = {
49
const uint8_t gr_mask[16] = {
137 50
    (uint8_t)~0xf0, /* 0x00 */
138 51
    (uint8_t)~0xf0, /* 0x01 */
139 52
    (uint8_t)~0xf0, /* 0x02 */
......
656 569
#endif
657 570

  
658 571
/* called for accesses between 0xa0000 and 0xc0000 */
659
static uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr)
572
uint32_t vga_mem_readb(void *opaque, target_phys_addr_t addr)
660 573
{
661 574
    VGAState *s = opaque;
662 575
    int memory_map_mode, plane;
......
743 656
}
744 657

  
745 658
/* called for accesses between 0xa0000 and 0xc0000 */
746
static void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
659
void vga_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
747 660
{
748 661
    VGAState *s = opaque;
749 662
    int memory_map_mode, plane, write_mode, b, func_select;
......
1027 940
    return full_update;
1028 941
}
1029 942

  
1030
/* update start_addr and line_offset. Return TRUE if modified */
1031
static int update_basic_params(VGAState *s)
943
static void vga_get_offsets(VGAState *s, 
944
                            uint32_t *pline_offset, 
945
                            uint32_t *pstart_addr)
1032 946
{
1033
    int full_update;
1034
    uint32_t start_addr, line_offset, line_compare;
1035
    
1036
    full_update = 0;
1037

  
947
    uint32_t start_addr, line_offset;
1038 948
#ifdef CONFIG_BOCHS_VBE
1039 949
    if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
1040 950
        line_offset = s->vbe_line_offset;
......
1061 971
        start_addr |= (s->cr[0x69] & 0x1f) << 16; /* S3 extension */
1062 972
#endif
1063 973
    }
974
    *pline_offset = line_offset;
975
    *pstart_addr = start_addr;
976
}
977

  
978
/* update start_addr and line_offset. Return TRUE if modified */
979
static int update_basic_params(VGAState *s)
980
{
981
    int full_update;
982
    uint32_t start_addr, line_offset, line_compare;
1064 983
    
984
    full_update = 0;
985

  
986
    s->get_offsets(s, &line_offset, &start_addr);
1065 987
    /* line compare */
1066 988
    line_compare = s->cr[0x18] | 
1067 989
        ((s->cr[0x07] & 0x10) << 4) |
......
1373 1295
    vga_draw_line32_32,
1374 1296
};
1375 1297

  
1298
static int vga_get_bpp(VGAState *s)
1299
{
1300
    int ret;
1301
#ifdef CONFIG_BOCHS_VBE
1302
    if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
1303
        ret = s->vbe_regs[VBE_DISPI_INDEX_BPP];
1304
    } else 
1305
#endif
1306
    {
1307
        ret = 0;
1308
    }
1309
    return ret;
1310
}
1311

  
1376 1312
/* 
1377 1313
 * graphic modes
1378 1314
 * Missing:
......
1429 1365
            v = VGA_DRAW_LINE2;
1430 1366
        }
1431 1367
    } else {
1432
#ifdef CONFIG_BOCHS_VBE
1433
        if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) {
1434
            switch(s->vbe_regs[VBE_DISPI_INDEX_BPP]) {
1435
            default:
1436
            case 8:
1437
                full_update |= update_palette256(s);
1438
                v = VGA_DRAW_LINE8;
1439
                break;
1440
            case 15:
1441
                v = VGA_DRAW_LINE15;
1442
                break;
1443
            case 16:
1444
                v = VGA_DRAW_LINE16;
1445
                break;
1446
            case 24:
1447
                v = VGA_DRAW_LINE24;
1448
                break;
1449
            case 32:
1450
                v = VGA_DRAW_LINE32;
1451
                break;
1452
            }
1453
        } else 
1454
#endif
1455
        {
1368
        switch(s->get_bpp(s)) {
1369
        default:
1370
        case 0:
1456 1371
            full_update |= update_palette256(s);
1457 1372
            v = VGA_DRAW_LINE8D2;
1373
            break;
1374
        case 8:
1375
            full_update |= update_palette256(s);
1376
            v = VGA_DRAW_LINE8;
1377
            break;
1378
        case 15:
1379
            v = VGA_DRAW_LINE15;
1380
            break;
1381
        case 16:
1382
            v = VGA_DRAW_LINE16;
1383
            break;
1384
        case 24:
1385
            v = VGA_DRAW_LINE24;
1386
            break;
1387
        case 32:
1388
            v = VGA_DRAW_LINE32;
1389
            break;
1458 1390
        }
1459 1391
    }
1460 1392
    vga_draw_line = vga_draw_line_table[v * 4 + get_depth_index(s->ds->depth)];
......
1747 1679
    cpu_register_physical_memory(addr, s->vram_size, s->vram_offset);
1748 1680
}
1749 1681

  
1750
int vga_initialize(DisplayState *ds, uint8_t *vga_ram_base, 
1751
                   unsigned long vga_ram_offset, int vga_ram_size, 
1752
                   int is_pci)
1682
void vga_common_init(VGAState *s, DisplayState *ds, uint8_t *vga_ram_base, 
1683
                     unsigned long vga_ram_offset, int vga_ram_size)
1753 1684
{
1754
    VGAState *s = &vga_state;
1755 1685
    int i, j, v, b;
1756 1686

  
1757 1687
    for(i = 0;i < 256; i++) {
......
1783 1713
    s->vram_offset = vga_ram_offset;
1784 1714
    s->vram_size = vga_ram_size;
1785 1715
    s->ds = ds;
1716
    s->get_bpp = vga_get_bpp;
1717
    s->get_offsets = vga_get_offsets;
1718
}
1719

  
1720

  
1721
int vga_initialize(DisplayState *ds, uint8_t *vga_ram_base, 
1722
                   unsigned long vga_ram_offset, int vga_ram_size, 
1723
                   int is_pci)
1724
{
1725
    VGAState *s = &vga_state;
1726

  
1727
    vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size);
1786 1728

  
1787 1729
    register_savevm("vga", 0, 1, vga_save, vga_load, s);
1788 1730

  

Also available in: Unified diff