From 4c4ac5438a5f2a81dfd6492412fcbbe2342ed1ff Mon Sep 17 00:00:00 2001 From: Adrien Moulin Date: Tue, 9 Aug 2022 18:13:21 +0200 Subject: [PATCH 1/5] Optimize timer processing Around 25% faster timer processing --- src/include/86box/timer.h | 27 +++++------------- src/timer.c | 58 ++++++++++++++++++--------------------- 2 files changed, 34 insertions(+), 51 deletions(-) diff --git a/src/include/86box/timer.h b/src/include/86box/timer.h index afbcec140..fcccb8494 100644 --- a/src/include/86box/timer.h +++ b/src/include/86box/timer.h @@ -198,30 +198,12 @@ extern pc_timer_t * timer_head; extern int timer_inited; -static __inline void -timer_remove_head_inline(void) -{ - pc_timer_t *timer; - - if (timer_inited && timer_head) { - timer = timer_head; - timer_head = timer->next; - if (timer_head) { - timer_head->prev = NULL; - timer->next->prev = NULL; - } - timer->next = timer->prev = NULL; - timer->flags &= ~TIMER_ENABLED; - } -} - - static __inline void timer_process_inline(void) { pc_timer_t *timer; - if (!timer_inited || !timer_head) + if (!timer_head) return; while(1) { @@ -230,7 +212,12 @@ timer_process_inline(void) if (!TIMER_LESS_THAN_VAL(timer, (uint32_t)tsc)) break; - timer_remove_head_inline(); + timer_head = timer->next; + if (timer_head) + timer_head->prev = NULL; + + timer->next = timer->prev = NULL; + timer->flags &= ~TIMER_ENABLED; if (timer->flags & TIMER_SPLIT) timer_advance_ex(timer, 0); /* We're splitting a > 1 s period into multiple <= 1 s periods. */ diff --git a/src/timer.c b/src/timer.c index 32d382d54..f8e17be2e 100644 --- a/src/timer.c +++ b/src/timer.c @@ -41,20 +41,31 @@ timer_enable(pc_timer_t *timer) return; } - timer_node = timer_head; + if (TIMER_LESS_THAN(timer, timer_head)) { + timer->next = timer_head; + timer->prev = NULL; + timer_head->prev = timer; + timer_head = timer; + timer_target = timer_head->ts.ts32.integer; + return; + } + + if (!timer_head->next) { + timer_head->next = timer; + timer->prev = timer_head; + return; + } + + pc_timer_t *prev = timer_head; + timer_node = timer_head->next; while(1) { /*Timer expires before timer_node. Add to list in front of timer_node*/ if (TIMER_LESS_THAN(timer, timer_node)) { timer->next = timer_node; - timer->prev = timer_node->prev; + timer->prev = prev; timer_node->prev = timer; - if (timer->prev) - timer->prev->next = timer; - else { - timer_head = timer; - timer_target = timer_head->ts.ts32.integer; - } + prev->next = timer; return; } @@ -65,6 +76,7 @@ timer_enable(pc_timer_t *timer) return; } + prev = timer_node; timer_node = timer_node->next; } } @@ -91,33 +103,12 @@ timer_disable(pc_timer_t *timer) } -void -timer_remove_head(void) -{ - pc_timer_t *timer; - - if (!timer_inited) - return; - - if (timer_head) { - timer = timer_head; - timer_head = timer->next; - if (timer_head) { - timer_head->prev = NULL; - timer->next->prev = NULL; - } - timer->next = timer->prev = NULL; - timer->flags &= ~TIMER_ENABLED; - } -} - - void timer_process(void) { pc_timer_t *timer; - if (!timer_inited || !timer_head) + if (!timer_head) return; while(1) { @@ -126,7 +117,12 @@ timer_process(void) if (!TIMER_LESS_THAN_VAL(timer, (uint32_t)tsc)) break; - timer_remove_head(); + timer_head = timer->next; + if (timer_head) + timer_head->prev = NULL; + + timer->next = timer->prev = NULL; + timer->flags &= ~TIMER_ENABLED; if (timer->flags & TIMER_SPLIT) timer_advance_ex(timer, 0); /* We're splitting a > 1 s period into multiple <= 1 s periods. */ From 26d6b308a90631b545e92f46b55a406118147021 Mon Sep 17 00:00:00 2001 From: Adrien Moulin Date: Tue, 9 Aug 2022 19:14:42 +0200 Subject: [PATCH 2/5] Optimize IO in Around 36% faster --- src/include/86box/m_amstrad.h | 2 +- src/io.c | 73 +++++++++++++++++++++-------------- src/machine/m_amstrad.c | 5 ++- 3 files changed, 48 insertions(+), 32 deletions(-) diff --git a/src/include/86box/m_amstrad.h b/src/include/86box/m_amstrad.h index c33d10c70..1b99617ca 100644 --- a/src/include/86box/m_amstrad.h +++ b/src/include/86box/m_amstrad.h @@ -20,7 +20,7 @@ #ifndef MACHINE_AMSTRAD_H #define MACHINE_AMSTRAD_H -extern int amstrad_latch; +extern uint32_t amstrad_latch; enum { AMSTRAD_NOLATCH, diff --git a/src/io.c b/src/io.c index 08e61f7ba..6501a199a 100644 --- a/src/io.c +++ b/src/io.c @@ -312,12 +312,14 @@ inb(uint16_t port) p = q; } - if (port & 0x80) - amstrad_latch = AMSTRAD_NOLATCH; - else if (port & 0x4000) - amstrad_latch = AMSTRAD_SW10; - else - amstrad_latch = AMSTRAD_SW9; + if (amstrad_latch & 0x80000000) { + if (port & 0x80) + amstrad_latch = AMSTRAD_NOLATCH | 0x80000000; + else if (port & 0x4000) + amstrad_latch = AMSTRAD_SW10 | 0x80000000; + else + amstrad_latch = AMSTRAD_SW9 | 0x80000000; + } if (!found) cycles -= io_delay; @@ -401,12 +403,14 @@ inw(uint16_t port) } ret = (ret8[1] << 8) | ret8[0]; - if (port & 0x80) - amstrad_latch = AMSTRAD_NOLATCH; - else if (port & 0x4000) - amstrad_latch = AMSTRAD_SW10; - else - amstrad_latch = AMSTRAD_SW9; + if (amstrad_latch & 0x80000000) { + if (port & 0x80) + amstrad_latch = AMSTRAD_NOLATCH | 0x80000000; + else if (port & 0x4000) + amstrad_latch = AMSTRAD_SW10 | 0x80000000; + else + amstrad_latch = AMSTRAD_SW9 | 0x80000000; + } if (!found) cycles -= io_delay; @@ -487,17 +491,26 @@ inl(uint16_t port) ret16[0] = ret & 0xffff; ret16[1] = (ret >> 16) & 0xffff; - for (i = 0; i < 4; i += 2) { - p = io[(port + i) & 0xffff]; - while(p) { - q = p->next; - if (p->inw && !p->inl) { - ret16[i >> 1] &= p->inw(port + i, p->priv); - found |= 2; - qfound++; - } - p = q; - } + p = io[port & 0xffff]; + while (p) { + q = p->next; + if (p->inw && !p->inl) { + ret16[0] &= p->inw(port, p->priv); + found |= 2; + qfound++; + } + p = q; + } + + p = io[(port + 2) & 0xffff]; + while (p) { + q = p->next; + if (p->inw && !p->inl) { + ret16[1] &= p->inw(port + 2, p->priv); + found |= 2; + qfound++; + } + p = q; } ret = (ret16[1] << 16) | ret16[0]; @@ -519,12 +532,14 @@ inl(uint16_t port) } ret = (ret8[3] << 24) | (ret8[2] << 16) | (ret8[1] << 8) | ret8[0]; - if (port & 0x80) - amstrad_latch = AMSTRAD_NOLATCH; - else if (port & 0x4000) - amstrad_latch = AMSTRAD_SW10; - else - amstrad_latch = AMSTRAD_SW9; + if (amstrad_latch & 0x80000000) { + if (port & 0x80) + amstrad_latch = AMSTRAD_NOLATCH | 0x80000000; + else if (port & 0x4000) + amstrad_latch = AMSTRAD_SW10 | 0x80000000; + else + amstrad_latch = AMSTRAD_SW9 | 0x80000000; + } if (!found) cycles -= io_delay; diff --git a/src/machine/m_amstrad.c b/src/machine/m_amstrad.c index 5dc82226d..eb934ebd1 100644 --- a/src/machine/m_amstrad.c +++ b/src/machine/m_amstrad.c @@ -156,7 +156,7 @@ typedef struct { fdc_t *fdc; } amstrad_t; -int amstrad_latch; +uint32_t amstrad_latch; static uint8_t key_queue[16]; static int key_queue_start = 0, @@ -2255,7 +2255,7 @@ ams_read(uint16_t port, void *priv) else if (video_is_mda()) ret |= 0xc0; - switch (amstrad_latch) { + switch (amstrad_latch & 0x7fffffff) { case AMSTRAD_NOLATCH: ret &= ~0x20; break; @@ -2293,6 +2293,7 @@ machine_amstrad_init(const machine_t *model, int type) ams = (amstrad_t *) malloc(sizeof(amstrad_t)); memset(ams, 0x00, sizeof(amstrad_t)); ams->type = type; + amstrad_latch = 0x80000000; switch (type) { case AMS_PC200: From 0c2d9cb2891009c6cd53036e7ca9fc1ab8d10d3b Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 9 Aug 2022 23:16:38 +0200 Subject: [PATCH 3/5] XGA: Cursor no longer gets black parts when returning from Mystify screensaver to GUI and, at the same time, keeping the Win95 cursor intact. Mono blits no longer cause transparency issues in some programs (e.g.: Creative utilities such as MIDI and CD on Win3.1x). --- src/include/86box/vid_xga.h | 2 +- src/video/vid_xga.c | 144 ++++++++++++++++++++---------------- 2 files changed, 82 insertions(+), 64 deletions(-) diff --git a/src/include/86box/vid_xga.h b/src/include/86box/vid_xga.h index 866aea4a3..f60b3359b 100644 --- a/src/include/86box/vid_xga.h +++ b/src/include/86box/vid_xga.h @@ -92,7 +92,7 @@ typedef struct xga_t { int on; int op_mode_reset, linear_endian_reverse; int sprite_pos, sprite_pos_prefetch, cursor_data_on; - int pal_test; + int pal_test, a5_test; int type, bus; uint32_t linear_base, linear_size, banked_mask; diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 2941d9cb2..4a141660b 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -73,6 +73,8 @@ linear: } xga->on = 0; vga_on = 1; + if (((xga->op_mode & 7) == 4) && ((svga->gdcreg[6] & 0x0c) == 0x0c) && !xga->a5_test) + xga->linear_endian_reverse = 1; } else { mem_mapping_disable(&svga->mapping); mem_mapping_set_addr(&xga->video_mapping, 0xb0000, 0x10000); @@ -320,8 +322,18 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) xga->cursor_data_on = 0; } } - if ((xga->sprite_pos > 16) && (xga->sprite_pos <= 0x1ff)) - xga->cursor_data_on = 0; + + if ((xga->sprite_pos > 16) && (xga->sprite_pos <= 0x1ff)) { + if (xga->aperture_cntl) { + if (xga->sprite_pos & 0x0f) + xga->cursor_data_on = 1; + else + xga->cursor_data_on = 0; + } else { + xga->cursor_data_on = 0; + } + } + //pclog("Sprite POS = %d, data on = %d, idx = %d, apcntl = %d\n", xga->sprite_pos, xga->cursor_data_on, xga->sprite_pal_addr_idx, xga->aperture_cntl); break; case 0x62: @@ -716,7 +728,7 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t b xga_t *xga = &svga->xga; uint32_t addr = base; int bits; - uint32_t byte, byte2; + uint32_t byte; uint8_t px; int skip = 0; @@ -735,7 +747,6 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t b } else { byte = mem_readb_phys(addr); } - byte2 = byte; if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) if (xga->linear_endian_reverse) bits = 7 - (x & 7); @@ -744,18 +755,18 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t b else { bits = 7 - (x & 7); } - px = (byte2 >> bits) & 1; + 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, int height) +xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int width) { xga_t *xga = &svga->xga; uint32_t addr = base; int bits; - uint32_t byte, byte2; + uint32_t byte; uint8_t px; int skip = 0; @@ -776,7 +787,6 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int } else { byte = mem_readb_phys(addr); } - byte2 = byte; if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) if (xga->linear_endian_reverse) bits = 7 - (x & 7); @@ -785,7 +795,7 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int else { bits = 7 - (x & 7); } - px = (byte2 >> bits) & 1; + px = (byte >> bits) & 1; return px; case 3: /*8-bit*/ addr += (y * width); @@ -819,12 +829,11 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int } static void -xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, uint32_t pixel, int width, int height) +xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, uint32_t pixel, int width) { xga_t *xga = &svga->xga; uint32_t addr = base; uint8_t byte, mask; - uint8_t byte2; int skip = 0; if (xga->base_addr_1mb) { @@ -844,7 +853,6 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui } else { byte = mem_readb_phys(addr); } - byte2 = byte; if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) { if (xga->linear_endian_reverse) mask = 1 << (7 - (x & 7)); @@ -853,11 +861,19 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui } else { mask = 1 << (7 - (x & 7)); } - byte2 = (byte2 & ~mask) | ((pixel ? 0xff : 0) & mask); - if (!skip) { - WRITE(addr, byte2); + byte = (byte & ~mask) | ((pixel ? 0xff : 0) & mask); + if (pixel & 1) { + if (!skip) { + xga->vram[((addr)) & (xga->vram_mask)] |= mask; + xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = changeframecount; + } + } else { + if (!skip) { + xga->vram[((addr)) & (xga->vram_mask)] &= ~mask; + xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = changeframecount; + } } - mem_writeb_phys(addr, byte2); + mem_writeb_phys(addr, byte); break; case 3: /*8-bit*/ addr += (y * width); @@ -947,8 +963,8 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) 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.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, xga->accel.px_map_height[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, xga->accel.px_map_height[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, 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)) || @@ -962,19 +978,19 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) { if (ssv & 0x10) - 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, xga->accel.px_map_height[xga->accel.dst_map] + 1); + 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 (((xga->accel.command & 0x30) == 0x10) && x) { if (ssv & 0x10) - 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, xga->accel.px_map_height[xga->accel.dst_map] + 1); + 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 (((xga->accel.command & 0x30) == 0x20) && y) { if (ssv & 0x10) - 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, xga->accel.px_map_height[xga->accel.dst_map] + 1); + 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 { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, xga->accel.px_map_height[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, xga->accel.px_map_height[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, 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)) || @@ -988,13 +1004,13 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) { if (ssv & 0x10) - 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, xga->accel.px_map_height[xga->accel.dst_map] + 1); + 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 (((xga->accel.command & 0x30) == 0x10) && x) { if (ssv & 0x10) - 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, xga->accel.px_map_height[xga->accel.dst_map] + 1); + 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 (((xga->accel.command & 0x30) == 0x20) && y) { if (ssv & 0x10) - 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, xga->accel.px_map_height[xga->accel.dst_map] + 1); + 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); } } } @@ -1080,8 +1096,8 @@ xga_line_draw_write(svga_t *svga) if (steep) { 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.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, xga->accel.px_map_height[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, xga->accel.px_map_height[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, 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)) || @@ -1094,18 +1110,18 @@ xga_line_draw_write(svga_t *svga) ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) - 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, xga->accel.px_map_height[xga->accel.dst_map] + 1); + 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 (((xga->accel.command & 0x30) == 0x10) && x) - 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, xga->accel.px_map_height[xga->accel.dst_map] + 1); + 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 (((xga->accel.command & 0x30) == 0x20) && y) - 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, xga->accel.px_map_height[xga->accel.dst_map] + 1); + 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 ((dy >= xga->accel.mask_map_origin_x_off) && (dy <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (dx >= xga->accel.mask_map_origin_y_off) && (dx <= ((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.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, 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, dy, dx, 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)) || @@ -1118,18 +1134,18 @@ xga_line_draw_write(svga_t *svga) ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x10) && x) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x20) && y) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } } } } else { if (steep) { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, xga->accel.px_map_height[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, xga->accel.px_map_height[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, 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)) || @@ -1142,15 +1158,15 @@ xga_line_draw_write(svga_t *svga) ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) - 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, xga->accel.px_map_height[xga->accel.dst_map] + 1); + 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 (((xga->accel.command & 0x30) == 0x10) && x) - 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, xga->accel.px_map_height[xga->accel.dst_map] + 1); + 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 (((xga->accel.command & 0x30) == 0x20) && y) - 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, xga->accel.px_map_height[xga->accel.dst_map] + 1); + 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 { - src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, xga->accel.src_map, srcbase, xga->accel.px_map_width[xga->accel.src_map] + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + src_dat = (((xga->accel.command >> 28) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.src_map_x & 0xfff, xga->accel.src_map_y & 0xfff, 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, dy, dx, 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)) || @@ -1163,11 +1179,11 @@ xga_line_draw_write(svga_t *svga) ROP(1, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); if ((xga->accel.command & 0x30) == 0) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x10) && x) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); else if (((xga->accel.command & 0x30) == 0x20) && y) - xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, dy, dx, xga->accel.dst_map, dstbase, dest_dat, xga->accel.px_map_width[xga->accel.dst_map] + 1); } } } @@ -1267,8 +1283,8 @@ xga_bitblt(svga_t *svga) if (xga->accel.command & 0xc0) { if ((xga->accel.dx >= xga->accel.mask_map_origin_x_off) && (xga->accel.dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (xga->accel.dy >= xga->accel.mask_map_origin_y_off) && (xga->accel.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, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + 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) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -1280,12 +1296,12 @@ xga_bitblt(svga_t *svga) 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, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); } } } else { - 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, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + 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) : xga->accel.frgd_color; + dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -1297,7 +1313,7 @@ xga_bitblt(svga_t *svga) 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, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); } } @@ -1361,11 +1377,11 @@ xga_bitblt(svga_t *svga) if ((xga->accel.dx >= xga->accel.mask_map_origin_x_off) && (xga->accel.dx <= ((xga->accel.px_map_width[0] & 0xfff) + xga->accel.mask_map_origin_x_off)) && (xga->accel.dy >= xga->accel.mask_map_origin_y_off) && (xga->accel.dy <= ((xga->accel.px_map_height[0] & 0xfff) + xga->accel.mask_map_origin_y_off))) { if (mix) - 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, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; + 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) : xga->accel.frgd_color; else - src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.bkgd_color; + src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : xga->accel.bkgd_color; - dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -1377,16 +1393,16 @@ xga_bitblt(svga_t *svga) old_dest_dat = dest_dat; ROP(mix, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); } } } else { if (mix) - 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, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.frgd_color; + 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) : xga->accel.frgd_color; else - src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1, xga->accel.px_map_height[xga->accel.src_map] + 1) : xga->accel.bkgd_color; + src_dat = (((xga->accel.command >> 30) & 3) == 2) ? xga_accel_read_map_pixel(svga, xga->accel.sx, xga->accel.sy, xga->accel.src_map, srcbase, srcwidth + 1) : xga->accel.bkgd_color; - dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1); if ((xga->accel.cc_cond == 4) || ((xga->accel.cc_cond == 1) && (dest_dat > color_cmp)) || @@ -1398,7 +1414,7 @@ xga_bitblt(svga_t *svga) old_dest_dat = dest_dat; ROP(mix, dest_dat, src_dat); dest_dat = (dest_dat & plane_mask) | (old_dest_dat & ~plane_mask); - xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1, xga->accel.px_map_height[xga->accel.dst_map] + 1); + xga_accel_write_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dest_dat, dstwidth + 1); } } @@ -1827,7 +1843,7 @@ exec_command: xga->accel.src_map = ((xga->accel.command >> 20) & 0x0f); //if (xga->accel.pat_src) { - // pclog("[%04X:%08X]: Accel Command = %02x, full = %08x, patwidth = %d, dstwidth = %d, srcwidth = %d, patheight = %d, dstheight = %d, srcheight = %d, px = %d, py = %d, dx = %d, dy = %d, sx = %d, sy = %d, patsrc = %d, dstmap = %d, srcmap = %d, dstbase = %08x, srcbase = %08x, patbase = %08x, dstformat = %x, srcformat = %x\n", + // pclog("[%04X:%08X]: Accel Command = %02x, full = %08x, patwidth = %d, dstwidth = %d, srcwidth = %d, patheight = %d, dstheight = %d, srcheight = %d, px = %d, py = %d, dx = %d, dy = %d, sx = %d, sy = %d, patsrc = %d, dstmap = %d, srcmap = %d, dstbase = %08x, srcbase = %08x, patbase = %08x, dstformat = %x, srcformat = %x, planemask = %08x\n", // CS, cpu_state.pc, ((xga->accel.command >> 24) & 0x0f), xga->accel.command, xga->accel.px_map_width[xga->accel.pat_src], // xga->accel.px_map_width[xga->accel.dst_map], xga->accel.px_map_width[xga->accel.src_map], // xga->accel.px_map_height[xga->accel.pat_src], xga->accel.px_map_height[xga->accel.dst_map], @@ -1837,8 +1853,8 @@ exec_command: // xga->accel.src_map_x, xga->accel.src_map_y, // xga->accel.pat_src, xga->accel.dst_map, xga->accel.src_map, // xga->accel.px_map_base[xga->accel.dst_map], xga->accel.px_map_base[xga->accel.src_map], xga->accel.px_map_base[xga->accel.pat_src], - // xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, xga->accel.px_map_format[xga->accel.src_map] & 0x0f); - // pclog("\n"); + // xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, xga->accel.px_map_format[xga->accel.src_map] & 0x0f, xga->accel.plane_mask); + // //pclog("\n"); //} switch ((xga->accel.command >> 24) & 0x0f) { case 3: /*Bresenham Line Draw Read*/ @@ -2681,6 +2697,8 @@ static void xga->hwcursor.cur_xsize = 64; xga->hwcursor.cur_ysize = 64; xga->bios_rom.sz = 0x2000; + xga->linear_endian_reverse = 0; + xga->a5_test = 0; f = rom_fopen(xga->type ? XGA2_BIOS_PATH : XGA_BIOS_PATH, "rb"); (void)fseek(f, 0L, SEEK_END); From 43952325ba4aecd91be2e5a4d05ce1507c99b45c Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 9 Aug 2022 23:21:56 +0200 Subject: [PATCH 4/5] Fixed initialized 8-bit blits for OS/2 2.0 Limited Availability (6H.177) and other builds before GA/RTM. --- src/video/vid_svga.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/video/vid_svga.c b/src/video/vid_svga.c index ea70248dc..9ab96c169 100644 --- a/src/video/vid_svga.c +++ b/src/video/vid_svga.c @@ -1079,6 +1079,7 @@ svga_write_common(uint32_t addr, uint8_t val, uint8_t linear, void *p) if (((svga->xga.op_mode & 7) >= 4) && (svga->xga.aperture_cntl == 1)) { if (val == 0xa5) { /*Memory size test of XGA*/ svga->xga.test = val; + svga->xga.a5_test = 1; return; } else if (val == 0x5a) { svga->xga.test = val; From 8c8a42a9be0c2476fa1cd3c3c33a73644d60db89 Mon Sep 17 00:00:00 2001 From: TC1995 Date: Tue, 9 Aug 2022 23:27:03 +0200 Subject: [PATCH 5/5] ESDI MCA: No longer fatal on default reads, fixes Win3.0 MME installation to hard disk using ESDI MCA. --- src/disk/hdc_esdi_mca.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/disk/hdc_esdi_mca.c b/src/disk/hdc_esdi_mca.c index 72db74359..6f6b77723 100644 --- a/src/disk/hdc_esdi_mca.c +++ b/src/disk/hdc_esdi_mca.c @@ -863,7 +863,8 @@ esdi_read(uint16_t port, void *priv) break; default: - fatal("esdi_read port=%04x\n", port); + esdi_mca_log("esdi_read port=%04x\n", port); + break; } return (ret);