Merge pull request #5169 from 86Box/tc1995

The delayed video changes of the night (January 20th, 2025)
This commit is contained in:
Miran Grča 2025-01-20 05:38:46 +01:00 committed by GitHub
commit c7c9514c08
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 219 additions and 143 deletions

View file

@ -202,6 +202,14 @@ typedef struct svga_t {
void (*vblank_start)(struct svga_t *svga);
void (*write)(uint32_t addr, uint8_t val, void *priv);
void (*writew)(uint32_t addr, uint16_t val, void *priv);
void (*writel)(uint32_t addr, uint32_t val, void *priv);
uint8_t (*read)(uint32_t addr, void *priv);
uint16_t (*readw)(uint32_t addr, void *priv);
uint32_t (*readl)(uint32_t addr, void *priv);
void (*ven_write)(struct svga_t *svga, uint8_t val, uint32_t addr);
float (*getclock)(int clock, void *priv);
float (*getclock8514)(int clock, void *priv);

View file

@ -4403,7 +4403,13 @@ gd54xx_init(const device_t *info)
if ((vram == 1) || (vram >= 256 && vram <= 1024))
svga->decode_mask = gd54xx->vram_mask;
svga->read = gd54xx_read;
svga->readw = gd54xx_readw;
svga->write = gd54xx_write;
svga->writew = gd54xx_writew;
if (gd54xx->bit32) {
svga->readl = gd54xx_readl;
svga->writel = gd54xx_writel;
mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, gd54xx_readl,
gd54xx_write, gd54xx_writew, gd54xx_writel);
mem_mapping_add(&gd54xx->mmio_mapping, 0, 0,
@ -4423,6 +4429,8 @@ gd54xx_init(const device_t *info)
gd5480_vgablt_write, gd5480_vgablt_writew, gd5480_vgablt_writel,
NULL, MEM_MAPPING_EXTERNAL, gd54xx);
} else {
svga->readl = NULL;
svga->writel = NULL;
mem_mapping_set_handler(&svga->mapping, gd54xx_read, gd54xx_readw, NULL,
gd54xx_write, gd54xx_writew, NULL);
mem_mapping_add(&gd54xx->mmio_mapping, 0, 0,

View file

@ -33,9 +33,12 @@
#include <86box/rom.h>
#include <86box/device.h>
#include <86box/video.h>
#include <86box/vid_8514a.h>
#include <86box/vid_xga.h>
#include <86box/vid_svga.h>
#include <86box/vid_svga_render.h>
#include <86box/vid_ati_eeprom.h>
#include <86box/vid_ati_mach8.h>
#include <86box/plat_fallthrough.h>
#include <86box/plat_unused.h>
@ -425,9 +428,8 @@ ht216_out(uint16_t addr, uint8_t val, void *priv)
svga->banked_mask = 0xffff;
}
if (svga->gdcaddr <= 8) {
if (svga->gdcaddr <= 8)
svga->fast = (svga->gdcreg[8] == 0xff && !(svga->gdcreg[3] & 0x18) && !svga->gdcreg[1]) && svga->chain4 && svga->packed_chain4;
}
break;
case 0x3D4:
@ -625,7 +627,9 @@ ht216_remap(ht216_t *ht216)
void
ht216_recalctimings(svga_t *svga)
{
ht216_t *ht216 = (ht216_t *) svga->priv;
ht216_t *ht216 = (ht216_t *) svga->priv;
ibm8514_t *dev = (ibm8514_t *) svga->dev8514;
mach_t *mach = (mach_t *) svga->ext8514;
int high_res_256 = 0;
@ -672,10 +676,16 @@ ht216_recalctimings(svga_t *svga)
if (!svga->scrblank && svga->attr_palette_enable) {
if (!(svga->gdcreg[6] & 1) && !(svga->attrregs[0x10] & 1)) { /*Text mode*/
if (svga->seqregs[1] & 8) /*40 column*/ {
if (svga->seqregs[1] & 8) /*40 column*/
svga->render = svga_render_text_40;
} else {
else
svga->render = svga_render_text_80;
if (ibm8514_active && (svga->dev8514 != NULL)) {
if (svga->ext8514 != NULL) {
if (!(dev->accel.advfunc_cntl & 0x01) && !(mach->accel.clock_sel & 0x01)) /*FIXME: Possibly a BIOS bug within the V7 chips when it's used with a 8514/A card?*/
dev->on &= ~0x01;
}
}
} else {
if (svga->crtc[0x17] == 0xeb) {
@ -1576,10 +1586,17 @@ ht216_init(const device_t *info, uint32_t mem_size, int has_rom)
if (has_rom == 4)
svga->ramdac = device_add(&sc11484_nors2_ramdac_device);
svga->read = ht216_read;
svga->readw = NULL;
svga->readl = NULL;
svga->write = ht216_write;
svga->writew = ht216_writew;
if ((info->flags & DEVICE_VLB) || (info->flags & DEVICE_MCA)) {
svga->writel = ht216_writel;
mem_mapping_set_handler(&svga->mapping, ht216_read, NULL, NULL, ht216_write, ht216_writew, ht216_writel);
mem_mapping_add(&ht216->linear_mapping, 0, 0, ht216_read_linear, NULL, NULL, ht216_write_linear, ht216_writew_linear, ht216_writel_linear, NULL, MEM_MAPPING_EXTERNAL, svga);
} else {
svga->writel = NULL;
mem_mapping_set_handler(&svga->mapping, ht216_read, NULL, NULL, ht216_write, ht216_writew, NULL);
mem_mapping_add(&ht216->linear_mapping, 0, 0, ht216_read_linear, NULL, NULL, ht216_write_linear, ht216_writew_linear, NULL, NULL, MEM_MAPPING_EXTERNAL, svga);
}

View file

@ -362,11 +362,6 @@ paradise_write(uint32_t addr, uint8_t val, void *priv)
uint32_t prev_addr;
uint32_t prev_addr2;
if (!(svga->attrregs[0x10] & 0x40)) {
svga_write(addr, val, svga);
return;
}
addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3];
/*Could be done in a better way but it works.*/
@ -400,11 +395,6 @@ paradise_writew(uint32_t addr, uint16_t val, void *priv)
uint32_t prev_addr;
uint32_t prev_addr2;
if (!(svga->attrregs[0x10] & 0x40)) {
svga_writew(addr, val, svga);
return;
}
addr = (addr & 0x7fff) + paradise->write_bank[(addr >> 15) & 3];
/*Could be done in a better way but it works.*/
@ -438,9 +428,6 @@ paradise_read(uint32_t addr, void *priv)
uint32_t prev_addr;
uint32_t prev_addr2;
if (!(svga->attrregs[0x10] & 0x40))
return svga_read(addr, svga);
addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3];
/*Could be done in a better way but it works.*/
@ -474,9 +461,6 @@ paradise_readw(uint32_t addr, void *priv)
uint32_t prev_addr;
uint32_t prev_addr2;
if (!(svga->attrregs[0x10] & 0x40))
return svga_readw(addr, svga);
addr = (addr & 0x7fff) + paradise->read_bank[(addr >> 15) & 3];
/*Could be done in a better way but it works.*/
@ -550,6 +534,12 @@ paradise_init(const device_t *info, uint32_t memory)
break;
}
svga->read = paradise_read;
svga->readw = paradise_readw;
svga->readl = NULL;
svga->write = paradise_write;
svga->writew = paradise_writew;
svga->writel = NULL;
mem_mapping_set_handler(&svga->mapping, paradise_read, paradise_readw, NULL, paradise_write, paradise_writew, NULL);
mem_mapping_set_p(&svga->mapping, paradise);

View file

@ -984,7 +984,7 @@ svga_recalctimings(svga_t *svga)
svga_log("IBM 8514/A poll.\n");
timer_set_callback(&svga->timer, ibm8514_poll);
} else {
svga_log("SVGA Poll.\n");
svga_log("SVGA poll enabled.\n");
timer_set_callback(&svga->timer, svga_poll);
}
}
@ -1081,6 +1081,7 @@ svga_poll(void *priv)
}
}
svga_log("SVGA Poll.\n");
if (!svga->linepos) {
if (svga->displine == ((svga->hwcursor_latch.y < 0) ? 0 : svga->hwcursor_latch.y) && svga->hwcursor_latch.ena) {
svga->hwcursor_on = svga->hwcursor_latch.cur_ysize - svga->hwcursor_latch.yoff;
@ -1406,16 +1407,34 @@ svga_init(const device_t *info, svga_t *svga, void *priv, int memsize,
svga->ksc5601_english_font_type = 0;
if ((info->flags & DEVICE_PCI) || (info->flags & DEVICE_VLB) || (info->flags & DEVICE_MCA)) {
svga->read = svga_read;
svga->readw = svga_readw;
svga->readl = svga_readl;
svga->write = svga_write;
svga->writew = svga_writew;
svga->writel = svga_writel;
mem_mapping_add(&svga->mapping, 0xa0000, 0x20000,
svga_read, svga_readw, svga_readl,
svga_write, svga_writew, svga_writel,
NULL, MEM_MAPPING_EXTERNAL, svga);
} else if ((info->flags & DEVICE_ISA) && (info->flags & DEVICE_AT)) {
svga->read = svga_read;
svga->readw = svga_readw;
svga->readl = NULL;
svga->write = svga_write;
svga->writew = svga_writew;
svga->writel = NULL;
mem_mapping_add(&svga->mapping, 0xa0000, 0x20000,
svga_read, svga_readw, NULL,
svga_write, svga_writew, NULL,
NULL, MEM_MAPPING_EXTERNAL, svga);
} else {
svga->read = svga_read;
svga->readw = NULL;
svga->readl = NULL;
svga->write = svga_write;
svga->writew = NULL;
svga->writel = NULL;
mem_mapping_add(&svga->mapping, 0xa0000, 0x20000,
svga_read, NULL, NULL,
svga_write, NULL, NULL,

View file

@ -188,7 +188,7 @@ xga_updatemapping(svga_t *svga)
mem_mapping_disable(&xga->linear_mapping);
break;
default:
xga_log("XGA: Extended Graphics mode.\n");
xga_log("XGA: Extended Graphics mode, ap=%d.\n", xga->aperture_cntl);
switch (xga->aperture_cntl) {
case 0:
xga_log("XGA: No 64KB aperture: 1MB=%x, 4MB=%x, SVGA Mapping Base=%x.\n", xga->base_addr_1mb, xga->linear_base, svga->mapping.base);
@ -201,7 +201,7 @@ xga_updatemapping(svga_t *svga)
} else
mem_mapping_disable(&xga->linear_mapping);
mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel);
switch (svga->gdcreg[6] & 0xc) {
case 0x0: /*128k at A0000*/
mem_mapping_set_addr(&svga->mapping, 0xa0000, 0x20000);
@ -439,9 +439,9 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val)
break;
case 0x51:
xga_log("Reg51 write = %02x.\n", val);
xga_log("Reg51 write=%02x.\n", val & 0x07);
xga->disp_cntl_2 = val;
xga->on = ((val & 7) >= 2);
xga->on = ((val & 0x07) >= 0x02);
svga_recalctimings(svga);
break;
@ -535,9 +535,11 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *priv)
xga_log("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val);
switch (addr & 0x0f) {
case 0:
xga_log("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val);
xga->op_mode = val;
break;
case 1:
xga_log("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val);
xga->aperture_cntl = val & 3;
xga_updatemapping(svga);
break;
@ -579,6 +581,7 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *priv)
break;
default:
xga_log("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val);
break;
}
}
@ -807,6 +810,7 @@ xga_ext_inb(uint16_t addr, void *priv)
break;
default:
xga_log("[%04X:%08X]: EXT INB = %02x, ret = %02x.\n\n", CS, cpu_state.pc, addr, ret);
break;
}
@ -933,6 +937,32 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, uint32_t base, int
return px;
}
static uint32_t
xga_accel_read_area_map_pixel(svga_t *svga, int x, int y, uint32_t base, int width)
{
const xga_t *xga = (xga_t *) svga->xga;
uint32_t addr = base;
int bits;
uint8_t byte;
uint8_t px;
int skip = 0;
if ((addr < xga->linear_base) || (addr > (xga->linear_base + 0xfffff)))
skip = 1;
addr += (y * (width >> 3));
addr += (x >> 3);
if (!skip) {
READ(addr, byte);
} else
byte = mem_readb_phys(addr);
bits = 7 - (x & 7);
px = (byte >> bits) & 1;
return px;
}
static uint32_t
xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int width)
{
@ -971,6 +1001,7 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int
} else
byte = mem_readb_phys(addr);
xga_log("4bpp read: OPMODEBIG=%02x, SRC Map=%02x, DST Map=%02x, AccessMode=%02x, SRCPIX=%02x, DSTPIX=%02x, wordpix=%04x, x=%d, y=%d, skip=%d.\n", xga->op_mode & 0x08, (xga->accel.px_map_format[xga->accel.src_map] & 0x0f), (xga->accel.px_map_format[xga->accel.dst_map] & 0x0f), xga->access_mode & 0x0f, xga->accel.src_map, xga->accel.dst_map, byte, x, y, skip);
return byte;
case 3: /*8-bit*/
addr += (y * width);
@ -984,19 +1015,15 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int
case 4: /*16-bit*/
addr += (y * (width << 1));
addr += (x << 1);
if (xga->access_mode & 0x08) {
if (!skip) {
READW(addr, byte);
} else
byte = mem_readw_phys(addr);
} else {
if (!skip) {
READW(addr, byte);
} else {
byte = mem_readw_phys(addr);
if ((xga->access_mode & 0x07) == 0x04)
byte = ((byte & 0xff00) >> 8) | ((byte & 0x00ff) << 8);
}
if (!skip) {
READW(addr, byte);
} else {
byte = mem_readw_phys(addr);
if ((xga->access_mode & 0x07) == 0x04)
byte = ((byte & 0xff00) >> 8) | ((byte & 0x00ff) << 8);
else if (xga->access_mode & 0x08)
byte = ((byte & 0xff00) >> 8) | ((byte & 0x00ff) << 8);
}
return byte;
@ -1081,17 +1108,14 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui
case 4: /*16-bit*/
addr += (y * width << 1);
addr += (x << 1);
if (xga->access_mode & 0x08) {
if (!skip) {
WRITEW(addr, pixel);
}
if (!skip) {
WRITEW(addr, pixel);
} else {
if (!skip) {
WRITEW(addr, pixel);
} else {
if ((xga->access_mode & 0x07) == 0x04)
pixel = ((pixel & 0xff00) >> 8) | ((pixel & 0x00ff) << 8);
}
if ((xga->access_mode & 0x07) == 0x04)
pixel = ((pixel & 0xff00) >> 8) | ((pixel & 0x00ff) << 8);
else if (xga->access_mode & 0x08)
pixel = ((pixel & 0xff00) >> 8) | ((pixel & 0x00ff) << 8);
}
mem_writew_phys(addr, pixel);
break;
@ -1237,12 +1261,11 @@ xga_line_draw_write(svga_t *svga)
uint32_t srcbase = xga->accel.px_map_base[xga->accel.src_map];
int y = xga->accel.blt_width;
int x = 0;
int draw_pixel = 0;
int16_t dx;
int16_t dy;
int16_t cx;
int16_t cy;
int err = xga->accel.bres_err_term;
int draw_pixel = 0;
cx = xga->accel.src_map_x & 0xfff;
cy = xga->accel.src_map_y & 0xfff;
@ -1256,38 +1279,57 @@ xga_line_draw_write(svga_t *svga)
dy |= ~0x17ff;
if ((xga->accel.command & 0x30) == 0x30)
xga_log("Line Draw Write: BLTWIDTH=%d, BLTHEIGHT=%d, FRGDCOLOR=%04x, XDIR=%i, YDIR=%i, steep=%s, ERR=%04x.\n", xga->accel.blt_width, xga->accel.blt_height, xga->accel.frgd_color & 0xffff, xdir, ydir, (xga->accel.octant & 0x01) ? "0" : "1", err);
xga_log("Line Draw Write Fill: DX=%d, DY=%d, BLTWIDTH=%d, BLTHEIGHT=%d, FRGDCOLOR=%04x, negative XDIR=%i, negative YDIR=%i, YMAJOR=%d, ERR=%d, BRESK2=%d, BRESK1=%d, mask=%02x.\n", dx, dy, xga->accel.blt_width, xga->accel.blt_height, xga->accel.frgd_color & 0xffff, (xga->accel.octant & 0x04), (xga->accel.octant & 0x02), (xga->accel.octant & 0x01), xga->accel.bres_err_term, xga->accel.bres_k2, xga->accel.bres_k1, xga->accel.command & 0xc0);
if (xga->accel.pat_src == 8) {
if ((xga->accel.command & 0x30) == 0x30) {
while (y >= 0) {
draw_pixel = 0;
if (xga->accel.octant & 0x01) {
if (xga->accel.octant & 0x02) { /*Bottom-to-Top*/
if (xga->accel.octant & 0x01) { /*Y Major*/
if (xga->accel.octant & 0x02) { /*Bottom to Top*/
if (x)
draw_pixel = 1;
} else { /*Top-to-Bottom*/
} else { /*Top to Bottom*/
if (y)
draw_pixel = 1;
}
} else if (!(xga->accel.octant & 0x04) && (err < (xga->accel.bres_k2 + xga->accel.bres_k1))) /*X+*/
draw_pixel = 1;
else if ((xga->accel.octant & 0x04) && (err >= 0)) /*X-*/
draw_pixel = 1;
if (xga->accel.command & 0xc0) {
if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) {
if (draw_pixel) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
ROP(1, dest_dat, src_dat);
xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1);
} else { /*X Major*/
if (xga->accel.octant & 0x04) { /*Right to Left*/
if (xga->accel.bres_err_term >= 0) {
if (xga->accel.octant & 0x02) { /*Bottom to Top*/
if (x)
draw_pixel = 1;
} else { /*Top to Bottom*/
if (y)
draw_pixel = 1;
}
}
} else { /*Left to Right*/
if (xga->accel.bres_err_term < (xga->accel.bres_k1 + xga->accel.bres_k2)) {
if (xga->accel.octant & 0x02) { /*Bottom to Top*/
if (x)
draw_pixel = 1;
} else { /*Top to Bottom*/
if (y)
draw_pixel = 1;
}
}
}
}
xga_log("Draw Boundary: DX=%d, DY=%d, wrt_pix=%d, ymajor=%d, bottomtotop=%x, len=%d, err=%d, frgdmix=%02x.\n", dx, dy, draw_pixel, xga->accel.octant & 0x01, xga->accel.octant & 0x02, y, xga->accel.bres_err_term, xga->accel.frgd_mix & 0x1f);
if (xga->accel.command & 0xc0) {
if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off)) && draw_pixel) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, cx, cy, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1) : xga->accel.frgd_color;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(1, dest_dat, src_dat);
dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask);
xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1);
}
}
} else {
if (draw_pixel) {
@ -1295,7 +1337,9 @@ xga_line_draw_write(svga_t *svga)
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(1, dest_dat, src_dat);
dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask);
xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1);
}
}
@ -1310,28 +1354,28 @@ xga_line_draw_write(svga_t *svga)
else
dy++;
if (err >= 0) {
err += xga->accel.bres_k2;
if (xga->accel.bres_err_term >= 0) {
xga->accel.bres_err_term += xga->accel.bres_k2;
if (xga->accel.octant & 0x04)
dx--;
else
dx++;
} else
err += xga->accel.bres_k1;
xga->accel.bres_err_term += xga->accel.bres_k1;
} else {
if (xga->accel.octant & 0x04)
dx--;
else
dx++;
if (err >= 0) {
err += xga->accel.bres_k2;
if (xga->accel.bres_err_term >= 0) {
xga->accel.bres_err_term += xga->accel.bres_k2;
if (xga->accel.octant & 0x02)
dy--;
else
dy++;
} else
err += xga->accel.bres_k1;
xga->accel.bres_err_term += xga->accel.bres_k1;
}
x++;
y--;
@ -1384,28 +1428,28 @@ xga_line_draw_write(svga_t *svga)
else
dy++;
if (err >= 0) {
err += xga->accel.bres_k2;
if (xga->accel.bres_err_term >= 0) {
xga->accel.bres_err_term += xga->accel.bres_k2;
if (xga->accel.octant & 0x04)
dx--;
else
dx++;
} else
err += xga->accel.bres_k1;
xga->accel.bres_err_term += xga->accel.bres_k1;
} else {
if (xga->accel.octant & 0x04)
dx--;
else
dx++;
if (err >= 0) {
err += xga->accel.bres_k2;
if (xga->accel.bres_err_term >= 0) {
xga->accel.bres_err_term += xga->accel.bres_k2;
if (xga->accel.octant & 0x02)
dy--;
else
dy++;
} else
err += xga->accel.bres_k1;
xga->accel.bres_err_term += xga->accel.bres_k1;
}
y--;
x++;
@ -1454,20 +1498,21 @@ xga_bitblt(svga_t *svga)
if (xga->accel.dst_map_y >= 0x1800)
dy |= ~0x17ff;
xga_log("D(%d,%d), SWH(%d,%d), BLT(%d,%d), dstwidth=%d.\n", dx, dy, xga->accel.x, xga->accel.y, srcwidth, srcheight, dstwidth);
xga_log("D(%d,%d), SWH(%d,%d), BLT(%d,%d), dstwidth=%d, frgdcol=%04x, bkgdcol=%04x.\n", dx, dy, xga->accel.x, xga->accel.y, srcwidth, srcheight, dstwidth, frgdcol, bkgdcol);
xga->accel.pattern = 0;
xga->accel.filling = 0;
xga_log("XGA bitblt linear endian reverse=%d, access_mode=%x, octanty=%d, src command = %08x, "
xga_log("XGA bitblt access_mode=%x, octanty=%d, src command=%08x, "
"pxsrcmap=%x, pxpatmap=%x, pxdstmap=%x, srcmap=%d, patmap=%d, dstmap=%d, "
"usesrcvramfr=%d, usevrambk=%d.\n",
xga->linear_endian_reverse, xga->access_mode & 0x0f, ydir, xga->accel.command,
"usesrcvramfr=%d, usevrambk=%d, frgdcol=%04x, bkgdcol=%04x, bgmix=%02x, fgmix=%02x.\n",
xga->access_mode & 0x0f, ydir, xga->accel.command,
xga->accel.px_map_format[xga->accel.src_map] & 0x0f,
xga->accel.px_map_format[xga->accel.pat_src] & 0x0f,
xga->accel.px_map_format[xga->accel.dst_map] & 0x0f,
xga->accel.src_map, xga->accel.pat_src,
xga->accel.dst_map, ((xga->accel.command >> 28) & 3), ((xga->accel.command >> 30) & 3));
xga->accel.dst_map, ((xga->accel.command >> 28) & 3), ((xga->accel.command >> 30) & 3),
frgdcol, bkgdcol, xga->accel.bkgd_mix & 0x1f, xga->accel.frgd_mix & 0x1f);
if (xga->accel.pat_src == 8) {
if (srcheight == 7)
@ -1593,17 +1638,19 @@ xga_bitblt(svga_t *svga)
xga->accel.px_map_width[2], xga->accel.px_map_width[3], bkgdcol);
xga_log("Pattern Enabled?=%d, patwidth=%d, patheight=%d, P(%d,%d).\n", xga->accel.pattern, patwidth, patheight, xga->accel.px, xga->accel.py);
if ((((xga->accel.command >> 24) & 0x0f) == 0x0a) && ((xga->accel.bkgd_mix & 0x1f) == 5)) {
while (xga->accel.y >= 0) {
mix = xga_accel_read_pattern_map_pixel(svga, xga->accel.px, xga->accel.py, patbase, patwidth + 1);
if (mix)
xga->accel.filling = !xga->accel.filling;
if (((xga->accel.command >> 24) & 0x0f) == 0x0a) {
if ((xga->accel.bkgd_mix & 0x1f) == 0x05) {
while (xga->accel.y >= 0) {
mix = xga_accel_read_area_map_pixel(svga, xga->accel.px, xga->accel.py, patbase, patwidth + 1);
if (mix)
xga->accel.filling ^= 1;
if (xga->accel.command & 0xc0) {
if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : frgdcol;
if (xga->accel.filling) {
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, 1024);
xga_log("Area Fill Command: dx=%d, dy=%d, mix=%x, filling=%x.\n", dx, dy, mix, xga->accel.filling);
if (xga->accel.command & 0xc0) {
if ((dx >= xga->accel.mask_map_origin_x_off) && (dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dy >= xga->accel.mask_map_origin_y_off) && (dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off)) && xga->accel.filling) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : frgdcol;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
ROP(1, dest_dat, src_dat);
@ -1612,11 +1659,9 @@ xga_bitblt(svga_t *svga)
xga_accel_write_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1);
}
}
}
} else {
if ((dx >= 0) && (dx <= dstwidth) && (dy >= 0) && (dy <= dstheight)) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : frgdcol;
if (xga->accel.filling) {
} else {
if ((dx >= 0) && (dx <= dstwidth) && (dy >= 0) && (dy <= dstheight) && xga->accel.filling) {
src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : frgdcol;
dest_dat = xga_accel_read_map_pixel(svga, dx, dy, xga->accel.dst_map, dstbase, dstwidth + 1);
if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || ((xga->accel.cc_cond == 2) && (dest_dat == color_cmp)) || ((xga->accel.cc_cond == 3) && (dest_dat < color_cmp)) || ((xga->accel.cc_cond == 5) && (dest_dat >= color_cmp)) || ((xga->accel.cc_cond == 6) && (dest_dat != color_cmp)) || ((xga->accel.cc_cond == 7) && (dest_dat <= color_cmp))) {
old_dest_dat = dest_dat;
@ -1627,32 +1672,35 @@ xga_bitblt(svga_t *svga)
}
}
}
}
xga->accel.sx = ((xga->accel.sx + xdir) & srcwidth) | (xga->accel.sx & ~srcwidth);
xga->accel.px++;
xga->accel.sx = ((xga->accel.sx + xdir) & srcwidth) | (xga->accel.sx & ~srcwidth);
xga->accel.px++;
dx++;
xga->accel.x--;
if (xga->accel.x < 0) {
xga->accel.y--;
xga->accel.x = xga->accel.blt_width & 0xfff;
dx++;
xga->accel.x--;
if (xga->accel.x < 0) {
xga->accel.y--;
xga->accel.x = xga->accel.blt_width & 0xfff;
dx = xga->accel.dst_map_x;
if (xga->accel.dst_map_x >= 0x1800)
dx |= ~0x17ff;
dx = xga->accel.dst_map_x;
if (xga->accel.dst_map_x >= 0x1800)
dx |= ~0x17ff;
xga->accel.sx = xga->accel.src_map_x & 0xfff;
xga->accel.px = xga->accel.pat_map_x & 0xfff;
xga->accel.sx = xga->accel.src_map_x & 0xfff;
xga->accel.px = xga->accel.pat_map_x & 0xfff;
xga->accel.sy = ((xga->accel.sy + ydir) & srcheight) | (xga->accel.sy & ~srcheight);
xga->accel.py++;
xga->accel.sy = ((xga->accel.sy + ydir) & srcheight) | (xga->accel.sy & ~srcheight);
xga->accel.py++;
dy++;
xga->accel.filling = 0;
dy++;
xga->accel.filling = 0;
if (xga->accel.y < 0)
return;
if (xga->accel.y < 0) {
xga->accel.dst_map_x = dx;
xga->accel.dst_map_y = dy;
return;
}
}
}
}
} else {
@ -2171,7 +2219,6 @@ exec_command:
xga->accel.src_map = ((xga->accel.command >> 20) & 0x0f);
xga_log("PATMAP=%x, DSTMAP=%x, SRCMAP=%x.\n", xga->accel.px_map_format[xga->accel.pat_src], xga->accel.px_map_format[xga->accel.dst_map], xga->accel.px_map_format[xga->accel.src_map]);
#ifdef ENABLE_XGA_LOG
if (xga->accel.pat_src)
xga_log("[%04X:%08X]: Accel Command = %02x, full = %08x, patwidth = %d, "
"dstwidth = %d, srcwidth = %d, patheight = %d, dstheight = %d, "
@ -2196,7 +2243,7 @@ exec_command:
xga->accel.px_map_format[xga->accel.dst_map] & 0x0f,
xga->accel.px_map_format[xga->accel.src_map] & 0x0f,
xga->accel.plane_mask);
#endif
switch ((xga->accel.command >> 24) & 0x0f) {
case 2: /*Short Stroke Vectors Read */
xga_log("Short Stroke Vectors Read.\n");
@ -2670,7 +2717,7 @@ xga_write_test(uint32_t addr, uint8_t val, void *priv)
xga->vram[addr & xga->vram_mask] = val;
xga_log("XGA Linear endian reverse write, val = %02x, addr = %05x, banked mask = %04x, a5test=%d.\n", val, addr, svga->banked_mask, xga->a5_test);
}
} else if (xga->aperture_cntl)
} else if (xga->aperture_cntl || (!xga->aperture_cntl && (svga->mapping.base == 0xa0000)))
xga->on = 0;
}
}
@ -2777,9 +2824,8 @@ xga_read_test(uint32_t addr, void *priv)
addr += xga->read_bank;
return xga->vram[addr & xga->vram_mask];
}
} else if (xga->aperture_cntl) {
} else if (xga->aperture_cntl || (!xga->aperture_cntl && (svga->mapping.base == 0xa0000)))
xga->on = 0;
}
}
return ret;
}
@ -2874,7 +2920,7 @@ xga_write_linear(uint32_t addr, uint8_t val, void *priv)
svga_t *svga = (svga_t *) priv;
xga_t *xga = (xga_t *) svga->xga;
xga_log("WrtieLL XGA=%d.\n", xga->on);
xga_log("WriteLL XGA=%d.\n", xga->on);
if (!xga->on) {
svga_write_linear(addr, val, svga);
return;
@ -2889,13 +2935,6 @@ xga_write_linear(uint32_t addr, uint8_t val, void *priv)
cycles -= svga->monitor->mon_video_timing_write_b;
if (!(xga->access_mode & 0x08)) {
if ((xga->access_mode & 0x07) == 0x04) {
if ((xga->accel.px_map_format[xga->accel.dst_map] & 0x07) == 0x04)
addr ^= 1;
}
}
xga->changedvram[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount;
xga->vram[addr & xga->vram_mask] = val;
}
@ -2951,14 +2990,9 @@ xga_read_linear(uint32_t addr, void *priv)
cycles -= svga->monitor->mon_video_timing_read_b;
if (!(xga->access_mode & 0x08)) {
if ((xga->access_mode & 0x07) == 0x04) {
if ((xga->accel.px_map_format[xga->accel.dst_map] & 0x07) == 0x04)
addr ^= 1;
}
}
ret = xga->vram[addr & xga->vram_mask];
return xga->vram[addr & xga->vram_mask];
return ret;
}
static uint16_t
@ -3234,7 +3268,7 @@ xga_mca_reset(void *priv)
svga_t *svga = (svga_t *) priv;
xga_log("MCA Reset.\n");
mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel);
xga_mca_write(0x102, 0, svga);
}
@ -3250,7 +3284,7 @@ xga_reset(void *priv)
xga->on = 0;
xga->a5_test = 0;
mem_mapping_set_handler(&svga->mapping, svga_read, svga_readw, svga_readl, svga_write, svga_writew, svga_writel);
mem_mapping_set_handler(&svga->mapping, svga->read, svga->readw, svga->readl, svga->write, svga->writew, svga->writel);
}
static uint8_t