diff options
-rw-r--r-- | hw/vga.c | 127 | ||||
-rw-r--r-- | monitor.c | 11 | ||||
-rw-r--r-- | vl.h | 1 |
3 files changed, 116 insertions, 23 deletions
@@ -737,7 +737,7 @@ static uint32_t vga_mem_readl(uint32_t addr) } /* called for accesses between 0xa0000 and 0xc0000 */ -void vga_mem_writeb(uint32_t addr, uint32_t val, uint32_t vaddr) +static void vga_mem_writeb(uint32_t addr, uint32_t val, uint32_t vaddr) { VGAState *s = &vga_state; int memory_map_mode, plane, write_mode, b, func_select; @@ -865,13 +865,13 @@ void vga_mem_writeb(uint32_t addr, uint32_t val, uint32_t vaddr) } } -void vga_mem_writew(uint32_t addr, uint32_t val, uint32_t vaddr) +static void vga_mem_writew(uint32_t addr, uint32_t val, uint32_t vaddr) { vga_mem_writeb(addr, val & 0xff, vaddr); vga_mem_writeb(addr + 1, (val >> 8) & 0xff, vaddr); } -void vga_mem_writel(uint32_t addr, uint32_t val, uint32_t vaddr) +static void vga_mem_writel(uint32_t addr, uint32_t val, uint32_t vaddr) { vga_mem_writeb(addr, val & 0xff, vaddr); vga_mem_writeb(addr + 1, (val >> 8) & 0xff, vaddr); @@ -1523,7 +1523,23 @@ void vga_update_display(void) if (s->ds->depth == 0) { /* nothing to do */ - } else { + } else { + switch(s->ds->depth) { + case 8: + s->rgb_to_pixel = rgb_to_pixel8_dup; + break; + case 15: + s->rgb_to_pixel = rgb_to_pixel15_dup; + break; + default: + case 16: + s->rgb_to_pixel = rgb_to_pixel16_dup; + break; + case 32: + s->rgb_to_pixel = rgb_to_pixel32_dup; + break; + } + full_update = 0; graphic_mode = s->gr[6] & 1; if (graphic_mode != s->graphic_mode) { @@ -1537,7 +1553,7 @@ void vga_update_display(void) } } -void vga_reset(VGAState *s) +static void vga_reset(VGAState *s) { memset(s, 0, sizeof(VGAState)); #ifdef CONFIG_S3VGA @@ -1550,13 +1566,13 @@ void vga_reset(VGAState *s) s->graphic_mode = -1; /* force full update */ } -CPUReadMemoryFunc *vga_mem_read[3] = { +static CPUReadMemoryFunc *vga_mem_read[3] = { vga_mem_readb, vga_mem_readw, vga_mem_readl, }; -CPUWriteMemoryFunc *vga_mem_write[3] = { +static CPUWriteMemoryFunc *vga_mem_write[3] = { vga_mem_writeb, vga_mem_writew, vga_mem_writel, @@ -1593,22 +1609,6 @@ int vga_initialize(DisplayState *ds, uint8_t *vga_ram_base, vga_reset(s); - switch(ds->depth) { - case 8: - s->rgb_to_pixel = rgb_to_pixel8_dup; - break; - case 15: - s->rgb_to_pixel = rgb_to_pixel15_dup; - break; - default: - case 16: - s->rgb_to_pixel = rgb_to_pixel16_dup; - break; - case 32: - s->rgb_to_pixel = rgb_to_pixel32_dup; - break; - } - s->vram_ptr = vga_ram_base; s->vram_offset = vga_ram_offset; s->vram_size = vga_ram_size; @@ -1652,3 +1652,84 @@ int vga_initialize(DisplayState *ds, uint8_t *vga_ram_base, #endif return 0; } + +/********************************************************/ +/* vga screen dump */ + +static int vga_save_w, vga_save_h; + +static void vga_save_dpy_update(DisplayState *s, + int x, int y, int w, int h) +{ +} + +static void vga_save_dpy_resize(DisplayState *s, int w, int h) +{ + s->linesize = w * 4; + s->data = qemu_malloc(h * s->linesize); + vga_save_w = w; + vga_save_h = h; +} + +static void vga_save_dpy_refresh(DisplayState *s) +{ +} + +static int ppm_save(const char *filename, uint8_t *data, + int w, int h, int linesize) +{ + FILE *f; + uint8_t *d, *d1; + unsigned int v; + int y, x; + + f = fopen(filename, "wb"); + if (!f) + return -1; + fprintf(f, "P6\n%d %d\n%d\n", + w, h, 255); + d1 = data; + for(y = 0; y < h; y++) { + d = d1; + for(x = 0; x < w; x++) { + v = *(uint32_t *)d; + fputc((v >> 16) & 0xff, f); + fputc((v >> 8) & 0xff, f); + fputc((v) & 0xff, f); + d += 4; + } + d1 += linesize; + } + fclose(f); + return 0; +} + +/* save the vga display in a PPM image even if no display is + available */ +void vga_screen_dump(const char *filename) +{ + VGAState *s = &vga_state; + DisplayState *saved_ds, ds1, *ds = &ds1; + + /* XXX: this is a little hackish */ + s->last_width = -1; + s->last_height = -1; + saved_ds = s->ds; + + memset(ds, 0, sizeof(DisplayState)); + ds->dpy_update = vga_save_dpy_update; + ds->dpy_resize = vga_save_dpy_resize; + ds->dpy_refresh = vga_save_dpy_refresh; + ds->depth = 32; + + s->ds = ds; + s->graphic_mode = -1; + vga_update_display(); + + if (ds->data) { + ppm_save(filename, ds->data, vga_save_w, vga_save_h, + s->ds->linesize); + qemu_free(ds->data); + } + s->ds = saved_ds; +} @@ -245,6 +245,15 @@ static void do_change(int argc, const char **argv) bdrv_open(bs, argv[2], 0); } +static void do_screen_dump(int argc, const char **argv) +{ + if (argc != 2) { + help_cmd(argv[0]); + return; + } + vga_screen_dump(argv[1]); +} + static term_cmd_t term_cmds[] = { { "help|?", do_help, "[cmd]", "show the help" }, @@ -258,6 +267,8 @@ static term_cmd_t term_cmds[] = { "[-f] device", "eject a removable media (use -f to force it)" }, { "change", do_change, "device filename", "change a removable media" }, + { "screendump", do_screen_dump, + "filename", "save screen into PPM image 'filename'" }, { NULL, NULL, }, }; @@ -136,6 +136,7 @@ static inline void dpy_resize(DisplayState *s, int w, int h) int vga_initialize(DisplayState *ds, uint8_t *vga_ram_base, unsigned long vga_ram_offset, int vga_ram_size); void vga_update_display(void); +void vga_screen_dump(const char *filename); /* sdl.c */ void sdl_display_init(DisplayState *ds); |