--- trunk/src/devices/dev_vga.c 2007/10/08 16:19:23 20 +++ trunk/src/devices/dev_vga.c 2007/10/08 16:19:37 22 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2004-2005 Anders Gavare. All rights reserved. + * Copyright (C) 2004-2006 Anders Gavare. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -25,7 +25,7 @@ * SUCH DAMAGE. * * - * $Id: dev_vga.c,v 1.90 2005/11/13 00:14:10 debug Exp $ + * $Id: dev_vga.c,v 1.95 2006/01/01 13:17:18 debug Exp $ * * VGA charcell and graphics device. * @@ -73,7 +73,7 @@ uint64_t control_base; struct vfb_data *fb; - size_t fb_size; + uint32_t fb_size; int fb_max_x; /* pixels */ int fb_max_y; /* pixels */ @@ -99,7 +99,7 @@ int graphics_mode; int bits_per_pixel; unsigned char *gfx_mem; - size_t gfx_mem_size; + uint32_t gfx_mem_size; /* Registers: */ int attribute_state; /* 0 or 1 */ @@ -137,6 +137,7 @@ int cursor_y; int modified; + int palette_modified; int update_x1; int update_y1; int update_x2; @@ -207,7 +208,7 @@ for (i=16; i<256; i++) d->fb->rgb_palette[i*3 + 0] = d->fb->rgb_palette[i*3 + 1] = d->fb->rgb_palette[i*3 + 2] = (i & 15) * 4; - + d->palette_modified = 1; i = 0; if (grayscale) { @@ -360,7 +361,8 @@ } for (iy=y*ry; iy<(y+1)*ry; iy++) for (ix=x*rx; ix<(x+1)*rx; ix++) { - int addr2 = (d->fb_max_x * iy + ix) * 3; + uint32_t addr2 = (d->fb_max_x * iy + + ix) * 3; if (addr2 < d->fb_size) dev_fb_access(machine->cpus[0], machine->memory, addr2, @@ -381,11 +383,17 @@ static void vga_update_text(struct machine *machine, struct vga_data *d, int x1, int y1, int x2, int y2) { - int fg, bg, i, x,y, subx, line, start, end, base; + int fg, bg, x,y, subx, line; + size_t i, start, end, base; int font_size = d->font_height; int font_width = d->font_width; unsigned char *pal = d->fb->rgb_palette; + if (d->pixel_repx * font_width > 8*8) { + fatal("[ too large font ]\n"); + return; + } + /* Hm... I'm still using the old start..end code: */ start = (d->max_x * y1 + x1) * 2; end = (d->max_x * y2 + x2) * 2; @@ -405,7 +413,7 @@ for (i=start; i<=end; i+=2) { unsigned char ch = d->charcells[i + base]; - if (d->charcells_drawn[i] == ch && + if (!d->palette_modified && d->charcells_drawn[i] == ch && d->charcells_drawn[i+1] == d->charcells[i+base+1]) continue; @@ -425,8 +433,12 @@ /* Draw the character: */ for (line = 0; line < font_size; line++) { + /* hardcoded for max 8 scaleup... :-) */ + unsigned char rgb_line[3 * 8 * 8]; + int iy; + for (subx = 0; subx < font_width; subx++) { - int ix, iy, color_index; + int ix, color_index; if (d->use_palette_per_line) { int sline = d->pixel_repy * (line+y); @@ -443,19 +455,19 @@ else color_index = bg; - for (iy=0; iypixel_repy; iy++) - for (ix=0; ixpixel_repx; ix++) { - int addr = (d->fb_max_x* (d->pixel_repy - * (line+y) + iy) + (x+subx) * - d->pixel_repx + ix) * 3; + for (ix=0; ixpixel_repx; ix++) + memcpy(rgb_line + (subx*d->pixel_repx + + ix) * 3, &pal[color_index * 3], 3); + } - if (addr >= d->fb_size) - continue; - dev_fb_access(machine->cpus[0], - machine->memory, addr, - &pal[color_index * 3], 3, - MEM_WRITE, d->fb); - } + for (iy=0; iypixel_repy; iy++) { + uint32_t addr = (d->fb_max_x * (d->pixel_repy * + (line+y) + iy) + x * d->pixel_repx) * 3; + if (addr >= d->fb_size) + continue; + dev_fb_access(machine->cpus[0], + machine->memory, addr, rgb_line, + 3 * font_width, MEM_WRITE, d->fb); } } } @@ -560,6 +572,7 @@ vga_update_graphics(cpu->machine, d, d->update_x1, d->update_y1, d->update_x2, d->update_y2); + d->palette_modified = 0; d->modified = 0; d->update_x1 = 999999; d->update_x2 = -1; @@ -577,12 +590,11 @@ * * Reads and writes to the VGA video memory (pixels). */ -int dev_vga_graphics_access(struct cpu *cpu, struct memory *mem, - uint64_t relative_addr, unsigned char *data, size_t len, - int writeflag, void *extra) +DEVICE_ACCESS(vga_graphics) { struct vga_data *d = extra; - int i,j, x=0, y=0, x2=0, y2=0, modified = 0; + int j, x=0, y=0, x2=0, y2=0, modified = 0; + size_t i; if (relative_addr + len >= GFX_ADDR_WINDOW) return 0; @@ -619,8 +631,8 @@ int b = data[i] & pixelmask; int m = d->sequencer_reg[ VGA_SEQ_MAP_MASK] & 0x0f; - int addr = (y * d->max_x + x + i*8 + j) - * d->bits_per_pixel / 8; + uint32_t addr = (y * d->max_x + x + + i*8 + j) * d->bits_per_pixel / 8; unsigned char byte; if (!(d->graphcontr_reg[ VGA_GRAPHCONTR_MASK] & pixelmask)) @@ -675,12 +687,12 @@ * * Reads and writes to the VGA video memory (charcells). */ -int dev_vga_access(struct cpu *cpu, struct memory *mem, uint64_t relative_addr, - unsigned char *data, size_t len, int writeflag, void *extra) +DEVICE_ACCESS(vga) { struct vga_data *d = extra; uint64_t idata = 0, odata = 0; - int i, x, y, x2, y2, r, base; + int x, y, x2, y2, r, base; + size_t i; if (writeflag == MEM_WRITE) idata = memory_readmax64(cpu, data, len); @@ -950,12 +962,10 @@ * * Reads and writes of the VGA control registers. */ -int dev_vga_ctrl_access(struct cpu *cpu, struct memory *mem, - uint64_t relative_addr, unsigned char *data, size_t len, - int writeflag, void *extra) +DEVICE_ACCESS(vga_ctrl) { struct vga_data *d = extra; - int i; + size_t i; uint64_t idata = 0, odata = 0; for (i=0; imodified = 1; + d->palette_modified = 1; d->update_x1 = d->update_y1 = 0; d->update_x2 = d->max_x - 1; d->update_y2 = d->max_y - 1; @@ -1183,7 +1194,7 @@ uint64_t videomem_base, uint64_t control_base, char *name) { struct vga_data *d; - int i; + size_t i; size_t allocsize; d = malloc(sizeof(struct vga_data)); @@ -1193,7 +1204,8 @@ } memset(d, 0, sizeof(struct vga_data)); - d->console_handle = console_start_slave(machine, name); + d->console_handle = console_start_slave(machine, "vga", + CONSOLE_OUTPUT_ONLY); d->videomem_base = videomem_base; d->control_base = control_base;