151
147
static void vga_screen_dump(void *opaque, const char *filename);
153
static void vga_dumb_update_retrace_info(VGAState *s)
158
static void vga_precise_update_retrace_info(VGAState *s)
161
int hretr_start_char;
162
int hretr_skew_chars;
166
int vretr_start_line;
169
int div2, sldiv2, dots;
172
const int hz[] = {25175000, 28322000, 25175000, 25175000};
173
int64_t chars_per_sec;
174
struct vga_precise_retrace *r = &s->retrace_info.precise;
176
htotal_chars = s->cr[0x00] + 5;
177
hretr_start_char = s->cr[0x04];
178
hretr_skew_chars = (s->cr[0x05] >> 5) & 3;
179
hretr_end_char = s->cr[0x05] & 0x1f;
181
vtotal_lines = (s->cr[0x06]
182
| (((s->cr[0x07] & 1) | ((s->cr[0x07] >> 4) & 2)) << 8)) + 2
184
vretr_start_line = s->cr[0x10]
185
| ((((s->cr[0x07] >> 2) & 1) | ((s->cr[0x07] >> 6) & 2)) << 8)
187
vretr_end_line = s->cr[0x11] & 0xf;
190
div2 = (s->cr[0x17] >> 2) & 1;
191
sldiv2 = (s->cr[0x17] >> 3) & 1;
193
clocking_mode = (s->sr[0x01] >> 3) & 1;
194
clock_sel = (s->msr >> 2) & 3;
195
dots = (s->msr & 1) ? 8 : 9;
197
chars_per_sec = hz[clock_sel] / dots;
199
htotal_chars <<= clocking_mode;
201
r->total_chars = vtotal_lines * htotal_chars;
203
r->ticks_per_char = ticks_per_sec / (r->total_chars * r->freq);
205
r->ticks_per_char = ticks_per_sec / chars_per_sec;
208
r->vstart = vretr_start_line;
209
r->vend = r->vstart + vretr_end_line + 1;
211
r->hstart = hretr_start_char + hretr_skew_chars;
212
r->hend = r->hstart + hretr_end_char + 1;
213
r->htotal = htotal_chars;
225
"div2 = %d sldiv2 = %d\n"
226
"clocking_mode = %d\n"
227
"clock_sel = %d %d\n"
229
"ticks/char = %lld\n"
231
(double) ticks_per_sec / (r->ticks_per_char * r->total_chars),
249
static uint8_t vga_precise_retrace(VGAState *s)
251
struct vga_precise_retrace *r = &s->retrace_info.precise;
252
uint8_t val = s->st01 & ~(ST01_V_RETRACE | ST01_DISP_ENABLE);
254
if (r->total_chars) {
255
int cur_line, cur_line_char, cur_char;
258
cur_tick = qemu_get_clock(vm_clock);
260
cur_char = (cur_tick / r->ticks_per_char) % r->total_chars;
261
cur_line = cur_char / r->htotal;
263
if (cur_line >= r->vstart && cur_line <= r->vend) {
264
val |= ST01_V_RETRACE | ST01_DISP_ENABLE;
266
cur_line_char = cur_char % r->htotal;
267
if (cur_line_char >= r->hstart && cur_line_char <= r->hend) {
268
val |= ST01_DISP_ENABLE;
274
return s->st01 ^ (ST01_V_RETRACE | ST01_DISP_ENABLE);
278
static uint8_t vga_dumb_retrace(VGAState *s)
280
return s->st01 ^ (ST01_V_RETRACE | ST01_DISP_ENABLE);
283
149
static uint32_t vga_ioport_read(void *opaque, uint32_t addr)
285
151
VGAState *s = opaque;
608
461
!(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) {
609
462
int h, shift_control;
611
s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] =
464
s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] =
612
465
s->vbe_regs[VBE_DISPI_INDEX_XRES];
613
s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] =
466
s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] =
614
467
s->vbe_regs[VBE_DISPI_INDEX_YRES];
615
468
s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0;
616
469
s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0;
618
471
if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4)
619
472
s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 1;
621
s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] *
474
s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] *
622
475
((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3);
623
476
s->vbe_start_addr = 0;
625
478
/* clear the screen (should be done in BIOS) */
626
479
if (!(val & VBE_DISPI_NOCLEARMEM)) {
627
memset(s->vram_ptr, 0,
480
memset(s->vram_ptr, 0,
628
481
s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset);
631
484
/* we initialize the VGA graphic mode (should be done
633
486
s->gr[0x06] = (s->gr[0x06] & ~0x0c) | 0x05; /* graphic mode + memory map 1 */
955
808
const uint8_t *font_ptr, int h,
956
809
uint32_t fgcol, uint32_t bgcol);
957
810
typedef void vga_draw_glyph9_func(uint8_t *d, int linesize,
958
const uint8_t *font_ptr, int h,
811
const uint8_t *font_ptr, int h,
959
812
uint32_t fgcol, uint32_t bgcol, int dup9);
960
typedef void vga_draw_line_func(VGAState *s1, uint8_t *d,
813
typedef void vga_draw_line_func(VGAState *s1, uint8_t *d,
961
814
const uint8_t *s, int width);
1560
1413
* graphic modes
1562
1415
static void vga_draw_graphic(VGAState *s, int full_update)
1564
1417
int y1, y, update, page_min, page_max, linesize, y_start, double_scan, mask;
1565
int width, height, shift_control, line_offset, page0, page1, bwidth, bits;
1418
int width, height, shift_control, line_offset, page0, page1, bwidth;
1566
1419
int disp_width, multi_scan, multi_run;
1568
1421
uint32_t v, addr1, addr;
1569
1422
vga_draw_line_func *vga_draw_line;
1571
1424
full_update |= update_basic_params(s);
1573
1426
s->get_resolution(s, &width, &height);
1812
1657
s->graphic_mode = -1; /* force full update */
1815
#define TEXTMODE_X(x) ((x) % width)
1816
#define TEXTMODE_Y(x) ((x) / width)
1817
#define VMEM2CHTYPE(v) ((v & 0xff0007ff) | \
1818
((v & 0x00000800) << 10) | ((v & 0x00007000) >> 1))
1819
/* relay text rendering to the display driver
1820
* instead of doing a full vga_update_display() */
1821
static void vga_update_text(void *opaque, console_ch_t *chardata)
1823
VGAState *s = (VGAState *) opaque;
1824
int graphic_mode, i, cursor_offset, cursor_visible;
1825
int cw, cheight, width, height, size, c_min, c_max;
1827
console_ch_t *dst, val;
1828
char msg_buffer[80];
1829
int full_update = 0;
1831
if (!(s->ar_index & 0x20)) {
1832
graphic_mode = GMODE_BLANK;
1834
graphic_mode = s->gr[6] & 1;
1836
if (graphic_mode != s->graphic_mode) {
1837
s->graphic_mode = graphic_mode;
1840
if (s->last_width == -1) {
1845
switch (graphic_mode) {
1847
/* TODO: update palette */
1848
full_update |= update_basic_params(s);
1850
/* total width & height */
1851
cheight = (s->cr[9] & 0x1f) + 1;
1853
if (!(s->sr[1] & 0x01))
1855
if (s->sr[1] & 0x08)
1856
cw = 16; /* NOTE: no 18 pixel wide */
1857
width = (s->cr[0x01] + 1);
1858
if (s->cr[0x06] == 100) {
1859
/* ugly hack for CGA 160x100x16 - explain me the logic */
1862
height = s->cr[0x12] |
1863
((s->cr[0x07] & 0x02) << 7) |
1864
((s->cr[0x07] & 0x40) << 3);
1865
height = (height + 1) / cheight;
1868
size = (height * width);
1869
if (size > CH_ATTR_SIZE) {
1873
snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Text mode",
1878
if (width != s->last_width || height != s->last_height ||
1879
cw != s->last_cw || cheight != s->last_ch) {
1880
s->last_scr_width = width * cw;
1881
s->last_scr_height = height * cheight;
1882
qemu_console_resize(s->console, width, height);
1883
s->last_width = width;
1884
s->last_height = height;
1885
s->last_ch = cheight;
1890
/* Update "hardware" cursor */
1891
cursor_offset = ((s->cr[0x0e] << 8) | s->cr[0x0f]) - s->start_addr;
1892
if (cursor_offset != s->cursor_offset ||
1893
s->cr[0xa] != s->cursor_start ||
1894
s->cr[0xb] != s->cursor_end || full_update) {
1895
cursor_visible = !(s->cr[0xa] & 0x20);
1896
if (cursor_visible && cursor_offset < size && cursor_offset >= 0)
1898
TEXTMODE_X(cursor_offset),
1899
TEXTMODE_Y(cursor_offset));
1901
dpy_cursor(s->ds, -1, -1);
1902
s->cursor_offset = cursor_offset;
1903
s->cursor_start = s->cr[0xa];
1904
s->cursor_end = s->cr[0xb];
1907
src = (uint32_t *) s->vram_ptr + s->start_addr;
1911
for (i = 0; i < size; src ++, dst ++, i ++)
1912
console_write_ch(dst, VMEM2CHTYPE(*src));
1914
dpy_update(s->ds, 0, 0, width, height);
1918
for (i = 0; i < size; src ++, dst ++, i ++) {
1919
console_write_ch(&val, VMEM2CHTYPE(*src));
1927
for (; i < size; src ++, dst ++, i ++) {
1928
console_write_ch(&val, VMEM2CHTYPE(*src));
1935
if (c_min <= c_max) {
1936
i = TEXTMODE_Y(c_min);
1937
dpy_update(s->ds, 0, i, width, TEXTMODE_Y(c_max) - i + 1);
1946
s->get_resolution(s, &width, &height);
1947
snprintf(msg_buffer, sizeof(msg_buffer), "%i x %i Graphic mode",
1955
snprintf(msg_buffer, sizeof(msg_buffer), "VGA Blank mode");
1959
/* Display a message */
1961
s->last_height = height = 3;
1962
dpy_cursor(s->ds, -1, -1);
1963
qemu_console_resize(s->console, s->last_width, height);
1965
for (dst = chardata, i = 0; i < s->last_width * height; i ++)
1966
console_write_ch(dst ++, ' ');
1968
size = strlen(msg_buffer);
1969
width = (s->last_width - size) / 2;
1970
dst = chardata + s->last_width + width;
1971
for (i = 0; i < size; i ++)
1972
console_write_ch(dst ++, 0x00200100 | msg_buffer[i]);
1974
dpy_update(s->ds, 0, 0, s->last_width, height);
1977
1660
static CPUReadMemoryFunc *vga_mem_read[3] = {
2001
1684
qemu_put_buffer(f, s->gr, 16);
2002
1685
qemu_put_8s(f, &s->ar_index);
2003
1686
qemu_put_buffer(f, s->ar, 21);
2004
qemu_put_be32(f, s->ar_flip_flop);
1687
qemu_put_be32s(f, &s->ar_flip_flop);
2005
1688
qemu_put_8s(f, &s->cr_index);
2006
1689
qemu_put_buffer(f, s->cr, 256);
2007
1690
qemu_put_8s(f, &s->msr);
2008
1691
qemu_put_8s(f, &s->fcr);
2009
qemu_put_byte(f, s->st00);
1692
qemu_put_8s(f, &s->st00);
2010
1693
qemu_put_8s(f, &s->st01);
2012
1695
qemu_put_8s(f, &s->dac_state);
2196
1866
register_ioport_read(0xff81, 1, 2, vbe_ioport_read_data, s);
2198
1868
register_ioport_write(0xff80, 1, 2, vbe_ioport_write_index, s);
2199
register_ioport_write(0xff81, 1, 2, vbe_ioport_write_data, s);
1869
register_ioport_write(0xff81, 1, 2, vbe_ioport_write_data, s);
2201
1871
register_ioport_read(0x1ce, 1, 2, vbe_ioport_read_index, s);
2202
1872
register_ioport_read(0x1d0, 1, 2, vbe_ioport_read_data, s);
2337
int pci_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
2005
int pci_vga_init(PCIBus *bus, DisplayState *ds, uint8_t *vga_ram_base,
2338
2006
unsigned long vga_ram_offset, int vga_ram_size,
2339
2007
unsigned long vga_bios_offset, int vga_bios_size)
2341
2009
PCIVGAState *d;
2343
2011
uint8_t *pci_conf;
2345
d = (PCIVGAState *)pci_register_device(bus, "VGA",
2013
d = (PCIVGAState *)pci_register_device(bus, "VGA",
2346
2014
sizeof(PCIVGAState),
2347
2015
-1, NULL, NULL);
2350
2018
s = &d->vga_state;
2352
2020
vga_common_init(s, ds, vga_ram_base, vga_ram_offset, vga_ram_size);
2355
s->console = graphic_console_init(s->ds, s->update, s->invalidate,
2356
s->screen_dump, s->text_update, s);
2023
graphic_console_init(s->ds, s->update, s->invalidate, s->screen_dump, s);
2358
2025
s->pci_dev = &d->dev;
2360
2027
pci_conf = d->dev.config;
2361
2028
pci_conf[0x00] = 0x34; // dummy VGA (same as Bochs ID)
2362
2029
pci_conf[0x01] = 0x12;
2363
2030
pci_conf[0x02] = 0x11;
2364
2031
pci_conf[0x03] = 0x11;
2365
pci_conf[0x0a] = 0x00; // VGA controller
2032
pci_conf[0x0a] = 0x00; // VGA controller
2366
2033
pci_conf[0x0b] = 0x03;
2367
2034
pci_conf[0x0e] = 0x00; // header_type
2369
2036
/* XXX: vga_ram_size must be a power of two */
2370
pci_register_io_region(&d->dev, 0, vga_ram_size,
2037
pci_register_io_region(&d->dev, 0, vga_ram_size,
2371
2038
PCI_ADDRESS_SPACE_MEM_PREFETCH, vga_map);
2372
2039
if (vga_bios_size != 0) {
2373
2040
unsigned int bios_total_size;