From d2b0d0c3c20ec859e7bca3c68d93984558518f7a Mon Sep 17 00:00:00 2001 From: TC1995 Date: Thu, 27 Jul 2023 16:01:20 +0200 Subject: [PATCH] XGA: 16bpp mode in accelerated mode no longer shows inverted colors in various parts of some stuff (e.g.: Win3.1x, OS/2). --- src/include/86box/vid_xga.h | 137 +++----- src/video/vid_xga.c | 620 +++++++++++++++++------------------- 2 files changed, 340 insertions(+), 417 deletions(-) diff --git a/src/include/86box/vid_xga.h b/src/include/86box/vid_xga.h index af5191a81..4401c507d 100644 --- a/src/include/86box/vid_xga.h +++ b/src/include/86box/vid_xga.h @@ -20,7 +20,7 @@ #include <86box/rom.h> -typedef struct xga_hwcursor_t { +typedef struct { int ena; int x; int y; @@ -37,14 +37,11 @@ typedef struct xga_t { mem_mapping_t video_mapping; rom_t bios_rom; rom_t vga_bios_rom; - xga_hwcursor_t hwcursor; - xga_hwcursor_t hwcursor_latch; + xga_hwcursor_t hwcursor, hwcursor_latch; PALETTE extpal; - uint8_t test; - uint8_t atest[2]; - uint8_t testpixel; - + uint8_t test, atest[2], testpixel; + ; uint8_t pos_regs[8]; uint8_t disp_addr; uint8_t cfg_reg; @@ -57,43 +54,34 @@ typedef struct xga_t { uint8_t regs_idx; uint8_t hwc_hotspot_x; uint8_t hwc_hotspot_y; - uint8_t disp_cntl_1; - uint8_t disp_cntl_2; - uint8_t clk_sel_1; - uint8_t clk_sel_2; + uint8_t disp_cntl_1, disp_cntl_2; + uint8_t clk_sel_1, clk_sel_2; uint8_t hwc_control; uint8_t bus_arb; uint8_t isa_pos_enable; uint8_t hwcursor_oddeven; uint8_t cfg_reg_instance; uint8_t rowcount; - uint8_t pal_idx; - uint8_t pal_idx_prefetch; + uint8_t pal_idx, pal_idx_prefetch; uint8_t pal_seq; uint8_t pal_mask; - uint8_t pal_r; - uint8_t pal_r_prefetch; - uint8_t pal_g; - uint8_t pal_g_prefetch; - uint8_t pal_b; - uint8_t pal_b_prefetch; + uint8_t pal_r, pal_r_prefetch; + uint8_t pal_g, pal_g_prefetch; + uint8_t pal_b, pal_b_prefetch; uint8_t sprite_data[1024]; uint8_t scrollcache; + uint8_t border_color; uint8_t direct_color; uint8_t dma_channel; - uint8_t instance_isa; - uint8_t instance_num; - uint8_t ext_mem_addr; - uint8_t *vram; - uint8_t *changedvram; + uint8_t instance_isa, instance_num, ext_mem_addr; + uint8_t *vram, *changedvram; int16_t hwc_pos_x; int16_t hwc_pos_y; uint16_t pos_idx; uint16_t htotal; - uint16_t sprite_idx; - uint16_t sprite_idx_prefetch; + uint16_t sprite_idx, sprite_idx_prefetch; uint16_t hdisp; uint16_t vtotal; uint16_t vdispend; @@ -101,74 +89,41 @@ typedef struct xga_t { uint16_t vsyncstart; uint16_t linecmp; uint16_t pix_map_width; - uint16_t sprite_pal_addr_idx; - uint16_t old_pal_addr_idx; + uint16_t sprite_pal_addr_idx, old_pal_addr_idx; uint16_t sprite_pal_addr_idx_prefetch; - int v_total; - int dispend; - int v_syncstart; - int split; - int v_blankstart; - int h_disp; - int h_disp_old; - int h_total; - int h_disp_time; - int rowoffset; - int dispon; - int h_disp_on; - int vc; - int sc; - int linepos; - int oddeven; - int firstline; - int lastline; - int firstline_draw; - int lastline_draw; - int displine; - int fullchange; - int interlace; - int char_width; - int hwcursor_on; - int pal_pos; - int pal_pos_prefetch; + int v_total, dispend, v_syncstart, split, v_blankstart, + h_disp, h_disp_old, h_total, h_disp_time, rowoffset, + dispon, h_disp_on, vc, sc, linepos, oddeven, firstline, lastline, + firstline_draw, lastline_draw, displine, fullchange, interlace, + char_width, hwcursor_on; + int pal_pos, pal_pos_prefetch; int on; - int op_mode_reset; - int linear_endian_reverse; - int sprite_pos; - int sprite_pos_prefetch; - int cursor_data_on; - int pal_test; - int a5_test; - int type; - int bus; + int op_mode_reset, linear_endian_reverse; + int sprite_pos, sprite_pos_prefetch, cursor_data_on; + int pal_test, a5_test; + int type, bus; - uint32_t linear_base; - uint32_t linear_size; - uint32_t banked_mask; + uint32_t linear_base, linear_size, banked_mask; uint32_t base_addr_1mb; - uint32_t hwc_color0; - uint32_t hwc_color1; + uint32_t hwc_color0, hwc_color1; uint32_t disp_start_addr; uint32_t ma_latch; uint32_t vram_size; uint32_t vram_mask; uint32_t rom_addr; - uint32_t ma; - uint32_t maback; + uint32_t ma, maback; uint32_t extpallook[256]; - uint32_t read_bank; - uint32_t write_bank; + uint32_t read_bank, write_bank; uint32_t px_map_base; - uint64_t dispontime; - uint64_t dispofftime; + uint64_t dispontime, dispofftime; - struct { + struct + { uint8_t control; uint8_t px_map_idx; - uint8_t frgd_mix; - uint8_t bkgd_mix; + uint8_t frgd_mix, bkgd_mix; uint8_t cc_cond; uint8_t octant; uint8_t draw_mode; @@ -179,19 +134,15 @@ typedef struct xga_t { uint8_t short_stroke_vector4; int16_t bres_err_term; - int16_t bres_k1; - int16_t bres_k2; + int16_t bres_k1, bres_k2; uint16_t blt_width; uint16_t blt_height; uint16_t mask_map_origin_x_off; uint16_t mask_map_origin_y_off; - uint16_t src_map_x; - uint16_t src_map_y; - uint16_t dst_map_x; - uint16_t dst_map_y; - uint16_t pat_map_x; - uint16_t pat_map_y; + uint16_t src_map_x, src_map_y; + uint16_t dst_map_x, dst_map_y; + uint16_t pat_map_x, pat_map_y; int ssv_state; int pat_src; @@ -199,14 +150,7 @@ typedef struct xga_t { int dst_map; int bkgd_src; int fore_src; - int x; - int y; - int sx; - int sy; - int dx; - int dy; - int px; - int py; + int x, y, sx, sy, dx, dy, px, py; int pattern; int command_len; @@ -214,8 +158,7 @@ typedef struct xga_t { uint32_t color_cmp; uint32_t carry_chain; uint32_t plane_mask; - uint32_t frgd_color; - uint32_t bkgd_color; + uint32_t frgd_color, bkgd_color; uint32_t command; uint32_t dir_cmd; @@ -225,6 +168,6 @@ typedef struct xga_t { uint32_t px_map_base[4]; } accel; - volatile int force_busy; + int big_endian_linear; } xga_t; #endif /*VIDEO_XGA_H*/ diff --git a/src/video/vid_xga.c b/src/video/vid_xga.c index 50cfcb90a..7afa3e41a 100644 --- a/src/video/vid_xga.c +++ b/src/video/vid_xga.c @@ -42,15 +42,18 @@ static video_timings_t timing_xga_isa = { .type = VIDEO_ISA, .write_b = 3, .write_w = 3, .write_l = 6, .read_b = 5, .read_w = 5, .read_l = 10 }; static video_timings_t timing_xga_mca = { .type = VIDEO_MCA, .write_b = 4, .write_w = 5, .write_l = 10, .read_b = 5, .read_w = 5, .read_l = 10 }; -static void xga_ext_outb(uint16_t addr, uint8_t val, void *priv); -static uint8_t xga_ext_inb(uint16_t addr, void *priv); +static void xga_ext_outb(uint16_t addr, uint8_t val, void *p); +static uint8_t xga_ext_inb(uint16_t addr, void *p); + +static void xga_writew(uint32_t addr, uint16_t val, void *p); +static uint16_t xga_readw(uint32_t addr, void *p); int xga_has_vga = 0; void -svga_xga_out(uint16_t addr, uint8_t val, void *priv) +svga_xga_out(uint16_t addr, uint8_t val, void *p) { - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *)p; uint8_t old; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) @@ -86,9 +89,9 @@ svga_xga_out(uint16_t addr, uint8_t val, void *priv) } uint8_t -svga_xga_in(uint16_t addr, void *priv) +svga_xga_in(uint16_t addr, void *p) { - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *)p; uint8_t temp; if (((addr & 0xfff0) == 0x3d0 || (addr & 0xfff0) == 0x3b0) && !(svga->miscout & 1)) @@ -350,6 +353,10 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) svga_recalctimings(svga); break; + case 0x55: + xga->border_color = val; + break; + case 0x59: xga->direct_color = val; break; @@ -451,9 +458,9 @@ xga_ext_out_reg(xga_t *xga, svga_t *svga, uint8_t idx, uint8_t val) } static void -xga_ext_outb(uint16_t addr, uint8_t val, void *priv) +xga_ext_outb(uint16_t addr, uint8_t val, void *p) { - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *) p; xga_t *xga = &svga->xga; //pclog("[%04X:%08X]: EXT OUTB = %02x, val = %02x\n", CS, cpu_state.pc, addr, val); @@ -470,8 +477,6 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *priv) if ((xga->disp_cntl_2 & 7) == 4) xga->aperture_cntl = 0; break; - case 6: - break; case 8: xga->ap_idx = val; //pclog("Aperture CNTL = %d, val = %02x, up to bit6 = %02x\n", xga->aperture_cntl, val, val & 0x3f); @@ -500,11 +505,11 @@ xga_ext_outb(uint16_t addr, uint8_t val, void *priv) } static uint8_t -xga_ext_inb(uint16_t addr, void *priv) +xga_ext_inb(uint16_t addr, void *p) { - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *) p; xga_t *xga = &svga->xga; - uint8_t ret = 0xff; + uint8_t ret; uint8_t index; switch (addr & 0x0f) { @@ -646,6 +651,9 @@ xga_ext_inb(uint16_t addr, void *priv) case 0x54: ret = xga->clk_sel_1; break; + case 0x55: + ret = xga->border_color; + break; case 0x59: ret = xga->direct_color; @@ -743,37 +751,17 @@ xga_ext_inb(uint16_t addr, void *priv) #define READW(addr, dat) \ dat = *(uint16_t *) &xga->vram[(addr) & (xga->vram_mask)]; -#define READW_REVERSE(addr, dat) \ - dat = xga->vram[(addr + 1) & (xga->vram_mask - 1)] & 0xff; \ - dat |= (xga->vram[(addr) & (xga->vram_mask - 1)] << 8); - -#define READL(addr, dat) \ - dat = *(uint32_t *) &xga->vram[(addr) & (xga->vram_mask)]; - -#define READL_REVERSE(addr, dat) \ - dat = xga->vram[(addr + 3) & (xga->vram_mask - 3)] & 0xff; \ - dat |= (xga->vram[(addr + 2) & (xga->vram_mask - 3)] << 8); \ - dat |= (xga->vram[(addr + 1) & (xga->vram_mask - 3)] << 16); \ - dat |= (xga->vram[(addr) & (xga->vram_mask - 3)] << 24); +#define READW_INV(addr, dat) \ + dat = xga->vram[(addr + 1) & (xga->vram_mask)]; \ + dat |= (xga->vram[(addr) & (xga->vram_mask)] << 8); #define WRITEW(addr, dat) \ *(uint16_t *) &xga->vram[((addr)) & (xga->vram_mask)] = dat; \ xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount; -#define WRITEL(addr, dat) \ - *(uint32_t *) &xga->vram[((addr)) & (xga->vram_mask)] = dat; \ - xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount; - -#define WRITEW_REVERSE(addr, dat) \ - xga->vram[((addr + 1)) & (xga->vram_mask - 1)] = dat & 0xff; \ - xga->vram[((addr)) & (xga->vram_mask - 1)] = dat >> 8; \ - xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount; - -#define WRITEL_REVERSE(addr, dat) \ - xga->vram[((addr + 3)) & (xga->vram_mask - 3)] = dat & 0xff; \ - xga->vram[((addr + 2)) & (xga->vram_mask - 3)] = dat >> 8; \ - xga->vram[((addr + 1)) & (xga->vram_mask - 3)] = dat >> 16; \ - xga->vram[((addr)) & (xga->vram_mask - 3)] = dat >> 24; \ +#define WRITEW_INV(addr, dat) \ + xga->vram[((addr + 1)) & (xga->vram_mask)] = dat & 0xff; \ + xga->vram[((addr)) & (xga->vram_mask)] = dat >> 8; \ xga->changedvram[(((addr)) & (xga->vram_mask)) >> 12] = svga->monitor->mon_changeframecount; #define ROP(mix, d, s) \ @@ -873,20 +861,21 @@ xga_accel_read_pattern_map_pixel(svga_t *svga, int x, int y, int map, uint32_t b } else { byte = mem_readb_phys(addr); } - if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) - if (xga->linear_endian_reverse) - bits = 7 - (x & 7); - else - bits = (x & 7); - else { + if (xga->linear_endian_reverse) { bits = 7 - (x & 7); + } else { + if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) + bits = (x & 7); + else { + 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) +xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int width, int usesrc) { xga_t *xga = &svga->xga; uint32_t addr = base; @@ -912,13 +901,14 @@ xga_accel_read_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, int } else { byte = mem_readb_phys(addr); } - if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) - if (xga->linear_endian_reverse) - bits = 7 - (x & 7); - else - bits = (x & 7); - else { + if (xga->linear_endian_reverse) { bits = 7 - (x & 7); + } else { + if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) + bits = (x & 7); + else { + bits = 7 - (x & 7); + } } px = (byte >> bits) & 1; return px; @@ -934,39 +924,21 @@ 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 (!skip) { - if (xga->accel.px_map_format[map] & 8) { - if (xga->linear_endian_reverse) { - READW(addr, byte); - } else { - READW_REVERSE(addr, byte); - } - } else { - READW(addr, byte); - } - } else { + if (xga->linear_endian_reverse) { byte = mem_readw_phys(addr); - } - return byte; - case 5: /*24-bit*/ - addr += (y * (width << 2)); - addr += (x << 2); - if (!skip) { - if ((xga->accel.px_map_format[map] & 8)) { - if (xga->linear_endian_reverse) { - READL(addr, byte); - } else { - READL_REVERSE(addr, byte); - } - } else { - READL(addr, byte); - } + if ((xga->access_mode & 7) == 4) + byte = ((byte & 0xff00) >> 8) | ((byte & 0x00ff) << 8); + else if (xga->access_mode & 8) + byte = ((byte & 0xff00) >> 8) | ((byte & 0x00ff) << 8); } else { - byte = mem_readl_phys(addr); + if (!skip) { + READW(addr, byte); + } else { + byte = mem_readb_phys(addr) | (mem_readb_phys(addr + 1) << 8); + } } return byte; } - return 0; } @@ -996,13 +968,14 @@ xga_accel_write_map_pixel(svga_t *svga, int x, int y, int map, uint32_t base, ui } else { byte = mem_readb_phys(addr); } - if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) { - if (xga->linear_endian_reverse) - mask = 1 << (7 - (x & 7)); - else - mask = 1 << (x & 7); - } else { + if (xga->linear_endian_reverse) { mask = 1 << (7 - (x & 7)); + } else { + if ((xga->accel.px_map_format[map] & 8) && !(xga->access_mode & 8)) { + mask = 1 << (x & 7); + } else { + mask = 1 << (7 - (x & 7)); + } } byte = (byte & ~mask) | ((pixel ? 0xff : 0) & mask); if (pixel & 1) { @@ -1029,34 +1002,19 @@ 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 (!skip) { - if (xga->accel.px_map_format[map] & 8) { - if (xga->linear_endian_reverse) { - WRITEW(addr, pixel); - } else { - WRITEW_REVERSE(addr, pixel); - } - } else { + if (xga->linear_endian_reverse) { + if ((xga->access_mode & 7) == 4) + pixel = ((pixel & 0xff00) >> 8) | ((pixel & 0x00ff) << 8); + else if (xga->access_mode & 8) + pixel = ((pixel & 0xff00) >> 8) | ((pixel & 0x00ff) << 8); + + mem_writew_phys(addr, pixel); + } else { + if (!skip) { WRITEW(addr, pixel); } + mem_writew_phys(addr, pixel); } - mem_writew_phys(addr, pixel); - break; - case 5: /*24-bit*/ - addr += (y * (width) << 2); - addr += (x << 2); - if (!skip) { - if ((xga->accel.px_map_format[map] & 8)) { - if (xga->linear_endian_reverse) { - WRITEL(addr, pixel); - } else { - WRITEL_REVERSE(addr, pixel); - } - } else { - WRITEL(addr, pixel); - } - } - mem_writel_phys(addr, pixel); break; } } @@ -1080,11 +1038,11 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) int diry = 0; dx = xga->accel.dst_map_x & 0x1fff; - if (xga->accel.dst_map_x & 0x1800) + if (xga->accel.dst_map_x >= 0x1800) dx |= ~0x17ff; dy = xga->accel.dst_map_y & 0x1fff; - if (xga->accel.dst_map_y & 0x1800) + if (xga->accel.dst_map_y >= 0x1800) dy |= ~0x17ff; switch ((ssv >> 5) & 7) { @@ -1126,8 +1084,8 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) while (y >= 0) { 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.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); + 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, 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, 0); 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; @@ -1146,8 +1104,8 @@ xga_short_stroke(svga_t *svga, uint8_t ssv) } } } 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.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); + 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, 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, 0); 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; @@ -1239,11 +1197,11 @@ xga_line_draw_write(svga_t *svga) } dx = xga->accel.dst_map_x & 0x1fff; - if (xga->accel.dst_map_x & 0x1800) + if (xga->accel.dst_map_x >= 0x1800) dx |= ~0x17ff; dy = xga->accel.dst_map_y & 0x1fff; - if (xga->accel.dst_map_y & 0x1800) + if (xga->accel.dst_map_y >= 0x1800) dy |= ~0x17ff; if (xga->accel.octant & 0x01) { @@ -1257,8 +1215,8 @@ xga_line_draw_write(svga_t *svga) if (xga->accel.command & 0xc0) { 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.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); + 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, 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, 0); 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; @@ -1274,8 +1232,8 @@ xga_line_draw_write(svga_t *svga) } } 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.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); + 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, 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, 0); 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; @@ -1292,8 +1250,8 @@ xga_line_draw_write(svga_t *svga) } } 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.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); + 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, 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, 0); 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; @@ -1307,8 +1265,8 @@ xga_line_draw_write(svga_t *svga) 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.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); + 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, 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, 0); 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; @@ -1350,13 +1308,6 @@ xga_line_draw_write(svga_t *svga) } } -static int16_t -xga_dst_wrap(int16_t addr) -{ - addr &= 0x1fff; - return (addr & 0x1800) == 0x1800 ? (addr | 0xf800) : addr; -} - static void xga_bitblt(svga_t *svga) { @@ -1374,6 +1325,9 @@ xga_bitblt(svga_t *svga) uint32_t srcwidth = xga->accel.px_map_width[xga->accel.src_map]; uint32_t patheight = xga->accel.px_map_height[xga->accel.pat_src]; uint32_t srcheight = xga->accel.px_map_height[xga->accel.src_map]; + uint32_t dstheight = xga->accel.px_map_height[xga->accel.dst_map]; + uint32_t frgdcol = xga->accel.frgd_color; + uint32_t bkgdcol = xga->accel.bkgd_color; int mix = 0; int xdir; int ydir; @@ -1397,11 +1351,18 @@ xga_bitblt(svga_t *svga) xga->accel.sy = xga->accel.src_map_y & 0xfff; xga->accel.px = xga->accel.pat_map_x & 0xfff; xga->accel.py = xga->accel.pat_map_y & 0xfff; - xga->accel.dx = xga_dst_wrap(xga->accel.dst_map_x); - xga->accel.dy = xga_dst_wrap(xga->accel.dst_map_y); + xga->accel.dx = xga->accel.dst_map_x & 0x1fff; + if (xga->accel.dst_map_x >= 0x1800) + xga->accel.dx |= ~0x17ff; + xga->accel.dy = xga->accel.dst_map_y & 0x1fff; + if (xga->accel.dst_map_y >= 0x1800) + xga->accel.dy |= ~0x17ff; xga->accel.pattern = 0; + //pclog("XGA bitblt linear endian reverse=%d, 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, 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)); + if (xga->accel.pat_src == 8) { if (srcheight == 7) xga->accel.pattern = 1; @@ -1414,15 +1375,13 @@ xga_bitblt(svga_t *svga) } } } - // pclog("Pattern Map = 8: CMD = %08x: SRCBase = %08x, DSTBase = %08x, from/to vram dir = %d, cmd dir = %06x\n", xga->accel.command, srcbase, dstbase, xga->from_to_vram, xga->accel.dir_cmd); // pclog("CMD = %08x: Y = %d, X = %d, patsrc = %02x, srcmap = %d, dstmap = %d, py = %d, sy = %d, dy = %d, width0 = %d, width1 = %d, width2 = %d, width3 = %d\n", xga->accel.command, xga->accel.y, xga->accel.x, xga->accel.pat_src, xga->accel.src_map, xga->accel.dst_map, xga->accel.py, xga->accel.sy, xga->accel.dy, xga->accel.px_map_width[0], xga->accel.px_map_width[1], xga->accel.px_map_width[2], xga->accel.px_map_width[3]); while (xga->accel.y >= 0) { 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.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 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, 1) : frgdcol; + dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); 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); @@ -1431,9 +1390,8 @@ xga_bitblt(svga_t *svga) } } } 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.frgd_color; - dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 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, 1) : frgdcol; + dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); 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); @@ -1446,15 +1404,17 @@ xga_bitblt(svga_t *svga) xga->accel.sx = ((xga->accel.sx + xdir) & srcwidth) | (xga->accel.sx & ~srcwidth); else xga->accel.sx += xdir; - xga->accel.dx = xga_dst_wrap(xga->accel.dx + xdir); + xga->accel.dx += xdir; xga->accel.x--; if (xga->accel.x < 0) { xga->accel.x = (xga->accel.blt_width & 0xfff); - xga->accel.dx = xga_dst_wrap(xga->accel.dst_map_x); + xga->accel.dx = xga->accel.dst_map_x & 0x1fff; + if (xga->accel.dst_map_x >= 0x1800) + xga->accel.dx |= ~0x17ff; xga->accel.sx = xga->accel.src_map_x & 0xfff; - xga->accel.dy = xga_dst_wrap(xga->accel.dy + ydir); + xga->accel.dy += ydir; if (xga->accel.pattern) xga->accel.sy = ((xga->accel.sy + ydir) & srcheight) | (xga->accel.sy & ~srcheight); else @@ -1493,6 +1453,7 @@ xga_bitblt(svga_t *svga) } } + // pclog("XGA bitblt linear endian reverse=%d, octanty=%d, src command = %08x, pxsrcmap=%x, pxdstmap=%x, srcmap=%d, patmap=%d, dstmap=%d, dstwidth=%d, dstheight=%d, srcwidth=%d, srcheight=%d, dstbase=%08x, srcbase=%08x.\n", xga->linear_endian_reverse, ydir, xga->accel.command, xga->accel.px_map_format[xga->accel.src_map] & 0x0f, xga->accel.px_map_format[xga->accel.dst_map] & 0x0f, xga->accel.src_map, xga->accel.pat_src, xga->accel.dst_map, dstwidth, dstheight, srcwidth, srcheight, dstbase, srcbase); // pclog("Pattern Map = %d: CMD = %08x: PATBase = %08x, SRCBase = %08x, DSTBase = %08x\n", xga->accel.pat_src, xga->accel.command, patbase, srcbase, dstbase); // pclog("CMD = %08x: Y = %d, X = %d, patsrc = %02x, srcmap = %d, dstmap = %d, py = %d, sy = %d, dy = %d, width0 = %d, width1 = %d, width2 = %d, width3 = %d\n", xga->accel.command, xga->accel.y, xga->accel.x, xga->accel.pat_src, xga->accel.src_map, xga->accel.dst_map, xga->accel.py, xga->accel.sy, xga->accel.dy, xga->accel.px_map_width[0], xga->accel.px_map_width[1], xga->accel.px_map_width[2], xga->accel.px_map_width[3]); while (xga->accel.y >= 0) { @@ -1500,13 +1461,12 @@ 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))) { - 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.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.bkgd_color; - - dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1); - + 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, 1) : frgdcol; + } 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, 1) : bkgdcol; + } + dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); 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(mix, dest_dat, src_dat); @@ -1515,13 +1475,12 @@ xga_bitblt(svga_t *svga) } } } 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.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.bkgd_color; - - dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1); - + 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, 1) : frgdcol; + } 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, 1) : bkgdcol; + } + dest_dat = xga_accel_read_map_pixel(svga, xga->accel.dx, xga->accel.dy, xga->accel.dst_map, dstbase, dstwidth + 1, 0); 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(mix, dest_dat, src_dat); @@ -1535,13 +1494,15 @@ xga_bitblt(svga_t *svga) xga->accel.px = ((xga->accel.px + xdir) & patwidth) | (xga->accel.px & ~patwidth); else xga->accel.px += xdir; - xga->accel.dx = xga_dst_wrap(xga->accel.dx + xdir); + xga->accel.dx += xdir; xga->accel.x--; if (xga->accel.x < 0) { xga->accel.y--; xga->accel.x = (xga->accel.blt_width & 0xfff); - xga->accel.dx = xga_dst_wrap(xga->accel.dst_map_x); + xga->accel.dx = xga->accel.dst_map_x & 0x1fff; + if (xga->accel.dst_map_x >= 0x1800) + xga->accel.dx |= ~0x17ff; xga->accel.sx = xga->accel.src_map_x & 0xfff; xga->accel.px = xga->accel.pat_map_x & 0xfff; @@ -1550,7 +1511,7 @@ xga_bitblt(svga_t *svga) xga->accel.py = ((xga->accel.py + ydir) & patheight) | (xga->accel.py & ~patheight); else xga->accel.py += ydir; - xga->accel.dy = xga_dst_wrap(xga->accel.dy + ydir); + xga->accel.dy += ydir; if (xga->accel.y < 0) { xga->accel.dst_map_x = xga->accel.dx; @@ -1952,7 +1913,6 @@ xga_mem_write(uint32_t addr, uint32_t val, xga_t *xga, svga_t *svga, int len) exec_command: xga->accel.octant = xga->accel.command & 0x07; xga->accel.draw_mode = xga->accel.command & 0x30; - xga->accel.mask_mode = xga->accel.command & 0xc0; xga->accel.pat_src = ((xga->accel.command >> 12) & 0x0f); xga->accel.dst_map = ((xga->accel.command >> 16) & 0x0f); xga->accel.src_map = ((xga->accel.command >> 20) & 0x0f); @@ -1973,18 +1933,23 @@ exec_command: // } switch ((xga->accel.command >> 24) & 0x0f) { case 3: /*Bresenham Line Draw Read*/ - // pclog("Line Draw Read\n"); + //pclog("Line Draw Read\n"); break; case 4: /*Short Stroke Vectors*/ + //pclog("Short Stroke Vectors.\n"); break; case 5: /*Bresenham Line Draw Write*/ + //pclog("Line Draw Write.\n"); xga_line_draw_write(svga); break; case 8: /*BitBLT*/ xga_bitblt(svga); break; case 9: /*Inverting BitBLT*/ - // pclog("Inverting BitBLT\n"); + //pclog("Inverting BitBLT\n"); + break; + case 0x0a: /*Area Fill*/ + //pclog("Area Fill.\n"); break; } } else if (len == 2) { @@ -2014,9 +1979,9 @@ exec_command: } static void -xga_memio_writeb(uint32_t addr, uint8_t val, void *priv) +xga_memio_writeb(uint32_t addr, uint8_t val, void *p) { - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *) p; xga_t *xga = &svga->xga; xga_mem_write(addr, val, xga, svga, 1); @@ -2024,9 +1989,9 @@ xga_memio_writeb(uint32_t addr, uint8_t val, void *priv) } static void -xga_memio_writew(uint32_t addr, uint16_t val, void *priv) +xga_memio_writew(uint32_t addr, uint16_t val, void *p) { - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *) p; xga_t *xga = &svga->xga; xga_mem_write(addr, val, xga, svga, 2); @@ -2034,9 +1999,9 @@ xga_memio_writew(uint32_t addr, uint16_t val, void *priv) } static void -xga_memio_writel(uint32_t addr, uint32_t val, void *priv) +xga_memio_writel(uint32_t addr, uint32_t val, void *p) { - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *) p; xga_t *xga = &svga->xga; xga_mem_write(addr, val, xga, svga, 4); @@ -2125,9 +2090,9 @@ xga_mem_read(uint32_t addr, xga_t *xga, svga_t *svga) } static uint8_t -xga_memio_readb(uint32_t addr, void *priv) +xga_memio_readb(uint32_t addr, void *p) { - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *) p; xga_t *xga = &svga->xga; uint8_t temp; @@ -2138,9 +2103,9 @@ xga_memio_readb(uint32_t addr, void *priv) } static uint16_t -xga_memio_readw(uint32_t addr, void *priv) +xga_memio_readw(uint32_t addr, void *p) { - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *) p; xga_t *xga = &svga->xga; uint16_t temp; @@ -2152,9 +2117,9 @@ xga_memio_readw(uint32_t addr, void *priv) } static uint32_t -xga_memio_readl(uint32_t addr, void *priv) +xga_memio_readl(uint32_t addr, void *p) { - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *) p; xga_t *xga = &svga->xga; uint32_t temp; @@ -2326,9 +2291,9 @@ xga_render_16bpp(xga_t *xga, svga_t *svga) } static void -xga_write(uint32_t addr, uint8_t val, void *priv) +xga_write(uint32_t addr, uint8_t val, void *p) { - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *) p; xga_t *xga = &svga->xga; if (!xga->on) { @@ -2344,39 +2309,114 @@ xga_write(uint32_t addr, uint8_t val, void *priv) cycles -= video_timing_write_b; + if (xga->access_mode & 8) { + if ((xga->access_mode & 7) == 4) + addr ^= 1; + } + xga->changedvram[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount; - xga->vram[addr & xga->vram_mask] = val; + xga->vram[addr & xga->vram_mask] = val; } static void -xga_writeb(uint32_t addr, uint8_t val, void *priv) +xga_writew(uint32_t addr, uint16_t val, void *p) { - // pclog("[%04X:%08X]: WriteB\n", CS, cpu_state.pc); - xga_write(addr, val, priv); + svga_t *svga = (svga_t *) p; + xga_t *xga = &svga->xga; + + if (!xga->on) { + svga_writew(addr, val, svga); + return; + } + + xga_write(addr, val & 0xff, svga); + xga_write(addr + 1, val >> 8, svga); } static void -xga_writew(uint32_t addr, uint16_t val, void *priv) +xga_writel(uint32_t addr, uint32_t val, void *p) { - // pclog("[%04X:%08X]: WriteW\n", CS, cpu_state.pc); - xga_write(addr, val, priv); - xga_write(addr + 1, val >> 8, priv); + svga_t *svga = (svga_t *) p; + xga_t *xga = &svga->xga; + + if (!xga->on) { + svga_writel(addr, val, svga); + return; + } + + xga_write(addr, val & 0xff, svga); + xga_write(addr + 1, (val >> 8) & 0xff, svga); + xga_write(addr + 2, (val >> 16) & 0xff, svga); + xga_write(addr + 3, (val >> 24) & 0xff, svga); +} + + +static uint8_t +xga_read(uint32_t addr, void *p) +{ + svga_t *svga = (svga_t *) p; + xga_t *xga = &svga->xga; + uint8_t ret = 0xff; + + if (!xga->on) + return svga_read(addr, svga); + + addr &= xga->banked_mask; + addr += xga->read_bank; + + if (addr >= xga->vram_size) + return ret; + + cycles -= video_timing_read_b; + + if (xga->access_mode & 8) { + if ((xga->access_mode & 7) == 4) + addr ^= 1; + } + + ret = xga->vram[addr & xga->vram_mask]; + + return ret; +} + +static uint16_t +xga_readw(uint32_t addr, void *p) +{ + svga_t *svga = (svga_t *) p; + xga_t *xga = &svga->xga; + uint16_t ret = 0xffff; + + if (!xga->on) + return svga_readw(addr, svga); + + ret = xga_read(addr, svga); + ret |= (xga_read(addr + 1, svga) << 8); + + return ret; +} + +static uint32_t +xga_readl(uint32_t addr, void *p) +{ + svga_t *svga = (svga_t *) p; + xga_t *xga = &svga->xga; + uint32_t ret = 0xffffffff; + + if (!xga->on) + return svga_readl(addr, svga); + + ret = xga_read(addr, svga); + ret |= (xga_read(addr + 1, svga) << 8); + ret |= (xga_read(addr + 2, svga) << 16); + ret |= (xga_read(addr + 3, svga) << 24); + + return ret; } static void -xga_writel(uint32_t addr, uint32_t val, void *priv) +xga_write_linear(uint32_t addr, uint8_t val, void *p) { - // pclog("[%04X:%08X]: WriteL\n", CS, cpu_state.pc); - xga_write(addr, val, priv); - xga_write(addr + 1, val >> 8, priv); - xga_write(addr + 2, val >> 16, priv); - xga_write(addr + 3, val >> 24, priv); -} - -static void -xga_write_linear(uint32_t addr, uint8_t val, void *priv) -{ - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *) p; xga_t *xga = &svga->xga; if (!xga->on) { @@ -2391,14 +2431,24 @@ xga_write_linear(uint32_t addr, uint8_t val, void *priv) cycles -= video_timing_write_b; + if (xga->linear_endian_reverse) { + if ((xga->access_mode & 7) == 4) { + if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) == 4) + addr ^= 1; + } else if (xga->access_mode & 8) { + if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) == 4) + addr ^= 1; + } + } + xga->changedvram[(addr & xga->vram_mask) >> 12] = svga->monitor->mon_changeframecount; xga->vram[addr & xga->vram_mask] = val; } static void -xga_writew_linear(uint32_t addr, uint16_t val, void *priv) +xga_writew_linear(uint32_t addr, uint16_t val, void *p) { - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *) p; xga_t *xga = &svga->xga; if (!xga->on) { @@ -2406,35 +2456,14 @@ xga_writew_linear(uint32_t addr, uint16_t val, void *priv) return; } - if (xga->linear_endian_reverse) { - if (xga->accel.px_map_format[xga->accel.dst_map] == 0x0c) { - xga_write_linear(addr, val, priv); - xga_write_linear(addr + 1, val >> 8, priv); - } else if (xga->accel.px_map_format[xga->accel.dst_map] == 4) { - xga_write_linear(addr + 1, val, priv); - xga_write_linear(addr, val >> 8, priv); - } else { - xga_write_linear(addr, val, priv); - xga_write_linear(addr + 1, val >> 8, priv); - } - } else { - if (xga->accel.px_map_format[xga->accel.dst_map] == 0x0c) { - xga_write_linear(addr + 1, val, priv); - xga_write_linear(addr, val >> 8, priv); - } else if (xga->accel.px_map_format[xga->accel.dst_map] == 4) { - xga_write_linear(addr, val, priv); - xga_write_linear(addr + 1, val >> 8, priv); - } else { - xga_write_linear(addr, val, priv); - xga_write_linear(addr + 1, val >> 8, priv); - } - } + xga_write_linear(addr, val, p); + xga_write_linear(addr + 1, val >> 8, p); } static void -xga_writel_linear(uint32_t addr, uint32_t val, void *priv) +xga_writel_linear(uint32_t addr, uint32_t val, void *p) { - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *) p; xga_t *xga = &svga->xga; if (!xga->on) { @@ -2442,71 +2471,18 @@ xga_writel_linear(uint32_t addr, uint32_t val, void *priv) return; } - xga_write_linear(addr, val, priv); - xga_write_linear(addr + 1, val >> 8, priv); - xga_write_linear(addr + 2, val >> 16, priv); - xga_write_linear(addr + 3, val >> 24, priv); + xga_write_linear(addr, val, p); + xga_write_linear(addr + 1, val >> 8, p); + xga_write_linear(addr + 2, val >> 16, p); + xga_write_linear(addr + 3, val >> 24, p); } static uint8_t -xga_read(uint32_t addr, void *priv) +xga_read_linear(uint32_t addr, void *p) { - svga_t *svga = (svga_t *) priv; - xga_t *xga = &svga->xga; - - if (!xga->on) - return svga_read(addr, svga); - - addr &= xga->banked_mask; - addr += xga->read_bank; - - if (addr >= xga->vram_size) - return 0xff; - - cycles -= video_timing_read_b; - - return xga->vram[addr & xga->vram_mask]; -} - -static uint8_t -xga_readb(uint32_t addr, void *priv) -{ - uint8_t ret; - - ret = xga_read(addr, priv); - - return ret; -} - -static uint16_t -xga_readw(uint32_t addr, void *priv) -{ - uint16_t ret; - - ret = xga_read(addr, priv); - ret |= (xga_read(addr + 1, priv) << 8); - - return ret; -} - -static uint32_t -xga_readl(uint32_t addr, void *priv) -{ - uint32_t ret; - - ret = xga_read(addr, priv); - ret |= (xga_read(addr + 1, priv) << 8); - ret |= (xga_read(addr + 2, priv) << 16); - ret |= (xga_read(addr + 3, priv) << 24); - - return ret; -} - -static uint8_t -xga_read_linear(uint32_t addr, void *priv) -{ - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *) p; xga_t *xga = &svga->xga; + uint8_t ret = 0xff; if (!xga->on) return svga_read_linear(addr, svga); @@ -2514,51 +2490,55 @@ xga_read_linear(uint32_t addr, void *priv) addr &= svga->decode_mask; if (addr >= xga->vram_size) - return 0xff; + return ret; cycles -= video_timing_read_b; + if (xga->linear_endian_reverse) { + if ((xga->access_mode & 7) == 4) { + if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) == 4) + addr ^= 1; + } else if (xga->access_mode & 8) { + if ((xga->accel.px_map_format[xga->accel.dst_map] & 7) == 4) + addr ^= 1; + } + } + return xga->vram[addr & xga->vram_mask]; } static uint16_t -xga_readw_linear(uint32_t addr, void *priv) +xga_readw_linear(uint32_t addr, void *p) { - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *) p; xga_t *xga = &svga->xga; uint16_t ret; if (!xga->on) return svga_readw_linear(addr, svga); - if (xga->linear_endian_reverse) { - if (xga->accel.px_map_format[xga->accel.src_map] == 0x0c) { - ret = xga_read_linear(addr, priv) | (xga_read_linear(addr + 1, priv) << 8); - } else if (xga->accel.px_map_format[xga->accel.src_map] == 4) { - ret = xga_read_linear(addr + 1, priv) | (xga_read_linear(addr, priv) << 8); - } else - ret = xga_read_linear(addr, priv) | (xga_read_linear(addr + 1, priv) << 8); - } else { - if (xga->accel.px_map_format[xga->accel.src_map] == 0x0c) { - ret = xga_read_linear(addr + 1, priv) | (xga_read_linear(addr, priv) << 8); - } else if (xga->accel.px_map_format[xga->accel.src_map] == 4) { - ret = xga_read_linear(addr, priv) | (xga_read_linear(addr + 1, priv) << 8); - } else - ret = xga_read_linear(addr, priv) | (xga_read_linear(addr + 1, priv) << 8); - } + ret = xga_read_linear(addr, svga); + ret |= (xga_read_linear(addr + 1, svga) << 8); + return ret; } static uint32_t -xga_readl_linear(uint32_t addr, void *priv) +xga_readl_linear(uint32_t addr, void *p) { - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *) p; xga_t *xga = &svga->xga; + uint32_t ret; if (!xga->on) return svga_readl_linear(addr, svga); - return xga_read_linear(addr, priv) | (xga_read_linear(addr + 1, priv) << 8) | (xga_read_linear(addr + 2, priv) << 16) | (xga_read_linear(addr + 3, priv) << 24); + ret = xga_read_linear(addr, svga); + ret |= (xga_read_linear(addr + 1, svga) << 8); + ret |= (xga_read_linear(addr + 2, svga) << 16); + ret |= (xga_read_linear(addr + 3, svga) << 24); + + return ret; } static void @@ -2793,9 +2773,9 @@ xga_mca_feedb(void *priv) } static void -xga_mca_reset(void *priv) +xga_mca_reset(void *p) { - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *) p; xga_t *xga = &svga->xga; xga->on = 0; @@ -2804,9 +2784,9 @@ xga_mca_reset(void *priv) } static void -xga_reset(void *priv) +xga_reset(void *p) { - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *) p; xga_t *xga = &svga->xga; mem_mapping_disable(&xga->bios_rom.mapping); @@ -3033,8 +3013,8 @@ static void xga->rom_addr = 0xc0000 + (((xga->pos_regs[2] & 0xf0) >> 4) * 0x2000); } - mem_mapping_add(&xga->video_mapping, 0, 0, xga_readb, xga_readw, xga_readl, - xga_writeb, xga_writew, xga_writel, + mem_mapping_add(&xga->video_mapping, 0, 0, xga_read, xga_readw, xga_readl, + xga_write, xga_writew, xga_writel, NULL, MEM_MAPPING_EXTERNAL, svga); mem_mapping_add(&xga->linear_mapping, 0, 0, xga_read_linear, xga_readw_linear, xga_readl_linear, xga_write_linear, xga_writew_linear, xga_writel_linear, @@ -3090,9 +3070,9 @@ static void } static void -xga_close(void *priv) +xga_close(void *p) { - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *) p; xga_t *xga = &svga->xga; if (svga) { @@ -3114,17 +3094,17 @@ inmos_xga_available(void) } static void -xga_speed_changed(void *priv) +xga_speed_changed(void *p) { - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *) p; svga_recalctimings(svga); } static void -xga_force_redraw(void *priv) +xga_force_redraw(void *p) { - svga_t *svga = (svga_t *) priv; + svga_t *svga = (svga_t *) p; svga->fullchange = svga->monitor->mon_changeframecount; }